Initial commit

This commit is contained in:
2025-08-08 22:20:16 -03:00
commit 3cf07574d0
5 changed files with 411 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

49
README.md Normal file
View File

@@ -0,0 +1,49 @@
# Plugin Vagas Três Corações
Este plugin WordPress importa e exibe automaticamente as vagas de emprego publicadas no site da Prefeitura de Três Corações.
## Funcionalidades
- Busca automática das vagas diretamente do site oficial.
- Atualização automática das vagas apenas 4 vezes ao dia (00:00, 10:00, 18:00, 22:00), reduzindo requisições e otimizando performance.
- Exibição das vagas em uma tabela moderna, responsiva e ordenada alfabeticamente.
- Shortcode fácil de usar para inserir a tabela em qualquer página ou post.
## Instalação
1. Faça upload da pasta do plugin para o diretório `wp-content/plugins` do seu WordPress.
2. Ative o plugin no painel do WordPress.
## Como usar
Adicione o shortcode abaixo em qualquer página ou post onde deseja exibir as vagas:
```
[vagas_tres_coracoes]
```
## Personalização
- O plugin já inclui um CSS moderno e responsivo para a tabela de vagas.
- Para customizar o visual, edite o arquivo `style.css` dentro da pasta do plugin.
## Funcionamento do Cache
- As vagas são atualizadas automaticamente apenas nos horários: 00:00, 10:00, 18:00 e 22:00.
- Entre esses horários, o plugin utiliza cache para evitar múltiplas requisições ao site da Prefeitura.
## Estrutura dos Arquivos
- `tres-coracoes-vagas.php`: Arquivo principal do plugin.
- `includes/functions.php`: Funções de busca, cache e exibição das vagas.
- `style.css`: Estilos da tabela de vagas.
## Observações
- O plugin busca até 15 páginas de vagas por atualização.
- Linhas vazias ou vagas incompletas são automaticamente ignoradas na exibição.
- As vagas são ordenadas alfabeticamente pelo nome da vaga.
## Suporte
Para dúvidas ou sugestões, entre em contato com o desenvolvedor do plugin.

115
includes/functions.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
// Função para buscar vagas de todas as páginas
function tc_get_vagas() {
$base_url = 'https://trescoracoes.mg.gov.br/empregatrescoracoes/vagas?&pagina=';
$page = 1;
$vagas = array();
$max_pages = 15; // Limite de páginas para evitar loop infinito
while ($page <= $max_pages) {
$url = $base_url . $page;
$response = wp_remote_get($url);
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) != 200) {
break;
}
$body = wp_remote_retrieve_body($response);
$dom = new DOMDocument();
@$dom->loadHTML($body);
$xpath = new DOMXPath($dom);
// Encontrar a tabela de vagas
$rows = $xpath->query("//table[contains(@class, 'table')]/tbody/tr");
if ($rows->length === 0) {
break; // Não há mais vagas
}
foreach ($rows as $row) {
$cols = $row->getElementsByTagName('td');
if ($cols->length >= 3) {
$vaga = trim($cols[0]->textContent);
$cidade = trim($cols[1]->textContent);
$quantidade = trim($cols[2]->textContent);
// Ignora linhas totalmente vazias
if ($vaga !== '' || $cidade !== '' || $quantidade !== '') {
$vagas[] = array(
'vaga' => $vaga,
'cidade' => $cidade,
'quantidade' => $quantidade
);
}
}
}
$page++;
}
// Ordenar vagas por nome da vaga
usort($vagas, function($a, $b) {
return strcmp($a['vaga'], $b['vaga']);
});
return $vagas;
}
// Função para obter o próximo horário de atualização
function tc_get_next_update_time() {
$horarios = ['00:00', '10:00', '18:00', '22:00'];
$agora = current_time('H:i');
$hoje = current_time('Y-m-d');
foreach ($horarios as $hora) {
if ($agora < $hora) {
return strtotime("$hoje $hora:00");
}
}
// Se já passou de 22:00, retorna o próximo dia às 00:00
return strtotime("tomorrow 00:00:00");
}
// Shortcode para exibir as vagas
function tc_show_vagas_shortcode() {
$transient_key = 'tc_vagas_cache';
$vagas = get_transient($transient_key);
if ($vagas === false) {
$vagas = tc_get_vagas();
$next_update = tc_get_next_update_time();
$expira_em = $next_update - time();
if ($expira_em < 60) $expira_em = 60; // Garante pelo menos 1 min
set_transient($transient_key, $vagas, $expira_em);
}
if (empty($vagas)) {
return '<p>Nenhuma vaga encontrada no momento.</p>';
}
$output = '<div class="tc-vagas-wrapper"><table class="tc-vagas-table">
<thead>
<tr>
<th>Vaga</th>
<th>Cidade</th>
<th>Quantidade</th>
</tr>
</thead>
<tbody>';
foreach ($vagas as $vaga) {
// Ignora linhas totalmente vazias ou só com espaços
if (empty(trim($vaga['vaga'])) && empty(trim($vaga['cidade'])) && empty(trim($vaga['quantidade']))) continue;
$output .= sprintf(
'<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>',
esc_html($vaga['vaga']),
esc_html($vaga['cidade']),
esc_html($vaga['quantidade'])
);
}
$output .= '</tbody></table></div>';
return $output;
}
add_shortcode('tc_vagas', 'tc_show_vagas_shortcode');

159
style.css Normal file
View File

