Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AffiBridge

WordPress plugin that converts Moshimo affiliate scripts and Amazon Associates links into safe, reusable shortcodes.

Requirements

Dependency Minimum Tested up to
WordPress 5.0 6.8
PHP 8.1
jQuery (bundled with WordPress)

No external libraries. No Composer. No npm. Shared-hosting compatible.

Features

  • Moshimo Affiliate — Transform complex Moshimo affiliate scripts into simple shortcodes
  • Amazon Associates — Create product cards from Amazon Associates links (product name + URL + optional image)
  • Ad-Block Resistant Card — Custom HTML card output ([affi_card], [amazon_card]) that bypasses ad blockers
  • Centralized Management — Separate admin pages for Moshimo and Amazon with full CRUD
  • Script Analysis — Analyze and validate Moshimo affiliate scripts before saving
  • Click Tracking — Track affiliate link clicks with optional Google Analytics integration
  • Performance Caching — Transient-based caching (1-hour TTL) for faster shortcode rendering
  • Clean Uninstall — All plugin data is removed upon uninstallation

Installation

Manual

  1. Upload the affi-bridge directory to wp-content/plugins/.
  2. Activate through Plugins > Installed Plugins.
  3. Navigate to AffiBridge in the admin menu.

No build step required. No configuration files to edit. The plugin is ready to use immediately after activation.

Configuration

No configuration files, environment variables, or constants need to be set. All settings are managed through WordPress filters (see Filters section).

Usage

Adding a Moshimo affiliate link

  1. Go to AffiBridge > もしもアフィリエイト in the admin menu.
  2. Enter a unique name (e.g., biore-product) and paste the Moshimo affiliate script.
  3. Optionally click Analyze Script to verify the script.
  4. Click Generate Shortcode.

Adding an Amazon Associates link

  1. Go to AffiBridge > Amazonアソシエイト in the admin menu.
  2. Enter a unique name (e.g., echo-dot-5), the product name, and the Amazon Associates link URL.
  3. Optionally enter a product image URL (if omitted, the card switches to a compact horizontal layout).
  4. Click ショートコードを生成.

Shortcodes

Shortcode Output Ad-blocker resistance
[affi_link id="name"] Original Moshimo <script> block Low
[affi_card id="name"] Custom HTML product card (Moshimo) High
[amazon_card id="name"] Custom HTML product card (Amazon) High

Shortcodes can be used in posts, pages, text widgets, custom HTML blocks, and template files (do_shortcode()).

Managing existing shortcodes

  • View — See the original affiliate script / link details
  • Edit — Modify the affiliate script or link data inline; changes take effect immediately (cache is auto-cleared)
  • Copy — Copy the shortcode to clipboard
  • Delete — Remove a shortcode permanently

Architecture

affi-bridge.php               Main plugin – admin UI, AJAX, [affi_link] shortcode
uninstall.php                 Database cleanup on plugin deletion

src/
├── Autoloader.php            PSR-4 autoloader for AffiBridge\ namespace
├── ValidationResult.php      Immutable DTO – validation outcome
├── ScriptValidator.php       Validates raw Moshimo script blocks
├── ParsedButton.php          Immutable DTO – single affiliate button
├── ParsedScript.php          Immutable DTO – full parsed script data
├── ScriptParser.php          Extracts structured data from validated scripts
├── CardRenderer.php          Renders safe, CSP-compatible HTML cards (Moshimo)
├── CardHandler.php           WP integration for [affi_card] – caching, styles, tracking
├── AmazonCardRenderer.php    Renders Amazon product cards (vertical or horizontal layout)
└── AmazonCardHandler.php     WP integration for [amazon_card] – caching

assets/
├── css/admin.css             Admin dashboard styles
└── js/admin.js               Admin dashboard behaviour (Moshimo + Amazon)

Data flow

