=== GameSync Related Games ===
Contributors: tox
Tags: related games, shortcode, manual
Requires at least: 5.0
Tested up to: 6.6
Requires PHP: 7.2
Stable tag: 1.13.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Manually pick related games per post, then place them wherever you want with a shortcode - not auto-inserted into the loop.

== Description ==

This plugin is a shortcode-first alternative to the "Manual Related Posts"
plugin (https://wordpress.org/plugins/related/). That plugin lets you
hand-pick related games in a metabox, but shows them by automatically
hooking into `the_content` (or a widget). This plugin keeps the same idea -
a metabox where you search for and hand-pick related games, with drag and
drop reordering - but drops the automatic content-filter injection
entirely. Instead you place a `[gamesync_related_games]` shortcode exactly
where you want the list to appear: inside the post content, in a
page-builder text block, in a template via `do_shortcode()`, in a sidebar
text widget, wherever.

**Compatibility note:** this plugin stores its data in the same postmeta
key (`related_posts`) as the original "Manual Related Posts" plugin. If
you're switching from that plugin to this one, your existing per-post
selections will already be there - nothing to re-pick. (You can change the
meta key via the `gsrg_meta_key` filter if you'd rather keep the two sets
of data separate.)

= Features =

* Metabox on posts and pages (filterable via `gsrg_post_types`) with a
  live AJAX search box for finding posts/pages by title.
* Drag-and-drop reordering of the selected related games.
* Optional two-way relationships: picking a post as related to another can
  automatically add that other post as related back, and a one-time "Sync
  existing relationships now" button fills in the other side of anything
  set up by hand before this was turned on.
* `[gamesync_related_games]` shortcode with attributes for count, heading,
  thumbnails, excerpts, and an optional weighted multi-taxonomy fallback.
* `[gamesync_top_games]` shortcode: a site-wide leaderboard of the
  highest-rated or highest-reviewed games, independent of any single
  post's related-games picks.
* A matching "Related Games" block for the block editor, for
  sites that build pages with blocks instead of typing shortcodes.
* Optional audience-rating and critic-score badges on every card, when the
  companion **GameSync Game Ratings** and/or **GameSync Review Breakdown**
  plugins are active.
* An admin list-table column showing how many related games are stored
  for each post/page at a glance.
* A "Manage Relationships" bulk admin screen (Settings > Related Games
  > Manage Relationships) listing every supported post with its
  related-games count, a click-to-expand panel per row for editing that
  list without opening the post itself, a bulk action to clear related games for several posts at once, and a filter for posts that have none
  set up yet.
* A REST API (namespace `gamesync-related-games/v1`) for reading and setting
  a post's related-games list, and for triggering the reciprocal-relations
  sync for a single post, from outside wp-admin.
* No content filter, no automatic insertion anywhere - shortcode only.
* No custom database tables; everything lives in postmeta.
* Settings page (Settings > Related Games) for the default
  heading text, the featured-image size/display dimensions, a hover effect
  on the thumbnail, a custom CSS box, rating/review badge toggles, and
  settings to turn the same-genre fallback guess on or off site-wide and
  control which taxonomy it matches on (auto-detecting across the GameSync
  Game Data Importer's Genre, Platform, Game Mode, Theme and Player
  Perspective taxonomies for Game posts).

= Settings page =

Under Settings > Related Games you can set the defaults every
shortcode uses unless it explicitly overrides them:

* **Same-genre fallback** - on by default. When a game has no
  manually-picked related games, this shows games sharing a taxonomy term
  instead of an empty box, wherever a shortcode (or your theme) already
  passes `fallback="1"`. Turn this off to stop the guess everywhere and only
  ever show manually-picked related games, leaving the box empty until you
  pick some, even if `fallback="1"` is still set.
* **Same-genre fallback taxonomy** - which taxonomy the setting above
  actually matches on. Left on "Auto-detect" (the default), a Game post
  from the GameSync Game Data Importer matches across *all* of that
  plugin's own classification taxonomies that apply to it (Genre, Platform,
  Game Mode, Theme, Player Perspective) rather than just one - a candidate
  sharing several of those with the source game (same genre *and* same
  platform, say) outranks one that only shares a single term. WordPress's
  built-in Category is skipped for Game posts entirely, since games are
  usually classified by genre/platform there, not categories. Every other
  post type still falls back to Category. Pick a specific taxonomy here
  (e.g. Platform) to pin the match to that one taxonomy only, for every
  post type this plugin supports - overriding the multi-taxonomy
  auto-detect above.
* **Show rating badge** - on by default. Shows a related game's average
  visitor star rating on its card, when the companion **GameSync Game
  Ratings** plugin is active and that game already has at least one vote.
  No effect if that plugin isn't installed.
