Recent Commits to wp-pluginsused:master

  • 26/07/2026 13:27

    Move template-tags.php and deprecated.php under includes/

    Move template-tags.php and deprecated.php under includes/
    
    They were the only loose PHP left in the plugin root, which is inconsistent
    with the rest of the collection: wp-useronline keeps both under includes/
    (638001f), and wp-pagenavi and wp-polls do the same with template-tags.php.
    Only the three files WordPress requires to be there stay at the root -- the
    main plugin file, uninstall.php, and the index.php silence guard.
    
    Adds a test pinning that layout, so the next file cannot quietly land in the
    root again.
    
    Verified after the move: 115 tests single-site and multisite, the Playground
    harness 84/84 on PHP 7.4 / WP 6.0 and PHP 8.3 / WP latest, and a deploy dry-run
    confirming the shipped tree is the same 12 files in their new places.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo
  • 26/07/2026 13:20

    Cover multisite in CI and bin/test.sh

    Cover multisite in CI and bin/test.sh
    
    The suite passed as multisite already; nothing was pinning it that way, so
    nothing would have caught a regression. Two behaviours only exist on a network:
    uninstall.php branches on is_multisite(), and network-activated plugins are
    read from active_sitewide_plugins, a site option the single-site run never
    touches. Running as a network also makes the uninstall test execute the
    get_sites() loop and the switch_to_blog()/restore_current_blog() pair for real
    rather than only asserting on the source.
    
    WP_MULTISITE is read by the WordPress test bootstrap inside the container, so
    it is forwarded in rather than exported around the npx process.
    
    114 tests / 220 assertions green single-site and multisite.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo
  • 26/07/2026 13:17

    Run CI on Node 24

    Run CI on Node 24
    
    Node 20 went end-of-life in April 2026. This standardises every plugin on 24,
    the current active LTS (Krypton), which wp-polls was already using.
    
    This is the Node that runs npx @wordpress/env for the test suite, not the
    Actions runtime -- that was the separate checkout/setup-node v7 bump -- so it
    had to move on its own.
  • 26/07/2026 13:11

    Bump actions/checkout and actions/setup-node to v7

    Bump actions/checkout and actions/setup-node to v7
    
    GitHub is deprecating Node 20 on Actions runners, so checkout@v4 and
    setup-node@v4 were being force-run on Node 24 and emitting a warning on every
    job. v5 moved these actions to Node 24; v7 is the current major.
    
    Neither breaking change affects this workflow: setup-node v6 limited automatic
    caching to npm, and no cache input is passed here; checkout v7 blocks checking
    out fork PRs for pull_request_target and workflow_run, and this triggers on
    push and pull_request.
    
    shivammathur/setup-php stays at v2 -- that is still its current major and it
    was not in the deprecation warning.
  • 26/07/2026 9:37

    Expand the test suite from 67 to 114 tests

    Expand the test suite from 67 to 114 tests
    
    New coverage:
    
    - test-bootstrap.php: constants agree with the plugin header and the readme
      Stable tag, every code file carries its ABSPATH guard, the classes avoid the
      WP_ prefix core reserves, and the admin hooks are absent on the front end.
    - test-stats.php: the summary sentence pluralises through three independent
      _n() calls, so singular, plural and zero are three code paths. None were
      covered; the singular form had never been rendered by a test.
    - Uninstall is now executed, not just read: it deletes the option for real on
      the single-site branch. Added checks that it references no plugin class or
      function (it runs with the plugin inactive) and that the plugin writes no
      option row other than the one uninstall names.
    - Template: hiding matches whole names rather than substrings, no trailing
      space when the version is suppressed, absent URIs emit no anchor,
      descriptions are still texturized, the per-request cache holds and
      reset_cache() clears it, icons carry role/aria-label and differ by shape,
      and nothing enqueues a script or stylesheet.
    - Settings: a plugin name containing quotes round-trips through the form and
      still matches what it hides, unknown keys are dropped, ticked boxes render
      as checked.
    - Deprecated: the render path must never call a shim, or every page load would
      emit deprecation notices under WP_DEBUG.
    
    Two harness bugs the new tests exposed, both fixed:
    
    - GLOB_BRACE is a GNU extension and is undefined in the container's PHP, so
      three tests errored. Source files are now collected with two glob() calls.
    - Searching raw source matched comments, not code: the docblock in
      class-pluginsused-template.php explaining that pluginsused_format_display()
      forwards to it counted as a call site. Source inspection now goes through
      php_strip_whitespace(), the same fix the uninstall test already needed.
    
    phpcs.xml needed no new exemptions. helper-source.php is split out of
    helper-fixtures.php because a file may declare either functions or a class.
    
    114 tests / 220 assertions green on PHP 7.4 / WP 6.0 and PHP 8.3 / WP latest.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo
  • 26/07/2026 9:18

    Add PHPUnit suite, CI, and update the readme for 2.0.0

    Add PHPUnit suite, CI, and update the readme for 2.0.0
    
    67 tests / 122 assertions against a real WordPress database via wp-env, run
    on both ends of the support matrix (PHP 7.4 / WP 6.0 and PHP 8.3 / WP latest).
    Nothing here ships: plugin_deploy.sh already excludes tests/, bin/,
    phpunit.xml*, composer.*, .wp-env.json and .git*.
    
    The tests drive the plugin's own entry points against fixture plugins written
    to disk, because every defect worth catching here is integration, not logic:
    
    - test-escaping.php parses the output with DOMDocument and asserts no
      event-handler attribute and no javascript: URL survives into the DOM, while
      the hostile name is still displayed as text. Substring matching would be
      wrong: once escaped, "onmouseover=&quot;" still occurs inside an attribute
      value, where it is inert.
    - test-uninstall.php asserts on php_strip_whitespace() output rather than the
      raw file. Matching the raw source passes on the comment that documents
      'number' => 0 and keeps passing after the argument itself is deleted --
      confirmed by deleting it.
    - test-template.php covers the multisite active_sitewide_plugins fix, ordering,
      and that hidden plugins leave the counts as well as the listings.
    
    Every assertion was verified to fail against deliberately broken code.
    
    phpcs.xml relaxes docblock, file-naming and DOM-property rules under tests/
    only, so CI can fail on warnings everywhere else.
    
    Adds .gitignore: wp-env installs dev dependencies into the mounted plugin
    directory, so vendor/ appears on the host and must not be committed.
    
    Readme: documents the settings screen, the three filters and the template tag,
    trims Tags to the five-tag maximum, drops the dead dev.wp-plugins.org
    translations link and the FamFamFam credit for the removed GIFs.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo
  • 26/07/2026 8:54

    Restructure into includes/, add a settings screen, drop the GIF icons

    Restructure into includes/, add a settings screen, drop the GIF icons
    
    Replaces the hand-rolled plugin scanner and the edit-the-source config with
    current WordPress APIs. Behaviour is unchanged: the three shortcodes, the
    display_pluginsused() template tag and the rendered markup all keep working.
    
    - Scanning: get_plugins() replaces the bespoke directory walk and the
      "|Plugin Name:(.*)|i" header regexes, which read whole files and could
      match a "Version:" occurring anywhere in one. Core sorts identically
      (_sort_uname_callback is the same strnatcasecmp on name), so ordering is
      byte-for-byte what it was.
    - Config: settings now live in one option row, pluginsused_options, behind
      Settings -> WP-PluginsUsed. Previously the only way to hide a plugin or a
      version number was to edit wp-pluginsused.php, which every plugin update
      silently reverted. The PLUGINSUSED_SHOW_VERSION constant and the
      $pluginsused_hidden_plugins global are still honoured, and two new filters
      (pluginsused_show_version, pluginsused_hidden_plugins) are applied last.
    - Icons: inline SVG replaces images/plugin_{active,inactive}.gif. They stay
      crisp at any pixel density, inherit the theme's text colour, cost no HTTP
      request, and distinguish state by shape as well as by an aria-label.
    - Multisite: network-activated plugins were listed as inactive, because only
      active_plugins was consulted. active_sitewide_plugins is now merged in.
    - Empty Plugin URI / Author URI no longer emit <a href="">.
    - Drops load_plugin_textdomain(); WordPress has loaded plugin translations
      automatically since 4.6, and since 6.7 an early call triggers _doing_it_wrong.
    - Old procedural functions remain in deprecated.php as working shims.
    
    Layout follows the Plugin Handbook: includes/class-*.php, index.php silence
    guards, an uninstall.php whose multisite loop passes 'number' => 0 and
    restores inside the loop.
    
    Verified with a WordPress Playground harness, 84 assertions, on both PHP 7.4 /
    WP 6.0 and PHP 8.3 / WP latest.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo
  • 26/07/2026 8:40

    Apply WordPress Coding Standards (phpcbf)

    Apply WordPress Coding Standards (phpcbf)
    
    Formatting only, no logic change: 96 violations fixed automatically.
    Adds phpcs.xml so the ruleset is pinned to PHP files (WPCS has had no
    JavaScript sniffs since 3.0) and CI uses the same config as local runs.
    
    Verified against the Playground harness: 33/33 assertions unchanged.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo
  • 26/07/2026 8:39

    Fix stored XSS in plugin listing output

    Fix stored XSS in plugin listing output
    
    pluginsused_format_display() interpolated plugin header values straight
    into href/src/alt/title attributes. strip_tags() was the only filtering
    applied, and it removes tags but leaves quotes, so a plugin whose header
    contains a double quote broke out of the attribute:
    
      Plugin Name: Evil" onmouseover="alert(1)
      Plugin URI:  javascript:alert(2)
    
    rendered as a live onmouseover handler on both the <img> and the <a>,
    plus href="javascript:alert(2)". Escape at each sink with esc_url(),
    esc_attr() and esc_html() instead.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TFsMxKw9RRmE5Kk41hAxYo

Log in