Version Description
(2014-07-16) = * Initial public release on WordPress.org * Add an option to display a link to a booking form if the Restaurant Reservations plugin is active * Fix: skip a scheduling rule if no weekdays are set. h/t @jasonhobbsllc
Download this release
Release Info
Developer | NateWr |
Plugin | Business Profile |
Version | 1.0 |
Comparing to | |
See all releases |
Version 1.0
- GPL.txt +280 -0
- assets/css/contact-card.css +110 -0
- assets/js/map.js +62 -0
- business-profile.php +117 -0
- docs/index.html +141 -0
- docs/style.css +31 -0
- includes/Integrations.php +140 -0
- includes/Settings.class.php +255 -0
- includes/WP_Widget.ContactCardWidget.class.php +104 -0
- includes/template-functions.php +455 -0
- lib/simple-admin-pages/README.md +396 -0
- lib/simple-admin-pages/classes/AdminPage.Menu.class.php +32 -0
- lib/simple-admin-pages/classes/AdminPage.Submenu.class.php +38 -0
- lib/simple-admin-pages/classes/AdminPage.Themes.class.php +15 -0
- lib/simple-admin-pages/classes/AdminPage.class.php +215 -0
- lib/simple-admin-pages/classes/AdminPageSection.class.php +132 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php +138 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php +44 -0
- lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php +33 -0
- lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php +180 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php +664 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php +60 -0
- lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php +61 -0
- lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php +66 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php +35 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php +56 -0
- lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php +43 -0
- lib/simple-admin-pages/classes/AdminPageSetting.class.php +261 -0
- lib/simple-admin-pages/classes/Library.class.php +415 -0
- lib/simple-admin-pages/css/admin.css +225 -0
- lib/simple-admin-pages/js/address.js +96 -0
- lib/simple-admin-pages/js/opening-hours.js +20 -0
- lib/simple-admin-pages/js/scheduler.js +329 -0
- lib/simple-admin-pages/lib/pickadate/legacy.js +10 -0
- lib/simple-admin-pages/lib/pickadate/picker.date.js +5 -0
- lib/simple-admin-pages/lib/pickadate/picker.js +7 -0
- lib/simple-admin-pages/lib/pickadate/picker.time.js +5 -0
- lib/simple-admin-pages/lib/pickadate/themes/default.css +4 -0
- lib/simple-admin-pages/lib/pickadate/themes/default.date.css +1 -0
- lib/simple-admin-pages/lib/pickadate/themes/default.time.css +1 -0
- lib/simple-admin-pages/lib/pickadate/themes/rtl.css +3 -0
- lib/simple-admin-pages/lib/pickadate/translations/ar.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/bg_BG.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/bs_BA.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/ca_ES.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/cs_CZ.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/da_DK.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/de_DE.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/el_GR.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/es_ES.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/et_EE.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/eu_ES.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/fi_FI.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/fr_FR.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/gl_ES.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/he_IL.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/hr_HR.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/hu_HU.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/id_ID.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/is_IS.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/it_IT.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/ja_JP.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/ko_KR.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/nl_NL.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/no_NO.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/pl_PL.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/pt_BR.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/pt_PT.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/ro_RO.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/ru_RU.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/sk_SK.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/sl_SI.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/sv_SE.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/th_TH.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/tr_TR.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/uk_UA.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/zh_CN.js +1 -0
- lib/simple-admin-pages/lib/pickadate/translations/zh_TW.js +1 -0
- lib/simple-admin-pages/simple-admin-pages.php +57 -0
- readme.txt +66 -0
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
- screenshot-3.png +0 -0
GPL.txt
ADDED
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
+
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
6 |
+
|
7 |
+
Everyone is permitted to copy and distribute verbatim copies
|
8 |
+
of this license document, but changing it is not allowed.
|
9 |
+
|
10 |
+
Preamble
|
11 |
+
|
12 |
+
The licenses for most software are designed to take away your
|
13 |
+
freedom to share and change it. By contrast, the GNU General Public
|
14 |
+
License is intended to guarantee your freedom to share and change free
|
15 |
+
software--to make sure the software is free for all its users. This
|
16 |
+
General Public License applies to most of the Free Software
|
17 |
+
Foundation's software and to any other program whose authors commit to
|
18 |
+
using it. (Some other Free Software Foundation software is covered by
|
19 |
+
the GNU Library General Public License instead.) You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
this service if you wish), that you receive source code or can get it
|
26 |
+
if you want it, that you can change the software or use pieces of it
|
27 |
+
in new free programs; and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to make restrictions that forbid
|
30 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
31 |
+
These restrictions translate to certain responsibilities for you if you
|
32 |
+
distribute copies of the software, or if you modify it.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must give the recipients all the rights that
|
36 |
+
you have. You must make sure that they, too, receive or can get the
|
37 |
+
source code. And you must show them these terms so they know their
|
38 |
+
rights.
|
39 |
+
|
40 |
+
We protect your rights with two steps: (1) copyright the software, and
|
41 |
+
(2) offer you this license which gives you legal permission to copy,
|
42 |
+
distribute and/or modify the software.
|
43 |
+
|
44 |
+
Also, for each author's protection and ours, we want to make certain
|
45 |
+
that everyone understands that there is no warranty for this free
|
46 |
+
software. If the software is modified by someone else and passed on, we
|
47 |
+
want its recipients to know that what they have is not the original, so
|
48 |
+
that any problems introduced by others will not reflect on the original
|
49 |
+
authors' reputations.
|
50 |
+
|
51 |
+
Finally, any free program is threatened constantly by software
|
52 |
+
patents. We wish to avoid the danger that redistributors of a free
|
53 |
+
program will individually obtain patent licenses, in effect making the
|
54 |
+
program proprietary. To prevent this, we have made it clear that any
|
55 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
56 |
+
|
57 |
+
The precise terms and conditions for copying, distribution and
|
58 |
+
modification follow.
|
59 |
+
|
60 |
+
GNU GENERAL PUBLIC LICENSE
|
61 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
62 |
+
|
63 |
+
0. This License applies to any program or other work which contains
|
64 |
+
a notice placed by the copyright holder saying it may be distributed
|
65 |
+
under the terms of this General Public License. The "Program", below,
|
66 |
+
refers to any such program or work, and a "work based on the Program"
|
67 |
+
means either the Program or any derivative work under copyright law:
|
68 |
+
that is to say, a work containing the Program or a portion of it,
|
69 |
+
either verbatim or with modifications and/or translated into another
|
70 |
+
language. (Hereinafter, translation is included without limitation in
|
71 |
+
the term "modification".) Each licensee is addressed as "you".
|
72 |
+
|
73 |
+
Activities other than copying, distribution and modification are not
|
74 |
+
covered by this License; they are outside its scope. The act of
|
75 |
+
running the Program is not restricted, and the output from the Program
|
76 |
+
is covered only if its contents constitute a work based on the
|
77 |
+
Program (independent of having been made by running the Program).
|
78 |
+
Whether that is true depends on what the Program does.
|
79 |
+
|
80 |
+
1. You may copy and distribute verbatim copies of the Program's
|
81 |
+
source code as you receive it, in any medium, provided that you
|
82 |
+
conspicuously and appropriately publish on each copy an appropriate
|
83 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
84 |
+
notices that refer to this License and to the absence of any warranty;
|
85 |
+
and give any other recipients of the Program a copy of this License
|
86 |
+
along with the Program.
|
87 |
+
|
88 |
+
You may charge a fee for the physical act of transferring a copy, and
|
89 |
+
you may at your option offer warranty protection in exchange for a fee.
|
90 |
+
|
91 |
+
2. You may modify your copy or copies of the Program or any portion
|
92 |
+
of it, thus forming a work based on the Program, and copy and
|
93 |
+
distribute such modifications or work under the terms of Section 1
|
94 |
+
above, provided that you also meet all of these conditions:
|
95 |
+
|
96 |
+
a) You must cause the modified files to carry prominent notices
|
97 |
+
stating that you changed the files and the date of any change.
|
98 |
+
|
99 |
+
b) You must cause any work that you distribute or publish, that in
|
100 |
+
whole or in part contains or is derived from the Program or any
|
101 |
+
part thereof, to be licensed as a whole at no charge to all third
|
102 |
+
parties under the terms of this License.
|
103 |
+
|
104 |
+
c) If the modified program normally reads commands interactively
|
105 |
+
when run, you must cause it, when started running for such
|
106 |
+
interactive use in the most ordinary way, to print or display an
|
107 |
+
announcement including an appropriate copyright notice and a
|
108 |
+
notice that there is no warranty (or else, saying that you provide
|
109 |
+
a warranty) and that users may redistribute the program under
|
110 |
+
these conditions, and telling the user how to view a copy of this
|
111 |
+
License. (Exception: if the Program itself is interactive but
|
112 |
+
does not normally print such an announcement, your work based on
|
113 |
+
the Program is not required to print an announcement.)
|
114 |
+
|
115 |
+
These requirements apply to the modified work as a whole. If
|
116 |
+
identifiable sections of that work are not derived from the Program,
|
117 |
+
and can be reasonably considered independent and separate works in
|
118 |
+
themselves, then this License, and its terms, do not apply to those
|
119 |
+
sections when you distribute them as separate works. But when you
|
120 |
+
distribute the same sections as part of a whole which is a work based
|
121 |
+
on the Program, the distribution of the whole must be on the terms of
|
122 |
+
this License, whose permissions for other licensees extend to the
|
123 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
assets/css/contact-card.css
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Frontend CSS Stylesheet for Business Profile contact cards */
|
2 |
+
|
3 |
+
.bp-contact-card {
|
4 |
+
font-style: normal;
|
5 |
+
}
|
6 |
+
.bp-contact-card>div {
|
7 |
+
margin: 1em 0;
|
8 |
+
}
|
9 |
+
.bp-name {
|
10 |
+
font-weight: bold;
|
11 |
+
}
|
12 |
+
.bp-opening-hours {
|
13 |
+
max-width: 25em;
|
14 |
+
}
|
15 |
+
.bp-opening-hours .bp-title {
|
16 |
+
text-align: center;
|
17 |
+
display: block;
|
18 |
+
}
|
19 |
+
.bp-weekday:before,
|
20 |
+
.bp-weekday:after {
|
21 |
+
content: " ";
|
22 |
+
display: table;
|
23 |
+
}
|
24 |
+
.bp-weekday:after {
|
25 |
+
clear: both;
|
26 |
+
}
|
27 |
+
.bp-weekday-name {
|
28 |
+
float: left;
|
29 |
+
clear: left;
|
30 |
+
width: 45%;
|
31 |
+
}
|
32 |
+
.bp-times {
|
33 |
+
float: right;
|
34 |
+
clear: right;
|
35 |
+
width: 45%;
|
36 |
+
text-align: right;
|
37 |
+
}
|
38 |
+
.bp-times .bp-time {
|
39 |
+
display: block;
|
40 |
+
}
|
41 |
+
.bp-map {
|
42 |
+
height: 20em;
|
43 |
+
color: #333;
|
44 |
+
font-weight: 400;
|
45 |
+
}
|
46 |
+
.bp-map a {
|
47 |
+
color: #3a84df;
|
48 |
+
}
|
49 |
+
.bp-map a:hover {
|
50 |
+
text-decoration: underline;
|
51 |
+
}
|
52 |
+
|
53 |
+
.bp-map p {
|
54 |
+
margin: 4px;
|
55 |
+
line-height: 16px;
|
56 |
+
font-weight: 400;
|
57 |
+
}
|
58 |
+
|
59 |
+
.bp-map img {
|
60 |
+
max-width: none; /* Fixes Google Maps info window close button */
|
61 |
+
}
|
62 |
+
|
63 |
+
.bp-map-info-window {
|
64 |
+
width: 200px;
|
65 |
+
max-width: 100%;
|
66 |
+
}
|
67 |
+
|
68 |
+
.bp-directions:before,
|
69 |
+
.bp-phone:before,
|
70 |
+
.bp-contact:before,
|
71 |
+
.bp-booking:before,
|
72 |
+
.bp-opening-hours-brief:before,
|
73 |
+
.bp-opening-hours .bp-title:before {
|
74 |
+
display: inline-block;
|
75 |
+
width: 1.5em;
|
76 |
+
height: 1em;
|
77 |
+
font-size: 1.5em;
|
78 |
+
line-height: 1;
|
79 |
+
font-family: dashicons;
|
80 |
+
text-decoration: inherit;
|
81 |
+
font-weight: 400;
|
82 |
+
font-style: normal;
|
83 |
+
vertical-align: top;
|
84 |
+
text-align: center;
|
85 |
+
-webkit-transition: color .1s ease-in 0;
|
86 |
+
transition: color .1s ease-in 0;
|
87 |
+
-webkit-font-smoothing: antialiased;
|
88 |
+
-moz-osx-font-smoothing: grayscale;
|
89 |
+
}
|
90 |
+
|
91 |
+
.bp-directions:before {
|
92 |
+
content: "\f230";
|
93 |
+
}
|
94 |
+
|
95 |
+
.bp-phone:before {
|
96 |
+
content: "\f470";
|
97 |
+
}
|
98 |
+
|
99 |
+
.bp-contact:before {
|
100 |
+
content: "\f466";
|
101 |
+
}
|
102 |
+
|
103 |
+
.bp-booking:before {
|
104 |
+
content: "\f145";
|
105 |
+
}
|
106 |
+
|
107 |
+
.bp-opening-hours-brief:before,
|
108 |
+
.bp-opening-hours .bp-title:before {
|
109 |
+
content: "\f469";
|
110 |
+
}
|
assets/js/map.js
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Frontend Javascript for Business Profile maps */
|
2 |
+
jQuery(document).ready(function ($) {
|
3 |
+
|
4 |
+
// Load Google Maps API and initialize maps
|
5 |
+
var bp_map_script = document.createElement( 'script' );
|
6 |
+
bp_map_script.type = 'text/javascript';
|
7 |
+
bp_map_script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=bp_initialize_map';
|
8 |
+
document.body.appendChild( bp_map_script );
|
9 |
+
|
10 |
+
});
|
11 |
+
|
12 |
+
function bp_initialize_map() {
|
13 |
+
|
14 |
+
var bp_maps = [];
|
15 |
+
var bp_info_windows = [];
|
16 |
+
|
17 |
+
jQuery( '.bp-map' ).each( function() {
|
18 |
+
var id = jQuery(this).attr( 'id' );
|
19 |
+
var data = jQuery(this).data();
|
20 |
+
|
21 |
+
// Google Maps API v3
|
22 |
+
if ( typeof data.lat !== 'undefined' ) {
|
23 |
+
var latlon = new google.maps.LatLng( data.lat, data.lon );
|
24 |
+
var bp_map_options = {
|
25 |
+
zoom: 15,
|
26 |
+
center: latlon,
|
27 |
+
};
|
28 |
+
|
29 |
+
bp_maps[ id ] = new google.maps.Map( document.getElementById( id ), bp_map_options );
|
30 |
+
|
31 |
+
var content = '<div class="bp-map-info-window">' +
|
32 |
+
'<p><strong>' + data.name + '</strong></p>' +
|
33 |
+
'<p>' + data.address + '</p>';
|
34 |
+
|
35 |
+
if ( typeof data.phone !== 'undefined' ) {
|
36 |
+
content += '<p>' + data.phone + '</p>';
|
37 |
+
}
|
38 |
+
content += '<p><a target="_blank" href="//maps.google.com/maps?saddr=current+location&daddr=' + encodeURIComponent( data.address ) + '">Get Directions</a></p>' +
|
39 |
+
'</div>';
|
40 |
+
|
41 |
+
bp_info_windows[ id ] = new google.maps.InfoWindow({
|
42 |
+
position: latlon,
|
43 |
+
content: content,
|
44 |
+
});
|
45 |
+
bp_info_windows[ id ].open( bp_maps[ id ]);
|
46 |
+
|
47 |
+
// Google Maps iframe embed (fallback if no lat/lon data available)
|
48 |
+
} else if ( typeof data.address !== '' ) {
|
49 |
+
var bp_map_iframe = document.createElement( 'iframe' );
|
50 |
+
bp_map_iframe.frameBorder = 0;
|
51 |
+
bp_map_iframe.style.width = '100%';
|
52 |
+
bp_map_iframe.style.height = '100%';
|
53 |
+
|
54 |
+
if ( typeof data.name !== '' ) {
|
55 |
+
data.address = data.name + ',' + data.address;
|
56 |
+
}
|
57 |
+
bp_map_iframe.src = '//maps.google.com/maps?output=embed&q=' + encodeURIComponent( data.address );
|
58 |
+
|
59 |
+
jQuery(this).html( bp_map_iframe );
|
60 |
+
}
|
61 |
+
});
|
62 |
+
}
|
business-profile.php
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Business Profile
|
4 |
+
* Plugin URI: http://themeofthecrop.com
|
5 |
+
* Description: Contact information, Google Maps and opening hours made easy for businesses.
|
6 |
+
* Version: 1.0
|
7 |
+
* Author: Theme of the Crop
|
8 |
+
* Author URI: http://themeofthecrop.com
|
9 |
+
* License: GNU General Public License v2.0 or later
|
10 |
+
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
+
*
|
12 |
+
* Text Domain: bpfwpdomain
|
13 |
+
* Domain Path: /languages/
|
14 |
+
*
|
15 |
+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
16 |
+
* General Public License as published by the Free Software Foundation; either version 2 of the License,
|
17 |
+
* or (at your option) any later version.
|
18 |
+
*
|
19 |
+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
20 |
+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
21 |
+
*
|
22 |
+
* You should have received a copy of the GNU General Public License along with this program; if not, write
|
23 |
+
* to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
24 |
+
*/
|
25 |
+
if ( ! defined( 'ABSPATH' ) )
|
26 |
+
exit;
|
27 |
+
|
28 |
+
if ( !class_exists( 'bpfwpInit' ) ) {
|
29 |
+
class bpfwpInit {
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Settings for displaying the contact card currently being handled
|
33 |
+
* @since 0.0.1
|
34 |
+
*/
|
35 |
+
public $display_settings = array();
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Initialize the plugin and register hooks
|
39 |
+
*/
|
40 |
+
public function __construct() {
|
41 |
+
|
42 |
+
// Common strings
|
43 |
+
define( 'BPFWP_TEXTDOMAIN', 'bpfwpdomain' );
|
44 |
+
define( 'BPFWP_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
|
45 |
+
define( 'BPFWP_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
|
46 |
+
define( 'BPFWP_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
|
47 |
+
define( 'BPFWP_VERSION', 1 );
|
48 |
+
|
49 |
+
// Load the textdomain
|
50 |
+
add_action( 'init', array( $this, 'load_textdomain' ) );
|
51 |
+
|
52 |
+
// Load settings
|
53 |
+
require_once( BPFWP_PLUGIN_DIR . '/includes/Settings.class.php' );
|
54 |
+
$this->settings = new bpfwpSettings();
|
55 |
+
|
56 |
+
// Load the template functions which print the contact cards
|
57 |
+
require_once( BPFWP_PLUGIN_DIR . '/includes/template-functions.php' );
|
58 |
+
|
59 |
+
// Load integrations with third-party plugins/apps
|
60 |
+
require_once( BPFWP_PLUGIN_DIR . '/includes/integrations.php' );
|
61 |
+
|
62 |
+
// Load assets
|
63 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
|
64 |
+
|
65 |
+
// Register the widget
|
66 |
+
add_action( 'widgets_init', array( $this, 'register_widgets' ) );
|
67 |
+
|
68 |
+
// Add links to plugin listing
|
69 |
+
add_filter('plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2);
|
70 |
+
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Load the plugin textdomain for localistion
|
75 |
+
* @since 0.0.1
|
76 |
+
*/
|
77 |
+
public function load_textdomain() {
|
78 |
+
load_plugin_textdomain( BPFWP_TEXTDOMAIN, false, plugin_basename( dirname( __FILE__ ) ) . "/languages" );
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Register the front-end CSS styles
|
83 |
+
* @since 0.0.1
|
84 |
+
*/
|
85 |
+
function register_assets() {
|
86 |
+
wp_register_style( 'bpfwp-default', BPFWP_PLUGIN_URL . '/assets/css/contact-card.css' );
|
87 |
+
wp_register_script( 'bpfwp-map', BPFWP_PLUGIN_URL . '/assets/js/map.js' );
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Register the widgets
|
92 |
+
* @since 0.0.1
|
93 |
+
*/
|
94 |
+
public function register_widgets() {
|
95 |
+
require_once( BPFWP_PLUGIN_DIR . '/includes/WP_Widget.ContactCardWidget.class.php' );
|
96 |
+
register_widget( 'bpfwpContactCardWidget' );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Add links to the plugin listing on the installed plugins page
|
101 |
+
* @since 0.0.1
|
102 |
+
*/
|
103 |
+
public function plugin_action_links( $links, $plugin ) {
|
104 |
+
|
105 |
+
if ( $plugin == BPFWP_PLUGIN_FNAME ) {
|
106 |
+
|
107 |
+
$links['help'] = '<a href="' . BPFWP_PLUGIN_URL . '/docs" title="' . __( 'View the help documentation for Business Profile', BPFWP_TEXTDOMAIN ) . '">' . __( 'Help', BPFWP_TEXTDOMAIN ) . '</a>';
|
108 |
+
}
|
109 |
+
|
110 |
+
return $links;
|
111 |
+
|
112 |
+
}
|
113 |
+
|
114 |
+
}
|
115 |
+
} // endif;
|
116 |
+
|
117 |
+
$bpfwp_controller = new bpfwpInit();
|
docs/index.html
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en-US">
|
3 |
+
<head>
|
4 |
+
|
5 |
+
<meta charset="UTF-8">
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
+
<title>Business Profile | How to install and use this plugin</title>
|
8 |
+
<link rel="profile" href="http://gmpg.org/xfn/11">
|
9 |
+
<meta name="robots" content="noindex,nofollow">
|
10 |
+
<link rel="stylesheet" href="style.css" type="text/css" media="all" />
|
11 |
+
|
12 |
+
</head>
|
13 |
+
|
14 |
+
<body>
|
15 |
+
|
16 |
+
<div id="toc">
|
17 |
+
<ul>
|
18 |
+
<li>
|
19 |
+
<a href="#install">Installation</a>
|
20 |
+
</li>
|
21 |
+
<li>
|
22 |
+
<a href="#setup">Quick Setup</a>
|
23 |
+
</li>
|
24 |
+
<li>
|
25 |
+
<a href="#shortcode">Shortcode</a>
|
26 |
+
</li>
|
27 |
+
<li>
|
28 |
+
<a href="#extend">Extend this plugin</a>
|
29 |
+
</li>
|
30 |
+
</ul>
|
31 |
+
</div>
|
32 |
+
|
33 |
+
<div id="content">
|
34 |
+
|
35 |
+
<h1>Guide to the Business Profile plugin for WordPress</h1>
|
36 |
+
<p>This guide will help you install and configure the plugin for your site.</p>
|
37 |
+
<p>Further support for this plugin can be found at <a href="http://themeofthecrop.com/?utm_source=Plugin&utm_medium=Plugin%20Help%20Documentation&utm_campaign=Business%Profile">themeofthecrop.com</a>.</p>
|
38 |
+
|
39 |
+
<a name="install"></a>
|
40 |
+
<h2>Installation</h2>
|
41 |
+
<p>The following steps describe how to upload the Business Profile plugin to an
|
42 |
+
existing WordPress installation. If you have not yet installed WordPress, consult the
|
43 |
+
<a href="http://codex.wordpress.org/Installing_WordPress">WordPress
|
44 |
+
documentation</a> for more information.</p>
|
45 |
+
<ol>
|
46 |
+
<li>
|
47 |
+
Unpack the business-profile.zip file. It should create a folder
|
48 |
+
named <code>/business-profile/</code>.
|
49 |
+
</li>
|
50 |
+
<li>
|
51 |
+
Upload the <code>/business-profile/</code> folder to your
|
52 |
+
WordPress plugin directory at <code>/wp-content/plugins/</code>.
|
53 |
+
</li>
|
54 |
+
<li>
|
55 |
+
Go to your WordPress admin dashboard at yoursite.com/wp-admin and
|
56 |
+
click the <strong>Plugins</strong> item in the menu on the left.
|
57 |
+
</li>
|
58 |
+
<li>
|
59 |
+
Find <strong>Business Profile</strong> in the list of Plugins
|
60 |
+
and click the <strong>Activate</strong> link below the plugin name.
|
61 |
+
</li>
|
62 |
+
</ol>
|
63 |
+
<p>The plugin is now active. Next you'll need to get it setup.</p>
|
64 |
+
|
65 |
+
<a name="setup"></a>
|
66 |
+
<h2>Quick Setup</h2>
|
67 |
+
<p>To get this plugin working as quickly as possible, all you need to do is
|
68 |
+
fill out your business details and add the widget</p>
|
69 |
+
<ol>
|
70 |
+
<li>
|
71 |
+
Go to the <strong>Business Profile</strong> page in your admin
|
72 |
+
dashboard. It should appear near the bottom of the menu on the left.
|
73 |
+
</li>
|
74 |
+
<li>
|
75 |
+
Fill out your business details on this page and click the Save
|
76 |
+
button at the bottom.
|
77 |
+
</li>
|
78 |
+
<li>
|
79 |
+
Simply paste <code>[contact-card]</code> into the content of any
|
80 |
+
page or post. Or add the new Contact Card widget to any sidebar.
|
81 |
+
</li>
|
82 |
+
</ol>
|
83 |
+
<p>Once you've done that, your users can view your business details. Read
|
84 |
+
the <a href="#shortcode">Shortcode</a> section to learn about customizing
|
85 |
+
what details are displayed.</p>
|
86 |
+
|
87 |
+
<a name="shortcode"></a>
|
88 |
+
<h2>Shortcode</h2>
|
89 |
+
<p>Prints the contact details to your site. All details will be displayed with the default shortcode <code>[contact-card]</code>. To hide any of the components, set the attribute to 0.</p>
|
90 |
+
<p><code>[contact-card show_name=1 show_address=1 show_get_directions=1 show_phone=1 show_contact=1 show_opening_hours=1 show_opening_hours_brief=0 show_map=1]</code></p>
|
91 |
+
<ul>
|
92 |
+
<li>
|
93 |
+
<strong>show_name</strong><br>
|
94 |
+
Whether or not to show the name of the business.
|
95 |
+
</li>
|
96 |
+
<li>
|
97 |
+
<strong>show_address</strong><br>
|
98 |
+
Whether or not to show the address.
|
99 |
+
</li>
|
100 |
+
<li>
|
101 |
+
<strong>show_get_directions</strong><br>
|
102 |
+
Whether or not to show a link to Google Maps with directions from the user's current location to your address.
|
103 |
+
</li>
|
104 |
+
<li>
|
105 |
+
<strong>show_phone</strong><br>
|
106 |
+
Whether or not to show your phone number.
|
107 |
+
</li>
|
108 |
+
<li>
|
109 |
+
<strong>show_contact</strong><br>
|
110 |
+
Whether or not to show a link to your contact page if set. Otherwise it will show the email address if one has been added to the Business Profile settings page.
|
111 |
+
</li>
|
112 |
+
<li>
|
113 |
+
<strong>show_opening_hours</strong><br>
|
114 |
+
Whether or not to show your opening hours.
|
115 |
+
</li>
|
116 |
+
<li>
|
117 |
+
<strong>show_opening_hours_brief</strong><br>
|
118 |
+
Whether or not to show a short, one-line version of your opening hours. This is turned off by default. Set it to 1 to turn it on.
|
119 |
+
</li>
|
120 |
+
<li>
|
121 |
+
<strong>show_map</strong><br>
|
122 |
+
Whether or not to show a Google Map with your location.
|
123 |
+
</li>
|
124 |
+
</ul>
|
125 |
+
|
126 |
+
<a name="extend"></a>
|
127 |
+
<h2>Extend this plugin</h2>
|
128 |
+
<p>This plugin has been designed from the ground up to be extensible and
|
129 |
+
customizable. There are several hooks to allow you to customize the
|
130 |
+
functionality and output.</p>
|
131 |
+
<p>If you have any questions, please
|
132 |
+
<a href="http://themeofthecrop.com/about/support/?utm_source=Plugin&utm_medium=Plugin%20Help%20Documentation&utm_campaign=Business%Profile">contact me</a>.</p>
|
133 |
+
<p>This plugin is available on
|
134 |
+
<a href="https://github.com/NateWr/business-profile">GitHub</a>
|
135 |
+
if you would like to contribute pull requests.</p>
|
136 |
+
|
137 |
+
</div>
|
138 |
+
|
139 |
+
</body>
|
140 |
+
|
141 |
+
</html>
|
docs/style.css
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Documentation Markup
|
3 |
+
**********************/
|
4 |
+
body {
|
5 |
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
6 |
+
background-color: #eee;
|
7 |
+
margin: 0;
|
8 |
+
}
|
9 |
+
li {
|
10 |
+
padding-bottom: 5px;
|
11 |
+
}
|
12 |
+
#toc {
|
13 |
+
position: absolute;
|
14 |
+
width: 250px;
|
15 |
+
}
|
16 |
+
#content {
|
17 |
+
padding: 20px;
|
18 |
+
margin-left: 300px;
|
19 |
+
background-color: #fff;
|
20 |
+
box-shadow: 0 0 5px #000;
|
21 |
+
}
|
22 |
+
#toc>ul>li {
|
23 |
+
padding-bottom: 10px;
|
24 |
+
padding-top: 10px;
|
25 |
+
}
|
26 |
+
code {
|
27 |
+
font-family: Courier, monospace;
|
28 |
+
padding: 2px 5px;
|
29 |
+
background-color: #eee;
|
30 |
+
border-radius: 2px;
|
31 |
+
}
|
includes/Integrations.php
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Initialize third-party integrations
|
4 |
+
*
|
5 |
+
* This file loads and runs code to help the theme that can be found in
|
6 |
+
* wp-content/themes/plate-up/includes. This code is separated from the normal
|
7 |
+
* functions.php file to make that file easier to read. Ideally, all code that
|
8 |
+
* is typically customized by users will be accessible through functions.php.
|
9 |
+
* The code that is loaded here should only pertain to more advanced features
|
10 |
+
* and functions that few users will ever touch if they are using this theme.
|
11 |
+
*/
|
12 |
+
if ( ! defined( 'ABSPATH' ) )
|
13 |
+
exit;
|
14 |
+
|
15 |
+
if ( !class_exists( 'bpfwpIntegrations' ) ) {
|
16 |
+
class bpfwpIntegrations {
|
17 |
+
|
18 |
+
public function __construct() {
|
19 |
+
|
20 |
+
add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
|
21 |
+
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Integrations run after the plugins are loaded
|
26 |
+
* @since 0.0.1
|
27 |
+
*/
|
28 |
+
public function plugins_loaded() {
|
29 |
+
|
30 |
+
// Restaurant Reservations plugin
|
31 |
+
if ( defined( 'RTB_PLUGIN_DIR' ) ) {
|
32 |
+
|
33 |
+
// Add default setting for booking link to template function/shortcode
|
34 |
+
add_filter( 'bpwfp_contact_card_defaults', array( $this, 'bpwfp_booking_link_default' ) );
|
35 |
+
|
36 |
+
// Add the callback to print the booking link
|
37 |
+
add_filter( 'bpwfwp_component_callbacks', array( $this, 'bpwfp_booking_link_callback' ) );
|
38 |
+
|
39 |
+
// Add display toggle for the booking link to the widget options
|
40 |
+
add_filter( 'bpfwp_widget_display_toggles', array( $this, 'bpfwp_booking_link_widget_option' ) );
|
41 |
+
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Add default setting for booking link to template function/shortcode
|
47 |
+
* Restaurant Reservations plugin
|
48 |
+
* @since 0.0.1
|
49 |
+
*/
|
50 |
+
public function bpwfp_booking_link_default( $defaults ) {
|
51 |
+
|
52 |
+
$defaults['show_booking_link'] = true;
|
53 |
+
|
54 |
+
return $defaults;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Add the callback to print the booking link
|
59 |
+
* Restaurant Reservations plugin
|
60 |
+
* @since 0.0.1
|
61 |
+
*/
|
62 |
+
public function bpwfp_booking_link_callback( $data ) {
|
63 |
+
|
64 |
+
global $rtb_controller;
|
65 |
+
$booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
|
66 |
+
|
67 |
+
if ( !empty( $booking_page ) ) {
|
68 |
+
|
69 |
+
// Place the link at the end of other short links if they're
|
70 |
+
// displayed
|
71 |
+
if ( isset( $data['contact'] ) ) {
|
72 |
+
$pos = array_search( 'contact', array_keys( $data ) );
|
73 |
+
} elseif ( isset( $data['phone'] ) ) {
|
74 |
+
$pos = array_search( 'phone', array_keys( $data ) );
|
75 |
+
} elseif ( isset( $data['address'] ) ) {
|
76 |
+
$pos = array_search( 'address', array_keys( $data ) );
|
77 |
+
}
|
78 |
+
|
79 |
+
if ( !empty( $pos ) ) {
|
80 |
+
$a = array_slice( $data, 0, $pos );
|
81 |
+
$b = array_slice( $data, $pos + 1 );
|
82 |
+
$data = array_merge( $a, array( 'booking_page' => array( $this, 'bpfwp_print_booking_link' ) ) , $b );
|
83 |
+
|
84 |
+
// If no short links are being displayed, just add it to the bottom.
|
85 |
+
} else {
|
86 |
+
$data['booking_page'] = array( $this, 'bpfwp_print_booking_link' );
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
return $data;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Print the booking link
|
95 |
+
* Restaurant Reservations plugin
|
96 |
+
* @since 0.0.1
|
97 |
+
*/
|
98 |
+
public function bpfwp_print_booking_link() {
|
99 |
+
|
100 |
+
global $bpfwp_controller;
|
101 |
+
|
102 |
+
if ( $bpfwp_controller->display_settings['show_booking_link'] ) :
|
103 |
+
global $rtb_controller;
|
104 |
+
?>
|
105 |
+
|
106 |
+
<div class="bp-booking">
|
107 |
+
<a href="<?php echo get_permalink( $rtb_controller->settings->get_setting( 'booking-page' ) ); ?>"><?php _e( 'Book a table', BPFWP_TEXTDOMAIN ); ?></a>
|
108 |
+
</div>
|
109 |
+
|
110 |
+
<?php
|
111 |
+
endif;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Add the booking page display option to the widget options
|
116 |
+
* Restaurant Reservations plugin
|
117 |
+
* @since 0.0.1
|
118 |
+
*/
|
119 |
+
public function bpfwp_booking_link_widget_option( $toggles ) {
|
120 |
+
|
121 |
+
// Place the option below the contact option
|
122 |
+
$pos = array_search( 'show_contact', array_keys( $toggles ) );
|
123 |
+
|
124 |
+
if ( !empty( $pos ) ) {
|
125 |
+
$a = array_slice( $toggles, 0, $pos );
|
126 |
+
$b = array_slice( $toggles, $pos + 1 );
|
127 |
+
$toggles = array_merge( $a, array( 'show_booking_link' => __( 'Show book a table link', BPFWP_TEXTDOMAIN ) ) , $b );
|
128 |
+
|
129 |
+
// If no short links are being displayed, just add it to the bottom.
|
130 |
+
} else {
|
131 |
+
$toggles['show_booking_link'] = __( 'Show book a table link', BPFWP_TEXTDOMAIN );
|
132 |
+
}
|
133 |
+
|
134 |
+
return $toggles;
|
135 |
+
}
|
136 |
+
|
137 |
+
}
|
138 |
+
} // endif;
|
139 |
+
|
140 |
+
new bpfwpIntegrations();
|
includes/Settings.class.php
ADDED
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
if ( !class_exists( 'bpfwpSettings' ) ) {
|
5 |
+
/**
|
6 |
+
* Class to handle configurable settings for Business Profile
|
7 |
+
*
|
8 |
+
* @since 0.0.1
|
9 |
+
*/
|
10 |
+
class bpfwpSettings {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Default values for settings
|
14 |
+
* @since 0.0.1
|
15 |
+
*/
|
16 |
+
public $defaults = array();
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Stored values for settings
|
20 |
+
* @since 0.0.1
|
21 |
+
*/
|
22 |
+
public $settings = array();
|
23 |
+
|
24 |
+
public function __construct() {
|
25 |
+
|
26 |
+
add_action( 'init', array( $this, 'set_defaults' ) );
|
27 |
+
|
28 |
+
add_action( 'init', array( $this, 'load_settings_panel' ) );
|
29 |
+
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Load the plugin's default settings
|
34 |
+
* @since 0.0.1
|
35 |
+
*/
|
36 |
+
public function set_defaults() {
|
37 |
+
|
38 |
+
$this->defaults = array(
|
39 |
+
'schema_type' => 'Organization',
|
40 |
+
'name' => get_bloginfo( 'name' ),
|
41 |
+
);
|
42 |
+
|
43 |
+
$this->defaults = apply_filters( 'bpfwp_defaults', $this->defaults );
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Get a setting's value or fallback to a default if one exists
|
48 |
+
* @since 0.0.1
|
49 |
+
*/
|
50 |
+
public function get_setting( $setting ) {
|
51 |
+
|
52 |
+
if ( empty( $this->settings ) ) {
|
53 |
+
$this->settings = get_option( 'bpfwp-settings' );
|
54 |
+
}
|
55 |
+
|
56 |
+
if ( !empty( $this->settings[ $setting ] ) ) {
|
57 |
+
return $this->settings[ $setting ];
|
58 |
+
}
|
59 |
+
|
60 |
+
if ( !empty( $this->defaults[ $setting ] ) ) {
|
61 |
+
return $this->defaults[ $setting ];
|
62 |
+
}
|
63 |
+
|
64 |
+
return null;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Load the admin settings page
|
69 |
+
* @since 0.0.1
|
70 |
+
* @sa https://github.com/NateWr/simple-admin-pages
|
71 |
+
*/
|
72 |
+
public function load_settings_panel() {
|
73 |
+
|
74 |
+
require_once( BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php' );
|
75 |
+
$sap = sap_initialize_library(
|
76 |
+
$args = array(
|
77 |
+
'version' => '2.0.a.5',
|
78 |
+
'lib_url' => BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/',
|
79 |
+
)
|
80 |
+
);
|
81 |
+
|
82 |
+
$sap->add_page(
|
83 |
+
'menu',
|
84 |
+
array(
|
85 |
+
'id' => 'bpfwp-settings',
|
86 |
+
'title' => __( 'Business Profile', BPFWP_TEXTDOMAIN ),
|
87 |
+
'menu_title' => __( 'Business Profile', BPFWP_TEXTDOMAIN ),
|
88 |
+
'capability' => 'manage_options',
|
89 |
+
'icon' => 'dashicons-businessman',
|
90 |
+
'position' => null
|
91 |
+
)
|
92 |
+
);
|
93 |
+
|
94 |
+
$sap->add_section(
|
95 |
+
'bpfwp-settings',
|
96 |
+
array(
|
97 |
+
'id' => 'bpfwp-seo',
|
98 |
+
'title' => __( 'Search Engine Optimization', BPFWP_TEXTDOMAIN ),
|
99 |
+
)
|
100 |
+
);
|
101 |
+
|
102 |
+
$sap->add_setting(
|
103 |
+
'bpfwp-settings',
|
104 |
+
'bpfwp-seo',
|
105 |
+
'select',
|
106 |
+
array(
|
107 |
+
'id' => 'schema_type',
|
108 |
+
'title' => __( 'Schema Type', BPFWP_TEXTDOMAIN ),
|
109 |
+
'description' => __( 'Select the option that best describes your business to improve how search engines understand your website', BPFWP_TEXTDOMAIN ) . ' <a href="http://schema.org/" target="_blank">Schema.org</a>',
|
110 |
+
'blank_option' => false,
|
111 |
+
'options' => array(
|
112 |
+
'Organization' => 'Organization',
|
113 |
+
'Corporation' => 'Corporation',
|
114 |
+
'EducationalOrganization' => 'Educational Organization',
|
115 |
+
'GovernmentOrganization' => 'Government Organization',
|
116 |
+
'LocalBusiness' => 'Local Business',
|
117 |
+
'AnimalShelter' => '- Animal Shelter',
|
118 |
+
'AutomotiveBusiness' => '- Automotive Business',
|
119 |
+
'ChildCare' => '- Child Care',
|
120 |
+
'DryCleaningOrLaundry' => '- Dry Cleaning or Laundry',
|
121 |
+
'EmergencyService' => '- Emergency Service',
|
122 |
+
'EmploymentAgency' => '- Employment Agency',
|
123 |
+
'EntertainmentBusiness' => '- Entertainment Business',
|
124 |
+
'FinancialService' => '- Financial Service',
|
125 |
+
'FoodEstablishment' => '- Food Establishment',
|
126 |
+
'GovernmentOffice' => '- Government Office',
|
127 |
+
'HealthAndBeautyBusiness' => '- Health and Beauty Business',
|
128 |
+
'HomeAndConstructionBusiness' => '- Home and Construction Business',
|
129 |
+
'InternetCafe' => '- Internet Cafe',
|
130 |
+
'Library' => '- Library',
|
131 |
+
'LodgingBusiness' => '- Lodging Business',
|
132 |
+
'MedicalOrganization' => '- Medical Organization',
|
133 |
+
'RadioStation' => '- Radio Station',
|
134 |
+
'RealEstateAgent' => '- Real Estate Agent',
|
135 |
+
'RecyclingCenter' => '- Recycling Center',
|
136 |
+
'SelfStorage' => '- Self Storage',
|
137 |
+
'SportsActivityLocation' => '- Sports Activity Location',
|
138 |
+
'Store' => '- Store',
|
139 |
+
'TouristInformationCenter' => '- Tourist Information Center',
|
140 |
+
'TravelAgency' => '- Travel Agency',
|
141 |
+
'NGO' => 'NGO',
|
142 |
+
'PerformingGroup' => 'PerformingGroup',
|
143 |
+
'SportsTeam' => 'SportsTeam',
|
144 |
+
),
|
145 |
+
)
|
146 |
+
);
|
147 |
+
|
148 |
+
$sap->add_section(
|
149 |
+
'bpfwp-settings',
|
150 |
+
array(
|
151 |
+
'id' => 'rtb-contact',
|
152 |
+
'title' => __( 'Contact Information', BPFWP_TEXTDOMAIN ),
|
153 |
+
)
|
154 |
+
);
|
155 |
+
|
156 |
+
$sap->add_setting(
|
157 |
+
'bpfwp-settings',
|
158 |
+
'rtb-contact',
|
159 |
+
'text',
|
160 |
+
array(
|
161 |
+
'id' => 'name',
|
162 |
+
'title' => __( 'Name', BPFWP_TEXTDOMAIN ),
|
163 |
+
'description' => __( 'Enter the name of your business if it is different than the website name.', BPFWP_TEXTDOMAIN ),
|
164 |
+
'placeholder' => $this->defaults['name'],
|
165 |
+
)
|
166 |
+
);
|
167 |
+
|
168 |
+
$sap->add_setting(
|
169 |
+
'bpfwp-settings',
|
170 |
+
'rtb-contact',
|
171 |
+
'address',
|
172 |
+
array(
|
173 |
+
'id' => 'address',
|
174 |
+
'title' => __( 'Address', BPFWP_TEXTDOMAIN ),
|
175 |
+
)
|
176 |
+
);
|
177 |
+
|
178 |
+
$sap->add_setting(
|
179 |
+
'bpfwp-settings',
|
180 |
+
'rtb-contact',
|
181 |
+
'text',
|
182 |
+
array(
|
183 |
+
'id' => 'phone',
|
184 |
+
'title' => __( 'Phone', BPFWP_TEXTDOMAIN ),
|
185 |
+
)
|
186 |
+
);
|
187 |
+
|
188 |
+
$sap->add_setting(
|
189 |
+
'bpfwp-settings',
|
190 |
+
'rtb-contact',
|
191 |
+
'post',
|
192 |
+
array(
|
193 |
+
'id' => 'contact-page',
|
194 |
+
'title' => __( 'Contact Page', BPFWP_TEXTDOMAIN ),
|
195 |
+
'description' => __( 'Select a page on your site where users can reach you, such as a contact form.', BPFWP_TEXTDOMAIN ),
|
196 |
+
'blank_option' => true,
|
197 |
+
'args' => array(
|
198 |
+
'post_type' => 'page',
|
199 |
+
'posts_per_page' => -1,
|
200 |
+
'post_status' => 'publish',
|
201 |
+
),
|
202 |
+
)
|
203 |
+
);
|
204 |
+
|
205 |
+
$sap->add_setting(
|
206 |
+
'bpfwp-settings',
|
207 |
+
'rtb-contact',
|
208 |
+
'text',
|
209 |
+
array(
|
210 |
+
'id' => 'contact-email',
|
211 |
+
'title' => __( 'Email Address (optional)', BPFWP_TEXTDOMAIN ),
|
212 |
+
'description' => __( 'Enter an email address only if you want to display this publicly. Showing your email address on your site may cause you to receive excessive spam.', BPFWP_TEXTDOMAIN ),
|
213 |
+
)
|
214 |
+
);
|
215 |
+
|
216 |
+
$sap->add_section(
|
217 |
+
'bpfwp-settings',
|
218 |
+
array(
|
219 |
+
'id' => 'rtb-schedule',
|
220 |
+
'title' => __( 'Schedule', BPFWP_TEXTDOMAIN ),
|
221 |
+
)
|
222 |
+
);
|
223 |
+
|
224 |
+
$sap->add_setting(
|
225 |
+
'bpfwp-settings',
|
226 |
+
'rtb-schedule',
|
227 |
+
'scheduler',
|
228 |
+
array(
|
229 |
+
'id' => 'opening-hours',
|
230 |
+
'title' => __( 'Opening Hours', BPFWP_TEXTDOMAIN ),
|
231 |
+
'description' => __( 'Define your weekly opening hours by adding scheduling rules.', BPFWP_TEXTDOMAIN ),
|
232 |
+
'weekdays' => array(
|
233 |
+
'monday' => _x( 'Mo', 'Monday abbreviation', BPFWP_TEXTDOMAIN ),
|
234 |
+
'tuesday' => _x( 'Tu', 'Tuesday abbreviation', BPFWP_TEXTDOMAIN ),
|
235 |
+
'wednesday' => _x( 'We', 'Wednesday abbreviation', BPFWP_TEXTDOMAIN ),
|
236 |
+
'thursday' => _x( 'Th', 'Thursday abbreviation', BPFWP_TEXTDOMAIN ),
|
237 |
+
'friday' => _x( 'Fr', 'Friday abbreviation', BPFWP_TEXTDOMAIN ),
|
238 |
+
'saturday' => _x( 'Sa', 'Saturday abbreviation', BPFWP_TEXTDOMAIN ),
|
239 |
+
'sunday' => _x( 'Su', 'Sunday abbreviation', BPFWP_TEXTDOMAIN )
|
240 |
+
),
|
241 |
+
'time_format' => _x( 'h:i A', 'Time format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/time.htm#formats', BPFWP_TEXTDOMAIN ),
|
242 |
+
'date_format' => _x( 'mmmm d, yyyy', 'Date format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/date.htm#formatting-rules', BPFWP_TEXTDOMAIN ),
|
243 |
+
'disable_weeks' => true,
|
244 |
+
'disable_date' => true,
|
245 |
+
)
|
246 |
+
);
|
247 |
+
|
248 |
+
$sap = apply_filters( 'bpfwp_settings_page', $sap );
|
249 |
+
|
250 |
+
$sap->add_admin_menus();
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
}
|
255 |
+
} // endif;
|
includes/WP_Widget.ContactCardWidget.class.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
if ( ! class_exists( 'WP_Widget' ) ) {
|
5 |
+
require_once ABSPATH . 'wp-admin/includes/widgets.php';
|
6 |
+
}
|
7 |
+
|
8 |
+
if ( !class_exists( 'bpfwpContactCardWidget' ) ) {
|
9 |
+
/**
|
10 |
+
* Contact card widget
|
11 |
+
*
|
12 |
+
* Extends WP_Widget to display a contact card in a widget.
|
13 |
+
* @since 0.0.1
|
14 |
+
*/
|
15 |
+
class bpfwpContactCardWidget extends WP_Widget {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Register widget with WordPress.
|
19 |
+
* @since 0.0.1
|
20 |
+
*/
|
21 |
+
function __construct() {
|
22 |
+
|
23 |
+
// Display toggles
|
24 |
+
$this->toggles = apply_filters( 'bpfwp_widget_display_toggles', array(
|
25 |
+
'show_name' => __( 'Show Name', BPFWP_TEXTDOMAIN ),
|
26 |
+
'show_address' => __( 'Show Address', BPFWP_TEXTDOMAIN ),
|
27 |
+
'show_get_directions' => __( 'Show link to get directions on Google Maps', BPFWP_TEXTDOMAIN ),
|
28 |
+
'show_phone' => __( 'Show Phone number', BPFWP_TEXTDOMAIN ),
|
29 |
+
'show_contact' => __( 'Show contact details', BPFWP_TEXTDOMAIN ),
|
30 |
+
'show_opening_hours' => __( 'Show Opening Hours', BPFWP_TEXTDOMAIN ),
|
31 |
+
'show_opening_hours_brief' => __( 'Show brief opening hours on one line', BPFWP_TEXTDOMAIN ),
|
32 |
+
'show_map' => __( 'Show Google Map', BPFWP_TEXTDOMAIN ),
|
33 |
+
)
|
34 |
+
);
|
35 |
+
|
36 |
+
parent::__construct(
|
37 |
+
'bpfwp_contact_card_widget',
|
38 |
+
__('Contact Card', BPFWP_TEXTDOMAIN),
|
39 |
+
array( 'description' => __( 'Display a contact card with your name, address, phone number, opening hours and map.', BPFWP_TEXTDOMAIN ), )
|
40 |
+
);
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Print the widget content
|
46 |
+
* @since 0.0.1
|
47 |
+
*/
|
48 |
+
public function widget( $args, $instance ) {
|
49 |
+
|
50 |
+
global $bpfwp_controller;
|
51 |
+
|
52 |
+
// Print the widget's HTML markup
|
53 |
+
echo $args['before_widget'];
|
54 |
+
if( isset( $instance['title'] ) ) {
|
55 |
+
$title = apply_filters( 'widget_title', $instance['title'] );
|
56 |
+
echo $args['before_title'] . $title . $args['after_title'];
|
57 |
+
}
|
58 |
+
echo bpwfwp_print_contact_card( $instance );
|
59 |
+
echo $args['after_widget'];
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Print the form to configure this widget in the admin panel
|
65 |
+
* @since 1.0
|
66 |
+
*/
|
67 |
+
public function form( $instance ) {
|
68 |
+
?>
|
69 |
+
|
70 |
+
<p>
|
71 |
+
<label for="<?php echo $this->get_field_id( 'title' ); ?>"> <?php _e( 'Title' ); ?></label>
|
72 |
+
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text"<?php if ( isset( $instance['title'] ) ) : ?> value="<?php echo esc_attr( $instance['title'] ); ?>"<?php endif; ?>>
|
73 |
+
</p>
|
74 |
+
|
75 |
+
<?php foreach( $this->toggles as $id => $label ) : ?>
|
76 |
+
|
77 |
+
<p>
|
78 |
+
<label for="<?php echo $this->get_field_id( $id ); ?>"> <?php echo $label; ?></label>
|
79 |
+
<input type="checkbox" id="<?php echo $this->get_field_id( $id ); ?>" name="<?php echo $this->get_field_name( $id ); ?>" value="1"<?php if ( !empty( $instance[$id] ) ) : ?> checked="checked"<?php endif; ?>>
|
80 |
+
</p>
|
81 |
+
|
82 |
+
<?php endforeach;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Sanitize and save the widget form values.
|
87 |
+
* @since 1.0
|
88 |
+
*/
|
89 |
+
public function update( $new_instance, $old_instance ) {
|
90 |
+
|
91 |
+
$instance = array();
|
92 |
+
if ( !empty( $new_instance['title'] ) ) {
|
93 |
+
$instance['title'] = strip_tags( $new_instance['title'] );
|
94 |
+
}
|
95 |
+
|
96 |
+
foreach( $this->toggles as $id => $label ) {
|
97 |
+
$instance[ $id ] = empty( $new_instance[ $id ] ) ? false : true;
|
98 |
+
}
|
99 |
+
|
100 |
+
return $instance;
|
101 |
+
}
|
102 |
+
|
103 |
+
}
|
104 |
+
} // endif
|
includes/template-functions.php
ADDED
@@ -0,0 +1,455 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Template functions for rendering contact cards
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Print a contact card and add a shortcode
|
8 |
+
* @since 0.0.1
|
9 |
+
*/
|
10 |
+
if ( !function_exists( 'bpwfwp_print_contact_card' ) ) {
|
11 |
+
function bpwfwp_print_contact_card( $args = array() ) {
|
12 |
+
|
13 |
+
// Define shortcode attributes
|
14 |
+
$defaults = array(
|
15 |
+
'show_name' => true,
|
16 |
+
'show_address' => true,
|
17 |
+
'show_get_directions' => true,
|
18 |
+
'show_phone' => true,
|
19 |
+
'show_contact' => true,
|
20 |
+
'show_opening_hours' => true,
|
21 |
+
'show_opening_hours_brief' => false,
|
22 |
+
'show_map' => true,
|
23 |
+
);
|
24 |
+
|
25 |
+
$defaults = apply_filters( 'bpwfp_contact_card_defaults', $defaults );
|
26 |
+
|
27 |
+
global $bpfwp_controller;
|
28 |
+
$bpfwp_controller->display_settings = shortcode_atts( $defaults, $args, 'contact-card' );
|
29 |
+
|
30 |
+
// Setup components and callback functions to render them
|
31 |
+
$data = array();
|
32 |
+
|
33 |
+
if ( $bpfwp_controller->settings->get_setting( 'name' ) ) {
|
34 |
+
$data['name'] = 'bpwfwp_print_name';
|
35 |
+
}
|
36 |
+
|
37 |
+
if ( $bpfwp_controller->settings->get_setting( 'address' ) ) {
|
38 |
+
$data['address'] = 'bpwfwp_print_address';
|
39 |
+
}
|
40 |
+
|
41 |
+
if ( $bpfwp_controller->settings->get_setting( 'phone' ) ) {
|
42 |
+
$data['phone'] = 'bpwfwp_print_phone';
|
43 |
+
}
|
44 |
+
|
45 |
+
if ( $bpfwp_controller->display_settings['show_contact'] &&
|
46 |
+
( $bpfwp_controller->settings->get_setting( 'contact-email' ) || $bpfwp_controller->settings->get_setting( 'contact-page' ) ) ) {
|
47 |
+
$data['contact'] = 'bpwfwp_print_contact';
|
48 |
+
}
|
49 |
+
|
50 |
+
if ( $bpfwp_controller->settings->get_setting( 'opening-hours' ) ) {
|
51 |
+
$data['opening_hours'] = 'bpwfwp_print_opening_hours';
|
52 |
+
}
|
53 |
+
|
54 |
+
if ( $bpfwp_controller->display_settings['show_map'] && $bpfwp_controller->settings->get_setting( 'address' ) ) {
|
55 |
+
$data['map'] = 'bpwfwp_print_map';
|
56 |
+
}
|
57 |
+
|
58 |
+
$data = apply_filters( 'bpwfwp_component_callbacks', $data );
|
59 |
+
|
60 |
+
|
61 |
+
if ( apply_filters( 'bpfwp-load-frontend-assets', true ) ) {
|
62 |
+
wp_enqueue_style( 'dashicons' );
|
63 |
+
wp_enqueue_style( 'bpfwp-default' );
|
64 |
+
}
|
65 |
+
|
66 |
+
ob_start();
|
67 |
+
?>
|
68 |
+
|
69 |
+
<address class="bp-contact-card" itemscope itemtype="http://schema.org/<?php echo $bpfwp_controller->settings->get_setting( 'schema_type' ); ?>">
|
70 |
+
<?php foreach ( $data as $data => $callback ) { call_user_func( $callback ); } ?>
|
71 |
+
</address>
|
72 |
+
|
73 |
+
<?php
|
74 |
+
$output = ob_get_clean();
|
75 |
+
|
76 |
+
return apply_filters( 'bpwfwp_contact_card_output', $output );
|
77 |
+
}
|
78 |
+
if ( !shortcode_exists( 'contact-card' ) ) {
|
79 |
+
add_shortcode( 'contact-card', 'bpwfwp_print_contact_card' );
|
80 |
+
}
|
81 |
+
} // endif;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Print the name
|
85 |
+
* @since 0.0.1
|
86 |
+
*/
|
87 |
+
if ( !function_exists( 'bpwfwp_print_name' ) ) {
|
88 |
+
function bpwfwp_print_name() {
|
89 |
+
|
90 |
+
global $bpfwp_controller;
|
91 |
+
|
92 |
+
if ( $bpfwp_controller->display_settings['show_name'] ) :
|
93 |
+
?>
|
94 |
+
<div class="bp-name" itemprop="name">
|
95 |
+
<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'name' ) ); ?>
|
96 |
+
</div>
|
97 |
+
|
98 |
+
<?php else : ?>
|
99 |
+
<meta itemprop="name" content="<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'name' ) ); ?>">
|
100 |
+
|
101 |
+
<?php endif; ?>
|
102 |
+
|
103 |
+
<meta itemprop="description" content="<?php echo esc_attr( get_bloginfo( 'url' ) ) ?>">
|
104 |
+
<meta itemprop="url" content="<?php echo esc_attr( get_bloginfo( 'description' ) ); ?>">
|
105 |
+
|
106 |
+
<?php
|
107 |
+
}
|
108 |
+
} // endif;
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Print the address with a get directions link to Google Maps
|
112 |
+
* @since 0.0.1
|
113 |
+
*/
|
114 |
+
if ( !function_exists( 'bpwfwp_print_address' ) ) {
|
115 |
+
function bpwfwp_print_address() {
|
116 |
+
|
117 |
+
global $bpfwp_controller;
|
118 |
+
|
119 |
+
$address = $bpfwp_controller->settings->get_setting( 'address' );
|
120 |
+
|
121 |
+
if ( $bpfwp_controller->display_settings['show_address'] ) :
|
122 |
+
?>
|
123 |
+
|
124 |
+
<div class="bp-address" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
|
125 |
+
<?php echo nl2br( $address['text'] ); ?>
|
126 |
+
</div>
|
127 |
+
|
128 |
+
<?php else : ?>
|
129 |
+
<meta itemprop="address" content="<?php echo esc_attr( $address['text'] ); ?>">
|
130 |
+
|
131 |
+
<?php endif; ?>
|
132 |
+
|
133 |
+
<?php if ( $bpfwp_controller->display_settings['show_get_directions'] ) : ?>
|
134 |
+
<div class="bp-directions">
|
135 |
+
<a href="//maps.google.com/maps?saddr=current+location&daddr=<?php echo urlencode( esc_attr( $address['text'] ) ); ?>"><?php _e( 'Get directions', BPFWP_TEXTDOMAIN ); ?></a>
|
136 |
+
</div>
|
137 |
+
<?php endif;
|
138 |
+
|
139 |
+
}
|
140 |
+
} // endif;
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Print the phone number
|
144 |
+
* @since 0.0.1
|
145 |
+
*/
|
146 |
+
if ( !function_exists( 'bpwfwp_print_phone' ) ) {
|
147 |
+
function bpwfwp_print_phone() {
|
148 |
+
|
149 |
+
global $bpfwp_controller;
|
150 |
+
|
151 |
+
if ( $bpfwp_controller->display_settings['show_phone'] ) :
|
152 |
+
?>
|
153 |
+
|
154 |
+
<div class="bp-phone" itemprop="telephone">
|
155 |
+
<?php echo $bpfwp_controller->settings->get_setting( 'phone' ); ?>
|
156 |
+
</div>
|
157 |
+
|
158 |
+
<?php else : ?>
|
159 |
+
<meta itemprop="telephone" content="<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'phone' ) ); ?>">
|
160 |
+
|
161 |
+
<?php endif;
|
162 |
+
}
|
163 |
+
} // endif;
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Print the contact link
|
167 |
+
* @since 0.0.1
|
168 |
+
*/
|
169 |
+
if ( !function_exists( 'bpwfwp_print_contact' ) ) {
|
170 |
+
function bpwfwp_print_contact() {
|
171 |
+
|
172 |
+
global $bpfwp_controller;
|
173 |
+
|
174 |
+
$email = $bpfwp_controller->settings->get_setting( 'contact-email' );
|
175 |
+
if ( !empty( $email ) ) :
|
176 |
+
?>
|
177 |
+
|
178 |
+
<div class="bp-contact bp-contact-email" itemprop="email">
|
179 |
+
<a href="mailto:<?php echo esc_attr( $email ); ?>"><?php echo $email; ?></a>
|
180 |
+
</div>
|
181 |
+
|
182 |
+
<?php
|
183 |
+
return;
|
184 |
+
endif;
|
185 |
+
|
186 |
+
$contact = $bpfwp_controller->settings->get_setting( 'contact-page' );
|
187 |
+
if ( !empty( $contact ) ) :
|
188 |
+
?>
|
189 |
+
|
190 |
+
<div class="bp-contact bp-contact-page" itemprop="ContactPoint" itemscope itemtype="http://schema.org/ContactPoint">
|
191 |
+
<a href="<?php echo get_post_permalink( $contact ); ?>"><?php _e( 'Contact', BPFWP_TEXTDOMAIN ); ?></a>
|
192 |
+
</div>
|
193 |
+
|
194 |
+
<?php endif;
|
195 |
+
|
196 |
+
}
|
197 |
+
} // endif;
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Print the opening hours
|
201 |
+
* @since 0.0.1
|
202 |
+
*/
|
203 |
+
if ( !function_exists( 'bpwfwp_print_opening_hours' ) ) {
|
204 |
+
function bpwfwp_print_opening_hours() {
|
205 |
+
|
206 |
+
global $bpfwp_controller;
|
207 |
+
|
208 |
+
$weekdays_schema = array(
|
209 |
+
'monday' => 'Mo',
|
210 |
+
'tuesday' => 'Tu',
|
211 |
+
'wednesday' => 'We',
|
212 |
+
'thursday' => 'Th',
|
213 |
+
'friday' => 'Fr',
|
214 |
+
'saturday' => 'Sa',
|
215 |
+
'sunday' => 'Su',
|
216 |
+
);
|
217 |
+
|
218 |
+
$hours = $bpfwp_controller->settings->get_setting( 'opening-hours' );
|
219 |
+
|
220 |
+
// Output proper schema.org format
|
221 |
+
foreach( $hours as $slot ) {
|
222 |
+
|
223 |
+
// Skip this entry if no weekdays are set
|
224 |
+
if ( empty( $slot['weekdays'] ) ) {
|
225 |
+
continue;
|
226 |
+
}
|
227 |
+
|
228 |
+
$days = array();
|
229 |
+
foreach( $slot['weekdays'] as $day => $val ) {
|
230 |
+
$days[] = $weekdays_schema[ $day ];
|
231 |
+
}
|
232 |
+
$string = !empty( $days ) ? join( ',', $days ) : '';
|
233 |
+
|
234 |
+
if ( !empty( $string) && !empty( $slot['time'] ) ) {
|
235 |
+
|
236 |
+
if ( empty( $slot['time']['start'] ) ) {
|
237 |
+
$start = '00:00';
|
238 |
+
} else {
|
239 |
+
$start = trim( substr( $slot['time']['start'], 0, -2 ) );
|
240 |
+
if ( substr( $slot['time']['start'], -2 ) == 'PM' && $start !== '12:00' ) {
|
241 |
+
$split = explode( ':', $start );
|
242 |
+
$split[0] += 12;
|
243 |
+
$start = join( ':', $split );
|
244 |
+
}
|
245 |
+
if ( substr( $slot['time']['start'], -2 ) == 'AM' && $start == '12:00' ) {
|
246 |
+
$start = '00:00';
|
247 |
+
}
|
248 |
+
}
|
249 |
+
|
250 |
+
if ( empty( $slot['time']['end'] ) ) {
|
251 |
+
$end = '24:00';
|
252 |
+
} else {
|
253 |
+
$end = trim( substr( $slot['time']['end'], 0, -2 ) );
|
254 |
+
if ( substr( $slot['time']['end'], -2 ) == 'PM' ) {
|
255 |
+
$split = explode( ':', $end );
|
256 |
+
$split[0] += 12;
|
257 |
+
$end = join( ':', $split );
|
258 |
+
}
|
259 |
+
if ( substr( $slot['time']['start'], -2 ) == 'AM' && $start == '12:00' ) {
|
260 |
+
$end = '24:00';
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
$string .= ' ' . $start . '-' . $end;
|
265 |
+
}
|
266 |
+
echo '<meta itemprop="openingHours" content="' . esc_attr( $string ) . '">';
|
267 |
+
}
|
268 |
+
|
269 |
+
// Output display format
|
270 |
+
if ( !$bpfwp_controller->display_settings['show_opening_hours'] ) {
|
271 |
+
return;
|
272 |
+
}
|
273 |
+
|
274 |
+
if ( $bpfwp_controller->display_settings['show_opening_hours_brief'] ) :
|
275 |
+
?>
|
276 |
+
|
277 |
+
<div class="bp-opening-hours-brief">
|
278 |
+
|
279 |
+
<?php
|
280 |
+
$slots = array();
|
281 |
+
foreach( $hours as $slot ) {
|
282 |
+
|
283 |
+
// Skip this entry if no weekdays are set
|
284 |
+
if ( empty( $slot['weekdays'] ) ) {
|
285 |
+
continue;
|
286 |
+
}
|
287 |
+
|
288 |
+
$days = array();
|
289 |
+
foreach( $slot['weekdays'] as $day => $val ) {
|
290 |
+
$days[] = $weekdays_schema[ $day ];
|
291 |
+
}
|
292 |
+
$string = !empty( $days ) ? join( ',', $days ) : '';
|
293 |
+
|
294 |
+
|
295 |
+
if ( empty( $slot['time'] ) ) {
|
296 |
+
$string .= __( ' all day', BPFWP_TEXTDOMAIN );
|
297 |
+
} else {
|
298 |
+
if ( !empty( $slot['time']['start'] ) ) {
|
299 |
+
$start = new DateTime( $slot['time']['start'] );
|
300 |
+
}
|
301 |
+
if ( !empty( $slot['time']['end'] ) ) {
|
302 |
+
$end = new DateTime( $slot['time']['end'] );
|
303 |
+
}
|
304 |
+
|
305 |
+
if ( empty( $start ) ) {
|
306 |
+
$string .= __( ' open until ', BPFWP_TEXTDOMAIN ) . $end->format( get_option( 'time_format' ) );
|
307 |
+
} elseif ( empty( $end ) ) {
|
308 |
+
$string .= __( ' open from ', BPFWP_TEXTDOMAIN ) . $start->format( get_option( 'time_format' ) );
|
309 |
+
} else {
|
310 |
+
$string .= ' ' . $start->format( get_option( 'time_format' ) ) . _x( '-', 'Separator between opening and closing times. Example: 9:00am-5:00pm', BPFWP_TEXTDOMAIN ) . $end->format( get_option( 'time_format' ) );
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
$slots[] = $string;
|
315 |
+
}
|
316 |
+
|
317 |
+
echo join( _x( '; ', 'Separator between multiple opening times in the brief opening hours. Example: Mo,We 9:00 AM - 5:00 PM; Tu,Th 10:00 AM - 5:00 PM', BPFWP_TEXTDOMAIN ), $slots );
|
318 |
+
?>
|
319 |
+
|
320 |
+
</div>
|
321 |
+
|
322 |
+
<?php
|
323 |
+
return;
|
324 |
+
endif; // brief opening hours
|
325 |
+
|
326 |
+
$weekdays_display = array(
|
327 |
+
'monday' => __( 'Monday' ),
|
328 |
+
'tuesday' => __( 'Tuesday' ),
|
329 |
+
'wednesday' => __( 'Wednesday' ),
|
330 |
+
'thursday' => __( 'Thursday' ),
|
331 |
+
'friday' => __( 'Friday' ),
|
332 |
+
'saturday' => __( 'Saturday' ),
|
333 |
+
'sunday' => __( 'Sunday' ),
|
334 |
+
);
|
335 |
+
|
336 |
+
$weekdays = array();
|
337 |
+
foreach( $hours as $rule ) {
|
338 |
+
|
339 |
+
// Skip this entry if no weekdays are set
|
340 |
+
if ( empty( $rule['weekdays'] ) ) {
|
341 |
+
continue;
|
342 |
+
}
|
343 |
+
|
344 |
+
if ( empty( $rule['time'] ) ) {
|
345 |
+
$time = __( 'Open', BPFWP_TEXTDOMAIN );
|
346 |
+
|
347 |
+
} else {
|
348 |
+
|
349 |
+
if ( !empty( $rule['time']['start'] ) ) {
|
350 |
+
$start = new DateTime( $rule['time']['start'] );
|
351 |
+
}
|
352 |
+
if ( !empty( $rule['time']['end'] ) ) {
|
353 |
+
$end = new DateTime( $rule['time']['end'] );
|
354 |
+
}
|
355 |
+
|
356 |
+
if ( empty( $start ) ) {
|
357 |
+
$time = __( 'Open until ', BPFWP_TEXTDOMAIN ) . $end->format( get_option( 'time_format' ) );
|
358 |
+
} elseif ( empty( $end ) ) {
|
359 |
+
$time = __( 'Open from ', BPFWP_TEXTDOMAIN ) . $start->format( get_option( 'time_format' ) );
|
360 |
+
} else {
|
361 |
+
$time = $start->format( get_option( 'time_format' ) ) . _x( '-', 'Separator between opening and closing times. Example: 9:00am-5:00pm', BPFWP_TEXTDOMAIN ) . $end->format( get_option( 'time_format' ) );
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
foreach( $rule['weekdays'] as $day => $val ) {
|
366 |
+
|
367 |
+
if ( !array_key_exists( $day, $weekdays ) ) {
|
368 |
+
$weekdays[$day] = array();
|
369 |
+
}
|
370 |
+
|
371 |
+
$weekdays[$day][] = $time;
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
if ( count( $weekdays ) ) :
|
376 |
+
|
377 |
+
// Order the weekdays and add any missing days as "closed"
|
378 |
+
$weekdays_ordered = array();
|
379 |
+
foreach( $weekdays_display as $slug => $name ) {
|
380 |
+
if ( !array_key_exists( $slug, $weekdays ) ) {
|
381 |
+
$weekdays_ordered[$slug] = array( __( 'Closed', BPFWP_TEXTDOMAIN ) );
|
382 |
+
} else {
|
383 |
+
$weekdays_ordered[$slug] = $weekdays[$slug];
|
384 |
+
}
|
385 |
+
}
|
386 |
+
?>
|
387 |
+
|
388 |
+
<div class="bp-opening-hours">
|
389 |
+
<span class="bp-title"><?php _e( 'Opening Hours', BPFWP_TEXTDOMAIN ); ?></span>
|
390 |
+
<?php foreach ( $weekdays_ordered as $weekday => $times ) : ?>
|
391 |
+
<div class="bp-weekday">
|
392 |
+
<span class="bp-weekday-name bp-weekday-<?php echo $weekday; ?>"><?php echo $weekdays_display[$weekday]; ?></span>
|
393 |
+
<span class="bp-times">
|
394 |
+
<?php foreach ( $times as $time ) : ?>
|
395 |
+
<span class="bp-time"><?php echo $time; ?></span>
|
396 |
+
<?php endforeach; ?>
|
397 |
+
</span>
|
398 |
+
</div>
|
399 |
+
<?php endforeach; ?>
|
400 |
+
</div>
|
401 |
+
|
402 |
+
<?php
|
403 |
+
endif;
|
404 |
+
}
|
405 |
+
} // endif;
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Print a map to the address
|
409 |
+
* @since 0.0.1
|
410 |
+
*/
|
411 |
+
if ( !function_exists( 'bpwfwp_print_map' ) ) {
|
412 |
+
function bpwfwp_print_map() {
|
413 |
+
|
414 |
+
global $bpfwp_controller;
|
415 |
+
|
416 |
+
$address = $bpfwp_controller->settings->get_setting( 'address' );
|
417 |
+
|
418 |
+
wp_enqueue_script( 'bpfwp-map' );
|
419 |
+
wp_localize_script(
|
420 |
+
'bpfwp-map',
|
421 |
+
'bpfwp_map',
|
422 |
+
array(
|
423 |
+
'strings' => array(
|
424 |
+
'get_directions' => __( 'Get directions', BPFWP_TEXTDOMAIN ),
|
425 |
+
)
|
426 |
+
)
|
427 |
+
);
|
428 |
+
|
429 |
+
global $bpfwp_map_ids;
|
430 |
+
if ( empty( $bpfwp_map_ids ) ) {
|
431 |
+
$bpfwp_map_ids = array();
|
432 |
+
}
|
433 |
+
|
434 |
+
$id = count( $bpfwp_map_ids );
|
435 |
+
$bpfwp_map_ids[] = $id;
|
436 |
+
|
437 |
+
|
438 |
+
$attr = '';
|
439 |
+
|
440 |
+
$phone = $bpfwp_controller->settings->get_setting( 'phone' );
|
441 |
+
if ( !empty( $phone ) ) {
|
442 |
+
$attr .= ' data-phone="' . esc_attr( $phone ) . '"';
|
443 |
+
}
|
444 |
+
|
445 |
+
if ( !empty( $address['lat'] ) && !empty( $address['lon'] ) ) {
|
446 |
+
$attr .= ' data-lat="' . esc_attr( $address['lat'] ) . '" data-lon="' . esc_attr( $address['lon'] ) . '"';
|
447 |
+
}
|
448 |
+
?>
|
449 |
+
|
450 |
+
<div id="bp-map-<?php echo $id; ?>" class="bp-map" itemprop="map" data-name="<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'name' ) ); ?>" data-address="<?php echo esc_attr( nl2br( $address['text'] ) ); ?>"<?php echo $attr; ?>>
|
451 |
+
</div>
|
452 |
+
|
453 |
+
<?php
|
454 |
+
}
|
455 |
+
} // endif;
|
lib/simple-admin-pages/README.md
ADDED
@@ -0,0 +1,396 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Simple Admin Pages for WordPress
|
2 |
+
================================
|
3 |
+
|
4 |
+
Simple Admin Pages is a very small utility library to easily add new admin
|
5 |
+
pages to the WordPress admin interface. It simply collects WordPress' useful
|
6 |
+
Settings API into reuseable classes and implements a set of simple controls.
|
7 |
+
|
8 |
+
*Please note that Simple Admin Pages is still undergoing testing and development
|
9 |
+
in the wild. I don't recommend you use it in your own plugins and themes just
|
10 |
+
yet.*
|
11 |
+
|
12 |
+
## Settings Pages Supported
|
13 |
+
|
14 |
+
- Settings sub-page
|
15 |
+
- Themes sub-page
|
16 |
+
- Submenu pages for custom menu items
|
17 |
+
|
18 |
+
## General Controls Supported
|
19 |
+
|
20 |
+
- Text field
|
21 |
+
- Textarea field
|
22 |
+
- Checkbox (single option to enable/disable setting)
|
23 |
+
- Select dropdown with custom options
|
24 |
+
- Select dropdown of any post type
|
25 |
+
- Select dropdown of any taxonomy type
|
26 |
+
- HTML Content (for instructions, links or other inert text)
|
27 |
+
|
28 |
+
## Controls Supported for Special Use Cases
|
29 |
+
|
30 |
+
- Business Opening Hours
|
31 |
+
|
32 |
+
## Usage
|
33 |
+
|
34 |
+
Here's a simple example of how you can use this library to create an admin page.
|
35 |
+
|
36 |
+
```
|
37 |
+
// Instantiate the Simple Admin Library
|
38 |
+
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
|
39 |
+
$sap = sap_initialize_library(
|
40 |
+
array(
|
41 |
+
'version' => '2.0.a.5', // Version of the library
|
42 |
+
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
|
43 |
+
)
|
44 |
+
);
|
45 |
+
|
46 |
+
// Create a page for the options under the Settings (options) menu
|
47 |
+
$sap->add_page(
|
48 |
+
'options', // Admin menu which this page should be added to
|
49 |
+
array( // Array of key/value pairs matching the AdminPage class constructor variables
|
50 |
+
'id' => 'basic-settings',
|
51 |
+
'title' => __( 'Page Title', SAP_TEXTDOMAIN ),
|
52 |
+
'menu_title' => __( 'menu Title', SAP_TEXTDOMAIN ),
|
53 |
+
'description' => '',
|
54 |
+
'capability' => 'manage_options' // User permissions access level
|
55 |
+
)
|
56 |
+
);
|
57 |
+
|
58 |
+
// Create a basic details section
|
59 |
+
$sap->add_section(
|
60 |
+
'basic-settings', // Page to add this section to
|
61 |
+
array( // Array of key/value pairs matching the AdminPageSection class constructor variables
|
62 |
+
'id' => 'basic-details',
|
63 |
+
'title' => __( 'Basic Details', SAP_TEXTDOMAIN ),
|
64 |
+
'description' => __( 'This section includes some basic details for you to configure.', SAP_TEXTDOMAIN )
|
65 |
+
)
|
66 |
+
);
|
67 |
+
|
68 |
+
// Create the options fields
|
69 |
+
$sap->add_setting(
|
70 |
+
'basic-settings', // Page to add this setting to
|
71 |
+
'basic-details', // Section to add this setting to
|
72 |
+
'select', // Type of setting (see sapLibrary::get_setting_classname()
|
73 |
+
array(
|
74 |
+
'id' => 'select-field',
|
75 |
+
'title' => __( 'Select Field', SAP_TEXTDOMAIN ),
|
76 |
+
'description' => __( 'A demonstration of the select field type.', SAP_TEXTDOMAIN ),
|
77 |
+
'options' => array(
|
78 |
+
'one' => __( 'Option 1', SAP_TEXTDOMAIN ),
|
79 |
+
'two' => __( 'Option 2', SAP_TEXTDOMAIN ),
|
80 |
+
'three' => __( 'Option 3', SAP_TEXTDOMAIN )
|
81 |
+
)
|
82 |
+
)
|
83 |
+
);
|
84 |
+
|
85 |
+
// Allow third-party addons to hook into your settings page
|
86 |
+
$sap = apply_filters( 'sap_page_setup', $sap );
|
87 |
+
|
88 |
+
// Register all admin pages and settings with WordPress
|
89 |
+
$sap->add_admin_menus();
|
90 |
+
```
|
91 |
+
|
92 |
+
Check out the documentation section below for more examples and explanation.
|
93 |
+
|
94 |
+
## License
|
95 |
+
|
96 |
+
Simple Admin Pages is released under the GNU GPL 2 or later.
|
97 |
+
|
98 |
+
## Requirements
|
99 |
+
|
100 |
+
Simple Admin Pages has been tested with WordPress versions 3.5 and above.
|
101 |
+
|
102 |
+
## Roadmap
|
103 |
+
|
104 |
+
- Better documentation
|
105 |
+
- Support custom top-level admin pages
|
106 |
+
- More custom data types
|
107 |
+
|
108 |
+
## Documentation
|
109 |
+
|
110 |
+
### sap_initialize_library()
|
111 |
+
Instantiate the library by loading the simple-admin-pages.php file and calling sap_initialize_library. You'll do everything with the $sap object that is returned.
|
112 |
+
|
113 |
+
**args**
|
114 |
+
An array of properties to pass to the library.
|
115 |
+
|
116 |
+
*version*
|
117 |
+
(required)
|
118 |
+
|
119 |
+
This used to ensure that plugins can play well together even if they use different versions of the library. The version will convert . to _ and append that to the class names which are loaded. If version 1.0 is passed, the library will attempt to load a class named sapAdminPage_1_0.
|
120 |
+
|
121 |
+
*lib_url*
|
122 |
+
(required)
|
123 |
+
|
124 |
+
The lib_url is used to print stylesheets or scripts attached to the library.
|
125 |
+
|
126 |
+
```
|
127 |
+
require_once( 'path/to/simple-admin-pages/simple-admin-pages.php' );
|
128 |
+
$sap = sap_initialize_library(
|
129 |
+
$args = array(
|
130 |
+
'version' => '2.0.a.5', // Version of the library
|
131 |
+
'lib_url' => PLUGIN_URL . '/lib/simple-admin-pages/', // URL path to sap library
|
132 |
+
)
|
133 |
+
);
|
134 |
+
```
|
135 |
+
|
136 |
+
### sapLibrary::add_page()
|
137 |
+
Create a new page with the library by calling the add_page() method. You can attach the page to the options (Settings) or themes (Appearance) menus or any custom menu.
|
138 |
+
|
139 |
+
**type**
|
140 |
+
(required)
|
141 |
+
|
142 |
+
What type of admin menu page to create. Accepts:
|
143 |
+
|
144 |
+
- "options" - A subpage of the Settings menu
|
145 |
+
- "themes" - A subpage of the Appearance menu
|
146 |
+
- "submenu" - A subpage of any top-level menu item
|
147 |
+
|
148 |
+
**args**
|
149 |
+
|
150 |
+
An array of properties to pass to the page.
|
151 |
+
|
152 |
+
*id*
|
153 |
+
(required)
|
154 |
+
|
155 |
+
All settings attached to this page will be stored with the page ID and can be retrieved with get_options( $page_id ).
|
156 |
+
|
157 |
+
*title*
|
158 |
+
(required)
|
159 |
+
|
160 |
+
This will be displayed at the top of the page.
|
161 |
+
|
162 |
+
*menu_title*
|
163 |
+
(required)
|
164 |
+
|
165 |
+
The title to display in the menu.
|
166 |
+
|
167 |
+
*description*
|
168 |
+
(optional)
|
169 |
+
|
170 |
+
Actually, I think this one isn't used at the moment.
|
171 |
+
|
172 |
+
*capability*
|
173 |
+
(required)
|
174 |
+
|
175 |
+
The user permissions access level (capability in WP terms) required to access and edit this page.
|
176 |
+
|
177 |
+
*default_tab*
|
178 |
+
(optional)
|
179 |
+
|
180 |
+
If your page will have multiple tabs, you need to specify a default tab to display when the page is initially loaded. This must match the ID used in the add_section() method. *Leave this parameter out if you don't need any tabs.*
|
181 |
+
|
182 |
+
```
|
183 |
+
$sap->add_page(
|
184 |
+
$type,
|
185 |
+
$args = array(
|
186 |
+
'id' => 'my-settings',
|
187 |
+
'title' => __( 'Page Title', SAP_TEXTDOMAIN ),
|
188 |
+
'menu_title' => __( 'menu Title', SAP_TEXTDOMAIN ),
|
189 |
+
'description' => '',
|
190 |
+
'capability' => 'manage_options'
|
191 |
+
'default_tab' => 'tab-one',
|
192 |
+
)
|
193 |
+
);
|
194 |
+
```
|
195 |
+
|
196 |
+
### sapLibrary::add_section()
|
197 |
+
Create a new section to attach it to an existing page.
|
198 |
+
|
199 |
+
Sections can act as Tabs or as internal sections within the normal settings flow of a Tab or Page. In other words, you can define a section as a tab, attach a section to another section which is acting as a tab, or ignore tabs altogether to display all of your sections at once. The example below adds a tab and then adds a sub-section to that tab.
|
200 |
+
|
201 |
+
**page_id**
|
202 |
+
|
203 |
+
Page this section should be attached to. Must match the id passed in add_page().
|
204 |
+
|
205 |
+
**args**
|
206 |
+
|
207 |
+
An array of properties to pass to the section.
|
208 |
+
|
209 |
+
*id*
|
210 |
+
|
211 |
+
(required)
|
212 |
+
Unique slug to which settings will be attached.
|
213 |
+
|
214 |
+
*title*
|
215 |
+
(required)
|
216 |
+
|
217 |
+
This will be displayed at the top of the settings section.
|
218 |
+
|
219 |
+
*description*
|
220 |
+
(optional)
|
221 |
+
|
222 |
+
An optional description to display below the title.
|
223 |
+
|
224 |
+
*is_tab*
|
225 |
+
(optional)
|
226 |
+
|
227 |
+
Set this to true if this section should act like a tab.
|
228 |
+
|
229 |
+
*tab*
|
230 |
+
(optional)
|
231 |
+
|
232 |
+
Use this to attach a section to an existing tab.
|
233 |
+
|
234 |
+
#### Add a section to a page with no tabs:
|
235 |
+
```
|
236 |
+
$sap->add_section(
|
237 |
+
$page_id,
|
238 |
+
$args = array(
|
239 |
+
'id' => 'basic-details-section',
|
240 |
+
'title' => __( 'Basic Details', SAP_TEXTDOMAIN ),
|
241 |
+
'description' => __( 'This section includes some basic details for you to configure.', SAP_TEXTDOMAIN )
|
242 |
+
)
|
243 |
+
);
|
244 |
+
```
|
245 |
+
|
246 |
+
#### Add a tab and a sub-section to a page with tabs:
|
247 |
+
```
|
248 |
+
/**
|
249 |
+
* Create a section that acts as a tab with the is_tab parameter.
|
250 |
+
*/
|
251 |
+
$sap->add_section(
|
252 |
+
$page_id,
|
253 |
+
$args = array(
|
254 |
+
'id' => 'tab-one',
|
255 |
+
'title' => __( 'Tab One', SAP_TEXTDOMAIN ),
|
256 |
+
'description' => __( 'This tab includes some settings for you to configure.', SAP_TEXTDOMAIN ),
|
257 |
+
'is_tab' => true,
|
258 |
+
)
|
259 |
+
);
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Create a sub-section of the tab we just created with the tab parameter.
|
263 |
+
*/
|
264 |
+
$sap->add_section(
|
265 |
+
$page_id,
|
266 |
+
$args = array(
|
267 |
+
'id' => 'section-one-under-tab-one',
|
268 |
+
'title' => __( 'Section One', SAP_TEXTDOMAIN ),
|
269 |
+
'description' => __( 'This section includes some settings for you to configure.', SAP_TEXTDOMAIN ),
|
270 |
+
'tab' => 'tab-one',
|
271 |
+
)
|
272 |
+
);
|
273 |
+
```
|
274 |
+
|
275 |
+
### sapLibrary::add_setting()
|
276 |
+
Create a new setting and attach to an existing section.
|
277 |
+
|
278 |
+
There are several types of settings, each with their own input arguments. I'll try to document it more in the future. For now, check out the AdminPageSetting.*.class.php files in /classes/.
|
279 |
+
|
280 |
+
**page_id**
|
281 |
+
(required)
|
282 |
+
|
283 |
+
Page this setting should be attached to. Must match the id passed in add_page().
|
284 |
+
|
285 |
+
**section_id**
|
286 |
+
(required)
|
287 |
+
|
288 |
+
Section this setting should be attached to. Must match the id passed in add_setting().
|
289 |
+
|
290 |
+
**type**
|
291 |
+
(required)
|
292 |
+
|
293 |
+
Type of setting to add. There are currently several types supported and you can extend the library with your own. I'll try to document this further. For now, you can see all the types supported by default at sapLibrary::get_setting_classname().
|
294 |
+
|
295 |
+
**args**
|
296 |
+
|
297 |
+
An array of properties to pass to the setting.
|
298 |
+
|
299 |
+
*id*
|
300 |
+
(required)
|
301 |
+
|
302 |
+
Unique slug under which the setting will be saved. You would then retrieve the setting with:
|
303 |
+
|
304 |
+
```
|
305 |
+
$options = get_option( $page_id );
|
306 |
+
$options[$setting_id];
|
307 |
+
```
|
308 |
+
|
309 |
+
*title*
|
310 |
+
(required)
|
311 |
+
|
312 |
+
Title of the setting. Typically acts as the field label.
|
313 |
+
|
314 |
+
*description*
|
315 |
+
(optional)
|
316 |
+
|
317 |
+
An optional description to display with the setting. Useful for instructions.
|
318 |
+
|
319 |
+
*...*
|
320 |
+
|
321 |
+
Several setting types have additional parameters. I'll try to document them further.
|
322 |
+
|
323 |
+
```
|
324 |
+
$sap->add_setting(
|
325 |
+
$page_id,
|
326 |
+
$section_id,
|
327 |
+
$type,
|
328 |
+
array(
|
329 |
+
'id' => 'my-first-setting',
|
330 |
+
'title' => __( 'My First Setting', SAP_TEXTDOMAIN ),
|
331 |
+
'description' => __( 'A demonstration of my first setting', SAP_TEXTDOMAIN );
|
332 |
+
...
|
333 |
+
)
|
334 |
+
);
|
335 |
+
```
|
336 |
+
|
337 |
+
### sapLibrary::add_admin_menus()
|
338 |
+
Once everything is configured, run this method to register the pages with WordPress.
|
339 |
+
|
340 |
+
```
|
341 |
+
// Before you run add_admin_menus, filter the whole library so that
|
342 |
+
// third-party addons can hook into your settings page to add new settings
|
343 |
+
// or adjust existing ones.
|
344 |
+
$sap = apply_filters( 'sap_page_setup', $sap );
|
345 |
+
|
346 |
+
$sap->add_admin_menus();
|
347 |
+
```
|
348 |
+
|
349 |
+
### Backwards Compatibility
|
350 |
+
Version 2.0 introduced changes which break backwards compatibility due to the way that the library now stores data in the database. If you are upgrading the version of this library used in your plugin or theme, you must call ```$sap->port_data(2);``` **after** you have declared all of your settings but **before** you call ```$sap->add_admin_menus();```.
|
351 |
+
|
352 |
+
*Note: to ensure all of the old options are found and ported, you shouldn't change any of the structure or ids of your settings. Just drop this method into your existing flow.*
|
353 |
+
|
354 |
+
This changes the way that your settings are stored in the database. Previously, each setting was stored as its own option. Now all the settings on a page are stored in one row.
|
355 |
+
|
356 |
+
You will need to update your plugin to retrieve the settings from their new location. If you previously accessed a setting this way:
|
357 |
+
|
358 |
+
```
|
359 |
+
$my_setting = get_option( $my_setting_id );
|
360 |
+
```
|
361 |
+
|
362 |
+
You should now access the setting this way:
|
363 |
+
|
364 |
+
```
|
365 |
+
$all_page_settings = get_option( $settings_page_id );
|
366 |
+
$all_page_settings[ $my_setting_id ];
|
367 |
+
```
|
368 |
+
|
369 |
+
## Changelog
|
370 |
+
|
371 |
+
- 2.0.a.5 - 2014-05-15
|
372 |
+
- Fix a bug with the Textarea component callback
|
373 |
+
|
374 |
+
- 2.0.a.4 - 2014-05-15
|
375 |
+
- Only load assets when component is called
|
376 |
+
- Revert adding version number to script handles
|
377 |
+
- Fix localized script handler for Scheduler
|
378 |
+
- Fix pickadate CSS rule specificity
|
379 |
+
|
380 |
+
- 2.0.a.3 - 2014-05-14
|
381 |
+
- Fix undefined function error in Scheduler javascript when using Firefox
|
382 |
+
- Add version number to style and script handles so different versions will be enqueued
|
383 |
+
|
384 |
+
- 2.0.a.2 - 2014-05-11
|
385 |
+
- Add support for top-level menus
|
386 |
+
- Support line breaks in textarea components
|
387 |
+
|
388 |
+
- 2.0.a.1 - 2014-04-03
|
389 |
+
- Save all data on a page as one row in wp_options
|
390 |
+
|
391 |
+
- 1.1 - never released
|
392 |
+
- Support themes pages
|
393 |
+
- Support submenu pages for custom menu items
|
394 |
+
|
395 |
+
- 1.0 - 2013-11-20
|
396 |
+
- Initial release
|
lib/simple-admin-pages/classes/AdminPage.Menu.class.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an settings page as a submenu item in the
|
5 |
+
* WordPress admin menu.
|
6 |
+
*
|
7 |
+
* @since 1.1
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
|
11 |
+
class sapAdminPageMenu_2_0_a_5 extends sapAdminPage_2_0_a_5 {
|
12 |
+
|
13 |
+
public $setup_function = 'add_menu_page'; // WP function to register the page
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Add the page to the appropriate menu slot.
|
17 |
+
* @since 1.0
|
18 |
+
*/
|
19 |
+
public function add_admin_menu() {
|
20 |
+
|
21 |
+
call_user_func(
|
22 |
+
$this->setup_function,
|
23 |
+
$this->title,
|
24 |
+
$this->menu_title,
|
25 |
+
$this->capability,
|
26 |
+
$this->id,
|
27 |
+
array( $this, 'display_admin_menu' ),
|
28 |
+
$this->icon,
|
29 |
+
$this->position
|
30 |
+
);
|
31 |
+
}
|
32 |
+
}
|
lib/simple-admin-pages/classes/AdminPage.Submenu.class.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an settings page as a submenu item in the
|
5 |
+
* WordPress admin menu.
|
6 |
+
*
|
7 |
+
* @since 1.1
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
|
11 |
+
class sapAdminPageSubmenu_2_0_a_5 extends sapAdminPage_2_0_a_5 {
|
12 |
+
|
13 |
+
public $setup_function = 'add_submenu_page'; // WP function to register the page
|
14 |
+
|
15 |
+
public $parent_menu = null; // Which menu to attach this submenu page to
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Add the page to the appropriate menu slot.
|
19 |
+
* @since 1.0
|
20 |
+
*/
|
21 |
+
public function add_admin_menu() {
|
22 |
+
|
23 |
+
// Don't register if no parent menu is specified
|
24 |
+
if ( !$this->parent_menu ) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
+
call_user_func(
|
29 |
+
$this->setup_function,
|
30 |
+
$this->parent_menu,
|
31 |
+
$this->title,
|
32 |
+
$this->menu_title,
|
33 |
+
$this->capability,
|
34 |
+
$this->id,
|
35 |
+
array( $this, 'display_admin_menu' )
|
36 |
+
);
|
37 |
+
}
|
38 |
+
}
|
lib/simple-admin-pages/classes/AdminPage.Themes.class.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a settings page in the WordPress admin Appearance
|
5 |
+
* menu.
|
6 |
+
*
|
7 |
+
* @since 1.0
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
|
11 |
+
class sapAdminPageThemes_2_0_a_5 extends sapAdminPage_2_0_a_5 {
|
12 |
+
|
13 |
+
public $setup_function = 'add_theme_page'; // WP function to register the page
|
14 |
+
|
15 |
+
}
|
lib/simple-admin-pages/classes/AdminPage.class.php
ADDED
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a settings page in the WordPress admin menu.
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPage_2_0_a_5 {
|
11 |
+
|
12 |
+
public $title;
|
13 |
+
public $menu_title;
|
14 |
+
public $description; // optional description for this page
|
15 |
+
public $capability; // user permissions needed to edit this panel
|
16 |
+
public $id; // id of this page
|
17 |
+
public $sections = array(); // array of sections to display on this page
|
18 |
+
public $show_button = true; // whether or not to show the Save Changes button
|
19 |
+
|
20 |
+
public $setup_function = 'add_options_page'; // WP function to register the page
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Initialize the page
|
25 |
+
* @since 1.0
|
26 |
+
*/
|
27 |
+
public function __construct( $args ) {
|
28 |
+
|
29 |
+
// Parse the values passed
|
30 |
+
$this->parse_args( $args );
|
31 |
+
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Parse the arguments passed in the construction and assign them to
|
36 |
+
* internal variables.
|
37 |
+
* @since 1.1
|
38 |
+
*/
|
39 |
+
private function parse_args( $args ) {
|
40 |
+
foreach ( $args as $key => $val ) {
|
41 |
+
switch ( $key ) {
|
42 |
+
|
43 |
+
case 'id' :
|
44 |
+
$this->{$key} = esc_attr( $val );
|
45 |
+
|
46 |
+
default :
|
47 |
+
$this->{$key} = $val;
|
48 |
+
|
49 |
+
}
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Add the page to the appropriate menu slot.
|
55 |
+
* @note The default will be to post to the options page, but other classes
|
56 |
+
* should override this function.
|
57 |
+
* @since 1.0
|
58 |
+
*/
|
59 |
+
public function add_admin_menu() {
|
60 |
+
call_user_func( $this->setup_function, $this->title, $this->menu_title, $this->capability, $this->id, array( $this, 'display_admin_menu' ) );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Add a section to the page
|
65 |
+
* @since 1.0
|
66 |
+
*/
|
67 |
+
public function add_section( $section ) {
|
68 |
+
|
69 |
+
if ( !$section ) {
|
70 |
+
return;
|
71 |
+
}
|
72 |
+
|
73 |
+
$this->sections[ $section->id ] = $section;
|
74 |
+
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Register the settings and sanitization callbacks for each setting
|
79 |
+
* @since 1.0
|
80 |
+
*/
|
81 |
+
public function register_admin_menu() {
|
82 |
+
|
83 |
+
foreach ( $this->sections as $section ) {
|
84 |
+
$section->add_settings_section();
|
85 |
+
|
86 |
+
foreach ( $section->settings as $setting ) {
|
87 |
+
$setting->add_settings_field( $section->id );
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
register_setting( $this->id, $this->id, array( $this, 'sanitize_callback' ) );
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Loop through the settings and sanitize the data
|
96 |
+
* @since 2.0
|
97 |
+
*/
|
98 |
+
public function sanitize_callback( $value ) {
|
99 |
+
|
100 |
+
if ( empty( $_POST['_wp_http_referer'] ) ) {
|
101 |
+
return $value;
|
102 |
+
}
|
103 |
+
|
104 |
+
// Get the current page/tab so we only update those settings
|
105 |
+
parse_str( $_POST['_wp_http_referer'], $referrer );
|
106 |
+
$current_page = $this->get_current_page( $referrer );
|
107 |
+
|
108 |
+
// Use a new empty value so only values for settings that were added are
|
109 |
+
// passed to the db.
|
110 |
+
$new_value = array();
|
111 |
+
|
112 |
+
foreach ( $this->sections as $section ) {
|
113 |
+
foreach ( $section->settings as $setting ) {
|
114 |
+
if ( $setting->tab == $current_page ) {
|
115 |
+
$setting_value = isset( $value[$setting->id] ) ? $value[$setting->id] : '';
|
116 |
+
$new_value[$setting->id] = $setting->sanitize_callback_wrapper( $setting_value );
|
117 |
+
}
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
// Pull in the existing values so we never overwrite values that were
|
122 |
+
// on a different tab
|
123 |
+
$old_value = get_option( $this->id );
|
124 |
+
|
125 |
+
if ( is_array( $old_value ) ) {
|
126 |
+
return array_merge( $old_value, $new_value );
|
127 |
+
} else {
|
128 |
+
return $new_value;
|
129 |
+
}
|
130 |
+
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Get the current page/tab being viewed
|
135 |
+
* @since 2.0
|
136 |
+
*/
|
137 |
+
public function get_current_page( $request ) {
|
138 |
+
|
139 |
+
if ( !empty( $request['tab'] ) ) {
|
140 |
+
return $request['tab'];
|
141 |
+
} elseif ( !empty( $this->default_tab ) ) {
|
142 |
+
return $this->default_tab;
|
143 |
+
} else {
|
144 |
+
return $this->id;
|
145 |
+
}
|
146 |
+
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Output the settings passed to this page
|
151 |
+
* @since 1.0
|
152 |
+
*/
|
153 |
+
public function display_admin_menu() {
|
154 |
+
|
155 |
+
if ( !$this->title && !count( $this->settings ) ) {
|
156 |
+
return;
|
157 |
+
}
|
158 |
+
|
159 |
+
$current_page = $this->get_current_page( $_GET );
|
160 |
+
|
161 |
+
?>
|
162 |
+
|
163 |
+
<div class="wrap">
|
164 |
+
|
165 |
+
<?php $this->display_page_title(); ?>
|
166 |
+
|
167 |
+
<?php if ( isset( $this->default_tab ) ) : ?>
|
168 |
+
<h2 class="nav-tab-wrapper">
|
169 |
+
<?php
|
170 |
+
foreach( $this->sections as $section ) {
|
171 |
+
|
172 |
+
if ( isset( $section->is_tab ) && $section->is_tab === true ) {
|
173 |
+
|
174 |
+
$tab_url = add_query_arg(
|
175 |
+
array(
|
176 |
+
'settings-updated' => false,
|
177 |
+
'tab' => $section->id
|
178 |
+
)
|
179 |
+
);
|
180 |
+
|
181 |
+
$active = $current_page == $section->id ? ' nav-tab-active' : '';
|
182 |
+
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $section->title ) . '" class="nav-tab' . $active . '">';
|
183 |
+
echo esc_html( $section->title );
|
184 |
+
echo '</a>';
|
185 |
+
}
|
186 |
+
}
|
187 |
+
?>
|
188 |
+
</h2>
|
189 |
+
<?php endif; ?>
|
190 |
+
|
191 |
+
<form method="post" action="options.php">
|
192 |
+
<?php settings_fields( $this->id ); ?>
|
193 |
+
<?php do_settings_sections( $current_page ); ?>
|
194 |
+
<?php if ( $this->show_button ) { submit_button(); } ?>
|
195 |
+
</form>
|
196 |
+
</div>
|
197 |
+
|
198 |
+
<?php
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Output the title of the page
|
203 |
+
* @since 1.0
|
204 |
+
*/
|
205 |
+
public function display_page_title() {
|
206 |
+
|
207 |
+
if ( empty( $this->title ) ) {
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
?>
|
211 |
+
<h2><?php echo $this->title; ?></h2>
|
212 |
+
<?php
|
213 |
+
}
|
214 |
+
|
215 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSection.class.php
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a section on a custom admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSection_2_0_a_5 {
|
11 |
+
|
12 |
+
// Page defaults
|
13 |
+
public $id; // unique id for this section
|
14 |
+
public $title; // optional title to display above this section
|
15 |
+
public $description; // optional description of the section
|
16 |
+
public $settings = array(); // Array of settings to display in this option set
|
17 |
+
|
18 |
+
// Array to store errors
|
19 |
+
public $errors = array();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Initialize the section
|
23 |
+
* @since 1.0
|
24 |
+
*/
|
25 |
+
public function __construct( $args ) {
|
26 |
+
|
27 |
+
// Parse the values passed
|
28 |
+
$this->parse_args( $args );
|
29 |
+
|
30 |
+
// Set an error if there is no id for this section
|
31 |
+
if ( !isset( $this->id ) ) {
|
32 |
+
$this->set_error(
|
33 |
+
array(
|
34 |
+
'type' => 'missing_data',
|
35 |
+
'data' => 'id'
|
36 |
+
)
|
37 |
+
);
|
38 |
+
}
|
39 |
+
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Parse the arguments passed in the construction and assign them to
|
44 |
+
* internal variables.
|
45 |
+
* @since 1.0
|
46 |
+
*/
|
47 |
+
private function parse_args( $args ) {
|
48 |
+
foreach ( $args as $key => $val ) {
|
49 |
+
switch ( $key ) {
|
50 |
+
|
51 |
+
case 'id' :
|
52 |
+
$this->{$key} = esc_attr( $val );
|
53 |
+
|
54 |
+
default :
|
55 |
+
$this->{$key} = $val;
|
56 |
+
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Add a setting to this section
|
63 |
+
* @since 1.0
|
64 |
+
*/
|
65 |
+
public function add_setting( $setting ) {
|
66 |
+
if ( !$setting ) {
|
67 |
+
return;
|
68 |
+
}
|
69 |
+
|
70 |
+
$this->settings[ $setting->id ] = $setting;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Display the description for this section
|
75 |
+
* @since 1.0
|
76 |
+
*/
|
77 |
+
public function display_section() {
|
78 |
+
|
79 |
+
if ( !count( $this->settings ) ) {
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
|
83 |
+
if ( !empty( $this->description ) ) :
|
84 |
+
?>
|
85 |
+
|
86 |
+
<p class="description"><?php echo $this->description; ?></p>
|
87 |
+
|
88 |
+
<?php
|
89 |
+
endif;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Add the settings section to the page in WordPress
|
94 |
+
* @since 1.0
|
95 |
+
*/
|
96 |
+
public function add_settings_section() {
|
97 |
+
add_settings_section( $this->id, $this->title, array( $this, 'display_section' ), $this->get_page_slug() );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Determine the page slug to use when calling add_settings_section.
|
102 |
+
*
|
103 |
+
* Tabs should use their own ID and settings that are attached to tabs
|
104 |
+
* should use that tab's ID.
|
105 |
+
* @since 2.0
|
106 |
+
*/
|
107 |
+
public function get_page_slug() {
|
108 |
+
if ( isset( $this->is_tab ) && $this->is_tab === true ) {
|
109 |
+
return $this->id;
|
110 |
+
} elseif ( isset( $this->tab ) ) {
|
111 |
+
return $this->tab;
|
112 |
+
} else {
|
113 |
+
return $this->page;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Set an error
|
119 |
+
* @since 1.0
|
120 |
+
*/
|
121 |
+
public function set_error( $error ) {
|
122 |
+
$this->errors[] = array_merge(
|
123 |
+
$error,
|
124 |
+
array(
|
125 |
+
'class' => get_class( $this ),
|
126 |
+
'id' => $this->id,
|
127 |
+
'backtrace' => debug_backtrace()
|
128 |
+
)
|
129 |
+
);
|
130 |
+
}
|
131 |
+
|
132 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Address.class.php
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a textarea field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 2.0.a.5
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingAddress_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
11 |
+
|
12 |
+
/*
|
13 |
+
* Size of this textarea
|
14 |
+
*
|
15 |
+
* This is put directly into a css class [size]-text,
|
16 |
+
* and setting this to 'large' will link into WordPress's existing textarea
|
17 |
+
* style for full-width textareas.
|
18 |
+
*/
|
19 |
+
public $size = 'small';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Scripts that must be loaded for this component
|
23 |
+
* @since 2.0.a.5
|
24 |
+
*/
|
25 |
+
public $scripts = array(
|
26 |
+
'sap-address' => array(
|
27 |
+
'path' => 'js/address.js',
|
28 |
+
'dependencies' => array( 'jquery' ),
|
29 |
+
'version' => '2.0.a.5',
|
30 |
+
'footer' => true,
|
31 |
+
),
|
32 |
+
);
|
33 |
+
|
34 |
+
public $sanitize_callback = 'sanitize_text_field';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Escape the value to display it safely HTML textarea fields
|
38 |
+
* @since 2.0.a.5
|
39 |
+
*/
|
40 |
+
public function esc_value( $val ) {
|
41 |
+
|
42 |
+
$escaped = array();
|
43 |
+
$escaped['text'] = empty( $val['text'] ) ? '' : esc_textarea( $val['text'] );
|
44 |
+
$escaped['lat'] = empty( $val['lat'] ) ? '' : esc_textarea( $val['lat'] );
|
45 |
+
$escaped['lon'] = empty( $val['lon'] ) ? '' : esc_textarea( $val['lon'] );
|
46 |
+
|
47 |
+
return $escaped;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Set the size of this textarea field
|
52 |
+
* @since 1.0
|
53 |
+
*/
|
54 |
+
public function set_size( $size ) {
|
55 |
+
$this->size = esc_attr( $size );
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Wrapper for the sanitization callback function.
|
60 |
+
*
|
61 |
+
* This just reduces code duplication for child classes that need a custom
|
62 |
+
* callback function.
|
63 |
+
* @since 2.0.a.5
|
64 |
+
*/
|
65 |
+
public function sanitize_callback_wrapper( $value ) {
|
66 |
+
|
67 |
+
$sanitized = array();
|
68 |
+
$sanitized['text'] = empty( $value['text'] ) ? '' : wp_kses_post( $value['text'] );
|
69 |
+
$sanitized['lat'] = empty( $value['lat'] ) ? '' : sanitize_text_field( $value['lat'] );
|
70 |
+
$sanitized['lon'] = empty( $value['lon'] ) ? '' : sanitize_text_field( $value['lon'] );
|
71 |
+
|
72 |
+
return $sanitized;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Display this setting
|
77 |
+
* @since 2.0.a.5
|
78 |
+
*/
|
79 |
+
public function display_setting() {
|
80 |
+
|
81 |
+
$strings = array(
|
82 |
+
'sep-lat-lon' => _x( ', ', 'separates latitude and longitude', SAP_TEXTDOMAIN ),
|
83 |
+
'no-setting' => __( 'No map coordinates set.', SAP_TEXTDOMAIN ),
|
84 |
+
'retrieving' => __( 'Requesting new coordinates', SAP_TEXTDOMAIN ),
|
85 |
+
'select' => __( 'Select a match below', SAP_TEXTDOMAIN ),
|
86 |
+
'view' => __( 'View', SAP_TEXTDOMAIN ),
|
87 |
+
'retrieve' => __( 'Retrieve map coordinates', SAP_TEXTDOMAIN ),
|
88 |
+
'remove' => __( 'Remove map coordinates', SAP_TEXTDOMAIN ),
|
89 |
+
'try_again' => __( 'Try again?', SAP_TEXTDOMAIN ),
|
90 |
+
'result_error' => __( 'Error', SAP_TEXTDOMAIN ),
|
91 |
+
'result_invalid' => __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', SAP_TEXTDOMAIN ),
|
92 |
+
'result_denied' => __( 'Request denied.', SAP_TEXTDOMAIN ),
|
93 |
+
'result_limit' => __( 'Request denied because you are over your request quota.', SAP_TEXTDOMAIN ),
|
94 |
+
'result_empty' => __( 'Nothing was found at that address', SAP_TEXTDOMAIN ),
|
95 |
+
);
|
96 |
+
|
97 |
+
wp_localize_script(
|
98 |
+
'sap-address',
|
99 |
+
'sap_address',
|
100 |
+
array(
|
101 |
+
'strings' => $strings,
|
102 |
+
)
|
103 |
+
);
|
104 |
+
|
105 |
+
$this->display_description();
|
106 |
+
|
107 |
+
?>
|
108 |
+
|
109 |
+
<div class="sap-address" id="<?php echo $this->id; ?>">
|
110 |
+
<textarea name="<?php echo $this->get_input_name(); ?>[text]" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?>><?php echo $this->value['text']; ?></textarea>
|
111 |
+
<p class="sap-map-coords-wrapper">
|
112 |
+
<span class="dashicons dashicons-location-alt"></span>
|
113 |
+
<span class="sap-map-coords">
|
114 |
+
<?php if ( empty( $this->value['lat'] ) || empty( $this->value['lon'] ) ) : ?>
|
115 |
+
<?php echo $strings['no-setting']; ?>
|
116 |
+
<?php else : ?>
|
117 |
+
<?php echo $this->value['lat'] . $strings['sep-lat-lon'] . $this->value['lon']; ?>
|
118 |
+
<a href="//maps.google.com/maps?q=<?php echo esc_attr( $this->value['lat'] ) . ',' . esc_attr( $this->value['lon'] ); ?>" class="sap-view-coords" target="_blank"><?php echo $strings['view']; ?></a>
|
119 |
+
<?php endif; ?>
|
120 |
+
</span>
|
121 |
+
</p>
|
122 |
+
<p class="sap-coords-action-wrapper">
|
123 |
+
<a href="#" class="sap-get-coords">
|
124 |
+
<?php echo $strings['retrieve']; ?>
|
125 |
+
</a>
|
126 |
+
<?php _ex( ' | ', 'separator between admin action links in address component', SAP_TEXTDOMAIN ); ?>
|
127 |
+
<a href="#" class="sap-remove-coords">
|
128 |
+
<?php echo $strings['remove']; ?>
|
129 |
+
</a>
|
130 |
+
</p>
|
131 |
+
<input type="hidden" class="lat" name="<?php echo $this->get_input_name(); ?>[lat]" value="<?php echo $this->value['lat']; ?>">
|
132 |
+
<input type="hidden" class="lon" name="<?php echo $this->get_input_name(); ?>[lon]" value="<?php echo $this->value['lon']; ?>">
|
133 |
+
</div>
|
134 |
+
|
135 |
+
<?php
|
136 |
+
}
|
137 |
+
|
138 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Editor.class.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a TinyMC Editor field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingEditor_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'wp_kses_post';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* List of arguments accepted by wp_editor
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $args = array();
|
19 |
+
|
20 |
+
/**
|
21 |
+
* wp_editor() will handle the escaping
|
22 |
+
* @since 2.0
|
23 |
+
*/
|
24 |
+
public function esc_value( $val ) {
|
25 |
+
return $val;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Display this setting
|
30 |
+
* @since 2.0
|
31 |
+
*/
|
32 |
+
public function display_setting() {
|
33 |
+
|
34 |
+
$this->args['textarea_name'] = $this->get_input_name();
|
35 |
+
|
36 |
+
$value = empty( $this->value ) && !empty( $this->default ) ? $this->default : $this->value;
|
37 |
+
|
38 |
+
wp_editor( $value, preg_replace( '/[^\da-z]/i', '', $this->id), $this->args );
|
39 |
+
|
40 |
+
$this->display_description();
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.HTML.class.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register and save an arbitrary HTML chunk in the admin menu
|
5 |
+
*
|
6 |
+
* This allows you to easily add in a dummy "setting" with any arbitrary HTML
|
7 |
+
* code. It's good for displaying a link to documentation, upgrades or anything
|
8 |
+
* else you can think of.
|
9 |
+
*
|
10 |
+
* Data in this field will not be saved or passed. It's purely for presenting
|
11 |
+
* information.
|
12 |
+
*
|
13 |
+
* @since 1.0
|
14 |
+
* @package Simple Admin Pages
|
15 |
+
*/
|
16 |
+
|
17 |
+
class sapAdminPageSettingHTML_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
18 |
+
|
19 |
+
public $sanitize_callback = 'sanitize_text_field';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Display this setting
|
23 |
+
* @since 1.0
|
24 |
+
*/
|
25 |
+
public function display_setting() {
|
26 |
+
|
27 |
+
echo $this->html;
|
28 |
+
|
29 |
+
$this->display_description();
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.OpeningHours.class.php
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a series of fields to specify the opening hours
|
5 |
+
* of a business/company.
|
6 |
+
*
|
7 |
+
* This setting accepts the following arguments in its constructor function.
|
8 |
+
*
|
9 |
+
* $args = array(
|
10 |
+
* 'id' => 'setting_id', // Unique id
|
11 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
12 |
+
* 'description' => 'Description', // Help text description
|
13 |
+
* 'weekday_names' => array( // Optional array of custom
|
14 |
+
* 'monday' => 'Monday', // weekday names. These can be
|
15 |
+
* 'tuesday' => 'Tuesday', // passed in any order to
|
16 |
+
* 'wednesday' => 'Wednesday', // set a new start of the week.
|
17 |
+
* 'thursday' => 'Thursday',
|
18 |
+
* 'friday' => 'Friday',
|
19 |
+
* 'saturday' => 'Saturday',
|
20 |
+
* 'sunday' => 'Sunday'
|
21 |
+
* );
|
22 |
+
* );
|
23 |
+
*
|
24 |
+
* @since 1.0
|
25 |
+
* @package Simple Admin Pages
|
26 |
+
*/
|
27 |
+
|
28 |
+
class sapAdminPageSettingOpeningHours_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
29 |
+
|
30 |
+
public $sanitize_callback = 'sanitize_text_field';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Scripts that must be loaded for this component
|
34 |
+
* @since 2.0.a.4
|
35 |
+
*/
|
36 |
+
public $scripts = array(
|
37 |
+
'sap-opening-hours' => array(
|
38 |
+
'path' => 'js/opening-hours.js',
|
39 |
+
'dependencies' => array( 'jquery' ),
|
40 |
+
'version' => '2.0.a.5',
|
41 |
+
'footer' => true,
|
42 |
+
),
|
43 |
+
);
|
44 |
+
|
45 |
+
// Array of days of the week
|
46 |
+
public $weekdays = array(
|
47 |
+
'monday' => 'Monday',
|
48 |
+
'tuesday' => 'Tuesday',
|
49 |
+
'wednesday' => 'Wednesday',
|
50 |
+
'thursday' => 'Thursday',
|
51 |
+
'friday' => 'Friday',
|
52 |
+
'saturday' => 'Saturday',
|
53 |
+
'sunday' => 'Sunday'
|
54 |
+
);
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Parse the arguments passed in the construction and assign them to
|
58 |
+
* internal variables.
|
59 |
+
* @since 1.0
|
60 |
+
*/
|
61 |
+
private function parse_args( $args ) {
|
62 |
+
foreach ( $args as $key => $val ) {
|
63 |
+
switch ( $key ) {
|
64 |
+
|
65 |
+
case 'id' :
|
66 |
+
$this->{$key} = esc_attr( $val );
|
67 |
+
|
68 |
+
case 'weekdays' :
|
69 |
+
|
70 |
+
$this->weekdays = $val;
|
71 |
+
|
72 |
+
default :
|
73 |
+
$this->{$key} = $val;
|
74 |
+
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Escape the value to display it in text fields and other input fields
|
81 |
+
*
|
82 |
+
* @since 1.0
|
83 |
+
*/
|
84 |
+
public function esc_value( $val ) {
|
85 |
+
|
86 |
+
$value = array();
|
87 |
+
|
88 |
+
// Loop over the values and sanitize them
|
89 |
+
for ( $i = 0; $i < 7; $i++ ) {
|
90 |
+
$value[$i]['day'] = isset( $val[$i] ) && isset( $val[$i]['day'] ) ? esc_attr( $val[$i]['day'] ) : '';
|
91 |
+
$value[$i]['hours'] = isset( $val[$i] ) && isset( $val[$i]['hours'] ) ? esc_attr( $val[$i]['hours'] ) : '';
|
92 |
+
}
|
93 |
+
|
94 |
+
return $value;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Get a day's display name
|
99 |
+
* @since 1.0
|
100 |
+
*/
|
101 |
+
private function get_day_name( $day ) {
|
102 |
+
foreach ( $this->weekdays as $id => $name ) {
|
103 |
+
if ( $day == $id ) {
|
104 |
+
return $name;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
return '';
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Display this setting
|
113 |
+
* @since 1.0
|
114 |
+
* @todo integrate time picker
|
115 |
+
*/
|
116 |
+
public function display_setting() {
|
117 |
+
|
118 |
+
$this->display_description();
|
119 |
+
|
120 |
+
for ($i = 0; $i < 7; $i++) {
|
121 |
+
|
122 |
+
?>
|
123 |
+
|
124 |
+
<table class="sap-opening-hours">
|
125 |
+
<tr>
|
126 |
+
<td>
|
127 |
+
<input type="hidden" id="sap-opening-hours-day-<?php echo $i; ?>-name" name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][day_name]" value="<?php echo esc_attr( $this->get_day_name( $this->value[$i]['day'] ) ); ?>">
|
128 |
+
<select name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][day]" id="<?php echo $this->id . '-' . $i; ?>-day" class="sap-opening-hours-day" data-target="#sap-opening-hours-day-<?php echo $i; ?>-name">
|
129 |
+
<option value=""></option>
|
130 |
+
|
131 |
+
<?php foreach ( $this->weekdays as $id => $name ) : ?>
|
132 |
+
|
133 |
+
<option value="<?php echo $id; ?>" data-name="<?php echo esc_attr( $name ); ?>"<?php if ( $this->value[$i]['day'] == $id ) : ?> selected<?php endif; ?>>
|
134 |
+
<?php echo $name; ?>
|
135 |
+
</option>
|
136 |
+
|
137 |
+
<?php endforeach; ?>
|
138 |
+
|
139 |
+
</select>
|
140 |
+
</td>
|
141 |
+
<td>
|
142 |
+
<input name="<?php echo $this->get_input_name(); ?>[<?php echo $i; ?>][hours]" type="text" id="<?php echo $this->id . '-' . $i; ?>-hours" value="<?php echo $this->value[$i]['hours']; ?>" class="regular-text sap-opening-hours-hours" />
|
143 |
+
</td>
|
144 |
+
</tr>
|
145 |
+
</table>
|
146 |
+
|
147 |
+
<?php
|
148 |
+
|
149 |
+
}
|
150 |
+
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Sanitize the array of text inputs for this setting
|
155 |
+
* @since 1.0
|
156 |
+
*/
|
157 |
+
public function sanitize_callback_wrapper( $values ) {
|
158 |
+
|
159 |
+
// If no sanitization callback exists, don't register the setting.
|
160 |
+
if ( !isset( $this->sanitize_callback ) || !trim( $this->sanitize_callback ) ) {
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
|
164 |
+
// If this isn't an array, just sanitize it as a string
|
165 |
+
if (!is_array( $values ) ) {
|
166 |
+
return call_user_func( $this->sanitize_callback, $values );
|
167 |
+
}
|
168 |
+
|
169 |
+
// Loop over the values and sanitize them
|
170 |
+
for ( $i = 0; $i < 7; $i++ ) {
|
171 |
+
if ( isset( $values[ $i ] ) && is_array( $values[ $i ] ) ) {
|
172 |
+
$values[$i]['day'] = call_user_func( $this->sanitize_callback, $values[$i]['day'] );
|
173 |
+
$values[$i]['hours'] = call_user_func( $this->sanitize_callback, $values[$i]['hours'] );
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
return $values;
|
178 |
+
}
|
179 |
+
|
180 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php
ADDED
@@ -0,0 +1,664 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a schedule of dates and times.
|
5 |
+
*
|
6 |
+
* This is designed for use for opening hours, a booking schedule or anything
|
7 |
+
* that requires recurring dates and times.
|
8 |
+
*
|
9 |
+
* @since 2.0
|
10 |
+
* @package Simple Admin Pages
|
11 |
+
*/
|
12 |
+
|
13 |
+
class sapAdminPageSettingScheduler_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
14 |
+
|
15 |
+
public $sanitize_callback = 'sanitize_text_field';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Scripts that must be loaded for this component
|
19 |
+
* @since 2.0.a.4
|
20 |
+
*/
|
21 |
+
public $scripts = array(
|
22 |
+
'pickadate' => array(
|
23 |
+
'path' => 'lib/pickadate/picker.js',
|
24 |
+
'dependencies' => array( 'jquery' ),
|
25 |
+
'version' => '3.5.0',
|
26 |
+
'footer' => true,
|
27 |
+
),
|
28 |
+
'pickadate-date' => array(
|
29 |
+
'path' => 'lib/pickadate/picker.date.js',
|
30 |
+
'dependencies' => array( 'jquery' ),
|
31 |
+
'version' => '3.5.0',
|
32 |
+
'footer' => true,
|
33 |
+
),
|
34 |
+
'pickadate-time' => array(
|
35 |
+
'path' => 'lib/pickadate/picker.time.js',
|
36 |
+
'dependencies' => array( 'jquery' ),
|
37 |
+
'version' => '3.5.0',
|
38 |
+
'footer' => true,
|
39 |
+
),
|
40 |
+
'pickadate-legacy' => array(
|
41 |
+
'path' => 'lib/pickadate/legacy.js',
|
42 |
+
'dependencies' => array( 'jquery' ),
|
43 |
+
'version' => '3.5.0',
|
44 |
+
'footer' => true,
|
45 |
+
),
|
46 |
+
'sap-scheduler' => array(
|
47 |
+
'path' => 'js/scheduler.js',
|
48 |
+
'dependencies' => array( 'jquery' ),
|
49 |
+
'version' => '2.0.a.5',
|
50 |
+
'footer' => true,
|
51 |
+
),
|
52 |
+
// @todo there should be some way to load alternate language .js files
|
53 |
+
// and RTL CSS scripts
|
54 |
+
);
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Styles that must be loaded for this component
|
58 |
+
* @since 2.0.a.4
|
59 |
+
*/
|
60 |
+
public $styles = array(
|
61 |
+
'pickadate-default' => array(
|
62 |
+
'path' => 'lib/pickadate/themes/default.css',
|
63 |
+
'dependencies' => '',
|
64 |
+
'version' => '3.5.0',
|
65 |
+
'media' => null,
|
66 |
+
),
|
67 |
+
'pickadate-date' => array(
|
68 |
+
'path' => 'lib/pickadate/themes/default.date.css',
|
69 |
+
'dependencies' => '',
|
70 |
+
'version' => '3.5.0',
|
71 |
+
'media' => null,
|
72 |
+
),
|
73 |
+
'pickadate-time' => array(
|
74 |
+
'path' => 'lib/pickadate/themes/default.time.css',
|
75 |
+
'dependencies' => '',
|
76 |
+
'version' => '3.5.0',
|
77 |
+
'media' => null,
|
78 |
+
),
|
79 |
+
);
|
80 |
+
|
81 |
+
public $weekdays = array(
|
82 |
+
'monday' => 'Mo',
|
83 |
+
'tuesday' => 'Tu',
|
84 |
+
'wednesday' => 'We',
|
85 |
+
'thursday' => 'Th',
|
86 |
+
'friday' => 'Fr',
|
87 |
+
'saturday' => 'Sa',
|
88 |
+
'sunday' => 'Su',
|
89 |
+
);
|
90 |
+
|
91 |
+
public $weeks = array(
|
92 |
+
'first' => '1st',
|
93 |
+
'second' => '2nd',
|
94 |
+
'third' => '3rd',
|
95 |
+
'fourth' => '4th',
|
96 |
+
'last' => 'last',
|
97 |
+
);
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Number of minutes between time selection intervals
|
101 |
+
*/
|
102 |
+
public $time_interval = 15;
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Display format for time selection
|
106 |
+
* See http://amsul.ca/pickadate.js/ for formatting options
|
107 |
+
*/
|
108 |
+
public $time_format = 'h:i A';
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Display format for date selection
|
112 |
+
* See http://amsul.ca/pickadate.js/ for formatting options
|
113 |
+
*/
|
114 |
+
public $date_format = 'd mmmm, yyyy';
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Boolean to disable the weekday selection option
|
118 |
+
*/
|
119 |
+
public $disable_weekdays = false;
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Boolean to disable the weeks selection option
|
123 |
+
*/
|
124 |
+
public $disable_weeks = false;
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Boolean to disable the date selection option
|
128 |
+
*/
|
129 |
+
public $disable_date = false;
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Boolean to disable the time selection option
|
133 |
+
*/
|
134 |
+
public $disable_time = false;
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Boolean to disable the end time selection option
|
138 |
+
*/
|
139 |
+
public $disable_end_time = false;
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Array containing strings for schedule summaries. See the default
|
143 |
+
* summaries at set_schedule_summaries(). Use this to overwrite the defaults
|
144 |
+
* with anything more useful to this instance.
|
145 |
+
*/
|
146 |
+
public $instance_schedule_summaries;
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Escape the value to display it in text fields and other input fields
|
150 |
+
* @since 2.0
|
151 |
+
*/
|
152 |
+
public function esc_value( $val ) {
|
153 |
+
|
154 |
+
$value = array();
|
155 |
+
|
156 |
+
if ( empty( $val ) ) {
|
157 |
+
return $value;
|
158 |
+
}
|
159 |
+
|
160 |
+
foreach ( $val as $i => $rule ) {
|
161 |
+
|
162 |
+
if ( !empty( $rule['weekdays'] ) ) {
|
163 |
+
$value[$i]['weekdays'] = array();
|
164 |
+
foreach ( $rule['weekdays'] as $day => $flag ) {
|
165 |
+
if ( $flag !== '1' ) {
|
166 |
+
continue;
|
167 |
+
}
|
168 |
+
|
169 |
+
$value[$i]['weekdays'][$day] = $flag;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
if ( !empty( $rule['weeks'] ) ) {
|
174 |
+
$value[$i]['weeks'] = array();
|
175 |
+
foreach ( $rule['weeks'] as $week => $flag ) {
|
176 |
+
if ( $flag !== '1' ) {
|
177 |
+
continue;
|
178 |
+
}
|
179 |
+
|
180 |
+
$value[$i]['weeks'][$week] = $flag;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
if ( !empty( $rule['date'] ) ) {
|
185 |
+
$value[$i]['date'] = esc_attr( $rule['date'] );
|
186 |
+
}
|
187 |
+
|
188 |
+
if ( !empty( $rule['time']['start'] ) ) {
|
189 |
+
$value[$i]['time']['start'] = esc_attr( $rule['time']['start'] );
|
190 |
+
}
|
191 |
+
if ( !empty( $rule['time']['end'] ) ) {
|
192 |
+
$value[$i]['time']['end'] = esc_attr( $rule['time']['end'] );
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
return $value;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Compile and pass configurable variables to the javascript file, so they
|
201 |
+
* can be used when we initialize the pickadate components
|
202 |
+
* @since 2.0
|
203 |
+
*/
|
204 |
+
public function pass_to_scripts() {
|
205 |
+
|
206 |
+
// Create a global variable containing settings for all schedulers
|
207 |
+
// that are being rendered on the page. This allows us to pass different
|
208 |
+
// settings for different schedulers on the same page.
|
209 |
+
global $sap_scheduler_settings;
|
210 |
+
|
211 |
+
if ( !isset( $sap_scheduler_settings ) ) {
|
212 |
+
$sap_scheduler_settings = array();
|
213 |
+
}
|
214 |
+
|
215 |
+
$sap_scheduler_settings[ $this->id ] = array(
|
216 |
+
'time_interval' => $this->time_interval,
|
217 |
+
'time_format' => $this->time_format,
|
218 |
+
'date_format' => $this->date_format,
|
219 |
+
'template' => $this->get_template(),
|
220 |
+
'weekdays' => $this->weekdays,
|
221 |
+
'weeks' => $this->weeks,
|
222 |
+
'disable_weekdays' => $this->disable_weekdays,
|
223 |
+
'disable_weeks' => $this->disable_weeks,
|
224 |
+
'disable_date' => $this->disable_date,
|
225 |
+
'disable_time' => $this->disable_time,
|
226 |
+
'summaries' => $this->schedule_summaries,
|
227 |
+
);
|
228 |
+
|
229 |
+
// This gets called multiple times, but only the last call is actually
|
230 |
+
// pushed to the script.
|
231 |
+
wp_localize_script(
|
232 |
+
'sap-scheduler',
|
233 |
+
'sap_scheduler',
|
234 |
+
array(
|
235 |
+
'settings' => $sap_scheduler_settings
|
236 |
+
)
|
237 |
+
);
|
238 |
+
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Display this setting
|
243 |
+
* @since 2.0
|
244 |
+
*/
|
245 |
+
public function display_setting() {
|
246 |
+
|
247 |
+
$this->display_description();
|
248 |
+
|
249 |
+
// Define summary text to use when a rule is displayed in brief
|
250 |
+
$this->set_schedule_summaries();
|
251 |
+
|
252 |
+
// Pass data to the script files to handle js interactions
|
253 |
+
$this->pass_to_scripts();
|
254 |
+
|
255 |
+
?>
|
256 |
+
|
257 |
+
<div class="sap-scheduler" id="<?php echo $this->id; ?>">
|
258 |
+
<?php
|
259 |
+
foreach ( $this->value as $id => $rule ) {
|
260 |
+
echo $this->get_template( $id, $rule, true );
|
261 |
+
}
|
262 |
+
?>
|
263 |
+
</div>
|
264 |
+
<div class="sap-add-scheduler">
|
265 |
+
<a href="#" class="button">
|
266 |
+
<?php _e( 'Add new scheduling rule', SAP_TEXTDOMAIN ); ?>
|
267 |
+
</a>
|
268 |
+
</div>
|
269 |
+
|
270 |
+
<?php
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Retrieve the template for a scheduling rule
|
275 |
+
* @since 2.0
|
276 |
+
*/
|
277 |
+
public function get_template( $id = 0, $values = array(), $list = false ) {
|
278 |
+
|
279 |
+
$date_format = $this->get_date_format( $values );
|
280 |
+
$time_format = $this->get_time_format( $values );
|
281 |
+
|
282 |
+
ob_start();
|
283 |
+
?>
|
284 |
+
|
285 |
+
<div class="sap-scheduler-rule clearfix<?php echo $list ? ' list' : ''; ?>">
|
286 |
+
<div class="sap-scheduler-date <?php echo $date_format; echo $this->disable_time === true ? ' full-width' : ''; ?>">
|
287 |
+
<ul class="sap-selector">
|
288 |
+
|
289 |
+
<?php if ( !$this->has_multiple_date_formats() ) : ?>
|
290 |
+
<li>
|
291 |
+
<div class="dashicons dashicons-calendar"></div>
|
292 |
+
<?php if ( $date_format == 'weekly' ) : ?>
|
293 |
+
<?php _ex( 'Weekly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
294 |
+
<?php elseif ( $date_format == 'monthly' ) : ?>
|
295 |
+
<?php _ex( 'Monthly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
296 |
+
<?php elseif ( $date_format == 'date' ) : ?>
|
297 |
+
<?php _ex( 'Date', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
298 |
+
<?php endif; ?>
|
299 |
+
</li>
|
300 |
+
<?php else : ?>
|
301 |
+
|
302 |
+
<?php if ( $this->disable_weekdays === false ) : ?>
|
303 |
+
<li>
|
304 |
+
<div class="dashicons dashicons-calendar"></div>
|
305 |
+
<a href="#" data-format="weekly"<?php echo $date_format == 'weekly' ? ' class="selected"' : ''; ?>>
|
306 |
+
<?php _ex( 'Weekly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
307 |
+
</a>
|
308 |
+
</li>
|
309 |
+
<?php endif; ?>
|
310 |
+
|
311 |
+
<?php if ( $this->disable_weeks === false ) : ?>
|
312 |
+
<li>
|
313 |
+
<a href="#" data-format="monthly"<?php echo $date_format == 'monthly' ? ' class="selected"' : ''; ?>>
|
314 |
+
<?php _ex( 'Monthly', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
315 |
+
</a>
|
316 |
+
</li>
|
317 |
+
<?php endif; ?>
|
318 |
+
|
319 |
+
<?php if ( $this->disable_date === false ) : ?>
|
320 |
+
<li>
|
321 |
+
<a href="#" data-format="date"<?php echo $date_format == 'date' ? ' class="selected"' : ''; ?>>
|
322 |
+
<?php _ex( 'Date', 'Format of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
323 |
+
</a>
|
324 |
+
</li>
|
325 |
+
<?php endif; ?>
|
326 |
+
|
327 |
+
<?php endif; ?>
|
328 |
+
</ul>
|
329 |
+
|
330 |
+
<?php if ( $this->disable_weekdays === false ) : ?>
|
331 |
+
<ul class="sap-scheduler-weekdays">
|
332 |
+
<li class="label">
|
333 |
+
<?php _ex( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
334 |
+
</li>
|
335 |
+
<?php
|
336 |
+
foreach ( $this->weekdays as $slug => $label ) :
|
337 |
+
$input_name = $this->get_input_name() . '[' . $id . '][weekdays][' . esc_attr( $slug ) . ']';
|
338 |
+
?>
|
339 |
+
<li>
|
340 |
+
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php echo empty( $values['weekdays'][$slug] ) ? '' : ' checked="checked"'; ?> data-day="<?php echo esc_attr( $slug ); ?>"><label for="<?php echo $input_name; ?>"><?php echo ucfirst( $label ); ?></label>
|
341 |
+
</li>
|
342 |
+
<?php endforeach; ?>
|
343 |
+
</ul>
|
344 |
+
<?php endif; ?>
|
345 |
+
|
346 |
+
<?php if ( $this->disable_weeks === false ) : ?>
|
347 |
+
<ul class="sap-scheduler-weeks">
|
348 |
+
<li class="label">
|
349 |
+
<?php _ex( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
350 |
+
</li>
|
351 |
+
<?php
|
352 |
+
foreach ( $this->weeks as $slug => $label ) :
|
353 |
+
$input_name = $this->get_input_name() . '[' . $id . '][weeks][' . esc_attr( $slug ) . ']';
|
354 |
+
?>
|
355 |
+
<li>
|
356 |
+
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php echo empty( $values['weeks'][$slug] ) ? '' : ' checked="checked"'; ?> data-week="<?php echo esc_attr( $slug ); ?>"><label for="<?php echo $input_name; ?>"><?php echo ucfirst( $label ); ?></label>
|
357 |
+
</li>
|
358 |
+
<?php endforeach; ?>
|
359 |
+
</ul>
|
360 |
+
<?php endif; ?>
|
361 |
+
|
362 |
+
<?php if ( $this->disable_date === false ) : ?>
|
363 |
+
<div class="sap-scheduler-date-input">
|
364 |
+
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]">
|
365 |
+
<?php _e( 'Date', SAP_TEXTDOMAIN ); ?>
|
366 |
+
</label>
|
367 |
+
<input type="text" name="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" id="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][date]" value="<?php echo empty( $values['date'] ) ? '' : $values['date']; ?>">
|
368 |
+
</div>
|
369 |
+
<?php endif; ?>
|
370 |
+
|
371 |
+
</div>
|
372 |
+
|
373 |
+
<?php if ( $this->disable_time === false ) : ?>
|
374 |
+
<div class="sap-scheduler-time <?php echo $time_format; ?>">
|
375 |
+
|
376 |
+
<ul class="sap-selector">
|
377 |
+
<li>
|
378 |
+
<div class="dashicons dashicons-clock"></div>
|
379 |
+
<a href="#" data-format="time-slot"<?php echo $time_format == 'time-slot' ? ' class="selected"' : ''; ?>>
|
380 |
+
<?php _ex( 'Time', 'Label to select time slot for a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
381 |
+
</a>
|
382 |
+
</li>
|
383 |
+
<li>
|
384 |
+
<a href="#" data-format="all-day"<?php echo $time_format == 'all-day' ? ' class="selected"' : ''; ?>>
|
385 |
+
<?php _ex( 'All day', 'Label to set a scheduling rule to last all day', SAP_TEXTDOMAIN ); ?>
|
386 |
+
</a>
|
387 |
+
</li>
|
388 |
+
</ul>
|
389 |
+
|
390 |
+
<div class="sap-scheduler-time-input clearfix">
|
391 |
+
|
392 |
+
<div class="start">
|
393 |
+
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][start]">
|
394 |
+
<?php _ex( 'Start', 'Label for the starting time of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
395 |
+
</label>
|
396 |
+
<input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][start]'; ?>" value="<?php echo empty( $values['time']['start'] ) ? '' : $values['time']['start']; ?>">
|
397 |
+
</div>
|
398 |
+
|
399 |
+
<?php if ( $this->disable_end_time === false ) : ?>
|
400 |
+
<div class="end">
|
401 |
+
<label for="<?php echo $this->get_input_name(); ?>[<?php echo $id; ?>][time][end]">
|
402 |
+
<?php _ex( 'End', 'Label for the ending time of a scheduling rule', SAP_TEXTDOMAIN ); ?>
|
403 |
+
</label>
|
404 |
+
<input type="text" name="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" id="<?php echo $this->get_input_name() . '[' . $id . '][time][end]'; ?>" value="<?php echo empty( $values['time']['end'] ) ? '' : $values['time']['end']; ?>">
|
405 |
+
</div>
|
406 |
+
<?php endif; ?>
|
407 |
+
|
408 |
+
</div>
|
409 |
+
|
410 |
+
<div class="sap-scheduler-all-day">
|
411 |
+
<?php _ex( 'All day long. Want to <a href="#" data-format="time-slot">set a time slot</a>?', 'Prompt displayed when a scheduling rule is set without any time restrictions.', SAP_TEXTDOMAIN ); ?>
|
412 |
+
</div>
|
413 |
+
|
414 |
+
</div>
|
415 |
+
<?php endif; ?>
|
416 |
+
|
417 |
+
<div class="sap-scheduler-brief">
|
418 |
+
<div class="date">
|
419 |
+
<div class="dashicons dashicons-calendar"></div>
|
420 |
+
<span class="value"><?php echo $this->get_date_summary( $values ); ?></span>
|
421 |
+
</div>
|
422 |
+
<?php if ( $this->disable_time === false ) : ?>
|
423 |
+
<div class="time">
|
424 |
+
<div class="dashicons dashicons-clock"></div>
|
425 |
+
<span class="value"><?php echo $this->get_time_summary( $values ); ?></span>
|
426 |
+
</div>
|
427 |
+
<?php endif; ?>
|
428 |
+
</div>
|
429 |
+
<div class="sap-scheduler-control">
|
430 |
+
<a href="#" class="toggle" title="<?php _e( 'Open and close this rule', SAP_TEXTDOMAIN ); ?>">
|
431 |
+
<div class="dashicons dashicons-<?php echo $list ? 'edit' : 'arrow-up-alt2'; ?>"></div>
|
432 |
+
<span class="screen-reader-text">
|
433 |
+
<?php _e( 'Open and close this rule', SAP_TEXTDOMAIN ); ?>
|
434 |
+
</span>
|
435 |
+
</a>
|
436 |
+
<a href="#" class="delete" title="<?php _e( 'Delete rule', SAP_TEXTDOMAIN ); ?>">
|
437 |
+
<div class="dashicons dashicons-dismiss"></div>
|
438 |
+
<span class="screen-reader-text">
|
439 |
+
<?php _e( 'Delete scheduling rule', SAP_TEXTDOMAIN ); ?>
|
440 |
+
</span>
|
441 |
+
</a>
|
442 |
+
</div>
|
443 |
+
</div>
|
444 |
+
|
445 |
+
<?php
|
446 |
+
$output = ob_get_clean();
|
447 |
+
|
448 |
+
return $output;
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Determine the date format of a rule (weeky/monthly/date)
|
453 |
+
* @since 2.0
|
454 |
+
*/
|
455 |
+
public function get_date_format( $values ) {
|
456 |
+
|
457 |
+
if ( !empty( $values['date'] ) ) {
|
458 |
+
return 'date';
|
459 |
+
} elseif ( !empty( $values['weeks'] ) ) {
|
460 |
+
return 'monthly';
|
461 |
+
} elseif ( !empty( $values['weekdays'] ) ) {
|
462 |
+
return 'weekly';
|
463 |
+
}
|
464 |
+
|
465 |
+
if ( $this->disable_weekdays === false ) {
|
466 |
+
return 'weekly';
|
467 |
+
}
|
468 |
+
if ( $this->disable_weeks === false ) {
|
469 |
+
return 'monthly';
|
470 |
+
}
|
471 |
+
if ( $this->disable_date === false ) {
|
472 |
+
return 'date';
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Determine the time format of a rule (time-slot/all-day)
|
478 |
+
* @since 2.0
|
479 |
+
*/
|
480 |
+
public function get_time_format( $values ) {
|
481 |
+
if ( empty( $values['time']['start'] ) && empty( $values['time']['end'] ) ) {
|
482 |
+
return 'all-day';
|
483 |
+
}
|
484 |
+
|
485 |
+
return 'time-slot';
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Determine if multiple date formats are enabled
|
490 |
+
* @since 2.0
|
491 |
+
*/
|
492 |
+
public function has_multiple_date_formats() {
|
493 |
+
$i = 0;
|
494 |
+
if ( $this->disable_weekdays === false ) {
|
495 |
+
$i++;
|
496 |
+
}
|
497 |
+
if ( $this->disable_weeks === false ) {
|
498 |
+
$i++;
|
499 |
+
}
|
500 |
+
if ( $this->disable_date === false ) {
|
501 |
+
$i++;
|
502 |
+
}
|
503 |
+
|
504 |
+
if ( $i > 1 ) {
|
505 |
+
return true;
|
506 |
+
} else {
|
507 |
+
return false;
|
508 |
+
}
|
509 |
+
}
|
510 |
+
|
511 |
+
/**
|
512 |
+
* Set some default summary strings that can be used when the scheduler
|
513 |
+
* rule is shown in brief
|
514 |
+
* @since 2.0
|
515 |
+
*/
|
516 |
+
public function set_schedule_summaries() {
|
517 |
+
|
518 |
+
if ( !empty( $this->schedule_summaries ) ) {
|
519 |
+
return;
|
520 |
+
}
|
521 |
+
|
522 |
+
$this->schedule_summaries = array(
|
523 |
+
'never' => _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule.', SAP_TEXTDOMAIN ),
|
524 |
+
'weekly_always' => _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule.', SAP_TEXTDOMAIN ),
|
525 |
+
'monthly_weekdays' => _x( '{days} on the {weeks} week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. The {days} and {weeks} bits should be left alone and will be replaced by a comma-separated list of days (the first one) and weeks (the second one) in the following format: M, T, W on the first, second week of the month', SAP_TEXTDOMAIN ),
|
526 |
+
'monthly_weeks' => _x( '{weeks} week of the month', 'Brief description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. {weeks} should be left alone and will be replaced by a comma-separated list of weeks (the second one) in the following format: First, second week of the month', SAP_TEXTDOMAIN ),
|
527 |
+
'all_day' => _x( 'All day', 'Brief default description of a scheduling rule when no times are set', SAP_TEXTDOMAIN ),
|
528 |
+
'before' => _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm.', SAP_TEXTDOMAIN ),
|
529 |
+
'after' => _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm.', SAP_TEXTDOMAIN ),
|
530 |
+
'separator' => _x( '—', 'Default separator between times of a scheduling rule.', SAP_TEXTDOMAIN ),
|
531 |
+
);
|
532 |
+
|
533 |
+
if ( !empty( $this->instance_schedule_summaries ) ) {
|
534 |
+
$this->schedule_summaries = array_merge( $this->schedule_summaries, $this->instance_schedule_summaries );
|
535 |
+
}
|
536 |
+
}
|
537 |
+
|
538 |
+
/**
|
539 |
+
* Print the date phrase, a brief description of the date settings
|
540 |
+
* @since 2.0
|
541 |
+
*/
|
542 |
+
public function get_date_summary( $values = array() ) {
|
543 |
+
|
544 |
+
if ( !empty( $values['date'] ) ) {
|
545 |
+
return $values['date'];
|
546 |
+
}
|
547 |
+
|
548 |
+
if ( empty( $values['weekdays'] ) && $this->disable_weekdays === false ) {
|
549 |
+
return $this->schedule_summaries['never'];
|
550 |
+
}
|
551 |
+
|
552 |
+
if ( empty( $values['weekdays'] ) ) {
|
553 |
+
$weekdays = '';
|
554 |
+
} elseif ( count( $values['weekdays'] ) == 7 ) {
|
555 |
+
$weekdays = $this->schedule_summaries['weekly_always'];
|
556 |
+
} else {
|
557 |
+
$arr = array();
|
558 |
+
foreach ( $values['weekdays'] as $weekday => $state ) {
|
559 |
+
$arr[] = $this->weekdays[$weekday];
|
560 |
+
}
|
561 |
+
$weekdays = join( ', ', $arr );
|
562 |
+
}
|
563 |
+
|
564 |
+
if ( ( empty( $values['weeks'] ) || count( $values['weeks'] ) == 5 ) && $this->disable_weekdays === false ) {
|
565 |
+
return $weekdays;
|
566 |
+
}
|
567 |
+
|
568 |
+
if ( empty( $values['weeks'] ) ) {
|
569 |
+
return $this->schedule_summaries['never'];
|
570 |
+
}
|
571 |
+
|
572 |
+
$arr = array();
|
573 |
+
foreach ( $values['weeks'] as $weeks => $state ) {
|
574 |
+
$arr[] = $this->weeks[$weeks];
|
575 |
+
}
|
576 |
+
$weeks = join( ', ', $arr );
|
577 |
+
|
578 |
+
if ( !empty( $weekdays ) ) {
|
579 |
+
return str_replace( array( '{days}', '{weeks}' ), array( $weekdays, $weeks ), $this->schedule_summaries['monthly_weekdays'] );
|
580 |
+
} else {
|
581 |
+
return str_replace( '{weeks}', ucfirst( $weeks ), $this->schedule_summaries['monthly_weeks'] );
|
582 |
+
}
|
583 |
+
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Print the time phrase, a brief description of the time settings
|
588 |
+
* @since 2.0
|
589 |
+
*/
|
590 |
+
public function get_time_summary( $values = array() ) {
|
591 |
+
|
592 |
+
if ( empty( $values['time']['start'] ) && empty( $values['time']['end'] ) ) {
|
593 |
+
return $this->schedule_summaries['all_day'];
|
594 |
+
}
|
595 |
+
|
596 |
+
if ( empty( $values['time']['start'] ) ) {
|
597 |
+
return $this->schedule_summaries['before'] . ' ' . $values['time']['end'];
|
598 |
+
}
|
599 |
+
|
600 |
+
if ( empty( $values['time']['end'] ) ) {
|
601 |
+
return $this->schedule_summaries['after'] . ' ' . $values['time']['start'];
|
602 |
+
}
|
603 |
+
|
604 |
+
return $values['time']['start'] . $this->schedule_summaries['separator'] . $values['time']['end'];
|
605 |
+
|
606 |
+
}
|
607 |
+
|
608 |
+
/**
|
609 |
+
* Sanitize the array of text inputs for this setting
|
610 |
+
* @since 2.0
|
611 |
+
*/
|
612 |
+
public function sanitize_callback_wrapper( $values ) {
|
613 |
+
|
614 |
+
$output = array();
|
615 |
+
|
616 |
+
if ( !is_array( $values ) || !count( $values ) ) {
|
617 |
+
return $output;
|
618 |
+
}
|
619 |
+
|
620 |
+
foreach ( $values as $i => $rule ) {
|
621 |
+
|
622 |
+
if ( !empty( $rule['weekdays'] ) ) {
|
623 |
+
$output[$i]['weekdays'] = array();
|
624 |
+
foreach ( $rule['weekdays'] as $day => $flag ) {
|
625 |
+
if ( $flag !== '1' ||
|
626 |
+
( $day !== 'monday' && $day !== 'tuesday' && $day !== 'wednesday' && $day !== 'thursday' && $day !== 'friday' && $day !== 'saturday' && $day !== 'sunday' ) ) {
|
627 |
+
continue;
|
628 |
+
}
|
629 |
+
|
630 |
+
$output[$i]['weekdays'][$day] = $flag;
|
631 |
+
}
|
632 |
+
}
|
633 |
+
|
634 |
+
if ( !empty( $rule['weeks'] ) ) {
|
635 |
+
$output[$i]['weeks'] = array();
|
636 |
+
foreach ( $rule['weeks'] as $week => $flag ) {
|
637 |
+
if ( $flag !== '1' ||
|
638 |
+
( $week !== 'first' && $week !== 'second' && $week !== 'third' && $week !== 'fourth' && $week !== 'last' ) ) {
|
639 |
+
continue;
|
640 |
+
}
|
641 |
+
|
642 |
+
$output[$i]['weeks'][$week] = $flag;
|
643 |
+
}
|
644 |
+
}
|
645 |
+
|
646 |
+
if ( !empty( $rule['date'] ) ) {
|
647 |
+
$date = new DateTime( $rule['date'] );
|
648 |
+
if ( checkdate( $date->format( 'n' ), $date->format( 'j' ), $date->format( 'Y' ) ) ) {
|
649 |
+
$output[$i]['date'] = call_user_func( $this->sanitize_callback, $rule['date'] );
|
650 |
+
}
|
651 |
+
}
|
652 |
+
|
653 |
+
if ( !empty( $rule['time']['start'] ) ) {
|
654 |
+
$output[$i]['time']['start'] = call_user_func( $this->sanitize_callback, $rule['time']['start'] );
|
655 |
+
}
|
656 |
+
if ( !empty( $rule['time']['end'] ) ) {
|
657 |
+
$output[$i]['time']['end'] = call_user_func( $this->sanitize_callback, $rule['time']['end'] );
|
658 |
+
}
|
659 |
+
}
|
660 |
+
|
661 |
+
return $output;
|
662 |
+
}
|
663 |
+
|
664 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Select.class.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection option with a drop-down menu.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
+
* 'options' => array( // An array of key/value pairs which
|
14 |
+
* 'option1' => 'Option 1', // define the options.
|
15 |
+
* 'option2' => 'Option 2',
|
16 |
+
* ...
|
17 |
+
* );
|
18 |
+
* );
|
19 |
+
*
|
20 |
+
* @since 1.0
|
21 |
+
* @package Simple Admin Pages
|
22 |
+
*/
|
23 |
+
|
24 |
+
class sapAdminPageSettingSelect_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
25 |
+
|
26 |
+
public $sanitize_callback = 'sanitize_text_field';
|
27 |
+
|
28 |
+
// Whether or not to display a blank option
|
29 |
+
public $blank_option = true;
|
30 |
+
|
31 |
+
// An array of options for this select field, accepted as a key/value pair.
|
32 |
+
public $options = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Display this setting
|
36 |
+
* @since 1.0
|
37 |
+
*/
|
38 |
+
public function display_setting() {
|
39 |
+
|
40 |
+
?>
|
41 |
+
|
42 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->id; ?>">
|
43 |
+
|
44 |
+
<?php if ( $this->blank_option === true ) : ?>
|
45 |
+
<option></option>
|
46 |
+
<?php endif; ?>
|
47 |
+
|
48 |
+
<?php foreach ( $this->options as $id => $title ) : ?>
|
49 |
+
<option value="<?php echo esc_attr( $id ); ?>"<?php if( $this->value == $id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $title ); ?></option>
|
50 |
+
<?php endforeach; ?>
|
51 |
+
|
52 |
+
</select>
|
53 |
+
|
54 |
+
<?php
|
55 |
+
|
56 |
+
$this->display_description();
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.SelectPost.class.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection with a drop-down list of any post type
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
13 |
+
* 'args' => array(); // Arguments to pass to WordPress's get_post() function
|
14 |
+
* );
|
15 |
+
*
|
16 |
+
* @since 1.0
|
17 |
+
* @package Simple Admin Pages
|
18 |
+
*/
|
19 |
+
|
20 |
+
class sapAdminPageSettingSelectPost_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
21 |
+
|
22 |
+
public $sanitize_callback = 'intval';
|
23 |
+
|
24 |
+
// Whether or not to display a blank option
|
25 |
+
public $blank_option = true;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* An array of arguments accepted by get_posts().
|
29 |
+
* See: http://codex.wordpress.org/Template_Tags/get_posts
|
30 |
+
*/
|
31 |
+
public $args = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Display this setting
|
35 |
+
* @since 1.0
|
36 |
+
*/
|
37 |
+
public function display_setting() {
|
38 |
+
|
39 |
+
$posts = get_posts( $this->args );
|
40 |
+
|
41 |
+
?>
|
42 |
+
|
43 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>">
|
44 |
+
|
45 |
+
<?php if ( $this->blank_option === true ) : ?>
|
46 |
+
<option></option>
|
47 |
+
<?php endif; ?>
|
48 |
+
|
49 |
+
<?php foreach ( $posts as $post ) : ?>
|
50 |
+
<option value="<?php echo esc_attr( $post->ID ); ?>"<?php if( $this->value == $post->ID ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $post->post_title ); ?></option>
|
51 |
+
<?php endforeach; ?>
|
52 |
+
|
53 |
+
</select>
|
54 |
+
|
55 |
+
<?php
|
56 |
+
|
57 |
+
$this->display_description();
|
58 |
+
|
59 |
+
}
|
60 |
+
|
61 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.SelectTaxonomy.class.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a selection with a drop-down list of any taxonomy
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'taxonomies' => array(); // Array of taxonomies to fetch (required)
|
13 |
+
* 'blank_option' => true, // Whether or not to show a blank option
|
14 |
+
* 'args' => array(); // Arguments to pass to WordPress's get_terms() function
|
15 |
+
* );
|
16 |
+
* type
|
17 |
+
*
|
18 |
+
* @since 1.0
|
19 |
+
* @package Simple Admin Pages
|
20 |
+
*/
|
21 |
+
|
22 |
+
class sapAdminPageSettingSelectTaxonomy_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
23 |
+
|
24 |
+
public $sanitize_callback = 'intval';
|
25 |
+
|
26 |
+
// Whether or not to display a blank option
|
27 |
+
public $blank_option = true;
|
28 |
+
|
29 |
+
// Arrays of taxonomies to fetch (required)
|
30 |
+
public $taxonomies;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Array of options accepted by get_terms()
|
34 |
+
* See: http://codex.wordpress.org/Function_Reference/get_terms
|
35 |
+
*/
|
36 |
+
public $args = array();
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Display this setting
|
40 |
+
* @since 1.0
|
41 |
+
*/
|
42 |
+
public function display_setting() {
|
43 |
+
|
44 |
+
$terms = get_terms( $this->taxonomies, $this->args );
|
45 |
+
|
46 |
+
?>
|
47 |
+
|
48 |
+
<select name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>">
|
49 |
+
|
50 |
+
<?php if ( $this->blank_option === true ) : ?>
|
51 |
+
<option></option>
|
52 |
+
<?php endif; ?>
|
53 |
+
|
54 |
+
<?php foreach ( $terms as $term ) : ?>
|
55 |
+
<option value="<?php echo esc_attr( $term->term_id ); ?>"<?php if( $this->value == $term->term_id ) : ?> selected="selected"<?php endif; ?>><?php echo esc_html( $term->name ); ?></option>
|
56 |
+
<?php endforeach; ?>
|
57 |
+
|
58 |
+
</select>
|
59 |
+
|
60 |
+
<?php
|
61 |
+
|
62 |
+
$this->display_description();
|
63 |
+
|
64 |
+
}
|
65 |
+
|
66 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Text.class.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a text field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
class sapAdminPageSettingText_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
11 |
+
|
12 |
+
public $sanitize_callback = 'sanitize_text_field';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Placeholder string for the input field
|
16 |
+
* @since 2.0
|
17 |
+
*/
|
18 |
+
public $placeholder = '';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Display this setting
|
22 |
+
* @since 1.0
|
23 |
+
*/
|
24 |
+
public function display_setting() {
|
25 |
+
?>
|
26 |
+
|
27 |
+
<input name="<?php echo $this->get_input_name(); ?>" type="text" id="<?php echo $this->get_input_name(); ?>" value="<?php echo $this->value; ?>"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?> class="regular-text" />
|
28 |
+
|
29 |
+
<?php
|
30 |
+
|
31 |
+
$this->display_description();
|
32 |
+
|
33 |
+
}
|
34 |
+
|
35 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Textarea.class.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a textarea field setting in the admin menu
|
5 |
+
*
|
6 |
+
* @since 1.0
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*
|
9 |
+
* @todo textareas should have an option to swap new lines for <br>s
|
10 |
+
*/
|
11 |
+
|
12 |
+
class sapAdminPageSettingTextarea_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
13 |
+
|
14 |
+
/*
|
15 |
+
* Size of this textarea
|
16 |
+
*
|
17 |
+
* This is put directly into a css class [size]-text,
|
18 |
+
* and setting this to 'large' will link into WordPress's existing textarea
|
19 |
+
* style for full-width textareas.
|
20 |
+
*/
|
21 |
+
public $size = 'small';
|
22 |
+
|
23 |
+
public $sanitize_callback = 'wp_kses_post';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Escape the value to display it safely HTML textarea fields
|
27 |
+
* @since 1.0
|
28 |
+
*/
|
29 |
+
public function esc_value( $val ) {
|
30 |
+
return esc_textarea( $val );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Set the size of this textarea field
|
35 |
+
* @since 1.0
|
36 |
+
*/
|
37 |
+
public function set_size( $size ) {
|
38 |
+
$this->size = esc_attr( $size );
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Display this setting
|
43 |
+
* @since 1.0
|
44 |
+
*/
|
45 |
+
public function display_setting() {
|
46 |
+
?>
|
47 |
+
|
48 |
+
<textarea name="<?php echo $this->get_input_name(); ?>" id="<?php echo $this->get_input_name(); ?>" class="<?php echo $this->size; ?>-text"<?php echo !empty( $this->placeholder ) ? ' placeholder="' . esc_attr( $this->placeholder ) . '"' : ''; ?>><?php echo $this->value; ?></textarea>
|
49 |
+
|
50 |
+
<?php
|
51 |
+
|
52 |
+
$this->display_description();
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.Toggle.class.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save an option with a single checkbox.
|
5 |
+
*
|
6 |
+
* This setting accepts the following arguments in its constructor function.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description', // Help text description
|
12 |
+
* 'label' => 'Label', // Checkbox label text
|
13 |
+
* );
|
14 |
+
* );
|
15 |
+
*
|
16 |
+
* @since 1.0
|
17 |
+
* @package Simple Admin Pages
|
18 |
+
*/
|
19 |
+
|
20 |
+
class sapAdminPageSettingToggle_2_0_a_5 extends sapAdminPageSetting_2_0_a_5 {
|
21 |
+
|
22 |
+
public $sanitize_callback = 'sanitize_text_field';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Display this setting
|
26 |
+
* @since 1.0
|
27 |
+
*/
|
28 |
+
public function display_setting() {
|
29 |
+
|
30 |
+
$input_name = $this->get_input_name();
|
31 |
+
|
32 |
+
?>
|
33 |
+
|
34 |
+
<input type="checkbox" name="<?php echo $input_name; ?>" id="<?php echo $input_name; ?>" value="1"<?php if( $this->value == '1' ) : ?> checked="checked"<?php endif; ?>>
|
35 |
+
<label for="<?php echo $input_name; ?>"><?php echo $this->label; ?></label>
|
36 |
+
|
37 |
+
<?php
|
38 |
+
|
39 |
+
$this->display_description();
|
40 |
+
|
41 |
+
}
|
42 |
+
|
43 |
+
}
|
lib/simple-admin-pages/classes/AdminPageSetting.class.php
ADDED
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register, display and save a setting on a custom admin menu
|
5 |
+
*
|
6 |
+
* All settings accept the following arguments in their constructor functions.
|
7 |
+
*
|
8 |
+
* $args = array(
|
9 |
+
* 'id' => 'setting_id', // Unique id
|
10 |
+
* 'title' => 'My Setting', // Title or label for the setting
|
11 |
+
* 'description' => 'Description' // Help text description
|
12 |
+
* );
|
13 |
+
*
|
14 |
+
* @since 1.0
|
15 |
+
* @package Simple Admin Pages
|
16 |
+
*/
|
17 |
+
|
18 |
+
abstract class sapAdminPageSetting_2_0_a_5 {
|
19 |
+
|
20 |
+
// Page defaults
|
21 |
+
public $id; // used in form fields and database to track and store setting
|
22 |
+
public $title; // setting label
|
23 |
+
public $description; // optional description of the setting
|
24 |
+
public $value; // value of the setting, if a value exists
|
25 |
+
|
26 |
+
// Array to store errors
|
27 |
+
public $errors = array();
|
28 |
+
|
29 |
+
/*
|
30 |
+
* Function to use when sanitizing the data
|
31 |
+
*
|
32 |
+
* We set this to a strict sanitization function as a default, but a
|
33 |
+
* setting should override this in an extended class when needed.
|
34 |
+
*
|
35 |
+
* @since 1.0
|
36 |
+
*/
|
37 |
+
public $sanitize_callback = 'sanitize_text_field';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Scripts that must be loaded for this component
|
41 |
+
* @since 2.0.a.4
|
42 |
+
*/
|
43 |
+
public $scripts = array(
|
44 |
+
/**
|
45 |
+
* Example
|
46 |
+
* See: http://codex.wordpress.org/Function_Reference/wp_enqueue_script
|
47 |
+
*
|
48 |
+
'handle' => array(
|
49 |
+
'path' => 'path/from/simple-admin-pages/file.js',
|
50 |
+
'dependencies' => array( 'jquery' ),
|
51 |
+
'version' => '3.5.0',
|
52 |
+
'footer' => true,
|
53 |
+
),
|
54 |
+
*/
|
55 |
+
);
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Styles that must be loaded for this component
|
59 |
+
* @since 2.0.a.4
|
60 |
+
*/
|
61 |
+
public $styles = array(
|
62 |
+
/**
|
63 |
+
* Example
|
64 |
+
* See: http://codex.wordpress.org/Function_Reference/wp_enqueue_style
|
65 |
+
*
|
66 |
+
'handle' => array(
|
67 |
+
'path' => 'path/from/simple-admin-pages/file.css',
|
68 |
+
'dependencies' => 'array( 'another-handle')', // or empty string
|
69 |
+
'version' => '3.5.0',
|
70 |
+
'media' => null,
|
71 |
+
),
|
72 |
+
*/
|
73 |
+
);
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Initialize the setting
|
77 |
+
*
|
78 |
+
* By default, every setting takes an id, title and description in the $args
|
79 |
+
* array.
|
80 |
+
*
|
81 |
+
* @since 1.0
|
82 |
+
*/
|
83 |
+
public function __construct( $args ) {
|
84 |
+
|
85 |
+
// Parse the values passed
|
86 |
+
$this->parse_args( $args );
|
87 |
+
|
88 |
+
// Get any existing value
|
89 |
+
$this->set_value();
|
90 |
+
|
91 |
+
// Set an error if the object is missing necessary data
|
92 |
+
if ( $this->missing_data() ) {
|
93 |
+
$this->set_error();
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Parse the arguments passed in the construction and assign them to
|
99 |
+
* internal variables. This function will be overwritten for most subclasses
|
100 |
+
* @since 1.0
|
101 |
+
*/
|
102 |
+
private function parse_args( $args ) {
|
103 |
+
foreach ( $args as $key => $val ) {
|
104 |
+
switch ( $key ) {
|
105 |
+
|
106 |
+
case 'id' :
|
107 |
+
$this->{$key} = esc_attr( $val );
|
108 |
+
|
109 |
+
default :
|
110 |
+
$this->{$key} = $val;
|
111 |
+
|
112 |
+
}
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Check for missing data when setup.
|
118 |
+
* @since 1.0
|
119 |
+
*/
|
120 |
+
private function missing_data( ) {
|
121 |
+
|
122 |
+
$error_type = 'missing_data';
|
123 |
+
|
124 |
+
// Required fields
|
125 |
+
if ( empty( $this->id ) ) {
|
126 |
+
$this->set_error(
|
127 |
+
array(
|
128 |
+
'type' => $error_type,
|
129 |
+
'data' => 'id'
|
130 |
+
)
|
131 |
+
);
|
132 |
+
}
|
133 |
+
if ( empty( $this->title ) ) {
|
134 |
+
$this->set_error(
|
135 |
+
array(
|
136 |
+
'type' => $error_type,
|
137 |
+
'data' => 'title'
|
138 |
+
)
|
139 |
+
);
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Set a value
|
145 |
+
* @since 2.0
|
146 |
+
*/
|
147 |
+
public function set_value( $val = null ) {
|
148 |
+
|
149 |
+
if ( $val === null ) {
|
150 |
+
$option_group_value = get_option( $this->page );
|
151 |
+
$val = isset( $option_group_value[ $this->id ] ) ? $option_group_value[ $this->id ] : '';
|
152 |
+
}
|
153 |
+
|
154 |
+
$this->value = $this->esc_value( $val );
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Escape the value to display it in text fields and other input fields
|
159 |
+
*
|
160 |
+
* We use esc_attr() here so that the default is quite strict, but other
|
161 |
+
* setting types should override this function with the appropriate escape
|
162 |
+
* function. See: http://codex.wordpress.org/Data_Validation
|
163 |
+
*
|
164 |
+
* @since 1.0
|
165 |
+
*/
|
166 |
+
public function esc_value( $val ) {
|
167 |
+
return esc_attr( $val );
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Wrapper for the sanitization callback function.
|
172 |
+
*
|
173 |
+
* This just reduces code duplication for child classes that need a custom
|
174 |
+
* callback function.
|
175 |
+
* @since 1.0
|
176 |
+
*/
|
177 |
+
public function sanitize_callback_wrapper( $value ) {
|
178 |
+
return call_user_func( $this->sanitize_callback, $value );
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Display this setting
|
183 |
+
* @since 1.0
|
184 |
+
*/
|
185 |
+
abstract public function display_setting();
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Display a description for this setting
|
189 |
+
* @since 1.0
|
190 |
+
*/
|
191 |
+
public function display_description() {
|
192 |
+
|
193 |
+
if ( !empty( $this->description ) ) {
|
194 |
+
|
195 |
+
?>
|
196 |
+
|
197 |
+
<p class="description"><?php echo $this->description; ?></p>
|
198 |
+
|
199 |
+
<?php
|
200 |
+
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Generate an option input field name, using the grouped schema:
|
206 |
+
* "page[option_name]"
|
207 |
+
* @since 1.2
|
208 |
+
*/
|
209 |
+
public function get_input_name() {
|
210 |
+
return esc_attr( $this->page ) . '[' . esc_attr( $this->id ) . ']';
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Add and register this setting
|
215 |
+
*
|
216 |
+
* @since 1.0
|
217 |
+
*/
|
218 |
+
public function add_settings_field( $section_id ) {
|
219 |
+
|
220 |
+
// If no sanitization callback exists, don't register the setting.
|
221 |
+
if ( !$this->has_sanitize_callback() ) {
|
222 |
+
return;
|
223 |
+
}
|
224 |
+
|
225 |
+
add_settings_field(
|
226 |
+
$this->id,
|
227 |
+
$this->title,
|
228 |
+
array( $this, 'display_setting' ),
|
229 |
+
$this->tab,
|
230 |
+
$section_id
|
231 |
+
);
|
232 |
+
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Check if this field has a sanitization callback set
|
237 |
+
* @since 1.2
|
238 |
+
*/
|
239 |
+
public function has_sanitize_callback() {
|
240 |
+
if ( isset( $this->sanitize_callback ) && trim( $this->sanitize_callback ) ) {
|
241 |
+
return true;
|
242 |
+
}
|
243 |
+
|
244 |
+
return false;
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Set an error
|
249 |
+
* @since 1.0
|
250 |
+
*/
|
251 |
+
public function set_error( $error ) {
|
252 |
+
$this->errors[] = array_merge(
|
253 |
+
$error,
|
254 |
+
array(
|
255 |
+
'class' => get_class( $this ),
|
256 |
+
'id' => $this->id,
|
257 |
+
'backtrace' => debug_backtrace()
|
258 |
+
)
|
259 |
+
);
|
260 |
+
}
|
261 |
+
}
|
lib/simple-admin-pages/classes/Library.class.php
ADDED
@@ -0,0 +1,415 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !class_exists( 'sapLibrary_2_0_a_5' ) ) {
|
3 |
+
/**
|
4 |
+
* This library class loads and provides access to the correct version of the
|
5 |
+
* Simple Admin Pages library.
|
6 |
+
*
|
7 |
+
* @since 1.0
|
8 |
+
* @package Simple Admin Pages
|
9 |
+
*/
|
10 |
+
class sapLibrary_2_0_a_5 {
|
11 |
+
|
12 |
+
// Version of the library
|
13 |
+
private $version = '2.0.a.5';
|
14 |
+
|
15 |
+
// A full URL to the library which is used to correctly link scripts and
|
16 |
+
// stylesheets.
|
17 |
+
public $lib_url;
|
18 |
+
|
19 |
+
// A relative path to any custom library extension classes. When
|
20 |
+
// instantiating a custom setting class, the library will search in its own
|
21 |
+
// directory of classes adn also the $lib_extension_path. This way,
|
22 |
+
// developers can add on their own classes without mixing them with the
|
23 |
+
// default classes.
|
24 |
+
public $lib_extension_path;
|
25 |
+
|
26 |
+
// An array of pages to add to the admin menus
|
27 |
+
public $pages = array();
|
28 |
+
|
29 |
+
// Collects errors for debugging
|
30 |
+
public $errors = array();
|
31 |
+
|
32 |
+
// Set debug mode to true to stop and print errors found while processing.
|
33 |
+
// @note This is not related to your PHP error reporting setting, but is an
|
34 |
+
// internal error tracking mechanism to catch missing or malformed data
|
35 |
+
// during development.
|
36 |
+
public $debug_mode = false;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Initialize the library with the appropriate version
|
40 |
+
* @since 1.0
|
41 |
+
*/
|
42 |
+
public function __construct( $args ) {
|
43 |
+
|
44 |
+
// If no URL path to the library is passed, we won't be able to add the
|
45 |
+
// CSS and Javascript to the admin panel
|
46 |
+
if ( !isset( $args['lib_url'] ) ) {
|
47 |
+
$this->set_error(
|
48 |
+
array(
|
49 |
+
'id' => 'no-lib-url',
|
50 |
+
'desc' => 'No URL path to the library provided when the libary was created.',
|
51 |
+
'var' => $args,
|
52 |
+
'line' => __LINE__,
|
53 |
+
'function' => __FUNCTION__
|
54 |
+
)
|
55 |
+
);
|
56 |
+
} else {
|
57 |
+
$this->lib_url = $args['lib_url'];
|
58 |
+
}
|
59 |
+
|
60 |
+
// Set a library extension path if passed
|
61 |
+
if ( isset( $args['lib_extension_path'] ) ) {
|
62 |
+
$this->lib_extension_path = $args['lib_extension_path'];
|
63 |
+
}
|
64 |
+
|
65 |
+
// Set the debug mode
|
66 |
+
if ( isset( $args['debug_mode'] ) && $args['debug_mode'] === true ) {
|
67 |
+
$this->debug_mode = true;
|
68 |
+
}
|
69 |
+
|
70 |
+
// Ensure we have access to WordPress' plugin functions
|
71 |
+
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
|
72 |
+
|
73 |
+
// Load the required classes
|
74 |
+
$this->load_class( 'sapAdminPage', 'AdminPage.class.php' );
|
75 |
+
$this->load_class( 'sapAdminPageSection', 'AdminPageSection.class.php' );
|
76 |
+
$this->load_class( 'sapAdminPageSetting', 'AdminPageSetting.class.php' );
|
77 |
+
|
78 |
+
// Add the scripts to the admin pages
|
79 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Load the class if it isn't already loaded
|
85 |
+
* @since 1.0
|
86 |
+
*/
|
87 |
+
private function load_class( $class, $file ) {
|
88 |
+
|
89 |
+
if ( !class_exists( $this->get_versioned_classname( $class ) ) ) {
|
90 |
+
require_once( $file );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Return the version suffix for a class
|
96 |
+
* @since 1.0
|
97 |
+
*/
|
98 |
+
private function get_versioned_classname( $class ) {
|
99 |
+
return $class . '_' . str_replace( '.', '_', $this->version );
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Check if the correct version of a class exists
|
104 |
+
* @since 1.0
|
105 |
+
*/
|
106 |
+
private function versioned_class_exists( $class ) {
|
107 |
+
if ( class_exists( $this->get_versioned_classname( $class ) ) ) {
|
108 |
+
return true;
|
109 |
+
} else {
|
110 |
+
return false;
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Load the files for a specific setting type and return the class
|
116 |
+
* to use when instantiating the setting object.
|
117 |
+
*
|
118 |
+
* @since 1.0
|
119 |
+
*/
|
120 |
+
private function get_setting_classname( $type ) {
|
121 |
+
|
122 |
+
switch( $type ) {
|
123 |
+
|
124 |
+
case 'text' :
|
125 |
+
require_once('AdminPageSetting.Text.class.php');
|
126 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingText' );
|
127 |
+
|
128 |
+
case 'textarea' :
|
129 |
+
require_once('AdminPageSetting.Textarea.class.php');
|
130 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingTextarea' );
|
131 |
+
|
132 |
+
case 'select' :
|
133 |
+
require_once('AdminPageSetting.Select.class.php');
|
134 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelect' );
|
135 |
+
|
136 |
+
case 'toggle' :
|
137 |
+
require_once('AdminPageSetting.Toggle.class.php');
|
138 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingToggle' );
|
139 |
+
|
140 |
+
case 'post' :
|
141 |
+
require_once('AdminPageSetting.SelectPost.class.php');
|
142 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelectPost' );
|
143 |
+
|
144 |
+
case 'taxonomy' :
|
145 |
+
require_once('AdminPageSetting.SelectTaxonomy.class.php');
|
146 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingSelectTaxonomy' );
|
147 |
+
|
148 |
+
case 'editor' :
|
149 |
+
require_once('AdminPageSetting.Editor.class.php');
|
150 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingEditor' );
|
151 |
+
|
152 |
+
case 'html' :
|
153 |
+
require_once('AdminPageSetting.HTML.class.php');
|
154 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingHTML' );
|
155 |
+
|
156 |
+
case 'scheduler' :
|
157 |
+
require_once('AdminPageSetting.Scheduler.class.php');
|
158 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingScheduler' );
|
159 |
+
|
160 |
+
case 'opening-hours' :
|
161 |
+
require_once('AdminPageSetting.OpeningHours.class.php');
|
162 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingOpeningHours' );
|
163 |
+
|
164 |
+
case 'address' :
|
165 |
+
require_once('AdminPageSetting.Address.class.php');
|
166 |
+
return $this->get_versioned_classname( 'sapAdminPageSettingAddress' );
|
167 |
+
|
168 |
+
default :
|
169 |
+
|
170 |
+
// Exit early if a custom type is declared without providing the
|
171 |
+
// details to find the type class
|
172 |
+
if ( ( !is_array( $type ) || !isset( $type['id'] ) ) ||
|
173 |
+
( !isset( $type['class'] ) || !isset( $type['filename'] ) ) ) {
|
174 |
+
return false;
|
175 |
+
}
|
176 |
+
|
177 |
+
// Load the custom type file. Look for the file in the library's
|
178 |
+
// folder or check the custom library extension path.
|
179 |
+
if ( file_exists( $type['filename'] ) ) {
|
180 |
+
require_once( $type['filename'] );
|
181 |
+
} elseif ( isset( $this->lib_extension_path ) && file_exists( $this->lib_extension_path . $type['filename'] ) ) {
|
182 |
+
require_once( $this->lib_extension_path . '/' . $type['filename'] );
|
183 |
+
} else {
|
184 |
+
return false;
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
// Check that we've loaded the appropriate class
|
189 |
+
if ( !$this->versioned_class_exists( $type['class'] ) ) {
|
190 |
+
return false;
|
191 |
+
}
|
192 |
+
|
193 |
+
return $this->get_versioned_classname( $type['class'] );
|
194 |
+
|
195 |
+
}
|
196 |
+
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Initialize a page
|
201 |
+
* @since 1.0
|
202 |
+
*
|
203 |
+
* @todo perform some checks on args to ensure a valid page can be constructed
|
204 |
+
*/
|
205 |
+
public function add_page( $menu_location, $args = array() ) {
|
206 |
+
|
207 |
+
// default should be 'options'
|
208 |
+
$class = $this->get_versioned_classname( 'sapAdminPage' );
|
209 |
+
|
210 |
+
if ( $menu_location == 'themes' ) {
|
211 |
+
$this->load_class( 'sapAdminPageThemes', 'AdminPage.Themes.class.php' );
|
212 |
+
$class = $this->get_versioned_classname( 'sapAdminPageThemes' );
|
213 |
+
} elseif ( $menu_location == 'menu' ) {
|
214 |
+
$this->load_class( 'sapAdminPageMenu', 'AdminPage.Menu.class.php' );
|
215 |
+
$class = $this->get_versioned_classname( 'sapAdminPageMenu' );
|
216 |
+
} elseif ( $menu_location == 'submenu' ) {
|
217 |
+
$this->load_class( 'sapAdminPageSubmenu', 'AdminPage.Submenu.class.php' );
|
218 |
+
$class = $this->get_versioned_classname( 'sapAdminPageSubmenu' );
|
219 |
+
}
|
220 |
+
|
221 |
+
if ( class_exists( $class ) ) {
|
222 |
+
$this->pages[ $args['id'] ] = new $class( $args );
|
223 |
+
}
|
224 |
+
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Initialize a section
|
229 |
+
* @since 1.0
|
230 |
+
*
|
231 |
+
* @todo perform some checks on args to ensure a valid section can be constructed
|
232 |
+
*/
|
233 |
+
public function add_section( $page, $args = array() ) {
|
234 |
+
|
235 |
+
if ( !isset( $this->pages[ $page ] ) ) {
|
236 |
+
return false;
|
237 |
+
} else {
|
238 |
+
$args['page'] = $page;
|
239 |
+
}
|
240 |
+
|
241 |
+
$class = $this->get_versioned_classname( 'sapAdminPageSection' );
|
242 |
+
if ( class_exists( $class ) ) {
|
243 |
+
$this->pages[ $page ]->add_section( new $class( $args ) );
|
244 |
+
}
|
245 |
+
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Initialize a setting
|
250 |
+
*
|
251 |
+
* The type variable can be a string pointing to a pre-defined setting type,
|
252 |
+
* or an array consisting of an id, classname and filename which references
|
253 |
+
* a custom setting type. @sa get_setting_classname()
|
254 |
+
*
|
255 |
+
* @since 1.0
|
256 |
+
*/
|
257 |
+
public function add_setting( $page, $section, $type, $args = array() ) {
|
258 |
+
|
259 |
+
if ( !isset( $this->pages[ $page ] ) || !isset( $this->pages[ $page ]->sections[ $section ] ) ) {
|
260 |
+
return false;
|
261 |
+
} else {
|
262 |
+
$args['page'] = $page;
|
263 |
+
$args['tab'] = $this->pages[$page]->sections[ $section ]->get_page_slug();
|
264 |
+
}
|
265 |
+
|
266 |
+
$class = $this->get_setting_classname( $type );
|
267 |
+
if ( ( $class && class_exists( $class ) ) && is_subclass_of( $class, $this->get_versioned_classname( 'sapAdminPageSetting' ) ) ) {
|
268 |
+
$this->pages[ $page ]->sections[ $section ]->add_setting( new $class( $args ) );
|
269 |
+
}
|
270 |
+
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Register all page, section and settings content with WordPress
|
275 |
+
* @since 1.0
|
276 |
+
*/
|
277 |
+
public function add_admin_menus() {
|
278 |
+
|
279 |
+
// If the library is run in debug mode, check for any errors in content,
|
280 |
+
// print any errors found, and don't add the menu if there are errors
|
281 |
+
if ( $this->debug_mode ) {
|
282 |
+
$errors = array();
|
283 |
+
foreach ( $this->pages as $page ) {
|
284 |
+
foreach ( $page->sections as $section ) {
|
285 |
+
if ( count( $section->errors ) ) {
|
286 |
+
array_merge( $errors, $section->errors );
|
287 |
+
}
|
288 |
+
foreach ( $section->settings as $setting ) {
|
289 |
+
if ( count( $setting->errors ) ) {
|
290 |
+
$errors = array_merge( $errors, $setting->errors );
|
291 |
+
}
|
292 |
+
}
|
293 |
+
}
|
294 |
+
}
|
295 |
+
if ( count( $errors ) ) {
|
296 |
+
print_r( $errors );
|
297 |
+
return;
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
// Add the action hooks
|
302 |
+
foreach ( $this->pages as $id => $page ) {
|
303 |
+
add_action( 'admin_menu', array( $page, 'add_admin_menu' ) );
|
304 |
+
add_action( 'admin_init', array( $page, 'register_admin_menu' ) );
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Port data from a previous version to the current version
|
310 |
+
*
|
311 |
+
* Version 2.0 of the library changes the structure of how it stores data.
|
312 |
+
* In order to upgrade the version of the library your plugin/theme is
|
313 |
+
* using, this method must be called after all of your pages and settings
|
314 |
+
* have been declared but before you run add_admin_menus().
|
315 |
+
*
|
316 |
+
* This method will loop over all of the settings data and port any existing
|
317 |
+
* data to the new data structure. It will check if the data has been ported
|
318 |
+
* first before it updates the data. The old data will be removed to keep
|
319 |
+
* the database clean.
|
320 |
+
*
|
321 |
+
* @var int target_version Which data version the library should update to.
|
322 |
+
* @since 2.0
|
323 |
+
*/
|
324 |
+
public function port_data( $target_version, $delete_old_data = true ) {
|
325 |
+
|
326 |
+
// Port data to the storage structure in version 2
|
327 |
+
if ( $target_version == 2 ) {
|
328 |
+
|
329 |
+
foreach ( $this->pages as $page_id => $page ) {
|
330 |
+
|
331 |
+
// Skip if this page has already been ported
|
332 |
+
if ( get_option( $page_id ) !== false ) {
|
333 |
+
continue;
|
334 |
+
}
|
335 |
+
|
336 |
+
$page_values = array();
|
337 |
+
|
338 |
+
foreach ( $page->sections as $section ) {
|
339 |
+
foreach ( $section->settings as $setting ) {
|
340 |
+
$value = get_option( $setting->id );
|
341 |
+
if ( $value !== false ) {
|
342 |
+
$page_values[ $setting->id ] = $value;
|
343 |
+
}
|
344 |
+
}
|
345 |
+
}
|
346 |
+
|
347 |
+
if ( count( $page_values ) ) {
|
348 |
+
$result = add_option( $page_id, $page_values );
|
349 |
+
|
350 |
+
// Delete old data if the flag is set and the new data was
|
351 |
+
// saved successfully.
|
352 |
+
if ( $delete_old_data === true && $result !== false ) {
|
353 |
+
foreach( $page_values as $setting_id => $setting_value ) {
|
354 |
+
delete_option( $setting_id );
|
355 |
+
}
|
356 |
+
}
|
357 |
+
|
358 |
+
// Reset settings values
|
359 |
+
if ( $result === true ) {
|
360 |
+
|
361 |
+
foreach ( $page->sections as $section ) {
|
362 |
+
foreach ( $section->settings as $setting ) {
|
363 |
+
$setting->set_value();
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
}
|
368 |
+
}
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Enqueue the stylesheets and scripts
|
376 |
+
* @since 1.0
|
377 |
+
* @todo complex settings should enqueue their assets only when loaded
|
378 |
+
*/
|
379 |
+
public function enqueue_scripts() {
|
380 |
+
|
381 |
+
// Enqueue assets for specific settings
|
382 |
+
foreach ( $this->pages as $page ) {
|
383 |
+
foreach ( $page->sections as $section ) {
|
384 |
+
foreach ( $section->settings as $setting ) {
|
385 |
+
foreach( $setting->scripts as $handle => $script ) {
|
386 |
+
wp_enqueue_script( $handle, $this->lib_url . $script['path'], $script['dependencies'], $script['version'], $script['footer'] );
|
387 |
+
}
|
388 |
+
foreach( $setting->styles as $handle => $style ) {
|
389 |
+
wp_enqueue_style( $handle . '-' . $this->version, $this->lib_url . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
|
390 |
+
}
|
391 |
+
}
|
392 |
+
}
|
393 |
+
}
|
394 |
+
|
395 |
+
// Default styles and scripts
|
396 |
+
wp_enqueue_style( 'sap-admin-style-' . $this->version, $this->lib_url . 'css/admin.css' );
|
397 |
+
}
|
398 |
+
|
399 |
+
/**
|
400 |
+
* Set an error
|
401 |
+
* @since 1.0
|
402 |
+
*/
|
403 |
+
public function set_error( $error ) {
|
404 |
+
$this->errors[] = array_merge(
|
405 |
+
$error,
|
406 |
+
array(
|
407 |
+
'class' => get_class( $this ),
|
408 |
+
'id' => $this->id,
|
409 |
+
'backtrace' => debug_backtrace()
|
410 |
+
)
|
411 |
+
);
|
412 |
+
}
|
413 |
+
|
414 |
+
}
|
415 |
+
} // endif;
|
lib/simple-admin-pages/css/admin.css
ADDED
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* CSS Stylesheet for Simple Admin Pages library
|
3 |
+
*
|
4 |
+
* This stylesheet formats the display components placed into the WordPress
|
5 |
+
* admin menu. It attempts to replicate WordPress's existing admin menu style.
|
6 |
+
*
|
7 |
+
* @package Simple Admin Pages
|
8 |
+
*/
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Clear floats
|
12 |
+
*/
|
13 |
+
.clearfix:before,
|
14 |
+
.clearfix:after {
|
15 |
+
content: " ";
|
16 |
+
display: table;
|
17 |
+
}
|
18 |
+
.clearfix:after {
|
19 |
+
clear: both;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Textarea
|
24 |
+
*/
|
25 |
+
textarea.small-text {
|
26 |
+
width: 25em;
|
27 |
+
height: 10em;
|
28 |
+
}
|
29 |
+
textarea.large-text {
|
30 |
+
height: 30em;
|
31 |
+
}
|
32 |
+
|
33 |
+
/*
|
34 |
+
* Opening Hours
|
35 |
+
*/
|
36 |
+
.sap-opening-hours td {
|
37 |
+
padding-left: 0;
|
38 |
+
padding-right: 1em;
|
39 |
+
padding-top: 0;
|
40 |
+
}
|
41 |
+
input.sap-opening-hours-day {
|
42 |
+
width: 15em;
|
43 |
+
}
|
44 |
+
input.sap-opening-hours-hours {
|
45 |
+
width: 9em;
|
46 |
+
}
|
47 |
+
|
48 |
+
/*
|
49 |
+
* Scheduler
|
50 |
+
*/
|
51 |
+
.sap-add-scheduler {
|
52 |
+
margin-top: 1em;
|
53 |
+
}
|
54 |
+
.sap-scheduler-rule {
|
55 |
+
position: relative;
|
56 |
+
padding: 1em;
|
57 |
+
margin: 1em 0;
|
58 |
+
max-width: 800px;
|
59 |
+
background: #fff;
|
60 |
+
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
61 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
62 |
+
}
|
63 |
+
.sap-selector {
|
64 |
+
display: inline-block;
|
65 |
+
margin-top: 0;
|
66 |
+
margin-right: 1em;
|
67 |
+
border-bottom: 1px solid #ccc;
|
68 |
+
}
|
69 |
+
.sap-selector li {
|
70 |
+
display: inline-block;
|
71 |
+
margin-right: 1em;
|
72 |
+
line-height: 20px;
|
73 |
+
}
|
74 |
+
.sap-selector a {
|
75 |
+
text-decoration: none;
|
76 |
+
}
|
77 |
+
.sap-selector .selected {
|
78 |
+
font-weight: 600;
|
79 |
+
color: #666;
|
80 |
+
}
|
81 |
+
.sap-scheduler-weekdays li,
|
82 |
+
.sap-scheduler-weeks li {
|
83 |
+
display: inline-block;
|
84 |
+
margin-right: 0.5em;
|
85 |
+
text-align: center;
|
86 |
+
}
|
87 |
+
.sap-scheduler-date .label,
|
88 |
+
.sap-scheduler-date-input label {
|
89 |
+
display: block;
|
90 |
+
font-style: italic;
|
91 |
+
text-align: left;
|
92 |
+
margin-bottom: 0;
|
93 |
+
}
|
94 |
+
.sap-scheduler-weekdays input,
|
95 |
+
.sap-scheduler-weeks input {
|
96 |
+
margin-top: 6px;
|
97 |
+
margin-bottom: 7px;
|
98 |
+
}
|
99 |
+
.sap-scheduler-date label {
|
100 |
+
display: block;
|
101 |
+
}
|
102 |
+
.sap-scheduler-date-input {
|
103 |
+
display: none;
|
104 |
+
margin-top: 1em;
|
105 |
+
}
|
106 |
+
.sap-scheduler-date.date .sap-scheduler-weeks,
|
107 |
+
.sap-scheduler-date.date .sap-scheduler-weekdays {
|
108 |
+
display: none;
|
109 |
+
}
|
110 |
+
.sap-scheduler-date.weekly .sap-scheduler-weeks,
|
111 |
+
.sap-scheduler-date.date .sap-scheduler-weeks {
|
112 |
+
display: none;
|
113 |
+
}
|
114 |
+
.sap-scheduler-date.date .sap-scheduler-date-input {
|
115 |
+
display: block;
|
116 |
+
}
|
117 |
+
.sap-scheduler-time {
|
118 |
+
margin-top: 4em;
|
119 |
+
}
|
120 |
+
.sap-scheduler-time.all-day .sap-scheduler-time-input {
|
121 |
+
display: none;
|
122 |
+
}
|
123 |
+
.sap-scheduler-time-input .start,
|
124 |
+
.sap-scheduler-time-input .end {
|
125 |
+
margin-top: 1em;
|
126 |
+
display: inline-block;
|
127 |
+
}
|
128 |
+
.sap-scheduler-time-input .start {
|
129 |
+
margin-right: 1em;
|
130 |
+
}
|
131 |
+
.sap-scheduler-time-input label {
|
132 |
+
display: block;
|
133 |
+
font-style: italic;
|
134 |
+
}
|
135 |
+
.sap-scheduler-time-input input {
|
136 |
+
max-width: 8em;
|
137 |
+
}
|
138 |
+
.sap-scheduler-all-day {
|
139 |
+
display: block;
|
140 |
+
margin-top: 1.7em;
|
141 |
+
font-style: italic;
|
142 |
+
padding: 1em;
|
143 |
+
background: #eee;
|
144 |
+
}
|
145 |
+
.sap-scheduler-all-day p {
|
146 |
+
margin-top: 0;
|
147 |
+
}
|
148 |
+
.sap-scheduler-time.time-slot .sap-scheduler-all-day {
|
149 |
+
display: none;
|
150 |
+
}
|
151 |
+
.sap-scheduler-control {
|
152 |
+
clear: both;
|
153 |
+
line-height: 1.5em;
|
154 |
+
}
|
155 |
+
.sap-scheduler-control {
|
156 |
+
position: absolute;
|
157 |
+
top: 1em;
|
158 |
+
right: 1em;
|
159 |
+
}
|
160 |
+
.sap-scheduler-control a {
|
161 |
+
text-decoration: none;
|
162 |
+
}
|
163 |
+
.sap-scheduler-control .delete {
|
164 |
+
color: #a00;
|
165 |
+
}
|
166 |
+
.sap-scheduler-control .delete:hover,
|
167 |
+
.sap-scheduler-control .delete:focus {
|
168 |
+
color: red;
|
169 |
+
}
|
170 |
+
.sap-scheduler-rule.list .sap-scheduler-date,
|
171 |
+
.sap-scheduler-rule.list .sap-scheduler-time {
|
172 |
+
display: none;
|
173 |
+
}
|
174 |
+
.sap-scheduler-rule .sap-scheduler-brief {
|
175 |
+
display: none;
|
176 |
+
clear: both;
|
177 |
+
}
|
178 |
+
.sap-scheduler-rule.list .sap-scheduler-brief {
|
179 |
+
display: block;
|
180 |
+
}
|
181 |
+
.sap-scheduler-brief {
|
182 |
+
margin-right: 4em;
|
183 |
+
line-height: 1.5em;
|
184 |
+
}
|
185 |
+
.sap-scheduler-brief .date,
|
186 |
+
.sap-scheduler-brief .time {
|
187 |
+
display: inline-block;
|
188 |
+
}
|
189 |
+
.sap-scheduler-brief .date {
|
190 |
+
margin-right: 1em;
|
191 |
+
}
|
192 |
+
@media (min-width: 783px) {
|
193 |
+
.sap-selector li {
|
194 |
+
font-size: 13px;
|
195 |
+
}
|
196 |
+
.sap-scheduler-time {
|
197 |
+
margin-top: 0;
|
198 |
+
}
|
199 |
+
.sap-scheduler-date {
|
200 |
+
float: left;
|
201 |
+
width: 50%;
|
202 |
+
}
|
203 |
+
.sap-scheduler-date.full-width {
|
204 |
+
float: none;
|
205 |
+
width: 100%;
|
206 |
+
}
|
207 |
+
.sap-scheduler-time {
|
208 |
+
float: right;
|
209 |
+
width: 50%;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Adjustements to pickadate library css to override WP admin styles
|
215 |
+
*/
|
216 |
+
.picker .picker__table {
|
217 |
+
table-layout: auto;
|
218 |
+
}
|
219 |
+
.picker .picker__table th,
|
220 |
+
.picker .picker__table td {
|
221 |
+
text-align: center;
|
222 |
+
display: table-cell;
|
223 |
+
padding: 0.5em;
|
224 |
+
font-size: 1em;
|
225 |
+
}
|
lib/simple-admin-pages/js/address.js
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Javascript functions for Address component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Set coordinate that have been received
|
11 |
+
*/
|
12 |
+
function sap_address_set_coords( control, lat, lon ) {
|
13 |
+
control.find( '.sap-coords-result' ).remove();
|
14 |
+
control.find( 'input.lat' ).val( lat );
|
15 |
+
control.find( 'input.lon' ).val( lon );
|
16 |
+
|
17 |
+
if ( lat == '' && lon == '' ) {
|
18 |
+
control.find( '.sap-map-coords' ).text( lat + sap_address.strings['no-setting'] + lon ).attr( 'style', '' );
|
19 |
+
} else {
|
20 |
+
control.find( '.sap-map-coords' ).text( lat + sap_address.strings['sep-lat-lon'] + lon ).attr( 'style', '' );
|
21 |
+
}
|
22 |
+
|
23 |
+
var url = '//maps.google.com/maps?q=' + lat + ',' + lon;
|
24 |
+
if ( control.find( '.sap-view-coords' ).length ) {
|
25 |
+
control.find( '.sap-view-coords' ).attr( 'href', url );
|
26 |
+
} else {
|
27 |
+
control.find( '.sap-map-coords-wrapper' ).append( '<a class="sap-view-coords" href="' + url + '" target="_blank">' + sap_address.strings.view + '</a>' );
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Retrieve coordinates
|
33 |
+
*/
|
34 |
+
$('.sap-get-coords').click( function() {
|
35 |
+
var control = $(this).parent().parent();
|
36 |
+
var address = control.find( 'textarea' ).val();
|
37 |
+
|
38 |
+
// Reset messages
|
39 |
+
control.find( '.sap-coords-result' ).remove();
|
40 |
+
control.find( '.error' ).remove();
|
41 |
+
control.find( '.sap-view-coords' ).remove();
|
42 |
+
control.find( '.sap-map-coords' ).text( sap_address.strings.retrieving ).attr( 'style', 'opacity: 0.3' );
|
43 |
+
|
44 |
+
// Call Google Maps geocoding API
|
45 |
+
// See: https://developers.google.com/maps/documentation/geocoding/
|
46 |
+
var req = $.get(
|
47 |
+
'//maps.googleapis.com/maps/api/geocode/json',
|
48 |
+
{ sensor: false, address: address },
|
49 |
+
function( data ) {
|
50 |
+
|
51 |
+
if ( data.status == 'OK' ) {
|
52 |
+
if ( data.results.length == 1 ) {
|
53 |
+
sap_address_set_coords( control, data.results[0].geometry.location.lat, data.results[0].geometry.location.lng );
|
54 |
+
|
55 |
+
} else {
|
56 |
+
for ( var key in data.results ) {
|
57 |
+
control.append( '<p class="sap-coords-result">' + data.results[key].formatted_address + ' <span class="dashicons dashicons-arrow-right"></span> <a href="#" data-lat="' + data.results[key].geometry.location.lat + '" data-lon="' + data.results[key].geometry.location.lng + '">Set</a></p>' );
|
58 |
+
}
|
59 |
+
control.find( '.sap-map-coords' ).text( sap_address.strings.select ).attr( 'style', '' );
|
60 |
+
|
61 |
+
control.find( '.sap-coords-result a' ).click( function() {
|
62 |
+
sap_address_set_coords( control, $(this).data( 'lat' ), $(this).data( 'lon' ) );
|
63 |
+
});
|
64 |
+
|
65 |
+
}
|
66 |
+
|
67 |
+
} else {
|
68 |
+
sap_address_set_coords( control, control.find( 'input.lat' ).val(), control.find( 'input.lon' ).val() );
|
69 |
+
|
70 |
+
if ( data.status == 'UNKNOWN_ERROR' ) {
|
71 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
|
72 |
+
} else if ( data.status == 'INVALID_REQUEST' ) {
|
73 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_invalid + '</div>' );
|
74 |
+
} else if ( data.status == 'INVALID_REQUEST' ) {
|
75 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_error + '</div>' );
|
76 |
+
} else if ( data.status == 'REQUEST_DENIED' ) {
|
77 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_denied + '</div>' );
|
78 |
+
} else if ( data.status == 'OVER_QUERY_LIMIT' ) {
|
79 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_limit + '</div>' );
|
80 |
+
} else if ( data.status == 'ZERO_RESULTS' ) {
|
81 |
+
control.find( '.sap-coords-action-wrapper' ).prepend( '<div class="error">' + sap_address.strings.result_empty + '</div>' );
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
85 |
+
)
|
86 |
+
});
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Remove coordinates from settings
|
90 |
+
*/
|
91 |
+
$('.sap-remove-coords').click( function() {
|
92 |
+
var control = $(this).parent().parent();
|
93 |
+
sap_address_set_coords( control, '', '' );
|
94 |
+
});
|
95 |
+
|
96 |
+
});
|
lib/simple-admin-pages/js/opening-hours.js
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Javascript functions for Opening Hours component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Opening Hours
|
11 |
+
***************/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Update the name of each day when the select option is changed
|
15 |
+
*/
|
16 |
+
$( '.sap-opening-hours-day' ).change( function() {
|
17 |
+
$( $(this).data( 'target' ) ).val( $(this).children( 'option:selected' ).data( 'name' ) );
|
18 |
+
});
|
19 |
+
|
20 |
+
});
|
lib/simple-admin-pages/js/scheduler.js
ADDED
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Javascript functions for the Scheduler component
|
3 |
+
*
|
4 |
+
* @package Simple Admin Pages
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(document).ready(function ($) {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Scheduler
|
11 |
+
***********/
|
12 |
+
|
13 |
+
if ( typeof sap_scheduler != 'undefined' ) {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Register event handlers on the scheduler rules. This is run on page load
|
17 |
+
* and every time a rule is added.
|
18 |
+
*/
|
19 |
+
function sap_scheduler_register_events() {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Open and close the full view of a scheduling rule
|
23 |
+
*/
|
24 |
+
$( '.sap-scheduler-rule .toggle' ).off( 'click' ).click( function() {
|
25 |
+
|
26 |
+
var controls = $(this).parent();
|
27 |
+
|
28 |
+
if ( $(this).parent().parent().hasClass( 'list' ) ) {
|
29 |
+
controls.hide();
|
30 |
+
$(this).children( '.dashicons-edit' ).removeClass( 'dashicons-edit' ).addClass( 'dashicons-arrow-up-alt2' );
|
31 |
+
controls.siblings( '.sap-scheduler-brief' ).hide();
|
32 |
+
controls.siblings( '.sap-scheduler-date, .sap-scheduler-time' ).slideDown( function() {
|
33 |
+
$(this).parent().removeClass( 'list' );
|
34 |
+
controls.fadeIn();
|
35 |
+
});
|
36 |
+
|
37 |
+
} else {
|
38 |
+
controls.hide();
|
39 |
+
$(this).children( '.dashicons-arrow-up-alt2' ).removeClass( 'dashicons-arrow-up-alt2' ).addClass( 'dashicons-edit' );
|
40 |
+
controls.siblings( '.sap-scheduler-brief' ).fadeIn();
|
41 |
+
controls.siblings( '.sap-scheduler-time' ).slideUp();
|
42 |
+
controls.siblings( '.sap-scheduler-date' ).slideUp( function() {
|
43 |
+
|
44 |
+
var scheduler_rule = $(this).parent();
|
45 |
+
var scheduler_id = scheduler_rule.parent().attr( 'id' );
|
46 |
+
|
47 |
+
scheduler_rule.addClass( 'list' );
|
48 |
+
controls.fadeIn();
|
49 |
+
|
50 |
+
sap_scheduler_set_date_phrase( scheduler_rule, scheduler_id );
|
51 |
+
sap_scheduler_set_time_phrase( scheduler_rule, scheduler_id );
|
52 |
+
});
|
53 |
+
}
|
54 |
+
|
55 |
+
return false;
|
56 |
+
});
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Update current selection for selector lists
|
60 |
+
*/
|
61 |
+
$( '.sap-selector a' ).off( 'switch.sap' ).on( 'switch.sap', function() {
|
62 |
+
$(this).parent().parent().find( 'a' ).removeClass( 'selected' );
|
63 |
+
$(this).addClass( 'selected' );
|
64 |
+
|
65 |
+
return false;
|
66 |
+
});
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Switch between weekly, monthly and date options
|
70 |
+
*/
|
71 |
+
$( '.sap-scheduler-date .sap-selector a' ).off( 'click' ).click( function() {
|
72 |
+
|
73 |
+
$(this).trigger( 'switch.sap' );
|
74 |
+
|
75 |
+
var date = $(this).closest( '.sap-scheduler-date' );
|
76 |
+
|
77 |
+
if ( $(this).data( 'format' ) == 'weekly' && date.hasClass( 'weekly' ) === false ) {
|
78 |
+
date.children( '.sap-scheduler-weeks' ).slideUp( function() {
|
79 |
+
$(this).find( 'input' ).prop('checked', false);
|
80 |
+
});
|
81 |
+
date.children( '.sap-scheduler-date-input' ).slideUp( function() {
|
82 |
+
$(this).find( 'input' ).val( '' );
|
83 |
+
});
|
84 |
+
date.children( '.sap-scheduler-weekdays' ).slideDown( function() {
|
85 |
+
date.removeClass( 'monthly date' );
|
86 |
+
date.addClass( 'weekly' );
|
87 |
+
});
|
88 |
+
|
89 |
+
} else if ( $(this).data( 'format' ) == 'monthly' && date.hasClass( 'monthly' ) === false ) {
|
90 |
+
date.children( '.sap-scheduler-date-input' ).slideUp( function() {
|
91 |
+
$(this).find( 'input' ).val( '' );
|
92 |
+
});
|
93 |
+
date.children( '.sap-scheduler-weekdays' ).slideDown();
|
94 |
+
date.children( '.sap-scheduler-weeks' ).slideDown( function() {
|
95 |
+
date.removeClass( 'weekly date' );
|
96 |
+
date.addClass( 'monthly' );
|
97 |
+
});
|
98 |
+
|
99 |
+
} else if ( $(this).data( 'format' ) == 'date' && date.hasClass( 'date' ) === false ) {
|
100 |
+
date.children( '.sap-scheduler-weekdays' ).slideUp( function() {
|
101 |
+
$(this).find( 'input' ).prop('checked', false);
|
102 |
+
});
|
103 |
+
date.children( '.sap-scheduler-weeks' ).slideUp( function() {
|
104 |
+
$(this).find( 'input' ).prop('checked', false);
|
105 |
+
});
|
106 |
+
date.children( '.sap-scheduler-date-input' ).slideDown( function() {
|
107 |
+
date.removeClass( 'weekly monthly' );
|
108 |
+
date.addClass( 'date' );
|
109 |
+
});
|
110 |
+
}
|
111 |
+
|
112 |
+
return false;
|
113 |
+
});
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Show or hide time slot options
|
117 |
+
*/
|
118 |
+
$( '.sap-scheduler-time .sap-selector a' ).off( 'click' ).click( function() {
|
119 |
+
|
120 |
+
$(this).trigger( 'switch.sap' );
|
121 |
+
|
122 |
+
var time = $(this).closest( '.sap-scheduler-time' );
|
123 |
+
|
124 |
+
if ( $(this).data( 'format' ) == 'time-slot' && time.hasClass( 'time-slot' ) === false ) {
|
125 |
+
time.children( '.sap-scheduler-time-input' ).slideDown();
|
126 |
+
time.children( '.sap-scheduler-all-day' ).slideUp( function() {
|
127 |
+
time.removeClass( 'all-day' );
|
128 |
+
time.addClass( 'time-slot' );
|
129 |
+
});
|
130 |
+
|
131 |
+
} else if ( $(this).data( 'format' ) == 'all-day' && time.hasClass( 'all-day' ) === false ) {
|
132 |
+
time.children( '.sap-scheduler-all-day' ).slideDown();
|
133 |
+
time.children( '.sap-scheduler-time-input' ).slideUp( function() {
|
134 |
+
time.removeClass( 'time-slot' );
|
135 |
+
time.addClass( 'all-day' );
|
136 |
+
time.find( 'input' ).val( '' );
|
137 |
+
});
|
138 |
+
}
|
139 |
+
|
140 |
+
return false;
|
141 |
+
});
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Show time slot options from the link in the all-day notice
|
145 |
+
*/
|
146 |
+
$( '.sap-scheduler-all-day a' ).off( 'click' ).click( function() {
|
147 |
+
$(this).closest( '.sap-scheduler-time' ).children( '.sap-selector' ).find( 'a[data-format="time-slot"]' ).trigger( 'click' );
|
148 |
+
|
149 |
+
return false;
|
150 |
+
});
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Delete a scheduling rule panel
|
154 |
+
*/
|
155 |
+
$( '.sap-scheduler-control .delete' ).off( 'click' ).click( function() {
|
156 |
+
var scheduler = $(this).closest( '.sap-scheduler' );
|
157 |
+
$(this).parent().parent().fadeOut( function() {
|
158 |
+
$(this).remove();
|
159 |
+
|
160 |
+
// Reset the index of each rule
|
161 |
+
// @todo optimize this excessive use of regex (32x per rule).
|
162 |
+
// maybe set a data-slug attribute on .sap-scheduler-rule and a
|
163 |
+
// data-slug prop on each input/select/label, then use these to
|
164 |
+
// construct the new attributes: rule-slug[index][input-slug]
|
165 |
+
scheduler.children( '.sap-scheduler-rule' ).each( function( i ) {
|
166 |
+
var index = i.toString();
|
167 |
+
$(this).find( 'input' ).each( function() {
|
168 |
+
var name = $(this).attr( 'name' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
169 |
+
$(this).attr( 'name', name );
|
170 |
+
$(this).attr( 'id', name );
|
171 |
+
var aria_owns = $(this).attr( 'aria-owns' );
|
172 |
+
if ( typeof aria_owns !== 'undefined' && aria_owns !== false) {
|
173 |
+
$(this).attr( 'aria-owns', name );
|
174 |
+
}
|
175 |
+
});
|
176 |
+
$(this).find( 'label' ).each( function() {
|
177 |
+
var name = $(this).attr( 'for' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
178 |
+
$(this).attr( 'for', name );
|
179 |
+
});
|
180 |
+
$(this).find( '.picker' ).each( function() {
|
181 |
+
var name = $(this).attr( 'id' ).replace( /\[\d*\]/g, '[' + index + ']' );
|
182 |
+
$(this).attr( 'id', name );
|
183 |
+
});
|
184 |
+
});
|
185 |
+
});
|
186 |
+
|
187 |
+
return false;
|
188 |
+
});
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Set the summary phrase for a scheduler rule's date. This phrase is shown
|
193 |
+
* when the rule's view is minimized.
|
194 |
+
*/
|
195 |
+
function sap_scheduler_set_date_phrase( scheduler_rule, scheduler_id ) {
|
196 |
+
|
197 |
+
var date_value = scheduler_rule.find( '.sap-scheduler-date-input input' ).val();
|
198 |
+
if ( typeof date_value !== 'undefined' && date_value != '' ) {
|
199 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( date_value );
|
200 |
+
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
|
204 |
+
var weekdays = 0;
|
205 |
+
var weekday_arr = new Array();
|
206 |
+
scheduler_rule.find( '.sap-scheduler-weekdays input' ).each( function() {
|
207 |
+
if ( $(this).prop( 'checked' ) !== false ) {
|
208 |
+
weekdays += 1;
|
209 |
+
weekday_arr.push( sap_scheduler.settings[scheduler_id]['weekdays'][ $(this).data( 'day' ) ] );
|
210 |
+
}
|
211 |
+
});
|
212 |
+
|
213 |
+
if ( weekdays == 0 && sap_scheduler.settings[ scheduler_id ].disable_weekdays === false ) {
|
214 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['never'] );
|
215 |
+
|
216 |
+
return;
|
217 |
+
|
218 |
+
} else if ( weekdays == 7 ) {
|
219 |
+
var weekday_string = sap_scheduler.settings[scheduler_id].summaries['weekly_always'];
|
220 |
+
|
221 |
+
} else {
|
222 |
+
var weekday_string = weekday_arr.join( ', ' );
|
223 |
+
}
|
224 |
+
|
225 |
+
var weeks = 0;
|
226 |
+
var weeks_arr = new Array();
|
227 |
+
scheduler_rule.find( '.sap-scheduler-weeks input' ).each( function() {
|
228 |
+
if ( $(this).prop( 'checked' ) !== false ) {
|
229 |
+
weeks +=1;
|
230 |
+
weeks_arr.push( sap_scheduler.settings[scheduler_id]['weeks'][ $(this).data( 'week' ) ] );
|
231 |
+
}
|
232 |
+
});
|
233 |
+
|
234 |
+
if ( ( weeks == 0 || weeks == 5 ) && sap_scheduler.settings[ scheduler_id ].disable_weekdays === false ) {
|
235 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( weekday_string );
|
236 |
+
|
237 |
+
return;
|
238 |
+
}
|
239 |
+
|
240 |
+
if ( weeks == 0 ) {
|
241 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['never'] );
|
242 |
+
|
243 |
+
return;
|
244 |
+
}
|
245 |
+
|
246 |
+
if ( weekday_string != '' ) {
|
247 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['monthly_weekdays'].replace( '{days}', weekday_arr.join( ', ' ) ).replace( '{weeks}', weeks_arr.join( ', ' ) ) );
|
248 |
+
} else {
|
249 |
+
scheduler_rule.find( '.sap-scheduler-brief .date .value' ).html( sap_scheduler.settings[scheduler_id].summaries['monthly_weeks'].replace( '{weeks}', weeks_arr.join( ', ' ) ) );
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Set the summary phrase for a scheduler rule's time. This phrase is shown
|
255 |
+
* when the rule's view is minimized.
|
256 |
+
*/
|
257 |
+
function sap_scheduler_set_time_phrase( scheduler_rule, scheduler_id ) {
|
258 |
+
|
259 |
+
var start = scheduler_rule.find( '.sap-scheduler-time-input .start input' ).val();
|
260 |
+
var end = scheduler_rule.find( '.sap-scheduler-time-input .end input' ).val();
|
261 |
+
|
262 |
+
if ( start == '' && ( end == '' || typeof end == 'undefined' ) ) {
|
263 |
+
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['all_day'] );
|
264 |
+
|
265 |
+
return;
|
266 |
+
}
|
267 |
+
|
268 |
+
if ( start == '' ) {
|
269 |
+
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['before'] + ' ' + end );
|
270 |
+
|
271 |
+
return;
|
272 |
+
}
|
273 |
+
|
274 |
+
if ( end == '' || typeof end == 'undefined' ) {
|
275 |
+
scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( sap_scheduler.settings[scheduler_id].summaries['after'] + ' ' + start );
|
276 |
+
|
277 |
+
return;
|
278 |
+
}
|
279 |
+
|
280 |
+
if ( typeof end == 'undefined' ) {
|
281 |
+
return scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( start );
|
282 |
+
} else {
|
283 |
+
return scheduler_rule.find( '.sap-scheduler-brief .time .value' ).html( start + sap_scheduler.settings[scheduler_id].summaries['separator'] + end );
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Register click events on load
|
289 |
+
*/
|
290 |
+
sap_scheduler_register_events();
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Enable datepickers on load
|
294 |
+
*/
|
295 |
+
if ( typeof sap_scheduler.settings != 'undefined' ) {
|
296 |
+
for ( var key in sap_scheduler.settings ) {
|
297 |
+
var obj = sap_scheduler.settings[key];
|
298 |
+
$( '#' + key + ' .sap-scheduler-date-input input' ).pickadate({
|
299 |
+
format: obj.date_format,
|
300 |
+
});
|
301 |
+
$( '#' + key + ' .sap-scheduler-time-input input' ).pickatime({
|
302 |
+
interval: obj.time_interval,
|
303 |
+
format: obj.time_format,
|
304 |
+
});
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Add a new scheduler panel
|
310 |
+
*/
|
311 |
+
$( '.sap-add-scheduler a' ).click( function() {
|
312 |
+
var scheduler = $(this).parent().siblings( '.sap-scheduler' );
|
313 |
+
var scheduler_id = scheduler.attr( 'id' );
|
314 |
+
var scheduler_settings = sap_scheduler.settings[ scheduler_id ];
|
315 |
+
scheduler.append( scheduler_settings.template.replace( /\[0\]/g, '[' + scheduler.children( '.sap-scheduler-rule' ).length + ']' ) );
|
316 |
+
scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-date-input input' ).pickadate({
|
317 |
+
format: scheduler_settings.date_format,
|
318 |
+
});
|
319 |
+
scheduler.last( '#' + scheduler_id + ' .sap-scheduler-rule' ).find( '.sap-scheduler-time-input input' ).pickatime({
|
320 |
+
interval: scheduler_settings.time_interval,
|
321 |
+
format: scheduler_settings.time_format,
|
322 |
+
});
|
323 |
+
sap_scheduler_register_events();
|
324 |
+
|
325 |
+
return false;
|
326 |
+
});
|
327 |
+
}
|
328 |
+
|
329 |
+
});
|
lib/simple-admin-pages/lib/pickadate/legacy.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Legacy browser support
|
3 |
+
*/
|
4 |
+
[].map||(Array.prototype.map=function(a,b){for(var c=this,d=c.length,e=new Array(d),f=0;d>f;f++)f in c&&(e[f]=a.call(b,c[f],f,c));return e}),[].filter||(Array.prototype.filter=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=arguments[1],f=0;c>f;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g)}return d}),[].indexOf||(Array.prototype.indexOf=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!==d&&1/0!=d&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1});/*!
|
5 |
+
* Cross-Browser Split 1.1.1
|
6 |
+
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
|
7 |
+
* Available under the MIT License
|
8 |
+
* http://blog.stevenlevithan.com/archives/cross-browser-split
|
9 |
+
*/
|
10 |
+
var nativeSplit=String.prototype.split,compliantExecNpcg=void 0===/()??/.exec("")[1];String.prototype.split=function(a,b){var c=this;if("[object RegExp]"!==Object.prototype.toString.call(a))return nativeSplit.call(c,a,b);var d,e,f,g,h=[],i=(a.ignoreCase?"i":"")+(a.multiline?"m":"")+(a.extended?"x":"")+(a.sticky?"y":""),j=0;for(a=new RegExp(a.source,i+"g"),c+="",compliantExecNpcg||(d=new RegExp("^"+a.source+"$(?!\\s)",i)),b=void 0===b?-1>>>0:b>>>0;(e=a.exec(c))&&(f=e.index+e[0].length,!(f>j&&(h.push(c.slice(j,e.index)),!compliantExecNpcg&&e.length>1&&e[0].replace(d,function(){for(var a=1;a<arguments.length-2;a++)void 0===arguments[a]&&(e[a]=void 0)}),e.length>1&&e.index<c.length&&Array.prototype.push.apply(h,e.slice(1)),g=e[0].length,j=f,h.length>=b)));)a.lastIndex===e.index&&a.lastIndex++;return j===c.length?(g||!a.test(""))&&h.push(""):h.push(c.slice(j)),h.length>b?h.slice(0,b):h};
|
lib/simple-admin-pages/lib/pickadate/picker.date.js
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Date picker for pickadate.js v3.5.0
|
3 |
+
* http://amsul.github.io/pickadate.js/date.htm
|
4 |
+
*/
|
5 |
+
!function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format,h=function(){return"rtl"===getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return h()?-1:1},37:function(){return h()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",[d.getFullYear(),d.getMonth(),d.getDate()],{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})}).on("open",function(){a.$root.find("button, select").attr("disabled",!1)}).on("close",function(){a.$root.find("button, select").attr("disabled",!0)})}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-1/0||1/0==c?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-1/0:1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?a===d.create(c).day+1:f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?c===d.create(a).day+1:b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;g>i;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysShort).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(){var d=c.showMonthsShort?c.monthsShort:c.monthsFull;return c.selectMonths?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[d[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth,(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):f.node("div",d[k.month],c.klass.month)},r=function(){var d=k.year,e=c.selectYears===!0?5:~~(c.selectYears/2);if(e){var g=m.year,h=n.year,i=d-e,j=d+e;if(g>i&&(j+=g-i,i=g),j>h){var l=i-g,o=j-h;i-=l>o?o:l,j=h}return f.node("select",f.group({min:i,max:j,i:1,node:"option",item:function(a){return[a,0,"value="+a+(d==a?" selected":"")]}}),c.klass.selectYear,(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return f.node("div",d,c.klass.year)};return f.node("div",(c.selectYears?r()+q():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick;return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",selected:d&&b.$node.val()===f.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0}))+f.node("div",f.node("button",c.today,c.klass.buttonToday,"type=button data-pick="+h.pick+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)});
|
lib/simple-admin-pages/lib/pickadate/picker.js
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* pickadate.js v3.5.0, 2014/04/13
|
3 |
+
* By Amsul, http://amsul.ca
|
4 |
+
* Hosted on http://amsul.github.io/pickadate.js
|
5 |
+
* Licensed under MIT
|
6 |
+
*/
|
7 |
+
!function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):this.Picker=a(jQuery)}(function(a){function b(f,g,i,j){function k(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",v.component.nodes(q.open),s.box),s.wrap),s.frame),s.holder)}function l(){t.data(g,v).addClass(s.input).val(t.data("value")?v.get("select",r.format):f.value).on("focus."+q.id+" click."+q.id,o),r.editable||t.on("keydown."+q.id,function(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(v.close(),!1):void((32==b||c||!q.open&&v.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?v.clear().close():v.open()))}),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"+(v._hidden?" "+v._hidden.id:"")})}function m(){v.$root.on({focusin:function(a){v.$root.removeClass(s.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=v.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is(":input")||"OPTION"==c.nodeName||(b.preventDefault(),f.focus()))}}).on("click","[data-pick], [data-nav], [data-clear]",function(){var c=a(this),d=c.data(),e=c.hasClass(s.navDisabled)||c.hasClass(s.disabled),g=document.activeElement;g=g&&(g.type||g.href)&&g,(e||g&&!a.contains(v.$root[0],g))&&f.focus(),d.nav&&!e?v.set("highlight",v.component.item.highlight,{nav:d.nav}):b._.isInteger(d.pick)&&!e?v.set("select",d.pick).close(!0):d.clear&&v.clear().close(!0)}),e(v.$root[0],"hidden",!0)}function n(){var b,c;r.hiddenName===!0?(b=f.name+"_hidden",c=f.name,f.name=""):(c=["string"==typeof r.hiddenPrefix?r.hiddenPrefix:"","string"==typeof r.hiddenSuffix?r.hiddenSuffix:"_submit"],c=b=c[0]+f.name+c[1]),v._hidden=a('<input type=hidden name="'+c+'"id="'+b+'"'+(t.data("value")||f.value?' value="'+v.get("select",r.formatSubmit)+'"':"")+">")[0],t.on("change."+q.id,function(){v._hidden.value=f.value?v.get("select",r.formatSubmit):""}).after(v._hidden)}function o(a){a.stopPropagation(),"focus"==a.type&&v.$root.addClass(s.focused),v.open()}if(!f)return b;var p=!1,q={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},r=i?a.extend(!0,{},i.defaults,j):j||{},s=a.extend({},b.klasses(),r.klass),t=a(f),u=function(){return this.start()},v=u.prototype={constructor:u,$node:t,start:function(){return q&&q.start?v:(q.methods={},q.start=!0,q.open=!1,q.type=f.type,f.autofocus=f==document.activeElement,f.type="text",f.readOnly=!r.editable,f.id=f.id||q.id,v.component=new i(v,r),v.$root=a(b._.node("div",k(),s.picker,'id="'+f.id+'_root"')),m(),r.formatSubmit&&n(),l(),r.container?a(r.container).append(v.$root):t.after(v.$root),v.on({start:v.component.onStart,render:v.component.onRender,stop:v.component.onStop,open:v.component.onOpen,close:v.component.onClose,set:v.component.onSet}).on({start:r.onStart,render:r.onRender,stop:r.onStop,open:r.onOpen,close:r.onClose,set:r.onSet}),p=c(v.$root.children()[0]),f.autofocus&&v.open(),v.trigger("start").trigger("render"))},render:function(a){return a?v.$root.html(k()):v.$root.find("."+s.box).html(v.component.nodes(q.open)),v.trigger("render")},stop:function(){return q.start?(v.close(),v._hidden&&v._hidden.parentNode.removeChild(v._hidden),v.$root.remove(),t.removeClass(s.input).removeData(g),setTimeout(function(){t.off("."+q.id)},0),f.type=q.type,f.readOnly=!1,v.trigger("stop"),q.methods={},q.start=!1,v):v},open:function(c){return q.open?v:(t.addClass(s.active),e(f,"expanded",!0),setTimeout(function(){v.$root.addClass(s.opened),e(v.$root[0],"hidden",!1)},0),c!==!1&&(q.open=!0,p&&a("html").css("overflow","hidden").css("padding-right","+="+d()),t.trigger("focus"),h.on("click."+q.id+" focusin."+q.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&v.close(b===v.$root.children()[0])}).on("keydown."+q.id,function(c){var d=c.keyCode,e=v.component.key[d],g=c.target;27==d?v.close(!0):g!=f||!e&&13!=d?a.contains(v.$root[0],g)&&13==d&&(c.preventDefault(),g.click()):(c.preventDefault(),e?b._.trigger(v.component.key.go,v,[b._.trigger(e)]):v.$root.find("."+s.highlighted).hasClass(s.disabled)||v.set("select",v.component.item.highlight).close())})),v.trigger("open"))},close:function(b){return b&&(t.off("focus."+q.id).trigger("focus"),setTimeout(function(){t.on("focus."+q.id,o)},0)),t.removeClass(s.active),e(f,"expanded",!1),setTimeout(function(){v.$root.removeClass(s.opened+" "+s.focused),e(v.$root[0],"hidden",!0)},0),q.open?(q.open=!1,p&&a("html").css("overflow","").css("padding-right","-="+d()),h.off("."+q.id),v.trigger("close")):v},clear:function(){return v.set("clear")},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in v.component.item&&(void 0===f&&(f=null),v.component.set(e,f,d)),("select"==e||"clear"==e)&&t.val("clear"==e?"":v.get(e,r.format)).trigger("change");v.render()}return d.muted?v:v.trigger("set",h)},get:function(a,c){return a=a||"value",null!=q[a]?q[a]:"value"==a?f.value:a in v.component.item?"string"==typeof c?b._.trigger(v.component.formats.toString,v.component,[c,v.component.get(a)]):v.component.get(a):void 0},on:function(b,c){var d,e,f=a.isPlainObject(b),g=f?b:{};if(b){f||(g[b]=c);for(d in g)e=g[d],q.methods[d]=q.methods[d]||[],q.methods[d].push(e)}return v},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;namesCount>a;a+=1)b=c[a],b in q.methods&&delete q.methods[b];return v},trigger:function(a,c){var d=q.methods[a];return d&&d.map(function(a){b._.trigger(a,v,[c])}),v}};return new u}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}var h=a(document);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b});
|
lib/simple-admin-pages/lib/pickadate/picker.time.js
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Time picker for pickadate.js v3.5.0
|
3 |
+
* http://amsul.github.io/pickadate.js/time.htm
|
4 |
+
*/
|
5 |
+
!function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format;c.settings=b,c.$node=a.$node,c.queue={interval:"i",min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse create validate",view:"parse create validate",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.interval=b.interval||30,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g,fromValue:!!d}):c.set("select",null).set("highlight",c.item.now),c.key={40:1,38:-1,39:1,37:-1,go:function(a){c.set("highlight",c.item.highlight.pick+a*c.item.interval,{interval:a*c.item.interval}),this.render()}},a.on("render",function(){var c=a.$root.children(),d=c.find("."+b.klass.viewset);d.length&&(c[0].scrollTop=~~d.position().top-2*d[0].clientHeight)}).on("open",function(){a.$root.find("button").attr("disabled",!1)}).on("close",function(){a.$root.find("button").attr("disabled",!0)})}var d=24,e=60,f=12,g=d*e,h=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):"interval"==a?d.set("min",e.min,c).set("max",e.max,c):a.match(/^(flip|min|max|disable|enable)$/)&&("min"==a&&d.set("max",e.max,c),e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,f){var i=this;return c=void 0===c?a:c,h.isDate(c)&&(c=[c.getHours(),c.getMinutes()]),b.isPlainObject(c)&&h.isInteger(c.pick)?c=c.pick:b.isArray(c)?c=+c[0]*e+ +c[1]:h.isInteger(c)||(c=i.now(a,c,f)),"max"==a&&c<i.item.min.pick&&(c+=g),"min"!=a&&"max"!=a&&(c-i.item.min.pick)%i.item.interval!==0&&(c+=i.item.interval),c=i.normalize(a,c,f),{hour:~~(d+c/e)%d,mins:(e+c%e)%e,time:(g+c)%g,pick:c}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||h.isDate(a)?d.create(a):a};return h.isInteger(a)||(a=e(a)),h.isInteger(c)||(c=e(c)),h.isInteger(a)&&b.isPlainObject(c)?a=[c.hour,c.mins+a*d.settings.interval]:h.isInteger(c)&&b.isPlainObject(a)&&(c=[a.hour,a.mins+c*d.settings.interval]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b){var c,d=this.item.interval,f=new Date,g=f.getHours()*e+f.getMinutes(),i=h.isInteger(b);return g-=g%d,c=0>b&&-d>=d*b+g,g+="min"==a&&c?0:d,i&&(g+=d*(c&&"max"!=a?b+1:b)),g},c.prototype.normalize=function(a,b){var c=this.item.interval,d=this.item.min&&this.item.min.pick||0;return b-="min"==a?0:(b-d)%c},c.prototype.measure=function(a,c,f){var g=this;return c?c===!0||h.isInteger(c)?c=g.now(a,c,f):b.isPlainObject(c)&&h.isInteger(c.pick)&&(c=g.normalize(a,c.pick,f)):c="min"==a?[0,0]:[d-1,e-1],c},c.prototype.validate=function(a,b,c){var d=this,e=c&&c.interval?c.interval:d.item.interval;return d.disabled(b)&&(b=d.shift(b,e)),b=d.scope(b),d.disabled(b)&&(b=d.shift(b,-1*e)),b},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return h.isInteger(d)?a.hour==d:b.isArray(d)||h.isDate(d)?a.pick==c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[2]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.shift=function(a,b){var c=this,d=c.item.min.pick,e=c.item.max.pick;for(b=b||c.item.interval;c.disabled(a)&&(a=c.create(a.pick+=b),!(a.pick<=d||a.pick>=e)););return a},c.prototype.scope=function(a){var b=this.item.min.pick,c=this.item.max.pick;return this.create(a.pick>c?c:a.pick<b?b:a)},c.prototype.parse=function(a,b,c){var d,f,g,i,j,k=this,l={};if(!b||"string"!=typeof b)return b;c&&c.format||(c=c||{},c.format=k.settings.format),k.formats.toArray(c.format).map(function(a){var c,d=k.formats[a],e=d?h.trigger(d,k,[b,l]):a.replace(/^!/,"").length;d&&(c=b.substr(0,e),l[a]=c.match(/^\d+$/)?+c:c),b=b.substr(e)});for(i in l)j=l[i],h.isInteger(j)?i.match(/^(h|hh)$/i)?(d=j,("h"==i||"hh"==i)&&(d%=12)):"i"==i&&(f=j):i.match(/^a$/i)&&j.match(/^p/i)&&("h"in l||"hh"in l)&&(g=!0);return(g?d+12:d)*e+f},c.prototype.formats={h:function(a,b){return a?h.digits(a):b.hour%f||f},hh:function(a,b){return a?2:h.lead(b.hour%f||f)},H:function(a,b){return a?h.digits(a):""+b.hour%24},HH:function(a,b){return a?h.digits(a):h.lead(b.hour%24)},i:function(a,b){return a?2:h.lead(b.mins)},a:function(a,b){return a?4:g/2>b.time%g?"a.m.":"p.m."},A:function(a,b){return a?2:g/2>b.time%g?"AM":"PM"},toArray:function(a){return a.split(/(h{1,2}|H{1,2}|i|a|A|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return h.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}},c.prototype.isTimeExact=function(a,c){var d=this;return h.isInteger(a)&&h.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(h.isDate(a)||b.isArray(a))&&(h.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isTimeExact(a.from,c.from)&&d.isTimeExact(a.to,c.to):!1},c.prototype.isTimeOverlap=function(a,c){var d=this;return h.isInteger(a)&&(h.isDate(c)||b.isArray(c))?a===d.create(c).hour:h.isInteger(c)&&(h.isDate(a)||b.isArray(a))?c===d.create(a).hour:b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,f=0;f<e.length;f+=1)if(d.isTimeExact(a,e[f])){c=!0;break}c||(h.isInteger(a)||h.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,f=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,g,i,j;for(i=0;f>i;i+=1){if(g=e[i],d.isTimeExact(g,a)){c=e[i]=null,j=!0;break}if(d.isTimeOverlap(g,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[2]||c.push("inverted")):h.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;f>i;i+=1)if(d.isTimeExact(e[i],a)){e[i]=null;break}if(j)for(i=0;f>i;i+=1)if(d.isTimeOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.i=function(a,b){return h.isInteger(b)&&b>0?b:this.item.interval},c.prototype.nodes=function(a){var b=this,c=b.settings,d=b.item.select,e=b.item.highlight,f=b.item.view,g=b.item.disable;return h.node("ul",h.group({min:b.item.min.pick,max:b.item.max.pick,i:b.item.interval,node:"li",item:function(a){a=b.create(a);var i=a.pick,j=d&&d.pick==i,k=e&&e.pick==i,l=g&&b.disabled(a);return[h.trigger(b.formats.toString,b,[h.trigger(c.formatLabel,b,[a])||c.format,a]),function(a){return j&&a.push(c.klass.selected),k&&a.push(c.klass.highlighted),f&&f.pick==i&&a.push(c.klass.viewset),l&&a.push(c.klass.disabled),a.join(" ")}([c.klass.listItem]),"data-pick="+a.pick+" "+h.ariaAttr({role:"option",selected:j&&b.$node.val()===h.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:k?!0:null,disabled:l?!0:null})]}})+h.node("li",h.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+h.ariaAttr({controls:b.$node[0].id})),"",h.ariaAttr({role:"presentation"})),c.klass.list,h.ariaAttr({role:"listbox",controls:b.$node[0].id}))},c.defaults=function(a){return{clear:"Clear",format:"h:i A",interval:30,klass:{picker:a+" "+a+"--time",holder:a+"__holder",list:a+"__list",listItem:a+"__list-item",disabled:a+"__list-item--disabled",selected:a+"__list-item--selected",highlighted:a+"__list-item--highlighted",viewset:a+"__list-item--viewset",now:a+"__list-item--now",buttonClear:a+"__button--clear"}}}(a.klasses().picker),a.extend("pickatime",c)});
|
lib/simple-admin-pages/lib/pickadate/themes/default.css
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
.picker{font-size:16px;text-align:left;line-height:1.2;color:#000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
|
2 |
+
* Default mobile-first, responsive styling for pickadate.js
|
3 |
+
* Demo: http://amsul.github.io/pickadate.js
|
4 |
+
*/.picker__frame,.picker__holder{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;-webkit-transition:background .15s ease-out,top 0s .15s;-moz-transition:background .15s ease-out,top 0s .15s;transition:background .15s ease-out,top 0s .15s}.picker__frame{position:absolute;margin:0 auto;min-width:256px;max-width:666px;width:100%;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;-webkit-transition:all .15s ease-out;-moz-transition:all .15s ease-out;transition:all .15s ease-out}@media (min-height:33.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height:40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height:33.875em){.picker__wrap{display:block}}.picker__box{background:#fff;display:table-cell;vertical-align:middle}@media (min-height:26.5em){.picker__box{font-size:1.25em}}@media (min-height:33.875em){.picker__box{display:block;font-size:1.33em;border:1px solid #777;border-top-color:#898989;border-bottom-width:0;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;-webkit-box-shadow:0 12px 36px 16px rgba(0,0,0,.24);-moz-box-shadow:0 12px 36px 16px rgba(0,0,0,.24);box-shadow:0 12px 36px 16px rgba(0,0,0,.24)}}@media (min-height:40.125em){.picker__box{font-size:1.5em;border-bottom-width:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}}.picker--opened .picker__holder{top:0;zoom:1;background:rgba(0,0,0,.32);-webkit-transition:background .15s ease-out;-moz-transition:background .15s ease-out;transition:background .15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height:33.875em){.picker--opened .picker__frame{top:auto;bottom:0}}
|
lib/simple-admin-pages/lib/pickadate/themes/default.date.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{font-weight:500;display:inline-block;margin-left:.25em;margin-right:.25em}.picker__year{color:#999;font-size:.8em;font-style:italic}.picker__select--month,.picker__select--year{border:1px solid #b7b7b7;height:2em;padding:.5em;margin-left:.25em;margin-right:.25em}@media (min-width:24.5em){.picker__select--month,.picker__select--year{margin-top:-.5em}}.picker__select--month{width:35%}.picker__select--year{width:22.5%}.picker__select--month:focus,.picker__select--year:focus{border-color:#0089ec}.picker__nav--next,.picker__nav--prev{position:absolute;padding:.5em 1.25em;width:1em;height:1em;top:-.25em}@media (min-width:24.5em){.picker__nav--next,.picker__nav--prev{top:-.33em}}.picker__nav--prev{left:-1em;padding-right:1.25em}@media (min-width:24.5em){.picker__nav--prev{padding-right:1.5em}}.picker__nav--next{right:-1em;padding-left:1.25em}@media (min-width:24.5em){.picker__nav--next{padding-left:1.5em}}.picker__nav--next:before,.picker__nav--prev:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:.75em solid #000;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:.75em solid #000}.picker__nav--next:hover,.picker__nav--prev:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker__nav--disabled,.picker__nav--disabled:before,.picker__nav--disabled:before:hover,.picker__nav--disabled:hover{cursor:default;background:0 0;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:inherit;width:100%;margin-top:.75em;margin-bottom:.5em}@media (min-height:33.875em){.picker__table{margin-bottom:.75em}}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999;font-weight:500}@media (min-height:33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day{padding:.3125em 0;font-weight:200;border:1px solid transparent}.picker__day--today{color:#0089ec;position:relative}.picker__day--today:before{content:" ";position:absolute;top:2px;right:2px;width:0;height:0;border-top:.5em solid #0059bc;border-left:.5em solid transparent}.picker__day--selected,.picker__day--selected:hover{border-color:#0089ec}.picker__day--highlighted{background:#b1dcfb}.picker__day--disabled:before{border-top-color:#aaa}.picker__day--outfocus{color:#ddd}.picker__day--infocus:hover,.picker__day--outfocus:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker--focused .picker__day--highlighted,.picker__day--highlighted:hover{background:#0089ec;color:#fff}.picker__day--disabled,.picker__day--disabled:hover{background:#f5f5f5;border-color:#f5f5f5;color:#ddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbb}.picker__footer{text-align:center}.picker__button--clear,.picker__button--today{border:1px solid #fff;background:#fff;font-size:.8em;padding:.66em 0;font-weight:700;width:50%;display:inline-block;vertical-align:bottom}.picker__button--clear:hover,.picker__button--today:hover{cursor:pointer;color:#000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--clear:focus,.picker__button--today:focus{background:#b1dcfb;border-color:#0089ec;outline:0}.picker__button--clear:before,.picker__button--today:before{position:relative;display:inline-block;height:0}.picker__button--today:before{content:" ";margin-right:.45em;top:-.05em;width:0;border-top:.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{content:"\D7";margin-right:.35em;top:-.1em;color:#e20;vertical-align:top;font-size:1.1em}
|
lib/simple-admin-pages/lib/pickadate/themes/default.time.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.picker__list{list-style:none;padding:.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #ddd;border-top:1px solid #ddd;margin-bottom:-1px;position:relative;background:#fff;padding:.75em 1.25em}@media (min-height:46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--selected,.picker__list-item--selected:hover{border-color:#0089ec;z-index:10}.picker__list-item--highlighted{background:#b1dcfb}.picker--focused .picker__list-item--highlighted,.picker__list-item--highlighted:hover{background:#0089ec;color:#fff}.picker--focused .picker__list-item--disabled,.picker__list-item--disabled,.picker__list-item--disabled:hover{background:#f5f5f5;color:#ddd;cursor:default;border-color:#ddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:0 0;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:focus,.picker--time .picker__button--clear:hover{background:#b1dcfb;background:#e20;border-color:#e20;cursor:pointer;color:#fff;outline:0}.picker--time .picker__button--clear:before{top:-.25em;color:#666;font-size:1.25em;font-weight:700}.picker--time .picker__button--clear:focus:before,.picker--time .picker__button--clear:hover:before{color:#fff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height:40.125em){.picker--time .picker__box{margin-bottom:5em}}
|
lib/simple-admin-pages/lib/pickadate/themes/rtl.css
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Styling for RTL (right-to-left) languages using pickadate.js
|
3 |
+
*/.picker{direction:rtl}.picker__nav--next{right:auto;left:-1em}.picker__nav--prev{left:auto;right:-1em}.picker__nav--next:before{border-left:0;border-right:.75em solid #000}.picker__nav--prev:before{border-right:0;border-left:.75em solid #000}
|
lib/simple-admin-pages/lib/pickadate/translations/ar.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
$.extend($.fn.pickadate.defaults,{monthsFull:["يناير","فبراير","مارس","ابريل","مايو","يونيو","يوليو","اغسطس","سبتمبر","اكتوبر","نوفمبر","ديسمبر"],monthsShort:["يناير","فبراير","مارس","ابريل","مايو","يونيو","يوليو","اغسطس","سبتمبر","اكتوبر","نوفمبر","ديسمبر"],weekdaysFull:["الاحد","الاثنين","الثلاثاء","الاربعاء","الخميس","الجمعة","السبت"],weekdaysShort:["الاحد","الاثنين","الثلاثاء","الاربعاء","الخميس","الجمعة","السبت"],today:"اليوم",clear:"مسح",format:"yyyy mmmm dd",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/bg_BG.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["януари","февруари","март","април","май","юни","юли","август","септември","октомври","ноември","декември"],monthsShort:["янр","фев","мар","апр","май","юни","юли","авг","сеп","окт","ное","дек"],weekdaysFull:["неделя","понеделник","вторник","сряда","четвъртък","петък","събота"],weekdaysShort:["нд","пн","вт","ср","чт","пт","сб"],today:"днес",clear:"изтривам",firstDay:1,format:"d mmmm yyyy г.",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/bs_BA.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","mart","april","maj","juni","juli","august","septembar","oktobar","novembar","decembar"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["nedjelja","ponedjeljak","utorak","srijeda","cetvrtak","petak","subota"],weekdaysShort:["ne","po","ut","sr","če","pe","su"],today:"danas",clear:"izbrisati",firstDay:1,format:"dd. mmmm yyyy.",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/ca_ES.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Gener","Febrer","Març","Abril","Maig","juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],monthsShort:["Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Set","Oct","Nov","Des"],weekdaysFull:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],weekdaysShort:["diu","dil","dim","dmc","dij","div","dis"],today:"avui",clear:"esborrar",firstDay:1,format:"dddd d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/cs_CZ.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec"],monthsShort:["led","úno","bře","dub","kvě","čer","čvc","srp","zář","říj","lis","pro"],weekdaysFull:["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"],weekdaysShort:["ne","po","út","st","čt","pá","so"],today:"dnes",clear:"vymazat",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/da_DK.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","marts","april","maj","juni","juli","august","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],weekdaysShort:["søn","man","tir","ons","tor","fre","lør"],today:"i dag",clear:"slet",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/de_DE.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],weekdaysFull:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],weekdaysShort:["So","Mo","Di","Mi","Do","Fr","Sa"],today:"Heute",clear:"Löschen",firstDay:1,format:"dddd, dd. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/el_GR.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος"],monthsShort:["Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ"],weekdaysFull:["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"],weekdaysShort:["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"],today:"σήμερα",clear:"Διαγραφή",firstDay:1,format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/es_ES.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"],monthsShort:["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic"],weekdaysFull:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],weekdaysShort:["dom","lun","mar","mié","jue","vie","sáb"],today:"hoy",clear:"borrar",firstDay:1,format:"dddd d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/et_EE.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["jaanuar","veebruar","märts","aprill","mai","juuni","juuli","august","september","oktoober","november","detsember"],monthsShort:["jaan","veebr","märts","apr","mai","juuni","juuli","aug","sept","okt","nov","dets"],weekdaysFull:["pühapäev","esmaspäev","teisipäev","kolmapäev","neljapäev","reede","laupäev"],weekdaysShort:["püh","esm","tei","kol","nel","ree","lau"],today:"täna",clear:"kustutama",firstDay:1,format:"d. mmmm yyyy. a",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/eu_ES.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["urtarrila","otsaila","martxoa","apirila","maiatza","ekaina","uztaila","abuztua","iraila","urria","azaroa","abendua"],monthsShort:["urt","ots","mar","api","mai","eka","uzt","abu","ira","urr","aza","abe"],weekdaysFull:["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"],weekdaysShort:["ig.","al.","ar.","az.","og.","or.","lr."],today:"gaur",clear:"garbitu",firstDay:1,format:"dddd, yyyy(e)ko mmmmren da",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/fi_FI.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tammi","helmi","maalis","huhti","touko","kesä","heinä","elo","syys","loka","marras","joulu"],weekdaysFull:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],weekdaysShort:["su","ma","ti","ke","to","pe","la"],today:"tänään",clear:"tyhjennä",firstDay:1,format:"d.m.yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/fr_FR.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthsShort:["Jan","Fev","Mar","Avr","Mai","Juin","Juil","Aou","Sep","Oct","Nov","Dec"],weekdaysFull:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],weekdaysShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],today:"Aujourd'hui",clear:"Effacer",firstDay:1,format:"dd mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/gl_ES.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Xaneiro","Febreiro","Marzo","Abril","Maio","Xuño","Xullo","Agosto","Setembro","Outubro","Novembro","Decembro"],monthsShort:["xan","feb","mar","abr","mai","xun","xul","ago","sep","out","nov","dec"],weekdaysFull:["domingo","luns","martes","mércores","xoves","venres","sábado"],weekdaysShort:["dom","lun","mar","mér","xov","ven","sab"],today:"hoxe",clear:"borrar",firstDay:1,format:"dddd d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/he_IL.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthsShort:["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ"],weekdaysFull:["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום ששי","יום שבת"],weekdaysShort:["א","ב","ג","ד","ה","ו","ש"],today:"היום",clear:"למחוק",format:"yyyy mmmmב d dddd",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/hr_HR.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["sijećanj","veljača","ožujak","travanj","svibanj","lipanj","srpanj","kolovoz","rujan","listopad","studeni","prosinac"],monthsShort:["sij","velj","ožu","tra","svi","lip","srp","kol","ruj","lis","stu","pro"],weekdaysFull:["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"],weekdaysShort:["ned","pon","uto","sri","čet","pet","sub"],today:"danas",clear:"izbrisati",firstDay:1,format:"d. mmmm yyyy.",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/hu_HU.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["január","február","március","aprilis","május","június","július","augusztus","szeptember","október","november","december"],monthsShort:["jan","febr","márc","apr","máj","jún","júl","aug","szept","okt","nov","dec"],weekdaysFull:["vasámap","hétfö","kedd","szerda","csütörtök","péntek","szombat"],weekdaysShort:["V","H","K","SZ","CS","P","SZ"],today:"ma",clear:"töröl",firstDay:1,format:"yyyy. mmmm dd.",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/id_ID.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des"],weekdaysFull:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],weekdaysShort:["Min","Sen","Sel","Rab","Kam","Jum","Sab"],today:"hari ini",clear:"menghapus",firstDay:1,format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/is_IS.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["janúar","febrúar","mars","apríl","maí","júní","júlí","ágúst","september","október","nóvember","desember"],monthsShort:["jan","feb","mar","apr","maí","jún","júl","ágú","sep","okt","nóv","des"],weekdaysFull:["sunnudagur","mánudagur","þriðjudagur","miðvikudagur","fimmtudagur","föstudagur","laugardagur"],weekdaysShort:["sun","mán","þri","mið","fim","fös","lau"],today:"Í dag",clear:"Hreinsa",firstDay:1,format:"dd. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/it_IT.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre"],monthsShort:["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic"],weekdaysFull:["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"],weekdaysShort:["dom","lun","mar","mer","gio","ven","sab"],today:"oggi",clear:"cancellare",firstDay:1,format:"dddd d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/ja_JP.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],weekdaysFull:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],weekdaysShort:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],today:"今日",clear:"消去",firstDay:1,format:"yyyy mm dd",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/ko_KR.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],monthsShort:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],weekdaysFull:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],weekdaysShort:["일","월","화","수","목","금","토"],today:"오늘",clear:"취소",firstDay:1,format:"yyyy 년 mm 월 dd 일",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/nl_NL.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthsShort:["jan","feb","maa","apr","mei","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],weekdaysShort:["zo","ma","di","wo","do","vr","za"],today:"vandaag",clear:"verwijderen",firstDay:1,format:"dddd d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/no_NO.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember"],monthsShort:["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des"],weekdaysFull:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],weekdaysShort:["søn","man","tir","ons","tor","fre","lør"],today:"i dag",clear:"nullstill",firstDay:1,format:"dd. mmm. yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/pl_PL.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień"],monthsShort:["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru"],weekdaysFull:["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"],weekdaysShort:["N","Pn","Wt","Śr","Cz","Pt","So"],today:"dzisiaj",clear:"usunąć",firstDay:1,format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/pt_BR.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],monthsShort:["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"],weekdaysFull:["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"],weekdaysShort:["dom","seg","ter","qua","qui","sex","sab"],today:"hoje",clear:"excluir",format:"dddd, d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/pt_PT.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],monthsShort:["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"],weekdaysFull:["domingo","segunda","terça","quarta","quinta","sexta","sábado"],weekdaysShort:["dom","seg","ter","qua","qui","sex","sab"],today:"hoje",clear:"excluir",format:"d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/ro_RO.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["ianuarie","februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie"],monthsShort:["ian","feb","mar","apr","mai","iun","iul","aug","sep","oct","noi","dec"],weekdaysFull:["duminică","luni","marţi","miercuri","joi","vineri","sâmbătă"],weekdaysShort:["D","L","Ma","Mi","J","V","S"],today:"azi",clear:"șterge",firstDay:1,format:"dd mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/ru_RU.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Января","Февраля","Марта","Апреля","Мая","Июня","Июля","Августа","Сентября","Октября","Ноября","Декабря"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],weekdaysFull:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],weekdaysShort:["вс","пн","вт","ср","чт","пт","сб"],today:"сегодня",clear:"удалить",firstDay:1,format:"d mmmm yyyy г.",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/sk_SK.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december"],monthsShort:["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"],weekdaysFull:["nedeļľa","pondelok","utorok","streda","š̌švrtok","piatok","sobota"],weekdaysShort:["Ne","Po","Ut","St","Št","Pi","So"],today:"dnes",clear:"vymazať",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/sl_SI.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","marec","april","maj","junij","julij","avgust","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec"],weekdaysFull:["nedelja","ponedeljek","torek","sreda","četrtek","petek","sobota"],weekdaysShort:["ned","pon","tor","sre","čet","pet","sob"],today:"danes",clear:"izbriši",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/sv_SE.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],weekdaysShort:["sön","mån","tis","ons","tor","fre","lör"],today:"i dag",clear:"bort",firstDay:1,format:"d/m yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/th_TH.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthsShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],weekdaysFull:["อาทติย","จันทร","องัคาร","พุธ","พฤหสั บดี","ศกุร","เสาร"],weekdaysShort:["อ.","จ.","อ.","พ.","พฤ.","ศ.","ส."],today:"วันนี้",clear:"ลบ",format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/tr_TR.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"],monthsShort:["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara"],weekdaysFull:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],weekdaysShort:["Pzr","Pzt","Sal","Çrş","Prş","Cum","Cmt"],today:"bugün",clear:"sil",firstDay:1,format:"dd mmmm yyyy dddd",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/uk_UA.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["січень","лютий","березень","квітень","травень","червень","липень","серпень","вересень","жовтень","листопад","грудень"],monthsShort:["січ","лют","бер","кві","тра","чер","лип","сер","вер","жов","лис","гру"],weekdaysFull:["неділя","понеділок","вівторок","середа","четвер","п‘ятниця","субота"],weekdaysShort:["нд","пн","вт","ср","чт","пт","сб"],today:"сьогодні",clear:"викреслити",firstDay:1,format:"dd mmmm yyyy p.",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/zh_CN.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["一","二","三","四","五","六","七","八","九","十","十一","十二"],weekdaysFull:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],weekdaysShort:["日","一","二","三","四","五","六"],today:"今日",clear:"删",firstDay:1,format:"yyyy 年 mm 月 dd 日",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/lib/pickadate/translations/zh_TW.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["一","二","三","四","五","六","七","八","九","十","十一","十二"],weekdaysFull:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],weekdaysShort:["日","一","二","三","四","五","六"],today:"今天",clear:"清除",firstDay:1,format:"yyyy 年 mm 月 dd 日",formatSubmit:"yyyy/mm/dd"});
|
lib/simple-admin-pages/simple-admin-pages.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Simple Admin Pages
|
5 |
+
*
|
6 |
+
* This is a very small utility library to easily add new admin pages to the
|
7 |
+
* WordPress admin interface. It simply collects WordPress' useful Settings API
|
8 |
+
* into reuseable classes.
|
9 |
+
*
|
10 |
+
* Created by Nate Wright
|
11 |
+
*
|
12 |
+
*
|
13 |
+
* @since 1.0
|
14 |
+
* @package Simple Admin Pages
|
15 |
+
* @license GNU GPL 2 or later
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Always load the library files attached to this copy of SAP
|
20 |
+
*
|
21 |
+
* This fixes a compatibility bug if two versions of the library are being
|
22 |
+
* loaded by different plugins/themes. However, versions prior to 2.0 do not
|
23 |
+
* include this and can cause compatibility issues.
|
24 |
+
*/
|
25 |
+
require_once( 'classes/Library.class.php' );
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Initialize the appropriate version of the libary.
|
29 |
+
*
|
30 |
+
* This function should remain backwards compatible at all times, so that the
|
31 |
+
* initialization function from version 1.0 will still be able to initialize
|
32 |
+
* the library appropriately for version 2.0. This way, if two plugins exist
|
33 |
+
* with different versions, the plugin creator will still be able to initialize
|
34 |
+
* their library.
|
35 |
+
*
|
36 |
+
* @since 1.0
|
37 |
+
*/
|
38 |
+
if ( !function_exists( 'sap_initialize_library' ) ) {
|
39 |
+
|
40 |
+
function sap_initialize_library( $args = array() ) {
|
41 |
+
|
42 |
+
// Exit early if no version was provided
|
43 |
+
if ( !isset( $args['version'] ) ) {
|
44 |
+
return null;
|
45 |
+
}
|
46 |
+
|
47 |
+
// Set the textdomain for translation
|
48 |
+
if ( !defined( 'SAP_TEXTDOMAIN' ) ) {
|
49 |
+
define( 'SAP_TEXTDOMAIN', 'sapdomain' );
|
50 |
+
}
|
51 |
+
|
52 |
+
$lib_class_name = 'sapLibrary_' . str_replace( '.', '_', $args['version'] );
|
53 |
+
|
54 |
+
return new $lib_class_name( $args );
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
readme.txt
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Business Profile ===
|
2 |
+
Contributors: NateWr
|
3 |
+
Author URI: https://github.com/NateWr
|
4 |
+
Plugin URL: http://themeofthecrop.com
|
5 |
+
Requires at Least: 3.9
|
6 |
+
Tested Up To: 3.9.1
|
7 |
+
Tags: business profile, address, google map, schema, contact, phone, address, seo
|
8 |
+
Stable tag: 1.0
|
9 |
+
License: GPLv2 or later
|
10 |
+
Donate link: http://themeofthecrop.com
|
11 |
+
|
12 |
+
Display your business's contact details with seo-friendly Schema.org markup. Supports a Google Map, opening hours and more.
|
13 |
+
|
14 |
+
== Description ==
|
15 |
+
|
16 |
+
Add your business contact details to your site with seo-friendly Schema.org markup. This plugin adds a Contact Card widget and a `[contact-card]` shortcode. You can use these to display the following on any page:
|
17 |
+
|
18 |
+
* Business name
|
19 |
+
* Address
|
20 |
+
* Phone number
|
21 |
+
* Contact page link or email address
|
22 |
+
* Link to Google Map with directions to your establishment
|
23 |
+
* Google Map showing your location
|
24 |
+
* Opening hours
|
25 |
+
|
26 |
+
Schema.org markup helps search engines like Google discover your address, phone number and opening hours so that they can display them with your listing on Google.
|
27 |
+
|
28 |
+
**Sorry, it does not support multiple locations.**
|
29 |
+
|
30 |
+
This plugin is part of a group of plugins in development for restaurants. Check out the [Food and Drink Menu](http://wordpress.org/plugins/food-and-drink-menu/) and [Restaurant Reservations](http://wordpress.org/plugins/restaurant-reservations/) plugins as well.
|
31 |
+
|
32 |
+
= How to use =
|
33 |
+
|
34 |
+
There is a short guide to using the plugin in the /docs/ folder. It can be accessed by following the Help link listed under the plugin on the Plugins page in your WordPress admin area.
|
35 |
+
|
36 |
+
= Developers =
|
37 |
+
|
38 |
+
This plugin is packed with hooks so you can extend it as needed. Development takes place on [GitHub](https://github.com/NateWr/business-profile/), so fork it up.
|
39 |
+
|
40 |
+
== Installation ==
|
41 |
+
|
42 |
+
1. Unzip `business-profile.zip`
|
43 |
+
2. Upload the contents of `business-profile.zip` to the `/wp-content/plugins/` directory
|
44 |
+
3. Activate the plugin through the 'Plugins' menu in WordPress
|
45 |
+
4. Go to the Business Profile page in your admin menu. You will find it near the bottom.
|
46 |
+
|
47 |
+
== Screenshots ==
|
48 |
+
|
49 |
+
1. Display a full contact card on the front-end with the shortcode [contact-card] or use the widget to add it to a sidebar.
|
50 |
+
2. An easy-to-use form lets you add all of the information, locate the correct map coordinates and set up your opening hours.
|
51 |
+
3. Choose what information to display with the widget, or check out the shortcode attributes in the help document included.
|
52 |
+
|
53 |
+
== Changelog ==
|
54 |
+
|
55 |
+
= 1.0 (2014-07-16) =
|
56 |
+
* Initial public release on WordPress.org
|
57 |
+
* Add an option to display a link to a booking form if the Restaurant Reservations plugin is active
|
58 |
+
* Fix: skip a scheduling rule if no weekdays are set. h/t @jasonhobbsllc
|
59 |
+
|
60 |
+
= 0.0.1 (2014-05-26) =
|
61 |
+
* Initial release
|
62 |
+
|
63 |
+
== Upgrade Notice ==
|
64 |
+
|
65 |
+
= 1.0 =
|
66 |
+
This initial public release adds an integration with the Restaurant Reservations plugin. If the plugin is active it will now let you display a link to the booking form.
|
screenshot-1.png
ADDED
Binary file
|
screenshot-2.png
ADDED
Binary file
|
screenshot-3.png
ADDED
Binary file
|