Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 66 additions & 8 deletions src/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@
class Query {
private readonly string $name;

private string $label;
private readonly string $label;

private array $controls = [];

private $callback;

private Query_Type $type;

private int $total;
private int $max_pages;

private array $config_flags = [
'wpgb' => true,
'per_page_control' => true,
Expand Down Expand Up @@ -60,6 +63,12 @@ public function bricks_query( array $results, \Bricks\Query $query_obj ): array
return $results;
}

// Try fetching the query results from the history
$query_history = Query_Registry::getInstance()->get_from_history( $query_obj->element_id );
if ( $query_history !== false && ! empty( $query_history['results'] ) ) {
return $query_history['results'];
}

// Start profiling with query monitor
do_action( 'qm/start', "bricks-$this->name-query" );

Expand All @@ -74,6 +83,9 @@ public function bricks_query( array $results, \Bricks\Query $query_obj ): array
$results = $this->process_wordpress_queries( $results, $query_obj );
}

// Add query to history
Query_Registry::getInstance()->add_to_history( $query_obj, $this, $results );

// Stop profiling with query monitor
do_action( 'qm/stop', "bricks-$this->name-query" );

Expand All @@ -83,12 +95,12 @@ public function bricks_query( array $results, \Bricks\Query $query_obj ): array
/**
* Process wordpress native queries
*
* @param $results
* @param $query_obj
* @param array $results
* @param \Bricks\Query $query_obj
*
* @return array
*/
private function process_wordpress_queries(array $results, \Bricks\Query $query_obj): array {
private function process_wordpress_queries( array $results, \Bricks\Query $query_obj ): array {
$prepared_args = [];

// --- Config Flag: wpgb ---
Expand Down Expand Up @@ -134,16 +146,29 @@ private function process_wordpress_queries(array $results, \Bricks\Query $query_
}
}

$query = new WP_Query( $args );
$query = new WP_Query( $args );
$this->setMaxPages( $query->max_num_pages ?? 0 );
$this->setTotal( $query->found_posts ?? 0 );
$results = $query->get_posts();
break;
case Query_Type::User:
$query = new WP_User_Query( $args );
$query = new WP_User_Query( $args );
$this->setTotal( $query->get_total() ?? 0 );
$max_num_pages = empty( $prepared_args['number'] ) || count( $this->getTotal() ) < 1 ? 1 : ceil( $this->getTotal() / $prepared_args['number'] );
$this->setMaxPages( $max_num_pages );
$results = $query->get_results();
break;
case Query_Type::Term:
$query = new WP_Term_Query( $args );
$results = $query->get_terms();

// Run another query to get the total count, set number to 0 to avoid limit
$total_terms_query = new \WP_Term_Query( array_merge( $prepared_args, [ 'number' => 0 ] ) );

$this->setTotal( $total_terms_query->get_terms() ?? 0 );
$max_num_pages = empty( $prepared_args['number'] ) || count( $this->getTotal() ) < 1 ? 1 : ceil( $this->getTotal() / $prepared_args['number'] );
$this->setMaxPages( $max_num_pages );

break;
}

Expand Down Expand Up @@ -261,13 +286,13 @@ public function bricks_query_loop_object( $loop_object, $loop_key, $query_obj )
/**
* Callback used to remove super global after loop
*
* @param $query
* @param \Bricks\Query $query
* @param $args
*
* @return void
* @see https://academy.bricksbuilder.io/article/action-bricks-query-after_loop/
*/
public function bricks_query_after_loop( $query, $args ): void {
public function bricks_query_after_loop( \Bricks\Query $query, $args ): void {

if ( $query->object_type !== $this->name ) {
return;
Expand All @@ -279,6 +304,23 @@ public function bricks_query_after_loop( $query, $args ): void {
}
}

/**
* Set max pages for query
*
* @param int $max_num_pages
* @param \Bricks\Query $query_obj
*
* @return int
* @see https://academy.bricksbuilder.io/article/filter-bricks-query-result_max_num_pages/
*/
public function bricks_query_result_max_num_pages( int $max_num_pages, \Bricks\Query $query_obj ): int {
if ( $query_obj->object_type !== $this->name ) {
return $max_num_pages;
}

return $this->getMaxPages();
}

/**
* Allows adding custom controls for the query
*
Expand Down Expand Up @@ -349,4 +391,20 @@ public function loop_object_callback( callable $callback ): static {
return $this;
}

public function getTotal(): int {
return $this->total;
}

public function setTotal( int $total ): void {
$this->total = $total;
}

public function getMaxPages(): int {
return $this->max_pages;
}

public function setMaxPages( int $max_pages ): void {
$this->max_pages = $max_pages;
}

}
84 changes: 84 additions & 0 deletions src/Query_Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,22 @@
class Query_Registry
{

/**
* Query history through the lifetime of a request
*
* @var array
*/
private static array $history = [];
private static ?Query_Registry $instance = null;
private array $storage = [];

/**
* We store each query made with its unique id inside this array
*
* @var array
*/
public static array $query_history = [];

private function __construct() {
add_action('pre_get_posts', function() {
$this->registerQuery();
Expand Down Expand Up @@ -61,6 +74,7 @@ public function registerQuery(): void
add_filter('bricks/query/loop_object', [$query, 'bricks_query_loop_object'], 10, 3);
add_action('bricks/query/after_loop', [$query, 'bricks_query_after_loop'], 10, 2);
add_filter('bricks/setup/control_options', [$query, 'bricks_add_query_type']);
add_filter('bricks/query/result_max_num_pages', [$query, 'bricks_query_result_max_num_pages'], 10, 2);

// Register Loops for some elements
$elements = ['container', 'block', 'div'];
Expand All @@ -71,4 +85,74 @@ public function registerQuery(): void

}

/**
* Generate a universal deterministic key for the query.
* Directly copied from bricks
*
* @param string $element_id
*
* @link Bricks\Query::generate_query_history_id in bricks/includes/query.php
* @return string
*/
private static function build_history_key(string $element_id): string {
$unique_id = [];
$looping_query_id = \Bricks\Query::is_any_looping();

if ( $looping_query_id && $looping_query_id !== $element_id ) {
$unique_id[] = \Bricks\Query::get_query_element_id( $looping_query_id );
$unique_id[] = $element_id;
$unique_id[] = \Bricks\Query::get_query_object_type( $looping_query_id );

// Get loop ID
$loop_id = \Bricks\Query::get_loop_object_id( $looping_query_id );
if ( $loop_id ) {
$unique_id[] = $loop_id;
}

// Return: No loop ID found
else {
return "";
}
} else {
$unique_id[] = $element_id;
}

return implode( '_', $unique_id );
}

/**
* Adds a query to the global history.
*
* @param \Bricks\Query $bricks_query
* @param Query $query
* @param array $results
*
* @return void
*/
public static function add_to_history(\Bricks\Query $bricks_query, Query $query, array $results = []): void {
self::$history[self::build_history_key($bricks_query->element_id)] = [
'results' => $results,
'max_pages' => $query->getMaxPages(),
'total' => $query->getTotal()
];
}

/**
* Tries to receive a query from global history
*
* @param string $id
*
* @return false|array
*/
public static function get_from_history(string $element_id): false|array {

$key = self::build_history_key($element_id);

if (!in_array($key, array_keys(self::$history))) {
return false;
}

return self::$history[$key];
}

}