function update_table($table_name)
{
    global $case;
    // First check whether the table exists.
    $res = mysql_query("\n\t\tDESCRIBE {$table_name}\n\t");
    if (!$res) {
        // table doesn't exist (has been archived).
        // echo "$table_name doesn't exist\n";
        return;
    }
    $existing_column_names = dpsql_fetch_all_keyed($res);
    echo "{$table_name}: ";
    mysql_query("\n\t\tUPDATE {$table_name}\n\t\tSET state={$case}\n\t") or die(mysql_error());
    echo "State field changed on " . mysql_affected_rows(), " rows. ";
    $n_columns_to_add = 0;
    $adds_sql = "";
    for ($rn = 1; $rn <= MAX_NUM_PAGE_EDITING_ROUNDS; $rn++) {
        $round = get_Round_for_round_number($rn);
        if (!array_key_exists($round->time_column_name, $existing_column_names)) {
            $n_columns_to_add += 3;
            if ($adds_sql) {
                $adds_sql .= ',';
            }
            $adds_sql .= "\n\t\t\t\tADD COLUMN {$round->time_column_name} int(20)     NOT NULL default '0',\n\t\t\t\tADD COLUMN {$round->user_column_name} varchar(25) NOT NULL default '',\n\t\t\t\tADD COLUMN {$round->text_column_name} longtext    NOT NULL\n\t\t\t";
        }
    }
    if ($n_columns_to_add > 0) {
        // echo $adds_sql, "\n";
        mysql_query("\n\t\t\tALTER TABLE {$table_name}\n\t\t\t{$adds_sql}\n\t\t") or die(mysql_error());
    }
    echo "Added {$n_columns_to_add} columns.";
    echo "\n";
}
function display_graph($d)
{
    $total_pages = 0;
    if ($d == 0) {
        $graph = init_pie_graph(660, 400, 5);
        $title = _("Net pages saved so far today");
        for ($rn = 1; $rn <= MAX_NUM_PAGE_EDITING_ROUNDS; $rn++) {
            $round = get_Round_for_round_number($rn);
            $site_stats = get_site_page_tally_summary($round->id);
            $data[] = $pages = $site_stats->curr_day_actual;
            $labels[] = "{$round->id} ({$pages})";
            $total_pages += $pages;
        }
    } else {
        $graph = init_pie_graph(660, 400, 60);
        $title = sprintf(_("Net pages saved in preceding %s days"), $d);
        $now = time();
        for ($rn = 1; $rn <= MAX_NUM_PAGE_EDITING_ROUNDS; $rn++) {
            $round = get_Round_for_round_number($rn);
            $tallyboard = new TallyBoard($round->id, 'S');
            $data[] = $pages = $tallyboard->get_delta_sum(1, $now - 60 * 60 * 24 * $d, $now);
            $labels[] = "{$round->id} ({$pages})";
            $total_pages += $pages;
        }
    }
    if ($total_pages == 0) {
        dpgraph_error(_("No pages saved in specified range"));
    }
    draw_pie_graph($graph, $labels, $data, $title);
}
function _get_word_list($projectid, $timeCutoff)
{
    $messages = array();
    // load the suggestions
    $suggestions = load_project_good_word_suggestions($projectid, $timeCutoff);
    if (!is_array($suggestions)) {
        $messages[] = sprintf(_("Unable to load suggestions: %s"), $suggestions);
        return array(array(), array(), array(), array(), array(), array(), $messages);
    }
    if (count($suggestions) == 0) {
        return array(array(), array(), array(), array(), array(), array(), $messages);
    }
    // load project good words
    $project_good_words = load_project_good_words($projectid);
    // load project bad words
    $project_bad_words = load_project_bad_words($projectid);
    // get the latest project text of all pages up to last possible round
    $last_possible_round = get_Round_for_round_number(MAX_NUM_PAGE_EDITING_ROUNDS);
    $pages_res = page_info_query($projectid, $last_possible_round->id, 'LE');
    $all_words_w_freq = get_distinct_words_in_text(get_page_texts($pages_res));
    // array to hold all words
    $all_suggestions = array();
    $round_page_count = array();
    // parse the suggestions complex array
    // it is in the format: $suggestions[$round][$pagenum]=$wordsArray
    foreach ($suggestions as $round => $pageArray) {
        $round_suggestions = array();
        foreach ($pageArray as $page => $words) {
            // add the words to the per-round array
            $round_suggestions = array_merge($round_suggestions, $words);
            // add the words to the combined array too
            $all_suggestions = array_merge($all_suggestions, $words);
            @$round_page_count[$round]++;
        }
        // remove any words already on the project's good or bad words lists
        $round_suggestions = array_diff($round_suggestions, array_merge($project_good_words, $project_bad_words));
        // get the suggestion occurrences
        $round_suggestions_w_occurrences[$round] = generate_frequencies($round_suggestions);
        // get suggestion with project word frequency
        $round_suggestions_w_freq[$round] = array_intersect_key($all_words_w_freq, array_flip($round_suggestions));
        // multisort screws up all-numeric words so we need to preprocess first
        prep_numeric_keys_for_multisort($round_suggestions_w_freq[$round]);
        // sort the list by frequency, then by word
        array_multisort(array_values($round_suggestions_w_freq[$round]), SORT_DESC, array_map('strtolower', array_keys($round_suggestions_w_freq[$round])), SORT_ASC, $round_suggestions_w_freq[$round]);
    }
    // now, remove any words that are already on the project's good or bad words lists
    $all_suggestions = array_diff($all_suggestions, array_merge($project_good_words, $project_bad_words));
    // get the number of suggestion occurrences
    $all_suggestions_w_occurrences = generate_frequencies($all_suggestions);
    // $all_suggestions doesn't have frequency info,
    // so start with the info in $all_words_w_freq,
    // and extract the items where the key matches a key in $all_suggestions.
    $all_suggestions_w_freq = array_intersect_key($all_words_w_freq, array_flip($all_suggestions));
    // multisort screws up all-numeric words so we need to preprocess first
    prep_numeric_keys_for_multisort($all_suggestions_w_freq);
    // sort the list by frequency, then by word
    array_multisort(array_values($all_suggestions_w_freq), SORT_DESC, array_map('strtolower', array_keys($all_suggestions_w_freq)), SORT_ASC, $all_suggestions_w_freq);
    // get a list of all rounds
    $rounds = array_keys($round_suggestions_w_freq);
    return array($all_suggestions_w_freq, $all_suggestions_w_occurrences, $round_suggestions_w_freq, $round_suggestions_w_occurrences, $rounds, $round_page_count, $messages);
}
function _get_word_list($projectid)
{
    global $aspell_temp_dir;
    $ocr_filename = "{$aspell_temp_dir}/{$projectid}_ocr.txt";
    $latest_filename = "{$aspell_temp_dir}/{$projectid}_latest.txt";
    $messages = array();
    // get the OCR text
    // Note: If the code is changed to allow selecting of arbitrary round text
    //       instead of just the OCR round, edit_project_word_lists.php should
    //       be updated to allow this page to be accessed for those type-in
    //       projects with no OCR text.
    $pages_res = page_info_query($projectid, '[OCR]', 'LE');
    $all_page_text = get_page_texts($pages_res);
    // remove any formatting tags and add a final \r\n to each page-text
    // to ensure that there is whitespace between pages so they don't run together
    $all_page_text = preg_replace(array('#<[/]?\\w+>#', '#$#'), array('', "\r\n"), $all_page_text);
    file_put_contents($ocr_filename, $all_page_text);
    // get the latest project text of all pages up to last possible round
    $last_possible_round = get_Round_for_round_number(MAX_NUM_PAGE_EDITING_ROUNDS);
    $pages_res = page_info_query($projectid, $last_possible_round->id, 'LE');
    $all_page_text = get_page_texts($pages_res);
    // remove any formatting tags and add a final \r\n to each page-text
    // to ensure that there is whitespace between pages so they don't run together
    $all_page_text = preg_replace(array('#<[/]?\\w+>#', '#$#'), array('', "\r\n"), $all_page_text);
    file_put_contents($latest_filename, $all_page_text);
    $all_words_w_freq = get_distinct_words_in_text($all_page_text);
    // clean up unused variables
    unset($all_page_text);
    // make external call to wdiff
    exec("wdiff -3 {$ocr_filename} {$latest_filename}", $wdiff_output, $return_code);
    // check to see if wdiff wasn't found to execute
    if ($return_code == 127) {
        die("Error invoking wdiff to do the diff analysis. Perhaps it is not installed.");
    }
    if ($return_code == 2) {
        die("Error reported from wdiff while attempting to do the diff analysis.");
    }
    // clean up the temporary files
    if (is_file($ocr_filename)) {
        unlink($ocr_filename);
    }
    if (is_file($latest_filename)) {
        unlink($latest_filename);
    }
    // specify the separator between the wdiff segments
    $separator = '======================================================================';
    $possible_scannos_w_correction = array();
    $possible_scannos_w_count = array();
    // parse the incoming data one segment at a time
    // from the original datastream to conserve memory
    $lineIndex = 0;
    $totalLines = count($wdiff_output);
    while ($lineIndex < $totalLines) {
        // pull the next segment
        $segment = "";
        while ($lineIndex <= $totalLines) {
            $line = $wdiff_output[$lineIndex];
            $lineIndex++;
            if ($line == $separator) {
                break;
            }
            $segment .= "{$line}\n";
        }
        // note that we're handling the case where two adjacent
        // words are updated
        $ocr_words = $latest_words = array();
        // pull out the original word(s)
        if (preg_match("/\\[-(.*?)-\\]/", $segment, $matches)) {
            $ocr_words = $matches[1];
            $ocr_words = get_all_words_in_text($ocr_words);
        }
        // if we don't have any ocr_words (probably because
        // the correction spanned lines) then don't bother
        // continuing with this segment
        if (!count($ocr_words)) {
            continue;
        }
        // pull out the replacement(s)
        if (preg_match("/{\\+(.*?)\\+}/", $segment, $matches)) {
            $latest_words = $matches[1];
            $latest_words = get_all_words_in_text($latest_words);
        }
        // if the number of words isn't the same between the two
        // bail since we don't handle that case yet
        if (count($ocr_words) != count($latest_words)) {
            continue;
        }
        // process the words, handles multi-words strings
        for ($index = 0; $index < count($ocr_words); $index++) {
            $ocr_word = $ocr_words[$index];
            $latest_word = $latest_words[$index];
            // if the words are the same or one of them empty, skip it
            if ($ocr_word == $latest_word || empty($ocr_word) || empty($latest_word)) {
                continue;
            }
            $possible_scannos_w_correction[$ocr_word] = $latest_word;
            @$possible_scannos_w_count[$ocr_word]++;
        }
    }
    // $wdiff_output can be very large
    // so unset it here to be nice for the rest of the function
    unset($wdiff_output);
    $possible_scannos = array_keys($possible_scannos_w_correction);
    // create a string of words to run through WordCheck
    $text_to_check = implode(" ", $possible_scannos);
    // run the list through WordCheck to see which it would flag
    list($possible_scannos_via_wordcheck, $languages, $messages) = get_bad_words_for_text($text_to_check, $projectid, 'all', '', array(), 'FREQS');
    // load site words
    $site_bad_words = load_site_bad_words_given_project($projectid);
    // load the project bad words
    $project_bad_words = load_project_bad_words($projectid);
    // remove words that WordCheck would flag
    $possible_scannos = array_diff($possible_scannos, array_keys($possible_scannos_via_wordcheck));
    // remove any scannos already on the site and project bad word lists
    $possible_scannos = array_diff($possible_scannos, $site_bad_words, $project_bad_words);
    // $possible_scannos doesn't have frequency info,
    // so start with the info in $all_words_w_freq,
    // and extract the items where the key matches a key in $possible_scannos
    $possible_scannos_w_freq = array_intersect_key($all_words_w_freq, array_flip($possible_scannos));
    $percent_changed = array();
    foreach ($possible_scannos as $word) {
        $count = $possible_scannos_w_count[$word];
        $totalInstances = @$possible_scannos_w_freq[$word] + $count;
        $percent_changed[$word] = sprintf("%0.2f", $count / $totalInstances * 100);
        if ($percent_changed[$word] >= 100 && $totalInstances == 1) {
            unset($percent_changed[$word]);
        }
    }
    // multisort screws up all-numeric words so we need to preprocess first
    prep_numeric_keys_for_multisort($percent_changed);
    // sort the list by frequency, then by word
    array_multisort(array_values($percent_changed), SORT_DESC, array_map('strtolower', array_keys($percent_changed)), SORT_ASC, $percent_changed);
    return array($percent_changed, $possible_scannos_w_freq, $messages, $possible_scannos_w_correction, $possible_scannos_w_count);
}
function _get_word_list($projectid)
{
    $messages = array();
    // get the latest project text of all pages up to last possible round
    $last_possible_round = get_Round_for_round_number(MAX_NUM_PAGE_EDITING_ROUNDS);
    $pages_res = page_info_query($projectid, $last_possible_round->id, 'LE');
    $all_words_w_freq = get_distinct_words_in_text(get_page_texts($pages_res));
    // load site word lists for project languages
    $site_possible_bad_words = load_site_possible_bad_words_given_project($projectid);
    // now, remove any words that are already on the project's bad word list
    $site_possible_bad_words = array_diff($site_possible_bad_words, load_project_bad_words($projectid));
    // $site_possible_bad_words doesn't have frequency info,
    // so start with the info in $all_words_w_freq,
    // and extract the items where the key matches a key in $bad_words.
    $bad_words_w_freq = array_intersect_key($all_words_w_freq, array_flip($site_possible_bad_words));
    // multisort screws up all-numeric words so we need to preprocess first
    prep_numeric_keys_for_multisort($bad_words_w_freq);
    // sort the list by frequency, then by word
    array_multisort(array_values($bad_words_w_freq), SORT_DESC, array_map('strtolower', array_keys($bad_words_w_freq)), SORT_ASC, $bad_words_w_freq);
    return array($bad_words_w_freq, $messages);
}
include_once $relPath . 'user_project_info.inc';
require_login();
$title = _("Most Requested Books");
output_header($title);
echo "<br><h2 style='color: {$theme['color_headerbar_bg']};'>{$title}</h2><br>\n";
echo "<p>" . _("You can sign up for notifications in the Event Subscriptions section of the Project Comments page when proofreading.") . "</p>";
echo "<br><br><h3 style='color: {$theme['color_headerbar_bg']};'>" . _("Most Requested Books Being Proofread") . "</h3><br>\n";
create_temporary_project_event_subscription_summary_table();
$comments_url1 = mysql_escape_string("<a href='{$code_url}/project.php?id=");
$comments_url2 = mysql_escape_string("'>");
$comments_url3 = mysql_escape_string("</a>");
// Looking at the other two queries, you might expect the first one to use
// SQL_CONDITION_BRONZE. However, that would exclude the WAITING_FOR_RELEASE
// states, which we apparently want to include here.
// Instead, custom-build a project-state condition that includes the
// WAITING and AVAILABLE states from each round.
$state_condition = '0';
for ($rn = 1; $rn <= MAX_NUM_PAGE_EDITING_ROUNDS; $rn++) {
    $round = get_Round_for_round_number($rn);
    $state_condition .= "\n        OR state='{$round->project_waiting_state}'\n        OR state='{$round->project_available_state}'\n    ";
}
dpsql_dump_themed_query("\n    SELECT\n        CONCAT('{$comments_url1}',projects.projectid,'{$comments_url2}', nameofwork, '{$comments_url3}') AS '" . mysql_real_escape_string(_("Title")) . "', \n        authorsname AS '" . mysql_real_escape_string(_("Author")) . "', \n        genre AS '" . mysql_real_escape_string(_("Genre")) . "',\n        language AS '" . mysql_real_escape_string(_("Language")) . "',\n        pesgbp.nouste_posted AS '" . mysql_real_escape_string(_("Notification Requests")) . "'\n    FROM project_event_subscriptions_grouped_by_project AS pesgbp, projects\n    WHERE pesgbp.projectid = projects.projectid\n        AND ({$state_condition})\n    ORDER BY 5 DESC \n    LIMIT 50\n", 1, DPSQL_SHOW_RANK);
echo "<br>\n";
echo "<br><br><h3 style='color: {$theme['color_headerbar_bg']};'>" . _("Most Requested Books In Post-Processing") . "</h3><br>\n";
//        $post_url1 = mysql_escape_string("<a href='$code_url/project.php?id=");
dpsql_dump_themed_query("\n    SELECT\n        CONCAT('{$comments_url1}',projects.projectid,'{$comments_url2}', nameofwork, '{$comments_url3}') AS '" . mysql_real_escape_string(_("Title")) . "', \n        authorsname AS '" . mysql_real_escape_string(_("Author")) . "', \n        genre AS '" . mysql_real_escape_string(_("Genre")) . "',\n        language AS '" . mysql_real_escape_string(_("Language")) . "',\n        pesgbp.nouste_posted AS '" . mysql_real_escape_string(_("Notification Requests")) . "'\n    FROM project_event_subscriptions_grouped_by_project AS pesgbp, projects\n    WHERE pesgbp.projectid = projects.projectid\n        AND " . SQL_CONDITION_SILVER . "\n    ORDER BY 5 DESC \n    LIMIT 50\n", 1, DPSQL_SHOW_RANK);
echo "<br>\n";
echo "<br><br><h3 style='color: {$theme['color_headerbar_bg']};'>" . _("Most Requested Books Posted to Project Gutenberg") . "</h3><br>\n";
$pg_url1 = mysql_escape_string("<a href='http://www.gutenberg.org/ebooks/");
dpsql_dump_themed_query("\n    SELECT\n        CONCAT('{$pg_url1}',postednum,'{$comments_url2}', nameofwork, '{$comments_url3}') AS '" . mysql_real_escape_string(_("Title")) . "', \n        authorsname AS '" . mysql_real_escape_string(_("Author")) . "', \n        genre AS '" . mysql_real_escape_string(_("Genre")) . "',\n        language AS '" . mysql_real_escape_string(_("Language")) . "',\n        int_level AS '" . mysql_real_escape_string(_("Notification Requests")) . "' \n    FROM projects \n    WHERE " . SQL_CONDITION_GOLD . "\n        AND int_level !=0\n    ORDER BY 5 DESC \n    LIMIT 50\n", 1, DPSQL_SHOW_RANK);
// vim: sw=4 ts=4 expandtab
Example #7
0
    $L_user_column_name = "'none'";
    // string literal, not column name
    $L_label = _('OCR');
} else {
    $L_round = get_Round_for_round_number($L_round_num);
    $L_text_column_name = $L_round->text_column_name;
    $L_user_column_name = $L_round->user_column_name;
    $L_label = $L_round->id;
}
if ($R_round_num == 0) {
    $R_text_column_name = 'master_text';
    $R_user_column_name = "'none'";
    // string literal, not column name
    $R_label = _('OCR');
} else {
    $R_round = get_Round_for_round_number($R_round_num);
    $R_text_column_name = $R_round->text_column_name;
    $R_user_column_name = $R_round->user_column_name;
    $R_label = $R_round->id;
}
$query = "\n    SELECT {$L_text_column_name}, {$R_text_column_name},\n           {$L_user_column_name}, {$R_user_column_name}\n    FROM {$projectid}\n    WHERE image='{$image}'";
$res = mysql_query($query) or die(mysql_error());
list($L_text, $R_text, $L_user, $R_user) = mysql_fetch_row($res);
$can_see_names_for_this_page = can_see_names_for_page($projectid, $image);
if ($can_see_names_for_this_page) {
    $L_label .= " ({$L_user})";
    $R_label .= " ({$R_user})";
}
// now have the image, users, labels etc all set up
// -----------------------------------------------------------------------------
$title = sprintf(_('Difference for page %s'), $image);
function _get_word_list($projectid)
{
    $messages = array();
    // get the latest project text of all pages up to last possible round
    $last_possible_round = get_Round_for_round_number(MAX_NUM_PAGE_EDITING_ROUNDS);
    $pages_res = page_info_query($projectid, $last_possible_round->id, 'LE');
    $page_texts = get_page_texts($pages_res);
    // now run it through WordCheck
    list($bad_words_w_freq, $languages, $messages) = get_bad_words_for_text($page_texts, $projectid, 'all', '', array(), 'FREQS');
    // multisort screws up all-numeric words so we need to preprocess first
    prep_numeric_keys_for_multisort($bad_words_w_freq);
    // sort the list by frequency, then by word
    array_multisort(array_values($bad_words_w_freq), SORT_DESC, array_map('strtolower', array_keys($bad_words_w_freq)), SORT_ASC, $bad_words_w_freq);
    return array($bad_words_w_freq, $messages);
}
function _get_word_list($projectid, $queryWords)
{
    $messages = array();
    // get the latest project text of all pages up to last possible round
    $last_possible_round = get_Round_for_round_number(MAX_NUM_PAGE_EDITING_ROUNDS);
    $pages_res = page_info_query($projectid, $last_possible_round->id, 'LE');
    $page_texts = get_page_texts($pages_res);
    // now run it through WordCheck
    $all_words_w_freq = get_distinct_words_in_text($page_texts);
    $words_w_freq = array();
    foreach ($queryWords as $word) {
        if (@$all_words_w_freq[$word]) {
            $words_w_freq[$word] = $all_words_w_freq[$word];
        }
    }
    // multisort screws up all-numeric words so we need to preprocess first
    prep_numeric_keys_for_multisort($words_w_freq);
    // sort the list by frequency, then by word
    array_multisort(array_values($words_w_freq), SORT_DESC, array_map('strtolower', array_keys($words_w_freq)), SORT_ASC, $words_w_freq);
    return array($words_w_freq, $messages);
}
Example #10
0
         $state = $round->project_complete_state;
         if ($verbose) {
             echo "    Advancing \"{$nameofwork}\" to {$state}\n";
         }
         $error_msg = project_transition($projectid, $state, PT_AUTO);
         if ($error_msg) {
             echo "{$error_msg}\n";
             continue;
         }
     }
 }
 if ($state == $round->project_complete_state) {
     // The project is ready to exit this round.
     if ($round->round_number < MAX_NUM_PAGE_EDITING_ROUNDS) {
         // It goes to the next round.
         $next_round = get_Round_for_round_number(1 + $round->round_number);
         $new_state = $next_round->project_waiting_state;
     } elseif ($round->round_number == MAX_NUM_PAGE_EDITING_ROUNDS) {
         // It goes into post-processing.
         if (is_null(project_get_auto_PPer($projectid))) {
             $new_state = PROJ_POST_FIRST_AVAILABLE;
         } else {
             $new_state = PROJ_POST_FIRST_CHECKED_OUT;
         }
     } else {
         die("round_number is {$round->round_number}???\n");
     }
     if ($verbose) {
         ensure_project_blurb($project);
         echo "    Promoting \"{$nameofwork}\" to {$new_state}\n";
     }
 $access_name = "{$activity_id}.access";
 $res = mysql_query("\n        SELECT\n            usersettings.username,\n            users.u_id,\n            access_log_summary.t_latest_request,\n            access_log_summary.t_latest_deny,\n            users.t_last_activity\n        FROM usersettings\n            LEFT OUTER JOIN users USING (username)\n            LEFT OUTER JOIN access_log_summary ON (\n                access_log_summary.subject_username = usersettings.username\n                AND\n                access_log_summary.activity = '{$activity_id}'\n            )\n        WHERE setting = '{$access_name}' AND value='requested'\n        ORDER BY username\n    ") or die(mysql_error());
 if (mysql_num_rows($res) == 0) {
     $word = _('none');
     echo "({$word})";
 } else {
     $review_round = get_Round_for_round_id($activity_id);
     if ($review_round && $review_round->after_satisfying_minima == 'REQ-HUMAN') {
         $can_review_work = TRUE;
         // These users are all requesting access to round Y.  For each, we will
         // provide a link to allow the requestor to review their round X work,
         // by considering each page they worked on in X, and comparing
         // their X result to the subsequent Y result (if it exists yet).
         //
         // (We assume that X is the round immediately preceding Y.)
         $work_round = get_Round_for_round_number($review_round->round_number - 1);
         $round_params = "work_round_id={$work_round->id}&amp;review_round_id={$review_round->id}";
     } else {
         $can_review_work = FALSE;
     }
     echo "<table border='1'>\n";
     echo "<tr>";
     echo "<th>" . _("username (link to member stats)") . "</th>";
     if ($can_review_work) {
         echo "<th>" . _("link to review work") . "</th>";
     }
     echo "<th>" . _("this request") . "</th>";
     echo "<th>" . _("prev denial") . "</th>";
     echo "<th>" . _("last on site") . "</th>";
     echo "</tr>";
     echo "\n";
 function show_visible_controls()
 {
     $goodWordData = html_safe($this->good_words);
     $badWordData = html_safe($this->bad_words);
     $fields = array("projectid" => _("Project ID"), "nameofwork" => _("Name of Work"), "authorsname" => _("Author's Name"), "projectmanager" => _("Project Manager"), "checkedoutby" => _("Post-Processor"), "language" => _("Language"));
     foreach ($fields as $field => $label) {
         echo "<tr>";
         echo "<td class='label'>{$label}</td>";
         echo "<td>" . $this->{$field} . "</td>";
         echo "</tr>";
     }
     $exist_OCR_pages = $this->number_of_pages_in_round(null) > 0;
     $exist_pages_in_P1_or_later = $this->number_of_pages_in_round(get_Round_for_round_number(1)) > 0;
     // due to some special circumstances, not all projects may have pages in P1
     // so we'll check to see if the project is in a state after P1 and count
     // that as just as good
     if (!$exist_pages_in_P1_or_later) {
         $current_project_round = get_Round_for_project_state($this->state);
         if ($current_project_round && $current_project_round->round_number > 1) {
             $exist_pages_in_P1_or_later = true;
         }
     }
     // if the project doesn't have any OCR pages and the project
     // has no P1 or later pages, report a message. The second criteria
     // is important for type-in projects that may have no OCR pages but
     // will have P1 or later pages
     if (!$exist_OCR_pages && !$exist_pages_in_P1_or_later) {
         echo "<tr>";
         echo "<td colspan='2'>";
         echo "<p class='error' style='text-align: center;'>";
         echo _("There are no pages associated with this project.");
         echo "</p>";
         echo "</td>";
         echo "</tr>";
     } else {
         echo "<tr>";
         echo "<td class='label' style='text-align: center;' colspan='2'>";
         echo _("WordCheck Tools and Reports");
         echo "</td>";
         echo "</tr>";
         echo "<tr>";
         echo "<td class='label'>" . _("Ad Hoc Word Details") . "</td>";
         echo "<td>" . new_window_link("show_adhoc_word_details.php?projectid={$this->projectid}", _("Show details for ad hoc words")) . "</td>";
         echo "</tr>";
         echo "<tr>";
         echo "<td class='label'>" . _("WordCheck Statistics") . "</td>";
         echo "<td>" . new_window_link("show_project_wordcheck_stats.php?projectid={$this->projectid}", _("Show WordCheck flagged word statistics")) . "</td>";
         echo "</tr>";
         if ($exist_pages_in_P1_or_later) {
             echo "<tr>";
             echo "<td class='label'>" . _("WordCheck Usage") . "</td>";
             echo "<td>" . new_window_link("show_project_wordcheck_usage.php?projectid={$this->projectid}", _("Show WordCheck interface usage")) . "</td>";
             echo "</tr>";
         }
         echo "<tr>";
         echo "<td class='label' style='text-align: center;' colspan='2'>";
         echo _("Word List Suggestion Tools");
         echo "</td>";
         echo "</tr>";
         echo "<tr>";
         echo "<td colspan='2'>";
         echo "<table width='100%'>";
         echo "<tr>";
         echo "<td style='width: 50%; text-align: center;' valign='top'>";
         echo "<p>";
         echo "<b>" . _("Words that WordCheck would currently flag:") . "</b><br>";
         echo new_window_link("show_current_flagged_words.php?projectid={$this->projectid}", _("Display"));
         echo " | ";
         echo "<a href='show_current_flagged_words.php?projectid={$this->projectid}&amp;format=file'>" . _("Download") . "</a>";
         echo "</p>";
         $suggestions = load_project_good_word_suggestions($this->projectid);
         if (count($suggestions)) {
             echo "<p>";
             echo "<b>" . _("Suggestions from proofreaders:") . "</b><br>";
             echo new_window_link("show_good_word_suggestions.php?projectid={$this->projectid}", _("Display"));
             echo " | ";
             echo "<a href='show_good_word_suggestions.php?projectid={$this->projectid}&amp;timeCutoff=0&amp;format=file'>" . _("Download") . "</a>";
             echo "</p>";
         }
         echo "</td>";
         echo "<td style='width: 50%; text-align: center;' valign='top'>";
         // see if the site has Possible Bad Word files
         $possible_bad_words = load_site_possible_bad_words_given_project($this->projectid);
         if (count($possible_bad_words)) {
             echo "<p>";
             echo "<b>" . _("Words in the Site's Possible bad words file:") . "</b><br>";
             echo new_window_link("show_project_possible_bad_words.php?projectid={$this->projectid}", _("Display"));
             echo " | ";
             echo "<a href='show_project_possible_bad_words.php?projectid={$this->projectid}&amp;format=file'>" . _("Download") . "</a>";
             echo "</p>";
         }
         // see if there are P1 (or later) and OCR pages before showing the link.
         // type-in projects may have P1 (or later) pages but no OCR pages
         // and the current show_project_stealth_scannos.php page only works
         // with projects that have OCR text
         if ($exist_pages_in_P1_or_later && $exist_OCR_pages) {
             echo "<p>";
             echo "<b>" . _("Suggestions from diff analysis:") . "</b><br>";
             echo new_window_link("show_project_stealth_scannos.php?projectid={$this->projectid}", _("Display"));
             echo " | ";
             echo "<a href='show_project_stealth_scannos.php?projectid={$this->projectid}&amp;format=file'>" . _("Download") . "</a>";
             echo "</p>";
         }
         echo "</td>";
         echo "</tr>";
         echo "</table>";
         echo "</td>";
         echo "</tr>";
     }
     echo "<tr>";
     echo "<td class='label' style='text-align: center;' colspan='2'>";
     echo _("Project Dictionary - Word Lists");
     echo "</td>";
     echo "</tr>";
     echo "<tr>";
     echo "<td colspan='2'>";
     echo "<table width='100%'>";
     echo "<tr>";
     echo "<td class='label' style='text-align: center;'>" . _("Good Words") . "</td>";
     echo "<td class='label' style='text-align: center;'>" . _("Bad Words") . "</td>";
     echo "</tr>";
     echo "<tr>";
     echo "<td style='width: 50%;'>";
     echo "<textarea class='mono' name='good_words' cols='40' rows='20'>{$goodWordData}</textarea>";
     echo "</td>";
     echo "<td style='width: 50%;'>";
     echo "<textarea class='mono' name='bad_words' cols='40' rows='20'>{$badWordData}</textarea>";
     echo "</td>";
     echo "</tr>";
     echo "</table>";
     echo "</td>";
     echo "</tr>";
     echo "<tr>";
     echo "<td colspan='2' style='text-align: center;'>";
     echo sprintf(_("See the %s for more information on word lists."), new_window_link("../../faq/wordcheck-faq.php", _("WordCheck FAQ")));
     echo "</td>";
     echo "</tr>";
 }
}
if (!$resolution) {
    //Find out information about the bad page report
    $result = mysql_query("SELECT * FROM {$projectid} WHERE image='{$image}'");
    $page = mysql_fetch_assoc($result);
    $state = $page['state'];
    $b_User = $page['b_user'];
    $b_Code = $page['b_code'];
    $project = new Project($projectid);
    $round = get_Round_for_page_state($state);
    // It's a bit messy to have this here,
    // since it reiterates stuff that appears in other files,
    // but this page is kind of messy to begin with.
    // It'll get cleaned up eventually.
    for ($prev_round_num = $round->round_number - 1; $prev_round_num > 0; $prev_round_num--) {
        $r = get_Round_for_round_number($prev_round_num);
        if ($page[$r->user_column_name] != '') {
            $prevtext_column = $r->text_column_name;
            break;
        }
    }
    if ($prev_round_num == 0) {
        $prevtext_column = 'master_text';
    }
    // Is it a bad page report, or are we merely fixing an ordinary page
    $is_a_bad_page = page_state_is_a_bad_state($state);
    if ($is_a_bad_page) {
        $header = _("Bad Page Report");
    } else {
        $header = _("Fix Page");
    }
 slim_header(_("Suggestion Detail"));
 $project_name = get_project_name($projectid);
 // TRANSLATORS: %1$s is a word, %2$s is the project name.
 echo "<h2>", sprintf(_("Context for '%1\$s' in %2\$s"), $word, $project_name), "</h2>";
 echo_word_freq_style();
 echo "<p>";
 echo "<a target='_PARENT' href='" . attr_safe($_SERVER['PHP_SELF']) . "?projectid={$projectid}&amp;word={$encWord}&amp;wordInstances={$wordInstances}&amp;";
 if ($layout == LAYOUT_HORIZ) {
     echo "layout=" . LAYOUT_VERT . "'>" . _("Change to vertical layout");
 } else {
     echo "layout=" . LAYOUT_HORIZ . "'>" . _("Change to horizontal layout");
 }
 echo "</a>";
 echo "</p>";
 // get the latest possible round
 $last_possible_round = get_Round_for_round_number(MAX_NUM_PAGE_EDITING_ROUNDS);
 $pages_res = page_info_query($projectid, $last_possible_round->id, 'LE');
 // iterate through all the pages until we find $wordInstances of the word
 // we're looking for
 $foundInstances = 0;
 while (list($page_text, $page, $proofer_names) = page_info_fetch($pages_res)) {
     // get a context string
     list($context_strings, $totalLines) = _get_word_context_from_text($page_text, $word);
     if (!count($context_strings)) {
         continue;
     }
     echo "<p>";
     echo "<b>" . _("Page") . "</b>: <a href='displayimage.php?project={$projectid}&amp;imagefile={$page}&amp;showreturnlink=0' target='imageframe'>{$page}</a><br>";
     foreach ($context_strings as $lineNum => $context_string) {
         $context_string = _highlight_word(html_safe($context_string, ENT_NOQUOTES), $word);
         echo "<b>", _("Line"), "</b>: ", sprintf(_('~%1$d of %2$d'), $lineNum, $totalLines), " &nbsp; | &nbsp; ";