'form', 'plural' => 'forms', )); add_action('admin_footer', array($this, '_script')); } /** * you can skip columns that you do not want to show * like content, or description * * @return array */ function get_columns() { $columns = array( 'cb' => '', 'name' => __('Form', "ajaxy-forms"), 'shortcode' => __('Shortcode', "ajaxy-forms"), 'entries' => __('Entries', "ajaxy-forms"), 'metadata' => __('Metadata', "ajaxy-forms"), 'created' => __('Date', "ajaxy-forms"), ); return $columns; } /** * @global string $comment_status * @global string $comment_type * * @param string $which */ protected function extra_tablenav($which) { static $has_items; if (!isset($has_items)) { $has_items = $this->has_items(); } echo '
'; echo '
'; } /** * all strings in array - is column names * notice that true on name column means that its default sort * * @return array */ function get_sortable_columns() { $sortable_columns = array( 'name' => array('name', true), 'created' => array('created', true), ); return $sortable_columns; } /** * * @param $item - row (key, value array) * @param $column_name - string (key) * @return HTML */ function column_default($item, $column_name) { return $item[$column_name] ?? ''; } function column_entries($item) { return \sprintf('(%s) - View Entries', Data::count_entries($item['name']), admin_url('admin.php?page=ajaxy-form-entries&form=' . $item['name'])); } /** * * @param $item - row (key, value array) * @return HTML */ function column_cb($item) { return sprintf( '', $item['id'] ); } /** * when you hover row "Edit | Delete" links showed * * @param $item - row (key, value array) * @return HTML */ function column_name($item) { $edit_url = esc_url( add_query_arg( array( 'action' => 'edit', 'form' => $item['id'], ), admin_url('admin.php?page=ajaxy-form') ) ); $delete_url = esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'form' => $item['id'], ), admin_url('admin.php?page=ajaxy-form') ), 'delete-form-' . $item['id'] ) ); $actions = array( 'edit' => sprintf('%s', $edit_url, __('Edit', "ajaxy-forms")), 'delete' => sprintf('%s', $delete_url, __('Delete', "ajaxy-forms")), ); return sprintf( '%s %s', ucwords($item['name']), $this->row_actions($actions) ); } /** * when you hover row "Edit | Delete" links showed * * @param $item - row (key, value array) * @return HTML */ function column_shortcode($item) { if (!isset($item['name'])) { return ''; } return sprintf(' ', sprintf('[form name="%s"]', \esc_attr($item['name']))); } function column_metadata($item) { if (!isset($item['metadata'])) { return ''; } return $this->create_tree_list(json_decode($item['metadata'], true)); } public function column_created($item) { $output = ''; $metadata = $item['metadata'] ?? null; $default = 'Submitted By Anonymous'; if ($metadata) { $metadata = json_decode($metadata, true); if (isset($metadata['user'])) { $user = $metadata['user']; if (!empty($user)) { $output .= sprintf( 'Submitted By %2$s', esc_url( add_query_arg( 'wp_http_referer', urlencode(wp_unslash($_SERVER['REQUEST_URI'])), self_admin_url('user-edit.php?user_id=' . $user['id']) ) ), ucwords($user['display_name']) ); } else { $output .= $default; } } else { $output .= $default; } if (isset($metadata['ip'])) { $output .= sprintf('
IP: %1$s', $metadata['ip']); } } else { $output .= $default; } $output .= "
"; $datetime = $this->parse_datetime($item['created']); if (false === $datetime) { return $output; } $t_time = sprintf( /* translators: 1: date, 2: time */ __('%1$s at %2$s', "ajaxy-forms"), /* translators: date format, see https://www.php.net/date */ $datetime->format(__('Y/m/d', "ajaxy-forms")), /* translators: time format, see https://www.php.net/date */ $datetime->format(__('g:i a', "ajaxy-forms")) ); return $output . $t_time; } /** * * @return array */ function get_bulk_actions() { $actions = array( 'delete' => 'Delete' ); return $actions; } /** * it can be outside of class * it can not use wp_redirect coz there is output already * in this example we are processing delete action * message about successful deletion will be shown on page in next part */ function process_bulk_action() { if ('delete' === $this->current_action() && \wp_verify_nonce($_REQUEST['_wpnonce'], 'bulk-' . $this->_args['plural'])) { $ids = (array)(isset($_REQUEST['id']) ? $_REQUEST['id'] : array()); if (!empty($ids)) { Data::delete_forms($ids); } } } /** * * It will get rows from database and prepare them to be showed in table */ function prepare_items() { $per_page = 10; // constant, how much records will be shown per page $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); $this->process_bulk_action(); // will be used in pagination settings $total_items = Data::count_entries(); if ($total_items === null || \is_wp_error($total_items)) { global $wpdb; add_action('admin_notices', function () { $class = 'notice notice-error'; $message = __('An error has occurred.', "ajaxy-forms"); printf('

%2$s

', esc_attr($class), esc_html($message)); }); \printf('

Error: %s - %s

', esc_html($wpdb->last_error), 'Please activate and deactivate the plugin to reinstall the tables'); } // prepare query params, as usual current page, order by and order direction $paged = isset($_REQUEST['paged']) ? intval($_REQUEST['paged']) : 1; $orderby = (isset($_REQUEST['orderby']) && in_array($_REQUEST['orderby'], array_keys($this->get_sortable_columns()))) ? $_REQUEST['orderby'] : 'created'; $order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'desc'; $this->items = Data::get_database_forms($paged, $orderby, $order, $per_page); $this->set_pagination_args(array( 'total_items' => intval($total_items), // total items defined above 'per_page' => $per_page, // per page constant defined at top of method 'total_pages' => ceil($total_items / $per_page) // calculate pages count )); } function parse_datetime($time) { $wp_timezone = wp_timezone();; $timezone = $wp_timezone; if (empty($time) || '0000-00-00 00:00:00' === $time) { return false; } $datetime = date_create_immutable_from_format('Y-m-d H:i:s', $time, $timezone); if (false === $datetime) { return false; } return $datetime->setTimezone($wp_timezone); } public function _script() { ?>