@@ -0,0 +1,159 @@
/* Estilos atualizados para a tabela de vagas */
.tc-vagas-wrapper {
max-width: 1000px;
margin: 40px auto;
background: var(--branco);
border-radius: var(--borda-radius);
box-shadow: var(--sombra);
padding: 30px;
border: 1px solid rgba(0, 0, 0, 0.05);
}
.tc-vagas-table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
margin: 0;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
font-size: 1.05em;
background: var(--branco);
border-radius: var(--borda-radius);
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
}
.tc-vagas-table th,
.tc-vagas-table td {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
padding: 15px 20px;
text-align: left;
transition: var(--transicao);
}
.tc-vagas-table th {
background: linear-gradient(135deg, var(--azul-principal) 0%, var(--azul-escuro) 100%);
color: var(--branco);
font-weight: 600;
letter-spacing: 0.3px;
text-transform: uppercase;
font-size: 0.9em;
border-top: none;
position: sticky;
top: 0;
z-index: 10;
}
.tc-vagas-table tr:nth-child(even) {
background-color: var(--cinza-claro);
}
.tc-vagas-table tr:hover {
background: rgba(0, 166, 251, 0.05);
}
.tc-vagas-table tr:hover td {
transform: translateX(4px);
}
.tc-vagas-table td {
color: var(--preto);
vertical-align: middle;
position: relative;
}
.tc-vagas-table td:first-child {
font-weight: 500;
color: var(--azul-escuro);
}
.tc-vagas-table td:last-child {
text-align: center;
font-weight: 600;
color: var(--azul-principal);
}
/* Efeito de destaque para a coluna de quantidade */
.tc-vagas-table td:last-child::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 60%;
background: var(--azul-brilhante);
border-radius: 3px;
opacity: 0;
transition: var(--transicao);
}
.tc-vagas-table tr:hover td:last-child::before {
opacity: 1;
}
/* Badge para vagas urgentes */
.vaga-urgente {
position: relative;
padding-left: 20px;
}
.vaga-urgente::before {
content: 'URGENTE';
position: absolute;
left: -5px;
top: 50%;
transform: translateY(-50%);
background: var(--vermelho);
color: white;
font-size: 0.7em;
font-weight: 700;
padding: 2px 8px;
border-radius: 10px;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 0.8; }
50% { opacity: 1; }
100% { opacity: 0.8; }
}
/* Responsividade */
@media (max-width: 768px) {
.tc-vagas-wrapper {
padding: 15px;
margin: 20px auto;
}
.tc-vagas-table th,
.tc-vagas-table td {
padding: 12px 10px;
font-size: 0.95em;
}
.tc-vagas-table td:first-child {
font-weight: 600;
}
}
@media (max-width: 480px) {
.tc-vagas-wrapper {
padding: 10px 5px;
}
.tc-vagas-table {
display: block;
overflow-x: auto;
white-space: nowrap;
}
.tc-vagas-table th {
font-size: 0.85em;
padding: 10px 8px;
}
.tc-vagas-table td {
padding: 10px 8px;
font-size: 0.9em;
}
}

86
tres-coracoes-vagas.php Normal file
View File

@@ -0,0 +1,86 @@
<?php
/**
* Plugin Name: Vagas Três Corações
* Description: Importa e exibe automaticamente as vagas do site da Prefeitura de Três Corações.
* Version: 1.0
* Author: Marco Antonio Vivas
*/
add_shortcode('vagas_tres_coracoes', 'vtc_exibir_vagas');
function vtc_enqueue_styles() {
wp_register_style('tc-vagas-style', plugin_dir_url(__FILE__) . 'style.css');
wp_enqueue_style('tc-vagas-style');
}
add_action('wp_enqueue_scripts', 'vtc_enqueue_styles');
function vtc_exibir_vagas() {
$todas_vagas = [];
for ($pagina = 1; $pagina <= 10; $pagina++) {
$html = wp_remote_get("https://trescoracoes.mg.gov.br/empregatrescoracoes/vagas?&pagina={$pagina}");
if (is_wp_error($html)) break;
$body = wp_remote_retrieve_body($html);
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($body);
libxml_clear_errors();
$xpath = new DOMXPath($dom);
$items = $xpath->query('//div[contains(@class, "home-painel__listagem-item")]');
if ($items->length === 0) break;
foreach ($items as $item) {
$vaga_node = $xpath->query('.//h2', $item);
$cidade_node = $xpath->query('.//div[contains(@class,"subtitulos")]/span[2]', $item);
$quantidade_node = $xpath->query('.//div[contains(@class,"descricao")]/span', $item);
$vaga = $vaga_node->length ? trim($vaga_node[0]->textContent) : '';
$cidade = $cidade_node->length ? trim($cidade_node[0]->textContent) : '';
$quantidade = $quantidade_node->length ? trim($quantidade_node[0]->textContent) : '';
// Verifica se a vaga não está vazia antes de adicionar
if (!empty($vaga) || !empty($cidade) || !empty($quantidade)) {
$todas_vagas[] = [
'vaga' => $vaga,
'cidade' => $cidade,
'quantidade' => $quantidade,
];
}
}
}
// Se não houver vagas, retorna mensagem
if (empty($todas_vagas)) {
return '<div class="tc-vagas-wrapper"><p>Nenhuma vaga encontrada no momento.</p></div>';
}
$output = '<div class="tc-vagas-wrapper"><table class="tc-vagas-table">';
$output .= '<thead><tr><th>Vaga</th><th>Cidade</th><th>Quantidade</th></tr></thead><tbody>';
foreach ($todas_vagas as $vaga) {
// Ignora linhas totalmente vazias (segunda verificação por segurança)
if (empty(trim($vaga['vaga'])) && empty(trim($vaga['cidade'])) && empty(trim($vaga['quantidade']))) {
continue;
}
$output .= sprintf(
'<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>',
esc_html($vaga['vaga']),
esc_html($vaga['cidade']),
esc_html($vaga['quantidade'])
);
}
$output .= '</tbody></table></div>';
return $output;
}