public function __construct(&$result_file)
 {
     $columns = array();
     $hw = array();
     $sw = array();
     foreach ($result_file->get_systems() as $system) {
         $columns[] = $system->get_identifier();
         $hw[] = $system->get_hardware();
         $sw[] = $system->get_software();
     }
     $rows = array();
     $table_data = array();
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $hw);
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $sw);
     pts_result_file_analyzer::compact_result_table_data($table_data, $columns, true);
     // TODO: see if this true value works fine but if rendering starts messing up, disable it
     if (defined('OPENBENCHMARKING_IDS')) {
         foreach ($columns as &$column) {
             $column = new pts_graph_ir_value($column);
             $column->set_attribute('href', 'http://openbenchmarking.org/system/' . OPENBENCHMARKING_IDS . '/' . $column);
         }
     }
     parent::__construct($rows, $columns, $table_data, $result_file);
     $this->i['identifier_size'] *= 0.8;
     $this->column_heading_vertical = false;
     $this->graph_title = $result_file->get_title();
     if (!defined('PHOROMATIC_EXPORT_VIEWER')) {
         pts_render::report_system_notes_to_table($result_file, $this);
     }
 }
 public static function result_file_to_csv(&$result_file)
 {
     $csv_output = null;
     $delimiter = ',';
     $csv_output .= $result_file->get_title() . PHP_EOL . PHP_EOL;
     $columns = array();
     $hw = array();
     $sw = array();
     foreach ($result_file->get_systems() as $system) {
         array_push($columns, $system->get_identifier());
         array_push($hw, $system->get_hardware());
         array_push($sw, $system->get_software());
     }
     $rows = array();
     $table_data = array();
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $hw);
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $sw);
     $csv_output .= ' ';
     foreach ($columns as $column) {
         $csv_output .= $delimiter . '"' . $column . '"';
     }
     $csv_output .= PHP_EOL;
     foreach ($rows as $i => $row) {
         $csv_output .= $row;
         foreach ($columns as $column) {
             $csv_output .= $delimiter . $table_data[$column][$i];
         }
         $csv_output .= PHP_EOL;
     }
     $csv_output .= PHP_EOL;
     $csv_output .= ' ';
     foreach ($columns as $column) {
         $csv_output .= $delimiter . '"' . $column . '"';
     }
     $csv_output .= PHP_EOL;
     foreach ($result_file->get_result_objects() as $result_object) {
         $csv_output .= '"' . $result_object->test_profile->get_title() . ' - ' . $result_object->get_arguments_description() . '"';
         foreach ($columns as $column) {
             $buffer_item = $result_object->test_result_buffer->find_buffer_item($column);
             $value = $buffer_item != false ? $buffer_item->get_result_value() : null;
             $csv_output .= $delimiter . $value;
         }
         $csv_output .= PHP_EOL;
     }
     $csv_output .= PHP_EOL;
     return $csv_output;
 }
 public static function render_page_process($PATH)
 {
     echo '<h1>' . self::$result_file->get_title() . '</h2>';
     $extra_attributes = array();
     $intent = null;
     if (self::$result_file->get_system_count() == 1 || ($intent = pts_result_file_analyzer::analyze_result_file_intent(self::$result_file, $intent, true))) {
         $table = new pts_ResultFileCompactSystemsTable(self::$result_file, $intent);
     } else {
         $table = new pts_ResultFileSystemsTable(self::$result_file);
     }
     echo '<p class="result_object">' . pts_render::render_graph_inline_embed($table, self::$result_file, $extra_attributes) . '</p>';
     foreach (self::$result_file->get_result_objects() as $i => $result_object) {
         echo '<h2><a name="r-' . $i . '"></a>' . $result_object->test_profile->get_title() . '</h2>';
         echo '<p class="result_object">';
         echo pts_render::render_graph_inline_embed($result_object, self::$result_file, $extra_attributes);
         echo '</p>';
     }
 }
 public static function render_page_process($PATH)
 {
     echo phoromatic_webui_header_logged_in();
     $main = '<h1>System Components</h1>';
     $main .= '<p>Detected hardware/software components via Phoronix Test Suite\'s Phodevi implementation on the Phoromatic client systems.</p>';
     $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, Hardware, Software, ClientVersion, NetworkWakeOnLAN, NetworkMAC FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 ORDER BY Title ASC');
     $stmt->bindValue(':account_id', $_SESSION['AccountID']);
     $result = $stmt->execute();
     while ($row = $result->fetchArray()) {
         $components[$row['SystemID']] = array_merge(pts_result_file_analyzer::system_component_string_to_array($row['Software'], array('OS', 'Kernel', 'OpenGL', 'File-System')), pts_result_file_analyzer::system_component_string_to_array($row['Hardware'], array('Processor', 'Motherboard', 'Memory', 'Disk', 'Graphics')));
         $components[$row['SystemID']]['Phoronix Test Suite'] = $row['ClientVersion'];
         $components[$row['SystemID']]['WoL Info'] = $row['NetworkWakeOnLAN'];
         $components[$row['SystemID']]['MAC'] = $row['NetworkMAC'];
         $system_ids[$row['SystemID']] = $row['Title'];
     }
     $main .= '<div style="margin: 10px auto; overflow: auto;"><table>';
     $component_types = array('MAC', 'Processor', 'Motherboard', 'Memory', 'Disk', 'Graphics', 'OS', 'Kernel', 'OpenGL', 'File-System', 'Phoronix Test Suite', 'WoL Info');
     $main .= '<tr><th>&nbsp;</th>';
     foreach ($component_types as $type) {
         $main .= '<th>' . $type . '</th>';
     }
     foreach ($components as $system_id => $component_array) {
         $main .= '<tr>';
         $main .= '<th><a href="/?systems/' . $system_id . '">' . $system_ids[$system_id] . '</a></th>';
         foreach ($component_types as $type) {
             $c = isset($component_array[$type]) ? $component_array[$type] : 'N/A';
             if (($x = stripos($c, ' @ ')) !== false) {
                 $c = substr($c, 0, $x);
             }
             if (($x = stripos($c, ' (')) !== false) {
                 $c = substr($c, 0, $x);
             }
             $main .= '<td>' . $c . '</td>';
         }
         $main .= '</tr>';
     }
     $main .= '</table></div>';
     $right = null;
     echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in($right));
     echo phoromatic_webui_footer();
 }
 public static function result_file_to_csv(&$result_file)
 {
     $csv_output = null;
     $delimiter = ',';
     $csv_output .= $result_file->get_title() . PHP_EOL . PHP_EOL;
     $columns = $result_file->get_system_identifiers();
     $rows = array();
     $table_data = array();
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $result_file->get_system_hardware());
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $result_file->get_system_software());
     $csv_output .= ' ';
     foreach ($columns as $column) {
         $csv_output .= $delimiter . '"' . $column . '"';
     }
     $csv_output .= PHP_EOL;
     foreach ($rows as $i => $row) {
         $csv_output .= $row;
         foreach ($columns as $column) {
             $csv_output .= $delimiter . $table_data[$column][$i];
         }
         $csv_output .= PHP_EOL;
     }
     $csv_output .= PHP_EOL;
     $csv_output .= ' ';
     foreach ($columns as $column) {
         $csv_output .= $delimiter . '"' . $column . '"';
     }
     $csv_output .= PHP_EOL;
     foreach ($result_file->get_result_objects() as $result_object) {
         $csv_output .= '"' . $result_object->test_profile->get_title() . ' - ' . $result_object->get_arguments_description() . '"';
         foreach ($result_object->test_result_buffer->get_values() as $value) {
             $csv_output .= $delimiter . $value;
         }
         $csv_output .= PHP_EOL;
     }
     $csv_output .= PHP_EOL;
     return $csv_output;
 }
