Beispiel #1
0
/**
 * Import existing codes for a release.
 */
function dc_import_codes($release_id, $prefix, $list_of_codes)
{
    global $wpdb;
    // Prepare array of import codes
    $arr_codes = split("\n", str_replace("\r", '', $list_of_codes));
    // Verify code prefixes before inserting
    if ('' != $prefix) {
        foreach ($arr_codes as $code) {
            // Check if code starts with prefix, otherwise return error message
            if ('' != $code && strpos($code, $prefix) !== 0) {
                return dc_admin_message('Not all codes start with the given prefix "' . $prefix . '"', 'error');
            }
        }
    }
    // Verify that none of the existing codes collides with the import codes
    $existing_codes = $wpdb->get_results('SELECT CONCAT(code_prefix, code_suffix) AS `code` FROM ' . dc_tbl_codes() . ' WHERE CONCAT(code_prefix, code_suffix) IN ("' . join('","', $arr_codes) . '")', ARRAY_N);
    if (sizeof($existing_codes) > 0) {
        $existing_codes_list = array();
        foreach ($existing_codes as $existing_code) {
            array_push($existing_codes_list, $existing_code[0]);
        }
        return dc_admin_message('The codes could not be imported, because the following codes already exist for this release: ' . join(", ", $existing_codes_list), 'error');
    }
    // Create new code group
    $wpdb->insert(dc_tbl_code_groups(), array('release' => $release_id), array('%d'));
    $group_id = $wpdb->insert_id;
    // Import codes
    $number_of_codes = 0;
    foreach ($arr_codes as $code) {
        if ('' != $code) {
            // Insert code
            $wpdb->insert(dc_tbl_codes(), array('code_prefix' => $prefix, 'code_suffix' => substr($code, strlen($prefix)), 'group' => $group_id, 'release' => $release_id), array('%s', '%s', '%d', '%d'));
            $number_of_codes++;
        }
    }
    return dc_admin_message($number_of_codes . " code" . ($number_of_codes != 1 ? "s have" : " has") . " been imported");
}
Beispiel #2
0
/**
 * Manages download codes
 */
