navsection = 'about'; $this->content_template = 'about/featurematrix.html'; $this->category = $category; $this->master = $_SETTINGS['masterserver']; if ($suffix == 'edit') { $this->editor = true; $this->requirelogin = true; } if ($suffix == 'save') { $this->editor = true; $this->saveform = true; $this->requirelogin = true; } if ($suffix == 'add') { $this->editor = true; $this->addform = true; $this->requirelogin = true; } if ($this->requirelogin) { // Disable navigation on these pages $this->navsection=''; } $this->states = array(0=>'No', 1=>'Yes', 2=>'Obsolete', 3=>'?'); } function BuildQuery() { // We list all versions by default. Filter here in the future? $activefilter = $this->editor?'':'active AND '; $verrs = $this->pg_query_params("SELECT versionid,versionname FROM features_versions WHERE $activefilter category=$1 ORDER BY versionname", array($this->category)); $selects = ''; $joins = ''; for ($i=0; $i < pg_num_rows($verrs); $i++) { $vid = pg_fetch_result($verrs, $i, 0); $vname = pg_fetch_result($verrs, $i, 1); $selects .= "COALESCE(fm{$vid}.state,0) AS \"{$vname}\","; $joins .= "LEFT JOIN features_matrix fm{$vid} ON fm{$vid}.feature=features_features.featureid AND fm{$vid}.version={$vid} "; $this->versionmap[$i] = $vid; } $selects = rtrim($selects,','); return "SELECT features_groups.groupname,features_features.featurename,features_features.featureid,features_features.featuredescription,features_groups.groupid,{$selects} FROM features_groups NATURAL JOIN features_features {$joins} WHERE features_groups.category=" . $this->category . " ORDER BY groupsort,featurename"; } function Render() { if ($this->requirelogin && $this->userinfo['matrixeditor'] != 1) { throw new Exception("You don't have permissions to edit feature matrixes. If you want to contribute to these pages, please contact the web team on the pgsql-www mailinglist."); } if ($this->saveform) { $this->SaveForm(); } if ($this->addform) { $this->AddForm(); } if ($this->editor) { $this->grouprs = $this->pg_query_params('SELECT groupid,groupname FROM features_groups WHERE category=$1 ORDER BY groupsort', array($this->category)); } $rs = $this->pg_query($this->BuildQuery()); $this->lastsection = ''; $content = ''; while ($row = pg_fetch_row($rs)) { if ($this->lastsection != $row[0]) { $content .= $this->RenderSectionHeader($row, $rs); } $content .= $this->RenderRow($row); } $this->tpl->setVariable('table_contents', $content); if ($this->editor) { $this->tpl->touchBlock('feature_editor'); $this->tpl->touchBlock('feature_editor2'); $cnt = ''; while ($row = pg_fetch_row($this->grouprs)) { $cnt .= ''; } $this->tpl->setVariable('feature_groups', $cnt); $this->tpl->setVariable('saveurl', $this->master . '/' . substr($this->url,0,strlen($this->url)-4) . 'save'); $this->tpl->setVariable('addurl', $this->master . '/' . substr($this->url,0,strlen($this->url)-4) . 'add'); // group editor $this->tpl->setVariable('group_table_contents', $this->GetGroupTableContents()); } else { $this->tpl->setVariable('editurl', $this->master . '/' . $this->url . '.edit'); $this->tpl->touchBlock('feature_teaser'); } } function GetGroupTableContents() { $c = ''; $rs = $this->pg_query_params('SELECT groupid,groupname,groupsort,CASE WHEN EXISTS (SELECT * FROM features_features WHERE features_features.groupid=features_groups.groupid) THEN 1 ELSE 0 END FROM features_groups WHERE category=$1 ORDER BY groupsort', array($this->category)); for ($i = 0; $i < pg_num_rows($rs); $i++) { $c .= ''; $c .= ''; $c .= ''; $c .= ''; $c .= ''; if (pg_fetch_result($rs,$i,3)==0) { $c .= 'Del'; } $c .= ''; } return $c; } function SaveGroups() { $rs = $this->pg_query_params('SELECT groupid,groupname,groupsort FROM features_groups WHERE category=$1', array($this->category)); $this->pg_query('BEGIN'); for ($i = 0; $i < pg_num_rows($rs); $i++) { $id = pg_fetch_result($rs,$i,0); if ($_POST['gn_' . $id] != pg_fetch_result($rs,$i,1) || $_POST['gs_' . $id] != pg_fetch_result($rs,$i,2)) { $this->pg_query_params('UPDATE features_groups SET groupname=$1,groupsort=$2 WHERE groupid=$3', array($_POST['gn_' . $id], $_POST['gs_' . $id], $id)); $this->LogAction('Modified group ' . $id); } } $this->pg_query('COMMIT'); } function SaveForm() { // Check for delete first if (isset($_GET['deletefeature']) && $_GET['deletefeature']=='1') { $this->pg_query('BEGIN'); $this->pg_query_params('DELETE FROM features_matrix WHERE feature=$1', array(intval($_GET['feature']))); $this->pg_query_params('DELETE FROM features_features WHERE featureid=$1', array(intval($_GET['feature']))); $this->LogAction('Deleted feature ' . $_GET['feature']); $this->pg_query('COMMIT'); header('Location: ' . $this->master . '/' . substr($this->url,0,strlen($this->url)-4) . 'edit'); exit(0); } if (isset($_GET['delgroup']) && $_GET['delgroup']=='1') { $this->pg_query_params('DELETE FROM features_groups WHERE groupid=$1', array(intval($_GET['groupid']))); $this->LogAction('Deleted group ' . $_GET['groupid']); header('Location: ' . $this->master . '/' . substr($this->url,0,strlen($this->url)-4) . 'edit'); exit(0); } if (isset($_POST['savegroup']) && $_POST['savegroup']=='1') { $this->SaveGroups(); header('Location: ' . $this->master . '/' . substr($this->url,0,strlen($this->url)-4) . 'edit'); exit(0); } // Fetch the old status in the db $rs = $this->pg_query($this->BuildQuery()); $this->pg_query('BEGIN'); // Walk through the results and see if we need to change anything while ($row = pg_fetch_row($rs)) { for ($j=5; $j < count($row); $j++) { // Skip past the first 5 columns, which are fixed fields, and look only at the fields that have // actual feature values. // $row[2] is the id value for the feature. $new = $this->ValidateState($_POST['fs_' . $row[2] . '_' . $this->versionmap[$j-5]]); $old = $row[$j]; if ($new != $old) { // Changed! if ($new == 0) { // Turn into zero, so remove the row $this->pg_query_params('DELETE FROM features_matrix WHERE version=$1 AND feature=$2', array($this->versionmap[$j-5], $row[2])); $this->LogAction('Removed feature ' . $row[2] . ' from version ' . $this->versionmap[$j-5]); } elseif ($old == 0) { // Didn't exist before, so add a new row $this->pg_query_params('INSERT INTO features_matrix (version,feature,state) VALUES ($1,$2,$3)', array($this->versionmap[$j-5], $row[2], $new)); $this->LogAction('Added feature ' . $row[2] . ', value ' . $new . ' to version ' . $this->versionmap[$j-5]); } else { // Existed before, just changed value $this->pg_query_params('UPDATE features_matrix SET state=$1 WHERE version=$2 AND feature=$3', array($new, $this->versionmap[$j-5], $row[2])); $this->LogAction('Updated feature ' . $row[2] . ' to value ' . $new . ' for version ' . $this->versionmap[$j-5]); } } // Name, description or group changed? if ($_POST['fn_' . $row[2]] != $row[1] || $_POST['fd_' . $row[2]] != $row[3] || $_POST['fg_' . $row[2]] != $row[4]) { $this->pg_query_params('UPDATE features_features SET featurename=$1,featuredescription=$2,groupid=$3 WHERE featureid=$4', array($_POST['fn_' . $row[2]], $_POST['fd_' . $row[2]], $_POST['fg_' . $row[2]], $row[2])); $this->LogAction('Changed name/description for feature ' . $row[2]); } } } $this->pg_query('COMMIT'); header('Location: ' . $this->master . '/' . substr($this->url,0,strlen($this->url)-4) . 'edit'); exit(0); } function AddForm() { if (isset($_POST['featurename']) && strlen($_POST['featurename'])>1) { $this->pg_query_params('INSERT INTO features_features (groupid,featurename,featuredescription) VALUES ($1,$2,$3)', array($_POST['groupid'], $_POST['featurename'], $_POST['featuredescription'])); $this->LogAction('Added new feature ' . $_POST['featurename']); } if (isset($_POST['groupname']) && strlen($_POST['groupname'])>1) { $this->pg_query_params('INSERT INTO features_groups (groupname,groupsort,category) VALUES ($1,0,$2)', array($_POST['groupname'], $this->category)); $this->LogAction('Added new grop ' . $_POST['groupname']); } header('Location: ' . $this->master . '/' . substr($this->url,0,strlen($this->url)-3) . 'edit'); exit(0); } function ValidateState($state) { if (isset($this->states[$state])) { return $state; } return 0; } function RenderSectionHeader($row,$rs) { $this->sectnum++; $this->lastsection = $row[0]; $content = '' . htmlentities($row[0]) . ' '; if ($this->editor) { $content .= 'Description'; } for ($j=5; $j < count($row); $j++) { if ($j == count($row)-1) { $content .= ''; } else { $content .= ''; } $content .= pg_field_name($rs,$j) . ''; } $content .= "\n"; $this->tpl->setVariable('sectionnum', $this->sectnum); $this->tpl->setVariable('sectionname', htmlentities($row[0])); $this->tpl->parse('sections_list'); return $content; } function RenderRow($row) { $rs = $this->pg_query_params("SELECT categoryname,categorydescription FROM features_categories WHERE categoryid=$1", array($this->category)); $this->tpl->setVariable(pg_fetch_assoc($rs)); $this->title = pg_fetch_result($rs, 0, 0); if ($this->editor) { return $this->RenderRowEdit($row); } else { return $this->RenderRowView($row); } } function RenderRowView($row) { if (substr($row[3], 0, 7) == 'http://') { $content = '' . htmlentities($row[1]) . ''; } elseif ($row[3] != '') { $content = '' . htmlentities($row[1]) . ''; } else { $content = "" . htmlentities($row[1]) . ""; } for ($j=5; $j < count($row); $j++) { $txt = 'No'; $col = 'ffdddd'; switch ($row[$j]) { case '1': $txt = 'Yes';$col = 'ddffdd'; break; case '2': $txt = 'Obsolete';$col = 'ddddff'; break; case '3': $txt = '?';$col = 'ffffaa'; break; } $content .= "{$txt}"; } $content .= "\n"; return $content; } function RenderRowEdit($row) { $content = ''; $content .= ''; for ($j=5; $j < count($row); $j++) { $content .= ''; } $content .= 'Del'; return $content . "\n"; } function LogAction($msg) { $this->pg_query_params('INSERT INTO features_log (userid, txt) VALUES ($1,$2)', array($this->userinfo['userid'], $msg)); } } ?>