Переписать класс Woocommerce
Всем привет! Вопрос полагаю не тривиальный) Есть метод в классе WC_Product_Cat_List_Walker, выглядит он так
class WC_Product_Cat_List_Walker extends Walker {
public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) {
$cat_id = intval( $cat->term_id );
$output .= '<li class="cat-item test cat-item-' . $cat_id;
if ( $args['current_category'] === $cat_id ) {
$output .= ' current-cat';
}
if ( $args['has_children'] && $args['hierarchical'] && ( empty( $args['max_depth'] ) || $args['max_depth'] > $depth + 1 ) ) {
$output .= ' cat-parent';
}
if ( $args['current_category_ancestors'] && $args['current_category'] && in_array( $cat_id, $args['current_category_ancestors'], true ) ) {
$output .= ' current-cat-parent';
}
$output .= '"><a href="' . get_term_link( $cat_id, $this->tree_type ) . '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '</a>';
if ( $args['show_count'] ) {
$output .= ' <span class="count">(' . $cat->count . ')</span>';
}
}
}
я хочу переписать этот класс, но не могу понять как это сделать не в папке плагина, а внутри моего файла function, пробовал расширить класс такого плана
class My_class extends WC_Product_Cat_List_Walker {
public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) {
$cat_id = intval( $cat->term_id );
$output .= '<li class="cat-item test cat-item-' . $cat_id;
if ( $args['current_category'] === $cat_id ) {
$output .= ' current-cat';
}
if ( $args['has_children'] && $args['hierarchical'] && ( empty( $args['max_depth'] ) || $args['max_depth'] > $depth + 1 ) ) {
$output .= ' cat-parent';
}
if ( $args['current_category_ancestors'] && $args['current_category'] && in_array( $cat_id, $args['current_category_ancestors'], true ) ) {
$output .= ' current-cat-parent';
}
$output .= '"><a href="' . get_term_link( $cat_id, $this->tree_type ) . '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '</a>';
if ( $args['show_count'] ) {
$output .= ' <span class="count">(' . $cat->count . ')</span>';
}
}
}
, но сайт отваливается, можете ткнуть носом, куда смотреть? Заранее спасибо!
PS Объясню, что я вообще хочу сделать) Мне надо в меню вывести описание категории, меню я вывожу в сайдаре, используя виджет Категории товаров
При копировании класса к себе в файл function, я переношу следующий код
class WC_Product_Cat_List_Walker extends Walker {
/**
* What the class handles.
*
* @var string
*/
public $tree_type = 'product_cat';
/**
* DB fields to use.
*
* @var array
*/
public $db_fields = array(
'parent' => 'parent',
'id' => 'term_id',
'slug' => 'slug',
);
/**
* Starts the list before the elements are added.
*
* @see Walker::start_lvl()
* @since 2.1.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param int $depth Depth of category. Used for tab indentation.
* @param array $args Will only append content if style argument value is 'list'.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
if ( 'list' !== $args['style'] ) {
return;
}
$indent = str_repeat( "\t", $depth );
$output .= "$indent<ul class='children'>\n";
}
/**
* Ends the list of after the elements are added.
*
* @see Walker::end_lvl()
* @since 2.1.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param int $depth Depth of category. Used for tab indentation.
* @param array $args Will only append content if style argument value is 'list'.
*/
public function end_lvl( &$output, $depth = 0, $args = array() ) {
if ( 'list' !== $args['style'] ) {
return;
}
$indent = str_repeat( "\t", $depth );
$output .= "$indent</ul>\n";
}
/**
* Start the element output.
*
* @see Walker::start_el()
* @since 2.1.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $cat Category.
* @param int $depth Depth of category in reference to parents.
* @param array $args Arguments.
* @param integer $current_object_id Current object ID.
*/
public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) {
$cat_id = intval( $cat->term_id );
$output .= '<li class="cat-item cat-item-' . $cat_id;
if ( $args['current_category'] === $cat_id ) {
$output .= ' current-cat';
}
if ( $args['has_children'] && $args['hierarchical'] && ( empty( $args['max_depth'] ) || $args['max_depth'] > $depth + 1 ) ) {
$output .= ' cat-parent';
}
if ( $args['current_category_ancestors'] && $args['current_category'] && in_array( $cat_id, $args['current_category_ancestors'], true ) ) {
$output .= ' current-cat-parent';
}
$output .= '"><a href="' . get_term_link( $cat_id, $this->tree_type ) . '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '</a>';
if ( $args['show_count'] ) {
$output .= ' <span class="count">(' . $cat->count . ')</span>';
}
}
/**
* Ends the element output, if needed.
*
* @see Walker::end_el()
* @since 2.1.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $cat Category.
* @param int $depth Depth of category. Not used.
* @param array $args Only uses 'list' for whether should append to output.
*/
public function end_el( &$output, $cat, $depth = 0, $args = array() ) {
$output .= "</li>\n";
}
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn't have any children otherwise,
* display the element and its children. Will only traverse up to the max.
* depth and no ignore elements under that depth. It is possible to set the.
* max depth to include all depths, see walk() method.
*
* This method shouldn't be called directly, use the walk() method instead.
*
* @since 2.5.0
*
* @param object $element Data object.
* @param array $children_elements List of elements to continue traversing.
* @param int $max_depth Max depth to traverse.
* @param int $depth Depth of current element.
* @param array $args Arguments.
* @param string $output Passed by reference. Used to append additional content.
* @return null Null on failure with no changes to parameters.
*/
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element || ( 0 === $element->count && ! empty( $args[0]['hide_empty'] ) ) ) {
return;
}
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
}
UPD Ошибка после добавления в папку mu-plugins
Fatal error: Uncaught Error: Class 'WC_Product_Cat_List_Walker' not found in /home/c/cowboy/bestguys.ru/public_html/wp-content/mu-plugins/my-wc-walker.php:3 Stack trace: #0 /home/c/cowboy/bestguys.ru/public_html/wp-settings.php(340): include_once() #1 /home/c/cowboy/bestguys.ru/public_html/wp-config.php(95): require_once('/home/c/cowboy/...') #2 /home/c/cowboy/bestguys.ru/public_html/wp-load.php(50): require_once('/home/c/cowboy/...') #3 /home/c/cowboy/bestguys.ru/public_html/wp-blog-header.php(13): require_once('/home/c/cowboy/...') #4 /home/c/cowboy/bestguys.ru/public_html/index.php(17): require('/home/c/cowboy/...') #5 {main} thrown in /home/c/cowboy/bestguys.ru/public_html/wp-content/mu-plugins/my-wc-walker.php on line 3
Создайте файл с любым именем, например, my-wc-walker.php в папке wp-content/mu-plugins. Если такой папки нет, создаёте её. Вставьте код класса WC_Product_Cat_List_Walker в этот файл (добавив первую строчку <?php).
В итоге я добавил файлы как вы рекомендовали, но на странице все равно вылетала ошибка
Fatal error: Cannot declare class WC_Product_Cat_List_Walker, because the name is already in use in /home/c/cowboy/bestguys.ru/public_html/wp-content/plugins/woocommerce/includes/walkers/class-wc-product-cat-list-walker.php on line 0
То есть после уже моего класса, проверка шла дальше и ругалась уже на класс плагина, сейчас я добавил в начале ту же проверку, что была у начального класса только с одним изменением, я заменил false на true, подскажите, это верное решение ?
if ( class_exists( 'WC_Product_Cat_List_Walker', true ) ) {
return;}
Ответы (1 шт):
К счастью, файл класса содержит конструкцию
if ( class_exists( 'WC_Product_Cat_List_Walker', false ) ) {
return;
}
Это означает, что его можно объявить в своём коде. Скопируйте код класса прямо с тем же самым именем WC_Product_Cat_List_Walker в functions.php и исправьте так, как вам нужно.
Update
В связи с противоречащими друг другу ошибками, которые приведены ниже в комментариях, предлагаю более радикальный сценарий.
Создайте файл с любым именем, например, my-wc-walker.php в папке wp-content/mu-plugins. Если такой папки нет, создаёте её. Вставьте код класса WC_Product_Cat_List_Walker в этот файл (добавив первую строчку <?php).
MU-плагины (must use plugins) грузятся всегда раньше любых обычных плагинов. Таким образом, ваша версия класса будет загружен однозначно раньше WC и не будет фатальной ошибки Cannot declare class WC_Product_Cat_List_Walker, because the name is already in use in.