├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── composer.json
├── readme.txt
├── uninstall.php
├── wp-spider-cache.php
└── wp-spider-cache
├── assets
├── css
│ └── spider-cache.css
├── img
│ ├── spinner-2x.gif
│ └── spinner.gif
└── js
│ └── spider-cache.js
├── drop-ins
├── advanced-cache.php
└── object-cache.php
└── includes
├── class-object-base.php
├── class-object-cache.php
├── class-object-memcached.php
├── class-object-memory.php
├── class-object-redis.php
├── class-output-cache.php
├── class-var-dump.php
└── functions.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [6.0.1] - 2021-05-29
2 | * Update author info
3 |
4 | ## [6.0.0] - 2017-05-20
5 | * UI for copying drop-ins
6 |
7 | ## [5.0.0] - 2017-04-03
8 | * Updated signup and signupmeta global cache groups
9 |
10 | ## [4.1.0] - 2016-11-20
11 | * General code improvements
12 |
13 | ## [4.0.0] - 2016-10-24
14 | * Add support for global LudicrousDB cache group
15 |
16 | ## [3.4.0] - 2016-10-18
17 | * Fix key & group deletion from UI
18 | * Move BuddyPress cache-groups to root site of network
19 |
20 | ## [3.3.0] - 2016-10-07
21 | * Prevent fatal errors on WordPress 4.7
22 | * Bump minimum WordPress version to 4.7
23 |
24 | ## 3.2.0 (2016-09-22)
25 | * Prevent fatals if packaged drop-ins are not used
26 | * Prevent fatal errors if supported back-ends are not installed
27 |
28 | ## 3.0.3 (2016-08-22)
29 | * Yield to XDebug if enabled
30 | * Improve output of pretty var_dump
31 |
32 | ## 3.0.2 (2016-08-22)
33 | * Use correct callback functions
34 |
35 | ## 3.0.1 (2016-08-21)
36 | * Fix bug relating to Thickbox refresh
37 |
38 | ## 3.0.0 (2016-08-21)
39 | * Improved cache view using Thickbox
40 |
41 | ## 2.2.1 (2016-07-29)
42 | * Asset bump
43 |
44 | ## 2.2.0 (2016-07-29)
45 | * Refactoring throughout
46 | * Adding caps
47 | * Cache exempt cookie
48 |
49 | ## 2.1.1 (2016-02-15)
50 | * Sanity checks for Memcached & drop-ins
51 |
52 | ## 2.1.0 (2016-02-15)
53 | * Refactor drop-ins
54 | * More accurate debug times
55 | * More protective method scopes
56 | * Better output cache encapsulation
57 | * Rename a few old functions
58 |
59 | ## 2.0.0 (2016-02-15)
60 | * Initial release
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WP Spider Cache
2 |
3 | WP Spider Cache is your friendly neighborhood caching solution for WordPress. It uses Memcached to store both objects & page output.
4 |
5 | If you are familiar with Batcache and WP Super Cache, you'll be right at home here.
6 |
7 | It comes with:
8 | * Support for registering multiple Memcached backend servers
9 | * An administration interface for viewing cache data
10 | * Ability to flush specific keys & groups
11 | * Drop-in plugins for `object-cache.php` & `advanced-cache.php`
12 |
13 | # Installation
14 |
15 | * Download and install using the built in WordPress plugin installer.
16 | * Copy contents of `drop-ins` to your `wp-content` directory
17 | * Activate in the "Plugins" area of your `wp-admin` by clicking the "Activate" link.
18 | * Consider sponsoring future development by clicking "Sponsor".
19 | * No further setup or configuration is necessary.
20 |
21 | # FAQ
22 |
23 | ### Does this work with on single-site, multi-site, and multi-network installations?
24 |
25 | Yes. Yes. Yes.
26 |
27 | ### Does this work with BuddyPress, bbPress, and GlotPress?
28 |
29 | Yes. Yes. Yes.
30 |
31 | ### What other plugins has this been tested with?
32 |
33 | * EasyDigitalDownloads
34 | * WooCommerce
35 | * Jetpack
36 | * All Stuttter plugins
37 | * Keyring
38 | * User Switching
39 |
40 | ### Credits
41 |
42 | This plugin is largely inspired by:
43 |
44 | * Memcached
45 | * Batcache
46 | * Super Cache
47 | * Johnny Cache
48 |
49 | ### Where can I get support?
50 |
51 | This plugin is free for anyone to use.
52 |
53 | * Community: https://wordpress.org/support/plugin/wp-spider-cache
54 | * Development: https://github.com/stuttter/wp-spider-cache/discussions
55 |
56 | If you require immediate assistance, please consider a paid support subscription.
57 |
58 | ### Contributing
59 |
60 | Please [open a new issue](/pull/new/master) to discuss whether the feature is a good fit for the project. Once you've decided to work on a pull request, please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/).
61 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stuttter/wp-spider-cache",
3 | "description": "Your friendly neighborhood caching solution for WordPress",
4 | "homepage": "https://github.com/stuttter/wp-spider-cache",
5 | "type": "wordpress-plugin",
6 | "require": {
7 | "php": ">=5.2",
8 | "composer/installers": "^1.0"
9 | },
10 | "license": "GPL-2.0-or-later",
11 | "authors": [
12 | {
13 | "name": "John James Jacoby",
14 | "email": "johnjamesjacoby@me.com"
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === WP Spider Cache ===
2 | Author: Triple J Software, Inc.
3 | Author URI: https://jjj.software
4 | Donate link: https://buy.stripe.com/7sI3cd2tK1Cy2lydQR
5 | Plugin URI: https://wordpress.org/plugins/wp-spider-cache
6 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
7 | License: GPLv2 or later
8 | Contributors: johnjamesjacoby
9 | Tags: cache, memcache, memcached, object, output
10 | Requires PHP: 7.2
11 | Requires at least: 5.2
12 | Tested up to: 5.8
13 | Stable tag: 6.0.1
14 |
15 | == Description ==
16 |
17 | WP Spider Cache is your friendly neighborhood caching solution for WordPress. It uses Memcached to store both objects & page output.
18 |
19 | It is heroic like Batcache & Super Cache, but younger, faster, and a natural web-slinger.
20 |
21 | It comes with:
22 |
23 | * Support for registering multiple cache servers
24 | * An administration interface for viewing cache data
25 | * Ability to flush specific keys & groups
26 | * Drop-in plugins for `object-cache.php` & `advanced-cache.php`
27 |
28 | = Also checkout =
29 |
30 | Admin:
31 |
32 | * [WP Chosen](https://wordpress.org/plugins/wp-chosen/ "Make long, unwieldy select boxes much more user-friendly.")
33 | * [WP Comment Humility](https://wordpress.org/plugins/wp-comment-humility/ "Move the "Comments" menu underneath 'Posts'.")
34 | * [WP Pretty Filters](https://wordpress.org/plugins/wp-pretty-filters/ "Make all filters match the Media & Attachments interface.")
35 | * [WP Reset Filters](https://wordpress.org/plugins/wp-reset-filters/ "Adds a "Reset" button to all admin area filters.")
36 |
37 | Media:
38 |
39 | * [WP Media Categories](https://wordpress.org/plugins/wp-media-categories/ "Add categories to media & attachments.")
40 |
41 | Multisite:
42 |
43 | * [WP Multi Network](https://wordpress.org/plugins/wp-multi-network/ "Create many networks of many sites with any domains.")
44 | * [WP Site Aliases](https://wordpress.org/plugins/wp-site-aliases/ "Create many networks of many sites with any domains.")
45 |
46 | Posts:
47 |
48 | * [WP Article Order](https://wordpress.org/plugins/wp-article-order/ "Move articles to the end of post titles.")
49 |
50 | System:
51 |
52 | * [LudicrousDB](https://wordpress.org/plugins/ludicrousdb/ "Minifies & concatenates enqueued scripts & styles.")
53 | * [WP Enqueue Masher](https://wordpress.org/plugins/wp-enqueue-masher/ "Minifies & concatenates enqueued scripts & styles.")
54 | * [WP Spider Cache](https://wordpress.org/plugins/wp-spider-cache/ "Your friendly neighborhood caching solution for WordPress.")
55 |
56 | Terms:
57 |
58 | * [WP Term Authors](https://wordpress.org/plugins/wp-term-authors/ "Authors for categories, tags, and other taxonomy terms.")
59 | * [WP Term Colors](https://wordpress.org/plugins/wp-term-colors/ "Pretty colors for categories, tags, and other taxonomy terms.")
60 | * [WP Term Families](https://wordpress.org/plugins/wp-term-families/ "Associate taxonomy terms with other taxonomy terms.")
61 | * [WP Term Icons](https://wordpress.org/plugins/wp-term-icons/ "Pretty icons for categories, tags, and other taxonomy terms.")
62 | * [WP Term Images](https://wordpress.org/plugins/wp-term-images/ "Pretty images for categories, tags, and other taxonomy terms.")
63 | * [WP Term Locks](https://wordpress.org/plugins/wp-term-locks/ "Protect categories, tags, and other taxonomy terms from being edited or deleted.")
64 | * [WP Term Order](https://wordpress.org/plugins/wp-term-order/ "Sort taxonomy terms, your way.")
65 | * [WP Term Visibility](https://wordpress.org/plugins/wp-term-visibility/ "Visibilities for categories, tags, and other taxonomy terms.")
66 |
67 | Users:
68 |
69 | * [WP User Activity](https://wordpress.org/plugins/wp-user-activity/ "The best way to log activity in WordPress.")
70 | * [WP User Alerts](https://wordpress.org/plugins/wp-user-alerts/ "Send alerts to users when new posts are published.")
71 | * [WP User Avatars](https://wordpress.org/plugins/wp-user-avatars/ "Allow users to upload avatars or choose them from your media library.")
72 | * [WP User Groups](https://wordpress.org/plugins/wp-user-groups/ "Group users together with taxonomies & terms.")
73 | * [WP User Parents](https://wordpress.org/plugins/wp-user-parents/ "A user hierarchy for WordPress user accounts.")
74 | * [WP User Preferences](https://wordpress.org/plugins/wp-user-preferences/ "Cascading user options with intelligent defaults.")
75 | * [WP User Profiles](https://wordpress.org/plugins/wp-user-profiles/ "A sophisticated way to edit users in WordPress.")
76 | * [WP User Signups](https://wordpress.org/plugins/wp-user-signups/ "An interface for managing user signups.")
77 | * [WP User Tagline](https://wordpress.org/plugins/wp-user-tagline/ "Allow users to give themselves unique taglines.")
78 | * [WP User Title](https://wordpress.org/plugins/wp-user-title/ "Allow users to give themselves unique titles.")
79 |
80 | = Credits =
81 |
82 | This plugin is largely inspired by:
83 |
84 | * Memcached
85 | * Batcache
86 | * Super Cache
87 | * Johnny Cache
88 |
89 | == Screenshots ==
90 |
91 | 1. Admin UI
92 | 2. Servers
93 | 3. Data View
94 |
95 | == Installation ==
96 |
97 | * Download and install using the built in WordPress plugin installer.
98 | * Copy contents of `drop-ins` to your `wp-content` directory
99 | * Activate in the "Plugins" area of your admin by clicking the "Activate" link.
100 | * No further setup or configuration is necessary.
101 |
102 | == Frequently Asked Questions ==
103 |
104 | = Does this work with on single-site, multi-site, and multi-network installations? =
105 |
106 | Yes. Yes. Yes.
107 |
108 | = Does this work with BuddyPress, bbPress, and GlotPress? =
109 |
110 | Yes. Yes. Yes.
111 |
112 | = What other plugins has this been tested with? =
113 |
114 | * Easy Digital Downloads
115 | * Jetpack
116 | * Keyring
117 | * User Switching
118 | * WooCommerce
119 |
120 | = Where can I get support? =
121 |
122 | * Community: https://wordpress.org/support/plugin/wp-spider-cache
123 | * Development: https://github.com/stuttter/wp-spider-cache/discussions
124 |
125 | == Changelog ==
126 |
127 | = [6.0.1] - 2021-05-29 =
128 | * Update author info
129 |
130 | = [6.0.0] - 2017-05-20 =
131 | * UI for copying drop-ins
132 |
133 | = [5.0.0] - 2017-04-03 =
134 | * Updated signup and signupmeta global cache groups
135 |
136 | = [4.1.0] - 2016-11-20 =
137 | * General code improvements
138 |
139 | = [4.0.0] - 2016-10-24 =
140 | * Add support for global LudicrousDB cache group
141 |
142 | = [3.4.0] - 2016-10-18 =
143 | * Fix key & group deletion from UI
144 | * Move BuddyPress cache-groups to root site of network
145 |
146 | = [3.3.0] - 2016-10-07 =
147 | * Prevent fatal errors on WordPress 4.7
148 | * Bump minimum WordPress version to 4.7
149 |
150 | = [3.2.0] - 2016-09-22 =
151 | * Prevent fatal errors if packaged drop-ins are not used
152 | * Prevent fatal errors if supported back-ends are not installed
153 |
154 | = [3.1.0] - 2016-09-08 =
155 | * Add extended global cache groups
156 |
157 | = [3.0.3] - 2016-08-22 =
158 | * Yield to XDebug if enabled
159 | * Improve output of pretty var_dump
160 |
161 | = [3.0.2] - 2016-08-22 =
162 | * Use correct callback functions
163 |
164 | = [3.0.1] - 2016-08-21 =
165 | * Fix bug relating to Thickbox refresh
166 |
167 | = [3.0.0] - 2016-08-21 =
168 | * Improved cache view using Thickbox
169 |
170 | = [2.2.1] - 2016-07-29 =
171 | * Asset bump
172 |
173 | = [2.2.0] - 2016-07-29 =
174 | * Refactoring throughout
175 | * Adding caps
176 | * Cache exempt cookie
177 |
178 | = [2.1.1] - 2016-02-15 =
179 | * Sanity checks for Memcached & drop-ins
180 |
181 | = [2.1.0] - 2016-02-15 =
182 | * Refactor drop-ins
183 | * More accurate debug times
184 | * More protective method scopes
185 | * Better output cache encapsulation
186 | * Rename a few old functions
187 |
188 | = [2.0.0] - 2016-02-15 =
189 | * Initial release
190 |
--------------------------------------------------------------------------------
/uninstall.php:
--------------------------------------------------------------------------------
1 | delete( WP_CONTENT_DIR . '/object-cache.php' );
20 | }
21 | }
22 |
23 | // Output cache
24 | if ( file_exists( WP_CONTENT_DIR . '/advanced-cache.php' ) ) {
25 |
26 | // Flush the entire cache before procedeing
27 | wp_cache_flush();
28 |
29 | // Delete
30 | if ( WP_Filesystem( request_filesystem_credentials( '' ) ) ) {
31 | $wp_filesystem->delete( WP_CONTENT_DIR . '/advanced-cache.php' );
32 | }
33 | }
34 |
35 | // End & clean the buffer
36 | ob_end_clean();
37 |
--------------------------------------------------------------------------------
/wp-spider-cache.php:
--------------------------------------------------------------------------------
1 | hook = add_menu_page(
193 | esc_html__( 'Spider Cache', 'wp-spider-cache' ),
194 | esc_html__( 'Spider Cache', 'wp-spider-cache' ),
195 | 'manage_cache', // Single-site admins and multi-site super admins
196 | 'wp-spider-cache',
197 | array( $this, 'page' ),
198 | 'dashicons-editor-code'
199 | );
200 |
201 | // Load page on hook
202 | add_action( "load-{$this->hook}", array( $this, 'load' ) );
203 | add_action( "load-{$this->hook}", array( $this, 'help' ) );
204 | }
205 |
206 | /**
207 | * Enqueue assets
208 | *
209 | * @since 2.0.0
210 | */
211 | public function admin_enqueue() {
212 |
213 | // Bail if not this page
214 | if ( $GLOBALS['page_hook'] !== $this->hook ) {
215 | return;
216 | }
217 |
218 | // Setup the plugin URL, for enqueues
219 | $this->asset_url = plugin_dir_url( __FILE__ ) . 'wp-spider-cache/';
220 |
221 | // Enqueue
222 | wp_enqueue_style( 'wp-spider-cache', $this->asset_url . 'assets/css/spider-cache.css', array(), $this->asset_version );
223 | wp_enqueue_script( 'wp-spider-cache', $this->asset_url . 'assets/js/spider-cache.js', array( 'jquery' ), $this->asset_version, true );
224 |
225 | // Localize JS
226 | wp_localize_script( 'wp-spider-cache', 'WP_Spider_Cache', array(
227 | 'no_results' => $this->get_no_results_row(),
228 | 'refreshing_results' => $this->get_refreshing_results_row()
229 | ) );
230 | }
231 |
232 | /**
233 | * Map `manage_cache` capability
234 | *
235 | * @since 2.3.0
236 | *
237 | * @param array $caps
238 | * @param string $cap
239 | */
240 | public function map_meta_cap( $caps = array(), $cap = '' ) {
241 |
242 | // Map single-site cap check to 'manage_options'
243 | if ( 'manage_cache' === $cap ) {
244 | if ( ! is_multisite() ) {
245 | $caps = array( 'manage_options' );
246 | }
247 | }
248 |
249 | // Return maybe-mapped caps
250 | return $caps;
251 | }
252 |
253 | /**
254 | * Maybe copy a drop-in plugin based on user request
255 | *
256 | * @since 6.0.0
257 | *
258 | * @param bool $redirect
259 | */
260 | private function maybe_copy_drop_in( $redirect = true ) {
261 |
262 | // Bail if not copying or missing nonce
263 | if ( empty( $_GET['copy'] ) || empty( $_GET['nonce'] ) ) {
264 | return;
265 | }
266 |
267 | // Sanitize action
268 | $which = sanitize_key( $_GET['copy'] );
269 |
270 | // Check which to copy, or bail
271 | if ( 'object' === $which ) {
272 | $dest = WP_CONTENT_DIR . '/object-cache.php';
273 | $source = plugin_dir_path( __FILE__ ) . 'wp-spider-cache/drop-ins/object-cache.php';
274 | } elseif ( 'output' === $which ) {
275 | $dest = WP_CONTENT_DIR . '/advanced-cache.php';
276 | $source = plugin_dir_path( __FILE__ ) . 'wp-spider-cache/drop-ins/advanced-cache.php';
277 | } else {
278 | return;
279 | }
280 |
281 | // Bail if under version control
282 | if ( true === $this->vcs ) {
283 | return;
284 | }
285 |
286 | // Try to copy
287 | if ( wp_verify_nonce( $_GET['nonce'], self::FILE_NONCE ) ) {
288 | $copied = copy( $source, $dest )
289 | ? 'success'
290 | : 'failed';
291 | } else {
292 | $copied = 'failed';
293 | }
294 |
295 | // Bail if no redirect
296 | if ( false === $redirect ) {
297 | return;
298 | }
299 |
300 | // Assemble the URL
301 | $url = add_query_arg( array(
302 | 'copied' => $copied,
303 | ), menu_page_url( 'wp-spider-cache', false ) );
304 |
305 | // Redirect
306 | wp_safe_redirect( $url );
307 | exit();
308 | }
309 |
310 | /**
311 | * Maybe clear a cache group, based on user request
312 | *
313 | * @since 2.0.0
314 | *
315 | * @param bool $redirect
316 | */
317 | private function maybe_clear_cache_group( $redirect = true ) {
318 |
319 | // Bail if not clearing
320 | if ( empty( $_GET['cache_group'] ) ) {
321 | return;
322 | }
323 |
324 | // Sanitize cache group to clear
325 | $group = $this->sanitize_key( $_GET['cache_group'] );
326 |
327 | // Clear the cache group
328 | $cleared = $this->clear_group( $group );
329 |
330 | // Bail if not redirecting
331 | if ( false === $redirect ) {
332 | return;
333 | }
334 |
335 | // Assemble the URL
336 | $url = add_query_arg( array(
337 | 'type' => 'group',
338 | 'keys_cleared' => $cleared,
339 | 'cache_cleared' => $group
340 | ), menu_page_url( 'wp-spider-cache', false ) );
341 |
342 | // Redirect
343 | wp_safe_redirect( $url );
344 | exit();
345 | }
346 |
347 | /**
348 | * Maybe clear a user's entire cache, based on user request
349 | *
350 | * @since 2.0.0
351 | *
352 | * @param bool $redirect
353 | */
354 | private function maybe_clear_user_cache( $redirect = true ) {
355 |
356 | // Clear user ID
357 | if ( empty( $_GET['user_id'] ) ) {
358 | return;
359 | }
360 |
361 | // How are we getting the user?
362 | if ( is_numeric( $_GET['user_id'] ) ) {
363 | $by = 'id';
364 | } elseif ( is_email( $_GET['user_id'] ) ) {
365 | $by = 'email';
366 | } elseif ( is_string( $_GET['user_id'] ) ) {
367 | $by = 'slug';
368 | } else {
369 | $by = 'login';
370 | }
371 |
372 | // Get the user
373 | $_user = get_user_by( $by, $_GET['user_id'] );
374 |
375 | // Bail if no user found
376 | if ( empty( $_user ) ) {
377 | return;
378 | }
379 |
380 | $cleared = array();
381 |
382 | // Delete user caches
383 | $cleared[] = wp_cache_delete( $_user->ID, 'users' );
384 | $cleared[] = wp_cache_delete( $_user->ID, 'usermeta' );
385 | $cleared[] = wp_cache_delete( $_user->ID, 'user_meta' );
386 | $cleared[] = wp_cache_delete( $_user->user_login, 'userlogins' );
387 | $cleared[] = wp_cache_delete( $_user->user_nicename, 'userslugs' );
388 | $cleared[] = wp_cache_delete( $_user->user_email, 'useremail' );
389 | $cleared[] = wp_cache_delete( $_user->user_email, 'signups' );
390 | $cleared[] = wp_cache_delete( $_user->user_email, 'signup_meta' );
391 |
392 | // Bail if not redirecting
393 | if ( false === $redirect ) {
394 | return;
395 | }
396 |
397 | // Assemble the URL
398 | $url = add_query_arg( array(
399 | 'type' => 'user',
400 | 'keys_cleared' => count( array_filter( $cleared ) ),
401 | 'cache_cleared' => $_user->ID
402 | ), menu_page_url( 'wp-spider-cache', false ) );
403 |
404 | // Redirect
405 | wp_safe_redirect( $url );
406 | exit();
407 | }
408 |
409 | /**
410 | * Check for network activation and init to add menu item.
411 | *
412 | * @since 2.2.0
413 | */
414 | public function set_blog_ids() {
415 |
416 | // Sanitize type
417 | $type = ! empty( $_POST['type'] )
418 | ? sanitize_key( $_POST['type'] )
419 | : '';
420 |
421 | // Set blog IDs
422 | switch ( $type ) {
423 | case 'user' :
424 | case 'network' :
425 | $this->blog_ids = array( 0 );
426 | break;
427 | case 'blog' :
428 | case '' :
429 | $this->blog_ids = array( get_current_blog_id() );
430 | break;
431 | }
432 | }
433 |
434 | /**
435 | * Custom cache key separator
436 | *
437 | * @since 5.0.0
438 | */
439 | public function set_separator() {
440 |
441 | // Use from object cache
442 | $this->cache_key_separator = function_exists( 'wp_object_cache' )
443 | ? wp_object_cache()->cache_key_separator
444 | : ':';
445 |
446 | // Fallback support, incase it's empty
447 | if ( empty( $this->cache_key_separator ) ) {
448 | $this->cache_key_separator = ':';
449 | }
450 | }
451 |
452 | /**
453 | * Helper function to check nonce and avoid caching the request
454 | *
455 | * @since 2.0.0
456 | *
457 | * @param string $nonce
458 | */
459 | private function check_nonce( $nonce = '' ) {
460 | check_ajax_referer( $nonce , 'nonce' );
461 |
462 | nocache_headers();
463 | }
464 |
465 | /**
466 | * Attempt to output the server cache contents
467 | *
468 | * @since 2.0.0
469 | */
470 | public function ajax_get_instance() {
471 | $this->check_nonce( self::INSTANCE_NONCE );
472 |
473 | // Attempt to output the server contents
474 | if ( empty( $_POST['name'] ) ) {
475 | wp_die( -1 );
476 | }
477 |
478 | // Get memcache data
479 | $server = filter_var( $_POST['name'], FILTER_VALIDATE_IP );
480 | $this->set_blog_ids();
481 | $this->set_separator();
482 | $this->do_rows( $server );
483 |
484 | wp_die();
485 | }
486 |
487 | /**
488 | * Delete all cache keys in a cache group
489 | *
490 | * @since 2.0.0
491 | */
492 | public function ajax_flush_group() {
493 | $this->check_nonce( self::FLUSH_NONCE );
494 |
495 | // Bail if missing keys or group
496 | if ( empty( $_POST['keys'] ) || empty( $_GET['group'] ) ) {
497 | wp_die( $_POST );
498 | }
499 |
500 | // Decode group
501 | $g_code = base64_decode( $_GET['group'] );
502 | $keys = array();
503 |
504 | // Loop through ajax posted keys and attempt to delete them
505 | foreach ( $_POST['keys'] as $key ) {
506 |
507 | // Decode key
508 | $k_code = base64_decode( $key );
509 |
510 | // Deleted
511 | $deleted = wp_cache_delete(
512 | $this->sanitize_key( $k_code ),
513 | $this->sanitize_key( $g_code )
514 | );
515 |
516 | $keys[] = array(
517 | 'group' => $g_code,
518 | 'id' => $k_code,
519 | 'code' => $key,
520 | 'result' => $deleted
521 | );
522 | }
523 |
524 | // Pass keys
525 | wp_die( json_encode( array(
526 | 'success' => ! empty( $keys ),
527 | 'keys' => $keys
528 | ) ) );
529 | }
530 |
531 | /**
532 | * Delete a single cache key in a specific group
533 | *
534 | * @since 2.0.0
535 | */
536 | public function ajax_remove_item() {
537 | $this->check_nonce( self::REMOVE_NONCE );
538 |
539 | // Delete a key in a group
540 | if ( empty( $_GET['key'] ) || empty( $_GET['group'] ) ) {
541 | wp_die( -1 );
542 | }
543 |
544 | // Decode
545 | $k_code = base64_decode( $_GET['key'] );
546 | $g_code = base64_decode( $_GET['group'] );
547 |
548 | // Delete cache
549 | $deleted = wp_cache_delete(
550 | $this->sanitize_key( $k_code ),
551 | $this->sanitize_key( $g_code )
552 | );
553 |
554 | // Pass keys
555 | wp_die( json_encode( array(
556 | 'success' => $deleted,
557 | 'key' => $k_code,
558 | 'group' => $g_code
559 | ) ) );
560 | }
561 |
562 | /**
563 | * Attempt to get a cached item
564 | *
565 | * @since 2.0.0
566 | */
567 | public function ajax_get_item() {
568 | $this->check_nonce( self::GET_NONCE );
569 |
570 | // Bail if invalid posted data
571 | if ( empty( $_GET['key'] ) || empty( $_GET['group'] ) ) {
572 | wp_die( -1 );
573 | }
574 |
575 | // Decode
576 | $k_code = base64_decode( $_GET['key'] );
577 | $g_code = base64_decode( $_GET['group'] );
578 |
579 | // Get the item
580 | $this->do_item(
581 | $this->sanitize_key( $k_code ),
582 | $this->sanitize_key( $g_code )
583 | );
584 |
585 | wp_die();
586 | }
587 |
588 | /**
589 | * Clear all of the items in a cache group
590 | *
591 | * @since 2.0.0
592 | *
593 | * @param string $group
594 | * @return int
595 | */
596 | public function clear_group( $group = '' ) {
597 |
598 | // Setup counter
599 | $cleared = 0;
600 | $servers = $this->get_servers();
601 |
602 | // Loop through servers
603 | foreach ( $servers as $server ) {
604 | $port = empty( $server[1] ) ? 11211 : $server['port'];
605 | $list = $this->retrieve_keys( $server['host'], $port );
606 |
607 | // Loop through items
608 | foreach ( $list as $item ) {
609 | if ( strstr( $item, "{$group}:" ) ) {
610 | wp_cache_delete( $item, $group );
611 | $cleared++;
612 | }
613 | }
614 | }
615 |
616 | // Return count
617 | return $cleared;
618 | }
619 |
620 | /**
621 | * Check for actions
622 | *
623 | * @since 2.0.0
624 | */
625 | public function load() {
626 |
627 | // Set drop-ins state
628 | $this->drop_ins = array(
629 | 'output' => file_exists( WP_CONTENT_DIR . '/advanced-cache.php' ),
630 | 'object' => file_exists( WP_CONTENT_DIR . '/object-cache.php' )
631 | );
632 |
633 | // Include the automatic updater
634 | if ( ! class_exists( 'WP_Automatic_Updater' ) ) {
635 | include ABSPATH . 'wp-admin/includes/class-wp-automatic-updater.php';
636 | }
637 |
638 | /*
639 | * Avoid messing with VCS installs, at least for now.
640 | * Noted: this is not the ideal way to accomplish this.
641 | */
642 | if ( class_exists( 'WP_Automatic_Updater' ) ) {
643 | $check_vcs = new WP_Automatic_Updater;
644 | $this->vcs = $check_vcs->is_vcs_checkout( __DIR__ );
645 | }
646 |
647 | // Maybe execute user actions
648 | $this->maybe_copy_drop_in( true );
649 | $this->maybe_clear_cache_group( true );
650 | $this->maybe_clear_user_cache( true );
651 | }
652 |
653 | /**
654 | * Help text
655 | *
656 | * @since 2.1.0
657 | */
658 | public function help() {
659 |
660 | // Overview
661 | get_current_screen()->add_help_tab( array(
662 | 'id' => 'overview',
663 | 'title' => esc_html__( 'Overview', 'wp-spider-cache' ),
664 | 'content' =>
665 | '
' . esc_html__( 'All the cached objects and output is listed alphabetically in Spider Cache, starting with global groups and ending with this specific site.', 'wp-spider-cache' ) . '
' .
666 | '
' . esc_html__( 'You can narrow the list by searching for specific group & key names.', 'wp-spider-cache' ) . '
' . sprintf( esc_html__( 'A Cache Key Salt was identified: %s', 'wp-spider-cache' ), '' . WP_CACHE_KEY_SALT . '' ) . '
' .
676 | '
' . __( 'This advanced configuration option is usually defined in wp-config.php and is commonly used as a way to invalidate all cached data for the entire installation by updating the value of the WP_CACHE_KEY_SALT constant.', 'wp-spider-cache' ) . '
' . esc_html__( 'Choose a registered cache server from the list. Content from that server is automatically retrieved & presented in the table.', 'wp-spider-cache' ) . '
' .
686 | '
' . esc_html__( 'It is possible to have more than one cache server, and each server may have different cached content available to it.', 'wp-spider-cache' ) . '
' .
687 | '
' . esc_html__( 'Clicking "Refresh" will fetch fresh data from the selected server, and repopulate the table.', 'wp-spider-cache' ) . '
' . esc_html__( 'Hovering over a row in the list will display action links that allow you to manage that content. You can perform the following actions:', 'wp-spider-cache' ) . '
' .
707 | '
' . __( 'Search for content within the list.', 'wp-spider-cache' ) . '
' .
708 | '
' . __( 'Clear many caches at the same time, by group or user ID.', 'wp-spider-cache' ) . '
' .
709 | '
' . __( 'Flush an entire cache group to remove all of the subsequent keys.', 'wp-spider-cache' ) . '
' .
710 | '
' . __( 'Remove a single cache key from within a cache group.', 'wp-spider-cache' ) . '
' .
711 | '
' . __( 'View the contents of a single cache key.', 'wp-spider-cache' ) . '