blob: 92a218f5be5b04f9972fba47aa9826d16a0a5f81 [file] [log] [blame]
<?php
require_once('db.php');
require_once('manifest-generator.php');
?><!DOCTYPE html>
<html>
<head>
<title>WebKit Perf Monitor</title>
<link rel="stylesheet" href="/common.css">
<link rel="stylesheet" href="/admin/admin.css">
</head>
<body>
<header id="title">
<h1><a href="/">WebKit Perf Monitor</a></h1>
<ul>
<li><a href="/admin/platforms">Platforms</a></li>
<li><a href="/admin/tests">Tests</a></li>
<li><a href="/admin/aggregators">Aggregators</a></li>
<li><a href="/admin/builders">Builders</a></li>
<li><a href="/admin/build-slaves">Slaves</a></li>
<li><a href="/admin/triggerables">Triggerables</a></li>
<li><a href="/admin/repositories">Repositories</a></li>
<li><a href="/admin/bug-trackers">Bug Trackers</a></li>
<li><a href="/admin/files">Files</a></li>
</ul>
</header>
<div id="mainContents">
<?php
function notice($message) {
echo "<p class='notice'>$message</p>";
}
$db = new Database;
if (!$db->connect()) {
notice('Failed to connect to the database');
$db = NULL;
} else
$action = array_key_exists('action', $_POST) ? $_POST['action'] : NULL;
function execute_query_and_expect_one_row_to_be_affected($query, $params, $success_message, $failure_message) {
global $db;
foreach ($params as &$param) {
if ($param == '')
$param = NULL;
}
$affected_rows = $db->query_and_get_affected_rows($query, $params);
if ($affected_rows) {
assert('$affected_rows == 1');
notice($success_message);
return true;
}
notice($failure_message);
return false;
}
function update_field($table, $prefix, $field_name, $new_value = NULL) {
global $db;
if (!array_key_exists('id', $_POST))
return FALSE;
$id = intval($_POST['id']);
$prefixed_field_name = $prefix . '_' . $field_name;
$id_field_name = $prefix . '_id';
if ($new_value == NULL) {
if (array_get($_POST, 'updated-column') != $field_name && !array_key_exists($field_name, $_POST))
return FALSE;
$new_value = array_get($_POST, $field_name);
}
execute_query_and_expect_one_row_to_be_affected("UPDATE $table SET $prefixed_field_name = \$2 WHERE $id_field_name = \$1",
array($id, $new_value),
"Updated the $prefix $id",
"Could not update $prefix $id");
return TRUE;
}
function update_boolean_field($table, $prefix, $field_name) {
return update_field($table, $prefix, $field_name, Database::to_database_boolean(array_get($_POST, $field_name)));
}
function regenerate_manifest() {
global $db;
$generator = new ManifestGenerator($db);
if (!$generator->generate()) {
notice("Failed to generate the manifest (before trying to write into the filesystem).");
return FALSE;
}
if (!$generator->store()) {
notice("Failed to save the generated manifest into the filesystem");
return FALSE;
}
return TRUE;
}
class AdministrativePage {
private $table;
private $prefix;
private $column_to_be_ordered_by;
private $column_info;
function __construct($db, $table, $prefix, $column_info) {
$this->db = $db;
$this->table = $table;
$this->prefix = $prefix;
$this->column_info = $column_info;
}
private function name_to_titlecase($name) {
return ucwords(str_replace('_', ' ', $name));
}
private function column_label($name) {
return array_get($this->column_info[$name], 'label', $this->name_to_titlecase($name));
}
private function render_form_control_for_column($editing_mode, $name, $value = '', $show_update_button_if_needed = FALSE) {
$show_update_button = FALSE;
switch ($editing_mode) {
case 'text':
echo <<< END
<textarea name="$name" rows="7" cols="50">$value</textarea><br>
END;
$show_update_button = $show_update_button_if_needed;
break;
case 'boolean':
$checkedness = Database::is_true($value) ? ' checked' : '';
echo <<< END
<input type="checkbox" name="$name"$checkedness>
END;
$show_update_button = $show_update_button_if_needed;
break;
case 'url':
echo <<< END
<input type="text" name="$name" value="$value" size="70">
END;
break;
default:
assert($editing_mode == 'string');
echo <<< END
<input type="text" name="$name" value="$value">
END;
}
if ($show_update_button) {
echo <<< END
<button type="submit" name="action" value="update">Update</button>
END;
}
}
function render_table($column_to_be_ordered_by) {
$column_names = array_keys($this->column_info);
$column_to_subcolumn_names = array();
foreach ($column_names as $name) {
if (array_get($this->column_info[$name], 'pre_insertion'))
continue;
$subcolumns = array_get($this->column_info[$name], 'subcolumns', array());
if (!$subcolumns || !array_get($this->column_info[$name], 'custom'))
continue;
$column_to_subcolumn_names[$name] = $subcolumns;
}
$rowspan_if_needed = $column_to_subcolumn_names ? ' rowspan="2"' : '';
$headers = "<tr><td$rowspan_if_needed>ID</td>";
foreach ($column_names as $name) {
if (array_get($this->column_info[$name], 'pre_insertion'))
continue;
$label = htmlspecialchars($this->column_label($name));
if (array_get($column_to_subcolumn_names, $name)) {
$count = count($column_to_subcolumn_names[$name]);
$headers .= "<td colspan=\"$count\">$label</td>";
} else
$headers .= "<td$rowspan_if_needed>$label</td>";
}
$headers .= "</tr>\n";
if ($column_to_subcolumn_names) {
$headers .= '<tr>';
foreach ($column_names as $name) {
$subcolumn_names = array_get($column_to_subcolumn_names, $name);
if (!$subcolumn_names)
continue;
foreach ($subcolumn_names as $label)
$headers .= '<td>' . htmlspecialchars($label) . '</td>';
}
$headers .= "</tr>\n";
}
echo <<< END
<table>
<thead>
$headers
</thead>
<tbody>
END;
assert(ctype_alnum_underscore($column_to_be_ordered_by));
$rows = $this->db->fetch_table($this->table, $this->prefix . '_' . $column_to_be_ordered_by);
if ($rows) {
foreach ($rows as $row) {
$id = intval($row[$this->prefix . '_id']);
$custom_cells_list = array();
$maximum_rows = 1;
foreach ($column_names as $name) {
if (array_get($this->column_info[$name], 'pre_insertion'))
continue;
if ($custom = array_get($this->column_info[$name], 'custom')) {
$custom_cells_list[$name] = $custom($row);
$maximum_rows = max($maximum_rows, count($custom_cells_list[$name]));
}
}
$rowspan_if_needed = $maximum_rows > 1 ? ' rowspan="' . $maximum_rows . '"' : '';
echo "<tr>\n<td$rowspan_if_needed>$id</td>\n";
foreach ($column_names as $name) {
if (array_get($this->column_info[$name], 'pre_insertion'))
continue;
if (array_key_exists($name, $custom_cells_list)) {
$this->render_custom_cells(array_get($column_to_subcolumn_names, $name), $custom_cells_list[$name], 0);
continue;
}
$value = htmlspecialchars(array_get($row, $this->prefix . '_' . $name), ENT_QUOTES);
$editing_mode = array_get($this->column_info[$name], 'editing_mode');
if (!$editing_mode) {
echo "<td$rowspan_if_needed>$value</td>\n";
continue;
}
echo <<< END
<td$rowspan_if_needed>
<form method="POST">
<input type="hidden" name="id" value="$id">
<input type="hidden" name="action" value="update">
<input type="hidden" name="updated-column" value="$name">
END;
$this->render_form_control_for_column($editing_mode, $name, $value, TRUE);
echo "</form></td>\n";
}
echo "</tr>\n";
for ($row = 1; $row < $maximum_rows; $row++) {
echo "<tr>\n";
foreach ($column_names as $name) {
if (array_key_exists($name, $custom_cells_list))
$this->render_custom_cells(array_get($column_to_subcolumn_names, $name), $custom_cells_list[$name], $row);
}
echo "</tr>\n";
}
}
}
echo <<< END
</tbody>
</table>
END;
}
function render_custom_cells($subcolum_names, $rows, $row_index) {
$cells = array_get($rows, $row_index, array());
if (!is_array($cells))
$cells = array($cells);
if ($subcolum_names && count($cells) <= 1) {
$colspan = count($subcolum_names);
$content = $cells ? $cells[0] : '';
echo "<td colspan=\"$colspan\">$content</td>\n";
return;
}
for ($i = 0; $i < ($subcolum_names ? count($subcolum_names) : 1); $i++)
echo '<td>' . array_get($cells, $i, '') . '</td>';
echo "\n";
}
function render_form_to_add($title = NULL) {
if (!$title) # Can't use the table name since it needs to be singular.
$title = 'New ' . $this->name_to_titlecase($this->prefix);
echo <<< END
<section class="action-field">
<h2>$title</h2>
<form method="POST">
END;
foreach (array_keys($this->column_info) as $name) {
$editing_mode = array_get($this->column_info[$name], 'editing_mode');
if (array_get($this->column_info[$name], 'custom') || !$editing_mode)
continue;
if (array_get($this->column_info[$name], 'post_insertion'))
continue;
$label = htmlspecialchars($this->column_label($name));
echo "<label>$label<br>\n";
$this->render_form_control_for_column($editing_mode, $name);
echo "</label><br>\n";
}
echo <<< END
<button type="submit" name="action" value="add">Add</button>
</form>
</section>
END;
}
}
?>