=== MARC21 Bibliographic Importer ===
Contributors:      saptarshighosh
Tags:               marc21, isbd, library, bibliographic, catalogue
Requires at least:  6.2
Tested up to:       7.2
Requires PHP:       7.4
Stable tag:         1.1.2
License:            GPL-2.0+
License URI:        http://www.gnu.org/licenses/gpl-2.0.txt

Import binary MARC21 (.mrc) files into WordPress and display records
via shortcodes in ISBD or MARC21 format.

== Description ==

MARC21 Bibliographic Importer lets library professionals:

* Upload binary ISO 2709 MARC21 (.mrc) files through the WordPress admin.
* Parse and store all bibliographic records in a custom database table.
* Display records on any page or post using simple shortcodes.
* Choose between ISBD citation format, full MARC21 field table, or both.
* Search and filter the catalogue by title, author, or subject headings.

Built by the LIS Software Lab (https://lissoftware.in), a project of the
Department of Library and Information Science, University of North Bengal.

=== ISBD Display ===
Records are formatted following ISBD (International Standard Bibliographic
Description) punctuation rules:

  Author. Title : subtitle / statement of responsibility. –
  Edition. – Place : Publisher, Year. – Pagination. – (Series)
  ISBN  ISSN  Notes  Subject headings

=== MARC21 Display ===
All fields are displayed in a structured table showing tag, indicators,
subfield codes ($a, $b …) and data — identical to how catalogue records
appear in library management systems.

== Installation ==

1. Upload the `marc21-bibliographic` folder to `/wp-content/plugins/`.
2. Activate the plugin through the 'Plugins' menu in WordPress.
3. The custom database table is created automatically on activation.
4. Go to **MARC21 Biblio → Import** and upload your .mrc file.
5. Use the shortcodes below on any page or post.

== Shortcodes ==

=== [marc21_catalog] ===
Full paginated catalogue with a search bar.

Attributes:
  format      isbd | marc21 | both        (default: isbd)
  limit       integer                      (default: 10)
  orderby     title | author | pub_year    (default: title)
  order       ASC | DESC                   (default: ASC)
  show_search yes | no                     (default: yes)
  search      pre-fill search query
  author      filter by author name
  subject     filter by subject heading

Examples:
  [marc21_catalog]
  [marc21_catalog format="marc21" limit="25"]
  [marc21_catalog format="both" author="Ranganathan"]
  [marc21_catalog subject="Library science" show_search="no"]

=== [marc21_record id="X"] ===
Display a single record by its database ID.

Attributes:
  id      (required) database row ID — visible in Browse Records page
  format  isbd | marc21 | both  (default: isbd)

Example:
  [marc21_record id="42"]
  [marc21_record id="5" format="marc21"]

=== [marc21_search] ===
AJAX-powered live search box (no page reload).

Attributes:
  format   isbd | marc21 | both  (default: isbd)
  limit    integer                (default: 10)
  orderby  title | author         (default: title)

Example:
  [marc21_search format="isbd" limit="5"]

== Database Schema ==

Table: {prefix}marc21_records

  id, record_id, leader, title, title_sub, author,
  edition, place_pub, publisher, pub_year, pagination,
  series, isbn, issn, notes, subjects, language,
  record_type, marc_json, imported_at

The full raw record is stored as JSON in marc_json, enabling
future format extensions without re-importing.

== MARC Fields Mapped ==

  001  → record_id
  100$a, 110$a, 700$a → author
  245$a → title
  245$b → title_sub
  250$a → edition
  260$a / 264$a → place of publication
  260$b / 264$b → publisher
  260$c / 264$c → year of publication
  300$a → pagination
  490$a → series
  020$a → ISBN
  022$a → ISSN
  500$a → notes (all occurrences joined)
  650$a → subjects (all occurrences joined with |)
  LDR/06 → record_type
  LDR/35-37 → language code

== Frequently Asked Questions ==

= What MARC21 file format is supported? =
Binary ISO 2709 (.mrc) files only. MARCXML is not currently supported.

= Can I import multiple files? =
Yes. Import as many times as you need. Use the duplicate-handling option
(Skip / Replace / Add) to control what happens with repeat record IDs.

= How do I find the DB id for [marc21_record]? =
Go to MARC21 Biblio → Browse Records. The "DB ID" column shows each record's id.

= Does the plugin affect my existing WordPress tables? =
No. It creates only one additional table: {prefix}marc21_records.

= Is the display OPAC-standard? =
ISBD display follows ISBD 2011 consolidated edition punctuation.
MARC21 display follows the Library of Congress MARC21 bibliographic format.

== Changelog ==

= 1.1.2 =
* Nested the $wpdb->prepare() calls directly inside get_var()/get_results() in
  MARC21_DB::query_records() instead of assigning the prepared query to an
  intermediate variable first, so static analysis unambiguously recognizes every
  query as prepared at its point of use.
* Added justified ignore comments on $wpdb->delete() (no core wrapper exists for
  deleting a single row from a custom table).

= 1.1.1 =
* Removed a hidden file (languages/.gitkeep) that WordPress.org disallows in plugin packages.
* Rewrote MARC21_DB::query_records() to use a single fully-static WHERE clause (every
  filter always present in the literal SQL text, each an "%s = ''" / "%d = 0" no-op
  when unused) instead of dynamically assembling the WHERE text — this keeps every
  placeholder statically visible to $wpdb->prepare() so argument counts always match.
* Added a justified ignore comment on $wpdb->insert() (no core wrapper exists for
  writing to a custom table).

= 1.1.0 =
* Fixed Text Domain to match the plugin slug (marc21-bibliographic) throughout the plugin.
* Added an existing /languages folder for the Domain Path header.
* Escaped all remaining dynamic output (record counts, notices, sequence numbers).
* Added nonce-check justification comments on read-only GET pagination/search params.
* Validated and sanitized uploaded file data ($_FILES) before use.
* Rewrote all custom-table SQL to always go through $wpdb->prepare(), including table
  names via the %i identifier placeholder (requires WordPress 6.2+).
* Fixed readme.txt: valid Contributors username, current Tested-up-to, Stable tag
  matching the plugin Version header.

= 1.0.0 =
* Initial release.
* Binary MARC21 parser (ISO 2709).
* ISBD and MARC21 display modes.
* AJAX live-search shortcode.
* Paginated catalogue shortcode.
* Admin import, browse, delete, settings.

== Upgrade Notice ==

= 1.1.2 =
Resolves remaining static-analysis flags on the custom-table query builder. Please update.

= 1.1.1 =
Fixes a hidden-file packaging issue and tightens custom-table SQL for full static-analysis compliance. Please update.

= 1.1.0 =
Security, escaping, and internationalization fixes; requires WordPress 6.2+. Please update.