* **Show review score badge** - on by default. Shows a related game's
  critic score (out of 10) on its card, when the companion **GameSync
  Review Breakdown** plugin is active and that game already has a scored
  review. No effect if that plugin isn't installed. Appears alongside the
  rating badge above when both are on and both companion plugins are
  active.
* **Default heading text** - replaces "Related Games". A shortcode with its
  own `heading=""` attribute still wins for that one placement.
* **Featured image size** - which registered WordPress image size gets
  served (thumbnail, medium, large, full, or any size a theme/plugin
  registered).
* **Display dimensions** - optional fixed width/height in pixels for the
  thumbnail box. When both are set, the image is cropped to fill the box
  (`object-fit: cover`) so every related-game thumbnail lines up evenly,
  regardless of the source image's own aspect ratio.
* **Hover effect** - what happens to the featured image when a visitor
  hovers a related game: None, Zoom in, a dark overlay with "View Game",
  Grayscale to color, or Lift with shadow.
* **Custom CSS** - loaded right after the plugin's own stylesheet on the
  front end, so it overrides anything above. Useful selectors:
  `.gsrg-related-posts` (wrapper), `.gsrg-heading`, `.gsrg-list`,
  `.gsrg-item`, `.gsrg-thumb` / `.gsrg-thumb img`, `.gsrg-title`,
  `.gsrg-excerpt`, `.gsrg-badges` (badge wrapper), `.gsrg-rating-badge`,
  `.gsrg-review-badge`.

= Shortcode =

Basic usage, placed inside (or near) the post it should describe:

`[gamesync_related_games]`

Show the related games picked for a specific post ID, from anywhere on the
site (handy in a sidebar widget or a template):

`[gamesync_related_games id="123"]`

All attributes:

* `id` - Post ID to pull related games from. Defaults to the current post.
* `count` - Max number of related games to show. `0` (default) shows all
  that were picked.
* `heading` - Heading text above the list. Default: "Related Games". Set to
  an empty string to hide the heading entirely.
* `heading_tag` - HTML tag for the heading, e.g. `h2`, `h3` (default),
  `h4`.
* `show_thumbnail` - `1` (default) or `0`. Shows the featured image.
* `thumbnail_size` - Any registered image size. Default: `thumbnail`.
* `show_excerpt` - `1` or `0` (default). Shows a trimmed excerpt.
* `excerpt_length` - Number of words in the excerpt. Default: `20`.
* `fallback` - `1` or `0` (default). When `1` and no related games were
  picked (or none of them still exist/are published), falls back to the
  most recent posts (of any supported post type) sharing a taxonomy term
  with the source post - which taxonomy depends on the "Same-genre
  fallback taxonomy" setting; see Settings page above. Also requires the
  "Same-genre fallback" setting (Settings > Related Games) to be on,
  which it is by default; turning that setting off suppresses the
  fallback everywhere regardless of this attribute.
* `class` - Extra CSS class added to the wrapper `<div>`.

Example with more options:

`[gamesync_related_games count="3" heading="You might also like" heading_tag="h2" show_excerpt="1" excerpt_length="15" fallback="1"]`

= Top Games Shortcode =

`[gamesync_top_games]` is a separate, self-contained shortcode: a site-wide
leaderboard of the highest-rated or highest-reviewed games, built from the
companion rating plugins' own data rather than any per-post picks. Drop it
on a homepage, a "Best Games" landing page, or a sidebar - it queries
across the whole site, with no source post needed.

`[gamesync_top_games]`

`[gamesync_top_games sort="critic" count="5" heading="Top Reviewed Games"]`

`[gamesync_top_games sort="combined" weight="0.6" count="10" heading="Leaderboard"]`

All attributes:

* `sort` - `rating` (default) ranks by audience rating, via the companion
  **GameSync Game Ratings** plugin. `critic` ranks by critic score, via
  the companion **GameSync Review Breakdown** plugin. `combined` blends
  both into one ranking (see `weight` below) - a game strong on both
  axes outranks one that's only strong on a single axis. If a requested
  ranking's owning plugin isn't installed/active, the shortcode quietly
  outputs nothing (for `rating`/`critic`) or degrades to whichever one
  companion plugin IS active (for `combined`) - never a PHP notice.
* `count` - Max number of games to show. Default: `10`.
* `min_votes` - Used with `sort="rating"` or `sort="combined"`. Minimum
  number of votes a game needs for its audience rating to count, so a
  single 5-star vote can't outrank a game with dozens of 4-star votes.
  Default: `1`.
