You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
300 lines
11 KiB
PHP
300 lines
11 KiB
PHP
<?php
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class AWSM_Job_Openings_Overview {
|
|
private static $instance = null;
|
|
|
|
protected $cpath = null;
|
|
|
|
public static $menu_slug = 'awsm-jobs-overview';
|
|
|
|
public static $screen_id = 'awsm_job_openings_page_awsm-jobs-overview';
|
|
|
|
public function __construct() {
|
|
$this->cpath = untrailingslashit( plugin_dir_path( __FILE__ ) );
|
|
|
|
add_action( 'admin_menu', array( $this, 'admin_menu' ), 1 );
|
|
add_action( 'admin_init', array( $this, 'redirect_to_overview' ) );
|
|
add_action( 'add_meta_boxes_' . self::$screen_id, array( $this, 'register_overview_widgets' ) );
|
|
}
|
|
|
|
public static function init() {
|
|
if ( is_null( self::$instance ) ) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
public function get_widget_path( $basename, $custom_id = false ) {
|
|
$path = $this->cpath . "/templates/overview/widgets/{$basename}.php";
|
|
$unique_id = self::$menu_slug . '-' . $basename;
|
|
if ( ! empty( $custom_id ) ) {
|
|
$unique_id = $custom_id;
|
|
}
|
|
/**
|
|
* Filters the overview widget template path.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param string $path Template path.
|
|
* @param string $unique_id Unique ID to filter the path.
|
|
*/
|
|
return apply_filters( 'awsm_jobs_overview_widget_template_path', $path, $unique_id );
|
|
}
|
|
|
|
public function admin_menu() {
|
|
$wp_version = get_bloginfo( 'version' );
|
|
$page_title = esc_html__( 'WP Job Openings - Overview', 'wp-job-openings' );
|
|
$menu_title = esc_html__( 'Overview', 'wp-job-openings' );
|
|
if ( version_compare( $wp_version, '5.3', '>=' ) ) {
|
|
add_submenu_page( 'edit.php?post_type=awsm_job_openings', $page_title, $menu_title, 'edit_jobs', self::$menu_slug, array( $this, 'overview_page' ), 0 );
|
|
} else {
|
|
add_submenu_page( 'edit.php?post_type=awsm_job_openings', $page_title, $menu_title, 'edit_jobs', self::$menu_slug, array( $this, 'overview_page' ) );
|
|
}
|
|
}
|
|
|
|
public function overview_page() {
|
|
include_once $this->cpath . '/templates/overview/main.php';
|
|
}
|
|
|
|
public function redirect_to_overview() {
|
|
global $pagenow;
|
|
if ( isset( $pagenow ) && $pagenow === 'admin.php' && isset( $_GET['page'] ) && $_GET['page'] === self::$menu_slug ) {
|
|
wp_safe_redirect( add_query_arg( array( 'page' => self::$menu_slug ), admin_url( 'edit.php?post_type=awsm_job_openings' ) ) );
|
|
exit;
|
|
}
|
|
}
|
|
|
|
public function register_overview_widgets() {
|
|
$widgets = array(
|
|
'applications-analytics' => array(
|
|
'active' => current_user_can( 'edit_applications' ),
|
|
'name' => esc_html__( 'Applications Analytics', 'wp-job-openings' ),
|
|
'priority' => 'high',
|
|
),
|
|
'get-started' => array(
|
|
'name' => esc_html__( 'Get Started', 'wp-job-openings' ),
|
|
'context' => 'side',
|
|
'priority' => 'high',
|
|
),
|
|
'applications-by-status' => array(
|
|
'active' => current_user_can( 'edit_applications' ) && ! class_exists( 'AWSM_Job_Openings_Pro_Pack' ),
|
|
'name' => esc_html__( 'Applications by Status', 'wp-job-openings' ),
|
|
'context' => 'side',
|
|
'callback' => array( $this, 'applications_by_status_widget' ),
|
|
),
|
|
'recent-applications' => array(
|
|
'active' => current_user_can( 'edit_others_applications' ),
|
|
'name' => esc_html__( 'Recent Applications', 'wp-job-openings' ),
|
|
),
|
|
'open-positions' => array(
|
|
'name' => esc_html__( 'Open Positions', 'wp-job-openings' ),
|
|
'context' => 'side',
|
|
'callback' => array( $this, 'open_positions_widget' ),
|
|
),
|
|
'your-listings' => array(
|
|
'name' => esc_html__( 'Your Listings', 'wp-job-openings' ),
|
|
'callback' => array( $this, 'your_listings_widget' ),
|
|
),
|
|
);
|
|
/**
|
|
* Filters the overview widgets.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param array $widgets Overview widgets.
|
|
*/
|
|
$widgets = apply_filters( 'awsm_jobs_overview_widgets', $widgets );
|
|
|
|
foreach ( $widgets as $widget_id => $widget_data ) {
|
|
$defaults = array(
|
|
'active' => true,
|
|
'name' => '',
|
|
'context' => 'normal',
|
|
'priority' => 'default',
|
|
);
|
|
$widget_data = wp_parse_args( $widget_data, $defaults );
|
|
if ( ! $widget_data['active'] ) {
|
|
continue;
|
|
}
|
|
|
|
$callback = '';
|
|
if ( isset( $widget_data['callback'] ) ) {
|
|
$callback = $widget_data['callback'];
|
|
} else {
|
|
$callback = function () use ( $widget_id ) {
|
|
include_once $this->get_widget_path( $widget_id );
|
|
};
|
|
}
|
|
add_meta_box( self::$menu_slug . '-' . $widget_id, $widget_data['name'], $callback, self::$screen_id, $widget_data['context'], $widget_data['priority'] );
|
|
}
|
|
}
|
|
|
|
public function applications_by_status_widget() {
|
|
/* translators: %1$s: opening anchor tag, %2$s: closing anchor tag */
|
|
$pro_link = sprintf( esc_html__( 'This feature requires %1$sPRO Plan%2$s to work', 'wp-job-openings' ), '<a href="https://awsm.in/get/wpjo-pro/">', '</a>' );
|
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
printf( '<div class="awsm-jobs-overview-widget-wrapper"><div class="awsm-jobs-pro-feature"><img src="%2$s"><p>%1$s</p></div></div>', $pro_link, esc_url( AWSM_JOBS_PLUGIN_URL . '/assets/img/applications-by-status-chart.png' ) );
|
|
}
|
|
|
|
public function open_positions_widget() {
|
|
$widget_id = 'open-positions';
|
|
$jobs = self::get_jobs(
|
|
array(
|
|
'numberjobs' => 10,
|
|
'job_status' => 'publish',
|
|
)
|
|
);
|
|
include $this->get_widget_path( 'job-listings', self::$menu_slug . '-' . $widget_id );
|
|
}
|
|
|
|
public function your_listings_widget() {
|
|
$widget_id = 'your-listings';
|
|
$jobs = self::get_jobs_by_author();
|
|
include $this->get_widget_path( 'job-listings', self::$menu_slug . '-' . $widget_id );
|
|
self::get_applications_analytics_data();
|
|
}
|
|
|
|
public static function get_jobs( $args ) {
|
|
global $wpdb;
|
|
$defaults = array(
|
|
'numberjobs' => -1,
|
|
'job_status' => array( 'publish', 'expired', 'future', 'draft', 'pending', 'private' ),
|
|
);
|
|
$parsed_args = wp_parse_args( $args, $defaults );
|
|
/**
|
|
* Filters the arguments to retrieve jobs in the overview section.
|
|
*
|
|
* @since 3.3.3
|
|
*
|
|
* @param array $parsed_args Arguments to retrieve jobs.
|
|
* @param array $defaults Overview jobs arguments.
|
|
*/
|
|
$parsed_args = apply_filters( 'awsm_overview_jobs_args', $parsed_args, $defaults );
|
|
|
|
$values = array();
|
|
$join = "LEFT JOIN {$wpdb->posts} AS applications ON {$wpdb->posts}.ID = applications.post_parent AND applications.post_type = 'awsm_job_application'";
|
|
$where = 'WHERE 1=1';
|
|
if ( isset( $parsed_args['tax_query'] ) && is_array( $parsed_args['tax_query'] ) ) {
|
|
$in = array();
|
|
$term_ids = array();
|
|
foreach ( $parsed_args['tax_query'] as $tax_terms ) {
|
|
foreach ( $tax_terms['terms'] as $term_id ) {
|
|
$in[] = '%d';
|
|
$term_ids[] = intval( $term_id );
|
|
}
|
|
}
|
|
$in = implode( ',', $in );
|
|
$term_tax_query = "SELECT t.term_id, tt.term_taxonomy_id, tt.taxonomy FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.term_id IN ({$in})";
|
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
$term_tax_results = $wpdb->get_results( $wpdb->prepare( $term_tax_query, $term_ids ), ARRAY_A );
|
|
if ( ! empty( $term_tax_results ) ) {
|
|
$taxonomies_ids = array();
|
|
foreach ( $term_tax_results as $term_tax_result ) {
|
|
$taxonomy = $term_tax_result['taxonomy'];
|
|
if ( ! isset( $taxonomies_ids[ $taxonomy ] ) ) {
|
|
$taxonomies_ids[ $taxonomy ] = array();
|
|
}
|
|
$taxonomies_ids[ $taxonomy ][] = $term_tax_result['term_taxonomy_id'];
|
|
}
|
|
|
|
$index = 1;
|
|
foreach ( $taxonomies_ids as $term_tax_ids ) {
|
|
$join .= " LEFT JOIN {$wpdb->term_relationships} AS tt{$index} ON ({$wpdb->posts}.ID = tt{$index}.object_id)";
|
|
$in = array();
|
|
foreach ( $term_tax_ids as $term_tax_id ) {
|
|
$in[] = '%d';
|
|
$values[] = intval( $term_tax_id );
|
|
}
|
|
$in = implode( ',', $in );
|
|
$where .= " AND tt{$index}.term_taxonomy_id IN({$in})";
|
|
$index++;
|
|
}
|
|
}
|
|
}
|
|
$where .= " AND {$wpdb->posts}.post_type = 'awsm_job_openings'";
|
|
// status.
|
|
if ( is_string( $parsed_args['job_status'] ) ) {
|
|
$where .= " AND {$wpdb->posts}.post_status = %s";
|
|
$values[] = sanitize_text_field( $parsed_args['job_status'] );
|
|
} elseif ( is_array( $parsed_args['job_status'] ) ) {
|
|
$status = array_map( 'sanitize_text_field', $parsed_args['job_status'] );
|
|
$status_placeholder = rtrim( str_repeat( "{$wpdb->posts}.post_status = %s OR ", count( $status ) ), ' OR ' );
|
|
$where .= " AND ({$status_placeholder})";
|
|
$values = array_merge( $values, $status );
|
|
}
|
|
// author.
|
|
if ( isset( $parsed_args['author_id'] ) ) {
|
|
$where .= " AND {$wpdb->posts}.post_author = %d";
|
|
$values[] = $parsed_args['author_id'];
|
|
}
|
|
// limit.
|
|
$limit = '';
|
|
if ( $parsed_args['numberjobs'] !== -1 ) {
|
|
$limit .= ' LIMIT %d';
|
|
$values[] = $parsed_args['numberjobs'];
|
|
}
|
|
|
|
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
|
$results = $wpdb->get_results( $wpdb->prepare( "SELECT {$wpdb->posts}.ID, COUNT(applications.ID) AS applications_count FROM {$wpdb->posts} {$join} {$where} GROUP BY {$wpdb->posts}.ID ORDER BY applications_count DESC, {$wpdb->posts}.ID{$limit}", $values ), OBJECT );
|
|
/**
|
|
* Filters the overview jobs result.
|
|
*
|
|
* @since 3.3.3
|
|
*
|
|
* @param array $results Overview jobs results.
|
|
* @param array $parsed_args Arguments to retrieve jobs.
|
|
*/
|
|
return apply_filters( 'awsm_overview_jobs', $results, $parsed_args );
|
|
}
|
|
|
|
public static function get_jobs_by_author( $numberjobs = 10 ) {
|
|
$args = array(
|
|
'numberjobs' => $numberjobs,
|
|
'author_id' => get_current_user_id(),
|
|
);
|
|
return self::get_jobs( $args );
|
|
}
|
|
|
|
public static function get_applications_analytics_data( $date_query = array(), $key_format = 'n', $label_format = 'M' ) {
|
|
$analytics_data = array();
|
|
if ( ! current_user_can( 'edit_applications' ) ) {
|
|
return $analytics_data;
|
|
}
|
|
|
|
if ( empty( $date_query ) ) {
|
|
$date_query = array(
|
|
array(
|
|
'year' => gmdate( 'Y' ),
|
|
),
|
|
);
|
|
}
|
|
$args = array(
|
|
'orderby' => 'date',
|
|
'order' => 'ASC',
|
|
'date_query' => $date_query,
|
|
);
|
|
$applications = AWSM_Job_Openings::get_all_applications( 'ids', $args );
|
|
if ( ! empty( $applications ) ) {
|
|
$data = array();
|
|
foreach ( $applications as $application_id ) {
|
|
$key = get_post_time( $key_format, false, $application_id );
|
|
$label = get_post_time( $label_format, false, $application_id, true );
|
|
$data[ $key ]['label'] = esc_html( $label );
|
|
$count = 1;
|
|
if ( isset( $data[ $key ]['count'] ) ) {
|
|
$count = $data[ $key ]['count'];
|
|
$count++;
|
|
}
|
|
$data[ $key ]['count'] = $count;
|
|
}
|
|
$analytics_data['labels'] = array_values( wp_list_pluck( $data, 'label' ) );
|
|
$analytics_data['data'] = array_values( wp_list_pluck( $data, 'count' ) );
|
|
}
|
|
return $analytics_data;
|
|
}
|
|
}
|