Version Description
Download this release
Release Info
Developer | theluckywp |
Plugin | LuckyWP Table of Contents |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- LICENSE.txt +339 -0
- admin/Admin.php +198 -0
- admin/assets/main.min.css +1 -0
- admin/assets/main.min.js +1 -0
- admin/controllers/EditorBlockController.php +78 -0
- admin/controllers/MetaboxController.php +83 -0
- admin/controllers/SettingsController.php +14 -0
- admin/controllers/ShortcodeController.php +82 -0
- admin/forms/CustomizeForm.php +264 -0
- admin/views/settings/index.php +9 -0
- admin/widgets/OverrideColorBadge.php +19 -0
- admin/widgets/PostTypes.php +46 -0
- admin/widgets/customizeModal/CustomizeModal.php +41 -0
- admin/widgets/customizeModal/views/modal.php +497 -0
- admin/widgets/customizeSuccess/CustomizeSuccess.php +21 -0
- admin/widgets/customizeSuccess/views/widget.php +12 -0
- admin/widgets/fontSizeField/FontSizeField.php +47 -0
- admin/widgets/fontSizeField/views/widget.php +30 -0
- admin/widgets/metabox/Metabox.php +24 -0
- admin/widgets/metabox/views/box.php +50 -0
- admin/widgets/widthField/WidthField.php +43 -0
- admin/widgets/widthField/views/widget.php +27 -0
- config/plugin.php +29 -0
- config/settings.php +309 -0
- core/Core.php +65 -0
- core/admin/AdminController.php +48 -0
- core/admin/helpers/AdminHtml.php +84 -0
- core/admin/helpers/AdminUrl.php +47 -0
- core/base/BaseObject.php +65 -0
- core/base/BasePlugin.php +98 -0
- core/base/Container.php +160 -0
- core/base/Controller.php +74 -0
- core/base/Model.php +311 -0
- core/base/Request.php +37 -0
- core/base/ServiceLocator.php +111 -0
- core/base/View.php +83 -0
- core/base/ViewContextInterface.php +13 -0
- core/base/Widget.php +51 -0
- core/front/BaseFront.php +66 -0
- core/helpers/ArrayHelper.php +72 -0
- core/helpers/Html.php +323 -0
- core/helpers/Json.php +27 -0
- core/validators/BooleanValidator.php +53 -0
- core/validators/FilterValidator.php +23 -0
- core/validators/InlineValidator.php +26 -0
- core/validators/RangeValidator.php +36 -0
- core/validators/RequiredValidator.php +31 -0
- core/validators/Validator.php +175 -0
- core/wp/Settings.php +551 -0
- front/Front.php +162 -0
- front/assets/main.min.css +1 -0
- front/assets/main.min.js +1 -0
- front/views/body.php +36 -0
- front/views/items.php +19 -0
- functions.php +26 -0
- languages/lwptoc-ru_RU.mo +0 -0
- languages/lwptoc.pot +468 -0
- luckywp-table-of-contents.php +34 -0
- lwptocAutoloader.php +95 -0
- plugin/Activation.php +20 -0
- plugin/Plugin.php +233 -0
- plugin/PostSettings.php +263 -0
- plugin/Settings.php +301 -0
- plugin/Shortcode.php +442 -0
- plugin/editorBlock/EditorBlock.php +46 -0
- plugin/editorBlock/editorBlock.min.js +1 -0
- plugin/editorBlock/src/editorBlock.js +105 -0
- plugin/mcePlugin/McePlugin.php +66 -0
- plugin/mcePlugin/mce.min.css +1 -0
- plugin/mcePlugin/plugin.min.js +1 -0
- readme.txt +88 -0
- uninstall.php +9 -0
LICENSE.txt
ADDED
@@ -0,0 +1,339 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
7 |
+
of this license document, but changing it is not allowed.
|
8 |
+
|
9 |
+
Preamble
|
10 |
+
|
11 |
+
The licenses for most software are designed to take away your
|
12 |
+
freedom to share and change it. By contrast, the GNU General Public
|
13 |
+
License is intended to guarantee your freedom to share and change free
|
14 |
+
software--to make sure the software is free for all its users. This
|
15 |
+
General Public License applies to most of the Free Software
|
16 |
+
Foundation's software and to any other program whose authors commit to
|
17 |
+
using it. (Some other Free Software Foundation software is covered by
|
18 |
+
the GNU Lesser General Public License instead.) You can apply it to
|
19 |
+
your programs, too.
|
20 |
+
|
21 |
+
When we speak of free software, we are referring to freedom, not
|
22 |
+
price. Our General Public Licenses are designed to make sure that you
|
23 |
+
have the freedom to distribute copies of free software (and charge for
|
24 |
+
this service if you wish), that you receive source code or can get it
|
25 |
+
if you want it, that you can change the software or use pieces of it
|
26 |
+
in new free programs; and that you know you can do these things.
|
27 |
+
|
28 |
+
To protect your rights, we need to make restrictions that forbid
|
29 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
30 |
+
These restrictions translate to certain responsibilities for you if you
|
31 |
+
distribute copies of the software, or if you modify it.
|
32 |
+
|
33 |
+
For example, if you distribute copies of such a program, whether
|
34 |
+
gratis or for a fee, you must give the recipients all the rights that
|
35 |
+
you have. You must make sure that they, too, receive or can get the
|
36 |
+
source code. And you must show them these terms so they know their
|
37 |
+
rights.
|
38 |
+
|
39 |
+
We protect your rights with two steps: (1) copyright the software, and
|
40 |
+
(2) offer you this license which gives you legal permission to copy,
|
41 |
+
distribute and/or modify the software.
|
42 |
+
|
43 |
+
Also, for each author's protection and ours, we want to make certain
|
44 |
+
that everyone understands that there is no warranty for this free
|
45 |
+
software. If the software is modified by someone else and passed on, we
|
46 |
+
want its recipients to know that what they have is not the original, so
|
47 |
+
that any problems introduced by others will not reflect on the original
|
48 |
+
authors' reputations.
|
49 |
+
|
50 |
+
Finally, any free program is threatened constantly by software
|
51 |
+
patents. We wish to avoid the danger that redistributors of a free
|
52 |
+
program will individually obtain patent licenses, in effect making the
|
53 |
+
program proprietary. To prevent this, we have made it clear that any
|
54 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
55 |
+
|
56 |
+
The precise terms and conditions for copying, distribution and
|
57 |
+
modification follow.
|
58 |
+
|
59 |
+
GNU GENERAL PUBLIC LICENSE
|
60 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
+
|
62 |
+
0. This License applies to any program or other work which contains
|
63 |
+
a notice placed by the copyright holder saying it may be distributed
|
64 |
+
under the terms of this General Public License. The "Program", below,
|
65 |
+
refers to any such program or work, and a "work based on the Program"
|
66 |
+
means either the Program or any derivative work under copyright law:
|
67 |
+
that is to say, a work containing the Program or a portion of it,
|
68 |
+
either verbatim or with modifications and/or translated into another
|
69 |
+
language. (Hereinafter, translation is included without limitation in
|
70 |
+
the term "modification".) Each licensee is addressed as "you".
|
71 |
+
|
72 |
+
Activities other than copying, distribution and modification are not
|
73 |
+
covered by this License; they are outside its scope. The act of
|
74 |
+
running the Program is not restricted, and the output from the Program
|
75 |
+
is covered only if its contents constitute a work based on the
|
76 |
+
Program (independent of having been made by running the Program).
|
77 |
+
Whether that is true depends on what the Program does.
|
78 |
+
|
79 |
+
1. You may copy and distribute verbatim copies of the Program's
|
80 |
+
source code as you receive it, in any medium, provided that you
|
81 |
+
conspicuously and appropriately publish on each copy an appropriate
|
82 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
83 |
+
notices that refer to this License and to the absence of any warranty;
|
84 |
+
and give any other recipients of the Program a copy of this License
|
85 |
+
along with the Program.
|
86 |
+
|
87 |
+
You may charge a fee for the physical act of transferring a copy, and
|
88 |
+
you may at your option offer warranty protection in exchange for a fee.
|
89 |
+
|
90 |
+
2. You may modify your copy or copies of the Program or any portion
|
91 |
+
of it, thus forming a work based on the Program, and copy and
|
92 |
+
distribute such modifications or work under the terms of Section 1
|
93 |
+
above, provided that you also meet all of these conditions:
|
94 |
+
|
95 |
+
a) You must cause the modified files to carry prominent notices
|
96 |
+
stating that you changed the files and the date of any change.
|
97 |
+
|
98 |
+
b) You must cause any work that you distribute or publish, that in
|
99 |
+
whole or in part contains or is derived from the Program or any
|
100 |
+
part thereof, to be licensed as a whole at no charge to all third
|
101 |
+
parties under the terms of this License.
|
102 |
+
|
103 |
+
c) If the modified program normally reads commands interactively
|
104 |
+
when run, you must cause it, when started running for such
|
105 |
+
interactive use in the most ordinary way, to print or display an
|
106 |
+
announcement including an appropriate copyright notice and a
|
107 |
+
notice that there is no warranty (or else, saying that you provide
|
108 |
+
a warranty) and that users may redistribute the program under
|
109 |
+
these conditions, and telling the user how to view a copy of this
|
110 |
+
License. (Exception: if the Program itself is interactive but
|
111 |
+
does not normally print such an announcement, your work based on
|
112 |
+
the Program is not required to print an announcement.)
|
113 |
+
|
114 |
+
These requirements apply to the modified work as a whole. If
|
115 |
+
identifiable sections of that work are not derived from the Program,
|
116 |
+
and can be reasonably considered independent and separate works in
|
117 |
+
themselves, then this License, and its terms, do not apply to those
|
118 |
+
sections when you distribute them as separate works. But when you
|
119 |
+
distribute the same sections as part of a whole which is a work based
|
120 |
+
on the Program, the distribution of the whole must be on the terms of
|
121 |
+
this License, whose permissions for other licensees extend to the
|
122 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
123 |
+
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
+
|
282 |
+
How to Apply These Terms to Your New Programs
|
283 |
+
|
284 |
+
If you develop a new program, and you want it to be of the greatest
|
285 |
+
possible use to the public, the best way to achieve this is to make it
|
286 |
+
free software which everyone can redistribute and change under these terms.
|
287 |
+
|
288 |
+
To do so, attach the following notices to the program. It is safest
|
289 |
+
to attach them to the start of each source file to most effectively
|
290 |
+
convey the exclusion of warranty; and each file should have at least
|
291 |
+
the "copyright" line and a pointer to where the full notice is found.
|
292 |
+
|
293 |
+
<one line to give the program's name and a brief idea of what it does.>
|
294 |
+
Copyright (C) <year> <name of author>
|
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.
|
admin/Admin.php
ADDED
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\admin\controllers\EditorBlockController;
|
6 |
+
use luckywp\tableOfContents\admin\controllers\MetaboxController;
|
7 |
+
use luckywp\tableOfContents\admin\controllers\SettingsController;
|
8 |
+
use luckywp\tableOfContents\admin\controllers\ShortcodeController;
|
9 |
+
use luckywp\tableOfContents\admin\widgets\metabox\Metabox;
|
10 |
+
use luckywp\tableOfContents\admin\widgets\OverrideColorBadge;
|
11 |
+
use luckywp\tableOfContents\core\admin\helpers\AdminUrl;
|
12 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
13 |
+
use luckywp\tableOfContents\core\Core;
|
14 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
15 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
16 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
17 |
+
|
18 |
+
class Admin extends BaseObject
|
19 |
+
{
|
20 |
+
|
21 |
+
protected $pageSettingsHook;
|
22 |
+
|
23 |
+
public function init()
|
24 |
+
{
|
25 |
+
if (is_admin()) {
|
26 |
+
add_action('admin_menu', [$this, 'menu']);
|
27 |
+
add_action('admin_enqueue_scripts', [$this, 'assets'], 9);
|
28 |
+
add_action('add_meta_boxes', [$this, 'addMetaBoxes']);
|
29 |
+
|
30 |
+
// Ссылки в списке плагинов
|
31 |
+
add_filter('plugin_action_links_' . Core::$plugin->basename, function ($links) {
|
32 |
+
array_unshift($links, Html::a(esc_html__('Settings', 'lwptoc'), AdminUrl::toOptions('settings')));
|
33 |
+
return $links;
|
34 |
+
});
|
35 |
+
|
36 |
+
// Контроллеры
|
37 |
+
MetaboxController::getInstance();
|
38 |
+
ShortcodeController::getInstance();
|
39 |
+
EditorBlockController::getInstance();
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
public function menu()
|
44 |
+
{
|
45 |
+
$this->pageSettingsHook = add_submenu_page(
|
46 |
+
'options-general.php',
|
47 |
+
esc_html__('Table of Contents', 'lwptoc'),
|
48 |
+
esc_html__('Table of Contents', 'lwptoc'),
|
49 |
+
'manage_options',
|
50 |
+
Core::$plugin->prefix . 'settings',
|
51 |
+
[SettingsController::className(), 'router']
|
52 |
+
);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
public function getMetaboxPostTypes()
|
59 |
+
{
|
60 |
+
if (Core::$plugin->settings->autoInsertEnable &&
|
61 |
+
$postTypes = Core::$plugin->settings->autoInsertPostTypes) {
|
62 |
+
return $postTypes;
|
63 |
+
}
|
64 |
+
return [];
|
65 |
+
}
|
66 |
+
|
67 |
+
public function addMetaBoxes()
|
68 |
+
{
|
69 |
+
if (current_user_can('edit_post') && $this->getMetaboxPostTypes()) {
|
70 |
+
add_meta_box(
|
71 |
+
Core::$plugin->prefix . '_postSettings',
|
72 |
+
esc_html__('Table of Contents', 'lwptoc'),
|
73 |
+
function ($post) {
|
74 |
+
echo Metabox::widget([
|
75 |
+
'post' => $post,
|
76 |
+
]);
|
77 |
+
},
|
78 |
+
$this->getMetaboxPostTypes(),
|
79 |
+
'side',
|
80 |
+
'low'
|
81 |
+
);
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
public function assets($hook)
|
86 |
+
{
|
87 |
+
global $post;
|
88 |
+
if (in_array($hook, [$this->pageSettingsHook, 'post.php', 'post-new.php'])) {
|
89 |
+
wp_enqueue_style('wp-color-picker');
|
90 |
+
wp_enqueue_script('wp-color-picker');
|
91 |
+
}
|
92 |
+
wp_enqueue_style(Core::$plugin->prefix . 'adminMain', Core::$plugin->url . '/admin/assets/main.min.css', [], Core::$plugin->version);
|
93 |
+
wp_enqueue_script(Core::$plugin->prefix . 'adminMain', Core::$plugin->url . '/admin/assets/main.min.js', ['jquery'], Core::$plugin->version);
|
94 |
+
wp_localize_script(Core::$plugin->prefix . 'adminMain', 'lwptocMain', [
|
95 |
+
'ajaxUrl' => admin_url('admin-ajax.php'),
|
96 |
+
'nonce' => wp_create_nonce(Core::$plugin->prefix . 'adminMain'),
|
97 |
+
'postId' => in_array($hook, ['post.php', 'post-new.php']) ? ArrayHelper::getValue($post, 'ID') : null,
|
98 |
+
'tableOfContents' => esc_html__('Table of Contents', 'lwptoc'),
|
99 |
+
'Edit' => esc_html__('Edit', 'lwptoc'),
|
100 |
+
]);
|
101 |
+
}
|
102 |
+
|
103 |
+
public function checkAjaxReferer()
|
104 |
+
{
|
105 |
+
check_ajax_referer(Core::$plugin->prefix . 'adminMain');
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @param PostSettings|array $source
|
110 |
+
* @return array
|
111 |
+
*/
|
112 |
+
public function overrideSettingsToRows($source)
|
113 |
+
{
|
114 |
+
$getValue = function ($source, $key) {
|
115 |
+
$v = ArrayHelper::getValue($source, $key);
|
116 |
+
if ($v === null) {
|
117 |
+
$lowerKey = strtolower($key);
|
118 |
+
if ($lowerKey != $key) {
|
119 |
+
$v = ArrayHelper::getValue($source, $lowerKey);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
return $v;
|
123 |
+
};
|
124 |
+
$rows = [];
|
125 |
+
if (null !== $v = $getValue($source, 'position')) {
|
126 |
+
$rows[] = [esc_html__('Position', 'lwptoc'), ArrayHelper::getValue(Core::$plugin->positionsList, $v)];
|
127 |
+
}
|
128 |
+
if (null !== $v = $getValue($source, 'min')) {
|
129 |
+
$rows[] = [esc_html__('Minimal Count of Headers', 'lwptoc'), $v];
|
130 |
+
}
|
131 |
+
if (null !== $v = $getValue($source, 'depth')) {
|
132 |
+
$rows[] = [esc_html__('Depth', 'lwptoc'), $v];
|
133 |
+
}
|
134 |
+
if (null !== $v = $getValue($source, 'hierarchical')) {
|
135 |
+
$rows[] = [esc_html__('Hierarchical View', 'lwptoc'), $v ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc')];
|
136 |
+
}
|
137 |
+
if (null !== $v = $getValue($source, 'numeration')) {
|
138 |
+
$rows[] = [esc_html__('Numeration', 'lwptoc'), ArrayHelper::getValue(Core::$plugin->numerationsList, $v)];
|
139 |
+
}
|
140 |
+
if (null !== $v = $getValue($source, 'title')) {
|
141 |
+
$rows[] = [esc_html__('Title', 'lwptoc'), $v == '' ? null : $v];
|
142 |
+
}
|
143 |
+
if (null !== $v = $getValue($source, 'toggle')) {
|
144 |
+
$rows[] = [esc_html__('Toggle Show/Hide', 'lwptoc'), $v ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc')];
|
145 |
+
}
|
146 |
+
if (null !== $v = $getValue($source, 'labelShow')) {
|
147 |
+
$rows[] = [esc_html__('Label Show', 'lwptoc'), $v == '' ? null : $v];
|
148 |
+
}
|
149 |
+
if (null !== $v = $getValue($source, 'labelHide')) {
|
150 |
+
$rows[] = [esc_html__('Label Hide', 'lwptoc'), $v == '' ? null : $v];
|
151 |
+
}
|
152 |
+
if (null !== $v = $getValue($source, 'hideItems')) {
|
153 |
+
$rows[] = [esc_html__('Hide Items', 'lwptoc'), $v ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc')];
|
154 |
+
}
|
155 |
+
if (null !== $v = $getValue($source, 'smoothScroll')) {
|
156 |
+
$rows[] = [esc_html__('Smooth Scroll', 'lwptoc'), $v ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc')];
|
157 |
+
}
|
158 |
+
if (null !== $v = $getValue($source, 'smoothScrollOffset')) {
|
159 |
+
$rows[] = [esc_html__('Smooth Scroll Offset Top', 'lwptoc'), $v . 'px'];
|
160 |
+
}
|
161 |
+
if (null !== $v = $getValue($source, 'width')) {
|
162 |
+
$rows[] = [esc_html__('Width', 'lwptoc'), Core::$plugin->widthToLabel($v)];
|
163 |
+
}
|
164 |
+
if (null !== $v = $getValue($source, 'float')) {
|
165 |
+
$rows[] = [esc_html__('Float', 'lwptoc'), ArrayHelper::getValue(Core::$plugin->floatsList, $v)];
|
166 |
+
}
|
167 |
+
if (null !== $v = $getValue($source, 'titleFontSize')) {
|
168 |
+
$rows[] = [esc_html__('Title Font Size', 'lwptoc'), Core::$plugin->fontSizeToLabel($v)];
|
169 |
+
}
|
170 |
+
if (null !== $v = $getValue($source, 'titleFontWeight')) {
|
171 |
+
$rows[] = [esc_html__('Title Font Weight', 'lwptoc'), ArrayHelper::getValue(Core::$plugin->fontWeightsList, $v)];
|
172 |
+
}
|
173 |
+
if (null !== $v = $getValue($source, 'itemsFontSize')) {
|
174 |
+
$rows[] = [esc_html__('Items Font Size', 'lwptoc'), Core::$plugin->fontSizeToLabel($v)];
|
175 |
+
}
|
176 |
+
if (null !== $v = $getValue($source, 'colorScheme')) {
|
177 |
+
$rows[] = [esc_html__('Color Scheme', 'lwptoc'), ArrayHelper::getValue(Core::$plugin->colorSchemesList, $v)];
|
178 |
+
}
|
179 |
+
foreach ([
|
180 |
+
'backgroundColor' => 'Background Color',
|
181 |
+
'borderColor' => 'Border Color',
|
182 |
+
'titleColor' => 'Title Color',
|
183 |
+
'linkColor' => 'Link Color',
|
184 |
+
'hoverLinkColor' => 'Hover Link Color',
|
185 |
+
'visitedLinkColor' => 'Visited Link Color',
|
186 |
+
] as $var => $label) {
|
187 |
+
if (null !== $v = $getValue($source, $var)) {
|
188 |
+
$rows[] = [esc_html__($label, 'lwptoc'), OverrideColorBadge::widget(['color' => $v]), false];
|
189 |
+
}
|
190 |
+
}
|
191 |
+
return array_map(function ($row) {
|
192 |
+
if ($row[1] !== null && ArrayHelper::getValue($row, 2, true) === true) {
|
193 |
+
$row[1] = esc_html($row[1]);
|
194 |
+
}
|
195 |
+
return $row;
|
196 |
+
}, $rows);
|
197 |
+
}
|
198 |
+
}
|
admin/assets/main.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
@keyframes lwptocLightSpinnerKeyFrames{0%,100%,20%,80%{transform:scale(.7)}50%{transform:scale(1.5)}}.lwptocLightSpinner{display:inline-block;position:relative;width:64px;height:64px}.lwptocLightSpinner div{position:absolute;width:5px;height:5px;background:#fff;border-radius:50%;animation:lwptocLightSpinnerKeyFrames 1.2s linear infinite}.lwptocLightSpinner div:nth-child(1){animation-delay:0s;top:29px;left:53px}.lwptocLightSpinner div:nth-child(2){animation-delay:-.1s;top:18px;left:50px}.lwptocLightSpinner div:nth-child(3){animation-delay:-.2s;top:9px;left:41px}.lwptocLightSpinner div:nth-child(4){animation-delay:-.3s;top:6px;left:29px}.lwptocLightSpinner div:nth-child(5){animation-delay:-.4s;top:9px;left:18px}.lwptocLightSpinner div:nth-child(6){animation-delay:-.5s;top:18px;left:9px}.lwptocLightSpinner div:nth-child(7){animation-delay:-.6s;top:29px;left:6px}.lwptocLightSpinner div:nth-child(8){animation-delay:-.7s;top:41px;left:9px}.lwptocLightSpinner div:nth-child(9){animation-delay:-.8s;top:50px;left:18px}.lwptocLightSpinner div:nth-child(10){animation-delay:-.9s;top:53px;left:29px}.lwptocLightSpinner div:nth-child(11){animation-delay:-1s;top:50px;left:41px}.lwptocLightSpinner div:nth-child(12){animation-delay:-1.1s;top:41px;left:50px}@keyframes lwptocDarkSpinnerKeyFrames{0%,100%,20%,80%{transform:scale(.7)}50%{transform:scale(1.5)}}.lwptocDarkSpinner{display:inline-block;position:relative;width:64px;height:64px}.lwptocDarkSpinner div{position:absolute;width:5px;height:5px;background:#aaa;border-radius:50%;animation:lwptocDarkSpinnerKeyFrames 1.2s linear infinite}.lwptocDarkSpinner div:nth-child(1){animation-delay:0s;top:29px;left:53px}.lwptocDarkSpinner div:nth-child(2){animation-delay:-.1s;top:18px;left:50px}.lwptocDarkSpinner div:nth-child(3){animation-delay:-.2s;top:9px;left:41px}.lwptocDarkSpinner div:nth-child(4){animation-delay:-.3s;top:6px;left:29px}.lwptocDarkSpinner div:nth-child(5){animation-delay:-.4s;top:9px;left:18px}.lwptocDarkSpinner div:nth-child(6){animation-delay:-.5s;top:18px;left:9px}.lwptocDarkSpinner div:nth-child(7){animation-delay:-.6s;top:29px;left:6px}.lwptocDarkSpinner div:nth-child(8){animation-delay:-.7s;top:41px;left:9px}.lwptocDarkSpinner div:nth-child(9){animation-delay:-.8s;top:50px;left:18px}.lwptocDarkSpinner div:nth-child(10){animation-delay:-.9s;top:53px;left:29px}.lwptocDarkSpinner div:nth-child(11){animation-delay:-1s;top:50px;left:41px}.lwptocDarkSpinner div:nth-child(12){animation-delay:-1.1s;top:41px;left:50px}.lwptocPreloaderWrapper{position:relative!important}.lwptocPreloaderOverlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:50;background:rgba(255,255,255,.7)}.lwptocPreloaderOverlay>DIV{position:absolute;top:50%;left:50%;margin-left:-32px;margin-top:-32px}.lwptocModal-container,.lwptocModal-overlay{position:fixed;left:0;top:0;right:0;bottom:0;z-index:1000}.lwptocModal-container{overflow:auto}.lwptocModal-container_i{display:table;height:100%;margin:0 auto}.lwptocModal-container_i2{display:table-cell;padding:24px}.lwptocModal-error{padding:20px;border-radius:10px;background:#000;color:#fff}.lwptocModal-preloader{width:80px;height:80px;border-radius:10px;background:#000 url(preloader.gif) no-repeat 50% 50%}.lwptocModalBox{position:relative;width:500px;background:#fff;color:#000;box-shadow:0 3px 6px rgba(0,0,0,.3)}.lwptocModalBox_close{position:absolute;top:4px;right:8px;color:#666;text-align:center;line-height:29px;width:29px;height:29px;cursor:pointer}.lwptocModalBox_close:before{content:'\f158';font:normal 20px/29px dashicons}.lwptocModalBox_close:hover{color:#00a0d2}.lwptocModalBox_title{background:#fcfcfc;border-bottom:1px solid #dfdfdf;font-weight:600;font-size:13px;line-height:19px;padding:8px 29px 10px 18px}.lwptocModalBox_body{padding:18px 18px 22px 18px}.lwptocModalBox_footer{padding:18px;border-top:1px solid #dfdfdf}.lwptocModalBox_footer_buttons{text-align:right}.lwptocModalBox_footer_buttons .button{margin-left:4px}.lwptocModalBox_footer_buttons .button:first-child{margin-left:0}.lwptocModalBox_footer_buttons:after{content:".";display:block;height:0;font-size:0;line-height:0;clear:both;visibility:hidden}.lwptocMetabox P{padding:0;margin:12px 0 0}.lwptocMetabox P:first-child{margin-top:0}.lwptocMetabox .button-link{margin-left:12px}.lwptocMetabox_settings{margin:6px 0 18px;padding:6px 0 6px 4px;box-shadow:-2px 0 0 #fafafa,-4px 0 0 #ddd,4px 0 0 #fafafa;background:#fafafa}.lwptocMetabox_settings_item{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-top:4px}.lwptocMetabox_settings_item:first-child{margin-top:0}.lwptocMetabox_settings_item B{font-weight:400;color:#888}.lwptocMetabox_settings_item .lwptocColorBadge B{position:relative;top:1px;margin-left:2px}.lwptocCustomize .lwptocModalBox_body{padding:0 0 22px}.lwptocCustomize_errors{margin:14px;border-left:2px solid red;background:#fff4f6;padding:4px 12px 6px;color:red}.lwptocCustomize_errors P{margin:2px 0 0 0}.lwptocCustomize_errors P:first-child{margin-top:0}.lwptocCustomize_tabs{padding:0 14px;margin-top:12px;background:#f1f1f1}.lwptocCustomize_tabs:after{content:".";display:block;height:0;font-size:0;line-height:0;clear:both;visibility:hidden}.lwptocCustomize_tab{float:left;white-space:nowrap;padding:6px 12px 7px;cursor:pointer}.lwptocCustomize_tab:hover{background:#ddd}.lwptocCustomize_tab-active{background:#0073aa!important;color:#fff;cursor:default}.lwptocCustomize_fields{display:none;padding:16px 18px 0}.lwptocCustomize_field{position:relative;margin-top:12px}.lwptocCustomize_field:first-child{margin-top:0}.lwptocCustomize_field_label{font-weight:700}.lwptocCustomize_field_default{float:right;margin-left:4px;cursor:pointer;color:#0073aa;border-bottom:1px dotted #0073aa}.lwptocCustomize_field_default:hover{color:#00a0d2;border-color:#00a0d2}.lwptocCustomize_field_override{display:none;position:absolute;left:-4px;top:-4px;right:-4px;bottom:-4px;background:rgba(42,150,204,.8);color:#fff;font-size:16px;font-weight:700;text-align:center;padding-top:12px;cursor:pointer;-webkit-transition:.1s linear;-moz-transition:.1s linear;-o-transition:.1s linear;transition:.1s linear;opacity:0}.lwptocCustomize_field_defaultValue{display:none;font-size:16px;line-height:20px;font-style:italic;color:#aaa}.lwptocCustomize_field_el{margin-top:4px}.lwptocCustomize_field_el_select,.lwptocCustomize_field_el_textInput{width:100%}.lwptocCustomize_field_desc{margin-top:2px;font-size:90%;color:#888}.lwptocCustomize_field-default .lwptocCustomize_field_default,.lwptocCustomize_field-default .lwptocCustomize_field_el{display:none}.lwptocCustomize_field-default .lwptocCustomize_field_defaultValue,.lwptocCustomize_field-default .lwptocCustomize_field_override{display:block}.lwptocCustomize_field-default .lwptocCustomize_field_desc{margin-top:0}.lwptocCustomize_field-default:hover .lwptocCustomize_field_override{opacity:1}.lwptocWidthField_custom{display:inline}.lwptocWidthField_sizeInput{vertical-align:top;width:64px;padding-bottom:4px;text-align:center}.lwptocWidthField_unitInput{vertical-align:top}.lwptocFontSizeField_custom{display:inline}.lwptocFontSizeField_sizeInput{vertical-align:top;width:64px;padding-bottom:4px;text-align:center}.lwptocFontSizeField_unitInput{vertical-align:top}.lwptocModalSuccess{text-align:center;cursor:default;color:#8bc34a}.lwptocModalSuccess_ico{font-family:dashicons;font-size:160px;line-height:124px}.lwptocModalSuccess_text{color:#fff;font-size:24px;line-height:30px}.lwptocColorBadge B{display:inline-block;margin-right:4px;width:12px;height:12px;border-radius:6px}.lwptocFloatLeft{float:left}.lwptocEditorBlock{display:block;padding:12px 16px 13px;border:2px dashed #ddd;background:#fff;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.lwptocEditorBlock_title{font-size:14px;line-height:18px;font-weight:700}.lwptocEditorBlock_title-loading{color:#aaa}.lwptocEditorBlock_items{margin-top:4px;font-size:12px;line-height:16px}.lwptocEditorBlock_item{margin-top:2px}.lwptocEditorBlock_item:first-child{margin-top:0}.lwptocEditorBlock_item_label{color:#888}.lwptocEditorBlock .lwptocColorBadge B{position:relative;top:1px;margin-left:2px}.mce-i-lwptocButton:before{font:400 20px/1 dashicons;content:"\f163"}
|
admin/assets/main.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(t,e){var o="lwptocPreloader";t.fn[o+"Show"]=function(){var e=t(this);e.addClass(o+"Wrapper"),e.append('<div class="'+o+'Overlay"><div class="lwptocDarkSpinner"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div></div>')},t.fn[o+"Hide"]=function(){var e=t(this);e.removeClass(o+"Wrapper"),e.find("."+o+"Overlay").remove()}}(jQuery),function(r,e){var l="lwptocModal",t={type:"html",content:"",url:"",ajax:{},ajaxRequest:null,closeOnEsc:!0,closeOnOverlayClick:!0,clone:!1,overlay:{block:void 0,tpl:'<div class="'+l+'-overlay"></div>',css:{backgroundColor:"#000",opacity:.6,zIndex:1e5}},container:{block:void 0,tpl:'<div class="'+l+'-container"><div class="'+l+'-container_i"><div class="'+l+'-container_i2"></div></div></div>'},preloader:{verticalAlign:void 0,tpl:'<div class="'+l+'-preloader" />'},wrap:void 0,body:void 0,errors:{tpl:'<div class="'+l+"-error "+l+'-close"></div>',autocloseDelay:2e3,ajaxUnsuccessfulLoad:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},width:"auto",verticalAlign:"middle",beforeOpen:r.noop,afterOpen:r.noop,beforeClose:r.noop,afterClose:r.noop,afterLoading:r.noop,afterLoadingOnShow:r.noop,errorLoading:r.noop},d=0,s=r([]),u=function(e,t){var o=!0;return r(e).each(function(){r(t.target).get(0)==r(this).get(0)&&(o=!1),0==r(t.target).closest("HTML",r(this).get(0)).length&&(o=!1)}),o},i={getParentEl:function(e){var t=r(e);return t.data(l)?t:(t=r(e).closest("."+l+"-container").data(l+"ParentEl"))||!1},transition:function(e,t,o,n){switch(n=null==n?r.noop:n,o.type){case"fade":"show"==t?e.fadeIn(o.speed,n):e.fadeOut(o.speed,n);break;case"none":"show"==t?e.show():e.hide(),n()}},setWrapMarginRight:function(e,t){e.wrap.css("marginRight",t+"px"),r(document).trigger(l+"_setWrapMarginRight",t)},initEl:function(t,e){var o=t.data(l);if(!o){if(d++,(o=e).modalID=d,o.overlay.block=r(o.overlay.tpl),o.overlay.block.css(o.overlay.css),o.container.block=r(o.container.tpl),o.body=r("."+l+"-container_i2",o.container.block),e.clone?o.body.html(t.clone(!0)):(t.before('<div id="'+l+"Reserve"+o.modalID+'" style="display: none" />'),o.body.html(t)),o.body.on("click","."+l+"-close",function(){return t[l]("close"),!1}),o.closeOnOverlayClick&&o.overlay.block.add(o.container.block).click(function(e){u(r(">*",o.body),e)&&t[l]("close")}),o.container.block.data(l+"ParentEl",t),t.data(l,o),s=r.merge(s,t),r.proxy(p.show,t)(),"html"==o.type)return t;if(null!=o.ajax.beforeSend){var n=o.ajax.beforeSend;delete o.ajax.beforeSend}if(null!=o.ajax.success){var i=o.ajax.success;delete o.ajax.success}if(null!=o.ajax.error){var a=o.ajax.error;delete o.ajax.error}var c=r.extend(!0,{url:o.url,beforeSend:function(){o.body.html(o.preloader.tpl).css("verticalAlign",void 0===o.preloader.verticalAlign?o.verticalAlign:o.preloader.verticalAlign),void 0!==n&&n(o,t)},success:function(e){t.trigger("afterLoading."+l),e=o.afterLoading(o,t,e)||e,o.body.css("verticalAlign",o.verticalAlign),null==i?o.body.html(e):i(o,t,e),t.trigger("afterLoadingOnShow."+l),o.afterLoadingOnShow(o,t,e)},error:function(){t.trigger("errorLoading."+l),o.errorLoading(o,t),null==a?(o.body.html(o.errors.tpl),r("."+l+"-error",o.body).html(o.errors.ajaxUnsuccessfulLoad),r("."+l+"-close",o.body).click(function(){return t[l]("close"),!1}),o.errors.autocloseDelay&&setTimeout(function(){t[l]("close")},o.errors.autocloseDelay)):a(o,t)}},o.ajax);o.ajaxRequest=r.ajax(c),t.data(l,o)}},init:function(e){return e=r.extend(!0,{},t,e),r.isFunction(this)?null==e?void r.error(l+": Uncorrect parameters"):""!=e.url?(e.type="ajax",i.initEl(r("<div />"),e)):""!=e.content?(e.type="html",i.initEl(r(e.content),e)):void r.error(l+': Set parameter "url" or "content"'):this.each(function(){i.initEl(r(this),r.extend(!0,{},e))})}},p={show:function(){var e=i.getParentEl(this);if(!1!==e){var t=e.data(l);if(t.overlay.block.hide(),t.container.block.hide(),r("BODY").append(t.overlay.block),r("BODY").append(t.container.block),t.container.block.css("zIndex",t.overlay.block.css("zIndex")),t.beforeOpen(t,e),e.trigger("beforeOpen."+l),"hidden"!=t.wrap.css("overflow-y")){t.wrap.data(l+"Overflow",t.wrap.css("overflow-y"));var o=t.wrap.outerWidth(!0);t.wrap.css("overflow-y","hidden");var n=t.wrap.outerWidth(!0);n!=o&&i.setWrapMarginRight(t,n-o)}return s.not(e).each(function(){r(this).data(l).overlay.block.hide()}),t.body.css("verticalAlign",t.verticalAlign),t.body.parent().css("width",t.width),i.transition(t.overlay.block,"show",1<s.length?{type:"none"}:t.openEffect),i.transition(t.container.block,"show",1<s.length?{type:"none"}:t.openEffect,function(){t.afterOpen(t,e),e.trigger("afterOpen."+l)}),e}r.error(l+": Uncorrect call")},close:function(){if(!r.isFunction(this))return this.each(function(){var e=i.getParentEl(this);if(!1!==e){var t=e.data(l);!1!==t.beforeClose(t,e)&&(e.trigger("beforeClose."+l),s.not(e).last().each(function(){r(this).data(l).overlay.block.show()}),i.transition(t.overlay.block,"hide",1<s.length?{type:"none"}:t.closeEffect),i.transition(t.container.block,"hide",1<s.length?{type:"none"}:t.closeEffect,function(){t.afterClose(t,e),e.trigger("afterClose."+l),t.clone||r("#"+l+"Reserve"+t.modalID).replaceWith(t.body.find(">*")),t.overlay.block.remove(),t.container.block.remove(),e.data(l,null),r("."+l+"-container").length||(t.wrap.data(l+"Overflow")&&t.wrap.css("overflow-y",t.wrap.data(l+"Overflow")),i.setWrapMarginRight(t,0))}),"ajax"==t.type&&t.ajaxRequest.abort(),s=s.not(e))}else r.error(l+": Uncorrect call")});s.each(function(){r(this)[l]("close")})},getActive:function(){var e=r("."+l+"-container").last();return!!e.length&&e.data(l+"ParentEl").data(l)},setDefault:function(e){r.extend(!0,t,e)}};r(function(){t.wrap=r(document.all&&!document.querySelector?"html":"body")}),r(document).bind("keyup."+l,function(e){var t=s.last();t.length&&(t.data(l).closeOnEsc&&27===e.keyCode&&t[l]("close"))}),r[l]=r.fn[l]=function(e){return p[e]?p[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?void r.error(l+": Method "+e+" does not exist"):i.init.apply(this,arguments)}}(jQuery),function(n,e){var i="lwptocAjaxForm",t={afterInit:n.noop,beforeSend:n.noop,success:n.noop,error:function(){alert("Failed to execute the query. Reload the page and try again.")},b:{}},a={isForm:function(e){return"form"==e.get(0).tagName.toLowerCase()},makeData:function(e){return a.isForm(e)?e.serialize():(t=e.clone().wrap("<form/>"),e.find("select").each(function(e){t.find("select").eq(e).val(n(this).val())}),t.serialize());var t},submit:function(e,t){n.ajax({type:"POST",cache:!1,data:a.makeData(e),url:a.isForm(e)?e.attr("action"):e.data("action"),beforeSend:function(){t.beforeSend(t,e)},success:function(e){t.b.container.html(e),t.success(t)},error:function(){t.error(t,e)}})},initContainer:function(e,t){var o=e.data(i);o||(o=t,e.data(i,o),(o.b.container=e).on("submit","[data-ajax-form]",function(){return a.submit(n(this),o),!1}),o.afterInit(o))},init:function(e){return e=n.extend(!0,{},t,e),n.isFunction(this)?(n.error(i+": Uncorrect call"),!1):this.each(function(){a.initContainer(n(this),n.extend(!0,{},e))})}},o={setDefault:function(e){n.extend(!0,t,e)}};n[i]=n.fn[i]=function(e){return o[e]?o[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?(n.error(i+": Method "+e+" does not exist"),!1):a.init.apply(this,arguments)}}(jQuery),function(r){r.lwptocModal("setDefault",{preloader:{tpl:'<div class="lwptocLightSpinner"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>'},overlay:{css:{zIndex:999999}}}),r(function(){var e=r(".js-lwptocSmoothScrollCheckbox");if(e.length){var t=r(".js-lwptocSmoothScrollIOffsetInput").closest("TR");e.change(function(){e.prop("checked")?t.show():t.hide()}).change()}var o=r(".js-lwptocToggleCheckbox");if(o.length){var n=r(".js-lwptocToggleEl").closest("TR");o.change(function(){o.prop("checked")?n.show():n.hide()}).change()}var i=r(".js-lwptocAutoInsertEnableCheckbox");if(i.length){var a=r(".js-lwptocAutoInsertEl").closest("TR");i.change(function(){i.prop("checked")?a.show():a.hide()}).change()}var c=r(".lwptoc_colorPicker");c.length&&c.wpColorPicker()}),r.lwptocCustomize={init:function(t,o){n.init(t.find(".lwptocWidthField")),i.init(t.find(".lwptocFontSizeField")),t.find(".lwptoc_colorPicker").wpColorPicker(),t.on("click",".lwptocCustomize_field_override",function(){var e=r(this).closest(".lwptocCustomize_field");e.removeClass("lwptocCustomize_field-default"),e.find("INPUT[type=text]").focus(),e.find(".lwptocCustomize_field_inputDefault").val(0)}),t.on("click",".lwptocCustomize_field_default",function(){var e=r(this).closest(".lwptocCustomize_field");e.addClass("lwptocCustomize_field-default"),e.find(".lwptocCustomize_field_inputDefault").val(1)}),t.on("click",".lwptocCustomize_tab",function(){t.find(".lwptocCustomize_tab-active").removeClass("lwptocCustomize_tab-active"),r(this).addClass("lwptocCustomize_tab-active"),t.find(".lwptocCustomize_fields").hide(),t.find(".lwptocCustomize_fields-"+r(this).data("tab")).show()}),t.lwptocAjaxForm({beforeSend:function(){t.lwptocPreloaderShow()},success:function(e){t.lwptocPreloaderHide(),o()}})},show:function(e,t){e._ajax_nonce=lwptocMain.nonce,r.lwptocModal({url:lwptocMain.ajaxUrl,closeOnOverlayClick:!1,verticalAlign:"top",ajax:{data:e},afterLoadingOnShow:function(e){r.lwptocCustomize.init(e.body.find(".lwptocCustomize"),function(){e.body.lwptocModal("close")})},afterClose:t})}};var o={reload:function(e){var t=r(e);o.$container.replaceWith(t),o.init(t)},setEnabled:function(e){r.ajax({url:lwptocMain.ajaxUrl,data:{_ajax_nonce:lwptocMain.nonce,action:"lwptoc_metabox_set_enabled",postId:o.$container.data("postId"),enabled:e?1:0},beforeSend:function(){o.$container.lwptocPreloaderShow()},success:function(e){o.$container.lwptocPreloaderHide(),o.reload(e)}})},init:function(){o.$container=r(".lwptocMetabox"),o.$container.length&&(o.$container.find(".lwptocMetabox_disable").click(function(){o.setEnabled(!1)}),o.$container.find(".lwptocMetabox_enable").click(function(){o.setEnabled(!0)}),o.$container.find(".lwptocMetabox_customize").click(function(){r.lwptocCustomize.show({action:"lwptoc_metabox_customize",postId:o.$container.data("postId")},r.noop)}),r(document).on("lwptocMetaboxCustomized",function(e,t){r(".lwptocCustomize-metabox").lwptocModal("close"),o.reload(t.metabox)}))}};r(function(){o.init()});var n={update:function(e){"custom"==e.$typeInput.val()?(e.$input.val(e.$sizeInput.val()+e.$unitInput.val()),e.$custom.show()):(e.$input.val(e.$typeInput.val()),e.$custom.hide())},init:function(e){e.each(function(){var e={$container:r(this)};e.$typeInput=e.$container.find(".lwptocWidthField_typeInput"),e.$sizeInput=e.$container.find(".lwptocWidthField_sizeInput"),e.$unitInput=e.$container.find(".lwptocWidthField_unitInput"),e.$input=e.$container.find(".lwptocWidthField_input"),e.$custom=e.$container.find(".lwptocWidthField_custom"),e.$typeInput.add(e.$sizeInput).add(e.$unitInput).change(function(){n.update(e)})})}};r(function(){n.init(r(".lwptocWidthField"))});var i={update:function(e){"custom"==e.$typeInput.val()?(e.$input.val(e.$sizeInput.val()+e.$unitInput.val()),e.$custom.show()):(e.$input.val(e.$typeInput.val()),e.$custom.hide())},init:function(e){e.each(function(){var e={$container:r(this)};e.$typeInput=e.$container.find(".lwptocFontSizeField_typeInput"),e.$sizeInput=e.$container.find(".lwptocFontSizeField_sizeInput"),e.$unitInput=e.$container.find(".lwptocFontSizeField_unitInput"),e.$input=e.$container.find(".lwptocFontSizeField_input"),e.$custom=e.$container.find(".lwptocFontSizeField_custom"),e.$typeInput.add(e.$sizeInput).add(e.$unitInput).change(function(){i.update(e)})})}};r(function(){i.init(r(".lwptocFontSizeField"))})}(jQuery);
|
admin/controllers/EditorBlockController.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\controllers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\admin\forms\CustomizeForm;
|
6 |
+
use luckywp\tableOfContents\admin\widgets\customizeModal\CustomizeModal;
|
7 |
+
use luckywp\tableOfContents\admin\widgets\customizeSuccess\CustomizeSuccess;
|
8 |
+
use luckywp\tableOfContents\core\admin\AdminController;
|
9 |
+
use luckywp\tableOfContents\core\Core;
|
10 |
+
use luckywp\tableOfContents\core\helpers\Json;
|
11 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
12 |
+
|
13 |
+
class EditorBlockController extends AdminController
|
14 |
+
{
|
15 |
+
|
16 |
+
public function init()
|
17 |
+
{
|
18 |
+
parent::init();
|
19 |
+
add_action('plugins_loaded', [$this, 'initAjax']);
|
20 |
+
}
|
21 |
+
|
22 |
+
public function initAjax()
|
23 |
+
{
|
24 |
+
add_action('wp_ajax_lwptoc_block_edit', [$this, 'ajaxEdit']);
|
25 |
+
add_action('wp_ajax_lwptoc_block_view', [$this, 'ajaxView']);
|
26 |
+
}
|
27 |
+
|
28 |
+
public function ajaxEdit()
|
29 |
+
{
|
30 |
+
$post = get_post((int)Core::$plugin->request->get('postId'));
|
31 |
+
$attrs = Core::$plugin->request->get('attrs');
|
32 |
+
if (!is_array($attrs)) {
|
33 |
+
$attrs = [];
|
34 |
+
}
|
35 |
+
$onlyBody = false;
|
36 |
+
|
37 |
+
$postSettings = new PostSettings($post->ID);
|
38 |
+
$model = new CustomizeForm($postSettings, $attrs);
|
39 |
+
if ($model->load(Core::$plugin->request->post())) {
|
40 |
+
if ($model->validate()) {
|
41 |
+
echo CustomizeSuccess::widget([
|
42 |
+
'after' => '<script>$(document).trigger("lwptocEditorBlockChanged", ' . Json::encode($model->getAttrs()) . ');</script>',
|
43 |
+
]);
|
44 |
+
wp_die();
|
45 |
+
}
|
46 |
+
$onlyBody = true;
|
47 |
+
}
|
48 |
+
|
49 |
+
echo CustomizeModal::widget([
|
50 |
+
'onlyBody' => $onlyBody,
|
51 |
+
'post' => $post,
|
52 |
+
'action' => 'lwptoc_block_edit',
|
53 |
+
'model' => $model,
|
54 |
+
]);
|
55 |
+
wp_die();
|
56 |
+
}
|
57 |
+
|
58 |
+
public function ajaxView()
|
59 |
+
{
|
60 |
+
$attrs = Core::$plugin->request->get('attrs');
|
61 |
+
if (!is_array($attrs)) {
|
62 |
+
$attrs = [];
|
63 |
+
}
|
64 |
+
$rows = Core::$plugin->admin->overrideSettingsToRows($attrs);
|
65 |
+
echo '<div class="lwptocEditorBlock_title">' . esc_html__('Table of Contents', 'lwptoc') . '</div>';
|
66 |
+
if ($rows) {
|
67 |
+
echo '<div class="lwptocEditorBlock_items">';
|
68 |
+
foreach ($rows as $row) {
|
69 |
+
echo '<div class="lwptocEditorBlock_item">';
|
70 |
+
echo '<span class="lwptocEditorBlock_item_label">' . esc_html($row[0]) . ':</span> ';
|
71 |
+
echo $row[1] === null ? '<i>' . __('empty', 'lwptoc') . '</i>' : $row[1];
|
72 |
+
echo '</div>';
|
73 |
+
}
|
74 |
+
echo '</div>';
|
75 |
+
}
|
76 |
+
wp_die();
|
77 |
+
}
|
78 |
+
}
|
admin/controllers/MetaboxController.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\controllers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\admin\forms\CustomizeForm;
|
6 |
+
use luckywp\tableOfContents\admin\widgets\customizeModal\CustomizeModal;
|
7 |
+
use luckywp\tableOfContents\admin\widgets\customizeSuccess\CustomizeSuccess;
|
8 |
+
use luckywp\tableOfContents\admin\widgets\metabox\Metabox;
|
9 |
+
use luckywp\tableOfContents\core\admin\AdminController;
|
10 |
+
use luckywp\tableOfContents\core\Core;
|
11 |
+
use luckywp\tableOfContents\core\helpers\Json;
|
12 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
13 |
+
|
14 |
+
class MetaboxController extends AdminController
|
15 |
+
{
|
16 |
+
|
17 |
+
public function init()
|
18 |
+
{
|
19 |
+
parent::init();
|
20 |
+
add_action('plugins_loaded', [$this, 'initAjax']);
|
21 |
+
}
|
22 |
+
|
23 |
+
public function initAjax()
|
24 |
+
{
|
25 |
+
add_action('wp_ajax_lwptoc_metabox_set_enabled', [$this, 'ajaxSetEnabled']);
|
26 |
+
add_action('wp_ajax_lwptoc_metabox_customize', [$this, 'ajaxCustomize']);
|
27 |
+
}
|
28 |
+
|
29 |
+
protected function checkAccess($post)
|
30 |
+
{
|
31 |
+
Core::$plugin->admin->checkAjaxReferer();
|
32 |
+
if (!$post ||
|
33 |
+
!current_user_can('edit_post', $post->ID) ||
|
34 |
+
!in_array($post->post_type, Core::$plugin->admin->getMetaboxPostTypes())
|
35 |
+
) {
|
36 |
+
$this->notAllowed();
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
public function ajaxSetEnabled()
|
41 |
+
{
|
42 |
+
$post = get_post((int)Core::$plugin->request->get('postId'));
|
43 |
+
$this->checkAccess($post);
|
44 |
+
|
45 |
+
$settings = new PostSettings($post->ID);
|
46 |
+
$settings->enabled = (bool)Core::$plugin->request->get('enabled', true);
|
47 |
+
$settings->save();
|
48 |
+
|
49 |
+
echo Metabox::widget(['post' => $post]);
|
50 |
+
wp_die();
|
51 |
+
}
|
52 |
+
|
53 |
+
public function ajaxCustomize()
|
54 |
+
{
|
55 |
+
$post = get_post((int)Core::$plugin->request->get('postId'));
|
56 |
+
$this->checkAccess($post);
|
57 |
+
$onlyBody = false;
|
58 |
+
|
59 |
+
$postSettings = new PostSettings($post->ID);
|
60 |
+
$model = new CustomizeForm($postSettings);
|
61 |
+
if ($model->load(Core::$plugin->request->post())) {
|
62 |
+
if ($model->validate()) {
|
63 |
+
$model->toPostSettings($postSettings);
|
64 |
+
$postSettings->save();
|
65 |
+
echo CustomizeSuccess::widget([
|
66 |
+
'after' => '<script>$(document).trigger("lwptocMetaboxCustomized", ' . Json::encode([
|
67 |
+
'metabox' => Metabox::widget(['post' => $post]),
|
68 |
+
]) . ');</script>',
|
69 |
+
]);
|
70 |
+
wp_die();
|
71 |
+
}
|
72 |
+
$onlyBody = true;
|
73 |
+
}
|
74 |
+
|
75 |
+
echo CustomizeModal::widget([
|
76 |
+
'onlyBody' => $onlyBody,
|
77 |
+
'post' => $post,
|
78 |
+
'action' => 'lwptoc_metabox_customize',
|
79 |
+
'model' => $model,
|
80 |
+
]);
|
81 |
+
wp_die();
|
82 |
+
}
|
83 |
+
}
|
admin/controllers/SettingsController.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\controllers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\admin\AdminController;
|
6 |
+
|
7 |
+
class SettingsController extends AdminController
|
8 |
+
{
|
9 |
+
|
10 |
+
public function actionIndex()
|
11 |
+
{
|
12 |
+
$this->render('index');
|
13 |
+
}
|
14 |
+
}
|
admin/controllers/ShortcodeController.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\controllers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\admin\forms\CustomizeForm;
|
6 |
+
use luckywp\tableOfContents\admin\widgets\customizeModal\CustomizeModal;
|
7 |
+
use luckywp\tableOfContents\admin\widgets\customizeSuccess\CustomizeSuccess;
|
8 |
+
use luckywp\tableOfContents\core\admin\AdminController;
|
9 |
+
use luckywp\tableOfContents\core\Core;
|
10 |
+
use luckywp\tableOfContents\core\helpers\Json;
|
11 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
12 |
+
|
13 |
+
class ShortcodeController extends AdminController
|
14 |
+
{
|
15 |
+
|
16 |
+
public function init()
|
17 |
+
{
|
18 |
+
parent::init();
|
19 |
+
add_action('plugins_loaded', [$this, 'initAjax']);
|
20 |
+
}
|
21 |
+
|
22 |
+
public function initAjax()
|
23 |
+
{
|
24 |
+
add_action('wp_ajax_lwptoc_shortcode_customize', [$this, 'ajaxCustomize']);
|
25 |
+
add_action('wp_ajax_lwptoc_shortcode_view', [$this, 'ajaxView']);
|
26 |
+
}
|
27 |
+
|
28 |
+
public function ajaxCustomize()
|
29 |
+
{
|
30 |
+
Core::$plugin->admin->checkAjaxReferer();
|
31 |
+
$post = get_post((int)Core::$plugin->request->get('postId'));
|
32 |
+
$attrs = Core::$plugin->request->get('attrs');
|
33 |
+
if (!is_array($attrs)) {
|
34 |
+
$attrs = [];
|
35 |
+
}
|
36 |
+
$onlyBody = false;
|
37 |
+
|
38 |
+
$postSettings = new PostSettings($post->ID);
|
39 |
+
$model = new CustomizeForm($postSettings, $attrs);
|
40 |
+
if ($model->load(Core::$plugin->request->post())) {
|
41 |
+
if ($model->validate()) {
|
42 |
+
echo CustomizeSuccess::widget([
|
43 |
+
'after' => '<script>$(document).trigger("lwptocShortcodeGenerated", ' . Json::encode(['shortcode' => $model->generateShortcode()]) . ');</script>',
|
44 |
+
]);
|
45 |
+
wp_die();
|
46 |
+
}
|
47 |
+
$onlyBody = true;
|
48 |
+
}
|
49 |
+
|
50 |
+
echo CustomizeModal::widget([
|
51 |
+
'onlyBody' => $onlyBody,
|
52 |
+
'post' => $post,
|
53 |
+
'action' => 'lwptoc_shortcode_customize',
|
54 |
+
'model' => $model,
|
55 |
+
]);
|
56 |
+
wp_die();
|
57 |
+
}
|
58 |
+
|
59 |
+
public function ajaxView()
|
60 |
+
{
|
61 |
+
Core::$plugin->admin->checkAjaxReferer();
|
62 |
+
$attrs = Core::$plugin->request->get('attrs');
|
63 |
+
if (!is_array($attrs)) {
|
64 |
+
$attrs = [];
|
65 |
+
}
|
66 |
+
$rows = Core::$plugin->admin->overrideSettingsToRows($attrs);
|
67 |
+
echo '<div class="lwptocShortcode">';
|
68 |
+
echo '<div class="lwptocShortcode_title">' . esc_html__('Table of Contents', 'lwptoc') . '</div>';
|
69 |
+
if ($rows) {
|
70 |
+
echo '<div class="lwptocShortcode_items">';
|
71 |
+
foreach ($rows as $row) {
|
72 |
+
echo '<div class="lwptocShortcode_item">';
|
73 |
+
echo '<span class="lwptocShortcode_item_label">' . esc_html($row[0]) . ':</span> ';
|
74 |
+
echo $row[1] === null ? '<i>' . __('empty', 'lwptoc') . '</i>' : $row[1];
|
75 |
+
echo '</div>';
|
76 |
+
}
|
77 |
+
echo '</div>';
|
78 |
+
}
|
79 |
+
echo '</div>';
|
80 |
+
wp_die();
|
81 |
+
}
|
82 |
+
}
|
admin/forms/CustomizeForm.php
ADDED
@@ -0,0 +1,264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\forms;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Model;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
8 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
9 |
+
|
10 |
+
class CustomizeForm extends Model
|
11 |
+
{
|
12 |
+
|
13 |
+
public $defaultMin;
|
14 |
+
public $min;
|
15 |
+
|
16 |
+
public $defaultDepth;
|
17 |
+
public $depth;
|
18 |
+
|
19 |
+
public $defaultHierarchical;
|
20 |
+
public $hierarchical;
|
21 |
+
|
22 |
+
public $defaultNumeration;
|
23 |
+
public $numeration;
|
24 |
+
|
25 |
+
public $defaultTitle;
|
26 |
+
public $title;
|
27 |
+
|
28 |
+
public $defaultToggle;
|
29 |
+
public $toggle;
|
30 |
+
|
31 |
+
public $defaultLabelShow;
|
32 |
+
public $labelShow;
|
33 |
+
|
34 |
+
public $defaultLabelHide;
|
35 |
+
public $labelHide;
|
36 |
+
|
37 |
+
public $defaultHideItems;
|
38 |
+
public $hideItems;
|
39 |
+
|
40 |
+
public $defaultSmoothScroll;
|
41 |
+
public $smoothScroll;
|
42 |
+
|
43 |
+
public $defaultSmoothScrollOffset;
|
44 |
+
public $smoothScrollOffset;
|
45 |
+
|
46 |
+
public $defaultPosition;
|
47 |
+
public $position;
|
48 |
+
|
49 |
+
public $defaultWidth;
|
50 |
+
public $width;
|
51 |
+
|
52 |
+
public $defaultFloat;
|
53 |
+
public $float;
|
54 |
+
|
55 |
+
public $defaultTitleFontSize;
|
56 |
+
public $titleFontSize;
|
57 |
+
|
58 |
+
public $defaultTitleFontWeight;
|
59 |
+
public $titleFontWeight;
|
60 |
+
|
61 |
+
public $defaultItemsFontSize;
|
62 |
+
public $itemsFontSize;
|
63 |
+
|
64 |
+
public $defaultColorScheme;
|
65 |
+
public $colorScheme;
|
66 |
+
|
67 |
+
public $defaultBackgroundColor;
|
68 |
+
public $backgroundColor;
|
69 |
+
|
70 |
+
public $defaultBorderColor;
|
71 |
+
public $borderColor;
|
72 |
+
|
73 |
+
public $defaultTitleColor;
|
74 |
+
public $titleColor;
|
75 |
+
|
76 |
+
public $defaultLinkColor;
|
77 |
+
public $linkColor;
|
78 |
+
|
79 |
+
public $defaultHoverLinkColor;
|
80 |
+
public $hoverLinkColor;
|
81 |
+
|
82 |
+
public $defaultVisitedLinkColor;
|
83 |
+
public $visitedLinkColor;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @var PostSettings
|
87 |
+
*/
|
88 |
+
public $postSettings;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @var bool
|
92 |
+
*/
|
93 |
+
public $isPostSettings;
|
94 |
+
|
95 |
+
protected $vars = [
|
96 |
+
'min',
|
97 |
+
'depth',
|
98 |
+
'hierarchical',
|
99 |
+
'numeration',
|
100 |
+
'title',
|
101 |
+
'toggle',
|
102 |
+
'labelShow',
|
103 |
+
'labelHide',
|
104 |
+
'hideItems',
|
105 |
+
'smoothScroll',
|
106 |
+
'smoothScrollOffset',
|
107 |
+
'width',
|
108 |
+
'float',
|
109 |
+
'titleFontSize',
|
110 |
+
'titleFontWeight',
|
111 |
+
'itemsFontSize',
|
112 |
+
'colorScheme',
|
113 |
+
'backgroundColor',
|
114 |
+
'borderColor',
|
115 |
+
'titleColor',
|
116 |
+
'linkColor',
|
117 |
+
'hoverLinkColor',
|
118 |
+
'visitedLinkColor',
|
119 |
+
];
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @param PostSettings $postSettings
|
123 |
+
* @param array|null $attrs
|
124 |
+
* @param array $config
|
125 |
+
*/
|
126 |
+
public function __construct($postSettings, $attrs = null, array $config = [])
|
127 |
+
{
|
128 |
+
$this->postSettings = $postSettings;
|
129 |
+
$this->isPostSettings = $attrs === null;
|
130 |
+
if ($this->isPostSettings) {
|
131 |
+
$this->vars[] = 'position';
|
132 |
+
}
|
133 |
+
|
134 |
+
if (is_array($attrs)) {
|
135 |
+
$attrs = array_change_key_case($attrs, CASE_LOWER);
|
136 |
+
}
|
137 |
+
|
138 |
+
foreach ($this->vars as $var) {
|
139 |
+
$value = $this->isPostSettings ? $postSettings->$var : ArrayHelper::getValue($attrs, strtolower($var));
|
140 |
+
$this->{'default' . ucfirst($var)} = ($value === null) ? 1 : 0;
|
141 |
+
if (!$this->{'default' . ucfirst($var)}) {
|
142 |
+
$this->$var = $value;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
parent::__construct($config);
|
146 |
+
}
|
147 |
+
|
148 |
+
public function rules()
|
149 |
+
{
|
150 |
+
return [
|
151 |
+
[
|
152 |
+
array_map(function ($v) {
|
153 |
+
return 'default' . ucfirst($v);
|
154 |
+
}, $this->vars),
|
155 |
+
'boolean'
|
156 |
+
],
|
157 |
+
['min', 'filter', 'filter' => 'intval'],
|
158 |
+
['depth', 'filter', 'filter' => 'intval'],
|
159 |
+
['depth', 'in', 'range' => array_keys(Core::$plugin->depthsList)],
|
160 |
+
['hierarchical', 'boolean'],
|
161 |
+
['numeration', 'in', 'range' => array_keys(Core::$plugin->numerationsList)],
|
162 |
+
['title', 'filter', 'filter' => 'trim'],
|
163 |
+
['toggle', 'boolean'],
|
164 |
+
[['labelShow', 'labelHide'], 'filter', 'filter' => 'trim'],
|
165 |
+
[
|
166 |
+
'labelShow',
|
167 |
+
'required',
|
168 |
+
'when' => function () {
|
169 |
+
return !$this->defaultLabelShow;
|
170 |
+
}
|
171 |
+
],
|
172 |
+
[
|
173 |
+
'labelHide',
|
174 |
+
'required',
|
175 |
+
'when' => function () {
|
176 |
+
return !$this->defaultLabelHide;
|
177 |
+
}
|
178 |
+
],
|
179 |
+
['hideItems', 'boolean'],
|
180 |
+
['smoothScroll', 'boolean'],
|
181 |
+
['smoothScrollOffset', 'filter', 'filter' => 'intval'],
|
182 |
+
['position', 'in', 'range' => array_keys(Core::$plugin->positionsList)],
|
183 |
+
['width', 'filter', 'filter' => [Core::$plugin->settings, 'sanitizeWidth']],
|
184 |
+
['float', 'in', 'range' => array_keys(Core::$plugin->floatsList)],
|
185 |
+
['titleFontSize', 'filter', 'filter' => [Core::$plugin->settings, 'sanitizeFontSize']],
|
186 |
+
['titleFontWeight', 'in', 'range' => array_keys(Core::$plugin->fontWeightsList)],
|
187 |
+
['itemsFontSize', 'filter', 'filter' => [Core::$plugin->settings, 'sanitizeFontSize']],
|
188 |
+
['colorScheme', 'in', 'range' => array_keys(Core::$plugin->colorSchemesList)],
|
189 |
+
[
|
190 |
+
['backgroundColor', 'borderColor', 'titleColor', 'linkColor', 'hoverLinkColor', 'visitedLinkColor'],
|
191 |
+
'filter',
|
192 |
+
'filter' => [Core::$plugin->settings, 'sanitizeCallbackColor'],
|
193 |
+
],
|
194 |
+
];
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* @return array
|
199 |
+
*/
|
200 |
+
public function attributeLabels()
|
201 |
+
{
|
202 |
+
return [
|
203 |
+
'depth' => esc_html__('Depth', 'lwptoc'),
|
204 |
+
'numeration' => esc_html__('Numeration', 'lwptoc'),
|
205 |
+
'labelShow' => esc_html__('Label Show', 'lwptoc'),
|
206 |
+
'labelHide' => esc_html__('Label Hide', 'lwptoc'),
|
207 |
+
'position' => esc_html__('Position', 'lwptoc'),
|
208 |
+
'float' => esc_html__('Float', 'lwptoc'),
|
209 |
+
'titleFontWeight' => esc_html__('Title Font Weight', 'lwptoc'),
|
210 |
+
'colorScheme' => esc_html__('Color Scheme', 'lwptoc'),
|
211 |
+
];
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* @param PostSettings $postSettings
|
216 |
+
*/
|
217 |
+
public function toPostSettings($postSettings)
|
218 |
+
{
|
219 |
+
$postSettings->position = $this->defaultPosition ? null : $this->position;
|
220 |
+
foreach ($this->getAttrs() as $var => $value) {
|
221 |
+
$postSettings->$var = $value;
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* @return string
|
227 |
+
*/
|
228 |
+
public function generateShortcode()
|
229 |
+
{
|
230 |
+
return Core::$plugin->shortcode->make($this->getAttrs());
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* @return array
|
235 |
+
*/
|
236 |
+
public function getAttrs()
|
237 |
+
{
|
238 |
+
return [
|
239 |
+
'min' => $this->defaultMin ? null : ($this->min < 0 ? 0 : $this->min),
|
240 |
+
'depth' => $this->defaultDepth ? null : $this->depth,
|
241 |
+
'hierarchical' => $this->defaultHierarchical ? null : (bool)$this->hierarchical,
|
242 |
+
'numeration' => $this->defaultNumeration ? null : $this->numeration,
|
243 |
+
'title' => $this->defaultTitle ? null : $this->title,
|
244 |
+
'toggle' => $this->defaultToggle ? null : (bool)$this->toggle,
|
245 |
+
'labelShow' => $this->defaultLabelShow ? null : $this->labelShow,
|
246 |
+
'labelHide' => $this->defaultLabelHide ? null : $this->labelHide,
|
247 |
+
'hideItems' => $this->defaultHideItems ? null : (bool)$this->hideItems,
|
248 |
+
'smoothScroll' => $this->defaultSmoothScroll ? null : (bool)$this->smoothScroll,
|
249 |
+
'smoothScrollOffset' => $this->defaultSmoothScrollOffset ? null : (int)$this->smoothScrollOffset,
|
250 |
+
'width' => $this->defaultWidth ? null : $this->width,
|
251 |
+
'float' => $this->defaultFloat ? null : $this->float,
|
252 |
+
'titleFontSize' => $this->defaultTitleFontSize ? null : $this->titleFontSize,
|
253 |
+
'titleFontWeight' => $this->defaultTitleFontWeight ? null : $this->titleFontWeight,
|
254 |
+
'itemsFontSize' => $this->defaultItemsFontSize ? null : $this->itemsFontSize,
|
255 |
+
'colorScheme' => $this->defaultColorScheme ? null : $this->colorScheme,
|
256 |
+
'backgroundColor' => $this->defaultBackgroundColor ? null : ($this->backgroundColor ? $this->backgroundColor : ''),
|
257 |
+
'borderColor' => $this->defaultBorderColor ? null : ($this->borderColor ? $this->borderColor : ''),
|
258 |
+
'titleColor' => $this->defaultTitleColor ? null : ($this->titleColor ? $this->titleColor : ''),
|
259 |
+
'linkColor' => $this->defaultLinkColor ? null : ($this->linkColor ? $this->linkColor : ''),
|
260 |
+
'hoverLinkColor' => $this->defaultHoverLinkColor ? null : ($this->hoverLinkColor ? $this->hoverLinkColor : ''),
|
261 |
+
'visitedLinkColor' => $this->defaultVisitedLinkColor ? null : ($this->visitedLinkColor ? $this->visitedLinkColor : ''),
|
262 |
+
];
|
263 |
+
}
|
264 |
+
}
|
admin/views/settings/index.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use luckywp\tableOfContents\core\Core;
|
4 |
+
|
5 |
+
?>
|
6 |
+
<div class="wrap">
|
7 |
+
<h1><?= esc_html__('Table of Contents Settings', 'lwptoc') ?></h1>
|
8 |
+
<?php Core::$plugin->settings->showPage(false) ?>
|
9 |
+
</div>
|
admin/widgets/OverrideColorBadge.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Widget;
|
6 |
+
|
7 |
+
class OverrideColorBadge extends Widget
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string
|
12 |
+
*/
|
13 |
+
public $color;
|
14 |
+
|
15 |
+
public function run()
|
16 |
+
{
|
17 |
+
return $this->color ? '<span class="lwptocColorBadge"><b style="background:' . $this->color . '"></b>' . $this->color . '</span>' : esc_html__('from scheme', 'lwptoc');
|
18 |
+
}
|
19 |
+
}
|
admin/widgets/PostTypes.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Widget;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
8 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
9 |
+
|
10 |
+
class PostTypes extends Widget
|
11 |
+
{
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array
|
15 |
+
*/
|
16 |
+
public $field;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var array
|
20 |
+
*/
|
21 |
+
public $containerOptions = [];
|
22 |
+
|
23 |
+
public function run()
|
24 |
+
{
|
25 |
+
$value = Core::$plugin->settings->getValue($this->field['group'], $this->field['id'], [], false);
|
26 |
+
if (!is_array($value)) {
|
27 |
+
$value = [];
|
28 |
+
}
|
29 |
+
|
30 |
+
// Типы постов
|
31 |
+
$postTypes = ArrayHelper::map(Core::$plugin->postTypes, 'name', 'labels.singular_name');
|
32 |
+
|
33 |
+
// HTML
|
34 |
+
$html = Html::beginTag('div', $this->containerOptions);
|
35 |
+
$html .= Html::hiddenInput($this->field['name']);
|
36 |
+
foreach ($postTypes as $postName => $postLabel) {
|
37 |
+
$options = [
|
38 |
+
'label' => $postLabel,
|
39 |
+
'value' => $postName,
|
40 |
+
];
|
41 |
+
$html .= '<p>' . Html::checkbox($this->field['name'] . '[]', in_array($postName, $value), $options) . '</p>';
|
42 |
+
}
|
43 |
+
$html .= '</div>';
|
44 |
+
return $html;
|
45 |
+
}
|
46 |
+
}
|
admin/widgets/customizeModal/CustomizeModal.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets\customizeModal;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\admin\forms\CustomizeForm;
|
6 |
+
use luckywp\tableOfContents\core\base\Widget;
|
7 |
+
use WP_Post;
|
8 |
+
|
9 |
+
class CustomizeModal extends Widget
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var WP_Post
|
14 |
+
*/
|
15 |
+
public $post;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
public $action;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var CustomizeForm
|
24 |
+
*/
|
25 |
+
public $model;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var bool
|
29 |
+
*/
|
30 |
+
public $onlyBody;
|
31 |
+
|
32 |
+
public function run()
|
33 |
+
{
|
34 |
+
return $this->render('modal', [
|
35 |
+
'post' => $this->post,
|
36 |
+
'action' => $this->action,
|
37 |
+
'model' => $this->model,
|
38 |
+
'onlyBody' => $this->onlyBody,
|
39 |
+
]);
|
40 |
+
}
|
41 |
+
}
|
admin/widgets/customizeModal/views/modal.php
ADDED
@@ -0,0 +1,497 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $post WP_Post
|
4 |
+
* @var $action string
|
5 |
+
* @var $model \luckywp\tableOfContents\admin\forms\CustomizeForm
|
6 |
+
* @var $onlyBody bool
|
7 |
+
*/
|
8 |
+
|
9 |
+
use luckywp\tableOfContents\admin\widgets\fontSizeField\FontSizeField;
|
10 |
+
use luckywp\tableOfContents\admin\widgets\OverrideColorBadge;
|
11 |
+
use luckywp\tableOfContents\admin\widgets\widthField\WidthField;
|
12 |
+
use luckywp\tableOfContents\core\admin\helpers\AdminHtml;
|
13 |
+
use luckywp\tableOfContents\core\Core;
|
14 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
15 |
+
|
16 |
+
echo $onlyBody ? '' : '<div class="lwptocCustomize lwptocCustomize-metabox">';
|
17 |
+
?>
|
18 |
+
<form
|
19 |
+
action="<?= admin_url('admin-ajax.php?_ajax_nonce=' . wp_create_nonce(Core::$plugin->prefix . 'adminMain') . '&action=' . $action . '&postId=' . $post->ID) ?>"
|
20 |
+
data-ajax-form="1"
|
21 |
+
class="lwptocModalBox"
|
22 |
+
>
|
23 |
+
<div class="lwptocModalBox_close lwptocModal-close" title="<?= __('Cancel', 'lwptoc') ?>"></div>
|
24 |
+
<div class="lwptocModalBox_title"><?= __('Customize Table of Contents', 'lwptoc') ?></div>
|
25 |
+
<div class="lwptocModalBox_body">
|
26 |
+
|
27 |
+
<?php
|
28 |
+
if ($model->hasErrors()) {
|
29 |
+
echo '<div class="lwptocCustomize_errors">';
|
30 |
+
foreach ($model->getErrorSummary() as $error) {
|
31 |
+
echo '<p>' . $error . '</p>';
|
32 |
+
}
|
33 |
+
echo '</div>';
|
34 |
+
}
|
35 |
+
?>
|
36 |
+
|
37 |
+
<div class="lwptocCustomize_tabs">
|
38 |
+
<div class="lwptocCustomize_tab lwptocCustomize_tab-active" data-tab="general"><?= esc_html__('General', 'lwptoc') ?></div>
|
39 |
+
<div class="lwptocCustomize_tab" data-tab="appearance"><?= esc_html__('Appearance', 'lwptoc') ?></div>
|
40 |
+
</div>
|
41 |
+
|
42 |
+
<div class="lwptocCustomize_fields lwptocCustomize_fields-general" style="display:block;">
|
43 |
+
|
44 |
+
<?php if ($model->isPostSettings) { ?>
|
45 |
+
<div class="lwptocCustomize_field<?= $model->defaultPosition ? ' lwptocCustomize_field-default' : '' ?>">
|
46 |
+
<div class="lwptocCustomize_field_header">
|
47 |
+
<span class="lwptocCustomize_field_label"><?= __('Position', 'lwptoc') ?></span>
|
48 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
49 |
+
</div>
|
50 |
+
<div class="lwptocCustomize_field_override">
|
51 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
52 |
+
</div>
|
53 |
+
<div class="lwptocCustomize_field_el">
|
54 |
+
<?= Html::dropDownList(Html::getInputName($model, 'position'), $model->defaultPosition ? Core::$plugin->settings->autoInsertPosition : $model->position, Core::$plugin->positionsList, [
|
55 |
+
'class' => 'lwptocCustomize_field_el_select',
|
56 |
+
]) ?>
|
57 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultPosition'), $model->defaultPosition, [
|
58 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
59 |
+
]) ?>
|
60 |
+
</div>
|
61 |
+
<div class="lwptocCustomize_field_defaultValue">
|
62 |
+
<?= Core::$plugin->positionsList[Core::$plugin->settings->autoInsertPosition] ?>
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
<?php } ?>
|
66 |
+
|
67 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->min)) ? Core::$plugin->settings->generalMin : $model->postSettings->min ?>
|
68 |
+
<div class="lwptocCustomize_field<?= $model->defaultMin ? ' lwptocCustomize_field-default' : '' ?>">
|
69 |
+
<div class="lwptocCustomize_field_header">
|
70 |
+
<span class="lwptocCustomize_field_label"><?= __('Minimal Count of Headers', 'lwptoc') ?></span>
|
71 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
72 |
+
</div>
|
73 |
+
<div class="lwptocCustomize_field_override">
|
74 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
75 |
+
</div>
|
76 |
+
<div class="lwptocCustomize_field_el">
|
77 |
+
<?= Html::textInput(Html::getInputName($model, 'min'), $model->defaultMin ? $defaultValue : $model->min, ['class' => 'lwptocCustomize_field_el_textInput']) ?>
|
78 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultMin'), $model->defaultMin, [
|
79 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
80 |
+
]) ?>
|
81 |
+
</div>
|
82 |
+
<div class="lwptocCustomize_field_desc">
|
83 |
+
<?= __('If the count of headers in the post is less, then table of contents is not displayed.', 'lwptoc') ?>
|
84 |
+
</div>
|
85 |
+
<div class="lwptocCustomize_field_defaultValue">
|
86 |
+
<?= $defaultValue ?>
|
87 |
+
</div>
|
88 |
+
</div>
|
89 |
+
|
90 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->depth)) ? Core::$plugin->settings->generalDepth : $model->postSettings->depth ?>
|
91 |
+
<div class="lwptocCustomize_field<?= $model->defaultDepth ? ' lwptocCustomize_field-default' : '' ?>">
|
92 |
+
<div class="lwptocCustomize_field_header">
|
93 |
+
<span class="lwptocCustomize_field_label"><?= __('Depth', 'lwptoc') ?></span>
|
94 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
95 |
+
</div>
|
96 |
+
<div class="lwptocCustomize_field_override">
|
97 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
98 |
+
</div>
|
99 |
+
<div class="lwptocCustomize_field_el">
|
100 |
+
<?= Html::dropDownList(Html::getInputName($model, 'depth'), $model->defaultDepth ? $defaultValue : $model->depth, Core::$plugin->depthsList, [
|
101 |
+
'class' => 'lwptocCustomize_field_el_select',
|
102 |
+
]) ?>
|
103 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultDepth'), $model->defaultDepth, [
|
104 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
105 |
+
]) ?>
|
106 |
+
</div>
|
107 |
+
<div class="lwptocCustomize_field_defaultValue">
|
108 |
+
<?= Core::$plugin->depthsList[$defaultValue] ?>
|
109 |
+
</div>
|
110 |
+
</div>
|
111 |
+
|
112 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->hierarchical)) ? Core::$plugin->settings->generalHierarchical : $model->postSettings->hierarchical ?>
|
113 |
+
<div class="lwptocCustomize_field<?= $model->defaultHierarchical ? ' lwptocCustomize_field-default' : '' ?>">
|
114 |
+
<div class="lwptocCustomize_field_header">
|
115 |
+
<span class="lwptocCustomize_field_label"><?= __('Hierarchical View', 'lwptoc') ?></span>
|
116 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
117 |
+
</div>
|
118 |
+
<div class="lwptocCustomize_field_override">
|
119 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
120 |
+
</div>
|
121 |
+
<div class="lwptocCustomize_field_el">
|
122 |
+
<label>
|
123 |
+
<?= Html::checkbox(Html::getInputName($model, 'hierarchical'), $model->defaultHierarchical ? $defaultValue : $model->hierarchical, ['uncheck' => 0]) ?>
|
124 |
+
<?= __('Enable', 'lwptoc') ?>
|
125 |
+
</label>
|
126 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultHierarchical'), $model->defaultHierarchical, [
|
127 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
128 |
+
]) ?>
|
129 |
+
</div>
|
130 |
+
<div class="lwptocCustomize_field_defaultValue">
|
131 |
+
<?= $defaultValue ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc') ?>
|
132 |
+
</div>
|
133 |
+
</div>
|
134 |
+
|
135 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->numeration)) ? Core::$plugin->settings->generalNumeration : $model->postSettings->numeration ?>
|
136 |
+
<div class="lwptocCustomize_field<?= $model->defaultNumeration ? ' lwptocCustomize_field-default' : '' ?>">
|
137 |
+
<div class="lwptocCustomize_field_header">
|
138 |
+
<span class="lwptocCustomize_field_label"><?= __('Numeration', 'lwptoc') ?></span>
|
139 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
140 |
+
</div>
|
141 |
+
<div class="lwptocCustomize_field_override">
|
142 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
143 |
+
</div>
|
144 |
+
<div class="lwptocCustomize_field_el">
|
145 |
+
<?= Html::dropDownList(Html::getInputName($model, 'numeration'), $model->defaultNumeration ? $defaultValue : $model->numeration, Core::$plugin->numerationsList, [
|
146 |
+
'class' => 'lwptocCustomize_field_el_select',
|
147 |
+
]) ?>
|
148 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultNumeration'), $model->defaultNumeration, [
|
149 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
150 |
+
]) ?>
|
151 |
+
</div>
|
152 |
+
<div class="lwptocCustomize_field_defaultValue">
|
153 |
+
<?= Core::$plugin->numerationsList[$defaultValue] ?>
|
154 |
+
</div>
|
155 |
+
</div>
|
156 |
+
|
157 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->title)) ? Core::$plugin->settings->generalTitle : $model->postSettings->title ?>
|
158 |
+
<div class="lwptocCustomize_field<?= $model->defaultTitle ? ' lwptocCustomize_field-default' : '' ?>">
|
159 |
+
<div class="lwptocCustomize_field_header">
|
160 |
+
<span class="lwptocCustomize_field_label"><?= __('Title', 'lwptoc') ?></span>
|
161 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
162 |
+
</div>
|
163 |
+
<div class="lwptocCustomize_field_override">
|
164 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
165 |
+
</div>
|
166 |
+
<div class="lwptocCustomize_field_el">
|
167 |
+
<?= Html::textInput(Html::getInputName($model, 'title'), $model->defaultTitle ? $defaultValue : $model->title, ['class' => 'lwptocCustomize_field_el_textInput']) ?>
|
168 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultTitle'), $model->defaultTitle, [
|
169 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
170 |
+
]) ?>
|
171 |
+
</div>
|
172 |
+
<div class="lwptocCustomize_field_defaultValue">
|
173 |
+
<?php
|
174 |
+
if ('' == $defaultValue) {
|
175 |
+
echo '<i>' . __('Without title', 'lwptoc') . '</i>';
|
176 |
+
} else {
|
177 |
+
echo $defaultValue;
|
178 |
+
}
|
179 |
+
?>
|
180 |
+
</div>
|
181 |
+
</div>
|
182 |
+
|
183 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->toggle)) ? Core::$plugin->settings->generalToggle : $model->postSettings->toggle ?>
|
184 |
+
<div class="lwptocCustomize_field<?= $model->defaultToggle ? ' lwptocCustomize_field-default' : '' ?>">
|
185 |
+
<div class="lwptocCustomize_field_header">
|
186 |
+
<span class="lwptocCustomize_field_label"><?= __('Toggle Show/Hide', 'lwptoc') ?></span>
|
187 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
188 |
+
</div>
|
189 |
+
<div class="lwptocCustomize_field_override">
|
190 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
191 |
+
</div>
|
192 |
+
<div class="lwptocCustomize_field_el">
|
193 |
+
<label>
|
194 |
+
<?= Html::checkbox(Html::getInputName($model, 'toggle'), $model->defaultToggle ? $defaultValue : $model->toggle, ['uncheck' => 0]) ?>
|
195 |
+
<?= __('Enable', 'lwptoc') ?>
|
196 |
+
</label>
|
197 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultToggle'), $model->defaultToggle, [
|
198 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
199 |
+
]) ?>
|
200 |
+
</div>
|
201 |
+
<div class="lwptocCustomize_field_defaultValue">
|
202 |
+
<?= $defaultValue ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc') ?>
|
203 |
+
</div>
|
204 |
+
</div>
|
205 |
+
|
206 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->labelShow)) ? Core::$plugin->settings->generalLabelShow : $model->postSettings->labelShow ?>
|
207 |
+
<div class="lwptocCustomize_field<?= $model->defaultLabelShow ? ' lwptocCustomize_field-default' : '' ?>">
|
208 |
+
<div class="lwptocCustomize_field_header">
|
209 |
+
<span class="lwptocCustomize_field_label"><?= __('Label Show', 'lwptoc') ?></span>
|
210 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
211 |
+
</div>
|
212 |
+
<div class="lwptocCustomize_field_override">
|
213 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
214 |
+
</div>
|
215 |
+
<div class="lwptocCustomize_field_el">
|
216 |
+
<?= Html::textInput(Html::getInputName($model, 'labelShow'), $model->defaultLabelShow ? $defaultValue : $model->labelShow, ['class' => 'lwptocCustomize_field_el_textInput']) ?>
|
217 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultLabelShow'), $model->defaultLabelShow, [
|
218 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
219 |
+
]) ?>
|
220 |
+
</div>
|
221 |
+
<div class="lwptocCustomize_field_defaultValue">
|
222 |
+
<?= $defaultValue ?>
|
223 |
+
</div>
|
224 |
+
</div>
|
225 |
+
|
226 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->labelHide)) ? Core::$plugin->settings->generalLabelHide : $model->postSettings->labelHide ?>
|
227 |
+
<div class="lwptocCustomize_field<?= $model->defaultLabelHide ? ' lwptocCustomize_field-default' : '' ?>">
|
228 |
+
<div class="lwptocCustomize_field_header">
|
229 |
+
<span class="lwptocCustomize_field_label"><?= __('Label Hide', 'lwptoc') ?></span>
|
230 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
231 |
+
</div>
|
232 |
+
<div class="lwptocCustomize_field_override">
|
233 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
234 |
+
</div>
|
235 |
+
<div class="lwptocCustomize_field_el">
|
236 |
+
<?= Html::textInput(Html::getInputName($model, 'labelHide'), $model->defaultLabelHide ? $defaultValue : $model->labelHide, ['class' => 'lwptocCustomize_field_el_textInput']) ?>
|
237 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultLabelHide'), $model->defaultLabelHide, [
|
238 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
239 |
+
]) ?>
|
240 |
+
</div>
|
241 |
+
<div class="lwptocCustomize_field_defaultValue">
|
242 |
+
<?= $defaultValue ?>
|
243 |
+
</div>
|
244 |
+
</div>
|
245 |
+
|
246 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->hideItems)) ? Core::$plugin->settings->generalHideItems : $model->postSettings->hideItems ?>
|
247 |
+
<div class="lwptocCustomize_field<?= $model->defaultHideItems ? ' lwptocCustomize_field-default' : '' ?>">
|
248 |
+
<div class="lwptocCustomize_field_header">
|
249 |
+
<span class="lwptocCustomize_field_label"><?= __('By default, items of contents will be hidden', 'lwptoc') ?></span>
|
250 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
251 |
+
</div>
|
252 |
+
<div class="lwptocCustomize_field_override">
|
253 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
254 |
+
</div>
|
255 |
+
<div class="lwptocCustomize_field_el">
|
256 |
+
<label>
|
257 |
+
<?= Html::checkbox(Html::getInputName($model, 'hideItems'), $model->defaultHideItems ? $defaultValue : $model->hideItems, ['uncheck' => 0]) ?>
|
258 |
+
<?= __('Enable', 'lwptoc') ?>
|
259 |
+
</label>
|
260 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultHideItems'), $model->defaultHideItems, [
|
261 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
262 |
+
]) ?>
|
263 |
+
</div>
|
264 |
+
<div class="lwptocCustomize_field_defaultValue">
|
265 |
+
<?= $defaultValue ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc') ?>
|
266 |
+
</div>
|
267 |
+
</div>
|
268 |
+
|
269 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->smoothScroll)) ? Core::$plugin->settings->generalSmoothScroll : $model->postSettings->smoothScroll ?>
|
270 |
+
<div class="lwptocCustomize_field<?= $model->defaultSmoothScroll ? ' lwptocCustomize_field-default' : '' ?>">
|
271 |
+
<div class="lwptocCustomize_field_header">
|
272 |
+
<span class="lwptocCustomize_field_label"><?= __('Smooth Scroll', 'lwptoc') ?></span>
|
273 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
274 |
+
</div>
|
275 |
+
<div class="lwptocCustomize_field_override">
|
276 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
277 |
+
</div>
|
278 |
+
<div class="lwptocCustomize_field_el">
|
279 |
+
<label>
|
280 |
+
<?= Html::checkbox(Html::getInputName($model, 'smoothScroll'), $model->defaultSmoothScroll ? $defaultValue : $model->smoothScroll, ['uncheck' => 0]) ?>
|
281 |
+
<?= __('Enable', 'lwptoc') ?>
|
282 |
+
</label>
|
283 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultSmoothScroll'), $model->defaultSmoothScroll, [
|
284 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
285 |
+
]) ?>
|
286 |
+
</div>
|
287 |
+
<div class="lwptocCustomize_field_defaultValue">
|
288 |
+
<?= $defaultValue ? __('Enabled', 'lwptoc') : __('Disabled', 'lwptoc') ?>
|
289 |
+
</div>
|
290 |
+
</div>
|
291 |
+
|
292 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->smoothScrollOffset)) ? Core::$plugin->settings->generalSmoothScrollOffset : $model->postSettings->smoothScrollOffset ?>
|
293 |
+
<div class="lwptocCustomize_field<?= $model->defaultSmoothScrollOffset ? ' lwptocCustomize_field-default' : '' ?>">
|
294 |
+
<div class="lwptocCustomize_field_header">
|
295 |
+
<span class="lwptocCustomize_field_label"><?= __('Smooth Scroll Offset Top', 'lwptoc') ?></span>
|
296 |
+
<span class="lwptocCustomize_field_default"><?= __('default', 'lwptoc') ?></span>
|
297 |
+
</div>
|
298 |
+
<div class="lwptocCustomize_field_override">
|
299 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
300 |
+
</div>
|
301 |
+
<div class="lwptocCustomize_field_el">
|
302 |
+
<?= Html::textInput(Html::getInputName($model, 'smoothScrollOffset'), $model->defaultSmoothScrollOffset ? $defaultValue : $model->smoothScrollOffset, ['class' => 'lwptocCustomize_field_el_textInput']) ?>
|
303 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultSmoothScrollOffset'), $model->defaultSmoothScrollOffset, [
|
304 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
305 |
+
]) ?>
|
306 |
+
</div>
|
307 |
+
<div class="lwptocCustomize_field_defaultValue">
|
308 |
+
<?= $defaultValue ?>px
|
309 |
+
</div>
|
310 |
+
</div>
|
311 |
+
|
312 |
+
</div>
|
313 |
+
|
314 |
+
<div class="lwptocCustomize_fields lwptocCustomize_fields-appearance">
|
315 |
+
|
316 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->width)) ? Core::$plugin->settings->appearanceWidth : $model->postSettings->width ?>
|
317 |
+
<div class="lwptocCustomize_field<?= $model->defaultWidth ? ' lwptocCustomize_field-default' : '' ?>">
|
318 |
+
<div class="lwptocCustomize_field_header">
|
319 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__('Width', 'lwptoc') ?></span>
|
320 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
321 |
+
</div>
|
322 |
+
<div class="lwptocCustomize_field_override">
|
323 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
324 |
+
</div>
|
325 |
+
<div class="lwptocCustomize_field_el">
|
326 |
+
<?= WidthField::widget([
|
327 |
+
'name' => Html::getInputName($model, 'width'),
|
328 |
+
'value' => $model->defaultWidth ? $defaultValue : $model->width,
|
329 |
+
]) ?>
|
330 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultWidth'), $model->defaultWidth, [
|
331 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
332 |
+
]) ?>
|
333 |
+
</div>
|
334 |
+
<div class="lwptocCustomize_field_defaultValue">
|
335 |
+
<?= Core::$plugin->widthToLabel($defaultValue) ?>
|
336 |
+
</div>
|
337 |
+
</div>
|
338 |
+
|
339 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->float)) ? Core::$plugin->settings->appearanceFloat : $model->postSettings->float ?>
|
340 |
+
<div class="lwptocCustomize_field<?= $model->defaultFloat ? ' lwptocCustomize_field-default' : '' ?>">
|
341 |
+
<div class="lwptocCustomize_field_header">
|
342 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__('Float', 'lwptoc') ?></span>
|
343 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
344 |
+
</div>
|
345 |
+
<div class="lwptocCustomize_field_override">
|
346 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
347 |
+
</div>
|
348 |
+
<div class="lwptocCustomize_field_el">
|
349 |
+
<?= Html::dropDownList(Html::getInputName($model, 'float'), $model->defaultFloat ? $defaultValue : $model->float, Core::$plugin->floatsList, [
|
350 |
+
'class' => 'lwptocCustomize_field_el_select',
|
351 |
+
]) ?>
|
352 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultFloat'), $model->defaultFloat, [
|
353 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
354 |
+
]) ?>
|
355 |
+
</div>
|
356 |
+
<div class="lwptocCustomize_field_defaultValue">
|
357 |
+
<?= Core::$plugin->floatsList[$defaultValue] ?>
|
358 |
+
</div>
|
359 |
+
</div>
|
360 |
+
|
361 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->titleFontSize)) ? Core::$plugin->settings->appearanceTitleFontSize : $model->postSettings->titleFontSize ?>
|
362 |
+
<div class="lwptocCustomize_field<?= $model->defaultTitleFontSize ? ' lwptocCustomize_field-default' : '' ?>">
|
363 |
+
<div class="lwptocCustomize_field_header">
|
364 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__('Title Font Size', 'lwptoc') ?></span>
|
365 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
366 |
+
</div>
|
367 |
+
<div class="lwptocCustomize_field_override">
|
368 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
369 |
+
</div>
|
370 |
+
<div class="lwptocCustomize_field_el">
|
371 |
+
<?= FontSizeField::widget([
|
372 |
+
'name' => Html::getInputName($model, 'titleFontSize'),
|
373 |
+
'value' => $model->defaultTitleFontSize ? $defaultValue : $model->titleFontSize,
|
374 |
+
'defaultSize' => 100,
|
375 |
+
]) ?>
|
376 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultTitleFontSize'), $model->defaultTitleFontSize, [
|
377 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
378 |
+
]) ?>
|
379 |
+
</div>
|
380 |
+
<div class="lwptocCustomize_field_defaultValue">
|
381 |
+
<?= Core::$plugin->fontSizeToLabel($defaultValue) ?>
|
382 |
+
</div>
|
383 |
+
</div>
|
384 |
+
|
385 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->titleFontWeight)) ? Core::$plugin->settings->appearanceTitleFontWeight : $model->postSettings->titleFontWeight ?>
|
386 |
+
<div class="lwptocCustomize_field<?= $model->defaultTitleFontWeight ? ' lwptocCustomize_field-default' : '' ?>">
|
387 |
+
<div class="lwptocCustomize_field_header">
|
388 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__('Title Font Weight', 'lwptoc') ?></span>
|
389 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
390 |
+
</div>
|
391 |
+
<div class="lwptocCustomize_field_override">
|
392 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
393 |
+
</div>
|
394 |
+
<div class="lwptocCustomize_field_el">
|
395 |
+
<?= Html::dropDownList(Html::getInputName($model, 'titleFontWeight'), $model->defaultTitleFontWeight ? $defaultValue : $model->titleFontWeight, Core::$plugin->fontWeightsList, [
|
396 |
+
'class' => 'lwptocCustomize_field_el_select',
|
397 |
+
]) ?>
|
398 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultTitleFontWeight'), $model->defaultTitleFontWeight, [
|
399 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
400 |
+
]) ?>
|
401 |
+
</div>
|
402 |
+
<div class="lwptocCustomize_field_defaultValue">
|
403 |
+
<?= Core::$plugin->fontWeightsList[$defaultValue] ?>
|
404 |
+
</div>
|
405 |
+
</div>
|
406 |
+
|
407 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->itemsFontSize)) ? Core::$plugin->settings->appearanceItemsFontSize : $model->postSettings->itemsFontSize ?>
|
408 |
+
<div class="lwptocCustomize_field<?= $model->defaultItemsFontSize ? ' lwptocCustomize_field-default' : '' ?>">
|
409 |
+
<div class="lwptocCustomize_field_header">
|
410 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__('Items Font Size', 'lwptoc') ?></span>
|
411 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
412 |
+
</div>
|
413 |
+
<div class="lwptocCustomize_field_override">
|
414 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
415 |
+
</div>
|
416 |
+
<div class="lwptocCustomize_field_el">
|
417 |
+
<?= FontSizeField::widget([
|
418 |
+
'name' => Html::getInputName($model, 'itemsFontSize'),
|
419 |
+
'value' => $model->defaultItemsFontSize ? $defaultValue : $model->itemsFontSize,
|
420 |
+
'defaultSize' => 90,
|
421 |
+
]) ?>
|
422 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultItemsFontSize'), $model->defaultItemsFontSize, [
|
423 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
424 |
+
]) ?>
|
425 |
+
</div>
|
426 |
+
<div class="lwptocCustomize_field_defaultValue">
|
427 |
+
<?= Core::$plugin->fontSizeToLabel($defaultValue) ?>
|
428 |
+
</div>
|
429 |
+
</div>
|
430 |
+
|
431 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->colorScheme)) ? Core::$plugin->settings->appearanceColorScheme : $model->postSettings->colorScheme ?>
|
432 |
+
<div class="lwptocCustomize_field<?= $model->defaultColorScheme ? ' lwptocCustomize_field-default' : '' ?>">
|
433 |
+
<div class="lwptocCustomize_field_header">
|
434 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__('Color Scheme', 'lwptoc') ?></span>
|
435 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
436 |
+
</div>
|
437 |
+
<div class="lwptocCustomize_field_override">
|
438 |
+
<?= __('Click for override default value', 'lwptoc') ?>
|
439 |
+
</div>
|
440 |
+
<div class="lwptocCustomize_field_el">
|
441 |
+
<?= Html::dropDownList(Html::getInputName($model, 'colorScheme'), $model->defaultColorScheme ? $defaultValue : $model->colorScheme, Core::$plugin->colorSchemesList, [
|
442 |
+
'class' => 'lwptocCustomize_field_el_select',
|
443 |
+
]) ?>
|
444 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'defaultColorScheme'), $model->defaultColorScheme, [
|
445 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
446 |
+
]) ?>
|
447 |
+
</div>
|
448 |
+
<div class="lwptocCustomize_field_defaultValue">
|
449 |
+
<?= Core::$plugin->colorSchemesList[$defaultValue] ?>
|
450 |
+
</div>
|
451 |
+
</div>
|
452 |
+
|
453 |
+
<?php foreach ([
|
454 |
+
'backgroundColor' => 'Background Color',
|
455 |
+
'borderColor' => 'Border Color',
|
456 |
+
'titleColor' => 'Title Color',
|
457 |
+
'linkColor' => 'Link Color',
|
458 |
+
'hoverLinkColor' => 'Hover Link Color',
|
459 |
+
'visitedLinkColor' => 'Visited Link Color',
|
460 |
+
] as $var => $label) { ?>
|
461 |
+
<?php $defaultValue = ($model->isPostSettings || is_null($model->postSettings->$var)) ? Core::$plugin->settings->{'appearance' . ucfirst($var)} : $model->postSettings->$var ?>
|
462 |
+
<div class="lwptocCustomize_field<?= $model->{'default' . ucfirst($var)} ? ' lwptocCustomize_field-default' : '' ?>">
|
463 |
+
<div class="lwptocCustomize_field_header">
|
464 |
+
<span class="lwptocCustomize_field_label"><?= esc_html__($label, 'lwptoc') ?></span>
|
465 |
+
<span class="lwptocCustomize_field_default"><?= esc_html__('default', 'lwptoc') ?></span>
|
466 |
+
</div>
|
467 |
+
<div class="lwptocCustomize_field_override">
|
468 |
+
<?= esc_html__('Click for override default value', 'lwptoc') ?>
|
469 |
+
</div>
|
470 |
+
<div class="lwptocCustomize_field_defaultValue">
|
471 |
+
<?= OverrideColorBadge::widget(['color' => Core::$plugin->settings->{'appearance' . ucfirst($var)}]) ?>
|
472 |
+
</div>
|
473 |
+
<div class="lwptocCustomize_field_el">
|
474 |
+
<?= Html::textInput(Html::getInputName($model, $var), $model->{'default' . ucfirst($var)} ? Core::$plugin->settings->{'appearance' . ucfirst($var)} : $model->$var, ['class' => 'lwptoc_colorPicker']) ?>
|
475 |
+
<?= Html::hiddenInput(Html::getInputName($model, 'default' . ucfirst($var)), $model->{'default' . ucfirst($var)}, [
|
476 |
+
'class' => 'lwptocCustomize_field_inputDefault',
|
477 |
+
]) ?>
|
478 |
+
</div>
|
479 |
+
</div>
|
480 |
+
<?php } ?>
|
481 |
+
|
482 |
+
</div>
|
483 |
+
|
484 |
+
</div>
|
485 |
+
<div class="lwptocModalBox_footer">
|
486 |
+
<div class="lwptocModalBox_footer_buttons">
|
487 |
+
<?= AdminHtml::button(__('Cancel', 'lwptoc'), [
|
488 |
+
'class' => 'lwptocModal-close lwptocFloatLeft'
|
489 |
+
]) ?>
|
490 |
+
<?= AdminHtml::button(__('Save', 'lwptoc'), [
|
491 |
+
'theme' => AdminHtml::BUTTON_THEME_PRIMARY,
|
492 |
+
'submit' => true,
|
493 |
+
]) ?>
|
494 |
+
</div>
|
495 |
+
</div>
|
496 |
+
</form>
|
497 |
+
<?= $onlyBody ? '' : '</div>' ?>
|
admin/widgets/customizeSuccess/CustomizeSuccess.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets\customizeSuccess;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Widget;
|
6 |
+
|
7 |
+
class CustomizeSuccess extends Widget
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string
|
12 |
+
*/
|
13 |
+
public $after = '';
|
14 |
+
|
15 |
+
public function run()
|
16 |
+
{
|
17 |
+
return $this->render('widget', [
|
18 |
+
'after' => $this->after,
|
19 |
+
]);
|
20 |
+
}
|
21 |
+
}
|
admin/widgets/customizeSuccess/views/widget.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $after string
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<div class="lwptocModalSuccess lwptocModal-close">
|
7 |
+
<div class="lwptocModalSuccess_ico"></div>
|
8 |
+
<div class="lwptocModalSuccess_text">
|
9 |
+
<?= __('Saved!', 'lwptoc') ?>
|
10 |
+
</div>
|
11 |
+
</div>
|
12 |
+
<?= $after ?>
|
admin/widgets/fontSizeField/FontSizeField.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets\fontSizeField;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Widget;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
|
8 |
+
class FontSizeField extends Widget
|
9 |
+
{
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
public $name;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
public $value;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var int|float
|
23 |
+
*/
|
24 |
+
public $defaultSize = 100;
|
25 |
+
|
26 |
+
public function run()
|
27 |
+
{
|
28 |
+
$type = 'default';
|
29 |
+
$size = $this->defaultSize;
|
30 |
+
$unit = '%';
|
31 |
+
|
32 |
+
$value = Core::$plugin->settings->sanitizeFontSize((string)$this->value, $matches);
|
33 |
+
if ($value !== 'default') {
|
34 |
+
$type = 'custom';
|
35 |
+
$size = $matches[1];
|
36 |
+
$unit = $matches[2];
|
37 |
+
}
|
38 |
+
|
39 |
+
return $this->render('widget', [
|
40 |
+
'name' => $this->name,
|
41 |
+
'value' => $value,
|
42 |
+
'type' => $type,
|
43 |
+
'size' => $size,
|
44 |
+
'unit' => $unit,
|
45 |
+
]);
|
46 |
+
}
|
47 |
+
}
|
admin/widgets/fontSizeField/views/widget.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $name string
|
4 |
+
* @var $value string
|
5 |
+
* @var $type string
|
6 |
+
* @var $size int
|
7 |
+
* @var $unit string
|
8 |
+
*/
|
9 |
+
|
10 |
+
use luckywp\tableOfContents\core\Core;
|
11 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
12 |
+
|
13 |
+
?>
|
14 |
+
<div class="lwptocFontSizeField">
|
15 |
+
<?= Html::dropDownList(null, $type, [
|
16 |
+
'default' => esc_html__('Default', 'lwptoc'),
|
17 |
+
'custom' => esc_html__('Custom Value', 'lwptoc'),
|
18 |
+
], [
|
19 |
+
'class' => 'lwptocFontSizeField_typeInput',
|
20 |
+
]) ?>
|
21 |
+
<div class="lwptocFontSizeField_custom"<?= $type == 'custom' ? '' : ' style="display:none;"' ?>>
|
22 |
+
<?= Html::textInput(null, $size, [
|
23 |
+
'class' => 'lwptocFontSizeField_sizeInput',
|
24 |
+
]) ?>
|
25 |
+
<?= Html::dropDownList(null, $unit, Core::$plugin->fontSizeUnitsList, [
|
26 |
+
'class' => 'lwptocFontSizeField_unitInput',
|
27 |
+
]) ?>
|
28 |
+
</div>
|
29 |
+
<?= Html::hiddenInput($name, $value, ['class' => 'lwptocFontSizeField_input']) ?>
|
30 |
+
</div>
|
admin/widgets/metabox/Metabox.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets\metabox;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Widget;
|
6 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
7 |
+
use WP_Post;
|
8 |
+
|
9 |
+
class Metabox extends Widget
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var WP_Post
|
14 |
+
*/
|
15 |
+
public $post;
|
16 |
+
|
17 |
+
public function run()
|
18 |
+
{
|
19 |
+
return $this->render('box', [
|
20 |
+
'post' => $this->post,
|
21 |
+
'settings' => new PostSettings($this->post->ID),
|
22 |
+
]);
|
23 |
+
}
|
24 |
+
}
|
admin/widgets/metabox/views/box.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $post WP_Post
|
4 |
+
* @var $settings \luckywp\tableOfContents\plugin\PostSettings
|
5 |
+
*/
|
6 |
+
|
7 |
+
use luckywp\tableOfContents\core\admin\helpers\AdminHtml;
|
8 |
+
use luckywp\tableOfContents\core\Core;
|
9 |
+
|
10 |
+
?>
|
11 |
+
<div class="lwptocMetabox" data-post-id="<?= $post->ID ?>">
|
12 |
+
<?php if ($settings->enabled) { ?>
|
13 |
+
<p>
|
14 |
+
<?= __('The table of contents will be automatic added to this post.', 'lwptoc') ?>
|
15 |
+
</p>
|
16 |
+
<?php
|
17 |
+
$rows = Core::$plugin->admin->overrideSettingsToRows($settings);
|
18 |
+
if ($rows) { ?>
|
19 |
+
<p>
|
20 |
+
<?= __('Overridden settings:', 'lwptoc') ?>
|
21 |
+
</p>
|
22 |
+
<div class="lwptocMetabox_settings">
|
23 |
+
<?php foreach ($rows as $row) { ?>
|
24 |
+
<div class="lwptocMetabox_settings_item">
|
25 |
+
<b><?= $row[0] ?>:</b>
|
26 |
+
<?= $row[1] === null ? '<i>' . __('empty', 'lwptoc') . '</i>' : $row[1] ?>
|
27 |
+
</div>
|
28 |
+
<?php } ?>
|
29 |
+
</div>
|
30 |
+
<?php } ?>
|
31 |
+
<p>
|
32 |
+
<?= AdminHtml::button(__('Customize', 'lwptoc'), [
|
33 |
+
'class' => 'lwptocMetabox_customize',
|
34 |
+
]) ?>
|
35 |
+
<?= AdminHtml::button(__('Disable', 'lwptoc'), [
|
36 |
+
'theme' => AdminHtml::BUTTON_THEME_LINK_DELETE,
|
37 |
+
'class' => 'lwptocMetabox_disable',
|
38 |
+
]) ?>
|
39 |
+
</p>
|
40 |
+
<?php } else { ?>
|
41 |
+
<p>
|
42 |
+
<?= __('Click "Enable" for automatic add table of contents to this post.', 'lwptoc') ?>
|
43 |
+
</p>
|
44 |
+
<p>
|
45 |
+
<?= AdminHtml::button(__('Enable', 'lwptoc'), [
|
46 |
+
'class' => 'lwptocMetabox_enable',
|
47 |
+
]) ?>
|
48 |
+
</p>
|
49 |
+
<?php } ?>
|
50 |
+
</div>
|
admin/widgets/widthField/WidthField.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\admin\widgets\widthField;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Widget;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
|
8 |
+
class WidthField extends Widget
|
9 |
+
{
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
public $name;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
public $value;
|
20 |
+
|
21 |
+
public function run()
|
22 |
+
{
|
23 |
+
$size = 75;
|
24 |
+
$unit = '%';
|
25 |
+
|
26 |
+
$value = Core::$plugin->settings->sanitizeWidth((string)$this->value, $matches);
|
27 |
+
if (Core::$plugin->isCustomWidth($value)) {
|
28 |
+
$type = 'custom';
|
29 |
+
$size = $matches[1];
|
30 |
+
$unit = $matches[2];
|
31 |
+
} else {
|
32 |
+
$type = $value;
|
33 |
+
}
|
34 |
+
|
35 |
+
return $this->render('widget', [
|
36 |
+
'name' => $this->name,
|
37 |
+
'value' => $value,
|
38 |
+
'type' => $type,
|
39 |
+
'size' => $size,
|
40 |
+
'unit' => $unit,
|
41 |
+
]);
|
42 |
+
}
|
43 |
+
}
|
admin/widgets/widthField/views/widget.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $name string
|
4 |
+
* @var $value string
|
5 |
+
* @var $type string
|
6 |
+
* @var $size int
|
7 |
+
* @var $unit string
|
8 |
+
*/
|
9 |
+
|
10 |
+
use luckywp\tableOfContents\core\Core;
|
11 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
12 |
+
|
13 |
+
?>
|
14 |
+
<div class="lwptocWidthField">
|
15 |
+
<?= Html::dropDownList(null, $type, Core::$plugin->getWidthsList(), [
|
16 |
+
'class' => 'lwptocWidthField_typeInput',
|
17 |
+
]) ?>
|
18 |
+
<div class="lwptocWidthField_custom"<?= $type == 'custom' ? '' : ' style="display:none;"' ?>>
|
19 |
+
<?= Html::textInput(null, $size, [
|
20 |
+
'class' => 'lwptocWidthField_sizeInput',
|
21 |
+
]) ?>
|
22 |
+
<?= Html::dropDownList(null, $unit, Core::$plugin->blockSizeUnitsList, [
|
23 |
+
'class' => 'lwptocWidthField_unitInput',
|
24 |
+
]) ?>
|
25 |
+
</div>
|
26 |
+
<?= Html::hiddenInput($name, $value, ['class' => 'lwptocWidthField_input']) ?>
|
27 |
+
</div>
|
config/plugin.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
return [
|
3 |
+
'textDomain' => 'lwptoc',
|
4 |
+
'bootstrap' => [
|
5 |
+
'activation',
|
6 |
+
'admin',
|
7 |
+
'editorBlock',
|
8 |
+
'front',
|
9 |
+
'mcePlugin',
|
10 |
+
'shortcode',
|
11 |
+
],
|
12 |
+
'pluginsLoadedBootstrap' => [
|
13 |
+
'settings',
|
14 |
+
],
|
15 |
+
'components' => [
|
16 |
+
'activation' => \luckywp\tableOfContents\plugin\Activation::className(),
|
17 |
+
'admin' => \luckywp\tableOfContents\admin\Admin::className(),
|
18 |
+
'front' => \luckywp\tableOfContents\front\Front::className(),
|
19 |
+
'mcePlugin' => \luckywp\tableOfContents\plugin\mcePlugin\McePlugin::className(),
|
20 |
+
'request' => \luckywp\tableOfContents\core\base\Request::className(),
|
21 |
+
'settings' => [
|
22 |
+
'class' => \luckywp\tableOfContents\plugin\Settings::className(),
|
23 |
+
'initGroupsConfigFile' => __DIR__ . '/settings.php',
|
24 |
+
],
|
25 |
+
'editorBlock' => \luckywp\tableOfContents\plugin\editorBlock\EditorBlock::className(),
|
26 |
+
'shortcode' => \luckywp\tableOfContents\plugin\Shortcode::className(),
|
27 |
+
'view' => \luckywp\tableOfContents\core\base\View::className(),
|
28 |
+
],
|
29 |
+
];
|
config/settings.php
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use luckywp\tableOfContents\admin\widgets\fontSizeField\FontSizeField;
|
4 |
+
use luckywp\tableOfContents\admin\widgets\widthField\WidthField;
|
5 |
+
use luckywp\tableOfContents\core\admin\helpers\AdminHtml;
|
6 |
+
use luckywp\tableOfContents\admin\widgets\PostTypes;
|
7 |
+
use luckywp\tableOfContents\core\Core;
|
8 |
+
|
9 |
+
return [
|
10 |
+
|
11 |
+
// Основные настройки
|
12 |
+
'general' => [
|
13 |
+
'label' => esc_html__('General', 'lwptoc'),
|
14 |
+
'sections' => [
|
15 |
+
'main' => [
|
16 |
+
'fields' => [
|
17 |
+
|
18 |
+
'min' => [
|
19 |
+
'label' => esc_html__('Minimal Count of Headers', 'lwptoc'),
|
20 |
+
'widget' => 'textInput',
|
21 |
+
'params' => [
|
22 |
+
'inputOptions' => [
|
23 |
+
'size' => AdminHtml::TEXT_INPUT_SIZE_SMALL,
|
24 |
+
],
|
25 |
+
],
|
26 |
+
'default' => 2,
|
27 |
+
'desc' => esc_html__('If the count of headers in the post is less, then table of contents is not displayed.', 'lwptoc'),
|
28 |
+
],
|
29 |
+
|
30 |
+
'depth' => [
|
31 |
+
'label' => esc_html__('Depth', 'lwptoc'),
|
32 |
+
'widget' => 'select',
|
33 |
+
'params' => [
|
34 |
+
'items' => Core::$plugin->depthsList,
|
35 |
+
],
|
36 |
+
'default' => 6,
|
37 |
+
],
|
38 |
+
|
39 |
+
'hierarchical' => [
|
40 |
+
'label' => esc_html__('Hierarchical View', 'lwptoc'),
|
41 |
+
'widget' => 'checkbox',
|
42 |
+
'params' => [
|
43 |
+
'checkboxOptions' => [
|
44 |
+
'label' => esc_html__('Enable', 'lwptoc'),
|
45 |
+
],
|
46 |
+
],
|
47 |
+
'default' => true,
|
48 |
+
],
|
49 |
+
|
50 |
+
'numeration' => [
|
51 |
+
'label' => esc_html__('Numeration', 'lwptoc'),
|
52 |
+
'widget' => 'select',
|
53 |
+
'params' => [
|
54 |
+
'items' => Core::$plugin->numerationsList,
|
55 |
+
],
|
56 |
+
'default' => 'decimalnested',
|
57 |
+
],
|
58 |
+
],
|
59 |
+
],
|
60 |
+
|
61 |
+
'header' => [
|
62 |
+
'title' => esc_html__('Header', 'lwptoc'),
|
63 |
+
'fields' => [
|
64 |
+
|
65 |
+
'title' => [
|
66 |
+
'label' => esc_html__('Title', 'lwptoc'),
|
67 |
+
'widget' => 'textInput',
|
68 |
+
'default' => __('Contents', 'lwptoc'),
|
69 |
+
],
|
70 |
+
|
71 |
+
'toggle' => [
|
72 |
+
'label' => esc_html__('Toggle Show/Hide', 'lwptoc'),
|
73 |
+
'widget' => 'checkbox',
|
74 |
+
'params' => [
|
75 |
+
'checkboxOptions' => [
|
76 |
+
'label' => esc_html__('Enable', 'lwptoc'),
|
77 |
+
'class' => 'js-lwptocToggleCheckbox',
|
78 |
+
],
|
79 |
+
],
|
80 |
+
'default' => true,
|
81 |
+
],
|
82 |
+
|
83 |
+
'labelShow' => [
|
84 |
+
'label' => esc_html__('Label Show', 'lwptoc'),
|
85 |
+
'widget' => 'textInput',
|
86 |
+
'params' => [
|
87 |
+
'inputOptions' => [
|
88 |
+
'class' => 'js-lwptocToggleEl'
|
89 |
+
],
|
90 |
+
],
|
91 |
+
'default' => __('show', 'lwptoc'),
|
92 |
+
],
|
93 |
+
|
94 |
+
'labelHide' => [
|
95 |
+
'label' => esc_html__('Label Hide', 'lwptoc'),
|
96 |
+
'widget' => 'textInput',
|
97 |
+
'params' => [
|
98 |
+
'inputOptions' => [
|
99 |
+
'class' => 'js-lwptocToggleEl'
|
100 |
+
],
|
101 |
+
],
|
102 |
+
'default' => __('hide', 'lwptoc'),
|
103 |
+
],
|
104 |
+
|
105 |
+
'hideItems' => [
|
106 |
+
'label' => '',
|
107 |
+
'widget' => 'checkbox',
|
108 |
+
'params' => [
|
109 |
+
'checkboxOptions' => [
|
110 |
+
'label' => esc_html__('By default, items of contents will be hidden', 'lwptoc'),
|
111 |
+
'class' => 'js-lwptocToggleEl',
|
112 |
+
],
|
113 |
+
],
|
114 |
+
'default' => false,
|
115 |
+
],
|
116 |
+
],
|
117 |
+
],
|
118 |
+
'behavior' => [
|
119 |
+
'title' => esc_html__('Behavior', 'lwptoc'),
|
120 |
+
'fields' => [
|
121 |
+
|
122 |
+
'smoothScroll' => [
|
123 |
+
'label' => esc_html__('Smooth Scroll', 'lwptoc'),
|
124 |
+
'widget' => 'checkbox',
|
125 |
+
'params' => [
|
126 |
+
'checkboxOptions' => [
|
127 |
+
'label' => esc_html__('Enable', 'lwptoc'),
|
128 |
+
'class' => 'js-lwptocSmoothScrollCheckbox',
|
129 |
+
],
|
130 |
+
],
|
131 |
+
'default' => true,
|
132 |
+
],
|
133 |
+
|
134 |
+
'smoothScrollOffset' => [
|
135 |
+
'label' => esc_html__('Scroll Offset Top', 'lwptoc'),
|
136 |
+
'widget' => 'textInput',
|
137 |
+
'params' => [
|
138 |
+
'inputOptions' => [
|
139 |
+
'size' => AdminHtml::TEXT_INPUT_SIZE_SMALL,
|
140 |
+
'class' => 'js-lwptocSmoothScrollIOffsetInput'
|
141 |
+
],
|
142 |
+
'after' => ' px',
|
143 |
+
],
|
144 |
+
'default' => 24,
|
145 |
+
],
|
146 |
+
],
|
147 |
+
],
|
148 |
+
],
|
149 |
+
],
|
150 |
+
|
151 |
+
// Внешний вид
|
152 |
+
'appearance' => [
|
153 |
+
'label' => esc_html__('Appearance', 'lwptoc'),
|
154 |
+
'sections' => [
|
155 |
+
'main' => [
|
156 |
+
'fields' => [
|
157 |
+
|
158 |
+
'width' => [
|
159 |
+
'label' => esc_html__('Width', 'lwptoc'),
|
160 |
+
'widget' => function ($field) {
|
161 |
+
echo WidthField::widget([
|
162 |
+
'name' => $field['name'],
|
163 |
+
'value' => Core::$plugin->settings->getValue($field['group'], $field['id'], 'auto', false),
|
164 |
+
]);
|
165 |
+
},
|
166 |
+
'sanitizeCallback' => [Core::$plugin->settings, 'sanitizeWidth'],
|
167 |
+
'default' => 'auto',
|
168 |
+
],
|
169 |
+
|
170 |
+
'float' => [
|
171 |
+
'label' => esc_html__('Float', 'lwptoc'),
|
172 |
+
'widget' => 'select',
|
173 |
+
'params' => [
|
174 |
+
'items' => Core::$plugin->floatsList,
|
175 |
+
],
|
176 |
+
'default' => 'none',
|
177 |
+
],
|
178 |
+
|
179 |
+
'titleFontSize' => [
|
180 |
+
'label' => esc_html__('Title Font Size', 'lwptoc'),
|
181 |
+
'widget' => function ($field) {
|
182 |
+
echo FontSizeField::widget([
|
183 |
+
'name' => $field['name'],
|
184 |
+
'value' => Core::$plugin->settings->getValue($field['group'], $field['id'], 'default', false),
|
185 |
+
'defaultSize' => 100,
|
186 |
+
]);
|
187 |
+
},
|
188 |
+
'sanitizeCallback' => [Core::$plugin->settings, 'sanitizeFontSize'],
|
189 |
+
'default' => 'default',
|
190 |
+
],
|
191 |
+
|
192 |
+
'titleFontWeight' => [
|
193 |
+
'label' => esc_html__('Title Font Weight', 'lwptoc'),
|
194 |
+
'widget' => 'select',
|
195 |
+
'params' => [
|
196 |
+
'items' => Core::$plugin->fontWeightsList,
|
197 |
+
],
|
198 |
+
'default' => 'bold',
|
199 |
+
],
|
200 |
+
|
201 |
+
'itemsFontSize' => [
|
202 |
+
'label' => esc_html__('Items Font Size', 'lwptoc'),
|
203 |
+
'widget' => function ($field) {
|
204 |
+
echo FontSizeField::widget([
|
205 |
+
'name' => $field['name'],
|
206 |
+
'value' => Core::$plugin->settings->getValue($field['group'], $field['id'], 'default', false),
|
207 |
+
'defaultSize' => 90,
|
208 |
+
]);
|
209 |
+
},
|
210 |
+
'sanitizeCallback' => [Core::$plugin->settings, 'sanitizeFontSize'],
|
211 |
+
'default' => '90%',
|
212 |
+
],
|
213 |
+
|
214 |
+
'colorScheme' => [
|
215 |
+
'label' => esc_html__('Color Scheme', 'lwptoc'),
|
216 |
+
'widget' => 'select',
|
217 |
+
'params' => [
|
218 |
+
'items' => Core::$plugin->colorSchemesList,
|
219 |
+
],
|
220 |
+
'default' => 'light',
|
221 |
+
],
|
222 |
+
],
|
223 |
+
],
|
224 |
+
'overrideColors' => [
|
225 |
+
'title' => esc_html__('Override Color Scheme Colors', 'lwptoc'),
|
226 |
+
'fields' => [
|
227 |
+
|
228 |
+
'backgroundColor' => [
|
229 |
+
'widget' => 'color',
|
230 |
+
'label' => esc_html__('Background Color', 'lwptoc'),
|
231 |
+
],
|
232 |
+
|
233 |
+
'borderColor' => [
|
234 |
+
'widget' => 'color',
|
235 |
+
'label' => esc_html__('Border Color', 'lwptoc'),
|
236 |
+
],
|
237 |
+
|
238 |
+
'titleColor' => [
|
239 |
+
'widget' => 'color',
|
240 |
+
'label' => esc_html__('Title Color', 'lwptoc'),
|
241 |
+
],
|
242 |
+
|
243 |
+
'linkColor' => [
|
244 |
+
'widget' => 'color',
|
245 |
+
'label' => esc_html__('Link Color', 'lwptoc'),
|
246 |
+
],
|
247 |
+
|
248 |
+
'hoverLinkColor' => [
|
249 |
+
'widget' => 'color',
|
250 |
+
'label' => esc_html__('Hover Link Color', 'lwptoc'),
|
251 |
+
],
|
252 |
+
|
253 |
+
'visitedLinkColor' => [
|
254 |
+
'widget' => 'color',
|
255 |
+
'label' => esc_html__('Visited Link Color', 'lwptoc'),
|
256 |
+
],
|
257 |
+
],
|
258 |
+
],
|
259 |
+
],
|
260 |
+
],
|
261 |
+
|
262 |
+
// Автоматическая вставка
|
263 |
+
'autoInsert' => [
|
264 |
+
'label' => esc_html__('Auto Insert', 'lwptoc'),
|
265 |
+
'sections' => [
|
266 |
+
'main' => [
|
267 |
+
'fields' => [
|
268 |
+
|
269 |
+
'enable' => [
|
270 |
+
'label' => esc_html__('Auto Insert Table of Contents', 'lwptoc'),
|
271 |
+
'widget' => 'checkbox',
|
272 |
+
'params' => [
|
273 |
+
'checkboxOptions' => [
|
274 |
+
'label' => esc_html__('Enable', 'lwptoc'),
|
275 |
+
'class' => 'js-lwptocAutoInsertEnableCheckbox',
|
276 |
+
],
|
277 |
+
],
|
278 |
+
'default' => true,
|
279 |
+
],
|
280 |
+
|
281 |
+
'position' => [
|
282 |
+
'label' => esc_html__('Position', 'lwptoc'),
|
283 |
+
'widget' => 'select',
|
284 |
+
'params' => [
|
285 |
+
'items' => Core::$plugin->positionsList,
|
286 |
+
'selectOptions' => [
|
287 |
+
'class' => 'js-lwptocAutoInsertEl',
|
288 |
+
],
|
289 |
+
],
|
290 |
+
'default' => 'beforefirstheading',
|
291 |
+
],
|
292 |
+
|
293 |
+
'postTypes' => [
|
294 |
+
'label' => esc_html__('Post Types', 'lwptoc'),
|
295 |
+
'widget' => function ($field) {
|
296 |
+
echo PostTypes::widget([
|
297 |
+
'field' => $field,
|
298 |
+
'containerOptions' => [
|
299 |
+
'class' => 'js-lwptocAutoInsertEl',
|
300 |
+
],
|
301 |
+
]);
|
302 |
+
},
|
303 |
+
'default' => ['post'],
|
304 |
+
],
|
305 |
+
],
|
306 |
+
],
|
307 |
+
],
|
308 |
+
],
|
309 |
+
];
|
core/Core.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use luckywp\tableOfContents\core\base\BasePlugin;
|
7 |
+
use luckywp\tableOfContents\core\base\Container;
|
8 |
+
|
9 |
+
class Core
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var Container
|
14 |
+
*/
|
15 |
+
public static $container;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var \luckywp\tableOfContents\plugin\Plugin
|
19 |
+
*/
|
20 |
+
public static $plugin;
|
21 |
+
|
22 |
+
public static function initialize(BasePlugin $plugin)
|
23 |
+
{
|
24 |
+
static::$container = new Container();
|
25 |
+
static::$plugin = $plugin;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @param object $object
|
30 |
+
* @param array $properties
|
31 |
+
* @return object
|
32 |
+
*/
|
33 |
+
public static function configure($object, $properties)
|
34 |
+
{
|
35 |
+
foreach ($properties as $name => $value) {
|
36 |
+
$object->$name = $value;
|
37 |
+
}
|
38 |
+
return $object;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param string|array $type
|
43 |
+
* @param array $params
|
44 |
+
* @return object
|
45 |
+
*/
|
46 |
+
public static function createObject($type, array $params = [])
|
47 |
+
{
|
48 |
+
if (is_string($type)) {
|
49 |
+
return static::$container->get($type, $params);
|
50 |
+
} elseif (is_array($type) && isset($type['class'])) {
|
51 |
+
$class = $type['class'];
|
52 |
+
unset($type['class']);
|
53 |
+
return static::$container->get($class, $params, $type);
|
54 |
+
}
|
55 |
+
throw new Exception('Unsupported configuration type: ' . gettype($type));
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @return bool
|
60 |
+
*/
|
61 |
+
public static function isFront()
|
62 |
+
{
|
63 |
+
return !is_admin() && !wp_doing_ajax();
|
64 |
+
}
|
65 |
+
}
|
core/admin/AdminController.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\admin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\admin\helpers\AdminUrl;
|
6 |
+
use luckywp\tableOfContents\core\base\Controller;
|
7 |
+
use luckywp\tableOfContents\core\Core;
|
8 |
+
|
9 |
+
class AdminController extends Controller
|
10 |
+
{
|
11 |
+
|
12 |
+
private $_action;
|
13 |
+
|
14 |
+
public function init()
|
15 |
+
{
|
16 |
+
parent::init();
|
17 |
+
if (AdminUrl::isPage($this->id)) {
|
18 |
+
$methodName = 'handle' . ucfirst($this->getAction());
|
19 |
+
if (method_exists($this, $methodName)) {
|
20 |
+
add_action('wp_loaded', [$this, $methodName]);
|
21 |
+
}
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
public function getAction()
|
26 |
+
{
|
27 |
+
if ($this->_action === null) {
|
28 |
+
$this->_action = Core::$plugin->request->get('action', 'index');
|
29 |
+
}
|
30 |
+
return $this->_action;
|
31 |
+
}
|
32 |
+
|
33 |
+
public static function router()
|
34 |
+
{
|
35 |
+
/** @var self $controller */
|
36 |
+
$controller = static::getInstance();
|
37 |
+
$methodName = 'action' . ucfirst($controller->getAction());
|
38 |
+
if (!method_exists($controller, $methodName)) {
|
39 |
+
$controller->notAllowed();
|
40 |
+
}
|
41 |
+
$controller->$methodName();
|
42 |
+
}
|
43 |
+
|
44 |
+
public function notAllowed()
|
45 |
+
{
|
46 |
+
wp_die(esc_html__('Sorry, you are not allowed to access this page.', 'lwptoc'), 403);
|
47 |
+
}
|
48 |
+
}
|
core/admin/helpers/AdminHtml.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\admin\helpers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
6 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
7 |
+
|
8 |
+
class AdminHtml
|
9 |
+
{
|
10 |
+
|
11 |
+
const BUTTON_SIZE_SMALL = 'small';
|
12 |
+
const BUTTON_SIZE_LARGE = 'large';
|
13 |
+
const BUTTON_SIZE_HERO = 'hero';
|
14 |
+
|
15 |
+
const BUTTON_THEME_PRIMARY = 'primary';
|
16 |
+
const BUTTON_THEME_SECONDARY = 'secondary';
|
17 |
+
const BUTTON_THEME_LINK = 'link';
|
18 |
+
const BUTTON_THEME_LINK_DELETE = 'link button-link-delete';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param $content
|
22 |
+
* @param array $options
|
23 |
+
* @return string
|
24 |
+
*/
|
25 |
+
public static function button($content, $options = [])
|
26 |
+
{
|
27 |
+
$submit = isset($options['submit']) ? (bool)$options['submit'] : false;
|
28 |
+
$href = isset($options['href']) ? $options['href'] : false;
|
29 |
+
$class = isset($options['class']) ? $options['class'] : false;
|
30 |
+
$size = isset($options['size']) ? $options['size'] : false;
|
31 |
+
$theme = isset($options['theme']) ? $options['theme'] : false;
|
32 |
+
$attrs = isset($options['attrs']) ? $options['attrs'] : [];
|
33 |
+
$tag = isset($options['tag']) ? strtolower($options['tag']) : ($href ? 'a' : 'button');
|
34 |
+
|
35 |
+
if (isset($attrs['class'])) {
|
36 |
+
if (!is_array($attrs['class'])) {
|
37 |
+
$attrs['class'] = explode(' ', $attrs['class']);
|
38 |
+
}
|
39 |
+
} else {
|
40 |
+
$attrs['class'] = is_array($class) ? $class : ($class === false ? [] : [$class]);
|
41 |
+
}
|
42 |
+
$attrs['class'][] = 'button';
|
43 |
+
|
44 |
+
if (($tag == 'input') && (!isset($attrs['value']))) {
|
45 |
+
$attrs['value'] = $content;
|
46 |
+
}
|
47 |
+
|
48 |
+
if ($size) {
|
49 |
+
$attrs['class'][] = 'button-' . $size;
|
50 |
+
}
|
51 |
+
|
52 |
+
if ($theme) {
|
53 |
+
$attrs['class'][] = 'button-' . $theme;
|
54 |
+
}
|
55 |
+
|
56 |
+
if (($tag == 'a') && ($href !== false)) {
|
57 |
+
$attrs['href'] = $href;
|
58 |
+
}
|
59 |
+
|
60 |
+
if (($tag == 'input') || ($tag == 'button')) {
|
61 |
+
$attrs['type'] = $submit ? 'submit' : 'button';
|
62 |
+
}
|
63 |
+
|
64 |
+
return Html::tag($tag, $content, $attrs);
|
65 |
+
}
|
66 |
+
|
67 |
+
const TEXT_INPUT_SIZE_REGULAR = 'regular';
|
68 |
+
const TEXT_INPUT_SIZE_SMALL = 'small';
|
69 |
+
const TEXT_INPUT_SIZE_LARGE = 'large';
|
70 |
+
|
71 |
+
public static function textInput($name, $value, $options = [])
|
72 |
+
{
|
73 |
+
$options = Html::prepareClassInOptions($options);
|
74 |
+
|
75 |
+
if ('' != $size = ArrayHelper::getValue($options, 'size')) {
|
76 |
+
$options['class'][] = $size . '-text';
|
77 |
+
unset($options['size']);
|
78 |
+
} else {
|
79 |
+
$options['class'][] = $size . 'regular-text';
|
80 |
+
}
|
81 |
+
|
82 |
+
return Html::textInput($name, $value, $options);
|
83 |
+
}
|
84 |
+
}
|
core/admin/helpers/AdminUrl.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\admin\helpers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\Core;
|
6 |
+
|
7 |
+
class AdminUrl
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param string $pageId
|
12 |
+
* @param string|null $action
|
13 |
+
* @param array $params
|
14 |
+
* @return string
|
15 |
+
*/
|
16 |
+
public static function toOptions($pageId, $action = null, $params = [])
|
17 |
+
{
|
18 |
+
return static::makeUrl('options-general.php', $pageId, $action, $params);
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param string $wpPage
|
23 |
+
* @param string $pageId
|
24 |
+
* @param string|null $action
|
25 |
+
* @param array $params
|
26 |
+
* @return string
|
27 |
+
*/
|
28 |
+
protected static function makeUrl($wpPage, $pageId, $action = null, $params = [])
|
29 |
+
{
|
30 |
+
$params['page'] = Core::$plugin->prefix . $pageId;
|
31 |
+
if ($action !== null) {
|
32 |
+
$params['action'] = $action;
|
33 |
+
}
|
34 |
+
return admin_url($wpPage . '?' . http_build_query($params));
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @param string $pageId
|
39 |
+
* @param string $action
|
40 |
+
* @return bool
|
41 |
+
*/
|
42 |
+
public static function isPage($pageId, $action = '')
|
43 |
+
{
|
44 |
+
return Core::$plugin->request->get('page') == Core::$plugin->prefix . $pageId
|
45 |
+
&& (!$action || Core::$plugin->request->get('action') == $action);
|
46 |
+
}
|
47 |
+
}
|
core/base/BaseObject.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
|
8 |
+
abstract class BaseObject
|
9 |
+
{
|
10 |
+
|
11 |
+
public function __construct($config = [])
|
12 |
+
{
|
13 |
+
if (!empty($config)) {
|
14 |
+
Core::configure($this, $config);
|
15 |
+
}
|
16 |
+
$this->init();
|
17 |
+
}
|
18 |
+
|
19 |
+
public function init()
|
20 |
+
{
|
21 |
+
}
|
22 |
+
|
23 |
+
public static function className()
|
24 |
+
{
|
25 |
+
return get_called_class();
|
26 |
+
}
|
27 |
+
|
28 |
+
public function __get($name)
|
29 |
+
{
|
30 |
+
$getter = 'get' . $name;
|
31 |
+
if (method_exists($this, $getter)) {
|
32 |
+
return $this->$getter();
|
33 |
+
}
|
34 |
+
throw new Exception('Getting unknown property: ' . get_class($this) . '::' . $name);
|
35 |
+
}
|
36 |
+
|
37 |
+
public function __set($name, $value)
|
38 |
+
{
|
39 |
+
$setter = 'set' . $name;
|
40 |
+
if (method_exists($this, $setter)) {
|
41 |
+
$this->$setter($value);
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
throw new Exception('Setting unknown property: ' . get_class($this) . '::' . $name);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function __isset($name)
|
48 |
+
{
|
49 |
+
$getter = 'get' . $name;
|
50 |
+
if (method_exists($this, $getter)) {
|
51 |
+
return $this->$getter() !== null;
|
52 |
+
}
|
53 |
+
return false;
|
54 |
+
}
|
55 |
+
|
56 |
+
public function __unset($name)
|
57 |
+
{
|
58 |
+
$setter = 'set' . $name;
|
59 |
+
if (method_exists($this, $setter)) {
|
60 |
+
$this->$setter(null);
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
throw new Exception('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
|
64 |
+
}
|
65 |
+
}
|
core/base/BasePlugin.php
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @property string $basename
|
9 |
+
*/
|
10 |
+
abstract class BasePlugin extends ServiceLocator
|
11 |
+
{
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
public $version;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
public $fileName;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $dir;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $url;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public $prefix;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $textDomain;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var string
|
45 |
+
*/
|
46 |
+
public $domainPath = 'languages/';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @var array
|
50 |
+
*/
|
51 |
+
public $bootstrap = [];
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @var array
|
55 |
+
*/
|
56 |
+
public $pluginsLoadedBootstrap = [];
|
57 |
+
|
58 |
+
public function __construct(array $config = [])
|
59 |
+
{
|
60 |
+
Core::initialize($this);
|
61 |
+
add_action('plugins_loaded', function () {
|
62 |
+
if ($this->textDomain) {
|
63 |
+
load_plugin_textdomain($this->textDomain, false, basename($this->dir) . '/' . $this->domainPath);
|
64 |
+
}
|
65 |
+
$this->bootstrap($this->pluginsLoadedBootstrap);
|
66 |
+
});
|
67 |
+
parent::__construct($config);
|
68 |
+
}
|
69 |
+
|
70 |
+
protected function bootstrap($bootstrap)
|
71 |
+
{
|
72 |
+
foreach ($bootstrap as $mixed) {
|
73 |
+
$component = null;
|
74 |
+
if (is_callable($mixed)) {
|
75 |
+
if (!$component = call_user_func($mixed, $this)) {
|
76 |
+
continue;
|
77 |
+
}
|
78 |
+
} elseif (is_string($mixed) && $this->has($mixed)) {
|
79 |
+
$this->get($mixed);
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
public function run($version, $fileName, $prefix)
|
85 |
+
{
|
86 |
+
$this->version = $version;
|
87 |
+
$this->fileName = $fileName;
|
88 |
+
$this->dir = dirname($fileName);
|
89 |
+
$this->url = plugins_url('', $fileName);
|
90 |
+
$this->prefix = $prefix;
|
91 |
+
$this->bootstrap($this->bootstrap);
|
92 |
+
}
|
93 |
+
|
94 |
+
public function getBasename()
|
95 |
+
{
|
96 |
+
return plugin_basename($this->fileName);
|
97 |
+
}
|
98 |
+
}
|
core/base/Container.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
use ReflectionClass;
|
8 |
+
|
9 |
+
class Container
|
10 |
+
{
|
11 |
+
private $_singletons = [];
|
12 |
+
private $_definitions = [];
|
13 |
+
private $_params = [];
|
14 |
+
private $_reflections = [];
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param string $class
|
18 |
+
* @param array $params
|
19 |
+
* @param array $config
|
20 |
+
* @return object
|
21 |
+
*/
|
22 |
+
public function get($class, $params = [], $config = [])
|
23 |
+
{
|
24 |
+
if (isset($this->_singletons[$class])) {
|
25 |
+
return $this->_singletons[$class];
|
26 |
+
} elseif (!isset($this->_definitions[$class])) {
|
27 |
+
return $this->build($class, $params, $config);
|
28 |
+
}
|
29 |
+
|
30 |
+
$definition = $this->_definitions[$class];
|
31 |
+
|
32 |
+
if (is_callable($definition, true)) {
|
33 |
+
$params = $this->mergeParams($class, $params);
|
34 |
+
$object = call_user_func($definition, $this, $params, $config);
|
35 |
+
} elseif (is_array($definition)) {
|
36 |
+
$concrete = $definition['class'];
|
37 |
+
unset($definition['class']);
|
38 |
+
|
39 |
+
$config = array_merge($definition, $config);
|
40 |
+
$params = $this->mergeParams($class, $params);
|
41 |
+
|
42 |
+
if ($concrete === $class) {
|
43 |
+
$object = $this->build($class, $params, $config);
|
44 |
+
} else {
|
45 |
+
$object = $this->get($concrete, $params, $config);
|
46 |
+
}
|
47 |
+
} elseif (is_object($definition)) {
|
48 |
+
return $this->_singletons[$class] = $definition;
|
49 |
+
} else {
|
50 |
+
throw new Exception('Unexpected object definition type: ' . gettype($definition));
|
51 |
+
}
|
52 |
+
|
53 |
+
if (array_key_exists($class, $this->_singletons)) {
|
54 |
+
$this->_singletons[$class] = $object;
|
55 |
+
}
|
56 |
+
|
57 |
+
return $object;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param string $class
|
62 |
+
* @param string|array|callable $definition
|
63 |
+
* @param array $params
|
64 |
+
* @return $this
|
65 |
+
*/
|
66 |
+
public function set($class, $definition = [], array $params = [])
|
67 |
+
{
|
68 |
+
$this->_definitions[$class] = $this->normalizeDefinition($class, $definition);
|
69 |
+
$this->_params[$class] = $params;
|
70 |
+
unset($this->_singletons[$class]);
|
71 |
+
return $this;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param string $class
|
76 |
+
* @param string|array|callable $definition
|
77 |
+
* @param array $params
|
78 |
+
* @return $this
|
79 |
+
*/
|
80 |
+
public function setSingleton($class, $definition = [], array $params = [])
|
81 |
+
{
|
82 |
+
$this->_definitions[$class] = $this->normalizeDefinition($class, $definition);
|
83 |
+
$this->_params[$class] = $params;
|
84 |
+
$this->_singletons[$class] = null;
|
85 |
+
return $this;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param string $class
|
90 |
+
* @param array $params
|
91 |
+
* @return array
|
92 |
+
*/
|
93 |
+
protected function mergeParams($class, $params)
|
94 |
+
{
|
95 |
+
if (empty($this->_params[$class])) {
|
96 |
+
return $params;
|
97 |
+
} elseif (empty($params)) {
|
98 |
+
return $this->_params[$class];
|
99 |
+
}
|
100 |
+
|
101 |
+
$ps = $this->_params[$class];
|
102 |
+
foreach ($params as $index => $value) {
|
103 |
+
$ps[$index] = $value;
|
104 |
+
}
|
105 |
+
|
106 |
+
return $ps;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @param string $class
|
111 |
+
* @param string|array|callable $definition
|
112 |
+
* @return array
|
113 |
+
*/
|
114 |
+
protected function normalizeDefinition($class, $definition)
|
115 |
+
{
|
116 |
+
if (empty($definition)) {
|
117 |
+
return ['class' => $class];
|
118 |
+
} elseif (is_string($definition)) {
|
119 |
+
return ['class' => $definition];
|
120 |
+
} elseif (is_callable($definition, true) || is_object($definition)) {
|
121 |
+
return $definition;
|
122 |
+
} elseif (is_array($definition)) {
|
123 |
+
if (!isset($definition['class'])) {
|
124 |
+
if (strpos($class, '\\') !== false) {
|
125 |
+
$definition['class'] = $class;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
return $definition;
|
129 |
+
}
|
130 |
+
throw new Exception('Unsupported definition type for "' . $class . '": ' . gettype($definition));
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* @param string $class
|
135 |
+
* @param array $params
|
136 |
+
* @param array $config
|
137 |
+
* @return object
|
138 |
+
*/
|
139 |
+
protected function build($class, array $params, array $config)
|
140 |
+
{
|
141 |
+
if (isset($this->_reflections[$class])) {
|
142 |
+
$reflection = $this->_reflections[$class];
|
143 |
+
} else {
|
144 |
+
$reflection = new ReflectionClass($class);
|
145 |
+
$this->_reflections[$class] = $reflection;
|
146 |
+
}
|
147 |
+
|
148 |
+
if ($reflection->isSubclassOf(BaseObject::className())) {
|
149 |
+
$params[] = $config;
|
150 |
+
$object = $reflection->newInstanceArgs($params);
|
151 |
+
} else {
|
152 |
+
$object = $reflection->newInstanceArgs($params);
|
153 |
+
if ($config) {
|
154 |
+
Core::configure($object, $config);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
return $object;
|
159 |
+
}
|
160 |
+
}
|
core/base/Controller.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\Core;
|
6 |
+
use ReflectionClass;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @property string $id
|
10 |
+
*/
|
11 |
+
abstract class Controller extends BaseObject implements ViewContextInterface
|
12 |
+
{
|
13 |
+
|
14 |
+
private $_id;
|
15 |
+
|
16 |
+
public function getId()
|
17 |
+
{
|
18 |
+
if ($this->_id === null) {
|
19 |
+
$class = new ReflectionClass($this);
|
20 |
+
$this->_id .= lcfirst(substr($class->getShortName(), 0, -10));
|
21 |
+
}
|
22 |
+
return $this->_id;
|
23 |
+
}
|
24 |
+
|
25 |
+
private $_viewPath;
|
26 |
+
|
27 |
+
public function getViewPath()
|
28 |
+
{
|
29 |
+
if ($this->_viewPath === null) {
|
30 |
+
$class = new ReflectionClass($this);
|
31 |
+
$this->_viewPath = dirname($class->getFileName()) . '/../views';
|
32 |
+
$this->_viewPath .= '/' . $this->id;
|
33 |
+
}
|
34 |
+
return $this->_viewPath;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @param string $view
|
39 |
+
* @return array
|
40 |
+
*/
|
41 |
+
public function getViewFiles($view)
|
42 |
+
{
|
43 |
+
return [$this->getViewPath() . '/' . $view . '.php'];
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param string $view
|
48 |
+
* @param array $params
|
49 |
+
* @param bool $echo
|
50 |
+
* @return string|null
|
51 |
+
*/
|
52 |
+
public function render($view, $params = [], $echo = true)
|
53 |
+
{
|
54 |
+
$html = Core::$plugin->view->renderFile($this->getViewFiles($view), $params, $this);
|
55 |
+
if ($echo) {
|
56 |
+
echo $html;
|
57 |
+
return null;
|
58 |
+
}
|
59 |
+
return $html;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @return self
|
64 |
+
*/
|
65 |
+
public static function getInstance()
|
66 |
+
{
|
67 |
+
static $instances = [];
|
68 |
+
$className = static::className();
|
69 |
+
if (!isset($instances[$className])) {
|
70 |
+
$instances[$className] = Core::createObject($className);
|
71 |
+
}
|
72 |
+
return $instances[$className];
|
73 |
+
}
|
74 |
+
}
|
core/base/Model.php
ADDED
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
7 |
+
use luckywp\tableOfContents\core\validators\Validator;
|
8 |
+
use ReflectionClass;
|
9 |
+
use ReflectionProperty;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @property array $attributes
|
13 |
+
*/
|
14 |
+
abstract class Model extends BaseObject
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param array $data
|
19 |
+
* @param string $formName
|
20 |
+
* @return bool
|
21 |
+
*/
|
22 |
+
public function load($data, $formName = null)
|
23 |
+
{
|
24 |
+
$scope = $formName === null ? $this->formName() : $formName;
|
25 |
+
if ($scope === '' && !empty($data)) {
|
26 |
+
$this->setAttributes($data);
|
27 |
+
return true;
|
28 |
+
}
|
29 |
+
if (isset($data[$scope])) {
|
30 |
+
$this->setAttributes($data[$scope]);
|
31 |
+
return true;
|
32 |
+
}
|
33 |
+
return false;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @return string
|
38 |
+
*/
|
39 |
+
public function formName()
|
40 |
+
{
|
41 |
+
$reflector = new ReflectionClass($this);
|
42 |
+
return $reflector->getShortName();
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* ---------------------------------------------------------------------------
|
48 |
+
* Валидация
|
49 |
+
* ---------------------------------------------------------------------------
|
50 |
+
*/
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var Validator[]
|
54 |
+
*/
|
55 |
+
private $_validators;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param string $attribute
|
59 |
+
* @return Validator[]
|
60 |
+
*/
|
61 |
+
public function getValidators($attribute = null)
|
62 |
+
{
|
63 |
+
if ($this->_validators === null) {
|
64 |
+
$this->_validators = [];
|
65 |
+
foreach ($this->rules() as $rule) {
|
66 |
+
if ($rule instanceof Validator) {
|
67 |
+
$this->_validators[] = $rule;
|
68 |
+
} elseif (is_array($rule) && isset($rule[0], $rule[1])) {
|
69 |
+
$validator = Validator::createValidator($rule[1], $this, (array)$rule[0], array_slice($rule, 2));
|
70 |
+
$this->_validators[] = $validator;
|
71 |
+
} else {
|
72 |
+
throw new Exception('Invalid validation rule: a rule must specify both attribute names and validator type.');
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
if ($attribute === null) {
|
78 |
+
return $this->_validators;
|
79 |
+
}
|
80 |
+
|
81 |
+
$validators = [];
|
82 |
+
foreach ($this->_validators as $validator) {
|
83 |
+
if (in_array($attribute, $validator->getAttributeNames(), true)) {
|
84 |
+
$validators[] = $validator;
|
85 |
+
}
|
86 |
+
}
|
87 |
+
return $validators;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @param array $attributeNames
|
92 |
+
* @param bool $clearErrors
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
public function validate($attributeNames = null, $clearErrors = true)
|
96 |
+
{
|
97 |
+
if ($clearErrors) {
|
98 |
+
$this->clearErrors();
|
99 |
+
}
|
100 |
+
if ($attributeNames === null) {
|
101 |
+
$attributeNames = $this->attributeNames();
|
102 |
+
}
|
103 |
+
foreach ($this->getValidators() as $validator) {
|
104 |
+
$validator->validateAttributes($this, $attributeNames);
|
105 |
+
}
|
106 |
+
return !$this->hasErrors();
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @return array
|
111 |
+
*/
|
112 |
+
public function rules()
|
113 |
+
{
|
114 |
+
return [];
|
115 |
+
}
|
116 |
+
|
117 |
+
|
118 |
+
/**
|
119 |
+
* ---------------------------------------------------------------------------
|
120 |
+
* Атрибуты
|
121 |
+
* ---------------------------------------------------------------------------
|
122 |
+
*/
|
123 |
+
|
124 |
+
/**
|
125 |
+
* @var string[]
|
126 |
+
*/
|
127 |
+
private $_attributeNames;
|
128 |
+
|
129 |
+
/**
|
130 |
+
* @return string[]
|
131 |
+
*/
|
132 |
+
public function attributeNames()
|
133 |
+
{
|
134 |
+
if ($this->_attributeNames === null) {
|
135 |
+
$class = new ReflectionClass($this);
|
136 |
+
$this->_attributeNames = [];
|
137 |
+
foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
|
138 |
+
if (!$property->isStatic()) {
|
139 |
+
$this->_attributeNames[] = $property->getName();
|
140 |
+
}
|
141 |
+
}
|
142 |
+
}
|
143 |
+
return $this->_attributeNames;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @return string[]
|
148 |
+
*/
|
149 |
+
public function safeAttributeNames()
|
150 |
+
{
|
151 |
+
$names = [];
|
152 |
+
foreach ($this->getValidators() as $validator) {
|
153 |
+
foreach ($validator->attributes as $attribute) {
|
154 |
+
$names[] = $attribute;
|
155 |
+
}
|
156 |
+
}
|
157 |
+
return array_unique($names);
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @return array
|
162 |
+
*/
|
163 |
+
public function attributeLabels()
|
164 |
+
{
|
165 |
+
return [];
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @param string $attribute
|
170 |
+
* @return string
|
171 |
+
*/
|
172 |
+
public function getAttributeLabel($attribute)
|
173 |
+
{
|
174 |
+
return ArrayHelper::getValue($this->attributeLabels(), $attribute, $attribute);
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* @return array
|
179 |
+
*/
|
180 |
+
public function attributeHints()
|
181 |
+
{
|
182 |
+
return [];
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* @param array $names
|
187 |
+
* @return array
|
188 |
+
*/
|
189 |
+
public function getAttributes($names = null)
|
190 |
+
{
|
191 |
+
$values = [];
|
192 |
+
if ($names === null) {
|
193 |
+
$names = $this->attributeNames();
|
194 |
+
}
|
195 |
+
foreach ($names as $name) {
|
196 |
+
$values[$name] = $this->$name;
|
197 |
+
}
|
198 |
+
return $values;
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* @param array $values
|
203 |
+
* @param bool $safeOnly
|
204 |
+
*/
|
205 |
+
public function setAttributes($values, $safeOnly = true)
|
206 |
+
{
|
207 |
+
if (is_array($values)) {
|
208 |
+
$attributes = array_flip($safeOnly ? $this->safeAttributeNames() : $this->attributeNames());
|
209 |
+
foreach ($values as $name => $value) {
|
210 |
+
if (isset($attributes[$name])) {
|
211 |
+
$this->$name = $value;
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
/**
|
219 |
+
* ---------------------------------------------------------------------------
|
220 |
+
* Ошибки
|
221 |
+
* ---------------------------------------------------------------------------
|
222 |
+
*/
|
223 |
+
|
224 |
+
/**
|
225 |
+
* @var array
|
226 |
+
*/
|
227 |
+
private $_errors = [];
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @param string|null $attribute
|
231 |
+
* @return array
|
232 |
+
*/
|
233 |
+
public function getErrors($attribute = null)
|
234 |
+
{
|
235 |
+
if ($attribute === null) {
|
236 |
+
return $this->_errors;
|
237 |
+
}
|
238 |
+
return ArrayHelper::getValue($this->_errors, $attribute, []);
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* @return array
|
243 |
+
*/
|
244 |
+
public function getFirstErrors()
|
245 |
+
{
|
246 |
+
if (empty($this->_errors)) {
|
247 |
+
return [];
|
248 |
+
}
|
249 |
+
|
250 |
+
$errors = [];
|
251 |
+
foreach ($this->_errors as $name => $es) {
|
252 |
+
if (!empty($es)) {
|
253 |
+
$errors[$name] = reset($es);
|
254 |
+
}
|
255 |
+
}
|
256 |
+
return $errors;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* @param bool $showAllErrors
|
261 |
+
* @return array
|
262 |
+
*/
|
263 |
+
public function getErrorSummary($showAllErrors = true)
|
264 |
+
{
|
265 |
+
$lines = [];
|
266 |
+
$errors = $showAllErrors ? $this->getErrors() : $this->getFirstErrors();
|
267 |
+
foreach ($errors as $es) {
|
268 |
+
$lines = array_merge($lines, (array)$es);
|
269 |
+
}
|
270 |
+
return $lines;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* @param string $attribute
|
275 |
+
* @return string
|
276 |
+
*/
|
277 |
+
public function getFirstError($attribute)
|
278 |
+
{
|
279 |
+
return isset($this->_errors[$attribute]) ? reset($this->_errors[$attribute]) : null;
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* @param string $attribute
|
284 |
+
* @param string $error
|
285 |
+
*/
|
286 |
+
public function addError($attribute, $error = '')
|
287 |
+
{
|
288 |
+
$this->_errors[$attribute][] = $error;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* @param string|null $attribute
|
293 |
+
*/
|
294 |
+
public function clearErrors($attribute = null)
|
295 |
+
{
|
296 |
+
if ($attribute === null) {
|
297 |
+
$this->_errors = [];
|
298 |
+
} else {
|
299 |
+
unset($this->_errors[$attribute]);
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* @param string|null $attribute
|
305 |
+
* @return bool
|
306 |
+
*/
|
307 |
+
public function hasErrors($attribute = null)
|
308 |
+
{
|
309 |
+
return $attribute === null ? !empty($this->_errors) : isset($this->_errors[$attribute]);
|
310 |
+
}
|
311 |
+
}
|
core/base/Request.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
6 |
+
|
7 |
+
class Request extends BaseObject
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Возвращает значение, переданное методом GET.
|
12 |
+
* Значение приводится к исходному виду (по-умолчанию, WP экранирует символы)
|
13 |
+
* Если значения не существует, то функция вернёт $defaultValue
|
14 |
+
* @param string|null $name
|
15 |
+
* @param mixed $defaultValue
|
16 |
+
* @return mixed
|
17 |
+
*/
|
18 |
+
public function get($name = null, $defaultValue = null)
|
19 |
+
{
|
20 |
+
$value = $name === null ? $_GET : ArrayHelper::getValue($_GET, $name, $defaultValue);
|
21 |
+
return $value === null ? null : stripslashes_deep($value);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Возвращает значение, переданное методом POST.
|
26 |
+
* Значение приводится к исходному виду (по-умолчанию, WP экранирует символы)
|
27 |
+
* Если значения не существует, то функция вернёт $defaultValue
|
28 |
+
* @param string|null $name
|
29 |
+
* @param mixed $defaultValue
|
30 |
+
* @return mixed
|
31 |
+
*/
|
32 |
+
public function post($name = null, $defaultValue = null)
|
33 |
+
{
|
34 |
+
$value = $name === null ? $_POST : ArrayHelper::getValue($_POST, $name, $defaultValue);
|
35 |
+
return $value === null ? null : stripslashes_deep($value);
|
36 |
+
}
|
37 |
+
}
|
core/base/ServiceLocator.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use Closure;
|
6 |
+
use Exception;
|
7 |
+
use luckywp\tableOfContents\core\Core;
|
8 |
+
|
9 |
+
class ServiceLocator extends BaseObject
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var array
|
14 |
+
*/
|
15 |
+
private $_components = [];
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var array component
|
19 |
+
*/
|
20 |
+
private $_definitions = [];
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @param string $name
|
24 |
+
* @return mixed
|
25 |
+
*/
|
26 |
+
public function __get($name)
|
27 |
+
{
|
28 |
+
if ($this->has($name)) {
|
29 |
+
return $this->get($name);
|
30 |
+
}
|
31 |
+
return parent::__get($name);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param string $name
|
36 |
+
* @return bool
|
37 |
+
*/
|
38 |
+
public function __isset($name)
|
39 |
+
{
|
40 |
+
if ($this->has($name)) {
|
41 |
+
return true;
|
42 |
+
}
|
43 |
+
return parent::__isset($name);
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param string $id
|
48 |
+
* @param bool $checkInstance
|
49 |
+
* @return bool
|
50 |
+
* @see set()
|
51 |
+
*/
|
52 |
+
public function has($id, $checkInstance = false)
|
53 |
+
{
|
54 |
+
return $checkInstance ? isset($this->_components[$id]) : isset($this->_definitions[$id]);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param string $id
|
59 |
+
* @param bool $throwException
|
60 |
+
* @return object|null
|
61 |
+
*/
|
62 |
+
public function get($id, $throwException = true)
|
63 |
+
{
|
64 |
+
if (isset($this->_components[$id])) {
|
65 |
+
return $this->_components[$id];
|
66 |
+
}
|
67 |
+
|
68 |
+
if (isset($this->_definitions[$id])) {
|
69 |
+
$definition = $this->_definitions[$id];
|
70 |
+
if (is_object($definition) && !$definition instanceof Closure) {
|
71 |
+
return $this->_components[$id] = $definition;
|
72 |
+
}
|
73 |
+
return $this->_components[$id] = Core::createObject($definition);
|
74 |
+
}
|
75 |
+
|
76 |
+
if ($throwException) {
|
77 |
+
throw new Exception("Unknown component ID: $id");
|
78 |
+
}
|
79 |
+
return null;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @param string $id
|
84 |
+
* @param mixed $definition
|
85 |
+
*/
|
86 |
+
public function set($id, $definition)
|
87 |
+
{
|
88 |
+
unset($this->_components[$id]);
|
89 |
+
|
90 |
+
if ($definition === null) {
|
91 |
+
unset($this->_definitions[$id]);
|
92 |
+
return;
|
93 |
+
}
|
94 |
+
|
95 |
+
if (is_object($definition) || is_callable($definition, true)) {
|
96 |
+
$this->_definitions[$id] = $definition;
|
97 |
+
} elseif (is_array($definition)) {
|
98 |
+
$this->_definitions[$id] = $definition;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @param array $components
|
104 |
+
*/
|
105 |
+
public function setComponents($components)
|
106 |
+
{
|
107 |
+
foreach ($components as $id => $component) {
|
108 |
+
$this->set($id, $component);
|
109 |
+
}
|
110 |
+
}
|
111 |
+
}
|
core/base/View.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
class View extends BaseObject
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var array
|
10 |
+
*/
|
11 |
+
private $_vars = [];
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var ViewContextInterface
|
15 |
+
*/
|
16 |
+
public $context;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @param string $view
|
20 |
+
* @param array $params
|
21 |
+
* @param ViewContextInterface $context
|
22 |
+
* @return bool|string
|
23 |
+
*/
|
24 |
+
public function render($view, $params = [], $context = null)
|
25 |
+
{
|
26 |
+
$currentContext = $context ? $context : $this->context;
|
27 |
+
return $this->renderFile($currentContext->getViewFiles($view), $params, $context);
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @param array|string $files
|
32 |
+
* @param array $vars
|
33 |
+
* @param ViewContextInterface|null $context
|
34 |
+
* @return bool|string
|
35 |
+
*/
|
36 |
+
public function renderFile($files, $vars, $context = null)
|
37 |
+
{
|
38 |
+
$count = count($this->_vars);
|
39 |
+
$this->_vars[$count] = $count > 0 ? array_merge($this->_vars[$count - 1], $vars) : $vars;
|
40 |
+
|
41 |
+
if (!is_array($files)) {
|
42 |
+
$files = [$files];
|
43 |
+
}
|
44 |
+
$file = false;
|
45 |
+
foreach ($files as $f) {
|
46 |
+
if (file_exists($f)) {
|
47 |
+
$file = $f;
|
48 |
+
break;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
if ($file === false) {
|
52 |
+
return false;
|
53 |
+
}
|
54 |
+
|
55 |
+
$oldContext = $this->context;
|
56 |
+
if ($context !== null) {
|
57 |
+
$this->context = $context;
|
58 |
+
}
|
59 |
+
$result = $this->renderPhpFile($file, $this->_vars[$count]);
|
60 |
+
$this->context = $oldContext;
|
61 |
+
|
62 |
+
unset($this->_vars[$count]);
|
63 |
+
|
64 |
+
return $result;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param string $____f
|
69 |
+
* @param array $____v
|
70 |
+
*
|
71 |
+
* @return false|string
|
72 |
+
*/
|
73 |
+
public function renderPhpFile($____f, $____v)
|
74 |
+
{
|
75 |
+
extract($____v);
|
76 |
+
if (!file_exists($____f)) {
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
ob_start();
|
80 |
+
require $____f;
|
81 |
+
return ob_get_clean();
|
82 |
+
}
|
83 |
+
}
|
core/base/ViewContextInterface.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
interface ViewContextInterface
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @param string $view
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getViewFiles($view);
|
13 |
+
}
|
core/base/Widget.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\base;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\Core;
|
6 |
+
use ReflectionClass;
|
7 |
+
|
8 |
+
abstract class Widget extends BaseObject
|
9 |
+
{
|
10 |
+
|
11 |
+
private $_viewPath;
|
12 |
+
|
13 |
+
public function getViewPath()
|
14 |
+
{
|
15 |
+
if ($this->_viewPath === null) {
|
16 |
+
$class = new ReflectionClass($this);
|
17 |
+
$this->_viewPath = dirname($class->getFileName()) . '/views';
|
18 |
+
}
|
19 |
+
return $this->_viewPath;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @param string $view
|
24 |
+
* @param array $params
|
25 |
+
* @param bool $echo
|
26 |
+
* @return string|null
|
27 |
+
*/
|
28 |
+
public function render($view, $params = [], $echo = false)
|
29 |
+
{
|
30 |
+
$html = Core::$plugin->view->renderFile($this->getViewPath() . '/' . $view . '.php', $params);
|
31 |
+
if ($echo) {
|
32 |
+
echo $html;
|
33 |
+
return null;
|
34 |
+
}
|
35 |
+
return $html;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @param array $config
|
40 |
+
* @return string
|
41 |
+
*/
|
42 |
+
public static function widget($config = [])
|
43 |
+
{
|
44 |
+
/* @var $widget Widget */
|
45 |
+
$config['class'] = get_called_class();
|
46 |
+
$widget = Core::createObject($config);
|
47 |
+
return $widget->run();
|
48 |
+
}
|
49 |
+
|
50 |
+
abstract public function run();
|
51 |
+
}
|
core/front/BaseFront.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\front;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
6 |
+
use luckywp\tableOfContents\core\base\ViewContextInterface;
|
7 |
+
use luckywp\tableOfContents\core\Core;
|
8 |
+
use ReflectionClass;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @property string $themeViewsDir
|
12 |
+
*/
|
13 |
+
class BaseFront extends BaseObject implements ViewContextInterface
|
14 |
+
{
|
15 |
+
|
16 |
+
private $_theme_views_dir;
|
17 |
+
|
18 |
+
protected $defaultThemeViewsDir;
|
19 |
+
|
20 |
+
public function getThemeViewsDir()
|
21 |
+
{
|
22 |
+
if ($this->_theme_views_dir === null) {
|
23 |
+
$this->_theme_views_dir = apply_filters(Core::$plugin->prefix . 'theme_views_dir', $this->defaultThemeViewsDir);
|
24 |
+
}
|
25 |
+
return $this->_theme_views_dir;
|
26 |
+
}
|
27 |
+
|
28 |
+
private $_viewPath;
|
29 |
+
|
30 |
+
public function getViewPath()
|
31 |
+
{
|
32 |
+
if ($this->_viewPath === null) {
|
33 |
+
$class = new ReflectionClass($this);
|
34 |
+
$this->_viewPath = dirname($class->getFileName()) . '/views';
|
35 |
+
}
|
36 |
+
return $this->_viewPath;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param string $view
|
41 |
+
* @return array
|
42 |
+
*/
|
43 |
+
public function getViewFiles($view)
|
44 |
+
{
|
45 |
+
return [
|
46 |
+
get_template_directory() . '/' . $this->themeViewsDir . '/' . $view . '.php',
|
47 |
+
$this->getViewPath() . '/' . $view . '.php',
|
48 |
+
];
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param string $view
|
53 |
+
* @param array $params
|
54 |
+
* @param bool $echo
|
55 |
+
* @return string|null
|
56 |
+
*/
|
57 |
+
public function render($view, $params = [], $echo = false)
|
58 |
+
{
|
59 |
+
$html = Core::$plugin->view->renderFile($this->getViewFiles($view), $params, $this);
|
60 |
+
if ($echo) {
|
61 |
+
echo $html;
|
62 |
+
return null;
|
63 |
+
}
|
64 |
+
return $html;
|
65 |
+
}
|
66 |
+
}
|
core/helpers/ArrayHelper.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\helpers;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
|
7 |
+
class ArrayHelper
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param array|object $array
|
12 |
+
* @param string $key
|
13 |
+
* @param mixed $default
|
14 |
+
* @return mixed
|
15 |
+
*/
|
16 |
+
public static function getValue($array, $key, $default = null)
|
17 |
+
{
|
18 |
+
if (false !== $pos = strrpos($key, '.')) {
|
19 |
+
$array = static::getValue($array, substr($key, 0, $pos), $default);
|
20 |
+
$key = substr($key, $pos + 1);
|
21 |
+
}
|
22 |
+
if (is_object($array)) {
|
23 |
+
try {
|
24 |
+
return $array->$key;
|
25 |
+
} catch (Exception $e) {
|
26 |
+
return null;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
if (is_array($array)) {
|
30 |
+
return array_key_exists($key, $array) ? $array[$key] : $default;
|
31 |
+
}
|
32 |
+
return $default;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @param array $array
|
37 |
+
* @param string $key
|
38 |
+
* @param mixed $default
|
39 |
+
* @return mixed
|
40 |
+
*/
|
41 |
+
public static function remove(&$array, $key, $default = null)
|
42 |
+
{
|
43 |
+
if (is_array($array) && array_key_exists($key, $array)) {
|
44 |
+
$value = $array[$key];
|
45 |
+
unset($array[$key]);
|
46 |
+
return $value;
|
47 |
+
}
|
48 |
+
return $default;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param array $array
|
53 |
+
* @param string $from
|
54 |
+
* @param string $to
|
55 |
+
* @param string $group
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
public static function map($array, $from, $to, $group = null)
|
59 |
+
{
|
60 |
+
$result = [];
|
61 |
+
foreach ($array as $element) {
|
62 |
+
$key = static::getValue($element, $from);
|
63 |
+
$value = static::getValue($element, $to);
|
64 |
+
if ($group !== null) {
|
65 |
+
$result[static::getValue($element, $group)][$key] = $value;
|
66 |
+
} else {
|
67 |
+
$result[$key] = $value;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
return $result;
|
71 |
+
}
|
72 |
+
}
|
core/helpers/Html.php
ADDED
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\helpers;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\Model;
|
6 |
+
|
7 |
+
class Html
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var array
|
12 |
+
* @see https://www.w3.org/TR/html/syntax.html#void-elements
|
13 |
+
*/
|
14 |
+
public static $voidElements = [
|
15 |
+
'area',
|
16 |
+
'base',
|
17 |
+
'br',
|
18 |
+
'col',
|
19 |
+
'embed',
|
20 |
+
'hr',
|
21 |
+
'img',
|
22 |
+
'input',
|
23 |
+
'link',
|
24 |
+
'meta',
|
25 |
+
'param',
|
26 |
+
'source',
|
27 |
+
'track',
|
28 |
+
'wbr',
|
29 |
+
];
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param string|false|null $name
|
33 |
+
* @param string $content
|
34 |
+
* @param array $options
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
public static function tag($name, $content = '', $options = [])
|
38 |
+
{
|
39 |
+
if ($name === null || $name === false) {
|
40 |
+
return $content;
|
41 |
+
}
|
42 |
+
$html = "<$name" . static::renderTagAttributes($options) . '>';
|
43 |
+
return array_key_exists(strtolower($name), static::$voidElements) ? $html : "$html$content</$name>";
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param string|false|null $name
|
48 |
+
* @param array $options
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
public static function beginTag($name, $options = [])
|
52 |
+
{
|
53 |
+
if ($name === null || $name === false) {
|
54 |
+
return '';
|
55 |
+
}
|
56 |
+
return "<$name" . static::renderTagAttributes($options) . '>';
|
57 |
+
}
|
58 |
+
|
59 |
+
public static function renderTagAttributes($attributes)
|
60 |
+
{
|
61 |
+
$html = '';
|
62 |
+
foreach ($attributes as $name => $value) {
|
63 |
+
if (is_bool($value)) {
|
64 |
+
if ($value) {
|
65 |
+
$html .= " $name";
|
66 |
+
}
|
67 |
+
} elseif (is_array($value)) {
|
68 |
+
if ($name == 'data') {
|
69 |
+
foreach ($value as $n => $v) {
|
70 |
+
if (is_array($v)) {
|
71 |
+
$html .= " $name-$n='" . Json::htmlEncode($v) . "'";
|
72 |
+
} else {
|
73 |
+
$html .= " $name-$n=\"" . static::encode($v) . '"';
|
74 |
+
}
|
75 |
+
}
|
76 |
+
} elseif ($name === 'class') {
|
77 |
+
if (empty($value)) {
|
78 |
+
continue;
|
79 |
+
}
|
80 |
+
$html .= " $name=\"" . static::encode(implode(' ', $value)) . '"';
|
81 |
+
} elseif ($name === 'style') {
|
82 |
+
if (empty($value)) {
|
83 |
+
continue;
|
84 |
+
}
|
85 |
+
$html .= " $name=\"" . static::encode(static::cssStyleFromArray($value)) . '"';
|
86 |
+
} else {
|
87 |
+
$html .= " $name='" . Json::htmlEncode($value) . "'";
|
88 |
+
}
|
89 |
+
} elseif ($value !== null) {
|
90 |
+
$html .= " $name=\"" . static::encode($value) . '"';
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
return $html;
|
95 |
+
}
|
96 |
+
|
97 |
+
public static function encode($content, $doubleEncode = true)
|
98 |
+
{
|
99 |
+
return htmlspecialchars($content, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', $doubleEncode);
|
100 |
+
}
|
101 |
+
|
102 |
+
public static function cssStyleFromArray(array $style)
|
103 |
+
{
|
104 |
+
$result = '';
|
105 |
+
foreach ($style as $name => $value) {
|
106 |
+
$result .= "$name: $value; ";
|
107 |
+
}
|
108 |
+
return $result === '' ? null : rtrim($result);
|
109 |
+
}
|
110 |
+
|
111 |
+
public static function prepareClassInOptions(array $options)
|
112 |
+
{
|
113 |
+
if (!isset($options['class'])) {
|
114 |
+
$options['class'] = [];
|
115 |
+
}
|
116 |
+
if (!is_array($options['class'])) {
|
117 |
+
$options['class'] = [$options['class']];
|
118 |
+
}
|
119 |
+
return $options;
|
120 |
+
}
|
121 |
+
|
122 |
+
public static function a($text, $url = null, $options = [])
|
123 |
+
{
|
124 |
+
if ($url !== null) {
|
125 |
+
$options['href'] = $url;
|
126 |
+
}
|
127 |
+
return static::tag('a', $text, $options);
|
128 |
+
}
|
129 |
+
|
130 |
+
public static function label($content, $for = null, $options = [])
|
131 |
+
{
|
132 |
+
$options['for'] = $for;
|
133 |
+
return static::tag('label', $content, $options);
|
134 |
+
}
|
135 |
+
|
136 |
+
public static function input($type, $name = null, $value = null, $options = [])
|
137 |
+
{
|
138 |
+
if (!isset($options['type'])) {
|
139 |
+
$options['type'] = $type;
|
140 |
+
}
|
141 |
+
$options['name'] = $name;
|
142 |
+
$options['value'] = $value === null ? null : (string)$value;
|
143 |
+
return static::tag('input', '', $options);
|
144 |
+
}
|
145 |
+
|
146 |
+
public static function textInput($name, $value = null, $options = [])
|
147 |
+
{
|
148 |
+
return static::input('text', $name, $value, $options);
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* @param string $name
|
153 |
+
* @param string $value
|
154 |
+
* @param array $options
|
155 |
+
* @return string
|
156 |
+
*/
|
157 |
+
public static function hiddenInput($name, $value = null, $options = [])
|
158 |
+
{
|
159 |
+
return static::input('hidden', $name, $value, $options);
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* @param string $type "radio" или "checkbox"
|
164 |
+
* @param string $name
|
165 |
+
* @param bool $checked
|
166 |
+
* @param array $options
|
167 |
+
* @return string
|
168 |
+
*/
|
169 |
+
protected static function booleanInput($type, $name, $checked = false, $options = [])
|
170 |
+
{
|
171 |
+
$options['checked'] = (bool)$checked;
|
172 |
+
$value = array_key_exists('value', $options) ? $options['value'] : '1';
|
173 |
+
|
174 |
+
$hidden = '';
|
175 |
+
if (isset($options['uncheck'])) {
|
176 |
+
$hiddenOptions = [];
|
177 |
+
$hidden = static::hiddenInput($name, $options['uncheck'], $hiddenOptions);
|
178 |
+
unset($options['uncheck']);
|
179 |
+
}
|
180 |
+
|
181 |
+
if (isset($options['label'])) {
|
182 |
+
$label = $options['label'];
|
183 |
+
$labelOptions = isset($options['labelOptions']) ? $options['labelOptions'] : [];
|
184 |
+
unset($options['label'], $options['labelOptions']);
|
185 |
+
$content = static::label(static::input($type, $name, $value, $options) . ' ' . $label, null, $labelOptions);
|
186 |
+
return $hidden . $content;
|
187 |
+
}
|
188 |
+
return $hidden . static::input($type, $name, $value, $options);
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* @param string $name
|
193 |
+
* @param bool $checked
|
194 |
+
* @param array $options
|
195 |
+
* @return string
|
196 |
+
*/
|
197 |
+
public static function checkbox($name, $checked = false, $options = [])
|
198 |
+
{
|
199 |
+
return static::booleanInput('checkbox', $name, $checked, $options);
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @param array|string|null $selection
|
204 |
+
* @param $items
|
205 |
+
* @param array $tagOptions
|
206 |
+
* @return string
|
207 |
+
*/
|
208 |
+
public static function renderSelectOptions($selection, $items, &$tagOptions = [])
|
209 |
+
{
|
210 |
+
if (is_array($selection)) {
|
211 |
+
$selection = array_map('strval', (array)$selection);
|
212 |
+
}
|
213 |
+
|
214 |
+
$lines = [];
|
215 |
+
$encodeSpaces = ArrayHelper::remove($tagOptions, 'encodeSpaces', false);
|
216 |
+
$encode = ArrayHelper::remove($tagOptions, 'encode', true);
|
217 |
+
if (isset($tagOptions['prompt'])) {
|
218 |
+
$promptOptions = ['value' => ''];
|
219 |
+
if (is_string($tagOptions['prompt'])) {
|
220 |
+
$promptText = $tagOptions['prompt'];
|
221 |
+
} else {
|
222 |
+
$promptText = $tagOptions['prompt']['text'];
|
223 |
+
$promptOptions = array_merge($promptOptions, $tagOptions['prompt']['options']);
|
224 |
+
}
|
225 |
+
$promptText = $encode ? static::encode($promptText) : $promptText;
|
226 |
+
if ($encodeSpaces) {
|
227 |
+
$promptText = str_replace(' ', ' ', $promptText);
|
228 |
+
}
|
229 |
+
$lines[] = static::tag('option', $promptText, $promptOptions);
|
230 |
+
}
|
231 |
+
|
232 |
+
$options = isset($tagOptions['options']) ? $tagOptions['options'] : [];
|
233 |
+
$groups = isset($tagOptions['groups']) ? $tagOptions['groups'] : [];
|
234 |
+
unset($tagOptions['prompt'], $tagOptions['options'], $tagOptions['groups']);
|
235 |
+
$options['encodeSpaces'] = ArrayHelper::getValue($options, 'encodeSpaces', $encodeSpaces);
|
236 |
+
$options['encode'] = ArrayHelper::getValue($options, 'encode', $encode);
|
237 |
+
|
238 |
+
foreach ($items as $key => $value) {
|
239 |
+
if (is_array($value)) {
|
240 |
+
$groupAttrs = isset($groups[$key]) ? $groups[$key] : [];
|
241 |
+
if (!isset($groupAttrs['label'])) {
|
242 |
+
$groupAttrs['label'] = $key;
|
243 |
+
}
|
244 |
+
$attrs = ['options' => $options, 'groups' => $groups, 'encodeSpaces' => $encodeSpaces, 'encode' => $encode];
|
245 |
+
$content = static::renderSelectOptions($selection, $value, $attrs);
|
246 |
+
$lines[] = static::tag('optgroup', "\n" . $content . "\n", $groupAttrs);
|
247 |
+
} else {
|
248 |
+
$attrs = isset($options[$key]) ? $options[$key] : [];
|
249 |
+
$attrs['value'] = (string)$key;
|
250 |
+
if (!array_key_exists('selected', $attrs)) {
|
251 |
+
$attrs['selected'] = $selection !== null &&
|
252 |
+
(!is_array($selection) && !strcmp($key, $selection)
|
253 |
+
|| is_array($selection) && in_array((string)$key, $selection));
|
254 |
+
}
|
255 |
+
$text = $encode ? static::encode($value) : $value;
|
256 |
+
if ($encodeSpaces) {
|
257 |
+
$text = str_replace(' ', ' ', $text);
|
258 |
+
}
|
259 |
+
$lines[] = static::tag('option', $text, $attrs);
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
return implode("\n", $lines);
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* @param string $name
|
268 |
+
* @param string|array|null $selection
|
269 |
+
* @param array $items
|
270 |
+
* @param array $options
|
271 |
+
* @return string
|
272 |
+
*/
|
273 |
+
public static function dropDownList($name, $selection = null, $items = [], $options = [])
|
274 |
+
{
|
275 |
+
if (!empty($options['multiple'])) {
|
276 |
+
return static::listBox($name, $selection, $items, $options);
|
277 |
+
}
|
278 |
+
$options['name'] = $name;
|
279 |
+
unset($options['unselect']);
|
280 |
+
$selectOptions = static::renderSelectOptions($selection, $items, $options);
|
281 |
+
return static::tag('select', "\n" . $selectOptions . "\n", $options);
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @param string $name
|
286 |
+
* @param string|array|null $selection
|
287 |
+
* @param array $items
|
288 |
+
* @param array $options
|
289 |
+
* @return string
|
290 |
+
*/
|
291 |
+
public static function listBox($name, $selection = null, $items = [], $options = [])
|
292 |
+
{
|
293 |
+
if (!array_key_exists('size', $options)) {
|
294 |
+
$options['size'] = 4;
|
295 |
+
}
|
296 |
+
if (!empty($options['multiple']) && !empty($name) && substr_compare($name, '[]', -2, 2)) {
|
297 |
+
$name .= '[]';
|
298 |
+
}
|
299 |
+
$options['name'] = $name;
|
300 |
+
if (isset($options['unselect'])) {
|
301 |
+
if (!empty($name) && substr_compare($name, '[]', -2, 2) === 0) {
|
302 |
+
$name = substr($name, 0, -2);
|
303 |
+
}
|
304 |
+
$hidden = static::hiddenInput($name, $options['unselect']);
|
305 |
+
unset($options['unselect']);
|
306 |
+
} else {
|
307 |
+
$hidden = '';
|
308 |
+
}
|
309 |
+
$selectOptions = static::renderSelectOptions($selection, $items, $options);
|
310 |
+
return $hidden . static::tag('select', "\n" . $selectOptions . "\n", $options);
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* @param Model $model
|
315 |
+
* @param string $attribute
|
316 |
+
* @return string
|
317 |
+
*/
|
318 |
+
public static function getInputName($model, $attribute)
|
319 |
+
{
|
320 |
+
$formName = $model->formName();
|
321 |
+
return $formName . '[' . $attribute . ']';
|
322 |
+
}
|
323 |
+
}
|
core/helpers/Json.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\helpers;
|
4 |
+
|
5 |
+
class Json
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see http://php.net/manual/ru/function.json-encode.php
|
10 |
+
* @param mixed $value Данные для кодирования
|
11 |
+
* @param int $options Настройки кодирования. По-умолчанию, `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`
|
12 |
+
* @return string
|
13 |
+
*/
|
14 |
+
public static function encode($value, $options = 320)
|
15 |
+
{
|
16 |
+
return wp_json_encode($value, $options);
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param mixed $value
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public static function htmlEncode($value)
|
24 |
+
{
|
25 |
+
return static::encode($value, JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS);
|
26 |
+
}
|
27 |
+
}
|
core/validators/BooleanValidator.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\validators;
|
4 |
+
|
5 |
+
class BooleanValidator extends Validator
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var mixed
|
10 |
+
*/
|
11 |
+
public $trueValue = '1';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var mixed
|
15 |
+
*/
|
16 |
+
public $falseValue = '0';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var bool
|
20 |
+
*/
|
21 |
+
public $strict = false;
|
22 |
+
|
23 |
+
public function init()
|
24 |
+
{
|
25 |
+
parent::init();
|
26 |
+
if ($this->message === null) {
|
27 |
+
$this->message = __('{attribute} must be either "{true}" or "{false}".', 'lwptoc');
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
public function validateAttribute($model, $attribute)
|
32 |
+
{
|
33 |
+
$value = $model->$attribute;
|
34 |
+
|
35 |
+
if ($this->strict) {
|
36 |
+
$valid = $value === $this->trueValue || $value === $this->falseValue;
|
37 |
+
} else {
|
38 |
+
$valid = $value == $this->trueValue || $value == $this->falseValue;
|
39 |
+
}
|
40 |
+
|
41 |
+
if ($valid) {
|
42 |
+
return null;
|
43 |
+
}
|
44 |
+
|
45 |
+
return [
|
46 |
+
$this->message,
|
47 |
+
[
|
48 |
+
'{true}' => $this->trueValue,
|
49 |
+
'{false}' => $this->falseValue,
|
50 |
+
]
|
51 |
+
];
|
52 |
+
}
|
53 |
+
}
|
core/validators/FilterValidator.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\validators;
|
4 |
+
|
5 |
+
class FilterValidator extends Validator
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var callable
|
10 |
+
*/
|
11 |
+
public $filter;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var bool
|
15 |
+
*/
|
16 |
+
public $skipOnEmpty = false;
|
17 |
+
|
18 |
+
public function validateAttribute($model, $attribute)
|
19 |
+
{
|
20 |
+
$value = $model->$attribute;
|
21 |
+
$model->$attribute = call_user_func($this->filter, $value);
|
22 |
+
}
|
23 |
+
}
|
core/validators/InlineValidator.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\validators;
|
4 |
+
|
5 |
+
class InlineValidator extends Validator
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var string|callable
|
10 |
+
*/
|
11 |
+
public $method;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var mixed
|
15 |
+
*/
|
16 |
+
public $params;
|
17 |
+
|
18 |
+
public function validateAttribute($model, $attribute)
|
19 |
+
{
|
20 |
+
$method = $this->method;
|
21 |
+
if (is_string($method)) {
|
22 |
+
$method = [$model, $method];
|
23 |
+
}
|
24 |
+
call_user_func($method, $attribute, $this->params, $this);
|
25 |
+
}
|
26 |
+
}
|
core/validators/RangeValidator.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\validators;
|
4 |
+
|
5 |
+
class RangeValidator extends Validator
|
6 |
+
{
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var array
|
10 |
+
*/
|
11 |
+
public $range;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var bool
|
15 |
+
*/
|
16 |
+
public $strict = false;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var bool
|
20 |
+
*/
|
21 |
+
public $not = false;
|
22 |
+
|
23 |
+
public function init()
|
24 |
+
{
|
25 |
+
parent::init();
|
26 |
+
if ($this->message === null) {
|
27 |
+
$this->message = __('{attribute} is invalid.', 'lwptoc');
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
protected function validateValue($value)
|
32 |
+
{
|
33 |
+
$in = in_array($value, $this->range, $this->strict);
|
34 |
+
return $this->not !== $in ? null : [$this->message, []];
|
35 |
+
}
|
36 |
+
}
|
core/validators/RequiredValidator.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\validators;
|
4 |
+
|
5 |
+
class RequiredValidator extends Validator
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* @var bool
|
9 |
+
*/
|
10 |
+
public $skipOnEmpty = false;
|
11 |
+
|
12 |
+
public function init()
|
13 |
+
{
|
14 |
+
parent::init();
|
15 |
+
if ($this->message === null) {
|
16 |
+
$this->message = __('{attribute} cannot be blank.', 'lwptoc');
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param mixed $value
|
22 |
+
* @return array|null
|
23 |
+
*/
|
24 |
+
protected function validateValue($value)
|
25 |
+
{
|
26 |
+
if (!$this->isEmpty(is_string($value) ? trim($value) : $value)) {
|
27 |
+
return null;
|
28 |
+
}
|
29 |
+
return [$this->message, []];
|
30 |
+
}
|
31 |
+
}
|
core/validators/Validator.php
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\validators;
|
4 |
+
|
5 |
+
use Exception;
|
6 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
7 |
+
use luckywp\tableOfContents\core\base\Model;
|
8 |
+
use luckywp\tableOfContents\core\Core;
|
9 |
+
|
10 |
+
abstract class Validator extends BaseObject
|
11 |
+
{
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var array Атрибуты для валидации
|
15 |
+
*/
|
16 |
+
public $attributes;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string Сообщение об ошибке
|
20 |
+
*/
|
21 |
+
public $message;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var callable
|
25 |
+
*/
|
26 |
+
public $when;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var bool
|
30 |
+
*/
|
31 |
+
public $skipOnError = true;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var bool
|
35 |
+
*/
|
36 |
+
public $skipOnEmpty = true;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @return array
|
40 |
+
*/
|
41 |
+
public static function builtInValidators()
|
42 |
+
{
|
43 |
+
return [
|
44 |
+
'boolean' => BooleanValidator::className(),
|
45 |
+
'filter' => FilterValidator::className(),
|
46 |
+
'in' => RangeValidator::className(),
|
47 |
+
'required' => RequiredValidator::className(),
|
48 |
+
];
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Создаёт и возвращает валидатор
|
53 |
+
* @param string|callable $name
|
54 |
+
* @param Model $model
|
55 |
+
* @param array $attributes
|
56 |
+
* @param array $params
|
57 |
+
* @return mixed
|
58 |
+
*/
|
59 |
+
public static function createValidator($name, $model, $attributes, $params = [])
|
60 |
+
{
|
61 |
+
$params['attributes'] = $attributes;
|
62 |
+
if (is_callable($name) || method_exists($model, $name)) {
|
63 |
+
$params['class'] = InlineValidator::className();
|
64 |
+
$params['method'] = $name;
|
65 |
+
} else {
|
66 |
+
if (isset(static::builtInValidators()[$name])) {
|
67 |
+
$name = static::builtInValidators()[$name];
|
68 |
+
}
|
69 |
+
$params['class'] = $name;
|
70 |
+
}
|
71 |
+
return Core::createObject($params);
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param Model $model
|
76 |
+
* @param array|null $attributes
|
77 |
+
*/
|
78 |
+
public function validateAttributes($model, $attributes = null)
|
79 |
+
{
|
80 |
+
if (is_array($attributes)) {
|
81 |
+
$newAttributes = [];
|
82 |
+
foreach ($attributes as $attribute) {
|
83 |
+
if (in_array($attribute, $this->getAttributeNames(), true)) {
|
84 |
+
$newAttributes[] = $attribute;
|
85 |
+
}
|
86 |
+
}
|
87 |
+
$attributes = $newAttributes;
|
88 |
+
} else {
|
89 |
+
$attributes = $this->getAttributeNames();
|
90 |
+
}
|
91 |
+
|
92 |
+
foreach ($attributes as $attribute) {
|
93 |
+
$skip = $this->skipOnError && $model->hasErrors($attribute)
|
94 |
+
|| $this->skipOnEmpty && $this->isEmpty($model->$attribute);
|
95 |
+
if (!$skip) {
|
96 |
+
if ($this->when === null || call_user_func($this->when, $model, $attribute)) {
|
97 |
+
$this->validateAttribute($model, $attribute);
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* @param Model $model
|
105 |
+
* @param string
|
106 |
+
*/
|
107 |
+
public function validateAttribute($model, $attribute)
|
108 |
+
{
|
109 |
+
$result = $this->validateValue($model->$attribute);
|
110 |
+
if (!empty($result)) {
|
111 |
+
$this->addError($model, $attribute, $result[0], $result[1]);
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @param mixed $value
|
117 |
+
*/
|
118 |
+
protected function validateValue($value)
|
119 |
+
{
|
120 |
+
throw new Exception(get_class($this) . ' does not support validateValue().');
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param Model $model
|
125 |
+
* @param string $attribute
|
126 |
+
* @param string $message
|
127 |
+
* @param array $params
|
128 |
+
*/
|
129 |
+
public function addError($model, $attribute, $message, $params = [])
|
130 |
+
{
|
131 |
+
$params['attribute'] = $model->getAttributeLabel($attribute);
|
132 |
+
if (!isset($params['value'])) {
|
133 |
+
$value = $model->$attribute;
|
134 |
+
if (is_array($value)) {
|
135 |
+
$params['value'] = 'array()';
|
136 |
+
} elseif (is_object($value) && !method_exists($value, '__toString')) {
|
137 |
+
$params['value'] = '(object)';
|
138 |
+
} else {
|
139 |
+
$params['value'] = $value;
|
140 |
+
}
|
141 |
+
}
|
142 |
+
$model->addError($attribute, $this->formatMessage($message, $params));
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* @param string $message
|
147 |
+
* @param array $params
|
148 |
+
* @return string
|
149 |
+
*/
|
150 |
+
protected function formatMessage($message, $params)
|
151 |
+
{
|
152 |
+
$placeholders = [];
|
153 |
+
foreach ($params as $name => $value) {
|
154 |
+
$placeholders['{' . $name . '}'] = $value;
|
155 |
+
}
|
156 |
+
return ($placeholders === []) ? $message : strtr($message, $placeholders);
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @param mixed $value
|
161 |
+
* @return bool
|
162 |
+
*/
|
163 |
+
public function isEmpty($value)
|
164 |
+
{
|
165 |
+
return $value === null || $value === [] || $value === '';
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @return array
|
170 |
+
*/
|
171 |
+
public function getAttributeNames()
|
172 |
+
{
|
173 |
+
return $this->attributes;
|
174 |
+
}
|
175 |
+
}
|
core/wp/Settings.php
ADDED
@@ -0,0 +1,551 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\core\wp;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\admin\helpers\AdminHtml;
|
6 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
7 |
+
use luckywp\tableOfContents\core\Core;
|
8 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
9 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
10 |
+
|
11 |
+
class Settings extends BaseObject
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Префикс. Добавляется к названию секций и групп
|
16 |
+
* @var string
|
17 |
+
*/
|
18 |
+
protected $prefix;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Массив описывает группы опций.
|
22 |
+
* Каждый элемент массива — массив с параметрами группы.
|
23 |
+
* Парамтеры:
|
24 |
+
* id - идентификатор
|
25 |
+
* name - идентификатор без префикса
|
26 |
+
* label - заголовок (используется, как заголовок таба)
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $groups = [];
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Массив описывает секции ($groupId => $config)
|
33 |
+
* Каждый элемент массива — массив с параметрами секции
|
34 |
+
* Параметры секций:
|
35 |
+
* id - идентификатор (должно быть уникально)
|
36 |
+
* title - заголовок
|
37 |
+
* desc - описание
|
38 |
+
* group - ID группы
|
39 |
+
* @var array
|
40 |
+
*/
|
41 |
+
protected $sections = [];
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Массив описывает поля ($groupId => $config)
|
46 |
+
* Каждый элемент массива — массив с параметрами поля
|
47 |
+
* Параметры полей:
|
48 |
+
* id - идентификатор (должно быть уникально в рамках группы)
|
49 |
+
* label - заголовок
|
50 |
+
* desc - описание
|
51 |
+
* default - значение по-умолчанию
|
52 |
+
* widget - виджет для ввода
|
53 |
+
* params - параметры виджета
|
54 |
+
* sanitizeCallback - функция для валидации и подготовки значения
|
55 |
+
* section - ID секции
|
56 |
+
* group - ID группы
|
57 |
+
* name - атрибут name для виджета
|
58 |
+
* @var array
|
59 |
+
*/
|
60 |
+
protected $fields = [];
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Конфиг для инициализации
|
64 |
+
* @var array
|
65 |
+
*/
|
66 |
+
public $initGroupsConfig = [];
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Файл с конфигом для инициализации
|
70 |
+
* @var array
|
71 |
+
*/
|
72 |
+
public $initGroupsConfigFile;
|
73 |
+
|
74 |
+
public function init()
|
75 |
+
{
|
76 |
+
if ($this->prefix === null) {
|
77 |
+
$this->prefix = Core::$plugin->prefix;
|
78 |
+
}
|
79 |
+
|
80 |
+
$config = [];
|
81 |
+
if ($this->initGroupsConfig) {
|
82 |
+
$config = $this->initGroupsConfig;
|
83 |
+
} elseif ($this->initGroupsConfigFile !== null) {
|
84 |
+
$config = require($this->initGroupsConfigFile);
|
85 |
+
}
|
86 |
+
if ($config) {
|
87 |
+
$this->addGroups($config);
|
88 |
+
}
|
89 |
+
|
90 |
+
if (is_admin() && !wp_doing_ajax()) {
|
91 |
+
add_action('admin_init', [$this, 'adminInit']);
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
public function adminInit()
|
96 |
+
{
|
97 |
+
// Добавляем секции
|
98 |
+
foreach ($this->sections as $groupId => $sections) {
|
99 |
+
foreach ($sections as $sectionId => $section) {
|
100 |
+
add_settings_section(
|
101 |
+
$section['id'],
|
102 |
+
$section['title'],
|
103 |
+
[$this, 'sectionCallback'],
|
104 |
+
$section['group']
|
105 |
+
);
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
// Добавляем поля
|
110 |
+
foreach ($this->fields as $groupId => $fields) {
|
111 |
+
foreach ($fields as $fieldId => $field) {
|
112 |
+
$callback = null;
|
113 |
+
if (is_callable($field['widget'])) {
|
114 |
+
$callback = $field['widget'];
|
115 |
+
} elseif (is_string($field['widget'])) {
|
116 |
+
$methodName = 'field' . ucfirst($field['widget']);
|
117 |
+
if (method_exists($this, $methodName)) {
|
118 |
+
$callback = [$this, $methodName];
|
119 |
+
}
|
120 |
+
}
|
121 |
+
add_settings_field(
|
122 |
+
$field['id'],
|
123 |
+
$field['label'],
|
124 |
+
$callback,
|
125 |
+
$field['group'],
|
126 |
+
$field['section'],
|
127 |
+
$field
|
128 |
+
);
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
// Регистрация настроек
|
133 |
+
foreach ($this->groups as $group) {
|
134 |
+
register_setting(
|
135 |
+
$group['id'],
|
136 |
+
$group['id'],
|
137 |
+
[$this, 'sanitizeCallback']
|
138 |
+
);
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Добавление групп
|
144 |
+
* @param array $config
|
145 |
+
* @return $this
|
146 |
+
*/
|
147 |
+
public function addGroups($config)
|
148 |
+
{
|
149 |
+
foreach ($config as $groupId => $groupConfig) {
|
150 |
+
$this->addGroup($groupId, $groupConfig);
|
151 |
+
}
|
152 |
+
return $this;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Добавление группы
|
157 |
+
* @param string $groupId
|
158 |
+
* @param array $config
|
159 |
+
* @return $this
|
160 |
+
*/
|
161 |
+
public function addGroup($groupId, $config)
|
162 |
+
{
|
163 |
+
$group = [
|
164 |
+
'id' => $this->prefix . $groupId,
|
165 |
+
'name' => $groupId,
|
166 |
+
'label' => ArrayHelper::getValue($config, 'label', $groupId),
|
167 |
+
];
|
168 |
+
$this->groups[$group['id']] = $group;
|
169 |
+
$this->addSections($groupId, ArrayHelper::getValue($config, 'sections', []));
|
170 |
+
return $this;
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Добавление секций
|
175 |
+
* @param string $groupId
|
176 |
+
* @param array $config
|
177 |
+
* @return $this
|
178 |
+
*/
|
179 |
+
public function addSections($groupId, $config)
|
180 |
+
{
|
181 |
+
foreach ($config as $sectionId => $sectionConfig) {
|
182 |
+
$this->addSection($sectionId, $groupId, $sectionConfig);
|
183 |
+
}
|
184 |
+
return $this;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Добавление секции
|
189 |
+
* @param string $sectionId
|
190 |
+
* @param string $groupId
|
191 |
+
* @param array $config
|
192 |
+
* @return $this
|
193 |
+
*/
|
194 |
+
public function addSection($sectionId, $groupId, $config)
|
195 |
+
{
|
196 |
+
$section = [
|
197 |
+
'id' => $this->prefix . $sectionId,
|
198 |
+
'group' => $this->prefix . $groupId,
|
199 |
+
'title' => ArrayHelper::getValue($config, 'title'),
|
200 |
+
'desc' => ArrayHelper::getValue($config, 'desc'),
|
201 |
+
];
|
202 |
+
$this->sections[$section['group']][$section['id']] = $section;
|
203 |
+
$this->addFields($groupId, $sectionId, ArrayHelper::getValue($config, 'fields', []));
|
204 |
+
return $this;
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Добавление полей
|
209 |
+
* @param string $groupId
|
210 |
+
* @param string $sectionId
|
211 |
+
* @param array $config
|
212 |
+
* @return $this
|
213 |
+
*/
|
214 |
+
public function addFields($groupId, $sectionId, $config)
|
215 |
+
{
|
216 |
+
foreach ($config as $fieldId => $fieldConfig) {
|
217 |
+
$this->addField($fieldId, $groupId, $sectionId, $fieldConfig);
|
218 |
+
}
|
219 |
+
return $this;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Добавление поля
|
224 |
+
* @param string $fieldId
|
225 |
+
* @param string $groupId
|
226 |
+
* @param string $sectionId
|
227 |
+
* @param array $config
|
228 |
+
* @return $this
|
229 |
+
*/
|
230 |
+
public function addField($fieldId, $groupId, $sectionId, $config)
|
231 |
+
{
|
232 |
+
$field = [
|
233 |
+
'id' => $fieldId,
|
234 |
+
'group' => $this->prefix . $groupId,
|
235 |
+
'section' => $this->prefix . $sectionId,
|
236 |
+
'label' => ArrayHelper::getValue($config, 'label'),
|
237 |
+
'desc' => ArrayHelper::getValue($config, 'desc'),
|
238 |
+
'default' => ArrayHelper::getValue($config, 'default'),
|
239 |
+
'widget' => ArrayHelper::getValue($config, 'widget', 'textInput'),
|
240 |
+
'params' => ArrayHelper::getValue($config, 'params', []),
|
241 |
+
'sanitizeCallback' => ArrayHelper::getValue($config, 'sanitizeCallback'),
|
242 |
+
'name' => $this->prefix . $groupId . '[' . $fieldId . ']',
|
243 |
+
];
|
244 |
+
$this->fields[$field['group']][$field['id']] = $field;
|
245 |
+
return $this;
|
246 |
+
}
|
247 |
+
|
248 |
+
public function install()
|
249 |
+
{
|
250 |
+
$options = [];
|
251 |
+
foreach ($this->fields as $groupId => $fields) {
|
252 |
+
foreach ($fields as $fieldId => $field) {
|
253 |
+
if (!is_null($field['default'])) {
|
254 |
+
if (!isset($options[$field['group']])) {
|
255 |
+
$options[$field['group']] = [];
|
256 |
+
}
|
257 |
+
$options[$field['group']][$field['id']] = $field['default'];
|
258 |
+
}
|
259 |
+
}
|
260 |
+
}
|
261 |
+
foreach ($options as $option => $value) {
|
262 |
+
if (get_option($option) === false) {
|
263 |
+
add_option($option, $value);
|
264 |
+
}
|
265 |
+
}
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Вывод описания секции
|
270 |
+
* @param $arg
|
271 |
+
*/
|
272 |
+
public function sectionCallback($arg)
|
273 |
+
{
|
274 |
+
foreach ($this->sections as $sections) {
|
275 |
+
if (array_key_exists($arg['id'], $sections)) {
|
276 |
+
echo $sections[$arg['id']]['desc'];
|
277 |
+
}
|
278 |
+
}
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Подготовка и валидация значений
|
283 |
+
* @param $options
|
284 |
+
* @return mixed
|
285 |
+
*/
|
286 |
+
public function sanitizeCallback($options)
|
287 |
+
{
|
288 |
+
if (!is_array($options)) {
|
289 |
+
return [];
|
290 |
+
}
|
291 |
+
$currentGroup = $this->getCurrentGroup();
|
292 |
+
if ($currentGroup === false) {
|
293 |
+
return [];
|
294 |
+
}
|
295 |
+
foreach ($options as $id => $value) {
|
296 |
+
$oldValue = $this->getValue($currentGroup['id'], $id, null, false);
|
297 |
+
|
298 |
+
if (is_string($this->fields[$currentGroup['id']][$id]['widget'])) {
|
299 |
+
$methodName = 'sanitizeCallback' . ucfirst($this->fields[$currentGroup['id']][$id]['widget']);
|
300 |
+
if (method_exists($this, $methodName)) {
|
301 |
+
$options[$id] = call_user_func([$this, $methodName], $value, $oldValue, $id);
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
$callable = ArrayHelper::getValue($this->fields[$currentGroup['id']][$id], 'sanitizeCallback');
|
306 |
+
if (is_callable($callable)) {
|
307 |
+
$options[$id] = call_user_func($callable, $value, $oldValue, $id);
|
308 |
+
}
|
309 |
+
}
|
310 |
+
return $options;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Возвращает значение опции
|
315 |
+
* @param $groupId
|
316 |
+
* @param $fieldId
|
317 |
+
* @param string $default
|
318 |
+
* @param bool $prepareArgs
|
319 |
+
* @return string
|
320 |
+
*/
|
321 |
+
public function getValue($groupId, $fieldId, $default = null, $prepareArgs = true)
|
322 |
+
{
|
323 |
+
if ($prepareArgs) {
|
324 |
+
$groupId = $this->prefix . $groupId;
|
325 |
+
}
|
326 |
+
$options = get_option($groupId);
|
327 |
+
if (is_array($options) && array_key_exists($fieldId, $options)) {
|
328 |
+
return $options[$fieldId];
|
329 |
+
}
|
330 |
+
return $default;
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Возвращает все значения опций группы
|
335 |
+
* @param string $groupId
|
336 |
+
* @return array
|
337 |
+
*/
|
338 |
+
public function getValues($groupId)
|
339 |
+
{
|
340 |
+
$values = get_option($this->prefix . $groupId);
|
341 |
+
return is_array($values) ? $values : [];
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* @param string $groupId
|
346 |
+
* @param string $fieldId
|
347 |
+
* @param mixed $value
|
348 |
+
*/
|
349 |
+
public function setValue($groupId, $fieldId, $value)
|
350 |
+
{
|
351 |
+
$values = $this->getValues($groupId);
|
352 |
+
$values[$fieldId] = $value;
|
353 |
+
update_option($this->prefix . $groupId, $values);
|
354 |
+
}
|
355 |
+
|
356 |
+
|
357 |
+
/**
|
358 |
+
* ---------------------------------------------------------------------------
|
359 |
+
* Вывод и обработка формы
|
360 |
+
* ---------------------------------------------------------------------------
|
361 |
+
*/
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Возвращает текущую группу
|
365 |
+
* @return array|false
|
366 |
+
*/
|
367 |
+
private function getCurrentGroup()
|
368 |
+
{
|
369 |
+
if (!count($this->groups)) {
|
370 |
+
return false;
|
371 |
+
}
|
372 |
+
|
373 |
+
$key = ArrayHelper::getValue($_POST, 'option_page');
|
374 |
+
if ($key === null) {
|
375 |
+
$tab = ArrayHelper::getValue($_GET, 'tab');
|
376 |
+
if ($tab) {
|
377 |
+
$key = $this->prefix . $tab;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
if ($key && isset($this->groups[$key])) {
|
382 |
+
return $this->groups[$key];
|
383 |
+
}
|
384 |
+
|
385 |
+
reset($this->groups);
|
386 |
+
$group = current($this->groups);
|
387 |
+
return $group;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Вывод табов
|
392 |
+
*/
|
393 |
+
public function showTabs()
|
394 |
+
{
|
395 |
+
// Активная группа
|
396 |
+
$currentGroup = $this->getCurrentGroup();
|
397 |
+
if ($currentGroup === false) {
|
398 |
+
return;
|
399 |
+
}
|
400 |
+
|
401 |
+
// Вывод
|
402 |
+
echo '<h2 class="nav-tab-wrapper">';
|
403 |
+
foreach ($this->groups as $group) {
|
404 |
+
echo '<a href="?page=' . $_GET['page'] . '&tab=' . $group['name'] . '" class="nav-tab' . ($group['name'] == $currentGroup['name'] ? ' nav-tab-active' : '') . '">' . $group['label'] . '</a>';
|
405 |
+
}
|
406 |
+
echo '</h2>';
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Вывод формы
|
411 |
+
* @param string|null $groupId
|
412 |
+
*/
|
413 |
+
public function showForm($groupId = null)
|
414 |
+
{
|
415 |
+
if ($groupId === null) {
|
416 |
+
$currentGroup = $this->getCurrentGroup();
|
417 |
+
if ($currentGroup === false) {
|
418 |
+
return;
|
419 |
+
}
|
420 |
+
$groupId = $currentGroup['id'];
|
421 |
+
} else {
|
422 |
+
$groupId = $this->prefix . $groupId;
|
423 |
+
}
|
424 |
+
|
425 |
+
echo '<form action="options.php" method="POST">';
|
426 |
+
settings_fields($groupId);
|
427 |
+
do_settings_sections($groupId);
|
428 |
+
submit_button();
|
429 |
+
echo '</form>';
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Вывод страницы с настройками
|
434 |
+
* @param bool $showErrors
|
435 |
+
*/
|
436 |
+
public function showPage($showErrors = true)
|
437 |
+
{
|
438 |
+
if ($showErrors) {
|
439 |
+
settings_errors();
|
440 |
+
}
|
441 |
+
if (count($this->groups) > 1) {
|
442 |
+
$this->showTabs();
|
443 |
+
}
|
444 |
+
$this->showForm();
|
445 |
+
}
|
446 |
+
|
447 |
+
|
448 |
+
/**
|
449 |
+
* ---------------------------------------------------------------------------
|
450 |
+
* Поля
|
451 |
+
* ---------------------------------------------------------------------------
|
452 |
+
*/
|
453 |
+
|
454 |
+
/**
|
455 |
+
* @param array $field
|
456 |
+
*/
|
457 |
+
public function fieldTextInput($field)
|
458 |
+
{
|
459 |
+
$value = $this->getValue($field['group'], $field['id'], '', false);
|
460 |
+
|
461 |
+
// Параметры
|
462 |
+
$params = $field['params'];
|
463 |
+
$inputOptions = isset($params['inputOptions']) ? $params['inputOptions'] : [];
|
464 |
+
$before = ArrayHelper::getValue($params, 'before');
|
465 |
+
if (is_callable($before)) {
|
466 |
+
$before = call_user_func($before);
|
467 |
+
}
|
468 |
+
$after = ArrayHelper::getValue($params, 'after');
|
469 |
+
if (is_callable($after)) {
|
470 |
+
$after = call_user_func($after);
|
471 |
+
}
|
472 |
+
|
473 |
+
// Вывод
|
474 |
+
echo $before . AdminHtml::textInput($field['name'], $value, $inputOptions) . $after;
|
475 |
+
if ($field['desc'] != '') {
|
476 |
+
echo '<p class="description">' . $field['desc'] . '</p>';
|
477 |
+
}
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* @param $field
|
482 |
+
*/
|
483 |
+
public function fieldSelect($field)
|
484 |
+
{
|
485 |
+
$value = $this->getValue($field['group'], $field['id'], '', false);
|
486 |
+
|
487 |
+
// Параметры
|
488 |
+
$params = $field['params'];
|
489 |
+
$selectOptions = ArrayHelper::getValue($params, 'selectOptions', []);
|
490 |
+
$items = ArrayHelper::getValue($params, 'items', []);
|
491 |
+
|
492 |
+
// Вывод
|
493 |
+
echo Html::dropDownList($field['name'], $value, $items, $selectOptions);
|
494 |
+
if ($field['desc'] != '') {
|
495 |
+
echo '<p class="description">' . $field['desc'] . '</p>';
|
496 |
+
}
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* @param array $field
|
501 |
+
*/
|
502 |
+
public function fieldCheckbox($field)
|
503 |
+
{
|
504 |
+
$checked = (bool)$this->getValue($field['group'], $field['id'], false, false);
|
505 |
+
|
506 |
+
// Параметры
|
507 |
+
$params = $field['params'];
|
508 |
+
$checkboxOptions = isset($params['checkboxOptions']) ? $params['checkboxOptions'] : [];
|
509 |
+
$checkboxOptions['value'] = 1;
|
510 |
+
$checkboxOptions['uncheck'] = 0;
|
511 |
+
|
512 |
+
// Вывод
|
513 |
+
echo Html::checkbox($field['name'], $checked, $checkboxOptions);
|
514 |
+
if ($field['desc'] != '') {
|
515 |
+
echo '<p class="description">' . $field['desc'] . '</p>';
|
516 |
+
}
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* @param mixed $value
|
521 |
+
* @return bool
|
522 |
+
*/
|
523 |
+
public function sanitizeCallbackCheckbox($value)
|
524 |
+
{
|
525 |
+
return (bool)$value;
|
526 |
+
}
|
527 |
+
|
528 |
+
/**
|
529 |
+
* @param array $field
|
530 |
+
*/
|
531 |
+
public function fieldColor($field)
|
532 |
+
{
|
533 |
+
$value = $this->getValue($field['group'], $field['id'], '', false);
|
534 |
+
|
535 |
+
// Вывод
|
536 |
+
echo Html::textInput($field['name'], $value, ['class' => Core::$plugin->prefix . 'colorPicker']);
|
537 |
+
if ($field['desc'] != '') {
|
538 |
+
echo '<p class="description">' . $field['desc'] . '</p>';
|
539 |
+
}
|
540 |
+
}
|
541 |
+
|
542 |
+
/**
|
543 |
+
* @param mixed $value
|
544 |
+
* @return string|null
|
545 |
+
*/
|
546 |
+
public function sanitizeCallbackColor($value)
|
547 |
+
{
|
548 |
+
$value = strtolower((string)$value);
|
549 |
+
return preg_match('/^#[0-9a-f]{6}$/', $value) ? $value : null;
|
550 |
+
}
|
551 |
+
}
|
front/Front.php
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\front;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\Core;
|
6 |
+
use luckywp\tableOfContents\core\front\BaseFront;
|
7 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
8 |
+
use luckywp\tableOfContents\plugin\PostSettings;
|
9 |
+
use luckywp\tableOfContents\plugin\Shortcode;
|
10 |
+
|
11 |
+
class Front extends BaseFront
|
12 |
+
{
|
13 |
+
|
14 |
+
public $defaultThemeViewsDir = 'luckywp-table-of-contents';
|
15 |
+
|
16 |
+
public function init()
|
17 |
+
{
|
18 |
+
parent::init();
|
19 |
+
if (Core::isFront()) {
|
20 |
+
add_action('wp_enqueue_scripts', [$this, 'assets']);
|
21 |
+
add_action('init', function () {
|
22 |
+
if (Core::$plugin->settings->autoInsertEnable) {
|
23 |
+
add_filter('the_content', [$this, 'autoInsert'], 998);
|
24 |
+
}
|
25 |
+
});
|
26 |
+
add_action('wp_footer', [$this, 'overrideColors']);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
public function assets()
|
31 |
+
{
|
32 |
+
wp_register_style('lwptoc-main', Core::$plugin->url . '/front/assets/main.min.css', [], Core::$plugin->version);
|
33 |
+
if (apply_filters('lwptoc_enqueue_style', true)) {
|
34 |
+
wp_enqueue_style('lwptoc-main');
|
35 |
+
}
|
36 |
+
wp_register_script('lwptoc-main', Core::$plugin->url . '/front/assets/main.min.js', ['jquery'], Core::$plugin->version);
|
37 |
+
if (apply_filters('lwptoc_enqueue_script', true)) {
|
38 |
+
wp_enqueue_script('lwptoc-main');
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
public function overrideColors()
|
43 |
+
{
|
44 |
+
if (Core::$plugin->shortcode->overrideColors) {
|
45 |
+
$styles = [];
|
46 |
+
|
47 |
+
$iStyles = [];
|
48 |
+
if ($color = ArrayHelper::getValue(Core::$plugin->shortcode->overrideColors, 'backgroundColor')) {
|
49 |
+
$iStyles[] = 'background-color:' . $color . ';';
|
50 |
+
}
|
51 |
+
if ($color = ArrayHelper::getValue(Core::$plugin->shortcode->overrideColors, 'borderColor')) {
|
52 |
+
$iStyles[] = 'border:1px solid ' . $color . ';';
|
53 |
+
}
|
54 |
+
if ($iStyles) {
|
55 |
+
$styles[] = '.lwptoc .lwptoc_i{' . implode($iStyles) . '}';
|
56 |
+
}
|
57 |
+
|
58 |
+
if ($color = ArrayHelper::getValue(Core::$plugin->shortcode->overrideColors, 'titleColor')) {
|
59 |
+
$styles[] = '.lwptoc_header{color:' . $color . ';}';
|
60 |
+
}
|
61 |
+
|
62 |
+
if ($color = ArrayHelper::getValue(Core::$plugin->shortcode->overrideColors, 'linkColor')) {
|
63 |
+
$styles[] = '.lwptoc .lwptoc_i A{color:' . $color . ';}';
|
64 |
+
}
|
65 |
+
if ($color = ArrayHelper::getValue(Core::$plugin->shortcode->overrideColors, 'hoverLinkColor')) {
|
66 |
+
$styles[] = '.lwptoc .lwptoc_i A:hover,.lwptoc .lwptoc_i A:focus,.lwptoc .lwptoc_i A:active{color:' . $color . ';border-color:' . $color . ';}';
|
67 |
+
}
|
68 |
+
if ($color = ArrayHelper::getValue(Core::$plugin->shortcode->overrideColors, 'visitedLinkColor')) {
|
69 |
+
$styles[] = '.lwptoc .lwptoc_i A:visited{color:' . $color . ';}';
|
70 |
+
}
|
71 |
+
|
72 |
+
if ($styles) {
|
73 |
+
echo '<style>' . implode('', $styles) . '</style>';
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @param string $content
|
80 |
+
* @return string
|
81 |
+
*/
|
82 |
+
public function autoInsert($content)
|
83 |
+
{
|
84 |
+
global $post;
|
85 |
+
|
86 |
+
if (!is_single($post) && !is_page($post)) {
|
87 |
+
return $content;
|
88 |
+
}
|
89 |
+
|
90 |
+
if (!in_array($post->post_type, Core::$plugin->settings->autoInsertPostTypes)) {
|
91 |
+
return $content;
|
92 |
+
}
|
93 |
+
|
94 |
+
if (has_shortcode($content, Shortcode::TAG)) {
|
95 |
+
return $content;
|
96 |
+
}
|
97 |
+
|
98 |
+
$settings = new PostSettings($post->ID);
|
99 |
+
|
100 |
+
if (!$settings->enabled) {
|
101 |
+
return $content;
|
102 |
+
}
|
103 |
+
|
104 |
+
$attrs = [];
|
105 |
+
$attrs['min'] = $settings->min;
|
106 |
+
$attrs['depth'] = $settings->depth;
|
107 |
+
$attrs['hierarchical'] = $settings->hierarchical;
|
108 |
+
$attrs['numeration'] = $settings->numeration;
|
109 |
+
$attrs['title'] = $settings->title;
|
110 |
+
$attrs['toggle'] = $settings->toggle;
|
111 |
+
$attrs['labelShow'] = $settings->labelShow;
|
112 |
+
$attrs['labelHide'] = $settings->labelHide;
|
113 |
+
$attrs['hideItems'] = $settings->hideItems;
|
114 |
+
$attrs['smoothScroll'] = $settings->smoothScroll;
|
115 |
+
$attrs['smoothScrollOffset'] = $settings->smoothScrollOffset;
|
116 |
+
$attrs['width'] = $settings->width;
|
117 |
+
$attrs['float'] = $settings->float;
|
118 |
+
$attrs['titleFontSize'] = $settings->titleFontSize;
|
119 |
+
$attrs['titleFontWeight'] = $settings->titleFontWeight;
|
120 |
+
$attrs['itemsFontSize'] = $settings->itemsFontSize;
|
121 |
+
$attrs['colorScheme'] = $settings->colorScheme;
|
122 |
+
$attrs['backgroundColor'] = $settings->backgroundColor;
|
123 |
+
$attrs['borderColor'] = $settings->borderColor;
|
124 |
+
$attrs['titleColor'] = $settings->titleColor;
|
125 |
+
$attrs['linkColor'] = $settings->linkColor;
|
126 |
+
$attrs['hoverLinkColor'] = $settings->hoverLinkColor;
|
127 |
+
$attrs['visitedLinkColor'] = $settings->visitedLinkColor;
|
128 |
+
|
129 |
+
$shortcode = Core::$plugin->shortcode->make($attrs);
|
130 |
+
|
131 |
+
$position = $settings->position ? $settings->position : Core::$plugin->settings->autoInsertPosition;
|
132 |
+
switch ($position) {
|
133 |
+
case 'beforefirstheading':
|
134 |
+
default:
|
135 |
+
$result = preg_replace($this->generateRegexp('h[1-6]'), $shortcode . ' $1', $content, 1, $count);
|
136 |
+
return $count ? $result : ($shortcode . $content);
|
137 |
+
|
138 |
+
case 'afterfirstheading':
|
139 |
+
$result = preg_replace($this->generateRegexp('h[1-6]'), '$1 ' . $shortcode, $content, 1, $count);
|
140 |
+
return $count ? $result : ($shortcode . $content);
|
141 |
+
|
142 |
+
case 'afterfirstblock':
|
143 |
+
$result = preg_replace($this->generateRegexp('[^ ]+'), '$1 ' . $shortcode, $content, 1, $count);
|
144 |
+
return $count ? $result : ($shortcode . $content);
|
145 |
+
|
146 |
+
case 'bottom':
|
147 |
+
return $content . $shortcode;
|
148 |
+
|
149 |
+
case 'top':
|
150 |
+
return $shortcode . $content;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* @param string $tagsRe
|
156 |
+
* @return string
|
157 |
+
*/
|
158 |
+
protected function generateRegexp($tagsRe)
|
159 |
+
{
|
160 |
+
return '#(<(' . $tagsRe . ')[^>]*>.*?(<\2[^>]*>.*?</\2>)*.*?</\2>)#imsu';
|
161 |
+
}
|
162 |
+
}
|
front/assets/main.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.lwptoc{margin:32px 0}.lwptoc:first-child{margin-top:16px}.lwptoc_i{padding:14px 18px 18px}.lwptoc_i DIV A{box-shadow:none!important;border:none!important;text-decoration:none!important}.lwptoc_i DIV A:active,.lwptoc_i DIV A:focus,.lwptoc_i DIV A:hover{box-shadow:none!important;border:none!important;text-decoration:none!important}.lwptoc_i DIV A:hover{border-bottom:1px dotted!important}.lwptoc_header{margin-bottom:6px}.lwptoc_toggle{margin-left:4px;font-size:80%}.lwptoc_toggle:before{content:'['}.lwptoc_toggle:after{content:']'}.lwptoc_toggle_label{margin:0 1px}.lwptoc_item_number{margin-right:2px}.lwptoc UL{list-style:none;padding:0;margin:0}.lwptoc UL UL{margin:2px 0 0 14px}.lwptoc LI{margin:2px 0 0 0;padding:0}.lwptoc LI:first-child{margin-top:0}.lwptoc-autoWidth .lwptoc_i{display:inline-block}.lwptoc-left{float:left;margin-top:0;margin-right:32px}.lwptoc-right{float:right;margin-top:0;margin-left:32px}.lwptoc-baseItems .lwptoc_items{font-size:90%}.lwptoc-light .lwptoc_i{color:#333;background:#fafafa}.lwptoc-light .lwptoc_i A{color:#3175e4}.lwptoc-light .lwptoc_i A:active,.lwptoc-light .lwptoc_i A:focus,.lwptoc-light .lwptoc_i A:hover{color:#3175e4;border-color:#3175e4}.lwptoc-light .lwptoc_items A:visited{color:#000394}.lwptoc-dark .lwptoc_i{color:#d3d5d8;background:#2b2b2b}.lwptoc-dark .lwptoc_i A{color:#96c6ff}.lwptoc-dark .lwptoc_i A:active,.lwptoc-dark .lwptoc_i A:focus,.lwptoc-dark .lwptoc_i A:hover{color:#96c6ff;border-color:#71b2ff}.lwptoc-dark .lwptoc_items A:visited{color:#53a1ff}.lwptoc-white .lwptoc_i{color:#333;background:#fff}.lwptoc-white .lwptoc_i A{color:#3175e4}.lwptoc-white .lwptoc_i A:active,.lwptoc-white .lwptoc_i A:focus,.lwptoc-white .lwptoc_i A:hover{color:#3175e4;border-color:#3175e4}.lwptoc-white .lwptoc_items A:visited{color:#000394}.lwptoc-transparent .lwptoc_i{border:1px solid #eee}
|
front/assets/main.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(a){var t=function(t){t.each(function(){var i=a(this);i.data("smoothScroll")&&i.find(".lwptoc_items").on("click",'A[href^="#"]',function(t){t.preventDefault();var l=a("A[name="+this.hash.slice(1)+"]");if(l.length){var o=a(this).attr("href"),n=l.offset().top-i.data("smoothScrollOffset");a("html, body").animate({scrollTop:n<0?0:n},500,function(){if(l.focus(),l.is(":focus"))return!1;l.attr("tabindex","-1"),l.focus(),window.history.pushState&&window.history.pushState(null,null,o)})}})}),t.find(".lwptoc_toggle_label").click(function(){var t=a(this),l=t.closest(".lwptoc").find(".lwptoc_items"),o=t.data("label");return"none"==l.css("display")?(l.stop(!0).slideDown(300),t.data("label",t.html()).html(o)):l.stop(!0).slideUp(300,function(){t.data("label",t.html()).html(o)}),!1})};a(function(){t(a(".lwptoc"))})}(jQuery);
|
front/views/body.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $title string
|
4 |
+
* @var $toggle bool
|
5 |
+
* @var $labelShow string
|
6 |
+
* @var $labelHide string
|
7 |
+
* @var $hideItems bool
|
8 |
+
* @var $containerOptions array
|
9 |
+
* @var $headerStyles array
|
10 |
+
* @var $titleStyles array
|
11 |
+
* @var $itemsStyles array
|
12 |
+
* @var $items array
|
13 |
+
*/
|
14 |
+
|
15 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
16 |
+
|
17 |
+
echo Html::beginTag('div', $containerOptions);
|
18 |
+
?>
|
19 |
+
<div class="lwptoc_i">
|
20 |
+
<?php if ($toggle || $title) { ?>
|
21 |
+
<div class="lwptoc_header"<?= $headerStyles ? ' style="' . implode('', $headerStyles) . '"' : '' ?>>
|
22 |
+
<?= $title ? '<b class="lwptoc_title"' . ($titleStyles ? ' style="' . implode('', $titleStyles) . '"' : '') . '>' . $title . '</b>' : '' ?>
|
23 |
+
<?php if ($toggle) { ?>
|
24 |
+
<span class="lwptoc_toggle">
|
25 |
+
<a href="#" class="lwptoc_toggle_label" data-label="<?= $hideItems ? $labelHide : $labelShow ?>">
|
26 |
+
<?= $hideItems ? $labelShow : $labelHide ?>
|
27 |
+
</a>
|
28 |
+
</span>
|
29 |
+
<?php } ?>
|
30 |
+
</div>
|
31 |
+
<?php } ?>
|
32 |
+
<div class="lwptoc_items"<?= $itemsStyles ? ' style="' . implode('', $itemsStyles) . '"' : '' ?>>
|
33 |
+
<?php lwptoc_items($items) ?>
|
34 |
+
</div>
|
35 |
+
</div>
|
36 |
+
<?= '</div>' ?>
|
front/views/items.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $items array
|
4 |
+
* @var $depth int
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<ul>
|
8 |
+
<?php foreach ($items as $item) { ?>
|
9 |
+
<li>
|
10 |
+
<a href="#<?= $item['id'] ?>" class="lwptoc_item">
|
11 |
+
<?php if ($item['number']) { ?>
|
12 |
+
<span class="lwptoc_item_number"><?= $item['number'] ?></span>
|
13 |
+
<?php } ?>
|
14 |
+
<span class="lwptoc_item_label"><?= $item['label'] ?></span>
|
15 |
+
</a>
|
16 |
+
<?php lwptoc_items($item['childrens']) ?>
|
17 |
+
</li>
|
18 |
+
<?php } ?>
|
19 |
+
</ul>
|
functions.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use luckywp\tableOfContents\core\Core;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @param array $items
|
7 |
+
* @param bool $echo
|
8 |
+
* @return string|null
|
9 |
+
*/
|
10 |
+
function lwptoc_items($items, $echo = true)
|
11 |
+
{
|
12 |
+
$html = '';
|
13 |
+
if ($items) {
|
14 |
+
Core::$plugin->shortcode->currentOutputDepth++;
|
15 |
+
$html = Core::$plugin->front->render('items', [
|
16 |
+
'items' => $items,
|
17 |
+
'depth' => Core::$plugin->shortcode->currentOutputDepth,
|
18 |
+
]);
|
19 |
+
Core::$plugin->shortcode->currentOutputDepth--;
|
20 |
+
}
|
21 |
+
if ($echo) {
|
22 |
+
echo $html;
|
23 |
+
return null;
|
24 |
+
}
|
25 |
+
return $html;
|
26 |
+
}
|
languages/lwptoc-ru_RU.mo
ADDED
Binary file
|
languages/lwptoc.pot
ADDED
@@ -0,0 +1,468 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: \n"
|
4 |
+
"POT-Creation-Date: 2018-11-14 12:23+0300\n"
|
5 |
+
"PO-Revision-Date: 2018-11-14 12:24+0300\n"
|
6 |
+
"Last-Translator: \n"
|
7 |
+
"Language-Team: \n"
|
8 |
+
"Language: ru_RU\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 2.1.1\n"
|
13 |
+
"X-Poedit-Basepath: ..\n"
|
14 |
+
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
15 |
+
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
|
16 |
+
"X-Poedit-KeywordsList: __;_;esc_html__\n"
|
17 |
+
"X-Poedit-SearchPath-0: .\n"
|
18 |
+
"X-Poedit-SearchPathExcluded-0: plugin/editorBlock/src\n"
|
19 |
+
|
20 |
+
#: admin/Admin.php:32
|
21 |
+
msgid "Settings"
|
22 |
+
msgstr ""
|
23 |
+
|
24 |
+
#: admin/Admin.php:47 admin/Admin.php:48 admin/Admin.php:72 admin/Admin.php:98
|
25 |
+
#: admin/controllers/EditorBlockController.php:65
|
26 |
+
#: admin/controllers/ShortcodeController.php:68
|
27 |
+
msgid "Table of Contents"
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#: admin/Admin.php:99
|
31 |
+
msgid "Edit"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: admin/Admin.php:126 admin/forms/CustomizeForm.php:207
|
35 |
+
#: admin/widgets/customizeModal/views/modal.php:47 config/settings.php:282
|
36 |
+
msgid "Position"
|
37 |
+
msgstr ""
|
38 |
+
|
39 |
+
#: admin/Admin.php:129 admin/widgets/customizeModal/views/modal.php:70
|
40 |
+
#: config/settings.php:19
|
41 |
+
msgid "Minimal Count of Headers"
|
42 |
+
msgstr ""
|
43 |
+
|
44 |
+
#: admin/Admin.php:132 admin/forms/CustomizeForm.php:203
|
45 |
+
#: admin/widgets/customizeModal/views/modal.php:93 config/settings.php:31
|
46 |
+
msgid "Depth"
|
47 |
+
msgstr ""
|
48 |
+
|
49 |
+
#: admin/Admin.php:135 admin/widgets/customizeModal/views/modal.php:115
|
50 |
+
#: config/settings.php:40
|
51 |
+
msgid "Hierarchical View"
|
52 |
+
msgstr ""
|
53 |
+
|
54 |
+
#: admin/Admin.php:135 admin/Admin.php:144 admin/Admin.php:153
|
55 |
+
#: admin/Admin.php:156 admin/widgets/customizeModal/views/modal.php:131
|
56 |
+
#: admin/widgets/customizeModal/views/modal.php:202
|
57 |
+
#: admin/widgets/customizeModal/views/modal.php:265
|
58 |
+
#: admin/widgets/customizeModal/views/modal.php:288
|
59 |
+
msgid "Enabled"
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: admin/Admin.php:135 admin/Admin.php:144 admin/Admin.php:153
|
63 |
+
#: admin/Admin.php:156 admin/widgets/customizeModal/views/modal.php:131
|
64 |
+
#: admin/widgets/customizeModal/views/modal.php:202
|
65 |
+
#: admin/widgets/customizeModal/views/modal.php:265
|
66 |
+
#: admin/widgets/customizeModal/views/modal.php:288
|
67 |
+
msgid "Disabled"
|
68 |
+
msgstr ""
|
69 |
+
|
70 |
+
#: admin/Admin.php:138 admin/forms/CustomizeForm.php:204
|
71 |
+
#: admin/widgets/customizeModal/views/modal.php:138 config/settings.php:51
|
72 |
+
msgid "Numeration"
|
73 |
+
msgstr ""
|
74 |
+
|
75 |
+
#: admin/Admin.php:141 admin/widgets/customizeModal/views/modal.php:160
|
76 |
+
#: config/settings.php:66
|
77 |
+
msgid "Title"
|
78 |
+
msgstr ""
|
79 |
+
|
80 |
+
#: admin/Admin.php:144 admin/widgets/customizeModal/views/modal.php:186
|
81 |
+
#: config/settings.php:72
|
82 |
+
msgid "Toggle Show/Hide"
|
83 |
+
msgstr ""
|
84 |
+
|
85 |
+
#: admin/Admin.php:147 admin/forms/CustomizeForm.php:205
|
86 |
+
#: admin/widgets/customizeModal/views/modal.php:209 config/settings.php:84
|
87 |
+
msgid "Label Show"
|
88 |
+
msgstr ""
|
89 |
+
|
90 |
+
#: admin/Admin.php:150 admin/forms/CustomizeForm.php:206
|
91 |
+
#: admin/widgets/customizeModal/views/modal.php:229 config/settings.php:95
|
92 |
+
msgid "Label Hide"
|
93 |
+
msgstr ""
|
94 |
+
|
95 |
+
#: admin/Admin.php:153
|
96 |
+
msgid "Hide Items"
|
97 |
+
msgstr ""
|
98 |
+
|
99 |
+
#: admin/Admin.php:156 admin/widgets/customizeModal/views/modal.php:272
|
100 |
+
#: config/settings.php:123
|
101 |
+
msgid "Smooth Scroll"
|
102 |
+
msgstr ""
|
103 |
+
|
104 |
+
#: admin/Admin.php:159 admin/widgets/customizeModal/views/modal.php:295
|
105 |
+
msgid "Smooth Scroll Offset Top"
|
106 |
+
msgstr ""
|
107 |
+
|
108 |
+
#: admin/Admin.php:162 admin/widgets/customizeModal/views/modal.php:319
|
109 |
+
#: config/settings.php:159
|
110 |
+
msgid "Width"
|
111 |
+
msgstr ""
|
112 |
+
|
113 |
+
#: admin/Admin.php:165 admin/forms/CustomizeForm.php:208
|
114 |
+
#: admin/widgets/customizeModal/views/modal.php:342 config/settings.php:171
|
115 |
+
msgid "Float"
|
116 |
+
msgstr ""
|
117 |
+
|
118 |
+
#: admin/Admin.php:168 admin/widgets/customizeModal/views/modal.php:364
|
119 |
+
#: config/settings.php:180
|
120 |
+
msgid "Title Font Size"
|
121 |
+
msgstr ""
|
122 |
+
|
123 |
+
#: admin/Admin.php:171 admin/forms/CustomizeForm.php:209
|
124 |
+
#: admin/widgets/customizeModal/views/modal.php:388 config/settings.php:193
|
125 |
+
msgid "Title Font Weight"
|
126 |
+
msgstr ""
|
127 |
+
|
128 |
+
#: admin/Admin.php:174 admin/widgets/customizeModal/views/modal.php:410
|
129 |
+
#: config/settings.php:202
|
130 |
+
msgid "Items Font Size"
|
131 |
+
msgstr ""
|
132 |
+
|
133 |
+
#: admin/Admin.php:177 admin/forms/CustomizeForm.php:210
|
134 |
+
#: admin/widgets/customizeModal/views/modal.php:434 config/settings.php:215
|
135 |
+
msgid "Color Scheme"
|
136 |
+
msgstr ""
|
137 |
+
|
138 |
+
#: admin/controllers/EditorBlockController.php:71
|
139 |
+
#: admin/controllers/ShortcodeController.php:74
|
140 |
+
#: admin/widgets/metabox/views/box.php:26
|
141 |
+
msgid "empty"
|
142 |
+
msgstr ""
|
143 |
+
|
144 |
+
#: admin/views/settings/index.php:7
|
145 |
+
msgid "Table of Contents Settings"
|
146 |
+
msgstr ""
|
147 |
+
|
148 |
+
#: admin/widgets/OverrideColorBadge.php:17
|
149 |
+
msgid "from scheme"
|
150 |
+
msgstr ""
|
151 |
+
|
152 |
+
#: admin/widgets/customizeModal/views/modal.php:23
|
153 |
+
#: admin/widgets/customizeModal/views/modal.php:487
|
154 |
+
msgid "Cancel"
|
155 |
+
msgstr ""
|
156 |
+
|
157 |
+
#: admin/widgets/customizeModal/views/modal.php:24
|
158 |
+
msgid "Customize Table of Contents"
|
159 |
+
msgstr ""
|
160 |
+
|
161 |
+
#: admin/widgets/customizeModal/views/modal.php:38 config/settings.php:13
|
162 |
+
msgid "General"
|
163 |
+
msgstr ""
|
164 |
+
|
165 |
+
#: admin/widgets/customizeModal/views/modal.php:39 config/settings.php:153
|
166 |
+
msgid "Appearance"
|
167 |
+
msgstr ""
|
168 |
+
|
169 |
+
#: admin/widgets/customizeModal/views/modal.php:48
|
170 |
+
#: admin/widgets/customizeModal/views/modal.php:71
|
171 |
+
#: admin/widgets/customizeModal/views/modal.php:94
|
172 |
+
#: admin/widgets/customizeModal/views/modal.php:116
|
173 |
+
#: admin/widgets/customizeModal/views/modal.php:139
|
174 |
+
#: admin/widgets/customizeModal/views/modal.php:161
|
175 |
+
#: admin/widgets/customizeModal/views/modal.php:187
|
176 |
+
#: admin/widgets/customizeModal/views/modal.php:210
|
177 |
+
#: admin/widgets/customizeModal/views/modal.php:230
|
178 |
+
#: admin/widgets/customizeModal/views/modal.php:250
|
179 |
+
#: admin/widgets/customizeModal/views/modal.php:273
|
180 |
+
#: admin/widgets/customizeModal/views/modal.php:296
|
181 |
+
#: admin/widgets/customizeModal/views/modal.php:320
|
182 |
+
#: admin/widgets/customizeModal/views/modal.php:343
|
183 |
+
#: admin/widgets/customizeModal/views/modal.php:365
|
184 |
+
#: admin/widgets/customizeModal/views/modal.php:389
|
185 |
+
#: admin/widgets/customizeModal/views/modal.php:411
|
186 |
+
#: admin/widgets/customizeModal/views/modal.php:435
|
187 |
+
#: admin/widgets/customizeModal/views/modal.php:465
|
188 |
+
msgid "default"
|
189 |
+
msgstr ""
|
190 |
+
|
191 |
+
#: admin/widgets/customizeModal/views/modal.php:51
|
192 |
+
#: admin/widgets/customizeModal/views/modal.php:74
|
193 |
+
#: admin/widgets/customizeModal/views/modal.php:97
|
194 |
+
#: admin/widgets/customizeModal/views/modal.php:119
|
195 |
+
#: admin/widgets/customizeModal/views/modal.php:142
|
196 |
+
#: admin/widgets/customizeModal/views/modal.php:164
|
197 |
+
#: admin/widgets/customizeModal/views/modal.php:190
|
198 |
+
#: admin/widgets/customizeModal/views/modal.php:213
|
199 |
+
#: admin/widgets/customizeModal/views/modal.php:233
|
200 |
+
#: admin/widgets/customizeModal/views/modal.php:253
|
201 |
+
#: admin/widgets/customizeModal/views/modal.php:276
|
202 |
+
#: admin/widgets/customizeModal/views/modal.php:299
|
203 |
+
#: admin/widgets/customizeModal/views/modal.php:323
|
204 |
+
#: admin/widgets/customizeModal/views/modal.php:346
|
205 |
+
#: admin/widgets/customizeModal/views/modal.php:368
|
206 |
+
#: admin/widgets/customizeModal/views/modal.php:392
|
207 |
+
#: admin/widgets/customizeModal/views/modal.php:414
|
208 |
+
#: admin/widgets/customizeModal/views/modal.php:438
|
209 |
+
#: admin/widgets/customizeModal/views/modal.php:468
|
210 |
+
msgid "Click for override default value"
|
211 |
+
msgstr ""
|
212 |
+
|
213 |
+
#: admin/widgets/customizeModal/views/modal.php:83 config/settings.php:27
|
214 |
+
msgid ""
|
215 |
+
"If the count of headers in the post is less, then table of contents is not "
|
216 |
+
"displayed."
|
217 |
+
msgstr ""
|
218 |
+
|
219 |
+
#: admin/widgets/customizeModal/views/modal.php:124
|
220 |
+
#: admin/widgets/customizeModal/views/modal.php:195
|
221 |
+
#: admin/widgets/customizeModal/views/modal.php:258
|
222 |
+
#: admin/widgets/customizeModal/views/modal.php:281
|
223 |
+
#: admin/widgets/metabox/views/box.php:45 config/settings.php:44
|
224 |
+
#: config/settings.php:76 config/settings.php:127 config/settings.php:274
|
225 |
+
msgid "Enable"
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#: admin/widgets/customizeModal/views/modal.php:175
|
229 |
+
msgid "Without title"
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: admin/widgets/customizeModal/views/modal.php:249 config/settings.php:110
|
233 |
+
msgid "By default, items of contents will be hidden"
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#: admin/widgets/customizeModal/views/modal.php:490
|
237 |
+
msgid "Save"
|
238 |
+
msgstr ""
|
239 |
+
|
240 |
+
#: admin/widgets/customizeSuccess/views/widget.php:9
|
241 |
+
msgid "Saved!"
|
242 |
+
msgstr ""
|
243 |
+
|
244 |
+
#: admin/widgets/fontSizeField/views/widget.php:16 plugin/Plugin.php:226
|
245 |
+
msgid "Default"
|
246 |
+
msgstr ""
|
247 |
+
|
248 |
+
#: admin/widgets/fontSizeField/views/widget.php:17 plugin/Plugin.php:191
|
249 |
+
msgid "Custom Value"
|
250 |
+
msgstr ""
|
251 |
+
|
252 |
+
#: admin/widgets/metabox/views/box.php:14
|
253 |
+
msgid "The table of contents will be automatic added to this post."
|
254 |
+
msgstr ""
|
255 |
+
|
256 |
+
#: admin/widgets/metabox/views/box.php:20
|
257 |
+
msgid "Overridden settings:"
|
258 |
+
msgstr ""
|
259 |
+
|
260 |
+
#: admin/widgets/metabox/views/box.php:32
|
261 |
+
msgid "Customize"
|
262 |
+
msgstr ""
|
263 |
+
|
264 |
+
#: admin/widgets/metabox/views/box.php:35
|
265 |
+
msgid "Disable"
|
266 |
+
msgstr ""
|
267 |
+
|
268 |
+
#: admin/widgets/metabox/views/box.php:42
|
269 |
+
msgid "Click \"Enable\" for automatic add table of contents to this post."
|
270 |
+
msgstr ""
|
271 |
+
|
272 |
+
#: config/settings.php:62
|
273 |
+
msgid "Header"
|
274 |
+
msgstr ""
|
275 |
+
|
276 |
+
#: config/settings.php:68 plugin/Settings.php:85
|
277 |
+
msgid "Contents"
|
278 |
+
msgstr ""
|
279 |
+
|
280 |
+
#: config/settings.php:91 plugin/Settings.php:101
|
281 |
+
msgid "show"
|
282 |
+
msgstr ""
|
283 |
+
|
284 |
+
#: config/settings.php:102 plugin/Settings.php:109
|
285 |
+
msgid "hide"
|
286 |
+
msgstr ""
|
287 |
+
|
288 |
+
#: config/settings.php:119
|
289 |
+
msgid "Behavior"
|
290 |
+
msgstr ""
|
291 |
+
|
292 |
+
#: config/settings.php:135
|
293 |
+
msgid "Scroll Offset Top"
|
294 |
+
msgstr ""
|
295 |
+
|
296 |
+
#: config/settings.php:225
|
297 |
+
msgid "Override Color Scheme Colors"
|
298 |
+
msgstr ""
|
299 |
+
|
300 |
+
#: config/settings.php:230
|
301 |
+
msgid "Background Color"
|
302 |
+
msgstr ""
|
303 |
+
|
304 |
+
#: config/settings.php:235
|
305 |
+
msgid "Border Color"
|
306 |
+
msgstr ""
|
307 |
+
|
308 |
+
#: config/settings.php:240
|
309 |
+
msgid "Title Color"
|
310 |
+
msgstr ""
|
311 |
+
|
312 |
+
#: config/settings.php:245
|
313 |
+
msgid "Link Color"
|
314 |
+
msgstr ""
|
315 |
+
|
316 |
+
#: config/settings.php:250
|
317 |
+
msgid "Hover Link Color"
|
318 |
+
msgstr ""
|
319 |
+
|
320 |
+
#: config/settings.php:255
|
321 |
+
msgid "Visited Link Color"
|
322 |
+
msgstr ""
|
323 |
+
|
324 |
+
#: config/settings.php:264
|
325 |
+
msgid "Auto Insert"
|
326 |
+
msgstr ""
|
327 |
+
|
328 |
+
#: config/settings.php:270
|
329 |
+
msgid "Auto Insert Table of Contents"
|
330 |
+
msgstr ""
|
331 |
+
|
332 |
+
#: config/settings.php:294
|
333 |
+
msgid "Post Types"
|
334 |
+
msgstr ""
|
335 |
+
|
336 |
+
#: core/admin/AdminController.php:46
|
337 |
+
msgid "Sorry, you are not allowed to access this page."
|
338 |
+
msgstr ""
|
339 |
+
|
340 |
+
#: core/validators/BooleanValidator.php:27
|
341 |
+
msgid "{attribute} must be either \"{true}\" or \"{false}\"."
|
342 |
+
msgstr ""
|
343 |
+
|
344 |
+
#: core/validators/RangeValidator.php:27
|
345 |
+
msgid "{attribute} is invalid."
|
346 |
+
msgstr ""
|
347 |
+
|
348 |
+
#: core/validators/RequiredValidator.php:16
|
349 |
+
msgid "{attribute} cannot be blank."
|
350 |
+
msgstr ""
|
351 |
+
|
352 |
+
#: plugin/Plugin.php:74
|
353 |
+
msgid "Without numeration"
|
354 |
+
msgstr ""
|
355 |
+
|
356 |
+
#: plugin/Plugin.php:75
|
357 |
+
msgid "Decimal numbers (nested)"
|
358 |
+
msgstr ""
|
359 |
+
|
360 |
+
#: plugin/Plugin.php:76
|
361 |
+
msgid "Decimal numbers"
|
362 |
+
msgstr ""
|
363 |
+
|
364 |
+
#: plugin/Plugin.php:77
|
365 |
+
msgid "Roman numbers (nested)"
|
366 |
+
msgstr ""
|
367 |
+
|
368 |
+
#: plugin/Plugin.php:78
|
369 |
+
msgid "Roman numbers"
|
370 |
+
msgstr ""
|
371 |
+
|
372 |
+
#: plugin/Plugin.php:88
|
373 |
+
msgid "Before first heading"
|
374 |
+
msgstr ""
|
375 |
+
|
376 |
+
#: plugin/Plugin.php:89
|
377 |
+
msgid "After first heading"
|
378 |
+
msgstr ""
|
379 |
+
|
380 |
+
#: plugin/Plugin.php:90
|
381 |
+
msgid "After first block (paragraph, list or heading)"
|
382 |
+
msgstr ""
|
383 |
+
|
384 |
+
#: plugin/Plugin.php:91
|
385 |
+
msgid "Top"
|
386 |
+
msgstr ""
|
387 |
+
|
388 |
+
#: plugin/Plugin.php:92
|
389 |
+
msgid "Bottom"
|
390 |
+
msgstr ""
|
391 |
+
|
392 |
+
#: plugin/Plugin.php:126
|
393 |
+
msgid "Thin"
|
394 |
+
msgstr ""
|
395 |
+
|
396 |
+
#: plugin/Plugin.php:127
|
397 |
+
msgid "Extra Light"
|
398 |
+
msgstr ""
|
399 |
+
|
400 |
+
#: plugin/Plugin.php:128
|
401 |
+
msgid "Light"
|
402 |
+
msgstr ""
|
403 |
+
|
404 |
+
#: plugin/Plugin.php:129
|
405 |
+
msgid "Normal"
|
406 |
+
msgstr ""
|
407 |
+
|
408 |
+
#: plugin/Plugin.php:130
|
409 |
+
msgid "Medium"
|
410 |
+
msgstr ""
|
411 |
+
|
412 |
+
#: plugin/Plugin.php:131
|
413 |
+
msgid "Semi Bold"
|
414 |
+
msgstr ""
|
415 |
+
|
416 |
+
#: plugin/Plugin.php:132
|
417 |
+
msgid "Bold"
|
418 |
+
msgstr ""
|
419 |
+
|
420 |
+
#: plugin/Plugin.php:133
|
421 |
+
msgid "Extra Bold"
|
422 |
+
msgstr ""
|
423 |
+
|
424 |
+
#: plugin/Plugin.php:134
|
425 |
+
msgid "Heavy"
|
426 |
+
msgstr ""
|
427 |
+
|
428 |
+
#: plugin/Plugin.php:163
|
429 |
+
msgid "None"
|
430 |
+
msgstr ""
|
431 |
+
|
432 |
+
#: plugin/Plugin.php:164
|
433 |
+
msgid "Left"
|
434 |
+
msgstr ""
|
435 |
+
|
436 |
+
#: plugin/Plugin.php:165
|
437 |
+
msgid "Right"
|
438 |
+
msgstr ""
|
439 |
+
|
440 |
+
#: plugin/Plugin.php:175
|
441 |
+
msgid "Light Colors"
|
442 |
+
msgstr ""
|
443 |
+
|
444 |
+
#: plugin/Plugin.php:176
|
445 |
+
msgid "Dark Colors"
|
446 |
+
msgstr ""
|
447 |
+
|
448 |
+
#: plugin/Plugin.php:177
|
449 |
+
msgid "White"
|
450 |
+
msgstr ""
|
451 |
+
|
452 |
+
#: plugin/Plugin.php:178
|
453 |
+
msgid "Transparent"
|
454 |
+
msgstr ""
|
455 |
+
|
456 |
+
#: plugin/Plugin.php:189
|
457 |
+
msgid "Auto"
|
458 |
+
msgstr ""
|
459 |
+
|
460 |
+
#: plugin/Plugin.php:190
|
461 |
+
msgid "Full Width"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: plugin/Plugin.php:231
|
465 |
+
msgid ""
|
466 |
+
"Creates a table of contents for your posts/pages. Works automatically or "
|
467 |
+
"manually (via shortcode or Gutenberg block)."
|
468 |
+
msgstr ""
|
luckywp-table-of-contents.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: LuckyWP Table of Contents
|
4 |
+
Plugin URI: https://theluckywp.com/product/table-of-contents/
|
5 |
+
Description: Creates a table of contents for your posts/pages. Works automatically or manually (via shortcode or Gutenberg block).
|
6 |
+
Version: 1.0.0
|
7 |
+
Author: LuckyWP
|
8 |
+
Author URI: https://theluckywp.com/
|
9 |
+
Text Domain: lwptoc
|
10 |
+
Domain Path: /languages
|
11 |
+
|
12 |
+
LuckyWP Table of Contents is free software: you can redistribute it and/or modify
|
13 |
+
it under the terms of the GNU General Public License as published by
|
14 |
+
the Free Software Foundation, either version 2 of the License, or
|
15 |
+
any later version.
|
16 |
+
|
17 |
+
LuckyWP Table of Contents is distributed in the hope that it will be useful,
|
18 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20 |
+
GNU General Public License for more details.
|
21 |
+
|
22 |
+
You should have received a copy of the GNU General Public License
|
23 |
+
along with LuckyWP Table of Contents. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
|
24 |
+
*/
|
25 |
+
|
26 |
+
require 'lwptocAutoloader.php';
|
27 |
+
$lwptocAutoloader = new lwptocAutoloader();
|
28 |
+
$lwptocAutoloader->register();
|
29 |
+
$lwptocAutoloader->addNamespace('luckywp\tableOfContents', __DIR__);
|
30 |
+
|
31 |
+
$config = require(__DIR__ . '/config/plugin.php');
|
32 |
+
(new \luckywp\tableOfContents\plugin\Plugin($config))->run('1.0.0', __FILE__, 'lwptoc_');
|
33 |
+
|
34 |
+
require_once __DIR__ . '/functions.php';
|
lwptocAutoloader.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class lwptocAutoloader
|
4 |
+
{
|
5 |
+
|
6 |
+
/**
|
7 |
+
* @var array
|
8 |
+
*/
|
9 |
+
protected $prefixes = [];
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string $prefix
|
13 |
+
* @param string $baseDir
|
14 |
+
* @param bool $prepend
|
15 |
+
* @return void
|
16 |
+
*/
|
17 |
+
public function addNamespace($prefix, $baseDir, $prepend = false)
|
18 |
+
{
|
19 |
+
$prefix = trim($prefix, '\\') . '\\';
|
20 |
+
$baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . '/';
|
21 |
+
|
22 |
+
if (isset($this->prefixes[$prefix]) === false) {
|
23 |
+
$this->prefixes[$prefix] = [];
|
24 |
+
}
|
25 |
+
|
26 |
+
if ($prepend) {
|
27 |
+
array_unshift($this->prefixes[$prefix], $baseDir);
|
28 |
+
} else {
|
29 |
+
array_push($this->prefixes[$prefix], $baseDir);
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @return void
|
35 |
+
*/
|
36 |
+
public function register()
|
37 |
+
{
|
38 |
+
spl_autoload_register([$this, 'loadClass']);
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param string $class
|
43 |
+
* @return mixed
|
44 |
+
*/
|
45 |
+
public function loadClass($class)
|
46 |
+
{
|
47 |
+
$prefix = $class;
|
48 |
+
while (false !== $pos = strrpos($prefix, '\\')) {
|
49 |
+
$prefix = substr($class, 0, $pos + 1);
|
50 |
+
$relativeClass = substr($class, $pos + 1);
|
51 |
+
|
52 |
+
$mappedFile = $this->loadMappedFile($prefix, $relativeClass);
|
53 |
+
if ($mappedFile) {
|
54 |
+
return $mappedFile;
|
55 |
+
}
|
56 |
+
|
57 |
+
$prefix = rtrim($prefix, '\\');
|
58 |
+
}
|
59 |
+
return false;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @param string $prefix
|
64 |
+
* @param string $relativeClass
|
65 |
+
* @return mixed Boolean
|
66 |
+
*/
|
67 |
+
protected function loadMappedFile($prefix, $relativeClass)
|
68 |
+
{
|
69 |
+
if (isset($this->prefixes[$prefix]) === false) {
|
70 |
+
return false;
|
71 |
+
}
|
72 |
+
foreach ($this->prefixes[$prefix] as $baseDir) {
|
73 |
+
$file = $baseDir
|
74 |
+
. str_replace('\\', '/', $relativeClass)
|
75 |
+
. '.php';
|
76 |
+
if ($this->requireFile($file)) {
|
77 |
+
return $file;
|
78 |
+
}
|
79 |
+
}
|
80 |
+
return false;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @param string $file
|
85 |
+
* @return bool True
|
86 |
+
*/
|
87 |
+
protected function requireFile($file)
|
88 |
+
{
|
89 |
+
if (file_exists($file)) {
|
90 |
+
require $file;
|
91 |
+
return true;
|
92 |
+
}
|
93 |
+
return false;
|
94 |
+
}
|
95 |
+
}
|
plugin/Activation.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
|
8 |
+
class Activation extends BaseObject
|
9 |
+
{
|
10 |
+
|
11 |
+
public function init()
|
12 |
+
{
|
13 |
+
register_activation_hook(Core::$plugin->fileName, [$this, 'activate']);
|
14 |
+
}
|
15 |
+
|
16 |
+
public function activate()
|
17 |
+
{
|
18 |
+
Core::$plugin->settings->install();
|
19 |
+
}
|
20 |
+
}
|
plugin/Plugin.php
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\admin\Admin;
|
6 |
+
use luckywp\tableOfContents\core\base\BasePlugin;
|
7 |
+
use luckywp\tableOfContents\core\base\Request;
|
8 |
+
use luckywp\tableOfContents\core\base\View;
|
9 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
10 |
+
use luckywp\tableOfContents\front\Front;
|
11 |
+
use luckywp\tableOfContents\plugin\editorBlock\EditorBlock;
|
12 |
+
use luckywp\tableOfContents\plugin\mcePlugin\McePlugin;
|
13 |
+
use WP_Post_Type;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @property Admin $admin
|
17 |
+
* @property Front $front
|
18 |
+
* @property Request $request
|
19 |
+
* @property Settings $settings
|
20 |
+
* @property EditorBlock $editorBlock
|
21 |
+
* @property McePlugin $mcePlugin
|
22 |
+
* @property Shortcode $shortcode
|
23 |
+
* @property View $view
|
24 |
+
*
|
25 |
+
* @property WP_Post_Type[] $postTypes
|
26 |
+
* @property array $depthsList
|
27 |
+
* @property array $numerationsList
|
28 |
+
* @property array $positionsList
|
29 |
+
* @property array $blockSizeUnitsList
|
30 |
+
* @property array $fontSizeUnitsList
|
31 |
+
* @property array $fontWeightsList
|
32 |
+
* @property array $floatsList
|
33 |
+
* @property array $colorSchemesList
|
34 |
+
*/
|
35 |
+
class Plugin extends BasePlugin
|
36 |
+
{
|
37 |
+
|
38 |
+
private $_postTypes;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return WP_Post_Type[]
|
42 |
+
*/
|
43 |
+
public function getPostTypes()
|
44 |
+
{
|
45 |
+
if ($this->_postTypes === null) {
|
46 |
+
$this->_postTypes = get_post_types([
|
47 |
+
'public' => true,
|
48 |
+
], 'objects');
|
49 |
+
}
|
50 |
+
return $this->_postTypes;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @return array
|
55 |
+
*/
|
56 |
+
public function getDepthsList()
|
57 |
+
{
|
58 |
+
return [
|
59 |
+
1 => '1',
|
60 |
+
2 => '2',
|
61 |
+
3 => '3',
|
62 |
+
4 => '4',
|
63 |
+
5 => '5',
|
64 |
+
6 => '6',
|
65 |
+
];
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @return array
|
70 |
+
*/
|
71 |
+
public function getNumerationsList()
|
72 |
+
{
|
73 |
+
return [
|
74 |
+
'none' => esc_html__('Without numeration', 'lwptoc'),
|
75 |
+
'decimalnested' => esc_html__('Decimal numbers (nested)', 'lwptoc'),
|
76 |
+
'decimal' => esc_html__('Decimal numbers', 'lwptoc'),
|
77 |
+
'romannested' => esc_html__('Roman numbers (nested)', 'lwptoc'),
|
78 |
+
'roman' => esc_html__('Roman numbers', 'lwptoc'),
|
79 |
+
];
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @return array
|
84 |
+
*/
|
85 |
+
public function getPositionsList()
|
86 |
+
{
|
87 |
+
return [
|
88 |
+
'beforefirstheading' => esc_html__('Before first heading', 'lwptoc'),
|
89 |
+
'afterfirstheading' => esc_html__('After first heading', 'lwptoc'),
|
90 |
+
'afterfirstblock' => esc_html__('After first block (paragraph, list or heading)', 'lwptoc'),
|
91 |
+
'top' => esc_html__('Top', 'lwptoc'),
|
92 |
+
'bottom' => esc_html__('Bottom', 'lwptoc'),
|
93 |
+
];
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @return array
|
98 |
+
*/
|
99 |
+
public function getBlockSizeUnitsList()
|
100 |
+
{
|
101 |
+
return [
|
102 |
+
'px' => 'px',
|
103 |
+
'%' => '%',
|
104 |
+
];
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @return array
|
109 |
+
*/
|
110 |
+
public function getFontSizeUnitsList()
|
111 |
+
{
|
112 |
+
return [
|
113 |
+
'%' => '%',
|
114 |
+
'em' => 'em',
|
115 |
+
'pt' => 'pt',
|
116 |
+
'px' => 'px',
|
117 |
+
];
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @return array
|
122 |
+
*/
|
123 |
+
public function getFontWeightsList()
|
124 |
+
{
|
125 |
+
return [
|
126 |
+
'thin' => esc_html__('Thin', 'lwptoc'),
|
127 |
+
'extralight' => esc_html__('Extra Light', 'lwptoc'),
|
128 |
+
'light' => esc_html__('Light', 'lwptoc'),
|
129 |
+
'normal' => esc_html__('Normal', 'lwptoc'),
|
130 |
+
'medium' => esc_html__('Medium', 'lwptoc'),
|
131 |
+
'semibold' => esc_html__('Semi Bold', 'lwptoc'),
|
132 |
+
'bold' => esc_html__('Bold', 'lwptoc'),
|
133 |
+
'extrabold' => esc_html__('Extra Bold', 'lwptoc'),
|
134 |
+
'heavy' => esc_html__('Heavy', 'lwptoc'),
|
135 |
+
];
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* @param string $id
|
140 |
+
* @return string|null
|
141 |
+
*/
|
142 |
+
public function fontWeightToValue($id)
|
143 |
+
{
|
144 |
+
return ArrayHelper::getValue([
|
145 |
+
'thin' => '100',
|
146 |
+
'extralight' => '200',
|
147 |
+
'light' => '300',
|
148 |
+
'normal' => 'normal',
|
149 |
+
'medium' => '500',
|
150 |
+
'semibold' => '600',
|
151 |
+
'bold' => 'bold',
|
152 |
+
'extrabold' => '800',
|
153 |
+
'heavy' => '900',
|
154 |
+
], $id);
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* @return array
|
159 |
+
*/
|
160 |
+
public function getFloatsList()
|
161 |
+
{
|
162 |
+
return [
|
163 |
+
'none' => esc_html__('None', 'lwptoc'),
|
164 |
+
'left' => esc_html__('Left', 'lwptoc'),
|
165 |
+
'right' => esc_html__('Right', 'lwptoc'),
|
166 |
+
];
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* @return array
|
171 |
+
*/
|
172 |
+
public function getColorSchemesList()
|
173 |
+
{
|
174 |
+
return [
|
175 |
+
'light' => esc_html__('Light Colors', 'lwptoc'),
|
176 |
+
'dark' => esc_html__('Dark Colors', 'lwptoc'),
|
177 |
+
'white' => esc_html__('White', 'lwptoc'),
|
178 |
+
'transparent' => esc_html__('Transparent', 'lwptoc'),
|
179 |
+
];
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* @param bool $withCustom
|
184 |
+
* @return array
|
185 |
+
*/
|
186 |
+
public function getWidthsList($withCustom = true)
|
187 |
+
{
|
188 |
+
$widths = [
|
189 |
+
'auto' => esc_html__('Auto', 'lwptoc'),
|
190 |
+
'full' => esc_html__('Full Width', 'lwptoc'),
|
191 |
+
'custom' => esc_html__('Custom Value', 'lwptoc'),
|
192 |
+
];
|
193 |
+
if (!$withCustom) {
|
194 |
+
unset($widths['custom']);
|
195 |
+
}
|
196 |
+
return $widths;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* @param string $width
|
201 |
+
* @return bool
|
202 |
+
*/
|
203 |
+
public function isCustomWidth($width)
|
204 |
+
{
|
205 |
+
return !array_key_exists($width, $this->getWidthsList(false));
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* @param string $width
|
210 |
+
* @return string
|
211 |
+
*/
|
212 |
+
public function widthToLabel($width)
|
213 |
+
{
|
214 |
+
if ($this->isCustomWidth($width)) {
|
215 |
+
return $width;
|
216 |
+
}
|
217 |
+
return $this->getWidthsList()[$width];
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* @param string $fontSize
|
222 |
+
* @return string
|
223 |
+
*/
|
224 |
+
public function fontSizeToLabel($fontSize)
|
225 |
+
{
|
226 |
+
return $fontSize == 'default' ? esc_html__('Default', 'lwptoc') : $fontSize;
|
227 |
+
}
|
228 |
+
|
229 |
+
private function pluginI18n()
|
230 |
+
{
|
231 |
+
__('Creates a table of contents for your posts/pages. Works automatically or manually (via shortcode or Gutenberg block).', 'lwptdr');
|
232 |
+
}
|
233 |
+
}
|
plugin/PostSettings.php
ADDED
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
8 |
+
|
9 |
+
class PostSettings extends BaseObject
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var bool
|
14 |
+
*/
|
15 |
+
public $enabled = true;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var int|null
|
19 |
+
*/
|
20 |
+
public $min;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var int|null
|
24 |
+
*/
|
25 |
+
public $depth;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var bool|null
|
29 |
+
*/
|
30 |
+
public $hierarchical;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string|null
|
34 |
+
*/
|
35 |
+
public $numeration;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string|null
|
39 |
+
*/
|
40 |
+
public $title;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var bool|null
|
44 |
+
*/
|
45 |
+
public $toggle;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @var string|null
|
49 |
+
*/
|
50 |
+
public $labelShow;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var string|null
|
54 |
+
*/
|
55 |
+
public $labelHide;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @var bool|null
|
59 |
+
*/
|
60 |
+
public $hideItems;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @var bool|null
|
64 |
+
*/
|
65 |
+
public $smoothScroll;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @var int|null
|
69 |
+
*/
|
70 |
+
public $smoothScrollOffset;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @var string|null
|
74 |
+
*/
|
75 |
+
public $position;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @var string|null
|
79 |
+
*/
|
80 |
+
public $width;
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @var string|null
|
84 |
+
*/
|
85 |
+
public $float;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @var string|null
|
89 |
+
*/
|
90 |
+
public $titleFontSize;
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @var string|null
|
94 |
+
*/
|
95 |
+
public $titleFontWeight;
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @var string|null
|
99 |
+
*/
|
100 |
+
public $itemsFontSize;
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @var string|null
|
104 |
+
*/
|
105 |
+
public $colorScheme;
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @var string|null
|
109 |
+
*/
|
110 |
+
public $backgroundColor;
|
111 |
+
|
112 |
+
/**
|
113 |
+
* @var string|null
|
114 |
+
*/
|
115 |
+
public $borderColor;
|
116 |
+
|
117 |
+
/**
|
118 |
+
* @var string|null
|
119 |
+
*/
|
120 |
+
public $titleColor;
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @var string|null
|
124 |
+
*/
|
125 |
+
public $linkColor;
|
126 |
+
|
127 |
+
/**
|
128 |
+
* @var string|null
|
129 |
+
*/
|
130 |
+
public $hoverLinkColor;
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @var string|null
|
134 |
+
*/
|
135 |
+
public $visitedLinkColor;
|
136 |
+
|
137 |
+
/**
|
138 |
+
* @var int
|
139 |
+
*/
|
140 |
+
protected $postId;
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @param int $postId
|
144 |
+
*/
|
145 |
+
public function __construct($postId)
|
146 |
+
{
|
147 |
+
parent::__construct();
|
148 |
+
if (in_array(get_post_type($postId), Core::$plugin->admin->getMetaboxPostTypes())) {
|
149 |
+
$this->postId = $postId;
|
150 |
+
$data = get_post_meta($postId, '_lwptoc_settings', true);
|
151 |
+
if ($data && is_array($data)) {
|
152 |
+
$this->enabled = ArrayHelper::getValue($data, 'enabled', true);
|
153 |
+
$this->min = ArrayHelper::getValue($data, 'min');
|
154 |
+
$this->depth = ArrayHelper::getValue($data, 'depth');
|
155 |
+
$this->hierarchical = ArrayHelper::getValue($data, 'hierarchical');
|
156 |
+
$this->numeration = ArrayHelper::getValue($data, 'numeration');
|
157 |
+
$this->title = ArrayHelper::getValue($data, 'title');
|
158 |
+
$this->toggle = ArrayHelper::getValue($data, 'toggle');
|
159 |
+
$this->labelShow = ArrayHelper::getValue($data, 'labelShow');
|
160 |
+
$this->labelHide = ArrayHelper::getValue($data, 'labelHide');
|
161 |
+
$this->hideItems = ArrayHelper::getValue($data, 'hideItems');
|
162 |
+
$this->smoothScroll = ArrayHelper::getValue($data, 'smoothScroll');
|
163 |
+
$this->smoothScrollOffset = ArrayHelper::getValue($data, 'smoothScrollOffset');
|
164 |
+
$this->position = ArrayHelper::getValue($data, 'position');
|
165 |
+
$this->width = ArrayHelper::getValue($data, 'width');
|
166 |
+
$this->float = ArrayHelper::getValue($data, 'float');
|
167 |
+
$this->titleFontSize = ArrayHelper::getValue($data, 'titleFontSize');
|
168 |
+
$this->titleFontWeight = ArrayHelper::getValue($data, 'titleFontWeight');
|
169 |
+
$this->itemsFontSize = ArrayHelper::getValue($data, 'itemsFontSize');
|
170 |
+
$this->colorScheme = ArrayHelper::getValue($data, 'colorScheme');
|
171 |
+
$this->backgroundColor = ArrayHelper::getValue($data, 'backgroundColor');
|
172 |
+
$this->borderColor = ArrayHelper::getValue($data, 'borderColor');
|
173 |
+
$this->titleColor = ArrayHelper::getValue($data, 'titleColor');
|
174 |
+
$this->linkColor = ArrayHelper::getValue($data, 'linkColor');
|
175 |
+
$this->hoverLinkColor = ArrayHelper::getValue($data, 'hoverLinkColor');
|
176 |
+
$this->visitedLinkColor = ArrayHelper::getValue($data, 'visitedLinkColor');
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
public function save()
|
182 |
+
{
|
183 |
+
$data = [];
|
184 |
+
if ($this->min !== null) {
|
185 |
+
$data['min'] = (int)$this->min;
|
186 |
+
}
|
187 |
+
if ($this->depth !== null) {
|
188 |
+
$data['depth'] = (int)$this->depth;
|
189 |
+
}
|
190 |
+
if ($this->hierarchical !== null) {
|
191 |
+
$data['hierarchical'] = (bool)$this->hierarchical;
|
192 |
+
}
|
193 |
+
if ($this->numeration !== null) {
|
194 |
+
$data['numeration'] = $this->numeration;
|
195 |
+
}
|
196 |
+
if ($this->title !== null) {
|
197 |
+
$data['title'] = wp_slash($this->title);
|
198 |
+
}
|
199 |
+
if ($this->toggle !== null) {
|
200 |
+
$data['toggle'] = (bool)$this->toggle;
|
201 |
+
}
|
202 |
+
if ($this->labelShow !== null) {
|
203 |
+
$data['labelShow'] = wp_slash($this->labelShow);
|
204 |
+
}
|
205 |
+
if ($this->labelHide !== null) {
|
206 |
+
$data['labelHide'] = wp_slash($this->labelHide);
|
207 |
+
}
|
208 |
+
if ($this->hideItems !== null) {
|
209 |
+
$data['hideItems'] = (bool)$this->hideItems;
|
210 |
+
}
|
211 |
+
if ($this->smoothScroll !== null) {
|
212 |
+
$data['smoothScroll'] = (bool)$this->smoothScroll;
|
213 |
+
}
|
214 |
+
if ($this->smoothScrollOffset !== null) {
|
215 |
+
$data['smoothScrollOffset'] = (int)$this->smoothScrollOffset;
|
216 |
+
}
|
217 |
+
if ($this->position !== null) {
|
218 |
+
$data['position'] = $this->position;
|
219 |
+
}
|
220 |
+
if ($this->width !== null) {
|
221 |
+
$data['width'] = $this->width;
|
222 |
+
}
|
223 |
+
if ($this->float !== null) {
|
224 |
+
$data['float'] = $this->float;
|
225 |
+
}
|
226 |
+
if ($this->titleFontSize !== null) {
|
227 |
+
$data['titleFontSize'] = $this->titleFontSize;
|
228 |
+
}
|
229 |
+
if ($this->titleFontWeight !== null) {
|
230 |
+
$data['titleFontWeight'] = $this->titleFontWeight;
|
231 |
+
}
|
232 |
+
if ($this->itemsFontSize !== null) {
|
233 |
+
$data['itemsFontSize'] = $this->itemsFontSize;
|
234 |
+
}
|
235 |
+
if ($this->colorScheme !== null) {
|
236 |
+
$data['colorScheme'] = $this->colorScheme;
|
237 |
+
}
|
238 |
+
if ($this->backgroundColor !== null) {
|
239 |
+
$data['backgroundColor'] = $this->backgroundColor;
|
240 |
+
}
|
241 |
+
if ($this->borderColor !== null) {
|
242 |
+
$data['borderColor'] = $this->borderColor;
|
243 |
+
}
|
244 |
+
if ($this->titleColor !== null) {
|
245 |
+
$data['titleColor'] = $this->titleColor;
|
246 |
+
}
|
247 |
+
if ($this->linkColor !== null) {
|
248 |
+
$data['linkColor'] = $this->linkColor;
|
249 |
+
}
|
250 |
+
if ($this->hoverLinkColor !== null) {
|
251 |
+
$data['hoverLinkColor'] = $this->hoverLinkColor;
|
252 |
+
}
|
253 |
+
if ($this->visitedLinkColor !== null) {
|
254 |
+
$data['visitedLinkColor'] = $this->visitedLinkColor;
|
255 |
+
}
|
256 |
+
if ($data || !$this->enabled) {
|
257 |
+
$data['enabled'] = $this->enabled;
|
258 |
+
update_post_meta($this->postId, '_lwptoc_settings', $data);
|
259 |
+
} else {
|
260 |
+
delete_post_meta($this->postId, '_lwptoc_settings');
|
261 |
+
}
|
262 |
+
}
|
263 |
+
}
|
plugin/Settings.php
ADDED
@@ -0,0 +1,301 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @property int $generalMin
|
9 |
+
* @property int $generalDepth
|
10 |
+
* @property bool $generalHierarchical
|
11 |
+
* @property string $generalNumeration
|
12 |
+
* @property string $generalTitle
|
13 |
+
* @property bool $generalToggle
|
14 |
+
* @property string $generalLabelShow
|
15 |
+
* @property string $generalLabelHide
|
16 |
+
* @property bool $generalHideItems
|
17 |
+
* @property bool $generalSmoothScroll
|
18 |
+
* @property int $generalSmoothScrollOffset
|
19 |
+
*
|
20 |
+
* @property string $appearanceWidth
|
21 |
+
* @property string $appearanceFloat
|
22 |
+
* @property string $appearanceTitleFontSize
|
23 |
+
* @property string $appearanceTitleFontWeight
|
24 |
+
* @property string $appearanceItemsFontSize
|
25 |
+
* @property string $appearanceColorScheme
|
26 |
+
* @property string|null $appearanceBackgroundColor
|
27 |
+
* @property string|null $appearanceBorderColor
|
28 |
+
* @property string|null $appearanceTitleColor
|
29 |
+
* @property string|null $appearanceLinkColor
|
30 |
+
* @property string|null $appearanceHoverLinkColor
|
31 |
+
* @property string|null $appearanceVisitedLinkColor
|
32 |
+
*
|
33 |
+
* @property bool $autoInsertEnable
|
34 |
+
* @property string $autoInsertPosition
|
35 |
+
* @property array $autoInsertPostTypes
|
36 |
+
*/
|
37 |
+
class Settings extends \luckywp\tableOfContents\core\wp\Settings
|
38 |
+
{
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return int
|
42 |
+
*/
|
43 |
+
public function getGeneralMin()
|
44 |
+
{
|
45 |
+
return (int)$this->getValue('general', 'min', 2);
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @return int
|
50 |
+
*/
|
51 |
+
public function getGeneralDepth()
|
52 |
+
{
|
53 |
+
$depth = (int)$this->getValue('general', 'depth');
|
54 |
+
if (!array_key_exists($depth, Core::$plugin->depthsList)) {
|
55 |
+
$depth = 6;
|
56 |
+
}
|
57 |
+
return $depth;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return bool
|
62 |
+
*/
|
63 |
+
public function getGeneralHierarchical()
|
64 |
+
{
|
65 |
+
return (bool)$this->getValue('general', 'hierarchical', true);
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public function getGeneralNumeration()
|
72 |
+
{
|
73 |
+
$numeration = $this->getValue('general', 'numeration');
|
74 |
+
if (!array_key_exists($numeration, Core::$plugin->numerationsList)) {
|
75 |
+
$numeration = 'decimalnested';
|
76 |
+
}
|
77 |
+
return $numeration;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
public function getGeneralTitle()
|
84 |
+
{
|
85 |
+
return (string)$this->getValue('general', 'title', __('Contents', 'lwptoc'));
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return bool
|
90 |
+
*/
|
91 |
+
public function getGeneralToggle()
|
92 |
+
{
|
93 |
+
return (bool)$this->getValue('general', 'toggle', true);
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @return string
|
98 |
+
*/
|
99 |
+
public function getGeneralLabelShow()
|
100 |
+
{
|
101 |
+
return (string)$this->getValue('general', 'labelShow', __('show', 'lwptoc'));
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
public function getGeneralLabelHide()
|
108 |
+
{
|
109 |
+
return (string)$this->getValue('general', 'labelHide', __('hide', 'lwptoc'));
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* @return bool
|
114 |
+
*/
|
115 |
+
public function getGeneralHideItems()
|
116 |
+
{
|
117 |
+
return (bool)$this->getValue('general', 'hideItems', false);
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @return bool
|
122 |
+
*/
|
123 |
+
public function getGeneralSmoothScroll()
|
124 |
+
{
|
125 |
+
return (bool)$this->getValue('general', 'smoothScroll', true);
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* @return int
|
130 |
+
*/
|
131 |
+
public function getGeneralSmoothScrollOffset()
|
132 |
+
{
|
133 |
+
return (int)$this->getValue('general', 'smoothScrollOffset', 24);
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return string
|
138 |
+
*/
|
139 |
+
public function getAppearanceWidth()
|
140 |
+
{
|
141 |
+
return $this->sanitizeWidth((string)$this->getValue('appearance', 'width', 'auto'));
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @return string
|
146 |
+
*/
|
147 |
+
public function getAppearanceFloat()
|
148 |
+
{
|
149 |
+
$float = $this->getValue('appearance', 'float');
|
150 |
+
if (!array_key_exists($float, Core::$plugin->floatsList)) {
|
151 |
+
$float = 'none';
|
152 |
+
}
|
153 |
+
return $float;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* @return string
|
158 |
+
*/
|
159 |
+
public function getAppearanceTitleFontSize()
|
160 |
+
{
|
161 |
+
return $this->sanitizeFontSize((string)$this->getValue('appearance', 'titleFontSize', 'default'));
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @return string
|
166 |
+
*/
|
167 |
+
public function getAppearanceTitleFontWeight()
|
168 |
+
{
|
169 |
+
$weight = $this->getValue('appearance', 'titleFontWeight');
|
170 |
+
if (!array_key_exists($weight, Core::$plugin->fontWeightsList)) {
|
171 |
+
$weight = 'bold';
|
172 |
+
}
|
173 |
+
return $weight;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* @return string
|
178 |
+
*/
|
179 |
+
public function getAppearanceItemsFontSize()
|
180 |
+
{
|
181 |
+
return $this->sanitizeFontSize((string)$this->getValue('appearance', 'itemsFontSize', 'default'));
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* @return string
|
186 |
+
*/
|
187 |
+
public function getAppearanceColorScheme()
|
188 |
+
{
|
189 |
+
$scheme = $this->getValue('appearance', 'colorScheme');
|
190 |
+
if (!array_key_exists($scheme, Core::$plugin->colorSchemesList)) {
|
191 |
+
$scheme = 'light';
|
192 |
+
}
|
193 |
+
return $scheme;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* @return string|null
|
198 |
+
*/
|
199 |
+
public function getAppearanceBackgroundColor()
|
200 |
+
{
|
201 |
+
return $this->getValue('appearance', 'backgroundColor');
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* @return string|null
|
206 |
+
*/
|
207 |
+
public function getAppearanceBorderColor()
|
208 |
+
{
|
209 |
+
return $this->getValue('appearance', 'borderColor');
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @return string|null
|
214 |
+
*/
|
215 |
+
public function getAppearanceTitleColor()
|
216 |
+
{
|
217 |
+
return $this->getValue('appearance', 'titleColor');
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* @return string|null
|
222 |
+
*/
|
223 |
+
public function getAppearanceLinkColor()
|
224 |
+
{
|
225 |
+
return $this->getValue('appearance', 'linkColor');
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* @return string|null
|
230 |
+
*/
|
231 |
+
public function getAppearanceHoverLinkColor()
|
232 |
+
{
|
233 |
+
return $this->getValue('appearance', 'hoverLinkColor');
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* @return string|null
|
238 |
+
*/
|
239 |
+
public function getAppearanceVisitedLinkColor()
|
240 |
+
{
|
241 |
+
return $this->getValue('appearance', 'visitedLinkColor');
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* @return bool
|
246 |
+
*/
|
247 |
+
public function getAutoInsertEnable()
|
248 |
+
{
|
249 |
+
return (bool)$this->getValue('autoInsert', 'enable', true);
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* @return string
|
254 |
+
*/
|
255 |
+
public function getAutoInsertPosition()
|
256 |
+
{
|
257 |
+
$position = $this->getValue('autoInsert', 'position');
|
258 |
+
if (!array_key_exists($position, Core::$plugin->positionsList)) {
|
259 |
+
$position = 'beforefirstheading';
|
260 |
+
}
|
261 |
+
return $position;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* @return array
|
266 |
+
*/
|
267 |
+
public function getAutoInsertPostTypes()
|
268 |
+
{
|
269 |
+
$postTypes = $this->getValue('autoInsert', 'postTypes', []);
|
270 |
+
return is_array($postTypes) ? $postTypes : [];
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* @param string $value
|
275 |
+
* @param null $matches
|
276 |
+
* @return string
|
277 |
+
*/
|
278 |
+
public function sanitizeWidth($value, &$matches = null)
|
279 |
+
{
|
280 |
+
if (!Core::$plugin->isCustomWidth($value)) {
|
281 |
+
return $value;
|
282 |
+
}
|
283 |
+
if (preg_match('/^(\d+|\d+\.\d+)(' . implode('|', array_keys(Core::$plugin->blockSizeUnitsList)) . ')$/', $value, $matches)) {
|
284 |
+
return $value;
|
285 |
+
}
|
286 |
+
return 'auto';
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* @param string $value
|
291 |
+
* @param null $matches
|
292 |
+
* @return string
|
293 |
+
*/
|
294 |
+
public function sanitizeFontSize($value, &$matches = null)
|
295 |
+
{
|
296 |
+
if (preg_match('/^(\d+|\d+\.\d+)(' . implode('|', array_keys(Core::$plugin->fontSizeUnitsList)) . ')$/', $value, $matches)) {
|
297 |
+
return $value;
|
298 |
+
}
|
299 |
+
return 'default';
|
300 |
+
}
|
301 |
+
}
|
plugin/Shortcode.php
ADDED
@@ -0,0 +1,442 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
use luckywp\tableOfContents\core\helpers\ArrayHelper;
|
8 |
+
use luckywp\tableOfContents\core\helpers\Html;
|
9 |
+
use WP_Post;
|
10 |
+
|
11 |
+
class Shortcode extends BaseObject
|
12 |
+
{
|
13 |
+
|
14 |
+
const TAG = 'lwptoc';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var int
|
18 |
+
*/
|
19 |
+
protected $idCounter;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var array
|
23 |
+
*/
|
24 |
+
protected $headers;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var int
|
28 |
+
*/
|
29 |
+
public $currentOutputDepth;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var array
|
33 |
+
*/
|
34 |
+
public $overrideColors = [];
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Инициализация
|
38 |
+
*/
|
39 |
+
public function init()
|
40 |
+
{
|
41 |
+
parent::init();
|
42 |
+
add_shortcode(self::TAG, function ($attrs) {
|
43 |
+
if (!is_array($attrs)) {
|
44 |
+
$attrs = [];
|
45 |
+
}
|
46 |
+
global $post;
|
47 |
+
if ($post instanceof WP_Post) {
|
48 |
+
$postSettings = new PostSettings($post->ID);
|
49 |
+
foreach ([
|
50 |
+
'min',
|
51 |
+
'depth',
|
52 |
+
'hierarchical',
|
53 |
+
'numeration',
|
54 |
+
'title',
|
55 |
+
'toggle',
|
56 |
+
'labelShow',
|
57 |
+
'labelHide',
|
58 |
+
'hideItems',
|
59 |
+
'smoothScroll',
|
60 |
+
'smoothScrollOffset',
|
61 |
+
'width',
|
62 |
+
'float',
|
63 |
+
'titleFontSize',
|
64 |
+
'titleFontWeight',
|
65 |
+
'itemsFontSize',
|
66 |
+
'colorScheme',
|
67 |
+
'backgroundColor',
|
68 |
+
'borderColor',
|
69 |
+
'titleColor',
|
70 |
+
'linkColor',
|
71 |
+
'hoverLinkColor',
|
72 |
+
'visitedLinkColor',
|
73 |
+
] as $var) {
|
74 |
+
if (!array_key_exists($var, $attrs)) {
|
75 |
+
$attrs[$var] = $postSettings->$var;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
79 |
+
return $this->make($attrs);
|
80 |
+
});
|
81 |
+
add_filter('the_content', [$this, 'begin'], 999);
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @param string $content
|
86 |
+
* @return string
|
87 |
+
*/
|
88 |
+
public function begin($content)
|
89 |
+
{
|
90 |
+
if ($this->needToc($content)) {
|
91 |
+
$this->idCounter = 0;
|
92 |
+
$this->headers = [];
|
93 |
+
$content = preg_replace_callback('#<h([1-6])(.*?)>(.*?)</h\d>#', [$this, 'processHeaders'], $content);
|
94 |
+
$content = preg_replace_callback('/' . get_shortcode_regex() . '/s', [$this, 'doShortcode'], $content);
|
95 |
+
}
|
96 |
+
return $content;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Выводить ли содержание?
|
101 |
+
* @param string $content
|
102 |
+
* @return bool
|
103 |
+
*/
|
104 |
+
protected function needToc($content)
|
105 |
+
{
|
106 |
+
return is_singular() &&
|
107 |
+
has_shortcode($content, self::TAG);
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Сбор данных и добавление якорей к заголовкам
|
112 |
+
* @param array $m
|
113 |
+
* @return string
|
114 |
+
*/
|
115 |
+
public function processHeaders($m)
|
116 |
+
{
|
117 |
+
$header = [
|
118 |
+
'id' => 'lwptoc' . ++$this->idCounter,
|
119 |
+
'index' => (int)$m[1],
|
120 |
+
'label' => strip_tags($m[3]),
|
121 |
+
];
|
122 |
+
$this->headers[] = $header;
|
123 |
+
|
124 |
+
$content = '';
|
125 |
+
$htmlOptions = [
|
126 |
+
'name' => $header['id'],
|
127 |
+
];
|
128 |
+
$anchor = Html::a($content, null, $htmlOptions);
|
129 |
+
|
130 |
+
return $anchor . $m[0];
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Заменить шорткод на блок с содержанием
|
135 |
+
* @param array $m
|
136 |
+
* @return string
|
137 |
+
*/
|
138 |
+
public function doShortcode($m)
|
139 |
+
{
|
140 |
+
if ($m[2] == self::TAG) {
|
141 |
+
return $this->shortcode(shortcode_parse_atts($m[3]));
|
142 |
+
}
|
143 |
+
return $m[0];
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @param array $attrs
|
148 |
+
* @return string
|
149 |
+
*/
|
150 |
+
protected function shortcode($attrs)
|
151 |
+
{
|
152 |
+
$headerStyles = [];
|
153 |
+
$titleStyles = [];
|
154 |
+
$itemsStyles = [];
|
155 |
+
|
156 |
+
$min = (int)ArrayHelper::getValue($attrs, 'min', Core::$plugin->settings->generalMin);
|
157 |
+
if ($min < 1) {
|
158 |
+
$min = 1;
|
159 |
+
}
|
160 |
+
if (count($this->headers) < $min) {
|
161 |
+
return '';
|
162 |
+
}
|
163 |
+
|
164 |
+
$items = [];
|
165 |
+
$tree = [];
|
166 |
+
foreach ($this->headers as $header) {
|
167 |
+
$node = null;
|
168 |
+
while (count($tree) && ($node === null)) {
|
169 |
+
end($tree);
|
170 |
+
$key = key($tree);
|
171 |
+
if ($header['index'] > $tree[$key]['index']) {
|
172 |
+
$node = $key;
|
173 |
+
} else {
|
174 |
+
unset($tree[$key]);
|
175 |
+
}
|
176 |
+
}
|
177 |
+
|
178 |
+
$item = [
|
179 |
+
'id' => $header['id'],
|
180 |
+
'index' => $header['index'],
|
181 |
+
'number' => null,
|
182 |
+
'label' => $header['label'],
|
183 |
+
'childrens' => [],
|
184 |
+
];
|
185 |
+
|
186 |
+
if ($node === null) {
|
187 |
+
$items[] = $item;
|
188 |
+
$tree[] = &$items[count($items) - 1];
|
189 |
+
} else {
|
190 |
+
$tree[$node]['childrens'][] = $item;
|
191 |
+
$tree[] = &$tree[$node]['childrens'][count($tree[$node]['childrens']) - 1];
|
192 |
+
}
|
193 |
+
}
|
194 |
+
unset($tree);
|
195 |
+
|
196 |
+
// Вложенность
|
197 |
+
$depth = (int)ArrayHelper::getValue($attrs, 'depth', Core::$plugin->settings->generalDepth);
|
198 |
+
if (!array_key_exists($depth, Core::$plugin->depthsList)) {
|
199 |
+
$depth = 6;
|
200 |
+
}
|
201 |
+
|
202 |
+
// Уберём все элменты, не подходящие по вложенности
|
203 |
+
$currentDepth = 0;
|
204 |
+
$fn = function (&$items, $depth) use (&$fn, &$currentDepth) {
|
205 |
+
$currentDepth++;
|
206 |
+
foreach ($items as $key => $item) {
|
207 |
+
if ($currentDepth == $depth) {
|
208 |
+
$items[$key]['childrens'] = [];
|
209 |
+
}
|
210 |
+
$fn($items[$key]['childrens'], $depth);
|
211 |
+
}
|
212 |
+
$currentDepth--;
|
213 |
+
};
|
214 |
+
$fn($items, $depth);
|
215 |
+
|
216 |
+
// Нумерация
|
217 |
+
$numeration = ArrayHelper::getValue($attrs, 'numeration', Core::$plugin->settings->generalNumeration);
|
218 |
+
$numeration = str_replace(['_', ' ', '-'], '', strtolower($numeration));
|
219 |
+
if (in_array($numeration, ['decimalnested', 'decimal', 'roman', 'romannested'])) {
|
220 |
+
if (in_array($numeration, ['decimalnested', 'romannested'])) {
|
221 |
+
$fn = function (&$items, $numbers) use (&$fn, $numeration) {
|
222 |
+
foreach ($items as $key => $item) {
|
223 |
+
$numbers[count($numbers) - 1]++;
|
224 |
+
$items[$key]['number'] = implode('.', $numeration == 'decimalnested' ? $numbers : array_map([$this, 'decimalToRoman'], $numbers));
|
225 |
+
$fn($items[$key]['childrens'], array_merge($numbers, [0]));
|
226 |
+
}
|
227 |
+
};
|
228 |
+
$fn($items, [0]);
|
229 |
+
} else {
|
230 |
+
$number = 0;
|
231 |
+
$fn = function (&$items) use (&$fn, &$number, $numeration) {
|
232 |
+
foreach ($items as $key => $item) {
|
233 |
+
$number++;
|
234 |
+
$items[$key]['number'] = $numeration == 'decimal' ? $number : $this->decimalToRoman($number);
|
235 |
+
$fn($items[$key]['childrens']);
|
236 |
+
}
|
237 |
+
};
|
238 |
+
$fn($items);
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
// Без иерархии
|
243 |
+
$hierarchical = $this->assertBool(ArrayHelper::getValue($attrs, 'hierarchical', Core::$plugin->settings->generalHierarchical));
|
244 |
+
if (!$hierarchical) {
|
245 |
+
$newItems = [];
|
246 |
+
$fn = function ($items) use (&$fn, &$newItems) {
|
247 |
+
foreach ($items as $item) {
|
248 |
+
$newItem = $item;
|
249 |
+
$newItem['childrens'] = [];
|
250 |
+
$newItems[] = $newItem;
|
251 |
+
$fn($item['childrens']);
|
252 |
+
}
|
253 |
+
};
|
254 |
+
$fn($items);
|
255 |
+
$items = $newItems;
|
256 |
+
}
|
257 |
+
|
258 |
+
$toggle = $this->assertBool(ArrayHelper::getValue($attrs, 'toggle', Core::$plugin->settings->generalToggle));
|
259 |
+
$labelShow = null;
|
260 |
+
$labelHide = null;
|
261 |
+
$hideItems = false;
|
262 |
+
if ($toggle) {
|
263 |
+
$labelShow = ArrayHelper::getValue($attrs, 'labelshow', Core::$plugin->settings->generalLabelShow);
|
264 |
+
$labelHide = ArrayHelper::getValue($attrs, 'labelhide', Core::$plugin->settings->generalLabelHide);
|
265 |
+
$hideItems = $this->assertBool(ArrayHelper::getValue($attrs, 'hideitems', Core::$plugin->settings->generalHideItems));
|
266 |
+
}
|
267 |
+
if ($hideItems) {
|
268 |
+
$itemsStyles[] = 'display:none;';
|
269 |
+
}
|
270 |
+
|
271 |
+
$containerOptions = [
|
272 |
+
'class' => ['lwptoc'],
|
273 |
+
'data' => [],
|
274 |
+
];
|
275 |
+
|
276 |
+
// Плавная прокрутка
|
277 |
+
$smoothScroll = $this->assertBool(ArrayHelper::getValue($attrs, 'smoothscroll', Core::$plugin->settings->generalSmoothScroll));
|
278 |
+
$containerOptions['data']['smooth-scroll'] = $smoothScroll ? 1 : 0;
|
279 |
+
if ($smoothScroll) {
|
280 |
+
$containerOptions['data']['smooth-scroll-offset'] = (int)ArrayHelper::getValue($attrs, 'smoothscrolloffset', Core::$plugin->settings->generalSmoothScrollOffset);
|
281 |
+
}
|
282 |
+
|
283 |
+
// Ширина
|
284 |
+
$width = ArrayHelper::getValue($attrs, 'width');
|
285 |
+
if ($width === null) {
|
286 |
+
$width = Core::$plugin->settings->appearanceWidth;
|
287 |
+
} else {
|
288 |
+
$width = Core::$plugin->settings->sanitizeWidth($width);
|
289 |
+
}
|
290 |
+
if ($width != 'full') {
|
291 |
+
if ($width == 'auto') {
|
292 |
+
$containerOptions['class'][] = 'lwptoc-autoWidth';
|
293 |
+
} else {
|
294 |
+
$containerOptions['style'] = 'width:' . $width;
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
+
// Выравнивание
|
299 |
+
$float = ArrayHelper::getValue($attrs, 'float', Core::$plugin->settings->appearanceFloat);
|
300 |
+
$float = strtolower($float);
|
301 |
+
if (in_array($float, ['left', 'right'])) {
|
302 |
+
$containerOptions['class'][] = 'lwptoc-' . $float;
|
303 |
+
}
|
304 |
+
|
305 |
+
// Размер шрифта заголовка
|
306 |
+
$titleFontSize = ArrayHelper::getValue($attrs, 'titlefontsize');
|
307 |
+
if ($titleFontSize === null) {
|
308 |
+
$titleFontSize = Core::$plugin->settings->appearanceTitleFontSize;
|
309 |
+
} else {
|
310 |
+
$titleFontSize = Core::$plugin->settings->sanitizeFontSize($titleFontSize);
|
311 |
+
}
|
312 |
+
if ($titleFontSize != 'default') {
|
313 |
+
$headerStyles[] = 'font-size:' . $titleFontSize . ';';
|
314 |
+
}
|
315 |
+
|
316 |
+
// Толщина шрифта заголовка
|
317 |
+
$titleFontWeight = ArrayHelper::getValue($attrs, 'titlefontweight', Core::$plugin->settings->appearanceTitleFontWeight);
|
318 |
+
$titleFontWeight = str_replace(['_', ' ', '-'], '', strtolower($titleFontWeight));
|
319 |
+
if ($titleFontWeight != 'bold' && array_key_exists($titleFontWeight, Core::$plugin->fontWeightsList)) {
|
320 |
+
$titleStyles[] = 'font-weight:' . Core::$plugin->fontWeightToValue($titleFontWeight) . ';';
|
321 |
+
}
|
322 |
+
|
323 |
+
// Размер шрифта элементов
|
324 |
+
$itemsFontSize = ArrayHelper::getValue($attrs, 'itemsfontsize');
|
325 |
+
if ($itemsFontSize === null) {
|
326 |
+
$itemsFontSize = Core::$plugin->settings->appearanceItemsFontSize;
|
327 |
+
} else {
|
328 |
+
$itemsFontSize = Core::$plugin->settings->sanitizeFontSize($itemsFontSize);
|
329 |
+
}
|
330 |
+
if ($itemsFontSize == '90%') {
|
331 |
+
$containerOptions['class'][] = 'lwptoc-baseItems';
|
332 |
+
} elseif ($itemsFontSize != 'default') {
|
333 |
+
$itemsStyles[] = 'font-size:' . $itemsFontSize . ';';
|
334 |
+
}
|
335 |
+
|
336 |
+
// Цветовая схема
|
337 |
+
$colorScheme = ArrayHelper::getValue($attrs, 'colorscheme', Core::$plugin->settings->appearanceColorScheme);
|
338 |
+
$colorScheme = str_replace(['_', ' ', '-'], '', strtolower($colorScheme));
|
339 |
+
if (array_key_exists($colorScheme, Core::$plugin->colorSchemesList)) {
|
340 |
+
$containerOptions['class'][] = 'lwptoc-' . $colorScheme;
|
341 |
+
}
|
342 |
+
|
343 |
+
// Запомним цвета для переопределения
|
344 |
+
$this->overrideColors = [];
|
345 |
+
foreach ([
|
346 |
+
'backgroundColor',
|
347 |
+
'borderColor',
|
348 |
+
'titleColor',
|
349 |
+
'linkColor',
|
350 |
+
'hoverLinkColor',
|
351 |
+
'visitedLinkColor',
|
352 |
+
] as $var) {
|
353 |
+
$color = ArrayHelper::getValue($attrs, strtolower($var), Core::$plugin->settings->{'appearance' . ucfirst($var)});
|
354 |
+
$color = Core::$plugin->settings->sanitizeCallbackColor($color);
|
355 |
+
if ($color) {
|
356 |
+
$this->overrideColors[$var] = $color;
|
357 |
+
}
|
358 |
+
}
|
359 |
+
|
360 |
+
// Вывод
|
361 |
+
$this->currentOutputDepth = -1;
|
362 |
+
return Core::$plugin->front->render('body', [
|
363 |
+
'title' => ArrayHelper::getValue($attrs, 'title', Core::$plugin->settings->generalTitle),
|
364 |
+
'toggle' => $toggle,
|
365 |
+
'labelShow' => $labelShow,
|
366 |
+
'labelHide' => $labelHide,
|
367 |
+
'hideItems' => $hideItems,
|
368 |
+
'containerOptions' => $containerOptions,
|
369 |
+
'headerStyles' => $headerStyles,
|
370 |
+
'titleStyles' => $titleStyles,
|
371 |
+
'itemsStyles' => $itemsStyles,
|
372 |
+
'items' => $items,
|
373 |
+
]);
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* @param array $attrs
|
378 |
+
* @return string
|
379 |
+
*/
|
380 |
+
public function make($attrs)
|
381 |
+
{
|
382 |
+
$shortcode = '[' . static::TAG;
|
383 |
+
foreach ($attrs as $k => $v) {
|
384 |
+
if ($v !== null) {
|
385 |
+
if (is_string($v)) {
|
386 |
+
$v = str_replace('"', '"', $v);
|
387 |
+
} elseif (is_bool($v)) {
|
388 |
+
$v = $v ? 1 : 0;
|
389 |
+
}
|
390 |
+
$shortcode .= ' ' . $k . '="' . $v . '"';
|
391 |
+
}
|
392 |
+
}
|
393 |
+
$shortcode .= ']';
|
394 |
+
return $shortcode;
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* @param $v
|
399 |
+
* @return bool
|
400 |
+
*/
|
401 |
+
protected function assertBool($v)
|
402 |
+
{
|
403 |
+
if (is_bool($v)) {
|
404 |
+
return $v;
|
405 |
+
}
|
406 |
+
$v = strtolower((string)$v);
|
407 |
+
if (in_array($v, ['1', 'true', 'yes', 'y'], true)) {
|
408 |
+
return true;
|
409 |
+
}
|
410 |
+
return false;
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* @param int $decimal
|
415 |
+
* @return string
|
416 |
+
*/
|
417 |
+
protected function decimalToRoman($decimal)
|
418 |
+
{
|
419 |
+
$roman = '';
|
420 |
+
$map = [
|
421 |
+
'M' => 1000,
|
422 |
+
'CM' => 900,
|
423 |
+
'D' => 500,
|
424 |
+
'CD' => 400,
|
425 |
+
'C' => 100,
|
426 |
+
'XC' => 90,
|
427 |
+
'L' => 50,
|
428 |
+
'XL' => 40,
|
429 |
+
'X' => 10,
|
430 |
+
'IX' => 9,
|
431 |
+
'V' => 5,
|
432 |
+
'IV' => 4,
|
433 |
+
'I' => 1
|
434 |
+
];
|
435 |
+
foreach ($map as $number => $value) {
|
436 |
+
$matches = intval($decimal / $value);
|
437 |
+
$roman .= str_repeat($number, $matches);
|
438 |
+
$decimal = $decimal % $value;
|
439 |
+
}
|
440 |
+
return $roman;
|
441 |
+
}
|
442 |
+
}
|
plugin/editorBlock/EditorBlock.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin\editorBlock;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
|
8 |
+
class EditorBlock extends BaseObject
|
9 |
+
{
|
10 |
+
|
11 |
+
public function init()
|
12 |
+
{
|
13 |
+
if (function_exists('register_block_type')) {
|
14 |
+
add_action('init', [$this, 'wpInit']);
|
15 |
+
add_action('admin_init', [$this, 'adminInit'], 21);
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
public function wpInit()
|
20 |
+
{
|
21 |
+
register_block_type('luckywp/tableofcontents', [
|
22 |
+
'editor_script' => 'lwptoc-editorBlock',
|
23 |
+
'render_callback' => function ($attrs) {
|
24 |
+
return Core::$plugin->shortcode->make($attrs);
|
25 |
+
},
|
26 |
+
]);
|
27 |
+
}
|
28 |
+
|
29 |
+
public function adminInit()
|
30 |
+
{
|
31 |
+
add_action('enqueue_block_editor_assets', [$this, 'blockEditorAssets']);
|
32 |
+
}
|
33 |
+
|
34 |
+
public function blockEditorAssets()
|
35 |
+
{
|
36 |
+
wp_register_script('lwptoc-editorBlock', $this->getUrl() . '/editorBlock.min.js', ['wp-blocks', 'wp-element', 'wp-editor', 'wp-components'], Core::$plugin->version);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @return string
|
41 |
+
*/
|
42 |
+
protected function getUrl()
|
43 |
+
{
|
44 |
+
return Core::$plugin->url . '/plugin/editorBlock';
|
45 |
+
}
|
46 |
+
}
|
plugin/editorBlock/editorBlock.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(t){var e={};function o(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,o),r.l=!0,r.exports}o.m=t,o.c=e,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)o.d(n,r,function(e){return t[e]}.bind(null,r));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=0)}([function(t,e){var o=wp.blocks.registerBlockType,n=wp.element,r=n.createElement,i=n.Fragment,l=wp.editor.BlockControls,c=wp.components,a=c.Toolbar,s=c.IconButton,p=0,u={};o("luckywp/tableofcontents",{title:lwptocMain.tableOfContents,icon:"list-view",category:"common",supports:{customClassName:!1,html:!1},attributes:{min:{type:"integer"},depth:{type:"integer"},hierarchical:{type:"boolean"},numeration:{type:"string"},title:{type:"string"},toggle:{type:"boolean"},labelShow:{type:"string"},labelHide:{type:"string"},hideItems:{type:"boolean"},smoothScroll:{type:"boolean"},smoothScrollOffset:{type:"integer"},width:{type:"string"},float:{type:"string"},titleFontSize:{type:"string"},titleFontWeight:{type:"string"},itemsFontSize:{type:"string"},colorScheme:{type:"string"},backgroundColor:{type:"string"},borderColor:{type:"string"},titleColor:{type:"string"},linkColor:{type:"string"},hoverLinkColor:{type:"string"},visitedLinkColor:{type:"string"}},edit:function(t){var e=t.attributes,o=t.setAttributes;var n="lwptocEditorBlock"+ ++p,c=JSON.stringify(e);return void 0===u[c]&&($.ajax({url:lwptocMain.ajaxUrl,data:{_ajax_nonce:lwptocMain.nonce,action:"lwptoc_block_view",attrs:e},success:function(t){u[c]=t,$("#"+n).replaceWith(t)}}),u[c]='<div class="lwptocEditorBlock_title lwptocEditorBlock_title-loading" id="'+n+'">'+lwptocMain.tableOfContents+"</div>"),r(i,null,r(l,null,r(a,null,r(s,{label:lwptocMain.Edit,icon:"edit",onClick:function(){$(document).one("lwptocEditorBlockChanged",function(t,e){_.each(e,function(t,o){null===t&&(e[o]=void 0)}),o(e)}),$.lwptocCustomize.show({action:"lwptoc_block_edit",attrs:e,postId:lwptocMain.postId},function(){$(document).off("lwptocEditorBlockChanged")})}}))),r("div",{class:"lwptocEditorBlock",dangerouslySetInnerHTML:{__html:u[c]}}))},save:function(t){return t.attributes.shortcode}})}]);
|
plugin/editorBlock/src/editorBlock.js
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const {
|
2 |
+
registerBlockType,
|
3 |
+
} = wp.blocks;
|
4 |
+
const {
|
5 |
+
createElement,
|
6 |
+
Fragment,
|
7 |
+
} = wp.element;
|
8 |
+
const {
|
9 |
+
BlockControls,
|
10 |
+
} = wp.editor;
|
11 |
+
const {
|
12 |
+
Toolbar,
|
13 |
+
IconButton,
|
14 |
+
} = wp.components;
|
15 |
+
|
16 |
+
let viewCounter = 0,
|
17 |
+
viewCache = {};
|
18 |
+
|
19 |
+
registerBlockType('luckywp/tableofcontents', {
|
20 |
+
title: lwptocMain.tableOfContents,
|
21 |
+
icon: 'list-view',
|
22 |
+
category: 'common',
|
23 |
+
supports: {
|
24 |
+
customClassName: false,
|
25 |
+
html: false,
|
26 |
+
},
|
27 |
+
attributes: {
|
28 |
+
min: {type: 'integer'},
|
29 |
+
depth: {type: 'integer'},
|
30 |
+
hierarchical: {type: 'boolean'},
|
31 |
+
numeration: {type: 'string'},
|
32 |
+
title: {type: 'string'},
|
33 |
+
toggle: {type: 'boolean'},
|
34 |
+
labelShow: {type: 'string'},
|
35 |
+
labelHide: {type: 'string'},
|
36 |
+
hideItems: {type: 'boolean'},
|
37 |
+
smoothScroll: {type: 'boolean'},
|
38 |
+
smoothScrollOffset: {type: 'integer'},
|
39 |
+
width: {type: 'string'},
|
40 |
+
float: {type: 'string'},
|
41 |
+
titleFontSize: {type: 'string'},
|
42 |
+
titleFontWeight: {type: 'string'},
|
43 |
+
itemsFontSize: {type: 'string'},
|
44 |
+
colorScheme: {type: 'string'},
|
45 |
+
backgroundColor: {type: 'string'},
|
46 |
+
borderColor: {type: 'string'},
|
47 |
+
titleColor: {type: 'string'},
|
48 |
+
linkColor: {type: 'string'},
|
49 |
+
hoverLinkColor: {type: 'string'},
|
50 |
+
visitedLinkColor: {type: 'string'},
|
51 |
+
},
|
52 |
+
edit: function({attributes, setAttributes}) {
|
53 |
+
function onEdit() {
|
54 |
+
$(document).one('lwptocEditorBlockChanged', function(e, data) {
|
55 |
+
_.each(data, function(el, idx) {
|
56 |
+
if (el === null) {
|
57 |
+
data[idx] = undefined;
|
58 |
+
}
|
59 |
+
});
|
60 |
+
setAttributes(data);
|
61 |
+
});
|
62 |
+
$.lwptocCustomize.show({
|
63 |
+
action: 'lwptoc_block_edit',
|
64 |
+
attrs: attributes,
|
65 |
+
postId: lwptocMain.postId,
|
66 |
+
}, function() {
|
67 |
+
$(document).off('lwptocEditorBlockChanged');
|
68 |
+
});
|
69 |
+
};
|
70 |
+
|
71 |
+
let id = 'lwptocEditorBlock' + (++viewCounter),
|
72 |
+
key = JSON.stringify(attributes);
|
73 |
+
if (typeof viewCache[key] === 'undefined') {
|
74 |
+
$.ajax({
|
75 |
+
url: lwptocMain.ajaxUrl,
|
76 |
+
data: {
|
77 |
+
_ajax_nonce: lwptocMain.nonce,
|
78 |
+
action: 'lwptoc_block_view',
|
79 |
+
attrs: attributes,
|
80 |
+
},
|
81 |
+
success: function(response) {
|
82 |
+
viewCache[key] = response;
|
83 |
+
$('#' + id).replaceWith(response);
|
84 |
+
},
|
85 |
+
});
|
86 |
+
viewCache[key] = '<div class="lwptocEditorBlock_title lwptocEditorBlock_title-loading" id="' + id + '">' + lwptocMain.tableOfContents + '</div>';
|
87 |
+
}
|
88 |
+
|
89 |
+
return <Fragment>
|
90 |
+
<BlockControls>
|
91 |
+
<Toolbar>
|
92 |
+
<IconButton
|
93 |
+
label={lwptocMain.Edit}
|
94 |
+
icon="edit"
|
95 |
+
onClick={onEdit}
|
96 |
+
/>
|
97 |
+
</Toolbar>
|
98 |
+
</BlockControls>
|
99 |
+
<div class="lwptocEditorBlock" dangerouslySetInnerHTML={{__html: viewCache[key]}}></div>
|
100 |
+
</Fragment>;
|
101 |
+
},
|
102 |
+
save: function(props) {
|
103 |
+
return props.attributes.shortcode;
|
104 |
+
},
|
105 |
+
});
|
plugin/mcePlugin/McePlugin.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace luckywp\tableOfContents\plugin\mcePlugin;
|
4 |
+
|
5 |
+
use luckywp\tableOfContents\core\base\BaseObject;
|
6 |
+
use luckywp\tableOfContents\core\Core;
|
7 |
+
|
8 |
+
class McePlugin extends BaseObject
|
9 |
+
{
|
10 |
+
|
11 |
+
public function init()
|
12 |
+
{
|
13 |
+
parent::init();
|
14 |
+
add_action('admin_init', [$this, 'adminInit'], 20);
|
15 |
+
}
|
16 |
+
|
17 |
+
public function adminInit()
|
18 |
+
{
|
19 |
+
if (current_user_can('edit_posts') || current_user_can('edit_pages')) {
|
20 |
+
add_filter('mce_css', [$this, 'css']);
|
21 |
+
add_filter('mce_external_plugins', [$this, 'plugin']);
|
22 |
+
add_filter('mce_buttons', [$this, 'button']);
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param string $css
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
public function css($css)
|
31 |
+
{
|
32 |
+
if (!empty($css)) {
|
33 |
+
$css .= ',';
|
34 |
+
}
|
35 |
+
$css .= $this->getUrl() . '/mce.min.css';
|
36 |
+
return $css;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param array $plugins
|
41 |
+
* @return array
|
42 |
+
*/
|
43 |
+
public function plugin($plugins)
|
44 |
+
{
|
45 |
+
$plugins['lwptoc'] = $this->getUrl() . '/plugin.min.js';
|
46 |
+
return $plugins;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param array $buttons
|
51 |
+
* @return array
|
52 |
+
*/
|
53 |
+
public function button($buttons)
|
54 |
+
{
|
55 |
+
array_push($buttons, 'lwptocButton');
|
56 |
+
return $buttons;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
protected function getUrl()
|
63 |
+
{
|
64 |
+
return Core::$plugin->url . '/plugin/mcePlugin';
|
65 |
+
}
|
66 |
+
}
|
plugin/mcePlugin/mce.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.lwptocShortcode{display:block;padding:12px 16px;border:2px dashed #ddd;background:#fff;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif}.lwptocShortcode-loading{color:#aaa}.lwptocShortcode_title{font-size:14px;line-height:18px;font-weight:700}.lwptocShortcode_items{margin-top:4px;font-size:12px;line-height:16px}.lwptocShortcode_item{margin-top:2px}.lwptocShortcode_item:first-child{margin-top:0}.lwptocShortcode_item_label{color:#888}.lwptocShortcode .lwptocColorBadge B{position:relative;top:1px;margin-left:2px;display:inline-block;margin-right:4px;width:12px;height:12px;border-radius:6px}
|
plugin/mcePlugin/plugin.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(n){lwptocMain.postId&&(tinymce.PluginManager.add("lwptoc",function(t){t.addButton("lwptocButton",{icon:"lwptocButton",tooltip:lwptocMain.tableOfContents,onclick:function(){wp.mce.lwptoc.popupWindow(t,!1,{})}})}),wp.mce.lwptoc={viewCounter:0,cache:{},getContent:function(){var t=this,c="lwptocShortcode"+ ++wp.mce.lwptoc.viewCounter,e=JSON.stringify(this.shortcode.attrs.named);return void 0===wp.mce.lwptoc[e]?(n.ajax({url:lwptocMain.ajaxUrl,data:{_ajax_nonce:lwptocMain.nonce,action:"lwptoc_shortcode_view",attrs:this.shortcode.attrs.named},success:function(o){wp.mce.lwptoc[e]=o,t.getEditors(function(t){n(t.getBody()).find("#"+c).replaceWith(o)})}}),'<div class="lwptocShortcode lwptocShortcode-loading" id="'+c+'"><div class="lwptocShortcode_title">'+lwptocMain.tableOfContents+"</div></div>"):wp.mce.lwptoc[e]},edit:function(t,o){wp.mce.lwptoc.popupWindow(tinyMCE.activeEditor,o,wp.shortcode.next("lwptoc",t).shortcode.attrs.named)},popupWindow:function(c,e,t){n(document).one("lwptocShortcodeGenerated",function(t,o){!1===e?c.insertContent(o.shortcode):e(o.shortcode)}),n.lwptocCustomize.show({action:"lwptoc_shortcode_customize",attrs:t,postId:lwptocMain.postId},function(){n(document).off("lwptocShortcodeGenerated")})}},wp.mce.views.register("lwptoc",wp.mce.lwptoc))}(jQuery);
|
readme.txt
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== LuckyWP Table of Contents ===
|
2 |
+
Contributors: theluckywp
|
3 |
+
Donate link: https://theluckywp.com/product/table-of-contents/
|
4 |
+
Tags: table of contents, toc, navigation, links, heading
|
5 |
+
Requires at least: 4.7
|
6 |
+
Tested up to: 5.0
|
7 |
+
Stable tag: 1.0.0
|
8 |
+
Requires PHP: 5.4.45
|
9 |
+
License: GPLv2 or later
|
10 |
+
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
11 |
+
|
12 |
+
Creates a table of contents for your posts/pages. Works automatically or manually (via shortcode or Gutenberg block).
|
13 |
+
|
14 |
+
== Description ==
|
15 |
+
|
16 |
+
Creates a table of contents for your posts, pages or custom post types. Great customizable appearance.
|
17 |
+
|
18 |
+
#### Features
|
19 |
+
|
20 |
+
* Automatical insertion a table of contents (configure post types and position).
|
21 |
+
* Insert by shortcode or Gutenberg block.
|
22 |
+
* Button on toolbar of the classic editor.
|
23 |
+
* Gutenberg block into "Common Blocks".
|
24 |
+
* Setting the minimum number of headings to display table of contents.
|
25 |
+
* Setting the depth of headings for table of contents.
|
26 |
+
* Hierarchical or linear view.
|
27 |
+
* Numeration items: decimal or roman numbers in order or nested.
|
28 |
+
* Customizable appearance: width, float, title font size and weight, items font size, colors.
|
29 |
+
* Color schemes (dark, light, white, transparent) and the ability to override colors.
|
30 |
+
* Toggle Show/Hide (optionally)
|
31 |
+
* Customizalbe labels.
|
32 |
+
* Smooth scroll (optionally).
|
33 |
+
* Setting offset top for smooth scroll.
|
34 |
+
* Available override global settings for a particular post.
|
35 |
+
* Highly compatible with WordPress themes and plugins.
|
36 |
+
|
37 |
+
#### Auto Insert
|
38 |
+
|
39 |
+
For automatical insertion a table of contents in a posts, select option "Auto Insert Table of Contents" in the plugin settings (tab "Auto Insert").
|
40 |
+
|
41 |
+
Supported positions:
|
42 |
+
|
43 |
+
* before first heading;
|
44 |
+
* after first heading;
|
45 |
+
* after first block (paragraph, list or heading);
|
46 |
+
* top of post content;
|
47 |
+
* bottom of post content.
|
48 |
+
|
49 |
+
You can also select post types to which the table of contents will be automatically added.
|
50 |
+
|
51 |
+
== Installation ==
|
52 |
+
|
53 |
+
#### Installing from the WordPress control panel
|
54 |
+
|
55 |
+
1. Go to the page "Plugins > Add New".
|
56 |
+
2. Input the name "LuckyWP Table of Contents" in the search field
|
57 |
+
3. Find the "LuckyWP Table of Contents" plugin in the search result and click on the "Install Now" button, the installation process of plugin will begin.
|
58 |
+
4. Click "Activate" when the installation is complete.
|
59 |
+
|
60 |
+
#### Installing with the archive
|
61 |
+
|
62 |
+
1. Go to the page "Plugins > Add New" on the WordPress control panel
|
63 |
+
2. Click on the "Upload Plugin" button, the form to upload the archive will be opened.
|
64 |
+
3. Select the archive with the plugin and click "Install Now".
|
65 |
+
4. Click on the "Activate Plugin" button when the installation is complete.
|
66 |
+
|
67 |
+
#### Manual installation
|
68 |
+
|
69 |
+
1. Upload the folder `luckywp-table-of-contents` to a directory with the plugin, usually it is `/wp-content/plugins/`.
|
70 |
+
2. Go to the page "Plugins > Add New" on the WordPress control panel
|
71 |
+
3. Find "LuckyWP Table of Contents" in the plugins list and click "Activate".
|
72 |
+
|
73 |
+
### After activation
|
74 |
+
|
75 |
+
Into classic editor will appear button "Table of Contents" (available on edit post/page screen).
|
76 |
+
Into Gutenberg editor will appear block "Table of Contents" (see "Common Blocks").
|
77 |
+
The menu item "Table of Contents" will appear in the menu "Settings" of the WordPress control panel.
|
78 |
+
|
79 |
+
== Screenshots ==
|
80 |
+
|
81 |
+
1. Table of Contents
|
82 |
+
2. Gutenberg Support
|
83 |
+
3. Classic Editor Support
|
84 |
+
4. Customize Window
|
85 |
+
5. Examples of Color Solutions
|
86 |
+
6. General Settings
|
87 |
+
7. Appearance Settings
|
88 |
+
8. Auto Insert Settings
|
uninstall.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!defined('WP_UNINSTALL_PLUGIN')) {
|
4 |
+
die;
|
5 |
+
}
|
6 |
+
|
7 |
+
delete_option('lwptoc_general');
|
8 |
+
delete_option('lwptoc_appearance');
|
9 |
+
delete_option('lwptoc_autoInsert');
|