array( 'success', esc_html__( 'Configurações de licença salvas.', 'portus-header' ) ),
'license_activated' => array( 'success', esc_html__( 'Licença ativa para este domínio.', 'portus-header' ) ),
'license_deactivated' => array( 'success', esc_html__( 'Licença desativada neste domínio.', 'portus-header' ) ),
'license_checked' => array( 'success', esc_html__( 'Consulta de atualização concluída.', 'portus-header' ) ),
'license_failed' => array( 'error', esc_html__( 'Não foi possível validar a licença no servidor Portus.', 'portus-header' ) ),
'license_missing' => array( 'warning', esc_html__( 'Informe a chave de licença antes de ativar ou verificar atualizações.', 'portus-header' ) ),
);
if ( empty( $messages[ $message_key ] ) ) {
return;
}
list( $type, $message ) = $messages[ $message_key ];
?>
'array',
'sanitize_callback' => array( 'Portus_Header_Settings', 'sanitize' ),
'default' => Portus_Header_Settings::defaults(),
)
);
}
/**
* Adiciona a página em Aparência.
*/
public function add_page() {
add_theme_page(
esc_html__( 'Portus Header', 'portus-header' ),
esc_html__( 'Portus Header', 'portus-header' ),
'manage_options',
'portus-header',
array( $this, 'render_page' )
);
}
/**
* Carrega somente os assets do painel do plugin.
*
* @param string $hook_suffix Identificador da tela.
*/
public function enqueue_assets( $hook_suffix ) {
if ( 'appearance_page_portus-header' !== $hook_suffix ) {
return;
}
wp_enqueue_media();
wp_enqueue_style(
'portus-header-admin',
PORTUS_HEADER_URL . 'assets/css/portus-header-admin.css',
array(),
PORTUS_HEADER_VERSION
);
wp_enqueue_script(
'portus-header-admin',
PORTUS_HEADER_URL . 'assets/js/portus-header-admin.js',
array( 'media-editor' ),
PORTUS_HEADER_VERSION,
true
);
wp_localize_script(
'portus-header-admin',
'PortusHeaderAdmin',
array(
'defaults' => Portus_Header_Settings::defaults(),
'presets' => $this->get_visual_presets(),
'i18n' => array(
'mediaTitle' => esc_html__( 'Selecionar logo', 'portus-header' ),
'mediaButton' => esc_html__( 'Usar esta imagem', 'portus-header' ),
'restoreColors' => esc_html__( 'Restaurar somente as cores oficiais da Portus?', 'portus-header' ),
'restoreSizes' => esc_html__( 'Restaurar somente medidas, fontes e espaçamentos oficiais da Portus?', 'portus-header' ),
'restoreVisual' => esc_html__( 'Restaurar todo o visual oficial da Portus?', 'portus-header' ),
'preset' => esc_html__( 'Aplicar este preset visual? Revise o preview e clique em Salvar configurações para publicar.', 'portus-header' ),
'importError' => esc_html__( 'O arquivo não contém configurações válidas do Portus Header.', 'portus-header' ),
'importDone' => esc_html__( 'Configurações importadas. Revise e clique em Salvar configurações.', 'portus-header' ),
),
)
);
}
/**
* Adiciona atalho na lista de plugins.
*
* @param array $links Links atuais.
* @return array
*/
public function add_settings_link( $links ) {
array_unshift(
$links,
'' . esc_html__( 'Configurações', 'portus-header' ) . ''
);
return $links;
}
/**
* Presets visuais aplicados no painel antes de salvar.
*
* @return array>
*/
private function get_visual_presets() {
return array(
'portus' => array(
'label' => esc_html__( 'Portus padrão', 'portus-header' ),
'description' => esc_html__( 'Identidade oficial: azul Portus, dourado no CTA e dimensões equilibradas.', 'portus-header' ),
'settings' => array(
'layout_preset' => 'standard',
'color_header_bg' => '#00053A',
'color_text' => '#FFFFFF',
'color_hover' => '#C0A821',
'color_cta_bg' => '#C0A821',
'color_cta_text' => '#00053A',
'color_cta_hover_bg' => '#D3C45A',
'desktop_height' => 82,
'mobile_height' => 72,
'menu_gap' => 30,
'cta_radius' => 6,
'desktop_menu_font_size' => 15,
'desktop_menu_font_weight' => 600,
'header_action_gap' => 10,
),
),
'compact' => array(
'label' => esc_html__( 'Compacto', 'portus-header' ),
'description' => esc_html__( 'Header mais baixo e denso para lojas com muitos links.', 'portus-header' ),
'settings' => array(
'layout_preset' => 'compact',
'desktop_height' => 68,
'mobile_height' => 64,
'desktop_logo_width' => 180,
'desktop_logo_height' => 44,
'mobile_logo_width' => 150,
'mobile_logo_height' => 40,
'menu_gap' => 20,
'cta_radius' => 6,
'desktop_menu_font_size' => 14,
'cta_font_size' => 14,
'header_action_gap' => 6,
'search_icon_size' => 22,
'account_icon_size' => 21,
'cart_icon_size' => 22,
),
),
'centered' => array(
'label' => esc_html__( 'Centralizado', 'portus-header' ),
'description' => esc_html__( 'Logo à esquerda, menu perfeitamente central e ações alinhadas à direita.', 'portus-header' ),
'settings' => array(
'layout_preset' => 'centered',
'desktop_height' => 86,
'container_max_width' => 1280,
'menu_gap' => 34,
'desktop_menu_font_size' => 15,
'desktop_menu_font_weight' => 700,
'header_action_gap' => 12,
'mega_menu_width' => 1160,
),
),
'cta' => array(
'label' => esc_html__( 'CTA forte', 'portus-header' ),
'description' => esc_html__( 'Mais destaque comercial para o botão principal e ações do topo.', 'portus-header' ),
'settings' => array(
'layout_preset' => 'cta',
'cta_enabled' => 1,
'color_cta_bg' => '#C0A821',
'color_cta_text' => '#00053A',
'color_cta_hover_bg' => '#FFFFFF',
'color_cta_hover_text'=> '#00053A',
'desktop_height' => 84,
'cta_radius' => 12,
'cta_font_size' => 16,
'header_action_gap' => 14,
'menu_gap' => 28,
),
),
);
}
/**
* Renderiza o painel.
*/
public function render_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$settings = Portus_Header_Settings::get_all();
$option = Portus_Header_Settings::OPTION_NAME;
$presets = $this->get_visual_presets();
$is_pro = $this->is_pro_edition();
$pro_tabs = $is_pro && class_exists( 'Portus_Header_Pro_Admin' ) ? Portus_Header_Pro_Admin::tabs() : array();
$preview_logo_id = ! empty( $settings['desktop_logo_id'] ) ? absint( $settings['desktop_logo_id'] ) : 0;
$preview_logo_id = ! $preview_logo_id && ! empty( $settings['mobile_logo_id'] ) ? absint( $settings['mobile_logo_id'] ) : $preview_logo_id;
$preview_logo_id = ! $preview_logo_id ? absint( get_theme_mod( 'custom_logo' ) ) : $preview_logo_id;
$preview_logo_url = $preview_logo_id ? wp_get_attachment_image_url( $preview_logo_id, 'medium' ) : '';
update_option( 'portus_header_onboarding_pending', 0, false );
?>
$settings Configurações.
* @param string $option Nome da opção.
*/
private function render_media_field( $key, $label, $settings, $option ) {
$id = absint( $settings[ $key ] );
$url = $id ? wp_get_attachment_image_url( $id, 'medium' ) : '';
?>
$settings Configurações.
* @param string $option Nome da opção.
*/
public function render_color_field( $key, $label, $settings, $option ) {
?>
$settings Configurações.
* @param string $option Nome da opção.
*/
public function render_number_field( $key, $label, $min, $max, $settings, $option, $unit = 'px' ) {
?>
get( 'Version' ) );
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return (bool) $cached;
}
$directories = array_unique( array( get_stylesheet_directory(), get_template_directory() ) );
$found = false;
foreach ( $directories as $directory ) {
if ( $this->directory_contains_body_open( $directory ) ) {
$found = true;
break;
}
}
set_transient( $cache_key, $found ? 1 : 0, 12 * HOUR_IN_SECONDS );
return $found;
}
/**
* Faz uma varredura limitada nos PHPs do tema.
*
* @param string $directory Diretório do tema.
* @return bool
*/
private function directory_contains_body_open( $directory ) {
if ( ! is_dir( $directory ) || ! is_readable( $directory ) ) {
return false;
}
$checked = 0;
try {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $directory, FilesystemIterator::SKIP_DOTS )
);
foreach ( $iterator as $file ) {
if ( $checked >= 500 ) {
break;
}
if ( ! $file->isFile() || 'php' !== strtolower( $file->getExtension() ) ) {
continue;
}
$path = $file->getPathname();
if ( preg_match( '#[\\\\/](vendor|node_modules|\.git)[\\\\/]#i', $path ) || $file->getSize() > 1048576 || ! is_readable( $path ) ) {
continue;
}
++$checked;
$content = file_get_contents( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
if ( is_string( $content ) && preg_match( '/(?:\\bwp_body_open\\s*\\(|do_action\\s*\\(\\s*[\'\"]wp_body_open[\'\"])/', $content ) ) {
return true;
}
}
} catch ( Exception $exception ) {
return false;
}
return false;
}
/**
* Informa se o painel deve exibir recursos Pro.
*
* @return bool
*/
private function is_pro_edition() {
return ! class_exists( 'Portus_Header_Edition_Manager' ) || Portus_Header_Edition_Manager::is_pro();
}
}