Moshimo script input              Amazon link input
       │                          (product name + URL + image URL)
       ▼                                    │
 ScriptValidator                            ▼
       │                            URL validation
       ▼                                    │
   (stored in DB as raw script)     (stored in DB as JSON)
       │                                    │
   ┌───┴───┐                                │
   ▼       ▼                                ▼
[affi_link]  [affi_card]             [amazon_card]
   │           │                            │
   │       ScriptParser             AmazonCardRenderer
   │           │                            │
   │       CardRenderer                     ▼
   │           │                    safe HTML card
   ▼           ▼                    (horizontal compact if no image)
raw script   safe HTML card

Security model

Validation (ScriptValidator)

Every script must pass all of these checks before it is stored:

  1. Comment markers<!-- START MoshimoAffiliateEasyLink -->END -->
  2. Single <script> tag – exactly one; multiple tags are rejected
  3. Official CDN – the script tag must reference dn.msmstatic.com
  4. msmaflink() call – the known Moshimo function must be present
  5. Valid JSON payload – extracted via brace-depth counting, decoded with json_decode
  6. Required keysn, u, b_l, eid, s must all be present and non-empty
  7. No unsafe content – outside the <script> block, no extra scripts, javascript: URIs, event handlers, or dangerous tags (<iframe>, <object>, etc.)

Validation is deterministic and order-independent of WordPress hooks.

Rendering (CardRenderer)

  • No inline scripts in the HTML output
  • No event-handler attributes (onclick, etc.)
  • No remote resource loads from the rendered card
  • Every dynamic value is escaped: esc_html(), esc_attr(), esc_url()
  • Output is CSP-compatible (no unsafe-inline requirement from card HTML)

Rendering (AmazonCardRenderer)

  • Same security guarantees as CardRenderer (no inline scripts, full escaping)
  • Image URL provided — vertical card layout (image on top, product name, button below)
  • Image URL empty — compact horizontal card layout (product name left, button right). On mobile (640px and below) the horizontal card falls back to vertical stacking.

Storage

All data is stored as custom post type (affi_bridge_link) entries. Moshimo entries store raw script in post_content with _affi_bridge_link_type = moshimo post meta. Amazon entries store JSON ({"product_name", "url", "image_url"}) in post_content with _affi_bridge_link_type = amazon post meta. Legacy Moshimo entries without the type meta are treated as Moshimo (backward compatible via NOT EXISTS queries). All admin operations require manage_options capability and pass nonce verification.

Filters

Filter Type Description
affi_bridge_custom_validation ?array{valid: bool, message?: string} Short-circuit validation — must return valid (bool) and message (string, required when valid is false); malformed returns are ignored
affi_bridge_allowed_markers string[] Accepted comment-marker identifiers
affi_bridge_required_params string[] Required JSON keys
affi_bridge_card_styles string Override card CSS
affi_bridge_card_html string Post-process rendered card HTML
affi_bridge_card_tracking_enabled bool Enable/disable click tracking
affi_bridge_card_tracking_script string Override tracking JS
affi_bridge_card_show_footer bool Show affiliate-ID footer

FAQ

What is Moshimo Affiliate? Moshimo Affiliate is a Japanese affiliate marketing platform that provides affiliate links for Rakuten, Amazon, Yahoo! Shopping, and other online stores.

Which affiliate networks are supported? Moshimo Affiliate (もしもアフィリエイト) and Amazon Associates (Amazonアソシエイト). Moshimo scripts are validated against Moshimo-specific format. Amazon links are entered manually (product name + URL + optional image).

What is the difference between affi_link, affi_card, and amazon_card? [affi_link] outputs the original Moshimo script as-is. [affi_card] parses the Moshimo script and renders a custom HTML card with product image, title, brand, and platform-specific buttons. [amazon_card] renders a product card for Amazon Associates links. The card shortcodes are resistant to ad blockers because they use standard HTML instead of third-party scripts.

What happens when I don't provide an image URL for Amazon cards? The card automatically switches to a compact horizontal layout — product name on the left, Amazon button on the right. No placeholder or "NO IMAGE" text is shown. On mobile screens (640px and below) the horizontal card falls back to vertical stacking.