function dc_manage_codes()
{
    global $wpdb;
    // Set option to enable big SQL selects
    $wpdb->query('SET OPTION SQL_BIG_SELECTS = 1');
    // GET parameters
    $get_release = $_GET['release'];
    $get_group = $_GET['group'];
    $get_action = $_GET['action'];
    // POST parameters
    $post_release = $_POST['release'];
    // List of releases
    $releases = dc_get_releases();
    if ($get_release == '' && $post_release == '') {
        $release_id = $releases[0]->ID;
    } elseif ($post_release != '') {
        $release_id = $post_release;
    } elseif ($get_release != '') {
        $release_id = $get_release;
    }
    // Show page title
    echo '<div class="wrap">';
    echo '<h2>Download Codes &raquo; Manage Codes</h2>';
    switch ($get_action) {
        case 'make-final':
            // Finalize new codes
            $finalize_count = dc_finalize_codes($release_id, $get_group);
            echo dc_admin_message('' . $finalize_count . ' download code(s) were finalized');
            break;
        case 'delete':
            // Delete (not finalized) codes
            $deleted_count = dc_delete_codes($release_id, $get_group);
            echo dc_admin_message('' . $deleted_count . ' download code(s) were deleted');
            break;
        case 'generate':
            // Generate new codes
            $message = dc_generate_codes($release_id, strtoupper(trim($_POST['prefix'])), trim($_POST['codes']), trim($_POST['characters']));
            echo $message;
            break;
        case 'import':
            // Import existing codes
            $message = dc_import_codes($release_id, strtoupper(trim($_POST['import-prefix'])), trim($_POST['import-codes']));
            echo $message;
            break;
        case 'reset':
            // Reset codes
            $reset_count = dc_reset_downloads($_POST['download-ids']);
            echo dc_admin_message('' . $reset_count . ' downloads reset');
            break;
    }
    if (sizeof($releases) == 0) {
        // Display message if no release exists yet
        echo dc_admin_message('No releases have been created yet');
        echo '<p><a class="button-primary" href="admin.php?page=dc-manage-releases&amp;action=add">Add New Release</a></p>';
    } else {
        // There are some releases
        echo '<form action="admin.php?page=dc-manage-codes&action=select" method="post">';
        echo '<input type="hidden" name="action" value="select" />';
        // Display release picker
        echo '<h3>Select a Release: ';
        echo '<select name="release" id="release" onchange="submit();">';
        foreach ($releases as $release) {
            echo '<option value="' . $release->ID . '"' . ($release->ID == $release_id ? ' selected="selected"' : '') . '>' . ($release->artist ? $release->artist . ' - ' : '') . $release->title . ' (' . $release->filename . ')</option>';
        }
        echo '</select>';
        echo '</h3>';
        echo '</form>';
        // Get codes for current release
        $code_groups = dc_get_code_groups($release_id);
        $release = $code_groups[0];
        if (sizeof($code_groups) > 0) {
            // Subtitle
            echo '<h3>' . $release->artist . ' - ' . $release->title . ' (' . $release->filename . ') [ID: ' . $release->ID . ']</h3>';
            // Show shortcode example
            echo '<p><span class="description">Insert the following shortcode into a page or article:</span> <code>[download-code id="' . $release_id . '"]</code></p>';
            echo '<table class="widefat dc_codes">';
            echo '<thead>';
            echo '<tr><th>Prefix</th><th>Finalized</th><th>Codes</th><th>Sample Code</th><th>Downloaded</th><th>Actions</th></tr>';
            echo '</thead>';
            // List codes
            echo '<tbody>';
            // Check that codes are actual data
            if ($code_groups[0]->group != '') {
                foreach ($code_groups as $code_group) {
                    echo '<tr><td>' . $code_group->code_prefix . '</td><td>' . ($code_group->final == 1 ? "Yes" : "No") . '</td>';
                    echo '<td>' . $code_group->codes . '</td>';
                    echo '<td>' . $code_group->code_prefix . $code_group->code_example . '</td>';
                    echo '<td>' . $code_group->downloads . ' (' . $code_group->downloaded_codes . ' ' . ($code_group->downloaded_codes == 1 ? 'code' : 'codes') . ')</td>';
                    echo '<td>';
                    // Link to make codes final/delete codes or to export final codes
                    if ($code_group->final == 0) {
                        echo '<a href="admin.php?page=dc-manage-codes&amp;release=' . $release->ID . '&amp;group=' . $code_group->group . '&amp;action=make-final" class="action-finalize">Finalize</a> | ';
                        echo '<a href="admin.php?page=dc-manage-codes&amp;release=' . $release->ID . '&amp;group=' . $code_group->group . '&amp;action=delete" class="action-delete">Delete</a>';
                    } else {
                        echo '<a href="admin.php?page=dc-manage-codes&amp;release=' . $release->ID . '&amp;group=' . $code_group->group . '&amp;action=list" class="action-list" rel="dc_list-' . $code_group->group . '">List codes</a> | ';
                        echo '<a href="admin.php?page=dc-manage-codes&amp;release=' . $release->ID . '&amp;group=' . $code_group->group . '&amp;action=report" class="action-report" rel="dc_downloads-' . $code_group->group . '">View report</a>';
                    }
                    echo '</td></tr>';
                }
            }
            echo '</tbody>';
            echo '<tfoot>';
            echo '<tr><th>Prefix</th><th>Finalized</th><th>Codes</th><th>Sample Code</th><th>Downloaded</th><th>Actions</th></tr>';
            echo '</tfoot>';
            echo '</table>';
            // Output codes and downloads for lightbox option
            foreach ($code_groups as $code_group) {
                dc_list_codes($release_id, $code_group->group, FALSE);
                dc_list_downloads($release_id, $code_group->group, FALSE, 'admin.php?page=dc-manage-codes&amp;action=reset');
            }
            // Show form to add codes
            echo '<form id="form-manage-codes" action="admin.php?page=dc-manage-codes&amp;action=generate" method="post">';
            echo '<input type="hidden" name="release" value="' . $release->ID . '" />';
            echo '<h3>Generate New Batch of Codes</h3>';
            echo '<table class="form-table">';
            echo '<tr valign="top">';
            echo '<th scope="row"><label for="new-prefix">Code Prefix</label></th>';
            echo '<td><input type="text" name="prefix" id="new-prefix" class="small-text" value="' . $post_prefix . '" />';
            echo ' <span class="description">First characters of each code</span></td>';
            echo '</tr>';
            echo '<tr valign="top">';
            echo '<th scope="row"><label for="new-quantity">Quantity</label></th>';
            echo '<td><input type="text" name="codes" id="new-quantity" class="small-text" maxlength="5" value="' . $post_codes . '" />';
            echo ' <span class="description">Number of codes to generate</span></td>';
            echo '</tr>';
            echo '<tr valign="top">';
            echo '<th scope="row"><label for="new-length">Length</label></th>';
            echo '<td><input type="text" name="characters" id="new-length" class="small-text" maxlength="2" value="' . ($post_characters != '' ? $post_characters : '8') . '" />';
            echo ' <span class="description">Number of random characters each code contains</span></td>';
            echo '</tr>';
            echo '</table>';
            echo '<p class="submit">';
            echo '<input type="submit" name="submit" class="button-secondary" value="Generate Codes" />';
            echo '</p>';
            echo '</form>';
            // Show form to import existing codes
            echo '<form action="admin.php?page=dc-manage-codes&amp;action=import" method="post">';
            echo '<input type="hidden" name="release" value="' . $release->ID . '" />';
            echo '<h3>Import Existing Download Codes</h3>';
            echo '<table class="form-table">';
            echo '<tr valign="top">';
            echo '<th scope="row"><label for="import-prefix">Code Prefix</label></th>';
            echo '<td><input type="text" name="import-prefix" id="import-prefix" class="small-text" value="' . $_POST['import-prefix'] . '" />';
            echo ' <span class="description">First characters of each code. It is recommended that all of your codes to be imported have a common prefix. If this is not the case, this field can be left empty.</span></td>';
            echo '</tr>';
            echo '<tr valign="top">';
            echo '<th scope="row"><label for="import-codes">List of Codes</label></th>';
            echo '<td><textarea name="import-codes" id="import-codes" cols="20" rows="20" class="small-text">' . $_POST['import-codes'] . '</textarea>';
            echo ' <span class="description">Plain list of codes to be imported (separated by linebreaks)</span></td>';
            echo '</tr>';
            echo '</table>';
            echo '<p class="submit">';
            echo '<input type="submit" name="submit" class="button-secondary" value="Import Codes" />';
            echo '</p>';
            echo '</form>';
        }
        // Show list of download codes or download report in case lightbox option is not applicable
        switch ($get_action) {
            case 'list':
                echo '<h3>List of Download Codes</h3>';
                dc_list_codes($release_id, $get_group);
                break;
            case 'report':
                echo '<h3>Code Usage Report</h3>';
                dc_list_downloads($release_id, $get_group);
                break;
        }
    }
    echo '</div>';
}
/**
 * General download code plugin settings
 */
