oont-contents/plugins/insert-headers-and-footers/includes/generator/class-wpcode-generator-query.php
2025-04-06 08:34:48 +02:00

743 lines
25 KiB
PHP

<?php
/**
* Generate a snippet using WP_Query
*
* @package WPCode
*/
/**
* WPCode_Generator_Query class.
*/
class WPCode_Generator_Query extends WPCode_Generator_Type {
/**
* The generator slug.
*
* @var string
*/
public $name = 'query';
/**
* The categories for this generator.
*
* @var string[]
*/
public $categories = array(
'query',
);
/**
* This snippet should not be auto-inserted by default.
*
* @var bool
*/
public $auto_insert = false;
/**
* Set the translatable strings.
*
* @return void
*/
protected function set_strings() {
$this->title = __( 'WP_Query', 'insert-headers-and-footers' );
$this->description = __( 'Generate a snippet using WP_Query to load posts from your website.', 'insert-headers-and-footers' );
}
/**
* Get a list of available post types for autocomplete.
*
* @return array
*/
public function get_autocomplete_post_types() {
return array_keys( get_post_types() );
}
/**
* Get a list of available post statuses for autocomplete.
*
* @return array
*/
public function get_autocomplete_post_statuses() {
return array_keys( get_post_statuses() );
}
/**
* Load the generator tabs.
*
* @return void
*/
protected function load_tabs() {
$this->tabs = array(
'info' => array(
'label' => __( 'Info', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
// Column 1 fields.
array(
'type' => 'description',
'label' => __( 'Overview', 'insert-headers-and-footers' ),
'content' => sprintf(
// Translators: Placeholders add links to the wordpress.org references.
__( 'This generator makes it easy for you to create custom queries using %1$sWP_Query%2$s which you can then extend to display posts or similar.', 'insert-headers-and-footers' ),
'<a href="https://developer.wordpress.org/reference/classes/wp_query/" target="_blank">',
'</a>'
),
),
),
// Column 2.
array(
// Column 2 fields.
array(
'type' => 'list',
'label' => __( 'Usage', 'insert-headers-and-footers' ),
'content' => array(
__( 'Fill in the forms using the menu on the left.', 'insert-headers-and-footers' ),
__( 'Click the "Update Code" button.', 'insert-headers-and-footers' ),
__( 'Click on "Use Snippet" to create a new snippet with the generated code.', 'insert-headers-and-footers' ),
__( 'Activate and save the snippet and you\'re ready to go', 'insert-headers-and-footers' ),
),
),
),
// Column 3.
array(
// Column 3 fields.
array(
'type' => 'description',
'label' => __( 'Examples', 'insert-headers-and-footers' ),
'content' => __( 'You can use this generator to get quickly started with a query for all the posts of an author and display them using the shortcode functionality of WPCode or automatically displaying the posts using the auto-insert option.', 'insert-headers-and-footers' ),
),
),
),
),
'general' => array(
'label' => __( 'General', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Query variable name', 'insert-headers-and-footers' ),
'description' => __( 'If you want to use something more specific. The leading $ will be automatically added.', 'insert-headers-and-footers' ),
'id' => 'var_name',
'placeholder' => '$query',
'default' => 'query',
),
),
// Column 2.
array(
array(
'type' => 'select',
'label' => __( 'Include loop', 'insert-headers-and-footers' ),
'description' => __( 'Select yes if you want to include an empty loop of the results that you can fill in for output.', 'insert-headers-and-footers' ),
'id' => 'loop',
'default' => 'true',
'options' => array(
'true' => __( 'Yes', 'insert-headers-and-footers' ),
'false' => __( 'No', 'insert-headers-and-footers' ),
),
),
),
),
),
'post' => array(
'label' => __( 'IDs & Parents', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Post ID(s)', 'insert-headers-and-footers' ),
'description' => __( 'Query a specific post ID or comma-separated list of ids. Cannot be combined with "Post ID not in" below.', 'insert-headers-and-footers' ),
'id' => 'post__in',
'default' => '',
'comma-separated' => true,
),
array(
'type' => 'text',
'label' => __( 'Post ID not in', 'insert-headers-and-footers' ),
'description' => __( 'Post ids to exclude from this query. Cannot be combined with "Post ID(s)" above.', 'insert-headers-and-footers' ),
'id' => 'post__not_in',
'default' => '',
'comma-separated' => true,
),
),
// Column 2.
array(
array(
'type' => 'text',
'label' => __( 'Post parent ID(s)', 'insert-headers-and-footers' ),
'description' => __( 'Comma-separated list of post parent ids if the post type is hierarchical (like pages).', 'insert-headers-and-footers' ),
'id' => 'post_parent__in',
'default' => '',
'comma-separated' => true,
),
array(
'type' => 'text',
'label' => __( 'Post parent not in', 'insert-headers-and-footers' ),
'description' => __( 'Comma-separated list of post parent ids to exclude.', 'insert-headers-and-footers' ),
'id' => 'post_parent__not_in',
'default' => '',
'comma-separated' => true,
),
),
// Column 3.
array(
array(
'type' => 'text',
'label' => __( 'Post slugs', 'insert-headers-and-footers' ),
'description' => __( 'Comma-separated list of post slugs to query by.', 'insert-headers-and-footers' ),
'id' => 'post_name__in',
'default' => '',
'comma-separated' => true,
),
),
),
),
'status' => array(
'label' => __( 'Type & Status', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Post type', 'insert-headers-and-footers' ),
'description' => __( 'Post type to query by, start typing to get suggestions.', 'insert-headers-and-footers' ),
'id' => 'post_type',
'default' => 'post',
'autocomplete' => $this->get_autocomplete_post_types(),
),
),
// Column 2.
array(
array(
'type' => 'text',
'label' => __( 'Post status', 'insert-headers-and-footers' ),
'description' => __( 'Post status to query by.', 'insert-headers-and-footers' ),
'id' => 'post_status',
'default' => 'publish',
'autocomplete' => $this->get_autocomplete_post_statuses(),
),
),
),
),
'author' => array(
'label' => __( 'Author', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Author ID(s)', 'insert-headers-and-footers' ),
'description' => __( 'Author ID or comma-separated list of ids.', 'insert-headers-and-footers' ),
'id' => 'author',
'default' => '',
),
array(
'type' => 'text',
'label' => __( 'Author not in', 'insert-headers-and-footers' ),
'description' => __( 'Comma-separated list of author ids to exclude from the query.', 'insert-headers-and-footers' ),
'id' => 'author__not_in',
'default' => '',
'comma-separated' => true,
),
),
// Column 2.
array(
array(
'type' => 'text',
'label' => __( 'Author name', 'insert-headers-and-footers' ),
'description' => __( 'Use the "user_nicename" parameter to query by author.', 'insert-headers-and-footers' ),
'id' => 'author_name',
'default' => '',
),
),
),
),
'search' => array(
'label' => __( 'Search', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Search term', 'insert-headers-and-footers' ),
'description' => __( 'Search for posts by this search term.', 'insert-headers-and-footers' ),
'id' => 's',
'default' => '',
),
),
),
),
'order' => array(
'label' => __( 'Order', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'select',
'label' => __( 'Results Order', 'insert-headers-and-footers' ),
'id' => 'order',
'default' => 'DESC',
'options' => array(
'DESC' => __( 'Descending order (3, 2, 1; c, b, a)', 'insert-headers-and-footers' ),
'ASC' => __( 'Ascending order (1, 2, 3; a, b, c)', 'insert-headers-and-footers' ),
),
),
),
// Column 2.
array(
array(
'type' => 'select',
'label' => __( 'Order by', 'insert-headers-and-footers' ),
'id' => 'orderby',
'default' => 'date',
'options' => array(
'none' => __( 'No order (none)', 'insert-headers-and-footers' ),
'ID' => __( 'ID', 'insert-headers-and-footers' ),
'author' => __( 'Author', 'insert-headers-and-footers' ),
'title' => __( 'Title', 'insert-headers-and-footers' ),
'name' => __( 'Slug (name)', 'insert-headers-and-footers' ),
'type' => __( 'Post type (type)', 'insert-headers-and-footers' ),
'date' => __( 'Date (default)', 'insert-headers-and-footers' ),
'modified' => __( 'Modified date', 'insert-headers-and-footers' ),
'parent' => __( 'Parent id', 'insert-headers-and-footers' ),
'rand' => __( 'Random', 'insert-headers-and-footers' ),
'comment_count' => __( 'Comment count', 'insert-headers-and-footers' ),
'relevance' => __( 'Relevance (for search)', 'insert-headers-and-footers' ),
'menu_order' => __( 'Page Order (menu_order)', 'insert-headers-and-footers' ),
//phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
'meta_value' => __( 'Meta value', 'insert-headers-and-footers' ),
'meta_value_num' => __( 'Numerical meta value (meta_value_num)', 'insert-headers-and-footers' ),
'post__in' => __( 'Order of ids in post__in', 'insert-headers-and-footers' ),
'post_name__in' => __( 'Order of names in post_name__in', 'insert-headers-and-footers' ),
'post_parent__in' => __( 'Order of ids in post_parent__in', 'insert-headers-and-footers' ),
),
),
array(
'type' => 'text',
'label' => __( 'Meta Key', 'insert-headers-and-footers' ),
'description' => __( 'Meta key to use if you choose to order by meta value.', 'insert-headers-and-footers' ),
'id' => 'meta_key',
'default' => '',
),
),
// Column 3.
array(),
),
),
'pagination' => array(
'label' => __( 'Pagination', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'select',
'label' => __( 'Use Pagination', 'insert-headers-and-footers' ),
'id' => 'nopaging',
'default' => 'false',
'description' => __( 'Choose no to display all posts (not recommended).', 'insert-headers-and-footers' ),
'options' => array(
'true' => __( 'No', 'insert-headers-and-footers' ),
'false' => __( 'Yes (default)', 'insert-headers-and-footers' ),
),
),
array(
'type' => 'text',
'label' => __( 'Page number', 'insert-headers-and-footers' ),
'description' => __( 'Which page to show.', 'insert-headers-and-footers' ),
'id' => 'paged',
'default' => '',
),
),
// Column 2.
array(
array(
'type' => 'text',
'label' => __( 'Posts per page', 'insert-headers-and-footers' ),
'description' => __( 'How many posts should be displayed per page.', 'insert-headers-and-footers' ),
'id' => 'posts_per_page',
'default' => '',
),
array(
'type' => 'text',
'label' => __( 'Offset', 'insert-headers-and-footers' ),
'description' => __( 'Number of posts to skip.', 'insert-headers-and-footers' ),
'id' => 'offset',
'default' => '',
),
),
// Column 3.
array(
array(
'type' => 'select',
'label' => __( 'Ignore sticky posts', 'insert-headers-and-footers' ),
'id' => 'ignore_sticky_posts',
'default' => 'false',
'options' => array(
'true' => __( 'Yes', 'insert-headers-and-footers' ),
'false' => __( 'No (default)', 'insert-headers-and-footers' ),
),
),
),
),
),
'taxonomy' => array(
'label' => __( 'Taxonomy', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Taxonomy', 'insert-headers-and-footers' ),
'description' => __( 'Taxonomy slug that you want to query by.', 'insert-headers-and-footers' ),
'id' => 'taxonomy',
'name' => 'taxonomy[]',
'default' => '',
'repeater' => 'tax_query',
),
array(
'type' => 'select',
'label' => __( 'Field', 'insert-headers-and-footers' ),
'description' => __( 'Select taxonomy term by.', 'insert-headers-and-footers' ),
'id' => 'field',
'name' => 'field[]',
'repeater' => 'tax_query',
'default' => 'term_id',
'options' => array(
'term_id' => __( 'Term ID (default)', 'insert-headers-and-footers' ),
'name' => __( 'Term Name', 'insert-headers-and-footers' ),
'slug' => __( 'Term Slug', 'insert-headers-and-footers' ),
'term_taxonomy_id' => __( 'Term Taxonomy ID', 'insert-headers-and-footers' ),
),
),
array(
'type' => 'text',
'label' => __( 'Terms', 'insert-headers-and-footers' ),
'description' => __( 'Comma-separated list of terms to query by.', 'insert-headers-and-footers' ),
'id' => 'terms',
'name' => 'terms[]',
'default' => '',
'repeater' => 'tax_query',
'comma-separated' => true,
),
),
// Column 2.
array(
array(
'type' => 'select',
'label' => __( 'Include Children', 'insert-headers-and-footers' ),
'id' => 'include_children',
'name' => 'include_children[]',
'default' => 'true',
'description' => __( 'Whether or not to include children for hierarchical taxonomies.', 'insert-headers-and-footers' ),
'options' => array(
'true' => __( 'Yes', 'insert-headers-and-footers' ),
'false' => __( 'No', 'insert-headers-and-footers' ),
),
'repeater' => 'tax_query',
),
array(
'type' => 'select',
'label' => __( 'Operator', 'insert-headers-and-footers' ),
'id' => 'operator',
'name' => 'operator[]',
'default' => 'IN',
'description' => __( 'Operator to test relation by.', 'insert-headers-and-footers' ),
'options' => array(
'IN' => 'IN',
'NOT IN' => 'NOT IN',
'AND' => 'AND',
'EXISTS' => 'EXISTS',
'NOT EXISTS' => 'NOT EXISTS',
),
'repeater' => 'tax_query',
),
array(
'type' => 'spacer',
),
),
// Column 3.
array(
array(
'type' => 'description',
'label' => __( 'Add another taxonomy', 'insert-headers-and-footers' ),
'content' => __( 'Use the "Add Taxonomy" button below to query multiple taxonomies.', 'insert-headers-and-footers' ),
),
array(
'type' => 'repeater_button',
'button_text' => __( 'Add Taxonomy', 'insert-headers-and-footers' ),
'id' => 'tax_query', // Repeater to repeat when clicked.
),
array(
'type' => 'select',
'label' => __( 'Tax Relation', 'insert-headers-and-footers' ),
'id' => 'relation',
'default' => 'AND',
'options' => array(
'AND' => __( 'AND (default)', 'insert-headers-and-footers' ),
'OR' => __( 'OR', 'insert-headers-and-footers' ),
),
),
),
),
),
'meta' => array(
'label' => __( 'Custom Fields', 'insert-headers-and-footers' ),
'columns' => array(
// Column 1.
array(
array(
'type' => 'text',
'label' => __( 'Meta Key', 'insert-headers-and-footers' ),
'description' => __( 'The key of the custom field.', 'insert-headers-and-footers' ),
'id' => 'key',
'name' => 'key[]',
'default' => '',
'repeater' => 'meta_query',
),
array(
'type' => 'text',
'label' => __( 'Meta Value', 'insert-headers-and-footers' ),
'description' => __( 'Value to query the meta by.', 'insert-headers-and-footers' ),
'id' => 'value',
'name' => 'value[]',
'default' => '',
'repeater' => 'meta_query',
),
),
// Column 2.
array(
array(
'type' => 'select',
'label' => __( 'Compare', 'insert-headers-and-footers' ),
'description' => __( 'How to compare the value for querying by meta.', 'insert-headers-and-footers' ),
'id' => 'compare',
'name' => 'compare[]',
'repeater' => 'meta_query',
'default' => '=',
'options' => array(
'=' => '=',
'!=' => '!=',
'>' => '>',
'>=' => '>=',
'<' => '<',
'<=' => '<=',
'LIKE' => 'LIKE',
'NOT LIKE' => 'NOT LIKE',
'IN' => 'IN',
'NOT IN' => 'NOT IN',
'BETWEEN' => 'BETWEEN',
'NOT BETWEEN' => 'NOT BETWEEN',
'EXISTS' => 'EXISTS',
'NOT EXISTS' => 'NOT EXISTS',
'REGEXP' => 'REGEXP',
'NOT REGEXP' => 'NOT REGEXP',
'RLIKE' => 'RLIKE',
),
),
array(
'type' => 'select',
'label' => __( 'Type', 'insert-headers-and-footers' ),
'description' => __( 'Type of custom field.', 'insert-headers-and-footers' ),
'id' => 'meta_type',
'name' => 'meta_type[]',
'repeater' => 'meta_query',
'default' => 'CHAR',
'options' => array(
'NUMERIC' => 'NUMERIC',
'BINARY' => 'BINARY',
'CHAR' => 'CHAR',
'DATE' => 'DATE',
'DATETIME' => 'DATETIME',
'DECIMAL' => 'DECIMAL',
'SIGNED' => 'SIGNED',
'TIME' => 'TIME',
'UNSIGNED' => 'UNSIGNED',
),
),
),
// Column 3.
array(
array(
'type' => 'description',
'label' => __( 'Add another meta query', 'insert-headers-and-footers' ),
'content' => __( 'Use the "Add Meta" button below to use multiple meta queries.', 'insert-headers-and-footers' ),
),
array(
'type' => 'repeater_button',
'button_text' => __( 'Add Meta', 'insert-headers-and-footers' ),
'id' => 'meta_query', // Repeater to repeat when clicked.
),
array(
'type' => 'select',
'label' => __( 'Relation', 'insert-headers-and-footers' ),
'id' => 'meta_relation',
'default' => 'AND',
'options' => array(
'AND' => __( 'AND (default)', 'insert-headers-and-footers' ),
'OR' => __( 'OR', 'insert-headers-and-footers' ),
),
),
),
),
),
);
}
/**
* Get the snippet code with dynamic values applied.
*
* @return string
*/
public function get_snippet_code() {
$query_variable = '$' . str_replace( '$', '', $this->get_value( 'var_name' ) );
$loop_code = '';
if ( 'true' === $this->get_value( 'loop' ) ) {
$loop_code = "
if ( {$query_variable}->have_posts() ) {
while ( {$query_variable}->have_posts() ) {
{$query_variable}->the_post();
// Add you post code here.
}
} else {
// Display a no posts found message here.
}
// Reset post data.
wp_reset_postdata();
";
}
$optional_values = array(
'post__in' => false,
'post__not_in' => false, // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in
'post_parent__in' => false,
'post_parent__not_in' => false,
'post_name__in' => true,
'post_type' => true,
'post_status' => true,
'author' => true,
'author__not_in' => false,
'author_name' => true,
's' => true,
'order' => true,
'orderby' => true,
//phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_key' => true,
'nopaging' => false,
'paged' => false,
'posts_per_page' => false,
'offset' => false,
'ignore_sticky_posts' => false,
);
$args = '';
foreach ( $optional_values as $optional_value => $quotes ) {
$args .= $this->get_optional_value( $optional_value, $quotes );
}
$tax_query = '';
$taxonomies = $this->get_value( 'taxonomy' );
$fields = $this->get_value( 'field' );
$terms = $this->get_value( 'terms' );
$include_children = $this->get_value( 'include_children' );
$operator = $this->get_value( 'operator' );
if ( ! empty( $taxonomies ) ) {
$tax_query_arrays = array();
foreach ( $taxonomies as $key => $taxonomy ) {
if ( empty( $taxonomy ) ) {
continue;
}
$params = array(
$this->get_optional_value_code( $fields[ $key ], $this->get_default_value( 'field' ), 'field', true ),
$this->get_optional_value_code( $terms[ $key ], $this->get_default_value( 'terms' ), 'terms', true, true ),
$this->get_optional_value_code( $include_children[ $key ], $this->get_default_value( 'include_children' ), 'include_children' ),
$this->get_optional_value_code( $operator[ $key ], $this->get_default_value( 'operator' ), 'operator', true ),
);
$params = array_filter( $params );
$params = str_replace( "\n", '', $params );
$params = implode( "\n\t\t", $params );
if ( ! empty( $params ) ) {
$params = "\n\t\t" . $params;
}
$tax_query_arrays[] = "\n\t\t\tarray(
'taxonomy' => '$taxonomy',$params
),";
}
if ( ! empty( $tax_query_arrays ) ) {
$tax_query = "\t\t'tax_query' => array(";
if ( count( $tax_query_arrays ) > 1 ) {
$optional_relation = $this->get_optional_value( 'relation', true );
if ( ! empty( $optional_relation ) ) {
$tax_query .= "\n\t" . str_replace( "\n", '', $optional_relation );
}
}
$tax_query .= implode( '', $tax_query_arrays );
$tax_query .= '
),';
}
}
$meta_query = '';
$meta_keys = $this->get_value( 'key' );
$meta_values = $this->get_value( 'value' );
$meta_compares = $this->get_value( 'compare' );
$meta_types = $this->get_value( 'meta_type' );
if ( ! empty( $meta_keys ) ) {
$meta_query_arrays = array();
foreach ( $meta_keys as $key => $meta_key ) {
if ( empty( $meta_key ) ) {
continue;
}
$params = array(
$this->get_optional_value_code( $meta_values[ $key ], $this->get_default_value( 'value' ), 'value', true ),
$this->get_optional_value_code( $meta_compares[ $key ], $this->get_default_value( 'compare' ), 'compare', true ),
$this->get_optional_value_code( $meta_types[ $key ], $this->get_default_value( 'meta_type' ), 'type', true ),
);
$params = array_filter( $params );
$params = str_replace( "\n", '', $params );
$params = implode( "\n\t\t", $params );
if ( ! empty( $params ) ) {
$params = "\n\t\t" . $params;
}
$meta_query_arrays[] = "\n\t\t\tarray(
'key' => '$meta_key',$params
),";
}
if ( ! empty( $meta_query_arrays ) ) {
$meta_query = "\n\t\t'meta_query' => array(";
if ( count( $meta_query_arrays ) > 1 ) {
$optional_relation = $this->get_optional_value( 'meta_relation', true, 'relation' );
if ( ! empty( $optional_relation ) ) {
$meta_query .= "\n\t" . str_replace( "\n", '', $optional_relation );
}
}
$meta_query .= implode( '', $meta_query_arrays );
$meta_query .= '
),';
}
}
$args = "\n" . $args;
return '// Query Posts.
// Query arguments.
$query_args = array(' . $args . $tax_query . $meta_query . '
);
// Run the query.
' . $query_variable . ' = new WP_Query( $query_args );
' . $loop_code . '
';
}
}