What happens to my data if I uninstall the plugin? All stored affiliate link data, click tracking statistics, and cached data will be permanently removed from the database.

Will the shortcodes work if I deactivate the plugin? No. The shortcodes require the plugin to be active.

Privacy

When click tracking is enabled (default), the plugin records the following data per click:

  • Click timestamp
  • Platform name and URL
  • Visitor IP address (REMOTE_ADDR only)
  • Visitor user agent string

Data is stored locally in wp_options, limited to the most recent 1,000 entries. No data is transmitted to external servers by the plugin itself. Moshimo affiliate link clicks redirect through Moshimo's servers (af.moshimo.com). Amazon affiliate link clicks redirect through Amazon's servers.

Click tracking can be disabled via the affi_bridge_card_tracking_enabled filter.

Error handling

  • Invalid Moshimo script — Validation rejects the input with a specific error message (missing markers, malformed JSON, etc.). The script is not stored.
  • Invalid Amazon URLesc_url_raw() returns empty string for malformed URLs. The AJAX handler returns an error response.
  • Shortcode with unknown ID — Returns empty string. No error output to the frontend.
  • Malformed JSON in Amazon post_contentjson_decode returns null. The shortcode returns empty string.
  • Transient cache miss — Falls through to database query. No user-visible impact.
  • AJAX without valid nonce — WordPress returns 403. The JS displays an error notice.
  • AJAX without manage_options capability — Returns JSON error with "Permission denied" message.
  • wp_insert_post / wp_update_post failure — Returns WP_Error. The AJAX handler returns a JSON error response.

All AJAX error responses use wp_send_json_error() with a message key. The admin JS displays errors via a dismissible notice bar.

Assumptions

  • The WordPress installation has a working database with standard table structure (wp_posts, wp_postmeta, wp_options).
  • jQuery is available (bundled with WordPress core).
  • PHP json_encode / json_decode functions are available (standard since PHP 5.2).
  • manage_options capability maps to administrator-level users.
  • Moshimo affiliate scripts follow the official format with msmaflink() call and JSON payload.
  • Amazon Associates link URLs are provided by the user as-is. No URL format validation beyond esc_url_raw().

Non-goals

  • This plugin does not fetch product data from Amazon's Product Advertising API.
  • This plugin does not auto-generate affiliate tracking IDs.
  • This plugin does not support affiliate networks other than Moshimo and Amazon Associates.
  • This plugin does not provide analytics dashboards. Click tracking data is stored in wp_options but no UI is provided to view it.
  • This plugin does not validate whether Amazon URLs contain valid affiliate tags.
  • This plugin does not handle multisite network-wide activation (it operates per-site).

Limitations

  • Click tracking stores a maximum of 1,000 entries in a single wp_options row. Older entries are discarded.
  • Shortcode output is cached in WordPress transients with a 1-hour TTL. Edits clear the cache immediately, but external transient purges may cause a re-query.
  • The [affi_link] shortcode outputs raw Moshimo scripts. The content is re-validated with ScriptValidator at render time; scripts that no longer pass validation return empty output.
  • The affi_bridge_custom_validation filter can short-circuit validation. The filter return value must include a valid (bool) key and, when false, a message (string) key; malformed return values are ignored and standard validation runs instead.
  • Moshimo script storage requires the unfiltered_html capability. On multisite, only super-admins have this capability by default.

Development

# Syntax check (requires PHP 8.1+)
php -l affi-bridge.php
php -l uninstall.php
find src/ -name '*.php' -exec php -l {} \;

Changelog

2.1.4

  • Fix: Replaced <h3> tags in card shortcode output ([affi_card], [amazon_card]) with <span> to avoid heading hierarchy conflicts with WordPress themes

