Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/svg menu icon #4133

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 119 additions & 2 deletions header-footer-grid/Core/Components/MenuIcon.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace HFG\Core\Components;

use HFG\Core\Script_Register;
use HFG\Core\Settings\Manager as SettingsManager;
use HFG\Main;
use Neve\Core\Dynamic_Css;
Expand All @@ -34,6 +33,7 @@ class MenuIcon extends Abstract_Component {
const QUICK_LINKS_ID = 'quick-links';
const LABEL_MARGIN_ID = 'label_margin';
const MENU_ICON = 'menu_icon';
const SVG_MENU_ICON = 'svg_menu_icon';

/**
* Padding settings default values.
Expand Down Expand Up @@ -205,7 +205,7 @@ public function toggle_style() {
*/
private function get_menu_style( $menu_icon ) {
// We don't add any css for the default option.
if ( ! in_array( $menu_icon, [ 'arrow', 'donner', 'dots', 'minus', 'vortex', 'squeeze' ] ) ) {
if ( ! in_array( $menu_icon, [ 'arrow', 'donner', 'dots', 'minus', 'vortex', 'squeeze', 'svg' ] ) ) {
return '';
}

Expand Down Expand Up @@ -252,6 +252,17 @@ private function get_menu_style( $menu_icon ) {
}
CSS;

// SVG style
if ( $menu_icon === 'svg' ) {
$css .= <<<CSS
.hamburger-box.icon-svg {
width: 15px;
display:flex;
justify-content:center;
}
CSS;
}

// Arrow style
if ( $menu_icon === 'arrow' ) {
$css .= <<<CSS
Expand Down Expand Up @@ -538,6 +549,7 @@ public function add_settings() {
'minus' => 'Minus',
'vortex' => 'Vortex',
'squeeze' => 'Squeeze',
'svg' => __( 'Custom SVG', 'neve' ),
],
'default' => 'default',
],
Expand All @@ -547,6 +559,22 @@ public function add_settings() {
]
);

SettingsManager::get_instance()->add(
[
'id' => self::SVG_MENU_ICON,
'group' => $this->get_id(),
'tab' => SettingsManager::TAB_STYLE,
'transport' => 'refresh',
'sanitize_callback' => [ $this, 'sanitize_svg_input' ],
'label' => __( 'Custom SVG', 'neve' ),
'type' => 'textarea',
'section' => $this->section,
'options' => [
'active_callback' => [ $this, 'svg_menu_icon_active_callback' ],
],
]
);

$mod_key = self::BUTTON_APPEARANCE;
$default = [
'type' => 'outline',
Expand Down Expand Up @@ -681,4 +709,93 @@ public static function aria_expanded_behaviour( $only_click_attribute = false )
return ( $only_click_attribute ? '' : 'aria-expanded="false" ' ) . 'onclick="if(\'undefined\' !== typeof toggleAriaClick ) { toggleAriaClick() }"';
}

/**
* Callback to check if the menu icon is set to svg.
*
* @return bool
*/
public function svg_menu_icon_active_callback() {
return Mods::get( $this->get_id() . '_' . self::MENU_ICON, 'default' ) === 'svg';
}

/**
* Sanitize SVG input.
*
* @param string $content The input to sanitize.
*
* @return string
*/
public function sanitize_svg_input( $content ) {
// Remove comments
$content = preg_replace( '/<!--(.*)-->/Uis', '', $content );

// Load the SVG content into a DOMDocument
$dom = new \DOMDocument();
// phpcs:ignore
@$dom->loadXML( $content );

// List of allowed SVG elements
$allowed_tags = [
'svg',
'circle',
'ellipse',
'line',
'polygon',
'polyline',
'rect',
'path',
'g',
'defs',
'use',
'style',
'text',
'symbol',
'desc',
'title',
];

// List of allowed SVG attributes (again, expand as needed)
$allowed_attrs = [
'id',
'class',
'viewBox',
'width',
'height',
'fill',
'stroke',
'stroke-width',
'stroke-linecap',
'stroke-linejoin',
'd',
'transform',
'x',
'y',
'r',
'cx',
'cy',
];

// Remove disallowed elements
foreach ( $dom->getElementsByTagName( '*' ) as $node ) {
// phpcs:disable
if ( ! in_array( $node->tagName, $allowed_tags ) ) {
$node->parentNode->removeChild( $node );
// phpcs:enable
} else {
// For allowed elements, remove any disallowed attributes
for ( $i = $node->attributes->length - 1; $i >= 0; $i-- ) {
$attr_name = $node->attributes->item( $i )->name;

if ( ! in_array( $attr_name, $allowed_attrs ) ) {
$node->removeAttribute( $attr_name );
}
}
}
}

// Save the cleaned SVG content
$sanitized_svg = $dom->saveXML();

return $sanitized_svg;
}
}
18 changes: 15 additions & 3 deletions header-footer-grid/templates/components/component-menu-icon.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
$item_attributes = apply_filters( 'neve_nav_toggle_data_attrs', '' );
$label = component_setting( MenuIcon::TEXT_ID );
$menu_icon = component_setting( MenuIcon::MENU_ICON );

$menu_svg = component_setting( MenuIcon::SVG_MENU_ICON );
if ( $menu_icon === 'svg' && empty( $menu_svg ) ) {
$menu_icon = 'default';
}
$class = '';
if ( $menu_icon !== 'default' ) {
$class = apply_filters( 'neve_menu_icon_classes', 'hamburger ', $menu_icon );
Expand Down Expand Up @@ -43,8 +46,17 @@
<?php
} else {
?>
<span class="hamburger-box">
<span class="hamburger-inner"></span>
<span class="hamburger-box <?php echo esc_attr( 'icon-' . $menu_icon ); ?>">
<?php
if ( $menu_icon === 'svg' ) {
echo $menu_svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
?>
<span class="hamburger-inner"></span>
<?php
}
?>

</span>
<?php
}
Expand Down