From 3cf07574d01a52aa9d0e7e01c6fd97b6a8da187a Mon Sep 17 00:00:00 2001 From: Marco Antonio Vivas Date: Fri, 8 Aug 2025 22:20:16 -0300 Subject: [PATCH] Initial commit --- .gitattributes | 2 + README.md | 49 +++++++++++++ includes/functions.php | 115 +++++++++++++++++++++++++++++ style.css | 159 ++++++++++++++++++++++++++++++++++++++++ tres-coracoes-vagas.php | 86 ++++++++++++++++++++++ 5 files changed, 411 insertions(+) create mode 100644 .gitattributes create mode 100644 README.md create mode 100644 includes/functions.php create mode 100644 style.css create mode 100644 tres-coracoes-vagas.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/README.md b/README.md new file mode 100644 index 0000000..4c056d7 --- /dev/null +++ b/README.md @@ -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. \ No newline at end of file diff --git a/includes/functions.php b/includes/functions.php new file mode 100644 index 0000000..d6a3739 --- /dev/null +++ b/includes/functions.php @@ -0,0 +1,115 @@ +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 '

Nenhuma vaga encontrada no momento.

'; + } + + $output = '
+ + + + + + + + '; + + 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( + ' + + + + ', + esc_html($vaga['vaga']), + esc_html($vaga['cidade']), + esc_html($vaga['quantidade']) + ); + } + + $output .= '
VagaCidadeQuantidade
%s%s%s
'; + + return $output; +} +add_shortcode('tc_vagas', 'tc_show_vagas_shortcode'); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..2f42a6d --- /dev/null +++ b/style.css @@ -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; + } +} \ No newline at end of file diff --git a/tres-coracoes-vagas.php b/tres-coracoes-vagas.php new file mode 100644 index 0000000..8a9132f --- /dev/null +++ b/tres-coracoes-vagas.php @@ -0,0 +1,86 @@ +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 '

Nenhuma vaga encontrada no momento.

'; + } + + $output = '
'; + $output .= ''; + + 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( + ' + + + + ', + esc_html($vaga['vaga']), + esc_html($vaga['cidade']), + esc_html($vaga['quantidade']) + ); + } + + $output .= '
VagaCidadeQuantidade
%s%s%s
'; + + return $output; +} \ No newline at end of file