'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();
?>