<?php
/**
 * Plugin Name: LawFuel Job Importer
 * Description: Fetches law jobs from jobs.lawfuel.com, imports as custom posts with 80-word excerpts, and provides shortcode to display featured and recent listings.
 * Version: 1.0
 * Author: LawFuel
 */

if ( ! defined( 'ABSPATH' ) ) exit;

// Register custom post type for Job Listings
function lf_register_job_cpt() {
    register_post_type( 'lawfuel_job', array(
        'labels' => array(
            'name' => 'Job Listings',
            'singular_name' => 'Job Listing',
        ),
        'public' => true,
        'has_archive' => false,
        'show_in_menu' => true,
        'supports' => array('title','editor','excerpt','custom-fields'),
    ));
}
add_action('init','lf_register_job_cpt');

// Schedule daily cron event
function lf_schedule_job_fetch() {
    if ( ! wp_next_scheduled( 'lf_fetch_jobs_daily' ) ) {
        wp_schedule_event( time(), 'daily', 'lf_fetch_jobs_daily' );
    }
}
add_action('wp', 'lf_schedule_job_fetch');

// Hook into cron
add_action('lf_fetch_jobs_daily','lf_fetch_and_import_jobs');

// Fetch and import jobs
function lf_fetch_and_import_jobs() {
    // Fetch HTML from jobs.lawfuel.com
    $response = wp_remote_get('https://www.jobs.lawfuel.com');
    if ( is_wp_error( $response ) ) return;
    $html = wp_remote_retrieve_body( $response );

    libxml_use_internal_errors(true);
    $doc = new DOMDocument();
    $doc->loadHTML($html);
    libxml_clear_errors();

    $xpath = new DOMXPath($doc);
    // Adjust selector to match actual job listing elements
    $nodes = $xpath->query("//div[contains(@class,'job-listing')]");

    foreach ( $nodes as $node ) {
        // Title
        $titleNode = $xpath->query(".//h2/a", $node);
        if ( ! $titleNode->length ) continue;
        $title = trim($titleNode->item(0)->textContent);
        $link  = $titleNode->item(0)->getAttribute('href');

        // Full description from job detail page
        $detail = lf_fetch_job_detail($link);
        $excerpt = lf_trim_words( wp_strip_all_tags($detail), 80 );

        // Date posted
        $dateNode = $xpath->query(".//time", $node);
        $post_date = $dateNode->length ? date('Y-m-d', strtotime($dateNode->item(0)->getAttribute('datetime'))) : current_time('Y-m-d');

        // Featured flag (e.g. class 'featured')
        $is_featured = strpos($node->getAttribute('class'), 'featured') !== false;

        // Upsert post
        $existing = get_posts(array(
            'post_type'=>'lawfuel_job',
            'meta_key'=>'source_url',
            'meta_value'=>$link,
            'fields'=>'ids',
        ));

        $post_data = array(
            'post_title'   => $title,
            'post_type'    => 'lawfuel_job',
            'post_date'    => $post_date,
            'post_status'  => 'publish',
            'post_excerpt' => $excerpt,
        );

        if ( $existing ) {
            $post_data['ID'] = $existing[0];
            wp_update_post( $post_data );
            $post_id = $existing[0];
        } else {
            $post_id = wp_insert_post( $post_data );
        }

        if ( $post_id && ! is_wp_error($post_id) ) {
            update_post_meta( $post_id, 'source_url', esc_url_raw($link) );
            update_post_meta( $post_id, 'is_featured', $is_featured ? '1' : '0' );
        }
    }
}

// Helper: Fetch full job detail HTML/text
function lf_fetch_job_detail($url) {
    $response = wp_remote_get($url);
    if ( is_wp_error($response) ) return '';
    $body = wp_remote_retrieve_body($response);
    libxml_use_internal_errors(true);
    $doc = new DOMDocument();
    $doc->loadHTML($body);
    libxml_clear_errors();
    $xpath = new DOMXPath($doc);
    // Adjust selector for job description
    $descNode = $xpath->query("//div[contains(@class,'job-description')]");
    return $descNode->length ? $xpath->query('.//text()', $descNode->item(0))->item(0)->textContent : '';
}

// Helper: Trim to word count
function lf_trim_words($text, $limit=80) {
    $words = preg_split('/\s+/', $text);
    if ( count($words) <= $limit ) {
        return implode(' ', $words);
    }
    return implode(' ', array_slice($words,0,$limit)) . '...';
}

// Shortcode to display jobs
function lf_jobs_shortcode( $atts ) {
    $atts = shortcode_atts(array('days'=>60,'featured'=>'true'), $atts, 'lawfuel_jobs');

    $date_threshold = date('Y-m-d', strtotime("-{$atts['days']} days"));

    // Featured jobs
    $html = '<h2>Featured Jobs</h2><ul>';
    $featured = new WP_Query(array(
        'post_type'=>'lawfuel_job',
        'meta_key'=>'is_featured',
        'meta_value'=>'1',
        'date_query'=>array(array('after'=>$date_threshold)),
        'posts_per_page'=>5,
    ));
    while($featured->have_posts()) {
        $featured->the_post();
        $html .= '<li><strong><a href="'.esc_url(get_post_meta(get_the_ID(),'source_url',true)).'">'.get_the_title().'</a></strong></li>';
    }
    wp_reset_postdata();
    $html .= '</ul>';

    // Recent jobs
    $html .= '<h2>Recent Jobs</h2><ul>';
    $recent = new WP_Query(array(
        'post_type'=>'lawfuel_job',
        'date_query'=>array(array('after'=>$date_threshold)),
        'meta_key'=>'is_featured',
        'meta_value'=>'0',
        'posts_per_page'=>20,
    ));
    while($recent->have_posts()) {
        $recent->the_post();
        $html .= '<li><a href="'.esc_url(get_post_meta(get_the_ID(),'source_url',true)).'">'.get_the_title().'</a> &ndash; '.get_the_excerpt().'</li>';
    }
    wp_reset_postdata();
    $html .= '</ul>';

    return $html;
}
add_shortcode('lawfuel_jobs','lf_jobs_shortcode');

?>

Leave a Comment