* `min_score` - Used with `sort="critic"` or `sort="combined"`. Minimum
  overall critic score (0-10) a game needs for its critic score to
  count. Default: `0`.
* `weight` - Only used with `sort="combined"`. Audience-rating weight,
  `0` to `1` - `1` is pure audience rating, `0` is pure critic score,
  the default `0.5` is an even split. A game missing one of the two
  scores entirely is ranked on whichever one it has, at full weight,
  rather than excluded.
* `post_type` - Comma-separated post type(s) to restrict the leaderboard
  to. Default: any post type the relevant companion plugin considers.
* `heading` - Heading text above the list. Default: "Top Games". Set to an
  empty string to hide the heading entirely.
* `heading_tag`, `show_thumbnail`, `thumbnail_size`, `show_excerpt`,
  `excerpt_length`, `class` - same meaning as the matching
  `[gamesync_related_games]` attributes above.

Each entry shows a numbered rank badge over its thumbnail, plus the same
audience-rating/critic-score card badges as `[gamesync_related_games]`
(governed by the same "Show rating badge"/"Show review score badge"
settings).

= Bulk relationship management =

Settings > Related Games > Manage Relationships lists every post
this plugin supports with its current related-games count. Sort or filter
the list to find posts with no related games picked yet, click "Manage" on
any row to search for/add, reorder, or remove that post's related games
right there without opening its editor, or select several rows and use the
bulk actions dropdown to clear their related games in one go.

= REST API =

Under the `gamesync-related-games/v1` namespace:

* `GET /wp-json/gamesync-related-games/v1/posts/<id>/related` - the related games stored for post `<id>`. Public and read-only: works without
  authentication for published content, same as the shortcode itself, and
  never exposes titles/links for posts (the source post or any post in its
  related list) the requester isn't otherwise allowed to read.
* `POST` or `PUT /wp-json/gamesync-related-games/v1/posts/<id>/related` -
  replaces post `<id>`'s related-games list with the `related` array of
  post IDs in the request body. Requires the same edit access to that post
  as the metabox itself (`edit_post`), authenticated the normal WordPress
  REST way (cookie + nonce, or an application password).
* `POST /wp-json/gamesync-related-games/v1/posts/<id>/backfill-reciprocal` -
  forces the reciprocal-relations sync for just that one post (same
  authentication/capability requirement as above).

= Developer filters =

* `gsrg_post_types` - array of post types that get the metabox. Default
  `array( 'post', 'page' )`.
* `gsrg_meta_key` - postmeta key used for storage. Default `related_posts`.
* `gsrg_searchable_statuses` - post statuses returned by the admin search.
* `gsrg_related_ids` - filter the final list of related game IDs before the
  query runs (`$ids, $source_post_id, $atts, $used_fallback`).
* `gsrg_empty_output` - filter the (empty by default) output when there is
  nothing to show.
* `gsrg_fallback_taxonomies` - filter the array of taxonomies the same-genre
  fallback matches across for a given post (`$taxonomies, $post_id`).
* `gsrg_fallback_pool_size` - filter how many ANY-match candidates are
  pulled before ranking by taxonomy-term overlap (`$pool_size, $post_id,
  $taxonomies`). Not the final number shown - that's still the shortcode's
  `count`/fallback limit.
* `gsrg_top_game_ids` - filter `[gamesync_top_games]`'s final list of post
  IDs before the query runs (`$ids, $sort, $atts`).
* `gsrg_top_games_combined_weight` - site-wide override for `sort="combined"`'s
  audience-rating weight (0-1), independent of the shortcode's own `weight`
  attribute.
* `gsrg_top_games_combined_pool_size` - how many candidates `sort="combined"`
  pulls from each companion plugin before blending (`$pool_size, $limit`).
  Not the final number shown - that's still `count`.

== Installation ==

1. Upload the `gamesync-related-games` folder to `/wp-content/plugins/`.
2. Activate the plugin through the "Plugins" menu in WordPress.
3. Edit a post or page - you'll see a "Related Games" box.
   Search for posts, click to add them, drag to reorder, then update/publish.
4. Add `[gamesync_related_games]` wherever you want that post's related games to show up.

== Frequently Asked Questions ==

= Does this add anything to my posts automatically? =

No. Nothing is inserted anywhere unless you place the shortcode yourself.

= Can I migrate from the original "Manual Related Posts" plugin? =

Yes - it uses the same `related_posts` postmeta key by default, so your
existing selections carry over automatically. Just deactivate the old
plugin (or leave it deactivated) and start using the shortcode.

= Does it create any database tables? =

No, it only uses the standard `postmeta` table.

== Changelog ==