function dc_manage_settings()
{
    echo '<div class="wrap">';
    echo '<h2>Download Codes &raquo; Settings</h2>';
    // Overwrite existing options
    if (isset($_POST['submit'])) {
        $dc_file_location = trim('' != trim($_POST['dc_file_location_abs']) ? $_POST['dc_file_location_abs'] : $_POST['dc_file_location']);
        $dc_max_attempts = $_POST['dc_max_attempts'];
        // Update zip location
        if ($dc_file_location != '') {
            if (substr($dc_file_location, -1) != '/') {
                $dc_file_location .= '/';
            }
            update_option('dc_file_location', $dc_file_location);
        }
        // Update number of maximum attempts
        if (is_numeric($dc_max_attempts)) {
            update_option('dc_max_attempts', $dc_max_attempts);
        }
        // Update file types
        if ('' != trim($_POST['dc_file_types'])) {
            update_option('dc_file_types', trim($_POST['dc_file_types']));
        }
        // Update character list
        update_option('dc_code_chars', $_POST['dc_code_chars'] == '' ? DC_CODE_CHARS : $_POST['dc_code_chars']);
        // Update header settings
        update_option('dc_header_content_type', $_POST['dc_header_content_type'] == '' ? DC_HEADER_CONTENT_TYPE : $_POST['dc_header_content_type']);
        // Update xsenfile enabled flag
        update_option('dc_xsendfile_enabled', isset($_POST['dc_xsendfile_enabled']) ? 'true' : 'false');
        // Update messages
        update_option('dc_msg_code_enter', $_POST['dc_msg_code_enter']);
        update_option('dc_msg_code_valid', $_POST['dc_msg_code_valid']);
        update_option('dc_msg_code_invalid', $_POST['dc_msg_code_invalid']);
        update_option('dc_msg_max_downloads_reached', $_POST['dc_msg_max_downloads_reached']);
        update_option('dc_msg_max_attempts_reached', $_POST['dc_msg_max_attempts_reached']);
        // Print message
        echo dc_admin_message('The settings have been updated.');
    }
    echo '<form action="admin.php?page=dc-manage-settings" method="post">';
    echo '<h3>File Settings</h3>';
    echo '<table class="form-table">';
    /**
     * Location of download files
     */
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-location">Location of download files</label></th>';
    if ('' == get_option('dc_file_location') || '' != get_option('dc_file_location') && '/' != substr(get_option('dc_file_location'), 0, 1)) {
        // If current location of download files is empty or relative, try to locate the upload folder
        $wp_upload_dir = wp_upload_dir();
        $files = scandir($wp_upload_dir['basedir']);
        echo '<td>' . $wp_upload_dir['basedir'] . '/ <select name="dc_file_location" id="settings-location">';
        foreach ($files as $folder) {
            if (is_dir($wp_upload_dir['basedir'] . '/' . $folder) && $folder != '.' && $folder != '..') {
                echo '<option' . ($folder . '/' == get_option('dc_file_location') ? ' selected="selected"' : '') . '>' . $folder . '</option>';
            }
        }
        echo '</select>';
        // Provide possibility to define upload path directly
        echo '<p>If the upload folder cannot be determined or if the release management does not work (or if you want to have another download file location) you may specify the absolute path of the download file location here:</p>';
        echo '<input type="text" name="dc_file_location_abs" class="large-text" / >';
        echo '</td>';
    } else {
        echo '<td><input type="text" name="dc_file_location" id="settings-location" class="large-text" value="' . get_option('dc_file_location') . '" /></td>';
    }
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-max">Maximum attempts</label></th>';
    echo '<td><input type="text" name="dc_max_attempts" id="settings-max" class="small-text" value="' . dc_max_attempts() . '" />';
    echo ' <span class="description">Maximum invalid download attempts</span></td>';
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-filetypes">Allowed file types</label></th>';
    echo '<td><input type="text" name="dc_file_types" id="settings-filetypes" class="regular-text" value="' . implode(', ', dc_file_types()) . '" />';
    echo ' <span class="description">Separated by comma</span></td>';
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-chars">Allowed characters</label></th>';
    echo '<td><input type="text" name="dc_code_chars" id="settings-chars" class="regular-text" value="' . dc_code_chars() . '" />';
    echo ' <span class="description">Codes will contain a random mix of these characters</span></td>';
    echo '</tr>';
    echo '</table>';
    /**
     * Headers
     */
    echo '<h3>Header Settings</h3>';
    echo '<p>Finetune request headers to fix client-server issues:</p>';
    echo '<table class="form-table">';
    // Content type
    $dc_header_content_type = dc_header_content_type();
    $content_type_options = array('Default (MIME Type)', 'application/force-download', 'application/octet-stream', 'application/download');
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="headers-content-type">Content type</label></th>';
    echo '<td><select name="dc_header_content_type" id="headers-content-type">';
    foreach ($content_type_options as $option) {
        echo '<option' . ($option == $dc_header_content_type ? ' selected="selected"' : '') . '>' . $option . '</option>';
    }
    echo '</select> <span class="description">Override default content type (which is the MIME type of the download file)</span></td>';
    echo '</tr>';
    // Support for x-sendfile
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="headers-xsendfile-enabled">Apache X-Sendfile</label></th>';
    echo '<td><input type="checkbox" name="dc_xsendfile_enabled" id="dc-xsendfile-enabled" ' . (dc_xsendfile_enabled() ? 'checked' : '') . ' />';
    echo '<span class="description">Only check this setting if Apache\'s x-sendfile module is installed and configured properly</span>';
    echo '</td>';
    echo '</tr>';
    echo '</table>';
    /**
     * Messages
     */
    echo '<h3>Messages</h3>';
    echo '<p>Specify custom messages that your users see while downloading releases:</p>';
    echo '<table class="form-table">';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-msg-enter">"Enter code"</label></th>';
    echo '<td><input type="text" name="dc_msg_code_enter" id="settings-msg-enter" class="large-text" value="' . dc_msg('code_enter') . '" /></td>';
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-msg-valid">"Code valid"</label></th>';
    echo '<td><input type="text" name="dc_msg_code_valid" id="settings-msg-valid" class="large-text" value="' . dc_msg('code_valid') . '" /></td>';
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-msg-invalid">"Code invalid"</label></th>';
    echo '<td><input type="text" name="dc_msg_code_invalid" id="settings-msg-invalid" class="large-text" value="' . dc_msg('code_invalid') . '" /></td>';
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-msg-downloads">"Maximum downloads reached"</label></th>';
    echo '<td><input type="text" name="dc_msg_max_downloads_reached" id="settings-msg-downloads" class="large-text" value="' . dc_msg('max_downloads_reached') . '" /></td>';
    echo '</tr>';
    echo '<tr valign="top">';
    echo '<th scope="row"><label for="settings-msg-attempts">"Maximum attempts reached"</label></th>';
    echo '<td><input type="text" name="dc_msg_max_attempts_reached" id="settings-msg-attempts" class="large-text" value="' . dc_msg('max_attempts_reached') . '" /></td>';
    echo '</tr>';
    echo '</table>';
    echo '<p class="submit">';
    echo '<input type="submit" name="submit" class="button-primary" value="Save Changes" />';
    echo '</p>';
    echo '</form>';
    echo '</div>';
}
Beispiel #4
0
/**
 * Manages releases
 */
