One Hat Cyber Team
  • Dir : ~/var/softaculous/phplite/
  • View File Name : phpliteadmin.php
    "; echo ""; echo "
    "; echo "
    "; echo $lang['fields']."
    "; echo ""; echo ""; echo "
    "; echo "
    "; echo $lang['delimit']." "; echo ""; echo ""; echo ""; break; //- Empty table (=table_empty) case "table_empty": echo $params->getForm(array('action'=>'table_empty','confirm'=>'1')); echo "
    "; echo sprintf($lang['ques_empty'], htmlencode($target_table))."

    "; echo " ".$lang['vac_on_empty']."

    "; echo " "; echo $params->getLink(array('table'=>null), $lang['cancel']); echo "
    "; break; //- Drop table (=table_drop) case "table_drop": echo $params->getForm(array('action'=>'table_drop','confirm'=>'1')); echo "
    "; echo sprintf($lang['ques_drop'], htmlencode($target_table))."

    "; echo " ".$lang['vac_on_empty']."

    "; echo " "; echo $params->getLink(array('table'=>null), $lang['cancel']); echo "
    "; break; //- Drop view (=view_drop) case "view_drop": echo $params->getForm(array('action'=>'view_drop','confirm'=>'1')); echo ""; echo "
    "; echo sprintf($lang['ques_drop_view'], htmlencode($target_table))."

    "; echo " "; echo $params->getLink(array('table'=>null), $lang['cancel']); echo "
    "; break; //- Export table (=table_export) case "table_export": echo $params->getForm(); echo "
    ".$lang['export'].""; echo ""; echo ""; echo "
    "; echo "
    "; echo "
    ".$lang['options'].""; echo " ".helpLink($lang['help5'])."
    "; echo " ".helpLink($lang['help6'])."
    "; echo " ".helpLink($lang['help7'])."
    "; echo " ".helpLink($lang['help8'])."
    "; echo " ".helpLink($lang['help9'])."
    "; echo "
    "; echo ""; echo "
    "; echo "

    "; echo "
    ".$lang['save_as'].""; $file = pathinfo($db->getPath()); $name = $file['filename']; echo " "; echo "
    "; echo ""; echo "
    ".sprintf($lang['backup_hint'], $params->getLink(array('download' => $currentDB['path'], 'token' => $_SESSION[COOKIENAME.'token']), $lang["backup_hint_linktext"], '', $lang['backup']))."
    "; break; //- Import table (=table_import) case "table_import": if(isset($_POST['import'])) { echo "
    "; if($importSuccess===true) echo $lang['import_suc']; else echo $lang['err'].': '.htmlencode($importSuccess); echo "

    "; } echo $params->getForm(array('action' => 'table_import'), 'post', true); echo "
    ".$lang['import_into']." ".htmlencode($target_table).""; echo ""; echo "
    "; echo "
    "; echo "
    ".$lang['options'].""; echo $lang['no_opt']; echo "
    "; echo ""; echo "
    "; echo "

    "; echo "
    ".$lang['import_f'].""; echo "".$lang['max_file_size'].": ".number_format(fileUploadMaxSize()/1024/1024)." MiB ".helpLink($lang['help11'])."
    "; echo ""; echo ""; echo "
    "; break; //- Rename table (=table_rename) case "table_rename": echo $params->getForm(array('action'=>'table_rename', 'confirm'=>'1')); printf($lang['rename_tbl'], htmlencode($target_table)); echo " "; echo ""; break; //- Search table (=table_search) case "table_search": if(!isset($_GET['search'])) { $tableInfo = $db->getTableInfo($target_table); echo $params->getForm(array('action'=>'table_search', 'confirm'=>'1')); echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; for($i=0; $i"; $tdWithClassLeft = ""; echo $tdWithClassLeft; echo htmlencode($field); echo ""; echo $tdWithClassLeft; echo htmlencode($type); echo ""; echo $tdWithClassLeft; echo ""; echo ""; echo $tdWithClassLeft; if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") echo ""; else echo ""; echo ""; echo ""; } echo ""; echo ""; echo ""; echo "
    ".$lang['fld']."".$lang['type']."".$lang['operator']."".$lang['val']."
    "; if(isset($_GET['oldSearch']) && isset($_SESSION[COOKIENAME.'search'][$_GET['oldSearch']]['values'][$field])) $value = implode($_SESSION[COOKIENAME.'search'][$_GET['oldSearch']]['values'][$field], ","); else $value = ''; if(isset($_GET['oldSearch']) && isset($_SESSION[COOKIENAME.'search'][$_GET['oldSearch']]['operators'][$field])) $operator = $_SESSION[COOKIENAME.'search'][$_GET['oldSearch']]['operators'][$field]; elseif($typeAffinity=="TEXT" || $typeAffinity=="NONE") $operator = 'LIKE'; else $operator = '='; echo "
    "; echo ""; echo "
    "; echo ""; break; } elseif(isset($_SESSION[COOKIENAME.'search'][$_GET['search']])) { $params->search = $_GET['search']; $search = $_SESSION[COOKIENAME.'search'][$_GET['search']]; // NOTICE: we do not break here!! we just do the same now like row_view-action does } //- Row actions //- View row (=row_view) case "row_view": if(!isset($_GET['startRow'])) $_GET['startRow'] = 0; if(isset($_SESSION[COOKIENAME.'currentTable']) && $_SESSION[COOKIENAME.'currentTable']!=$target_table) { unset($_SESSION[COOKIENAME.'sortRows']); unset($_SESSION[COOKIENAME.'orderRows']); } if(isset($_GET['viewtype'])) { $_SESSION[COOKIENAME.'viewtype'] = $_GET['viewtype']; } //- Query execution if(!isset($_GET['sort'])) $_GET['sort'] = NULL; if(!isset($_GET['order'])) $_GET['order'] = NULL; $numRows = $params->numRows; $startRow = $_GET['startRow']; if(isset($_GET['sort'])) { $_SESSION[COOKIENAME.'sortRows'] = $_GET['sort']; $_SESSION[COOKIENAME.'currentTable'] = $target_table; } if(isset($_GET['order'])) { $_SESSION[COOKIENAME.'orderRows'] = $_GET['order']; $_SESSION[COOKIENAME.'currentTable'] = $target_table; } $query = "SELECT * "; // select the primary key column(s) last (ROWID if there is no PK). // this will be used to identify rows, e.g. when editing/deleting rows $primary_key = $db->getPrimaryKey($target_table); foreach($primary_key as $pk) { $query.= ', '.$db->quote_id($pk); $query.= ', typeof('.$db->quote_id($pk).')'; } $query .= " FROM ".$db->quote_id($target_table); $queryDisp = "SELECT * FROM ".$db->quote_id($target_table); $queryCount = "SELECT COUNT(*) AS count FROM ".$db->quote_id($target_table); $queryAdd = ""; if(isset($search) && isset($search['where'])) { $queryAdd = $search['where']; $queryCount .= $search['where']; } if(isset($_SESSION[COOKIENAME.'sortRows'])) $queryAdd .= " ORDER BY ".$db->quote_id($_SESSION[COOKIENAME.'sortRows']); if(isset($_SESSION[COOKIENAME.'orderRows'])) $queryAdd .= " ".$_SESSION[COOKIENAME.'orderRows']; $queryAdd .= " LIMIT ".$startRow.", ".$numRows; $query .= $queryAdd; $queryDisp .= $queryAdd; $resultRows = $db->select($queryCount); $totalRows = $resultRows['count']; $shownRows = min($resultRows['count']-$startRow, $numRows); //- HTML: pagination buttons $lastPage = intval($totalRows / $params->numRows); $remainder = intval($totalRows % $params->numRows); if($remainder==0) $remainder = $params->numRows; echo "
    "; //previous button if($_GET['startRow']>0) { echo "
    "; echo $params->getForm(array('action'=>$_GET['action']),'get'); echo ""; echo " "; echo ""; echo "
    "; echo "
    "; echo $params->getForm(array('action'=>$_GET['action']),'get'); echo "numRows))."'/>"; echo " "; echo ""; echo "
    "; } //show certain number buttons echo "
    "; echo $params->getForm(array('action'=>$_GET['action'], 'numRows'=>null),'get'); echo " "; echo " "; echo $lang['rows_records']; if(intval($_GET['startRow']+$params->numRows) < $totalRows) echo "numRows)."'/>"; else echo " "; echo $lang['as_a']; echo " "; echo ""; echo "
    "; //next button if(intval($_GET['startRow']+$params->numRows)<$totalRows) { echo "
    "; echo $params->getForm(array('action'=>$_GET['action']),'get'); echo "numRows)."'/>"; echo " "; echo ""; echo "
    "; echo "
    "; echo $params->getForm(array('action'=>$_GET['action']),'get'); echo ""; echo " "; echo ""; echo "
    "; } echo "
    "; echo "
    "; //- Show results if($shownRows>0) { $queryTimer = new MicroTimer(); $table_result = $db->query($query); $queryTimer->stop(); echo "
    "; echo "".$lang['showing_rows']." ".$startRow." - ".($startRow + $shownRows-1).", ".$lang['total'].": ".$totalRows." "; printf($lang['query_time'], $queryTimer); echo "
    "; echo "".htmlencode($queryDisp).""; echo "

    "; if($target_table_type == 'view') { echo sprintf($lang['readonly_tbl'], htmlencode($target_table))." https://en.wikipedia.org/wiki/View_(SQL)"; echo "

    "; } $tableInfo = $db->getTableInfo($target_table); $pkFirstCol = sizeof($tableInfo)+1; //- Table view if(!isset($_SESSION[COOKIENAME.'viewtype']) || $_SESSION[COOKIENAME.'viewtype']=="table") { echo $params->getForm(array('action'=>'row_editordelete'), 'post', false, 'checkForm'); echo ""; echo ""; echo ""; for($i=0; $i"; if(isset($_SESSION[COOKIENAME.'sortRows'])) $orderTag = ($_SESSION[COOKIENAME.'sortRows']==$tableInfo[$i]['name'] && $_SESSION[COOKIENAME.'orderRows']=="ASC") ? "DESC" : "ASC"; else $orderTag = "ASC"; echo $params->getLink(array('action'=>$_GET['action'], 'sort'=>$tableInfo[$i]['name'], 'order'=>$orderTag ), htmlencode($tableInfo[$i]['name'])); if(isset($_SESSION[COOKIENAME.'sortRows']) && $_SESSION[COOKIENAME.'sortRows']==$tableInfo[$i]['name']) echo (($_SESSION[COOKIENAME.'orderRows']=="ASC") ? " " : " "); echo ""; } echo ""; for($i=0; $row = $db->fetch($table_result, 'num'); $i++) { // -g-> $pk will always be the last columns in each row of the array because we are doing "SELECT *, PK_1, typeof(PK_1), PK2, typeof(PK_2), ... FROM ..." $pk_arr = array(); for($col = $pkFirstCol; array_key_exists($col, $row); $col=$col+2) { // in $col we have the type and in $col-1 the value if($row[$col]=='integer' || $row[$col]=='real') // json encode as int or float, not string $pk_arr[] = $row[$col-1]+0; else // encode as json string $pk_arr[] = $row[$col-1]; } $pk = json_encode($pk_arr); $tdWithClass = ""; if($target_table_type == 'table' && $db->isWritable() && $db->isDirWritable()) { echo $tdWithClass; echo ""; echo ""; echo $tdWithClass; // -g-> Here, we need to put the PK in as the link for both the edit and delete. echo $params->getLink(array('action'=>'row_editordelete', 'pk'=>$pk, 'type'=>'edit'),"".$lang['edit']."",'edit', $lang['edit']); echo ""; echo $tdWithClass; echo $params->getLink(array('action'=>'row_editordelete', 'pk'=>$pk, 'type'=>'delete'),"".$lang['del']."",'delete', $lang['del']); echo ""; } else { echo ""; } for($j=0; $jNULL"; elseif(preg_match('/^BLOB/i', $tableInfo[$j]['type'])) { echo "
    "; echo $params->getLink(array('action'=>'row_get_blob', 'confirm'=>1, 'pk'=>$pk, 'column'=>$tableInfo[$j]['name'], 'download_blob'=>1),$lang["download"]).' | '; echo $params->getLink(array('action'=>'row_get_blob', 'confirm'=>1, 'pk'=>$pk, 'column'=>$tableInfo[$j]['name'], 'download_blob'=>0),$lang["open_in_browser"],'','','_blank'); echo "
    "; echo 'Size: '.number_format(strlen($row[$j])).' Bytes'; echo "
    "; } elseif(isset($search)) echo markSearchWords(subString($row[$j]),$tableInfo[$j]['name'], $search); else echo htmlencode(subString($row[$j])); echo ""; } echo "
    "; } echo "
    "; echo "$_GET['action'], 'fulltexts'=>($params->fulltexts?0:1) ))."' title='".$lang[($params->fulltexts?'no_full_texts':'full_texts')]."'>"; echo "&".($params->fulltexts?'r':'l')."arr; T &".($params->fulltexts?'l':'r')."arr;"; echo "
    "; $tdWithClassLeft = ""; echo "
    "; if($target_table_type == 'table' && $db->isWritable() && $db->isDirWritable()) { echo "".$lang['chk_all']." / ".$lang['unchk_all']." ".$lang['with_sel'].": "; echo " "; echo ""; } echo ""; } else //- Chart view { if(!isset($_SESSION[COOKIENAME.$target_table.'chartlabels'])) { // No label-column set. Try to pick a text-column as label-column. for($i=0; $i
    Chart Settings"; echo $params->getForm(array('action'=>$_GET['action'])); echo $lang['chart_type'].": "; echo "

    "; echo $lang['lbl'].": "; echo "

    "; echo $lang['val'].": "; echo "

    "; echo ""; echo ""; echo ""; echo "
    "; //end chart view } } else //no rows - do nothing { echo "
    "; if(isset($search) || $totalRows>0) echo $lang['no_rows']."

    "; elseif($target_table_type == 'table') echo $lang['empty_tbl']." ".$params->getLink(array('action'=>'row_create'), $lang['click']) ." ".$lang['insert_rows'].'

    '; echo "".htmlencode($queryDisp).""; echo "

    "; } if(isset($search)) echo "

    ".$params->getLink(array('action'=>'table_search','search'=>null,'oldSearch' => (isset($_GET['search'])?$_GET['search']:null)), $lang['srch_again']); break; //- Create new row (=row_create) case "row_create": echo $params->getForm(array('action'=>'row_create'), 'get'); echo $lang['restart_insert']; echo " "; echo $lang['rows']; echo " "; echo ""; echo "
    "; echo $params->getForm(array('action'=>'row_create','confirm'=>'1'), 'post', true); $tableInfo = $db->getTableInfo($target_table); if(isset($_GET['newRows'])) $num = $_GET['newRows']; else $num = 1; echo ""; for($j=0; $j<$num; $j++) { if($j>0) echo "
    "; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; for($i=0; $i"; echo ""; echo $tdWithClassLeft; echo htmlencode($field); echo ""; echo $tdWithClassLeft; echo htmlencode($type); echo ""; echo $tdWithClassLeft; echo ""; echo ""; echo $tdWithClassLeft; if($tableInfo[$i]['notnull']==0) { if($value===NULL) echo ""; else echo ""; } echo ""; echo $tdWithClassLeft; if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") echo ""; elseif(preg_match('/^BLOB/', $type)) echo ""; else echo ""; echo ""; echo ""; } echo ""; echo ""; echo ""; echo "
    ".$lang['fld']."".$lang['type']."".$lang['func']."Null".$lang['val']."
    "; echo ""; echo "

    "; } echo ""; break; //- Edit or delete row (=row_editordelete) case "row_editordelete": if(isset($_POST['check'])) $pks = $_POST['check']; else if(isset($_GET['pk'])) $pks = array($_GET['pk']); else $pks[0] = ""; $str = implode(', ', $pks); if($str=="") //nothing was selected so show an error { echo "
    "; echo $lang['err'].": ".$lang['no_sel']; echo "
    "; echo "

    ".$params->getLink(array('action'=>'row_view'),$lang['return']); } else { if((isset($_POST['type']) && $_POST['type']=="edit") || (isset($_GET['type']) && $_GET['type']=="edit")) //edit { echo $params->getForm(array('action'=>'row_edit', 'confirm'=>'1', 'pk'=>json_encode($pks)),'post',true); $tableInfo = $db->getTableInfo($target_table); $primary_key = $db->getPrimaryKey($target_table); for($j=0; $jquote_id($target_table)." WHERE " . $db->wherePK($target_table, json_decode($pks[$j])); $result1 = $db->select($query, 'num'); echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; for($i=0; $i"; echo ""; echo $tdWithClassLeft; echo htmlencode($field); echo ""; echo $tdWithClassLeft; echo htmlencode($type); echo ""; echo $tdWithClassLeft; echo ""; echo ""; echo $tdWithClassLeft; if($tableInfo[$i]['notnull']==0) { if($value===NULL) echo ""; else echo ""; } echo ""; echo $tdWithClassLeft; if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") echo ""; elseif(preg_match('/^BLOB/', $type)) { if($value!==NULL) { echo ""; echo $params->getLink(array('action'=>'row_get_blob', 'confirm'=>1, 'pk'=>$pks[$j], 'column'=>$field, 'download_blob'=>1),$lang["download"]).' | '; echo $params->getLink(array('action'=>'row_get_blob', 'confirm'=>1, 'pk'=>$pks[$j], 'column'=>$field, 'download_blob'=>0),$lang["open_in_browser"],'','','_blank').'
    '; echo ""; } echo ""; } else echo ""; echo ""; echo ""; } echo ""; echo ""; echo ""; echo "
    ".$lang['fld']."".$lang['type']."".$lang['func']."Null".$lang['val']."
    "; // Note: the 'Save changes' button must be first in the code so it is the one used when submitting the form with the Enter key (issue #215) echo " "; echo " "; echo $params->getLink(array('action'=>'row_view'), $lang['cancel']); echo "
    "; echo "
    "; } echo ""; } else //delete { echo $params->getForm(array('action'=>'row_delete', 'confirm'=>'1', 'pk'=>json_encode($pks))); echo "
    "; printf($lang['ques_del_rows'], htmlencode($str), htmlencode($target_table)); echo "

    "; echo " "; echo $params->getLink(array('action'=>'row_view'), $lang['cancel']); echo "
    "; } } break; //- Column actions //- View table structure (=column_view) case "column_view": $tableInfo = $db->getTableInfo($target_table); echo $params->getForm(array('action'=>'column_confirm'), 'get', false, 'checkForm'); echo ""; echo ""; if($target_table_type == 'table' && $db->isWritable() && $db->isDirWritable()) echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; $noPrimaryKey = true; for($i=0; $i"; $tdWithClassLeft = ""; if($target_table_type == 'table' && $db->isWritable() && $db->isDirWritable()) { echo $tdWithClass; echo ""; echo ""; echo $tdWithClass; echo $params->getLink(array('action'=>'column_edit', 'pk'=>$fieldVal),"".$lang['edit']."",'edit', $lang['edit']); echo ""; echo $tdWithClass; echo $params->getLink(array('action'=>'column_confirm', 'action2'=>'column_delete', 'pk'=>$fieldVal),"".$lang['del']."",'delete', $lang['del']); echo ""; } echo $tdWithClass; echo htmlencode($colVal); echo ""; echo $tdWithClassLeft; echo htmlencode($fieldVal); echo ""; echo $tdWithClassLeft; echo htmlencode($typeVal); echo ""; echo $tdWithClassLeft; echo htmlencode($notnullVal); echo ""; echo $tdWithClassLeft; if($defaultVal===NULL) echo "".$lang['none'].""; elseif($defaultVal==="NULL") echo "NULL"; else echo htmlencode($defaultVal); echo ""; echo $tdWithClassLeft; echo htmlencode($primarykeyVal); echo ""; echo ""; } echo "
    ".$lang['col']." #".$lang['fld']."".$lang['type']."".$lang['not_null']."".$lang['def_val']."".$lang['prim_key']."
    "; echo "
    "; if($target_table_type == 'table' && $db->isWritable() && $db->isDirWritable()) { echo "".$lang['chk_all']." / ".$lang['unchk_all']." ".$lang['with_sel'].": "; echo " "; echo ""; } echo ""; if($target_table_type == 'table' && $db->isWritable() && $db->isDirWritable()) { echo "
    "; echo $params->getForm(array('action'=>'column_create'), 'get'); echo $lang['add']." ".$lang['tbl_end']." "; echo ""; } $query = "SELECT sql FROM sqlite_master WHERE name=".$db->quote($target_table); $master = $db->selectArray($query); echo "
    "; echo "
    "; echo "
    "; echo "".$lang['query_used_'.$target_table_type]."
    "; echo "".htmlencode($master[0]['sql']).""; echo "
    "; echo "
    "; if($target_table_type != 'view') { echo "


    "; $query = "PRAGMA index_list(".$db->quote_id($target_table).")"; $result = $db->selectArray($query); if(sizeof($result)>0) { echo "

    ".$lang['indexes'].":

    "; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; for($i=0; $iquote_id($result[$i]['name']).")"; $info = $db->selectArray($query); $span = sizeof($info); $tdWithClass = ""; echo $tdWithClassSpan; echo $params->getLink(array('action'=>'index_delete', 'pk'=>$result[$i]['name']), "".$lang['del']."", 'delete', $lang['del']); echo ""; echo $tdWithClassLeftSpan; echo $result[$i]['name']; echo ""; echo $tdWithClassLeftSpan; echo $unique; echo ""; for($j=0; $j<$span; $j++) { if($j!=0) echo ""; echo $tdWithClassLeft; echo htmlencode($info[$j]['seqno']); echo ""; echo $tdWithClassLeft; echo htmlencode($info[$j]['cid']); echo ""; echo $tdWithClassLeft; echo htmlencode($info[$j]['name']); echo ""; echo ""; } } echo "
    "; echo "".$lang['name']."".$lang['unique']."".$lang['seq_no']."".$lang['col']." #".$lang['fld']."
    "; $tdWithClassLeft = ""; $tdWithClassSpan = ""; $tdWithClassLeftSpan = ""; echo "


    "; } $query = "SELECT * FROM sqlite_master WHERE type='trigger' AND tbl_name=".$db->quote($target_table)." ORDER BY name"; $result = $db->selectArray($query); //print_r($result); if(sizeof($result)>0) { echo "

    ".$lang['triggers'].":

    "; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; for($i=0; $i"; echo ""; echo $tdWithClass; echo $params->getLink(array('action'=>'trigger_delete', 'pk'=>$result[$i]['name']), "".$lang['del']."", 'delete', $lang['del']); echo ""; echo $tdWithClass; echo htmlencode($result[$i]['name']); echo ""; echo $tdWithClass; echo htmlencode($result[$i]['sql']); echo ""; } echo "
    "; echo "".$lang['name']."".$lang['sql']."


    "; } if($db->isWritable() && $db->isDirWritable()) { echo $params->getForm(array('action'=>'index_create'),'get'); echo "
    "; echo $lang['create_index2']." ".$lang['cols']." "; echo "
    "; echo ""; echo $params->getForm(array('action'=>'trigger_create'),'get'); echo "
    "; echo $lang['create_trigger2']." "; echo "
    "; echo ""; } } break; //- Create column (=column_create) case "column_create": echo "

    ".sprintf($lang['new_fld'],htmlencode($_GET['table']))."

    "; if($_GET['tablefields']=="" || intval($_GET['tablefields'])<=0) echo $lang['specify_fields']; else if($_GET['table']=="") echo $lang['specify_tbl']; else { $num = intval($_GET['tablefields']); $name = $_GET['table']; echo $params->getForm(array('action'=>'column_create', 'confirm'=>'1')); echo ""; echo ""; echo ""; $headings = array($lang["fld"], $lang["type"], $lang["prim_key"]); if($db->getType() != "SQLiteDatabase") $headings[] = $lang["autoincrement"]; $headings[] = $lang["not_null"]; $headings[] = $lang["def_val"]; for($k=0; $k" . $headings[$k] . ""; echo ""; for($i=0; $i<$num; $i++) { $tdWithClass = ""; echo $tdWithClass; echo ""; echo ""; echo $tdWithClass; echo ""; echo ""; echo $tdWithClass; echo ""; echo ""; if($db->getType() != "SQLiteDatabase") { echo $tdWithClass; echo ""; echo ""; } echo $tdWithClass; echo ""; echo ""; echo $tdWithClass; echo ""; echo ""; echo ""; echo ""; } echo ""; echo ""; echo ""; echo "
    "; echo "
    "; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo "
    "; echo ""; } break; //- Delete column (=column_confirm) case "column_confirm": if(isset($_GET['check'])) $pks = $_GET['check']; elseif(isset($_GET['pk'])) $pks = array($_GET['pk']); else $pks = array(); if(sizeof($pks)==0) //nothing was selected so show an error { echo "
    "; echo $lang['err'].": ".$lang['no_sel']; echo "
    "; echo "

    "; echo $params->getLink(array('action'=>'column_view'), $lang['return']); } else { $str = $pks[0]; $pkVal = $pks[0]; for($i=1; $igetForm(array('action'=>$_GET['action2'], 'confirm'=>'1', 'pk'=>$pkVal)); echo "
    "; printf($lang['ques_'.$_GET['action2']], htmlencode($str), htmlencode($target_table)); echo "

    "; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo "
    "; } break; //- Edit column (=column_edit) case "column_edit": echo "

    ".sprintf($lang['edit_col'], htmlencode($_GET['pk']))." ".$lang['on_tbl']." '".htmlencode($target_table)."'

    "; echo $lang['sqlite_limit']."

    "; if(!isset($_GET['pk'])) echo $lang['specify_col']; else if (!$target_table) echo $lang['specify_tbl']; else { $tableInfo = $db->getTableInfo($target_table); for($i=0; $i".$lang['err'].": ".sprintf($lang['col_inexistent'], htmlencode($_GET['pk']))."
    "; } else { $name = $target_table; echo $params->getForm(array('action'=>'column_edit', 'confirm'=>'1')); echo ""; echo ""; echo ""; //$headings = array("Field", "Type", "Primary Key", "Autoincrement", "Not NULL", "Default Value"); $headings = array($lang["fld"], $lang["type"]); for($k=0; $k".$headings[$k].""; echo ""; $i = 0; $tdWithClass = ""; echo $tdWithClass; echo ""; echo ""; echo $tdWithClass; echo ""; echo ""; /* echo $tdWithClass; if($primarykeyVal) echo " Yes"; else echo " Yes"; echo ""; echo $tdWithClass; if(1==2) echo " Yes"; else echo " Yes"; echo ""; echo $tdWithClass; if($notnullVal) echo " Yes"; else echo " Yes"; echo ""; echo $tdWithClass; echo ""; echo ""; */ echo ""; echo ""; echo ""; echo ""; echo "
    "; echo "
    "; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo "
    "; echo ""; } } break; //- Delete index (=index_delete) case "index_delete": echo $params->getForm(array('action'=>'index_delete', 'pk'=>$_GET['pk'], 'confirm'=>'1')); echo "
    "; echo sprintf($lang['ques_del_index'], htmlencode($_GET['pk']))."

    "; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo "
    "; echo ""; break; //- Delete trigger (=trigger_delete) case "trigger_delete": echo $params->getForm(array('action'=>'trigger_delete', 'pk'=>$_GET['pk'], 'confirm'=>'1')); echo "
    "; echo sprintf($lang['ques_del_trigger'], htmlencode($_GET['pk']))."

    "; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo "
    "; echo ""; break; //- Create trigger (=trigger_create) case "trigger_create": echo "

    ".$lang['create_trigger']." '".htmlencode($_GET['table'])."'

    "; if($_GET['table']=="") echo $lang['specify_tbl']; else { echo $params->getForm(array('action'=>'trigger_create', 'confirm'=>'1')); echo $lang['trigger_name'].":

    "; echo "
    ".$lang['db_event'].""; echo $lang['before']."/".$lang['after'].": "; echo ""; echo "

    "; echo $lang['event'].": "; echo ""; echo "


    "; echo "
    ".$lang['trigger_act'].""; echo "

    "; echo $lang['when_exp'].":
    "; echo ""; echo "

    "; echo $lang['trigger_step'].":
    "; echo ""; echo "


    "; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo ""; } break; //- Create index (=index_create) case "index_create": echo "

    ".$lang['create_index']." '".htmlencode($_GET['table'])."'

    "; if($_GET['numcolumns']=="" || intval($_GET['numcolumns'])<=0) echo $lang['specify_fields']; else if($_GET['table']=="") echo $lang['specify_tbl']; else { echo $params->getForm(array('action'=>'index_create', 'confirm'=>'1')); $num = intval($_GET['numcolumns']); $tableInfo = $db->getTableInfo($_GET['table']); echo "
    ".$lang['define_index'].""; echo "
    "; echo ""; echo "
    "; if(version_compare($db->getSQLiteVersion(),'3.8.0')>=0) echo " ".helpLink($lang['help10']); echo "
    "; echo "
    "; echo "
    ".$lang['define_in_col'].""; for($i=0; $i<$num; $i++) { echo " "; echo "
    "; } echo "
    "; echo "

    "; echo ""; echo " "; echo $params->getLink(array('action'=>'column_view'), $lang['cancel']); echo ""; } break; } echo ""; } //- HMTL: views for databases if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (isset($_GET['action']) && $_GET['action']!="table_create"))) //the absence of these fields means we are viewing the database homepage { //- Switch on $view (actually a series of if-else) if($view=="structure") { //- Database structure, shows all the tables (=structure) if($db->isWritable() && !$db->isDirWritable()) { echo "
    "; echo $lang['attention'].': '.$lang['directory_not_writable']; echo "

    "; } elseif(!$db->isWritable()) { echo "
    "; echo $lang['attention'].': '.$lang['database_not_writable']; echo "

    "; } if ($auth->isPasswordDefault()) { echo "
    "; echo sprintf($lang['warn_passwd'],(is_readable('phpliteadmin.config.php')?'phpliteadmin.config.php':basename(__FILE__)))."
    ".$lang['warn0']; echo "
    "; } echo "".$lang['db_name'].": ".htmlencode($db->getName())."
    "; echo "".$lang['db_path'].": ".htmlencode($db->getPath())."
    "; echo "".$lang['db_size'].": ".number_format($db->getSize())." KiB
    "; echo "".$lang['db_mod'].": ".$db->getDate()."
    "; echo "".$lang['sqlite_v'].": ".$db->getSQLiteVersion()."
    "; echo "".$lang['sqlite_ext']." ".helpLink($lang['help1']).": ".$db->getType()."
    "; echo "".$lang['php_v'].": ".phpversion()."
    "; echo "".PROJECT." ".$lang["ver"].": ".VERSION; echo "

    "; echo ""; if(isset($_GET['sort']) && ($_GET['sort']=='type' || $_GET['sort']=='name')) $_SESSION[COOKIENAME.'sortTables'] = $_GET['sort']; if(isset($_GET['order']) && ($_GET['order']=='ASC' || $_GET['order']=='DESC')) $_SESSION[COOKIENAME.'orderTables'] = $_GET['order']; if(!isset($_SESSION[COOKIENAME.'sortTables'])) $_SESSION[COOKIENAME.'sortTables'] = 'name'; if(!isset($_SESSION[COOKIENAME.'orderTables'])) $_SESSION[COOKIENAME.'orderTables'] = 'ASC'; $tables = $db->getTables(true, false, $_SESSION[COOKIENAME.'sortTables'], $_SESSION[COOKIENAME.'orderTables']); if(sizeof($tables)==0) echo $lang['no_tbl']."

    "; else { echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; $totalRecords = 0; $skippedTables = false; foreach($tables as $tableName => $tableType) { $records = $db->numRows($tableName, (!isset($_GET['forceCount']))); if($records == '?') { $skippedTables = true; $records = $params->getLink(array('forceCount'=>'1'), '?'); } else $totalRecords += $records; $tdWithClass = ""; echo $tdWithClassLeft; echo ($tableType=="table"? $lang['tbl'] : $lang['view']); echo ""; echo $tdWithClassLeft; echo $params->getLink(array('table'=>$tableName, 'action'=>'row_view'), htmlencode($tableName)); echo ""; echo $tdWithClass; echo $params->getLink(array('table'=>$tableName, 'action'=>'row_view'), $lang['browse']); echo ""; echo $tdWithClass; echo $params->getLink(array('table'=>$tableName, 'action'=>'column_view'), $lang['struct']); echo ""; echo $tdWithClass; echo $params->getLink(array('table'=>$tableName, 'action'=>'table_sql'), $lang['sql']); echo ""; echo $tdWithClass; echo $params->getLink(array('table'=>$tableName, 'action'=>'table_search'), $lang['srch']); echo ""; echo $tdWithClass; if($tableType=="table" && $db->isWritable() && $db->isDirWritable()) echo $params->getLink(array('table'=>$tableName, 'action'=>'row_create'), $lang['insert']); else echo $lang['insert']; echo ""; echo $tdWithClass; echo $params->getLink(array('table'=>$tableName, 'action'=>'table_export'), $lang['export']); echo ""; echo $tdWithClass; if($tableType=="table" && $db->isWritable() && $db->isDirWritable()) echo $params->getLink(array('table'=>$tableName, 'action'=>'table_import'), $lang['import']); else echo $lang['import']; echo ""; echo $tdWithClass; if($db->isWritable() && $db->isDirWritable()) echo $params->getLink(array('table'=>$tableName, 'action'=>'table_rename'), $lang['rename']); else echo $lang['rename']; echo ""; echo $tdWithClass; if($tableType=="table" && $db->isWritable() && $db->isDirWritable()) echo $params->getLink(array('table'=>$tableName, 'action'=>'table_empty'), $lang['empty'], 'empty'); else echo $lang['empty']; echo ""; echo $tdWithClass; if($db->isWritable() && $db->isDirWritable()) echo $params->getLink(array('table'=>$tableName, 'action'=>'table_drop'), $lang['drop'], 'drop'); else echo $lang['drop']; echo ""; echo $tdWithClass; echo $records; echo ""; echo ""; } echo ""; echo ""; echo ""; echo ""; echo "
    "; if(isset($_SESSION[COOKIENAME.'sortTables'])) $orderTag = ($_SESSION[COOKIENAME.'sortTables']=="type" && $_SESSION[COOKIENAME.'orderTables']=="ASC") ? "DESC" : "ASC"; else $orderTag = "ASC"; echo $params->getLink(array('sort'=>'type', 'order'=>$orderTag), $lang['type']); echo helpLink($lang['help3']); if(isset($_SESSION[COOKIENAME.'sortTables']) && $_SESSION[COOKIENAME.'sortTables']=="type") echo (($_SESSION[COOKIENAME.'orderTables']=="ASC") ? " " : " "); echo ""; if(isset($_SESSION[COOKIENAME.'sortTables'])) $orderTag = ($_SESSION[COOKIENAME.'sortTables']=="name" && $_SESSION[COOKIENAME.'orderTables']=="ASC") ? "DESC" : "ASC"; else $orderTag = "ASC"; echo $params->getLink(array('sort'=>'name', 'order'=>$orderTag), $lang['name']); if(isset($_SESSION[COOKIENAME.'sortTables']) && $_SESSION[COOKIENAME.'sortTables']=="name") echo (($_SESSION[COOKIENAME.'orderTables']=="ASC") ? " " : " "); echo "".$lang['act']."".$lang['rec']."
    "; $tdWithClassLeft = ""; echo "
    ".sizeof($tables)." ".$lang['total']."".$totalRecords.($skippedTables?" ".$params->getLink(array('forceCount'=>'1'),'+ ?'):"")."
    "; echo "
    "; if($skippedTables) echo "
    ".sprintf($lang["counting_skipped"],"'1'))."'>","")."
    "; } if($db->isWritable() && $db->isDirWritable()) { echo "
    "; echo "".$lang['create_tbl_db']." '".htmlencode($db->getName())."'"; echo $params->getForm(array('action'=>'table_create'), 'get'); echo $lang['name'].": "; echo $lang['fld_num'].": "; echo ""; echo ""; echo "
    "; echo "
    "; echo "
    "; echo "".$lang['create_view']." '".htmlencode($db->getName())."'"; echo $params->getForm(array('action'=>'view_create', 'confirm'=>'1')); echo $lang['name'].": "; echo $lang['sel_state']." ".helpLink($lang['help4']).": "; echo ""; echo ""; echo "
    "; } } else if($view=="sql") { //- Database SQL editor (=sql) if(isset($_POST['query']) && $_POST['query']!="") { $delimiter = $_POST['delimiter']; $queryStr = $_POST['queryval']; //save the queries in history if necessary if($maxSavedQueries!=0 && $maxSavedQueries!=false) { if(!isset($_SESSION[COOKIENAME.'query_history'])) $_SESSION[COOKIENAME.'query_history'] = array(); $_SESSION[COOKIENAME.'query_history'][md5(strtolower($queryStr))] = $queryStr; if(sizeof($_SESSION[COOKIENAME.'query_history']) > $maxSavedQueries) array_shift($_SESSION[COOKIENAME.'query_history']); } $query = explode_sql($delimiter, $queryStr); //explode the query string into individual queries based on the delimiter for($i=0; $iquery($query[$i]); echo "
    "; echo "".htmlencode($query[$i]).""; if($table_result === NULL || $table_result === false) { echo "
    ".$lang['err'].": ".htmlencode($db->getError())."
    "; } echo "
    "; if($row = $db->fetch($table_result, 'num')) { for($j=0; $jgetColumnName($table_result,$j); echo ""; echo ""; for($j=0; $j"; echo htmlencode($headers[$j]); echo ""; } echo ""; $rowCount = 0; for(; $rowCount==0 || $row = $db->fetch($table_result, 'num'); $rowCount++) { $tdWithClass = ""; for($z=0; $zNULL"; else echo htmlencode(subString($row[$z])); echo ""; } echo ""; } $queryTimer->stop(); echo "
    "; echo "


    "; if($table_result !== NULL && $table_result !== false) { echo "
    "; if($rowCount>0 || $db->getAffectedRows()==0) { printf($lang['show_rows'], $rowCount); } if($db->getAffectedRows()>0 || $rowCount==0) { echo $db->getAffectedRows()." ".$lang['rows_aff']." "; } printf($lang['query_time'], $queryTimer); echo "
    "; } } } } } else { $delimiter = ";"; $queryStr = ""; } echo "
    "; echo "".sprintf($lang['run_sql'],htmlencode($db->getName())).""; echo $params->getForm(array('view'=>'sql')); if(isset($_SESSION[COOKIENAME.'query_history']) && sizeof($_SESSION[COOKIENAME.'query_history'])>0) { echo "".$lang['recent_queries']."

    "; } echo ""; echo ""; echo $lang['delimit']." "; echo ""; echo ""; echo "
    "; } else if($view=="vacuum") { //- Vacuum database confirmation (=vacuum) if(isset($_POST['vacuum'])) { $query = "VACUUM"; $db->query($query); echo "
    "; printf($lang['db_vac'], htmlencode($db->getName())); echo "

    "; } echo $params->getForm(array('view'=>'vacuum')); printf($lang['vac_desc'],htmlencode($db->getName())); echo "

    "; echo ""; echo ""; } else if($view=="export") { //- Export view (=export) echo $params->getForm(array('view'=>'export')); echo "
    ".$lang['export'].""; echo ""; echo "

    "; echo ""; echo "
    "; echo "
    "; echo "
    ".$lang['options'].""; echo " ".helpLink($lang['help5'])."
    "; echo " ".helpLink($lang['help6'])."
    "; echo " ".helpLink($lang['help7'])."
    "; echo " ".helpLink($lang['help8'])."
    "; echo " ".helpLink($lang['help9'])."
    "; echo "
    "; echo ""; echo "
    "; echo "

    "; echo "
    ".$lang['save_as'].""; $file = pathinfo($db->getPath()); $name = $file['filename']; echo " "; echo "
    "; echo ""; echo "
    ".sprintf($lang['backup_hint'], $params->getLink(array('download'=>$currentDB['path'], 'token'=>$_SESSION[COOKIENAME.'token']), $lang["backup_hint_linktext"], '', $lang['backup']) )."
    "; } else if($view=="import") { //- Import view (=import) if(isset($_POST['import'])) { echo "
    "; if($importSuccess===true) echo $lang['import_suc']; else echo $importSuccess; echo "

    "; } echo $params->getForm(array('view'=>'import'), 'post', true); echo "
    ".$lang['import'].""; echo ""; echo "
    "; echo "
    "; echo "
    ".$lang['options'].""; echo $lang['no_opt']; echo "
    "; echo ""; echo "
    "; echo "

    "; echo "
    ".$lang['import_f'].""; echo "".$lang['max_file_size'].": ".number_format(fileUploadMaxSize()/1024/1024)." MiB ".helpLink($lang['help11'])."
    "; echo ""; echo ""; echo "
    "; } else if($view=="rename") { //- Rename database confirmation (=rename) echo $params->getForm(array('view'=>'rename', 'database_rename'=>'1')); echo ""; echo $lang['db_rename']." '".htmlencode($db->getPath())."' ".$lang['to']." "; echo ""; } else if($view=="delete") { //- Delete database confirmation (=delete) echo $params->getForm(array('database_delete'=>'1')); echo "
    "; echo sprintf($lang['ques_del_db'],htmlencode($db->getPath()))."

    "; echo ""; echo " "; echo $params->getLink(array(), $lang['cancel']); echo "
    "; echo ""; } echo ""; } echo ""; //- HTML: page footer echo "
    "; echo "".$lang['powered']." ".PROJECT." | "; echo $lang['free_software']." ".$lang['please_donate']." | "; printf($lang['page_gen'], $pageTimer); echo ""; echo ""; $db->close(); //close the database echo ""; echo ""; //- End of main code // Authorization class // Maintains user's logged-in state and security of application // class Authorization { private $authorized; private $login_failed; private $system_password_encrypted; public function __construct() { // first, make sure a CSRF token is generated $this->generateToken(); // second, check for possible CSRF attacks. to protect logins, this is done before checking login $this->checkToken(); // the salt and password encrypting is probably unnecessary protection but is done just // for the sake of being very secure if(!isset($_SESSION[COOKIENAME.'_salt']) && !isset($_COOKIE[COOKIENAME.'_salt'])) { // create a random salt for this session if a cookie doesn't already exist for it $_SESSION[COOKIENAME.'_salt'] = self::generateSalt(22); } else if(!isset($_SESSION[COOKIENAME.'_salt']) && isset($_COOKIE[COOKIENAME.'_salt'])) { // session doesn't exist, but cookie does so grab it $_SESSION[COOKIENAME.'_salt'] = $_COOKIE[COOKIENAME.'_salt']; } // salted and encrypted password used for checking $this->system_password_encrypted = md5(SYSTEMPASSWORD."_".$_SESSION[COOKIENAME.'_salt']); $this->authorized = // no password SYSTEMPASSWORD == '' // correct password stored in session || isset($_SESSION[COOKIENAME.'password']) && hash_equals($_SESSION[COOKIENAME.'password'], $this->system_password_encrypted) // correct password stored in cookie || isset($_COOKIE[COOKIENAME]) && isset($_COOKIE[COOKIENAME.'_salt']) && hash_equals(md5(SYSTEMPASSWORD."_".$_COOKIE[COOKIENAME.'_salt']), $_COOKIE[COOKIENAME]); } public function attemptGrant($password, $remember) { $hashed_password = crypt(SYSTEMPASSWORD, '$2a$07$'.self::generateSalt(22).'$'); if (hash_equals($hashed_password, crypt($password, $hashed_password))) { if ($remember) { // user wants to be remembered, so set a cookie $expire = time()+60*60*24*30; //set expiration to 1 month from now setcookie(COOKIENAME, $this->system_password_encrypted, $expire, null, null, null, true); setcookie(COOKIENAME."_salt", $_SESSION[COOKIENAME.'_salt'], $expire, null, null, null, true); } else { // user does not want to be remembered, so destroy any potential cookies setcookie(COOKIENAME, "", time()-86400, null, null, null, true); setcookie(COOKIENAME."_salt", "", time()-86400, null, null, null, true); unset($_COOKIE[COOKIENAME]); unset($_COOKIE[COOKIENAME.'_salt']); } $_SESSION[COOKIENAME.'password'] = $this->system_password_encrypted; $this->authorized = true; return true; } $this->login_failed = true; return false; } public function revoke() { //destroy everything - cookies and session vars setcookie(COOKIENAME, "", time()-86400, null, null, null, true); setcookie(COOKIENAME."_salt", "", time()-86400, null, null, null, true); unset($_COOKIE[COOKIENAME]); unset($_COOKIE[COOKIENAME.'_salt']); session_unset(); session_destroy(); $this->authorized = false; // start a new session and generate a new CSRF token for the login form session_start(); $this->generateToken(); } public function isAuthorized() { return $this->authorized; } public function isFailedLogin() { return $this->login_failed; } public function isPasswordDefault() { return SYSTEMPASSWORD == 'admin'; } private static function generateSalt($saltSize) { $set = 'ABCDEFGHiJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $setLast = strlen($set) - 1; $salt = ''; while ($saltSize-- > 0) { $salt .= $set[mt_rand(0, $setLast)]; } return $salt; } private function generateToken() { // generate CSRF token if (empty($_SESSION[COOKIENAME.'token'])) { if (function_exists('random_bytes')) // introduced in PHP 7.0 { $_SESSION[COOKIENAME.'token'] = bin2hex(random_bytes(32)); } elseif (function_exists('openssl_random_pseudo_bytes')) // introduced in PHP 5.3.0 { $_SESSION[COOKIENAME.'token'] = bin2hex(openssl_random_pseudo_bytes(32)); } else { // For PHP 5.2.x - This case can be removed once we drop support for 5.2.x $_SESSION[COOKIENAME.'token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); } } } private function checkToken() { // checking CSRF token if($_SERVER['REQUEST_METHOD'] === 'POST' || isset($_GET['download'])) // all POST forms need tokens! downloads are protected as well { if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['token'])) $check_token=$_POST['token']; elseif($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['token'])) $check_token=$_GET['token']; if (!isset($check_token)) { die("CSRF token missing"); } elseif(!hash_equals($_SESSION[COOKIENAME.'token'], $check_token)) { die("CSRF token is wrong - please try to login again"); } } } } // Database class // Generic database abstraction class to manage interaction with database without worrying about SQLite vs. PHP versions // class Database { protected $db; //reference to the DB object protected $type; //the extension for PHP that handles SQLite protected $data; protected $lastResult; protected $alterError; protected $debugOutput =''; public function __construct($data) { global $lang, $params; $this->data = $data; try { if(!file_exists($this->data["path"]) && !is_writable(dirname($this->data["path"]))) //make sure the containing directory is writable if the database does not exist { echo "
    "; printf($lang['db_not_writeable'], htmlencode($this->data["path"]), htmlencode(dirname($this->data["path"]))); echo $params->getForm(); echo ""; echo ""; echo "

    "; exit(); } $ver = $this->getVersion(); switch(true) { case ((!isset($data['type']) || $data['type']!=2) && (FORCETYPE=="PDO" || (FORCETYPE==false && class_exists("PDO") && in_array("sqlite", PDO::getAvailableDrivers()) && ($ver==-1 || $ver==3)))): $this->db = new PDO("sqlite:".$this->data['path']); if($this->db!=NULL) { $this->type = "PDO"; break; } case ((!isset($data['type']) || $data['type']!=2) && (FORCETYPE=="SQLite3" || (FORCETYPE==false && class_exists("SQLite3") && ($ver==-1 || $ver==3)))): $this->db = new SQLite3($this->data['path']); if($this->db!=NULL) { $this->type = "SQLite3"; break; } case (FORCETYPE=="SQLiteDatabase" || (FORCETYPE==false && class_exists("SQLiteDatabase") && ($ver==-1 || $ver==2))): $this->db = new SQLiteDatabase($this->data['path']); if($this->db!=NULL) { $this->type = "SQLiteDatabase"; break; } default: $this->showError(); exit(); } $this->query("PRAGMA foreign_keys = ON"); } catch(Exception $e) { $this->showError(); exit(); } } public function registerUserFunction($ids) { // in case a single function id was passed if (is_string($ids)) $ids = array($ids); if ($this->type == 'PDO') { foreach ($ids as $id) { $this->db->sqliteCreateFunction($id, $id, -1); } } else { // type is Sqlite3 or SQLiteDatabase foreach ($ids as $id) { $this->db->createFunction($id, $id, -1); } } } public function getError($complete_msg = false) { global $lang, $debug; $error = "unknown"; if($this->alterError!='') { $error = $this->alterError; $this->alterError = ""; } else if($this->type=="PDO") { $e = $this->db->errorInfo(); $error = $e[2]; } else if($this->type=="SQLite3") { $error = $this->db->lastErrorMsg(); } else { $error = sqlite_error_string($this->db->lastError()); } if($complete_msg) { $error = $lang['err'].": ".htmlencode($error); // do not suggest to report a bug when constraints fail if(strpos($error, 'constraint failed')===false) $error.="
    ".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; } if($debug) $error .= $this->getDebugOutput(); return $error; } function getDebugOutput() { return ($this->debugOutput != "" ? "
    DEBUG:
    ".$this->debugOutput : $this->debugOutput); } public function showError() { global $lang; $classPDO = class_exists("PDO"); $classSQLite3 = class_exists("SQLite3"); $classSQLiteDatabase = class_exists("SQLiteDatabase"); if($classPDO) // PDO is there, check if the SQLite driver for PDO is missing $PDOSqliteDriver = (in_array("sqlite", PDO::getAvailableDrivers() )); else $PDOSqliteDriver = false; echo "
    "; printf($lang['db_setup'], $this->getPath()); echo ".

    ".$lang['chk_ext']."...

    "; echo "PDO: ".($classPDO ? $lang['installed'] : $lang['not_installed'])."
    "; echo "PDO SQLite Driver: ".($PDOSqliteDriver ? $lang['installed'] : $lang['not_installed'])."
    "; echo "SQLite3: ".($classSQLite3 ? $lang['installed'] : $lang['not_installed'])."
    "; echo "SQLiteDatabase: ".($classSQLiteDatabase ? $lang['installed'] : $lang['not_installed'])."
    "; echo "
    ...".$lang['done'].".


    "; if(!$classPDO && !$classSQLite3 && !$classSQLiteDatabase) printf($lang['sqlite_ext_support'], PROJECT); else { if(!$PDOSqliteDriver && !$classSQLite3 && $this->getVersion()==3) printf($lang['sqlite_v_error'], 3, PROJECT, 2); else if(!$classSQLiteDatabase && $this->getVersion()==2) printf($lang['sqlite_v_error'], 2, PROJECT, 3); else echo $lang['report_issue'].' '.PROJECT_BUGTRACKER_LINK.'.'; } echo "

    See ".PROJECT_INSTALL_LINK." for help.

    "; $this->print_db_list(); echo "
    "; } // print the list of databases public function print_db_list() { global $databases, $lang, $params, $currentDB; echo "
    ".$lang['db_ch'].""; if(sizeof($databases)<10) //if there aren't a lot of databases, just show them as a list of links instead of drop down menu { $i=0; foreach($databases as $database) { $i++; $name = $database['name']; if(mb_strlen($name)>25) $name = "...".mb_substr($name, mb_strlen($name)-22, 22); echo '[' . ($database['readable'] ? 'r':' ' ) . ($database['writable'] && $database['writable_dir'] ? 'w':' ' ) . '] '; echo $params->getLink(array('database'=>$database['path'], 'table'=>null), htmlencode($name), ($database == $currentDB? 'active_db': '') ); echo "  "; echo $params->getLink(array('download'=>$database['path'], 'table'=>null, 'token'=>$_SESSION[COOKIENAME.'token']), '[↓]', '', $lang['backup']); if($i"; } } else //there are a lot of databases - show a drop down menu { echo $params->getForm(array('table'=>null), 'get'); echo ""; echo ""; echo ""; } echo "
    "; } public function __destruct() { if($this->db) $this->close(); } //get the exact PHP extension being used for SQLite public function getType() { return $this->type; } // get the version of the SQLite library public function getSQLiteVersion() { $queryVersion = $this->select("SELECT sqlite_version() AS sqlite_version"); return $queryVersion['sqlite_version']; } //get the name of the database public function getName() { return $this->data["name"]; } //get the filename of the database public function getPath() { return $this->data["path"]; } //is the db-file writable? public function isWritable() { return $this->data["writable"]; } //is the db-folder writable? public function isDirWritable() { return $this->data["writable_dir"]; } //get the version of the database public function getVersion() { if(file_exists($this->data['path'])) //make sure file exists before getting its contents { $content = strtolower(file_get_contents($this->data['path'], NULL, NULL, 0, 40)); //get the first 40 characters of the database file $p = strpos($content, "** this file contains an sqlite 2"); //this text is at the beginning of every SQLite2 database if($p!==false) //the text is found - this is version 2 return 2; else return 3; } else //return -1 to indicate that it does not exist and needs to be created { return -1; } } //get the size of the database (in KiB) public function getSize() { return round(filesize($this->data["path"])*0.0009765625, 1); } //get the last modified time of database public function getDate() { global $lang; return date($lang['date_format'], filemtime($this->data['path'])); } //get number of affected rows from last query public function getAffectedRows() { if($this->type=="PDO") if(!is_object($this->lastResult)) // in case it was an alter table statement, there is no lastResult object return 0; else return $this->lastResult->rowCount(); else if($this->type=="SQLite3") return $this->db->changes(); else if($this->type=="SQLiteDatabase") return $this->db->changes(); } public function getTypeOfTable($table) { $result = $this->select("SELECT `type` FROM `sqlite_master` WHERE `name`=" . $this->quote($table), 'assoc'); return $result['type']; } public function getTableInfo($table) { return $this->selectArray("PRAGMA table_info(".$this->quote_id($table).")"); } // returns the list of tables (opt. incl. views) as // array( Tablename => tableType ) with tableType being 'view' or 'table' public function getTables($alsoViews=true, $alsoInternal=false, $orderBy='name', $orderDirection='ASC') { $query = "SELECT name, type FROM sqlite_master " . "WHERE (type='table'".($alsoViews?" OR type='view'":"").") " . "AND name!='' ".($alsoInternal? "":" AND name NOT LIKE 'sqlite_%' ") . "ORDER BY ".$this->quote_id($orderBy)." ".$orderDirection; $result = $this->selectArray($query); $list = array(); for($i=0; $i array(columName) ) public function getTableDefinitions() { $tables = $this->getTables(true, true); $result = array(); foreach ($tables as $tableName => $tableType) { $tableInfo = $this->getTableInfo($tableName); $columns = array(); foreach($tableInfo as $column) $columns[] = $column['name']; $result[$tableName] = $columns; } return $result; } public function close() { if($this->type=="PDO") $this->db = NULL; else if($this->type=="SQLite3") $this->db->close(); else if($this->type=="SQLiteDatabase") $this->db = NULL; } public function beginTransaction() { $this->query("BEGIN"); } public function commitTransaction() { $this->query("COMMIT"); } public function rollbackTransaction() { $this->query("ROLLBACK"); } //generic query wrapper //returns false on error and the query result on success public function query($query, $ignoreAlterCase=false) { global $debug; if(strtolower(substr(ltrim($query),0,5))=='alter' && $ignoreAlterCase==false) //this query is an ALTER query - call the necessary function { preg_match("/^\s*ALTER\s+TABLE\s+\"((?:[^\"]|\"\")+)\"\s+(.*)$/i",$query,$matches); if(!isset($matches[1]) || !isset($matches[2])) { if($debug) echo "SQL?
    "; return false; } $tablename = str_replace('""','"',$matches[1]); $alterdefs = $matches[2]; if($debug) echo "ALTER TABLE QUERY=(".htmlencode($query)."), tablename=($tablename), alterdefs=($alterdefs)
    "; $result = $this->alterTable($tablename, $alterdefs); } else //this query is normal - proceed as normal { $result = $this->db->query($query); if($debug) echo "SQL?
    "; } if($result===false) return false; $this->lastResult = $result; return $result; } //wrapper for an INSERT and returns the ID of the inserted row public function insert($query) { $result = $this->query($query); if($this->type=="PDO") return $this->db->lastInsertId(); else if($this->type=="SQLite3") return $this->db->lastInsertRowID(); else if($this->type=="SQLiteDatabase") return $this->db->lastInsertRowid(); } //returns an array for SELECT public function select($query, $mode="both") { $result = $this->query($query); if(!$result) //make sure the result is valid return NULL; if($this->type=="PDO") { if($mode=="assoc") $mode = PDO::FETCH_ASSOC; else if($mode=="num") $mode = PDO::FETCH_NUM; else $mode = PDO::FETCH_BOTH; $ret = $result->fetch($mode); $result->closeCursor(); return $ret; } else if($this->type=="SQLite3") { if($mode=="assoc") $mode = SQLITE3_ASSOC; else if($mode=="num") $mode = SQLITE3_NUM; else $mode = SQLITE3_BOTH; $ret = $result->fetchArray($mode); $result->finalize(); return $ret; } else if($this->type=="SQLiteDatabase") { if($mode=="assoc") $mode = SQLITE_ASSOC; else if($mode=="num") $mode = SQLITE_NUM; else $mode = SQLITE_BOTH; return $result->fetch($mode); } } //returns an array of arrays after doing a SELECT public function selectArray($query, $mode="both") { $result = $this->query($query); //make sure the result is valid if($result=== false || $result===NULL) return NULL; // error if(!is_object($result)) // no rows returned return array(); if($this->type=="PDO") { if($mode=="assoc") $mode = PDO::FETCH_ASSOC; else if($mode=="num") $mode = PDO::FETCH_NUM; else $mode = PDO::FETCH_BOTH; $ret = $result->fetchAll($mode); $result->closeCursor(); return $ret; } else if($this->type=="SQLite3") { if($mode=="assoc") $mode = SQLITE3_ASSOC; else if($mode=="num") $mode = SQLITE3_NUM; else $mode = SQLITE3_BOTH; $arr = array(); $i = 0; while($res = $result->fetchArray($mode)) { $arr[$i] = $res; $i++; } $result->finalize(); return $arr; } else if($this->type=="SQLiteDatabase") { if($mode=="assoc") $mode = SQLITE_ASSOC; else if($mode=="num") $mode = SQLITE_NUM; else $mode = SQLITE_BOTH; return $result->fetchAll($mode); } } //returns an array of the next row in $result public function fetch($result, $mode="both") { //make sure the result is valid if($result=== false || $result===NULL) return NULL; // error if(!is_object($result)) // no rows returned return array(); if($this->type=="PDO") { if($mode=="assoc") $mode = PDO::FETCH_ASSOC; else if($mode=="num") $mode = PDO::FETCH_NUM; else $mode = PDO::FETCH_BOTH; return $result->fetch($mode); } else if($this->type=="SQLite3") { if($mode=="assoc") $mode = SQLITE3_ASSOC; else if($mode=="num") $mode = SQLITE3_NUM; else $mode = SQLITE3_BOTH; return $result->fetchArray($mode); } else if($this->type=="SQLiteDatabase") { if($mode=="assoc") $mode = SQLITE_ASSOC; else if($mode=="num") $mode = SQLITE_NUM; else $mode = SQLITE_BOTH; return $result->fetch($mode); } } public function getColumnName($result, $colNum) { //make sure the result is valid if($result=== false || $result===NULL || !is_object($result)) return ""; // error or no rows returned if($this->type=="PDO") { $meta = $result->getColumnMeta($colNum); return $meta['name']; } else if($this->type=="SQLite3") { return $result->columnName($colNum); } else if($this->type=="SQLiteDatabase") { return $result->fieldName($colNum); } } // SQlite supports multiple ways of surrounding names in quotes: // single-quotes, double-quotes, backticks, square brackets. // As sqlite does not keep this strict, we also need to be flexible here. // This function generates a regex that matches any of the possibilities. private function sqlite_surroundings_preg($name,$preg_quote=true,$notAllowedCharsIfNone="'\"",$notAllowedName=false) { if($name=="*" || $name=="+") { if($notAllowedName!==false && $preg_quote) $notAllowedName = preg_quote($notAllowedName,"/"); // use possesive quantifiers to save memory // (There is a bug in PCRE starting in 8.13 and fixed in PCRE 8.36 // why we can't use posesive quantifiers - See issue #310). if(version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.36', '>=') || version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.12', '<=')) $posessive='+'; else $posessive=''; $nameSingle = ($notAllowedName!==false?"(?!".$notAllowedName."')":"")."(?:[^']$name+|'')$name".$posessive; $nameDouble = ($notAllowedName!==false?"(?!".$notAllowedName."\")":"")."(?:[^\"]$name+|\"\")$name".$posessive; $nameBacktick = ($notAllowedName!==false?"(?!".$notAllowedName."`)":"")."(?:[^`]$name+|``)$name".$posessive; $nameSquare = ($notAllowedName!==false?"(?!".$notAllowedName."\])":"")."(?:[^\]]$name+|\]\])$name".$posessive; $nameNo = ($notAllowedName!==false?"(?!".$notAllowedName."\s)":"")."[^".$notAllowedCharsIfNone."]$name"; } else { if($preg_quote) $name = preg_quote($name,"/"); $nameSingle = str_replace("'","''",$name); $nameDouble = str_replace('"','""',$name); $nameBacktick = str_replace('`','``',$name); $nameSquare = str_replace(']',']]',$name); $nameNo = $name; } $preg = "(?:'".$nameSingle."'|". // single-quote surrounded or not in quotes (correct SQL for values/new names) $nameNo."|". // not surrounded (correct SQL if not containing reserved words, spaces or some special chars) "\"".$nameDouble."\"|". // double-quote surrounded (correct SQL for identifiers) "`".$nameBacktick."`|". // backtick surrounded (MySQL-Style) "\[".$nameSquare."\])"; // square-bracket surrounded (MS Access/SQL server-Style) return $preg; } // Returns the last PREG error as a string, '' if no error occured private function getPregError() { $error = preg_last_error(); switch ($error) { case PREG_NO_ERROR: return 'No error'; case PREG_INTERNAL_ERROR: return 'There is an internal error!'; case PREG_BACKTRACK_LIMIT_ERROR: return 'Backtrack limit was exhausted!'; case PREG_RECURSION_LIMIT_ERROR: return 'Recursion limit was exhausted!'; case PREG_BAD_UTF8_ERROR: return 'Bad UTF8 error!'; // PREG_BAD_UTF8_OFFSET_ERROR is introduced in PHP 5.3.0, which is not yet required by PLA, so we use its value 5 instead so long case 5: return 'Bad UTF8 offset error!'; default: return 'Unknown Error'; } } // function that is called for an alter table statement in a query // code borrowed with permission from http://code.jenseng.com/db/ // this has been completely debugged / rewritten by Christopher Kramer public function alterTable($table, $alterdefs) { global $debug, $lang; $this->alterError=""; $errormsg = sprintf($lang['alter_failed'],htmlencode($table)).' - '; if($debug) $this->debugOutput .= "ALTER TABLE: table=($table), alterdefs=($alterdefs), PCRE version=(".PCRE_VERSION.")

    "; if($alterdefs != '') { $recreateQueries = array(); $resultArr = $this->selectArray("SELECT sql,name,type FROM sqlite_master WHERE tbl_name = ".$this->quote($table)); if(sizeof($resultArr)<1) { $this->alterError = $errormsg . sprintf($lang['tbl_inexistent'], htmlencode($table)); if($debug) $this->debugOutput .= "ERROR: unknown table

    "; return false; } for($i=0; $idebugOutput .= "recreate=(".$row['sql'].";)
    "; } } elseif($row['type']=='view') // workaround to rename views { $origsql = $row['sql']; $preg_remove_create_view = "/^\s*+CREATE\s++VIEW\s++".$this->sqlite_surroundings_preg($table)."\s*+(AS\s++SELECT\s++.*+)$/is"; $origsql_no_create = preg_replace($preg_remove_create_view, '$1', $origsql, 1); if($debug) $this->debugOutput .= "origsql=($origsql)
    preg_remove_create_table=($preg_remove_create_view)
    "; preg_match("/RENAME\s++TO\s++(?:\"((?:[^\"]|\"\")+)\"|'((?:[^']|'')+)')/is", $alterdefs, $matches); if(isset($matches[1]) && $matches[1]!='') $newname = $matches[1]; elseif(isset($matches[2]) && $matches[2]!='') $newname = $matches[2]; else { $this->alterError = $errormsg . ' could not detect new view name. It needs to be in single or double quotes.'; if($debug) $this->debugOutput .= "ERROR: could not detect new view name
    "; return false; } $dropoldSQL = 'DROP VIEW '.$this->quote_id($table); $createnewSQL = 'CREATE VIEW '.$this->quote_id($newname).' '.$origsql_no_create; $alter_transaction = 'BEGIN; ' . $dropoldSQL .'; '. $createnewSQL . '; ' . 'COMMIT;'; if($debug) $this->debugOutput .= $alter_transaction; return $this->multiQuery($alter_transaction); } else { // ALTER the table $tmpname = 't'.time(); $origsql = $row['sql']; $preg_remove_create_table = "/^\s*+CREATE\s++TABLE\s++".$this->sqlite_surroundings_preg($table)."\s*+(\(.*+)$/is"; $origsql_no_create = preg_replace($preg_remove_create_table, '$1', $origsql, 1); if($debug) $this->debugOutput .= "origsql=($origsql)
    preg_remove_create_table=($preg_remove_create_table)
    "; if($origsql_no_create == $origsql) { $this->alterError = $errormsg . $lang['alter_tbl_name_not_replacable']; if($debug) $this->debugOutput .= "ERROR: could not get rid of CREATE TABLE
    "; return false; } $createtemptableSQL = "CREATE TABLE ".$this->quote($tmpname)." ".$origsql_no_create; if($debug) $this->debugOutput .= "createtemptableSQL=($createtemptableSQL)
    "; $createindexsql = array(); $preg_alter_part = "/(?:DROP(?! PRIMARY KEY)|ADD(?! PRIMARY KEY)|CHANGE|RENAME TO|ADD PRIMARY KEY|DROP PRIMARY KEY)" // the ALTER command ."(?:" ."\s+\(".$this->sqlite_surroundings_preg("+",false,"\"'\[`)")."+\)" // stuff in brackets (in case of ADD PRIMARY KEY) ."|" // or ."\s+".$this->sqlite_surroundings_preg("+",false,",'\"\[`") // column names and stuff like this .")*/i"; if($debug) $this->debugOutput .= "preg_alter_part=(".$preg_alter_part.")
    "; preg_match_all($preg_alter_part,$alterdefs,$matches); $defs = $matches[0]; $result_oldcols = $this->getTableInfo($table); $newcols = array(); $coltypes = array(); $primarykey = array(); foreach($result_oldcols as $column_info) { $newcols[$column_info['name']] = $column_info['name']; $coltypes[$column_info['name']] = $column_info['type']; if($column_info['pk']) $primarykey[] = $column_info['name']; } $newcolumns = ''; $oldcolumns = ''; reset($newcols); while(list($key, $val) = each($newcols)) { $newcolumns .= ($newcolumns?', ':'').$this->quote_id($val); $oldcolumns .= ($oldcolumns?', ':'').$this->quote_id($key); } $copytotempsql = 'INSERT INTO '.$this->quote_id($tmpname).'('.$newcolumns.') SELECT '.$oldcolumns.' FROM '.$this->quote_id($table); $dropoldsql = 'DROP TABLE '.$this->quote_id($table); $createtesttableSQL = $createtemptableSQL; if(count($defs)<1) { $this->alterError = $errormsg . $lang['alter_no_def']; if($debug) $this->debugOutput .= "ERROR: defs<1

    "; return false; } foreach($defs as $def) { if($debug) $this->debugOutput .= "
    def=$def
    "; $preg_parse_def = "/^(DROP(?! PRIMARY KEY)|ADD(?! PRIMARY KEY)|CHANGE|RENAME TO|ADD PRIMARY KEY|DROP PRIMARY KEY)" // $matches[1]: command ."(?:" // this is either ."(?:\s+\((.+)\)\s*$)" // anything in brackets (for ADD PRIMARY KEY) // then $matches[2] is what there is in brackets ."|" // OR: ."(?:\s+\"((?:[^\"]|\"\")+)\"|\s+'((?:[^']|'')+)')"// (first) column name, either in single or double quotes // in case of RENAME TO, it is the new a table name // $matches[3] will be the column/table name without the quotes if double quoted // $matches[4] will be the column/table name without the quotes if single quoted ."(" // $matches[5]: anything after the column name ."(?:\s+'((?:[^']|'')+)')?" // $matches[6] (optional): a second column name surrounded with single quotes // (the match does not contain the quotes) ."\s*" ."((?:[A-Z]+\s*)+(?:\(\s*[+-]?\s*[0-9]+(?:\s*,\s*[+-]?\s*[0-9]+)?\s*\))?)?\s*" // $matches[7] (optional): a type name .".*". ")" ."?\s*$" .")?\s*$/i"; // in case of DROP PRIMARY KEY, there is nothing after the command if($debug) $this->debugOutput .= "preg_parse_def=$preg_parse_def
    "; $parse_def = preg_match($preg_parse_def,$def,$matches); if($parse_def===false) { $this->alterError = $errormsg . $lang['alter_parse_failed']; if($debug) $this->debugOutput .= "ERROR: !parse_def

    "; return false; } if(!isset($matches[1])) { $this->alterError = $errormsg . $lang['alter_action_not_recognized']; if($debug) $this->debugOutput .= "ERROR: !isset(matches[1])

    "; return false; } $action = strtolower($matches[1]); if(($action == 'add' || $action == 'rename to') && isset($matches[4]) && $matches[4]!='') $column = str_replace("''","'",$matches[4]); // enclosed in '' elseif($action == 'add primary key' && isset($matches[2]) && $matches[2]!='') $column = $matches[2]; elseif($action == 'drop primary key') $column = ''; // DROP PRIMARY KEY has no column definition elseif(isset($matches[3]) && $matches[3]!='') $column = str_replace('""','"',$matches[3]); // enclosed in "" else $column = ''; $column_escaped = str_replace("'","''",$column); if($debug) $this->debugOutput .= "action=($action), column=($column), column_escaped=($column_escaped)
    "; /* we build a regex that devides the CREATE TABLE statement parts: Part example Group Explanation 1. CREATE TABLE t... ( $1 2. 'col1' ..., 'col2' ..., 'colN' ..., $3 (with col1-colN being columns that are not changed and listed before the col to change) 3. 'colX' ..., (with colX being the column to change/drop) 4. 'colX+1' ..., ..., 'colK') $5 (with colX+1-colK being columns after the column to change/drop) */ $preg_create_table = "\s*+(CREATE\s++TABLE\s++".preg_quote($this->quote($tmpname),"/")."\s*+\()"; // This is group $1 (keep unchanged) $preg_column_definiton = "\s*+".$this->sqlite_surroundings_preg("+",true," '\"\[`,",$column)."(?:\s*+".$this->sqlite_surroundings_preg("*",false,"'\",`\[ ").")++"; // catches a complete column definition, even if it is // 'column' TEXT NOT NULL DEFAULT 'we have a comma, here and a double ''quote!' // this definition does NOT match columns with the column name $column if($debug) $this->debugOutput .= "preg_column_definition=(".$preg_column_definiton.")
    "; $preg_columns_before = // columns before the one changed/dropped (keep) "(?:". "(". // group $2. Keep this one unchanged! "(?:". "$preg_column_definiton,\s*+". // column definition + comma ")*". // there might be any number of such columns here $preg_column_definiton. // last column definition ")". // end of group $2 ",\s*+" // the last comma of the last column before the column to change. Do not keep it! .")?"; // there might be no columns before if($debug) $this->debugOutput .= "preg_columns_before=(".$preg_columns_before.")
    "; $preg_columns_after = "(,\s*(.+))?"; // the columns after the column to drop. This is group $3 (drop) or $4(change) (keep!) // we could remove the comma using $6 instead of $5, but then we might have no comma at all. // Keeping it leaves a problem if we drop the first column, so we fix that case in another regex. $table_new = $table; switch($action) { case 'add': if($column=='') { $this->alterError = $errormsg . ' (add) - '. $lang['alter_no_add_col']; return false; } $new_col_definition = "'$column_escaped' ".(isset($matches[5])?$matches[5]:''); $preg_pattern_add = "/^".$preg_create_table. // the CREATE TABLE statement ($1) "((?:(?!,\s*(?:PRIMARY\s+KEY\s*\(|CONSTRAINT\s|UNIQUE\s*\(|CHECK\s*\(|FOREIGN\s+KEY\s*\()).)*)". // column definitions ($2) "(.*)\\)\s*$/si"; // table-constraints like PRIMARY KEY(a,b) ($3) and the closing bracket // append the column definiton in the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_add, '$1$2, '.strtr($new_col_definition, array('\\' => '\\\\', '$' => '\$')).' $3', $createtesttableSQL).')'; $preg_error = $this->getPregError(); if($debug) { $this->debugOutput .= $createtesttableSQL."

    "; $this->debugOutput .= $newSQL."

    "; $this->debugOutput .= $preg_pattern_add."

    "; } if($newSQL==$createtesttableSQL) // pattern did not match, so column adding did not succed { $this->alterError = $errormsg . ' (add) - '.$lang['alter_pattern_mismatch'].'. PREG ERROR: '.$preg_error; return false; } $createtesttableSQL = $newSQL; break; case 'change': var_dump($matches); if(!isset($matches[6])) { $this->alterError = $errormsg . ' (change) - '.$lang['alter_col_not_recognized']; return false; } $new_col_name = $matches[6]; if(!isset($matches[7])) $new_col_type = ''; else $new_col_type = $matches[7]; $new_col_definition = "'$new_col_name' $new_col_type"; $preg_column_to_change = "\s*".$this->sqlite_surroundings_preg($column)."(?:\s+".preg_quote($coltypes[$column]).")?(\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\"`\[").")+)?"; // replace this part (we want to change this column) // group $3 contains the column constraints (keep!). the name & data type is replaced. $preg_pattern_change = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_change.$preg_columns_after."\s*\\)\s*$/s"; // replace the column definiton in the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_change, '$1$2,'.strtr($new_col_definition, array('\\' => '\\\\', '$' => '\$')).'$3$4)', $createtesttableSQL); $preg_error = $this->getPregError(); // remove comma at the beginning if the first column is changed // probably somebody is able to put this into the first regex (using lookahead probably). $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { $this->debugOutput .= "preg_column_to_change=(".$preg_column_to_change.")

    "; $this->debugOutput .= $createtesttableSQL."

    "; $this->debugOutput .= $newSQL."

    "; $this->debugOutput .= $preg_pattern_change."

    "; } if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed { $this->alterError = $errormsg . ' (change) - '.$lang['alter_pattern_mismatch'].'. PREG ERROR: '.$preg_error; return false; } $createtesttableSQL = $newSQL; $newcols[$column] = str_replace("''","'",$new_col_name); break; case 'drop': $preg_column_to_drop = "\s*".$this->sqlite_surroundings_preg($column)."\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\"\[`").")+"; // delete this part (we want to drop this column) $preg_pattern_drop = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_drop.$preg_columns_after."\s*\\)\s*$/s"; // remove the column out of the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_drop, '$1$2$3)', $createtesttableSQL); $preg_error = $this->getPregError(); // remove comma at the beginning if the first column is removed // probably somebody is able to put this into the first regex (using lookahead probably). $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { $this->debugOutput .= $createtesttableSQL."

    "; $this->debugOutput .= $newSQL."

    "; $this->debugOutput .= $preg_pattern_drop."

    "; } if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed { $this->alterError = $errormsg . ' (drop) - '.$lang['alter_pattern_mismatch'].'. PREG ERROR: '.$preg_error; return false; } $createtesttableSQL = $newSQL; unset($newcols[$column]); break; case 'rename to': // don't change column definition at all $newSQL = $createtesttableSQL; // only change the name of the table $table_new = $column; break; case 'add primary key': // we want to add a primary key for the column(s) stored in $column $newSQL = preg_replace("/\)\s*$/", ", PRIMARY KEY (".$column.") )", $createtesttableSQL); $createtesttableSQL = $newSQL; break; case 'drop primary key': // we want to drop the primary key if($debug) $this->debugOutput .= "DROP"; if(sizeof($primarykey)==1) { // if not compound primary key, might be a column constraint -> try removal $column = $primarykey[0]; if($debug) $this->debugOutput .= "
    Trying to drop column constraint for column $column
    "; /* TODO: This does not work yet: CREATE TABLE 't12' ('t1' INTEGER CONSTRAINT "bla" NOT NULL CONSTRAINT 'pk' PRIMARY KEY ); ALTER TABLE "t12" DROP PRIMARY KEY This does: ! ! CREATE TABLE 't12' ('t1' INTEGER CONSTRAINT bla NOT NULL CONSTRAINT 'pk' PRIMARY KEY ); ALTER TABLE "t12" DROP PRIMARY KEY */ $preg_column_to_change = "(\s*".$this->sqlite_surroundings_preg($column).")". // column ($3) "(?:". // opt. type and column constraints "(\s+(?:".$this->sqlite_surroundings_preg("(?:[^PC,'\"`\[]|P(?!RIMARY\s+KEY)|". "C(?!ONSTRAINT\s+".$this->sqlite_surroundings_preg("+",false," ,'\"\[`")."\s+PRIMARY\s+KEY))",false,",'\"`\[").")*)". // column constraints before PRIMARY KEY ($3) // primary key constraint (remove this!): "(?:CONSTRAINT\s+".$this->sqlite_surroundings_preg("+",false," ,'\"\[`")."\s+)?". "PRIMARY\s+KEY". "(?:\s+(?:ASC|DESC))?". "(?:\s+ON\s+CONFLICT\s+(?:ROLLBACK|ABORT|FAIL|IGNORE|REPLACE))?". "(?:\s+AUTOINCREMENT)?". "((?:".$this->sqlite_surroundings_preg("*",false,",'\"`\[").")*)". // column constraints after PRIMARY KEY ($4) ")"; // replace this part (we want to change this column) // group $3 (column) $4 (constraints before) and $5 (constraints after) contain the part to keep $preg_pattern_change = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_change.$preg_columns_after."\s*\\)\s*$/si"; // replace the column definiton in the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_change, '$1$2,$3$4$5$6)', $createtesttableSQL); // remove comma at the beginning if the first column is changed // probably somebody is able to put this into the first regex (using lookahead probably). $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { $this->debugOutput .= "preg_column_to_change=(".$preg_column_to_change.")

    "; $this->debugOutput .= $createtesttableSQL."

    "; $this->debugOutput .= $newSQL."

    "; $this->debugOutput .= $preg_pattern_change."

    "; } if($newSQL!=$createtesttableSQL && $newSQL!="") // pattern did match, so PRIMARY KEY constraint removed :) { $createtesttableSQL = $newSQL; if($debug) $this->debugOutput .= "
    SUCCEEDED
    "; } else { if($debug) $this->debugOutput .= "NO LUCK"; // TODO: try removing table constraint return false; } $createtesttableSQL = $newSQL; } else // TODO: Try removing table constraint return false; break; default: if($debug) $this->debugOutput .= 'ERROR: unknown alter operation!

    '; $this->alterError = $errormsg . $lang['alter_unknown_operation']; return false; } } $droptempsql = 'DROP TABLE '.$this->quote_id($tmpname); $createnewtableSQL = "CREATE TABLE ".$this->quote($table_new)." ".preg_replace("/^\s*CREATE\s+TABLE\s+'?".str_replace("'","''",preg_quote($tmpname,"/"))."'?\s+(.*)$/is", '$1', $createtesttableSQL, 1); $newcolumns = ''; $oldcolumns = ''; reset($newcols); while(list($key,$val) = each($newcols)) { $newcolumns .= ($newcolumns?', ':'').$this->quote_id($val); $oldcolumns .= ($oldcolumns?', ':'').$this->quote_id($key); } $copytonewsql = 'INSERT INTO '.$this->quote_id($table_new).'('.$newcolumns.') SELECT '.$oldcolumns.' FROM '.$this->quote_id($tmpname); } } $alter_transaction = 'BEGIN; '; $alter_transaction .= $createtemptableSQL.'; '; //create temp table $alter_transaction .= $copytotempsql.'; '; //copy to table $alter_transaction .= $dropoldsql.'; '; //drop old table $alter_transaction .= $createnewtableSQL.'; '; //recreate original table $alter_transaction .= $copytonewsql.'; '; //copy back to original table $alter_transaction .= $droptempsql.'; '; //drop temp table $preg_index="/^\s*(CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:".$this->sqlite_surroundings_preg("+",false," '\"\[`")."\s*)*ON\s+)(".$this->sqlite_surroundings_preg($table).")(\s*\((?:".$this->sqlite_surroundings_preg("+",false," '\"\[`")."\s*)*\)\s*)\s*$/i"; foreach($recreateQueries as $recreate_query) { if($recreate_query['type']=='index') { // this is an index. We need to make sure the index is not on a column that we drop. If it is, we drop the index as well. $indexInfos = $this->selectArray('PRAGMA index_info('.$this->quote_id($recreate_query['name']).')'); foreach($indexInfos as $indexInfo) { if(!isset($newcols[$indexInfo['name']])) { if($debug) $this->debugOutput .= 'Not recreating the following index:

    '.htmlencode($recreate_query['sql']).'

    '; // Index on a column that was dropped. Skip recreation. continue 2; } } } // TODO: In case we renamed a column on which there is an index, we need to recreate the index with the column name adjusted. // recreate triggers / indexes if($table == $table_new) { // we had no RENAME TO, so we can recreate indexes/triggers just like the original ones $alter_transaction .= $recreate_query['sql'].';'; } else { // we had a RENAME TO, so we need to exchange the table-name in the CREATE-SQL of triggers & indexes switch ($recreate_query['type']) { case 'index': $recreate_queryIndex = preg_replace($preg_index, '$1'.$this->quote_id(strtr($table_new, array('\\' => '\\\\', '$' => '\$'))).'$3 ', $recreate_query['sql']); if($recreate_queryIndex!=$recreate_query['sql'] && $recreate_queryIndex != NULL) $alter_transaction .= $recreate_queryIndex.';'; else { // the CREATE INDEX regex did not match. this normally should not happen if($debug) $this->debugOutput .= 'ERROR: CREATE INDEX regex did not match!?

    '; // just try to recreate the index originally (will fail most likely) $alter_transaction .= $recreate_query['sql'].';'; } break; case 'trigger': // TODO: IMPLEMENT $alter_transaction .= $recreate_query['sql'].';'; break; default: if($debug) $this->debugOutput .= 'ERROR: Unknown type '.htmlencode($recreate_query['type']).'

    '; $alter_transaction .= $recreate_query['sql'].';'; } } } $alter_transaction .= 'COMMIT;'; if($debug) $this->debugOutput .= $alter_transaction; return $this->multiQuery($alter_transaction); } } //multiple query execution //returns true on success, false otherwise. Use getError() to fetch the error. public function multiQuery($query) { if($this->type=="PDO") $success = $this->db->exec($query); else if($this->type=="SQLite3") $success = $this->db->exec($query); else $success = $this->db->queryExec($query, $error); return $success; } // checks whether a table has a primary key public function hasPrimaryKey($table) { $table_info = $this->getTableInfo($table); foreach($table_info as $row_id => $row_data) { if($row_data['pk']) { return true; } } return false; } // Returns an array of columns by which rows can be uniquely adressed. // For tables with a rowid column, this is always array('rowid') // for tables without rowid, this is an array of the primary key columns. public function getPrimaryKey($table) { $primary_key = array(); // check if this table has a rowid $getRowID = $this->select('SELECT ROWID FROM '.$this->quote_id($table).' LIMIT 0,1'); if(isset($getRowID[0])) // it has, so we prefer addressing rows by rowid return array('rowid'); else { // the table is without rowid, so use the primary key $table_info = $this->getTableInfo($table); if(is_array($table_info)) { foreach($table_info as $row_id => $row_data) { if($row_data['pk']) $primary_key[] = $row_data['name']; } } } return $primary_key; } // selects a row by a given key $pk, which is an array of values // for the columns by which a row can be adressed (rowid or primary key) public function wherePK($table, $pk) { $where = ""; $primary_key = $this->getPrimaryKey($table); foreach($primary_key as $pk_index => $column) { if($where!="") $where .= " AND "; $where .= $this->quote_id($column) . ' = '; if(is_int($pk[$pk_index]) || is_float($pk[$pk_index])) $where .= $pk[$pk_index]; else $where .= $this->quote($pk[$pk_index]); } return $where; } //get number of rows in table public function numRows($table, $dontTakeLong = false) { // as Count(*) can be slow on huge tables without PK, // if $dontTakeLong is set and the size is > 2MB only count() if there is a PK if(!$dontTakeLong || $this->getSize() <= 2000 || $this->hasPrimaryKey($table)) { $result = $this->select("SELECT Count(*) FROM ".$this->quote_id($table)); return $result[0]; } else { return '?'; } } //correctly escape a string to be injected into an SQL query public function quote($value) { if($this->type=="PDO") { // PDO quote() escapes and adds quotes return $this->db->quote($value); } else if($this->type=="SQLite3") { return "'".$this->db->escapeString($value)."'"; } else { return "'".sqlite_escape_string($value)."'"; } } //correctly escape an identifier (column / table / trigger / index name) to be injected into an SQL query public function quote_id($value) { // double-quotes need to be escaped by doubling them $value = str_replace('"','""',$value); return '"'.$value.'"'; } //import sql //returns true on success, error message otherwise public function import_sql($query) { $import = $this->multiQuery($query); if(!$import) return $this->getError(); else return true; } public function prepareQuery($query) { if($this->type=='PDO' || $this->type=='SQLite3') return $this->db->prepare($query); else { // here we are in trouble, SQLiteDatabase cannot prepare statements. // we need to emulate prepare as best as we can # todo: implement this return null; } } public function bindValue($handle, $parameter, $value, $type) { if($this->type=='SQLite3') { $types = array( 'bool'=>SQLITE3_INTEGER, 'int'=>SQLITE3_INTEGER, 'float'=>SQLITE3_FLOAT, 'text'=>SQLITE3_TEXT, 'blob'=>SQLITE3_BLOB, 'null'=>SQLITE3_NULL); if(!isset($types[$type])) $type = 'text'; // there is no SQLITE_BOOL, so check value and make sure it is 0/1 if($type=='bool') { if($value===1 || $value===true) $value=1; elseif($value===0 || $value===false) $value=0; else return false; } return $handle->bindValue($parameter, $value, $types[$type]); } if($this->type=='PDO') { $types = array( 'bool'=>PDO::PARAM_BOOL, 'int'=>PDO::PARAM_INT, 'float'=>PDO::PARAM_STR, 'text'=>PDO::PARAM_STR, 'blob'=>PDO::PARAM_LOB, 'null'=>PDO::PARAM_NULL); if(!isset($types[$type])) $type = 'text'; // there is no PDO::PARAM_FLOAT, so we check it ourself if($type=='float') { if(is_numeric($value)) $value = (float) $value; else return false; } return $handle->bindValue($parameter, $value, $types[$type]); } else # todo: workaround return false; } public function executePrepared($handle, $fetchResult=false) { if($this->type=='PDO') { $ok=$handle->execute(); if($fetchResult && $ok) { $res = $handle->fetchAll(); $handle->closeCursor(); return $res; } else { if($ok) $handle->closeCursor(); return $ok; } } elseif($this->type=='SQLite3') { $resultset=$handle->execute(); if($fetchResult && $resultset!==false) { $res = $resultset->fetchArray(); $resultset->finalize(); return $res; } else { if($resultset!==false) $resultset->finalize(); if($resultset===false) return false; else return true; } } else { #todo. return false; } } //import csv //returns true on success, error message otherwise public function import_csv($filename, $table, $field_terminate, $field_enclosed, $field_escaped, $null, $fields_in_first_row) { @set_time_limit(-1); $csv_handle = fopen($filename,'r'); $csv_insert = "BEGIN;\n"; $csv_number_of_rows = 0; // PHP requires enclosure defined, but has no problem if it was not used if($field_enclosed=="") $field_enclosed='"'; // PHP requires escaper defined if($field_escaped=="") $field_escaped='\\'; // support tab delimiters if($field_terminate=='\t') $field_terminate = "\t"; while($csv_handle!==false && !feof($csv_handle)) { $csv_data = fgetcsv($csv_handle, 0, $field_terminate, $field_enclosed, $field_escaped); if(is_array($csv_data) && ($csv_data[0] != NULL || count($csv_data)>1)) { $csv_number_of_rows++; if($csv_number_of_rows==1) { if($this->getTypeOfTable($table)!="table") { // First,Create a new table $csv_insert .="CREATE TABLE ".$this->quote($table)." ("; $number_of_cols = count($csv_data); foreach($csv_data as $csv_col => $csv_cell) { if($fields_in_first_row) $csv_insert .= $this->quote($csv_cell); else $csv_insert.= $this->quote("col{$csv_col}"); if($csv_col < $number_of_cols-1) $csv_insert .= ", "; } $csv_insert .=");"; } else { $number_of_cols = count($this->getTableInfo($table)); } if($fields_in_first_row) continue; } $csv_insert .= "INSERT INTO ".$this->quote_id($table)." VALUES ("; for($csv_col = 0; $csv_col < $number_of_cols; $csv_col++) { if(isset($csv_data[$csv_col])) $csv_cell = $csv_data[$csv_col]; else $csv_cell = $null; if($csv_cell == $null) $csv_insert .= "NULL"; else $csv_insert.= $this->quote($csv_cell); if($csv_col < $number_of_cols-1) $csv_insert .= ","; } $csv_insert .= ");\n"; if($csv_number_of_rows % 5000 == 0) { $csv_insert .= "COMMIT;\nBEGIN;\n"; } } } if($csv_handle === false) return "Error reading CSV file"; else { $csv_insert .= "COMMIT;"; fclose($csv_handle); $import = $this->multiQuery($csv_insert); if(!$import) return $this->getError(); else return true; } } //export csv public function export_csv($tables, $field_terminate, $field_enclosed, $field_escaped, $null, $crlf, $fields_in_first_row) { @set_time_limit(-1); // we use \r\n if the _client_ OS is windows (as the exported file is downloaded to the client), \n otherwise $crlf = (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Win')!==false ? "\r\n" : "\n"); $query = "SELECT * FROM sqlite_master WHERE type='table' or type='view' ORDER BY type DESC"; $result = $this->selectArray($query); for($i=0; $igetTableInfo($result[$i]['tbl_name']); $cols = array(); for($z=0; $zquote_id($result[$i]['tbl_name']); $table_result = $this->query($query); $firstRow=true; while($row = $this->fetch($table_result, "assoc")) { if(!$firstRow) echo $crlf; else $firstRow=false; for($y=0; $ygetPath().$crlf; echo "----".$crlf; } $query = "SELECT * FROM sqlite_master WHERE type='table' OR type='index' OR type='view' OR type='trigger' ORDER BY type='trigger', type='index', type='view', type='table'"; $result = $this->selectArray($query); if($transaction) echo "BEGIN TRANSACTION;".$crlf; //iterate through each table for($i=0; $iquote_id($result[$i]['name']).";".$crlf; } if($structure) { if($comments) { echo "\r\n----".$crlf; if($result[$i]['type']=="table" || $result[$i]['type']=="view") echo "-- ".ucfirst($result[$i]['type'])." ".$lang['struct_for']." ".$result[$i]['tbl_name'].$crlf; else // index or trigger echo "-- ".$lang['struct_for']." ".$result[$i]['type']." ".$result[$i]['name']." ".$lang['on_tbl']." ".$result[$i]['tbl_name'].$crlf; echo "----".$crlf; } echo $result[$i]['sql'].";".$crlf; } if($data && $result[$i]['type']=="table") { $query = "SELECT * FROM ".$this->quote_id($result[$i]['tbl_name']); $table_result = $this->query($query, "assoc"); if($comments) { $numRows = $this->numRows($result[$i]['tbl_name']); echo "\r\n----".$crlf; echo "-- ".$lang['data_dump']." ".$result[$i]['tbl_name'].", ".sprintf($lang['total_rows'], $numRows).$crlf; echo "----".$crlf; } $temp = $this->getTableInfo($result[$i]['tbl_name']); $cols = array(); $cols_quoted = array(); for($z=0; $zquote_id($temp[$z][1]); } while($row = $this->fetch($table_result)) { $vals = array(); for($y=0; $yquote($row[$cols[$y]]); } echo "INSERT INTO ".$this->quote_id($result[$i]['tbl_name'])." (".implode(",", $cols_quoted).") VALUES (".implode(",", $vals).");".$crlf; } } } } if($transaction) echo "COMMIT;".$crlf; } } class GetParameters { private $_fields; public function __construct(array $defaults = array()) { $this->_fields = $defaults; } public function __set($key, $value) { $this->_fields[$key] = $value; } public function __isset($key) { return isset($this->_fields[$key]); } public function __unset($key) { unset($this->_fields[$key]); } public function __get($key) { return $this->_fields[$key]; } public function getURL(array $assoc = array(), $html = true, $prefix='?') { $arg_sep = ($html?'&':'&'); return $prefix . http_build_query(array_merge($this->_fields, $assoc), '', $arg_sep); } public function getLink(array $assoc = array(), $content = '[ link ]', $class = '', $title = '', $target='') { return '' . $content . ''; } public function getForm(array $assoc = array(), $method = 'post', $upload = false, $name = '', $csrf = true) { $hidden = ''; if($method == 'get') { $url = ''; foreach(array_merge($this->_fields, $assoc) as $key => $value) { if(!is_null($value)) $hidden .= ' '; } } else $url = $this->getURL($assoc); if($csrf && $method == 'post') $hidden .= ''; return "
    " . $hidden; } public function redirect(array $assoc = array(), $message="") { if($message!="") { $_SESSION[COOKIENAME.'messages'][md5($message)] = $message; $url = $this->getURL(array_merge($assoc, array('message'=>md5($message))), false); } else $url = $this->getURL($assoc, false); $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http'); header("Location: ".$protocol."://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$url, true, 302); exit; } }// class MicroTimer (issue #146) // wraps calls to microtime(), calculating the elapsed time and rounding output // class MicroTimer { private $startTime, $stopTime; // creates and starts a timer function __construct() { $this->startTime = microtime(true); } // stops a timer public function stop() { $this->stopTime = microtime(true); } // returns the number of seconds from the timer's creation, or elapsed // between creation and call to ->stop() public function elapsed() { if ($this->stopTime) return round($this->stopTime - $this->startTime, 4); return round(microtime(true) - $this->startTime, 4); } // called when using a MicroTimer object as a string public function __toString() { return (string) $this->elapsed(); } } // class Resources (issue #157) // outputs secondary files, such as css and javascript // data is stored gzipped (gzencode) and encoded (base64_encode) // class Resources { // set this to the file containing getInternalResource; // currently unused in split mode; set to __FILE__ for built PLA. public static $embedding_file = __FILE__; private static $_resources = array( 'css' => array( 'mime' => 'text/css', 'data' => 'resources/phpliteadmin.css', ), 'javascript' => array( 'mime' => 'text/javascript', 'data' => 'resources/phpliteadmin.js', ), 'favicon' => array( 'mime' => 'image/x-icon', 'data' => 'resources/favicon.ico', 'base64' => 'true', ), ); // outputs the specified resource, if defined in this class. // the main script should do no further output after calling this function. public static function output($resource) { if (isset(self::$_resources[$resource])) { $res =& self::$_resources[$resource]; if (function_exists('getInternalResource') && $data = getInternalResource($res['data'])) { $filename = self::$embedding_file; } else { $filename = $res['data']; } // use last-modified time as etag; etag must be quoted $etag = '"' . filemtime($filename) . '"'; // check headers for matching etag; if etag hasn't changed, use the cached version if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) { header('HTTP/1.0 304 Not Modified'); return; } header('Etag: ' . $etag); // cache file for at most 30 days header('Cache-control: max-age=2592000'); // output resource header('Content-type: ' . $res['mime']); if (isset($data)) { if (isset($res['base64'])) { echo base64_decode($data); } else { echo $data; } } else { readfile($filename); } } } } // returns data from internal resources, available in single-file mode function getInternalResource($res) { $resources = array('resources/phpliteadmin.css'=>array(0=>0,1=>4059,),'resources/phpliteadmin.js'=>array(0=>4059,1=>4542,),'resources/favicon.ico'=>array(0=>8601,1=>1448,),); if (isset($resources[$res]) && $f = fopen(__FILE__, 'r')) { fseek($f, __COMPILER_HALT_OFFSET__ + $resources[$res][0]); $data = fread($f, $resources[$res][1]); fclose($f); return $data; } return false; } // resources embedded below, do not edit! __halt_compiler() ?>body{margin:0px;padding:0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#000;background-color:#e0ebf6;overflow:auto}.body_tbl td{padding:9px 2px 9px 9px}.left_td{width:100px}a{color:#03F;text-decoration:none;cursor:pointer}a:hover{color:#06F}hr{height:1px;border:0;color:#bbb;background-color:#bbb;width:100%}h1{margin:0px;padding:5px;font-size:24px;background-color:#f3cece;text-align:center;color:#000;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}#headerlinks{text-align:center;margin-bottom:10px;padding:5px 15px;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none;font-size:12px;background-color:#e0ebf6;font-weight:bold}h1 #version{color:#000;font-size:16px}h1 #logo{color:#000}h2{margin:0px;padding:0px;font-size:14px;margin-bottom:20px}input,select,textarea,.CodeMirror{font-family:Arial,Helvetica,sans-serif;background-color:#eaeaea;color:#03F;border-color:#03F;border-style:solid;border-width:1px;margin:5px;border-radius:5px;-moz-border-radius:5px;padding:3px}input.btn{cursor:pointer}input.btn:hover{background-color:#ccc}fieldset label{min-width:200px;display:block;float:left}fieldset{padding:15px;border-color:#03F;border-width:1px;border-style:solid;border-radius:5px;-moz-border-radius:5px;background-color:#f9f9f9}#container{padding:10px}#leftNav{min-width:250px;padding:0px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;padding-bottom:15px;border-radius:5px;-moz-border-radius:5px}.databaseList select{max-width:200px}.viewTable tr td{padding:1px}#loginBox{width:500px;margin-left:auto;margin-right:auto;margin-top:50px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;border-radius:5px;-moz-border-radius:5px}#main{border-color:#03F;border-width:1px;border-style:solid;padding:15px;background-color:#FFF;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-right-radius:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-moz-border-radius-topright:5px}.td1{background-color:#f9e3e3;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.td2{background-color:#f3cece;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.tdheader{border-color:#03F;border-width:1px;border-style:solid;font-weight:bold;font-size:12px;padding-left:10px;padding-right:10px;background-color:#e0ebf6;border-radius:5px;-moz-border-radius:5px}.confirm{border-color:#03F;border-width:1px;border-style:dashed;padding:15px;background-color:#e0ebf6}.tab{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;padding-bottom:4px;background-color:#eaeaea;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.tab_pressed{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;background-color:#FFF;cursor:default;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.helpq{font-size:11px;font-weight:normal}#help_container{padding:0px;font-size:12px;margin-left:auto;margin-right:auto;background-color:#fff}.help_outer{background-color:#FFF;padding:0px;height:300px;position:relative}.help_list{padding:10px;height:auto}.headd{font-size:14px;font-weight:bold;display:block;padding:10px;background-color:#e0ebf6;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none}.help_inner{padding:10px}.help_top{display:block;position:absolute;right:10px;bottom:10px}.warning,.delete,.empty,.drop,.delete_db{color:red}.sidebar_table{font-size:11px}.active_table,.active_db{text-decoration:underline}.null{color:#888}.found{background:#FF0;text-decoration:none} function initAutoincrement() {var i=0;while(document.getElementById('i'+i+'_autoincrement')!=undefined) {document.getElementById('i'+i+'_autoincrement').disabled=true;i++;}} function toggleAutoincrement(i) {var type=document.getElementById('i'+i+'_type');var primarykey=document.getElementById('i'+i+'_primarykey');var autoincrement=document.getElementById('i'+i+'_autoincrement');if(!autoincrement)return false;if(type.value=='INTEGER'&&primarykey.checked) autoincrement.disabled=false;else {autoincrement.disabled=true;autoincrement.checked=false;}} function toggleNull(i) {var pk=document.getElementById('i'+i+'_primarykey');var notnull=document.getElementById('i'+i+'_notnull');if(pk.checked) {notnull.disabled=true;notnull.checked=true;} else {notnull.disabled=false;}} function checkAll(field) {var i=0;while(document.getElementById('check_'+i)!=undefined) {document.getElementById('check_'+i).checked=true;i++;}} function uncheckAll(field) {var i=0;while(document.getElementById('check_'+i)!=undefined) {document.getElementById('check_'+i).checked=false;i++;}} function changeIgnore(area,e,u) {if(area.value!="") {if(document.getElementById(e)!=undefined) document.getElementById(e).checked=false;if(document.getElementById(u)!=undefined) document.getElementById(u).checked=false;}} function moveFields() {var fields=document.getElementById("fieldcontainer");var selected=[];for(var i=0;i0){CodeMirror.commands.autocomplete(instance);}} function checkFileSize(input) {if(input.files&&input.files.length==1) {if(input.files[0].size>fileUploadMaxSize) {alert(fileUploadMaxSizeErrorMsg+": "+(fileUploadMaxSize/1024/1024)+" MiB");return false;}} return true;}AAABAAEAEBAAAAEAIAAoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwoKZQAAABMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEMDJMAAAAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASDg7BAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAETDw9CCQkJ1QUFBb4AAABjAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgsLVgAAAO8YExP/AAAA7QAAALEAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQNDUsAAADJGBMT/xgTE/8AAAD/AAAAuAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZERE8DQoKwhgTE/8QDQ2sGBMT/xgTE/8AAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwICHkAAAD/EQwMzQAAAMIAAAD/AAAA7gAAAGEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOCwtWAAAA8RgTE/8IBQW1AAAA/wAAAP8AAADlAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KCsEAAAD/EQ8PzAAAAMkAAAD/AAAA/wAAAHoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDAAAA/xgTE/8TDw/FAAAA8gAAAP8AAADqAAAAJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAALUAAAD/GBMT/wAAALkAAAD/AAAA/wAAAIkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAA4wAAAP8GBgbFAAAA2QAAAP8AAADGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF4AAAD5AAAA/RgTE/8AAAD/AAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQAAAOIAAAD/AAAA/wAAAHYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjAAAArgAAAG4AAAAAAAAAAAAAAAAAAAAA