= 1.13.4 =
* Fixed: the plugin's "Visit plugin site" link now opens the GameSync Related Games page on gamesyncwp.com.

= 1.13.3 =
* Security: [gamesync_related_games id="N"] for another post, and the related-games REST route, no longer reveal the related list of a draft, private or password-protected post.

= 1.13.2 =
* Fixed: the critic-score badge on a related game's card now uses the same scale as the review itself. A review set to show stars reads e.g. 3.4/5 instead of 6.7/10; "points" reviews still show /10 and "percentage" reviews show %.

= 1.13.1 =
* Changed: the Related Games admin menu now has a fixed position at the bottom of the admin sidebar, grouped with the other GameSync menus. Only its position changed.

= 1.13.0 =
* Fixed: the same-genre fallback match (`fallback="1"`) now caches its result per post (an hour, cleared whenever that post is saved) instead of recomputing a tax_query plus a per-candidate overlap-scoring loop on every single front-end render -- the multi-taxonomy matching added in 1.12.0 made this noticeably more expensive than before, with no caching at all until now.
* Added: `[gamesync_top_games sort="combined"]` -- blends GameSync Game Ratings' audience rating and GameSync Review Breakdown's critic score into one ranking (a new `weight` attribute, default 0.5, controls the blend; a game with only one of the two scores is ranked on that one alone, at full weight, rather than excluded). New `gsrg_top_games_combined_weight`/`gsrg_top_games_combined_pool_size` filters.
* Also trimmed this Changelog to stay under the directory's 5,000-character display limit -- older entries (1.0.0-1.10.0) are now one rolled-up summary below; full detail remains in the bundled README.md.

= 1.12.0 =
* Added: when the companion **GameSync Review Breakdown** plugin is also
  active, a related game's card can now show its critic score
  (e.g. "7.8/10") alongside the audience rating badge. Controlled by a new
  "Show review score badge" setting under Settings > Related Games, on by
  default. Entirely optional: has no effect at all if Review Breakdown
  isn't installed, and a game with no scored review yet shows its card
  exactly as before.
* Added: a new `[gamesync_top_games]` shortcode - a site-wide leaderboard
  of the highest-rated (`sort="rating"`) or highest-reviewed
  (`sort="critic"`) games, drawing on GameSync Game Ratings' and GameSync
  Review Breakdown's own bulk-query APIs rather than any per-post picks.
  See "Top Games Shortcode" above for all attributes. Gracefully outputs
  nothing if the plugin that owns the requested ranking isn't active.
* Changed: the same-genre fallback now matches across every classification
  taxonomy that applies to a Game post (Genre, Platform, Game Mode, Theme,
  Player Perspective) instead of just one, pulling a wider pool of
  any-match candidates and then ranking them by how many of those terms
  they actually share with the source game - a game matching on several
  taxonomies at once now outranks one that only shares a single term. The
  "Same-genre fallback taxonomy" setting still pins the match to one
  specific taxonomy when set, exactly as before. New `gsrg_fallback_taxonomies`
  and `gsrg_fallback_pool_size` filters for extending either part of this.

= 1.11.0 =
* Added: when the companion **GameSync Game Ratings** plugin is also
  active, a related game's card can now show its average visitor star
  rating (e.g. "&#9733; 4.2") right under the title, drawing on however
  many votes that game already has. Controlled by a new "Show rating
  badge" setting under Settings > Related Games, on by default. Entirely
  optional: has no effect at all if Game Ratings isn't installed, and a
  game with no votes yet shows its card exactly as before.

= 1.0.0 - 1.10.0 =
* Early development through the plugin's public rename and early taxonomy-matching work: a Settings page, hover effects, reverse (two-way) relationship syncing, a "Manage Relationships" bulk admin screen, a REST API (`gamesync-related-games/v1`), a Gutenberg block, admin list-table integration, several security/hardening fixes (draft-visibility leaks, a related-games cap, validated IDs), accessibility improvements to the search/reorder UI, a site-wide "Same-genre fallback" toggle, and the fallback match's first move from categories to real taxonomy terms. 1.8.0 renamed the plugin from "GameSync WP Related Posts (Shortcode)" to **GameSync Related Games**, with a new slug/folder (`gamesync-related-games`), every `mrps_`/`MRPS_`/`.mrps-` identifier renamed to `gsrg_`/`GSRG_`/`.gsrg-`, the shortcode tag moved to `[gamesync_related_games]`, and the REST/block namespaces renamed to match -- the shared `related_posts` postmeta key itself was deliberately left unchanged, preserving compatibility with the original third-party "Manual Related Posts" plugin's saved data. Full version-by-version detail is in the plugin's bundled README.md.
