'snapshot', //singular name of the listed records 'plural' => 'snapshots', //plural name of the listed records 'ajax' => false //does this table support ajax? ) ); } function get_report() { global $wpdb; $prefix = $wpdb->prefix; $statement = "SELECT c.id, c.url, c.status, c.last_checked, c.message, ca.date, ca.size, ca.provider, ca.location, a.views, a.date as activity_date, substring_index(c.url,'://',-1) as url_sort " . "FROM ${prefix}amber_check c " . "LEFT JOIN ${prefix}amber_cache ca on ca.id = c.id " . "LEFT JOIN ${prefix}amber_activity a on ca.id = a.id "; if (!empty($_REQUEST['orderby'])) { if (in_array($_REQUEST['orderby'], array('c.url', 'c.last_checked', 'ca.date', 'c.status', 'ca.size', 'a.date', 'a.views', 'url_sort'), true)) { $statement .= " ORDER BY " . $_REQUEST['orderby']; if (!empty($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc','desc'))) { $statement .= " " . $_REQUEST['order']; } else { $statement .= " DESC"; } } } $rows = $wpdb->get_results($statement, ARRAY_A); return $rows; } /** Column display functions **/ function column_default($item, $column_name){ return $item[$column_name]; } function column_site($item) { $actions = array(); if (!empty($item['location'])) { if (strpos($item['location'],"http") === 0) { $url = htmlspecialchars($item['location']); } else { $url = join('/',array(get_site_url(),htmlspecialchars($item['location']))); } $actions['view'] = "View"; } if (!empty($item['id'])) { $url = join('/',array(get_site_url(),"wp-admin/tools.php?page=amber-dashboard")) . "&delete=" . $item['id'] . "&provider=" . $item['provider']; $params = array('orderby', 'order'); foreach ($params as $param) { if (isset($_REQUEST[$param])) { $url .= "&${param}=" . $_REQUEST[$param]; } } $url = wp_nonce_url($url, 'delete_link_' . $item['id']); $actions['delete'] = "Delete"; } return parse_url($item['url'],PHP_URL_HOST) . $this->row_actions($actions); } function column_status($item) { return $item['status'] ? 'Up' : 'Down'; } function column_size($item) { if (isset($item['provider']) && ($item['provider'] == AMBER_BACKEND_PERMA)) { return ""; } else { return round($item['size'] / 1024, 2); } } function column_last_checked($item) { return isset($item['last_checked']) ? date('r',$item['last_checked']) : ""; } function column_date($item) { return isset($item['date']) ? date('r',$item['date']) : ""; } function column_activity_date($item) { return isset($item['activity_date']) ? date('r',$item['activity_date']) : ""; } function column_method($item) { $p = isset($item['provider']) ? $item['provider'] : ""; if (!isset($item['size'])) { return ""; } switch ($p) { case AMBER_BACKEND_PERMA: return "Perma"; break; case AMBER_BACKEND_INTERNET_ARCHIVE: return "Internet Archive"; break; case AMBER_BACKEND_AMAZON_S3: return "Amazon S3"; break; case AMBER_BACKEND_LOCAL: return "Local storage"; break; } } /** Define the columns and sortable columns for the table **/ function get_columns(){ $columns = array( 'site' => 'Site', 'url' => 'URL', 'status' => 'Status', 'last_checked' => 'Last checked', 'date' => 'Date preserved', 'size' => 'Size (kB)', 'activity_date' => 'Last viewed', 'views' => 'Total views', 'method' => 'Storage method', 'message' => 'Notes', ); return $columns; } function get_sortable_columns() { $sortable_columns = array( 'url' => array('url_sort',false), //true means it's already sorted 'status' => array('c.status',false), 'last_checked' => array('c.last_checked',false), 'date' => array('ca.date',false), 'size' => array('ca.size',false), 'a.date' => array('a.date',false), 'views' => array('a.views',false), ); return $sortable_columns; } function single_row($item) { echo ""; $this->single_row_columns( $item ); echo ''; } function prepare_items() { $per_page = 20; $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); /** Load the data from the database **/ $data = $this->get_report(); /** Currently handling pagination within the PHP code **/ $current_page = $this->get_pagenum(); $total_items = count($data); $data = array_slice($data,(($current_page-1)*$per_page),$per_page); /** Setup the data for the table **/ $this->items = $data; /** Register our pagination options & calculations. **/ $this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items/$per_page) ) ); } } class AmberDashboardPage { /* Reference to the global $wpdb object */ private $db; public function __construct() { global $wpdb; add_action( 'admin_menu', array( $this, 'add_plugin_page' ) ); add_action( 'admin_init', array( $this, 'page_init' ) ); } /** * Add dashboard page to the menu system */ public function add_plugin_page() { add_management_page( 'Amber Dashboard', 'Amber Dashboard', 'manage_options', 'amber-dashboard', array( $this, 'render_dashboard_page' ) ); } /* Handle any actions that might be requested on a page load. * Other actions handled through ajax calls are not included in this function */ public function page_init() { global $_REQUEST; if (isset($_REQUEST['delete_all'])) { $this->delete_all(); } else if (isset($_REQUEST['delete'])) { $this->delete($_REQUEST['delete'], $_REQUEST['provider']); } else if (isset($_REQUEST['export'])) { $this->export(); } /* Since at least one action ('delete') is passed as a GET request in the URL, * redirect to this same page, but without that action in the URL. (This prevents * problems on refresh, such as deleting the item again). Add back any page parameters * we want to keep before redirecting. (This would not be necessary if submitted * delete requests through a post, with a combination of javascript and hidden fields) */ if (isset($_REQUEST['delete_all']) || isset($_REQUEST['delete'])) { $redirect = join('/',array(get_site_url(),"wp-admin/tools.php?page=amber-dashboard")); $params = array('orderby', 'order'); foreach ($params as $param) { if (isset($_REQUEST[$param])) { $redirect .= "&${param}=" . $_REQUEST[$param]; } } wp_redirect($redirect); die(); } } private function cache_size() { global $wpdb; $prefix = $wpdb->prefix; return $wpdb->get_var( "SELECT COUNT(*) FROM ${prefix}amber_cache" ); } private function queue_size() { global $wpdb; $prefix = $wpdb->prefix; return $wpdb->get_var( "SELECT COUNT(*) FROM ${prefix}amber_queue" ); } private function last_check() { $result = get_option(AMBER_VAR_LAST_CHECK_RUN, ""); return ($result) ? date("r", $result) : "Never"; } private function disk_usage() { global $wpdb; $status = new AmberStatus(new AmberWPDB($wpdb), $wpdb->prefix); $result = round($status->get_cache_size() / (1024 * 1024), 2); return $result ? $result : 0; } private function delete($id, $provider) { check_admin_referer( 'delete_link_' . $id ); $storage = Amber::get_storage_instance($provider); if (!is_null($storage)) { $storage->delete(array('id' => $id)); } $status = Amber::get_status(); $status->delete($id, $provider); } private function delete_all() { global $wpdb; check_admin_referer('amber_dashboard'); $storage = Amber::get_storage(); $storage->delete_all(); $status = Amber::get_status(); $status->delete_all(); $prefix = $wpdb->prefix; $wpdb->query("DELETE from ${prefix}amber_queue"); } private function export() { global $wpdb; $prefix = $wpdb->prefix; $statement = "SELECT c.id, c.url, c.status, c.last_checked, c.message, ca.date, ca.size, ca.location, a.views, a.date as activity_date " . "FROM ${prefix}amber_check c " . "LEFT JOIN ${prefix}amber_cache ca on ca.id = c.id " . "LEFT JOIN ${prefix}amber_activity a on ca.id = a.id "; $data = $wpdb->get_results($statement, ARRAY_A); $header = array( 'Site', 'URL', 'Status', 'Last Checked', 'Date preserved', 'Size (kB)', 'Last viewed', 'Total views', 'Notes', ); $rows = array(); foreach ($data as $r) { $host = parse_url($r['url'],PHP_URL_HOST); $rows[] = array( 'site' => $host, 'url' => $r['url'], 'status' => $r['status'] ? 'Up' : 'Down', 'last_checked' => isset($r['last_checked']) ? date('c',$r['last_checked']) : "", 'date' => isset($r['date']) ? date('c',$r['date']) : "", 'size' => round($r['size'] / 1024,2), 'a.date' => isset($r['a_date']) ? date('c',$r['a_date']) : "", 'views' => isset($r['views']) ? $r['views'] : 0, 'message' => isset($r['message']) ? $r['message'] : "" ); } header('Content-Type: text/csv'); header('Content-Disposition: attachment;filename=report.csv'); $fp = fopen('php://output', 'w'); fputcsv($fp, $header); foreach($rows as $line){ fputcsv($fp, $line); } fclose($fp); die(); } function render_dashboard_page(){ $this->list_table = new Amber_List_Table(); $this->list_table->prepare_items(); ?>

Amber Dashboard

Global Statistics

Snapshots preservedcache_size()); ?>
Links to snapshotqueue_size()); ?>
Last checklast_check()); ?>
Disk space useddisk_usage() . " of " . Amber::get_option('amber_max_disk')); ?> MB
list_table->display() ?>