From 74fc683b0a0b24bcd0e84767e5537555503f37af Mon Sep 17 00:00:00 2001 From: Alex Sirota Date: Mon, 11 Nov 2024 18:56:26 -0500 Subject: [PATCH] Updating stable playground-ready branch with latest changes to main (#174) --- .DS_Store | Bin 0 -> 6148 bytes .github/ISSUE_TEMPLATE/BugReport.yml | 148 ++++++++ .github/ISSUE_TEMPLATE/FeatureRequest.yml | 26 ++ .github/ISSUE_TEMPLATE/config.yml | 5 + .github/workflows/phpunit-tests.yml | 5 +- .github/workflows/playground-blueprint.yml | 46 +++ .github/workflows/releases.yml | 22 +- LICENSE.md | 338 ++++++++++++++++++ README.md | 26 +- aspire-update.php | 9 +- assets/css/aspire-update.css | 86 +++++ assets/images/aspirepress-logo-icon.svg | 1 + assets/js/aspire-update.js | 2 +- assets/playground/blueprint.json | 6 +- composer.json | 5 +- includes/class-admin-settings.php | 22 +- includes/class-branding.php | 138 +++++++ includes/class-controller.php | 5 +- languages/AspireUpdate-ca_ES.po | 162 +++++++++ languages/AspireUpdate-de_DE.mo | Bin 2236 -> 3283 bytes languages/AspireUpdate-de_DE.po | 34 +- languages/AspireUpdate-es_ES.po | 145 ++++++++ languages/AspireUpdate-fr_FR.l10n.php | 2 +- languages/AspireUpdate-fr_FR.mo | Bin 2513 -> 3260 bytes languages/AspireUpdate-fr_FR.po | 89 +++-- languages/AspireUpdate-nl_NL.l10n.php | 2 + languages/AspireUpdate-nl_NL.mo | Bin 0 -> 3200 bytes languages/AspireUpdate-nl_NL.po | 165 +++++++++ languages/AspireUpdate-sv_SE.mo | Bin 0 -> 2449 bytes languages/AspireUpdate-sv_SE.po | 134 +++++++ languages/AspireUpdate.pot | 147 ++++---- phpunit.xml.dist | 5 + readme.txt | 81 +++-- .../Branding_AdminEnqueueScriptsTest.php | 109 ++++++ tests/Branding/Branding_ConstructTest.php | 129 +++++++ tests/Branding/Branding_GetInstanceTest.php | 23 ++ .../Branding_OutputAdminNoticeTest.php | 141 ++++++++ tests/bootstrap.php | 1 - tests/multisite.xml | 41 +++ 39 files changed, 2108 insertions(+), 192 deletions(-) create mode 100644 .DS_Store create mode 100644 .github/ISSUE_TEMPLATE/BugReport.yml create mode 100644 .github/ISSUE_TEMPLATE/FeatureRequest.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/workflows/playground-blueprint.yml create mode 100644 LICENSE.md create mode 100644 assets/images/aspirepress-logo-icon.svg create mode 100644 includes/class-branding.php create mode 100644 languages/AspireUpdate-ca_ES.po create mode 100644 languages/AspireUpdate-es_ES.po create mode 100644 languages/AspireUpdate-nl_NL.l10n.php create mode 100644 languages/AspireUpdate-nl_NL.mo create mode 100644 languages/AspireUpdate-nl_NL.po create mode 100644 languages/AspireUpdate-sv_SE.mo create mode 100644 languages/AspireUpdate-sv_SE.po create mode 100644 tests/Branding/Branding_AdminEnqueueScriptsTest.php create mode 100644 tests/Branding/Branding_ConstructTest.php create mode 100644 tests/Branding/Branding_GetInstanceTest.php create mode 100644 tests/Branding/Branding_OutputAdminNoticeTest.php create mode 100644 tests/multisite.xml diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3322548063306d4f8aed84ea3f54f2f5350af4eb GIT binary patch literal 6148 zcmeHKO=}ZD7=9;7+f7R$f`T4|1+OutX%WRs8q43}dXJP`V}AGz zW(3}dE=p~FD={7J7yKfeU;)}Jjiho`@~^|w1LF+-9^y5I(&3Or)oO>Z<yN@7&dM`m2v8Y@pz^P zVK9cvn^$2R$VE@i;~-Jofv#}sPJP(8vs`wL4jwh#PWy1xbeE4i?WTKl_;9tVJGbsV zcyc!W^p8AmW`PWy_6tU453p@=oKb70tUz@loqFl zc;OVqJEapy+NbBh7Pvu?p%zh|v8xuehwo1?IW4q#Rc=M_*z%k$wd~QG^7IQ{E_qL6 zueX`$boQ?IFl_Iw0#<=Ppa7o_E&^lMV5U(W9f;Hu09Zq@GNkzjfjO?huE9(rYG6WB zfto7J6GLb^%3b5vHJEACbQ0$AAxz7{yikN{9p87AJBhAF8(Rge0!0O?I@{p;|K!*2 z|02oetO8bn|4IQ->ks-p49VQBYlGvv)> $GITHUB_ENV + elif [ "${{ github.ref_type }}" == "tag" ]; then + echo "CURRENT_REF=${{ github.ref_name }}" >> $GITHUB_ENV + fi + + - name: Update Blueprint JSON + run: | + jq --tab '.plugins[0] |= "https://github-proxy.com/proxy/?repo='$GITHUB_REPOSITORY'&branch='$CURRENT_REF'"' assets/playground/blueprint.json > assets/playground/blueprint.json.tmp + mv assets/playground/blueprint.json.tmp assets/playground/blueprint.json + + - name: Commit and Push Changes + run: | + if git diff --cached --quiet; then + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add assets/playground/blueprint.json + git commit -m "Update blueprint.json for branch/tag ${{ env.name }}" + git push + fi + env: + name: ${{ env.name }} + diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index e5e3e36..fc72a2a 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -11,33 +11,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@master + uses: actions/checkout@v4 - name: Get tag id: tag run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - name: Build project - run: git archive -o /tmp/AspireUpdate-${{ steps.tag.outputs.tag }}.zip --prefix=AspireUpdate/ ${{ steps.tag.outputs.tag }} + run: git archive -o /tmp/${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}.zip --prefix=${{ github.event.repository.name }}/ ${{ steps.tag.outputs.tag }} - name: Create Release id: create_release - uses: actions/create-release@v1 + uses: softprops/action-gh-release@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ steps.tag.outputs.tag }} - release_name: ${{ steps.tag.outputs.tag }} - draft: false - prerelease: false - - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: /tmp/AspireUpdate-${{ steps.tag.outputs.tag }}.zip - asset_name: AspireUpdate-${{ steps.tag.outputs.tag }}.zip - asset_content_type: application/zip + files: /tmp/${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}.zip diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..30a5c90 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,338 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Moe Ghoul, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README.md b/README.md index 49b5d1d..efbdde1 100644 --- a/README.md +++ b/README.md @@ -34,15 +34,15 @@ The plugin menu appears under the Dashboard main menu item. Don't look for it in The plugin can use the following configuration options in wp-config.php: -| Configuration Parameter | Description | Default, if any | -| :---------------------- | ------------------------------------------------------------------------------------------: | -------------------------------------: | -| AP_ENABLE | Enable API rewrite | false | -| AP_API_KEY | The API Key for AspireCloud (not currently enforced) | | -| AP_HOST | API domain name | api.aspirecloud.org | -| AP_DEBUG | Enable Debug Mode | false | -| AP_DEBUG_TYPES | an array of debug modes | array('string', 'request', 'response') | -| AP_DISABLE_SSL | Disabled SSL verification for local testing | true | -| AP_REMOVE_UI | Disables plugin settings user interface, defaults to config parameters set in wp-config.php | false | +| Configuration Parameter | Description | Default, if any | +| :---------------------- | -------------------------------------------------------------------------------------------------------: | -------------------------------------: | +| AP_ENABLE | Enable API rewrite | false | +| AP_API_KEY | The API Key for AspireCloud (not currently enforced) | | +| AP_HOST | API domain name | api.aspirecloud.org | +| AP_DEBUG | Enable Debug Mode | false | +| AP_DEBUG_TYPES | an array of debug modes | array('string', 'request', 'response') | +| AP_DISABLE_SSL | Disabled SSL verification for local testing | true | +| AP_REMOVE_UI | Disables plugin settings user interface and branding, defaults to config parameters set in wp-config.php | false | To set AP_DEBUG_TYPES use an array to define the constant: @@ -53,13 +53,15 @@ define('AP_DEBUG_TYPES', array( )); ``` -NOTE: Any AspirePress configuration parameters set in wp-config.php _will_ override any plugin options set in the plugin user interface. +NOTE: Any AspirePress configuration parameters set in wp-config.php _will_ override any plugin options set in the plugin user interface. -NOTE 2: Setting AP_REMOVE_UI to `true` removes the plugin user interface. This is intended to be used in situations where AspireUpdate is deployed in a pre-configured mode and end-user configuration is not expected nor allowed. +NOTE 2: Setting AP_REMOVE_UI to `true` removes the plugin user interface. This is intended to be used in situations where AspireUpdate is deployed in a pre-configured mode and end-user configuration is not expected nor allowed. ## WP Playgrounds Support -The AspireUpdate plugin can be quickly [experimented with in the WP Playgrounds environment](https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/aspirepress/AspireUpdate/refs/heads/playground-ready/assets/playground/blueprint.json). +The AspireUpdate current build ('main' branch) can be [experimented with in the WP Playground environment](https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/aspirepress/AspireUpdate/refs/heads/main/assets/playground/blueprint.json). + +The AspireUpdate stable build ('playground-ready' branch) can be [tested with in the WP Playground environment](https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/aspirepress/AspireUpdate/refs/heads/playground-ready/assets/playground/blueprint.json). ## Debug Logging diff --git a/aspire-update.php b/aspire-update.php index da28371..aca98c5 100644 --- a/aspire-update.php +++ b/aspire-update.php @@ -5,7 +5,7 @@ * @package aspire-update * @author AspireUpdate * @copyright AspireUpdate - * @license GPL-3.0-or-later + * @license GPLv2 * * Plugin Name: AspireUpdate * Plugin URI: https://aspirepress.org/ @@ -16,11 +16,12 @@ * Requires at least: 5.3 * Requires PHP: 7.4 * Tested up to: 6.7 - * License: GPL-3.0-or-later - * License URI: https://www.gnu.org/licenses/gpl-3.0.txt + * License: GPLv2 + * License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * Text Domain: AspireUpdate * Domain Path: /languages - * Network: true + * GitHub Plugin URI: https://github.com/aspirepress/AspireUpdate + * Primary Branch: main */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/assets/css/aspire-update.css b/assets/css/aspire-update.css index c8d1825..06856c1 100644 --- a/assets/css/aspire-update.css +++ b/assets/css/aspire-update.css @@ -1,3 +1,89 @@ +@keyframes glow { + 0% { + background-color: rgba(255, 223, 0, 0.1); + } + + 100% { + background-color: none; + } +} + +.glow-reveal { + animation: glow 0.5s ease-in-out; +} + +.aspireupdate-settings-field-hosts-wrapper .aspireupdate-settings-field-hosts-row { + margin: 0 0 10px; +} + +#aspireupdate-generate-api-key { + display: inline-block; + width: 30px; + height: 30px; + background: url(../images/icon-key.svg) no-repeat center center / 24px 24px; + background-color: #cbcbcb; + border: 1px solid #8c8f94; + border-radius: 3px; + clip-path: inset(0 0 0 0); + color: transparent; + cursor: pointer; + transition: background-color 0.3s ease; +} + +#aspireupdate-generate-api-key:hover { + background-color: #e3e3e3; +} + +.aspireupdate-settings-field-wrapper p.error { + color: #bc3b3b; + display: none; +} + +.aspireupdate-notice { + background-color: #f0f6fc; + border: 1px solid #70b9e3; + border-radius: 50px; + max-width: max-content; +} + +.aspireupdate-notice p::before { + content: ''; + display: inline-block; + margin-inline-end: .5em; + vertical-align: middle; + background: url(../images/aspirepress-logo-icon.svg) no-repeat center center / 20px 20px; + height: 20px; + width: 20px; +} + +#voltron { + color: transparent; + font-size: clamp(4px, 0.9vw, 8px); + line-height: 6px; + display: inline-block; + cursor: default; +} + +#voltron:hover { + animation: blink 1.8s ease-in-out infinite; + animation-delay: 5s; +} + +@keyframes blink { + 0%, + 100% { + color: inherit; + } + 50% { + color: transparent; + } +} + +@media only screen and (max-width: 576px) { + #voltron { + display: none; + } +======= @keyframes glow { 0% { diff --git a/assets/images/aspirepress-logo-icon.svg b/assets/images/aspirepress-logo-icon.svg new file mode 100644 index 0000000..2f2162f --- /dev/null +++ b/assets/images/aspirepress-logo-icon.svg @@ -0,0 +1 @@ + diff --git a/assets/js/aspire-update.js b/assets/js/aspire-update.js index e9f9f42..dd6e76e 100644 --- a/assets/js/aspire-update.js +++ b/assets/js/aspire-update.js @@ -150,7 +150,7 @@ class ApiRewrites { if ((response.status === 400) || (response.status === 401)) { ApiRewrites.api_key.show_error(response.responseJSON?.error); } else { - ApiRewrites.api_key.show_error('Unexpected Error: ' + response.status); + ApiRewrites.api_key.show_error(aspireupdate.string_unexpected_error + ' ' + response.status); } }); }, diff --git a/assets/playground/blueprint.json b/assets/playground/blueprint.json index d9e8453..c7d4e99 100644 --- a/assets/playground/blueprint.json +++ b/assets/playground/blueprint.json @@ -17,7 +17,7 @@ "blogname": "AspireUpdate Demo Site" }, "plugins": [ - "https://github-proxy.com/proxy/?repo=AspirePress/AspireUpdate&branch=playground-ready", + "https://github-proxy.com/proxy/?repo=AspirePress/AspireUpdate&branch=main", "error-log-viewer", "plugin-check" ], @@ -52,6 +52,10 @@ "step": "writeFile", "path": "/wordpress/wp-content/mu-plugins/bgnightly-notice.php", "data": "

Welcome to AspireUpdate Demo. Visit AspirePress documentation for more details.

'; });" + }, + { + "step": "rm", + "path": "/wordpress/wp-content/plugins/hello.php" } ] } diff --git a/composer.json b/composer.json index d2a49e5..40c90f8 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "name": "aspirepress/aspire-update", "description": "Update plugins and themes for WordPress.", "type": "wordpress-plugin", - "license": "GPL-3.0-or-later", + "license": "GPLv2", "authors": [ { "name": "AspirePress" @@ -26,7 +26,8 @@ "scripts": { "format": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --report=summary,source", "lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --report=summary, source", - "test": [ "Composer\\Config::disableProcessTimeout", "@php ./vendor/phpunit/phpunit/phpunit" ] + "test": [ "Composer\\Config::disableProcessTimeout", "@php ./vendor/phpunit/phpunit/phpunit" ], + "test:multisite": [ "Composer\\Config::disableProcessTimeout", "@php ./vendor/phpunit/phpunit/phpunit -c tests/multisite.xml" ] } diff --git a/includes/class-admin-settings.php b/includes/class-admin-settings.php index 1105ad9..d857330 100644 --- a/includes/class-admin-settings.php +++ b/includes/class-admin-settings.php @@ -53,7 +53,6 @@ public function __construct() { add_action( 'admin_init', [ $this, 'update_settings' ] ); add_action( 'network_admin_edit_aspireupdate-settings', [ $this, 'update_settings' ] ); - } /** @@ -102,7 +101,6 @@ public function reset_settings() { 'reset-success-nonce' => wp_create_nonce( 'aspireupdate-reset-success-nonce' ), ], - network_admin_url( 'index.php?page=aspireupdate-settings' ) ) ); @@ -241,13 +239,15 @@ public function update_settings() { } // Save settings and redirect. - if ( ( isset( $_POST['option_page'] ) && 'aspireupdate_settings' === $_POST['option_page'] ) ) { - update_site_option( $this->option_name, $this->sanitize_settings( wp_unslash( $_POST['aspireupdate_settings'] ) ) ); + if ( ( isset( $_POST['option_page'], $_POST['aspireupdate_settings'] ) && 'aspireupdate_settings' === $_POST['option_page'] ) ) { + update_site_option( + $this->option_name, + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Contents are sanitized in Admin_Settings::sanitize_settings. + $this->sanitize_settings( wp_unslash( $_POST['aspireupdate_settings'] ) ) + ); wp_safe_redirect( - add_query_arg( [ network_admin_url( 'index.php?page=aspireupdate-settings' ) ] ) - ); exit; } @@ -291,12 +291,11 @@ public function admin_enqueue_scripts( $hook ) { wp_localize_script( 'aspire_update_settings_js', 'aspireupdate', - [ - - 'ajax_url' => network_admin_url( 'admin-ajax.php' ), - 'nonce' => wp_create_nonce( 'aspireupdate-ajax' ), - 'domain' => Utilities::get_top_level_domain(), + 'ajax_url' => network_admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'aspireupdate-ajax' ), + 'domain' => Utilities::get_top_level_domain(), + 'string_unexpected_error' => esc_html__( 'Unexpected Error:', 'AspireUpdate' ), ] ); } @@ -313,7 +312,6 @@ public function the_settings_page() { 'reset-nonce' => wp_create_nonce( 'aspireupdate-reset-nonce' ), ], - network_admin_url( 'index.php?page=aspireupdate-settings' ) ); ?> diff --git a/includes/class-branding.php b/includes/class-branding.php new file mode 100644 index 0000000..85714d5 --- /dev/null +++ b/includes/class-branding.php @@ -0,0 +1,138 @@ +get_setting( 'enable', false ) ) { + $admin_notices_hook = is_multisite() ? 'network_admin_notices' : 'admin_notices'; + add_action( $admin_notices_hook, [ $this, 'output_admin_notice' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); + } + } + + /** + * Initialize Class. + * + * @return object + */ + public static function get_instance() { + if ( null === self::$instance ) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * Enqueue scripts and styles. + * + * @param string $hook The page identifier. + * @return void + */ + public function admin_enqueue_scripts( $hook ) { + if ( defined( 'AP_REMOVE_UI' ) && AP_REMOVE_UI ) { + return; + } + + $allowed_screens = [ + 'update-core', + 'plugins', + 'plugin-install', + 'themes', + 'theme-install', + ]; + + $screen = \WP_Screen::get( $hook ); + if ( in_array( $screen->id, $allowed_screens, true ) ) { + wp_enqueue_style( 'aspire_update_settings_css', plugin_dir_url( __DIR__ ) . 'assets/css/aspire-update.css', [], AP_VERSION ); + } + } + + /** + * Output admin notice. + * + * @return void + */ + public function output_admin_notice() { + if ( defined( 'AP_REMOVE_UI' ) && AP_REMOVE_UI ) { + return; + } + + $current_screen = get_current_screen(); + if ( ! $current_screen instanceof \WP_Screen ) { + return; + } + + $message = ''; + switch ( $current_screen->id ) { + case 'plugins': + case 'plugin-install': + if ( is_multisite() ) { + break; + } + // Fall-through. + case 'plugins-network': + case 'plugin-install-network': + $message = sprintf( + /* translators: 1: The name of the plugin, 2: The documentation URL. */ + __( 'Your plugin updates are now powered by %1$s. Learn more', 'AspireUpdate' ), + 'AspireUpdate', + __( 'https://docs.aspirepress.org/aspireupdate/', 'AspireUpdate' ) + ); + break; + case 'themes': + case 'theme-install': + if ( is_multisite() ) { + break; + } + // Fall-through. + case 'themes-network': + case 'theme-install-network': + $message = sprintf( + /* translators: 1: The name of the plugin, 2: The documentation URL. */ + __( 'Your theme updates are now powered by %1$s. Learn more', 'AspireUpdate' ), + 'AspireUpdate', + __( 'https://docs.aspirepress.org/aspireupdate/', 'AspireUpdate' ) + ); + break; + case 'update-core': + if ( is_multisite() ) { + break; + } + // Fall-through. + case 'update-core-network': + $message = sprintf( + /* translators: 1: The name of the plugin, 2: The documentation URL. */ + __( 'Your WordPress, plugin, theme and translation updates are now powered by %1$s. Learn more', 'AspireUpdate' ), + 'AspireUpdate', + __( 'https://docs.aspirepress.org/aspireupdate/', 'AspireUpdate' ) + ); + break; + } + + if ( '' === $message ) { + return; + } + + echo wp_kses_post( '

' . $message . '

' ); + } +} diff --git a/includes/class-controller.php b/includes/class-controller.php index 6099736..d573ecd 100644 --- a/includes/class-controller.php +++ b/includes/class-controller.php @@ -18,11 +18,9 @@ public function __construct() { Admin_Settings::get_instance(); Plugins_Screens::get_instance(); Themes_Screens::get_instance(); + Branding::get_instance(); $this->api_rewrite(); - - add_action( 'init', [ $this, 'load_textdomain' ] ); - } /** @@ -57,5 +55,4 @@ private function api_rewrite() { public function load_textdomain() { \load_plugin_textdomain( 'AspireUpdate', false, AP_PATH . '/languages/' ); } - } diff --git a/languages/AspireUpdate-ca_ES.po b/languages/AspireUpdate-ca_ES.po new file mode 100644 index 0000000..d1baa27 --- /dev/null +++ b/languages/AspireUpdate-ca_ES.po @@ -0,0 +1,162 @@ +# Copyright (C) 2024 AspirePress +# This file is distributed under the GPLv2. +msgid "" +msgstr "" +"Project-Id-Version: AspireUpdate 0.5\n" +"Report-Msgid-Bugs-To: https://github.com/aspirepress/AspireUpdate\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2024-11-08 11:23+0100\n" +"Last-Translator: Joan López \n" +"Language-Team: \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.4\n" +"X-Domain: AspireUpdate\n" + +#. Plugin Name of the plugin +#: aspire-update.php +msgid "AspireUpdate" +msgstr "AspireUpdate" + +#. Plugin URI of the plugin +#: aspire-update.php +msgid "https://aspirepress.org/" +msgstr "https://aspirepress.org/" + +#. Description of the plugin +#: aspire-update.php +msgid "Update plugins and themes for WordPress." +msgstr "Actualitza plugins i temes per WordPress." + +#. Author of the plugin +#: aspire-update.php +msgid "AspirePress" +msgstr "AspirePress" + +#. Author URI of the plugin +#: aspire-update.php includes/class-branding.php:91 +#: includes/class-branding.php:100 includes/class-branding.php:108 +msgid "https://docs.aspirepress.org/aspireupdate/" +msgstr "https://docs.aspirepress.org/aspireupdate/" + +#: includes/class-admin-settings.php:133 +msgid "Settings have been reset to default." +msgstr "La configuració s’ha restablert al valor predeterminat." + +#: includes/class-admin-settings.php:298 +msgid "Unexpected Error:" +msgstr "Error inesperat:" + +#: includes/class-admin-settings.php:319 +msgid "AspireUpdate Settings" +msgstr "Configuració d’AspireUpdate" + +#: includes/class-admin-settings.php:329 +msgid "Reset" +msgstr "Restableix" + +#: includes/class-admin-settings.php:428 +msgid "API Configuration" +msgstr "Configuració de l’API" + +#: includes/class-admin-settings.php:439 +msgid "Enable AspireUpdate API Rewrites" +msgstr "Activa les reescriptures de l’API d’AspireUpdate" + +#: includes/class-admin-settings.php:452 +msgid "API Host" +msgstr "Host de l’API" + +#: includes/class-admin-settings.php:460 +msgid "Your new API Host." +msgstr "El teu nou host de l’API" + +#: includes/class-admin-settings.php:470 +msgid "Other" +msgstr "Altres" + +#: includes/class-admin-settings.php:479 +msgid "API Key" +msgstr "Clau de l’API" + +#: includes/class-admin-settings.php:487 +msgid "Provides an API key for repositories that may require authentication." +msgstr "" +"Proporciona una clau d’API pels repositoris que requereixin autenticació" + +#: includes/class-admin-settings.php:493 +msgid "API Debug Configuration" +msgstr "Configuració de depuració de l’API" + +#: includes/class-admin-settings.php:504 +msgid "Enable Debug Mode" +msgstr "Activa el mode de depuració" + +#: includes/class-admin-settings.php:512 +msgid "Enables debug mode for the plugin." +msgstr "Activa el mode de depuració del plugin" + +#: includes/class-admin-settings.php:518 +msgid "Enable Debug Type" +msgstr "Activa el tipus de depuració" + +#: includes/class-admin-settings.php:527 +msgid "Request" +msgstr "Petició" + +#: includes/class-admin-settings.php:528 +msgid "Response" +msgstr "Resposta" + +#: includes/class-admin-settings.php:529 +msgid "String" +msgstr "Cadena de text" + +#: includes/class-admin-settings.php:531 +msgid "" +"Outputs the request URL and headers / response headers and body / string " +"that is being rewritten." +msgstr "" +"Emet l’URL de la petició i les capçaleres / encapçalaments de resposta i " +"el cos / cadena que s’està reescrivint." + +#: includes/class-admin-settings.php:537 +msgid "Disable SSL Verification" +msgstr "Desactiva la verificació SSL" + +#: includes/class-admin-settings.php:546 +msgid "Disables the verification of SSL to allow local testing." +msgstr "Desactiva la verificació de SSL per permetre proves locals." + +#: includes/class-admin-settings.php:609 +msgid "Generate API Key" +msgstr "Genera la clau de l’API" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:89 +msgid "" +"Your plugin updates are now powered by %1$s. Learn more" +msgstr "" +"L’actualització dels teus plugins funciona ara amb %1$s. " +"Més informació" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:98 +msgid "" +"Your theme updates are now powered by %1$s. Learn more" +msgstr "" +"L’actualització dels teus temes funciona funcionen ara amb %1$s. Més informació" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:106 +msgid "" +"Your WordPress, plugin, theme and translation updates are now powered by " +"%1$s. Learn more" +msgstr "" +"L’actualització de WordPress, els teus plugins i temes funciona ara amb " +"%1$s. Més informació" diff --git a/languages/AspireUpdate-de_DE.mo b/languages/AspireUpdate-de_DE.mo index b5e15cc0aca4748044a0ce65c8247df814a423b1..f0c491b099fda5abcee93e881004f440925e846c 100644 GIT binary patch literal 3283 zcmcJQJ8WD<6oxO5@L0ktya|skI zTyJcN6o?W5MJNyvLZm^WAry!ro#~-L6d)>ugp`Jk0tx;z_xcr5fJCme``x)SbLKy1 z&Ybyq=e7?bJTKt)EPjvO5k&{U9e3gn&llh$;5G0`a2324{1Lnd`~|!pyaDb2{{SBc zx8D^-Pl3C@LGUmrzz)dv-YxhExCiYo!H2=`!R_F$pagG#f`_!r1J7cluC=)kuTgO5SB^CA{uzh44* zy(#=X2%ZJmZvxrx3*a;0CGdIhL-08GHCP7!1fKv8-G>;1$3R~19QZW&7RdUqfKBi! zxCoX?x!+6R1883=+V6lhv@e6a{=UogG35N>*zogQju6X7 zi+2XLJH(x1g^)!^r;rz%Q;;4-qtg@OxY143%B=Lt=RIa+-%lCm!+_JY9F4lJ zvNUbUx#E4kn@CSv8e*2bSGwh*G38`EB{4fYDbA8rP1VR3EIORr{f zx@p!@x*VM(O$ZJJV7rWH(l!$R_ zjjcsRxbqOPz=T8AfgX37?z@KsX4M|-@snC=jbF!t3}6H8m`Er`RbZ_A$**@ zg`ix;?O86w;eR*X_P*e8Y)qxxa)ehC_q(ajI)55*K}?n@XjJM58S& z5_@ER?nFGeF^+XM$;RWlVG^9Yni#ArUwSnz&O19WX&OeXML3in<)~a&D;136&J7I% z4bx8EO@e#ZZV8EE^K)}`*N2pNo>6c(&0_SFbxq>Ax$y@wn2? zQ<`SFMLI&&jaRSK$#(7P^(MX{;BwKcC57{)qp|gd7l{f*dh75$k#$gi7bPnA94eg? zE1AGo=9M;LCEz=5l;Gp2hAfIss(S9@sBT(LO|ID)>es1Ivr(2u zweRsUC_Zpsd@Qfn3lyAfnzY4**7b#GWt|qWZ;I-W*Hbp(%8A%}fs&3-H;D?O`K+xM zacm4JpIcjxsqGQ6Etn9aMNx066?nt@M;4V99&zMzPojkko7-4KuCHKE3pb)Ii6D9z zCTVDI<{Rx%x}{A}W^uu-SKJ1?Kbx+D31q-VyRVqiC&KVBF=Q#P4<})&xDcR^WuIqVV#(-RUkA9xIF8UC zqW_QEVT#(811F(EhYJFFgr8h-;k CYsg># delta 620 zcmXZZO(+Cm7{Kv&*Vwfm*u}2Tn1qmzjX5kiSRchfkrU-04J(<&PC4#HDJf}E%F)?r z9UNSp9B~rI&4H4Wocy2Jd75{A@4U^t&-1+V)O;T=yw_q@cFf{5 z9^()`ViNzb0pnCB343r8mv9H~kV|!uO&mbk-@swapcK9@>*QBQOk|^T^iJLVkViMF zJ!_F>+>p+~-aLjht2hw1uzGKugLOl?mBQusNg)zaKu8A7xc@Ivyz%$?oX?74bT4P+ zO|@(vY+GB-hc;YonTL92abBOx%1$s. Learn more" +msgstr "Ihre Plugin-Updates werden jetzt von %1$s bereitgestellt. Mehr erfahren" + +#: includes/class-branding.php:98 +msgid "Your theme updates are now powered by %1$s. Learn more" +msgstr "Ihre Theme-Updates werden jetzt von %1$s bereitgestellt. Mehr erfahren" + +#: includes/class-branding.php:106 +msgid "Your WordPress, plugin, theme and translation updates are now powered by %1$s. Learn more" +msgstr "Ihre WordPress, Plugin, Theme und Übersetzungs updates werden jetzt von %1$s bereitgestellt. Mehr erfahren" diff --git a/languages/AspireUpdate-es_ES.po b/languages/AspireUpdate-es_ES.po new file mode 100644 index 0000000..c5670f4 --- /dev/null +++ b/languages/AspireUpdate-es_ES.po @@ -0,0 +1,145 @@ +msgid "" +msgstr "" +"Project-Id-Version: AspireUpdate 0.5\n" +"Report-Msgid-Bugs-To: https://github.com/aspirepress/AspireUpdate\n" +"Last-Translator: David Marín Carreño \n" +"Language-Team: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2024-11-07 14:05+0100\n" +"Language: es_ES \n" +"X-Generator: WP-CLI 2.11.0\n" +"X-Domain: AspireUpdate\n" + +#. Plugin Name of the plugin +#: aspire-update.php +msgid "AspireUpdate" +msgstr "AspireUpdate" + +#. Plugin URI of the plugin +#: aspire-update.php +msgid "https://aspirepress.org/" +msgstr "https://aspirepress.org/" + +#. Description of the plugin +#: aspire-update.php +msgid "Update plugins and themes for WordPress." +msgstr "Actualizar plugins y temas para WordPress." + +#. Author of the plugin +#: aspire-update.php +msgid "AspirePress" +msgstr "AspirePress" + +#. Author URI of the plugin +#: aspire-update.php +#: includes/class-branding.php:91 +#: includes/class-branding.php:100 +#: includes/class-branding.php:108 +msgid "https://docs.aspirepress.org/aspireupdate/" +msgstr "https://docs.aspirepress.org/aspireupdate/" + +#: includes/class-admin-settings.php:133 +msgid "Settings have been reset to default." +msgstr "Los ajustes se han reestablecido a sus valores por defecto." + +#: includes/class-admin-settings.php:298 +msgid "Unexpected Error:" +msgstr "Error inesperado:" + +#: includes/class-admin-settings.php:319 +msgid "AspireUpdate Settings" +msgstr "Ajustes de AspireUpdate" + +#: includes/class-admin-settings.php:329 +msgid "Reset" +msgstr "Reestablecer" + +#: includes/class-admin-settings.php:428 +msgid "API Configuration" +msgstr "Configuración de API" + +#: includes/class-admin-settings.php:439 +msgid "Enable AspireUpdate API Rewrites" +msgstr "Activar reescrituras de API de AspireUpdate" + +#: includes/class-admin-settings.php:452 +msgid "API Host" +msgstr "Host de API" + +#: includes/class-admin-settings.php:460 +msgid "Your new API Host." +msgstr "Tu nuevo host de API" + +#: includes/class-admin-settings.php:470 +msgid "Other" +msgstr "Otros" + +#: includes/class-admin-settings.php:479 +msgid "API Key" +msgstr "Clave de API" + +#: includes/class-admin-settings.php:487 +msgid "Provides an API key for repositories that may require authentication." +msgstr "Proporciona una clave de API para los repositorios que pueden requerir autenticación." + +#: includes/class-admin-settings.php:493 +msgid "API Debug Configuration" +msgstr "Configuración de depuración de API" + +#: includes/class-admin-settings.php:504 +msgid "Enable Debug Mode" +msgstr "Activa modo de depuración" + +#: includes/class-admin-settings.php:512 +msgid "Enables debug mode for the plugin." +msgstr "Activa el modo depuración para el plugin." + +#: includes/class-admin-settings.php:518 +msgid "Enable Debug Type" +msgstr "Activa tipo de depuración" + +#: includes/class-admin-settings.php:527 +msgid "Request" +msgstr "Solicitud" + +#: includes/class-admin-settings.php:528 +msgid "Response" +msgstr "Respuesta" + +#: includes/class-admin-settings.php:529 +msgid "String" +msgstr "Cadena" + +#: includes/class-admin-settings.php:531 +msgid "Outputs the request URL and headers / response headers and body / string that is being rewritten." +msgstr "Muestra la URL y las cabeceras de la solicitud / las cabeceras y cuerpo de la respuesta / la cadena que se reescribe." + +#: includes/class-admin-settings.php:537 +msgid "Disable SSL Verification" +msgstr "Desactivar verificación de SSL" + +#: includes/class-admin-settings.php:546 +msgid "Disables the verification of SSL to allow local testing." +msgstr "Desactiva la verificación de SSL para permitir pruebas locales." + +#: includes/class-admin-settings.php:609 +msgid "Generate API Key" +msgstr "Generar clave de API" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:89 +msgid "Your plugin updates are now powered by %1$s. Learn more" +msgstr "La actualización de tus plugins ahora funciona con %1$s. Leer más " + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:98 +msgid "Your theme updates are now powered by %1$s. Learn more" +msgstr "La actualización de tus temas ahora funciona con %1$s. Leer más" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:106 +msgid "Your WordPress, plugin, theme and translation updates are now powered by %1$s. Learn more" +msgstr "La actualización de WordPress, plugins, temas y traducciones ahora funciona con %1$s. Leer más" diff --git a/languages/AspireUpdate-fr_FR.l10n.php b/languages/AspireUpdate-fr_FR.l10n.php index cf65182..597964d 100644 --- a/languages/AspireUpdate-fr_FR.l10n.php +++ b/languages/AspireUpdate-fr_FR.l10n.php @@ -1,2 +1,2 @@ 'AspireUpdate','report-msgid-bugs-to'=>'','pot-creation-date'=>'2024-11-03 17:59+0000','po-revision-date'=>'2024-11-04 06:23+0000','last-translator'=>'','language-team'=>'Français','language'=>'fr_FR','plural-forms'=>'nplurals=2; plural=n > 1;','mime-version'=>'1.0','content-type'=>'text/plain; charset=UTF-8','content-transfer-encoding'=>'8bit','x-generator'=>'Loco https://localise.biz/','x-loco-version'=>'2.6.11; wp-6.6.2','x-domain'=>'AspireUpdate','messages'=>['API Configuration'=>'Configuration de l’API','API Debug Configuration'=>'Configuration du débogage de l’API','API Host'=>'Hôte de l’API','API Key'=>'Clé API','AspirePress'=>'AspirePress','AspireUpdate'=>'AspireUpdate','AspireUpdate Settings'=>'Réglages d’AspireUpdate','Disable SSL Verification'=>'Désactiver la vérification du SSL','Disables the verification of SSL to allow local testing.'=>'Désactive la vérification du SSL pour autoriser le test en local.','Enable AspireUpdate API Rewrites'=>'Activer la réécriture de l’API AspireUpdate','Enable Debug Mode'=>'Activer le mode débogage','Enable Debug Type'=>'Activer le type de débogage','Enables debug mode for the plugin.'=>'Active le mode débogage de l’extension.','Generate API Key'=>'Générer une clé API','https://aspirepress.org/'=>'https://aspirepress.org/','https://docs.aspirepress.org/aspireupdate/'=>'https://docs.aspirepress.org/aspireupdate/','Other'=>'Autre','Outputs the request URL and headers / response headers and body / string that is being rewritten.'=>'Affiche l’URL et les en-têtes de la requête/les en-têtes et le corps de la réponse/la chaîne qui est en train d\'être réécrite.','Provides an API key for repositories that may require authentication.'=>'Fournit une clé API pour les dépôts qui peuvent nécessiter une authentification.','Request'=>'Rquête','Reset'=>'Réinitialiser','Response'=>'Réponse','Save Changes'=>'Enregistrer les changements','Settings have been reset to default.'=>'Les réglages ont été réinitialisés à ceux par défaut.','String'=>'Chaine','Update plugins and themes for WordPress.'=>'Mets à jour les extensions et thème pour WordPress','Your new API Host.'=>'Votre nouvel hôte pour l’API']]; +return ['project-id-version'=>'AspireUpdate','report-msgid-bugs-to'=>'','pot-creation-date'=>'2024-11-03 17:59+0000','po-revision-date'=>'2024-11-08 08:14+0000','last-translator'=>'','language-team'=>'Français','language'=>'fr_FR','plural-forms'=>'nplurals=2; plural=n > 1;','mime-version'=>'1.0','content-type'=>'text/plain; charset=UTF-8','content-transfer-encoding'=>'8bit','x-generator'=>'Loco https://localise.biz/','x-loco-version'=>'2.6.11; wp-6.6.2','x-domain'=>'AspireUpdate','messages'=>['API Configuration'=>'Configuration de l’API','API Debug Configuration'=>'Configuration du débogage de l’API','API Host'=>'Hôte de l’API','API Key'=>'Clé API','AspirePress'=>'AspirePress','AspireUpdate'=>'AspireUpdate','AspireUpdate Settings'=>'Réglages d’AspireUpdate','Disable SSL Verification'=>'Désactiver la vérification du SSL','Disables the verification of SSL to allow local testing.'=>'Désactive la vérification du SSL pour autoriser le test en local.','Enable AspireUpdate API Rewrites'=>'Activer la réécriture de l’API AspireUpdate','Enable Debug Mode'=>'Activer le mode débogage','Enable Debug Type'=>'Activer le type de débogage','Enables debug mode for the plugin.'=>'Active le mode débogage de l’extension.','Generate API Key'=>'Générer une clé API','https://aspirepress.org/'=>'https://aspirepress.org/','https://docs.aspirepress.org/aspireupdate/'=>'https://docs.aspirepress.org/aspireupdate/','Other'=>'Autre','Outputs the request URL and headers / response headers and body / string that is being rewritten.'=>'Affiche l’URL et les en-têtes de la requête/les en-têtes et le corps de la réponse/la chaîne qui est en train d\'être réécrite.','Provides an API key for repositories that may require authentication.'=>'Fournit une clé API pour les dépôts qui peuvent nécessiter une authentification.','Request'=>'Rquête','Reset'=>'Réinitialiser','Response'=>'Réponse','Settings have been reset to default.'=>'Les réglages ont été réinitialisés à ceux par défaut.','String'=>'Chaine','Unexpected Error:'=>'Erreur inattendue :','Update plugins and themes for WordPress.'=>'Mets à jour les extensions et thème pour WordPress','Your new API Host.'=>'Votre nouvel hôte pour l’API','Your plugin updates are now powered by %1$s. Learn more'=>'Vos mises à jour d’extension sont maintenant propulsées par %1$s. En savoir plus','Your theme updates are now powered by %1$s. Learn more'=>'Vos mises à jour de thèmes sont maintenant propulsés par %1$s. En savoir plus','Your WordPress, plugin, theme and translation updates are now powered by %1$s. Learn more'=>'Vos mises à jour de WordPress, d’extensions et de thèmes sont maintenant propulsés par %1$s. En savoir plus']]; diff --git a/languages/AspireUpdate-fr_FR.mo b/languages/AspireUpdate-fr_FR.mo index 2a24e7bad802c4ababc5f9cc6474046a74339bc8..d79a18740c87ca09491b7a0a73fd34b3b5a1a06e 100644 GIT binary patch delta 1349 zcmcK1K}b|V7zgm#T+=NxbF(r6zc!^2E1l3gtf^Lh44k2ATBm`cfgNF_kV*Q5|5;X8&3(Ie29`F6X@0*YDcb&oK z_UJUjuM7Vp`0tO{9b+v!{<;s#J=hra zB)kZ(z%-nOop2u7NiV`A^4SU&2jKBoz4JVLjQtQCg&!a?SYj8Z1d|Z2u(L1+2chje zfN}T;_QU7!8C-z&ddE=hJ^LI^zzC{twVh95k%UiM<~~JMBjHj*s!fVXU)(mrp@LGL z%7%NR>EN2DoDn6oPLW@#jJq;LrYOpSxOB)UE_I0;*OOH79d3jst^`T1O1@VW3g5bQ zmvY)DPmbq%`nq*4y|(G49H*iZW9Je*r@M6`e_3!Psq86{OY=Ot?o|}YKve0%$R!%~ zwCSy%)yw!ldG*%TwKB9Fy@XFWi*zbQkfGTFZVxp?DzL-@UUD2_o3wCPH2jF3)6 zP&OQhWdcoQS7Vs9S-NBA;0RiG5zd!~Ghz}iXbfJHF!s4A)?SwJiuRTRfPeKr4%M`>Hm-!z`t=wQQK WwzKcebBo6KI-5>&?YrSjEb|A(woXp~ delta 586 zcmYMwODIH99LMo9Pv${mgc&1lj1qZIW5{M2<57x*os>y8lo>U5JQB@LHX=6*tjT^h z5;Y}dAySIOtdymVl_cN8lvC$^{^y?V`Tfs5^WK%Fb8hplU{vMjms~KO4gZ!ME85ILG@uLJ*p0HGVQfSd4-IJ{w(}c7zN%+q1Z5)&C*6K zh`soMWQlg05CIHf4aQO4a1&+Vku764ej6OIMOBH+#1hl0rd!P|dcV23D4{MX;n5*w za9&Hb=u6J1{%Kh)2q%1$s. Learn more" +msgstr "" +"Vos mises à jour d’extension sont maintenant propulsées par " +"%1$s. En savoir plus" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:98 +msgid "" +"Your theme updates are now powered by %1$s. Learn more" +msgstr "" +"Vos mises à jour de thèmes sont maintenant propulsés par " +"%1$s. En savoir plus" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:106 +msgid "" +"Your WordPress, plugin, theme and translation updates are now powered by " +"%1$s. Learn more" +msgstr "" +"Vos mises à jour de WordPress, d’extensions et de thèmes sont maintenant " +"propulsés par %1$s. En savoir plus" diff --git a/languages/AspireUpdate-nl_NL.l10n.php b/languages/AspireUpdate-nl_NL.l10n.php new file mode 100644 index 0000000..7fc8a97 --- /dev/null +++ b/languages/AspireUpdate-nl_NL.l10n.php @@ -0,0 +1,2 @@ +'AspireUpdate','plural-forms'=>NULL,'language'=>'nl_NL','project-id-version'=>'AspireUpdate','pot-creation-date'=>'','po-revision-date'=>'2024-11-09 14:01+0100','x-generator'=>'Poedit 3.5','messages'=>['AspireUpdate'=>'AspireUpdate','https://aspirepress.org/'=>'https://aspirepress.org/','Update plugins and themes for WordPress.'=>'Update plugins en thema\'s voor WordPress.','AspirePress'=>'AspirePress','https://docs.aspirepress.org/aspireupdate/'=>'https://docs.aspirepress.org/aspireupdate/','Settings have been reset to default.'=>'Instellingen zijn opnieuw ingesteld naar de standaardwaarden.','Unexpected Error:'=>'Onverwachte fout:','AspireUpdate Settings'=>'AspireUpdate Instellingen','Reset'=>'Opnieuw instellen','API Configuration'=>'API Configuratie','Enable AspireUpdate API Rewrites'=>'AspireUpdate API herschrijfregels inschakelen','API Host'=>'API Host','Your new API Host.'=>'Je nieuwe API Host.','Other'=>'Overig','API Key'=>'API Sleutel','Provides an API key for repositories that may require authentication.'=>'Biedt een API sleutel voor repositories waarvoor authenticatie vereist kan zijn.','API Debug Configuration'=>'API Debug Configuratie','Enable Debug Mode'=>'Debug Modus inschakelen','Enables debug mode for the plugin.'=>'Schakelt debug modus in voor de plugin.','Enable Debug Type'=>'Debug Type inschakelen','Request'=>'Aanvraag','Response'=>'Antwoord','String'=>'Tekst','Outputs the request URL and headers / response headers and body / string that is being rewritten.'=>'Toon de aanvraag URL en headers / antwoord headers en body / tekst die wordt herschreven.','Disable SSL Verification'=>'SSL Verificatie uitschakelen','Disables the verification of SSL to allow local testing.'=>'Schakel SSL verificatie uit om lokaal testen mogelijk te maken.','Generate API Key'=>'Genereer API Sleutel','Your plugin updates are now powered by %1$s. Learn more'=>'Je plugin updates worden nu mogelijk gemaakt door %1$s. Lees meer','Your theme updates are now powered by %1$s. Learn more'=>'Je thema updates worden nu mogelijk gemaakt door %1$s. Lees meer','Your WordPress, plugin, theme and translation updates are now powered by %1$s. Learn more'=>'Je WordPress, plugin, thema en vertalingen updates worden nu mogelijk gemaakt door %1$s. Lees meer']]; \ No newline at end of file diff --git a/languages/AspireUpdate-nl_NL.mo b/languages/AspireUpdate-nl_NL.mo new file mode 100644 index 0000000000000000000000000000000000000000..8de163d4145e8f53e435c71f3e3836277b832088 GIT binary patch literal 3200 zcmcJQNpBoQ7={~2SWMVLSVCAzQKBrQXE7lP6DP>Q1|00zvd4i0AyhN{O;3AzswP#{ zo;VT`ClD9JAzTnb2qZ3W0R94hfD7b+goK15A>{{fgZHcM@ys|mM2NK1^GvPZR`vGp zJGXrr;CT-3(|C8?5d??89e3gf&-dUX;1A#v;7{Pa;BVkP;Gf|A;B{~Z_&4|%xc#mm zcoN(L9tV$t0_=jk-^T^N1oxu-Bls}*3%DJ;21@WcI18TLmfO1m^7!W<`|%aH5BwIq z8~hpM{jY)t!N0)wz@1pM6Z`~x8~hr)0R98ApBJ$BFlfQc$iWvN`?DKH9tRJDY;PJr z9PgQe=Rl6T0qzDh$a(w-d>Q-(48dz4=Wo}2`F=;h18Bbj?gBd?`~N<89{dno0{;N9 zG?<*o<2nIydjUKNo&ym=aHSak3_OJPci;!$ui&HLJ8+u7i(mv^1v&01IDZ&i1rhex z1JePP`?z>6KM&;y9w^AM^Vwk^kZOM>IG#OtpTf&Aao#z0&dalS`FSQs@F2+k4IY%+ z*N=0~apE}nI`Em|ya&@ubK(`PT1lK4=@PAc&kQxP_$K|YYwP@kH)tc6w!OsAk|Ar0 z|Es-7IvQ(;6>=_7u?=PtD;p_^m6dsMj!e=@nz_MZzzWwUu|6^)bj#0nTF5ljeUa*> zOob!MJC=f3C<~;gr60m+a22Q&Kc@yn>cL}jQQ1Fxq*cjGZaL~4DKmc zq_-3-=e~iK9RGTMfuKb*ZcwTb+}CRPrtNZL!xoDKcloV}4t&@BAPwumOPtB7wN_4fMsj@tkTUXTg>EqK|IFx&F zd(8Pf{O?=0o$J|Jxh(yy>!DP(q)l871_P09+S1n1yq#yY%;#whRSf5%5I4}`w%5ey z?U`7{!7?sfuyGQFr?c3GbzKt!3vuGwS)>J@hRd{`@ZRAJ?o3TgRwj>z z)oNIINmP&4D%IyJ)k_Ll6 zIIEgE!u6|($qO%Z52-OWTn|E)j>`F?Rqx2S)c1~GLP7wsDU|eNMWQns#L5ETv%>Q|D9SW|W zBy<-t+mVINLKM0>rZidWAe*9#4WLV-756s_CBp6|S!)@>Y%3Bqw6-a~+0FX7Qe)E# z=iE?{{W`I(AuLemF;ylq-hn};7CD?asB5iwu9RxsNEv%wMl3^Fmdf?9;ZUhDTBx$4 z4wO7fNc1tmVUZ7x);aXk389O{k_%|_0_DDqsd8UR<2@c#WB+-h1iN>j=$Df<&Sl|Z zu-H=xWqr;Cml0)}E_@6|E9;jDy*W9?XNS^AC>Z3Bt;1cx|A;+^*yTFM6D%sErZ1aq zl(D5VcY}l@BvvkYz~%1$s. Learn more" +msgstr "" +"Je plugin updates worden nu mogelijk gemaakt door %1$s. Lees meer" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:98 +msgid "" +"Your theme updates are now powered by %1$s. Learn more" +msgstr "" +"Je thema updates worden nu mogelijk gemaakt door %1$s. Lees meer" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:106 +msgid "" +"Your WordPress, plugin, theme and translation updates are now powered by " +"%1$s. Learn more" +msgstr "" +"Je WordPress, plugin, thema en vertalingen updates worden nu mogelijk " +"gemaakt door %1$s. Lees meer" + +#~ msgid "Save Changes" +#~ msgstr "Wijzigingen opslaan" diff --git a/languages/AspireUpdate-sv_SE.mo b/languages/AspireUpdate-sv_SE.mo new file mode 100644 index 0000000000000000000000000000000000000000..47855b3ec313f36c80f8d20a9516cf63fd8dcc36 GIT binary patch literal 2449 zcmb`I&5ImG7{*JDUt^3KHGV@O3P$Ok*(BmJA{gC`uF1N~&a8~RN^;T8S zW{x6y_7XhkaW@diNg?Ev%izVMmmCzqga3g-KoOs}x@UGa>dl6pUsqT4ThIGZ@BDoD zz$J$3+3Nlid=d9gci;zCekWs(fLq`b;HThy;8)G>6W8T<=;4?Z4+F2oBlW&m3*va)3{SGZR`pc3+_0K(-1j9P z&CPJr3#+~1BFoG+&rDZj+)GCmW45e=!BR)LHz$8KrBOBCviH+B-8L31%m<)Rl7%}_M6qakb9UP$giCN$K+%@ZU5eg{B zt}ZqP06TSe-k zwrTR|_Nnsyq7!$`a9&A$-b!tKE!vPHMfRg5lt7aoYaBZfEi6Qh*LdT2^TgsSjfF;| zc1AcKwXM)D6Ua-G=M*ON9{)?JgJbeepzqkQdLR23}gST{0Jo*zdv&P7XR z2z&bjRbx0Z(O_Q-I9-i!7EzF5#CtMxlWPM_Lq(YkAB`qEHVIF9+#Sg5zdOQ;c7C#x zWn@5D-kV&r`?AGWv>14W!!N21FxwjKVs6&XPorX?jrxh3>~i5f8pNP#5JBny=f(|W z%uY^?o1q(6HL7&Ll~96vy<>0XoXako?4)RGQzL$y-xieF92$qpXn88p8UA6T>LuhR zMSU7Jt%YYT5+*G#$}VEM{aMQh@uHueo$RJU*WE~1+F;sdXtB~-_9wepR!3Wz>>yLl z4BI7+LOX2pLv|W zkX_cor%2X(uC?Hk-Pwvng!rKGkq(=L3ZhPjK0}h(+5qqrIBGHBtWRrj)>9%chmb}- VN7HD>_$d&*A literal 0 HcmV?d00001 diff --git a/languages/AspireUpdate-sv_SE.po b/languages/AspireUpdate-sv_SE.po new file mode 100644 index 0000000..329737e --- /dev/null +++ b/languages/AspireUpdate-sv_SE.po @@ -0,0 +1,134 @@ +# Copyright (C) 2024 AspirePress +# This file is distributed under the GPLv2. +msgid "" +msgstr "" +"Project-Id-Version: AspireUpdate 0.5\n" +"Report-Msgid-Bugs-To: https://github.com/aspirepress/AspireUpdate\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2024-11-07 03:48+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: sv_SE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.5\n" +"X-Domain: AspireUpdate\n" + +#. Plugin Name of the plugin +#: aspire-update.php +msgid "AspireUpdate" +msgstr "AspireUpdate" + +#. Plugin URI of the plugin +#: aspire-update.php +msgid "https://aspirepress.org/" +msgstr "https://aspirepress.org/" + +#. Description of the plugin +#: aspire-update.php +msgid "Update plugins and themes for WordPress." +msgstr "Uppdatering av WordPress-teman och -tillägg." + +#. Author of the plugin +#: aspire-update.php +msgid "AspirePress" +msgstr "AspirePress" + +#. Author URI of the plugin +#: aspire-update.php +msgid "https://docs.aspirepress.org/aspireupdate/" +msgstr "https://docs.aspirepress.org/aspireupdate/" + +#: includes/class-admin-settings.php:133 +msgid "Settings have been reset to default." +msgstr "Inställningarna återställda till standardvärden." + +#: includes/class-admin-settings.php:298 +msgid "Unexpected Error:" +msgstr "Okänt fel:" + +#: includes/class-admin-settings.php:319 +msgid "AspireUpdate Settings" +msgstr "Inställningar för AspireUpdate" + +#: includes/class-admin-settings.php:329 +msgid "Reset" +msgstr "Återställ" + +#: includes/class-admin-settings.php:428 +msgid "API Configuration" +msgstr "API-konfiguration" + +#: includes/class-admin-settings.php:439 +msgid "Enable AspireUpdate API Rewrites" +msgstr "Aktivera omskrivningar i AspireUpdate API" + +#: includes/class-admin-settings.php:452 +msgid "API Host" +msgstr "API-värd" + +#: includes/class-admin-settings.php:460 +msgid "Your new API Host." +msgstr "Din nya API-värd." + +#: includes/class-admin-settings.php:470 +msgid "Other" +msgstr "Annat" + +#: includes/class-admin-settings.php:479 +msgid "API Key" +msgstr "API-nyckel" + +#: includes/class-admin-settings.php:487 +msgid "Provides an API key for repositories that may require authentication." +msgstr "" +"Tillhandahåller API-nyckel för filförvar som kan kräva autentisering." + +#: includes/class-admin-settings.php:493 +msgid "API Debug Configuration" +msgstr "Konfigurering av felsökning i API" + +#: includes/class-admin-settings.php:504 +msgid "Enable Debug Mode" +msgstr "Aktivera felsökningsläge" + +#: includes/class-admin-settings.php:512 +msgid "Enables debug mode for the plugin." +msgstr "Aktiverar tilläggets felsökningsläge." + +#: includes/class-admin-settings.php:518 +msgid "Enable Debug Type" +msgstr "Aktivera typ av felsökning" + +#: includes/class-admin-settings.php:527 +msgid "Request" +msgstr "Förfrågan" + +#: includes/class-admin-settings.php:528 +msgid "Response" +msgstr "Svar" + +#: includes/class-admin-settings.php:529 +msgid "String" +msgstr "Sträng" + +#: includes/class-admin-settings.php:531 +msgid "" +"Outputs the request URL and headers / response headers and body / string " +"that is being rewritten." +msgstr "" +"Skriver ut URL och headers för förfrågan/svarets headers och innehåll/" +"sträng som skrivs om." + +#: includes/class-admin-settings.php:537 +msgid "Disable SSL Verification" +msgstr "Inaktivera verifiering av SSL" + +#: includes/class-admin-settings.php:546 +msgid "Disables the verification of SSL to allow local testing." +msgstr "Inaktiverar verifieringen av SSL så att lokal testning kan ske." + +#: includes/class-admin-settings.php:609 +msgid "Generate API Key" +msgstr "Generera API-nyckel" diff --git a/languages/AspireUpdate.pot b/languages/AspireUpdate.pot index 99e5ca8..a4cf65b 100644 --- a/languages/AspireUpdate.pot +++ b/languages/AspireUpdate.pot @@ -1,127 +1,146 @@ -#, fuzzy +# Copyright (C) 2024 AspirePress +# This file is distributed under the GPLv2. msgid "" msgstr "" -"Project-Id-Version: AspireUpdate\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-11-04 06:19+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Project-Id-Version: AspireUpdate 0.5\n" +"Report-Msgid-Bugs-To: https://github.com/aspirepress/AspireUpdate\n" "Last-Translator: FULL NAME \n" -"Language-Team: \n" -"Language: \n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Loco https://localise.biz/\n" -"X-Loco-Version: 2.6.11; wp-6.6.2\n" -"X-Domain: AspireUpdate" - -#: includes/class-admin-settings.php:313 -msgid "API Configuration" -msgstr "" +"POT-Creation-Date: \n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"X-Generator: WP-CLI 2.11.0\n" +"X-Domain: AspireUpdate\n" -#: includes/class-admin-settings.php:378 -msgid "API Debug Configuration" +#. Plugin Name of the plugin +#: aspire-update.php +msgid "AspireUpdate" msgstr "" -#: includes/class-admin-settings.php:337 -msgid "API Host" +#. Plugin URI of the plugin +#: aspire-update.php +msgid "https://aspirepress.org/" msgstr "" -#: includes/class-admin-settings.php:364 -msgid "API Key" +#. Description of the plugin +#: aspire-update.php +msgid "Update plugins and themes for WordPress." msgstr "" #. Author of the plugin +#: aspire-update.php msgid "AspirePress" msgstr "" -#. Name of the plugin -msgid "AspireUpdate" +#. Author URI of the plugin +#: aspire-update.php +#: includes/class-branding.php:91 +#: includes/class-branding.php:100 +#: includes/class-branding.php:108 +msgid "https://docs.aspirepress.org/aspireupdate/" msgstr "" -#: includes/class-admin-settings.php:272 +#: includes/class-admin-settings.php:133 +msgid "Settings have been reset to default." +msgstr "" + +#: includes/class-admin-settings.php:298 +msgid "Unexpected Error:" +msgstr "" + +#: includes/class-admin-settings.php:319 msgid "AspireUpdate Settings" msgstr "" -#: includes/class-admin-settings.php:422 -msgid "Disable SSL Verification" +#: includes/class-admin-settings.php:329 +msgid "Reset" msgstr "" -#: includes/class-admin-settings.php:431 -msgid "Disables the verification of SSL to allow local testing." +#: includes/class-admin-settings.php:428 +msgid "API Configuration" msgstr "" -#: includes/class-admin-settings.php:324 +#: includes/class-admin-settings.php:439 msgid "Enable AspireUpdate API Rewrites" msgstr "" -#: includes/class-admin-settings.php:389 -msgid "Enable Debug Mode" +#: includes/class-admin-settings.php:452 +msgid "API Host" msgstr "" -#: includes/class-admin-settings.php:403 -msgid "Enable Debug Type" +#: includes/class-admin-settings.php:460 +msgid "Your new API Host." msgstr "" -#: includes/class-admin-settings.php:397 -msgid "Enables debug mode for the plugin." +#: includes/class-admin-settings.php:470 +msgid "Other" msgstr "" -#: includes/class-admin-settings.php:494 -msgid "Generate API Key" +#: includes/class-admin-settings.php:479 +msgid "API Key" msgstr "" -#. URI of the plugin -msgid "https://aspirepress.org/" +#: includes/class-admin-settings.php:487 +msgid "Provides an API key for repositories that may require authentication." msgstr "" -#. Author URI of the plugin -msgid "https://docs.aspirepress.org/aspireupdate/" +#: includes/class-admin-settings.php:493 +msgid "API Debug Configuration" msgstr "" -#: includes/class-admin-settings.php:355 -msgid "Other" +#: includes/class-admin-settings.php:504 +msgid "Enable Debug Mode" msgstr "" -#: includes/class-admin-settings.php:416 -msgid "" -"Outputs the request URL and headers / response headers and body / string " -"that is being rewritten." +#: includes/class-admin-settings.php:512 +msgid "Enables debug mode for the plugin." msgstr "" -#: includes/class-admin-settings.php:372 -msgid "Provides an API key for repositories that may require authentication." +#: includes/class-admin-settings.php:518 +msgid "Enable Debug Type" msgstr "" -#: includes/class-admin-settings.php:412 +#: includes/class-admin-settings.php:527 msgid "Request" msgstr "" -#: includes/class-admin-settings.php:280 -msgid "Reset" +#: includes/class-admin-settings.php:528 +msgid "Response" msgstr "" -#: includes/class-admin-settings.php:413 -msgid "Response" +#: includes/class-admin-settings.php:529 +msgid "String" msgstr "" -#: includes/class-admin-settings.php:279 -msgid "Save Changes" +#: includes/class-admin-settings.php:531 +msgid "Outputs the request URL and headers / response headers and body / string that is being rewritten." msgstr "" -#: includes/class-admin-settings.php:119 -msgid "Settings have been reset to default." +#: includes/class-admin-settings.php:537 +msgid "Disable SSL Verification" msgstr "" -#: includes/class-admin-settings.php:414 -msgid "String" +#: includes/class-admin-settings.php:546 +msgid "Disables the verification of SSL to allow local testing." msgstr "" -#. Description of the plugin -msgid "Update plugins and themes for WordPress." +#: includes/class-admin-settings.php:609 +msgid "Generate API Key" msgstr "" -#: includes/class-admin-settings.php:345 -msgid "Your new API Host." +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:89 +msgid "Your plugin updates are now powered by %1$s. Learn more" +msgstr "" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:98 +msgid "Your theme updates are now powered by %1$s. Learn more" +msgstr "" + +#. translators: 1: The name of the plugin, 2: The documentation URL. +#: includes/class-branding.php:106 +msgid "Your WordPress, plugin, theme and translation updates are now powered by %1$s. Learn more" msgstr "" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d6751ac..72d0b05 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -14,6 +14,11 @@ ./tests/ + + + ms-required + + ./aspire-update.php diff --git a/readme.txt b/readme.txt index 6844d4b..55e75cd 100644 --- a/readme.txt +++ b/readme.txt @@ -1,41 +1,40 @@ -=== AspireUpdate === -Contributors: sarah-savage, namithj, asirota -Donate link: https://github.com/sponsors/aspirepress -Tags: -Requires at least: 5.3 -Tested up to: 6.7 -Stable tag: 0.5 -Requires PHP: 7.4 -License: GPL-3.0-or-later -License URI: https://www.gnu.org/licenses/gpl-3.0.html - -This plugin allows a WordPress user to automatically rewrite certain URLs and URL paths to a new URL. - -== Description == - -This plugin allows a WordPress user to automatically rewrite certain URLs and URL paths to a new URL. This is helpful because it allows for the rewriting of api.wordpress.org to some other repository that contains the plugins the user wants. - -The plugin supports multiple rewrites, and also supports rewriting the URL paths of the requests on a per-host basis. This improves the capacity of the plugin to adequately support newer or different repositories. -. - -== Frequently Asked Questions == - -= A question that someone might have = - -An answer to that question. - -= What about foo bar? = - -Answer to foo bar dilemma. - -== Screenshots == - -1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Screenshots are stored in the /assets directory. -2. This is the second screen shot - -== Changelog == - -= 0.5 = -* first stable version, connects to api.wordpress.org or an alternative AspireCloud repository - -== Upgrade Notice == +=== AspireUpdate === +Contributors: sarah-savage, namithj, asirota +Donate link: https://github.com/sponsors/aspirepress +Tags: +Requires at least: 5.3 +Tested up to: 6.7 +Stable tag: 0.5 +Requires PHP: 7.4 +License: GPLv2 +License URI: https://www.gnu.org/licenses/gpl-2.0.html + +This plugin allows a WordPress user to automatically rewrite certain URLs and URL paths to a new URL. + +== Description == + +This plugin allows a WordPress user to automatically rewrite certain URLs and URL paths to a new URL. This is helpful because it allows for the rewriting of api.wordpress.org to some other repository that contains the plugins the user wants. + +The plugin supports multiple rewrites, and also supports rewriting the URL paths of the requests on a per-host basis. This improves the capacity of the plugin to adequately support newer or different repositories. + +== Frequently Asked Questions == + += A question that someone might have = + +An answer to that question. + += What about foo bar? = + +Answer to foo bar dilemma. + +== Screenshots == + +1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Screenshots are stored in the /assets directory. +2. This is the second screen shot + +== Changelog == + += 0.5 = +* first stable version, connects to api.wordpress.org or an alternative AspireCloud repository + +== Upgrade Notice == \ No newline at end of file diff --git a/tests/Branding/Branding_AdminEnqueueScriptsTest.php b/tests/Branding/Branding_AdminEnqueueScriptsTest.php new file mode 100644 index 0000000..9176483 --- /dev/null +++ b/tests/Branding/Branding_AdminEnqueueScriptsTest.php @@ -0,0 +1,109 @@ +admin_enqueue_scripts( $hook ); + $this->assertTrue( wp_style_is( 'aspire_update_settings_css' ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_hooks() { + return self::text_array_to_dataprovider( + [ + 'update-core', + 'plugins', + 'plugin-install', + 'themes', + 'theme-install', + ] + ); + } + + /** + * Test that the stylesheet is not enqueued on adjacent screens. + * + * @dataProvider data_adjacent_screens + * + * @param string $hook The current screen's hook. + */ + public function test_should_not_enqueue_style_on_adjacent_screens( $hook ) { + if ( is_multisite() ) { + $hook .= '-network'; + } + + $branding = new AspireUpdate\Branding(); + $branding->admin_enqueue_scripts( $hook ); + $this->assertFalse( wp_style_is( 'aspire_update_settings_css' ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_adjacent_screens() { + return self::text_array_to_dataprovider( + [ + 'dashboard', + 'nav-menus', + 'plugin-editor', + ] + ); + } + + /** + * Test that the stylesheet is not enqueued when there is no screen. + */ + public function test_should_not_enqueue_style_when_there_is_no_screen() { + $branding = new AspireUpdate\Branding(); + $branding->admin_enqueue_scripts( '' ); + $this->assertFalse( wp_style_is( 'aspire_update_settings_css' ) ); + } + + /** + * Test that the stylesheet is not enqueued when AP_REMOVE_UI is set to true. + * + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function test_should_not_enqueue_style_when_ap_remove_ui_is_true() { + // Prevent the notice from being displayed. + define( 'AP_REMOVE_UI', true ); + + $hook = is_multisite() ? 'plugins-network' : 'plugins'; + $branding = new AspireUpdate\Branding(); + $branding->admin_enqueue_scripts( $hook ); + $this->assertFalse( wp_style_is( 'aspire_update_settings_css' ) ); + } +} diff --git a/tests/Branding/Branding_ConstructTest.php b/tests/Branding/Branding_ConstructTest.php new file mode 100644 index 0000000..bb05fc1 --- /dev/null +++ b/tests/Branding/Branding_ConstructTest.php @@ -0,0 +1,129 @@ +assertIsInt( has_action( $hook, [ $branding, $method ] ) ); + } + + /** + * Test that hooks are not added when API rewriting is disabled in single-site. + * + * @dataProvider data_single_site_hooks_and_methods + * + * @group ms-excluded + * + * @runInSeparateProcess + * @preserveGlobalState disabled + * + * @string $hook The hook's name. + * @string $method The method to hook. + */ + public function test_should_not_add_hooks_in_single_site( $hook, $method ) { + define( 'AP_ENABLE', false ); + + $branding = new AspireUpdate\Branding(); + $this->assertFalse( has_action( $hook, [ $branding, $method ] ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_single_site_hooks_and_methods() { + return [ + 'admin_notices -> output_admin_notice' => [ + 'hook' => 'admin_notices', + 'method' => 'output_admin_notice', + ], + 'admin_enqueue_scripts -> admin_enqueue_scripts' => [ + 'hook' => 'admin_enqueue_scripts', + 'method' => 'admin_enqueue_scripts', + ], + ]; + } + + /** + * Test that hooks are added when API rewriting is enabled in multisite. + * + * @dataProvider data_multisite_hooks_and_methods + * + * @group ms-required + * + * @runInSeparateProcess + * @preserveGlobalState disabled + * + * @string $hook The hook's name. + * @string $method The method to hook. + */ + public function test_should_add_hooks_in_multisite( $hook, $method ) { + define( 'AP_ENABLE', true ); + + $branding = new AspireUpdate\Branding(); + $this->assertIsInt( has_action( $hook, [ $branding, $method ] ) ); + } + + /** + * Test that hooks are not added when API rewriting is disabled in multisite. + * + * @dataProvider data_multisite_hooks_and_methods + * + * @group ms-required + * + * @runInSeparateProcess + * @preserveGlobalState disabled + * + * @string $hook The hook's name. + * @string $method The method to hook. + */ + public function test_should_not_add_hooks_in_multisite( $hook, $method ) { + define( 'AP_ENABLE', false ); + + $branding = new AspireUpdate\Branding(); + $this->assertFalse( has_action( $hook, [ $branding, $method ] ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_multisite_hooks_and_methods() { + return [ + 'network_admin_notices -> output_admin_notice' => [ + 'hook' => 'network_admin_notices', + 'method' => 'output_admin_notice', + ], + 'admin_enqueue_scripts -> admin_enqueue_scripts' => [ + 'hook' => 'admin_enqueue_scripts', + 'method' => 'admin_enqueue_scripts', + ], + ]; + } +} diff --git a/tests/Branding/Branding_GetInstanceTest.php b/tests/Branding/Branding_GetInstanceTest.php new file mode 100644 index 0000000..fd21413 --- /dev/null +++ b/tests/Branding/Branding_GetInstanceTest.php @@ -0,0 +1,23 @@ +assertSame( + AspireUpdate\Branding::get_instance(), + AspireUpdate\Branding::get_instance() + ); + } +} diff --git a/tests/Branding/Branding_OutputAdminNoticeTest.php b/tests/Branding/Branding_OutputAdminNoticeTest.php new file mode 100644 index 0000000..7e5ffb9 --- /dev/null +++ b/tests/Branding/Branding_OutputAdminNoticeTest.php @@ -0,0 +1,141 @@ +assertStringContainsString( $expected, get_echo( [ $branding, 'output_admin_notice' ] ) ); + } + + /** + * Test that no admin notice is output on adjacent screens. + * + * @dataProvider data_screen_specific_messages + * + * @group ms-required + * + * @param string $hook The current screen's hook. + */ + public function test_should_not_output_notice_on_single_site_screens_in_multisite( $hook ) { + set_current_screen( $hook ); + + $branding = new AspireUpdate\Branding(); + $this->assertSame( '', get_echo( [ $branding, 'output_admin_notice' ] ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_screen_specific_messages() { + return [ + 'update-core' => [ + 'hook' => 'update-core', + 'expected' => 'WordPress, plugin, theme and translation updates', + ], + 'plugins' => [ + 'hook' => 'plugins', + 'expected' => 'plugin updates', + ], + 'plugin-install' => [ + 'hook' => 'plugin-install', + 'expected' => 'plugin updates', + ], + 'themes' => [ + 'hook' => 'themes', + 'expected' => 'theme updates', + ], + 'theme-install' => [ + 'hook' => 'theme-install', + 'expected' => 'theme updates', + ], + ]; + } + + /** + * Test that no admin notice is output on adjacent screens. + * + * @dataProvider data_adjacent_screens + * + * @param string $hook The current screen's hook. + */ + public function test_should_not_output_notice_on_adjacent_screens( $hook ) { + if ( is_multisite() ) { + $hook .= '-network'; + } + set_current_screen( $hook ); + + $branding = new AspireUpdate\Branding(); + $this->assertSame( '', get_echo( [ $branding, 'output_admin_notice' ] ) ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_adjacent_screens() { + return self::text_array_to_dataprovider( + [ + 'dashboard', + 'nav-menus', + 'plugin-editor', + ] + ); + } + + /** + * Test that no admin notice is output when there is no screen. + */ + public function test_should_not_output_notice_when_there_is_no_screen() { + global $current_screen; + $current_screen_backup = $current_screen; + unset( $current_screen ); + + $branding = new AspireUpdate\Branding(); + $actual = get_echo( [ $branding, 'output_admin_notice' ] ); + $current_screen = $current_screen_backup; + + $this->assertSame( '', $actual ); + } + + /** + * Test that no admin notice is output when AP_REMOVE_UI is set to true. + * + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function test_should_not_output_notice_when_ap_remove_ui_is_true() { + // Set to a screen that should display an admin notice. + set_current_screen( is_multisite() ? 'plugins-network' : 'plugins' ); + + // Prevent the notice from being displayed. + define( 'AP_REMOVE_UI', true ); + + $branding = new AspireUpdate\Branding(); + $this->assertSame( '', get_echo( [ $branding, 'output_admin_notice' ] ) ); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index b851569..c44d4d8 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -33,7 +33,6 @@ function _manually_load_plugin() { require dirname( __DIR__ ) . '/aspire-update.php'; - } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); diff --git a/tests/multisite.xml b/tests/multisite.xml new file mode 100644 index 0000000..1536460 --- /dev/null +++ b/tests/multisite.xml @@ -0,0 +1,41 @@ + + + + + + + + + ./ + + + + + ms-excluded + + + + + ../includes + + + ../includes/autoload.php + + + + + + +