Example #6
0
 public static function compact_result_file_test_object(&$mto, &$result_table = false, &$result_file, $extra_attributes = null)
 {
     $identifiers_inverted = $result_file && $result_file->is_multi_way_inverted();
     // TODO: this may need to be cleaned up, its logic is rather messy
     $condense_multi_way = isset($extra_attributes['condense_multi_way']);
     if (count($mto->test_profile->get_result_scale_offset()) > 0) {
         // It's already doing something
         return;
     }
     $scale_special = array();
     $days = array();
     $systems = array();
     $prev_date = null;
     $is_tracking = true;
     $sha1_short_count = 0;
     $buffer_count = $mto->test_result_buffer->get_count();
     if ($identifiers_inverted) {
         $system_index = 0;
         $date_index = 1;
     } else {
         $system_index = 1;
         $date_index = 0;
     }
     foreach ($mto->test_result_buffer->get_buffer_items() as $buffer_item) {
         $identifier = array_map('trim', explode(':', $buffer_item->get_result_identifier()));
         switch (count($identifier)) {
             case 2:
                 $system = $identifier[$system_index];
                 $date = $identifier[$date_index];
                 break;
             case 1:
                 $system = 0;
                 $date = $identifier[0];
                 break;
             default:
                 return;
                 break;
         }
         if (!isset($systems[$system])) {
             $systems[$system] = 0;
         }
         if (!isset($days[$date])) {
             $days[$date] = null;
         }
         if ($is_tracking) {
             // First do a dirty SHA1 hash check
             if (strlen($date) != 40 || strpos($date, ' ') !== false) {
                 if (($x = strpos($date, ' + ')) !== false) {
                     $date = substr($date, 0, $x);
                 }
                 // Check to see if only numeric changes are being made
                 $sha1_short_hash_ending = isset($date[7]) && ctype_alnum(substr($date, -8));
                 $date = str_replace('s', null, pts_strings::remove_from_string($date, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH | pts_strings::CHAR_DECIMAL));
                 if ($sha1_short_hash_ending) {
                     $sha1_short_count++;
                 }
                 if ($prev_date != null && $date != $prev_date && $sha1_short_hash_ending == false && $sha1_short_count < 3) {
                     $is_tracking = false;
                 }
                 $prev_date = $date;
             }
         }
     }
     if ($is_tracking) {
         $prev_date_r = explode(' ', $prev_date);
         if (count($prev_date_r) == 2 && ctype_alpha($prev_date_r[0])) {
             // This check should make it so when like testing every Ubuntu releases (Ubuntu 11.04, Ubuntu 11.10, etc) it's not in a line graph
             $is_tracking = false;
         }
     } else {
         if ($is_tracking == false && $sha1_short_count > 5) {
             // It's probably actually tracking..... based upon Stefan's Wine 1.4 example on 15 March 2012
             $is_tracking = true;
         }
     }
     foreach (array_keys($days) as $day_key) {
         $days[$day_key] = $systems;
     }
     $raw_days = $days;
     $json_days = $days;
     foreach ($mto->test_result_buffer->get_buffer_items() as $buffer_item) {
         $identifier = array_map('trim', explode(':', $buffer_item->get_result_identifier()));
         switch (count($identifier)) {
             case 2:
                 $system = $identifier[$system_index];
                 $date = $identifier[$date_index];
                 break;
             case 1:
                 $system = 0;
                 $date = $identifier[0];
                 break;
             default:
                 return;
                 break;
         }
         $days[$date][$system] = $buffer_item->get_result_value();
         $raw_days[$date][$system] = $buffer_item->get_result_raw();
         $json_days[$date][$system] = $buffer_item->get_result_json();
         if (!is_numeric($days[$date][$system])) {
             return;
         }
     }
     $mto->test_result_buffer = new pts_test_result_buffer();
     $day_keys = array_keys($days);
     if ($condense_multi_way) {
         $mto->set_used_arguments_description($mto->get_arguments_description() . ' | Composite Of: ' . implode(' - ', array_keys($days)));
         foreach (array_keys($systems) as $system_key) {
             $sum = 0;
             $count = 0;
             foreach ($day_keys as $day_key) {
                 $sum += $days[$day_key][$system_key];
                 $count++;
             }
             $mto->test_result_buffer->add_test_result($system_key, $sum / $count);
         }
     } else {
         $mto->test_profile->set_result_scale($mto->test_profile->get_result_scale() . ' | ' . implode(',', array_keys($days)));
         if ($is_tracking && $buffer_count < 16 && $result_file && pts_result_file_analyzer::analyze_result_file_intent($result_file) == false) {
             // It can't be a tracker if the result file is comparing hardware/software, etc
             $is_tracking = false;
         }
         switch ($mto->test_profile->get_display_format()) {
             //case 'HORIZONTAL_BOX_PLOT':
             //	$mto->test_profile->set_display_format('HORIZONTAL_BOX_PLOT_MULTI');
             //	break;
             case 'SCATTER_PLOT':
                 break;
             default:
                 $line_graph_type = 'LINE_GRAPH';
                 $mto->test_profile->set_display_format(!isset($extra_attributes['force_tracking_line_graph']) && (count($days) < 5 || $is_tracking == false && !isset($extra_attributes['force_line_graph_compact'])) ? 'BAR_ANALYZE_GRAPH' : $line_graph_type);
                 break;
         }
         foreach (array_keys($systems) as $system_key) {
             $results = array();
             $raw_results = array();
             $json_results = array();
             foreach ($day_keys as $day_key) {
                 array_push($results, $days[$day_key][$system_key]);
                 array_push($raw_results, $raw_days[$day_key][$system_key]);
                 pts_arrays::unique_push($json_results, $json_days[$day_key][$system_key]);
             }
             // TODO XXX: Make JSON data work for multi-way comparisons!
             if (count($json_results) == 1) {
                 $json = array_shift($json_results);
             } else {
                 $json = null;
             }
             $mto->test_result_buffer->add_test_result($system_key, implode(',', $results), implode(',', $raw_results), $json);
         }
     }
     if ($result_table !== false) {
         foreach (array_keys($systems) as $system_key) {
             foreach ($day_keys as $day_key) {
                 if (!isset($result_table[$system_key][$day_key])) {
                     $result_table[$system_key][$day_key] = array();
                 }
                 array_push($result_table[$system_key][$day_key], $days[$day_key][$system_key], $raw_days[$day_key][$system_key]);
             }
         }
     }
 }
 public function render_graph_start()
 {
     $this->i['top_heading_height'] = 22 + self::$c['size']['headers'];
     $longest_component = pts_strings::find_longest_string($this->components);
     $component_header_height = $this->text_string_height($longest_component, $this->i['identifier_size'] + 3) + 6;
     $this->i['graph_width'] = 10 + max($this->text_string_width($this->graph_title, self::$c['size']['headers']) - (isset($this->graph_title[30]) ? 20 : 0), $this->text_string_width($longest_component, $this->i['identifier_size'] + (isset($longest_component[29]) ? 1.8 : 2)));
     $intent_count = 0;
     $dupes = array();
     if ($this->intent[1] && is_array($this->intent[1])) {
         foreach ($this->intent[1] as $x) {
             if (!in_array($x, $dupes)) {
                 $intent_count += count($x);
                 array_push($dupes, $x);
             }
         }
         $intent_count -= count($this->intent[0]);
     }
     unset($dupes);
     $bottom_footer = 50 + $this->note_display_height();
     // needs to be at least 86 to make room for PTS logo
     $this->i['graph_height'] = $this->i['top_heading_height'] + (count($this->components) + $intent_count) * $component_header_height + $bottom_footer;
     // Do the actual work
     $this->render_graph_pre_init();
     $this->render_graph_init();
     // Header
     $this->svg_dom->add_element('rect', array('x' => 2, 'y' => 1, 'width' => $this->i['graph_width'] - 3, 'height' => $this->i['top_heading_height'] - 1, 'fill' => self::$c['color']['main_headers'], 'stroke' => self::$c['color']['border'], 'stroke-width' => 1));
     $this->svg_dom->add_text_element($this->graph_title, array('x' => $this->i['graph_width'] / 2, 'y' => 2 + self::$c['size']['headers'], 'font-size' => self::$c['size']['headers'], 'fill' => self::$c['color']['background'], 'text-anchor' => 'middle'));
     $this->svg_dom->add_text_element(self::$c['text']['watermark'], array('x' => 4, 'y' => $this->i['top_heading_height'] - 3, 'font-size' => 8, 'fill' => self::$c['color']['background'], 'text-anchor' => 'start', 'xlink:show' => 'new', 'xlink:href' => self::$c['text']['watermark_url']));
     $this->svg_dom->add_text_element($this->i['graph_version'], array('x' => $this->i['graph_width'] - 4, 'y' => $this->i['top_heading_height'] - 3, 'font-size' => 8, 'fill' => self::$c['color']['background'], 'text-anchor' => 'end', 'xlink:show' => 'new', 'xlink:href' => 'http://www.phoronix-test-suite.com/'));
     // Body
     $offset = $this->i['top_heading_height'];
     $dash = false;
     foreach ($this->components as $type => $component) {
         if (is_array($this->intent[0]) && ($key = array_search($type, $this->intent[0])) !== false) {
             $component = array();
             foreach ($this->intent[1] as $s) {
                 if (isset($s[$key])) {
                     array_push($component, $s[$key]);
                 }
             }
             // Eliminate duplicates from printing
             $component = array_unique($component);
             $next_offset = $offset + $component_header_height * count($component);
         } else {
             $next_offset = $offset + $component_header_height;
             $component = array($component);
         }
         if ($dash) {
             $this->svg_dom->add_element('rect', array('x' => 0, 'y' => $offset, 'width' => $this->i['graph_width'], 'height' => $next_offset - $offset, 'fill' => self::$c['color']['body_light']));
         }
         $this->svg_dom->draw_svg_line(0, $offset, $this->i['graph_width'], $offset, self::$c['color']['notches'], 1);
         if (isset($component[1])) {
             $this->svg_dom->add_element('rect', array('x' => 1, 'y' => $offset + 1, 'width' => $this->i['graph_width'] - 2, 'height' => $next_offset - $offset - 1, 'fill' => 'none', 'stroke-width' => 1, 'stroke' => self::$c['color']['highlight']));
         }
         $text = $type . (isset($component[1]) && substr($type, -1) != 'y' && substr($type, -1) != 's' ? 's' : null);
         $this->svg_dom->add_text_element($text, array('x' => $this->i['graph_width'] - 4, 'y' => $offset + 9, 'font-size' => 7, 'fill' => self::$c['color']['text'], 'text-anchor' => 'end'));
         $offset += 2;
         foreach ($component as $c) {
             $c = pts_result_file_analyzer::system_value_to_ir_value($c, $type);
             $this->svg_dom->add_text_element($c, array('x' => $this->i['graph_width'] / 2, 'y' => $offset + $component_header_height - 5, 'font-size' => $this->i['identifier_size'], 'fill' => self::$c['color']['text'], 'text-anchor' => 'middle', 'xlink:title' => $type . ': ' . $c, 'font-weight' => 'bold', 'xlink:href' => $c->get_attribute('href')));
             $offset += $component_header_height;
         }
         $offset = $next_offset;
         $dash = !$dash;
     }
     // Footer
     $this->svg_dom->add_element('rect', array('x' => 1, 'y' => $this->i['graph_height'] - $bottom_footer, 'width' => $this->i['graph_width'] - 2, 'height' => $bottom_footer, 'fill' => self::$c['color']['main_headers']));
     //$this->svg_dom->add_element('image', array('http_link' => 'http://www.phoronix-test-suite.com/', 'xlink:href' => pts_svg_dom::embed_png_image(PTS_CORE_STATIC_PATH . 'images/pts-80x42-white.png'), 'x' => 10, 'y' => ($this->i['graph_height'] - 46), 'width' => 80, 'height' => 42));
     if (defined('OPENBENCHMARKING_IDS')) {
         $back_width = $this->i['graph_width'] - 4;
         $this->svg_dom->add_text_element(OPENBENCHMARKING_TITLE, array('x' => $back_width, 'y' => $this->i['graph_height'] - $bottom_footer + 12, 'font-size' => 8, 'fill' => self::$c['color']['background'], 'text-anchor' => 'end', 'font-weight' => 'bold', 'xlink:show' => 'new', 'xlink:href' => 'http://openbenchmarking.org/result/' . OPENBENCHMARKING_IDS));
         $this->svg_dom->add_text_element('System Logs', array('x' => $back_width, 'y' => $this->i['graph_height'] - 20, 'font-size' => 8, 'fill' => self::$c['color']['background'], 'text-anchor' => 'end', 'xlink:show' => 'new', 'xlink:href' => 'http://openbenchmarking.org/system/' . OPENBENCHMARKING_IDS));
         $this->svg_dom->add_text_element('OPC Classification', array('x' => $back_width, 'y' => $this->i['graph_height'] - 6, 'font-size' => 8, 'fill' => self::$c['color']['background'], 'text-anchor' => 'end', 'xlink:show' => 'new', 'xlink:href' => 'http://openbenchmarking.org/opc/' . OPENBENCHMARKING_IDS));
     }
     if (!empty($this->i['notes'])) {
         $estimated_height = 0;
         foreach ($this->i['notes'] as $i => $note_r) {
             $this->svg_dom->add_textarea_element('- ' . $note_r['note'], array('x' => 4, 'y' => $this->i['graph_height'] - $bottom_footer + $estimated_height + 21, 'font-size' => self::$c['size']['key'], 'fill' => self::$c['color']['background'], 'text-anchor' => 'start', 'xlink:title' => $note_r['hover-title']), $estimated_height);
         }
     }
 }
    public static function render_page_process($PATH)
    {
        $main = null;
        if (isset($PATH[0])) {
            $upload_ids = explode(',', $PATH[0]);
            foreach ($upload_ids as $i => $upload_id) {
                if (isset($upload_id[5]) && substr($upload_id, 0, 2) == 'S:') {
                    $t = explode(':', $upload_id);
                    $stmt = phoromatic_server::$db->prepare('SELECT UploadID, UploadTime FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':schedule_id', $t[1]);
                    $test_result_result = $stmt->execute();
                    $cutoff_time = is_numeric($t[2]) ? strtotime('today -' . $t[2] . ' days') : false;
                    while ($test_result_row = $test_result_result->fetchArray()) {
                        if ($cutoff_time !== false && strtotime($test_result_row['UploadTime']) < $cutoff_time) {
                            break;
                        }
                        $upload_ids[] = $test_result_row['UploadID'];
                    }
                    unset($upload_ids[$i]);
                }
            }
            $upload_ids = array_unique($upload_ids);
            $result_files = array();
            $display_rows = array();
            $system_types = array();
            $schedule_types = array();
            $trigger_types = array();
            $upload_times = array();
            $benchmark_tickets = array();
            $xml_result_hash = array();
            $tickets = array();
            foreach ($upload_ids as $id) {
                $result_share_opt = phoromatic_server::read_setting('force_result_sharing') ? '1 = 1' : 'AccountID = (SELECT AccountID FROM phoromatic_account_settings WHERE LetOtherGroupsViewResults = "1" AND AccountID = phoromatic_results.AccountID)';
                $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE PPRID = :pprid AND (AccountID = :account_id OR ' . $result_share_opt . ') LIMIT 1');
                $stmt->bindValue(':pprid', $id);
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if (false && empty($row)) {
                    // TODO XXX
                    // XXX this code is ultimately dead
                    $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND UploadID = :upload_id LIMIT 1');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':upload_id', $id);
                    $result = $stmt->execute();
                    $row = $result->fetchArray();
                }
                if (empty($row)) {
                    continue;
                }
                $composite_xml = phoromatic_server::phoromatic_account_result_path($row['AccountID'], $row['UploadID']) . 'composite.xml';
                if (!is_file($composite_xml)) {
                    echo 'File Not Found: ' . $composite_xml;
                    return false;
                }
                $display_rows[$composite_xml] = $row;
                pts_arrays::unique_push($benchmark_tickets, $row['BenchmarkTicketID']);
                pts_arrays::unique_push($upload_times, $row['UploadTime']);
                pts_arrays::unique_push($xml_result_hash, $row['XmlUploadHash']);
                pts_arrays::unique_push($system_types, $row['SystemID']);
                pts_arrays::unique_push($schedule_types, $row['ScheduleID']);
                pts_arrays::unique_push($trigger_types, $row['Trigger']);
                pts_arrays::unique_push($tickets, $row['BenchmarkTicketID']);
                // Update view counter
                $stmt_view = phoromatic_server::$db->prepare('UPDATE phoromatic_results SET TimesViewed = (TimesViewed + 1) WHERE AccountID = :account_id AND UploadID = :upload_id');
                $stmt_view->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt_view->bindValue(':upload_id', $row['UploadID']);
                $stmt_view->execute();
            }
            $result_file_title = null;
            if (count($system_types) == 1) {
                $result_file_title = phoromatic_system_id_to_name($system_types[0]) . ' Tests';
            }
            if (!empty($tickets) && $tickets[0] != null) {
                $system_name_format = 'ORIGINAL_DATA';
            } else {
                if (count($trigger_types) == 1 && $trigger_types[0] != null && $benchmark_tickets[0] != null && count($display_rows) > 1) {
                    $system_name_format = 'TRIGGER_AND_SYSTEM';
                } else {
                    if (empty($schedule_types[0])) {
                        $system_name_format = 'ORIGINAL_DATA';
                    } else {
                        if (count($display_rows) == 1) {
                            $system_name_format = 'SYSTEM_NAME';
                        } else {
                            if (count($schedule_types) == 1 && count($system_types) == 1) {
                                $system_name_format = 'TRIGGER';
                                $result_file_title = phoromatic_schedule_id_to_name($schedule_types[0]);
                            } else {
                                if (count($schedule_types) == 1) {
                                    $system_name_format = 'TRIGGER_AND_SYSTEM';
                                } else {
                                    if (false && count($trigger_types) == 1) {
                                        // TODO XXX: this approach yields garbage strings generally without refining the selector
                                        // i.e. first make sure all the schedules match or are comparable
                                        $system_name_format = 'SYSTEM_AND_SCHEDULE';
                                    } else {
                                        $system_name_format = null;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (count($schedule_types) == 1 && $schedule_types[0] != 0) {
                self::$schedule_id = $schedule_types[0];
            }
            foreach ($display_rows as $composite_xml => $row) {
                //  $row['SystemID'] . ' ' . $row['ScheduleID'] . ' ' . $row['Trigger']
                switch ($system_name_format) {
                    case 'ORIGINAL_DATA':
                        $system_name = null;
                        break;
                    case 'SYSTEM_NAME':
                        $system_name = phoromatic_system_id_to_name($row['SystemID']);
                        break;
                    case 'TRIGGER':
                        $system_name = $row['Trigger'];
                        break;
                    case 'TRIGGER_AND_SYSTEM':
                        $system_name = phoromatic_system_id_to_name($row['SystemID']) . ': ' . $row['Trigger'];
                        break;
                    case 'SYSTEM_AND_SCHEDULE':
                        $system_name = phoromatic_schedule_id_to_name($row['ScheduleID']) . ': ' . $row['Trigger'];
                        break;
                    default:
                        $system_name = phoromatic_system_id_to_name($row['SystemID']) . ' - ' . phoromatic_schedule_id_to_name($row['ScheduleID']) . ' - ' . $row['Trigger'];
                }
                if ($system_name == null) {
                    $rf = new pts_result_file($composite_xml);
                    $identifiers = $rf->get_system_identifiers();
                    if (count($identifiers) == 1) {
                        $system_name = $identifiers[0];
                    }
                }
                $system_name = str_replace('.SYSTEM', phoromatic_system_id_to_name($row['SystemID']), $system_name);
                $system_name = str_replace('.GROUP', phoromatic_account_id_to_group_name($row['AccountID']), $system_name);
                $system_variables = explode(';', phoromatic_server::system_id_variables($row['SystemID'], $row['AccountID']));
                foreach ($system_variables as $var) {
                    $var = explode('=', $var);
                    if (count($var) == 2) {
                        $system_name = str_replace('.' . $var[0], $var[1], $system_name);
                    }
                }
                $result_files[] = new pts_result_merge_select($composite_xml, null, $system_name);
            }
            $result_file = new pts_result_file(null, true);
            $result_file->set_title('Phoromatic Results');
            if (!empty($result_files)) {
                $attributes = array('new_result_file_title' => $result_file_title);
                if (!empty($result_files)) {
                    $result_file->merge($result_files, $attributes);
                }
            }
            $extra_attributes = array();
            if (isset($_GET['upload_to_openbenchmarking'])) {
                $ob_url = pts_openbenchmarking_client::upload_test_result($result_file, false);
                if ($ob_url) {
                    header('Location: ' . $ob_url);
                }
            }
            $attribute_options = array('normalize_results' => 'normalize_result_buffer', 'sort_by_performance' => 'sort_result_buffer_values', 'sort_by_reverse' => 'reverse_result_buffer', 'sort_by_name' => 'sort_result_buffer', 'condense_comparison' => 'condense_multi_way', 'force_line_graph' => 'force_tracking_line_graph');
            $url_append = null;
            foreach ($attribute_options as $web_var => $attr_var) {
                if (isset($_REQUEST[$web_var])) {
                    $extra_attributes[$attr_var] = true;
                    $url_append .= '&' . $web_var . '=1';
                }
            }
            if (isset($_POST['transpose_comparison'])) {
                $result_file->invert_multi_way_invert();
            }
            $intent = null;
            if (isset($_GET['download']) && $_GET['download'] == 'csv') {
                $result_csv = pts_result_file_output::result_file_to_csv($result_file);
                header('Content-Description: File Transfer');
                header('Content-Type: application/csv');
                header('Content-Disposition: attachment; filename=phoromatic-result.csv');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . strlen($result_csv));
                ob_clean();
                flush();
                echo $result_csv;
                return;
            } else {
                if (isset($_GET['download']) && $_GET['download'] == 'txt') {
                    $result_txt = pts_result_file_output::result_file_to_text($result_file);
                    header('Content-Description: File Transfer');
                    header('Content-Type: application/txt');
                    header('Content-Disposition: attachment; filename=phoromatic-result.txt');
                    header('Expires: 0');
                    header('Cache-Control: must-revalidate');
                    header('Pragma: public');
                    header('Content-Length: ' . strlen($result_txt));
                    ob_clean();
                    flush();
                    echo $result_txt;
                    return;
                } else {
                    if (isset($_GET['download']) && $_GET['download'] == 'pdf') {
                        ob_start();
                        $_REQUEST['force_format'] = 'PNG';
                        // Force to PNG renderer
                        $_REQUEST['svg_dom_gd_no_interlacing'] = true;
                        // Otherwise FPDF will fail
                        $tdir = pts_client::create_temporary_directory();
                        pts_client::generate_result_file_graphs($result_file, $tdir, $extra_attributes);
                        $pdf = new pts_pdf_template($result_file->get_title(), null);
                        $pdf->AddPage();
                        $pdf->Image(PTS_CORE_STATIC_PATH . 'images/pts-308x160.png', 69, 85, 73, 38);
                        $pdf->Ln(120);
                        $pdf->WriteStatementCenter('www.phoronix-test-suite.com');
                        $pdf->Ln(15);
                        $pdf->WriteBigHeaderCenter($result_file->get_title());
                        $pdf->WriteText($result_file->get_description());
                        $pdf->AddPage();
                        $pdf->Ln(15);
                        $pdf->SetSubject($result_file->get_title() . ' Benchmarks');
                        //$pdf->SetKeywords(implode(', ', $identifiers));
                        $pdf->WriteHeader('Test Systems:');
                        foreach ($result_file->get_systems() as $s) {
                            $pdf->WriteMiniHeader($s->get_identifier());
                            $pdf->WriteText($s->get_hardware());
                            $pdf->WriteText($s->get_software());
                        }
                        $pdf->AddPage();
                        $placement = 1;
                        $results = $result_file->get_result_objects();
                        for ($i = 1; $i <= count($results); $i++) {
                            if (is_file($tdir . 'result-graphs/' . $i . '.png')) {
                                $pdf->Ln(100);
                                $pdf->Image($tdir . 'result-graphs/' . $i . '.png', 50, 40 + ($placement - 1) * 120, 120);
                            }
                            if ($placement == 2) {
                                $placement = 0;
                                if ($i != count($results)) {
                                    $pdf->AddPage();
                                }
                            }
                            $placement++;
                        }
                        ob_get_clean();
                        $pdf->Output('phoromatic.pdf', 'I');
                        //pts_file_io::delete($tdir, null, true);
                        return;
                    } else {
                        if (isset($_GET['download']) && $_GET['download'] == 'xml') {
                            echo $result_file->get_xml();
                            return;
                        }
                    }
                }
            }
            $main .= '<h1>' . $result_file->get_title() . '</h1>';
            $main .= phoromatic_annotate_entry('RESULT', implode(',', $upload_ids), 'TOP');
            if ($result_file->get_system_count() == 1 || ($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true))) {
                $table = new pts_ResultFileCompactSystemsTable($result_file, $intent);
            } else {
                $table = new pts_ResultFileSystemsTable($result_file);
            }
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $table = new pts_ResultFileTable($result_file, $intent);
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $main .= '<div id="pts_results_area">';
            foreach ($result_file->get_result_objects(isset($_POST['show_only_changed_results']) ? 'ONLY_CHANGED_RESULTS' : -1) as $i => $result_object) {
                $main .= '<h2><a name="r-' . $i . '"></a><a name="' . $result_object->get_comparison_hash(true, false) . '"></a>' . $result_object->test_profile->get_title() . '</h2>';
                $main .= phoromatic_annotate_entry('RESULT', implode(',', $upload_ids), $result_object->get_comparison_hash(true, false));
                $main .= '<p class="result_object">';
                $main .= pts_render::render_graph_inline_embed($result_object, $result_file, $extra_attributes);
                $main .= '</p>';
            }
            $main .= '</div>';
        } else {
            // No result
        }
        $right = null;
        if (self::$schedule_id && !empty(self::$schedule_id)) {
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_schedules WHERE AccountID = :account_id AND ScheduleID = :schedule_id LIMIT 1');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':schedule_id', self::$schedule_id);
            $result = $stmt->execute();
            $row = $result->fetchArray();
            if (!empty($row)) {
                $right .= '<h3><a href="?schedules/' . $row['ScheduleID'] . '">' . $row['Title'] . '</a></h3>';
                if (!empty($row['ActiveOn'])) {
                    $right .= '<p align="center"><strong>' . phoromatic_schedule_activeon_string($row['ActiveOn'], $row['RunAt']) . '</strong></p>';
                }
                $right .= '<p>Compare this result file to the latest results from the past: ';
                $right .= '<select name="view_results_from_past" id="view_results_from_past" onchange="phoromatic_jump_to_results_from(\'' . $row['ScheduleID'] . '\', \'view_results_from_past\', \'' . $PATH[0] . ',\');">';
                $oldest_upload_time = strtotime(phoromatic_oldest_result_for_schedule(self::$schedule_id));
                $opts = array('Week' => 7, 'Three Weeks' => 21, 'Month' => 30, 'Quarter' => 90, 'Six Months' => 180, 'Year' => 365);
                foreach ($opts as $str_name => $time_offset) {
                    if ($oldest_upload_time > time() - 86400 * $time_offset) {
                        break;
                    }
                    $right .= '<option value="' . $time_offset . '">' . $str_name . '</option>';
                }
                $right .= '<option value="all">All Results</option>';
                $right .= '</select>';
                $right .= '</p>';
            }
        }
        if (true) {
            $compare_results = array();
            $hash_matches = 0;
            $ticket_matches = 0;
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND ComparisonHash = :comparison_hash AND PPRID NOT IN (:pprid) ORDER BY UploadTime DESC LIMIT 12');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':comparison_hash', $result_file->get_contained_tests_hash(false));
            $stmt->bindValue(':pprid', implode(',', $upload_ids));
            $result = $stmt->execute();
            while ($row = $result->fetchArray()) {
                $compare_results[$row['PPRID']] = $row;
                $hash_matches++;
            }
            foreach ($benchmark_tickets as $ticket_id) {
                $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND BenchmarkTicketID = :ticket_id AND PPRID NOT IN (:pprid) ORDER BY UploadTime DESC LIMIT 12');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':ticket_id', $ticket_id);
                $stmt->bindValue(':pprid', implode(',', $upload_ids));
                $result = $stmt->execute();
                while ($row = $result->fetchArray()) {
                    $compare_results[$row['PPRID']] = $row;
                    $ticket_matches++;
                }
            }
            if (!empty($compare_results)) {
                $right .= '<hr /><h3>Compare Results</h3><form name="compare_similar_results" onsubmit="return false;">
						<input type="hidden" value="' . implode(',', $upload_ids) . '" id="compare_similar_results_this" />';
                foreach ($compare_results as &$row) {
                    $right .= '<p><input type="checkbox" value="' . $row['PPRID'] . '" name="compare_results" /> ' . $row['Title'] . '<br /><em>' . phoromatic_system_id_to_name($row['SystemID'], $row['AccountID']) . '</em></p>';
                }
                $right .= '<p><input type="submit" value="Compare Results" id="compare_results_submit" onclick="javascript:phoromatic_do_custom_compare_results(this); return false;" /></p></form>';
                if ($ticket_matches > 3) {
                    $right .= '<p><a href="/results/ticket/' . $ticket_id . '">Find All Matching Results</a>';
                } else {
                    if ($hash_matches > 3) {
                        $right .= '<p><a href="/results/hash/' . $result_file->get_contained_tests_hash(false) . '">Find All Matching Results</a>';
                    }
                }
            }
        }
        if (count($upload_ids) > 1) {
            $checkbox_options = array('normalize_results' => 'Normalize Results', 'sort_by_performance' => 'Sort Results By Performance', 'sort_by_name' => 'Reverse Result By Identifier', 'sort_by_reverse' => 'Reverse Result Order', 'show_only_changed_results' => 'Show Only Results With Result Variation', 'force_line_graph' => 'Force Line Graph');
            if ($result_file->is_multi_way_comparison()) {
                $checkbox_options['condense_comparison'] = 'Condense Comparison';
                $checkbox_options['transpose_comparison'] = 'Transpose Comparison';
            }
            $right .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_result_view" method="post"><hr /><h3>Result Analysis Options</h3><p align="left">' . PHP_EOL;
            foreach ($checkbox_options as $val => $name) {
                $right .= '<input type="checkbox" name="' . $val . '" value="1" ' . (isset($_POST[$val]) ? 'checked="checked" ' : null) . '/> ' . $name . '<br />';
            }
            $right .= '<br /><input type="submit" value="Refresh Results"></p></form>';
        }
        if (self::$schedule_id && !empty(self::$schedule_id) && $system_types[0] && $trigger_types[0]) {
            $stmt = phoromatic_server::$db->prepare('SELECT UserContextStep FROM phoromatic_system_context_logs WHERE AccountID = :account_id AND ScheduleID = :schedule_id AND SystemID = :system_id AND TriggerID = :trigger_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $system_types[0]);
            $stmt->bindValue(':schedule_id', self::$schedule_id);
            $stmt->bindValue(':trigger_id', $trigger_types[0]);
            $result = $stmt->execute();
            if ($row = $result->fetchArray()) {
                $right .= '<hr /><h3>User Context Logs</h3>';
                do {
                    $right .= '<p><a href="?logs/context/' . $system_types[0] . ',' . self::$schedule_id . ',' . base64_encode($trigger_types[0]) . '">' . $row['UserContextStep'] . '</a></p>';
                } while ($row = $result->fetchArray());
            }
        }
        $right .= '<hr /><h3>Result Export</h3>';
        $right .= '<p><a href="/public.php?t=result&ut=' . implode(',', $upload_ids) . $url_append . '">Public Viewer</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=pdf' . $url_append . '">Download As PDF</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=csv">Download As CSV</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=xml">Download As XML</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=txt">Download As TEXT</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&upload_to_openbenchmarking">Upload To OpenBenchmarking.org</a></p>';
        if (is_file(phoromatic_server::phoromatic_account_result_path($_SESSION['AccountID'], $row['UploadID']) . 'system-logs.zip')) {
            $right .= '<hr /><p><a href="?logs/system/' . $row['UploadID'] . '">View System Logs</a></p>';
        }
        echo phoromatic_webui_header_logged_in();
        echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in($right));
        echo phoromatic_webui_footer();
    }
 protected function auto_generate_description()
 {
     $hw_components = array(pts_result_file_analyzer::system_component_string_to_array(phodevi::system_hardware(true)));
     $sw_components = array(pts_result_file_analyzer::system_component_string_to_array(phodevi::system_software(true)));
     if ($this->is_new_result_file) {
         $existing_identifiers = array();
         $hw_components = array();
         $sw_components = array();
         foreach ($this->result_file->get_systems() as $s) {
             array_push($hw_components, pts_result_file_analyzer::system_component_string_to_array($s->get_hardware()));
             array_push($sw_components, pts_result_file_analyzer::system_component_string_to_array($s->get_software()));
             array_push($existing_identifiers, $s->get_identifier());
         }
         $existing_identifier_count = count($existing_identifiers);
     } else {
         $existing_identifier_count = 0;
     }
     $auto_description = 'Running ' . implode(', ', array_unique($this->get_tests_to_run_identifiers()));
     $subsystems_to_test = $this->subsystems_under_test();
     // TODO: hook into $hw_components and $sw_components for leveraging existing result file data for comparisons already in existent
     // dropped: count($subsystems_to_test) == 1 && $
     if ($existing_identifier_count == 0) {
         switch ($subsystems_to_test) {
             case 'Graphics':
                 $auto_description = phodevi::read_property('gpu', 'model') . ' graphics testing with ' . phodevi::read_property('system', 'display-driver-string') . ' / ' . phodevi::read_property('system', 'opengl-driver');
                 break;
             case 'Disk':
                 $auto_description = phodevi::read_name('disk') . ' testing on ' . phodevi::read_property('system', 'operating-system') . ' with a ' . phodevi::read_property('system', 'filesystem') . ' file-system';
                 break;
             case 'Memory':
             case 'Processor':
                 $auto_description = phodevi::read_property('cpu', 'model') . ' testing with a ' . phodevi::read_name('motherboard') . ' on ' . phodevi::read_property('system', 'operating-system');
                 break;
             default:
                 if (phodevi::read_property('system', 'system-layer')) {
                     // Virtualization, Wine testing...
                     $auto_description = phodevi::read_property('system', 'system-layer') . ' testing on ' . phodevi::read_property('system', 'operating-system');
                 } else {
                     if (phodevi::read_name('motherboard') != null && phodevi::read_property('gpu', 'model') != null) {
                         // Standard description
                         $auto_description = phodevi::read_property('cpu', 'model') . ' testing with a ' . phodevi::read_name('motherboard') . ' and ' . phodevi::read_property('gpu', 'model') . ' on ' . phodevi::read_property('system', 'operating-system');
                     } else {
                         // A virtualized environment or a BSD or other OS where not all hardware info is available...
                         $auto_description = phodevi::read_property('cpu', 'model') . ' testing on ' . phodevi::read_property('system', 'operating-system');
                     }
                 }
                 break;
         }
     } else {
         if ($this->is_new_result_file) {
             $result_file_intent = pts_result_file_analyzer::analyze_result_file_intent($this->result_file);
             if (is_array($result_file_intent) && $result_file_intent[0] != 'Unknown') {
                 $auto_description = 'A ' . $result_file_intent[0] . ' comparison';
             }
         }
     }
     $auto_description .= ' via the Phoronix Test Suite.';
     return $auto_description;
 }
 public function renderGraph()
 {
     $this->i['top_heading_height'] = max(self::$c['size']['headers'] + 22 + self::$c['size']['key'], 48);
     $this->i['top_start'] = $this->i['top_heading_height'] + 50;
     $this->update_graph_dimensions($this->i['graph_width'], $this->i['graph_height'] + $this->i['top_start'], true);
     // Do the actual work
     $this->render_graph_init();
     $this->graph_key_height();
     $this->render_graph_key();
     $this->render_graph_heading();
     $work_area = $this->i['graph_left_end'] - $this->i['left_start'];
     $unit_size = floor($work_area / ($this->i['graph_max_value'] * 1.05));
     for ($i = $this->i['graph_max_value']; $i >= 0.99; $i -= ($this->i['graph_max_value'] - 1) / $this->i['mark_count']) {
         $num = pts_math::set_precision(round($i, 1), 1);
         $length = round($unit_size * $num);
         $this->svg_dom->draw_svg_arc($this->i['left_start'], $this->i['top_start'], $length, 10, 0.25, array('fill' => self::$c['color']['background'], 'stroke' => self::$c['color']['body_light'], 'stroke-width' => 1, 'stroke-dasharray' => '10,20'));
         $this->svg_dom->add_text_element($num, array('x' => $this->i['left_start'] + $length, 'y' => $this->i['top_start'] - self::$c['size']['tick_mark'] + 2, 'font-size' => self::$c['size']['tick_mark'], 'fill' => self::$c['color']['notches'], 'text-anchor' => 'middle'));
         $this->svg_dom->draw_svg_line($this->i['left_start'] + $length, $this->i['top_start'] - 6, $this->i['left_start'] + $length, $this->i['top_start'], self::$c['color']['notches'], 1);
         $this->svg_dom->add_text_element($num, array('x' => $this->i['left_start'] - 8, 'y' => $this->i['top_start'] + $length, 'font-size' => self::$c['size']['tick_mark'], 'fill' => self::$c['color']['notches'], 'text-anchor' => 'end', 'dominant-baseline' => 'middle'));
         $this->svg_dom->draw_svg_line($this->i['left_start'] - 6, $this->i['top_start'] + $length, $this->i['left_start'], $this->i['top_start'] + $length, self::$c['color']['notches'], 1);
     }
     $this->svg_dom->draw_svg_line($this->i['left_start'], $this->i['top_start'], $this->i['graph_left_end'], $this->i['top_start'], self::$c['color']['notches'], 1);
     $this->svg_dom->draw_svg_line($this->i['left_start'], $this->i['top_start'], $this->i['left_start'], $this->i['graph_top_end'], self::$c['color']['notches'], 1);
     $this->svg_dom->draw_svg_line($this->i['graph_left_end'], $this->i['graph_top_end'], $this->i['graph_left_end'], $this->i['top_start'], self::$c['color']['notches'], 1);
     $this->svg_dom->draw_svg_line($this->i['left_start'], $this->i['graph_top_end'], $this->i['graph_left_end'], $this->i['graph_top_end'], self::$c['color']['notches'], 1);
     for ($i = 1, $result_object_count = count($this->result_objects); $i < $result_object_count; $i++) {
         for ($c = 0, $c_count = $this->result_objects[$i]->test_result_buffer->get_count(); $c < $c_count; $c++) {
             $pre_rad = deg2rad(360 - ($i - 1) / $result_object_count * 90);
             $pre_result = $this->result_objects[$i - 1]->test_result_buffer->get_buffer_item($c)->get_result_value();
             $result = $this->result_objects[$i]->test_result_buffer->get_buffer_item($c)->get_result_value();
             if ($result_object_count - 1 == $i && 90 % $result_object_count != 0) {
                 $rad = deg2rad(270);
             } else {
                 $rad = deg2rad(360 - $i / $result_object_count * 90);
             }
             $result_identifier = $this->result_objects[$i]->test_result_buffer->get_buffer_item($c)->get_result_identifier();
             $pre_size = $unit_size * $pre_result;
             $size = $unit_size * $result;
             $tooltip = $this->result_objects[$i]->test_profile->get_title() . ' - ' . $this->result_objects[$i]->test_result_buffer->get_buffer_item($c)->get_result_identifier() . ' - ' . $this->result_objects[$i]->test_result_buffer->get_buffer_item($c)->get_result_value() . 'x Faster Than ' . $this->result_objects[$i]->test_result_buffer->get_buffer_item($c_count - 1)->get_result_identifier();
             $points = array(array($this->i['left_start'], $this->i['top_start']), array(round($this->i['left_start'] + cos($pre_rad) * $pre_size), round($this->i['top_start'] + abs(sin($pre_rad)) * $pre_size)), array(round($this->i['left_start'] + cos($rad) * $pre_size), round($this->i['top_start'] + abs(sin($rad)) * $pre_size)));
             $svg_poly = array();
             foreach ($points as $point_pair) {
                 array_push($svg_poly, implode(',', $point_pair));
             }
             $this->svg_dom->add_element('polygon', array('points' => implode(' ', $svg_poly), 'fill' => $this->get_paint_color($result_identifier), 'stroke' => self::$c['color']['text'], 'stroke-width' => 2, 'xlink:title' => $tooltip));
         }
     }
     $this->svg_dom->draw_svg_arc($this->i['left_start'], $this->i['top_start'], round($unit_size), 10, 0.25, array('fill' => self::$c['color']['background'], 'stroke' => self::$c['color']['notches'], 'stroke-width' => 1));
     $last_hardware_type = $this->result_objects[0]->test_profile->get_test_hardware_type();
     $hw_types = array();
     $last_hardware_type_i = 0;
     for ($i = 0, $result_object_count = count($this->result_objects); $i < $result_object_count; $i++) {
         $hardware_type = $this->result_objects[$i]->test_profile->get_test_hardware_type();
         if ($hardware_type != $last_hardware_type || $i == $result_object_count - 1) {
             if ($i != $result_object_count - 1) {
                 $rad = deg2rad(360 - $i / $result_object_count * 90);
                 $cos_unit = cos($rad) * $unit_size;
                 $sin_unit = abs(sin($rad)) * $unit_size;
                 $this->svg_dom->draw_svg_line(round($this->i['left_start'] + $cos_unit), round($this->i['top_start'] + $sin_unit), round($this->i['left_start'] + $cos_unit * $this->i['graph_max_value']), round($this->i['top_start'] + $sin_unit * $this->i['graph_max_value']), self::$c['color']['alert'], 1);
             }
             $rad = deg2rad(360 - (($i - $last_hardware_type_i) / 2 + $last_hardware_type_i) / $result_object_count * 90);
             $cos_unit = $this->i['left_start'] + cos($rad) * $unit_size * 0.9;
             $sin_unit = $this->i['top_start'] + abs(sin($rad)) * $unit_size * 0.9;
             $this->svg_dom->add_text_element($last_hardware_type, array('x' => $cos_unit, 'y' => $sin_unit, 'font-size' => self::$c['size']['bars'], 'fill' => self::$c['color']['alert'], 'text-anchor' => 'end', 'dominant-baseline' => 'middle'));
             array_push($hw_types, $last_hardware_type);
             $last_hardware_type = $hardware_type;
             $last_hardware_type_i = $i;
         }
     }
     $hw = array();
     $sw = array();
     foreach ($this->result_file->get_systems() as $system) {
         array_push($hw, $system->get_hardware());
         array_push($sw, $system->get_software());
     }
     $shw = array();
     foreach ($this->graph_data_title as $i => $title) {
         $merged = pts_result_file_analyzer::system_component_string_to_array($hw[$i] . ', ' . $sw[$i], $hw_types);
         if (!empty($merged)) {
             $shw[$title] = $merged;
         }
     }
     $i = 1;
     foreach ($shw as $key => $line) {
         $this->svg_dom->add_text_element(implode('; ', $line), array('x' => $this->i['graph_left_end'] - 4, 'y' => $this->i['graph_top_end'] - $i * self::$c['size']['key'], 'font-size' => self::$c['size']['key'], 'fill' => $this->get_paint_color($key), 'text-anchor' => 'end', 'dominant-baseline' => 'middle'));
         $i++;
     }
 }
    public static function render_page_process($PATH)
    {
        echo phoromatic_webui_header_logged_in();
        $main = null;
        if (isset($PATH[0]) && !empty($PATH[0])) {
            ini_set('memory_limit', '4G');
            if (isset($_POST['view_results_from_past']) && is_numeric($_POST['view_results_from_past'])) {
                $cut_duration = $_POST['view_results_from_past'];
            } else {
                $cut_duration = 21;
            }
            $stmt = phoromatic_server::$db->prepare('SELECT UploadID, UploadTime, ScheduleID, Trigger, SystemID FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':schedule_id', $PATH[0]);
            $test_result_result = $stmt->execute();
            $cutoff_time = is_numeric($cut_duration) ? strtotime('today -' . $cut_duration . ' days') : false;
            $show_only_latest_systems = array();
            $result_files = array();
            while ($test_result_result && ($row = $test_result_result->fetchArray())) {
                if ($cutoff_time !== false && strtotime($row['UploadTime']) < $cutoff_time) {
                    break;
                }
                $composite_xml = phoromatic_server::phoromatic_account_result_path($_SESSION['AccountID'], $row['UploadID']) . 'composite.xml';
                if (!is_file($composite_xml)) {
                    continue;
                }
                // Add to result file
                $system_name = phoromatic_server::system_id_to_name($row['SystemID']) . ': ' . $row['Trigger'];
                array_push($result_files, new pts_result_merge_select($composite_xml, null, $system_name));
                if (!isset($show_only_latest_systems[$_SESSION['AccountID'] . $row['SystemID']])) {
                    $show_only_latest_systems[$_SESSION['AccountID'] . $row['SystemID']] = new pts_result_merge_select($composite_xml, null, $system_name);
                }
            }
            if (count($result_files) < 21) {
                $show_only_latest_systems = null;
            }
            $attributes = array('new_result_file_title' => phoromatic_schedule_id_to_name($row['ScheduleID']));
            $result_file = new pts_result_file(null, true);
            $result_file->merge($result_files, $attributes);
            $extra_attributes = array('reverse_result_buffer' => true, 'force_simple_keys' => true, 'force_line_graph_compact' => true, 'force_tracking_line_graph' => true);
            if (isset($_POST['normalize_results']) && $_POST['normalize_results']) {
                $extra_attributes['normalize_result_buffer'] = true;
            }
            $main .= '<h1>' . $result_file->get_title() . '</h1>';
            if ($result_file->get_system_count() == 1 || ($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true))) {
                $table = new pts_ResultFileCompactSystemsTable($result_file, $intent);
            } else {
                $table = new pts_ResultFileSystemsTable($result_file);
            }
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $table = new pts_ResultFileTable($result_file, $intent);
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $main .= '<div id="pts_results_area">';
            foreach ($result_file->get_result_objects(isset($_POST['show_only_changed_results']) ? 'ONLY_CHANGED_RESULTS' : -1) as $i => $result_object) {
                $main .= '<h2><a name="r-' . $i . '"></a><a name="' . $result_object->get_comparison_hash(true, false) . '"></a>' . $result_object->test_profile->get_title() . '</h2>';
                $main .= '<p class="result_object">';
                $main .= pts_render::render_graph_inline_embed($result_object, $result_file, $extra_attributes);
                $main .= '</p>';
            }
            $main .= '</div>';
            $right = '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_result_view" method="post">';
            $right .= '<p>Compare results for the past: ';
            $right .= '<select name="view_results_from_past" id="view_results_from_past">';
            $oldest_upload_time = strtotime(phoromatic_oldest_result_for_schedule($PATH[0]));
            $opts = array('Two Weeks' => 14, 'Three Weeks' => 21, 'One Month' => 30, 'Two Months' => 60, 'Quarter' => 90, 'Six Months' => 180, 'Year' => 365);
            foreach ($opts as $str_name => $time_offset) {
                if ($oldest_upload_time > time() - 86400 * $time_offset) {
                    break;
                }
                $right .= '<option value="' . $time_offset . '">' . $str_name . '</option>';
            }
            $right .= '<option value="all">All Results</option>';
            $right .= '</select>';
            $right .= '</p>';
            $right .= '<p><input type="checkbox" name="normalize_results" value="1" ' . (isset($_POST['normalize_results']) ? 'checked="checked" ' : null) . '/> Normalize Results?</p>';
            $right .= '<p><input type="submit" value="Refresh Results"></p></form>';
        } else {
            if (empty($PATH)) {
                $main .= '<h1>Phoromatic Tracker</h1>
					<p>The Phoromatic Tracker will show result schedules that have enough uploaded test results from the associated systems to begin providing concise overviews of performance over time.</p>
					<div class="pts_phoromatic_info_box_area">
					<ul>
						<li><h1>Trackable Results</h1></li>';
                $stmt = phoromatic_server::$db->prepare('SELECT Title, ScheduleID, Description, RunTargetSystems, RunTargetGroups, RunAt, ActiveOn, (SELECT COUNT(*) FROM phoromatic_results WHERE ScheduleID = phoromatic_schedules.ScheduleID) AS UploadedResultCount FROM phoromatic_schedules WHERE AccountID = :account_id AND State >= 1 ORDER BY Title ASC');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if ($row == false) {
                    $main .= '<li class="light" style="text-align: center;">No Relevant Schedules Found</li>';
                } else {
                    do {
                        if ($row['UploadedResultCount'] > ($row['RunTargetSystems'] + $row['RunTargetGroups'] + 1) * 7) {
                            $stmt_tests = phoromatic_server::$db->prepare('SELECT COUNT(*) AS TestCount FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY TestProfile ASC');
                            $stmt_tests->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt_tests->bindValue(':schedule_id', $row['ScheduleID']);
                            $result_tests = $stmt_tests->execute();
                            $row_tests = $result_tests->fetchArray();
                            $test_count = !empty($row_tests) ? $row_tests['TestCount'] : 0;
                            $group_count = empty($row['RunTargetGroups']) ? 0 : count(explode(',', $row['RunTargetGroups']));
                            $main .= '<a href="?tracker/' . $row['ScheduleID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . pts_strings::plural_handler(count(phoromatic_server::systems_associated_with_schedule($_SESSION['AccountID'], $row['ScheduleID'])), 'System') . '</td><td>' . pts_strings::plural_handler($group_count, 'Group') . '</td><td>' . pts_strings::plural_handler($test_count, 'Test') . '</td><td>' . pts_strings::plural_handler($row['UploadedResultCount'], 'Result') . ' Total</td></tr></table></li></a>';
                        }
                    } while ($row = $result->fetchArray());
                }
                $main .= '</ul>
			</div>';
                $right = null;
            }
        }
        echo phoromatic_webui_main($main, $right);
        echo phoromatic_webui_footer();
    }
 public static function analyze_result_file_intent(&$result_file, &$flagged_results = -1, $return_all_changed_indexes = false)
 {
     $identifiers = array();
     $hw = array();
     $sw = array();
     foreach ($result_file->get_systems() as $system) {
         array_push($identifiers, $system->get_identifier());
         array_push($hw, $system->get_hardware());
         array_push($sw, $system->get_software());
     }
     if (count($identifiers) < 2) {
         // Not enough tests to be valid for anything
         return false;
     }
     foreach ($identifiers as $identifier) {
         if (pts_strings::string_only_contains($identifier, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH | pts_strings::CHAR_SPACE)) {
             // All the identifiers are just dates or other junk
             return false;
         }
     }
     $hw_unique = array_unique($hw);
     $sw_unique = array_unique($sw);
     $desc = false;
     if (count($hw_unique) == 1 && count($sw_unique) == 1) {
         // The hardware and software is maintained throughout the testing, so if there's a change in results its something we aren't monitoring
         // TODO XXX: Not sure this below check is needed anymore...
         if (true || count($hw) > 2 && $result_file->get_test_count() != count($hw)) {
             $desc = array('Unknown', implode(', ', $identifiers));
         }
     } else {
         if (count($sw_unique) == 1) {
             // The software is being maintained, but the hardware is being flipped out
             $rows = array();
             $data = array();
             pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $hw);
             pts_result_file_analyzer::compact_result_table_data($data, $identifiers, true);
             $desc = pts_result_file_analyzer::analyze_system_component_changes($data, $rows, array(array('Processor', 'Motherboard', 'Chipset', 'Audio', 'Network'), array('Processor', 'Motherboard', 'Chipset', 'Network'), array('Processor', 'Chipset', 'Graphics'), array('Processor', 'Graphics'), array('Processor', 'Chipset'), array('Motherboard', 'Chipset'), array('Motherboard', 'Chipset', 'Audio', 'Network'), array('Graphics', 'Audio')), $return_all_changed_indexes);
         } else {
             if (count($hw_unique) == 1) {
                 // The hardware is being maintained, but the software is being flipped out
                 $rows = array();
                 $data = array();
                 pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $sw);
                 pts_result_file_analyzer::compact_result_table_data($data, $identifiers, true);
                 $desc = pts_result_file_analyzer::analyze_system_component_changes($data, $rows, array(array('Display Driver', 'OpenGL'), array('OpenGL'), array('Display Driver')), $return_all_changed_indexes);
             } else {
                 // Both software and hardware are being flipped out
                 $rows = array();
                 $data = array();
                 pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $hw);
                 pts_result_file_analyzer::system_components_to_table($data, $identifiers, $rows, $sw);
                 pts_result_file_analyzer::compact_result_table_data($data, $identifiers, true);
                 $desc = pts_result_file_analyzer::analyze_system_component_changes($data, $rows, array(array('Memory', 'Graphics', 'Display Driver', 'OpenGL'), array('Graphics', 'Monitor', 'Kernel', 'Display Driver', 'OpenGL'), array('Graphics', 'Monitor', 'Display Driver', 'OpenGL'), array('Graphics', 'Kernel', 'Display Driver', 'OpenGL'), array('Graphics', 'Display Driver', 'OpenGL'), array('Graphics', 'OpenGL'), array('Graphics', 'Kernel'), array('Graphics', 'Display Driver')), $return_all_changed_indexes);
             }
         }
     }
     if ($desc) {
         if ($flagged_results === -1) {
             return $desc;
         } else {
             $mark_results = self::locate_interesting_results($result_file, $flagged_results);
             return array($desc[0], $desc[1], $mark_results);
         }
     }
     return false;
 }
    public static function render_page_process($PATH)
    {
        echo phoromatic_webui_header_logged_in();
        $main = null;
        if (!PHOROMATIC_USER_IS_VIEWER && !empty($PATH[0]) && isset($_POST['system_title']) && !empty($_POST['system_title']) && isset($_POST['system_description']) && isset($_POST['system_state'])) {
            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET Title = :title, Description = :description, State = :state, CurrentTask = \'Awaiting Task\', BlockPowerOffs = :block_power_offs WHERE AccountID = :account_id AND SystemID = :system_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $PATH[0]);
            $stmt->bindValue(':title', $_POST['system_title']);
            $stmt->bindValue(':description', $_POST['system_description']);
            $stmt->bindValue(':state', $_POST['system_state']);
            $stmt->bindValue(':block_power_offs', $_POST['block_power_offs']);
            $stmt->execute();
        }
        if (!PHOROMATIC_USER_IS_VIEWER && !empty($PATH[0]) && isset($_POST['maintenance_mode'])) {
            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET MaintenanceMode = :maintenance_mode WHERE AccountID = :account_id AND SystemID = :system_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $PATH[0]);
            $stmt->bindValue(':maintenance_mode', $_POST['maintenance_mode']);
            $stmt->execute();
        }
        if (!PHOROMATIC_USER_IS_VIEWER && !empty($PATH[0]) && isset($_POST['tick_thread_reboot'])) {
            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET TickThreadEvent = :event WHERE AccountID = :account_id AND SystemID = :system_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $PATH[0]);
            $stmt->bindValue(':event', time() . ':reboot');
            $stmt->execute();
        }
        if (!PHOROMATIC_USER_IS_VIEWER && !empty($PATH[0]) && isset($_POST['tick_thread_halt'])) {
            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET TickThreadEvent = :event WHERE AccountID = :account_id AND SystemID = :system_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $PATH[0]);
            $stmt->bindValue(':event', time() . ':halt-testing');
            $stmt->execute();
        }
        if (!PHOROMATIC_USER_IS_VIEWER && !empty($PATH[0]) && isset($_POST['system_var_names']) && isset($_POST['system_var_values'])) {
            $vars = array();
            foreach ($_POST['system_var_names'] as $i => $name) {
                if (isset($_POST['system_var_values'][$i])) {
                    $name = pts_strings::keep_in_string(strtoupper($name), pts_strings::CHAR_LETTER | pts_strings::CHAR_NUMERIC | pts_strings::CHAR_UNDERSCORE);
                    $val = pts_strings::keep_in_string($_POST['system_var_values'][$i], pts_strings::CHAR_LETTER | pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH | pts_strings::CHAR_UNDERSCORE | pts_strings::CHAR_COMMA | pts_strings::CHAR_SLASH | pts_strings::CHAR_SPACE | pts_strings::CHAR_DECIMAL | pts_strings::CHAR_PLUS | pts_strings::CHAR_EQUAL);
                    if ($name != null) {
                        $vars[$name] = $val;
                    }
                }
            }
            $var_string = null;
            foreach ($vars as $name => $val) {
                $var_string .= $name . '=' . $val . ';';
            }
            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET SystemVariables = :system_variables WHERE AccountID = :account_id AND SystemID = :system_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $PATH[0]);
            $stmt->bindValue(':system_variables', $var_string);
            $stmt->execute();
        }
        if (!empty($PATH[0])) {
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_systems WHERE AccountID = :account_id AND SystemID = :system_id ORDER BY LastCommunication DESC');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $PATH[0]);
            $result = $stmt->execute();
            if (!empty($result)) {
                $row = $result->fetchArray();
                if (!PHOROMATIC_USER_IS_VIEWER && isset($PATH[1]) && $PATH[1] == 'edit') {
                    $main = '<h1>' . $row['Title'] . '</h1>';
                    $main .= '<form name="system_form" id="system_form" action="?systems/' . $PATH[0] . '" method="post" onsubmit="return phoromatic_system_edit(this);">
			<p><div style="width: 200px; font-weight: bold; float: left;">System Title:</div> <input type="text" style="width: 400px;" name="system_title" value="' . $row['Title'] . '" /></p>
			<p><div style="width: 200px; font-weight: bold; float: left;">System Description:</div> <textarea style="width: 400px;" name="system_description">' . $row['Description'] . '</textarea></p>
			<p><div style="width: 200px; font-weight: bold; float: left;">System State:</div><select name="system_state" style="width: 200px;"><option value="-1">Disabled</option><option value="1" selected="selected">Enabled</option></select></p>
			<p><div style="width: 200px; font-weight: bold; float: left;">Allow Phoromatic To Power Off System When Testing Complete:</div><select name="block_power_offs" style="width: 200px;"><option value="0">Permitted</option><option value="1">Block Power-Off Signaling For This System</option></select> <sup>Assuming the power-off setting is enabled from the account settings page.</sup></p>
			<p><div style="width: 200px; font-weight: bold; float: left;">&nbsp;</div> <input type="submit" value="Submit" /></p></form>';
                } else {
                    $main = '<h1>' . $row['Title'] . '</h1><p><em>' . ($row['Description'] != null ? $row['Description'] : 'No system description.') . '</em></p>';
                    if (phoromatic_server::system_check_if_down($_SESSION['AccountID'], $row['SystemID'], $row['LastCommunication'], $row['CurrentTask'])) {
                        $main .= '<h3 style="text-align: center; color: red;">This system appears to be offline or inactive and there are pending tests scheduled to be run on this system that have yet to be completed. This system has not communicated with the Phoromatic Server in ' . pts_strings::format_time(time() - strtotime($row['LastCommunication']), 'SECONDS', true, 60) . '.</h3>';
                    }
                    if (!PHOROMATIC_USER_IS_VIEWER) {
                        $main .= '<p><a href="?systems/' . $PATH[0] . '/edit">Edit Task & Enable/Disable System</a></p>';
                    }
                }
                switch ($row['State']) {
                    case -1:
                        $state = 'Disabled';
                        break;
                    case 0:
                        $state = 'Connected; Awaiting Approval';
                        break;
                    case 1:
                        $state = 'Active';
                        break;
                }
                $main .= '<hr />';
                $info_table = array('Status:' => $row['CurrentTask'], 'Last Communication:' => phoromatic_user_friendly_timedate($row['LastCommunication']), 'Estimated Time Left For Task: ' => phoromatic_compute_estimated_time_remaining_string($row['EstimatedTimeForTask'], $row['LastCommunication']), 'State:' => $state, 'Phoronix Test Suite Client:' => $row['ClientVersion'], 'Initial Creation:' => phoromatic_user_friendly_timedate($row['CreatedOn']), 'System ID:' => $row['SystemID'], 'Last IP:' => $row['LastIP'], 'MAC Address:' => $row['NetworkMAC'], 'Wake-On-LAN Information:' => empty($row['NetworkWakeOnLAN']) ? 'N/A' : $row['NetworkWakeOnLAN'], 'Power-Off Sequence Permitted: ' => $row['BlockPowerOffs'] == 1 ? 'Blocked' : 'Permitted');
                $main .= '<h2>System State</h2>' . pts_webui::r2d_array_to_table($info_table, 'auto');
                if (!PHOROMATIC_USER_IS_VIEWER) {
                    if ($row['MaintenanceMode'] == 1) {
                        $mm_str = 'Disable Maintenance Mode';
                        $mm_val = 0;
                        $mm_onclick = 'return true;';
                    } else {
                        $mm_str = 'Enter Maintenance Mode';
                        $mm_val = 1;
                        $mm_onclick = 'return confirm(\'Enter maintenance mode now?\');';
                    }
                    $main .= '<p><form action="' . $_SERVER['REQUEST_URI'] . '" name="update_groups" method="post"><input type="hidden" name="maintenance_mode" value="' . $mm_val . '" /><input type="submit" value="' . $mm_str . '" onclick="' . $mm_onclick . '" style="float: left; margin: 0 20px 5px 0;" /></form> Putting the system into maintenance mode will power up the system (if supported and applicable) and cause the Phoronix Test Suite Phoromatic client to idle and block all testing until the mode has been disabled. If a test is already running on the system, the maintenance mode will not be entered until after the testing has completed. The maintenance mode can be used if wishing to update the system software or carry out other tasks without interfering with the Phoromatic client process. Once disabled, the Phoronix Test Suite will continue to function as normal.</p>';
                    if ($row['CoreVersion'] >= 5730) {
                        $main .= '<p><form action="' . $_SERVER['REQUEST_URI'] . '" name="update_groups" method="post"><input type="hidden" name="tick_thread_reboot" value="1" /><input type="submit" value="Reboot System" style="float: left; margin: 0 20px 5px 0;" /></form> If the system is currently powered up and connected to the Phoromatic Server, this will send a message to the system to issue a reboot -- in case the system is hung on a test or you wish to otherwise manually reboot the server. This feature was added with Phoronix Test Suite 5.8.</p>';
                        $main .= '<p><form action="' . $_SERVER['REQUEST_URI'] . '" name="update_groups" method="post"><input type="hidden" name="tick_thread_halt" value="1" /><input type="submit" value="Halt Testing" style="float: left; margin: 0 20px 5px 0;" /></form> If the system is currently powered up and running a test/benchmark via the Phoromatic Server, this will tell the system to halt the testing prematurely as soon as the currently-active test has finished. The results successfully ran will then be uploaded to the Phoromatic Server. This feature was added with Phoronix Test Suite 5.8.</p>';
                    }
                }
                $main .= '<hr /><h2>System Variables</h2><p>System variables are a new feature of Phoronix Test Suite 5.6 to allow for providing per-system information in an easy-to-use manner for other parts of the Phoromatic system. Initially these named variables can be used for the results identifier when <a href="/?benchmark">creating a benchmark ticket</a> and in the future the system variables may be used elsewhere. Examples of system variables could include providing a <em>.SERIAL</em> variable to acknowledge the system\'s serial number that may not be presented elsewhere by the Phoronix Test Suite, <em>.ADMIN</em> for the system\'s local administrator, etc. Variable names can only be alpha-numeric strings while their values are also alpha-numeric strings but with spaces allowed. System variables are always prefixed by a period. These system variables are also automatically transferred to the Phoromatic clients and set as environment variables prior to running any scheduled tests/process via Phoromatic.</p>';
                $system_variables = explode(';', $row['SystemVariables']);
                $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_system_variables" method="post">';
                $main .= '<table width="80%"><tr><th>Variable Name</th><th>Value</th></tr>';
                foreach ($system_variables as $i => $v_string) {
                    $var = explode('=', $v_string);
                    if (count($var) == 2) {
                        $main .= '<tr id="system_var_' . $i . '">';
                        $main .= '<td><span style="font-weight: 800; font-size: 16px;">.</span><input name="system_var_names[]" value="' . $var[0] . '" readonly /></td>';
                        $main .= '<td><input name="system_var_values[]" value="' . $var[1] . '" readonly /></td>';
                        $main .= '</tr>';
                    }
                }
                $main .= '<tr id="system_var_' . ($i + 1) . '">';
                $main .= '<td><span style="font-weight: 800; font-size: 16px;">.</span><input name="system_var_names[]" /></td>';
                $main .= '<td><input name="system_var_values[]" /></td>';
                $main .= '</tr>';
                $main .= '</table>';
                $main .= '<p><input name="submit" value="Update System Variables" type="submit" /></p></form>';
                $main .= '<hr /><h2>System Components</h2><div style="float: left; width: 50%;">';
                $components = pts_result_file_analyzer::system_component_string_to_array($row['Hardware']);
                $main .= pts_webui::r2d_array_to_table($components) . '</div><div style="float: left; width: 50%;">';
                $components = pts_result_file_analyzer::system_component_string_to_array($row['Software']);
                $main .= pts_webui::r2d_array_to_table($components) . '</div>';
                $system_path = phoromatic_server::phoromatic_account_system_path($_SESSION['AccountID'], $row['SystemID']);
                $main .= '<hr />';
                if (is_file($system_path . 'sensors-pool.json')) {
                    $sensors = file_get_contents($system_path . 'sensors-pool.json');
                    $sensors = json_decode($sensors, true);
                    foreach ($sensors as $title => $s) {
                        if (!isset($s['values']) || count($s['values']) < 5 || max($s['values']) == min($s['values'])) {
                            continue;
                        }
                        $graph = new pts_sys_graph(array('title' => $title, 'x_scale' => 'm', 'y_scale' => $s['unit'], 'text_size' => 12, 'reverse_x_direction' => false, 'width' => 920, 'height' => 400));
                        $graph->render_base();
                        $svg_dom = $graph->render_graph_data($s['values']);
                        if ($svg_dom === false) {
                            continue;
                        }
                        $output_type = 'SVG';
                        $graph = $svg_dom->output(null, $output_type);
                        $main .= '<p align="center">' . substr($graph, strpos($graph, '<svg')) . '</p>';
                    }
                } else {
                    if (is_file($system_path . 'sensors.json')) {
                        $sensor_file = file_get_contents($system_path . 'sensors.json');
                        $sensor_file = json_decode($sensor_file, true);
                        if ($sensor_file && isset($sensor_file['sensors']) && !empty($sensor_file['sensors'])) {
                            $i = 0;
                            $col = array(1 => array(), 2 => array(), 3 => array(), 0 => array());
                            foreach ($sensor_file['sensors'] as $name => $sensor) {
                                array_push($col[$i % 4], '<strong>' . $name . ':</strong> ' . $sensor['value'] . ' ' . $sensor['unit']);
                                $i++;
                            }
                            $main .= '<h2>System Sensors</h2>';
                            foreach ($col as $sensors) {
                                $main .= '<div style="float: left; width: 25%;">';
                                foreach ($sensors as $sensor) {
                                    $main .= '<p>' . $sensor . '</p>';
                                }
                                $main .= '</div>';
                            }
                            $main .= '<p><em><strong>Last Updated:</strong>' . date('d F H:i', filemtime(phoromatic_server::phoromatic_account_system_path($_SESSION['AccountID'], $row['SystemID']) . 'sensors.json')) . ' <strong>System Uptime:</strong> ' . $sensor_file['uptime'] . ' Minutes</em></p>';
                        }
                    }
                }
                $log_file = phoromatic_server::phoromatic_account_system_path($_SESSION['AccountID'], $row['SystemID']) . 'phoronix-test-suite.log';
                if (is_file($log_file)) {
                    $main .= '<hr /><h2>Phoronix Test Suite Client Log</h2>';
                    $main .= '<p><textarea style="width: 60%; height: 200px;">' . file_get_contents($log_file) . '</textarea></p>';
                    $main .= '<p><em><strong>Last Updated:</strong>' . date('d F H:i', filemtime($log_file)) . '</em></p>';
                }
                $groups = explode('#', $row['Groups']);
                foreach ($groups as $i => $group) {
                    if (empty($group)) {
                        unset($groups[$i]);
                    }
                }
                $schedules = phoromatic_server::schedules_that_run_on_system($_SESSION['AccountID'], $row['SystemID']);
                if (!empty($groups) || !empty($schedules)) {
                    $main .= '<hr /><h2>Schedules</h2>';
                    if (!empty($groups)) {
                        $group_msg = 'This system belongs to the following groups: <strong>' . implode(', ', $groups) . '</strong>.';
                    } else {
                        $group_msg = 'This system does not currently belong to any groups.';
                    }
                    $main .= '<p>' . $group_msg . ' Manage groups via the <a href="?systems">systems page</a>.</p>';
                    if (!empty($schedules)) {
                        $main .= '<div class="pts_phoromatic_info_box_area" style="margin: 0 10%;"><ul><li><h1>Schedules Running On This System</h1></li>';
                        foreach ($schedules as &$row) {
                            $group_count = empty($row['RunTargetGroups']) ? 0 : count(explode(',', $row['RunTargetGroups']));
                            $main .= '<a href="?schedules/' . $row['ScheduleID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . pts_strings::plural_handler(count(phoromatic_server::systems_associated_with_schedule($_SESSION['AccountID'], $row['ScheduleID'])), 'System') . '</td><td>' . pts_strings::plural_handler($group_count, 'Group') . '</td><td>' . pts_strings::plural_handler(phoromatic_results_for_schedule($row['ScheduleID']), 'Result') . '</td><td><strong>' . phoromatic_schedule_activeon_string($row['ActiveOn'], $row['RunAt']) . '</strong></td></tr></table></li></a>';
                        }
                        $main .= '</ul></div>';
                    }
                }
                $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, ScheduleID, PPRID, UploadTime FROM phoromatic_results WHERE AccountID = :account_id AND SystemID = :system_id ORDER BY UploadTime DESC');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':system_id', $PATH[0]);
                $test_result_result = $stmt->execute();
                $test_result_row = $test_result_result->fetchArray();
                $results = 0;
                if ($test_result_row != false) {
                    $main .= '<hr /><h2>Test Results</h2>';
                    $main .= '<div class="pts_phoromatic_info_box_area" style="margin: 0 10%;">';
                    $main .= '<ul><li><h1>Recent Test Results</h1></li>';
                    do {
                        if ($results > 20) {
                            break;
                        }
                        $main .= '<a href="?result/' . $test_result_row['PPRID'] . '"><li>' . $test_result_row['Title'] . '<br /><table><tr><td>' . phoromatic_system_id_to_name($test_result_row['SystemID']) . '</td><td>' . phoromatic_user_friendly_timedate($test_result_row['UploadTime']) . '</td></tr></table></li></a>';
                        $results++;
                    } while ($test_result_row = $test_result_result->fetchArray());
                }
                if ($results > 0) {
                    $main .= '</ul></div>';
                }
                // Any System Errors?
                $stmt = phoromatic_server::$db->prepare('SELECT ErrorMessage, UploadTime, SystemID, TestIdentifier FROM phoromatic_system_client_errors WHERE AccountID = :account_id AND SystemID = :system_id ORDER BY UploadTime DESC LIMIT 10');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':system_id', $PATH[0]);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if ($row != false) {
                    $main .= '<hr /><div class="pts_phoromatic_info_box_area" style="margin: 0 10%;"><ul><li><h1>Recent System Warnings &amp; Errors</h1></li>';
                    do {
                        $main .= '<a onclick=""><li>' . $row['ErrorMessage'] . '<br /><table><tr><td>' . $row['UploadTime'] . '</td><td>' . $row['TestIdentifier'] . '</td></tr></table></li></a>';
                    } while ($row = $result->fetchArray());
                    $main .= '	</ul></div>';
                }
            }
        }
        if ($main == null) {
            if (!PHOROMATIC_USER_IS_VIEWER && isset($_POST['new_group']) && !empty($_POST['new_group'])) {
                $group = trim($_POST['new_group']);
                if ($group) {
                    $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_groups (AccountID, GroupName) VALUES (:account_id, :group_name)');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':group_name', $group);
                    $result = $stmt->execute();
                    phoromatic_add_activity_stream_event('groups', $group, 'added');
                    if (!empty($_POST['systems_for_group']) && is_array($_POST['systems_for_group'])) {
                        foreach ($_POST['systems_for_group'] as $sid) {
                            // Find current groups
                            $stmt = phoromatic_server::$db->prepare('SELECT Groups FROM phoromatic_systems WHERE AccountID = :account_id AND SystemID = :system_id ORDER BY LastCommunication DESC');
                            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt->bindValue(':system_id', $sid);
                            $result = $stmt->execute();
                            $row = $result->fetchArray();
                            $existing_groups = $row != false ? $row['Groups'] : null;
                            // Append new Group
                            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET Groups = :new_group WHERE AccountID = :account_id AND SystemID = :system_id');
                            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt->bindValue(':system_id', $sid);
                            $stmt->bindValue(':new_group', $existing_groups . '#' . $group . '#');
                            $stmt->execute();
                        }
                    }
                }
            } else {
                if (!PHOROMATIC_USER_IS_VIEWER && isset($_POST['system_group_update'])) {
                    $stmt = phoromatic_server::$db->prepare('SELECT SystemID FROM phoromatic_systems WHERE AccountID = :account_id');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $result = $stmt->execute();
                    phoromatic_add_activity_stream_event('groups', null, 'modified');
                    while ($row = $result->fetchArray()) {
                        if (isset($_POST['groups_' . $row['SystemID']])) {
                            $group_string = null;
                            foreach ($_POST['groups_' . $row['SystemID']] as $group) {
                                if ($group != null) {
                                    $group_string .= '#' . $group . '#';
                                }
                            }
                            $stmt1 = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET Groups = :new_groups WHERE AccountID = :account_id AND SystemID = :system_id');
                            $stmt1->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt1->bindValue(':system_id', $row['SystemID']);
                            $stmt1->bindValue(':new_groups', $group_string);
                            $stmt1->execute();
                        }
                    }
                } else {
                    if (!PHOROMATIC_USER_IS_VIEWER && isset($_POST['remove_group'])) {
                        $stmt = phoromatic_server::$db->prepare('DELETE FROM phoromatic_groups WHERE AccountID = :account_id AND GroupName = :group_name');
                        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                        $stmt->bindValue(':group_name', $_POST['remove_group']);
                        $stmt->execute();
                        phoromatic_add_activity_stream_event('groups', $group, 'removed');
                        $stmt = phoromatic_server::$db->prepare('SELECT SystemID, Groups FROM phoromatic_systems WHERE AccountID = :account_id AND Groups LIKE \'%#' . $_POST['remove_group'] . '#%\'');
                        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                        $result = $stmt->execute();
                        while ($row = $result->fetchArray()) {
                            $revised_groups = str_replace('#' . $_POST['remove_group'] . '#', null, $row['Groups']);
                            $stmt1 = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET Groups = :new_groups WHERE AccountID = :account_id AND SystemID = :system_id');
                            $stmt1->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt1->bindValue(':system_id', $row['SystemID']);
                            $stmt1->bindValue(':new_groups', $revised_groups);
                            $stmt1->execute();
                        }
                    }
                }
            }
            $main = '<h1>Test Systems</h1>';
            if (!PHOROMATIC_USER_IS_VIEWER) {
                $main .= phoromatic_systems_needing_attention();
                $main .= '<h2>Add A System</h2>
				<p>To connect a <a href="http://www.phoronix-test-suite.com/">Phoronix Test Suite</a> test system to this account for remotely managing and/or carrying out routine automated benchmarking, follow these simple and quick steps:</p>
				<ol><li>From a system with <em>Phoronix Test Suite 5.4 or newer</em> run <strong>phoronix-test-suite phoromatic.connect ' . phoromatic_web_socket_server_addr() . '</strong>. (The test system must be able to access this server\'s correct IP address / domain name.)</li><li>When you have run the command from the test system, you will need to log into this page on Phoromatic server again where you can approve the system and configure the system settings so you can begin using it as part of this Phoromatic account.</li><li>Repeat the two steps for as many systems as you would like! When you are all done -- if you haven\'t done so already, you can start creating test schedules, groups, and other Phoromatic events.</li></ol>
				<p>Those having to connect many Phoronix Test Suite Phoromatic clients can also attempt <a href="?system_claim">adding the server configuration</a> via SSH or an IP/MAC address claim.</p>
				<p><button onclick="javascript:window.location.replace(\'?system_claim\');">Add Via SSH Or IP/MAC Claim</button></p>';
            }
            $main .= '<hr />

			<h2>Systems</h2>
			<div class="pts_phoromatic_info_box_area" style="margin: 0 10%;">

					<ul>
						<li><h1>Active Systems</h1></li>';
            $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, LocalIP, CurrentTask, LastCommunication, EstimatedTimeForTask, TaskPercentComplete FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 ORDER BY LastCommunication DESC');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $result = $stmt->execute();
            $row = $result->fetchArray();
            $active_system_count = 0;
            if ($row == false) {
                $main .= '<li class="light" style="text-align: center;">No Systems Found</li>';
            } else {
                do {
                    $acti = phoromatic_compute_estimated_time_remaining_string($row['EstimatedTimeForTask'], $row['LastCommunication']) . ($row['TaskPercentComplete'] > 0 ? ' [' . $row['TaskPercentComplete'] . '% Complete]' : null);
                    if (empty($acti)) {
                        $next_job_in = phoromatic_server::time_to_next_scheduled_job($_SESSION['AccountID'], $row['SystemID']);
                        if ($next_job_in > 0) {
                            if ($next_job_in > 600) {
                                $next_job_in = round($next_job_in / 60);
                                $next_unit = 'hours';
                            } else {
                                $next_unit = 'minutes';
                            }
                            $acti = 'Next job in ' . $next_job_in . ' ' . $next_unit;
                        }
                    }
                    $main .= '<a href="?systems/' . $row['SystemID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . $row['LocalIP'] . '</td><td><strong>' . $row['CurrentTask'] . '</strong></td><td><strong>' . $acti . '</strong></td><td><strong>Last Communication:</strong> ' . date('j F Y H:i', strtotime($row['LastCommunication'])) . '</td></tr></table></li></a>';
                    $active_system_count++;
                } while ($row = $result->fetchArray());
            }
            $main .= '</ul>';
            $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, LocalIP, CurrentTask, LastCommunication, EstimatedTimeForTask, TaskPercentComplete FROM phoromatic_systems WHERE AccountID = :account_id AND State < 0 ORDER BY LastCommunication DESC');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $result = $stmt->execute();
            $row = $result->fetchArray();
            if ($row != false) {
                $main .= '<ul>
				<li><h1>Inactive Systems</h1></li>';
                do {
                    $main .= '<a href="?systems/' . $row['SystemID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . $row['LocalIP'] . '</td><td><strong>' . $row['CurrentTask'] . '</strong></td><td><strong>Deactivated</strong></td><td><strong>Last Communication:</strong> ' . date('j F Y H:i', strtotime($row['LastCommunication'])) . '</td></tr></table></li></a>';
                } while ($row = $result->fetchArray());
                $main .= '</ul>';
            }
            $main .= '</div>';
            if ($active_system_count > 2) {
                $main .= '<h3 align="center"><a href="/?component_table">System Component Table</a> | <a href="/?maintenance_table">System Maintenance Table</a> | <a href="/?dashboard">System Dashboard</a></h3>';
            }
            if (!PHOROMATIC_USER_IS_VIEWER) {
                $main .= '<hr />
				<h2>System Groups</h2>
				<p>System groups make it very easy to organize multiple test systems for targeting by test schedules. You can always add/remove systems to groups, create new groups, and add systems to multiple groups. After creating a group and adding systems to the group, you can begin targeting tests against a particular group of systems. Systems can always be added/removed from groups later and a system can belong to multiple groups.</p>';
                $main .= '<div style="float: left;"><form name="new_group_form" id="new_group_form" action="?systems" method="post" onsubmit="return phoromatic_new_group(this);">
				<p><div style="width: 200px; font-weight: bold; float: left;">New Group Name:</div> <input type="text" style="width: 300px;" name="new_group" value="" /></p>
				<p><div style="width: 200px; font-weight: bold; float: left;">Select System(s) To Add To Group:</div><select name="systems_for_group[]" multiple="multiple" style="width: 300px;">';
                $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 ORDER BY Title ASC');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if ($row != false) {
                    do {
                        $main .= '<option value="' . $row['SystemID'] . '">' . $row['Title'] . '</option>';
                    } while ($row = $result->fetchArray());
                }
                $main .= '</select></p>
				<p><div style="width: 200px; font-weight: bold; float: left;">&nbsp;</div> <input type="submit" value="Create Group" /></p></form></div>';
                $stmt = phoromatic_server::$db->prepare('SELECT GroupName FROM phoromatic_groups WHERE AccountID = :account_id ORDER BY GroupName ASC');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if ($row != false) {
                    $main .= '<div style="float: left; margin-left: 90px;"><h3>Current System Groups</h3>';
                    do {
                        $stmt_count = phoromatic_server::$db->prepare('SELECT COUNT(SystemID) AS system_count FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 AND Groups LIKE \'%#' . $row['GroupName'] . '#%\'');
                        $stmt_count->bindValue(':account_id', $_SESSION['AccountID']);
                        $result_count = $stmt_count->execute();
                        $row_count = $result_count->fetchArray();
                        $row_count['system_count'] = isset($row_count['system_count']) ? $row_count['system_count'] : 0;
                        $main .= '<div style="clear: both;"><div style="width: 200px; float: left; font-weight: bold;">' . $row['GroupName'] . '</div> ' . $row_count['system_count'] . ' System' . ($row_count['system_count'] != 1 ? 's' : '') . '</div>';
                    } while ($row = $result->fetchArray());
                    $main .= '</div>';
                    $main .= '<hr /><a name="group_edit"></a><h2>System Group Editing</h2><div style="text-align: center;"><form action="' . $_SERVER['REQUEST_URI'] . '" name="update_groups" method="post"><input type="hidden" name="system_group_update"  value="1" />';
                    $main .= '<table style="margin: 5px auto; overflow: auto;">';
                    $main .= '<tr>';
                    $main .= '<th></th>';
                    $stmt = phoromatic_server::$db->prepare('SELECT GroupName FROM phoromatic_groups WHERE AccountID = :account_id ORDER BY GroupName ASC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $result = $stmt->execute();
                    $all_groups = array();
                    while ($row = $result->fetchArray()) {
                        $main .= '<th>' . $row['GroupName'] . '</th>';
                        array_push($all_groups, $row['GroupName']);
                    }
                    $main .= '</tr>';
                    $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, Groups FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 ORDER BY Title ASC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $result = $stmt->execute();
                    while ($row = $result->fetchArray()) {
                        $main .= '<tr>';
                        $main .= '<th>' . $row['Title'] . '</th>';
                        $main .= '<input type="hidden" name="groups_' . $row['SystemID'] . '[]" value="" />';
                        foreach ($all_groups as $group) {
                            $checked = stripos($row['Groups'], '#' . $group . '#') !== false ? 'checked="checked" ' : null;
                            $main .= '<td><input type="checkbox" name="groups_' . $row['SystemID'] . '[]" value="' . $group . '" ' . $checked . '/></td>';
                        }
                        $main .= '</tr>';
                    }
                    $main .= '</table><p><input name="submit" value="Update Groups" type="submit" /></p></form></div>';
                    $main .= '<hr /><h2>Remove A Group</h2><p>Removing a group is a permanent action that cannot be undone.</p>';
                    $main .= '<p><form action="' . $_SERVER['REQUEST_URI'] . '" name="remove_group" method="post"><select name="remove_group" id="remove_group">';
                    foreach ($all_groups as $group) {
                        $main .= '<option value="' . $group . '">' . $group . '</option>';
                    }
                    $main .= '</select> <input name="submit" value="Remove Group" type="submit" /></form></p>';
                }
            }
        }
        $right = '<ul><li>Active Systems</li>';
        $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID FROM phoromatic_systems WHERE AccountID = :account_id AND State > 0 ORDER BY Title ASC');
        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
        $result = $stmt->execute();
        $row = $result->fetchArray();
        if ($row == false) {
            $right .= '</ul><p style="text-align: left; margin: 6px 10px;">No Systems Found</p>';
        } else {
            do {
                $right .= '<li><a href="?systems/' . $row['SystemID'] . '">' . $row['Title'] . '</a></li>';
            } while ($row = $result->fetchArray());
            $right .= '</ul>';
        }
        echo '<div id="pts_phoromatic_main_area">' . $main . '</div>';
        echo phoromatic_webui_footer();
    }
 public static function render_page_process($PATH)
 {
     echo phoromatic_webui_header_logged_in();
     $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 ORDER BY LastCommunication DESC');
     $stmt->bindValue(':account_id', $_SESSION['AccountID']);
     $result = $stmt->execute();
     echo '<script type="text/javascript"> setInterval(function() { window.location.reload(); }, 79000); </script>';
     echo '<div style="margin: 10px 0 30px; clear: both; padding-bottom: 40px;">';
     while ($row = $result->fetchArray()) {
         $opacity = null;
         // stripos($row['CurrentTask'], 'idling') !== false ||
         if (phoromatic_server::system_check_if_down($_SESSION['AccountID'], $row['SystemID'], $row['LastCommunication'], $row['CurrentTask']) || stripos($row['CurrentTask'], 'Unknown') !== false) {
             $not_testing = false;
             $opacity = ' style="background: #f44336; color: #FFF;"';
         } else {
             if (stripos($row['CurrentTask'], 'idling') !== false) {
                 $not_testing = true;
                 //	continue;
             } else {
                 if (stripos($row['CurrentTask'], 'waiting') !== false || stripos($row['CurrentTask'], 'shutdown') !== false) {
                     $not_testing = true;
                     $opacity = ' style="opacity: 0.3;"';
                 } else {
                     $not_testing = false;
                 }
             }
         }
         echo '<a href="?systems/' . $row['SystemID'] . '"><div class="phoromatic_dashboard_block"' . $opacity . '>';
         echo '<div style="float: left; width: 30%;">';
         echo '<h1>' . $row['Title'] . '</h1>';
         $components = array_merge(pts_result_file_analyzer::system_component_string_to_array($row['Hardware'], array('Processor', 'Motherboard')), pts_result_file_analyzer::system_component_string_to_array($row['Software'], array('OS', 'Kernel')));
         foreach ($components as &$c) {
             if (($x = stripos($c, ' @')) !== false) {
                 $c = substr($c, 0, $x);
             }
             if (($x = stripos($c, ' (')) !== false) {
                 $c = substr($c, 0, $x);
             }
         }
         echo '<p><em>' . implode(' - ', $components) . '</em></p>';
         echo '<h2>' . $row['CurrentTask'] . '</h2>';
         if (!empty($row['CurrentProcessSchedule'])) {
             echo '<h2>' . phoromatic_server::schedule_id_to_name($row['CurrentProcessSchedule']) . '</h2>';
         }
         echo '</div>';
         echo '<div style="float: left;">';
         echo '<h2>' . $row['LastIP'] . '</h2>';
         echo '</div>';
         $time_remaining = phoromatic_compute_estimated_time_remaining($row['EstimatedTimeForTask'], $row['LastCommunication']);
         if ($time_remaining) {
             echo '<div style="float: left; text-align: center; margin: 0 6px;">';
             echo '<h2>~ ' . $time_remaining . ' <sub>mins</sub></h2>';
             echo '<p class="font-size: 90%;"><em>Estimated Time Remaining</em></p>';
             if (!empty($row['TimeToNextCommunication'])) {
                 echo '<p><em>' . phoromatic_compute_estimated_time_remaining_string($row['TimeToNextCommunication'], $row['LastCommunication'], 'To Next Communication') . '</em></p>';
             }
             echo '</div>';
         }
         if ($not_testing) {
             $next_job_in = phoromatic_server::time_to_next_scheduled_job($_SESSION['AccountID'], $row['SystemID']);
             if ($next_job_in > 0) {
                 if ($next_job_in > 240) {
                     $next_job_in = round($next_job_in / 60);
                     $next_unit = 'hours';
                 } else {
                     $next_unit = 'mins';
                 }
                 echo '<div style="float: left; margin: 0 0 0 10px; text-align: center;">';
                 echo '<h2>' . $next_job_in . ' <sub>' . $next_unit . '</sub></h2>';
                 echo '<p class="font-size: 90%;"><em>Time To Next Scheduled Task</em></p>';
                 echo '</div>';
             }
         }
         $system_path = phoromatic_server::phoromatic_account_system_path($_SESSION['AccountID'], $row['SystemID']);
         if (is_file($system_path . 'sensors-pool.json')) {
             $sensors = file_get_contents($system_path . 'sensors-pool.json');
             $sensors = json_decode($sensors, true);
             echo '<div style="float: right; margin: 0 10px 0 10px;">';
             $g_count = 0;
             foreach (array('CPU Usage', 'Memory Usage', 'CPU Temperature', 'System Temperature', 'GPU Temperature', 'Swap Usage', 'System Iowait', 'CPU Frequency') as $s) {
                 if (!isset($sensors[$s]) || !isset($sensors[$s]['values']) || count($sensors[$s]['values']) < 5) {
                     continue;
                 }
                 $g_count++;
                 if ($g_count <= 3) {
                     $graph = new pts_sys_graph(array('title' => $s, 'x_scale' => 'm', 'y_scale' => $sensors[$s]['unit'], 'text_size' => 10, 'reverse_x_direction' => false, 'width' => 300, 'height' => 120));
                     $graph->render_base();
                     $svg_dom = $graph->render_graph_data($sensors[$s]['values']);
                     if ($svg_dom === false) {
                         continue;
                     }
                     $output_type = 'SVG';
                     $graph = $svg_dom->output(null, $output_type);
                     echo substr($graph, strpos($graph, '<svg'));
                 } else {
                     break;
                 }
             }
             echo '</div>';
         }
         echo '<hr style="width: ' . $row['TaskPercentComplete'] . '%;" />';
         echo '</div></a>';
     }
     echo '</div>';
     echo phoromatic_webui_footer();
 }
 public function __construct(&$result_file, $log_location, $intent = false)
 {
     if (!is_readable($log_location)) {
         return false;
     }
     if ($intent == false) {
         $intent = -1;
         $intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true);
     }
     if (!isset($intent[0])) {
         return false;
     }
     if (is_array($intent[0]) && in_array('Processor', $intent[0])) {
         $component_report = 'Processor';
     } else {
         if (is_array($intent[0]) && in_array('Graphics', $intent[0])) {
             $component_report = 'Graphics';
         } else {
             return false;
         }
     }
     $this->rows = array();
     $this->columns = array();
     $this->table_data = array();
     $logs_to_capture = array();
     if ($component_report == 'Processor') {
         $this->columns = array('Model Name', 'Core Count', 'Thread Count', 'L2 Cache', 'Cache Size', 'Virtualization', 'Features', 'Flags');
         $logs_to_capture = array('cpuinfo', 'lscpu');
     } else {
         if ($component_report == 'Graphics') {
             $this->columns = array('OpenGL Renderer', 'OpenGL Version', 'GLSL Version', 'OpenGL Extensions');
             $logs_to_capture = array('glxinfo');
         }
     }
     if (is_dir($log_location)) {
         foreach ($result_file->get_system_identifiers() as $system_identifier) {
             phodevi::$vfs->clear_cache();
             foreach ($logs_to_capture as $log_file_name) {
                 if (is_file($log_location . $system_identifier . '/' . $log_file_name)) {
                     phodevi::$vfs->set_cache_item($log_file_name, file_get_contents($log_location . $system_identifier . '/' . $log_file_name));
                 }
             }
             if (count(phodevi::$vfs->cache_index()) > 0) {
                 switch ($component_report) {
                     case 'Processor':
                         $this->generate_processor_data($result_file, $system_identifier);
                         break;
                     case 'Graphics':
                         $this->generate_graphics_data($result_file, $system_identifier);
                         break;
                 }
             }
             phodevi::$vfs->clear_cache();
         }
     }
     if (empty($this->rows)) {
         return false;
     }
     foreach (array(array('Processor', 'Flags', 'Common CPU Flags'), array('Graphics', 'OpenGL Extensions', 'Common OpenGL Extensions')) as $set) {
         if ($component_report == $set[0]) {
             $flags_data = $this->table_data[array_search($set[1], $this->columns)];
             foreach ($flags_data as $i => &$flags) {
                 $flags = explode(' ', $flags);
                 sort($flags);
             }
             if ($flags_data == null || count($flags_data) < 2) {
                 continue;
             }
             $intersect = call_user_func_array('array_intersect', $flags_data);
             sort($intersect);
             foreach ($flags_data as $i => &$flags) {
                 $flags = array_diff($flags, $intersect);
                 $flags = implode(' ', $flags);
             }
             $this->table_data[array_search($set[1], $this->columns)] = $flags_data;
             $intersect_label = $set[2];
             break;
         }
     }
     parent::__construct($this->rows, $this->columns, $this->table_data);
     if (isset($intersect) && !empty($intersect)) {
         $this->addTestNote(trim(implode(' ', $intersect)), null, $intersect_label);
     }
 }
Example #16
0
 public static function generate_result_file_graphs($test_results_identifier, $save_to_dir = false, $extra_attributes = null)
 {
     if ($save_to_dir) {
         if (pts_file_io::mkdir($save_to_dir . '/result-graphs') == false) {
             // Directory must exist, so remove any old graph files first
             foreach (pts_file_io::glob($save_to_dir . '/result-graphs/*') as $old_file) {
                 unlink($old_file);
             }
         }
     }
     if ($test_results_identifier instanceof pts_result_file) {
         $result_file =& $test_results_identifier;
     } else {
         $result_file = new pts_result_file($test_results_identifier);
     }
     $generated_graphs = array();
     $generated_graph_tables = false;
     // Render overview chart
     if ($save_to_dir) {
         $chart = new pts_ResultFileTable($result_file);
         $chart->renderChart($save_to_dir . '/result-graphs/overview.BILDE_EXTENSION');
         $intent = -1;
         if (($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true)) || $result_file->get_system_count() == 1) {
             $chart = new pts_ResultFileCompactSystemsTable($result_file, $intent);
         } else {
             $chart = new pts_ResultFileSystemsTable($result_file);
         }
         $chart->renderChart($save_to_dir . '/result-graphs/systems.BILDE_EXTENSION');
         unset($chart);
         if ($intent && is_dir($save_to_dir . '/system-logs/')) {
             $chart = new pts_DetailedSystemComponentTable($result_file, $save_to_dir . '/system-logs/', $intent);
             if ($chart) {
                 $chart->renderChart($save_to_dir . '/result-graphs/detailed_component.BILDE_EXTENSION');
             }
         }
     }
     $result_objects = $result_file->get_result_objects();
     $test_titles = array();
     foreach ($result_objects as &$result_object) {
         array_push($test_titles, $result_object->test_profile->get_title());
     }
     $offset = 0;
     foreach ($result_objects as $key => &$result_object) {
         $save_to = $save_to_dir;
         $offset++;
         if ($save_to_dir && is_dir($save_to_dir)) {
             $save_to .= '/result-graphs/' . $offset . '.BILDE_EXTENSION';
             if (PTS_IS_CLIENT) {
                 if ($result_file->is_multi_way_comparison(null, $extra_attributes) || pts_client::read_env('GRAPH_GROUP_SIMILAR')) {
                     $table_keys = array();
                     foreach ($test_titles as $this_title_index => $this_title) {
                         if (isset($test_titles[$key]) && $this_title == $test_titles[$key]) {
                             array_push($table_keys, $this_title_index);
                         }
                     }
                 } else {
                     $table_keys = $key;
                 }
                 $chart = new pts_ResultFileTable($result_file, null, $table_keys);
                 $chart->renderChart($save_to_dir . '/result-graphs/' . $offset . '_table.BILDE_EXTENSION');
                 unset($chart);
                 $generated_graph_tables = true;
             }
         }
         $graph = pts_render::render_graph($result_object, $result_file, $save_to, $extra_attributes);
         array_push($generated_graphs, $graph);
     }
     // Generate mini / overview graphs
     if ($save_to_dir) {
         $graph = new pts_OverviewGraph($result_file);
         if ($graph->doSkipGraph() == false) {
             $graph->renderGraph();
             // Check to see if skip_graph was realized during the rendering process
             if ($graph->doSkipGraph() == false) {
                 $graph->svg_dom->output($save_to_dir . '/result-graphs/visualize.BILDE_EXTENSION');
             }
         }
         unset($graph);
         $graph = new pts_RadarOverviewGraph($result_file);
         if ($graph->doSkipGraph() == false) {
             $graph->renderGraph();
             // Check to see if skip_graph was realized during the rendering process
             if ($graph->doSkipGraph() == false) {
                 $graph->svg_dom->output($save_to_dir . '/result-graphs/radar.BILDE_EXTENSION');
             }
         }
         unset($graph);
     }
     // Save XSL
     if (count($generated_graphs) > 0 && $save_to_dir) {
         file_put_contents($save_to_dir . '/pts-results-viewer.xsl', pts_client::xsl_results_viewer_graph_template($generated_graph_tables));
     }
     return $generated_graphs;
 }
 public static function report_system_notes_to_table(&$result_file, &$table)
 {
     $identifier_count = 0;
     $system_attributes = array();
     foreach ($result_file->get_systems() as $s) {
         $json = $s->get_json();
         $identifier = $s->get_identifier();
         $identifier_count++;
         if (isset($json['kernel-parameters']) && $json['kernel-parameters'] != null) {
             $system_attributes['Kernel'][$identifier] = $json['kernel-parameters'];
         }
         if (isset($json['environment-variables']) && $json['environment-variables'] != null) {
             $system_attributes['Environment'][$identifier] = $json['environment-variables'];
         }
         if (isset($json['compiler-configuration']) && $json['compiler-configuration'] != null) {
             $system_attributes['Compiler'][$identifier] = $json['compiler-configuration'];
         }
         if (isset($json['disk-scheduler']) && isset($json['disk-mount-options'])) {
             $system_attributes['Disk'][$identifier] = $json['disk-scheduler'] . ' / ' . $json['disk-mount-options'];
         }
         if (isset($json['cpu-scaling-governor'])) {
             $system_attributes['Processor'][$identifier] = 'Scaling Governor: ' . $json['cpu-scaling-governor'];
         }
         if (isset($json['graphics-2d-acceleration']) || isset($json['graphics-aa']) || isset($json['graphics-af'])) {
             $report = array();
             foreach (array('graphics-2d-acceleration', 'graphics-aa', 'graphics-af') as $check) {
                 if (isset($json[$check]) && !empty($json[$check])) {
                     array_push($report, $json[$check]);
                 }
             }
             $system_attributes['Graphics'][$identifier] = implode(' - ', $report);
         }
         if (isset($json['graphics-compute-cores'])) {
             $system_attributes['OpenCL'][$identifier] = 'GPU Compute Cores: ' . $json['graphics-compute-cores'];
         }
     }
     if (isset($system_attributes['compiler']) && count($system_attributes['compiler']) == 1 && ($result_file->get_system_count() > 1 && ($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true)) && isset($intent[0]) && is_array($intent[0]) && array_shift($intent[0]) == 'Compiler') == false) {
         // Only show compiler strings when it's meaningful (since they tend to be long strings)
         unset($system_attributes['compiler']);
     }
     foreach ($system_attributes as $index_name => $attributes) {
         $unique_attribue_count = count(array_unique($attributes));
         $section = $identifier_count > 1 ? ucwords($index_name) : null;
         switch ($unique_attribue_count) {
             case 0:
                 break;
             case 1:
                 if ($identifier_count == count($attributes)) {
                     // So there is something for all of the test runs and it's all the same...
                     $table->addTestNote(array_pop($attributes), null, $section);
                 } else {
                     // There is missing data for some test runs for this value so report the runs this is relevant to.
                     $table->addTestNote(implode(', ', array_keys($attributes)) . ': ' . array_pop($attributes), null, $section);
                 }
                 break;
             default:
                 foreach ($attributes as $identifier => $configuration) {
                     $table->addTestNote($identifier . ': ' . $configuration, null, $section);
                 }
                 break;
         }
     }
 }
Example #18
0
 $result_file->merge($result_files, $attributes);
 $extra_attributes = array();
 $attribute_options = array('normalize_results' => 'normalize_result_buffer', 'sort_by_performance' => 'sort_result_buffer_values', 'sort_by_reverse' => 'reverse_result_buffer', 'sort_by_name' => 'sort_result_buffer', 'condense_comparison' => 'condense_multi_way');
 foreach ($attribute_options as $web_var => $attr_var) {
     if (isset($_REQUEST[$web_var])) {
         $extra_attributes[$attr_var] = true;
     }
 }
 if (isset($_POST['transpose_comparison'])) {
     $result_file->invert_multi_way_invert();
 }
 $intent = null;
 $main .= '<h1>' . $result_file->get_title() . '</h1>';
 $main .= '<p>' . $result_file->get_description() . '</p>';
 $main .= phoromatic_annotate_entry('RESULT', implode(',', $result_ids), 'TOP');
 if ($result_file->get_system_count() == 1 || ($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true))) {
     $table = new pts_ResultFileCompactSystemsTable($result_file, $intent);
 } else {
     $table = new pts_ResultFileSystemsTable($result_file);
 }
 $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
 $table = new pts_ResultFileTable($result_file, $intent);
 $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
 $main .= '<div id="pts_results_area">';
 foreach ($result_file->get_result_objects(isset($_POST['show_only_changed_results']) ? 'ONLY_CHANGED_RESULTS' : -1) as $i => $result_object) {
     $main .= '<h2><a name="r-' . $i . '"></a><a name="' . $result_object->get_comparison_hash(true, false) . '"></a>' . $result_object->test_profile->get_title() . '</h2>';
     $main .= phoromatic_annotate_entry('RESULT', implode(',', $result_ids), $result_object->get_comparison_hash(true, false));
     $main .= '<p style="text-align: center; overflow: auto;">';
     $main .= pts_render::render_graph_inline_embed($result_object, $result_file, $extra_attributes);
     $main .= '</p>';
 }