function dc_manage_releases()
{
    global $wpdb;
    $wpdb->query('SET OPTION SQL_BIG_SELECTS = 1');
    // Get parameters
    $get_action = $_GET['action'];
    $get_release = $_GET['release'];
    // Post parameters
    $post_action = $_POST['action'];
    $post_release = $_POST['release'];
    // Show page title
    echo '<div class="wrap">';
    echo '<h2>Download Codes &raquo; Manage Releases</h2>';
    switch ($get_action) {
        case 'edit':
        case 'add':
            // Update or insert release
            if (isset($_POST['submit'])) {
                if ($post_action == 'add') {
                    $result = dc_add_release();
                    if (is_array($result)) {
                        echo dc_admin_message(implode('</p><p>', $result));
                    } else {
                        if ($result === FALSE) {
                            echo dc_admin_message('There was an error adding the release');
                        } else {
                            echo dc_admin_message('The release was added successfully');
                            $add_success = true;
                        }
                    }
                }
                if ($post_action == 'edit') {
                    $result = dc_edit_release();
                    if (is_array($result)) {
                        // display errors
                    } else {
                        if ($result === FALSE) {
                            echo dc_admin_message('There was an error updating the release');
                        } else {
                            echo dc_admin_message('The release was updated successfully');
                            $edit_success = true;
                        }
                    }
                }
            }
            break;
        case 'delete':
            $result = dc_delete_release($get_release);
            if ($result) {
                echo dc_admin_message('The release was deleted successfully');
            } else {
                echo dc_admin_message('There was an error deleting the release');
            }
            break;
    }
    if (($get_action == 'edit' || $get_action == 'add') && !$add_success) {
        //*********************************************
        // Add or edit a release
        //*********************************************
        // Get zip files in download folder
        $files = scandir(dc_file_location());
        $num_download_files = 0;
        foreach ($files as $filename) {
            if (in_array(strtolower(substr($filename, -3)), dc_file_types())) {
                $num_download_files++;
            }
        }
        if ($num_download_files == 0) {
            echo dc_admin_message('No files have been uploaded to the releases folder: <em>' . dc_file_location() . '</em></p><p><strong>You must do this first before adding a release!</strong>');
        }
        // Get current release
        if ('' != $get_release) {
            $release = dc_get_release($get_release);
        }
        if ('' != $post_release) {
            $release = dc_get_release($post_release);
        }
        // Write page subtitle
        echo '<h3>' . ('add' == $get_action ? 'Add New' : 'Edit') . ' Release</h3>';
        echo '<p><a href="admin.php?page=dc-manage-releases">&laquo; Back to releases</a></p>';
        // Display form
        echo '<form action="admin.php?page=dc-manage-releases&action=' . $get_action . '" method="post">';
        echo '<input type="hidden" name="release" value="' . $release->ID . '" />';
        echo '<input type="hidden" name="action" value="' . $get_action . '" />';
        echo '<table class="form-table">';
        // Title
        echo '<tr valign="top">';
        echo '<th scope="row"><label for="release-title">Title</label></th>';
        echo '<td><input type="text" name="title" id="release-title" class="regular-text" value="' . $release->title . '" />';
        echo ' <span class="description">For example, the album title</span></td>';
        echo '</tr>';
        // Artist
        echo '<tr valign="top">';
        echo '<th scope="row"><label for="release-artist">Artist (optional)</label></th>';
        echo '<td><input type="text" name="artist" id="release-artist" class="regular-text" value="' . $release->artist . '" />';
        echo ' <span class="description">The band or artist</span></td>';
        echo '</tr>';
        // File
        echo '<tr valign="top">';
        echo '<th scope="row"><label for="release-file">File</label></th>';
        echo '<td>' . dc_file_location() . ' <select name="filename" id="release-file">-->';
        // Get array of allowed file types/extensions
        $allowed_file_types = dc_file_types();
        // List all files matching the allowed extensions
        foreach ($files as $filename) {
            $file_extension_array = split("\\.", $filename);
            $file_extension = strtolower($file_extension_array[sizeof($file_extension_array) - 1]);
            if (in_array($file_extension, $allowed_file_types)) {
                echo '<option' . ($filename == $release->filename ? ' selected="selected"' : '') . '>' . $filename . '</option>';
            }
        }
        echo '</select></td>';
        echo '</tr>';
        // Allowed downloads
        echo '<tr valign="top">';
        echo '<th scope="row"><label for="release-downloads">Allowed downloads</label></th>';
        echo '<td><input type="text" name="downloads" id="release-downloads" class="small-text" value="' . ($release->allowed_downloads > 0 ? $release->allowed_downloads : DC_ALLOWED_DOWNLOADS) . '" />';
        echo ' <span class="description">Maximum number of times each code can be used</span></td>';
        echo '</tr>';
        echo '</table>';
        // Submit
        echo '<p class="submit">';
        echo '<input type="submit" name="submit" class="button-primary" value="' . ($get_action == 'edit' ? 'Save Changes' : 'Add Release') . '" />';
        echo '</p>';
        echo '</form>';
    } else {
        //*********************************************
        // List releases
        //*********************************************
        // Write page subtitle
        echo '<h3>Releases</h3>';
        // Get releases
        $releases = dc_get_releases();
        // Check if the releases are empty
        if (sizeof($releases) == 0) {
            echo dc_admin_message('No releases have been created yet');
            echo '<p>You might want to <a href="admin.php?page=dc-manage-releases&action=add">add a new release</a></p>';
        } else {
            echo '<table class="widefat">';
            echo '<thead>';
            echo '<tr><th>Title</th><th>Artist</th><th>ID</th><th>File</th><th>Codes</th><th>Downloaded</th><th>Actions</th></tr>';
            echo '</thead>';
            echo '<tbody>';
            foreach ($releases as $release) {
                echo '<tr>';
                echo '<td><strong>' . $release->title . '</strong></td><td>' . $release->artist . '</td>';
                echo '<td>' . $release->ID . '</td>';
                echo '<td>' . $release->filename . '</td>';
                echo '<td>' . $release->codes . '</td><td>' . $release->downloads . '</td>';
                echo '<td>';
                echo '<a href="admin.php?page=dc-manage-releases&amp;release=' . $release->ID . '&amp;action=edit" class="action-edit">Edit</a> | ';
                echo '<a href="admin.php?page=dc-manage-codes&amp;release=' . $release->ID . '" class="action-manage">Manage codes</a> | ';
                echo '<a href="admin.php?page=dc-manage-codes&amp;release=' . $release->ID . '&amp;action=report" class="action-report" rel="dc_downloads-' . $release->ID . '">View report</a> | ';
                echo '<a href="admin.php?page=dc-manage-releases&amp;release=' . $release->ID . '&amp;action=delete" class="action-delete">Delete</a>';
                echo '</td>';
                echo '</tr>';
            }
            echo '</tbody>';
            echo '<tfoot>';
            echo '<tr><th>Title</th><th>Artist</th><th>ID</th><th>File</th><th>Codes</th><th>Downloaded</th><th>Actions</th></tr>';
            echo '</tfoot>';
            echo '</table>';
            foreach ($releases as $release) {
                dc_list_downloads($release->ID, NULL, FALSE);
            }
        }
        // Show link to add a new release
        echo '<p><a class="button-primary" href="admin.php?page=dc-manage-releases&amp;action=add">Add New Release</a></p>';
    }
    echo '</div>';
}