Skip to content

Snippets / PHP

PHP

Counting CPTs and relations

B brindeau.joachim · 206 views · Updated 1 year ago
 
This snippet can:

count the number of any post relation to the current post (without creating extra fields)
count the total number of any given CPT

The values will appear as Elementor Dynamic Tags.
Simply paste this in any code snippet plugin or in the functions file of your theme.
function register_cpt_relation_dynamic_tags($dynamic_tags_manager) {
$post_types = get_post_types(['public' => true], 'names');

foreach ($post_types as $post_type) {
$file_name = 'cpt-' . $post_type . '-relation-tag.php';
$file_path = __DIR__ . '/dynamic-tags/' . $file_name;

if (file_exists($file_path)) {
require_once($file_path);
$class_name = 'Elementor_CPT_' . str_replace('-', '_', $post_type) . '_Relation_Tag';
if (class_exists($class_name)) {
$dynamic_tags_manager->register(new $class_name());
}
}

$total_file_name = 'cpt-' . $post_type . '-total-tag.php';
$total_file_path = __DIR__ . '/dynamic-tags/' . $total_file_name;

if (file_exists($total_file_path)) {
require_once($total_file_path);
$total_class_name = 'Elementor_CPT_' . str_replace('-', '_', $post_type) . '_Total_Tag';
if (class_exists($total_class_name)) {
$dynamic_tags_manager->register(new $total_class_name());
}
}
}
}
add_action('elementor/dynamic_tags/register', 'register_cpt_relation_dynamic_tags');

function create_cpt_relation_dynamic_tag_files() {
$post_types = get_post_types(['public' => true], 'names');
$dynamic_tags_dir = __DIR__ . '/dynamic-tags';

if (!file_exists($dynamic_tags_dir)) {
wp_mkdir_p($dynamic_tags_dir);
}

foreach ($post_types as $post_type) {
$file_name = 'cpt-' . $post_type . '-relation-tag.php';
$file_path = $dynamic_tags_dir . '/' . $file_name;

if (!file_exists($file_path)) {
$class_name = 'Elementor_CPT_' . str_replace('-', '_', $post_type) . '_Relation_Tag';
$content = "<?php
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}

class {$class_name} extends \\Elementor\\Core\\DynamicTags\\Tag {
public function get_name() {
return 'cpt-{$post_type}-relation';
}

public function get_title() {
return __('" . ucwords(str_replace('_', ' ', $post_type)) . " Relation', 'your-text-domain');
}

public function get_group() {
return 'post';
}

public function get_categories() {
return ['text'];
}

protected function render() {
global \$post, \$wpdb;

if (!\$post) return;

\$count = \$wpdb->get_var(\$wpdb->prepare(\"
SELECT COUNT(DISTINCT r.child_id)
FROM {\$wpdb->prefix}voxel_relations r
JOIN {\$wpdb->posts} p ON r.child_id = p.ID
WHERE r.parent_id = %d AND p.post_type = %s
\", \$post->ID, '{$post_type}'));

echo \$count !== null ? \$count : '0';
}
}";
file_put_contents($file_path, $content);
}

$total_file_name = 'cpt-' . $post_type . '-total-tag.php';
$total_file_path = $dynamic_tags_dir . '/' . $total_file_name;

if (!file_exists($total_file_path)) {
$total_class_name = 'Elementor_CPT_' . str_replace('-', '_', $post_type) . '_Total_Tag';
$total_content = "<?php
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}

class {$total_class_name} extends \\Elementor\\Core\\DynamicTags\\Tag {
public function get_name() {
return 'cpt-{$post_type}-total';
}

public function get_title() {
return __('" . ucwords(str_replace('_', ' ', $post_type)) . " Total', 'your-text-domain');
}

public function get_group() {
return 'post';
}

public function get_categories() {
return ['text'];
}

protected function render() {
\$count = wp_count_posts('{$post_type}')->publish;
echo \$count !== null ? \$count : '0';
}
}";
file_put_contents($total_file_path, $total_content);
}
}
}
add_action('init', 'create_cpt_relation_dynamic_tag_files');
PHP · 120 lines

Discussion 1

Ask a question or share how you used this.

Log in to join the discussion.
Donald McGuinn 1 year ago

You made this for Elementor Dynamic tag and not Voxel Dynamic Tag modifier?

Voxel Guide assistant
Ask about snippets, addons & how-tos

Hey — how can I help?

I can dig through the library for snippets, addons, and tutorials.

AI can be wrong — double-check anything important.