Version Description
- Fix: Do not follow symlinks during file copy process
- Fix: css error
- Fix: Show "not-compatible" notice only when blog version is higher than plugin tested version.
- Fix: undefined var $size
- Fix: Check if $path is null before writing to remaining_files.json
- Fix: $db_helper undefined message
- Fix: Skip non utf8 encoded files during copying process
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- CONTRIBUTING.md +38 -0
- LICENSE +340 -0
- README.md +29 -0
- assets/css/wpstg-admin.css +611 -0
- assets/css/wpstg-admin.min.css +1 -0
- assets/images/admin_dashboard.png +0 -0
- assets/images/loading.gif +0 -0
- assets/images/loading.svg +1 -0
- assets/images/logo_clean_small_212_25.png +0 -0
- assets/js/wpstg-admin.js +800 -0
- assets/js/wpstg-admin.min.js +1 -0
- assets/js/wpstg.js +0 -0
- assets/js/wpstg.min.js +0 -0
- includes/WPSTG_SL_Plugin_Updater.php +377 -0
- includes/admin/add-ons.php +59 -0
- includes/admin/admin-actions.php +31 -0
- includes/admin/admin-footer.php +41 -0
- includes/admin/admin-notices.php +258 -0
- includes/admin/admin-pages.php +56 -0
- includes/admin/plugins.php +62 -0
- includes/admin/settings/contextual-help.php +50 -0
- includes/admin/settings/display-settings.php +181 -0
- includes/admin/settings/register-settings.php +839 -0
- includes/admin/tools.php +460 -0
- includes/admin/upload-functions.php +190 -0
- includes/admin/welcome.php +73 -0
- includes/class-wpstg-html-elements.php +219 -0
- includes/class-wpstg-license-handler.php +368 -0
- includes/debug/browsers/WPChromePHP.class.php +25 -0
- includes/debug/browsers/WPFirePHP.class.php +28 -0
- includes/debug/browsers/api/chromephp/ChromePhp.php +440 -0
- includes/debug/browsers/api/chromephp/README +16 -0
- includes/debug/browsers/api/firephp/CHANGELOG.md +167 -0
- includes/debug/browsers/api/firephp/README.md +75 -0
- includes/debug/browsers/api/firephp/examples/oo.php +82 -0
- includes/debug/browsers/api/firephp/examples/oo.php4 +72 -0
- includes/debug/browsers/api/firephp/examples/procedural.php +79 -0
- includes/debug/browsers/api/firephp/examples/procedural.php4 +69 -0
- includes/debug/browsers/api/firephp/lib/FirePHPCore/FirePHP.class.php +1828 -0
- includes/debug/browsers/api/firephp/lib/FirePHPCore/FirePHP.class.php4 +1327 -0
- includes/debug/browsers/api/firephp/lib/FirePHPCore/fb.php +275 -0
- includes/debug/browsers/api/firephp/lib/FirePHPCore/fb.php4 +245 -0
- includes/debug/browsers/api/firephp/package.json +42 -0
- includes/debug/browsers/api/firephp/program.json +5 -0
- includes/debug/browsers/api/firephp/tests/API/newlines.php +12 -0
- includes/debug/browsers/api/firephp/tests/FirePHPCore/FirePHPTest.php +181 -0
- includes/debug/browsers/api/firephp/tests/TestHelper.php +55 -0
- includes/debug/browsers/api/firephp/tests/phpunit.xml +2 -0
- includes/debug/browsers/api/firephp/workspace/README.md +19 -0
- includes/debug/browsers/api/firephp/workspace/lib/project.js +5 -0
- includes/debug/browsers/api/firephp/workspace/package.json +28 -0
- includes/debug/browsers/api/firephp/workspace/program.json +78 -0
- includes/debug/browsers/api/firephp/workspace/scripts/build.js +164 -0
- includes/debug/browsers/api/firephp/workspace/scripts/publish.js +65 -0
- includes/debug/browsers/api/firephp/workspace/tpl/license.tpl.md +21 -0
- includes/debug/browsers/api/firephp/workspace/tpl/pear.package.tpl.xml +61 -0
- includes/debug/browsers/api/firephp/workspace/tpl/readme.tpl.md +17 -0
- includes/debug/classes/wpstgDebug.class.php +277 -0
- includes/debug/classes/wpstgDebug.interface.php +11 -0
- includes/install.php +160 -0
- includes/libraries/RolingCurlX.php +218 -0
- includes/libraries/browser.php +1082 -0
- includes/logger.php +128 -0
- includes/scripts.php +79 -0
- includes/staging-functions.php +114 -0
- includes/template-functions.php +1722 -0
- includes/wpstg-sanitize.php +158 -0
- languages/Gruntfile.js +105 -0
- languages/README.md +18 -0
- languages/index.php +6 -0
- languages/readme.txt +16 -0
- languages/wpstg-en_EN.mo +0 -0
- languages/wpstg-en_EN.po +648 -0
- languages/wpstg.mo +0 -0
- languages/wpstg.po +648 -0
- license.txt +281 -0
- optimizer/wp-staging-optimizer.php +147 -0
- readme.txt +203 -0
- templates/wpstg.min.css +0 -0
- uninstall.php +35 -0
- wp-staging.php +248 -0
CONTRIBUTING.md
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#Contribute To Quick Adsense Reloaded
|
2 |
+
|
3 |
+
Community made patches, localisations, bug reports and contributions are always welcome.
|
4 |
+
|
5 |
+
When contributing please ensure you follow the guidelines below so that we can keep on top of things.
|
6 |
+
|
7 |
+
__Please Note:__ GitHub is for bug reports and contributions only.
|
8 |
+
|
9 |
+
## Getting Started
|
10 |
+
|
11 |
+
* Submit a ticket for your issue, assuming one does not already exist.
|
12 |
+
* Raise it on our [Issue Tracker](https://github.com/rene-hermenau/quick-adsense-reloaded/issues)
|
13 |
+
* Clearly describe the issue including steps to reproduce the bug.
|
14 |
+
* Make sure you fill in the earliest version that you know has the issue as well as the version of WordPress you're using.
|
15 |
+
|
16 |
+
## Making Changes
|
17 |
+
|
18 |
+
* Fork the repository on GitHub
|
19 |
+
* Make the changes to your forked repository
|
20 |
+
* Ensure you stick to the [WordPress Coding Standards](https://codex.wordpress.org/WordPress_Coding_Standards)
|
21 |
+
* When committing, reference your issue (if present) and include a note about the fix
|
22 |
+
* (coming soon) If possible, and if applicable, please also add/update unit tests for your changes
|
23 |
+
* Push the changes to your fork and submit a pull request to the 'master' branch of the Quick Adsense Reloaded repository
|
24 |
+
|
25 |
+
## Code Documentation
|
26 |
+
|
27 |
+
* We ensure that every Quick Adsense Reloaded function is documented well and follows the standards set by phpDoc
|
28 |
+
* An example function can be found [here](https://gist.github.com/rene-hermenau/8d3d7ee0633ee2f64b4b)
|
29 |
+
* Please make sure that every function is documented so that when we update our API Documentation it will complete
|
30 |
+
* If you're adding/editing a function in a class, make sure to add `@access {private|public|protected}`
|
31 |
+
* Finally, please use tabs and not spaces. The tab indent size should be 4 for all Quick Adsense Reloaded code.
|
32 |
+
|
33 |
+
At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
|
34 |
+
|
35 |
+
# Additional Resources
|
36 |
+
* [General GitHub Documentation](http://help.github.com/)
|
37 |
+
* [GitHub Pull Request documentation](http://help.github.com/send-pull-requests/)
|
38 |
+
* [PHPUnit Tests Guide](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html)
|
LICENSE
ADDED
@@ -0,0 +1,340 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
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 |
+
|
README.md
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
### Welcome to the WP-Staging repository
|
2 |
+
|
3 |
+
## Note ##
|
4 |
+
|
5 |
+
This is the latest developer version of WP-Staging for WordPress.
|
6 |
+
|
7 |
+
## Installation ##
|
8 |
+
|
9 |
+
1. You can clone the GitHub repository: `https://github.com/rene-hermenau/wp-staging.git`
|
10 |
+
2. Or download it directly as a ZIP file: `https://github.com/rene-hermenau/wp-staging/archive/master.zip`
|
11 |
+
3. Upload it via WordPress->Plugin->AddNew
|
12 |
+
|
13 |
+
This will download the latest developer copy of WP-Staging.
|
14 |
+
|
15 |
+
## Bugs ##
|
16 |
+
If you find an issue, let us know [here](https://github.com/rene-hermenau/wp-staging/issues?state=open)!
|
17 |
+
|
18 |
+
## Support ##
|
19 |
+
This is a developer's portal for WP-Staging
|
20 |
+
|
21 |
+
## Contributions ##
|
22 |
+
Anyone is welcome to contribute to WP-Staging. Please read the [guidelines for contributing](https://github.com/rene-hermenau/wp-staging/blob/master/CONTRIBUTING.md) to this repository.
|
23 |
+
|
24 |
+
There are various ways you can contribute:
|
25 |
+
|
26 |
+
1. Raise an [Issue](https://github.com/rene-hermenau/wp-staging/issues) on GitHub
|
27 |
+
2. Send us a Pull Request with your bug fixes and/or new features
|
28 |
+
3. Translate WP-Staging into different languages
|
29 |
+
4. Provide feedback and suggestions on [enhancements](https://github.com/rene-hermenau/wp-staging/issues?direction=desc&labels=Enhancement&page=1&sort=created&state=open)
|
assets/css/wpstg-admin.css
ADDED
@@ -0,0 +1,611 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* WPSTG Admin CSS
|
3 |
+
*
|
4 |
+
* @package WPSTG
|
5 |
+
* @subpackage Admin CSS
|
6 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
7 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
/* CSS for Tabs */
|
12 |
+
|
13 |
+
#tab_container ul {
|
14 |
+
/*height: 200px;*/
|
15 |
+
list-style: none;
|
16 |
+
margin: 0;
|
17 |
+
padding: 0;
|
18 |
+
background: #f1f1f1;
|
19 |
+
float: left;
|
20 |
+
padding-top: 0px;
|
21 |
+
/*list-style-type: square;*/
|
22 |
+
}
|
23 |
+
|
24 |
+
#tab_container ul li:first-child.selected-tab {
|
25 |
+
border-top: none;
|
26 |
+
}
|
27 |
+
|
28 |
+
#tab_container ul li a.selected-tab {
|
29 |
+
font-weight: bold;
|
30 |
+
text-decoration: none;
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
#tab_container .row{
|
36 |
+
padding-top:10px;
|
37 |
+
padding-bottom:12px;
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
#tab_container .row label strong, #tab_container .row strong {
|
42 |
+
font-weight: bold;
|
43 |
+
}
|
44 |
+
|
45 |
+
.wpstg-tabs a {
|
46 |
+
padding:5px;
|
47 |
+
}
|
48 |
+
|
49 |
+
#tab_container > ul > li.wpstg-tabs.active {
|
50 |
+
background-color:white;
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
+
|
55 |
+
#wpstg_settingsgeneral_header .row:nth-child(3), #wpstg_settingsgeneral_header .row:nth-child(4){
|
56 |
+
display:none;
|
57 |
+
}
|
58 |
+
|
59 |
+
/* Layout of admin table and rows
|
60 |
+
*/
|
61 |
+
|
62 |
+
#tab_container .panel-container {
|
63 |
+
background: #FFF;
|
64 |
+
padding:20px;
|
65 |
+
padding-top:0px;
|
66 |
+
overflow:auto;
|
67 |
+
}
|
68 |
+
|
69 |
+
#tab_container .form-table th {
|
70 |
+
vertical-align: top;
|
71 |
+
text-align: left;
|
72 |
+
padding: 20px 10px 20px 0;
|
73 |
+
width: 200px;
|
74 |
+
line-height: 1.3;
|
75 |
+
font-weight: bold;
|
76 |
+
font-size: 14px;
|
77 |
+
color:#484848;
|
78 |
+
width: 30%;
|
79 |
+
}
|
80 |
+
|
81 |
+
#tab_container .form-table tr {
|
82 |
+
border-bottom: 1px solid #E7E7E7;
|
83 |
+
}
|
84 |
+
|
85 |
+
#tab_container span.description{
|
86 |
+
display: block;
|
87 |
+
font-weight: 400;
|
88 |
+
font-style: normal;
|
89 |
+
font-size: 13px;
|
90 |
+
margin-top: 7px;
|
91 |
+
color:#484848;
|
92 |
+
}
|
93 |
+
|
94 |
+
#tab_container .col-title{
|
95 |
+
color:#484848;
|
96 |
+
}
|
97 |
+
|
98 |
+
@media only screen and (max-width:680px) {
|
99 |
+
#tab_container ul {
|
100 |
+
float:none;
|
101 |
+
}
|
102 |
+
#tab_container .form-table tr > th {
|
103 |
+
width:100%;
|
104 |
+
}
|
105 |
+
#tab_container span.description{
|
106 |
+
font-size: 14px;
|
107 |
+
}
|
108 |
+
#tab_container .form-table tr > th, #tab_container .form-table tr > td {
|
109 |
+
padding:10px;
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
#tab_container ul li {
|
114 |
+
margin-bottom:0px;
|
115 |
+
}
|
116 |
+
|
117 |
+
#tab_container ul li a {
|
118 |
+
display: block;
|
119 |
+
padding:10px 4px 10px 14px;
|
120 |
+
border-width: 1px 0;
|
121 |
+
border-style: solid;
|
122 |
+
border-top-color:white;
|
123 |
+
border-bottom-color:#e7e7e7;
|
124 |
+
text-decoration: none;
|
125 |
+
color: #0097DF;
|
126 |
+
font-weight: bold;
|
127 |
+
}
|
128 |
+
#tab_container ul li a:hover {
|
129 |
+
background-color: #e5e5e5;
|
130 |
+
color:#777777;
|
131 |
+
}
|
132 |
+
|
133 |
+
|
134 |
+
.wp-staginglogo{
|
135 |
+
display: block;
|
136 |
+
font-size:16px;
|
137 |
+
padding-top:20px;
|
138 |
+
width:220px;
|
139 |
+
float:left;
|
140 |
+
}
|
141 |
+
|
142 |
+
.wpstg-version{
|
143 |
+
display: block;
|
144 |
+
padding-top:29px
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
.wpstg_admin .nav-tab {
|
149 |
+
color: #3C3C3C;
|
150 |
+
}
|
151 |
+
|
152 |
+
|
153 |
+
#tab_container table tbody tr:nth-child(1) > th > div {
|
154 |
+
font-size: 20px;
|
155 |
+
}
|
156 |
+
|
157 |
+
.wpstg_hidden{
|
158 |
+
display: none;
|
159 |
+
}
|
160 |
+
|
161 |
+
/* End layout of admin table and rows
|
162 |
+
*/
|
163 |
+
#mashtabcontainer > .mashtabs {
|
164 |
+
background-color: #ffffff;
|
165 |
+
}
|
166 |
+
|
167 |
+
#mashtabcontainer ul .active {
|
168 |
+
background-color: #00adef;
|
169 |
+
color: white;
|
170 |
+
border-bottom-color: #0098D2;
|
171 |
+
}
|
172 |
+
|
173 |
+
#mashtabcontainer ul .active:hover {
|
174 |
+
background-color: #00A4E2;
|
175 |
+
color: white;
|
176 |
+
border-bottom-color: #0098D2;
|
177 |
+
}
|
178 |
+
|
179 |
+
#mashtabcontainer ul li a {
|
180 |
+
padding: 10px 14px 10px 14px;
|
181 |
+
background-color: #f3f3f3
|
182 |
+
|
183 |
+
}
|
184 |
+
|
185 |
+
#mashtabcontainer .mashtab-container {
|
186 |
+
border: 0px solid #ececec;
|
187 |
+
}
|
188 |
+
|
189 |
+
/* Cloning workflow */
|
190 |
+
#wpstg-clonepage-wrapper {
|
191 |
+
margin-bottom: 20px;
|
192 |
+
width: 690px;
|
193 |
+
}
|
194 |
+
|
195 |
+
@media screen and (min-width:1090px){
|
196 |
+
#wpstg-clonepage-wrapper {
|
197 |
+
float: left;
|
198 |
+
margin-bottom: 20px;
|
199 |
+
width: 690px;
|
200 |
+
}
|
201 |
+
.wpstg-sidebar{
|
202 |
+
display: none;
|
203 |
+
margin-left: 700px;
|
204 |
+
margin-top: 138px;
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
.wpstg-sidebar{
|
209 |
+
display: none;
|
210 |
+
padding: 10px;
|
211 |
+
border: 1px solid #DFDFDF;
|
212 |
+
max-width: 250px;
|
213 |
+
height: 250px;
|
214 |
+
}
|
215 |
+
|
216 |
+
#wpstg-steps {
|
217 |
+
margin-top:30px;
|
218 |
+
}
|
219 |
+
|
220 |
+
#wpstg-steps li {
|
221 |
+
color: #444;
|
222 |
+
line-height: 20px;
|
223 |
+
padding-right:10px;
|
224 |
+
float:left;
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
.wpstg-step-num {
|
229 |
+
border: 1px solid #444;
|
230 |
+
border-radius: 3px;
|
231 |
+
display: inline-block;
|
232 |
+
width: 20px;
|
233 |
+
height: 20px;
|
234 |
+
text-align: center;
|
235 |
+
margin-right: 5px;
|
236 |
+
}
|
237 |
+
|
238 |
+
.wpstg-current-step {
|
239 |
+
font-weight: bold;
|
240 |
+
}
|
241 |
+
|
242 |
+
.wpstg-current-step .wpstg-step-num {
|
243 |
+
background: #444;
|
244 |
+
color: #eee;
|
245 |
+
}
|
246 |
+
|
247 |
+
.wpstg-clone {
|
248 |
+
border: 3px solid #ffffff;
|
249 |
+
margin-bottom: 5px;
|
250 |
+
padding: 5px 10px;
|
251 |
+
width: 300px;
|
252 |
+
position: relative;
|
253 |
+
overflow: hidden;
|
254 |
+
transition: border-color .2s ease-in-out;
|
255 |
+
background-color: #DDDDDD;
|
256 |
+
}
|
257 |
+
|
258 |
+
.wpstg-clone.active {
|
259 |
+
border-color: #1d94cf;;
|
260 |
+
}
|
261 |
+
|
262 |
+
.wpstg-clone-title {
|
263 |
+
display: inline-block;
|
264 |
+
font-size: 15px;
|
265 |
+
max-width: 130px;
|
266 |
+
text-decoration: none;
|
267 |
+
font-weight: bold;
|
268 |
+
color:#0285AE;
|
269 |
+
}
|
270 |
+
|
271 |
+
.wpstg-clone-action {
|
272 |
+
background: #ffffff;
|
273 |
+
border-left: 1px solid #ccc;
|
274 |
+
color: #bbb;
|
275 |
+
display: none;
|
276 |
+
padding: 0 5px;
|
277 |
+
float: right;
|
278 |
+
text-decoration: none;
|
279 |
+
position: relative;
|
280 |
+
transition: color .2s ease-in-out;
|
281 |
+
}
|
282 |
+
|
283 |
+
.wpstg-remove-clone:hover {
|
284 |
+
color: #ef6d6d;
|
285 |
+
}
|
286 |
+
|
287 |
+
.wpstg-clone-action:last-child {
|
288 |
+
border: none;
|
289 |
+
}
|
290 |
+
|
291 |
+
.wpstg-clone:hover .wpstg-clone-action {
|
292 |
+
display: inline-block;
|
293 |
+
}
|
294 |
+
|
295 |
+
#wpstg-show-error-details:focus,
|
296 |
+
#wpstg-workflow .wpstg-clone-action {
|
297 |
+
outline: none;
|
298 |
+
box-shadow: none;
|
299 |
+
}
|
300 |
+
|
301 |
+
.wpstg-link-btn {
|
302 |
+
background: #45a1c9;
|
303 |
+
color: #fff;
|
304 |
+
display: inline-block;
|
305 |
+
padding: 5px 10px;
|
306 |
+
text-decoration: none;
|
307 |
+
vertical-align: baseline;
|
308 |
+
transition: all .2s ease-in-out;
|
309 |
+
}
|
310 |
+
|
311 |
+
.wpstg-link-btn:hover,
|
312 |
+
.wpstg-link-btn:focus {
|
313 |
+
color: #fff;
|
314 |
+
outline: none;
|
315 |
+
box-shadow: none;
|
316 |
+
}
|
317 |
+
|
318 |
+
#wpstg-workflow .wpstg-link-btn:active {
|
319 |
+
vertical-align: baseline;
|
320 |
+
}
|
321 |
+
|
322 |
+
.wpstg-link-btn[disabled] {
|
323 |
+
background: #777 !important;
|
324 |
+
pointer-events: none;
|
325 |
+
}
|
326 |
+
|
327 |
+
#wpstg-cancel-cloning {
|
328 |
+
background: #ff3428;
|
329 |
+
border-color: #e72f24;
|
330 |
+
margin-top: 5px;
|
331 |
+
}
|
332 |
+
|
333 |
+
#wpstg-cancel-cloning.success {
|
334 |
+
background: #64dd58;
|
335 |
+
border-color: #54bd4a;
|
336 |
+
}
|
337 |
+
|
338 |
+
#wpstg-error-wrapper,
|
339 |
+
#wpstg-error-details {
|
340 |
+
display: none;
|
341 |
+
margin-top: 10px;
|
342 |
+
font-size: 13px;
|
343 |
+
}
|
344 |
+
|
345 |
+
#wpstg-show-error-details {
|
346 |
+
display: inline-block;
|
347 |
+
margin-left: 5px;
|
348 |
+
color: #555;
|
349 |
+
text-decoration: none;
|
350 |
+
transition: color .2s ease-in-out;
|
351 |
+
}
|
352 |
+
|
353 |
+
#wpstg-show-error-details:hover {
|
354 |
+
color: #1d94cf;
|
355 |
+
}
|
356 |
+
|
357 |
+
#wpstg-error-details {
|
358 |
+
border-left: 5px solid #ef6d6d;
|
359 |
+
padding: 10px;
|
360 |
+
width: 500px;
|
361 |
+
}
|
362 |
+
|
363 |
+
#wpstg-home-link,
|
364 |
+
#wpstg-try-again {
|
365 |
+
display: none;
|
366 |
+
}
|
367 |
+
|
368 |
+
|
369 |
+
#wpstg-loader {
|
370 |
+
content: url('../images/loading.gif');
|
371 |
+
margin-top:-5px;
|
372 |
+
}
|
373 |
+
|
374 |
+
#wpstg-workflow {
|
375 |
+
position: relative;
|
376 |
+
clear:both;
|
377 |
+
padding-top:20px;
|
378 |
+
margin-right:20px;
|
379 |
+
}
|
380 |
+
|
381 |
+
#wpstg-workflow.loading::after,
|
382 |
+
#wpstg-removing-clone.loading::after {
|
383 |
+
background: rgba(255, 255, 255, .7);
|
384 |
+
content: 'LOADING May take little bit longer for large sites... ';
|
385 |
+
display: block;
|
386 |
+
width: 100%;
|
387 |
+
height: 100%;
|
388 |
+
font-size: 20px;
|
389 |
+
padding-top: 100px;
|
390 |
+
text-align: center;
|
391 |
+
position: absolute;
|
392 |
+
top: 0;
|
393 |
+
left: 0;
|
394 |
+
z-index: 99;
|
395 |
+
}
|
396 |
+
|
397 |
+
#wpstg-removing-clone.loading::after {
|
398 |
+
content: 'REMOVING' !important;
|
399 |
+
}
|
400 |
+
|
401 |
+
#wpstg-existing-clones,
|
402 |
+
#wpstg-removing-clone {
|
403 |
+
position: relative;
|
404 |
+
}
|
405 |
+
|
406 |
+
.wpstg-progress-bar {
|
407 |
+
max-width: 900px;
|
408 |
+
height: 27px;
|
409 |
+
padding: 0px;
|
410 |
+
background-color: #d6d8d7;
|
411 |
+
}
|
412 |
+
|
413 |
+
.wpstg-progress {
|
414 |
+
background: #1d94cf;
|
415 |
+
width: 0;
|
416 |
+
height: 100%;
|
417 |
+
transition: width 1s;
|
418 |
+
color:white;
|
419 |
+
line-height:25px;
|
420 |
+
text-align:center;
|
421 |
+
}
|
422 |
+
|
423 |
+
#wpstg-new-clone-id.wpstg-error-input,
|
424 |
+
#wpstg-clone-path.wpstg-error-input {
|
425 |
+
border: 1px solid #ff4235;
|
426 |
+
box-shadow: 0 0 2px rgba(255, 66, 53, .8);
|
427 |
+
}
|
428 |
+
|
429 |
+
#wpstg-clone-path {
|
430 |
+
margin-left: 10px;
|
431 |
+
width: 350px;
|
432 |
+
}
|
433 |
+
|
434 |
+
.wpstg-error-msg {
|
435 |
+
color: #ff4235;
|
436 |
+
}
|
437 |
+
|
438 |
+
#wpstg-start-cloning + .wpstg-error-msg {
|
439 |
+
display: block;
|
440 |
+
margin-top: 5px;
|
441 |
+
}
|
442 |
+
|
443 |
+
.wpstg-size-info {
|
444 |
+
color: #999;
|
445 |
+
font-weight: normal;
|
446 |
+
position: relative;
|
447 |
+
left: 2px;
|
448 |
+
}
|
449 |
+
|
450 |
+
.wpstg-db-table .wpstg-size-info {
|
451 |
+
top: 2px;
|
452 |
+
}
|
453 |
+
|
454 |
+
#wpstg-workflow #wpstg-start-cloning {
|
455 |
+
display: inline-block;
|
456 |
+
margin-left: 5px;
|
457 |
+
font-size: 14px;
|
458 |
+
vertical-align: baseline;
|
459 |
+
}
|
460 |
+
|
461 |
+
/* Tabs */
|
462 |
+
.wpstg-tabs-wrapper {
|
463 |
+
max-width: 640px;
|
464 |
+
margin: 10px 0;
|
465 |
+
}
|
466 |
+
|
467 |
+
#wpstg-path-wrapper {
|
468 |
+
border-bottom: 2px dashed #ccc;
|
469 |
+
padding-bottom: 10px;
|
470 |
+
margin-bottom: 10px;
|
471 |
+
}
|
472 |
+
|
473 |
+
.wpstg-tabs-wrapper {
|
474 |
+
border: 1px solid #ddd;
|
475 |
+
border-right: none;
|
476 |
+
border-left: none;
|
477 |
+
}
|
478 |
+
|
479 |
+
.wpstg-tab-section {
|
480 |
+
border: 1px solid #ddd;
|
481 |
+
border-right: none;
|
482 |
+
border-left: none;
|
483 |
+
display: none;
|
484 |
+
padding: 20px;
|
485 |
+
}
|
486 |
+
|
487 |
+
.wpstg-tab-section::after {
|
488 |
+
display: block;
|
489 |
+
content: '';
|
490 |
+
clear: both;
|
491 |
+
}
|
492 |
+
|
493 |
+
.wpstg-tab-header {
|
494 |
+
border: 1px solid #ddd;
|
495 |
+
border-right: none;
|
496 |
+
border-left: none;
|
497 |
+
color: #444;
|
498 |
+
font-size: 16px;
|
499 |
+
font-weight: bolder;
|
500 |
+
display: block;
|
501 |
+
padding: 10px;;
|
502 |
+
text-decoration: none;
|
503 |
+
}
|
504 |
+
|
505 |
+
.wpstg-tab-triangle {
|
506 |
+
display: inline-block;
|
507 |
+
margin-right: 10px;
|
508 |
+
}
|
509 |
+
|
510 |
+
.wpstg-tab-header:focus {
|
511 |
+
color: #444;
|
512 |
+
outline: none;
|
513 |
+
box-shadow: none;
|
514 |
+
}
|
515 |
+
|
516 |
+
#wpstg-large-files {
|
517 |
+
display:none;
|
518 |
+
border: 1px dashed #ccc;
|
519 |
+
/*float: right;*/
|
520 |
+
padding: 10px 10px 10px;
|
521 |
+
margin-top:20px;
|
522 |
+
position: relative;
|
523 |
+
font-size:12px;
|
524 |
+
}
|
525 |
+
|
526 |
+
#wpstg-large-files h3 {
|
527 |
+
background: #fff;
|
528 |
+
margin: 0;
|
529 |
+
padding: 0 5px;
|
530 |
+
position: absolute;
|
531 |
+
top: -10px;
|
532 |
+
left: 5px;
|
533 |
+
}
|
534 |
+
|
535 |
+
/* tmp */
|
536 |
+
.wpstg-subdir {
|
537 |
+
display: none;
|
538 |
+
margin-left: 20px;
|
539 |
+
}
|
540 |
+
|
541 |
+
.wpstg-dir a.disabled {
|
542 |
+
color: #888;
|
543 |
+
cursor: default;
|
544 |
+
text-decoration: none;
|
545 |
+
}
|
546 |
+
|
547 |
+
.wpstg-check-subdirs {
|
548 |
+
display: inline-block;
|
549 |
+
margin-left: 10px;
|
550 |
+
}
|
551 |
+
|
552 |
+
.wpstg-notice-alert{
|
553 |
+
display:block;
|
554 |
+
background-color:#FFD0D0;
|
555 |
+
padding:20px;
|
556 |
+
border: 1px solid #fff;
|
557 |
+
max-width: 600px;
|
558 |
+
}
|
559 |
+
|
560 |
+
.wpstg-header{
|
561 |
+
font-weight: 400;
|
562 |
+
line-height: 1.6em;
|
563 |
+
font-size: 19px;
|
564 |
+
border-bottom: 1px solid #DFDFDF;
|
565 |
+
clear:both;
|
566 |
+
}
|
567 |
+
|
568 |
+
|
569 |
+
#wpstg-clone-label{
|
570 |
+
font-size: 14px;
|
571 |
+
font-weight: bold;
|
572 |
+
}
|
573 |
+
|
574 |
+
#wpstg-log-details{
|
575 |
+
display:none;
|
576 |
+
height: 300px;
|
577 |
+
overflow: scroll;
|
578 |
+
max-width: 500px;
|
579 |
+
font-size: 11px;
|
580 |
+
border: 1px solid #FFF;
|
581 |
+
background-color: black;
|
582 |
+
color: white;
|
583 |
+
padding:10px;
|
584 |
+
}
|
585 |
+
|
586 |
+
#wpstg-finished-result {
|
587 |
+
display:none;
|
588 |
+
}
|
589 |
+
|
590 |
+
#wpstg-remove-cloning {
|
591 |
+
background: #ff3428;
|
592 |
+
border-color: #e72f24;
|
593 |
+
margin-top: 5px;
|
594 |
+
}
|
595 |
+
|
596 |
+
#wpstg-success-notice{
|
597 |
+
padding: 10px;
|
598 |
+
background-color: white;
|
599 |
+
max-width: 900px;
|
600 |
+
border: 1px solid #ccc;
|
601 |
+
margin-top: 20px;
|
602 |
+
}
|
603 |
+
|
604 |
+
.wpstg_beta_notice {
|
605 |
+
margin-bottom:20px;
|
606 |
+
}
|
607 |
+
|
608 |
+
.wpstg-sysinfo {
|
609 |
+
width:400px;
|
610 |
+
height: 500px;
|
611 |
+
}
|
assets/css/wpstg-admin.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
#tab_container ul{list-style:none;margin:0;padding:0;background:#f1f1f1;float:left}#tab_container ul li:first-child.selected-tab{border-top:none}#tab_container ul li a.selected-tab{font-weight:700;text-decoration:none}#tab_container .row{padding-top:10px;padding-bottom:12px}#tab_container .row label strong,#tab_container .row strong{font-weight:700}.wpstg-tabs a{padding:5px}#tab_container>ul>li.wpstg-tabs.active{background-color:#fff}#wpstg_settingsgeneral_header .row:nth-child(3),#wpstg_settingsgeneral_header .row:nth-child(4){display:none}#tab_container .panel-container{background:#FFF;padding:0 20px 20px;overflow:auto}#tab_container .form-table th{vertical-align:top;text-align:left;padding:20px 10px 20px 0;line-height:1.3;font-weight:700;font-size:14px;color:#484848;width:30%}#wpstg-workflow .wpstg-link-btn:active,.wpstg-link-btn{vertical-align:baseline}#tab_container .form-table tr{border-bottom:1px solid #E7E7E7}#tab_container span.description{display:block;font-weight:400;font-style:normal;font-size:13px;margin-top:7px;color:#484848}#tab_container .col-title{color:#484848}@media only screen and (max-width:680px){#tab_container ul{float:none}#tab_container .form-table tr>th{width:100%}#tab_container span.description{font-size:14px}#tab_container .form-table tr>td,#tab_container .form-table tr>th{padding:10px}}#tab_container ul li{margin-bottom:0}#tab_container ul li a{display:block;padding:10px 4px 10px 14px;border-width:1px 0;border-style:solid;border-top-color:#fff;border-bottom-color:#e7e7e7;text-decoration:none;color:#0097DF;font-weight:700}#tab_container ul li a:hover{background-color:#e5e5e5;color:#777}.wp-staginglogo{display:block;font-size:16px;padding-top:20px;width:220px;float:left}.wpstg-version{display:block;padding-top:29px}.wpstg_admin .nav-tab{color:#3C3C3C}#tab_container table tbody tr:nth-child(1)>th>div{font-size:20px}.wpstg_hidden{display:none}#mashtabcontainer>.mashtabs{background-color:#fff}#mashtabcontainer ul .active{background-color:#00adef;color:#fff;border-bottom-color:#0098D2}#mashtabcontainer ul .active:hover{background-color:#00A4E2;color:#fff;border-bottom-color:#0098D2}#mashtabcontainer ul li a{padding:10px 14px;background-color:#f3f3f3}#mashtabcontainer .mashtab-container{border:0 solid #ececec}#wpstg-clonepage-wrapper{margin-bottom:20px;width:690px}@media screen and (min-width:1090px){#wpstg-clonepage-wrapper{float:left;margin-bottom:20px;width:690px}.wpstg-sidebar{display:none;margin-left:700px;margin-top:138px}}.wpstg-sidebar{display:none;padding:10px;border:1px solid #DFDFDF;max-width:250px;height:250px}#wpstg-steps{margin-top:30px}#wpstg-steps li{color:#444;line-height:20px;padding-right:10px;float:left}.wpstg-step-num{border:1px solid #444;border-radius:3px;display:inline-block;width:20px;height:20px;text-align:center;margin-right:5px}.wpstg-current-step{font-weight:700}.wpstg-current-step .wpstg-step-num{background:#444;color:#eee}.wpstg-clone{border:3px solid #fff;margin-bottom:5px;padding:5px 10px;width:300px;position:relative;overflow:hidden;transition:border-color .2s ease-in-out;background-color:#DDD}.wpstg-clone.active{border-color:#1d94cf}.wpstg-clone-title{display:inline-block;font-size:15px;max-width:130px;text-decoration:none;font-weight:700;color:#0285AE}.wpstg-clone-action{background:#fff;border-left:1px solid #ccc;color:#bbb;display:none;padding:0 5px;float:right;text-decoration:none;position:relative;transition:color .2s ease-in-out}.wpstg-clone:hover .wpstg-clone-action,.wpstg-link-btn{display:inline-block}.wpstg-remove-clone:hover{color:#ef6d6d}.wpstg-clone-action:last-child{border:none}#wpstg-show-error-details:focus,#wpstg-workflow .wpstg-clone-action{outline:0;box-shadow:none}.wpstg-link-btn{background:#45a1c9;color:#fff;padding:5px 10px;text-decoration:none;transition:all .2s ease-in-out}.wpstg-link-btn:focus,.wpstg-link-btn:hover{color:#fff;outline:0;box-shadow:none}.wpstg-link-btn[disabled]{background:#777!important;pointer-events:none}#wpstg-cancel-cloning{background:#ff3428;border-color:#e72f24;margin-top:5px}#wpstg-cancel-cloning.success{background:#64dd58;border-color:#54bd4a}#wpstg-error-details,#wpstg-error-wrapper{display:none;margin-top:10px;font-size:13px}#wpstg-show-error-details{display:inline-block;margin-left:5px;color:#555;text-decoration:none;transition:color .2s ease-in-out}#wpstg-show-error-details:hover{color:#1d94cf}#wpstg-error-details{border-left:5px solid #ef6d6d;padding:10px;width:500px}.wpstg-tab-header,.wpstg-tab-section,.wpstg-tabs-wrapper{border:1px solid #ddd;border-left:none}#wpstg-home-link,#wpstg-try-again{display:none}#wpstg-loader{content:url(../images/loading.gif);margin-top:-5px}#wpstg-workflow{position:relative;clear:both;padding-top:20px;margin-right:20px}#wpstg-removing-clone.loading::after,#wpstg-workflow.loading::after{background:rgba(255,255,255,.7);content:'LOADING May take little bit longer for large sites... ';display:block;width:100%;height:100%;font-size:20px;padding-top:100px;text-align:center;position:absolute;top:0;left:0;z-index:99}#wpstg-existing-clones,#wpstg-removing-clone,.wpstg-size-info{position:relative}#wpstg-removing-clone.loading::after{content:'REMOVING'!important}.wpstg-progress-bar{max-width:900px;height:27px;padding:0;background-color:#d6d8d7}.wpstg-progress{background:#1d94cf;width:0;height:100%;transition:width 1s;color:#fff;line-height:25px;text-align:center}#wpstg-clone-path.wpstg-error-input,#wpstg-new-clone-id.wpstg-error-input{border:1px solid #ff4235;box-shadow:0 0 2px rgba(255,66,53,.8)}#wpstg-clone-path{margin-left:10px;width:350px}.wpstg-error-msg{color:#ff4235}#wpstg-start-cloning+.wpstg-error-msg{display:block;margin-top:5px}.wpstg-size-info{color:#999;font-weight:400;left:2px}.wpstg-db-table .wpstg-size-info{top:2px}#wpstg-workflow #wpstg-start-cloning{display:inline-block;margin-left:5px;font-size:14px;vertical-align:baseline}.wpstg-tabs-wrapper{max-width:640px;margin:10px 0;border-right:none}#wpstg-path-wrapper{border-bottom:2px dashed #ccc;padding-bottom:10px;margin-bottom:10px}.wpstg-tab-section{border-right:none;display:none;padding:20px}.wpstg-tab-section::after{display:block;content:'';clear:both}.wpstg-tab-header{border-right:none;color:#444;font-size:16px;font-weight:bolder;display:block;padding:10px;text-decoration:none}.wpstg-tab-triangle{display:inline-block;margin-right:10px}.wpstg-tab-header:focus{color:#444;outline:0;box-shadow:none}#wpstg-large-files{display:none;border:1px dashed #ccc;padding:10px;margin-top:20px;position:relative;font-size:12px}#wpstg-large-files h3{background:#fff;margin:0;padding:0 5px;position:absolute;top:-10px;left:5px}.wpstg-subdir{display:none;margin-left:20px}.wpstg-dir a.disabled{color:#888;cursor:default;text-decoration:none}.wpstg-check-subdirs{display:inline-block;margin-left:10px}.wpstg-notice-alert{display:block;background-color:#FFD0D0;padding:20px;border:1px solid #fff;max-width:600px}.wpstg-header{font-weight:400;line-height:1.6em;font-size:19px;border-bottom:1px solid #DFDFDF;clear:both}#wpstg-clone-label{font-size:14px;font-weight:700}#wpstg-log-details{display:none;height:300px;overflow:scroll;max-width:500px;font-size:11px;border:1px solid #FFF;background-color:#000;color:#fff;padding:10px}#wpstg-finished-result{display:none}#wpstg-remove-cloning{background:#ff3428;border-color:#e72f24;margin-top:5px}#wpstg-success-notice{padding:10px;background-color:#fff;max-width:900px;border:1px solid #ccc;margin-top:20px}.wpstg_beta_notice{margin-bottom:20px}.wpstg-sysinfo{width:400px;height:500px}
|
assets/images/admin_dashboard.png
ADDED
Binary file
|
assets/images/loading.gif
ADDED
Binary file
|
assets/images/loading.svg
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8"?><svg width='32px' height='32px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-reload"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><g><path d="M50 15A35 35 0 1 0 74.787 25.213" fill="none" stroke="#444444" stroke-width="12px"></path><path d="M50 0L50 30L66 15L50 0" fill="#444444"></path><animateTransform attributeName="transform" type="rotate" from="0 50 50" to="360 50 50" dur="1.5s" repeatCount="indefinite"></animateTransform></g></svg>
|
assets/images/logo_clean_small_212_25.png
ADDED
Binary file
|
assets/js/wpstg-admin.js
ADDED
@@ -0,0 +1,800 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* WP Staging
|
3 |
+
* Main functions
|
4 |
+
*
|
5 |
+
* @author René Hermenau
|
6 |
+
* @author url https://wp-staging.com
|
7 |
+
* @date 17.08.2015
|
8 |
+
*
|
9 |
+
* @scince 0.9
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Cloning workflow
|
13 |
+
(function ($) {
|
14 |
+
$(document).ready(function () {
|
15 |
+
|
16 |
+
// Unselect/select all db tables
|
17 |
+
var ischecked = true;
|
18 |
+
$('#wpstg-workflow').on("click", ".wpstg-button-unselect", function (e) {
|
19 |
+
e.preventDefault();
|
20 |
+
if (ischecked == false) {
|
21 |
+
$(".wpstg-db-table-checkboxes").attr("checked", "checked");
|
22 |
+
$(".wpstg-button-unselect").html("Uncheck All");
|
23 |
+
ischecked = true;
|
24 |
+
} else {
|
25 |
+
$(".wpstg-db-table-checkboxes").removeAttr("checked");
|
26 |
+
$(".wpstg-button-unselect").html("Check All");
|
27 |
+
ischecked = false;
|
28 |
+
}
|
29 |
+
});
|
30 |
+
|
31 |
+
// Ajax loading spinner
|
32 |
+
var admin_url = ajaxurl.replace('/admin-ajax.php', '');
|
33 |
+
var spinner_url = admin_url + '/images/spinner';
|
34 |
+
if (2 < window.devicePixelRatio) {
|
35 |
+
spinner_url += '-2x';
|
36 |
+
}
|
37 |
+
spinner_url += '.gif';
|
38 |
+
var ajax_spinner = '<img src="' + spinner_url + '" alt="" class="ajax-spinner general-spinner" />';
|
39 |
+
|
40 |
+
var doing_plugin_compatibility_ajax = false;
|
41 |
+
|
42 |
+
// Basic functions
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Check if object is JSON valid
|
46 |
+
*
|
47 |
+
* @param {string} str
|
48 |
+
* @returns {Boolean}
|
49 |
+
*/
|
50 |
+
function wpstgIsJsonObj(obj) {
|
51 |
+
if (typeof obj == 'object')
|
52 |
+
{
|
53 |
+
return true;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Check if given value is an integer
|
60 |
+
* This also casts strings as potential integers as well
|
61 |
+
*
|
62 |
+
* */
|
63 |
+
function wpstgIsInt(value) {
|
64 |
+
return !isNaN(value) &&
|
65 |
+
parseInt(Number(value)) == value &&
|
66 |
+
!isNaN(parseInt(value, 10));
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Do some checks first for the clone name.
|
71 |
+
* Check the max length of string and if clone name already exists
|
72 |
+
*/
|
73 |
+
$('#wpstg-workflow').on('keyup', '#wpstg-new-clone-id', function () {
|
74 |
+
var data = {
|
75 |
+
action: 'wpstg_check_clone',
|
76 |
+
cloneID: this.value
|
77 |
+
};
|
78 |
+
$.post(ajaxurl, data, function (resp, status, xhr) {
|
79 |
+
if (resp.status !== "fail") {
|
80 |
+
$('#wpstg-new-clone-id').removeClass('wpstg-error-input');
|
81 |
+
$('#wpstg-start-cloning').removeAttr('disabled');
|
82 |
+
$('#wpstg-clone-id-error').text(resp.message);
|
83 |
+
} else {
|
84 |
+
$('#wpstg-new-clone-id').addClass('wpstg-error-input');
|
85 |
+
$('#wpstg-start-cloning').attr('disabled', 'disabled');
|
86 |
+
$('#wpstg-clone-id-error').text(resp.message);
|
87 |
+
}
|
88 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
89 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is often caused by other plugins. Enable first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
90 |
+
console.log(xhr.statusText);
|
91 |
+
});
|
92 |
+
});
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Check cloning path
|
96 |
+
*/
|
97 |
+
$('#wpstg-workflow').on('keyup', '#wpstg-clone-path', function () {
|
98 |
+
var path = this.value;
|
99 |
+
if (path.length < 1) {
|
100 |
+
$('#wpstg-clone-path').removeClass('wpstg-error-input');
|
101 |
+
$('#wpstg-start-cloning').removeAttr('disabled');
|
102 |
+
$('#wpstg-path-error').text('');
|
103 |
+
return true;
|
104 |
+
}
|
105 |
+
|
106 |
+
var data = {
|
107 |
+
action: 'wpstg_check_path',
|
108 |
+
path: path
|
109 |
+
};
|
110 |
+
|
111 |
+
$.post(ajaxurl, data, function (resp, status, xhr) {
|
112 |
+
if (resp) {
|
113 |
+
$('#wpstg-clone-path').removeClass('wpstg-error-input');
|
114 |
+
$('#wpstg-start-cloning').removeAttr('disabled');
|
115 |
+
$('#wpstg-path-error').text('');
|
116 |
+
} else {
|
117 |
+
$('#wpstg-clone-path').addClass('wpstg-error-input');
|
118 |
+
$('#wpstg-start-cloning').attr('disabled', 'disabled');
|
119 |
+
$('#wpstg-path-error').text('Folder does not exist or is not writable!');
|
120 |
+
}
|
121 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
122 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
123 |
+
console.log(xhr.statusText);
|
124 |
+
});
|
125 |
+
});
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Edit profile
|
129 |
+
*/
|
130 |
+
$('#wpstg-workflow').on('click', '.wpstg-edit-clone', function (e) {
|
131 |
+
e.preventDefault();
|
132 |
+
|
133 |
+
var data = {
|
134 |
+
action: 'wpstg_edit_profile',
|
135 |
+
clone: $(this).data('clone'),
|
136 |
+
nonce: wpstg.nonce
|
137 |
+
};
|
138 |
+
$('#wpstg-workflow').load(ajaxurl, data);
|
139 |
+
});
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Save profile
|
143 |
+
*/
|
144 |
+
$('#wpstg-workflow').on('click', '#wpstg-save-profile', function (e) {
|
145 |
+
e.preventDefault();
|
146 |
+
|
147 |
+
var data = {
|
148 |
+
action: 'wpstg_save_profile',
|
149 |
+
cloneID: $(this).data('clone'),
|
150 |
+
nonce: wpstg.nonce,
|
151 |
+
dbCredentials: {
|
152 |
+
dbname: $('#wpstgdb-name').val(),
|
153 |
+
dbuser: $('#wpstgdb-user').val(),
|
154 |
+
dbpassword: $('#wpstgdb-password').val(),
|
155 |
+
dbhost: $('#wpstgdb-host').val()
|
156 |
+
}
|
157 |
+
};
|
158 |
+
wpstg_additional_data(data, false);
|
159 |
+
$.post(ajaxurl, data, function (resp, status, xhr) {
|
160 |
+
location.reload();
|
161 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
162 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
163 |
+
console.log(xhr.statusText);
|
164 |
+
});
|
165 |
+
});
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Next step
|
169 |
+
*/
|
170 |
+
$('#wpstg-workflow').on('click', '.wpstg-next-step-link', function (e) {
|
171 |
+
e.preventDefault();
|
172 |
+
if ($(this).attr('disabled'))
|
173 |
+
return false;
|
174 |
+
|
175 |
+
$('#wpstg-workflow').addClass('loading');
|
176 |
+
var data = {
|
177 |
+
action: $(this).data('action'),
|
178 |
+
nonce: wpstg.nonce
|
179 |
+
};
|
180 |
+
if (data.action == 'wpstg_cloning') {
|
181 |
+
data.cloneID = $('#wpstg-new-clone-id').val() || new Date().getTime();
|
182 |
+
wpstg_additional_data(data, false);
|
183 |
+
}
|
184 |
+
|
185 |
+
$('#wpstg-workflow').load(ajaxurl, data, function (response, status, xhr) {
|
186 |
+
if ( status == 'error') { //Unknown error
|
187 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
188 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this: ' + xhr.status + ' ' + xhr.statusText);
|
189 |
+
}
|
190 |
+
$('#wpstg-workflow').removeClass('loading');
|
191 |
+
$('.wpstg-current-step').removeClass('wpstg-current-step')
|
192 |
+
.next('li').addClass('wpstg-current-step');
|
193 |
+
if (data.action == 'wpstg_cloning') {
|
194 |
+
clone_db();
|
195 |
+
}
|
196 |
+
});
|
197 |
+
});
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Previous step
|
201 |
+
*/
|
202 |
+
$('#wpstg-workflow').on('click', '.wpstg-prev-step-link', function (e) {
|
203 |
+
e.preventDefault();
|
204 |
+
$('#wpstg-workflow').addClass('loading');
|
205 |
+
var data = {
|
206 |
+
action: 'wpstg_overview',
|
207 |
+
nonce: wpstg.nonce
|
208 |
+
};
|
209 |
+
$('#wpstg-workflow').load(ajaxurl, data, function (response, status, xhr) {
|
210 |
+
if ( status == 'error') { //Unknown error
|
211 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
212 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this: ' + xhr.status + ' ' + xhr.statusText);
|
213 |
+
}
|
214 |
+
$('#wpstg-workflow').removeClass('loading');
|
215 |
+
$('.wpstg-current-step').removeClass('wpstg-current-step')
|
216 |
+
.prev('li').addClass('wpstg-current-step');
|
217 |
+
});
|
218 |
+
});
|
219 |
+
|
220 |
+
var cloneID;
|
221 |
+
function wpstg_additional_data(data, isRemoving) {
|
222 |
+
data.uncheckedTables = [];
|
223 |
+
$('.wpstg-db-table input:not(:checked)').each(function () {
|
224 |
+
data.uncheckedTables.push(this.name);
|
225 |
+
});
|
226 |
+
data.excludedFolders = [];
|
227 |
+
$('.wpstg-dir input:not(:checked)').each(function () {
|
228 |
+
if (! $(this).parent('.wpstg-dir').parents('.wpstg-dir').children('.wpstg-expand-dirs').hasClass('disabled'))
|
229 |
+
data.excludedFolders.push(this.name);
|
230 |
+
});
|
231 |
+
|
232 |
+
cloneID = data.cloneID.toString();
|
233 |
+
}
|
234 |
+
|
235 |
+
/*
|
236 |
+
* Start scanning process
|
237 |
+
*/
|
238 |
+
$('#wpstg-workflow').on('click', '.wpstg-execute-clone', function (e) {
|
239 |
+
e.preventDefault();
|
240 |
+
$('#wpstg-workflow').addClass('loading');
|
241 |
+
var data = {
|
242 |
+
action: 'wpstg_scanning',
|
243 |
+
clone: $(this).data('clone'),
|
244 |
+
nonce: wpstg.nonce
|
245 |
+
};
|
246 |
+
|
247 |
+
$('#wpstg-workflow').load(ajaxurl, data, function (response, status, xhr) {
|
248 |
+
if ( status == 'error') { //Unknown error
|
249 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
250 |
+
wpstg_show_error_die('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ' + xhr.status + ' ' + xhr.statusText);
|
251 |
+
}
|
252 |
+
$('#wpstg-workflow').removeClass('loading');
|
253 |
+
$('.wpstg-current-step').removeClass('wpstg-current-step')
|
254 |
+
.next('li').addClass('wpstg-current-step');
|
255 |
+
});
|
256 |
+
});
|
257 |
+
|
258 |
+
$('#wpstg-workflow').on('click', '.wpstg-remove-clone', function (e) {
|
259 |
+
e.preventDefault();
|
260 |
+
$('.wpstg-clone').removeClass('active');
|
261 |
+
$( '#wpstg-existing-clones' ).append( ajax_spinner );
|
262 |
+
var data = {
|
263 |
+
action: 'wpstg_preremove',
|
264 |
+
cloneID: $(this).data('clone')
|
265 |
+
};
|
266 |
+
$('#wpstg-removing-clone').load(ajaxurl, data, function (resp, status, xhr){
|
267 |
+
if ( status == 'error') { //Unknown error
|
268 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
269 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
270 |
+
}
|
271 |
+
if (status === 'success'){
|
272 |
+
$('#wpstg-existing-clones').children("img").remove();
|
273 |
+
}
|
274 |
+
});
|
275 |
+
});
|
276 |
+
|
277 |
+
$('#wpstg-workflow').on('click', '#wpstg-cancel-removing', function (e) {
|
278 |
+
e.preventDefault();
|
279 |
+
$('.wpstg-clone').removeClass('active');
|
280 |
+
$('#wpstg-removing-clone').html('');
|
281 |
+
});
|
282 |
+
|
283 |
+
$('#wpstg-workflow').on('click', '#wpstg-remove-clone', function (e) {
|
284 |
+
e.preventDefault();
|
285 |
+
$('#wpstg-removing-clone').addClass('loading');
|
286 |
+
var cloneID = $(this).data('clone');
|
287 |
+
var data = {
|
288 |
+
action: 'wpstg_remove_clone',
|
289 |
+
cloneID: cloneID,
|
290 |
+
nonce: wpstg.nonce
|
291 |
+
};
|
292 |
+
|
293 |
+
wpstg_additional_data(data, true);
|
294 |
+
$.post(ajaxurl, data, function (resp, status, xhr) {
|
295 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
296 |
+
if ( status == 'error') { //Unknown error
|
297 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
298 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
299 |
+
}
|
300 |
+
if (resp == 0) {
|
301 |
+
$('#wpstg-removing-clone').html('');
|
302 |
+
$('.wpstg-clone#' + cloneID).remove();
|
303 |
+
$('#wpstg-removing-clone').removeClass('loading');
|
304 |
+
var remaining_clones = $('.wpstg-clone');
|
305 |
+
if (remaining_clones.length < 1)
|
306 |
+
$('#wpstg-existing-clones h3').text('');
|
307 |
+
}
|
308 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
309 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
310 |
+
console.log(xhr.statusText);
|
311 |
+
});
|
312 |
+
});
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Show error message and die()
|
316 |
+
* Writes error message into log file
|
317 |
+
*
|
318 |
+
* @param {string} $error notice
|
319 |
+
* @returns void
|
320 |
+
*/
|
321 |
+
function wpstg_show_error_die(error) {
|
322 |
+
$('#wpstg-try-again').css('display', 'inline-block');
|
323 |
+
$('#wpstg-cancel-cloning').text('Reset');
|
324 |
+
$('#wpstg-cloning-result').text('Fail');
|
325 |
+
$('#wpstg-error-wrapper').show();
|
326 |
+
$('#wpstg-error-details').show();
|
327 |
+
$('#wpstg-error-details').html(error);
|
328 |
+
$('#wpstg-loader').hide();
|
329 |
+
isFinished = true; // die cloning process
|
330 |
+
console.log(error);
|
331 |
+
var add_error = ' Fatal Error: This should not happen! Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not fix it enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out what is causing this.';
|
332 |
+
var data = {
|
333 |
+
action: 'wpstg_error_processing',
|
334 |
+
wpstg_error_msg: error + add_error
|
335 |
+
};
|
336 |
+
$.post(ajaxurl, data);
|
337 |
+
}
|
338 |
+
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Clone database
|
342 |
+
*
|
343 |
+
* @return void
|
344 |
+
*/
|
345 |
+
var isCanceled = false;
|
346 |
+
function clone_db() {
|
347 |
+
|
348 |
+
setTimeout(function(){ // timeout of x sec - prevent security blocks and cpu overload
|
349 |
+
$('#wpstg-loader').show();
|
350 |
+
var data = {
|
351 |
+
action: 'wpstg_clone_db',
|
352 |
+
nonce: wpstg.nonce
|
353 |
+
};
|
354 |
+
$.post(ajaxurl, data, function (resp, status, xhr) {
|
355 |
+
if (isCanceled) {
|
356 |
+
cancelCloning();
|
357 |
+
return false;
|
358 |
+
}
|
359 |
+
if ( status == "error" ) { //Unknown error
|
360 |
+
wpstg_show_error_die('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ' . xhr.statusText);
|
361 |
+
} else if (!wpstgIsJsonObj(resp)) { //Unknown error
|
362 |
+
wpstg_show_error_die('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ' . xhr.statusText);
|
363 |
+
} else if (resp.percent < 0) { //Fail
|
364 |
+
wpstg_show_error_die('Fatal Error: This should never happen. Please try again! <br>If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ' . xhr.statusText);
|
365 |
+
} else if(resp.percent < 1) { //Continue cloning
|
366 |
+
var complete = Math.floor(resp.percent * 100) + '%';
|
367 |
+
$('#wpstg-db-progress').text(complete).css('width', complete);
|
368 |
+
$('#wpstg-error-wrapper').show();
|
369 |
+
if (resp.message !== '')
|
370 |
+
$('#wpstg-log-details').append(resp.message);
|
371 |
+
|
372 |
+
wpstg_logscroll_bottom();
|
373 |
+
clone_db();
|
374 |
+
} else { //Success cloning
|
375 |
+
$('#wpstg-db-progress').text('').css('width', '100%');
|
376 |
+
$('#wpstg-log-details').append(resp.message + '<br>');
|
377 |
+
wpstg_logscroll_bottom();
|
378 |
+
copy_files();
|
379 |
+
}
|
380 |
+
})
|
381 |
+
.fail(function(xhr) { // Will be executed when $.post() fails
|
382 |
+
wpstg_show_error_die(xhr.statusText);
|
383 |
+
console.log('Fatal Error: This should not happen but is often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
384 |
+
});
|
385 |
+
},wpstg.cpu_load); // timeout of x sec - prevent security blocks and cpu overload
|
386 |
+
}
|
387 |
+
|
388 |
+
|
389 |
+
|
390 |
+
|
391 |
+
function copy_files() {
|
392 |
+
setTimeout(function(){ // timeout of x sec - prevent security blocks and cpu overload
|
393 |
+
var data = {
|
394 |
+
action: 'wpstg_copy_files',
|
395 |
+
nonce: wpstg.nonce
|
396 |
+
};
|
397 |
+
$.post(ajaxurl, data, function(resp, status, xhr) {
|
398 |
+
if (isCanceled) {
|
399 |
+
cancelCloning();
|
400 |
+
return false;
|
401 |
+
}
|
402 |
+
|
403 |
+
if (!wpstgIsJsonObj(resp)) { //Unknown error
|
404 |
+
wpstg_show_error_die('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ');
|
405 |
+
} else if (resp.percent < 0) { //Fail
|
406 |
+
wpstg_show_error_die('Fatal Error: This should never happen. Please try again! <br>If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '. xhr.statusText);
|
407 |
+
} else if (resp.percent < 1) { //Continue copying
|
408 |
+
var complete = Math.floor(resp.percent * 100) + '%';
|
409 |
+
$('#wpstg-files-progress').text(complete).css('width', complete);
|
410 |
+
$('#wpstg-loader').show();
|
411 |
+
if (resp.message !== '')
|
412 |
+
$('#wpstg-log-details').append(resp.message + '<br>');
|
413 |
+
wpstg_logscroll_bottom();
|
414 |
+
copy_files();
|
415 |
+
} else { //Success copying
|
416 |
+
$('#wpstg-files-progress').text('').css('width', '100%');
|
417 |
+
wpstg_logscroll_bottom();
|
418 |
+
replace_links();
|
419 |
+
}
|
420 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
421 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
422 |
+
console.log(xhr.statusText);
|
423 |
+
});
|
424 |
+
},wpstg.cpu_load); // timeout of x sec - prevent security blocks and cpu overload
|
425 |
+
}
|
426 |
+
|
427 |
+
var isFinished = false;
|
428 |
+
function replace_links() {
|
429 |
+
var data = {
|
430 |
+
action: 'wpstg_replace_links',
|
431 |
+
nonce: wpstg.nonce
|
432 |
+
};
|
433 |
+
$.post(ajaxurl, data, function(resp, status, xhr) {
|
434 |
+
if (isCanceled) {
|
435 |
+
cancelCloning();
|
436 |
+
return false;
|
437 |
+
}
|
438 |
+
|
439 |
+
if (!wpstgIsJsonObj(resp)) { //Unknown error
|
440 |
+
wpstg_show_error_die('Fatal Error code: 1001. This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ');
|
441 |
+
} else if (resp.percent < 0) { //Fail
|
442 |
+
wpstg_show_error_die('Fatal Error code: 1002. This should never happen. Please try again! <br>If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ' . xhr.statusText);
|
443 |
+
} else if (resp.percent < 1) { //Continue replacing string
|
444 |
+
var complete = Math.floor(resp.percent * 100) + '%';
|
445 |
+
$('#wpstg-links-progress').text('').css('width', complete);
|
446 |
+
$('#wpstg-loader').show();
|
447 |
+
if (resp.message !== '')
|
448 |
+
$('#wpstg-log-details').append(resp.message + '<br>');
|
449 |
+
wpstg_logscroll_bottom();
|
450 |
+
replace_links();
|
451 |
+
} else { //Success
|
452 |
+
$('#wpstg-links-progress').text('').css('width', '100%');
|
453 |
+
$('#wpstg-loader').hide();
|
454 |
+
wpstg_logscroll_bottom();
|
455 |
+
cloneID = cloneID.replace(/[^A-Za-z0-9]/g, '');
|
456 |
+
var redirectURL = $('#wpstg-clone-url').attr('href') + '/' + cloneID + '/';
|
457 |
+
setTimeout(function () {
|
458 |
+
$('#wpstg-finished-result').show();
|
459 |
+
$('#wpstg-clone-url').text('Visit staging site <span style="font-size: 10px;">(login with your admin credentials)</span>' . cloneID).attr('href', redirectURL );
|
460 |
+
$('#wpstg_staging_name').text(cloneID);
|
461 |
+
$('#wpstg-cancel-cloning').hide();
|
462 |
+
$('#wpstg-home-link').css('display', 'inline-block');
|
463 |
+
isFinished = true;
|
464 |
+
}, 1200);
|
465 |
+
if (resp.message !== '')
|
466 |
+
$('#wpstg-log-details').append(resp.message + '<br>');
|
467 |
+
wpstg_logscroll_bottom();
|
468 |
+
}
|
469 |
+
|
470 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
471 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is sometimes caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
472 |
+
console.log(xhr.statusText);
|
473 |
+
});
|
474 |
+
};
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Show error log button
|
478 |
+
*/
|
479 |
+
$('#wpstg-workflow').on('click', '#wpstg-show-log-button', function (e) {
|
480 |
+
e.preventDefault();
|
481 |
+
$('#wpstg-log-details').toggle();
|
482 |
+
$('html, body').animate({
|
483 |
+
scrollTop: $("#wpstg-log-details").offset().top
|
484 |
+
}, 400);
|
485 |
+
});
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Scroll the log window to the bottom
|
489 |
+
*
|
490 |
+
* @return void
|
491 |
+
*/
|
492 |
+
function wpstg_logscroll_bottom(){
|
493 |
+
var $mydiv = $('#wpstg-log-details');
|
494 |
+
$mydiv.scrollTop($mydiv[0].scrollHeight);
|
495 |
+
}
|
496 |
+
|
497 |
+
/**
|
498 |
+
* Cancel Cloning process button
|
499 |
+
*/
|
500 |
+
$('#wpstg-workflow').on('click', '#wpstg-cancel-cloning', function (e) {
|
501 |
+
e.preventDefault();
|
502 |
+
if (! confirm('Are you sure?'))
|
503 |
+
return false;
|
504 |
+
$('#wpstg-try-again, #wpstg-home-link').hide();
|
505 |
+
$(this).attr('disabled', 'disabled');
|
506 |
+
isCanceled = true;
|
507 |
+
$('#wpstg-cloning-result').text('Please wait...this can take up to a minute');
|
508 |
+
$('#wpstg-loader').hide();
|
509 |
+
$('#wpstg-show-log-button').hide();
|
510 |
+
$( this ).parent().append( ajax_spinner );
|
511 |
+
if (isFinished)
|
512 |
+
cancelCloning();
|
513 |
+
});
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Remove Clone button
|
517 |
+
*/
|
518 |
+
$('#wpstg-workflow').on('click', '#wpstg-remove-cloning', function (e) {
|
519 |
+
e.preventDefault();
|
520 |
+
if (! confirm('Are you sure you want to remove the clone site ?'))
|
521 |
+
return false;
|
522 |
+
$('#wpstg-try-again, #wpstg-home-link').hide();
|
523 |
+
$(this).attr('disabled', 'disabled');
|
524 |
+
$('#wpstg-clone-url').attr('disabled', 'disabled');
|
525 |
+
isCanceled = true;
|
526 |
+
$('#wpstg-cloning-result').text('Please wait...this can take up to a minute');
|
527 |
+
$('#wpstg-loader').hide();
|
528 |
+
$('#wpstg-success-notice').hide();
|
529 |
+
$('#wpstg-show-log-button').hide();
|
530 |
+
$('#wpstg-log-details').hide();
|
531 |
+
$( this ).parent().append( ajax_spinner );
|
532 |
+
if (isFinished)
|
533 |
+
cancelCloning();
|
534 |
+
});
|
535 |
+
|
536 |
+
/**
|
537 |
+
* Try again button
|
538 |
+
*/
|
539 |
+
$('#wpstg-workflow').on('click', '#wpstg-try-again', function (e) {
|
540 |
+
e.preventDefault();
|
541 |
+
console.log('test');
|
542 |
+
$('#wpstg-workflow').addClass('loading');
|
543 |
+
var data = {
|
544 |
+
action: 'wpstg_scanning',
|
545 |
+
nonce: wpstg.nonce
|
546 |
+
};
|
547 |
+
$('#wpstg-workflow').load(ajaxurl, data, function (response, status, xhr) {
|
548 |
+
if ( status == 'error') { //Unknown error
|
549 |
+
console.log(xhr.status + ' ' + xhr.statusText);
|
550 |
+
wpstg_show_error_die('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
551 |
+
}
|
552 |
+
$('#wpstg-workflow').removeClass('loading');
|
553 |
+
$('.wpstg-current-step').removeClass('wpstg-current-step')
|
554 |
+
.prev('li').addClass('wpstg-current-step');
|
555 |
+
});
|
556 |
+
});
|
557 |
+
|
558 |
+
/**
|
559 |
+
* Reset button
|
560 |
+
*/
|
561 |
+
$('#wpstg-workflow').on('click', '#wpstg-reset-clone', function (e) {
|
562 |
+
e.preventDefault();
|
563 |
+
$(this).attr('disabled', 'disabled')
|
564 |
+
.next('.wpstg-next-step-link').hide();
|
565 |
+
$('#wpstg-loader').show();
|
566 |
+
cloneID = $(this).data('clone');
|
567 |
+
cancelCloning();
|
568 |
+
});
|
569 |
+
|
570 |
+
/**
|
571 |
+
* Cancel Cloning process
|
572 |
+
*
|
573 |
+
* @returns void
|
574 |
+
*/
|
575 |
+
function cancelCloning() {
|
576 |
+
var data = {
|
577 |
+
action: 'wpstg_cancel_cloning',
|
578 |
+
nonce: wpstg.nonce,
|
579 |
+
cloneID: cloneID
|
580 |
+
};
|
581 |
+
$.post(ajaxurl, data, function (resp, status, xhr) {
|
582 |
+
if (resp == 0) {
|
583 |
+
$('#wpstg-cloning-result').text('');
|
584 |
+
$('#wpstg-cancel-cloning').text('Success').addClass('success').removeAttr('disabled');
|
585 |
+
location.reload();
|
586 |
+
}
|
587 |
+
}).fail(function(xhr) { // Will be executed when $.post() fails
|
588 |
+
wpstg_show_error_die(xhr.statusText);
|
589 |
+
console.log('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> ' + xhr.status + ' ' + xhr.statusText);
|
590 |
+
});
|
591 |
+
}
|
592 |
+
|
593 |
+
$('#wpstg-workflow').on('click', '#wpstg-home-link', function (e) {
|
594 |
+
e.preventDefault();
|
595 |
+
location.reload();
|
596 |
+
});
|
597 |
+
|
598 |
+
/**
|
599 |
+
* Tabs
|
600 |
+
*/
|
601 |
+
$('#wpstg-workflow').on('click', '.wpstg-tab-header', function (e) {
|
602 |
+
e.preventDefault();
|
603 |
+
var section = $(this).data('id');
|
604 |
+
$(this).toggleClass('expand');
|
605 |
+
$(section).slideToggle();
|
606 |
+
if ($(this).hasClass('expand'))
|
607 |
+
$(this).find('.wpstg-tab-triangle').html('▼');
|
608 |
+
else
|
609 |
+
$(this).find('.wpstg-tab-triangle').html('►');
|
610 |
+
|
611 |
+
});
|
612 |
+
|
613 |
+
/**
|
614 |
+
* Directory structure
|
615 |
+
*/
|
616 |
+
$('#wpstg-workflow').on('click', '.wpstg-expand-dirs', function (e) {
|
617 |
+
e.preventDefault();
|
618 |
+
if (! $(this).hasClass('disabled'))
|
619 |
+
$(this).siblings('.wpstg-subdir').slideToggle();
|
620 |
+
});
|
621 |
+
|
622 |
+
|
623 |
+
$('#wpstg-workflow').on('change', '.wpstg-check-dir', function () {
|
624 |
+
var dir = $(this).parent('.wpstg-dir');
|
625 |
+
if (this.checked) {
|
626 |
+
dir.parents('.wpstg-dir').children('.wpstg-check-dir').attr('checked', 'checked');
|
627 |
+
dir.find('.wpstg-expand-dirs').removeClass('disabled');
|
628 |
+
dir.find('.wpstg-subdir .wpstg-check-dir').attr('checked', 'checked');
|
629 |
+
} else {
|
630 |
+
dir.find('.wpstg-dir .wpstg-check-dir').removeAttr('checked');
|
631 |
+
dir.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');
|
632 |
+
dir.find('.wpstg-check-subdirs').data('action', 'check').text('check');
|
633 |
+
dir.children('.wpstg-subdir').slideUp();
|
634 |
+
}
|
635 |
+
});
|
636 |
+
|
637 |
+
/**
|
638 |
+
* install must-use plugin
|
639 |
+
*/
|
640 |
+
|
641 |
+
$( '#plugin-compatibility' ).change( function( e ) {
|
642 |
+
var install = '1';
|
643 |
+
if ( $( this ).is( ':checked' ) ) {
|
644 |
+
var answer = confirm( wpstg.mu_plugin_confirmation );
|
645 |
+
|
646 |
+
if ( !answer ) {
|
647 |
+
$( this ).prop( 'checked', false );
|
648 |
+
return;
|
649 |
+
}
|
650 |
+
} else {
|
651 |
+
install = '0';
|
652 |
+
}
|
653 |
+
|
654 |
+
$( '.plugin-compatibility-wrap' ).toggle();
|
655 |
+
|
656 |
+
$( this ).parent().append( ajax_spinner );
|
657 |
+
$( '#plugin-compatibility' ).attr( 'disabled', 'disabled' );
|
658 |
+
$( '.plugin-compatibility' ).addClass( 'disabled' );
|
659 |
+
|
660 |
+
$.ajax( {
|
661 |
+
url: ajaxurl,
|
662 |
+
type: 'POST',
|
663 |
+
dataType: 'text',
|
664 |
+
cache: false,
|
665 |
+
data: {
|
666 |
+
action: 'wpstg_muplugin_install',
|
667 |
+
install: install
|
668 |
+
},
|
669 |
+
error: function( jqXHR, textStatus, errorThrown ) {
|
670 |
+
alert( "Error: " + wpstg.plugin_compatibility_settings_problem + '\r\n\r\n' + wpstg.status + ' ' + jqXHR.status + ' ' + jqXHR.statusText + '\r\n\r\n' + wpstg.response + '\r\n' + jqXHR.responseText );
|
671 |
+
$( '.ajax-spinner' ).remove();
|
672 |
+
$( '#plugin-compatibility' ).removeAttr( 'disabled' );
|
673 |
+
$( '.plugin-compatibility' ).removeClass( 'disabled' );
|
674 |
+
},
|
675 |
+
success: function( data ) {
|
676 |
+
if ( '' !== $.trim( data ) ) {
|
677 |
+
alert( data );
|
678 |
+
} else {
|
679 |
+
$( '.plugin-compatibility' ).append( '<span class="ajax-success-msg">' + wpstg.saved + '</span>' );
|
680 |
+
$( '.ajax-success-msg' ).fadeOut( 2000, function() {
|
681 |
+
$( this ).remove();
|
682 |
+
} );
|
683 |
+
}
|
684 |
+
$( '.ajax-spinner' ).remove();
|
685 |
+
$( '#plugin-compatibility' ).removeAttr( 'disabled' );
|
686 |
+
$( '.plugin-compatibility' ).removeClass( 'disabled' );
|
687 |
+
}
|
688 |
+
} );
|
689 |
+
|
690 |
+
});
|
691 |
+
|
692 |
+
if ( $( '#plugin-compatibility' ).is( ':checked' ) ) {
|
693 |
+
$( '.plugin-compatibility-wrap' ).show();
|
694 |
+
}
|
695 |
+
$( '.plugin-compatibility-save' ).click( function() {
|
696 |
+
if ( doing_plugin_compatibility_ajax ) {
|
697 |
+
return;
|
698 |
+
}
|
699 |
+
$( this ).addClass( 'disabled' );
|
700 |
+
var select_element = $( '#selected-plugins' );
|
701 |
+
$( select_element ).attr( 'disabled', 'disabled' );
|
702 |
+
var query_limit = $( '#wpstg_settings\\[wpstg_query_limit\\]' );
|
703 |
+
var batch_size = $( '#wpstg_settings\\[wpstg_batch_size\\]' );
|
704 |
+
var disable_admin_login = $( '#wpstg_settings\\[disable_admin_login\\]' );
|
705 |
+
var uninstall_on_delete = $( '#wpstg_settings\\[uninstall_on_delete\\]' );
|
706 |
+
disable_admin_login = $( disable_admin_login ).prop('checked') ? '1' : '0';
|
707 |
+
uninstall_on_delete = $( uninstall_on_delete ).prop('checked') ? '1' : '0';
|
708 |
+
|
709 |
+
doing_plugin_compatibility_ajax = true;
|
710 |
+
$( this ).after( '<img src="' + spinner_url + '" alt="" class="plugin-compatibility-spinner general-spinner" />' );
|
711 |
+
|
712 |
+
$.ajax( {
|
713 |
+
url: ajaxurl,
|
714 |
+
type: 'POST',
|
715 |
+
dataType: 'text',
|
716 |
+
cache: false,
|
717 |
+
data: {
|
718 |
+
action: 'wpstg_disable_plugins',
|
719 |
+
blacklist_plugins: $( select_element ).val(),
|
720 |
+
query_limit: $( query_limit ).val(),
|
721 |
+
batch_size: $( batch_size ).val(),
|
722 |
+
disable_admin_login: disable_admin_login,
|
723 |
+
uninstall_on_delete: uninstall_on_delete,
|
724 |
+
|
725 |
+
},
|
726 |
+
error: function( jqXHR, textStatus, errorThrown ) {
|
727 |
+
alert( wpstg.blacklist_problem + '\r\n\r\n' + wpstg.status + ' ' + jqXHR.status + ' ' + jqXHR.statusText + '\r\n\r\n' + wpstg.response + '\r\n' + jqXHR.responseText );
|
728 |
+
$( select_element ).removeAttr( 'disabled' );
|
729 |
+
$( '.plugin-compatibility-save' ).removeClass( 'disabled' );
|
730 |
+
doing_plugin_compatibility_ajax = false;
|
731 |
+
$( '.plugin-compatibility-spinner' ).remove();
|
732 |
+
$( '.plugin-compatibility-success-msg' ).show().fadeOut( 2000 );
|
733 |
+
},
|
734 |
+
success: function( data ) {
|
735 |
+
if ( '' !== $.trim( data ) ) {
|
736 |
+
alert( data );
|
737 |
+
}
|
738 |
+
$( select_element ).removeAttr( 'disabled' );
|
739 |
+
$( '.plugin-compatibility-save' ).removeClass( 'disabled' );
|
740 |
+
doing_plugin_compatibility_ajax = false;
|
741 |
+
$( '.plugin-compatibility-spinner' ).remove();
|
742 |
+
$( '.plugin-compatibility-success-msg' ).show().fadeOut( 2000 );
|
743 |
+
}
|
744 |
+
} );
|
745 |
+
} );
|
746 |
+
|
747 |
+
// select all tables
|
748 |
+
$( '.multiselect-select-all' ).click( function() {
|
749 |
+
var multiselect = $( this ).parents( '.select-wrap' ).children( '.multiselect' );
|
750 |
+
$( 'option', multiselect ).attr( 'selected', 1 );
|
751 |
+
$( multiselect ).focus().trigger( 'change' );
|
752 |
+
} );
|
753 |
+
|
754 |
+
// deselect all tables
|
755 |
+
$( '.multiselect-deselect-all' ).click( function() {
|
756 |
+
var multiselect = $( this ).parents( '.select-wrap' ).children( '.multiselect' );
|
757 |
+
$( 'option', multiselect ).removeAttr( 'selected' );
|
758 |
+
$( multiselect ).focus().trigger( 'change' );
|
759 |
+
} );
|
760 |
+
|
761 |
+
// invert table selection
|
762 |
+
$( '.multiselect-invert-selection' ).click( function() {
|
763 |
+
var multiselect = $( this ).parents( '.select-wrap' ).children( '.multiselect' );
|
764 |
+
$( 'option', multiselect ).each( function() {
|
765 |
+
$( this ).attr( 'selected', !$( this ).attr( 'selected' ) );
|
766 |
+
} );
|
767 |
+
$( multiselect ).focus().trigger( 'change' );
|
768 |
+
} );
|
769 |
+
|
770 |
+
|
771 |
+
|
772 |
+
// Show large files
|
773 |
+
$('#wpstg-workflow').on('click', '#wpstg-show-large-files', function (e) {
|
774 |
+
e.preventDefault();
|
775 |
+
//$('#wpstg-show-large-files').on('click', ) click(function(){
|
776 |
+
$('#wpstg-large-files').toggle();
|
777 |
+
});
|
778 |
+
|
779 |
+
|
780 |
+
|
781 |
+
});
|
782 |
+
})(jQuery);
|
783 |
+
|
784 |
+
// Load twitter button async
|
785 |
+
window.twttr = (function(d, s, id) {
|
786 |
+
var js, fjs = d.getElementsByTagName(s)[0],
|
787 |
+
t = window.twttr || {};
|
788 |
+
if (d.getElementById(id)) return t;
|
789 |
+
js = d.createElement(s);
|
790 |
+
js.id = id;
|
791 |
+
js.src = "https://platform.twitter.com/widgets.js";
|
792 |
+
fjs.parentNode.insertBefore(js, fjs);
|
793 |
+
|
794 |
+
t._e = [];
|
795 |
+
t.ready = function(f) {
|
796 |
+
t._e.push(f);
|
797 |
+
};
|
798 |
+
|
799 |
+
return t;
|
800 |
+
}(document, "script", "twitter-wjs"));
|
assets/js/wpstg-admin.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(a){a(document).ready(function(){function b(a){return"object"==typeof a?!0:void 0}function c(b){b.uncheckedTables=[],a(".wpstg-db-table input:not(:checked)").each(function(){b.uncheckedTables.push(this.name)}),b.excludedFolders=[],a(".wpstg-dir input:not(:checked)").each(function(){a(this).parent(".wpstg-dir").parents(".wpstg-dir").children(".wpstg-expand-dirs").hasClass("disabled")||b.excludedFolders.push(this.name)}),o=b.cloneID.toString()}function d(b){a("#wpstg-try-again").css("display","inline-block"),a("#wpstg-cancel-cloning").text("Reset"),a("#wpstg-cloning-result").text("Fail"),a("#wpstg-error-wrapper").show(),a("#wpstg-error-details").show(),a("#wpstg-error-details").html(b),a("#wpstg-loader").hide(),q=!0,console.log(b);var c=' Fatal Error: This should not happen! Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not fix it enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out what is causing this.',d={action:"wpstg_error_processing",wpstg_error_msg:b+c};a.post(ajaxurl,d)}function e(){setTimeout(function(){a("#wpstg-loader").show();var c={action:"wpstg_clone_db",nonce:wpstg.nonce};a.post(ajaxurl,c,function(c,g){if(p)return i(),!1;if("error"==g)d('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '.xhr.statusText);else if(b(c))if(c.percent<0)d('Fatal Error: This should never happen. Please try again! <br>If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '.xhr.statusText);else if(c.percent<1){var j=Math.floor(100*c.percent)+"%";a("#wpstg-db-progress").text(j).css("width",j),a("#wpstg-error-wrapper").show(),""!==c.message&&a("#wpstg-log-details").append(c.message),h(),e()}else a("#wpstg-db-progress").text("").css("width","100%"),a("#wpstg-log-details").append(c.message+"<br>"),h(),f();else d('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '.xhr.statusText)}).fail(function(a){d(a.statusText),console.log('Fatal Error: This should not happen but is often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText)})},wpstg.cpu_load)}function f(){setTimeout(function(){var c={action:"wpstg_copy_files",nonce:wpstg.nonce};a.post(ajaxurl,c,function(c){if(p)return i(),!1;if(b(c))if(c.percent<0)d('Fatal Error: This should never happen. Please try again! <br>If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '.xhr.statusText);else if(c.percent<1){var e=Math.floor(100*c.percent)+"%";a("#wpstg-files-progress").text(e).css("width",e),a("#wpstg-loader").show(),""!==c.message&&a("#wpstg-log-details").append(c.message+"<br>"),h(),f()}else a("#wpstg-files-progress").text("").css("width","100%"),h(),g();else d('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ')}).fail(function(a){d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText),console.log(a.statusText)})},wpstg.cpu_load)}function g(){var c={action:"wpstg_replace_links",nonce:wpstg.nonce};a.post(ajaxurl,c,function(c){if(p)return i(),!1;if(b(c))if(c.percent<0)d('Fatal Error code: 1002. This should never happen. Please try again! <br>If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '.xhr.statusText);else if(c.percent<1){var e=Math.floor(100*c.percent)+"%";a("#wpstg-links-progress").text("").css("width",e),a("#wpstg-loader").show(),""!==c.message&&a("#wpstg-log-details").append(c.message+"<br>"),h(),g()}else{a("#wpstg-links-progress").text("").css("width","100%"),a("#wpstg-loader").hide(),h(),o=o.replace(/[^A-Za-z0-9]/g,"");var f=a("#wpstg-clone-url").attr("href")+"/"+o+"/";setTimeout(function(){a("#wpstg-finished-result").show(),a("#wpstg-clone-url").text('Visit staging site <span style="font-size: 10px;">(login with your admin credentials)</span>'.cloneID).attr("href",f),a("#wpstg_staging_name").text(o),a("#wpstg-cancel-cloning").hide(),a("#wpstg-home-link").css("display","inline-block"),q=!0},1200),""!==c.message&&a("#wpstg-log-details").append(c.message+"<br>"),h()}else d('Fatal Error code: 1001. This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> ')}).fail(function(a){d('Fatal Error: This should not happen but is sometimes caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText),console.log(a.statusText)})}function h(){var b=a("#wpstg-log-details");b.scrollTop(b[0].scrollHeight)}function i(){var b={action:"wpstg_cancel_cloning",nonce:wpstg.nonce,cloneID:o};a.post(ajaxurl,b,function(b){0==b&&(a("#wpstg-cloning-result").text(""),a("#wpstg-cancel-cloning").text("Success").addClass("success").removeAttr("disabled"),location.reload())}).fail(function(a){d(a.statusText),console.log('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText)})}var j=!0;a("#wpstg-workflow").on("click",".wpstg-button-unselect",function(b){b.preventDefault(),0==j?(a(".wpstg-db-table-checkboxes").attr("checked","checked"),a(".wpstg-button-unselect").html("Uncheck All"),j=!0):(a(".wpstg-db-table-checkboxes").removeAttr("checked"),a(".wpstg-button-unselect").html("Check All"),j=!1)});var k=ajaxurl.replace("/admin-ajax.php",""),l=k+"/images/spinner";2<window.devicePixelRatio&&(l+="-2x"),l+=".gif";var m='<img src="'+l+'" alt="" class="ajax-spinner general-spinner" />',n=!1;a("#wpstg-workflow").on("keyup","#wpstg-new-clone-id",function(){var b={action:"wpstg_check_clone",cloneID:this.value};a.post(ajaxurl,b,function(b){"fail"!==b.status?(a("#wpstg-new-clone-id").removeClass("wpstg-error-input"),a("#wpstg-start-cloning").removeAttr("disabled"),a("#wpstg-clone-id-error").text(b.message)):(a("#wpstg-new-clone-id").addClass("wpstg-error-input"),a("#wpstg-start-cloning").attr("disabled","disabled"),a("#wpstg-clone-id-error").text(b.message))}).fail(function(a){d('Fatal Error: This should not happen but is often caused by other plugins. Enable first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText),console.log(a.statusText)})}),a("#wpstg-workflow").on("keyup","#wpstg-clone-path",function(){var b=this.value;if(b.length<1)return a("#wpstg-clone-path").removeClass("wpstg-error-input"),a("#wpstg-start-cloning").removeAttr("disabled"),a("#wpstg-path-error").text(""),!0;var c={action:"wpstg_check_path",path:b};a.post(ajaxurl,c,function(b){b?(a("#wpstg-clone-path").removeClass("wpstg-error-input"),a("#wpstg-start-cloning").removeAttr("disabled"),a("#wpstg-path-error").text("")):(a("#wpstg-clone-path").addClass("wpstg-error-input"),a("#wpstg-start-cloning").attr("disabled","disabled"),a("#wpstg-path-error").text("Folder does not exist or is not writable!"))}).fail(function(a){d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText),console.log(a.statusText)})}),a("#wpstg-workflow").on("click",".wpstg-edit-clone",function(b){b.preventDefault();var c={action:"wpstg_edit_profile",clone:a(this).data("clone"),nonce:wpstg.nonce};a("#wpstg-workflow").load(ajaxurl,c)}),a("#wpstg-workflow").on("click","#wpstg-save-profile",function(b){b.preventDefault();var e={action:"wpstg_save_profile",cloneID:a(this).data("clone"),nonce:wpstg.nonce,dbCredentials:{dbname:a("#wpstgdb-name").val(),dbuser:a("#wpstgdb-user").val(),dbpassword:a("#wpstgdb-password").val(),dbhost:a("#wpstgdb-host").val()}};c(e,!1),a.post(ajaxurl,e,function(){location.reload()}).fail(function(a){d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText),console.log(a.statusText)})}),a("#wpstg-workflow").on("click",".wpstg-next-step-link",function(b){if(b.preventDefault(),a(this).attr("disabled"))return!1;a("#wpstg-workflow").addClass("loading");var f={action:a(this).data("action"),nonce:wpstg.nonce};"wpstg_cloning"==f.action&&(f.cloneID=a("#wpstg-new-clone-id").val()||(new Date).getTime(),c(f,!1)),a("#wpstg-workflow").load(ajaxurl,f,function(b,c,g){"error"==c&&(console.log(g.status+" "+g.statusText),d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this: '+g.status+" "+g.statusText)),a("#wpstg-workflow").removeClass("loading"),a(".wpstg-current-step").removeClass("wpstg-current-step").next("li").addClass("wpstg-current-step"),"wpstg_cloning"==f.action&&e()})}),a("#wpstg-workflow").on("click",".wpstg-prev-step-link",function(b){b.preventDefault(),a("#wpstg-workflow").addClass("loading");var c={action:"wpstg_overview",nonce:wpstg.nonce};a("#wpstg-workflow").load(ajaxurl,c,function(b,c,e){"error"==c&&(console.log(e.status+" "+e.statusText),d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this: '+e.status+" "+e.statusText)),a("#wpstg-workflow").removeClass("loading"),a(".wpstg-current-step").removeClass("wpstg-current-step").prev("li").addClass("wpstg-current-step")})});var o;a("#wpstg-workflow").on("click",".wpstg-execute-clone",function(b){b.preventDefault(),a("#wpstg-workflow").addClass("loading");var c={action:"wpstg_scanning",clone:a(this).data("clone"),nonce:wpstg.nonce};a("#wpstg-workflow").load(ajaxurl,c,function(b,c,e){"error"==c&&(console.log(e.status+" "+e.statusText),d('Fatal Error: This should not happen. Please try again! <br> If restarting does not work <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">get in contact with us</a> '+e.status+" "+e.statusText)),a("#wpstg-workflow").removeClass("loading"),a(".wpstg-current-step").removeClass("wpstg-current-step").next("li").addClass("wpstg-current-step")})}),a("#wpstg-workflow").on("click",".wpstg-remove-clone",function(b){b.preventDefault(),a(".wpstg-clone").removeClass("active"),a("#wpstg-existing-clones").append(m);var c={action:"wpstg_preremove",cloneID:a(this).data("clone")};a("#wpstg-removing-clone").load(ajaxurl,c,function(b,c,e){"error"==c&&(console.log(e.status+" "+e.statusText),d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+e.status+" "+e.statusText)),"success"===c&&a("#wpstg-existing-clones").children("img").remove()})}),a("#wpstg-workflow").on("click","#wpstg-cancel-removing",function(b){b.preventDefault(),a(".wpstg-clone").removeClass("active"),a("#wpstg-removing-clone").html("")}),a("#wpstg-workflow").on("click","#wpstg-remove-clone",function(b){b.preventDefault(),a("#wpstg-removing-clone").addClass("loading");var e=a(this).data("clone"),f={action:"wpstg_remove_clone",cloneID:e,nonce:wpstg.nonce};c(f,!0),a.post(ajaxurl,f,function(b,c,f){if(console.log(f.status+" "+f.statusText),"error"==c&&(console.log(f.status+" "+f.statusText),d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+f.status+" "+f.statusText)),0==b){a("#wpstg-removing-clone").html(""),a(".wpstg-clone#"+e).remove(),a("#wpstg-removing-clone").removeClass("loading");var g=a(".wpstg-clone");g.length<1&&a("#wpstg-existing-clones h3").text("")}}).fail(function(a){d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+a.status+" "+a.statusText),console.log(a.statusText)})});var p=!1,q=!1;a("#wpstg-workflow").on("click","#wpstg-show-log-button",function(b){b.preventDefault(),a("#wpstg-log-details").toggle(),a("html, body").animate({scrollTop:a("#wpstg-log-details").offset().top},400)}),a("#wpstg-workflow").on("click","#wpstg-cancel-cloning",function(b){return b.preventDefault(),confirm("Are you sure?")?(a("#wpstg-try-again, #wpstg-home-link").hide(),a(this).attr("disabled","disabled"),p=!0,a("#wpstg-cloning-result").text("Please wait...this can take up to a minute"),a("#wpstg-loader").hide(),a("#wpstg-show-log-button").hide(),a(this).parent().append(m),void(q&&i())):!1}),a("#wpstg-workflow").on("click","#wpstg-remove-cloning",function(b){return b.preventDefault(),confirm("Are you sure you want to remove the clone site ?")?(a("#wpstg-try-again, #wpstg-home-link").hide(),a(this).attr("disabled","disabled"),a("#wpstg-clone-url").attr("disabled","disabled"),p=!0,a("#wpstg-cloning-result").text("Please wait...this can take up to a minute"),a("#wpstg-loader").hide(),a("#wpstg-success-notice").hide(),a("#wpstg-show-log-button").hide(),a("#wpstg-log-details").hide(),a(this).parent().append(m),void(q&&i())):!1}),a("#wpstg-workflow").on("click","#wpstg-try-again",function(b){b.preventDefault(),console.log("test"),a("#wpstg-workflow").addClass("loading");var c={action:"wpstg_scanning",nonce:wpstg.nonce};a("#wpstg-workflow").load(ajaxurl,c,function(b,c,e){"error"==c&&(console.log(e.status+" "+e.statusText),d('Fatal Error: This should not happen but is most often caused by other plugins. Try first the option "Optimizer" in WP Staging->Settings and try again. If this does not help, enable <a href="https://codex.wordpress.org/Debugging_in_WordPress" target="_blank">wordpress debug mode</a> to find out which plugin is causing this:<br> '+e.status+" "+e.statusText)),a("#wpstg-workflow").removeClass("loading"),a(".wpstg-current-step").removeClass("wpstg-current-step").prev("li").addClass("wpstg-current-step")})}),a("#wpstg-workflow").on("click","#wpstg-reset-clone",function(b){b.preventDefault(),a(this).attr("disabled","disabled").next(".wpstg-next-step-link").hide(),a("#wpstg-loader").show(),o=a(this).data("clone"),i()}),a("#wpstg-workflow").on("click","#wpstg-home-link",function(a){a.preventDefault(),location.reload()}),a("#wpstg-workflow").on("click",".wpstg-tab-header",function(b){b.preventDefault();var c=a(this).data("id");a(this).toggleClass("expand"),a(c).slideToggle(),a(this).find(".wpstg-tab-triangle").html(a(this).hasClass("expand")?"▼":"►")}),a("#wpstg-workflow").on("click",".wpstg-expand-dirs",function(b){b.preventDefault(),a(this).hasClass("disabled")||a(this).siblings(".wpstg-subdir").slideToggle()}),a("#wpstg-workflow").on("change",".wpstg-check-dir",function(){var b=a(this).parent(".wpstg-dir");this.checked?(b.parents(".wpstg-dir").children(".wpstg-check-dir").attr("checked","checked"),b.find(".wpstg-expand-dirs").removeClass("disabled"),b.find(".wpstg-subdir .wpstg-check-dir").attr("checked","checked")):(b.find(".wpstg-dir .wpstg-check-dir").removeAttr("checked"),b.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled"),b.find(".wpstg-check-subdirs").data("action","check").text("check"),b.children(".wpstg-subdir").slideUp())}),a("#plugin-compatibility").change(function(){var b="1";if(a(this).is(":checked")){var c=confirm(wpstg.mu_plugin_confirmation);if(!c)return void a(this).prop("checked",!1)}else b="0";a(".plugin-compatibility-wrap").toggle(),a(this).parent().append(m),a("#plugin-compatibility").attr("disabled","disabled"),a(".plugin-compatibility").addClass("disabled"),a.ajax({url:ajaxurl,type:"POST",dataType:"text",cache:!1,data:{action:"wpstg_muplugin_install",install:b},error:function(b){alert("Error: "+wpstg.plugin_compatibility_settings_problem+"\r\n\r\n"+wpstg.status+" "+b.status+" "+b.statusText+"\r\n\r\n"+wpstg.response+"\r\n"+b.responseText),a(".ajax-spinner").remove(),a("#plugin-compatibility").removeAttr("disabled"),a(".plugin-compatibility").removeClass("disabled")},success:function(b){""!==a.trim(b)?alert(b):(a(".plugin-compatibility").append('<span class="ajax-success-msg">'+wpstg.saved+"</span>"),a(".ajax-success-msg").fadeOut(2e3,function(){a(this).remove()})),a(".ajax-spinner").remove(),a("#plugin-compatibility").removeAttr("disabled"),a(".plugin-compatibility").removeClass("disabled")}})}),a("#plugin-compatibility").is(":checked")&&a(".plugin-compatibility-wrap").show(),a(".plugin-compatibility-save").click(function(){if(!n){a(this).addClass("disabled");var b=a("#selected-plugins");a(b).attr("disabled","disabled");var c=a("#wpstg_settings\\[wpstg_query_limit\\]"),d=a("#wpstg_settings\\[wpstg_batch_size\\]"),e=a("#wpstg_settings\\[disable_admin_login\\]"),f=a("#wpstg_settings\\[uninstall_on_delete\\]");e=a(e).prop("checked")?"1":"0",f=a(f).prop("checked")?"1":"0",n=!0,a(this).after('<img src="'+l+'" alt="" class="plugin-compatibility-spinner general-spinner" />'),a.ajax({url:ajaxurl,type:"POST",dataType:"text",cache:!1,data:{action:"wpstg_disable_plugins",blacklist_plugins:a(b).val(),query_limit:a(c).val(),batch_size:a(d).val(),disable_admin_login:e,uninstall_on_delete:f},error:function(c){alert(wpstg.blacklist_problem+"\r\n\r\n"+wpstg.status+" "+c.status+" "+c.statusText+"\r\n\r\n"+wpstg.response+"\r\n"+c.responseText),a(b).removeAttr("disabled"),a(".plugin-compatibility-save").removeClass("disabled"),n=!1,a(".plugin-compatibility-spinner").remove(),a(".plugin-compatibility-success-msg").show().fadeOut(2e3)},success:function(c){""!==a.trim(c)&&alert(c),a(b).removeAttr("disabled"),a(".plugin-compatibility-save").removeClass("disabled"),n=!1,a(".plugin-compatibility-spinner").remove(),a(".plugin-compatibility-success-msg").show().fadeOut(2e3)}})}}),a(".multiselect-select-all").click(function(){var b=a(this).parents(".select-wrap").children(".multiselect");a("option",b).attr("selected",1),a(b).focus().trigger("change")}),a(".multiselect-deselect-all").click(function(){var b=a(this).parents(".select-wrap").children(".multiselect");a("option",b).removeAttr("selected"),a(b).focus().trigger("change")}),a(".multiselect-invert-selection").click(function(){var b=a(this).parents(".select-wrap").children(".multiselect");a("option",b).each(function(){a(this).attr("selected",!a(this).attr("selected"))}),a(b).focus().trigger("change")}),a("#wpstg-workflow").on("click","#wpstg-show-large-files",function(b){b.preventDefault(),a("#wpstg-large-files").toggle()})})}(jQuery),window.twttr=function(a,b,c){var d,e=a.getElementsByTagName(b)[0],f=window.twttr||{};return a.getElementById(c)?f:(d=a.createElement(b),d.id=c,d.src="https://platform.twitter.com/widgets.js",e.parentNode.insertBefore(d,e),f._e=[],f.ready=function(a){f._e.push(a)},f)}(document,"script","twitter-wjs");
|
assets/js/wpstg.js
ADDED
File without changes
|
assets/js/wpstg.min.js
ADDED
File without changes
|
includes/WPSTG_SL_Plugin_Updater.php
ADDED
@@ -0,0 +1,377 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// uncomment this line for testing
|
4 |
+
//set_site_transient( 'update_plugins', null );
|
5 |
+
|
6 |
+
// Exit if accessed directly
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Allows plugins to use their own update API.
|
11 |
+
*
|
12 |
+
* @author Pippin Williamson, René Hermenau
|
13 |
+
* @version 1.6
|
14 |
+
*/
|
15 |
+
class WPSTG_SL_Plugin_Updater {
|
16 |
+
private $api_url = '';
|
17 |
+
private $api_data = array();
|
18 |
+
private $name = '';
|
19 |
+
private $slug = '';
|
20 |
+
private $version = '';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Class constructor.
|
24 |
+
*
|
25 |
+
* @uses plugin_basename()
|
26 |
+
* @uses hook()
|
27 |
+
*
|
28 |
+
* @param string $_api_url The URL pointing to the custom API endpoint.
|
29 |
+
* @param string $_plugin_file Path to the plugin file.
|
30 |
+
* @param array $_api_data Optional data to send with API calls.
|
31 |
+
*/
|
32 |
+
function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
33 |
+
$this->api_url = trailingslashit( $_api_url );
|
34 |
+
$this->api_data = $_api_data;
|
35 |
+
$this->name = plugin_basename( $_plugin_file );
|
36 |
+
$this->slug = basename( $_plugin_file, '.php' );
|
37 |
+
$this->version = $_api_data['version'];
|
38 |
+
$this->item_name = sanitize_title($_api_data['item_name']); //rhe return the item name words separated by hyphens
|
39 |
+
|
40 |
+
// Set up hooks.
|
41 |
+
$this->init();
|
42 |
+
add_action( 'admin_init', array( $this, 'show_changelog' ) );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Set up WordPress filters to hook into WP's update process.
|
47 |
+
*
|
48 |
+
* @uses add_filter()
|
49 |
+
*
|
50 |
+
* @return void
|
51 |
+
*/
|
52 |
+
public function init() {
|
53 |
+
|
54 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
|
55 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
56 |
+
|
57 |
+
add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Check for Updates at the defined API endpoint and modify the update array.
|
62 |
+
*
|
63 |
+
* This function dives into the update API just when WordPress creates its update array,
|
64 |
+
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
65 |
+
* It is reassembled from parts of the native WordPress plugin update code.
|
66 |
+
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
67 |
+
*
|
68 |
+
* @uses api_request()
|
69 |
+
*
|
70 |
+
* @param array $_transient_data Update array build by WordPress.
|
71 |
+
* @return array Modified update array with custom plugin data.
|
72 |
+
*/
|
73 |
+
function check_update( $_transient_data ) {
|
74 |
+
|
75 |
+
global $pagenow;
|
76 |
+
|
77 |
+
if( ! is_object( $_transient_data ) ) {
|
78 |
+
$_transient_data = new stdClass;
|
79 |
+
}
|
80 |
+
|
81 |
+
if( 'plugins.php' == $pagenow && is_multisite() ) {
|
82 |
+
return $_transient_data;
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
|
87 |
+
|
88 |
+
$version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug) );
|
89 |
+
|
90 |
+
/*echo "<pre>check_update() line 74 in WPSTG_SL_Plugin_Updater";
|
91 |
+
echo " slug: " . $this->slug;
|
92 |
+
echo " version info: " . $version_info->slug;
|
93 |
+
echo " new version :" . $version_info->new_version;
|
94 |
+
echo " item_name: " . $this->item_name;
|
95 |
+
exit;*/
|
96 |
+
|
97 |
+
if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
|
98 |
+
|
99 |
+
if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
100 |
+
|
101 |
+
$_transient_data->response[ $this->name ] = $version_info;
|
102 |
+
}
|
103 |
+
$_transient_data->last_checked = time();
|
104 |
+
$_transient_data->checked[ $this->name ] = $this->version;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
return $_transient_data;
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
|
113 |
+
*
|
114 |
+
* @param string $file
|
115 |
+
* @param array $plugin
|
116 |
+
*/
|
117 |
+
public function show_update_notification( $file, $plugin ) {
|
118 |
+
|
119 |
+
if( ! current_user_can( 'update_plugins' ) ) {
|
120 |
+
return;
|
121 |
+
}
|
122 |
+
|
123 |
+
if( ! is_multisite() ) {
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
if ( $this->name != $file ) {
|
128 |
+
return;
|
129 |
+
}
|
130 |
+
|
131 |
+
// Remove our filter on the site transient
|
132 |
+
remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
|
133 |
+
|
134 |
+
$update_cache = get_site_transient( 'update_plugins' );
|
135 |
+
|
136 |
+
if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
|
137 |
+
|
138 |
+
$cache_key = md5( 'wpstg_plugin_' .sanitize_key( $this->name ) . '_version_info' );
|
139 |
+
$version_info = get_transient( $cache_key );
|
140 |
+
|
141 |
+
if( false === $version_info ) {
|
142 |
+
$version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug) );
|
143 |
+
set_transient( $cache_key, $version_info, 3600 );
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
if( ! is_object( $version_info ) ) {
|
148 |
+
return;
|
149 |
+
}
|
150 |
+
|
151 |
+
if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
152 |
+
|
153 |
+
$update_cache->response[ $this->name ] = $version_info;
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
$update_cache->last_checked = time();
|
158 |
+
$update_cache->checked[ $this->name ] = $this->version;
|
159 |
+
|
160 |
+
set_site_transient( 'update_plugins', $update_cache );
|
161 |
+
|
162 |
+
} else {
|
163 |
+
|
164 |
+
$version_info = $update_cache->response[ $this->name ];
|
165 |
+
|
166 |
+
}
|
167 |
+
|
168 |
+
// Restore our filter
|
169 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
|
170 |
+
|
171 |
+
if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
172 |
+
|
173 |
+
// build a plugin list row, with update notification
|
174 |
+
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
175 |
+
echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
|
176 |
+
|
177 |
+
$changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
|
178 |
+
|
179 |
+
if ( empty( $version_info->download_link ) ) {
|
180 |
+
printf(
|
181 |
+
__( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a>.', 'wpstg' ),
|
182 |
+
esc_html( $version_info->name ),
|
183 |
+
esc_url( $changelog_link ),
|
184 |
+
esc_html( $version_info->new_version )
|
185 |
+
);
|
186 |
+
} else {
|
187 |
+
printf(
|
188 |
+
__( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'wpstg' ),
|
189 |
+
esc_html( $version_info->name ),
|
190 |
+
esc_url( $changelog_link ),
|
191 |
+
esc_html( $version_info->new_version ),
|
192 |
+
esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )
|
193 |
+
);
|
194 |
+
}
|
195 |
+
|
196 |
+
echo '</div></td></tr>';
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Updates information on the "View version x.x details" page with custom data.
|
203 |
+
*
|
204 |
+
* @uses get_transient()
|
205 |
+
* @uses api_request()
|
206 |
+
*
|
207 |
+
* @param mixed $_data
|
208 |
+
* @param string $_action
|
209 |
+
* @param object $_args
|
210 |
+
* @return object $_data
|
211 |
+
*/
|
212 |
+
|
213 |
+
function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
214 |
+
|
215 |
+
|
216 |
+
if ( $_action != 'plugin_information' ) {
|
217 |
+
|
218 |
+
return $_data;
|
219 |
+
|
220 |
+
}
|
221 |
+
|
222 |
+
if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
|
223 |
+
|
224 |
+
return $_data;
|
225 |
+
|
226 |
+
}
|
227 |
+
|
228 |
+
$to_send = array(
|
229 |
+
'slug' => $this->slug,
|
230 |
+
'is_ssl' => is_ssl(),
|
231 |
+
'fields' => array(
|
232 |
+
'banners' => false, // These will be supported soon hopefully
|
233 |
+
'reviews' => false
|
234 |
+
)
|
235 |
+
);
|
236 |
+
// rhe get plugin information from transient storage cache
|
237 |
+
$api_response = $this->get_plugin_transient($this->slug);
|
238 |
+
if (empty($api_response)){
|
239 |
+
$api_response = $this->api_request( 'plugin_information', $to_send );
|
240 |
+
}
|
241 |
+
|
242 |
+
|
243 |
+
if ( false !== $api_response ) {
|
244 |
+
$_data = $api_response;
|
245 |
+
}
|
246 |
+
|
247 |
+
return $_data;
|
248 |
+
}
|
249 |
+
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Disable SSL verification in order to prevent download update failures
|
253 |
+
*
|
254 |
+
* @param array $args
|
255 |
+
* @param string $url
|
256 |
+
* @return object $array
|
257 |
+
*/
|
258 |
+
function http_request_args( $args, $url ) {
|
259 |
+
// If it is an https request and we are performing a package download, disable ssl verification
|
260 |
+
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
|
261 |
+
$args['sslverify'] = false;
|
262 |
+
}
|
263 |
+
return $args;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
268 |
+
*
|
269 |
+
*
|
270 |
+
* @uses get_bloginfo()
|
271 |
+
* @uses wp_remote_post()
|
272 |
+
* @uses is_wp_error()
|
273 |
+
*
|
274 |
+
* @param string $_action The requested action.
|
275 |
+
* @param array $_data Parameters for the API action.
|
276 |
+
* @return false|object
|
277 |
+
*/
|
278 |
+
private function api_request( $_action, $_data ) {
|
279 |
+
|
280 |
+
global $wp_version;
|
281 |
+
|
282 |
+
$data = array_merge( $this->api_data, $_data );
|
283 |
+
|
284 |
+
if ( $data['slug'] != $this->slug )
|
285 |
+
return;
|
286 |
+
|
287 |
+
|
288 |
+
//if ( empty( $data['license'] ) )
|
289 |
+
//return;
|
290 |
+
|
291 |
+
//if ( empty( $data['[item_name]'] ) )
|
292 |
+
//return; //rhe
|
293 |
+
|
294 |
+
if( $this->api_url == home_url() ) {
|
295 |
+
return false; // Don't allow a plugin to ping itself
|
296 |
+
}
|
297 |
+
|
298 |
+
$api_params = array(
|
299 |
+
'edd_action' => 'get_version',
|
300 |
+
'license' => $data['license'],
|
301 |
+
'item_name' => $this->item_name, //rhe
|
302 |
+
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
|
303 |
+
'slug' => $data['slug'],
|
304 |
+
'author' => $data['author'],
|
305 |
+
'url' => home_url()
|
306 |
+
);
|
307 |
+
/*echo "<pre>api_requests() line 277 WPSTG_SL_Plugin_Updater. api params";
|
308 |
+
echo " item name: " . $this->name;
|
309 |
+
var_dump($api_params);
|
310 |
+
exit;*/
|
311 |
+
|
312 |
+
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
|
313 |
+
/*echo "<pre>api_requests() line 277 WPSTG_SL_Plugin_Updater requests:";
|
314 |
+
var_dump(wp_remote_retrieve_body($request));
|
315 |
+
exit;*/
|
316 |
+
|
317 |
+
if ( ! is_wp_error( $request ) ) {
|
318 |
+
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
319 |
+
}
|
320 |
+
|
321 |
+
if ( $request && isset( $request->sections ) ) {
|
322 |
+
$request->sections = maybe_unserialize( $request->sections );
|
323 |
+
} else {
|
324 |
+
$request = false;
|
325 |
+
}
|
326 |
+
|
327 |
+
return $request;
|
328 |
+
}
|
329 |
+
|
330 |
+
public function show_changelog() {
|
331 |
+
|
332 |
+
|
333 |
+
if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
|
334 |
+
return;
|
335 |
+
}
|
336 |
+
|
337 |
+
if( empty( $_REQUEST['plugin'] ) ) {
|
338 |
+
return;
|
339 |
+
}
|
340 |
+
|
341 |
+
if( empty( $_REQUEST['slug'] ) ) {
|
342 |
+
return;
|
343 |
+
}
|
344 |
+
|
345 |
+
if( ! current_user_can( 'update_plugins' ) ) {
|
346 |
+
wp_die( __( 'You do not have permission to install plugin updates', 'wpstg' ), __( 'Error', 'wpstg' ), array( 'response' => 403 ) );
|
347 |
+
}
|
348 |
+
|
349 |
+
$response = $this->api_request( 'plugin_latest_version', array( 'slug' => $_REQUEST['slug'] ) );
|
350 |
+
|
351 |
+
if( $response && isset( $response->sections['changelog'] ) ) {
|
352 |
+
echo '<div style="background:#fff;padding:10px;">' . $response->sections['changelog'] . '</div>';
|
353 |
+
}
|
354 |
+
|
355 |
+
|
356 |
+
exit;
|
357 |
+
}
|
358 |
+
|
359 |
+
/* Get result of transient by slug
|
360 |
+
*
|
361 |
+
*
|
362 |
+
* @author René Hermenau
|
363 |
+
* @scince x.x.x
|
364 |
+
* @param $response string
|
365 |
+
*/
|
366 |
+
|
367 |
+
public function get_plugin_transient($slug) {
|
368 |
+
$result = get_transient($slug . '_update_info');
|
369 |
+
$result = json_decode($result);
|
370 |
+
|
371 |
+
if ($result && isset($result->sections)) {
|
372 |
+
$result->sections = maybe_unserialize($result->sections);
|
373 |
+
}
|
374 |
+
return $result;
|
375 |
+
}
|
376 |
+
|
377 |
+
}
|
includes/admin/add-ons.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Add-ons
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Add-ons
|
7 |
+
* @copyright Copyright (c) 2014, Rene Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.1.8
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Add-ons
|
17 |
+
*
|
18 |
+
* Renders the add-ons content.
|
19 |
+
*
|
20 |
+
* @since 1.1.8
|
21 |
+
* @return void
|
22 |
+
*/
|
23 |
+
function wpstg_add_ons_page() {
|
24 |
+
ob_start(); ?>
|
25 |
+
<div class="wrap" id="wpstg-add-ons">
|
26 |
+
<h2>
|
27 |
+
<?php _e( 'Add Ons for WP-Staging', 'wpstg' ); ?>
|
28 |
+
— <a href="https://www.wp-staging.com" class="button-primary" title="<?php _e( 'Visit Website', 'wpstg' ); ?>" target="_blank"><?php _e( 'See Details', 'wpstg' ); ?></a>
|
29 |
+
</h2>
|
30 |
+
<p><?php _e( 'These add-ons extend the functionality of WP-Staging.', 'wpstg' ); ?></p>
|
31 |
+
<?php echo wpstg_add_ons_get_feed(); ?>
|
32 |
+
</div>
|
33 |
+
<?php
|
34 |
+
echo ob_get_clean();
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Add-ons Get Feed
|
39 |
+
*
|
40 |
+
* Gets the add-ons page feed.
|
41 |
+
*
|
42 |
+
* @since 1.1.8
|
43 |
+
* @return void
|
44 |
+
*/
|
45 |
+
function wpstg_add_ons_get_feed() {
|
46 |
+
if ( false === ( $cache = get_transient( 'wp-staging_add_ons_feed' ) ) ) {
|
47 |
+
$feed = wp_remote_get( 'https://www.wp-staging.net/?feed=addons', array( 'sslverify' => false ) );
|
48 |
+
if ( ! is_wp_error( $feed ) ) {
|
49 |
+
if ( isset( $feed['body'] ) && strlen( $feed['body'] ) > 0 ) {
|
50 |
+
$cache = wp_remote_retrieve_body( $feed );
|
51 |
+
set_transient( 'wp-staging_add_ons_feed', $cache, 3600 );
|
52 |
+
}
|
53 |
+
} else {
|
54 |
+
$cache = '<div class="error"><p>' . __( 'There was an error retrieving the WP-Staging addon list from the server. Please try again later.', 'wpstg' ) . '
|
55 |
+
<br>Visit instead the WP-Staging Addon Website <a href="https://www.wp-staging.net" class="button-primary" title="WP-Staging Add ons" target="_blank"> Get Add-Ons </a></div>';
|
56 |
+
}
|
57 |
+
}
|
58 |
+
return $cache;
|
59 |
+
}
|
includes/admin/admin-actions.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Actions
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Actions
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Processes all WPSTG actions sent via POST and GET by looking for the 'wpstg-action'
|
17 |
+
* request and running do_action() to call the function
|
18 |
+
*
|
19 |
+
* @since 1.0
|
20 |
+
* @return void
|
21 |
+
*/
|
22 |
+
function wpstg_process_actions() {
|
23 |
+
if ( isset( $_POST['wpstg-action'] ) ) {
|
24 |
+
do_action( 'wpstg_' . $_POST['wpstg-action'], $_POST );
|
25 |
+
}
|
26 |
+
|
27 |
+
if ( isset( $_GET['wpstg-action'] ) ) {
|
28 |
+
do_action( 'wpstg_' . $_GET['wpstg-action'], $_GET );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
add_action( 'admin_init', 'wpstg_process_actions' );
|
includes/admin/admin-footer.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Footer
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Footer
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Add rating links to the admin dashboard
|
17 |
+
*
|
18 |
+
* @since 0.9.0
|
19 |
+
* @global string $typenow
|
20 |
+
* @param string $footer_text The existing footer text
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
function wpstg_admin_rate_us( $footer_text ) {
|
24 |
+
global $typenow;
|
25 |
+
|
26 |
+
if ( wpstg_is_admin_page() ) {
|
27 |
+
|
28 |
+
/*$rate_text = sprintf( __( 'Thank you for using <a href="%1$s" target="_blank">WP Staging</a>! Please <a href="%2$s" target="_blank">rate WP Staging</a> on <a href="%2$s" target="_blank">WordPress.org</a> and help to support this project.<br>Something not working as expected with WP Staging? Read the <a href="https://www.wp-staging.net/faq/" target="blank">FAQ</a> and visit the WP-Staging <a href="https://wp-staging.net/support" target="blank">Support Forum</a>', 'wpstg' ),
|
29 |
+
'https://www.wp-staging.net',
|
30 |
+
'http://wordpress.org/support/view/plugin-reviews/wp-staging?filter=5#postform'
|
31 |
+
);*/
|
32 |
+
$rate_text = sprintf( __( 'Please <a href="%1$s" target="_blank">rate WP Staging</a> and help to support this project.<br>Something not working as expected? Visit the WP Staging <a href="https://wordpress.org/support/plugin/wp-staging" target="blank">Support Forum</a>', 'wpstg' ),
|
33 |
+
'http://wordpress.org/support/view/plugin-reviews/wp-staging?filter=5#postform'
|
34 |
+
);
|
35 |
+
|
36 |
+
return str_replace( '</span>', '', '' ) . $rate_text . '</span>';
|
37 |
+
} else {
|
38 |
+
return $footer_text;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
add_filter( 'admin_footer_text', 'wpstg_admin_rate_us' );
|
includes/admin/admin-notices.php
ADDED
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Notices
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Notices
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Admin Messages
|
17 |
+
*
|
18 |
+
* @since 0.9.0
|
19 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
20 |
+
* @return void
|
21 |
+
*/
|
22 |
+
function wpstg_admin_messages() {
|
23 |
+
global $wpstg_options;
|
24 |
+
|
25 |
+
if ( wpstg_is_admin_page() && !wp_is_writable( wpstg_get_upload_dir() ) ){
|
26 |
+
echo '<div class="error">';
|
27 |
+
echo '<p><strong>WP Staging File Permission error: </strong>' . wpstg_get_upload_dir() . ' is not write and/or readable. <br> Check if the folder '.wpstg_get_upload_dir().' exists! File permissions should be chmod 755 or 777.</p>';
|
28 |
+
echo '</div>';
|
29 |
+
}
|
30 |
+
if ( wpstg_is_admin_page() && !wp_is_writable( WPSTG_PLUGIN_DIR . 'logs' ) ){
|
31 |
+
echo '<div class="error">';
|
32 |
+
echo '<p><strong>WP Staging File Permission error: </strong>' . WPSTG_PLUGIN_DIR . 'logs' . ' is not write and/or readable. <br> Check if the folder '.WPSTG_PLUGIN_DIR . 'logs'.' exists! File permissions should be chmod 755 or 777.</p>';
|
33 |
+
echo '</div>';
|
34 |
+
}
|
35 |
+
$path = wpstg_get_upload_dir() . '/clone_details.json';
|
36 |
+
if ( wpstg_is_admin_page() && !wpstg_clonedetailsjson_exists() || !is_readable( $path ) ){
|
37 |
+
echo '<div class="error">';
|
38 |
+
echo '<p><strong>WP Staging File Permission error: </strong>' . $path . ' is not write and/or readable. <br> Check if the file '.$path.' exists! File permissions should be chmod 644 or 777.</p>';
|
39 |
+
echo '</div>';
|
40 |
+
}
|
41 |
+
$path = wpstg_get_upload_dir() . '/remaining_files.json';
|
42 |
+
if ( wpstg_is_admin_page() && !wpstg_remainingjson_exists() || !is_readable( $path ) ){
|
43 |
+
echo '<div class="error">';
|
44 |
+
echo '<p><strong>WP Staging File Permission error: </strong>' . $path . ' is not write and/or readable . <br> Check if the file '.$path.' exists! File permissions should be chmod 644 or 777.</p>';
|
45 |
+
echo '</div>';
|
46 |
+
}
|
47 |
+
if ( wpstg_is_admin_page() && version_compare( WPSTG_WP_COMPATIBLE, get_bloginfo('version'), '<' )){
|
48 |
+
echo '<div class="error"><p>';
|
49 |
+
echo sprintf( __('You are using a version of WP Staging which has not been tested with your WordPress version %2$s.<br>
|
50 |
+
As WP Staging is using crucial db and file functions it\'s important that you are using a WP Staging version<br>
|
51 |
+
which has been verified to be working with your WordPress version. You risk unexpected results up to data lose if you do not so.
|
52 |
+
<p>Please look at <a href="%1$s" target="_blank">%s</a> for the latest WP Staging version.', 'wpstg') ,
|
53 |
+
'https://wordpress.org/plugins/wp-staging/',
|
54 |
+
get_bloginfo('version')
|
55 |
+
);
|
56 |
+
echo '</p></div>';
|
57 |
+
}
|
58 |
+
|
59 |
+
echo wpstg_show_beta_message();
|
60 |
+
|
61 |
+
$install_date = get_option('wpstg_installDate');
|
62 |
+
$display_date = date('Y-m-d h:i:s');
|
63 |
+
$datetime1 = new DateTime($install_date);
|
64 |
+
$datetime2 = new DateTime($display_date);
|
65 |
+
$diff_intrval = round(($datetime2->format('U') - $datetime1->format('U')) / (60*60*24));
|
66 |
+
|
67 |
+
if($diff_intrval >= 7 && get_option('wpstg_RatingDiv')=="no")
|
68 |
+
{
|
69 |
+
echo '<div class="wpstg_fivestar updated" style="box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);">
|
70 |
+
<p>Awesome, you\'ve been using <strong>WP Staging </strong> for more than 1 week. May we ask you to give it a <strong>5-star</strong> rating on Wordpress?
|
71 |
+
<p><strong>Regards,<br>René Hermenau</strong>
|
72 |
+
<ul>
|
73 |
+
<li><a href="https://wordpress.org/support/view/plugin-reviews/wp-staging" class="thankyou" target="_new" title="Ok, you deserved it" style="font-weight:bold;">Ok, you deserved it</a></li>
|
74 |
+
<li><a href="javascript:void(0);" class="wpstg_hide_rating" title="I already did" style="font-weight:bold;">I already did</a></li>
|
75 |
+
<li><a href="javascript:void(0);" class="wpstg_hide_rating" title="No, not good enough" style="font-weight:bold;">No, not good enough</a></li>
|
76 |
+
</ul>
|
77 |
+
</div>
|
78 |
+
<script>
|
79 |
+
jQuery( document ).ready(function( $ ) {
|
80 |
+
jQuery(\'.wpstg_hide_rating\').click(function(){
|
81 |
+
var data={\'action\':\'wpstg_hide_rating\'}
|
82 |
+
jQuery.ajax({
|
83 |
+
url: "'.admin_url( 'admin-ajax.php' ).'",
|
84 |
+
type: "post",
|
85 |
+
data: data,
|
86 |
+
dataType: "json",
|
87 |
+
async: !0,
|
88 |
+
success: function(e) {
|
89 |
+
if (e=="success") {
|
90 |
+
jQuery(\'.wpstg_fivestar\').slideUp(\'slow\');
|
91 |
+
}
|
92 |
+
}
|
93 |
+
});
|
94 |
+
})
|
95 |
+
jQuery(\'.wpstg_hide_beta\').click(function(){
|
96 |
+
var data={\'action\':\'wpstg_hide_beta\'}
|
97 |
+
jQuery.ajax({
|
98 |
+
url: "'.admin_url( 'admin-ajax.php' ).'",
|
99 |
+
type: "post",
|
100 |
+
data: data,
|
101 |
+
dataType: "json",
|
102 |
+
async: !0,
|
103 |
+
success: function(e) {
|
104 |
+
if (e=="success") {
|
105 |
+
jQuery(\'.wpstg_beta_notice\').slideUp(\'slow\');
|
106 |
+
}
|
107 |
+
}
|
108 |
+
});
|
109 |
+
})
|
110 |
+
});
|
111 |
+
</script>
|
112 |
+
';
|
113 |
+
}
|
114 |
+
}
|
115 |
+
add_action( 'admin_notices', 'wpstg_admin_messages' );
|
116 |
+
|
117 |
+
/* Hide the rating div
|
118 |
+
*
|
119 |
+
* @subpackage Admin/Notices
|
120 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
121 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
122 |
+
* @since 0.9.0
|
123 |
+
*
|
124 |
+
* @return json string
|
125 |
+
*
|
126 |
+
*/
|
127 |
+
|
128 |
+
function wpstg_hide_rating_div(){
|
129 |
+
update_option('wpstg_RatingDiv','yes');
|
130 |
+
echo json_encode(array("success")); exit;
|
131 |
+
}
|
132 |
+
add_action('wp_ajax_wpstg_hide_rating','wpstg_hide_rating_div');
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Admin Add-ons Notices
|
136 |
+
*
|
137 |
+
* @since 0.9.0
|
138 |
+
* @return void
|
139 |
+
*/
|
140 |
+
function wpstg_admin_addons_notices() {
|
141 |
+
add_settings_error( 'wpstg-notices', 'wpstg-addons-feed-error', __( 'There seems to be an issue with the server. Please try again in a few minutes.', 'wpstg' ), 'error' );
|
142 |
+
settings_errors( 'wpstg-notices' );
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Dismisses admin notices when Dismiss links are clicked
|
147 |
+
*
|
148 |
+
* @since 0.9.0
|
149 |
+
* @return void
|
150 |
+
*/
|
151 |
+
function wpstg_dismiss_notices() {
|
152 |
+
|
153 |
+
if( ! is_user_logged_in() ) {
|
154 |
+
return;
|
155 |
+
}
|
156 |
+
|
157 |
+
$notice = isset( $_GET['wpstg_notice'] ) ? $_GET['wpstg_notice'] : false;
|
158 |
+
|
159 |
+
if( ! $notice )
|
160 |
+
return; // No notice, so get out of here
|
161 |
+
|
162 |
+
update_user_meta( get_current_user_id(), '_wpstg_' . $notice . '_dismissed', 1 );
|
163 |
+
wp_redirect( remove_query_arg( array( 'wpstg_action', 'wpstg_notice' ) ) ); exit;
|
164 |
+
|
165 |
+
}
|
166 |
+
add_action( 'wpstg_dismiss_notices', 'wpstg_dismiss_notices' );
|
167 |
+
|
168 |
+
|
169 |
+
/*
|
170 |
+
* Show big colored update information below the official update notification in /wp-admin/plugins
|
171 |
+
* @since 0.9.0
|
172 |
+
* @return void
|
173 |
+
*
|
174 |
+
*/
|
175 |
+
|
176 |
+
function wpstg_plugin_update_message( $args ) {
|
177 |
+
$transient_name = 'wpstg_upgrade_notice_' . $args['Version'];
|
178 |
+
|
179 |
+
if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
|
180 |
+
|
181 |
+
$response = wp_remote_get( 'https://plugins.svn.wordpress.org/wp-staging/trunk/readme.txt' );
|
182 |
+
|
183 |
+
if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
|
184 |
+
|
185 |
+
// Output Upgrade Notice
|
186 |
+
$matches = null;
|
187 |
+
$regexp = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( WPSTG_VERSION ) . '\s*=|$)~Uis';
|
188 |
+
$upgrade_notice = '';
|
189 |
+
|
190 |
+
if ( preg_match( $regexp, $response['body'], $matches ) ) {
|
191 |
+
$version = trim( $matches[1] );
|
192 |
+
$notices = (array) preg_split('~[\r\n]+~', trim( $matches[2] ) );
|
193 |
+
|
194 |
+
if ( version_compare( WPSTG_VERSION, $version, '<' ) ) {
|
195 |
+
|
196 |
+
$upgrade_notice .= '<div class="wpstg_plugin_upgrade_notice" style="padding:10px;background-color: #479CCF;color: #FFF;">';
|
197 |
+
|
198 |
+
foreach ( $notices as $index => $line ) {
|
199 |
+
$upgrade_notice .= wp_kses_post( preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}" style="text-decoration:underline;color:#ffffff;">${1}</a>', $line ) );
|
200 |
+
}
|
201 |
+
|
202 |
+
$upgrade_notice .= '</div> ';
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
echo wp_kses_post( $upgrade_notice );
|
211 |
+
}
|
212 |
+
add_action ( "in_plugin_update_message-wp-staging/wp-staging.php", 'wpstg_plugin_update_message' );
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Show a admin notice that this software is beta
|
216 |
+
*/
|
217 |
+
function wpstg_show_beta_message(){
|
218 |
+
$notice = '<div class="wpstg_beta_notice error" style="box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);">
|
219 |
+
<p>This software is beta and work in progress! <br>WP Staging is well tested and we did our best to catch every possible error we can forecast but we can not handle all possible combinations of different server, plugins and themes. <br><strong>BEFORE</strong> you create your first staging site it´s highly recommended <strong>to make a full backup of your website</strong> first!
|
220 |
+
<p><strong>This is no joke! </strong>WP Staging is using crucial database and system close functions which have the power to break your website or even to delete your entire database! WP-Staging has neever caused any errors like data loose on any of the sites we are using for testing, so in most cases everything will be running fine, but we have
|
221 |
+
to give out this warning until WP Staging is not in beta status any longer.
|
222 |
+
<p>
|
223 |
+
One of the best free plugins for an entire wordpress backup is the free one <a href="https://wordpress.org/plugins/backwpup/" target="_blank">BackWPup</a>
|
224 |
+
<p>To be more clear: <p>We are not responsible for any damages this plugin will cause to your site. <br>Do a full backup first!</p>
|
225 |
+
<ul>
|
226 |
+
<li><a href="javascript:void(0);" class="wpstg_hide_beta" title="I understand" style="font-weight:bold;color:#00a0d2;">I understand! (Do not show this again)</a></li>
|
227 |
+
</ul>
|
228 |
+
</div>
|
229 |
+
<script>
|
230 |
+
jQuery( document ).ready(function( $ ) {
|
231 |
+
jQuery(\'.wpstg_hide_beta\').click(function(){
|
232 |
+
var data={\'action\':\'wpstg_hide_beta\'}
|
233 |
+
jQuery.ajax({
|
234 |
+
url: "'.admin_url( 'admin-ajax.php' ).'",
|
235 |
+
type: "post",
|
236 |
+
data: data,
|
237 |
+
dataType: "json",
|
238 |
+
async: !0,
|
239 |
+
success: function(e) {
|
240 |
+
if (e=="success") {
|
241 |
+
jQuery(\'.wpstg_beta_notice\').slideUp(\'slow\');
|
242 |
+
}
|
243 |
+
}
|
244 |
+
});
|
245 |
+
})
|
246 |
+
});
|
247 |
+
</script>
|
248 |
+
';
|
249 |
+
|
250 |
+
if( get_option('wpstg_hide_beta') === "no" && wpstg_is_admin_page() )
|
251 |
+
return $notice;
|
252 |
+
}
|
253 |
+
|
254 |
+
function wpstg_hide_beta_div(){
|
255 |
+
update_option('wpstg_hide_beta','yes');
|
256 |
+
echo json_encode(array("success")); exit;
|
257 |
+
}
|
258 |
+
add_action('wp_ajax_wpstg_hide_beta','wpstg_hide_beta_div');
|
includes/admin/admin-pages.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Pages
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Pages
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 0.9.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Creates the admin submenu pages under the WP-Staging menu and assigns their
|
17 |
+
* links to global variables
|
18 |
+
*
|
19 |
+
* @since 1.0
|
20 |
+
* @global $wpstg_settings_page
|
21 |
+
* @global $wpstg_add_ons_page
|
22 |
+
* @global $wpstg_tools_page
|
23 |
+
* @return void
|
24 |
+
*/
|
25 |
+
function wpstg_add_options_link() {
|
26 |
+
global $wpstg_parent_page, $wpstg_add_ons_page, $wpstg_add_ons_page2, $wpstg_settings_page, $wpstg_tools_page, $wpstg_clone_page;
|
27 |
+
$wpstg_parent_page = add_menu_page( 'WP-Staging', __( 'WP Staging', 'wpstg' ), 'manage_options', 'wpstg_clone', 'wpstg_clone_page', 'dashicons-hammer' );
|
28 |
+
$wpstg_clone_page = add_submenu_page('wpstg_clone', __('WP Staging Jobs', 'wpstg'), __('Start', 'wpstg'), 'manage_options', 'wpstg_clone', 'wpstg_clone_page');
|
29 |
+
$wpstg_settings_page = add_submenu_page( 'wpstg_clone', __( 'WP Staging Settings', 'wpstg' ), __( 'Settings', 'wpstg' ), 'manage_options', 'wpstg-settings', 'wpstg_options_page' );
|
30 |
+
$wpstg_tools_page = add_submenu_page( 'wpstg_clone', __( 'WP Staging Tools', 'wpstg' ), __( 'Tools', 'wpstg' ), 'manage_options', 'wpstg-tools', 'wpstg_tools_page' );
|
31 |
+
|
32 |
+
}
|
33 |
+
add_action( 'admin_menu', 'wpstg_add_options_link', 10 );
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Determines whether the current admin page is an WPSTG admin page.
|
37 |
+
*
|
38 |
+
* Only works after the `wp_loaded` hook, & most effective
|
39 |
+
* starting on `admin_menu` hook.
|
40 |
+
*
|
41 |
+
* @since 0.9.0
|
42 |
+
* @return bool True if WPSTG admin page.
|
43 |
+
*/
|
44 |
+
function wpstg_is_admin_page() {
|
45 |
+
$currentpage = isset($_GET['page']) ? $_GET['page'] : '';
|
46 |
+
if ( ! is_admin() || ! did_action( 'wp_loaded' ) ) {
|
47 |
+
return false;
|
48 |
+
}
|
49 |
+
|
50 |
+
global $wpstg_parent_page, $pagenow, $typenow, $wpstg_settings_page, $wpstg_add_ons_page, $wpstg_tools_page, $wpstg_clone_page;
|
51 |
+
|
52 |
+
if ( 'wpstg-settings' == $currentpage || 'wpstg-addons' == $currentpage || 'wpstg-tools' == $currentpage || 'wpstg-clone' == $currentpage || 'wpstg_clone' == $currentpage) {
|
53 |
+
//mashdebug()->info("wpstg_is_admin_page() = true");
|
54 |
+
return true;
|
55 |
+
}
|
56 |
+
}
|
includes/admin/plugins.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Plugins
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Plugins
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Plugins row action links
|
19 |
+
*
|
20 |
+
* @author Michael Cannon <mc@aihr.us>
|
21 |
+
* @since 0.9.0
|
22 |
+
* @param array $links already defined action links
|
23 |
+
* @param string $file plugin file path and name being processed
|
24 |
+
* @return array $links
|
25 |
+
*/
|
26 |
+
function wpstg_plugin_action_links( $links, $file ) {
|
27 |
+
$settings_link = '<a href="' . admin_url( 'admin.php?page=wpstg-settings' ) . '">' . esc_html__( 'General Settings', 'wpstg' ) . '</a>';
|
28 |
+
if ( $file == 'wp-staging/wp-staging.php' )
|
29 |
+
array_unshift( $links, $settings_link );
|
30 |
+
|
31 |
+
return $links;
|
32 |
+
}
|
33 |
+
add_filter( 'plugin_action_links', 'wpstg_plugin_action_links', 10, 2 );
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Plugin row meta links
|
38 |
+
*
|
39 |
+
* @author Michael Cannon <mc@aihr.us>
|
40 |
+
* @since 2.0
|
41 |
+
* @param array $input already defined meta links
|
42 |
+
* @param string $file plugin file path and name being processed
|
43 |
+
* @return array $input
|
44 |
+
*/
|
45 |
+
function wpstg_plugin_row_meta( $input, $file ) {
|
46 |
+
if ( $file != 'wp-staging/wp-staging.php' )
|
47 |
+
return $input;
|
48 |
+
|
49 |
+
/*$links = array(
|
50 |
+
'<a href="' . admin_url( 'options-general.php?page=wpstg-settings' ) . '">' . esc_html__( 'Getting Started', 'wpstg' ) . '</a>',
|
51 |
+
'<a href="https://www.wp-staging.net/downloads/">' . esc_html__( 'Add Ons', 'wpstg' ) . '</a>',
|
52 |
+
);*/
|
53 |
+
|
54 |
+
$links = array(
|
55 |
+
'<a href="' . admin_url( 'admin.php?page=wpstg-settings' ) . '">' . esc_html__( 'Getting Started', 'wpstg' ) . '</a>',
|
56 |
+
);
|
57 |
+
|
58 |
+
$input = array_merge( $input, $links );
|
59 |
+
|
60 |
+
return $input;
|
61 |
+
}
|
62 |
+
add_filter( 'plugin_row_meta', 'wpstg_plugin_row_meta', 10, 2 );
|
includes/admin/settings/contextual-help.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Contextual Help
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Settings
|
7 |
+
* @copyright Copyright (c) 2014, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Settings contextual help.
|
17 |
+
*
|
18 |
+
* @access private
|
19 |
+
* @since 1.0
|
20 |
+
* @return void
|
21 |
+
*/
|
22 |
+
function wpstg_settings_contextual_help() {
|
23 |
+
$screen = get_current_screen();
|
24 |
+
|
25 |
+
/*if ( $screen->id != 'wpstg-settings' )
|
26 |
+
return;
|
27 |
+
*/
|
28 |
+
$screen->set_help_sidebar(
|
29 |
+
'<p><strong>' . $screen->id . sprintf( __( 'For more information:', 'wpstg' ) . '</strong></p>' .
|
30 |
+
'<p>' . sprintf( __( 'Visit the <a href="%s">documentation</a> on the WP-Staging website.', 'wpstg' ), esc_url( 'https://www.wp-staging.net/' ) ) ) . '</p>' .
|
31 |
+
'<p>' . sprintf(
|
32 |
+
__( '<a href="%s">Post an issue</a> on <a href="%s">WP-Staging</a>. View <a href="%s">extensions</a>.', 'wpstg' ),
|
33 |
+
esc_url( 'https://www.wp-staging.net/contact-support/' ),
|
34 |
+
esc_url( 'https://www.wp-staging.net' ),
|
35 |
+
esc_url( 'https://www.wp-staging.net/downloads' )
|
36 |
+
) . '</p>'
|
37 |
+
);
|
38 |
+
|
39 |
+
$screen->add_help_tab( array(
|
40 |
+
'id' => 'wpstg-settings-general',
|
41 |
+
'title' => __( 'General', 'wpstg' ),
|
42 |
+
'content' => '<p>' . __( 'This screen provides the most basic settings for configuring WP-Staging.', 'wpstg' ) . '</p>'
|
43 |
+
) );
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
|
48 |
+
do_action( 'wpstg_settings_contextual_help', $screen );
|
49 |
+
}
|
50 |
+
add_action( 'load-wpstg-settings', 'wpstg_settings_contextual_help' );
|
includes/admin/settings/display-settings.php
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Options Page
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Settings
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/* Returns list elements for jQuery tab navigation
|
16 |
+
* based on header callback
|
17 |
+
*
|
18 |
+
* @since 0.9.0
|
19 |
+
* @todo Use sprintf to sanitize $field['id'] instead using str_replace() Should be faster?
|
20 |
+
* @return string
|
21 |
+
*/
|
22 |
+
|
23 |
+
function wpstg_getTabHeader($page, $section){
|
24 |
+
global $wpstg_options;
|
25 |
+
global $wp_settings_fields;
|
26 |
+
|
27 |
+
if (!isset($wp_settings_fields[$page][$section]))
|
28 |
+
return;
|
29 |
+
|
30 |
+
echo '<ul>';
|
31 |
+
foreach ((array) $wp_settings_fields[$page][$section] as $field) {
|
32 |
+
$sanitizedID = str_replace('[', '', $field['id'] );
|
33 |
+
$sanitizedID = str_replace(']', '', $sanitizedID );
|
34 |
+
if (strpos($field['callback'],'header') !== false) {
|
35 |
+
echo '<li class="wpstg-tabs"><a href="#' . $sanitizedID . '">' . $field['title'] .'</a></li>';
|
36 |
+
}
|
37 |
+
}
|
38 |
+
echo '</ul>';
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Print out the settings fields for a particular settings section
|
44 |
+
*
|
45 |
+
* Part of the Settings API. Use this in a settings page to output
|
46 |
+
* a specific section. Should normally be called by do_settings_sections()
|
47 |
+
* rather than directly.
|
48 |
+
*
|
49 |
+
* @global $wp_settings_fields Storage array of settings fields and their pages/sections
|
50 |
+
* @return string
|
51 |
+
*
|
52 |
+
* @since 2.1.2
|
53 |
+
*
|
54 |
+
* @param string $page Slug title of the admin page who's settings fields you want to show.
|
55 |
+
* @param section $section Slug title of the settings section who's fields you want to show.
|
56 |
+
*
|
57 |
+
* Copied from WP Core 4.0 /wp-admin/includes/template.php do_settings_fields()
|
58 |
+
* We use our own function to be able to create jQuery tabs with easytabs()
|
59 |
+
*
|
60 |
+
* We dont use tables here any longer. Are we stuck in the nineties?
|
61 |
+
* @todo Use sprintf to sanitize $field['id'] instead using str_replace() Should be faster?
|
62 |
+
* @todo some media queries for better responisbility
|
63 |
+
*/
|
64 |
+
function wpstg_do_settings_fields($page, $section) {
|
65 |
+
global $wp_settings_fields;
|
66 |
+
$header = false;
|
67 |
+
$firstHeader = false;
|
68 |
+
|
69 |
+
if (!isset($wp_settings_fields[$page][$section]))
|
70 |
+
return;
|
71 |
+
|
72 |
+
// Check first if any callback header registered
|
73 |
+
foreach ((array) $wp_settings_fields[$page][$section] as $field) {
|
74 |
+
strpos($field['callback'],'header') !== false ? $header = true : $header = false;
|
75 |
+
|
76 |
+
if ($header === true)
|
77 |
+
break;
|
78 |
+
}
|
79 |
+
|
80 |
+
foreach ((array) $wp_settings_fields[$page][$section] as $field) {
|
81 |
+
|
82 |
+
$sanitizedID = str_replace('[', '', $field['id'] );
|
83 |
+
$sanitizedID = str_replace(']', '', $sanitizedID );
|
84 |
+
|
85 |
+
// Check if header has been created previously
|
86 |
+
if (strpos($field['callback'],'header') !== false && $firstHeader === false) {
|
87 |
+
echo '<div id="' . $sanitizedID . '">';
|
88 |
+
echo '<table class="form-table"><tbody>';
|
89 |
+
$firstHeader = true;
|
90 |
+
} elseif (strpos($field['callback'],'header') !== false && $firstHeader === true) {
|
91 |
+
// Header has been created previously so we have to close the first opened div
|
92 |
+
echo '</table></div><div id="' . $sanitizedID . '">';
|
93 |
+
echo '<table class="form-table"><tbody>';
|
94 |
+
|
95 |
+
}
|
96 |
+
echo '<tr class="row"><th class="row th">';
|
97 |
+
//echo "<pre>";
|
98 |
+
//var_dump($field);
|
99 |
+
if (!empty($field['args']['label_for']))
|
100 |
+
echo '<label for="' . esc_attr($field['args']['label_for']) . '">' . $field['title'] . '</label>';
|
101 |
+
else
|
102 |
+
echo '<div class="col-title">' . $field['title'] . '<span class="description">' . $field['args']['desc'] . '</span></div>';
|
103 |
+
echo '</th>';
|
104 |
+
echo '<td>';
|
105 |
+
call_user_func($field['callback'], $field['args']);
|
106 |
+
echo '</td></tr>';
|
107 |
+
|
108 |
+
|
109 |
+
}
|
110 |
+
echo '</tbody></table>';
|
111 |
+
if ($header === true){
|
112 |
+
echo '</div>';
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Options Page
|
118 |
+
*
|
119 |
+
* Renders the options page contents.
|
120 |
+
*
|
121 |
+
* @since 1.0
|
122 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
123 |
+
* @return void
|
124 |
+
*/
|
125 |
+
function wpstg_options_page() {
|
126 |
+
global $wpstg_options;
|
127 |
+
|
128 |
+
$active_tab = isset( $_GET[ 'tab' ] ) && array_key_exists( $_GET['tab'], wpstg_get_settings_tabs() ) ? $_GET[ 'tab' ] : 'general';
|
129 |
+
|
130 |
+
ob_start();
|
131 |
+
?>
|
132 |
+
<div class="wpstg_admin">
|
133 |
+
<span class="wp-staginglogo"><img src="<?php echo WPSTG_PLUGIN_URL . 'assets/images/logo_clean_small_212_25.png';?>"></span><span class="wpstg-version"><?php echo WPSTG_VERSION . ''; ?></span>
|
134 |
+
<div class="wpstg-header">
|
135 |
+
<?php echo __('Thank you for using WP Staging.', 'wpstg');?>
|
136 |
+
<br>
|
137 |
+
<?php echo __('WP Staging is ready to create a staging site!', 'wpstg'); ?>
|
138 |
+
<br>
|
139 |
+
<iframe src="//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwordpress.org%2Fplugins%2Fwp-staging%2F&width=100&layout=standard&action=like&show_faces=false&share=true&height=35&appId=449277011881884" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:96px; height:20px;" allowTransparency="true"></iframe>
|
140 |
+
<a class="twitter-follow-button" href="https://twitter.com/wp_staging" data-size="small" id="twitter-wjs" style="display: none;">Follow @wp_staging</a>
|
141 |
+
<a class="twitter-share-button" href="https://twitter.com/intent/tweet?text=Check%20this%20WordPress%20Staging%20plugin%20&url=https://wordpress.org/plugins/wp-staging&hashtags=wpstaging&via=wp_staging">Tweet</a>
|
142 |
+
</div>
|
143 |
+
<h2 class="nav-tab-wrapper">
|
144 |
+
<?php
|
145 |
+
foreach( wpstg_get_settings_tabs() as $tab_id => $tab_name ) {
|
146 |
+
|
147 |
+
$tab_url = esc_url(add_query_arg( array(
|
148 |
+
'settings-updated' => false,
|
149 |
+
'tab' => $tab_id
|
150 |
+
) ));
|
151 |
+
|
152 |
+
$active = $active_tab == $tab_id ? ' nav-tab-active' : '';
|
153 |
+
|
154 |
+
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $tab_name ) . '" class="nav-tab' . $active . '">';
|
155 |
+
echo esc_html( $tab_name );
|
156 |
+
echo '</a>';
|
157 |
+
}
|
158 |
+
?>
|
159 |
+
</h2>
|
160 |
+
<div id="tab_container" class="tab_container">
|
161 |
+
<?php //wpstg_getTabHeader( 'wpstg_settings_' . $active_tab, 'wpstg_settings_' . $active_tab ); ?>
|
162 |
+
<div class="panel-container"> <!-- new //-->
|
163 |
+
<form method="post" action="options.php">
|
164 |
+
<?php
|
165 |
+
settings_fields( 'wpstg_settings' );
|
166 |
+
wpstg_do_settings_fields( 'wpstg_settings_' . $active_tab, 'wpstg_settings_' . $active_tab );
|
167 |
+
?>
|
168 |
+
<!--</table>-->
|
169 |
+
|
170 |
+
<?php
|
171 |
+
// do not show save button on add-on page
|
172 |
+
if ($active_tab !== 'addons')
|
173 |
+
submit_button();
|
174 |
+
?>
|
175 |
+
</form>
|
176 |
+
</div> <!-- new //-->
|
177 |
+
</div><!-- #tab_container-->
|
178 |
+
</div><!-- .wrap -->
|
179 |
+
<?php
|
180 |
+
echo ob_get_clean();
|
181 |
+
}
|
includes/admin/settings/register-settings.php
ADDED
@@ -0,0 +1,839 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Register Settings
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Settings
|
7 |
+
* @copyright Copyright (c) 2014, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( !defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Get an option
|
19 |
+
*
|
20 |
+
* Looks to see if the specified setting exists, returns default if not
|
21 |
+
*
|
22 |
+
* @since 0.9.0
|
23 |
+
* @return mixed
|
24 |
+
*/
|
25 |
+
function wpstg_get_option( $key = '', $default = false ) {
|
26 |
+
global $wpstg_options;
|
27 |
+
$value = ! empty( $wpstg_options[ $key ] ) ? $wpstg_options[ $key ] : $default;
|
28 |
+
$value = apply_filters( 'wpstg_get_option', $value, $key, $default );
|
29 |
+
return apply_filters( 'wpstg_get_option_' . $key, $value, $key, $default );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Get Settings
|
34 |
+
*
|
35 |
+
* Retrieves all plugin settings
|
36 |
+
*
|
37 |
+
* @since 1.0
|
38 |
+
* @return array WPSTG settings
|
39 |
+
*/
|
40 |
+
function wpstg_get_settings() {
|
41 |
+
$settings = get_option( 'wpstg_settings' );
|
42 |
+
|
43 |
+
|
44 |
+
if( empty( $settings ) ) {
|
45 |
+
// Update old settings with new single option
|
46 |
+
$general_settings = is_array( get_option( 'wpstg_settings_general' ) ) ? get_option( 'wpstg_settings_general' ) : array();
|
47 |
+
|
48 |
+
//$settings = array_merge( $general_settings, $ext_settings, $license_settings);//, $networks, $ext_settings, $license_settings, $addons_settings);
|
49 |
+
$settings = $general_settings;
|
50 |
+
|
51 |
+
update_option( 'wpstg_settings', $settings);
|
52 |
+
}
|
53 |
+
return apply_filters( 'wpstg_get_settings', $settings );
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Add all settings sections and fields
|
58 |
+
*
|
59 |
+
* @since 1.0
|
60 |
+
* @return void
|
61 |
+
*/
|
62 |
+
function wpstg_register_settings() {
|
63 |
+
|
64 |
+
if ( false == get_option( 'wpstg_settings' ) ) {
|
65 |
+
add_option( 'wpstg_settings' );
|
66 |
+
}
|
67 |
+
|
68 |
+
foreach( wpstg_get_registered_settings() as $tab => $settings ) {
|
69 |
+
|
70 |
+
add_settings_section(
|
71 |
+
'wpstg_settings_' . $tab,
|
72 |
+
__return_null(),
|
73 |
+
'__return_false',
|
74 |
+
'wpstg_settings_' . $tab
|
75 |
+
);
|
76 |
+
|
77 |
+
foreach ( $settings as $option ) {
|
78 |
+
|
79 |
+
$name = isset( $option['name'] ) ? $option['name'] : '';
|
80 |
+
|
81 |
+
add_settings_field(
|
82 |
+
'wpstg_settings[' . $option['id'] . ']',
|
83 |
+
$name,
|
84 |
+
function_exists( 'wpstg_' . $option['type'] . '_callback' ) ? 'wpstg_' . $option['type'] . '_callback' : 'wpstg_missing_callback',
|
85 |
+
'wpstg_settings_' . $tab,
|
86 |
+
'wpstg_settings_' . $tab,
|
87 |
+
array(
|
88 |
+
'id' => isset( $option['id'] ) ? $option['id'] : null,
|
89 |
+
'desc' => ! empty( $option['desc'] ) ? $option['desc'] : '',
|
90 |
+
'name' => isset( $option['name'] ) ? $option['name'] : null,
|
91 |
+
'section' => $tab,
|
92 |
+
'size' => isset( $option['size'] ) ? $option['size'] : null,
|
93 |
+
'options' => isset( $option['options'] ) ? $option['options'] : '',
|
94 |
+
'std' => isset( $option['std'] ) ? $option['std'] : '',
|
95 |
+
'textarea_rows' => isset( $option['textarea_rows']) ? $option['textarea_rows'] : ''
|
96 |
+
)
|
97 |
+
);
|
98 |
+
}
|
99 |
+
|
100 |
+
}
|
101 |
+
|
102 |
+
// Creates our settings in the options table
|
103 |
+
register_setting( 'wpstg_settings', 'wpstg_settings', 'wpstg_settings_sanitize' );
|
104 |
+
|
105 |
+
}
|
106 |
+
add_action('admin_init', 'wpstg_register_settings');
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Retrieve the array of plugin settings
|
110 |
+
*
|
111 |
+
* @since 1.8
|
112 |
+
* @return array
|
113 |
+
*/
|
114 |
+
function wpstg_get_registered_settings() {
|
115 |
+
|
116 |
+
/**
|
117 |
+
* 'Whitelisted' WPSTG settings, filters are provided for each settings
|
118 |
+
* section to allow extensions and other plugins to add their own settings
|
119 |
+
*/
|
120 |
+
$wpstg_settings = array(
|
121 |
+
/** General Settings */
|
122 |
+
'general' => apply_filters( 'wpstg_settings_general',
|
123 |
+
array(
|
124 |
+
array(
|
125 |
+
'id' => 'wpstg_header',
|
126 |
+
'name' => '<strong>' . __( 'General', 'wpstg' ) . '</strong>',
|
127 |
+
'desc' => '',
|
128 |
+
'type' => 'header',
|
129 |
+
'size' => 'regular'
|
130 |
+
),
|
131 |
+
array(
|
132 |
+
'id' => 'wpstg_query_limit',
|
133 |
+
'name' => __('DB Copy Query Limit', 'wpstg'),
|
134 |
+
'desc' => __('Number of DB rows, that will be copied within one ajax request. The higher the value the faster the database copy process. To find out the highest possible values try a high value like 1.000 or more and decrease it until you get no more errors during copy process. <strong> Default: 100 </strong>'),
|
135 |
+
'type' => 'number',
|
136 |
+
'size' => 'medium',
|
137 |
+
'std' => 100,
|
138 |
+
),
|
139 |
+
array(
|
140 |
+
'id' => 'wpstg_batch_size',
|
141 |
+
'name' => __('File Copy Batch Size', 'wpstg'),
|
142 |
+
'desc' => __('Buffer size for the file copy process in megabyte. The higher the value the faster large files will be copied. To find out the highest possible values try a high one and lower it until you get no errors during file copy process. Usually this value correlates directly with the memory consumption of php so make sure that it does not exceed any php.ini max_memory limits. <strong>Default:</strong> 2 ', 'wpstg'),
|
143 |
+
'type' => 'number',
|
144 |
+
'size' => 'medium',
|
145 |
+
'std' => '2',
|
146 |
+
),
|
147 |
+
array(
|
148 |
+
'id' => 'wpstg_cpu_load',
|
149 |
+
'name' => __('CPU load priority', 'wpstg'),
|
150 |
+
'desc' => __('Using high will result in fast as possible processing but the cpu load increases and it\'s also possible that staging process gets interupted because of too many ajax requests (e.g. <strong>authorization error</strong>). Using a lower value results in lower cpu load on your server but also slower staging site creation. <strong>Default: </strong> Medium ', 'wpstg'),
|
151 |
+
'type' => 'select',
|
152 |
+
'size' => 'medium',
|
153 |
+
'options' => array(
|
154 |
+
'default' => 'Default',
|
155 |
+
'high' => 'High (fast)',
|
156 |
+
'medium' => 'Medium (average)',
|
157 |
+
'low' => 'Low (slow)'
|
158 |
+
|
159 |
+
)
|
160 |
+
),
|
161 |
+
array(
|
162 |
+
'id' => 'wpstg_disabled_plugins',
|
163 |
+
'name' => __('Optimizer', 'wpstg'),
|
164 |
+
'desc' => __('Select the plugins that should be disabled during build process of the staging site. Some plugins slow down the copy process and add overhead to each request, requiring extra CPU and memory consumption. Some of them can interfere with cloning process and cause them to fail, so we recommend to disable all plugins that are not directly related to WP Staging.', 'wpstg'),
|
165 |
+
'type' => 'install_muplugin',
|
166 |
+
'size' => 'medium',
|
167 |
+
'std' => '20',
|
168 |
+
),
|
169 |
+
'disable_admin_login' => array(
|
170 |
+
'id' => 'disable_admin_login',
|
171 |
+
'name' => __( 'Disable admin authorization', 'mashsb' ),
|
172 |
+
'desc' => __( 'Use this option only if you are using a custom login page and not the default login.php. If you enable this option you are allowing everyone including searchengines to see your staging site, so you have to create a custom authentication like using .htaccess', 'mashsb' ),
|
173 |
+
'type' => 'checkbox'
|
174 |
+
),
|
175 |
+
'wordpress_subdirectory' => array(
|
176 |
+
'id' => 'wordpress_subdirectory',
|
177 |
+
'name' => __( 'Wordpress in subdirectory', 'mashsb' ),
|
178 |
+
'desc' => __( 'Use this option when you gave wordpress its own subdirectory. if you enable this, WP Staging will reset the index.php of the clone site to the originally one. <br> <a href="https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory" target="_blank">Read more in the WordPress Codex</a>', 'mashsb' ),
|
179 |
+
'type' => 'checkbox'
|
180 |
+
),
|
181 |
+
/*'link_images' => array(
|
182 |
+
'id' => 'link_images',
|
183 |
+
'name' => __( 'Link images. Change upload ', 'mashsb' ),
|
184 |
+
'desc' => __( 'Enable this if you want WP Staging to link images. if you enable this, WP Staging will reset the index.php of the clone site to the originally one. <br> <a href="https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory" target="_blank">Read more in the WordPress Codex</a>', 'mashsb' ),
|
185 |
+
'type' => 'checkbox'
|
186 |
+
),*/
|
187 |
+
/*'admin_login_page' => array(
|
188 |
+
'id' => 'admin_login_page',
|
189 |
+
'name' => __( 'Login page', 'mashsb' ),
|
190 |
+
'desc' => __( ' This is necessary if you are using a custom login page and not the default login.php. Fill in the page id of your custom login page, otherwise you will not be able to login to your staging website.', 'mashsb' ),
|
191 |
+
'type' => 'text',
|
192 |
+
'size' => 'medium'
|
193 |
+
),*/
|
194 |
+
'debug_mode' => array(
|
195 |
+
'id' => 'debug_mode',
|
196 |
+
'name' => __( 'Debug Mode', 'mashsb' ),
|
197 |
+
'desc' => __( 'This will enable an extended debug mode which creates additional entries in <strong>wp-content/wp-staging/logs</strong>. Please enable this when we ask you to do so.', 'mashsb' ),
|
198 |
+
'type' => 'checkbox'
|
199 |
+
),
|
200 |
+
'uninstall_on_delete' => array(
|
201 |
+
'id' => 'uninstall_on_delete',
|
202 |
+
'name' => __( 'Remove Data on Uninstall?', 'mashsb' ),
|
203 |
+
'desc' => __( 'Check this box if you like WP Staging to completely remove all of its data when the plugin is deleted.', 'mashsb' ),
|
204 |
+
'type' => 'checkbox'
|
205 |
+
),
|
206 |
+
|
207 |
+
)
|
208 |
+
),
|
209 |
+
'licenses' => apply_filters('wpstg_settings_licenses',
|
210 |
+
array('licenses_header' => array(
|
211 |
+
'id' => 'licenses_header',
|
212 |
+
'name' => __( 'Activate your Add-Ons', 'wpstg' ),
|
213 |
+
'desc' => '',
|
214 |
+
'type' => 'header'
|
215 |
+
),)
|
216 |
+
),
|
217 |
+
'extensions' => apply_filters('wpstg_settings_extension',
|
218 |
+
array()
|
219 |
+
),
|
220 |
+
'addons' => apply_filters('wpstg_settings_addons',
|
221 |
+
array(
|
222 |
+
'addons' => array(
|
223 |
+
'id' => 'addons',
|
224 |
+
'name' => __( '', 'wpstg' ),
|
225 |
+
'desc' => __( '', 'wpstg' ),
|
226 |
+
'type' => 'addons'
|
227 |
+
)
|
228 |
+
)
|
229 |
+
)
|
230 |
+
);
|
231 |
+
|
232 |
+
return $wpstg_settings;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Settings Sanitization
|
237 |
+
*
|
238 |
+
* Adds a settings error (for the updated message)
|
239 |
+
* At some point this will validate input
|
240 |
+
*
|
241 |
+
* @since 0.9.0
|
242 |
+
*
|
243 |
+
* @param array $input The value input in the field
|
244 |
+
*
|
245 |
+
* @return string $input Sanitized value
|
246 |
+
*/
|
247 |
+
function wpstg_settings_sanitize( $input = array() ) {
|
248 |
+
|
249 |
+
global $wpstg_options;
|
250 |
+
|
251 |
+
if ( empty( $_POST['_wp_http_referer'] ) ) {
|
252 |
+
return $input;
|
253 |
+
}
|
254 |
+
|
255 |
+
parse_str( $_POST['_wp_http_referer'], $referrer );
|
256 |
+
|
257 |
+
$settings = wpstg_get_registered_settings();
|
258 |
+
$tab = isset( $referrer['tab'] ) ? $referrer['tab'] : 'general';
|
259 |
+
|
260 |
+
$input = $input ? $input : array();
|
261 |
+
$input = apply_filters( 'wpstg_settings_' . $tab . '_sanitize', $input );
|
262 |
+
|
263 |
+
// Loop through each setting being saved and pass it through a sanitization filter
|
264 |
+
foreach ( $input as $key => $value ) {
|
265 |
+
|
266 |
+
// Get the setting type (checkbox, select, etc)
|
267 |
+
$type = isset( $settings[$tab][$key]['type'] ) ? $settings[$tab][$key]['type'] : false;
|
268 |
+
|
269 |
+
if ( $type ) {
|
270 |
+
// Field type specific filter
|
271 |
+
$input[$key] = apply_filters( 'wpstg_settings_sanitize_' . $type, $value, $key );
|
272 |
+
}
|
273 |
+
|
274 |
+
// General filter
|
275 |
+
$input[$key] = apply_filters( 'wpstg_settings_sanitize', $value, $key );
|
276 |
+
}
|
277 |
+
|
278 |
+
// Loop through the whitelist and unset any that are empty for the tab being saved
|
279 |
+
if ( ! empty( $settings[$tab] ) ) {
|
280 |
+
foreach ( $settings[$tab] as $key => $value ) {
|
281 |
+
|
282 |
+
// settings used to have numeric keys, now they have keys that match the option ID. This ensures both methods work
|
283 |
+
if ( is_numeric( $key ) ) {
|
284 |
+
$key = $value['id'];
|
285 |
+
}
|
286 |
+
|
287 |
+
if ( empty( $input[$key] ) ) {
|
288 |
+
unset( $wpstg_options[$key] );
|
289 |
+
}
|
290 |
+
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
// Merge our new settings with the existing
|
295 |
+
$output = array_merge( $wpstg_options, $input );
|
296 |
+
|
297 |
+
add_settings_error( 'wpstg-notices', '', __( 'Settings updated.', 'wpstg' ), 'updated' );
|
298 |
+
|
299 |
+
return $output;
|
300 |
+
}
|
301 |
+
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Sanitize text fields
|
305 |
+
*
|
306 |
+
* @since 1.8
|
307 |
+
* @param array $input The field value
|
308 |
+
* @return string $input Sanitizied value
|
309 |
+
*/
|
310 |
+
function wpstg_sanitize_text_field( $input ) {
|
311 |
+
return trim( $input );
|
312 |
+
}
|
313 |
+
add_filter( 'wpstg_settings_sanitize_text', 'wpstg_sanitize_text_field' );
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Retrieve settings tabs
|
317 |
+
*
|
318 |
+
* @since 1.8
|
319 |
+
* @param array $input The field value
|
320 |
+
* @return string $input Sanitizied value
|
321 |
+
*/
|
322 |
+
function wpstg_get_settings_tabs() {
|
323 |
+
|
324 |
+
$settings = wpstg_get_registered_settings();
|
325 |
+
|
326 |
+
$tabs = array();
|
327 |
+
$tabs['general'] = __( 'General', 'wpstg' );
|
328 |
+
|
329 |
+
if( ! empty( $settings['misc'] ) ) {
|
330 |
+
$tabs['misc'] = __( 'Misc', 'wpstg' );
|
331 |
+
}
|
332 |
+
|
333 |
+
if( ! empty( $settings['networks'] ) ) {
|
334 |
+
//$tabs['networks'] = __( 'Social Networks', 'wpstg' );
|
335 |
+
}
|
336 |
+
|
337 |
+
if( ! empty( $settings['extensions'] ) ) {
|
338 |
+
$tabs['extensions'] = __( 'Extensions', 'wpstg' );
|
339 |
+
}
|
340 |
+
|
341 |
+
if( ! empty( $settings['licenses'] ) ) {
|
342 |
+
//$tabs['licenses'] = __( 'Licenses', 'wpstg' );
|
343 |
+
}
|
344 |
+
//$tabs['addons'] = __( 'Add-Ons', 'wpstg' );
|
345 |
+
|
346 |
+
//$tabs['misc'] = __( 'Misc', 'wpstg' );
|
347 |
+
|
348 |
+
return apply_filters( 'wpstg_settings_tabs', $tabs );
|
349 |
+
}
|
350 |
+
|
351 |
+
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Header Callback
|
355 |
+
*
|
356 |
+
* Renders the header.
|
357 |
+
*
|
358 |
+
* @since 1.0
|
359 |
+
* @param array $args Arguments passed by the setting
|
360 |
+
* @return void
|
361 |
+
*/
|
362 |
+
function wpstg_header_callback( $args ) {
|
363 |
+
//echo '<hr/>';
|
364 |
+
echo ' ';
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Checkbox Callback
|
369 |
+
*
|
370 |
+
* Renders checkboxes.
|
371 |
+
*
|
372 |
+
* @since 1.0
|
373 |
+
* @param array $args Arguments passed by the setting
|
374 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
375 |
+
* @return void
|
376 |
+
*/
|
377 |
+
function wpstg_checkbox_callback( $args ) {
|
378 |
+
global $wpstg_options;
|
379 |
+
|
380 |
+
$checked = isset( $wpstg_options[ $args[ 'id' ] ] ) ? checked( 1, $wpstg_options[ $args[ 'id' ] ], false ) : '';
|
381 |
+
$html = '<input type="checkbox" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="1" ' . $checked . '/>';
|
382 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
383 |
+
|
384 |
+
echo $html;
|
385 |
+
}
|
386 |
+
|
387 |
+
|
388 |
+
/**
|
389 |
+
* Multicheck Callback
|
390 |
+
*
|
391 |
+
* Renders multiple checkboxes.
|
392 |
+
*
|
393 |
+
* @since 1.0
|
394 |
+
* @param array $args Arguments passed by the setting
|
395 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
396 |
+
* @return void
|
397 |
+
*/
|
398 |
+
function wpstg_multicheck_callback( $args ) {
|
399 |
+
global $wpstg_options;
|
400 |
+
|
401 |
+
if ( ! empty( $args['options'] ) ) {
|
402 |
+
foreach( $args['options'] as $key => $option ):
|
403 |
+
if( isset( $wpstg_options[$args['id']][$key] ) ) { $enabled = $option; } else { $enabled = NULL; }
|
404 |
+
echo '<input name="wpstg_settings[' . $args['id'] . '][' . $key . ']" id="wpstg_settings[' . $args['id'] . '][' . $key . ']" type="checkbox" value="' . $option . '" ' . checked($option, $enabled, false) . '/> ';
|
405 |
+
echo '<label for="wpstg_settings[' . $args['id'] . '][' . $key . ']">' . $option . '</label><br/>';
|
406 |
+
endforeach;
|
407 |
+
echo '<p class="description wpstg_hidden">' . $args['desc'] . '</p>';
|
408 |
+
}
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Radio Callback
|
413 |
+
*
|
414 |
+
* Renders radio boxes.
|
415 |
+
*
|
416 |
+
* @since 1.3.3
|
417 |
+
* @param array $args Arguments passed by the setting
|
418 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
419 |
+
* @return void
|
420 |
+
*/
|
421 |
+
function wpstg_radio_callback( $args ) {
|
422 |
+
global $wpstg_options;
|
423 |
+
|
424 |
+
foreach ( $args['options'] as $key => $option ) :
|
425 |
+
$checked = false;
|
426 |
+
|
427 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) && $wpstg_options[ $args['id'] ] == $key )
|
428 |
+
$checked = true;
|
429 |
+
elseif( isset( $args['std'] ) && $args['std'] == $key && ! isset( $wpstg_options[ $args['id'] ] ) )
|
430 |
+
$checked = true;
|
431 |
+
|
432 |
+
echo '<input name="wpstg_settings[' . $args['id'] . ']"" id="wpstg_settings[' . $args['id'] . '][' . $key . ']" type="radio" value="' . $key . '" ' . checked(true, $checked, false) . '/> ';
|
433 |
+
echo '<label for="wpstg_settings[' . $args['id'] . '][' . $key . ']">' . $option . '</label><br/>';
|
434 |
+
endforeach;
|
435 |
+
|
436 |
+
echo '<p class="description wpstg_hidden">' . $args['desc'] . '</p>';
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* Text Callback
|
441 |
+
*
|
442 |
+
* Renders text fields.
|
443 |
+
*
|
444 |
+
* @since 1.0
|
445 |
+
* @param array $args Arguments passed by the setting
|
446 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
447 |
+
* @return void
|
448 |
+
*/
|
449 |
+
function wpstg_text_callback( $args ) {
|
450 |
+
global $wpstg_options;
|
451 |
+
|
452 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
453 |
+
$value = $wpstg_options[ $args['id'] ];
|
454 |
+
else
|
455 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
456 |
+
|
457 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
458 |
+
$html = '<input type="text" class="' . $size . '-text" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
|
459 |
+
$html .= '<label class="wpstg_hidden" class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
460 |
+
|
461 |
+
echo $html;
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Number Callback
|
466 |
+
*
|
467 |
+
* Renders number fields.
|
468 |
+
*
|
469 |
+
* @since 1.9
|
470 |
+
* @param array $args Arguments passed by the setting
|
471 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
472 |
+
* @return void
|
473 |
+
*/
|
474 |
+
function wpstg_number_callback( $args ) {
|
475 |
+
global $wpstg_options;
|
476 |
+
|
477 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
478 |
+
$value = $wpstg_options[ $args['id'] ];
|
479 |
+
else
|
480 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
481 |
+
|
482 |
+
$max = isset( $args['max'] ) ? $args['max'] : 999999;
|
483 |
+
$min = isset( $args['min'] ) ? $args['min'] : 0;
|
484 |
+
$step = isset( $args['step'] ) ? $args['step'] : 1;
|
485 |
+
|
486 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
487 |
+
$html = '<input type="number" step="' . esc_attr( $step ) . '" max="' . esc_attr( $max ) . '" min="' . esc_attr( $min ) . '" class="' . $size . '-text" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
|
488 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
489 |
+
|
490 |
+
echo $html;
|
491 |
+
}
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Textarea Callback
|
495 |
+
*
|
496 |
+
* Renders textarea fields.
|
497 |
+
*
|
498 |
+
* @since 1.0
|
499 |
+
* @param array $args Arguments passed by the setting
|
500 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
501 |
+
* @return void
|
502 |
+
*/
|
503 |
+
function wpstg_textarea_callback( $args ) {
|
504 |
+
global $wpstg_options;
|
505 |
+
|
506 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
507 |
+
$value = $wpstg_options[ $args['id'] ];
|
508 |
+
else
|
509 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
510 |
+
|
511 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : '40';
|
512 |
+
$html = '<textarea class="large-text wpstg-textarea" cols="50" rows="' . $size . '" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
|
513 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
514 |
+
|
515 |
+
echo $html;
|
516 |
+
}
|
517 |
+
|
518 |
+
/**
|
519 |
+
* Password Callback
|
520 |
+
*
|
521 |
+
* Renders password fields.
|
522 |
+
*
|
523 |
+
* @since 1.3
|
524 |
+
* @param array $args Arguments passed by the setting
|
525 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
526 |
+
* @return void
|
527 |
+
*/
|
528 |
+
function wpstg_password_callback( $args ) {
|
529 |
+
global $wpstg_options;
|
530 |
+
|
531 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
532 |
+
$value = $wpstg_options[ $args['id'] ];
|
533 |
+
else
|
534 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
535 |
+
|
536 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
537 |
+
$html = '<input type="password" class="' . $size . '-text" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( $value ) . '"/>';
|
538 |
+
$html .= '<label for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
539 |
+
|
540 |
+
echo $html;
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Missing Callback
|
545 |
+
*
|
546 |
+
* If a function is missing for settings callbacks alert the user.
|
547 |
+
*
|
548 |
+
* @since 1.3.1
|
549 |
+
* @param array $args Arguments passed by the setting
|
550 |
+
* @return void
|
551 |
+
*/
|
552 |
+
function wpstg_missing_callback($args) {
|
553 |
+
printf( __( 'The callback function used for the <strong>%s</strong> setting is missing.', 'wpstg' ), $args['id'] );
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Select Callback
|
558 |
+
*
|
559 |
+
* Renders select fields.
|
560 |
+
*
|
561 |
+
* @since 1.0
|
562 |
+
* @param array $args Arguments passed by the setting
|
563 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
564 |
+
* @return void
|
565 |
+
*/
|
566 |
+
function wpstg_select_callback($args) {
|
567 |
+
global $wpstg_options;
|
568 |
+
|
569 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
570 |
+
$value = $wpstg_options[ $args['id'] ];
|
571 |
+
else
|
572 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
573 |
+
|
574 |
+
$html = '<select id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']"/>';
|
575 |
+
|
576 |
+
foreach ( $args['options'] as $option => $name ) :
|
577 |
+
$selected = selected( $option, $value, false );
|
578 |
+
$html .= '<option value="' . $option . '" ' . $selected . '>' . $name . '</option>';
|
579 |
+
endforeach;
|
580 |
+
|
581 |
+
$html .= '</select>';
|
582 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
583 |
+
|
584 |
+
echo $html;
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* Color select Callback
|
589 |
+
*
|
590 |
+
* Renders color select fields.
|
591 |
+
*
|
592 |
+
* @since 2.1.2
|
593 |
+
* @param array $args Arguments passed by the setting
|
594 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
595 |
+
* @return void
|
596 |
+
*/
|
597 |
+
|
598 |
+
|
599 |
+
function wpstg_color_select_callback( $args ) {
|
600 |
+
global $wpstg_options;
|
601 |
+
|
602 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
603 |
+
$value = $wpstg_options[ $args['id'] ];
|
604 |
+
else
|
605 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
606 |
+
|
607 |
+
$html = '<strong>#:</strong><input type="text" style="max-width:80px;border:1px solid #' . esc_attr( stripslashes( $value ) ) . ';border-right:20px solid #' . esc_attr( stripslashes( $value ) ) . ';" id="wpstg_settings[' . $args['id'] . ']" class="medium-text ' . $args['id'] . '" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
|
608 |
+
|
609 |
+
$html .= '</select>';
|
610 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
611 |
+
|
612 |
+
echo $html;
|
613 |
+
}
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Rich Editor Callback
|
617 |
+
*
|
618 |
+
* Renders rich editor fields.
|
619 |
+
*
|
620 |
+
* @since 1.0
|
621 |
+
* @param array $args Arguments passed by the setting
|
622 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
623 |
+
* @global $wp_version WordPress Version
|
624 |
+
*/
|
625 |
+
function wpstg_rich_editor_callback( $args ) {
|
626 |
+
global $wpstg_options, $wp_version;
|
627 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
628 |
+
$value = $wpstg_options[ $args['id'] ];
|
629 |
+
else
|
630 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
631 |
+
|
632 |
+
if ( $wp_version >= 3.3 && function_exists( 'wp_editor' ) ) {
|
633 |
+
ob_start();
|
634 |
+
wp_editor( stripslashes( $value ), 'wpstg_settings_' . $args['id'], array( 'textarea_name' => 'wpstg_settings[' . $args['id'] . ']', 'textarea_rows' => $args['textarea_rows'] ) );
|
635 |
+
$html = ob_get_clean();
|
636 |
+
} else {
|
637 |
+
$html = '<textarea class="large-text wpstg-richeditor" rows="10" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
|
638 |
+
}
|
639 |
+
|
640 |
+
$html .= '<br/><label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
641 |
+
|
642 |
+
echo $html;
|
643 |
+
}
|
644 |
+
|
645 |
+
/**
|
646 |
+
* Upload Callback
|
647 |
+
*
|
648 |
+
* Renders upload fields.
|
649 |
+
*
|
650 |
+
* @since 1.0
|
651 |
+
* @param array $args Arguments passed by the setting
|
652 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
653 |
+
* @return void
|
654 |
+
*/
|
655 |
+
function wpstg_upload_callback( $args ) {
|
656 |
+
global $wpstg_options;
|
657 |
+
|
658 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
659 |
+
$value = $wpstg_options[$args['id']];
|
660 |
+
else
|
661 |
+
$value = isset($args['std']) ? $args['std'] : '';
|
662 |
+
|
663 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
664 |
+
$html = '<input type="text" class="' . $size . '-text wpstg_upload_field" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
|
665 |
+
$html .= '<span> <input type="button" class="wpstg_settings_upload_button button-secondary" value="' . __( 'Upload File', 'wpstg' ) . '"/></span>';
|
666 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
667 |
+
|
668 |
+
echo $html;
|
669 |
+
}
|
670 |
+
|
671 |
+
|
672 |
+
/**
|
673 |
+
* Registers the license field callback for Software Licensing
|
674 |
+
*
|
675 |
+
* @since 1.5
|
676 |
+
* @param array $args Arguments passed by the setting
|
677 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
678 |
+
* @return void
|
679 |
+
*/
|
680 |
+
if ( ! function_exists( 'wpstg_license_key_callback' ) ) {
|
681 |
+
function wpstg_license_key_callback( $args ) {
|
682 |
+
global $wpstg_options;
|
683 |
+
|
684 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
685 |
+
$value = $wpstg_options[ $args['id'] ];
|
686 |
+
else
|
687 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
688 |
+
|
689 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
690 |
+
$html = '<input type="text" class="' . $size . '-text" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( $value ) . '"/>';
|
691 |
+
|
692 |
+
if ( 'valid' == get_option( $args['options']['is_valid_license_option'] ) ) {
|
693 |
+
$html .= '<input type="submit" class="button-secondary" name="' . $args['id'] . '_deactivate" value="' . __( 'Deactivate License', 'wpstg' ) . '"/>';
|
694 |
+
$html .= '<span style="font-weight:bold;color:green;"> License key activated! </span> <p style="color:green;font-size:13px;"> You´ll get updates for this Add-On automatically!</p>';
|
695 |
+
} else {
|
696 |
+
$html .= '<span style="color:red;"> License key not activated!</span style=""><p style="font-size:13px;font-weight:bold;">You´ll get no important security and feature updates for this Add-On!</p>';
|
697 |
+
}
|
698 |
+
$html .= '<label for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
699 |
+
|
700 |
+
wp_nonce_field( $args['id'] . '-nonce', $args['id'] . '-nonce' );
|
701 |
+
|
702 |
+
echo $html;
|
703 |
+
}
|
704 |
+
}
|
705 |
+
|
706 |
+
|
707 |
+
|
708 |
+
/**
|
709 |
+
* Registers the Add-Ons field callback for WP-Staging Add-Ons
|
710 |
+
*
|
711 |
+
* @since 2.0.5
|
712 |
+
* @param array $args Arguments passed by the setting
|
713 |
+
* @return html
|
714 |
+
*/
|
715 |
+
function wpstg_addons_callback( $args ) {
|
716 |
+
$html = wpstg_add_ons_page();
|
717 |
+
echo $html;
|
718 |
+
}
|
719 |
+
|
720 |
+
/**
|
721 |
+
* Registers the image upload field
|
722 |
+
*
|
723 |
+
* @since 1.0
|
724 |
+
* @param array $args Arguments passed by the setting
|
725 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
726 |
+
* @return void
|
727 |
+
*/
|
728 |
+
|
729 |
+
function wpstg_upload_image_callback( $args ) {
|
730 |
+
global $wpstg_options;
|
731 |
+
|
732 |
+
if ( isset( $wpstg_options[ $args['id'] ] ) )
|
733 |
+
$value = $wpstg_options[ $args['id'] ];
|
734 |
+
else
|
735 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
736 |
+
|
737 |
+
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
738 |
+
$html = '<input type="text" class="' . $size . '-text ' . $args['id'] . '" id="wpstg_settings[' . $args['id'] . ']" name="wpstg_settings[' . $args['id'] . ']" value="' . esc_attr( $value ) . '"/>';
|
739 |
+
|
740 |
+
$html .= '<input type="submit" class="button-secondary wpstg_upload_image" name="' . $args['id'] . '_upload" value="' . __( 'Select Image', 'wpstg' ) . '"/>';
|
741 |
+
|
742 |
+
$html .= '<label class="wpstg_hidden" for="wpstg_settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
|
743 |
+
|
744 |
+
echo $html;
|
745 |
+
}
|
746 |
+
|
747 |
+
|
748 |
+
|
749 |
+
|
750 |
+
|
751 |
+
/**
|
752 |
+
* Hook Callback
|
753 |
+
*
|
754 |
+
* Adds a do_action() hook in place of the field
|
755 |
+
*
|
756 |
+
* @since 1.0.8.2
|
757 |
+
* @param array $args Arguments passed by the setting
|
758 |
+
* @return void
|
759 |
+
*/
|
760 |
+
function wpstg_hook_callback( $args ) {
|
761 |
+
do_action( 'wpstg_' . $args['id'] );
|
762 |
+
}
|
763 |
+
|
764 |
+
/**
|
765 |
+
* Set manage_options as the cap required to save WPSTG settings pages
|
766 |
+
*
|
767 |
+
* @since 1.9
|
768 |
+
* @return string capability required
|
769 |
+
*/
|
770 |
+
function wpstg_set_settings_cap() {
|
771 |
+
return 'manage_options';
|
772 |
+
}
|
773 |
+
add_filter( 'option_page_capability_wpstg_settings', 'wpstg_set_settings_cap' );
|
774 |
+
|
775 |
+
|
776 |
+
|
777 |
+
|
778 |
+
/* Permission check if logfile is writable
|
779 |
+
*
|
780 |
+
* @since 2.0.6
|
781 |
+
* @return string
|
782 |
+
*/
|
783 |
+
|
784 |
+
function wpstg_log_permissions(){
|
785 |
+
global $wpstg_options;
|
786 |
+
if (!WPSTG()->logger->checkDir() ){
|
787 |
+
return '<br><strong style="color:red;">' . __('Log file directory not writable! Set FTP permission to 755 or 777 for /wp-content/plugins/wp-staging/logs/', 'wpstg') . '</strong> <br> Read here more about <a href="http://codex.wordpress.org/Changing_File_Permissions" target="_blank">file permissions</a> ';
|
788 |
+
}
|
789 |
+
}
|
790 |
+
|
791 |
+
/**
|
792 |
+
* Render template for installing a must-use plugin (MU Plugin)
|
793 |
+
*/
|
794 |
+
function wpstg_install_muplugin_callback(){
|
795 |
+
$plugin_compatibility_checked = isset( $GLOBALS['wpstg_optimizer'] ) ? ' checked="checked"' : '';
|
796 |
+
ob_start();
|
797 |
+
?>
|
798 |
+
<div class="option-section plugin-compatibility-section">
|
799 |
+
<label for="plugin-compatibility" class="plugin-compatibility bubble" style="float:left;">
|
800 |
+
<input id="plugin-compatibility" type="checkbox" name="plugin_compatibility"<?php echo $plugin_compatibility_checked; ?> autocomplete="off"<?php echo $plugin_compatibility_checked; ?> />
|
801 |
+
<?php __( 'Improve performance and reliability by not loading the following plugins for migration requests', 'wpstg' ); ?>
|
802 |
+
</label>
|
803 |
+
<a href="#" class="general-helper plugin-compatibility-helper js-action-link"></a>
|
804 |
+
|
805 |
+
<div class="plugin-compatibility-message helper-message bottom">
|
806 |
+
<?php echo __( 'Select the plugins you wish to disable during clone process', 'wpstg' ); ?></br>
|
807 |
+
</div>
|
808 |
+
|
809 |
+
<div class="indent-wrap expandable-content plugin-compatibility-wrap select-wrap" style="display:none;">
|
810 |
+
<select autocomplete="off" class="multiselect" id="selected-plugins" name="selected_plugins[]" multiple="multiple" style="min-height:400px;">
|
811 |
+
<?php
|
812 |
+
global $wpstg_options;
|
813 |
+
$blacklist = array_flip( (array) $wpstg_options['blacklist_plugins'] );
|
814 |
+
foreach ( get_plugins() as $key => $plugin ) {
|
815 |
+
if ( 0 === strpos( $key, 'wp-staging' ) ) {
|
816 |
+
continue;
|
817 |
+
}
|
818 |
+
$selected = ( isset( $blacklist[ $key ] ) ) ? ' selected' : '';
|
819 |
+
printf( '<option value="%s"%s>%s</option>', $key, $selected, $plugin['Name'] );
|
820 |
+
}
|
821 |
+
?>
|
822 |
+
</select>
|
823 |
+
<br>
|
824 |
+
<a class="multiselect-select-all js-action-link" href="#"><?php _e( 'Select All', 'wpstg' ); ?></a>
|
825 |
+
<span class="select-deselect-divider">/</span>
|
826 |
+
<a class="multiselect-deselect-all js-action-link" href="#"><?php _e( 'Deselect All', 'wpstg' ); ?></a>
|
827 |
+
<span class="select-deselect-divider">/</span>
|
828 |
+
<a class="multiselect-invert-selection js-action-link" href="#"><?php _e( 'Invert Selection', 'wpstg' ); ?></a>
|
829 |
+
<p>
|
830 |
+
<span class="button plugin-compatibility-save"><?php _e( 'Save Changes', 'wpstg' ); ?></span>
|
831 |
+
<span class="plugin-compatibility-success-msg"><?php _ex( 'Saved', 'The settings were saved successfully', 'wpstg' ); ?></span>
|
832 |
+
</p>
|
833 |
+
</div>
|
834 |
+
</div>
|
835 |
+
<?php
|
836 |
+
$html = ob_get_contents();
|
837 |
+
ob_end_clean();
|
838 |
+
echo $html;
|
839 |
+
}
|
includes/admin/tools.php
ADDED
@@ -0,0 +1,460 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Tools
|
4 |
+
*
|
5 |
+
* These are functions used for displaying WPSTG tools such as the import/export system.
|
6 |
+
*
|
7 |
+
* @package WPSTG
|
8 |
+
* @subpackage Admin/Tools
|
9 |
+
* @copyright Copyright (c) 2015, Pippin Williamson, René Hermenau
|
10 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Tools
|
18 |
+
*
|
19 |
+
* Shows the tools panel which contains WPSTG-specific tools including the
|
20 |
+
* built-in import/export system.
|
21 |
+
*
|
22 |
+
* @since 0.9.0
|
23 |
+
* @author Daniel J Griffiths
|
24 |
+
* @return void
|
25 |
+
*/
|
26 |
+
function wpstg_tools_page() {
|
27 |
+
$active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'import_export';
|
28 |
+
?>
|
29 |
+
<div class="wrap">
|
30 |
+
<h2 class="nav-tab-wrapper">
|
31 |
+
<?php
|
32 |
+
foreach( wpstg_get_tools_tabs() as $tab_id => $tab_name ) {
|
33 |
+
|
34 |
+
$tab_url = add_query_arg( array(
|
35 |
+
'tab' => $tab_id
|
36 |
+
) );
|
37 |
+
|
38 |
+
$tab_url = remove_query_arg( array(
|
39 |
+
'wpstg-message'
|
40 |
+
), $tab_url );
|
41 |
+
|
42 |
+
$active = $active_tab == $tab_id ? ' nav-tab-active' : '';
|
43 |
+
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $tab_name ) . '" class="nav-tab' . $active . '">' . esc_html( $tab_name ) . '</a>';
|
44 |
+
|
45 |
+
}
|
46 |
+
?>
|
47 |
+
</h2>
|
48 |
+
<div class="metabox-holder">
|
49 |
+
<?php
|
50 |
+
do_action( 'wpstg_tools_tab_' . $active_tab );
|
51 |
+
?>
|
52 |
+
</div><!-- .metabox-holder -->
|
53 |
+
</div><!-- .wrap -->
|
54 |
+
<?php
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Retrieve tools tabs
|
60 |
+
*
|
61 |
+
* @since 2.1.6
|
62 |
+
* @return array
|
63 |
+
*/
|
64 |
+
function wpstg_get_tools_tabs() {
|
65 |
+
|
66 |
+
$tabs = array();
|
67 |
+
$tabs['import_export'] = __( 'Import/Export', 'wpstg' );
|
68 |
+
$tabs['system_info'] = __( 'System Info', 'wpstg' );
|
69 |
+
|
70 |
+
return apply_filters( 'wpstg_tools_tabs', $tabs );
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Display the tools import/export tab
|
77 |
+
*
|
78 |
+
* @since 2.1.6
|
79 |
+
* @return void
|
80 |
+
*/
|
81 |
+
function wpstg_tools_import_export_display() {
|
82 |
+
|
83 |
+
if( ! current_user_can( 'update_plugins' ) ) {
|
84 |
+
return;
|
85 |
+
}
|
86 |
+
|
87 |
+
do_action( 'wpstg_tools_import_export_before' );
|
88 |
+
?>
|
89 |
+
<div class="postbox">
|
90 |
+
<h3><span><?php _e( 'Export Settings', 'wpstg' ); ?></span></h3>
|
91 |
+
<div class="inside">
|
92 |
+
<p><?php _e( 'Export the WP-Staging settings for this site as a .json file. This allows you to easily import the configuration into another site.', 'wpstg' ); ?></p>
|
93 |
+
|
94 |
+
<form method="post" action="<?php echo admin_url( 'admin.php?page=wpstg-tools&tab=import_export' ); ?>">
|
95 |
+
<p><input type="hidden" name="wpstg-action" value="export_settings" /></p>
|
96 |
+
<p>
|
97 |
+
<?php wp_nonce_field( 'wpstg_export_nonce', 'wpstg_export_nonce' ); ?>
|
98 |
+
<?php submit_button( __( 'Export', 'wpstg' ), 'primary', 'submit', false ); ?>
|
99 |
+
</p>
|
100 |
+
</form>
|
101 |
+
</div><!-- .inside -->
|
102 |
+
</div><!-- .postbox -->
|
103 |
+
|
104 |
+
<div class="postbox">
|
105 |
+
<h3><span><?php _e( 'Import Settings', 'wpstg' ); ?></span></h3>
|
106 |
+
<div class="inside">
|
107 |
+
<p><?php _e( 'Import the WP-Staging settings from a .json file. This file can be obtained by exporting the settings on another site using the form above.', 'wpstg' ); ?></p>
|
108 |
+
<form method="post" enctype="multipart/form-data" action="<?php echo admin_url( 'admin.php?page=wpstg-tools&tab=import_export' ); ?>">
|
109 |
+
<p>
|
110 |
+
<input type="file" name="import_file"/>
|
111 |
+
</p>
|
112 |
+
<p>
|
113 |
+
<input type="hidden" name="wpstg-action" value="import_settings" />
|
114 |
+
<?php wp_nonce_field( 'wpstg_import_nonce', 'wpstg_import_nonce' ); ?>
|
115 |
+
<?php submit_button( __( 'Import', 'wpstg' ), 'secondary', 'submit', false ); ?>
|
116 |
+
</p>
|
117 |
+
</form>
|
118 |
+
</div><!-- .inside -->
|
119 |
+
</div><!-- .postbox -->
|
120 |
+
<?php
|
121 |
+
do_action( 'wpstg_tools_import_export_after' );
|
122 |
+
}
|
123 |
+
add_action( 'wpstg_tools_tab_import_export', 'wpstg_tools_import_export_display' );
|
124 |
+
|
125 |
+
/* check if function is disabled or not
|
126 |
+
*
|
127 |
+
* @returns bool
|
128 |
+
* @since 2.1.6
|
129 |
+
*/
|
130 |
+
function wpstg_is_func_disabled( $function ) {
|
131 |
+
$disabled = explode( ',', ini_get( 'disable_functions' ) );
|
132 |
+
return in_array( $function, $disabled );
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Process a settings export that generates a .json file of the WP-Staging settings
|
137 |
+
*
|
138 |
+
* @since 2.1.6
|
139 |
+
* @return void
|
140 |
+
*/
|
141 |
+
function wpstg_tools_import_export_process_export() {
|
142 |
+
if( empty( $_POST['wpstg_export_nonce'] ) )
|
143 |
+
return;
|
144 |
+
|
145 |
+
if( ! wp_verify_nonce( $_POST['wpstg_export_nonce'], 'wpstg_export_nonce' ) )
|
146 |
+
return;
|
147 |
+
|
148 |
+
if( ! current_user_can( 'manage_options' ) )
|
149 |
+
return;
|
150 |
+
|
151 |
+
$settings = array();
|
152 |
+
$settings = get_option( 'wpstg_settings' );
|
153 |
+
|
154 |
+
ignore_user_abort( true );
|
155 |
+
|
156 |
+
if ( ! wpstg_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) )
|
157 |
+
set_time_limit( 0 );
|
158 |
+
|
159 |
+
nocache_headers();
|
160 |
+
header( 'Content-Type: application/json; charset=utf-8' );
|
161 |
+
header( 'Content-Disposition: attachment; filename=' . apply_filters( 'wpstg_settings_export_filename', 'wpstg-settings-export-' . date( 'm-d-Y' ) ) . '.json' );
|
162 |
+
header( "Expires: 0" );
|
163 |
+
|
164 |
+
echo json_encode( $settings );
|
165 |
+
exit;
|
166 |
+
}
|
167 |
+
add_action( 'wpstg_export_settings', 'wpstg_tools_import_export_process_export' );
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Get File Extension
|
171 |
+
*
|
172 |
+
* Returns the file extension of a filename.
|
173 |
+
*
|
174 |
+
* @since 1.0
|
175 |
+
* @param unknown $str File name
|
176 |
+
* @return mixed File extension
|
177 |
+
*/
|
178 |
+
function wpstg_get_file_extension( $str ) {
|
179 |
+
$parts = explode( '.', $str );
|
180 |
+
return end( $parts );
|
181 |
+
}
|
182 |
+
|
183 |
+
/* Convert an object to an associative array.
|
184 |
+
* Can handle multidimensional arrays
|
185 |
+
*
|
186 |
+
* @returns array
|
187 |
+
* @since 2.1.6
|
188 |
+
*/
|
189 |
+
function wpstg_object_to_array( $data ) {
|
190 |
+
if ( is_array( $data ) || is_object( $data ) ) {
|
191 |
+
$result = array();
|
192 |
+
foreach ( $data as $key => $value ) {
|
193 |
+
$result[ $key ] = wpstg_object_to_array( $value );
|
194 |
+
}
|
195 |
+
return $result;
|
196 |
+
}
|
197 |
+
return $data;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Process a settings import from a json file
|
202 |
+
*
|
203 |
+
* @since 2.1.6
|
204 |
+
* @return void
|
205 |
+
*/
|
206 |
+
function wpstg_tools_import_export_process_import() {
|
207 |
+
if( empty( $_POST['wpstg_import_nonce'] ) )
|
208 |
+
return;
|
209 |
+
|
210 |
+
if( ! wp_verify_nonce( $_POST['wpstg_import_nonce'], 'wpstg_import_nonce' ) )
|
211 |
+
return;
|
212 |
+
|
213 |
+
if( ! current_user_can( 'update_plugins' ) )
|
214 |
+
return;
|
215 |
+
|
216 |
+
if( wpstg_get_file_extension( $_FILES['import_file']['name'] ) != 'json' ) {
|
217 |
+
wp_die( __( 'Please upload a valid .json file', 'wpstg' ) );
|
218 |
+
}
|
219 |
+
|
220 |
+
$import_file = $_FILES['import_file']['tmp_name'];
|
221 |
+
|
222 |
+
if( empty( $import_file ) ) {
|
223 |
+
wp_die( __( 'Please upload a file to import', 'wpstg' ) );
|
224 |
+
}
|
225 |
+
|
226 |
+
// Retrieve the settings from the file and convert the json object to an array
|
227 |
+
$settings = wpstg_object_to_array( json_decode( file_get_contents( $import_file ) ) );
|
228 |
+
|
229 |
+
update_option( 'wpstg_settings', $settings );
|
230 |
+
|
231 |
+
wp_safe_redirect( admin_url( 'admin.php?page=wpstg-tools&wpstg-message=settings-imported' ) ); exit;
|
232 |
+
|
233 |
+
}
|
234 |
+
add_action( 'wpstg_import_settings', 'wpstg_tools_import_export_process_import' );
|
235 |
+
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Display the system info tab
|
239 |
+
*
|
240 |
+
* @since 2.1.6
|
241 |
+
* @return void
|
242 |
+
* @change 2.3.1
|
243 |
+
*/
|
244 |
+
function wpstg_tools_sysinfo_display() {
|
245 |
+
|
246 |
+
if( ! current_user_can( 'update_plugins' ) ) {
|
247 |
+
return;
|
248 |
+
}
|
249 |
+
|
250 |
+
?>
|
251 |
+
<form action="<?php echo esc_url( admin_url( 'admin.php?page=wpstg-tools&tab=system_info' ) ); ?>" method="post" dir="ltr">
|
252 |
+
<textarea class="wpstg-sysinfo" readonly="readonly" onclick="this.focus(); this.select()" id="system-info-textarea" name="wpstg-sysinfo" title="To copy the system info, click below then press Ctrl + C (PC) or Cmd + C (Mac)."><?php echo wpstg_tools_sysinfo_get(); ?></textarea>
|
253 |
+
<p class="submit">
|
254 |
+
<input type="hidden" name="wpstg-action" value="download_sysinfo" />
|
255 |
+
<?php submit_button( 'Download System Info File', 'primary', 'wpstg-download-sysinfo', false ); ?>
|
256 |
+
</p>
|
257 |
+
</form>
|
258 |
+
<?php
|
259 |
+
}
|
260 |
+
add_action( 'wpstg_tools_tab_system_info', 'wpstg_tools_sysinfo_display' );
|
261 |
+
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Get system info
|
265 |
+
*
|
266 |
+
* @since 2.1.6
|
267 |
+
* @access public
|
268 |
+
* @global object $wpdb Used to query the database using the WordPress Database API
|
269 |
+
* @global array $wpstg_options Array of all WPSTG options
|
270 |
+
* @return string $return A string containing the info to output
|
271 |
+
*/
|
272 |
+
function wpstg_tools_sysinfo_get() {
|
273 |
+
global $wpdb, $wpstg_options;
|
274 |
+
|
275 |
+
if( !class_exists( 'Browser' ) )
|
276 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/libraries/browser.php';
|
277 |
+
|
278 |
+
$browser = new Browser();
|
279 |
+
|
280 |
+
// Get theme info
|
281 |
+
if( get_bloginfo( 'version' ) < '3.4' ) {
|
282 |
+
$theme_data = get_theme_data( get_stylesheet_directory() . '/style.css' );
|
283 |
+
$theme = $theme_data['Name'] . ' ' . $theme_data['Version'];
|
284 |
+
} else {
|
285 |
+
$theme_data = wp_get_theme();
|
286 |
+
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
287 |
+
}
|
288 |
+
|
289 |
+
|
290 |
+
$return = '### Begin System Info ###' . "\n\n";
|
291 |
+
|
292 |
+
// Start with the basics...
|
293 |
+
$return .= '-- Site Info' . "\n\n";
|
294 |
+
$return .= 'Site URL: ' . site_url() . "\n";
|
295 |
+
$return .= 'Home URL: ' . home_url() . "\n";
|
296 |
+
$return .= 'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ) . "\n";
|
297 |
+
|
298 |
+
$return = apply_filters( 'wpstg_sysinfo_after_site_info', $return );
|
299 |
+
|
300 |
+
|
301 |
+
// The local users' browser information, handled by the Browser class
|
302 |
+
$return .= "\n" . '-- User Browser' . "\n\n";
|
303 |
+
$return .= $browser;
|
304 |
+
|
305 |
+
$return = apply_filters( 'wpstg_sysinfo_after_user_browser', $return );
|
306 |
+
|
307 |
+
// WordPress configuration
|
308 |
+
$return .= "\n" . '-- WordPress Configuration' . "\n\n";
|
309 |
+
$return .= 'Version: ' . get_bloginfo( 'version' ) . "\n";
|
310 |
+
$return .= 'Language: ' . ( defined( 'WPLANG' ) && WPLANG ? WPLANG : 'en_US' ) . "\n";
|
311 |
+
$return .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . "\n";
|
312 |
+
$return .= 'Active Theme: ' . $theme . "\n";
|
313 |
+
$return .= 'Show On Front: ' . get_option( 'show_on_front' ) . "\n";
|
314 |
+
|
315 |
+
// Only show page specs if frontpage is set to 'page'
|
316 |
+
if( get_option( 'show_on_front' ) == 'page' ) {
|
317 |
+
$front_page_id = get_option( 'page_on_front' );
|
318 |
+
$blog_page_id = get_option( 'page_for_posts' );
|
319 |
+
|
320 |
+
$return .= 'Page On Front: ' . ( $front_page_id != 0 ? get_the_title( $front_page_id ) . ' (#' . $front_page_id . ')' : 'Unset' ) . "\n";
|
321 |
+
$return .= 'Page For Posts: ' . ( $blog_page_id != 0 ? get_the_title( $blog_page_id ) . ' (#' . $blog_page_id . ')' : 'Unset' ) . "\n";
|
322 |
+
}
|
323 |
+
|
324 |
+
// Make sure wp_remote_post() is working
|
325 |
+
$request['cmd'] = '_notify-validate';
|
326 |
+
|
327 |
+
$params = array(
|
328 |
+
'sslverify' => false,
|
329 |
+
'timeout' => 60,
|
330 |
+
'user-agent' => 'WPSTG/' . WPSTG_VERSION,
|
331 |
+
'body' => $request
|
332 |
+
);
|
333 |
+
|
334 |
+
$response = wp_remote_post( 'https://www.paypal.com/cgi-bin/webscr', $params );
|
335 |
+
|
336 |
+
if( !is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) {
|
337 |
+
$WP_REMOTE_POST = 'wp_remote_post() works';
|
338 |
+
} else {
|
339 |
+
$WP_REMOTE_POST = 'wp_remote_post() does not work';
|
340 |
+
}
|
341 |
+
|
342 |
+
$return .= 'Remote Post: ' . $WP_REMOTE_POST . "\n";
|
343 |
+
$return .= 'Table Prefix: ' . 'Length: ' . strlen( $wpdb->prefix ) . ' Status: ' . ( strlen( $wpdb->prefix ) > 16 ? 'ERROR: Too long' : 'Acceptable' ) . "\n";
|
344 |
+
$return .= 'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' ) . "\n";
|
345 |
+
$return .= 'Memory Limit: ' . WP_MEMORY_LIMIT . "\n";
|
346 |
+
$return .= 'Registered Post Stati: ' . implode( ', ', get_post_stati() ) . "\n";
|
347 |
+
|
348 |
+
$return = apply_filters( 'wpstg_sysinfo_after_wordpress_config', $return );
|
349 |
+
|
350 |
+
// WPSTG configuration
|
351 |
+
$return .= "\n" . '-- WPSTG Configuration' . "\n\n";
|
352 |
+
$return .= 'Version: ' . WPSTG_VERSION . "\n";
|
353 |
+
$return .= 'Upgraded From: ' . get_option( 'wpstg_version_upgraded_from', 'None' ) . "\n";
|
354 |
+
|
355 |
+
$return = apply_filters( 'wpstg_sysinfo_after_wpstg_config', $return );
|
356 |
+
|
357 |
+
|
358 |
+
// WordPress active plugins
|
359 |
+
$return .= "\n" . '-- WordPress Active Plugins' . "\n\n";
|
360 |
+
|
361 |
+
$plugins = get_plugins();
|
362 |
+
$active_plugins = get_option( 'active_plugins', array() );
|
363 |
+
|
364 |
+
foreach( $plugins as $plugin_path => $plugin ) {
|
365 |
+
if( !in_array( $plugin_path, $active_plugins ) )
|
366 |
+
continue;
|
367 |
+
|
368 |
+
$return .= $plugin['Name'] . ': ' . $plugin['Version'] . "\n";
|
369 |
+
}
|
370 |
+
|
371 |
+
$return = apply_filters( 'wpstg_sysinfo_after_wordpress_plugins', $return );
|
372 |
+
|
373 |
+
// WordPress inactive plugins
|
374 |
+
$return .= "\n" . '-- WordPress Inactive Plugins' . "\n\n";
|
375 |
+
|
376 |
+
foreach( $plugins as $plugin_path => $plugin ) {
|
377 |
+
if( in_array( $plugin_path, $active_plugins ) )
|
378 |
+
continue;
|
379 |
+
|
380 |
+
$return .= $plugin['Name'] . ': ' . $plugin['Version'] . "\n";
|
381 |
+
}
|
382 |
+
|
383 |
+
$return = apply_filters( 'wpstg_sysinfo_after_wordpress_plugins_inactive', $return );
|
384 |
+
|
385 |
+
if( is_multisite() ) {
|
386 |
+
// WordPress Multisite active plugins
|
387 |
+
$return .= "\n" . '-- Network Active Plugins' . "\n\n";
|
388 |
+
|
389 |
+
$plugins = wp_get_active_network_plugins();
|
390 |
+
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
|
391 |
+
|
392 |
+
foreach( $plugins as $plugin_path ) {
|
393 |
+
$plugin_base = plugin_basename( $plugin_path );
|
394 |
+
|
395 |
+
if( !array_key_exists( $plugin_base, $active_plugins ) )
|
396 |
+
continue;
|
397 |
+
|
398 |
+
$plugin = get_plugin_data( $plugin_path );
|
399 |
+
$return .= $plugin['Name'] . ': ' . $plugin['Version'] . "\n";
|
400 |
+
}
|
401 |
+
|
402 |
+
$return = apply_filters( 'wpstg_sysinfo_after_wordpress_ms_plugins', $return );
|
403 |
+
}
|
404 |
+
|
405 |
+
// Server configuration (really just versioning)
|
406 |
+
$return .= "\n" . '-- Webserver Configuration' . "\n\n";
|
407 |
+
$return .= 'PHP Version: ' . PHP_VERSION . "\n";
|
408 |
+
$return .= 'MySQL Version: ' . $wpdb->db_version() . "\n";
|
409 |
+
$return .= 'Webserver Info: ' . $_SERVER['SERVER_SOFTWARE'] . "\n";
|
410 |
+
|
411 |
+
$return = apply_filters( 'wpstg_sysinfo_after_webserver_config', $return );
|
412 |
+
|
413 |
+
// PHP configs... now we're getting to the important stuff
|
414 |
+
$return .= "\n" . '-- PHP Configuration' . "\n\n";
|
415 |
+
$return .= 'Safe Mode: ' . ( ini_get( 'safe_mode' ) ? 'Enabled' : 'Disabled' . "\n" );
|
416 |
+
$return .= 'Memory Limit: ' . ini_get( 'memory_limit' ) . "\n";
|
417 |
+
$return .= 'Upload Max Size: ' . ini_get( 'upload_max_filesize' ) . "\n";
|
418 |
+
$return .= 'Post Max Size: ' . ini_get( 'post_max_size' ) . "\n";
|
419 |
+
$return .= 'Upload Max Filesize: ' . ini_get( 'upload_max_filesize' ) . "\n";
|
420 |
+
$return .= 'Time Limit: ' . ini_get( 'max_execution_time' ) . "\n";
|
421 |
+
$return .= 'Max Input Vars: ' . ini_get( 'max_input_vars' ) . "\n";
|
422 |
+
$return .= 'Display Errors: ' . ( ini_get( 'display_errors' ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A' ) . "\n";
|
423 |
+
|
424 |
+
$return = apply_filters( 'wpstg_sysinfo_after_php_config', $return );
|
425 |
+
|
426 |
+
// PHP extensions and such
|
427 |
+
$return .= "\n" . '-- PHP Extensions' . "\n\n";
|
428 |
+
$return .= 'cURL: ' . ( function_exists( 'curl_init' ) ? 'Supported' : 'Not Supported' ) . "\n";
|
429 |
+
$return .= 'fsockopen: ' . ( function_exists( 'fsockopen' ) ? 'Supported' : 'Not Supported' ) . "\n";
|
430 |
+
$return .= 'SOAP Client: ' . ( class_exists( 'SoapClient' ) ? 'Installed' : 'Not Installed' ) . "\n";
|
431 |
+
$return .= 'Suhosin: ' . ( extension_loaded( 'suhosin' ) ? 'Installed' : 'Not Installed' ) . "\n";
|
432 |
+
|
433 |
+
$return = apply_filters( 'wpstg_sysinfo_after_php_ext', $return );
|
434 |
+
|
435 |
+
$return .= "\n" . '### End System Info ###';
|
436 |
+
|
437 |
+
return $return;
|
438 |
+
}
|
439 |
+
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Generates a System Info download file
|
443 |
+
*
|
444 |
+
* @since 2.0
|
445 |
+
* @return void
|
446 |
+
*/
|
447 |
+
function wpstg_tools_sysinfo_download() {
|
448 |
+
|
449 |
+
if( ! current_user_can( 'update_plugins' ) )
|
450 |
+
return;
|
451 |
+
|
452 |
+
nocache_headers();
|
453 |
+
|
454 |
+
header( 'Content-Type: text/plain' );
|
455 |
+
header( 'Content-Disposition: attachment; filename="wpstg-system-info.txt"' );
|
456 |
+
|
457 |
+
echo wp_strip_all_tags( $_POST['wpstg-sysinfo'] );
|
458 |
+
wp_die();
|
459 |
+
}
|
460 |
+
add_action( 'wpstg_download_sysinfo', 'wpstg_tools_sysinfo_download' );
|
includes/admin/upload-functions.php
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Upload Functions
|
5 |
+
*
|
6 |
+
* @package WPSTG
|
7 |
+
* @subpackage Admin/Upload
|
8 |
+
* @copyright Copyright (c) 2015, Pippin Williamson, René Hermenau
|
9 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
10 |
+
* @since 0.9.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Retrieve the absolute path to the file upload directory without the trailing slash
|
16 |
+
*
|
17 |
+
* @since 0.9.0
|
18 |
+
* @return string $path Absolute path to the WPSTG upload directory
|
19 |
+
*/
|
20 |
+
function wpstg_get_upload_dir() {
|
21 |
+
$wp_upload_dir = wp_upload_dir();
|
22 |
+
wp_mkdir_p( $wp_upload_dir['basedir'] . '/wp-staging' );
|
23 |
+
$path = $wp_upload_dir['basedir'] . '/wp-staging';
|
24 |
+
|
25 |
+
return apply_filters( 'wpstg_get_upload_dir', $path );
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Checks if the .htaccess file exists in wp-content/uploads/wp-staging
|
30 |
+
*
|
31 |
+
* @since 0.9.0
|
32 |
+
* @return bool
|
33 |
+
*/
|
34 |
+
function wpstg_htaccess_exists() {
|
35 |
+
$upload_path = wpstg_get_upload_dir();
|
36 |
+
|
37 |
+
return file_exists( $upload_path . '/.htaccess' );
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Checks if the remaining_files.json file exists in wp-content/uploads/wp-staging
|
42 |
+
*
|
43 |
+
* @since 0.9.0
|
44 |
+
* @return bool
|
45 |
+
*/
|
46 |
+
function wpstg_remainingjson_exists() {
|
47 |
+
$upload_path = wpstg_get_upload_dir();
|
48 |
+
|
49 |
+
return file_exists( $upload_path . '/remaining_files.json' );
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Checks if the clone_details.json file exists in wp-content/uploads/wp-staging
|
54 |
+
*
|
55 |
+
* @since 0.9.0
|
56 |
+
* @return bool
|
57 |
+
*/
|
58 |
+
function wpstg_clonedetailsjson_exists() {
|
59 |
+
$upload_path = wpstg_get_upload_dir();
|
60 |
+
|
61 |
+
return file_exists( $upload_path . '/clone_details.json' );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Retrieve the .htaccess rules to wp-content/uploads/wp-staging/
|
66 |
+
*
|
67 |
+
* @since 0.9.0
|
68 |
+
*
|
69 |
+
* @param bool $method
|
70 |
+
* @return mixed|void The htaccess rules
|
71 |
+
*/
|
72 |
+
function wpstg_get_htaccess_rules() {
|
73 |
+
// Prevent directory browsing and direct access to all files
|
74 |
+
$rules = "<Files \"*\">\n";
|
75 |
+
$rules .= "<IfModule mod_access.c>\n";
|
76 |
+
$rules .= "Deny from all\n";
|
77 |
+
$rules .= "</IfModule>\n";
|
78 |
+
$rules .= "<IfModule !mod_access_compat>\n";
|
79 |
+
$rules .= "<IfModule mod_authz_host.c>\n";
|
80 |
+
$rules .= "Deny from all\n";
|
81 |
+
$rules .= "</IfModule>\n";
|
82 |
+
$rules .= "</IfModule>\n";
|
83 |
+
$rules .= "<IfModule mod_access_compat>\n";
|
84 |
+
$rules .= "Deny from all\n";
|
85 |
+
$rules .= "</IfModule>\n";
|
86 |
+
$rules .= "</Files>\n";
|
87 |
+
$rules = apply_filters('wpstg_protected_directory_htaccess_rules', $rules);
|
88 |
+
return $rules;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Creates blank index.php and .htaccess files
|
93 |
+
* Creates /wp-content/uploads/wp-staging subfolder
|
94 |
+
*
|
95 |
+
* This function runs approximately once per month in order to ensure all folders
|
96 |
+
* have their necessary protection files
|
97 |
+
*
|
98 |
+
* @since 1.1.0
|
99 |
+
*
|
100 |
+
* @param bool $force
|
101 |
+
*/
|
102 |
+
|
103 |
+
function wpstg_create_protection_files( $force = false ) {
|
104 |
+
if ( false === get_transient( 'wpstg_check_protection_files' ) || $force ) {
|
105 |
+
|
106 |
+
$upload_path = wpstg_get_upload_dir();
|
107 |
+
|
108 |
+
// Make sure the /wpstg folder is created
|
109 |
+
wp_mkdir_p( $upload_path );
|
110 |
+
|
111 |
+
// Top level .htaccess file
|
112 |
+
$rules = wpstg_get_htaccess_rules();
|
113 |
+
if ( wpstg_htaccess_exists() ) {
|
114 |
+
$contents = @file_get_contents( $upload_path . '/.htaccess' );
|
115 |
+
if ( $contents !== $rules || ! $contents ) {
|
116 |
+
// Update the .htaccess rules if they don't match
|
117 |
+
@file_put_contents( $upload_path . '/.htaccess', $rules );
|
118 |
+
}
|
119 |
+
} elseif( wp_is_writable( $upload_path ) ) {
|
120 |
+
// Create the file if it doesn't exist
|
121 |
+
@file_put_contents( $upload_path . '/.htaccess', $rules );
|
122 |
+
}
|
123 |
+
|
124 |
+
// Top level blank index.php
|
125 |
+
if ( ! file_exists( $upload_path . '/index.php' ) && wp_is_writable( $upload_path ) ) {
|
126 |
+
@file_put_contents( $upload_path . '/index.php', '<?php' . PHP_EOL . '// Silence is golden.' );
|
127 |
+
}
|
128 |
+
|
129 |
+
// Now place index.php files in all sub folders
|
130 |
+
$folders = wpstg_scan_upload_folders( $upload_path );
|
131 |
+
foreach ( $folders as $folder ) {
|
132 |
+
// Create index.php, if it doesn't exist
|
133 |
+
if ( ! file_exists( $folder . 'index.php' ) && wp_is_writable( $folder ) ) {
|
134 |
+
@file_put_contents( $folder . 'index.php', '<?php' . PHP_EOL . '// Silence is golden.' );
|
135 |
+
}
|
136 |
+
}
|
137 |
+
// Check for the files once per day
|
138 |
+
set_transient( 'wpstg_check_protection_files', true, 3600 * 24 );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
add_action( 'admin_init', 'wpstg_create_protection_files' );
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Scans all folders inside of /uploads/wpstg
|
145 |
+
*
|
146 |
+
* @since 0.9.0
|
147 |
+
* @return array $return List of files inside directory
|
148 |
+
*/
|
149 |
+
function wpstg_scan_upload_folders( $path = '', $return = array() ) {
|
150 |
+
$path = $path == ''? dirname( __FILE__ ) : $path;
|
151 |
+
$lists = @scandir( $path );
|
152 |
+
|
153 |
+
if ( ! empty( $lists ) ) {
|
154 |
+
foreach ( $lists as $f ) {
|
155 |
+
if ( is_dir( $path . DIRECTORY_SEPARATOR . $f ) && $f != "." && $f != ".." ) {
|
156 |
+
if ( ! in_array( $path . DIRECTORY_SEPARATOR . $f, $return ) )
|
157 |
+
$return[] = trailingslashit( $path . DIRECTORY_SEPARATOR . $f );
|
158 |
+
|
159 |
+
wpstg_scan_upload_folders( $path . DIRECTORY_SEPARATOR . $f, $return);
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
return $return;
|
165 |
+
}
|
166 |
+
|
167 |
+
// For installs on pre WP 3.6
|
168 |
+
if( ! function_exists( 'wp_is_writable' ) ) {
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Determine if a directory is writable.
|
172 |
+
*
|
173 |
+
* This function is used to work around certain ACL issues
|
174 |
+
* in PHP primarily affecting Windows Servers.
|
175 |
+
*
|
176 |
+
* @see win_is_writable()
|
177 |
+
*
|
178 |
+
* @since 3.6.0
|
179 |
+
*
|
180 |
+
* @param string $path
|
181 |
+
* @return bool
|
182 |
+
*/
|
183 |
+
function wp_is_writable( $path ) {
|
184 |
+
if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) )
|
185 |
+
return win_is_writable( $path );
|
186 |
+
else
|
187 |
+
return @is_writable( $path );
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
includes/admin/welcome.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Weclome Page Class
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Admin/Welcome
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* WPSTG_Welcome Class
|
17 |
+
*
|
18 |
+
* A general class for About and Credits page.
|
19 |
+
*
|
20 |
+
* @since 1.0
|
21 |
+
*/
|
22 |
+
class WPSTG_Welcome {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var string The capability users should have to view the page
|
26 |
+
*/
|
27 |
+
public $minimum_capability = 'manage_options';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Get things started
|
31 |
+
*
|
32 |
+
* @since 1.0.1
|
33 |
+
*/
|
34 |
+
public function __construct() {
|
35 |
+
add_action( 'admin_init', array( $this, 'welcome' ) );
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Sends user to the Settings page on first activation of WPSTG as well as each
|
42 |
+
* time WPSTG is upgraded to a new version
|
43 |
+
*
|
44 |
+
* @access public
|
45 |
+
* @since 0.9.0
|
46 |
+
* @global $wpstg_options Array of all the WPSTG Options
|
47 |
+
* @return void
|
48 |
+
*/
|
49 |
+
public function welcome() {
|
50 |
+
global $wpstg_options;
|
51 |
+
|
52 |
+
// Bail if no activation redirect
|
53 |
+
if ( ! get_transient( '_wpstg_activation_redirect' ) )
|
54 |
+
return;
|
55 |
+
|
56 |
+
// Delete the redirect transient
|
57 |
+
delete_transient( '_wpstg_activation_redirect' );
|
58 |
+
|
59 |
+
// Bail if activating from network, or bulk
|
60 |
+
if ( is_network_admin() || isset( $_GET['activate-multi'] ) )
|
61 |
+
return;
|
62 |
+
|
63 |
+
$upgrade = get_option( 'wpstg_version_upgraded_from' );
|
64 |
+
|
65 |
+
//@since 0.9.0
|
66 |
+
if( ! $upgrade ) { // First time install
|
67 |
+
wp_safe_redirect( admin_url( 'admin.php?page=wpstg_clone' ) ); exit;
|
68 |
+
} else { // Update
|
69 |
+
wp_safe_redirect( admin_url( 'admin.php?page=wpstg_clone' ) ); exit;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
}
|
73 |
+
new WPSTG_Welcome();
|
includes/class-wpstg-html-elements.php
ADDED
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* HTML elements
|
4 |
+
*
|
5 |
+
* A helper class for outputting common HTML elements, such as product drop downs
|
6 |
+
*
|
7 |
+
* @package WPSTG
|
8 |
+
* @subpackage Classes/HTML
|
9 |
+
* @copyright Copyright (c) 2015, René Hermenau, Pippin Williamsen
|
10 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
11 |
+
* @since 0.9.0
|
12 |
+
*/
|
13 |
+
|
14 |
+
// Exit if accessed directly
|
15 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* WPSTG_HTML_Elements Class
|
19 |
+
*
|
20 |
+
* @since 1.0
|
21 |
+
*/
|
22 |
+
class WPSTG_HTML_Elements {
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Renders an HTML Dropdown
|
27 |
+
*
|
28 |
+
* @since 0.9.0
|
29 |
+
*
|
30 |
+
* @param array $args
|
31 |
+
*
|
32 |
+
* @return string
|
33 |
+
*/
|
34 |
+
public function select( $args = array() ) {
|
35 |
+
$defaults = array(
|
36 |
+
'options' => array(),
|
37 |
+
'name' => null,
|
38 |
+
'class' => '',
|
39 |
+
'id' => '',
|
40 |
+
'selected' => 0,
|
41 |
+
'chosen' => false,
|
42 |
+
'multiple' => false,
|
43 |
+
'show_option_all' => _x( 'All', 'all dropdown items', 'wpstg' ),
|
44 |
+
'show_option_none' => _x( 'None', 'no dropdown items', 'wpstg' )
|
45 |
+
);
|
46 |
+
|
47 |
+
$args = wp_parse_args( $args, $defaults );
|
48 |
+
|
49 |
+
|
50 |
+
if( $args['multiple'] ) {
|
51 |
+
$multiple = ' MULTIPLE';
|
52 |
+
} else {
|
53 |
+
$multiple = '';
|
54 |
+
}
|
55 |
+
|
56 |
+
if( $args['chosen'] ) {
|
57 |
+
$args['class'] .= ' wpstg-select-chosen';
|
58 |
+
}
|
59 |
+
|
60 |
+
$output = '<select name="' . esc_attr( $args[ 'name' ] ) . '" id="' . esc_attr( sanitize_key( str_replace( '-', '_', $args[ 'id' ] ) ) ) . '" class="wpstg-select ' . esc_attr( $args[ 'class'] ) . '"' . $multiple . '>';
|
61 |
+
|
62 |
+
if ( ! empty( $args[ 'options' ] ) ) {
|
63 |
+
if ( $args[ 'show_option_all' ] ) {
|
64 |
+
if( $args['multiple'] ) {
|
65 |
+
$selected = selected( true, in_array( 0, $args['selected'] ), false );
|
66 |
+
} else {
|
67 |
+
$selected = selected( $args['selected'], 0, false );
|
68 |
+
}
|
69 |
+
$output .= '<option value="all"' . $selected . '>' . esc_html( $args[ 'show_option_all' ] ) . '</option>';
|
70 |
+
}
|
71 |
+
|
72 |
+
if ( $args[ 'show_option_none' ] ) {
|
73 |
+
if( $args['multiple'] ) {
|
74 |
+
$selected = selected( true, in_array( -1, $args['selected'] ), false );
|
75 |
+
} else {
|
76 |
+
$selected = selected( $args['selected'], -1, false );
|
77 |
+
}
|
78 |
+
$output .= '<option value="-1"' . $selected . '>' . esc_html( $args[ 'show_option_none' ] ) . '</option>';
|
79 |
+
}
|
80 |
+
|
81 |
+
foreach( $args[ 'options' ] as $key => $option ) {
|
82 |
+
|
83 |
+
if( $args['multiple'] && is_array( $args['selected'] ) ) {
|
84 |
+
$selected = selected( true, in_array( $key, $args['selected'] ), false );
|
85 |
+
} else {
|
86 |
+
$selected = selected( $args['selected'], $key, false );
|
87 |
+
}
|
88 |
+
|
89 |
+
$output .= '<option value="' . esc_attr( $key ) . '"' . $selected . '>' . esc_html( $option ) . '</option>';
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
$output .= '</select>';
|
94 |
+
|
95 |
+
return $output;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Renders an HTML Checkbox
|
100 |
+
*
|
101 |
+
* @since 1.9
|
102 |
+
*
|
103 |
+
* @param array $args
|
104 |
+
*
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
public function checkbox( $args = array() ) {
|
108 |
+
$defaults = array(
|
109 |
+
'name' => null,
|
110 |
+
'current' => null,
|
111 |
+
'class' => 'wpstg-checkbox'
|
112 |
+
);
|
113 |
+
|
114 |
+
$args = wp_parse_args( $args, $defaults );
|
115 |
+
|
116 |
+
$output = '<input type="checkbox" name="' . esc_attr( $args[ 'name' ] ) . '" id="' . esc_attr( $args[ 'name' ] ) . '" class="' . $args[ 'class' ] . ' ' . esc_attr( $args[ 'name'] ) . '" ' . checked( 1, $args[ 'current' ], false ) . ' />';
|
117 |
+
|
118 |
+
return $output;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Renders an HTML Text field
|
123 |
+
*
|
124 |
+
* @since 1.5.2
|
125 |
+
*
|
126 |
+
* @param string $name Name attribute of the text field
|
127 |
+
* @param string $value The value to prepopulate the field with
|
128 |
+
* @param string $label
|
129 |
+
* @param string $desc
|
130 |
+
* @return string Text field
|
131 |
+
*/
|
132 |
+
public function text( $args = array() ) {
|
133 |
+
// Backwards compatabliity
|
134 |
+
if ( func_num_args() > 1 ) {
|
135 |
+
$args = func_get_args();
|
136 |
+
|
137 |
+
$name = $args[0];
|
138 |
+
$value = isset( $args[1] ) ? $args[1] : '';
|
139 |
+
$label = isset( $args[2] ) ? $args[2] : '';
|
140 |
+
$desc = isset( $args[3] ) ? $args[3] : '';
|
141 |
+
}
|
142 |
+
|
143 |
+
$defaults = array(
|
144 |
+
'name' => isset( $name ) ? $name : 'text',
|
145 |
+
'value' => isset( $value ) ? $value : null,
|
146 |
+
'label' => isset( $label ) ? $label : null,
|
147 |
+
'desc' => isset( $desc ) ? $desc : null,
|
148 |
+
'placeholder' => '',
|
149 |
+
'class' => 'regular-text',
|
150 |
+
'disabled' => false,
|
151 |
+
'autocomplete' => ''
|
152 |
+
);
|
153 |
+
|
154 |
+
$args = wp_parse_args( $args, $defaults );
|
155 |
+
|
156 |
+
$disabled = '';
|
157 |
+
if( $args['disabled'] ) {
|
158 |
+
$disabled = ' disabled="disabled"';
|
159 |
+
}
|
160 |
+
|
161 |
+
$output = '<span id="wpstg-' . sanitize_key( $args[ 'name' ] ) . '-wrap">';
|
162 |
+
|
163 |
+
$output .= '<label class="wpstg-label" for="wpstg-' . sanitize_key( $args[ 'name' ] ) . '">' . esc_html( $args[ 'label' ] ) . '</label>';
|
164 |
+
|
165 |
+
if ( ! empty( $args[ 'desc' ] ) ) {
|
166 |
+
$output .= '<span class="wpstg-description">' . esc_html( $args[ 'desc' ] ) . '</span>';
|
167 |
+
}
|
168 |
+
|
169 |
+
$output .= '<input type="text" name="' . esc_attr( $args[ 'name' ] ) . '" id="' . esc_attr( $args[ 'name' ] ) . '" autocomplete="' . esc_attr( $args[ 'autocomplete' ] ) . '" value="' . esc_attr( $args[ 'value' ] ) . '" placeholder="' . esc_attr( $args[ 'placeholder' ] ) . '" class="' . $args[ 'class' ] . '"' . $disabled . '/>';
|
170 |
+
|
171 |
+
$output .= '</span>';
|
172 |
+
|
173 |
+
return $output;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Renders an HTML textarea
|
178 |
+
*
|
179 |
+
* @since 0.9.0
|
180 |
+
*
|
181 |
+
* @param string $name Name attribute of the textarea
|
182 |
+
* @param string $value The value to prepopulate the field with
|
183 |
+
* @param string $label
|
184 |
+
* @param string $desc
|
185 |
+
* @return string textarea
|
186 |
+
*/
|
187 |
+
public function textarea( $args = array() ) {
|
188 |
+
$defaults = array(
|
189 |
+
'name' => 'textarea',
|
190 |
+
'value' => null,
|
191 |
+
'label' => null,
|
192 |
+
'desc' => null,
|
193 |
+
'class' => 'large-text',
|
194 |
+
'disabled' => false
|
195 |
+
);
|
196 |
+
|
197 |
+
$args = wp_parse_args( $args, $defaults );
|
198 |
+
|
199 |
+
$disabled = '';
|
200 |
+
if( $args['disabled'] ) {
|
201 |
+
$disabled = ' disabled="disabled"';
|
202 |
+
}
|
203 |
+
|
204 |
+
$output = '<span id="wpstg-' . sanitize_key( $args[ 'name' ] ) . '-wrap">';
|
205 |
+
|
206 |
+
$output .= '<label class="wpstg-label" for="wpstg-' . sanitize_key( $args[ 'name' ] ) . '">' . esc_html( $args[ 'label' ] ) . '</label>';
|
207 |
+
|
208 |
+
$output .= '<textarea name="' . esc_attr( $args[ 'name' ] ) . '" id="' . esc_attr( $args[ 'name' ] ) . '" class="' . $args[ 'class' ] . '"' . $disabled . '>' . esc_attr( $args[ 'value' ] ) . '</textarea>';
|
209 |
+
|
210 |
+
if ( ! empty( $args[ 'desc' ] ) ) {
|
211 |
+
$output .= '<span class="wpstg-description">' . esc_html( $args[ 'desc' ] ) . '</span>';
|
212 |
+
}
|
213 |
+
|
214 |
+
$output .= '</span>';
|
215 |
+
|
216 |
+
return $output;
|
217 |
+
}
|
218 |
+
|
219 |
+
}
|
includes/class-wpstg-license-handler.php
ADDED
@@ -0,0 +1,368 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* License handler for WP-Staging Add-Ons
|
4 |
+
*
|
5 |
+
* This class should simplify the process of adding license information
|
6 |
+
* to new WPSTG extensions.
|
7 |
+
*
|
8 |
+
* @version 1.1
|
9 |
+
*/
|
10 |
+
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
12 |
+
|
13 |
+
if ( ! class_exists( 'WPSTG_License' ) ) :
|
14 |
+
|
15 |
+
/**
|
16 |
+
* WPSTG_License Class
|
17 |
+
*/
|
18 |
+
class WPSTG_License {
|
19 |
+
private $file;
|
20 |
+
private $license;
|
21 |
+
private $item_name;
|
22 |
+
private $item_shortname;
|
23 |
+
private $version;
|
24 |
+
private $author;
|
25 |
+
private $api_url = 'https://www.wp-staging.com/edd-sl-api/';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Class constructor
|
29 |
+
*
|
30 |
+
* @global array $wpstg_options
|
31 |
+
* @param string $_file
|
32 |
+
* @param string $_item_name
|
33 |
+
* @param string $_version
|
34 |
+
* @param string $_author
|
35 |
+
* @param string $_optname
|
36 |
+
* @param string $_api_url
|
37 |
+
*/
|
38 |
+
function __construct( $_file, $_item_name, $_version, $_author, $_optname = null, $_api_url = null ) {
|
39 |
+
global $wpstg_options;
|
40 |
+
|
41 |
+
$this->file = $_file;
|
42 |
+
$this->item_name = $_item_name;
|
43 |
+
$this->item_shortname = 'wpstg_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->item_name ) ) );
|
44 |
+
$this->version = $_version;
|
45 |
+
$this->license = isset( $wpstg_options[ $this->item_shortname . '_license_key' ] ) ? trim( $wpstg_options[ $this->item_shortname . '_license_key' ] ) : '';
|
46 |
+
$this->author = $_author;
|
47 |
+
$this->api_url = is_null( $_api_url ) ? $this->api_url : $_api_url;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Allows for backwards compatibility with old license options,
|
51 |
+
* i.e. if the plugins had license key fields previously, the license
|
52 |
+
* handler will automatically pick these up and use those in lieu of the
|
53 |
+
* user having to reactive their license.
|
54 |
+
*/
|
55 |
+
if ( ! empty( $_optname ) ) {
|
56 |
+
$opt = wpstg_get_option( $_optname, false );
|
57 |
+
|
58 |
+
if( isset( $opt ) && empty( $this->license ) ) {
|
59 |
+
$this->license = trim( $opt );
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
// Setup hooks
|
64 |
+
$this->includes();
|
65 |
+
$this->hooks();
|
66 |
+
//$this->auto_updater();
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Include the updater class
|
71 |
+
*
|
72 |
+
* @access private
|
73 |
+
* @return void
|
74 |
+
*/
|
75 |
+
private function includes() {
|
76 |
+
if ( ! class_exists( 'WPSTG_SL_Plugin_Updater' ) ) require_once 'WPSTG_SL_Plugin_Updater.php';
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Setup hooks
|
81 |
+
*
|
82 |
+
* @access private
|
83 |
+
* @return void
|
84 |
+
*/
|
85 |
+
private function hooks() {
|
86 |
+
|
87 |
+
// Register settings
|
88 |
+
add_filter( 'wpstg_settings_licenses', array( $this, 'settings' ), 1 );
|
89 |
+
|
90 |
+
// Activate license key on settings save
|
91 |
+
add_action( 'admin_init', array( $this, 'activate_license' ) );
|
92 |
+
|
93 |
+
// Deactivate license key
|
94 |
+
add_action( 'admin_init', array( $this, 'deactivate_license' ) );
|
95 |
+
|
96 |
+
// Updater
|
97 |
+
add_action( 'admin_init', array( $this, 'auto_updater' ), 0 );
|
98 |
+
|
99 |
+
add_action( 'admin_notices', array( $this, 'notices' ) );
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Auto updater
|
104 |
+
*
|
105 |
+
* @access private
|
106 |
+
* @global array $wpstg_options
|
107 |
+
* @return void
|
108 |
+
*/
|
109 |
+
public function auto_updater() {
|
110 |
+
|
111 |
+
//if ( 'valid' !== get_option( $this->item_shortname . '_license_active' ) )
|
112 |
+
//return;
|
113 |
+
//rhe
|
114 |
+
|
115 |
+
$test = array(
|
116 |
+
'version' => $this->version,
|
117 |
+
'license' => $this->license,
|
118 |
+
'item_name' => $this->item_name,
|
119 |
+
'author' => $this->author
|
120 |
+
);
|
121 |
+
|
122 |
+
|
123 |
+
// Setup the updater
|
124 |
+
$wpstg_updater = new WPSTG_SL_Plugin_Updater(
|
125 |
+
$this->api_url,
|
126 |
+
$this->file,
|
127 |
+
array(
|
128 |
+
'version' => $this->version,
|
129 |
+
'license' => $this->license,
|
130 |
+
'item_name' => $this->item_name,
|
131 |
+
'author' => $this->author
|
132 |
+
)
|
133 |
+
);
|
134 |
+
}
|
135 |
+
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Add license field to settings
|
139 |
+
*
|
140 |
+
* @access public
|
141 |
+
* @param array $settings
|
142 |
+
* @return array
|
143 |
+
*/
|
144 |
+
public function settings( $settings ) {
|
145 |
+
$wpstg_license_settings = array(
|
146 |
+
array(
|
147 |
+
'id' => $this->item_shortname . '_license_key',
|
148 |
+
'name' => sprintf( __( '%1$s License Key', 'wpstg' ), $this->item_name ),
|
149 |
+
'desc' => '',
|
150 |
+
'type' => 'license_key',
|
151 |
+
'options' => array( 'is_valid_license_option' => $this->item_shortname . '_license_active' ),
|
152 |
+
'size' => 'regular'
|
153 |
+
)
|
154 |
+
);
|
155 |
+
|
156 |
+
return array_merge( $settings, $wpstg_license_settings );
|
157 |
+
}
|
158 |
+
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Activate the license key
|
162 |
+
*
|
163 |
+
* @access public
|
164 |
+
* @return void
|
165 |
+
*/
|
166 |
+
public function activate_license() {
|
167 |
+
if ( ! isset( $_POST['wpstg_settings'] ) ) {
|
168 |
+
return;
|
169 |
+
}
|
170 |
+
|
171 |
+
if ( ! isset( $_POST['wpstg_settings'][ $this->item_shortname . '_license_key'] ) ) {
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
|
175 |
+
foreach( $_POST as $key => $value ) {
|
176 |
+
if( false !== strpos( $key, 'license_key_deactivate' ) ) {
|
177 |
+
// Don't activate a key when deactivating a different key
|
178 |
+
return;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
if( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce'], $this->item_shortname . '_license_key-nonce' ) ) {
|
183 |
+
|
184 |
+
wp_die( __( 'Nonce verification failed', 'wpstg' ), __( 'Error', 'wpstg' ), array( 'response' => 403 ) );
|
185 |
+
|
186 |
+
}
|
187 |
+
|
188 |
+
if( ! current_user_can( 'manage_options' ) ) {
|
189 |
+
return;
|
190 |
+
}
|
191 |
+
|
192 |
+
if ( 'valid' === get_option( $this->item_shortname . '_license_active' ) ) {
|
193 |
+
return;
|
194 |
+
}
|
195 |
+
|
196 |
+
$license = sanitize_text_field( $_POST['wpstg_settings'][ $this->item_shortname . '_license_key'] );
|
197 |
+
|
198 |
+
if( empty( $license ) ) {
|
199 |
+
return;
|
200 |
+
}
|
201 |
+
|
202 |
+
// Data to send to the API
|
203 |
+
$api_params = array(
|
204 |
+
'edd_action' => 'activate_license',
|
205 |
+
'license' => $license,
|
206 |
+
'item_name' => urlencode( $this->item_name ),
|
207 |
+
'url' => home_url()
|
208 |
+
);
|
209 |
+
|
210 |
+
// Call the API
|
211 |
+
$response = wp_remote_post(
|
212 |
+
$this->api_url,
|
213 |
+
array(
|
214 |
+
'timeout' => 15,
|
215 |
+
'sslverify' => false,
|
216 |
+
'body' => $api_params
|
217 |
+
)
|
218 |
+
);
|
219 |
+
|
220 |
+
// Make sure there are no errors
|
221 |
+
if ( is_wp_error( $response ) ) {
|
222 |
+
return;
|
223 |
+
}
|
224 |
+
|
225 |
+
// Tell WordPress to look for updates
|
226 |
+
set_site_transient( 'update_plugins', null );
|
227 |
+
|
228 |
+
// Decode license data
|
229 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
230 |
+
|
231 |
+
update_option( $this->item_shortname . '_license_active', $license_data->license );
|
232 |
+
|
233 |
+
if( ! (bool) $license_data->success ) {
|
234 |
+
set_transient( 'wpstg_license_error', $license_data, 1000 );
|
235 |
+
} else {
|
236 |
+
delete_transient( 'wpstg_license_error' );
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Deactivate the license key
|
243 |
+
*
|
244 |
+
* @access public
|
245 |
+
* @return void
|
246 |
+
*/
|
247 |
+
public function deactivate_license() {
|
248 |
+
|
249 |
+
if ( ! isset( $_POST['wpstg_settings'] ) )
|
250 |
+
return;
|
251 |
+
|
252 |
+
if ( ! isset( $_POST['wpstg_settings'][ $this->item_shortname . '_license_key'] ) )
|
253 |
+
return;
|
254 |
+
|
255 |
+
if( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce'], $this->item_shortname . '_license_key-nonce' ) ) {
|
256 |
+
|
257 |
+
wp_die( __( 'Nonce verification failed', 'wpstg' ), __( 'Error', 'wpstg' ), array( 'response' => 403 ) );
|
258 |
+
|
259 |
+
}
|
260 |
+
|
261 |
+
if( ! current_user_can( 'manage_options' ) ) {
|
262 |
+
return;
|
263 |
+
}
|
264 |
+
|
265 |
+
// Run on deactivate button press
|
266 |
+
if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate'] ) ) {
|
267 |
+
|
268 |
+
// Data to send to the API
|
269 |
+
$api_params = array(
|
270 |
+
'edd_action' => 'deactivate_license',
|
271 |
+
'license' => $this->license,
|
272 |
+
'item_name' => urlencode( $this->item_name ),
|
273 |
+
'url' => home_url()
|
274 |
+
);
|
275 |
+
|
276 |
+
// Call the API
|
277 |
+
$response = wp_remote_post(
|
278 |
+
$this->api_url,
|
279 |
+
array(
|
280 |
+
'timeout' => 15,
|
281 |
+
'sslverify' => false,
|
282 |
+
'body' => $api_params
|
283 |
+
)
|
284 |
+
);
|
285 |
+
|
286 |
+
// Make sure there are no errors
|
287 |
+
if ( is_wp_error( $response ) ) {
|
288 |
+
return;
|
289 |
+
}
|
290 |
+
|
291 |
+
// Decode the license data
|
292 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
293 |
+
|
294 |
+
delete_option( $this->item_shortname . '_license_active' );
|
295 |
+
|
296 |
+
if( ! (bool) $license_data->success ) {
|
297 |
+
set_transient( 'wpstg_license_error', $license_data, 1000 );
|
298 |
+
} else {
|
299 |
+
delete_transient( 'wpstg_license_error' );
|
300 |
+
}
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Admin notices for errors
|
307 |
+
*
|
308 |
+
* @access public
|
309 |
+
* @return void
|
310 |
+
*/
|
311 |
+
public function notices() {
|
312 |
+
|
313 |
+
if( ! isset( $_GET['page'] ) || 'wpstg-settings' !== $_GET['page'] ) {
|
314 |
+
return;
|
315 |
+
}
|
316 |
+
|
317 |
+
if( ! isset( $_GET['tab'] ) || 'licenses' !== $_GET['tab'] ) {
|
318 |
+
return;
|
319 |
+
}
|
320 |
+
|
321 |
+
$license_error = get_transient( 'wpstg_license_error' );
|
322 |
+
|
323 |
+
if( false === $license_error ) {
|
324 |
+
return;
|
325 |
+
}
|
326 |
+
|
327 |
+
if( ! empty( $license_error->error ) ) {
|
328 |
+
|
329 |
+
switch( $license_error->error ) {
|
330 |
+
|
331 |
+
case 'item_name_mismatch' :
|
332 |
+
|
333 |
+
$message = __( 'This license does not belong to the product you have entered it for.', 'wpstg' );
|
334 |
+
break;
|
335 |
+
|
336 |
+
case 'no_activations_left' :
|
337 |
+
|
338 |
+
$message = __( 'This license does not have any activations left', 'wpstg' );
|
339 |
+
break;
|
340 |
+
|
341 |
+
case 'expired' :
|
342 |
+
|
343 |
+
$message = __( 'This license key is expired. Please renew it.', 'wpstg' );
|
344 |
+
break;
|
345 |
+
|
346 |
+
default :
|
347 |
+
|
348 |
+
$message = sprintf( __( 'There was a problem activating your license key, please try again or contact support. Error code: %s', 'wpstg' ), $license_error->error );
|
349 |
+
break;
|
350 |
+
|
351 |
+
}
|
352 |
+
|
353 |
+
}
|
354 |
+
|
355 |
+
if( ! empty( $message ) ) {
|
356 |
+
|
357 |
+
echo '<div class="error">';
|
358 |
+
echo '<p>' . $message . '</p>';
|
359 |
+
echo '</div>';
|
360 |
+
|
361 |
+
}
|
362 |
+
|
363 |
+
delete_transient( 'wpstg_license_error' );
|
364 |
+
|
365 |
+
}
|
366 |
+
}
|
367 |
+
|
368 |
+
endif; // end class_exists check
|
includes/debug/browsers/WPChromePHP.class.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class WPChromePHP implements iMashDebug {
|
3 |
+
|
4 |
+
public function __construct() {
|
5 |
+
include 'api/chromephp/ChromePhp.php';
|
6 |
+
$this->api = ChromePhp::getInstance();
|
7 |
+
}
|
8 |
+
|
9 |
+
|
10 |
+
public function log( $var, $label = null ) {
|
11 |
+
$this->api->log( $label, $var );
|
12 |
+
}
|
13 |
+
|
14 |
+
public function info( $var, $label = null ) {
|
15 |
+
$this->api->info( $label, $var );
|
16 |
+
}
|
17 |
+
|
18 |
+
public function warn( $var, $label = null ) {
|
19 |
+
$this->api->warn( $label, $var );
|
20 |
+
}
|
21 |
+
|
22 |
+
public function error( $var, $label = null ) {
|
23 |
+
$this->api->error( $label, $var );
|
24 |
+
}
|
25 |
+
}
|
includes/debug/browsers/WPFirePHP.class.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class WPFirePHP implements iMashDebug {
|
3 |
+
|
4 |
+
private $api;
|
5 |
+
|
6 |
+
public function __construct() {
|
7 |
+
include 'api/firephp/lib/FirePHPCore/FirePHP.class.php';
|
8 |
+
$this->api = FirePHP::getInstance( true );
|
9 |
+
}
|
10 |
+
|
11 |
+
public function log( $var, $label = null ) {
|
12 |
+
$this->api->log( $var, $label );
|
13 |
+
}
|
14 |
+
|
15 |
+
public function info( $var, $label = null ) {
|
16 |
+
$this->api->info( $var, $label );
|
17 |
+
}
|
18 |
+
|
19 |
+
public function warn( $var, $label = null ) {
|
20 |
+
$this->api->warn( $var, $label );
|
21 |
+
}
|
22 |
+
|
23 |
+
public function error( $var, $label = null ) {
|
24 |
+
$this->api->error( $var, $label );
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
}
|
includes/debug/browsers/api/chromephp/ChromePhp.php
ADDED
@@ -0,0 +1,440 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright 2012 Craig Campbell
|
4 |
+
*
|
5 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6 |
+
* you may not use this file except in compliance with the License.
|
7 |
+
* You may obtain a copy of the License at
|
8 |
+
*
|
9 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10 |
+
*
|
11 |
+
* Unless required by applicable law or agreed to in writing, software
|
12 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 |
+
* See the License for the specific language governing permissions and
|
15 |
+
* limitations under the License.
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Server Side Chrome PHP debugger class
|
20 |
+
*
|
21 |
+
* @package ChromePhp
|
22 |
+
* @author Craig Campbell <iamcraigcampbell@gmail.com>
|
23 |
+
*/
|
24 |
+
class ChromePhp
|
25 |
+
{
|
26 |
+
/**
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
const VERSION = '3.0';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
const HEADER_NAME = 'X-ChromePhp-Data';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
const BACKTRACE_LEVEL = 'backtrace_level';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
const LOG = 'log';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
const WARN = 'warn';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
const ERROR = 'error';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
const GROUP = 'group';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @var string
|
63 |
+
*/
|
64 |
+
const INFO = 'info';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
const GROUP_END = 'groupEnd';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @var string
|
73 |
+
*/
|
74 |
+
const GROUP_COLLAPSED = 'groupCollapsed';
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @var string
|
78 |
+
*/
|
79 |
+
protected $_php_version;
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @var int
|
83 |
+
*/
|
84 |
+
protected $_timestamp;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @var array
|
88 |
+
*/
|
89 |
+
protected $_json = array(
|
90 |
+
'version' => self::VERSION,
|
91 |
+
'columns' => array('label', 'log', 'backtrace', 'type'),
|
92 |
+
'rows' => array()
|
93 |
+
);
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @var array
|
97 |
+
*/
|
98 |
+
protected $_backtraces = array();
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @var bool
|
102 |
+
*/
|
103 |
+
protected $_error_triggered = false;
|
104 |
+
|
105 |
+
/**
|
106 |
+
* @var array
|
107 |
+
*/
|
108 |
+
protected $_settings = array(
|
109 |
+
self::BACKTRACE_LEVEL => 1
|
110 |
+
);
|
111 |
+
|
112 |
+
/**
|
113 |
+
* @var ChromePhp
|
114 |
+
*/
|
115 |
+
protected static $_instance;
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Prevent recursion when working with objects referring to each other
|
119 |
+
*
|
120 |
+
* @var array
|
121 |
+
*/
|
122 |
+
protected $_processed = array();
|
123 |
+
|
124 |
+
/**
|
125 |
+
* constructor
|
126 |
+
*/
|
127 |
+
private function __construct()
|
128 |
+
{
|
129 |
+
$this->_php_version = phpversion();
|
130 |
+
$this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time();
|
131 |
+
$this->_json['request_uri'] = $_SERVER['REQUEST_URI'];
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* gets instance of this class
|
136 |
+
*
|
137 |
+
* @return ChromePhp
|
138 |
+
*/
|
139 |
+
public static function getInstance()
|
140 |
+
{
|
141 |
+
if (self::$_instance === null) {
|
142 |
+
self::$_instance = new ChromePhp();
|
143 |
+
}
|
144 |
+
return self::$_instance;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* logs a variable to the console
|
149 |
+
*
|
150 |
+
* @param string label
|
151 |
+
* @param mixed value
|
152 |
+
* @param string severity ChromePhp::LOG || ChromePhp::WARN || ChromePhp::ERROR
|
153 |
+
* @return void
|
154 |
+
*/
|
155 |
+
public static function log()
|
156 |
+
{
|
157 |
+
$args = func_get_args();
|
158 |
+
$severity = count($args) == 3 ? array_pop($args) : '';
|
159 |
+
|
160 |
+
// save precious bytes
|
161 |
+
if ($severity == self::LOG) {
|
162 |
+
$severity = '';
|
163 |
+
}
|
164 |
+
|
165 |
+
return self::_log($args + array('type' => $severity));
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* logs a warning to the console
|
170 |
+
*
|
171 |
+
* @param string label
|
172 |
+
* @param mixed value
|
173 |
+
* @return void
|
174 |
+
*/
|
175 |
+
public static function warn()
|
176 |
+
{
|
177 |
+
return self::_log(func_get_args() + array('type' => self::WARN));
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* logs an error to the console
|
182 |
+
*
|
183 |
+
* @param string label
|
184 |
+
* @param mixed value
|
185 |
+
* @return void
|
186 |
+
*/
|
187 |
+
public static function error()
|
188 |
+
{
|
189 |
+
return self::_log(func_get_args() + array('type' => self::ERROR));
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* sends a group log
|
194 |
+
*
|
195 |
+
* @param string value
|
196 |
+
*/
|
197 |
+
public static function group()
|
198 |
+
{
|
199 |
+
return self::_log(func_get_args() + array('type' => self::GROUP));
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* sends an info log
|
204 |
+
*
|
205 |
+
* @param string value
|
206 |
+
*/
|
207 |
+
public static function info()
|
208 |
+
{
|
209 |
+
return self::_log(func_get_args() + array('type' => self::INFO));
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* sends a collapsed group log
|
214 |
+
*
|
215 |
+
* @param string value
|
216 |
+
*/
|
217 |
+
public static function groupCollapsed()
|
218 |
+
{
|
219 |
+
return self::_log(func_get_args() + array('type' => self::GROUP_COLLAPSED));
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* ends a group log
|
224 |
+
*
|
225 |
+
* @param string value
|
226 |
+
*/
|
227 |
+
public static function groupEnd()
|
228 |
+
{
|
229 |
+
return self::_log(func_get_args() + array('type' => self::GROUP_END));
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* internal logging call
|
234 |
+
*
|
235 |
+
* @param string $type
|
236 |
+
* @return void
|
237 |
+
*/
|
238 |
+
protected static function _log(array $args)
|
239 |
+
{
|
240 |
+
$type = $args['type'];
|
241 |
+
unset($args['type']);
|
242 |
+
|
243 |
+
// nothing passed in, don't do anything
|
244 |
+
if (count($args) == 0 && $type != self::GROUP_END) {
|
245 |
+
return;
|
246 |
+
}
|
247 |
+
|
248 |
+
// default to single
|
249 |
+
$label = null;
|
250 |
+
$value = isset($args[0]) ? $args[0] : '';
|
251 |
+
|
252 |
+
$logger = self::getInstance();
|
253 |
+
|
254 |
+
// if there are two values passed in then the first one is the label
|
255 |
+
if (count($args) == 2) {
|
256 |
+
$label = $args[0];
|
257 |
+
$value = $args[1];
|
258 |
+
}
|
259 |
+
|
260 |
+
$logger->_processed = array();
|
261 |
+
$value = $logger->_convert($value);
|
262 |
+
|
263 |
+
$backtrace = debug_backtrace(false);
|
264 |
+
$level = $logger->getSetting(self::BACKTRACE_LEVEL);
|
265 |
+
|
266 |
+
$backtrace_message = 'unknown';
|
267 |
+
if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) {
|
268 |
+
$backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line'];
|
269 |
+
}
|
270 |
+
|
271 |
+
$logger->_addRow($label, $value, $backtrace_message, $type);
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* converts an object to a better format for logging
|
276 |
+
*
|
277 |
+
* @param Object
|
278 |
+
* @return array
|
279 |
+
*/
|
280 |
+
protected function _convert($object)
|
281 |
+
{
|
282 |
+
// if this isn't an object then just return it
|
283 |
+
if (!is_object($object)) {
|
284 |
+
return $object;
|
285 |
+
}
|
286 |
+
|
287 |
+
//Mark this object as processed so we don't convert it twice and it
|
288 |
+
//Also avoid recursion when objects refer to each other
|
289 |
+
$this->_processed[] = $object;
|
290 |
+
|
291 |
+
$object_as_array = array();
|
292 |
+
|
293 |
+
// first add the class name
|
294 |
+
$object_as_array['___class_name'] = get_class($object);
|
295 |
+
|
296 |
+
// loop through object vars
|
297 |
+
$object_vars = get_object_vars($object);
|
298 |
+
foreach ($object_vars as $key => $value) {
|
299 |
+
|
300 |
+
// same instance as parent object
|
301 |
+
if ($value === $object || in_array($value, $this->_processed, true)) {
|
302 |
+
$value = 'recursion - parent object [' . get_class($value) . ']';
|
303 |
+
}
|
304 |
+
$object_as_array[$key] = $this->_convert($value);
|
305 |
+
}
|
306 |
+
|
307 |
+
$reflection = new ReflectionClass($object);
|
308 |
+
|
309 |
+
// loop through the properties and add those
|
310 |
+
foreach ($reflection->getProperties() as $property) {
|
311 |
+
|
312 |
+
// if one of these properties was already added above then ignore it
|
313 |
+
if (array_key_exists($property->getName(), $object_vars)) {
|
314 |
+
continue;
|
315 |
+
}
|
316 |
+
$type = $this->_getPropertyKey($property);
|
317 |
+
|
318 |
+
if ($this->_php_version >= 5.3) {
|
319 |
+
$property->setAccessible(true);
|
320 |
+
}
|
321 |
+
|
322 |
+
try {
|
323 |
+
$value = $property->getValue($object);
|
324 |
+
} catch (ReflectionException $e) {
|
325 |
+
$value = 'only PHP 5.3 can access private/protected properties';
|
326 |
+
}
|
327 |
+
|
328 |
+
// same instance as parent object
|
329 |
+
if ($value === $object || in_array($value, $this->_processed, true)) {
|
330 |
+
$value = 'recursion - parent object [' . get_class($value) . ']';
|
331 |
+
}
|
332 |
+
|
333 |
+
$object_as_array[$type] = $this->_convert($value);
|
334 |
+
}
|
335 |
+
return $object_as_array;
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* takes a reflection property and returns a nicely formatted key of the property name
|
340 |
+
*
|
341 |
+
* @param ReflectionProperty
|
342 |
+
* @return string
|
343 |
+
*/
|
344 |
+
protected function _getPropertyKey(ReflectionProperty $property)
|
345 |
+
{
|
346 |
+
$static = $property->isStatic() ? ' static' : '';
|
347 |
+
if ($property->isPublic()) {
|
348 |
+
return 'public' . $static . ' ' . $property->getName();
|
349 |
+
}
|
350 |
+
|
351 |
+
if ($property->isProtected()) {
|
352 |
+
return 'protected' . $static . ' ' . $property->getName();
|
353 |
+
}
|
354 |
+
|
355 |
+
if ($property->isPrivate()) {
|
356 |
+
return 'private' . $static . ' ' . $property->getName();
|
357 |
+
}
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* adds a value to the data array
|
362 |
+
*
|
363 |
+
* @var mixed
|
364 |
+
* @return void
|
365 |
+
*/
|
366 |
+
protected function _addRow($label, $log, $backtrace, $type)
|
367 |
+
{
|
368 |
+
// if this is logged on the same line for example in a loop, set it to null to save space
|
369 |
+
if (in_array($backtrace, $this->_backtraces)) {
|
370 |
+
$backtrace = null;
|
371 |
+
}
|
372 |
+
|
373 |
+
if ($backtrace !== null) {
|
374 |
+
$this->_backtraces[] = $backtrace;
|
375 |
+
}
|
376 |
+
|
377 |
+
$row = array($label, $log, $backtrace, $type);
|
378 |
+
|
379 |
+
$this->_json['rows'][] = $row;
|
380 |
+
$this->_writeHeader($this->_json);
|
381 |
+
}
|
382 |
+
|
383 |
+
protected function _writeHeader($data)
|
384 |
+
{
|
385 |
+
//ob_start();
|
386 |
+
@header(self::HEADER_NAME . ': ' . $this->_encode($data));
|
387 |
+
//echo self::HEADER_NAME . ': ' . $this->_encode($data);
|
388 |
+
//ob_end_clean();
|
389 |
+
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* encodes the data to be sent along with the request
|
393 |
+
*
|
394 |
+
* @param array $data
|
395 |
+
* @return string
|
396 |
+
*/
|
397 |
+
protected function _encode($data)
|
398 |
+
{
|
399 |
+
return base64_encode(utf8_encode(json_encode($data)));
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* adds a setting
|
404 |
+
*
|
405 |
+
* @param string key
|
406 |
+
* @param mixed value
|
407 |
+
* @return void
|
408 |
+
*/
|
409 |
+
public function addSetting($key, $value)
|
410 |
+
{
|
411 |
+
$this->_settings[$key] = $value;
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* add ability to set multiple settings in one call
|
416 |
+
*
|
417 |
+
* @param array $settings
|
418 |
+
* @return void
|
419 |
+
*/
|
420 |
+
public function addSettings(array $settings)
|
421 |
+
{
|
422 |
+
foreach ($settings as $key => $value) {
|
423 |
+
$this->addSetting($key, $value);
|
424 |
+
}
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* gets a setting
|
429 |
+
*
|
430 |
+
* @param string key
|
431 |
+
* @return mixed
|
432 |
+
*/
|
433 |
+
public function getSetting($key)
|
434 |
+
{
|
435 |
+
if (!isset($this->_settings[$key])) {
|
436 |
+
return null;
|
437 |
+
}
|
438 |
+
return $this->_settings[$key];
|
439 |
+
}
|
440 |
+
}
|
includes/debug/browsers/api/chromephp/README
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version 3.0
|
2 |
+
This class requires PHP 5 or later.
|
3 |
+
|
4 |
+
ChromePhp is a PHP class to go along with the ChromePhp Google Chrome extension.
|
5 |
+
|
6 |
+
This class allows you to log variables to the Chrome console.
|
7 |
+
|
8 |
+
INSTALLATION
|
9 |
+
1. Download the Chrome extension from: https://chrome.google.com/extensions/detail/noaneddfkdjfnfdakjjmocngnfkfehhd
|
10 |
+
2. Put ChromePhp.php somewhere in your PHP include path
|
11 |
+
3. Click the extension icon on the browser to enable it for the current site
|
12 |
+
3. include 'ChromePhp.php';
|
13 |
+
4. ChromePhp::log('hello world');
|
14 |
+
|
15 |
+
More information can be found here:
|
16 |
+
http://www.chromephp.com
|
includes/debug/browsers/api/firephp/CHANGELOG.md
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
TODO:
|
3 |
+
|
4 |
+
* Fix code indenting in PHP 4 code
|
5 |
+
* Port maxDepth option to PHP 4 code
|
6 |
+
|
7 |
+
2011-06-22 - Release Version: 0.4.0rc3
|
8 |
+
|
9 |
+
* Build fixes
|
10 |
+
|
11 |
+
2011-06-20 - Release Version: 0.4.0rc1
|
12 |
+
|
13 |
+
* (Issue 163) PHP5 class_exists() throws Exception without second parameter
|
14 |
+
* (Issue 166) Non-utf8 array values replaced with null
|
15 |
+
* Cleaned up code formatting [sokolov.innokenty@gmail.com]
|
16 |
+
* Ensure JSON keys are never NULL (due to NULL key in some arrays)
|
17 |
+
* Better UTF-8 encoding detection
|
18 |
+
* Code style cleanup (qbbr)
|
19 |
+
* Changed license to MIT
|
20 |
+
* Refactored project
|
21 |
+
|
22 |
+
2010-10-26 - Release Version: 0.3.2
|
23 |
+
|
24 |
+
2010-10-12 - Release Version: 0.3.2rc6
|
25 |
+
|
26 |
+
* (Issue 154) getRequestHeader uses "getallheaders" even though it doesn't always exist. [25m]
|
27 |
+
|
28 |
+
2010-10-09 - Release Version: 0.3.2rc5
|
29 |
+
|
30 |
+
* (Issue 153) FirePHP incorrectly double-encodes UTF8 when mbstring.func_overload is enabled
|
31 |
+
|
32 |
+
2010-10-08 - Release Version: 0.3.2rc4
|
33 |
+
|
34 |
+
* Trigger upgrade message if part of FirePHP 1.0
|
35 |
+
* Removed FirePHP/Init.php inclusion logic and only load FirePHP.class.php if not already loaded
|
36 |
+
|
37 |
+
2010-07-19 - Release Version: 0.3.2rc3
|
38 |
+
|
39 |
+
* Fixed FirePHP/Init.php inclusion logic
|
40 |
+
|
41 |
+
2010-07-19 - Release Version: 0.3.2rc2
|
42 |
+
|
43 |
+
* (Issue 145) maxDepth option
|
44 |
+
* Changed maxObjectDepth and maxArrayDepth option defaults to 5
|
45 |
+
* Fixed code indentation
|
46 |
+
|
47 |
+
2010-03-05 - Release Version: 0.3.2rc1
|
48 |
+
|
49 |
+
* (Issue 114) Allow options to be passed on to basic logging wrappers
|
50 |
+
* (Issue 122) Filter objectStack property of FirePHP class
|
51 |
+
* (Issue 123) registerErrorHandler(false) by default
|
52 |
+
* Added setOption() and getOption() methods
|
53 |
+
* (Issue 117) dump() method argument validation
|
54 |
+
* Started adding PHPUnit tests
|
55 |
+
* Some refactoring to support unit testing
|
56 |
+
* Deprecated setProcessorUrl() and setRendererUrl()
|
57 |
+
* Check User-Agent and X-FirePHP-Version header to detect FirePHP on client
|
58 |
+
* (Issue 135) FirePHP 0.4.3 with Firebug 1.5 changes user agent on the fly
|
59 |
+
* (Issue 112) Error Predefined Constants Not available for PHP 5.x versions
|
60 |
+
|
61 |
+
2008-06-14 - Release Version: 0.3.1
|
62 |
+
|
63 |
+
* (Issue 108) ignore class name case in object filter
|
64 |
+
|
65 |
+
2009-05-11 - Release Version: 0.3
|
66 |
+
2009-05-01 - Release Version: 0.3.rc.1
|
67 |
+
|
68 |
+
* (Issue 90) PHP4 compatible version of FirePHPCore
|
69 |
+
* (Issue 98) Thrown exceptions don't send an HTTP 500 if the FirePHP exception handler is enabled
|
70 |
+
* (Issue 85) Support associative arrays in encodeTable method in FirePHP.class.php
|
71 |
+
* (Issue 66) Add a new getOptions() public method in API
|
72 |
+
* (Issue 82) Define $this->options outside of __construct
|
73 |
+
* (Issue 72) Message error if group name is null
|
74 |
+
* (Issue 68) registerErrorHandler() and registerExceptionHandler() should returns previous handlers defined
|
75 |
+
* (Issue 69) Add the missing register handler in the triumvirate (error, exception, assert)
|
76 |
+
* (Issue 75) [Error & Exception Handling] Option to not exit script execution
|
77 |
+
* (Issue 83) Exception handler can't throw exceptions
|
78 |
+
* (Issue 80) Auto/Pre collapsing groups AND Custom group row colors
|
79 |
+
|
80 |
+
2008-11-09 - Release Version: 0.2.1
|
81 |
+
|
82 |
+
* (Issue 70) Problem when logging resources
|
83 |
+
|
84 |
+
2008-10-21 - Release Version: 0.2.0
|
85 |
+
|
86 |
+
* Updated version to 0.2.0
|
87 |
+
* Switched to using __sleep instead of __wakeup
|
88 |
+
* Added support to exclude object members when encoding
|
89 |
+
* Add support to enable/disable logging
|
90 |
+
|
91 |
+
2008-10-17 - Release Version: 0.2.b.8
|
92 |
+
|
93 |
+
* New implementation for is_utf8()
|
94 |
+
* (Issue 55) maxObjectDepth Option not working correctly when using TABLE and EXCEPTION Type
|
95 |
+
* Bugfix for max[Object|Array]Depth when encoding nested array/object graphs
|
96 |
+
* Bugfix for FB::setOptions()
|
97 |
+
|
98 |
+
2008-10-16 - Release Version: 0.2.b.7
|
99 |
+
|
100 |
+
* (Issue 45) Truncate dump when string have non utf8 cars
|
101 |
+
* (Issue 52) logging will not work when firephp object gets stored in the session.
|
102 |
+
|
103 |
+
2008-10-16 - Release Version: 0.2.b.6
|
104 |
+
|
105 |
+
* (Issue 37) Display file and line information for each log message
|
106 |
+
* (Issue 51) Limit output of object graphs
|
107 |
+
* Bugfix for encoding object members set to NULL|false|''
|
108 |
+
|
109 |
+
2008-10-14 - Release Version: 0.2.b.5
|
110 |
+
|
111 |
+
* Updated JsonStream wildfire protocol to be more robust
|
112 |
+
* (Issue 33) PHP error notices running demos
|
113 |
+
* (Issue 48) Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given
|
114 |
+
|
115 |
+
2008-10-08 - Release Version: 0.2.b.4
|
116 |
+
|
117 |
+
* Bugfix for logging objects with recursion
|
118 |
+
|
119 |
+
2008-10-08 - Release Version: 0.2.b.3
|
120 |
+
|
121 |
+
* (Issue 43) Notice message in 0.2b2
|
122 |
+
* Added support for PHP's native json_encode() if available
|
123 |
+
* Revised object encoder to detect object recursion
|
124 |
+
|
125 |
+
2008-10-07 - Release Version: 0.2.b.2
|
126 |
+
|
127 |
+
* (Issue 28) Need solution for logging private and protected object variables
|
128 |
+
* Added trace() and table() aliases in FirePHP class
|
129 |
+
* (Issue 41) Use PHP doc in FirePHP
|
130 |
+
* (Issue 39) Static logging method for object oriented API
|
131 |
+
|
132 |
+
2008-10-01 - Release Version: 0.2.b.1
|
133 |
+
|
134 |
+
* Added support for error and exception handling
|
135 |
+
* Updated min PHP version for PEAR package to 5.2
|
136 |
+
* Added version constant for library
|
137 |
+
* Gave server library it's own wildfire plugin namespace
|
138 |
+
* Migrated communication protocol to Wildfire JsonStream
|
139 |
+
* Added support for console groups using "group" and "groupEnd"
|
140 |
+
* Added support for log, info, warn and error logging aliases
|
141 |
+
* (Issue 29) problem with TRACE when using with error_handler
|
142 |
+
* (Issue 33) PHP error notices running demos
|
143 |
+
* (Issue 12) undefined index php notice
|
144 |
+
* Removed closing ?> php tags
|
145 |
+
* (Issue 13) the code in the fb() function has a second return statement that will never be reached
|
146 |
+
|
147 |
+
2008-07-30 - Release Version: 0.1.1.3
|
148 |
+
|
149 |
+
* Include __className property in JSON string if variable was an object
|
150 |
+
* Bugfix - Mis-spelt "Exception" in JSON encoding code
|
151 |
+
|
152 |
+
2008-06-13 - Release Version: 0.1.1.1
|
153 |
+
|
154 |
+
* Bugfix - Standardize windows paths in stack traces
|
155 |
+
* Bugfix - Display correct stack trace info in windows environments
|
156 |
+
* Bugfix - Check $_SERVER['HTTP_USER_AGENT'] before returning
|
157 |
+
|
158 |
+
2008-06-13 - Release Version: 0.1.1
|
159 |
+
|
160 |
+
* Added support for FirePHP::TRACE log style
|
161 |
+
* Changed license to New BSD License
|
162 |
+
|
163 |
+
2008-06-06 - Release Version: 0.0.2
|
164 |
+
|
165 |
+
* Bugfix - Added usleep() to header writing loop to ensure unique index
|
166 |
+
* Bugfix - Ensure chunk_split does not generate trailing "\n" with empty data header
|
167 |
+
* Added support for FirePHP::TABLE log style
|
includes/debug/browsers/api/firephp/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FirePHPCore
|
2 |
+
===========
|
3 |
+
|
4 |
+
**Status: stable**
|
5 |
+
|
6 |
+
> **FirePHP is an advanced logging system that can display PHP variables in the browser as an application is navigated.**
|
7 |
+
> All communication is out of band to the application meaning that the logging data will not interfere with the normal functioning of the application.
|
8 |
+
|
9 |
+
This project contains the *FirePHPCore* PHP server library and provides a development environment (see `./workspace/`) for working on *FirePHPCore*.
|
10 |
+
|
11 |
+
|
12 |
+
Usage
|
13 |
+
=====
|
14 |
+
|
15 |
+
See [Install/Traditional: FirePHPCore](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/Configuration/Traditional) in the
|
16 |
+
[FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/).
|
17 |
+
|
18 |
+
|
19 |
+
Testing
|
20 |
+
=======
|
21 |
+
|
22 |
+
cd tests
|
23 |
+
phpunit .
|
24 |
+
|
25 |
+
|
26 |
+
Support & Feedback
|
27 |
+
==================
|
28 |
+
|
29 |
+
See [Support](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#support) in the [FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/).
|
30 |
+
|
31 |
+
|
32 |
+
Contribute
|
33 |
+
==========
|
34 |
+
|
35 |
+
See [Contribute](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#contribute) in the [FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/).
|
36 |
+
|
37 |
+
|
38 |
+
Author
|
39 |
+
======
|
40 |
+
|
41 |
+
This project is authored and maintained by [Christoph Dorn](http://www.christophdorn.com/).
|
42 |
+
|
43 |
+
|
44 |
+
Documentation License
|
45 |
+
=====================
|
46 |
+
|
47 |
+
[Creative Commons Attribution-NonCommercial-ShareAlike 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/)
|
48 |
+
|
49 |
+
Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
50 |
+
|
51 |
+
|
52 |
+
Code License
|
53 |
+
============
|
54 |
+
|
55 |
+
[MIT License](http://www.opensource.org/licenses/mit-license.php)
|
56 |
+
|
57 |
+
Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
58 |
+
|
59 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
60 |
+
of this software and associated documentation files (the "Software"), to deal
|
61 |
+
in the Software without restriction, including without limitation the rights
|
62 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
63 |
+
copies of the Software, and to permit persons to whom the Software is
|
64 |
+
furnished to do so, subject to the following conditions:
|
65 |
+
|
66 |
+
The above copyright notice and this permission notice shall be included in
|
67 |
+
all copies or substantial portions of the Software.
|
68 |
+
|
69 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
70 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
71 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
72 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
73 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
74 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
75 |
+
THE SOFTWARE.
|
includes/debug/browsers/api/firephp/examples/oo.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
5 |
+
|
6 |
+
/* *** BEGIN LICENSE BLOCK *****
|
7 |
+
*
|
8 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
9 |
+
*
|
10 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
11 |
+
*
|
12 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 |
+
* of this software and associated documentation files (the "Software"), to deal
|
14 |
+
* in the Software without restriction, including without limitation the rights
|
15 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16 |
+
* copies of the Software, and to permit persons to whom the Software is
|
17 |
+
* furnished to do so, subject to the following conditions:
|
18 |
+
*
|
19 |
+
* The above copyright notice and this permission notice shall be included in
|
20 |
+
* all copies or substantial portions of the Software.
|
21 |
+
*
|
22 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
28 |
+
* THE SOFTWARE.
|
29 |
+
*
|
30 |
+
* ***** END LICENSE BLOCK ***** */
|
31 |
+
|
32 |
+
|
33 |
+
/* NOTE: You must have the FirePHPCore library in your include path */
|
34 |
+
|
35 |
+
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
36 |
+
|
37 |
+
|
38 |
+
require('FirePHPCore/FirePHP.class.php');
|
39 |
+
|
40 |
+
/* NOTE: You must have Output Buffering enabled via
|
41 |
+
ob_start() or output_buffering ini directive. */
|
42 |
+
|
43 |
+
|
44 |
+
$firephp = FirePHP::getInstance(true);
|
45 |
+
|
46 |
+
|
47 |
+
$firephp->fb('Hello World'); /* Defaults to FirePHP::LOG */
|
48 |
+
|
49 |
+
$firephp->fb('Log message' ,FirePHP::LOG);
|
50 |
+
$firephp->fb('Info message' ,FirePHP::INFO);
|
51 |
+
$firephp->fb('Warn message' ,FirePHP::WARN);
|
52 |
+
$firephp->fb('Error message',FirePHP::ERROR);
|
53 |
+
|
54 |
+
$firephp->fb('Message with label','Label',FirePHP::LOG);
|
55 |
+
|
56 |
+
$firephp->fb(array('key1'=>'val1',
|
57 |
+
'key2'=>array(array('v1','v2'),'v3')),
|
58 |
+
'TestArray',FirePHP::LOG);
|
59 |
+
|
60 |
+
function test($Arg1) {
|
61 |
+
throw new Exception('Test Exception');
|
62 |
+
}
|
63 |
+
try {
|
64 |
+
test(array('Hello'=>'World'));
|
65 |
+
} catch(Exception $e) {
|
66 |
+
/* Log exception including stack trace & variables */
|
67 |
+
$firephp->fb($e);
|
68 |
+
}
|
69 |
+
|
70 |
+
$firephp->fb('Backtrace to here',FirePHP::TRACE);
|
71 |
+
|
72 |
+
$firephp->fb(array('2 SQL queries took 0.06 seconds',array(
|
73 |
+
array('SQL Statement','Time','Result'),
|
74 |
+
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
75 |
+
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
76 |
+
)),FirePHP::TABLE);
|
77 |
+
|
78 |
+
/* Will show only in "Server" tab for the request */
|
79 |
+
$firephp->fb(apache_request_headers(),'RequestHeaders',FirePHP::DUMP);
|
80 |
+
|
81 |
+
|
82 |
+
print 'Hello World';
|
includes/debug/browsers/api/firephp/examples/oo.php4
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
5 |
+
|
6 |
+
/* *** BEGIN LICENSE BLOCK *****
|
7 |
+
*
|
8 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
9 |
+
*
|
10 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
11 |
+
*
|
12 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 |
+
* of this software and associated documentation files (the "Software"), to deal
|
14 |
+
* in the Software without restriction, including without limitation the rights
|
15 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16 |
+
* copies of the Software, and to permit persons to whom the Software is
|
17 |
+
* furnished to do so, subject to the following conditions:
|
18 |
+
*
|
19 |
+
* The above copyright notice and this permission notice shall be included in
|
20 |
+
* all copies or substantial portions of the Software.
|
21 |
+
*
|
22 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
28 |
+
* THE SOFTWARE.
|
29 |
+
*
|
30 |
+
* ***** END LICENSE BLOCK ***** */
|
31 |
+
|
32 |
+
|
33 |
+
/* NOTE: You must have the FirePHPCore library in your include path */
|
34 |
+
|
35 |
+
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
36 |
+
|
37 |
+
|
38 |
+
require('FirePHPCore/FirePHP.class.php4');
|
39 |
+
|
40 |
+
/* NOTE: You must have Output Buffering enabled via
|
41 |
+
ob_start() or output_buffering ini directive. */
|
42 |
+
|
43 |
+
|
44 |
+
$firephp =& FirePHP::getInstance(true);
|
45 |
+
|
46 |
+
|
47 |
+
$firephp->fb('Hello World'); /* Defaults to FirePHP::LOG */
|
48 |
+
|
49 |
+
$firephp->fb('Log message' ,FirePHP_LOG);
|
50 |
+
$firephp->fb('Info message' ,FirePHP_INFO);
|
51 |
+
$firephp->fb('Warn message' ,FirePHP_WARN);
|
52 |
+
$firephp->fb('Error message',FirePHP_ERROR);
|
53 |
+
|
54 |
+
$firephp->fb('Message with label','Label',FirePHP_LOG);
|
55 |
+
|
56 |
+
$firephp->fb(array('key1'=>'val1',
|
57 |
+
'key2'=>array(array('v1','v2'),'v3')),
|
58 |
+
'TestArray',FirePHP_LOG);
|
59 |
+
|
60 |
+
$firephp->fb('Backtrace to here',FirePHP_TRACE);
|
61 |
+
|
62 |
+
$firephp->fb(array('2 SQL queries took 0.06 seconds',array(
|
63 |
+
array('SQL Statement','Time','Result'),
|
64 |
+
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
65 |
+
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
66 |
+
)),FirePHP_TABLE);
|
67 |
+
|
68 |
+
/* Will show only in "Server" tab for the request */
|
69 |
+
$firephp->fb(apache_request_headers(),'RequestHeaders',FirePHP_DUMP);
|
70 |
+
|
71 |
+
|
72 |
+
print 'Hello World';
|
includes/debug/browsers/api/firephp/examples/procedural.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
5 |
+
|
6 |
+
/* *** BEGIN LICENSE BLOCK *****
|
7 |
+
*
|
8 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
9 |
+
*
|
10 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
11 |
+
*
|
12 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 |
+
* of this software and associated documentation files (the "Software"), to deal
|
14 |
+
* in the Software without restriction, including without limitation the rights
|
15 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16 |
+
* copies of the Software, and to permit persons to whom the Software is
|
17 |
+
* furnished to do so, subject to the following conditions:
|
18 |
+
*
|
19 |
+
* The above copyright notice and this permission notice shall be included in
|
20 |
+
* all copies or substantial portions of the Software.
|
21 |
+
*
|
22 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
28 |
+
* THE SOFTWARE.
|
29 |
+
*
|
30 |
+
* ***** END LICENSE BLOCK ***** */
|
31 |
+
|
32 |
+
|
33 |
+
/* NOTE: You must have the FirePHPCore library in your include path */
|
34 |
+
|
35 |
+
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
36 |
+
|
37 |
+
|
38 |
+
require('FirePHPCore/fb.php');
|
39 |
+
|
40 |
+
/* NOTE: You must have Output Buffering enabled via
|
41 |
+
ob_start() or output_buffering ini directive. */
|
42 |
+
|
43 |
+
fb('Hello World'); /* Defaults to FirePHP::LOG */
|
44 |
+
|
45 |
+
fb('Log message' ,FirePHP::LOG);
|
46 |
+
fb('Info message' ,FirePHP::INFO);
|
47 |
+
fb('Warn message' ,FirePHP::WARN);
|
48 |
+
fb('Error message',FirePHP::ERROR);
|
49 |
+
|
50 |
+
fb('Message with label','Label',FirePHP::LOG);
|
51 |
+
|
52 |
+
fb(array('key1'=>'val1',
|
53 |
+
'key2'=>array(array('v1','v2'),'v3')),
|
54 |
+
'TestArray',FirePHP::LOG);
|
55 |
+
|
56 |
+
function test($Arg1) {
|
57 |
+
throw new Exception('Test Exception');
|
58 |
+
}
|
59 |
+
try {
|
60 |
+
test(array('Hello'=>'World'));
|
61 |
+
} catch(Exception $e) {
|
62 |
+
/* Log exception including stack trace & variables */
|
63 |
+
fb($e);
|
64 |
+
}
|
65 |
+
|
66 |
+
fb('Backtrace to here',FirePHP::TRACE);
|
67 |
+
|
68 |
+
fb(array('2 SQL queries took 0.06 seconds',array(
|
69 |
+
array('SQL Statement','Time','Result'),
|
70 |
+
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
71 |
+
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
72 |
+
)),FirePHP::TABLE);
|
73 |
+
|
74 |
+
/* Will show only in "Server" tab for the request */
|
75 |
+
fb(apache_request_headers(),'RequestHeaders',FirePHP::DUMP);
|
76 |
+
|
77 |
+
|
78 |
+
print 'Hello World';
|
79 |
+
|
includes/debug/browsers/api/firephp/examples/procedural.php4
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
5 |
+
|
6 |
+
/* *** BEGIN LICENSE BLOCK *****
|
7 |
+
*
|
8 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
9 |
+
*
|
10 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
11 |
+
*
|
12 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 |
+
* of this software and associated documentation files (the "Software"), to deal
|
14 |
+
* in the Software without restriction, including without limitation the rights
|
15 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16 |
+
* copies of the Software, and to permit persons to whom the Software is
|
17 |
+
* furnished to do so, subject to the following conditions:
|
18 |
+
*
|
19 |
+
* The above copyright notice and this permission notice shall be included in
|
20 |
+
* all copies or substantial portions of the Software.
|
21 |
+
*
|
22 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
28 |
+
* THE SOFTWARE.
|
29 |
+
*
|
30 |
+
* ***** END LICENSE BLOCK ***** */
|
31 |
+
|
32 |
+
|
33 |
+
/* NOTE: You must have the FirePHPCore library in your include path */
|
34 |
+
|
35 |
+
set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path());
|
36 |
+
|
37 |
+
|
38 |
+
require('FirePHPCore/fb.php');
|
39 |
+
|
40 |
+
/* NOTE: You must have Output Buffering enabled via
|
41 |
+
ob_start() or output_buffering ini directive. */
|
42 |
+
|
43 |
+
fb('Hello World'); /* Defaults to FirePHP::LOG */
|
44 |
+
|
45 |
+
fb('Log message' ,FirePHP_LOG);
|
46 |
+
fb('Info message' ,FirePHP_INFO);
|
47 |
+
fb('Warn message' ,FirePHP_WARN);
|
48 |
+
fb('Error message',FirePHP_ERROR);
|
49 |
+
|
50 |
+
fb('Message with label','Label',FirePHP_LOG);
|
51 |
+
|
52 |
+
fb(array('key1'=>'val1',
|
53 |
+
'key2'=>array(array('v1','v2'),'v3')),
|
54 |
+
'TestArray',FirePHP_LOG);
|
55 |
+
|
56 |
+
fb('Backtrace to here',FirePHP_TRACE);
|
57 |
+
|
58 |
+
fb(array('2 SQL queries took 0.06 seconds',array(
|
59 |
+
array('SQL Statement','Time','Result'),
|
60 |
+
array('SELECT * FROM Foo','0.02',array('row1','row2')),
|
61 |
+
array('SELECT * FROM Bar','0.04',array('row1','row2'))
|
62 |
+
)),FirePHP_TABLE);
|
63 |
+
|
64 |
+
/* Will show only in "Server" tab for the request */
|
65 |
+
fb(apache_request_headers(),'RequestHeaders',FirePHP_DUMP);
|
66 |
+
|
67 |
+
|
68 |
+
print 'Hello World';
|
69 |
+
|
includes/debug/browsers/api/firephp/lib/FirePHPCore/FirePHP.class.php
ADDED
@@ -0,0 +1,1828 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - qbbr, Sokolov Innokenty <sokolov.innokenty@gmail.com>, Copyright 2011, New BSD License
|
5 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
6 |
+
|
7 |
+
/**
|
8 |
+
* *** BEGIN LICENSE BLOCK *****
|
9 |
+
*
|
10 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
11 |
+
*
|
12 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
13 |
+
*
|
14 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 |
+
* of this software and associated documentation files (the "Software"), to deal
|
16 |
+
* in the Software without restriction, including without limitation the rights
|
17 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18 |
+
* copies of the Software, and to permit persons to whom the Software is
|
19 |
+
* furnished to do so, subject to the following conditions:
|
20 |
+
*
|
21 |
+
* The above copyright notice and this permission notice shall be included in
|
22 |
+
* all copies or substantial portions of the Software.
|
23 |
+
*
|
24 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
25 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
26 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
27 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
28 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
29 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
30 |
+
* THE SOFTWARE.
|
31 |
+
*
|
32 |
+
* ***** END LICENSE BLOCK *****
|
33 |
+
*
|
34 |
+
* @copyright Copyright (C) 2007+ Christoph Dorn
|
35 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
36 |
+
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
37 |
+
* @package FirePHPCore
|
38 |
+
*/
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @see http://code.google.com/p/firephp/issues/detail?id=112
|
42 |
+
*/
|
43 |
+
if (!defined('E_STRICT')) {
|
44 |
+
define('E_STRICT', 2048);
|
45 |
+
}
|
46 |
+
if (!defined('E_RECOVERABLE_ERROR')) {
|
47 |
+
define('E_RECOVERABLE_ERROR', 4096);
|
48 |
+
}
|
49 |
+
if (!defined('E_DEPRECATED')) {
|
50 |
+
define('E_DEPRECATED', 8192);
|
51 |
+
}
|
52 |
+
if (!defined('E_USER_DEPRECATED')) {
|
53 |
+
define('E_USER_DEPRECATED', 16384);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Sends the given data to the FirePHP Firefox Extension.
|
58 |
+
* The data can be displayed in the Firebug Console or in the
|
59 |
+
* "Server" request tab.
|
60 |
+
*
|
61 |
+
* For more information see: http://www.firephp.org/
|
62 |
+
*
|
63 |
+
* @copyright Copyright (C) 2007+ Christoph Dorn
|
64 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
65 |
+
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
66 |
+
* @package FirePHPCore
|
67 |
+
*/
|
68 |
+
class FirePHP {
|
69 |
+
|
70 |
+
/**
|
71 |
+
* FirePHP version
|
72 |
+
*
|
73 |
+
* @var string
|
74 |
+
*/
|
75 |
+
const VERSION = '0.3'; // @pinf replace '0.3' with '%%VERSION%%'
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Firebug LOG level
|
79 |
+
*
|
80 |
+
* Logs a message to firebug console.
|
81 |
+
*
|
82 |
+
* @var string
|
83 |
+
*/
|
84 |
+
const LOG = 'LOG';
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Firebug INFO level
|
88 |
+
*
|
89 |
+
* Logs a message to firebug console and displays an info icon before the message.
|
90 |
+
*
|
91 |
+
* @var string
|
92 |
+
*/
|
93 |
+
const INFO = 'INFO';
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Firebug WARN level
|
97 |
+
*
|
98 |
+
* Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise.
|
99 |
+
*
|
100 |
+
* @var string
|
101 |
+
*/
|
102 |
+
const WARN = 'WARN';
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Firebug ERROR level
|
106 |
+
*
|
107 |
+
* Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count.
|
108 |
+
*
|
109 |
+
* @var string
|
110 |
+
*/
|
111 |
+
const ERROR = 'ERROR';
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Dumps a variable to firebug's server panel
|
115 |
+
*
|
116 |
+
* @var string
|
117 |
+
*/
|
118 |
+
const DUMP = 'DUMP';
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Displays a stack trace in firebug console
|
122 |
+
*
|
123 |
+
* @var string
|
124 |
+
*/
|
125 |
+
const TRACE = 'TRACE';
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Displays an exception in firebug console
|
129 |
+
*
|
130 |
+
* Increments the firebug error count.
|
131 |
+
*
|
132 |
+
* @var string
|
133 |
+
*/
|
134 |
+
const EXCEPTION = 'EXCEPTION';
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Displays an table in firebug console
|
138 |
+
*
|
139 |
+
* @var string
|
140 |
+
*/
|
141 |
+
const TABLE = 'TABLE';
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Starts a group in firebug console
|
145 |
+
*
|
146 |
+
* @var string
|
147 |
+
*/
|
148 |
+
const GROUP_START = 'GROUP_START';
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Ends a group in firebug console
|
152 |
+
*
|
153 |
+
* @var string
|
154 |
+
*/
|
155 |
+
const GROUP_END = 'GROUP_END';
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Singleton instance of FirePHP
|
159 |
+
*
|
160 |
+
* @var FirePHP
|
161 |
+
*/
|
162 |
+
protected static $instance = null;
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Flag whether we are logging from within the exception handler
|
166 |
+
*
|
167 |
+
* @var boolean
|
168 |
+
*/
|
169 |
+
protected $inExceptionHandler = false;
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Flag whether to throw PHP errors that have been converted to ErrorExceptions
|
173 |
+
*
|
174 |
+
* @var boolean
|
175 |
+
*/
|
176 |
+
protected $throwErrorExceptions = true;
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Flag whether to convert PHP assertion errors to Exceptions
|
180 |
+
*
|
181 |
+
* @var boolean
|
182 |
+
*/
|
183 |
+
protected $convertAssertionErrorsToExceptions = true;
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Flag whether to throw PHP assertion errors that have been converted to Exceptions
|
187 |
+
*
|
188 |
+
* @var boolean
|
189 |
+
*/
|
190 |
+
protected $throwAssertionExceptions = false;
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Wildfire protocol message index
|
194 |
+
*
|
195 |
+
* @var integer
|
196 |
+
*/
|
197 |
+
protected $messageIndex = 1;
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Options for the library
|
201 |
+
*
|
202 |
+
* @var array
|
203 |
+
*/
|
204 |
+
protected $options = array('maxDepth' => 10,
|
205 |
+
'maxObjectDepth' => 5,
|
206 |
+
'maxArrayDepth' => 5,
|
207 |
+
'useNativeJsonEncode' => true,
|
208 |
+
'includeLineNumbers' => true);
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Filters used to exclude object members when encoding
|
212 |
+
*
|
213 |
+
* @var array
|
214 |
+
*/
|
215 |
+
protected $objectFilters = array(
|
216 |
+
'firephp' => array('objectStack', 'instance', 'json_objectStack'),
|
217 |
+
'firephp_test_class' => array('objectStack', 'instance', 'json_objectStack')
|
218 |
+
);
|
219 |
+
|
220 |
+
/**
|
221 |
+
* A stack of objects used to detect recursion during object encoding
|
222 |
+
*
|
223 |
+
* @var object
|
224 |
+
*/
|
225 |
+
protected $objectStack = array();
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Flag to enable/disable logging
|
229 |
+
*
|
230 |
+
* @var boolean
|
231 |
+
*/
|
232 |
+
protected $enabled = true;
|
233 |
+
|
234 |
+
/**
|
235 |
+
* The insight console to log to if applicable
|
236 |
+
*
|
237 |
+
* @var object
|
238 |
+
*/
|
239 |
+
protected $logToInsightConsole = null;
|
240 |
+
|
241 |
+
/**
|
242 |
+
* When the object gets serialized only include specific object members.
|
243 |
+
*
|
244 |
+
* @return array
|
245 |
+
*/
|
246 |
+
public function __sleep()
|
247 |
+
{
|
248 |
+
return array('options', 'objectFilters', 'enabled');
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Gets singleton instance of FirePHP
|
253 |
+
*
|
254 |
+
* @param boolean $autoCreate
|
255 |
+
* @return FirePHP
|
256 |
+
*/
|
257 |
+
public static function getInstance($autoCreate = false)
|
258 |
+
{
|
259 |
+
if ($autoCreate === true && !self::$instance) {
|
260 |
+
self::init();
|
261 |
+
}
|
262 |
+
return self::$instance;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Creates FirePHP object and stores it for singleton access
|
267 |
+
*
|
268 |
+
* @return FirePHP
|
269 |
+
*/
|
270 |
+
public static function init()
|
271 |
+
{
|
272 |
+
return self::setInstance(new self());
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Set the instance of the FirePHP singleton
|
277 |
+
*
|
278 |
+
* @param FirePHP $instance The FirePHP object instance
|
279 |
+
* @return FirePHP
|
280 |
+
*/
|
281 |
+
public static function setInstance($instance)
|
282 |
+
{
|
283 |
+
return self::$instance = $instance;
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Set an Insight console to direct all logging calls to
|
288 |
+
*
|
289 |
+
* @param object $console The console object to log to
|
290 |
+
* @return void
|
291 |
+
*/
|
292 |
+
public function setLogToInsightConsole($console)
|
293 |
+
{
|
294 |
+
if (is_string($console)) {
|
295 |
+
if (get_class($this) != 'FirePHP_Insight' && !is_subclass_of($this, 'FirePHP_Insight')) {
|
296 |
+
throw new Exception('FirePHP instance not an instance or subclass of FirePHP_Insight!');
|
297 |
+
}
|
298 |
+
$this->logToInsightConsole = $this->to('request')->console($console);
|
299 |
+
} else {
|
300 |
+
$this->logToInsightConsole = $console;
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Enable and disable logging to Firebug
|
306 |
+
*
|
307 |
+
* @param boolean $enabled TRUE to enable, FALSE to disable
|
308 |
+
* @return void
|
309 |
+
*/
|
310 |
+
public function setEnabled($enabled)
|
311 |
+
{
|
312 |
+
$this->enabled = $enabled;
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Check if logging is enabled
|
317 |
+
*
|
318 |
+
* @return boolean TRUE if enabled
|
319 |
+
*/
|
320 |
+
public function getEnabled()
|
321 |
+
{
|
322 |
+
return $this->enabled;
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Specify a filter to be used when encoding an object
|
327 |
+
*
|
328 |
+
* Filters are used to exclude object members.
|
329 |
+
*
|
330 |
+
* @param string $class The class name of the object
|
331 |
+
* @param array $filter An array of members to exclude
|
332 |
+
* @return void
|
333 |
+
*/
|
334 |
+
public function setObjectFilter($class, $filter)
|
335 |
+
{
|
336 |
+
$this->objectFilters[strtolower($class)] = $filter;
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* Set some options for the library
|
341 |
+
*
|
342 |
+
* Options:
|
343 |
+
* - maxDepth: The maximum depth to traverse (default: 10)
|
344 |
+
* - maxObjectDepth: The maximum depth to traverse objects (default: 5)
|
345 |
+
* - maxArrayDepth: The maximum depth to traverse arrays (default: 5)
|
346 |
+
* - useNativeJsonEncode: If true will use json_encode() (default: true)
|
347 |
+
* - includeLineNumbers: If true will include line numbers and filenames (default: true)
|
348 |
+
*
|
349 |
+
* @param array $options The options to be set
|
350 |
+
* @return void
|
351 |
+
*/
|
352 |
+
public function setOptions($options)
|
353 |
+
{
|
354 |
+
$this->options = array_merge($this->options, $options);
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Get options from the library
|
359 |
+
*
|
360 |
+
* @return array The currently set options
|
361 |
+
*/
|
362 |
+
public function getOptions()
|
363 |
+
{
|
364 |
+
return $this->options;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Set an option for the library
|
369 |
+
*
|
370 |
+
* @param string $name
|
371 |
+
* @param mixed $value
|
372 |
+
* @return void
|
373 |
+
* @throws Exception
|
374 |
+
*/
|
375 |
+
public function setOption($name, $value)
|
376 |
+
{
|
377 |
+
if (!isset($this->options[$name])) {
|
378 |
+
throw $this->newException('Unknown option: ' . $name);
|
379 |
+
}
|
380 |
+
$this->options[$name] = $value;
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Get an option from the library
|
385 |
+
*
|
386 |
+
* @param string $name
|
387 |
+
* @return mixed
|
388 |
+
* @throws Exception
|
389 |
+
*/
|
390 |
+
public function getOption($name)
|
391 |
+
{
|
392 |
+
if (!isset($this->options[$name])) {
|
393 |
+
throw $this->newException('Unknown option: ' . $name);
|
394 |
+
}
|
395 |
+
return $this->options[$name];
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Register FirePHP as your error handler
|
400 |
+
*
|
401 |
+
* Will throw exceptions for each php error.
|
402 |
+
*
|
403 |
+
* @return mixed Returns a string containing the previously defined error handler (if any)
|
404 |
+
*/
|
405 |
+
public function registerErrorHandler($throwErrorExceptions = false)
|
406 |
+
{
|
407 |
+
//NOTE: The following errors will not be caught by this error handler:
|
408 |
+
// E_ERROR, E_PARSE, E_CORE_ERROR,
|
409 |
+
// E_CORE_WARNING, E_COMPILE_ERROR,
|
410 |
+
// E_COMPILE_WARNING, E_STRICT
|
411 |
+
|
412 |
+
$this->throwErrorExceptions = $throwErrorExceptions;
|
413 |
+
|
414 |
+
return set_error_handler(array($this, 'errorHandler'));
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* FirePHP's error handler
|
419 |
+
*
|
420 |
+
* Throws exception for each php error that will occur.
|
421 |
+
*
|
422 |
+
* @param integer $errno
|
423 |
+
* @param string $errstr
|
424 |
+
* @param string $errfile
|
425 |
+
* @param integer $errline
|
426 |
+
* @param array $errcontext
|
427 |
+
*/
|
428 |
+
public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
|
429 |
+
{
|
430 |
+
// Don't throw exception if error reporting is switched off
|
431 |
+
if (error_reporting() == 0) {
|
432 |
+
return;
|
433 |
+
}
|
434 |
+
// Only throw exceptions for errors we are asking for
|
435 |
+
if (error_reporting() & $errno) {
|
436 |
+
|
437 |
+
$exception = new ErrorException($errstr, 0, $errno, $errfile, $errline);
|
438 |
+
if ($this->throwErrorExceptions) {
|
439 |
+
throw $exception;
|
440 |
+
} else {
|
441 |
+
$this->fb($exception);
|
442 |
+
}
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
/**
|
447 |
+
* Register FirePHP as your exception handler
|
448 |
+
*
|
449 |
+
* @return mixed Returns the name of the previously defined exception handler,
|
450 |
+
* or NULL on error.
|
451 |
+
* If no previous handler was defined, NULL is also returned.
|
452 |
+
*/
|
453 |
+
public function registerExceptionHandler()
|
454 |
+
{
|
455 |
+
return set_exception_handler(array($this, 'exceptionHandler'));
|
456 |
+
}
|
457 |
+
|
458 |
+
/**
|
459 |
+
* FirePHP's exception handler
|
460 |
+
*
|
461 |
+
* Logs all exceptions to your firebug console and then stops the script.
|
462 |
+
*
|
463 |
+
* @param Exception $exception
|
464 |
+
* @throws Exception
|
465 |
+
*/
|
466 |
+
function exceptionHandler($exception)
|
467 |
+
{
|
468 |
+
$this->inExceptionHandler = true;
|
469 |
+
|
470 |
+
header('HTTP/1.1 500 Internal Server Error');
|
471 |
+
|
472 |
+
try {
|
473 |
+
$this->fb($exception);
|
474 |
+
} catch (Exception $e) {
|
475 |
+
echo 'We had an exception: ' . $e;
|
476 |
+
}
|
477 |
+
|
478 |
+
$this->inExceptionHandler = false;
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Register FirePHP driver as your assert callback
|
483 |
+
*
|
484 |
+
* @param boolean $convertAssertionErrorsToExceptions
|
485 |
+
* @param boolean $throwAssertionExceptions
|
486 |
+
* @return mixed Returns the original setting or FALSE on errors
|
487 |
+
*/
|
488 |
+
public function registerAssertionHandler($convertAssertionErrorsToExceptions = true, $throwAssertionExceptions = false)
|
489 |
+
{
|
490 |
+
$this->convertAssertionErrorsToExceptions = $convertAssertionErrorsToExceptions;
|
491 |
+
$this->throwAssertionExceptions = $throwAssertionExceptions;
|
492 |
+
|
493 |
+
if ($throwAssertionExceptions && !$convertAssertionErrorsToExceptions) {
|
494 |
+
throw $this->newException('Cannot throw assertion exceptions as assertion errors are not being converted to exceptions!');
|
495 |
+
}
|
496 |
+
|
497 |
+
return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler'));
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* FirePHP's assertion handler
|
502 |
+
*
|
503 |
+
* Logs all assertions to your firebug console and then stops the script.
|
504 |
+
*
|
505 |
+
* @param string $file File source of assertion
|
506 |
+
* @param integer $line Line source of assertion
|
507 |
+
* @param mixed $code Assertion code
|
508 |
+
*/
|
509 |
+
public function assertionHandler($file, $line, $code)
|
510 |
+
{
|
511 |
+
if ($this->convertAssertionErrorsToExceptions) {
|
512 |
+
|
513 |
+
$exception = new ErrorException('Assertion Failed - Code[ ' . $code . ' ]', 0, null, $file, $line);
|
514 |
+
|
515 |
+
if ($this->throwAssertionExceptions) {
|
516 |
+
throw $exception;
|
517 |
+
} else {
|
518 |
+
$this->fb($exception);
|
519 |
+
}
|
520 |
+
|
521 |
+
} else {
|
522 |
+
$this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File' => $file, 'Line' => $line));
|
523 |
+
}
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Start a group for following messages.
|
528 |
+
*
|
529 |
+
* Options:
|
530 |
+
* Collapsed: [true|false]
|
531 |
+
* Color: [#RRGGBB|ColorName]
|
532 |
+
*
|
533 |
+
* @param string $name
|
534 |
+
* @param array $options OPTIONAL Instructions on how to log the group
|
535 |
+
* @return true
|
536 |
+
* @throws Exception
|
537 |
+
*/
|
538 |
+
public function group($name, $options = null)
|
539 |
+
{
|
540 |
+
|
541 |
+
if (!$name) {
|
542 |
+
throw $this->newException('You must specify a label for the group!');
|
543 |
+
}
|
544 |
+
|
545 |
+
if ($options) {
|
546 |
+
if (!is_array($options)) {
|
547 |
+
throw $this->newException('Options must be defined as an array!');
|
548 |
+
}
|
549 |
+
if (array_key_exists('Collapsed', $options)) {
|
550 |
+
$options['Collapsed'] = ($options['Collapsed']) ? 'true' : 'false';
|
551 |
+
}
|
552 |
+
}
|
553 |
+
|
554 |
+
return $this->fb(null, $name, FirePHP::GROUP_START, $options);
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Ends a group you have started before
|
559 |
+
*
|
560 |
+
* @return true
|
561 |
+
* @throws Exception
|
562 |
+
*/
|
563 |
+
public function groupEnd()
|
564 |
+
{
|
565 |
+
return $this->fb(null, null, FirePHP::GROUP_END);
|
566 |
+
}
|
567 |
+
|
568 |
+
/**
|
569 |
+
* Log object with label to firebug console
|
570 |
+
*
|
571 |
+
* @see FirePHP::LOG
|
572 |
+
* @param mixes $object
|
573 |
+
* @param string $label
|
574 |
+
* @return true
|
575 |
+
* @throws Exception
|
576 |
+
*/
|
577 |
+
public function log($object, $label = null, $options = array())
|
578 |
+
{
|
579 |
+
return $this->fb($object, $label, FirePHP::LOG, $options);
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Log object with label to firebug console
|
584 |
+
*
|
585 |
+
* @see FirePHP::INFO
|
586 |
+
* @param mixes $object
|
587 |
+
* @param string $label
|
588 |
+
* @return true
|
589 |
+
* @throws Exception
|
590 |
+
*/
|
591 |
+
public function info($object, $label = null, $options = array())
|
592 |
+
{
|
593 |
+
return $this->fb($object, $label, FirePHP::INFO, $options);
|
594 |
+
}
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Log object with label to firebug console
|
598 |
+
*
|
599 |
+
* @see FirePHP::WARN
|
600 |
+
* @param mixes $object
|
601 |
+
* @param string $label
|
602 |
+
* @return true
|
603 |
+
* @throws Exception
|
604 |
+
*/
|
605 |
+
public function warn($object, $label = null, $options = array())
|
606 |
+
{
|
607 |
+
return $this->fb($object, $label, FirePHP::WARN, $options);
|
608 |
+
}
|
609 |
+
|
610 |
+
/**
|
611 |
+
* Log object with label to firebug console
|
612 |
+
*
|
613 |
+
* @see FirePHP::ERROR
|
614 |
+
* @param mixes $object
|
615 |
+
* @param string $label
|
616 |
+
* @return true
|
617 |
+
* @throws Exception
|
618 |
+
*/
|
619 |
+
public function error($object, $label = null, $options = array())
|
620 |
+
{
|
621 |
+
return $this->fb($object, $label, FirePHP::ERROR, $options);
|
622 |
+
}
|
623 |
+
|
624 |
+
/**
|
625 |
+
* Dumps key and variable to firebug server panel
|
626 |
+
*
|
627 |
+
* @see FirePHP::DUMP
|
628 |
+
* @param string $key
|
629 |
+
* @param mixed $variable
|
630 |
+
* @return true
|
631 |
+
* @throws Exception
|
632 |
+
*/
|
633 |
+
public function dump($key, $variable, $options = array())
|
634 |
+
{
|
635 |
+
if (!is_string($key)) {
|
636 |
+
throw $this->newException('Key passed to dump() is not a string');
|
637 |
+
}
|
638 |
+
if (strlen($key) > 100) {
|
639 |
+
throw $this->newException('Key passed to dump() is longer than 100 characters');
|
640 |
+
}
|
641 |
+
if (!preg_match_all('/^[a-zA-Z0-9-_\.:]*$/', $key, $m)) {
|
642 |
+
throw $this->newException('Key passed to dump() contains invalid characters [a-zA-Z0-9-_\.:]');
|
643 |
+
}
|
644 |
+
return $this->fb($variable, $key, FirePHP::DUMP, $options);
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* Log a trace in the firebug console
|
649 |
+
*
|
650 |
+
* @see FirePHP::TRACE
|
651 |
+
* @param string $label
|
652 |
+
* @return true
|
653 |
+
* @throws Exception
|
654 |
+
*/
|
655 |
+
public function trace($label)
|
656 |
+
{
|
657 |
+
return $this->fb($label, FirePHP::TRACE);
|
658 |
+
}
|
659 |
+
|
660 |
+
/**
|
661 |
+
* Log a table in the firebug console
|
662 |
+
*
|
663 |
+
* @see FirePHP::TABLE
|
664 |
+
* @param string $label
|
665 |
+
* @param string $table
|
666 |
+
* @return true
|
667 |
+
* @throws Exception
|
668 |
+
*/
|
669 |
+
public function table($label, $table, $options = array())
|
670 |
+
{
|
671 |
+
return $this->fb($table, $label, FirePHP::TABLE, $options);
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* Insight API wrapper
|
676 |
+
*
|
677 |
+
* @see Insight_Helper::to()
|
678 |
+
*/
|
679 |
+
public static function to()
|
680 |
+
{
|
681 |
+
$instance = self::getInstance();
|
682 |
+
if (!method_exists($instance, '_to')) {
|
683 |
+
throw new Exception('FirePHP::to() implementation not loaded');
|
684 |
+
}
|
685 |
+
$args = func_get_args();
|
686 |
+
return call_user_func_array(array($instance, '_to'), $args);
|
687 |
+
}
|
688 |
+
|
689 |
+
/**
|
690 |
+
* Insight API wrapper
|
691 |
+
*
|
692 |
+
* @see Insight_Helper::plugin()
|
693 |
+
*/
|
694 |
+
public static function plugin()
|
695 |
+
{
|
696 |
+
$instance = self::getInstance();
|
697 |
+
if (!method_exists($instance, '_plugin')) {
|
698 |
+
throw new Exception('FirePHP::plugin() implementation not loaded');
|
699 |
+
}
|
700 |
+
$args = func_get_args();
|
701 |
+
return call_user_func_array(array($instance, '_plugin'), $args);
|
702 |
+
}
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Check if FirePHP is installed on client
|
706 |
+
*
|
707 |
+
* @return boolean
|
708 |
+
*/
|
709 |
+
public function detectClientExtension()
|
710 |
+
{
|
711 |
+
// Check if FirePHP is installed on client via User-Agent header
|
712 |
+
if (@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si', $this->getUserAgent(), $m) &&
|
713 |
+
version_compare($m[1][0], '0.0.6', '>=')) {
|
714 |
+
return true;
|
715 |
+
} else
|
716 |
+
// Check if FirePHP is installed on client via X-FirePHP-Version header
|
717 |
+
if (@preg_match_all('/^([\.\d]*)$/si', $this->getRequestHeader('X-FirePHP-Version'), $m) &&
|
718 |
+
version_compare($m[1][0], '0.0.6', '>=')) {
|
719 |
+
return true;
|
720 |
+
}
|
721 |
+
return false;
|
722 |
+
}
|
723 |
+
|
724 |
+
/**
|
725 |
+
* Log varible to Firebug
|
726 |
+
*
|
727 |
+
* @see http://www.firephp.org/Wiki/Reference/Fb
|
728 |
+
* @param mixed $object The variable to be logged
|
729 |
+
* @return boolean Return TRUE if message was added to headers, FALSE otherwise
|
730 |
+
* @throws Exception
|
731 |
+
*/
|
732 |
+
public function fb($object)
|
733 |
+
{
|
734 |
+
if ($this instanceof FirePHP_Insight && method_exists($this, '_logUpgradeClientMessage')) {
|
735 |
+
if (!FirePHP_Insight::$upgradeClientMessageLogged) { // avoid infinite recursion as _logUpgradeClientMessage() logs a message
|
736 |
+
$this->_logUpgradeClientMessage();
|
737 |
+
}
|
738 |
+
}
|
739 |
+
|
740 |
+
static $insightGroupStack = array();
|
741 |
+
|
742 |
+
if (!$this->getEnabled()) {
|
743 |
+
return false;
|
744 |
+
}
|
745 |
+
|
746 |
+
if ($this->headersSent($filename, $linenum)) {
|
747 |
+
// If we are logging from within the exception handler we cannot throw another exception
|
748 |
+
if ($this->inExceptionHandler) {
|
749 |
+
// Simply echo the error out to the page
|
750 |
+
echo '<div style="border: 2px solid red; font-family: Arial; font-size: 12px; background-color: lightgray; padding: 5px;"><span style="color: red; font-weight: bold;">FirePHP ERROR:</span> Headers already sent in <b>' . $filename . '</b> on line <b>' . $linenum . '</b>. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.</div>';
|
751 |
+
} else {
|
752 |
+
throw $this->newException('Headers already sent in ' . $filename . ' on line ' . $linenum . '. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.');
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
$type = null;
|
757 |
+
$label = null;
|
758 |
+
$options = array();
|
759 |
+
|
760 |
+
if (func_num_args() == 1) {
|
761 |
+
} else if (func_num_args() == 2) {
|
762 |
+
switch (func_get_arg(1)) {
|
763 |
+
case self::LOG:
|
764 |
+
case self::INFO:
|
765 |
+
case self::WARN:
|
766 |
+
case self::ERROR:
|
767 |
+
case self::DUMP:
|
768 |
+
case self::TRACE:
|
769 |
+
case self::EXCEPTION:
|
770 |
+
case self::TABLE:
|
771 |
+
case self::GROUP_START:
|
772 |
+
case self::GROUP_END:
|
773 |
+
$type = func_get_arg(1);
|
774 |
+
break;
|
775 |
+
default:
|
776 |
+
$label = func_get_arg(1);
|
777 |
+
break;
|
778 |
+
}
|
779 |
+
} else if (func_num_args() == 3) {
|
780 |
+
$type = func_get_arg(2);
|
781 |
+
$label = func_get_arg(1);
|
782 |
+
} else if (func_num_args() == 4) {
|
783 |
+
$type = func_get_arg(2);
|
784 |
+
$label = func_get_arg(1);
|
785 |
+
$options = func_get_arg(3);
|
786 |
+
} else {
|
787 |
+
throw $this->newException('Wrong number of arguments to fb() function!');
|
788 |
+
}
|
789 |
+
|
790 |
+
if ($this->logToInsightConsole !== null && (get_class($this) == 'FirePHP_Insight' || is_subclass_of($this, 'FirePHP_Insight'))) {
|
791 |
+
$trace = debug_backtrace();
|
792 |
+
if (!$trace) return false;
|
793 |
+
for ($i = 0; $i < sizeof($trace); $i++) {
|
794 |
+
if (isset($trace[$i]['class'])) {
|
795 |
+
if ($trace[$i]['class'] == 'FirePHP' || $trace[$i]['class'] == 'FB') {
|
796 |
+
continue;
|
797 |
+
}
|
798 |
+
}
|
799 |
+
if (isset($trace[$i]['file'])) {
|
800 |
+
$path = $this->_standardizePath($trace[$i]['file']);
|
801 |
+
if (substr($path, -18, 18) == 'FirePHPCore/fb.php' || substr($path, -29, 29) == 'FirePHPCore/FirePHP.class.php') {
|
802 |
+
continue;
|
803 |
+
}
|
804 |
+
}
|
805 |
+
if (isset($trace[$i]['function']) && $trace[$i]['function'] == 'fb' &&
|
806 |
+
isset($trace[$i - 1]['file']) && substr($this->_standardizePath($trace[$i - 1]['file']), -18, 18) == 'FirePHPCore/fb.php') {
|
807 |
+
continue;
|
808 |
+
}
|
809 |
+
if (isset($trace[$i]['class']) && $trace[$i]['class'] == 'FB' &&
|
810 |
+
isset($trace[$i - 1]['file']) && substr($this->_standardizePath($trace[$i - 1]['file']), -18, 18) == 'FirePHPCore/fb.php') {
|
811 |
+
continue;
|
812 |
+
}
|
813 |
+
break;
|
814 |
+
}
|
815 |
+
// adjust trace offset
|
816 |
+
$msg = $this->logToInsightConsole->option('encoder.trace.offsetAdjustment', $i);
|
817 |
+
|
818 |
+
if ($object instanceof Exception) {
|
819 |
+
$type = self::EXCEPTION;
|
820 |
+
}
|
821 |
+
if ($label && $type != self::TABLE && $type != self::GROUP_START) {
|
822 |
+
$msg = $msg->label($label);
|
823 |
+
}
|
824 |
+
switch ($type) {
|
825 |
+
case self::DUMP:
|
826 |
+
case self::LOG:
|
827 |
+
return $msg->log($object);
|
828 |
+
case self::INFO:
|
829 |
+
return $msg->info($object);
|
830 |
+
case self::WARN:
|
831 |
+
return $msg->warn($object);
|
832 |
+
case self::ERROR:
|
833 |
+
return $msg->error($object);
|
834 |
+
case self::TRACE:
|
835 |
+
return $msg->trace($object);
|
836 |
+
case self::EXCEPTION:
|
837 |
+
return $this->plugin('error')->handleException($object, $msg);
|
838 |
+
case self::TABLE:
|
839 |
+
if (isset($object[0]) && !is_string($object[0]) && $label) {
|
840 |
+
$object = array($label, $object);
|
841 |
+
}
|
842 |
+
return $msg->table($object[0], array_slice($object[1], 1), $object[1][0]);
|
843 |
+
case self::GROUP_START:
|
844 |
+
$insightGroupStack[] = $msg->group(md5($label))->open();
|
845 |
+
return $msg->log($label);
|
846 |
+
case self::GROUP_END:
|
847 |
+
if (count($insightGroupStack) == 0) {
|
848 |
+
throw new Error('Too many groupEnd() as opposed to group() calls!');
|
849 |
+
}
|
850 |
+
$group = array_pop($insightGroupStack);
|
851 |
+
return $group->close();
|
852 |
+
default:
|
853 |
+
return $msg->log($object);
|
854 |
+
}
|
855 |
+
}
|
856 |
+
|
857 |
+
if (!$this->detectClientExtension()) {
|
858 |
+
return false;
|
859 |
+
}
|
860 |
+
|
861 |
+
$meta = array();
|
862 |
+
$skipFinalObjectEncode = false;
|
863 |
+
|
864 |
+
if ($object instanceof Exception) {
|
865 |
+
|
866 |
+
$meta['file'] = $this->_escapeTraceFile($object->getFile());
|
867 |
+
$meta['line'] = $object->getLine();
|
868 |
+
|
869 |
+
$trace = $object->getTrace();
|
870 |
+
if ($object instanceof ErrorException
|
871 |
+
&& isset($trace[0]['function'])
|
872 |
+
&& $trace[0]['function'] == 'errorHandler'
|
873 |
+
&& isset($trace[0]['class'])
|
874 |
+
&& $trace[0]['class'] == 'FirePHP') {
|
875 |
+
|
876 |
+
$severity = false;
|
877 |
+
switch ($object->getSeverity()) {
|
878 |
+
case E_WARNING:
|
879 |
+
$severity = 'E_WARNING';
|
880 |
+
break;
|
881 |
+
|
882 |
+
case E_NOTICE:
|
883 |
+
$severity = 'E_NOTICE';
|
884 |
+
break;
|
885 |
+
|
886 |
+
case E_USER_ERROR:
|
887 |
+
$severity = 'E_USER_ERROR';
|
888 |
+
break;
|
889 |
+
|
890 |
+
case E_USER_WARNING:
|
891 |
+
$severity = 'E_USER_WARNING';
|
892 |
+
break;
|
893 |
+
|
894 |
+
case E_USER_NOTICE:
|
895 |
+
$severity = 'E_USER_NOTICE';
|
896 |
+
break;
|
897 |
+
|
898 |
+
case E_STRICT:
|
899 |
+
$severity = 'E_STRICT';
|
900 |
+
break;
|
901 |
+
|
902 |
+
case E_RECOVERABLE_ERROR:
|
903 |
+
$severity = 'E_RECOVERABLE_ERROR';
|
904 |
+
break;
|
905 |
+
|
906 |
+
case E_DEPRECATED:
|
907 |
+
$severity = 'E_DEPRECATED';
|
908 |
+
break;
|
909 |
+
|
910 |
+
case E_USER_DEPRECATED:
|
911 |
+
$severity = 'E_USER_DEPRECATED';
|
912 |
+
break;
|
913 |
+
}
|
914 |
+
|
915 |
+
$object = array('Class' => get_class($object),
|
916 |
+
'Message' => $severity . ': ' . $object->getMessage(),
|
917 |
+
'File' => $this->_escapeTraceFile($object->getFile()),
|
918 |
+
'Line' => $object->getLine(),
|
919 |
+
'Type' => 'trigger',
|
920 |
+
'Trace' => $this->_escapeTrace(array_splice($trace, 2)));
|
921 |
+
$skipFinalObjectEncode = true;
|
922 |
+
} else {
|
923 |
+
$object = array('Class' => get_class($object),
|
924 |
+
'Message' => $object->getMessage(),
|
925 |
+
'File' => $this->_escapeTraceFile($object->getFile()),
|
926 |
+
'Line' => $object->getLine(),
|
927 |
+
'Type' => 'throw',
|
928 |
+
'Trace' => $this->_escapeTrace($trace));
|
929 |
+
$skipFinalObjectEncode = true;
|
930 |
+
}
|
931 |
+
$type = self::EXCEPTION;
|
932 |
+
|
933 |
+
} else if ($type == self::TRACE) {
|
934 |
+
|
935 |
+
$trace = debug_backtrace();
|
936 |
+
if (!$trace) return false;
|
937 |
+
for ($i = 0; $i < sizeof($trace); $i++) {
|
938 |
+
|
939 |
+
if (isset($trace[$i]['class'])
|
940 |
+
&& isset($trace[$i]['file'])
|
941 |
+
&& ($trace[$i]['class'] == 'FirePHP'
|
942 |
+
|| $trace[$i]['class'] == 'FB')
|
943 |
+
&& (substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php'
|
944 |
+
|| substr($this->_standardizePath($trace[$i]['file']), -29, 29) == 'FirePHPCore/FirePHP.class.php')) {
|
945 |
+
/* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
|
946 |
+
} else
|
947 |
+
if (isset($trace[$i]['class'])
|
948 |
+
&& isset($trace[$i+1]['file'])
|
949 |
+
&& $trace[$i]['class'] == 'FirePHP'
|
950 |
+
&& substr($this->_standardizePath($trace[$i + 1]['file']), -18, 18) == 'FirePHPCore/fb.php') {
|
951 |
+
/* Skip fb() */
|
952 |
+
} else
|
953 |
+
if ($trace[$i]['function'] == 'fb'
|
954 |
+
|| $trace[$i]['function'] == 'trace'
|
955 |
+
|| $trace[$i]['function'] == 'send') {
|
956 |
+
|
957 |
+
$object = array('Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '',
|
958 |
+
'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '',
|
959 |
+
'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '',
|
960 |
+
'Message' => $trace[$i]['args'][0],
|
961 |
+
'File' => isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : '',
|
962 |
+
'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '',
|
963 |
+
'Args' => isset($trace[$i]['args']) ? $this->encodeObject($trace[$i]['args']) : '',
|
964 |
+
'Trace' => $this->_escapeTrace(array_splice($trace, $i + 1)));
|
965 |
+
|
966 |
+
$skipFinalObjectEncode = true;
|
967 |
+
$meta['file'] = isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : '';
|
968 |
+
$meta['line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : '';
|
969 |
+
break;
|
970 |
+
}
|
971 |
+
}
|
972 |
+
|
973 |
+
} else
|
974 |
+
if ($type == self::TABLE) {
|
975 |
+
|
976 |
+
if (isset($object[0]) && is_string($object[0])) {
|
977 |
+
$object[1] = $this->encodeTable($object[1]);
|
978 |
+
} else {
|
979 |
+
$object = $this->encodeTable($object);
|
980 |
+
}
|
981 |
+
|
982 |
+
$skipFinalObjectEncode = true;
|
983 |
+
|
984 |
+
} else if ($type == self::GROUP_START) {
|
985 |
+
|
986 |
+
if (!$label) {
|
987 |
+
throw $this->newException('You must specify a label for the group!');
|
988 |
+
}
|
989 |
+
|
990 |
+
} else {
|
991 |
+
if ($type === null) {
|
992 |
+
$type = self::LOG;
|
993 |
+
}
|
994 |
+
}
|
995 |
+
|
996 |
+
if ($this->options['includeLineNumbers']) {
|
997 |
+
if (!isset($meta['file']) || !isset($meta['line'])) {
|
998 |
+
|
999 |
+
$trace = debug_backtrace();
|
1000 |
+
for ($i = 0; $trace && $i < sizeof($trace); $i++) {
|
1001 |
+
|
1002 |
+
if (isset($trace[$i]['class'])
|
1003 |
+
&& isset($trace[$i]['file'])
|
1004 |
+
&& ($trace[$i]['class'] == 'FirePHP'
|
1005 |
+
|| $trace[$i]['class'] == 'FB')
|
1006 |
+
&& (substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php'
|
1007 |
+
|| substr($this->_standardizePath($trace[$i]['file']), -29, 29) == 'FirePHPCore/FirePHP.class.php')) {
|
1008 |
+
/* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
|
1009 |
+
} else
|
1010 |
+
if (isset($trace[$i]['class'])
|
1011 |
+
&& isset($trace[$i + 1]['file'])
|
1012 |
+
&& $trace[$i]['class'] == 'FirePHP'
|
1013 |
+
&& substr($this->_standardizePath($trace[$i + 1]['file']), -18, 18) == 'FirePHPCore/fb.php') {
|
1014 |
+
/* Skip fb() */
|
1015 |
+
} else
|
1016 |
+
if (isset($trace[$i]['file'])
|
1017 |
+
&& substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php') {
|
1018 |
+
/* Skip FB::fb() */
|
1019 |
+
} else {
|
1020 |
+
$meta['file'] = isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : '';
|
1021 |
+
$meta['line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : '';
|
1022 |
+
break;
|
1023 |
+
}
|
1024 |
+
}
|
1025 |
+
}
|
1026 |
+
} else {
|
1027 |
+
unset($meta['file']);
|
1028 |
+
unset($meta['line']);
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
$this->setHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
|
1032 |
+
$this->setHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/' . self::VERSION);
|
1033 |
+
|
1034 |
+
$structureIndex = 1;
|
1035 |
+
if ($type == self::DUMP) {
|
1036 |
+
$structureIndex = 2;
|
1037 |
+
$this->setHeader('X-Wf-1-Structure-2', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
|
1038 |
+
} else {
|
1039 |
+
$this->setHeader('X-Wf-1-Structure-1', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
if ($type == self::DUMP) {
|
1043 |
+
$msg = '{"' . $label . '":' . $this->jsonEncode($object, $skipFinalObjectEncode) . '}';
|
1044 |
+
} else {
|
1045 |
+
$msgMeta = $options;
|
1046 |
+
$msgMeta['Type'] = $type;
|
1047 |
+
if ($label !== null) {
|
1048 |
+
$msgMeta['Label'] = $label;
|
1049 |
+
}
|
1050 |
+
if (isset($meta['file']) && !isset($msgMeta['File'])) {
|
1051 |
+
$msgMeta['File'] = $meta['file'];
|
1052 |
+
}
|
1053 |
+
if (isset($meta['line']) && !isset($msgMeta['Line'])) {
|
1054 |
+
$msgMeta['Line'] = $meta['line'];
|
1055 |
+
}
|
1056 |
+
$msg = '[' . $this->jsonEncode($msgMeta) . ',' . $this->jsonEncode($object, $skipFinalObjectEncode) . ']';
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
$parts = explode("\n", chunk_split($msg, 5000, "\n"));
|
1060 |
+
|
1061 |
+
for ($i = 0; $i < count($parts); $i++) {
|
1062 |
+
|
1063 |
+
$part = $parts[$i];
|
1064 |
+
if ($part) {
|
1065 |
+
|
1066 |
+
if (count($parts) > 2) {
|
1067 |
+
// Message needs to be split into multiple parts
|
1068 |
+
$this->setHeader('X-Wf-1-' . $structureIndex . '-' . '1-' . $this->messageIndex,
|
1069 |
+
(($i == 0) ? strlen($msg) : '')
|
1070 |
+
. '|' . $part . '|'
|
1071 |
+
. (($i < count($parts) - 2) ? '\\' : ''));
|
1072 |
+
} else {
|
1073 |
+
$this->setHeader('X-Wf-1-' . $structureIndex . '-' . '1-' . $this->messageIndex,
|
1074 |
+
strlen($part) . '|' . $part . '|');
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
$this->messageIndex++;
|
1078 |
+
|
1079 |
+
if ($this->messageIndex > 99999) {
|
1080 |
+
throw $this->newException('Maximum number (99,999) of messages reached!');
|
1081 |
+
}
|
1082 |
+
}
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
$this->setHeader('X-Wf-1-Index', $this->messageIndex - 1);
|
1086 |
+
|
1087 |
+
return true;
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
/**
|
1091 |
+
* Standardizes path for windows systems.
|
1092 |
+
*
|
1093 |
+
* @param string $path
|
1094 |
+
* @return string
|
1095 |
+
*/
|
1096 |
+
protected function _standardizePath($path)
|
1097 |
+
{
|
1098 |
+
return preg_replace('/\\\\+/', '/', $path);
|
1099 |
+
}
|
1100 |
+
|
1101 |
+
/**
|
1102 |
+
* Escape trace path for windows systems
|
1103 |
+
*
|
1104 |
+
* @param array $trace
|
1105 |
+
* @return array
|
1106 |
+
*/
|
1107 |
+
protected function _escapeTrace($trace)
|
1108 |
+
{
|
1109 |
+
if (!$trace) return $trace;
|
1110 |
+
for ($i = 0; $i < sizeof($trace); $i++) {
|
1111 |
+
if (isset($trace[$i]['file'])) {
|
1112 |
+
$trace[$i]['file'] = $this->_escapeTraceFile($trace[$i]['file']);
|
1113 |
+
}
|
1114 |
+
if (isset($trace[$i]['args'])) {
|
1115 |
+
$trace[$i]['args'] = $this->encodeObject($trace[$i]['args']);
|
1116 |
+
}
|
1117 |
+
}
|
1118 |
+
return $trace;
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
/**
|
1122 |
+
* Escape file information of trace for windows systems
|
1123 |
+
*
|
1124 |
+
* @param string $file
|
1125 |
+
* @return string
|
1126 |
+
*/
|
1127 |
+
protected function _escapeTraceFile($file)
|
1128 |
+
{
|
1129 |
+
/* Check if we have a windows filepath */
|
1130 |
+
if (strpos($file, '\\')) {
|
1131 |
+
/* First strip down to single \ */
|
1132 |
+
|
1133 |
+
$file = preg_replace('/\\\\+/', '\\', $file);
|
1134 |
+
|
1135 |
+
return $file;
|
1136 |
+
}
|
1137 |
+
return $file;
|
1138 |
+
}
|
1139 |
+
|
1140 |
+
/**
|
1141 |
+
* Check if headers have already been sent
|
1142 |
+
*
|
1143 |
+
* @param string $filename
|
1144 |
+
* @param integer $linenum
|
1145 |
+
*/
|
1146 |
+
protected function headersSent(&$filename, &$linenum)
|
1147 |
+
{
|
1148 |
+
return headers_sent($filename, $linenum);
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
/**
|
1152 |
+
* Send header
|
1153 |
+
*
|
1154 |
+
* @param string $name
|
1155 |
+
* @param string $value
|
1156 |
+
*/
|
1157 |
+
protected function setHeader($name, $value)
|
1158 |
+
{
|
1159 |
+
return header($name . ': ' . $value);
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
/**
|
1163 |
+
* Get user agent
|
1164 |
+
*
|
1165 |
+
* @return string|false
|
1166 |
+
*/
|
1167 |
+
protected function getUserAgent()
|
1168 |
+
{
|
1169 |
+
if (!isset($_SERVER['HTTP_USER_AGENT'])) return false;
|
1170 |
+
return $_SERVER['HTTP_USER_AGENT'];
|
1171 |
+
}
|
1172 |
+
|
1173 |
+
/**
|
1174 |
+
* Get all request headers
|
1175 |
+
*
|
1176 |
+
* @return array
|
1177 |
+
*/
|
1178 |
+
public static function getAllRequestHeaders()
|
1179 |
+
{
|
1180 |
+
static $_cachedHeaders = false;
|
1181 |
+
if ($_cachedHeaders !== false) {
|
1182 |
+
return $_cachedHeaders;
|
1183 |
+
}
|
1184 |
+
$headers = array();
|
1185 |
+
if (function_exists('getallheaders')) {
|
1186 |
+
foreach (getallheaders() as $name => $value) {
|
1187 |
+
$headers[strtolower($name)] = $value;
|
1188 |
+
}
|
1189 |
+
} else {
|
1190 |
+
foreach ($_SERVER as $name => $value) {
|
1191 |
+
if (substr($name, 0, 5) == 'HTTP_') {
|
1192 |
+
$headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value;
|
1193 |
+
}
|
1194 |
+
}
|
1195 |
+
}
|
1196 |
+
return $_cachedHeaders = $headers;
|
1197 |
+
}
|
1198 |
+
|
1199 |
+
/**
|
1200 |
+
* Get a request header
|
1201 |
+
*
|
1202 |
+
* @return string|false
|
1203 |
+
*/
|
1204 |
+
protected function getRequestHeader($name)
|
1205 |
+
{
|
1206 |
+
$headers = self::getAllRequestHeaders();
|
1207 |
+
if (isset($headers[strtolower($name)])) {
|
1208 |
+
return $headers[strtolower($name)];
|
1209 |
+
}
|
1210 |
+
return false;
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
/**
|
1214 |
+
* Returns a new exception
|
1215 |
+
*
|
1216 |
+
* @param string $message
|
1217 |
+
* @return Exception
|
1218 |
+
*/
|
1219 |
+
protected function newException($message)
|
1220 |
+
{
|
1221 |
+
return new Exception($message);
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
/**
|
1225 |
+
* Encode an object into a JSON string
|
1226 |
+
*
|
1227 |
+
* Uses PHP's jeson_encode() if available
|
1228 |
+
*
|
1229 |
+
* @param object $object The object to be encoded
|
1230 |
+
* @param boolean $skipObjectEncode
|
1231 |
+
* @return string The JSON string
|
1232 |
+
*/
|
1233 |
+
public function jsonEncode($object, $skipObjectEncode = false)
|
1234 |
+
{
|
1235 |
+
if (!$skipObjectEncode) {
|
1236 |
+
$object = $this->encodeObject($object);
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
if (function_exists('json_encode')
|
1240 |
+
&& $this->options['useNativeJsonEncode'] != false) {
|
1241 |
+
|
1242 |
+
return json_encode($object);
|
1243 |
+
} else {
|
1244 |
+
return $this->json_encode($object);
|
1245 |
+
}
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
/**
|
1249 |
+
* Encodes a table by encoding each row and column with encodeObject()
|
1250 |
+
*
|
1251 |
+
* @param array $table The table to be encoded
|
1252 |
+
* @return array
|
1253 |
+
*/
|
1254 |
+
protected function encodeTable($table)
|
1255 |
+
{
|
1256 |
+
if (!$table) return $table;
|
1257 |
+
|
1258 |
+
$newTable = array();
|
1259 |
+
foreach ($table as $row) {
|
1260 |
+
|
1261 |
+
if (is_array($row)) {
|
1262 |
+
$newRow = array();
|
1263 |
+
|
1264 |
+
foreach ($row as $item) {
|
1265 |
+
$newRow[] = $this->encodeObject($item);
|
1266 |
+
}
|
1267 |
+
|
1268 |
+
$newTable[] = $newRow;
|
1269 |
+
}
|
1270 |
+
}
|
1271 |
+
|
1272 |
+
return $newTable;
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
/**
|
1276 |
+
* Encodes an object including members with
|
1277 |
+
* protected and private visibility
|
1278 |
+
*
|
1279 |
+
* @param object $object The object to be encoded
|
1280 |
+
* @param integer $Depth The current traversal depth
|
1281 |
+
* @return array All members of the object
|
1282 |
+
*/
|
1283 |
+
protected function encodeObject($object, $objectDepth = 1, $arrayDepth = 1, $maxDepth = 1)
|
1284 |
+
{
|
1285 |
+
if ($maxDepth > $this->options['maxDepth']) {
|
1286 |
+
return '** Max Depth (' . $this->options['maxDepth'] . ') **';
|
1287 |
+
}
|
1288 |
+
|
1289 |
+
$return = array();
|
1290 |
+
|
1291 |
+
if (is_resource($object)) {
|
1292 |
+
|
1293 |
+
return '** ' . (string) $object . ' **';
|
1294 |
+
|
1295 |
+
} else if (is_object($object)) {
|
1296 |
+
|
1297 |
+
if ($objectDepth > $this->options['maxObjectDepth']) {
|
1298 |
+
return '** Max Object Depth (' . $this->options['maxObjectDepth'] . ') **';
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
foreach ($this->objectStack as $refVal) {
|
1302 |
+
if ($refVal === $object) {
|
1303 |
+
return '** Recursion (' . get_class($object) . ') **';
|
1304 |
+
}
|
1305 |
+
}
|
1306 |
+
array_push($this->objectStack, $object);
|
1307 |
+
|
1308 |
+
$return['__className'] = $class = get_class($object);
|
1309 |
+
$classLower = strtolower($class);
|
1310 |
+
|
1311 |
+
$reflectionClass = new ReflectionClass($class);
|
1312 |
+
$properties = array();
|
1313 |
+
foreach ($reflectionClass->getProperties() as $property) {
|
1314 |
+
$properties[$property->getName()] = $property;
|
1315 |
+
}
|
1316 |
+
|
1317 |
+
$members = (array)$object;
|
1318 |
+
|
1319 |
+
foreach ($properties as $plainName => $property) {
|
1320 |
+
|
1321 |
+
$name = $rawName = $plainName;
|
1322 |
+
if ($property->isStatic()) {
|
1323 |
+
$name = 'static:' . $name;
|
1324 |
+
}
|
1325 |
+
if ($property->isPublic()) {
|
1326 |
+
$name = 'public:' . $name;
|
1327 |
+
} else if ($property->isPrivate()) {
|
1328 |
+
$name = 'private:' . $name;
|
1329 |
+
$rawName = "\0" . $class . "\0" . $rawName;
|
1330 |
+
} else if ($property->isProtected()) {
|
1331 |
+
$name = 'protected:' . $name;
|
1332 |
+
$rawName = "\0" . '*' . "\0" . $rawName;
|
1333 |
+
}
|
1334 |
+
|
1335 |
+
if (!(isset($this->objectFilters[$classLower])
|
1336 |
+
&& is_array($this->objectFilters[$classLower])
|
1337 |
+
&& in_array($plainName, $this->objectFilters[$classLower]))) {
|
1338 |
+
|
1339 |
+
if (array_key_exists($rawName, $members) && !$property->isStatic()) {
|
1340 |
+
$return[$name] = $this->encodeObject($members[$rawName], $objectDepth + 1, 1, $maxDepth + 1);
|
1341 |
+
} else {
|
1342 |
+
if (method_exists($property, 'setAccessible')) {
|
1343 |
+
$property->setAccessible(true);
|
1344 |
+
$return[$name] = $this->encodeObject($property->getValue($object), $objectDepth + 1, 1, $maxDepth + 1);
|
1345 |
+
} else
|
1346 |
+
if ($property->isPublic()) {
|
1347 |
+
$return[$name] = $this->encodeObject($property->getValue($object), $objectDepth + 1, 1, $maxDepth + 1);
|
1348 |
+
} else {
|
1349 |
+
$return[$name] = '** Need PHP 5.3 to get value **';
|
1350 |
+
}
|
1351 |
+
}
|
1352 |
+
} else {
|
1353 |
+
$return[$name] = '** Excluded by Filter **';
|
1354 |
+
}
|
1355 |
+
}
|
1356 |
+
|
1357 |
+
// Include all members that are not defined in the class
|
1358 |
+
// but exist in the object
|
1359 |
+
foreach ($members as $rawName => $value) {
|
1360 |
+
|
1361 |
+
$name = $rawName;
|
1362 |
+
|
1363 |
+
if ($name{0} == "\0") {
|
1364 |
+
$parts = explode("\0", $name);
|
1365 |
+
$name = $parts[2];
|
1366 |
+
}
|
1367 |
+
|
1368 |
+
$plainName = $name;
|
1369 |
+
|
1370 |
+
if (!isset($properties[$name])) {
|
1371 |
+
$name = 'undeclared:' . $name;
|
1372 |
+
|
1373 |
+
if (!(isset($this->objectFilters[$classLower])
|
1374 |
+
&& is_array($this->objectFilters[$classLower])
|
1375 |
+
&& in_array($plainName, $this->objectFilters[$classLower]))) {
|
1376 |
+
|
1377 |
+
$return[$name] = $this->encodeObject($value, $objectDepth + 1, 1, $maxDepth + 1);
|
1378 |
+
} else {
|
1379 |
+
$return[$name] = '** Excluded by Filter **';
|
1380 |
+
}
|
1381 |
+
}
|
1382 |
+
}
|
1383 |
+
|
1384 |
+
array_pop($this->objectStack);
|
1385 |
+
|
1386 |
+
} elseif (is_array($object)) {
|
1387 |
+
|
1388 |
+
if ($arrayDepth > $this->options['maxArrayDepth']) {
|
1389 |
+
return '** Max Array Depth (' . $this->options['maxArrayDepth'] . ') **';
|
1390 |
+
}
|
1391 |
+
|
1392 |
+
foreach ($object as $key => $val) {
|
1393 |
+
|
1394 |
+
// Encoding the $GLOBALS PHP array causes an infinite loop
|
1395 |
+
// if the recursion is not reset here as it contains
|
1396 |
+
// a reference to itself. This is the only way I have come up
|
1397 |
+
// with to stop infinite recursion in this case.
|
1398 |
+
if ($key == 'GLOBALS'
|
1399 |
+
&& is_array($val)
|
1400 |
+
&& array_key_exists('GLOBALS', $val)) {
|
1401 |
+
$val['GLOBALS'] = '** Recursion (GLOBALS) **';
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
if (!$this->is_utf8($key)) {
|
1405 |
+
$key = utf8_encode($key);
|
1406 |
+
}
|
1407 |
+
|
1408 |
+
$return[$key] = $this->encodeObject($val, 1, $arrayDepth + 1, $maxDepth + 1);
|
1409 |
+
}
|
1410 |
+
} else {
|
1411 |
+
if ($this->is_utf8($object)) {
|
1412 |
+
return $object;
|
1413 |
+
} else {
|
1414 |
+
return utf8_encode($object);
|
1415 |
+
}
|
1416 |
+
}
|
1417 |
+
return $return;
|
1418 |
+
}
|
1419 |
+
|
1420 |
+
/**
|
1421 |
+
* Returns true if $string is valid UTF-8 and false otherwise.
|
1422 |
+
*
|
1423 |
+
* @param mixed $str String to be tested
|
1424 |
+
* @return boolean
|
1425 |
+
*/
|
1426 |
+
protected function is_utf8($str)
|
1427 |
+
{
|
1428 |
+
if (function_exists('mb_detect_encoding')) {
|
1429 |
+
return (
|
1430 |
+
mb_detect_encoding($str, 'UTF-8', true) == 'UTF-8' &&
|
1431 |
+
($str === null || $this->jsonEncode($str, true) !== 'null')
|
1432 |
+
);
|
1433 |
+
}
|
1434 |
+
$c = 0;
|
1435 |
+
$b = 0;
|
1436 |
+
$bits = 0;
|
1437 |
+
$len = strlen($str);
|
1438 |
+
for ($i = 0; $i < $len; $i++) {
|
1439 |
+
$c = ord($str[$i]);
|
1440 |
+
if ($c > 128) {
|
1441 |
+
if (($c >= 254)) return false;
|
1442 |
+
elseif ($c >= 252) $bits = 6;
|
1443 |
+
elseif ($c >= 248) $bits = 5;
|
1444 |
+
elseif ($c >= 240) $bits = 4;
|
1445 |
+
elseif ($c >= 224) $bits = 3;
|
1446 |
+
elseif ($c >= 192) $bits = 2;
|
1447 |
+
else return false;
|
1448 |
+
if (($i + $bits) > $len) return false;
|
1449 |
+
while($bits > 1) {
|
1450 |
+
$i++;
|
1451 |
+
$b = ord($str[$i]);
|
1452 |
+
if ($b < 128 || $b > 191) return false;
|
1453 |
+
$bits--;
|
1454 |
+
}
|
1455 |
+
}
|
1456 |
+
}
|
1457 |
+
return ($str === null || $this->jsonEncode($str, true) !== 'null');
|
1458 |
+
}
|
1459 |
+
|
1460 |
+
/**
|
1461 |
+
* Converts to and from JSON format.
|
1462 |
+
*
|
1463 |
+
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
1464 |
+
* format. It is easy for humans to read and write. It is easy for machines
|
1465 |
+
* to parse and generate. It is based on a subset of the JavaScript
|
1466 |
+
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
1467 |
+
* This feature can also be found in Python. JSON is a text format that is
|
1468 |
+
* completely language independent but uses conventions that are familiar
|
1469 |
+
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
1470 |
+
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
1471 |
+
* ideal data-interchange language.
|
1472 |
+
*
|
1473 |
+
* This package provides a simple encoder and decoder for JSON notation. It
|
1474 |
+
* is intended for use with client-side Javascript applications that make
|
1475 |
+
* use of HTTPRequest to perform server communication functions - data can
|
1476 |
+
* be encoded into JSON notation for use in a client-side javascript, or
|
1477 |
+
* decoded from incoming Javascript requests. JSON format is native to
|
1478 |
+
* Javascript, and can be directly eval()'ed with no further parsing
|
1479 |
+
* overhead
|
1480 |
+
*
|
1481 |
+
* All strings should be in ASCII or UTF-8 format!
|
1482 |
+
*
|
1483 |
+
* LICENSE: Redistribution and use in source and binary forms, with or
|
1484 |
+
* without modification, are permitted provided that the following
|
1485 |
+
* conditions are met: Redistributions of source code must retain the
|
1486 |
+
* above copyright notice, this list of conditions and the following
|
1487 |
+
* disclaimer. Redistributions in binary form must reproduce the above
|
1488 |
+
* copyright notice, this list of conditions and the following disclaimer
|
1489 |
+
* in the documentation and/or other materials provided with the
|
1490 |
+
* distribution.
|
1491 |
+
*
|
1492 |
+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
1493 |
+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
1494 |
+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
1495 |
+
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
1496 |
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
1497 |
+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
1498 |
+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
1499 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
1500 |
+
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
1501 |
+
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
1502 |
+
* DAMAGE.
|
1503 |
+
*
|
1504 |
+
* @category
|
1505 |
+
* @package Services_JSON
|
1506 |
+
* @author Michal Migurski <mike-json@teczno.com>
|
1507 |
+
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
1508 |
+
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
1509 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
1510 |
+
* @copyright 2005 Michal Migurski
|
1511 |
+
* @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
|
1512 |
+
* @license http://www.opensource.org/licenses/bsd-license.php
|
1513 |
+
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
1514 |
+
*/
|
1515 |
+
|
1516 |
+
|
1517 |
+
/**
|
1518 |
+
* Keep a list of objects as we descend into the array so we can detect recursion.
|
1519 |
+
*/
|
1520 |
+
private $json_objectStack = array();
|
1521 |
+
|
1522 |
+
|
1523 |
+
/**
|
1524 |
+
* convert a string from one UTF-8 char to one UTF-16 char
|
1525 |
+
*
|
1526 |
+
* Normally should be handled by mb_convert_encoding, but
|
1527 |
+
* provides a slower PHP-only method for installations
|
1528 |
+
* that lack the multibye string extension.
|
1529 |
+
*
|
1530 |
+
* @param string $utf8 UTF-8 character
|
1531 |
+
* @return string UTF-16 character
|
1532 |
+
* @access private
|
1533 |
+
*/
|
1534 |
+
private function json_utf82utf16($utf8)
|
1535 |
+
{
|
1536 |
+
// oh please oh please oh please oh please oh please
|
1537 |
+
if (function_exists('mb_convert_encoding')) {
|
1538 |
+
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
1539 |
+
}
|
1540 |
+
|
1541 |
+
switch (strlen($utf8)) {
|
1542 |
+
case 1:
|
1543 |
+
// this case should never be reached, because we are in ASCII range
|
1544 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1545 |
+
return $utf8;
|
1546 |
+
|
1547 |
+
case 2:
|
1548 |
+
// return a UTF-16 character from a 2-byte UTF-8 char
|
1549 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1550 |
+
return chr(0x07 & (ord($utf8{0}) >> 2))
|
1551 |
+
. chr((0xC0 & (ord($utf8{0}) << 6))
|
1552 |
+
| (0x3F & ord($utf8{1})));
|
1553 |
+
|
1554 |
+
case 3:
|
1555 |
+
// return a UTF-16 character from a 3-byte UTF-8 char
|
1556 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1557 |
+
return chr((0xF0 & (ord($utf8{0}) << 4))
|
1558 |
+
| (0x0F & (ord($utf8{1}) >> 2)))
|
1559 |
+
. chr((0xC0 & (ord($utf8{1}) << 6))
|
1560 |
+
| (0x7F & ord($utf8{2})));
|
1561 |
+
}
|
1562 |
+
|
1563 |
+
// ignoring UTF-32 for now, sorry
|
1564 |
+
return '';
|
1565 |
+
}
|
1566 |
+
|
1567 |
+
/**
|
1568 |
+
* encodes an arbitrary variable into JSON format
|
1569 |
+
*
|
1570 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
1571 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
1572 |
+
* if var is a strng, note that encode() always expects it
|
1573 |
+
* to be in ASCII or UTF-8 format!
|
1574 |
+
*
|
1575 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
1576 |
+
* @access public
|
1577 |
+
*/
|
1578 |
+
private function json_encode($var)
|
1579 |
+
{
|
1580 |
+
if (is_object($var)) {
|
1581 |
+
if (in_array($var, $this->json_objectStack)) {
|
1582 |
+
return '"** Recursion **"';
|
1583 |
+
}
|
1584 |
+
}
|
1585 |
+
|
1586 |
+
switch (gettype($var)) {
|
1587 |
+
case 'boolean':
|
1588 |
+
return $var ? 'true' : 'false';
|
1589 |
+
|
1590 |
+
case 'NULL':
|
1591 |
+
return 'null';
|
1592 |
+
|
1593 |
+
case 'integer':
|
1594 |
+
return (int) $var;
|
1595 |
+
|
1596 |
+
case 'double':
|
1597 |
+
case 'float':
|
1598 |
+
return (float) $var;
|
1599 |
+
|
1600 |
+
case 'string':
|
1601 |
+
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
1602 |
+
$ascii = '';
|
1603 |
+
$strlen_var = strlen($var);
|
1604 |
+
|
1605 |
+
/*
|
1606 |
+
* Iterate over every character in the string,
|
1607 |
+
* escaping with a slash or encoding to UTF-8 where necessary
|
1608 |
+
*/
|
1609 |
+
for ($c = 0; $c < $strlen_var; ++$c) {
|
1610 |
+
|
1611 |
+
$ord_var_c = ord($var{$c});
|
1612 |
+
|
1613 |
+
switch (true) {
|
1614 |
+
case $ord_var_c == 0x08:
|
1615 |
+
$ascii .= '\b';
|
1616 |
+
break;
|
1617 |
+
case $ord_var_c == 0x09:
|
1618 |
+
$ascii .= '\t';
|
1619 |
+
break;
|
1620 |
+
case $ord_var_c == 0x0A:
|
1621 |
+
$ascii .= '\n';
|
1622 |
+
break;
|
1623 |
+
case $ord_var_c == 0x0C:
|
1624 |
+
$ascii .= '\f';
|
1625 |
+
break;
|
1626 |
+
case $ord_var_c == 0x0D:
|
1627 |
+
$ascii .= '\r';
|
1628 |
+
break;
|
1629 |
+
|
1630 |
+
case $ord_var_c == 0x22:
|
1631 |
+
case $ord_var_c == 0x2F:
|
1632 |
+
case $ord_var_c == 0x5C:
|
1633 |
+
// double quote, slash, slosh
|
1634 |
+
$ascii .= '\\' . $var{$c};
|
1635 |
+
break;
|
1636 |
+
|
1637 |
+
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
1638 |
+
// characters U-00000000 - U-0000007F (same as ASCII)
|
1639 |
+
$ascii .= $var{$c};
|
1640 |
+
break;
|
1641 |
+
|
1642 |
+
case (($ord_var_c & 0xE0) == 0xC0):
|
1643 |
+
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
1644 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1645 |
+
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
1646 |
+
$c += 1;
|
1647 |
+
$utf16 = $this->json_utf82utf16($char);
|
1648 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1649 |
+
break;
|
1650 |
+
|
1651 |
+
case (($ord_var_c & 0xF0) == 0xE0):
|
1652 |
+
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
1653 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1654 |
+
$char = pack('C*', $ord_var_c,
|
1655 |
+
ord($var{$c + 1}),
|
1656 |
+
ord($var{$c + 2}));
|
1657 |
+
$c += 2;
|
1658 |
+
$utf16 = $this->json_utf82utf16($char);
|
1659 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1660 |
+
break;
|
1661 |
+
|
1662 |
+
case (($ord_var_c & 0xF8) == 0xF0):
|
1663 |
+
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
1664 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1665 |
+
$char = pack('C*', $ord_var_c,
|
1666 |
+
ord($var{$c + 1}),
|
1667 |
+
ord($var{$c + 2}),
|
1668 |
+
ord($var{$c + 3}));
|
1669 |
+
$c += 3;
|
1670 |
+
$utf16 = $this->json_utf82utf16($char);
|
1671 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1672 |
+
break;
|
1673 |
+
|
1674 |
+
case (($ord_var_c & 0xFC) == 0xF8):
|
1675 |
+
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
1676 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1677 |
+
$char = pack('C*', $ord_var_c,
|
1678 |
+
ord($var{$c + 1}),
|
1679 |
+
ord($var{$c + 2}),
|
1680 |
+
ord($var{$c + 3}),
|
1681 |
+
ord($var{$c + 4}));
|
1682 |
+
$c += 4;
|
1683 |
+
$utf16 = $this->json_utf82utf16($char);
|
1684 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1685 |
+
break;
|
1686 |
+
|
1687 |
+
case (($ord_var_c & 0xFE) == 0xFC):
|
1688 |
+
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
1689 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1690 |
+
$char = pack('C*', $ord_var_c,
|
1691 |
+
ord($var{$c + 1}),
|
1692 |
+
ord($var{$c + 2}),
|
1693 |
+
ord($var{$c + 3}),
|
1694 |
+
ord($var{$c + 4}),
|
1695 |
+
ord($var{$c + 5}));
|
1696 |
+
$c += 5;
|
1697 |
+
$utf16 = $this->json_utf82utf16($char);
|
1698 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1699 |
+
break;
|
1700 |
+
}
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
return '"' . $ascii . '"';
|
1704 |
+
|
1705 |
+
case 'array':
|
1706 |
+
/*
|
1707 |
+
* As per JSON spec if any array key is not an integer
|
1708 |
+
* we must treat the the whole array as an object. We
|
1709 |
+
* also try to catch a sparsely populated associative
|
1710 |
+
* array with numeric keys here because some JS engines
|
1711 |
+
* will create an array with empty indexes up to
|
1712 |
+
* max_index which can cause memory issues and because
|
1713 |
+
* the keys, which may be relevant, will be remapped
|
1714 |
+
* otherwise.
|
1715 |
+
*
|
1716 |
+
* As per the ECMA and JSON specification an object may
|
1717 |
+
* have any string as a property. Unfortunately due to
|
1718 |
+
* a hole in the ECMA specification if the key is a
|
1719 |
+
* ECMA reserved word or starts with a digit the
|
1720 |
+
* parameter is only accessible using ECMAScript's
|
1721 |
+
* bracket notation.
|
1722 |
+
*/
|
1723 |
+
|
1724 |
+
// treat as a JSON object
|
1725 |
+
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
1726 |
+
|
1727 |
+
$this->json_objectStack[] = $var;
|
1728 |
+
|
1729 |
+
$properties = array_map(array($this, 'json_name_value'),
|
1730 |
+
array_keys($var),
|
1731 |
+
array_values($var));
|
1732 |
+
|
1733 |
+
array_pop($this->json_objectStack);
|
1734 |
+
|
1735 |
+
foreach ($properties as $property) {
|
1736 |
+
if ($property instanceof Exception) {
|
1737 |
+
return $property;
|
1738 |
+
}
|
1739 |
+
}
|
1740 |
+
|
1741 |
+
return '{' . join(',', $properties) . '}';
|
1742 |
+
}
|
1743 |
+
|
1744 |
+
$this->json_objectStack[] = $var;
|
1745 |
+
|
1746 |
+
// treat it like a regular array
|
1747 |
+
$elements = array_map(array($this, 'json_encode'), $var);
|
1748 |
+
|
1749 |
+
array_pop($this->json_objectStack);
|
1750 |
+
|
1751 |
+
foreach ($elements as $element) {
|
1752 |
+
if ($element instanceof Exception) {
|
1753 |
+
return $element;
|
1754 |
+
}
|
1755 |
+
}
|
1756 |
+
|
1757 |
+
return '[' . join(',', $elements) . ']';
|
1758 |
+
|
1759 |
+
case 'object':
|
1760 |
+
$vars = self::encodeObject($var);
|
1761 |
+
|
1762 |
+
$this->json_objectStack[] = $var;
|
1763 |
+
|
1764 |
+
$properties = array_map(array($this, 'json_name_value'),
|
1765 |
+
array_keys($vars),
|
1766 |
+
array_values($vars));
|
1767 |
+
|
1768 |
+
array_pop($this->json_objectStack);
|
1769 |
+
|
1770 |
+
foreach ($properties as $property) {
|
1771 |
+
if ($property instanceof Exception) {
|
1772 |
+
return $property;
|
1773 |
+
}
|
1774 |
+
}
|
1775 |
+
|
1776 |
+
return '{' . join(',', $properties) . '}';
|
1777 |
+
|
1778 |
+
default:
|
1779 |
+
return null;
|
1780 |
+
}
|
1781 |
+
}
|
1782 |
+
|
1783 |
+
/**
|
1784 |
+
* array-walking function for use in generating JSON-formatted name-value pairs
|
1785 |
+
*
|
1786 |
+
* @param string $name name of key to use
|
1787 |
+
* @param mixed $value reference to an array element to be encoded
|
1788 |
+
*
|
1789 |
+
* @return string JSON-formatted name-value pair, like '"name":value'
|
1790 |
+
* @access private
|
1791 |
+
*/
|
1792 |
+
private function json_name_value($name, $value)
|
1793 |
+
{
|
1794 |
+
// Encoding the $GLOBALS PHP array causes an infinite loop
|
1795 |
+
// if the recursion is not reset here as it contains
|
1796 |
+
// a reference to itself. This is the only way I have come up
|
1797 |
+
// with to stop infinite recursion in this case.
|
1798 |
+
if ($name == 'GLOBALS'
|
1799 |
+
&& is_array($value)
|
1800 |
+
&& array_key_exists('GLOBALS', $value)) {
|
1801 |
+
$value['GLOBALS'] = '** Recursion **';
|
1802 |
+
}
|
1803 |
+
|
1804 |
+
$encodedValue = $this->json_encode($value);
|
1805 |
+
|
1806 |
+
if ($encodedValue instanceof Exception) {
|
1807 |
+
return $encodedValue;
|
1808 |
+
}
|
1809 |
+
|
1810 |
+
return $this->json_encode(strval($name)) . ':' . $encodedValue;
|
1811 |
+
}
|
1812 |
+
|
1813 |
+
/**
|
1814 |
+
* @deprecated
|
1815 |
+
*/
|
1816 |
+
public function setProcessorUrl($URL)
|
1817 |
+
{
|
1818 |
+
trigger_error('The FirePHP::setProcessorUrl() method is no longer supported', E_USER_DEPRECATED);
|
1819 |
+
}
|
1820 |
+
|
1821 |
+
/**
|
1822 |
+
* @deprecated
|
1823 |
+
*/
|
1824 |
+
public function setRendererUrl($URL)
|
1825 |
+
{
|
1826 |
+
trigger_error('The FirePHP::setRendererUrl() method is no longer supported', E_USER_DEPRECATED);
|
1827 |
+
}
|
1828 |
+
}
|
includes/debug/browsers/api/firephp/lib/FirePHPCore/FirePHP.class.php4
ADDED
@@ -0,0 +1,1327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - qbbr, Michael Day <manveru.alma@gmail.com>, Copyright 2008, New BSD License
|
5 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
6 |
+
|
7 |
+
/**
|
8 |
+
* *** BEGIN LICENSE BLOCK *****
|
9 |
+
*
|
10 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
11 |
+
*
|
12 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
13 |
+
*
|
14 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 |
+
* of this software and associated documentation files (the "Software"), to deal
|
16 |
+
* in the Software without restriction, including without limitation the rights
|
17 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18 |
+
* copies of the Software, and to permit persons to whom the Software is
|
19 |
+
* furnished to do so, subject to the following conditions:
|
20 |
+
*
|
21 |
+
* The above copyright notice and this permission notice shall be included in
|
22 |
+
* all copies or substantial portions of the Software.
|
23 |
+
*
|
24 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
25 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
26 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
27 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
28 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
29 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
30 |
+
* THE SOFTWARE.
|
31 |
+
*
|
32 |
+
* ***** END LICENSE BLOCK *****
|
33 |
+
*
|
34 |
+
* This verion of FirePHPCore is for use with PHP4. If you do not require PHP4
|
35 |
+
* compatibility, it is suggested you use FirePHPCore.class.php instead.
|
36 |
+
*
|
37 |
+
* @copyright Copyright (C) 2007+ Christoph Dorn
|
38 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
39 |
+
* @author Michael Day <manveru.alma@gmail.com>
|
40 |
+
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
41 |
+
* @package FirePHPCore
|
42 |
+
*/
|
43 |
+
|
44 |
+
/**
|
45 |
+
* FirePHP version
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
define('FirePHP_VERSION', '0.3'); // @pinf replace '0.3' with '%%VERSION%%'
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Firebug LOG level
|
53 |
+
*
|
54 |
+
* Logs a message to firebug console
|
55 |
+
*
|
56 |
+
* @var string
|
57 |
+
*/
|
58 |
+
define('FirePHP_LOG', 'LOG');
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Firebug INFO level
|
62 |
+
*
|
63 |
+
* Logs a message to firebug console and displays an info icon before the message
|
64 |
+
*
|
65 |
+
* @var string
|
66 |
+
*/
|
67 |
+
define('FirePHP_INFO', 'INFO');
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Firebug WARN level
|
71 |
+
*
|
72 |
+
* Logs a message to firebug console, displays a warning icon before the message and colors the line turquoise
|
73 |
+
*
|
74 |
+
* @var string
|
75 |
+
*/
|
76 |
+
define('FirePHP_WARN', 'WARN');
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Firebug ERROR level
|
80 |
+
*
|
81 |
+
* Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count.
|
82 |
+
*
|
83 |
+
* @var string
|
84 |
+
*/
|
85 |
+
define('FirePHP_ERROR', 'ERROR');
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Dumps a variable to firebug's server panel
|
89 |
+
*
|
90 |
+
* @var string
|
91 |
+
*/
|
92 |
+
define('FirePHP_DUMP', 'DUMP');
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Displays a stack trace in firebug console
|
96 |
+
*
|
97 |
+
* @var string
|
98 |
+
*/
|
99 |
+
define('FirePHP_TRACE', 'TRACE');
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Displays a table in firebug console
|
103 |
+
*
|
104 |
+
* @var string
|
105 |
+
*/
|
106 |
+
define('FirePHP_TABLE', 'TABLE');
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Starts a group in firebug console
|
110 |
+
*
|
111 |
+
* @var string
|
112 |
+
*/
|
113 |
+
define('FirePHP_GROUP_START', 'GROUP_START');
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Ends a group in firebug console
|
117 |
+
*
|
118 |
+
* @var string
|
119 |
+
*/
|
120 |
+
define('FirePHP_GROUP_END', 'GROUP_END');
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Sends the given data to the FirePHP Firefox Extension.
|
124 |
+
* The data can be displayed in the Firebug Console or in the
|
125 |
+
* "Server" request tab.
|
126 |
+
*
|
127 |
+
* For more information see: http://www.firephp.org/
|
128 |
+
*
|
129 |
+
* @copyright Copyright (C) 2007+ Christoph Dorn
|
130 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
131 |
+
* @author Michael Day <manveru.alma@gmail.com>
|
132 |
+
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
133 |
+
* @package FirePHPCore
|
134 |
+
*/
|
135 |
+
class FirePHP {
|
136 |
+
/**
|
137 |
+
* Wildfire protocol message index
|
138 |
+
*
|
139 |
+
* @var int
|
140 |
+
*/
|
141 |
+
var $messageIndex = 1;
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Options for the library
|
145 |
+
*
|
146 |
+
* @var array
|
147 |
+
*/
|
148 |
+
var $options = array('maxObjectDepth' => 5,
|
149 |
+
'maxArrayDepth' => 5,
|
150 |
+
'useNativeJsonEncode' => true,
|
151 |
+
'includeLineNumbers' => true);
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Filters used to exclude object members when encoding
|
155 |
+
*
|
156 |
+
* @var array
|
157 |
+
*/
|
158 |
+
var $objectFilters = array();
|
159 |
+
|
160 |
+
/**
|
161 |
+
* A stack of objects used to detect recursion during object encoding
|
162 |
+
*
|
163 |
+
* @var object
|
164 |
+
*/
|
165 |
+
var $objectStack = array();
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Flag to enable/disable logging
|
169 |
+
*
|
170 |
+
* @var boolean
|
171 |
+
*/
|
172 |
+
var $enabled = true;
|
173 |
+
|
174 |
+
/**
|
175 |
+
* The object constructor
|
176 |
+
*/
|
177 |
+
function FirePHP() {
|
178 |
+
}
|
179 |
+
|
180 |
+
|
181 |
+
/**
|
182 |
+
* When the object gets serialized only include specific object members.
|
183 |
+
*
|
184 |
+
* @return array
|
185 |
+
*/
|
186 |
+
function __sleep() {
|
187 |
+
return array('options','objectFilters','enabled');
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Gets singleton instance of FirePHP
|
192 |
+
*
|
193 |
+
* @param boolean $AutoCreate
|
194 |
+
* @return FirePHP
|
195 |
+
*/
|
196 |
+
function &getInstance($AutoCreate=false) {
|
197 |
+
global $FirePHP_Instance;
|
198 |
+
|
199 |
+
if($AutoCreate===true && !$FirePHP_Instance) {
|
200 |
+
$FirePHP_Instance = new FirePHP();
|
201 |
+
}
|
202 |
+
|
203 |
+
return $FirePHP_Instance;
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Enable and disable logging to Firebug
|
208 |
+
*
|
209 |
+
* @param boolean $Enabled TRUE to enable, FALSE to disable
|
210 |
+
* @return void
|
211 |
+
*/
|
212 |
+
function setEnabled($Enabled) {
|
213 |
+
$this->enabled = $Enabled;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Check if logging is enabled
|
218 |
+
*
|
219 |
+
* @return boolean TRUE if enabled
|
220 |
+
*/
|
221 |
+
function getEnabled() {
|
222 |
+
return $this->enabled;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Specify a filter to be used when encoding an object
|
227 |
+
*
|
228 |
+
* Filters are used to exclude object members.
|
229 |
+
*
|
230 |
+
* @param string $Class The class name of the object
|
231 |
+
* @param array $Filter An array of members to exclude
|
232 |
+
* @return void
|
233 |
+
*/
|
234 |
+
function setObjectFilter($Class, $Filter) {
|
235 |
+
$this->objectFilters[strtolower($Class)] = $Filter;
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Set some options for the library
|
240 |
+
*
|
241 |
+
* Options:
|
242 |
+
* - maxObjectDepth: The maximum depth to traverse objects (default: 5)
|
243 |
+
* - maxArrayDepth: The maximum depth to traverse arrays (default: 5)
|
244 |
+
* - useNativeJsonEncode: If true will use json_encode() (default: true)
|
245 |
+
* - includeLineNumbers: If true will include line numbers and filenames (default: true)
|
246 |
+
*
|
247 |
+
* @param array $Options The options to be set
|
248 |
+
* @return void
|
249 |
+
*/
|
250 |
+
function setOptions($Options) {
|
251 |
+
$this->options = array_merge($this->options,$Options);
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Get options from the library
|
256 |
+
*
|
257 |
+
* @return array The currently set options
|
258 |
+
*/
|
259 |
+
function getOptions() {
|
260 |
+
return $this->options;
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Register FirePHP as your error handler
|
265 |
+
*
|
266 |
+
* Will use FirePHP to log each php error.
|
267 |
+
*
|
268 |
+
* @return mixed Returns a string containing the previously defined error handler (if any)
|
269 |
+
*/
|
270 |
+
function registerErrorHandler()
|
271 |
+
{
|
272 |
+
//NOTE: The following errors will not be caught by this error handler:
|
273 |
+
// E_ERROR, E_PARSE, E_CORE_ERROR,
|
274 |
+
// E_CORE_WARNING, E_COMPILE_ERROR,
|
275 |
+
// E_COMPILE_WARNING, E_STRICT
|
276 |
+
|
277 |
+
return set_error_handler(array($this,'errorHandler'));
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* FirePHP's error handler
|
282 |
+
*
|
283 |
+
* Logs each php error that will occur.
|
284 |
+
*
|
285 |
+
* @param int $errno
|
286 |
+
* @param string $errstr
|
287 |
+
* @param string $errfile
|
288 |
+
* @param int $errline
|
289 |
+
* @param array $errcontext
|
290 |
+
*/
|
291 |
+
function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
|
292 |
+
{
|
293 |
+
global $FirePHP_Instance;
|
294 |
+
// Don't log error if error reporting is switched off
|
295 |
+
if (error_reporting() == 0) {
|
296 |
+
return;
|
297 |
+
}
|
298 |
+
// Only log error for errors we are asking for
|
299 |
+
if (error_reporting() & $errno) {
|
300 |
+
$FirePHP_Instance->group($errstr);
|
301 |
+
$FirePHP_Instance->error("{$errfile}, line $errline");
|
302 |
+
$FirePHP_Instance->groupEnd();
|
303 |
+
}
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Register FirePHP driver as your assert callback
|
308 |
+
*
|
309 |
+
* @return mixed Returns the original setting
|
310 |
+
*/
|
311 |
+
function registerAssertionHandler()
|
312 |
+
{
|
313 |
+
return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler'));
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* FirePHP's assertion handler
|
318 |
+
*
|
319 |
+
* Logs all assertions to your firebug console and then stops the script.
|
320 |
+
*
|
321 |
+
* @param string $file File source of assertion
|
322 |
+
* @param int $line Line source of assertion
|
323 |
+
* @param mixed $code Assertion code
|
324 |
+
*/
|
325 |
+
function assertionHandler($file, $line, $code)
|
326 |
+
{
|
327 |
+
$this->fb($code, 'Assertion Failed', FirePHP_ERROR, array('File'=>$file,'Line'=>$line));
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Set custom processor url for FirePHP
|
332 |
+
*
|
333 |
+
* @param string $URL
|
334 |
+
*/
|
335 |
+
function setProcessorUrl($URL)
|
336 |
+
{
|
337 |
+
$this->setHeader('X-FirePHP-ProcessorURL', $URL);
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Set custom renderer url for FirePHP
|
342 |
+
*
|
343 |
+
* @param string $URL
|
344 |
+
*/
|
345 |
+
function setRendererUrl($URL)
|
346 |
+
{
|
347 |
+
$this->setHeader('X-FirePHP-RendererURL', $URL);
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Start a group for following messages.
|
352 |
+
*
|
353 |
+
* Options:
|
354 |
+
* Collapsed: [true|false]
|
355 |
+
* Color: [#RRGGBB|ColorName]
|
356 |
+
*
|
357 |
+
* @param string $Name
|
358 |
+
* @param array $Options OPTIONAL Instructions on how to log the group
|
359 |
+
* @return true
|
360 |
+
* @throws Exception
|
361 |
+
*/
|
362 |
+
function group($Name, $Options=null) {
|
363 |
+
|
364 |
+
if(!$Name) {
|
365 |
+
trigger_error('You must specify a label for the group!');
|
366 |
+
}
|
367 |
+
|
368 |
+
if($Options) {
|
369 |
+
if(!is_array($Options)) {
|
370 |
+
trigger_error('Options must be defined as an array!');
|
371 |
+
}
|
372 |
+
if(array_key_exists('Collapsed', $Options)) {
|
373 |
+
$Options['Collapsed'] = ($Options['Collapsed'])?'true':'false';
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
+
return $this->fb(null, $Name, FirePHP_GROUP_START, $Options);
|
378 |
+
}
|
379 |
+
|
380 |
+
/**
|
381 |
+
* Ends a group you have started before
|
382 |
+
*
|
383 |
+
* @return true
|
384 |
+
* @throws Exception
|
385 |
+
*/
|
386 |
+
function groupEnd() {
|
387 |
+
return $this->fb(null, null, FirePHP_GROUP_END);
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Log object with label to firebug console
|
392 |
+
*
|
393 |
+
* @see FirePHP::LOG
|
394 |
+
* @param mixes $Object
|
395 |
+
* @param string $Label
|
396 |
+
* @return true
|
397 |
+
* @throws Exception
|
398 |
+
*/
|
399 |
+
function log($Object, $Label=null) {
|
400 |
+
return $this->fb($Object, $Label, FirePHP_LOG);
|
401 |
+
}
|
402 |
+
|
403 |
+
/**
|
404 |
+
* Log object with label to firebug console
|
405 |
+
*
|
406 |
+
* @see FirePHP::INFO
|
407 |
+
* @param mixes $Object
|
408 |
+
* @param string $Label
|
409 |
+
* @return true
|
410 |
+
* @throws Exception
|
411 |
+
*/
|
412 |
+
function info($Object, $Label=null) {
|
413 |
+
return $this->fb($Object, $Label, FirePHP_INFO);
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Log object with label to firebug console
|
418 |
+
*
|
419 |
+
* @see FirePHP::WARN
|
420 |
+
* @param mixes $Object
|
421 |
+
* @param string $Label
|
422 |
+
* @return true
|
423 |
+
* @throws Exception
|
424 |
+
*/
|
425 |
+
function warn($Object, $Label=null) {
|
426 |
+
return $this->fb($Object, $Label, FirePHP_WARN);
|
427 |
+
}
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Log object with label to firebug console
|
431 |
+
*
|
432 |
+
* @see FirePHP::ERROR
|
433 |
+
* @param mixes $Object
|
434 |
+
* @param string $Label
|
435 |
+
* @return true
|
436 |
+
* @throws Exception
|
437 |
+
*/
|
438 |
+
function error($Object, $Label=null) {
|
439 |
+
return $this->fb($Object, $Label, FirePHP_ERROR);
|
440 |
+
}
|
441 |
+
|
442 |
+
/**
|
443 |
+
* Dumps key and variable to firebug server panel
|
444 |
+
*
|
445 |
+
* @see FirePHP::DUMP
|
446 |
+
* @param string $Key
|
447 |
+
* @param mixed $Variable
|
448 |
+
* @return true
|
449 |
+
* @throws Exception
|
450 |
+
*/
|
451 |
+
function dump($Key, $Variable) {
|
452 |
+
return $this->fb($Variable, $Key, FirePHP_DUMP);
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Log a trace in the firebug console
|
457 |
+
*
|
458 |
+
* @see FirePHP::TRACE
|
459 |
+
* @param string $Label
|
460 |
+
* @return true
|
461 |
+
* @throws Exception
|
462 |
+
*/
|
463 |
+
function trace($Label) {
|
464 |
+
return $this->fb($Label, FirePHP_TRACE);
|
465 |
+
}
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Log a table in the firebug console
|
469 |
+
*
|
470 |
+
* @see FirePHP::TABLE
|
471 |
+
* @param string $Label
|
472 |
+
* @param string $Table
|
473 |
+
* @return true
|
474 |
+
* @throws Exception
|
475 |
+
*/
|
476 |
+
function table($Label, $Table) {
|
477 |
+
return $this->fb($Table, $Label, FirePHP_TABLE);
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Check if FirePHP is installed on client
|
482 |
+
*
|
483 |
+
* @return boolean
|
484 |
+
*/
|
485 |
+
function detectClientExtension() {
|
486 |
+
// Check if FirePHP is installed on client via User-Agent header
|
487 |
+
if(@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si',$this->getUserAgent(),$m) &&
|
488 |
+
version_compare($m[1][0],'0.0.6','>=')) {
|
489 |
+
return true;
|
490 |
+
} else
|
491 |
+
// Check if FirePHP is installed on client via X-FirePHP-Version header
|
492 |
+
if(@preg_match_all('/^([\.\d]*)$/si',$this->getRequestHeader("X-FirePHP-Version"),$m) &&
|
493 |
+
version_compare($m[1][0],'0.0.6','>=')) {
|
494 |
+
return true;
|
495 |
+
}
|
496 |
+
return false;
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* Log varible to Firebug
|
501 |
+
*
|
502 |
+
* @see http://www.firephp.org/Wiki/Reference/Fb
|
503 |
+
* @param mixed $Object The variable to be logged
|
504 |
+
* @return true Return TRUE if message was added to headers, FALSE otherwise
|
505 |
+
* @throws Exception
|
506 |
+
*/
|
507 |
+
function fb($Object) {
|
508 |
+
|
509 |
+
if(!$this->enabled) {
|
510 |
+
return false;
|
511 |
+
}
|
512 |
+
|
513 |
+
if (headers_sent($filename, $linenum)) {
|
514 |
+
trigger_error('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.');
|
515 |
+
}
|
516 |
+
|
517 |
+
$Type = null;
|
518 |
+
$Label = null;
|
519 |
+
$Options = array();
|
520 |
+
|
521 |
+
if(func_num_args()==1) {
|
522 |
+
} else
|
523 |
+
if(func_num_args()==2) {
|
524 |
+
switch(func_get_arg(1)) {
|
525 |
+
case FirePHP_LOG:
|
526 |
+
case FirePHP_INFO:
|
527 |
+
case FirePHP_WARN:
|
528 |
+
case FirePHP_ERROR:
|
529 |
+
case FirePHP_DUMP:
|
530 |
+
case FirePHP_TRACE:
|
531 |
+
case FirePHP_TABLE:
|
532 |
+
case FirePHP_GROUP_START:
|
533 |
+
case FirePHP_GROUP_END:
|
534 |
+
$Type = func_get_arg(1);
|
535 |
+
break;
|
536 |
+
default:
|
537 |
+
$Label = func_get_arg(1);
|
538 |
+
break;
|
539 |
+
}
|
540 |
+
} else
|
541 |
+
if(func_num_args()==3) {
|
542 |
+
$Type = func_get_arg(2);
|
543 |
+
$Label = func_get_arg(1);
|
544 |
+
} else
|
545 |
+
if(func_num_args()==4) {
|
546 |
+
$Type = func_get_arg(2);
|
547 |
+
$Label = func_get_arg(1);
|
548 |
+
$Options = func_get_arg(3);
|
549 |
+
} else {
|
550 |
+
trigger_error('Wrong number of arguments to fb() function!');
|
551 |
+
}
|
552 |
+
|
553 |
+
|
554 |
+
if(!$this->detectClientExtension()) {
|
555 |
+
return false;
|
556 |
+
}
|
557 |
+
|
558 |
+
$meta = array();
|
559 |
+
$skipFinalObjectEncode = false;
|
560 |
+
|
561 |
+
if($Type==FirePHP_TRACE) {
|
562 |
+
|
563 |
+
$trace = debug_backtrace();
|
564 |
+
if(!$trace) return false;
|
565 |
+
for( $i=0 ; $i<sizeof($trace) ; $i++ ) {
|
566 |
+
|
567 |
+
if(isset($trace[$i]['class'])
|
568 |
+
&& isset($trace[$i]['file'])
|
569 |
+
&& ($trace[$i]['class']=='FirePHP'
|
570 |
+
|| $trace[$i]['class']=='FB')
|
571 |
+
&& (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
|
572 |
+
|| substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
|
573 |
+
/* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
|
574 |
+
} else
|
575 |
+
if(isset($trace[$i]['class'])
|
576 |
+
&& isset($trace[$i+1]['file'])
|
577 |
+
&& $trace[$i]['class']=='FirePHP'
|
578 |
+
&& substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
|
579 |
+
/* Skip fb() */
|
580 |
+
} else
|
581 |
+
if($trace[$i]['function']=='fb'
|
582 |
+
|| $trace[$i]['function']=='trace'
|
583 |
+
|| $trace[$i]['function']=='send') {
|
584 |
+
$Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'',
|
585 |
+
'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'',
|
586 |
+
'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'',
|
587 |
+
'Message'=>$trace[$i]['args'][0],
|
588 |
+
'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'',
|
589 |
+
'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'',
|
590 |
+
'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'',
|
591 |
+
'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1)));
|
592 |
+
|
593 |
+
$skipFinalObjectEncode = true;
|
594 |
+
$meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
|
595 |
+
$meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
|
596 |
+
break;
|
597 |
+
}
|
598 |
+
}
|
599 |
+
|
600 |
+
} else
|
601 |
+
if($Type==FirePHP_TABLE) {
|
602 |
+
|
603 |
+
if(isset($Object[0]) && is_string($Object[0])) {
|
604 |
+
$Object[1] = $this->encodeTable($Object[1]);
|
605 |
+
} else {
|
606 |
+
$Object = $this->encodeTable($Object);
|
607 |
+
}
|
608 |
+
|
609 |
+
$skipFinalObjectEncode = true;
|
610 |
+
|
611 |
+
} else
|
612 |
+
if($Type==FirePHP_GROUP_START) {
|
613 |
+
|
614 |
+
if(!$Label) {
|
615 |
+
trigger_error('You must specify a label for the group!');
|
616 |
+
}
|
617 |
+
} else {
|
618 |
+
if($Type===null) {
|
619 |
+
$Type = FirePHP_LOG;
|
620 |
+
}
|
621 |
+
}
|
622 |
+
|
623 |
+
if($this->options['includeLineNumbers']) {
|
624 |
+
if(!isset($meta['file']) || !isset($meta['line'])) {
|
625 |
+
|
626 |
+
$trace = debug_backtrace();
|
627 |
+
for( $i=0 ; $trace && $i<sizeof($trace) ; $i++ ) {
|
628 |
+
|
629 |
+
if(isset($trace[$i]['class'])
|
630 |
+
&& isset($trace[$i]['file'])
|
631 |
+
&& ($trace[$i]['class']=='FirePHP'
|
632 |
+
|| $trace[$i]['class']=='FB')
|
633 |
+
&& (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
|
634 |
+
|| substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
|
635 |
+
/* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
|
636 |
+
} else
|
637 |
+
if(isset($trace[$i]['class'])
|
638 |
+
&& isset($trace[$i+1]['file'])
|
639 |
+
&& $trace[$i]['class']=='FirePHP'
|
640 |
+
&& substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
|
641 |
+
/* Skip fb() */
|
642 |
+
} else
|
643 |
+
if(isset($trace[$i]['file'])
|
644 |
+
&& substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') {
|
645 |
+
/* Skip FB::fb() */
|
646 |
+
} else {
|
647 |
+
$meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
|
648 |
+
$meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
|
649 |
+
break;
|
650 |
+
}
|
651 |
+
}
|
652 |
+
|
653 |
+
}
|
654 |
+
} else {
|
655 |
+
unset($meta['file']);
|
656 |
+
unset($meta['line']);
|
657 |
+
}
|
658 |
+
|
659 |
+
$this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
|
660 |
+
$this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.FirePHP_VERSION);
|
661 |
+
|
662 |
+
$structure_index = 1;
|
663 |
+
if($Type==FirePHP_DUMP) {
|
664 |
+
$structure_index = 2;
|
665 |
+
$this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
|
666 |
+
} else {
|
667 |
+
$this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
|
668 |
+
}
|
669 |
+
|
670 |
+
if($Type==FirePHP_DUMP) {
|
671 |
+
$msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}';
|
672 |
+
} else {
|
673 |
+
$msg_meta = $Options;
|
674 |
+
$msg_meta['Type'] = $Type;
|
675 |
+
if($Label!==null) {
|
676 |
+
$msg_meta['Label'] = $Label;
|
677 |
+
}
|
678 |
+
if(isset($meta['file']) && !isset($msg_meta['File'])) {
|
679 |
+
$msg_meta['File'] = $meta['file'];
|
680 |
+
}
|
681 |
+
if(isset($meta['line']) && !isset($msg_meta['Line'])) {
|
682 |
+
$msg_meta['Line'] = $meta['line'];
|
683 |
+
}
|
684 |
+
$msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']';
|
685 |
+
}
|
686 |
+
|
687 |
+
$parts = explode("\n",chunk_split($msg, 5000, "\n"));
|
688 |
+
|
689 |
+
for( $i=0 ; $i<count($parts) ; $i++) {
|
690 |
+
|
691 |
+
$part = $parts[$i];
|
692 |
+
if ($part) {
|
693 |
+
|
694 |
+
if(count($parts)>2) {
|
695 |
+
// Message needs to be split into multiple parts
|
696 |
+
$this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
|
697 |
+
(($i==0)?strlen($msg):'')
|
698 |
+
. '|' . $part . '|'
|
699 |
+
. (($i<count($parts)-2)?'\\':''));
|
700 |
+
} else {
|
701 |
+
$this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
|
702 |
+
strlen($part) . '|' . $part . '|');
|
703 |
+
}
|
704 |
+
|
705 |
+
$this->messageIndex++;
|
706 |
+
|
707 |
+
if ($this->messageIndex > 99999) {
|
708 |
+
trigger_error('Maximum number (99,999) of messages reached!');
|
709 |
+
}
|
710 |
+
}
|
711 |
+
}
|
712 |
+
|
713 |
+
$this->setHeader('X-Wf-1-Index',$this->messageIndex-1);
|
714 |
+
|
715 |
+
return true;
|
716 |
+
}
|
717 |
+
|
718 |
+
|
719 |
+
/**
|
720 |
+
* Standardizes path for windows systems.
|
721 |
+
*
|
722 |
+
* @param string $Path
|
723 |
+
* @return string
|
724 |
+
*/
|
725 |
+
function _standardizePath($Path) {
|
726 |
+
return preg_replace('/\\\\+/','/',$Path);
|
727 |
+
}
|
728 |
+
|
729 |
+
/**
|
730 |
+
* Escape trace path for windows systems
|
731 |
+
*
|
732 |
+
* @param array $Trace
|
733 |
+
* @return array
|
734 |
+
*/
|
735 |
+
function _escapeTrace($Trace) {
|
736 |
+
if(!$Trace) return $Trace;
|
737 |
+
for( $i=0 ; $i<sizeof($Trace) ; $i++ ) {
|
738 |
+
if(isset($Trace[$i]['file'])) {
|
739 |
+
$Trace[$i]['file'] = $this->_escapeTraceFile($Trace[$i]['file']);
|
740 |
+
}
|
741 |
+
if(isset($Trace[$i]['args'])) {
|
742 |
+
$Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']);
|
743 |
+
}
|
744 |
+
}
|
745 |
+
return $Trace;
|
746 |
+
}
|
747 |
+
|
748 |
+
/**
|
749 |
+
* Escape file information of trace for windows systems
|
750 |
+
*
|
751 |
+
* @param string $File
|
752 |
+
* @return string
|
753 |
+
*/
|
754 |
+
function _escapeTraceFile($File) {
|
755 |
+
/* Check if we have a windows filepath */
|
756 |
+
if(strpos($File,'\\')) {
|
757 |
+
/* First strip down to single \ */
|
758 |
+
|
759 |
+
$file = preg_replace('/\\\\+/','\\',$File);
|
760 |
+
|
761 |
+
return $file;
|
762 |
+
}
|
763 |
+
return $File;
|
764 |
+
}
|
765 |
+
|
766 |
+
/**
|
767 |
+
* Send header
|
768 |
+
*
|
769 |
+
* @param string $Name
|
770 |
+
* @param string_type $Value
|
771 |
+
*/
|
772 |
+
function setHeader($Name, $Value) {
|
773 |
+
return header($Name.': '.$Value);
|
774 |
+
}
|
775 |
+
|
776 |
+
/**
|
777 |
+
* Get user agent
|
778 |
+
*
|
779 |
+
* @return string|false
|
780 |
+
*/
|
781 |
+
function getUserAgent() {
|
782 |
+
if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
|
783 |
+
return $_SERVER['HTTP_USER_AGENT'];
|
784 |
+
}
|
785 |
+
|
786 |
+
/**
|
787 |
+
* Get all request headers
|
788 |
+
*
|
789 |
+
* @return array
|
790 |
+
*/
|
791 |
+
function getAllRequestHeaders() {
|
792 |
+
$headers = array();
|
793 |
+
if(function_exists('getallheaders')) {
|
794 |
+
foreach( getallheaders() as $name => $value ) {
|
795 |
+
$headers[strtolower($name)] = $value;
|
796 |
+
}
|
797 |
+
} else {
|
798 |
+
foreach($_SERVER as $name => $value) {
|
799 |
+
if(substr($name, 0, 5) == 'HTTP_') {
|
800 |
+
$headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value;
|
801 |
+
}
|
802 |
+
}
|
803 |
+
}
|
804 |
+
return $headers;
|
805 |
+
}
|
806 |
+
|
807 |
+
/**
|
808 |
+
* Get a request header
|
809 |
+
*
|
810 |
+
* @return string|false
|
811 |
+
*/
|
812 |
+
function getRequestHeader($Name)
|
813 |
+
{
|
814 |
+
$headers = $this->getAllRequestHeaders();
|
815 |
+
if (isset($headers[strtolower($Name)])) {
|
816 |
+
return $headers[strtolower($Name)];
|
817 |
+
}
|
818 |
+
return false;
|
819 |
+
}
|
820 |
+
|
821 |
+
/**
|
822 |
+
* Encode an object into a JSON string
|
823 |
+
*
|
824 |
+
* Uses PHP's jeson_encode() if available
|
825 |
+
*
|
826 |
+
* @param object $Object The object to be encoded
|
827 |
+
* @return string The JSON string
|
828 |
+
*/
|
829 |
+
function jsonEncode($Object, $skipObjectEncode=false)
|
830 |
+
{
|
831 |
+
if(!$skipObjectEncode) {
|
832 |
+
$Object = $this->encodeObject($Object);
|
833 |
+
}
|
834 |
+
|
835 |
+
if(function_exists('json_encode')
|
836 |
+
&& $this->options['useNativeJsonEncode']!=false) {
|
837 |
+
|
838 |
+
return json_encode($Object);
|
839 |
+
} else {
|
840 |
+
return $this->json_encode($Object);
|
841 |
+
}
|
842 |
+
}
|
843 |
+
|
844 |
+
/**
|
845 |
+
* Encodes a table by encoding each row and column with encodeObject()
|
846 |
+
*
|
847 |
+
* @param array $Table The table to be encoded
|
848 |
+
* @return array
|
849 |
+
*/
|
850 |
+
function encodeTable($Table) {
|
851 |
+
|
852 |
+
if(!$Table) return $Table;
|
853 |
+
|
854 |
+
$new_table = array();
|
855 |
+
foreach($Table as $row) {
|
856 |
+
|
857 |
+
if(is_array($row)) {
|
858 |
+
$new_row = array();
|
859 |
+
|
860 |
+
foreach($row as $item) {
|
861 |
+
$new_row[] = $this->encodeObject($item);
|
862 |
+
}
|
863 |
+
|
864 |
+
$new_table[] = $new_row;
|
865 |
+
}
|
866 |
+
}
|
867 |
+
|
868 |
+
return $new_table;
|
869 |
+
}
|
870 |
+
|
871 |
+
/**
|
872 |
+
* Encodes an object
|
873 |
+
*
|
874 |
+
* @param Object $Object The object to be encoded
|
875 |
+
* @param int $Depth The current traversal depth
|
876 |
+
* @return array All members of the object
|
877 |
+
*/
|
878 |
+
function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1)
|
879 |
+
{
|
880 |
+
$return = array();
|
881 |
+
|
882 |
+
if (is_resource($Object)) {
|
883 |
+
|
884 |
+
return '** '.(string)$Object.' **';
|
885 |
+
|
886 |
+
} else
|
887 |
+
if (is_object($Object)) {
|
888 |
+
|
889 |
+
if ($ObjectDepth > $this->options['maxObjectDepth']) {
|
890 |
+
return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **';
|
891 |
+
}
|
892 |
+
|
893 |
+
foreach ($this->objectStack as $refVal) {
|
894 |
+
if ($refVal === $Object) {
|
895 |
+
return '** Recursion ('.get_class($Object).') **';
|
896 |
+
}
|
897 |
+
}
|
898 |
+
array_push($this->objectStack, $Object);
|
899 |
+
|
900 |
+
$return['__className'] = $class = get_class($Object);
|
901 |
+
$class_lower = strtolower($class);
|
902 |
+
|
903 |
+
$members = (array)$Object;
|
904 |
+
|
905 |
+
// Include all members that are not defined in the class
|
906 |
+
// but exist in the object
|
907 |
+
foreach( $members as $raw_name => $value ) {
|
908 |
+
|
909 |
+
$name = $raw_name;
|
910 |
+
|
911 |
+
if ($name{0} == "\0") {
|
912 |
+
$parts = explode("\0", $name);
|
913 |
+
$name = $parts[2];
|
914 |
+
}
|
915 |
+
|
916 |
+
if(!isset($properties[$name])) {
|
917 |
+
$name = 'undeclared:'.$name;
|
918 |
+
|
919 |
+
if(!(isset($this->objectFilters[$class_lower])
|
920 |
+
&& is_array($this->objectFilters[$class_lower])
|
921 |
+
&& in_array($raw_name,$this->objectFilters[$class_lower]))) {
|
922 |
+
|
923 |
+
$return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1);
|
924 |
+
} else {
|
925 |
+
$return[$name] = '** Excluded by Filter **';
|
926 |
+
}
|
927 |
+
}
|
928 |
+
}
|
929 |
+
|
930 |
+
array_pop($this->objectStack);
|
931 |
+
|
932 |
+
} elseif (is_array($Object)) {
|
933 |
+
|
934 |
+
if ($ArrayDepth > $this->options['maxArrayDepth']) {
|
935 |
+
return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **';
|
936 |
+
}
|
937 |
+
|
938 |
+
foreach ($Object as $key => $val) {
|
939 |
+
|
940 |
+
// Encoding the $GLOBALS PHP array causes an infinite loop
|
941 |
+
// if the recursion is not reset here as it contains
|
942 |
+
// a reference to itself. This is the only way I have come up
|
943 |
+
// with to stop infinite recursion in this case.
|
944 |
+
if($key=='GLOBALS'
|
945 |
+
&& is_array($val)
|
946 |
+
&& array_key_exists('GLOBALS',$val)) {
|
947 |
+
$val['GLOBALS'] = '** Recursion (GLOBALS) **';
|
948 |
+
}
|
949 |
+
|
950 |
+
$return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1);
|
951 |
+
}
|
952 |
+
} else {
|
953 |
+
if($this->is_utf8($Object)) {
|
954 |
+
return $Object;
|
955 |
+
} else {
|
956 |
+
return utf8_encode($Object);
|
957 |
+
}
|
958 |
+
}
|
959 |
+
return $return;
|
960 |
+
|
961 |
+
}
|
962 |
+
|
963 |
+
/**
|
964 |
+
* Returns true if $string is valid UTF-8 and false otherwise.
|
965 |
+
*
|
966 |
+
* @param mixed $str String to be tested
|
967 |
+
* @return boolean
|
968 |
+
*/
|
969 |
+
function is_utf8($str) {
|
970 |
+
$c=0; $b=0;
|
971 |
+
$bits=0;
|
972 |
+
$len=strlen($str);
|
973 |
+
for($i=0; $i<$len; $i++){
|
974 |
+
$c=ord($str[$i]);
|
975 |
+
if($c > 128){
|
976 |
+
if(($c >= 254)) return false;
|
977 |
+
elseif($c >= 252) $bits=6;
|
978 |
+
elseif($c >= 248) $bits=5;
|
979 |
+
elseif($c >= 240) $bits=4;
|
980 |
+
elseif($c >= 224) $bits=3;
|
981 |
+
elseif($c >= 192) $bits=2;
|
982 |
+
else return false;
|
983 |
+
if(($i+$bits) > $len) return false;
|
984 |
+
while($bits > 1){
|
985 |
+
$i++;
|
986 |
+
$b=ord($str[$i]);
|
987 |
+
if($b < 128 || $b > 191) return false;
|
988 |
+
$bits--;
|
989 |
+
}
|
990 |
+
}
|
991 |
+
}
|
992 |
+
return true;
|
993 |
+
}
|
994 |
+
|
995 |
+
/**
|
996 |
+
* Converts to and from JSON format.
|
997 |
+
*
|
998 |
+
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
999 |
+
* format. It is easy for humans to read and write. It is easy for machines
|
1000 |
+
* to parse and generate. It is based on a subset of the JavaScript
|
1001 |
+
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
1002 |
+
* This feature can also be found in Python. JSON is a text format that is
|
1003 |
+
* completely language independent but uses conventions that are familiar
|
1004 |
+
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
1005 |
+
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
1006 |
+
* ideal data-interchange language.
|
1007 |
+
*
|
1008 |
+
* This package provides a simple encoder and decoder for JSON notation. It
|
1009 |
+
* is intended for use with client-side Javascript applications that make
|
1010 |
+
* use of HTTPRequest to perform server communication functions - data can
|
1011 |
+
* be encoded into JSON notation for use in a client-side javascript, or
|
1012 |
+
* decoded from incoming Javascript requests. JSON format is native to
|
1013 |
+
* Javascript, and can be directly eval()'ed with no further parsing
|
1014 |
+
* overhead
|
1015 |
+
*
|
1016 |
+
* All strings should be in ASCII or UTF-8 format!
|
1017 |
+
*
|
1018 |
+
* LICENSE: Redistribution and use in source and binary forms, with or
|
1019 |
+
* without modification, are permitted provided that the following
|
1020 |
+
* conditions are met: Redistributions of source code must retain the
|
1021 |
+
* above copyright notice, this list of conditions and the following
|
1022 |
+
* disclaimer. Redistributions in binary form must reproduce the above
|
1023 |
+
* copyright notice, this list of conditions and the following disclaimer
|
1024 |
+
* in the documentation and/or other materials provided with the
|
1025 |
+
* distribution.
|
1026 |
+
*
|
1027 |
+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
1028 |
+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
1029 |
+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
1030 |
+
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
1031 |
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
1032 |
+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
1033 |
+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
1034 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
1035 |
+
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
1036 |
+
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
1037 |
+
* DAMAGE.
|
1038 |
+
*
|
1039 |
+
* @category
|
1040 |
+
* @package Services_JSON
|
1041 |
+
* @author Michal Migurski <mike-json@teczno.com>
|
1042 |
+
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
1043 |
+
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
1044 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
1045 |
+
* @copyright 2005 Michal Migurski
|
1046 |
+
* @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
|
1047 |
+
* @license http://www.opensource.org/licenses/bsd-license.php
|
1048 |
+
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
1049 |
+
*/
|
1050 |
+
|
1051 |
+
|
1052 |
+
/**
|
1053 |
+
* Keep a list of objects as we descend into the array so we can detect recursion.
|
1054 |
+
*/
|
1055 |
+
var $json_objectStack = array();
|
1056 |
+
|
1057 |
+
|
1058 |
+
/**
|
1059 |
+
* convert a string from one UTF-8 char to one UTF-16 char
|
1060 |
+
*
|
1061 |
+
* Normally should be handled by mb_convert_encoding, but
|
1062 |
+
* provides a slower PHP-only method for installations
|
1063 |
+
* that lack the multibye string extension.
|
1064 |
+
*
|
1065 |
+
* @param string $utf8 UTF-8 character
|
1066 |
+
* @return string UTF-16 character
|
1067 |
+
* @access private
|
1068 |
+
*/
|
1069 |
+
function json_utf82utf16($utf8)
|
1070 |
+
{
|
1071 |
+
// oh please oh please oh please oh please oh please
|
1072 |
+
if(function_exists('mb_convert_encoding')) {
|
1073 |
+
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
switch(strlen($utf8)) {
|
1077 |
+
case 1:
|
1078 |
+
// this case should never be reached, because we are in ASCII range
|
1079 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1080 |
+
return $utf8;
|
1081 |
+
|
1082 |
+
case 2:
|
1083 |
+
// return a UTF-16 character from a 2-byte UTF-8 char
|
1084 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1085 |
+
return chr(0x07 & (ord($utf8{0}) >> 2))
|
1086 |
+
. chr((0xC0 & (ord($utf8{0}) << 6))
|
1087 |
+
| (0x3F & ord($utf8{1})));
|
1088 |
+
|
1089 |
+
case 3:
|
1090 |
+
// return a UTF-16 character from a 3-byte UTF-8 char
|
1091 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1092 |
+
return chr((0xF0 & (ord($utf8{0}) << 4))
|
1093 |
+
| (0x0F & (ord($utf8{1}) >> 2)))
|
1094 |
+
. chr((0xC0 & (ord($utf8{1}) << 6))
|
1095 |
+
| (0x7F & ord($utf8{2})));
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
// ignoring UTF-32 for now, sorry
|
1099 |
+
return '';
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
/**
|
1103 |
+
* encodes an arbitrary variable into JSON format
|
1104 |
+
*
|
1105 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
1106 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
1107 |
+
* if var is a strng, note that encode() always expects it
|
1108 |
+
* to be in ASCII or UTF-8 format!
|
1109 |
+
*
|
1110 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
1111 |
+
* @access public
|
1112 |
+
*/
|
1113 |
+
function json_encode($var)
|
1114 |
+
{
|
1115 |
+
|
1116 |
+
if(is_object($var)) {
|
1117 |
+
if(in_array($var,$this->json_objectStack)) {
|
1118 |
+
return '"** Recursion **"';
|
1119 |
+
}
|
1120 |
+
}
|
1121 |
+
|
1122 |
+
switch (gettype($var)) {
|
1123 |
+
case 'boolean':
|
1124 |
+
return $var ? 'true' : 'false';
|
1125 |
+
|
1126 |
+
case 'NULL':
|
1127 |
+
return 'null';
|
1128 |
+
|
1129 |
+
case 'integer':
|
1130 |
+
return (int) $var;
|
1131 |
+
|
1132 |
+
case 'double':
|
1133 |
+
case 'float':
|
1134 |
+
return (float) $var;
|
1135 |
+
|
1136 |
+
case 'string':
|
1137 |
+
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
1138 |
+
$ascii = '';
|
1139 |
+
$strlen_var = strlen($var);
|
1140 |
+
|
1141 |
+
/*
|
1142 |
+
* Iterate over every character in the string,
|
1143 |
+
* escaping with a slash or encoding to UTF-8 where necessary
|
1144 |
+
*/
|
1145 |
+
for ($c = 0; $c < $strlen_var; ++$c) {
|
1146 |
+
|
1147 |
+
$ord_var_c = ord($var{$c});
|
1148 |
+
|
1149 |
+
switch (true) {
|
1150 |
+
case $ord_var_c == 0x08:
|
1151 |
+
$ascii .= '\b';
|
1152 |
+
break;
|
1153 |
+
case $ord_var_c == 0x09:
|
1154 |
+
$ascii .= '\t';
|
1155 |
+
break;
|
1156 |
+
case $ord_var_c == 0x0A:
|
1157 |
+
$ascii .= '\n';
|
1158 |
+
break;
|
1159 |
+
case $ord_var_c == 0x0C:
|
1160 |
+
$ascii .= '\f';
|
1161 |
+
break;
|
1162 |
+
case $ord_var_c == 0x0D:
|
1163 |
+
$ascii .= '\r';
|
1164 |
+
break;
|
1165 |
+
|
1166 |
+
case $ord_var_c == 0x22:
|
1167 |
+
case $ord_var_c == 0x2F:
|
1168 |
+
case $ord_var_c == 0x5C:
|
1169 |
+
// double quote, slash, slosh
|
1170 |
+
$ascii .= '\\'.$var{$c};
|
1171 |
+
break;
|
1172 |
+
|
1173 |
+
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
1174 |
+
// characters U-00000000 - U-0000007F (same as ASCII)
|
1175 |
+
$ascii .= $var{$c};
|
1176 |
+
break;
|
1177 |
+
|
1178 |
+
case (($ord_var_c & 0xE0) == 0xC0):
|
1179 |
+
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
1180 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1181 |
+
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
1182 |
+
$c += 1;
|
1183 |
+
$utf16 = $this->json_utf82utf16($char);
|
1184 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1185 |
+
break;
|
1186 |
+
|
1187 |
+
case (($ord_var_c & 0xF0) == 0xE0):
|
1188 |
+
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
1189 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1190 |
+
$char = pack('C*', $ord_var_c,
|
1191 |
+
ord($var{$c + 1}),
|
1192 |
+
ord($var{$c + 2}));
|
1193 |
+
$c += 2;
|
1194 |
+
$utf16 = $this->json_utf82utf16($char);
|
1195 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1196 |
+
break;
|
1197 |
+
|
1198 |
+
case (($ord_var_c & 0xF8) == 0xF0):
|
1199 |
+
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
1200 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1201 |
+
$char = pack('C*', $ord_var_c,
|
1202 |
+
ord($var{$c + 1}),
|
1203 |
+
ord($var{$c + 2}),
|
1204 |
+
ord($var{$c + 3}));
|
1205 |
+
$c += 3;
|
1206 |
+
$utf16 = $this->json_utf82utf16($char);
|
1207 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1208 |
+
break;
|
1209 |
+
|
1210 |
+
case (($ord_var_c & 0xFC) == 0xF8):
|
1211 |
+
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
1212 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1213 |
+
$char = pack('C*', $ord_var_c,
|
1214 |
+
ord($var{$c + 1}),
|
1215 |
+
ord($var{$c + 2}),
|
1216 |
+
ord($var{$c + 3}),
|
1217 |
+
ord($var{$c + 4}));
|
1218 |
+
$c += 4;
|
1219 |
+
$utf16 = $this->json_utf82utf16($char);
|
1220 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1221 |
+
break;
|
1222 |
+
|
1223 |
+
case (($ord_var_c & 0xFE) == 0xFC):
|
1224 |
+
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
1225 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
1226 |
+
$char = pack('C*', $ord_var_c,
|
1227 |
+
ord($var{$c + 1}),
|
1228 |
+
ord($var{$c + 2}),
|
1229 |
+
ord($var{$c + 3}),
|
1230 |
+
ord($var{$c + 4}),
|
1231 |
+
ord($var{$c + 5}));
|
1232 |
+
$c += 5;
|
1233 |
+
$utf16 = $this->json_utf82utf16($char);
|
1234 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
1235 |
+
break;
|
1236 |
+
}
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
return '"'.$ascii.'"';
|
1240 |
+
|
1241 |
+
case 'array':
|
1242 |
+
/*
|
1243 |
+
* As per JSON spec if any array key is not an integer
|
1244 |
+
* we must treat the the whole array as an object. We
|
1245 |
+
* also try to catch a sparsely populated associative
|
1246 |
+
* array with numeric keys here because some JS engines
|
1247 |
+
* will create an array with empty indexes up to
|
1248 |
+
* max_index which can cause memory issues and because
|
1249 |
+
* the keys, which may be relevant, will be remapped
|
1250 |
+
* otherwise.
|
1251 |
+
*
|
1252 |
+
* As per the ECMA and JSON specification an object may
|
1253 |
+
* have any string as a property. Unfortunately due to
|
1254 |
+
* a hole in the ECMA specification if the key is a
|
1255 |
+
* ECMA reserved word or starts with a digit the
|
1256 |
+
* parameter is only accessible using ECMAScript's
|
1257 |
+
* bracket notation.
|
1258 |
+
*/
|
1259 |
+
|
1260 |
+
// treat as a JSON object
|
1261 |
+
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
1262 |
+
|
1263 |
+
$this->json_objectStack[] = $var;
|
1264 |
+
|
1265 |
+
$properties = array_map(array($this, 'json_name_value'),
|
1266 |
+
array_keys($var),
|
1267 |
+
array_values($var));
|
1268 |
+
|
1269 |
+
array_pop($this->json_objectStack);
|
1270 |
+
|
1271 |
+
return '{' . join(',', $properties) . '}';
|
1272 |
+
}
|
1273 |
+
|
1274 |
+
$this->json_objectStack[] = $var;
|
1275 |
+
|
1276 |
+
// treat it like a regular array
|
1277 |
+
$elements = array_map(array($this, 'json_encode'), $var);
|
1278 |
+
|
1279 |
+
array_pop($this->json_objectStack);
|
1280 |
+
|
1281 |
+
return '[' . join(',', $elements) . ']';
|
1282 |
+
|
1283 |
+
case 'object':
|
1284 |
+
$vars = FirePHP::encodeObject($var);
|
1285 |
+
|
1286 |
+
$this->json_objectStack[] = $var;
|
1287 |
+
|
1288 |
+
$properties = array_map(array($this, 'json_name_value'),
|
1289 |
+
array_keys($vars),
|
1290 |
+
array_values($vars));
|
1291 |
+
|
1292 |
+
array_pop($this->json_objectStack);
|
1293 |
+
|
1294 |
+
return '{' . join(',', $properties) . '}';
|
1295 |
+
|
1296 |
+
default:
|
1297 |
+
return null;
|
1298 |
+
}
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
/**
|
1302 |
+
* array-walking function for use in generating JSON-formatted name-value pairs
|
1303 |
+
*
|
1304 |
+
* @param string $name name of key to use
|
1305 |
+
* @param mixed $value reference to an array element to be encoded
|
1306 |
+
*
|
1307 |
+
* @return string JSON-formatted name-value pair, like '"name":value'
|
1308 |
+
* @access private
|
1309 |
+
*/
|
1310 |
+
function json_name_value($name, $value)
|
1311 |
+
{
|
1312 |
+
// Encoding the $GLOBALS PHP array causes an infinite loop
|
1313 |
+
// if the recursion is not reset here as it contains
|
1314 |
+
// a reference to itself. This is the only way I have come up
|
1315 |
+
// with to stop infinite recursion in this case.
|
1316 |
+
if($name=='GLOBALS'
|
1317 |
+
&& is_array($value)
|
1318 |
+
&& array_key_exists('GLOBALS',$value)) {
|
1319 |
+
$value['GLOBALS'] = '** Recursion **';
|
1320 |
+
}
|
1321 |
+
|
1322 |
+
$encoded_value = $this->json_encode($value);
|
1323 |
+
|
1324 |
+
return $this->json_encode(strval($name)) . ':' . $encoded_value;
|
1325 |
+
}
|
1326 |
+
}
|
1327 |
+
|
includes/debug/browsers/api/firephp/lib/FirePHPCore/fb.php
ADDED
@@ -0,0 +1,275 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - qbbr, Sokolov Innokenty <sokolov.innokenty@gmail.com>, Copyright 2011, New BSD License
|
5 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
6 |
+
|
7 |
+
/**
|
8 |
+
* ***** BEGIN LICENSE BLOCK *****
|
9 |
+
*
|
10 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
11 |
+
*
|
12 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
13 |
+
*
|
14 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 |
+
* of this software and associated documentation files (the "Software"), to deal
|
16 |
+
* in the Software without restriction, including without limitation the rights
|
17 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18 |
+
* copies of the Software, and to permit persons to whom the Software is
|
19 |
+
* furnished to do so, subject to the following conditions:
|
20 |
+
*
|
21 |
+
* The above copyright notice and this permission notice shall be included in
|
22 |
+
* all copies or substantial portions of the Software.
|
23 |
+
*
|
24 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
25 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
26 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
27 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
28 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
29 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
30 |
+
* THE SOFTWARE.
|
31 |
+
*
|
32 |
+
* ***** END LICENSE BLOCK *****
|
33 |
+
*
|
34 |
+
* @copyright Copyright (C) 2007+ Christoph Dorn
|
35 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
36 |
+
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
37 |
+
* @package FirePHPCore
|
38 |
+
*/
|
39 |
+
|
40 |
+
if (!class_exists('FirePHP', false)) {
|
41 |
+
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'FirePHP.class.php';
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Sends the given data to the FirePHP Firefox Extension.
|
46 |
+
* The data can be displayed in the Firebug Console or in the
|
47 |
+
* "Server" request tab.
|
48 |
+
*
|
49 |
+
* @see http://www.firephp.org/Wiki/Reference/Fb
|
50 |
+
* @param mixed $Object
|
51 |
+
* @return true
|
52 |
+
* @throws Exception
|
53 |
+
*/
|
54 |
+
function fb()
|
55 |
+
{
|
56 |
+
$instance = FirePHP::getInstance(true);
|
57 |
+
|
58 |
+
$args = func_get_args();
|
59 |
+
return call_user_func_array(array($instance, 'fb'), $args);
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
class FB
|
64 |
+
{
|
65 |
+
/**
|
66 |
+
* Set an Insight console to direct all logging calls to
|
67 |
+
*
|
68 |
+
* @param object $console The console object to log to
|
69 |
+
* @return void
|
70 |
+
*/
|
71 |
+
public static function setLogToInsightConsole($console)
|
72 |
+
{
|
73 |
+
FirePHP::getInstance(true)->setLogToInsightConsole($console);
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Enable and disable logging to Firebug
|
78 |
+
*
|
79 |
+
* @see FirePHP->setEnabled()
|
80 |
+
* @param boolean $enabled TRUE to enable, FALSE to disable
|
81 |
+
* @return void
|
82 |
+
*/
|
83 |
+
public static function setEnabled($enabled)
|
84 |
+
{
|
85 |
+
FirePHP::getInstance(true)->setEnabled($enabled);
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Check if logging is enabled
|
90 |
+
*
|
91 |
+
* @see FirePHP->getEnabled()
|
92 |
+
* @return boolean TRUE if enabled
|
93 |
+
*/
|
94 |
+
public static function getEnabled()
|
95 |
+
{
|
96 |
+
return FirePHP::getInstance(true)->getEnabled();
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Specify a filter to be used when encoding an object
|
101 |
+
*
|
102 |
+
* Filters are used to exclude object members.
|
103 |
+
*
|
104 |
+
* @see FirePHP->setObjectFilter()
|
105 |
+
* @param string $class The class name of the object
|
106 |
+
* @param array $filter An array or members to exclude
|
107 |
+
* @return void
|
108 |
+
*/
|
109 |
+
public static function setObjectFilter($class, $filter)
|
110 |
+
{
|
111 |
+
FirePHP::getInstance(true)->setObjectFilter($class, $filter);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Set some options for the library
|
116 |
+
*
|
117 |
+
* @see FirePHP->setOptions()
|
118 |
+
* @param array $options The options to be set
|
119 |
+
* @return void
|
120 |
+
*/
|
121 |
+
public static function setOptions($options)
|
122 |
+
{
|
123 |
+
FirePHP::getInstance(true)->setOptions($options);
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Get options for the library
|
128 |
+
*
|
129 |
+
* @see FirePHP->getOptions()
|
130 |
+
* @return array The options
|
131 |
+
*/
|
132 |
+
public static function getOptions()
|
133 |
+
{
|
134 |
+
return FirePHP::getInstance(true)->getOptions();
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Log object to firebug
|
139 |
+
*
|
140 |
+
* @see http://www.firephp.org/Wiki/Reference/Fb
|
141 |
+
* @param mixed $object
|
142 |
+
* @return true
|
143 |
+
* @throws Exception
|
144 |
+
*/
|
145 |
+
public static function send()
|
146 |
+
{
|
147 |
+
$args = func_get_args();
|
148 |
+
return call_user_func_array(array(FirePHP::getInstance(true), 'fb'), $args);
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Start a group for following messages
|
153 |
+
*
|
154 |
+
* Options:
|
155 |
+
* Collapsed: [true|false]
|
156 |
+
* Color: [#RRGGBB|ColorName]
|
157 |
+
*
|
158 |
+
* @param string $name
|
159 |
+
* @param array $options OPTIONAL Instructions on how to log the group
|
160 |
+
* @return true
|
161 |
+
*/
|
162 |
+
public static function group($name, $options=null)
|
163 |
+
{
|
164 |
+
return FirePHP::getInstance(true)->group($name, $options);
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Ends a group you have started before
|
169 |
+
*
|
170 |
+
* @return true
|
171 |
+
* @throws Exception
|
172 |
+
*/
|
173 |
+
public static function groupEnd()
|
174 |
+
{
|
175 |
+
return self::send(null, null, FirePHP::GROUP_END);
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Log object with label to firebug console
|
180 |
+
*
|
181 |
+
* @see FirePHP::LOG
|
182 |
+
* @param mixes $object
|
183 |
+
* @param string $label
|
184 |
+
* @return true
|
185 |
+
* @throws Exception
|
186 |
+
*/
|
187 |
+
public static function log($object, $label=null)
|
188 |
+
{
|
189 |
+
return self::send($object, $label, FirePHP::LOG);
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Log object with label to firebug console
|
194 |
+
*
|
195 |
+
* @see FirePHP::INFO
|
196 |
+
* @param mixes $object
|
197 |
+
* @param string $label
|
198 |
+
* @return true
|
199 |
+
* @throws Exception
|
200 |
+
*/
|
201 |
+
public static function info($object, $label=null)
|
202 |
+
{
|
203 |
+
return self::send($object, $label, FirePHP::INFO);
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Log object with label to firebug console
|
208 |
+
*
|
209 |
+
* @see FirePHP::WARN
|
210 |
+
* @param mixes $object
|
211 |
+
* @param string $label
|
212 |
+
* @return true
|
213 |
+
* @throws Exception
|
214 |
+
*/
|
215 |
+
public static function warn($object, $label=null)
|
216 |
+
{
|
217 |
+
return self::send($object, $label, FirePHP::WARN);
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Log object with label to firebug console
|
222 |
+
*
|
223 |
+
* @see FirePHP::ERROR
|
224 |
+
* @param mixes $object
|
225 |
+
* @param string $label
|
226 |
+
* @return true
|
227 |
+
* @throws Exception
|
228 |
+
*/
|
229 |
+
public static function error($object, $label=null)
|
230 |
+
{
|
231 |
+
return self::send($object, $label, FirePHP::ERROR);
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Dumps key and variable to firebug server panel
|
236 |
+
*
|
237 |
+
* @see FirePHP::DUMP
|
238 |
+
* @param string $key
|
239 |
+
* @param mixed $variable
|
240 |
+
* @return true
|
241 |
+
* @throws Exception
|
242 |
+
*/
|
243 |
+
public static function dump($key, $variable)
|
244 |
+
{
|
245 |
+
return self::send($variable, $key, FirePHP::DUMP);
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Log a trace in the firebug console
|
250 |
+
*
|
251 |
+
* @see FirePHP::TRACE
|
252 |
+
* @param string $label
|
253 |
+
* @return true
|
254 |
+
* @throws Exception
|
255 |
+
*/
|
256 |
+
public static function trace($label)
|
257 |
+
{
|
258 |
+
return self::send($label, FirePHP::TRACE);
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Log a table in the firebug console
|
263 |
+
*
|
264 |
+
* @see FirePHP::TABLE
|
265 |
+
* @param string $label
|
266 |
+
* @param string $table
|
267 |
+
* @return true
|
268 |
+
* @throws Exception
|
269 |
+
*/
|
270 |
+
public static function table($label, $table)
|
271 |
+
{
|
272 |
+
return self::send($table, $label, FirePHP::TABLE);
|
273 |
+
}
|
274 |
+
|
275 |
+
}
|
includes/debug/browsers/api/firephp/lib/FirePHPCore/fb.php4
ADDED
@@ -0,0 +1,245 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Authors:
|
3 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2007, New BSD License
|
4 |
+
// - qbbr, Michael Day <manveru.alma@gmail.com>, Copyright 2008, New BSD License
|
5 |
+
// - cadorn, Christoph Dorn <christoph@christophdorn.com>, Copyright 2011, MIT License
|
6 |
+
|
7 |
+
/* ***** BEGIN LICENSE BLOCK *****
|
8 |
+
*
|
9 |
+
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
10 |
+
*
|
11 |
+
* Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
12 |
+
*
|
13 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
14 |
+
* of this software and associated documentation files (the "Software"), to deal
|
15 |
+
* in the Software without restriction, including without limitation the rights
|
16 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
17 |
+
* copies of the Software, and to permit persons to whom the Software is
|
18 |
+
* furnished to do so, subject to the following conditions:
|
19 |
+
*
|
20 |
+
* The above copyright notice and this permission notice shall be included in
|
21 |
+
* all copies or substantial portions of the Software.
|
22 |
+
*
|
23 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
24 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
25 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
26 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
27 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
28 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
29 |
+
* THE SOFTWARE.
|
30 |
+
*
|
31 |
+
* ***** END LICENSE BLOCK *****
|
32 |
+
*
|
33 |
+
* @copyright Copyright (C) 2007+ Christoph Dorn
|
34 |
+
* @author Christoph Dorn <christoph@christophdorn.com>
|
35 |
+
* @author Michael Day <manveru.alma@gmail.com>
|
36 |
+
* @license [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
37 |
+
* @package FirePHPCore
|
38 |
+
*/
|
39 |
+
|
40 |
+
require_once dirname(__FILE__).'/FirePHP.class.php4';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Sends the given data to the FirePHP Firefox Extension.
|
44 |
+
* The data can be displayed in the Firebug Console or in the
|
45 |
+
* "Server" request tab.
|
46 |
+
*
|
47 |
+
* @see http://www.firephp.org/Wiki/Reference/Fb
|
48 |
+
* @param mixed $Object
|
49 |
+
* @return true
|
50 |
+
* @throws Exception
|
51 |
+
*/
|
52 |
+
function fb()
|
53 |
+
{
|
54 |
+
$instance =& FirePHP::getInstance(true);
|
55 |
+
|
56 |
+
$args = func_get_args();
|
57 |
+
return call_user_func_array(array(&$instance,'fb'),$args);
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
class FB
|
62 |
+
{
|
63 |
+
/**
|
64 |
+
* Enable and disable logging to Firebug
|
65 |
+
*
|
66 |
+
* @see FirePHP->setEnabled()
|
67 |
+
* @param boolean $Enabled TRUE to enable, FALSE to disable
|
68 |
+
* @return void
|
69 |
+
*/
|
70 |
+
function setEnabled($Enabled) {
|
71 |
+
$instance =& FirePHP::getInstance(true);
|
72 |
+
$instance->setEnabled($Enabled);
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Check if logging is enabled
|
77 |
+
*
|
78 |
+
* @see FirePHP->getEnabled()
|
79 |
+
* @return boolean TRUE if enabled
|
80 |
+
*/
|
81 |
+
function getEnabled() {
|
82 |
+
$instance =& FirePHP::getInstance(true);
|
83 |
+
return $instance->getEnabled();
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Specify a filter to be used when encoding an object
|
88 |
+
*
|
89 |
+
* Filters are used to exclude object members.
|
90 |
+
*
|
91 |
+
* @see FirePHP->setObjectFilter()
|
92 |
+
* @param string $Class The class name of the object
|
93 |
+
* @param array $Filter An array or members to exclude
|
94 |
+
* @return void
|
95 |
+
*/
|
96 |
+
function setObjectFilter($Class, $Filter) {
|
97 |
+
$instance =& FirePHP::getInstance(true);
|
98 |
+
$instance->setObjectFilter($Class, $Filter);
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Set some options for the library
|
103 |
+
*
|
104 |
+
* @see FirePHP->setOptions()
|
105 |
+
* @param array $Options The options to be set
|
106 |
+
* @return void
|
107 |
+
*/
|
108 |
+
function setOptions($Options) {
|
109 |
+
$instance =& FirePHP::getInstance(true);
|
110 |
+
$instance->setOptions($Options);
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get options for the library
|
115 |
+
*
|
116 |
+
* @see FirePHP->getOptions()
|
117 |
+
* @return array The options
|
118 |
+
*/
|
119 |
+
function getOptions() {
|
120 |
+
$instance =& FirePHP::getInstance(true);
|
121 |
+
return $instance->getOptions();
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Log object to firebug
|
126 |
+
*
|
127 |
+
* @see http://www.firephp.org/Wiki/Reference/Fb
|
128 |
+
* @param mixed $Object
|
129 |
+
* @return true
|
130 |
+
*/
|
131 |
+
function send()
|
132 |
+
{
|
133 |
+
$instance =& FirePHP::getInstance(true);
|
134 |
+
$args = func_get_args();
|
135 |
+
return call_user_func_array(array(&$instance,'fb'),$args);
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Start a group for following messages
|
140 |
+
*
|
141 |
+
* Options:
|
142 |
+
* Collapsed: [true|false]
|
143 |
+
* Color: [#RRGGBB|ColorName]
|
144 |
+
*
|
145 |
+
* @param string $Name
|
146 |
+
* @param array $Options OPTIONAL Instructions on how to log the group
|
147 |
+
* @return true
|
148 |
+
*/
|
149 |
+
function group($Name, $Options=null) {
|
150 |
+
$instance =& FirePHP::getInstance(true);
|
151 |
+
return $instance->group($Name, $Options);
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Ends a group you have started before
|
156 |
+
*
|
157 |
+
* @return true
|
158 |
+
*/
|
159 |
+
function groupEnd() {
|
160 |
+
return FB::send(null, null, FirePHP_GROUP_END);
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Log object with label to firebug console
|
165 |
+
*
|
166 |
+
* @see FirePHP::LOG
|
167 |
+
* @param mixes $Object
|
168 |
+
* @param string $Label
|
169 |
+
* @return true
|
170 |
+
*/
|
171 |
+
function log($Object, $Label=null) {
|
172 |
+
return FB::send($Object, $Label, FirePHP_LOG);
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Log object with label to firebug console
|
177 |
+
*
|
178 |
+
* @see FirePHP::INFO
|
179 |
+
* @param mixes $Object
|
180 |
+
* @param string $Label
|
181 |
+
* @return true
|
182 |
+
*/
|
183 |
+
function info($Object, $Label=null) {
|
184 |
+
return FB::send($Object, $Label, FirePHP_INFO);
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Log object with label to firebug console
|
189 |
+
*
|
190 |
+
* @see FirePHP::WARN
|
191 |
+
* @param mixes $Object
|
192 |
+
* @param string $Label
|
193 |
+
* @return true
|
194 |
+
*/
|
195 |
+
function warn($Object, $Label=null) {
|
196 |
+
return FB::send($Object, $Label, FirePHP_WARN);
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Log object with label to firebug console
|
201 |
+
*
|
202 |
+
* @see FirePHP::ERROR
|
203 |
+
* @param mixes $Object
|
204 |
+
* @param string $Label
|
205 |
+
* @return true
|
206 |
+
*/
|
207 |
+
function error($Object, $Label=null) {
|
208 |
+
return FB::send($Object, $Label, FirePHP_ERROR);
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Dumps key and variable to firebug server panel
|
213 |
+
*
|
214 |
+
* @see FirePHP::DUMP
|
215 |
+
* @param string $Key
|
216 |
+
* @param mixed $Variable
|
217 |
+
* @return true
|
218 |
+
*/
|
219 |
+
function dump($Key, $Variable) {
|
220 |
+
return FB::send($Variable, $Key, FirePHP_DUMP);
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Log a trace in the firebug console
|
225 |
+
*
|
226 |
+
* @see FirePHP::TRACE
|
227 |
+
* @param string $Label
|
228 |
+
* @return true
|
229 |
+
*/
|
230 |
+
function trace($Label) {
|
231 |
+
return FB::send($Label, FirePHP_TRACE);
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Log a table in the firebug console
|
236 |
+
*
|
237 |
+
* @see FirePHP::TABLE
|
238 |
+
* @param string $Label
|
239 |
+
* @param string $Table
|
240 |
+
* @return true
|
241 |
+
*/
|
242 |
+
function table($Label, $Table) {
|
243 |
+
return FB::send($Table, $Label, FirePHP_TABLE);
|
244 |
+
}
|
245 |
+
}
|
includes/debug/browsers/api/firephp/package.json
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"uid": "https://github.com/firephp/firephp-core/",
|
3 |
+
"name": "firephp-core",
|
4 |
+
"label": "FirePHP Server Library",
|
5 |
+
"repositories": [
|
6 |
+
{
|
7 |
+
"type": "git",
|
8 |
+
"url": "git://github.com/firephp/firephp-core.git"
|
9 |
+
}
|
10 |
+
],
|
11 |
+
"maintainers": [
|
12 |
+
{
|
13 |
+
"name": "Christoph Dorn",
|
14 |
+
"email": "christoph@christophdorn.com",
|
15 |
+
"web": "http://www.christophdorn.com/",
|
16 |
+
"alias": {
|
17 |
+
"github": "cadorn"
|
18 |
+
}
|
19 |
+
}
|
20 |
+
],
|
21 |
+
"contributors": [
|
22 |
+
{
|
23 |
+
"name": "Christoph Dorn",
|
24 |
+
"email": "christoph@christophdorn.com",
|
25 |
+
"web": "http://www.christophdorn.com/",
|
26 |
+
"alias": {
|
27 |
+
"github": "cadorn"
|
28 |
+
}
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"name": "Michael Day",
|
32 |
+
"email": "manveru.alma@gmail.com"
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"name": "Sokolov Innokenty",
|
36 |
+
"email": "sokolov.innokenty@gmail.com",
|
37 |
+
"alias": {
|
38 |
+
"github": "qbbr"
|
39 |
+
}
|
40 |
+
}
|
41 |
+
]
|
42 |
+
}
|
includes/debug/browsers/api/firephp/program.json
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"extends": {
|
3 |
+
"location": "./workspace/program.json"
|
4 |
+
}
|
5 |
+
}
|
includes/debug/browsers/api/firephp/tests/API/newlines.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
set_include_path(dirname(dirname(dirname(__FILE__))).'/lib'.PATH_SEPARATOR.get_include_path());
|
4 |
+
require('FirePHPCore/fb.php');
|
5 |
+
|
6 |
+
|
7 |
+
fb('Hello\nWorld');
|
8 |
+
fb(array('Hello\nWorld'));
|
9 |
+
fb(array('Table cell with newline',array(
|
10 |
+
array('Header'),
|
11 |
+
array('Hello\nWorld'),
|
12 |
+
)),FirePHP::TABLE);
|
includes/debug/browsers/api/firephp/tests/FirePHPCore/FirePHPTest.php
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class FirePHPCore_FirePHPTest extends PHPUnit_Framework_TestCase
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @issue http://code.google.com/p/firephp/issues/detail?id=117
|
7 |
+
*/
|
8 |
+
public function testDumpArguments()
|
9 |
+
{
|
10 |
+
$firephp = new FirePHP_Test_Class();
|
11 |
+
|
12 |
+
$firephp->dump("key", "value");
|
13 |
+
$headers = $firephp->_getHeaders();
|
14 |
+
$this->assertEquals('15|{"key":"value"}|', $headers['X-Wf-1-2-1-1']);
|
15 |
+
$firephp->_clearHeaders();
|
16 |
+
|
17 |
+
$caught = false;
|
18 |
+
try {
|
19 |
+
$firephp->dump(array(), "value");
|
20 |
+
} catch(Exception $e) {
|
21 |
+
// Key passed to dump() is not a string
|
22 |
+
$caught = true;
|
23 |
+
}
|
24 |
+
if(!$caught) $this->fail('No exception thrown');
|
25 |
+
|
26 |
+
$caught = false;
|
27 |
+
try {
|
28 |
+
$firephp->dump("key \n\r value", "value");
|
29 |
+
} catch(Exception $e) {
|
30 |
+
// Key passed to dump() contains invalid characters [a-zA-Z0-9-_\.:]
|
31 |
+
$caught = true;
|
32 |
+
}
|
33 |
+
if(!$caught) $this->fail('No exception thrown');
|
34 |
+
|
35 |
+
$caught = false;
|
36 |
+
try {
|
37 |
+
$firephp->dump("keykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeyk1", "value");
|
38 |
+
} catch(Exception $e) {
|
39 |
+
// Key passed to dump() is longer than 100 characters
|
40 |
+
$caught = true;
|
41 |
+
}
|
42 |
+
if(!$caught) $this->fail('No exception thrown');
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @issue http://code.google.com/p/firephp/issues/detail?id=123
|
47 |
+
*/
|
48 |
+
public function testRegisterErrorHandler()
|
49 |
+
{
|
50 |
+
$firephp = new FirePHP_Test_Class();
|
51 |
+
$firephp->setOption("maxObjectDepth", 1);
|
52 |
+
$firephp->setOption("maxArrayDepth", 1);
|
53 |
+
|
54 |
+
$firephp->registerErrorHandler();
|
55 |
+
trigger_error("Hello World");
|
56 |
+
$headers = $firephp->_getHeaders();
|
57 |
+
if(!isset($headers["X-Wf-1-1-1-1"])) {
|
58 |
+
$this->fail("Error not in headers");
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @issue http://code.google.com/p/firephp/issues/detail?id=122
|
64 |
+
*/
|
65 |
+
public function testFirePHPClassInstanceLogging()
|
66 |
+
{
|
67 |
+
$firephp = new FirePHP_Test_Class();
|
68 |
+
|
69 |
+
$firephp->log($firephp);
|
70 |
+
$headers = $firephp->_getHeaders();
|
71 |
+
if(!preg_match_all('/"protected:objectStack":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) {
|
72 |
+
$this->fail("objectStack member contains value");
|
73 |
+
}
|
74 |
+
if(!preg_match_all('/"protected:static:instance":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) {
|
75 |
+
$this->fail("instance member should not be logged");
|
76 |
+
}
|
77 |
+
if(!preg_match_all('/"undeclared:json_objectStack":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) {
|
78 |
+
$this->fail("json_objectStack member should not be logged");
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @issue http://code.google.com/p/firephp/issues/detail?id=114
|
84 |
+
*/
|
85 |
+
public function testCustomFileLineOptions()
|
86 |
+
{
|
87 |
+
$firephp = new FirePHP_Test_Class();
|
88 |
+
|
89 |
+
$firephp->log("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
90 |
+
$firephp->info("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
91 |
+
$firephp->warn("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
92 |
+
$firephp->error("message", "label", array("File"=>"/file/path", "Line"=>"1"));
|
93 |
+
$firephp->dump("key", "value", array("File"=>"/file/path", "Line"=>"1"));
|
94 |
+
$firephp->table("label", array(array("header"),array("cell")), array("File"=>"/file/path", "Line"=>"1"));
|
95 |
+
|
96 |
+
$headers = $firephp->_getHeaders();
|
97 |
+
|
98 |
+
$this->assertEquals('75|[{"File":"\/file\/path","Line":"1","Type":"LOG","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-1']);
|
99 |
+
$this->assertEquals('76|[{"File":"\/file\/path","Line":"1","Type":"INFO","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-2']);
|
100 |
+
$this->assertEquals('76|[{"File":"\/file\/path","Line":"1","Type":"WARN","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-3']);
|
101 |
+
$this->assertEquals('77|[{"File":"\/file\/path","Line":"1","Type":"ERROR","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-4']);
|
102 |
+
$this->assertEquals('15|{"key":"value"}|', $headers['X-Wf-1-2-1-5']);
|
103 |
+
$this->assertEquals('89|[{"File":"\/file\/path","Line":"1","Type":"TABLE","Label":"label"},[["header"],["cell"]]]|', $headers['X-Wf-1-1-1-6']);
|
104 |
+
}
|
105 |
+
|
106 |
+
public function testRecursiveEncode()
|
107 |
+
{
|
108 |
+
$firephp = new FirePHP_Test_Class();
|
109 |
+
|
110 |
+
$obj = new FirePHPCore_FirePHPTest__TestObject();
|
111 |
+
$obj->child = $obj;
|
112 |
+
|
113 |
+
$firephp->log($obj, "label", array("File"=>"/file/path", "Line"=>"1"));
|
114 |
+
$headers = $firephp->_getHeaders();
|
115 |
+
$this->assertEquals('215|[{"File":"\/file\/path","Line":"1","Type":"LOG","Label":"label"},{"__className":"FirePHPCore_FirePHPTest__TestObject","public:var":"value","undeclared:child":"** Recursion (FirePHPCore_FirePHPTest__TestObject) **"}]|', $headers['X-Wf-1-1-1-1']);
|
116 |
+
}
|
117 |
+
|
118 |
+
public function testOptions()
|
119 |
+
{
|
120 |
+
$firephp = new FirePHP_Test_Class();
|
121 |
+
|
122 |
+
// defaults
|
123 |
+
$this->assertEquals(5, $firephp->getOption("maxObjectDepth"));
|
124 |
+
$this->assertEquals(5, $firephp->getOption("maxArrayDepth"));
|
125 |
+
$this->assertEquals(true, $firephp->getOption("useNativeJsonEncode"));
|
126 |
+
$this->assertEquals(true, $firephp->getOption("includeLineNumbers"));
|
127 |
+
|
128 |
+
// modify
|
129 |
+
$firephp->setOption("maxObjectDepth", 1);
|
130 |
+
$this->assertEquals(1, $firephp->getOption("maxObjectDepth"));
|
131 |
+
|
132 |
+
// invalid
|
133 |
+
$caught = false;
|
134 |
+
try {
|
135 |
+
$firephp->setOption("invalidName", 1);
|
136 |
+
} catch(Exception $e) {
|
137 |
+
$caught = true;
|
138 |
+
}
|
139 |
+
if(!$caught) $this->fail('No exception thrown');
|
140 |
+
|
141 |
+
$caught = false;
|
142 |
+
try {
|
143 |
+
$firephp->getOption("invalidName");
|
144 |
+
} catch(Exception $e) {
|
145 |
+
$caught = true;
|
146 |
+
}
|
147 |
+
if(!$caught) $this->fail('No exception thrown');
|
148 |
+
}
|
149 |
+
|
150 |
+
public function testDeprecatedMethods()
|
151 |
+
{
|
152 |
+
$firephp = new FirePHP_Test_Class();
|
153 |
+
|
154 |
+
$caught = false;
|
155 |
+
try {
|
156 |
+
$firephp->setProcessorUrl('URL');
|
157 |
+
} catch(Exception $e) {
|
158 |
+
$caught = true;
|
159 |
+
$this->assertEquals(E_USER_DEPRECATED, $e->getCode());
|
160 |
+
$this->assertEquals('The FirePHP::setProcessorUrl() method is no longer supported', $e->getMessage());
|
161 |
+
}
|
162 |
+
if(!$caught) $this->fail('No deprecation error thrown');
|
163 |
+
|
164 |
+
$caught = false;
|
165 |
+
try {
|
166 |
+
$firephp->setRendererUrl('URL');
|
167 |
+
} catch(Exception $e) {
|
168 |
+
$caught = true;
|
169 |
+
$this->assertEquals(E_USER_DEPRECATED, $e->getCode());
|
170 |
+
$this->assertEquals('The FirePHP::setRendererUrl() method is no longer supported', $e->getMessage());
|
171 |
+
}
|
172 |
+
if(!$caught) $this->fail('No deprecation error thrown');
|
173 |
+
}
|
174 |
+
|
175 |
+
}
|
176 |
+
|
177 |
+
|
178 |
+
class FirePHPCore_FirePHPTest__TestObject
|
179 |
+
{
|
180 |
+
public $var = "value";
|
181 |
+
}
|
includes/debug/browsers/api/firephp/tests/TestHelper.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
function __autoload__($class)
|
4 |
+
{
|
5 |
+
if (strpos($class, 'FirePHPCore') !== 0 && $class != 'FirePHP') {
|
6 |
+
return;
|
7 |
+
}
|
8 |
+
|
9 |
+
$basePath = dirname(dirname(__FILE__)) . '/lib';
|
10 |
+
if (!file_exists($basePath)) {
|
11 |
+
$basePath = dirname(dirname(dirname(dirname(__FILE__)))) . '/lib';
|
12 |
+
}
|
13 |
+
|
14 |
+
if ($class == 'FirePHP') {
|
15 |
+
$class = 'FirePHPCore/FirePHP.class';
|
16 |
+
}
|
17 |
+
|
18 |
+
// find relative
|
19 |
+
if (file_exists($file = $basePath . '/' . str_replace('_', '/', $class) . '.php')) {
|
20 |
+
require_once($file);
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
spl_autoload_register('__autoload__');
|
25 |
+
|
26 |
+
class FirePHP_Test_Class extends FirePHP {
|
27 |
+
|
28 |
+
private $_headers = array();
|
29 |
+
|
30 |
+
|
31 |
+
public function _getHeaders() {
|
32 |
+
return $this->_headers;
|
33 |
+
}
|
34 |
+
public function _clearHeaders() {
|
35 |
+
$this->_headers = array();
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
// ######################
|
40 |
+
// # Subclassed Methods #
|
41 |
+
// ######################
|
42 |
+
|
43 |
+
protected function setHeader($Name, $Value) {
|
44 |
+
$this->_headers[$Name] = $Value;
|
45 |
+
}
|
46 |
+
|
47 |
+
protected function headersSent(&$Filename, &$Linenum) {
|
48 |
+
return false;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function detectClientExtension() {
|
52 |
+
return true;
|
53 |
+
}
|
54 |
+
|
55 |
+
}
|
includes/debug/browsers/api/firephp/tests/phpunit.xml
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<phpunit bootstrap="TestHelper.php">
|
2 |
+
</phpunit>
|
includes/debug/browsers/api/firephp/workspace/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
The [PINF JavaScript Loader](https://github.com/pinf/loader-js) is used to provide a development environment and package releases for this project.
|
3 |
+
|
4 |
+
**NOTE:** It is assumed you have the _PINF JavaScript Loader_ mapped to the `commonjs` command and are using the `node` platform by default as explained [here](https://github.com/pinf/loader-js/blob/master/docs/Setup.md).
|
5 |
+
|
6 |
+
|
7 |
+
Publishing
|
8 |
+
==========
|
9 |
+
|
10 |
+
git tag v...
|
11 |
+
|
12 |
+
commonjs -v --script build .
|
13 |
+
|
14 |
+
commonjs -v --script publish .
|
15 |
+
|
16 |
+
|
17 |
+
TODO: Auto-upload to PEAR channel server at http://pear.firephp.org/
|
18 |
+
|
19 |
+
NOTE: For PEAR RC releases: Change release stability to "beta" and capitalize "RC" in release version in package.xml
|
includes/debug/browsers/api/firephp/workspace/lib/project.js
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
exports.main = function(options)
|
3 |
+
{
|
4 |
+
|
5 |
+
}
|
includes/debug/browsers/api/firephp/workspace/package.json
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "firephp-core",
|
3 |
+
"engine": [
|
4 |
+
"node"
|
5 |
+
],
|
6 |
+
"main": "lib/project.js",
|
7 |
+
"scripts": {
|
8 |
+
"build": {
|
9 |
+
"location": "./",
|
10 |
+
"module": "/scripts/build.js"
|
11 |
+
},
|
12 |
+
"publish": {
|
13 |
+
"location": "./",
|
14 |
+
"module": "/scripts/publish.js"
|
15 |
+
}
|
16 |
+
},
|
17 |
+
"mappings": {
|
18 |
+
"nodejs": {
|
19 |
+
"id": "nodejs.org/"
|
20 |
+
},
|
21 |
+
"pinf": {
|
22 |
+
"id": "pinf.org/loader/"
|
23 |
+
},
|
24 |
+
"modules": {
|
25 |
+
"id": "github.com/pinf/modules-js/"
|
26 |
+
}
|
27 |
+
}
|
28 |
+
}
|
includes/debug/browsers/api/firephp/workspace/program.json
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"boot": "workspace",
|
3 |
+
"engine": [
|
4 |
+
"node"
|
5 |
+
],
|
6 |
+
"packages": {
|
7 |
+
"workspace": {
|
8 |
+
"locator": {
|
9 |
+
"location": "./"
|
10 |
+
}
|
11 |
+
},
|
12 |
+
"nodejs.org/": {
|
13 |
+
"provider": "nodejs.org/"
|
14 |
+
},
|
15 |
+
"pinf.org/loader/": {
|
16 |
+
"provider": "pinf.org/loader/"
|
17 |
+
},
|
18 |
+
"github.com/pinf/modules-js/": {
|
19 |
+
"locator": {
|
20 |
+
"archive": "https://github.com/pinf/modules-js/zipball/master"
|
21 |
+
}
|
22 |
+
},
|
23 |
+
"github.com/kriskowal/q/": {
|
24 |
+
"locator": {
|
25 |
+
"archive": "https://github.com/kriskowal/q/zipball/v0.3.0"
|
26 |
+
},
|
27 |
+
"descriptor": {
|
28 |
+
"uid": "https://github.com/kriskowal/q/",
|
29 |
+
"dependencies": [
|
30 |
+
{
|
31 |
+
"id": "github.com/pinf/modules-js/"
|
32 |
+
}
|
33 |
+
]
|
34 |
+
}
|
35 |
+
},
|
36 |
+
"private-registry.appspot.com/cadorn.com/github/com.cadorn.baby/projects/sourcemint/packages/client-js/": {
|
37 |
+
"locator": {
|
38 |
+
"archive": "https://github.com/cadorn/com.cadorn.baby/zipball/master",
|
39 |
+
"path": "projects/sourcemint/packages/client-js"
|
40 |
+
}
|
41 |
+
},
|
42 |
+
"github.com/cadorn/aws-lib/": {
|
43 |
+
"locator": {
|
44 |
+
"archive": "https://github.com/cadorn/aws-lib/zipball/master"
|
45 |
+
},
|
46 |
+
"descriptor": {
|
47 |
+
"uid": "https://github.com/cadorn/aws-lib/",
|
48 |
+
"native": true,
|
49 |
+
"dependencies": [
|
50 |
+
{
|
51 |
+
"id": "registry.npmjs.org/sax/"
|
52 |
+
},
|
53 |
+
{
|
54 |
+
"id": "registry.npmjs.org/xml2js/"
|
55 |
+
}
|
56 |
+
]
|
57 |
+
}
|
58 |
+
},
|
59 |
+
"registry.npmjs.org/sax/": {
|
60 |
+
"locator": {
|
61 |
+
"archive": "http://registry.npmjs.org/sax/-/sax-0.1.2.tgz"
|
62 |
+
},
|
63 |
+
"descriptor": {
|
64 |
+
"uid": "http://registry.npmjs.org/sax/",
|
65 |
+
"native": true
|
66 |
+
}
|
67 |
+
},
|
68 |
+
"registry.npmjs.org/xml2js/": {
|
69 |
+
"locator": {
|
70 |
+
"archive": "http://registry.npmjs.org/xml2js/-/xml2js-0.1.6.tgz"
|
71 |
+
},
|
72 |
+
"descriptor": {
|
73 |
+
"uid": "http://registry.npmjs.org/xml2js/",
|
74 |
+
"native": true
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
includes/debug/browsers/api/firephp/workspace/scripts/build.js
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
var FILE = require("modules/file"),
|
3 |
+
Q = require("modules/q"),
|
4 |
+
SYSTEM = require("modules/system"),
|
5 |
+
UTIL = require("modules/util"),
|
6 |
+
JSON = require("modules/json");
|
7 |
+
|
8 |
+
|
9 |
+
var pkgPath = FILE.dirname(FILE.dirname(FILE.dirname(module.id))),
|
10 |
+
buildPath = pkgPath + "/build",
|
11 |
+
tplPath = pkgPath + "/workspace/tpl",
|
12 |
+
version = false;
|
13 |
+
|
14 |
+
exports.getBuildPath = function()
|
15 |
+
{
|
16 |
+
return buildPath;
|
17 |
+
}
|
18 |
+
|
19 |
+
exports.main = function()
|
20 |
+
{
|
21 |
+
|
22 |
+
SYSTEM.exec("rm -Rf " + buildPath, function()
|
23 |
+
{
|
24 |
+
FILE.mkdirs(buildPath, 0775);
|
25 |
+
|
26 |
+
SYSTEM.exec("git tag", function(stdout)
|
27 |
+
{
|
28 |
+
version = UTIL.trim(stdout).split("\n").pop().match(/^v(.*)$/)[1];
|
29 |
+
|
30 |
+
// TODO: Compare against version in `../../program.json ~ version` (ensure =)
|
31 |
+
|
32 |
+
module.print("\0cyan(Building version: " + version + "\0)\n");
|
33 |
+
|
34 |
+
buildZipArchive(function()
|
35 |
+
{
|
36 |
+
buildPEARArchive(function()
|
37 |
+
{
|
38 |
+
done();
|
39 |
+
});
|
40 |
+
});
|
41 |
+
});
|
42 |
+
});
|
43 |
+
|
44 |
+
function done()
|
45 |
+
{
|
46 |
+
module.print("\0green(Done\0)\n");
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
function buildZipArchive(callback)
|
51 |
+
{
|
52 |
+
var targetBasePath = buildPath + "/FirePHPCore-" + version;
|
53 |
+
|
54 |
+
FILE.mkdirs(targetBasePath, 0775);
|
55 |
+
|
56 |
+
SYSTEM.exec("rsync -r --copy-links --exclude \"- .DS_Store\" --exclude \"- .git/\" --exclude \"- .tmp_*\" " + pkgPath + "/lib " + targetBasePath, function()
|
57 |
+
{
|
58 |
+
replaceVariablesInFile(targetBasePath + "/lib/FirePHPCore/FirePHP.class.php");
|
59 |
+
replaceVariablesInFile(targetBasePath + "/lib/FirePHPCore/FirePHP.class.php4");
|
60 |
+
|
61 |
+
SYSTEM.exec("cp -Rf " + pkgPath + "/examples " + targetBasePath, function()
|
62 |
+
{
|
63 |
+
next1();
|
64 |
+
});
|
65 |
+
});
|
66 |
+
|
67 |
+
function next1()
|
68 |
+
{
|
69 |
+
var content = FILE.read(tplPath + "/readme.tpl.md");
|
70 |
+
content = content.replace(/%%VERSION%%/g, version);
|
71 |
+
FILE.write(targetBasePath + "/README.md", content);
|
72 |
+
|
73 |
+
var content = FILE.read(tplPath + "/license.tpl.md");
|
74 |
+
FILE.write(targetBasePath + "/LICENSE.md", content);
|
75 |
+
|
76 |
+
FILE.write(buildPath + "/info.json", JSON.encode({
|
77 |
+
version: version
|
78 |
+
}));
|
79 |
+
|
80 |
+
next2();
|
81 |
+
}
|
82 |
+
|
83 |
+
function next2()
|
84 |
+
{
|
85 |
+
SYSTEM.exec("cd " + buildPath + " ; zip -vr FirePHPCore-" + version + ".zip FirePHPCore-" + version, function(stdout)
|
86 |
+
{
|
87 |
+
console.log(stdout);
|
88 |
+
|
89 |
+
callback();
|
90 |
+
});
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
function buildPEARArchive(callback)
|
95 |
+
{
|
96 |
+
var targetBasePath = buildPath + "/pear";
|
97 |
+
|
98 |
+
FILE.mkdirs(targetBasePath, 0775);
|
99 |
+
|
100 |
+
SYSTEM.exec("rsync -r --copy-links --exclude \"- .DS_Store\" --exclude \"- .git/\" --exclude \"- .tmp_*\" " + pkgPath + "/lib/FirePHPCore/* " + targetBasePath, function()
|
101 |
+
{
|
102 |
+
replaceVariablesInFile(targetBasePath + "/FirePHP.class.php");
|
103 |
+
replaceVariablesInFile(targetBasePath + "/FirePHP.class.php4");
|
104 |
+
|
105 |
+
next1();
|
106 |
+
});
|
107 |
+
|
108 |
+
function next1()
|
109 |
+
{
|
110 |
+
var content = FILE.read(tplPath + "/pear.package.tpl.xml");
|
111 |
+
|
112 |
+
var date = new Date();
|
113 |
+
content = content.replace(/%%DATE%%/g, date.getFullYear() + "-" + UTIL.padBegin(date.getMonth()+1, 2, "0") + "-" + date.getDate());
|
114 |
+
content = content.replace(/%%VERSION%%/g, version);
|
115 |
+
content = content.replace(/%%STABILITY%%/g, "stable");
|
116 |
+
|
117 |
+
FILE.write(targetBasePath + "/package.xml", content);
|
118 |
+
|
119 |
+
next2();
|
120 |
+
}
|
121 |
+
|
122 |
+
function next2()
|
123 |
+
{
|
124 |
+
SYSTEM.exec("pear channel-discover pear.firephp.org", function(stdout)
|
125 |
+
{
|
126 |
+
console.log(stdout);
|
127 |
+
|
128 |
+
SYSTEM.exec("cd " + targetBasePath + "; pear package package.xml", function(stdout)
|
129 |
+
{
|
130 |
+
console.log(stdout);
|
131 |
+
|
132 |
+
callback();
|
133 |
+
});
|
134 |
+
});
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
function replaceVariablesInFile(path)
|
139 |
+
{
|
140 |
+
var content = FILE.read(path);
|
141 |
+
|
142 |
+
// @pinf replace '0.3' with '%%VERSION%%'
|
143 |
+
var re1 = /\n(.*)\/\/\s*@pinf\s(.*)\n/g;
|
144 |
+
var match1;
|
145 |
+
while (match1 = re1.exec(content)) {
|
146 |
+
var rule = match1[2].match(/^replace (.*?) with (.*)$/);
|
147 |
+
if(rule) {
|
148 |
+
// replace variables in rule
|
149 |
+
var re2 = /%%([^%]*)%%/g;
|
150 |
+
var match2;
|
151 |
+
while (match2 = re2.exec(rule[2])) {
|
152 |
+
var value;
|
153 |
+
if(match2[1]=="VERSION") {
|
154 |
+
value = version;
|
155 |
+
}
|
156 |
+
rule[2] = rule[2].replace(match2[0], value);
|
157 |
+
}
|
158 |
+
match1[1] = match1[1].replace(rule[1], rule[2]);
|
159 |
+
content = content.replace(match1[0], "\n"+match1[1]+"\n");
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
FILE.write(path, content);
|
164 |
+
}
|
includes/debug/browsers/api/firephp/workspace/scripts/publish.js
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
var PINF_LOADER = require("pinf/loader"),
|
3 |
+
SANDBOX = PINF_LOADER.getSandbox(),
|
4 |
+
FILE = require("modules/file"),
|
5 |
+
Q = require("modules/q"),
|
6 |
+
SYSTEM = require("modules/system"),
|
7 |
+
BUILD = require("./build"),
|
8 |
+
JSON = require("modules/json"),
|
9 |
+
SOURCEMINT_CLIENT = false;
|
10 |
+
|
11 |
+
exports.main = function()
|
12 |
+
{
|
13 |
+
module.load({
|
14 |
+
id: "private-registry.appspot.com/cadorn.com/github/com.cadorn.baby/projects/sourcemint/packages/client-js/",
|
15 |
+
descriptor: {
|
16 |
+
main: "lib/client.js"
|
17 |
+
}
|
18 |
+
}, function(id)
|
19 |
+
{
|
20 |
+
SOURCEMINT_CLIENT = require(id);
|
21 |
+
|
22 |
+
publish();
|
23 |
+
});
|
24 |
+
}
|
25 |
+
|
26 |
+
function publish()
|
27 |
+
{
|
28 |
+
var buildPath = BUILD.getBuildPath(),
|
29 |
+
info = JSON.decode(FILE.read(buildPath + "/info.json")),
|
30 |
+
descriptor = JSON.decode(FILE.read(FILE.dirname(FILE.dirname(FILE.dirname(module.id))) + "/package.json"));
|
31 |
+
|
32 |
+
var bundles = {};
|
33 |
+
bundles["firephp-core.zip"] = {
|
34 |
+
"type": "zip",
|
35 |
+
"options": {
|
36 |
+
"archivePath": buildPath + "/FirePHPCore-" + info.version + ".zip",
|
37 |
+
}
|
38 |
+
};
|
39 |
+
|
40 |
+
var packages = [
|
41 |
+
{
|
42 |
+
"uid": descriptor.uid,
|
43 |
+
"stream": "stable",
|
44 |
+
"version": info.version,
|
45 |
+
"bundles": bundles
|
46 |
+
}
|
47 |
+
];
|
48 |
+
|
49 |
+
try
|
50 |
+
{
|
51 |
+
Q.when(SOURCEMINT_CLIENT.publish(packages), function(info)
|
52 |
+
{
|
53 |
+
module.print("\0green(Published:\n");
|
54 |
+
console.log(info);
|
55 |
+
module.print("\0)");
|
56 |
+
}, function(e)
|
57 |
+
{
|
58 |
+
throw e;
|
59 |
+
});
|
60 |
+
}
|
61 |
+
catch(e)
|
62 |
+
{
|
63 |
+
console.error("Error: " + e);
|
64 |
+
}
|
65 |
+
}
|
includes/debug/browsers/api/firephp/workspace/tpl/license.tpl.md
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[MIT License](http://www.opensource.org/licenses/mit-license.php)
|
2 |
+
|
3 |
+
Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/)
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in
|
13 |
+
all copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21 |
+
THE SOFTWARE.
|
includes/debug/browsers/api/firephp/workspace/tpl/pear.package.tpl.xml
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<package packagerversion="1.7.1"
|
3 |
+
version="2.0"
|
4 |
+
xmlns="http://pear.php.net/dtd/package-2.0"
|
5 |
+
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
|
6 |
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
7 |
+
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
|
8 |
+
|
9 |
+
<name>FirePHPCore</name>
|
10 |
+
<channel>pear.firephp.org</channel>
|
11 |
+
<summary>Log variables from PHP to the browser (Firebug Console)</summary>
|
12 |
+
<description>Handles all communication between the PHP code on the server and the client. Also implements all core FirePHP features.</description>
|
13 |
+
|
14 |
+
<lead>
|
15 |
+
<name>Christoph Dorn</name>
|
16 |
+
<user>cadorn</user>
|
17 |
+
<email>christoph@christophdorn.com</email>
|
18 |
+
<active>yes</active>
|
19 |
+
</lead>
|
20 |
+
|
21 |
+
<date>%%DATE%%</date>
|
22 |
+
<version>
|
23 |
+
<release>%%VERSION%%</release>
|
24 |
+
<api>0.3</api>
|
25 |
+
</version>
|
26 |
+
|
27 |
+
<stability>
|
28 |
+
<release>%%STABILITY%%</release>
|
29 |
+
<api>stable</api>
|
30 |
+
</stability>
|
31 |
+
|
32 |
+
<license>MIT</license>
|
33 |
+
|
34 |
+
<notes>No Notes</notes>
|
35 |
+
|
36 |
+
<contents>
|
37 |
+
<dir name="/" baseinstalldir="FirePHPCore">
|
38 |
+
|
39 |
+
<file name="fb.php" role="php"/>
|
40 |
+
<file name="fb.php4" role="php"/>
|
41 |
+
|
42 |
+
<file name="FirePHP.class.php" role="php"/>
|
43 |
+
<file name="FirePHP.class.php4" role="php"/>
|
44 |
+
|
45 |
+
</dir>
|
46 |
+
</contents>
|
47 |
+
|
48 |
+
<dependencies>
|
49 |
+
<required>
|
50 |
+
<php>
|
51 |
+
<min>4.0</min>
|
52 |
+
</php>
|
53 |
+
<pearinstaller>
|
54 |
+
<min>1.4.5</min>
|
55 |
+
</pearinstaller>
|
56 |
+
</required>
|
57 |
+
</dependencies>
|
58 |
+
|
59 |
+
<phprelease />
|
60 |
+
|
61 |
+
</package>
|
includes/debug/browsers/api/firephp/workspace/tpl/readme.tpl.md
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FirePHPCore Server Library
|
2 |
+
==========================
|
3 |
+
|
4 |
+
Status: stable
|
5 |
+
|
6 |
+
Version: [%%VERSION%%](https://github.com/firephp/firephp-core/tree/v%%VERSION%%)
|
7 |
+
|
8 |
+
This archive contains the *FirePHPCore* PHP server library.
|
9 |
+
|
10 |
+
Links
|
11 |
+
-----
|
12 |
+
|
13 |
+
* Documentation: http://docs.sourcemint.org/firephp.org/firephp/1/-docs/
|
14 |
+
* Install: http://docs.sourcemint.org/firephp.org/firephp/1/-docs/Configuration/Traditional
|
15 |
+
* Support: http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#support
|
16 |
+
* Author: [Christoph Dorn](http://www.christophdorn.com/)
|
17 |
+
* License: [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
includes/debug/classes/wpstgDebug.class.php
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* wpstgDebug
|
4 |
+
*
|
5 |
+
* Based on WP Log in browser by MZAWeb
|
6 |
+
* http://wordpress.org/plugins/wp-log-in-browser
|
7 |
+
*
|
8 |
+
* @package WPSTG
|
9 |
+
* @subpackage Classes/debug
|
10 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
11 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
12 |
+
* @since 0.9.0
|
13 |
+
* @author MZAWeb
|
14 |
+
* @author Rene Hermenau
|
15 |
+
*
|
16 |
+
*/
|
17 |
+
|
18 |
+
if ( class_exists( "wpstgDebug" ) )
|
19 |
+
return;
|
20 |
+
|
21 |
+
class wpstgDebug implements iWPstgDebug {
|
22 |
+
|
23 |
+
private static $instance;
|
24 |
+
private $path;
|
25 |
+
|
26 |
+
private $interfaces = array();
|
27 |
+
private static $timers = array();
|
28 |
+
private static $memory = array();
|
29 |
+
|
30 |
+
public function __construct() {
|
31 |
+
|
32 |
+
$this->path = trailingslashit( dirname( dirname( __FILE__ ) ) );
|
33 |
+
|
34 |
+
$this->_get_interfaces();
|
35 |
+
|
36 |
+
add_action( 'init', array( $this, 'init' ) );
|
37 |
+
add_action( 'shutdown', array( $this, 'shutdown' ) );
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
/************* API **************/
|
42 |
+
|
43 |
+
/**
|
44 |
+
*
|
45 |
+
* @param mixed $var
|
46 |
+
* @param string $label
|
47 |
+
*
|
48 |
+
* @return wpstgDebug
|
49 |
+
*/
|
50 |
+
public function log( $var, $label = null ) {
|
51 |
+
$this->_run( 'log', array( $var, $label ) );
|
52 |
+
return $this;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
*
|
57 |
+
* @param mixed $var
|
58 |
+
* @param string $label
|
59 |
+
*
|
60 |
+
* @return wpstgDebug
|
61 |
+
*/
|
62 |
+
public function info( $var, $label = null ) {
|
63 |
+
$this->_run( 'info', array( $var, $label ) );
|
64 |
+
return $this;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param mixed $var
|
69 |
+
* @param string $label
|
70 |
+
*
|
71 |
+
* @return wpstgDebug
|
72 |
+
*/
|
73 |
+
public function warn( $var, $label = null ) {
|
74 |
+
$this->_run( 'warn', array( $var, $label ) );
|
75 |
+
return $this;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @param mixed $var
|
80 |
+
* @param string $label
|
81 |
+
*
|
82 |
+
* @return wpstgDebug
|
83 |
+
*/
|
84 |
+
public function error( $var, $label = null ) {
|
85 |
+
$this->_run( 'error', array( $var, $label ) );
|
86 |
+
return $this;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @static
|
91 |
+
*
|
92 |
+
* @param string $key
|
93 |
+
* @param bool $log
|
94 |
+
*
|
95 |
+
* @return bool|float
|
96 |
+
*
|
97 |
+
*/
|
98 |
+
public function timer( $key, $log = false ) {
|
99 |
+
if ( !isset( self::$timers[$key] ) ) {
|
100 |
+
$time = microtime();
|
101 |
+
$time = explode( ' ', $time );
|
102 |
+
$time = $time[1] + $time[0];
|
103 |
+
self::$timers[$key] = $time;
|
104 |
+
return false;
|
105 |
+
|
106 |
+
} else {
|
107 |
+
$time = microtime();
|
108 |
+
$time = explode( ' ', $time );
|
109 |
+
$time = $time[1] + $time[0];
|
110 |
+
$finish = $time;
|
111 |
+
$total_time = round( ( $finish - self::$timers[$key] ), 4 );
|
112 |
+
|
113 |
+
if ( $log )
|
114 |
+
$this->log( $total_time, $key );
|
115 |
+
|
116 |
+
unset( self::$timers[$key] );
|
117 |
+
|
118 |
+
return $total_time;
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @static
|
125 |
+
*
|
126 |
+
* @param string $key
|
127 |
+
* @param bool $log
|
128 |
+
*
|
129 |
+
* @return bool|float
|
130 |
+
*
|
131 |
+
*/
|
132 |
+
public function memory( $key, $log = false ) {
|
133 |
+
if ( !isset( self::$memory[$key] ) ) {
|
134 |
+
$memory = memory_get_usage();
|
135 |
+
self::$memory[$key] = $memory;
|
136 |
+
|
137 |
+
return false;
|
138 |
+
} else {
|
139 |
+
$memory = memory_get_usage();
|
140 |
+
$total_memory = $memory - self::$memory[$key];
|
141 |
+
|
142 |
+
if ( $log )
|
143 |
+
$this->log( $total_memory, $key );
|
144 |
+
|
145 |
+
unset( self::$memory[$key] );
|
146 |
+
|
147 |
+
return $total_memory;
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
/************* API **************/
|
152 |
+
|
153 |
+
public function init() {
|
154 |
+
ob_start();
|
155 |
+
}
|
156 |
+
|
157 |
+
public function shutdown() {
|
158 |
+
if ( ob_get_level() )
|
159 |
+
ob_end_flush();
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* @return bool
|
164 |
+
*/
|
165 |
+
private function _should_run() {
|
166 |
+
global $wpstg_options;
|
167 |
+
//$enabled = apply_filters( 'wplinb-enabled', true );
|
168 |
+
$match_wp_debug = apply_filters( 'wplinb-match-wp-debug', false );
|
169 |
+
$enabled = isset($wpstg_options['debug_mode']) ? $wpstg_options['debug_mode'] : false;
|
170 |
+
|
171 |
+
if ( !$enabled )
|
172 |
+
return false;
|
173 |
+
|
174 |
+
if ( !$match_wp_debug )
|
175 |
+
return true;
|
176 |
+
|
177 |
+
if ( WP_DEBUG )
|
178 |
+
return true;
|
179 |
+
|
180 |
+
return false;
|
181 |
+
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* @param string $command
|
186 |
+
* @param array $params
|
187 |
+
*/
|
188 |
+
private function _run( $command, $params = array() ) {
|
189 |
+
|
190 |
+
if ( !$this->_should_run() )
|
191 |
+
return;
|
192 |
+
|
193 |
+
if ( empty( $this->interfaces ) )
|
194 |
+
return;
|
195 |
+
|
196 |
+
foreach ( $this->interfaces as $interface ) {
|
197 |
+
try {
|
198 |
+
call_user_func_array( array( $interface, $command ), $params );
|
199 |
+
} catch ( Exception $e ) {
|
200 |
+
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
*
|
207 |
+
*/
|
208 |
+
private function _get_interfaces() {
|
209 |
+
// This will come from the admin config
|
210 |
+
$selected_interfaces = array( 'FirePHP', 'ChromePHP' );
|
211 |
+
|
212 |
+
$selected_interfaces = apply_filters( 'wplinb-selected-interfaces', $selected_interfaces );
|
213 |
+
|
214 |
+
foreach ( (array)$selected_interfaces as $interface_name ) {
|
215 |
+
$interface = $this->_get_interface( $interface_name );
|
216 |
+
if ( !empty( $interface ) )
|
217 |
+
$this->interfaces[] = $interface;
|
218 |
+
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @param $interface_name
|
224 |
+
*
|
225 |
+
* @return mixed|null|WPChromePHP|WPFirePHP
|
226 |
+
*/
|
227 |
+
private function _get_interface( $interface_name ) {
|
228 |
+
|
229 |
+
switch ( $interface_name ) {
|
230 |
+
|
231 |
+
case 'FirePHP':
|
232 |
+
include $this->path . 'browsers/WPFirePHP.class.php';
|
233 |
+
$interface = new WPFirePHP();
|
234 |
+
break;
|
235 |
+
|
236 |
+
case 'ChromePHP':
|
237 |
+
include $this->path . 'browsers/WPChromePHP.class.php';
|
238 |
+
$interface = new WPChromePHP();
|
239 |
+
break;
|
240 |
+
|
241 |
+
default:
|
242 |
+
$interface = apply_filters( 'wplinb-get-interface', null, $interface_name );
|
243 |
+
|
244 |
+
if ( $interface && !in_array( 'iWPstgDebug', class_implements( $interface ) ) )
|
245 |
+
$interface = null;
|
246 |
+
|
247 |
+
break;
|
248 |
+
}
|
249 |
+
|
250 |
+
return $interface;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @static
|
255 |
+
* @return wpstgDebug
|
256 |
+
*
|
257 |
+
* Return an instance of this class. Singleton.
|
258 |
+
*/
|
259 |
+
public static function instance() {
|
260 |
+
if ( !isset( self::$instance ) ) {
|
261 |
+
$className = __CLASS__;
|
262 |
+
self::$instance = new $className;
|
263 |
+
}
|
264 |
+
return self::$instance;
|
265 |
+
}
|
266 |
+
}
|
267 |
+
|
268 |
+
if ( !function_exists( 'wpstgdebug' ) ) {
|
269 |
+
/**
|
270 |
+
* Returns a wpstgDebug instance.
|
271 |
+
*
|
272 |
+
* @return wpstgDebug
|
273 |
+
*/
|
274 |
+
function wpstgdebug() {
|
275 |
+
return wpstgDebug::instance();
|
276 |
+
}
|
277 |
+
}
|
includes/debug/classes/wpstgDebug.interface.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
interface iWPstgDebug {
|
3 |
+
|
4 |
+
public function log( $var, $label = null );
|
5 |
+
|
6 |
+
public function info( $var, $label = null );
|
7 |
+
|
8 |
+
public function warn( $var, $label = null );
|
9 |
+
|
10 |
+
public function error( $var, $label = null );
|
11 |
+
}
|
includes/install.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Install Function
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Functions/Install
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 2.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/* Install Multisite
|
16 |
+
* check first if multisite is enabled
|
17 |
+
* @since 0.9.0
|
18 |
+
*
|
19 |
+
*/
|
20 |
+
|
21 |
+
register_activation_hook( WPSTG_PLUGIN_FILE, 'wpstg_install_multisite' );
|
22 |
+
|
23 |
+
function wpstg_install_multisite($networkwide) {
|
24 |
+
global $wpdb;
|
25 |
+
|
26 |
+
if (function_exists('is_multisite') && is_multisite()) {
|
27 |
+
// check if it is a network activation - if so, run the activation function for each blog id
|
28 |
+
if ($networkwide) {
|
29 |
+
$old_blog = $wpdb->blogid;
|
30 |
+
// Get all blog ids
|
31 |
+
$blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
|
32 |
+
foreach ($blogids as $blog_id) {
|
33 |
+
switch_to_blog($blog_id);
|
34 |
+
wpstg_install();
|
35 |
+
}
|
36 |
+
switch_to_blog($old_blog);
|
37 |
+
return;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
wpstg_install();
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Install
|
45 |
+
*
|
46 |
+
* Runs on plugin install to populates the settings fields for those plugin
|
47 |
+
* pages. After successful install, the user is redirected to the WPSTG Welcome
|
48 |
+
* screen.
|
49 |
+
*
|
50 |
+
* @since 0.9.0
|
51 |
+
* @global $wpdb
|
52 |
+
* @global $wpstg_options
|
53 |
+
* @global $wp_version
|
54 |
+
* @return void
|
55 |
+
*/
|
56 |
+
|
57 |
+
|
58 |
+
|
59 |
+
function wpstg_install() {
|
60 |
+
global $wpdb, $wpstg_options, $wp_version;
|
61 |
+
|
62 |
+
|
63 |
+
// Add Upgraded from Option
|
64 |
+
$current_version = get_option( 'wpstg_version' );
|
65 |
+
if ( $current_version ) {
|
66 |
+
update_option( 'wpstg_version_upgraded_from', $current_version );
|
67 |
+
}
|
68 |
+
|
69 |
+
// Update the current version
|
70 |
+
update_option( 'wpstg_version', WPSTG_VERSION );
|
71 |
+
// Add plugin installation date and variable for rating div
|
72 |
+
add_option('wpstg_installDate',date('Y-m-d h:i:s'));
|
73 |
+
add_option('wpstg_RatingDiv','no');
|
74 |
+
// Add First-time variables
|
75 |
+
add_option('wpstg_firsttime','true');
|
76 |
+
add_option('wpstg_is_staging_site','false');
|
77 |
+
// Show beta notice
|
78 |
+
add_option('wpstg_hide_beta','no');
|
79 |
+
|
80 |
+
// Create empty config files in /wp-content/uploads/wp-staging
|
81 |
+
wpstg_create_remaining_files();
|
82 |
+
wpstg_create_clonedetails_files();
|
83 |
+
|
84 |
+
|
85 |
+
|
86 |
+
/* Setup some default options
|
87 |
+
* Store our initial social networks in separate option row.
|
88 |
+
* For easier modification and to prevent some trouble
|
89 |
+
*/
|
90 |
+
|
91 |
+
// Bail if activating from network, or bulk
|
92 |
+
if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
|
96 |
+
// Add the transient to redirect / not for multisites
|
97 |
+
set_transient( '_wpstg_activation_redirect', true, 30 );
|
98 |
+
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Post-installation
|
103 |
+
*
|
104 |
+
* Runs just after plugin installation and exposes the
|
105 |
+
* wpstg_after_install hook.
|
106 |
+
*
|
107 |
+
* @since 2.0
|
108 |
+
* @return void
|
109 |
+
*/
|
110 |
+
function wpstg_after_install() {
|
111 |
+
|
112 |
+
if ( ! is_admin() ) {
|
113 |
+
return;
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
$activation_pages = get_transient( '_wpstg_activation_pages' );
|
118 |
+
|
119 |
+
// Exit if not in admin or the transient doesn't exist
|
120 |
+
if ( false === $activation_pages ) {
|
121 |
+
return;
|
122 |
+
}
|
123 |
+
|
124 |
+
// Delete the transient
|
125 |
+
delete_transient( '_wpstg_activation_pages' );
|
126 |
+
|
127 |
+
do_action( 'wpstg_after_install', $activation_pages );
|
128 |
+
}
|
129 |
+
add_action( 'admin_init', 'wpstg_after_install' );
|
130 |
+
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Create json remaining_files.json after activation of the plugin
|
134 |
+
*
|
135 |
+
* @return bool
|
136 |
+
*/
|
137 |
+
function wpstg_create_remaining_files() {
|
138 |
+
$path = wpstg_get_upload_dir();
|
139 |
+
if (wp_is_writable($path)) {
|
140 |
+
$file = 'remaining_files.json';
|
141 |
+
file_put_contents($path . '/' . $file, null);
|
142 |
+
}else {
|
143 |
+
WPSTG()->logger->info($path . '/' . $file . ' is not writeable! ');
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Create json cloning_details.json after activation of the plugin
|
149 |
+
*
|
150 |
+
* @return bool
|
151 |
+
*/
|
152 |
+
function wpstg_create_clonedetails_files() {
|
153 |
+
$path = wpstg_get_upload_dir();
|
154 |
+
if (wp_is_writable($path)) {
|
155 |
+
$file = 'clone_details.json';
|
156 |
+
file_put_contents($path . '/' . $file, null);
|
157 |
+
}else {
|
158 |
+
WPSTG()->logger->info($path . '/' . $file . ' is not writeable! ');
|
159 |
+
}
|
160 |
+
}
|
includes/libraries/RolingCurlX.php
ADDED
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Based on RollingCurlX https://github.com/marcushat/rollingcurlx
|
4 |
+
*
|
5 |
+
* Modified for WP-Staging by René Hermenau to be compatible with php 5.3 and older versions
|
6 |
+
*
|
7 |
+
* @scince 2.2.7
|
8 |
+
*/
|
9 |
+
Class RollingCurlX {
|
10 |
+
private $_maxConcurrent = 0; //max. number of simultaneous connections allowed
|
11 |
+
private $_options = array(); //shared cURL options
|
12 |
+
private $_headers = array(); //shared cURL request headers
|
13 |
+
private $_callback = NULL; //default callback
|
14 |
+
private $_timeout = 1; //timeout used for curl_multi_select() function in seconds. Lower this to zero increases total performance.
|
15 |
+
private $requests = array(); //request_queue
|
16 |
+
|
17 |
+
function __construct($max_concurrent = 10) {
|
18 |
+
$this->setMaxConcurrent($max_concurrent);
|
19 |
+
}
|
20 |
+
|
21 |
+
public function setMaxConcurrent($max_requests) {
|
22 |
+
if($max_requests > 0) {
|
23 |
+
$this->_maxConcurrent = $max_requests;
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
public function setOptions(array $options) {
|
28 |
+
$this->_options = $options;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function setHeaders(array $headers) {
|
32 |
+
if(is_array($headers) && count($headers)) {
|
33 |
+
$this->_headers = $headers;
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
//public function setCallback(callable $callback) {
|
39 |
+
public function setCallback($callback) {
|
40 |
+
$this->_callback = $callback;
|
41 |
+
}
|
42 |
+
|
43 |
+
/* Bug on php 5.3 Do not use this
|
44 |
+
|
45 |
+
*/
|
46 |
+
/*public function setTimeout($timeout) { //in milliseconds
|
47 |
+
if($timeout > 0) {
|
48 |
+
$this->_timeout = $timeout/1000; //to seconds
|
49 |
+
}
|
50 |
+
}*/
|
51 |
+
|
52 |
+
//Add a request to the request queue
|
53 |
+
public function addRequest(
|
54 |
+
$url,
|
55 |
+
array $post_data = NULL,
|
56 |
+
//callable $callback = NULL, //individual callback rhe
|
57 |
+
//$callback = NULL, //individual callback
|
58 |
+
array $callback = NULL,
|
59 |
+
$user_data = NULL,
|
60 |
+
array $options = NULL, //individual cURL options
|
61 |
+
array $headers = NULL //individual cURL request headers
|
62 |
+
) { //Add to request queue
|
63 |
+
$this->requests[] = array(
|
64 |
+
'url' => $url,
|
65 |
+
'post_data' => ($post_data) ? $post_data : NULL,
|
66 |
+
'callback' => ($callback) ? $callback : $this->_callback,
|
67 |
+
'user_data' => ($user_data) ? $user_data : NULL,
|
68 |
+
'options' => ($options) ? $options : NULL,
|
69 |
+
'headers' => ($headers) ? $headers : NULL
|
70 |
+
);
|
71 |
+
return count($this->requests) - 1; //return request number/index
|
72 |
+
}
|
73 |
+
|
74 |
+
//Reset request queue
|
75 |
+
public function reset() {
|
76 |
+
$this->requests = array();
|
77 |
+
}
|
78 |
+
|
79 |
+
//Execute the request queue
|
80 |
+
public function execute() {
|
81 |
+
if(count($this->requests) < $this->_maxConcurrent) {
|
82 |
+
$this->_maxConcurrent = count($this->requests);
|
83 |
+
}
|
84 |
+
//the request map that maps the request queue to request curl handles
|
85 |
+
$requests_map = array();
|
86 |
+
$multi_handle = curl_multi_init();
|
87 |
+
//start processing the initial request queue
|
88 |
+
for($i = 0; $i < $this->_maxConcurrent; $i++) {
|
89 |
+
$ch = curl_init();
|
90 |
+
|
91 |
+
$request =& $this->requests[$i];
|
92 |
+
$this->addTimer($request);
|
93 |
+
|
94 |
+
curl_setopt_array($ch, $this->buildOptions($request));
|
95 |
+
curl_multi_add_handle($multi_handle, $ch);
|
96 |
+
|
97 |
+
|
98 |
+
//add curl handle of a request to the request map
|
99 |
+
$key = (string) $ch;
|
100 |
+
$requests_map[$key] = $i;
|
101 |
+
}
|
102 |
+
do{
|
103 |
+
while(($mh_status = curl_multi_exec($multi_handle, $active)) == CURLM_CALL_MULTI_PERFORM);
|
104 |
+
if($mh_status != CURLM_OK) {
|
105 |
+
break;
|
106 |
+
}
|
107 |
+
|
108 |
+
//a request is just completed, find out which one
|
109 |
+
while($completed = curl_multi_info_read($multi_handle)) {
|
110 |
+
$ch = $completed['handle'];
|
111 |
+
$request_info = curl_getinfo($ch);
|
112 |
+
if(curl_errno($ch) !== 0 || intval($request_info['http_code']) !== 200) { //if server responded with http error
|
113 |
+
$response = false;
|
114 |
+
} else { //sucessful response
|
115 |
+
$response = curl_multi_getcontent($ch);
|
116 |
+
}
|
117 |
+
|
118 |
+
//get request info
|
119 |
+
$key = (string) $ch;
|
120 |
+
$request =& $this->requests[$requests_map[$key]]; //map handler to request index to get request info
|
121 |
+
$url = $request['url'];
|
122 |
+
$callback = $request['callback'];
|
123 |
+
$user_data = $request['user_data'];
|
124 |
+
$options = $request['options'];
|
125 |
+
$this->stopTimer($request); //record request time
|
126 |
+
$time = $request['time'];
|
127 |
+
|
128 |
+
if($response && (isset($this->_options[CURLOPT_HEADER]) || isset($options[CURLOPT_HEADER]))) {
|
129 |
+
$k = intval($request_info['header_size']);
|
130 |
+
$request_info['response_header'] = substr($response, 0, $k);
|
131 |
+
$response = substr($response, $k);
|
132 |
+
}
|
133 |
+
|
134 |
+
//remove completed request and its curl handle
|
135 |
+
unset($requests_map[$key]);
|
136 |
+
curl_multi_remove_handle($multi_handle, $ch);
|
137 |
+
|
138 |
+
//call the callback function and pass request info and user data to it
|
139 |
+
if($callback) {
|
140 |
+
call_user_func($callback, $response, $url, $request_info, $user_data, $time);
|
141 |
+
}
|
142 |
+
$request = NULL; //free up memory now just incase response was large
|
143 |
+
|
144 |
+
//add/start a new request to the request queue
|
145 |
+
if($i < count($this->requests) && isset($this->requests[$i])) { //if requests left
|
146 |
+
$ch = curl_init();
|
147 |
+
|
148 |
+
$request =& $this->requests[$i];
|
149 |
+
$this->addTimer($request);
|
150 |
+
|
151 |
+
curl_setopt_array($ch, $this->buildOptions($request));
|
152 |
+
curl_multi_add_handle($multi_handle, $ch);
|
153 |
+
|
154 |
+
//add curl handle of a new request to the request map
|
155 |
+
$key = (string) $ch;
|
156 |
+
$requests_map[$key] = $i;
|
157 |
+
$i++;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
if($active) {
|
161 |
+
if(curl_multi_select($multi_handle, $this->_timeout) === -1) { //wait for activity on any connection
|
162 |
+
usleep(5);
|
163 |
+
}
|
164 |
+
|
165 |
+
}
|
166 |
+
} while ($active || count($requests_map)); //End do-while
|
167 |
+
|
168 |
+
$this->reset();
|
169 |
+
curl_multi_close($multi_handle);
|
170 |
+
}
|
171 |
+
|
172 |
+
|
173 |
+
|
174 |
+
//Build individual cURL options for a request
|
175 |
+
private function buildOptions(array $request) {
|
176 |
+
$url = $request['url'];
|
177 |
+
$post_data = $request['post_data'];
|
178 |
+
$individual_opts = $request['options'];
|
179 |
+
$individual_headers = $request['headers'];
|
180 |
+
|
181 |
+
$options = ($individual_opts) ? $individual_opts + $this->_options : $this->_options; //merge shared and individual request options
|
182 |
+
$headers = ($individual_headers) ? $individual_headers + $this->_headers : $this->_headers; //merge shared and individual request headers
|
183 |
+
|
184 |
+
//the below will overide the corresponding default or individual options
|
185 |
+
$options[CURLOPT_RETURNTRANSFER] = true;
|
186 |
+
//$options[CURLOPT_TIMEOUT] = $this->_timeout; //timeout in ms. bug in php 5.3
|
187 |
+
$options[CURLOPT_TIMEOUT] = 5; //timeout in seconds;
|
188 |
+
if($url) {
|
189 |
+
$options[CURLOPT_URL] = $url;
|
190 |
+
}
|
191 |
+
|
192 |
+
if($headers) {
|
193 |
+
$options[CURLOPT_HTTPHEADER] = $headers;
|
194 |
+
}
|
195 |
+
|
196 |
+
// enable POST method and set POST parameters
|
197 |
+
if($post_data) {
|
198 |
+
$options[CURLOPT_POST] = 1;
|
199 |
+
$options[CURLOPT_POSTFIELDS] = is_array($post_data)? http_build_query($post_data) : $post_data;
|
200 |
+
}
|
201 |
+
return $options;
|
202 |
+
}
|
203 |
+
|
204 |
+
|
205 |
+
|
206 |
+
private function addTimer(array &$request) { //adds timer object to request
|
207 |
+
$request['timer'] = microtime(true);
|
208 |
+
$request['time'] = false; //default if not overridden by time later
|
209 |
+
}
|
210 |
+
|
211 |
+
private function stopTimer(array &$request) {
|
212 |
+
$start_time = $request['timer'];
|
213 |
+
$end_time = microtime(true);
|
214 |
+
$elapsed_time = rtrim(sprintf('%.20F', ($end_time - $start_time)), '0') . 'secs'; //convert float to string
|
215 |
+
$request['time'] = $elapsed_time*1000; //
|
216 |
+
unset($request['timer']);
|
217 |
+
}
|
218 |
+
}
|
includes/libraries/browser.php
ADDED
@@ -0,0 +1,1082 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Modified to remove var
|
4 |
+
* Chris Christoff on 12/26/2012
|
5 |
+
* Changes: Changes vars to publics
|
6 |
+
*
|
7 |
+
* Modified to work for EDD by
|
8 |
+
* Chris Christoff on 12/23/2012
|
9 |
+
* Changes: Removed the browser string return and added spacing. Also removed return HTML formatting.
|
10 |
+
*
|
11 |
+
* Modified to add formatted User Agent string for EDD System Info by
|
12 |
+
* Chris Christoff on 12/23/2012
|
13 |
+
* Changes: Split user string and add formatting so we can print a nicely
|
14 |
+
* formatted user agent string on the EDD System Info
|
15 |
+
*
|
16 |
+
* File: Browser.php
|
17 |
+
* Author: Chris Schuld (http://chrisschuld.com/)
|
18 |
+
* Last Modified: August 20th, 2010
|
19 |
+
* @version 1.9
|
20 |
+
* @package PegasusPHP
|
21 |
+
*
|
22 |
+
* Copyright (C) 2008-2010 Chris Schuld (chris@chrisschuld.com)
|
23 |
+
*
|
24 |
+
* This program is free software; you can redistribute it and/or
|
25 |
+
* modify it under the terms of the GNU General Public License as
|
26 |
+
* published by the Free Software Foundation; either version 2 of
|
27 |
+
* the License, or (at your option) any later version.
|
28 |
+
*
|
29 |
+
* This program is distributed in the hope that it will be useful,
|
30 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
31 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
32 |
+
* GNU General Public License for more details at:
|
33 |
+
* http://www.gnu.org/copyleft/gpl.html
|
34 |
+
*
|
35 |
+
*
|
36 |
+
* Typical Usage:
|
37 |
+
*
|
38 |
+
* $browser = new Browser();
|
39 |
+
* if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 2 ) {
|
40 |
+
* echo 'You have FireFox version 2 or greater';
|
41 |
+
* }
|
42 |
+
*
|
43 |
+
* User Agents Sampled from: http://www.useragentstring.com/
|
44 |
+
*
|
45 |
+
* This implementation is based on the original work from Gary White
|
46 |
+
* http://apptools.com/phptools/browser/
|
47 |
+
*
|
48 |
+
* UPDATES:
|
49 |
+
*
|
50 |
+
* 2010-08-20 (v1.9):
|
51 |
+
* + Added MSN Explorer Browser (legacy)
|
52 |
+
* + Added Bing/MSN Robot (Thanks Rob MacDonald)
|
53 |
+
* + Added the Android Platform (PLATFORM_ANDROID)
|
54 |
+
* + Fixed issue with Android 1.6/2.2 (Thanks Tom Hirashima)
|
55 |
+
*
|
56 |
+
* 2010-04-27 (v1.8):
|
57 |
+
* + Added iPad Support
|
58 |
+
*
|
59 |
+
* 2010-03-07 (v1.7):
|
60 |
+
* + *MAJOR* Rebuild (preg_match and other "slow" routine removal(s))
|
61 |
+
* + Almost allof Gary's original code has been replaced
|
62 |
+
* + Large PHPUNIT testing environment created to validate new releases and additions
|
63 |
+
* + Added FreeBSD Platform
|
64 |
+
* + Added OpenBSD Platform
|
65 |
+
* + Added NetBSD Platform
|
66 |
+
* + Added SunOS Platform
|
67 |
+
* + Added OpenSolaris Platform
|
68 |
+
* + Added support of the Iceweazel Browser
|
69 |
+
* + Added isChromeFrame() call to check if chromeframe is in use
|
70 |
+
* + Moved the Opera check in front of the Firefox check due to legacy Opera User Agents
|
71 |
+
* + Added the __toString() method (Thanks Deano)
|
72 |
+
*
|
73 |
+
* 2009-11-15:
|
74 |
+
* + Updated the checkes for Firefox
|
75 |
+
* + Added the NOKIA platform
|
76 |
+
* + Added Checks for the NOKIA brower(s)
|
77 |
+
*
|
78 |
+
* 2009-11-08:
|
79 |
+
* + PHP 5.3 Support
|
80 |
+
* + Added support for BlackBerry OS and BlackBerry browser
|
81 |
+
* + Added support for the Opera Mini browser
|
82 |
+
* + Added additional documenation
|
83 |
+
* + Added support for isRobot() and isMobile()
|
84 |
+
* + Added support for Opera version 10
|
85 |
+
* + Added support for deprecated Netscape Navigator version 9
|
86 |
+
* + Added support for IceCat
|
87 |
+
* + Added support for Shiretoko
|
88 |
+
*
|
89 |
+
* 2010-04-27 (v1.8):
|
90 |
+
* + Added iPad Support
|
91 |
+
*
|
92 |
+
* 2009-08-18:
|
93 |
+
* + Updated to support PHP 5.3 - removed all deprecated function calls
|
94 |
+
* + Updated to remove all double quotes (") -- converted to single quotes (')
|
95 |
+
*
|
96 |
+
* 2009-04-27:
|
97 |
+
* + Updated the IE check to remove a typo and bug (thanks John)
|
98 |
+
*
|
99 |
+
* 2009-04-22:
|
100 |
+
* + Added detection for GoogleBot
|
101 |
+
* + Added detection for the W3C Validator.
|
102 |
+
* + Added detection for Yahoo! Slurp
|
103 |
+
*
|
104 |
+
* 2009-03-14:
|
105 |
+
* + Added detection for iPods.
|
106 |
+
* + Added Platform detection for iPhones
|
107 |
+
* + Added Platform detection for iPods
|
108 |
+
*
|
109 |
+
* 2009-02-16: (Rick Hale)
|
110 |
+
* + Added version detection for Android phones.
|
111 |
+
*
|
112 |
+
* 2008-12-09:
|
113 |
+
* + Removed unused constant
|
114 |
+
*
|
115 |
+
* 2008-11-07:
|
116 |
+
* + Added Google's Chrome to the detection list
|
117 |
+
* + Added isBrowser(string) to the list of functions special thanks to
|
118 |
+
* Daniel 'mavrick' Lang for the function concept (http://mavrick.id.au)
|
119 |
+
*
|
120 |
+
*
|
121 |
+
* Gary White noted: "Since browser detection is so unreliable, I am
|
122 |
+
* no longer maintaining this script. You are free to use and or
|
123 |
+
* modify/update it as you want, however the author assumes no
|
124 |
+
* responsibility for the accuracy of the detected values."
|
125 |
+
*
|
126 |
+
* Anyone experienced with Gary's script might be interested in these notes:
|
127 |
+
*
|
128 |
+
* Added class constants
|
129 |
+
* Added detection and version detection for Google's Chrome
|
130 |
+
* Updated the version detection for Amaya
|
131 |
+
* Updated the version detection for Firefox
|
132 |
+
* Updated the version detection for Lynx
|
133 |
+
* Updated the version detection for WebTV
|
134 |
+
* Updated the version detection for NetPositive
|
135 |
+
* Updated the version detection for IE
|
136 |
+
* Updated the version detection for OmniWeb
|
137 |
+
* Updated the version detection for iCab
|
138 |
+
* Updated the version detection for Safari
|
139 |
+
* Updated Safari to remove mobile devices (iPhone)
|
140 |
+
* Added detection for iPhone
|
141 |
+
* Added detection for robots
|
142 |
+
* Added detection for mobile devices
|
143 |
+
* Added detection for BlackBerry
|
144 |
+
* Removed Netscape checks (matches heavily with firefox & mozilla)
|
145 |
+
*
|
146 |
+
*/
|
147 |
+
|
148 |
+
class Browser {
|
149 |
+
public $_agent = '';
|
150 |
+
public $_browser_name = '';
|
151 |
+
public $_version = '';
|
152 |
+
public $_platform = '';
|
153 |
+
public $_os = '';
|
154 |
+
public $_is_aol = false;
|
155 |
+
public $_is_mobile = false;
|
156 |
+
public $_is_robot = false;
|
157 |
+
public $_aol_version = '';
|
158 |
+
|
159 |
+
public $BROWSER_UNKNOWN = 'unknown';
|
160 |
+
public $VERSION_UNKNOWN = 'unknown';
|
161 |
+
|
162 |
+
public $BROWSER_OPERA = 'Opera'; // Http://www.opera.com/
|
163 |
+
public $BROWSER_OPERA_MINI = 'Opera Mini'; // Http://www.opera.com/mini/
|
164 |
+
public $BROWSER_WEBTV = 'WebTV'; // Http://www.webtv.net/pc/
|
165 |
+
public $BROWSER_IE = 'Internet Explorer'; // Http://www.microsoft.com/ie/
|
166 |
+
public $BROWSER_POCKET_IE = 'Pocket Internet Explorer'; // Http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
|
167 |
+
public $BROWSER_KONQUEROR = 'Konqueror'; // Http://www.konqueror.org/
|
168 |
+
public $BROWSER_ICAB = 'iCab'; // Http://www.icab.de/
|
169 |
+
public $BROWSER_OMNIWEB = 'OmniWeb'; // Http://www.omnigroup.com/applications/omniweb/
|
170 |
+
public $BROWSER_FIREBIRD = 'Firebird'; // Http://www.ibphoenix.com/
|
171 |
+
public $BROWSER_FIREFOX = 'Firefox'; // Http://www.mozilla.com/en-US/firefox/firefox.html
|
172 |
+
public $BROWSER_ICEWEASEL = 'Iceweasel'; // Http://www.geticeweasel.org/
|
173 |
+
public $BROWSER_SHIRETOKO = 'Shiretoko'; // Http://wiki.mozilla.org/Projects/shiretoko
|
174 |
+
public $BROWSER_MOZILLA = 'Mozilla'; // Http://www.mozilla.com/en-US/
|
175 |
+
public $BROWSER_AMAYA = 'Amaya'; // Http://www.w3.org/Amaya/
|
176 |
+
public $BROWSER_LYNX = 'Lynx'; // Http://en.wikipedia.org/wiki/Lynx
|
177 |
+
public $BROWSER_SAFARI = 'Safari'; // Http://apple.com
|
178 |
+
public $BROWSER_IPHONE = 'iPhone'; // Http://apple.com
|
179 |
+
public $BROWSER_IPOD = 'iPod'; // Http://apple.com
|
180 |
+
public $BROWSER_IPAD = 'iPad'; // Http://apple.com
|
181 |
+
public $BROWSER_CHROME = 'Chrome'; // Http://www.google.com/chrome
|
182 |
+
public $BROWSER_ANDROID = 'Android'; // Http://www.android.com/
|
183 |
+
public $BROWSER_GOOGLEBOT = 'GoogleBot'; // Http://en.wikipedia.org/wiki/Googlebot
|
184 |
+
public $BROWSER_SLURP = 'Yahoo! Slurp'; // Http://en.wikipedia.org/wiki/Yahoo!_Slurp
|
185 |
+
public $BROWSER_W3CVALIDATOR = 'W3C Validator'; // Http://validator.w3.org/
|
186 |
+
public $BROWSER_BLACKBERRY = 'BlackBerry'; // Http://www.blackberry.com/
|
187 |
+
public $BROWSER_ICECAT = 'IceCat'; // Http://en.wikipedia.org/wiki/GNU_IceCat
|
188 |
+
public $BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser'; // Http://en.wikipedia.org/wiki/Web_Browser_for_S60
|
189 |
+
public $BROWSER_NOKIA = 'Nokia Browser'; // * all other WAP-based browsers on the Nokia Platform
|
190 |
+
public $BROWSER_MSN = 'MSN Browser'; // Http://explorer.msn.com/
|
191 |
+
public $BROWSER_MSNBOT = 'MSN Bot'; // Http://search.msn.com/msnbot.htm
|
192 |
+
// Http://en.wikipedia.org/wiki/Msnbot (used for Bing as well)
|
193 |
+
|
194 |
+
public $BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator'; // Http://browser.netscape.com/ (DEPRECATED)
|
195 |
+
public $BROWSER_GALEON = 'Galeon'; // Http://galeon.sourceforge.net/ (DEPRECATED)
|
196 |
+
public $BROWSER_NETPOSITIVE = 'NetPositive'; // Http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
|
197 |
+
public $BROWSER_PHOENIX = 'Phoenix'; // Http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
|
198 |
+
|
199 |
+
public $PLATFORM_UNKNOWN = 'unknown';
|
200 |
+
public $PLATFORM_WINDOWS = 'Windows';
|
201 |
+
public $PLATFORM_WINDOWS_CE = 'Windows CE';
|
202 |
+
public $PLATFORM_APPLE = 'Apple';
|
203 |
+
public $PLATFORM_LINUX = 'Linux';
|
204 |
+
public $PLATFORM_OS2 = 'OS/2';
|
205 |
+
public $PLATFORM_BEOS = 'BeOS';
|
206 |
+
public $PLATFORM_IPHONE = 'iPhone';
|
207 |
+
public $PLATFORM_IPOD = 'iPod';
|
208 |
+
public $PLATFORM_IPAD = 'iPad';
|
209 |
+
public $PLATFORM_BLACKBERRY = 'BlackBerry';
|
210 |
+
public $PLATFORM_NOKIA = 'Nokia';
|
211 |
+
public $PLATFORM_FREEBSD = 'FreeBSD';
|
212 |
+
public $PLATFORM_OPENBSD = 'OpenBSD';
|
213 |
+
public $PLATFORM_NETBSD = 'NetBSD';
|
214 |
+
public $PLATFORM_SUNOS = 'SunOS';
|
215 |
+
public $PLATFORM_OPENSOLARIS = 'OpenSolaris';
|
216 |
+
public $PLATFORM_ANDROID = 'Android';
|
217 |
+
|
218 |
+
public $OPERATING_SYSTEM_UNKNOWN = 'unknown';
|
219 |
+
|
220 |
+
function Browser($useragent="") {
|
221 |
+
$this->reset();
|
222 |
+
if( $useragent != "" ) {
|
223 |
+
$this->setUserAgent($useragent);
|
224 |
+
}
|
225 |
+
else {
|
226 |
+
$this->determine();
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Reset all properties
|
232 |
+
*/
|
233 |
+
function reset() {
|
234 |
+
$this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
|
235 |
+
$this->_browser_name = $this->BROWSER_UNKNOWN;
|
236 |
+
$this->_version = $this->VERSION_UNKNOWN;
|
237 |
+
$this->_platform = $this->PLATFORM_UNKNOWN;
|
238 |
+
$this->_os = $this->OPERATING_SYSTEM_UNKNOWN;
|
239 |
+
$this->_is_aol = false;
|
240 |
+
$this->_is_mobile = false;
|
241 |
+
$this->_is_robot = false;
|
242 |
+
$this->_aol_version = $this->VERSION_UNKNOWN;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Check to see if the specific browser is valid
|
247 |
+
* @param string $browserName
|
248 |
+
* @return True if the browser is the specified browser
|
249 |
+
*/
|
250 |
+
function isBrowser($browserName) { return( 0 == strcasecmp($this->_browser_name, trim($browserName))); }
|
251 |
+
|
252 |
+
/**
|
253 |
+
* The name of the browser. All return types are from the class contants
|
254 |
+
* @return string Name of the browser
|
255 |
+
*/
|
256 |
+
function getBrowser() { return $this->_browser_name; }
|
257 |
+
/**
|
258 |
+
* Set the name of the browser
|
259 |
+
* @param $browser The name of the Browser
|
260 |
+
*/
|
261 |
+
function setBrowser($browser) { return $this->_browser_name = $browser; }
|
262 |
+
/**
|
263 |
+
* The name of the platform. All return types are from the class contants
|
264 |
+
* @return string Name of the browser
|
265 |
+
*/
|
266 |
+
function getPlatform() { return $this->_platform; }
|
267 |
+
/**
|
268 |
+
* Set the name of the platform
|
269 |
+
* @param $platform The name of the Platform
|
270 |
+
*/
|
271 |
+
function setPlatform($platform) { return $this->_platform = $platform; }
|
272 |
+
/**
|
273 |
+
* The version of the browser.
|
274 |
+
* @return string Version of the browser (will only contain alpha-numeric characters and a period)
|
275 |
+
*/
|
276 |
+
function getVersion() { return $this->_version; }
|
277 |
+
/**
|
278 |
+
* Set the version of the browser
|
279 |
+
* @param $version The version of the Browser
|
280 |
+
*/
|
281 |
+
function setVersion($version) { $this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/','',$version); }
|
282 |
+
/**
|
283 |
+
* The version of AOL.
|
284 |
+
* @return string Version of AOL (will only contain alpha-numeric characters and a period)
|
285 |
+
*/
|
286 |
+
function getAolVersion() { return $this->_aol_version; }
|
287 |
+
/**
|
288 |
+
* Set the version of AOL
|
289 |
+
* @param $version The version of AOL
|
290 |
+
*/
|
291 |
+
function setAolVersion($version) { $this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/','',$version); }
|
292 |
+
/**
|
293 |
+
* Is the browser from AOL?
|
294 |
+
* @return boolean True if the browser is from AOL otherwise false
|
295 |
+
*/
|
296 |
+
function isAol() { return $this->_is_aol; }
|
297 |
+
/**
|
298 |
+
* Is the browser from a mobile device?
|
299 |
+
* @return boolean True if the browser is from a mobile device otherwise false
|
300 |
+
*/
|
301 |
+
function isMobile() { return $this->_is_mobile; }
|
302 |
+
/**
|
303 |
+
* Is the browser from a robot (ex Slurp,GoogleBot)?
|
304 |
+
* @return boolean True if the browser is from a robot otherwise false
|
305 |
+
*/
|
306 |
+
function isRobot() { return $this->_is_robot; }
|
307 |
+
/**
|
308 |
+
* Set the browser to be from AOL
|
309 |
+
* @param $isAol
|
310 |
+
*/
|
311 |
+
function setAol($isAol) { $this->_is_aol = $isAol; }
|
312 |
+
/**
|
313 |
+
* Set the Browser to be mobile
|
314 |
+
* @param boolean $value is the browser a mobile brower or not
|
315 |
+
*/
|
316 |
+
function setMobile($value=true) { $this->_is_mobile = $value; }
|
317 |
+
/**
|
318 |
+
* Set the Browser to be a robot
|
319 |
+
* @param boolean $value is the browser a robot or not
|
320 |
+
*/
|
321 |
+
function setRobot($value=true) { $this->_is_robot = $value; }
|
322 |
+
/**
|
323 |
+
* Get the user agent value in use to determine the browser
|
324 |
+
* @return string The user agent from the HTTP header
|
325 |
+
*/
|
326 |
+
function getUserAgent() { return $this->_agent; }
|
327 |
+
/**
|
328 |
+
* Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
|
329 |
+
* @param $agent_string The value for the User Agent
|
330 |
+
*/
|
331 |
+
function setUserAgent($agent_string) {
|
332 |
+
$this->reset();
|
333 |
+
$this->_agent = $agent_string;
|
334 |
+
$this->determine();
|
335 |
+
}
|
336 |
+
/**
|
337 |
+
* Used to determine if the browser is actually "chromeframe"
|
338 |
+
* @since 1.7
|
339 |
+
* @return boolean True if the browser is using chromeframe
|
340 |
+
*/
|
341 |
+
function isChromeFrame() {
|
342 |
+
return( strpos($this->_agent,"chromeframe") !== false );
|
343 |
+
}
|
344 |
+
/**
|
345 |
+
* Returns a formatted string with a summary of the details of the browser.
|
346 |
+
* @return string formatted string with a summary of the browser
|
347 |
+
*/
|
348 |
+
function __toString() {
|
349 |
+
$text1 = $this->getUserAgent(); //grabs the UA (user agent) string
|
350 |
+
$UAline1 = substr($text1, 0, 32); //the first line we print should only be the first 32 characters of the UA string
|
351 |
+
$text2 = $this->getUserAgent();//now we grab it again and save it to a string
|
352 |
+
$towrapUA = str_replace($UAline1, '', $text2);//the rest of the printoff (other than first line) is equivolent
|
353 |
+
// To the whole string minus the part we printed off. IE
|
354 |
+
// User Agent: thefirst32charactersfromUAline1
|
355 |
+
// the rest of it is now stored in
|
356 |
+
// $text2 to be printed off
|
357 |
+
// But we need to add spaces before each line that is split other than line 1
|
358 |
+
$space = '';
|
359 |
+
for($i = 0; $i < 25; $i++) {
|
360 |
+
$space .= ' ';
|
361 |
+
}
|
362 |
+
// Now we split the remaining string of UA ($text2) into lines that are prefixed by spaces for formatting
|
363 |
+
$wordwrapped = chunk_split($towrapUA, 32, "\n $space");
|
364 |
+
return "Platform: {$this->getPlatform()} \n".
|
365 |
+
"Browser Name: {$this->getBrowser()} \n" .
|
366 |
+
"Browser Version: {$this->getVersion()} \n" .
|
367 |
+
"User Agent String: $UAline1 \n\t\t\t " .
|
368 |
+
"$wordwrapped";
|
369 |
+
}
|
370 |
+
/**
|
371 |
+
* Protected routine to calculate and determine what the browser is in use (including platform)
|
372 |
+
*/
|
373 |
+
function determine() {
|
374 |
+
$this->checkPlatform();
|
375 |
+
$this->checkBrowsers();
|
376 |
+
$this->checkForAol();
|
377 |
+
}
|
378 |
+
/**
|
379 |
+
* Protected routine to determine the browser type
|
380 |
+
* @return boolean True if the browser was detected otherwise false
|
381 |
+
*/
|
382 |
+
function checkBrowsers() {
|
383 |
+
return (
|
384 |
+
// Well-known, well-used
|
385 |
+
// Special Notes:
|
386 |
+
// (1) Opera must be checked before FireFox due to the odd
|
387 |
+
// user agents used in some older versions of Opera
|
388 |
+
// (2) WebTV is strapped onto Internet Explorer so we must
|
389 |
+
// check for WebTV before IE
|
390 |
+
// (3) (deprecated) Galeon is based on Firefox and needs to be
|
391 |
+
// tested before Firefox is tested
|
392 |
+
// (4) OmniWeb is based on Safari so OmniWeb check must occur
|
393 |
+
// before Safari
|
394 |
+
// (5) Netscape 9+ is based on Firefox so Netscape checks
|
395 |
+
// before FireFox are necessary
|
396 |
+
$this->checkBrowserWebTv() ||
|
397 |
+
$this->checkBrowserInternetExplorer() ||
|
398 |
+
$this->checkBrowserOpera() ||
|
399 |
+
$this->checkBrowserGaleon() ||
|
400 |
+
$this->checkBrowserNetscapeNavigator9Plus() ||
|
401 |
+
$this->checkBrowserFirefox() ||
|
402 |
+
$this->checkBrowserChrome() ||
|
403 |
+
$this->checkBrowserOmniWeb() ||
|
404 |
+
|
405 |
+
// Common mobile
|
406 |
+
$this->checkBrowserAndroid() ||
|
407 |
+
$this->checkBrowseriPad() ||
|
408 |
+
$this->checkBrowseriPod() ||
|
409 |
+
$this->checkBrowseriPhone() ||
|
410 |
+
$this->checkBrowserBlackBerry() ||
|
411 |
+
$this->checkBrowserNokia() ||
|
412 |
+
|
413 |
+
// Common bots
|
414 |
+
$this->checkBrowserGoogleBot() ||
|
415 |
+
$this->checkBrowserMSNBot() ||
|
416 |
+
$this->checkBrowserSlurp() ||
|
417 |
+
|
418 |
+
// WebKit base check (post mobile and others)
|
419 |
+
$this->checkBrowserSafari() ||
|
420 |
+
|
421 |
+
// Everyone else
|
422 |
+
$this->checkBrowserNetPositive() ||
|
423 |
+
$this->checkBrowserFirebird() ||
|
424 |
+
$this->checkBrowserKonqueror() ||
|
425 |
+
$this->checkBrowserIcab() ||
|
426 |
+
$this->checkBrowserPhoenix() ||
|
427 |
+
$this->checkBrowserAmaya() ||
|
428 |
+
$this->checkBrowserLynx() ||
|
429 |
+
|
430 |
+
$this->checkBrowserShiretoko() ||
|
431 |
+
$this->checkBrowserIceCat() ||
|
432 |
+
$this->checkBrowserW3CValidator() ||
|
433 |
+
$this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
|
434 |
+
);
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Determine if the user is using a BlackBerry (last updated 1.7)
|
439 |
+
* @return boolean True if the browser is the BlackBerry browser otherwise false
|
440 |
+
*/
|
441 |
+
function checkBrowserBlackBerry() {
|
442 |
+
if( stripos($this->_agent,'blackberry') !== false ) {
|
443 |
+
$aresult = explode("/",stristr($this->_agent,"BlackBerry"));
|
444 |
+
$aversion = explode(' ',$aresult[1]);
|
445 |
+
$this->setVersion($aversion[0]);
|
446 |
+
$this->_browser_name = $this->BROWSER_BLACKBERRY;
|
447 |
+
$this->setMobile(true);
|
448 |
+
return true;
|
449 |
+
}
|
450 |
+
return false;
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Determine if the user is using an AOL User Agent (last updated 1.7)
|
455 |
+
* @return boolean True if the browser is from AOL otherwise false
|
456 |
+
*/
|
457 |
+
function checkForAol() {
|
458 |
+
$this->setAol(false);
|
459 |
+
$this->setAolVersion($this->VERSION_UNKNOWN);
|
460 |
+
|
461 |
+
if( stripos($this->_agent,'aol') !== false ) {
|
462 |
+
$aversion = explode(' ',stristr($this->_agent, 'AOL'));
|
463 |
+
$this->setAol(true);
|
464 |
+
$this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
|
465 |
+
return true;
|
466 |
+
}
|
467 |
+
return false;
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Determine if the browser is the GoogleBot or not (last updated 1.7)
|
472 |
+
* @return boolean True if the browser is the GoogletBot otherwise false
|
473 |
+
*/
|
474 |
+
function checkBrowserGoogleBot() {
|
475 |
+
if( stripos($this->_agent,'googlebot') !== false ) {
|
476 |
+
$aresult = explode('/',stristr($this->_agent,'googlebot'));
|
477 |
+
$aversion = explode(' ',$aresult[1]);
|
478 |
+
$this->setVersion(str_replace(';','',$aversion[0]));
|
479 |
+
$this->_browser_name = $this->BROWSER_GOOGLEBOT;
|
480 |
+
$this->setRobot(true);
|
481 |
+
return true;
|
482 |
+
}
|
483 |
+
return false;
|
484 |
+
}
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Determine if the browser is the MSNBot or not (last updated 1.9)
|
488 |
+
* @return boolean True if the browser is the MSNBot otherwise false
|
489 |
+
*/
|
490 |
+
function checkBrowserMSNBot() {
|
491 |
+
if( stripos($this->_agent,"msnbot") !== false ) {
|
492 |
+
$aresult = explode("/",stristr($this->_agent,"msnbot"));
|
493 |
+
$aversion = explode(" ",$aresult[1]);
|
494 |
+
$this->setVersion(str_replace(";","",$aversion[0]));
|
495 |
+
$this->_browser_name = $this->BROWSER_MSNBOT;
|
496 |
+
$this->setRobot(true);
|
497 |
+
return true;
|
498 |
+
}
|
499 |
+
return false;
|
500 |
+
}
|
501 |
+
|
502 |
+
/**
|
503 |
+
* Determine if the browser is the W3C Validator or not (last updated 1.7)
|
504 |
+
* @return boolean True if the browser is the W3C Validator otherwise false
|
505 |
+
*/
|
506 |
+
function checkBrowserW3CValidator() {
|
507 |
+
if( stripos($this->_agent,'W3C-checklink') !== false ) {
|
508 |
+
$aresult = explode('/',stristr($this->_agent,'W3C-checklink'));
|
509 |
+
$aversion = explode(' ',$aresult[1]);
|
510 |
+
$this->setVersion($aversion[0]);
|
511 |
+
$this->_browser_name = $this->BROWSER_W3CVALIDATOR;
|
512 |
+
return true;
|
513 |
+
}
|
514 |
+
else if( stripos($this->_agent,'W3C_Validator') !== false ) {
|
515 |
+
// Some of the Validator versions do not delineate w/ a slash - add it back in
|
516 |
+
$ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
|
517 |
+
$aresult = explode('/',stristr($ua,'W3C_Validator'));
|
518 |
+
$aversion = explode(' ',$aresult[1]);
|
519 |
+
$this->setVersion($aversion[0]);
|
520 |
+
$this->_browser_name = $this->BROWSER_W3CVALIDATOR;
|
521 |
+
return true;
|
522 |
+
}
|
523 |
+
return false;
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
|
528 |
+
* @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
|
529 |
+
*/
|
530 |
+
function checkBrowserSlurp() {
|
531 |
+
if( stripos($this->_agent,'slurp') !== false ) {
|
532 |
+
$aresult = explode('/',stristr($this->_agent,'Slurp'));
|
533 |
+
$aversion = explode(' ',$aresult[1]);
|
534 |
+
$this->setVersion($aversion[0]);
|
535 |
+
$this->_browser_name = $this->BROWSER_SLURP;
|
536 |
+
$this->setRobot(true);
|
537 |
+
$this->setMobile(false);
|
538 |
+
return true;
|
539 |
+
}
|
540 |
+
return false;
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Determine if the browser is Internet Explorer or not (last updated 1.7)
|
545 |
+
* @return boolean True if the browser is Internet Explorer otherwise false
|
546 |
+
*/
|
547 |
+
function checkBrowserInternetExplorer() {
|
548 |
+
|
549 |
+
// Test for v1 - v1.5 IE
|
550 |
+
if( stripos($this->_agent,'microsoft internet explorer') !== false ) {
|
551 |
+
$this->setBrowser($this->BROWSER_IE);
|
552 |
+
$this->setVersion('1.0');
|
553 |
+
$aresult = stristr($this->_agent, '/');
|
554 |
+
if( preg_match('/308|425|426|474|0b1/i', $aresult) ) {
|
555 |
+
$this->setVersion('1.5');
|
556 |
+
}
|
557 |
+
return true;
|
558 |
+
}
|
559 |
+
// Test for versions > 1.5
|
560 |
+
else if( stripos($this->_agent,'msie') !== false && stripos($this->_agent,'opera') === false ) {
|
561 |
+
// See if the browser is the odd MSN Explorer
|
562 |
+
if( stripos($this->_agent,'msnb') !== false ) {
|
563 |
+
$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'MSN'));
|
564 |
+
$this->setBrowser( $this->BROWSER_MSN );
|
565 |
+
$this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
|
566 |
+
return true;
|
567 |
+
}
|
568 |
+
$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'msie'));
|
569 |
+
$this->setBrowser( $this->BROWSER_IE );
|
570 |
+
$this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
|
571 |
+
return true;
|
572 |
+
}
|
573 |
+
// Test for Pocket IE
|
574 |
+
else if( stripos($this->_agent,'mspie') !== false || stripos($this->_agent,'pocket') !== false ) {
|
575 |
+
$aresult = explode(' ',stristr($this->_agent,'mspie'));
|
576 |
+
$this->setPlatform( $this->PLATFORM_WINDOWS_CE );
|
577 |
+
$this->setBrowser( $this->BROWSER_POCKET_IE );
|
578 |
+
$this->setMobile(true);
|
579 |
+
|
580 |
+
if( stripos($this->_agent,'mspie') !== false ) {
|
581 |
+
$this->setVersion($aresult[1]);
|
582 |
+
}
|
583 |
+
else {
|
584 |
+
$aversion = explode('/',$this->_agent);
|
585 |
+
$this->setVersion($aversion[1]);
|
586 |
+
}
|
587 |
+
return true;
|
588 |
+
}
|
589 |
+
return false;
|
590 |
+
}
|
591 |
+
|
592 |
+
/**
|
593 |
+
* Determine if the browser is Opera or not (last updated 1.7)
|
594 |
+
* @return boolean True if the browser is Opera otherwise false
|
595 |
+
*/
|
596 |
+
function checkBrowserOpera() {
|
597 |
+
if( stripos($this->_agent,'opera mini') !== false ) {
|
598 |
+
$resultant = stristr($this->_agent, 'opera mini');
|
599 |
+
if( preg_match('/\//',$resultant) ) {
|
600 |
+
$aresult = explode('/',$resultant);
|
601 |
+
$aversion = explode(' ',$aresult[1]);
|
602 |
+
$this->setVersion($aversion[0]);
|
603 |
+
}
|
604 |
+
else {
|
605 |
+
$aversion = explode(' ',stristr($resultant,'opera mini'));
|
606 |
+
$this->setVersion($aversion[1]);
|
607 |
+
}
|
608 |
+
$this->_browser_name = $this->BROWSER_OPERA_MINI;
|
609 |
+
$this->setMobile(true);
|
610 |
+
return true;
|
611 |
+
}
|
612 |
+
else if( stripos($this->_agent,'opera') !== false ) {
|
613 |
+
$resultant = stristr($this->_agent, 'opera');
|
614 |
+
if( preg_match('/Version\/(10.*)$/',$resultant,$matches) ) {
|
615 |
+
$this->setVersion($matches[1]);
|
616 |
+
}
|
617 |
+
else if( preg_match('/\//',$resultant) ) {
|
618 |
+
$aresult = explode('/',str_replace("("," ",$resultant));
|
619 |
+
$aversion = explode(' ',$aresult[1]);
|
620 |
+
$this->setVersion($aversion[0]);
|
621 |
+
}
|
622 |
+
else {
|
623 |
+
$aversion = explode(' ',stristr($resultant,'opera'));
|
624 |
+
$this->setVersion(isset($aversion[1])?$aversion[1]:"");
|
625 |
+
}
|
626 |
+
$this->_browser_name = $this->BROWSER_OPERA;
|
627 |
+
return true;
|
628 |
+
}
|
629 |
+
return false;
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Determine if the browser is Chrome or not (last updated 1.7)
|
634 |
+
* @return boolean True if the browser is Chrome otherwise false
|
635 |
+
*/
|
636 |
+
function checkBrowserChrome() {
|
637 |
+
if( stripos($this->_agent,'Chrome') !== false ) {
|
638 |
+
$aresult = explode('/',stristr($this->_agent,'Chrome'));
|
639 |
+
$aversion = explode(' ',$aresult[1]);
|
640 |
+
$this->setVersion($aversion[0]);
|
641 |
+
$this->setBrowser($this->BROWSER_CHROME);
|
642 |
+
return true;
|
643 |
+
}
|
644 |
+
return false;
|
645 |
+
}
|
646 |
+
|
647 |
+
|
648 |
+
/**
|
649 |
+
* Determine if the browser is WebTv or not (last updated 1.7)
|
650 |
+
* @return boolean True if the browser is WebTv otherwise false
|
651 |
+
*/
|
652 |
+
function checkBrowserWebTv() {
|
653 |
+
if( stripos($this->_agent,'webtv') !== false ) {
|
654 |
+
$aresult = explode('/',stristr($this->_agent,'webtv'));
|
655 |
+
$aversion = explode(' ',$aresult[1]);
|
656 |
+
$this->setVersion($aversion[0]);
|
657 |
+
$this->setBrowser($this->BROWSER_WEBTV);
|
658 |
+
return true;
|
659 |
+
}
|
660 |
+
return false;
|
661 |
+
}
|
662 |
+
|
663 |
+
/**
|
664 |
+
* Determine if the browser is NetPositive or not (last updated 1.7)
|
665 |
+
* @return boolean True if the browser is NetPositive otherwise false
|
666 |
+
*/
|
667 |
+
function checkBrowserNetPositive() {
|
668 |
+
if( stripos($this->_agent,'NetPositive') !== false ) {
|
669 |
+
$aresult = explode('/',stristr($this->_agent,'NetPositive'));
|
670 |
+
$aversion = explode(' ',$aresult[1]);
|
671 |
+
$this->setVersion(str_replace(array('(',')',';'),'',$aversion[0]));
|
672 |
+
$this->setBrowser($this->BROWSER_NETPOSITIVE);
|
673 |
+
return true;
|
674 |
+
}
|
675 |
+
return false;
|
676 |
+
}
|
677 |
+
|
678 |
+
/**
|
679 |
+
* Determine if the browser is Galeon or not (last updated 1.7)
|
680 |
+
* @return boolean True if the browser is Galeon otherwise false
|
681 |
+
*/
|
682 |
+
function checkBrowserGaleon() {
|
683 |
+
if( stripos($this->_agent,'galeon') !== false ) {
|
684 |
+
$aresult = explode(' ',stristr($this->_agent,'galeon'));
|
685 |
+
$aversion = explode('/',$aresult[0]);
|
686 |
+
$this->setVersion($aversion[1]);
|
687 |
+
$this->setBrowser($this->BROWSER_GALEON);
|
688 |
+
return true;
|
689 |
+
}
|
690 |
+
return false;
|
691 |
+
}
|
692 |
+
|
693 |
+
/**
|
694 |
+
* Determine if the browser is Konqueror or not (last updated 1.7)
|
695 |
+
* @return boolean True if the browser is Konqueror otherwise false
|
696 |
+
*/
|
697 |
+
function checkBrowserKonqueror() {
|
698 |
+
if( stripos($this->_agent,'Konqueror') !== false ) {
|
699 |
+
$aresult = explode(' ',stristr($this->_agent,'Konqueror'));
|
700 |
+
$aversion = explode('/',$aresult[0]);
|
701 |
+
$this->setVersion($aversion[1]);
|
702 |
+
$this->setBrowser($this->BROWSER_KONQUEROR);
|
703 |
+
return true;
|
704 |
+
}
|
705 |
+
return false;
|
706 |
+
}
|
707 |
+
|
708 |
+
/**
|
709 |
+
* Determine if the browser is iCab or not (last updated 1.7)
|
710 |
+
* @return boolean True if the browser is iCab otherwise false
|
711 |
+
*/
|
712 |
+
function checkBrowserIcab() {
|
713 |
+
if( stripos($this->_agent,'icab') !== false ) {
|
714 |
+
$aversion = explode(' ',stristr(str_replace('/',' ',$this->_agent),'icab'));
|
715 |
+
$this->setVersion($aversion[1]);
|
716 |
+
$this->setBrowser($this->BROWSER_ICAB);
|
717 |
+
return true;
|
718 |
+
}
|
719 |
+
return false;
|
720 |
+
}
|
721 |
+
|
722 |
+
/**
|
723 |
+
* Determine if the browser is OmniWeb or not (last updated 1.7)
|
724 |
+
* @return boolean True if the browser is OmniWeb otherwise false
|
725 |
+
*/
|
726 |
+
function checkBrowserOmniWeb() {
|
727 |
+
if( stripos($this->_agent,'omniweb') !== false ) {
|
728 |
+
$aresult = explode('/',stristr($this->_agent,'omniweb'));
|
729 |
+
$aversion = explode(' ',isset($aresult[1])?$aresult[1]:"");
|
730 |
+
$this->setVersion($aversion[0]);
|
731 |
+
$this->setBrowser($this->BROWSER_OMNIWEB);
|
732 |
+
return true;
|
733 |
+
}
|
734 |
+
return false;
|
735 |
+
}
|
736 |
+
|
737 |
+
/**
|
738 |
+
* Determine if the browser is Phoenix or not (last updated 1.7)
|
739 |
+
* @return boolean True if the browser is Phoenix otherwise false
|
740 |
+
*/
|
741 |
+
function checkBrowserPhoenix() {
|
742 |
+
if( stripos($this->_agent,'Phoenix') !== false ) {
|
743 |
+
$aversion = explode('/',stristr($this->_agent,'Phoenix'));
|
744 |
+
$this->setVersion($aversion[1]);
|
745 |
+
$this->setBrowser($this->BROWSER_PHOENIX);
|
746 |
+
return true;
|
747 |
+
}
|
748 |
+
return false;
|
749 |
+
}
|
750 |
+
|
751 |
+
/**
|
752 |
+
* Determine if the browser is Firebird or not (last updated 1.7)
|
753 |
+
* @return boolean True if the browser is Firebird otherwise false
|
754 |
+
*/
|
755 |
+
function checkBrowserFirebird() {
|
756 |
+
if( stripos($this->_agent,'Firebird') !== false ) {
|
757 |
+
$aversion = explode('/',stristr($this->_agent,'Firebird'));
|
758 |
+
$this->setVersion($aversion[1]);
|
759 |
+
$this->setBrowser($this->BROWSER_FIREBIRD);
|
760 |
+
return true;
|
761 |
+
}
|
762 |
+
return false;
|
763 |
+
}
|
764 |
+
|
765 |
+
/**
|
766 |
+
* Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
|
767 |
+
* NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
|
768 |
+
* @return boolean True if the browser is Netscape Navigator 9+ otherwise false
|
769 |
+
*/
|
770 |
+
function checkBrowserNetscapeNavigator9Plus() {
|
771 |
+
if( stripos($this->_agent,'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i',$this->_agent,$matches) ) {
|
772 |
+
$this->setVersion($matches[1]);
|
773 |
+
$this->setBrowser($this->BROWSER_NETSCAPE_NAVIGATOR);
|
774 |
+
return true;
|
775 |
+
}
|
776 |
+
else if( stripos($this->_agent,'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i',$this->_agent,$matches) ) {
|
777 |
+
$this->setVersion($matches[1]);
|
778 |
+
$this->setBrowser($this->BROWSER_NETSCAPE_NAVIGATOR);
|
779 |
+
return true;
|
780 |
+
}
|
781 |
+
return false;
|
782 |
+
}
|
783 |
+
|
784 |
+
/**
|
785 |
+
* Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
|
786 |
+
* @return boolean True if the browser is Shiretoko otherwise false
|
787 |
+
*/
|
788 |
+
function checkBrowserShiretoko() {
|
789 |
+
if( stripos($this->_agent,'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i',$this->_agent,$matches) ) {
|
790 |
+
$this->setVersion($matches[1]);
|
791 |
+
$this->setBrowser($this->BROWSER_SHIRETOKO);
|
792 |
+
return true;
|
793 |
+
}
|
794 |
+
return false;
|
795 |
+
}
|
796 |
+
|
797 |
+
/**
|
798 |
+
* Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
|
799 |
+
* @return boolean True if the browser is Ice Cat otherwise false
|
800 |
+
*/
|
801 |
+
function checkBrowserIceCat() {
|
802 |
+
if( stripos($this->_agent,'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i',$this->_agent,$matches) ) {
|
803 |
+
$this->setVersion($matches[1]);
|
804 |
+
$this->setBrowser($this->BROWSER_ICECAT);
|
805 |
+
return true;
|
806 |
+
}
|
807 |
+
return false;
|
808 |
+
}
|
809 |
+
|
810 |
+
/**
|
811 |
+
* Determine if the browser is Nokia or not (last updated 1.7)
|
812 |
+
* @return boolean True if the browser is Nokia otherwise false
|
813 |
+
*/
|
814 |
+
function checkBrowserNokia() {
|
815 |
+
if( preg_match("/Nokia([^\/]+)\/([^ SP]+)/i",$this->_agent,$matches) ) {
|
816 |
+
$this->setVersion($matches[2]);
|
817 |
+
if( stripos($this->_agent,'Series60') !== false || strpos($this->_agent,'S60') !== false ) {
|
818 |
+
$this->setBrowser($this->BROWSER_NOKIA_S60);
|
819 |
+
}
|
820 |
+
else {
|
821 |
+
$this->setBrowser( $this->BROWSER_NOKIA );
|
822 |
+
}
|
823 |
+
$this->setMobile(true);
|
824 |
+
return true;
|
825 |
+
}
|
826 |
+
return false;
|
827 |
+
}
|
828 |
+
|
829 |
+
/**
|
830 |
+
* Determine if the browser is Firefox or not (last updated 1.7)
|
831 |
+
* @return boolean True if the browser is Firefox otherwise false
|
832 |
+
*/
|
833 |
+
function checkBrowserFirefox() {
|
834 |
+
if( stripos($this->_agent,'safari') === false ) {
|
835 |
+
if( preg_match("/Firefox[\/ \(]([^ ;\)]+)/i",$this->_agent,$matches) ) {
|
836 |
+
$this->setVersion($matches[1]);
|
837 |
+
$this->setBrowser($this->BROWSER_FIREFOX);
|
838 |
+
return true;
|
839 |
+
}
|
840 |
+
else if( preg_match("/Firefox$/i",$this->_agent,$matches) ) {
|
841 |
+
$this->setVersion("");
|
842 |
+
$this->setBrowser($this->BROWSER_FIREFOX);
|
843 |
+
return true;
|
844 |
+
}
|
845 |
+
}
|
846 |
+
return false;
|
847 |
+
}
|
848 |
+
|
849 |
+
/**
|
850 |
+
* Determine if the browser is Firefox or not (last updated 1.7)
|
851 |
+
* @return boolean True if the browser is Firefox otherwise false
|
852 |
+
*/
|
853 |
+
function checkBrowserIceweasel() {
|
854 |
+
if( stripos($this->_agent,'Iceweasel') !== false ) {
|
855 |
+
$aresult = explode('/',stristr($this->_agent,'Iceweasel'));
|
856 |
+
$aversion = explode(' ',$aresult[1]);
|
857 |
+
$this->setVersion($aversion[0]);
|
858 |
+
$this->setBrowser($this->BROWSER_ICEWEASEL);
|
859 |
+
return true;
|
860 |
+
}
|
861 |
+
return false;
|
862 |
+
}
|
863 |
+
/**
|
864 |
+
* Determine if the browser is Mozilla or not (last updated 1.7)
|
865 |
+
* @return boolean True if the browser is Mozilla otherwise false
|
866 |
+
*/
|
867 |
+
function checkBrowserMozilla() {
|
868 |
+
if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent) && stripos($this->_agent,'netscape') === false) {
|
869 |
+
$aversion = explode(' ',stristr($this->_agent,'rv:'));
|
870 |
+
preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent,$aversion);
|
871 |
+
$this->setVersion(str_replace('rv:','',$aversion[0]));
|
872 |
+
$this->setBrowser($this->BROWSER_MOZILLA);
|
873 |
+
return true;
|
874 |
+
}
|
875 |
+
else if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i',$this->_agent) && stripos($this->_agent,'netscape') === false ) {
|
876 |
+
$aversion = explode('',stristr($this->_agent,'rv:'));
|
877 |
+
$this->setVersion(str_replace('rv:','',$aversion[0]));
|
878 |
+
$this->setBrowser($this->BROWSER_MOZILLA);
|
879 |
+
return true;
|
880 |
+
}
|
881 |
+
else if( stripos($this->_agent,'mozilla') !== false && preg_match('/mozilla\/([^ ]*)/i',$this->_agent,$matches) && stripos($this->_agent,'netscape') === false ) {
|
882 |
+
$this->setVersion($matches[1]);
|
883 |
+
$this->setBrowser($this->BROWSER_MOZILLA);
|
884 |
+
return true;
|
885 |
+
}
|
886 |
+
return false;
|
887 |
+
}
|
888 |
+
|
889 |
+
/**
|
890 |
+
* Determine if the browser is Lynx or not (last updated 1.7)
|
891 |
+
* @return boolean True if the browser is Lynx otherwise false
|
892 |
+
*/
|
893 |
+
function checkBrowserLynx() {
|
894 |
+
if( stripos($this->_agent,'lynx') !== false ) {
|
895 |
+
$aresult = explode('/',stristr($this->_agent,'Lynx'));
|
896 |
+
$aversion = explode(' ',(isset($aresult[1])?$aresult[1]:""));
|
897 |
+
$this->setVersion($aversion[0]);
|
898 |
+
$this->setBrowser($this->BROWSER_LYNX);
|
899 |
+
return true;
|
900 |
+
}
|
901 |
+
return false;
|
902 |
+
}
|
903 |
+
|
904 |
+
/**
|
905 |
+
* Determine if the browser is Amaya or not (last updated 1.7)
|
906 |
+
* @return boolean True if the browser is Amaya otherwise false
|
907 |
+
*/
|
908 |
+
function checkBrowserAmaya() {
|
909 |
+
if( stripos($this->_agent,'amaya') !== false ) {
|
910 |
+
$aresult = explode('/',stristr($this->_agent,'Amaya'));
|
911 |
+
$aversion = explode(' ',$aresult[1]);
|
912 |
+
$this->setVersion($aversion[0]);
|
913 |
+
$this->setBrowser($this->BROWSER_AMAYA);
|
914 |
+
return true;
|
915 |
+
}
|
916 |
+
return false;
|
917 |
+
}
|
918 |
+
|
919 |
+
/**
|
920 |
+
* Determine if the browser is Safari or not (last updated 1.7)
|
921 |
+
* @return boolean True if the browser is Safari otherwise false
|
922 |
+
*/
|
923 |
+
function checkBrowserSafari() {
|
924 |
+
if( stripos($this->_agent,'Safari') !== false && stripos($this->_agent,'iPhone') === false && stripos($this->_agent,'iPod') === false ) {
|
925 |
+
$aresult = explode('/',stristr($this->_agent,'Version'));
|
926 |
+
if( isset($aresult[1]) ) {
|
927 |
+
$aversion = explode(' ',$aresult[1]);
|
928 |
+
$this->setVersion($aversion[0]);
|
929 |
+
}
|
930 |
+
else {
|
931 |
+
$this->setVersion($this->VERSION_UNKNOWN);
|
932 |
+
}
|
933 |
+
$this->setBrowser($this->BROWSER_SAFARI);
|
934 |
+
return true;
|
935 |
+
}
|
936 |
+
return false;
|
937 |
+
}
|
938 |
+
|
939 |
+
/**
|
940 |
+
* Determine if the browser is iPhone or not (last updated 1.7)
|
941 |
+
* @return boolean True if the browser is iPhone otherwise false
|
942 |
+
*/
|
943 |
+
function checkBrowseriPhone() {
|
944 |
+
if( stripos($this->_agent,'iPhone') !== false ) {
|
945 |
+
$aresult = explode('/',stristr($this->_agent,'Version'));
|
946 |
+
if( isset($aresult[1]) ) {
|
947 |
+
$aversion = explode(' ',$aresult[1]);
|
948 |
+
$this->setVersion($aversion[0]);
|
949 |
+
}
|
950 |
+
else {
|
951 |
+
$this->setVersion($this->VERSION_UNKNOWN);
|
952 |
+
}
|
953 |
+
$this->setMobile(true);
|
954 |
+
$this->setBrowser($this->BROWSER_IPHONE);
|
955 |
+
return true;
|
956 |
+
}
|
957 |
+
return false;
|
958 |
+
}
|
959 |
+
|
960 |
+
/**
|
961 |
+
* Determine if the browser is iPod or not (last updated 1.7)
|
962 |
+
* @return boolean True if the browser is iPod otherwise false
|
963 |
+
*/
|
964 |
+
function checkBrowseriPad() {
|
965 |
+
if( stripos($this->_agent,'iPad') !== false ) {
|
966 |
+
$aresult = explode('/',stristr($this->_agent,'Version'));
|
967 |
+
if( isset($aresult[1]) ) {
|
968 |
+
$aversion = explode(' ',$aresult[1]);
|
969 |
+
$this->setVersion($aversion[0]);
|
970 |
+
}
|
971 |
+
else {
|
972 |
+
$this->setVersion($this->VERSION_UNKNOWN);
|
973 |
+
}
|
974 |
+
$this->setMobile(true);
|
975 |
+
$this->setBrowser($this->BROWSER_IPAD);
|
976 |
+
return true;
|
977 |
+
}
|
978 |
+
return false;
|
979 |
+
}
|
980 |
+
|
981 |
+
/**
|
982 |
+
* Determine if the browser is iPod or not (last updated 1.7)
|
983 |
+
* @return boolean True if the browser is iPod otherwise false
|
984 |
+
*/
|
985 |
+
function checkBrowseriPod() {
|
986 |
+
if( stripos($this->_agent,'iPod') !== false ) {
|
987 |
+
$aresult = explode('/',stristr($this->_agent,'Version'));
|
988 |
+
if( isset($aresult[1]) ) {
|
989 |
+
$aversion = explode(' ',$aresult[1]);
|
990 |
+
$this->setVersion($aversion[0]);
|
991 |
+
}
|
992 |
+
else {
|
993 |
+
$this->setVersion($this->VERSION_UNKNOWN);
|
994 |
+
}
|
995 |
+
$this->setMobile(true);
|
996 |
+
$this->setBrowser($this->BROWSER_IPOD);
|
997 |
+
return true;
|
998 |
+
}
|
999 |
+
return false;
|
1000 |
+
}
|
1001 |
+
|
1002 |
+
/**
|
1003 |
+
* Determine if the browser is Android or not (last updated 1.7)
|
1004 |
+
* @return boolean True if the browser is Android otherwise false
|
1005 |
+
*/
|
1006 |
+
function checkBrowserAndroid() {
|
1007 |
+
if( stripos($this->_agent,'Android') !== false ) {
|
1008 |
+
$aresult = explode(' ',stristr($this->_agent,'Android'));
|
1009 |
+
if( isset($aresult[1]) ) {
|
1010 |
+
$aversion = explode(' ',$aresult[1]);
|
1011 |
+
$this->setVersion($aversion[0]);
|
1012 |
+
}
|
1013 |
+
else {
|
1014 |
+
$this->setVersion($this->VERSION_UNKNOWN);
|
1015 |
+
}
|
1016 |
+
$this->setMobile(true);
|
1017 |
+
$this->setBrowser($this->BROWSER_ANDROID);
|
1018 |
+
return true;
|
1019 |
+
}
|
1020 |
+
return false;
|
1021 |
+
}
|
1022 |
+
|
1023 |
+
/**
|
1024 |
+
* Determine the user's platform (last updated 1.7)
|
1025 |
+
*/
|
1026 |
+
function checkPlatform() {
|
1027 |
+
if( stripos($this->_agent, 'windows') !== false ) {
|
1028 |
+
$this->_platform = $this->PLATFORM_WINDOWS;
|
1029 |
+
}
|
1030 |
+
else if( stripos($this->_agent, 'iPad') !== false ) {
|
1031 |
+
$this->_platform = $this->PLATFORM_IPAD;
|
1032 |
+
}
|
1033 |
+
else if( stripos($this->_agent, 'iPod') !== false ) {
|
1034 |
+
$this->_platform = $this->PLATFORM_IPOD;
|
1035 |
+
}
|
1036 |
+
else if( stripos($this->_agent, 'iPhone') !== false ) {
|
1037 |
+
$this->_platform = $this->PLATFORM_IPHONE;
|
1038 |
+
}
|
1039 |
+
elseif( stripos($this->_agent, 'mac') !== false ) {
|
1040 |
+
$this->_platform = $this->PLATFORM_APPLE;
|
1041 |
+
}
|
1042 |
+
elseif( stripos($this->_agent, 'android') !== false ) {
|
1043 |
+
$this->_platform = $this->PLATFORM_ANDROID;
|
1044 |
+
}
|
1045 |
+
elseif( stripos($this->_agent, 'linux') !== false ) {
|
1046 |
+
$this->_platform = $this->PLATFORM_LINUX;
|
1047 |
+
}
|
1048 |
+
else if( stripos($this->_agent, 'Nokia') !== false ) {
|
1049 |
+
$this->_platform = $this->PLATFORM_NOKIA;
|
1050 |
+
}
|
1051 |
+
else if( stripos($this->_agent, 'BlackBerry') !== false ) {
|
1052 |
+
$this->_platform = $this->PLATFORM_BLACKBERRY;
|
1053 |
+
}
|
1054 |
+
elseif( stripos($this->_agent,'FreeBSD') !== false ) {
|
1055 |
+
$this->_platform = $this->PLATFORM_FREEBSD;
|
1056 |
+
}
|
1057 |
+
elseif( stripos($this->_agent,'OpenBSD') !== false ) {
|
1058 |
+
$this->_platform = $this->PLATFORM_OPENBSD;
|
1059 |
+
}
|
1060 |
+
elseif( stripos($this->_agent,'NetBSD') !== false ) {
|
1061 |
+
$this->_platform = $this->PLATFORM_NETBSD;
|
1062 |
+
}
|
1063 |
+
elseif( stripos($this->_agent, 'OpenSolaris') !== false ) {
|
1064 |
+
$this->_platform = $this->PLATFORM_OPENSOLARIS;
|
1065 |
+
}
|
1066 |
+
elseif( stripos($this->_agent, 'SunOS') !== false ) {
|
1067 |
+
$this->_platform = $this->PLATFORM_SUNOS;
|
1068 |
+
}
|
1069 |
+
elseif( stripos($this->_agent, 'OS\/2') !== false ) {
|
1070 |
+
$this->_platform = $this->PLATFORM_OS2;
|
1071 |
+
}
|
1072 |
+
elseif( stripos($this->_agent, 'BeOS') !== false ) {
|
1073 |
+
$this->_platform = $this->PLATFORM_BEOS;
|
1074 |
+
}
|
1075 |
+
elseif( stripos($this->_agent, 'win') !== false ) {
|
1076 |
+
$this->_platform = $this->PLATFORM_WINDOWS;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
}
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
?>
|
includes/logger.php
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Simple Logger Class
|
4 |
+
*
|
5 |
+
* @author Josh Nesbitt <josh@josh-nesbitt.net>
|
6 |
+
*
|
7 |
+
* By default will write to path/to/logger/ + log/filename.log
|
8 |
+
* Author url: https://raw.githubusercontent.com/joshnesbitt/logger/master/lib/logger.php
|
9 |
+
*
|
10 |
+
**/
|
11 |
+
class wpstgLogger {
|
12 |
+
var $file, $path, $level, $stream;
|
13 |
+
const INFO = 4;
|
14 |
+
const DEBUG = 3;
|
15 |
+
const WARN = 2;
|
16 |
+
const ERROR = 1;
|
17 |
+
const FATAL = 0;
|
18 |
+
|
19 |
+
function __construct($file, $level)
|
20 |
+
{
|
21 |
+
$this->file = $file;
|
22 |
+
$this->level = $level;
|
23 |
+
$this->path = str_replace('\\', '/', WPSTG_PLUGIN_DIR . "logs/$this->file");
|
24 |
+
$this->folder = str_replace('\\', '/', WPSTG_PLUGIN_DIR . "logs");
|
25 |
+
$this->start();
|
26 |
+
}
|
27 |
+
|
28 |
+
function info($string)
|
29 |
+
{
|
30 |
+
return $this->check_level(self::INFO) ? true : $this->log($string);
|
31 |
+
}
|
32 |
+
|
33 |
+
function warn($string)
|
34 |
+
{
|
35 |
+
return $this->check_level(self::WARN) ? true : $this->log($string);
|
36 |
+
}
|
37 |
+
|
38 |
+
function debug($string)
|
39 |
+
{
|
40 |
+
return $this->check_level(self::DEBUG) ? true : $this->log($string);
|
41 |
+
}
|
42 |
+
|
43 |
+
function error($string)
|
44 |
+
{
|
45 |
+
return $this->check_level(self::ERROR) ? true : $this->log($string);
|
46 |
+
}
|
47 |
+
|
48 |
+
function fatal($string)
|
49 |
+
{
|
50 |
+
return $this->check_level(self::FATAL) ? true : $this->log($string);
|
51 |
+
}
|
52 |
+
|
53 |
+
function clear()
|
54 |
+
{
|
55 |
+
$this->close();
|
56 |
+
$this->open("w");
|
57 |
+
$this->close();
|
58 |
+
$this->open();
|
59 |
+
}
|
60 |
+
|
61 |
+
private function check_level($level)
|
62 |
+
{
|
63 |
+
return $this->level < $level;
|
64 |
+
}
|
65 |
+
|
66 |
+
/* Start logging
|
67 |
+
*/
|
68 |
+
private function log($string)
|
69 |
+
{
|
70 |
+
global $wpstg_options;
|
71 |
+
//$enabled = isset($wpstg_options['debug_mode']) ? $wpstg_options['debug_mode'] : false;
|
72 |
+
//if ($enabled)
|
73 |
+
$this->write("[". date('l jS F Y : h:i:sa') . "] ". $string . "\r\n");
|
74 |
+
|
75 |
+
return false;
|
76 |
+
}
|
77 |
+
|
78 |
+
private function write($string)
|
79 |
+
{
|
80 |
+
return fwrite($this->stream, $string);
|
81 |
+
}
|
82 |
+
|
83 |
+
/* Check if wp-staging debug mode is enabled
|
84 |
+
*
|
85 |
+
* @return bool
|
86 |
+
*/
|
87 |
+
private function start()
|
88 |
+
{
|
89 |
+
global $wpstg_options;
|
90 |
+
//$enabled = isset($wpstg_options['debug_mode']) ? $wpstg_options['debug_mode'] : false;
|
91 |
+
//if ($enabled)
|
92 |
+
return $this->open();
|
93 |
+
|
94 |
+
return false;
|
95 |
+
}
|
96 |
+
|
97 |
+
/* Check if directory is writable
|
98 |
+
*
|
99 |
+
* @return bool
|
100 |
+
*/
|
101 |
+
|
102 |
+
function checkDir(){
|
103 |
+
$writable = is_writable($this->folder);
|
104 |
+
if ($writable)
|
105 |
+
return true;
|
106 |
+
|
107 |
+
return false;
|
108 |
+
}
|
109 |
+
|
110 |
+
/* Open the log file
|
111 |
+
*
|
112 |
+
* @return stream
|
113 |
+
*/
|
114 |
+
private function open($mode="a")
|
115 |
+
{
|
116 |
+
if ($this->checkDir())
|
117 |
+
return $this->stream = fopen($this->path, $mode);
|
118 |
+
//or die("Cannot write to file '$this->path', please ensure '$this->path' is writable.");
|
119 |
+
}
|
120 |
+
|
121 |
+
private function close()
|
122 |
+
{
|
123 |
+
return fclose($this->stream);
|
124 |
+
}
|
125 |
+
|
126 |
+
}
|
127 |
+
|
128 |
+
?>
|
includes/scripts.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Scripts
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Functions
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 1.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
|
16 |
+
function wpstg_get_cpu_load_sett(){
|
17 |
+
global $wpstg_options;
|
18 |
+
|
19 |
+
$get_cpu_load = isset($wpstg_options['wpstg_cpu_load']) ? $wpstg_options['wpstg_cpu_load'] : 'default';
|
20 |
+
|
21 |
+
if ($get_cpu_load === 'default')
|
22 |
+
$cpu_load = 1000;
|
23 |
+
|
24 |
+
if ($get_cpu_load === 'high')
|
25 |
+
$cpu_load = 0;
|
26 |
+
|
27 |
+
if ($get_cpu_load === 'medium')
|
28 |
+
$cpu_load = 1000;
|
29 |
+
|
30 |
+
if ($get_cpu_load === 'low')
|
31 |
+
$cpu_load = 3000;
|
32 |
+
|
33 |
+
return $cpu_load;
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Load Admin Scripts
|
39 |
+
*
|
40 |
+
* Enqueues the required admin scripts.
|
41 |
+
*
|
42 |
+
* @since 1.0
|
43 |
+
* @global $post
|
44 |
+
* @param string $hook Page hook
|
45 |
+
* @return void
|
46 |
+
*/
|
47 |
+
|
48 |
+
function wpstg_load_admin_scripts( $hook ) {
|
49 |
+
if ( ! apply_filters( 'wpstg_load_admin_scripts', wpstg_is_admin_page(), $hook ) ) {
|
50 |
+
return;
|
51 |
+
}
|
52 |
+
global $wp_version, $wpstg_options;
|
53 |
+
|
54 |
+
|
55 |
+
$js_dir = WPSTG_PLUGIN_URL . 'assets/js/';
|
56 |
+
$css_dir = WPSTG_PLUGIN_URL . 'assets/css/';
|
57 |
+
|
58 |
+
// Use minified libraries if SCRIPT_DEBUG is turned off
|
59 |
+
//$suffix = '';//( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
|
60 |
+
$suffix = isset($wpstg_options['debug_mode']) ? '.min' : '';
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
// These have to be global
|
65 |
+
wp_enqueue_script( 'wpstg-admin-script', $js_dir . 'wpstg-admin' . $suffix . '.js', array( 'jquery' ), WPSTG_VERSION, false );
|
66 |
+
wp_enqueue_style( 'wpstg-admin', $css_dir . 'wpstg-admin' . $suffix . '.css', WPSTG_VERSION );
|
67 |
+
wp_localize_script( 'wpstg-admin-script', 'wpstg', array(
|
68 |
+
'nonce' => wp_create_nonce( 'wpstg_ajax_nonce' ),
|
69 |
+
'mu_plugin_confirmation' => __( "If confirmed we will install an additional WordPress 'Must Use' plugin. This plugin will allow us to control which plugins are loaded during WP Staging specific operations. Do you wish to continue?", 'wpstg' ),
|
70 |
+
'plugin_compatibility_settings_problem' => __( 'A problem occurred when trying to change the plugin compatibility setting.', 'wpstg' ),
|
71 |
+
'saved' => __( 'Saved', 'The settings were saved successfully', 'wpstg' ),
|
72 |
+
'status' => __( 'Status', 'Current request status', 'wpstg' ),
|
73 |
+
'response' => __( 'Response', 'The message the server responded with', 'wpstg' ),
|
74 |
+
'blacklist_problem' => __( 'A problem occurred when trying to add plugins to backlist.', 'wpstg' ),
|
75 |
+
'cpu_load' => wpstg_get_cpu_load_sett(),
|
76 |
+
|
77 |
+
));
|
78 |
+
}
|
79 |
+
add_action( 'admin_enqueue_scripts', 'wpstg_load_admin_scripts', 100 );
|
includes/staging-functions.php
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Staging functions
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage includes/staging-functions
|
7 |
+
* @copyright Copyright (c) 2015, Rene Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 0.9.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Check if website is a clone or not.
|
17 |
+
* If it' s a clone website we allow access to the frontend only for administrators.
|
18 |
+
*
|
19 |
+
* At init() stage most of WP is loaded, and the user is authenticated.
|
20 |
+
* Get the wpstg_options via get_option because our global $wpstg_option is only available on admin pages
|
21 |
+
*
|
22 |
+
* @return string wp_die()
|
23 |
+
*/
|
24 |
+
function wpstg_staging_permissions(){
|
25 |
+
$wpstg_options = get_option( 'wpstg_settings' );
|
26 |
+
$wpstg_disable_admin_login = isset($wpstg_options['disable_admin_login']) ? $wpstg_options['disable_admin_login'] : 0;
|
27 |
+
|
28 |
+
if ( wpstg_is_staging_site() && $wpstg_disable_admin_login === 0){
|
29 |
+
if ( !current_user_can( 'administrator' ) && !wpstg_is_login_page() && !is_admin() )
|
30 |
+
//wp_die( sprintf ( __('Access denied. <a href="%1$s" target="_blank">Login</a> first','wpstg'), './wp-admin/' ) );
|
31 |
+
wp_die( sprintf ( __('Access denied. <a href="%1$s" target="_blank">Login</a> first','wpstg'), wp_login_url() ) );
|
32 |
+
}
|
33 |
+
wpstg_reset_permalinks();
|
34 |
+
}
|
35 |
+
add_action( 'init', 'wpstg_staging_permissions' );
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Inject custom header for staging website
|
39 |
+
*
|
40 |
+
* @deprecated since version 0.2
|
41 |
+
*/
|
42 |
+
/*function wpstg_inject_header(){
|
43 |
+
if ( !wpstg_is_staging_site() ) {
|
44 |
+
?>
|
45 |
+
<script type="text/javascript">
|
46 |
+
jQuery(document).ready( function($) {
|
47 |
+
var struct='<div id="wpstg_staging_header" style="display:block;position:fixed;background-color:#c12161;color:#fff;height:32px;top:0;left:0;width:100%;">Staging website!</div>';
|
48 |
+
function
|
49 |
+
jQuery('body').append(struct);
|
50 |
+
})
|
51 |
+
</script>
|
52 |
+
<?php
|
53 |
+
}
|
54 |
+
}*/
|
55 |
+
//add_action('wp_head','wpstg_inject_header');
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Change admin_bar site_name
|
59 |
+
*
|
60 |
+
* @global object $wp_admin_bar
|
61 |
+
* @return void
|
62 |
+
*/
|
63 |
+
function wpstg_change_adminbar_name() {
|
64 |
+
global $wp_admin_bar;
|
65 |
+
if (wpstg_is_staging_site()) {
|
66 |
+
// Main Title
|
67 |
+
$wp_admin_bar->add_menu(array(
|
68 |
+
'id' => 'site-name',
|
69 |
+
'title' => is_admin() ? ('STAGING - ' . get_bloginfo( 'name' ) ) : ( 'STAGING ' . get_bloginfo( 'name' ) . ' Dashboard' ),
|
70 |
+
'href' => is_admin() ? home_url('/') : admin_url(),
|
71 |
+
));
|
72 |
+
}
|
73 |
+
}
|
74 |
+
add_filter('wp_before_admin_bar_render', 'wpstg_change_adminbar_name');
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Check if current wordpress instance is the main site or a clone
|
78 |
+
*
|
79 |
+
* @global array $wpstg_options options
|
80 |
+
* @return bool true if current website is a staging website
|
81 |
+
*/
|
82 |
+
function wpstg_is_staging_site(){
|
83 |
+
$is_staging_site = get_option('wpstg_is_staging_site') ? get_option('wpstg_is_staging_site') : 'false';
|
84 |
+
if ($is_staging_site === 'true'){
|
85 |
+
return true;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Reset permalink structure of the clone to default index.php/p=123
|
91 |
+
* This is used once
|
92 |
+
* @global array $wpstg_options options
|
93 |
+
*/
|
94 |
+
function wpstg_reset_permalinks(){
|
95 |
+
global $wp_rewrite;
|
96 |
+
$permalink_structure = null;
|
97 |
+
$already_executed = get_option('wpstg_rmpermalinks_executed') ? get_option('wpstg_rmpermalinks_executed') : 'false';
|
98 |
+
if (wpstg_is_staging_site() && $already_executed !== 'true' ){
|
99 |
+
$wp_rewrite->set_permalink_structure( $permalink_structure );
|
100 |
+
flush_rewrite_rules();
|
101 |
+
update_option('wpstg_rmpermalinks_executed', 'true');
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Check if current page is a login page
|
107 |
+
*
|
108 |
+
* @return bool true if page is login page
|
109 |
+
*/
|
110 |
+
function wpstg_is_login_page() {
|
111 |
+
global $wpstg_options;
|
112 |
+
//$wpstg_login_page = isset($wpstg_options['admin_login_page']) ? $wpstg_options['admin_login_page'] : '';
|
113 |
+
return in_array( $GLOBALS['pagenow'], array('wp-login.php') );
|
114 |
+
}
|
includes/template-functions.php
ADDED
@@ -0,0 +1,1722 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template Functions
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Functions/Templates
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 0.9.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
14 |
+
|
15 |
+
//error_reporting(-1);
|
16 |
+
//ini_set('display_errors', 'On');
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Main Page
|
20 |
+
*
|
21 |
+
* Renders the main WP-Staging page contents.
|
22 |
+
*
|
23 |
+
* @since 1.0
|
24 |
+
* @return void
|
25 |
+
*/
|
26 |
+
|
27 |
+
/* Global vars
|
28 |
+
*
|
29 |
+
*/
|
30 |
+
|
31 |
+
$state_data = '';
|
32 |
+
$start_time = microtime(true);
|
33 |
+
|
34 |
+
function wpstg_clone_page() {
|
35 |
+
ob_start();
|
36 |
+
?>
|
37 |
+
<div id="wpstg-clonepage-wrapper">
|
38 |
+
<span class="wp-staginglogo"><img src="<?php echo WPSTG_PLUGIN_URL . 'assets/images/logo_clean_small_212_25.png';?>"></span><span class="wpstg-version"><?php echo WPSTG_VERSION . ''; ?></span>
|
39 |
+
<div class="wpstg-header">
|
40 |
+
<?php echo __('Thank you for using WP Staging', 'wpstg');?>
|
41 |
+
<br>
|
42 |
+
<?php echo __('WP Staging is ready to create a staging site!', 'wpstg'); ?>
|
43 |
+
<br>
|
44 |
+
<iframe src="//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwordpress.org%2Fplugins%2Fwp-staging%2F&width=100&layout=button&action=like&show_faces=false&share=true&height=35&appId=449277011881884" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:96px; height:20px;" allowTransparency="true"></iframe>
|
45 |
+
<a class="twitter-follow-button" href="https://twitter.com/wp_staging" data-size="small" id="twitter-wjs" style="display: none;">Follow @wp_staging</a>
|
46 |
+
<a class="twitter-share-button" href="https://twitter.com/intent/tweet?text=Check%20this%20WordPress%20Staging%20plugin%20&url=https://wordpress.org/plugins/wp-staging&hashtags=wpstaging&via=wp_staging">Tweet</a>
|
47 |
+
</div>
|
48 |
+
<?php do_action('wpstg_notifications');?>
|
49 |
+
<?php if (is_multisite()) {
|
50 |
+
echo '<span class="wpstg-notice-alert" style="margin-top:20px;">' . __('WordPress Multisite is currently not supported! <a href="https://wp-staging.com/contact">Get in contact with us</a> and ask for it.', 'wpstg') . '</span>';
|
51 |
+
exit;
|
52 |
+
}?>
|
53 |
+
<ul id="wpstg-steps">
|
54 |
+
<li class="wpstg-current-step"><span class="wpstg-step-num">1</span><?php echo __('Overview', 'wpstg');?></li>
|
55 |
+
<li><span class="wpstg-step-num">2</span><?php echo __('Scanning', 'wpstg');?></li>
|
56 |
+
<li><span class="wpstg-step-num">3</span><?php echo __('Cloning', 'wpstg');?></li>
|
57 |
+
<li><span href="#" id="wpstg-loader" style="display:none;"></span></li>
|
58 |
+
</ul> <!-- #wpstg-steps -->
|
59 |
+
<div id="wpstg-workflow">
|
60 |
+
<?php echo wpstg_overview(false); ?>
|
61 |
+
</div> <!-- #wpstg-workflow -->
|
62 |
+
<div id="wpstg-error-wrapper">
|
63 |
+
<div id="wpstg-error-details"></div>
|
64 |
+
</div>
|
65 |
+
</div> <!-- #wpstg-clonepage-wrapper -->
|
66 |
+
<?php
|
67 |
+
echo wpstg_get_sidebar();
|
68 |
+
echo ob_get_clean();
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Renders the sidebar
|
73 |
+
*
|
74 |
+
* @return string
|
75 |
+
*/
|
76 |
+
function wpstg_get_sidebar(){
|
77 |
+
$html = '<div class="wpstg-sidebar">side bar here</div>';
|
78 |
+
return $html;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* 1st step: Overview
|
83 |
+
* Renders the overview page content
|
84 |
+
*
|
85 |
+
* @global type $wpstg_clone_details
|
86 |
+
*/
|
87 |
+
function wpstg_overview() {
|
88 |
+
global $wpstg_clone_details;
|
89 |
+
$wpstg_clone_details = wpstg_get_options();
|
90 |
+
$existing_clones = get_option('wpstg_existing_clones', array());
|
91 |
+
|
92 |
+
?>
|
93 |
+
<?php if (isset($wpstg_clone_details['current_clone'])) : ?>
|
94 |
+
Current clone: <?php echo $wpstg_clone_details['current_clone']; ?>
|
95 |
+
<a href="#" id="wpstg-reset-clone" class="wpstg-link-btn button-primary" data-clone="<?php echo $wpstg_clone_details['current_clone']; ?>">Reset</a>
|
96 |
+
<a href="#" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="wpstg_scanning">Continue</a>
|
97 |
+
<?php else : ?>
|
98 |
+
<a href="#" id="wpstg-new-clone" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="wpstg_scanning"><?php echo __('Create new staging site', 'wpstg'); ?></a>
|
99 |
+
<?php endif; ?>
|
100 |
+
<br>
|
101 |
+
<div id="wpstg-existing-clones">
|
102 |
+
<?php if (!empty($existing_clones)) : ?>
|
103 |
+
<h3><?php _e('Available Staging Sites:', 'wpstg'); ?></h3>
|
104 |
+
<?php foreach ($existing_clones as $clone) : ?>
|
105 |
+
<div class="wpstg-clone" id="<?php echo $clone; ?>">
|
106 |
+
<a href="<?php echo get_home_url() . "/$clone/wp-login.php"; ?>" class="wpstg-clone-title" target="_blank"><?php echo $clone; ?></a>
|
107 |
+
<a href="<?php echo get_home_url() . "/$clone/wp-login.php"; ?>" class="wpstg-open-clone wpstg-clone-action" target="_blank"><?php _e('Open', 'wpstg'); ?></a>
|
108 |
+
<a href="#" class="wpstg-execute-clone wpstg-clone-action" data-clone="<?php echo $clone; ?>"><?php _e('Edit', 'wpstg'); ?></a>
|
109 |
+
<a href="#" class="wpstg-remove-clone wpstg-clone-action" data-clone="<?php echo $clone; ?>"><?php _e('Delete', 'wpstg'); ?></a>
|
110 |
+
<!--<a href="#" class="wpstg-edit-clone wpstg-clone-action" data-clone="<?php //echo $clone; ?>"><?php //_e('Edit', 'wpstg'); ?></a>-->
|
111 |
+
</div> <!-- .wpstg-clone -->
|
112 |
+
<?php endforeach; ?>
|
113 |
+
<?php endif; ?>
|
114 |
+
</div> <!-- #wpstg-existing-clones -->
|
115 |
+
<div id="wpstg-removing-clone">
|
116 |
+
|
117 |
+
</div> <!-- #wpstg-removing-clone -->
|
118 |
+
<?php
|
119 |
+
if (check_ajax_referer('wpstg_ajax_nonce', 'nonce', false))
|
120 |
+
wp_die();
|
121 |
+
}
|
122 |
+
add_action('wp_ajax_wpstg_overview', 'wpstg_overview');
|
123 |
+
|
124 |
+
|
125 |
+
/**
|
126 |
+
* 2nd step: Scanning
|
127 |
+
* Collect database and file data for clone
|
128 |
+
*
|
129 |
+
* @global object $wpdb
|
130 |
+
* @global array $wpstg_clone_details
|
131 |
+
* @global array $all_files
|
132 |
+
*/
|
133 |
+
function wpstg_scanning() {
|
134 |
+
global $wpdb, $wpstg_clone_details, $all_files;
|
135 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
136 |
+
$wpstg_clone_details = wpstg_get_options();
|
137 |
+
|
138 |
+
$unchecked_tables = array();
|
139 |
+
$excluded_folders = array();
|
140 |
+
$clone_path = 'value="' . get_home_path() . '"';
|
141 |
+
|
142 |
+
$disabled = isset($wpstg_clone_details['current_clone']) ? 'disabled' : false;
|
143 |
+
$clone = isset($_POST['clone']) ? $_POST['clone']
|
144 |
+
: (isset($wpstg_clone_details['current_clone']) ? $wpstg_clone_details['current_clone'] : false);
|
145 |
+
|
146 |
+
if ($clone) {
|
147 |
+
//$wpstg_profile = wpstg_get_profile($clone);
|
148 |
+
//$unchecked_tables = $wpstg_profile['unchecked_tables'];
|
149 |
+
//$excluded_folders = $wpstg_profile['excluded_folders'];
|
150 |
+
//$excluded_folders[] = get_home_path() . $wpstg_profile['name'];
|
151 |
+
//$clone_path = 'value = "' . $wpstg_profile['path'] . '"';
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
//Scan DB
|
156 |
+
$tables = $wpdb->get_results("show table status like '" . $wpdb->prefix . "_%'");
|
157 |
+
$wpstg_clone_details['all_tables'] = $wpdb->get_col("show tables like '" . $wpdb->prefix . "%'");
|
158 |
+
|
159 |
+
//Scan Files
|
160 |
+
$wpstg_clone_details['total_size'] = 0;
|
161 |
+
unset($wpstg_clone_details['large_files']);
|
162 |
+
//$folders = wpstg_scan_files(rtrim(get_home_path(), '/'));
|
163 |
+
//$folders = wpstg_scan_files(get_home_path());
|
164 |
+
$folders = wpstg_scan_files(wpstg_get_clone_root_path());
|
165 |
+
|
166 |
+
array_pop($folders);
|
167 |
+
|
168 |
+
$path = wpstg_get_upload_dir() . '/remaining_files.json';
|
169 |
+
file_put_contents($path, json_encode($all_files));
|
170 |
+
|
171 |
+
wpstg_save_options();
|
172 |
+
|
173 |
+
$clone_id = '';
|
174 |
+
if (isset($wpstg_clone_details['current_clone']))
|
175 |
+
$clone_id = 'value="' . $wpstg_clone_details['current_clone'] . '" disabled';
|
176 |
+
|
177 |
+
//$free_space = function_exists('disk_free_space') ? disk_free_space(get_home_path()) : '';
|
178 |
+
//$overflow = $free_space < $wpstg_clone_details['total_size'] ? true : false;
|
179 |
+
?>
|
180 |
+
<label id="wpstg-clone-label" for="wpstg-new-clone">
|
181 |
+
<?php echo __('Name your new site, e.g. staging, dev (keep it short):', 'wpstg');?>
|
182 |
+
<input type="text" id="wpstg-new-clone-id" value="<?php echo $clone; ?>" <?php echo $disabled; ?>>
|
183 |
+
</label>
|
184 |
+
<span class="wpstg-error-msg" id="wpstg-clone-id-error">
|
185 |
+
<?php
|
186 |
+
echo wpstg_check_diskspace($wpstg_clone_details['total_size']);
|
187 |
+
?>
|
188 |
+
</span>
|
189 |
+
<div class="wpstg-tabs-wrapper">
|
190 |
+
<a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
|
191 |
+
<span class="wpstg-tab-triangle">►</span>
|
192 |
+
<?php echo __('DB Tables', 'wpstg'); ?>
|
193 |
+
</a>
|
194 |
+
<div class="wpstg-tab-section" id="wpstg-scanning-db">
|
195 |
+
<?php
|
196 |
+
do_action('wpstg_scanning_db');
|
197 |
+
echo '<h4 style="margin:0px;">' . __('Select the tables to copy. (If the copy process was previously interrupted, succesfull copied tables are greyed out and copy process will skip these ones)', 'wpstg') . '<h4>';
|
198 |
+
wpstg_show_tables($tables, $unchecked_tables); ?>
|
199 |
+
</div> <!-- #wpstg-scanning-db -->
|
200 |
+
|
201 |
+
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
202 |
+
<span class="wpstg-tab-triangle">►</span>
|
203 |
+
<?php echo __('Files', 'wpstg'); ?>
|
204 |
+
</a>
|
205 |
+
<div class="wpstg-tab-section" id="wpstg-scanning-files">
|
206 |
+
|
207 |
+
<?php
|
208 |
+
echo '<h4 style="margin:0px;">' . __('Exclude folders (Click on it for expanding)', 'wpstg') . '<h4>';
|
209 |
+
wpstg_directory_structure($folders, null, false, false, $excluded_folders);
|
210 |
+
wpstg_show_large_files();
|
211 |
+
echo '<p><span id=wpstg-file-summary>' . __('Files will be copied into subfolder of: ','wpstg') . wpstg_get_clone_root_path() . '</span>';
|
212 |
+
?>
|
213 |
+
</div> <!-- #wpstg-scanning-files -->
|
214 |
+
|
215 |
+
<a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
|
216 |
+
<span class="wpstg-tab-triangle">►</span>
|
217 |
+
<?php echo __('Advanced Options', 'wpstg'); ?>
|
218 |
+
</a>
|
219 |
+
<div class="wpstg-tab-section" id="wpstg-advanced-settings">
|
220 |
+
<?php echo wpstg_advanced_settings(); ?>
|
221 |
+
</div> <!-- #wpstg-advanced-settings -->
|
222 |
+
|
223 |
+
|
224 |
+
</div>
|
225 |
+
<a href="#" class="wpstg-prev-step-link wpstg-link-btn button-primary"><?php _e('Back', 'wpstg'); ?></a>
|
226 |
+
<a href="#" id="wpstg-start-cloning" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="wpstg_cloning"><?php echo wpstg_return_button_title();?></a>
|
227 |
+
<?php
|
228 |
+
wp_die();
|
229 |
+
}
|
230 |
+
add_action('wp_ajax_wpstg_scanning', 'wpstg_scanning');
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Display db tables
|
234 |
+
*
|
235 |
+
* @param array $tables
|
236 |
+
* @param array $unchecked_tables
|
237 |
+
* @global array $wpstg_clone_details
|
238 |
+
*/
|
239 |
+
function wpstg_show_tables($tables, $unchecked_tables = array()) {
|
240 |
+
global $wpstg_clone_details;
|
241 |
+
|
242 |
+
$cloned_tables = isset($wpstg_clone_details['cloned_tables']) ? $wpstg_clone_details['cloned_tables'] : array();
|
243 |
+
foreach ($tables as $table) { ?>
|
244 |
+
<div class="wpstg-db-table">
|
245 |
+
<label>
|
246 |
+
<?php
|
247 |
+
$attributes = in_array($table->Name, $unchecked_tables) ? '' : 'checked';
|
248 |
+
$attributes .= in_array($table->Name, $cloned_tables) ? ' disabled' : '';
|
249 |
+
?>
|
250 |
+
<input class="wpstg-db-table-checkboxes" type="checkbox" name="<?php echo $table->Name; ?>" <?php echo $attributes; ?>>
|
251 |
+
<?php echo $table->Name; ?>
|
252 |
+
</label>
|
253 |
+
<span class="wpstg-size-info">
|
254 |
+
<?php echo wpstg_short_size($table->Data_length + $table->Index_length); ?>
|
255 |
+
</span>
|
256 |
+
</div>
|
257 |
+
<?php } ?>
|
258 |
+
<div><a href="#" class="wpstg-button-unselect">Unselect all tables</a></div>
|
259 |
+
<?php
|
260 |
+
}
|
261 |
+
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Scan all files and create directory structure
|
265 |
+
*
|
266 |
+
* @global array $all_files
|
267 |
+
* @global array $wpstg_clone_details
|
268 |
+
* @global $wpstg_options $wpstg_options
|
269 |
+
* @param string $path
|
270 |
+
* @param array $folders
|
271 |
+
* @return array
|
272 |
+
*/
|
273 |
+
function wpstg_scan_files($path, &$folders = array()) {
|
274 |
+
global $all_files, $wpstg_clone_details, $wpstg_options;
|
275 |
+
|
276 |
+
$batch_size = isset($wpstg_options['wpstg_batch_size']) ? $wpstg_options['wpstg_batch_size'] : 20;
|
277 |
+
$batch_size *= 1024*1024;
|
278 |
+
$wpstg_clone_details['large_files'] = isset($wpstg_clone_details['large_files']) ? $wpstg_clone_details['large_files'] : array();
|
279 |
+
$clone = isset($wpstg_clone_details['current_clone']) ? $wpstg_clone_details['current_clone'] : null;
|
280 |
+
|
281 |
+
if (is_dir($path)) {
|
282 |
+
$dir = dir($path);
|
283 |
+
$dirsize = 0;
|
284 |
+
while ( method_exists($dir,'read') && false !== ($entry = $dir->read()) ) { // works
|
285 |
+
if ($entry == '.' || $entry == '..' || $entry == $clone)
|
286 |
+
continue;
|
287 |
+
//if ( is_file($path . $entry) && !is_null($path) && !empty($path) && !is_null($path) ) {
|
288 |
+
//if (is_file($path . $entry) && is_readable($path . $entry) && !is_null($path) && $path != 'null' && $path != '' && !empty($path)) {
|
289 |
+
if (is_file($path . $entry) && is_readable($path . $entry)) {
|
290 |
+
$all_files[] = utf8_encode($path . $entry);
|
291 |
+
//$all_files[] = $path . $entry;
|
292 |
+
//$all_files[] = $path . $entry;
|
293 |
+
$dirsize += filesize( $path . $entry);
|
294 |
+
if ($batch_size < $size = filesize($path . $entry ))
|
295 |
+
$wpstg_clone_details['large_files'][] = $path . $entry;
|
296 |
+
$wpstg_clone_details['total_size'] += $size;
|
297 |
+
continue;
|
298 |
+
}
|
299 |
+
|
300 |
+
$tmp_path = str_replace('//', '/' ,$path . '/' . $entry .'//'); // Make sure that directory contains ending slash / but never double slashes //
|
301 |
+
$tmp = wpstg_scan_files($tmp_path, $folders[$entry]);
|
302 |
+
|
303 |
+
$dirsize += $tmp['size'];
|
304 |
+
}
|
305 |
+
$folders['size'] = $dirsize;
|
306 |
+
}
|
307 |
+
return $folders;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Get a list of all files which will be copied
|
312 |
+
*
|
313 |
+
* @param string $folder
|
314 |
+
* @param array $files
|
315 |
+
* @param string $total_size
|
316 |
+
* @return array files
|
317 |
+
*/
|
318 |
+
|
319 |
+
function wpstg_get_files($folder, &$files = array(), &$total_size) {
|
320 |
+
if (! is_dir($folder))
|
321 |
+
return array();
|
322 |
+
$dir = dir($folder);
|
323 |
+
|
324 |
+
while (false !== $entry = $dir->read()) {
|
325 |
+
if ($entry == '.' || $entry == '..')
|
326 |
+
continue;
|
327 |
+
if (is_file("$folder/$entry")) {
|
328 |
+
$files[] = "$folder/$entry";
|
329 |
+
$total_size -= filesize("$folder/$entry");
|
330 |
+
} else
|
331 |
+
wpstg_get_files("$folder/$entry", $files, $total_size);
|
332 |
+
|
333 |
+
}
|
334 |
+
return $files;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Display directory structure with checkboxes
|
339 |
+
*
|
340 |
+
* @param array $folders list of folder names
|
341 |
+
* @param string $path base path for the directory structure
|
342 |
+
* @param bool $not_checked checkbox value
|
343 |
+
* @param bool $is_removing
|
344 |
+
* @param array $excluded_folders
|
345 |
+
*/
|
346 |
+
function wpstg_directory_structure($folders, $path = null, $not_checked = false, $is_removing = false, $excluded_folders = array()) {
|
347 |
+
/** @var array $existing_clones */
|
348 |
+
$existing_clones = get_option('wpstg_existing_clones', array());
|
349 |
+
$path = $path === null ? rtrim(get_home_path(), '/') : $path;
|
350 |
+
|
351 |
+
foreach ($folders as $name => $folder) {
|
352 |
+
$size = array_pop($folder);
|
353 |
+
if ($is_removing) {
|
354 |
+
$not_checked_tmp = false;
|
355 |
+
} else {
|
356 |
+
if (empty ($excluded_folders))
|
357 |
+
$not_checked_tmp = $not_checked ? $not_checked : in_array($name, $existing_clones);
|
358 |
+
else
|
359 |
+
$not_checked_tmp = in_array("$path/$name", $excluded_folders);
|
360 |
+
}
|
361 |
+
?>
|
362 |
+
<div class="wpstg-dir">
|
363 |
+
<input type="checkbox" class="wpstg-check-dir" <?php echo $not_checked_tmp ? '' : 'checked'; ?> name="<?php echo "$path/$name"; ?>">
|
364 |
+
<a href="#" class="wpstg-expand-dirs <?php echo $not_checked_tmp ? 'disabled' : ''; ?>"><?php echo $name;?></a>
|
365 |
+
<span class="wpstg-size-info"><?php echo wpstg_short_size($size); ?></span>
|
366 |
+
<?php if (!empty($folder)) : ?>
|
367 |
+
<div class="wpstg-dir wpstg-subdir">
|
368 |
+
<?php wpstg_directory_structure($folder, "$path/$name", $not_checked_tmp, $is_removing, $excluded_folders); ?>
|
369 |
+
</div>
|
370 |
+
<?php endif; ?>
|
371 |
+
</div>
|
372 |
+
<?php }
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Convert byte into human readable numbers
|
377 |
+
*
|
378 |
+
* @param integer $size
|
379 |
+
* @return string
|
380 |
+
*/
|
381 |
+
function wpstg_short_size($size) {
|
382 |
+
if (1 < $out = $size / 1000000000)
|
383 |
+
return round($out, 2) . ' Gb';
|
384 |
+
else if (1 < $out = $size / 1000000)
|
385 |
+
return round($out, 2) . ' Mb';
|
386 |
+
else if (1 < $out = $size / 1000)
|
387 |
+
return round($out, 2) . ' Kb';
|
388 |
+
return $size . ' bytes';
|
389 |
+
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Display list of large files
|
393 |
+
*/
|
394 |
+
function wpstg_show_large_files() {
|
395 |
+
global $wpstg_clone_details;
|
396 |
+
|
397 |
+
$large_files = isset($wpstg_clone_details['large_files']) ? $wpstg_clone_details['large_files'] : array();
|
398 |
+
if (! empty($large_files)) : ?>
|
399 |
+
<br>
|
400 |
+
<span style="font-weight:bold;">That might require your attention:</span>
|
401 |
+
<br>
|
402 |
+
<span id="wpstg-show-large-files"><a href="#">Show large files</a></span>
|
403 |
+
|
404 |
+
<div id="wpstg-large-files">
|
405 |
+
<h4 style="margin-top: 0px;">
|
406 |
+
<?php echo __('We have detected the following large files which could neeed some investigation. Often this files are backup files or other temporary files which must not necessarily copied for creating a staging site:','wpstg');?>
|
407 |
+
</h4>
|
408 |
+
|
409 |
+
<?php foreach ($large_files as $file) : ?>
|
410 |
+
<div class="wpstg-large-file"><li><?php echo $file; ?></li></div>
|
411 |
+
<?php endforeach; ?>
|
412 |
+
</div> <!-- #wpstg-large-file -->
|
413 |
+
|
414 |
+
<?php endif;
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Display advanced settings
|
419 |
+
*/
|
420 |
+
function wpstg_advanced_settings() {
|
421 |
+
?>
|
422 |
+
Comming soon
|
423 |
+
<?php
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Sanitize staging name
|
428 |
+
* Lowercase alphanumeric characters, dashes and underscores are allowed.
|
429 |
+
* Uppercase characters will be converted to lowercase.
|
430 |
+
*
|
431 |
+
* @param string
|
432 |
+
* @return string
|
433 |
+
*/
|
434 |
+
|
435 |
+
function wpstg_sanitize_key($key){
|
436 |
+
return sanitize_key( $key );
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* Check the staging name input
|
441 |
+
*
|
442 |
+
* - Check if name does not contain more than 17 characters
|
443 |
+
* - Check is staging name does not already exists
|
444 |
+
* - Sanitize staging name
|
445 |
+
*
|
446 |
+
* @return json message | name | percent | running time | status
|
447 |
+
*/
|
448 |
+
function wpstg_check_clone() {
|
449 |
+
global $wpstg_clone_details;
|
450 |
+
$wpstg_clone_details = wpstg_get_options();
|
451 |
+
//$cur_clone = preg_replace('/[^A-Za-z0-9]/', '', $_POST['cloneID']);
|
452 |
+
$cur_clone = wpstg_sanitize_key($_POST['cloneID']);
|
453 |
+
$existing_clones = get_option('wpstg_existing_clones', array());
|
454 |
+
strlen($_POST['cloneID']) >= 17 ? $max_length = true : $max_length = false;
|
455 |
+
//wp_die(!in_array($cur_clone, $existing_clones));
|
456 |
+
if ( $max_length )
|
457 |
+
wpstg_return_json('wpstg_check_clone', 'fail', 'Clone name must not be longer than 16 characters', 1, wpstg_get_runtime());
|
458 |
+
|
459 |
+
if ( in_array($cur_clone, $existing_clones) )
|
460 |
+
wpstg_return_json('wpstg_check_clone', 'fail', 'Clone with same name already exists', 1, wpstg_get_runtime());
|
461 |
+
|
462 |
+
if ( !in_array($cur_clone, $existing_clones ) && $max_length !== true )
|
463 |
+
wpstg_return_json('wpstg_check_clone', 'success', '', 1, wpstg_get_runtime());
|
464 |
+
}
|
465 |
+
add_action('wp_ajax_wpstg_check_clone', 'wpstg_check_clone');
|
466 |
+
|
467 |
+
/**
|
468 |
+
* 3rd step: Cloning
|
469 |
+
*
|
470 |
+
* @global array $wpstg_clone_details clone related data
|
471 |
+
*/
|
472 |
+
function wpstg_cloning() {
|
473 |
+
global $wpstg_clone_details;
|
474 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
475 |
+
$wpstg_clone_details = wpstg_get_options();
|
476 |
+
|
477 |
+
$clone = preg_replace('/[^A-Za-z0-9]/', '', $_POST['cloneID']);
|
478 |
+
$wpstg_clone_details['current_clone'] = isset($wpstg_clone_details['current_clone']) ? $wpstg_clone_details['current_clone'] : $clone;
|
479 |
+
|
480 |
+
$wpstg_clone_details['cloned_tables'] = isset($wpstg_clone_details['cloned_tables']) ? $wpstg_clone_details['cloned_tables'] : array();
|
481 |
+
if (isset($_POST['uncheckedTables']))
|
482 |
+
$wpstg_clone_details['cloned_tables'] = array_merge($wpstg_clone_details['cloned_tables'], $_POST['uncheckedTables']);
|
483 |
+
if (isset($_POST['excludedFolders'])) {
|
484 |
+
$path = wpstg_get_upload_dir() . '/remaining_files.json';
|
485 |
+
$all_files = json_decode(file_get_contents($path), true);
|
486 |
+
|
487 |
+
$excluded_files = array();
|
488 |
+
//$excluded_files = array (null, 'null'); //rhe 25.09.2015
|
489 |
+
foreach ($_POST['excludedFolders'] as $folder) {
|
490 |
+
$tmp_array = array();
|
491 |
+
|
492 |
+
$excluded_files = array_merge($excluded_files, wpstg_get_files($folder, $tmp_array, $wpstg_clone_details['total_size']));
|
493 |
+
}
|
494 |
+
$excluded_files = array_map("utf8_encode", $excluded_files ); // convert to utf 8 because $all_files is also utf8
|
495 |
+
$remaining_files = array_diff($all_files, $excluded_files);
|
496 |
+
file_put_contents($path, json_encode(array_values($remaining_files)));
|
497 |
+
}
|
498 |
+
|
499 |
+
$wpstg_clone_details['db_progress'] = isset($wpstg_clone_details['db_progress']) ? $wpstg_clone_details['db_progress'] : 0;
|
500 |
+
$wpstg_clone_details['files_progress'] = isset($wpstg_clone_details['files_progress']) ? $wpstg_clone_details['files_progress'] : 0;
|
501 |
+
$wpstg_clone_details['links_progress'] = isset($wpstg_clone_details['links_progress']) ? $wpstg_clone_details['links_progress'] : 0;
|
502 |
+
|
503 |
+
wpstg_save_options();
|
504 |
+
|
505 |
+
$unchecked_tables = isset($_POST['uncheckedTables']) ? $_POST['uncheckedTables'] : array();
|
506 |
+
$excluded_folders = isset($_POST['excludedFolders']) ? $_POST['excludedFolders'] : array();
|
507 |
+
//$clone_path = isset($_POST['path']) ? $_POST['path'] : get_home_path();
|
508 |
+
|
509 |
+
//wpstg_initiate_profile($clone, $unchecked_tables, $excluded_folders, $clone_path);
|
510 |
+
do_action('wpstg_start_cloning', $clone);
|
511 |
+
?>
|
512 |
+
<div class="wpstg-cloning-section"> <?php echo __('Copy database tables', 'wpstg');?>
|
513 |
+
<div class="wpstg-progress-bar">
|
514 |
+
<div class="wpstg-progress" id="wpstg-db-progress" style="width: <?php echo 100 * $wpstg_clone_details['db_progress']; ?>%;"></div>
|
515 |
+
</div>
|
516 |
+
</div>
|
517 |
+
<div class="wpstg-cloning-section"><?php echo __('Copy files', 'wpstg');?>
|
518 |
+
<div class="wpstg-progress-bar">
|
519 |
+
<div class="wpstg-progress" id="wpstg-files-progress" style="width: <?php echo 100 * $wpstg_clone_details['files_progress']; ?>%;"></div>
|
520 |
+
</div>
|
521 |
+
</div>
|
522 |
+
<div class="wpstg-cloning-section"><?php echo __('Replace Links', 'wpstg');?>
|
523 |
+
<div class="wpstg-progress-bar">
|
524 |
+
<div class="wpstg-progress" id="wpstg-links-progress" style="width: <?php echo 100 * $wpstg_clone_details['links_progress']; ?>%"></div>
|
525 |
+
</div>
|
526 |
+
</div>
|
527 |
+
<!--<a href="<?php //echo get_home_url();?>" id="wpstg-clone-url" target="_blank"></a>-->
|
528 |
+
<a href="#" id="wpstg-cancel-cloning" class="wpstg-link-btn button-primary"><?php echo __('Cancel', 'wpstg');?></a>
|
529 |
+
<!--<a href="#" id="wpstg-home-link" class="wpstg-link-btn button-primary"><?php //echo __('Home', 'wpstg');?></a>
|
530 |
+
<a href="#" id="wpstg-try-again" class="wpstg-link-btn button-primary"><?php //echo __('Try Again', 'wpstg');?></a>-->
|
531 |
+
|
532 |
+
<a href="#" id="wpstg-show-log-button" class="button" style="margin-top: 5px;"><?php _e('Display working log','wpstg'); ?></a>
|
533 |
+
<div><span id="wpstg-cloning-result"></span></div>
|
534 |
+
<div id="wpstg-finished-result"><h3>Congratulations: </h3>
|
535 |
+
<?php echo __('WP Staging succesfully created a staging site in a subfolder of your main site in: <strong> ', 'wpstg') . get_home_url(); ?>/<span id="wpstg_staging_name"></span></strong>
|
536 |
+
<br><br>
|
537 |
+
<?php echo __('Now, you have several options: ', 'wpstg'); ?>
|
538 |
+
<br>
|
539 |
+
<a href="<?php echo get_home_url();?>" id="wpstg-clone-url" target="_blank" class="wpstg-link-btn button-primary">Open staging site <span style="font-size: 10px;">(login with your admin credentials)</span></a>
|
540 |
+
<a href="" class="wpstg-link-btn button-primary" id="wpstg-remove-cloning"><?php echo __('Remove', 'wpstg');?></a>
|
541 |
+
<a href="" class="wpstg-link-btn button-primary" id="wpstg-home-link"><?php echo __('Start again', 'wpstg');?></a>
|
542 |
+
<div id="wpstg-success-notice">
|
543 |
+
<h3 style="margin-top:0px;"><?php _e('Important notes:' ,'wpstg'); ?></h3>
|
544 |
+
<ul>
|
545 |
+
<li> <strong>1. Permalinks on your <span style="font-style:italic;">staging site</span> will be disabled for technical reasons! </strong><br>Usually this is no problem for a staging website and you do not have to use permalinks!<br>
|
546 |
+
<p>If you really need permalinks on your staging site you have to do several modifications to your .htaccess (Apache) or *.conf (Nginx). <br>WP Staging can not do this automatically.
|
547 |
+
<p><strong>Read more:</strong>
|
548 |
+
<a href="http://stackoverflow.com/questions/5564881/htaccess-to-rewrite-wordpress-subdirectory-with-permalinks-to-root" target="_blank">Changes .htaccess </a> | <a href="http://robido.com/nginx/nginx-wordpress-subdirectory-configuration-example/" target="_blank">Changes nginx conf</a>
|
549 |
+
</li>
|
550 |
+
<li> <strong>2. Verify that you are REALLY working on your staging site and NOT on your production site if you are uncertain! </strong>
|
551 |
+
<br>Your main and your staging site are both reachable under the same domain so<br> it´s easy to become confused. <p>
|
552 |
+
To assist you we changed the name of the dashboard link to <strong style="font-style:italic;">"Staging - <span class="wpstg-clone-name"><?php echo get_bloginfo('name');?></span>"</strong>.
|
553 |
+
<br>You will notice this new name in the admin bar:
|
554 |
+
<br><br>
|
555 |
+
<img src="<?php echo WPSTG_PLUGIN_URL . '/assets/images/admin_dashboard.png'; ?>">
|
556 |
+
</li>
|
557 |
+
</ul>
|
558 |
+
</div>
|
559 |
+
</div>
|
560 |
+
<div id="wpstg-error-wrapper">
|
561 |
+
<div id="wpstg-error-details"></div>
|
562 |
+
</div>
|
563 |
+
<div id="wpstg-log-details"></div>
|
564 |
+
<?php
|
565 |
+
wp_die();
|
566 |
+
}
|
567 |
+
add_action('wp_ajax_wpstg_cloning', 'wpstg_cloning');
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Create a clone profile with start settings
|
571 |
+
*
|
572 |
+
* @param $clone
|
573 |
+
* @param $unchecked_tables
|
574 |
+
* @param $excluded_folders
|
575 |
+
*/
|
576 |
+
function wpstg_initiate_profile($clone, $unchecked_tables, $excluded_folders, $path) {
|
577 |
+
$wpstg_profiles = get_option('wpstg_profiles', array());
|
578 |
+
|
579 |
+
$profile = array(
|
580 |
+
'name' => $clone,
|
581 |
+
'unchecked_tables' => $unchecked_tables,
|
582 |
+
'excluded_folders' => $excluded_folders,
|
583 |
+
'path' => $path,
|
584 |
+
);
|
585 |
+
$wpstg_profiles[$clone] = $profile;
|
586 |
+
|
587 |
+
update_option('wpstg_profiles', $wpstg_profiles);
|
588 |
+
}
|
589 |
+
|
590 |
+
function wpstg_get_profile($clone) {
|
591 |
+
$wpstg_profiles = get_option('wpstg_profiles', array());
|
592 |
+
|
593 |
+
return isset($wpstg_profiles[$clone]) ? $wpstg_profiles[$clone] : false;
|
594 |
+
}
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Helper function to get database object for cloning into external database
|
598 |
+
*
|
599 |
+
* @global object $wpdb database object
|
600 |
+
* @global array $wpstg_clone_details clone related settings
|
601 |
+
*/
|
602 |
+
function wpstg_clone_db() {
|
603 |
+
global $wpdb, $wpstg_clone_details;
|
604 |
+
$wpstg_clone_details = wpstg_get_options();
|
605 |
+
|
606 |
+
// $clone = $profile = wpstg_get_profile
|
607 |
+
|
608 |
+
$db_helper = apply_filters('wpstg_db_helper', $wpdb, $wpstg_clone_details['current_clone']);
|
609 |
+
if ($db_helper->dbname != $wpdb->dbname)
|
610 |
+
wpstg_clone_db_external($db_helper);
|
611 |
+
else
|
612 |
+
wpstg_clone_db_internal();
|
613 |
+
}
|
614 |
+
add_action('wp_ajax_wpstg_clone_db', 'wpstg_clone_db');
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Clone into internal database
|
618 |
+
*
|
619 |
+
* @global object $wpdb database object
|
620 |
+
* @global array $wpstg_clone_details clone data
|
621 |
+
* @global array $wpstg_options global options
|
622 |
+
*/
|
623 |
+
function wpstg_clone_db_internal() {
|
624 |
+
global $wpdb, $wpstg_clone_details, $wpstg_options;
|
625 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
626 |
+
$wpstg_clone_details = wpstg_get_options();
|
627 |
+
|
628 |
+
// Start timer
|
629 |
+
wpstg_get_runtime();
|
630 |
+
|
631 |
+
// Use only for debugging
|
632 |
+
//usleep(40000000);
|
633 |
+
|
634 |
+
$progress = isset($wpstg_clone_details['db_progress']) ? $wpstg_clone_details['db_progress'] : 0;
|
635 |
+
if ($progress >= 1)
|
636 |
+
wpstg_return_json('wpstg_clone_db_internal', 'success', 'DB successfull copied', 1, wpstg_get_runtime());
|
637 |
+
|
638 |
+
|
639 |
+
$limit = isset($wpstg_options['wpstg_query_limit']) ? $wpstg_options['wpstg_query_limit'] : 100;
|
640 |
+
$rows_count = 0;
|
641 |
+
$log_data = '';
|
642 |
+
|
643 |
+
while (true) {
|
644 |
+
$table = isset($wpstg_clone_details['current_table']) ? $wpstg_clone_details['current_table'] : null;
|
645 |
+
$is_new = false;
|
646 |
+
|
647 |
+
if ($table === null) {
|
648 |
+
$tables = $wpstg_clone_details['all_tables'];
|
649 |
+
$cloned_tables = !empty($wpstg_clone_details['cloned_tables']) ? $wpstg_clone_details['cloned_tables'] : array(); //already cloned tables
|
650 |
+
$tables = array_diff($tables, $cloned_tables);
|
651 |
+
if (empty($tables)) { //exit condition
|
652 |
+
$wpstg_clone_details['db_progress'] = 1;
|
653 |
+
wpstg_save_options();
|
654 |
+
WPSTG()->logger->info('DB has been cloned successfully');
|
655 |
+
wpstg_return_json('wpstg_clone_db_internal', 'success', 'DB has been cloned successfully', 1, wpstg_get_runtime());
|
656 |
+
}
|
657 |
+
$table = reset($tables);
|
658 |
+
$is_new = true;
|
659 |
+
}
|
660 |
+
|
661 |
+
$new_table = $wpstg_clone_details['current_clone'] . '_' . $table;
|
662 |
+
$offset = isset($wpstg_clone_details['offsets'][$table]) ? $wpstg_clone_details['offsets'][$table] : 0;
|
663 |
+
$is_cloned = true;
|
664 |
+
|
665 |
+
if ($is_new) {
|
666 |
+
$existing_table = $wpdb->get_var(
|
667 |
+
$wpdb->prepare(
|
668 |
+
'show tables like %s',
|
669 |
+
$new_table
|
670 |
+
)
|
671 |
+
);
|
672 |
+
if ($existing_table == $new_table)
|
673 |
+
$wpdb->query("drop table $new_table");
|
674 |
+
|
675 |
+
$is_cloned = $wpdb->query("create table `$new_table` like `$table`");
|
676 |
+
wpstg_debug_log("Debug QUERY: create table $new_table like $table");
|
677 |
+
$wpstg_clone_details['current_table'] = $table;
|
678 |
+
}
|
679 |
+
if ($is_cloned) {
|
680 |
+
/*$limit -= $rows_count;
|
681 |
+
if ($limit < 1)
|
682 |
+
break; rhe */
|
683 |
+
$inserted_rows = $wpdb->query(
|
684 |
+
"insert `$new_table` select * from `$table` limit $offset, $limit"
|
685 |
+
);
|
686 |
+
wpstg_debug_log("Debug QUERY: insert $new_table select * from $table limit $offset, $limit");
|
687 |
+
if ($inserted_rows !== false) {
|
688 |
+
$wpstg_clone_details['offsets'][$table] = $offset + $inserted_rows;
|
689 |
+
$rows_count += $inserted_rows;
|
690 |
+
if ($inserted_rows < $limit) {
|
691 |
+
$wpstg_clone_details['cloned_tables'][] = $table;
|
692 |
+
$all_tables_count = count($wpstg_clone_details['all_tables']);
|
693 |
+
$cloned_tables_count = count($wpstg_clone_details['cloned_tables']);
|
694 |
+
$wpstg_clone_details['db_progress'] = $cloned_tables_count / $all_tables_count;
|
695 |
+
$log_data .= '[' . date('d-m-Y H:i:s') . '] Copy database table: ' . $wpstg_clone_details['current_table'] . '<br>';
|
696 |
+
unset($wpstg_clone_details['current_table']);
|
697 |
+
wpstg_save_options();
|
698 |
+
}
|
699 |
+
|
700 |
+
if ($rows_count > $limit) {
|
701 |
+
$all_tables_count = count($wpstg_clone_details['all_tables']);
|
702 |
+
$cloned_tables_count = count($wpstg_clone_details['cloned_tables']);
|
703 |
+
$wpstg_clone_details['db_progress'] = $cloned_tables_count / $all_tables_count;
|
704 |
+
wpstg_save_options();
|
705 |
+
$log_data .= '[' . date('d-m-Y H:i:s') . '] Copy database table: ' . $table . '<br>';
|
706 |
+
WPSTG()->logger->info( 'Query limit exceeded. Starting new query batch! Table: ' . $table);
|
707 |
+
wpstg_return_json('wpstg_clone_db_internal', 'success', wpstg_get_log_data($progress) . $log_data, $wpstg_clone_details['db_progress'], wpstg_get_runtime());
|
708 |
+
}
|
709 |
+
} else {
|
710 |
+
WPSTG()->logger->info('Table ' . $new_table . ' has been created, BUT inserting rows failed. This happens sometimes when a table had been updated during staging process. Exclude this table from copying and try again. Offset: ' . $offset . '');
|
711 |
+
wpstg_save_options();
|
712 |
+
wpstg_return_json('wpstg_clone_db_internal', 'fail', 'Table ' . $new_table . ' has been created, BUT inserting rows failed. This happens sometimes when a table had been updated during staging process. Exclude this table from copying and try again. Offset: ' . $offset, $wpstg_clone_details['db_progress'] . ' ', wpstg_get_runtime());
|
713 |
+
|
714 |
+
}
|
715 |
+
} else {
|
716 |
+
WPSTG()->logger->info('Creating table ' . $table . ' has been failed.');
|
717 |
+
wpstg_save_options();
|
718 |
+
wpstg_return_json('wpstg_clone_db_internal', 'fail', 'Copying table ' . $table . ' has been failed.', $wpstg_clone_details['db_progress'], wpstg_get_runtime());
|
719 |
+
}
|
720 |
+
$log_data .= '[' . date('d-m-Y H:i:s') . '] Copy database table: ' . $table . ' DB rows: ' . $offset . '<br>';
|
721 |
+
} //end while
|
722 |
+
wpstg_save_options();
|
723 |
+
wpstg_return_json('wpstg_clone_db_internal', 'success', wpstg_get_log_data($progress) . $log_data, $progress, wpstg_get_runtime());
|
724 |
+
}
|
725 |
+
/**
|
726 |
+
*
|
727 |
+
* Clone into separate database
|
728 |
+
*
|
729 |
+
* @global object $wpdb database object
|
730 |
+
* @global array $wpstg_clone_details clone related data
|
731 |
+
* @global array $wpstg_options global settings
|
732 |
+
*
|
733 |
+
* @param object $db_helper new database object
|
734 |
+
*/
|
735 |
+
function wpstg_clone_db_external($db_helper) {
|
736 |
+
global $wpdb, $wpstg_clone_details, $wpstg_options;
|
737 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
738 |
+
$one = 1;
|
739 |
+
|
740 |
+
$progress = isset($wpstg_clone_details['db_progress']) ? $wpstg_clone_details['db_progress'] : 0;
|
741 |
+
if ($progress >= 1)
|
742 |
+
wp_die(1);
|
743 |
+
|
744 |
+
$limit = isset($wpstg_options['wpstg_query_limit']) ? $wpstg_options['wpstg_query_limit'] : 1000;
|
745 |
+
$rows_count = 0;
|
746 |
+
|
747 |
+
while (true) {
|
748 |
+
$table = isset($wpstg_clone_details['current_table']) ? $wpstg_clone_details['current_table'] : null;
|
749 |
+
$is_new = false;
|
750 |
+
|
751 |
+
if ($table === null) {
|
752 |
+
$tables = $wpstg_clone_details['all_tables'];
|
753 |
+
$cloned_tables = !empty($wpstg_clone_details['cloned_tables']) ? $wpstg_clone_details['cloned_tables'] : array(); //already cloned tables
|
754 |
+
$tables = array_diff($tables, $cloned_tables);
|
755 |
+
if (empty($tables)) { //exit condition
|
756 |
+
$wpstg_clone_details['db_progress'] = 1;
|
757 |
+
wpstg_save_options();
|
758 |
+
WPSTG()->logger->info('DB has been cloned successfully');
|
759 |
+
wp_die(1);
|
760 |
+
}
|
761 |
+
$table = reset($tables);
|
762 |
+
$is_new = true;
|
763 |
+
}
|
764 |
+
|
765 |
+
$new_table = $wpstg_clone_details['current_clone'] . '_' . $table;
|
766 |
+
$offset = isset($wpstg_clone_details['offsets'][$table]) ? $wpstg_clone_details['offsets'][$table] : 0;
|
767 |
+
$is_cloned = true;
|
768 |
+
|
769 |
+
if ($is_new) {
|
770 |
+
$existing_table = $db_helper->get_var(
|
771 |
+
$db_helper->prepare(
|
772 |
+
'show tables like %s',
|
773 |
+
$new_table
|
774 |
+
)
|
775 |
+
);
|
776 |
+
if ($existing_table == $new_table)
|
777 |
+
$db_helper->query("drop table $new_table");
|
778 |
+
|
779 |
+
$tmp_result = $wpdb->get_row("show create table $table", ARRAY_N);
|
780 |
+
$create_sql = str_replace($tmp_result[0], $new_table, $tmp_result[1], $one);
|
781 |
+
$is_cloned = $db_helper->query($create_sql);
|
782 |
+
$wpstg_clone_details['current_table'] = $table;
|
783 |
+
}
|
784 |
+
if ($is_cloned) {
|
785 |
+
$limit -= $rows_count;
|
786 |
+
if ($limit < 1)
|
787 |
+
break;
|
788 |
+
|
789 |
+
$selected_rows = $wpdb->get_results("select * from $table limit $offset, $limit", ARRAY_N);
|
790 |
+
$inserted_rows = 0;
|
791 |
+
foreach ($selected_rows as $row) {
|
792 |
+
$row = esc_sql($row);
|
793 |
+
$values = implode("', '", $row);
|
794 |
+
$query = "insert into $new_table values('$values')";
|
795 |
+
$inserted_rows += $db_helper->query($query);
|
796 |
+
}
|
797 |
+
|
798 |
+
if ($inserted_rows !== false) {
|
799 |
+
$wpstg_clone_details['offsets'][$table] = $offset + $inserted_rows;
|
800 |
+
$rows_count += $inserted_rows;
|
801 |
+
if ($inserted_rows < $limit) {
|
802 |
+
$wpstg_clone_details['cloned_tables'][] = $table;
|
803 |
+
$all_tables_count = count($wpstg_clone_details['all_tables']);
|
804 |
+
$cloned_tables_count = count($wpstg_clone_details['cloned_tables']);
|
805 |
+
$wpstg_clone_details['db_progress'] = $cloned_tables_count / $all_tables_count;
|
806 |
+
unset($wpstg_clone_details['current_table']);
|
807 |
+
wpstg_save_options();
|
808 |
+
}
|
809 |
+
if ($rows_count > $limit) {
|
810 |
+
$all_tables_count = count($wpstg_clone_details['all_tables']);
|
811 |
+
$cloned_tables_count = count($wpstg_clone_details['cloned_tables']);
|
812 |
+
$wpstg_clone_details['db_progress'] = $cloned_tables_count / $all_tables_count;
|
813 |
+
wpstg_save_options();
|
814 |
+
WPSTG()->logger->info('Query limit is exceeded. Current Table: ' . $table);
|
815 |
+
wp_die($wpstg_clone_details['db_progress']);
|
816 |
+
}
|
817 |
+
} else {
|
818 |
+
WPSTG()->logger->info('Table ' . $new_table . ' has been created, BUT inserting rows failed. Offset: ' . $offset);
|
819 |
+
wpstg_save_options();
|
820 |
+
//wp_die(-1);
|
821 |
+
wp_die('Table ' . $new_table . ' has been created, BUT inserting rows failed. Offset: ' . $offset);
|
822 |
+
}
|
823 |
+
} else {
|
824 |
+
WPSTG()->logger->info('Creating table ' . $table . ' has been failed.');
|
825 |
+
wpstg_save_options();
|
826 |
+
//wp_die(-1);
|
827 |
+
wp_die('Creating table ' . $table . ' has been failed.');
|
828 |
+
}
|
829 |
+
} //end while
|
830 |
+
wpstg_save_options();
|
831 |
+
wp_die($progress);
|
832 |
+
}
|
833 |
+
|
834 |
+
/**
|
835 |
+
* Get clone root path. Thats the absolute path to wordpress,
|
836 |
+
* no matter if wordpress is installed in a subdirectory or not.
|
837 |
+
* This path is everytime the same and is used to determine the clone destination
|
838 |
+
*
|
839 |
+
* @global $wpstg_options global settings
|
840 |
+
* @return string clone root path
|
841 |
+
*/
|
842 |
+
function wpstg_get_clone_root_path() {
|
843 |
+
$home_path = ABSPATH;
|
844 |
+
return str_replace('\\', '/', $home_path);
|
845 |
+
}
|
846 |
+
|
847 |
+
/**
|
848 |
+
* Copy selected files files into staging subfolder
|
849 |
+
*
|
850 |
+
* @global $wpstg_clone_details
|
851 |
+
* @global $wpstg_options
|
852 |
+
* @global $batch
|
853 |
+
*/
|
854 |
+
function wpstg_copy_files() {
|
855 |
+
global $wpstg_clone_details, $wpstg_options, $batch;
|
856 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
857 |
+
$wpstg_clone_details = wpstg_get_options();
|
858 |
+
|
859 |
+
// Start timer
|
860 |
+
wpstg_get_runtime();
|
861 |
+
|
862 |
+
// Use only for debugging
|
863 |
+
//usleep(40000000);
|
864 |
+
|
865 |
+
$clone_root_path = get_home_path() . $wpstg_clone_details['current_clone'];
|
866 |
+
//$clone_root_path = wpstg_get_clone_root_path() . $wpstg_clone_details['current_clone'];
|
867 |
+
$sourcepath = wpstg_get_upload_dir() . '/remaining_files.json';
|
868 |
+
$files = json_decode(file_get_contents($sourcepath), true);
|
869 |
+
$start_index = isset($wpstg_clone_details['file_index']) ? $wpstg_clone_details['file_index'] : 0;
|
870 |
+
$wpstg_clone_details['files_progress'] = isset($wpstg_clone_details['files_progress']) ? $wpstg_clone_details['files_progress'] : 0;
|
871 |
+
$batch_size = isset($wpstg_options['wpstg_batch_size']) ? $wpstg_options['wpstg_batch_size'] : 2;
|
872 |
+
$batch_size *= 1024*1024;
|
873 |
+
$batch = 0;
|
874 |
+
$log_data = '';
|
875 |
+
$size = 0;
|
876 |
+
|
877 |
+
if (!is_dir($clone_root_path))
|
878 |
+
mkdir($clone_root_path);
|
879 |
+
|
880 |
+
for ($i = $start_index; $i < count($files); $i++) {
|
881 |
+
$new_file = wpstg_create_directories($files[$i], wpstg_get_clone_root_path(), $clone_root_path);
|
882 |
+
|
883 |
+
if ( file_exists($files[$i] ) ){
|
884 |
+
$size = filesize($files[$i]);
|
885 |
+
}
|
886 |
+
|
887 |
+
if ( is_file($files[$i]) && file_exists($files[$i]) && $size > $batch_size ) { // is_file() checks if its a symlink or real file
|
888 |
+
//if ( is_file($files[$i] && file_exists($files[$i] && $size > $batch_size) ) ) { // is_file() checks if its a symlink or real file
|
889 |
+
if (wpstg_copy_large_file($files[$i], $new_file, $batch_size)) {
|
890 |
+
//WPSTG()->logger->info('Copy LARGE file: ' . $files[$i] . '. Batch size: ' . wpstg_short_size($batch + $size) . ' (' . ($batch + $size) . ' bytes)');
|
891 |
+
$wpstg_clone_details['file_index'] = $i + 1;
|
892 |
+
//$part = ($batch + $size) / $wpstg_clone_details['total_size'];
|
893 |
+
$part = $batch / $wpstg_clone_details['total_size'];
|
894 |
+
$wpstg_clone_details['files_progress'] += $part;
|
895 |
+
wpstg_save_options();
|
896 |
+
wpstg_return_json('wpstg_copy_files', 'success', '<br> [' . date('d-m-Y H:i:s') . '] Copy LARGE file: ' . $files[$i] . '. Batch size: ' . wpstg_short_size($batch + $size) . ' (' . ($batch + $size) . ' bytes)', $wpstg_clone_details['files_progress'], wpstg_get_runtime());
|
897 |
+
} else {
|
898 |
+
WPSTG()->logger->info('Copying LARGE file has been failed and will be skipped: ' . $files[$i]);
|
899 |
+
$wpstg_clone_details['file_index'] = $i + 1; //increment it because we want to skip this file when it can not be copied successfully
|
900 |
+
$part = $batch / $wpstg_clone_details['total_size'];
|
901 |
+
$wpstg_clone_details['files_progress'] += $part;
|
902 |
+
wpstg_save_options();
|
903 |
+
wpstg_return_json('wpstg_copy_files', 'fail', '<br> [' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fail: </span> Copying LARGE file has been failed and will be skipped: ' . $files[$i], $wpstg_clone_details['files_progress'], wpstg_get_runtime());
|
904 |
+
}
|
905 |
+
}
|
906 |
+
if ( $batch_size > $batch + $size ) {
|
907 |
+
//if ( is_readable( $files[$i] ) && is_file($files[$i]) && copy($files[$i], $new_file)) {
|
908 |
+
if ( is_readable( $files[$i] ) && copy($files[$i], $new_file)) {
|
909 |
+
$batch += $size;
|
910 |
+
WPSTG()->logger->info('Copy file no: ' . $i . ' Total files:' . count($files) .' File: ' . $files[$i] . ' to ' . $new_file);
|
911 |
+
//wpstg_return_json('wpstg_copy_files', 'success', '[' . date('d-m-Y H:i:s') . '] Copy file no: ' . $i . ' Total files:' . count($files) .' File: ' . $files[$i] . ' to ' . $new_file, $wpstg_clone_details['files_progress'], wpstg_get_runtime());
|
912 |
+
} else {
|
913 |
+
WPSTG()->logger->info('Copying file has been failed and will be skipped: ' . $files[$i]);
|
914 |
+
$wpstg_clone_details['file_index'] = $i + 1; //increment it because we want to skip this file when it can not be copied successfully
|
915 |
+
$part = $batch / $wpstg_clone_details['total_size'];
|
916 |
+
$wpstg_clone_details['files_progress'] += $part;
|
917 |
+
wpstg_save_options();
|
918 |
+
//wp_die(-1);
|
919 |
+
//wp_die('Copying file has been failed: ' . $files[$i]);
|
920 |
+
wpstg_return_json('wpstg_copy_files', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fail: </span> Copying file has been failed and will be skipped: ' . $files[$i], $wpstg_clone_details['files_progress'], wpstg_get_runtime());
|
921 |
+
}
|
922 |
+
} else {
|
923 |
+
WPSTG()->logger->info('Batch size: ' . wpstg_short_size($batch) . ' (' . $batch . ' bytes)' . '. Current File: ' . $files[$i]);
|
924 |
+
$wpstg_clone_details['file_index'] = $i;
|
925 |
+
$part = $batch / $wpstg_clone_details['total_size'];
|
926 |
+
$wpstg_clone_details['files_progress'] += $part;
|
927 |
+
wpstg_save_options();
|
928 |
+
|
929 |
+
wpstg_return_json('wpstg_copy_files', 'success', '[' . date('d-m-Y H:i:s') . '] File copy in progress... ' . round($wpstg_clone_details['files_progress'] * 100, 1) . '%', $wpstg_clone_details['files_progress'], wpstg_get_runtime());
|
930 |
+
}
|
931 |
+
} // for loop
|
932 |
+
|
933 |
+
$wpstg_clone_details['files_progress'] = 1;
|
934 |
+
wpstg_save_options();
|
935 |
+
//wp_die(1);
|
936 |
+
wpstg_return_json('wpstg_copy_files', 'success', '[' . date('d-m-Y H:i:s') . '] File copy succeeded. Percent 100%', $wpstg_clone_details['files_progress'], wpstg_get_runtime());
|
937 |
+
}
|
938 |
+
add_action('wp_ajax_wpstg_copy_files', 'wpstg_copy_files');
|
939 |
+
|
940 |
+
|
941 |
+
/**
|
942 |
+
* Create target directory during copy process and returns path to the copied file
|
943 |
+
*
|
944 |
+
* @param string $source Source file including full path e.g. var/www/htdocs/mainsite/index.php
|
945 |
+
* @param string $home_root_path path of the main wordpress installation e.g. var/www/htdocs/mainsite/
|
946 |
+
* @param string $clone_root_path main path of the clone e.g. var/www/htdocs/mainsite/myclone/
|
947 |
+
*
|
948 |
+
* @return string full target path e.g. var/www/htdocs/mainsite/myclone/index.php
|
949 |
+
*
|
950 |
+
*
|
951 |
+
*/
|
952 |
+
function wpstg_create_directories($source, $home_root_path, $clone_root_path) {
|
953 |
+
$path = substr($source, strlen($home_root_path)); // remove the source part from home_root_path
|
954 |
+
$folders = explode('/', $path); // convert path into array
|
955 |
+
array_pop($folders); // remove the file
|
956 |
+
|
957 |
+
|
958 |
+
$new_folder = $clone_root_path;
|
959 |
+
//$new_folder = wpstg_get_clone_root_path();
|
960 |
+
foreach ($folders as $folder) {
|
961 |
+
$new_folder .= '/' . $folder;
|
962 |
+
if (!is_dir($new_folder))
|
963 |
+
mkdir($new_folder);
|
964 |
+
}
|
965 |
+
|
966 |
+
$destination = $clone_root_path . "/" . $path;
|
967 |
+
//$destination = $new_folder . "/" . $path;
|
968 |
+
return $destination;
|
969 |
+
}
|
970 |
+
|
971 |
+
|
972 |
+
|
973 |
+
/**
|
974 |
+
*
|
975 |
+
* Copy large files in chunks
|
976 |
+
* Set return value to true, no matter if copying has been successfull or not.
|
977 |
+
* Unsuccessfull copying will be skipped for large files.
|
978 |
+
*
|
979 |
+
* @param string $src source path
|
980 |
+
* @param string $dst destination path
|
981 |
+
* @param integer $buffersize // Not used at the moment
|
982 |
+
* @return boolean
|
983 |
+
*/
|
984 |
+
function wpstg_copy_large_file($src, $dst, $buffersize) {
|
985 |
+
$src = fopen($src, 'r');
|
986 |
+
$dest = fopen($dst, 'w');
|
987 |
+
|
988 |
+
// Try first method:
|
989 |
+
while (! feof($src)){
|
990 |
+
if (false === fwrite($dest, fread($src, $buffersize))){
|
991 |
+
$error = true;
|
992 |
+
}
|
993 |
+
}
|
994 |
+
// Try second method if first one failed
|
995 |
+
if (isset($error) && ($error === true)){
|
996 |
+
while(!feof($src)){
|
997 |
+
stream_copy_to_stream($src, $dest, 1024 );
|
998 |
+
}
|
999 |
+
fclose($src);
|
1000 |
+
fclose($dest);
|
1001 |
+
return true;
|
1002 |
+
}
|
1003 |
+
fclose($src);
|
1004 |
+
fclose($dest);
|
1005 |
+
return true;
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
|
1009 |
+
|
1010 |
+
/**
|
1011 |
+
* Replace all urls in data
|
1012 |
+
*
|
1013 |
+
* @global object $wpdb
|
1014 |
+
* @global array $wpstg_clone_details
|
1015 |
+
*/
|
1016 |
+
|
1017 |
+
function wpstg_replace_links() {
|
1018 |
+
global $wpdb, $wpstg_clone_details;
|
1019 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
1020 |
+
$wpstg_clone_details = wpstg_get_options();
|
1021 |
+
|
1022 |
+
$db_helper = apply_filters('wpstg_db_helper', $wpdb, $wpstg_clone_details['current_clone']);
|
1023 |
+
$new_prefix = $wpstg_clone_details['current_clone'] . '_' . $wpdb->prefix;
|
1024 |
+
$wpstg_clone_details['links_progress'] = isset($wpstg_clone_details['links_progress']) ? $wpstg_clone_details['links_progress'] : 0;
|
1025 |
+
//replace site url in options
|
1026 |
+
if ($wpstg_clone_details['links_progress'] < 0.1) {
|
1027 |
+
$result = $db_helper->query(
|
1028 |
+
$db_helper->prepare(
|
1029 |
+
'update ' . $new_prefix . 'options set option_value = %s where option_name = \'siteurl\' or option_name = \'home\'',
|
1030 |
+
get_home_url() . '/' . $wpstg_clone_details['current_clone']
|
1031 |
+
)
|
1032 |
+
);
|
1033 |
+
if (!$result) {
|
1034 |
+
$wpstg_clone_details['links_progress'] = 0.33;
|
1035 |
+
$error = isset($db_helper->dbh->error) ? $db_helper->dbh->error : '';
|
1036 |
+
WPSTG()->logger->info('Replacing site url has been failed. ' . $error);
|
1037 |
+
//wp_die($db_helper->dbh->error);
|
1038 |
+
wpstg_save_options();
|
1039 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fail: </span>Replacing site url has been failed. DB Error: ' . $error, $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1040 |
+
} else {
|
1041 |
+
$wpstg_clone_details['links_progress'] = 0.33;
|
1042 |
+
WPSTG()->logger->info('Replacing siteurl has been done succesfully');
|
1043 |
+
wpstg_save_options();
|
1044 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] Replacing "siteurl" has been done succesfully', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1045 |
+
}
|
1046 |
+
}
|
1047 |
+
//Update wpstg_is_staging_site in clone options table
|
1048 |
+
if ($wpstg_clone_details['links_progress'] < 0.34) {
|
1049 |
+
$result = $db_helper->query(
|
1050 |
+
$db_helper->prepare(
|
1051 |
+
'update ' . $new_prefix . 'options set option_value = %s where option_name = \'wpstg_is_staging_site\'',
|
1052 |
+
'true'
|
1053 |
+
)
|
1054 |
+
);
|
1055 |
+
if (!$result) {
|
1056 |
+
$wpstg_clone_details['links_progress'] = 0.43;
|
1057 |
+
WPSTG()->logger->info('Updating db table ' . $new_prefix . 'options where option_name = wpstg_is_staging_site has been failed');
|
1058 |
+
//wp_die(-1);
|
1059 |
+
//wp_die('Updating option[wpstg_is_staging_site] has been failed');
|
1060 |
+
wpstg_save_options();
|
1061 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fail: </span> Updating db' . $new_prefix . 'options where option_name = wpstg_is_staging_site has been failed', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1062 |
+
} else {
|
1063 |
+
$wpstg_clone_details['links_progress'] = 0.43;
|
1064 |
+
WPSTG()->logger->info('Updating option [wpstg_is_staging_site] has been done succesfully');
|
1065 |
+
wpstg_save_options();
|
1066 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] Updating option [wpstg_is_staging_site] has been done succesfully', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1067 |
+
}
|
1068 |
+
}
|
1069 |
+
|
1070 |
+
//Update rewrite_rules in clone options table
|
1071 |
+
if ($wpstg_clone_details['links_progress'] < 0.44) {
|
1072 |
+
$result = $db_helper->query(
|
1073 |
+
$db_helper->prepare(
|
1074 |
+
'update ' . $new_prefix . 'options set option_value = %s where option_name = \'rewrite_rules\'',
|
1075 |
+
''
|
1076 |
+
)
|
1077 |
+
);
|
1078 |
+
if (!$result) {
|
1079 |
+
WPSTG()->logger->info('Updating option[rewrite_rules] not successfull, probably because the main site is not using permalinks');
|
1080 |
+
$wpstg_clone_details['links_progress'] = 0.45;
|
1081 |
+
// Do not die here. This db option is not available on sites with permalinks disabled, so we want to continue
|
1082 |
+
//wp_die(-1);
|
1083 |
+
wpstg_save_options();
|
1084 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . '] Updating option[rewrite_rules] was not possible. Will be skipped! Usually this is no problem and happens only when main site has no permalinks enabled!', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1085 |
+
} else {
|
1086 |
+
$wpstg_clone_details['links_progress'] = 0.45;
|
1087 |
+
WPSTG()->logger->info('Updating option [rewrite_rules] has been done succesfully');
|
1088 |
+
wpstg_save_options();
|
1089 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] Updating option [rewrite_rules] has been done succesfully', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1090 |
+
|
1091 |
+
}
|
1092 |
+
}
|
1093 |
+
|
1094 |
+
//replace table prefix in meta_keys
|
1095 |
+
if ($wpstg_clone_details['links_progress'] < 0.50) {
|
1096 |
+
$result_options = $db_helper->query(
|
1097 |
+
$db_helper->prepare(
|
1098 |
+
'update ' . $new_prefix . 'usermeta set meta_key = replace(meta_key, %s, %s) where meta_key like %s',
|
1099 |
+
$wpdb->prefix,
|
1100 |
+
$new_prefix,
|
1101 |
+
$wpdb->prefix . '_%'
|
1102 |
+
)
|
1103 |
+
);
|
1104 |
+
$result_usermeta = $db_helper->query(
|
1105 |
+
$db_helper->prepare(
|
1106 |
+
'update ' . $new_prefix . 'options set option_name = replace(option_name, %s, %s) where option_name like %s',
|
1107 |
+
$wpdb->prefix,
|
1108 |
+
$new_prefix,
|
1109 |
+
$wpdb->prefix . '_%'
|
1110 |
+
)
|
1111 |
+
);
|
1112 |
+
if (!$result_options || !$result_usermeta) {
|
1113 |
+
$wpstg_clone_details['links_progress'] = 0.66;
|
1114 |
+
WPSTG()->logger->error('Updating table ' . $new_prefix . ' has been failed.');
|
1115 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . ']<span style="color:red;">Fatal error!</span> Updating table ' . $new_prefix . ' has been failed.', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1116 |
+
//wp_die(.51);
|
1117 |
+
//wp_die('Updating table ' . $new_prefix . ' has been failed.');
|
1118 |
+
} else {
|
1119 |
+
$wpstg_clone_details['links_progress'] = 0.66;
|
1120 |
+
WPSTG()->logger->error('Updating db prefix "' . $wpdb->prefix . '" to "' . $new_prefix . '" has been done succesfully.');
|
1121 |
+
wpstg_save_options();
|
1122 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] Updating prefix name ' . $wpdb->prefix . ' to ' . $new_prefix . ' has been done succesfully.', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1123 |
+
}
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
//replace $table_prefix in wp-config.php
|
1127 |
+
if ($wpstg_clone_details['links_progress'] < 0.67) {
|
1128 |
+
$wpstg_clone_details['links_progress'] = 0.67;
|
1129 |
+
$path = get_home_path() . $wpstg_clone_details['current_clone'] . '/wp-config.php';
|
1130 |
+
$content = file_get_contents($path);
|
1131 |
+
if ($content) {
|
1132 |
+
$content = str_replace('$table_prefix', '$table_prefix = \'' . $new_prefix . '\';//', $content); // replace table prefix
|
1133 |
+
$content = str_replace(get_home_url(), wpstg_get_staging_url(), $content); // replace any url
|
1134 |
+
if ($db_helper->dbname != $wpdb->dbname) {
|
1135 |
+
$content = str_replace('define(\'DB_NAME\'', 'define(\'DB_NAME\', \'' . $db_helper->dbname . '\');//', $content);
|
1136 |
+
$content = str_replace('define(\'DB_USER\'', 'define(\'DB_USER\', \'' . $db_helper->dbuser . '\');//', $content);
|
1137 |
+
$content = str_replace('define(\'DB_PASSWORD\'', 'define(\'DB_PASSWORD\', \'' . $db_helper->dbpassword . '\');//', $content);
|
1138 |
+
$content = str_replace('define(\'DB_HOST\'', 'define(\'DB_HOST\', \'' . $db_helper->dbhost . '\');//', $content);
|
1139 |
+
}
|
1140 |
+
if (FALSE === file_put_contents($path, $content)) {
|
1141 |
+
wpstg_save_options(); // we have to die hier @to do write function
|
1142 |
+
WPSTG()->logger->info($path . ' is not writable');
|
1143 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fatal error: </span>Can not modify ' . $path . ' !', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1144 |
+
}else{
|
1145 |
+
wpstg_save_options();
|
1146 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] ' . $path . ' has been successfully modified!', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1147 |
+
}
|
1148 |
+
} else {
|
1149 |
+
WPSTG()->logger->info($path . ' is not readable.');
|
1150 |
+
wpstg_save_options();
|
1151 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fail: </span>' . $path . ' is not writable', $wpstg_clone_details['links_progress'], wpstg_get_runtime());
|
1152 |
+
}
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
|
1156 |
+
// Replace path in index.php
|
1157 |
+
wpstg_reset_index_php(0.71);
|
1158 |
+
|
1159 |
+
$existing_clones = get_option('wpstg_existing_clones', array());
|
1160 |
+
if (false === array_search($wpstg_clone_details['current_clone'], $existing_clones)) {
|
1161 |
+
$existing_clones[] = $wpstg_clone_details['current_clone'];
|
1162 |
+
update_option('wpstg_existing_clones', $existing_clones);
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
wpstg_clear_options();
|
1166 |
+
|
1167 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] All string replacements have been done successfully', 1, wpstg_get_runtime());
|
1168 |
+
}
|
1169 |
+
add_action('wp_ajax_wpstg_replace_links', 'wpstg_replace_links');
|
1170 |
+
|
1171 |
+
/**
|
1172 |
+
* Reset index.php to original file
|
1173 |
+
* Check first if main wordpress is used in subfolder and index.php in parent directory
|
1174 |
+
*
|
1175 |
+
* See: https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
|
1176 |
+
*
|
1177 |
+
* @param $progress decimal value as progress indicatior. 1 = 100% | 0.9 = 90% and so on
|
1178 |
+
*
|
1179 |
+
* Return JSON
|
1180 |
+
*/
|
1181 |
+
function wpstg_reset_index_php($progress){
|
1182 |
+
global $wpstg_options, $wpstg_clone_details;
|
1183 |
+
|
1184 |
+
if ( isset( $wpstg_options['wordpress_subdirectory'] ) && $wpstg_options['wordpress_subdirectory'] === "1" && $wpstg_clone_details['links_progress'] < $progress) {
|
1185 |
+
$wpstg_clone_details['links_progress'] = $progress;
|
1186 |
+
$path = get_home_path() . $wpstg_clone_details['current_clone'] . '/index.php';
|
1187 |
+
$content = file_get_contents($path);
|
1188 |
+
|
1189 |
+
if ($content) {
|
1190 |
+
|
1191 |
+
$pattern = "/(require(.*)wp-blog-header.php' \);)/";
|
1192 |
+
if ( !preg_match($pattern, $content, $matches) )
|
1193 |
+
wpstg_return_json('wpstg_wp_in_subdirectory', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fatal error: </span>wp-blog-header.php not included in ' . $path . ' !', $progress, wpstg_get_runtime());
|
1194 |
+
|
1195 |
+
$pattern2 = "/require(.*) dirname(.*) __FILE__ (.*) \. '(.*)wp-blog-header.php'(.*);/";
|
1196 |
+
$replace = "require( dirname( __FILE__ ) . '/wp-blog-header.php' ); // " . $matches[0] . " // Changed by WP-Staging";
|
1197 |
+
$content = preg_replace($pattern2, $replace, $content);
|
1198 |
+
|
1199 |
+
if (FALSE === file_put_contents($path, $content)) {
|
1200 |
+
wpstg_save_options(); // we should throw fatal error here to die @todo create function()
|
1201 |
+
WPSTG()->logger->info($path . ' is not writable');
|
1202 |
+
wpstg_return_json('wpstg_wp_in_subdirectory', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fatal error: </span>Can not modify ' . $path . ' !', $progress, wpstg_get_runtime());
|
1203 |
+
} else {
|
1204 |
+
wpstg_save_options();
|
1205 |
+
wpstg_return_json('wpstg_replace_links', 'success', '[' . date('d-m-Y H:i:s') . '] ' . $path . ' has been successfully modified!', $progress, wpstg_get_runtime());
|
1206 |
+
}
|
1207 |
+
} else {
|
1208 |
+
WPSTG()->logger->info($path . ' is not readable.');
|
1209 |
+
wpstg_save_options();
|
1210 |
+
wpstg_return_json('wpstg_replace_links', 'fail', '[' . date('d-m-Y H:i:s') . '] <span style="color:red;">Fail: </span>' . $path . ' is not writable', $progress, wpstg_get_runtime());
|
1211 |
+
}
|
1212 |
+
}
|
1213 |
+
}
|
1214 |
+
|
1215 |
+
/**
|
1216 |
+
* Clear all task related data in *.json files
|
1217 |
+
*
|
1218 |
+
* @return void
|
1219 |
+
*/
|
1220 |
+
function wpstg_clear_options() {
|
1221 |
+
$path = wpstg_get_upload_dir() . '/clone_details.json';
|
1222 |
+
if (wp_is_writable($path)) {
|
1223 |
+
file_put_contents($path, '');
|
1224 |
+
}
|
1225 |
+
WPSTG()->logger->info(wpstg_get_upload_dir() . '/clone_details.json has been purged successfully');
|
1226 |
+
|
1227 |
+
$path = wpstg_get_upload_dir() . '/remaining_files.json';
|
1228 |
+
if (wp_is_writable($path)) {
|
1229 |
+
file_put_contents($path, '');
|
1230 |
+
}
|
1231 |
+
WPSTG()->logger->info(wpstg_get_upload_dir() . '/remaining_files.json has been purged successfully');
|
1232 |
+
}
|
1233 |
+
|
1234 |
+
/** Check the files before removing
|
1235 |
+
*
|
1236 |
+
* @global object $wpdb
|
1237 |
+
*/
|
1238 |
+
function wpstg_preremove_clone() {
|
1239 |
+
global $wpdb;
|
1240 |
+
|
1241 |
+
$clone = $_POST['cloneID'];
|
1242 |
+
$prefix = $clone . '_' . $wpdb->prefix;
|
1243 |
+
$db_helper = apply_filters('wpstg_db_helper', $wpdb, $clone);
|
1244 |
+
$tables = $db_helper->get_results("show table status like '" . $prefix . "_%'");
|
1245 |
+
|
1246 |
+
$path = get_home_path() . $clone;
|
1247 |
+
$folders[$clone] = wpstg_check_removing_files($path);
|
1248 |
+
?>
|
1249 |
+
<h4 class="wpstg-notice-alert">
|
1250 |
+
<?php _e('Attention: Check carefully if this DB tables and files are safe to delete for the staging site','wpstg'); ?>
|
1251 |
+
<span style="background-color:#575757;color:#fff;"><?php echo $clone; ?></span>
|
1252 |
+
<?php _e('Usually the preselected data can be deleted without any risk, but in case something goes wrong you better check it first.','wpstg'); ?>
|
1253 |
+
</h4>
|
1254 |
+
<div class="wpstg-tabs-wrapper">
|
1255 |
+
<a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
|
1256 |
+
<span class="wpstg-tab-triangle">►</span>
|
1257 |
+
<?php echo __('DB tables to remove', 'wpstg');?>
|
1258 |
+
</a>
|
1259 |
+
<div class="wpstg-tab-section" id="wpstg-scanning-db">
|
1260 |
+
<h4 style="margin:0px;">
|
1261 |
+
<?php
|
1262 |
+
_e('Select the tables for removal:', 'wpstg');
|
1263 |
+
wpstg_show_tables($tables);
|
1264 |
+
?>
|
1265 |
+
<h4>
|
1266 |
+
</div> <!-- #wpstg-scanning-db -->
|
1267 |
+
|
1268 |
+
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
1269 |
+
<span class="wpstg-tab-triangle">►</span>
|
1270 |
+
<?php echo __('Files to remove', 'wpstg');?>
|
1271 |
+
</a>
|
1272 |
+
<div class="wpstg-tab-section" id="wpstg-scanning-files">
|
1273 |
+
<h4 style="margin:0px;">
|
1274 |
+
<?php
|
1275 |
+
_e('Select the folders for removal. Click on a folder name to expand it:', 'wpstg');
|
1276 |
+
wpstg_directory_structure($folders, null, false, true);
|
1277 |
+
?>
|
1278 |
+
<h4>
|
1279 |
+
</div> <!-- #wpstg-scanning-files -->
|
1280 |
+
</div>
|
1281 |
+
<a href="#" class="wpstg-link-btn button-primary" id="wpstg-cancel-removing"><?php _e('Cancel', 'wpstg');?></a>
|
1282 |
+
<a href="#" class="wpstg-link-btn button-primary" id="wpstg-remove-clone" data-clone="<?php echo $clone; ?>"><?php echo __('Remove', 'wpstg');?></a>
|
1283 |
+
<?php
|
1284 |
+
wp_die();
|
1285 |
+
}
|
1286 |
+
add_action('wp_ajax_wpstg_preremove', 'wpstg_preremove_clone');
|
1287 |
+
|
1288 |
+
/**
|
1289 |
+
* Check the folders for removing
|
1290 |
+
*
|
1291 |
+
* @param string $path
|
1292 |
+
* @param array $folders
|
1293 |
+
*
|
1294 |
+
* @return array
|
1295 |
+
*/
|
1296 |
+
function wpstg_check_removing_files($path, &$folders = array()) {
|
1297 |
+
if (is_dir($path)) {
|
1298 |
+
$dirsize = 0;
|
1299 |
+
$dir = dir($path);
|
1300 |
+
while (false !== $entry = $dir->read()) {
|
1301 |
+
if ($entry == '.' || $entry == '..')
|
1302 |
+
continue;
|
1303 |
+
if (is_file("$path/$entry")) {
|
1304 |
+
$dirsize += filesize("$path/$entry");
|
1305 |
+
continue;
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
$tmp = wpstg_check_removing_files("$path/$entry", $folders[$entry]);
|
1309 |
+
$dirsize += $tmp['size'];
|
1310 |
+
}
|
1311 |
+
$folders['size'] = $dirsize;
|
1312 |
+
}
|
1313 |
+
return $folders;
|
1314 |
+
}
|
1315 |
+
|
1316 |
+
/**
|
1317 |
+
* Removes current clone
|
1318 |
+
*
|
1319 |
+
* @global object $wpdb
|
1320 |
+
* @global array $wpstg_clone_details
|
1321 |
+
* @param bool $isAjax
|
1322 |
+
*/
|
1323 |
+
function wpstg_remove_clone($isAjax = true) {
|
1324 |
+
global $wpdb, $wpstg_clone_details;
|
1325 |
+
check_ajax_referer( 'wpstg_ajax_nonce', 'nonce' );
|
1326 |
+
$wpstg_clone_details = wpstg_get_options();
|
1327 |
+
|
1328 |
+
$clone = $_POST['cloneID'];
|
1329 |
+
|
1330 |
+
if (empty ($clone) || $clone === '' ) {
|
1331 |
+
WPSTG()->logger->info('cloneID does not exist or is empty');
|
1332 |
+
//wp_die(-1);
|
1333 |
+
wp_die('cloneID does not exist or is empty');
|
1334 |
+
}
|
1335 |
+
|
1336 |
+
//drop clone tables
|
1337 |
+
$db_helper = apply_filters('wpstg_db_helper', $wpdb, $clone);
|
1338 |
+
$tables = $db_helper->get_col( $wpdb->prepare('show tables like %s', $clone . '_%'));
|
1339 |
+
$unchecked_tables = isset($_POST['uncheckedTables']) ? $_POST['uncheckedTables'] : array();
|
1340 |
+
$tables = array_diff($tables, $unchecked_tables);
|
1341 |
+
foreach ($tables as $table) {
|
1342 |
+
if (! wpstg_is_root_table($table, $wpdb->prefix))
|
1343 |
+
$result = $db_helper->query("drop table `$table`");
|
1344 |
+
if (! $result) {
|
1345 |
+
WPSTG()->logger->info('Droping table ' . $table . ' has been failed.');
|
1346 |
+
//wp_die(-1);
|
1347 |
+
wp_die('Droping table ' . $table . ' has been failed.');
|
1348 |
+
}
|
1349 |
+
WPSTG()->logger->info('Droping table ' . $table . ' was successfull');
|
1350 |
+
}
|
1351 |
+
|
1352 |
+
//remove clone folder
|
1353 |
+
$excluded_folders = isset($_POST['excludedFolders']) ? $_POST['excludedFolders'] : array();
|
1354 |
+
$result = wpstgDeleteDirectory(get_home_path() . $clone, $excluded_folders);
|
1355 |
+
if (! $result) {
|
1356 |
+
WPSTG()->logger->info('Removing clone folder '.get_home_path() . $clone.' has been failed.');
|
1357 |
+
wp_die(-1);
|
1358 |
+
}
|
1359 |
+
WPSTG()->logger->info('Clone folder '.get_home_path() . $clone.' has been removed successfully.');
|
1360 |
+
$existing_clones = get_option('wpstg_existing_clones', array());
|
1361 |
+
$key = array_search($clone, $existing_clones);
|
1362 |
+
|
1363 |
+
if ($key !== false && $key !== NULL) {
|
1364 |
+
unset($existing_clones[$key]);
|
1365 |
+
update_option('wpstg_existing_clones', $existing_clones);
|
1366 |
+
}
|
1367 |
+
|
1368 |
+
do_action('wpstg_remove_clone', $clone);
|
1369 |
+
if ($isAjax) {
|
1370 |
+
WPSTG()->logger->info('Clone( ' . $clone . ' ) has been removed successfully.');
|
1371 |
+
wp_die(0);
|
1372 |
+
}
|
1373 |
+
}
|
1374 |
+
add_action('wp_ajax_wpstg_remove_clone', 'wpstg_remove_clone');
|
1375 |
+
|
1376 |
+
|
1377 |
+
|
1378 |
+
/**
|
1379 |
+
* Delete a specific directory
|
1380 |
+
*
|
1381 |
+
* @param array $dir
|
1382 |
+
* @param array $excluded_dirs
|
1383 |
+
* @return boolean
|
1384 |
+
*/
|
1385 |
+
function wpstgDeleteDirectory($dir, $excluded_dirs) {
|
1386 |
+
if (!file_exists($dir))
|
1387 |
+
return true;
|
1388 |
+
|
1389 |
+
if (!is_dir($dir))
|
1390 |
+
return unlink($dir);
|
1391 |
+
|
1392 |
+
foreach (scandir($dir) as $item) {
|
1393 |
+
if ($item == '.' || $item == '..' || in_array("$dir/$item", $excluded_dirs))
|
1394 |
+
continue;
|
1395 |
+
|
1396 |
+
if (!wpstgDeleteDirectory("$dir/$item", $excluded_dirs))
|
1397 |
+
return false;
|
1398 |
+
}
|
1399 |
+
|
1400 |
+
$need_rm = true;
|
1401 |
+
foreach ($excluded_dirs as $ex_dir)
|
1402 |
+
if (strpos($ex_dir, $dir) !== false) {
|
1403 |
+
$need_rm = false;
|
1404 |
+
break;
|
1405 |
+
}
|
1406 |
+
|
1407 |
+
return $need_rm ? rmdir($dir) : true;
|
1408 |
+
}
|
1409 |
+
|
1410 |
+
/** Cancel cloning process
|
1411 |
+
* Remove current clone and purge json files containing task related data
|
1412 |
+
*
|
1413 |
+
* @return void
|
1414 |
+
*/
|
1415 |
+
|
1416 |
+
function wpstg_cancel_cloning() {
|
1417 |
+
wpstg_remove_clone(false);
|
1418 |
+
wpstg_clear_options();
|
1419 |
+
wp_die(0);
|
1420 |
+
}
|
1421 |
+
add_action('wp_ajax_wpstg_cancel_cloning', 'wpstg_cancel_cloning');
|
1422 |
+
|
1423 |
+
|
1424 |
+
/**
|
1425 |
+
* Check if table name starts with prefix which belongs to the wordpress root table
|
1426 |
+
*
|
1427 |
+
* @param string $haystack
|
1428 |
+
* @param string $needle
|
1429 |
+
* @return bool true if table name starts with prefix of the root table
|
1430 |
+
*/
|
1431 |
+
function wpstg_is_root_table($haystack, $needle) {
|
1432 |
+
return strpos($haystack, $needle) === 0;
|
1433 |
+
}
|
1434 |
+
|
1435 |
+
/** Get global clone details options
|
1436 |
+
*
|
1437 |
+
* @return string JSON that includes the cloning relevant data
|
1438 |
+
*/
|
1439 |
+
function wpstg_get_options() {
|
1440 |
+
$path = wpstg_get_upload_dir() . '/clone_details.json';
|
1441 |
+
$content = @file_get_contents($path);
|
1442 |
+
if ($content) {
|
1443 |
+
return json_decode($content, true);
|
1444 |
+
}else{
|
1445 |
+
return json_decode('', true);
|
1446 |
+
}
|
1447 |
+
}
|
1448 |
+
|
1449 |
+
/**
|
1450 |
+
* Save global clone details options
|
1451 |
+
* and create clone_details.json
|
1452 |
+
*
|
1453 |
+
* @return void
|
1454 |
+
*/
|
1455 |
+
function wpstg_save_options() {
|
1456 |
+
global $wpstg_clone_details;
|
1457 |
+
$path = wpstg_get_upload_dir();
|
1458 |
+
|
1459 |
+
if (wp_is_writable($path)) {
|
1460 |
+
$file = 'clone_details.json';
|
1461 |
+
file_put_contents($path . '/' . $file, json_encode($wpstg_clone_details));
|
1462 |
+
}else {
|
1463 |
+
WPSTG()->logger->info($path . '/' . $file . ' is not writeable! ');
|
1464 |
+
}
|
1465 |
+
}
|
1466 |
+
|
1467 |
+
/**
|
1468 |
+
* Write unexpected errors into the log file
|
1469 |
+
*/
|
1470 |
+
function wpstg_error_processing() {
|
1471 |
+
$msg = sanitize_text_field($_POST['wpstg_error_msg']);
|
1472 |
+
if (! empty($msg))
|
1473 |
+
WPSTG()->logger->info($msg);
|
1474 |
+
wp_die();
|
1475 |
+
}
|
1476 |
+
add_action('wp_ajax_wpstg_error_processing', 'wpstg_error_processing');
|
1477 |
+
|
1478 |
+
|
1479 |
+
/**
|
1480 |
+
* Install must-use plugin that disables other plugins when wp staging ajax requests are made.
|
1481 |
+
*
|
1482 |
+
* @return void;
|
1483 |
+
*/
|
1484 |
+
function wpstg_ajax_muplugin_install() {
|
1485 |
+
global $state_data;
|
1486 |
+
|
1487 |
+
$key_rules = array(
|
1488 |
+
'action' => 'key',
|
1489 |
+
'install' => 'numeric',
|
1490 |
+
);
|
1491 |
+
wpstg_set_post_data($key_rules);
|
1492 |
+
|
1493 |
+
$mu_dir = ( defined('WPMU_PLUGIN_DIR') && defined('WPMU_PLUGIN_URL') ) ? WPMU_PLUGIN_DIR : trailingslashit(WP_CONTENT_DIR) . 'mu-plugins';
|
1494 |
+
$source = trailingslashit(WPSTG_PLUGIN_DIR) . 'optimizer/wp-staging-optimizer.php';
|
1495 |
+
$dest = trailingslashit($mu_dir) . 'wp-staging-optimizer.php';
|
1496 |
+
|
1497 |
+
if ('1' === trim($state_data['install'])) { // install MU plugin
|
1498 |
+
if (!wp_mkdir_p($mu_dir)) {
|
1499 |
+
printf(esc_html__('The following directory could not be created: %s', 'wpstg'), $mu_dir);
|
1500 |
+
exit;
|
1501 |
+
}
|
1502 |
+
|
1503 |
+
if (!copy($source, $dest)) {
|
1504 |
+
printf(esc_html__('Could not copy the compatibility plugin from %1$s to %2$s', 'wpstg'), $source, $dest);
|
1505 |
+
exit;
|
1506 |
+
}
|
1507 |
+
} else { // uninstall MU plugin
|
1508 |
+
// TODO: Use WP_Filesystem API.
|
1509 |
+
if (file_exists($dest) && !unlink($dest)) {
|
1510 |
+
printf(esc_html__('Could not remove the compatibility plugin from %s', 'wpstg'), $dest);
|
1511 |
+
exit;
|
1512 |
+
}
|
1513 |
+
}
|
1514 |
+
exit;
|
1515 |
+
}
|
1516 |
+
|
1517 |
+
add_action('wp_ajax_wpstg_muplugin_install', 'wpstg_ajax_muplugin_install');
|
1518 |
+
|
1519 |
+
/**
|
1520 |
+
* Handler for saving the options and for updating
|
1521 |
+
* the plugins that are not loaded during a request (Optimizing Mode).
|
1522 |
+
*/
|
1523 |
+
function wpstg_ajax_disable_plugins() {
|
1524 |
+
global $state_data, $wpstg_options;
|
1525 |
+
|
1526 |
+
$key_rules = array(
|
1527 |
+
'action' => 'key',
|
1528 |
+
'blacklist_plugins' => 'array',
|
1529 |
+
'batch_size' => 'int',
|
1530 |
+
'query_limit' => 'int',
|
1531 |
+
'disable_admin_login' => 'int',
|
1532 |
+
'uninstall_on_delete' => 'int'
|
1533 |
+
|
1534 |
+
);
|
1535 |
+
|
1536 |
+
wpstg_set_post_data($key_rules);
|
1537 |
+
|
1538 |
+
$wpstg_options['blacklist_plugins'] = (array) $state_data['blacklist_plugins'];
|
1539 |
+
$wpstg_options['wpstg_batch_size'] = (int) $state_data['batch_size'];
|
1540 |
+
$wpstg_options['wpstg_query_limit'] = (int) $state_data['query_limit'];
|
1541 |
+
$wpstg_options['disable_admin_login'] = (int) $state_data['disable_admin_login'];
|
1542 |
+
$wpstg_options['uninstall_on_delete'] = (int) $state_data['uninstall_on_delete'];
|
1543 |
+
|
1544 |
+
update_option('wpstg_settings', $wpstg_options);
|
1545 |
+
exit;
|
1546 |
+
}
|
1547 |
+
add_action('wp_ajax_wpstg_disable_plugins', 'wpstg_ajax_disable_plugins');
|
1548 |
+
|
1549 |
+
/**
|
1550 |
+
* Sets $state_data from $_POST, potentially un-slashed and sanitized.
|
1551 |
+
*
|
1552 |
+
* @param array $key_rules An optional associative array of expected keys and their sanitization rule(s).
|
1553 |
+
* @param string $context The method that is specifying the sanitization rules. Defaults to calling method.
|
1554 |
+
*/
|
1555 |
+
function wpstg_set_post_data($key_rules = array(), $context = '') {
|
1556 |
+
global $state_data;
|
1557 |
+
|
1558 |
+
if (is_null($state_data)) {
|
1559 |
+
$state_data = wp_unslash($_POST);
|
1560 |
+
} else {
|
1561 |
+
return;
|
1562 |
+
}
|
1563 |
+
|
1564 |
+
// Sanitize the new state data.
|
1565 |
+
if (!empty($key_rules)) {
|
1566 |
+
$context = empty($context) ? wpstg_get_caller_function() : trim($context);
|
1567 |
+
$state_data = WPSTG_Sanitize::sanitize_data($state_data, $key_rules, $context);
|
1568 |
+
|
1569 |
+
if (false === $state_data) {
|
1570 |
+
exit;
|
1571 |
+
}
|
1572 |
+
}
|
1573 |
+
}
|
1574 |
+
|
1575 |
+
/**
|
1576 |
+
* Returns the function name that called the function using this function.
|
1577 |
+
*
|
1578 |
+
* @return string function name
|
1579 |
+
*/
|
1580 |
+
function wpstg_get_caller_function() {
|
1581 |
+
list(,, $caller ) = debug_backtrace(false);
|
1582 |
+
|
1583 |
+
if (!empty($caller['function'])) {
|
1584 |
+
$caller = $caller['function'];
|
1585 |
+
} else {
|
1586 |
+
$caller = '';
|
1587 |
+
}
|
1588 |
+
|
1589 |
+
return $caller;
|
1590 |
+
}
|
1591 |
+
|
1592 |
+
/**
|
1593 |
+
*
|
1594 |
+
*
|
1595 |
+
*
|
1596 |
+
* @param string $function php function name
|
1597 |
+
* @param string $status | success | fail
|
1598 |
+
* @param string $message error message or successfull notice
|
1599 |
+
* @param integer step
|
1600 |
+
*
|
1601 |
+
* @result json
|
1602 |
+
*/
|
1603 |
+
function wpstg_return_json($name, $status, $message, $percent, $running_time){
|
1604 |
+
$result = array(
|
1605 |
+
'name' => $name,
|
1606 |
+
'status' => $status,
|
1607 |
+
'message' => $message,
|
1608 |
+
'percent' => $percent,
|
1609 |
+
'running_time' => $running_time
|
1610 |
+
);
|
1611 |
+
wp_send_json( $result );
|
1612 |
+
}
|
1613 |
+
|
1614 |
+
/**
|
1615 |
+
* Get runtime
|
1616 |
+
*
|
1617 |
+
* @global type $start_time
|
1618 |
+
* @return integer
|
1619 |
+
*/
|
1620 |
+
function wpstg_get_runtime(){
|
1621 |
+
global $start_time;
|
1622 |
+
$now_time = microtime(true);
|
1623 |
+
$now = $now_time - $start_time;
|
1624 |
+
return $now;
|
1625 |
+
}
|
1626 |
+
|
1627 |
+
/**
|
1628 |
+
* Get header of working log
|
1629 |
+
*
|
1630 |
+
* @param integer $progress percent of progress
|
1631 |
+
* @param string $message define optional logging message
|
1632 |
+
* @return string
|
1633 |
+
*/
|
1634 |
+
function wpstg_get_log_data($progress){
|
1635 |
+
if ($progress === 0) {
|
1636 |
+
return $log_data_header = '###########################################<br>'
|
1637 |
+
. ' WP Staging working log <br>'
|
1638 |
+
. ' You find all log files in: <br>'
|
1639 |
+
. ' wp-content/plugins/wp-staging/logs <br>'
|
1640 |
+
. '###########################################<br>';
|
1641 |
+
} else {
|
1642 |
+
return '';
|
1643 |
+
}
|
1644 |
+
}
|
1645 |
+
|
1646 |
+
/*
|
1647 |
+
* This checks if a job has been started previously
|
1648 |
+
*
|
1649 |
+
* @return bool
|
1650 |
+
*/
|
1651 |
+
function wpstg_check_job_exists(){
|
1652 |
+
global $wpstg_clone_details;
|
1653 |
+
if ( isset($wpstg_clone_details['db_progress']) ) {
|
1654 |
+
return true;
|
1655 |
+
}
|
1656 |
+
}
|
1657 |
+
|
1658 |
+
/**
|
1659 |
+
* Return the button title depending if the
|
1660 |
+
*
|
1661 |
+
* @return string
|
1662 |
+
*/
|
1663 |
+
function wpstg_return_button_title(){
|
1664 |
+
If ( !wpstg_check_job_exists() ) {
|
1665 |
+
return __('Start Cloning', 'wpstg');
|
1666 |
+
} else {
|
1667 |
+
return __('Resume Cloning', 'wpstg');
|
1668 |
+
}
|
1669 |
+
}
|
1670 |
+
/**
|
1671 |
+
* Check if there is enough disk space left for cloning site
|
1672 |
+
*
|
1673 |
+
* @return string
|
1674 |
+
*/
|
1675 |
+
/*function wpstg_check_diskspace_($clone_size){
|
1676 |
+
$free_space = function_exists('disk_free_space') ? disk_free_space(get_home_path()) : 'undefined';
|
1677 |
+
$overflow = $free_space < $clone_size ? true : false;
|
1678 |
+
|
1679 |
+
if (function_exists('disk_free_space') ) {
|
1680 |
+
return $overflow ? __('Probably not enough free disk space to create a staging site. You can continue but its likely that the copying process will fail.', 'wpstg') : '';
|
1681 |
+
}
|
1682 |
+
//return __('Can not check if there is enough disk space left for the staging website. This is not really a bad thing so you can still continue.', 'wpstg');
|
1683 |
+
}*/
|
1684 |
+
|
1685 |
+
function wpstg_check_diskspace($clone_size) {
|
1686 |
+
if ( !function_exists('disk_free_space') )
|
1687 |
+
return '';
|
1688 |
+
|
1689 |
+
$overflow = @disk_free_space(get_home_path());
|
1690 |
+
if ( $overflow == false)
|
1691 |
+
return '';
|
1692 |
+
|
1693 |
+
$overflow = $overflow < $clone_size ? true : false;
|
1694 |
+
return $overflow ? '<br>' . __('Probably not enough free disk space to create a staging site. <br> You can continue but its likely that the copying process will fail.', 'wpstg') : '';
|
1695 |
+
}
|
1696 |
+
|
1697 |
+
/**
|
1698 |
+
* Write extended debug messsages into logfiles
|
1699 |
+
*
|
1700 |
+
* @param string $error
|
1701 |
+
*/
|
1702 |
+
function wpstg_debug_log($error){
|
1703 |
+
global $wpstg_options;
|
1704 |
+
|
1705 |
+
if ( isset($wpstg_options['debug_mode']) )
|
1706 |
+
WPSTG()->logger->info($error);
|
1707 |
+
}
|
1708 |
+
|
1709 |
+
/**
|
1710 |
+
* Get URL of staging site
|
1711 |
+
*
|
1712 |
+
* @global type $wpstg_clone_details
|
1713 |
+
* @return mixed bool | string false when there is not staging url defined
|
1714 |
+
*/
|
1715 |
+
function wpstg_get_staging_url(){
|
1716 |
+
global $wpstg_clone_details;
|
1717 |
+
|
1718 |
+
if ( !empty($wpstg_clone_details['current_clone']))
|
1719 |
+
return get_home_url() . '/' . $wpstg_clone_details['current_clone'];
|
1720 |
+
|
1721 |
+
return false;
|
1722 |
+
}
|
includes/wpstg-sanitize.php
ADDED
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WPSTG_Sanitize {
|
4 |
+
/**
|
5 |
+
* Sanitize and validate data.
|
6 |
+
*
|
7 |
+
* @param string|array $data The data to the sanitized.
|
8 |
+
* @param string|array $key_rules The keys in the data (if data is an array) and the sanitization rule(s) to apply for each key.
|
9 |
+
* @param string $context Additional context data for messages etc.
|
10 |
+
*
|
11 |
+
* @return mixed The sanitized data, the data if no key rules supplied or `false` if an unrecognized rule supplied.
|
12 |
+
*/
|
13 |
+
static function sanitize_data( $data, $key_rules, $context ) {
|
14 |
+
if ( empty( $data ) || empty( $key_rules ) ) {
|
15 |
+
return $data;
|
16 |
+
}
|
17 |
+
|
18 |
+
return WPSTG_Sanitize::_sanitize_data( $data, $key_rules, $context );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Sanitize and validate data.
|
23 |
+
*
|
24 |
+
* @param string|array $data The data to the sanitized.
|
25 |
+
* @param string|array $key_rules The keys in the data (if data is an array) and the sanitization rule(s) to apply for each key.
|
26 |
+
* @param string $context Additional context data for messages etc.
|
27 |
+
* @param int $recursion_level How deep in the recursion are we? Optional, defaults to 0.
|
28 |
+
*
|
29 |
+
* @return mixed The sanitized data, the data if no key rules supplied or `false` if an unrecognized rule supplied.
|
30 |
+
*/
|
31 |
+
private static function _sanitize_data( $data, $key_rules, $context, $recursion_level = 0 ) {
|
32 |
+
if ( empty( $data ) || empty( $key_rules ) ) {
|
33 |
+
return $data;
|
34 |
+
}
|
35 |
+
|
36 |
+
if ( 0 === $recursion_level && is_array( $data ) ) {
|
37 |
+
// We always expect associative arrays.
|
38 |
+
if ( ! is_array( $key_rules ) ) {
|
39 |
+
wp_die( sprintf( __( '%1$s was not expecting data to be an array.', 'wpstg' ), $context ) );
|
40 |
+
|
41 |
+
return false;
|
42 |
+
}
|
43 |
+
foreach ( $data as $key => $value ) {
|
44 |
+
// If a key does not have a rule it's not ours and can be removed.
|
45 |
+
// We should not fail if there is extra data as plugins like Polylang add their own data to each ajax request.
|
46 |
+
if ( ! array_key_exists( $key, $key_rules ) ) {
|
47 |
+
unset( $data[ $key ] );
|
48 |
+
continue;
|
49 |
+
}
|
50 |
+
$data[ $key ] = WPSTG_Sanitize::_sanitize_data( $value, $key_rules[ $key ], $context, ( $recursion_level + 1 ) );
|
51 |
+
}
|
52 |
+
} elseif ( is_array( $key_rules ) ) {
|
53 |
+
foreach ( $key_rules as $rule ) {
|
54 |
+
$data = WPSTG_Sanitize::_sanitize_data( $data, $rule, $context, ( $recursion_level + 1 ) );
|
55 |
+
}
|
56 |
+
} else {
|
57 |
+
// Neither $data or $key_rules are a first level array so can be analysed.
|
58 |
+
if ( 'array' == $key_rules ) {
|
59 |
+
if ( ! is_array( $data ) ) {
|
60 |
+
wp_die( sprintf( __( '%1$s was expecting an array but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
61 |
+
|
62 |
+
return false;
|
63 |
+
}
|
64 |
+
} elseif ( 'string' == $key_rules ) {
|
65 |
+
if ( ! is_string( $data ) ) {
|
66 |
+
wp_die( sprintf( __( '%1$s was expecting a string but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
67 |
+
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
} elseif ( 'key' == $key_rules ) {
|
71 |
+
$key_name = sanitize_key( $data );
|
72 |
+
if ( $key_name !== $data ) {
|
73 |
+
wp_die( sprintf( __( '%1$s was expecting a valid key but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
74 |
+
|
75 |
+
return false;
|
76 |
+
}
|
77 |
+
$data = $key_name;
|
78 |
+
} elseif ( 'text' == $key_rules ) {
|
79 |
+
$text = sanitize_text_field( $data );
|
80 |
+
if ( $text !== $data ) {
|
81 |
+
wp_die( sprintf( __( '%1$s was expecting text but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
82 |
+
|
83 |
+
return false;
|
84 |
+
}
|
85 |
+
$data = $text;
|
86 |
+
} elseif ( 'serialized' == $key_rules ) {
|
87 |
+
if ( ! is_string( $data ) || ! is_serialized( $data ) ) {
|
88 |
+
wp_die( sprintf( __( '%1$s was expecting serialized data but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
89 |
+
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
} elseif ( 'numeric' == $key_rules ) {
|
93 |
+
if ( ! is_numeric( $data ) ) {
|
94 |
+
wp_die( sprintf( __( '%1$s was expecting a valid numeric but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
95 |
+
|
96 |
+
return false;
|
97 |
+
}
|
98 |
+
} elseif ( 'int' == $key_rules ) {
|
99 |
+
// As we are sanitizing form data, even integers are within a string.
|
100 |
+
if ( ! is_numeric( $data ) || (int) $data != $data ) {
|
101 |
+
wp_die( sprintf( __( '%1$s was expecting an integer but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
102 |
+
|
103 |
+
return false;
|
104 |
+
}
|
105 |
+
$data = (int) $data;
|
106 |
+
} elseif ( 'positive_int' == $key_rules ) {
|
107 |
+
if ( ! is_numeric( $data ) || (int) $data != $data || 0 > $data ) {
|
108 |
+
wp_die( sprintf( __( '%1$s was expecting a positive number (int) but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
109 |
+
|
110 |
+
return false;
|
111 |
+
}
|
112 |
+
$data = floor( $data );
|
113 |
+
} elseif ( 'negative_int' == $key_rules ) {
|
114 |
+
if ( ! is_numeric( $data ) || (int) $data != $data || 0 < $data ) {
|
115 |
+
wp_die( sprintf( __( '%1$s was expecting a negative number (int) but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
116 |
+
|
117 |
+
return false;
|
118 |
+
}
|
119 |
+
$data = ceil( $data );
|
120 |
+
} elseif ( 'zero_int' == $key_rules ) {
|
121 |
+
if ( ! is_numeric( $data ) || (int) $data != $data || 0 !== $data ) {
|
122 |
+
wp_die( sprintf( __( '%1$s was expecting 0 (int) but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
123 |
+
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
$data = 0;
|
127 |
+
} elseif ( 'empty' == $key_rules ) {
|
128 |
+
if ( ! empty( $data ) ) {
|
129 |
+
wp_die( sprintf( __( '%1$s was expecting an empty value but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
130 |
+
|
131 |
+
return false;
|
132 |
+
}
|
133 |
+
} elseif ( 'url' == $key_rules ) {
|
134 |
+
$url = esc_url_raw( $data );
|
135 |
+
if ( empty( $url ) ) {
|
136 |
+
wp_die( sprintf( __( '%1$s was expecting a URL but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
137 |
+
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
$data = $url;
|
141 |
+
} elseif ( 'bool' == $key_rules ) {
|
142 |
+
$bool = sanitize_key( $data );
|
143 |
+
if ( empty( $bool ) || ! in_array( $bool, array( 'true', 'false' ) ) ) {
|
144 |
+
wp_die( sprintf( __( '%1$s was expecting a bool but got something else: "%2$s"', 'wpstg' ), $context, $data ) );
|
145 |
+
|
146 |
+
return false;
|
147 |
+
}
|
148 |
+
$data = $bool;
|
149 |
+
} else {
|
150 |
+
wp_die( sprintf( __( 'Unknown sanitization rule "%1$s" supplied by %2$s', 'wpstg' ), $key_rules, $context ) );
|
151 |
+
|
152 |
+
return false;
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
return $data;
|
157 |
+
}
|
158 |
+
}
|
languages/Gruntfile.js
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* local path for wp-staging git repository
|
2 |
+
cd "s:\github\wp-staging"
|
3 |
+
*
|
4 |
+
*/
|
5 |
+
module.exports = function(grunt) {
|
6 |
+
|
7 |
+
// Project configuration.
|
8 |
+
grunt.initConfig({
|
9 |
+
|
10 |
+
pkg: grunt.file.readJSON( 'package.json' ),
|
11 |
+
paths : {
|
12 |
+
// Base destination dir
|
13 |
+
base : '../../wordpress-svn/staging/tags/<%= pkg.version %>',
|
14 |
+
basetrunk : '../../wordpress-svn/staging/svn/trunk/',
|
15 |
+
basezip: '../../wordpress-svn/staging/'
|
16 |
+
},
|
17 |
+
|
18 |
+
// Tasks here
|
19 |
+
// Bump version numbers
|
20 |
+
version: {
|
21 |
+
css: {
|
22 |
+
options: {
|
23 |
+
prefix: 'Version\\:\\s'
|
24 |
+
},
|
25 |
+
src: [ 'style.css' ]
|
26 |
+
},
|
27 |
+
php: {
|
28 |
+
options: {
|
29 |
+
prefix: '\@version\\s+'
|
30 |
+
},
|
31 |
+
src: [ 'functions.php', '<%= pkg.name %>.php' ]
|
32 |
+
}
|
33 |
+
},
|
34 |
+
// minify js
|
35 |
+
uglify: {
|
36 |
+
build: {
|
37 |
+
files:[
|
38 |
+
{'assets/js/wpstg-admin.min.js' : 'assets/js/wpstg-admin.js'},
|
39 |
+
{'assets/js/wpstg.min.js' : 'assets/js/wpstg.js'},
|
40 |
+
]
|
41 |
+
}
|
42 |
+
},
|
43 |
+
// Copy to build folder
|
44 |
+
copy: {
|
45 |
+
build: {
|
46 |
+
files: [
|
47 |
+
{expand: true, src: ['**', '!node_modules/**', '!Gruntfile.js', '!package.json', '!nbproject/**', '!grunt/**'],
|
48 |
+
dest: '<%= paths.base %>'},
|
49 |
+
|
50 |
+
{expand: true, src: ['**', '!node_modules/**', '!Gruntfile.js', '!package.json', '!nbproject/**', '!grunt/**'],
|
51 |
+
dest: '<%= paths.basetrunk %>'},
|
52 |
+
]
|
53 |
+
},
|
54 |
+
},
|
55 |
+
|
56 |
+
// Clean the build folder
|
57 |
+
clean: {
|
58 |
+
options: {
|
59 |
+
force: true
|
60 |
+
},
|
61 |
+
build: {
|
62 |
+
files:[
|
63 |
+
{src: ['<%= paths.base %>']},
|
64 |
+
{src: ['<%= paths.basetrunk %>']},
|
65 |
+
]
|
66 |
+
|
67 |
+
}
|
68 |
+
},
|
69 |
+
// Minify CSS files into NAME-OF-FILE.min.css
|
70 |
+
cssmin: {
|
71 |
+
build: {
|
72 |
+
files:[
|
73 |
+
{'assets/css/wpstg-admin.min.css' : 'assets/css/wpstg-admin.css'},
|
74 |
+
{'templates/wpstg.min.css' : 'templates/wpstg.min.css'},
|
75 |
+
]
|
76 |
+
}
|
77 |
+
},
|
78 |
+
// Compress the build folder into an upload-ready zip file
|
79 |
+
compress: {
|
80 |
+
build: {
|
81 |
+
options: {
|
82 |
+
archive: '<%= paths.basezip %>/<%= pkg.name %>.zip'
|
83 |
+
},
|
84 |
+
cwd: '<%= paths.base %>',
|
85 |
+
src: ['**/*']
|
86 |
+
//dest: '../../',
|
87 |
+
//expand: true
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
});
|
93 |
+
|
94 |
+
// Load all grunt plugins here
|
95 |
+
// [...]
|
96 |
+
//require('load-grunt-config')(grunt);
|
97 |
+
require('load-grunt-tasks')(grunt);
|
98 |
+
|
99 |
+
// Display task timing
|
100 |
+
require('time-grunt')(grunt);
|
101 |
+
|
102 |
+
// Build task
|
103 |
+
//grunt.registerTask( 'build', [ 'compress:build' ]);
|
104 |
+
grunt.registerTask( 'build', [ 'clean:build', 'uglify:build', 'cssmin:build', 'copy:build', 'compress:build' ]);
|
105 |
+
};
|
languages/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Staging I18n #
|
2 |
+
|
3 |
+
To help translate, review, or improve a translation, write Rene Hermenau at info@wp-staging.net
|
4 |
+
|
5 |
+
More info at https://www.wp-staging.net/
|
6 |
+
|
7 |
+
# Quick Start #
|
8 |
+
|
9 |
+
In staging/languages/ you find a file named wpstg.po
|
10 |
+
|
11 |
+
- Open it with the free editor: http://poedit.net/
|
12 |
+
|
13 |
+
- Translate the strings and save it. Poedit automatically creates the file wpstg.mo
|
14 |
+
|
15 |
+
- Rename this to your language specific translation. E.g. for italy the file is called wpstg-it_IT.mo and put it into the folder /wp-content/languages/staging/
|
16 |
+
|
17 |
+
If you like to send us new mo files we will put it into this plugin package.
|
18 |
+
|
languages/index.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Do not put custom translations here. They will be deleted on Staging updates.
|
4 |
+
*
|
5 |
+
* Keep custom WPSTG translations in /wp-content/languages/wpstg/
|
6 |
+
*/
|
languages/readme.txt
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
********************************************************
|
2 |
+
|
3 |
+
Staging I18n
|
4 |
+
============================
|
5 |
+
|
6 |
+
Do not put custom translations here. They will be deleted
|
7 |
+
on Staging updates.
|
8 |
+
|
9 |
+
Keep custom WPSTG translations in /wp-content/languages/staging/
|
10 |
+
|
11 |
+
You want to translate, help, or improve a translation?
|
12 |
+
Write: info@wp-staging.net
|
13 |
+
|
14 |
+
More info at https://www.wp-staging.net/
|
15 |
+
|
16 |
+
********************************************************
|
languages/wpstg-en_EN.mo
ADDED
Binary file
|
languages/wpstg-en_EN.po
ADDED
@@ -0,0 +1,648 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2015 WP Staging - Create a staging clone site for testing & developing
|
2 |
+
# This file is distributed under the same license as the WP Staging - Create a staging clone site for testing & developing package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: WP Staging - Create a staging clone site for testing & "
|
6 |
+
"developing 0.9.0\n"
|
7 |
+
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-staging\n"
|
8 |
+
"POT-Creation-Date: 2015-08-05 09:53:10+00:00\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"PO-Revision-Date: 2015-08-05 11:55+0100\n"
|
13 |
+
"Last-Translator: Rene Hermenau <support@wp-staging.com>\n"
|
14 |
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
+
"X-Generator: Poedit 1.5.6\n"
|
16 |
+
|
17 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:181
|
18 |
+
msgid ""
|
19 |
+
"There is a new version of %1$s available. <a target=\"_blank\" class="
|
20 |
+
"\"thickbox\" href=\"%2$s\">View version %3$s details</a>."
|
21 |
+
msgstr ""
|
22 |
+
|
23 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:188
|
24 |
+
msgid ""
|
25 |
+
"There is a new version of %1$s available. <a target=\"_blank\" class="
|
26 |
+
"\"thickbox\" href=\"%2$s\">View version %3$s details</a> or <a href=\"%4$s"
|
27 |
+
"\">update now</a>."
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:346
|
31 |
+
msgid "You do not have permission to install plugin updates"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:346
|
35 |
+
#: includes/class-wpstg-license-handler.php:184
|
36 |
+
#: includes/class-wpstg-license-handler.php:257
|
37 |
+
msgid "Error"
|
38 |
+
msgstr ""
|
39 |
+
|
40 |
+
#: includes/admin/add-ons.php:27
|
41 |
+
msgid "Add Ons for WP-Staging"
|
42 |
+
msgstr ""
|
43 |
+
|
44 |
+
#: includes/admin/add-ons.php:28
|
45 |
+
msgid "Visit Website"
|
46 |
+
msgstr ""
|
47 |
+
|
48 |
+
#: includes/admin/add-ons.php:28
|
49 |
+
msgid "See Details"
|
50 |
+
msgstr ""
|
51 |
+
|
52 |
+
#: includes/admin/add-ons.php:30
|
53 |
+
msgid "These add-ons extend the functionality of WP-Staging."
|
54 |
+
msgstr ""
|
55 |
+
|
56 |
+
#: includes/admin/add-ons.php:54
|
57 |
+
msgid ""
|
58 |
+
"There was an error retrieving the WP-Staging addon list from the server. "
|
59 |
+
"Please try again later."
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: includes/admin/admin-footer.php:32
|
63 |
+
msgid ""
|
64 |
+
"Please <a href=\"%1$s\" target=\"_blank\">rate WP Staging</a> and help to "
|
65 |
+
"support this project.<br>Something not working as expected? Visit the WP "
|
66 |
+
"Staging <a href=\"https://wordpress.org/support/plugin/wp-staging\" target="
|
67 |
+
"\"blank\">Support Forum</a>"
|
68 |
+
msgstr ""
|
69 |
+
|
70 |
+
#: includes/admin/admin-notices.php:44
|
71 |
+
msgid ""
|
72 |
+
"You are using an outdated version of WP Staging which has not been tested "
|
73 |
+
"with your WordPress version %2$s.<br> \r\n"
|
74 |
+
" As WP Staging is using crucial db and file functions it's "
|
75 |
+
"important that you are using a WP Staging version<br> \r\n"
|
76 |
+
" which has been verified to be working with your WordPress "
|
77 |
+
"version. You risk unexpected results up to data lose if you do not so.\r\n"
|
78 |
+
" <p>Please look at <a href=\"%1$s\" target=\"_blank\">%s</a> for "
|
79 |
+
"the latest WP Staging version."
|
80 |
+
msgstr ""
|
81 |
+
|
82 |
+
#: includes/admin/admin-notices.php:135
|
83 |
+
msgid ""
|
84 |
+
"There seems to be an issue with the server. Please try again in a few "
|
85 |
+
"minutes."
|
86 |
+
msgstr ""
|
87 |
+
|
88 |
+
#: includes/admin/admin-pages.php:27
|
89 |
+
msgid "WP Staging"
|
90 |
+
msgstr ""
|
91 |
+
|
92 |
+
#: includes/admin/admin-pages.php:28
|
93 |
+
msgid "WP Staging Jobs"
|
94 |
+
msgstr ""
|
95 |
+
|
96 |
+
#: includes/admin/admin-pages.php:28
|
97 |
+
msgid "Start"
|
98 |
+
msgstr ""
|
99 |
+
|
100 |
+
#: includes/admin/admin-pages.php:29
|
101 |
+
msgid "WP Staging Settings"
|
102 |
+
msgstr ""
|
103 |
+
|
104 |
+
#: includes/admin/admin-pages.php:29
|
105 |
+
msgid "Settings"
|
106 |
+
msgstr ""
|
107 |
+
|
108 |
+
#: includes/admin/admin-pages.php:30
|
109 |
+
msgid "WP Staging Tools"
|
110 |
+
msgstr ""
|
111 |
+
|
112 |
+
#: includes/admin/admin-pages.php:30
|
113 |
+
msgid "Tools"
|
114 |
+
msgstr ""
|
115 |
+
|
116 |
+
#: includes/admin/plugins.php:27
|
117 |
+
msgid "General Settings"
|
118 |
+
msgstr ""
|
119 |
+
|
120 |
+
#: includes/admin/plugins.php:55
|
121 |
+
msgid "Getting Started"
|
122 |
+
msgstr ""
|
123 |
+
|
124 |
+
#: includes/admin/settings/contextual-help.php:29
|
125 |
+
msgid "For more information:"
|
126 |
+
msgstr ""
|
127 |
+
|
128 |
+
#: includes/admin/settings/contextual-help.php:30
|
129 |
+
msgid "Visit the <a href=\"%s\">documentation</a> on the WP-Staging website."
|
130 |
+
msgstr ""
|
131 |
+
|
132 |
+
#: includes/admin/settings/contextual-help.php:32
|
133 |
+
msgid ""
|
134 |
+
"<a href=\"%s\">Post an issue</a> on <a href=\"%s\">WP-Staging</a>. View <a "
|
135 |
+
"href=\"%s\">extensions</a>."
|
136 |
+
msgstr ""
|
137 |
+
|
138 |
+
#: includes/admin/settings/contextual-help.php:41
|
139 |
+
#: includes/admin/settings/register-settings.php:126
|
140 |
+
#: includes/admin/settings/register-settings.php:301
|
141 |
+
msgid "General"
|
142 |
+
msgstr ""
|
143 |
+
|
144 |
+
#: includes/admin/settings/contextual-help.php:42
|
145 |
+
msgid ""
|
146 |
+
"This screen provides the most basic settings for configuring WP-Staging."
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: includes/admin/settings/display-settings.php:135
|
150 |
+
#: includes/template-functions.php:40
|
151 |
+
msgid "Thank you for using WP Staging"
|
152 |
+
msgstr ""
|
153 |
+
|
154 |
+
#: includes/admin/settings/display-settings.php:137
|
155 |
+
#: includes/template-functions.php:42
|
156 |
+
msgid "WP Staging is ready to create a staging site!"
|
157 |
+
msgstr ""
|
158 |
+
|
159 |
+
#: includes/admin/settings/register-settings.php:133
|
160 |
+
msgid "DB Copy Query Limit"
|
161 |
+
msgstr ""
|
162 |
+
|
163 |
+
#: includes/admin/settings/register-settings.php:134
|
164 |
+
msgid ""
|
165 |
+
"Number of DB rows, that will be copied within one ajax request. The higher "
|
166 |
+
"the value the faster the database copy process. To find out the highest "
|
167 |
+
"possible values try a high value like 1.000 or more and decrease it until "
|
168 |
+
"you get no more errors during copy process. <strong> Default: 100 </strong>"
|
169 |
+
msgstr ""
|
170 |
+
|
171 |
+
#: includes/admin/settings/register-settings.php:141
|
172 |
+
msgid "File Copy Batch Size"
|
173 |
+
msgstr ""
|
174 |
+
|
175 |
+
#: includes/admin/settings/register-settings.php:142
|
176 |
+
msgid ""
|
177 |
+
"Buffer size for the file copy process in megabyte. The higher the value the "
|
178 |
+
"faster large files will be copied. To find out the highest possible values "
|
179 |
+
"try a high one and lower it until you get no errors during file copy "
|
180 |
+
"process. Usually this value correlates directly with the memory consumption "
|
181 |
+
"of php so make sure that it does not exceed any php.ini max_memory limits. "
|
182 |
+
"<strong>Default:</strong> 2 "
|
183 |
+
msgstr ""
|
184 |
+
|
185 |
+
#: includes/admin/settings/register-settings.php:149
|
186 |
+
msgid "Optimizer"
|
187 |
+
msgstr ""
|
188 |
+
|
189 |
+
#: includes/admin/settings/register-settings.php:150
|
190 |
+
msgid ""
|
191 |
+
"Select the plugins that should be disabled during build process of the "
|
192 |
+
"staging site. Some plugins slow down the copy process and add overhead to "
|
193 |
+
"each request, requiring extra CPU and memory consumption. Some of them can "
|
194 |
+
"interfere with cloning process and cause them to fail, so we recommend to "
|
195 |
+
"disable all plugins that are not directly related to WP Staging."
|
196 |
+
msgstr ""
|
197 |
+
|
198 |
+
#: includes/admin/settings/register-settings.php:157
|
199 |
+
msgid "Don´t force admin login"
|
200 |
+
msgstr ""
|
201 |
+
|
202 |
+
#: includes/admin/settings/register-settings.php:158
|
203 |
+
msgid ""
|
204 |
+
"Use this option only if you are using a custom login page and not the "
|
205 |
+
"default login.php. If you enable this option you are allowing everyone "
|
206 |
+
"including searchengines to see your staging site, so you have to create a "
|
207 |
+
"custom authentication like using .htaccess"
|
208 |
+
msgstr ""
|
209 |
+
|
210 |
+
#: includes/admin/settings/register-settings.php:170
|
211 |
+
msgid "Remove Data on Uninstall?"
|
212 |
+
msgstr ""
|
213 |
+
|
214 |
+
#: includes/admin/settings/register-settings.php:171
|
215 |
+
msgid ""
|
216 |
+
"Check this box if you like WP Staging to completely remove all of its data "
|
217 |
+
"when the plugin is deleted."
|
218 |
+
msgstr ""
|
219 |
+
|
220 |
+
#: includes/admin/settings/register-settings.php:186
|
221 |
+
msgid "Activate your Add-Ons"
|
222 |
+
msgstr ""
|
223 |
+
|
224 |
+
#: includes/admin/settings/register-settings.php:271
|
225 |
+
msgid "Settings updated."
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#: includes/admin/settings/register-settings.php:304
|
229 |
+
msgid "Misc"
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: includes/admin/settings/register-settings.php:312
|
233 |
+
msgid "Extensions"
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#: includes/admin/settings/register-settings.php:527
|
237 |
+
msgid ""
|
238 |
+
"The callback function used for the <strong>%s</strong> setting is missing."
|
239 |
+
msgstr ""
|
240 |
+
|
241 |
+
#: includes/admin/settings/register-settings.php:639
|
242 |
+
msgid "Upload File"
|
243 |
+
msgstr ""
|
244 |
+
|
245 |
+
#: includes/admin/settings/register-settings.php:667
|
246 |
+
msgid "Deactivate License"
|
247 |
+
msgstr ""
|
248 |
+
|
249 |
+
#: includes/admin/settings/register-settings.php:714
|
250 |
+
msgid "Select Image"
|
251 |
+
msgstr ""
|
252 |
+
|
253 |
+
#: includes/admin/settings/register-settings.php:761
|
254 |
+
msgid ""
|
255 |
+
"Log file directory not writable! Set FTP permission to 755 or 777 for /wp-"
|
256 |
+
"content/plugins/wp-staging/logs/"
|
257 |
+
msgstr ""
|
258 |
+
|
259 |
+
#: includes/admin/settings/register-settings.php:775
|
260 |
+
msgid ""
|
261 |
+
"Improve performance and reliability by not loading the following plugins for "
|
262 |
+
"migration requests"
|
263 |
+
msgstr ""
|
264 |
+
|
265 |
+
#: includes/admin/settings/register-settings.php:780
|
266 |
+
msgid "Select the plugins you wish to disable during clone process"
|
267 |
+
msgstr ""
|
268 |
+
|
269 |
+
#: includes/admin/settings/register-settings.php:798
|
270 |
+
msgid "Select All"
|
271 |
+
msgstr ""
|
272 |
+
|
273 |
+
#: includes/admin/settings/register-settings.php:800
|
274 |
+
msgid "Deselect All"
|
275 |
+
msgstr ""
|
276 |
+
|
277 |
+
#: includes/admin/settings/register-settings.php:802
|
278 |
+
msgid "Invert Selection"
|
279 |
+
msgstr ""
|
280 |
+
|
281 |
+
#: includes/admin/settings/register-settings.php:804
|
282 |
+
msgid "Save Changes"
|
283 |
+
msgstr ""
|
284 |
+
|
285 |
+
#: includes/admin/settings/register-settings.php:805
|
286 |
+
msgctxt "The settings were saved successfully"
|
287 |
+
msgid "Saved"
|
288 |
+
msgstr ""
|
289 |
+
|
290 |
+
#: includes/admin/tools.php:67
|
291 |
+
msgid "Import/Export"
|
292 |
+
msgstr ""
|
293 |
+
|
294 |
+
#: includes/admin/tools.php:68
|
295 |
+
msgid "System Info"
|
296 |
+
msgstr ""
|
297 |
+
|
298 |
+
#: includes/admin/tools.php:90
|
299 |
+
msgid "Export Settings"
|
300 |
+
msgstr ""
|
301 |
+
|
302 |
+
#: includes/admin/tools.php:92
|
303 |
+
msgid ""
|
304 |
+
"Export the WP-Staging settings for this site as a .json file. This allows "
|
305 |
+
"you to easily import the configuration into another site."
|
306 |
+
msgstr ""
|
307 |
+
|
308 |
+
#: includes/admin/tools.php:98
|
309 |
+
msgid "Export"
|
310 |
+
msgstr ""
|
311 |
+
|
312 |
+
#: includes/admin/tools.php:105
|
313 |
+
msgid "Import Settings"
|
314 |
+
msgstr ""
|
315 |
+
|
316 |
+
#: includes/admin/tools.php:107
|
317 |
+
msgid ""
|
318 |
+
"Import the WP-Staging settings from a .json file. This file can be obtained "
|
319 |
+
"by exporting the settings on another site using the form above."
|
320 |
+
msgstr ""
|
321 |
+
|
322 |
+
#: includes/admin/tools.php:115
|
323 |
+
msgid "Import"
|
324 |
+
msgstr ""
|
325 |
+
|
326 |
+
#: includes/admin/tools.php:217
|
327 |
+
msgid "Please upload a valid .json file"
|
328 |
+
msgstr ""
|
329 |
+
|
330 |
+
#: includes/admin/tools.php:223
|
331 |
+
msgid "Please upload a file to import"
|
332 |
+
msgstr ""
|
333 |
+
|
334 |
+
#: includes/class-wpstg-html-elements.php:43
|
335 |
+
msgctxt "all dropdown items"
|
336 |
+
msgid "All"
|
337 |
+
msgstr ""
|
338 |
+
|
339 |
+
#: includes/class-wpstg-html-elements.php:44
|
340 |
+
msgctxt "no dropdown items"
|
341 |
+
msgid "None"
|
342 |
+
msgstr ""
|
343 |
+
|
344 |
+
#: includes/class-wpstg-license-handler.php:148
|
345 |
+
msgid "%1$s License Key"
|
346 |
+
msgstr ""
|
347 |
+
|
348 |
+
#: includes/class-wpstg-license-handler.php:184
|
349 |
+
#: includes/class-wpstg-license-handler.php:257
|
350 |
+
msgid "Nonce verification failed"
|
351 |
+
msgstr ""
|
352 |
+
|
353 |
+
#: includes/class-wpstg-license-handler.php:333
|
354 |
+
msgid "This license does not belong to the product you have entered it for."
|
355 |
+
msgstr ""
|
356 |
+
|
357 |
+
#: includes/class-wpstg-license-handler.php:338
|
358 |
+
msgid "This license does not have any activations left"
|
359 |
+
msgstr ""
|
360 |
+
|
361 |
+
#: includes/class-wpstg-license-handler.php:343
|
362 |
+
msgid "This license key is expired. Please renew it."
|
363 |
+
msgstr ""
|
364 |
+
|
365 |
+
#: includes/class-wpstg-license-handler.php:348
|
366 |
+
msgid ""
|
367 |
+
"There was a problem activating your license key, please try again or contact "
|
368 |
+
"support. Error code: %s"
|
369 |
+
msgstr ""
|
370 |
+
|
371 |
+
#: includes/scripts.php:45
|
372 |
+
msgid ""
|
373 |
+
"If confirmed we will install an additional WordPress 'Must Use' plugin. This "
|
374 |
+
"plugin will allow us to control which plugins are loaded during WP Staging "
|
375 |
+
"specific operations. Do you wish to continue?"
|
376 |
+
msgstr ""
|
377 |
+
|
378 |
+
#: includes/scripts.php:46
|
379 |
+
msgid ""
|
380 |
+
"A problem occurred when trying to change the plugin compatibility setting."
|
381 |
+
msgstr ""
|
382 |
+
|
383 |
+
#: includes/scripts.php:47
|
384 |
+
msgid "Saved"
|
385 |
+
msgstr ""
|
386 |
+
|
387 |
+
#: includes/scripts.php:48
|
388 |
+
msgid "Status"
|
389 |
+
msgstr ""
|
390 |
+
|
391 |
+
#: includes/scripts.php:49
|
392 |
+
msgid "Response"
|
393 |
+
msgstr ""
|
394 |
+
|
395 |
+
#: includes/scripts.php:50
|
396 |
+
msgid "A problem occurred when trying to add plugins to backlist."
|
397 |
+
msgstr ""
|
398 |
+
|
399 |
+
#: includes/staging-functions.php:31
|
400 |
+
msgid "Access denied. <a href=\"%1$s\" target=\"_blank\">Login</a> first"
|
401 |
+
msgstr ""
|
402 |
+
|
403 |
+
#: includes/template-functions.php:50
|
404 |
+
msgid ""
|
405 |
+
"WordPress Multisite is currently not supported! <a href=\"https://wp-staging."
|
406 |
+
"com/contact\">Get in contact with us</a> and ask for it."
|
407 |
+
msgstr ""
|
408 |
+
|
409 |
+
#: includes/template-functions.php:54
|
410 |
+
msgid "Overview"
|
411 |
+
msgstr ""
|
412 |
+
|
413 |
+
#: includes/template-functions.php:55
|
414 |
+
msgid "Scanning"
|
415 |
+
msgstr ""
|
416 |
+
|
417 |
+
#: includes/template-functions.php:56
|
418 |
+
msgid "Cloning"
|
419 |
+
msgstr ""
|
420 |
+
|
421 |
+
#: includes/template-functions.php:87
|
422 |
+
msgid "Create new staging site"
|
423 |
+
msgstr ""
|
424 |
+
|
425 |
+
#: includes/template-functions.php:92
|
426 |
+
msgid "Available Staging Sites:"
|
427 |
+
msgstr ""
|
428 |
+
|
429 |
+
#: includes/template-functions.php:96
|
430 |
+
msgid "Open"
|
431 |
+
msgstr ""
|
432 |
+
|
433 |
+
#: includes/template-functions.php:97
|
434 |
+
msgid "Edit"
|
435 |
+
msgstr ""
|
436 |
+
|
437 |
+
#: includes/template-functions.php:98
|
438 |
+
msgid "Delete"
|
439 |
+
msgstr ""
|
440 |
+
|
441 |
+
#: includes/template-functions.php:169
|
442 |
+
msgid "Name your new site, e.g. staging, development:"
|
443 |
+
msgstr ""
|
444 |
+
|
445 |
+
#: includes/template-functions.php:181
|
446 |
+
msgid "DB Tables"
|
447 |
+
msgstr ""
|
448 |
+
|
449 |
+
#: includes/template-functions.php:186
|
450 |
+
msgid ""
|
451 |
+
"Select the tables to copy. (If the copy process was previously interrupted, "
|
452 |
+
"succesfull copied tables are greyed out and copy process will skip these "
|
453 |
+
"ones)"
|
454 |
+
msgstr ""
|
455 |
+
|
456 |
+
#: includes/template-functions.php:192
|
457 |
+
msgid "Files"
|
458 |
+
msgstr ""
|
459 |
+
|
460 |
+
#: includes/template-functions.php:197
|
461 |
+
msgid "Select the folders to copy:"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: includes/template-functions.php:205
|
465 |
+
msgid "Advanced Options"
|
466 |
+
msgstr ""
|
467 |
+
|
468 |
+
#: includes/template-functions.php:211
|
469 |
+
msgid "Back"
|
470 |
+
msgstr ""
|
471 |
+
|
472 |
+
#: includes/template-functions.php:380
|
473 |
+
msgid ""
|
474 |
+
"We have detected the following large files which could neeed some "
|
475 |
+
"investigation. Often this files are backup files or other temporary files "
|
476 |
+
"which must not necessarily copied for creating a staging site:"
|
477 |
+
msgstr ""
|
478 |
+
|
479 |
+
#: includes/template-functions.php:468
|
480 |
+
msgid "Copy database tables"
|
481 |
+
msgstr ""
|
482 |
+
|
483 |
+
#: includes/template-functions.php:473
|
484 |
+
msgid "Copy files"
|
485 |
+
msgstr ""
|
486 |
+
|
487 |
+
#: includes/template-functions.php:478
|
488 |
+
msgid "Replace Links"
|
489 |
+
msgstr ""
|
490 |
+
|
491 |
+
#: includes/template-functions.php:484 includes/template-functions.php:1180
|
492 |
+
msgid "Cancel"
|
493 |
+
msgstr ""
|
494 |
+
|
495 |
+
#: includes/template-functions.php:488
|
496 |
+
msgid "Display working log"
|
497 |
+
msgstr ""
|
498 |
+
|
499 |
+
#: includes/template-functions.php:494 includes/template-functions.php:1181
|
500 |
+
msgid "Remove"
|
501 |
+
msgstr ""
|
502 |
+
|
503 |
+
#: includes/template-functions.php:495
|
504 |
+
msgid "Start again"
|
505 |
+
msgstr ""
|
506 |
+
|
507 |
+
#: includes/template-functions.php:497
|
508 |
+
msgid "Important notes:"
|
509 |
+
msgstr ""
|
510 |
+
|
511 |
+
#: includes/template-functions.php:1149
|
512 |
+
msgid ""
|
513 |
+
"Attention: Check carefully if this DB tables and files are safe to delete "
|
514 |
+
"for the staging site"
|
515 |
+
msgstr ""
|
516 |
+
|
517 |
+
#: includes/template-functions.php:1151
|
518 |
+
msgid ""
|
519 |
+
"Usually the preselected data can be deleted without any risk, but in case "
|
520 |
+
"something goes wrong you better check it first."
|
521 |
+
msgstr ""
|
522 |
+
|
523 |
+
#: includes/template-functions.php:1156
|
524 |
+
msgid "DB tables to remove"
|
525 |
+
msgstr ""
|
526 |
+
|
527 |
+
#: includes/template-functions.php:1161
|
528 |
+
msgid "Select the tables for removal:"
|
529 |
+
msgstr ""
|
530 |
+
|
531 |
+
#: includes/template-functions.php:1169
|
532 |
+
msgid "Files to remove"
|
533 |
+
msgstr ""
|
534 |
+
|
535 |
+
#: includes/template-functions.php:1174
|
536 |
+
msgid "Select the folders for removal. Click on a folder name to expand it:"
|
537 |
+
msgstr ""
|
538 |
+
|
539 |
+
#: includes/template-functions.php:1394
|
540 |
+
msgid "The following directory could not be created: %s"
|
541 |
+
msgstr ""
|
542 |
+
|
543 |
+
#: includes/template-functions.php:1399
|
544 |
+
msgid "Could not copy the compatibility plugin from %1$s to %2$s"
|
545 |
+
msgstr ""
|
546 |
+
|
547 |
+
#: includes/template-functions.php:1405
|
548 |
+
msgid "Could not remove the compatibility plugin from %s"
|
549 |
+
msgstr ""
|
550 |
+
|
551 |
+
#: includes/template-functions.php:1560
|
552 |
+
msgid "Start Cloning"
|
553 |
+
msgstr ""
|
554 |
+
|
555 |
+
#: includes/template-functions.php:1562
|
556 |
+
msgid "Resume Cloning"
|
557 |
+
msgstr ""
|
558 |
+
|
559 |
+
#: includes/template-functions.php:1575
|
560 |
+
msgid ""
|
561 |
+
"Probably not enough free disk space to create a staging site. You can "
|
562 |
+
"continue but its likely that the copying process will fail."
|
563 |
+
msgstr ""
|
564 |
+
|
565 |
+
#: includes/wpstg-sanitize.php:39
|
566 |
+
msgid "%1$s was not expecting data to be an array."
|
567 |
+
msgstr ""
|
568 |
+
|
569 |
+
#: includes/wpstg-sanitize.php:60
|
570 |
+
msgid "%1$s was expecting an array but got something else: \"%2$s\""
|
571 |
+
msgstr ""
|
572 |
+
|
573 |
+
#: includes/wpstg-sanitize.php:66
|
574 |
+
msgid "%1$s was expecting a string but got something else: \"%2$s\""
|
575 |
+
msgstr ""
|
576 |
+
|
577 |
+
#: includes/wpstg-sanitize.php:73
|
578 |
+
msgid "%1$s was expecting a valid key but got something else: \"%2$s\""
|
579 |
+
msgstr ""
|
580 |
+
|
581 |
+
#: includes/wpstg-sanitize.php:81
|
582 |
+
msgid "%1$s was expecting text but got something else: \"%2$s\""
|
583 |
+
msgstr ""
|
584 |
+
|
585 |
+
#: includes/wpstg-sanitize.php:88
|
586 |
+
msgid "%1$s was expecting serialized data but got something else: \"%2$s\""
|
587 |
+
msgstr ""
|
588 |
+
|
589 |
+
#: includes/wpstg-sanitize.php:94
|
590 |
+
msgid "%1$s was expecting a valid numeric but got something else: \"%2$s\""
|
591 |
+
msgstr ""
|
592 |
+
|
593 |
+
#: includes/wpstg-sanitize.php:101
|
594 |
+
msgid "%1$s was expecting an integer but got something else: \"%2$s\""
|
595 |
+
msgstr ""
|
596 |
+
|
597 |
+
#: includes/wpstg-sanitize.php:108
|
598 |
+
msgid ""
|
599 |
+
"%1$s was expecting a positive number (int) but got something else: \"%2$s\""
|
600 |
+
msgstr ""
|
601 |
+
|
602 |
+
#: includes/wpstg-sanitize.php:115
|
603 |
+
msgid ""
|
604 |
+
"%1$s was expecting a negative number (int) but got something else: \"%2$s\""
|
605 |
+
msgstr ""
|
606 |
+
|
607 |
+
#: includes/wpstg-sanitize.php:122
|
608 |
+
msgid "%1$s was expecting 0 (int) but got something else: \"%2$s\""
|
609 |
+
msgstr ""
|
610 |
+
|
611 |
+
#: includes/wpstg-sanitize.php:129
|
612 |
+
msgid "%1$s was expecting an empty value but got something else: \"%2$s\""
|
613 |
+
msgstr ""
|
614 |
+
|
615 |
+
#: includes/wpstg-sanitize.php:136
|
616 |
+
msgid "%1$s was expecting a URL but got something else: \"%2$s\""
|
617 |
+
msgstr ""
|
618 |
+
|
619 |
+
#: includes/wpstg-sanitize.php:144
|
620 |
+
msgid "%1$s was expecting a bool but got something else: \"%2$s\""
|
621 |
+
msgstr ""
|
622 |
+
|
623 |
+
#: includes/wpstg-sanitize.php:150
|
624 |
+
msgid "Unknown sanitization rule \"%1$s\" supplied by %2$s"
|
625 |
+
msgstr ""
|
626 |
+
|
627 |
+
#: wp-staging.php:114 wp-staging.php:126
|
628 |
+
msgid "Cheatin’ huh?"
|
629 |
+
msgstr ""
|
630 |
+
|
631 |
+
#. Plugin Name of the plugin/theme
|
632 |
+
msgid "WP Staging - Create a staging clone site for testing & developing"
|
633 |
+
msgstr ""
|
634 |
+
|
635 |
+
#. #-#-#-#-# plugin.pot (WP Staging - Create a staging clone site for testing & developing 0.9.0) #-#-#-#-#
|
636 |
+
#. Plugin URI of the plugin/theme
|
637 |
+
#. #-#-#-#-# plugin.pot (WP Staging - Create a staging clone site for testing & developing 0.9.0) #-#-#-#-#
|
638 |
+
#. Author URI of the plugin/theme
|
639 |
+
msgid "wordpress.org/plugins/wp-staging"
|
640 |
+
msgstr ""
|
641 |
+
|
642 |
+
#. Description of the plugin/theme
|
643 |
+
msgid "WP-Staging - Create a staging clone site for testing & developing"
|
644 |
+
msgstr ""
|
645 |
+
|
646 |
+
#. Author of the plugin/theme
|
647 |
+
msgid "René Hermenau"
|
648 |
+
msgstr ""
|
languages/wpstg.mo
ADDED
Binary file
|
languages/wpstg.po
ADDED
@@ -0,0 +1,648 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2015 WP Staging - Create a staging clone site for testing & developing
|
2 |
+
# This file is distributed under the same license as the WP Staging - Create a staging clone site for testing & developing package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: WP Staging - Create a staging clone site for testing & "
|
6 |
+
"developing 0.9.0\n"
|
7 |
+
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-staging\n"
|
8 |
+
"POT-Creation-Date: 2015-08-05 09:53:10+00:00\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"PO-Revision-Date: 2015-08-05 11:54+0100\n"
|
13 |
+
"Last-Translator: Rene Hermenau <support@wp-staging.com>\n"
|
14 |
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15 |
+
"X-Generator: Poedit 1.5.6\n"
|
16 |
+
|
17 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:181
|
18 |
+
msgid ""
|
19 |
+
"There is a new version of %1$s available. <a target=\"_blank\" class="
|
20 |
+
"\"thickbox\" href=\"%2$s\">View version %3$s details</a>."
|
21 |
+
msgstr ""
|
22 |
+
|
23 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:188
|
24 |
+
msgid ""
|
25 |
+
"There is a new version of %1$s available. <a target=\"_blank\" class="
|
26 |
+
"\"thickbox\" href=\"%2$s\">View version %3$s details</a> or <a href=\"%4$s"
|
27 |
+
"\">update now</a>."
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:346
|
31 |
+
msgid "You do not have permission to install plugin updates"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: includes/WPSTG_SL_Plugin_Updater.php:346
|
35 |
+
#: includes/class-wpstg-license-handler.php:184
|
36 |
+
#: includes/class-wpstg-license-handler.php:257
|
37 |
+
msgid "Error"
|
38 |
+
msgstr ""
|
39 |
+
|
40 |
+
#: includes/admin/add-ons.php:27
|
41 |
+
msgid "Add Ons for WP-Staging"
|
42 |
+
msgstr ""
|
43 |
+
|
44 |
+
#: includes/admin/add-ons.php:28
|
45 |
+
msgid "Visit Website"
|
46 |
+
msgstr ""
|
47 |
+
|
48 |
+
#: includes/admin/add-ons.php:28
|
49 |
+
msgid "See Details"
|
50 |
+
msgstr ""
|
51 |
+
|
52 |
+
#: includes/admin/add-ons.php:30
|
53 |
+
msgid "These add-ons extend the functionality of WP-Staging."
|
54 |
+
msgstr ""
|
55 |
+
|
56 |
+
#: includes/admin/add-ons.php:54
|
57 |
+
msgid ""
|
58 |
+
"There was an error retrieving the WP-Staging addon list from the server. "
|
59 |
+
"Please try again later."
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: includes/admin/admin-footer.php:32
|
63 |
+
msgid ""
|
64 |
+
"Please <a href=\"%1$s\" target=\"_blank\">rate WP Staging</a> and help to "
|
65 |
+
"support this project.<br>Something not working as expected? Visit the WP "
|
66 |
+
"Staging <a href=\"https://wordpress.org/support/plugin/wp-staging\" target="
|
67 |
+
"\"blank\">Support Forum</a>"
|
68 |
+
msgstr ""
|
69 |
+
|
70 |
+
#: includes/admin/admin-notices.php:44
|
71 |
+
msgid ""
|
72 |
+
"You are using an outdated version of WP Staging which has not been tested "
|
73 |
+
"with your WordPress version %2$s.<br> \r\n"
|
74 |
+
" As WP Staging is using crucial db and file functions it's "
|
75 |
+
"important that you are using a WP Staging version<br> \r\n"
|
76 |
+
" which has been verified to be working with your WordPress "
|
77 |
+
"version. You risk unexpected results up to data lose if you do not so.\r\n"
|
78 |
+
" <p>Please look at <a href=\"%1$s\" target=\"_blank\">%s</a> for "
|
79 |
+
"the latest WP Staging version."
|
80 |
+
msgstr ""
|
81 |
+
|
82 |
+
#: includes/admin/admin-notices.php:135
|
83 |
+
msgid ""
|
84 |
+
"There seems to be an issue with the server. Please try again in a few "
|
85 |
+
"minutes."
|
86 |
+
msgstr ""
|
87 |
+
|
88 |
+
#: includes/admin/admin-pages.php:27
|
89 |
+
msgid "WP Staging"
|
90 |
+
msgstr ""
|
91 |
+
|
92 |
+
#: includes/admin/admin-pages.php:28
|
93 |
+
msgid "WP Staging Jobs"
|
94 |
+
msgstr ""
|
95 |
+
|
96 |
+
#: includes/admin/admin-pages.php:28
|
97 |
+
msgid "Start"
|
98 |
+
msgstr ""
|
99 |
+
|
100 |
+
#: includes/admin/admin-pages.php:29
|
101 |
+
msgid "WP Staging Settings"
|
102 |
+
msgstr ""
|
103 |
+
|
104 |
+
#: includes/admin/admin-pages.php:29
|
105 |
+
msgid "Settings"
|
106 |
+
msgstr ""
|
107 |
+
|
108 |
+
#: includes/admin/admin-pages.php:30
|
109 |
+
msgid "WP Staging Tools"
|
110 |
+
msgstr ""
|
111 |
+
|
112 |
+
#: includes/admin/admin-pages.php:30
|
113 |
+
msgid "Tools"
|
114 |
+
msgstr ""
|
115 |
+
|
116 |
+
#: includes/admin/plugins.php:27
|
117 |
+
msgid "General Settings"
|
118 |
+
msgstr ""
|
119 |
+
|
120 |
+
#: includes/admin/plugins.php:55
|
121 |
+
msgid "Getting Started"
|
122 |
+
msgstr ""
|
123 |
+
|
124 |
+
#: includes/admin/settings/contextual-help.php:29
|
125 |
+
msgid "For more information:"
|
126 |
+
msgstr ""
|
127 |
+
|
128 |
+
#: includes/admin/settings/contextual-help.php:30
|
129 |
+
msgid "Visit the <a href=\"%s\">documentation</a> on the WP-Staging website."
|
130 |
+
msgstr ""
|
131 |
+
|
132 |
+
#: includes/admin/settings/contextual-help.php:32
|
133 |
+
msgid ""
|
134 |
+
"<a href=\"%s\">Post an issue</a> on <a href=\"%s\">WP-Staging</a>. View <a "
|
135 |
+
"href=\"%s\">extensions</a>."
|
136 |
+
msgstr ""
|
137 |
+
|
138 |
+
#: includes/admin/settings/contextual-help.php:41
|
139 |
+
#: includes/admin/settings/register-settings.php:126
|
140 |
+
#: includes/admin/settings/register-settings.php:301
|
141 |
+
msgid "General"
|
142 |
+
msgstr ""
|
143 |
+
|
144 |
+
#: includes/admin/settings/contextual-help.php:42
|
145 |
+
msgid ""
|
146 |
+
"This screen provides the most basic settings for configuring WP-Staging."
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: includes/admin/settings/display-settings.php:135
|
150 |
+
#: includes/template-functions.php:40
|
151 |
+
msgid "Thank you for using WP Staging"
|
152 |
+
msgstr ""
|
153 |
+
|
154 |
+
#: includes/admin/settings/display-settings.php:137
|
155 |
+
#: includes/template-functions.php:42
|
156 |
+
msgid "WP Staging is ready to create a staging site!"
|
157 |
+
msgstr ""
|
158 |
+
|
159 |
+
#: includes/admin/settings/register-settings.php:133
|
160 |
+
msgid "DB Copy Query Limit"
|
161 |
+
msgstr ""
|
162 |
+
|
163 |
+
#: includes/admin/settings/register-settings.php:134
|
164 |
+
msgid ""
|
165 |
+
"Number of DB rows, that will be copied within one ajax request. The higher "
|
166 |
+
"the value the faster the database copy process. To find out the highest "
|
167 |
+
"possible values try a high value like 1.000 or more and decrease it until "
|
168 |
+
"you get no more errors during copy process. <strong> Default: 100 </strong>"
|
169 |
+
msgstr ""
|
170 |
+
|
171 |
+
#: includes/admin/settings/register-settings.php:141
|
172 |
+
msgid "File Copy Batch Size"
|
173 |
+
msgstr ""
|
174 |
+
|
175 |
+
#: includes/admin/settings/register-settings.php:142
|
176 |
+
msgid ""
|
177 |
+
"Buffer size for the file copy process in megabyte. The higher the value the "
|
178 |
+
"faster large files will be copied. To find out the highest possible values "
|
179 |
+
"try a high one and lower it until you get no errors during file copy "
|
180 |
+
"process. Usually this value correlates directly with the memory consumption "
|
181 |
+
"of php so make sure that it does not exceed any php.ini max_memory limits. "
|
182 |
+
"<strong>Default:</strong> 2 "
|
183 |
+
msgstr ""
|
184 |
+
|
185 |
+
#: includes/admin/settings/register-settings.php:149
|
186 |
+
msgid "Optimizer"
|
187 |
+
msgstr ""
|
188 |
+
|
189 |
+
#: includes/admin/settings/register-settings.php:150
|
190 |
+
msgid ""
|
191 |
+
"Select the plugins that should be disabled during build process of the "
|
192 |
+
"staging site. Some plugins slow down the copy process and add overhead to "
|
193 |
+
"each request, requiring extra CPU and memory consumption. Some of them can "
|
194 |
+
"interfere with cloning process and cause them to fail, so we recommend to "
|
195 |
+
"disable all plugins that are not directly related to WP Staging."
|
196 |
+
msgstr ""
|
197 |
+
|
198 |
+
#: includes/admin/settings/register-settings.php:157
|
199 |
+
msgid "Don´t force admin login"
|
200 |
+
msgstr ""
|
201 |
+
|
202 |
+
#: includes/admin/settings/register-settings.php:158
|
203 |
+
msgid ""
|
204 |
+
"Use this option only if you are using a custom login page and not the "
|
205 |
+
"default login.php. If you enable this option you are allowing everyone "
|
206 |
+
"including searchengines to see your staging site, so you have to create a "
|
207 |
+
"custom authentication like using .htaccess"
|
208 |
+
msgstr ""
|
209 |
+
|
210 |
+
#: includes/admin/settings/register-settings.php:170
|
211 |
+
msgid "Remove Data on Uninstall?"
|
212 |
+
msgstr ""
|
213 |
+
|
214 |
+
#: includes/admin/settings/register-settings.php:171
|
215 |
+
msgid ""
|
216 |
+
"Check this box if you like WP Staging to completely remove all of its data "
|
217 |
+
"when the plugin is deleted."
|
218 |
+
msgstr ""
|
219 |
+
|
220 |
+
#: includes/admin/settings/register-settings.php:186
|
221 |
+
msgid "Activate your Add-Ons"
|
222 |
+
msgstr ""
|
223 |
+
|
224 |
+
#: includes/admin/settings/register-settings.php:271
|
225 |
+
msgid "Settings updated."
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#: includes/admin/settings/register-settings.php:304
|
229 |
+
msgid "Misc"
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: includes/admin/settings/register-settings.php:312
|
233 |
+
msgid "Extensions"
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#: includes/admin/settings/register-settings.php:527
|
237 |
+
msgid ""
|
238 |
+
"The callback function used for the <strong>%s</strong> setting is missing."
|
239 |
+
msgstr ""
|
240 |
+
|
241 |
+
#: includes/admin/settings/register-settings.php:639
|
242 |
+
msgid "Upload File"
|
243 |
+
msgstr ""
|
244 |
+
|
245 |
+
#: includes/admin/settings/register-settings.php:667
|
246 |
+
msgid "Deactivate License"
|
247 |
+
msgstr ""
|
248 |
+
|
249 |
+
#: includes/admin/settings/register-settings.php:714
|
250 |
+
msgid "Select Image"
|
251 |
+
msgstr ""
|
252 |
+
|
253 |
+
#: includes/admin/settings/register-settings.php:761
|
254 |
+
msgid ""
|
255 |
+
"Log file directory not writable! Set FTP permission to 755 or 777 for /wp-"
|
256 |
+
"content/plugins/wp-staging/logs/"
|
257 |
+
msgstr ""
|
258 |
+
|
259 |
+
#: includes/admin/settings/register-settings.php:775
|
260 |
+
msgid ""
|
261 |
+
"Improve performance and reliability by not loading the following plugins for "
|
262 |
+
"migration requests"
|
263 |
+
msgstr ""
|
264 |
+
|
265 |
+
#: includes/admin/settings/register-settings.php:780
|
266 |
+
msgid "Select the plugins you wish to disable during clone process"
|
267 |
+
msgstr ""
|
268 |
+
|
269 |
+
#: includes/admin/settings/register-settings.php:798
|
270 |
+
msgid "Select All"
|
271 |
+
msgstr ""
|
272 |
+
|
273 |
+
#: includes/admin/settings/register-settings.php:800
|
274 |
+
msgid "Deselect All"
|
275 |
+
msgstr ""
|
276 |
+
|
277 |
+
#: includes/admin/settings/register-settings.php:802
|
278 |
+
msgid "Invert Selection"
|
279 |
+
msgstr ""
|
280 |
+
|
281 |
+
#: includes/admin/settings/register-settings.php:804
|
282 |
+
msgid "Save Changes"
|
283 |
+
msgstr ""
|
284 |
+
|
285 |
+
#: includes/admin/settings/register-settings.php:805
|
286 |
+
msgctxt "The settings were saved successfully"
|
287 |
+
msgid "Saved"
|
288 |
+
msgstr ""
|
289 |
+
|
290 |
+
#: includes/admin/tools.php:67
|
291 |
+
msgid "Import/Export"
|
292 |
+
msgstr ""
|
293 |
+
|
294 |
+
#: includes/admin/tools.php:68
|
295 |
+
msgid "System Info"
|
296 |
+
msgstr ""
|
297 |
+
|
298 |
+
#: includes/admin/tools.php:90
|
299 |
+
msgid "Export Settings"
|
300 |
+
msgstr ""
|
301 |
+
|
302 |
+
#: includes/admin/tools.php:92
|
303 |
+
msgid ""
|
304 |
+
"Export the WP-Staging settings for this site as a .json file. This allows "
|
305 |
+
"you to easily import the configuration into another site."
|
306 |
+
msgstr ""
|
307 |
+
|
308 |
+
#: includes/admin/tools.php:98
|
309 |
+
msgid "Export"
|
310 |
+
msgstr ""
|
311 |
+
|
312 |
+
#: includes/admin/tools.php:105
|
313 |
+
msgid "Import Settings"
|
314 |
+
msgstr ""
|
315 |
+
|
316 |
+
#: includes/admin/tools.php:107
|
317 |
+
msgid ""
|
318 |
+
"Import the WP-Staging settings from a .json file. This file can be obtained "
|
319 |
+
"by exporting the settings on another site using the form above."
|
320 |
+
msgstr ""
|
321 |
+
|
322 |
+
#: includes/admin/tools.php:115
|
323 |
+
msgid "Import"
|
324 |
+
msgstr ""
|
325 |
+
|
326 |
+
#: includes/admin/tools.php:217
|
327 |
+
msgid "Please upload a valid .json file"
|
328 |
+
msgstr ""
|
329 |
+
|
330 |
+
#: includes/admin/tools.php:223
|
331 |
+
msgid "Please upload a file to import"
|
332 |
+
msgstr ""
|
333 |
+
|
334 |
+
#: includes/class-wpstg-html-elements.php:43
|
335 |
+
msgctxt "all dropdown items"
|
336 |
+
msgid "All"
|
337 |
+
msgstr ""
|
338 |
+
|
339 |
+
#: includes/class-wpstg-html-elements.php:44
|
340 |
+
msgctxt "no dropdown items"
|
341 |
+
msgid "None"
|
342 |
+
msgstr ""
|
343 |
+
|
344 |
+
#: includes/class-wpstg-license-handler.php:148
|
345 |
+
msgid "%1$s License Key"
|
346 |
+
msgstr ""
|
347 |
+
|
348 |
+
#: includes/class-wpstg-license-handler.php:184
|
349 |
+
#: includes/class-wpstg-license-handler.php:257
|
350 |
+
msgid "Nonce verification failed"
|
351 |
+
msgstr ""
|
352 |
+
|
353 |
+
#: includes/class-wpstg-license-handler.php:333
|
354 |
+
msgid "This license does not belong to the product you have entered it for."
|
355 |
+
msgstr ""
|
356 |
+
|
357 |
+
#: includes/class-wpstg-license-handler.php:338
|
358 |
+
msgid "This license does not have any activations left"
|
359 |
+
msgstr ""
|
360 |
+
|
361 |
+
#: includes/class-wpstg-license-handler.php:343
|
362 |
+
msgid "This license key is expired. Please renew it."
|
363 |
+
msgstr ""
|
364 |
+
|
365 |
+
#: includes/class-wpstg-license-handler.php:348
|
366 |
+
msgid ""
|
367 |
+
"There was a problem activating your license key, please try again or contact "
|
368 |
+
"support. Error code: %s"
|
369 |
+
msgstr ""
|
370 |
+
|
371 |
+
#: includes/scripts.php:45
|
372 |
+
msgid ""
|
373 |
+
"If confirmed we will install an additional WordPress 'Must Use' plugin. This "
|
374 |
+
"plugin will allow us to control which plugins are loaded during WP Staging "
|
375 |
+
"specific operations. Do you wish to continue?"
|
376 |
+
msgstr ""
|
377 |
+
|
378 |
+
#: includes/scripts.php:46
|
379 |
+
msgid ""
|
380 |
+
"A problem occurred when trying to change the plugin compatibility setting."
|
381 |
+
msgstr ""
|
382 |
+
|
383 |
+
#: includes/scripts.php:47
|
384 |
+
msgid "Saved"
|
385 |
+
msgstr ""
|
386 |
+
|
387 |
+
#: includes/scripts.php:48
|
388 |
+
msgid "Status"
|
389 |
+
msgstr ""
|
390 |
+
|
391 |
+
#: includes/scripts.php:49
|
392 |
+
msgid "Response"
|
393 |
+
msgstr ""
|
394 |
+
|
395 |
+
#: includes/scripts.php:50
|
396 |
+
msgid "A problem occurred when trying to add plugins to backlist."
|
397 |
+
msgstr ""
|
398 |
+
|
399 |
+
#: includes/staging-functions.php:31
|
400 |
+
msgid "Access denied. <a href=\"%1$s\" target=\"_blank\">Login</a> first"
|
401 |
+
msgstr ""
|
402 |
+
|
403 |
+
#: includes/template-functions.php:50
|
404 |
+
msgid ""
|
405 |
+
"WordPress Multisite is currently not supported! <a href=\"https://wp-staging."
|
406 |
+
"com/contact\">Get in contact with us</a> and ask for it."
|
407 |
+
msgstr ""
|
408 |
+
|
409 |
+
#: includes/template-functions.php:54
|
410 |
+
msgid "Overview"
|
411 |
+
msgstr ""
|
412 |
+
|
413 |
+
#: includes/template-functions.php:55
|
414 |
+
msgid "Scanning"
|
415 |
+
msgstr ""
|
416 |
+
|
417 |
+
#: includes/template-functions.php:56
|
418 |
+
msgid "Cloning"
|
419 |
+
msgstr ""
|
420 |
+
|
421 |
+
#: includes/template-functions.php:87
|
422 |
+
msgid "Create new staging site"
|
423 |
+
msgstr ""
|
424 |
+
|
425 |
+
#: includes/template-functions.php:92
|
426 |
+
msgid "Available Staging Sites:"
|
427 |
+
msgstr ""
|
428 |
+
|
429 |
+
#: includes/template-functions.php:96
|
430 |
+
msgid "Open"
|
431 |
+
msgstr ""
|
432 |
+
|
433 |
+
#: includes/template-functions.php:97
|
434 |
+
msgid "Edit"
|
435 |
+
msgstr ""
|
436 |
+
|
437 |
+
#: includes/template-functions.php:98
|
438 |
+
msgid "Delete"
|
439 |
+
msgstr ""
|
440 |
+
|
441 |
+
#: includes/template-functions.php:169
|
442 |
+
msgid "Name your new site, e.g. staging, development:"
|
443 |
+
msgstr ""
|
444 |
+
|
445 |
+
#: includes/template-functions.php:181
|
446 |
+
msgid "DB Tables"
|
447 |
+
msgstr ""
|
448 |
+
|
449 |
+
#: includes/template-functions.php:186
|
450 |
+
msgid ""
|
451 |
+
"Select the tables to copy. (If the copy process was previously interrupted, "
|
452 |
+
"succesfull copied tables are greyed out and copy process will skip these "
|
453 |
+
"ones)"
|
454 |
+
msgstr ""
|
455 |
+
|
456 |
+
#: includes/template-functions.php:192
|
457 |
+
msgid "Files"
|
458 |
+
msgstr ""
|
459 |
+
|
460 |
+
#: includes/template-functions.php:197
|
461 |
+
msgid "Select the folders to copy:"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: includes/template-functions.php:205
|
465 |
+
msgid "Advanced Options"
|
466 |
+
msgstr ""
|
467 |
+
|
468 |
+
#: includes/template-functions.php:211
|
469 |
+
msgid "Back"
|
470 |
+
msgstr ""
|
471 |
+
|
472 |
+
#: includes/template-functions.php:380
|
473 |
+
msgid ""
|
474 |
+
"We have detected the following large files which could neeed some "
|
475 |
+
"investigation. Often this files are backup files or other temporary files "
|
476 |
+
"which must not necessarily copied for creating a staging site:"
|
477 |
+
msgstr ""
|
478 |
+
|
479 |
+
#: includes/template-functions.php:468
|
480 |
+
msgid "Copy database tables"
|
481 |
+
msgstr ""
|
482 |
+
|
483 |
+
#: includes/template-functions.php:473
|
484 |
+
msgid "Copy files"
|
485 |
+
msgstr ""
|
486 |
+
|
487 |
+
#: includes/template-functions.php:478
|
488 |
+
msgid "Replace Links"
|
489 |
+
msgstr ""
|
490 |
+
|
491 |
+
#: includes/template-functions.php:484 includes/template-functions.php:1180
|
492 |
+
msgid "Cancel"
|
493 |
+
msgstr ""
|
494 |
+
|
495 |
+
#: includes/template-functions.php:488
|
496 |
+
msgid "Display working log"
|
497 |
+
msgstr ""
|
498 |
+
|
499 |
+
#: includes/template-functions.php:494 includes/template-functions.php:1181
|
500 |
+
msgid "Remove"
|
501 |
+
msgstr ""
|
502 |
+
|
503 |
+
#: includes/template-functions.php:495
|
504 |
+
msgid "Start again"
|
505 |
+
msgstr ""
|
506 |
+
|
507 |
+
#: includes/template-functions.php:497
|
508 |
+
msgid "Important notes:"
|
509 |
+
msgstr ""
|
510 |
+
|
511 |
+
#: includes/template-functions.php:1149
|
512 |
+
msgid ""
|
513 |
+
"Attention: Check carefully if this DB tables and files are safe to delete "
|
514 |
+
"for the staging site"
|
515 |
+
msgstr ""
|
516 |
+
|
517 |
+
#: includes/template-functions.php:1151
|
518 |
+
msgid ""
|
519 |
+
"Usually the preselected data can be deleted without any risk, but in case "
|
520 |
+
"something goes wrong you better check it first."
|
521 |
+
msgstr ""
|
522 |
+
|
523 |
+
#: includes/template-functions.php:1156
|
524 |
+
msgid "DB tables to remove"
|
525 |
+
msgstr ""
|
526 |
+
|
527 |
+
#: includes/template-functions.php:1161
|
528 |
+
msgid "Select the tables for removal:"
|
529 |
+
msgstr ""
|
530 |
+
|
531 |
+
#: includes/template-functions.php:1169
|
532 |
+
msgid "Files to remove"
|
533 |
+
msgstr ""
|
534 |
+
|
535 |
+
#: includes/template-functions.php:1174
|
536 |
+
msgid "Select the folders for removal. Click on a folder name to expand it:"
|
537 |
+
msgstr ""
|
538 |
+
|
539 |
+
#: includes/template-functions.php:1394
|
540 |
+
msgid "The following directory could not be created: %s"
|
541 |
+
msgstr ""
|
542 |
+
|
543 |
+
#: includes/template-functions.php:1399
|
544 |
+
msgid "Could not copy the compatibility plugin from %1$s to %2$s"
|
545 |
+
msgstr ""
|
546 |
+
|
547 |
+
#: includes/template-functions.php:1405
|
548 |
+
msgid "Could not remove the compatibility plugin from %s"
|
549 |
+
msgstr ""
|
550 |
+
|
551 |
+
#: includes/template-functions.php:1560
|
552 |
+
msgid "Start Cloning"
|
553 |
+
msgstr ""
|
554 |
+
|
555 |
+
#: includes/template-functions.php:1562
|
556 |
+
msgid "Resume Cloning"
|
557 |
+
msgstr ""
|
558 |
+
|
559 |
+
#: includes/template-functions.php:1575
|
560 |
+
msgid ""
|
561 |
+
"Probably not enough free disk space to create a staging site. You can "
|
562 |
+
"continue but its likely that the copying process will fail."
|
563 |
+
msgstr ""
|
564 |
+
|
565 |
+
#: includes/wpstg-sanitize.php:39
|
566 |
+
msgid "%1$s was not expecting data to be an array."
|
567 |
+
msgstr ""
|
568 |
+
|
569 |
+
#: includes/wpstg-sanitize.php:60
|
570 |
+
msgid "%1$s was expecting an array but got something else: \"%2$s\""
|
571 |
+
msgstr ""
|
572 |
+
|
573 |
+
#: includes/wpstg-sanitize.php:66
|
574 |
+
msgid "%1$s was expecting a string but got something else: \"%2$s\""
|
575 |
+
msgstr ""
|
576 |
+
|
577 |
+
#: includes/wpstg-sanitize.php:73
|
578 |
+
msgid "%1$s was expecting a valid key but got something else: \"%2$s\""
|
579 |
+
msgstr ""
|
580 |
+
|
581 |
+
#: includes/wpstg-sanitize.php:81
|
582 |
+
msgid "%1$s was expecting text but got something else: \"%2$s\""
|
583 |
+
msgstr ""
|
584 |
+
|
585 |
+
#: includes/wpstg-sanitize.php:88
|
586 |
+
msgid "%1$s was expecting serialized data but got something else: \"%2$s\""
|
587 |
+
msgstr ""
|
588 |
+
|
589 |
+
#: includes/wpstg-sanitize.php:94
|
590 |
+
msgid "%1$s was expecting a valid numeric but got something else: \"%2$s\""
|
591 |
+
msgstr ""
|
592 |
+
|
593 |
+
#: includes/wpstg-sanitize.php:101
|
594 |
+
msgid "%1$s was expecting an integer but got something else: \"%2$s\""
|
595 |
+
msgstr ""
|
596 |
+
|
597 |
+
#: includes/wpstg-sanitize.php:108
|
598 |
+
msgid ""
|
599 |
+
"%1$s was expecting a positive number (int) but got something else: \"%2$s\""
|
600 |
+
msgstr ""
|
601 |
+
|
602 |
+
#: includes/wpstg-sanitize.php:115
|
603 |
+
msgid ""
|
604 |
+
"%1$s was expecting a negative number (int) but got something else: \"%2$s\""
|
605 |
+
msgstr ""
|
606 |
+
|
607 |
+
#: includes/wpstg-sanitize.php:122
|
608 |
+
msgid "%1$s was expecting 0 (int) but got something else: \"%2$s\""
|
609 |
+
msgstr ""
|
610 |
+
|
611 |
+
#: includes/wpstg-sanitize.php:129
|
612 |
+
msgid "%1$s was expecting an empty value but got something else: \"%2$s\""
|
613 |
+
msgstr ""
|
614 |
+
|
615 |
+
#: includes/wpstg-sanitize.php:136
|
616 |
+
msgid "%1$s was expecting a URL but got something else: \"%2$s\""
|
617 |
+
msgstr ""
|
618 |
+
|
619 |
+
#: includes/wpstg-sanitize.php:144
|
620 |
+
msgid "%1$s was expecting a bool but got something else: \"%2$s\""
|
621 |
+
msgstr ""
|
622 |
+
|
623 |
+
#: includes/wpstg-sanitize.php:150
|
624 |
+
msgid "Unknown sanitization rule \"%1$s\" supplied by %2$s"
|
625 |
+
msgstr ""
|
626 |
+
|
627 |
+
#: wp-staging.php:114 wp-staging.php:126
|
628 |
+
msgid "Cheatin’ huh?"
|
629 |
+
msgstr ""
|
630 |
+
|
631 |
+
#. Plugin Name of the plugin/theme
|
632 |
+
msgid "WP Staging - Create a staging clone site for testing & developing"
|
633 |
+
msgstr ""
|
634 |
+
|
635 |
+
#. #-#-#-#-# plugin.pot (WP Staging - Create a staging clone site for testing & developing 0.9.0) #-#-#-#-#
|
636 |
+
#. Plugin URI of the plugin/theme
|
637 |
+
#. #-#-#-#-# plugin.pot (WP Staging - Create a staging clone site for testing & developing 0.9.0) #-#-#-#-#
|
638 |
+
#. Author URI of the plugin/theme
|
639 |
+
msgid "wordpress.org/plugins/wp-staging"
|
640 |
+
msgstr ""
|
641 |
+
|
642 |
+
#. Description of the plugin/theme
|
643 |
+
msgid "WP-Staging - Create a staging clone site for testing & developing"
|
644 |
+
msgstr ""
|
645 |
+
|
646 |
+
#. Author of the plugin/theme
|
647 |
+
msgid "René Hermenau"
|
648 |
+
msgstr ""
|
license.txt
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
+
51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
6 |
+
|
7 |
+
Everyone is permitted to copy and distribute verbatim copies
|
8 |
+
of this license document, but changing it is not allowed.
|
9 |
+
|
10 |
+
Preamble
|
11 |
+
|
12 |
+
The licenses for most software are designed to take away your
|
13 |
+
freedom to share and change it. By contrast, the GNU General Public
|
14 |
+
License is intended to guarantee your freedom to share and change free
|
15 |
+
software--to make sure the software is free for all its users. This
|
16 |
+
General Public License applies to most of the Free Software
|
17 |
+
Foundation's software and to any other program whose authors commit to
|
18 |
+
using it. (Some other Free Software Foundation software is covered by
|
19 |
+
the GNU Library General Public License instead.) You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
this service if you wish), that you receive source code or can get it
|
26 |
+
if you want it, that you can change the software or use pieces of it
|
27 |
+
in new free programs; and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to make restrictions that forbid
|
30 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
31 |
+
These restrictions translate to certain responsibilities for you if you
|
32 |
+
distribute copies of the software, or if you modify it.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must give the recipients all the rights that
|
36 |
+
you have. You must make sure that they, too, receive or can get the
|
37 |
+
source code. And you must show them these terms so they know their
|
38 |
+
rights.
|
39 |
+
|
40 |
+
We protect your rights with two steps: (1) copyright the software, and
|
41 |
+
(2) offer you this license which gives you legal permission to copy,
|
42 |
+
distribute and/or modify the software.
|
43 |
+
|
44 |
+
Also, for each author's protection and ours, we want to make certain
|
45 |
+
that everyone understands that there is no warranty for this free
|
46 |
+
software. If the software is modified by someone else and passed on, we
|
47 |
+
want its recipients to know that what they have is not the original, so
|
48 |
+
that any problems introduced by others will not reflect on the original
|
49 |
+
authors' reputations.
|
50 |
+
|
51 |
+
Finally, any free program is threatened constantly by software
|
52 |
+
patents. We wish to avoid the danger that redistributors of a free
|
53 |
+
program will individually obtain patent licenses, in effect making the
|
54 |
+
program proprietary. To prevent this, we have made it clear that any
|
55 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
56 |
+
|
57 |
+
The precise terms and conditions for copying, distribution and
|
58 |
+
modification follow.
|
59 |
+
|
60 |
+
GNU GENERAL PUBLIC LICENSE
|
61 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
62 |
+
|
63 |
+
0. This License applies to any program or other work which contains
|
64 |
+
a notice placed by the copyright holder saying it may be distributed
|
65 |
+
under the terms of this General Public License. The "Program", below,
|
66 |
+
refers to any such program or work, and a "work based on the Program"
|
67 |
+
means either the Program or any derivative work under copyright law:
|
68 |
+
that is to say, a work containing the Program or a portion of it,
|
69 |
+
either verbatim or with modifications and/or translated into another
|
70 |
+
language. (Hereinafter, translation is included without limitation in
|
71 |
+
the term "modification".) Each licensee is addressed as "you".
|
72 |
+
|
73 |
+
Activities other than copying, distribution and modification are not
|
74 |
+
covered by this License; they are outside its scope. The act of
|
75 |
+
running the Program is not restricted, and the output from the Program
|
76 |
+
is covered only if its contents constitute a work based on the
|
77 |
+
Program (independent of having been made by running the Program).
|
78 |
+
Whether that is true depends on what the Program does.
|
79 |
+
|
80 |
+
1. You may copy and distribute verbatim copies of the Program's
|
81 |
+
source code as you receive it, in any medium, provided that you
|
82 |
+
conspicuously and appropriately publish on each copy an appropriate
|
83 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
84 |
+
notices that refer to this License and to the absence of any warranty;
|
85 |
+
and give any other recipients of the Program a copy of this License
|
86 |
+
along with the Program.
|
87 |
+
|
88 |
+
You may charge a fee for the physical act of transferring a copy, and
|
89 |
+
you may at your option offer warranty protection in exchange for a fee.
|
90 |
+
|
91 |
+
2. You may modify your copy or copies of the Program or any portion
|
92 |
+
of it, thus forming a work based on the Program, and copy and
|
93 |
+
distribute such modifications or work under the terms of Section 1
|
94 |
+
above, provided that you also meet all of these conditions:
|
95 |
+
|
96 |
+
a) You must cause the modified files to carry prominent notices
|
97 |
+
stating that you changed the files and the date of any change.
|
98 |
+
|
99 |
+
b) You must cause any work that you distribute or publish, that in
|
100 |
+
whole or in part contains or is derived from the Program or any
|
101 |
+
part thereof, to be licensed as a whole at no charge to all third
|
102 |
+
parties under the terms of this License.
|
103 |
+
|
104 |
+
c) If the modified program normally reads commands interactively
|
105 |
+
when run, you must cause it, when started running for such
|
106 |
+
interactive use in the most ordinary way, to print or display an
|
107 |
+
announcement including an appropriate copyright notice and a
|
108 |
+
notice that there is no warranty (or else, saying that you provide
|
109 |
+
a warranty) and that users may redistribute the program under
|
110 |
+
these conditions, and telling the user how to view a copy of this
|
111 |
+
License. (Exception: if the Program itself is interactive but
|
112 |
+
does not normally print such an announcement, your work based on
|
113 |
+
the Program is not required to print an announcement.)
|
114 |
+
|
115 |
+
These requirements apply to the modified work as a whole. If
|
116 |
+
identifiable sections of that work are not derived from the Program,
|
117 |
+
and can be reasonably considered independent and separate works in
|
118 |
+
themselves, then this License, and its terms, do not apply to those
|
119 |
+
sections when you distribute them as separate works. But when you
|
120 |
+
distribute the same sections as part of a whole which is a work based
|
121 |
+
on the Program, the distribution of the whole must be on the terms of
|
122 |
+
this License, whose permissions for other licensees extend to the
|
123 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
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 |
+
|
optimizer/wp-staging-optimizer.php
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: WP Staging Optimizer
|
4 |
+
Plugin URI: https://wp-staging.com
|
5 |
+
Description: Prevents 3rd party plugins from being loaded during WP Staging specific operations
|
6 |
+
Author: René Hermenau
|
7 |
+
Version: 1.0
|
8 |
+
Author URI: https://wp-staging.com
|
9 |
+
Credit: Original version is made by Delicious Brains (WP Migrate DB). Thank you guys!
|
10 |
+
*/
|
11 |
+
|
12 |
+
$GLOBALS['wpstg_optimizer'] = true;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Remove TGM Plugin Activation 'force_activation' admin_init action hook if present.
|
16 |
+
*
|
17 |
+
* This is to stop excluded plugins being deactivated after a migration, when a theme uses TGMPA to require a plugin to be always active.
|
18 |
+
*/
|
19 |
+
function wpstg_tgmpa_compatibility() {
|
20 |
+
$remove_function = false;
|
21 |
+
|
22 |
+
// run on wpstg page
|
23 |
+
if ( isset( $_GET['page'] ) && 'wpstg_clone' == $_GET['page'] ) {
|
24 |
+
$remove_function = true;
|
25 |
+
}
|
26 |
+
// run on wpstg ajax requests
|
27 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['action'] ) && false !== strpos( $_POST['action'], 'wpstg' ) ) {
|
28 |
+
$remove_function = true;
|
29 |
+
}
|
30 |
+
|
31 |
+
if ( $remove_function ) {
|
32 |
+
global $wp_filter;
|
33 |
+
$admin_init_functions = $wp_filter['admin_init'];
|
34 |
+
foreach ( $admin_init_functions as $priority => $functions ) {
|
35 |
+
foreach ( $functions as $key => $function ) {
|
36 |
+
// searching for function this way as can't rely on the calling class being named TGM_Plugin_Activation
|
37 |
+
if ( false !== strpos( $key, 'force_activation' ) ) {
|
38 |
+
unset( $wp_filter['admin_init'][ $priority ][ $key ] );
|
39 |
+
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
add_action( 'admin_init', 'wpstg_tgmpa_compatibility', 1 );
|
48 |
+
|
49 |
+
/**
|
50 |
+
* remove blog-active plugins
|
51 |
+
*
|
52 |
+
* @param array $plugins numerically keyed array of plugin names
|
53 |
+
*
|
54 |
+
* @return array
|
55 |
+
*/
|
56 |
+
function wpstg_exclude_plugins( $plugins ) {
|
57 |
+
if ( ! is_array( $plugins ) || empty( $plugins ) ) {
|
58 |
+
return $plugins;
|
59 |
+
}
|
60 |
+
|
61 |
+
if ( ! wpstg_is_compatibility_mode_request() ) {
|
62 |
+
return $plugins;
|
63 |
+
}
|
64 |
+
|
65 |
+
$blacklist_plugins = wpstg_get_blacklist_plugins();
|
66 |
+
|
67 |
+
if ( ! empty( $blacklist_plugins ) ) {
|
68 |
+
foreach ( $plugins as $key => $plugin ) {
|
69 |
+
if ( false !== strpos( $plugin, 'wp-staging' ) || ! isset( $blacklist_plugins[ $plugin ] ) ) {
|
70 |
+
continue;
|
71 |
+
}
|
72 |
+
unset( $plugins[ $key ] );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
return $plugins;
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
add_filter( 'option_active_plugins', 'wpstg_exclude_plugins' );
|
81 |
+
|
82 |
+
/**
|
83 |
+
* remove network-active plugins
|
84 |
+
*
|
85 |
+
* @param array $plugins array of plugins keyed by name (name=>timestamp pairs)
|
86 |
+
*
|
87 |
+
* @return array
|
88 |
+
*/
|
89 |
+
function wpstg_exclude_site_plugins( $plugins ) {
|
90 |
+
if ( ! is_array( $plugins ) || empty( $plugins ) ) {
|
91 |
+
return $plugins;
|
92 |
+
}
|
93 |
+
|
94 |
+
if ( ! wpstg_is_compatibility_mode_request() ) {
|
95 |
+
return $plugins;
|
96 |
+
}
|
97 |
+
|
98 |
+
$blacklist_plugins = wpstg_get_blacklist_plugins();
|
99 |
+
|
100 |
+
if ( ! empty( $blacklist_plugins ) ) {
|
101 |
+
foreach ( array_keys( $plugins ) as $plugin ) {
|
102 |
+
if ( false !== strpos( $plugin, 'wp-staging' ) || ! isset( $blacklist_plugins[ $plugin ] ) ) {
|
103 |
+
continue;
|
104 |
+
}
|
105 |
+
unset( $plugins[ $plugin ] );
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
return $plugins;
|
110 |
+
}
|
111 |
+
|
112 |
+
add_filter( 'site_option_active_sitewide_plugins', 'wpstg_exclude_site_plugins' );
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Should the current request be processed by Compatibility Mode?
|
116 |
+
*
|
117 |
+
* @return bool
|
118 |
+
*/
|
119 |
+
function wpstg_is_compatibility_mode_request() {
|
120 |
+
if ( ! defined( 'DOING_AJAX' ) ||
|
121 |
+
! DOING_AJAX ||
|
122 |
+
! isset( $_POST['action'] ) ||
|
123 |
+
false === strpos( $_POST['action'], 'wpstg' )
|
124 |
+
) {
|
125 |
+
return false;
|
126 |
+
}
|
127 |
+
return true;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Returns an array of plugin slugs to be blacklisted.
|
132 |
+
*
|
133 |
+
* @return array
|
134 |
+
*/
|
135 |
+
function wpstg_get_blacklist_plugins() {
|
136 |
+
$blacklist_plugins = array();
|
137 |
+
|
138 |
+
//@todo use this later for multisites
|
139 |
+
//$wpstg_options = get_site_option( 'wpstg_settings' );
|
140 |
+
$wpstg_options = get_option( 'wpstg_settings' );
|
141 |
+
|
142 |
+
if ( ! empty( $wpstg_options['blacklist_plugins'] ) ) {
|
143 |
+
$blacklist_plugins = array_flip( $wpstg_options['blacklist_plugins'] );
|
144 |
+
}
|
145 |
+
|
146 |
+
return $blacklist_plugins;
|
147 |
+
}
|
readme.txt
ADDED
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== WP Staging - DB & file duplicator & migration ===
|
2 |
+
|
3 |
+
Author URL: https://wordpress.org/plugins/wp-staging
|
4 |
+
Plugin URL: https://wordpress.org/plugins/wp-staging
|
5 |
+
Contributors: ReneHermi, WP-Staging
|
6 |
+
Donate link: https://wordpress.org/plugins/wp-staging
|
7 |
+
License: GPLv2 or later
|
8 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
+
Tags: staging, migration, wordpress migration, wordpress staging, development, migrate, cloning, clone, database export, database find replace, database serialization, duplication, duplicator, duplicate, site duplicate, duplicate posts, db backup, file backup, backup, db migration, db restore, website backup, website staging, website deploy, staging, admin, page, content, plugin, media, backup, test, test site, testing, sandbox, widget, post, plugin, admin, posts, sidebar, shortcode, google, administration, ajax, api, authentication, blog, code, comments, contact, dashboard, multisite, theme
|
10 |
+
Requires at least: 3.6+
|
11 |
+
Tested up to: 4.4.1
|
12 |
+
Stable tag: 1.0.0
|
13 |
+
|
14 |
+
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
15 |
+
|
16 |
+
== Description ==
|
17 |
+
|
18 |
+
<strong>This cloning and staging plugin is well tested but still work in progress! <br>
|
19 |
+
If you find a bug please open a ticket in the [support request](https://wordpress.org/support/plugin/wp-staging/ "support forum"). Every issue will be fixed asap!
|
20 |
+
</strong>
|
21 |
+
<br /><br />
|
22 |
+
<strong>Note: </strong> This plugin is not able to push back your changes to the live site at the moment! This is a feature i am already working on.
|
23 |
+
<br /> <br />
|
24 |
+
|
25 |
+
|
26 |
+
<blockquote>
|
27 |
+
<h4> WP Staging for WordPress Migration </h4>
|
28 |
+
This duplicator plugin allows you to create an staging or development environment in seconds* <br /> <br />
|
29 |
+
It creates a file clone of your website into a subfolder of your current WordPress installation with an entire copy of your database.
|
30 |
+
This sounds pretty simple and yes it is! All the hard time consumptive database and file copy stuff including url replacements is done in the background.
|
31 |
+
<br /> <br />
|
32 |
+
I created this plugin because all other solutions are way too complex, overloaded with dozens of options or having server requirements which are not available on most shared hosting solutions.
|
33 |
+
All these reasons prevent user from testing new plugins and updates first before installing them on their live website, so its time to release a plugin which has the potential to be merged into everyone´s wordpress workflow.
|
34 |
+
<br /> <br />
|
35 |
+
<p><small><em>* Time of creation depends on size of your database and file size</em></small></p>
|
36 |
+
</blockquote>
|
37 |
+
|
38 |
+
WP Staging helps you to prevent your website from being broken or unavailable because of installing untested plugin updates!
|
39 |
+
|
40 |
+
[youtube https://www.youtube.com/watch?v=Ye3fC6cdB3A]
|
41 |
+
|
42 |
+
= Main Features =
|
43 |
+
|
44 |
+
* <strong>Easy: </strong> Staging migration applicable for everyone. No configuration needed!
|
45 |
+
* <strong>Fast: </strong> Migration process lasts only a few seconds or minutes, depending on the site's size and server I/O power
|
46 |
+
* <strong>Safe: </strong> Access to staging site is granted for administrators only.
|
47 |
+
<br /><br />
|
48 |
+
<strong>More safe:</strong>
|
49 |
+
<br>
|
50 |
+
* Admin bar reflects that you are working on a staging site
|
51 |
+
* Extensive logging if duplication and migration process fails.
|
52 |
+
|
53 |
+
= What does not work or is not tested when running wordpress migration? =
|
54 |
+
|
55 |
+
* Wordpress migration of wordpress multisites (not tested)
|
56 |
+
* WordPress duplicating process on windows server (not tested but will probably work)
|
57 |
+
Edit: Duplication on windows server seems to be working well: [Read more](https://wordpress.org/support/topic/wont-copy-files?replies=5 "Read more")
|
58 |
+
|
59 |
+
|
60 |
+
<strong>Change your workflow of updating themes and plugins data:</strong>
|
61 |
+
|
62 |
+
1. Use WP Staging for migration of a production website to a clone site for staging purposes
|
63 |
+
2. Customize theme, configuration and plugins or install new plugins
|
64 |
+
3. Test everything on your staging site first
|
65 |
+
4. Everything running as expected? You are on the save side for migration of all these modifications to your production site!
|
66 |
+
|
67 |
+
|
68 |
+
<h3> Why should i use a staging website? </h3>
|
69 |
+
|
70 |
+
Plugin updates and theme customizations should be tested on a staging platform first. Its recommended to have the staging platform on the same server where the production website is located.
|
71 |
+
When you run a plugin update or plan to install a new one, it is a necessary task to check first the modifications on a clone of your production website.
|
72 |
+
This makes sure that any modifications is working on your website without throwing unexpected errors or preventing your site from loading. (Better known as the wordpress blank page error)
|
73 |
+
|
74 |
+
Testing a plugin update before installing it in live environment isn´t done very often by most user because existing staging solutions are too complex and need a lot of time to create a
|
75 |
+
up-to-date copy of your website.
|
76 |
+
|
77 |
+
Some people are also afraid of installing plugins updates because they follow the rule "never touch a running system" with having in mind that untested updates are increasing the risk of breaking their site.
|
78 |
+
I totally understand this and i am guilty as well here, but unfortunately this leads to one of the main reasons why WordPress installations are often outdated, not updated at all and unsecure due to this non-update behavior.
|
79 |
+
|
80 |
+
<strong> I think its time to change this, so i created "WP Staging" for WordPress migration of staging sites</strong>
|
81 |
+
|
82 |
+
<h3> Can´t i just use my local wordpress development copy for testing like xampp / lampp? </h3>
|
83 |
+
|
84 |
+
Nope! If your local hardware and software environment is not a 100% exact clone of your production server there is NO guarantee that every aspect
|
85 |
+
of your local copy is working on your live website exactely as you would expect it.
|
86 |
+
There are some obvious things like differences in the config of php and the server you are running but even such non obvious settings like the amount of ram or the
|
87 |
+
the cpu performance can lead to unexpected results on your production website.
|
88 |
+
There are dozens of other possible cause of failure which can not be handled well when you are testing your changes on a local staging platform.
|
89 |
+
|
90 |
+
This is were WP Staging steps in... Site cloning and staging site creation simplified!
|
91 |
+
|
92 |
+
<h3>I just want to migrate the database from one installation to another</h3>
|
93 |
+
If you want to migrate your local database to a already existing production site you can use a tool like WP Migrate DB.
|
94 |
+
WP Staging is only for creating a staging site with latest data from your production site. So it goes the opposite way of WP Migrate DB.
|
95 |
+
Both tools are excellent cooperating eachother.
|
96 |
+
|
97 |
+
<h3>What are the benefits compared to a plugin like Duplicator?</h3>
|
98 |
+
At first, i love the [Duplicator plugin](https://wordpress.org/plugins/duplicator/ "Duplicator plugin"). Duplicator is a great tool for migrating from development site to production one or from production site to development one.
|
99 |
+
The downside is that Duplicator needs adjustments, manually interventions and prerequirements for this. Duplicator also needs some skills to be able to create a development / staging site, where WP Staging does not need more than a click from you.
|
100 |
+
However, Duplicator is best placed to be a tool for first-time creation of your production site. This is something where it is very handy and powerful.
|
101 |
+
|
102 |
+
So, if you have created a local or webhosted development site and you need to migrate this site the first time to your production domain than you are doing nothing wrong with using
|
103 |
+
the Duplicator plugin! If you need all you latest production data like posts, updated plugins, theme data and styles in a testing environment than i recommend to use WP Staging instead!
|
104 |
+
|
105 |
+
= I need you feedback =
|
106 |
+
This plugin has been done in hundreds of hours to work on even the smallest shared webhosting package but i am limited in testing this only on a handful of different server so i need your help:
|
107 |
+
Please open a [support request](https://wordpress.org/support/plugin/wp-staging/ "support request") and describe your problem exactely. In wp-content/wp-staging/logs you find extended logfiles. Have a look at them and let me know the error-thrown lines.
|
108 |
+
|
109 |
+
|
110 |
+
= Important =
|
111 |
+
|
112 |
+
Per default the staging site will have permalinks disabled because the staging site will be cloned into a subfolder and regular permalinks are not working
|
113 |
+
without doing changes to your .htaccess or nginx.conf.
|
114 |
+
In the majority of cases this is abolutely fine for a staging platform and you still will be able to test new plugins and do some theme changes on your staging platform.
|
115 |
+
If you need the same permalink stucture on your staging platform as you have in your prodcution website you have to create a custom .htaccess for apache webserver
|
116 |
+
or to adjust your nginx.conf.
|
117 |
+
|
118 |
+
|
119 |
+
= How to install and setup? =
|
120 |
+
Install it via the admin dashboard and to 'Plugins', click 'Add New' and search the plugins for 'Staging'. Install the plugin with 'Install Now'.
|
121 |
+
After installation goto the settings page 'Staging' and do your adjustments there.
|
122 |
+
|
123 |
+
|
124 |
+
== Frequently Asked Questions ==
|
125 |
+
|
126 |
+
|
127 |
+
== Official Site ==
|
128 |
+
|
129 |
+
|
130 |
+
== Installation ==
|
131 |
+
1. Download the file "wp-staging" , unzip and place it in your wp-content/plugins/wp-staging folder. You can alternatively upload and install it via the WordPress plugin backend.
|
132 |
+
2. Activate the plugin through the 'Plugins' menu in WordPress.
|
133 |
+
3. Start Plugins->Staging
|
134 |
+
|
135 |
+
== Screenshots ==
|
136 |
+
|
137 |
+
1. Step 1. Create new WordPress staging site
|
138 |
+
2. Step 2. Scanning your website for files and database tables
|
139 |
+
3. Step 3. Wordpress Staging site creation in progress
|
140 |
+
4. Finish!
|
141 |
+
|
142 |
+
== Changelog ==
|
143 |
+
|
144 |
+
= 1.0.0 =
|
145 |
+
* Fix: Do not follow symlinks during file copy process
|
146 |
+
* Fix: css error
|
147 |
+
* Fix: Show "not-compatible" notice only when blog version is higher than plugin tested version.
|
148 |
+
* Fix: undefined var $size
|
149 |
+
* Fix: Check if $path is null before writing to remaining_files.json
|
150 |
+
* Fix: $db_helper undefined message
|
151 |
+
* Fix: Skip non utf8 encoded files during copying process
|
152 |
+
|
153 |
+
= 0.9.9 =
|
154 |
+
* Fix: Use back ticks for table names to prevent copy errors when table names are containing hyphens or similar special characters
|
155 |
+
* New: Load option to reduce cpu load and to lower the risk of killed ajax calls because of security flooding mechanism (Prevent 405 errors: not allowed)
|
156 |
+
* Tweak: Load non minified js file when WPSTG debug mode is enabled
|
157 |
+
|
158 |
+
= 0.9.8 =
|
159 |
+
* New: Tested up to WP 4.4
|
160 |
+
* New: New debug mode in settings
|
161 |
+
* Tweak: Check if url's in staging's wp-config.php needs a replacement and do so.
|
162 |
+
* Fix: Prevent fatal error and end of copying process. Make sure files are writable before trying to copy them
|
163 |
+
|
164 |
+
= 0.9.7 =
|
165 |
+
* Fix: Change backend link to https://wordpress.org/plugins/wp-staging/ when using an outdated version of the plugin
|
166 |
+
* New: Tested up to WP 4.3.1
|
167 |
+
|
168 |
+
= 0.9.6 =
|
169 |
+
* New: Show notice when there is not enough disk space for a clone
|
170 |
+
* Fix: PHP Error on 32bit systems: "disk_free_space(): Value too large for defined data type"
|
171 |
+
* Fix: Copying process of larges files gets interupted sometimes due undefined variable
|
172 |
+
* Fix: Define width and height for the system info export formular
|
173 |
+
* Fix: Cannot redeclare deleteDirectory()
|
174 |
+
|
175 |
+
= 0.9.5 =
|
176 |
+
* Fix: Option for cloning sites which are moved into a subdirectory was not working on several systems
|
177 |
+
* New: WordPress Migration tested up to WP 4.3
|
178 |
+
|
179 |
+
= 0.9.4 =
|
180 |
+
* Fix: Large files are copied partly
|
181 |
+
* Fix: js error xhr.statusText not defined
|
182 |
+
* New: Option for cloning sites which are moved into a subdirectory. Read more: https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
|
183 |
+
* New: Create an alternative copy method for large files
|
184 |
+
* New: Add new author WP-Staging to the readme.txt and to the wordpress repository
|
185 |
+
|
186 |
+
= 0.9.3 =
|
187 |
+
* Fix: Rating container is not shown because of wrong wordpress option name
|
188 |
+
* Tweak: Change color of the rating links
|
189 |
+
|
190 |
+
= 0.9.2 =
|
191 |
+
* Fix: A conflict with the plugin WP Migrate DB (Pro)
|
192 |
+
* Fix: Limit the staging name to maximum of 16 characters for migration process
|
193 |
+
|
194 |
+
= 0.9.1 =
|
195 |
+
* Fix: Change search and replace function for table wp_options when running migration. This prevented on some sites the moving of serialized theme data
|
196 |
+
|
197 |
+
= 0.9 =
|
198 |
+
* New: Release
|
199 |
+
|
200 |
+
== Upgrade Notice ==
|
201 |
+
|
202 |
+
= 0.9.7 =
|
203 |
+
0.9.7 <strong> * New: Tested up to wp 4.3.1</strong>
|
templates/wpstg.min.css
ADDED
File without changes
|
uninstall.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Uninstall WP-Staging
|
4 |
+
*
|
5 |
+
* @package WPSTG
|
6 |
+
* @subpackage Uninstall
|
7 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 0.9.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) exit;
|
14 |
+
|
15 |
+
// Load WPSTG file
|
16 |
+
include_once( 'wp-staging.php' );
|
17 |
+
|
18 |
+
global $wpdb, $wpstg_options;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Delete all the Plugin Options
|
22 |
+
*
|
23 |
+
*/
|
24 |
+
if( wpstg_get_option( 'uninstall_on_delete' ) ) {
|
25 |
+
delete_option('wpstg_version_upgraded_from');
|
26 |
+
delete_option('wpstg_version');
|
27 |
+
delete_option('wpstg_installDate');
|
28 |
+
delete_option('wpstg_RatingDiv');
|
29 |
+
delete_option('wpstg_firsttime');
|
30 |
+
delete_option('wpstg_is_staging_site');
|
31 |
+
delete_option('wpstg_hide_beta');
|
32 |
+
delete_option('wpstg_settings');
|
33 |
+
delete_option( 'wpstg_existing_clones' );
|
34 |
+
}
|
35 |
+
|
wp-staging.php
ADDED
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: WP Staging - Create a staging clone site for testing & developing
|
4 |
+
* Plugin URI: wordpress.org/plugins/wp-staging
|
5 |
+
* Description: WP-Staging - Create a staging clone site for testing & developing
|
6 |
+
* Author: WP-Staging, René Hermenau
|
7 |
+
* Author URI: https://wordpress.org/plugins/wp-staging
|
8 |
+
* Version: 0.9.9
|
9 |
+
* Text Domain: wpstg
|
10 |
+
* Domain Path: languages
|
11 |
+
|
12 |
+
*
|
13 |
+
* WP-Staging is free software: you can redistribute it and/or modify
|
14 |
+
* it under the terms of the GNU General Public License as published by
|
15 |
+
* the Free Software Foundation, either version 2 of the License, or
|
16 |
+
* any later version.
|
17 |
+
*
|
18 |
+
* WP-Staging is distributed in the hope that it will be useful,
|
19 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
+
* GNU General Public License for more details.
|
22 |
+
*
|
23 |
+
* You should have received a copy of the GNU General Public License
|
24 |
+
* along with Staging. If not, see <http://www.gnu.org/licenses/>.
|
25 |
+
*
|
26 |
+
* @package WPSTG
|
27 |
+
* @category Core
|
28 |
+
* @author René Hermenau
|
29 |
+
* @version 0.9.1
|
30 |
+
*/
|
31 |
+
// Exit if accessed directly
|
32 |
+
if (!defined('ABSPATH'))
|
33 |
+
exit;
|
34 |
+
|
35 |
+
// Plugin version
|
36 |
+
if (!defined('WPSTG_VERSION')) {
|
37 |
+
define('WPSTG_VERSION', '0.9.9');
|
38 |
+
}
|
39 |
+
// Plugin version
|
40 |
+
if (!defined('WPSTG_WP_COMPATIBLE')) {
|
41 |
+
define('WPSTG_WP_COMPATIBLE', '4.4.1');
|
42 |
+
}
|
43 |
+
|
44 |
+
if (!class_exists('wpstaging')) :
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Main wpstg Class
|
48 |
+
*
|
49 |
+
* @since 0.9.0
|
50 |
+
*/
|
51 |
+
final class wpstaging {
|
52 |
+
/** Singleton ************************************************************ */
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @var WP-Staging The one and only WP-Staging
|
56 |
+
* @since 1.0
|
57 |
+
*/
|
58 |
+
private static $instance;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* WPSTG HTML Element Helper Object
|
62 |
+
*
|
63 |
+
* @var object
|
64 |
+
* @since 2.0.0
|
65 |
+
*/
|
66 |
+
//public $html;
|
67 |
+
|
68 |
+
/* WPSTG LOGGER Class
|
69 |
+
*
|
70 |
+
*/
|
71 |
+
public $logger;
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Main WP-Staging Instance
|
77 |
+
*
|
78 |
+
* Insures that only one instance of wp-staging exists in memory at any one
|
79 |
+
* time. Also prevents needing to define globals all over the place.
|
80 |
+
*
|
81 |
+
* @since 1.0
|
82 |
+
* @static
|
83 |
+
* @staticvar array $instance
|
84 |
+
* @uses wp-staging::setup_constants() Setup the constants needed
|
85 |
+
* @uses wp-staging::includes() Include the required files
|
86 |
+
* @uses wp-staging::load_textdomain() load the language files
|
87 |
+
* @see WPSTG()
|
88 |
+
* @return The one true wp-staging
|
89 |
+
*/
|
90 |
+
public static function instance() {
|
91 |
+
if (!isset(self::$instance) && !( self::$instance instanceof wpstaging )) {
|
92 |
+
self::$instance = new wpstaging;
|
93 |
+
self::$instance->setup_constants();
|
94 |
+
self::$instance->includes();
|
95 |
+
self::$instance->load_textdomain();
|
96 |
+
//self::$instance->html = new WPSTG_HTML_Elements();
|
97 |
+
self::$instance->logger = new wpstgLogger("wpstglog_" . date("Y-m-d") . ".log", wpstgLogger::INFO);
|
98 |
+
}
|
99 |
+
return self::$instance;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Throw error on object clone
|
104 |
+
*
|
105 |
+
* The whole idea of the singleton design pattern is that there is a single
|
106 |
+
* object therefore, we don't want the object to be cloned.
|
107 |
+
*
|
108 |
+
* @since 1.0
|
109 |
+
* @access protected
|
110 |
+
* @return void
|
111 |
+
*/
|
112 |
+
public function __clone() {
|
113 |
+
// Cloning instances of the class is forbidden
|
114 |
+
_doing_it_wrong(__FUNCTION__, __('Cheatin’ huh?', 'WPSTG'), '1.0');
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Disable unserializing of the class
|
119 |
+
*
|
120 |
+
* @since 1.0
|
121 |
+
* @access protected
|
122 |
+
* @return void
|
123 |
+
*/
|
124 |
+
public function __wakeup() {
|
125 |
+
// Unserializing instances of the class is forbidden
|
126 |
+
_doing_it_wrong(__FUNCTION__, __('Cheatin’ huh?', 'WPSTG'), '1.0');
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Setup plugin constants
|
131 |
+
*
|
132 |
+
* @access private
|
133 |
+
* @since 1.0
|
134 |
+
* @return void
|
135 |
+
*/
|
136 |
+
private function setup_constants() {
|
137 |
+
global $wpdb;
|
138 |
+
|
139 |
+
// Plugin Folder Path
|
140 |
+
if (!defined('WPSTG_PLUGIN_DIR')) {
|
141 |
+
define('WPSTG_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
142 |
+
}
|
143 |
+
|
144 |
+
// Plugin Folder URL
|
145 |
+
if (!defined('WPSTG_PLUGIN_URL')) {
|
146 |
+
define('WPSTG_PLUGIN_URL', plugin_dir_url(__FILE__));
|
147 |
+
}
|
148 |
+
|
149 |
+
// Plugin Root File
|
150 |
+
if (!defined('WPSTG_PLUGIN_FILE')) {
|
151 |
+
define('WPSTG_PLUGIN_FILE', __FILE__);
|
152 |
+
}
|
153 |
+
|
154 |
+
// Plugin database
|
155 |
+
// Plugin Root File
|
156 |
+
if (!defined('WPSTG_TABLE')) {
|
157 |
+
define('WPSTG_TABLE', $wpdb->prefix . 'wp-staging');
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Include required files
|
163 |
+
*
|
164 |
+
* @access private
|
165 |
+
* @since 1.0
|
166 |
+
* @return void
|
167 |
+
*/
|
168 |
+
private function includes() {
|
169 |
+
global $wpstg_options;
|
170 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/logger.php';
|
171 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/staging-functions.php';
|
172 |
+
if (is_admin() || ( defined('WP_CLI') && WP_CLI )) {
|
173 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/settings/register-settings.php';
|
174 |
+
$wpstg_options = wpstg_get_settings(); // Load it on top of all
|
175 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/admin-actions.php';
|
176 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/admin-notices.php';
|
177 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/admin-footer.php';
|
178 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/admin-pages.php';
|
179 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/plugins.php';
|
180 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/welcome.php';
|
181 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/settings/display-settings.php';
|
182 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/settings/contextual-help.php';
|
183 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/install.php';
|
184 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/tools.php';
|
185 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/admin/upload-functions.php';
|
186 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/scripts.php';
|
187 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/class-wpstg-license-handler.php';
|
188 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/debug/classes/wpstgDebug.interface.php';
|
189 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/debug/classes/wpstgDebug.class.php';
|
190 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/wpstg-sanitize.php';
|
191 |
+
require_once WPSTG_PLUGIN_DIR . 'includes/template-functions.php';
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Loads the plugin language files
|
197 |
+
*
|
198 |
+
* @access public
|
199 |
+
* @since 1.0
|
200 |
+
* @return void
|
201 |
+
*/
|
202 |
+
public function load_textdomain() {
|
203 |
+
// Set filter for plugin's languages directory
|
204 |
+
$wpstg_lang_dir = dirname(plugin_basename(WPSTG_PLUGIN_FILE)) . '/languages/';
|
205 |
+
$wpstg_lang_dir = apply_filters('wpstg_languages_directory', $wpstg_lang_dir);
|
206 |
+
|
207 |
+
// Traditional WordPress plugin locale filter
|
208 |
+
$locale = apply_filters('plugin_locale', get_locale(), 'wpstg');
|
209 |
+
$mofile = sprintf('%1$s-%2$s.mo', 'wpstg', $locale);
|
210 |
+
|
211 |
+
// Setup paths to current locale file
|
212 |
+
$mofile_local = $wpstg_lang_dir . $mofile;
|
213 |
+
$mofile_global = WP_LANG_DIR . '/wpstg/' . $mofile;
|
214 |
+
|
215 |
+
if (file_exists($mofile_global)) {
|
216 |
+
// Look in global /wp-content/languages/WPSTG folder
|
217 |
+
load_textdomain('wpstg', $mofile_global);
|
218 |
+
} elseif (file_exists($mofile_local)) {
|
219 |
+
// Look in local /wp-content/plugins/wp-staging/languages/ folder
|
220 |
+
load_textdomain('wpstg', $mofile_local);
|
221 |
+
} else {
|
222 |
+
// Load the default language files
|
223 |
+
load_plugin_textdomain('wpstg', false, $wpstg_lang_dir);
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
}
|
228 |
+
|
229 |
+
endif; // End if class_exists check
|
230 |
+
|
231 |
+
/**
|
232 |
+
* The main function responsible for returning the one true wpstaging
|
233 |
+
* Instance to functions everywhere.
|
234 |
+
*
|
235 |
+
* Use this function like you would a global variable, except without needing
|
236 |
+
* to declare the global.
|
237 |
+
*
|
238 |
+
* Example: <?php $WPSTG = WPSTG(); ?>
|
239 |
+
*
|
240 |
+
* @since 0.9.0
|
241 |
+
* @return object The one true wpstaging Instance
|
242 |
+
*/
|
243 |
+
function WPSTG() {
|
244 |
+
return wpstaging::instance();
|
245 |
+
}
|
246 |
+
|
247 |
+
// Get WPSTG Running
|
248 |
+
WPSTG();
|