PHP WordPress Code - Pricelist Template
I've been working on a WordPress pricing page template and would appreciate feedback on the code structure, organization, and any potential improvements. The template is used to display a pricing list with categories and items.
How can we reduce this whole amount of nestiness and code? UPDATE CODE WITH MORE LOGIC FROM PHP
<?php
get_header();
get_template_part( 'template-parts/components/hero-subpage' );
$cennik_kat_order = get_field( 'cennik_kat', 'option' );
if ( ! is_array( $cennik_kat_order ) ) {
$cennik_kat_order = [];
}
$sorted_cennik_categories = get_sorted_pricelist_categories( $cennik_kat_order );
$mediraty = get_field( 'mediraty', 'option' );
?>
<section class="prl c d-grid l-d">
<div class="prl--s">
Informujemy Państwa, że w klinice Wilmed istnieje możliwość płacenia za usługi medyczne w systemie ratalnym MediRaty.
<?php
$image = new MiLossy( $mediraty );
$image->Draw();
?>
</div>
<h3 class="prl__heading h3 f-400 c-black-800 m-reset">Cennik zabiegów</h3>
<div class="prl__cats hm d-flex f-c">
<?php
foreach ( $sorted_cennik_categories as $key => $category ) :
?>
<div class="details prl__cat hm__item--wr br" id="<?= $category->slug; ?>">
<summary class="hm__title--main p d-flex f-c ais jcb cp w-100 zero-level-hierarchy">
<span class="c-black-800 h5 f-400 m-0"><?= $category->name; ?>
<?php if ( DEBUG ) : ?>
<a style="font-size: 1em;" tabindex="-1" href="<?= get_edit_term_link( $category->term_id, 'cennik_kat' ); ?>">(Edytuj)</a>
<?php endif; ?></span>
<div class="prl__cat-btn d-flex aic jce">
<span class="toggle-text level-zero">Rozwiń</span>
<div class="hm__icon-wr d-flex aic jcc br">
<svg class="hm__icon" width="16" height="16" viewBox="0 0 16 16">
<use xlink:href="#arrow-down"></use>
</svg>
</div>
</div>
</summary>
<div class="content-wrapper prl__hm--wrapper w-100">
<div class="content-inner prl__hm--inner">
<div class="real-content prl__gap d-flex f-c">
<?php
$term_posts_order_ids = get_field( 'cennik_order_' . $category->slug, 'option' );
$query = new WP_Query(
[
'post_type' => 'cennik',
'posts_per_page' => -1,
'post_parent' => 0,
'tax_query' => [
[
'taxonomy' => 'cennik_kat',
'field' => 'term_id',
'terms' => $category->term_id,
'include_children' => true,
'operator' => 'IN',
],
],
'orderby' => 'title',
'order' => 'ASC',
]
);
if ( is_array( $term_posts_order_ids ) && ! empty( $term_posts_order_ids ) ) {
$query->posts = sort_objects_by_id_order( $query->posts, $term_posts_order_ids );
}
if ( $query->have_posts() ) :
while ( $query->have_posts() ) :
$query->the_post();
$is_pakiet = has_term( get_pakiet_term_id(), 'cennik_kat', $post->ID );
$maybe_children = get_pages( [ 'child_of' => $post->ID, 'post_type' => 'cennik' ] );
$has_children = ! empty( $maybe_children );
$is_pakiet = $has_children && $is_pakiet;
$is_group = $has_children && ! $is_pakiet;
$is_single = ! $has_children && ! $is_pakiet;
?>
<?php if ( $is_group ) : ?>
<div class="details prl__item prl__gap prl__item--gr d-flex f-c w-100">
<summary class="hm__title p d-flex f-c ais jcb cp w-100 first-level-hierarchy">
<span class="c-black-800 h5 f-400 m-0"><?= $post->post_title; ?>
<?php if ( DEBUG ) : ?>
<a style="font-size: 1em;" tabindex="-1" href="<?= get_edit_post_link( $post->ID ); ?>">(Edytuj)</a>
<?php endif; ?>
</span>
<div class="prl__cat-btn d-flex aic jce">
<span class="toggle-text level-one">Rozwiń</span>
<div class="hm__icon-wr d-flex aic jcc br">
<svg class="hm__icon" width="16" height="16" viewBox="0 0 16 16">
<use xlink:href="#arrow-down"></use>
</svg>
</div>
</div>
</summary>
<div class="content-wrapper prl__hm--wrapper">
<div class="content-inner prl__hm--inner">
<div class="real-content prl__items-gr prl__gap--small d-flex f-c">
<div class="prl__hr w-100"></div>
<?php
if ( $has_children ) {
$children = $maybe_children;
$children_order_ids = get_field( 'children_order', $post->ID );
$maybe_children = get_pages( [ 'child_of' => $post->ID, 'post_type' => 'cennik' ] );
$has_children = ! empty( $maybe_children );
$grandchildrens = [];
if ( is_array( $children_order_ids ) && ! empty( $children_order_ids ) ) {
$children = sort_objects_by_id_order( $children, $children_order_ids );
}
foreach ( $children as $key => $page ) {
$is_group = has_term( get_pakiet_term_id(), 'cennik_kat', $page->ID );
$group_children = get_pages( [ 'child_of' => $page->ID, 'post_type' => 'cennik' ] );
if ( $is_group ) {
?>
<div class="details details--last prl__item prl__gap prl__item--gr d-flex f-c w-100">
<summary class="hm__title p d-flex f-c ais jcb cp w-100">
<span class="c-black-800 h6 f-500 m-0 l-3"><?= $page->post_title; ?>
<?php if ( DEBUG ) : ?>
<a style="font-size: 1em;" tabindex="-1" href="<?= get_edit_post_link( $page->ID ); ?>">(Edytuj)</a>
<?php endif; ?>
</span>
<div class="prl__cat-btn d-flex aic jce">
<span class="toggle-text level-one">Rozwiń</span>
<div class="hm__icon-wr d-flex aic jcc br">
<svg class="hm__icon" width="16" height="16" viewBox="0 0 16 16">
<use xlink:href="#arrow-down"></use>
</svg>
</div>
</div>
</summary>
<div class="content-wrapper prl__hm--wrapper w-100">
<div class="content-inner prl__hm--inner">
<div class="real-content prl__gap d-flex f-c">
<div class="prl__hr w-100"></div>
<?php
foreach ( $group_children as $grandchild ) {
$displayed_grandchildren[] = $grandchild->ID;
print_pricelist_item( $grandchild->ID, true );
}
?>
</div>
</div>
</div>
</div>
<?php
}
}
foreach ( $children as $page ) {
$is_group = has_term( get_pakiet_term_id(), 'cennik_kat', $page->ID );
if ( ! $is_group && ! in_array( $page->ID, $displayed_grandchildren ) ) {
print_pricelist_item( $page->ID, false );
}
}
}
?>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if ( $is_single ) : ?>
<div class="real-content prl__item prl__gap d-flex f-c w-100">
<?php print_pricelist_item( $post->ID ); ?>
</div>
<?php endif; ?>
<?php
endwhile;
wp_reset_postdata();
endif;
?>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<?php try_attach_resource( 'js/priceListOpening.min.js' ); ?>
<?php
get_footer();
?>
function get_sorted_pricelist_categories( array $ordered_terms_id, bool $hide_empty = true ): array {
$all_terms = get_terms(
[
'taxonomy' => 'cennik_kat',
'hide_empty' => $hide_empty,
]
);
if ( ! empty( $ordered_terms_id ) ) {
$sorted_terms = sort_objects_by_id_order( $all_terms, $ordered_terms_id, 'term_id' );
} else {
usort(
$all_terms,
function ( $a, $b ) {
return strcmp( $a->slug, $b->slug );
}
);
$sorted_terms = $all_terms;
}
foreach ( $sorted_terms as $key => $term ) {
if ( $term->term_id == get_pakiet_term_id() ) {
unset( $sorted_terms[ $key ] );
}
}
return array_values( $sorted_terms );
}
/**
* Recursively retrieves a custom field value from a post or its ancestors.
*
* @param WP_Post $post_object The post object to start searching from.
* @param string $field_name The custom field name to retrieve.
* @return int|null The field value or null if not found.
*/
function get_recursive_category_id( WP_Post $post_object, string $field_name ): ?int {
if ( $cat_id = get_field( $field_name, $post_object->ID ) ) {
return $cat_id;
}
if ( ! $post_object->post_parent ) {
return null;
}
$parent = get_post( $post_object->post_parent );
return get_recursive_category_id( $parent, $field_name );
}
/**
* Retrieves and formats the price for a specific post.
*
* @param int $post_id The ID of the post for which to retrieve the price.
* @return string Formatted price or a call-to-action text if the price is not set.
*/
function show_price( int $post_id ): string {
$maybe_price = get_field( 'price', $post_id );
$maybe_from = get_field( 'prefix_from', $post_id );
$maybe_to = get_field( 'prefix_to', $post_id );
$price_upper = get_field( 'price_upper', $post_id );
if ( ! $maybe_price ) {
return 'Zadzwoń';
}
$price = format_price( $maybe_price );
if ( $maybe_price && $maybe_from ) {
$price = 'od ' . $price;
}
if ( $maybe_price && $maybe_to ) {
$price .= ' do ' . $price_upper . ' zł';
}
return $price;
}
function show_pricelist_item_type( int $post_id ) {
$type = get_field( 'type', $post_id );
if ( $type ) {
return $type;
}
$parent_id = get_post( $post_id )->post_parent;
if ( $parent_id ) {
return show_pricelist_item_type( $parent_id );
}
return '';
}
/**
* Print a pricelist item.
*
* @param int $post_id The post ID of the pricelist item.
* @param bool $white_style Whether to use white style for the item (default: false).
*/
function print_pricelist_item( int $post_id, bool $second_level = false ) {
?>
<div class="prl__price-item<?= $second_level ? ' prl__test' : null; ?> d-flex aic jcb">
<div class="d-flex f-c" style="gap: 8px;">
<div class="prl__heading h6 m-0">
<?= get_the_title( $post_id ); ?>
<?php if ( DEBUG ) : ?>
<a style="font-size: 1em;" tabindex="-1" href="<?= get_edit_post_link( $post_id ); ?>">(Edytuj)</a>
<?php endif; ?>
</div>
<div class="prl__desc"><?= get_field( 'desc', $post_id ); ?></div>
</div>
<div class="d-flex f-c jcc aie" style="gap:8px">
<div class="prl__price h6 f-500 t-r"><?= show_price( $post_id ); ?></div>
<!-- show_pricelist_item_type -->
<div class="prl__type h6 f-400 t-r c-black-700">
<?= show_pricelist_item_type( $post_id ); ?>
<?php if ( DEBUG ) : ?>
<a style="font-size: 1em;" tabindex="-1" href="<?= get_edit_post_link( $post_id ); ?>">(Edytuj)</a>
<?php endif; ?>
</div>
</div>
</div>
<?php
}
Here's what I'd like feedback on:
Code Structure: Any suggestions for improving the organization and structure of the code to make it more modular and maintainable.
Performance: Any potential performance optimizations or areas where code can be optimized.
Readability: Suggestions for improving code comments, variable names, and overall code readability.
WordPress Best Practices: Any recommendations for following WordPress best practices and conventions.
Code Quality: Any potential bugs or issues in the code that I may have missed.
I appreciate your time and assistance in reviewing this code. Your feedback will help me improve my coding skills and the quality of my project. Thank you!
- 264
- 2
- 14