Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
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.
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.

View File

@@ -0,0 +1,424 @@
=== Advanced Database Cleaner ===
Contributors: symptote
Donate Link: https://www.sigmaplugin.com/donation
Tags: clean, database, optimize, performance, postmeta
Requires at least: 3.1.0
Requires PHP: 5.0
Tested up to: 6.8
Stable tag: 3.1.7
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Clean database by deleting orphaned data such as 'revisions', 'expired transients', optimize database and more...
== Description ==
Clean up database by deleting orphaned items such as 'old revisions', 'spam comments', optimize database and more...
If you have been using WordPress for a while, then you should think absolutely about a database cleanup. Indeed, your database may be full of garbage that makes your site sluggish and bloated such as old revisions, orphaned post meta, spam comments, etc. You should clean-up this unnecessary data to reduce your database size and improve website speed and performance. In addition, you will have quicker database backup since the file of your backup will be smaller.
'Advanced Database Cleaner' is a must-have plugin that allows you to clean database, optimize database and more.
= Main Features =
* Delete old revisions of posts and pages
* Delete old auto drafts
* Delete trash posts
* Delete pending comments
* Delete spam comments
* Delete trash comments
* Delete pingbacks
* Delete trackbacks
* Delete orphan post metadata
* Delete orphan comment metadata
* Delete orphan user metadata
* Delete orphan term metadata
* Delete orphan relationships
* Delete expired transients
* Display and view orphaned information before making a database clean-up so you can be sure about what you are going to clean-up
* Search & filter all items based on their names or values
* Keep last x days' data from being cleaned: clean only data older than the number of days you have specified
* Schedule database clean up to run automatically
* Create as many scheduled cleanup tasks as you need and specify what items should be cleaned by the scheduled task
* Scheduled tasks can be executed based on several frequencies: Once, hourly, twice a day, daily, weekly or monthly
* Display database tables information such as the number of rows, table size, etc.
* Optimize database tables (The plugin will notify you if any tables require optimization)
* Repair corrupted database tables or damaged ones (The plugin will notify you if any tables are corrupted or damaged)
* Schedule database optimization and/or reparation to run automatically and specify what tables should be optimized and/or repaired
* Empty database tables rows
* Clean and delete database tables
* Display options list
* Display options information such as option name, option value, option size, option autoload
* Clean and delete options
* Set options autoload to no / yes
* Display active cron tasks list (scheduled tasks) with their information such as arguments, next run, etc.
* Clean and delete scheduled tasks
* User-friendly and simple to use
= Multisite Support =
* The plugin is compatible with Multisite installations
* Only the main site can view, clean and optimize the whole network. Other sites in the network cannot perform these tasks. We have opted for this philosophy because we are sure that your DB is precious and only the super administrator can perform such actions
* You can clean up all sites from one place (the main site). You can also specify specific sites you want to cleanup
= By using the ADC plugin, you will =
* <strong>Get an overview:</strong> The plugin will help you get an overview of what is happening in your database. It will report all unused/orphaned items that should be cleaned, it will give you the number of tables/options/tasks you have, etc. This way, you can control your database if anything goes wrong
* <strong>Save time:</strong> You can specify what items should be cleaned/optimized/repaired, what is the number of days' data to keep and the cleanup/optimization/reparation frequency. The plugin will then automate the process to run automatically based on your settings
* <strong>Save space:</strong> By deleting unused/orphaned items, you will save space in your database and make quicker backups since the file of your backup will be smaller
= Pro Features (<a href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner">Official website</a>) =
Do you know that even after deleting a plugin/theme from your WordPress website, some of its leftovers may remain in your database? Such as orphan options, orphan tables, and orphan cron tasks. As you may know, not all plugins/themes care about the housekeeping of your WordPress database. As long as you are removing plugins/themes, leftovers will be accumulated in your database and will influence your website performance. The Pro version of Advanced Database Cleaner will help you remove all those leftovers and perform a deep database clean up. In the pro version you can:
* Classify options according to their "creator". They can be either: plugins options, themes options or WP core options
* Detect and delete orphan options. Your 'wp_options' table may be full of orphaned options and therefore can impact the performance of loading data from it, which may lead to a slow website. Clean up orphaned options is then important
* Classify tables according to their "creator". They can be either: plugins tables, themes tables or WP core tables
* Detect and delete orphan tables. As for options, you may also have some orphaned tables that were created by plugins/themes you are not using anymore. Clean up orphaned tables will decrease the size of your database
* Classify all cron tasks (cron jobs) according to their "creator". They can be either: plugins cron tasks, themes cron tasks or WP core tasks
* Detect and delete orphan cron jobs. After you uninstall a plugin/theme, some of its cron tasks may still be active making WordPress calling unknown functions. using the pro version, you can detect and clean orphaned tasks
* Search & filter options, filter tables and filter cron tasks based on several criteria such as the "name", "creator", "value", etc.
* Get premium support: we will provide quick support as well as any technical answers to help you clean up your database efficiently
= Translations =
You are welcome to contribute to the plugin translation via the [WordPress translation website](https://translate.wordpress.org/projects/wp-plugins/advanced-database-cleaner).
= Thanks To =
* [Fabio Fava](https://profiles.wordpress.org/fabiofava) for translating the plugin to pt_BR
* [Julio Potier](https://profiles.wordpress.org/juliobox) for the security remarks
== Installation ==
This section describes how to install the plugin. In general, there are 3 ways to install this plugin like any other WordPress plugin.
= 1. Via WordPress dashboard =
* Click on 'Add New' in the plugins dashboard
* Search for 'advanced-database-cleaner'
* Click 'Install Now' button
* Activate the plugin from the same page or from the Plugins dashboard
= 2. Via uploading the plugin to WordPress dashboard =
* Download the plugin to your computer from (https://wordpress.org/plugins/advanced-database-cleaner/)
* Click on 'Add New' in the plugins dashboard
* Click on 'Upload Plugin' button
* Select the zip file of the plugin that you have downloaded to your computer before
* Click 'Install Now'
* Activate the plugin from the Plugins dashboard
= 3. Via FTP =
* Download the plugin to your computer from (https://wordpress.org/plugins/advanced-database-cleaner/)
* Unzip the zip file, which will extract the 'advanced-database-cleaner-3.0.0' directory
* Upload the 'advanced-database-cleaner' directory (included inside the extracted folder) to the /wp-content/plugins/ directory in your web space
* Activate the plugin from the Plugins dashboard
= For Multisite installation =
* Log in to your primary site and go to "My Sites" &raquo; "Network Admin" &raquo; "Plugins"
* Install the plugin following one of the above ways
* Network activate the plugin (Note that only the main site can have access to the plugin)
= Where the plugin menu will be displayed? =
* The plugin page can be accessed via "Dashboard" &raquo; "Tools" &raquo; "WP DB Cleaner" or via the left menu "WP DB Cleaner" (You can change this via the plugin settings)
== Screenshots ==
1. Database with items to clean
2. View items before cleaning them (case of revisions)
3. Cleanup scheduled task
4. Tables overview (scan of tables is available in PRO)
5. Tables optimization/repair scheduled task
6. Options overview (scan of options is available in PRO)
7. Scheduled tasks overview (scan of tasks is available in PRO)
8. Overview and settings page
== Changelog ==
= 3.1.7 - 22/10/2025 =
- Fix: enhanced security by adding a missing nonce (thanks to Bao BlueRock via Wordfence)
- Announcement: stay tuned! A completely new version will be available by the end of November 2025, featuring a brand-new design and exciting new features. The PRO version has also been significantly improved with additional functionality.
= 3.1.6 - 24/03/2025 =
- Fix: names containing HTML were not displayed correctly.
- Fix: certain transients, options, tables, and cron jobs could not be deleted.
- Fix: function _load_textdomain_just_in_time was called incorrectly.
- Fix: after optimizing tables, the plugin now refreshes the data to accurately reflect the databases real status.
- Fix: enhanced the plugin's security.
- Fix (PRO): sometimes users were unable to deactivate their license.
- Tweak: improved how the plugin edits the autoload value for options.
- Tweak: increased the max_execution_time only after a scan has started, and under specific conditions.
- Tweak: cleaned up and enhanced some PHP, CSS, and JS code parts.
- New: the Options tab now displays the total size of autoloaded options.
- New: in Multisite, users can now choose to display the plugin menu in the Network Admin panel.
- New (PRO): added support for new autoload option values in filters: on, auto, auto-on, auto-off.
- New (PRO): users can now assign items to WordPress using the “manual categorization” feature.
= 3.1.5 - 19/09/2024 =
- Fix: Automatic conversion of false to array is deprecated
- Fix: Cannot modify header information - headers already sent..
- Fix: Object of class stdClass could not be converted to string
= 3.1.4 - 23/01/2024 =
- Security: enhancing the security by avoiding deserialization (thanks to Richard Telleng from Wordfence)
- PRO: fix endless scan reloading
- PRO: fix PHP warning: Implicit conversion from float to int
- PRO: some code cleanup
= 3.1.3 - 12/09/2023 =
- Security: enhancing the security by sanitizing some parameters
- Fix: fixed 'Constant FILTER_SANITIZE_STRING is deprecated in PHP 8'
- Fix: fixed 'Undefined property : stdClass::$data_free'
- Fix: fixed 'PHP Fatal error: Uncaught TypeError: date(): Argument #2 ($timestamp) must be of type ?int'
- Tweak: better handling of nonces
- Compatibility: tested with the latest version of WordPress 6.3.1
= 3.1.2 - 22/02/2023 =
- Security fix: when saving the settings
- Fix: changing the 'autoload' of an option may sometimes result in it being created twice
- Fix: activating both the free and pro versions together causes compatibility issues
- Tweak: enhancing some blocks of code to use Ajax
- Tweak: better handling the use of the WP_List_Table class
- Tweak (PRO): enhancing the license page + the update process of the plugin
- Compatibility: Tested with the latest version of WordPress 6.1.1
= 3.1.1 - 24/06/2022 =
- Security fix: enhancing the security of the plugin by escaping some URLs before outputting them
= 3.1.0 - 16/06/2022 =
- Fix: fixing the error 'Fatal error: Can't use function return value in write context'
- Fix: fixing the Warning: count(): Parameter must be an array or an object that implements Countable
- Tweak: correcting of some typos and grammar
- Tweak: deleting some useless data from "overview & settings" tab
- Tweak: enhancing the CSS code, the plugin is responsive now and can be used in small screens
- Tweak: enhancing some blocks of PHP code
- New: adding “delete filter” for custom cleanup elements in “general cleanup” tab
- Info: since we have changed a lot of CSS code, please refresh your browser cache or click "Ctrl + F5"
- Info: great feature will be added to the next version
= 3.0.4 - 21/01/2022 =
- Tweak: Enhancing the security of the plugin
- Tweak: Testing the plugin with latest versions of WP
= 3.0.3 - 06/10/2020 =
- Tweak: Cleaning the code by deleting unused blocks of code
- Tweak: Enhancing the security of the plugin
= 3.0.2 - 01/09/2020 =
- Fix: fixing an issue in the general cleanup tab preventing users from deleting orphaned items
- Tweak: we are now using SweetAlert for all popup boxes
- Tweak: enhancing the JavaScript code
- Tweak: enhancing some blocks of code
- Tweak: enhancing the security of the plugin
= 3.0.1 - 26/08/2020 =
- Fix: some calls in the JS file has been corrected
- Fix: the warning "Deprecated: array_key_exists()" is now solved
- Fix: an issue of 'failed to open stream: No such file or directory' is now solved
- Tested with WordPress 5.5
- New features very soon!
= 3.0.0 - 05/12/2019 =
* IMPORTANT NOTICE FOR PRO USERS: After you upgrade to 3.0.0 from an old version, you will notice that WordPress has deactivated the plugin due to an error: 'Plugin file does not exist'. This is because we have renamed the pro plugin folder name from "advanced-db-cleaner" to "advanced-database-cleaner-pro", causing the WordPress to not being able to find the old one and therefore deactivating the plugin. Just activate it again. It doesnt break anything. Once you activate the plugin again it will continue working normally without any issues. You will also probably lose the pro version after this upgrade (This is due to a conflict between the free and pro versions which is now solved). If it is the case, please follow these steps to restore your pro version with all new features: (https://sigmaplugin.com/blog/restore-pro-version-after-upgrade-to-3-0-0)
* COMPATIBILITY: The plugin is tested with WordPress 5.3
* CHANGE: Some changes to readme.txt file
* REMOVE: Drafts are not cleaned anymore in 3.0.0 since many users have reported that drafts are useful for them
* New: You can now clean up new items: pingbacks, trackbacks, orphaned user meta, orphaned term meta, expired transients
* New: The plugin icon in the left side menu has been changed to white color
* New: Change text-domain to 'advanced-database-cleaner'
* New: Enhancements to the look and feel of the plugin
* New: The sidebar has been changed for the free version and deleted in the pro version
* New: For options, we have added the option size column and two new actions: Set autoload to no / yes
* New: For tables, we have added two actions: Empty tables and repair tables
* New: You can now order and sort all items
* New: You can change the number of items per page
* New: You can keep last x days' data from being cleaned and clean only data older than the number of days you have specified
* New: You can specify elements to cleanup in a scheduled task. You can also create as many scheduled tasks as you need
* New: Add information to each line of unused data in 'General clean-up' tab to let users know more about each item they will clean
* New: Display/view items before cleaning them (in 'General cleanup' tab) is now in the free version
* New: Add a new setting to hide the "premium" tab in the free version
* Fix: Repair some strings with correct text domain
* Fix: Some tasks with arguments can't be cleaned. This is fixed now
* Fix: Some tasks with the same hook name and different arguments were not displayed. This is fixed now
* Fix: In some previous versions, tables were not shown for some users. This has been fixed
* PERFORMANCE: All images used by the plugin are now in SVG format
* PERFORMANCE: Restructuring the whole code for better performance
* SECURITY: add some _wpnonce to forms
* New (PRO): Add "Pro" to the title of the pro version to distinguish between the free and the pro versions
* New (PRO): You can now search and filter all elements: options, tables, tasks, etc. based on several criteria
* New (PRO): Add progress bar when searching for orphan items to show remaining items to process
* New (PRO): Add a category called "uncategorized" to let users see items that have not been categorized yet
* Fix (PRO): The activation issue is now fixed
* Fix (PRO): The scan of orphaned items generated timeout errors for big databases, we use now ajax to solve this
* Fix (PRO): A conflict between the free and the pro versions is now solved
* PERFORMANCE (PRO): We are now using an enhanced new update class provided by EDD plugin
* PERFORMANCE (PRO): Set autoload to no in all options used by the plugin
* PERFORMANCE (PRO): The plugin does not store scan results in DB anymore. We use files instead
* SECURITY (PRO): The license is now hidden after activation for security reasons
* WEBSITE (PRO): You can now view your purchase history, downloads, generate an invoice, upgrade your license, etc. [Read more](https://sigmaplugin.com/blog/how-to-get-access-to-my-account-and-downloads)
* WEBSITE (PRO): Enhancements of the [plugin premium page](https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner)
= 2.0.0 =
* Some changes to readme.txt file
* Changing the way the plugin can be translated
* Correcting __() to some texts
* Correcting some displaying texts
* Big change in styles
* Restructuring the whole code for better performance
* Creation of the plugin main page: (https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner)
* Adding language translation support
* Correct the time zone offset for the scheduled tasks
* Skipping InnoDB tables while optimizing
* Change size of lost tables data from 'o' to 'KB'
* Main menu is now under 'Tools' not 'settings'
* Adding separate left menu (can be disabled)
* Adding overview page with some useful information
* Adding settings page
* "Reset database" is now in a separate plugin (please view our plugins page)
* Multisite: now only the main site can clean the network
* New feature: Display/view items before cleaning them (Pro)
* New feature: view and clean options
* New feature: Detect orphan options, plugins options, themes options and WP options (Pro)
* New feature: view and clean cron (scheduled tasks)
* New feature: Detect orphan tasks, plugins tasks, themes tasks and WP tasks (Pro)
* New feature: view and clean database tables
* New feature: Detect orphan tables, plugins tables, themes tables and WP tables (Pro)
= 1.3.7 =
* Adding "clean trash-posts"
* Updating FAQ
* Updating readme file
* Tested up to: 4.4
= 1.3.6 =
* Fixing a problem in donate button
* Using _e() and __() for all texts in the plugin
= 1.3.5 =
* New feature: Adding "Clean Cron". You can now clean unnecessary scheduled tasks.
* Updating FAQ
= 1.3.1 =
* Adding FAQ
= 1.3.0 =
* Some code optimizations
* New feature: Support multisite. You can now clean and optimize your database in multisite installation.
= 1.2.3 =
* Some optimizations and style modifications
* New feature: Adding the scheduler. You can now schedule the clean-up and optimization of your database.
= 1.2.2 =
* Some optimizations and style modifications
= 1.2.1 =
* Some optimizations and style modifications
* "Clean database" tab shows now only elements that should be cleaned instead of listing all elements.
* "Clean database" tab shows now an icon that indicates the state of your database.
* "Optimize database" tab shows now only tables that should be optimized instead of listing all tables.
* "Optimize database" tab shows now an icon that indicates the state of your tables.
* "Reset database" shows now a warning before resetting the database.
= 1.2.0 =
* Some optimizations and style modifications
* New feature: Adding "Reset database"
= 1.1.1 =
* Some optimizations and style modifications
* Adding "Donate link"
= 1.1.0 =
* Some optimizations and style modifications
* New feature: Adding "Optimize Database"
= 1.0.0 =
* First release: Hello world!
== Upgrade Notice ==
= 3.0.0 =
Known issues have been fixed in both free and pro versions (timeout error, activation, scheduled tasks...) New features have been added (new items to cleanup, filter & sort items...) Readme.txt file updated.
= 2.0.0 =
New release.
== Frequently Asked Questions ==
= What does mean "clean my database"? =
As you use WordPress, your database accumulates a lot of extra data such as revisions, spam comments, trashed comments, etc. Removing this unnecessary data will reduce your database size, speeds up your backup process and speeds up your site also.
= Is it safe to clean my database? =
Yes, it is. We do not run any code that can break down your site or delete your posts, pages, comments, etc. However, make sure to always back up your database before any cleanup. This is not optional; it is required! It is always better to be safe than sorry!
= What does mean "Optimize my database"? =
Optimizing your database will reclaim unused space in your tables, which will reduce storage space and improve efficiency when accessing tables. Optimizing the database can sometimes significantly improve performance, particularly on sites that receive a lot of traffic or have a large amount of content. Optimizing your database is absolutely safe.
= Is it safe to clean the cron (scheduled tasks)? =
A scheduled task enables plugins to execute some actions at specified times, without having to manually execute code at that time. Wordpress itself uses some scheduled tasks to perform some regular actions. However, some scheduled tasks may not be removed even if the responsible plugins are deleted from your WordPress installation. As you know, not all plugins care about the housekeeping of your WordPress. Hence, deleting these unnecessary tasks may help in cleaning your site. It should be noted that cleaning scheduled tasks is safe as long as you know what tasks to clean. If you are not sure, it is better to not clean any task.
= What does mean "Revision"? What sql code is used to clean it? =
WordPress stores a record (called "revision") of each saved draft or published update. This system allows you to see what changes were made in each post and page over time. However, this can lead to a lot of unnecessary overhead in your WordPress database, which consumes a lot of space. The sql query used by the plugin to clean all revisions is:
`DELETE FROM posts WHERE post_type = 'revision'`
= What does mean "Auto-draft"? What sql code is used to clean it? =
Wordpress automatically saves your post/page while you are editing it. This is called an auto-draft. If you don't hit the publish/update button, then the post/page will be saved as auto-draft and any modification to your post/page will not be visible in your public site. Over time, you could have multiple auto-drafts that you will never publish and hence you can clean them. The sql query used by the plugin to clean all auto-drafts is:
`DELETE FROM posts WHERE post_status = 'auto-draft'`
= What does mean "Pending comment"? What sql code is used to clean it? =
Pending comments are comments published by users and which are waiting for your approval before appearing in your site. In some cases, you will have to clean all these comments. The sql query used by the plugin to clean all pending comments is:
`DELETE FROM comments WHERE comment_approved = '0'`
= What does mean "Spam comment"? What sql code is used to clean it? =
It is a comment that you (or a plugin) have marked as spam. The sql query used by the plugin to clean all spam comments is:
`DELETE FROM comments WHERE comment_approved = 'spam'`
= What does mean "Trash comment"? What sql code is used to clean it? =
A trash comment is a comment that you have deleted from your Wordpress and have been moved to the trash. A trash comment is not visible in your site and should be deleted forever. The sql query used by the plugin to clean all trash comments is:
`DELETE FROM comments WHERE comment_approved = 'trash'`
= What does mean "trackback"? What sql code is used to clean it? =
Trackbacks allows you to notify other websites owners that you have linked to their article on your website. These trackbacks can be used to send huge amounts of spam. Spammers use them to get their links posted on as many sites as possible. That is why they should be deactivated/cleaned if you do not use them. The sql query used by the plugin to clean trackbacks is:
`DELETE FROM comments WHERE comment_type = 'trackback'`
= What does mean "pingback"? What sql code is used to clean it? =
Pingbacks allow you to notify other websites owners that you have linked to their article on your website. Pingbacks were designed to solve some of the problems that people saw with trackbacks. Although there are some minor technical differences, a trackback is basically the same things as a pingback. These pingbacks can be used to send huge amounts of spam. Spammers use them to get their links posted on as many sites as possible. That is why they should be deactivated/cleaned if you do not use them. The sql query used by the plugin to clean pingbacks is:
`DELETE FROM comments WHERE comment_type = 'pingback'`
= What does mean "Orphan post meta"? What sql code is used to clean it? =
The post meta data is the information you provide to viewers about each post. This information usually includes the author of the post, when it was written (or posted), and how the author categorized that particular post. In some cases, some post meta data information becomes orphan and does not belong to any post. They are then called "orphan postmeta" and should be cleaned since they are not useful. The sql query used by the plugin to clean all orphan postmeta is:
`DELETE pm FROM postmeta pm LEFT JOIN posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL`
= What does mean "Orphan comment meta"? What sql code is used to clean it? =
The same as "Orphan post meta" with the exception that "orphan comment meta" concern comments and not posts. The sql query used by the plugin to clean all orphan comment meta is:
`DELETE FROM commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM comments)`
= What does mean "Orphan user meta"? What sql code is used to clean it? =
The user meta data is the information you provide to viewers about each user. This information usually includes additional data that is not stored in the users table of WordPress. In some cases, some user meta data information becomes orphaned and does not belong to any user. They are then called "orphaned usermeta" and should be cleaned since they are not useful. The sql query used by the plugin to clean all orphan comment meta is:
`DELETE FROM usermeta WHERE user_id NOT IN (SELECT ID FROM users)`
= What does mean "Orphan term meta"? What sql code is used to clean it? =
The term meta data is the information that is provided for each taxonomy term. This information usually includes additional data that is not stored in the terms table of WordPress. In some cases, some term meta data information becomes orphaned and does not belong to any taxonomy term. They are then called "orphaned termmeta" and should be cleaned since they are not useful. The sql query used by the plugin to clean all orphan comment meta is:
`DELETE FROM termmeta WHERE term_id NOT IN (SELECT term_id FROM terms)`
= What does mean "Orphan relationships"? What sql code is used to clean it? =
Sometimes the wp_term_relationships table becomes bloated with many orphaned relationships. This happens particularly often if youre using your site not as a blog but as some other type of content site where posts are deleted periodically. Over time, you could get thousands of term relationships for posts that no longer exist which consumes a lot of database space. The sql query used by the plugin to clean all orphan relationships is:
`DELETE FROM term_relationships WHERE term_taxonomy_id=1 AND object_id NOT IN (SELECT id FROM posts)`
= What does mean "expired transient"? =
Transients are a way of storing cached data in the WordPress DB temporarily by giving it a name and a time frame after which it will expire and be deleted. This helps improve WordPress performance and speed up your website while reducing the overall server load. Expired transients are transients that are expired and still exist in the database. These ones can be safely cleaned. Transients housekeeping is now part of WordPress core, as of version 4.9, so no need to clean up them manually unless you have specific needs.
= Is this plugin compatible with multisite? =
Yes, it is compatible with multisite. It should be noted that only the main site in the network can clean the database and orphan items of all the network. We prevent other sites to clean your DB since we believe that only the super administrator has the right to perform such operation. Your database is precious!
= Is this plugin compatible with SharDB, HyperDB or Multi-DB? =
Actually the plugin is not supposed to be compatible with SharDB, HyperDB or Multi-DB. We will try to make it compatible in the coming releases.
= Does this plugin cleans itself after the uninstall? =
We do clean-up of your WordPress site, it will be a shame if the plugin does not clean itself after an uninstall! Of course yes, the plugin cleans itself and removes any data used to store its settings once uninstalled.

View File

@@ -0,0 +1,954 @@
<?php
/*
Plugin Name: Advanced Database Cleaner
Plugin URI: https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner
Description: Clean database by deleting unused data such as 'old revisions', 'old drafts', 'orphan options', etc. Optimize database and more.
Version: 3.1.7
Author: Younes JFR.
Author URI: https://www.sigmaplugin.com
Contributors: symptote
Text Domain: advanced-database-cleaner
Domain Path: /languages/
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/
// Don't load directly
if ( ! defined( 'ABSPATH' ) ) return;
if ( ! is_main_site() ) return;
class ADBC_Advanced_DB_Cleaner {
public function __construct() {
/***************************************************************************
* Prevent conflict between free and pro versions
***************************************************************************/
if ( ! function_exists( 'deactivate_plugins' ) ) include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
// Prevent conflict between free and pro versions
if ( is_plugin_active( 'advanced-database-cleaner-pro/advanced-db-cleaner.php' ) &&
is_plugin_active( 'advanced-database-cleaner/advanced-db-cleaner.php' ) ) {
// Deactivate the free version in silent mode to keep scheduled tasks for pro
deactivate_plugins( 'advanced-database-cleaner/advanced-db-cleaner.php', true );
add_action( 'admin_notices', array( $this, 'aDBc_conflict_notice_free' ) );
return;
}
// Prevent conflict between new pro and old pro versions
if ( is_plugin_active( 'advanced-database-cleaner-pro/advanced-db-cleaner.php' ) &&
is_plugin_active( 'advanced-db-cleaner/advanced-db-cleaner.php' ) ) {
// Deactivate the old pro in silent mode to keep scheduled tasks for pro
deactivate_plugins( 'advanced-db-cleaner/advanced-db-cleaner.php', true );
add_action( 'admin_notices', array( $this, 'aDBc_conflict_notice_old_pro' ) );
return;
}
/***************************************************************************
* Add actions and filters
***************************************************************************/
// Load plugin
add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
// Load text-domain
add_action( 'init', array( $this, 'aDBc_init' ) );
// Load CSS and JS
add_action( 'admin_enqueue_scripts', array( $this, 'aDBc_load_styles_and_scripts' ) );
// Add some schedules
add_filter( 'cron_schedules', array( $this, 'aDBc_additional_schedules' ) );
// Add actions for scheduled events
add_action( 'aDBc_optimize_scheduler', 'aDBc_optimize_scheduled_tables' );
add_action( 'aDBc_clean_scheduler', 'aDBc_clean_scheduled_elements' );
// Register activation, deactivation and uninstall hooks of the plugin
register_activation_hook ( __FILE__, array( $this, 'aDBc_activate_plugin' ) );
register_deactivation_hook ( __FILE__, array( $this, 'aDBc_deactivate_plugin' ) );
register_uninstall_hook ( __FILE__, array( 'ADBC_Advanced_DB_Cleaner', 'aDBc_uninstall' ) );
// Ignore admin notice if needed + ignore double check if needed
add_action( 'admin_init', array( $this, 'aDBc_ignore_notice' ) );
// Add admin notice to rate plugin
add_action( 'admin_notices', array( $this, 'aDBc_rate_notice' ) );
}
// Do this on plugins loaded : load text-domain and check if we should update settings in DB
public function plugins_loaded() {
/***************************************************************************
* Define common constants and variables (we switch all "\" to "/" in paths)
***************************************************************************/
if( ! defined( "ADBC_PLUGIN_VERSION" ) ) define( "ADBC_PLUGIN_VERSION", "3.1.7" );
if( ! defined( "ADBC_PLUGIN_PLAN" ) ) define( "ADBC_PLUGIN_PLAN", "free" );
if ( ! defined( "ADBC_PLUGIN_DIR_PATH" ) ) define( "ADBC_PLUGIN_DIR_PATH", plugins_url( '' , __FILE__ ) );
// Main Plugin file
if ( ! defined( "ADBC_MAIN_PLUGIN_FILE_PATH" ) ) define( "ADBC_MAIN_PLUGIN_FILE_PATH", str_replace( '\\' ,'/', __FILE__ ) );
// ABSPATH without trailing slash
if ( ! defined( "ADBC_ABSPATH" ) ) define( "ADBC_ABSPATH", rtrim( str_replace( '\\' ,'/', ABSPATH ), "/" ) );
// WP Content directory
if ( ! defined( "WP_CONTENT_DIR" ) ) define( "WP_CONTENT_DIR", ABSPATH . 'wp-content' );
if ( ! defined( "ADBC_WP_CONTENT_DIR_PATH" ) ) define( "ADBC_WP_CONTENT_DIR_PATH", str_replace( '\\' ,'/', WP_CONTENT_DIR ) );
// WP Plugin directory path & name
if ( ! defined( "WP_PLUGIN_DIR" ) ) define( "WP_PLUGIN_DIR", WP_CONTENT_DIR . '/plugins' );
if ( ! defined( "ADBC_WP_PLUGINS_DIR_PATH" ) ) define( "ADBC_WP_PLUGINS_DIR_PATH", str_replace( '\\' ,'/', WP_PLUGIN_DIR ) );
// MU Must have plugin path & name
if ( ! defined( "WPMU_PLUGIN_DIR" ) ) define( "WPMU_PLUGIN_DIR", WP_CONTENT_DIR . '/mu-plugins' );
if ( ! defined( "ADBC_WPMU_PLUGIN_DIR_PATH" ) ) define( "ADBC_WPMU_PLUGIN_DIR_PATH", str_replace( '\\' ,'/', WPMU_PLUGIN_DIR ) );
// WP Uploads directory & name
$aDBc_upload_dir = wp_upload_dir();
if ( ! defined( "ADBC_UPLOAD_DIR_PATH" ) ) define( "ADBC_UPLOAD_DIR_PATH", str_replace( '\\' ,'/', $aDBc_upload_dir['basedir'] ) );
/***************************************************************************
* Include functions and add Ajax functions
***************************************************************************/
include_once 'includes/functions.php';
// Add Ajax functions used by both free and pro versions
add_action( 'wp_ajax_aDBc_save_settings_callback', 'aDBc_save_settings_callback' );
// In pro, include these as well
if ( ADBC_PLUGIN_PLAN == "pro" ) {
include_once 'includes/functions_pro.php';
register_shutdown_function( 'aDBc_shutdown_due_to_timeout' );
include_once 'includes/license/adbc-edd-sample-plugin.php';
add_action( 'wp_ajax_aDBc_license_actions_callback', 'aDBc_license_actions_callback' );
add_action( 'wp_ajax_aDBc_new_run_search_for_items', 'aDBc_new_run_search_for_items' );
add_action( 'wp_ajax_aDBc_get_progress_bar_width', 'aDBc_get_progress_bar_width' );
add_action( 'wp_ajax_aDBc_double_check_items', 'aDBc_double_check_items' );
add_action( 'wp_ajax_aDBc_stop_search', 'aDBc_stop_search' );
add_action('wp_ajax_aDBc_hide_not_categorized_yet_msg', 'aDBc_hide_not_categorized_yet_msg');
}
/***************************************************************************
* Add default settings if needed
***************************************************************************/
$settings = get_option( 'aDBc_settings' );
// Check if the option is not set or returns false
if ( $settings === false || empty( $settings ) ) {
$settings = array(); // Initialize an empty array
if (is_multisite()){
$settings['network_menu'] = 1;
$settings['left_menu'] = 0;
$settings['menu_under_tools'] = 0;
} else {
$settings['left_menu'] = 1;
$settings['menu_under_tools'] = 1;
}
$settings['plugin_version'] = ADBC_PLUGIN_VERSION;
$settings['installed_on'] = date( "Y/m/d" );
update_option( 'aDBc_settings', $settings, "no" );
}
/**************************************************************************************************************
*
* In pro, define & create adbc upload folder or rename existing one by adding security code for versions < 3.1.0
* In version >= 3.0.0 of ADBC, we are using files to store scan data instead of database
* In version >= 3.1.0, we've added a unique security code to the end of the folder
*
**************************************************************************************************************/
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$aDBc_security_folder_code = get_option( 'aDBc_security_folder_code' );
// If the security code does not exist, generate a new one
if ( empty( $aDBc_security_folder_code ) ) {
$permitted_chars = '00112233445566778899abcdefghijklmnopqrstuvwxyz';
$aDBc_security_folder_code = substr( str_shuffle( $permitted_chars ), 0, 12 );
update_option( 'aDBc_security_folder_code', $aDBc_security_folder_code, "no" );
}
// Define ADBC upload folder name with the security code
if ( ! defined( "ADBC_UPLOAD_DIR_PATH_TO_ADBC" ) ) {
define( "ADBC_UPLOAD_DIR_PATH_TO_ADBC", ADBC_UPLOAD_DIR_PATH . '/adbc_uploads_' . $aDBc_security_folder_code );
}
// Test of the old folder "/adbc_uploads" exists. If so, rename it by adding new security code
if ( file_exists( ADBC_UPLOAD_DIR_PATH . '/adbc_uploads' ) ) {
rename( ADBC_UPLOAD_DIR_PATH . '/adbc_uploads', ADBC_UPLOAD_DIR_PATH . '/adbc_uploads_' . $aDBc_security_folder_code );
} else {
// Create the new folder with the security code
if ( ! file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC ) ) {
aDBc_create_folder_plus_index_file( ADBC_UPLOAD_DIR_PATH_TO_ADBC );
}
}
}
// Define & increase timeout
if ( ! defined( "ADBC_ORIGINAL_TIMEOUT" ) ) {
define( "ADBC_ORIGINAL_TIMEOUT", ini_get( 'max_execution_time' ) );
}
// Add plugin menu to Wordpress admin dashboard in main site
add_action('admin_menu', array($this, 'aDBc_add_admin_menu'));
// Add plugin menu to network admin in multisite
if (function_exists('is_multisite') && is_multisite()) {
add_action('network_admin_menu', array($this, 'aDBc_add_network_admin_menu'));
}
// If plugin get updated, make changes to old version
$this->aDBc_update_plugin_check();
}
// Load text-domain
function aDBc_init() {
// Load text-domain
load_plugin_textdomain('advanced-database-cleaner', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
// Show notice if conflict detected between free and pro versions
function aDBc_conflict_notice_free() {
echo '<div class="error"><p>';
_e( 'The free version of Advanced DB Cleaner has been de-activated since the pro version is active.', 'advanced-database-cleaner' );
echo "</p></div>";
}
// Show notice if conflict detected between old pro and new pro versions
function aDBc_conflict_notice_old_pro() {
echo '<div class="error"><p>';
_e( 'The old pro of Advanced DB Cleaner has been de-activated since the new pro version is active.', 'advanced-database-cleaner' );
echo "</p></div>";
}
// Add 'Database Cleaner' to Wordpress menu
function aDBc_add_admin_menu(){
global $aDBc_left_menu, $aDBc_tool_submenu;
$aDBc_settings = get_option('aDBc_settings');
$icon_svg = 'data:image/svg+xml;base64,' . base64_encode('<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#a0a5aa" d="M896 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-384q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-1152q208 0 385 34.5t280 93.5 103 128v128q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-128q0-69 103-128t280-93.5 385-34.5z"/></svg>');
// Add the menu to the admin dashboard in main site
if(!empty($aDBc_settings['left_menu']) && $aDBc_settings['left_menu'] != 0){
$aDBc_left_menu = add_menu_page('Advanced DB Cleaner', 'WP DB Cleaner', 'manage_options', 'advanced_db_cleaner', array($this, 'aDBc_main_page_callback'), $icon_svg, '80.01123');
}
if(!empty($aDBc_settings['menu_under_tools']) && $aDBc_settings['menu_under_tools'] != 0){
$aDBc_tool_submenu = add_submenu_page('tools.php', 'Advanced DB Cleaner', 'WP DB Cleaner', 'manage_options', 'advanced_db_cleaner', array($this, 'aDBc_main_page_callback'));
}
// In case the settings has been deleted by accident, create left menu
if (!is_multisite()) {
if(empty($aDBc_settings['left_menu']) && empty($aDBc_settings['menu_under_tools'])){
$aDBc_left_menu = add_menu_page('Advanced DB Cleaner', 'WP DB Cleaner', 'manage_options', 'advanced_db_cleaner', array($this, 'aDBc_main_page_callback'), $icon_svg, '80.01123');
}
}
}
// Add 'Database Cleaner' to network admin menu in multisite
function aDBc_add_network_admin_menu() {
global $aDBc_network_menu;
$aDBc_settings = get_option('aDBc_settings');
$icon_svg = 'data:image/svg+xml;base64,' . base64_encode('<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#a0a5aa" d="M896 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-384q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-1152q208 0 385 34.5t280 93.5 103 128v128q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-128q0-69 103-128t280-93.5 385-34.5z"/></svg>');
if((!empty($aDBc_settings['network_menu']) && $aDBc_settings['network_menu'] != 0) ||
(empty($aDBc_settings['left_menu']) && empty($aDBc_settings['menu_under_tools']) && empty($aDBc_settings['network_menu']))
){
// Add the menu to network admin dashboard
$aDBc_network_menu = add_menu_page('Advanced DB Cleaner', 'WP DB Cleaner', 'manage_network_options', 'advanced_db_cleaner', array($this, 'aDBc_main_page_callback'), $icon_svg, '80.01123');
}
}
// Load CSS and JS
function aDBc_load_styles_and_scripts($hook){
// Enqueue our js and css in the plugin pages only
global $aDBc_left_menu, $aDBc_tool_submenu, $aDBc_network_menu;
if($hook != $aDBc_left_menu && $hook != $aDBc_tool_submenu && $hook != $aDBc_network_menu){
return;
}
wp_enqueue_style('aDBc_css', ADBC_PLUGIN_DIR_PATH . '/css/admin.css', array(), ADBC_PLUGIN_VERSION);
wp_enqueue_style('aDBc_sweet2_css', ADBC_PLUGIN_DIR_PATH . '/css/sweetalert2.min.css');
wp_enqueue_script('aDBc_js', ADBC_PLUGIN_DIR_PATH . '/js/admin.js', array(), ADBC_PLUGIN_VERSION);
wp_enqueue_script('aDBc_sweet2_js', ADBC_PLUGIN_DIR_PATH . '/js/sweetalert2.min.js');
// The wp_localize_script allows us to output the ajax_url path for our script to use.
wp_localize_script('aDBc_js', 'aDBc_ajax_obj', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'network_admin_url' => network_admin_url(),
'is_multisite' => is_multisite() ? "1" : "0",
'images_path' => ADBC_PLUGIN_DIR_PATH . "/images/",
'ajax_nonce' => wp_create_nonce('aDBc_nonce'),
'sentence_scanning' => __( 'Scanning ...', 'advanced-database-cleaner' ),
'please_wait' => __( 'Please wait ...', 'advanced-database-cleaner' ),
'all_items' => __( 'All items', 'advanced-database-cleaner' ),
'all_items2' => __( 'Scan all items', 'advanced-database-cleaner' ),
'uncategorized' => __( 'Uncategorized', 'advanced-database-cleaner' ),
'scan_time_depends' => __( 'The scan time depends on your DB size and number of files', 'advanced-database-cleaner' ),
'scan_all_only' => __( 'The scan will process all items, continue?', 'advanced-database-cleaner' ),
'scan_all_or_u' => __( 'Do you want to scan all items or only uncategorized ones?', 'advanced-database-cleaner' ),
'unexpected_error' => __( 'Unexpected error! Please refresh the page and try again!', 'advanced-database-cleaner' ),
'select_action' => __( 'Please select an action!', 'advanced-database-cleaner' ),
'no_items_selected' => __( 'No items selected!', 'advanced-database-cleaner' ),
'clean_items_warning' => __( 'You are about to clean some of your unused data. This operation is irreversible!', 'advanced-database-cleaner' ),
'empty_tables_warning' => __( 'You are about to empty some of your tables. This operation is irreversible!', 'advanced-database-cleaner' ),
'are_you_sure' => __( 'Are you sure?', 'advanced-database-cleaner' ),
'make_db_backup_first' => __( 'Don\'t forget to make a backup of your database first!', 'advanced-database-cleaner' ),
'cancel' => __( 'Cancel', 'advanced-database-cleaner' ),
'Continue' => __( 'Continue', 'advanced-database-cleaner' ),
'active' => __( 'Active', 'advanced-database-cleaner' ),
'inactive' => __( 'Inactive', 'advanced-database-cleaner' )
));
//wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui-dialog');
wp_enqueue_style('wp-jquery-ui-dialog');
}
/******************************************************************************************
* Add some schedules
* Get more info here: http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
******************************************************************************************/
function aDBc_additional_schedules($schedules){
// hourly, daily and twice-daily are default schedules in WP, we will add weekly and monthly
// Add weekly schedule
$schedules['weekly'] = array(
'interval' => 604800,
'display' => __('Once weekly', 'advanced-database-cleaner')
);
// Add monthly schedule
$schedules['monthly'] = array(
'interval' => 2635200,
'display' => __('Once monthly', 'advanced-database-cleaner')
);
return $schedules;
}
// Register activation of the plugin (nothing to do)
function aDBc_activate_plugin(){}
// Register deactivation hook
function aDBc_deactivate_plugin($network_wide){
// Clean these in case there are any remaining tasks from older versions < 3.0.0. Those tasks were without arguments
wp_clear_scheduled_hook('aDBc_optimize_scheduler');
wp_clear_scheduled_hook('aDBc_clean_scheduler');
// Clear all schedules and update options in DB
// Clear clean tasks
$aDBc_clean_schedules = get_option('aDBc_clean_schedule');
$aDBc_clean_schedules = is_array($aDBc_clean_schedules) ? $aDBc_clean_schedules : array();
foreach($aDBc_clean_schedules as $task_name => $task_info){
wp_clear_scheduled_hook('aDBc_clean_scheduler', array($task_name));
// Set active to no in DB
$task_info['active'] = 0;
$aDBc_clean_schedules[$task_name] = $task_info;
update_option('aDBc_clean_schedule', $aDBc_clean_schedules, "no");
}
// Clear optimize tasks
$aDBc_optimize_schedules = get_option('aDBc_optimize_schedule');
$aDBc_optimize_schedules = is_array($aDBc_optimize_schedules) ? $aDBc_optimize_schedules : array();
foreach($aDBc_optimize_schedules as $task_name => $task_info){
wp_clear_scheduled_hook('aDBc_optimize_scheduler', array($task_name));
// Set active to no in DB
$task_info['active'] = 0;
$aDBc_optimize_schedules[$task_name] = $task_info;
update_option('aDBc_optimize_schedule', $aDBc_optimize_schedules, "no");
}
}
// Register UNINSTALL hook
public static function aDBc_uninstall() {
// Delete these ones in case they still in DB from older version < 3.0.0
delete_option( 'aDBc_options_status' );
delete_option( 'aDBc_tables_status' );
delete_option( 'aDBc_tasks_status' );
// Delete these options in pro
if ( __METHOD__ == 'ADBC_Advanced_DB_Cleaner_Pro::aDBc_uninstall' ) {
// These options should not exist after the scan. Make sure to clean them just in case
$array_items = array( 'options', 'tables', 'tasks' );
foreach ( $array_items as $item ) {
delete_option( 'aDBc_temp_last_iteration_' . $item );
delete_option( 'aDBc_temp_still_searching_' . $item );
delete_option( 'aDBc_temp_last_item_line_' . $item );
delete_option( 'aDBc_temp_last_file_line_' . $item );
delete_option( 'aDBc_last_search_ok_' . $item );
delete_option( 'aDBc_temp_total_files_' . $item );
delete_option( 'aDBc_temp_maybe_scores_' . $item );
delete_option( 'aDBc_temp_currently_scanning_' . $item );
delete_option( 'aDBc_temp_progress_scan_' . $item );
delete_option( 'aDBc_temp_progress_files_preparation_' . $item );
delete_option( 'aDBc_temp_last_collected_file_path_' . $item );
delete_option( 'aDBc_temp_items_to_scan_' . $item );
delete_option( 'aDBc_temp_scan_type_' . $item );
delete_option( 'aDBc_temp_current_scan_step_' . $item );
}
// Delete folder containing scan results
$aDBc_security_code = get_option( 'aDBc_security_folder_code' );
$aDBc_upload_dir = wp_upload_dir();
$aDBc_upload_dir = str_replace( '\\' ,'/', $aDBc_upload_dir['basedir'] ) . '/adbc_uploads_' . $aDBc_security_code;
if(file_exists($aDBc_upload_dir)){
$dir = opendir($aDBc_upload_dir);
while(($file = readdir($dir)) !== false){
if ($file != '.' && $file != '..'){
unlink($aDBc_upload_dir . "/" . $file);
}
}
closedir($dir);
rmdir($aDBc_upload_dir);
}
// Just in case the old folder (in versions < 3.1.0) have not been cleaned for any reason, try to clean it
$aDBc_upload_dir = wp_upload_dir();
$aDBc_upload_dir = str_replace('\\' ,'/', $aDBc_upload_dir['basedir']) . '/adbc_uploads';
if(file_exists($aDBc_upload_dir)){
$dir = opendir($aDBc_upload_dir);
while(($file = readdir($dir)) !== false){
if ($file != '.' && $file != '..'){
unlink($aDBc_upload_dir . "/" . $file);
}
}
closedir($dir);
rmdir($aDBc_upload_dir);
}
// Delete security code option
delete_option('aDBc_security_folder_code');
// Delete license options
delete_option('aDBc_edd_license_key');
delete_option('aDBc_edd_license_status');
// Uninstall the license key? Maybe no need for deactivating the license!
// if(!function_exists('aDBc_edd_deactivate_license_after_uninstall')){
// include_once 'includes/license/adbc-edd-sample-plugin.php';
// }
// aDBc_edd_deactivate_license_after_uninstall();
}
// Options below are used by both free and pro version
// Test if both version are installed to prevent deleting options
if ( ( file_exists( WP_PLUGIN_DIR . "/advanced-database-cleaner-pro") &&
file_exists( WP_PLUGIN_DIR . "/advanced-database-cleaner" )
) ||
( file_exists( WPMU_PLUGIN_DIR . "/advanced-database-cleaner-pro" ) &&
file_exists( WPMU_PLUGIN_DIR . "/advanced-database-cleaner" )
)
) {
// Do nothing in this case because we want to keep settings for the remaining version of the plugin
} else {
delete_option( 'aDBc_optimize_schedule' );
delete_option( 'aDBc_clean_schedule' );
delete_option( 'aDBc_settings' );
}
}
// If plugin get updated, make changes to old version
function aDBc_update_plugin_check(){
$settings = get_option('aDBc_settings');
if(!empty($settings)){
if(empty($settings['plugin_version'])){
// If settings is not empty, this means that the users had already installed ADBC plugin
// if empty($settings['plugin_version']) => the user will update to or will install the version >= 3.0.0 for the first time, because in previous versions, this option "plugin_version" does not exist
// Proceed to update routine. First, add some options
// xxx we have deleted this process in all version from 09.02.2023. Delete $settings['ignore_premium'] later
// $settings['ignore_premium'] = "no";
$settings['plugin_version'] = ADBC_PLUGIN_VERSION;
$settings['installed_on'] = date("Y/m/d");
// Delete some unused options
unset($settings['top_main_msg']);
unset($settings['tables_cleanup_warning']);
update_option('aDBc_settings', $settings, "no");
// If there are any scheduled cleanup tasks, change corresponding structure in DB to meet the new version
if($timestamp = wp_next_scheduled('aDBc_clean_scheduler')){
// Prepare new structure
// Since in version <= 3.0.0 the schedule cleans all elements, we will add only those elements not new introduced ones
$new_schedule_params['elements_to_clean'] = array('revision','auto-draft','trash-posts','moderated-comments','spam-comments','trash-comments','orphan-postmeta','orphan-commentmeta','orphan-relationships');
$repeat = get_option('aDBc_clean_schedule');
$repeat = empty($repeat) ? 'weekly' : $repeat;
$new_schedule_params['repeat'] = $repeat;
$date = date('Y-m-d', $timestamp) . "";
$time = date('H:i', $timestamp) . "";
$new_schedule_params['start_date'] = $date;
$new_schedule_params['start_time'] = $time;
$new_schedule_params['active'] = "1";
$clean_schedule_setting['cleanup_schedule'] = $new_schedule_params;
update_option('aDBc_clean_schedule', $clean_schedule_setting, "no");
// Reschedule the event with arg name
wp_clear_scheduled_hook('aDBc_clean_scheduler');
wp_schedule_event($timestamp, $repeat, "aDBc_clean_scheduler", array('cleanup_schedule'));
}else{
// If no scheduled task, delete any remaining option in DB
delete_option('aDBc_clean_schedule');
}
// If there are any optimize cleanup tasks, change corresponding structure in DB to meet the new version
if($timestamp = wp_next_scheduled('aDBc_optimize_scheduler')){
// Prepare new structure
$repeat = get_option('aDBc_optimize_schedule');
$repeat = empty($repeat) ? 'weekly' : $repeat;
$new_schedule_params['repeat'] = $repeat;
$date = date('Y-m-d', $timestamp) . "";
$time = date('H:i', $timestamp) . "";
$new_schedule_params['start_date'] = $date;
$new_schedule_params['start_time'] = $time;
// Prepare operations to perform. Since in versions < 3.0.0 there were no repair, add only optimize to keep users settings
$operations = array('optimize');
$new_schedule_params['operations'] = $operations;
$new_schedule_params['active'] = "1";
$optimize_schedule_setting['optimize_schedule'] = $new_schedule_params;
update_option('aDBc_optimize_schedule', $optimize_schedule_setting, "no");
// Reschedule the event with arg name
wp_clear_scheduled_hook('aDBc_optimize_scheduler');
wp_schedule_event($timestamp, $repeat, "aDBc_optimize_scheduler", array('optimize_schedule'));
}else{
// If no scheduled task, delete any remaining option in DB
delete_option('aDBc_optimize_schedule');
}
// Change categorization of tables, options, tasks from database to files
$types_array = array('tables', 'options', 'tasks');
foreach($types_array as $type){
$aDBc_items = get_option("aDBc_" . $type . "_status");
$aDBc_items_status = empty($aDBc_items['items_status']) ? "" : $aDBc_items['items_status'];
if(!empty($aDBc_items_status)){
$item_info = explode(",", $aDBc_items_status);
$myfile = fopen(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/" . $type . ".txt", "a");
foreach($item_info as $item){
$columns = explode(":", $item);
// A customer reported that the colon is not supported as separator in searching and all options with colon are not categorized!
// == 5 means that the option does not contain a colon. Process only these cases since items with >=5 are by default uncategorized
if(count($columns) == 5){
fwrite($myfile, $item."\n");
}
}
fclose($myfile);
}
// Delete options in DB that store searching status since they are not used anymore in version >= 3.0.0
delete_option("aDBc_" . $type . "_status");
}
// When activating version >= 2.0.0, delete all options and tasks created by older versions in MU sites since only the main site can clean the network now
if(function_exists('is_multisite') && is_multisite()){
global $wpdb;
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
if(!is_main_site()){
delete_option('aDBc_optimize_schedule');
delete_option('aDBc_clean_schedule');
wp_clear_scheduled_hook('aDBc_optimize_scheduler');
wp_clear_scheduled_hook('aDBc_clean_scheduler');
}
restore_current_blog();
}
}
} else {
// If plugin_version is not empty, we update the plugin version in DB
if ( $settings['plugin_version'] != ADBC_PLUGIN_VERSION ) {
// We update the plugin version in DB
$settings['plugin_version'] = ADBC_PLUGIN_VERSION;
update_option( 'aDBc_settings', $settings, "no" );
// In pro, from V 3.1.2, we deleted some options and files
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$array_items = array( 'options', 'tables', 'tasks' );
foreach ( $array_items as $item ) {
// This option is not used anymore from V 3.2.1
delete_option( 'aDBc_temp_still_searching_' . $item );
// Delete any temp option after each release
delete_option('aDBc_temp_last_iteration_' . $item);
delete_option('aDBc_temp_last_item_line_' . $item);
delete_option('aDBc_temp_last_file_line_' . $item);
delete_option('aDBc_last_search_ok_' . $item);
delete_option('aDBc_temp_total_files_' . $item);
delete_option("aDBc_temp_maybe_scores_" . $item);
// From V 3.2.1, some temp files should not exist after the scan
if(file_exists(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/timeout_" . $item . ".txt"))
unlink(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/timeout_" . $item . ".txt");
if(file_exists(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/maybe_scores_" . $item . ".txt"))
unlink(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/maybe_scores_" . $item . ".txt");
if(file_exists(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/total_items_" . $item . ".txt"))
unlink(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/total_items_" . $item . ".txt");
if(file_exists(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/progress_items_" . $item . ".txt"))
unlink(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/progress_items_" . $item . ".txt");
if(file_exists(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/" . $item . "_to_categorize.txt"))
unlink(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/" . $item . "_to_categorize.txt");
}
// From v 3.1.2, the "all_files_paths.txt" should not be present after the scan
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/all_files_paths.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/all_files_paths.txt" );
}
}
}
}
}
// Add admin notice to rate plugin
function aDBc_rate_notice(){
$settings = get_option('aDBc_settings');
$rating_url = 'https://wordpress.org/support/plugin/advanced-database-cleaner/reviews/?filter=5';
if(!empty($settings['installed_on'])){
$ignore_rating = empty($settings['ignore_rating']) ? "" : $settings['ignore_rating'];
if($ignore_rating != "yes"){
$date1 = $settings['installed_on'];
$date2 = date("Y/m/d");
$diff = abs(strtotime($date2) - strtotime($date1));
$days = floor($diff / (60*60*24));
if($days >= 7){
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = add_query_arg('adbc-ignore-notice', '0', $aDBc_new_URI);
echo '<div id="aDBc-rating-notice" class="notice notice-success" style="display:flex;padding:15px">';
echo '<div style="width:100%;">';
echo '<span style="font-weight:bold;color:green;font-size:16px">' . __('Awesome!', 'advanced-database-cleaner') . '</span> ';
echo __('You have been using <a href="admin.php?page=advanced_db_cleaner">Advanced DB Cleaner</a> for more than 1 week. Would you mind taking a few seconds to give it a 5-star rating on WordPress? Thank you in advance :)','advanced-database-cleaner');
echo '<div style="padding-top:15px">';
echo '<a href="' . $rating_url . '" target="_blank" class="button-secondary" style="margin-right:5px;padding:0px 5px"><span class="dashicons dashicons-smiley" style="color:black;margin-top:2px;margin-right:5px"></span><b>' . __('Ok, you deserved it', 'advanced-database-cleaner') . '</b></a>';
echo '<a href="' . esc_url($aDBc_new_URI) . '" class="button-secondary" style="margin-right:5px;border:0">' . __('I already did', 'advanced-database-cleaner') . '</a>';
echo '<a href="' . esc_url($aDBc_new_URI) . '" class="button-secondary" style="margin-right:5px;border:0">' . __('No, not good enough', 'advanced-database-cleaner') . '</a>';
echo '</div>';
echo '</div>';
echo '<div>';
echo '<a href="' . esc_url($aDBc_new_URI) . '" id="aDBc-dismiss-rating-notice" title="' . __('Dismiss', 'advanced-database-cleaner') . '"><span class="dashicons dashicons-dismiss" style="text-decoration:none"></span></a>';
echo '</div>';
echo '</div>';
}
}
}
}
function aDBc_ignore_notice(){
// Disable rating notice
if(isset($_GET['adbc-ignore-notice']) && $_GET['adbc-ignore-notice'] == "0"){
$settings = get_option('aDBc_settings');
$settings['ignore_rating'] = "yes";
update_option('aDBc_settings', $settings, "no");
}
// xxx In pro, hide double check message, this is not working for now
if ( ADBC_PLUGIN_PLAN == "pro" ) {
if(isset($_GET['ignore-double-check-tables'])){
delete_option('aDBc_last_search_ok_tables');
}
if(isset($_GET['ignore-double-check-options'])){
delete_option('aDBc_last_search_ok_options');
}
if(isset($_GET['ignore-double-check-tasks'])){
delete_option('aDBc_last_search_ok_tasks');
}
}
}
// The admin page of the plugin
function aDBc_main_page_callback() {
// Require WordPress List Table Administration API
if ( ! class_exists( 'WP_List_Table' ) ) require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
?>
<div class="wrap">
<div class="aDBc-header-wrap">
<img class="aDBc-header-logo" src="<?php echo ADBC_PLUGIN_DIR_PATH; ?>/images/icon-128x128.png"/>
<div class="aDBc-float-left">
<div class="aDBc-header-title">
<?php
$aDBc_pro = "";
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$aDBc_pro = " <b>PRO</b>";
}
echo "Advanced DB Cleaner" . $aDBc_pro . " <span class='aDBc-font-13'>" . ADBC_PLUGIN_VERSION . "</span>";
?>
</div>
<div class="aDBc-header-meta">
<span class="aDBc-header-by">
<span><?php _e('By', 'advanced-database-cleaner'); ?></span>
<a class="aDBc-link" href="https://profiles.wordpress.org/symptote/" target="_blank">
Younes JFR.
</a>
</span>
|
<span class="aDBc-header-need-help-ls">
<span><?php _e('Need help?', 'advanced-database-cleaner'); ?></span>
<a class="aDBc-link" href="https://sigmaplugin.com/contact" target="_blank">
<?php _e('Contact me', 'advanced-database-cleaner'); ?>
</a>
</span>
<span class="aDBc-header-need-help-ss">
<a class="aDBc-link" href="https://sigmaplugin.com/contact" target="_blank">
<?php _e('Support', 'advanced-database-cleaner'); ?>
</a>
</span>
</div>
</div>
<div class="aDBc-header-support">
<a class="aDBc-link" href="https://sigmaplugin.com/contact" target="_blank">
<img class="aDBc-header-help-svg" src="<?php echo ADBC_PLUGIN_DIR_PATH; ?>/images/help.svg"/>
<br/>
<?php _e('Support', 'advanced-database-cleaner'); ?>
</a>
</div>
</div>
<h2></h2>
<?php
if ( ADBC_PLUGIN_PLAN == "pro") {
$visibility_style = aDBc_edd_is_license_activated() ? "display:none" : "";
echo '<div class="aDBc-please-activate-msg notice is-dismissible" style="' . $visibility_style .'"><p>';
echo __( 'Please activate your license key to get lifetime automatic updates and support.', 'advanced-database-cleaner' );
echo ' <a href="?page=advanced_db_cleaner&aDBc_tab=license">' . __( 'Activate now', 'advanced-database-cleaner' ) . "</a>";
echo '</p></div>';
}
// YY. Notice to users who will lose their pro after upgrading to 3.0.0 from an old version
// YY. This process has been deleted, no need for it anymore
$main_content_style = "";
if ( ADBC_PLUGIN_PLAN == "free" ) {
$main_content_style = "aDBc-main-content";
}
?>
<div class="<?php echo $main_content_style; ?>">
<div class="aDBc-tab-box">
<?php
$aDBc_tabs = array( 'general' => __( 'General clean-up', 'advanced-database-cleaner' ),
'tables' => __( 'Tables', 'advanced-database-cleaner' ),
'options' => __( 'Options', 'advanced-database-cleaner' ),
'cron' => __( 'Cron jobs', 'advanced-database-cleaner' ),
'overview' => __( 'Overview & settings', 'advanced-database-cleaner' ),
'premium' => __( 'Premium', 'advanced-database-cleaner' ),
'license' => __( 'License', 'advanced-database-cleaner' )
);
// Hide premium tab in pro + In free, test if the user chose to hide the premium tab
$aDBc_settings = get_option('aDBc_settings');
if ( ADBC_PLUGIN_PLAN == "pro" ||
( ADBC_PLUGIN_PLAN == "free" && ! empty( $aDBc_settings['hide_premium_tab'] ) && $aDBc_settings['hide_premium_tab'] == "1" )
) {
unset( $aDBc_tabs['premium'] );
}
// Hide license in free
if ( ADBC_PLUGIN_PLAN == "free" ) {
unset( $aDBc_tabs['license'] );
}
$aDBc_dashicons_css = array('general' => 'dashicons-format-aside dashicons',
'tables' => 'dashicons-grid-view dashicons',
'options' => 'dashicons-forms dashicons',
'cron' => 'dashicons-backup dashicons',
'overview' => 'dashicons-admin-settings dashicons',
'premium' => 'dashicons-awards dashicons',
'license' => 'dashicons-admin-network dashicons'
);
$current_tab = isset( $_GET['aDBc_tab'] ) ? $_GET['aDBc_tab'] : 'general';
echo '<ul class="nav-tab-wrapper">';
foreach($aDBc_tabs as $tab => $name){
$class = ($tab == $current_tab) ? ' nav-tab-active' : '';
$link = "?page=advanced_db_cleaner&aDBc_tab=$tab";
if($tab == "tables" || $tab == "options" || $tab == "cron"){
$link .= '&aDBc_cat=all';
}
echo "<li><a class='nav-tab$class' href='$link'><span class='$aDBc_dashicons_css[$tab]'></span> $name</a></li>";
}
echo '</ul>';
echo '<div class="aDBc-tab-box-div">';
switch ( $current_tab ) {
case 'general' :
include_once 'includes/clean_db.php';
break;
case 'tables' :
include_once 'includes/optimize_db.php';
break;
case 'options' :
include_once 'includes/class_clean_options.php';
break;
case 'cron' :
include_once 'includes/class_clean_cron.php';
break;
case 'overview' :
include_once 'includes/overview_settings.php';
break;
case 'premium' :
include_once 'includes/premium_page.php';
break;
case 'license' :
aDBc_edd_license_page();
break;
}
echo '</div>';
?>
</div>
<?php
if ( ADBC_PLUGIN_PLAN == "free" ) {
include_once 'includes/sidebar.php';
}
?>
</div>
</div>
<?php
}
}
// Get instance
new ADBC_Advanced_DB_Cleaner();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
<?php
#Silence is golden.
?>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 57.157 57.157" style="enable-background:new 0 0 57.157 57.157;" xml:space="preserve" width="60px" height="60px" class=""><g><circle style="fill:#FFFFFF" cx="28.578" cy="29.157" r="26" data-original="#E0E1E2" class="active-path" data-old_color="#ffffff"/><circle style="fill:#FFFFFF;" cx="28.578" cy="29.157" r="15" data-original="#FFFFFF" class=""/><path style="fill:#424A60;" d="M12.578,57.157c-0.256,0-0.512-0.098-0.707-0.293c-0.391-0.391-0.391-1.023,0-1.414l3.933-3.933 c0.391-0.391,1.023-0.391,1.414,0s0.391,1.023,0,1.414l-3.933,3.933C13.09,57.059,12.834,57.157,12.578,57.157z" data-original="#424A60" class=""/><path style="fill:#424A60;" d="M44.578,57.157c-0.256,0-0.512-0.098-0.707-0.293l-3.963-3.963c-0.391-0.391-0.391-1.023,0-1.414 s1.023-0.391,1.414,0l3.963,3.963c0.391,0.391,0.391,1.023,0,1.414C45.09,57.059,44.834,57.157,44.578,57.157z" data-original="#424A60" class=""/><path style="fill:#F6F9F6" d="M46.672,11.371c-0.256,0-0.512-0.098-0.707-0.293c-0.391-0.391-0.391-1.023,0-1.414l3-3 c0.391-0.391,1.023-0.391,1.414,0s0.391,1.023,0,1.414l-3,3C47.183,11.274,46.927,11.371,46.672,11.371z" data-original="#C7CAC7" class="" data-old_color="#F0F7F0"/><path style="fill:#F6F9F6" d="M10.485,11.371c-0.256,0-0.512-0.098-0.707-0.293l-3-3c-0.391-0.391-0.391-1.023,0-1.414 s1.023-0.391,1.414,0l3,3c0.391,0.391,0.391,1.023,0,1.414C10.997,11.274,10.741,11.371,10.485,11.371z" data-original="#C7CAC7" class="" data-old_color="#F0F7F0"/><path style="fill:#26B99A;" d="M28.578,57.157c-15.439,0-28-12.561-28-28s12.561-28,28-28s28,12.561,28,28 S44.018,57.157,28.578,57.157z M28.578,5.157c-13.234,0-24,10.767-24,24s10.766,24,24,24s24-10.767,24-24S41.812,5.157,28.578,5.157 z" data-original="#26B99A" class=""/><g>
<path style="fill:#26B99A;" d="M28.578,6.036c-0.552,0-1,0.447-1,1v1c0,0.553,0.448,1,1,1s1-0.447,1-1v-1 C29.578,6.483,29.131,6.036,28.578,6.036z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M28.578,49.036c-0.552,0-1,0.447-1,1v1c0,0.553,0.448,1,1,1s1-0.447,1-1v-1 C29.578,49.483,29.131,49.036,28.578,49.036z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M50.578,28.036h-1c-0.552,0-1,0.447-1,1s0.448,1,1,1h1c0.552,0,1-0.447,1-1 S51.131,28.036,50.578,28.036z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M7.578,28.036h-1c-0.552,0-1,0.447-1,1s0.448,1,1,1h1c0.552,0,1-0.447,1-1 S8.131,28.036,7.578,28.036z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M43.427,12.772l-0.707,0.707c-0.391,0.391-0.391,1.023,0,1.414c0.195,0.195,0.451,0.293,0.707,0.293 s0.512-0.098,0.707-0.293l0.707-0.707c0.391-0.391,0.391-1.023,0-1.414S43.818,12.381,43.427,12.772z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M13.022,43.178l-0.707,0.707c-0.391,0.391-0.391,1.023,0,1.414c0.195,0.195,0.451,0.293,0.707,0.293 s0.512-0.098,0.707-0.293l0.707-0.707c0.391-0.391,0.391-1.023,0-1.414S13.413,42.788,13.022,43.178z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M44.134,43.178c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l0.707,0.707 c0.195,0.195,0.451,0.293,0.707,0.293s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L44.134,43.178z" data-original="#26B99A" class=""/>
<path style="fill:#26B99A;" d="M13.729,12.772c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l0.707,0.707 c0.195,0.195,0.451,0.293,0.707,0.293s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L13.729,12.772z" data-original="#26B99A" class=""/>
</g><path style="fill:#424A60;" d="M39.578,30.157h-8c-0.552,0-1-0.447-1-1s0.448-1,1-1h8c0.552,0,1,0.447,1,1 S40.131,30.157,39.578,30.157z" data-original="#424A60" class=""/><path style="fill:#424A60;" d="M28.578,27.157c-0.552,0-1-0.447-1-1v-11c0-0.553,0.448-1,1-1s1,0.447,1,1v11 C29.578,26.709,29.131,27.157,28.578,27.157z" data-original="#424A60" class=""/><path style="fill:#424A60;" d="M28.578,33.157c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S30.784,33.157,28.578,33.157z M28.578,27.157c-1.103,0-2,0.897-2,2s0.897,2,2,2s2-0.897,2-2S29.681,27.157,28.578,27.157z" data-original="#424A60" class=""/><path style="fill:#F8FBFB" d="M54.493,2.086c2.781,2.781,2.781,7.29,0,10.071L44.421,2.086C47.203-0.695,51.711-0.695,54.493,2.086 z" data-original="#E7ECED" class="" data-old_color="#EDF4F4"/><path style="fill:#F8FBFB" d="M2.664,2.086c-2.781,2.781-2.781,7.29,0,10.071L12.735,2.086C9.954-0.695,5.445-0.695,2.664,2.086z" data-original="#E7ECED" class="" data-old_color="#EDF4F4"/></g> </svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1 @@
<svg height="13pt" viewBox="0 0 512 512.92258" width="13pt" xmlns="http://www.w3.org/2000/svg"><path d="m433.347656 512.921875h-352.898437c-27.71875-.003906-53.460938-14.355469-68.039063-37.9375-14.574218-23.578125-15.902344-53.023437-3.511718-77.820313l176.433593-352.914062c13.542969-27.117188 41.253907-44.25 71.566407-44.25s58.023437 17.132812 71.566406 44.25l176.433594 352.914062c12.390624 24.796876 11.0625 54.242188-3.511719 77.820313-14.574219 23.582031-40.320313 37.933594-68.039063 37.9375zm0 0" fill="#ff7761"/><g fill="#fff"><path d="m256.898438 128.203125c8.835937 0 16 7.164063 16 16v192c0 8.835937-7.164063 16-16 16-8.835938 0-16-7.164063-16-16v-192c0-8.835937 7.164062-16 16-16zm0 0"/><path d="m240.898438 384.203125h32v32h-32zm0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@@ -0,0 +1 @@
<svg height="35pt" viewBox="0 0 512 512.92258" width="35pt" xmlns="http://www.w3.org/2000/svg"><path d="m433.347656 512.921875h-352.898437c-27.71875-.003906-53.460938-14.355469-68.039063-37.9375-14.574218-23.578125-15.902344-53.023437-3.511718-77.820313l176.433593-352.914062c13.542969-27.117188 41.253907-44.25 71.566407-44.25s58.023437 17.132812 71.566406 44.25l176.433594 352.914062c12.390624 24.796876 11.0625 54.242188-3.511719 77.820313-14.574219 23.582031-40.320313 37.933594-68.039063 37.9375zm0 0" fill="#ff7761"/><g fill="#fff"><path d="m256.898438 128.203125c8.835937 0 16 7.164063 16 16v192c0 8.835937-7.164063 16-16 16-8.835938 0-16-7.164063-16-16v-192c0-8.835937 7.164062-16 16-16zm0 0"/><path d="m240.898438 384.203125h32v32h-32zm0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="58px" height="58px" class="hovered-paths"><g><path d="m256 0c-141.164062 0-256 114.835938-256 256s114.835938 256 256 256 256-114.835938 256-256-114.835938-256-256-256zm0 0" fill="#2196f3" data-original="#2196F3" class="" data-old_color="#2196f3" style="fill:#FFFFFF"/><path d="m385.75 201.75-138.667969 138.664062c-4.160156 4.160157-9.621093 6.253907-15.082031 6.253907s-10.921875-2.09375-15.082031-6.253907l-69.332031-69.332031c-8.34375-8.339843-8.34375-21.824219 0-30.164062 8.339843-8.34375 21.820312-8.34375 30.164062 0l54.25 54.25 123.585938-123.582031c8.339843-8.34375 21.820312-8.34375 30.164062 0 8.339844 8.339843 8.339844 21.820312 0 30.164062zm0 0" fill="#fafafa" data-original="#FAFAFA" class="hovered-path active-path" style="fill:#44C3FF" data-old_color="#fafafa"/></g> </svg>

After

Width:  |  Height:  |  Size: 884 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 214.864 214.864" style="enable-background:new 0 0 214.864 214.864;" xml:space="preserve" width="25px" height="25px"><g><g>
<path d="M208.35,56.943c-8.703-8.7-22.864-8.702-31.567,0l-53.626,53.625l-3.414-3.414l18.644-18.644 c0.183-0.183,0.355-0.374,0.515-0.57c8.16-8.74,8.004-22.477-0.515-30.996c-4.216-4.217-9.82-6.538-15.783-6.538 s-11.567,2.321-15.784,6.537l-53.625,53.625l-15.091-15.09c-8.703-8.701-22.863-8.701-31.566,0C2.321,99.695,0,105.299,0,111.262 c0,5.844,2.241,11.334,6.299,15.52c0.08,0.087,0.153,0.179,0.238,0.263l30.835,30.835c0.013,0.013,0.023,0.028,0.037,0.041 c4.217,4.216,9.821,6.537,15.784,6.537c5.962,0,11.566-2.321,15.783-6.537l0.002-0.002l0,0l0,0l19.197-19.197l19.159,19.159 c0.013,0.013,0.023,0.028,0.037,0.041c4.217,4.216,9.821,6.537,15.783,6.537c5.963,0,11.567-2.321,15.784-6.537L208.35,88.51 c0.183-0.183,0.355-0.374,0.515-0.57C217.025,79.2,216.869,65.463,208.35,56.943z M17.144,106.086 c2.854-2.853,7.499-2.854,10.354,0l20.394,20.394c0.183,0.183,0.374,0.354,0.57,0.515c1.375,1.121,3.055,1.682,4.734,1.682 s3.359-0.561,4.734-1.682c0.196-0.16,0.387-0.332,0.57-0.515l58.929-58.929c1.383-1.383,3.221-2.145,5.177-2.145 c1.955,0,3.793,0.761,5.176,2.145c2.854,2.854,2.854,7.498,0,10.353l-69.408,69.409c-1.383,1.383-3.221,2.145-5.176,2.145 c-1.956,0-3.794-0.762-5.177-2.145l-30.874-30.874c-0.002-0.002-0.004-0.003-0.005-0.005c-1.38-1.382-2.139-3.218-2.139-5.171 C15,109.306,15.762,107.468,17.144,106.086z M109.135,117.762l8.717,8.717c1.465,1.464,3.384,2.196,5.304,2.196 c1.919,0,3.839-0.732,5.304-2.196l58.93-58.929c2.854-2.856,7.499-2.854,10.353,0c2.854,2.854,2.854,7.498,0,10.353l-69.409,69.409 c-1.383,1.383-3.221,2.145-5.177,2.145c-1.955,0-3.793-0.762-5.176-2.145l-19.197-19.198L109.135,117.762z" data-original="#1D1D1B" class="active-path" data-old_color="#1D1D1B" fill="#FFFFFF"/>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 97.16 97.16" style="enable-background:new 0 0 97.16 97.16;" xml:space="preserve"><g><g>
<g>
<path d="M48.58,0C21.793,0,0,21.793,0,48.58s21.793,48.58,48.58,48.58s48.58-21.793,48.58-48.58S75.367,0,48.58,0z M48.58,86.823 c-21.087,0-38.244-17.155-38.244-38.243S27.493,10.337,48.58,10.337S86.824,27.492,86.824,48.58S69.667,86.823,48.58,86.823z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#1CD60A"/>
<path d="M73.898,47.08H52.066V20.83c0-2.209-1.791-4-4-4c-2.209,0-4,1.791-4,4v30.25c0,2.209,1.791,4,4,4h25.832 c2.209,0,4-1.791,4-4S76.107,47.08,73.898,47.08z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#1CD60A"/>
</g>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 898 B

View File

@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 97.16 97.16" style="enable-background:new 0 0 97.16 97.16;" xml:space="preserve"><g><g>
<g>
<path d="M48.58,0C21.793,0,0,21.793,0,48.58s21.793,48.58,48.58,48.58s48.58-21.793,48.58-48.58S75.367,0,48.58,0z M48.58,86.823 c-21.087,0-38.244-17.155-38.244-38.243S27.493,10.337,48.58,10.337S86.824,27.492,86.824,48.58S69.667,86.823,48.58,86.823z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#ccc"/>
<path d="M73.898,47.08H52.066V20.83c0-2.209-1.791-4-4-4c-2.209,0-4,1.791-4,4v30.25c0,2.209,1.791,4,4,4h25.832 c2.209,0,4-1.791,4-4S76.107,47.08,73.898,47.08z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#ccc"/>
</g>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40px" height="40px" viewBox="0 0 504.124 504.124" style="enable-background:new 0 0 504.124 504.124;" xml:space="preserve">
<path style="fill:#E4E7E7;" d="M441.108,244.578l-1.182-16.148l10.24-10.24c45.292-45.292,45.292-119.335,0-164.234
c-45.292-45.292-118.942-45.292-164.234,0l-10.24,10.24c-5.12-0.788-10.634-1.182-16.148-1.182l17.723-17.723
c50.018-50.018,131.545-50.412,181.563,0c50.018,50.018,50.018,131.545,0,181.563C458.831,226.855,441.108,244.578,441.108,244.578z
M228.825,64.591l-10.24-10.24c-45.292-45.292-119.335-45.292-164.234,0c-45.686,44.898-45.686,118.942,0,164.234l10.24,10.24
c-0.788,5.12-1.182,10.634-1.182,16.148L45.686,227.25c-50.018-50.018-50.412-131.545,0-181.563
c50.018-50.018,131.545-50.018,181.563,0l17.723,17.723C239.458,63.409,233.945,63.803,228.825,64.591z M63.015,259.545
l1.182,16.148l-10.24,10.24C8.665,331.225,8.665,405.268,53.563,450.166c45.292,45.292,118.942,45.292,164.234,0l10.24-10.24
c5.12,0.788,10.634,1.182,16.148,1.182l-17.723,17.723c-50.018,50.018-131.545,50.412-181.563,0.394S-5.12,327.68,45.292,277.661
L63.015,259.545z M275.298,439.532l10.24,10.24c45.292,45.292,119.335,45.292,164.234,0c45.292-45.292,45.292-118.942-0.394-164.234
l-10.24-10.24c0.788-5.12,1.182-10.634,1.182-16.148l17.723,17.723c50.018,50.018,50.412,131.545,0.394,181.563
s-131.545,50.018-181.563-0.394l-17.723-17.723C264.665,440.714,270.178,440.32,275.298,439.532z"/>
<path style="fill:#E2574C;" d="M252.062,0C113.034,0,0,113.034,0,252.062s112.64,252.062,252.062,252.062
c139.028,0,252.062-113.034,252.062-252.062S391.089,0,252.062,0z M252.062,378.092c-69.711,0-126.031-56.32-126.031-126.031
s56.32-126.031,126.031-126.031s126.031,56.32,126.031,126.031S321.772,378.092,252.062,378.092z"/>
<path style="fill:#D95449;" d="M252.062,95.705c-86.252,0-156.357,70.105-156.357,156.357s70.105,156.357,156.357,156.357
s156.357-70.105,156.357-156.357S338.314,95.705,252.062,95.705z M252.062,378.092c-69.711,0-126.031-56.32-126.031-126.031
s56.32-126.031,126.031-126.031s126.031,56.32,126.031,126.031S321.772,378.092,252.062,378.092z"/>
<path style="fill:#E5685E;" d="M252.062,35.446c-119.729,0-216.615,96.886-216.615,216.615s96.886,216.615,216.615,216.615
s216.615-96.886,216.615-216.615S371.791,35.446,252.062,35.446z M252.062,452.923c-111.065,0-200.862-89.797-200.862-200.862
S140.997,51.2,252.062,51.2s200.862,89.797,200.862,200.862S363.126,452.923,252.062,452.923z"/>
<path style="fill:#EFEFEF;" d="M193.378,363.52c-22.843-11.815-41.354-30.72-53.169-53.169l-90.978,91.372
c14.966,20.086,32.689,38.203,53.169,53.169L193.378,363.52z M310.351,140.209c22.843,11.815,41.354,30.326,53.169,53.169
l91.372-90.978c-14.966-20.086-33.083-38.203-53.169-53.169L310.351,140.209z M49.231,102.4l90.978,90.978
c11.815-22.843,30.326-41.354,53.169-53.169L102.4,49.231C82.314,64.197,64.197,82.314,49.231,102.4z M454.892,401.723
l-90.978-90.978c-11.815,22.843-30.326,41.354-53.169,53.169l90.978,90.978C421.809,439.926,439.926,421.809,454.892,401.723z"/>
<path style="fill:#E6E6E6;" d="M332.8,118.154l-22.055,22.055c22.843,11.815,41.354,30.326,53.169,53.169l22.055-22.055
C372.578,149.662,354.462,131.151,332.8,118.154z M140.209,310.351L118.154,332.8c12.997,21.662,31.508,39.778,53.169,53.169
l22.055-22.055C170.929,351.705,152.418,333.194,140.209,310.351z M310.745,363.914l22.055,22.055
c21.662-12.997,39.778-31.508,53.169-53.169l-22.055-22.055C351.705,333.194,333.194,351.705,310.745,363.914z M193.772,140.603
l-22.449-22.449c-21.662,13.391-39.778,31.508-53.169,53.169l22.055,22.055C152.418,170.929,170.929,152.418,193.772,140.603z"/>
<path style="fill:#F1F1F1;" d="M85.858,365.095l-11.422,11.422c14.572,20.48,32.295,38.597,53.169,53.169l11.422-11.422
C118.154,403.692,100.037,385.969,85.858,365.095z M418.265,365.095c-14.178,20.874-32.295,38.991-53.169,53.169l11.422,11.422
c20.48-14.572,38.597-32.689,53.169-53.169L418.265,365.095z M85.858,139.028c14.178-20.874,32.295-38.991,53.169-53.169L128,74.831
C107.52,89.403,89.403,107.52,74.831,128L85.858,139.028z M418.265,139.028l11.422-11.422
c-14.572-20.48-32.689-38.597-53.169-53.169l-11.422,11.422C385.969,100.037,403.692,118.154,418.265,139.028z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 23.625 23.625" style="enable-background:new 0 0 23.625 23.625;" xml:space="preserve" width="20px" height="20px" class=""><g><g>
<path d="M11.812,0C5.289,0,0,5.289,0,11.812s5.289,11.813,11.812,11.813s11.813-5.29,11.813-11.813 S18.335,0,11.812,0z M14.271,18.307c-0.608,0.24-1.092,0.422-1.455,0.548c-0.362,0.126-0.783,0.189-1.262,0.189 c-0.736,0-1.309-0.18-1.717-0.539s-0.611-0.814-0.611-1.367c0-0.215,0.015-0.435,0.045-0.659c0.031-0.224,0.08-0.476,0.147-0.759 l0.761-2.688c0.067-0.258,0.125-0.503,0.171-0.731c0.046-0.23,0.068-0.441,0.068-0.633c0-0.342-0.071-0.582-0.212-0.717 c-0.143-0.135-0.412-0.201-0.813-0.201c-0.196,0-0.398,0.029-0.605,0.09c-0.205,0.063-0.383,0.12-0.529,0.176l0.201-0.828 c0.498-0.203,0.975-0.377,1.43-0.521c0.455-0.146,0.885-0.218,1.29-0.218c0.731,0,1.295,0.178,1.692,0.53 c0.395,0.353,0.594,0.812,0.594,1.376c0,0.117-0.014,0.323-0.041,0.617c-0.027,0.295-0.078,0.564-0.152,0.811l-0.757,2.68 c-0.062,0.215-0.117,0.461-0.167,0.736c-0.049,0.275-0.073,0.485-0.073,0.626c0,0.356,0.079,0.599,0.239,0.728 c0.158,0.129,0.435,0.194,0.827,0.194c0.185,0,0.392-0.033,0.626-0.097c0.232-0.064,0.4-0.121,0.506-0.17L14.271,18.307z M14.137,7.429c-0.353,0.328-0.778,0.492-1.275,0.492c-0.496,0-0.924-0.164-1.28-0.492c-0.354-0.328-0.533-0.727-0.533-1.193 c0-0.465,0.18-0.865,0.533-1.196c0.356-0.332,0.784-0.497,1.28-0.497c0.497,0,0.923,0.165,1.275,0.497 c0.353,0.331,0.53,0.731,0.53,1.196C14.667,6.703,14.49,7.101,14.137,7.429z" data-original="#030104" class="active-path" data-old_color="#030104" fill="#0CBDF0"/>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="17px" height="17px" viewBox="0 0 437.6 437.6" style="enable-background:new 0 0 437.6 437.6;" xml:space="preserve">
<g>
<g>
<g>
<path d="M194,142.8c0.8,1.6,1.6,3.2,2.4,4.4c0.8,1.2,2,2.4,2.8,3.6c1.2,1.2,2.4,2.4,4,3.6c1.2,0.8,2.8,2,4.8,2.4
c1.6,0.8,3.2,1.2,5.2,1.6c2,0.4,3.6,0.4,5.2,0.4c1.6,0,3.6,0,5.2-0.4c1.6-0.4,3.2-0.8,4.4-1.6h0.4c1.6-0.8,3.2-1.6,4.8-2.8
c1.2-0.8,2.4-2,3.6-3.2l0.4-0.4c1.2-1.2,2-2.4,2.8-3.6s1.6-2.4,2-4c0-0.4,0-0.4,0.4-0.8c0.8-1.6,1.2-3.6,1.6-5.2
c0.4-1.6,0.4-3.6,0.4-5.2s0-3.6-0.4-5.2c-0.4-1.6-0.8-3.2-1.6-5.2c-1.2-2.8-2.8-5.2-4.8-7.2c-0.4-0.4-0.4-0.4-0.8-0.8
c-1.2-1.2-2.4-2-4-3.2c-1.6-0.8-2.8-1.6-4.4-2.4c-1.6-0.8-3.2-1.2-4.8-1.6c-2-0.4-3.6-0.4-5.2-0.4c-1.6,0-3.6,0-5.2,0.4
c-1.6,0.4-3.2,0.8-4.8,1.6H208c-1.6,0.8-3.2,1.6-4.4,2.4c-1.6,1.2-2.8,2-4,3.2c-1.2,1.2-2.4,2.4-3.2,3.6
c-0.8,1.2-1.6,2.8-2.4,4.4c-0.8,1.6-1.2,3.2-1.6,4.8c-0.4,2-0.4,3.6-0.4,5.2c0,1.6,0,3.6,0.4,5.2
C192.8,139.6,193.6,141.2,194,142.8z"/>
<path d="M249.6,289.2h-9.2v-98c0-5.6-4.4-10.4-10.4-10.4h-42c-5.6,0-10.4,4.4-10.4,10.4v21.6c0,5.6,4.4,10.4,10.4,10.4h8.4v66.4
H188c-5.6,0-10.4,4.4-10.4,10.4v21.6c0,5.6,4.4,10.4,10.4,10.4h61.6c5.6,0,10.4-4.4,10.4-10.4V300
C260,294,255.2,289.2,249.6,289.2z"/>
<path d="M218.8,0C98,0,0,98,0,218.8s98,218.8,218.8,218.8s218.8-98,218.8-218.8S339.6,0,218.8,0z M218.8,408.8
c-104.8,0-190-85.2-190-190s85.2-190,190-190s190,85.2,190,190S323.6,408.8,218.8,408.8z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="15px" height="15px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<g>
<circle cx="256" cy="378.5" r="25"/>
<path d="M256,0C114.516,0,0,114.497,0,256c0,141.484,114.497,256,256,256c141.484,0,256-114.497,256-256
C512,114.516,397.503,0,256,0z M256,472c-119.377,0-216-96.607-216-216c0-119.377,96.607-216,216-216
c119.377,0,216,96.607,216,216C472,375.377,375.393,472,256,472z"/>
<path d="M256,128.5c-44.112,0-80,35.888-80,80c0,11.046,8.954,20,20,20s20-8.954,20-20c0-22.056,17.944-40,40-40
c22.056,0,40,17.944,40,40c0,22.056-17.944,40-40,40c-11.046,0-20,8.954-20,20v50c0,11.046,8.954,20,20,20
c11.046,0,20-8.954,20-20v-32.531c34.466-8.903,60-40.26,60-77.469C336,164.388,300.112,128.5,256,128.5z"/>
</g>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 437.6 437.6" style="enable-background:new 0 0 437.6 437.6;" xml:space="preserve">
<g>
<g>
<g>
<path d="M194,142.8c0.8,1.6,1.6,3.2,2.4,4.4c0.8,1.2,2,2.4,2.8,3.6c1.2,1.2,2.4,2.4,4,3.6c1.2,0.8,2.8,2,4.8,2.4
c1.6,0.8,3.2,1.2,5.2,1.6c2,0.4,3.6,0.4,5.2,0.4c1.6,0,3.6,0,5.2-0.4c1.6-0.4,3.2-0.8,4.4-1.6h0.4c1.6-0.8,3.2-1.6,4.8-2.8
c1.2-0.8,2.4-2,3.6-3.2l0.4-0.4c1.2-1.2,2-2.4,2.8-3.6s1.6-2.4,2-4c0-0.4,0-0.4,0.4-0.8c0.8-1.6,1.2-3.6,1.6-5.2
c0.4-1.6,0.4-3.6,0.4-5.2s0-3.6-0.4-5.2c-0.4-1.6-0.8-3.2-1.6-5.2c-1.2-2.8-2.8-5.2-4.8-7.2c-0.4-0.4-0.4-0.4-0.8-0.8
c-1.2-1.2-2.4-2-4-3.2c-1.6-0.8-2.8-1.6-4.4-2.4c-1.6-0.8-3.2-1.2-4.8-1.6c-2-0.4-3.6-0.4-5.2-0.4c-1.6,0-3.6,0-5.2,0.4
c-1.6,0.4-3.2,0.8-4.8,1.6H208c-1.6,0.8-3.2,1.6-4.4,2.4c-1.6,1.2-2.8,2-4,3.2c-1.2,1.2-2.4,2.4-3.2,3.6
c-0.8,1.2-1.6,2.8-2.4,4.4c-0.8,1.6-1.2,3.2-1.6,4.8c-0.4,2-0.4,3.6-0.4,5.2c0,1.6,0,3.6,0.4,5.2
C192.8,139.6,193.6,141.2,194,142.8z" fill="#E97F31"/>
<path d="M249.6,289.2h-9.2v-98c0-5.6-4.4-10.4-10.4-10.4h-42c-5.6,0-10.4,4.4-10.4,10.4v21.6c0,5.6,4.4,10.4,10.4,10.4h8.4v66.4
H188c-5.6,0-10.4,4.4-10.4,10.4v21.6c0,5.6,4.4,10.4,10.4,10.4h61.6c5.6,0,10.4-4.4,10.4-10.4V300
C260,294,255.2,289.2,249.6,289.2z" fill="#E97F31"/>
<path d="M218.8,0C98,0,0,98,0,218.8s98,218.8,218.8,218.8s218.8-98,218.8-218.8S339.6,0,218.8,0z M218.8,408.8
c-104.8,0-190-85.2-190-190s85.2-190,190-190s190,85.2,190,190S323.6,408.8,218.8,408.8z" fill="#E97F31"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg width="26px" height="26px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-disk" style="background: none;"><g transform="translate(50,50)"><g ng-attr-transform="scale({{config.scale}})" transform="scale(0.7)"><circle cx="0" cy="0" r="50" ng-attr-fill="{{config.c1}}" fill="rgba(0%,0%,0%,0.436)"></circle><circle cx="0" ng-attr-cy="{{config.cy}}" ng-attr-r="{{config.r}}" ng-attr-fill="{{config.c2}}" cy="-27" r="18" fill="#ffffff" transform="rotate(289.484)"><animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 0 0;360 0 0" keyTimes="0;1" dur="0.6s" begin="0s" repeatCount="indefinite"></animateTransform></circle></g></g></svg>

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 488.85 488.85" style="enable-background:new 0 0 488.85 488.85;" xml:space="preserve" width="20px" height="20px" class=""><g><g>
<path d="M244.425,98.725c-93.4,0-178.1,51.1-240.6,134.1c-5.1,6.8-5.1,16.3,0,23.1c62.5,83.1,147.2,134.2,240.6,134.2 s178.1-51.1,240.6-134.1c5.1-6.8,5.1-16.3,0-23.1C422.525,149.825,337.825,98.725,244.425,98.725z M251.125,347.025 c-62,3.9-113.2-47.2-109.3-109.3c3.2-51.2,44.7-92.7,95.9-95.9c62-3.9,113.2,47.2,109.3,109.3 C343.725,302.225,302.225,343.725,251.125,347.025z M248.025,299.625c-33.4,2.1-61-25.4-58.8-58.8c1.7-27.6,24.1-49.9,51.7-51.7 c33.4-2.1,61,25.4,58.8,58.8C297.925,275.625,275.525,297.925,248.025,299.625z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#D2D2D2"/>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1 @@
<svg height="80pt" viewBox="0 0 512 512.0002" width="80pt" xmlns="http://www.w3.org/2000/svg"><path d="m301.636719 170c3.066406 0 6.117187-.953125 8.683593-2.820312 4.351563-3.160157 6.640626-8.441407 5.972657-13.78125l-5.394531-43.144532 29.726562-31.734375c3.679688-3.929687 4.929688-9.542969 3.265625-14.664062-1.664063-5.117188-5.976563-8.921875-11.261719-9.9375l-42.699218-8.203125-20.996094-38.078125c-2.597656-4.710938-7.554688-7.636719-12.933594-7.636719-5.382812 0-10.335938 2.925781-12.933594 7.636719l-20.996094 38.078125-42.703124 8.203125c-5.28125 1.011719-9.597657 4.820312-11.261719 9.9375-1.660157 5.121093-.410157 10.734375 3.269531 14.664062l29.726562 31.734375-5.394531 43.144532c-.671875 5.339843 1.617188 10.621093 5.972657 13.78125 4.351562 3.164062 10.078124 3.710937 14.953124 1.421874l39.367188-18.460937 39.367188 18.460937c2 .9375 4.140624 1.398438 6.269531 1.398438zm0 0" fill="#ffa000"/><path d="m343.890625 63.855469c-1.660156-5.117188-5.976563-8.925781-11.257813-9.9375l-42.703124-8.203125-20.996094-38.078125c-2.597656-4.710938-7.554688-7.636719-12.933594-7.636719v150.140625l39.367188 18.460937c1.996093.9375 4.136718 1.398438 6.269531 1.398438 3.066406 0 6.117187-.953125 8.683593-2.820312 4.351563-3.160157 6.640626-8.441407 5.972657-13.78125l-5.394531-43.144532 29.726562-31.734375c3.679688-3.929687 4.929688-9.546875 3.265625-14.664062zm0 0" fill="#ee8700"/><path d="m511.277344 213.855469c-1.664063-5.117188-5.976563-8.925781-11.261719-9.941407l-42.703125-8.203124-20.996094-38.078126c-2.597656-4.710937-7.550781-7.636718-12.933594-7.636718-5.378906 0-10.335937 2.925781-12.933593 7.636718l-20.996094 38.078126-42.699219 8.203124c-5.285156 1.015626-9.597656 4.824219-11.261718 9.941407-1.664063 5.117187-.410157 10.730469 3.265624 14.660156l29.726563 31.734375-5.394531 43.148438c-.667969 5.339843 1.621094 10.617187 5.972656 13.777343 4.351562 3.164063 10.078125 3.710938 14.953125 1.425781l39.367187-18.464843 39.371094 18.464843c1.996094.9375 4.136719 1.398438 6.265625 1.398438 3.070313 0 6.117188-.957031 8.683594-2.820312 4.351563-3.164063 6.640625-8.441407 5.972656-13.78125l-5.394531-43.144532 29.726562-31.738281c3.679688-3.925781 4.933594-9.542969 3.269532-14.660156zm0 0" fill="#ee8700"/><path d="m229.246094 395.914062-42.699219-8.199218-20.996094-38.078125c-2.597656-4.710938-7.554687-7.640625-12.933593-7.640625-5.382813 0-10.335938 2.929687-12.933594 7.640625l-20.996094 38.078125-42.703125 8.199218c-5.285156 1.015626-9.597656 4.824219-11.261719 9.941407-1.660156 5.117187-.410156 10.734375 3.269532 14.660156l29.722656 31.734375-5.394532 43.148438c-.667968 5.339843 1.621094 10.617187 5.976563 13.78125 4.351563 3.160156 10.078125 3.710937 14.949219 1.421874l39.371094-18.464843 39.367187 18.464843c1.996094.9375 4.136719 1.398438 6.269531 1.398438 3.066406 0 6.113282-.957031 8.679688-2.820312 4.355468-3.164063 6.644531-8.441407 5.976562-13.78125l-5.398437-43.148438 29.726562-31.734375c3.679688-3.925781 4.929688-9.542969 3.269531-14.660156-1.660156-5.117188-5.976562-8.925781-11.261718-9.941407zm0 0" fill="#ffa000"/><path d="m436.015625 395.914062-42.703125-8.199218-20.996094-38.078125c-2.597656-4.710938-7.550781-7.640625-12.933594-7.640625-5.378906 0-10.332031 2.929687-12.933593 7.640625l-20.996094 38.078125-42.699219 8.199218c-5.285156 1.015626-9.597656 4.824219-11.261718 9.941407-1.664063 5.117187-.410157 10.734375 3.265624 14.660156l29.726563 31.734375-5.394531 43.148438c-.667969 5.339843 1.621094 10.617187 5.972656 13.78125 4.351562 3.160156 10.078125 3.710937 14.953125 1.421874l39.367187-18.464843 39.371094 18.464843c1.996094.9375 4.136719 1.398438 6.265625 1.398438 3.070313 0 6.117188-.957031 8.683594-2.820312 4.351563-3.164063 6.640625-8.441407 5.972656-13.78125l-5.394531-43.148438 29.726562-31.734375c3.679688-3.925781 4.929688-9.542969 3.265626-14.660156-1.660157-5.117188-5.972657-8.925781-11.257813-9.941407zm0 0" fill="#ee8700"/><path d="m127.984375 318.601562c1.996094.9375 4.136719 1.398438 6.269531 1.398438 3.066406 0 6.113282-.957031 8.683594-2.820312 4.351562-3.164063 6.640625-8.441407 5.972656-13.78125l-5.394531-43.144532 29.722656-31.738281c3.679688-3.925781 4.933594-9.542969 3.269531-14.660156-1.664062-5.117188-5.976562-8.925781-11.261718-9.941407l-42.703125-8.199218-20.996094-38.078125c-2.597656-4.710938-7.550781-7.640625-12.933594-7.640625-5.378906 0-10.335937 2.929687-12.933593 7.640625l-20.992188 38.074219-42.703125 8.203124c-5.285156 1.015626-9.597656 4.824219-11.261719 9.941407-1.660156 5.117187-.410156 10.730469 3.265625 14.660156l29.726563 31.734375-5.394532 43.148438c-.667968 5.339843 1.621094 10.617187 5.972657 13.777343 4.351562 3.164063 10.082031 3.710938 14.953125 1.425781l39.371094-18.464843zm0 0" fill="#ffa000"/></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 446.25 446.25" style="enable-background:new 0 0 446.25 446.25;" xml:space="preserve" class=""><g><g>
<g id="search">
<path d="M318.75,280.5h-20.4l-7.649-7.65c25.5-28.05,40.8-66.3,40.8-107.1C331.5,73.95,257.55,0,165.75,0S0,73.95,0,165.75 S73.95,331.5,165.75,331.5c40.8,0,79.05-15.3,107.1-40.8l7.65,7.649v20.4L408,446.25L446.25,408L318.75,280.5z M165.75,280.5 C102,280.5,51,229.5,51,165.75S102,51,165.75,51S280.5,102,280.5,165.75S229.5,280.5,165.75,280.5z" data-original="#000000" class="active-path" data-old_color="#000000" fill="#FFFFFF"/>
</g>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 765 B

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 488.85 488.85" style="enable-background:new 0 0 488.85 488.85;" xml:space="preserve">
<g>
<path d="M244.425,98.725c-93.4,0-178.1,51.1-240.6,134.1c-5.1,6.8-5.1,16.3,0,23.1c62.5,83.1,147.2,134.2,240.6,134.2
s178.1-51.1,240.6-134.1c5.1-6.8,5.1-16.3,0-23.1C422.525,149.825,337.825,98.725,244.425,98.725z M251.125,347.025
c-62,3.9-113.2-47.2-109.3-109.3c3.2-51.2,44.7-92.7,95.9-95.9c62-3.9,113.2,47.2,109.3,109.3
C343.725,302.225,302.225,343.725,251.125,347.025z M248.025,299.625c-33.4,2.1-61-25.4-58.8-58.8c1.7-27.6,24.1-49.9,51.7-51.7
c33.4-2.1,61,25.4,58.8,58.8C297.925,275.625,275.525,297.925,248.025,299.625z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 948 B

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve" width="30px" height="30px" class=""><g><path style="fill:#F3F3F3" d="M373.333,117.333H138.667C62.083,117.333,0,179.417,0,256s62.083,138.667,138.667,138.667h234.667 C449.917,394.667,512,332.583,512,256S449.917,117.333,373.333,117.333z" data-original="#CFD8DC" class="active-path" data-old_color="#F2F2F2"/><circle style="fill:#F44336;" cx="138.667" cy="256" r="96" data-original="#F44336"/><g>
<path style="fill:#455A64" d="M288,309.333c-17.673,0-32-14.327-32-32v-42.667c0-17.673,14.327-32,32-32c17.673,0,32,14.327,32,32 v42.667C320,295.006,305.673,309.333,288,309.333z M288,224c-5.891,0-10.667,4.776-10.667,10.667v42.667 c0,5.891,4.776,10.667,10.667,10.667c5.891,0,10.667-4.776,10.667-10.667v-42.667C298.667,228.776,293.891,224,288,224z" data-original="#455A64" class=""/>
<path style="fill:#455A64" d="M352,309.333c-5.891,0-10.667-4.776-10.667-10.667v-85.333c0-5.891,4.776-10.667,10.667-10.667h32 c5.891,0,10.667,4.776,10.667,10.667c0,5.891-4.776,10.667-10.667,10.667h-21.333v74.667 C362.667,304.558,357.891,309.333,352,309.333z" data-original="#455A64" class=""/>
<path style="fill:#455A64" d="M373.333,266.667H352c-5.891,0-10.667-4.776-10.667-10.667c0-5.891,4.776-10.667,10.667-10.667 h21.333c5.891,0,10.667,4.776,10.667,10.667C384,261.891,379.224,266.667,373.333,266.667z" data-original="#455A64" class=""/>
<path style="fill:#455A64" d="M416,309.333c-5.891,0-10.667-4.776-10.667-10.667v-85.333c0-5.891,4.776-10.667,10.667-10.667h32 c5.891,0,10.667,4.776,10.667,10.667c0,5.891-4.776,10.667-10.667,10.667h-21.333v74.667 C426.667,304.558,421.891,309.333,416,309.333z" data-original="#455A64" class=""/>
<path style="fill:#455A64" d="M437.333,266.667H416c-5.891,0-10.667-4.776-10.667-10.667c0-5.891,4.776-10.667,10.667-10.667 h21.333c5.891,0,10.667,4.776,10.667,10.667C448,261.891,443.224,266.667,437.333,266.667z" data-original="#455A64" class=""/>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve" width="30px" height="30px" class=""><g><path style="fill:#F3F3F3" d="M373.333,117.333H138.667C62.083,117.333,0,179.417,0,256s62.083,138.667,138.667,138.667h234.667 C449.917,394.667,512,332.583,512,256S449.917,117.333,373.333,117.333z" data-original="#CFD8DC" class="active-path" data-old_color="#f3f3f3"/><circle style="fill:#4CAF50;" cx="373.333" cy="256" r="96" data-original="#4CAF50"/><g>
<path style="fill:#455A64" d="M117.333,309.333c-17.673,0-32-14.327-32-32v-42.667c0-17.673,14.327-32,32-32s32,14.327,32,32 v42.667C149.333,295.006,135.006,309.333,117.333,309.333z M117.333,224c-5.891,0-10.667,4.776-10.667,10.667v42.667 c0,5.891,4.776,10.667,10.667,10.667S128,283.224,128,277.333v-42.667C128,228.776,123.224,224,117.333,224z" data-original="#455A64" class=""/>
<path style="fill:#455A64" d="M224,309.333c-4.037,0-7.728-2.279-9.536-5.888L192,258.517v40.149 c0,5.891-4.776,10.667-10.667,10.667c-5.891,0-10.667-4.776-10.667-10.667v-85.333c0.006-4.941,3.405-9.232,8.213-10.368 c4.819-1.186,9.812,1.151,11.989,5.611l22.464,44.907v-40.149c0-5.891,4.776-10.667,10.667-10.667 c5.891,0,10.667,4.776,10.667,10.667v85.333c-0.006,4.941-3.405,9.232-8.213,10.368C225.651,309.237,224.827,309.337,224,309.333z" data-original="#455A64" class=""/>
</g></g> </svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve" width="55px" height="55px"><g><path style="fill:none;stroke:#DC9628;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" d="M34,12 V8c0-2.209-1.791-4-4-4s-4,1.791-4,4v4.072"/><path style="fill:#EEAF4B;" d="M16.491,50.638c10.701,1.847,16.658,1.847,27.36,0L53.341,49l0,0c-4.685-4.657-7.317-10.415-7.317-17 v-9c0.038-6.047-3.957-10.478-7.946-12.301c-4.999-2.285-10.815-2.294-15.806,0.008C18.319,12.53,14.038,16.958,14,23v9 c0,6.585-2.315,12.343-7,17l0,0L16.491,50.638z" data-original="#EEAF4B"/><path style="fill:#FBD490;" d="M19,25.991c-0.002,0-0.004,0-0.006,0c-0.552-0.004-0.997-0.454-0.994-1.006 c0.03-4.682,3.752-7.643,5.948-8.654c3.849-1.775,8.594-1.772,12.469-0.002c0.502,0.229,0.723,0.822,0.494,1.325 c-0.229,0.502-0.822,0.724-1.326,0.493c-3.354-1.533-7.469-1.537-10.799,0c-1.767,0.814-4.762,3.173-4.785,6.85 C19.997,25.547,19.549,25.991,19,25.991z" data-original="#FBD490"/><path style="fill:#DC9628;" d="M21.906,51.46C23.35,54.728,26.508,57,30.183,57c3.676,0,6.834-2.273,8.278-5.543 C32.533,52.209,27.83,52.21,21.906,51.46z" data-original="#DC9628"/><path style="fill:#F2ECBF;" d="M4.095,39.967c-0.256,0-0.512-0.098-0.707-0.293C1.203,37.489,0,34.58,0,31.483 c0-3.098,1.203-6.006,3.388-8.19c0.391-0.391,1.023-0.391,1.414,0s0.391,1.023,0,1.414C2.995,26.514,2,28.92,2,31.483 c0,2.563,0.995,4.969,2.802,6.776c0.391,0.391,0.391,1.023,0,1.414C4.606,39.869,4.351,39.967,4.095,39.967z" data-original="#F2ECBF" class="active-path"/><path style="fill:#F2ECBF;" d="M8.305,37.69c-0.256,0-0.512-0.098-0.707-0.293c-3.337-3.337-3.337-8.768,0-12.104 c0.391-0.391,1.023-0.391,1.414,0s0.391,1.023,0,1.414c-2.558,2.558-2.558,6.719,0,9.276c0.391,0.391,0.391,1.023,0,1.414 C8.817,37.593,8.561,37.69,8.305,37.69z" data-original="#F2ECBF" class="active-path"/><path style="fill:#F2ECBF;" d="M55.905,39.967c-0.256,0-0.512-0.098-0.707-0.293c-0.391-0.391-0.391-1.023,0-1.414 C57.005,36.452,58,34.046,58,31.483c0-2.563-0.995-4.97-2.802-6.776c-0.391-0.391-0.391-1.023,0-1.414s1.023-0.391,1.414,0 C58.797,25.478,60,28.386,60,31.483c0,3.097-1.203,6.006-3.388,8.19C56.417,39.869,56.161,39.967,55.905,39.967z" data-original="#F2ECBF" class="active-path"/><path style="fill:#F2ECBF;" d="M51.695,37.69c-0.256,0-0.512-0.098-0.707-0.293c-0.391-0.391-0.391-1.023,0-1.414 c2.558-2.558,2.558-6.719,0-9.276c-0.391-0.391-0.391-1.023,0-1.414s1.023-0.391,1.414,0c3.337,3.337,3.337,8.768,0,12.104 C52.207,37.593,51.951,37.69,51.695,37.69z" data-original="#F2ECBF" class="active-path"/></g> </svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,572 @@
<?php
class ADBC_Tasks_List extends WP_List_Table {
/** Holds the message to be displayed if any */
private $aDBc_message = "";
/** Holds the class for the message : updated or error. Default is updated */
private $aDBc_class_message = "updated";
/** Holds tasks that will be displayed */
private $aDBc_tasks_to_display = array();
/** Holds counts + info of tasks categories */
private $aDBc_tasks_categories_info = array();
/** Should we display "run search" or "continue search" button (after a timeout failed). Default is "run search" */
private $aDBc_which_button_to_show = "new_search";
// This array contains belongs_to info about plugins and themes
private $array_belongs_to_counts = array();
// Holds msg that will be shown if folder adbc_uploads cannot be created by the plugin (This is verified after clicking on scan button)
private $aDBc_permission_adbc_folder_msg = "";
function __construct() {
parent::__construct( array(
'singular' => __( 'Task', 'advanced-database-cleaner' ),
'plural' => __( 'Tasks', 'advanced-database-cleaner' ),
'ajax' => false
) );
$this->aDBc_prepare_and_count_tasks();
$this->aDBc_print_page_content();
}
/** Prepare items */
function aDBc_prepare_and_count_tasks() {
if ( ADBC_PLUGIN_PLAN == "pro" ) {
// Verify if the adbc_uploads cannot be created
$adbc_folder_permission = get_option( "aDBc_permission_adbc_folder_needed" );
if ( ! empty( $adbc_folder_permission ) ) {
$this->aDBc_permission_adbc_folder_msg = sprintf( __( 'The plugin needs to create the following directory "%1$s" to save the scan results but this was not possible automatically. Please create that directory manually and set correct permissions so it can be writable by the plugin.','advanced-database-cleaner' ), ADBC_UPLOAD_DIR_PATH_TO_ADBC );
// Once we display the msg, we delete that option from DB
delete_option( "aDBc_permission_adbc_folder_needed" );
}
}
// Verify if the user wants to edit the categorization of a task. This block test comes from edit_item_categorization.php
if ( ADBC_PLUGIN_PLAN == "pro" ) {
if ( isset( $_POST['aDBc_cancel'] ) ) {
// If the user cancels the edit, remove the temp file
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tasks_manually_correction_temp.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tasks_manually_correction_temp.txt" );
} else if ( isset( $_POST['aDBc_correct'] ) ) {
// Get the new belongs to of items
$new_belongs_to = $_POST['new_belongs_to'];
// Get value of checkbox to see if user wants to send correction to the server
if ( isset( $_POST['aDBc_send_correction_to_server'] ) ) {
$this->aDBc_message = aDBc_edit_categorization_of_items( "tasks", $new_belongs_to, 1 );
} else {
$this->aDBc_message = aDBc_edit_categorization_of_items( "tasks", $new_belongs_to, 0 );
}
// Remove the temp file
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tasks_manually_correction_temp.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tasks_manually_correction_temp.txt" );
}
}
// Process bulk action if any before preparing tasks to display
$this->process_bulk_action();
// Prepare data
aDBc_prepare_items_to_display(
$this->aDBc_tasks_to_display,
$this->aDBc_tasks_categories_info,
$this->aDBc_which_button_to_show,
array(),
array(),
$this->array_belongs_to_counts,
$this->aDBc_message,
$this->aDBc_class_message,
"tasks"
);
// Call WP prepare_items function
$this->prepare_items();
}
/** WP: Get columns */
function get_columns() {
$aDBc_belongs_to_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __( 'Indicates the creator of the task: either a plugin, a theme or WordPress itself. If not sure about the creator, an estimation (%) will be displayed. The higher the percentage is, the more likely that the task belongs to that creator.','advanced-database-cleaner' ) ." </span>
</span>";
$columns = array(
'cb' => '<input type="checkbox" />',
'hook_name' => __( 'Hook name','advanced-database-cleaner' ),
'arguments' => __( 'Arguments','advanced-database-cleaner' ),
'next_run' => __( 'Next run - Frequency','advanced-database-cleaner' ),
'site_id' => __( 'Site','advanced-database-cleaner' ),
'hook_belongs_to' => __( 'Belongs to','advanced-database-cleaner' ) . $aDBc_belongs_to_toolip
);
return $columns;
}
function get_sortable_columns() {
$sortable_columns = array(
'hook_name' => array( 'hook_name', false ),
'site_id' => array( 'site_id', false )
);
return $sortable_columns;
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of tasks to display
$display_data = array_slice($this->aDBc_tasks_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_tasks_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'arguments':
if($item[$column_name] == "none"){
return "<span>" . __('None', 'advanced-database-cleaner') . "</span>";
}else{
$unserialized_args = json_decode($item[$column_name]);
// If the arguments are not an array, we return [N/A]
if (is_array($unserialized_args)) {
$args_as_string = array_map(function($arg) {
return (is_object($arg) || is_array($arg)) ? json_encode($arg) : (string) $arg;
}, $unserialized_args);
return "<span class='aDBc-arguments'>" . implode(" / ", $args_as_string) . "</span>";
} else {
return "<span class='aDBc-arguments'>[N/A]</span>";
}
}
break;
case 'hook_name':
return esc_html($item[$column_name]);
case 'next_run':
case 'site_id':
case 'hook_belongs_to':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Column cb for check box */
function column_cb($item) {
$data = array(
'site_id' => $item['site_id'],
'hook_name' => $item['hook_name'],
'timestamp' => $item['timestamp'],
'arguments' => $item['arguments']
);
$value = json_encode($data);
return sprintf(
"<input type='checkbox' name='aDBc_elements_to_process[]' value='%s' />",
esc_attr($value)
);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'scan_selected' => __( 'Scan selected tasks','advanced-database-cleaner' ),
'edit_categorization' => __( 'Edit categorization','advanced-database-cleaner' ),
'delete' => __( 'Delete','advanced-database-cleaner' )
);
if ( ADBC_PLUGIN_PLAN == "free" ) {
unset( $actions['scan_selected'] );
unset( $actions['edit_categorization'] );
}
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('No tasks found!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'delete' ) {
// If the user wants to clean the tasks he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare tasks to delete in organized array to minimize switching from blogs
$tasks_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $task){
$json = wp_unslash( $task ); // Unslash because WP adds slashes to the POST data
$data = json_decode( $json, true );
$site_id = sanitize_html_class($data['site_id']);
if(is_numeric($site_id)){
if(empty($tasks_to_delete[$site_id])){
$tasks_to_delete[$site_id] = array();
}
array_push($tasks_to_delete[$site_id], $task);
}
}
// Delete tasks
foreach($tasks_to_delete as $site_id => $tasks_info){
switch_to_blog($site_id);
foreach($tasks_info as $task) {
$json = wp_unslash( $task ); // Unslash because WP adds slashes to the POST data
$data = json_decode( $json, true );
$hook = $data['hook_name'];
$timestamp = $data['timestamp'];
$args = $data['arguments'];
if(is_numeric($timestamp)){
if($args == "none"){
wp_unschedule_event($timestamp, $hook);
}else{
$args = json_decode(stripslashes($args));
wp_unschedule_event($timestamp, $hook, $args);
// Check if the user has deleted a task beloging to this plugin. If so, update his data in DB to inactive
// A task of ADBC cannot be without an arg, not necessary to add this check to "none" args
if($hook == "aDBc_clean_scheduler"){
aDBc_update_task_in_db_after_delete($args[0], "aDBc_clean_schedule");
}else if($hook == "aDBc_optimize_scheduler"){
aDBc_update_task_in_db_after_delete($args[0], "aDBc_optimize_schedule");
}
}
}
}
restore_current_blog();
}
}else{
foreach($_POST['aDBc_elements_to_process'] as $task) {
$json = wp_unslash( $task ); // Unslash because WP adds slashes to the POST data
$data = json_decode( $json, true );
$hook = $data['hook_name'];
$timestamp = $data['timestamp'];
$args = $data['arguments'];
if(is_numeric($timestamp)){
if($args == "none"){
wp_unschedule_event($timestamp, $hook);
}else{
$args = json_decode(stripslashes($args));
wp_unschedule_event($timestamp, $hook, $args);
// Check if the user has deleted a task beloging to this plugin. If so, update his data in DB to inactive
// A task of ADBC cannot be without an arg, not necessary to add this check to "none" args
if($hook == "aDBc_clean_scheduler"){
aDBc_update_task_in_db_after_delete($args[0], "aDBc_clean_schedule");
}else if($hook == "aDBc_optimize_scheduler"){
aDBc_update_task_in_db_after_delete($args[0], "aDBc_optimize_schedule");
}
}
}
}
}
// Update the message to show to the user
$this->aDBc_message = __('Selected scheduled tasks cleaned successfully!', 'advanced-database-cleaner');
}
}else if($action == 'edit_categorization'){
// If the user wants to edit categorization of the tasks he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
// Create a temp file containing tasks names to change categorization for
$aDBc_path_items = @fopen(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tasks_manually_correction_temp.txt", "w");
if($aDBc_path_items){
foreach($_POST['aDBc_elements_to_process'] as $task) {
$json = wp_unslash( $task ); // Unslash because WP adds slashes to the POST data
$data = json_decode( $json, true );
$hook = $data['hook_name'];
fwrite($aDBc_path_items, $hook . "\n");
}
fclose($aDBc_path_items);
}
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
// Print a message if any
if($this->aDBc_message != ""){
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
// If the folder adbc_uploads cannot be created, show a msg to users
if(!empty($this->aDBc_permission_adbc_folder_msg)){
echo '<div class="error notice is-dismissible"><p>' . $this->aDBc_permission_adbc_folder_msg . '</p></div>';
}
?>
<div class="aDBc-content-max-width">
<?php
// If tasks_manually_correction_temp.txt exist, this means that user want to edit categorization
if ( ADBC_PLUGIN_PLAN == "pro" && file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . '/tasks_manually_correction_temp.txt' ) ) {
include_once 'edit_item_categorization.php';
} else {
// If not, we print the tasks normally
// Print a notice/warning according to each type of tasks
if ( ADBC_PLUGIN_PLAN == "pro" ) {
if($_GET['aDBc_cat'] == 'o' && $this->aDBc_tasks_categories_info['o']['count'] > 0){
echo '<div class="aDBc-box-warning-orphan">' . __('Tasks below seem to be orphan! However, please delete only those you are sure to be orphan!','advanced-database-cleaner') . '</div>';
}else if(($_GET['aDBc_cat'] == 'all' || $_GET['aDBc_cat'] == 'u') && $this->aDBc_tasks_categories_info['u']['count'] > 0){
$aDBc_settings = get_option('aDBc_settings');
$hide_not_categorized_msg = empty($aDBc_settings['hide_not_categorized_yet_msg']) ? "" : $aDBc_settings['hide_not_categorized_yet_msg'];
if ( $hide_not_categorized_msg != "yes" ) {
echo '<div id="aDBc-box-info" class="aDBc-box-info">'
. '<div style="width:100%">'
. __('Some of your tasks are not categorized yet! Please click on the button below to categorize them!','advanced-database-cleaner')
. '</div>'
. '<div><a href="#" id="aDBc-dismiss-not-categorized-yet-msg" title="' . __('Dismiss similar messages', 'advanced-database-cleaner') . '"><span class="dashicons dashicons-dismiss" style="text-decoration:none;font-size:16px;margin-top:4px"></span></a></div>'
. '</div>';
}
}
}
?>
<div class="aDBc-clear-both" style="margin-top:15px"></div>
<!-- Code for "run new search" button + Show loading image -->
<div style="float:left">
<?php
if ( $this->aDBc_which_button_to_show == "new_search" ) {
$aDBc_search_text = __( 'Scan tasks', 'advanced-database-cleaner' );
} else {
$aDBc_search_text = __( 'Continue scanning ...', 'advanced-database-cleaner' );
}
?>
<!-- Hidden input used by ajax to know which item type we are dealing with -->
<input type="hidden" id="aDBc_item_type" value="tasks"/>
<?php
// These hidden inputs are used by ajax to see if we should execute the scan automatically after reloading a page
$iteration = get_option("aDBc_temp_last_iteration_tasks");
$currently_scanning = get_option("aDBc_temp_currently_scanning_tasks");
?>
<input type="hidden" id="aDBc_currently_scanning" value="<?php echo $currently_scanning; ?>"/>
<input type="hidden" id="aDBc_iteration" value="<?php echo $iteration; ?>"/>
<input type="hidden" id="aDBc_count_uncategorized" value="<?php echo $this->aDBc_tasks_categories_info['u']['count']; ?>"/>
<input type="hidden" id="aDBc_count_all_items" value="<?php echo $this->aDBc_tasks_categories_info['all']['count']; ?>"/>
<?php
if ( ADBC_PLUGIN_PLAN == "pro" ) {
?>
<input id="aDBc_new_search_button" type="submit" class="aDBc-run-new-search" value="<?php echo $aDBc_search_text; ?>" name="aDBc_new_search_button" />
<?php
} else {
?>
<div class="aDBc-premium-tooltip">
<input id="aDBc_new_search_button" type="submit" class="aDBc-run-new-search" value="<?php echo $aDBc_search_text; ?>" name="aDBc_new_search_button" style="opacity:0.5" disabled />
<span style="width:390px" class="aDBc-premium-tooltiptext">
<?php _e('Please <a href="?page=advanced_db_cleaner&aDBc_tab=premium">upgrade</a> to Pro to categorize and detect orphaned tasks','advanced-database-cleaner') ?>
</span>
</div>
<?php
}
?>
</div>
<!-- Print numbers of items found in each category -->
<div class="aDBc-category-counts">
<?php
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
// Remove the paged parameter to start always from the first page when selecting a new category
$aDBc_new_URI = remove_query_arg( 'paged', $aDBc_new_URI );
foreach ( $this->aDBc_tasks_categories_info as $abreviation => $category_info ) {
$aDBc_new_URI = add_query_arg( 'aDBc_cat', $abreviation, $aDBc_new_URI );
$selected_color = $abreviation == $_GET['aDBc_cat'] ? $category_info['color'] : '#eee';
$aDBc_link_style = "color:" . $category_info['color'];
$aDBc_count = $category_info['count'];
if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) {
$aDBc_new_URI = "";
$aDBc_link_style = $aDBc_link_style . ";cursor:default;pointer-events:none";
$aDBc_count = "-";
}
?>
<span class="<?php echo $abreviation == $_GET['aDBc_cat'] ? 'aDBc-selected-category' : ''?>">
<span class="aDBc-premium-tooltip aDBc-category-span">
<a href="<?php echo esc_url( $aDBc_new_URI ) ?>" class="aDBc-category-counts-links" style="<?php echo $aDBc_link_style ?>">
<span><?php echo $category_info['name']; ?></span>
</a>
<div class="aDBc-category-total" style="border:1px solid <?php echo $selected_color ?>; border-bottom:3px solid <?php echo $selected_color ?>;">
<span style="color:#000"><?php echo $aDBc_count ?></span>
</div>
<?php
if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) {
?>
<span style="width:150px" class="aDBc-premium-tooltiptext">
<a href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner/" target="_blank">
<?php _e( 'Available in Pro version!', 'advanced-database-cleaner' ); ?>
</a>
</span>
<?php
}
?>
</span>
</span>
<?php
}
?>
</div>
<div class="aDBc-clear-both"></div>
<div id="aDBc-progress-container">
<span id="aDBc_collected_files" href="#" style="color:gray">
</span>
<div class="aDBc-progress-background">
<div id="aDBc-progress-bar" class="aDBc-progress-bar"></div>
</div>
<a id="aDBc_stop_scan" href="#" style="color:red">
<?php _e('Stop the scan','advanced-database-cleaner') ?>
</a>
<span id="aDBc_stopping_msg" style="display:none">
<?php _e('Stopping...','advanced-database-cleaner') ?>
</span>
</div>
<?php include_once 'header_page_filter.php'; ?>
<div class="aDBc-clear-both"></div>
<form id="aDBc_form" action="" method="post">
<?php
$this->display();
?>
</form>
<?php
}
?>
</div>
<?php
}
}
new ADBC_Tasks_List();
?>

View File

@@ -0,0 +1,632 @@
<?php
class ADBC_Options_List extends WP_List_Table {
/** Holds the message to be displayed if any */
private $aDBc_message = "";
/** Holds the class for the message : updated or error. Default is updated */
private $aDBc_class_message = "updated";
/** Holds options that will be displayed */
private $aDBc_options_to_display = array();
/** Holds counts + info of options categories */
private $aDBc_options_categories_info = array();
/** Should we display "run search" or "continue search" button (after a timeout failed). Default is "run search" */
private $aDBc_which_button_to_show = "new_search";
// This array contains belongs_to info about plugins and themes
private $array_belongs_to_counts = array();
// Holds msg that will be shown if folder adbc_uploads cannot be created by the plugin (This is verified after clicking on scan button)
private $aDBc_permission_adbc_folder_msg = "";
function __construct(){
parent::__construct(array(
'singular' => __('Option', 'advanced-database-cleaner'),
'plural' => __('Options', 'advanced-database-cleaner'),
'ajax' => false
));
$this->aDBc_prepare_and_count_options();
$this->aDBc_print_page_content();
}
/** Prepare items */
function aDBc_prepare_and_count_options() {
if ( ADBC_PLUGIN_PLAN == "pro" ) {
// Verify if the adbc_uploads cannot be created
$adbc_folder_permission = get_option( "aDBc_permission_adbc_folder_needed" );
if ( ! empty( $adbc_folder_permission ) ) {
$this->aDBc_permission_adbc_folder_msg = sprintf( __( 'The plugin needs to create the following directory "%1$s" to save the scan results but this was not possible automatically. Please create that directory manually and set correct permissions so it can be writable by the plugin.','advanced-database-cleaner' ), ADBC_UPLOAD_DIR_PATH_TO_ADBC );
// Once we display the msg, we delete that option from DB
delete_option( "aDBc_permission_adbc_folder_needed" );
}
}
// Verify if the user wants to edit the categorization of an option. This block test comes from edit_item_categorization.php
if ( ADBC_PLUGIN_PLAN == "pro" ) {
if ( isset( $_POST['aDBc_cancel'] ) ) {
// If the user cancels the edit, remove the temp file
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/options_manually_correction_temp.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/options_manually_correction_temp.txt" );
} else if ( isset( $_POST['aDBc_correct'] ) ) {
// Get the new belongs to of items
$new_belongs_to = $_POST['new_belongs_to'];
// Get value of checkbox to see if user wants to send correction to the server
if ( isset( $_POST['aDBc_send_correction_to_server'] ) ) {
$this->aDBc_message = aDBc_edit_categorization_of_items( "options", $new_belongs_to, 1 );
} else {
$this->aDBc_message = aDBc_edit_categorization_of_items( "options", $new_belongs_to, 0 );
}
// Remove the temp file
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/options_manually_correction_temp.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/options_manually_correction_temp.txt" );
}
}
// Process bulk action if any before preparing options to display
$this->process_bulk_action();
// Prepare data
aDBc_prepare_items_to_display(
$this->aDBc_options_to_display,
$this->aDBc_options_categories_info,
$this->aDBc_which_button_to_show,
array(),
array(),
$this->array_belongs_to_counts,
$this->aDBc_message,
$this->aDBc_class_message,
"options"
);
// Call WP prepare_items function
$this->prepare_items();
}
/** WP: Get columns */
function get_columns(){
$aDBc_belongs_to_tooltip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __('Indicates the creator of the option: either a plugin, a theme or WordPress itself. If not sure about the creator, an estimation (%) will be displayed. The higher the percentage is, the more likely that the option belongs to that creator.','advanced-database-cleaner') ." </span>
</span>";
$autoload_true_values = 'yes';
$autoload_false_values = 'no';
if(function_exists('wp_autoload_values_to_autoload')){
$autoload_true_values = 'yes, on, auto, auto-on';
$autoload_false_values = 'no, off, auto-off';
}
$autoload_message = sprintf(
__( 'Indicates whether an option is autoloaded or not. Values to autoload are: %1$s. Values to not autoload are: %2$s', 'advanced-database-cleaner' ),
$autoload_true_values,
$autoload_false_values
);
$aDBc_autoload_tooltip = "<span class='aDBc-tooltips-headers' style='position:absolute;margin-left:18px;margin-top:-1px'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . $autoload_message ." </span>
</span>";
$columns = array(
'cb' => '<input type="checkbox" />',
'option_name' => __('Option name','advanced-database-cleaner'),
'option_value' => __('Value','advanced-database-cleaner'),
'option_size' => __('Size','advanced-database-cleaner'),
'option_autoload' => __('Autoload','advanced-database-cleaner') . $aDBc_autoload_tooltip,
'site_id' => __('Site','advanced-database-cleaner'),
'option_belongs_to' => __('Belongs to','advanced-database-cleaner') . $aDBc_belongs_to_tooltip
);
return $columns;
}
function get_sortable_columns() {
$sortable_columns = array(
'option_name' => array('option_name',false),
'option_size' => array('option_size',false),
'option_autoload' => array('option_autoload',false),
'site_id' => array('site_id',false)
);
return $sortable_columns;
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of options to display
$display_data = array_slice($this->aDBc_options_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_options_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'option_name':
return esc_html($item[$column_name]);
case 'option_size':
return aDBc_format_bytes((int) $item[$column_name]);
case 'option_value':
case 'option_autoload':
case 'site_id':
case 'option_belongs_to':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Column cb for check box */
function column_cb($item) {
$value = $item['site_id'] . "|" . $item['option_name'];
return sprintf(
'<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />',
esc_attr($value)
);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$autoload_on = function_exists('wp_autoload_values_to_autoload') ? " (on)" : "";
$autoload_off = function_exists('wp_autoload_values_to_autoload') ? " (off)" : "";
$actions = array(
'scan_selected' => __( 'Scan selected options','advanced-database-cleaner' ),
'edit_categorization' => __( 'Edit categorization','advanced-database-cleaner' ),
'autoload_yes' => __( 'Set autoload to yes','advanced-database-cleaner' ) . $autoload_on,
'autoload_no' => __( 'Set autoload to no','advanced-database-cleaner' ) . $autoload_off,
'delete' => __( 'Delete','advanced-database-cleaner' )
);
if ( ADBC_PLUGIN_PLAN == "free" ) {
unset( $actions['scan_selected'] );
unset( $actions['edit_categorization'] );
}
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e( 'No options found!', 'advanced-database-cleaner' );
}
/** WP: Process bulk actions */
public function process_bulk_action() {
global $wpdb;
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'delete' ) {
// If the user wants to clean the options he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare options to delete in organized array to minimize switching from blogs
$options_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $option){
$option_info = explode("|", $option, 2);
$site_id = sanitize_html_class($option_info[0]);
$option_name = wp_unslash($option_info[1]);
if(is_numeric($site_id)){
if(empty($options_to_delete[$site_id])){
$options_to_delete[$site_id] = array();
}
array_push($options_to_delete[$site_id], $option_name);
}
}
// Delete options
foreach($options_to_delete as $site_id => $options){
switch_to_blog($site_id);
foreach($options as $option) {
delete_option($option);
}
restore_current_blog();
}
}else{
foreach($_POST['aDBc_elements_to_process'] as $option) {
$aDBc_option_info = explode("|", $option, 2);
$option_name = wp_unslash($aDBc_option_info[1]); // Because WP adds slashes to options in the POST array
delete_option($option_name);
}
}
// Update the message to show to the user
$this->aDBc_message = __('Selected options cleaned successfully!', 'advanced-database-cleaner');
}
} else if ( $action == 'autoload_yes' || $action == 'autoload_no' ) {
$autoload_value = function_exists( 'wp_autoload_values_to_autoload' )
? ( $action == 'autoload_yes' ? 'on' : 'off' )
: ( $action == 'autoload_yes' ? 'yes' : 'no' );
// If the user wants to change autoload for selected options
if ( isset( $_POST['aDBc_elements_to_process'] ) ) {
if ( function_exists( 'is_multisite' ) && is_multisite() ) {
// Prepare options to process in organized array to minimize switching from blogs
$options_to_process = array();
foreach ( $_POST['aDBc_elements_to_process'] as $option ) {
$option_info = explode( "|", $option, 2);
$site_id = sanitize_html_class( $option_info[0] );
$option_name = wp_unslash($option_info[1]); // Because WP adds slashes to options in the POST array
if ( is_numeric( $site_id ) ) {
if ( empty( $options_to_process[$site_id] ) )
$options_to_process[$site_id] = array();
array_push( $options_to_process[$site_id], $option_name );
}
}
// Change autoload
foreach ( $options_to_process as $site_id => $options ) {
switch_to_blog( $site_id );
if ( ! empty( $options ) ) {
// Build the placeholders for each option name.
$placeholders = implode( ',', array_fill( 0, count( $options ), '%s' ) );
// Construct the options table name with the blog prefix.
$table_name = $wpdb->prefix . 'options';
// Create the SQL update statement.
$sql = "UPDATE {$table_name} SET autoload = %s WHERE option_name IN ($placeholders)";
// Merge the autoload value and option names into a single array.
$args = array_merge( [ $autoload_value ], $options );
// Execute the prepared query.
$wpdb->query( $wpdb->prepare( $sql, $args ) );
}
restore_current_blog();
}
} else {
// Array to store the option names to update
$options_list = array();
// Loop through the selected options
foreach ( $_POST['aDBc_elements_to_process'] as $option ) {
$aDBc_option_info = explode( "|", $option, 2 );
$option_name = wp_unslash($aDBc_option_info[1]); // Because WP adds slashes to options in the POST array
// Collect the option names to update
$options_list[] = $option_name;
}
// Update the autoload value for the selected options
if ( ! empty( $options_list ) ) {
// Build the placeholders for each option name
$placeholders = implode( ',', array_fill( 0, count( $options_list ), "'%s'" ) );
// Create the SQL update statement
$sql = "UPDATE {$wpdb->options} SET autoload = %s WHERE option_name IN ($placeholders)";
// Merge the autoload value and option names into a single array
$args = array_merge( [ $autoload_value ], $options_list );
// Execute the prepared query
$wpdb->query( $wpdb->prepare( $sql, $args ) );
}
}
// Update the message to show to the user
$this->aDBc_message = __( 'Autoload value successfully changed!', 'advanced-database-cleaner' );
}
} else if ( $action == 'edit_categorization' ) {
// If the user wants to edit categorization of the options he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
// Create a temp file containing options names to change categorization for
$aDBc_path_items = @fopen(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/options_manually_correction_temp.txt", "w");
if($aDBc_path_items){
foreach($_POST['aDBc_elements_to_process'] as $option){
$option_info = explode("|", $option, 2);
$option_name = wp_unslash($option_info[1]); // Because WP adds slashes to options in the POST array
fwrite($aDBc_path_items, $option_name . "\n");
}
fclose($aDBc_path_items);
}
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
// Print a message if any
if($this->aDBc_message != ""){
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
// If the folder adbc_uploads cannot be created, show a msg to users
if(!empty($this->aDBc_permission_adbc_folder_msg)){
echo '<div class="error notice is-dismissible"><p>' . $this->aDBc_permission_adbc_folder_msg . '</p></div>';
}
?>
<div class="aDBc-content-max-width">
<?php
// If options_manually_correction_temp.txt exist, this means that user want to edit categorization
if ( ADBC_PLUGIN_PLAN == "pro" && file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . '/options_manually_correction_temp.txt' ) ) {
include_once 'edit_item_categorization.php';
} else {
// If not, we print the options normally
// Print a notice/warning according to each type of options
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$aDBc_iteration = get_option( "aDBc_temp_last_iteration_options" );
$aDBc_currently_scanning = get_option( "aDBc_temp_currently_scanning_options" );
if ($aDBc_iteration === false && $aDBc_currently_scanning === false) {
if($_GET['aDBc_cat'] == 'o' && $this->aDBc_options_categories_info['o']['count'] > 0){
echo '<div class="aDBc-box-warning-orphan">' . __('Options below seem to be orphan! However, please delete only those you are sure to be orphan!','advanced-database-cleaner') . '</div>';
}else if(($_GET['aDBc_cat'] == 'all' || $_GET['aDBc_cat'] == 'u') && $this->aDBc_options_categories_info['u']['count'] > 0){
$aDBc_settings = get_option('aDBc_settings');
$hide_not_categorized_msg = empty($aDBc_settings['hide_not_categorized_yet_msg']) ? "" : $aDBc_settings['hide_not_categorized_yet_msg'];
if ( $hide_not_categorized_msg != "yes" ) {
echo '<div id="aDBc-box-info" class="aDBc-box-info">'
. '<div style="width:100%">'
. __('Some of your options are not categorized yet! Please click on the button below to categorize them!','advanced-database-cleaner')
. '</div>'
. '<div><a href="#" id="aDBc-dismiss-not-categorized-yet-msg" title="' . __('Dismiss similar messages', 'advanced-database-cleaner') . '"><span class="dashicons dashicons-dismiss" style="text-decoration:none;font-size:16px;margin-top:4px"></span></a></div>'
. '</div>';
}
}
}
}
?>
<div class="aDBc-clear-both" style="margin-top:15px"></div>
<!-- Code for "run new search" button + Show loading image -->
<div style="float:left">
<?php
if ( $this->aDBc_which_button_to_show == "new_search" ) {
$aDBc_search_text = __( 'Scan options', 'advanced-database-cleaner' );
} else {
$aDBc_search_text = __( 'Continue scanning ...', 'advanced-database-cleaner' );
}
?>
<!-- Hidden input used by ajax to know which item type we are dealing with -->
<input type="hidden" id="aDBc_item_type" value="options"/>
<?php
// These hidden inputs are used by ajax to see if we should execute the scan automatically after reloading a page
$iteration = get_option("aDBc_temp_last_iteration_options");
$currently_scanning = get_option("aDBc_temp_currently_scanning_options");
?>
<input type="hidden" id="aDBc_currently_scanning" value="<?php echo $currently_scanning; ?>"/>
<input type="hidden" id="aDBc_iteration" value="<?php echo $iteration; ?>"/>
<input type="hidden" id="aDBc_count_uncategorized" value="<?php echo $this->aDBc_options_categories_info['u']['count']; ?>"/>
<input type="hidden" id="aDBc_count_all_items" value="<?php echo $this->aDBc_options_categories_info['all']['count']; ?>"/>
<?php
if ( ADBC_PLUGIN_PLAN == "pro" ) {
?>
<input id="aDBc_new_search_button" type="submit" class="aDBc-run-new-search" value="<?php echo $aDBc_search_text; ?>" name="aDBc_new_search_button" />
<?php
} else {
?>
<div class="aDBc-premium-tooltip">
<input id="aDBc_new_search_button" type="submit" class="aDBc-run-new-search" value="<?php echo $aDBc_search_text; ?>" name="aDBc_new_search_button" style="opacity:0.5" disabled />
<span style="width:390px" class="aDBc-premium-tooltiptext">
<?php _e('Please <a href="?page=advanced_db_cleaner&aDBc_tab=premium">upgrade</a> to Pro to categorize and detect orphaned options','advanced-database-cleaner') ?>
</span>
</div>
<?php
}
?>
</div>
<!-- Print numbers of items found in each category -->
<div class="aDBc-category-counts">
<?php
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
// Remove the paged parameter to start always from the first page when selecting a new category
$aDBc_new_URI = remove_query_arg( 'paged', $aDBc_new_URI );
foreach ( $this->aDBc_options_categories_info as $abreviation => $category_info ) {
$aDBc_new_URI = add_query_arg( 'aDBc_cat', $abreviation, $aDBc_new_URI );
$selected_color = $abreviation == $_GET['aDBc_cat'] ? $category_info['color'] : '#eee';
$aDBc_link_style = "color:" . $category_info['color'];
$aDBc_count = $category_info['count'];
if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) {
$aDBc_new_URI = "";
$aDBc_link_style = $aDBc_link_style . ";cursor:default;pointer-events:none";
$aDBc_count = "-";
}
?>
<span class="<?php echo $abreviation == $_GET['aDBc_cat'] ? 'aDBc-selected-category' : ''?>">
<span class="aDBc-premium-tooltip aDBc-category-span">
<a href="<?php echo esc_url( $aDBc_new_URI ) ?>" class="aDBc-category-counts-links" style="<?php echo $aDBc_link_style ?>">
<span><?php echo $category_info['name']; ?></span>
</a>
<div class="aDBc-category-total" style="border:1px solid <?php echo $selected_color ?>; border-bottom:3px solid <?php echo $selected_color ?>;">
<span style="color:#000"><?php echo $aDBc_count ?></span>
</div>
<?php
if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) {
?>
<span style="width:150px" class="aDBc-premium-tooltiptext">
<a href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner/" target="_blank">
<?php _e( 'Available in Pro version!', 'advanced-database-cleaner' ); ?>
</a>
</span>
<?php
}
?>
</span>
</span>
<?php
}
?>
</div>
<div class="aDBc-clear-both"></div>
<div id="aDBc-progress-container">
<span id="aDBc_collected_files" href="#" style="color:gray">
</span>
<div class="aDBc-progress-background">
<div id="aDBc-progress-bar" class="aDBc-progress-bar"></div>
</div>
<a id="aDBc_stop_scan" href="#" style="color:red">
<?php _e('Stop the scan','advanced-database-cleaner') ?>
</a>
<span id="aDBc_stopping_msg" style="display:none">
<?php _e('Stopping...','advanced-database-cleaner') ?>
</span>
</div>
<?php include_once 'header_page_filter.php'; ?>
<div class="aDBc-clear-both"></div>
<?php
// print the total size of autoloaded options
[$total_size, $health_status] = adbc_get_total_autoload_size('KB');
$style = $health_status == 'good' ? 'background:rgb(235, 252, 239);border:1px solid rgb(207, 246, 217)':'background:rgb(255, 242, 242);border:1px solid rgb(242, 217, 217)';
$dashicon = $health_status == 'good' ? 'dashicons-yes' : 'dashicons-warning';
$dashicon_style = $health_status == 'good' ? 'color:green' : 'color:orange';
$status_sentence = $health_status == 'good' ? '[' . __('Good', 'advanced-database-cleaner') . ']' : __('This size should be reduced to prevent performance issues', 'advanced-database-cleaner');
echo '<div style="' . $style . ';color:#222;margin-top:-10px;margin-bottom:15px;padding-bottom:10px;padding-left:10px;padding-right:10px;border-radius:4px">'
. '<span class="dashicons ' . $dashicon . '" style="' . $dashicon_style . ';padding-right:5px"></span>'
. __('Total size of autoloaded options: ','advanced-database-cleaner') . '<b>' . $total_size . '</b> KB. ' . $status_sentence . '</div>';
?>
<form id="aDBc_form" action="" method="post">
<?php
$this->display();
?>
</form>
<?php
}
?>
</div>
<?php
}
}
new ADBC_Options_List();
?>

View File

@@ -0,0 +1,869 @@
<?php
class ADBC_Tables_List extends WP_List_Table {
/** Holds the message to be displayed if any */
private $aDBc_message = "";
/** Holds the class for the message : updated or error. Default is updated */
private $aDBc_class_message = "updated";
/** Holds tables that will be displayed */
private $aDBc_tables_to_display = array();
/** Holds counts + info of tables categories */
private $aDBc_tables_categories_info = array();
/** Should we display "run search" or "continue search" button (after a timeout failed). Default is "run search" */
private $aDBc_which_button_to_show = "new_search";
private $aDBc_total_tables_to_optimize = 0;
private $aDBc_total_lost = 0;
private $aDBc_tables_name_to_optimize = array();
private $aDBc_total_tables_to_repair = 0;
private $aDBc_tables_name_to_repair = array();
// This array contains belongs_to info about plugins and themes
private $array_belongs_to_counts = array();
// Holds msg that will be shown if folder adbc_uploads cannot be created by the plugin (This is verified after clicking on scan button)
private $aDBc_permission_adbc_folder_msg = "";
function __construct(){
parent::__construct(array(
'singular' => __('Table', 'advanced-database-cleaner'),
'plural' => __('Tables', 'advanced-database-cleaner'),
'ajax' => false
));
$this->aDBc_prepare_and_count_tables();
$this->aDBc_print_page_content();
}
/** Prepare items */
function aDBc_prepare_and_count_tables() {
if ( ADBC_PLUGIN_PLAN == "pro" ) {
// Verify if the adbc_uploads cannot be created
$adbc_folder_permission = get_option( "aDBc_permission_adbc_folder_needed" );
if ( ! empty( $adbc_folder_permission ) ) {
$this->aDBc_permission_adbc_folder_msg = sprintf( __( 'The plugin needs to create the following directory "%1$s" to save the scan results but this was not possible automatically. Please create that directory manually and set correct permissions so it can be writable by the plugin.','advanced-database-cleaner' ), ADBC_UPLOAD_DIR_PATH_TO_ADBC );
// Once we display the msg, we delete that option from DB
delete_option( "aDBc_permission_adbc_folder_needed" );
}
}
// Test if user wants to delete a scheduled task
if(isset($_POST['aDBc_delete_schedule'])){
//Quick nonce security check!
if(!check_admin_referer('delete_optimize_schedule_nonce', 'delete_optimize_schedule_nonce'))
return; //get out if we didn't click the delete link
// We delete the schedule
$aDBc_sanitized_schedule_name = sanitize_html_class($_POST['aDBc_delete_schedule']);
wp_clear_scheduled_hook('aDBc_optimize_scheduler', array($aDBc_sanitized_schedule_name));
// We delete the item from database
$aDBc_schedules = get_option('aDBc_optimize_schedule');
unset($aDBc_schedules[$aDBc_sanitized_schedule_name]);
update_option('aDBc_optimize_schedule', $aDBc_schedules, "no");
$this->aDBc_message = __('The clean-up schedule deleted successfully!', 'advanced-database-cleaner');
}
// Verify if the user wants to edit the categorization of a table. This block test comes from edit_item_categorization.php
if ( ADBC_PLUGIN_PLAN == "pro" ) {
if ( isset( $_POST['aDBc_cancel'] ) ) {
// If the user cancels the edit, remove the temp file
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" );
} else if ( isset( $_POST['aDBc_correct'] ) ) {
// Get the new belongs to of items
$new_belongs_to = $_POST['new_belongs_to'];
// Get value of checkbox to see if user wants to send correction to the server
if ( isset( $_POST['aDBc_send_correction_to_server'] ) ) {
$this->aDBc_message = aDBc_edit_categorization_of_items( "tables", $new_belongs_to, 1 );
} else {
$this->aDBc_message = aDBc_edit_categorization_of_items( "tables", $new_belongs_to, 0 );
}
// Remove the temp file
if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" ) )
unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" );
}
}
// Process bulk action if any before preparing tables to display
$this->process_bulk_action();
// Get the names of all tables that should be optimized and count them to print it in the right side of the page
global $wpdb;
$aDBc_tables_to_optimize = $wpdb->get_results("SELECT table_name, data_free FROM information_schema.tables WHERE table_schema = '" . DB_NAME ."' and Engine <> 'InnoDB' and data_free > 0");
$this->aDBc_total_tables_to_optimize = count($aDBc_tables_to_optimize);
foreach($aDBc_tables_to_optimize as $table){
// Get table name
$table_name = "";
// This test to prevent issues in MySQL 8 where tables are not shown
// MySQL 5 uses $table->table_name while MySQL 8 uses $table->TABLE_NAME
if(property_exists($table, "table_name")){
$table_name = $table->table_name;
}else if(property_exists($table, "TABLE_NAME")){
$table_name = $table->TABLE_NAME;
}
array_push($this->aDBc_tables_name_to_optimize, $table_name);
if(property_exists($table, "data_free")){
$this->aDBc_total_lost += $table->data_free;
}
}
// Get the names of all tables that should be repaired and count them to print it in the right side of the page
$aDBc_tables_maybe_repair = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_schema = '" . DB_NAME ."' and Engine IN ('CSV', 'MyISAM', 'ARCHIVE')");
foreach($aDBc_tables_maybe_repair as $table){
// Get table name
$table_name = "";
// This test to prevent issues in MySQL 8 where tables are not shown
// MySQL 5 uses $table->table_name while MySQL 8 uses $table->TABLE_NAME
if(property_exists($table, "table_name")){
$table_name = $table->table_name;
}else if(property_exists($table, "TABLE_NAME")){
$table_name = $table->TABLE_NAME;
}
$query_result = $wpdb->get_results("CHECK TABLE `" . $table_name. "`");
foreach($query_result as $row){
if($row->Msg_type == 'error'){
if(preg_match('/corrupt/i', $row->Msg_text)){
array_push($this->aDBc_tables_name_to_repair, $table_name);
}
}
}
}
$this->aDBc_total_tables_to_repair = count($this->aDBc_tables_name_to_repair);
// Prepare data
aDBc_prepare_items_to_display(
$this->aDBc_tables_to_display,
$this->aDBc_tables_categories_info,
$this->aDBc_which_button_to_show,
$this->aDBc_tables_name_to_optimize,
$this->aDBc_tables_name_to_repair,
$this->array_belongs_to_counts,
$this->aDBc_message,
$this->aDBc_class_message,
"tables"
);
// Call WP prepare_items function
$this->prepare_items();
}
/** WP: Get columns */
function get_columns(){
$aDBc_belongs_to_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __('Indicates the creator of the table: either a plugin, a theme or WordPress itself. If not sure about the creator, an estimation (%) will be displayed. The higher the percentage is, the more likely that the table belongs to that creator.','advanced-database-cleaner') ." </span>
</span>";
$columns = array(
'cb' => '<input type="checkbox" />',
'table_name' => __('Table name','advanced-database-cleaner'),
'table_prefix' => __('Prefix','advanced-database-cleaner'),
'table_rows' => __('Rows','advanced-database-cleaner'),
'table_size' => __('Size','advanced-database-cleaner'),
'table_lost' => __('Lost','advanced-database-cleaner'),
'site_id' => __('Site','advanced-database-cleaner'),
'table_belongs_to' => __('Belongs to','advanced-database-cleaner') . $aDBc_belongs_to_toolip
);
return $columns;
}
function get_sortable_columns() {
$sortable_columns = array(
'table_name' => array( 'table_name', false ),
'table_rows' => array( 'table_rows', false ),
'table_size' => array( 'table_size', false ),
'site_id' => array( 'site_id', false )
);
return $sortable_columns;
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of tables to display
$display_data = array_slice($this->aDBc_tables_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_tables_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Get columns that should be hidden */
function get_hidden_columns() {
// If MU, nothing to hide, else hide Side ID column
if ( function_exists( 'is_multisite' ) && is_multisite() ) {
return array( 'table_prefix', 'table_lost' );
} else {
return array( 'table_prefix', 'table_lost', 'site_id' );
}
}
/** WP: Column default */
function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'table_name':
$prefix_and_name = $item['table_prefix'] . $item[$column_name];
$return_name = "<span class='aDBc-bold'>" . esc_html($item['table_prefix']) . "</span>" . esc_html($item[$column_name]);
if ( $item['table_lost'] > 0 && in_array( $prefix_and_name, $this->aDBc_tables_name_to_optimize ) ) {
$lost = aDBc_get_size_from_bytes( $item['table_lost'] );
$return_name .= "<br/>";
$return_name .= "<span class='aDBc-lost-space'>" . __( 'Lost space', 'advanced-database-cleaner' ) . "</span>";
$return_name .= "<span style='font-size:12px'> : " . $lost . "</span>";
$return_name .= "<span style='color:grey'> (" . __( 'to optimize', 'advanced-database-cleaner' ) . ")</span>";
}
if ( in_array( $prefix_and_name, $this->aDBc_tables_name_to_repair ) ) {
$return_name .= "<br/>";
$return_name .= "<span class='aDBc-corrupted'>" . __( 'Corrupted!', 'advanced-database-cleaner' ) . "</span>";
$return_name .= "<span style='color:grey'> (" . __( 'to repair', 'advanced-database-cleaner' ) . ")</span>";
}
return $return_name;
break;
case 'table_size':
return aDBc_get_size_from_bytes( $item['table_size'] );
break;
case 'table_lost':
return aDBc_get_size_from_bytes( $item['table_lost'] );
break;
case 'table_prefix':
case 'table_rows':
case 'site_id':
case 'table_belongs_to':
return $item[$column_name];
default:
return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Column cb for check box */
function column_cb( $item ) {
$value = $item['table_prefix'] . "|" . $item['table_name'];
return sprintf(
'<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />',
esc_attr($value)
);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'scan_selected' => __( 'Scan selected tables', 'advanced-database-cleaner' ),
'edit_categorization' => __( 'Edit categorization', 'advanced-database-cleaner' ),
'optimize' => __( 'Optimize', 'advanced-database-cleaner' ),
'repair' => __( 'Repair', 'advanced-database-cleaner' ),
'empty' => __( 'Empty rows', 'advanced-database-cleaner' ),
'delete' => __( 'Delete', 'advanced-database-cleaner' )
);
if ( ADBC_PLUGIN_PLAN == "free" ) {
unset( $actions['scan_selected'] );
unset( $actions['edit_categorization'] );
}
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e( 'No tables found!', 'advanced-database-cleaner' );
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
// Get the list of all tables names to validate selected tables
global $wpdb;
$sql_rows = "SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = '" . DB_NAME . "';";
$valid_tables_names = $wpdb->get_col( $sql_rows );
if ( $action == 'delete' ) {
// Prepare an array containing names of tables deleted
$names_deleted = array();
// If the user wants to clean the tables he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
foreach($_POST['aDBc_elements_to_process'] as $table){
$table_info = explode("|", $table, 2);
$table_prefix = $table_info[0];
$table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request
$full_table_name = $table_prefix . $table_name;
// Validate table name before deleting
if ( in_array( $full_table_name, $valid_tables_names ) ) {
if($wpdb->query("DROP TABLE `" . $full_table_name . "`")){
array_push($names_deleted, $table_name);
}
}
}
// After deleting tables, delete names also from file categorization
// xxx (should I add this as well to options & crons?)
if ( ADBC_PLUGIN_PLAN == "pro" ) {
aDBc_refresh_categorization_file_after_delete($names_deleted, 'tables');
}
// Update the message to show to the user
$this->aDBc_message = __('Selected tables cleaned successfully!', 'advanced-database-cleaner');
}
}else if($action == 'optimize'){
// If the user wants to optimize the tables he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
foreach($_POST['aDBc_elements_to_process'] as $table) {
$table_info = explode("|", $table, 2);
$table_prefix = $table_info[0];
$table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request
$full_table_name = $table_prefix . $table_name;
// Validate table name before optimizing
if ( in_array( $full_table_name, $valid_tables_names ) ) {
$wpdb->query("OPTIMIZE TABLE `" . $full_table_name . "`");
// run analyze sql query to force updating the table statistics
$wpdb->query("ANALYZE TABLE `" . $full_table_name . "`");
}
}
// Update the message to show to the user
$this->aDBc_message = __('Selected tables optimized successfully!', 'advanced-database-cleaner');
}
}else if($action == 'empty'){
// If the user wants to empty the tables he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
foreach($_POST['aDBc_elements_to_process'] as $table) {
$table_info = explode("|", $table, 2);
$table_prefix = $table_info[0];
$table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request
$full_table_name = $table_prefix . $table_name;
// Validate table name before emptying
if ( in_array( $full_table_name, $valid_tables_names ) ) {
$wpdb->query("TRUNCATE TABLE `" . $full_table_name . "`");
// run analyze sql query to force updating the table statistics
$wpdb->query("ANALYZE TABLE `" . $full_table_name . "`");
}
}
// Update the message to show to the user
$this->aDBc_message = __('Selected tables emptied successfully!', 'advanced-database-cleaner');
}
}else if($action == 'repair'){
// If the user wants to repair the tables he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
$cannot_repair = 0;
foreach($_POST['aDBc_elements_to_process'] as $table) {
$table_info = explode("|", $table, 2);
$table_prefix = $table_info[0];
$table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request
$full_table_name = $table_prefix . $table_name;
// Validate table name before repairing
if ( in_array( $full_table_name, $valid_tables_names ) ) {
$query_result = $wpdb->get_results("REPAIR TABLE `" . $full_table_name . "`");
foreach($query_result as $row){
if($row->Msg_type == 'error'){
if(preg_match('/corrupt/i', $row->Msg_text)){
$cannot_repair++;
}
} else {
// run analyze sql query to force updating the table statistics
$wpdb->query("ANALYZE TABLE `" . $full_table_name . "`");
}
}
}
}
// Update the message to show to the user
if($cannot_repair == 0){
$this->aDBc_message = __('Selected tables repaired successfully!', 'advanced-database-cleaner');
}else{
$this->aDBc_class_message = "error";
$this->aDBc_message = __('Some of your tables cannot be repaired!', 'advanced-database-cleaner');
}
}
}else if($action == 'edit_categorization'){
// If the user wants to edit categorization of the tables he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
// Create a temp file containing tables names to change categorization for
$aDBc_path_items = @fopen(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt", "w");
if($aDBc_path_items){
foreach($_POST['aDBc_elements_to_process'] as $table) {
$table_info = explode("|", $table, 2);
$table_prefix = $table_info[0];
$table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request
$full_table_name = $table_prefix . $table_name;
// Validate table name before adding it to the file
if ( in_array( $full_table_name, $valid_tables_names ) ) {
fwrite($aDBc_path_items, $table_name . "\n");
}
}
fclose($aDBc_path_items);
}
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
// Print a message if any
if($this->aDBc_message != ""){
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
// If the folder adbc_uploads cannot be created, show a msg to users
if(!empty($this->aDBc_permission_adbc_folder_msg)){
echo '<div class="error notice is-dismissible"><p>' . $this->aDBc_permission_adbc_folder_msg . '</p></div>';
}
?>
<div class="aDBc-content-max-width">
<?php
// If tables_manually_correction_temp.txt exist, this means that user want to edit categorization.
if ( ADBC_PLUGIN_PLAN == "pro" && file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . '/tables_manually_correction_temp.txt' ) ) {
include_once 'edit_item_categorization.php';
} else {
// If not, we print the tables normally
// Print a notice/warning according to each type of tables
if ( ADBC_PLUGIN_PLAN == "pro" ) {
if($_GET['aDBc_cat'] == 'o' && $this->aDBc_tables_categories_info['o']['count'] > 0){
echo '<div class="aDBc-box-warning-orphan">' . __('Tables below seem to be orphan! However, please delete only those you are sure to be orphan!','advanced-database-cleaner') . '</div>';
}else if(($_GET['aDBc_cat'] == 'all' || $_GET['aDBc_cat'] == 'u') && $this->aDBc_tables_categories_info['u']['count'] > 0){
$aDBc_settings = get_option('aDBc_settings');
$hide_not_categorized_msg = empty($aDBc_settings['hide_not_categorized_yet_msg']) ? "" : $aDBc_settings['hide_not_categorized_yet_msg'];
if ( $hide_not_categorized_msg != "yes" ) {
echo '<div id="aDBc-box-info" class="aDBc-box-info">'
. '<div style="width:100%">'
. __('Some of your tables are not categorized yet! Please click on the button below to categorize them!','advanced-database-cleaner')
. '</div>'
. '<div><a href="#" id="aDBc-dismiss-not-categorized-yet-msg" title="' . __('Dismiss similar messages', 'advanced-database-cleaner') . '"><span class="dashicons dashicons-dismiss" style="text-decoration:none;font-size:16px;margin-top:4px"></span></a></div>'
. '</div>';
}
}
}
?>
<div class="aDBc-clear-both" style="margin-top:15px"></div>
<!-- Code for "run new search" button + Show loading image -->
<div style="float:left">
<?php
if ( $this->aDBc_which_button_to_show == "new_search" ) {
$aDBc_search_text = __( 'Scan tables', 'advanced-database-cleaner' );
} else {
$aDBc_search_text = __( 'Continue scanning ...', 'advanced-database-cleaner' );
}
?>
<!-- Hidden input used by ajax to know which item type we are dealing with -->
<input type="hidden" id="aDBc_item_type" value="tables"/>
<?php
// These hidden inputs are used by ajax to see if we should execute scanning automatically after reloading a page
$iteration = get_option("aDBc_temp_last_iteration_tables");
$currently_scanning = get_option("aDBc_temp_currently_scanning_tables");
?>
<input type="hidden" id="aDBc_currently_scanning" value="<?php echo $currently_scanning; ?>"/>
<input type="hidden" id="aDBc_iteration" value="<?php echo $iteration; ?>"/>
<input type="hidden" id="aDBc_count_uncategorized" value="<?php echo $this->aDBc_tables_categories_info['u']['count']; ?>"/>
<input type="hidden" id="aDBc_count_all_items" value="<?php echo $this->aDBc_tables_categories_info['all']['count']; ?>"/>
<?php
if ( ADBC_PLUGIN_PLAN == "pro" ) {
?>
<input id="aDBc_new_search_button" type="submit" class="aDBc-run-new-search" value="<?php echo $aDBc_search_text; ?>" name="aDBc_new_search_button" />
<?php
} else {
?>
<div class="aDBc-premium-tooltip">
<input id="aDBc_new_search_button" type="submit" class="aDBc-run-new-search" value="<?php echo $aDBc_search_text; ?>" name="aDBc_new_search_button" style="opacity:0.5" disabled />
<span style="width:390px" class="aDBc-premium-tooltiptext">
<?php _e('Please <a href="?page=advanced_db_cleaner&aDBc_tab=premium">upgrade</a> to Pro to categorize and detect orphaned tables','advanced-database-cleaner') ?>
</span>
</div>
<?php
}
?>
</div>
<!-- Print numbers of items found in each category -->
<div class="aDBc-category-counts">
<?php
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
// Remove the paged parameter to start always from the first page when selecting a new category
$aDBc_new_URI = remove_query_arg( 'paged', $aDBc_new_URI );
foreach ( $this->aDBc_tables_categories_info as $abreviation => $category_info ) {
$aDBc_new_URI = add_query_arg( 'aDBc_cat', $abreviation, $aDBc_new_URI );
$selected_color = $abreviation == $_GET['aDBc_cat'] ? $category_info['color'] : '#eee';
$aDBc_link_style = "color:" . $category_info['color'];
$aDBc_count = $category_info['count'];
if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) {
$aDBc_new_URI = "";
$aDBc_link_style = $aDBc_link_style . ";cursor:default;pointer-events:none";
$aDBc_count = "-";
}
?>
<span class="<?php echo $abreviation == $_GET['aDBc_cat'] ? 'aDBc-selected-category' : ''?>">
<span class="aDBc-premium-tooltip aDBc-category-span">
<a href="<?php echo esc_url( $aDBc_new_URI ); ?>" class="aDBc-category-counts-links" style="<?php echo $aDBc_link_style ?>">
<span><?php echo $category_info['name']; ?></span>
</a>
<div class="aDBc-category-total" style="border:1px solid <?php echo $selected_color ?>; border-bottom:3px solid <?php echo $selected_color ?>;">
<span style="color:#000"><?php echo $aDBc_count ?></span>
</div>
<?php
if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) {
?>
<span style="width:150px" class="aDBc-premium-tooltiptext">
<a href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner/" target="_blank">
<?php _e( 'Available in Pro version!', 'advanced-database-cleaner' ); ?>
</a>
</span>
<?php
}
?>
</span>
</span>
<?php
}
?>
</div>
<div class="aDBc-clear-both"></div>
<div id="aDBc-progress-container">
<span id="aDBc_collected_files" href="#" style="color:gray">
</span>
<div class="aDBc-progress-background">
<div id="aDBc-progress-bar" class="aDBc-progress-bar"></div>
</div>
<a id="aDBc_stop_scan" href="#" style="color:red">
<?php _e('Stop the scan','advanced-database-cleaner') ?>
</a>
<span id="aDBc_stopping_msg" style="display:none">
<?php _e('Stopping...','advanced-database-cleaner') ?>
</span>
</div>
<?php include_once 'header_page_filter.php'; ?>
<div class="aDBc-clear-both"></div>
<form id="aDBc_form" action="" method="post">
<div class="aDBc-left-content">
<?php
$this->display();
?>
</div>
</form>
<div class="aDBc-right-box">
<div class="aDBc-right-box-content" style="text-align:center">
<?php
if ( $this->aDBc_total_tables_to_optimize == 0 && $this->aDBc_total_tables_to_repair == 0 ) {
?>
<img width="58px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/db_clean.svg'?>"/>
<div class="aDBc-text-status-db"><?php _e( 'Your database is optimized!', 'advanced-database-cleaner' ); ?></div>
<?php
} else {
// Add link to numbers of tables that should be optimized/repaired
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = remove_query_arg( array( 'paged', 's', 'belongs_to' ), $aDBc_new_URI );
$aDBc_new_URI = add_query_arg( 'aDBc_cat', 'all', $aDBc_new_URI );
?>
<img width="55px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/warning.svg'?>"/>
<?php
if ( $this->aDBc_total_tables_to_optimize > 0 ) {
$aDBc_new_URI = add_query_arg( 't_type', 'optimize', $aDBc_new_URI );
?>
<div class="aDBc-text-status-db">
<b><a href="<?php echo esc_url( $aDBc_new_URI ); ?>"><?php echo $this->aDBc_total_tables_to_optimize; ?></a></b>
<?php _e( 'table(s) should be optimized!', 'advanced-database-cleaner' ); ?>
</div>
<div>
<?php
$aDBc_table_size = aDBc_get_size_from_bytes( $this->aDBc_total_lost );
echo __( 'You can save around', 'advanced-database-cleaner' ) . " : " . $aDBc_table_size;
?>
</div>
<?php
}
if ( $this->aDBc_total_tables_to_repair > 0 ) {
$aDBc_new_URI = add_query_arg( 't_type', 'repair', $aDBc_new_URI );
$to_repair_css = $this->aDBc_total_tables_to_optimize > 0 ? "aDBc-to-repair-section" : "";
?>
<div class="aDBc-text-status-db <?php echo $to_repair_css; ?>">
<b><a href="<?php echo esc_url( $aDBc_new_URI ); ?>"><?php echo $this->aDBc_total_tables_to_repair; ?></a></b>
<?php _e( 'table(s) should be repaired!', 'advanced-database-cleaner' ); ?>
</div>
<?php
}
}
?>
</div>
<div class="aDBc-right-box-content">
<div style="text-align:center">
<img width="60px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/alarm-clock.svg'?>"/>
<?php
$aDBc_schedules = get_option( 'aDBc_optimize_schedule' );
$aDBc_schedules = is_array( $aDBc_schedules ) ? $aDBc_schedules : array();
// Count schedules available
$count_schedules = count( $aDBc_schedules );
echo "<div class='aDBc-schedule-text'><b>" . $count_schedules ."</b> " .__('optimize schedule(s) set','advanced-database-cleaner') . "</div>";
?>
</div>
<?php
foreach ( $aDBc_schedules as $hook_name => $hook_params ) {
echo "<div class='aDBc-schedule-hook-box'>";
echo "<b>" . __( 'Name', 'advanced-database-cleaner' ) . "</b> : " . $hook_name;
echo "</br>";
// We convert hook name to a string because the arg maybe only a digit!
$timestamp = wp_next_scheduled( "aDBc_optimize_scheduler", array( $hook_name . '' ) );
if($timestamp){
$next_run = get_date_from_gmt(date('Y-m-d H:i:s', (int) $timestamp), 'M j, Y - H:i');
}else{
$next_run = "---";
}
echo "<b>".__('Next run','advanced-database-cleaner') . "</b> : " . $next_run . "</br>";
$operation1 = in_array('optimize', $hook_params['operations']) ? __('Optimize','advanced-database-cleaner') : '';
$operation2 = in_array('repair', $hook_params['operations']) ? __('Repair','advanced-database-cleaner') : '';
$plus = !empty($operation1) && !empty($operation2) ? " + " : "";
echo "<b>".__('Perform','advanced-database-cleaner') . "</b> : " . $operation1 . $plus . $operation2 . "</br>";
$repeat = $hook_params['repeat'];
switch($repeat){
case "once" :
$repeat = __('Once','advanced-database-cleaner');
break;
case "hourly" :
$repeat = __('Hourly','advanced-database-cleaner');
break;
case "twicedaily" :
$repeat = __('Twice a day','advanced-database-cleaner');
break;
case "daily" :
$repeat = __('Daily','advanced-database-cleaner');
break;
case "weekly" :
$repeat = __('Weekly','advanced-database-cleaner');
break;
case "monthly" :
$repeat = __('Monthly','advanced-database-cleaner');
break;
}
echo "<b>".__('Frequency','advanced-database-cleaner') . "</b> : " . $repeat . "</br>";
echo $hook_params['active'] == "1" ? "<img class='aDBc-schedule-on-off' src='". ADBC_PLUGIN_DIR_PATH . "/images/switch-on.svg" . "'/>" : "<img class='aDBc-schedule-on-off' src='". ADBC_PLUGIN_DIR_PATH . "/images/switch-off.svg" . "'/>";
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = add_query_arg('aDBc_view', 'edit_optimize_schedule', $aDBc_new_URI);
$aDBc_new_URI = add_query_arg('hook_name', $hook_name, $aDBc_new_URI);
?>
<span class="aDBc-edit-delete-schedule">
<a href="<?php echo esc_url( $aDBc_new_URI ); ?>" class="aDBc-edit-schedule-link">
<?php _e( 'Edit', 'advanced-database-cleaner' ); ?>
</a>
|
<form action="" method="post" class="aDBc-delete-schedule-link">
<input type="hidden" name="aDBc_delete_schedule" value="<?php echo $hook_name ?>" />
<input class="aDBc-submit-link" type="submit" value="<?php _e('Delete','advanced-database-cleaner') ?>" />
<?php wp_nonce_field('delete_optimize_schedule_nonce', 'delete_optimize_schedule_nonce') ?>
</form>
</span>
</div>
<?php
}
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = add_query_arg('aDBc_view', 'add_optimize_schedule', $aDBc_new_URI);
?>
<a href="<?php echo esc_url( $aDBc_new_URI ); ?>" id="aDBc_add_schedule" class="button-primary aDBc-add-new-schedule">
<?php _e('Add new schedule','advanced-database-cleaner'); ?>
</a>
</div>
</div>
<div class="aDBc-clear-both"></div>
<?php
}
?>
</div>
<?php
}
}
new ADBC_Tables_List();
?>

View File

@@ -0,0 +1,453 @@
<?php
// Style ok, code not yet
class ADBC_Clean_DB_List extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_total_elements_to_clean = 0;
/**
* Constructor
*/
function __construct(){
parent::__construct(array(
'singular' => __('Element', 'advanced-database-cleaner'), //singular name of the listed records
'plural' => __('Elements', 'advanced-database-cleaner'), //plural name of the listed records
'ajax' => false //does this table support ajax?
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean(){
// Test if user wants to delete a scheduled task
if(isset($_POST['aDBc_delete_schedule'])){
//Quick nonce security check!
if(!check_admin_referer('delete_cleanup_schedule_nonce', 'delete_cleanup_schedule_nonce'))
return; //get out if we didn't click the delete link
// We delete the schedule
$aDBc_sanitized_schedule_name = sanitize_html_class($_POST['aDBc_delete_schedule']);
wp_clear_scheduled_hook('aDBc_clean_scheduler', array($aDBc_sanitized_schedule_name));
// We delete the item from database
$aDBc_schedules = get_option('aDBc_clean_schedule');
unset($aDBc_schedules[$aDBc_sanitized_schedule_name]);
update_option('aDBc_clean_schedule', $aDBc_schedules, "no");
$this->aDBc_message = __('The clean-up schedule deleted successfully!', 'advanced-database-cleaner');
}
// Test if user wants to edit keep_last column for an item
if(isset($_POST['aDBc_keep_input'])){
// Security check - verify nonce
if(!check_admin_referer('aDBc_keep_last_nonce', 'aDBc_keep_last_nonce'))
return; //get out if nonce verification fails
$sanitized_keep_input = sanitize_html_class($_POST['aDBc_keep_input']);
$sanitized_item_keep_to_edit = sanitize_html_class($_POST['aDBc_item_keep_to_edit']);
$settings = get_option('aDBc_settings');
if(empty($settings['keep_last'])){
$keep_value = array($sanitized_item_keep_to_edit => intval($sanitized_keep_input));
}else{
$keep_value = $settings['keep_last'];
$keep_value[$sanitized_item_keep_to_edit] = intval($sanitized_keep_input);
}
$settings['keep_last'] = $keep_value;
update_option('aDBc_settings', $settings, "no");
// Test if the items belongs to a scheduled task. If so, show msg differently
$aDBc_schedules = get_option('aDBc_clean_schedule');
$aDBc_schedules = is_array($aDBc_schedules) ? $aDBc_schedules : array();
$msg_keep_last = __("The 'keep last' value saved successfully!", "advanced-database-cleaner");
foreach($aDBc_schedules as $hook_name => $hook_params){
$lits_of_elements = $hook_params['elements_to_clean'];
if(in_array($sanitized_item_keep_to_edit, $lits_of_elements)){
$msg_keep_last = __("The 'keep last' value saved successfully!", "advanced-database-cleaner") . " <span style='color:orange'>" . __("Please keep in mind that this will change the value of 'keep last' of your corresponding scheduled tasks as well!", "advanced-database-cleaner") . "</span>";
break;
}
}
$this->aDBc_message = $msg_keep_last;
}
// Process bulk action if any before preparing elements to clean
$this->process_bulk_action();
// Get all unused elements
$aDBc_unused_elements = aDBc_count_all_elements_to_clean();
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
// Get settings from DB
$settings = get_option('aDBc_settings');
$aDBc_schedules = get_option('aDBc_clean_schedule');
$aDBc_schedules = is_array($aDBc_schedules) ? $aDBc_schedules : array();
foreach($aDBc_unused_elements as $element_type => $element_info){
// Count total unused elements
$this->aDBc_total_elements_to_clean += $element_info['count'];
// If the item is scheduled, show green image, otherwise show grey one. Select also the text to show next green image
$scheduled_img_name = "grey_clock.svg";
$item_scheduled_in = "";
foreach($aDBc_schedules as $hook_name => $hook_params){
$lits_of_elements = $hook_params['elements_to_clean'];
if(in_array ($element_type, $lits_of_elements)){
$scheduled_img_name = "green_clock.svg";
$item_scheduled_in .= "<div class='aDBc-scheduled-in-row'>" . $hook_name . "</div>";
}
}
if(empty($item_scheduled_in)){
$aDBc_scheduled = "<img style='width:17px' alt='-' src='".ADBC_PLUGIN_DIR_PATH . "/images/" . $scheduled_img_name . "'/>";
}else{
$aDBc_scheduled = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' style='width:17px' alt='-' src='".ADBC_PLUGIN_DIR_PATH . "/images/" . $scheduled_img_name . "'/><span style='width:190px'>" . __('Scheduled in:','advanced-database-cleaner') . $item_scheduled_in . "</span></span>";
}
if($element_info['count'] > 0){
$color = "red";
$aDBc_count = "<font color='$color' style='font-weight:bold'>" . $element_info['count'] . "</font>";
$aDBc_new_URI = add_query_arg('aDBc_view', $element_type, $aDBc_new_URI);
$aDBc_see = "<a href='" . esc_url( $aDBc_new_URI ) . "'><img width='20px' alt='view' src='".ADBC_PLUGIN_DIR_PATH . '/images/see.svg'."'/></a>";
}else{
$aDBc_count = "<font color='#ccc' style='font-weight:bold'>0</font>";
$aDBc_see = "<img width='20px' alt='-' src='".ADBC_PLUGIN_DIR_PATH . '/images/nothing_to_see.svg'."'/>";
}
// Get "keep_last" option. This option is added in ADBC version 3.0, so test if it is not empty before using it
if(empty($settings['keep_last'])){
$keep_number = '0';
}else{
$keep_setting = $settings['keep_last'];
if(empty($keep_setting[$element_type])){
$keep_number = '0';
}else{
$keep_number = $keep_setting[$element_type];
}
}
// If the item can have keep_last, then prepare it, otherwise echo N/A
if($element_type == "revision" ||
$element_type == "auto-draft" ||
$element_type == "trash-posts" ||
$element_type == "moderated-comments" ||
$element_type == "spam-comments" ||
$element_type == "trash-comments" ||
$element_type == "pingbacks" ||
$element_type == "trackbacks"){
$save_button = __('Save','advanced-database-cleaner');
$keep_info = "<span id='aDBc_keep_label_$element_type'>" . $keep_number . " " . __('days','advanced-database-cleaner') . " | </span>" . "<a id='aDBc_edit_keep_$element_type' class='aDBc-keep-link'>" . __("Edit", "advanced-database-cleaner") . "</a>";
$keep_info .= "<form action='' method='post'>
<input type='hidden' name='aDBc_item_keep_to_edit' value='$element_type'>
<input id='aDBc_keep_input_$element_type' class='aDBc-keep-input' name='aDBc_keep_input' value='$keep_number'/>
<input id='aDBc_keep_button_$element_type' class='aDBc-keep-button button-primary' type='submit' value='$save_button' style='display:none'/>
<a id='aDBc_keep_cancel_$element_type' class='aDBc-keep-cancel-link'> " . __('Cancel','advanced-database-cleaner') . "</a>";
$keep_info .= wp_nonce_field('aDBc_keep_last_nonce', 'aDBc_keep_last_nonce', true, false);
$keep_info .= "</form>";
}else{
$keep_info = __('N/A','advanced-database-cleaner') ;
}
if($element_type == "revision"){
}else if($element_type == "revision"){
$keep_info = __('N/A','advanced-database-cleaner') ;
}
array_push($this->aDBc_elements_to_display, array(
'element_to_clean' => "<a href='". $element_info['URL_blog'] ."' target='_blank' class='aDBc-info-icon'>&nbsp;</a>" . $element_info['name'],
'count' => $aDBc_count,
'view' => $aDBc_see,
'scheduled' => $aDBc_scheduled,
'keep' => $keep_info,
'type' => $element_type
)
);
}
// Call WP prepare_items function
$this->prepare_items();
}
/** WP: Get columns */
function get_columns() {
$aDBc_scheduled_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __('Indicates if you have selected the item to be cleaned automatically on a scheduled task. A green image indicates that the item is scheduled while a grey image indicated the opposite.','advanced-database-cleaner') ." </span>
</span>";
$aDBc_keep_last_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __('Keep the last x days data from being displayed, and therefore from being cleaned. The plugin will always show only data older than the number of days you have specified.','advanced-database-cleaner') ." </span>
</span>";
$columns = array(
'cb' => '<input type="checkbox" />',
'element_to_clean' => __('Elements to clean','advanced-database-cleaner'),
'count' => __('Count','advanced-database-cleaner'),
'view' => __('View','advanced-database-cleaner'),
'scheduled' => __('Scheduled','advanced-database-cleaner') . $aDBc_scheduled_toolip,
'keep' => __('Keep last','advanced-database-cleaner') . $aDBc_keep_last_toolip,
'type' => 'Type'
);
return $columns;
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = array();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice($this->aDBc_elements_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_elements_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
return array('type');
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'element_to_clean':
case 'count':
case 'view':
case 'scheduled':
case 'keep':
case 'type':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Column cb for check box */
function column_cb($item) {
return sprintf('<input id="checkbox_%s" type="checkbox" name="aDBc_elements_to_process[]" value="%s" />', $item['type'], $item['type']);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'clean' => __('Clean','advanced-database-cleaner')
);
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('Your database is clean!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'clean' ) {
// If the user wants to clean the elements he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
// Create an array containing allowed elements_types to clean for security
$aDBc_allowed_types = array("revision", "auto-draft", "trash-posts", "moderated-comments", "spam-comments", "trash-comments", "pingbacks", "trackbacks", "orphan-postmeta", "orphan-commentmeta", "orphan-relationships", "orphan-usermeta", "orphan-termmeta", "expired-transients");
foreach($_POST['aDBc_elements_to_process'] as $element){
$aDBc_sanitized_element = sanitize_html_class($element);
if(in_array($aDBc_sanitized_element, $aDBc_allowed_types)){
aDBc_clean_all_elements_type($aDBc_sanitized_element);
}
}
// Update the message to show to the user
$this->aDBc_message = __('Selected elements successfully cleaned!', 'advanced-database-cleaner');
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
// Print a message if any
if($this->aDBc_message != ""){
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
?>
<div class="aDBc-content-max-width">
<div class="aDBc-left-content">
<form id="aDBc_form" action="" method="post">
<?php
// Print the elements to clean
$this->display();
?>
</form>
</div>
<div class="aDBc-right-box">
<div class="aDBc-right-box-content" style="text-align:center">
<?php
if ( $this->aDBc_total_elements_to_clean == 0 ) {
?>
<img width="58px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/db_clean.svg'?>"/>
<div class="aDBc-text-status-db"><?php _e( 'Your database is clean!', 'advanced-database-cleaner' ); ?></div>
<?php
} else {
?>
<img width="55px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/warning.svg'?>"/>
<div class="aDBc-text-status-db">
<b><?php echo $this->aDBc_total_elements_to_clean; ?></b> <?php _e('Element(s) can be cleaned!','advanced-database-cleaner'); ?>
</div>
<?php
}
?>
</div>
<div class="aDBc-right-box-content">
<div style="text-align:center">
<img width="60px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/alarm-clock.svg'?>"/>
<?php
$aDBc_schedules = get_option( 'aDBc_clean_schedule' );
$aDBc_schedules = is_array( $aDBc_schedules ) ? $aDBc_schedules : array();
// Count schedules available
$count_schedules = count( $aDBc_schedules );
echo "<div class='aDBc-schedule-text'><b>" . $count_schedules ."</b> " .__('Cleanup schedule(s) set','advanced-database-cleaner') . "</div>";
?>
</div>
<?php
foreach ( $aDBc_schedules as $hook_name => $hook_params ) {
echo "<div class='aDBc-schedule-hook-box'>";
echo "<b>" . __( 'Name', 'advanced-database-cleaner' ) . "</b> : " . $hook_name;
echo "</br>";
// We convert hook name to a string because the arg maybe only a digit!
$timestamp = wp_next_scheduled( "aDBc_clean_scheduler", array( $hook_name . '' ) );
if($timestamp){
$next_run = get_date_from_gmt(date('Y-m-d H:i:s', (int) $timestamp), 'M j, Y - H:i');
}else{
$next_run = "---";
}
echo "<b>".__('Next run','advanced-database-cleaner') . "</b> : " . $next_run . "</br>";
$repeat = $hook_params['repeat'];
switch($repeat){
case "once" :
$repeat = __('Once','advanced-database-cleaner');
break;
case "hourly" :
$repeat = __('Hourly','advanced-database-cleaner');
break;
case "twicedaily" :
$repeat = __('Twice a day','advanced-database-cleaner');
break;
case "daily" :
$repeat = __('Daily','advanced-database-cleaner');
break;
case "weekly" :
$repeat = __('Weekly','advanced-database-cleaner');
break;
case "monthly" :
$repeat = __('Monthly','advanced-database-cleaner');
break;
}
echo "<b>".__('Frequency','advanced-database-cleaner') . "</b> : " . $repeat . "</br>";
echo "<b>".__('Items to clean','advanced-database-cleaner') . " : </b>" . count($hook_params['elements_to_clean'])."</br>";
echo $hook_params['active'] == "1" ? "<img class='aDBc-schedule-on-off' src='". ADBC_PLUGIN_DIR_PATH . "/images/switch-on.svg" . "'/>" : "<img class='aDBc-schedule-on-off' src='". ADBC_PLUGIN_DIR_PATH . "/images/switch-off.svg" . "'/>";
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = add_query_arg('aDBc_view', 'edit_cleanup_schedule', $aDBc_new_URI);
$aDBc_new_URI = add_query_arg('hook_name', $hook_name, $aDBc_new_URI);
?>
<span class="aDBc-edit-delete-schedule">
<a href="<?php echo esc_url( $aDBc_new_URI ) ?>" class="aDBc-edit-schedule-link">
<?php _e( 'Edit', 'advanced-database-cleaner' ); ?>
</a>
|
<form action="" method="post" class="aDBc-delete-schedule-link">
<input type="hidden" name="aDBc_delete_schedule" value="<?php echo $hook_name ?>" />
<input class="aDBc-submit-link" type="submit" value="<?php _e('Delete','advanced-database-cleaner') ?>" />
<?php wp_nonce_field('delete_cleanup_schedule_nonce', 'delete_cleanup_schedule_nonce') ?>
</form>
</span>
</div>
<?php
}
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = add_query_arg('aDBc_view', 'add_cleanup_schedule', $aDBc_new_URI);
?>
<a href="<?php echo esc_url( $aDBc_new_URI ) ?>" id="aDBc_add_schedule" class="button-primary aDBc-add-new-schedule">
<?php _e('Add new schedule','advanced-database-cleaner'); ?>
</a>
</div>
</div>
<div class="aDBc-clear-both"></div>
</div>
<?php
}
}
new ADBC_Clean_DB_List();
?>

View File

@@ -0,0 +1,67 @@
<?php
if ( isset( $_GET['aDBc_view'] ) ) {
// If the user wants to perform custom cleaning
if ( $_GET['aDBc_view'] == "revision" ||
$_GET['aDBc_view'] == "auto-draft" ||
$_GET['aDBc_view'] == "trash-posts" ) {
include_once 'custom-clean-view/class_clean_revision_draft_trash.php';
new ADBC_Clean_Revision_Trash_Draft( $_GET['aDBc_view'] );
} else if ( $_GET['aDBc_view'] == "moderated-comments" ||
$_GET['aDBc_view'] == "spam-comments" ||
$_GET['aDBc_view'] == "trash-comments" ||
$_GET['aDBc_view'] == "pingbacks" ||
$_GET['aDBc_view'] == "trackbacks" ) {
include_once 'custom-clean-view/class_clean_comment.php';
new ADBC_Clean_Comment( $_GET['aDBc_view'] );
} else if ( $_GET['aDBc_view'] == "orphan-postmeta" ||
$_GET['aDBc_view'] == "orphan-commentmeta" ||
$_GET['aDBc_view'] == "orphan-usermeta" ||
$_GET['aDBc_view'] == "orphan-termmeta" ) {
include_once 'custom-clean-view/class_clean_meta_comment_post_user_term.php';
new ADBC_Clean_Meta_Comment_Post_User_Term( $_GET['aDBc_view'] );
} else if ( $_GET['aDBc_view'] == "orphan-relationships" ) {
include_once 'custom-clean-view/class_clean_relationships.php';
new ADBC_Clean_Relationship();
} else if ( $_GET['aDBc_view'] == "expired-transients" ) {
include_once 'custom-clean-view/class_clean_transient.php';
new ADBC_Clean_Transient( $_GET['aDBc_view'] );
} else if ( $_GET['aDBc_view'] == "add_cleanup_schedule" ) {
include_once 'custom-schedule-view/class_add_cleanup_schedule.php';
new ADBC_SCHEDULE_CLEANUP( $_GET['aDBc_view'] );
} else if ( $_GET['aDBc_view'] == "edit_cleanup_schedule" ) {
include_once 'custom-schedule-view/class_edit_cleanup_schedule.php';
new EDIT_SCHEDULE_CLEANUP($_GET['aDBc_view']);
}
} else {
// Else, return the general clean-up page
include_once 'class_general_cleanup.php';
}
?>

View File

@@ -0,0 +1,322 @@
<?php
/** Used to view Pending comments, Spam Comments, Trash comments, Pingbacks and Trackbacks */
class ADBC_Clean_Comment extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_type_to_clean = "";
private $aDBc_plural_title = "";
private $aDBc_column_comment_name = "";
private $aDBc_sql_get_elements = "";
private $aDBc_custom_sql_args = "";
private $aDBc_search_sql_arg = "";
private $aDBc_order_by_sql_arg = "";
private $aDBc_limit_offset_sql_arg = "";
private $aDBc_keep_last_sql_arg = "";
/**
* Constructor
*/
function __construct($element_type){
if($element_type == "moderated-comments"){
$this->aDBc_type_to_clean = "0";
$aDBc_singular = __('Pending comment', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Pending comments', 'advanced-database-cleaner');
$this->aDBc_column_comment_name = __('Comment content', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " comment_approved = '0'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('moderated-comments');
}else if($element_type == "spam-comments"){
$this->aDBc_type_to_clean = "spam";
$aDBc_singular = __('Spam comment', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Spam comments', 'advanced-database-cleaner');
$this->aDBc_column_comment_name = __('Comment content', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " comment_approved = 'spam'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('spam-comments');
}else if($element_type == "trash-comments"){
$this->aDBc_type_to_clean = "trash";
$aDBc_singular = __('Trash comment', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Trash comments', 'advanced-database-cleaner');
$this->aDBc_column_comment_name = __('Comment content', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " comment_approved = 'trash'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('trash-comments');
}else if($element_type == "pingbacks"){
$this->aDBc_type_to_clean = "pingback";
$aDBc_singular = __('Pingback', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Pingbacks', 'advanced-database-cleaner');
$this->aDBc_column_comment_name = __('Pingback content', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " comment_type = 'pingback'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('pingbacks');
}else if($element_type == "trackbacks"){
$this->aDBc_type_to_clean = "trackback";
$aDBc_singular = __('Trackback', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Trackbacks', 'advanced-database-cleaner');
$this->aDBc_column_comment_name = __('Trackback content', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " comment_type = 'trackback'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('trackbacks');
}
// Prepare additional sql args if any: per page, LIMIT, OFFSET, etc.
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$this->aDBc_search_sql_arg = aDBc_get_search_sql_arg( "comment_author", "comment_content" );
}
$this->aDBc_order_by_sql_arg = aDBc_get_order_by_sql_arg( "comment_ID" );
$this->aDBc_limit_offset_sql_arg = aDBc_get_limit_offset_sql_args();
parent::__construct(array(
'singular' => $aDBc_singular,
'plural' => $this->aDBc_plural_title,
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean(){
global $wpdb;
// Process bulk action if any before preparing elements to clean
$this->process_bulk_action();
// Get all elements to clean
if(function_exists('is_multisite') && is_multisite()){
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
$this->aDBc_fill_array_elements_to_clean($blog_id);
restore_current_blog();
}
}else{
$this->aDBc_fill_array_elements_to_clean("1");
}
// Call WP prepare_items function
$this->prepare_items();
}
/** Fill array elements to display */
function aDBc_fill_array_elements_to_clean($blog_id){
global $wpdb;
// Get all elements query
$this->aDBc_sql_get_elements = "SELECT comment_ID, comment_author, comment_content, comment_date FROM $wpdb->comments WHERE"
. $this->aDBc_custom_sql_args
. $this->aDBc_keep_last_sql_arg
. $this->aDBc_search_sql_arg
. $this->aDBc_order_by_sql_arg
//. $this->aDBc_limit_offset_sql_arg
;
$aDBc_all_elements = $wpdb->get_results($this->aDBc_sql_get_elements);
foreach($aDBc_all_elements as $aDBc_element){
// Get author name
$author_name = aDBc_create_tooltip_for_long_string($aDBc_element->comment_author, 16);
// Get comment content
$comment_content = aDBc_create_tooltip_for_long_string($aDBc_element->comment_content, 60);
array_push($this->aDBc_elements_to_display, array(
'comment_id' => $aDBc_element->comment_ID,
'comment_author' => $author_name,
'comment_content' => $comment_content,
'comment_date' => $aDBc_element->comment_date,
'site_id' => $blog_id
)
);
}
}
/** Prepare keep_last element if any **/
function aDBc_get_keep_last_sql_arg($element_type){
$settings = get_option('aDBc_settings');
if(!empty($settings['keep_last'])){
$keep_setting = $settings['keep_last'];
if(!empty($keep_setting[$element_type]))
return " and comment_date < NOW() - INTERVAL " . $keep_setting[$element_type] . " DAY";
}
return "";
}
/** WP: Get columns */
function get_columns(){
$columns = array(
'cb' => '<input type="checkbox" />',
'comment_id' => __('ID','advanced-database-cleaner'),
'comment_author' => __('Author','advanced-database-cleaner'),
'comment_content' => $this->aDBc_column_comment_name,
'comment_date' => __('Date','advanced-database-cleaner'),
'site_id' => __('Site id','advanced-database-cleaner')
);
return $columns;
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'comment_id':
case 'comment_author':
case 'comment_content':
case 'comment_date':
case 'site_id':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
function get_sortable_columns() {
$sortable_columns = array(
'comment_id' => array('comment_ID',false),
'comment_author' => array('comment_author',false)
);
// Since order_by works directly with sql request, we will not order_by in mutlisite since it will not work
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return $sortable_columns;
}
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice($this->aDBc_elements_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_elements_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Column cb for check box */
function column_cb($item) {
return sprintf('<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />', $item['site_id']."|".$item['comment_id']);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'clean' => __('Clean','advanced-database-cleaner')
);
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('No elements found!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'clean' ) {
// If the user wants to clean the elements he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare elements to delete
$elements_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $element){
$element_info = explode("|", $element);
$sanitized_site_id = sanitize_html_class($element_info[0]);
$sanitized_item_id = sanitize_html_class($element_info[1]);
// For security, we only proceed if both parts are clean and are numbers
if(is_numeric($sanitized_site_id) && is_numeric($sanitized_item_id)){
if(empty($elements_to_delete[$sanitized_site_id])){
$elements_to_delete[$sanitized_site_id] = array();
}
array_push($elements_to_delete[$sanitized_site_id], $sanitized_item_id);
}
}
// Delete elements
foreach($elements_to_delete as $site_id => $elements_ids){
switch_to_blog($site_id);
global $wpdb;
foreach($elements_ids as $id_comment) {
$wpdb->query("DELETE FROM $wpdb->comments WHERE comment_ID = $id_comment");
}
restore_current_blog();
}
}else{
global $wpdb;
foreach($_POST['aDBc_elements_to_process'] as $element) {
$element_info = explode("|", $element);
$sanitized_id = sanitize_html_class($element_info[1]);
if(is_numeric($sanitized_id)){
$wpdb->query("DELETE FROM $wpdb->comments WHERE comment_ID = " . $sanitized_id);
}
}
}
// Update the message to show to the user
$this->aDBc_message = __("Selected '$this->aDBc_plural_title' successfully cleaned!", 'advanced-database-cleaner');
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
include_once 'page_custom_clean.php';
}
}
?>

View File

@@ -0,0 +1,311 @@
<?php
/** View comment meta and post meta */
class ADBC_Clean_Meta_Comment_Post_User_Term extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_type_to_clean = "";
private $aDBc_plural_title = "";
private $aDBc_column_meta_name = "";
private $aDBc_sql_get_elements = "";
private $aDBc_custom_sql_args = "";
private $aDBc_search_sql_arg = "";
private $aDBc_order_by_sql_arg = "";
private $aDBc_limit_offset_sql_arg = "";
private $aDBc_delete_from_table = "";
private $aDBc_metaid_or_umetaid = "";
/**
* Constructor
*/
function __construct($element_type){
if($element_type == "orphan-commentmeta"){
$this->aDBc_type_to_clean = "orphan-commentmeta";
$aDBc_singular = __('Orphaned comment meta', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Orphaned comments meta', 'advanced-database-cleaner');
$this->aDBc_column_meta_name = __('Comment meta key', 'advanced-database-cleaner');
$this->aDBc_delete_from_table = "commentmeta";
$this->aDBc_metaid_or_umetaid = "meta_id";
}else if($element_type == "orphan-postmeta"){
$this->aDBc_type_to_clean = "orphan-postmeta";
$aDBc_singular = __('Orphaned post meta', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Orphaned posts meta', 'advanced-database-cleaner');
$this->aDBc_column_meta_name = __('Post meta key', 'advanced-database-cleaner');
$this->aDBc_delete_from_table = "postmeta";
$this->aDBc_metaid_or_umetaid = "meta_id";
}else if($element_type == "orphan-usermeta"){
$this->aDBc_type_to_clean = "orphan-usermeta";
$aDBc_singular = __('Orphaned User Meta', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Orphaned Users Meta', 'advanced-database-cleaner');
$this->aDBc_column_meta_name = __('User meta key', 'advanced-database-cleaner');
$this->aDBc_delete_from_table = "usermeta";
$this->aDBc_metaid_or_umetaid = "umeta_id";
}else if($element_type == "orphan-termmeta"){
$this->aDBc_type_to_clean = "orphan-termmeta";
$aDBc_singular = __('Orphaned Term Meta', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Orphaned Terms Meta', 'advanced-database-cleaner');
$this->aDBc_column_meta_name = __('Term meta key', 'advanced-database-cleaner');
$this->aDBc_delete_from_table = "termmeta";
$this->aDBc_metaid_or_umetaid = "meta_id";
}
// Prepare additional sql args if any: per page, LIMIT, OFFSET, etc.
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$this->aDBc_search_sql_arg = aDBc_get_search_sql_arg( "meta_key", "meta_value" );
}
$this->aDBc_order_by_sql_arg = aDBc_get_order_by_sql_arg( $this->aDBc_metaid_or_umetaid );
$this->aDBc_limit_offset_sql_arg = aDBc_get_limit_offset_sql_args();
parent::__construct(array(
'singular' => $aDBc_singular,
'plural' => $this->aDBc_plural_title,
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean(){
global $wpdb;
// Process bulk action if any before preparing elements to clean
$this->process_bulk_action();
// Get all elements (for the table usermeta, only one table exists for MU, do not switch over blogs for it)
if(function_exists('is_multisite') && is_multisite() && $this->aDBc_type_to_clean != "orphan-usermeta"){
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
$this->aDBc_fill_array_elements_to_clean($blog_id);
restore_current_blog();
}
}else{
$this->aDBc_fill_array_elements_to_clean("1");
}
// Call WP prepare_items function
$this->prepare_items();
}
/** Fill array elements to display */
function aDBc_fill_array_elements_to_clean($blog_id){
global $wpdb;
if($this->aDBc_type_to_clean == "orphan-commentmeta"){
$this->aDBc_custom_sql_args = "SELECT meta_id, meta_key, meta_value FROM $wpdb->commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM $wpdb->comments)";
}else if($this->aDBc_type_to_clean == "orphan-postmeta"){
$this->aDBc_custom_sql_args = "SELECT meta_id, meta_key, meta_value FROM $wpdb->postmeta pm LEFT JOIN $wpdb->posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL";
}else if($this->aDBc_type_to_clean == "orphan-usermeta"){
$this->aDBc_custom_sql_args = "SELECT umeta_id, meta_key, meta_value FROM $wpdb->usermeta WHERE user_id NOT IN (SELECT ID FROM $wpdb->users)";
}else if($this->aDBc_type_to_clean == "orphan-termmeta"){
$this->aDBc_custom_sql_args = "SELECT meta_id, meta_key, meta_value FROM $wpdb->termmeta WHERE term_id NOT IN (SELECT term_id FROM $wpdb->terms)";
}
// Get all elements query
$this->aDBc_sql_get_elements = $this->aDBc_custom_sql_args
. $this->aDBc_search_sql_arg
. $this->aDBc_order_by_sql_arg
//. $this->aDBc_limit_offset_sql_arg
;
$aDBc_all_elements = $wpdb->get_results($this->aDBc_sql_get_elements);
foreach($aDBc_all_elements as $aDBc_element){
// Get meta key
$meta_key = aDBc_create_tooltip_for_long_string($aDBc_element->meta_key, 28);
// Get meta value
$meta_value = aDBc_create_tooltip_for_long_string($aDBc_element->meta_value, 95);
array_push($this->aDBc_elements_to_display, array(
'meta_id' => ($this->aDBc_metaid_or_umetaid == 'meta_id' ? $aDBc_element->meta_id : $aDBc_element->umeta_id),
'meta_key' => $meta_key,
'meta_value' => $meta_value,
'site_id' => $blog_id
)
);
}
}
/** WP: Get columns */
function get_columns(){
$columns = array(
'cb' => '<input type="checkbox" />',
'meta_id' => __('ID','advanced-database-cleaner'),
'meta_key' => $this->aDBc_column_meta_name,
'meta_value' => __('Meta value','advanced-database-cleaner'),
'site_id' => __('Site id','advanced-database-cleaner')
);
return $columns;
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'meta_id':
case 'meta_key':
case 'meta_value':
case 'site_id':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
function get_sortable_columns() {
$sortable_columns = array(
'meta_id' => array($this->aDBc_metaid_or_umetaid, false),
'meta_key' => array('meta_key', false)
);
// Since order_by works directly with sql request, we will not order_by in mutlisite since it will not work
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return $sortable_columns;
}
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice($this->aDBc_elements_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_elements_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Column cb for check box */
function column_cb($item) {
return sprintf('<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />', $item['site_id']."|".$item['meta_id']);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'clean' => __('Clean','advanced-database-cleaner')
);
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('No elements found!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'clean' ) {
// If the user wants to clean the elements he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare meta to delete
$meta_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $meta){
$meta_info = explode("|", $meta);
$sanitized_site_id = sanitize_html_class($meta_info[0]);
$sanitized_item_id = sanitize_html_class($meta_info[1]);
// For security, we only proceed if both parts are clean and are numbers
if(is_numeric($sanitized_site_id) && is_numeric($sanitized_item_id)){
if(empty($meta_to_delete[$sanitized_site_id])){
$meta_to_delete[$sanitized_site_id] = array();
}
array_push($meta_to_delete[$sanitized_site_id], $sanitized_item_id);
}
}
// Delete meta
foreach($meta_to_delete as $site_id => $meta_ids){
switch_to_blog($site_id);
global $wpdb;
foreach($meta_ids as $id_meta) {
$table_name = $wpdb->prefix . $this->aDBc_delete_from_table;
$wpdb->query("DELETE FROM $table_name WHERE $this->aDBc_metaid_or_umetaid = $id_meta");
}
restore_current_blog();
}
}else{
global $wpdb;
$table_name = $wpdb->prefix . $this->aDBc_delete_from_table;
foreach($_POST['aDBc_elements_to_process'] as $meta) {
$meta_info = explode("|", $meta);
$sanitized_id = sanitize_html_class($meta_info[1]);
if(is_numeric($sanitized_id)){
$wpdb->query("DELETE FROM $table_name WHERE $this->aDBc_metaid_or_umetaid = " . $sanitized_id);
}
}
}
// Update the message to show to the user
$this->aDBc_message = __("Selected '$this->aDBc_plural_title' successfully cleaned!", "advanced-database-cleaner");
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
include_once 'page_custom_clean.php';
}
}
?>

View File

@@ -0,0 +1,257 @@
<?php
class ADBC_Clean_Relationship extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_type_to_clean = "";
private $aDBc_plural_title = "";
private $aDBc_column_meta_name = "";
private $aDBc_sql_get_elements = "";
private $aDBc_search_sql_arg = "";
private $aDBc_order_by_sql_arg = "";
private $aDBc_limit_offset_sql_arg = "";
private $aDBc_delete_from_table = "";
/**
* Constructor
*/
function __construct(){
$this->aDBc_plural_title = __('Orphaned Relationships', 'advanced-database-cleaner');
// Prepare additional sql args if any: per page, LIMIT, OFFSET, etc.
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$this->aDBc_search_sql_arg = aDBc_get_search_sql_arg( "term_taxonomy_id", "term_order" );
}
$this->aDBc_order_by_sql_arg = aDBc_get_order_by_sql_arg( "object_id" );
$this->aDBc_limit_offset_sql_arg = aDBc_get_limit_offset_sql_args();
parent::__construct(array(
'singular' => __( 'Orphaned Relationship', 'advanced-database-cleaner' ),
'plural' => $this->aDBc_plural_title,
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean(){
global $wpdb;
// Process bulk action if any before preparing elements to clean
$this->process_bulk_action();
// Get all elements to clean
if(function_exists('is_multisite') && is_multisite()){
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
$this->aDBc_fill_array_elements_to_clean($blog_id);
restore_current_blog();
}
}else{
$this->aDBc_fill_array_elements_to_clean("1");
}
// Call WP prepare_items function
$this->prepare_items();
}
/** Fill array elements to display */
function aDBc_fill_array_elements_to_clean($blog_id){
global $wpdb;
// Get all elements query
$this->aDBc_sql_get_elements = "SELECT * from $wpdb->term_relationships WHERE term_taxonomy_id=1 AND object_id NOT IN (SELECT id FROM $wpdb->posts)"
. $this->aDBc_search_sql_arg
. $this->aDBc_order_by_sql_arg
//. $this->aDBc_limit_offset_sql_arg
;
$aDBc_all_elements = $wpdb->get_results($this->aDBc_sql_get_elements);
foreach($aDBc_all_elements as $aDBc_element){
array_push($this->aDBc_elements_to_display, array(
'object_id' => $aDBc_element->object_id,
'term_taxonomy_id' => $aDBc_element->term_taxonomy_id,
'term_order' => $aDBc_element->term_order,
'site_id' => $blog_id
)
);
}
}
/** WP: Get columns */
function get_columns(){
$columns = array(
'cb' => '<input type="checkbox" />',
'object_id' => __('ID','advanced-database-cleaner'),
'term_taxonomy_id' => __('Term taxonomy id','advanced-database-cleaner'),
'term_order' => __('Term order','advanced-database-cleaner'),
'site_id' => __('Site id','advanced-database-cleaner')
);
return $columns;
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'object_id':
case 'term_taxonomy_id':
case 'term_order':
case 'site_id':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
function get_sortable_columns() {
$sortable_columns = array(
'object_id' => array('object_id',false),
'term_taxonomy_id' => array('term_taxonomy_id',false),
'term_order' => array('term_order',false)
);
// Since order_by works directly with sql request, we will not order_by in mutlisite since it will not work
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return $sortable_columns;
}
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice($this->aDBc_elements_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_elements_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Column cb for check box */
function column_cb($item) {
return sprintf('<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />', $item['site_id']."|".$item['object_id']);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'clean' => __('Clean','advanced-database-cleaner')
);
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('No elements found!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'clean' ) {
// If the user wants to clean the elements he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare relationships to delete
$relationships_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $relationship){
$relationship_info = explode("|", $relationship);
$sanitized_site_id = sanitize_html_class($relationship_info[0]);
$sanitized_item_id = sanitize_html_class($relationship_info[1]);
// For security, we only proceed if both parts are clean and are numbers
if(is_numeric($sanitized_site_id) && is_numeric($sanitized_item_id)){
if(empty($relationships_to_delete[$sanitized_site_id])){
$relationships_to_delete[$sanitized_site_id] = array();
}
array_push($relationships_to_delete[$sanitized_site_id], $sanitized_item_id);
}
}
// Delete relationships
foreach($relationships_to_delete as $site_id => $object_ids){
switch_to_blog($site_id);
global $wpdb;
foreach($object_ids as $object_id) {
$wpdb->query("DELETE FROM $wpdb->term_relationships WHERE term_taxonomy_id=1 AND object_id = $object_id");
}
restore_current_blog();
}
}else{
global $wpdb;
foreach($_POST['aDBc_elements_to_process'] as $relationship){
$relationship_info = explode("|", $relationship);
$sanitized_id = sanitize_html_class($relationship_info[1]);
if(is_numeric($sanitized_id)){
$wpdb->query("DELETE FROM $wpdb->term_relationships WHERE term_taxonomy_id=1 AND object_id = " . $sanitized_id);
}
}
}
// Update the message to show to the user
$this->aDBc_message = __("Selected 'Orphaned relationships' successfully cleaned!", "advanced-database-cleaner");
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
include_once 'page_custom_clean.php';
}
}
?>

View File

@@ -0,0 +1,303 @@
<?php
/** Used to view revisions, auto-drafts and trash posts */
class ADBC_Clean_Revision_Trash_Draft extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_type_to_clean = "";
private $aDBc_plural_title = "";
private $aDBc_column_post_name_title = "";
private $aDBc_sql_get_elements = "";
private $aDBc_custom_sql_args = "";
private $aDBc_search_sql_arg = "";
private $aDBc_order_by_sql_arg = "";
private $aDBc_limit_offset_sql_arg = "";
private $aDBc_keep_last_sql_arg = "";
/**
* Constructor
*/
function __construct($element_type){
if($element_type == "auto-draft"){
$this->aDBc_type_to_clean = "auto-draft";
$aDBc_singular = __('Auto draft', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Auto drafts', 'advanced-database-cleaner');
$this->aDBc_column_post_name_title = __('Auto draft title', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " post_status = 'auto-draft'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('auto-draft');
}else if($element_type == "trash-posts"){
$this->aDBc_type_to_clean = "trash";
$aDBc_singular = __('Trash post', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Trash posts', 'advanced-database-cleaner');
$this->aDBc_column_post_name_title = __('Trash post title', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " post_status = 'trash'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('trash-posts');
}else if($element_type == "revision"){
$this->aDBc_type_to_clean = "revision";
$aDBc_singular = __('Revision', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Revisions', 'advanced-database-cleaner');
$this->aDBc_column_post_name_title = __('Revision title', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " post_type = 'revision'";
$this->aDBc_keep_last_sql_arg = $this->aDBc_get_keep_last_sql_arg('revision');
}
// Prepare additional sql args if any: per page, LIMIT, OFFSET, etc.
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$this->aDBc_search_sql_arg = aDBc_get_search_sql_arg( "post_title", "post_content" );
}
$this->aDBc_order_by_sql_arg = aDBc_get_order_by_sql_arg( "ID" );
$this->aDBc_limit_offset_sql_arg = aDBc_get_limit_offset_sql_args();
parent::__construct(array(
'singular' => $aDBc_singular,
'plural' => $this->aDBc_plural_title,
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean(){
global $wpdb;
// Process bulk action if any before preparing elements to clean
$this->process_bulk_action();
// Get all elements to clean
if(function_exists('is_multisite') && is_multisite()){
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
$this->aDBc_fill_array_elements_to_clean($blog_id);
restore_current_blog();
}
}else{
$this->aDBc_fill_array_elements_to_clean("1");
}
// Call WP prepare_items function
$this->prepare_items();
}
/** Fill array elements to display */
function aDBc_fill_array_elements_to_clean($blog_id){
global $wpdb;
// Get all elements query
$this->aDBc_sql_get_elements = "SELECT ID, post_title, post_date, post_content FROM $wpdb->posts WHERE"
. $this->aDBc_custom_sql_args
. $this->aDBc_keep_last_sql_arg
. $this->aDBc_search_sql_arg
. $this->aDBc_order_by_sql_arg
//. $this->aDBc_limit_offset_sql_arg
;
$aDBc_all_elements = $wpdb->get_results($this->aDBc_sql_get_elements);
foreach($aDBc_all_elements as $aDBc_element){
// Susbstr post title
$post_title = aDBc_create_tooltip_for_long_string($aDBc_element->post_title, 35);
// Get content
$post_content = aDBc_create_tooltip_for_long_string($aDBc_element->post_content, 35);
array_push($this->aDBc_elements_to_display, array(
'post_id' => $aDBc_element->ID,
'post_title' => $post_title,
'post_content' => $post_content, //xxx add if empty, replace by 'Empty' to prevent responsive issues in WP table
'post_date' => $aDBc_element->post_date,
'site_id' => $blog_id
)
);
}
}
/** Prepare keep_last element if any **/
function aDBc_get_keep_last_sql_arg($element_type){
$settings = get_option('aDBc_settings');
if(!empty($settings['keep_last'])){
$keep_setting = $settings['keep_last'];
if(!empty($keep_setting[$element_type]))
return " and post_modified < NOW() - INTERVAL " . $keep_setting[$element_type] . " DAY";
}
return "";
}
/** WP: Get columns */
function get_columns(){
$columns = array(
'cb' => '<input type="checkbox" />',
'post_id' => __('ID','advanced-database-cleaner'),
'post_title' => $this->aDBc_column_post_name_title,
'post_content' => __('Content','advanced-database-cleaner'),
'post_date' => __('Date','advanced-database-cleaner'),
'site_id' => __('Site id','advanced-database-cleaner')
);
return $columns;
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'post_id':
case 'post_title':
case 'post_content':
case 'post_date':
case 'site_id':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
function get_sortable_columns() {
$sortable_columns = array(
'post_id' => array('ID',false), //true means it's already sorted
'post_title' => array('post_title',false),
'post_date' => array('post_date',false)
);
// Since order_by works directly with sql request, we will not order_by in mutlisite since it will not work
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return $sortable_columns;
}
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice($this->aDBc_elements_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_elements_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Column cb for check box */
function column_cb($item) {
return sprintf('<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />', $item['site_id']."|".$item['post_id']);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'clean' => __('Clean','advanced-database-cleaner')
);
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('No elements found!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'clean' ) {
// If the user wants to clean the elements he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare posts to delete
$posts_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $post){
$post_info = explode("|", $post);
$sanitized_site_id = sanitize_html_class($post_info[0]);
$sanitized_item_id = sanitize_html_class($post_info[1]);
// For security, we only proceed if both parts are clean and are numbers
if(is_numeric($sanitized_site_id) && is_numeric($sanitized_item_id)){
if(empty($posts_to_delete[$sanitized_site_id])){
$posts_to_delete[$sanitized_site_id] = array();
}
array_push($posts_to_delete[$sanitized_site_id], $sanitized_item_id);
}
}
// Delete posts
foreach($posts_to_delete as $site_id => $posts_ids){
switch_to_blog($site_id);
global $wpdb;
foreach($posts_ids as $id_post) {
$wpdb->query("DELETE FROM $wpdb->posts WHERE ID = $id_post");
}
restore_current_blog();
}
}else{
global $wpdb;
foreach($_POST['aDBc_elements_to_process'] as $post){
$post_info = explode("|", $post);
$sanitized_id = sanitize_html_class($post_info[1]);
if(is_numeric($sanitized_id)){
$wpdb->query("DELETE FROM $wpdb->posts WHERE ID = " . $sanitized_id);
}
}
}
// Update the message to show to the user
$this->aDBc_message = __("Selected '$this->aDBc_plural_title' successfully cleaned!", "advanced-database-cleaner");
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
include_once 'page_custom_clean.php';
}
}
?>

View File

@@ -0,0 +1,324 @@
<?php
class ADBC_Clean_Transient extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_type_to_clean = "";
private $aDBc_plural_title = "";
private $aDBc_sql_get_transients = "";
private $aDBc_custom_sql_args = "";
private $aDBc_search_sql_arg = "";
private $aDBc_order_by_sql_arg = "";
private $aDBc_limit_offset_sql_arg = "";
/**
* Constructor
*/
function __construct($element_type){
if($element_type == "expired-transients"){
$this->aDBc_type_to_clean = "expired-transients";
$aDBc_singular = __('Expired transient', 'advanced-database-cleaner');
$this->aDBc_plural_title = __('Expired transients', 'advanced-database-cleaner');
$this->aDBc_custom_sql_args = " AND b.option_value < UNIX_TIMESTAMP()";
}
// Prepare additional sql args if any: per page, LIMIT, OFFSET, etc.
if ( ADBC_PLUGIN_PLAN == "pro" ) {
$this->aDBc_search_sql_arg = aDBc_get_search_sql_arg( "a.option_name", "a.option_value" );
}
$this->aDBc_order_by_sql_arg = aDBc_get_order_by_sql_arg( "a.option_id" );
$this->aDBc_limit_offset_sql_arg = aDBc_get_limit_offset_sql_args();
parent::__construct(array(
'singular' => $aDBc_singular,
'plural' => $this->aDBc_plural_title,
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean(){
global $wpdb;
// Process bulk action if any before preparing elements to clean
$this->process_bulk_action();
// Get all elements to clean
if(function_exists('is_multisite') && is_multisite()){
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
$this->aDBc_fill_array_elements_to_clean($blog_id);
restore_current_blog();
}
}else{
$this->aDBc_fill_array_elements_to_clean("1");
}
// Call WP prepare_items function
$this->prepare_items();
}
/** Fill array elements to display */
function aDBc_fill_array_elements_to_clean($blog_id){
global $wpdb;
// Get all dashboard transients
$this->aDBc_sql_get_transients = "SELECT a.option_id, a.option_name, a.option_value as option_content, a.autoload, b.option_value as option_timeout FROM $wpdb->options a LEFT JOIN $wpdb->options b ON b.option_name =
CONCAT(
CASE WHEN a.option_name LIKE '\_site\_transient\_%'
THEN '_site_transient_timeout_'
ELSE '_transient_timeout_'
END
,
SUBSTRING(a.option_name, CHAR_LENGTH(
CASE WHEN a.option_name LIKE '\_site\_transient\_%'
THEN '_site_transient_'
ELSE '_transient_'
END
) + 1)
)
WHERE (a.option_name LIKE '\_transient\_%' OR a.option_name LIKE '\_site\_transient\_%') AND a.option_name NOT LIKE '%\_transient\_timeout\_%'"
. $this->aDBc_custom_sql_args
. $this->aDBc_search_sql_arg
. $this->aDBc_order_by_sql_arg
//. $this->aDBc_limit_offset_sql_arg
;
$time_now = time();
$aDBc_all_transient_feed = $wpdb->get_results($this->aDBc_sql_get_transients);
foreach($aDBc_all_transient_feed as $aDBc_transient){
// Get timeout of transient
switch ( $this->aDBc_type_to_clean ) {
case "expired-transients" :
$transient_timeout = __( 'Expired', 'advanced-database-cleaner' );
break;
}
// Get transient content
$transient_content = maybe_unserialize($aDBc_transient->option_content);
if(is_array($transient_content)){
$transient_content = "<i>Array</i>";
}elseif(gettype($transient_content) == 'object'){
$transient_content = "<i>Object</i>";
}else{
$transient_content = aDBc_create_tooltip_for_long_string($aDBc_transient->option_content, 35);
}
// Susbst transient name
$transient_name = aDBc_create_tooltip_for_long_string($aDBc_transient->option_name, 35);
array_push($this->aDBc_elements_to_display, array(
'transient_id' => $aDBc_transient->option_id,
'transient_name' => $transient_name,
'transient_content' => $transient_content,
'transient_timeout' => $transient_timeout,
'transient_autoload' => $aDBc_transient->autoload,
'site_id' => $blog_id
)
);
}
}
/** WP: Get columns */
function get_columns(){
$columns = array(
'cb' => '<input type="checkbox" />',
'transient_id' => __('ID','advanced-database-cleaner'),
'transient_name' => __('Transient name','advanced-database-cleaner'),
'transient_content' => __('Value','advanced-database-cleaner'),
'transient_timeout' => __('Expires In','advanced-database-cleaner'),
'transient_autoload' => __('Autoload','advanced-database-cleaner'),
'site_id' => __('Site id','advanced-database-cleaner')
);
return $columns;
}
/** WP: Column default */
function column_default($item, $column_name){
switch($column_name){
case 'transient_id':
case 'transient_name':
case 'transient_content':
case 'transient_timeout':
case 'transient_autoload':
case 'site_id':
return $item[$column_name];
default:
return print_r($item, true) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Get columns that should be hidden */
function get_hidden_columns(){
// If MU, nothing to hide, else hide Side ID column
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return array('site_id');
}
}
function get_sortable_columns() {
$sortable_columns = array(
'transient_id' => array('a.option_id', false), //true means it's already sorted
'transient_name' => array('a.option_name', false)
);
// Since order_by works directly with sql request, we will not order_by in mutlisite since it will not work
if(function_exists('is_multisite') && is_multisite()){
return array();
}else{
return $sortable_columns;
}
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$per_page = 50;
if(!empty($_GET['per_page'])){
$per_page = absint($_GET['per_page']);
}
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice($this->aDBc_elements_to_display,(($current_page-1) * $per_page), $per_page);
$this->set_pagination_args( array(
'total_items' => count($this->aDBc_elements_to_display),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Column cb for check box */
function column_cb($item) {
return sprintf('<input type="checkbox" name="aDBc_elements_to_process[]" value="%s" />', $item['site_id']."|".$item['transient_id']);
}
/** WP: Get bulk actions */
function get_bulk_actions() {
$actions = array(
'clean' => __('Clean','advanced-database-cleaner')
);
return $actions;
}
/** WP: Message to display when no items found */
function no_items() {
_e('No elements found!','advanced-database-cleaner');
}
/** WP: Process bulk actions */
public function process_bulk_action() {
// Detect when a bulk action is being triggered.
$action = $this->current_action();
if ( ! $action )
return;
// security check!
check_admin_referer( 'bulk-' . $this->_args['plural'] );
// Check role
if ( ! current_user_can( 'administrator' ) )
wp_die( 'Security check failed!' );
if ( $action == 'clean' ) {
// If the user wants to clean the elements he/she selected
if(isset($_POST['aDBc_elements_to_process'])){
if(function_exists('is_multisite') && is_multisite()){
// Prepare feeds to delete
$feeds_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $aDBc_feed){
$feed_info = explode("|", $aDBc_feed);
$sanitized_site_id = sanitize_html_class($feed_info[0]);
$sanitized_item_id = sanitize_html_class($feed_info[1]);
// For security, we only proceed if both parts are clean and are numbers
if(is_numeric($sanitized_site_id) && is_numeric($sanitized_item_id)){
if(empty($feeds_to_delete[$sanitized_site_id])){
$feeds_to_delete[$sanitized_site_id] = array();
}
array_push($feeds_to_delete[$sanitized_site_id], $sanitized_item_id);
}
}
// Delete feeds
foreach($feeds_to_delete as $site_id => $feed_ids){
switch_to_blog($site_id);
global $wpdb;
$transients_to_delete = $wpdb->get_results("select option_name, option_id from $wpdb->options WHERE option_id IN (" . implode(',',$feed_ids) . ")");
foreach($transients_to_delete as $transient){
$site_wide = (strpos($transient->option_name, '_site_transient') !== false);
$name = str_replace($site_wide ? '_site_transient_' : '_transient_', '', $transient->option_name);
if(false !== $site_wide){
// We used a query directly here instead of delete_site_transient() because in MU, WP tries to delete the transient from sitemeta table, however, in our case, all results above are from options table. So, we need to delete them from options table
$name_timeout = '_site_transient_timeout_' . $name;
$wpdb->query("DELETE FROM $wpdb->options WHERE option_id = {$transient->option_id} OR option_name = '{$name_timeout}'");
}else{
delete_transient($name);
}
}
restore_current_blog();
}
}else{
global $wpdb;
$ids_to_delete = array();
foreach($_POST['aDBc_elements_to_process'] as $aDBc_feed){
$feed_info = explode("|", $aDBc_feed);
$sanitized_id = sanitize_html_class($feed_info[1]);
if(is_numeric($sanitized_id)){
array_push($ids_to_delete, $sanitized_id);
}
}
$names_to_delete = $wpdb->get_col("select option_name from $wpdb->options WHERE option_id IN (" . implode(',',$ids_to_delete) . ")");
foreach($names_to_delete as $transient_name){
$site_wide = (strpos($transient_name, '_site_transient') !== false);
$name = str_replace($site_wide ? '_site_transient_' : '_transient_', '', $transient_name);
if(false !== $site_wide){
// Here, we used delete_site_transient() instead of a query because on a single site, this function will delete the transient from options table
delete_site_transient($name);
}else{
delete_transient($name);
}
}
}
// Update the message to show to the user
$this->aDBc_message = __("Selected 'Transients' successfully cleaned!", "advanced-database-cleaner");
}
}
}
/** Print the page content */
function aDBc_print_page_content(){
include_once 'page_custom_clean.php';
}
}
?>

View File

@@ -0,0 +1,160 @@
<!-- style et code ok -->
<div class="aDBc-float-left aDBc-margin-t-10">
<a href="?page=advanced_db_cleaner&aDBc_tab=general" style="text-decoration:none">
<span class="dashicons dashicons-controls-back aDBc-back-dashicon"></span>
<span style="vertical-align:middle"><?php echo __( 'Return', 'advanced-database-cleaner' ); ?></span>
</a>
</div>
<div>
<div class="aDBc-custom-clean-text">
<?php
echo __( 'Custom cleanup of', 'advanced-database-cleaner' ) . " ";
echo "<strong>" . $this->aDBc_plural_title . "</strong> - ";
echo __( 'Total Found', 'advanced-database-cleaner' ) . " : ";
echo "<b><span class='aDBc-custom-total'>" . count( $this->aDBc_elements_to_display ) . "</span></b>";
?>
</div>
<div class="aDBc-filter-container">
<div class="aDBc-filter-section">
<span class="aDBc-premium-tooltip">
<?php
$free_style = "";
if ( ADBC_PLUGIN_PLAN == "free" ) {
$free_style = "aDBc-filter-pro-only";
}
?>
<form class="<?php echo $free_style; ?>" method="get">
<?php
// Generate current parameters in URL
foreach ( $_GET as $name => $value ) {
if ( $name != "s" && $name != "in" && $name != "paged" ) {
$name = esc_attr( sanitize_text_field( $name ) );
$value = esc_attr( sanitize_text_field( $value ) );
echo "<input type='hidden' name='$name' value='$value'/>";
}
}
// Return paged to page 1
echo "<input type='hidden' name='paged' value='1'/>";
?>
<input class="aDBc-filter-search-input" type="search" placeholder="<?php _e( 'Search for', 'advanced-database-cleaner' ); ?>" name="s" value="<?php echo empty( $_GET['s'] ) ? '' : esc_attr( $_GET['s'] ); ?>"/>
<div class="aDBc-custom-filter-radio-section">
<span style="padding:0px 10px"><?php _e( 'Search in', 'advanced-database-cleaner' ); ?></span>
<?php
$in_checked = empty( $_GET['in'] ) || ( ! empty( $_GET['in'] ) && $_GET['in'] == "key" ) ? 'checked' : '';
$value_checked = ! empty( $_GET['in'] ) && $_GET['in'] == "value" ? 'checked' : '';
?>
<input type="radio" name="in" value="key" checked <?php echo $in_checked; ?>><?php _e( 'Name', 'advanced-database-cleaner' ); ?> &nbsp;
<input type="radio" name="in" value="value" <?php echo $value_checked; ?>><?php _e( 'Value', 'advanced-database-cleaner' ); ?>
</div>
<input class="button-secondary aDBc-filter-botton" type="submit" value="<?php _e( 'Filter', 'advanced-database-cleaner' ); ?>"/>
</form>
<?php
if ( ADBC_PLUGIN_PLAN == "free" ) {
?>
<span style="width:150px" class="aDBc-premium-tooltiptext">
<a href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner/" target="_blank">
<?php _e( 'Available in Pro version!', 'advanced-database-cleaner' ); ?>
</a>
</span>
<?php
}
?>
</span>
</div>
<!-- Items per page -->
<div class="aDBc-items-per-page">
<form method="get">
<?php
// Generate current parameters in URL
foreach ( $_GET as $name => $value ) {
if ( $name != "per_page" && $name != "paged" ) {
$name = esc_attr( sanitize_text_field( $name ) );
$value = esc_attr( sanitize_text_field( $value ) );
echo "<input type='hidden' name='$name' value='$value'/>";
}
}
// Return paged to page 1
echo "<input type='hidden' name='paged' value='1'/>";
?>
<span class="aDBc-items-per-page-label">
<?php _e( 'Items per page', 'advanced-database-cleaner' ); ?>
</span>
<input name="per_page" class="aDBc-items-per-page-input" type="number" value="<?php echo empty( $_GET['per_page'] ) ? '50' : esc_attr( $_GET['per_page'] ); ?>"/>
<input type="submit" class="button-secondary aDBc-show-botton" value="<?php _e( 'Show', 'advanced-database-cleaner' ); ?>"/>
</form>
</div>
<?php
if ( ( ! empty( $_GET['s'] ) && trim( $_GET['s'] ) != "" ) ||
! empty( $_GET['in'] )
) {
// Remove args to delete custom filter
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = remove_query_arg( array( 's', 'in' ), $aDBc_new_URI );
?>
<div class="aDBc-delete-custom-filter">
<a style="color:red" href="<?php echo esc_url( $aDBc_new_URI ); ?>">
<?php _e( 'Delete custom filter', 'advanced-database-cleaner' ); ?>
</a>
</div>
<?php
}
?>
</div>
</div>

View File

@@ -0,0 +1,22 @@
<?php
// Print a message if any
if($this->aDBc_message != ""){
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
?>
<div class="aDBc-content-max-width">
<?php include_once 'header_page_custom_clean.php'; ?>
<div>
<form id="aDBc_form" action="" method="post">
<?php
// Print the elements to clean
$this->display();
?>
</form>
</div>
</div>

View File

@@ -0,0 +1,396 @@
<?php
// style et code ok
class ADBC_SCHEDULE_CLEANUP extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_total_elements_to_clean = 0;
/**
* Constructor
*/
function __construct() {
parent::__construct( array(
'singular' => __( 'Element', 'advanced-database-cleaner' ),
'plural' => __( 'Elements', 'advanced-database-cleaner' ),
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean() {
// Test if user wants to save the scheduled task
if ( isset( $_POST['aDBc_schedule_name'] ) ) {
//Quick nonce security check!
if ( ! check_admin_referer( 'add_cleanup_schedule_nonce', 'add_cleanup_schedule_nonce' ) )
return; //get out if we didn't click the save_schedule button
if ( ! empty( $_POST['aDBc_elements_to_process'] ) ) {
$trim_schedule_name = trim( $_POST['aDBc_schedule_name'] );
if ( ! empty( $trim_schedule_name ) ) {
if ( preg_match( '/^[a-zA-Z0-9_]+$/', $_POST['aDBc_schedule_name'] ) ) {
// Test if the name is used by other schedules.
$clean_schedule_setting = get_option( 'aDBc_clean_schedule' );
$clean_schedule_setting = is_array( $clean_schedule_setting ) ? $clean_schedule_setting : array();
$optimize_schedule_setting = get_option( 'aDBc_optimize_schedule' );
$optimize_schedule_setting = is_array( $optimize_schedule_setting ) ? $optimize_schedule_setting : array();
if ( ! array_key_exists( $_POST['aDBc_schedule_name'], $clean_schedule_setting ) &&
! array_key_exists( $_POST['aDBc_schedule_name'], $optimize_schedule_setting ) ) {
if ( ! empty( $_POST['aDBc_date'] ) ) {
if ( ! empty( $_POST['aDBc_time'] ) ) {
// We will create the new schedule
$sanitized_elements_to_process = array();
foreach ( $_POST['aDBc_elements_to_process'] as $element ) {
array_push( $sanitized_elements_to_process, sanitize_html_class( $element ) );
}
$new_schedule_params['elements_to_clean'] = $sanitized_elements_to_process;
$new_schedule_params['repeat'] = sanitize_html_class( $_POST['aDBc_schedule_repeat'] );
$new_schedule_params['start_date'] = preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] );
$new_schedule_params['start_time'] = preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] );
$new_schedule_params['active'] = sanitize_html_class( $_POST['aDBc_status'] );
$clean_schedule_setting[$_POST['aDBc_schedule_name']] = $new_schedule_params;
update_option( 'aDBc_clean_schedule', $clean_schedule_setting, "no" );
list( $year, $month, $day ) = explode( '-', preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] ) );
list( $hours, $minutes ) = explode( ':', preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] ) );
$seconds = "0";
$timestamp = mktime( $hours, $minutes, $seconds, $month, $day, $year );
if ( $_POST['aDBc_status'] == "1" ) {
if ( $_POST['aDBc_schedule_repeat'] == "once" ) {
wp_schedule_single_event( $timestamp, "aDBc_clean_scheduler", array( $_POST['aDBc_schedule_name'] ) );
} else {
wp_schedule_event( $timestamp, sanitize_html_class( $_POST['aDBc_schedule_repeat'] ), "aDBc_clean_scheduler", array( $_POST['aDBc_schedule_name'] ) );
}
$this->aDBc_message = __( 'The clean-up schedule saved successfully!', 'advanced-database-cleaner' );
} else {
$this->aDBc_message = __( 'The clean-up schedule saved successfully but it is inactive!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide time!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide date!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'The name you have specified is already used by another schedule! Please change it!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please change the name! Only letters, numbers and underscores are allowed!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please give a name to your schedule!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please select at least one item to include in the schedule from the table below!', 'advanced-database-cleaner' );
}
}
// Get all unused elements
$aDBc_unused_elements = aDBc_return_array_all_elements_to_clean();
// Get settings from DB
$settings = get_option( 'aDBc_settings' );
foreach ( $aDBc_unused_elements as $element_type => $element_name ) {
// Get "keep_last" option. This option is added in ADBC version 3.0, so test if it is not empty before using it
if ( empty( $settings['keep_last'] ) ) {
$keep_number = '0';
} else {
$keep_setting = $settings['keep_last'];
if ( empty( $keep_setting[$element_type] ) ) {
$keep_number = '0';
} else {
$keep_number = $keep_setting[$element_type];
}
}
// If the item can have keep_last, then prepare it, otherwise echo N/A
if ( $element_type == "revision" ||
$element_type == "auto-draft" ||
$element_type == "trash-posts" ||
$element_type == "moderated-comments" ||
$element_type == "spam-comments" ||
$element_type == "trash-comments" ||
$element_type == "pingbacks" ||
$element_type == "trackbacks") {
$keep_info = "<span>" . $keep_number . " " . __( 'days', 'advanced-database-cleaner' );
} else {
$keep_info = __( 'N/A', 'advanced-database-cleaner' );
}
array_push( $this->aDBc_elements_to_display, array(
'element_to_schedule' => "<a href='" . $element_name['URL_blog'] . "' target='_blank' class='aDBc-info-icon'>&nbsp;</a>" . $element_name['name'],
'keep' => $keep_info,
'type' => $element_type
)
);
}
// Call WP prepare_items function
$this->prepare_items();
}
/** WP: Get columns */
function get_columns() {
$aDBc_keep_last_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __( 'Only data that is older than the number you have specified will be cleaned based on you schedule parameters. To change this value, click on "go back" button.', 'advanced-database-cleaner' ) ." </span>
</span>";
$columns = array(
'cb' => '<input type="checkbox" />',
'element_to_schedule' => __( 'Elements to include in the schedule', 'advanced-database-cleaner' ),
'keep' => __( 'Keep last', 'advanced-database-cleaner' ) . $aDBc_keep_last_toolip,
'type' => 'Type'
);
return $columns;
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = array();
$this->_column_headers = array( $columns, $hidden, $sortable );
$per_page = 50;
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice( $this->aDBc_elements_to_display, ( ( $current_page-1 ) * $per_page ), $per_page );
$this->set_pagination_args( array(
'total_items' => count( $this->aDBc_elements_to_display ),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Get columns that should be hidden */
function get_hidden_columns() {
return array( 'type' );
}
/** WP: Column default */
function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'element_to_schedule':
case 'keep':
case 'type':
return $item[$column_name];
default:
return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Column cb for check box */
function column_cb( $item ) {
$checked = "";
if ( isset( $_POST['aDBc_elements_to_process'] ) ) {
if ( in_array( $item['type'], $_POST['aDBc_elements_to_process'] ) ) {
$checked = "checked";
}
}
return sprintf( '<input type="checkbox" name="aDBc_elements_to_process[]" value="%s"' . $checked . '/>', $item['type'] );
}
/** WP: Get bulk actions */
function get_bulk_actions() {
return array();
}
/** WP: Message to display when no items found */
function no_items() {
_e( 'Your database is clean!', 'advanced-database-cleaner' );
}
/** Print the page content */
function aDBc_print_page_content() {
// Print a message if any
if ( $this->aDBc_message != "" ) {
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
?>
<div style="max-width:700px">
<div class="aDBc-float-left aDBc-margin-t-10">
<a href="?page=advanced_db_cleaner&aDBc_tab=general" style="text-decoration:none">
<span class="dashicons dashicons-controls-back aDBc-back-dashicon"></span>
<span style="vertical-align:middle"><?php echo __( 'Return', 'advanced-database-cleaner' ); ?></span>
</a>
</div>
<div class="aDBc-schedule-title">
<span class="dashicons dashicons-plus aDBc-schedule-dashicon"></span>
<?php echo __( 'Add cleanup schedule', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-clear-both"></div>
<form id="aDBc_form" action="" method="post">
<!-- Print the elements to clean -->
<div class="aDBc-schedule-table-elements">
<?php $this->display(); ?>
</div>
<div class="aDBc-right-box">
<div class="aDBc-right-box-content">
<div style="text-align:center">
<img width="60px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/alarm-clock.svg' ?>"/>
</div>
<div id="add_schedule" class="aDBc-schedule-info-container">
<div class="aDBc-margin-t-10"></div>
<div><?php _e( 'Schedule name', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_schedule_name" class="aDBc-schedule-input-field" type="text" value="<?php echo isset( $_POST['aDBc_schedule_name'] ) ? esc_attr( $_POST['aDBc_schedule_name'] ) : "" ?>" maxlength="25">
<div><?php _e( 'Frequency of execution', 'advanced-database-cleaner' ); ?></div>
<select name="aDBc_schedule_repeat" class="aDBc-schedule-input-field">
<?php
$schedules_repeat = array( 'once' => __( 'Once', 'advanced-database-cleaner' ),
'hourly' => __( 'Hourly', 'advanced-database-cleaner' ),
'twicedaily' => __( 'Twice a day', 'advanced-database-cleaner' ),
'daily' => __( 'Daily', 'advanced-database-cleaner' ),
'weekly' => __( 'Weekly', 'advanced-database-cleaner' ),
'monthly' => __( 'Monthly', 'advanced-database-cleaner' )
);
foreach ( $schedules_repeat as $code_repeat => $name_repeat ) {
if ( isset( $_POST['aDBc_schedule_repeat'] ) && $_POST['aDBc_schedule_repeat'] == $code_repeat ) {
echo "<option value='$code_repeat' selected='selected'>$name_repeat</option>";
} else {
echo "<option value='$code_repeat'>$name_repeat</option>";
}
}
?>
</select>
<div><?php _e( 'Start date', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_date" class="aDBc-schedule-input-field" type="date" value="<?php echo isset( $_POST['aDBc_date'] ) ? esc_attr( $_POST['aDBc_date'] ) : date( "Y-m-d" ); ?>" min="<?php echo date( "Y-m-d" ); ?>">
<div><?php _e( 'Start time (GMT)', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_time" class="aDBc-schedule-input-field" type="time" value="<?php echo isset( $_POST['aDBc_time'] ) ? esc_attr( $_POST['aDBc_time'] ) : date( "H:i", time() ); ?>">
<div><?php _e( 'Schedule status', 'advanced-database-cleaner' ); ?></div>
<div class="aDBc-schedule-radio-container">
<input name="aDBc_status" type="radio" value="1" checked>
<span style="margin-right:20px"><?php _e( 'Active', 'advanced-database-cleaner' ); ?></span>
<input name="aDBc_status" type="radio" value="0" <?php echo ( isset( $_POST['aDBc_status'] ) && $_POST['aDBc_status'] == "0" ) ? 'checked' : ''; ?>>
<?php _e( 'Inactive', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-schedule-save-btn-div">
<input class="button-primary" type="submit" value="<?php _e( 'Save the schedule', 'advanced-database-cleaner' ); ?>" style="width:100%"/>
</div>
</div>
</div>
</div>
<?php wp_nonce_field( 'add_cleanup_schedule_nonce', 'add_cleanup_schedule_nonce' ); ?>
</form>
<div class="aDBc-clear-both"></div>
</div>
<?php
}
}
?>

View File

@@ -0,0 +1,269 @@
<?php
// style et code ok
class ADBC_SCHEDULE_OPTIMIZE {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
/**
* Constructor
*/
function __construct() {
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean() {
// Test if user wants to save the scheduled task
if ( isset( $_POST['aDBc_schedule_name'] ) ) {
//Quick nonce security check!
if ( ! check_admin_referer( 'add_optimize_schedule_nonce', 'add_optimize_schedule_nonce' ) )
return; //get out if we didn't click the save_schedule button
$trim_schedule_name = trim( $_POST['aDBc_schedule_name'] );
if ( ! empty( $trim_schedule_name ) ) {
if ( preg_match( '/^[a-zA-Z0-9_]+$/', $_POST['aDBc_schedule_name'] ) ) {
// Test if the name is used by other schedules.
$clean_schedule_setting = get_option( 'aDBc_clean_schedule' );
$clean_schedule_setting = is_array( $clean_schedule_setting ) ? $clean_schedule_setting : array();
$optimize_schedule_setting = get_option( 'aDBc_optimize_schedule' );
$optimize_schedule_setting = is_array( $optimize_schedule_setting ) ? $optimize_schedule_setting : array();
if ( ! array_key_exists( $_POST['aDBc_schedule_name'], $clean_schedule_setting ) &&
! array_key_exists( $_POST['aDBc_schedule_name'], $optimize_schedule_setting ) ) {
if ( ! empty( $_POST['aDBc_date'] ) ) {
if ( ! empty( $_POST['aDBc_time'] ) ) {
if ( ! empty( $_POST['aDBc_operation1'] ) || ! empty( $_POST['aDBc_operation2'] ) ) {
// We will create the new schedule
$new_schedule_params['repeat'] = sanitize_html_class( $_POST['aDBc_schedule_repeat'] );
$new_schedule_params['start_date'] = preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] );
$new_schedule_params['start_time'] = preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] );
// Prepare operations to perform
$operations = array();
if ( ! empty( $_POST['aDBc_operation1'] ) )
array_push( $operations, sanitize_html_class( $_POST['aDBc_operation1'] ) );
if ( ! empty( $_POST['aDBc_operation2'] ) )
array_push( $operations, sanitize_html_class( $_POST['aDBc_operation2'] ) );
$new_schedule_params['operations'] = $operations;
$new_schedule_params['active'] = sanitize_html_class( $_POST['aDBc_status'] );
$optimize_schedule_setting[$_POST['aDBc_schedule_name']] = $new_schedule_params;
update_option( 'aDBc_optimize_schedule', $optimize_schedule_setting, "no" );
list( $year, $month, $day ) = explode( '-', preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] ) );
list( $hours, $minutes ) = explode( ':', preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] ) );
$seconds = "0";
$timestamp = mktime( $hours, $minutes, $seconds, $month, $day, $year );
if ( $_POST['aDBc_status'] == "1" ) {
if ( $_POST['aDBc_schedule_repeat'] == "once" ) {
wp_schedule_single_event( $timestamp, "aDBc_optimize_scheduler", array( $_POST['aDBc_schedule_name'] ) );
} else {
wp_schedule_event( $timestamp, sanitize_html_class( $_POST['aDBc_schedule_repeat'] ), "aDBc_optimize_scheduler", array( $_POST['aDBc_schedule_name'] ) );
}
$this->aDBc_message = __( 'The clean-up schedule saved successfully!', 'advanced-database-cleaner' );
} else {
$this->aDBc_message = __( 'The clean-up schedule saved successfully but it is inactive!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please choose at least one operation to perform!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide time!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide date!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'The name you have specified is already used by another schedule! Please change it!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please change the name! Only letters, numbers and underscores are allowed!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please give a name to your schedule!', 'advanced-database-cleaner' );
}
}
}
/** Print the page content */
function aDBc_print_page_content() {
// Print a message if any
if ( $this->aDBc_message != "" ) {
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
?>
<div style="max-width:700px">
<div class="aDBc-float-left aDBc-margin-t-10">
<a href="?page=advanced_db_cleaner&aDBc_tab=tables&aDBc_cat=all" style="text-decoration:none">
<span class="dashicons dashicons-controls-back aDBc-back-dashicon"></span>
<span style="vertical-align:middle"><?php echo __( 'Return', 'advanced-database-cleaner' ); ?></span>
</a>
</div>
<div class="aDBc-schedule-title">
<span class="dashicons dashicons-plus aDBc-schedule-dashicon"></span>
<?php echo __( 'Add optimize schedule', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-clear-both"></div>
<form id="aDBc_form" action="" method="post">
<!-- Print box info for tables that will be optimized -->
<div class="aDBc-schedule-table-elements aDBc-schedule-tables-box-info">
<div style="padding:40px 20px">
<?php echo __( 'By default, all your database tables will be optimized and/or repaired (if needed) according to your schedule settings', 'advanced-database-cleaner' ); ?>
</div>
</div>
<div class="aDBc-right-box">
<div class="aDBc-right-box-content">
<div style="text-align:center">
<img width="60px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/alarm-clock.svg' ?>"/>
</div>
<div id="add_schedule" class="aDBc-schedule-info-container">
<div class="aDBc-margin-t-10"></div>
<div><?php _e( 'Schedule name', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_schedule_name" class="aDBc-schedule-input-field" type="text" value="<?php echo isset( $_POST['aDBc_schedule_name'] ) ? esc_attr( $_POST['aDBc_schedule_name'] ) : "" ?>" maxlength="25">
<div><?php _e( 'Frequency of execution', 'advanced-database-cleaner' ); ?></div>
<select name="aDBc_schedule_repeat" class="aDBc-schedule-input-field">
<?php
$schedules_repeat = array( 'once' => __( 'Once', 'advanced-database-cleaner' ),
'hourly' => __( 'Hourly', 'advanced-database-cleaner' ),
'twicedaily' => __( 'Twice a day', 'advanced-database-cleaner' ),
'daily' => __( 'Daily', 'advanced-database-cleaner' ),
'weekly' => __( 'Weekly', 'advanced-database-cleaner' ),
'monthly' => __( 'Monthly', 'advanced-database-cleaner' )
);
foreach ( $schedules_repeat as $code_repeat => $name_repeat ) {
if ( isset( $_POST['aDBc_schedule_repeat'] ) && $_POST['aDBc_schedule_repeat'] == $code_repeat ) {
echo "<option value='$code_repeat' selected='selected'>$name_repeat</option>";
} else {
echo "<option value='$code_repeat'>$name_repeat</option>";
}
}
?>
</select>
<div><?php _e( 'Start date', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_date" class="aDBc-schedule-input-field" type="date" value="<?php echo isset( $_POST['aDBc_date'] ) ? esc_attr( $_POST['aDBc_date'] ) : date( "Y-m-d" ); ?>" min="<?php echo date( "Y-m-d" ); ?>">
<div><?php _e( 'Start time (GMT)', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_time" class="aDBc-schedule-input-field" type="time" value="<?php echo isset( $_POST['aDBc_time'] ) ? esc_attr( $_POST['aDBc_time'] ) : date( "H:i", time() ); ?>">
<div><?php _e( 'Perform operations', 'advanced-database-cleaner' ); ?></div>
<div class="aDBc-schedule-radio-container">
<?php
$optimize_checked = ( isset( $_POST['aDBc_operation1'] ) && $_POST['aDBc_operation1'] == "optimize" ) ? 'checked' : '';
$repair_checked = ( isset( $_POST['aDBc_operation2'] ) && $_POST['aDBc_operation2'] == "repair" ) ? 'checked' : '';
?>
<input name="aDBc_operation1" type="checkbox" value="optimize" <?php echo $optimize_checked; ?>>
<span style="margin-right:20px"><?php _e( 'Optimize', 'advanced-database-cleaner' ); ?></span>
<input name="aDBc_operation2" type="checkbox" value="repair" <?php echo $repair_checked; ?>>
<?php _e( 'Repair', 'advanced-database-cleaner' ); ?>
</div>
<div><?php _e( 'Schedule status', 'advanced-database-cleaner' ); ?></div>
<div class="aDBc-schedule-radio-container">
<input name="aDBc_status" type="radio" value="1" checked>
<span style="margin-right:20px"><?php _e( 'Active', 'advanced-database-cleaner' ); ?></span>
<input name="aDBc_status" type="radio" value="0" <?php echo ( isset( $_POST['aDBc_status'] ) && $_POST['aDBc_status'] == "0" ) ? 'checked' : ''; ?>>
<?php _e( 'Inactive', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-schedule-save-btn-div">
<input class="button-primary" type="submit" value="<?php _e( 'Save the schedule', 'advanced-database-cleaner' ); ?>" style="width:100%"/>
</div>
</div>
</div>
</div>
<?php wp_nonce_field( 'add_optimize_schedule_nonce', 'add_optimize_schedule_nonce' ); ?>
</form>
<div class="aDBc-clear-both"></div>
</div>
<?php
}
}
?>

View File

@@ -0,0 +1,451 @@
<?php
// style et code ok
class EDIT_SCHEDULE_CLEANUP extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
private $aDBc_elements_to_display = array();
private $aDBc_total_elements_to_clean = 0;
/**
* Constructor
*/
function __construct() {
parent::__construct( array(
'singular' => __( 'Element', 'advanced-database-cleaner' ),
'plural' => __( 'Elements', 'advanced-database-cleaner' ),
'ajax' => false
));
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean() {
// Test if user wants to save the edited scheduled task
if ( isset( $_POST['aDBc_schedule_name'] ) ) {
//Quick nonce security check!
if ( ! check_admin_referer( 'edit_cleanup_schedule_nonce', 'edit_cleanup_schedule_nonce' ) )
return; //get out if we didn't click the save_schedule button
if ( ! empty( $_POST['aDBc_elements_to_process'] ) ) {
$trim_schedule_name = trim( $_POST['aDBc_schedule_name'] );
if ( ! empty( $trim_schedule_name ) ) {
if ( preg_match( '/^[a-zA-Z0-9_]+$/', $_POST['aDBc_schedule_name'] ) ) {
// Test if the name is used by other schedules.
$clean_schedule_setting = get_option( 'aDBc_clean_schedule' );
$clean_schedule_setting = is_array( $clean_schedule_setting ) ? $clean_schedule_setting : array();
$optimize_schedule_setting = get_option( 'aDBc_optimize_schedule' );
$optimize_schedule_setting = is_array( $optimize_schedule_setting ) ? $optimize_schedule_setting : array();
if ( $_POST['aDBc_schedule_name'] == $_GET['hook_name'] ||
( $_POST['aDBc_schedule_name'] != $_GET['hook_name'] &&
! array_key_exists( $_POST['aDBc_schedule_name'], $clean_schedule_setting ) &&
! array_key_exists( $_POST['aDBc_schedule_name'], $optimize_schedule_setting ) )
) {
if ( ! empty( $_POST['aDBc_date'] ) ) {
if ( ! empty( $_POST['aDBc_time'] ) ) {
// Delete the old schedule and replace it with the new
// We will create the new schedule
$sanitized_elements_to_process = array();
foreach ( $_POST['aDBc_elements_to_process'] as $element ) {
array_push( $sanitized_elements_to_process, sanitize_html_class( $element ) );
}
$new_schedule_params['elements_to_clean'] = $sanitized_elements_to_process;
$new_schedule_params['repeat'] = sanitize_html_class( $_POST['aDBc_schedule_repeat'] );
$new_schedule_params['start_date'] = preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] );
$new_schedule_params['start_time'] = preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] );
$new_schedule_params['active'] = sanitize_html_class( $_POST['aDBc_status'] );
$clean_schedule_setting[$_POST['aDBc_schedule_name']] = $new_schedule_params;
update_option( 'aDBc_clean_schedule', $clean_schedule_setting, "no" );
list( $year, $month, $day ) = explode( '-', preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] ) );
list( $hours, $minutes ) = explode( ':', preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] ) );
$seconds = "0";
$timestamp = mktime( $hours, $minutes, $seconds, $month, $day, $year );
// Clear scheduled event
wp_clear_scheduled_hook( 'aDBc_clean_scheduler', array( $_POST['aDBc_schedule_name'] . '' ) );
if ( $_POST['aDBc_status'] == "1" ) {
if ( $_POST['aDBc_schedule_repeat'] == "once" ) {
wp_schedule_single_event( $timestamp, "aDBc_clean_scheduler", array( $_POST['aDBc_schedule_name'] ) );
} else {
wp_schedule_event( $timestamp, sanitize_html_class( $_POST['aDBc_schedule_repeat'] ), "aDBc_clean_scheduler", array( $_POST['aDBc_schedule_name'] ) );
}
$this->aDBc_message = __( 'The clean-up schedule saved successfully!', 'advanced-database-cleaner' );
} else {
$this->aDBc_message = __( 'The clean-up schedule saved successfully but it is inactive!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide time!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide date!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'The name you have specified is already used by another schedule! Please change it!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please change the name! Only letters, numbers and underscores are allowed!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please give a name to your schedule!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please select at least one item to include in the schedule from the table below!', 'advanced-database-cleaner' );
}
}
// Get all unused elements
$aDBc_unused_elements = aDBc_return_array_all_elements_to_clean();
// Get settings from DB
$settings = get_option( 'aDBc_settings' );
foreach ( $aDBc_unused_elements as $element_type => $element_name ) {
// Get "keep_last" option. This option is added in ADBC version 3.0, so test if it is not empty before using it
if ( empty( $settings['keep_last'] ) ) {
$keep_number = '0';
} else {
$keep_setting = $settings['keep_last'];
if ( empty( $keep_setting[$element_type] ) ) {
$keep_number = '0';
} else {
$keep_number = $keep_setting[$element_type];
}
}
// If the item can have keep_last, then prepare it, otherwise echo N/A
if ( $element_type == "revision" ||
$element_type == "auto-draft" ||
$element_type == "trash-posts" ||
$element_type == "moderated-comments" ||
$element_type == "spam-comments" ||
$element_type == "trash-comments" ||
$element_type == "pingbacks" ||
$element_type == "trackbacks") {
$keep_info = "<span>" . $keep_number . " " . __( 'days', 'advanced-database-cleaner' );
} else {
$keep_info = __( 'N/A', 'advanced-database-cleaner' );
}
array_push( $this->aDBc_elements_to_display, array(
'element_to_schedule' => "<a href='" . $element_name['URL_blog'] . "' target='_blank' class='aDBc-info-icon'>&nbsp;</a>" . $element_name['name'],
'keep' => $keep_info,
'type' => $element_type
)
);
}
// Call WP prepare_items function
$this->prepare_items();
}
/** WP: Get columns */
function get_columns() {
$aDBc_keep_last_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __( 'Only data that is older than the number you have specified will be cleaned based on you schedule parameters. To change this value, click on "go back" button.', 'advanced-database-cleaner' ) ." </span>
</span>";
$columns = array(
'cb' => '<input type="checkbox" />',
'element_to_schedule' => __( 'Elements to include in the schedule', 'advanced-database-cleaner' ),
'keep' => __( 'Keep last', 'advanced-database-cleaner' ) . $aDBc_keep_last_toolip,
'type' => 'Type'
);
return $columns;
}
/** WP: Prepare items to display */
function prepare_items() {
$columns = $this->get_columns();
$hidden = $this->get_hidden_columns();
$sortable = array();
$this->_column_headers = array( $columns, $hidden, $sortable );
$per_page = 50;
$current_page = $this->get_pagenum();
// Prepare sequence of elements to display
$display_data = array_slice( $this->aDBc_elements_to_display, ( ( $current_page-1 ) * $per_page ), $per_page );
$this->set_pagination_args( array(
'total_items' => count( $this->aDBc_elements_to_display ),
'per_page' => $per_page
));
$this->items = $display_data;
}
/** WP: Get columns that should be hidden */
function get_hidden_columns() {
return array( 'type' );
}
/** WP: Column default */
function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'element_to_schedule':
case 'keep':
case 'type':
return $item[$column_name];
default:
return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes
}
}
/** WP: Column cb for check box */
function column_cb( $item ) {
$checked = "";
if ( isset( $_POST['aDBc_schedule_name'] ) && ! empty( $_POST['aDBc_elements_to_process'] ) ) {
if ( in_array( $item['type'], $_POST['aDBc_elements_to_process'] ) ) {
$checked = "checked";
}
} else {
$schedule_settings = get_option('aDBc_clean_schedule');
$schedule_params = $schedule_settings[sanitize_html_class($_GET['hook_name'])];
$schedule_elements_to_clean = $schedule_params['elements_to_clean'];
$schedule_elements_to_clean = is_array($schedule_elements_to_clean) ? $schedule_elements_to_clean : array();
if ( in_array($item['type'], $schedule_elements_to_clean ) ) {
$checked = "checked";
}
}
return sprintf( '<input type="checkbox" name="aDBc_elements_to_process[]" value="%s"' . $checked . '/>', $item['type'] );
}
/** WP: Get bulk actions */
function get_bulk_actions() {
return array();
}
/** WP: Message to display when no items found */
function no_items() {
_e( 'Your database is clean!', 'advanced-database-cleaner' );
}
/** Print the page content */
function aDBc_print_page_content() {
// Print a message if any
if ( $this->aDBc_message != "" ) {
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
?>
<div style="max-width:700px">
<div class="aDBc-float-left aDBc-margin-t-10">
<a href="?page=advanced_db_cleaner&aDBc_tab=general" style="text-decoration:none">
<span class="dashicons dashicons-controls-back aDBc-back-dashicon"></span>
<span style="vertical-align:middle"><?php echo __( 'Return', 'advanced-database-cleaner' ); ?></span>
</a>
</div>
<div class="aDBc-schedule-title">
<span class="dashicons dashicons-edit aDBc-schedule-dashicon"></span>
<?php echo __( 'Edit cleanup schedule', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-clear-both"></div>
<form id="aDBc_form" action="" method="post">
<!-- Print the elements to clean -->
<div class="aDBc-schedule-table-elements">
<?php $this->display(); ?>
</div>
<?php
// Prepare info of the original schedule to fill it into inputs...
if ( isset( $_POST['aDBc_schedule_name'] ) ) {
$hook_name = sanitize_html_class( $_POST['aDBc_schedule_name'] );
$schedule_repeat = sanitize_html_class( $_POST['aDBc_schedule_repeat'] );
$schedule_date = preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] );
$schedule_time = preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] );
$schedule_status = sanitize_html_class( $_POST['aDBc_status'] );
} else {
$schedule_settings = get_option( 'aDBc_clean_schedule' );
$schedule_params = $schedule_settings[sanitize_html_class( $_GET['hook_name'] )];
$hook_name = sanitize_html_class( $_GET['hook_name'] );
$schedule_repeat = $schedule_params['repeat'];
$timestamp = wp_next_scheduled( "aDBc_clean_scheduler", array( sanitize_html_class( $_GET['hook_name'] ) . '' ) );
if ( $timestamp ) {
$schedule_date = date( "Y-m-d", $timestamp );
$schedule_time = date( "H:i", $timestamp );
} else {
$schedule_date = date( "Y-m-d" );
$schedule_time = date( "H:i", time() );
}
$schedule_status = $schedule_params['active'];
}
?>
<div class="aDBc-right-box">
<div class="aDBc-right-box-content">
<div style="text-align:center">
<img width="60px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/alarm-clock.svg' ?>"/>
</div>
<div id="add_schedule" class="aDBc-schedule-info-container">
<div class="aDBc-margin-t-10"></div>
<div><?php _e( 'Schedule name', 'advanced-database-cleaner' ); ?></div>
<input class="aDBc-schedule-input-field" type="text" value="<?php echo $hook_name; ?>" maxlength="25" disabled>
<input type="hidden" name="aDBc_schedule_name" value="<?php echo $hook_name; ?>" maxlength="25">
<div><?php _e( 'Frequency of execution', 'advanced-database-cleaner' ); ?></div>
<select name="aDBc_schedule_repeat" class="aDBc-schedule-input-field">
<?php
$schedules_repeat = array( 'once' => __( 'Once', 'advanced-database-cleaner' ),
'hourly' => __( 'Hourly', 'advanced-database-cleaner' ),
'twicedaily' => __( 'Twice a day', 'advanced-database-cleaner' ),
'daily' => __( 'Daily', 'advanced-database-cleaner' ),
'weekly' => __( 'Weekly', 'advanced-database-cleaner' ),
'monthly' => __( 'Monthly', 'advanced-database-cleaner' )
);
foreach ( $schedules_repeat as $code_repeat => $name_repeat ) {
if ( $code_repeat == $schedule_repeat ) {
echo "<option value='$code_repeat' selected='selected'>$name_repeat</option>";
} else {
echo "<option value='$code_repeat'>$name_repeat</option>";
}
}
?>
</select>
<div><?php _e( 'Start date', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_date" class="aDBc-schedule-input-field" type="date" value="<?php echo $schedule_date; ?>" min="<?php echo date( "Y-m-d" ); ?>">
<div><?php _e( 'Start time (GMT)', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_time" class="aDBc-schedule-input-field" type="time" value="<?php echo $schedule_time; ?>">
<div><?php _e( 'Schedule status', 'advanced-database-cleaner' ); ?></div>
<div class="aDBc-schedule-radio-container">
<input name="aDBc_status" type="radio" value="1" checked>
<span style="margin-right:20px"><?php _e( 'Active', 'advanced-database-cleaner' ); ?></span>
<input name="aDBc_status" type="radio" value="0" <?php echo $schedule_status == "0" ? 'checked' : ''; ?>>
<?php _e( 'Inactive', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-schedule-save-btn-div">
<input class="button-primary" type="submit" value="<?php _e( 'Save the schedule', 'advanced-database-cleaner' ); ?>" style="width:100%"/>
</div>
</div>
</div>
</div>
<?php wp_nonce_field( 'edit_cleanup_schedule_nonce', 'edit_cleanup_schedule_nonce' ); ?>
</form>
<div class="aDBc-clear-both"></div>
</div>
<?php
}
}
?>

View File

@@ -0,0 +1,313 @@
<?php
// style et code ok
class EDIT_SCHEDULE_OPTIMIZE extends WP_List_Table {
private $aDBc_message = "";
private $aDBc_class_message = "updated";
/**
* Constructor
*/
function __construct() {
$this->aDBc_prepare_elements_to_clean();
$this->aDBc_print_page_content();
}
/** Prepare elements to display */
function aDBc_prepare_elements_to_clean() {
// Test if user wants to save the edited scheduled task
if ( isset( $_POST['aDBc_schedule_name'] ) ) {
//Quick nonce security check!
if ( ! check_admin_referer( 'edit_optimize_schedule_nonce', 'edit_optimize_schedule_nonce' ) )
return; //get out if we didn't click the save_schedule button
$trim_schedule_name = trim( $_POST['aDBc_schedule_name'] );
if ( ! empty( $trim_schedule_name ) ) {
if ( preg_match( '/^[a-zA-Z0-9_]+$/', $_POST['aDBc_schedule_name'] ) ) {
// Test if the name is used by other schedules.
$clean_schedule_setting = get_option( 'aDBc_clean_schedule' );
$clean_schedule_setting = is_array( $clean_schedule_setting ) ? $clean_schedule_setting : array();
$optimize_schedule_setting = get_option( 'aDBc_optimize_schedule' );
$optimize_schedule_setting = is_array( $optimize_schedule_setting ) ? $optimize_schedule_setting : array();
if ( $_POST['aDBc_schedule_name'] == $_GET['hook_name'] ||
( $_POST['aDBc_schedule_name'] != $_GET['hook_name'] &&
! array_key_exists( $_POST['aDBc_schedule_name'], $clean_schedule_setting ) &&
! array_key_exists( $_POST['aDBc_schedule_name'], $optimize_schedule_setting ) )
) {
if ( ! empty( $_POST['aDBc_date'] ) ) {
if ( ! empty( $_POST['aDBc_time'] ) ) {
if ( ! empty( $_POST['aDBc_operation1'] ) || ! empty( $_POST['aDBc_operation2'] ) ) {
// Delete the old schedule and replace it with the new
// We will create the new schedule
$new_schedule_params['repeat'] = sanitize_html_class( $_POST['aDBc_schedule_repeat'] );
$new_schedule_params['start_date'] = preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] );
$new_schedule_params['start_time'] = preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] );
// Prepare operations to perform
$operations = array();
if ( ! empty( $_POST['aDBc_operation1'] ) )
array_push( $operations, sanitize_html_class( $_POST['aDBc_operation1'] ) );
if ( ! empty( $_POST['aDBc_operation2'] ) )
array_push( $operations, sanitize_html_class( $_POST['aDBc_operation2'] ) );
$new_schedule_params['operations'] = $operations;
$new_schedule_params['active'] = sanitize_html_class( $_POST['aDBc_status'] );
$optimize_schedule_setting[$_POST['aDBc_schedule_name']] = $new_schedule_params;
update_option( 'aDBc_optimize_schedule', $optimize_schedule_setting, "no" );
list( $year, $month, $day ) = explode( '-', preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] ) );
list( $hours, $minutes ) = explode( ':', preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] ) );
$seconds = "0";
$timestamp = mktime( $hours, $minutes, $seconds, $month, $day, $year );
// Clear scheduled event
wp_clear_scheduled_hook( 'aDBc_optimize_scheduler', array( $_POST['aDBc_schedule_name'] . '') );
if ( $_POST['aDBc_status'] == "1" ) {
if ( $_POST['aDBc_schedule_repeat'] == "once" ) {
wp_schedule_single_event( $timestamp, "aDBc_optimize_scheduler", array( $_POST['aDBc_schedule_name'] ) );
} else {
wp_schedule_event( $timestamp, sanitize_html_class( $_POST['aDBc_schedule_repeat'] ), "aDBc_optimize_scheduler", array( $_POST['aDBc_schedule_name'] ) );
}
$this->aDBc_message = __( 'The clean-up schedule saved successfully!', 'advanced-database-cleaner' );
} else {
$this->aDBc_message = __( 'The clean-up schedule saved successfully but it is inactive!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please choose at least one operation to perform!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide time!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please specify a valide date!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'The name you have specified is already used by another schedule! Please change it!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please change the name! Only letters, numbers and underscores are allowed!', 'advanced-database-cleaner' );
}
} else {
$this->aDBc_class_message = "error";
$this->aDBc_message = __( 'Please give a name to your schedule!', 'advanced-database-cleaner' );
}
}
}
/** Print the page content */
function aDBc_print_page_content() {
// Print a message if any
if ( $this->aDBc_message != "" ) {
echo '<div id="aDBc_message" class="' . $this->aDBc_class_message . ' notice is-dismissible"><p>' . $this->aDBc_message . '</p></div>';
}
?>
<div style="max-width:700px">
<div class="aDBc-float-left aDBc-margin-t-10">
<a href="?page=advanced_db_cleaner&aDBc_tab=tables&aDBc_cat=all" style="text-decoration:none">
<span class="dashicons dashicons-controls-back aDBc-back-dashicon"></span>
<span style="vertical-align:middle"><?php echo __( 'Return', 'advanced-database-cleaner' ); ?></span>
</a>
</div>
<div class="aDBc-schedule-title">
<span class="dashicons dashicons-plus aDBc-schedule-dashicon"></span>
<?php echo __( 'Edit cleanup schedule', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-clear-both"></div>
<form id="aDBc_form" action="" method="post">
<!-- Print box info for tables that will be optimized -->
<div class="aDBc-schedule-table-elements aDBc-schedule-tables-box-info">
<div style="padding:40px 20px">
<?php echo __( 'By default, all your database tables will be optimized and/or repaired (if needed) according to your schedule settings', 'advanced-database-cleaner' ); ?>
</div>
</div>
<?php
// Prepare info of the original schedule to fill it into inputs...
if ( isset( $_POST['aDBc_schedule_name'] ) ) {
$hook_name = sanitize_html_class( $_POST['aDBc_schedule_name'] );
$schedule_repeat = sanitize_html_class( $_POST['aDBc_schedule_repeat'] );
$schedule_date = preg_replace( "/[^0-9-]/", '', $_POST['aDBc_date'] );
$schedule_time = preg_replace( "/[^0-9:]/", '', $_POST['aDBc_time'] );
$operation1 = isset( $_POST['aDBc_operation1'] ) ? sanitize_html_class( $_POST['aDBc_operation1'] ) : "";
$operation2 = isset( $_POST['aDBc_operation2'] ) ? sanitize_html_class( $_POST['aDBc_operation2'] ) : "";
$schedule_status = sanitize_html_class( $_POST['aDBc_status'] );
} else {
$schedule_settings = get_option( 'aDBc_optimize_schedule' );
$schedule_params = $schedule_settings[sanitize_html_class( $_GET['hook_name'] )];
$hook_name = sanitize_html_class( $_GET['hook_name'] );
$schedule_repeat = $schedule_params['repeat'];
$timestamp = wp_next_scheduled( "aDBc_optimize_scheduler", array( sanitize_html_class( $_GET['hook_name'] ) . '' ) );
if ( $timestamp ) {
$schedule_date = date( "Y-m-d", $timestamp );
$schedule_time = date( "H:i", $timestamp );
} else {
$schedule_date = date( "Y-m-d" );
$schedule_time = date( "H:i", time() );
}
$operation1 = in_array( 'optimize', $schedule_params['operations'] ) ? 'optimize' : '';
$operation2 = in_array( 'repair', $schedule_params['operations'] ) ? 'repair' : '';
$schedule_status = $schedule_params['active'];
}
?>
<div class="aDBc-right-box">
<div class="aDBc-right-box-content">
<div style="text-align:center">
<img width="60px" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/alarm-clock.svg' ?>"/>
</div>
<div id="add_schedule" class="aDBc-schedule-info-container">
<div class="aDBc-margin-t-10"></div>
<div><?php _e( 'Schedule name', 'advanced-database-cleaner' ); ?></div>
<input class="aDBc-schedule-input-field" type="text" value="<?php echo $hook_name; ?>" maxlength="25" disabled>
<input type="hidden" name="aDBc_schedule_name" value="<?php echo $hook_name; ?>" maxlength="25">
<div><?php _e( 'Frequency of execution', 'advanced-database-cleaner' ); ?></div>
<select name="aDBc_schedule_repeat" class="aDBc-schedule-input-field">
<?php
$schedules_repeat = array( 'once' => __( 'Once', 'advanced-database-cleaner' ),
'hourly' => __( 'Hourly', 'advanced-database-cleaner' ),
'twicedaily' => __( 'Twice a day', 'advanced-database-cleaner' ),
'daily' => __( 'Daily', 'advanced-database-cleaner' ),
'weekly' => __( 'Weekly', 'advanced-database-cleaner' ),
'monthly' => __( 'Monthly', 'advanced-database-cleaner' )
);
foreach ( $schedules_repeat as $code_repeat => $name_repeat ) {
if ( $code_repeat == $schedule_repeat ) {
echo "<option value='$code_repeat' selected='selected'>$name_repeat</option>";
} else {
echo "<option value='$code_repeat'>$name_repeat</option>";
}
}
?>
</select>
<div><?php _e( 'Start date', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_date" class="aDBc-schedule-input-field" type="date" value="<?php echo $schedule_date; ?>" min="<?php echo date( "Y-m-d" ); ?>">
<div><?php _e( 'Start time (GMT)', 'advanced-database-cleaner' ); ?></div>
<input name="aDBc_time" class="aDBc-schedule-input-field" type="time" value="<?php echo $schedule_time; ?>">
<div><?php _e( 'Perform operations', 'advanced-database-cleaner' ); ?></div>
<div class="aDBc-schedule-radio-container">
<input name="aDBc_operation1" type="checkbox" value="optimize" <?php echo $operation1 == "optimize" ? 'checked' : ''; ?>>
<span style="margin-right:20px"><?php _e( 'Optimize', 'advanced-database-cleaner' ); ?></span>
<input name="aDBc_operation2" type="checkbox" value="repair" <?php echo $operation2 == "repair" ? 'checked' : ''; ?>>
<?php _e( 'Repair', 'advanced-database-cleaner' ); ?>
</div>
<div><?php _e( 'Schedule status', 'advanced-database-cleaner' ); ?></div>
<div class="aDBc-schedule-radio-container">
<input name="aDBc_status" type="radio" value="1" checked>
<span style="margin-right:20px"><?php _e( 'Active', 'advanced-database-cleaner' ); ?></span>
<input name="aDBc_status" type="radio" value="0" <?php echo $schedule_status == "0" ? 'checked' : ''; ?>>
<?php _e( 'Inactive', 'advanced-database-cleaner' ); ?>
</div>
<div class="aDBc-schedule-save-btn-div">
<input class="button-primary" type="submit" value="<?php _e( 'Save the schedule', 'advanced-database-cleaner' ); ?>" style="width:100%"/>
</div>
</div>
</div>
</div>
<?php wp_nonce_field( 'edit_optimize_schedule_nonce', 'edit_optimize_schedule_nonce' ); ?>
</form>
<div class="aDBc-clear-both"></div>
</div>
<?php
}
}
?>

View File

@@ -0,0 +1,126 @@
<!-- style et code ok -->
<div style="max-width:700px">
<form id="aDBc_form" action="" method="post">
<div class="aDBc-edit-correction-title">
<?php echo __( 'Manual correction of the categorization', 'advanced-database-cleaner' ); ?>
</div>
<?php
// Get the current tab
$item_type = $_GET['aDBc_tab'];
// We change the cron tab name to tasks. No problem with tables and options
if ( $item_type == "cron" ) {
$item_type = "tasks";
}
// Open the file in which the items to edit have been saved
$path_items = @fopen( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/" . $item_type . "_manually_correction_temp.txt", "r" );
if ( $path_items ) {
echo "<div style='margin-top:30px'>";
$items_to_correct_array = array();
while ( ( $item = fgets( $path_items ) ) !== false ) {
$item = trim( $item );
if ( ! empty( $item ) ) {
array_push( $items_to_correct_array, $item );
echo "<span class='aDBc-correction-item'>" . esc_html($item) . "</span>";
}
}
echo "</div>";
fclose( $path_items );
}
?>
<div class="aDBc-clear-both"></div>
<div class="aDBc-correction-new-wrapper">
<div>
<?php
if ( $item_type == "tables" ) {
echo __( 'The tables above belong to:', 'advanced-database-cleaner' );
} elseif ( $item_type == "options" ) {
echo __( 'The options above belong to:', 'advanced-database-cleaner' );
} elseif ( $item_type == "tasks" ) {
echo __( 'The cron tasks above belong to:', 'advanced-database-cleaner' );
}
?>
</div>
<?php
$plugins_folders_names = aDBc_get_plugins_folder_names();
$themes_folders_names = aDBc_get_themes_folder_names();
?>
<select name="new_belongs_to" class="aDBc-correction-belongs-to">
<optgroup label="<?php echo __( 'Plugins', 'advanced-database-cleaner' ); ?>">
<?php
foreach ( $plugins_folders_names as $plugin ) {
echo "<option value='$plugin|p'>" . $plugin . "</option>";
}
?>
</optgroup>
<optgroup label="<?php echo __( 'Themes', 'advanced-database-cleaner' ); ?>">
<?php
foreach ( $themes_folders_names as $theme ) {
echo "<option value='$theme|t'>" . $theme . "</option>";
}
?>
</optgroup>
<optgroup label="<?php echo __( 'WordPress', 'advanced-database-cleaner' ); ?>">
<?php
echo "<option value='w|w'>" . __( 'WordPress core', 'advanced-database-cleaner' ) . "</option>";
?>
</optgroup>
</select>
</div>
<div class="aDBc-clear-both"></div>
<div class="aDBc-correction-btns-div">
<input name="aDBc_correct" class="button-primary aDBc-correction-btn" type="submit" value="<?php _e( 'Save', 'advanced-database-cleaner' ); ?>"/>
<input name="aDBc_cancel" class="button-secondary aDBc-correction-btn" type="submit" value="<?php _e( 'Cancel', 'advanced-database-cleaner' ); ?>"/>
</div>
</form>
</div>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,336 @@
<!-- style et code ok -->
<div class="aDBc-filter-container" style="border-radius:4px">
<div class="aDBc-filter-section">
<span class="aDBc-premium-tooltip">
<?php
$free_style = "";
if ( ADBC_PLUGIN_PLAN == "free" ) {
$free_style = "aDBc-filter-pro-only";
}
?>
<form class="<?php echo $free_style; ?>" method="get">
<?php
// Generate current parameters in URL
foreach ( $_GET as $name => $value ) {
if ( $name != "s" && $name != "paged" && $name != "aDBc_cat" ) {
$name = esc_attr( sanitize_text_field( $name ) );
$value = esc_attr( sanitize_text_field( $value ) );
echo "<input type='hidden' name='$name' value='$value'/>";
}
}
// Return paged to "1" and aDBc_cat to "all" after each filter
echo "<input type='hidden' name='paged' value='1'/>";
echo "<input type='hidden' name='aDBc_cat' value='all'/>";
?>
<div class="aDBc-filter-elements">
<div>
<label class="aDBc-filter-label">
<?php _e('Search for', 'advanced-database-cleaner' ); ?>
</label>
<input class="aDBc-filter-search-input" type="search" placeholder="<?php _e( 'Search for', 'advanced-database-cleaner' ); ?>" name="s" value="<?php echo empty( $_GET['s'] ) ? '' : esc_attr( $_GET['s'] ); ?>"/>
</div>
<?php
// Show this filter tables type only for tables
if ( isset( $_GET['aDBc_tab'] ) && $_GET['aDBc_tab'] == 'tables' ) {
$all_selected = ( isset( $_GET['t_type'] ) && $_GET['t_type'] == 'all' ) ? "selected='selected'" : "";
$optimize_selected = ( isset( $_GET['t_type'] ) && $_GET['t_type'] == 'optimize' ) ? "selected='selected'" : "";
$repair_selected = ( isset( $_GET['t_type'] ) && $_GET['t_type'] == 'repair' ) ? "selected='selected'" : "";
?>
<div>
<label class="aDBc-filter-label">
<?php _e('Table status', 'advanced-database-cleaner' ); ?>
</label>
<select name="t_type" class="aDBc-filter-dropdown-menu" style="width:100px">
<option value="all" <?php echo $all_selected; ?>>
<?php _e( 'All', 'advanced-database-cleaner' ) ?>
</option>
<option value="optimize" <?php echo $optimize_selected; ?>>
<?php
echo __( 'To optimize', 'advanced-database-cleaner' ) . " (" . count( $this->aDBc_tables_name_to_optimize ) . ")"
?>
</option>
<option value="repair" <?php echo $repair_selected; ?>>
<?php
echo __( 'To repair', 'advanced-database-cleaner' ) . " (" . count( $this->aDBc_tables_name_to_repair ) . ")"
?>
</option>
</select>
</div>
<?php
}
// Show autoload only for options
if ( isset( $_GET['aDBc_tab'] ) && $_GET['aDBc_tab'] == 'options' ) {
$all_autoload = ( isset( $_GET['autoload'] ) && $_GET['autoload'] == 'all' ) ? "selected='selected'" : "";
$autoload_yes = ( isset( $_GET['autoload'] ) && $_GET['autoload'] == 'yes' ) ? "selected='selected'" : "";
$autoload_no = ( isset( $_GET['autoload'] ) && $_GET['autoload'] == 'no' ) ? "selected='selected'" : "";
?>
<div>
<label class="aDBc-filter-label">
<?php _e('Autoload', 'advanced-database-cleaner' ); ?>
</label>
<select name="autoload" class="aDBc-filter-dropdown-menu" style="width:100px">
<option value="all" <?php echo $all_autoload; ?>>
<?php _e( 'All', 'advanced-database-cleaner' ); ?>
</option>
<option value="yes" <?php echo $autoload_yes; ?>>
<?php
echo __( 'Yes', 'advanced-database-cleaner' );
if(function_exists('wp_autoload_values_to_autoload')){
echo " [on, auto, auto-on]";
}
?>&nbsp;
</option>
<option value="no" <?php echo $autoload_no; ?>>
<?php
echo __( 'No', 'advanced-database-cleaner' );
if(function_exists('wp_autoload_values_to_autoload')){
echo " [off, auto-off]";
}
?>
</option>
</select>
</div>
<?php
}
?>
<div>
<label class="aDBc-filter-label">
<?php _e( 'Belongs to', 'advanced-database-cleaner' ); ?>
</label>
<select name="belongs_to" class="aDBc-filter-dropdown-menu" style="width:135px">
<option value="all">
<?php _e( 'All', 'advanced-database-cleaner' ); ?>
</option>
<?php
$total_plugins = 0;
$total_themes = 0;
foreach ( $this->array_belongs_to_counts as $name => $info ) {
if ( $info['type'] == "p" ) {
$total_plugins++;
} elseif ( $info['type'] == "t" ) {
$total_themes++;
}
}
?>
<optgroup label="<?php echo __( 'Plugins', 'advanced-database-cleaner' ) . " (" . $total_plugins . ")" ?>">
<?php
foreach ( $this->array_belongs_to_counts as $name => $info ) {
if ( $info['type'] == "p" ) {
$selected = isset( $_GET['belongs_to'] ) && $_GET['belongs_to'] == $name ? "selected='selected'" : "";
echo "<option value='$name'" . $selected . ">" . $name . " (" . $info['count'] .")" . "</option>";
}
}
?>
</optgroup>
<optgroup label="<?php echo __( 'Themes', 'advanced-database-cleaner' ) . " (" . $total_themes . ")" ?>">
<?php
foreach ( $this->array_belongs_to_counts as $name => $info ) {
if ( $info['type'] == "t" ) {
$selected = isset( $_GET['belongs_to'] ) && $_GET['belongs_to'] == $name ? "selected='selected'" : "";
echo "<option value='$name'" . $selected . ">" . $name . " (" . $info['count'] .")" . "</option>";
}
}
?>
</optgroup>
</select>
</div>
<?php
if ( function_exists( 'is_multisite' ) && is_multisite() ){
?>
<div>
<label class="aDBc-filter-label">
<?php _e( 'In site', 'advanced-database-cleaner' ); ?>
</label>
<select name="site" class="aDBc-filter-dropdown-menu" style="width:85px">
<option value=""> <?php _e( 'All', 'advanced-database-cleaner' ); ?> </option>
<?php
global $wpdb;
$blogs_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
foreach ( $blogs_ids as $blog_id ) {
$blog_details = get_blog_details( $blog_id );
$selected = ( isset( $_GET['site'] ) && $_GET['site'] == $blog_id ) ? "selected='selected'" : "";
echo "<option value='$blog_id'". $selected .">" . __( 'Site', 'advanced-database-cleaner' ) . " ". $blog_id . " | " . $blog_details->blogname . "</option>";
}
?>
</select>
</div>
<?php
}
?>
<div>
<label class="aDBc-filter-label" style="visibility:hidden">
Submit
</label>
<input class="button-secondary aDBc-filter-botton" type="submit" value="<?php _e( 'Filter', 'advanced-database-cleaner' ); ?>"/>
</div>
</div>
</form>
<?php
if ( ADBC_PLUGIN_PLAN == "free" ) {
?>
<span style="width:150px" class="aDBc-premium-tooltiptext">
<a href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner/" target="_blank">
<?php _e( 'Available in Pro version!', 'advanced-database-cleaner' ); ?>
</a>
</span>
<?php
}
?>
</span>
</div>
<!-- Items per page -->
<div class="aDBc-items-per-page">
<form method="get">
<?php
// Generate current parameters in URL
foreach ( $_GET as $name => $value ) {
if ( $name != "per_page" && $name != "paged" ) {
$name = esc_attr( sanitize_text_field( $name ) );
$value = esc_attr( sanitize_text_field( $value ) );
echo "<input type='hidden' name='$name' value='$value'/>";
}
}
// Return paged to page 1
echo "<input type='hidden' name='paged' value='1'/>";
?>
<div>
<label class="aDBc-filter-label" style="font-weight:normal">
<?php _e( 'Items per page', 'advanced-database-cleaner' ); ?>
</label>
<input name="per_page" class="aDBc-items-per-page-input" type="number" value="<?php echo empty( $_GET['per_page'] ) ? '50' : esc_attr( $_GET['per_page'] ); ?>"/>
<input type="submit" class="button-secondary aDBc-show-botton" value="<?php _e( 'Show', 'advanced-database-cleaner' ); ?>"/>
</div>
</form>
</div>
<?php
if ( ( ! empty( $_GET['s'] ) && trim( $_GET['s'] ) != "" ) ||
! empty( $_GET['t_type'] ) ||
! empty( $_GET['belongs_to'] ) ||
! empty( $_GET['site'] )
) {
// Remove args to delete custom filter
$aDBc_new_URI = $_SERVER['REQUEST_URI'];
$aDBc_new_URI = remove_query_arg( array( 's', 't_type', 'belongs_to', 'site', 'autoload' ), $aDBc_new_URI );
$aDBc_new_URI = add_query_arg( 'aDBc_cat', 'all', $aDBc_new_URI );
?>
<div class="aDBc-delete-custom-filter">
<a style="color:red" href="<?php echo esc_url( $aDBc_new_URI ); ?>">
<?php _e( 'Delete custom filter', 'advanced-database-cleaner' ); ?>
</a>
</div>
<?php
}
?>
</div>

View File

@@ -0,0 +1,676 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Allows plugins to use their own update API.
*
* @author Easy Digital Downloads
* @version 1.9.2
*/
class ADBC_EDD_SL_Plugin_Updater {
private $api_url = '';
private $api_data = array();
private $plugin_file = '';
private $name = '';
private $slug = '';
private $version = '';
private $wp_override = false;
private $beta = false;
private $failed_request_cache_key;
/**
* Class constructor.
*
* @uses plugin_basename()
* @uses hook()
*
* @param string $_api_url The URL pointing to the custom API endpoint.
* @param string $_plugin_file Path to the plugin file.
* @param array $_api_data Optional data to send with API calls.
*/
public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
global $edd_plugin_data;
$this->api_url = trailingslashit( $_api_url );
$this->api_data = $_api_data;
$this->plugin_file = $_plugin_file;
$this->name = plugin_basename( $_plugin_file );
$this->slug = basename( $_plugin_file, '.php' );
$this->version = $_api_data['version'];
$this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
$this->beta = ! empty( $this->api_data['beta'] ) ? true : false;
$this->failed_request_cache_key = 'edd_sl_failed_http_' . md5( $this->api_url );
$edd_plugin_data[ $this->slug ] = $this->api_data;
/**
* Fires after the $edd_plugin_data is setup.
*
* @since x.x.x
*
* @param array $edd_plugin_data Array of EDD SL plugin data.
*/
do_action( 'post_edd_sl_plugin_updater_setup', $edd_plugin_data );
// Set up hooks.
$this->init();
}
/**
* Set up WordPress filters to hook into WP's update process.
*
* @uses add_filter()
*
* @return void
*/
public function init() {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
add_action( 'after_plugin_row', array( $this, 'show_update_notification' ), 10, 2 );
add_action( 'admin_init', array( $this, 'show_changelog' ) );
}
/**
* Check for Updates at the defined API endpoint and modify the update array.
*
* This function dives into the update API just when WordPress creates its update array,
* then adds a custom API call and injects the custom plugin data retrieved from the API.
* It is reassembled from parts of the native WordPress plugin update code.
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
*
* @uses api_request()
*
* @param array $_transient_data Update array build by WordPress.
* @return array Modified update array with custom plugin data.
*/
public function check_update( $_transient_data ) {
global $pagenow;
if ( ! is_object( $_transient_data ) ) {
$_transient_data = new stdClass();
}
if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
return $_transient_data;
}
$current = $this->get_repo_api_data();
if ( false !== $current && is_object( $current ) && isset( $current->new_version ) ) {
if ( version_compare( $this->version, $current->new_version, '<' ) ) {
$_transient_data->response[ $this->name ] = $current;
} else {
// Populating the no_update information is required to support auto-updates in WordPress 5.5.
$_transient_data->no_update[ $this->name ] = $current;
}
}
$_transient_data->last_checked = time();
$_transient_data->checked[ $this->name ] = $this->version;
return $_transient_data;
}
/**
* Get repo API data from store.
* Save to cache.
*
* @return \stdClass
*/
public function get_repo_api_data() {
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->api_request(
'plugin_latest_version',
array(
'slug' => $this->slug,
'beta' => $this->beta,
)
);
if ( ! $version_info ) {
return false;
}
// This is required for your plugin to support auto-updates in WordPress 5.5.
$version_info->plugin = $this->name;
$version_info->id = $this->name;
$version_info->tested = $this->get_tested_version( $version_info );
$this->set_version_info_cache( $version_info );
}
return $version_info;
}
/**
* Gets the plugin's tested version.
*
* @since 1.9.2
* @param object $version_info
* @return null|string
*/
private function get_tested_version( $version_info ) {
// There is no tested version.
if ( empty( $version_info->tested ) ) {
return null;
}
// Strip off extra version data so the result is x.y or x.y.z.
list( $current_wp_version ) = explode( '-', get_bloginfo( 'version' ) );
// The tested version is greater than or equal to the current WP version, no need to do anything.
if ( version_compare( $version_info->tested, $current_wp_version, '>=' ) ) {
return $version_info->tested;
}
$current_version_parts = explode( '.', $current_wp_version );
$tested_parts = explode( '.', $version_info->tested );
// The current WordPress version is x.y.z, so update the tested version to match it.
if ( isset( $current_version_parts[2] ) && $current_version_parts[0] === $tested_parts[0] && $current_version_parts[1] === $tested_parts[1] ) {
$tested_parts[2] = $current_version_parts[2];
}
return implode( '.', $tested_parts );
}
/**
* Show the update notification on multisite subsites.
*
* @param string $file
* @param array $plugin
*/
public function show_update_notification( $file, $plugin ) {
// Return early if in the network admin, or if this is not a multisite install.
if ( is_network_admin() || ! is_multisite() ) {
return;
}
// Allow single site admins to see that an update is available.
if ( ! current_user_can( 'activate_plugins' ) ) {
return;
}
if ( $this->name !== $file ) {
return;
}
// Do not print any message if update does not exist.
$update_cache = get_site_transient( 'update_plugins' );
if ( ! isset( $update_cache->response[ $this->name ] ) ) {
if ( ! is_object( $update_cache ) ) {
$update_cache = new stdClass();
}
$update_cache->response[ $this->name ] = $this->get_repo_api_data();
}
// Return early if this plugin isn't in the transient->response or if the site is running the current or newer version of the plugin.
if ( empty( $update_cache->response[ $this->name ] ) || version_compare( $this->version, $update_cache->response[ $this->name ]->new_version, '>=' ) ) {
return;
}
printf(
'<tr class="plugin-update-tr %3$s" id="%1$s-update" data-slug="%1$s" data-plugin="%2$s">',
$this->slug,
$file,
in_array( $this->name, $this->get_active_plugins(), true ) ? 'active' : 'inactive'
);
echo '<td colspan="3" class="plugin-update colspanchange">';
echo '<div class="update-message notice inline notice-warning notice-alt"><p>';
$changelog_link = '';
if ( ! empty( $update_cache->response[ $this->name ]->sections->changelog ) ) {
$changelog_link = add_query_arg(
array(
'edd_sl_action' => 'view_plugin_changelog',
'plugin' => urlencode( $this->name ),
'slug' => urlencode( $this->slug ),
'TB_iframe' => 'true',
'width' => 77,
'height' => 911,
),
self_admin_url( 'index.php' )
);
}
$update_link = add_query_arg(
array(
'action' => 'upgrade-plugin',
'plugin' => urlencode( $this->name ),
),
self_admin_url( 'update.php' )
);
printf(
/* translators: the plugin name. */
esc_html__( 'There is a new version of %1$s available.', 'advanced-database-cleaner' ),
esc_html( $plugin['Name'] )
);
if ( ! current_user_can( 'update_plugins' ) ) {
echo ' ';
esc_html_e( 'Contact your network administrator to install the update.', 'advanced-database-cleaner' );
} elseif ( empty( $update_cache->response[ $this->name ]->package ) && ! empty( $changelog_link ) ) {
echo ' ';
printf(
/* translators: 1. opening anchor tag, do not translate 2. the new plugin version 3. closing anchor tag, do not translate. */
__( '%1$sView version %2$s details%3$s.', 'advanced-database-cleaner' ),
'<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
esc_html( $update_cache->response[ $this->name ]->new_version ),
'</a>'
);
} elseif ( ! empty( $changelog_link ) ) {
echo ' ';
printf(
__( '%1$sView version %2$s details%3$s or %4$supdate now%5$s.', 'advanced-database-cleaner' ),
'<a target="_blank" class="thickbox open-plugin-details-modal" href="' . esc_url( $changelog_link ) . '">',
esc_html( $update_cache->response[ $this->name ]->new_version ),
'</a>',
'<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">',
'</a>'
);
} else {
printf(
' %1$s%2$s%3$s',
'<a target="_blank" class="update-link" href="' . esc_url( wp_nonce_url( $update_link, 'upgrade-plugin_' . $file ) ) . '">',
esc_html__( 'Update now.', 'advanced-database-cleaner' ),
'</a>'
);
}
do_action( "in_plugin_update_message-{$file}", $plugin, $plugin );
echo '</p></div></td></tr>';
}
/**
* Gets the plugins active in a multisite network.
*
* @return array
*/
private function get_active_plugins() {
$active_plugins = (array) get_option( 'active_plugins' );
$active_network_plugins = (array) get_site_option( 'active_sitewide_plugins' );
return array_merge( $active_plugins, array_keys( $active_network_plugins ) );
}
/**
* Updates information on the "View version x.x details" page with custom data.
*
* @uses api_request()
*
* @param mixed $_data
* @param string $_action
* @param object $_args
* @return object $_data
*/
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
if ( 'plugin_information' !== $_action ) {
return $_data;
}
if ( ! isset( $_args->slug ) || ( $_args->slug !== $this->slug ) ) {
return $_data;
}
$to_send = array(
'slug' => $this->slug,
'is_ssl' => is_ssl(),
'fields' => array(
'banners' => array(),
'reviews' => false,
'icons' => array(),
),
);
// Get the transient where we store the api request for this plugin for 24 hours
$edd_api_request_transient = $this->get_cached_version_info();
//If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
if ( empty( $edd_api_request_transient ) ) {
$api_response = $this->api_request( 'plugin_information', $to_send );
// Expires in 3 hours
$this->set_version_info_cache( $api_response );
if ( false !== $api_response ) {
$_data = $api_response;
}
} else {
$_data = $edd_api_request_transient;
}
// Convert sections into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
$_data->sections = $this->convert_object_to_array( $_data->sections );
}
// Convert banners into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
$_data->banners = $this->convert_object_to_array( $_data->banners );
}
// Convert icons into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->icons ) && ! is_array( $_data->icons ) ) {
$_data->icons = $this->convert_object_to_array( $_data->icons );
}
// Convert contributors into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->contributors ) && ! is_array( $_data->contributors ) ) {
$_data->contributors = $this->convert_object_to_array( $_data->contributors );
}
if ( ! isset( $_data->plugin ) ) {
$_data->plugin = $this->name;
}
return $_data;
}
/**
* Convert some objects to arrays when injecting data into the update API
*
* Some data like sections, banners, and icons are expected to be an associative array, however due to the JSON
* decoding, they are objects. This method allows us to pass in the object and return an associative array.
*
* @since 3.6.5
*
* @param stdClass $data
*
* @return array
*/
private function convert_object_to_array( $data ) {
if ( ! is_array( $data ) && ! is_object( $data ) ) {
return array();
}
$new_data = array();
foreach ( $data as $key => $value ) {
$new_data[ $key ] = is_object( $value ) ? $this->convert_object_to_array( $value ) : $value;
}
return $new_data;
}
/**
* Disable SSL verification in order to prevent download update failures
*
* @param array $args
* @param string $url
* @return object $array
*/
public function http_request_args( $args, $url ) {
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
$args['sslverify'] = $this->verify_ssl();
}
return $args;
}
/**
* Calls the API and, if successfull, returns the object delivered by the API.
*
* @uses get_bloginfo()
* @uses wp_remote_post()
* @uses is_wp_error()
*
* @param string $_action The requested action.
* @param array $_data Parameters for the API action.
* @return false|object|void
*/
private function api_request( $_action, $_data ) {
$data = array_merge( $this->api_data, $_data );
if ( $data['slug'] !== $this->slug ) {
return;
}
// Don't allow a plugin to ping itself
if ( trailingslashit( home_url() ) === $this->api_url ) {
return false;
}
if ( $this->request_recently_failed() ) {
return false;
}
return $this->get_version_from_remote();
}
/**
* Determines if a request has recently failed.
*
* @since 1.9.1
*
* @return bool
*/
private function request_recently_failed() {
$failed_request_details = get_option( $this->failed_request_cache_key );
// Request has never failed.
if ( empty( $failed_request_details ) || ! is_numeric( $failed_request_details ) ) {
return false;
}
/*
* Request previously failed, but the timeout has expired.
* This means we're allowed to try again.
*/
if ( time() > $failed_request_details ) {
delete_option( $this->failed_request_cache_key );
return false;
}
return true;
}
/**
* Logs a failed HTTP request for this API URL.
* We set a timestamp for 1 hour from now. This prevents future API requests from being
* made to this domain for 1 hour. Once the timestamp is in the past, API requests
* will be allowed again. This way if the site is down for some reason we don't bombard
* it with failed API requests.
*
* @see EDD_SL_Plugin_Updater::request_recently_failed
*
* @since 1.9.1
*/
private function log_failed_request() {
update_option( $this->failed_request_cache_key, strtotime( '+1 hour' ) );
}
/**
* If available, show the changelog for sites in a multisite install.
*/
public function show_changelog() {
if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== $_REQUEST['edd_sl_action'] ) {
return;
}
if ( empty( $_REQUEST['plugin'] ) ) {
return;
}
if ( empty( $_REQUEST['slug'] ) || $this->slug !== $_REQUEST['slug'] ) {
return;
}
if ( ! current_user_can( 'update_plugins' ) ) {
wp_die( esc_html__( 'You do not have permission to install plugin updates', 'advanced-database-cleaner' ), esc_html__( 'Error', 'advanced-database-cleaner' ), array( 'response' => 403 ) );
}
$version_info = $this->get_repo_api_data();
if ( isset( $version_info->sections ) ) {
$sections = $this->convert_object_to_array( $version_info->sections );
if ( ! empty( $sections['changelog'] ) ) {
echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
}
}
exit;
}
/**
* Gets the current version information from the remote site.
*
* @return array|false
*/
private function get_version_from_remote() {
$api_params = array(
'edd_action' => 'get_version',
'license' => ! empty( $this->api_data['license'] ) ? $this->api_data['license'] : '',
'item_name' => isset( $this->api_data['item_name'] ) ? $this->api_data['item_name'] : false,
'item_id' => isset( $this->api_data['item_id'] ) ? $this->api_data['item_id'] : false,
'version' => isset( $this->api_data['version'] ) ? $this->api_data['version'] : false,
'slug' => $this->slug,
'author' => $this->api_data['author'],
'url' => home_url(),
'beta' => $this->beta,
'php_version' => phpversion(),
'wp_version' => get_bloginfo( 'version' ),
);
/**
* Filters the parameters sent in the API request.
*
* @param array $api_params The array of data sent in the request.
* @param array $this->api_data The array of data set up in the class constructor.
* @param string $this->plugin_file The full path and filename of the file.
*/
$api_params = apply_filters( 'edd_sl_plugin_updater_api_params', $api_params, $this->api_data, $this->plugin_file );
$request = wp_remote_post(
$this->api_url,
array(
'timeout' => 15,
'sslverify' => $this->verify_ssl(),
'body' => $api_params,
)
);
if ( is_wp_error( $request ) || ( 200 !== wp_remote_retrieve_response_code( $request ) ) ) {
$this->log_failed_request();
return false;
}
$request = json_decode( wp_remote_retrieve_body( $request ) );
if ( $request && isset( $request->sections ) ) {
$request->sections = maybe_unserialize( $request->sections );
} else {
$request = false;
}
if ( $request && isset( $request->banners ) ) {
$request->banners = maybe_unserialize( $request->banners );
}
if ( $request && isset( $request->icons ) ) {
$request->icons = maybe_unserialize( $request->icons );
}
if ( ! empty( $request->sections ) ) {
foreach ( $request->sections as $key => $section ) {
$request->$key = (array) $section;
}
}
return $request;
}
/**
* Get the version info from the cache, if it exists.
*
* @param string $cache_key
* @return object
*/
public function get_cached_version_info( $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->get_cache_key();
}
$cache = get_option( $cache_key );
// Cache is expired
if ( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
return false;
}
// We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
$cache['value'] = json_decode( $cache['value'] );
if ( ! empty( $cache['value']->icons ) ) {
$cache['value']->icons = (array) $cache['value']->icons;
}
return $cache['value'];
}
/**
* Adds the plugin version information to the database.
*
* @param string $value
* @param string $cache_key
*/
public function set_version_info_cache( $value = '', $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->get_cache_key();
}
$data = array(
'timeout' => strtotime( '+3 hours', time() ),
'value' => wp_json_encode( $value ),
);
update_option( $cache_key, $data, 'no' );
// Delete the duplicate option
delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );
}
/**
* Returns if the SSL of the store should be verified.
*
* @since 1.6.13
* @return bool
*/
private function verify_ssl() {
return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this );
}
/**
* Gets the unique key (option name) for a plugin.
*
* @since 1.9.0
* @return string
*/
private function get_cache_key() {
$string = $this->slug . $this->api_data['license'] . $this->beta;
return 'edd_sl_' . md5( serialize( $string ) );
}
}

View File

@@ -0,0 +1,378 @@
<?php
/**
* For further details please visit:
* http://docs.easydigitaldownloads.com/article/383-automatic-upgrades-for-wordpress-plugins
*/
define( 'ADBC_EDD_STORE_URL', 'https://sigmaplugin.com' );
define( 'ADBC_EDD_ITEM_ID', 10 );
define( 'ADBC_EDD_ITEM_NAME', 'WordPress Advanced Database Cleaner' );
if ( ! class_exists( 'ADBC_EDD_SL_Plugin_Updater' ) ) {
// load our custom updater
include dirname( __FILE__ ) . '/ADBC_EDD_SL_Plugin_Updater.php';
}
/**
* Initialize the updater. Hooked into `init` to work with the
* wp_version_check cron job, which allows auto-updates.
*/
function aDBc_edd_sl_plugin_updater() {
// To support auto-updates, this needs to run during the wp_version_check cron job for privileged users.
$doing_cron = defined( 'DOING_CRON' ) && DOING_CRON;
if ( ! current_user_can( 'manage_options' ) && ! $doing_cron ) {
return;
}
// retrieve our license key from the DB
$license_key = trim( get_option( 'aDBc_edd_license_key' ) );
// setup the updater
$edd_updater = new ADBC_EDD_SL_Plugin_Updater( ADBC_EDD_STORE_URL, ADBC_MAIN_PLUGIN_FILE_PATH, array(
'version' => ADBC_PLUGIN_VERSION,
'license' => $license_key,
'item_id' => ADBC_EDD_ITEM_ID,
'author' => 'Younes JFR.',
'beta' => false,
)
);
}
add_action( 'init', 'aDBc_edd_sl_plugin_updater' );
/**
* License page
*
* @return void
*/
function aDBc_edd_license_page() {
$license = get_option('aDBc_edd_license_key');
$status = get_option('aDBc_edd_license_status');
if ( $status !== false && $status == 'valid' ) {
$license_key_hidden = substr( $license, 0, 4 ) . "************************" . substr( $license, -4 );
$license_status = __( 'Active', 'advanced-database-cleaner' );
$color = "color:green";
$activate_btn_style = "display:none";
$deactivate_btn_style = "";
$input_disabled = " disabled";
} else {
$license_key_hidden = "";
$license_status = __( 'Inactive', 'advanced-database-cleaner' );
$color = "color:red";
$activate_btn_style = "";
$deactivate_btn_style = "display:none";
$input_disabled = "";
}
?>
<div class="aDBc-content-max-width aDBc-padding-20">
<div class="aDBc-license-container">
<div class="aDBc-status-box">
<div class="aDBc-div-status">
<span class="aDBc-license-status-label"><?php _e( 'Status:', 'advanced-database-cleaner' ); ?></span>
<span id="aDBc_license_status" style="<?php echo $color; ?>" class="aDBc-license-status">
<?php echo $license_status ?>
</span>
</div>
<div id="aDBc_check_license_btn" style="<?php echo $deactivate_btn_style; ?>" class="aDBc-check-license-btn">
<a>
<span class="dashicons dashicons-update-alt"></span>
<?php _e( 'Check status', 'advanced-database-cleaner' ); ?>
</a>
</div>
<div class="aDBc-license-account">
<a href="https://sigmaplugin.com/login?utm_source=license_tab&utm_medium=adbc_plugin&utm_campaign=plugins" target="_blank">
<span class="dashicons dashicons-admin-users aDBc-license-icon"></span>
<?php _e( 'My account', 'advanced-database-cleaner' ); ?>
</a>
</div>
</div>
<div class="aDBc-license-box">
<input id="aDBc_license_key_input" class="aDBc-license-key-input" placeholder="<?php _e( 'License key', 'advanced-database-cleaner' ); ?>" type="text" value="<?php echo $license_key_hidden; ?>" <?php echo $input_disabled; ?>/>
<div id="aDBc_activate_license_btn" style="<?php echo $activate_btn_style; ?>" class="aDBc-license-btn">
<span class="dashicons dashicons-admin-links aDBc-license-icon"></span>
<?php _e( 'Activate license', 'advanced-database-cleaner' ); ?>
</div>
<div id="aDBc_deactivate_license_btn" style="<?php echo $deactivate_btn_style; ?>" class="aDBc-license-btn">
<span class="dashicons dashicons-editor-unlink aDBc-license-icon"></span>
<?php _e( 'Deactivate license', 'advanced-database-cleaner' ); ?>
</div>
</div>
</div>
</div>
<?php
}
/**
* Activate/deactivate/check the license key.
*
* @return void
*/
function aDBc_license_actions_callback() {
// Check nonce and user capabilities
if ( false === check_ajax_referer( 'aDBc_nonce', 'security', false ) || ! current_user_can( 'administrator' ) )
wp_send_json_error( __( 'Security check failed!', 'advanced-database-cleaner' ) );
// Get button action
$aDBc_edd_action = sanitize_text_field( $_REQUEST['aDBc_edd_action'] );
switch ( $aDBc_edd_action ) {
case 'aDBc_activate_license_btn':
$license = trim( sanitize_text_field( $_REQUEST['license_key'] ) );
$edd_action = "activate_license";
break;
case 'aDBc_deactivate_license_btn':
$license = trim( get_option( 'aDBc_edd_license_key' ) );
$edd_action = "deactivate_license";
break;
case 'aDBc_check_license_btn':
$license = trim( get_option( 'aDBc_edd_license_key' ) );
$edd_action = "check_license";
break;
default:
wp_send_json_error( __( 'Cannot proceed!', 'advanced-database-cleaner' ) );
break;
}
if ( false === $license || empty( $license ) )
wp_send_json_error( __( 'Empty license field!', 'advanced-database-cleaner' ) );
// Data to send in our API request
$api_params = array(
'edd_action' => $edd_action,
'license' => $license,
'item_id' => ADBC_EDD_ITEM_ID,
'item_name' => rawurlencode( ADBC_EDD_ITEM_NAME ),
'url' => home_url(),
'environment' => function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production',
);
// Call the custom API
$response = wp_remote_post(
ADBC_EDD_STORE_URL,
array(
'timeout' => 15,
'sslverify' => false,
'body' => $api_params,
)
);
// make sure the response came back okay
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
if ( is_wp_error( $response ) ) {
wp_send_json_error( $response->get_error_message() );
} else {
wp_send_json_error( __( 'An error occurred, please try again.', 'advanced-database-cleaner' ) );
}
}
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
if ( $edd_action == "activate_license" ) {
if ( false === $license_data->success ) {
switch ( $license_data->error ) {
case 'expired':
$message = sprintf(
/* translators: the license key expiration date */
__( 'Your license key expired on %s.', 'advanced-database-cleaner' ),
date_i18n( get_option( 'date_format' ), strtotime( $license_data->expires, current_time( 'timestamp' ) ) )
);
break;
case 'disabled':
case 'revoked':
$message = __( 'Your license key has been disabled.', 'advanced-database-cleaner' );
break;
case 'missing':
$message = __( 'Invalid license.', 'advanced-database-cleaner' );
break;
case 'invalid':
case 'site_inactive':
$message = __( 'Your license is not active for this URL.', 'advanced-database-cleaner' );
break;
case 'item_name_mismatch':
/* translators: the plugin name */
$message = sprintf( __( 'This appears to be an invalid license key for %s.', 'advanced-database-cleaner' ), ADBC_EDD_ITEM_NAME );
break;
case 'no_activations_left':
$message = __( 'Your license key has reached its activation limit.', 'advanced-database-cleaner' );
break;
default:
$message = __( 'An error has occurred, please try again.', 'advanced-database-cleaner' );
break;
}
wp_send_json_error( sanitize_text_field( $message ) );
}
// $license_data->license will be either "valid" or "invalid"
if ( 'valid' === $license_data->license ) {
update_option( 'aDBc_edd_license_key', $license, 'no' );
update_option( 'aDBc_edd_license_status', $license_data->license, 'no' );
wp_send_json_success( __( 'Activated!', 'advanced-database-cleaner' ) );
} else {
wp_send_json_error( __( 'License cannot be activated.', 'advanced-database-cleaner' ) );
}
} else if ( $edd_action == "check_license" ) {
// $license_data->license will be either "valid" or "invalid"
if ( 'valid' === $license_data->license ) {
wp_send_json_success( __( 'Your license is valid.', 'advanced-database-cleaner' ) );
} else {
wp_send_json_error( __( 'Your license is no longer valid.', 'advanced-database-cleaner' ) );
}
} else if ( $edd_action == "deactivate_license" ) {
// $license_data->license will be either "deactivated" or "failed"
// if ( 'deactivated' === $license_data->license ) {
delete_option( 'aDBc_edd_license_key' );
delete_option( 'aDBc_edd_license_status' );
wp_send_json_success( __( 'Deactivated!', 'advanced-database-cleaner' ) );
// } else {
// wp_send_json_error( __( 'License cannot be deactivated, please try again.', 'advanced-database-cleaner' ) );
// }
}
// If we are here, maybe un unknown error occurred
wp_send_json_error( __( 'Unknown error occurred, please try again.', 'advanced-database-cleaner' ) );
}
/**
* Checks if a license has been activated
*
* @return bool true if activated, false if not
*/
function aDBc_edd_is_license_activated() {
$license_status = trim( get_option( 'aDBc_edd_license_status') );
if ( $license_status == 'valid' ) {
return true;
} else {
return false;
}
}
/**
* Deactivate a license key after uninstall. This will descrease the site count
*
* @return void
*/
function aDBc_edd_deactivate_license_after_uninstall() {
$license = trim( sanitize_text_field( get_option( 'aDBc_edd_license_key' ) ) );
// data to send in our API request
$api_params = array(
'edd_action' => 'deactivate_license',
'license' => $license,
'item_id' => ADBC_EDD_ITEM_ID,
'item_name' => rawurlencode( ADBC_EDD_ITEM_NAME ),
'url' => home_url(),
'environment' => function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production',
);
// Call the custom API.
$response = wp_remote_post(
ADBC_EDD_STORE_URL,
array(
'timeout' => 15,
'sslverify' => false,
'body' => $api_params
)
);
}

View File

@@ -0,0 +1,22 @@
<?php
if(isset($_GET['aDBc_view'])){
if($_GET['aDBc_view'] == "add_optimize_schedule"){
include_once 'custom-schedule-view/class_add_optimize_schedule.php';
new ADBC_SCHEDULE_OPTIMIZE();
}else if($_GET['aDBc_view'] == "edit_optimize_schedule"){
include_once 'custom-schedule-view/class_edit_optimize_schedule.php';
new EDIT_SCHEDULE_OPTIMIZE();
}
}else{
// Else return the general clean-up page
include_once 'class_clean_tables.php';
}
?>

View File

@@ -0,0 +1,228 @@
<?php
global $wpdb, $wp_version;
// DB size
$aDBc_db_size = $wpdb->get_var("SELECT sum(round(((data_length + index_length) / 1024), 2)) FROM information_schema.tables WHERE table_schema = '" . DB_NAME . "'");
if($aDBc_db_size >= 1024){
$aDBc_db_size = round(($aDBc_db_size / 1024), 2) . " MB";
}else{
$aDBc_db_size = round($aDBc_db_size, 2) . " KB";
}
// Total tables
$aDBc_total_tables = $wpdb->get_var("SELECT count(*) FROM information_schema.tables WHERE table_schema = '" . DB_NAME . "'");
// Total options
if(function_exists('is_multisite') && is_multisite()){
$aDBc_options_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __('Indicates the total number of rows in your option tables of all your network sites, including transients...','advanced-database-cleaner') ." </span>
</span>";
}else{
$aDBc_options_toolip = "<span class='aDBc-tooltips-headers'>
<img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
<span>" . __('Indicates the total number of rows in your options table, including transients...','advanced-database-cleaner') ." </span>
</span>";
}
// Total options
$aDBc_total_options = 0;
if(function_exists('is_multisite') && is_multisite()){
$blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach($blogs_ids as $blog_id){
switch_to_blog($blog_id);
global $wpdb;
$aDBc_total_options += $wpdb->get_var("SELECT count(*) FROM $wpdb->options");
restore_current_blog();
}
}else{
// Count total options
$aDBc_total_options = $wpdb->get_var("SELECT count(*) FROM $wpdb->options");
}
// Total scheduled tasks
$aDBc_all_tasks = aDBc_get_all_scheduled_tasks();
$aDBc_total_tasks = 0;
if(function_exists('is_multisite') && is_multisite()){
foreach($aDBc_all_tasks as $hook => $task_info){
foreach($task_info['sites'] as $site => $info){
$aDBc_total_tasks += count($task_info['sites'][$site]['args']);
}
}
}else{
foreach($aDBc_all_tasks as $hook => $task_info){
$aDBc_total_tasks += count($task_info['sites'][1]['args']);
}
}
// Is MU?
if(function_exists('is_multisite') && is_multisite()){
$aDBc_is_mu = __('Yes', 'advanced-database-cleaner');
$aDBc_number_sites = $wpdb->get_var("SELECT count(*) FROM $wpdb->blogs");
}else{
$aDBc_is_mu = __('No', 'advanced-database-cleaner');
$aDBc_number_sites = "1";
}
?>
<div class="aDBc-content-max-width">
<div class="aDBc-overview-box">
<div class="aDBc-overview-box-head"><?php _e('Overview', 'advanced-database-cleaner'); ?></div>
<ul>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('WP Version', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo $wp_version ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('Database size', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo $aDBc_db_size ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('Total tables', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo $aDBc_total_tables ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php echo __('Total options', 'advanced-database-cleaner') . $aDBc_options_toolip ?> :
</div>
<div class="aDBc-float-left"><?php echo $aDBc_total_options ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('Total cron tasks', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo $aDBc_total_tasks ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('WP multisite Enabled ?', 'advanced-database-cleaner'); ?>
</div>
<div class="aDBc-float-left"><?php echo $aDBc_is_mu ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('Number of sites', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo $aDBc_number_sites ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('Script Max timeout', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo ADBC_ORIGINAL_TIMEOUT . " ". __('seconds', 'advanced-database-cleaner') ?></div>
</li>
<li>
<div class="aDBc-overview-text-left">
<span class="dashicons dashicons-yes aDBc-overview-dashicon"></span>
<?php _e('Local time', 'advanced-database-cleaner'); ?> :
</div>
<div class="aDBc-float-left"><?php echo date_i18n('Y-m-d H:i:s') ?></div>
</li>
</ul>
</div>
<div class="aDBc-overview-box">
<div class="aDBc-overview-box-head"><?php _e('Settings', 'advanced-database-cleaner') ?></div>
<form action="" method="post">
<ul>
<?php
$aDBc_settings = get_option('aDBc_settings');
$in_main_site_msg = "";
if(is_multisite()){
$in_main_site_msg = __('(In main site only)', 'advanced-database-cleaner');
?>
<li style="padding-top:10px;padding-bottom:10px">
<input type="checkbox" name="aDBc_network_menu" <?php echo (!empty($aDBc_settings['network_menu']) && $aDBc_settings['network_menu'] != "0") ? "checked='checked'" : "" ?>/>
<?php _e('Show network plugin menu', 'advanced-database-cleaner'); ?>
<div class="aDBc-overview-setting-desc">
<?php _e('Displays a menu at the left side of your network admin panel', 'advanced-database-cleaner'); ?>
</div>
</li>
<?php
}
?>
<li style="padding-top:10px;padding-bottom:10px">
<input type="checkbox" name="aDBc_left_menu" <?php echo (!empty($aDBc_settings['left_menu']) && $aDBc_settings['left_menu'] != "0") ? "checked='checked'" : "" ?>/>
<?php echo __('Show plugin left menu', 'advanced-database-cleaner') . ' ' . $in_main_site_msg; ?>
<div class="aDBc-overview-setting-desc">
<?php _e('Displays a menu at the left side of your WP admin', 'advanced-database-cleaner'); ?>
</div>
</li>
<li style="padding-top:10px;padding-bottom:10px">
<input type="checkbox" name="aDBc_menu_under_tools" <?php echo (!empty($aDBc_settings['menu_under_tools']) && $aDBc_settings['menu_under_tools'] != "0") ? "checked='checked'" : "" ?>/>
<?php echo __('Show plugin menu under tools', 'advanced-database-cleaner') . ' ' . $in_main_site_msg;; ?>
<div class="aDBc-overview-setting-desc">
<?php _e('Displays a menu under "tools" menu', 'advanced-database-cleaner'); ?>
</div>
</li>
<?php
if ( ADBC_PLUGIN_PLAN == "free" ) {
?>
<li>
<input type="checkbox" name="aDBc_hide_premium_tab" <?php echo (!empty($aDBc_settings['hide_premium_tab']) && $aDBc_settings['hide_premium_tab']) == '1' ? "checked='checked'" : ""?>/>
<?php _e('Hide premium tab', 'advanced-database-cleaner'); ?>
<div class="aDBc-overview-setting-desc">
<?php _e('If checked, it will hide the above premium tab', 'advanced-database-cleaner'); ?>
</div>
</li>
<?php
}
?>
</ul>
<div id="aDBc_save_settings" class="button-primary aDBc-save-settings">
<span id="aDBc_save_icon" class="dashicons dashicons-saved aDBc-button-icon"></span>
<?php _e( 'Save settings', 'advanced-database-cleaner' ); ?>
</div>
</form>
</div>
<div class="aDBc-clear-both"></div>
</div>

View File

@@ -0,0 +1,111 @@
<!-- style et code ok -->
<div class="aDBc-content-max-width aDBc-margin-t-20">
<div class="aDBc-vertical-box">
<div><?php _e( 'Need more features ?', 'advanced-database-cleaner' ); ?></div>
<div><?php _e( 'Find more advanced features!', 'advanced-database-cleaner' ); ?></div>
<div><img class="aDBc-premium-img" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/features.png'?>"/></div>
<div>
<ul>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Filter & search specific items', 'advanced-database-cleaner' ); ?>
</li>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Detect orphaned options', 'advanced-database-cleaner' ); ?>
</li>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Detect orphaned tables', 'advanced-database-cleaner' ); ?>
</li>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Detect orphaned cron tasks', 'advanced-database-cleaner' ); ?>
</li>
</ul>
</div>
</div>
<div class="aDBc-vertical-box">
<div><?php _e( 'Need support as well ?', 'advanced-database-cleaner' ); ?></div>
<div><?php _e( 'We are available to support you!', 'advanced-database-cleaner' ); ?></div>
<div><img class="aDBc-premium-img" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/help.png'?>"/></div>
<div>
<ul>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Get quick support', 'advanced-database-cleaner' ); ?>
</li>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Get technical support', 'advanced-database-cleaner' ); ?>
</li>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'No additional fees', 'advanced-database-cleaner' ); ?>
</li>
<li>
<span class="dashicons dashicons-yes"></span>
<?php _e( 'Great support service!', 'advanced-database-cleaner' ); ?>
</li>
</ul>
</div>
</div>
<div class="aDBc-vertical-box">
<?php
$product_url = "https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner";
?>
<div>
<a href="<?php echo $product_url; ?>" target="_blank"><?php _e( 'Buy now!', 'advanced-database-cleaner' ); ?></a>
</div>
<div><?php _e( 'Buy now and get all pro features!', 'advanced-database-cleaner' ); ?></div>
<div>
<a href="<?php echo $product_url; ?>" target="_blank">
<img class="aDBc-premium-img" src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/premium_ok.png'?>"/>
</a>
</div>
<div>
<a href="<?php echo $product_url; ?>" target="_blank">
<div class="aDBc-purchase-btn">
<img src="<?php echo ADBC_PLUGIN_DIR_PATH . '/images/order_now.png'?>"/>
</div>
</a>
</div>
</div>
<div class="aDBc-clear-both"></div>
</div>

View File

@@ -0,0 +1,38 @@
<!-- style et code ok -->
<div class="aDBc-sidebar">
<div class="aDBc-upgrade">
<a target="_blank" href="https://sigmaplugin.com/downloads/wordpress-advanced-database-cleaner">
<img src="<?php echo ADBC_PLUGIN_DIR_PATH; ?>/images/premium.svg" />
<h3><?php _e( 'Upgrade to Pro', 'advanced-database-cleaner' ); ?></h3>
<ul>
<li><span class="dashicons dashicons-yes"></span> <?php _e( 'Filter & search specific items', 'advanced-database-cleaner' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php _e( 'Detect orphaned options', 'advanced-database-cleaner' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php _e( 'Detect orphaned tables', 'advanced-database-cleaner' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php _e( 'Detect orphaned cron tasks', 'advanced-database-cleaner' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php _e( 'Premium & technical support', 'advanced-database-cleaner' ); ?></li>
</ul>
<div>
<?php echo __( 'The price will increase soon! Buy now at lower price!', 'advanced-database-cleaner' ); ?>
</div>
</a>
</div>
</div>

View File

@@ -0,0 +1,3 @@
<?php
#Silence is golden.
?>

View File

@@ -0,0 +1,520 @@
jQuery(document).ready(function () {
// Prevent submitting forms via Enter key to prevent any unexpected form submission
jQuery(window).keydown(function (event) {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
});
// x10: After upgrading to WP 5.5, the button of #doaction2 at the button does not work anymore
// This is because when submitting the form below via 'jQuery("#aDBc_form").submit()', the form is sent without the action selected at bottom
// We make sure that both dropdowns have the same values so that the form is sent without issues
jQuery("#bulk-action-selector-bottom").on("change", function (e) {
var abdc_action = jQuery("#bulk-action-selector-bottom").val();
jQuery("#bulk-action-selector-top").val(abdc_action);
});
jQuery("#bulk-action-selector-top").on("change", function (e) {
var abdc_action = jQuery("#bulk-action-selector-top").val();
jQuery("#bulk-action-selector-bottom").val(abdc_action);
});
// Get items type from hidden input in the page
var aDBc_item_type = jQuery("#aDBc_item_type").attr("value");
if (aDBc_item_type == "tables" || aDBc_item_type == "options" || aDBc_item_type == "tasks") {
var iteration = jQuery("#aDBc_iteration").attr("value");
var currently_scanning = jQuery("#aDBc_currently_scanning").attr("value");
// After reload page, check if we should call ajax processing, if so, proceed even before clicking "continue" btn after timeout
if (iteration != "" || currently_scanning != "") {
// Since we continue scan, not need to send parameters
startOrContinueScan("", "");
}
}
jQuery("#aDBc_new_search_button").on("click", function (e) {
e.preventDefault();
// Get counts of all items and uncategorized from hidden inputs
var aDBc_count_all_items = jQuery("#aDBc_count_all_items").attr("value");
var aDBc_count_uncategorized = jQuery("#aDBc_count_uncategorized").attr("value");
// Choose what to show in the dialog box according to the number of items to scan
if (aDBc_count_uncategorized == 0 || aDBc_count_uncategorized == aDBc_count_all_items) {
var aDBc_text = aDBc_ajax_obj.scan_all_only;
var aDBc_scan = aDBc_ajax_obj.all_items2;
} else {
var aDBc_text = aDBc_ajax_obj.scan_all_or_u;
var aDBc_scan = aDBc_ajax_obj.all_items;
}
Swal.fire({
text: aDBc_text,
footer: '<font size="2px" color="grey">' + aDBc_ajax_obj.scan_time_depends + "</font>",
icon: "question",
showCloseButton: true,
showCancelButton: true,
confirmButtonText: aDBc_scan + " (" + aDBc_count_all_items + ")",
confirmButtonColor: "#0085ba",
cancelButtonText: aDBc_ajax_obj.uncategorized + " (" + aDBc_count_uncategorized + ")",
cancelButtonColor: "#555",
// Test if aDBc_count_uncategorized == 0 or aDBc_count_uncategorized == aDBc_count_all_items, disable uncategorized button
onOpen: () => {
if (aDBc_count_uncategorized == 0 || aDBc_count_uncategorized == aDBc_count_all_items) {
jQuery(".swal2-cancel").hide();
}
},
}).then((result) => {
// If the user clicked on "confirm" which is "All items"
if (result.value) {
startOrContinueScan("scan_all", "");
} else if (result.dismiss === Swal.DismissReason.cancel) {
startOrContinueScan("scan_uncategorized", "");
}
});
return false;
});
// This function starts/continue a scan, only one of the two parameters will have a value, the other one will be empty
// If aDBc_scan_type not empty => the user wants to scan all items or uncategorized ones
// if aDBc_items_to_scan not empty => the user want to scan specific selected items
// If both empty => the scan should continue
function startOrContinueScan(aDBc_scan_type, aDBc_items_to_scan) {
// Disable all buttons ont the page to prevent clicking on them + Change scan button
jQuery("#aDBc_new_search_button").attr("value", aDBc_ajax_obj.sentence_scanning);
jQuery("#aDBc_new_search_button").css("background-image", "url(" + aDBc_ajax_obj.images_path + "loading20px.svg)");
jQuery("#aDBc_new_search_button").attr("disabled", true);
// Show progress bar
jQuery("#aDBc-progress-container").show();
jQuery("#aDBc-progress-bar").html("0%");
jQuery.ajax({
type: "post",
url: aDBc_ajax_obj.ajaxurl,
cache: false,
data: {
action: "aDBc_new_run_search_for_items",
aDBc_item_type: aDBc_item_type,
aDBc_scan_type: aDBc_scan_type,
aDBc_items_to_scan: aDBc_items_to_scan,
},
success: function (result) {
jQuery("#aDBc-progress-bar").html("100 %");
jQuery("#aDBc-progress-bar").css("width", "100%");
},
complete: function () {
// wait for 1 sec then reload the page.
setTimeout(function () {
location.reload();
}, 1000);
},
});
setTimeout(getProgress, 500);
}
function getProgress() {
jQuery.ajax({
type: "post",
url: aDBc_ajax_obj.ajaxurl,
data: {
action: "aDBc_get_progress_bar_width",
aDBc_item_type: aDBc_item_type,
},
dataType: "json",
success: function (result) {
var current = result["aDBc_progress"];
var total = result["aDBc_total_items"];
var collected_files = result["aDBc_collected_files"];
var scanned_files = result["aDBc_scanned_files"];
var current_scan_step = result["aDBc_current_scan_step"];
// Update progress bar
var htmlProgress = "<div>";
if (current_scan_step == 1) {
htmlProgress += "<b>Step 1/2</b>";
htmlProgress += " (collecting files to scan";
if (collected_files == 0) {
htmlProgress += "..)";
} else {
htmlProgress += " : " + collected_files + " from " + scanned_files + ")";
}
} else if (current_scan_step == 2) {
htmlProgress += "<b>Step 2/2</b>";
htmlProgress += " (scanning files..)";
}
htmlProgress += "</div>";
jQuery("#aDBc_collected_files").html(htmlProgress);
if (total > 0) {
jQuery("#aDBc-progress-bar").html(parseFloat(current * (100 / total)).toFixed(2) + "%");
jQuery("#aDBc-progress-bar").css("width", parseFloat(current * (100 / total)).toFixed(2) + "%");
}
setTimeout(getProgress, 2000);
},
});
}
// Scan specific selected items
jQuery("#doaction, #doaction2").on("click", function (e) {
// Get action from the clicked button
if (this.id == "doaction") {
var aDBc_action = jQuery("#bulk-action-selector-top").val();
} else if (this.id == "doaction2") {
var aDBc_action = jQuery("#bulk-action-selector-bottom").val();
}
// Get values of top_action and bottom action
var abdc_top_action = jQuery("#bulk-action-selector-top").val();
var abdc_bottom_action = jQuery("#bulk-action-selector-bottom").val();
// Before performing any action, test first if #bulk-action-selector-top and #bulk-action-selector-bottom have the same value as in x10 above
if (abdc_top_action != abdc_bottom_action) {
// Prevent doaction button from its default behaviour
e.preventDefault();
// If values are different, show an error msg
Swal.fire({
icon: "error",
confirmButtonColor: "#0085ba",
showCloseButton: true,
text: aDBc_ajax_obj.unexpected_error,
});
// If no action selected
} else if (aDBc_action == "-1") {
// Prevent doaction button from its default behaviour
e.preventDefault();
// If no actions selected, show an error message
Swal.fire({
icon: "error",
confirmButtonColor: "#0085ba",
showCloseButton: true,
text: aDBc_ajax_obj.select_action,
});
} else {
// Test if the user has checked some items
var aDBc_elements_to_process = [];
// Get all selected items
jQuery('input[name="aDBc_elements_to_process[]"]:checked').each(function () {
aDBc_elements_to_process.push(this.value);
});
// If no items selected, show error message
if (aDBc_elements_to_process.length === 0) {
// Prevent doaction button from its default behaviour
e.preventDefault();
Swal.fire({
icon: "error",
confirmButtonColor: "#0085ba",
showCloseButton: true,
text: aDBc_ajax_obj.no_items_selected,
});
} else {
// Test if the user has selected "scan_selected" action
if (aDBc_action == "scan_selected") {
// Prevent doaction button from its default behaviour if the action is "scan_selected"
e.preventDefault();
// Disable all buttons ont the page to prevent clicking on them + Change scan button
jQuery("#doaction").attr("disabled", true);
jQuery("#doaction2").attr("disabled", true);
startOrContinueScan("", aDBc_elements_to_process);
} else {
// The default warning msg to show is
var message_to_show = aDBc_ajax_obj.clean_items_warning;
// If 'empty' action is selected for tables, override the warning msg
if (aDBc_action == "empty") {
var message_to_show = aDBc_ajax_obj.empty_tables_warning;
}
// We show the warning box msg only when actions such as: delete, clean, empty... are selected
if (aDBc_action == "delete" || aDBc_action == "clean" || aDBc_action == "empty") {
// Prevent doaction button from its default behaviour
e.preventDefault();
Swal.fire({
title: '<font size="4px">' + aDBc_ajax_obj.are_you_sure + "</font>",
text: message_to_show,
footer: '<font size="3px" color="red"><b>' + aDBc_ajax_obj.make_db_backup_first + "</b></font>",
imageUrl: aDBc_ajax_obj.images_path + "alert_delete.svg",
imageWidth: 60,
imageHeight: 60,
showCancelButton: true,
showCloseButton: true,
cancelButtonText: aDBc_ajax_obj.cancel,
cancelButtonColor: "#555",
confirmButtonText: aDBc_ajax_obj.Continue,
confirmButtonColor: "#0085ba",
focusCancel: true,
}).then((result) => {
// If the user clicked on "confirm", submit the form
if (result.value) {
jQuery("#aDBc_form").submit();
}
});
}
}
}
}
});
// Stop the scan
jQuery("#aDBc_stop_scan").on("click", function (e) {
e.preventDefault();
jQuery("#aDBc_stop_scan").hide();
jQuery("#aDBc_stopping_msg").show();
jQuery.ajax({
type: "post",
url: aDBc_ajax_obj.ajaxurl,
cache: false,
data: {
action: "aDBc_stop_search",
security: aDBc_ajax_obj.ajax_nonce,
aDBc_item_type: aDBc_item_type,
},
success: function (result) {},
complete: function () {},
});
//xxx return false;
});
// Actions to do when the user clicks on 'Edit' link to change the 'Keep last' value
jQuery(".aDBc-keep-link").click(function (event) {
var idelement = event.target.id.split("_");
var itemname = idelement[idelement.length - 1];
jQuery("#aDBc_edit_keep_" + itemname).hide();
jQuery("#aDBc_keep_label_" + itemname).hide();
jQuery("#aDBc_keep_input_" + itemname).show();
jQuery("#aDBc_keep_button_" + itemname).show();
jQuery("#aDBc_keep_cancel_" + itemname).show();
jQuery(".aDBc-keep-link").css("pointer-events", "none");
jQuery(".aDBc-keep-link").css("cursor", "default");
jQuery(".aDBc-keep-link").css("color", "#eee");
});
jQuery(".aDBc-keep-cancel-link").click(function (event) {
var idelement = event.target.id.split("_");
var itemname = idelement[idelement.length - 1];
jQuery("#aDBc_keep_input_" + itemname).hide();
jQuery("#aDBc_keep_button_" + itemname).hide();
jQuery("#aDBc_keep_cancel_" + itemname).hide();
jQuery("#aDBc_edit_keep_" + itemname).show();
jQuery("#aDBc_keep_label_" + itemname).show();
jQuery(".aDBc-keep-link").css("pointer-events", "");
jQuery(".aDBc-keep-link").css("cursor", "pointer");
jQuery(".aDBc-keep-link").css("color", "");
});
// Save settings in "Overview & Settings"
jQuery("#aDBc_save_settings").on("click", function (e) {
e.preventDefault();
showProcessingMsgBox(aDBc_ajax_obj.please_wait);
// Get checkboxes values
const left_menu = jQuery('input[name="aDBc_left_menu"]').is(":checked") ? "1" : "0";
const menu_under_tools = jQuery('input[name="aDBc_menu_under_tools"]').is(":checked") ? "1" : "0";
const network_menu = jQuery('input[name="aDBc_network_menu"]').is(":checked") ? "1" : "0"; // Only for multi-site
const hide_premium_tab = jQuery('input[name="aDBc_hide_premium_tab"]').is(":checked") ? "1" : "0";
jQuery.ajax({
type: "post",
url: aDBc_ajax_obj.ajaxurl,
cache: false,
data: {
action: "aDBc_save_settings_callback",
security: aDBc_ajax_obj.ajax_nonce,
left_menu: left_menu,
menu_under_tools: menu_under_tools,
network_menu: network_menu,
hide_premium_tab: hide_premium_tab,
},
success: function (result) {
// Show success/error message
if (true === result.success) {
Swal.fire({
icon: "success",
showConfirmButton: false,
});
// Check if we're on the network admin page and conditions are met, redirect to the main network admin page
setTimeout(function () {
const isNetworkAdmin = window.location.href.indexOf(aDBc_ajax_obj.network_admin_url) !== -1;
const shouldRedirectToNetworkAdmin =
aDBc_ajax_obj.is_multisite == "1" &&
((isNetworkAdmin && network_menu == "0") ||
(!isNetworkAdmin && left_menu == "0" && menu_under_tools == "0"));
if (shouldRedirectToNetworkAdmin) {
// Redirect to the network admin page.
window.location.href = aDBc_ajax_obj.network_admin_url;
} else {
// Otherwise, reload the current page.
location.reload();
}
}, 1000);
} else {
Swal.fire({
html: '<font size="3px">' + result.data + "</font>",
icon: "error",
});
}
},
complete: function () {},
});
});
/*****************************************************************************
*
* Activate / deactivate / check license
*
******************************************************************************/
jQuery("#aDBc_activate_license_btn, #aDBc_deactivate_license_btn, #aDBc_check_license_btn").on("click", function (e) {
e.preventDefault();
showProcessingMsgBox(aDBc_ajax_obj.please_wait);
// Get action from the clicked button
var aDBc_edd_action = this.id;
// Get license
var license_key = jQuery.trim(jQuery("#aDBc_license_key_input").val());
jQuery.ajax({
type: "post",
url: aDBc_ajax_obj.ajaxurl,
cache: false,
data: {
action: "aDBc_license_actions_callback",
security: aDBc_ajax_obj.ajax_nonce,
aDBc_edd_action: aDBc_edd_action,
license_key: license_key,
},
success: function (result) {
// Show success/error message
if (true === result.success) {
if (aDBc_edd_action == "aDBc_activate_license_btn") {
jQuery(".aDBc-please-activate-msg").hide();
jQuery("#aDBc_license_status").text(aDBc_ajax_obj.active);
jQuery("#aDBc_license_status").css("color", "green");
jQuery("#aDBc_check_license_btn").show();
jQuery("#aDBc_activate_license_btn").hide();
jQuery("#aDBc_deactivate_license_btn").show();
jQuery("#aDBc_license_key_input").val(license_key.substring(0, 4) + "************************" + license_key.slice(-4));
jQuery("#aDBc_license_key_input").prop("disabled", true);
} else if (aDBc_edd_action == "aDBc_deactivate_license_btn") {
jQuery(".aDBc-please-activate-msg").show();
jQuery("#aDBc_license_status").text(aDBc_ajax_obj.inactive);
jQuery("#aDBc_license_status").css("color", "red");
jQuery("#aDBc_check_license_btn").hide();
jQuery("#aDBc_activate_license_btn").show();
jQuery("#aDBc_deactivate_license_btn").hide();
jQuery("#aDBc_license_key_input").val("");
jQuery("#aDBc_license_key_input").prop("disabled", false);
}
Swal.fire({
icon: "success",
html: '<font size="3px">' + result.data + "</font>",
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
});
} else {
Swal.fire({
html: '<font size="3px">' + result.data + "</font>",
icon: "error",
});
}
},
complete: function () {},
});
});
/*****************************************************************************
*
* Shows a "processing" msg when performing an action
*
******************************************************************************/
function showProcessingMsgBox(msgToShow) {
Swal.fire({
html: '<font size="3px">' + msgToShow + "</font>",
imageUrl: aDBc_ajax_obj.images_path + "loading20px.svg",
imageWidth: 50,
imageHeight: 50,
showCloseButton: false,
showConfirmButton: false,
allowOutsideClick: false,
});
}
/*****************************************************************************
*
* Dismiss rating notice
*
* ***************************************************************************/
jQuery('#aDBc-dismiss-rating-notice').on("click", function (e) {
e.preventDefault();
// Get URL directly from the href attribute
var dismissUrl = jQuery(this).attr('href');
// Send AJAX request to the dismissal URL
jQuery.get(dismissUrl);
// Hide the notice
jQuery("#aDBc-rating-notice").fadeOut();
});
/*****************************************************************************
*
* Dismiss 'not categorized yet' notice msg
*
* ***************************************************************************/
jQuery('#aDBc-dismiss-not-categorized-yet-msg').on("click", function (e) {
e.preventDefault();
// Hide the notice
jQuery("#aDBc-box-info").fadeOut();
jQuery.ajax({
type: "post",
url: aDBc_ajax_obj.ajaxurl,
cache: false,
data: {
action: "aDBc_hide_not_categorized_yet_msg",
security: aDBc_ajax_obj.ajax_nonce
},
success: function (result) {},
complete: function () {},
});
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff