Changeset 3751048
- Timestamp:
- 10/16/2026 07:51:27 PM (4 weeks ago)
- Location:
- airworthy
- Files:
-
- 3 added
- 22 edited
- 1 copied
-
assets/screenshot-7.png (added)
-
tags/1.0.1 (copied) (copied from airworthy/trunk )
-
tags/1.0.1/airworthy.php (modified) (2 diffs)
-
tags/1.0.1/assets/admin.css (modified) (1 diff)
-
tags/1.0.1/assets/admin.js (modified) (3 diffs)
-
tags/1.0.1/readme.txt (modified) (6 diffs)
-
tags/1.0.1/sbom.cdx.json (modified) (2 diffs)
-
tags/1.0.1/src/Admin/Page.php (modified) (1 diff)
-
tags/1.0.1/src/Admin/Review.php (added)
-
tags/1.0.1/src/Cli/Command.php (modified) (1 diff)
-
tags/1.0.1/src/Installer.php (modified) (1 diff)
-
tags/1.0.1/src/Rest/Controller.php (modified) (1 diff)
-
tags/1.0.1/src/Targets.php (modified) (1 diff)
-
tags/1.0.1/vendor/composer/installed.php (modified) (1 diff)
-
trunk/airworthy.php (modified) (2 diffs)
-
trunk/assets/admin.css (modified) (1 diff)
-
trunk/assets/admin.js (modified) (3 diffs)
-
trunk/readme.txt (modified) (6 diffs)
-
trunk/sbom.cdx.json (modified) (2 diffs)
-
trunk/src/Admin/Page.php (modified) (1 diff)
-
trunk/src/Admin/Review.php (added)
-
trunk/src/Cli/Command.php (modified) (1 diff)
-
trunk/src/Installer.php (modified) (1 diff)
-
trunk/src/Rest/Controller.php (modified) (1 diff)
-
trunk/src/Targets.php (modified) (1 diff)
-
trunk/vendor/composer/installed.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
airworthy/tags/1.0.1/airworthy.php
r3722113 r3751048 4 4 * Plugin URI: https://airworthywp.com 5 5 * Description: Before you upgrade PHP, see which plugins and themes are ready, which need fixing, and which look abandoned. 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 6.9 8 8 * Requires PHP: 7.2 … … 25 25 } 26 26 27 define( 'AIRWORTHY_VERSION', '1.0. 0' );27 define( 'AIRWORTHY_VERSION', '1.0.1' ); 28 28 define( 'AIRWORTHY_FILE', __FILE__ ); 29 29 define( 'AIRWORTHY_DIR', plugin_dir_path( __FILE__ ) ); -
airworthy/tags/1.0.1/assets/admin.css
r3722113 r3751048 1200 1200 box-shadow: 0 1px 2px rgba(23, 71, 166, 0.3); 1201 1201 } 1202 1203 /* "Did Airworthy help?" below a finished scan's results. */ 1204 1205 .airworthy-wrap .airworthy-review { 1206 border-left: 4px solid #2f74e8; 1207 } 1208 1209 .airworthy-review p { 1210 max-width: 46rem; 1211 } 1212 1213 .airworthy-review-actions { 1214 display: flex; 1215 flex-wrap: wrap; 1216 gap: 16px; 1217 align-items: center; 1218 } 1219 1220 .airworthy-head-actions { 1221 flex-wrap: wrap; 1222 } -
airworthy/tags/1.0.1/assets/admin.js
r3722113 r3751048 1443 1443 { class: 'airworthy-head-actions' }, 1444 1444 el( 'a', { class: 'button', href: scan.export_url }, __( 'Export CSV', 'airworthy' ) ), 1445 el( 1446 'button', 1447 { type: 'button', class: 'button airworthy-copy-summary', onclick: function ( event ) { 1448 copySummary( scan, components, event.currentTarget ); 1449 } }, 1450 __( 'Copy summary', 'airworthy' ) 1451 ), 1445 1452 ( config.resultsActions || [] ).map( 1446 1453 function ( a ) { … … 1535 1542 } 1536 1543 ) : el( 'tbody', null, el( 'tr', null, el( 'td', { colspan: 5 }, __( 'No plugins or themes were checked in this scan.', 'airworthy' ) ) ) ) 1537 ) 1544 ), 1545 'complete' === scan.status && config.review ? reviewCard() : null 1538 1546 ); 1539 1547 show( 'results' ); … … 1549 1557 } 1550 1558 watchWporg( scan ); 1559 } 1560 1561 /** 1562 * A plain-text summary of the results, for an email or support ticket to a host or 1563 * developer: the overall answer, then each plugin and theme grouped by what to do next. 1564 */ 1565 function summaryText( scan, components ) { 1566 var counts = {}; 1567 components.forEach( 1568 function ( c ) { 1569 counts[ c.verdict ] = ( counts[ c.verdict ] || 0 ) + 1; 1570 } 1571 ); 1572 var needs = counts.blocker || 0; 1573 var overall = 'complete' !== scan.status ? 1574 __( 'The scan was stopped before it finished, so these results are incomplete.', 'airworthy' ) : 1575 ( needs ? 1576 /* translators: 1: number of plugins/themes, 2: PHP version. */ 1577 sprintf( _n( '%1$d plugin or theme needs attention before the upgrade to PHP %2$s.', '%1$d plugins or themes need attention before the upgrade to PHP %2$s.', needs, 'airworthy' ), needs, scan.target_php ) : 1578 ( counts.unknown ? 1579 /* translators: %s: PHP version. */ 1580 sprintf( __( 'Nothing found that would break on PHP %s, but some files could not be checked.', 'airworthy' ), scan.target_php ) : 1581 /* translators: %s: PHP version. */ 1582 sprintf( __( 'Nothing found that would break on PHP %s.', 'airworthy' ), scan.target_php ) ) ); 1583 1584 var lines = [ 1585 /* translators: %s: PHP version. */ 1586 sprintf( __( 'Airworthy check for PHP %s', 'airworthy' ), scan.target_php ), 1587 [ 1588 /* translators: %s: date and time. */ 1589 scan.finished_at ? sprintf( __( 'Checked %s', 'airworthy' ), formatDateTime( scan.finished_at ) ) : '', 1590 /* translators: %s: PHP version. */ 1591 sprintf( __( 'server runs PHP %s', 'airworthy' ), scan.host_php ), 1592 ].filter( Boolean ).join( ' · ' ), 1593 '', 1594 overall, 1595 ]; 1596 1597 resultGroups( scan, components ).forEach( 1598 function ( g ) { 1599 lines.push( '', g.title + ':' ); 1600 if ( 'good' === g.key ) { 1601 var names = g.items.map( 1602 function ( c ) { 1603 return c.name; 1604 } 1605 ); 1606 lines.push( names.join( ', ' ) ); 1607 return; 1608 } 1609 g.items.forEach( 1610 function ( c ) { 1611 var notes = []; 1612 if ( c.verdict && VERDICTS[ c.verdict ] ) { 1613 notes.push( VERDICTS[ c.verdict ].label ); 1614 } 1615 if ( c.update ) { 1616 /* translators: %s: version number. */ 1617 notes.push( sprintf( __( 'update available: %s', 'airworthy' ), c.update.version ) ); 1618 } 1619 if ( c.wporg && 'closed' === c.wporg.status ) { 1620 notes.push( __( 'removed from WordPress.org', 'airworthy' ) ); 1621 } else if ( c.wporg && c.wporg.abandoned ) { 1622 notes.push( __( 'looks abandoned', 'airworthy' ) ); 1623 } 1624 if ( c.wporg && c.wporg.requires_php_blocker ) { 1625 /* translators: %s: PHP version. */ 1626 notes.push( sprintf( __( 'requires PHP %s', 'airworthy' ), c.wporg.requires_php ) ); 1627 } 1628 lines.push( '- ' + c.name + ( c.version ? ' ' + c.version : '' ) + ( notes.length ? ' (' + notes.join( ', ' ) + ')' : '' ) ); 1629 } 1630 ); 1631 } 1632 ); 1633 1634 lines.push( 1635 '', 1636 __( 'Airworthy reads the code without running it, so test the new PHP version on a staging copy before switching the live site.', 'airworthy' ), 1637 /* translators: %s: link to Airworthy on WordPress.org. */ 1638 sprintf( __( 'Checked with Airworthy (free): %s', 'airworthy' ), config.pluginUrl || 'https://wordpress.org/plugins/airworthy/' ) 1639 ); 1640 return lines.join( '\n' ); 1641 } 1642 1643 /** 1644 * Copies the summary, and says so on the button for a moment. Falls back to a hidden text 1645 * box where the clipboard API isn't available (admin screens served over plain http). 1646 */ 1647 function copySummary( scan, components, button ) { 1648 var text = summaryText( scan, components ); 1649 var done = function () { 1650 var label = button.textContent; 1651 button.textContent = __( 'Copied', 'airworthy' ); 1652 announce( __( 'Summary copied. Paste it into an email or support ticket.', 'airworthy' ) ); 1653 setTimeout( 1654 function () { 1655 button.textContent = label; 1656 }, 1657 2500 1658 ); 1659 }; 1660 var fallback = function () { 1661 var box = el( 'textarea', { class: 'screen-reader-text', readonly: 'readonly' } ); 1662 box.value = text; 1663 document.body.appendChild( box ); 1664 box.select(); 1665 var ok = false; 1666 try { 1667 ok = document.execCommand( 'copy' ); 1668 } catch ( e ) { 1669 ok = false; 1670 } 1671 document.body.removeChild( box ); 1672 if ( ok ) { 1673 done(); 1674 } else { 1675 window.prompt( __( 'Copy the summary:', 'airworthy' ), text ); 1676 } 1677 }; 1678 if ( navigator.clipboard && window.isSecureContext ) { 1679 navigator.clipboard.writeText( text ).then( done, fallback ); 1680 } else { 1681 fallback(); 1682 } 1683 } 1684 1685 /** 1686 * "Did Airworthy help?" below the results of a finished scan. Asked once per user: Leave a 1687 * review and Don't ask again end it, Maybe later asks again in 30 days. 1688 */ 1689 function reviewCard() { 1690 var card = null; 1691 var answer = function ( choice ) { 1692 config.review = null; // Not again on this page. 1693 if ( card && card.parentNode ) { 1694 card.parentNode.removeChild( card ); 1695 } 1696 apiFetch( { path: REST + '/review', method: 'POST', data: { choice: choice } } ).catch( function () {} ); 1697 if ( 'done' !== choice ) { 1698 announce( __( 'Thanks. Airworthy won\'t ask again for now.', 'airworthy' ) ); 1699 } 1700 }; 1701 card = el( 1702 'div', 1703 { class: 'airworthy-card airworthy-review' }, 1704 el( 'h3', null, __( 'Did Airworthy help?', 'airworthy' ) ), 1705 el( 'p', null, __( 'Airworthy is free. A short review on WordPress.org helps other site owners find it before their own PHP upgrade, and takes about a minute.', 'airworthy' ) ), 1706 el( 1707 'p', 1708 { class: 'airworthy-review-actions' }, 1709 el( 1710 'a', 1711 { class: 'button button-primary', href: config.review.url, target: '_blank', rel: 'noopener', onclick: function () { 1712 answer( 'done' ); 1713 } }, 1714 __( 'Leave a review', 'airworthy' ), 1715 el( 'span', { class: 'screen-reader-text' }, __( '(opens in a new tab)', 'airworthy' ) ) 1716 ), 1717 el( 1718 'button', 1719 { type: 'button', class: 'button-link', onclick: function () { 1720 answer( 'later' ); 1721 } }, 1722 __( 'Maybe later', 'airworthy' ) 1723 ), 1724 el( 1725 'button', 1726 { type: 'button', class: 'button-link', onclick: function () { 1727 answer( 'never' ); 1728 } }, 1729 __( 'Don\'t ask again', 'airworthy' ) 1730 ) 1731 ) 1732 ); 1733 return card; 1551 1734 } 1552 1735 -
airworthy/tags/1.0.1/readme.txt
r3739681 r3751048 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.2 7 Stable tag: 1.0. 07 Stable tag: 1.0.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 22 22 23 23 * **A verdict for every plugin and theme.** Blocker, Unknown, Suppressed, Guarded, Warnings or Ready, each with one plain sentence explaining what it means for you. 24 * **Fewer false alarms.** Many plugins carry old code that only runs on old PHP versions, behind a version check. Airworthy recognises those checks and marks that code as guarded instead of broken. In our test of the 30 most popular plugins, this cut the plugins flagged as broken from 4 to 2, and in both the flagged codereally would fail on PHP 8.24 * **Fewer false alarms.** Many plugins carry old code that only runs on old PHP versions, behind a version check. Airworthy recognises those checks and marks that code as guarded instead of broken. In our test of the 30 most popular plugins, this cut the plugins flagged as broken from 4 to 2, and both of those contain code that really would fail on PHP 8. 25 25 * **Maintenance signals from WordPress.org (if you allow it).** Plugins that were closed (removed from the directory), not updated in two years, not tested with recent WordPress versions, or that need a newer PHP version than you picked are called out. 26 26 * **Know what to do next.** Results are grouped into fix before you upgrade, keep an eye on, and all good. Plugins with an update waiting say so, with a one-click update, and Airworthy checks them again once they're updated. 27 27 * **Know how long you have.** Airworthy shows when your server's PHP version stops getting security fixes, so you can plan the upgrade before it's urgent. 28 * **The details when you want them.** Every finding shows the file, the line and what changed in PHP. Filter by verdict, rescan one plugin after an update, or download everything as a CSV file for your developer or host.28 * **The details when you want them.** Every finding shows the file, the line and what changed in PHP. Filter by verdict, rescan one plugin after an update, copy a plain-text summary to paste into an email or support ticket, or download everything as a CSV file for your developer or host. 29 29 * **Sensible default.** Airworthy recommends the oldest PHP version that still gets security fixes: the smallest upgrade that keeps your site protected. It shows every version's support dates. 30 30 * **Safe on any host.** Scans run in the background in short batches, so they never time out, and they watch memory use. You can leave the page while a scan runs. Nothing is changed on your site. … … 32 32 * **In Site Health too.** Tools > Site Health shows whether your plugins and themes are ready for the next PHP version, with a link to the full results. 33 33 * **Multisite ready.** On a network, Airworthy is activated network-wide and lives under Network Admin > Settings. 34 35 = For freelancers and agencies = 36 37 Hosts are moving sites off old PHP versions, and every client asks the same question: will my site break? Install Airworthy on each client site before the host's deadline (it's free, on as many sites as you like), and you have an answer per plugin in minutes. Copy summary gives you a plain-text list to paste into the client email or the host's support ticket, the CSV has every finding for your developer, and the Site Health check keeps showing whether the site is ready for the next PHP version. For many sites at once, use WP-CLI. 34 38 35 39 = WP-CLI = … … 136 140 That menu comes from Action Scheduler, the background-job library Airworthy uses (WooCommerce uses the same one). It's harmless, and lists Airworthy's jobs under the "airworthy" group. 137 141 142 = Can I use Airworthy on client sites? = 143 144 Yes. Airworthy is free and GPL-licensed, with no limit on sites and no account. Agencies often run it from WP-CLI (`wp airworthy scan --target=8.4 --fail-on=blocker`) across all their sites, and use Copy summary or the CSV export for each client. 145 138 146 = How do I report a security problem? = 139 147 … … 148 156 5. Settings: skip inactive plugins, never check chosen plugins or themes, and pick a scan speed that suits your hosting. Changes save as you make them. 149 157 6. A PHP upgrade check in Tools > Site Health, next to WordPress's own checks. 158 7. The same check from WP-CLI, for agencies looking after many sites. 150 159 151 160 == Changelog == 161 162 = 1.0.1 = 163 * New: Copy summary, next to Export CSV on the results. Copies a plain-text summary (the overall answer, then each plugin and theme grouped by what to do next, with updates waiting and closed plugins) to paste into an email or support ticket for your host or developer. 164 * New: after a finished scan, the results ask once whether you'd leave a review on WordPress.org. Maybe later asks again in 30 days; Don't ask again means never. It only appears on Airworthy's own screen, below the results. 165 * PHP support dates checked against php.net on 16 October 2026: PHP 8.2 gets security fixes until 31 December 2026. 166 * WP-CLI: the note about problems that already apply on your current PHP version now says how to list them (`wp airworthy results --fields=name,verdict,existing`); it pointed to a column the scan table doesn't show. 152 167 153 168 = 1.0.0 = … … 167 182 == Upgrade Notice == 168 183 184 = 1.0.1 = 185 Adds Copy summary on the results, for sending to your host or developer. 186 169 187 = 1.0.0 = 170 188 First release. -
airworthy/tags/1.0.1/sbom.cdx.json
r3722113 r3751048 4 4 "version": 1, 5 5 "metadata": { 6 "timestamp": "2026- 09-30T21:58:36Z",6 "timestamp": "2026-10-16T19:45:22Z", 7 7 "component": { 8 8 "type": "application", 9 "bom-ref": "pkg:wordpress-plugin/airworthy@1.0. 0",9 "bom-ref": "pkg:wordpress-plugin/airworthy@1.0.1", 10 10 "name": "airworthy", 11 "version": "1.0. 0",11 "version": "1.0.1", 12 12 "description": "Airworthy – PHP Compatibility & Upgrade Checker (WordPress plugin)", 13 13 "licenses": [ … … 209 209 "dependencies": [ 210 210 { 211 "ref": "pkg:wordpress-plugin/airworthy@1.0. 0",211 "ref": "pkg:wordpress-plugin/airworthy@1.0.1", 212 212 "dependsOn": [ 213 213 "pkg:composer/phpcompatibility/php-compatibility@10.0.0-alpha2", -
airworthy/tags/1.0.1/src/Admin/Page.php
r3722113 r3751048 82 82 'cronDisabled' => defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON, 83 83 'resultsActions' => self::results_actions(), 84 'review' => Review::config(), 85 'pluginUrl' => 'https://wordpress.org/plugins/airworthy/', 84 86 ) 85 87 ) . ';', -
airworthy/tags/1.0.1/src/Cli/Command.php
r3722113 r3751048 529 529 $existing = array_sum( wp_list_pluck( $this->components( $scan_id ), 'existing' ) ); 530 530 if ( $existing && ! empty( $scan->from_php ) ) { 531 WP_CLI::log( sprintf( '%1$d problems already apply on PHP %2$s, so they are not caused by this upgrade (see the "existing" column).', $existing, $scan->from_php ) ); 531 WP_CLI::log( 532 sprintf( 533 1 === $existing ? 534 '%1$d problem already applies on PHP %2$s, so it is not caused by this upgrade. To see where: wp airworthy results --fields=name,verdict,existing' : 535 '%1$d problems already apply on PHP %2$s, so they are not caused by this upgrade. To see where: wp airworthy results --fields=name,verdict,existing', 536 $existing, 537 $scan->from_php 538 ) 539 ); 532 540 } 533 541 if ( in_array( $scan->wporg_status, array( 'offline', 'partial' ), true ) ) { -
airworthy/tags/1.0.1/src/Installer.php
r3722113 r3751048 199 199 delete_site_option( $option ); 200 200 } 201 \Airworthy\Admin\Review::forget_all(); // Each user's answer to the review request. 201 202 202 203 // Cached WordPress.org lookups. They're site transients, which live in the options table -
airworthy/tags/1.0.1/src/Rest/Controller.php
r3722113 r3751048 217 217 'permission_callback' => $can, 218 218 'args' => array( 'id' => $id ), 219 ) 220 ); 221 register_rest_route( 222 $ns, 223 '/review', 224 array( 225 'methods' => 'POST', 226 'callback' => array( \Airworthy\Admin\Review::class, 'rest_answer' ), 227 'permission_callback' => $can, 228 'args' => array( 229 'choice' => array( 230 'required' => true, 231 'type' => 'string', 232 'enum' => \Airworthy\Admin\Review::CHOICES, 233 'description' => __( 'The user\'s answer to the review request: done, later or never.', 'airworthy' ), 234 ), 235 ), 219 236 ) 220 237 ); -
airworthy/tags/1.0.1/src/Targets.php
r3722113 r3751048 38 38 39 39 /** When SECURITY_UNTIL was last checked against php.net. */ 40 const TABLE_CHECKED = '2026- 09-29';40 const TABLE_CHECKED = '2026-10-16'; 41 41 42 42 /** -
airworthy/tags/1.0.1/vendor/composer/installed.php
r3722113 r3751048 3 3 namespace Airworthy\Vendor; 4 4 5 return array('root' => array('name' => 'digitalkind/airworthy', 'pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => ' 8ed4539c1fdedf95361a42ed753e4a4897ecf320', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('dealerdirect/phpcodesniffer-composer-installer' => array('pretty_version' => 'v1.2.1', 'version' => '1.2.1.0', 'reference' => '963f0c67bffde0eac41b56be71ac0e8ba132f0bd', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../dealerdirect/phpcodesniffer-composer-installer', 'aliases' => array(), 'dev_requirement' => \false), 'digitalkind/airworthy' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '8ed4539c1fdedf95361a42ed753e4a4897ecf320', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/php-compatibility' => array('pretty_version' => '10.0.0-alpha2', 'version' => '10.0.0.0-alpha2', 'reference' => 'e0f0e5a3dc819a4a0f8d679a0f2453d941976e18', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/php-compatibility', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-paragonie' => array('pretty_version' => '2.0.0-alpha2', 'version' => '2.0.0.0-alpha2', 'reference' => '7a979711c87d8202b52f56c56bd719d09d8ed7f5', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-paragonie', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-wp' => array('pretty_version' => '3.0.0-alpha2', 'version' => '3.0.0.0-alpha2', 'reference' => 'bd53f24e7528422ac51d64dc8d53e8d4c4a877b3', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-wp', 'aliases' => array(), 'dev_requirement' => \false), 'phpcsstandards/phpcsutils' => array('pretty_version' => '1.2.3', 'version' => '1.2.3.0', 'reference' => '5f35d9408c54d7b529501f3c688b6eae562aea1f', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcsstandards/phpcsutils', 'aliases' => array(), 'dev_requirement' => \false), 'squizlabs/php_codesniffer' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => 'bbdc3d0532623e21838b7041a4364383a8126f96', 'type' => 'library', 'install_path' => __DIR__ . '/../squizlabs/php_codesniffer', 'aliases' => array(), 'dev_requirement' => \false), 'wimg/php-compatibility' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'woocommerce/action-scheduler' => array('pretty_version' => '4.2.0', 'version' => '4.2.0.0', 'reference' => '9e2c6b02e89652bade4445ea2ca5fb12e0fa7242', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../woocommerce/action-scheduler', 'aliases' => array(), 'dev_requirement' => \false)));5 return array('root' => array('name' => 'digitalkind/airworthy', 'pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '9c9a53d3656967dc5abc254b265e07368204d493', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('dealerdirect/phpcodesniffer-composer-installer' => array('pretty_version' => 'v1.2.1', 'version' => '1.2.1.0', 'reference' => '963f0c67bffde0eac41b56be71ac0e8ba132f0bd', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../dealerdirect/phpcodesniffer-composer-installer', 'aliases' => array(), 'dev_requirement' => \false), 'digitalkind/airworthy' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '9c9a53d3656967dc5abc254b265e07368204d493', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/php-compatibility' => array('pretty_version' => '10.0.0-alpha2', 'version' => '10.0.0.0-alpha2', 'reference' => 'e0f0e5a3dc819a4a0f8d679a0f2453d941976e18', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/php-compatibility', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-paragonie' => array('pretty_version' => '2.0.0-alpha2', 'version' => '2.0.0.0-alpha2', 'reference' => '7a979711c87d8202b52f56c56bd719d09d8ed7f5', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-paragonie', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-wp' => array('pretty_version' => '3.0.0-alpha2', 'version' => '3.0.0.0-alpha2', 'reference' => 'bd53f24e7528422ac51d64dc8d53e8d4c4a877b3', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-wp', 'aliases' => array(), 'dev_requirement' => \false), 'phpcsstandards/phpcsutils' => array('pretty_version' => '1.2.3', 'version' => '1.2.3.0', 'reference' => '5f35d9408c54d7b529501f3c688b6eae562aea1f', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcsstandards/phpcsutils', 'aliases' => array(), 'dev_requirement' => \false), 'squizlabs/php_codesniffer' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => 'bbdc3d0532623e21838b7041a4364383a8126f96', 'type' => 'library', 'install_path' => __DIR__ . '/../squizlabs/php_codesniffer', 'aliases' => array(), 'dev_requirement' => \false), 'wimg/php-compatibility' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'woocommerce/action-scheduler' => array('pretty_version' => '4.2.0', 'version' => '4.2.0.0', 'reference' => '9e2c6b02e89652bade4445ea2ca5fb12e0fa7242', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../woocommerce/action-scheduler', 'aliases' => array(), 'dev_requirement' => \false))); -
airworthy/trunk/airworthy.php
r3722113 r3751048 4 4 * Plugin URI: https://airworthywp.com 5 5 * Description: Before you upgrade PHP, see which plugins and themes are ready, which need fixing, and which look abandoned. 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 6.9 8 8 * Requires PHP: 7.2 … … 25 25 } 26 26 27 define( 'AIRWORTHY_VERSION', '1.0. 0' );27 define( 'AIRWORTHY_VERSION', '1.0.1' ); 28 28 define( 'AIRWORTHY_FILE', __FILE__ ); 29 29 define( 'AIRWORTHY_DIR', plugin_dir_path( __FILE__ ) ); -
airworthy/trunk/assets/admin.css
r3722113 r3751048 1200 1200 box-shadow: 0 1px 2px rgba(23, 71, 166, 0.3); 1201 1201 } 1202 1203 /* "Did Airworthy help?" below a finished scan's results. */ 1204 1205 .airworthy-wrap .airworthy-review { 1206 border-left: 4px solid #2f74e8; 1207 } 1208 1209 .airworthy-review p { 1210 max-width: 46rem; 1211 } 1212 1213 .airworthy-review-actions { 1214 display: flex; 1215 flex-wrap: wrap; 1216 gap: 16px; 1217 align-items: center; 1218 } 1219 1220 .airworthy-head-actions { 1221 flex-wrap: wrap; 1222 } -
airworthy/trunk/assets/admin.js
r3722113 r3751048 1443 1443 { class: 'airworthy-head-actions' }, 1444 1444 el( 'a', { class: 'button', href: scan.export_url }, __( 'Export CSV', 'airworthy' ) ), 1445 el( 1446 'button', 1447 { type: 'button', class: 'button airworthy-copy-summary', onclick: function ( event ) { 1448 copySummary( scan, components, event.currentTarget ); 1449 } }, 1450 __( 'Copy summary', 'airworthy' ) 1451 ), 1445 1452 ( config.resultsActions || [] ).map( 1446 1453 function ( a ) { … … 1535 1542 } 1536 1543 ) : el( 'tbody', null, el( 'tr', null, el( 'td', { colspan: 5 }, __( 'No plugins or themes were checked in this scan.', 'airworthy' ) ) ) ) 1537 ) 1544 ), 1545 'complete' === scan.status && config.review ? reviewCard() : null 1538 1546 ); 1539 1547 show( 'results' ); … … 1549 1557 } 1550 1558 watchWporg( scan ); 1559 } 1560 1561 /** 1562 * A plain-text summary of the results, for an email or support ticket to a host or 1563 * developer: the overall answer, then each plugin and theme grouped by what to do next. 1564 */ 1565 function summaryText( scan, components ) { 1566 var counts = {}; 1567 components.forEach( 1568 function ( c ) { 1569 counts[ c.verdict ] = ( counts[ c.verdict ] || 0 ) + 1; 1570 } 1571 ); 1572 var needs = counts.blocker || 0; 1573 var overall = 'complete' !== scan.status ? 1574 __( 'The scan was stopped before it finished, so these results are incomplete.', 'airworthy' ) : 1575 ( needs ? 1576 /* translators: 1: number of plugins/themes, 2: PHP version. */ 1577 sprintf( _n( '%1$d plugin or theme needs attention before the upgrade to PHP %2$s.', '%1$d plugins or themes need attention before the upgrade to PHP %2$s.', needs, 'airworthy' ), needs, scan.target_php ) : 1578 ( counts.unknown ? 1579 /* translators: %s: PHP version. */ 1580 sprintf( __( 'Nothing found that would break on PHP %s, but some files could not be checked.', 'airworthy' ), scan.target_php ) : 1581 /* translators: %s: PHP version. */ 1582 sprintf( __( 'Nothing found that would break on PHP %s.', 'airworthy' ), scan.target_php ) ) ); 1583 1584 var lines = [ 1585 /* translators: %s: PHP version. */ 1586 sprintf( __( 'Airworthy check for PHP %s', 'airworthy' ), scan.target_php ), 1587 [ 1588 /* translators: %s: date and time. */ 1589 scan.finished_at ? sprintf( __( 'Checked %s', 'airworthy' ), formatDateTime( scan.finished_at ) ) : '', 1590 /* translators: %s: PHP version. */ 1591 sprintf( __( 'server runs PHP %s', 'airworthy' ), scan.host_php ), 1592 ].filter( Boolean ).join( ' · ' ), 1593 '', 1594 overall, 1595 ]; 1596 1597 resultGroups( scan, components ).forEach( 1598 function ( g ) { 1599 lines.push( '', g.title + ':' ); 1600 if ( 'good' === g.key ) { 1601 var names = g.items.map( 1602 function ( c ) { 1603 return c.name; 1604 } 1605 ); 1606 lines.push( names.join( ', ' ) ); 1607 return; 1608 } 1609 g.items.forEach( 1610 function ( c ) { 1611 var notes = []; 1612 if ( c.verdict && VERDICTS[ c.verdict ] ) { 1613 notes.push( VERDICTS[ c.verdict ].label ); 1614 } 1615 if ( c.update ) { 1616 /* translators: %s: version number. */ 1617 notes.push( sprintf( __( 'update available: %s', 'airworthy' ), c.update.version ) ); 1618 } 1619 if ( c.wporg && 'closed' === c.wporg.status ) { 1620 notes.push( __( 'removed from WordPress.org', 'airworthy' ) ); 1621 } else if ( c.wporg && c.wporg.abandoned ) { 1622 notes.push( __( 'looks abandoned', 'airworthy' ) ); 1623 } 1624 if ( c.wporg && c.wporg.requires_php_blocker ) { 1625 /* translators: %s: PHP version. */ 1626 notes.push( sprintf( __( 'requires PHP %s', 'airworthy' ), c.wporg.requires_php ) ); 1627 } 1628 lines.push( '- ' + c.name + ( c.version ? ' ' + c.version : '' ) + ( notes.length ? ' (' + notes.join( ', ' ) + ')' : '' ) ); 1629 } 1630 ); 1631 } 1632 ); 1633 1634 lines.push( 1635 '', 1636 __( 'Airworthy reads the code without running it, so test the new PHP version on a staging copy before switching the live site.', 'airworthy' ), 1637 /* translators: %s: link to Airworthy on WordPress.org. */ 1638 sprintf( __( 'Checked with Airworthy (free): %s', 'airworthy' ), config.pluginUrl || 'https://wordpress.org/plugins/airworthy/' ) 1639 ); 1640 return lines.join( '\n' ); 1641 } 1642 1643 /** 1644 * Copies the summary, and says so on the button for a moment. Falls back to a hidden text 1645 * box where the clipboard API isn't available (admin screens served over plain http). 1646 */ 1647 function copySummary( scan, components, button ) { 1648 var text = summaryText( scan, components ); 1649 var done = function () { 1650 var label = button.textContent; 1651 button.textContent = __( 'Copied', 'airworthy' ); 1652 announce( __( 'Summary copied. Paste it into an email or support ticket.', 'airworthy' ) ); 1653 setTimeout( 1654 function () { 1655 button.textContent = label; 1656 }, 1657 2500 1658 ); 1659 }; 1660 var fallback = function () { 1661 var box = el( 'textarea', { class: 'screen-reader-text', readonly: 'readonly' } ); 1662 box.value = text; 1663 document.body.appendChild( box ); 1664 box.select(); 1665 var ok = false; 1666 try { 1667 ok = document.execCommand( 'copy' ); 1668 } catch ( e ) { 1669 ok = false; 1670 } 1671 document.body.removeChild( box ); 1672 if ( ok ) { 1673 done(); 1674 } else { 1675 window.prompt( __( 'Copy the summary:', 'airworthy' ), text ); 1676 } 1677 }; 1678 if ( navigator.clipboard && window.isSecureContext ) { 1679 navigator.clipboard.writeText( text ).then( done, fallback ); 1680 } else { 1681 fallback(); 1682 } 1683 } 1684 1685 /** 1686 * "Did Airworthy help?" below the results of a finished scan. Asked once per user: Leave a 1687 * review and Don't ask again end it, Maybe later asks again in 30 days. 1688 */ 1689 function reviewCard() { 1690 var card = null; 1691 var answer = function ( choice ) { 1692 config.review = null; // Not again on this page. 1693 if ( card && card.parentNode ) { 1694 card.parentNode.removeChild( card ); 1695 } 1696 apiFetch( { path: REST + '/review', method: 'POST', data: { choice: choice } } ).catch( function () {} ); 1697 if ( 'done' !== choice ) { 1698 announce( __( 'Thanks. Airworthy won\'t ask again for now.', 'airworthy' ) ); 1699 } 1700 }; 1701 card = el( 1702 'div', 1703 { class: 'airworthy-card airworthy-review' }, 1704 el( 'h3', null, __( 'Did Airworthy help?', 'airworthy' ) ), 1705 el( 'p', null, __( 'Airworthy is free. A short review on WordPress.org helps other site owners find it before their own PHP upgrade, and takes about a minute.', 'airworthy' ) ), 1706 el( 1707 'p', 1708 { class: 'airworthy-review-actions' }, 1709 el( 1710 'a', 1711 { class: 'button button-primary', href: config.review.url, target: '_blank', rel: 'noopener', onclick: function () { 1712 answer( 'done' ); 1713 } }, 1714 __( 'Leave a review', 'airworthy' ), 1715 el( 'span', { class: 'screen-reader-text' }, __( '(opens in a new tab)', 'airworthy' ) ) 1716 ), 1717 el( 1718 'button', 1719 { type: 'button', class: 'button-link', onclick: function () { 1720 answer( 'later' ); 1721 } }, 1722 __( 'Maybe later', 'airworthy' ) 1723 ), 1724 el( 1725 'button', 1726 { type: 'button', class: 'button-link', onclick: function () { 1727 answer( 'never' ); 1728 } }, 1729 __( 'Don\'t ask again', 'airworthy' ) 1730 ) 1731 ) 1732 ); 1733 return card; 1551 1734 } 1552 1735 -
airworthy/trunk/readme.txt
r3739681 r3751048 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.2 7 Stable tag: 1.0. 07 Stable tag: 1.0.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 22 22 23 23 * **A verdict for every plugin and theme.** Blocker, Unknown, Suppressed, Guarded, Warnings or Ready, each with one plain sentence explaining what it means for you. 24 * **Fewer false alarms.** Many plugins carry old code that only runs on old PHP versions, behind a version check. Airworthy recognises those checks and marks that code as guarded instead of broken. In our test of the 30 most popular plugins, this cut the plugins flagged as broken from 4 to 2, and in both the flagged codereally would fail on PHP 8.24 * **Fewer false alarms.** Many plugins carry old code that only runs on old PHP versions, behind a version check. Airworthy recognises those checks and marks that code as guarded instead of broken. In our test of the 30 most popular plugins, this cut the plugins flagged as broken from 4 to 2, and both of those contain code that really would fail on PHP 8. 25 25 * **Maintenance signals from WordPress.org (if you allow it).** Plugins that were closed (removed from the directory), not updated in two years, not tested with recent WordPress versions, or that need a newer PHP version than you picked are called out. 26 26 * **Know what to do next.** Results are grouped into fix before you upgrade, keep an eye on, and all good. Plugins with an update waiting say so, with a one-click update, and Airworthy checks them again once they're updated. 27 27 * **Know how long you have.** Airworthy shows when your server's PHP version stops getting security fixes, so you can plan the upgrade before it's urgent. 28 * **The details when you want them.** Every finding shows the file, the line and what changed in PHP. Filter by verdict, rescan one plugin after an update, or download everything as a CSV file for your developer or host.28 * **The details when you want them.** Every finding shows the file, the line and what changed in PHP. Filter by verdict, rescan one plugin after an update, copy a plain-text summary to paste into an email or support ticket, or download everything as a CSV file for your developer or host. 29 29 * **Sensible default.** Airworthy recommends the oldest PHP version that still gets security fixes: the smallest upgrade that keeps your site protected. It shows every version's support dates. 30 30 * **Safe on any host.** Scans run in the background in short batches, so they never time out, and they watch memory use. You can leave the page while a scan runs. Nothing is changed on your site. … … 32 32 * **In Site Health too.** Tools > Site Health shows whether your plugins and themes are ready for the next PHP version, with a link to the full results. 33 33 * **Multisite ready.** On a network, Airworthy is activated network-wide and lives under Network Admin > Settings. 34 35 = For freelancers and agencies = 36 37 Hosts are moving sites off old PHP versions, and every client asks the same question: will my site break? Install Airworthy on each client site before the host's deadline (it's free, on as many sites as you like), and you have an answer per plugin in minutes. Copy summary gives you a plain-text list to paste into the client email or the host's support ticket, the CSV has every finding for your developer, and the Site Health check keeps showing whether the site is ready for the next PHP version. For many sites at once, use WP-CLI. 34 38 35 39 = WP-CLI = … … 136 140 That menu comes from Action Scheduler, the background-job library Airworthy uses (WooCommerce uses the same one). It's harmless, and lists Airworthy's jobs under the "airworthy" group. 137 141 142 = Can I use Airworthy on client sites? = 143 144 Yes. Airworthy is free and GPL-licensed, with no limit on sites and no account. Agencies often run it from WP-CLI (`wp airworthy scan --target=8.4 --fail-on=blocker`) across all their sites, and use Copy summary or the CSV export for each client. 145 138 146 = How do I report a security problem? = 139 147 … … 148 156 5. Settings: skip inactive plugins, never check chosen plugins or themes, and pick a scan speed that suits your hosting. Changes save as you make them. 149 157 6. A PHP upgrade check in Tools > Site Health, next to WordPress's own checks. 158 7. The same check from WP-CLI, for agencies looking after many sites. 150 159 151 160 == Changelog == 161 162 = 1.0.1 = 163 * New: Copy summary, next to Export CSV on the results. Copies a plain-text summary (the overall answer, then each plugin and theme grouped by what to do next, with updates waiting and closed plugins) to paste into an email or support ticket for your host or developer. 164 * New: after a finished scan, the results ask once whether you'd leave a review on WordPress.org. Maybe later asks again in 30 days; Don't ask again means never. It only appears on Airworthy's own screen, below the results. 165 * PHP support dates checked against php.net on 16 October 2026: PHP 8.2 gets security fixes until 31 December 2026. 166 * WP-CLI: the note about problems that already apply on your current PHP version now says how to list them (`wp airworthy results --fields=name,verdict,existing`); it pointed to a column the scan table doesn't show. 152 167 153 168 = 1.0.0 = … … 167 182 == Upgrade Notice == 168 183 184 = 1.0.1 = 185 Adds Copy summary on the results, for sending to your host or developer. 186 169 187 = 1.0.0 = 170 188 First release. -
airworthy/trunk/sbom.cdx.json
r3722113 r3751048 4 4 "version": 1, 5 5 "metadata": { 6 "timestamp": "2026- 09-30T21:58:36Z",6 "timestamp": "2026-10-16T19:45:22Z", 7 7 "component": { 8 8 "type": "application", 9 "bom-ref": "pkg:wordpress-plugin/airworthy@1.0. 0",9 "bom-ref": "pkg:wordpress-plugin/airworthy@1.0.1", 10 10 "name": "airworthy", 11 "version": "1.0. 0",11 "version": "1.0.1", 12 12 "description": "Airworthy – PHP Compatibility & Upgrade Checker (WordPress plugin)", 13 13 "licenses": [ … … 209 209 "dependencies": [ 210 210 { 211 "ref": "pkg:wordpress-plugin/airworthy@1.0. 0",211 "ref": "pkg:wordpress-plugin/airworthy@1.0.1", 212 212 "dependsOn": [ 213 213 "pkg:composer/phpcompatibility/php-compatibility@10.0.0-alpha2", -
airworthy/trunk/src/Admin/Page.php
r3722113 r3751048 82 82 'cronDisabled' => defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON, 83 83 'resultsActions' => self::results_actions(), 84 'review' => Review::config(), 85 'pluginUrl' => 'https://wordpress.org/plugins/airworthy/', 84 86 ) 85 87 ) . ';', -
airworthy/trunk/src/Cli/Command.php
r3722113 r3751048 529 529 $existing = array_sum( wp_list_pluck( $this->components( $scan_id ), 'existing' ) ); 530 530 if ( $existing && ! empty( $scan->from_php ) ) { 531 WP_CLI::log( sprintf( '%1$d problems already apply on PHP %2$s, so they are not caused by this upgrade (see the "existing" column).', $existing, $scan->from_php ) ); 531 WP_CLI::log( 532 sprintf( 533 1 === $existing ? 534 '%1$d problem already applies on PHP %2$s, so it is not caused by this upgrade. To see where: wp airworthy results --fields=name,verdict,existing' : 535 '%1$d problems already apply on PHP %2$s, so they are not caused by this upgrade. To see where: wp airworthy results --fields=name,verdict,existing', 536 $existing, 537 $scan->from_php 538 ) 539 ); 532 540 } 533 541 if ( in_array( $scan->wporg_status, array( 'offline', 'partial' ), true ) ) { -
airworthy/trunk/src/Installer.php
r3722113 r3751048 199 199 delete_site_option( $option ); 200 200 } 201 \Airworthy\Admin\Review::forget_all(); // Each user's answer to the review request. 201 202 202 203 // Cached WordPress.org lookups. They're site transients, which live in the options table -
airworthy/trunk/src/Rest/Controller.php
r3722113 r3751048 217 217 'permission_callback' => $can, 218 218 'args' => array( 'id' => $id ), 219 ) 220 ); 221 register_rest_route( 222 $ns, 223 '/review', 224 array( 225 'methods' => 'POST', 226 'callback' => array( \Airworthy\Admin\Review::class, 'rest_answer' ), 227 'permission_callback' => $can, 228 'args' => array( 229 'choice' => array( 230 'required' => true, 231 'type' => 'string', 232 'enum' => \Airworthy\Admin\Review::CHOICES, 233 'description' => __( 'The user\'s answer to the review request: done, later or never.', 'airworthy' ), 234 ), 235 ), 219 236 ) 220 237 ); -
airworthy/trunk/src/Targets.php
r3722113 r3751048 38 38 39 39 /** When SECURITY_UNTIL was last checked against php.net. */ 40 const TABLE_CHECKED = '2026- 09-29';40 const TABLE_CHECKED = '2026-10-16'; 41 41 42 42 /** -
airworthy/trunk/vendor/composer/installed.php
r3722113 r3751048 3 3 namespace Airworthy\Vendor; 4 4 5 return array('root' => array('name' => 'digitalkind/airworthy', 'pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => ' 8ed4539c1fdedf95361a42ed753e4a4897ecf320', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('dealerdirect/phpcodesniffer-composer-installer' => array('pretty_version' => 'v1.2.1', 'version' => '1.2.1.0', 'reference' => '963f0c67bffde0eac41b56be71ac0e8ba132f0bd', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../dealerdirect/phpcodesniffer-composer-installer', 'aliases' => array(), 'dev_requirement' => \false), 'digitalkind/airworthy' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '8ed4539c1fdedf95361a42ed753e4a4897ecf320', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/php-compatibility' => array('pretty_version' => '10.0.0-alpha2', 'version' => '10.0.0.0-alpha2', 'reference' => 'e0f0e5a3dc819a4a0f8d679a0f2453d941976e18', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/php-compatibility', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-paragonie' => array('pretty_version' => '2.0.0-alpha2', 'version' => '2.0.0.0-alpha2', 'reference' => '7a979711c87d8202b52f56c56bd719d09d8ed7f5', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-paragonie', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-wp' => array('pretty_version' => '3.0.0-alpha2', 'version' => '3.0.0.0-alpha2', 'reference' => 'bd53f24e7528422ac51d64dc8d53e8d4c4a877b3', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-wp', 'aliases' => array(), 'dev_requirement' => \false), 'phpcsstandards/phpcsutils' => array('pretty_version' => '1.2.3', 'version' => '1.2.3.0', 'reference' => '5f35d9408c54d7b529501f3c688b6eae562aea1f', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcsstandards/phpcsutils', 'aliases' => array(), 'dev_requirement' => \false), 'squizlabs/php_codesniffer' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => 'bbdc3d0532623e21838b7041a4364383a8126f96', 'type' => 'library', 'install_path' => __DIR__ . '/../squizlabs/php_codesniffer', 'aliases' => array(), 'dev_requirement' => \false), 'wimg/php-compatibility' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'woocommerce/action-scheduler' => array('pretty_version' => '4.2.0', 'version' => '4.2.0.0', 'reference' => '9e2c6b02e89652bade4445ea2ca5fb12e0fa7242', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../woocommerce/action-scheduler', 'aliases' => array(), 'dev_requirement' => \false)));5 return array('root' => array('name' => 'digitalkind/airworthy', 'pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '9c9a53d3656967dc5abc254b265e07368204d493', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('dealerdirect/phpcodesniffer-composer-installer' => array('pretty_version' => 'v1.2.1', 'version' => '1.2.1.0', 'reference' => '963f0c67bffde0eac41b56be71ac0e8ba132f0bd', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../dealerdirect/phpcodesniffer-composer-installer', 'aliases' => array(), 'dev_requirement' => \false), 'digitalkind/airworthy' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '9c9a53d3656967dc5abc254b265e07368204d493', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/php-compatibility' => array('pretty_version' => '10.0.0-alpha2', 'version' => '10.0.0.0-alpha2', 'reference' => 'e0f0e5a3dc819a4a0f8d679a0f2453d941976e18', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/php-compatibility', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-paragonie' => array('pretty_version' => '2.0.0-alpha2', 'version' => '2.0.0.0-alpha2', 'reference' => '7a979711c87d8202b52f56c56bd719d09d8ed7f5', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-paragonie', 'aliases' => array(), 'dev_requirement' => \false), 'phpcompatibility/phpcompatibility-wp' => array('pretty_version' => '3.0.0-alpha2', 'version' => '3.0.0.0-alpha2', 'reference' => 'bd53f24e7528422ac51d64dc8d53e8d4c4a877b3', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcompatibility/phpcompatibility-wp', 'aliases' => array(), 'dev_requirement' => \false), 'phpcsstandards/phpcsutils' => array('pretty_version' => '1.2.3', 'version' => '1.2.3.0', 'reference' => '5f35d9408c54d7b529501f3c688b6eae562aea1f', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../phpcsstandards/phpcsutils', 'aliases' => array(), 'dev_requirement' => \false), 'squizlabs/php_codesniffer' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => 'bbdc3d0532623e21838b7041a4364383a8126f96', 'type' => 'library', 'install_path' => __DIR__ . '/../squizlabs/php_codesniffer', 'aliases' => array(), 'dev_requirement' => \false), 'wimg/php-compatibility' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'woocommerce/action-scheduler' => array('pretty_version' => '4.2.0', 'version' => '4.2.0.0', 'reference' => '9e2c6b02e89652bade4445ea2ca5fb12e0fa7242', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../woocommerce/action-scheduler', 'aliases' => array(), 'dev_requirement' => \false)));
Note:
See TracChangeset
for help on using the changeset viewer.