KOK - MANAGER
Edit File: Repository.php
<?php /** * Repository service. * * @author Code Atlantic * @package PopupMaker * @copyright (c) 2024, Code Atlantic LLC. */ namespace PopupMaker\Base\Service; use PopupMaker\Base\Service; use PopupMaker\Base\Model\Post; defined( 'ABSPATH' ) || exit; /** * Repository service for managing Post-based entities. * * @since 1.21.0 * @template TPost of Post * @template-extends Service<\PopupMaker\Plugin\Core> */ abstract class Repository extends Service { /** * Post type key for registration. * * @var non-empty-string */ protected $post_type_key; /** * Registered WordPress post type name. * * @var non-empty-string */ protected $post_type; /** * Cache of instantiated items indexed by post ID. * * @var array<int, TPost> */ protected $items_by_id = []; /** * Initialize the service. * * @param \PopupMaker\Plugin\Core $container Plugin container. */ public function __construct( $container ) { parent::__construct( $container ); $this->post_type = $container->get_controller( 'PostTypes' )->get_type_key( $this->post_type_key ); } /** * Instantiate model from post. * * @param \WP_Post $post Post object. * * @return TPost|null */ abstract public function instantiate_model_from_post( $post ); /** * Cache an item in internal storage. * * @param TPost $item Item to cache by ID for fast retrieval. * @return void */ protected function cache_item( $item ) { $this->items_by_id[ $item->ID ] = $item; } /** * Get a list of all queried items. * * @param array<string, mixed> $args { * Optional. WP_Query arguments for filtering posts. * * @type string|string[] $post_type Post type to query. * @type int $posts_per_page Number of posts to retrieve. * @type string|string[] $post_status Post status to query. * @type string $meta_key Meta key to query. * @type mixed $meta_value Meta value to query. * } * @return TPost[] Array of instantiated model objects matching the query. */ public function query( $args = [] ) { $query_args = wp_parse_args( $args, [ 'post_type' => $this->post_type, 'posts_per_page' => - 1, ] ); $query_results = new \WP_Query( $query_args ); /** @var TPost[] $items */ $items = []; foreach ( $query_results->posts as $post ) { if ( ! $post instanceof \WP_Post ) { continue; } $item = $this->instantiate_model_from_post( $post ); if ( ! $item ) { continue; } // Cache the item. $this->cache_item( $item ); $items[] = $item; } return $items; } /** * Get item by ID. * * @param int|numeric-string $item_id Item ID to retrieve. * @return TPost|null Model instance if found, null otherwise. */ public function get_by_id( $item_id = 0 ) { // Convert to integer for consistent handling. $item_id = (int) $item_id; // If item is cached, get the object. if ( isset( $this->items_by_id[ $item_id ] ) ) { return $this->items_by_id[ $item_id ]; } // Query for a post by ID. if ( $item_id > 0 ) { $post = get_post( $item_id ); if ( $post && $post->post_type === $this->post_type ) { $item = $this->instantiate_model_from_post( $post ); if ( $item ) { $this->cache_item( $item ); } return $item; } } return null; } /** * Get item by custom field or column. * * @param non-empty-string $field Field name (post column like 'post_name' or meta key). * @param string|int|float $value Field value to search for. * @param 'column'|'meta' $type Search type: 'column' for post table columns or 'meta' for post meta fields. * @return TPost|null Model instance if found, null otherwise. */ public function get_by_field( $field, $value, $type = 'column' ) { if ( empty( $field ) || ( empty( $value ) && 0 !== $value && '0' !== $value ) ) { return null; } $query_args = [ 'post_type' => $this->post_type, 'posts_per_page' => 1, 'post_status' => [ 'publish', 'private', 'draft' ], ]; if ( 'meta' === $type ) { $query_args['meta_key'] = $field; // phpcs:ignore WordPress.DB.SlowDBQuery $query_args['meta_value'] = $value; // phpcs:ignore WordPress.DB.SlowDBQuery } else { // For post columns like post_name, post_title, etc. $query_args[ $field ] = $value; } $query = new \WP_Query( $query_args ); if ( $query->have_posts() ) { $post = $query->posts[0]; if ( $post instanceof \WP_Post ) { $item = $this->instantiate_model_from_post( $post ); if ( $item ) { $this->cache_item( $item ); } return $item; } } return null; } }