2.1.3

  • Security: [affi_link] shortcode now re-validates stored script content at render time via ScriptValidator; invalid content returns empty output instead of raw HTML
  • Security: [affi_link] transient cache is invalidated when cached content no longer passes validation
  • Security: affi_bridge_custom_validation filter return value is now strictly validated — must contain valid (bool) key; malformed returns are ignored and standard validation runs
  • Security: Moshimo script save/edit AJAX handlers now require unfiltered_html capability; users without this capability receive an explicit error instead of silent content stripping by wp_kses_post
  • Security: post_int() helper changed from (int) cast to absint() to reject negative values
  • Security: Removed Google Fonts @import from card stylesheets — eliminates third-party resource load that leaked visitor IPs to Google on every frontend page
  • Security: Admin JS no_results messages are now HTML-escaped via escapeHtml() before DOM insertion
  • Performance: Card styles and tracking JS are now registered on all frontend pages but only enqueued when a card shortcode ([affi_card] or [amazon_card]) is actually rendered
  • Hardening: Uninstall SQL queries for postmeta cleanup now use $wpdb->prepare() for consistency with WordPress coding standards

2.1.2

  • Fixed load_textdomain never executing — the callback was registered on plugins_loaded during plugins_loaded execution, making it unreliable; moved to init priority 1
  • Fixed [affi_card] shortcode missing _affi_bridge_link_type filter — could match Amazon entries and output raw JSON to the page
  • Fixed [affi_card] returning raw post_content (Moshimo script HTML) when script parsing failed; now returns empty string

2.1.1

  • Amazon cards: image-less cards now use compact horizontal layout (product name left, button right) instead of hiding the image section
  • Added mobile responsive fallback (640px) for horizontal cards — falls back to vertical stacking
  • Fixed ajax_get_links() returning Amazon entries on Moshimo admin page (added type meta filter)
  • Fixed [affi_link] shortcode potentially outputting Amazon JSON data (added type guard)
  • New Moshimo entries now set _affi_bridge_link_type = moshimo meta symmetrically with Amazon entries
  • Added explicit CSS dependency for AmazonCardHandler with fallback styles when CardHandler is inactive
  • Added missing admin CSS for Amazon-specific selectors (#amazon-name-check-result, .amazon-detail-row, .amazon-edit-row)

2.1.0

  • Added Amazon Associates support ([amazon_card] shortcode)
  • Added separate admin page for Amazon links (AffiBridge > Amazonアソシエイト)
  • Restructured admin menu to sub-menu layout (もしもアフィリエイト / Amazonアソシエイト)
  • Amazon cards: product name + link URL + optional image URL — horizontal compact layout when image is omitted
  • Added AmazonCardRenderer and AmazonCardHandler classes
  • Added _affi_bridge_link_type post meta to distinguish Moshimo and Amazon entries
  • Updated uninstall cleanup for Amazon transients and meta

2.0.0

  • Migrated all classes to PSR-4 namespaces (AffiBridge\ namespace)
  • Added custom PSR-4 autoloader (src/Autoloader.php) — no Composer required
  • Moved card handler to src/CardHandler.php (was class-affi-bridge-card.php)
  • Replaced manual require_once calls with autoloader
  • Bumped minimum PHP requirement to 8.1

1.1.0

  • Added inline editing for existing affiliate scripts
  • Added ad-block resistant custom card shortcode ([affi_card])
  • Added click tracking with optional Google Analytics integration
  • Added transient-based caching for shortcode output (1-hour TTL)
  • Fixed asset loading paths (CSS/JS were not loading)
  • Fixed post type verification on delete to prevent unintended deletions
  • Added capability checks to all AJAX endpoints
  • Added type-safe POST input handling (is_string guards with strict_types)
  • Hardened IP detection to use only REMOTE_ADDR
  • Changed click stats storage to non-autoloaded option
  • Improved uninstall cleanup: click stats, transient caches, multisite deduplication
  • Codebase modernized to PHP 8.1+ strict types throughout

1.0.0

  • Initial release

License

GPL v2 or later. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages