Skip to content

Commit 0d7a510

Browse files
committed
Avoid overriding classes when passing _atts attributes. Fixes #5
1 parent 44a6bd8 commit 0d7a510

File tree

1 file changed

+68
-9
lines changed

1 file changed

+68
-9
lines changed

src/WordPressMenuClasses.php

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ public function navSubmenuAttributes($atts, $args, $depth)
8585
* @return object Modified attributes for the current element
8686
*/
8787
public function buildAttributes($prefix, $atts, $args, $depth, $index = -1) {
88-
if (property_exists($args, "{$prefix}_atts")) {
89-
$atts = array_merge($atts, $args->{"{$prefix}_atts"});
88+
if ($this->hasAttribute($args, "{$prefix}_atts")) {
89+
$atts = $this->mergeAttributes($atts, $this->getAttribute($args, "{$prefix}_atts"));
9090
}
91-
if (property_exists($args, "{$prefix}_atts_{$depth}")) {
92-
$atts = array_merge($atts, $args->{"{$prefix}_atts_{$depth}"});
91+
if ($this->hasAttribute($args, "{$prefix}_atts_{$depth}")) {
92+
$atts = $this->mergeAttributes($atts, $this->getAttribute($args, "{$prefix}_atts_{$depth}"));
9393
}
94-
if ($index !== -1 && property_exists($args, "{$prefix}_atts_order_{$index}")) {
95-
$atts = array_merge($atts, $args->{"{$prefix}_atts_order_{$index}"});
94+
if ($index !== -1 && $this->hasAttribute($args, "{$prefix}_atts_order_{$index}")) {
95+
$atts = $this->mergeAttributes($atts, $this->getAttribute($args, "{$prefix}_atts_order_{$index}"));
9696
}
9797

9898
if (empty($atts['class'])) {
@@ -115,7 +115,7 @@ public function buildAttributes($prefix, $atts, $args, $depth, $index = -1) {
115115
* @return object Modified attributes for the current element
116116
*/
117117
public function buildClasses($prefix, $atts, $args, $depth, $index = -1) {
118-
$classes = explode(' ', $atts['class']);
118+
$classes = explode(' ', $this->getAttribute($atts, 'class'));
119119

120120
$classes = array_merge($classes, $this->arrayOrStringClasses("{$prefix}_class", $args));
121121
$classes = array_merge($classes, $this->arrayOrStringClasses("{$prefix}_class_$depth", $args));
@@ -140,8 +140,8 @@ public function buildClasses($prefix, $atts, $args, $depth, $index = -1) {
140140
*/
141141
public function arrayOrStringClasses($prop, $args) {
142142
$classes = [];
143-
if (property_exists($args, $prop)) {
144-
$temp_classes = $args->{$prop};
143+
if ($this->hasAttribute($args, $prop)) {
144+
$temp_classes = $this->getAttribute($args, $prop);
145145
if(is_string($temp_classes)) {
146146
$temp_classes = explode(' ', $temp_classes);
147147
}
@@ -151,6 +151,65 @@ public function arrayOrStringClasses($prop, $args) {
151151
return $classes;
152152
}
153153

154+
/**
155+
* Utility function to merge attributes with an exception on handling the classes to avoid overriding
156+
*
157+
* @param String $atts Original attributes
158+
* @param object $new_atts New attributes
159+
*
160+
* @return array Modified attributes array
161+
*/
162+
public function mergeAttributes($atts, $new_atts) {
163+
$new_classes = $this->arrayOrStringClasses('class', $new_atts);
164+
165+
if(!empty($new_classes)) {
166+
$original_classes = $this->arrayOrStringClasses('class', $atts);
167+
$new_classes = array_merge($original_classes, $new_classes);
168+
169+
// Applying this fix everywhere even though there's only
170+
// a user interface to add classes to links so far
171+
$classes = $this->fixWordPressClasses($new_classes);
172+
173+
$new_atts['class'] = implode(' ', $classes);
174+
}
175+
176+
$atts = array_merge($atts, $new_atts);
177+
178+
return $atts;
179+
}
180+
181+
/**
182+
* Checks if an attribute exists on a variable regardless of whether it's an object or array
183+
*
184+
* @param object|array $variable The variable to check (object or array)
185+
* @param string $attribute The attribute/key name to check for
186+
*
187+
* @return bool True if the attribute exists, false otherwise
188+
*/
189+
function hasAttribute($variable, $attribute) {
190+
return (is_object($variable) && property_exists($variable, $attribute)) ||
191+
(is_array($variable) && array_key_exists($attribute, $variable));
192+
}
193+
194+
/**
195+
* Gets an attribute from a variable regardless of whether it's an object or array
196+
*
197+
* @param object|array $variable The variable to get the attribute from (object or array)
198+
* @param string $attribute The attribute/key name to retrieve
199+
* @param mixed $default The default value to return if attribute doesn't exist
200+
*
201+
* @return mixed The value of the attribute or the default value if not found
202+
*/
203+
function getAttribute($variable, $attribute, $default = null) {
204+
if (is_object($variable)) {
205+
return property_exists($variable, $attribute) ? $variable->$attribute : $default;
206+
} elseif (is_array($variable)) {
207+
return array_key_exists($attribute, $variable) ? $variable[$attribute] : $default;
208+
}
209+
210+
return $default;
211+
}
212+
154213
/**
155214
* Fix for tailwindcss classes that include ":" (colon)
156215
* Enter triple underscore hover___text-primary instaed of hover:text-primary

0 commit comments

Comments
 (0)