Amazon Associates Link Builder - Version 1.4.3

Version Description

This update fixes the issue of add shortcode button not clickable for some users after v1.4.2.

Download this release

Release Info

Developer amazonlinkbuilder
Plugin Icon 128x128 Amazon Associates Link Builder
Version 1.4.3
Comparing to
See all releases

Code changes from version 1.4.2 to 1.4.3

Files changed (83) hide show
  1. COPYING.txt +285 -285
  2. NOTICE.txt +76 -76
  3. aalb_admin_item_search_items.hbs +27 -15
  4. aalb_config.php +237 -236
  5. admin/aalb_admin.php +258 -239
  6. admin/css/aalb_admin.css +383 -379
  7. admin/js/aalb_admin.js +408 -394
  8. admin/partials/aalb_editor_search_box.php +30 -0
  9. admin/partials/aalb_meta_box.php +91 -95
  10. admin/sidebar/aalb_sidebar.php +135 -135
  11. admin/sidebar/js/aalb_credentials.js +54 -54
  12. admin/sidebar/js/aalb_template.js +113 -113
  13. admin/sidebar/partials/aalb_about.php +170 -170
  14. admin/sidebar/partials/aalb_admin_ui_common.php +32 -32
  15. admin/sidebar/partials/aalb_credentials.php +148 -148
  16. admin/sidebar/partials/aalb_templates.php +252 -252
  17. admin/sidebar/partials/aalb_ui_common.php +33 -33
  18. amazon-associates-link-builder.php +101 -114
  19. bin/install-wp-tests.sh +118 -118
  20. css/aalb_basics.css +83 -83
  21. includes/aalb_activator.php +94 -82
  22. includes/aalb_admin_notice_manager.php +85 -0
  23. includes/aalb_autoloader.php +72 -72
  24. includes/aalb_cache_loader.php +88 -88
  25. includes/aalb_cache_template_loader.php +53 -53
  26. includes/aalb_compatibility_helper.php +81 -0
  27. includes/aalb_config_loader.php +77 -77
  28. includes/aalb_deactivator.php +72 -72
  29. includes/aalb_helper.php +297 -297
  30. includes/aalb_hook_loader.php +86 -86
  31. includes/aalb_manager.php +84 -83
  32. includes/aalb_remote_loader.php +99 -99
  33. includes/aalb_template_engine.php +146 -146
  34. lib/php/Mustache/Autoloader.php +74 -74
  35. lib/php/Mustache/Cache.php +36 -36
  36. lib/php/Mustache/Cache/AbstractCache.php +60 -60
  37. lib/php/Mustache/Cache/FilesystemCache.php +155 -155
  38. lib/php/Mustache/Cache/NoopCache.php +47 -47
  39. lib/php/Mustache/Compiler.php +684 -684
  40. lib/php/Mustache/Context.php +242 -242
  41. lib/php/Mustache/Engine.php +787 -787
  42. lib/php/Mustache/Exception.php +18 -18
  43. lib/php/Mustache/Exception/InvalidArgumentException.php +18 -18
  44. lib/php/Mustache/Exception/LogicException.php +18 -18
  45. lib/php/Mustache/Exception/RuntimeException.php +18 -18
  46. lib/php/Mustache/Exception/SyntaxException.php +36 -36
  47. lib/php/Mustache/Exception/UnknownFilterException.php +32 -32
  48. lib/php/Mustache/Exception/UnknownHelperException.php +32 -32
  49. lib/php/Mustache/Exception/UnknownTemplateException.php +32 -32
  50. lib/php/Mustache/HelperCollection.php +172 -172
  51. lib/php/Mustache/LICENSE +21 -21
  52. lib/php/Mustache/LambdaHelper.php +76 -76
  53. lib/php/Mustache/Loader.php +27 -27
  54. lib/php/Mustache/Loader/ArrayLoader.php +79 -79
  55. lib/php/Mustache/Loader/CascadingLoader.php +69 -69
  56. lib/php/Mustache/Loader/FilesystemLoader.php +124 -124
  57. lib/php/Mustache/Loader/InlineLoader.php +123 -123
  58. lib/php/Mustache/Loader/MutableLoader.php +31 -31
  59. lib/php/Mustache/Loader/StringLoader.php +39 -39
  60. lib/php/Mustache/Logger.php +126 -126
  61. lib/php/Mustache/Logger/AbstractLogger.php +121 -121
  62. lib/php/Mustache/Logger/StreamLogger.php +194 -194
  63. lib/php/Mustache/Parser.php +317 -317
  64. lib/php/Mustache/Template.php +180 -180
  65. lib/php/Mustache/Tokenizer.php +322 -322
  66. lib/php/Paapi/aalb_paapi_helper.php +129 -129
  67. lib/php/aalb_internationalization_helper.php +88 -88
  68. lib/php/aalb_tracking_api_helper.php +135 -135
  69. lib/php/aalb_validation_helper.php +112 -112
  70. lib/php/aalb_xml_helper.php +321 -321
  71. readme.txt +158 -153
  72. shortcode/aalb_shortcode.php +104 -104
  73. shortcode/aalb_shortcode_helper.php +195 -195
  74. shortcode/aalb_shortcode_loader.php +109 -109
  75. shortcode/aalb_shortcode_text.php +103 -103
  76. template/PriceLink.mustache +7 -7
  77. template/ProductAd.css +259 -259
  78. template/ProductAd.mustache +141 -141
  79. template/ProductCarousel.css +261 -261
  80. template/ProductCarousel.mustache +142 -142
  81. template/ProductGrid.css +261 -261
  82. template/ProductGrid.mustache +144 -144
  83. template/ProductLink.mustache +7 -7
COPYING.txt CHANGED
@@ -1,286 +1,286 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
-
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
- 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
6
-
7
- Everyone is permitted to copy and distribute verbatim copies
8
- of this license document, but changing it is not allowed.
9
-
10
- Preamble
11
-
12
- The licenses for most software are designed to take away your
13
- freedom to share and change it. By contrast, the GNU General Public
14
- License is intended to guarantee your freedom to share and change free
15
- software--to make sure the software is free for all its users. This
16
- General Public License applies to most of the Free Software
17
- Foundation's software and to any other program whose authors commit to
18
- using it. (Some other Free Software Foundation software is covered by
19
- the GNU Library General Public License instead.) You can apply it to
20
- your programs, too.
21
-
22
- When we speak of free software, we are referring to freedom, not
23
- price. Our General Public Licenses are designed to make sure that you
24
- have the freedom to distribute copies of free software (and charge for
25
- this service if you wish), that you receive source code or can get it
26
- if you want it, that you can change the software or use pieces of it
27
- in new free programs; and that you know you can do these things.
28
-
29
- To protect your rights, we need to make restrictions that forbid
30
- anyone to deny you these rights or to ask you to surrender the rights.
31
- These restrictions translate to certain responsibilities for you if you
32
- distribute copies of the software, or if you modify it.
33
-
34
- For example, if you distribute copies of such a program, whether
35
- gratis or for a fee, you must give the recipients all the rights that
36
- you have. You must make sure that they, too, receive or can get the
37
- source code. And you must show them these terms so they know their
38
- rights.
39
-
40
- We protect your rights with two steps: (1) copyright the software, and
41
- (2) offer you this license which gives you legal permission to copy,
42
- distribute and/or modify the software.
43
-
44
- Also, for each author's protection and ours, we want to make certain
45
- that everyone understands that there is no warranty for this free
46
- software. If the software is modified by someone else and passed on, we
47
- want its recipients to know that what they have is not the original, so
48
- that any problems introduced by others will not reflect on the original
49
- authors' reputations.
50
-
51
- Finally, any free program is threatened constantly by software
52
- patents. We wish to avoid the danger that redistributors of a free
53
- program will individually obtain patent licenses, in effect making the
54
- program proprietary. To prevent this, we have made it clear that any
55
- patent must be licensed for everyone's free use or not licensed at all.
56
-
57
- The precise terms and conditions for copying, distribution and
58
- modification follow.
59
-
60
- GNU GENERAL PUBLIC LICENSE
61
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
62
-
63
- 0. This License applies to any program or other work which contains
64
- a notice placed by the copyright holder saying it may be distributed
65
- under the terms of this General Public License. The "Program", below,
66
- refers to any such program or work, and a "work based on the Program"
67
- means either the Program or any derivative work under copyright law:
68
- that is to say, a work containing the Program or a portion of it,
69
- either verbatim or with modifications and/or translated into another
70
- language. (Hereinafter, translation is included without limitation in
71
- the term "modification".) Each licensee is addressed as "you".
72
-
73
- Activities other than copying, distribution and modification are not
74
- covered by this License; they are outside its scope. The act of
75
- running the Program is not restricted, and the output from the Program
76
- is covered only if its contents constitute a work based on the
77
- Program (independent of having been made by running the Program).
78
- Whether that is true depends on what the Program does.
79
-
80
- 1. You may copy and distribute verbatim copies of the Program's
81
- source code as you receive it, in any medium, provided that you
82
- conspicuously and appropriately publish on each copy an appropriate
83
- copyright notice and disclaimer of warranty; keep intact all the
84
- notices that refer to this License and to the absence of any warranty;
85
- and give any other recipients of the Program a copy of this License
86
- along with the Program.
87
-
88
- You may charge a fee for the physical act of transferring a copy, and
89
- you may at your option offer warranty protection in exchange for a fee.
90
-
91
- 2. You may modify your copy or copies of the Program or any portion
92
- of it, thus forming a work based on the Program, and copy and
93
- distribute such modifications or work under the terms of Section 1
94
- above, provided that you also meet all of these conditions:
95
-
96
- a) You must cause the modified files to carry prominent notices
97
- stating that you changed the files and the date of any change.
98
-
99
- b) You must cause any work that you distribute or publish, that in
100
- whole or in part contains or is derived from the Program or any
101
- part thereof, to be licensed as a whole at no charge to all third
102
- parties under the terms of this License.
103
-
104
- c) If the modified program normally reads commands interactively
105
- when run, you must cause it, when started running for such
106
- interactive use in the most ordinary way, to print or display an
107
- announcement including an appropriate copyright notice and a
108
- notice that there is no warranty (or else, saying that you provide
109
- a warranty) and that users may redistribute the program under
110
- these conditions, and telling the user how to view a copy of this
111
- License. (Exception: if the Program itself is interactive but
112
- does not normally print such an announcement, your work based on
113
- the Program is not required to print an announcement.)
114
-
115
- These requirements apply to the modified work as a whole. If
116
- identifiable sections of that work are not derived from the Program,
117
- and can be reasonably considered independent and separate works in
118
- themselves, then this License, and its terms, do not apply to those
119
- sections when you distribute them as separate works. But when you
120
- distribute the same sections as part of a whole which is a work based
121
- on the Program, the distribution of the whole must be on the terms of
122
- this License, whose permissions for other licensees extend to the
123
- entire whole, and thus to each and every part regardless of who wrote it.
124
- Thus, it is not the intent of this section to claim rights or contest
125
- your rights to work written entirely by you; rather, the intent is to
126
- exercise the right to control the distribution of derivative or
127
- collective works based on the Program.
128
-
129
- In addition, mere aggregation of another work not based on the Program
130
- with the Program (or with a work based on the Program) on a volume of
131
- a storage or distribution medium does not bring the other work under
132
- the scope of this License.
133
-
134
- 3. You may copy and distribute the Program (or a work based on it,
135
- under Section 2) in object code or executable form under the terms of
136
- Sections 1 and 2 above provided that you also do one of the following:
137
-
138
- a) Accompany it with the complete corresponding machine-readable
139
- source code, which must be distributed under the terms of Sections
140
- 1 and 2 above on a medium customarily used for software interchange; or,
141
-
142
- b) Accompany it with a written offer, valid for at least three
143
- years, to give any third party, for a charge no more than your
144
- cost of physically performing source distribution, a complete
145
- machine-readable copy of the corresponding source code, to be
146
- distributed under the terms of Sections 1 and 2 above on a medium
147
- customarily used for software interchange; or,
148
-
149
- c) Accompany it with the information you received as to the offer
150
- to distribute corresponding source code. (This alternative is
151
- allowed only for noncommercial distribution and only if you
152
- received the program in object code or executable form with such
153
- an offer, in accord with Subsection b above.)
154
-
155
- The source code for a work means the preferred form of the work for
156
- making modifications to it. For an executable work, complete source
157
- code means all the source code for all modules it contains, plus any
158
- associated interface definition files, plus the scripts used to
159
- control compilation and installation of the executable. However, as a
160
- special exception, the source code distributed need not include
161
- anything that is normally distributed (in either source or binary
162
- form) with the major components (compiler, kernel, and so on) of the
163
- operating system on which the executable runs, unless that component
164
- itself accompanies the executable.
165
-
166
- If distribution of executable or object code is made by offering
167
- access to copy from a designated place, then offering equivalent
168
- access to copy the source code from the same place counts as
169
- distribution of the source code, even though third parties are not
170
- compelled to copy the source along with the object code.
171
-
172
- 4. You may not copy, modify, sublicense, or distribute the Program
173
- except as expressly provided under this License. Any attempt
174
- otherwise to copy, modify, sublicense or distribute the Program is
175
- void, and will automatically terminate your rights under this License.
176
- However, parties who have received copies, or rights, from you under
177
- this License will not have their licenses terminated so long as such
178
- parties remain in full compliance.
179
-
180
- 5. You are not required to accept this License, since you have not
181
- signed it. However, nothing else grants you permission to modify or
182
- distribute the Program or its derivative works. These actions are
183
- prohibited by law if you do not accept this License. Therefore, by
184
- modifying or distributing the Program (or any work based on the
185
- Program), you indicate your acceptance of this License to do so, and
186
- all its terms and conditions for copying, distributing or modifying
187
- the Program or works based on it.
188
-
189
- 6. Each time you redistribute the Program (or any work based on the
190
- Program), the recipient automatically receives a license from the
191
- original licensor to copy, distribute or modify the Program subject to
192
- these terms and conditions. You may not impose any further
193
- restrictions on the recipients' exercise of the rights granted herein.
194
- You are not responsible for enforcing compliance by third parties to
195
- this License.
196
-
197
- 7. If, as a consequence of a court judgment or allegation of patent
198
- infringement or for any other reason (not limited to patent issues),
199
- conditions are imposed on you (whether by court order, agreement or
200
- otherwise) that contradict the conditions of this License, they do not
201
- excuse you from the conditions of this License. If you cannot
202
- distribute so as to satisfy simultaneously your obligations under this
203
- License and any other pertinent obligations, then as a consequence you
204
- may not distribute the Program at all. For example, if a patent
205
- license would not permit royalty-free redistribution of the Program by
206
- all those who receive copies directly or indirectly through you, then
207
- the only way you could satisfy both it and this License would be to
208
- refrain entirely from distribution of the Program.
209
-
210
- If any portion of this section is held invalid or unenforceable under
211
- any particular circumstance, the balance of the section is intended to
212
- apply and the section as a whole is intended to apply in other
213
- circumstances.
214
-
215
- It is not the purpose of this section to induce you to infringe any
216
- patents or other property right claims or to contest validity of any
217
- such claims; this section has the sole purpose of protecting the
218
- integrity of the free software distribution system, which is
219
- implemented by public license practices. Many people have made
220
- generous contributions to the wide range of software distributed
221
- through that system in reliance on consistent application of that
222
- system; it is up to the author/donor to decide if he or she is willing
223
- to distribute software through any other system and a licensee cannot
224
- impose that choice.
225
-
226
- This section is intended to make thoroughly clear what is believed to
227
- be a consequence of the rest of this License.
228
-
229
- 8. If the distribution and/or use of the Program is restricted in
230
- certain countries either by patents or by copyrighted interfaces, the
231
- original copyright holder who places the Program under this License
232
- may add an explicit geographical distribution limitation excluding
233
- those countries, so that distribution is permitted only in or among
234
- countries not thus excluded. In such case, this License incorporates
235
- the limitation as if written in the body of this License.
236
-
237
- 9. The Free Software Foundation may publish revised and/or new versions
238
- of the General Public License from time to time. Such new versions will
239
- be similar in spirit to the present version, but may differ in detail to
240
- address new problems or concerns.
241
-
242
- Each version is given a distinguishing version number. If the Program
243
- specifies a version number of this License which applies to it and "any
244
- later version", you have the option of following the terms and conditions
245
- either of that version or of any later version published by the Free
246
- Software Foundation. If the Program does not specify a version number of
247
- this License, you may choose any version ever published by the Free Software
248
- Foundation.
249
-
250
- 10. If you wish to incorporate parts of the Program into other free
251
- programs whose distribution conditions are different, write to the author
252
- to ask for permission. For software which is copyrighted by the Free
253
- Software Foundation, write to the Free Software Foundation; we sometimes
254
- make exceptions for this. Our decision will be guided by the two goals
255
- of preserving the free status of all derivatives of our free software and
256
- of promoting the sharing and reuse of software generally.
257
-
258
- NO WARRANTY
259
-
260
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
- REPAIR OR CORRECTION.
269
-
270
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
- POSSIBILITY OF SUCH DAMAGES.
279
-
280
- END OF TERMS AND CONDITIONS
281
-
282
-
283
- Note: Other license terms may apply to certain, identified software files contained
284
- within or distributed with the accompanying software if such terms are included in
285
- the directory containing the accompanying software. Such other license terms will
286
  then apply in lieu of the terms of the software license above.
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
+ 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
6
+
7
+ Everyone is permitted to copy and distribute verbatim copies
8
+ of this license document, but changing it is not allowed.
9
+
10
+ Preamble
11
+
12
+ The licenses for most software are designed to take away your
13
+ freedom to share and change it. By contrast, the GNU General Public
14
+ License is intended to guarantee your freedom to share and change free
15
+ software--to make sure the software is free for all its users. This
16
+ General Public License applies to most of the Free Software
17
+ Foundation's software and to any other program whose authors commit to
18
+ using it. (Some other Free Software Foundation software is covered by
19
+ the GNU Library General Public License instead.) You can apply it to
20
+ your programs, too.
21
+
22
+ When we speak of free software, we are referring to freedom, not
23
+ price. Our General Public Licenses are designed to make sure that you
24
+ have the freedom to distribute copies of free software (and charge for
25
+ this service if you wish), that you receive source code or can get it
26
+ if you want it, that you can change the software or use pieces of it
27
+ in new free programs; and that you know you can do these things.
28
+
29
+ To protect your rights, we need to make restrictions that forbid
30
+ anyone to deny you these rights or to ask you to surrender the rights.
31
+ These restrictions translate to certain responsibilities for you if you
32
+ distribute copies of the software, or if you modify it.
33
+
34
+ For example, if you distribute copies of such a program, whether
35
+ gratis or for a fee, you must give the recipients all the rights that
36
+ you have. You must make sure that they, too, receive or can get the
37
+ source code. And you must show them these terms so they know their
38
+ rights.
39
+
40
+ We protect your rights with two steps: (1) copyright the software, and
41
+ (2) offer you this license which gives you legal permission to copy,
42
+ distribute and/or modify the software.
43
+
44
+ Also, for each author's protection and ours, we want to make certain
45
+ that everyone understands that there is no warranty for this free
46
+ software. If the software is modified by someone else and passed on, we
47
+ want its recipients to know that what they have is not the original, so
48
+ that any problems introduced by others will not reflect on the original
49
+ authors' reputations.
50
+
51
+ Finally, any free program is threatened constantly by software
52
+ patents. We wish to avoid the danger that redistributors of a free
53
+ program will individually obtain patent licenses, in effect making the
54
+ program proprietary. To prevent this, we have made it clear that any
55
+ patent must be licensed for everyone's free use or not licensed at all.
56
+
57
+ The precise terms and conditions for copying, distribution and
58
+ modification follow.
59
+
60
+ GNU GENERAL PUBLIC LICENSE
61
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
62
+
63
+ 0. This License applies to any program or other work which contains
64
+ a notice placed by the copyright holder saying it may be distributed
65
+ under the terms of this General Public License. The "Program", below,
66
+ refers to any such program or work, and a "work based on the Program"
67
+ means either the Program or any derivative work under copyright law:
68
+ that is to say, a work containing the Program or a portion of it,
69
+ either verbatim or with modifications and/or translated into another
70
+ language. (Hereinafter, translation is included without limitation in
71
+ the term "modification".) Each licensee is addressed as "you".
72
+
73
+ Activities other than copying, distribution and modification are not
74
+ covered by this License; they are outside its scope. The act of
75
+ running the Program is not restricted, and the output from the Program
76
+ is covered only if its contents constitute a work based on the
77
+ Program (independent of having been made by running the Program).
78
+ Whether that is true depends on what the Program does.
79
+
80
+ 1. You may copy and distribute verbatim copies of the Program's
81
+ source code as you receive it, in any medium, provided that you
82
+ conspicuously and appropriately publish on each copy an appropriate
83
+ copyright notice and disclaimer of warranty; keep intact all the
84
+ notices that refer to this License and to the absence of any warranty;
85
+ and give any other recipients of the Program a copy of this License
86
+ along with the Program.
87
+
88
+ You may charge a fee for the physical act of transferring a copy, and
89
+ you may at your option offer warranty protection in exchange for a fee.
90
+
91
+ 2. You may modify your copy or copies of the Program or any portion
92
+ of it, thus forming a work based on the Program, and copy and
93
+ distribute such modifications or work under the terms of Section 1
94
+ above, provided that you also meet all of these conditions:
95
+
96
+ a) You must cause the modified files to carry prominent notices
97
+ stating that you changed the files and the date of any change.
98
+
99
+ b) You must cause any work that you distribute or publish, that in
100
+ whole or in part contains or is derived from the Program or any
101
+ part thereof, to be licensed as a whole at no charge to all third
102
+ parties under the terms of this License.
103
+
104
+ c) If the modified program normally reads commands interactively
105
+ when run, you must cause it, when started running for such
106
+ interactive use in the most ordinary way, to print or display an
107
+ announcement including an appropriate copyright notice and a
108
+ notice that there is no warranty (or else, saying that you provide
109
+ a warranty) and that users may redistribute the program under
110
+ these conditions, and telling the user how to view a copy of this
111
+ License. (Exception: if the Program itself is interactive but
112
+ does not normally print such an announcement, your work based on
113
+ the Program is not required to print an announcement.)
114
+
115
+ These requirements apply to the modified work as a whole. If
116
+ identifiable sections of that work are not derived from the Program,
117
+ and can be reasonably considered independent and separate works in
118
+ themselves, then this License, and its terms, do not apply to those
119
+ sections when you distribute them as separate works. But when you
120
+ distribute the same sections as part of a whole which is a work based
121
+ on the Program, the distribution of the whole must be on the terms of
122
+ this License, whose permissions for other licensees extend to the
123
+ entire whole, and thus to each and every part regardless of who wrote it.
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+
283
+ Note: Other license terms may apply to certain, identified software files contained
284
+ within or distributed with the accompanying software if such terms are included in
285
+ the directory containing the accompanying software. Such other license terms will
286
  then apply in lieu of the terms of the software license above.
NOTICE.txt CHANGED
@@ -1,77 +1,77 @@
1
- AmazonAssociatesLinkBuilder
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
-
4
- The Amazon Associates Link Builder plugin includes the following third-party software/licensing:
5
-
6
- ** sha2.js
7
- Copyright (c) 2003-2004, Angel Marin
8
- All rights reserved.
9
-
10
- Redistribution and use in source and binary forms, with or without modification,
11
- are permitted provided that the following conditions are met:
12
-
13
- * Redistributions of source code must retain the above copyright notice, this
14
- list of conditions and the following disclaimer.
15
- * Redistributions in binary form must reproduce the above copyright notice,
16
- this list of conditions and the following disclaimer in the documentation
17
- and/or other materials provided with the distribution.
18
- * Neither the name of the <ORGANIZATION> nor the names of its contributors may
19
- be used to endorse or promote products derived from this software without
20
- specific prior written permission.
21
-
22
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
- IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30
- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31
- OF THE POSSIBILITY OF SUCH DAMAGE.
32
-
33
- ** jCarouselLite - v1.1 - http://www.gmarwaha.com/jquery/jcarousellite/
34
- Copyright (c) 2006-2014 Ganeshji Marwaha
35
-
36
- Permission is hereby granted, free of charge, to any person
37
- obtaining a copy of this software and associated documentation
38
- files (the "Software"), to deal in the Software without
39
- restriction, including without limitation the rights to use,
40
- copy, modify, merge, publish, distribute, sublicense, and/or sell
41
- copies of the Software, and to permit persons to whom the
42
- Software is furnished to do so, subject to the following
43
- conditions:
44
-
45
- The above copyright notice and this permission notice shall be
46
- included in all copies or substantial portions of the Software.
47
-
48
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
49
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
50
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
51
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
52
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
53
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
54
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
55
- OTHER DEALINGS IN THE SOFTWARE.
56
-
57
-
58
- ** Mustache - MIT License (MIT)
59
- Copyright (c) 2010-2015 Justin Hileman
60
-
61
- Permission is hereby granted, free of charge, to any person obtaining a copy
62
- of this software and associated documentation files (the "Software"), to deal
63
- in the Software without restriction, including without limitation the rights
64
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65
- copies of the Software, and to permit persons to whom the Software is
66
- furnished to do so, subject to the following conditions:
67
-
68
- The above copyright notice and this permission notice shall be included in all
69
- copies or substantial portions of the Software.
70
-
71
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
72
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
73
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
74
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
75
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
76
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
77
  OR OTHER DEALINGS IN THE SOFTWARE.
1
+ AmazonAssociatesLinkBuilder
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ The Amazon Associates Link Builder plugin includes the following third-party software/licensing:
5
+
6
+ ** sha2.js
7
+ Copyright (c) 2003-2004, Angel Marin
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without modification,
11
+ are permitted provided that the following conditions are met:
12
+
13
+ * Redistributions of source code must retain the above copyright notice, this
14
+ list of conditions and the following disclaimer.
15
+ * Redistributions in binary form must reproduce the above copyright notice,
16
+ this list of conditions and the following disclaimer in the documentation
17
+ and/or other materials provided with the distribution.
18
+ * Neither the name of the <ORGANIZATION> nor the names of its contributors may
19
+ be used to endorse or promote products derived from this software without
20
+ specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31
+ OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ ** jCarouselLite - v1.1 - http://www.gmarwaha.com/jquery/jcarousellite/
34
+ Copyright (c) 2006-2014 Ganeshji Marwaha
35
+
36
+ Permission is hereby granted, free of charge, to any person
37
+ obtaining a copy of this software and associated documentation
38
+ files (the "Software"), to deal in the Software without
39
+ restriction, including without limitation the rights to use,
40
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ copies of the Software, and to permit persons to whom the
42
+ Software is furnished to do so, subject to the following
43
+ conditions:
44
+
45
+ The above copyright notice and this permission notice shall be
46
+ included in all copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
49
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
50
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
51
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
52
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
53
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
54
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
55
+ OTHER DEALINGS IN THE SOFTWARE.
56
+
57
+
58
+ ** Mustache - MIT License (MIT)
59
+ Copyright (c) 2010-2015 Justin Hileman
60
+
61
+ Permission is hereby granted, free of charge, to any person obtaining a copy
62
+ of this software and associated documentation files (the "Software"), to deal
63
+ in the Software without restriction, including without limitation the rights
64
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65
+ copies of the Software, and to permit persons to whom the Software is
66
+ furnished to do so, subject to the following conditions:
67
+
68
+ The above copyright notice and this permission notice shall be included in all
69
+ copies or substantial portions of the Software.
70
+
71
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
72
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
73
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
74
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
75
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
76
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
77
  OR OTHER DEALINGS IN THE SOFTWARE.
aalb_admin_item_search_items.hbs CHANGED
@@ -1,15 +1,27 @@
1
- <div class="aalb-modal-box">
2
- {{#each this}}
3
- <div class="aalb-admin-item-search-items-item" data-asin="{{asin}}">
4
- <div class="aalb-admin-item-search-items-item-img">
5
- <img id="aalb-admin-item-search-items-item-img" src="{{image}}" />
6
- </div>
7
- <div class="aalb-admin-item-search-items-item-title">
8
- {{title}}
9
- </div>
10
- <div class="aalb-admin-item-search-items-item-price">
11
- {{price}}
12
- </div>
13
- </div>
14
- {{/each}}
15
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ -->
12
+
13
+ <div class="aalb-modal-box">
14
+ {{#each this}}
15
+ <div class="aalb-admin-item-search-items-item" data-asin="{{asin}}">
16
+ <div class="aalb-admin-item-search-items-item-img">
17
+ <img id="aalb-admin-item-search-items-item-img" src="{{image}}" />
18
+ </div>
19
+ <div class="aalb-admin-item-search-items-item-title">
20
+ {{title}}
21
+ </div>
22
+ <div class="aalb-admin-item-search-items-item-price">
23
+ {{price}}
24
+ </div>
25
+ </div>
26
+ {{/each}}
27
+ </div>
aalb_config.php CHANGED
@@ -1,236 +1,237 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- //version
16
- define( 'AALB_PLUGIN_CURRENT_VERSION', '1.4.2' );
17
-
18
- //PHP version compatible for AALB plugin
19
- define('AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION','5.3.0');
20
-
21
- //Plugin Name
22
- define('AALB_PLUGIN_NAME','Amazon Associates Link Builder');
23
- //paths
24
- define( 'AALB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
25
- define( 'AALB_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
26
-
27
- //Project Title
28
- define( 'AALB_PROJECT_TITLE', 'Associates Link Builder' );
29
-
30
- /**
31
- * File paths
32
- */
33
-
34
- //Library
35
- define( 'MUSTACHE_AUTOLOADER_PHP', AALB_PLUGIN_DIR . 'lib/php/Mustache/Autoloader.php' );
36
- define( 'AALB_PAAPI_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/Paapi/aalb_paapi_helper.php' );
37
- define( 'AALB_VALIDATION_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_validation_helper.php' );
38
- define( 'AALB_XML_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_xml_helper.php' );
39
- define( 'AALB_TRACKING_API_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_tracking_api_helper.php' );
40
-
41
- //Shortcode
42
- define( 'AALB_SHORTCODE_PHP', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode.php' );
43
- define( 'AALB_SHORTCODE_TEXT_PHP', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_text.php' );
44
- define( 'AALB_SHORTCODE_LOADER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_loader.php' );
45
- define( 'AALB_SHORTCODE_HELPER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_helper.php' );
46
-
47
- //Shortcodes supported
48
- define( 'AALB_SHORTCODE_AMAZON_LINK', 'amazon_link' );
49
- define( 'AALB_SHORTCODE_AMAZON_TEXT', 'amazon_textlink' );
50
-
51
- //Admin
52
- define( 'AALB_SIDEBAR_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/aalb_sidebar.php' );
53
- define( 'AALB_ADMIN_PHP', AALB_PLUGIN_DIR . 'admin/aalb_admin.php' );
54
- define( 'AALB_ABOUT_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_about.php' );
55
- define( 'AALB_CREDENTIALS_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_credentials.php' );
56
- define( 'AALB_TEMPLATE_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_templates.php' );
57
-
58
- //Directories
59
- define( 'AALB_TEMPLATE_DIR', AALB_PLUGIN_DIR . 'template/' );
60
- define( 'AALB_ADMIN_DIR', AALB_PLUGIN_DIR . 'admin/' );
61
- define( 'AALB_SIDEBAR_DIR', AALB_PLUGIN_DIR . 'admin/sidebar/' );
62
- define( 'AALB_INCLUDES_DIR', AALB_PLUGIN_DIR . 'includes/' );
63
- define( 'AALB_PAAPI_DIR', AALB_PLUGIN_DIR . 'lib/php/Paapi/' );
64
- define( 'AALB_SHORTCODE_DIR', AALB_PLUGIN_DIR . 'shortcode/' );
65
- define( 'AALB_LIBRARY_DIR', AALB_PLUGIN_DIR . 'lib/php/' );
66
-
67
- //Includes
68
- define( 'AALB_ACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_activator.php' );
69
- define( 'AALB_DEACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_deactivator.php' );
70
- define( 'AALB_MANAGER', AALB_PLUGIN_DIR . 'includes/aalb_manager.php' );
71
- define( 'AALB_HOOK_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_hook_loader.php' );
72
- define( 'AALB_CACHE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_cache_loader.php' );
73
- define( 'AALB_REMOTE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_remote_loader.php' );
74
- define( 'AALB_AUTOLOADER', AALB_PLUGIN_DIR . 'includes/aalb_autoloader.php' );
75
-
76
- //Templates Directory
77
- define( 'AALB_TEMPLATE_URL', AALB_PLUGIN_URL . 'template/' );
78
- define( 'AALB_TEMPLATE_UPLOADS_FOLDER', 'amazon-associates-link-builder/template/' );
79
-
80
- //Partials
81
- define( 'AALB_META_BOX_PARTIAL', AALB_PLUGIN_DIR . 'admin/partials/aalb_meta_box.php' );
82
-
83
- //Proxy
84
- define( 'AALB_PROXY_URL', AALB_PLUGIN_URL . 'lib/php/Paapi/aalb_paapi_proxy.php' );
85
-
86
- //Tracking API Endpoint
87
- define( 'AALB_TRACKING_API_ENDPOINT', 'https://rx5hfxbp45.execute-api.us-east-1.amazonaws.com/aalb/' );
88
- define( 'AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM', 'source-tool=aalb' );
89
- define( 'AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM', 'aws-access-key-id=' );
90
-
91
- //Wordpress Pages
92
- define( 'WP_POST', 'post.php' );
93
- define( 'WP_POST_NEW', 'post-new.php' );
94
-
95
- /**
96
- * Styles and scripts
97
- */
98
-
99
- //Local Styles
100
- define( 'AALB_ADMIN_CSS', AALB_PLUGIN_URL . 'admin/css/aalb_admin.css' );
101
- define( 'AALB_BASICS_CSS', AALB_PLUGIN_URL . 'css/aalb_basics.css' );
102
-
103
- //Local Scripts
104
- define( 'AALB_SHA2_JS', AALB_PLUGIN_URL . 'lib/js/jssha2/sha2.js' );
105
- define( 'AALB_ADMIN_JS', AALB_PLUGIN_URL . 'admin/js/aalb_admin.js' );
106
- define( 'AALB_ADMIN_ITEM_SEARCH_ITEMS_URL', AALB_PLUGIN_URL . 'aalb_admin_item_search_items.hbs' );
107
- define( 'AALB_TEMPLATE_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_template.js' );
108
- define( 'AALB_CREDENTIALS_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_credentials.js' );
109
-
110
- //External Scripts
111
- define( 'HANDLEBARS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/handlebars.js/4.0.5/handlebars.min.js' );
112
- define( 'CODEMIRROR_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.js' );
113
- define( 'CODEMIRROR_MODE_XML_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/xml/xml.min.js' );
114
- define( 'CODEMIRROR_MODE_CSS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/css/css.min.js' );
115
-
116
- //External Styles
117
- define( 'FONT_AWESOME_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/font-awesome/4.5.0/css/font-awesome.min.css' );
118
- define( 'CODEMIRROR_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.css' );
119
-
120
- /**
121
- * Icons
122
- */
123
- define( 'AALB_SECURE_HOSTNAME', 'https://images-na.ssl-images-amazon.com/' );
124
- define( 'AALB_NORMAL_HOSTNAME', 'http://g-ecx.images-amazon.com/' );
125
- define( 'AALB_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon-2._V276841048_.png' );
126
- define( 'AALB_ADMIN_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon._V278877987_.png' );
127
- //AALB_ICON URL is generated by wordpress at run-time by checking the remotehost's encryption. Image source has different URLs depending upon the encryption used.
128
- if ( is_ssl() ) {
129
- define( 'AALB_ICON', AALB_SECURE_HOSTNAME . AALB_ICON_LOCATION );
130
- } else {
131
- define( 'AALB_ICON', AALB_NORMAL_HOSTNAME . AALB_ICON_LOCATION );
132
- }
133
- define( 'AALB_ADMIN_ICON', AALB_SECURE_HOSTNAME . AALB_ADMIN_ICON_LOCATION );
134
-
135
-
136
- /**
137
- * Constants
138
- */
139
-
140
- //Search result items. Paapi returns 10 items by default.
141
- define( 'AALB_MAX_SEARCH_RESULT_ITEMS', 9 );
142
- //List of Default Amazon Template names
143
- define( 'AALB_AMAZON_TEMPLATE_NAMES', 'ProductCarousel,ProductGrid,ProductAd,PriceLink,ProductLink' );
144
-
145
- //Database keys
146
- define( 'AALB_TEMPLATE_NAMES', 'aalb_template_names' );
147
- define( 'AALB_MARKETPLACE_NAMES', 'aalb_marketplace_names' );
148
- define( 'AALB_DEFAULT_TEMPLATE', 'aalb_default_template' );
149
- define( 'AALB_DEFAULT_STORE_ID', 'aalb_default_store_id' );
150
- define( 'AALB_DEFAULT_MARKETPLACE', 'aalb_default_marketplace' );
151
- define( 'AALB_AWS_ACCESS_KEY', 'aalb_aws_access_key' );
152
- define( 'AALB_AWS_SECRET_KEY', 'aalb_aws_secret_key' );
153
- define( 'AALB_CRED_CONFIG_GROUP', 'aalb_cred_config_group' );
154
- define( 'AALB_STORE_ID_NAMES', 'aalb_store_id_names' );
155
- define( 'AALB_SHOW_HTTP_WARNING_ONCE', 'aalb_show_http_warning_once' );
156
- define( 'AALB_PLUGIN_VERSION', 'aalb_plugin_version' );
157
-
158
- //Masking constant
159
- define( 'AALB_AWS_SECRET_KEY_MASK', '••••••••••••••••••••••••••••••••••••••••' );
160
-
161
-
162
- //Defaults in case DB doesn't contain them.
163
- define( 'AALB_DEFAULT_TEMPLATE_NAME', 'ProductCarousel' );
164
- define( 'AALB_DEFAULT_MARKETPLACE_NAME', 'US' );
165
- define( 'AALB_DEFAULT_STORE_ID_NAME', 'not-specified' );
166
-
167
- //Marketplaces
168
- define( 'MARKETPLACES_URL', 'https://webservices.amazon.com/scratchpad/assets/config/config.json' );
169
-
170
- //PAAPI
171
- define( 'PAAPI_URI', '/onca/xml' );
172
- define( 'PAAPI_TRANSFER_PROTOCOL', 'https://' );
173
- define( 'PAAPI_URL_QUERY_SEPARATOR', '?' );
174
- define( 'PAAPI_SERVICE', 'AWSECommerceService' );
175
- define( 'PAAPI_VERSION', '2013-08-01' );
176
- define( 'PAAPI_URL_REGEX', '^https:\\/\\/(.*)\\/onca\\/xml\\?(.*)$' );
177
-
178
- //HTTP Status Codes
179
- define( 'HTTP_SUCCESS', '200' );
180
- define( 'HTTP_SUCCESS_MESSAGE', '<h4>Request Successful</h4>' );
181
- define( 'HTTP_BAD_REQUEST', '400' );
182
- define( 'HTTP_BAD_REQUEST_MESSAGE', '<h4>Your AWS Access Key Id is not registered as an Amazon Associate. Please verify that you are <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingAssociate.html" target="_blank">registered as an Amazon Associate</a> in respective locale and you added the email address registered for the Product Advertising API as a <a href="https://affiliate-program.amazon.com/help/node/topic/202049770" target="_blank">secondary email address in your Amazon Associates account</a>.</h4>' );
183
- define( 'HTTP_REQUEST_URI_TOO_LONG', '414' );
184
- define( 'HTTP_REQUEST_URI_TOO_LONG_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>' );
185
- define( 'HTTP_FORBIDDEN', '403' );
186
- define( 'HTTP_FORBIDDEN_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>' );
187
- define( 'HTTP_INTERNAL_SERVER_ERROR', '500' );
188
- define( 'HTTP_INTERNAL_SERVER_ERROR_MESSAGE', '<h4>Internal server error</h4>' );
189
- define( 'HTTP_THROTTLE', '503' );
190
- define( 'HTTP_THROTTLE_MESSAGE', '<h4>You are submitting requests too quickly. Please retry your requests at a slower rate. For more information, see <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/TroubleshootingApplications.html#efficiency-guidelines" target="_blank">Efficiency Guidelines</a>.</h4>' );
191
-
192
- /**
193
- * Cipher
194
- */
195
- //Make a key of length 32 byte.
196
- //Specify your unique encryption key here.
197
- define( 'AALB_ENCRYPTION_KEY', 'put your unique phrase here' );
198
- //Default Encryption Key. Do NOT change this.
199
- define( 'AALB_ENCRYPTION_KEY_DEFAULT', 'put your unique phrase here' );
200
-
201
- //Make IV of 16 bytes
202
- define( 'AALB_ENCRYPTION_IV', '0123456789ABCDEF' );
203
-
204
- //Algorithm to use
205
- define( 'AALB_ENCRYPTION_ALGORITHM', 'aes-256-cbc' );
206
-
207
- //Caching Requirements
208
- //====================
209
- //As defined by the Product Advertising API License Agreement at https://affiliate-program.amazon.com/gp/advertising/api/detail/agreement.html,
210
- //Dated Jul 22, 2016, Section 4(n) and 4(o), caching of product information is permitted upto a maximum of 24-hours.
211
- //Further, if the product price is not refreshed every one hour, the displayed price should be accompanied with a timestamp when the price was read.
212
- //Note that the plugin uses a two tier cache. It caches the ASINs as well as the rendered templates.
213
- //At any given time the sum of ASIN cache TTL and Rendered AdUnit cache TTL should be less than or equal to one hour.
214
- //The below configuration is compliant with the License Agreement. Any modification may result in the violation of the license agreement.
215
- define( 'AALB_CACHE_FOR_ASIN_RAWINFO_TTL', 30 * MINUTE_IN_SECONDS );
216
- define( 'AALB_CACHE_FOR_ASIN_ADUNIT_TTL', 30 * MINUTE_IN_SECONDS );
217
-
218
- //Translation keys
219
- define( 'CHECK_ON_AMAZON', 'Check on Amazon' );
220
- define( 'OUT_OF_STOCK', 'Out of stock' );
221
-
222
- //Marketplaces supported for translations
223
- define( 'US', 'US' );
224
- define( 'FR', 'FR' );
225
- define( 'IT', 'IT' );
226
- define( 'DE', 'DE' );
227
- define( 'ES', 'ES' );
228
- define( 'BR', 'BR' );
229
- define( 'CA', 'CA' );
230
- define( 'CN', 'CN' );
231
- define( 'IN', 'IN' );
232
- define( 'JP', 'JP' );
233
- define( 'MX', 'MX' );
234
- define( 'UK', 'UK' );
235
-
236
- ?>
 
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ //version
16
+ define( 'AALB_PLUGIN_CURRENT_VERSION', '1.4.3' );
17
+
18
+ //PHP version compatible for AALB plugin
19
+ define('AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION','5.3.0');
20
+
21
+ //Plugin Name
22
+ define('AALB_PLUGIN_NAME','Amazon Associates Link Builder');
23
+ //paths
24
+ define( 'AALB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
25
+ define( 'AALB_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
26
+
27
+ //Project Title
28
+ define( 'AALB_PROJECT_TITLE', 'Associates Link Builder' );
29
+
30
+ /**
31
+ * File paths
32
+ */
33
+
34
+ //Library
35
+ define( 'MUSTACHE_AUTOLOADER_PHP', AALB_PLUGIN_DIR . 'lib/php/Mustache/Autoloader.php' );
36
+ define( 'AALB_PAAPI_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/Paapi/aalb_paapi_helper.php' );
37
+ define( 'AALB_VALIDATION_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_validation_helper.php' );
38
+ define( 'AALB_XML_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_xml_helper.php' );
39
+ define( 'AALB_TRACKING_API_HELPER_PHP', AALB_PLUGIN_DIR . 'lib/php/aalb_tracking_api_helper.php' );
40
+
41
+ //Shortcode
42
+ define( 'AALB_SHORTCODE_PHP', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode.php' );
43
+ define( 'AALB_SHORTCODE_TEXT_PHP', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_text.php' );
44
+ define( 'AALB_SHORTCODE_LOADER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_loader.php' );
45
+ define( 'AALB_SHORTCODE_HELPER', AALB_PLUGIN_DIR . 'shortcode/aalb_shortcode_helper.php' );
46
+
47
+ //Shortcodes supported
48
+ define( 'AALB_SHORTCODE_AMAZON_LINK', 'amazon_link' );
49
+ define( 'AALB_SHORTCODE_AMAZON_TEXT', 'amazon_textlink' );
50
+
51
+ //Admin
52
+ define( 'AALB_SIDEBAR_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/aalb_sidebar.php' );
53
+ define( 'AALB_ADMIN_PHP', AALB_PLUGIN_DIR . 'admin/aalb_admin.php' );
54
+ define( 'AALB_ABOUT_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_about.php' );
55
+ define( 'AALB_CREDENTIALS_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_credentials.php' );
56
+ define( 'AALB_TEMPLATE_PHP', AALB_PLUGIN_DIR . 'admin/sidebar/partials/aalb_templates.php' );
57
+
58
+ //Directories
59
+ define( 'AALB_TEMPLATE_DIR', AALB_PLUGIN_DIR . 'template/' );
60
+ define( 'AALB_ADMIN_DIR', AALB_PLUGIN_DIR . 'admin/' );
61
+ define( 'AALB_SIDEBAR_DIR', AALB_PLUGIN_DIR . 'admin/sidebar/' );
62
+ define( 'AALB_INCLUDES_DIR', AALB_PLUGIN_DIR . 'includes/' );
63
+ define( 'AALB_PAAPI_DIR', AALB_PLUGIN_DIR . 'lib/php/Paapi/' );
64
+ define( 'AALB_SHORTCODE_DIR', AALB_PLUGIN_DIR . 'shortcode/' );
65
+ define( 'AALB_LIBRARY_DIR', AALB_PLUGIN_DIR . 'lib/php/' );
66
+
67
+ //Includes
68
+ define( 'AALB_ACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_activator.php' );
69
+ define( 'AALB_DEACTIVATOR_PHP', AALB_PLUGIN_DIR . 'includes/aalb_deactivator.php' );
70
+ define( 'AALB_MANAGER', AALB_PLUGIN_DIR . 'includes/aalb_manager.php' );
71
+ define( 'AALB_HOOK_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_hook_loader.php' );
72
+ define( 'AALB_CACHE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_cache_loader.php' );
73
+ define( 'AALB_REMOTE_LOADER', AALB_PLUGIN_DIR . 'includes/aalb_remote_loader.php' );
74
+ define( 'AALB_AUTOLOADER', AALB_PLUGIN_DIR . 'includes/aalb_autoloader.php' );
75
+
76
+ //Templates Directory
77
+ define( 'AALB_TEMPLATE_URL', AALB_PLUGIN_URL . 'template/' );
78
+ define( 'AALB_TEMPLATE_UPLOADS_FOLDER', 'amazon-associates-link-builder/template/' );
79
+
80
+ //Partials
81
+ define( 'AALB_META_BOX_PARTIAL', AALB_PLUGIN_DIR . 'admin/partials/aalb_meta_box.php' );
82
+ define( 'AALB_EDITOR_SEARCH_BOX', AALB_PLUGIN_DIR . 'admin/partials/aalb_editor_search_box.php' );
83
+
84
+ //Proxy
85
+ define( 'AALB_PROXY_URL', AALB_PLUGIN_URL . 'lib/php/Paapi/aalb_paapi_proxy.php' );
86
+
87
+ //Tracking API Endpoint
88
+ define( 'AALB_TRACKING_API_ENDPOINT', 'https://rx5hfxbp45.execute-api.us-east-1.amazonaws.com/aalb/' );
89
+ define( 'AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM', 'source-tool=aalb' );
90
+ define( 'AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM', 'aws-access-key-id=' );
91
+
92
+ //Wordpress Pages
93
+ define( 'WP_POST', 'post.php' );
94
+ define( 'WP_POST_NEW', 'post-new.php' );
95
+
96
+ /**
97
+ * Styles and scripts
98
+ */
99
+
100
+ //Local Styles
101
+ define( 'AALB_ADMIN_CSS', AALB_PLUGIN_URL . 'admin/css/aalb_admin.css' );
102
+ define( 'AALB_BASICS_CSS', AALB_PLUGIN_URL . 'css/aalb_basics.css' );
103
+
104
+ //Local Scripts
105
+ define( 'AALB_SHA2_JS', AALB_PLUGIN_URL . 'lib/js/jssha2/sha2.js' );
106
+ define( 'AALB_ADMIN_JS', AALB_PLUGIN_URL . 'admin/js/aalb_admin.js' );
107
+ define( 'AALB_ADMIN_ITEM_SEARCH_ITEMS_URL', AALB_PLUGIN_URL . 'aalb_admin_item_search_items.hbs' );
108
+ define( 'AALB_TEMPLATE_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_template.js' );
109
+ define( 'AALB_CREDENTIALS_JS', AALB_PLUGIN_URL . 'admin/sidebar/js/aalb_credentials.js' );
110
+
111
+ //External Scripts
112
+ define( 'HANDLEBARS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/handlebars.js/4.0.5/handlebars.min.js' );
113
+ define( 'CODEMIRROR_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.js' );
114
+ define( 'CODEMIRROR_MODE_XML_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/xml/xml.min.js' );
115
+ define( 'CODEMIRROR_MODE_CSS_JS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/mode/css/css.min.js' );
116
+
117
+ //External Styles
118
+ define( 'FONT_AWESOME_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/font-awesome/4.5.0/css/font-awesome.min.css' );
119
+ define( 'CODEMIRROR_CSS', 'https://d8fd03967nrad.cloudfront.net/libs/codemirror/5.13.2/codemirror.min.css' );
120
+
121
+ /**
122
+ * Icons
123
+ */
124
+ define( 'AALB_SECURE_HOSTNAME', 'https://images-na.ssl-images-amazon.com/' );
125
+ define( 'AALB_NORMAL_HOSTNAME', 'http://g-ecx.images-amazon.com/' );
126
+ define( 'AALB_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon-2._V276841048_.png' );
127
+ define( 'AALB_ADMIN_ICON_LOCATION', 'images/G/01/PAAPI/AmazonAssociatesLinkBuilder/icon._V278877987_.png' );
128
+ //AALB_ICON URL is generated by wordpress at run-time by checking the remotehost's encryption. Image source has different URLs depending upon the encryption used.
129
+ if ( is_ssl() ) {
130
+ define( 'AALB_ICON', AALB_SECURE_HOSTNAME . AALB_ICON_LOCATION );
131
+ } else {
132
+ define( 'AALB_ICON', AALB_NORMAL_HOSTNAME . AALB_ICON_LOCATION );
133
+ }
134
+ define( 'AALB_ADMIN_ICON', AALB_SECURE_HOSTNAME . AALB_ADMIN_ICON_LOCATION );
135
+
136
+
137
+ /**
138
+ * Constants
139
+ */
140
+
141
+ //Search result items. Paapi returns 10 items by default.
142
+ define( 'AALB_MAX_SEARCH_RESULT_ITEMS', 9 );
143
+ //List of Default Amazon Template names
144
+ define( 'AALB_AMAZON_TEMPLATE_NAMES', 'ProductCarousel,ProductGrid,ProductAd,PriceLink,ProductLink' );
145
+
146
+ //Database keys
147
+ define( 'AALB_TEMPLATE_NAMES', 'aalb_template_names' );
148
+ define( 'AALB_MARKETPLACE_NAMES', 'aalb_marketplace_names' );
149
+ define( 'AALB_DEFAULT_TEMPLATE', 'aalb_default_template' );
150
+ define( 'AALB_DEFAULT_STORE_ID', 'aalb_default_store_id' );
151
+ define( 'AALB_DEFAULT_MARKETPLACE', 'aalb_default_marketplace' );
152
+ define( 'AALB_AWS_ACCESS_KEY', 'aalb_aws_access_key' );
153
+ define( 'AALB_AWS_SECRET_KEY', 'aalb_aws_secret_key' );
154
+ define( 'AALB_CRED_CONFIG_GROUP', 'aalb_cred_config_group' );
155
+ define( 'AALB_STORE_ID_NAMES', 'aalb_store_id_names' );
156
+ define( 'AALB_SHOW_HTTP_WARNING_ONCE', 'aalb_show_http_warning_once' );
157
+ define( 'AALB_PLUGIN_VERSION', 'aalb_plugin_version' );
158
+
159
+ //Masking constant
160
+ define( 'AALB_AWS_SECRET_KEY_MASK', '••••••••••••••••••••••••••••••••••••••••' );
161
+
162
+
163
+ //Defaults in case DB doesn't contain them.
164
+ define( 'AALB_DEFAULT_TEMPLATE_NAME', 'ProductCarousel' );
165
+ define( 'AALB_DEFAULT_MARKETPLACE_NAME', 'US' );
166
+ define( 'AALB_DEFAULT_STORE_ID_NAME', 'not-specified' );
167
+
168
+ //Marketplaces
169
+ define( 'MARKETPLACES_URL', 'https://webservices.amazon.com/scratchpad/assets/config/config.json' );
170
+
171
+ //PAAPI
172
+ define( 'PAAPI_URI', '/onca/xml' );
173
+ define( 'PAAPI_TRANSFER_PROTOCOL', 'https://' );
174
+ define( 'PAAPI_URL_QUERY_SEPARATOR', '?' );
175
+ define( 'PAAPI_SERVICE', 'AWSECommerceService' );
176
+ define( 'PAAPI_VERSION', '2013-08-01' );
177
+ define( 'PAAPI_URL_REGEX', '^https:\\/\\/(.*)\\/onca\\/xml\\?(.*)$' );
178
+
179
+ //HTTP Status Codes
180
+ define( 'HTTP_SUCCESS', '200' );
181
+ define( 'HTTP_SUCCESS_MESSAGE', '<h4>Request Successful</h4>' );
182
+ define( 'HTTP_BAD_REQUEST', '400' );
183
+ define( 'HTTP_BAD_REQUEST_MESSAGE', '<h4>Your AWS Access Key Id is not registered as an Amazon Associate. Please verify that you are <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingAssociate.html" target="_blank">registered as an Amazon Associate</a> in respective locale and you added the email address registered for the Product Advertising API as a <a href="https://affiliate-program.amazon.com/help/node/topic/202049770" target="_blank">secondary email address in your Amazon Associates account</a>.</h4>' );
184
+ define( 'HTTP_REQUEST_URI_TOO_LONG', '414' );
185
+ define( 'HTTP_REQUEST_URI_TOO_LONG_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>' );
186
+ define( 'HTTP_FORBIDDEN', '403' );
187
+ define( 'HTTP_FORBIDDEN_MESSAGE', '<h4>Your AccessKey Id is not registered for Product Advertising API. Please sign up for Product Advertising API by <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/becomingDev.html" target="_blank">following these guidelines</a>.</h4>' );
188
+ define( 'HTTP_INTERNAL_SERVER_ERROR', '500' );
189
+ define( 'HTTP_INTERNAL_SERVER_ERROR_MESSAGE', '<h4>Internal server error</h4>' );
190
+ define( 'HTTP_THROTTLE', '503' );
191
+ define( 'HTTP_THROTTLE_MESSAGE', '<h4>You are submitting requests too quickly. Please retry your requests at a slower rate. For more information, see <a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/TroubleshootingApplications.html#efficiency-guidelines" target="_blank">Efficiency Guidelines</a>.</h4>' );
192
+
193
+ /**
194
+ * Cipher
195
+ */
196
+ //Make a key of length 32 byte.
197
+ //Specify your unique encryption key here.
198
+ define( 'AALB_ENCRYPTION_KEY', 'put your unique phrase here' );
199
+ //Default Encryption Key. Do NOT change this.
200
+ define( 'AALB_ENCRYPTION_KEY_DEFAULT', 'put your unique phrase here' );
201
+
202
+ //Make IV of 16 bytes
203
+ define( 'AALB_ENCRYPTION_IV', '0123456789ABCDEF' );
204
+
205
+ //Algorithm to use
206
+ define( 'AALB_ENCRYPTION_ALGORITHM', 'aes-256-cbc' );
207
+
208
+ //Caching Requirements
209
+ //====================
210
+ //As defined by the Product Advertising API License Agreement at https://affiliate-program.amazon.com/gp/advertising/api/detail/agreement.html,
211
+ //Dated Jul 22, 2016, Section 4(n) and 4(o), caching of product information is permitted upto a maximum of 24-hours.
212
+ //Further, if the product price is not refreshed every one hour, the displayed price should be accompanied with a timestamp when the price was read.
213
+ //Note that the plugin uses a two tier cache. It caches the ASINs as well as the rendered templates.
214
+ //At any given time the sum of ASIN cache TTL and Rendered AdUnit cache TTL should be less than or equal to one hour.
215
+ //The below configuration is compliant with the License Agreement. Any modification may result in the violation of the license agreement.
216
+ define( 'AALB_CACHE_FOR_ASIN_RAWINFO_TTL', 30 * MINUTE_IN_SECONDS );
217
+ define( 'AALB_CACHE_FOR_ASIN_ADUNIT_TTL', 30 * MINUTE_IN_SECONDS );
218
+
219
+ //Translation keys
220
+ define( 'CHECK_ON_AMAZON', 'Check on Amazon' );
221
+ define( 'OUT_OF_STOCK', 'Out of stock' );
222
+
223
+ //Marketplaces supported for translations
224
+ define( 'US', 'US' );
225
+ define( 'FR', 'FR' );
226
+ define( 'IT', 'IT' );
227
+ define( 'DE', 'DE' );
228
+ define( 'ES', 'ES' );
229
+ define( 'BR', 'BR' );
230
+ define( 'CA', 'CA' );
231
+ define( 'CN', 'CN' );
232
+ define( 'IN', 'IN' );
233
+ define( 'JP', 'JP' );
234
+ define( 'MX', 'MX' );
235
+ define( 'UK', 'UK' );
236
+
237
+ ?>
admin/aalb_admin.php CHANGED
@@ -1,239 +1,258 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * The class responsible for handling all the functionalities in the admin area.
17
- * Enqueues the styles and scripts for post.php and post-new.php.
18
- * Fetches the marketplace endpoints from external json file.
19
- * Handles UI in the admin area by providing a meta box and an asin button in the html text editor.
20
- *
21
- * @since 1.0.0
22
- * @package AmazonAssociatesLinkBuilder
23
- * @subpackage AmazonAssociatesLinkBuilder/admin
24
- */
25
- class Aalb_Admin {
26
-
27
- private $paapi_helper;
28
- private $remote_loader;
29
- private $tracking_api_helper;
30
- private $helper;
31
-
32
- public function __construct() {
33
- $this->paapi_helper = new Aalb_Paapi_Helper();
34
- $this->remote_loader = new Aalb_Remote_Loader();
35
- $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
36
- $this->helper = new Aalb_Helper();
37
- add_action( 'admin_notices', array( $this, 'aalb_plugin_activation' ) );
38
- }
39
-
40
- /**
41
- * Show warning message if the AWS Credentials are not yet set upon activation
42
- *
43
- * @since 1.0.0
44
- */
45
- public function aalb_plugin_activation() {
46
- if ( get_option( AALB_AWS_ACCESS_KEY ) == '' or get_option( AALB_AWS_SECRET_KEY ) == '' ) {
47
- echo "<div class=\"notice notice-error\">
48
- <h3>Amazon Associates Link Builder Important Message!</h3>
49
- <p>Please Note - You need to add your Access Key ID and Secret Access Key in the plugin settings page for adding links to Amazon using Amazon Associates Link Builder plugin.</p>
50
- </div>";
51
- }
52
- }
53
-
54
- /**
55
- * Adding CSS for post and post-new pages
56
- *
57
- * @since 1.0.0
58
- *
59
- * @param string $hook The name of the WordPress action that is being registered.
60
- */
61
- public function enqueue_styles( $hook ) {
62
- if ( WP_POST != $hook && WP_POST_NEW != $hook ) {
63
- return;
64
- }
65
- wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
66
- wp_enqueue_style( 'aalb_admin_css', AALB_ADMIN_CSS );
67
- wp_enqueue_style( 'font_awesome_css', FONT_AWESOME_CSS );
68
- wp_enqueue_style( 'thickbox' );
69
- }
70
-
71
- /**
72
- * Adding JS for post and post-new pages
73
- *
74
- * @since 1.0.0
75
- *
76
- * @param string $hook The name of the WordPress action that is being registered.
77
- */
78
- public function enqueue_scripts( $hook ) {
79
- if ( WP_POST != $hook && WP_POST_NEW != $hook ) {
80
- return;
81
- }
82
- wp_enqueue_style( 'thickbox' );
83
- wp_enqueue_script( 'jquery' );
84
- wp_enqueue_script( 'handlebars_js', HANDLEBARS_JS );
85
- wp_enqueue_script( 'aalb_sha2_js', AALB_SHA2_JS );
86
-
87
- wp_enqueue_script( 'aalb_admin_js', AALB_ADMIN_JS, array( 'handlebars_js', 'jquery', 'aalb_sha2_js' ) );
88
- wp_enqueue_style( 'thickbox' );
89
- wp_localize_script( 'aalb_admin_js', 'api_pref', $this->get_paapi_pref() );
90
- }
91
-
92
- /**
93
- * Returns data to be localized in the script.
94
- * Makes the variable values in PHP to be used in Javascript.
95
- *
96
- * @since 1.0.0
97
- * @return array Data to be localized in the script
98
- */
99
- private function get_paapi_pref() {
100
- return array(
101
- 'template_url' => AALB_ADMIN_ITEM_SEARCH_ITEMS_URL,
102
- 'max_search_result_items' => AALB_MAX_SEARCH_RESULT_ITEMS,
103
- 'store_id' => get_option( AALB_DEFAULT_STORE_ID ),
104
- 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ),
105
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
106
- 'action' => 'get_item_search_result',
107
- 'item_search_nonce' => wp_create_nonce( 'aalb-item-search-nonce' ),
108
- 'AALB_SHORTCODE_AMAZON_LINK' => AALB_SHORTCODE_AMAZON_LINK,
109
- 'AALB_SHORTCODE_AMAZON_TEXT' => AALB_SHORTCODE_AMAZON_TEXT
110
- );
111
- }
112
-
113
- /**
114
- * Checks if the plugin has been updated and calls required method
115
- *
116
- * @since 1.3
117
- */
118
- public function check_update() {
119
- if ( AALB_PLUGIN_CURRENT_VERSION !== get_option( AALB_PLUGIN_VERSION ) ) {
120
- $this->handle_plugin_update();
121
- }
122
- }
123
-
124
- /**
125
- * Block which runs whenever the plugin has been updated.
126
- * Refreshes the templates
127
- *
128
- * @since 1.3
129
- */
130
- public function handle_plugin_update() {
131
- //Clear all transients for price changes to reflect
132
- $this->helper->clear_cache_for_substring( '' );
133
- $this->helper->clear_expired_transients();
134
-
135
- global $wp_filesystem;
136
- $this->helper->aalb_initialize_wp_filesystem_api();
137
- $this->helper->refresh_template_list();
138
- update_option( AALB_PLUGIN_VERSION, AALB_PLUGIN_CURRENT_VERSION );
139
- }
140
-
141
- /**
142
- * Prints the aalb-admin sidebar search box.
143
- *
144
- * @since 1.0.0
145
- *
146
- * @param WP_Post $post The object for the current post/page.
147
- */
148
- function admin_display_callback( $post ) {
149
- require( AALB_META_BOX_PARTIAL );
150
- }
151
-
152
- /**
153
- * Asin button in text editor for putting the shortcode template
154
- *
155
- * @since 1.0.0
156
- */
157
- function add_quicktags() {
158
- if ( wp_script_is( 'quicktags' ) ) {
159
- ?>
160
- <script type="text/javascript">
161
- QTags.addButton( 'aalb_asin_button', 'asins', '[amazon_link asins="" template="" marketplace="" link_id=""]', '', '', 'Amazon Link' );
162
- </script>
163
- <?php
164
- }
165
- }
166
-
167
- /**
168
- * Supports the ajax request for item search.
169
- *
170
- * @since 1.0.0
171
- */
172
- public function get_item_search_result() {
173
- $nonce = $_GET['item_search_nonce'];
174
-
175
- //verify the user making the request.
176
- if ( ! wp_verify_nonce( $nonce, 'aalb-item-search-nonce' ) ) {
177
- die( 'Not authorised to make a request' );
178
- }
179
-
180
- //Only allow users who can edit post to make the request.
181
- if ( current_user_can( 'edit_posts' ) ) {
182
- $url = $this->paapi_helper->get_item_search_url( $_GET['keywords'], $_GET['marketplace'], $_GET['store_id'] );
183
- try {
184
- echo $this->remote_loader->load( $url );
185
- } catch ( Exception $e ) {
186
- echo $this->paapi_helper->get_error_message( $e->getMessage() );
187
- }
188
- }
189
-
190
- wp_die();
191
- }
192
-
193
- /**
194
- * Supports the ajax request for get link id API
195
- *
196
- * @since 1.0.0
197
- */
198
- public function get_link_code() {
199
-
200
- $shortcode_params_json_string = $_POST['shortcode_params'];
201
- $shortcode_name = $_POST['shortcode_name'];
202
-
203
- echo $this->tracking_api_helper->get_link_id( $shortcode_name, $shortcode_params_json_string );
204
- wp_die();
205
- }
206
-
207
- /**
208
- * Supports the ajax request for getting template contents for custom templates
209
- *
210
- * @since 1.3
211
- */
212
- public function get_custom_template_content() {
213
- global $wp_filesystem;
214
- $this->helper->aalb_initialize_wp_filesystem_api();
215
- $base_path = $this->helper->get_template_upload_directory();
216
- if ( current_user_can( 'edit_posts' ) ) {
217
- $css_file = $_POST['css'];
218
- $real_css_file = realpath( $css_file );
219
- $mustache_file = $_POST['mustache'];
220
- $real_mustache_file = realpath( $mustache_file );
221
- if ( $real_css_file === false || $real_mustache_file === false || strpos( $real_css_file, $base_path ) !== 0 || strpos( $real_mustache_file, $base_path ) !== 0 ) {
222
- //If base path is not a prefix of the realpath, this means that a directry traversal was attempted
223
- die( 'Not authorised to make request template content or Directory Traversal Attempted.' );
224
- } else {
225
- //No vulnerability. Get file contents.
226
- $css_file_content = $wp_filesystem->get_contents( $css_file );
227
- $mustache_file_content = $wp_filesystem->get_contents( $mustache_file );
228
-
229
- $response = array( "css" => $css_file_content, "mustache" => $mustache_file_content );
230
- echo json_encode( $response );
231
- }
232
- } else {
233
- die( 'Not authorised to make request' );
234
- }
235
- wp_die();
236
- }
237
- }
238
-
239
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class responsible for handling all the functionalities in the admin area.
17
+ * Enqueues the styles and scripts for post.php and post-new.php.
18
+ * Fetches the marketplace endpoints from external json file.
19
+ * Handles UI in the admin area by providing a meta box and an asin button in the html text editor.
20
+ *
21
+ * @since 1.0.0
22
+ * @package AmazonAssociatesLinkBuilder
23
+ * @subpackage AmazonAssociatesLinkBuilder/admin
24
+ */
25
+ class Aalb_Admin {
26
+
27
+ private $paapi_helper;
28
+ private $remote_loader;
29
+ private $tracking_api_helper;
30
+ private $helper;
31
+ private $admin_notice_manager;
32
+ private $compatibility_helper;
33
+
34
+ public function __construct() {
35
+ $this->compatibility_helper = new Aalb_Compatibility_Helper();
36
+ $this->paapi_helper = new Aalb_Paapi_Helper();
37
+ $this->remote_loader = new Aalb_Remote_Loader();
38
+ $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
39
+ $this->helper = new Aalb_Helper();
40
+ $admin_notice_manager = Aalb_Admin_Notice_Manager::getInstance();
41
+ $admin_notice_manager->add_notice( $this, 'aalb_plugin_activation' );
42
+ }
43
+
44
+ /**
45
+ * Show warning message if the AWS Credentials are not yet set upon activation
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function aalb_plugin_activation() {
50
+ if ( get_option( AALB_AWS_ACCESS_KEY ) == '' or get_option( AALB_AWS_SECRET_KEY ) == '' ) {
51
+ echo "<div class=\"notice notice-error\">
52
+ <h3>Amazon Associates Link Builder Important Message!</h3>
53
+ <p>Please Note - You need to add your Access Key ID and Secret Access Key in the plugin settings page for adding links to Amazon using Amazon Associates Link Builder plugin.</p>
54
+ </div>";
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Adding CSS for post and post-new pages
60
+ *
61
+ * @since 1.0.0
62
+ *
63
+ * @param string $hook The name of the WordPress action that is being registered.
64
+ */
65
+ public function enqueue_styles( $hook ) {
66
+ if ( WP_POST != $hook && WP_POST_NEW != $hook ) {
67
+ return;
68
+ }
69
+ wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
70
+ wp_enqueue_style( 'aalb_admin_css', AALB_ADMIN_CSS );
71
+ wp_enqueue_style( 'font_awesome_css', FONT_AWESOME_CSS );
72
+ wp_enqueue_style( 'thickbox' );
73
+ }
74
+
75
+ /**
76
+ * Adding JS for post and post-new pages
77
+ *
78
+ * @since 1.0.0
79
+ *
80
+ * @param string $hook The name of the WordPress action that is being registered.
81
+ */
82
+ public function enqueue_scripts( $hook ) {
83
+ if ( WP_POST != $hook && WP_POST_NEW != $hook ) {
84
+ return;
85
+ }
86
+ wp_enqueue_style( 'thickbox' );
87
+ wp_enqueue_script( 'jquery' );
88
+ wp_enqueue_script( 'handlebars_js', HANDLEBARS_JS );
89
+ wp_enqueue_script( 'aalb_sha2_js', AALB_SHA2_JS );
90
+
91
+ wp_enqueue_script( 'aalb_admin_js', AALB_ADMIN_JS, array( 'handlebars_js', 'jquery', 'aalb_sha2_js' ) );
92
+ wp_enqueue_style( 'thickbox' );
93
+ wp_localize_script( 'aalb_admin_js', 'api_pref', $this->get_paapi_pref() );
94
+ }
95
+
96
+ /**
97
+ * Returns data to be localized in the script.
98
+ * Makes the variable values in PHP to be used in Javascript.
99
+ *
100
+ * @since 1.0.0
101
+ * @return array Data to be localized in the script
102
+ */
103
+ private function get_paapi_pref() {
104
+ return array(
105
+ 'template_url' => AALB_ADMIN_ITEM_SEARCH_ITEMS_URL,
106
+ 'max_search_result_items' => AALB_MAX_SEARCH_RESULT_ITEMS,
107
+ 'store_id' => get_option( AALB_DEFAULT_STORE_ID ),
108
+ 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ),
109
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
110
+ 'action' => 'get_item_search_result',
111
+ 'item_search_nonce' => wp_create_nonce( 'aalb-item-search-nonce' ),
112
+ 'AALB_SHORTCODE_AMAZON_LINK' => AALB_SHORTCODE_AMAZON_LINK,
113
+ 'AALB_SHORTCODE_AMAZON_TEXT' => AALB_SHORTCODE_AMAZON_TEXT
114
+ );
115
+ }
116
+
117
+ /**
118
+ * Checks if the plugin has been updated and calls required method
119
+ *
120
+ * @since 1.3
121
+ */
122
+ public function check_update() {
123
+ if ( AALB_PLUGIN_CURRENT_VERSION !== get_option( AALB_PLUGIN_VERSION ) ) {
124
+ $this->handle_plugin_update();
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Block which runs whenever the plugin has been updated.
130
+ * Refreshes the templates
131
+ *
132
+ * @since 1.3
133
+ */
134
+ public function handle_plugin_update() {
135
+ if( $this->compatibility_helper->is_plugin_compatible() ) {
136
+ //Clear all transients for price changes to reflect
137
+ $this->helper->clear_cache_for_substring( '' );
138
+ $this->helper->clear_expired_transients();
139
+
140
+ global $wp_filesystem;
141
+ $this->helper->aalb_initialize_wp_filesystem_api();
142
+ $this->helper->refresh_template_list();
143
+ update_option( AALB_PLUGIN_VERSION, AALB_PLUGIN_CURRENT_VERSION );
144
+ } else {
145
+ $this->compatibility_helper->aalb_deactivate();
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Prints Search box to be displayed in Editor where user can type in keywords for search. @see aalb_editor_search_box.php
151
+ * This callback is attached with "media_buttons" hook of wordpress. @see aalb_manager::add_admin_hooks()
152
+ *
153
+ * @since 1.4.3 Only prints search box displayed in editor.
154
+ * @since 1.0.0 Prints the aalb-admin sidebar search box.
155
+ */
156
+ function admin_display_callback() {
157
+ require( AALB_EDITOR_SEARCH_BOX );
158
+ }
159
+
160
+ /**
161
+ * Prints Popup box of the plugin used to create shortcode. @see aalb_meta_box.php
162
+ * This callback is attached with "admin_footer" hook of wordpress. @see aalb_manager::add_admin_hooks()
163
+ *
164
+ * @since 1.4.3
165
+ *
166
+ */
167
+ function admin_footer_callback() {
168
+ require_once( AALB_META_BOX_PARTIAL );
169
+ }
170
+
171
+ /**
172
+ * Asin button in text editor for putting the shortcode template
173
+ *
174
+ * @since 1.0.0
175
+ */
176
+ function add_quicktags() {
177
+ if ( wp_script_is( 'quicktags' ) ) {
178
+ ?>
179
+ <script type="text/javascript">
180
+ QTags.addButton( 'aalb_asin_button', 'asins', '[amazon_link asins="" template="" marketplace="" link_id=""]', '', '', 'Amazon Link' );
181
+ </script>
182
+ <?php
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Supports the ajax request for item search.
188
+ *
189
+ * @since 1.0.0
190
+ */
191
+ public function get_item_search_result() {
192
+ $nonce = $_GET['item_search_nonce'];
193
+
194
+ //verify the user making the request.
195
+ if ( ! wp_verify_nonce( $nonce, 'aalb-item-search-nonce' ) ) {
196
+ die( 'Not authorised to make a request' );
197
+ }
198
+
199
+ //Only allow users who can edit post to make the request.
200
+ if ( current_user_can( 'edit_posts' ) ) {
201
+ $url = $this->paapi_helper->get_item_search_url( $_GET['keywords'], $_GET['marketplace'], $_GET['store_id'] );
202
+ try {
203
+ echo $this->remote_loader->load( $url );
204
+ } catch ( Exception $e ) {
205
+ echo $this->paapi_helper->get_error_message( $e->getMessage() );
206
+ }
207
+ }
208
+
209
+ wp_die();
210
+ }
211
+
212
+ /**
213
+ * Supports the ajax request for get link id API
214
+ *
215
+ * @since 1.0.0
216
+ */
217
+ public function get_link_code() {
218
+
219
+ $shortcode_params_json_string = $_POST['shortcode_params'];
220
+ $shortcode_name = $_POST['shortcode_name'];
221
+
222
+ echo $this->tracking_api_helper->get_link_id( $shortcode_name, $shortcode_params_json_string );
223
+ wp_die();
224
+ }
225
+
226
+ /**
227
+ * Supports the ajax request for getting template contents for custom templates
228
+ *
229
+ * @since 1.3
230
+ */
231
+ public function get_custom_template_content() {
232
+ global $wp_filesystem;
233
+ $this->helper->aalb_initialize_wp_filesystem_api();
234
+ $base_path = $this->helper->get_template_upload_directory();
235
+ if ( current_user_can( 'edit_posts' ) ) {
236
+ $css_file = $_POST['css'];
237
+ $real_css_file = realpath( $css_file );
238
+ $mustache_file = $_POST['mustache'];
239
+ $real_mustache_file = realpath( $mustache_file );
240
+ if ( $real_css_file === false || $real_mustache_file === false || strpos( $real_css_file, $base_path ) !== 0 || strpos( $real_mustache_file, $base_path ) !== 0 ) {
241
+ //If base path is not a prefix of the realpath, this means that a directry traversal was attempted
242
+ die( 'Not authorised to make request template content or Directory Traversal Attempted.' );
243
+ } else {
244
+ //No vulnerability. Get file contents.
245
+ $css_file_content = $wp_filesystem->get_contents( $css_file );
246
+ $mustache_file_content = $wp_filesystem->get_contents( $mustache_file );
247
+
248
+ $response = array( "css" => $css_file_content, "mustache" => $mustache_file_content );
249
+ echo json_encode( $response );
250
+ }
251
+ } else {
252
+ die( 'Not authorised to make request' );
253
+ }
254
+ wp_die();
255
+ }
256
+ }
257
+
258
+ ?>
admin/css/aalb_admin.css CHANGED
@@ -1,379 +1,383 @@
1
- /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
-
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
-
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
-
13
- #aalb-admin-searchbox {
14
- display: inline;
15
- }
16
-
17
- img#aalb-admin-searchbox-amzlogo {
18
- width: 30px;
19
- height: 30px;
20
- padding: 0px;
21
- }
22
-
23
- input#aalb-admin-input-search {
24
- vertical-align: top;
25
- margin-left: 3px;
26
- margin-right: 3px;
27
- height: 28px;
28
- }
29
-
30
- a#aalb-admin-button-create-amazon-shortcode {
31
- box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
32
- background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
33
- background-color: transparent;
34
- background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
35
- background-repeat: repeat;
36
- background-attachment: scroll;
37
- background-position: 0% 0%;
38
- background-clip: border-box;
39
- background-origin: padding-box;
40
- background-size: auto auto;
41
- border-color: #A88734 #9C7E31 #846A29;
42
- border-top-color: #A88734;
43
- border-right-color: #9C7E31;
44
- border-bottom-color: #846A29;
45
- border-left-color: #9C7E31;
46
- color: #111;
47
- }
48
-
49
- html, body {
50
- width: 100%;
51
- height: 100%;
52
- margin: 0;
53
- padding: 0;
54
- }
55
-
56
- #TB_ajaxContent {
57
- height: 90%;
58
- width: 95%;
59
- }
60
-
61
- #aalb-admin-popup-container {
62
- height: 100%;
63
- width: 100%;
64
- }
65
-
66
- #aalb-admin-popup-content {
67
- padding-top: 30px;
68
- height: 50%;
69
- width: 100%;
70
- }
71
-
72
- .aalb-modal-box {
73
- width: 100%;
74
- height: 100%;
75
- }
76
-
77
- .aalb-admin-alert {
78
- padding: 15px;
79
- margin-bottom: 20px;
80
- border: 1px solid transparent;
81
- border-radius: 4px;
82
- }
83
-
84
- .aalb-admin-alert {
85
- text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2);
86
- box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px 1px 2px rgba(0, 0, 0, 0.05);
87
- }
88
-
89
- .aalb-admin-alert-info {
90
- color: #E77600;
91
- background-color: #FEF8F2;
92
- border-color: #E77600;
93
- }
94
-
95
- .aalb-admin-alert-info {
96
- background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
97
- background-repeat: repeat-x;
98
- border-color: #E77600;
99
- }
100
-
101
- #aalb-add-shortcode-alert {
102
- color: #E77600;
103
- padding: 2px;
104
- display: inline;
105
- padding-left: 10px;
106
- opacity: 0;
107
- }
108
-
109
- .aalb-admin-icon {
110
- padding-right: 5px;
111
- height: 20%;
112
- display: inline;
113
- }
114
-
115
- .aalb-admin-item-search-loading {
116
- margin-top: 20px;
117
- }
118
-
119
- .aalb-admin-item-search {
120
- width: 100%;
121
- height: 90%;
122
- display: none;
123
- padding-top: 3%;
124
- }
125
-
126
- .aalb-admin-item-search-items {
127
- width: 100%;
128
- height: 100%;
129
- margin: 2px;
130
- padding: 0;
131
- -moz-column-gap: 8px;
132
- -webkit-column-gap: 8px;
133
- column-gap: 8px;
134
- -moz-column-count: 3;
135
- -webkit-column-count: 3;
136
- column-count: 3;
137
- }
138
-
139
- .aalb-admin-item-search-items-item {
140
- display: inline-block;
141
- background: #fff;
142
- padding: 5px;
143
- margin: 0 0 5px;
144
- width: 100%;
145
- height: 30%;
146
- -moz-box-sizing: border-box;
147
- -webkit-box-sizing: border-box;
148
- box-sizing: border-box;
149
- box-shadow: 2px 2px 4px 0 #ccc;
150
- border: 1px solid #CCC;
151
- border-radius: 4px;
152
- cursor: pointer;
153
- }
154
-
155
- .aalb-admin-item-search-items-item-img {
156
- float: left;
157
- padding-right: 5px;
158
- width: 25%;
159
- height: 100%;
160
- }
161
-
162
- #aalb-admin-item-search-items-item-img {
163
- max-width: 100%;
164
- height: 100%;
165
- display: block;
166
- margin-left: auto;
167
- margin-right: auto;
168
- }
169
-
170
- .aalb-admin-item-search-items-item-title {
171
- font-weight: bold;
172
- word-break: break-all;
173
- font-size: 1em;
174
- /* hide text if it more than N lines */
175
- overflow: hidden;
176
- /* for set '...' in absolute position */
177
- position: relative;
178
- /* use this value to count block height */
179
- line-height: 1.2em;
180
- /* max-height = line-height (1.2) * lines max number (2) */
181
- max-height: 2.4em;
182
- /* fix problem when last visible word doesn't adjoin right side */
183
- text-align: justify;
184
- /* place for '...' */
185
- margin-right: -1em;
186
- padding-right: 1em;
187
- }
188
-
189
- /* create the ... */
190
- .aalb-admin-item-search-items-item-title:before {
191
- /* points in the end */
192
- content: '...';
193
- /* absolute position */
194
- position: absolute;
195
- /* set position to right bottom corner of block */
196
- right: 0;
197
- bottom: 0;
198
- }
199
-
200
- /* hide ... if we have text, which is less than or equal to max lines */
201
- .aalb-admin-item-search-items-item-title:after {
202
- /* points in the end */
203
- content: '';
204
- /* absolute position */
205
- position: absolute;
206
- /* set position to right bottom corner of text */
207
- right: 0;
208
- /* set width and height */
209
- width: 1em;
210
- height: 1em;
211
- margin-top: 0.2em;
212
- /* bg color = bg color under block */
213
- background: white;
214
- }
215
-
216
- /* CSS Fix for rendering issues with safari */
217
- @media screen and (min-color-index: 0)
218
- and(-webkit-min-device-pixel-ratio: 0) {
219
- @media {
220
- .aalb-admin-item-search-items-item-title {
221
- position: initial;
222
- margin-left: 2em;
223
- margin-right: 0em;
224
- }
225
- }
226
- }
227
-
228
- .aalb-admin-item-search-items-item-price {
229
- font-size: 1em;
230
- color: #b12704;
231
- font-weight: bold;
232
- }
233
-
234
- .aalb-admin-item-search-items-item:hover {
235
- background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
236
- background-repeat: repeat-x;
237
- border-color: #E77600;
238
- }
239
-
240
- .aalb-admin-popup-shortocde-wrapper {
241
- display: block;
242
- width: 100%;
243
- }
244
-
245
- .aalb-admin-popup-shortcode-options {
246
- padding-top: 3%;
247
- width: 100%;
248
- -moz-column-gap: 10px;
249
- -webkit-column-gap: 10px;
250
- column-gap: 10px;
251
- -moz-column-count: 3;
252
- -webkit-column-count: 3;
253
- column-count: 3;
254
- }
255
-
256
- .aalb-admin-popup-shortcode-options label {
257
- display: block;
258
- text-align: left;
259
- }
260
-
261
- .aalb-admin-item-search-templates {
262
- width: 100%;
263
- }
264
-
265
- .aalb-admin-popup-store {
266
- width: 100%;
267
- }
268
-
269
- .aalb-admin-item-search-marketplaces {
270
- width: 100%;
271
- }
272
-
273
- .aalb-add-shortcode-button {
274
- padding-top: 20px;
275
- }
276
-
277
- .aalb-admin-popup-options {
278
- position: relative;
279
- }
280
-
281
- #aalb-admin-popup-input-search {
282
- position: absolute;
283
- width: 100%;
284
- left: 0;
285
- margin-top: 1%;
286
- height: 33px;
287
- vertical-align: middle;
288
- }
289
-
290
- #aalb-admin-popup-search-button {
291
- position: absolute;
292
- right: 0;
293
- }
294
-
295
- .aalb-selected {
296
- height: auto;
297
- width: 100%;
298
- padding-top: 10px;
299
- padding-bottom: 10px;
300
- }
301
-
302
- .aalb-selected label {
303
- display: block;
304
- text-align: left;
305
- padding: 15px 0px;
306
- }
307
-
308
- .aalb-selected-item {
309
- border: 1px solid #eee;
310
- float: left;
311
- margin: 4px 4px 4px 4px;
312
- position: relative;
313
- width: 10%;
314
- padding: 4px;
315
- font-family: Helvetica;
316
- }
317
-
318
- .aalb-selected-item:hover {
319
- border: 1px solid #900;
320
- }
321
-
322
- .aalb-selected-item-img {
323
- display: block;
324
- margin-top: auto;
325
- margin-bottom: auto;
326
- height: 90px;
327
- margin-left: auto;
328
- margin-right: auto;
329
- max-width: 100%;
330
- }
331
-
332
- .aalb-selected-item-img-wrap {
333
- position: relative;
334
- height: 100%;
335
- }
336
-
337
- .aalb-selected-item-close {
338
- position: absolute;
339
- top: -12px;
340
- right: -12px;
341
- z-index: 100;
342
- color: #FFF;
343
- border-radius: 10px;
344
- display: block;
345
- height: 20px;
346
- width: 20px;
347
- text-align: center;
348
- line-height: 20px;
349
- font-size: 20px;
350
- font-weight: bold;
351
- cursor: pointer;
352
- box-shadow: 1px 1px 4px #000;
353
- background-color: #a50200;
354
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
355
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
356
- }
357
-
358
- .aalb-selected-item-title h3 {
359
- margin: 2px 3px 0 2px;
360
- font-size: 8px;
361
- line-height: 12px;
362
- color: #000;
363
- position: relative;
364
- text-align: center;
365
- display: block;
366
- overflow: hidden;
367
- height: 35px;
368
- }
369
-
370
- .aalb-selected-item-price {
371
- text-align: center;
372
- color: #900;
373
- font-weight: bold;
374
- margin: 2px;
375
- }
376
-
377
- .aalb-selected-asin {
378
- display: none;
379
- }
 
 
 
 
1
+ /*
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
+
13
+ .aalb-admin-inline {
14
+ display: inline;
15
+ }
16
+
17
+ img#aalb-admin-searchbox-amzlogo {
18
+ width: 30px;
19
+ height: 30px;
20
+ padding: 0px;
21
+ }
22
+
23
+ input.aalb-admin-input-search {
24
+ vertical-align: top;
25
+ margin-left: 3px;
26
+ margin-right: 3px;
27
+ height: 28px;
28
+ }
29
+
30
+ .aalb-admin-searchbox a.aalb-admin-button-create-amazon-shortcode {
31
+ box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
32
+ background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
33
+ background-color: transparent;
34
+ background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
35
+ background-repeat: repeat;
36
+ background-attachment: scroll;
37
+ background-position: 0% 0%;
38
+ background-clip: border-box;
39
+ background-origin: padding-box;
40
+ background-size: auto auto;
41
+ border-color: #A88734 #9C7E31 #846A29;
42
+ border-top-color: #A88734;
43
+ border-right-color: #9C7E31;
44
+ border-bottom-color: #846A29;
45
+ border-left-color: #9C7E31;
46
+ color: #111;
47
+ }
48
+
49
+ .aalb-admin-searchbox a.aalb-admin-button-create-amazon-shortcode:hover {
50
+ background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
51
+ }
52
+
53
+ html, body {
54
+ width: 100%;
55
+ height: 100%;
56
+ margin: 0;
57
+ padding: 0;
58
+ }
59
+
60
+ #TB_ajaxContent {
61
+ height: 90%;
62
+ width: 95%;
63
+ }
64
+
65
+ #aalb-admin-popup-container {
66
+ height: 100%;
67
+ width: 100%;
68
+ }
69
+
70
+ #aalb-admin-popup-content {
71
+ padding-top: 30px;
72
+ height: 50%;
73
+ width: 100%;
74
+ }
75
+
76
+ .aalb-modal-box {
77
+ width: 100%;
78
+ height: 100%;
79
+ }
80
+
81
+ .aalb-admin-alert {
82
+ padding: 15px;
83
+ margin-bottom: 20px;
84
+ border: 1px solid transparent;
85
+ border-radius: 4px;
86
+ }
87
+
88
+ .aalb-admin-alert {
89
+ text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2);
90
+ box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px 1px 2px rgba(0, 0, 0, 0.05);
91
+ }
92
+
93
+ .aalb-admin-alert-info {
94
+ color: #E77600;
95
+ background-color: #FEF8F2;
96
+ border-color: #E77600;
97
+ }
98
+
99
+ .aalb-admin-alert-info {
100
+ background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
101
+ background-repeat: repeat-x;
102
+ border-color: #E77600;
103
+ }
104
+
105
+ #aalb-add-shortcode-alert {
106
+ color: #E77600;
107
+ padding: 2px;
108
+ display: inline;
109
+ padding-left: 10px;
110
+ opacity: 0;
111
+ }
112
+
113
+ .aalb-admin-icon {
114
+ padding-right: 5px;
115
+ height: 20%;
116
+ display: inline;
117
+ }
118
+
119
+ .aalb-admin-item-search-loading {
120
+ margin-top: 20px;
121
+ }
122
+
123
+ .aalb-admin-item-search {
124
+ width: 100%;
125
+ height: 90%;
126
+ display: none;
127
+ padding-top: 3%;
128
+ }
129
+
130
+ .aalb-admin-item-search-items {
131
+ width: 100%;
132
+ height: 100%;
133
+ margin: 2px;
134
+ padding: 0;
135
+ -moz-column-gap: 8px;
136
+ -webkit-column-gap: 8px;
137
+ column-gap: 8px;
138
+ -moz-column-count: 3;
139
+ -webkit-column-count: 3;
140
+ column-count: 3;
141
+ }
142
+
143
+ .aalb-admin-item-search-items-item {
144
+ display: inline-block;
145
+ background: #fff;
146
+ padding: 5px;
147
+ margin: 0 0 5px;
148
+ width: 100%;
149
+ height: 30%;
150
+ -moz-box-sizing: border-box;
151
+ -webkit-box-sizing: border-box;
152
+ box-sizing: border-box;
153
+ box-shadow: 2px 2px 4px 0 #ccc;
154
+ border: 1px solid #CCC;
155
+ border-radius: 4px;
156
+ cursor: pointer;
157
+ }
158
+
159
+ .aalb-admin-item-search-items-item-img {
160
+ float: left;
161
+ padding-right: 5px;
162
+ width: 25%;
163
+ height: 100%;
164
+ }
165
+
166
+ #aalb-admin-item-search-items-item-img {
167
+ max-width: 100%;
168
+ height: 100%;
169
+ display: block;
170
+ margin-left: auto;
171
+ margin-right: auto;
172
+ }
173
+
174
+ .aalb-admin-item-search-items-item-title {
175
+ font-weight: bold;
176
+ word-break: break-all;
177
+ font-size: 1em;
178
+ /* hide text if it more than N lines */
179
+ overflow: hidden;
180
+ /* for set '...' in absolute position */
181
+ position: relative;
182
+ /* use this value to count block height */
183
+ line-height: 1.2em;
184
+ /* max-height = line-height (1.2) * lines max number (2) */
185
+ max-height: 2.4em;
186
+ /* fix problem when last visible word doesn't adjoin right side */
187
+ text-align: justify;
188
+ /* place for '...' */
189
+ margin-right: -1em;
190
+ padding-right: 1em;
191
+ }
192
+
193
+ /* create the ... */
194
+ .aalb-admin-item-search-items-item-title:before {
195
+ /* points in the end */
196
+ content: '...';
197
+ /* absolute position */
198
+ position: absolute;
199
+ /* set position to right bottom corner of block */
200
+ right: 0;
201
+ bottom: 0;
202
+ }
203
+
204
+ /* hide ... if we have text, which is less than or equal to max lines */
205
+ .aalb-admin-item-search-items-item-title:after {
206
+ /* points in the end */
207
+ content: '';
208
+ /* absolute position */
209
+ position: absolute;
210
+ /* set position to right bottom corner of text */
211
+ right: 0;
212
+ /* set width and height */
213
+ width: 1em;
214
+ height: 1em;
215
+ margin-top: 0.2em;
216
+ /* bg color = bg color under block */
217
+ background: white;
218
+ }
219
+
220
+ /* CSS Fix for rendering issues with safari */
221
+ @media screen and (min-color-index: 0)
222
+ and(-webkit-min-device-pixel-ratio: 0) {
223
+ @media {
224
+ .aalb-admin-item-search-items-item-title {
225
+ position: initial;
226
+ margin-left: 2em;
227
+ margin-right: 0em;
228
+ }
229
+ }
230
+ }
231
+
232
+ .aalb-admin-item-search-items-item-price {
233
+ font-size: 1em;
234
+ color: #b12704;
235
+ font-weight: bold;
236
+ }
237
+
238
+ .aalb-admin-item-search-items-item:hover {
239
+ background-image: linear-gradient(to bottom, #FEF8F2 0px, #FFF1E3 100%);
240
+ background-repeat: repeat-x;
241
+ border-color: #E77600;
242
+ }
243
+
244
+ .aalb-admin-popup-shortocde-wrapper {
245
+ display: block;
246
+ width: 100%;
247
+ }
248
+
249
+ .aalb-admin-popup-shortcode-options {
250
+ padding-top: 3%;
251
+ width: 100%;
252
+ -moz-column-gap: 10px;
253
+ -webkit-column-gap: 10px;
254
+ column-gap: 10px;
255
+ -moz-column-count: 3;
256
+ -webkit-column-count: 3;
257
+ column-count: 3;
258
+ }
259
+
260
+ .aalb-admin-popup-shortcode-options label {
261
+ display: block;
262
+ text-align: left;
263
+ }
264
+
265
+ .aalb-admin-item-search-templates {
266
+ width: 100%;
267
+ }
268
+
269
+ .aalb-admin-popup-store {
270
+ width: 100%;
271
+ }
272
+
273
+ .aalb-admin-item-search-marketplaces {
274
+ width: 100%;
275
+ }
276
+
277
+ .aalb-add-shortcode-button {
278
+ padding-top: 20px;
279
+ }
280
+
281
+ .aalb-admin-popup-options {
282
+ position: relative;
283
+ }
284
+
285
+ #aalb-admin-popup-input-search {
286
+ position: absolute;
287
+ width: 100%;
288
+ left: 0;
289
+ margin-top: 1%;
290
+ height: 33px;
291
+ vertical-align: middle;
292
+ }
293
+
294
+ #aalb-admin-popup-search-button {
295
+ position: absolute;
296
+ right: 0;
297
+ }
298
+
299
+ .aalb-selected {
300
+ height: auto;
301
+ width: 100%;
302
+ padding-top: 10px;
303
+ padding-bottom: 10px;
304
+ }
305
+
306
+ .aalb-selected label {
307
+ display: block;
308
+ text-align: left;
309
+ padding: 15px 0px;
310
+ }
311
+
312
+ .aalb-selected-item {
313
+ border: 1px solid #eee;
314
+ float: left;
315
+ margin: 4px 4px 4px 4px;
316
+ position: relative;
317
+ width: 10%;
318
+ padding: 4px;
319
+ font-family: Helvetica;
320
+ }
321
+
322
+ .aalb-selected-item:hover {
323
+ border: 1px solid #900;
324
+ }
325
+
326
+ .aalb-selected-item-img {
327
+ display: block;
328
+ margin-top: auto;
329
+ margin-bottom: auto;
330
+ height: 90px;
331
+ margin-left: auto;
332
+ margin-right: auto;
333
+ max-width: 100%;
334
+ }
335
+
336
+ .aalb-selected-item-img-wrap {
337
+ position: relative;
338
+ height: 100%;
339
+ }
340
+
341
+ .aalb-selected-item-close {
342
+ position: absolute;
343
+ top: -12px;
344
+ right: -12px;
345
+ z-index: 100;
346
+ color: #FFF;
347
+ border-radius: 10px;
348
+ display: block;
349
+ height: 20px;
350
+ width: 20px;
351
+ text-align: center;
352
+ line-height: 20px;
353
+ font-size: 20px;
354
+ font-weight: bold;
355
+ cursor: pointer;
356
+ box-shadow: 1px 1px 4px #000;
357
+ background-color: #a50200;
358
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
359
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
360
+ }
361
+
362
+ .aalb-selected-item-title h3 {
363
+ margin: 2px 3px 0 2px;
364
+ font-size: 8px;
365
+ line-height: 12px;
366
+ color: #000;
367
+ position: relative;
368
+ text-align: center;
369
+ display: block;
370
+ overflow: hidden;
371
+ height: 35px;
372
+ }
373
+
374
+ .aalb-selected-item-price {
375
+ text-align: center;
376
+ color: #900;
377
+ font-weight: bold;
378
+ margin: 2px;
379
+ }
380
+
381
+ .aalb-selected-asin {
382
+ display: none;
383
+ }
admin/js/aalb_admin.js CHANGED
@@ -1,394 +1,408 @@
1
- /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
-
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
-
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
-
13
- var template;
14
- var TB_WIDTH, TB_HEIGHT;
15
- var tb_remove;
16
- var link_id = "";
17
- var AALB_SHORTCODE_AMAZON_LINK = api_pref.AALB_SHORTCODE_AMAZON_LINK; //constant value from server side is reused here
18
- var AALB_SHORTCODE_AMAZON_TEXT = api_pref.AALB_SHORTCODE_AMAZON_TEXT;
19
-
20
- jQuery( document ).ready( function() {
21
- // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
22
- jQuery( "#aalb-admin-popup-content" ).data( 'old-state', jQuery( "#aalb-admin-popup-content" ).html() );
23
-
24
- //Load the search result template
25
- jQuery.get( api_pref.template_url, function( data ) {
26
- template = Handlebars.compile( data );
27
- } );
28
-
29
- //Resize thickbox on window resize
30
- jQuery( window ).on( 'resize', resize_thickbox );
31
-
32
- //Storing the tb_remove function of Thickbox.js
33
- var old_tb_remove = window.tb_remove;
34
-
35
- //Custom tb_remove function
36
- tb_remove = function() {
37
- //call actual tb_remove
38
- old_tb_remove();
39
- //custom actions to execute
40
- jQuery( ".aalb-selected-item" ).each( function() {
41
- aalb_remove_selected_item( this );
42
- } );
43
- };
44
- } );
45
-
46
- /**
47
- * Resizing thickbox on change in window dimensions
48
- * Setting a max width and height of 1280x800 px for readability and to lessen distortion
49
- */
50
- function resize_thickbox() {
51
- TB_WIDTH = Math.min( 1280, 0.6 * jQuery( window ).width() );
52
- TB_HEIGHT = Math.min( 800, 0.9 * jQuery( window ).height() );
53
- jQuery( document ).find( '#TB_ajaxContent' ).width( TB_WIDTH - 35 ).height( TB_HEIGHT - 90 );
54
- jQuery( document ).find( '#TB_window' ).width( TB_WIDTH ).height( TB_HEIGHT );
55
- jQuery( document ).find( '#TB_window' ).css( { marginLeft: '-' + TB_WIDTH / 2 + 'px', top: TB_HEIGHT / 12 } );
56
- jQuery( document ).find( '#TB_window' ).removeClass();
57
- }
58
-
59
- /**
60
- * Ensure a button click on a return key press event
61
- *
62
- * @param HTML_DOM_EVENT event OnKeyPress event
63
- * @param HTML_DOM_OBJECT button_to_click Button id to click on a return key press event
64
- */
65
- function aalb_submit_event( event, button_to_click ) {
66
- //Code for the RETURN key is 13
67
- if ( event.keyCode == 13 ) {
68
- event.preventDefault();
69
- jQuery( '#' + button_to_click ).click();
70
- }
71
- }
72
-
73
- /**
74
- * Removes the selected HTML element
75
- *
76
- * @param HTML_DOM_OBJECT element HTML element to be removed.
77
- */
78
- function aalb_remove_selected_item( element ) {
79
- jQuery( element ).remove();
80
- }
81
-
82
- /**
83
- * Display pop up thickbox
84
- */
85
- function aalb_admin_show_create_shortcode_popup() {
86
- // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
87
- jQuery( "#aalb-admin-popup-content" ).html( jQuery( "#aalb-admin-popup-content" ).data( 'old-state' ) );
88
- var selected = aalb_get_selected_text_from_editor();
89
- var keywords = jQuery( "#aalb-admin-input-search" ).val();
90
- if ( selected ) {
91
- tb_show( 'Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container', false );
92
- resize_thickbox();
93
-
94
- //Setting Search field with selected value.
95
- jQuery( "#aalb-admin-input-search" ).attr( 'value', selected );
96
- // Getting the ItemSearch results
97
- aalb_admin_get_item_search_items( jQuery( "#aalb-admin-input-search" ).val() );
98
- jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', selected );
99
- //Chose ProductLink template By Default when some text is selected.
100
- jQuery( "#aalb_template_names_list" ).val( 'ProductLink' );
101
- } else if ( keywords ) {
102
- // Showing the TB and resetting the width - http://wordpress.stackexchange.com/questions/114107/thickbox-width-cant-be-changed-in-admin
103
- tb_show( 'Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container', false );
104
- resize_thickbox();
105
-
106
- // Getting the ItemSearch results
107
- aalb_admin_get_item_search_items( jQuery( "#aalb-admin-input-search" ).val() );
108
- jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', keywords );
109
- } else {
110
- alert( "Please enter the keywords or select some text from the editor." );
111
- jQuery( "#aalb-admin-input-search" ).focus();
112
- }
113
-
114
- }
115
-
116
- /**
117
- * Search items from within the thickbox
118
- */
119
- function aalb_admin_popup_search_items() {
120
- var keywords = jQuery( "#aalb-admin-popup-input-search" ).val();
121
- jQuery( "#aalb-admin-popup-content" ).html( jQuery( "#aalb-admin-popup-content" ).data( 'old-state' ) );
122
- if ( keywords ) {
123
- // Getting the ItemSearch results
124
- aalb_admin_get_item_search_items( keywords );
125
- jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', keywords );
126
-
127
- } else {
128
- alert( "Please enter the keywords" );
129
- jQuery( "#aalb-admin-popup-input-search" ).focus();
130
- }
131
- }
132
-
133
- /**
134
- * Search items for the keywords and display it in the pop up thickbox
135
- *
136
- * @param String keywords Items to search for.
137
- */
138
- function aalb_admin_get_item_search_items( keywords ) {
139
- marketplace = aalb_get_selected_marketplace();
140
- marketplace = marketplace ? marketplace : api_pref.marketplace;
141
- jQuery.get( api_pref.ajax_url, {
142
- "action": api_pref.action,
143
- "item_search_nonce": api_pref.item_search_nonce,
144
- "keywords": keywords,
145
- "marketplace": marketplace,
146
- "store_id": api_pref.store_id
147
- }, function( xml ) {
148
- var items_xml = jQuery( xml ).find( "Item" );
149
- if ( items_xml.length > 0 ) {
150
- var items = [];
151
- var i = 0;
152
- items_xml.each( function() {
153
- //selecting maximum of max_search_result_items elements
154
- if ( i < api_pref.max_search_result_items ) {
155
- var item = {};
156
- item.asin = jQuery( this ).find( "ASIN" ).text();
157
- item.title = jQuery( this ).find( "Title" ).text();
158
- item.image = jQuery( this ).find( "LargeImage" ).first().find( "URL" ).text();
159
- item.price = jQuery( this ).find( "LowestNewPrice" ).find( "FormattedPrice" ).text();
160
- items.push( item );
161
- }
162
- i++;
163
- } );
164
-
165
- var html = template( items );
166
- jQuery( ".aalb-admin-item-search-items" ).append( html );
167
- jQuery( "#aalb-admin-popup-more-results" ).attr( 'href', jQuery( xml ).find( "MoreSearchResultsUrl" ).text() );
168
- jQuery( ".aalb-admin-item-search-loading" ).slideUp( "slow" );
169
- jQuery( ".aalb-admin-item-search" ).fadeIn( "slow" );
170
- jQuery( ".aalb-admin-item-search-items-item" ).on( "click", function() {
171
- var dataAsin = jQuery( this ).attr( "data-asin" );
172
- var productImage = jQuery( this ).find( "img" ).attr( "src" );
173
- var productTitle = jQuery( this ).find( "div.aalb-admin-item-search-items-item-title" ).text();
174
- var productPrice = jQuery( this ).find( "div.aalb-admin-item-search-items-item-price" ).text();
175
-
176
- var selectedAsinHTML = '<div class="aalb-selected-item" onclick="aalb_remove_selected_item(this)"';
177
- selectedAsinHTML += ' data-asin="' + dataAsin + '">';
178
- selectedAsinHTML += '<div class="aalb-selected-item-img-wrap"><span class="aalb-selected-item-close">&times;</span>';
179
- selectedAsinHTML += '<img class="aalb-selected-item-img" src="' + productImage + '"></img></div>';
180
- selectedAsinHTML += '<div class="aalb-selected-item-title"><h3>' + productTitle + '</h3>';
181
- selectedAsinHTML += '<p class="aalb-selected-item-price">' + productPrice + '<br></p></div>';
182
-
183
- jQuery( ".aalb-selected" ).append( selectedAsinHTML );
184
- } );
185
- } else {
186
- errors_xml = jQuery( xml ).find( "Error" );
187
- if ( errors_xml.length > 0 ) {
188
- var htmlerror = "";
189
- errors_xml.each( function() {
190
- htmlerror += jQuery( this ).find( "Message" ).text() + "<br>";
191
- } );
192
- jQuery( ".aalb-admin-item-search-loading" ).html( htmlerror );
193
- } else {
194
- jQuery( ".aalb-admin-item-search-loading" ).html( xml );
195
- }
196
- }
197
- } );
198
- jQuery( "#aalb-add-shortcode-button" ).unbind().click( function() {
199
- var selectedAsins = aalb_get_selected_asins();
200
- var selected = aalb_get_selected_text_from_editor();
201
- if ( selectedAsins ) {
202
- if ( selected ) {
203
- /* If there was some text selected in the wordpress post editor. Implies amazon_textlink */
204
- var selectedAsinsLength = selectedAsins.split( "," ).length;
205
- if ( selectedAsinsLength > 1 ) {
206
- alert( "Failed to create Text Link shortcode. Editor has some text selected. Only one item can be selected while adding text links" );
207
- } else {
208
- jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "fast", 1 );
209
- aalb_add_shortcode( AALB_SHORTCODE_AMAZON_TEXT );
210
- }
211
- } else {
212
- jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "fast", 1 );
213
- aalb_add_shortcode( AALB_SHORTCODE_AMAZON_LINK );
214
- }
215
- } else {
216
- alert( "Please select at least one product for display" );
217
- }
218
- } );
219
- }
220
-
221
- /**
222
- * Adds the given shortcode to the editor
223
- *
224
- * @param String Shortcode type to be added
225
- */
226
- function aalb_add_shortcode( shortcodeName ) {
227
- var shortcodeJson;
228
- var selectedAsins = aalb_get_selected_asins();
229
- var selectedTemplate = aalb_get_selected_template();
230
- var selectedStore = aalb_get_selected_store();
231
- var selectedMarketplace = aalb_get_selected_marketplace_abbreviation();
232
-
233
- if ( shortcodeName == AALB_SHORTCODE_AMAZON_LINK ) {
234
- shortcodeJson = {
235
- "name": AALB_SHORTCODE_AMAZON_LINK,
236
- "params": {
237
- "asins": selectedAsins,
238
- "template": selectedTemplate,
239
- "store": selectedStore,
240
- "marketplace": selectedMarketplace,
241
- }
242
- };
243
- } else if ( shortcodeName == AALB_SHORTCODE_AMAZON_TEXT ) {
244
- shortcodeJson = {
245
- "name": AALB_SHORTCODE_AMAZON_TEXT,
246
- "params": {
247
- "asin": selectedAsins,
248
- "text": aalb_get_selected_text_from_editor(),
249
- "template": selectedTemplate,
250
- "store": selectedStore,
251
- "marketplace": selectedMarketplace,
252
- }
253
- };
254
- } else {
255
- console.log( "Invalid Shortcode provided!" );
256
- return;
257
- }
258
- aalb_get_link_id( shortcodeJson );
259
- }
260
-
261
- /**
262
- * Handler function when the Add Shortcode button is clicked
263
- * and link id is retrieved.
264
- *
265
- * @param Object shortcodeJson Object describing the shortcode
266
- */
267
- function aalb_add_shortcode_click_handler( shortcodeJson ) {
268
- aalb_create_shortcode( shortcodeJson );
269
- tb_remove();
270
- }
271
-
272
- /**
273
- * Builds shortcode from given JSON
274
- *
275
- * @param Object shortcodeJson Object describing the shortcode
276
- *
277
- * @return String returns the Shortcode String
278
- */
279
- function buildShortcode( shortcodeJson ) {
280
- var shortcodeParamsString = "";
281
- for ( var shortcodeParam in shortcodeJson.params ) {
282
- if ( shortcodeJson.params.hasOwnProperty( shortcodeParam ) ) {
283
- shortcodeParamsString += " " + shortcodeParam + "='" + shortcodeJson.params[ shortcodeParam ] + "'";
284
- }
285
- }
286
-
287
- var shortcodeString = "[" + shortcodeJson.name + shortcodeParamsString + "]";
288
- return shortcodeString;
289
- }
290
-
291
- /**
292
- * Get unique link id whenever add shortcode button is clicked
293
- *
294
- * @param Object shortcodeJson Object describing the shortcode
295
- */
296
- function aalb_get_link_id( shortcodeJson ) {
297
- jQuery.post( api_pref.ajax_url, {
298
- "action": "get_link_code", "shortcode_name": shortcodeJson.name, "shortcode_params": shortcodeJson.params
299
- } ).success( function( data ) {
300
- link_id = data;
301
- } ).fail( function() {
302
- link_id = "";
303
- } ).always( function() {
304
- shortcodeJson.params.link_id = link_id;
305
- jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "slow", 0 );
306
- aalb_add_shortcode_click_handler( shortcodeJson );
307
- } );
308
- }
309
-
310
- /**
311
- * Add the shortcode to the display editor
312
- *
313
- * @param Object shortcodeJson Object describing the shortcode
314
- */
315
- function aalb_create_shortcode( shortcodeJson ) {
316
- send_to_editor( buildShortcode( shortcodeJson ) );
317
- }
318
-
319
- /**
320
- * Get the selected Asins
321
- *
322
- * @return String Selected Asins
323
- */
324
- function aalb_get_selected_asins() {
325
- var selectedAsins = "";
326
- jQuery( ".aalb-selected-item" ).each( function() {
327
- selectedAsins += jQuery( this ).attr( "data-asin" ) + ",";
328
- } );
329
- return selectedAsins.slice( 0, -1 );
330
- }
331
-
332
- /**
333
- * Get the selected Template style
334
- *
335
- * @return String Selected Template style
336
- */
337
- function aalb_get_selected_template() {
338
- var selectedTemplate = "";
339
- var $selectedTemplate = jQuery( "#aalb_template_names_list option:selected" );
340
- if ( $selectedTemplate.length > 0 ) {
341
- selectedTemplate = $selectedTemplate.val();
342
- }
343
- return selectedTemplate;
344
- }
345
-
346
- /**
347
- * Get the selected associate tag
348
- *
349
- * @return String Selected Associate tag
350
- */
351
- function aalb_get_selected_store() {
352
- return jQuery( '#aalb-admin-popup-store-id' ).val();
353
- }
354
-
355
- /**
356
- * Get the selected marketplace
357
- *
358
- * @return String Selected Marketplace to search the product
359
- */
360
- function aalb_get_selected_marketplace() {
361
- var selectedMarketplace = "";
362
- var $selectedMarketplace = jQuery( "#aalb_marketplace_names_list option:selected" );
363
- if ( $selectedMarketplace.length > 0 ) {
364
- selectedMarketplace = $selectedMarketplace.val();
365
- }
366
- return selectedMarketplace;
367
- }
368
-
369
- /**
370
- * Get the selected marketplace abbreviation
371
- *
372
- * @return String Selected Marketplace abbreviation for the shortcode
373
- */
374
- function aalb_get_selected_marketplace_abbreviation() {
375
- var selectedMarketplace = "";
376
- var $selectedMarketplace = jQuery( "#aalb_marketplace_names_list option:selected" );
377
- if ( $selectedMarketplace.length > 0 ) {
378
- selectedMarketplace = $selectedMarketplace.text();
379
- }
380
- return selectedMarketplace;
381
- }
382
-
383
- /**
384
- * Get selected text from the editor.
385
- *
386
- * @return String Selected text from the wordpress post editor.
387
- */
388
- function aalb_get_selected_text_from_editor() {
389
- if ( tinyMCE.activeEditor ) {
390
- return tinyMCE.activeEditor.selection.getContent( { format: "text" } );
391
- } else {
392
- return null;
393
- }
394
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
+
13
+ var template;
14
+ var TB_WIDTH, TB_HEIGHT;
15
+ var tb_remove;
16
+ var link_id = "";
17
+ var AALB_SHORTCODE_AMAZON_LINK = api_pref.AALB_SHORTCODE_AMAZON_LINK; //constant value from server side is reused here
18
+ var AALB_SHORTCODE_AMAZON_TEXT = api_pref.AALB_SHORTCODE_AMAZON_TEXT;
19
+
20
+ jQuery( document ).ready( function() {
21
+ // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
22
+ jQuery( "#aalb-admin-popup-content" ).data( 'old-state', jQuery( "#aalb-admin-popup-content" ).html() );
23
+
24
+ //Load the search result template
25
+ jQuery.get( api_pref.template_url, function( data ) {
26
+ template = Handlebars.compile( data );
27
+ } );
28
+
29
+ //Resize thickbox on window resize
30
+ jQuery( window ).on( 'resize', resize_thickbox );
31
+
32
+ //Storing the tb_remove function of Thickbox.js
33
+ var old_tb_remove = window.tb_remove;
34
+
35
+ //Custom tb_remove function
36
+ tb_remove = function() {
37
+ //call actual tb_remove
38
+ old_tb_remove();
39
+ //custom actions to execute
40
+ jQuery( ".aalb-selected-item" ).each( function() {
41
+ aalb_remove_selected_item( this );
42
+ } );
43
+ };
44
+ } );
45
+
46
+ /**
47
+ * Resizing thickbox on change in window dimensions
48
+ * Setting a max width and height of 1280x800 px for readability and to lessen distortion
49
+ */
50
+ function resize_thickbox() {
51
+ TB_WIDTH = Math.min( 1280, 0.6 * jQuery( window ).width() );
52
+ TB_HEIGHT = Math.min( 800, 0.9 * jQuery( window ).height() );
53
+ jQuery( document ).find( '#TB_ajaxContent' ).width( TB_WIDTH - 35 ).height( TB_HEIGHT - 90 );
54
+ jQuery( document ).find( '#TB_window' ).width( TB_WIDTH ).height( TB_HEIGHT );
55
+ jQuery( document ).find( '#TB_window' ).css( { marginLeft: '-' + TB_WIDTH / 2 + 'px', top: TB_HEIGHT / 12 } );
56
+ jQuery( document ).find( '#TB_window' ).removeClass();
57
+ }
58
+
59
+ /**
60
+ * Ensure a button click on a return key press event
61
+ * Caller element and button_to_click_class needs to be part of a container having class name aalb-admin-searchbox.
62
+ *
63
+ * @param HTML_DOM_EVENT event OnKeyPress event
64
+ * @param string button_to_click_class name of a button to click on a return key press event
65
+ * @param HTMLElement caller_element caller of this function
66
+ *
67
+ * @since 1.4.3 added param caller_element and modified param button_to_click_class
68
+ */
69
+ function aalb_submit_event( event, button_to_click_class, caller_element ) {
70
+ //Code for the RETURN key is 13
71
+ if ( event.keyCode == 13 ) {
72
+ event.preventDefault();
73
+ //Find button to click in the container and invoke a click event.
74
+ var container_search_box = jQuery( caller_element ).closest( ".aalb-admin-searchbox" );
75
+ jQuery( container_search_box ).find( '.' + button_to_click_class ).click();
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Removes the selected HTML element
81
+ *
82
+ * @param HTMLElement element HTML element to be removed.
83
+ */
84
+ function aalb_remove_selected_item( element ) {
85
+ jQuery( element ).remove();
86
+ }
87
+
88
+ /**
89
+ * Display pop up thickbox
90
+ *
91
+ * @param HTMLElement search_button reference to the clicked button element to get to the keyword of interest.
92
+ *
93
+ * @since 1.4.3 added param search_button
94
+ */
95
+ function aalb_admin_show_create_shortcode_popup( search_button ) {
96
+ // Retain content from old state of pop content primarily input text of search box.
97
+ // http://stackoverflow.com/questions/5557641/how-can-i-reset-div-to-its-original-state-after-it-has-been-modified-by-java
98
+ jQuery( "#aalb-admin-popup-content" ).html( jQuery( "#aalb-admin-popup-content" ).data( 'old-state' ) );
99
+
100
+ var editor_selected_text = aalb_get_selected_text_from_editor();
101
+
102
+ if ( editor_selected_text ) {
103
+ //Make ProductLink template as a default choice of template when some text is selected.
104
+ jQuery( "#aalb_template_names_list" ).val( 'ProductLink' );
105
+ }
106
+
107
+ var editor_search_box_input = jQuery( search_button ).siblings( ".aalb-admin-input-search" );
108
+
109
+ var search_keywords = editor_selected_text || editor_search_box_input.val();
110
+ if ( search_keywords ) {
111
+
112
+ tb_show( 'Add Amazon Associates Link Builder Shortcode', '#TB_inline?inlineId=aalb-admin-popup-container', false );
113
+ resize_thickbox();
114
+
115
+ // Getting the ItemSearch results
116
+ aalb_admin_get_item_search_items( search_keywords );
117
+
118
+ //Setting search input of shortcode popup with search keyword.
119
+ jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', search_keywords );
120
+
121
+ //Setting editor search input with search keyword.
122
+ editor_search_box_input.attr( 'value', search_keywords );
123
+
124
+ } else {
125
+ alert( "Please enter the keywords or select some text from the editor." );
126
+ editor_search_box_input.focus();
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Search items from within the thickbox
132
+ */
133
+ function aalb_admin_popup_search_items() {
134
+ var keywords = jQuery( "#aalb-admin-popup-input-search" ).val();
135
+ jQuery( "#aalb-admin-popup-content" ).html( jQuery( "#aalb-admin-popup-content" ).data( 'old-state' ) );
136
+ if ( keywords ) {
137
+ // Getting the ItemSearch results
138
+ aalb_admin_get_item_search_items( keywords );
139
+ jQuery( "#aalb-admin-popup-input-search" ).attr( 'value', keywords );
140
+
141
+ } else {
142
+ alert( "Please enter the keywords" );
143
+ jQuery( "#aalb-admin-popup-input-search" ).focus();
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Search items for the keywords and display it in the pop up thickbox
149
+ *
150
+ * @param String keywords Items to search for.
151
+ */
152
+ function aalb_admin_get_item_search_items( keywords ) {
153
+ marketplace = aalb_get_selected_marketplace();
154
+ marketplace = marketplace ? marketplace : api_pref.marketplace;
155
+ jQuery.get( api_pref.ajax_url, {
156
+ "action": api_pref.action,
157
+ "item_search_nonce": api_pref.item_search_nonce,
158
+ "keywords": keywords,
159
+ "marketplace": marketplace,
160
+ "store_id": api_pref.store_id
161
+ }, function( xml ) {
162
+ var items_xml = jQuery( xml ).find( "Item" );
163
+ if ( items_xml.length > 0 ) {
164
+ var items = [];
165
+ var i = 0;
166
+ items_xml.each( function() {
167
+ //selecting maximum of max_search_result_items elements
168
+ if ( i < api_pref.max_search_result_items ) {
169
+ var item = {};
170
+ item.asin = jQuery( this ).find( "ASIN" ).text();
171
+ item.title = jQuery( this ).find( "Title" ).text();
172
+ item.image = jQuery( this ).find( "LargeImage" ).first().find( "URL" ).text();
173
+ item.price = jQuery( this ).find( "LowestNewPrice" ).find( "FormattedPrice" ).text();
174
+ items.push( item );
175
+ }
176
+ i++;
177
+ } );
178
+
179
+ var html = template( items );
180
+ jQuery( ".aalb-admin-item-search-items" ).append( html );
181
+ jQuery( "#aalb-admin-popup-more-results" ).attr( 'href', jQuery( xml ).find( "MoreSearchResultsUrl" ).text() );
182
+ jQuery( ".aalb-admin-item-search-loading" ).slideUp( "slow" );
183
+ jQuery( ".aalb-admin-item-search" ).fadeIn( "slow" );
184
+ jQuery( ".aalb-admin-item-search-items-item" ).on( "click", function() {
185
+ var dataAsin = jQuery( this ).attr( "data-asin" );
186
+ var productImage = jQuery( this ).find( "img" ).attr( "src" );
187
+ var productTitle = jQuery( this ).find( "div.aalb-admin-item-search-items-item-title" ).text();
188
+ var productPrice = jQuery( this ).find( "div.aalb-admin-item-search-items-item-price" ).text();
189
+
190
+ var selectedAsinHTML = '<div class="aalb-selected-item" onclick="aalb_remove_selected_item(this)"';
191
+ selectedAsinHTML += ' data-asin="' + dataAsin + '">';
192
+ selectedAsinHTML += '<div class="aalb-selected-item-img-wrap"><span class="aalb-selected-item-close">&times;</span>';
193
+ selectedAsinHTML += '<img class="aalb-selected-item-img" src="' + productImage + '"></img></div>';
194
+ selectedAsinHTML += '<div class="aalb-selected-item-title"><h3>' + productTitle + '</h3>';
195
+ selectedAsinHTML += '<p class="aalb-selected-item-price">' + productPrice + '<br></p></div>';
196
+
197
+ jQuery( ".aalb-selected" ).append( selectedAsinHTML );
198
+ } );
199
+ } else {
200
+ errors_xml = jQuery( xml ).find( "Error" );
201
+ if ( errors_xml.length > 0 ) {
202
+ var htmlerror = "";
203
+ errors_xml.each( function() {
204
+ htmlerror += jQuery( this ).find( "Message" ).text() + "<br>";
205
+ } );
206
+ jQuery( ".aalb-admin-item-search-loading" ).html( htmlerror );
207
+ } else {
208
+ jQuery( ".aalb-admin-item-search-loading" ).html( xml );
209
+ }
210
+ }
211
+ } );
212
+ jQuery( "#aalb-add-shortcode-button" ).unbind().click( function() {
213
+ var selectedAsins = aalb_get_selected_asins();
214
+ var selected = aalb_get_selected_text_from_editor();
215
+ if ( selectedAsins ) {
216
+ if ( selected ) {
217
+ /* If there was some text selected in the wordpress post editor. Implies amazon_textlink */
218
+ var selectedAsinsLength = selectedAsins.split( "," ).length;
219
+ if ( selectedAsinsLength > 1 ) {
220
+ alert( "Failed to create Text Link shortcode. Editor has some text selected. Only one item can be selected while adding text links" );
221
+ } else {
222
+ jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "fast", 1 );
223
+ aalb_add_shortcode( AALB_SHORTCODE_AMAZON_TEXT );
224
+ }
225
+ } else {
226
+ jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "fast", 1 );
227
+ aalb_add_shortcode( AALB_SHORTCODE_AMAZON_LINK );
228
+ }
229
+ } else {
230
+ alert( "Please select at least one product for display" );
231
+ }
232
+ } );
233
+ }
234
+
235
+ /**
236
+ * Adds the given shortcode to the editor
237
+ *
238
+ * @param String Shortcode type to be added
239
+ */
240
+ function aalb_add_shortcode( shortcodeName ) {
241
+ var shortcodeJson;
242
+ var selectedAsins = aalb_get_selected_asins();
243
+ var selectedTemplate = aalb_get_selected_template();
244
+ var selectedStore = aalb_get_selected_store();
245
+ var selectedMarketplace = aalb_get_selected_marketplace_abbreviation();
246
+
247
+ if ( shortcodeName == AALB_SHORTCODE_AMAZON_LINK ) {
248
+ shortcodeJson = {
249
+ "name": AALB_SHORTCODE_AMAZON_LINK,
250
+ "params": {
251
+ "asins": selectedAsins,
252
+ "template": selectedTemplate,
253
+ "store": selectedStore,
254
+ "marketplace": selectedMarketplace,
255
+ }
256
+ };
257
+ } else if ( shortcodeName == AALB_SHORTCODE_AMAZON_TEXT ) {
258
+ shortcodeJson = {
259
+ "name": AALB_SHORTCODE_AMAZON_TEXT,
260
+ "params": {
261
+ "asin": selectedAsins,
262
+ "text": aalb_get_selected_text_from_editor(),
263
+ "template": selectedTemplate,
264
+ "store": selectedStore,
265
+ "marketplace": selectedMarketplace,
266
+ }
267
+ };
268
+ } else {
269
+ console.log( "Invalid Shortcode provided!" );
270
+ return;
271
+ }
272
+ aalb_get_link_id( shortcodeJson );
273
+ }
274
+
275
+ /**
276
+ * Handler function when the Add Shortcode button is clicked
277
+ * and link id is retrieved.
278
+ *
279
+ * @param Object shortcodeJson Object describing the shortcode
280
+ */
281
+ function aalb_add_shortcode_click_handler( shortcodeJson ) {
282
+ aalb_create_shortcode( shortcodeJson );
283
+ tb_remove();
284
+ }
285
+
286
+ /**
287
+ * Builds shortcode from given JSON
288
+ *
289
+ * @param Object shortcodeJson Object describing the shortcode
290
+ *
291
+ * @return String returns the Shortcode String
292
+ */
293
+ function buildShortcode( shortcodeJson ) {
294
+ var shortcodeParamsString = "";
295
+ for ( var shortcodeParam in shortcodeJson.params ) {
296
+ if ( shortcodeJson.params.hasOwnProperty( shortcodeParam ) ) {
297
+ shortcodeParamsString += " " + shortcodeParam + "='" + shortcodeJson.params[ shortcodeParam ] + "'";
298
+ }
299
+ }
300
+
301
+ var shortcodeString = "[" + shortcodeJson.name + shortcodeParamsString + "]";
302
+ return shortcodeString;
303
+ }
304
+
305
+ /**
306
+ * Get unique link id whenever add shortcode button is clicked
307
+ *
308
+ * @param Object shortcodeJson Object describing the shortcode
309
+ */
310
+ function aalb_get_link_id( shortcodeJson ) {
311
+ jQuery.post( api_pref.ajax_url, {
312
+ "action": "get_link_code", "shortcode_name": shortcodeJson.name, "shortcode_params": shortcodeJson.params
313
+ } ).success( function( data ) {
314
+ link_id = data;
315
+ } ).fail( function() {
316
+ link_id = "";
317
+ } ).always( function() {
318
+ shortcodeJson.params.link_id = link_id;
319
+ jQuery( "#aalb-add-shortcode-alert" ).fadeTo( "slow", 0 );
320
+ aalb_add_shortcode_click_handler( shortcodeJson );
321
+ } );
322
+ }
323
+
324
+ /**
325
+ * Add the shortcode to the display editor
326
+ *
327
+ * @param Object shortcodeJson Object describing the shortcode
328
+ */
329
+ function aalb_create_shortcode( shortcodeJson ) {
330
+ send_to_editor( buildShortcode( shortcodeJson ) );
331
+ }
332
+
333
+ /**
334
+ * Get the selected Asins
335
+ *
336
+ * @return String Selected Asins
337
+ */
338
+ function aalb_get_selected_asins() {
339
+ var selectedAsins = "";
340
+ jQuery( ".aalb-selected-item" ).each( function() {
341
+ selectedAsins += jQuery( this ).attr( "data-asin" ) + ",";
342
+ } );
343
+ return selectedAsins.slice( 0, -1 );
344
+ }
345
+
346
+ /**
347
+ * Get the selected Template style
348
+ *
349
+ * @return String Selected Template style
350
+ */
351
+ function aalb_get_selected_template() {
352
+ var selectedTemplate = "";
353
+ var $selectedTemplate = jQuery( "#aalb_template_names_list option:selected" );
354
+ if ( $selectedTemplate.length > 0 ) {
355
+ selectedTemplate = $selectedTemplate.val();
356
+ }
357
+ return selectedTemplate;
358
+ }
359
+
360
+ /**
361
+ * Get the selected associate tag
362
+ *
363
+ * @return String Selected Associate tag
364
+ */
365
+ function aalb_get_selected_store() {
366
+ return jQuery( '#aalb-admin-popup-store-id' ).val();
367
+ }
368
+
369
+ /**
370
+ * Get the selected marketplace
371
+ *
372
+ * @return String Selected Marketplace to search the product
373
+ */
374
+ function aalb_get_selected_marketplace() {
375
+ var selectedMarketplace = "";
376
+ var $selectedMarketplace = jQuery( "#aalb_marketplace_names_list option:selected" );
377
+ if ( $selectedMarketplace.length > 0 ) {
378
+ selectedMarketplace = $selectedMarketplace.val();
379
+ }
380
+ return selectedMarketplace;
381
+ }
382
+
383
+ /**
384
+ * Get the selected marketplace abbreviation
385
+ *
386
+ * @return String Selected Marketplace abbreviation for the shortcode
387
+ */
388
+ function aalb_get_selected_marketplace_abbreviation() {
389
+ var selectedMarketplace = "";
390
+ var $selectedMarketplace = jQuery( "#aalb_marketplace_names_list option:selected" );
391
+ if ( $selectedMarketplace.length > 0 ) {
392
+ selectedMarketplace = $selectedMarketplace.text();
393
+ }
394
+ return selectedMarketplace;
395
+ }
396
+
397
+ /**
398
+ * Get selected text from the editor.
399
+ *
400
+ * @return String Selected text from the wordpress post editor.
401
+ */
402
+ function aalb_get_selected_text_from_editor() {
403
+ if ( tinyMCE.activeEditor ) {
404
+ return tinyMCE.activeEditor.selection.getContent( { format: "text" } );
405
+ } else {
406
+ return null;
407
+ }
408
+ }
admin/partials/aalb_editor_search_box.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
+ -->
13
+
14
+ <!--
15
+
16
+ UI for Search box shown in WordPress editors. User can type in keyword and trigger add short code box.
17
+
18
+ -->
19
+
20
+ <div class="aalb-admin-inline aalb-admin-searchbox">
21
+ <img src=<?= AALB_ADMIN_ICON ?> class="aalb-admin-searchbox-amzlogo"
22
+ style="height: 30px; width: 30px; padding: 0px;">
23
+ <input type="text" class="aalb-admin-input-search"
24
+ name="aalb-admin-input-search"
25
+ placeholder="Enter keyword(s)"
26
+ onkeypress='aalb_submit_event(event,"aalb-admin-button-create-amazon-shortcode",this)'/>
27
+ <a class="button aalb-admin-button-create-amazon-shortcode" title="Add Amazon Associates Link Builder Shortcode"
28
+ onclick="aalb_admin_show_create_shortcode_popup(this)">Search
29
+ </a>
30
+ </div>
admin/partials/aalb_meta_box.php CHANGED
@@ -1,95 +1,91 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
16
- $config_loader = new Aalb_Config_Loader();
17
- $aalb_marketplace_names = $config_loader->fetch_marketplaces();
18
- $helper = new Aalb_Helper();
19
- $aalb_store_id_names = $helper->get_store_ids_array();
20
- ?>
21
- <div id="aalb-admin-searchbox">
22
- <img src=<?= AALB_ADMIN_ICON ?> id="aalb-admin-searchbox-amzlogo"
23
- style="height: 30px; width: 30px; padding: 0px;">
24
- <input type="text" id="aalb-admin-input-search"
25
- name="aalb-admin-input-search"
26
- placeholder="Enter keyword(s)"
27
- onkeypress='aalb_submit_event(event,"aalb-admin-button-create-amazon-shortcode")'/>
28
- <a class="button" title="Add Amazon Associates Link Builder Shortcode"
29
- id="aalb-admin-button-create-amazon-shortcode" onclick="aalb_admin_show_create_shortcode_popup()">Search
30
- </a>
31
- </div>
32
- <div id="aalb-admin-popup-container" style="display:none;">
33
- <div class="aalb-admin-popup-options">
34
- <input type="text" id="aalb-admin-popup-input-search" name="aalb-admin-popup-input-search"
35
- placeholder="Enter keyword(s)" onkeypress='aalb_submit_event(event,"aalb-admin-popup-search-button")'/>
36
- <button class="aalb-btn aalb-btn-primary" id="aalb-admin-popup-search-button" type="button"
37
- onclick="aalb_admin_popup_search_items()" style="margin-top:1%">Search
38
- </button>
39
- </div><!--end .aalb-admin-popup-options-->
40
- <div id="aalb-admin-popup-content">
41
- <div class="aalb-admin-alert aalb-admin-alert-info aalb-admin-item-search-loading">
42
- <div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>
43
- Searching relevant products from Amazon
44
- </div><!--end .aalb-admin-item-search-loading-->
45
- <div class="aalb-admin-item-search">
46
- Click to select product(s) to advertise
47
- <div class="aalb-admin-item-search-items"></div>
48
- <a href="#" target="_blank" id="aalb-admin-popup-more-results" class="pull-right">Check more search results
49
- on Amazon</a>
50
- </div><!--end .aalb-admin-item-serch-->
51
- </div><!--end .aalb-admin-popup-content-->
52
- <div class="aalb-selected">
53
- <label>List of Selected Products</label>
54
- </div>
55
- <div class="aalb-admin-popup-shortocde-wrapper">
56
- <div class="aalb-admin-popup-shortcode-options">
57
- <div class="aalb-admin-item-search-templates">
58
- <label>Ad Template</label>
59
- <?php $aalb_default_template = get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ); ?>
60
- <select id="aalb_template_names_list" name="aalb_template_names_list" style="width:100%">
61
- <?php foreach ( $aalb_template_names as $aalb_template_name ) { ?>
62
- <option value="<?= $aalb_template_name ?>" <?php selected( $aalb_default_template, $aalb_template_name ); ?>><?= $aalb_template_name ?></option>
63
- <?php } ?>
64
- </select>
65
- </div>
66
- <div class="aalb-admin-popup-store">
67
- <label>Associate ID</label>
68
- <?php $aalb_default_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME ); ?>
69
- <select id="aalb-admin-popup-store-id" name="aalb-admin-popup-store-id" style="width:100%">
70
- <?php foreach ( $aalb_store_id_names as $aalb_store_id ) { ?>
71
- <option value="<?= $aalb_store_id ?>" <?php selected( $aalb_default_store_id, $aalb_store_id ); ?>> <?= $aalb_store_id ?> </option>
72
- <?php } ?>
73
- </select>
74
- </div>
75
- <div class="aalb-admin-item-search-marketplaces">
76
- <label>Marketplace</label>
77
- <?php $aalb_default_marketplace = get_option( AALB_DEFAULT_MARKETPLACE, AALB_DEFAULT_MARKETPLACE_NAME ); ?>
78
- <select id="aalb_marketplace_names_list" name="aalb_marketplace_names_list" style="width:100%">
79
- <?php foreach ( $aalb_marketplace_names as $aalb_marketplace => $aalb_marketplace_abbr ) { ?>
80
- <option value="<?= $aalb_marketplace ?>" <?php selected( $aalb_default_marketplace, $aalb_marketplace_abbr ); ?>><?= $aalb_marketplace_abbr ?></option>
81
- <?php } ?>
82
- </select>
83
- </div>
84
- </div>
85
- </div><!--end .aalb-admin-popup-shortcode-options-->
86
- <div class="aalb-add-shortcode-button">
87
- <button class="aalb-btn aalb-btn-primary" id="aalb-add-shortcode-button" type="button">Add Shortcode</button>
88
- <div id="aalb-add-shortcode-alert">
89
- <div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>
90
- Creating shortcode. Please wait....
91
- </div>
92
- </div><!--end .aalb-add-shortcode-button-->
93
- </div><!--end .aalb-admin-popup-container-->
94
- <?php
95
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * UI for Add short code popup. responsible to show list of products items based on the keywords.
17
+ * This Metabox enables users to choose template, Associate ID and Market place for which product is being added based on the
18
+ * details selected by plugin user short code is generated.
19
+ */
20
+
21
+ $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
22
+ $config_loader = new Aalb_Config_Loader();
23
+ $aalb_marketplace_names = $config_loader->fetch_marketplaces();
24
+ $helper = new Aalb_Helper();
25
+ $aalb_store_id_names = $helper->get_store_ids_array();
26
+ ?>
27
+
28
+ <div id="aalb-admin-popup-container" style="display:none;">
29
+ <div class="aalb-admin-searchbox aalb-admin-popup-options">
30
+ <input type="text" id="aalb-admin-popup-input-search" name="aalb-admin-popup-input-search"
31
+ placeholder="Enter keyword(s)" onkeypress='aalb_submit_event(event,"aalb-btn-primary",this)'/>
32
+ <button class="aalb-btn aalb-btn-primary" id="aalb-admin-popup-search-button" type="button"
33
+ onclick="aalb_admin_popup_search_items()" style="margin-top:1%">Search
34
+ </button>
35
+ </div><!--end .aalb-admin-popup-options-->
36
+ <div id="aalb-admin-popup-content">
37
+ <div class="aalb-admin-alert aalb-admin-alert-info aalb-admin-item-search-loading">
38
+ <div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>
39
+ Searching relevant products from Amazon
40
+ </div><!--end .aalb-admin-item-search-loading-->
41
+ <div class="aalb-admin-item-search">
42
+ Click to select product(s) to advertise
43
+ <div class="aalb-admin-item-search-items"></div>
44
+ <a href="#" target="_blank" id="aalb-admin-popup-more-results" class="pull-right">Check more search results
45
+ on Amazon</a>
46
+ </div><!--end .aalb-admin-item-serch-->
47
+ </div><!--end .aalb-admin-popup-content-->
48
+ <div class="aalb-selected">
49
+ <label>List of Selected Products</label>
50
+ </div>
51
+ <div class="aalb-admin-popup-shortocde-wrapper">
52
+ <div class="aalb-admin-popup-shortcode-options">
53
+ <div class="aalb-admin-item-search-templates">
54
+ <label>Ad Template</label>
55
+ <?php $aalb_default_template = get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ); ?>
56
+ <select id="aalb_template_names_list" name="aalb_template_names_list" style="width:100%">
57
+ <?php foreach ( $aalb_template_names as $aalb_template_name ) { ?>
58
+ <option value="<?= $aalb_template_name ?>" <?php selected( $aalb_default_template, $aalb_template_name ); ?>><?= $aalb_template_name ?></option>
59
+ <?php } ?>
60
+ </select>
61
+ </div>
62
+ <div class="aalb-admin-popup-store">
63
+ <label>Associate ID</label>
64
+ <?php $aalb_default_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME ); ?>
65
+ <select id="aalb-admin-popup-store-id" name="aalb-admin-popup-store-id" style="width:100%">
66
+ <?php foreach ( $aalb_store_id_names as $aalb_store_id ) { ?>
67
+ <option value="<?= $aalb_store_id ?>" <?php selected( $aalb_default_store_id, $aalb_store_id ); ?>> <?= $aalb_store_id ?> </option>
68
+ <?php } ?>
69
+ </select>
70
+ </div>
71
+ <div class="aalb-admin-item-search-marketplaces">
72
+ <label>Marketplace</label>
73
+ <?php $aalb_default_marketplace = get_option( AALB_DEFAULT_MARKETPLACE, AALB_DEFAULT_MARKETPLACE_NAME ); ?>
74
+ <select id="aalb_marketplace_names_list" name="aalb_marketplace_names_list" style="width:100%">
75
+ <?php foreach ( $aalb_marketplace_names as $aalb_marketplace => $aalb_marketplace_abbr ) { ?>
76
+ <option value="<?= $aalb_marketplace ?>" <?php selected( $aalb_default_marketplace, $aalb_marketplace_abbr ); ?>><?= $aalb_marketplace_abbr ?></option>
77
+ <?php } ?>
78
+ </select>
79
+ </div>
80
+ </div>
81
+ </div><!--end .aalb-admin-popup-shortcode-options-->
82
+ <div class="aalb-add-shortcode-button">
83
+ <button class="aalb-btn aalb-btn-primary" id="aalb-add-shortcode-button" type="button">Add Shortcode</button>
84
+ <div id="aalb-add-shortcode-alert">
85
+ <div class="aalb-admin-icon"><i class="fa fa-spinner fa-pulse"></i></div>
86
+ Creating shortcode. Please wait....
87
+ </div>
88
+ </div><!--end .aalb-add-shortcode-button-->
89
+ </div><!--end .aalb-admin-popup-container-->
90
+ <?php
91
+ ?>
 
 
 
 
admin/sidebar/aalb_sidebar.php CHANGED
@@ -1,135 +1,135 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * The class for adding menu and submenu pages on the sidebar.
17
- * Registers the settings using the Wordpress Settings API for suing in the partials
18
- *
19
- * @since 1.0.0
20
- * @package AmazonAssociatesLinkBuilder
21
- * @subpackage AmazonAssociatesLinkBuilder/admin/sidebar
22
- */
23
- class Aalb_Sidebar {
24
-
25
- /**
26
- * Adds categories to the menu page
27
- *
28
- * @since 1.0.0
29
- */
30
- public function register_sidebar_config_page() {
31
- // Create new top-level menu
32
- add_menu_page( AALB_PROJECT_TITLE, AALB_PROJECT_TITLE, 'manage_options', 'associates-link-builder-about', array( $this, 'about_callback' ), AALB_ICON );
33
- add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' About', 'About', 'manage_options', 'associates-link-builder-about', array( $this, 'about_callback' ) );
34
- add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Settings', 'Settings', 'manage_options', 'associates-link-builder-settings', array( $this, 'settings_callback' ) );
35
- add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Templates', 'Templates', 'manage_options', 'associates-link-builder-templates', array( $this, 'templates_callback' ) );
36
- }
37
-
38
- /**
39
- * Registers credentials to the config group
40
- *
41
- * @since 1.0.0
42
- */
43
- public function register_cred_config_group() {
44
- // Register Credentials
45
- register_setting( AALB_CRED_CONFIG_GROUP, AALB_AWS_ACCESS_KEY, array( $this, 'validate_access_key' ) );
46
- register_setting( AALB_CRED_CONFIG_GROUP, AALB_AWS_SECRET_KEY, array( $this, 'validate_secret_key' ) );
47
- register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_STORE_ID );
48
- register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_MARKETPLACE );
49
- register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_TEMPLATE );
50
- register_setting( AALB_CRED_CONFIG_GROUP, AALB_STORE_ID_NAMES );
51
- }
52
-
53
- /**
54
- * Load the about page partial
55
- * Callbacks to load the page makes the url to use the slug, making it clean.
56
- *
57
- * @since 1.0.0
58
- */
59
- public function about_callback() {
60
- require_once( AALB_ABOUT_PHP );
61
- }
62
-
63
- /**
64
- * Load the settings page partial
65
- * The page to save the credentials and default settings of the admin.
66
- *
67
- * @since 1.0.0
68
- */
69
- public function settings_callback() {
70
- require_once( AALB_CREDENTIALS_PHP );
71
- }
72
-
73
- /**
74
- * Load the template page partial
75
- * The page to make changes to the templates, add new templates or remove existing templates.
76
- *
77
- * @since 1.0.0
78
- */
79
- public function templates_callback() {
80
- require_once( AALB_TEMPLATE_PHP );
81
- }
82
-
83
- /**
84
- * Sanitize the access key provided by the admin.
85
- * Encrypt the access key and store in the db.
86
- *
87
- * @since 1.0.0
88
- *
89
- * @param string $input Access key input by the user.
90
- */
91
- public function validate_access_key( $input ) {
92
- $old_data = get_option( AALB_AWS_ACCESS_KEY );
93
-
94
- return $this->encrypt_keys( $input, $old_data );
95
- }
96
-
97
- /**
98
- * Sanitize the secret key provided by the admin.
99
- * Encrypt the secret key and store in the db.
100
- *
101
- * @since 1.0.0
102
- *
103
- * @param string $input Secret key input by the user.
104
- */
105
- public function validate_secret_key( $input ) {
106
- $old_data = get_option( AALB_AWS_SECRET_KEY );
107
-
108
- return $this->encrypt_keys( $input, $old_data );
109
- }
110
-
111
- /**
112
- * Encrypt the keys provided by the user.
113
- * If the data already exists in the database, then do not retrieve and print it on the viewer page.
114
- * Else encrypt the data and store it in the db.
115
- *
116
- * @since 1.0.0
117
- *
118
- * @param string $input Key input by the user to encrypt.
119
- * @param string $old_data The data if already stored in the database.
120
- */
121
- private function encrypt_keys( $input, $old_data ) {
122
- if ( ! isset( $input ) || trim( $input ) === '' ) {
123
- return $input;
124
- } elseif ( $input == AALB_AWS_SECRET_KEY_MASK ) {
125
- return $old_data;
126
- }
127
-
128
- $output = base64_encode( openssl_encrypt( $input, AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV ) );
129
-
130
- return $output;
131
- }
132
-
133
- }
134
-
135
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class for adding menu and submenu pages on the sidebar.
17
+ * Registers the settings using the Wordpress Settings API for suing in the partials
18
+ *
19
+ * @since 1.0.0
20
+ * @package AmazonAssociatesLinkBuilder
21
+ * @subpackage AmazonAssociatesLinkBuilder/admin/sidebar
22
+ */
23
+ class Aalb_Sidebar {
24
+
25
+ /**
26
+ * Adds categories to the menu page
27
+ *
28
+ * @since 1.0.0
29
+ */
30
+ public function register_sidebar_config_page() {
31
+ // Create new top-level menu
32
+ add_menu_page( AALB_PROJECT_TITLE, AALB_PROJECT_TITLE, 'manage_options', 'associates-link-builder-about', array( $this, 'about_callback' ), AALB_ICON );
33
+ add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' About', 'About', 'manage_options', 'associates-link-builder-about', array( $this, 'about_callback' ) );
34
+ add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Settings', 'Settings', 'manage_options', 'associates-link-builder-settings', array( $this, 'settings_callback' ) );
35
+ add_submenu_page( 'associates-link-builder-about', 'Configure ' . AALB_PROJECT_TITLE . ' Templates', 'Templates', 'manage_options', 'associates-link-builder-templates', array( $this, 'templates_callback' ) );
36
+ }
37
+
38
+ /**
39
+ * Registers credentials to the config group
40
+ *
41
+ * @since 1.0.0
42
+ */
43
+ public function register_cred_config_group() {
44
+ // Register Credentials
45
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_AWS_ACCESS_KEY, array( $this, 'validate_access_key' ) );
46
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_AWS_SECRET_KEY, array( $this, 'validate_secret_key' ) );
47
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_STORE_ID );
48
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_MARKETPLACE );
49
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_DEFAULT_TEMPLATE );
50
+ register_setting( AALB_CRED_CONFIG_GROUP, AALB_STORE_ID_NAMES );
51
+ }
52
+
53
+ /**
54
+ * Load the about page partial
55
+ * Callbacks to load the page makes the url to use the slug, making it clean.
56
+ *
57
+ * @since 1.0.0
58
+ */
59
+ public function about_callback() {
60
+ require_once( AALB_ABOUT_PHP );
61
+ }
62
+
63
+ /**
64
+ * Load the settings page partial
65
+ * The page to save the credentials and default settings of the admin.
66
+ *
67
+ * @since 1.0.0
68
+ */
69
+ public function settings_callback() {
70
+ require_once( AALB_CREDENTIALS_PHP );
71
+ }
72
+
73
+ /**
74
+ * Load the template page partial
75
+ * The page to make changes to the templates, add new templates or remove existing templates.
76
+ *
77
+ * @since 1.0.0
78
+ */
79
+ public function templates_callback() {
80
+ require_once( AALB_TEMPLATE_PHP );
81
+ }
82
+
83
+ /**
84
+ * Sanitize the access key provided by the admin.
85
+ * Encrypt the access key and store in the db.
86
+ *
87
+ * @since 1.0.0
88
+ *
89
+ * @param string $input Access key input by the user.
90
+ */
91
+ public function validate_access_key( $input ) {
92
+ $old_data = get_option( AALB_AWS_ACCESS_KEY );
93
+
94
+ return $this->encrypt_keys( $input, $old_data );
95
+ }
96
+
97
+ /**
98
+ * Sanitize the secret key provided by the admin.
99
+ * Encrypt the secret key and store in the db.
100
+ *
101
+ * @since 1.0.0
102
+ *
103
+ * @param string $input Secret key input by the user.
104
+ */
105
+ public function validate_secret_key( $input ) {
106
+ $old_data = get_option( AALB_AWS_SECRET_KEY );
107
+
108
+ return $this->encrypt_keys( $input, $old_data );
109
+ }
110
+
111
+ /**
112
+ * Encrypt the keys provided by the user.
113
+ * If the data already exists in the database, then do not retrieve and print it on the viewer page.
114
+ * Else encrypt the data and store it in the db.
115
+ *
116
+ * @since 1.0.0
117
+ *
118
+ * @param string $input Key input by the user to encrypt.
119
+ * @param string $old_data The data if already stored in the database.
120
+ */
121
+ private function encrypt_keys( $input, $old_data ) {
122
+ if ( ! isset( $input ) || trim( $input ) === '' ) {
123
+ return $input;
124
+ } elseif ( $input == AALB_AWS_SECRET_KEY_MASK ) {
125
+ return $old_data;
126
+ }
127
+
128
+ $output = base64_encode( openssl_encrypt( $input, AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV ) );
129
+
130
+ return $output;
131
+ }
132
+
133
+ }
134
+
135
+ ?>
admin/sidebar/js/aalb_credentials.js CHANGED
@@ -1,54 +1,54 @@
1
- /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
-
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
-
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
-
13
- /**
14
- * Update the Default Store ID dropdown onchange
15
- *
16
- * @param HTML DOM OBJECT element list of store IDs in "Store IDs" field
17
- */
18
- function aalb_credentials_store_ids_onchange( element ) {
19
- var aalb_store_ids = element.value;
20
- var aalb_store_ids_array = aalb_store_ids.trim().split( /[\n]+/ );
21
- //Selected Store ID
22
- var aalb_store_ids_selected = jQuery( '#aalb_default_store_id' ).val();
23
- var aalb_store_id_dropdown_html = "";
24
- for ( var i = 0; i < aalb_store_ids_array.length; i++ ) {
25
- if ( aalb_store_ids_array[ i ].length > 0 ) {
26
- aalb_store_ids_array[ i ] = aalb_store_ids_array[ i ].trim();
27
- aalb_store_id_dropdown_html += "<option value='" + aalb_store_ids_array[ i ] + "'>" + aalb_store_ids_array[ i ] + "</option>\n";
28
- } else {
29
- //Remove empty lines
30
- aalb_store_ids_array.splice( i, 1 );
31
- }
32
- }
33
- jQuery( '#aalb_store_id_names' ).val( aalb_store_ids_array.join( "\r\n" ) );
34
- //Set the HTML of select dropdown with updated store ids
35
- jQuery( '#aalb_default_store_id' ).html( aalb_store_id_dropdown_html );
36
- //Select the previously selected option value if it exists in the new list
37
- if ( aalb_store_ids_selected.length > 0 && jQuery.inArray( aalb_store_ids_selected, aalb_store_ids_array ) > 0 ) {
38
- jQuery( '#aalb_default_store_id' ).val( aalb_store_ids_selected );
39
- } else {
40
- //If no value is selected, automatically selects first element.
41
- jQuery( "#aalb_default_store_id" ).val( jQuery( "#aalb_default_store_id option:first" ).val() );
42
- }
43
- }
44
- /**
45
- * OnClick Handler for aalb terms and conditions checkbox.
46
- *
47
- */
48
- jQuery( '#aalb-terms-checkbox' ).click( function() {
49
- if ( jQuery( this ).is( ':checked' ) ) {
50
- jQuery( "#submit" ).removeAttr( 'disabled' );
51
- } else {
52
- jQuery( '#submit' ).attr( 'disabled', 'disabled' );
53
- }
54
- } );
1
+ /*
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
+
13
+ /**
14
+ * Update the Default Store ID dropdown onchange
15
+ *
16
+ * @param HTML DOM OBJECT element list of store IDs in "Store IDs" field
17
+ */
18
+ function aalb_credentials_store_ids_onchange( element ) {
19
+ var aalb_store_ids = element.value;
20
+ var aalb_store_ids_array = aalb_store_ids.trim().split( /[\n]+/ );
21
+ //Selected Store ID
22
+ var aalb_store_ids_selected = jQuery( '#aalb_default_store_id' ).val();
23
+ var aalb_store_id_dropdown_html = "";
24
+ for ( var i = 0; i < aalb_store_ids_array.length; i++ ) {
25
+ if ( aalb_store_ids_array[ i ].length > 0 ) {
26
+ aalb_store_ids_array[ i ] = aalb_store_ids_array[ i ].trim();
27
+ aalb_store_id_dropdown_html += "<option value='" + aalb_store_ids_array[ i ] + "'>" + aalb_store_ids_array[ i ] + "</option>\n";
28
+ } else {
29
+ //Remove empty lines
30
+ aalb_store_ids_array.splice( i, 1 );
31
+ }
32
+ }
33
+ jQuery( '#aalb_store_id_names' ).val( aalb_store_ids_array.join( "\r\n" ) );
34
+ //Set the HTML of select dropdown with updated store ids
35
+ jQuery( '#aalb_default_store_id' ).html( aalb_store_id_dropdown_html );
36
+ //Select the previously selected option value if it exists in the new list
37
+ if ( aalb_store_ids_selected.length > 0 && jQuery.inArray( aalb_store_ids_selected, aalb_store_ids_array ) > 0 ) {
38
+ jQuery( '#aalb_default_store_id' ).val( aalb_store_ids_selected );
39
+ } else {
40
+ //If no value is selected, automatically selects first element.
41
+ jQuery( "#aalb_default_store_id" ).val( jQuery( "#aalb_default_store_id option:first" ).val() );
42
+ }
43
+ }
44
+ /**
45
+ * OnClick Handler for aalb terms and conditions checkbox.
46
+ *
47
+ */
48
+ jQuery( '#aalb-terms-checkbox' ).click( function() {
49
+ if ( jQuery( this ).is( ':checked' ) ) {
50
+ jQuery( "#submit" ).removeAttr( 'disabled' );
51
+ } else {
52
+ jQuery( '#submit' ).attr( 'disabled', 'disabled' );
53
+ }
54
+ } );
admin/sidebar/js/aalb_template.js CHANGED
@@ -1,113 +1,113 @@
1
- /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
-
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
-
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
-
13
- var codeMirrorHtml = CodeMirror.fromTextArea( document.getElementById( 'aalb_template_template_html_box' ), {
14
- lineNumbers: true,
15
- value: "",
16
- mode: "xml"
17
- } );
18
-
19
- var codeMirrorCss = CodeMirror.fromTextArea( document.getElementById( 'aalb_template_template_css_box' ), {
20
- lineNumbers: true,
21
- value: "",
22
- mode: "css"
23
- } );
24
-
25
- jQuery.ajaxSetup( {
26
- //Disable caching of AJAX responses
27
- cache: false
28
- } );
29
-
30
- /**
31
- * Trigger onChange event of the template select dropdown on page load
32
- */
33
- jQuery( document ).ready( function() {
34
- if ( jQuery( '#aalb_template_list_select' ).val() != 'new' ) {
35
- jQuery( "#aalb_template_list_select" ).trigger( "change" );
36
- }
37
- } );
38
-
39
- /**
40
- * Set the JS and CSS of the particular template in the respective text area
41
- *
42
- * @param HTML DOM OBJECT element Selected Template name
43
- */
44
- function aalb_template_select_template_onchange( element ) {
45
- if ( element.value == 'new' ) {
46
- codeMirrorCss.setValue( '' );
47
- codeMirrorHtml.setValue( '' );
48
- set_template_read_only( false );
49
- jQuery( '#aalb_template_name' ).removeAttr( "readonly" );
50
- jQuery( '#aalb_template_name' ).val( '' );
51
- jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
52
- jQuery( '#clone_template' ).attr( 'disabled', 'disabled' );
53
- } else {
54
- jQuery( '#clone_template' ).removeAttr( 'disabled' );
55
- jQuery( '#aalb_template_name' ).val( element.value );
56
- jQuery( '#aalb_template_name' ).attr( "readonly", "readonly" );
57
- //Make the Amazon Default templates as Read-Only
58
- if ( wp_opt.aalb_default_templates.split( "," ).indexOf( element.value ) >= 0 ) {
59
- jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
60
- set_template_read_only( true );
61
- base = wp_opt.plugin_url + "template/" + element.value;
62
- jQuery.get( base + ".css", function( data ) {
63
- codeMirrorCss.setValue( data );
64
- } );
65
- jQuery.get( base + ".mustache", function( data ) {
66
- codeMirrorHtml.setValue( data );
67
- } );
68
- } else {
69
- jQuery( '#submit_remove' ).removeAttr( 'disabled' );
70
- set_template_read_only( false );
71
- base = wp_opt.upload_url + element.value;
72
- jQuery.post( wp_opt.ajax_url, {
73
- "action": "get_custom_template_content",
74
- "css": base + ".css",
75
- "mustache": base + ".mustache"
76
- }, function( json ) {
77
- codeMirrorCss.setValue( json.css );
78
- codeMirrorHtml.setValue( json.mustache );
79
- }, "json" );
80
- }
81
- }
82
- }
83
-
84
- /**
85
- * Clones an existing template into a new one.
86
- *
87
- */
88
- function clone_existing_template() {
89
- var templateNameToClone = jQuery( '#aalb_template_list_select' ).val();
90
- jQuery( '#aalb_template_list_select' ).val( 'new' );
91
- jQuery( '#aalb_template_name' ).removeAttr( "readonly" );
92
- jQuery( '#aalb_template_name' ).val( 'CopyOf-' + templateNameToClone );
93
- jQuery( '#clone_template' ).attr( 'disabled', 'disabled' );
94
- jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
95
- //Add CSS Prefix for Amazon Default Templates to prevent style overlapping for clones
96
- if ( wp_opt.aalb_default_templates.split( "," ).indexOf( templateNameToClone ) >= 0 ) {
97
- set_template_read_only( false );
98
- var randomNumForPrefix = Math.floor( (Math.random() * 1000) + 1 );
99
- var prefixRegExObject = new RegExp( 'aalb-', "g" );
100
- var prefixReplaceValue = 'aalb-' + randomNumForPrefix + '-';
101
- codeMirrorHtml.setValue( codeMirrorHtml.getValue().replace( prefixRegExObject, prefixReplaceValue ) );
102
- codeMirrorCss.setValue( codeMirrorCss.getValue().replace( prefixRegExObject, prefixReplaceValue ) );
103
- }
104
- }
105
-
106
- /**
107
- * Sets the HTML and CSS boxes to read only if TRUE is passed.
108
- *
109
- */
110
- function set_template_read_only( isReadOnly ) {
111
- codeMirrorHtml.setOption( "readOnly", isReadOnly );
112
- codeMirrorCss.setOption( "readOnly", isReadOnly );
113
- }
1
+ /*
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
+
13
+ var codeMirrorHtml = CodeMirror.fromTextArea( document.getElementById( 'aalb_template_template_html_box' ), {
14
+ lineNumbers: true,
15
+ value: "",
16
+ mode: "xml"
17
+ } );
18
+
19
+ var codeMirrorCss = CodeMirror.fromTextArea( document.getElementById( 'aalb_template_template_css_box' ), {
20
+ lineNumbers: true,
21
+ value: "",
22
+ mode: "css"
23
+ } );
24
+
25
+ jQuery.ajaxSetup( {
26
+ //Disable caching of AJAX responses
27
+ cache: false
28
+ } );
29
+
30
+ /**
31
+ * Trigger onChange event of the template select dropdown on page load
32
+ */
33
+ jQuery( document ).ready( function() {
34
+ if ( jQuery( '#aalb_template_list_select' ).val() != 'new' ) {
35
+ jQuery( "#aalb_template_list_select" ).trigger( "change" );
36
+ }
37
+ } );
38
+
39
+ /**
40
+ * Set the JS and CSS of the particular template in the respective text area
41
+ *
42
+ * @param HTML DOM OBJECT element Selected Template name
43
+ */
44
+ function aalb_template_select_template_onchange( element ) {
45
+ if ( element.value == 'new' ) {
46
+ codeMirrorCss.setValue( '' );
47
+ codeMirrorHtml.setValue( '' );
48
+ set_template_read_only( false );
49
+ jQuery( '#aalb_template_name' ).removeAttr( "readonly" );
50
+ jQuery( '#aalb_template_name' ).val( '' );
51
+ jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
52
+ jQuery( '#clone_template' ).attr( 'disabled', 'disabled' );
53
+ } else {
54
+ jQuery( '#clone_template' ).removeAttr( 'disabled' );
55
+ jQuery( '#aalb_template_name' ).val( element.value );
56
+ jQuery( '#aalb_template_name' ).attr( "readonly", "readonly" );
57
+ //Make the Amazon Default templates as Read-Only
58
+ if ( wp_opt.aalb_default_templates.split( "," ).indexOf( element.value ) >= 0 ) {
59
+ jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
60
+ set_template_read_only( true );
61
+ base = wp_opt.plugin_url + "template/" + element.value;
62
+ jQuery.get( base + ".css", function( data ) {
63
+ codeMirrorCss.setValue( data );
64
+ } );
65
+ jQuery.get( base + ".mustache", function( data ) {
66
+ codeMirrorHtml.setValue( data );
67
+ } );
68
+ } else {
69
+ jQuery( '#submit_remove' ).removeAttr( 'disabled' );
70
+ set_template_read_only( false );
71
+ base = wp_opt.upload_url + element.value;
72
+ jQuery.post( wp_opt.ajax_url, {
73
+ "action": "get_custom_template_content",
74
+ "css": base + ".css",
75
+ "mustache": base + ".mustache"
76
+ }, function( json ) {
77
+ codeMirrorCss.setValue( json.css );
78
+ codeMirrorHtml.setValue( json.mustache );
79
+ }, "json" );
80
+ }
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Clones an existing template into a new one.
86
+ *
87
+ */
88
+ function clone_existing_template() {
89
+ var templateNameToClone = jQuery( '#aalb_template_list_select' ).val();
90
+ jQuery( '#aalb_template_list_select' ).val( 'new' );
91
+ jQuery( '#aalb_template_name' ).removeAttr( "readonly" );
92
+ jQuery( '#aalb_template_name' ).val( 'CopyOf-' + templateNameToClone );
93
+ jQuery( '#clone_template' ).attr( 'disabled', 'disabled' );
94
+ jQuery( '#submit_remove' ).attr( 'disabled', 'disabled' );
95
+ //Add CSS Prefix for Amazon Default Templates to prevent style overlapping for clones
96
+ if ( wp_opt.aalb_default_templates.split( "," ).indexOf( templateNameToClone ) >= 0 ) {
97
+ set_template_read_only( false );
98
+ var randomNumForPrefix = Math.floor( (Math.random() * 1000) + 1 );
99
+ var prefixRegExObject = new RegExp( 'aalb-', "g" );
100
+ var prefixReplaceValue = 'aalb-' + randomNumForPrefix + '-';
101
+ codeMirrorHtml.setValue( codeMirrorHtml.getValue().replace( prefixRegExObject, prefixReplaceValue ) );
102
+ codeMirrorCss.setValue( codeMirrorCss.getValue().replace( prefixRegExObject, prefixReplaceValue ) );
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Sets the HTML and CSS boxes to read only if TRUE is passed.
108
+ *
109
+ */
110
+ function set_template_read_only( isReadOnly ) {
111
+ codeMirrorHtml.setOption( "readOnly", isReadOnly );
112
+ codeMirrorCss.setOption( "readOnly", isReadOnly );
113
+ }
admin/sidebar/partials/aalb_about.php CHANGED
@@ -1,171 +1,171 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- include 'aalb_admin_ui_common.php'; ?>
16
- <div class="wrap">
17
- <h2><?= AALB_PROJECT_TITLE ?></h2>
18
- <div class="card" style="max-width:100%;">
19
- <h2>About Amazon Associates Program</h2>
20
- <p>
21
- The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies
22
- across the globe, the Amazon Associates Program has been partnering with content creators to help them
23
- monetize their passions since 1996. To learn more about the Amazon Associates Program, please click <a
24
- target="_blank" href="https://affiliate-program.amazon.com/">here</a>.
25
- </p>
26
- <h2>About Amazon Associates Link Builder </h2>
27
- <p>
28
- Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to
29
- search for products in the Amazon catalog, access real-time price and availability information, and easily
30
- create links in your posts to products on Amazon.com. You will be able to generate text links, create custom
31
- ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
32
- </p>
33
- <b>Note</b>
34
- <ul>
35
- <li>
36
- You must review and accept the Amazon Associates Link Builder <a
37
- href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf"
38
- target="_blank">Conditions of Use</a>.
39
- </li>
40
- <li>
41
- The plugin is currently in beta form. We intend to regularly add new features and enhancements
42
- throughout the beta period and beyond, and welcome your feedback and input.
43
- </li>
44
- </ul>
45
- <h2>Getting Started</h2>
46
- <h3>Step 1 - Become an Associate</h3>
47
- <p>
48
- To become an Associate, create an Amazon Associates account using URL for your country:
49
- </p>
50
- <table border="0" cellpadding="10">
51
- <tr>
52
- <td><b>Brazil</b></td>
53
- <td>
54
- <a href="https://associados.amazon.com.br/" target="_blank">https://associados.amazon.com.br/</a>
55
- </td>
56
- </tr>
57
- <tr>
58
- <td><b>Canada</b></td>
59
- <td>
60
- <a href="https://associates.amazon.ca/" target="_blank">https://associates.amazon.ca/</a>
61
- </td>
62
- </tr>
63
- <tr>
64
- <td><b>China</b></td>
65
- <td>
66
- <a href="https://associates.amazon.cn/" target="_blank">https://associates.amazon.cn/</a>
67
- </td>
68
- </tr>
69
- <tr>
70
- <td><b>France</b></td>
71
- <td>
72
- <a href="http://partenaires.amazon.fr/" target="_blank">http://partenaires.amazon.fr/</a>
73
- </td>
74
- </tr>
75
- <tr>
76
- <td><b>Germany</b></td>
77
- <td>
78
- <a href="https://partnernet.amazon.de/" target="_blank">https://partnernet.amazon.de/</a>
79
- </td>
80
- </tr>
81
- <tr>
82
- <td><b>India</b></td>
83
- <td>
84
- <a href="http://affiliate-program.amazon.in/"
85
- target="_blank">http://affiliate-program.amazon.in/</a>
86
- </td>
87
- </tr>
88
- <tr>
89
- <td><b>Italy</b></td>
90
- <td>
91
- <a href="https://programma-affiliazione.amazon.it/" target="_blank">https://programma-affiliazione.amazon.it/</a>
92
- </td>
93
- </tr>
94
- <tr>
95
- <td><b>Japan</b></td>
96
- <td>
97
- <a href="https://affiliate.amazon.co.jp/" target="_blank">https://affiliate.amazon.co.jp/</a>
98
- </td>
99
- </tr>
100
- <tr>
101
- <td><b>Mexico</b></td>
102
- <td>
103
- <a href="https://afiliados.amazon.com.mx/" target="_blank">https://afiliados.amazon.com.mx/</a>
104
- </td>
105
- </tr>
106
- <tr>
107
- <td><b>Spain</b></td>
108
- <td>
109
- <a href="https://afiliados.amazon.es/" target="_blank">https://afiliados.amazon.es/</a>
110
- </td>
111
- </tr>
112
- <tr>
113
- <td><b>United Kingdom</b></td>
114
- <td>
115
- <a href="https://affiliate-program.amazon.co.uk/" target="_blank">https://affiliate-program.amazon.co.uk/</a>
116
- </td>
117
- </tr>
118
- <tr>
119
- <td><b>United States</b></td>
120
- <td>
121
- <a href="https://affiliate-program.amazon.com/" target="_blank">https://affiliate-program.amazon.com/</a>
122
- </td>
123
- </tr>
124
- </table>
125
- <p>
126
- Your Associate ID works only in the country in which you register. If you’d like to be an Associate in more
127
- than one country, please register separately for each country.
128
- </p>
129
- <h3>Step 2 - Sign up for the Amazon Product Advertising API</h3>
130
- <p>
131
- Sign up for the Amazon Product Advertising API by following the instructions listed
132
- <a target="_blank" href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html">here</a>.
133
- The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences
134
- around the world, serving tens of thousands of applications and more than 1 billion API requests every day.
135
- It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon
136
- product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access
137
- Amazon.com product catalog data without requiring additional software development.
138
- </p>
139
- <h3>Step 3 - Configure plugin for first use </h3>
140
- <p>
141
- Use the Associates Link Builder->Settings screen to configure the plugin.
142
- </p>
143
- <ol>
144
- <li>Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke
145
- requests to the Amazon Product Advertising API for fetching information on an item.
146
- </li>
147
- <li>Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon.
148
- You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new
149
- tracking ID in your Amazon Associates account for using it as Associate ID in the plugin.
150
- </li>
151
- <li>Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered
152
- (for example, if you’ve signed up for the Amazon Associates Program in UK, then your default marketplace
153
- selection should be UK) and select an appropriate template for rendering your ads.
154
- </li>
155
- </ol>
156
- <p>
157
- That's it! You’re all set to start adding Amazon affiliate links to your posts using the Amazon Associates
158
- Link Builder plugin!
159
- </p>
160
- <h2>User Guide</h2>
161
- <p>
162
- Review
163
- <a target="_blank" href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf">Link
164
- Builder User Guide</a> for more information on getting started and key features of the plugin.
165
- </p>
166
- <h2>Support</h2>
167
- <p>If you get stuck, or have any questions, you can ask for help in the <a href="https://wordpress.org/support/plugin/amazon-associates-link-builder"
168
- target="_blank">Amazon Associates Link Builder plugin forum</a>.
169
- </p>
170
- </div>
171
  </div>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ include 'aalb_admin_ui_common.php'; ?>
16
+ <div class="wrap">
17
+ <h2><?= AALB_PROJECT_TITLE ?></h2>
18
+ <div class="card" style="max-width:100%;">
19
+ <h2>About Amazon Associates Program</h2>
20
+ <p>
21
+ The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies
22
+ across the globe, the Amazon Associates Program has been partnering with content creators to help them
23
+ monetize their passions since 1996. To learn more about the Amazon Associates Program, please click <a
24
+ target="_blank" href="https://affiliate-program.amazon.com/">here</a>.
25
+ </p>
26
+ <h2>About Amazon Associates Link Builder </h2>
27
+ <p>
28
+ Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to
29
+ search for products in the Amazon catalog, access real-time price and availability information, and easily
30
+ create links in your posts to products on Amazon.com. You will be able to generate text links, create custom
31
+ ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
32
+ </p>
33
+ <b>Note</b>
34
+ <ul>
35
+ <li>
36
+ You must review and accept the Amazon Associates Link Builder <a
37
+ href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf"
38
+ target="_blank">Conditions of Use</a>.
39
+ </li>
40
+ <li>
41
+ The plugin is currently in beta form. We intend to regularly add new features and enhancements
42
+ throughout the beta period and beyond, and welcome your feedback and input.
43
+ </li>
44
+ </ul>
45
+ <h2>Getting Started</h2>
46
+ <h3>Step 1 - Become an Associate</h3>
47
+ <p>
48
+ To become an Associate, create an Amazon Associates account using URL for your country:
49
+ </p>
50
+ <table border="0" cellpadding="10">
51
+ <tr>
52
+ <td><b>Brazil</b></td>
53
+ <td>
54
+ <a href="https://associados.amazon.com.br/" target="_blank">https://associados.amazon.com.br/</a>
55
+ </td>
56
+ </tr>
57
+ <tr>
58
+ <td><b>Canada</b></td>
59
+ <td>
60
+ <a href="https://associates.amazon.ca/" target="_blank">https://associates.amazon.ca/</a>
61
+ </td>
62
+ </tr>
63
+ <tr>
64
+ <td><b>China</b></td>
65
+ <td>
66
+ <a href="https://associates.amazon.cn/" target="_blank">https://associates.amazon.cn/</a>
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td><b>France</b></td>
71
+ <td>
72
+ <a href="http://partenaires.amazon.fr/" target="_blank">http://partenaires.amazon.fr/</a>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td><b>Germany</b></td>
77
+ <td>
78
+ <a href="https://partnernet.amazon.de/" target="_blank">https://partnernet.amazon.de/</a>
79
+ </td>
80
+ </tr>
81
+ <tr>
82
+ <td><b>India</b></td>
83
+ <td>
84
+ <a href="http://affiliate-program.amazon.in/"
85
+ target="_blank">http://affiliate-program.amazon.in/</a>
86
+ </td>
87
+ </tr>
88
+ <tr>
89
+ <td><b>Italy</b></td>
90
+ <td>
91
+ <a href="https://programma-affiliazione.amazon.it/" target="_blank">https://programma-affiliazione.amazon.it/</a>
92
+ </td>
93
+ </tr>
94
+ <tr>
95
+ <td><b>Japan</b></td>
96
+ <td>
97
+ <a href="https://affiliate.amazon.co.jp/" target="_blank">https://affiliate.amazon.co.jp/</a>
98
+ </td>
99
+ </tr>
100
+ <tr>
101
+ <td><b>Mexico</b></td>
102
+ <td>
103
+ <a href="https://afiliados.amazon.com.mx/" target="_blank">https://afiliados.amazon.com.mx/</a>
104
+ </td>
105
+ </tr>
106
+ <tr>
107
+ <td><b>Spain</b></td>
108
+ <td>
109
+ <a href="https://afiliados.amazon.es/" target="_blank">https://afiliados.amazon.es/</a>
110
+ </td>
111
+ </tr>
112
+ <tr>
113
+ <td><b>United Kingdom</b></td>
114
+ <td>
115
+ <a href="https://affiliate-program.amazon.co.uk/" target="_blank">https://affiliate-program.amazon.co.uk/</a>
116
+ </td>
117
+ </tr>
118
+ <tr>
119
+ <td><b>United States</b></td>
120
+ <td>
121
+ <a href="https://affiliate-program.amazon.com/" target="_blank">https://affiliate-program.amazon.com/</a>
122
+ </td>
123
+ </tr>
124
+ </table>
125
+ <p>
126
+ Your Associate ID works only in the country in which you register. If you’d like to be an Associate in more
127
+ than one country, please register separately for each country.
128
+ </p>
129
+ <h3>Step 2 - Sign up for the Amazon Product Advertising API</h3>
130
+ <p>
131
+ Sign up for the Amazon Product Advertising API by following the instructions listed
132
+ <a target="_blank" href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html">here</a>.
133
+ The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences
134
+ around the world, serving tens of thousands of applications and more than 1 billion API requests every day.
135
+ It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon
136
+ product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access
137
+ Amazon.com product catalog data without requiring additional software development.
138
+ </p>
139
+ <h3>Step 3 - Configure plugin for first use </h3>
140
+ <p>
141
+ Use the Associates Link Builder->Settings screen to configure the plugin.
142
+ </p>
143
+ <ol>
144
+ <li>Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke
145
+ requests to the Amazon Product Advertising API for fetching information on an item.
146
+ </li>
147
+ <li>Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon.
148
+ You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new
149
+ tracking ID in your Amazon Associates account for using it as Associate ID in the plugin.
150
+ </li>
151
+ <li>Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered
152
+ (for example, if you’ve signed up for the Amazon Associates Program in UK, then your default marketplace
153
+ selection should be UK) and select an appropriate template for rendering your ads.
154
+ </li>
155
+ </ol>
156
+ <p>
157
+ That's it! You’re all set to start adding Amazon affiliate links to your posts using the Amazon Associates
158
+ Link Builder plugin!
159
+ </p>
160
+ <h2>User Guide</h2>
161
+ <p>
162
+ Review
163
+ <a target="_blank" href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf">Link
164
+ Builder User Guide</a> for more information on getting started and key features of the plugin.
165
+ </p>
166
+ <h2>Support</h2>
167
+ <p>If you get stuck, or have any questions, you can ask for help in the <a href="https://wordpress.org/support/plugin/amazon-associates-link-builder"
168
+ target="_blank">Amazon Associates Link Builder plugin forum</a>.
169
+ </p>
170
+ </div>
171
  </div>
admin/sidebar/partials/aalb_admin_ui_common.php CHANGED
@@ -1,32 +1,32 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- //File with common functionalities for Admin pages.
16
-
17
- include 'aalb_ui_common.php';
18
-
19
- if ( ! is_admin() ) {
20
- die( "Permission Denied" );
21
- }
22
-
23
- if ( ! is_ssl() ) {
24
- //action when page is NOT using SSL
25
- if ( ! get_option( AALB_SHOW_HTTP_WARNING_ONCE ) ) {
26
- // This info message is showed only once.
27
- aalb_info_notice( 'We <b>recommend</b> using HTTPs connection for improved security.' );
28
- update_option( AALB_SHOW_HTTP_WARNING_ONCE, true );
29
- }
30
- }
31
-
32
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ //File with common functionalities for Admin pages.
16
+
17
+ include 'aalb_ui_common.php';
18
+
19
+ if ( ! is_admin() ) {
20
+ die( "Permission Denied" );
21
+ }
22
+
23
+ if ( ! is_ssl() ) {
24
+ //action when page is NOT using SSL
25
+ if ( ! get_option( AALB_SHOW_HTTP_WARNING_ONCE ) ) {
26
+ // This info message is showed only once.
27
+ aalb_info_notice( 'We <b>recommend</b> using HTTPs connection for improved security.' );
28
+ update_option( AALB_SHOW_HTTP_WARNING_ONCE, true );
29
+ }
30
+ }
31
+
32
+ ?>
admin/sidebar/partials/aalb_credentials.php CHANGED
@@ -1,148 +1,148 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- include 'aalb_admin_ui_common.php';
16
- $helper = new Aalb_Helper();
17
- $aalb_store_id_names = $helper->get_store_ids_array();
18
- wp_enqueue_script( 'jquery' );
19
- wp_enqueue_script( 'aalb_credentials_js', AALB_CREDENTIALS_JS, array( 'jquery' ) );
20
- wp_localize_script( 'aalb_credentials_js', 'wp_opt', array( 'plugin_url' => AALB_PLUGIN_URL ) );
21
- ?>
22
-
23
- <div class="wrap">
24
- <h2>Settings for <?= AALB_PROJECT_TITLE ?></h2>
25
- <br>
26
- <form method="post" action="options.php">
27
- <?php settings_fields( AALB_CRED_CONFIG_GROUP );
28
- do_settings_sections( AALB_CRED_CONFIG_GROUP ); ?>
29
- <table class="widefat fixed">
30
- <tr>
31
- <th scope="row" style="width:15%;">Access Key ID</th>
32
- <td style="vertical-align:middle;">
33
- <input type="text" name="aalb_aws_access_key" required style="width:90%"
34
- value="<?php echo esc_attr( openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV ) ); ?>"/>
35
- </td>
36
- <td>Your Access Key ID that you generated after signing up for the Amazon Product Advertising API. If
37
- you have not already signed up for the Amazon Product Advertising API, you can do so by following
38
- instructions listed <a
39
- href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html"
40
- target="_blank">here</a>.
41
- </td>
42
- </tr>
43
- <tr>
44
- <th scope="row" style="width:15%;">Secret Access Key</th>
45
- <?php $secret_key = get_option( AALB_AWS_SECRET_KEY );
46
- if ( $secret_key ) {
47
- $secret_key = AALB_AWS_SECRET_KEY_MASK;
48
- }
49
- ?>
50
- <td style="vertical-align:middle;"><input type="password" name="aalb_aws_secret_key" required
51
- style="width:90%" value="<?php echo esc_attr( $secret_key ); ?>"
52
- autocomplete="off"/></td>
53
- <td>A key that is used in conjunction with the Access Key ID to cryptographically sign an API request.
54
- To retrieve your Access Key ID or Secret Access Key, go to <a
55
- href="https://affiliate-program.amazon.com/gp/advertising/api/detail/your-account.html"
56
- target="_blank">Manage Your Account</a>. The plugin uses a default encryption key for
57
- encrypting the Secret Key. You can change the key using AALB_ENCRYPTION_KEY parameter defined in
58
- /aalb_config.php.
59
- </td>
60
- </tr>
61
- <tr>
62
- <th scope="row" style="width:15%;">Associate ID</th>
63
- <td style="width:90%;vertical-align:middle;">
64
- <textarea type="text" id="aalb_store_id_names" name="aalb_store_id_names" style="width:90%"
65
- value="<?php echo esc_attr( get_option( AALB_STORE_ID_NAMES ) ); ?>"
66
- onchange="aalb_credentials_store_ids_onchange(this)"><?php echo esc_attr( get_option( AALB_STORE_ID_NAMES ) ); ?>
67
- </textarea>
68
- </td>
69
- <td>Associate ID is used to monitor traffic and sales from your links to Amazon. You can add one store
70
- id or tracking id per row. You are recommended to create a new tracking ID in your Amazon Associates
71
- account for using it as Associate ID in the plugin.
72
- </td>
73
- </tr>
74
- <tr>
75
- <th scope="row" style="width:15%;">Default Associate ID</th>
76
- <td style="vertical-align:middle;">
77
- <?php $default_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME ); ?>
78
- <select id="aalb_default_store_id" name="aalb_default_store_id" style="width:90%">
79
- <?php
80
- foreach ( $aalb_store_id_names as $store_id ) {
81
- echo '<option value="' . $store_id . '"';
82
- selected( $default_store_id, $store_id );
83
- echo '>' . $store_id . '</option>\n';
84
- }
85
- ?>
86
- </select>
87
- </td>
88
- <td>The Associate ID that will be used for tagging the affiliate links generated by the plugin if no tag
89
- is specified in the short code.
90
- </td>
91
- </tr>
92
- <tr>
93
- <th scope="row" style="width:15%;">Default Marketplace</th>
94
- <td style="vertical-align:middle;">
95
- <?php $default_marketplace = get_option( AALB_DEFAULT_MARKETPLACE, AALB_DEFAULT_MARKETPLACE_NAME ); ?>
96
- <select name="aalb_default_marketplace" style="width:90%">
97
- <?php
98
- $config_loader = new Aalb_Config_Loader();
99
- $aalb_marketplace_names = $config_loader->fetch_marketplaces();
100
- foreach ( $aalb_marketplace_names as $marketplace ) {
101
- echo '<option value="' . $marketplace . '"';
102
- selected( $default_marketplace, $marketplace );
103
- echo '>' . $marketplace . '</option>\n';
104
- }
105
- ?>
106
- </select>
107
- </td>
108
- <td>Set the default Amazon marketplace based on the Amazon website that is identified in your Associates
109
- Account (for instance, if you have signed up for Amazon.co.uk site, then your default marketplace
110
- selection should be UK).
111
- </td>
112
- </tr>
113
- <tr>
114
- <th scope="row" style="width:15%;">Default Template</th>
115
- <td style="vertical-align:middle;">
116
- <?php $default_template = get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ); ?>
117
- <select name="aalb_default_template" style="width:90%">
118
- <?php
119
- $templates = get_option( AALB_TEMPLATE_NAMES, $default_template );
120
- foreach ( $templates as $template ) {
121
- echo '<option value="' . $template . '"';
122
- selected( $default_template, $template );
123
- echo '>' . $template . '</option>\n';
124
- }
125
- ?>
126
- </select>
127
- </td>
128
- <td>The ad template that will be used for rendering the ad if no template is specified in the short
129
- code.
130
- </td>
131
- </tr>
132
- </table>
133
- <br>
134
- <table>
135
- <tr>
136
- <th scope="row" style="width:1%;">
137
- <input id="aalb-terms-checkbox" type="checkbox" name="demo-checkbox" value="1"/>
138
- </th>
139
- <td style="vertical-align:middle;">
140
- Check here to indicate that you have read and agree to the Amazon Associates Link Builder <a
141
- href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf"
142
- target="_blank">Conditions of Use</a>.
143
- </td>
144
- </tr>
145
- </table>
146
- <?php submit_button( 'Save Changes', 'primary', 'submit', true, array( 'disabled' => 'disabled' ) ); ?>
147
- </form>
148
- </div>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ include 'aalb_admin_ui_common.php';
16
+ $helper = new Aalb_Helper();
17
+ $aalb_store_id_names = $helper->get_store_ids_array();
18
+ wp_enqueue_script( 'jquery' );
19
+ wp_enqueue_script( 'aalb_credentials_js', AALB_CREDENTIALS_JS, array( 'jquery' ) );
20
+ wp_localize_script( 'aalb_credentials_js', 'wp_opt', array( 'plugin_url' => AALB_PLUGIN_URL ) );
21
+ ?>
22
+
23
+ <div class="wrap">
24
+ <h2>Settings for <?= AALB_PROJECT_TITLE ?></h2>
25
+ <br>
26
+ <form method="post" action="options.php">
27
+ <?php settings_fields( AALB_CRED_CONFIG_GROUP );
28
+ do_settings_sections( AALB_CRED_CONFIG_GROUP ); ?>
29
+ <table class="widefat fixed">
30
+ <tr>
31
+ <th scope="row" style="width:15%;">Access Key ID</th>
32
+ <td style="vertical-align:middle;">
33
+ <input type="text" name="aalb_aws_access_key" required style="width:90%"
34
+ value="<?php echo esc_attr( openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV ) ); ?>"/>
35
+ </td>
36
+ <td>Your Access Key ID that you generated after signing up for the Amazon Product Advertising API. If
37
+ you have not already signed up for the Amazon Product Advertising API, you can do so by following
38
+ instructions listed <a
39
+ href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html"
40
+ target="_blank">here</a>.
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <th scope="row" style="width:15%;">Secret Access Key</th>
45
+ <?php $secret_key = get_option( AALB_AWS_SECRET_KEY );
46
+ if ( $secret_key ) {
47
+ $secret_key = AALB_AWS_SECRET_KEY_MASK;
48
+ }
49
+ ?>
50
+ <td style="vertical-align:middle;"><input type="password" name="aalb_aws_secret_key" required
51
+ style="width:90%" value="<?php echo esc_attr( $secret_key ); ?>"
52
+ autocomplete="off"/></td>
53
+ <td>A key that is used in conjunction with the Access Key ID to cryptographically sign an API request.
54
+ To retrieve your Access Key ID or Secret Access Key, go to <a
55
+ href="https://affiliate-program.amazon.com/gp/advertising/api/detail/your-account.html"
56
+ target="_blank">Manage Your Account</a>. The plugin uses a default encryption key for
57
+ encrypting the Secret Key. You can change the key using AALB_ENCRYPTION_KEY parameter defined in
58
+ /aalb_config.php.
59
+ </td>
60
+ </tr>
61
+ <tr>
62
+ <th scope="row" style="width:15%;">Associate ID</th>
63
+ <td style="width:90%;vertical-align:middle;">
64
+ <textarea type="text" id="aalb_store_id_names" name="aalb_store_id_names" style="width:90%"
65
+ value="<?php echo esc_attr( get_option( AALB_STORE_ID_NAMES ) ); ?>"
66
+ onchange="aalb_credentials_store_ids_onchange(this)"><?php echo esc_attr( get_option( AALB_STORE_ID_NAMES ) ); ?>
67
+ </textarea>
68
+ </td>
69
+ <td>Associate ID is used to monitor traffic and sales from your links to Amazon. You can add one store
70
+ id or tracking id per row. You are recommended to create a new tracking ID in your Amazon Associates
71
+ account for using it as Associate ID in the plugin.
72
+ </td>
73
+ </tr>
74
+ <tr>
75
+ <th scope="row" style="width:15%;">Default Associate ID</th>
76
+ <td style="vertical-align:middle;">
77
+ <?php $default_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME ); ?>
78
+ <select id="aalb_default_store_id" name="aalb_default_store_id" style="width:90%">
79
+ <?php
80
+ foreach ( $aalb_store_id_names as $store_id ) {
81
+ echo '<option value="' . $store_id . '"';
82
+ selected( $default_store_id, $store_id );
83
+ echo '>' . $store_id . '</option>\n';
84
+ }
85
+ ?>
86
+ </select>
87
+ </td>
88
+ <td>The Associate ID that will be used for tagging the affiliate links generated by the plugin if no tag
89
+ is specified in the short code.
90
+ </td>
91
+ </tr>
92
+ <tr>
93
+ <th scope="row" style="width:15%;">Default Marketplace</th>
94
+ <td style="vertical-align:middle;">
95
+ <?php $default_marketplace = get_option( AALB_DEFAULT_MARKETPLACE, AALB_DEFAULT_MARKETPLACE_NAME ); ?>
96
+ <select name="aalb_default_marketplace" style="width:90%">
97
+ <?php
98
+ $config_loader = new Aalb_Config_Loader();
99
+ $aalb_marketplace_names = $config_loader->fetch_marketplaces();
100
+ foreach ( $aalb_marketplace_names as $marketplace ) {
101
+ echo '<option value="' . $marketplace . '"';
102
+ selected( $default_marketplace, $marketplace );
103
+ echo '>' . $marketplace . '</option>\n';
104
+ }
105
+ ?>
106
+ </select>
107
+ </td>
108
+ <td>Set the default Amazon marketplace based on the Amazon website that is identified in your Associates
109
+ Account (for instance, if you have signed up for Amazon.co.uk site, then your default marketplace
110
+ selection should be UK).
111
+ </td>
112
+ </tr>
113
+ <tr>
114
+ <th scope="row" style="width:15%;">Default Template</th>
115
+ <td style="vertical-align:middle;">
116
+ <?php $default_template = get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ); ?>
117
+ <select name="aalb_default_template" style="width:90%">
118
+ <?php
119
+ $templates = get_option( AALB_TEMPLATE_NAMES, $default_template );
120
+ foreach ( $templates as $template ) {
121
+ echo '<option value="' . $template . '"';
122
+ selected( $default_template, $template );
123
+ echo '>' . $template . '</option>\n';
124
+ }
125
+ ?>
126
+ </select>
127
+ </td>
128
+ <td>The ad template that will be used for rendering the ad if no template is specified in the short
129
+ code.
130
+ </td>
131
+ </tr>
132
+ </table>
133
+ <br>
134
+ <table>
135
+ <tr>
136
+ <th scope="row" style="width:1%;">
137
+ <input id="aalb-terms-checkbox" type="checkbox" name="demo-checkbox" value="1"/>
138
+ </th>
139
+ <td style="vertical-align:middle;">
140
+ Check here to indicate that you have read and agree to the Amazon Associates Link Builder <a
141
+ href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf"
142
+ target="_blank">Conditions of Use</a>.
143
+ </td>
144
+ </tr>
145
+ </table>
146
+ <?php submit_button( 'Save Changes', 'primary', 'submit', true, array( 'disabled' => 'disabled' ) ); ?>
147
+ </form>
148
+ </div>
admin/sidebar/partials/aalb_templates.php CHANGED
@@ -1,252 +1,252 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- include 'aalb_admin_ui_common.php';
16
- $helper = new Aalb_Helper();
17
- $helper->aalb_initialize_wp_filesystem_api();
18
-
19
- /**
20
- * Verifies whether file exists and is writable
21
- *
22
- * @since 1.0.0
23
- *
24
- * @param string $file Name of the file
25
- *
26
- * @return bool TRUE if file exists and is writable or if it's a new file which, throws exception otherwise
27
- */
28
- function aalb_verify_file_is_writable( $file ) {
29
- if ( is_file( $file ) and ! is_writable( $file ) ) {
30
- throw new Exception( "Save Failed. The existing file " . $file . " is not writable." );
31
- }
32
-
33
- return true;
34
- }
35
-
36
- /**
37
- * Writes content to a file
38
- *
39
- * @since 1.0.0
40
- *
41
- * @param string $file Name of the file
42
- * @param string $content Content to be written
43
- *
44
- * @return bool TRUE if write was successful, throws exception otherwise
45
- */
46
- function aalb_write_to_file( $file, $content ) {
47
- global $wp_filesystem;
48
- if ( $wp_filesystem->put_contents( $file, $content ) === false ) {
49
- throw new Exception( "Save Failed. Error writing contents to file: " . $file );
50
- }
51
-
52
- return true;
53
- }
54
-
55
- /**
56
- * Saves new or updates existing template.
57
- * Writes template CSS and HTML into files.
58
- *
59
- * @since 1.0.0
60
- *
61
- * @param string $file Name of the file without .extension
62
- * @param string $content_html HTML content to be saved
63
- * @param string $content_css CSS content to be saved
64
- */
65
- function aalb_save_template( $file, $content_html, $content_css ) {
66
- $file_mustache = $file . ".mustache";
67
- $file_css = $file . ".css";
68
- try {
69
- if ( ( aalb_verify_file_is_writable( $file_css ) and aalb_verify_file_is_writable( $file_mustache ) ) ) {
70
- //Both files are (existing and writable) or (a new file is specified)
71
- if ( aalb_write_to_file( $file_mustache, $content_html ) and aalb_write_to_file( $file_css, $content_css ) ) {
72
- //Both files were saved successfully
73
- //Else case never occurs as an exception is thrown in false case
74
- $saveFailed = false;
75
- aalb_success_notice( "Template Saved Successfully" );
76
- }
77
- }
78
- } catch ( Exception $e ) {
79
- throw new Exception( $e->getMessage() );
80
- }
81
- }
82
-
83
- /**
84
- * Finds any change in the current list of templates.
85
- * Flags a note if either a template is added or removed.
86
- *
87
- * @since 1.3
88
- *
89
- * @param array $aalb_current_template_names Current list of templates
90
- * @param array $aalb_template_names Refreshed list of templates
91
- */
92
- function aalb_find_template_change( $aalb_current_template_names, $aalb_template_names ) {
93
- $templates_added = array_diff( $aalb_template_names, $aalb_current_template_names );
94
- $templates_deleted = array_diff( $aalb_current_template_names, $aalb_template_names );
95
- if ( sizeof( $templates_added ) > 0 ) {
96
- aalb_info_notice( sizeof( $templates_added ) . " template(s) added: " . implode( ', ', $templates_added ) );
97
- }
98
- if ( sizeof( $templates_deleted ) > 0 ) {
99
- aalb_info_notice( sizeof( $templates_deleted ) . " template(s) deleted: " . implode( ', ', $templates_deleted ) );
100
- }
101
- }
102
-
103
- //Flag to check if the save is failed.
104
- $saveFailed = false;
105
- $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
106
-
107
- $aalb_current_template_names = get_option( AALB_TEMPLATE_NAMES );
108
-
109
- //Refresh templates
110
- $helper->refresh_template_list();
111
-
112
- $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
113
- aalb_find_template_change( $aalb_current_template_names, $aalb_template_names );
114
-
115
- if ( ! empty( $_POST["submit"] ) ) {
116
- $aalb_template_name = stripslashes( $_POST["aalb_template_name"] );
117
- $aalb_template_template_html_box = stripslashes( $_POST["aalb_template_template_html_box"] );
118
- $aalb_template_template_css_box = stripslashes( $_POST["aalb_template_template_css_box"] );
119
- $dir = AALB_TEMPLATE_DIR;
120
- $aalb_template_upload_dir = $helper->get_template_upload_directory();
121
- if ( $_POST["submit"] == "Save" ) {
122
- if ( $_POST["aalb_template_list"] == "new" ) {
123
- if ( empty( $aalb_template_name ) ) {
124
- aalb_error_notice( "Please define the template name for the new template" );
125
- } elseif ( ! ctype_alnum( str_replace( array( '-', '_' ), '', $aalb_template_name ) ) ) {
126
- //The template name can only be alphanumeric characters plus hyphens (-) and underscores (_)
127
- aalb_error_notice( "Save Failed. Only alphanumeric characters allowed for template name." );
128
- } else {
129
- if ( ! is_dir( $aalb_template_upload_dir ) or ! is_writable( $aalb_template_upload_dir ) ) {
130
- aalb_error_notice( $aalb_template_upload_dir . " doesn't exist or is not writable. Please set up Read-Write permissions for <ApacheHomeFolder>/wordpress/wp-content/uploads/amazon-associates-link-builder/template/" );
131
- } else {
132
- //Check if template of that name already exists
133
- if ( in_array( $aalb_template_name, $aalb_template_names ) ) {
134
- aalb_error_notice( "Save Failed. A template with the name \"" . $aalb_template_name . "\" already exists. Please specify some other name for the template" );
135
- //Ensures state is saved even on save failures
136
- $saveFailed = true;
137
- } else {
138
- try {
139
- aalb_save_template( $aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
140
- array_push( $aalb_template_names, $aalb_template_name );
141
- update_option( 'aalb_template_names', $aalb_template_names );
142
- } catch ( Exception $e ) {
143
- aalb_error_notice( $e->getMessage() );
144
- }
145
- }
146
- }
147
- }
148
- } else {
149
- try {
150
- if ( in_array( $aalb_template_name, $aalb_default_templates ) ) {
151
- aalb_save_template( $dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
152
- } else {
153
- aalb_save_template( $aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
154
- }
155
-
156
- //clears the cached rendered templates whenever the template is modified
157
- $helper->clear_cache_for_template( $aalb_template_name );
158
- } catch ( Exception $e ) {
159
- aalb_error_notice( $e->getMessage() );
160
- }
161
- }
162
- } elseif ( $_POST["submit"] == "Remove" ) {
163
- if ( $_POST["aalb_template_list"] == "new" ) {
164
- aalb_error_notice( "Cannot remove new template. Please select a valid template to remove." );
165
- } else {
166
- $aalb_template_names = array_diff( $aalb_template_names, array( $aalb_template_name ) );
167
- update_option( 'aalb_template_names', $aalb_template_names );
168
- if ( in_array( $aalb_template_name, $aalb_default_templates ) ) {
169
- //If Default Amazon Template is Removed
170
- aalb_error_notice( "Couldn't remove Default Template" );
171
- } else {
172
- if ( unlink( $aalb_template_upload_dir . $aalb_template_name . ".mustache" ) ) {
173
- aalb_success_notice( "Successfully removed Template HTML" );
174
- } else {
175
- aalb_error_notice( "Couldn't remove Template HTML. Please manually remove " . $dir . $aalb_template_name . ".mustache" );
176
- }
177
- if ( unlink( $aalb_template_upload_dir . $aalb_template_name . ".css" ) ) {
178
- aalb_success_notice( "Successfully removed Template CSS" );
179
- } else {
180
- aalb_error_notice( "Couldn't remove Template CSS. Please manually remove " . $dir . $aalb_template_name . ".css" );
181
- }
182
- }
183
-
184
- $aalb_template_name = "";
185
- $aalb_template_template_html_box = "";
186
- $aalb_template_template_css_box = "";
187
- }
188
- }
189
- }
190
-
191
- wp_enqueue_script( 'jquery' );
192
- wp_enqueue_script( 'codemirror_js', CODEMIRROR_JS );
193
- wp_enqueue_script( 'codemirror_mode_xml_js', CODEMIRROR_MODE_XML_JS );
194
- wp_enqueue_script( 'codemirror_mode_css_js', CODEMIRROR_MODE_CSS_JS );
195
- wp_enqueue_style( 'codemirror_css', CODEMIRROR_CSS );
196
-
197
- wp_enqueue_script( 'aalb_template_js', AALB_TEMPLATE_JS, array( 'jquery', 'codemirror_js', 'codemirror_mode_xml_js', 'codemirror_mode_css_js' ) );
198
- wp_localize_script( 'aalb_template_js', 'wp_opt', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'upload_url' => $helper->get_template_upload_directory(), 'plugin_url' => AALB_PLUGIN_URL, 'aalb_default_templates' => AALB_AMAZON_TEMPLATE_NAMES ) );
199
-
200
- ?>
201
- <div class="wrap">
202
- <h2>Templates for <?= AALB_PROJECT_TITLE ?></h2>
203
- <br>
204
- <form method="post">
205
- <table class="widefat fixed">
206
- <tr>
207
- <th scope="row" style="width:15%;">Select Template</th>
208
- <td>
209
- <select id="aalb_template_list_select" name="aalb_template_list" style="width:50%"
210
- onchange="aalb_template_select_template_onchange(this)">
211
- <option value="new">Create new template</option>
212
- <?php
213
- foreach ( $aalb_template_names as $aalb_template ) {
214
- ?>
215
- <option value="<?= $aalb_template ?>" <?php $saveFailed === false ? selected( $aalb_template, ( isset( $aalb_template_name ) ) ? $aalb_template_name : '' ) : selected( $aalb_template, "" ) ?>><?= $aalb_template ?></option>
216
- <?php
217
- }
218
- ?>
219
- </select>
220
- <input type="button" name="clone" id="clone_template" class="button button-secondary" value="Clone"
221
- onclick="clone_existing_template()" disabled>
222
- </td>
223
- </tr>
224
- <tr>
225
- <th scope="row" style="width:15%;">Set a name for your template</th>
226
- <td>
227
- <input type="text" id="aalb_template_name" name="aalb_template_name" style="width:50%"
228
- value="<?= ( isset( $aalb_template_name ) ) ? $aalb_template_name : '' ?>"/>
229
- <span style="font-size:0.9em;">[<a
230
- href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateCustomTemplates.pdf"
231
- target="_blank">Guide for creating custom templates</a>]</span>
232
- </td>
233
- </tr>
234
- <tr>
235
- <th scope="row" style="width:15%;">Add HTML for your template</th>
236
- <td><textarea id="aalb_template_template_html_box"
237
- name="aalb_template_template_html_box"><?= ( isset( $aalb_template_template_html_box ) ) ? $aalb_template_template_html_box : '' ?></textarea>
238
- </td>
239
- </tr>
240
- <tr>
241
- <th scope="row" style="width:15%;">Add CSS for your template</th>
242
- <td><textarea id="aalb_template_template_css_box"
243
- name="aalb_template_template_css_box"><?= ( isset( $aalb_template_template_css_box ) ) ? $aalb_template_template_css_box : '' ?></textarea>
244
- </td>
245
- </tr>
246
- </table>
247
- <p class="submit">
248
- <input name="submit" id="submit_save" class="button button-primary" value="Save" type="submit">
249
- <input name="submit" id="submit_remove" class="button button-secondary" value="Remove" type="submit" disabled>
250
- </p>
251
- </form>
252
- </div>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ include 'aalb_admin_ui_common.php';
16
+ $helper = new Aalb_Helper();
17
+ $helper->aalb_initialize_wp_filesystem_api();
18
+
19
+ /**
20
+ * Verifies whether file exists and is writable
21
+ *
22
+ * @since 1.0.0
23
+ *
24
+ * @param string $file Name of the file
25
+ *
26
+ * @return bool TRUE if file exists and is writable or if it's a new file which, throws exception otherwise
27
+ */
28
+ function aalb_verify_file_is_writable( $file ) {
29
+ if ( is_file( $file ) and ! is_writable( $file ) ) {
30
+ throw new Exception( "Save Failed. The existing file " . $file . " is not writable." );
31
+ }
32
+
33
+ return true;
34
+ }
35
+
36
+ /**
37
+ * Writes content to a file
38
+ *
39
+ * @since 1.0.0
40
+ *
41
+ * @param string $file Name of the file
42
+ * @param string $content Content to be written
43
+ *
44
+ * @return bool TRUE if write was successful, throws exception otherwise
45
+ */
46
+ function aalb_write_to_file( $file, $content ) {
47
+ global $wp_filesystem;
48
+ if ( $wp_filesystem->put_contents( $file, $content ) === false ) {
49
+ throw new Exception( "Save Failed. Error writing contents to file: " . $file );
50
+ }
51
+
52
+ return true;
53
+ }
54
+
55
+ /**
56
+ * Saves new or updates existing template.
57
+ * Writes template CSS and HTML into files.
58
+ *
59
+ * @since 1.0.0
60
+ *
61
+ * @param string $file Name of the file without .extension
62
+ * @param string $content_html HTML content to be saved
63
+ * @param string $content_css CSS content to be saved
64
+ */
65
+ function aalb_save_template( $file, $content_html, $content_css ) {
66
+ $file_mustache = $file . ".mustache";
67
+ $file_css = $file . ".css";
68
+ try {
69
+ if ( ( aalb_verify_file_is_writable( $file_css ) and aalb_verify_file_is_writable( $file_mustache ) ) ) {
70
+ //Both files are (existing and writable) or (a new file is specified)
71
+ if ( aalb_write_to_file( $file_mustache, $content_html ) and aalb_write_to_file( $file_css, $content_css ) ) {
72
+ //Both files were saved successfully
73
+ //Else case never occurs as an exception is thrown in false case
74
+ $saveFailed = false;
75
+ aalb_success_notice( "Template Saved Successfully" );
76
+ }
77
+ }
78
+ } catch ( Exception $e ) {
79
+ throw new Exception( $e->getMessage() );
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Finds any change in the current list of templates.
85
+ * Flags a note if either a template is added or removed.
86
+ *
87
+ * @since 1.3
88
+ *
89
+ * @param array $aalb_current_template_names Current list of templates
90
+ * @param array $aalb_template_names Refreshed list of templates
91
+ */
92
+ function aalb_find_template_change( $aalb_current_template_names, $aalb_template_names ) {
93
+ $templates_added = array_diff( $aalb_template_names, $aalb_current_template_names );
94
+ $templates_deleted = array_diff( $aalb_current_template_names, $aalb_template_names );
95
+ if ( sizeof( $templates_added ) > 0 ) {
96
+ aalb_info_notice( sizeof( $templates_added ) . " template(s) added: " . implode( ', ', $templates_added ) );
97
+ }
98
+ if ( sizeof( $templates_deleted ) > 0 ) {
99
+ aalb_info_notice( sizeof( $templates_deleted ) . " template(s) deleted: " . implode( ', ', $templates_deleted ) );
100
+ }
101
+ }
102
+
103
+ //Flag to check if the save is failed.
104
+ $saveFailed = false;
105
+ $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
106
+
107
+ $aalb_current_template_names = get_option( AALB_TEMPLATE_NAMES );
108
+
109
+ //Refresh templates
110
+ $helper->refresh_template_list();
111
+
112
+ $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
113
+ aalb_find_template_change( $aalb_current_template_names, $aalb_template_names );
114
+
115
+ if ( ! empty( $_POST["submit"] ) ) {
116
+ $aalb_template_name = stripslashes( $_POST["aalb_template_name"] );
117
+ $aalb_template_template_html_box = stripslashes( $_POST["aalb_template_template_html_box"] );
118
+ $aalb_template_template_css_box = stripslashes( $_POST["aalb_template_template_css_box"] );
119
+ $dir = AALB_TEMPLATE_DIR;
120
+ $aalb_template_upload_dir = $helper->get_template_upload_directory();
121
+ if ( $_POST["submit"] == "Save" ) {
122
+ if ( $_POST["aalb_template_list"] == "new" ) {
123
+ if ( empty( $aalb_template_name ) ) {
124
+ aalb_error_notice( "Please define the template name for the new template" );
125
+ } elseif ( ! ctype_alnum( str_replace( array( '-', '_' ), '', $aalb_template_name ) ) ) {
126
+ //The template name can only be alphanumeric characters plus hyphens (-) and underscores (_)
127
+ aalb_error_notice( "Save Failed. Only alphanumeric characters allowed for template name." );
128
+ } else {
129
+ if ( ! is_dir( $aalb_template_upload_dir ) or ! is_writable( $aalb_template_upload_dir ) ) {
130
+ aalb_error_notice( $aalb_template_upload_dir . " doesn't exist or is not writable. Please set up Read-Write permissions for <ApacheHomeFolder>/wordpress/wp-content/uploads/amazon-associates-link-builder/template/" );
131
+ } else {
132
+ //Check if template of that name already exists
133
+ if ( in_array( $aalb_template_name, $aalb_template_names ) ) {
134
+ aalb_error_notice( "Save Failed. A template with the name \"" . $aalb_template_name . "\" already exists. Please specify some other name for the template" );
135
+ //Ensures state is saved even on save failures
136
+ $saveFailed = true;
137
+ } else {
138
+ try {
139
+ aalb_save_template( $aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
140
+ array_push( $aalb_template_names, $aalb_template_name );
141
+ update_option( 'aalb_template_names', $aalb_template_names );
142
+ } catch ( Exception $e ) {
143
+ aalb_error_notice( $e->getMessage() );
144
+ }
145
+ }
146
+ }
147
+ }
148
+ } else {
149
+ try {
150
+ if ( in_array( $aalb_template_name, $aalb_default_templates ) ) {
151
+ aalb_save_template( $dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
152
+ } else {
153
+ aalb_save_template( $aalb_template_upload_dir . $aalb_template_name, $aalb_template_template_html_box, $aalb_template_template_css_box );
154
+ }
155
+
156
+ //clears the cached rendered templates whenever the template is modified
157
+ $helper->clear_cache_for_template( $aalb_template_name );
158
+ } catch ( Exception $e ) {
159
+ aalb_error_notice( $e->getMessage() );
160
+ }
161
+ }
162
+ } elseif ( $_POST["submit"] == "Remove" ) {
163
+ if ( $_POST["aalb_template_list"] == "new" ) {
164
+ aalb_error_notice( "Cannot remove new template. Please select a valid template to remove." );
165
+ } else {
166
+ $aalb_template_names = array_diff( $aalb_template_names, array( $aalb_template_name ) );
167
+ update_option( 'aalb_template_names', $aalb_template_names );
168
+ if ( in_array( $aalb_template_name, $aalb_default_templates ) ) {
169
+ //If Default Amazon Template is Removed
170
+ aalb_error_notice( "Couldn't remove Default Template" );
171
+ } else {
172
+ if ( unlink( $aalb_template_upload_dir . $aalb_template_name . ".mustache" ) ) {
173
+ aalb_success_notice( "Successfully removed Template HTML" );
174
+ } else {
175
+ aalb_error_notice( "Couldn't remove Template HTML. Please manually remove " . $dir . $aalb_template_name . ".mustache" );
176
+ }
177
+ if ( unlink( $aalb_template_upload_dir . $aalb_template_name . ".css" ) ) {
178
+ aalb_success_notice( "Successfully removed Template CSS" );
179
+ } else {
180
+ aalb_error_notice( "Couldn't remove Template CSS. Please manually remove " . $dir . $aalb_template_name . ".css" );
181
+ }
182
+ }
183
+
184
+ $aalb_template_name = "";
185
+ $aalb_template_template_html_box = "";
186
+ $aalb_template_template_css_box = "";
187
+ }
188
+ }
189
+ }
190
+
191
+ wp_enqueue_script( 'jquery' );
192
+ wp_enqueue_script( 'codemirror_js', CODEMIRROR_JS );
193
+ wp_enqueue_script( 'codemirror_mode_xml_js', CODEMIRROR_MODE_XML_JS );
194
+ wp_enqueue_script( 'codemirror_mode_css_js', CODEMIRROR_MODE_CSS_JS );
195
+ wp_enqueue_style( 'codemirror_css', CODEMIRROR_CSS );
196
+
197
+ wp_enqueue_script( 'aalb_template_js', AALB_TEMPLATE_JS, array( 'jquery', 'codemirror_js', 'codemirror_mode_xml_js', 'codemirror_mode_css_js' ) );
198
+ wp_localize_script( 'aalb_template_js', 'wp_opt', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'upload_url' => $helper->get_template_upload_directory(), 'plugin_url' => AALB_PLUGIN_URL, 'aalb_default_templates' => AALB_AMAZON_TEMPLATE_NAMES ) );
199
+
200
+ ?>
201
+ <div class="wrap">
202
+ <h2>Templates for <?= AALB_PROJECT_TITLE ?></h2>
203
+ <br>
204
+ <form method="post">
205
+ <table class="widefat fixed">
206
+ <tr>
207
+ <th scope="row" style="width:15%;">Select Template</th>
208
+ <td>
209
+ <select id="aalb_template_list_select" name="aalb_template_list" style="width:50%"
210
+ onchange="aalb_template_select_template_onchange(this)">
211
+ <option value="new">Create new template</option>
212
+ <?php
213
+ foreach ( $aalb_template_names as $aalb_template ) {
214
+ ?>
215
+ <option value="<?= $aalb_template ?>" <?php $saveFailed === false ? selected( $aalb_template, ( isset( $aalb_template_name ) ) ? $aalb_template_name : '' ) : selected( $aalb_template, "" ) ?>><?= $aalb_template ?></option>
216
+ <?php
217
+ }
218
+ ?>
219
+ </select>
220
+ <input type="button" name="clone" id="clone_template" class="button button-secondary" value="Clone"
221
+ onclick="clone_existing_template()" disabled>
222
+ </td>
223
+ </tr>
224
+ <tr>
225
+ <th scope="row" style="width:15%;">Set a name for your template</th>
226
+ <td>
227
+ <input type="text" id="aalb_template_name" name="aalb_template_name" style="width:50%"
228
+ value="<?= ( isset( $aalb_template_name ) ) ? $aalb_template_name : '' ?>"/>
229
+ <span style="font-size:0.9em;">[<a
230
+ href="https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateCustomTemplates.pdf"
231
+ target="_blank">Guide for creating custom templates</a>]</span>
232
+ </td>
233
+ </tr>
234
+ <tr>
235
+ <th scope="row" style="width:15%;">Add HTML for your template</th>
236
+ <td><textarea id="aalb_template_template_html_box"
237
+ name="aalb_template_template_html_box"><?= ( isset( $aalb_template_template_html_box ) ) ? $aalb_template_template_html_box : '' ?></textarea>
238
+ </td>
239
+ </tr>
240
+ <tr>
241
+ <th scope="row" style="width:15%;">Add CSS for your template</th>
242
+ <td><textarea id="aalb_template_template_css_box"
243
+ name="aalb_template_template_css_box"><?= ( isset( $aalb_template_template_css_box ) ) ? $aalb_template_template_css_box : '' ?></textarea>
244
+ </td>
245
+ </tr>
246
+ </table>
247
+ <p class="submit">
248
+ <input name="submit" id="submit_save" class="button button-primary" value="Save" type="submit">
249
+ <input name="submit" id="submit_remove" class="button button-secondary" value="Remove" type="submit" disabled>
250
+ </p>
251
+ </form>
252
+ </div>
admin/sidebar/partials/aalb_ui_common.php CHANGED
@@ -1,33 +1,33 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- //some commonly used UI functionality
16
-
17
- function aalb_info_notice( $message ) {
18
- echo "<div class=\"notice notice-info is-dismissible\"><p>INFO - " . $message . "</p></div>";
19
- }
20
-
21
- function aalb_warning_notice( $message ) {
22
- echo "<div class=\"notice notice-warning\"><p>WARNING - " . $message . "</p></div>";
23
- }
24
-
25
- function aalb_error_notice( $message ) {
26
- echo "<div class=\"notice notice-error\"><p>ERROR - " . $message . "</p></div>";
27
- }
28
-
29
- function aalb_success_notice( $message ) {
30
- echo "<div class=\"notice notice-success is-dismissible\"><p>SUCCESS - " . $message . "</p></div>";
31
- }
32
-
33
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ //some commonly used UI functionality
16
+
17
+ function aalb_info_notice( $message ) {
18
+ echo "<div class=\"notice notice-info is-dismissible\"><p>INFO - " . $message . "</p></div>";
19
+ }
20
+
21
+ function aalb_warning_notice( $message ) {
22
+ echo "<div class=\"notice notice-warning\"><p>WARNING - " . $message . "</p></div>";
23
+ }
24
+
25
+ function aalb_error_notice( $message ) {
26
+ echo "<div class=\"notice notice-error\"><p>ERROR - " . $message . "</p></div>";
27
+ }
28
+
29
+ function aalb_success_notice( $message ) {
30
+ echo "<div class=\"notice notice-success is-dismissible\"><p>SUCCESS - " . $message . "</p></div>";
31
+ }
32
+
33
+ ?>
amazon-associates-link-builder.php CHANGED
@@ -1,114 +1,101 @@
1
- <?php
2
- /**
3
- * @package AmazonAssociatesLinkBuilder
4
- *
5
- */
6
-
7
- /*
8
- Plugin Name: Amazon Associates Link Builder
9
- Description: Amazon Associates Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to search for products in the Amazon catalog, access real-time price and availability information, and easily create links in your posts to products on Amazon.com. You will be able to generate text links, create custom ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
10
- Version: 1.4.2
11
- Author: Amazon Associates Program
12
- Author URI: https://affiliate-program.amazon.com/
13
- License: GPLv2
14
- */
15
-
16
- /*
17
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
18
-
19
- Licensed under the GNU General Public License as published by the Free Software Foundation,
20
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
21
- A copy of the License is located in the "license" file accompanying this file.
22
-
23
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
24
- either express or implied. See the License for the specific language governing permissions
25
- and limitations under the License.
26
- */
27
-
28
- if ( ! defined( 'WPINC' ) ) {
29
- die;
30
- }
31
-
32
- require_once( plugin_dir_path( __FILE__ ) . 'aalb_config.php' );
33
-
34
- add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'add_action_links' );
35
- function add_action_links( $links ) {
36
- $mylinks = array(
37
- '<a href="' . admin_url( 'admin.php?page=associates-link-builder-about' ) . '">About</a>',
38
- '<a href="' . admin_url( 'admin.php?page=associates-link-builder-settings' ) . '">Settings</a>',
39
- '<a href="' . admin_url( 'admin.php?page=associates-link-builder-templates' ) . '">Templates</a>',
40
- );
41
-
42
- return array_merge( $links, $mylinks );
43
- }
44
-
45
- /**
46
- * Autoload the files required for the plugin.
47
- *
48
- * @since 1.0.0
49
- */
50
- function aalb_autoload() {
51
- //Load the autoloader for mustache.
52
- require_once( MUSTACHE_AUTOLOADER_PHP );
53
- Mustache_Autoloader::register();
54
-
55
- //Load the autoloader for plugin files.
56
- require_once( AALB_AUTOLOADER );
57
- Aalb_Autoloader::register();
58
- }
59
-
60
- aalb_autoload();
61
-
62
- /**
63
- * The code to run on activation
64
- *
65
- * @since 1.0.0
66
- */
67
- function aalb_activate() {
68
- $aalb_activator = new Aalb_Activator();
69
- $aalb_activator->check_php_version_compatibility();
70
- $aalb_activator->load_templates();
71
- $aalb_activator->load_db_keys();
72
- $aalb_activator->load_store_ids();
73
- }
74
-
75
- register_activation_hook( __FILE__, 'aalb_activate' );
76
-
77
- /**
78
- * The code to run on deactivation
79
- *
80
- * @since 1.0.0
81
- */
82
- function aalb_deactivate() {
83
- $aalb_deactivator = new Aalb_Deactivator();
84
- $aalb_deactivator->remove_cache();
85
- }
86
-
87
- register_deactivation_hook( __FILE__, 'aalb_deactivate' );
88
-
89
- /**
90
- * The code to run on uninstalltion
91
- *
92
- * @since 1.0.0
93
- */
94
- function aalb_uninstall() {
95
- $aalb_deactivator = new Aalb_Deactivator();
96
- $aalb_deactivator->remove_settings();
97
- $aalb_deactivator->remove_uploads_dir();
98
- }
99
-
100
- register_uninstall_hook( __FILE__, 'aalb_uninstall' );
101
-
102
- /**
103
- * Execute the plugin
104
- *
105
- * @since 1.0.0
106
- */
107
- function aalb_execute() {
108
- $aalb_manager = new Aalb_Manager();
109
- $aalb_manager->execute();
110
- }
111
-
112
- aalb_execute();
113
-
114
- ?>
1
+ <?php
2
+ /**
3
+ * @package AmazonAssociatesLinkBuilder
4
+ *
5
+ */
6
+
7
+ /*
8
+ Plugin Name: Amazon Associates Link Builder
9
+ Description: Amazon Associates Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to search for products in the Amazon catalog, access real-time price and availability information, and easily create links in your posts to products on Amazon.com. You will be able to generate text links, create custom ad units, or take advantage of out-of-the-box widgets that we’ve designed and included with the plugin.
10
+ Version: 1.4.3
11
+ Author: Amazon Associates Program
12
+ Author URI: https://affiliate-program.amazon.com/
13
+ License: GPLv2
14
+ */
15
+
16
+ /*
17
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
18
+
19
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
20
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
21
+ A copy of the License is located in the "license" file accompanying this file.
22
+
23
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
24
+ either express or implied. See the License for the specific language governing permissions
25
+ and limitations under the License.
26
+ */
27
+
28
+ if ( ! defined( 'WPINC' ) ) {
29
+ die;
30
+ }
31
+
32
+ require_once( plugin_dir_path( __FILE__ ) . 'aalb_config.php' );
33
+
34
+ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'add_action_links' );
35
+ function add_action_links( $links ) {
36
+ $mylinks = array(
37
+ '<a href="' . admin_url( 'admin.php?page=associates-link-builder-about' ) . '">About</a>',
38
+ '<a href="' . admin_url( 'admin.php?page=associates-link-builder-settings' ) . '">Settings</a>',
39
+ '<a href="' . admin_url( 'admin.php?page=associates-link-builder-templates' ) . '">Templates</a>',
40
+ );
41
+
42
+ return array_merge( $links, $mylinks );
43
+ }
44
+
45
+ /**
46
+ * Autoload the files required for the plugin.
47
+ *
48
+ * @since 1.0.0
49
+ */
50
+ function aalb_autoload() {
51
+ //Load the autoloader for mustache.
52
+ require_once( MUSTACHE_AUTOLOADER_PHP );
53
+ Mustache_Autoloader::register();
54
+
55
+ //Load the autoloader for plugin files.
56
+ require_once( AALB_AUTOLOADER );
57
+ Aalb_Autoloader::register();
58
+ }
59
+
60
+ aalb_autoload();
61
+
62
+ register_activation_hook( __FILE__, array( new Aalb_Activator(), 'activate' ) );
63
+
64
+ /**
65
+ * The code to run on deactivation
66
+ *
67
+ * @since 1.0.0
68
+ */
69
+ function aalb_deactivate() {
70
+ $aalb_deactivator = new Aalb_Deactivator();
71
+ $aalb_deactivator->remove_cache();
72
+ }
73
+
74
+ register_deactivation_hook( __FILE__, 'aalb_deactivate' );
75
+
76
+ /**
77
+ * The code to run on uninstalltion
78
+ *
79
+ * @since 1.0.0
80
+ */
81
+ function aalb_uninstall() {
82
+ $aalb_deactivator = new Aalb_Deactivator();
83
+ $aalb_deactivator->remove_settings();
84
+ $aalb_deactivator->remove_uploads_dir();
85
+ }
86
+
87
+ register_uninstall_hook( __FILE__, 'aalb_uninstall' );
88
+
89
+ /**
90
+ * Execute the plugin
91
+ *
92
+ * @since 1.0.0
93
+ */
94
+ function aalb_execute() {
95
+ $aalb_manager = new Aalb_Manager();
96
+ $aalb_manager->execute();
97
+ }
98
+
99
+ aalb_execute();
100
+
101
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
bin/install-wp-tests.sh CHANGED
@@ -1,118 +1,118 @@
1
- #!/usr/bin/env bash
2
-
3
- if [ $# -lt 3 ]; then
4
- echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version]"
5
- exit 1
6
- fi
7
-
8
- DB_NAME=$1
9
- DB_USER=$2
10
- DB_PASS=$3
11
- DB_HOST=${4-localhost}
12
- WP_VERSION=${5-latest}
13
-
14
- WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
15
- WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
16
-
17
- download() {
18
- if [ `which curl` ]; then
19
- curl -s "$1" > "$2";
20
- elif [ `which wget` ]; then
21
- wget -nv -O "$2" "$1"
22
- fi
23
- }
24
-
25
- if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
26
- WP_TESTS_TAG="tags/$WP_VERSION"
27
- elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
28
- WP_TESTS_TAG="trunk"
29
- else
30
- # http serves a single offer, whereas https serves multiple. we only want one
31
- download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
32
- grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
33
- LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
34
- if [[ -z "$LATEST_VERSION" ]]; then
35
- echo "Latest WordPress version could not be found"
36
- exit 1
37
- fi
38
- WP_TESTS_TAG="tags/$LATEST_VERSION"
39
- fi
40
-
41
- set -ex
42
-
43
- install_wp() {
44
-
45
- if [ -d $WP_CORE_DIR ]; then
46
- return;
47
- fi
48
-
49
- mkdir -p $WP_CORE_DIR
50
-
51
- if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
52
- mkdir -p /tmp/wordpress-nightly
53
- download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
54
- unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
55
- mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
56
- else
57
- if [ $WP_VERSION == 'latest' ]; then
58
- local ARCHIVE_NAME='latest'
59
- else
60
- local ARCHIVE_NAME="wordpress-$WP_VERSION"
61
- fi
62
- download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
63
- tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
64
- fi
65
-
66
- download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
67
- }
68
-
69
- install_test_suite() {
70
- # portable in-place argument for both GNU sed and Mac OSX sed
71
- if [[ $(uname -s) == 'Darwin' ]]; then
72
- local ioption='-i .bak'
73
- else
74
- local ioption='-i'
75
- fi
76
-
77
- # set up testing suite if it doesn't yet exist
78
- if [ ! -d $WP_TESTS_DIR ]; then
79
- # set up testing suite
80
- mkdir -p $WP_TESTS_DIR
81
- svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
82
- fi
83
-
84
- if [ ! -f wp-tests-config.php ]; then
85
- download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
86
- sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php
87
- sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
88
- sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
89
- sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
90
- sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
91
- fi
92
-
93
- }
94
-
95
- install_db() {
96
- # parse DB_HOST for port or socket references
97
- local PARTS=(${DB_HOST//\:/ })
98
- local DB_HOSTNAME=${PARTS[0]};
99
- local DB_SOCK_OR_PORT=${PARTS[1]};
100
- local EXTRA=""
101
-
102
- if ! [ -z $DB_HOSTNAME ] ; then
103
- if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
104
- EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
105
- elif ! [ -z $DB_SOCK_OR_PORT ] ; then
106
- EXTRA=" --socket=$DB_SOCK_OR_PORT"
107
- elif ! [ -z $DB_HOSTNAME ] ; then
108
- EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
109
- fi
110
- fi
111
-
112
- # create database
113
- mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
114
- }
115
-
116
- install_wp
117
- install_test_suite
118
- install_db
1
+ #!/usr/bin/env bash
2
+
3
+ if [ $# -lt 3 ]; then
4
+ echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version]"
5
+ exit 1
6
+ fi
7
+
8
+ DB_NAME=$1
9
+ DB_USER=$2
10
+ DB_PASS=$3
11
+ DB_HOST=${4-localhost}
12
+ WP_VERSION=${5-latest}
13
+
14
+ WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
15
+ WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
16
+
17
+ download() {
18
+ if [ `which curl` ]; then
19
+ curl -s "$1" > "$2";
20
+ elif [ `which wget` ]; then
21
+ wget -nv -O "$2" "$1"
22
+ fi
23
+ }
24
+
25
+ if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
26
+ WP_TESTS_TAG="tags/$WP_VERSION"
27
+ elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
28
+ WP_TESTS_TAG="trunk"
29
+ else
30
+ # http serves a single offer, whereas https serves multiple. we only want one
31
+ download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
32
+ grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
33
+ LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
34
+ if [[ -z "$LATEST_VERSION" ]]; then
35
+ echo "Latest WordPress version could not be found"
36
+ exit 1
37
+ fi
38
+ WP_TESTS_TAG="tags/$LATEST_VERSION"
39
+ fi
40
+
41
+ set -ex
42
+
43
+ install_wp() {
44
+
45
+ if [ -d $WP_CORE_DIR ]; then
46
+ return;
47
+ fi
48
+
49
+ mkdir -p $WP_CORE_DIR
50
+
51
+ if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
52
+ mkdir -p /tmp/wordpress-nightly
53
+ download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
54
+ unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
55
+ mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
56
+ else
57
+ if [ $WP_VERSION == 'latest' ]; then
58
+ local ARCHIVE_NAME='latest'
59
+ else
60
+ local ARCHIVE_NAME="wordpress-$WP_VERSION"
61
+ fi
62
+ download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
63
+ tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
64
+ fi
65
+
66
+ download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
67
+ }
68
+
69
+ install_test_suite() {
70
+ # portable in-place argument for both GNU sed and Mac OSX sed
71
+ if [[ $(uname -s) == 'Darwin' ]]; then
72
+ local ioption='-i .bak'
73
+ else
74
+ local ioption='-i'
75
+ fi
76
+
77
+ # set up testing suite if it doesn't yet exist
78
+ if [ ! -d $WP_TESTS_DIR ]; then
79
+ # set up testing suite
80
+ mkdir -p $WP_TESTS_DIR
81
+ svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
82
+ fi
83
+
84
+ if [ ! -f wp-tests-config.php ]; then
85
+ download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
86
+ sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php
87
+ sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
88
+ sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
89
+ sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
90
+ sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
91
+ fi
92
+
93
+ }
94
+
95
+ install_db() {
96
+ # parse DB_HOST for port or socket references
97
+ local PARTS=(${DB_HOST//\:/ })
98
+ local DB_HOSTNAME=${PARTS[0]};
99
+ local DB_SOCK_OR_PORT=${PARTS[1]};
100
+ local EXTRA=""
101
+
102
+ if ! [ -z $DB_HOSTNAME ] ; then
103
+ if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
104
+ EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
105
+ elif ! [ -z $DB_SOCK_OR_PORT ] ; then
106
+ EXTRA=" --socket=$DB_SOCK_OR_PORT"
107
+ elif ! [ -z $DB_HOSTNAME ] ; then
108
+ EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
109
+ fi
110
+ fi
111
+
112
+ # create database
113
+ mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
114
+ }
115
+
116
+ install_wp
117
+ install_test_suite
118
+ install_db
css/aalb_basics.css CHANGED
@@ -1,83 +1,83 @@
1
- /*
2
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
-
4
- Licensed under the GNU General Public License as published by the Free Software Foundation,
5
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
- A copy of the License is located in the "license" file accompanying this file.
7
-
8
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
- either express or implied. See the License for the specific language governing permissions
10
- and limitations under the License.
11
- */
12
-
13
- .aalb-btn {
14
- padding: 6px 12px;
15
- padding-top: 6px;
16
- padding-right: 12px;
17
- padding-bottom: 6px;
18
- padding-left: 12px;
19
- margin-bottom: 0px;
20
- font-size: 14px;
21
- font-weight: normal;
22
- line-height: 1.42857;
23
- text-align: center;
24
- white-space: nowrap;
25
- vertical-align: middle;
26
- cursor: pointer;
27
- -moz-user-select: none;
28
- background-image: none;
29
- border: 1px solid transparent;
30
- border-top-width: 1px;
31
- border-right-width: 1px;
32
- border-bottom-width: 1px;
33
- border-left-width: 1px;
34
- border-top-style: solid;
35
- border-right-style: solid;
36
- border-bottom-style: solid;
37
- border-left-style: solid;
38
- border-top-color: transparent;
39
- border-right-color: transparent;
40
- border-bottom-color: transparent;
41
- border-left-color: transparent;
42
- -moz-border-top-color: none;
43
- -moz-border-right-color: none;
44
- -moz-border-bottom-color: none;
45
- -moz-border-left-color: none;
46
- border-image-source: none;
47
- border-image-slice: 100% 100% 100% 100%;
48
- border-image-width: 1 1 1 1;
49
- border-image-outset: 0 0 0 0;
50
- border-image-repeat: stretch stretch;
51
- border-radius: 4px;
52
- border-top-left-radius: 4px;
53
- border-top-right-radius: 4px;
54
- border-bottom-right-radius: 4px;
55
- border-bottom-left-radius: 4px;
56
- }
57
-
58
- .aalb-btn-primary {
59
- box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
60
- background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
61
- background-color: transparent;
62
- background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
63
- background-repeat: repeat;
64
- background-attachment: scroll;
65
- background-position: 0% 0%;
66
- background-clip: border-box;
67
- background-origin: padding-box;
68
- background-size: auto auto;
69
- border-color: #A88734 #9C7E31 #846A29;
70
- border-top-color: #A88734;
71
- border-right-color: #9C7E31;
72
- border-bottom-color: #846A29;
73
- border-left-color: #9C7E31;
74
- color: #111;
75
- }
76
-
77
- .pull-right {
78
- float: right;
79
- }
80
-
81
- .pull-left {
82
- float: left;
83
- }
1
+ /*
2
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+
4
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
5
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
6
+ A copy of the License is located in the "license" file accompanying this file.
7
+
8
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied. See the License for the specific language governing permissions
10
+ and limitations under the License.
11
+ */
12
+
13
+ .aalb-btn {
14
+ padding: 6px 12px;
15
+ padding-top: 6px;
16
+ padding-right: 12px;
17
+ padding-bottom: 6px;
18
+ padding-left: 12px;
19
+ margin-bottom: 0px;
20
+ font-size: 14px;
21
+ font-weight: normal;
22
+ line-height: 1.42857;
23
+ text-align: center;
24
+ white-space: nowrap;
25
+ vertical-align: middle;
26
+ cursor: pointer;
27
+ -moz-user-select: none;
28
+ background-image: none;
29
+ border: 1px solid transparent;
30
+ border-top-width: 1px;
31
+ border-right-width: 1px;
32
+ border-bottom-width: 1px;
33
+ border-left-width: 1px;
34
+ border-top-style: solid;
35
+ border-right-style: solid;
36
+ border-bottom-style: solid;
37
+ border-left-style: solid;
38
+ border-top-color: transparent;
39
+ border-right-color: transparent;
40
+ border-bottom-color: transparent;
41
+ border-left-color: transparent;
42
+ -moz-border-top-color: none;
43
+ -moz-border-right-color: none;
44
+ -moz-border-bottom-color: none;
45
+ -moz-border-left-color: none;
46
+ border-image-source: none;
47
+ border-image-slice: 100% 100% 100% 100%;
48
+ border-image-width: 1 1 1 1;
49
+ border-image-outset: 0 0 0 0;
50
+ border-image-repeat: stretch stretch;
51
+ border-radius: 4px;
52
+ border-top-left-radius: 4px;
53
+ border-top-right-radius: 4px;
54
+ border-bottom-right-radius: 4px;
55
+ border-bottom-left-radius: 4px;
56
+ }
57
+
58
+ .aalb-btn-primary {
59
+ box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.4) inset;
60
+ background: transparent linear-gradient(to bottom, #F7DFA5, #F0C14B) repeat scroll 0% 0%;
61
+ background-color: transparent;
62
+ background-image: linear-gradient(to bottom, #F7DFA5, #F0C14B);
63
+ background-repeat: repeat;
64
+ background-attachment: scroll;
65
+ background-position: 0% 0%;
66
+ background-clip: border-box;
67
+ background-origin: padding-box;
68
+ background-size: auto auto;
69
+ border-color: #A88734 #9C7E31 #846A29;
70
+ border-top-color: #A88734;
71
+ border-right-color: #9C7E31;
72
+ border-bottom-color: #846A29;
73
+ border-left-color: #9C7E31;
74
+ color: #111;
75
+ }
76
+
77
+ .pull-right {
78
+ float: right;
79
+ }
80
+
81
+ .pull-left {
82
+ float: left;
83
+ }
includes/aalb_activator.php CHANGED
@@ -1,82 +1,94 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Fired during the plugin activation
17
- *
18
- * Gets the template names from the template directory and loads it into the database.
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/includes
23
- */
24
- class Aalb_Activator {
25
-
26
- protected $helper;
27
-
28
- public function __construct() {
29
- $this->helper = new Aalb_Helper();
30
- }
31
-
32
- /**
33
- * Add the template names to the database from the filesystem.
34
- *
35
- * @since 1.0.0
36
- */
37
- public function load_templates() {
38
- $this->helper->refresh_template_list();
39
- }
40
-
41
- /**
42
- * Add the aws key options into the database on activation.
43
- * This solves the problem of encryption as wordpress called an update option before calling
44
- * add option while sanitizing.
45
- * https://codex.wordpress.org/Function_Reference/register_setting
46
- *
47
- * @since 1.0.0
48
- */
49
- public function load_db_keys() {
50
- if ( ! get_option( AALB_AWS_ACCESS_KEY ) ) {
51
- update_option( AALB_AWS_ACCESS_KEY, '' );
52
- }
53
- if ( ! get_option( AALB_AWS_SECRET_KEY ) ) {
54
- update_option( AALB_AWS_SECRET_KEY, '' );
55
- }
56
- }
57
-
58
- /**
59
- * Init store ids key and add todatabase.
60
- *
61
- * @since 1.0.0
62
- */
63
- public function load_store_ids() {
64
- update_option( AALB_STORE_IDS, '' );
65
- }
66
-
67
- /**
68
- * Checks current PHP version of user and exits with error message
69
- * in case user's phpVersion is less than AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION
70
- *
71
- * @since 1.4.2
72
- */
73
- public function check_php_version_compatibility() {
74
- $phpversion = phpversion();
75
- if(version_compare($phpversion, AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION) < 0) {
76
- exit(sprintf('<span style="color:red;">%s plugin requires %s or higher. You’re still on %s.</span>', AALB_PLUGIN_NAME, AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION, $phpversion));
77
- }
78
- }
79
-
80
- }
81
-
82
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Fired during the plugin activation
17
+ *
18
+ * Gets the template names from the template directory and loads it into the database.
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/includes
23
+ */
24
+ class Aalb_Activator {
25
+
26
+ protected $helper;
27
+ private $aalb_compatibility_helper;
28
+
29
+ public function __construct() {
30
+ $this->helper = new Aalb_Helper();
31
+ $this->aalb_compatibility_helper = new Aalb_Compatibility_Helper();
32
+ }
33
+
34
+ /**
35
+ * Add the template names to the database from the filesystem.
36
+ *
37
+ * @since 1.0.0
38
+ */
39
+ private function load_templates() {
40
+ $this->helper->refresh_template_list();
41
+ }
42
+
43
+ /**
44
+ * Add the aws key options into the database on activation.
45
+ * This solves the problem of encryption as wordpress called an update option before calling
46
+ * add option while sanitizing.
47
+ * https://codex.wordpress.org/Function_Reference/register_setting
48
+ *
49
+ * @since 1.0.0
50
+ */
51
+ private function load_db_keys() {
52
+ if ( ! get_option( AALB_AWS_ACCESS_KEY ) ) {
53
+ update_option( AALB_AWS_ACCESS_KEY, '' );
54
+ }
55
+ if ( ! get_option( AALB_AWS_SECRET_KEY ) ) {
56
+ update_option( AALB_AWS_SECRET_KEY, '' );
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Init store ids key and add todatabase.
62
+ *
63
+ * @since 1.0.0
64
+ */
65
+ private function load_store_ids() {
66
+ update_option( AALB_STORE_IDS, '' );
67
+ }
68
+
69
+ /**
70
+ * Halts activation process if the plugin is not compatible with the user environment
71
+ *
72
+ * @since 1.4.3
73
+ */
74
+ private function halt_activation() {
75
+ exit(sprintf('<span style="color:red;">%s plugin requires PHP Version %s or higher. You’re still on %s.</span>', AALB_PLUGIN_NAME, AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION, phpversion()));
76
+ }
77
+
78
+ /**
79
+ * The code to run on activation
80
+ *
81
+ * @since 1.4.3
82
+ */
83
+ function activate() {
84
+ if($this->aalb_compatibility_helper->is_plugin_compatible()) {
85
+ $this->load_templates();
86
+ $this->load_db_keys();
87
+ $this->load_store_ids();
88
+ } else {
89
+ $this->halt_activation();
90
+ }
91
+ }
92
+ }
93
+
94
+ ?>
includes/aalb_admin_notice_manager.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Manager class for Admin notice action
17
+ * Uses singleton pattern to maintain single copy of function_list all over
18
+ *
19
+ * @since 1.4.3
20
+ * @package AmazonAssociatesLinkBuilder
21
+ * @subpackage AmazonAssociatesLinkBuilder/includes
22
+ */
23
+ class Aalb_Admin_Notice_Manager {
24
+ private static $instance = null;
25
+
26
+ private function __construct() {
27
+ }
28
+
29
+ private function __clone() {
30
+ }
31
+
32
+ public static function getInstance() {
33
+ if ( self::$instance == null ) {
34
+ self::$instance = new Aalb_Admin_Notice_Manager();
35
+ }
36
+
37
+ return self::$instance;
38
+ }
39
+
40
+ //Array to hold all admin notice action hooks in the plugin
41
+ private $functions_list = array();
42
+
43
+ /**
44
+ * Add action for admin notice and also make an entry in function_list
45
+ *
46
+ * @since 1.4.3
47
+ *
48
+ * @param string $obj Reference of the object
49
+ * @param callable $callback_function The name of the function you wish to be called.
50
+ * @param int $priority Optional. Used to specify the order in which the functions
51
+ * associated with a particular action are executed. Default 10.
52
+ * Lower numbers correspond with earlier execution,
53
+ * and functions with the same priority are executed
54
+ * in the order in which they were added to the action.
55
+ * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1.
56
+ *
57
+ */
58
+ public function add_notice( $obj, $callback_function, $priority = 10, $accepted_args = 1 ) {
59
+ $function_to_add = array( $obj, $callback_function );
60
+ add_action( 'admin_notices', $function_to_add, $priority, $accepted_args );
61
+ $key = get_class( $obj ) . "::" . $callback_function;
62
+ //Overrides the value of key if already present to prevent multiple entries in case object is instantiated again
63
+ $this->functions_list[$key] = array(
64
+ "function_to_add" => $function_to_add,
65
+ "priority" => $priority,
66
+ "accepted_args" => $accepted_args
67
+ );
68
+ }
69
+
70
+ /**
71
+ * Remove all functions for admin notice action that are added by plugin and
72
+ * also remove entry from the function_list
73
+ *
74
+ * @since 1.4.3
75
+ */
76
+ public function remove_all_notices() {
77
+ foreach ( $this->functions_list as $key => $value ) {
78
+ remove_action( 'admin_notices', $value["function_to_add"], $value["priority"],
79
+ $value["accepted_args"] );
80
+ unset( $this->functions_list[$key] );
81
+ }
82
+ }
83
+ }
84
+
85
+ ?>
includes/aalb_autoloader.php CHANGED
@@ -1,72 +1,72 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * The class reponsible for auto-loading files.
17
- *
18
- * Loads the class with respect to their respective directories.
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/includes
23
- */
24
- class Aalb_Autoloader {
25
-
26
- private $dir;
27
-
28
- /**
29
- * Register the autoloader for a directory in the plugin.
30
- *
31
- * @since 1.0.0
32
- *
33
- * @param string $dir Path of the directory.
34
- */
35
- public function __construct( $dir = '' ) {
36
- if ( ! empty( $dir ) ) {
37
- $this->dir = $dir;
38
- }
39
-
40
- spl_autoload_register( array( $this, 'autoload' ) );
41
- }
42
-
43
- /**
44
- * Make instances of the autoloaders for each directory in the plugin.
45
- *
46
- * @since 1.0.0
47
- */
48
- public static function register() {
49
- new self( AALB_INCLUDES_DIR );
50
- new self( AALB_ADMIN_DIR );
51
- new self( AALB_SIDEBAR_DIR );
52
- new self( AALB_PAAPI_DIR );
53
- new self( AALB_SHORTCODE_DIR );
54
- new self( AALB_LIBRARY_DIR );
55
- }
56
-
57
- /**
58
- * Callback function of spl_autoload_register to autoload the class.
59
- *
60
- * @since 1.0.0
61
- *
62
- * @param string $class Name of the class to autoload.
63
- */
64
- public function autoload( $class ) {
65
- $path = $this->dir . strtolower( $class ) . '.php';
66
- if ( file_exists( $path ) ) {
67
- require_once( $path );
68
- }
69
- }
70
- }
71
-
72
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class reponsible for auto-loading files.
17
+ *
18
+ * Loads the class with respect to their respective directories.
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/includes
23
+ */
24
+ class Aalb_Autoloader {
25
+
26
+ private $dir;
27
+
28
+ /**
29
+ * Register the autoloader for a directory in the plugin.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @param string $dir Path of the directory.
34
+ */
35
+ public function __construct( $dir = '' ) {
36
+ if ( ! empty( $dir ) ) {
37
+ $this->dir = $dir;
38
+ }
39
+
40
+ spl_autoload_register( array( $this, 'autoload' ) );
41
+ }
42
+
43
+ /**
44
+ * Make instances of the autoloaders for each directory in the plugin.
45
+ *
46
+ * @since 1.0.0
47
+ */
48
+ public static function register() {
49
+ new self( AALB_INCLUDES_DIR );
50
+ new self( AALB_ADMIN_DIR );
51
+ new self( AALB_SIDEBAR_DIR );
52
+ new self( AALB_PAAPI_DIR );
53
+ new self( AALB_SHORTCODE_DIR );
54
+ new self( AALB_LIBRARY_DIR );
55
+ }
56
+
57
+ /**
58
+ * Callback function of spl_autoload_register to autoload the class.
59
+ *
60
+ * @since 1.0.0
61
+ *
62
+ * @param string $class Name of the class to autoload.
63
+ */
64
+ public function autoload( $class ) {
65
+ $path = $this->dir . strtolower( $class ) . '.php';
66
+ if ( file_exists( $path ) ) {
67
+ require_once( $path );
68
+ }
69
+ }
70
+ }
71
+
72
+ ?>
includes/aalb_cache_loader.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Fired while making a GET request.
17
- *
18
- * Generic class that can be used by any class to get the data from the cache.
19
- * If the data is not available in the cache, a remote GET request is made.
20
- *
21
- * @since 1.0.0
22
- * @package AmazonAssociatesLinkBuilder
23
- * @subpackage AmazonAssociatesLinkBuilder/includes
24
- */
25
- class Aalb_Cache_Loader {
26
-
27
- public $loader;
28
- protected $helper;
29
-
30
- public function __construct( $loader ) {
31
- $this->loader = $loader;
32
- $this->helper = new Aalb_Helper();
33
- }
34
-
35
- /**
36
- * If the information is in the cache, then retrieve the information from the cache.
37
- * Else get the information by making a GET request.
38
- *
39
- * @param string $key Unique identification of the information.
40
- * @param string $url URL for making a request.
41
- *
42
- * @return string GET Response.
43
- */
44
- public function load( $key, $url ) {
45
- $info = $this->lookup( $key );
46
- if ( $info !== false ) {
47
- return $info;
48
- } else {
49
- return $this->load_and_save( $key, $url );
50
- }
51
- }
52
-
53
- /**
54
- * Lookup in the cache for a particular key.
55
- * If the key exists in the cache, the data is return.
56
- * Else false is returned.
57
- *
58
- * @param string $key Unique identification of the information.
59
- *
60
- * @return string Data in the cache.
61
- */
62
- private function lookup( $key ) {
63
- return get_transient( $key );
64
- }
65
-
66
- /**
67
- * Load the information with a GET request and save it in the cache. Return the loaded information.
68
- *
69
- * @param string $key Unique identification of the information.
70
- * @param string $url URL for making a request.
71
- *
72
- * @return string GET Response.
73
- */
74
- private function load_and_save( $key, $url ) {
75
- $info = $this->loader->load( $url );
76
-
77
- //use wordpress linkcode
78
- $info = str_replace( 'linkCode%3Dxm2', 'linkCode%3Dalb', $info );
79
- $info = str_replace( 'linkCode=xm2', 'linkCode=alb', $info );
80
-
81
- $this->helper->clear_expired_transients_at_intervals();
82
- set_transient( $key, $info, AALB_CACHE_FOR_ASIN_RAWINFO_TTL );
83
-
84
- return $info;
85
- }
86
- }
87
-
88
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Fired while making a GET request.
17
+ *
18
+ * Generic class that can be used by any class to get the data from the cache.
19
+ * If the data is not available in the cache, a remote GET request is made.
20
+ *
21
+ * @since 1.0.0
22
+ * @package AmazonAssociatesLinkBuilder
23
+ * @subpackage AmazonAssociatesLinkBuilder/includes
24
+ */
25
+ class Aalb_Cache_Loader {
26
+
27
+ public $loader;
28
+ protected $helper;
29
+
30
+ public function __construct( $loader ) {
31
+ $this->loader = $loader;
32
+ $this->helper = new Aalb_Helper();
33
+ }
34
+
35
+ /**
36
+ * If the information is in the cache, then retrieve the information from the cache.
37
+ * Else get the information by making a GET request.
38
+ *
39
+ * @param string $key Unique identification of the information.
40
+ * @param string $url URL for making a request.
41
+ *
42
+ * @return string GET Response.
43
+ */
44
+ public function load( $key, $url ) {
45
+ $info = $this->lookup( $key );
46
+ if ( $info !== false ) {
47
+ return $info;
48
+ } else {
49
+ return $this->load_and_save( $key, $url );
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Lookup in the cache for a particular key.
55
+ * If the key exists in the cache, the data is return.
56
+ * Else false is returned.
57
+ *
58
+ * @param string $key Unique identification of the information.
59
+ *
60
+ * @return string Data in the cache.
61
+ */
62
+ private function lookup( $key ) {
63
+ return get_transient( $key );
64
+ }
65
+
66
+ /**
67
+ * Load the information with a GET request and save it in the cache. Return the loaded information.
68
+ *
69
+ * @param string $key Unique identification of the information.
70
+ * @param string $url URL for making a request.
71
+ *
72
+ * @return string GET Response.
73
+ */
74
+ private function load_and_save( $key, $url ) {
75
+ $info = $this->loader->load( $url );
76
+
77
+ //use wordpress linkcode
78
+ $info = str_replace( 'linkCode%3Dxm2', 'linkCode%3Dalb', $info );
79
+ $info = str_replace( 'linkCode=xm2', 'linkCode=alb', $info );
80
+
81
+ $this->helper->clear_expired_transients_at_intervals();
82
+ set_transient( $key, $info, AALB_CACHE_FOR_ASIN_RAWINFO_TTL );
83
+
84
+ return $info;
85
+ }
86
+ }
87
+
88
+ ?>
includes/aalb_cache_template_loader.php CHANGED
@@ -1,53 +1,53 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Cache Loader for rendered templates.
17
- *
18
- * Loads ands saves the display unit in the cache.
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/includes
23
- */
24
- class Aalb_Cache_Template_Loader {
25
-
26
- /**
27
- * Get the html of the display unit from the cache
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param string $key Unique Key for the display unit in cache.
32
- *
33
- * @return string HTML of the display unit.
34
- */
35
- public function get_display_unit( $key ) {
36
- return get_transient( $key );
37
- }
38
-
39
- /**
40
- * Get the product information.
41
- *
42
- * @since 1.0.0
43
- *
44
- * @param string $key Unique identification of the product.
45
- * @param string $display_unit HTML of the display unit to save in the cache.
46
- */
47
- public function save_display_unit( $key, $display_unit ) {
48
- set_transient( $key, $display_unit, AALB_CACHE_FOR_ASIN_ADUNIT_TTL );
49
- }
50
-
51
- }
52
-
53
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Cache Loader for rendered templates.
17
+ *
18
+ * Loads ands saves the display unit in the cache.
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/includes
23
+ */
24
+ class Aalb_Cache_Template_Loader {
25
+
26
+ /**
27
+ * Get the html of the display unit from the cache
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param string $key Unique Key for the display unit in cache.
32
+ *
33
+ * @return string HTML of the display unit.
34
+ */
35
+ public function get_display_unit( $key ) {
36
+ return get_transient( $key );
37
+ }
38
+
39
+ /**
40
+ * Get the product information.
41
+ *
42
+ * @since 1.0.0
43
+ *
44
+ * @param string $key Unique identification of the product.
45
+ * @param string $display_unit HTML of the display unit to save in the cache.
46
+ */
47
+ public function save_display_unit( $key, $display_unit ) {
48
+ set_transient( $key, $display_unit, AALB_CACHE_FOR_ASIN_ADUNIT_TTL );
49
+ }
50
+
51
+ }
52
+
53
+ ?>
includes/aalb_compatibility_helper.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class responsible for handling all the functionalities related to
17
+ * plugin compatibility with user environment
18
+ *
19
+ * @since 1.4.3
20
+ * @package AmazonAssociatesLinkBuilder
21
+ * @subpackage AmazonAssociatesLinkBuilder/includes
22
+ */
23
+ class Aalb_Compatibility_Helper {
24
+
25
+ /**
26
+ * Checks whether PHP version of user is compatible with plugin
27
+ *
28
+ * @since 1.4.3
29
+ *
30
+ * @return bool is_php_version_compatible
31
+ */
32
+ private function is_php_version_compatible() {
33
+ return version_compare(phpversion(), AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION, ">=" );
34
+ }
35
+
36
+ /**
37
+ * Checks if the plugin is compatible with user environment or not
38
+ * Add more compatibility checks whenever required
39
+ *
40
+ * @since 1.4.3
41
+ *
42
+ * @return bool is_plugin_compatible
43
+ */
44
+ public function is_plugin_compatible() {
45
+ return $this->is_php_version_compatible();
46
+ }
47
+
48
+ /**
49
+ * Prints the reason for User environment not being compatible as notice on admin page
50
+ *
51
+ * @since 1.4.3
52
+ */
53
+ public function incompatible_environment_message() {
54
+ printf("<div class=\"notice notice-error\">
55
+ <h3>Amazon Associates Link Builder Plugin Deactivated!</h3>
56
+ <p><span style=\"color:red;\">%s plugin requires PHP Version %s or higher. You’re still on %s.</span>
57
+ </p></div>", AALB_PLUGIN_NAME, AALB_PLUGIN_MINIMUM_SUPPORTED_PHP_VERSION, phpversion());
58
+ }
59
+
60
+ /**
61
+ * Deactivates the plugin
62
+ *
63
+ * @since 1.4.3
64
+ */
65
+ public function aalb_deactivate() {
66
+ $plugin = plugin_basename(AALB_PLUGIN_DIR .'amazon-associates-link-builder.php' );
67
+
68
+ //To use functions is_plugin_active() and deactivate_plugins()
69
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
70
+
71
+ if(is_plugin_active($plugin) ) {
72
+ deactivate_plugins($plugin);
73
+ //Remove action_links from admin page present below the plugin
74
+ remove_filter( 'plugin_action_links_' . $plugin, 'add_action_links' );
75
+ $aalb_admin_notice_manager = Aalb_Admin_Notice_Manager::getInstance();
76
+ $aalb_admin_notice_manager->remove_all_notices();
77
+ $aalb_admin_notice_manager->add_notice($this, 'incompatible_environment_message');
78
+ }
79
+ }
80
+ }
81
+ ?>
includes/aalb_config_loader.php CHANGED
@@ -1,77 +1,77 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * The class responsible for getting all the configuration
17
- *
18
- * Loads the class with respect to their respective directories.
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/includes
23
- */
24
- class Aalb_Config_Loader {
25
-
26
- private $cache_loader;
27
-
28
- public function __construct() {
29
- $this->cache_loader = new Aalb_Cache_Loader( new Aalb_Remote_Loader() );
30
- }
31
-
32
- /**
33
- * Updating marketplaces from the external config file and storing it in the database.
34
- *
35
- * If some error occurs while fetching from external source, the error message
36
- * will be logged and marketplace endpoints would be retrieved from database.
37
- *
38
- * @since 1.0.0
39
- */
40
- public function fetch_marketplaces() {
41
- try {
42
- $body = $this->cache_loader->load( AALB_MARKETPLACE_NAMES, MARKETPLACES_URL );
43
-
44
- return $this->parse_json( $body );
45
- } catch ( Exception $e ) {
46
- error_log( $e->getMessage() );
47
-
48
- return get_option( AALB_MARKETPLACE_NAMES );
49
- }
50
- }
51
-
52
- /**
53
- * Parse the json file and extract the marketplace endpoints
54
- *
55
- * @since 1.0.0
56
- *
57
- * @param string $json_body Json retrieved from the server to parse.
58
- *
59
- * @return array Mapping of marketplace endpoint and its abbreviation.
60
- */
61
- private function parse_json( $json_body ) {
62
- $body = json_decode( $json_body, true );
63
- if ( json_last_error() !== JSON_ERROR_NONE ) {
64
- throw new Exception( 'Invalid Json returned by server' . json_last_error() );
65
- }
66
- $marketplaces_info = $body['Local']['Marketplace'];
67
- $updated_marketplace = array();
68
- foreach ( $marketplaces_info as $key => $value ) {
69
- $updated_marketplace[ substr( $value['Endpoint'], 0, strpos( $value['Endpoint'], '/' ) ) ] = $key;
70
- }
71
- update_option( AALB_MARKETPLACE_NAMES, $updated_marketplace );
72
-
73
- return $updated_marketplace;
74
- }
75
- }
76
-
77
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class responsible for getting all the configuration
17
+ *
18
+ * Loads the class with respect to their respective directories.
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/includes
23
+ */
24
+ class Aalb_Config_Loader {
25
+
26
+ private $cache_loader;
27
+
28
+ public function __construct() {
29
+ $this->cache_loader = new Aalb_Cache_Loader( new Aalb_Remote_Loader() );
30
+ }
31
+
32
+ /**
33
+ * Updating marketplaces from the external config file and storing it in the database.
34
+ *
35
+ * If some error occurs while fetching from external source, the error message
36
+ * will be logged and marketplace endpoints would be retrieved from database.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ public function fetch_marketplaces() {
41
+ try {
42
+ $body = $this->cache_loader->load( AALB_MARKETPLACE_NAMES, MARKETPLACES_URL );
43
+
44
+ return $this->parse_json( $body );
45
+ } catch ( Exception $e ) {
46
+ error_log( $e->getMessage() );
47
+
48
+ return get_option( AALB_MARKETPLACE_NAMES );
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Parse the json file and extract the marketplace endpoints
54
+ *
55
+ * @since 1.0.0
56
+ *
57
+ * @param string $json_body Json retrieved from the server to parse.
58
+ *
59
+ * @return array Mapping of marketplace endpoint and its abbreviation.
60
+ */
61
+ private function parse_json( $json_body ) {
62
+ $body = json_decode( $json_body, true );
63
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
64
+ throw new Exception( 'Invalid Json returned by server' . json_last_error() );
65
+ }
66
+ $marketplaces_info = $body['Local']['Marketplace'];
67
+ $updated_marketplace = array();
68
+ foreach ( $marketplaces_info as $key => $value ) {
69
+ $updated_marketplace[ substr( $value['Endpoint'], 0, strpos( $value['Endpoint'], '/' ) ) ] = $key;
70
+ }
71
+ update_option( AALB_MARKETPLACE_NAMES, $updated_marketplace );
72
+
73
+ return $updated_marketplace;
74
+ }
75
+ }
76
+
77
+ ?>
includes/aalb_deactivator.php CHANGED
@@ -1,72 +1,72 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Fired during the plugin deactivation
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/includes
21
- */
22
- class Aalb_Deactivator {
23
-
24
- protected $helper;
25
-
26
- public function __construct() {
27
- $this->helper = new Aalb_Helper();
28
- }
29
-
30
- /**
31
- * Remove the settings stored by the admin in the database
32
- *
33
- * @since 1.0.0
34
- */
35
- public function remove_settings() {
36
- global $wpdb;
37
- $table_prefix = $wpdb->prefix;
38
- $statement = 'DELETE from ' . $table_prefix . 'options
39
- WHERE option_name like %s';
40
- $settings = "aalb%";
41
- $prepared_statement = $wpdb->prepare( $statement, $settings );
42
-
43
- try {
44
- $wpdb->query( $prepared_statement );
45
- } catch ( Exception $e ) {
46
- error_log( 'Unable to clear settings. Query failed with the Exception ' . $e->getMessage() );
47
- }
48
- }
49
-
50
- /**
51
- * Remove the cache stored in the database.
52
- *
53
- * @since 1.0.0
54
- */
55
- public function remove_cache() {
56
- $this->helper->clear_cache_for_substring( '' );
57
- }
58
-
59
- /**
60
- * Recursively remove the template uploads dir
61
- *
62
- * @since 1.3
63
- */
64
- public function remove_uploads_dir() {
65
- global $wp_filesystem;
66
- $this->helper->aalb_initialize_wp_filesystem_api();
67
- $upload_dir = $this->helper->get_template_upload_directory();
68
- $wp_filesystem->rmdir( $upload_dir, true );
69
- }
70
- }
71
-
72
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Fired during the plugin deactivation
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/includes
21
+ */
22
+ class Aalb_Deactivator {
23
+
24
+ protected $helper;
25
+
26
+ public function __construct() {
27
+ $this->helper = new Aalb_Helper();
28
+ }
29
+
30
+ /**
31
+ * Remove the settings stored by the admin in the database
32
+ *
33
+ * @since 1.0.0
34
+ */
35
+ public function remove_settings() {
36
+ global $wpdb;
37
+ $table_prefix = $wpdb->prefix;
38
+ $statement = 'DELETE from ' . $table_prefix . 'options
39
+ WHERE option_name like %s';
40
+ $settings = "aalb%";
41
+ $prepared_statement = $wpdb->prepare( $statement, $settings );
42
+
43
+ try {
44
+ $wpdb->query( $prepared_statement );
45
+ } catch ( Exception $e ) {
46
+ error_log( 'Unable to clear settings. Query failed with the Exception ' . $e->getMessage() );
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Remove the cache stored in the database.
52
+ *
53
+ * @since 1.0.0
54
+ */
55
+ public function remove_cache() {
56
+ $this->helper->clear_cache_for_substring( '' );
57
+ }
58
+
59
+ /**
60
+ * Recursively remove the template uploads dir
61
+ *
62
+ * @since 1.3
63
+ */
64
+ public function remove_uploads_dir() {
65
+ global $wp_filesystem;
66
+ $this->helper->aalb_initialize_wp_filesystem_api();
67
+ $upload_dir = $this->helper->get_template_upload_directory();
68
+ $wp_filesystem->rmdir( $upload_dir, true );
69
+ }
70
+ }
71
+
72
+ ?>
includes/aalb_helper.php CHANGED
@@ -1,297 +1,297 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Hepler class for commonly used functions in the plugin.
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/includes
21
- */
22
- class Aalb_Helper {
23
-
24
- /**
25
- * Build key for storing rendered template in cache.
26
- *
27
- * @since 1.0.0
28
- *
29
- * @param string $asins List of hyphen separated asins.
30
- * @param string $marketplace Marketplace of the asin to look into.
31
- * @param string $store The identifier of the store to be used for current adunit
32
- * @param string $template Template to render the display unit.
33
- *
34
- * @return string Template cache key.
35
- */
36
- public function build_template_cache_key( $asins, $marketplace, $store, $template ) {
37
- return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store . '-' . $template;
38
- }
39
-
40
- /**
41
- * Build key for storing product information in cache.
42
- *
43
- * @since 1.0.0
44
- *
45
- * @param string $asins List of hyphen separated asins.
46
- * @param string $marketplace Marketplace of the asin to look into.
47
- * @param string $store The identifier of the store to be used for current adunit
48
- *
49
- * @return string Products information cache key.
50
- */
51
- public function build_products_cache_key( $asins, $marketplace, $store ) {
52
- return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store;
53
- }
54
-
55
- /**
56
- * Clears the cache for the given template name
57
- *
58
- * @since 1.0.0
59
- *
60
- * @param string $template The template to clear the cache for
61
- */
62
- public function clear_cache_for_template( $template ) {
63
- $this->clear_cache_for_substring( $template );
64
- }
65
-
66
- /**
67
- * Clear the cache for keys which contain the given substring
68
- *
69
- * @since 1.0.0
70
- *
71
- * @param string $substring The substring which is a part of the keys to be cleared
72
- */
73
- public function clear_cache_for_substring( $substring ) {
74
- global $wpdb;
75
- $table_prefix = $wpdb->prefix;
76
- $statement = 'DELETE from ' . $table_prefix . 'options
77
- WHERE option_name like %s or option_name like %s';
78
- $transient_timeout_cache = '_transient_timeout_aalb%' . $substring . '%';
79
- $transient_cache = '_transient_aalb%' . $substring . '%';
80
- $prepared_statement = $wpdb->prepare( $statement, $transient_timeout_cache, $transient_cache );
81
-
82
- try {
83
- $wpdb->query( $prepared_statement );
84
- } catch ( Exception $e ) {
85
- error_log( 'Unable to clear cache. Query to clear cache for substring ' . $substring . ' failed with the Exception ' . $e->getMessage() );
86
- }
87
- }
88
-
89
- /**
90
- * Clear the dead expired transients from cache at intervals
91
- *
92
- * @since 1.0.0
93
- */
94
- public function clear_expired_transients_at_intervals() {
95
- $randomNumber = rand( 1, 50 );
96
- // Clear the expired transients approximately once in 50 requests.
97
- if ( $randomNumber == 25 ) {
98
- $this->clear_expired_transients();
99
- }
100
- }
101
-
102
- /**
103
- * Clear the dead expired transients from cache
104
- *
105
- * @since 1.0.0
106
- */
107
- public function clear_expired_transients() {
108
- global $wpdb;
109
- $table_prefix = $wpdb->prefix;
110
- $transients_prefix = esc_sql( "_transient_timeout_aalb%" );
111
- $sql = $wpdb->prepare( '
112
- SELECT option_name
113
- FROM ' . $table_prefix . 'options
114
- WHERE option_name LIKE %s
115
- ', $transients_prefix );
116
- $transients = $wpdb->get_col( $sql );
117
- foreach ( $transients as $transient ) {
118
- // Strip away the WordPress prefix in order to arrive at the transient key.
119
- $key = str_replace( '_transient_timeout_', '', $transient );
120
- delete_transient( $key );
121
- }
122
- wp_cache_flush();
123
- }
124
-
125
- /**
126
- * Displays error messages in preview mode only
127
- *
128
- * @since 1.0.0
129
- *
130
- * @param string $error_message Error message to be displayed
131
- */
132
- public function show_error_in_preview( $error_message ) {
133
- if ( is_preview() ) {
134
- //If it's preview mode
135
- echo "<br><font color='red'><b>" . $error_message . "</b></font>";
136
- }
137
- }
138
-
139
- /**
140
- * Returns the Store IDs Array.
141
- * Returns AALB_DEFAULT_STORE_ID_NAME if the nothing is specified.
142
- *
143
- * @since 1.0.0
144
- */
145
- public function get_store_ids_array() {
146
- return explode( "\r\n", strlen( get_option( AALB_STORE_ID_NAMES ) ) ? get_option( AALB_STORE_ID_NAMES ) : AALB_DEFAULT_STORE_ID_NAME );
147
- }
148
-
149
- /**
150
- * Fetches the Wordpress version number
151
- *
152
- * @since 1.0.0
153
- * @return string Version number of Wordpress
154
- */
155
- function get_wordpress_version() {
156
- global $wp_version;
157
- return $wp_version;
158
- }
159
-
160
- /**
161
- * Gets the template uploads dir URL.
162
- *
163
- * @since 1.3.2
164
- * @return full URL of the template uploads directory
165
- */
166
- public function get_template_upload_directory_url() {
167
- $upload_dir = wp_upload_dir();
168
-
169
- return $upload_dir['baseurl'] . '/' . AALB_TEMPLATE_UPLOADS_FOLDER;
170
- }
171
-
172
- /**
173
- * Reads both the templates/ and the uploads/ directory and updates the template list.
174
- * Helper to replicate the current status of the default and custom templates
175
- *
176
- * @since 1.3
177
- */
178
- public function refresh_template_list() {
179
- global $wp_filesystem;
180
- $this->aalb_initialize_wp_filesystem_api();
181
-
182
- $aalb_templates = array();
183
- $upload_dir = $this->get_template_upload_directory();
184
-
185
- //Read and update templates from the plugin's template/ directory (Default Templates)
186
- if ( $handle = opendir( AALB_TEMPLATE_DIR ) ) {
187
- while ( false !== ( $entry = readdir( $handle ) ) ) {
188
- $file_name = $this->aalb_get_file_name( $entry );
189
- $file_extension = $this->aalb_get_file_extension( $entry );
190
- if ( $file_extension == "css" and file_exists( AALB_TEMPLATE_DIR . $file_name . '.mustache' ) ) {
191
- $aalb_templates[] = $file_name;
192
- }
193
- }
194
- closedir( $handle );
195
- }
196
-
197
- //Read and update templates from the uploads/ directory (Custom Templates)
198
- if ( $handle = opendir( $upload_dir ) ) {
199
- while ( false !== ( $entry = readdir( $handle ) ) ) {
200
- $file_name = $this->aalb_get_file_name( $entry );
201
- $file_extension = $this->aalb_get_file_extension( $entry );
202
- if ( $file_extension == "css" and file_exists( $upload_dir . $file_name . '.mustache' ) ) {
203
- $aalb_templates[] = $file_name;
204
- }
205
- }
206
- }
207
- update_option( AALB_TEMPLATE_NAMES, $aalb_templates );
208
- }
209
-
210
- /**
211
- * Loads necessary files and initializes WP Filesystem API
212
- *
213
- * @since 1.3
214
- */
215
- public function aalb_initialize_wp_filesystem_api() {
216
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
217
- WP_Filesystem();
218
- }
219
-
220
- /**
221
- * Fetches the Uploads Directory where custom templates are stored.
222
- * If the dir doesn't exists, it is created and returned.
223
- *
224
- * @since 1.3
225
- * @return Full directory path of the template uploads directory
226
- */
227
- public function get_template_upload_directory() {
228
- global $wp_filesystem;
229
- $this->aalb_initialize_wp_filesystem_api();
230
- $aalb_template_upload_dir = $this->get_template_upload_directory_name( $wp_filesystem );
231
- if ( ! $wp_filesystem->is_dir( $aalb_template_upload_dir ) ) {
232
- if ( ! $this->create_template_upload_dir( $aalb_template_upload_dir ) ) {
233
- return false;
234
- }
235
- }
236
-
237
- return $aalb_template_upload_dir;
238
- }
239
-
240
- /**
241
- * Gets the template uploads dir name.
242
- *
243
- * @since 1.3
244
- * @return full path of the template uploads directory
245
- */
246
- public function get_template_upload_directory_name() {
247
- global $wp_filesystem;
248
- $upload_dir = wp_upload_dir();
249
-
250
- return $wp_filesystem->find_folder( $upload_dir['basedir'] ) . AALB_TEMPLATE_UPLOADS_FOLDER;
251
- }
252
-
253
- /**
254
- * Creates the Uploads Directory where custom templates are stored
255
- *
256
- * @since 1.3
257
- * @return TRUE on successful creation of the dir; FALSE otherwise
258
- */
259
- public function create_template_upload_dir( $aalb_template_upload_dir ) {
260
- global $wp_filesystem;
261
- if ( ! wp_mkdir_p( $aalb_template_upload_dir ) ) {
262
- error_log( "Error Creating Dir . " . $aalb_template_upload_dir . ". Please set the folder permissions correctly." );
263
-
264
- return false;
265
- }
266
-
267
- return true;
268
- }
269
-
270
- /**
271
- * Gets the name of the file without the extension
272
- *
273
- * @since 1.0
274
- *
275
- * @param string $file_name Name of the file
276
- *
277
- * @return string Name of the file without the extension
278
- */
279
- function aalb_get_file_name( $file_name ) {
280
- return substr( $file_name, 0, strlen( $file_name ) - strlen( strrchr( $file_name, '.' ) ) );
281
- }
282
-
283
- /**
284
- * Gets the extension of the file
285
- *
286
- * @since 1.0
287
- *
288
- * @param string $file_name Name of the file
289
- *
290
- * @return string Extension of the file
291
- */
292
- public function aalb_get_file_extension( $file_name ) {
293
- return substr( strrchr( $file_name, '.' ), 1 );
294
- }
295
- }
296
-
297
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Hepler class for commonly used functions in the plugin.
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/includes
21
+ */
22
+ class Aalb_Helper {
23
+
24
+ /**
25
+ * Build key for storing rendered template in cache.
26
+ *
27
+ * @since 1.0.0
28
+ *
29
+ * @param string $asins List of hyphen separated asins.
30
+ * @param string $marketplace Marketplace of the asin to look into.
31
+ * @param string $store The identifier of the store to be used for current adunit
32
+ * @param string $template Template to render the display unit.
33
+ *
34
+ * @return string Template cache key.
35
+ */
36
+ public function build_template_cache_key( $asins, $marketplace, $store, $template ) {
37
+ return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store . '-' . $template;
38
+ }
39
+
40
+ /**
41
+ * Build key for storing product information in cache.
42
+ *
43
+ * @since 1.0.0
44
+ *
45
+ * @param string $asins List of hyphen separated asins.
46
+ * @param string $marketplace Marketplace of the asin to look into.
47
+ * @param string $store The identifier of the store to be used for current adunit
48
+ *
49
+ * @return string Products information cache key.
50
+ */
51
+ public function build_products_cache_key( $asins, $marketplace, $store ) {
52
+ return 'aalb' . '-' . $asins . '-' . $marketplace . '-' . $store;
53
+ }
54
+
55
+ /**
56
+ * Clears the cache for the given template name
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @param string $template The template to clear the cache for
61
+ */
62
+ public function clear_cache_for_template( $template ) {
63
+ $this->clear_cache_for_substring( $template );
64
+ }
65
+
66
+ /**
67
+ * Clear the cache for keys which contain the given substring
68
+ *
69
+ * @since 1.0.0
70
+ *
71
+ * @param string $substring The substring which is a part of the keys to be cleared
72
+ */
73
+ public function clear_cache_for_substring( $substring ) {
74
+ global $wpdb;
75
+ $table_prefix = $wpdb->prefix;
76
+ $statement = 'DELETE from ' . $table_prefix . 'options
77
+ WHERE option_name like %s or option_name like %s';
78
+ $transient_timeout_cache = '_transient_timeout_aalb%' . $substring . '%';
79
+ $transient_cache = '_transient_aalb%' . $substring . '%';
80
+ $prepared_statement = $wpdb->prepare( $statement, $transient_timeout_cache, $transient_cache );
81
+
82
+ try {
83
+ $wpdb->query( $prepared_statement );
84
+ } catch ( Exception $e ) {
85
+ error_log( 'Unable to clear cache. Query to clear cache for substring ' . $substring . ' failed with the Exception ' . $e->getMessage() );
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Clear the dead expired transients from cache at intervals
91
+ *
92
+ * @since 1.0.0
93
+ */
94
+ public function clear_expired_transients_at_intervals() {
95
+ $randomNumber = rand( 1, 50 );
96
+ // Clear the expired transients approximately once in 50 requests.
97
+ if ( $randomNumber == 25 ) {
98
+ $this->clear_expired_transients();
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Clear the dead expired transients from cache
104
+ *
105
+ * @since 1.0.0
106
+ */
107
+ public function clear_expired_transients() {
108
+ global $wpdb;
109
+ $table_prefix = $wpdb->prefix;
110
+ $transients_prefix = esc_sql( "_transient_timeout_aalb%" );
111
+ $sql = $wpdb->prepare( '
112
+ SELECT option_name
113
+ FROM ' . $table_prefix . 'options
114
+ WHERE option_name LIKE %s
115
+ ', $transients_prefix );
116
+ $transients = $wpdb->get_col( $sql );
117
+ foreach ( $transients as $transient ) {
118
+ // Strip away the WordPress prefix in order to arrive at the transient key.
119
+ $key = str_replace( '_transient_timeout_', '', $transient );
120
+ delete_transient( $key );
121
+ }
122
+ wp_cache_flush();
123
+ }
124
+
125
+ /**
126
+ * Displays error messages in preview mode only
127
+ *
128
+ * @since 1.0.0
129
+ *
130
+ * @param string $error_message Error message to be displayed
131
+ */
132
+ public function show_error_in_preview( $error_message ) {
133
+ if ( is_preview() ) {
134
+ //If it's preview mode
135
+ echo "<br><font color='red'><b>" . $error_message . "</b></font>";
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Returns the Store IDs Array.
141
+ * Returns AALB_DEFAULT_STORE_ID_NAME if the nothing is specified.
142
+ *
143
+ * @since 1.0.0
144
+ */
145
+ public function get_store_ids_array() {
146
+ return explode( "\r\n", strlen( get_option( AALB_STORE_ID_NAMES ) ) ? get_option( AALB_STORE_ID_NAMES ) : AALB_DEFAULT_STORE_ID_NAME );
147
+ }
148
+
149
+ /**
150
+ * Fetches the Wordpress version number
151
+ *
152
+ * @since 1.0.0
153
+ * @return string Version number of Wordpress
154
+ */
155
+ function get_wordpress_version() {
156
+ global $wp_version;
157
+ return $wp_version;
158
+ }
159
+
160
+ /**
161
+ * Gets the template uploads dir URL.
162
+ *
163
+ * @since 1.3.2
164
+ * @return full URL of the template uploads directory
165
+ */
166
+ public function get_template_upload_directory_url() {
167
+ $upload_dir = wp_upload_dir();
168
+
169
+ return $upload_dir['baseurl'] . '/' . AALB_TEMPLATE_UPLOADS_FOLDER;
170
+ }
171
+
172
+ /**
173
+ * Reads both the templates/ and the uploads/ directory and updates the template list.
174
+ * Helper to replicate the current status of the default and custom templates
175
+ *
176
+ * @since 1.3
177
+ */
178
+ public function refresh_template_list() {
179
+ global $wp_filesystem;
180
+ $this->aalb_initialize_wp_filesystem_api();
181
+
182
+ $aalb_templates = array();
183
+ $upload_dir = $this->get_template_upload_directory();
184
+
185
+ //Read and update templates from the plugin's template/ directory (Default Templates)
186
+ if ( $handle = opendir( AALB_TEMPLATE_DIR ) ) {
187
+ while ( false !== ( $entry = readdir( $handle ) ) ) {
188
+ $file_name = $this->aalb_get_file_name( $entry );
189
+ $file_extension = $this->aalb_get_file_extension( $entry );
190
+ if ( $file_extension == "css" and file_exists( AALB_TEMPLATE_DIR . $file_name . '.mustache' ) ) {
191
+ $aalb_templates[] = $file_name;
192
+ }
193
+ }
194
+ closedir( $handle );
195
+ }
196
+
197
+ //Read and update templates from the uploads/ directory (Custom Templates)
198
+ if ( $handle = opendir( $upload_dir ) ) {
199
+ while ( false !== ( $entry = readdir( $handle ) ) ) {
200
+ $file_name = $this->aalb_get_file_name( $entry );
201
+ $file_extension = $this->aalb_get_file_extension( $entry );
202
+ if ( $file_extension == "css" and file_exists( $upload_dir . $file_name . '.mustache' ) ) {
203
+ $aalb_templates[] = $file_name;
204
+ }
205
+ }
206
+ }
207
+ update_option( AALB_TEMPLATE_NAMES, $aalb_templates );
208
+ }
209
+
210
+ /**
211
+ * Loads necessary files and initializes WP Filesystem API
212
+ *
213
+ * @since 1.3
214
+ */
215
+ public function aalb_initialize_wp_filesystem_api() {
216
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
217
+ WP_Filesystem();
218
+ }
219
+
220
+ /**
221
+ * Fetches the Uploads Directory where custom templates are stored.
222
+ * If the dir doesn't exists, it is created and returned.
223
+ *
224
+ * @since 1.3
225
+ * @return Full directory path of the template uploads directory
226
+ */
227
+ public function get_template_upload_directory() {
228
+ global $wp_filesystem;
229
+ $this->aalb_initialize_wp_filesystem_api();
230
+ $aalb_template_upload_dir = $this->get_template_upload_directory_name( $wp_filesystem );
231
+ if ( ! $wp_filesystem->is_dir( $aalb_template_upload_dir ) ) {
232
+ if ( ! $this->create_template_upload_dir( $aalb_template_upload_dir ) ) {
233
+ return false;
234
+ }
235
+ }
236
+
237
+ return $aalb_template_upload_dir;
238
+ }
239
+
240
+ /**
241
+ * Gets the template uploads dir name.
242
+ *
243
+ * @since 1.3
244
+ * @return full path of the template uploads directory
245
+ */
246
+ public function get_template_upload_directory_name() {
247
+ global $wp_filesystem;
248
+ $upload_dir = wp_upload_dir();
249
+
250
+ return $wp_filesystem->find_folder( $upload_dir['basedir'] ) . AALB_TEMPLATE_UPLOADS_FOLDER;
251
+ }
252
+
253
+ /**
254
+ * Creates the Uploads Directory where custom templates are stored
255
+ *
256
+ * @since 1.3
257
+ * @return TRUE on successful creation of the dir; FALSE otherwise
258
+ */
259
+ public function create_template_upload_dir( $aalb_template_upload_dir ) {
260
+ global $wp_filesystem;
261
+ if ( ! wp_mkdir_p( $aalb_template_upload_dir ) ) {
262
+ error_log( "Error Creating Dir . " . $aalb_template_upload_dir . ". Please set the folder permissions correctly." );
263
+
264
+ return false;
265
+ }
266
+
267
+ return true;
268
+ }
269
+
270
+ /**
271
+ * Gets the name of the file without the extension
272
+ *
273
+ * @since 1.0
274
+ *
275
+ * @param string $file_name Name of the file
276
+ *
277
+ * @return string Name of the file without the extension
278
+ */
279
+ function aalb_get_file_name( $file_name ) {
280
+ return substr( $file_name, 0, strlen( $file_name ) - strlen( strrchr( $file_name, '.' ) ) );
281
+ }
282
+
283
+ /**
284
+ * Gets the extension of the file
285
+ *
286
+ * @since 1.0
287
+ *
288
+ * @param string $file_name Name of the file
289
+ *
290
+ * @return string Extension of the file
291
+ */
292
+ public function aalb_get_file_extension( $file_name ) {
293
+ return substr( strrchr( $file_name, '.' ), 1 );
294
+ }
295
+ }
296
+
297
+ ?>
includes/aalb_hook_loader.php CHANGED
@@ -1,86 +1,86 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * The class that loads all the hooks.
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/includes
21
- */
22
- class Aalb_Hook_Loader {
23
-
24
- protected $actions;
25
-
26
- public function __construct() {
27
- $this->actions = array();
28
- }
29
-
30
- /**
31
- * Add a new action to the collection to be registered with WordPress.
32
- *
33
- * @since 1.0.0
34
- *
35
- * @param string $hook The name of the WordPress action that is being registered.
36
- * @param object $component A reference to the instance of the object on which the action is defined.
37
- * @param string $callback The name of the function definition on the $component.
38
- * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
39
- * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
40
- */
41
- public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
42
- $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
43
- }
44
-
45
- /**
46
- * A utility function that is used to register the actions and hooks into a single
47
- * collection.
48
- *
49
- * @since 1.0.0
50
- * @access private
51
- *
52
- * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
53
- * @param string $hook The name of the WordPress filter that is being registered.
54
- * @param object $component A reference to the instance of the object on which the filter is defined.
55
- * @param string $callback The name of the function definition on the $component.
56
- * @param int $priority The priority at which the function should be fired.
57
- * @param int $accepted_args The number of arguments that should be passed to the $callback.
58
- *
59
- * @return array The collection of actions and filters registered with WordPress.
60
- */
61
- private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
62
- $hooks[] = array(
63
- 'hook' => $hook,
64
- 'component' => $component,
65
- 'callback' => $callback,
66
- 'priority' => $priority,
67
- 'accepted_args' => $accepted_args
68
- );
69
-
70
- return $hooks;
71
- }
72
-
73
- /**
74
- * Register the filters and actions with WordPress.
75
- *
76
- * @since 1.0.0
77
- */
78
- public function execute() {
79
- foreach ( $this->actions as $hook ) {
80
- add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
81
- }
82
- }
83
-
84
- }
85
-
86
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class that loads all the hooks.
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/includes
21
+ */
22
+ class Aalb_Hook_Loader {
23
+
24
+ protected $actions;
25
+
26
+ public function __construct() {
27
+ $this->actions = array();
28
+ }
29
+
30
+ /**
31
+ * Add a new action to the collection to be registered with WordPress.
32
+ *
33
+ * @since 1.0.0
34
+ *
35
+ * @param string $hook The name of the WordPress action that is being registered.
36
+ * @param object $component A reference to the instance of the object on which the action is defined.
37
+ * @param string $callback The name of the function definition on the $component.
38
+ * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
39
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
40
+ */
41
+ public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
42
+ $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
43
+ }
44
+
45
+ /**
46
+ * A utility function that is used to register the actions and hooks into a single
47
+ * collection.
48
+ *
49
+ * @since 1.0.0
50
+ * @access private
51
+ *
52
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
53
+ * @param string $hook The name of the WordPress filter that is being registered.
54
+ * @param object $component A reference to the instance of the object on which the filter is defined.
55
+ * @param string $callback The name of the function definition on the $component.
56
+ * @param int $priority The priority at which the function should be fired.
57
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
58
+ *
59
+ * @return array The collection of actions and filters registered with WordPress.
60
+ */
61
+ private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
62
+ $hooks[] = array(
63
+ 'hook' => $hook,
64
+ 'component' => $component,
65
+ 'callback' => $callback,
66
+ 'priority' => $priority,
67
+ 'accepted_args' => $accepted_args
68
+ );
69
+
70
+ return $hooks;
71
+ }
72
+
73
+ /**
74
+ * Register the filters and actions with WordPress.
75
+ *
76
+ * @since 1.0.0
77
+ */
78
+ public function execute() {
79
+ foreach ( $this->actions as $hook ) {
80
+ add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
81
+ }
82
+ }
83
+
84
+ }
85
+
86
+ ?>
includes/aalb_manager.php CHANGED
@@ -1,83 +1,84 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * The class that manages all the events of the wordpress.
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/includes
21
- */
22
- class Aalb_Manager {
23
-
24
- protected $hook_loader;
25
- protected $shortcode_loader;
26
-
27
- public function __construct() {
28
- $this->hook_loader = new Aalb_Hook_Loader();
29
- $this->shortcode_loader = new Aalb_Shortcode_Loader();
30
-
31
- //add the hooks specific to admin.
32
- $this->add_admin_hooks();
33
-
34
- //add the hooks for shortcode rendering.
35
- $this->register_shortcode_hooks();
36
- }
37
-
38
- /**
39
- * Add the hooks in the admin section
40
- *
41
- * @since 1.0.0
42
- */
43
- private function add_admin_hooks() {
44
- $aalb_admin = new Aalb_Admin();
45
- $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_styles' );
46
- $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_scripts' );
47
- $this->hook_loader->add_action( 'admin_print_footer_scripts', $aalb_admin, 'add_quicktags' );
48
- $this->hook_loader->add_action( 'wp_ajax_get_item_search_result', $aalb_admin, 'get_item_search_result' );
49
- $this->hook_loader->add_action( 'wp_ajax_get_link_code', $aalb_admin, 'get_link_code' );
50
- $this->hook_loader->add_action( 'wp_ajax_get_custom_template_content', $aalb_admin, 'get_custom_template_content' );
51
- $this->hook_loader->add_action( 'media_buttons', $aalb_admin, 'admin_display_callback' );
52
- $this->hook_loader->add_action( 'plugins_loaded', $aalb_admin, 'check_update' );
53
-
54
- $aalb_sidebar = new Aalb_Sidebar();
55
- $this->hook_loader->add_action( 'admin_init', $aalb_sidebar, 'register_cred_config_group' );
56
- $this->hook_loader->add_action( 'admin_menu', $aalb_sidebar, 'register_sidebar_config_page' );
57
- }
58
-
59
- /**
60
- * Add the hooks for the shortcode rendering.
61
- *
62
- * @since 1.0.0
63
- */
64
- private function register_shortcode_hooks() {
65
- $aalb_shortcode = $this->shortcode_loader->get_amazon_link_shortcode();
66
- $aalb_shortcode_text = $this->shortcode_loader->get_amazon_textlink_shortcode();
67
- $this->hook_loader->add_action( 'wp_enqueue_scripts', $aalb_shortcode, 'enqueue_styles' );
68
- $this->hook_loader->add_action( 'wp_enqueue_scripts', $aalb_shortcode_text, 'enqueue_styles' );
69
- }
70
-
71
- /**
72
- * Execute all the wordpress hooks and shortcodes.
73
- *
74
- * @since 1.0.0
75
- */
76
- public function execute() {
77
- $this->hook_loader->execute();
78
- $this->shortcode_loader->add_shortcode();
79
- }
80
-
81
- }
82
-
83
- ?>
 
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * The class that manages all the events of the wordpress.
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/includes
21
+ */
22
+ class Aalb_Manager {
23
+
24
+ protected $hook_loader;
25
+ protected $shortcode_loader;
26
+
27
+ public function __construct() {
28
+ $this->hook_loader = new Aalb_Hook_Loader();
29
+ $this->shortcode_loader = new Aalb_Shortcode_Loader();
30
+
31
+ //add the hooks specific to admin.
32
+ $this->add_admin_hooks();
33
+
34
+ //add the hooks for shortcode rendering.
35
+ $this->register_shortcode_hooks();
36
+ }
37
+
38
+ /**
39
+ * Add the hooks in the admin section
40
+ *
41
+ * @since 1.0.0
42
+ */
43
+ private function add_admin_hooks() {
44
+ $aalb_admin = new Aalb_Admin();
45
+ $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_styles' );
46
+ $this->hook_loader->add_action( 'admin_enqueue_scripts', $aalb_admin, 'enqueue_scripts' );
47
+ $this->hook_loader->add_action( 'admin_print_footer_scripts', $aalb_admin, 'add_quicktags' );
48
+ $this->hook_loader->add_action( 'wp_ajax_get_item_search_result', $aalb_admin, 'get_item_search_result' );
49
+ $this->hook_loader->add_action( 'wp_ajax_get_link_code', $aalb_admin, 'get_link_code' );
50
+ $this->hook_loader->add_action( 'wp_ajax_get_custom_template_content', $aalb_admin, 'get_custom_template_content' );
51
+ $this->hook_loader->add_action( 'media_buttons', $aalb_admin, 'admin_display_callback' );
52
+ $this->hook_loader->add_action( 'admin_footer', $aalb_admin, 'admin_footer_callback' );
53
+ $this->hook_loader->add_action( 'plugins_loaded', $aalb_admin, 'check_update' );
54
+
55
+ $aalb_sidebar = new Aalb_Sidebar();
56
+ $this->hook_loader->add_action( 'admin_init', $aalb_sidebar, 'register_cred_config_group' );
57
+ $this->hook_loader->add_action( 'admin_menu', $aalb_sidebar, 'register_sidebar_config_page' );
58
+ }
59
+
60
+ /**
61
+ * Add the hooks for the shortcode rendering.
62
+ *
63
+ * @since 1.0.0
64
+ */
65
+ private function register_shortcode_hooks() {
66
+ $aalb_shortcode = $this->shortcode_loader->get_amazon_link_shortcode();
67
+ $aalb_shortcode_text = $this->shortcode_loader->get_amazon_textlink_shortcode();
68
+ $this->hook_loader->add_action( 'wp_enqueue_scripts', $aalb_shortcode, 'enqueue_styles' );
69
+ $this->hook_loader->add_action( 'wp_enqueue_scripts', $aalb_shortcode_text, 'enqueue_styles' );
70
+ }
71
+
72
+ /**
73
+ * Execute all the wordpress hooks and shortcodes.
74
+ *
75
+ * @since 1.0.0
76
+ */
77
+ public function execute() {
78
+ $this->hook_loader->execute();
79
+ $this->shortcode_loader->add_shortcode();
80
+ }
81
+
82
+ }
83
+
84
+ ?>
includes/aalb_remote_loader.php CHANGED
@@ -1,99 +1,99 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Fired while making a GET request.
17
- *
18
- * Generic class that can be used by any class to make a GET request call.
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/includes
23
- */
24
- class Aalb_Remote_Loader {
25
-
26
- /**
27
- * Load the information by making a GET request.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param string $url URL for making a request.
32
- *
33
- * @return string GET response body.
34
- */
35
- public function load( $url ) {
36
- $response = $this->fetch( $url );
37
-
38
- return $this->verify( $response );
39
- }
40
-
41
- /**
42
- * Make a GET request and return the response.
43
- *
44
- * @since 1.0.0
45
- *
46
- * @param string $url URL for making a request.
47
- *
48
- * @return string GET Response.
49
- */
50
- private function fetch( $url ) {
51
- return wp_remote_get( $url );
52
- }
53
-
54
- /**
55
- * Verify the response the throw exceptions accordingly.
56
- * Return only the response body.
57
- *
58
- * @since 1.0.0
59
- *
60
- * @param string $response Whole response including headers,body and footers.
61
- *
62
- * @return string Response body.
63
- */
64
- private function verify( $response ) {
65
- if ( is_wp_error( $response ) ) {
66
- $error_message = $response->get_error_message();
67
- throw new Exception( 'HTTP Request failed! ' . $error_message );
68
- }
69
- $code = $response['response']['code'];
70
- if ( $code != HTTP_SUCCESS ) {
71
- throw new Exception( $code );
72
- }
73
- $response_body = wp_remote_retrieve_body( $response );
74
- if ( ! isset( $response_body ) || trim( $response_body ) === '' ) {
75
- throw new Exception( 'Response body is empty' );
76
- }
77
-
78
- return $response_body;
79
- }
80
-
81
- /**
82
- * Load the information by making a POST request.
83
- *
84
- * @since 1.0.0
85
- *
86
- * @param string $url URL for making a request.
87
- * @param string $body Body of the POST request.
88
- *
89
- * @return string POST response body.
90
- */
91
- public function post( $url, $body ) {
92
- $response = wp_remote_post( $url, array( 'body' => $body ) );
93
-
94
- return $this->verify( $response );
95
- }
96
-
97
- }
98
-
99
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Fired while making a GET request.
17
+ *
18
+ * Generic class that can be used by any class to make a GET request call.
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/includes
23
+ */
24
+ class Aalb_Remote_Loader {
25
+
26
+ /**
27
+ * Load the information by making a GET request.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param string $url URL for making a request.
32
+ *
33
+ * @return string GET response body.
34
+ */
35
+ public function load( $url ) {
36
+ $response = $this->fetch( $url );
37
+
38
+ return $this->verify( $response );
39
+ }
40
+
41
+ /**
42
+ * Make a GET request and return the response.
43
+ *
44
+ * @since 1.0.0
45
+ *
46
+ * @param string $url URL for making a request.
47
+ *
48
+ * @return string GET Response.
49
+ */
50
+ private function fetch( $url ) {
51
+ return wp_remote_get( $url );
52
+ }
53
+
54
+ /**
55
+ * Verify the response the throw exceptions accordingly.
56
+ * Return only the response body.
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @param string $response Whole response including headers,body and footers.
61
+ *
62
+ * @return string Response body.
63
+ */
64
+ private function verify( $response ) {
65
+ if ( is_wp_error( $response ) ) {
66
+ $error_message = $response->get_error_message();
67
+ throw new Exception( 'HTTP Request failed! ' . $error_message );
68
+ }
69
+ $code = $response['response']['code'];
70
+ if ( $code != HTTP_SUCCESS ) {
71
+ throw new Exception( $code );
72
+ }
73
+ $response_body = wp_remote_retrieve_body( $response );
74
+ if ( ! isset( $response_body ) || trim( $response_body ) === '' ) {
75
+ throw new Exception( 'Response body is empty' );
76
+ }
77
+
78
+ return $response_body;
79
+ }
80
+
81
+ /**
82
+ * Load the information by making a POST request.
83
+ *
84
+ * @since 1.0.0
85
+ *
86
+ * @param string $url URL for making a request.
87
+ * @param string $body Body of the POST request.
88
+ *
89
+ * @return string POST response body.
90
+ */
91
+ public function post( $url, $body ) {
92
+ $response = wp_remote_post( $url, array( 'body' => $body ) );
93
+
94
+ return $this->verify( $response );
95
+ }
96
+
97
+ }
98
+
99
+ ?>
includes/aalb_template_engine.php CHANGED
@@ -1,146 +1,146 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Template engine to render the product in the particular display unit.
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/includes
21
- */
22
- class Aalb_Template_Engine {
23
-
24
- protected $xml_loader;
25
- protected $cache_template_loader;
26
- protected $mustache;
27
- protected $xml_helper;
28
- protected $helper;
29
-
30
- public function __construct() {
31
- $this->xml_loader = new Aalb_Cache_Loader( new Aalb_Remote_Loader() );
32
- $this->helper = new Aalb_Helper();
33
- $this->cache_template_loader = new Aalb_Cache_Template_Loader();
34
- $this->mustache = new Mustache_Engine( array( 'loader' => new Mustache_Loader_FilesystemLoader( AALB_TEMPLATE_DIR ) ) );
35
- $this->mustache_custom = new Mustache_Engine( array( 'loader' => new Mustache_Loader_FilesystemLoader( $this->helper->get_template_upload_directory() ) ) );
36
- $this->xml_helper = new Aalb_Xml_Helper();
37
- }
38
-
39
- /**
40
- * Render the products into the display unit.
41
- * If the display unit exists in the cache return the display unit.
42
- * Else get the xml and render the product.
43
- *
44
- * @since 1.0.0
45
- *
46
- * @param string $display_key Key of the display unit.
47
- * @param string $products_key Key of the combined products.
48
- * @param string $template Template to render the display unit.
49
- * @param string $url Url to get the product from if not present in cache.
50
- *
51
- * @return string HTML of the disply unit.
52
- */
53
- public function render( $display_key, $products_key, $template, $url, $marketplace ) {
54
- if ( false === ( $display_unit = $this->cache_template_loader->get_display_unit( $display_key ) ) ) {
55
- $products = $this->get_products( $products_key, $url );
56
- $xml = $this->parse( $products );
57
- $items = $this->get_items( $xml );
58
-
59
- //Add custom nodes to the XML
60
- $custom_items = $this->xml_helper->add_custom_nodes( $items, $marketplace );
61
-
62
- $display_unit = $this->render_xml( $custom_items, $template );
63
- $this->cache_template_loader->save_display_unit( $display_key, $display_unit );
64
- }
65
-
66
- return $display_unit;
67
- }
68
-
69
- /**
70
- * Get the products information.
71
- *
72
- * @since 1.0.0
73
- *
74
- * @param string $key Unique identification of the product.
75
- * @param string $url Signed URL for the PAAPI request.
76
- *
77
- * @return string Xml response from PAAPI.
78
- */
79
- private function get_products( $key, $url ) {
80
- return $this->xml_loader->load( $key, $url );
81
- }
82
-
83
- /**
84
- * Convert the well-formed xml string into a SimpleXMLElement object.
85
- *
86
- * @since 1.0.0
87
- *
88
- * @param string $xml_string Well-formed XML string
89
- *
90
- * @return SimpleXMLElement Php xml object.
91
- */
92
- private function parse( $xml_string ) {
93
- libxml_use_internal_errors( true );
94
- $xml = simplexml_load_string( $xml_string );
95
-
96
- if ( $xml === false ) {
97
- throw new Exception( 'Failed Loading XML' );
98
- }
99
-
100
- if ( isset( $xml->Items->Request->Errors->Error ) ) {
101
- throw new Exception( $xml->Items->Request->Errors->Error->Code );
102
- }
103
-
104
- return $xml;
105
- }
106
-
107
- /**
108
- * Return the Item attribute contained in the xml.
109
- *
110
- * @since 1.0.0
111
- *
112
- * @param SimpleXMLElement $xml Well-formed XML string
113
- *
114
- * @return SimpleXMLElement Php xml object of the Items attribute.
115
- */
116
- private function get_items( $xml ) {
117
- return $xml->Items;
118
- }
119
-
120
- /**
121
- * Render the xml with a specific template.
122
- *
123
- * @since 1.0.0
124
- *
125
- * @param array $items Each key consists of an item information object.
126
- * @param string $template Template in which the content has to be rendered.
127
- *
128
- * @return string HTML of the display unit.
129
- */
130
- private function render_xml( $items, $template ) {
131
- $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
132
- try {
133
- if ( in_array( $template, $aalb_default_templates ) ) {
134
- $template = $this->mustache->loadTemplate( $template );
135
- } else {
136
- $template = $this->mustache_custom->loadTemplate( $template );
137
- }
138
- } catch ( Mustache_Exception_UnknownTemplateException $e ) {
139
- $template = $this->mustache->loadTemplate( get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ) );
140
- }
141
-
142
- return $template->render( array( 'StoreId' => get_option( AALB_DEFAULT_STORE_ID ), 'Items' => $items ) );
143
- }
144
- }
145
-
146
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Template engine to render the product in the particular display unit.
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/includes
21
+ */
22
+ class Aalb_Template_Engine {
23
+
24
+ protected $xml_loader;
25
+ protected $cache_template_loader;
26
+ protected $mustache;
27
+ protected $xml_helper;
28
+ protected $helper;
29
+
30
+ public function __construct() {
31
+ $this->xml_loader = new Aalb_Cache_Loader( new Aalb_Remote_Loader() );
32
+ $this->helper = new Aalb_Helper();
33
+ $this->cache_template_loader = new Aalb_Cache_Template_Loader();
34
+ $this->mustache = new Mustache_Engine( array( 'loader' => new Mustache_Loader_FilesystemLoader( AALB_TEMPLATE_DIR ) ) );
35
+ $this->mustache_custom = new Mustache_Engine( array( 'loader' => new Mustache_Loader_FilesystemLoader( $this->helper->get_template_upload_directory() ) ) );
36
+ $this->xml_helper = new Aalb_Xml_Helper();
37
+ }
38
+
39
+ /**
40
+ * Render the products into the display unit.
41
+ * If the display unit exists in the cache return the display unit.
42
+ * Else get the xml and render the product.
43
+ *
44
+ * @since 1.0.0
45
+ *
46
+ * @param string $display_key Key of the display unit.
47
+ * @param string $products_key Key of the combined products.
48
+ * @param string $template Template to render the display unit.
49
+ * @param string $url Url to get the product from if not present in cache.
50
+ *
51
+ * @return string HTML of the disply unit.
52
+ */
53
+ public function render( $display_key, $products_key, $template, $url, $marketplace ) {
54
+ if ( false === ( $display_unit = $this->cache_template_loader->get_display_unit( $display_key ) ) ) {
55
+ $products = $this->get_products( $products_key, $url );
56
+ $xml = $this->parse( $products );
57
+ $items = $this->get_items( $xml );
58
+
59
+ //Add custom nodes to the XML
60
+ $custom_items = $this->xml_helper->add_custom_nodes( $items, $marketplace );
61
+
62
+ $display_unit = $this->render_xml( $custom_items, $template );
63
+ $this->cache_template_loader->save_display_unit( $display_key, $display_unit );
64
+ }
65
+
66
+ return $display_unit;
67
+ }
68
+
69
+ /**
70
+ * Get the products information.
71
+ *
72
+ * @since 1.0.0
73
+ *
74
+ * @param string $key Unique identification of the product.
75
+ * @param string $url Signed URL for the PAAPI request.
76
+ *
77
+ * @return string Xml response from PAAPI.
78
+ */
79
+ private function get_products( $key, $url ) {
80
+ return $this->xml_loader->load( $key, $url );
81
+ }
82
+
83
+ /**
84
+ * Convert the well-formed xml string into a SimpleXMLElement object.
85
+ *
86
+ * @since 1.0.0
87
+ *
88
+ * @param string $xml_string Well-formed XML string
89
+ *
90
+ * @return SimpleXMLElement Php xml object.
91
+ */
92
+ private function parse( $xml_string ) {
93
+ libxml_use_internal_errors( true );
94
+ $xml = simplexml_load_string( $xml_string );
95
+
96
+ if ( $xml === false ) {
97
+ throw new Exception( 'Failed Loading XML' );
98
+ }
99
+
100
+ if ( isset( $xml->Items->Request->Errors->Error ) ) {
101
+ throw new Exception( $xml->Items->Request->Errors->Error->Code );
102
+ }
103
+
104
+ return $xml;
105
+ }
106
+
107
+ /**
108
+ * Return the Item attribute contained in the xml.
109
+ *
110
+ * @since 1.0.0
111
+ *
112
+ * @param SimpleXMLElement $xml Well-formed XML string
113
+ *
114
+ * @return SimpleXMLElement Php xml object of the Items attribute.
115
+ */
116
+ private function get_items( $xml ) {
117
+ return $xml->Items;
118
+ }
119
+
120
+ /**
121
+ * Render the xml with a specific template.
122
+ *
123
+ * @since 1.0.0
124
+ *
125
+ * @param array $items Each key consists of an item information object.
126
+ * @param string $template Template in which the content has to be rendered.
127
+ *
128
+ * @return string HTML of the display unit.
129
+ */
130
+ private function render_xml( $items, $template ) {
131
+ $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
132
+ try {
133
+ if ( in_array( $template, $aalb_default_templates ) ) {
134
+ $template = $this->mustache->loadTemplate( $template );
135
+ } else {
136
+ $template = $this->mustache_custom->loadTemplate( $template );
137
+ }
138
+ } catch ( Mustache_Exception_UnknownTemplateException $e ) {
139
+ $template = $this->mustache->loadTemplate( get_option( AALB_DEFAULT_TEMPLATE, AALB_DEFAULT_TEMPLATE_NAME ) );
140
+ }
141
+
142
+ return $template->render( array( 'StoreId' => get_option( AALB_DEFAULT_STORE_ID ), 'Items' => $items ) );
143
+ }
144
+ }
145
+
146
+ ?>
lib/php/Mustache/Autoloader.php CHANGED
@@ -1,74 +1,74 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache class autoloader.
14
- */
15
- class Mustache_Autoloader
16
- {
17
- private $baseDir;
18
-
19
- /**
20
- * Autoloader constructor.
21
- *
22
- * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
23
- */
24
- public function __construct($baseDir = null)
25
- {
26
- if ($baseDir === null) {
27
- $baseDir = dirname(__FILE__) . '/..';
28
- }
29
-
30
- // realpath doesn't always work, for example, with stream URIs
31
- $realDir = realpath($baseDir);
32
- if (is_dir($realDir)) {
33
- $this->baseDir = $realDir;
34
- } else {
35
- $this->baseDir = $baseDir;
36
- }
37
- }
38
-
39
- /**
40
- * Register a new instance as an SPL autoloader.
41
- *
42
- * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
43
- *
44
- * @return Mustache_Autoloader Registered Autoloader instance
45
- */
46
- public static function register($baseDir = null)
47
- {
48
- $loader = new self($baseDir);
49
- spl_autoload_register(array($loader, 'autoload'));
50
-
51
- return $loader;
52
- }
53
-
54
- /**
55
- * Autoload Mustache classes.
56
- *
57
- * @param string $class
58
- */
59
- public function autoload($class)
60
- {
61
- if ($class[0] === '\\') {
62
- $class = substr($class, 1);
63
- }
64
-
65
- if (strpos($class, 'Mustache') !== 0) {
66
- return;
67
- }
68
-
69
- $file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class));
70
- if (is_file($file)) {
71
- require $file;
72
- }
73
- }
74
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache class autoloader.
14
+ */
15
+ class Mustache_Autoloader
16
+ {
17
+ private $baseDir;
18
+
19
+ /**
20
+ * Autoloader constructor.
21
+ *
22
+ * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
23
+ */
24
+ public function __construct($baseDir = null)
25
+ {
26
+ if ($baseDir === null) {
27
+ $baseDir = dirname(__FILE__) . '/..';
28
+ }
29
+
30
+ // realpath doesn't always work, for example, with stream URIs
31
+ $realDir = realpath($baseDir);
32
+ if (is_dir($realDir)) {
33
+ $this->baseDir = $realDir;
34
+ } else {
35
+ $this->baseDir = $baseDir;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Register a new instance as an SPL autoloader.
41
+ *
42
+ * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
43
+ *
44
+ * @return Mustache_Autoloader Registered Autoloader instance
45
+ */
46
+ public static function register($baseDir = null)
47
+ {
48
+ $loader = new self($baseDir);
49
+ spl_autoload_register(array($loader, 'autoload'));
50
+
51
+ return $loader;
52
+ }
53
+
54
+ /**
55
+ * Autoload Mustache classes.
56
+ *
57
+ * @param string $class
58
+ */
59
+ public function autoload($class)
60
+ {
61
+ if ($class[0] === '\\') {
62
+ $class = substr($class, 1);
63
+ }
64
+
65
+ if (strpos($class, 'Mustache') !== 0) {
66
+ return;
67
+ }
68
+
69
+ $file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class));
70
+ if (is_file($file)) {
71
+ require $file;
72
+ }
73
+ }
74
+ }
lib/php/Mustache/Cache.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Cache interface.
14
- *
15
- * Interface for caching and loading Mustache_Template classes
16
- * generated by the Mustache_Compiler.
17
- */
18
- interface Mustache_Cache
19
- {
20
- /**
21
- * Load a compiled Mustache_Template class from cache.
22
- *
23
- * @param string $key
24
- *
25
- * @return bool indicates successfully class load
26
- */
27
- public function load($key);
28
-
29
- /**
30
- * Cache and load a compiled Mustache_Template class.
31
- *
32
- * @param string $key
33
- * @param string $value
34
- */
35
- public function cache($key, $value);
36
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Cache interface.
14
+ *
15
+ * Interface for caching and loading Mustache_Template classes
16
+ * generated by the Mustache_Compiler.
17
+ */
18
+ interface Mustache_Cache
19
+ {
20
+ /**
21
+ * Load a compiled Mustache_Template class from cache.
22
+ *
23
+ * @param string $key
24
+ *
25
+ * @return bool indicates successfully class load
26
+ */
27
+ public function load($key);
28
+
29
+ /**
30
+ * Cache and load a compiled Mustache_Template class.
31
+ *
32
+ * @param string $key
33
+ * @param string $value
34
+ */
35
+ public function cache($key, $value);
36
+ }
lib/php/Mustache/Cache/AbstractCache.php CHANGED
@@ -1,60 +1,60 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Abstract Mustache Cache class.
14
- *
15
- * Provides logging support to child implementations.
16
- *
17
- * @abstract
18
- */
19
- abstract class Mustache_Cache_AbstractCache implements Mustache_Cache
20
- {
21
- private $logger = null;
22
-
23
- /**
24
- * Get the current logger instance.
25
- *
26
- * @return Mustache_Logger|Psr\Log\LoggerInterface
27
- */
28
- public function getLogger()
29
- {
30
- return $this->logger;
31
- }
32
-
33
- /**
34
- * Set a logger instance.
35
- *
36
- * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
37
- */
38
- public function setLogger($logger = null)
39
- {
40
- if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
41
- throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
42
- }
43
-
44
- $this->logger = $logger;
45
- }
46
-
47
- /**
48
- * Add a log record if logging is enabled.
49
- *
50
- * @param int $level The logging level
51
- * @param string $message The log message
52
- * @param array $context The log context
53
- */
54
- protected function log($level, $message, array $context = array())
55
- {
56
- if (isset($this->logger)) {
57
- $this->logger->log($level, $message, $context);
58
- }
59
- }
60
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Abstract Mustache Cache class.
14
+ *
15
+ * Provides logging support to child implementations.
16
+ *
17
+ * @abstract
18
+ */
19
+ abstract class Mustache_Cache_AbstractCache implements Mustache_Cache
20
+ {
21
+ private $logger = null;
22
+
23
+ /**
24
+ * Get the current logger instance.
25
+ *
26
+ * @return Mustache_Logger|Psr\Log\LoggerInterface
27
+ */
28
+ public function getLogger()
29
+ {
30
+ return $this->logger;
31
+ }
32
+
33
+ /**
34
+ * Set a logger instance.
35
+ *
36
+ * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
37
+ */
38
+ public function setLogger($logger = null)
39
+ {
40
+ if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
41
+ throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
42
+ }
43
+
44
+ $this->logger = $logger;
45
+ }
46
+
47
+ /**
48
+ * Add a log record if logging is enabled.
49
+ *
50
+ * @param int $level The logging level
51
+ * @param string $message The log message
52
+ * @param array $context The log context
53
+ */
54
+ protected function log($level, $message, array $context = array())
55
+ {
56
+ if (isset($this->logger)) {
57
+ $this->logger->log($level, $message, $context);
58
+ }
59
+ }
60
+ }
lib/php/Mustache/Cache/FilesystemCache.php CHANGED
@@ -1,155 +1,155 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Cache filesystem implementation.
14
- *
15
- * A FilesystemCache instance caches Mustache Template classes from the filesystem by name:
16
- *
17
- * $cache = new Mustache_Cache_FilesystemCache(dirname(__FILE__).'/cache');
18
- * $cache->cache($className, $compiledSource);
19
- *
20
- * The FilesystemCache benefits from any opcode caching that may be setup in your environment. So do that, k?
21
- */
22
- class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
23
- {
24
- private $baseDir;
25
- private $fileMode;
26
-
27
- /**
28
- * Filesystem cache constructor.
29
- *
30
- * @param string $baseDir Directory for compiled templates.
31
- * @param int $fileMode Override default permissions for cache files. Defaults to using the system-defined umask.
32
- */
33
- public function __construct($baseDir, $fileMode = null)
34
- {
35
- $this->baseDir = $baseDir;
36
- $this->fileMode = $fileMode;
37
- }
38
-
39
- /**
40
- * Load the class from cache using `require_once`.
41
- *
42
- * @param string $key
43
- *
44
- * @return bool
45
- */
46
- public function load($key)
47
- {
48
- $fileName = $this->getCacheFilename($key);
49
- if (!is_file($fileName)) {
50
- return false;
51
- }
52
-
53
- require_once $fileName;
54
-
55
- return true;
56
- }
57
-
58
- /**
59
- * Cache and load the compiled class.
60
- *
61
- * @param string $key
62
- * @param string $value
63
- */
64
- public function cache($key, $value)
65
- {
66
- $fileName = $this->getCacheFilename($key);
67
-
68
- $this->log(
69
- Mustache_Logger::DEBUG,
70
- 'Writing to template cache: "{fileName}"',
71
- array('fileName' => $fileName)
72
- );
73
-
74
- $this->writeFile($fileName, $value);
75
- $this->load($key);
76
- }
77
-
78
- /**
79
- * Build the cache filename.
80
- * Subclasses should override for custom cache directory structures.
81
- *
82
- * @param string $name
83
- *
84
- * @return string
85
- */
86
- protected function getCacheFilename($name)
87
- {
88
- return sprintf('%s/%s.php', $this->baseDir, $name);
89
- }
90
-
91
- /**
92
- * Create cache directory.
93
- *
94
- * @throws Mustache_Exception_RuntimeException If unable to create directory
95
- *
96
- * @param string $fileName
97
- *
98
- * @return string
99
- */
100
- private function buildDirectoryForFilename($fileName)
101
- {
102
- $dirName = dirname($fileName);
103
- if (!is_dir($dirName)) {
104
- $this->log(
105
- Mustache_Logger::INFO,
106
- 'Creating Mustache template cache directory: "{dirName}"',
107
- array('dirName' => $dirName)
108
- );
109
-
110
- @mkdir($dirName, 0777, true);
111
- if (!is_dir($dirName)) {
112
- throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName));
113
- }
114
- }
115
-
116
- return $dirName;
117
- }
118
-
119
- /**
120
- * Write cache file.
121
- *
122
- * @throws Mustache_Exception_RuntimeException If unable to write file
123
- *
124
- * @param string $fileName
125
- * @param string $value
126
- */
127
- private function writeFile($fileName, $value)
128
- {
129
- $dirName = $this->buildDirectoryForFilename($fileName);
130
-
131
- $this->log(
132
- Mustache_Logger::DEBUG,
133
- 'Caching compiled template to "{fileName}"',
134
- array('fileName' => $fileName)
135
- );
136
-
137
- $tempFile = tempnam($dirName, basename($fileName));
138
- if (false !== @file_put_contents($tempFile, $value)) {
139
- if (@rename($tempFile, $fileName)) {
140
- $mode = isset($this->fileMode) ? $this->fileMode : (0666 & ~umask());
141
- @chmod($fileName, $mode);
142
-
143
- return;
144
- }
145
-
146
- $this->log(
147
- Mustache_Logger::ERROR,
148
- 'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"',
149
- array('tempName' => $tempFile, 'fileName' => $fileName)
150
- );
151
- }
152
-
153
- throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName));
154
- }
155
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Cache filesystem implementation.
14
+ *
15
+ * A FilesystemCache instance caches Mustache Template classes from the filesystem by name:
16
+ *
17
+ * $cache = new Mustache_Cache_FilesystemCache(dirname(__FILE__).'/cache');
18
+ * $cache->cache($className, $compiledSource);
19
+ *
20
+ * The FilesystemCache benefits from any opcode caching that may be setup in your environment. So do that, k?
21
+ */
22
+ class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
23
+ {
24
+ private $baseDir;
25
+ private $fileMode;
26
+
27
+ /**
28
+ * Filesystem cache constructor.
29
+ *
30
+ * @param string $baseDir Directory for compiled templates.
31
+ * @param int $fileMode Override default permissions for cache files. Defaults to using the system-defined umask.
32
+ */
33
+ public function __construct($baseDir, $fileMode = null)
34
+ {
35
+ $this->baseDir = $baseDir;
36
+ $this->fileMode = $fileMode;
37
+ }
38
+
39
+ /**
40
+ * Load the class from cache using `require_once`.
41
+ *
42
+ * @param string $key
43
+ *
44
+ * @return bool
45
+ */
46
+ public function load($key)
47
+ {
48
+ $fileName = $this->getCacheFilename($key);
49
+ if (!is_file($fileName)) {
50
+ return false;
51
+ }
52
+
53
+ require_once $fileName;
54
+
55
+ return true;
56
+ }
57
+
58
+ /**
59
+ * Cache and load the compiled class.
60
+ *
61
+ * @param string $key
62
+ * @param string $value
63
+ */
64
+ public function cache($key, $value)
65
+ {
66
+ $fileName = $this->getCacheFilename($key);
67
+
68
+ $this->log(
69
+ Mustache_Logger::DEBUG,
70
+ 'Writing to template cache: "{fileName}"',
71
+ array('fileName' => $fileName)
72
+ );
73
+
74
+ $this->writeFile($fileName, $value);
75
+ $this->load($key);
76
+ }
77
+
78
+ /**
79
+ * Build the cache filename.
80
+ * Subclasses should override for custom cache directory structures.
81
+ *
82
+ * @param string $name
83
+ *
84
+ * @return string
85
+ */
86
+ protected function getCacheFilename($name)
87
+ {
88
+ return sprintf('%s/%s.php', $this->baseDir, $name);
89
+ }
90
+
91
+ /**
92
+ * Create cache directory.
93
+ *
94
+ * @throws Mustache_Exception_RuntimeException If unable to create directory
95
+ *
96
+ * @param string $fileName
97
+ *
98
+ * @return string
99
+ */
100
+ private function buildDirectoryForFilename($fileName)
101
+ {
102
+ $dirName = dirname($fileName);
103
+ if (!is_dir($dirName)) {
104
+ $this->log(
105
+ Mustache_Logger::INFO,
106
+ 'Creating Mustache template cache directory: "{dirName}"',
107
+ array('dirName' => $dirName)
108
+ );
109
+
110
+ @mkdir($dirName, 0777, true);
111
+ if (!is_dir($dirName)) {
112
+ throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName));
113
+ }
114
+ }
115
+
116
+ return $dirName;
117
+ }
118
+
119
+ /**
120
+ * Write cache file.
121
+ *
122
+ * @throws Mustache_Exception_RuntimeException If unable to write file
123
+ *
124
+ * @param string $fileName
125
+ * @param string $value
126
+ */
127
+ private function writeFile($fileName, $value)
128
+ {
129
+ $dirName = $this->buildDirectoryForFilename($fileName);
130
+
131
+ $this->log(
132
+ Mustache_Logger::DEBUG,
133
+ 'Caching compiled template to "{fileName}"',
134
+ array('fileName' => $fileName)
135
+ );
136
+
137
+ $tempFile = tempnam($dirName, basename($fileName));
138
+ if (false !== @file_put_contents($tempFile, $value)) {
139
+ if (@rename($tempFile, $fileName)) {
140
+ $mode = isset($this->fileMode) ? $this->fileMode : (0666 & ~umask());
141
+ @chmod($fileName, $mode);
142
+
143
+ return;
144
+ }
145
+
146
+ $this->log(
147
+ Mustache_Logger::ERROR,
148
+ 'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"',
149
+ array('tempName' => $tempFile, 'fileName' => $fileName)
150
+ );
151
+ }
152
+
153
+ throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName));
154
+ }
155
+ }
lib/php/Mustache/Cache/NoopCache.php CHANGED
@@ -1,47 +1,47 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Cache in-memory implementation.
14
- *
15
- * The in-memory cache is used for uncached lambda section templates. It's also useful during development, but is not
16
- * recommended for production use.
17
- */
18
- class Mustache_Cache_NoopCache extends Mustache_Cache_AbstractCache
19
- {
20
- /**
21
- * Loads nothing. Move along.
22
- *
23
- * @param string $key
24
- *
25
- * @return bool
26
- */
27
- public function load($key)
28
- {
29
- return false;
30
- }
31
-
32
- /**
33
- * Loads the compiled Mustache Template class without caching.
34
- *
35
- * @param string $key
36
- * @param string $value
37
- */
38
- public function cache($key, $value)
39
- {
40
- $this->log(
41
- Mustache_Logger::WARNING,
42
- 'Template cache disabled, evaluating "{className}" class at runtime',
43
- array('className' => $key)
44
- );
45
- eval('?>' . $value);
46
- }
47
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Cache in-memory implementation.
14
+ *
15
+ * The in-memory cache is used for uncached lambda section templates. It's also useful during development, but is not
16
+ * recommended for production use.
17
+ */
18
+ class Mustache_Cache_NoopCache extends Mustache_Cache_AbstractCache
19
+ {
20
+ /**
21
+ * Loads nothing. Move along.
22
+ *
23
+ * @param string $key
24
+ *
25
+ * @return bool
26
+ */
27
+ public function load($key)
28
+ {
29
+ return false;
30
+ }
31
+
32
+ /**
33
+ * Loads the compiled Mustache Template class without caching.
34
+ *
35
+ * @param string $key
36
+ * @param string $value
37
+ */
38
+ public function cache($key, $value)
39
+ {
40
+ $this->log(
41
+ Mustache_Logger::WARNING,
42
+ 'Template cache disabled, evaluating "{className}" class at runtime',
43
+ array('className' => $key)
44
+ );
45
+ eval('?>' . $value);
46
+ }
47
+ }
lib/php/Mustache/Compiler.php CHANGED
@@ -1,684 +1,684 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Compiler class.
14
- *
15
- * This class is responsible for turning a Mustache token parse tree into normal PHP source code.
16
- */
17
- class Mustache_Compiler
18
- {
19
- private $pragmas;
20
- private $defaultPragmas = array();
21
- private $sections;
22
- private $blocks;
23
- private $source;
24
- private $indentNextLine;
25
- private $customEscape;
26
- private $entityFlags;
27
- private $charset;
28
- private $strictCallables;
29
-
30
- /**
31
- * Compile a Mustache token parse tree into PHP source code.
32
- *
33
- * @param string $source Mustache Template source code
34
- * @param string $tree Parse tree of Mustache tokens
35
- * @param string $name Mustache Template class name
36
- * @param bool $customEscape (default: false)
37
- * @param string $charset (default: 'UTF-8')
38
- * @param bool $strictCallables (default: false)
39
- * @param int $entityFlags (default: ENT_COMPAT)
40
- *
41
- * @return string Generated PHP source code
42
- */
43
- public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
44
- {
45
- $this->pragmas = $this->defaultPragmas;
46
- $this->sections = array();
47
- $this->blocks = array();
48
- $this->source = $source;
49
- $this->indentNextLine = true;
50
- $this->customEscape = $customEscape;
51
- $this->entityFlags = $entityFlags;
52
- $this->charset = $charset;
53
- $this->strictCallables = $strictCallables;
54
-
55
- return $this->writeCode($tree, $name);
56
- }
57
-
58
- /**
59
- * Enable pragmas across all templates, regardless of the presence of pragma
60
- * tags in the individual templates.
61
- *
62
- * @internal Users should set global pragmas in Mustache_Engine, not here :)
63
- *
64
- * @param string[] $pragmas
65
- */
66
- public function setPragmas(array $pragmas)
67
- {
68
- $this->pragmas = array();
69
- foreach ($pragmas as $pragma) {
70
- $this->pragmas[$pragma] = true;
71
- }
72
- $this->defaultPragmas = $this->pragmas;
73
- }
74
-
75
- /**
76
- * Helper function for walking the Mustache token parse tree.
77
- *
78
- * @throws Mustache_Exception_SyntaxException upon encountering unknown token types.
79
- *
80
- * @param array $tree Parse tree of Mustache tokens
81
- * @param int $level (default: 0)
82
- *
83
- * @return string Generated PHP source code
84
- */
85
- private function walk(array $tree, $level = 0)
86
- {
87
- $code = '';
88
- $level++;
89
- foreach ($tree as $node) {
90
- switch ($node[Mustache_Tokenizer::TYPE]) {
91
- case Mustache_Tokenizer::T_PRAGMA:
92
- $this->pragmas[$node[Mustache_Tokenizer::NAME]] = true;
93
- break;
94
-
95
- case Mustache_Tokenizer::T_SECTION:
96
- $code .= $this->section(
97
- $node[Mustache_Tokenizer::NODES],
98
- $node[Mustache_Tokenizer::NAME],
99
- isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
100
- $node[Mustache_Tokenizer::INDEX],
101
- $node[Mustache_Tokenizer::END],
102
- $node[Mustache_Tokenizer::OTAG],
103
- $node[Mustache_Tokenizer::CTAG],
104
- $level
105
- );
106
- break;
107
-
108
- case Mustache_Tokenizer::T_INVERTED:
109
- $code .= $this->invertedSection(
110
- $node[Mustache_Tokenizer::NODES],
111
- $node[Mustache_Tokenizer::NAME],
112
- isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
113
- $level
114
- );
115
- break;
116
-
117
- case Mustache_Tokenizer::T_PARTIAL:
118
- $code .= $this->partial(
119
- $node[Mustache_Tokenizer::NAME],
120
- isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
121
- $level
122
- );
123
- break;
124
-
125
- case Mustache_Tokenizer::T_PARENT:
126
- $code .= $this->parent(
127
- $node[Mustache_Tokenizer::NAME],
128
- isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
129
- $node[Mustache_Tokenizer::NODES],
130
- $level
131
- );
132
- break;
133
-
134
- case Mustache_Tokenizer::T_BLOCK_ARG:
135
- $code .= $this->blockArg(
136
- $node[Mustache_Tokenizer::NODES],
137
- $node[Mustache_Tokenizer::NAME],
138
- $node[Mustache_Tokenizer::INDEX],
139
- $node[Mustache_Tokenizer::END],
140
- $node[Mustache_Tokenizer::OTAG],
141
- $node[Mustache_Tokenizer::CTAG],
142
- $level
143
- );
144
- break;
145
-
146
- case Mustache_Tokenizer::T_BLOCK_VAR:
147
- $code .= $this->blockVar(
148
- $node[Mustache_Tokenizer::NODES],
149
- $node[Mustache_Tokenizer::NAME],
150
- $node[Mustache_Tokenizer::INDEX],
151
- $node[Mustache_Tokenizer::END],
152
- $node[Mustache_Tokenizer::OTAG],
153
- $node[Mustache_Tokenizer::CTAG],
154
- $level
155
- );
156
- break;
157
-
158
- case Mustache_Tokenizer::T_COMMENT:
159
- break;
160
-
161
- case Mustache_Tokenizer::T_ESCAPED:
162
- case Mustache_Tokenizer::T_UNESCAPED:
163
- case Mustache_Tokenizer::T_UNESCAPED_2:
164
- $code .= $this->variable(
165
- $node[Mustache_Tokenizer::NAME],
166
- isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
167
- $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_ESCAPED,
168
- $level
169
- );
170
- break;
171
-
172
- case Mustache_Tokenizer::T_TEXT:
173
- $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
174
- break;
175
-
176
- default:
177
- throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node);
178
- }
179
- }
180
-
181
- return $code;
182
- }
183
-
184
- const KLASS = '<?php
185
-
186
- class %s extends Mustache_Template
187
- {
188
- private $lambdaHelper;%s
189
-
190
- public function renderInternal(Mustache_Context $context, $indent = \'\')
191
- {
192
- $this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
193
- $buffer = \'\';
194
- $newContext = array();
195
- %s
196
-
197
- return $buffer;
198
- }
199
- %s
200
- %s
201
- }';
202
-
203
- const KLASS_NO_LAMBDAS = '<?php
204
-
205
- class %s extends Mustache_Template
206
- {%s
207
- public function renderInternal(Mustache_Context $context, $indent = \'\')
208
- {
209
- $buffer = \'\';
210
- $newContext = array();
211
- %s
212
-
213
- return $buffer;
214
- }
215
- }';
216
-
217
- const STRICT_CALLABLE = 'protected $strictCallables = true;';
218
-
219
- /**
220
- * Generate Mustache Template class PHP source.
221
- *
222
- * @param array $tree Parse tree of Mustache tokens
223
- * @param string $name Mustache Template class name
224
- *
225
- * @return string Generated PHP source code
226
- */
227
- private function writeCode($tree, $name)
228
- {
229
- $code = $this->walk($tree);
230
- $sections = implode("\n", $this->sections);
231
- $blocks = implode("\n", $this->blocks);
232
- $klass = empty($this->sections) && empty($this->blocks) ? self::KLASS_NO_LAMBDAS : self::KLASS;
233
-
234
- $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
235
-
236
- return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections, $blocks);
237
- }
238
-
239
- const BLOCK_VAR = '
240
- $blockFunction = $context->findInBlock(%s);
241
- if (is_callable($blockFunction)) {
242
- $buffer .= call_user_func($blockFunction, $context);
243
- } else {%s
244
- }
245
- ';
246
-
247
- /**
248
- * Generate Mustache Template inheritance block variable PHP source.
249
- *
250
- * @param array $nodes Array of child tokens
251
- * @param string $id Section name
252
- * @param int $start Section start offset
253
- * @param int $end Section end offset
254
- * @param string $otag Current Mustache opening tag
255
- * @param string $ctag Current Mustache closing tag
256
- * @param int $level
257
- *
258
- * @return string Generated PHP source code
259
- */
260
- private function blockVar($nodes, $id, $start, $end, $otag, $ctag, $level)
261
- {
262
- $id = var_export($id, true);
263
-
264
- return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, $level));
265
- }
266
-
267
- const BLOCK_ARG = '$newContext[%s] = array($this, \'block%s\');';
268
-
269
- /**
270
- * Generate Mustache Template inheritance block argument PHP source.
271
- *
272
- * @param array $nodes Array of child tokens
273
- * @param string $id Section name
274
- * @param int $start Section start offset
275
- * @param int $end Section end offset
276
- * @param string $otag Current Mustache opening tag
277
- * @param string $ctag Current Mustache closing tag
278
- * @param int $level
279
- *
280
- * @return string Generated PHP source code
281
- */
282
- private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
283
- {
284
- $key = $this->block($nodes);
285
- $keystr = var_export($key, true);
286
- $id = var_export($id, true);
287
-
288
- return sprintf($this->prepare(self::BLOCK_ARG, 1), $id, $key);
289
- }
290
-
291
- const BLOCK_FUNCTION = '
292
- public function block%s($context)
293
- {
294
- $indent = $buffer = \'\';%s
295
-
296
- return $buffer;
297
- }
298
- ';
299
-
300
- /**
301
- * Generate Mustache Template inheritance block function PHP source.
302
- *
303
- * @param array $nodes Array of child tokens
304
- *
305
- * @return string key of new block function
306
- */
307
- private function block($nodes)
308
- {
309
- $code = $this->walk($nodes, 0);
310
- $key = ucfirst(md5($code));
311
-
312
- if (!isset($this->blocks[$key])) {
313
- $this->blocks[$key] = sprintf($this->prepare(self::BLOCK_FUNCTION, 0), $key, $code);
314
- }
315
-
316
- return $key;
317
- }
318
-
319
- const SECTION_CALL = '
320
- // %s section
321
- $value = $context->%s(%s);%s
322
- $buffer .= $this->section%s($context, $indent, $value);
323
- ';
324
-
325
- const SECTION = '
326
- private function section%s(Mustache_Context $context, $indent, $value)
327
- {
328
- $buffer = \'\';
329
- if (%s) {
330
- $source = %s;
331
- $result = call_user_func($value, $source, %s);
332
- if (strpos($result, \'{{\') === false) {
333
- $buffer .= $result;
334
- } else {
335
- $buffer .= $this->mustache
336
- ->loadLambda((string) $result%s)
337
- ->renderInternal($context);
338
- }
339
- } elseif (!empty($value)) {
340
- $values = $this->isIterable($value) ? $value : array($value);
341
- foreach ($values as $value) {
342
- $context->push($value);
343
- %s
344
- $context->pop();
345
- }
346
- }
347
-
348
- return $buffer;
349
- }
350
- ';
351
-
352
- /**
353
- * Generate Mustache Template section PHP source.
354
- *
355
- * @param array $nodes Array of child tokens
356
- * @param string $id Section name
357
- * @param string[] $filters Array of filters
358
- * @param int $start Section start offset
359
- * @param int $end Section end offset
360
- * @param string $otag Current Mustache opening tag
361
- * @param string $ctag Current Mustache closing tag
362
- * @param int $level
363
- * @param bool $arg (default: false)
364
- *
365
- * @return string Generated section PHP source code
366
- */
367
- private function section($nodes, $id, $filters, $start, $end, $otag, $ctag, $level, $arg = false)
368
- {
369
- $source = var_export(substr($this->source, $start, $end - $start), true);
370
- $callable = $this->getCallable();
371
-
372
- if ($otag !== '{{' || $ctag !== '}}') {
373
- $delimTag = var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
374
- $helper = sprintf('$this->lambdaHelper->withDelimiters(%s)', $delimTag);
375
- $delims = ', ' . $delimTag;
376
- } else {
377
- $helper = '$this->lambdaHelper';
378
- $delims = '';
379
- }
380
-
381
- $key = ucfirst(md5($delims . "\n" . $source));
382
-
383
- if (!isset($this->sections[$key])) {
384
- $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $helper, $delims, $this->walk($nodes, 2));
385
- }
386
-
387
- if ($arg === true) {
388
- return $key;
389
- } else {
390
- $method = $this->getFindMethod($id);
391
- $id = var_export($id, true);
392
- $filters = $this->getFilters($filters, $level);
393
-
394
- return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
395
- }
396
- }
397
-
398
- const INVERTED_SECTION = '
399
- // %s inverted section
400
- $value = $context->%s(%s);%s
401
- if (empty($value)) {
402
- %s
403
- }
404
- ';
405
-
406
- /**
407
- * Generate Mustache Template inverted section PHP source.
408
- *
409
- * @param array $nodes Array of child tokens
410
- * @param string $id Section name
411
- * @param string[] $filters Array of filters
412
- * @param int $level
413
- *
414
- * @return string Generated inverted section PHP source code
415
- */
416
- private function invertedSection($nodes, $id, $filters, $level)
417
- {
418
- $method = $this->getFindMethod($id);
419
- $id = var_export($id, true);
420
- $filters = $this->getFilters($filters, $level);
421
-
422
- return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
423
- }
424
-
425
- const PARTIAL_INDENT = ', $indent . %s';
426
- const PARTIAL = '
427
- if ($partial = $this->mustache->loadPartial(%s)) {
428
- $buffer .= $partial->renderInternal($context%s);
429
- }
430
- ';
431
-
432
- /**
433
- * Generate Mustache Template partial call PHP source.
434
- *
435
- * @param string $id Partial name
436
- * @param string $indent Whitespace indent to apply to partial
437
- * @param int $level
438
- *
439
- * @return string Generated partial call PHP source code
440
- */
441
- private function partial($id, $indent, $level)
442
- {
443
- if ($indent !== '') {
444
- $indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
445
- } else {
446
- $indentParam = '';
447
- }
448
-
449
- return sprintf(
450
- $this->prepare(self::PARTIAL, $level),
451
- var_export($id, true),
452
- $indentParam
453
- );
454
- }
455
-
456
- const PARENT = '
457
- %s
458
-
459
- if ($parent = $this->mustache->LoadPartial(%s)) {
460
- $context->pushBlockContext($newContext);
461
- $buffer .= $parent->renderInternal($context, $indent);
462
- $context->popBlockContext();
463
- }
464
- ';
465
-
466
- /**
467
- * Generate Mustache Template inheritance parent call PHP source.
468
- *
469
- * @param string $id Parent tag name
470
- * @param string $indent Whitespace indent to apply to parent
471
- * @param array $children Child nodes
472
- * @param int $level
473
- *
474
- * @return string Generated PHP source code
475
- */
476
- private function parent($id, $indent, array $children, $level)
477
- {
478
- $realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
479
-
480
- return sprintf(
481
- $this->prepare(self::PARENT, $level),
482
- $this->walk($realChildren, $level),
483
- var_export($id, true),
484
- var_export($indent, true)
485
- );
486
- }
487
-
488
- /**
489
- * Helper method for filtering out non-block-arg tokens.
490
- *
491
- * @param array $node
492
- *
493
- * @return bool True if $node is a block arg token.
494
- */
495
- private static function onlyBlockArgs(array $node)
496
- {
497
- return $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_BLOCK_ARG;
498
- }
499
-
500
- const VARIABLE = '
501
- $value = $this->resolveValue($context->%s(%s), $context);%s
502
- $buffer .= %s%s;
503
- ';
504
-
505
- /**
506
- * Generate Mustache Template variable interpolation PHP source.
507
- *
508
- * @param string $id Variable name
509
- * @param string[] $filters Array of filters
510
- * @param bool $escape Escape the variable value for output?
511
- * @param int $level
512
- *
513
- * @return string Generated variable interpolation PHP source
514
- */
515
- private function variable($id, $filters, $escape, $level)
516
- {
517
- $method = $this->getFindMethod($id);
518
- $id = ($method !== 'last') ? var_export($id, true) : '';
519
- $filters = $this->getFilters($filters, $level);
520
- $value = $escape ? $this->getEscape() : '$value';
521
-
522
- return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
523
- }
524
-
525
- const FILTER = '
526
- $filter = $context->%s(%s);
527
- if (!(%s)) {
528
- throw new Mustache_Exception_UnknownFilterException(%s);
529
- }
530
- $value = call_user_func($filter, $value);%s
531
- ';
532
-
533
- /**
534
- * Generate Mustache Template variable filtering PHP source.
535
- *
536
- * @param string[] $filters Array of filters
537
- * @param int $level
538
- *
539
- * @return string Generated filter PHP source
540
- */
541
- private function getFilters(array $filters, $level)
542
- {
543
- if (empty($filters)) {
544
- return '';
545
- }
546
-
547
- $name = array_shift($filters);
548
- $method = $this->getFindMethod($name);
549
- $filter = ($method !== 'last') ? var_export($name, true) : '';
550
- $callable = $this->getCallable('$filter');
551
- $msg = var_export($name, true);
552
-
553
- return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilters($filters, $level));
554
- }
555
-
556
- const LINE = '$buffer .= "\n";';
557
- const TEXT = '$buffer .= %s%s;';
558
-
559
- /**
560
- * Generate Mustache Template output Buffer call PHP source.
561
- *
562
- * @param string $text
563
- * @param int $level
564
- *
565
- * @return string Generated output Buffer call PHP source
566
- */
567
- private function text($text, $level)
568
- {
569
- $indentNextLine = (substr($text, -1) === "\n");
570
- $code = sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true));
571
- $this->indentNextLine = $indentNextLine;
572
-
573
- return $code;
574
- }
575
-
576
- /**
577
- * Prepare PHP source code snippet for output.
578
- *
579
- * @param string $text
580
- * @param int $bonus Additional indent level (default: 0)
581
- * @param bool $prependNewline Prepend a newline to the snippet? (default: true)
582
- * @param bool $appendNewline Append a newline to the snippet? (default: false)
583
- *
584
- * @return string PHP source code snippet
585
- */
586
- private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false)
587
- {
588
- $text = ($prependNewline ? "\n" : '') . trim($text);
589
- if ($prependNewline) {
590
- $bonus++;
591
- }
592
- if ($appendNewline) {
593
- $text .= "\n";
594
- }
595
-
596
- return preg_replace("/\n( {8})?/", "\n" . str_repeat(' ', $bonus * 4), $text);
597
- }
598
-
599
- const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)';
600
- const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)';
601
-
602
- /**
603
- * Get the current escaper.
604
- *
605
- * @param string $value (default: '$value')
606
- *
607
- * @return string Either a custom callback, or an inline call to `htmlspecialchars`
608
- */
609
- private function getEscape($value = '$value')
610
- {
611
- if ($this->customEscape) {
612
- return sprintf(self::CUSTOM_ESCAPE, $value);
613
- }
614
-
615
- return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
616
- }
617
-
618
- /**
619
- * Select the appropriate Context `find` method for a given $id.
620
- *
621
- * The return value will be one of `find`, `findDot` or `last`.
622
- *
623
- * @see Mustache_Context::find
624
- * @see Mustache_Context::findDot
625
- * @see Mustache_Context::last
626
- *
627
- * @param string $id Variable name
628
- *
629
- * @return string `find` method name
630
- */
631
- private function getFindMethod($id)
632
- {
633
- if ($id === '.') {
634
- return 'last';
635
- }
636
-
637
- if (isset($this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) && $this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) {
638
- if (substr($id, 0, 1) === '.') {
639
- return 'findAnchoredDot';
640
- }
641
- }
642
-
643
- if (strpos($id, '.') === false) {
644
- return 'find';
645
- }
646
-
647
- return 'findDot';
648
- }
649
-
650
- const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
651
- const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
652
-
653
- /**
654
- * Helper function to compile strict vs lax "is callable" logic.
655
- *
656
- * @param string $variable (default: '$value')
657
- *
658
- * @return string "is callable" logic
659
- */
660
- private function getCallable($variable = '$value')
661
- {
662
- $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
663
-
664
- return sprintf($tpl, $variable, $variable);
665
- }
666
-
667
- const LINE_INDENT = '$indent . ';
668
-
669
- /**
670
- * Get the current $indent prefix to write to the buffer.
671
- *
672
- * @return string "$indent . " or ""
673
- */
674
- private function flushIndent()
675
- {
676
- if (!$this->indentNextLine) {
677
- return '';
678
- }
679
-
680
- $this->indentNextLine = false;
681
-
682
- return self::LINE_INDENT;
683
- }
684
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Compiler class.
14
+ *
15
+ * This class is responsible for turning a Mustache token parse tree into normal PHP source code.
16
+ */
17
+ class Mustache_Compiler
18
+ {
19
+ private $pragmas;
20
+ private $defaultPragmas = array();
21
+ private $sections;
22
+ private $blocks;
23
+ private $source;
24
+ private $indentNextLine;
25
+ private $customEscape;
26
+ private $entityFlags;
27
+ private $charset;
28
+ private $strictCallables;
29
+
30
+ /**
31
+ * Compile a Mustache token parse tree into PHP source code.
32
+ *
33
+ * @param string $source Mustache Template source code
34
+ * @param string $tree Parse tree of Mustache tokens
35
+ * @param string $name Mustache Template class name
36
+ * @param bool $customEscape (default: false)
37
+ * @param string $charset (default: 'UTF-8')
38
+ * @param bool $strictCallables (default: false)
39
+ * @param int $entityFlags (default: ENT_COMPAT)
40
+ *
41
+ * @return string Generated PHP source code
42
+ */
43
+ public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
44
+ {
45
+ $this->pragmas = $this->defaultPragmas;
46
+ $this->sections = array();
47
+ $this->blocks = array();
48
+ $this->source = $source;
49
+ $this->indentNextLine = true;
50
+ $this->customEscape = $customEscape;
51
+ $this->entityFlags = $entityFlags;
52
+ $this->charset = $charset;
53
+ $this->strictCallables = $strictCallables;
54
+
55
+ return $this->writeCode($tree, $name);
56
+ }
57
+
58
+ /**
59
+ * Enable pragmas across all templates, regardless of the presence of pragma
60
+ * tags in the individual templates.
61
+ *
62
+ * @internal Users should set global pragmas in Mustache_Engine, not here :)
63
+ *
64
+ * @param string[] $pragmas
65
+ */
66
+ public function setPragmas(array $pragmas)
67
+ {
68
+ $this->pragmas = array();
69
+ foreach ($pragmas as $pragma) {
70
+ $this->pragmas[$pragma] = true;
71
+ }
72
+ $this->defaultPragmas = $this->pragmas;
73
+ }
74
+
75
+ /**
76
+ * Helper function for walking the Mustache token parse tree.
77
+ *
78
+ * @throws Mustache_Exception_SyntaxException upon encountering unknown token types.
79
+ *
80
+ * @param array $tree Parse tree of Mustache tokens
81
+ * @param int $level (default: 0)
82
+ *
83
+ * @return string Generated PHP source code
84
+ */
85
+ private function walk(array $tree, $level = 0)
86
+ {
87
+ $code = '';
88
+ $level++;
89
+ foreach ($tree as $node) {
90
+ switch ($node[Mustache_Tokenizer::TYPE]) {
91
+ case Mustache_Tokenizer::T_PRAGMA:
92
+ $this->pragmas[$node[Mustache_Tokenizer::NAME]] = true;
93
+ break;
94
+
95
+ case Mustache_Tokenizer::T_SECTION:
96
+ $code .= $this->section(
97
+ $node[Mustache_Tokenizer::NODES],
98
+ $node[Mustache_Tokenizer::NAME],
99
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
100
+ $node[Mustache_Tokenizer::INDEX],
101
+ $node[Mustache_Tokenizer::END],
102
+ $node[Mustache_Tokenizer::OTAG],
103
+ $node[Mustache_Tokenizer::CTAG],
104
+ $level
105
+ );
106
+ break;
107
+
108
+ case Mustache_Tokenizer::T_INVERTED:
109
+ $code .= $this->invertedSection(
110
+ $node[Mustache_Tokenizer::NODES],
111
+ $node[Mustache_Tokenizer::NAME],
112
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
113
+ $level
114
+ );
115
+ break;
116
+
117
+ case Mustache_Tokenizer::T_PARTIAL:
118
+ $code .= $this->partial(
119
+ $node[Mustache_Tokenizer::NAME],
120
+ isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
121
+ $level
122
+ );
123
+ break;
124
+
125
+ case Mustache_Tokenizer::T_PARENT:
126
+ $code .= $this->parent(
127
+ $node[Mustache_Tokenizer::NAME],
128
+ isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
129
+ $node[Mustache_Tokenizer::NODES],
130
+ $level
131
+ );
132
+ break;
133
+
134
+ case Mustache_Tokenizer::T_BLOCK_ARG:
135
+ $code .= $this->blockArg(
136
+ $node[Mustache_Tokenizer::NODES],
137
+ $node[Mustache_Tokenizer::NAME],
138
+ $node[Mustache_Tokenizer::INDEX],
139
+ $node[Mustache_Tokenizer::END],
140
+ $node[Mustache_Tokenizer::OTAG],
141
+ $node[Mustache_Tokenizer::CTAG],
142
+ $level
143
+ );
144
+ break;
145
+
146
+ case Mustache_Tokenizer::T_BLOCK_VAR:
147
+ $code .= $this->blockVar(
148
+ $node[Mustache_Tokenizer::NODES],
149
+ $node[Mustache_Tokenizer::NAME],
150
+ $node[Mustache_Tokenizer::INDEX],
151
+ $node[Mustache_Tokenizer::END],
152
+ $node[Mustache_Tokenizer::OTAG],
153
+ $node[Mustache_Tokenizer::CTAG],
154
+ $level
155
+ );
156
+ break;
157
+
158
+ case Mustache_Tokenizer::T_COMMENT:
159
+ break;
160
+
161
+ case Mustache_Tokenizer::T_ESCAPED:
162
+ case Mustache_Tokenizer::T_UNESCAPED:
163
+ case Mustache_Tokenizer::T_UNESCAPED_2:
164
+ $code .= $this->variable(
165
+ $node[Mustache_Tokenizer::NAME],
166
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
167
+ $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_ESCAPED,
168
+ $level
169
+ );
170
+ break;
171
+
172
+ case Mustache_Tokenizer::T_TEXT:
173
+ $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
174
+ break;
175
+
176
+ default:
177
+ throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node);
178
+ }
179
+ }
180
+
181
+ return $code;
182
+ }
183
+
184
+ const KLASS = '<?php
185
+
186
+ class %s extends Mustache_Template
187
+ {
188
+ private $lambdaHelper;%s
189
+
190
+ public function renderInternal(Mustache_Context $context, $indent = \'\')
191
+ {
192
+ $this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
193
+ $buffer = \'\';
194
+ $newContext = array();
195
+ %s
196
+
197
+ return $buffer;
198
+ }
199
+ %s
200
+ %s
201
+ }';
202
+
203
+ const KLASS_NO_LAMBDAS = '<?php
204
+
205
+ class %s extends Mustache_Template
206
+ {%s
207
+ public function renderInternal(Mustache_Context $context, $indent = \'\')
208
+ {
209
+ $buffer = \'\';
210
+ $newContext = array();
211
+ %s
212
+
213
+ return $buffer;
214
+ }
215
+ }';
216
+
217
+ const STRICT_CALLABLE = 'protected $strictCallables = true;';
218
+
219
+ /**
220
+ * Generate Mustache Template class PHP source.
221
+ *
222
+ * @param array $tree Parse tree of Mustache tokens
223
+ * @param string $name Mustache Template class name
224
+ *
225
+ * @return string Generated PHP source code
226
+ */
227
+ private function writeCode($tree, $name)
228
+ {
229
+ $code = $this->walk($tree);
230
+ $sections = implode("\n", $this->sections);
231
+ $blocks = implode("\n", $this->blocks);
232
+ $klass = empty($this->sections) && empty($this->blocks) ? self::KLASS_NO_LAMBDAS : self::KLASS;
233
+
234
+ $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
235
+
236
+ return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections, $blocks);
237
+ }
238
+
239
+ const BLOCK_VAR = '
240
+ $blockFunction = $context->findInBlock(%s);
241
+ if (is_callable($blockFunction)) {
242
+ $buffer .= call_user_func($blockFunction, $context);
243
+ } else {%s
244
+ }
245
+ ';
246
+
247
+ /**
248
+ * Generate Mustache Template inheritance block variable PHP source.
249
+ *
250
+ * @param array $nodes Array of child tokens
251
+ * @param string $id Section name
252
+ * @param int $start Section start offset
253
+ * @param int $end Section end offset
254
+ * @param string $otag Current Mustache opening tag
255
+ * @param string $ctag Current Mustache closing tag
256
+ * @param int $level
257
+ *
258
+ * @return string Generated PHP source code
259
+ */
260
+ private function blockVar($nodes, $id, $start, $end, $otag, $ctag, $level)
261
+ {
262
+ $id = var_export($id, true);
263
+
264
+ return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, $level));
265
+ }
266
+
267
+ const BLOCK_ARG = '$newContext[%s] = array($this, \'block%s\');';
268
+
269
+ /**
270
+ * Generate Mustache Template inheritance block argument PHP source.
271
+ *
272
+ * @param array $nodes Array of child tokens
273
+ * @param string $id Section name
274
+ * @param int $start Section start offset
275
+ * @param int $end Section end offset
276
+ * @param string $otag Current Mustache opening tag
277
+ * @param string $ctag Current Mustache closing tag
278
+ * @param int $level
279
+ *
280
+ * @return string Generated PHP source code
281
+ */
282
+ private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
283
+ {
284
+ $key = $this->block($nodes);
285
+ $keystr = var_export($key, true);
286
+ $id = var_export($id, true);
287
+
288
+ return sprintf($this->prepare(self::BLOCK_ARG, 1), $id, $key);
289
+ }
290
+
291
+ const BLOCK_FUNCTION = '
292
+ public function block%s($context)
293
+ {
294
+ $indent = $buffer = \'\';%s
295
+
296
+ return $buffer;
297
+ }
298
+ ';
299
+
300
+ /**
301
+ * Generate Mustache Template inheritance block function PHP source.
302
+ *
303
+ * @param array $nodes Array of child tokens
304
+ *
305
+ * @return string key of new block function
306
+ */
307
+ private function block($nodes)
308
+ {
309
+ $code = $this->walk($nodes, 0);
310
+ $key = ucfirst(md5($code));
311
+
312
+ if (!isset($this->blocks[$key])) {
313
+ $this->blocks[$key] = sprintf($this->prepare(self::BLOCK_FUNCTION, 0), $key, $code);
314
+ }
315
+
316
+ return $key;
317
+ }
318
+
319
+ const SECTION_CALL = '
320
+ // %s section
321
+ $value = $context->%s(%s);%s
322
+ $buffer .= $this->section%s($context, $indent, $value);
323
+ ';
324
+
325
+ const SECTION = '
326
+ private function section%s(Mustache_Context $context, $indent, $value)
327
+ {
328
+ $buffer = \'\';
329
+ if (%s) {
330
+ $source = %s;
331
+ $result = call_user_func($value, $source, %s);
332
+ if (strpos($result, \'{{\') === false) {
333
+ $buffer .= $result;
334
+ } else {
335
+ $buffer .= $this->mustache
336
+ ->loadLambda((string) $result%s)
337
+ ->renderInternal($context);
338
+ }
339
+ } elseif (!empty($value)) {
340
+ $values = $this->isIterable($value) ? $value : array($value);
341
+ foreach ($values as $value) {
342
+ $context->push($value);
343
+ %s
344
+ $context->pop();
345
+ }
346
+ }
347
+
348
+ return $buffer;
349
+ }
350
+ ';
351
+
352
+ /**
353
+ * Generate Mustache Template section PHP source.
354
+ *
355
+ * @param array $nodes Array of child tokens
356
+ * @param string $id Section name
357
+ * @param string[] $filters Array of filters
358
+ * @param int $start Section start offset
359
+ * @param int $end Section end offset
360
+ * @param string $otag Current Mustache opening tag
361
+ * @param string $ctag Current Mustache closing tag
362
+ * @param int $level
363
+ * @param bool $arg (default: false)
364
+ *
365
+ * @return string Generated section PHP source code
366
+ */
367
+ private function section($nodes, $id, $filters, $start, $end, $otag, $ctag, $level, $arg = false)
368
+ {
369
+ $source = var_export(substr($this->source, $start, $end - $start), true);
370
+ $callable = $this->getCallable();
371
+
372
+ if ($otag !== '{{' || $ctag !== '}}') {
373
+ $delimTag = var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
374
+ $helper = sprintf('$this->lambdaHelper->withDelimiters(%s)', $delimTag);
375
+ $delims = ', ' . $delimTag;
376
+ } else {
377
+ $helper = '$this->lambdaHelper';
378
+ $delims = '';
379
+ }
380
+
381
+ $key = ucfirst(md5($delims . "\n" . $source));
382
+
383
+ if (!isset($this->sections[$key])) {
384
+ $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $helper, $delims, $this->walk($nodes, 2));
385
+ }
386
+
387
+ if ($arg === true) {
388
+ return $key;
389
+ } else {
390
+ $method = $this->getFindMethod($id);
391
+ $id = var_export($id, true);
392
+ $filters = $this->getFilters($filters, $level);
393
+
394
+ return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
395
+ }
396
+ }
397
+
398
+ const INVERTED_SECTION = '
399
+ // %s inverted section
400
+ $value = $context->%s(%s);%s
401
+ if (empty($value)) {
402
+ %s
403
+ }
404
+ ';
405
+
406
+ /**
407
+ * Generate Mustache Template inverted section PHP source.
408
+ *
409
+ * @param array $nodes Array of child tokens
410
+ * @param string $id Section name
411
+ * @param string[] $filters Array of filters
412
+ * @param int $level
413
+ *
414
+ * @return string Generated inverted section PHP source code
415
+ */
416
+ private function invertedSection($nodes, $id, $filters, $level)
417
+ {
418
+ $method = $this->getFindMethod($id);
419
+ $id = var_export($id, true);
420
+ $filters = $this->getFilters($filters, $level);
421
+
422
+ return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
423
+ }
424
+
425
+ const PARTIAL_INDENT = ', $indent . %s';
426
+ const PARTIAL = '
427
+ if ($partial = $this->mustache->loadPartial(%s)) {
428
+ $buffer .= $partial->renderInternal($context%s);
429
+ }
430
+ ';
431
+
432
+ /**
433
+ * Generate Mustache Template partial call PHP source.
434
+ *
435
+ * @param string $id Partial name
436
+ * @param string $indent Whitespace indent to apply to partial
437
+ * @param int $level
438
+ *
439
+ * @return string Generated partial call PHP source code
440
+ */
441
+ private function partial($id, $indent, $level)
442
+ {
443
+ if ($indent !== '') {
444
+ $indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
445
+ } else {
446
+ $indentParam = '';
447
+ }
448
+
449
+ return sprintf(
450
+ $this->prepare(self::PARTIAL, $level),
451
+ var_export($id, true),
452
+ $indentParam
453
+ );
454
+ }
455
+
456
+ const PARENT = '
457
+ %s
458
+
459
+ if ($parent = $this->mustache->LoadPartial(%s)) {
460
+ $context->pushBlockContext($newContext);
461
+ $buffer .= $parent->renderInternal($context, $indent);
462
+ $context->popBlockContext();
463
+ }
464
+ ';
465
+
466
+ /**
467
+ * Generate Mustache Template inheritance parent call PHP source.
468
+ *
469
+ * @param string $id Parent tag name
470
+ * @param string $indent Whitespace indent to apply to parent
471
+ * @param array $children Child nodes
472
+ * @param int $level
473
+ *
474
+ * @return string Generated PHP source code
475
+ */
476
+ private function parent($id, $indent, array $children, $level)
477
+ {
478
+ $realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
479
+
480
+ return sprintf(
481
+ $this->prepare(self::PARENT, $level),
482
+ $this->walk($realChildren, $level),
483
+ var_export($id, true),
484
+ var_export($indent, true)
485
+ );
486
+ }
487
+
488
+ /**
489
+ * Helper method for filtering out non-block-arg tokens.
490
+ *
491
+ * @param array $node
492
+ *
493
+ * @return bool True if $node is a block arg token.
494
+ */
495
+ private static function onlyBlockArgs(array $node)
496
+ {
497
+ return $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_BLOCK_ARG;
498
+ }
499
+
500
+ const VARIABLE = '
501
+ $value = $this->resolveValue($context->%s(%s), $context);%s
502
+ $buffer .= %s%s;
503
+ ';
504
+
505
+ /**
506
+ * Generate Mustache Template variable interpolation PHP source.
507
+ *
508
+ * @param string $id Variable name
509
+ * @param string[] $filters Array of filters
510
+ * @param bool $escape Escape the variable value for output?
511
+ * @param int $level
512
+ *
513
+ * @return string Generated variable interpolation PHP source
514
+ */
515
+ private function variable($id, $filters, $escape, $level)
516
+ {
517
+ $method = $this->getFindMethod($id);
518
+ $id = ($method !== 'last') ? var_export($id, true) : '';
519
+ $filters = $this->getFilters($filters, $level);
520
+ $value = $escape ? $this->getEscape() : '$value';
521
+
522
+ return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
523
+ }
524
+
525
+ const FILTER = '
526
+ $filter = $context->%s(%s);
527
+ if (!(%s)) {
528
+ throw new Mustache_Exception_UnknownFilterException(%s);
529
+ }
530
+ $value = call_user_func($filter, $value);%s
531
+ ';
532
+
533
+ /**
534
+ * Generate Mustache Template variable filtering PHP source.
535
+ *
536
+ * @param string[] $filters Array of filters
537
+ * @param int $level
538
+ *
539
+ * @return string Generated filter PHP source
540
+ */
541
+ private function getFilters(array $filters, $level)
542
+ {
543
+ if (empty($filters)) {
544
+ return '';
545
+ }
546
+
547
+ $name = array_shift($filters);
548
+ $method = $this->getFindMethod($name);
549
+ $filter = ($method !== 'last') ? var_export($name, true) : '';
550
+ $callable = $this->getCallable('$filter');
551
+ $msg = var_export($name, true);
552
+
553
+ return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilters($filters, $level));
554
+ }
555
+
556
+ const LINE = '$buffer .= "\n";';
557
+ const TEXT = '$buffer .= %s%s;';
558
+
559
+ /**
560
+ * Generate Mustache Template output Buffer call PHP source.
561
+ *
562
+ * @param string $text
563
+ * @param int $level
564
+ *
565
+ * @return string Generated output Buffer call PHP source
566
+ */
567
+ private function text($text, $level)
568
+ {
569
+ $indentNextLine = (substr($text, -1) === "\n");
570
+ $code = sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true));
571
+ $this->indentNextLine = $indentNextLine;
572
+
573
+ return $code;
574
+ }
575
+
576
+ /**
577
+ * Prepare PHP source code snippet for output.
578
+ *
579
+ * @param string $text
580
+ * @param int $bonus Additional indent level (default: 0)
581
+ * @param bool $prependNewline Prepend a newline to the snippet? (default: true)
582
+ * @param bool $appendNewline Append a newline to the snippet? (default: false)
583
+ *
584
+ * @return string PHP source code snippet
585
+ */
586
+ private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false)
587
+ {
588
+ $text = ($prependNewline ? "\n" : '') . trim($text);
589
+ if ($prependNewline) {
590
+ $bonus++;
591
+ }
592
+ if ($appendNewline) {
593
+ $text .= "\n";
594
+ }
595
+
596
+ return preg_replace("/\n( {8})?/", "\n" . str_repeat(' ', $bonus * 4), $text);
597
+ }
598
+
599
+ const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)';
600
+ const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)';
601
+
602
+ /**
603
+ * Get the current escaper.
604
+ *
605
+ * @param string $value (default: '$value')
606
+ *
607
+ * @return string Either a custom callback, or an inline call to `htmlspecialchars`
608
+ */
609
+ private function getEscape($value = '$value')
610
+ {
611
+ if ($this->customEscape) {
612
+ return sprintf(self::CUSTOM_ESCAPE, $value);
613
+ }
614
+
615
+ return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
616
+ }
617
+
618
+ /**
619
+ * Select the appropriate Context `find` method for a given $id.
620
+ *
621
+ * The return value will be one of `find`, `findDot` or `last`.
622
+ *
623
+ * @see Mustache_Context::find
624
+ * @see Mustache_Context::findDot
625
+ * @see Mustache_Context::last
626
+ *
627
+ * @param string $id Variable name
628
+ *
629
+ * @return string `find` method name
630
+ */
631
+ private function getFindMethod($id)
632
+ {
633
+ if ($id === '.') {
634
+ return 'last';
635
+ }
636
+
637
+ if (isset($this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) && $this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) {
638
+ if (substr($id, 0, 1) === '.') {
639
+ return 'findAnchoredDot';
640
+ }
641
+ }
642
+
643
+ if (strpos($id, '.') === false) {
644
+ return 'find';
645
+ }
646
+
647
+ return 'findDot';
648
+ }
649
+
650
+ const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
651
+ const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
652
+
653
+ /**
654
+ * Helper function to compile strict vs lax "is callable" logic.
655
+ *
656
+ * @param string $variable (default: '$value')
657
+ *
658
+ * @return string "is callable" logic
659
+ */
660
+ private function getCallable($variable = '$value')
661
+ {
662
+ $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
663
+
664
+ return sprintf($tpl, $variable, $variable);
665
+ }
666
+
667
+ const LINE_INDENT = '$indent . ';
668
+
669
+ /**
670
+ * Get the current $indent prefix to write to the buffer.
671
+ *
672
+ * @return string "$indent . " or ""
673
+ */
674
+ private function flushIndent()
675
+ {
676
+ if (!$this->indentNextLine) {
677
+ return '';
678
+ }
679
+
680
+ $this->indentNextLine = false;
681
+
682
+ return self::LINE_INDENT;
683
+ }
684
+ }
lib/php/Mustache/Context.php CHANGED
@@ -1,242 +1,242 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Template rendering Context.
14
- */
15
- class Mustache_Context
16
- {
17
- private $stack = array();
18
- private $blockStack = array();
19
-
20
- /**
21
- * Mustache rendering Context constructor.
22
- *
23
- * @param mixed $context Default rendering context (default: null)
24
- */
25
- public function __construct($context = null)
26
- {
27
- if ($context !== null) {
28
- $this->stack = array($context);
29
- }
30
- }
31
-
32
- /**
33
- * Push a new Context frame onto the stack.
34
- *
35
- * @param mixed $value Object or array to use for context
36
- */
37
- public function push($value)
38
- {
39
- array_push($this->stack, $value);
40
- }
41
-
42
- /**
43
- * Push a new Context frame onto the block context stack.
44
- *
45
- * @param mixed $value Object or array to use for block context
46
- */
47
- public function pushBlockContext($value)
48
- {
49
- array_push($this->blockStack, $value);
50
- }
51
-
52
- /**
53
- * Pop the last Context frame from the stack.
54
- *
55
- * @return mixed Last Context frame (object or array)
56
- */
57
- public function pop()
58
- {
59
- return array_pop($this->stack);
60
- }
61
-
62
- /**
63
- * Pop the last block Context frame from the stack.
64
- *
65
- * @return mixed Last block Context frame (object or array)
66
- */
67
- public function popBlockContext()
68
- {
69
- return array_pop($this->blockStack);
70
- }
71
-
72
- /**
73
- * Get the last Context frame.
74
- *
75
- * @return mixed Last Context frame (object or array)
76
- */
77
- public function last()
78
- {
79
- return end($this->stack);
80
- }
81
-
82
- /**
83
- * Find a variable in the Context stack.
84
- *
85
- * Starting with the last Context frame (the context of the innermost section), and working back to the top-level
86
- * rendering context, look for a variable with the given name:
87
- *
88
- * * If the Context frame is an associative array which contains the key $id, returns the value of that element.
89
- * * If the Context frame is an object, this will check first for a public method, then a public property named
90
- * $id. Failing both of these, it will try `__isset` and `__get` magic methods.
91
- * * If a value named $id is not found in any Context frame, returns an empty string.
92
- *
93
- * @param string $id Variable name
94
- *
95
- * @return mixed Variable value, or '' if not found
96
- */
97
- public function find($id)
98
- {
99
- return $this->findVariableInStack($id, $this->stack);
100
- }
101
-
102
- /**
103
- * Find a 'dot notation' variable in the Context stack.
104
- *
105
- * Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
106
- * the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
107
- * result. For example, given the following context stack:
108
- *
109
- * $data = array(
110
- * 'name' => 'Fred',
111
- * 'child' => array(
112
- * 'name' => 'Bob'
113
- * ),
114
- * );
115
- *
116
- * ... and the Mustache following template:
117
- *
118
- * {{ child.name }}
119
- *
120
- * ... the `name` value is only searched for within the `child` value of the global Context, not within parent
121
- * Context frames.
122
- *
123
- * @param string $id Dotted variable selector
124
- *
125
- * @return mixed Variable value, or '' if not found
126
- */
127
- public function findDot($id)
128
- {
129
- $chunks = explode('.', $id);
130
- $first = array_shift($chunks);
131
- $value = $this->findVariableInStack($first, $this->stack);
132
-
133
- foreach ($chunks as $chunk) {
134
- if ($value === '') {
135
- return $value;
136
- }
137
-
138
- $value = $this->findVariableInStack($chunk, array($value));
139
- }
140
-
141
- return $value;
142
- }
143
-
144
- /**
145
- * Find an 'anchored dot notation' variable in the Context stack.
146
- *
147
- * This is the same as findDot(), except it looks in the top of the context
148
- * stack for the first value, rather than searching the whole context stack
149
- * and starting from there.
150
- *
151
- * @see Mustache_Context::findDot
152
- *
153
- * @throws Mustache_Exception_InvalidArgumentException if given an invalid anchored dot $id.
154
- *
155
- * @param string $id Dotted variable selector
156
- *
157
- * @return mixed Variable value, or '' if not found
158
- */
159
- public function findAnchoredDot($id)
160
- {
161
- $chunks = explode('.', $id);
162
- $first = array_shift($chunks);
163
- if ($first !== '') {
164
- throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected id for findAnchoredDot: %s', $id));
165
- }
166
-
167
- $value = $this->last();
168
-
169
- foreach ($chunks as $chunk) {
170
- if ($value === '') {
171
- return $value;
172
- }
173
-
174
- $value = $this->findVariableInStack($chunk, array($value));
175
- }
176
-
177
- return $value;
178
- }
179
-
180
- /**
181
- * Find an argument in the block context stack.
182
- *
183
- * @param string $id
184
- *
185
- * @return mixed Variable value, or '' if not found.
186
- */
187
- public function findInBlock($id)
188
- {
189
- foreach ($this->blockStack as $context) {
190
- if (array_key_exists($id, $context)) {
191
- return $context[$id];
192
- }
193
- }
194
-
195
- return '';
196
- }
197
-
198
- /**
199
- * Helper function to find a variable in the Context stack.
200
- *
201
- * @see Mustache_Context::find
202
- *
203
- * @param string $id Variable name
204
- * @param array $stack Context stack
205
- *
206
- * @return mixed Variable value, or '' if not found
207
- */
208
- private function findVariableInStack($id, array $stack)
209
- {
210
- for ($i = count($stack) - 1; $i >= 0; $i--) {
211
- $frame = &$stack[$i];
212
-
213
- switch (gettype($frame)) {
214
- case 'object':
215
- if (!($frame instanceof Closure)) {
216
- // Note that is_callable() *will not work here*
217
- // See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
218
- if (method_exists($frame, $id)) {
219
- return $frame->$id();
220
- }
221
-
222
- if (isset($frame->$id)) {
223
- return $frame->$id;
224
- }
225
-
226
- if ($frame instanceof ArrayAccess && isset($frame[$id])) {
227
- return $frame[$id];
228
- }
229
- }
230
- break;
231
-
232
- case 'array':
233
- if (array_key_exists($id, $frame)) {
234
- return $frame[$id];
235
- }
236
- break;
237
- }
238
- }
239
-
240
- return '';
241
- }
242
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Template rendering Context.
14
+ */
15
+ class Mustache_Context
16
+ {
17
+ private $stack = array();
18
+ private $blockStack = array();
19
+
20
+ /**
21
+ * Mustache rendering Context constructor.
22
+ *
23
+ * @param mixed $context Default rendering context (default: null)
24
+ */
25
+ public function __construct($context = null)
26
+ {
27
+ if ($context !== null) {
28
+ $this->stack = array($context);
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Push a new Context frame onto the stack.
34
+ *
35
+ * @param mixed $value Object or array to use for context
36
+ */
37
+ public function push($value)
38
+ {
39
+ array_push($this->stack, $value);
40
+ }
41
+
42
+ /**
43
+ * Push a new Context frame onto the block context stack.
44
+ *
45
+ * @param mixed $value Object or array to use for block context
46
+ */
47
+ public function pushBlockContext($value)
48
+ {
49
+ array_push($this->blockStack, $value);
50
+ }
51
+
52
+ /**
53
+ * Pop the last Context frame from the stack.
54
+ *
55
+ * @return mixed Last Context frame (object or array)
56
+ */
57
+ public function pop()
58
+ {
59
+ return array_pop($this->stack);
60
+ }
61
+
62
+ /**
63
+ * Pop the last block Context frame from the stack.
64
+ *
65
+ * @return mixed Last block Context frame (object or array)
66
+ */
67
+ public function popBlockContext()
68
+ {
69
+ return array_pop($this->blockStack);
70
+ }
71
+
72
+ /**
73
+ * Get the last Context frame.
74
+ *
75
+ * @return mixed Last Context frame (object or array)
76
+ */
77
+ public function last()
78
+ {
79
+ return end($this->stack);
80
+ }
81
+
82
+ /**
83
+ * Find a variable in the Context stack.
84
+ *
85
+ * Starting with the last Context frame (the context of the innermost section), and working back to the top-level
86
+ * rendering context, look for a variable with the given name:
87
+ *
88
+ * * If the Context frame is an associative array which contains the key $id, returns the value of that element.
89
+ * * If the Context frame is an object, this will check first for a public method, then a public property named
90
+ * $id. Failing both of these, it will try `__isset` and `__get` magic methods.
91
+ * * If a value named $id is not found in any Context frame, returns an empty string.
92
+ *
93
+ * @param string $id Variable name
94
+ *
95
+ * @return mixed Variable value, or '' if not found
96
+ */
97
+ public function find($id)
98
+ {
99
+ return $this->findVariableInStack($id, $this->stack);
100
+ }
101
+
102
+ /**
103
+ * Find a 'dot notation' variable in the Context stack.
104
+ *
105
+ * Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
106
+ * the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
107
+ * result. For example, given the following context stack:
108
+ *
109
+ * $data = array(
110
+ * 'name' => 'Fred',
111
+ * 'child' => array(
112
+ * 'name' => 'Bob'
113
+ * ),
114
+ * );
115
+ *
116
+ * ... and the Mustache following template:
117
+ *
118
+ * {{ child.name }}
119
+ *
120
+ * ... the `name` value is only searched for within the `child` value of the global Context, not within parent
121
+ * Context frames.
122
+ *
123
+ * @param string $id Dotted variable selector
124
+ *
125
+ * @return mixed Variable value, or '' if not found
126
+ */
127
+ public function findDot($id)
128
+ {
129
+ $chunks = explode('.', $id);
130
+ $first = array_shift($chunks);
131
+ $value = $this->findVariableInStack($first, $this->stack);
132
+
133
+ foreach ($chunks as $chunk) {
134
+ if ($value === '') {
135
+ return $value;
136
+ }
137
+
138
+ $value = $this->findVariableInStack($chunk, array($value));
139
+ }
140
+
141
+ return $value;
142
+ }
143
+
144
+ /**
145
+ * Find an 'anchored dot notation' variable in the Context stack.
146
+ *
147
+ * This is the same as findDot(), except it looks in the top of the context
148
+ * stack for the first value, rather than searching the whole context stack
149
+ * and starting from there.
150
+ *
151
+ * @see Mustache_Context::findDot
152
+ *
153
+ * @throws Mustache_Exception_InvalidArgumentException if given an invalid anchored dot $id.
154
+ *
155
+ * @param string $id Dotted variable selector
156
+ *
157
+ * @return mixed Variable value, or '' if not found
158
+ */
159
+ public function findAnchoredDot($id)
160
+ {
161
+ $chunks = explode('.', $id);
162
+ $first = array_shift($chunks);
163
+ if ($first !== '') {
164
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected id for findAnchoredDot: %s', $id));
165
+ }
166
+
167
+ $value = $this->last();
168
+
169
+ foreach ($chunks as $chunk) {
170
+ if ($value === '') {
171
+ return $value;
172
+ }
173
+
174
+ $value = $this->findVariableInStack($chunk, array($value));
175
+ }
176
+
177
+ return $value;
178
+ }
179
+
180
+ /**
181
+ * Find an argument in the block context stack.
182
+ *
183
+ * @param string $id
184
+ *
185
+ * @return mixed Variable value, or '' if not found.
186
+ */
187
+ public function findInBlock($id)
188
+ {
189
+ foreach ($this->blockStack as $context) {
190
+ if (array_key_exists($id, $context)) {
191
+ return $context[$id];
192
+ }
193
+ }
194
+
195
+ return '';
196
+ }
197
+
198
+ /**
199
+ * Helper function to find a variable in the Context stack.
200
+ *
201
+ * @see Mustache_Context::find
202
+ *
203
+ * @param string $id Variable name
204
+ * @param array $stack Context stack
205
+ *
206
+ * @return mixed Variable value, or '' if not found
207
+ */
208
+ private function findVariableInStack($id, array $stack)
209
+ {
210
+ for ($i = count($stack) - 1; $i >= 0; $i--) {
211
+ $frame = &$stack[$i];
212
+
213
+ switch (gettype($frame)) {
214
+ case 'object':
215
+ if (!($frame instanceof Closure)) {
216
+ // Note that is_callable() *will not work here*
217
+ // See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
218
+ if (method_exists($frame, $id)) {
219
+ return $frame->$id();
220
+ }
221
+
222
+ if (isset($frame->$id)) {
223
+ return $frame->$id;
224
+ }
225
+
226
+ if ($frame instanceof ArrayAccess && isset($frame[$id])) {
227
+ return $frame[$id];
228
+ }
229
+ }
230
+ break;
231
+
232
+ case 'array':
233
+ if (array_key_exists($id, $frame)) {
234
+ return $frame[$id];
235
+ }
236
+ break;
237
+ }
238
+ }
239
+
240
+ return '';
241
+ }
242
+ }
lib/php/Mustache/Engine.php CHANGED
@@ -1,787 +1,787 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * A Mustache implementation in PHP.
14
- *
15
- * {@link http://defunkt.github.com/mustache}
16
- *
17
- * Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
18
- * logic from template files. In fact, it is not even possible to embed logic in the template.
19
- *
20
- * This is very, very rad.
21
- *
22
- * @author Justin Hileman {@link http://justinhileman.com}
23
- */
24
- class Mustache_Engine
25
- {
26
- const VERSION = '2.10.0';
27
- const SPEC_VERSION = '1.1.2';
28
-
29
- const PRAGMA_FILTERS = 'FILTERS';
30
- const PRAGMA_BLOCKS = 'BLOCKS';
31
- const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
32
-
33
- // Known pragmas
34
- private static $knownPragmas = array(
35
- self::PRAGMA_FILTERS => true,
36
- self::PRAGMA_BLOCKS => true,
37
- self::PRAGMA_ANCHORED_DOT => true,
38
- );
39
-
40
- // Template cache
41
- private $templates = array();
42
-
43
- // Environment
44
- private $templateClassPrefix = '__Mustache_';
45
- private $cache;
46
- private $lambdaCache;
47
- private $cacheLambdaTemplates = false;
48
- private $loader;
49
- private $partialsLoader;
50
- private $helpers;
51
- private $escape;
52
- private $entityFlags = ENT_COMPAT;
53
- private $charset = 'UTF-8';
54
- private $logger;
55
- private $strictCallables = false;
56
- private $pragmas = array();
57
-
58
- // Services
59
- private $tokenizer;
60
- private $parser;
61
- private $compiler;
62
-
63
- /**
64
- * Mustache class constructor.
65
- *
66
- * Passing an $options array allows overriding certain Mustache options during instantiation:
67
- *
68
- * $options = array(
69
- * // The class prefix for compiled templates. Defaults to '__Mustache_'.
70
- * 'template_class_prefix' => '__MyTemplates_',
71
- *
72
- * // A Mustache cache instance or a cache directory string for compiled templates.
73
- * // Mustache will not cache templates unless this is set.
74
- * 'cache' => dirname(__FILE__).'/tmp/cache/mustache',
75
- *
76
- * // Override default permissions for cache files. Defaults to using the system-defined umask. It is
77
- * // *strongly* recommended that you configure your umask properly rather than overriding permissions here.
78
- * 'cache_file_mode' => 0666,
79
- *
80
- * // Optionally, enable caching for lambda section templates. This is generally not recommended, as lambda
81
- * // sections are often too dynamic to benefit from caching.
82
- * 'cache_lambda_templates' => true,
83
- *
84
- * // A Mustache template loader instance. Uses a StringLoader if not specified.
85
- * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
86
- *
87
- * // A Mustache loader instance for partials.
88
- * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
89
- *
90
- * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as
91
- * // efficient or lazy as a Filesystem (or database) loader.
92
- * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')),
93
- *
94
- * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order
95
- * // sections), or any other valid Mustache context value. They will be prepended to the context stack,
96
- * // so they will be available in any template loaded by this Mustache instance.
97
- * 'helpers' => array('i18n' => function ($text) {
98
- * // do something translatey here...
99
- * }),
100
- *
101
- * // An 'escape' callback, responsible for escaping double-mustache variables.
102
- * 'escape' => function ($value) {
103
- * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8');
104
- * },
105
- *
106
- * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES.
107
- * 'entity_flags' => ENT_QUOTES,
108
- *
109
- * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'.
110
- * 'charset' => 'ISO-8859-1',
111
- *
112
- * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible
113
- * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is
114
- * // available as well:
115
- * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'),
116
- *
117
- * // Only treat Closure instances and invokable classes as callable. If true, values like
118
- * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally
119
- * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This
120
- * // helps protect against arbitrary code execution when user input is passed directly into the template.
121
- * // This currently defaults to false, but will default to true in v3.0.
122
- * 'strict_callables' => true,
123
- *
124
- * // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
125
- * // templates.
126
- * 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
127
- * );
128
- *
129
- * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
130
- *
131
- * @param array $options (default: array())
132
- */
133
- public function __construct(array $options = array())
134
- {
135
- if (isset($options['template_class_prefix'])) {
136
- $this->templateClassPrefix = $options['template_class_prefix'];
137
- }
138
-
139
- if (isset($options['cache'])) {
140
- $cache = $options['cache'];
141
-
142
- if (is_string($cache)) {
143
- $mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
144
- $cache = new Mustache_Cache_FilesystemCache($cache, $mode);
145
- }
146
-
147
- $this->setCache($cache);
148
- }
149
-
150
- if (isset($options['cache_lambda_templates'])) {
151
- $this->cacheLambdaTemplates = (bool) $options['cache_lambda_templates'];
152
- }
153
-
154
- if (isset($options['loader'])) {
155
- $this->setLoader($options['loader']);
156
- }
157
-
158
- if (isset($options['partials_loader'])) {
159
- $this->setPartialsLoader($options['partials_loader']);
160
- }
161
-
162
- if (isset($options['partials'])) {
163
- $this->setPartials($options['partials']);
164
- }
165
-
166
- if (isset($options['helpers'])) {
167
- $this->setHelpers($options['helpers']);
168
- }
169
-
170
- if (isset($options['escape'])) {
171
- if (!is_callable($options['escape'])) {
172
- throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable');
173
- }
174
-
175
- $this->escape = $options['escape'];
176
- }
177
-
178
- if (isset($options['entity_flags'])) {
179
- $this->entityFlags = $options['entity_flags'];
180
- }
181
-
182
- if (isset($options['charset'])) {
183
- $this->charset = $options['charset'];
184
- }
185
-
186
- if (isset($options['logger'])) {
187
- $this->setLogger($options['logger']);
188
- }
189
-
190
- if (isset($options['strict_callables'])) {
191
- $this->strictCallables = $options['strict_callables'];
192
- }
193
-
194
- if (isset($options['pragmas'])) {
195
- foreach ($options['pragmas'] as $pragma) {
196
- if (!isset(self::$knownPragmas[$pragma])) {
197
- throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
198
- }
199
- $this->pragmas[$pragma] = true;
200
- }
201
- }
202
- }
203
-
204
- /**
205
- * Shortcut 'render' invocation.
206
- *
207
- * Equivalent to calling `$mustache->loadTemplate($template)->render($context);`
208
- *
209
- * @see Mustache_Engine::loadTemplate
210
- * @see Mustache_Template::render
211
- *
212
- * @param string $template
213
- * @param mixed $context (default: array())
214
- *
215
- * @return string Rendered template
216
- */
217
- public function render($template, $context = array())
218
- {
219
- return $this->loadTemplate($template)->render($context);
220
- }
221
-
222
- /**
223
- * Get the current Mustache escape callback.
224
- *
225
- * @return callable|null
226
- */
227
- public function getEscape()
228
- {
229
- return $this->escape;
230
- }
231
-
232
- /**
233
- * Get the current Mustache entitity type to escape.
234
- *
235
- * @return int
236
- */
237
- public function getEntityFlags()
238
- {
239
- return $this->entityFlags;
240
- }
241
-
242
- /**
243
- * Get the current Mustache character set.
244
- *
245
- * @return string
246
- */
247
- public function getCharset()
248
- {
249
- return $this->charset;
250
- }
251
-
252
- /**
253
- * Get the current globally enabled pragmas.
254
- *
255
- * @return array
256
- */
257
- public function getPragmas()
258
- {
259
- return array_keys($this->pragmas);
260
- }
261
-
262
- /**
263
- * Set the Mustache template Loader instance.
264
- *
265
- * @param Mustache_Loader $loader
266
- */
267
- public function setLoader(Mustache_Loader $loader)
268
- {
269
- $this->loader = $loader;
270
- }
271
-
272
- /**
273
- * Get the current Mustache template Loader instance.
274
- *
275
- * If no Loader instance has been explicitly specified, this method will instantiate and return
276
- * a StringLoader instance.
277
- *
278
- * @return Mustache_Loader
279
- */
280
- public function getLoader()
281
- {
282
- if (!isset($this->loader)) {
283
- $this->loader = new Mustache_Loader_StringLoader();
284
- }
285
-
286
- return $this->loader;
287
- }
288
-
289
- /**
290
- * Set the Mustache partials Loader instance.
291
- *
292
- * @param Mustache_Loader $partialsLoader
293
- */
294
- public function setPartialsLoader(Mustache_Loader $partialsLoader)
295
- {
296
- $this->partialsLoader = $partialsLoader;
297
- }
298
-
299
- /**
300
- * Get the current Mustache partials Loader instance.
301
- *
302
- * If no Loader instance has been explicitly specified, this method will instantiate and return
303
- * an ArrayLoader instance.
304
- *
305
- * @return Mustache_Loader
306
- */
307
- public function getPartialsLoader()
308
- {
309
- if (!isset($this->partialsLoader)) {
310
- $this->partialsLoader = new Mustache_Loader_ArrayLoader();
311
- }
312
-
313
- return $this->partialsLoader;
314
- }
315
-
316
- /**
317
- * Set partials for the current partials Loader instance.
318
- *
319
- * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable
320
- *
321
- * @param array $partials (default: array())
322
- */
323
- public function setPartials(array $partials = array())
324
- {
325
- if (!isset($this->partialsLoader)) {
326
- $this->partialsLoader = new Mustache_Loader_ArrayLoader();
327
- }
328
-
329
- if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
330
- throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance');
331
- }
332
-
333
- $this->partialsLoader->setTemplates($partials);
334
- }
335
-
336
- /**
337
- * Set an array of Mustache helpers.
338
- *
339
- * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or
340
- * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in
341
- * any template loaded by this Mustache instance.
342
- *
343
- * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable
344
- *
345
- * @param array|Traversable $helpers
346
- */
347
- public function setHelpers($helpers)
348
- {
349
- if (!is_array($helpers) && !$helpers instanceof Traversable) {
350
- throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers');
351
- }
352
-
353
- $this->getHelpers()->clear();
354
-
355
- foreach ($helpers as $name => $helper) {
356
- $this->addHelper($name, $helper);
357
- }
358
- }
359
-
360
- /**
361
- * Get the current set of Mustache helpers.
362
- *
363
- * @see Mustache_Engine::setHelpers
364
- *
365
- * @return Mustache_HelperCollection
366
- */
367
- public function getHelpers()
368
- {
369
- if (!isset($this->helpers)) {
370
- $this->helpers = new Mustache_HelperCollection();
371
- }
372
-
373
- return $this->helpers;
374
- }
375
-
376
- /**
377
- * Add a new Mustache helper.
378
- *
379
- * @see Mustache_Engine::setHelpers
380
- *
381
- * @param string $name
382
- * @param mixed $helper
383
- */
384
- public function addHelper($name, $helper)
385
- {
386
- $this->getHelpers()->add($name, $helper);
387
- }
388
-
389
- /**
390
- * Get a Mustache helper by name.
391
- *
392
- * @see Mustache_Engine::setHelpers
393
- *
394
- * @param string $name
395
- *
396
- * @return mixed Helper
397
- */
398
- public function getHelper($name)
399
- {
400
- return $this->getHelpers()->get($name);
401
- }
402
-
403
- /**
404
- * Check whether this Mustache instance has a helper.
405
- *
406
- * @see Mustache_Engine::setHelpers
407
- *
408
- * @param string $name
409
- *
410
- * @return bool True if the helper is present
411
- */
412
- public function hasHelper($name)
413
- {
414
- return $this->getHelpers()->has($name);
415
- }
416
-
417
- /**
418
- * Remove a helper by name.
419
- *
420
- * @see Mustache_Engine::setHelpers
421
- *
422
- * @param string $name
423
- */
424
- public function removeHelper($name)
425
- {
426
- $this->getHelpers()->remove($name);
427
- }
428
-
429
- /**
430
- * Set the Mustache Logger instance.
431
- *
432
- * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface.
433
- *
434
- * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
435
- */
436
- public function setLogger($logger = null)
437
- {
438
- if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
439
- throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
440
- }
441
-
442
- if ($this->getCache()->getLogger() === null) {
443
- $this->getCache()->setLogger($logger);
444
- }
445
-
446
- $this->logger = $logger;
447
- }
448
-
449
- /**
450
- * Get the current Mustache Logger instance.
451
- *
452
- * @return Mustache_Logger|Psr\Log\LoggerInterface
453
- */
454
- public function getLogger()
455
- {
456
- return $this->logger;
457
- }
458
-
459
- /**
460
- * Set the Mustache Tokenizer instance.
461
- *
462
- * @param Mustache_Tokenizer $tokenizer
463
- */
464
- public function setTokenizer(Mustache_Tokenizer $tokenizer)
465
- {
466
- $this->tokenizer = $tokenizer;
467
- }
468
-
469
- /**
470
- * Get the current Mustache Tokenizer instance.
471
- *
472
- * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one.
473
- *
474
- * @return Mustache_Tokenizer
475
- */
476
- public function getTokenizer()
477
- {
478
- if (!isset($this->tokenizer)) {
479
- $this->tokenizer = new Mustache_Tokenizer();
480
- }
481
-
482
- return $this->tokenizer;
483
- }
484
-
485
- /**
486
- * Set the Mustache Parser instance.
487
- *
488
- * @param Mustache_Parser $parser
489
- */
490
- public function setParser(Mustache_Parser $parser)
491
- {
492
- $this->parser = $parser;
493
- }
494
-
495
- /**
496
- * Get the current Mustache Parser instance.
497
- *
498
- * If no Parser instance has been explicitly specified, this method will instantiate and return a new one.
499
- *
500
- * @return Mustache_Parser
501
- */
502
- public function getParser()
503
- {
504
- if (!isset($this->parser)) {
505
- $this->parser = new Mustache_Parser();
506
- }
507
-
508
- return $this->parser;
509
- }
510
-
511
- /**
512
- * Set the Mustache Compiler instance.
513
- *
514
- * @param Mustache_Compiler $compiler
515
- */
516
- public function setCompiler(Mustache_Compiler $compiler)
517
- {
518
- $this->compiler = $compiler;
519
- }
520
-
521
- /**
522
- * Get the current Mustache Compiler instance.
523
- *
524
- * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one.
525
- *
526
- * @return Mustache_Compiler
527
- */
528
- public function getCompiler()
529
- {
530
- if (!isset($this->compiler)) {
531
- $this->compiler = new Mustache_Compiler();
532
- }
533
-
534
- return $this->compiler;
535
- }
536
-
537
- /**
538
- * Set the Mustache Cache instance.
539
- *
540
- * @param Mustache_Cache $cache
541
- */
542
- public function setCache(Mustache_Cache $cache)
543
- {
544
- if (isset($this->logger) && $cache->getLogger() === null) {
545
- $cache->setLogger($this->getLogger());
546
- }
547
-
548
- $this->cache = $cache;
549
- }
550
-
551
- /**
552
- * Get the current Mustache Cache instance.
553
- *
554
- * If no Cache instance has been explicitly specified, this method will instantiate and return a new one.
555
- *
556
- * @return Mustache_Cache
557
- */
558
- public function getCache()
559
- {
560
- if (!isset($this->cache)) {
561
- $this->setCache(new Mustache_Cache_NoopCache());
562
- }
563
-
564
- return $this->cache;
565
- }
566
-
567
- /**
568
- * Get the current Lambda Cache instance.
569
- *
570
- * If 'cache_lambda_templates' is enabled, this is the default cache instance. Otherwise, it is a NoopCache.
571
- *
572
- * @see Mustache_Engine::getCache
573
- *
574
- * @return Mustache_Cache
575
- */
576
- protected function getLambdaCache()
577
- {
578
- if ($this->cacheLambdaTemplates) {
579
- return $this->getCache();
580
- }
581
-
582
- if (!isset($this->lambdaCache)) {
583
- $this->lambdaCache = new Mustache_Cache_NoopCache();
584
- }
585
-
586
- return $this->lambdaCache;
587
- }
588
-
589
- /**
590
- * Helper method to generate a Mustache template class.
591
- *
592
- * @param string $source
593
- *
594
- * @return string Mustache Template class name
595
- */
596
- public function getTemplateClassName($source)
597
- {
598
- return $this->templateClassPrefix . md5(sprintf(
599
- 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
600
- self::VERSION,
601
- isset($this->escape) ? 'custom' : 'default',
602
- $this->entityFlags,
603
- $this->charset,
604
- $this->strictCallables ? 'true' : 'false',
605
- implode(' ', $this->getPragmas()),
606
- $source
607
- ));
608
- }
609
-
610
- /**
611
- * Load a Mustache Template by name.
612
- *
613
- * @param string $name
614
- *
615
- * @return Mustache_Template
616
- */
617
- public function loadTemplate($name)
618
- {
619
- return $this->loadSource($this->getLoader()->load($name));
620
- }
621
-
622
- /**
623
- * Load a Mustache partial Template by name.
624
- *
625
- * This is a helper method used internally by Template instances for loading partial templates. You can most likely
626
- * ignore it completely.
627
- *
628
- * @param string $name
629
- *
630
- * @return Mustache_Template
631
- */
632
- public function loadPartial($name)
633
- {
634
- try {
635
- if (isset($this->partialsLoader)) {
636
- $loader = $this->partialsLoader;
637
- } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) {
638
- $loader = $this->loader;
639
- } else {
640
- throw new Mustache_Exception_UnknownTemplateException($name);
641
- }
642
-
643
- return $this->loadSource($loader->load($name));
644
- } catch (Mustache_Exception_UnknownTemplateException $e) {
645
- // If the named partial cannot be found, log then return null.
646
- $this->log(
647
- Mustache_Logger::WARNING,
648
- 'Partial not found: "{name}"',
649
- array('name' => $e->getTemplateName())
650
- );
651
- }
652
- }
653
-
654
- /**
655
- * Load a Mustache lambda Template by source.
656
- *
657
- * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most
658
- * likely ignore it completely.
659
- *
660
- * @param string $source
661
- * @param string $delims (default: null)
662
- *
663
- * @return Mustache_Template
664
- */
665
- public function loadLambda($source, $delims = null)
666
- {
667
- if ($delims !== null) {
668
- $source = $delims . "\n" . $source;
669
- }
670
-
671
- return $this->loadSource($source, $this->getLambdaCache());
672
- }
673
-
674
- /**
675
- * Instantiate and return a Mustache Template instance by source.
676
- *
677
- * Optionally provide a Mustache_Cache instance. This is used internally by Mustache_Engine::loadLambda to respect
678
- * the 'cache_lambda_templates' configuration option.
679
- *
680
- * @see Mustache_Engine::loadTemplate
681
- * @see Mustache_Engine::loadPartial
682
- * @see Mustache_Engine::loadLambda
683
- *
684
- * @param string $source
685
- * @param Mustache_Cache $cache (default: null)
686
- *
687
- * @return Mustache_Template
688
- */
689
- private function loadSource($source, Mustache_Cache $cache = null)
690
- {
691
- $className = $this->getTemplateClassName($source);
692
-
693
- if (!isset($this->templates[$className])) {
694
- if ($cache === null) {
695
- $cache = $this->getCache();
696
- }
697
-
698
- if (!class_exists($className, false)) {
699
- if (!$cache->load($className)) {
700
- $compiled = $this->compile($source);
701
- $cache->cache($className, $compiled);
702
- }
703
- }
704
-
705
- $this->log(
706
- Mustache_Logger::DEBUG,
707
- 'Instantiating template: "{className}"',
708
- array('className' => $className)
709
- );
710
-
711
- $this->templates[$className] = new $className($this);
712
- }
713
-
714
- return $this->templates[$className];
715
- }
716
-
717
- /**
718
- * Helper method to tokenize a Mustache template.
719
- *
720
- * @see Mustache_Tokenizer::scan
721
- *
722
- * @param string $source
723
- *
724
- * @return array Tokens
725
- */
726
- private function tokenize($source)
727
- {
728
- return $this->getTokenizer()->scan($source);
729
- }
730
-
731
- /**
732
- * Helper method to parse a Mustache template.
733
- *
734
- * @see Mustache_Parser::parse
735
- *
736
- * @param string $source
737
- *
738
- * @return array Token tree
739
- */
740
- private function parse($source)
741
- {
742
- $parser = $this->getParser();
743
- $parser->setPragmas($this->getPragmas());
744
-
745
- return $parser->parse($this->tokenize($source));
746
- }
747
-
748
- /**
749
- * Helper method to compile a Mustache template.
750
- *
751
- * @see Mustache_Compiler::compile
752
- *
753
- * @param string $source
754
- *
755
- * @return string generated Mustache template class code
756
- */
757
- private function compile($source)
758
- {
759
- $tree = $this->parse($source);
760
- $name = $this->getTemplateClassName($source);
761
-
762
- $this->log(
763
- Mustache_Logger::INFO,
764
- 'Compiling template to "{className}" class',
765
- array('className' => $name)
766
- );
767
-
768
- $compiler = $this->getCompiler();
769
- $compiler->setPragmas($this->getPragmas());
770
-
771
- return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
772
- }
773
-
774
- /**
775
- * Add a log record if logging is enabled.
776
- *
777
- * @param int $level The logging level
778
- * @param string $message The log message
779
- * @param array $context The log context
780
- */
781
- private function log($level, $message, array $context = array())
782
- {
783
- if (isset($this->logger)) {
784
- $this->logger->log($level, $message, $context);
785
- }
786
- }
787
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * A Mustache implementation in PHP.
14
+ *
15
+ * {@link http://defunkt.github.com/mustache}
16
+ *
17
+ * Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
18
+ * logic from template files. In fact, it is not even possible to embed logic in the template.
19
+ *
20
+ * This is very, very rad.
21
+ *
22
+ * @author Justin Hileman {@link http://justinhileman.com}
23
+ */
24
+ class Mustache_Engine
25
+ {
26
+ const VERSION = '2.10.0';
27
+ const SPEC_VERSION = '1.1.2';
28
+
29
+ const PRAGMA_FILTERS = 'FILTERS';
30
+ const PRAGMA_BLOCKS = 'BLOCKS';
31
+ const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
32
+
33
+ // Known pragmas
34
+ private static $knownPragmas = array(
35
+ self::PRAGMA_FILTERS => true,
36
+ self::PRAGMA_BLOCKS => true,
37
+ self::PRAGMA_ANCHORED_DOT => true,
38
+ );
39
+
40
+ // Template cache
41
+ private $templates = array();
42
+
43
+ // Environment
44
+ private $templateClassPrefix = '__Mustache_';
45
+ private $cache;
46
+ private $lambdaCache;
47
+ private $cacheLambdaTemplates = false;
48
+ private $loader;
49
+ private $partialsLoader;
50
+ private $helpers;
51
+ private $escape;
52
+ private $entityFlags = ENT_COMPAT;
53
+ private $charset = 'UTF-8';
54
+ private $logger;
55
+ private $strictCallables = false;
56
+ private $pragmas = array();
57
+
58
+ // Services
59
+ private $tokenizer;
60
+ private $parser;
61
+ private $compiler;
62
+
63
+ /**
64
+ * Mustache class constructor.
65
+ *
66
+ * Passing an $options array allows overriding certain Mustache options during instantiation:
67
+ *
68
+ * $options = array(
69
+ * // The class prefix for compiled templates. Defaults to '__Mustache_'.
70
+ * 'template_class_prefix' => '__MyTemplates_',
71
+ *
72
+ * // A Mustache cache instance or a cache directory string for compiled templates.
73
+ * // Mustache will not cache templates unless this is set.
74
+ * 'cache' => dirname(__FILE__).'/tmp/cache/mustache',
75
+ *
76
+ * // Override default permissions for cache files. Defaults to using the system-defined umask. It is
77
+ * // *strongly* recommended that you configure your umask properly rather than overriding permissions here.
78
+ * 'cache_file_mode' => 0666,
79
+ *
80
+ * // Optionally, enable caching for lambda section templates. This is generally not recommended, as lambda
81
+ * // sections are often too dynamic to benefit from caching.
82
+ * 'cache_lambda_templates' => true,
83
+ *
84
+ * // A Mustache template loader instance. Uses a StringLoader if not specified.
85
+ * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
86
+ *
87
+ * // A Mustache loader instance for partials.
88
+ * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
89
+ *
90
+ * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as
91
+ * // efficient or lazy as a Filesystem (or database) loader.
92
+ * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')),
93
+ *
94
+ * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order
95
+ * // sections), or any other valid Mustache context value. They will be prepended to the context stack,
96
+ * // so they will be available in any template loaded by this Mustache instance.
97
+ * 'helpers' => array('i18n' => function ($text) {
98
+ * // do something translatey here...
99
+ * }),
100
+ *
101
+ * // An 'escape' callback, responsible for escaping double-mustache variables.
102
+ * 'escape' => function ($value) {
103
+ * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8');
104
+ * },
105
+ *
106
+ * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES.
107
+ * 'entity_flags' => ENT_QUOTES,
108
+ *
109
+ * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'.
110
+ * 'charset' => 'ISO-8859-1',
111
+ *
112
+ * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible
113
+ * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is
114
+ * // available as well:
115
+ * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'),
116
+ *
117
+ * // Only treat Closure instances and invokable classes as callable. If true, values like
118
+ * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally
119
+ * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This
120
+ * // helps protect against arbitrary code execution when user input is passed directly into the template.
121
+ * // This currently defaults to false, but will default to true in v3.0.
122
+ * 'strict_callables' => true,
123
+ *
124
+ * // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
125
+ * // templates.
126
+ * 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
127
+ * );
128
+ *
129
+ * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
130
+ *
131
+ * @param array $options (default: array())
132
+ */
133
+ public function __construct(array $options = array())
134
+ {
135
+ if (isset($options['template_class_prefix'])) {
136
+ $this->templateClassPrefix = $options['template_class_prefix'];
137
+ }
138
+
139
+ if (isset($options['cache'])) {
140
+ $cache = $options['cache'];
141
+
142
+ if (is_string($cache)) {
143
+ $mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
144
+ $cache = new Mustache_Cache_FilesystemCache($cache, $mode);
145
+ }
146
+
147
+ $this->setCache($cache);
148
+ }
149
+
150
+ if (isset($options['cache_lambda_templates'])) {
151
+ $this->cacheLambdaTemplates = (bool) $options['cache_lambda_templates'];
152
+ }
153
+
154
+ if (isset($options['loader'])) {
155
+ $this->setLoader($options['loader']);
156
+ }
157
+
158
+ if (isset($options['partials_loader'])) {
159
+ $this->setPartialsLoader($options['partials_loader']);
160
+ }
161
+
162
+ if (isset($options['partials'])) {
163
+ $this->setPartials($options['partials']);
164
+ }
165
+
166
+ if (isset($options['helpers'])) {
167
+ $this->setHelpers($options['helpers']);
168
+ }
169
+
170
+ if (isset($options['escape'])) {
171
+ if (!is_callable($options['escape'])) {
172
+ throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable');
173
+ }
174
+
175
+ $this->escape = $options['escape'];
176
+ }
177
+
178
+ if (isset($options['entity_flags'])) {
179
+ $this->entityFlags = $options['entity_flags'];
180
+ }
181
+
182
+ if (isset($options['charset'])) {
183
+ $this->charset = $options['charset'];
184
+ }
185
+
186
+ if (isset($options['logger'])) {
187
+ $this->setLogger($options['logger']);
188
+ }
189
+
190
+ if (isset($options['strict_callables'])) {
191
+ $this->strictCallables = $options['strict_callables'];
192
+ }
193
+
194
+ if (isset($options['pragmas'])) {
195
+ foreach ($options['pragmas'] as $pragma) {
196
+ if (!isset(self::$knownPragmas[$pragma])) {
197
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
198
+ }
199
+ $this->pragmas[$pragma] = true;
200
+ }
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Shortcut 'render' invocation.
206
+ *
207
+ * Equivalent to calling `$mustache->loadTemplate($template)->render($context);`
208
+ *
209
+ * @see Mustache_Engine::loadTemplate
210
+ * @see Mustache_Template::render
211
+ *
212
+ * @param string $template
213
+ * @param mixed $context (default: array())
214
+ *
215
+ * @return string Rendered template
216
+ */
217
+ public function render($template, $context = array())
218
+ {
219
+ return $this->loadTemplate($template)->render($context);
220
+ }
221
+
222
+ /**
223
+ * Get the current Mustache escape callback.
224
+ *
225
+ * @return callable|null
226
+ */
227
+ public function getEscape()
228
+ {
229
+ return $this->escape;
230
+ }
231
+
232
+ /**
233
+ * Get the current Mustache entitity type to escape.
234
+ *
235
+ * @return int
236
+ */
237
+ public function getEntityFlags()
238
+ {
239
+ return $this->entityFlags;
240
+ }
241
+
242
+ /**
243
+ * Get the current Mustache character set.
244
+ *
245
+ * @return string
246
+ */
247
+ public function getCharset()
248
+ {
249
+ return $this->charset;
250
+ }
251
+
252
+ /**
253
+ * Get the current globally enabled pragmas.
254
+ *
255
+ * @return array
256
+ */
257
+ public function getPragmas()
258
+ {
259
+ return array_keys($this->pragmas);
260
+ }
261
+
262
+ /**
263
+ * Set the Mustache template Loader instance.
264
+ *
265
+ * @param Mustache_Loader $loader
266
+ */
267
+ public function setLoader(Mustache_Loader $loader)
268
+ {
269
+ $this->loader = $loader;
270
+ }
271
+
272
+ /**
273
+ * Get the current Mustache template Loader instance.
274
+ *
275
+ * If no Loader instance has been explicitly specified, this method will instantiate and return
276
+ * a StringLoader instance.
277
+ *
278
+ * @return Mustache_Loader
279
+ */
280
+ public function getLoader()
281
+ {
282
+ if (!isset($this->loader)) {
283
+ $this->loader = new Mustache_Loader_StringLoader();
284
+ }
285
+
286
+ return $this->loader;
287
+ }
288
+
289
+ /**
290
+ * Set the Mustache partials Loader instance.
291
+ *
292
+ * @param Mustache_Loader $partialsLoader
293
+ */
294
+ public function setPartialsLoader(Mustache_Loader $partialsLoader)
295
+ {
296
+ $this->partialsLoader = $partialsLoader;
297
+ }
298
+
299
+ /**
300
+ * Get the current Mustache partials Loader instance.
301
+ *
302
+ * If no Loader instance has been explicitly specified, this method will instantiate and return
303
+ * an ArrayLoader instance.
304
+ *
305
+ * @return Mustache_Loader
306
+ */
307
+ public function getPartialsLoader()
308
+ {
309
+ if (!isset($this->partialsLoader)) {
310
+ $this->partialsLoader = new Mustache_Loader_ArrayLoader();
311
+ }
312
+
313
+ return $this->partialsLoader;
314
+ }
315
+
316
+ /**
317
+ * Set partials for the current partials Loader instance.
318
+ *
319
+ * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable
320
+ *
321
+ * @param array $partials (default: array())
322
+ */
323
+ public function setPartials(array $partials = array())
324
+ {
325
+ if (!isset($this->partialsLoader)) {
326
+ $this->partialsLoader = new Mustache_Loader_ArrayLoader();
327
+ }
328
+
329
+ if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
330
+ throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance');
331
+ }
332
+
333
+ $this->partialsLoader->setTemplates($partials);
334
+ }
335
+
336
+ /**
337
+ * Set an array of Mustache helpers.
338
+ *
339
+ * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or
340
+ * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in
341
+ * any template loaded by this Mustache instance.
342
+ *
343
+ * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable
344
+ *
345
+ * @param array|Traversable $helpers
346
+ */
347
+ public function setHelpers($helpers)
348
+ {
349
+ if (!is_array($helpers) && !$helpers instanceof Traversable) {
350
+ throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers');
351
+ }
352
+
353
+ $this->getHelpers()->clear();
354
+
355
+ foreach ($helpers as $name => $helper) {
356
+ $this->addHelper($name, $helper);
357
+ }
358
+ }
359
+
360
+ /**
361
+ * Get the current set of Mustache helpers.
362
+ *
363
+ * @see Mustache_Engine::setHelpers
364
+ *
365
+ * @return Mustache_HelperCollection
366
+ */
367
+ public function getHelpers()
368
+ {
369
+ if (!isset($this->helpers)) {
370
+ $this->helpers = new Mustache_HelperCollection();
371
+ }
372
+
373
+ return $this->helpers;
374
+ }
375
+
376
+ /**
377
+ * Add a new Mustache helper.
378
+ *
379
+ * @see Mustache_Engine::setHelpers
380
+ *
381
+ * @param string $name
382
+ * @param mixed $helper
383
+ */
384
+ public function addHelper($name, $helper)
385
+ {
386
+ $this->getHelpers()->add($name, $helper);
387
+ }
388
+
389
+ /**
390
+ * Get a Mustache helper by name.
391
+ *
392
+ * @see Mustache_Engine::setHelpers
393
+ *
394
+ * @param string $name
395
+ *
396
+ * @return mixed Helper
397
+ */
398
+ public function getHelper($name)
399
+ {
400
+ return $this->getHelpers()->get($name);
401
+ }
402
+
403
+ /**
404
+ * Check whether this Mustache instance has a helper.
405
+ *
406
+ * @see Mustache_Engine::setHelpers
407
+ *
408
+ * @param string $name
409
+ *
410
+ * @return bool True if the helper is present
411
+ */
412
+ public function hasHelper($name)
413
+ {
414
+ return $this->getHelpers()->has($name);
415
+ }
416
+
417
+ /**
418
+ * Remove a helper by name.
419
+ *
420
+ * @see Mustache_Engine::setHelpers
421
+ *
422
+ * @param string $name
423
+ */
424
+ public function removeHelper($name)
425
+ {
426
+ $this->getHelpers()->remove($name);
427
+ }
428
+
429
+ /**
430
+ * Set the Mustache Logger instance.
431
+ *
432
+ * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface.
433
+ *
434
+ * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
435
+ */
436
+ public function setLogger($logger = null)
437
+ {
438
+ if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
439
+ throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
440
+ }
441
+
442
+ if ($this->getCache()->getLogger() === null) {
443
+ $this->getCache()->setLogger($logger);
444
+ }
445
+
446
+ $this->logger = $logger;
447
+ }
448
+
449
+ /**
450
+ * Get the current Mustache Logger instance.
451
+ *
452
+ * @return Mustache_Logger|Psr\Log\LoggerInterface
453
+ */
454
+ public function getLogger()
455
+ {
456
+ return $this->logger;
457
+ }
458
+
459
+ /**
460
+ * Set the Mustache Tokenizer instance.
461
+ *
462
+ * @param Mustache_Tokenizer $tokenizer
463
+ */
464
+ public function setTokenizer(Mustache_Tokenizer $tokenizer)
465
+ {
466
+ $this->tokenizer = $tokenizer;
467
+ }
468
+
469
+ /**
470
+ * Get the current Mustache Tokenizer instance.
471
+ *
472
+ * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one.
473
+ *
474
+ * @return Mustache_Tokenizer
475
+ */
476
+ public function getTokenizer()
477
+ {
478
+ if (!isset($this->tokenizer)) {
479
+ $this->tokenizer = new Mustache_Tokenizer();
480
+ }
481
+
482
+ return $this->tokenizer;
483
+ }
484
+
485
+ /**
486
+ * Set the Mustache Parser instance.
487
+ *
488
+ * @param Mustache_Parser $parser
489
+ */
490
+ public function setParser(Mustache_Parser $parser)
491
+ {
492
+ $this->parser = $parser;
493
+ }
494
+
495
+ /**
496
+ * Get the current Mustache Parser instance.
497
+ *
498
+ * If no Parser instance has been explicitly specified, this method will instantiate and return a new one.
499
+ *
500
+ * @return Mustache_Parser
501
+ */
502
+ public function getParser()
503
+ {
504
+ if (!isset($this->parser)) {
505
+ $this->parser = new Mustache_Parser();
506
+ }
507
+
508
+ return $this->parser;
509
+ }
510
+
511
+ /**
512
+ * Set the Mustache Compiler instance.
513
+ *
514
+ * @param Mustache_Compiler $compiler
515
+ */
516
+ public function setCompiler(Mustache_Compiler $compiler)
517
+ {
518
+ $this->compiler = $compiler;
519
+ }
520
+
521
+ /**
522
+ * Get the current Mustache Compiler instance.
523
+ *
524
+ * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one.
525
+ *
526
+ * @return Mustache_Compiler
527
+ */
528
+ public function getCompiler()
529
+ {
530
+ if (!isset($this->compiler)) {
531
+ $this->compiler = new Mustache_Compiler();
532
+ }
533
+
534
+ return $this->compiler;
535
+ }
536
+
537
+ /**
538
+ * Set the Mustache Cache instance.
539
+ *
540
+ * @param Mustache_Cache $cache
541
+ */
542
+ public function setCache(Mustache_Cache $cache)
543
+ {
544
+ if (isset($this->logger) && $cache->getLogger() === null) {
545
+ $cache->setLogger($this->getLogger());
546
+ }
547
+
548
+ $this->cache = $cache;
549
+ }
550
+
551
+ /**
552
+ * Get the current Mustache Cache instance.
553
+ *
554
+ * If no Cache instance has been explicitly specified, this method will instantiate and return a new one.
555
+ *
556
+ * @return Mustache_Cache
557
+ */
558
+ public function getCache()
559
+ {
560
+ if (!isset($this->cache)) {
561
+ $this->setCache(new Mustache_Cache_NoopCache());
562
+ }
563
+
564
+ return $this->cache;
565
+ }
566
+
567
+ /**
568
+ * Get the current Lambda Cache instance.
569
+ *
570
+ * If 'cache_lambda_templates' is enabled, this is the default cache instance. Otherwise, it is a NoopCache.
571
+ *
572
+ * @see Mustache_Engine::getCache
573
+ *
574
+ * @return Mustache_Cache
575
+ */
576
+ protected function getLambdaCache()
577
+ {
578
+ if ($this->cacheLambdaTemplates) {
579
+ return $this->getCache();
580
+ }
581
+
582
+ if (!isset($this->lambdaCache)) {
583
+ $this->lambdaCache = new Mustache_Cache_NoopCache();
584
+ }
585
+
586
+ return $this->lambdaCache;
587
+ }
588
+
589
+ /**
590
+ * Helper method to generate a Mustache template class.
591
+ *
592
+ * @param string $source
593
+ *
594
+ * @return string Mustache Template class name
595
+ */
596
+ public function getTemplateClassName($source)
597
+ {
598
+ return $this->templateClassPrefix . md5(sprintf(
599
+ 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
600
+ self::VERSION,
601
+ isset($this->escape) ? 'custom' : 'default',
602
+ $this->entityFlags,
603
+ $this->charset,
604
+ $this->strictCallables ? 'true' : 'false',
605
+ implode(' ', $this->getPragmas()),
606
+ $source
607
+ ));
608
+ }
609
+
610
+ /**
611
+ * Load a Mustache Template by name.
612
+ *
613
+ * @param string $name
614
+ *
615
+ * @return Mustache_Template
616
+ */
617
+ public function loadTemplate($name)
618
+ {
619
+ return $this->loadSource($this->getLoader()->load($name));
620
+ }
621
+
622
+ /**
623
+ * Load a Mustache partial Template by name.
624
+ *
625
+ * This is a helper method used internally by Template instances for loading partial templates. You can most likely
626
+ * ignore it completely.
627
+ *
628
+ * @param string $name
629
+ *
630
+ * @return Mustache_Template
631
+ */
632
+ public function loadPartial($name)
633
+ {
634
+ try {
635
+ if (isset($this->partialsLoader)) {
636
+ $loader = $this->partialsLoader;
637
+ } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) {
638
+ $loader = $this->loader;
639
+ } else {
640
+ throw new Mustache_Exception_UnknownTemplateException($name);
641
+ }
642
+
643
+ return $this->loadSource($loader->load($name));
644
+ } catch (Mustache_Exception_UnknownTemplateException $e) {
645
+ // If the named partial cannot be found, log then return null.
646
+ $this->log(
647
+ Mustache_Logger::WARNING,
648
+ 'Partial not found: "{name}"',
649
+ array('name' => $e->getTemplateName())
650
+ );
651
+ }
652
+ }
653
+
654
+ /**
655
+ * Load a Mustache lambda Template by source.
656
+ *
657
+ * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most
658
+ * likely ignore it completely.
659
+ *
660
+ * @param string $source
661
+ * @param string $delims (default: null)
662
+ *
663
+ * @return Mustache_Template
664
+ */
665
+ public function loadLambda($source, $delims = null)
666
+ {
667
+ if ($delims !== null) {
668
+ $source = $delims . "\n" . $source;
669
+ }
670
+
671
+ return $this->loadSource($source, $this->getLambdaCache());
672
+ }
673
+
674
+ /**
675
+ * Instantiate and return a Mustache Template instance by source.
676
+ *
677
+ * Optionally provide a Mustache_Cache instance. This is used internally by Mustache_Engine::loadLambda to respect
678
+ * the 'cache_lambda_templates' configuration option.
679
+ *
680
+ * @see Mustache_Engine::loadTemplate
681
+ * @see Mustache_Engine::loadPartial
682
+ * @see Mustache_Engine::loadLambda
683
+ *
684
+ * @param string $source
685
+ * @param Mustache_Cache $cache (default: null)
686
+ *
687
+ * @return Mustache_Template
688
+ */
689
+ private function loadSource($source, Mustache_Cache $cache = null)
690
+ {
691
+ $className = $this->getTemplateClassName($source);
692
+
693
+ if (!isset($this->templates[$className])) {
694
+ if ($cache === null) {
695
+ $cache = $this->getCache();
696
+ }
697
+
698
+ if (!class_exists($className, false)) {
699
+ if (!$cache->load($className)) {
700
+ $compiled = $this->compile($source);
701
+ $cache->cache($className, $compiled);
702
+ }
703
+ }
704
+
705
+ $this->log(
706
+ Mustache_Logger::DEBUG,
707
+ 'Instantiating template: "{className}"',
708
+ array('className' => $className)
709
+ );
710
+
711
+ $this->templates[$className] = new $className($this);
712
+ }
713
+
714
+ return $this->templates[$className];
715
+ }
716
+
717
+ /**
718
+ * Helper method to tokenize a Mustache template.
719
+ *
720
+ * @see Mustache_Tokenizer::scan
721
+ *
722
+ * @param string $source
723
+ *
724
+ * @return array Tokens
725
+ */
726
+ private function tokenize($source)
727
+ {
728
+ return $this->getTokenizer()->scan($source);
729
+ }
730
+
731
+ /**
732
+ * Helper method to parse a Mustache template.
733
+ *
734
+ * @see Mustache_Parser::parse
735
+ *
736
+ * @param string $source
737
+ *
738
+ * @return array Token tree
739
+ */
740
+ private function parse($source)
741
+ {
742
+ $parser = $this->getParser();
743
+ $parser->setPragmas($this->getPragmas());
744
+
745
+ return $parser->parse($this->tokenize($source));
746
+ }
747
+
748
+ /**
749
+ * Helper method to compile a Mustache template.
750
+ *
751
+ * @see Mustache_Compiler::compile
752
+ *
753
+ * @param string $source
754
+ *
755
+ * @return string generated Mustache template class code
756
+ */
757
+ private function compile($source)
758
+ {
759
+ $tree = $this->parse($source);
760
+ $name = $this->getTemplateClassName($source);
761
+
762
+ $this->log(
763
+ Mustache_Logger::INFO,
764
+ 'Compiling template to "{className}" class',
765
+ array('className' => $name)
766
+ );
767
+
768
+ $compiler = $this->getCompiler();
769
+ $compiler->setPragmas($this->getPragmas());
770
+
771
+ return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
772
+ }
773
+
774
+ /**
775
+ * Add a log record if logging is enabled.
776
+ *
777
+ * @param int $level The logging level
778
+ * @param string $message The log message
779
+ * @param array $context The log context
780
+ */
781
+ private function log($level, $message, array $context = array())
782
+ {
783
+ if (isset($this->logger)) {
784
+ $this->logger->log($level, $message, $context);
785
+ }
786
+ }
787
+ }
lib/php/Mustache/Exception.php CHANGED
@@ -1,18 +1,18 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * A Mustache Exception interface.
14
- */
15
- interface Mustache_Exception
16
- {
17
- // This space intentionally left blank.
18
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * A Mustache Exception interface.
14
+ */
15
+ interface Mustache_Exception
16
+ {
17
+ // This space intentionally left blank.
18
+ }
lib/php/Mustache/Exception/InvalidArgumentException.php CHANGED
@@ -1,18 +1,18 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Invalid argument exception.
14
- */
15
- class Mustache_Exception_InvalidArgumentException extends InvalidArgumentException implements Mustache_Exception
16
- {
17
- // This space intentionally left blank.
18
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Invalid argument exception.
14
+ */
15
+ class Mustache_Exception_InvalidArgumentException extends InvalidArgumentException implements Mustache_Exception
16
+ {
17
+ // This space intentionally left blank.
18
+ }
lib/php/Mustache/Exception/LogicException.php CHANGED
@@ -1,18 +1,18 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Logic exception.
14
- */
15
- class Mustache_Exception_LogicException extends LogicException implements Mustache_Exception
16
- {
17
- // This space intentionally left blank.
18
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Logic exception.
14
+ */
15
+ class Mustache_Exception_LogicException extends LogicException implements Mustache_Exception
16
+ {
17
+ // This space intentionally left blank.
18
+ }
lib/php/Mustache/Exception/RuntimeException.php CHANGED
@@ -1,18 +1,18 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Runtime exception.
14
- */
15
- class Mustache_Exception_RuntimeException extends RuntimeException implements Mustache_Exception
16
- {
17
- // This space intentionally left blank.
18
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Runtime exception.
14
+ */
15
+ class Mustache_Exception_RuntimeException extends RuntimeException implements Mustache_Exception
16
+ {
17
+ // This space intentionally left blank.
18
+ }
lib/php/Mustache/Exception/SyntaxException.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache syntax exception.
14
- */
15
- class Mustache_Exception_SyntaxException extends LogicException implements Mustache_Exception
16
- {
17
- protected $token;
18
-
19
- /**
20
- * @param string $msg
21
- * @param array $token
22
- */
23
- public function __construct($msg, array $token)
24
- {
25
- $this->token = $token;
26
- parent::__construct($msg);
27
- }
28
-
29
- /**
30
- * @return array
31
- */
32
- public function getToken()
33
- {
34
- return $this->token;
35
- }
36
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache syntax exception.
14
+ */
15
+ class Mustache_Exception_SyntaxException extends LogicException implements Mustache_Exception
16
+ {
17
+ protected $token;
18
+
19
+ /**
20
+ * @param string $msg
21
+ * @param array $token
22
+ */
23
+ public function __construct($msg, array $token)
24
+ {
25
+ $this->token = $token;
26
+ parent::__construct($msg);
27
+ }
28
+
29
+ /**
30
+ * @return array
31
+ */
32
+ public function getToken()
33
+ {
34
+ return $this->token;
35
+ }
36
+ }
lib/php/Mustache/Exception/UnknownFilterException.php CHANGED
@@ -1,32 +1,32 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Unknown filter exception.
14
- */
15
- class Mustache_Exception_UnknownFilterException extends UnexpectedValueException implements Mustache_Exception
16
- {
17
- protected $filterName;
18
-
19
- /**
20
- * @param string $filterName
21
- */
22
- public function __construct($filterName)
23
- {
24
- $this->filterName = $filterName;
25
- parent::__construct(sprintf('Unknown filter: %s', $filterName));
26
- }
27
-
28
- public function getFilterName()
29
- {
30
- return $this->filterName;
31
- }
32
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Unknown filter exception.
14
+ */
15
+ class Mustache_Exception_UnknownFilterException extends UnexpectedValueException implements Mustache_Exception
16
+ {
17
+ protected $filterName;
18
+
19
+ /**
20
+ * @param string $filterName
21
+ */
22
+ public function __construct($filterName)
23
+ {
24
+ $this->filterName = $filterName;
25
+ parent::__construct(sprintf('Unknown filter: %s', $filterName));
26
+ }
27
+
28
+ public function getFilterName()
29
+ {
30
+ return $this->filterName;
31
+ }
32
+ }
lib/php/Mustache/Exception/UnknownHelperException.php CHANGED
@@ -1,32 +1,32 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Unknown helper exception.
14
- */
15
- class Mustache_Exception_UnknownHelperException extends InvalidArgumentException implements Mustache_Exception
16
- {
17
- protected $helperName;
18
-
19
- /**
20
- * @param string $helperName
21
- */
22
- public function __construct($helperName)
23
- {
24
- $this->helperName = $helperName;
25
- parent::__construct(sprintf('Unknown helper: %s', $helperName));
26
- }
27
-
28
- public function getHelperName()
29
- {
30
- return $this->helperName;
31
- }
32
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Unknown helper exception.
14
+ */
15
+ class Mustache_Exception_UnknownHelperException extends InvalidArgumentException implements Mustache_Exception
16
+ {
17
+ protected $helperName;
18
+
19
+ /**
20
+ * @param string $helperName
21
+ */
22
+ public function __construct($helperName)
23
+ {
24
+ $this->helperName = $helperName;
25
+ parent::__construct(sprintf('Unknown helper: %s', $helperName));
26
+ }
27
+
28
+ public function getHelperName()
29
+ {
30
+ return $this->helperName;
31
+ }
32
+ }
lib/php/Mustache/Exception/UnknownTemplateException.php CHANGED
@@ -1,32 +1,32 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Unknown template exception.
14
- */
15
- class Mustache_Exception_UnknownTemplateException extends InvalidArgumentException implements Mustache_Exception
16
- {
17
- protected $templateName;
18
-
19
- /**
20
- * @param string $templateName
21
- */
22
- public function __construct($templateName)
23
- {
24
- $this->templateName = $templateName;
25
- parent::__construct(sprintf('Unknown template: %s', $templateName));
26
- }
27
-
28
- public function getTemplateName()
29
- {
30
- return $this->templateName;
31
- }
32
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Unknown template exception.
14
+ */
15
+ class Mustache_Exception_UnknownTemplateException extends InvalidArgumentException implements Mustache_Exception
16
+ {
17
+ protected $templateName;
18
+
19
+ /**
20
+ * @param string $templateName
21
+ */
22
+ public function __construct($templateName)
23
+ {
24
+ $this->templateName = $templateName;
25
+ parent::__construct(sprintf('Unknown template: %s', $templateName));
26
+ }
27
+
28
+ public function getTemplateName()
29
+ {
30
+ return $this->templateName;
31
+ }
32
+ }
lib/php/Mustache/HelperCollection.php CHANGED
@@ -1,172 +1,172 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * A collection of helpers for a Mustache instance.
14
- */
15
- class Mustache_HelperCollection
16
- {
17
- private $helpers = array();
18
-
19
- /**
20
- * Helper Collection constructor.
21
- *
22
- * Optionally accepts an array (or Traversable) of `$name => $helper` pairs.
23
- *
24
- * @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable
25
- *
26
- * @param array|Traversable $helpers (default: null)
27
- */
28
- public function __construct($helpers = null)
29
- {
30
- if ($helpers === null) {
31
- return;
32
- }
33
-
34
- if (!is_array($helpers) && !$helpers instanceof Traversable) {
35
- throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers');
36
- }
37
-
38
- foreach ($helpers as $name => $helper) {
39
- $this->add($name, $helper);
40
- }
41
- }
42
-
43
- /**
44
- * Magic mutator.
45
- *
46
- * @see Mustache_HelperCollection::add
47
- *
48
- * @param string $name
49
- * @param mixed $helper
50
- */
51
- public function __set($name, $helper)
52
- {
53
- $this->add($name, $helper);
54
- }
55
-
56
- /**
57
- * Add a helper to this collection.
58
- *
59
- * @param string $name
60
- * @param mixed $helper
61
- */
62
- public function add($name, $helper)
63
- {
64
- $this->helpers[$name] = $helper;
65
- }
66
-
67
- /**
68
- * Magic accessor.
69
- *
70
- * @see Mustache_HelperCollection::get
71
- *
72
- * @param string $name
73
- *
74
- * @return mixed Helper
75
- */
76
- public function __get($name)
77
- {
78
- return $this->get($name);
79
- }
80
-
81
- /**
82
- * Get a helper by name.
83
- *
84
- * @throws Mustache_Exception_UnknownHelperException If helper does not exist.
85
- *
86
- * @param string $name
87
- *
88
- * @return mixed Helper
89
- */
90
- public function get($name)
91
- {
92
- if (!$this->has($name)) {
93
- throw new Mustache_Exception_UnknownHelperException($name);
94
- }
95
-
96
- return $this->helpers[$name];
97
- }
98
-
99
- /**
100
- * Magic isset().
101
- *
102
- * @see Mustache_HelperCollection::has
103
- *
104
- * @param string $name
105
- *
106
- * @return bool True if helper is present
107
- */
108
- public function __isset($name)
109
- {
110
- return $this->has($name);
111
- }
112
-
113
- /**
114
- * Check whether a given helper is present in the collection.
115
- *
116
- * @param string $name
117
- *
118
- * @return bool True if helper is present
119
- */
120
- public function has($name)
121
- {
122
- return array_key_exists($name, $this->helpers);
123
- }
124
-
125
- /**
126
- * Magic unset().
127
- *
128
- * @see Mustache_HelperCollection::remove
129
- *
130
- * @param string $name
131
- */
132
- public function __unset($name)
133
- {
134
- $this->remove($name);
135
- }
136
-
137
- /**
138
- * Check whether a given helper is present in the collection.
139
- *
140
- * @throws Mustache_Exception_UnknownHelperException if the requested helper is not present.
141
- *
142
- * @param string $name
143
- */
144
- public function remove($name)
145
- {
146
- if (!$this->has($name)) {
147
- throw new Mustache_Exception_UnknownHelperException($name);
148
- }
149
-
150
- unset($this->helpers[$name]);
151
- }
152
-
153
- /**
154
- * Clear the helper collection.
155
- *
156
- * Removes all helpers from this collection
157
- */
158
- public function clear()
159
- {
160
- $this->helpers = array();
161
- }
162
-
163
- /**
164
- * Check whether the helper collection is empty.
165
- *
166
- * @return bool True if the collection is empty
167
- */
168
- public function isEmpty()
169
- {
170
- return empty($this->helpers);
171
- }
172
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * A collection of helpers for a Mustache instance.
14
+ */
15
+ class Mustache_HelperCollection
16
+ {
17
+ private $helpers = array();
18
+
19
+ /**
20
+ * Helper Collection constructor.
21
+ *
22
+ * Optionally accepts an array (or Traversable) of `$name => $helper` pairs.
23
+ *
24
+ * @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable
25
+ *
26
+ * @param array|Traversable $helpers (default: null)
27
+ */
28
+ public function __construct($helpers = null)
29
+ {
30
+ if ($helpers === null) {
31
+ return;
32
+ }
33
+
34
+ if (!is_array($helpers) && !$helpers instanceof Traversable) {
35
+ throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers');
36
+ }
37
+
38
+ foreach ($helpers as $name => $helper) {
39
+ $this->add($name, $helper);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Magic mutator.
45
+ *
46
+ * @see Mustache_HelperCollection::add
47
+ *
48
+ * @param string $name
49
+ * @param mixed $helper
50
+ */
51
+ public function __set($name, $helper)
52
+ {
53
+ $this->add($name, $helper);
54
+ }
55
+
56
+ /**
57
+ * Add a helper to this collection.
58
+ *
59
+ * @param string $name
60
+ * @param mixed $helper
61
+ */
62
+ public function add($name, $helper)
63
+ {
64
+ $this->helpers[$name] = $helper;
65
+ }
66
+
67
+ /**
68
+ * Magic accessor.
69
+ *
70
+ * @see Mustache_HelperCollection::get
71
+ *
72
+ * @param string $name
73
+ *
74
+ * @return mixed Helper
75
+ */
76
+ public function __get($name)
77
+ {
78
+ return $this->get($name);
79
+ }
80
+
81
+ /**
82
+ * Get a helper by name.
83
+ *
84
+ * @throws Mustache_Exception_UnknownHelperException If helper does not exist.
85
+ *
86
+ * @param string $name
87
+ *
88
+ * @return mixed Helper
89
+ */
90
+ public function get($name)
91
+ {
92
+ if (!$this->has($name)) {
93
+ throw new Mustache_Exception_UnknownHelperException($name);
94
+ }
95
+
96
+ return $this->helpers[$name];
97
+ }
98
+
99
+ /**
100
+ * Magic isset().
101
+ *
102
+ * @see Mustache_HelperCollection::has
103
+ *
104
+ * @param string $name
105
+ *
106
+ * @return bool True if helper is present
107
+ */
108
+ public function __isset($name)
109
+ {
110
+ return $this->has($name);
111
+ }
112
+
113
+ /**
114
+ * Check whether a given helper is present in the collection.
115
+ *
116
+ * @param string $name
117
+ *
118
+ * @return bool True if helper is present
119
+ */
120
+ public function has($name)
121
+ {
122
+ return array_key_exists($name, $this->helpers);
123
+ }
124
+
125
+ /**
126
+ * Magic unset().
127
+ *
128
+ * @see Mustache_HelperCollection::remove
129
+ *
130
+ * @param string $name
131
+ */
132
+ public function __unset($name)
133
+ {
134
+ $this->remove($name);
135
+ }
136
+
137
+ /**
138
+ * Check whether a given helper is present in the collection.
139
+ *
140
+ * @throws Mustache_Exception_UnknownHelperException if the requested helper is not present.
141
+ *
142
+ * @param string $name
143
+ */
144
+ public function remove($name)
145
+ {
146
+ if (!$this->has($name)) {
147
+ throw new Mustache_Exception_UnknownHelperException($name);
148
+ }
149
+
150
+ unset($this->helpers[$name]);
151
+ }
152
+
153
+ /**
154
+ * Clear the helper collection.
155
+ *
156
+ * Removes all helpers from this collection
157
+ */
158
+ public function clear()
159
+ {
160
+ $this->helpers = array();
161
+ }
162
+
163
+ /**
164
+ * Check whether the helper collection is empty.
165
+ *
166
+ * @return bool True if the collection is empty
167
+ */
168
+ public function isEmpty()
169
+ {
170
+ return empty($this->helpers);
171
+ }
172
+ }
lib/php/Mustache/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2010-2015 Justin Hileman
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21
- OR OTHER DEALINGS IN THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2010-2015 Justin Hileman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21
+ OR OTHER DEALINGS IN THE SOFTWARE.
lib/php/Mustache/LambdaHelper.php CHANGED
@@ -1,76 +1,76 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Lambda Helper.
14
- *
15
- * Passed as the second argument to section lambdas (higher order sections),
16
- * giving them access to a `render` method for rendering a string with the
17
- * current context.
18
- */
19
- class Mustache_LambdaHelper
20
- {
21
- private $mustache;
22
- private $context;
23
- private $delims;
24
-
25
- /**
26
- * Mustache Lambda Helper constructor.
27
- *
28
- * @param Mustache_Engine $mustache Mustache engine instance.
29
- * @param Mustache_Context $context Rendering context.
30
- * @param string $delims Optional custom delimiters, in the format `{{= <% %> =}}`. (default: null)
31
- */
32
- public function __construct(Mustache_Engine $mustache, Mustache_Context $context, $delims = null)
33
- {
34
- $this->mustache = $mustache;
35
- $this->context = $context;
36
- $this->delims = $delims;
37
- }
38
-
39
- /**
40
- * Render a string as a Mustache template with the current rendering context.
41
- *
42
- * @param string $string
43
- *
44
- * @return string Rendered template.
45
- */
46
- public function render($string)
47
- {
48
- return $this->mustache
49
- ->loadLambda((string) $string, $this->delims)
50
- ->renderInternal($this->context);
51
- }
52
-
53
- /**
54
- * Render a string as a Mustache template with the current rendering context.
55
- *
56
- * @param string $string
57
- *
58
- * @return string Rendered template
59
- */
60
- public function __invoke($string)
61
- {
62
- return $this->render($string);
63
- }
64
-
65
- /**
66
- * Get a Lambda Helper with custom delimiters.
67
- *
68
- * @param string $delims Custom delimiters, in the format `{{= <% %> =}}`.
69
- *
70
- * @return Mustache_LambdaHelper
71
- */
72
- public function withDelimiters($delims)
73
- {
74
- return new self($this->mustache, $this->context, $delims);
75
- }
76
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Lambda Helper.
14
+ *
15
+ * Passed as the second argument to section lambdas (higher order sections),
16
+ * giving them access to a `render` method for rendering a string with the
17
+ * current context.
18
+ */
19
+ class Mustache_LambdaHelper
20
+ {
21
+ private $mustache;
22
+ private $context;
23
+ private $delims;
24
+
25
+ /**
26
+ * Mustache Lambda Helper constructor.
27
+ *
28
+ * @param Mustache_Engine $mustache Mustache engine instance.
29
+ * @param Mustache_Context $context Rendering context.
30
+ * @param string $delims Optional custom delimiters, in the format `{{= <% %> =}}`. (default: null)
31
+ */
32
+ public function __construct(Mustache_Engine $mustache, Mustache_Context $context, $delims = null)
33
+ {
34
+ $this->mustache = $mustache;
35
+ $this->context = $context;
36
+ $this->delims = $delims;
37
+ }
38
+
39
+ /**
40
+ * Render a string as a Mustache template with the current rendering context.
41
+ *
42
+ * @param string $string
43
+ *
44
+ * @return string Rendered template.
45
+ */
46
+ public function render($string)
47
+ {
48
+ return $this->mustache
49
+ ->loadLambda((string) $string, $this->delims)
50
+ ->renderInternal($this->context);
51
+ }
52
+
53
+ /**
54
+ * Render a string as a Mustache template with the current rendering context.
55
+ *
56
+ * @param string $string
57
+ *
58
+ * @return string Rendered template
59
+ */
60
+ public function __invoke($string)
61
+ {
62
+ return $this->render($string);
63
+ }
64
+
65
+ /**
66
+ * Get a Lambda Helper with custom delimiters.
67
+ *
68
+ * @param string $delims Custom delimiters, in the format `{{= <% %> =}}`.
69
+ *
70
+ * @return Mustache_LambdaHelper
71
+ */
72
+ public function withDelimiters($delims)
73
+ {
74
+ return new self($this->mustache, $this->context, $delims);
75
+ }
76
+ }
lib/php/Mustache/Loader.php CHANGED
@@ -1,27 +1,27 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Template Loader interface.
14
- */
15
- interface Mustache_Loader
16
- {
17
- /**
18
- * Load a Template by name.
19
- *
20
- * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
21
- *
22
- * @param string $name
23
- *
24
- * @return string Mustache Template source
25
- */
26
- public function load($name);
27
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Template Loader interface.
14
+ */
15
+ interface Mustache_Loader
16
+ {
17
+ /**
18
+ * Load a Template by name.
19
+ *
20
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
21
+ *
22
+ * @param string $name
23
+ *
24
+ * @return string Mustache Template source
25
+ */
26
+ public function load($name);
27
+ }
lib/php/Mustache/Loader/ArrayLoader.php CHANGED
@@ -1,79 +1,79 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Template array Loader implementation.
14
- *
15
- * An ArrayLoader instance loads Mustache Template source by name from an initial array:
16
- *
17
- * $loader = new ArrayLoader(
18
- * 'foo' => '{{ bar }}',
19
- * 'baz' => 'Hey {{ qux }}!'
20
- * );
21
- *
22
- * $tpl = $loader->load('foo'); // '{{ bar }}'
23
- *
24
- * The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials
25
- * is set. It can also be used as a quick-and-dirty Template loader.
26
- */
27
- class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader
28
- {
29
- private $templates;
30
-
31
- /**
32
- * ArrayLoader constructor.
33
- *
34
- * @param array $templates Associative array of Template source (default: array())
35
- */
36
- public function __construct(array $templates = array())
37
- {
38
- $this->templates = $templates;
39
- }
40
-
41
- /**
42
- * Load a Template.
43
- *
44
- * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
45
- *
46
- * @param string $name
47
- *
48
- * @return string Mustache Template source
49
- */
50
- public function load($name)
51
- {
52
- if (!isset($this->templates[$name])) {
53
- throw new Mustache_Exception_UnknownTemplateException($name);
54
- }
55
-
56
- return $this->templates[$name];
57
- }
58
-
59
- /**
60
- * Set an associative array of Template sources for this loader.
61
- *
62
- * @param array $templates
63
- */
64
- public function setTemplates(array $templates)
65
- {
66
- $this->templates = $templates;
67
- }
68
-
69
- /**
70
- * Set a Template source by name.
71
- *
72
- * @param string $name
73
- * @param string $template Mustache Template source
74
- */
75
- public function setTemplate($name, $template)
76
- {
77
- $this->templates[$name] = $template;
78
- }
79
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Template array Loader implementation.
14
+ *
15
+ * An ArrayLoader instance loads Mustache Template source by name from an initial array:
16
+ *
17
+ * $loader = new ArrayLoader(
18
+ * 'foo' => '{{ bar }}',
19
+ * 'baz' => 'Hey {{ qux }}!'
20
+ * );
21
+ *
22
+ * $tpl = $loader->load('foo'); // '{{ bar }}'
23
+ *
24
+ * The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials
25
+ * is set. It can also be used as a quick-and-dirty Template loader.
26
+ */
27
+ class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader
28
+ {
29
+ private $templates;
30
+
31
+ /**
32
+ * ArrayLoader constructor.
33
+ *
34
+ * @param array $templates Associative array of Template source (default: array())
35
+ */
36
+ public function __construct(array $templates = array())
37
+ {
38
+ $this->templates = $templates;
39
+ }
40
+
41
+ /**
42
+ * Load a Template.
43
+ *
44
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
45
+ *
46
+ * @param string $name
47
+ *
48
+ * @return string Mustache Template source
49
+ */
50
+ public function load($name)
51
+ {
52
+ if (!isset($this->templates[$name])) {
53
+ throw new Mustache_Exception_UnknownTemplateException($name);
54
+ }
55
+
56
+ return $this->templates[$name];
57
+ }
58
+
59
+ /**
60
+ * Set an associative array of Template sources for this loader.
61
+ *
62
+ * @param array $templates
63
+ */
64
+ public function setTemplates(array $templates)
65
+ {
66
+ $this->templates = $templates;
67
+ }
68
+
69
+ /**
70
+ * Set a Template source by name.
71
+ *
72
+ * @param string $name
73
+ * @param string $template Mustache Template source
74
+ */
75
+ public function setTemplate($name, $template)
76
+ {
77
+ $this->templates[$name] = $template;
78
+ }
79
+ }
lib/php/Mustache/Loader/CascadingLoader.php CHANGED
@@ -1,69 +1,69 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * A Mustache Template cascading loader implementation, which delegates to other
14
- * Loader instances.
15
- */
16
- class Mustache_Loader_CascadingLoader implements Mustache_Loader
17
- {
18
- private $loaders;
19
-
20
- /**
21
- * Construct a CascadingLoader with an array of loaders.
22
- *
23
- * $loader = new Mustache_Loader_CascadingLoader(array(
24
- * new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__),
25
- * new Mustache_Loader_FilesystemLoader(__DIR__.'/templates')
26
- * ));
27
- *
28
- * @param Mustache_Loader[] $loaders
29
- */
30
- public function __construct(array $loaders = array())
31
- {
32
- $this->loaders = array();
33
- foreach ($loaders as $loader) {
34
- $this->addLoader($loader);
35
- }
36
- }
37
-
38
- /**
39
- * Add a Loader instance.
40
- *
41
- * @param Mustache_Loader $loader
42
- */
43
- public function addLoader(Mustache_Loader $loader)
44
- {
45
- $this->loaders[] = $loader;
46
- }
47
-
48
- /**
49
- * Load a Template by name.
50
- *
51
- * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
52
- *
53
- * @param string $name
54
- *
55
- * @return string Mustache Template source
56
- */
57
- public function load($name)
58
- {
59
- foreach ($this->loaders as $loader) {
60
- try {
61
- return $loader->load($name);
62
- } catch (Mustache_Exception_UnknownTemplateException $e) {
63
- // do nothing, check the next loader.
64
- }
65
- }
66
-
67
- throw new Mustache_Exception_UnknownTemplateException($name);
68
- }
69
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * A Mustache Template cascading loader implementation, which delegates to other
14
+ * Loader instances.
15
+ */
16
+ class Mustache_Loader_CascadingLoader implements Mustache_Loader
17
+ {
18
+ private $loaders;
19
+
20
+ /**
21
+ * Construct a CascadingLoader with an array of loaders.
22
+ *
23
+ * $loader = new Mustache_Loader_CascadingLoader(array(
24
+ * new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__),
25
+ * new Mustache_Loader_FilesystemLoader(__DIR__.'/templates')
26
+ * ));
27
+ *
28
+ * @param Mustache_Loader[] $loaders
29
+ */
30
+ public function __construct(array $loaders = array())
31
+ {
32
+ $this->loaders = array();
33
+ foreach ($loaders as $loader) {
34
+ $this->addLoader($loader);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Add a Loader instance.
40
+ *
41
+ * @param Mustache_Loader $loader
42
+ */
43
+ public function addLoader(Mustache_Loader $loader)
44
+ {
45
+ $this->loaders[] = $loader;
46
+ }
47
+
48
+ /**
49
+ * Load a Template by name.
50
+ *
51
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
52
+ *
53
+ * @param string $name
54
+ *
55
+ * @return string Mustache Template source
56
+ */
57
+ public function load($name)
58
+ {
59
+ foreach ($this->loaders as $loader) {
60
+ try {
61
+ return $loader->load($name);
62
+ } catch (Mustache_Exception_UnknownTemplateException $e) {
63
+ // do nothing, check the next loader.
64
+ }
65
+ }
66
+
67
+ throw new Mustache_Exception_UnknownTemplateException($name);
68
+ }
69
+ }
lib/php/Mustache/Loader/FilesystemLoader.php CHANGED
@@ -1,124 +1,124 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Template filesystem Loader implementation.
14
- *
15
- * A FilesystemLoader instance loads Mustache Template source from the filesystem by name:
16
- *
17
- * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
18
- * $tpl = $loader->load('foo'); // equivalent to `file_get_contents(dirname(__FILE__).'/views/foo.mustache');
19
- *
20
- * This is probably the most useful Mustache Loader implementation. It can be used for partials and normal Templates:
21
- *
22
- * $m = new Mustache(array(
23
- * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
24
- * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
25
- * ));
26
- */
27
- class Mustache_Loader_FilesystemLoader implements Mustache_Loader
28
- {
29
- private $baseDir;
30
- private $extension = '.mustache';
31
- private $templates = array();
32
-
33
- /**
34
- * Mustache filesystem Loader constructor.
35
- *
36
- * Passing an $options array allows overriding certain Loader options during instantiation:
37
- *
38
- * $options = array(
39
- * // The filename extension used for Mustache templates. Defaults to '.mustache'
40
- * 'extension' => '.ms',
41
- * );
42
- *
43
- * @throws Mustache_Exception_RuntimeException if $baseDir does not exist.
44
- *
45
- * @param string $baseDir Base directory containing Mustache template files.
46
- * @param array $options Array of Loader options (default: array())
47
- */
48
- public function __construct($baseDir, array $options = array())
49
- {
50
- $this->baseDir = $baseDir;
51
-
52
- if (strpos($this->baseDir, '://') === false) {
53
- $this->baseDir = realpath($this->baseDir);
54
- }
55
-
56
- if (!is_dir($this->baseDir)) {
57
- throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir));
58
- }
59
-
60
- if (array_key_exists('extension', $options)) {
61
- if (empty($options['extension'])) {
62
- $this->extension = '';
63
- } else {
64
- $this->extension = '.' . ltrim($options['extension'], '.');
65
- }
66
- }
67
- }
68
-
69
- /**
70
- * Load a Template by name.
71
- *
72
- * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
73
- * $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache";
74
- *
75
- * @param string $name
76
- *
77
- * @return string Mustache Template source
78
- */
79
- public function load($name)
80
- {
81
- if (!isset($this->templates[$name])) {
82
- $this->templates[$name] = $this->loadFile($name);
83
- }
84
-
85
- return $this->templates[$name];
86
- }
87
-
88
- /**
89
- * Helper function for loading a Mustache file by name.
90
- *
91
- * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
92
- *
93
- * @param string $name
94
- *
95
- * @return string Mustache Template source
96
- */
97
- protected function loadFile($name)
98
- {
99
- $fileName = $this->getFileName($name);
100
-
101
- if (!file_exists($fileName)) {
102
- throw new Mustache_Exception_UnknownTemplateException($name);
103
- }
104
-
105
- return file_get_contents($fileName);
106
- }
107
-
108
- /**
109
- * Helper function for getting a Mustache template file name.
110
- *
111
- * @param string $name
112
- *
113
- * @return string Template file name
114
- */
115
- protected function getFileName($name)
116
- {
117
- $fileName = $this->baseDir . '/' . $name;
118
- if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
119
- $fileName .= $this->extension;
120
- }
121
-
122
- return $fileName;
123
- }
124
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Template filesystem Loader implementation.
14
+ *
15
+ * A FilesystemLoader instance loads Mustache Template source from the filesystem by name:
16
+ *
17
+ * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
18
+ * $tpl = $loader->load('foo'); // equivalent to `file_get_contents(dirname(__FILE__).'/views/foo.mustache');
19
+ *
20
+ * This is probably the most useful Mustache Loader implementation. It can be used for partials and normal Templates:
21
+ *
22
+ * $m = new Mustache(array(
23
+ * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
24
+ * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
25
+ * ));
26
+ */
27
+ class Mustache_Loader_FilesystemLoader implements Mustache_Loader
28
+ {
29
+ private $baseDir;
30
+ private $extension = '.mustache';
31
+ private $templates = array();
32
+
33
+ /**
34
+ * Mustache filesystem Loader constructor.
35
+ *
36
+ * Passing an $options array allows overriding certain Loader options during instantiation:
37
+ *
38
+ * $options = array(
39
+ * // The filename extension used for Mustache templates. Defaults to '.mustache'
40
+ * 'extension' => '.ms',
41
+ * );
42
+ *
43
+ * @throws Mustache_Exception_RuntimeException if $baseDir does not exist.
44
+ *
45
+ * @param string $baseDir Base directory containing Mustache template files.
46
+ * @param array $options Array of Loader options (default: array())
47
+ */
48
+ public function __construct($baseDir, array $options = array())
49
+ {
50
+ $this->baseDir = $baseDir;
51
+
52
+ if (strpos($this->baseDir, '://') === false) {
53
+ $this->baseDir = realpath($this->baseDir);
54
+ }
55
+
56
+ if (!is_dir($this->baseDir)) {
57
+ throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir));
58
+ }
59
+
60
+ if (array_key_exists('extension', $options)) {
61
+ if (empty($options['extension'])) {
62
+ $this->extension = '';
63
+ } else {
64
+ $this->extension = '.' . ltrim($options['extension'], '.');
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Load a Template by name.
71
+ *
72
+ * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
73
+ * $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache";
74
+ *
75
+ * @param string $name
76
+ *
77
+ * @return string Mustache Template source
78
+ */
79
+ public function load($name)
80
+ {
81
+ if (!isset($this->templates[$name])) {
82
+ $this->templates[$name] = $this->loadFile($name);
83
+ }
84
+
85
+ return $this->templates[$name];
86
+ }
87
+
88
+ /**
89
+ * Helper function for loading a Mustache file by name.
90
+ *
91
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
92
+ *
93
+ * @param string $name
94
+ *
95
+ * @return string Mustache Template source
96
+ */
97
+ protected function loadFile($name)
98
+ {
99
+ $fileName = $this->getFileName($name);
100
+
101
+ if (!file_exists($fileName)) {
102
+ throw new Mustache_Exception_UnknownTemplateException($name);
103
+ }
104
+
105
+ return file_get_contents($fileName);
106
+ }
107
+
108
+ /**
109
+ * Helper function for getting a Mustache template file name.
110
+ *
111
+ * @param string $name
112
+ *
113
+ * @return string Template file name
114
+ */
115
+ protected function getFileName($name)
116
+ {
117
+ $fileName = $this->baseDir . '/' . $name;
118
+ if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
119
+ $fileName .= $this->extension;
120
+ }
121
+
122
+ return $fileName;
123
+ }
124
+ }
lib/php/Mustache/Loader/InlineLoader.php CHANGED
@@ -1,123 +1,123 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * A Mustache Template loader for inline templates.
14
- *
15
- * With the InlineLoader, templates can be defined at the end of any PHP source
16
- * file:
17
- *
18
- * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
19
- * $hello = $loader->load('hello');
20
- * $goodbye = $loader->load('goodbye');
21
- *
22
- * __halt_compiler();
23
- *
24
- * @@ hello
25
- * Hello, {{ planet }}!
26
- *
27
- * @@ goodbye
28
- * Goodbye, cruel {{ planet }}
29
- *
30
- * Templates are deliniated by lines containing only `@@ name`.
31
- *
32
- * The InlineLoader is well-suited to micro-frameworks such as Silex:
33
- *
34
- * $app->register(new MustacheServiceProvider, array(
35
- * 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__)
36
- * ));
37
- *
38
- * $app->get('/{name}', function ($name) use ($app) {
39
- * return $app['mustache']->render('hello', compact('name'));
40
- * })
41
- * ->value('name', 'world');
42
- *
43
- * // ...
44
- *
45
- * __halt_compiler();
46
- *
47
- * @@ hello
48
- * Hello, {{ name }}!
49
- */
50
- class Mustache_Loader_InlineLoader implements Mustache_Loader
51
- {
52
- protected $fileName;
53
- protected $offset;
54
- protected $templates;
55
-
56
- /**
57
- * The InlineLoader requires a filename and offset to process templates.
58
- *
59
- * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually
60
- * perfectly suited to the job:
61
- *
62
- * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
63
- *
64
- * Note that this only works if the loader is instantiated inside the same
65
- * file as the inline templates. If the templates are located in another
66
- * file, it would be necessary to manually specify the filename and offset.
67
- *
68
- * @param string $fileName The file to parse for inline templates
69
- * @param int $offset A string offset for the start of the templates.
70
- * This usually coincides with the `__halt_compiler`
71
- * call, and the `__COMPILER_HALT_OFFSET__`.
72
- */
73
- public function __construct($fileName, $offset)
74
- {
75
- if (!is_file($fileName)) {
76
- throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.');
77
- }
78
-
79
- if (!is_int($offset) || $offset < 0) {
80
- throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.');
81
- }
82
-
83
- $this->fileName = $fileName;
84
- $this->offset = $offset;
85
- }
86
-
87
- /**
88
- * Load a Template by name.
89
- *
90
- * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
91
- *
92
- * @param string $name
93
- *
94
- * @return string Mustache Template source
95
- */
96
- public function load($name)
97
- {
98
- $this->loadTemplates();
99
-
100
- if (!array_key_exists($name, $this->templates)) {
101
- throw new Mustache_Exception_UnknownTemplateException($name);
102
- }
103
-
104
- return $this->templates[$name];
105
- }
106
-
107
- /**
108
- * Parse and load templates from the end of a source file.
109
- */
110
- protected function loadTemplates()
111
- {
112
- if ($this->templates === null) {
113
- $this->templates = array();
114
- $data = file_get_contents($this->fileName, false, null, $this->offset);
115
- foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) {
116
- if (trim($chunk)) {
117
- list($name, $content) = explode("\n", $chunk, 2);
118
- $this->templates[trim($name)] = trim($content);
119
- }
120
- }
121
- }
122
- }
123
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * A Mustache Template loader for inline templates.
14
+ *
15
+ * With the InlineLoader, templates can be defined at the end of any PHP source
16
+ * file:
17
+ *
18
+ * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
19
+ * $hello = $loader->load('hello');
20
+ * $goodbye = $loader->load('goodbye');
21
+ *
22
+ * __halt_compiler();
23
+ *
24
+ * @@ hello
25
+ * Hello, {{ planet }}!
26
+ *
27
+ * @@ goodbye
28
+ * Goodbye, cruel {{ planet }}
29
+ *
30
+ * Templates are deliniated by lines containing only `@@ name`.
31
+ *
32
+ * The InlineLoader is well-suited to micro-frameworks such as Silex:
33
+ *
34
+ * $app->register(new MustacheServiceProvider, array(
35
+ * 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__)
36
+ * ));
37
+ *
38
+ * $app->get('/{name}', function ($name) use ($app) {
39
+ * return $app['mustache']->render('hello', compact('name'));
40
+ * })
41
+ * ->value('name', 'world');
42
+ *
43
+ * // ...
44
+ *
45
+ * __halt_compiler();
46
+ *
47
+ * @@ hello
48
+ * Hello, {{ name }}!
49
+ */
50
+ class Mustache_Loader_InlineLoader implements Mustache_Loader
51
+ {
52
+ protected $fileName;
53
+ protected $offset;
54
+ protected $templates;
55
+
56
+ /**
57
+ * The InlineLoader requires a filename and offset to process templates.
58
+ *
59
+ * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually
60
+ * perfectly suited to the job:
61
+ *
62
+ * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
63
+ *
64
+ * Note that this only works if the loader is instantiated inside the same
65
+ * file as the inline templates. If the templates are located in another
66
+ * file, it would be necessary to manually specify the filename and offset.
67
+ *
68
+ * @param string $fileName The file to parse for inline templates
69
+ * @param int $offset A string offset for the start of the templates.
70
+ * This usually coincides with the `__halt_compiler`
71
+ * call, and the `__COMPILER_HALT_OFFSET__`.
72
+ */
73
+ public function __construct($fileName, $offset)
74
+ {
75
+ if (!is_file($fileName)) {
76
+ throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.');
77
+ }
78
+
79
+ if (!is_int($offset) || $offset < 0) {
80
+ throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.');
81
+ }
82
+
83
+ $this->fileName = $fileName;
84
+ $this->offset = $offset;
85
+ }
86
+
87
+ /**
88
+ * Load a Template by name.
89
+ *
90
+ * @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
91
+ *
92
+ * @param string $name
93
+ *
94
+ * @return string Mustache Template source
95
+ */
96
+ public function load($name)
97
+ {
98
+ $this->loadTemplates();
99
+
100
+ if (!array_key_exists($name, $this->templates)) {
101
+ throw new Mustache_Exception_UnknownTemplateException($name);
102
+ }
103
+
104
+ return $this->templates[$name];
105
+ }
106
+
107
+ /**
108
+ * Parse and load templates from the end of a source file.
109
+ */
110
+ protected function loadTemplates()
111
+ {
112
+ if ($this->templates === null) {
113
+ $this->templates = array();
114
+ $data = file_get_contents($this->fileName, false, null, $this->offset);
115
+ foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) {
116
+ if (trim($chunk)) {
117
+ list($name, $content) = explode("\n", $chunk, 2);
118
+ $this->templates[trim($name)] = trim($content);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
lib/php/Mustache/Loader/MutableLoader.php CHANGED
@@ -1,31 +1,31 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Template mutable Loader interface.
14
- */
15
- interface Mustache_Loader_MutableLoader
16
- {
17
- /**
18
- * Set an associative array of Template sources for this loader.
19
- *
20
- * @param array $templates
21
- */
22
- public function setTemplates(array $templates);
23
-
24
- /**
25
- * Set a Template source by name.
26
- *
27
- * @param string $name
28
- * @param string $template Mustache Template source
29
- */
30
- public function setTemplate($name, $template);
31
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Template mutable Loader interface.
14
+ */
15
+ interface Mustache_Loader_MutableLoader
16
+ {
17
+ /**
18
+ * Set an associative array of Template sources for this loader.
19
+ *
20
+ * @param array $templates
21
+ */
22
+ public function setTemplates(array $templates);
23
+
24
+ /**
25
+ * Set a Template source by name.
26
+ *
27
+ * @param string $name
28
+ * @param string $template Mustache Template source
29
+ */
30
+ public function setTemplate($name, $template);
31
+ }
lib/php/Mustache/Loader/StringLoader.php CHANGED
@@ -1,39 +1,39 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Template string Loader implementation.
14
- *
15
- * A StringLoader instance is essentially a noop. It simply passes the 'name' argument straight through:
16
- *
17
- * $loader = new StringLoader;
18
- * $tpl = $loader->load('{{ foo }}'); // '{{ foo }}'
19
- *
20
- * This is the default Template Loader instance used by Mustache:
21
- *
22
- * $m = new Mustache;
23
- * $tpl = $m->loadTemplate('{{ foo }}');
24
- * echo $tpl->render(array('foo' => 'bar')); // "bar"
25
- */
26
- class Mustache_Loader_StringLoader implements Mustache_Loader
27
- {
28
- /**
29
- * Load a Template by source.
30
- *
31
- * @param string $name Mustache Template source
32
- *
33
- * @return string Mustache Template source
34
- */
35
- public function load($name)
36
- {
37
- return $name;
38
- }
39
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Template string Loader implementation.
14
+ *
15
+ * A StringLoader instance is essentially a noop. It simply passes the 'name' argument straight through:
16
+ *
17
+ * $loader = new StringLoader;
18
+ * $tpl = $loader->load('{{ foo }}'); // '{{ foo }}'
19
+ *
20
+ * This is the default Template Loader instance used by Mustache:
21
+ *
22
+ * $m = new Mustache;
23
+ * $tpl = $m->loadTemplate('{{ foo }}');
24
+ * echo $tpl->render(array('foo' => 'bar')); // "bar"
25
+ */
26
+ class Mustache_Loader_StringLoader implements Mustache_Loader
27
+ {
28
+ /**
29
+ * Load a Template by source.
30
+ *
31
+ * @param string $name Mustache Template source
32
+ *
33
+ * @return string Mustache Template source
34
+ */
35
+ public function load($name)
36
+ {
37
+ return $name;
38
+ }
39
+ }
lib/php/Mustache/Logger.php CHANGED
@@ -1,126 +1,126 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Describes a Mustache logger instance.
14
- *
15
- * This is identical to the Psr\Log\LoggerInterface.
16
- *
17
- * The message MUST be a string or object implementing __toString().
18
- *
19
- * The message MAY contain placeholders in the form: {foo} where foo
20
- * will be replaced by the context data in key "foo".
21
- *
22
- * The context array can contain arbitrary data, the only assumption that
23
- * can be made by implementors is that if an Exception instance is given
24
- * to produce a stack trace, it MUST be in a key named "exception".
25
- *
26
- * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
27
- * for the full interface specification.
28
- */
29
- interface Mustache_Logger
30
- {
31
- /**
32
- * Psr\Log compatible log levels.
33
- */
34
- const EMERGENCY = 'emergency';
35
- const ALERT = 'alert';
36
- const CRITICAL = 'critical';
37
- const ERROR = 'error';
38
- const WARNING = 'warning';
39
- const NOTICE = 'notice';
40
- const INFO = 'info';
41
- const DEBUG = 'debug';
42
-
43
- /**
44
- * System is unusable.
45
- *
46
- * @param string $message
47
- * @param array $context
48
- */
49
- public function emergency($message, array $context = array());
50
-
51
- /**
52
- * Action must be taken immediately.
53
- *
54
- * Example: Entire website down, database unavailable, etc. This should
55
- * trigger the SMS alerts and wake you up.
56
- *
57
- * @param string $message
58
- * @param array $context
59
- */
60
- public function alert($message, array $context = array());
61
-
62
- /**
63
- * Critical conditions.
64
- *
65
- * Example: Application component unavailable, unexpected exception.
66
- *
67
- * @param string $message
68
- * @param array $context
69
- */
70
- public function critical($message, array $context = array());
71
-
72
- /**
73
- * Runtime errors that do not require immediate action but should typically
74
- * be logged and monitored.
75
- *
76
- * @param string $message
77
- * @param array $context
78
- */
79
- public function error($message, array $context = array());
80
-
81
- /**
82
- * Exceptional occurrences that are not errors.
83
- *
84
- * Example: Use of deprecated APIs, poor use of an API, undesirable things
85
- * that are not necessarily wrong.
86
- *
87
- * @param string $message
88
- * @param array $context
89
- */
90
- public function warning($message, array $context = array());
91
-
92
- /**
93
- * Normal but significant events.
94
- *
95
- * @param string $message
96
- * @param array $context
97
- */
98
- public function notice($message, array $context = array());
99
-
100
- /**
101
- * Interesting events.
102
- *
103
- * Example: User logs in, SQL logs.
104
- *
105
- * @param string $message
106
- * @param array $context
107
- */
108
- public function info($message, array $context = array());
109
-
110
- /**
111
- * Detailed debug information.
112
- *
113
- * @param string $message
114
- * @param array $context
115
- */
116
- public function debug($message, array $context = array());
117
-
118
- /**
119
- * Logs with an arbitrary level.
120
- *
121
- * @param mixed $level
122
- * @param string $message
123
- * @param array $context
124
- */
125
- public function log($level, $message, array $context = array());
126
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Describes a Mustache logger instance.
14
+ *
15
+ * This is identical to the Psr\Log\LoggerInterface.
16
+ *
17
+ * The message MUST be a string or object implementing __toString().
18
+ *
19
+ * The message MAY contain placeholders in the form: {foo} where foo
20
+ * will be replaced by the context data in key "foo".
21
+ *
22
+ * The context array can contain arbitrary data, the only assumption that
23
+ * can be made by implementors is that if an Exception instance is given
24
+ * to produce a stack trace, it MUST be in a key named "exception".
25
+ *
26
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
27
+ * for the full interface specification.
28
+ */
29
+ interface Mustache_Logger
30
+ {
31
+ /**
32
+ * Psr\Log compatible log levels.
33
+ */
34
+ const EMERGENCY = 'emergency';
35
+ const ALERT = 'alert';
36
+ const CRITICAL = 'critical';
37
+ const ERROR = 'error';
38
+ const WARNING = 'warning';
39
+ const NOTICE = 'notice';
40
+ const INFO = 'info';
41
+ const DEBUG = 'debug';
42
+
43
+ /**
44
+ * System is unusable.
45
+ *
46
+ * @param string $message
47
+ * @param array $context
48
+ */
49
+ public function emergency($message, array $context = array());
50
+
51
+ /**
52
+ * Action must be taken immediately.
53
+ *
54
+ * Example: Entire website down, database unavailable, etc. This should
55
+ * trigger the SMS alerts and wake you up.
56
+ *
57
+ * @param string $message
58
+ * @param array $context
59
+ */
60
+ public function alert($message, array $context = array());
61
+
62
+ /**
63
+ * Critical conditions.
64
+ *
65
+ * Example: Application component unavailable, unexpected exception.
66
+ *
67
+ * @param string $message
68
+ * @param array $context
69
+ */
70
+ public function critical($message, array $context = array());
71
+
72
+ /**
73
+ * Runtime errors that do not require immediate action but should typically
74
+ * be logged and monitored.
75
+ *
76
+ * @param string $message
77
+ * @param array $context
78
+ */
79
+ public function error($message, array $context = array());
80
+
81
+ /**
82
+ * Exceptional occurrences that are not errors.
83
+ *
84
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
85
+ * that are not necessarily wrong.
86
+ *
87
+ * @param string $message
88
+ * @param array $context
89
+ */
90
+ public function warning($message, array $context = array());
91
+
92
+ /**
93
+ * Normal but significant events.
94
+ *
95
+ * @param string $message
96
+ * @param array $context
97
+ */
98
+ public function notice($message, array $context = array());
99
+
100
+ /**
101
+ * Interesting events.
102
+ *
103
+ * Example: User logs in, SQL logs.
104
+ *
105
+ * @param string $message
106
+ * @param array $context
107
+ */
108
+ public function info($message, array $context = array());
109
+
110
+ /**
111
+ * Detailed debug information.
112
+ *
113
+ * @param string $message
114
+ * @param array $context
115
+ */
116
+ public function debug($message, array $context = array());
117
+
118
+ /**
119
+ * Logs with an arbitrary level.
120
+ *
121
+ * @param mixed $level
122
+ * @param string $message
123
+ * @param array $context
124
+ */
125
+ public function log($level, $message, array $context = array());
126
+ }
lib/php/Mustache/Logger/AbstractLogger.php CHANGED
@@ -1,121 +1,121 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * This is a simple Logger implementation that other Loggers can inherit from.
14
- *
15
- * This is identical to the Psr\Log\AbstractLogger.
16
- *
17
- * It simply delegates all log-level-specific methods to the `log` method to
18
- * reduce boilerplate code that a simple Logger that does the same thing with
19
- * messages regardless of the error level has to implement.
20
- */
21
- abstract class Mustache_Logger_AbstractLogger implements Mustache_Logger
22
- {
23
- /**
24
- * System is unusable.
25
- *
26
- * @param string $message
27
- * @param array $context
28
- */
29
- public function emergency($message, array $context = array())
30
- {
31
- $this->log(Mustache_Logger::EMERGENCY, $message, $context);
32
- }
33
-
34
- /**
35
- * Action must be taken immediately.
36
- *
37
- * Example: Entire website down, database unavailable, etc. This should
38
- * trigger the SMS alerts and wake you up.
39
- *
40
- * @param string $message
41
- * @param array $context
42
- */
43
- public function alert($message, array $context = array())
44
- {
45
- $this->log(Mustache_Logger::ALERT, $message, $context);
46
- }
47
-
48
- /**
49
- * Critical conditions.
50
- *
51
- * Example: Application component unavailable, unexpected exception.
52
- *
53
- * @param string $message
54
- * @param array $context
55
- */
56
- public function critical($message, array $context = array())
57
- {
58
- $this->log(Mustache_Logger::CRITICAL, $message, $context);
59
- }
60
-
61
- /**
62
- * Runtime errors that do not require immediate action but should typically
63
- * be logged and monitored.
64
- *
65
- * @param string $message
66
- * @param array $context
67
- */
68
- public function error($message, array $context = array())
69
- {
70
- $this->log(Mustache_Logger::ERROR, $message, $context);
71
- }
72
-
73
- /**
74
- * Exceptional occurrences that are not errors.
75
- *
76
- * Example: Use of deprecated APIs, poor use of an API, undesirable things
77
- * that are not necessarily wrong.
78
- *
79
- * @param string $message
80
- * @param array $context
81
- */
82
- public function warning($message, array $context = array())
83
- {
84
- $this->log(Mustache_Logger::WARNING, $message, $context);
85
- }
86
-
87
- /**
88
- * Normal but significant events.
89
- *
90
- * @param string $message
91
- * @param array $context
92
- */
93
- public function notice($message, array $context = array())
94
- {
95
- $this->log(Mustache_Logger::NOTICE, $message, $context);
96
- }
97
-
98
- /**
99
- * Interesting events.
100
- *
101
- * Example: User logs in, SQL logs.
102
- *
103
- * @param string $message
104
- * @param array $context
105
- */
106
- public function info($message, array $context = array())
107
- {
108
- $this->log(Mustache_Logger::INFO, $message, $context);
109
- }
110
-
111
- /**
112
- * Detailed debug information.
113
- *
114
- * @param string $message
115
- * @param array $context
116
- */
117
- public function debug($message, array $context = array())
118
- {
119
- $this->log(Mustache_Logger::DEBUG, $message, $context);
120
- }
121
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * This is a simple Logger implementation that other Loggers can inherit from.
14
+ *
15
+ * This is identical to the Psr\Log\AbstractLogger.
16
+ *
17
+ * It simply delegates all log-level-specific methods to the `log` method to
18
+ * reduce boilerplate code that a simple Logger that does the same thing with
19
+ * messages regardless of the error level has to implement.
20
+ */
21
+ abstract class Mustache_Logger_AbstractLogger implements Mustache_Logger
22
+ {
23
+ /**
24
+ * System is unusable.
25
+ *
26
+ * @param string $message
27
+ * @param array $context
28
+ */
29
+ public function emergency($message, array $context = array())
30
+ {
31
+ $this->log(Mustache_Logger::EMERGENCY, $message, $context);
32
+ }
33
+
34
+ /**
35
+ * Action must be taken immediately.
36
+ *
37
+ * Example: Entire website down, database unavailable, etc. This should
38
+ * trigger the SMS alerts and wake you up.
39
+ *
40
+ * @param string $message
41
+ * @param array $context
42
+ */
43
+ public function alert($message, array $context = array())
44
+ {
45
+ $this->log(Mustache_Logger::ALERT, $message, $context);
46
+ }
47
+
48
+ /**
49
+ * Critical conditions.
50
+ *
51
+ * Example: Application component unavailable, unexpected exception.
52
+ *
53
+ * @param string $message
54
+ * @param array $context
55
+ */
56
+ public function critical($message, array $context = array())
57
+ {
58
+ $this->log(Mustache_Logger::CRITICAL, $message, $context);
59
+ }
60
+
61
+ /**
62
+ * Runtime errors that do not require immediate action but should typically
63
+ * be logged and monitored.
64
+ *
65
+ * @param string $message
66
+ * @param array $context
67
+ */
68
+ public function error($message, array $context = array())
69
+ {
70
+ $this->log(Mustache_Logger::ERROR, $message, $context);
71
+ }
72
+
73
+ /**
74
+ * Exceptional occurrences that are not errors.
75
+ *
76
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
77
+ * that are not necessarily wrong.
78
+ *
79
+ * @param string $message
80
+ * @param array $context
81
+ */
82
+ public function warning($message, array $context = array())
83
+ {
84
+ $this->log(Mustache_Logger::WARNING, $message, $context);
85
+ }
86
+
87
+ /**
88
+ * Normal but significant events.
89
+ *
90
+ * @param string $message
91
+ * @param array $context
92
+ */
93
+ public function notice($message, array $context = array())
94
+ {
95
+ $this->log(Mustache_Logger::NOTICE, $message, $context);
96
+ }
97
+
98
+ /**
99
+ * Interesting events.
100
+ *
101
+ * Example: User logs in, SQL logs.
102
+ *
103
+ * @param string $message
104
+ * @param array $context
105
+ */
106
+ public function info($message, array $context = array())
107
+ {
108
+ $this->log(Mustache_Logger::INFO, $message, $context);
109
+ }
110
+
111
+ /**
112
+ * Detailed debug information.
113
+ *
114
+ * @param string $message
115
+ * @param array $context
116
+ */
117
+ public function debug($message, array $context = array())
118
+ {
119
+ $this->log(Mustache_Logger::DEBUG, $message, $context);
120
+ }
121
+ }
lib/php/Mustache/Logger/StreamLogger.php CHANGED
@@ -1,194 +1,194 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * A Mustache Stream Logger.
14
- *
15
- * The Stream Logger wraps a file resource instance (such as a stream) or a
16
- * stream URL. All log messages over the threshold level will be appended to
17
- * this stream.
18
- *
19
- * Hint: Try `php://stderr` for your stream URL.
20
- */
21
- class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
22
- {
23
- protected static $levels = array(
24
- self::DEBUG => 100,
25
- self::INFO => 200,
26
- self::NOTICE => 250,
27
- self::WARNING => 300,
28
- self::ERROR => 400,
29
- self::CRITICAL => 500,
30
- self::ALERT => 550,
31
- self::EMERGENCY => 600,
32
- );
33
-
34
- protected $level;
35
- protected $stream = null;
36
- protected $url = null;
37
-
38
- /**
39
- * @throws InvalidArgumentException if the logging level is unknown.
40
- *
41
- * @param resource|string $stream Resource instance or URL
42
- * @param int $level The minimum logging level at which this handler will be triggered
43
- */
44
- public function __construct($stream, $level = Mustache_Logger::ERROR)
45
- {
46
- $this->setLevel($level);
47
-
48
- if (is_resource($stream)) {
49
- $this->stream = $stream;
50
- } else {
51
- $this->url = $stream;
52
- }
53
- }
54
-
55
- /**
56
- * Close stream resources.
57
- */
58
- public function __destruct()
59
- {
60
- if (is_resource($this->stream)) {
61
- fclose($this->stream);
62
- }
63
- }
64
-
65
- /**
66
- * Set the minimum logging level.
67
- *
68
- * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
69
- *
70
- * @param int $level The minimum logging level which will be written
71
- */
72
- public function setLevel($level)
73
- {
74
- if (!array_key_exists($level, self::$levels)) {
75
- throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
76
- }
77
-
78
- $this->level = $level;
79
- }
80
-
81
- /**
82
- * Get the current minimum logging level.
83
- *
84
- * @return int
85
- */
86
- public function getLevel()
87
- {
88
- return $this->level;
89
- }
90
-
91
- /**
92
- * Logs with an arbitrary level.
93
- *
94
- * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
95
- *
96
- * @param mixed $level
97
- * @param string $message
98
- * @param array $context
99
- */
100
- public function log($level, $message, array $context = array())
101
- {
102
- if (!array_key_exists($level, self::$levels)) {
103
- throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
104
- }
105
-
106
- if (self::$levels[$level] >= self::$levels[$this->level]) {
107
- $this->writeLog($level, $message, $context);
108
- }
109
- }
110
-
111
- /**
112
- * Write a record to the log.
113
- *
114
- * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present.
115
- * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened.
116
- *
117
- * @param int $level The logging level
118
- * @param string $message The log message
119
- * @param array $context The log context
120
- */
121
- protected function writeLog($level, $message, array $context = array())
122
- {
123
- if (!is_resource($this->stream)) {
124
- if (!isset($this->url)) {
125
- throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
126
- }
127
-
128
- $this->stream = fopen($this->url, 'a');
129
- if (!is_resource($this->stream)) {
130
- // @codeCoverageIgnoreStart
131
- throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url));
132
- // @codeCoverageIgnoreEnd
133
- }
134
- }
135
-
136
- fwrite($this->stream, self::formatLine($level, $message, $context));
137
- }
138
-
139
- /**
140
- * Gets the name of the logging level.
141
- *
142
- * @throws InvalidArgumentException if the logging level is unknown.
143
- *
144
- * @param int $level
145
- *
146
- * @return string
147
- */
148
- protected static function getLevelName($level)
149
- {
150
- return strtoupper($level);
151
- }
152
-
153
- /**
154
- * Format a log line for output.
155
- *
156
- * @param int $level The logging level
157
- * @param string $message The log message
158
- * @param array $context The log context
159
- *
160
- * @return string
161
- */
162
- protected static function formatLine($level, $message, array $context = array())
163
- {
164
- return sprintf(
165
- "%s: %s\n",
166
- self::getLevelName($level),
167
- self::interpolateMessage($message, $context)
168
- );
169
- }
170
-
171
- /**
172
- * Interpolate context values into the message placeholders.
173
- *
174
- * @param string $message
175
- * @param array $context
176
- *
177
- * @return string
178
- */
179
- protected static function interpolateMessage($message, array $context = array())
180
- {
181
- if (strpos($message, '{') === false) {
182
- return $message;
183
- }
184
-
185
- // build a replacement array with braces around the context keys
186
- $replace = array();
187
- foreach ($context as $key => $val) {
188
- $replace['{' . $key . '}'] = $val;
189
- }
190
-
191
- // interpolate replacement values into the the message and return
192
- return strtr($message, $replace);
193
- }
194
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * A Mustache Stream Logger.
14
+ *
15
+ * The Stream Logger wraps a file resource instance (such as a stream) or a
16
+ * stream URL. All log messages over the threshold level will be appended to
17
+ * this stream.
18
+ *
19
+ * Hint: Try `php://stderr` for your stream URL.
20
+ */
21
+ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
22
+ {
23
+ protected static $levels = array(
24
+ self::DEBUG => 100,
25
+ self::INFO => 200,
26
+ self::NOTICE => 250,
27
+ self::WARNING => 300,
28
+ self::ERROR => 400,
29
+ self::CRITICAL => 500,
30
+ self::ALERT => 550,
31
+ self::EMERGENCY => 600,
32
+ );
33
+
34
+ protected $level;
35
+ protected $stream = null;
36
+ protected $url = null;
37
+
38
+ /**
39
+ * @throws InvalidArgumentException if the logging level is unknown.
40
+ *
41
+ * @param resource|string $stream Resource instance or URL
42
+ * @param int $level The minimum logging level at which this handler will be triggered
43
+ */
44
+ public function __construct($stream, $level = Mustache_Logger::ERROR)
45
+ {
46
+ $this->setLevel($level);
47
+
48
+ if (is_resource($stream)) {
49
+ $this->stream = $stream;
50
+ } else {
51
+ $this->url = $stream;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Close stream resources.
57
+ */
58
+ public function __destruct()
59
+ {
60
+ if (is_resource($this->stream)) {
61
+ fclose($this->stream);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Set the minimum logging level.
67
+ *
68
+ * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
69
+ *
70
+ * @param int $level The minimum logging level which will be written
71
+ */
72
+ public function setLevel($level)
73
+ {
74
+ if (!array_key_exists($level, self::$levels)) {
75
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
76
+ }
77
+
78
+ $this->level = $level;
79
+ }
80
+
81
+ /**
82
+ * Get the current minimum logging level.
83
+ *
84
+ * @return int
85
+ */
86
+ public function getLevel()
87
+ {
88
+ return $this->level;
89
+ }
90
+
91
+ /**
92
+ * Logs with an arbitrary level.
93
+ *
94
+ * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
95
+ *
96
+ * @param mixed $level
97
+ * @param string $message
98
+ * @param array $context
99
+ */
100
+ public function log($level, $message, array $context = array())
101
+ {
102
+ if (!array_key_exists($level, self::$levels)) {
103
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
104
+ }
105
+
106
+ if (self::$levels[$level] >= self::$levels[$this->level]) {
107
+ $this->writeLog($level, $message, $context);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Write a record to the log.
113
+ *
114
+ * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present.
115
+ * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened.
116
+ *
117
+ * @param int $level The logging level
118
+ * @param string $message The log message
119
+ * @param array $context The log context
120
+ */
121
+ protected function writeLog($level, $message, array $context = array())
122
+ {
123
+ if (!is_resource($this->stream)) {
124
+ if (!isset($this->url)) {
125
+ throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
126
+ }
127
+
128
+ $this->stream = fopen($this->url, 'a');
129
+ if (!is_resource($this->stream)) {
130
+ // @codeCoverageIgnoreStart
131
+ throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url));
132
+ // @codeCoverageIgnoreEnd
133
+ }
134
+ }
135
+
136
+ fwrite($this->stream, self::formatLine($level, $message, $context));
137
+ }
138
+
139
+ /**
140
+ * Gets the name of the logging level.
141
+ *
142
+ * @throws InvalidArgumentException if the logging level is unknown.
143
+ *
144
+ * @param int $level
145
+ *
146
+ * @return string
147
+ */
148
+ protected static function getLevelName($level)
149
+ {
150
+ return strtoupper($level);
151
+ }
152
+
153
+ /**
154
+ * Format a log line for output.
155
+ *
156
+ * @param int $level The logging level
157
+ * @param string $message The log message
158
+ * @param array $context The log context
159
+ *
160
+ * @return string
161
+ */
162
+ protected static function formatLine($level, $message, array $context = array())
163
+ {
164
+ return sprintf(
165
+ "%s: %s\n",
166
+ self::getLevelName($level),
167
+ self::interpolateMessage($message, $context)
168
+ );
169
+ }
170
+
171
+ /**
172
+ * Interpolate context values into the message placeholders.
173
+ *
174
+ * @param string $message
175
+ * @param array $context
176
+ *
177
+ * @return string
178
+ */
179
+ protected static function interpolateMessage($message, array $context = array())
180
+ {
181
+ if (strpos($message, '{') === false) {
182
+ return $message;
183
+ }
184
+
185
+ // build a replacement array with braces around the context keys
186
+ $replace = array();
187
+ foreach ($context as $key => $val) {
188
+ $replace['{' . $key . '}'] = $val;
189
+ }
190
+
191
+ // interpolate replacement values into the the message and return
192
+ return strtr($message, $replace);
193
+ }
194
+ }
lib/php/Mustache/Parser.php CHANGED
@@ -1,317 +1,317 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Parser class.
14
- *
15
- * This class is responsible for turning a set of Mustache tokens into a parse tree.
16
- */
17
- class Mustache_Parser
18
- {
19
- private $lineNum;
20
- private $lineTokens;
21
- private $pragmas;
22
- private $defaultPragmas = array();
23
-
24
- private $pragmaFilters;
25
- private $pragmaBlocks;
26
-
27
- /**
28
- * Process an array of Mustache tokens and convert them into a parse tree.
29
- *
30
- * @param array $tokens Set of Mustache tokens
31
- *
32
- * @return array Mustache token parse tree
33
- */
34
- public function parse(array $tokens = array())
35
- {
36
- $this->lineNum = -1;
37
- $this->lineTokens = 0;
38
- $this->pragmas = $this->defaultPragmas;
39
-
40
- $this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
41
- $this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
42
-
43
- return $this->buildTree($tokens);
44
- }
45
-
46
- /**
47
- * Enable pragmas across all templates, regardless of the presence of pragma
48
- * tags in the individual templates.
49
- *
50
- * @internal Users should set global pragmas in Mustache_Engine, not here :)
51
- *
52
- * @param string[] $pragmas
53
- */
54
- public function setPragmas(array $pragmas)
55
- {
56
- $this->pragmas = array();
57
- foreach ($pragmas as $pragma) {
58
- $this->enablePragma($pragma);
59
- }
60
- $this->defaultPragmas = $this->pragmas;
61
- }
62
-
63
- /**
64
- * Helper method for recursively building a parse tree.
65
- *
66
- * @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered.
67
- *
68
- * @param array &$tokens Set of Mustache tokens
69
- * @param array $parent Parent token (default: null)
70
- *
71
- * @return array Mustache Token parse tree
72
- */
73
- private function buildTree(array &$tokens, array $parent = null)
74
- {
75
- $nodes = array();
76
-
77
- while (!empty($tokens)) {
78
- $token = array_shift($tokens);
79
-
80
- if ($token[Mustache_Tokenizer::LINE] === $this->lineNum) {
81
- $this->lineTokens++;
82
- } else {
83
- $this->lineNum = $token[Mustache_Tokenizer::LINE];
84
- $this->lineTokens = 0;
85
- }
86
-
87
- if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
88
- list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
89
- if (!empty($filters)) {
90
- $token[Mustache_Tokenizer::NAME] = $name;
91
- $token[Mustache_Tokenizer::FILTERS] = $filters;
92
- }
93
- }
94
-
95
- switch ($token[Mustache_Tokenizer::TYPE]) {
96
- case Mustache_Tokenizer::T_DELIM_CHANGE:
97
- $this->checkIfTokenIsAllowedInParent($parent, $token);
98
- $this->clearStandaloneLines($nodes, $tokens);
99
- break;
100
-
101
- case Mustache_Tokenizer::T_SECTION:
102
- case Mustache_Tokenizer::T_INVERTED:
103
- $this->checkIfTokenIsAllowedInParent($parent, $token);
104
- $this->clearStandaloneLines($nodes, $tokens);
105
- $nodes[] = $this->buildTree($tokens, $token);
106
- break;
107
-
108
- case Mustache_Tokenizer::T_END_SECTION:
109
- if (!isset($parent)) {
110
- $msg = sprintf(
111
- 'Unexpected closing tag: /%s on line %d',
112
- $token[Mustache_Tokenizer::NAME],
113
- $token[Mustache_Tokenizer::LINE]
114
- );
115
- throw new Mustache_Exception_SyntaxException($msg, $token);
116
- }
117
-
118
- if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
119
- $msg = sprintf(
120
- 'Nesting error: %s (on line %d) vs. %s (on line %d)',
121
- $parent[Mustache_Tokenizer::NAME],
122
- $parent[Mustache_Tokenizer::LINE],
123
- $token[Mustache_Tokenizer::NAME],
124
- $token[Mustache_Tokenizer::LINE]
125
- );
126
- throw new Mustache_Exception_SyntaxException($msg, $token);
127
- }
128
-
129
- $this->clearStandaloneLines($nodes, $tokens);
130
- $parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX];
131
- $parent[Mustache_Tokenizer::NODES] = $nodes;
132
-
133
- return $parent;
134
-
135
- case Mustache_Tokenizer::T_PARTIAL:
136
- $this->checkIfTokenIsAllowedInParent($parent, $token);
137
- //store the whitespace prefix for laters!
138
- if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
139
- $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
140
- }
141
- $nodes[] = $token;
142
- break;
143
-
144
- case Mustache_Tokenizer::T_PARENT:
145
- $this->checkIfTokenIsAllowedInParent($parent, $token);
146
- $nodes[] = $this->buildTree($tokens, $token);
147
- break;
148
-
149
- case Mustache_Tokenizer::T_BLOCK_VAR:
150
- if ($this->pragmaBlocks) {
151
- // BLOCKS pragma is enabled, let's do this!
152
- if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
153
- $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG;
154
- }
155
- $this->clearStandaloneLines($nodes, $tokens);
156
- $nodes[] = $this->buildTree($tokens, $token);
157
- } else {
158
- // pretend this was just a normal "escaped" token...
159
- $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_ESCAPED;
160
- // TODO: figure out how to figure out if there was a space after this dollar:
161
- $token[Mustache_Tokenizer::NAME] = '$' . $token[Mustache_Tokenizer::NAME];
162
- $nodes[] = $token;
163
- }
164
- break;
165
-
166
- case Mustache_Tokenizer::T_PRAGMA:
167
- $this->enablePragma($token[Mustache_Tokenizer::NAME]);
168
- // no break
169
-
170
- case Mustache_Tokenizer::T_COMMENT:
171
- $this->clearStandaloneLines($nodes, $tokens);
172
- $nodes[] = $token;
173
- break;
174
-
175
- default:
176
- $nodes[] = $token;
177
- break;
178
- }
179
- }
180
-
181
- if (isset($parent)) {
182
- $msg = sprintf(
183
- 'Missing closing tag: %s opened on line %d',
184
- $parent[Mustache_Tokenizer::NAME],
185
- $parent[Mustache_Tokenizer::LINE]
186
- );
187
- throw new Mustache_Exception_SyntaxException($msg, $parent);
188
- }
189
-
190
- return $nodes;
191
- }
192
-
193
- /**
194
- * Clear standalone line tokens.
195
- *
196
- * Returns a whitespace token for indenting partials, if applicable.
197
- *
198
- * @param array $nodes Parsed nodes.
199
- * @param array $tokens Tokens to be parsed.
200
- *
201
- * @return array|null Resulting indent token, if any.
202
- */
203
- private function clearStandaloneLines(array &$nodes, array &$tokens)
204
- {
205
- if ($this->lineTokens > 1) {
206
- // this is the third or later node on this line, so it can't be standalone
207
- return;
208
- }
209
-
210
- $prev = null;
211
- if ($this->lineTokens === 1) {
212
- // this is the second node on this line, so it can't be standalone
213
- // unless the previous node is whitespace.
214
- if ($prev = end($nodes)) {
215
- if (!$this->tokenIsWhitespace($prev)) {
216
- return;
217
- }
218
- }
219
- }
220
-
221
- if ($next = reset($tokens)) {
222
- // If we're on a new line, bail.
223
- if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) {
224
- return;
225
- }
226
-
227
- // If the next token isn't whitespace, bail.
228
- if (!$this->tokenIsWhitespace($next)) {
229
- return;
230
- }
231
-
232
- if (count($tokens) !== 1) {
233
- // Unless it's the last token in the template, the next token
234
- // must end in newline for this to be standalone.
235
- if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") {
236
- return;
237
- }
238
- }
239
-
240
- // Discard the whitespace suffix
241
- array_shift($tokens);
242
- }
243
-
244
- if ($prev) {
245
- // Return the whitespace prefix, if any
246
- return array_pop($nodes);
247
- }
248
- }
249
-
250
- /**
251
- * Check whether token is a whitespace token.
252
- *
253
- * True if token type is T_TEXT and value is all whitespace characters.
254
- *
255
- * @param array $token
256
- *
257
- * @return bool True if token is a whitespace token
258
- */
259
- private function tokenIsWhitespace(array $token)
260
- {
261
- if ($token[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_TEXT) {
262
- return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
263
- }
264
-
265
- return false;
266
- }
267
-
268
- /**
269
- * Check whether a token is allowed inside a parent tag.
270
- *
271
- * @throws Mustache_Exception_SyntaxException if an invalid token is found inside a parent tag.
272
- *
273
- * @param array|null $parent
274
- * @param array $token
275
- */
276
- private function checkIfTokenIsAllowedInParent($parent, array $token)
277
- {
278
- if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
279
- throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token);
280
- }
281
- }
282
-
283
- /**
284
- * Split a tag name into name and filters.
285
- *
286
- * @param string $name
287
- *
288
- * @return array [Tag name, Array of filters]
289
- */
290
- private function getNameAndFilters($name)
291
- {
292
- $filters = array_map('trim', explode('|', $name));
293
- $name = array_shift($filters);
294
-
295
- return array($name, $filters);
296
- }
297
-
298
- /**
299
- * Enable a pragma.
300
- *
301
- * @param string $name
302
- */
303
- private function enablePragma($name)
304
- {
305
- $this->pragmas[$name] = true;
306
-
307
- switch ($name) {
308
- case Mustache_Engine::PRAGMA_BLOCKS:
309
- $this->pragmaBlocks = true;
310
- break;
311
-
312
- case Mustache_Engine::PRAGMA_FILTERS:
313
- $this->pragmaFilters = true;
314
- break;
315
- }
316
- }
317
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Parser class.
14
+ *
15
+ * This class is responsible for turning a set of Mustache tokens into a parse tree.
16
+ */
17
+ class Mustache_Parser
18
+ {
19
+ private $lineNum;
20
+ private $lineTokens;
21
+ private $pragmas;
22
+ private $defaultPragmas = array();
23
+
24
+ private $pragmaFilters;
25
+ private $pragmaBlocks;
26
+
27
+ /**
28
+ * Process an array of Mustache tokens and convert them into a parse tree.
29
+ *
30
+ * @param array $tokens Set of Mustache tokens
31
+ *
32
+ * @return array Mustache token parse tree
33
+ */
34
+ public function parse(array $tokens = array())
35
+ {
36
+ $this->lineNum = -1;
37
+ $this->lineTokens = 0;
38
+ $this->pragmas = $this->defaultPragmas;
39
+
40
+ $this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
41
+ $this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
42
+
43
+ return $this->buildTree($tokens);
44
+ }
45
+
46
+ /**
47
+ * Enable pragmas across all templates, regardless of the presence of pragma
48
+ * tags in the individual templates.
49
+ *
50
+ * @internal Users should set global pragmas in Mustache_Engine, not here :)
51
+ *
52
+ * @param string[] $pragmas
53
+ */
54
+ public function setPragmas(array $pragmas)
55
+ {
56
+ $this->pragmas = array();
57
+ foreach ($pragmas as $pragma) {
58
+ $this->enablePragma($pragma);
59
+ }
60
+ $this->defaultPragmas = $this->pragmas;
61
+ }
62
+
63
+ /**
64
+ * Helper method for recursively building a parse tree.
65
+ *
66
+ * @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered.
67
+ *
68
+ * @param array &$tokens Set of Mustache tokens
69
+ * @param array $parent Parent token (default: null)
70
+ *
71
+ * @return array Mustache Token parse tree
72
+ */
73
+ private function buildTree(array &$tokens, array $parent = null)
74
+ {
75
+ $nodes = array();
76
+
77
+ while (!empty($tokens)) {
78
+ $token = array_shift($tokens);
79
+
80
+ if ($token[Mustache_Tokenizer::LINE] === $this->lineNum) {
81
+ $this->lineTokens++;
82
+ } else {
83
+ $this->lineNum = $token[Mustache_Tokenizer::LINE];
84
+ $this->lineTokens = 0;
85
+ }
86
+
87
+ if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
88
+ list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
89
+ if (!empty($filters)) {
90
+ $token[Mustache_Tokenizer::NAME] = $name;
91
+ $token[Mustache_Tokenizer::FILTERS] = $filters;
92
+ }
93
+ }
94
+
95
+ switch ($token[Mustache_Tokenizer::TYPE]) {
96
+ case Mustache_Tokenizer::T_DELIM_CHANGE:
97
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
98
+ $this->clearStandaloneLines($nodes, $tokens);
99
+ break;
100
+
101
+ case Mustache_Tokenizer::T_SECTION:
102
+ case Mustache_Tokenizer::T_INVERTED:
103
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
104
+ $this->clearStandaloneLines($nodes, $tokens);
105
+ $nodes[] = $this->buildTree($tokens, $token);
106
+ break;
107
+
108
+ case Mustache_Tokenizer::T_END_SECTION:
109
+ if (!isset($parent)) {
110
+ $msg = sprintf(
111
+ 'Unexpected closing tag: /%s on line %d',
112
+ $token[Mustache_Tokenizer::NAME],
113
+ $token[Mustache_Tokenizer::LINE]
114
+ );
115
+ throw new Mustache_Exception_SyntaxException($msg, $token);
116
+ }
117
+
118
+ if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
119
+ $msg = sprintf(
120
+ 'Nesting error: %s (on line %d) vs. %s (on line %d)',
121
+ $parent[Mustache_Tokenizer::NAME],
122
+ $parent[Mustache_Tokenizer::LINE],
123
+ $token[Mustache_Tokenizer::NAME],
124
+ $token[Mustache_Tokenizer::LINE]
125
+ );
126
+ throw new Mustache_Exception_SyntaxException($msg, $token);
127
+ }
128
+
129
+ $this->clearStandaloneLines($nodes, $tokens);
130
+ $parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX];
131
+ $parent[Mustache_Tokenizer::NODES] = $nodes;
132
+
133
+ return $parent;
134
+
135
+ case Mustache_Tokenizer::T_PARTIAL:
136
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
137
+ //store the whitespace prefix for laters!
138
+ if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
139
+ $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
140
+ }
141
+ $nodes[] = $token;
142
+ break;
143
+
144
+ case Mustache_Tokenizer::T_PARENT:
145
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
146
+ $nodes[] = $this->buildTree($tokens, $token);
147
+ break;
148
+
149
+ case Mustache_Tokenizer::T_BLOCK_VAR:
150
+ if ($this->pragmaBlocks) {
151
+ // BLOCKS pragma is enabled, let's do this!
152
+ if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
153
+ $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG;
154
+ }
155
+ $this->clearStandaloneLines($nodes, $tokens);
156
+ $nodes[] = $this->buildTree($tokens, $token);
157
+ } else {
158
+ // pretend this was just a normal "escaped" token...
159
+ $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_ESCAPED;
160
+ // TODO: figure out how to figure out if there was a space after this dollar:
161
+ $token[Mustache_Tokenizer::NAME] = '$' . $token[Mustache_Tokenizer::NAME];
162
+ $nodes[] = $token;
163
+ }
164
+ break;
165
+
166
+ case Mustache_Tokenizer::T_PRAGMA:
167
+ $this->enablePragma($token[Mustache_Tokenizer::NAME]);
168
+ // no break
169
+
170
+ case Mustache_Tokenizer::T_COMMENT:
171
+ $this->clearStandaloneLines($nodes, $tokens);
172
+ $nodes[] = $token;
173
+ break;
174
+
175
+ default:
176
+ $nodes[] = $token;
177
+ break;
178
+ }
179
+ }
180
+
181
+ if (isset($parent)) {
182
+ $msg = sprintf(
183
+ 'Missing closing tag: %s opened on line %d',
184
+ $parent[Mustache_Tokenizer::NAME],
185
+ $parent[Mustache_Tokenizer::LINE]
186
+ );
187
+ throw new Mustache_Exception_SyntaxException($msg, $parent);
188
+ }
189
+
190
+ return $nodes;
191
+ }
192
+
193
+ /**
194
+ * Clear standalone line tokens.
195
+ *
196
+ * Returns a whitespace token for indenting partials, if applicable.
197
+ *
198
+ * @param array $nodes Parsed nodes.
199
+ * @param array $tokens Tokens to be parsed.
200
+ *
201
+ * @return array|null Resulting indent token, if any.
202
+ */
203
+ private function clearStandaloneLines(array &$nodes, array &$tokens)
204
+ {
205
+ if ($this->lineTokens > 1) {
206
+ // this is the third or later node on this line, so it can't be standalone
207
+ return;
208
+ }
209
+
210
+ $prev = null;
211
+ if ($this->lineTokens === 1) {
212
+ // this is the second node on this line, so it can't be standalone
213
+ // unless the previous node is whitespace.
214
+ if ($prev = end($nodes)) {
215
+ if (!$this->tokenIsWhitespace($prev)) {
216
+ return;
217
+ }
218
+ }
219
+ }
220
+
221
+ if ($next = reset($tokens)) {
222
+ // If we're on a new line, bail.
223
+ if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) {
224
+ return;
225
+ }
226
+
227
+ // If the next token isn't whitespace, bail.
228
+ if (!$this->tokenIsWhitespace($next)) {
229
+ return;
230
+ }
231
+
232
+ if (count($tokens) !== 1) {
233
+ // Unless it's the last token in the template, the next token
234
+ // must end in newline for this to be standalone.
235
+ if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") {
236
+ return;
237
+ }
238
+ }
239
+
240
+ // Discard the whitespace suffix
241
+ array_shift($tokens);
242
+ }
243
+
244
+ if ($prev) {
245
+ // Return the whitespace prefix, if any
246
+ return array_pop($nodes);
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Check whether token is a whitespace token.
252
+ *
253
+ * True if token type is T_TEXT and value is all whitespace characters.
254
+ *
255
+ * @param array $token
256
+ *
257
+ * @return bool True if token is a whitespace token
258
+ */
259
+ private function tokenIsWhitespace(array $token)
260
+ {
261
+ if ($token[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_TEXT) {
262
+ return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
263
+ }
264
+
265
+ return false;
266
+ }
267
+
268
+ /**
269
+ * Check whether a token is allowed inside a parent tag.
270
+ *
271
+ * @throws Mustache_Exception_SyntaxException if an invalid token is found inside a parent tag.
272
+ *
273
+ * @param array|null $parent
274
+ * @param array $token
275
+ */
276
+ private function checkIfTokenIsAllowedInParent($parent, array $token)
277
+ {
278
+ if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
279
+ throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token);
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Split a tag name into name and filters.
285
+ *
286
+ * @param string $name
287
+ *
288
+ * @return array [Tag name, Array of filters]
289
+ */
290
+ private function getNameAndFilters($name)
291
+ {
292
+ $filters = array_map('trim', explode('|', $name));
293
+ $name = array_shift($filters);
294
+
295
+ return array($name, $filters);
296
+ }
297
+
298
+ /**
299
+ * Enable a pragma.
300
+ *
301
+ * @param string $name
302
+ */
303
+ private function enablePragma($name)
304
+ {
305
+ $this->pragmas[$name] = true;
306
+
307
+ switch ($name) {
308
+ case Mustache_Engine::PRAGMA_BLOCKS:
309
+ $this->pragmaBlocks = true;
310
+ break;
311
+
312
+ case Mustache_Engine::PRAGMA_FILTERS:
313
+ $this->pragmaFilters = true;
314
+ break;
315
+ }
316
+ }
317
+ }
lib/php/Mustache/Template.php CHANGED
@@ -1,180 +1,180 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Abstract Mustache Template class.
14
- *
15
- * @abstract
16
- */
17
- abstract class Mustache_Template
18
- {
19
- /**
20
- * @var Mustache_Engine
21
- */
22
- protected $mustache;
23
-
24
- /**
25
- * @var bool
26
- */
27
- protected $strictCallables = false;
28
-
29
- /**
30
- * Mustache Template constructor.
31
- *
32
- * @param Mustache_Engine $mustache
33
- */
34
- public function __construct(Mustache_Engine $mustache)
35
- {
36
- $this->mustache = $mustache;
37
- }
38
-
39
- /**
40
- * Mustache Template instances can be treated as a function and rendered by simply calling them.
41
- *
42
- * $m = new Mustache_Engine;
43
- * $tpl = $m->loadTemplate('Hello, {{ name }}!');
44
- * echo $tpl(array('name' => 'World')); // "Hello, World!"
45
- *
46
- * @see Mustache_Template::render
47
- *
48
- * @param mixed $context Array or object rendering context (default: array())
49
- *
50
- * @return string Rendered template
51
- */
52
- public function __invoke($context = array())
53
- {
54
- return $this->render($context);
55
- }
56
-
57
- /**
58
- * Render this template given the rendering context.
59
- *
60
- * @param mixed $context Array or object rendering context (default: array())
61
- *
62
- * @return string Rendered template
63
- */
64
- public function render($context = array())
65
- {
66
- return $this->renderInternal(
67
- $this->prepareContextStack($context)
68
- );
69
- }
70
-
71
- /**
72
- * Internal rendering method implemented by Mustache Template concrete subclasses.
73
- *
74
- * This is where the magic happens :)
75
- *
76
- * NOTE: This method is not part of the Mustache.php public API.
77
- *
78
- * @param Mustache_Context $context
79
- * @param string $indent (default: '')
80
- *
81
- * @return string Rendered template
82
- */
83
- abstract public function renderInternal(Mustache_Context $context, $indent = '');
84
-
85
- /**
86
- * Tests whether a value should be iterated over (e.g. in a section context).
87
- *
88
- * In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
89
- * should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
90
- * Java, Python, etc.
91
- *
92
- * PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
93
- * between between a list of things (numeric, normalized array) and a set of variables to be used as section context
94
- * (associative array). In other words, this will be iterated over:
95
- *
96
- * $items = array(
97
- * array('name' => 'foo'),
98
- * array('name' => 'bar'),
99
- * array('name' => 'baz'),
100
- * );
101
- *
102
- * ... but this will be used as a section context block:
103
- *
104
- * $items = array(
105
- * 1 => array('name' => 'foo'),
106
- * 'banana' => array('name' => 'bar'),
107
- * 42 => array('name' => 'baz'),
108
- * );
109
- *
110
- * @param mixed $value
111
- *
112
- * @return bool True if the value is 'iterable'
113
- */
114
- protected function isIterable($value)
115
- {
116
- switch (gettype($value)) {
117
- case 'object':
118
- return $value instanceof Traversable;
119
-
120
- case 'array':
121
- $i = 0;
122
- foreach ($value as $k => $v) {
123
- if ($k !== $i++) {
124
- return false;
125
- }
126
- }
127
-
128
- return true;
129
-
130
- default:
131
- return false;
132
- }
133
- }
134
-
135
- /**
136
- * Helper method to prepare the Context stack.
137
- *
138
- * Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
139
- *
140
- * @param mixed $context Optional first context frame (default: null)
141
- *
142
- * @return Mustache_Context
143
- */
144
- protected function prepareContextStack($context = null)
145
- {
146
- $stack = new Mustache_Context();
147
-
148
- $helpers = $this->mustache->getHelpers();
149
- if (!$helpers->isEmpty()) {
150
- $stack->push($helpers);
151
- }
152
-
153
- if (!empty($context)) {
154
- $stack->push($context);
155
- }
156
-
157
- return $stack;
158
- }
159
-
160
- /**
161
- * Resolve a context value.
162
- *
163
- * Invoke the value if it is callable, otherwise return the value.
164
- *
165
- * @param mixed $value
166
- * @param Mustache_Context $context
167
- *
168
- * @return string
169
- */
170
- protected function resolveValue($value, Mustache_Context $context)
171
- {
172
- if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) {
173
- return $this->mustache
174
- ->loadLambda((string) call_user_func($value))
175
- ->renderInternal($context);
176
- }
177
-
178
- return $value;
179
- }
180
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Abstract Mustache Template class.
14
+ *
15
+ * @abstract
16
+ */
17
+ abstract class Mustache_Template
18
+ {
19
+ /**
20
+ * @var Mustache_Engine
21
+ */
22
+ protected $mustache;
23
+
24
+ /**
25
+ * @var bool
26
+ */
27
+ protected $strictCallables = false;
28
+
29
+ /**
30
+ * Mustache Template constructor.
31
+ *
32
+ * @param Mustache_Engine $mustache
33
+ */
34
+ public function __construct(Mustache_Engine $mustache)
35
+ {
36
+ $this->mustache = $mustache;
37
+ }
38
+
39
+ /**
40
+ * Mustache Template instances can be treated as a function and rendered by simply calling them.
41
+ *
42
+ * $m = new Mustache_Engine;
43
+ * $tpl = $m->loadTemplate('Hello, {{ name }}!');
44
+ * echo $tpl(array('name' => 'World')); // "Hello, World!"
45
+ *
46
+ * @see Mustache_Template::render
47
+ *
48
+ * @param mixed $context Array or object rendering context (default: array())
49
+ *
50
+ * @return string Rendered template
51
+ */
52
+ public function __invoke($context = array())
53
+ {
54
+ return $this->render($context);
55
+ }
56
+
57
+ /**
58
+ * Render this template given the rendering context.
59
+ *
60
+ * @param mixed $context Array or object rendering context (default: array())
61
+ *
62
+ * @return string Rendered template
63
+ */
64
+ public function render($context = array())
65
+ {
66
+ return $this->renderInternal(
67
+ $this->prepareContextStack($context)
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Internal rendering method implemented by Mustache Template concrete subclasses.
73
+ *
74
+ * This is where the magic happens :)
75
+ *
76
+ * NOTE: This method is not part of the Mustache.php public API.
77
+ *
78
+ * @param Mustache_Context $context
79
+ * @param string $indent (default: '')
80
+ *
81
+ * @return string Rendered template
82
+ */
83
+ abstract public function renderInternal(Mustache_Context $context, $indent = '');
84
+
85
+ /**
86
+ * Tests whether a value should be iterated over (e.g. in a section context).
87
+ *
88
+ * In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
89
+ * should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
90
+ * Java, Python, etc.
91
+ *
92
+ * PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
93
+ * between between a list of things (numeric, normalized array) and a set of variables to be used as section context
94
+ * (associative array). In other words, this will be iterated over:
95
+ *
96
+ * $items = array(
97
+ * array('name' => 'foo'),
98
+ * array('name' => 'bar'),
99
+ * array('name' => 'baz'),
100
+ * );
101
+ *
102
+ * ... but this will be used as a section context block:
103
+ *
104
+ * $items = array(
105
+ * 1 => array('name' => 'foo'),
106
+ * 'banana' => array('name' => 'bar'),
107
+ * 42 => array('name' => 'baz'),
108
+ * );
109
+ *
110
+ * @param mixed $value
111
+ *
112
+ * @return bool True if the value is 'iterable'
113
+ */
114
+ protected function isIterable($value)
115
+ {
116
+ switch (gettype($value)) {
117
+ case 'object':
118
+ return $value instanceof Traversable;
119
+
120
+ case 'array':
121
+ $i = 0;
122
+ foreach ($value as $k => $v) {
123
+ if ($k !== $i++) {
124
+ return false;
125
+ }
126
+ }
127
+
128
+ return true;
129
+
130
+ default:
131
+ return false;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Helper method to prepare the Context stack.
137
+ *
138
+ * Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
139
+ *
140
+ * @param mixed $context Optional first context frame (default: null)
141
+ *
142
+ * @return Mustache_Context
143
+ */
144
+ protected function prepareContextStack($context = null)
145
+ {
146
+ $stack = new Mustache_Context();
147
+
148
+ $helpers = $this->mustache->getHelpers();
149
+ if (!$helpers->isEmpty()) {
150
+ $stack->push($helpers);
151
+ }
152
+
153
+ if (!empty($context)) {
154
+ $stack->push($context);
155
+ }
156
+
157
+ return $stack;
158
+ }
159
+
160
+ /**
161
+ * Resolve a context value.
162
+ *
163
+ * Invoke the value if it is callable, otherwise return the value.
164
+ *
165
+ * @param mixed $value
166
+ * @param Mustache_Context $context
167
+ *
168
+ * @return string
169
+ */
170
+ protected function resolveValue($value, Mustache_Context $context)
171
+ {
172
+ if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) {
173
+ return $this->mustache
174
+ ->loadLambda((string) call_user_func($value))
175
+ ->renderInternal($context);
176
+ }
177
+
178
+ return $value;
179
+ }
180
+ }
lib/php/Mustache/Tokenizer.php CHANGED
@@ -1,322 +1,322 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Mustache.php.
5
- *
6
- * (c) 2010-2015 Justin Hileman
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
- /**
13
- * Mustache Tokenizer class.
14
- *
15
- * This class is responsible for turning raw template source into a set of Mustache tokens.
16
- */
17
- class Mustache_Tokenizer
18
- {
19
- // Finite state machine states
20
- const IN_TEXT = 0;
21
- const IN_TAG_TYPE = 1;
22
- const IN_TAG = 2;
23
-
24
- // Token types
25
- const T_SECTION = '#';
26
- const T_INVERTED = '^';
27
- const T_END_SECTION = '/';
28
- const T_COMMENT = '!';
29
- const T_PARTIAL = '>';
30
- const T_PARENT = '<';
31
- const T_DELIM_CHANGE = '=';
32
- const T_ESCAPED = '_v';
33
- const T_UNESCAPED = '{';
34
- const T_UNESCAPED_2 = '&';
35
- const T_TEXT = '_t';
36
- const T_PRAGMA = '%';
37
- const T_BLOCK_VAR = '$';
38
- const T_BLOCK_ARG = '$arg';
39
-
40
- // Valid token types
41
- private static $tagTypes = array(
42
- self::T_SECTION => true,
43
- self::T_INVERTED => true,
44
- self::T_END_SECTION => true,
45
- self::T_COMMENT => true,
46
- self::T_PARTIAL => true,
47
- self::T_PARENT => true,
48
- self::T_DELIM_CHANGE => true,
49
- self::T_ESCAPED => true,
50
- self::T_UNESCAPED => true,
51
- self::T_UNESCAPED_2 => true,
52
- self::T_PRAGMA => true,
53
- self::T_BLOCK_VAR => true,
54
- );
55
-
56
- // Token properties
57
- const TYPE = 'type';
58
- const NAME = 'name';
59
- const OTAG = 'otag';
60
- const CTAG = 'ctag';
61
- const LINE = 'line';
62
- const INDEX = 'index';
63
- const END = 'end';
64
- const INDENT = 'indent';
65
- const NODES = 'nodes';
66
- const VALUE = 'value';
67
- const FILTERS = 'filters';
68
-
69
- private $state;
70
- private $tagType;
71
- private $buffer;
72
- private $tokens;
73
- private $seenTag;
74
- private $line;
75
- private $otag;
76
- private $ctag;
77
- private $otagLen;
78
- private $ctagLen;
79
-
80
- /**
81
- * Scan and tokenize template source.
82
- *
83
- * @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered.
84
- *
85
- * @param string $text Mustache template source to tokenize
86
- * @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
87
- *
88
- * @return array Set of Mustache tokens
89
- */
90
- public function scan($text, $delimiters = null)
91
- {
92
- // Setting mbstring.func_overload makes things *really* slow.
93
- // Let's do everyone a favor and scan this string as ASCII instead.
94
- $encoding = null;
95
- if (function_exists('mb_internal_encoding') && ini_get('mbstring.func_overload') & 2) {
96
- $encoding = mb_internal_encoding();
97
- mb_internal_encoding('ASCII');
98
- }
99
-
100
- $this->reset();
101
-
102
- if ($delimiters = trim($delimiters)) {
103
- $this->setDelimiters($delimiters);
104
- }
105
-
106
- $len = strlen($text);
107
- for ($i = 0; $i < $len; $i++) {
108
- switch ($this->state) {
109
- case self::IN_TEXT:
110
- if ($this->tagChange($this->otag, $this->otagLen, $text, $i)) {
111
- $i--;
112
- $this->flushBuffer();
113
- $this->state = self::IN_TAG_TYPE;
114
- } else {
115
- $char = $text[$i];
116
- $this->buffer .= $char;
117
- if ($char === "\n") {
118
- $this->flushBuffer();
119
- $this->line++;
120
- }
121
- }
122
- break;
123
-
124
- case self::IN_TAG_TYPE:
125
- $i += $this->otagLen - 1;
126
- $char = $text[$i + 1];
127
- if (isset(self::$tagTypes[$char])) {
128
- $tag = $char;
129
- $this->tagType = $tag;
130
- } else {
131
- $tag = null;
132
- $this->tagType = self::T_ESCAPED;
133
- }
134
-
135
- if ($this->tagType === self::T_DELIM_CHANGE) {
136
- $i = $this->changeDelimiters($text, $i);
137
- $this->state = self::IN_TEXT;
138
- } elseif ($this->tagType === self::T_PRAGMA) {
139
- $i = $this->addPragma($text, $i);
140
- $this->state = self::IN_TEXT;
141
- } else {
142
- if ($tag !== null) {
143
- $i++;
144
- }
145
- $this->state = self::IN_TAG;
146
- }
147
- $this->seenTag = $i;
148
- break;
149
-
150
- default:
151
- if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
152
- $token = array(
153
- self::TYPE => $this->tagType,
154
- self::NAME => trim($this->buffer),
155
- self::OTAG => $this->otag,
156
- self::CTAG => $this->ctag,
157
- self::LINE => $this->line,
158
- self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen,
159
- );
160
-
161
- if ($this->tagType === self::T_UNESCAPED) {
162
- // Clean up `{{{ tripleStache }}}` style tokens.
163
- if ($this->ctag === '}}') {
164
- if (($i + 2 < $len) && $text[$i + 2] === '}') {
165
- $i++;
166
- } else {
167
- $msg = sprintf(
168
- 'Mismatched tag delimiters: %s on line %d',
169
- $token[self::NAME],
170
- $token[self::LINE]
171
- );
172
-
173
- throw new Mustache_Exception_SyntaxException($msg, $token);
174
- }
175
- } else {
176
- $lastName = $token[self::NAME];
177
- if (substr($lastName, -1) === '}') {
178
- $token[self::NAME] = trim(substr($lastName, 0, -1));
179
- } else {
180
- $msg = sprintf(
181
- 'Mismatched tag delimiters: %s on line %d',
182
- $token[self::NAME],
183
- $token[self::LINE]
184
- );
185
-
186
- throw new Mustache_Exception_SyntaxException($msg, $token);
187
- }
188
- }
189
- }
190
-
191
- $this->buffer = '';
192
- $i += $this->ctagLen - 1;
193
- $this->state = self::IN_TEXT;
194
- $this->tokens[] = $token;
195
- } else {
196
- $this->buffer .= $text[$i];
197
- }
198
- break;
199
- }
200
- }
201
-
202
- $this->flushBuffer();
203
-
204
- // Restore the user's encoding...
205
- if ($encoding) {
206
- mb_internal_encoding($encoding);
207
- }
208
-
209
- return $this->tokens;
210
- }
211
-
212
- /**
213
- * Helper function to reset tokenizer internal state.
214
- */
215
- private function reset()
216
- {
217
- $this->state = self::IN_TEXT;
218
- $this->tagType = null;
219
- $this->buffer = '';
220
- $this->tokens = array();
221
- $this->seenTag = false;
222
- $this->line = 0;
223
- $this->otag = '{{';
224
- $this->ctag = '}}';
225
- $this->otagLen = 2;
226
- $this->ctagLen = 2;
227
- }
228
-
229
- /**
230
- * Flush the current buffer to a token.
231
- */
232
- private function flushBuffer()
233
- {
234
- if (strlen($this->buffer) > 0) {
235
- $this->tokens[] = array(
236
- self::TYPE => self::T_TEXT,
237
- self::LINE => $this->line,
238
- self::VALUE => $this->buffer,
239
- );
240
- $this->buffer = '';
241
- }
242
- }
243
-
244
- /**
245
- * Change the current Mustache delimiters. Set new `otag` and `ctag` values.
246
- *
247
- * @param string $text Mustache template source
248
- * @param int $index Current tokenizer index
249
- *
250
- * @return int New index value
251
- */
252
- private function changeDelimiters($text, $index)
253
- {
254
- $startIndex = strpos($text, '=', $index) + 1;
255
- $close = '=' . $this->ctag;
256
- $closeIndex = strpos($text, $close, $index);
257
-
258
- $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex)));
259
-
260
- $this->tokens[] = array(
261
- self::TYPE => self::T_DELIM_CHANGE,
262
- self::LINE => $this->line,
263
- );
264
-
265
- return $closeIndex + strlen($close) - 1;
266
- }
267
-
268
- /**
269
- * Set the current Mustache `otag` and `ctag` delimiters.
270
- *
271
- * @param string $delimiters
272
- */
273
- private function setDelimiters($delimiters)
274
- {
275
- list($otag, $ctag) = explode(' ', $delimiters);
276
- $this->otag = $otag;
277
- $this->ctag = $ctag;
278
- $this->otagLen = strlen($otag);
279
- $this->ctagLen = strlen($ctag);
280
- }
281
-
282
- /**
283
- * Add pragma token.
284
- *
285
- * Pragmas are hoisted to the front of the template, so all pragma tokens
286
- * will appear at the front of the token list.
287
- *
288
- * @param string $text
289
- * @param int $index
290
- *
291
- * @return int New index value
292
- */
293
- private function addPragma($text, $index)
294
- {
295
- $end = strpos($text, $this->ctag, $index);
296
- $pragma = trim(substr($text, $index + 2, $end - $index - 2));
297
-
298
- // Pragmas are hoisted to the front of the template.
299
- array_unshift($this->tokens, array(
300
- self::TYPE => self::T_PRAGMA,
301
- self::NAME => $pragma,
302
- self::LINE => 0,
303
- ));
304
-
305
- return $end + $this->ctagLen - 1;
306
- }
307
-
308
- /**
309
- * Test whether it's time to change tags.
310
- *
311
- * @param string $tag Current tag name
312
- * @param int $tagLen Current tag name length
313
- * @param string $text Mustache template source
314
- * @param int $index Current tokenizer index
315
- *
316
- * @return bool True if this is a closing section tag
317
- */
318
- private function tagChange($tag, $tagLen, $text, $index)
319
- {
320
- return substr($text, $index, $tagLen) === $tag;
321
- }
322
- }
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Mustache.php.
5
+ *
6
+ * (c) 2010-2015 Justin Hileman
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * Mustache Tokenizer class.
14
+ *
15
+ * This class is responsible for turning raw template source into a set of Mustache tokens.
16
+ */
17
+ class Mustache_Tokenizer
18
+ {
19
+ // Finite state machine states
20
+ const IN_TEXT = 0;
21
+ const IN_TAG_TYPE = 1;
22
+ const IN_TAG = 2;
23
+
24
+ // Token types
25
+ const T_SECTION = '#';
26
+ const T_INVERTED = '^';
27
+ const T_END_SECTION = '/';
28
+ const T_COMMENT = '!';
29
+ const T_PARTIAL = '>';
30
+ const T_PARENT = '<';
31
+ const T_DELIM_CHANGE = '=';
32
+ const T_ESCAPED = '_v';
33
+ const T_UNESCAPED = '{';
34
+ const T_UNESCAPED_2 = '&';
35
+ const T_TEXT = '_t';
36
+ const T_PRAGMA = '%';
37
+ const T_BLOCK_VAR = '$';
38
+ const T_BLOCK_ARG = '$arg';
39
+
40
+ // Valid token types
41
+ private static $tagTypes = array(
42
+ self::T_SECTION => true,
43
+ self::T_INVERTED => true,
44
+ self::T_END_SECTION => true,
45
+ self::T_COMMENT => true,
46
+ self::T_PARTIAL => true,
47
+ self::T_PARENT => true,
48
+ self::T_DELIM_CHANGE => true,
49
+ self::T_ESCAPED => true,
50
+ self::T_UNESCAPED => true,
51
+ self::T_UNESCAPED_2 => true,
52
+ self::T_PRAGMA => true,
53
+ self::T_BLOCK_VAR => true,
54
+ );
55
+
56
+ // Token properties
57
+ const TYPE = 'type';
58
+ const NAME = 'name';
59
+ const OTAG = 'otag';
60
+ const CTAG = 'ctag';
61
+ const LINE = 'line';
62
+ const INDEX = 'index';
63
+ const END = 'end';
64
+ const INDENT = 'indent';
65
+ const NODES = 'nodes';
66
+ const VALUE = 'value';
67
+ const FILTERS = 'filters';
68
+
69
+ private $state;
70
+ private $tagType;
71
+ private $buffer;
72
+ private $tokens;
73
+ private $seenTag;
74
+ private $line;
75
+ private $otag;
76
+ private $ctag;
77
+ private $otagLen;
78
+ private $ctagLen;
79
+
80
+ /**
81
+ * Scan and tokenize template source.
82
+ *
83
+ * @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered.
84
+ *
85
+ * @param string $text Mustache template source to tokenize
86
+ * @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
87
+ *
88
+ * @return array Set of Mustache tokens
89
+ */
90
+ public function scan($text, $delimiters = null)
91
+ {
92
+ // Setting mbstring.func_overload makes things *really* slow.
93
+ // Let's do everyone a favor and scan this string as ASCII instead.
94
+ $encoding = null;
95
+ if (function_exists('mb_internal_encoding') && ini_get('mbstring.func_overload') & 2) {
96
+ $encoding = mb_internal_encoding();
97
+ mb_internal_encoding('ASCII');
98
+ }
99
+
100
+ $this->reset();
101
+
102
+ if ($delimiters = trim($delimiters)) {
103
+ $this->setDelimiters($delimiters);
104
+ }
105
+
106
+ $len = strlen($text);
107
+ for ($i = 0; $i < $len; $i++) {
108
+ switch ($this->state) {
109
+ case self::IN_TEXT:
110
+ if ($this->tagChange($this->otag, $this->otagLen, $text, $i)) {
111
+ $i--;
112
+ $this->flushBuffer();
113
+ $this->state = self::IN_TAG_TYPE;
114
+ } else {
115
+ $char = $text[$i];
116
+ $this->buffer .= $char;
117
+ if ($char === "\n") {
118
+ $this->flushBuffer();
119
+ $this->line++;
120
+ }
121
+ }
122
+ break;
123
+
124
+ case self::IN_TAG_TYPE:
125
+ $i += $this->otagLen - 1;
126
+ $char = $text[$i + 1];
127
+ if (isset(self::$tagTypes[$char])) {
128
+ $tag = $char;
129
+ $this->tagType = $tag;
130
+ } else {
131
+ $tag = null;
132
+ $this->tagType = self::T_ESCAPED;
133
+ }
134
+
135
+ if ($this->tagType === self::T_DELIM_CHANGE) {
136
+ $i = $this->changeDelimiters($text, $i);
137
+ $this->state = self::IN_TEXT;
138
+ } elseif ($this->tagType === self::T_PRAGMA) {
139
+ $i = $this->addPragma($text, $i);
140
+ $this->state = self::IN_TEXT;
141
+ } else {
142
+ if ($tag !== null) {
143
+ $i++;
144
+ }
145
+ $this->state = self::IN_TAG;
146
+ }
147
+ $this->seenTag = $i;
148
+ break;
149
+
150
+ default:
151
+ if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
152
+ $token = array(
153
+ self::TYPE => $this->tagType,
154
+ self::NAME => trim($this->buffer),
155
+ self::OTAG => $this->otag,
156
+ self::CTAG => $this->ctag,
157
+ self::LINE => $this->line,
158
+ self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen,
159
+ );
160
+
161
+ if ($this->tagType === self::T_UNESCAPED) {
162
+ // Clean up `{{{ tripleStache }}}` style tokens.
163
+ if ($this->ctag === '}}') {
164
+ if (($i + 2 < $len) && $text[$i + 2] === '}') {
165
+ $i++;
166
+ } else {
167
+ $msg = sprintf(
168
+ 'Mismatched tag delimiters: %s on line %d',
169
+ $token[self::NAME],
170
+ $token[self::LINE]
171
+ );
172
+
173
+ throw new Mustache_Exception_SyntaxException($msg, $token);
174
+ }
175
+ } else {
176
+ $lastName = $token[self::NAME];
177
+ if (substr($lastName, -1) === '}') {
178
+ $token[self::NAME] = trim(substr($lastName, 0, -1));
179
+ } else {
180
+ $msg = sprintf(
181
+ 'Mismatched tag delimiters: %s on line %d',
182
+ $token[self::NAME],
183
+ $token[self::LINE]
184
+ );
185
+
186
+ throw new Mustache_Exception_SyntaxException($msg, $token);
187
+ }
188
+ }
189
+ }
190
+
191
+ $this->buffer = '';
192
+ $i += $this->ctagLen - 1;
193
+ $this->state = self::IN_TEXT;
194
+ $this->tokens[] = $token;
195
+ } else {
196
+ $this->buffer .= $text[$i];
197
+ }
198
+ break;
199
+ }
200
+ }
201
+
202
+ $this->flushBuffer();
203
+
204
+ // Restore the user's encoding...
205
+ if ($encoding) {
206
+ mb_internal_encoding($encoding);
207
+ }
208
+
209
+ return $this->tokens;
210
+ }
211
+
212
+ /**
213
+ * Helper function to reset tokenizer internal state.
214
+ */
215
+ private function reset()
216
+ {
217
+ $this->state = self::IN_TEXT;
218
+ $this->tagType = null;
219
+ $this->buffer = '';
220
+ $this->tokens = array();
221
+ $this->seenTag = false;
222
+ $this->line = 0;
223
+ $this->otag = '{{';
224
+ $this->ctag = '}}';
225
+ $this->otagLen = 2;
226
+ $this->ctagLen = 2;
227
+ }
228
+
229
+ /**
230
+ * Flush the current buffer to a token.
231
+ */
232
+ private function flushBuffer()
233
+ {
234
+ if (strlen($this->buffer) > 0) {
235
+ $this->tokens[] = array(
236
+ self::TYPE => self::T_TEXT,
237
+ self::LINE => $this->line,
238
+ self::VALUE => $this->buffer,
239
+ );
240
+ $this->buffer = '';
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Change the current Mustache delimiters. Set new `otag` and `ctag` values.
246
+ *
247
+ * @param string $text Mustache template source
248
+ * @param int $index Current tokenizer index
249
+ *
250
+ * @return int New index value
251
+ */
252
+ private function changeDelimiters($text, $index)
253
+ {
254
+ $startIndex = strpos($text, '=', $index) + 1;
255
+ $close = '=' . $this->ctag;
256
+ $closeIndex = strpos($text, $close, $index);
257
+
258
+ $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex)));
259
+
260
+ $this->tokens[] = array(
261
+ self::TYPE => self::T_DELIM_CHANGE,
262
+ self::LINE => $this->line,
263
+ );
264
+
265
+ return $closeIndex + strlen($close) - 1;
266
+ }
267
+
268
+ /**
269
+ * Set the current Mustache `otag` and `ctag` delimiters.
270
+ *
271
+ * @param string $delimiters
272
+ */
273
+ private function setDelimiters($delimiters)
274
+ {
275
+ list($otag, $ctag) = explode(' ', $delimiters);
276
+ $this->otag = $otag;
277
+ $this->ctag = $ctag;
278
+ $this->otagLen = strlen($otag);
279
+ $this->ctagLen = strlen($ctag);
280
+ }
281
+
282
+ /**
283
+ * Add pragma token.
284
+ *
285
+ * Pragmas are hoisted to the front of the template, so all pragma tokens
286
+ * will appear at the front of the token list.
287
+ *
288
+ * @param string $text
289
+ * @param int $index
290
+ *
291
+ * @return int New index value
292
+ */
293
+ private function addPragma($text, $index)
294
+ {
295
+ $end = strpos($text, $this->ctag, $index);
296
+ $pragma = trim(substr($text, $index + 2, $end - $index - 2));
297
+
298
+ // Pragmas are hoisted to the front of the template.
299
+ array_unshift($this->tokens, array(
300
+ self::TYPE => self::T_PRAGMA,
301
+ self::NAME => $pragma,
302
+ self::LINE => 0,
303
+ ));
304
+
305
+ return $end + $this->ctagLen - 1;
306
+ }
307
+
308
+ /**
309
+ * Test whether it's time to change tags.
310
+ *
311
+ * @param string $tag Current tag name
312
+ * @param int $tagLen Current tag name length
313
+ * @param string $text Mustache template source
314
+ * @param int $index Current tokenizer index
315
+ *
316
+ * @return bool True if this is a closing section tag
317
+ */
318
+ private function tagChange($tag, $tagLen, $text, $index)
319
+ {
320
+ return substr($text, $index, $tagLen) === $tag;
321
+ }
322
+ }
lib/php/Paapi/aalb_paapi_helper.php CHANGED
@@ -1,129 +1,129 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Helper class for Paapi
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/lib/php/Paapi
21
- */
22
- class Aalb_Paapi_Helper {
23
-
24
- /**
25
- * Returns the item lookup URL for asins
26
- *
27
- * @param string $asin Asin value.
28
- * @param string $marketplaces Marketplace to search the products.
29
- * @param string $tracking_id Associate tag.
30
- *
31
- * @return string Signed URL for item lookup.
32
- */
33
- function get_item_lookup_url( $asin, $marketplace, $tracking_id ) {
34
- $params = array(
35
- "Operation" => "ItemLookup", "ItemId" => "$asin", "IdType" => "ASIN", "ResponseGroup" => "Images,ItemAttributes,OfferFull", "AssociateTag" => "$tracking_id",
36
- );
37
- $url = $this->aws_signed_url( $params, $marketplace );
38
-
39
- return $url;
40
- }
41
-
42
- /**
43
- * Returns signed URL for Paapi request
44
- *
45
- * @since 1.0.0
46
- *
47
- * @param array $params Paapi parameters.
48
- * @param string $marketplace Marketplace to search the product.
49
- *
50
- * @return string Signed URL.
51
- */
52
- function aws_signed_url( $params, $marketplace ) {
53
- $access_key_id = openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
54
- $secret_key = openssl_decrypt( base64_decode( get_option( AALB_AWS_SECRET_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
55
- $host = $marketplace;
56
-
57
- $method = 'GET';
58
- $uri = PAAPI_URI;
59
-
60
- $params["Service"] = PAAPI_SERVICE;
61
- $params["AWSAccessKeyId"] = $access_key_id;
62
- $params["Timestamp"] = gmdate( 'Y-m-d\TH:i:s\Z' );
63
- $params["Version"] = PAAPI_VERSION;
64
-
65
- ksort( $params );
66
-
67
- $canonicalized_query = array();
68
- foreach ( $params as $param => $value ) {
69
- $param = str_replace( "%7E", "~", rawurlencode( $param ) );
70
- $value = str_replace( "%7E", "~", rawurlencode( $value ) );
71
- $canonicalized_query[] = $param . "=" . $value;
72
- }
73
-
74
- $canonicalized_query = implode( "&", $canonicalized_query );
75
-
76
- $string_to_sign = $method . "\n" . $host . "\n" . $uri . "\n" . $canonicalized_query;
77
- $signature = base64_encode( hash_hmac( "sha256", $string_to_sign, $secret_key, true ) );
78
- $signature = str_replace( "%7E", "~", rawurlencode( $signature ) );
79
-
80
- $signed_url = PAAPI_TRANSFER_PROTOCOL . $host . $uri . PAAPI_URL_QUERY_SEPARATOR . $canonicalized_query . "&Signature=" . $signature;
81
-
82
- return $signed_url;
83
- }
84
-
85
- /**
86
- * Returns the item search URL for search keywords
87
- *
88
- * @param string $search_keywords Search keywords of the products.
89
- * @param string $marketplaces Marketplace to search the products.
90
- * @param string $tracking_id Associate tag.
91
- *
92
- * @return string Signed URL for item search.
93
- */
94
- function get_item_search_url( $search_keywords, $marketplace, $tracking_id ) {
95
- $params = array(
96
- "Operation" => "ItemSearch", "SearchIndex" => "All", "Keywords" => "$search_keywords", "ResponseGroup" => "Images,ItemAttributes,Offers", "AssociateTag" => "$tracking_id",
97
- );
98
- $url = $this->aws_signed_url( $params, $marketplace );
99
-
100
- return $url;
101
- }
102
-
103
- /**
104
- * PA-API error messages to display in case of request errors
105
- *
106
- * @param string $error code Error code of the request.
107
- *
108
- * @return string PA-API error message.
109
- */
110
- function get_error_message( $error ) {
111
- switch ( $error ) {
112
- case HTTP_BAD_REQUEST:
113
- return HTTP_BAD_REQUEST_MESSAGE;
114
- case HTTP_FORBIDDEN:
115
- return HTTP_FORBIDDEN_MESSAGE;
116
- case HTTP_REQUEST_URI_TOO_LONG:
117
- return HTTP_REQUEST_URI_TOO_LONG_MESSAGE;
118
- case HTTP_INTERNAL_SERVER_ERROR:
119
- return HTTP_INTERNAL_SERVER_ERROR_MESSAGE;
120
- case HTTP_THROTTLE:
121
- return HTTP_THROTTLE_MESSAGE;
122
- default:
123
- return $error;
124
- }
125
- }
126
-
127
- }
128
-
129
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Helper class for Paapi
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/lib/php/Paapi
21
+ */
22
+ class Aalb_Paapi_Helper {
23
+
24
+ /**
25
+ * Returns the item lookup URL for asins
26
+ *
27
+ * @param string $asin Asin value.
28
+ * @param string $marketplaces Marketplace to search the products.
29
+ * @param string $tracking_id Associate tag.
30
+ *
31
+ * @return string Signed URL for item lookup.
32
+ */
33
+ function get_item_lookup_url( $asin, $marketplace, $tracking_id ) {
34
+ $params = array(
35
+ "Operation" => "ItemLookup", "ItemId" => "$asin", "IdType" => "ASIN", "ResponseGroup" => "Images,ItemAttributes,OfferFull", "AssociateTag" => "$tracking_id",
36
+ );
37
+ $url = $this->aws_signed_url( $params, $marketplace );
38
+
39
+ return $url;
40
+ }
41
+
42
+ /**
43
+ * Returns signed URL for Paapi request
44
+ *
45
+ * @since 1.0.0
46
+ *
47
+ * @param array $params Paapi parameters.
48
+ * @param string $marketplace Marketplace to search the product.
49
+ *
50
+ * @return string Signed URL.
51
+ */
52
+ function aws_signed_url( $params, $marketplace ) {
53
+ $access_key_id = openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
54
+ $secret_key = openssl_decrypt( base64_decode( get_option( AALB_AWS_SECRET_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
55
+ $host = $marketplace;
56
+
57
+ $method = 'GET';
58
+ $uri = PAAPI_URI;
59
+
60
+ $params["Service"] = PAAPI_SERVICE;
61
+ $params["AWSAccessKeyId"] = $access_key_id;
62
+ $params["Timestamp"] = gmdate( 'Y-m-d\TH:i:s\Z' );
63
+ $params["Version"] = PAAPI_VERSION;
64
+
65
+ ksort( $params );
66
+
67
+ $canonicalized_query = array();
68
+ foreach ( $params as $param => $value ) {
69
+ $param = str_replace( "%7E", "~", rawurlencode( $param ) );
70
+ $value = str_replace( "%7E", "~", rawurlencode( $value ) );
71
+ $canonicalized_query[] = $param . "=" . $value;
72
+ }
73
+
74
+ $canonicalized_query = implode( "&", $canonicalized_query );
75
+
76
+ $string_to_sign = $method . "\n" . $host . "\n" . $uri . "\n" . $canonicalized_query;
77
+ $signature = base64_encode( hash_hmac( "sha256", $string_to_sign, $secret_key, true ) );
78
+ $signature = str_replace( "%7E", "~", rawurlencode( $signature ) );
79
+
80
+ $signed_url = PAAPI_TRANSFER_PROTOCOL . $host . $uri . PAAPI_URL_QUERY_SEPARATOR . $canonicalized_query . "&Signature=" . $signature;
81
+
82
+ return $signed_url;
83
+ }
84
+
85
+ /**
86
+ * Returns the item search URL for search keywords
87
+ *
88
+ * @param string $search_keywords Search keywords of the products.
89
+ * @param string $marketplaces Marketplace to search the products.
90
+ * @param string $tracking_id Associate tag.
91
+ *
92
+ * @return string Signed URL for item search.
93
+ */
94
+ function get_item_search_url( $search_keywords, $marketplace, $tracking_id ) {
95
+ $params = array(
96
+ "Operation" => "ItemSearch", "SearchIndex" => "All", "Keywords" => "$search_keywords", "ResponseGroup" => "Images,ItemAttributes,Offers", "AssociateTag" => "$tracking_id",
97
+ );
98
+ $url = $this->aws_signed_url( $params, $marketplace );
99
+
100
+ return $url;
101
+ }
102
+
103
+ /**
104
+ * PA-API error messages to display in case of request errors
105
+ *
106
+ * @param string $error code Error code of the request.
107
+ *
108
+ * @return string PA-API error message.
109
+ */
110
+ function get_error_message( $error ) {
111
+ switch ( $error ) {
112
+ case HTTP_BAD_REQUEST:
113
+ return HTTP_BAD_REQUEST_MESSAGE;
114
+ case HTTP_FORBIDDEN:
115
+ return HTTP_FORBIDDEN_MESSAGE;
116
+ case HTTP_REQUEST_URI_TOO_LONG:
117
+ return HTTP_REQUEST_URI_TOO_LONG_MESSAGE;
118
+ case HTTP_INTERNAL_SERVER_ERROR:
119
+ return HTTP_INTERNAL_SERVER_ERROR_MESSAGE;
120
+ case HTTP_THROTTLE:
121
+ return HTTP_THROTTLE_MESSAGE;
122
+ default:
123
+ return $error;
124
+ }
125
+ }
126
+
127
+ }
128
+
129
+ ?>
lib/php/aalb_internationalization_helper.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Helper class for internationalizing the strings
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
- */
22
- class Aalb_Internationalization_Helper {
23
-
24
- /**
25
- * Array that defines the translations for various marketplaces
26
- */
27
- protected $translation_array;
28
-
29
- public function __construct() {
30
- $this->translation_array = array(
31
- CHECK_ON_AMAZON => array(
32
- US => "Check on Amazon",
33
- FR => "Consulter sur Amazon.fr",
34
- IT => "Vedi su Amazon.it",
35
- DE => "Hier auf Amazon.de",
36
- ES => "Consultar en Amazon.es",
37
- BR => "Check on Amazon",
38
- CA => "Check on Amazon",
39
- CN => "Check on Amazon",
40
- IN => "Check on Amazon",
41
- JP => "Check on Amazon",
42
- MX => "Check on Amazon",
43
- UK => "Check on Amazon",
44
- ),
45
- OUT_OF_STOCK => array(
46
- US => "Out of stock",
47
- FR => "Rupture de stock",
48
- IT => "Non disponibile",
49
- DE => "Derzeit nicht verfügbar",
50
- ES => "Producto no disponible",
51
- BR => "Out of stock",
52
- CA => "Out of stock",
53
- CN => "Out of stock",
54
- IN => "Out of stock",
55
- JP => "Out of stock",
56
- MX => "Out of stock",
57
- UK => "Out of stock",
58
- ),
59
- );
60
- }
61
-
62
- /**
63
- * Internationalize stings by marketplace
64
- *
65
- * @since 1.0.0
66
- *
67
- * @param string $key Identifier of string to be translated
68
- * @param string $marketplace The target marketplace name
69
- *
70
- * @return string
71
- */
72
- public function internationalize_by_marketplace( $key, $marketplace ) {
73
- $translated_string = $this->translation_array[ $key ][ $marketplace ];
74
-
75
- if ( $translated_string == null ) {
76
- //use english if transation is not available
77
- $translated_string = $this->translation_array[ $key ][ AALB_DEFAULT_MARKETPLACE_NAME ];
78
- if ( $translated_string == null ) {
79
- //use key name if english is also not available
80
- $translated_string = $key;
81
- }
82
- }
83
-
84
- return $translated_string;
85
- }
86
- }
87
-
88
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Helper class for internationalizing the strings
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
+ */
22
+ class Aalb_Internationalization_Helper {
23
+
24
+ /**
25
+ * Array that defines the translations for various marketplaces
26
+ */
27
+ protected $translation_array;
28
+
29
+ public function __construct() {
30
+ $this->translation_array = array(
31
+ CHECK_ON_AMAZON => array(
32
+ US => "Check on Amazon",
33
+ FR => "Consulter sur Amazon.fr",
34
+ IT => "Vedi su Amazon.it",
35
+ DE => "Hier auf Amazon.de",
36
+ ES => "Consultar en Amazon.es",
37
+ BR => "Check on Amazon",
38
+ CA => "Check on Amazon",
39
+ CN => "Check on Amazon",
40
+ IN => "Check on Amazon",
41
+ JP => "Check on Amazon",
42
+ MX => "Check on Amazon",
43
+ UK => "Check on Amazon",
44
+ ),
45
+ OUT_OF_STOCK => array(
46
+ US => "Out of stock",
47
+ FR => "Rupture de stock",
48
+ IT => "Non disponibile",
49
+ DE => "Derzeit nicht verfügbar",
50
+ ES => "Producto no disponible",
51
+ BR => "Out of stock",
52
+ CA => "Out of stock",
53
+ CN => "Out of stock",
54
+ IN => "Out of stock",
55
+ JP => "Out of stock",
56
+ MX => "Out of stock",
57
+ UK => "Out of stock",
58
+ ),
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Internationalize stings by marketplace
64
+ *
65
+ * @since 1.0.0
66
+ *
67
+ * @param string $key Identifier of string to be translated
68
+ * @param string $marketplace The target marketplace name
69
+ *
70
+ * @return string
71
+ */
72
+ public function internationalize_by_marketplace( $key, $marketplace ) {
73
+ $translated_string = $this->translation_array[ $key ][ $marketplace ];
74
+
75
+ if ( $translated_string == null ) {
76
+ //use english if transation is not available
77
+ $translated_string = $this->translation_array[ $key ][ AALB_DEFAULT_MARKETPLACE_NAME ];
78
+ if ( $translated_string == null ) {
79
+ //use key name if english is also not available
80
+ $translated_string = $key;
81
+ }
82
+ }
83
+
84
+ return $translated_string;
85
+ }
86
+ }
87
+
88
+ ?>
lib/php/aalb_tracking_api_helper.php CHANGED
@@ -1,135 +1,135 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Helper class for APIs used for impression and clicks tracking
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
- */
22
- class Aalb_Tracking_Api_Helper {
23
-
24
- protected $remote_loader;
25
- protected $helper;
26
- protected $version_info;
27
-
28
- public function __construct() {
29
- $this->remote_loader = new Aalb_Remote_Loader();
30
- $this->helper = new Aalb_Helper();
31
-
32
- //Initializes the version information once.
33
- $plugin_version = AALB_PLUGIN_CURRENT_VERSION;
34
- $wordpress_version = $this->helper->get_wordpress_version();
35
- $this->version_info = array(
36
- 'wordpress' => $wordpress_version,
37
- 'plugin' => $plugin_version
38
- );
39
- }
40
-
41
- /**
42
- * Returns the response of the link-id API.
43
- * The GET request returns a unique link-id everytime a shortcode is added
44
- *
45
- * @since 1.0.0
46
- *
47
- * @param string $shortcode_name Name of the shortcode used
48
- * @param string $shortcode_params Array of all shortcode parameter key-value pairs
49
- *
50
- * @return string Response of the get link-id API for the given link-id
51
- */
52
- public function get_link_id( $shortcode_name, $shortcode_params ) {
53
- $link_info = array(
54
- 'shortcode_name' => $shortcode_name, 'shortcode_params' => $shortcode_params, 'version' => $this->version_info
55
- );
56
- $request_body = wp_json_encode( $link_info );
57
- $base_url = $this->get_base_url( 'link-id' );
58
- $response = $this->remote_loader->post( $base_url, $request_body );
59
- $response_body = json_decode( $response, true );
60
-
61
- return $response_body["link-id"];
62
- }
63
-
64
- /**
65
- * Builds the base url for each tracking api request. Adds common parameters
66
- *
67
- * @since 1.0.0
68
- *
69
- * @param string $method_path Relative path of the api method to be called.
70
- *
71
- * @return string The base url with common query parameters
72
- */
73
- private function get_base_url( $method_path ) {
74
- $access_key_id = openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
75
-
76
- return ( AALB_TRACKING_API_ENDPOINT . $method_path . '?' . AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM . '&' . AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM . $access_key_id );
77
- }
78
-
79
- /**
80
- * Returns the response of the impressions API for a given link-id
81
- * TODO: Not used post v1.4. Impression tracking plugged out for re-vamping purposes.
82
- *
83
- * @since 1.0.0
84
- *
85
- * @param string $link_id Link ID for which impression parameters are required
86
- * @param string $shortcode_name Name of the shortcode used
87
- * @param string $shortcode_params Array of all shortcode parameter key-value pairs
88
- *
89
- * @return string Response of the get impression API for the given link-id
90
- */
91
- public function get_impression_params( $link_id, $shortcode_name, $shortcode_params ) {
92
- $link_info = array(
93
- 'shortcode_name' => $shortcode_name, 'shortcode_params' => $shortcode_params, 'version' => $this->version_info
94
- );
95
- $request_body = wp_json_encode( $link_info );
96
- $base_url = $this->get_base_url( 'impression' );
97
- $url = $base_url . '&link-id=' . $link_id;
98
-
99
- return $this->remote_loader->post( $url, $request_body );
100
- }
101
-
102
- /**
103
- * Returns the click URL by parsing the recieved getImpressions API Response
104
- * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
105
- *
106
- * @since 1.0.0
107
- *
108
- * @param string $impression_params JSON Response from the get impressions API for a link-id
109
- *
110
- * @return string $click_url Click URL for an impression ID
111
- */
112
- public function get_click_url( $impression_params ) {
113
- $body = json_decode( $impression_params, true );
114
-
115
- return $body["click-url"];
116
- }
117
-
118
- /**
119
- * Echoes an invisible img with src=pixel-url to fire the pixels
120
- * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
121
- *
122
- * @since 1.0.0
123
- *
124
- * @param string $impression_params JSON Response from the get impressions API for a link-id
125
- */
126
- public function insert_pixel( $impression_params ) {
127
- $body = json_decode( $impression_params, true );
128
- $pixel_url = $body["pixel-url"];
129
- if ( ! is_amp_endpoint() ) {
130
- echo '<img src="' . $pixel_url . '" style="display:none"></img>';
131
- }
132
- }
133
- }
134
-
135
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Helper class for APIs used for impression and clicks tracking
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
+ */
22
+ class Aalb_Tracking_Api_Helper {
23
+
24
+ protected $remote_loader;
25
+ protected $helper;
26
+ protected $version_info;
27
+
28
+ public function __construct() {
29
+ $this->remote_loader = new Aalb_Remote_Loader();
30
+ $this->helper = new Aalb_Helper();
31
+
32
+ //Initializes the version information once.
33
+ $plugin_version = AALB_PLUGIN_CURRENT_VERSION;
34
+ $wordpress_version = $this->helper->get_wordpress_version();
35
+ $this->version_info = array(
36
+ 'wordpress' => $wordpress_version,
37
+ 'plugin' => $plugin_version
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Returns the response of the link-id API.
43
+ * The GET request returns a unique link-id everytime a shortcode is added
44
+ *
45
+ * @since 1.0.0
46
+ *
47
+ * @param string $shortcode_name Name of the shortcode used
48
+ * @param string $shortcode_params Array of all shortcode parameter key-value pairs
49
+ *
50
+ * @return string Response of the get link-id API for the given link-id
51
+ */
52
+ public function get_link_id( $shortcode_name, $shortcode_params ) {
53
+ $link_info = array(
54
+ 'shortcode_name' => $shortcode_name, 'shortcode_params' => $shortcode_params, 'version' => $this->version_info
55
+ );
56
+ $request_body = wp_json_encode( $link_info );
57
+ $base_url = $this->get_base_url( 'link-id' );
58
+ $response = $this->remote_loader->post( $base_url, $request_body );
59
+ $response_body = json_decode( $response, true );
60
+
61
+ return $response_body["link-id"];
62
+ }
63
+
64
+ /**
65
+ * Builds the base url for each tracking api request. Adds common parameters
66
+ *
67
+ * @since 1.0.0
68
+ *
69
+ * @param string $method_path Relative path of the api method to be called.
70
+ *
71
+ * @return string The base url with common query parameters
72
+ */
73
+ private function get_base_url( $method_path ) {
74
+ $access_key_id = openssl_decrypt( base64_decode( get_option( AALB_AWS_ACCESS_KEY ) ), AALB_ENCRYPTION_ALGORITHM, AALB_ENCRYPTION_KEY, 0, AALB_ENCRYPTION_IV );
75
+
76
+ return ( AALB_TRACKING_API_ENDPOINT . $method_path . '?' . AALB_TRACKING_API_SOURCE_TOOL_QUERY_PARAM . '&' . AALB_TRACKING_API_ACCESS_KEY_QUERY_PARAM . $access_key_id );
77
+ }
78
+
79
+ /**
80
+ * Returns the response of the impressions API for a given link-id
81
+ * TODO: Not used post v1.4. Impression tracking plugged out for re-vamping purposes.
82
+ *
83
+ * @since 1.0.0
84
+ *
85
+ * @param string $link_id Link ID for which impression parameters are required
86
+ * @param string $shortcode_name Name of the shortcode used
87
+ * @param string $shortcode_params Array of all shortcode parameter key-value pairs
88
+ *
89
+ * @return string Response of the get impression API for the given link-id
90
+ */
91
+ public function get_impression_params( $link_id, $shortcode_name, $shortcode_params ) {
92
+ $link_info = array(
93
+ 'shortcode_name' => $shortcode_name, 'shortcode_params' => $shortcode_params, 'version' => $this->version_info
94
+ );
95
+ $request_body = wp_json_encode( $link_info );
96
+ $base_url = $this->get_base_url( 'impression' );
97
+ $url = $base_url . '&link-id=' . $link_id;
98
+
99
+ return $this->remote_loader->post( $url, $request_body );
100
+ }
101
+
102
+ /**
103
+ * Returns the click URL by parsing the recieved getImpressions API Response
104
+ * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
105
+ *
106
+ * @since 1.0.0
107
+ *
108
+ * @param string $impression_params JSON Response from the get impressions API for a link-id
109
+ *
110
+ * @return string $click_url Click URL for an impression ID
111
+ */
112
+ public function get_click_url( $impression_params ) {
113
+ $body = json_decode( $impression_params, true );
114
+
115
+ return $body["click-url"];
116
+ }
117
+
118
+ /**
119
+ * Echoes an invisible img with src=pixel-url to fire the pixels
120
+ * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
121
+ *
122
+ * @since 1.0.0
123
+ *
124
+ * @param string $impression_params JSON Response from the get impressions API for a link-id
125
+ */
126
+ public function insert_pixel( $impression_params ) {
127
+ $body = json_decode( $impression_params, true );
128
+ $pixel_url = $body["pixel-url"];
129
+ if ( ! is_amp_endpoint() ) {
130
+ echo '<img src="' . $pixel_url . '" style="display:none"></img>';
131
+ }
132
+ }
133
+ }
134
+
135
+ ?>
lib/php/aalb_validation_helper.php CHANGED
@@ -1,112 +1,112 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Hepler class for validations used in the plugin.
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
- */
22
- class Aalb_Validation_Helper {
23
-
24
- protected $config_loader;
25
- protected $helper;
26
-
27
- public function __construct() {
28
- $this->config_loader = new Aalb_Config_Loader();
29
- $this->helper = new Aalb_Helper();
30
- }
31
-
32
- /**
33
- * Validate ASIN
34
- *
35
- * @since 1.0.0
36
- *
37
- * @param string $asins ASIN
38
- *
39
- * @return bool TRUE if the asin is valid, FALSE otherwise
40
- */
41
- public function validate_asin( $asin ) {
42
- return preg_match( '/^([0-9][0-9]{8}[0-9X]|[A-Z][A-Z0-9]{9})$/', trim( $asin ) );
43
- }
44
-
45
- /**
46
- * Validate Template Name
47
- *
48
- * @since 1.0.0
49
- *
50
- * @param string $template template name
51
- *
52
- * @return bool TRUE if the template name is valid, FALSE otherwise
53
- */
54
- public function validate_template_name( $template ) {
55
- $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
56
-
57
- return in_array( $template, $aalb_template_names );
58
- }
59
-
60
- /**
61
- * Validate Link ID
62
- * The link id should be alphanumeric inlcude hyphens (-) to be valid
63
- *
64
- * @since 1.0.0
65
- *
66
- * @param string $link_id Link ID from shortcode
67
- *
68
- * @return bool TRUE if the link id is valid, FALSE otherwise
69
- */
70
- public function validate_link_id( $link_id ) {
71
- return ctype_alnum( str_replace( array( '-' ), '', $link_id ) );
72
- }
73
-
74
- /**
75
- * Validate Marketplace
76
- *
77
- * @since 1.0.0
78
- *
79
- * @param string $marketplace Marketplace Abbreviation from shortcode
80
- *
81
- * @return bool TRUE if the marketplace is valid, FALSE otherwise
82
- */
83
- public function validate_marketplace( $marketplace ) {
84
- $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
85
-
86
- return in_array( $marketplace, $aalb_marketplace_names );
87
- }
88
-
89
- /**
90
- * Validate Store ID
91
- *
92
- * @since 1.0.0
93
- *
94
- * @param string $store_id Associate Tag from Shortcode
95
- *
96
- * @return bool TRUE if the Associate Tag is valid, FALSE otherwise
97
- */
98
- public function validate_store_id( $store_id ) {
99
- $aalb_store_id_names = explode( "\r\n", get_option( AALB_STORE_ID_NAMES ) );
100
- //If the store id used is "not-specified".
101
- if ( $store_id === AALB_DEFAULT_STORE_ID_NAME ) {
102
- $this->helper->show_error_in_preview( "Associate Tag was not found. The sales will not be attributed to any store and you will not earn the associate fees for it. Please provide a valid Associate Tag if you wish to earn the referral fees. Assocaite Tags can be configured from the 'Settings' tab in the WordPress administration panel" );
103
-
104
- return true;
105
- }
106
-
107
- return in_array( $store_id, $aalb_store_id_names );
108
- }
109
-
110
- }
111
-
112
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Hepler class for validations used in the plugin.
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
+ */
22
+ class Aalb_Validation_Helper {
23
+
24
+ protected $config_loader;
25
+ protected $helper;
26
+
27
+ public function __construct() {
28
+ $this->config_loader = new Aalb_Config_Loader();
29
+ $this->helper = new Aalb_Helper();
30
+ }
31
+
32
+ /**
33
+ * Validate ASIN
34
+ *
35
+ * @since 1.0.0
36
+ *
37
+ * @param string $asins ASIN
38
+ *
39
+ * @return bool TRUE if the asin is valid, FALSE otherwise
40
+ */
41
+ public function validate_asin( $asin ) {
42
+ return preg_match( '/^([0-9][0-9]{8}[0-9X]|[A-Z][A-Z0-9]{9})$/', trim( $asin ) );
43
+ }
44
+
45
+ /**
46
+ * Validate Template Name
47
+ *
48
+ * @since 1.0.0
49
+ *
50
+ * @param string $template template name
51
+ *
52
+ * @return bool TRUE if the template name is valid, FALSE otherwise
53
+ */
54
+ public function validate_template_name( $template ) {
55
+ $aalb_template_names = get_option( AALB_TEMPLATE_NAMES );
56
+
57
+ return in_array( $template, $aalb_template_names );
58
+ }
59
+
60
+ /**
61
+ * Validate Link ID
62
+ * The link id should be alphanumeric inlcude hyphens (-) to be valid
63
+ *
64
+ * @since 1.0.0
65
+ *
66
+ * @param string $link_id Link ID from shortcode
67
+ *
68
+ * @return bool TRUE if the link id is valid, FALSE otherwise
69
+ */
70
+ public function validate_link_id( $link_id ) {
71
+ return ctype_alnum( str_replace( array( '-' ), '', $link_id ) );
72
+ }
73
+
74
+ /**
75
+ * Validate Marketplace
76
+ *
77
+ * @since 1.0.0
78
+ *
79
+ * @param string $marketplace Marketplace Abbreviation from shortcode
80
+ *
81
+ * @return bool TRUE if the marketplace is valid, FALSE otherwise
82
+ */
83
+ public function validate_marketplace( $marketplace ) {
84
+ $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
85
+
86
+ return in_array( $marketplace, $aalb_marketplace_names );
87
+ }
88
+
89
+ /**
90
+ * Validate Store ID
91
+ *
92
+ * @since 1.0.0
93
+ *
94
+ * @param string $store_id Associate Tag from Shortcode
95
+ *
96
+ * @return bool TRUE if the Associate Tag is valid, FALSE otherwise
97
+ */
98
+ public function validate_store_id( $store_id ) {
99
+ $aalb_store_id_names = explode( "\r\n", get_option( AALB_STORE_ID_NAMES ) );
100
+ //If the store id used is "not-specified".
101
+ if ( $store_id === AALB_DEFAULT_STORE_ID_NAME ) {
102
+ $this->helper->show_error_in_preview( "Associate Tag was not found. The sales will not be attributed to any store and you will not earn the associate fees for it. Please provide a valid Associate Tag if you wish to earn the referral fees. Assocaite Tags can be configured from the 'Settings' tab in the WordPress administration panel" );
103
+
104
+ return true;
105
+ }
106
+
107
+ return in_array( $store_id, $aalb_store_id_names );
108
+ }
109
+
110
+ }
111
+
112
+ ?>
lib/php/aalb_xml_helper.php CHANGED
@@ -1,321 +1,321 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Helper class for customizations to the xml response
17
- *
18
- * @since 1.0.0
19
- * @package AmazonAssociatesLinkBuilder
20
- * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
- */
22
- class Aalb_Xml_Helper {
23
-
24
- protected $internationalization_helper;
25
-
26
- public function __construct() {
27
- $this->internationalization_helper = new Aalb_Internationalization_Helper();
28
- }
29
-
30
- /**
31
- * Add custom nodes to xml response
32
- *
33
- * @since 1.0.0
34
- *
35
- * @param SimpleXMLElement $items Well-formed XML string
36
- *
37
- * @return SimpleXMLElement $items XML String with custom nodes added
38
- */
39
- public function add_custom_nodes( $items, $marketplace ) {
40
- $common_marketplace_node_name = 'Marketplace' . $marketplace;
41
- $items->ID = "[[UNIQUE_ID]]";
42
-
43
- //add aalb nodes needed for each item
44
- foreach ( $items->Item as $item ) {
45
- $aalb_node = $item->addChild( 'aalb' );
46
-
47
- $aalb_node->ASIN = isset( $item->ASIN ) ? $item->ASIN : null;
48
- $aalb_node->Title = isset( $item->ItemAttributes->Title ) ? $item->ItemAttributes->Title : null;
49
- $aalb_node->DetailPageURL = isset( $item->DetailPageURL ) ? $item->DetailPageURL : null;
50
- $aalb_node->LargeImageURL = isset( $item->LargeImage->URL ) ? $item->LargeImage->URL : null;
51
- $aalb_node->MediumImageURL = isset( $item->MediumImage->URL ) ? $item->MediumImage->URL : null;
52
- $aalb_node->SmallImageURL = isset( $item->MediumImage->URL ) ? $item->SmallImage->URL : null;
53
-
54
- //Marketplace
55
- $marketplace_node_name = $common_marketplace_node_name;
56
- $aalb_node = $this->add_xml_node( $aalb_node, $marketplace_node_name, 'true' );
57
-
58
- //By Information
59
- $aalb_node = $this->add_by_information_node( $item, $aalb_node );
60
-
61
- //Savings
62
- $aalb_node = $this->add_savings_node( $item, $aalb_node );
63
-
64
- //MinimumPrice
65
- $aalb_node = $this->add_min_price_node( $item, $aalb_node );
66
-
67
- //Prime
68
- $aalb_node = $this->add_prime_node( $item, $aalb_node );
69
-
70
- //Merchant Name
71
- $aalb_node = $this->add_merchant_node( $item, $aalb_node );
72
-
73
- //Current and Strike Price
74
- $aalb_node = $this->add_price_nodes( $item, $aalb_node );
75
-
76
-
77
- //Node to check "out of stock" items
78
- $aalb_node = $this->add_out_of_stock_node( $item, $aalb_node, $marketplace );
79
-
80
-
81
- //If the Buying Price is empty or if is is Too Low to Display
82
- if ( empty( $aalb_node->CurrentPrice ) or strtolower( $aalb_node->CurrentPrice ) == 'too low to display' ) {
83
- $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace( CHECK_ON_AMAZON, $marketplace );
84
- }
85
- }
86
-
87
- //add common aalb nodes
88
- $aalb_common_node = $items->addChild( 'AalbHeader' );
89
- $aalb_common_node = $this->add_xml_node( $aalb_common_node, $common_marketplace_node_name, 'true' );
90
-
91
- return $items;
92
- }
93
-
94
- /**
95
- * Adds a child xml node to a given parent node if the value is not empty.
96
- *
97
- * @since 1.0.0
98
- *
99
- * @param SimpleXMLElement $parent_node PHP XML Object of parent node
100
- * @param string $node_name Name of the new node to be added
101
- * @param string $node_value Value of the new node to be added
102
- *
103
- * @return SimpleXMLElement $parent_node Parent node with added child node
104
- */
105
- public function add_xml_node( $parent_node, $node_name, $node_value ) {
106
- if ( ! empty( $node_value ) ) {
107
- $parent_node->$node_name = $node_value;
108
- }
109
-
110
- return $parent_node;
111
- }
112
-
113
- /**
114
- * Adds By Information Node
115
- * And separated list of all artists, brands and authors
116
- *
117
- * @since 1.0.0
118
- *
119
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
120
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
121
- *
122
- * @return SimpleXMLElement Modified aalb_node
123
- */
124
- public function add_by_information_node( $item, $aalb_node ) {
125
- $author_array = array();
126
- $brand_array = array();
127
- $artist_array = array();
128
- $by_information = array();
129
- foreach ( $item->ItemAttributes->Author as $author ) {
130
- array_push( $author_array, $author );
131
- }
132
- foreach ( $item->ItemAttributes->Brand as $brand ) {
133
- array_push( $brand_array, $brand );
134
- }
135
- foreach ( $item->ItemAttributes->Artist as $artist ) {
136
- array_push( $artist_array, $artist );
137
- }
138
- if ( ! empty( $author_array ) ) {
139
- array_push( $by_information, implode( ', ', $author_array ) );
140
- }
141
- if ( ! empty( $brand_array ) ) {
142
- array_push( $by_information, implode( ', ', $brand_array ) );
143
- }
144
- if ( ! empty( $artist_array ) ) {
145
- array_push( $by_information, implode( ', ', $artist_array ) );
146
- }
147
- $aalb_node->By = implode( ' and ', $by_information );
148
-
149
- return $aalb_node;
150
- }
151
-
152
- /**
153
- * Adds Savings related nodes
154
- * Adds Amount saved in both raw and formatted way and the percentage saved.
155
- * Savings node are added only if we get saving nodes in the XML response from PAAPI.
156
- *
157
- * @since 1.0.0
158
- *
159
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
160
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
161
- *
162
- * @return SimpleXMLElement Node to which values are added
163
- */
164
- public function add_savings_node( $item, $aalb_node ) {
165
- if ( ! empty( $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice ) ) {
166
- $aalb_node = $this->add_xml_node( $aalb_node, 'Saving', $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice );
167
- }
168
- if ( ! empty( $item->Offers->Offer->OfferListing->AmountSaved->Amount ) ) {
169
- $aalb_node = $this->add_xml_node( $aalb_node, 'SavingValue', $item->Offers->Offer->OfferListing->AmountSaved->Amount );
170
- }
171
- if ( ! empty( $item->Offers->Offer->OfferListing->PercentageSaved ) ) {
172
- $aalb_node = $this->add_xml_node( $aalb_node, 'SavingPercent', $item->Offers->Offer->OfferListing->PercentageSaved );
173
- }
174
-
175
- return $aalb_node;
176
- }
177
-
178
- /**
179
- * Adds Minimum Price related nodes
180
- * Adds raw and formatted values of minimum price
181
- *
182
- * @since 1.0.0
183
- *
184
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
185
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
186
- *
187
- * @return SimpleXMLElement Node to which values are added
188
- */
189
- public function add_min_price_node( $item, $aalb_node ) {
190
- if ( ! empty( $item->OfferSummary->LowestNewPrice->FormattedPrice ) ) {
191
- $aalb_node = $this->add_xml_node( $aalb_node, 'MinimumPrice', $item->OfferSummary->LowestNewPrice->FormattedPrice );
192
- }
193
- if ( ! empty( $item->OfferSummary->LowestNewPrice->Amount ) ) {
194
- $aalb_node = $this->add_xml_node( $aalb_node, 'MinimumPriceValue', $item->OfferSummary->LowestNewPrice->Amount );
195
- }
196
-
197
- return $aalb_node;
198
- }
199
-
200
- /**
201
- * Adds Prime node
202
- * Adds Prime node if the item is eligible for prime
203
- *
204
- * @since 1.4.1
205
- *
206
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
207
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
208
- *
209
- * @return SimpleXMLElement Node to which values are added
210
- */
211
- public function add_prime_node( $item, $aalb_node ) {
212
- if ( ! empty( $item->Offers->Offer->OfferListing->IsEligibleForPrime ) ) {
213
- $aalb_node = $this->add_xml_node( $aalb_node, 'Prime', $item->Offers->Offer->OfferListing->IsEligibleForPrime );
214
- }
215
-
216
- return $aalb_node;
217
- }
218
-
219
- /**
220
- * Adds Merchant node
221
- * Adds Merchant information inside the Merchant node
222
- *
223
- * @since 1.4.1
224
- *
225
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
226
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
227
- *
228
- * @return SimpleXMLElement Node to which values are added
229
- */
230
- public function add_merchant_node( $item, $aalb_node ) {
231
- if ( ! empty( $item->Offers->Offer->Merchant->Name ) ) {
232
- $aalb_node = $this->add_xml_node( $aalb_node, 'Merchant', $item->Offers->Offer->Merchant->Name );
233
- }
234
-
235
- return $aalb_node;
236
- }
237
-
238
- /**
239
- * Adds Current Price and Strike Price Nodes after applying logic
240
- * Logic for Current Price and Strike Price
241
- *
242
- * @since 1.0.0
243
- *
244
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
245
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
246
- *
247
- * @return SimpleXMLElement Node to which values are added
248
- */
249
- public function add_price_nodes( $item, $aalb_node ) {
250
- $list_price = isset( $item->ItemAttributes->ListPrice->FormattedPrice ) ? $item->ItemAttributes->ListPrice->FormattedPrice : null;
251
- $price = isset( $item->Offers->Offer->OfferListing->Price->FormattedPrice ) ? $item->Offers->Offer->OfferListing->Price->FormattedPrice : null;
252
- $sale_price = isset( $item->Offers->Offer->OfferListing->SalePrice->FormattedPrice ) ? $item->Offers->Offer->OfferListing->SalePrice->FormattedPrice : null;
253
- $list_price_amount = isset( $item->ItemAttributes->ListPrice->Amount ) ? $item->ItemAttributes->ListPrice->Amount : null;
254
- $price_amount = isset( $item->Offers->Offer->OfferListing->Price->Amount ) ? $item->Offers->Offer->OfferListing->Price->Amount : null;
255
- $sale_price_amount = isset( $item->Offers->Offer->OfferListing->SalePrice->Amount ) ? $item->Offers->Offer->OfferListing->SalePrice->Amount : null;
256
- if ( ! empty( $sale_price_amount ) ) {
257
- //If Sale Price is returned
258
- $aalb_node->CurrentPrice = $sale_price;
259
- $aalb_node->CurrentPriceValue = $sale_price_amount;
260
- if ( (int) $aalb_node->SavingPercent > 1 ) {
261
- $aalb_node->StrikePrice = $price;
262
- $aalb_node->StrikePriceValue = $price_amount;
263
- }
264
- } else {
265
- $aalb_node->CurrentPrice = $price;
266
- $aalb_node->CurrentPriceValue = $price_amount;
267
- if ( (int) $aalb_node->SavingPercent > 1 ) {
268
- $aalb_node->StrikePrice = $list_price;
269
- $aalb_node->StrikePriceValue = $list_price_amount;
270
- }
271
- }
272
-
273
- return $aalb_node;
274
- }
275
-
276
- /**
277
- * Adds InStock node if the item is in stock; Updates Current Price otherwise
278
- *
279
- * @since 1.0.0
280
- *
281
- * @param SimpleXMLElement $item Well formed XML String: The Parent item node
282
- * @param SimpleXMLElement $aalb_node Node to which values are to be added
283
- *
284
- * @oaram string $marketplace
285
- *
286
- * @return SimpleXMLElement Node to which values are added
287
- */
288
- public function add_out_of_stock_node( $item, $aalb_node, $marketplace ) {
289
- $total_new = isset( $item->OfferSummary->TotalNew ) ? $item->OfferSummary->TotalNew : null;
290
- $availability = isset( $item->Offers->Offer->OfferListing->Availability ) ? $item->Offers->Offer->OfferListing->Availability : null;
291
- if ( ( $total_new == '0' or $availability == "Out of Stock" ) ) {
292
- //If the item is out of stock, update Buying Price
293
- $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace( OUT_OF_STOCK, $marketplace );;
294
- } else {
295
- //If the item is in stock; add a xml node to identify values in stock
296
- $aalb_node->InStock = 'Yes True';
297
- }
298
-
299
- return $aalb_node;
300
- }
301
-
302
- /**
303
- * Adds Click URL Prefix to requierd hyperlinks
304
- * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
305
- *
306
- * @since 1.0.0
307
- *
308
- * @param SimpleXMLElement $items Well formed XML String
309
- *
310
- * @return SimpleXMLElement $items XML String with hyperlinks prefixed with click URL
311
- */
312
- public function prefix_click_URL( $items ) {
313
- foreach ( $items->Item as $item ) {
314
- $item->DetailPageURL = '[[CLICK_URL_PREFIX]]' . $item->DetailPageURL;
315
- }
316
-
317
- return $items;
318
- }
319
- }
320
-
321
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Helper class for customizations to the xml response
17
+ *
18
+ * @since 1.0.0
19
+ * @package AmazonAssociatesLinkBuilder
20
+ * @subpackage AmazonAssociatesLinkBuilder/lib/php
21
+ */
22
+ class Aalb_Xml_Helper {
23
+
24
+ protected $internationalization_helper;
25
+
26
+ public function __construct() {
27
+ $this->internationalization_helper = new Aalb_Internationalization_Helper();
28
+ }
29
+
30
+ /**
31
+ * Add custom nodes to xml response
32
+ *
33
+ * @since 1.0.0
34
+ *
35
+ * @param SimpleXMLElement $items Well-formed XML string
36
+ *
37
+ * @return SimpleXMLElement $items XML String with custom nodes added
38
+ */
39
+ public function add_custom_nodes( $items, $marketplace ) {
40
+ $common_marketplace_node_name = 'Marketplace' . $marketplace;
41
+ $items->ID = "[[UNIQUE_ID]]";
42
+
43
+ //add aalb nodes needed for each item
44
+ foreach ( $items->Item as $item ) {
45
+ $aalb_node = $item->addChild( 'aalb' );
46
+
47
+ $aalb_node->ASIN = isset( $item->ASIN ) ? $item->ASIN : null;
48
+ $aalb_node->Title = isset( $item->ItemAttributes->Title ) ? $item->ItemAttributes->Title : null;
49
+ $aalb_node->DetailPageURL = isset( $item->DetailPageURL ) ? $item->DetailPageURL : null;
50
+ $aalb_node->LargeImageURL = isset( $item->LargeImage->URL ) ? $item->LargeImage->URL : null;
51
+ $aalb_node->MediumImageURL = isset( $item->MediumImage->URL ) ? $item->MediumImage->URL : null;
52
+ $aalb_node->SmallImageURL = isset( $item->MediumImage->URL ) ? $item->SmallImage->URL : null;
53
+
54
+ //Marketplace
55
+ $marketplace_node_name = $common_marketplace_node_name;
56
+ $aalb_node = $this->add_xml_node( $aalb_node, $marketplace_node_name, 'true' );
57
+
58
+ //By Information
59
+ $aalb_node = $this->add_by_information_node( $item, $aalb_node );
60
+
61
+ //Savings
62
+ $aalb_node = $this->add_savings_node( $item, $aalb_node );
63
+
64
+ //MinimumPrice
65
+ $aalb_node = $this->add_min_price_node( $item, $aalb_node );
66
+
67
+ //Prime
68
+ $aalb_node = $this->add_prime_node( $item, $aalb_node );
69
+
70
+ //Merchant Name
71
+ $aalb_node = $this->add_merchant_node( $item, $aalb_node );
72
+
73
+ //Current and Strike Price
74
+ $aalb_node = $this->add_price_nodes( $item, $aalb_node );
75
+
76
+
77
+ //Node to check "out of stock" items
78
+ $aalb_node = $this->add_out_of_stock_node( $item, $aalb_node, $marketplace );
79
+
80
+
81
+ //If the Buying Price is empty or if is is Too Low to Display
82
+ if ( empty( $aalb_node->CurrentPrice ) or strtolower( $aalb_node->CurrentPrice ) == 'too low to display' ) {
83
+ $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace( CHECK_ON_AMAZON, $marketplace );
84
+ }
85
+ }
86
+
87
+ //add common aalb nodes
88
+ $aalb_common_node = $items->addChild( 'AalbHeader' );
89
+ $aalb_common_node = $this->add_xml_node( $aalb_common_node, $common_marketplace_node_name, 'true' );
90
+
91
+ return $items;
92
+ }
93
+
94
+ /**
95
+ * Adds a child xml node to a given parent node if the value is not empty.
96
+ *
97
+ * @since 1.0.0
98
+ *
99
+ * @param SimpleXMLElement $parent_node PHP XML Object of parent node
100
+ * @param string $node_name Name of the new node to be added
101
+ * @param string $node_value Value of the new node to be added
102
+ *
103
+ * @return SimpleXMLElement $parent_node Parent node with added child node
104
+ */
105
+ public function add_xml_node( $parent_node, $node_name, $node_value ) {
106
+ if ( ! empty( $node_value ) ) {
107
+ $parent_node->$node_name = $node_value;
108
+ }
109
+
110
+ return $parent_node;
111
+ }
112
+
113
+ /**
114
+ * Adds By Information Node
115
+ * And separated list of all artists, brands and authors
116
+ *
117
+ * @since 1.0.0
118
+ *
119
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
120
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
121
+ *
122
+ * @return SimpleXMLElement Modified aalb_node
123
+ */
124
+ public function add_by_information_node( $item, $aalb_node ) {
125
+ $author_array = array();
126
+ $brand_array = array();
127
+ $artist_array = array();
128
+ $by_information = array();
129
+ foreach ( $item->ItemAttributes->Author as $author ) {
130
+ array_push( $author_array, $author );
131
+ }
132
+ foreach ( $item->ItemAttributes->Brand as $brand ) {
133
+ array_push( $brand_array, $brand );
134
+ }
135
+ foreach ( $item->ItemAttributes->Artist as $artist ) {
136
+ array_push( $artist_array, $artist );
137
+ }
138
+ if ( ! empty( $author_array ) ) {
139
+ array_push( $by_information, implode( ', ', $author_array ) );
140
+ }
141
+ if ( ! empty( $brand_array ) ) {
142
+ array_push( $by_information, implode( ', ', $brand_array ) );
143
+ }
144
+ if ( ! empty( $artist_array ) ) {
145
+ array_push( $by_information, implode( ', ', $artist_array ) );
146
+ }
147
+ $aalb_node->By = implode( ' and ', $by_information );
148
+
149
+ return $aalb_node;
150
+ }
151
+
152
+ /**
153
+ * Adds Savings related nodes
154
+ * Adds Amount saved in both raw and formatted way and the percentage saved.
155
+ * Savings node are added only if we get saving nodes in the XML response from PAAPI.
156
+ *
157
+ * @since 1.0.0
158
+ *
159
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
160
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
161
+ *
162
+ * @return SimpleXMLElement Node to which values are added
163
+ */
164
+ public function add_savings_node( $item, $aalb_node ) {
165
+ if ( ! empty( $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice ) ) {
166
+ $aalb_node = $this->add_xml_node( $aalb_node, 'Saving', $item->Offers->Offer->OfferListing->AmountSaved->FormattedPrice );
167
+ }
168
+ if ( ! empty( $item->Offers->Offer->OfferListing->AmountSaved->Amount ) ) {
169
+ $aalb_node = $this->add_xml_node( $aalb_node, 'SavingValue', $item->Offers->Offer->OfferListing->AmountSaved->Amount );
170
+ }
171
+ if ( ! empty( $item->Offers->Offer->OfferListing->PercentageSaved ) ) {
172
+ $aalb_node = $this->add_xml_node( $aalb_node, 'SavingPercent', $item->Offers->Offer->OfferListing->PercentageSaved );
173
+ }
174
+
175
+ return $aalb_node;
176
+ }
177
+
178
+ /**
179
+ * Adds Minimum Price related nodes
180
+ * Adds raw and formatted values of minimum price
181
+ *
182
+ * @since 1.0.0
183
+ *
184
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
185
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
186
+ *
187
+ * @return SimpleXMLElement Node to which values are added
188
+ */
189
+ public function add_min_price_node( $item, $aalb_node ) {
190
+ if ( ! empty( $item->OfferSummary->LowestNewPrice->FormattedPrice ) ) {
191
+ $aalb_node = $this->add_xml_node( $aalb_node, 'MinimumPrice', $item->OfferSummary->LowestNewPrice->FormattedPrice );
192
+ }
193
+ if ( ! empty( $item->OfferSummary->LowestNewPrice->Amount ) ) {
194
+ $aalb_node = $this->add_xml_node( $aalb_node, 'MinimumPriceValue', $item->OfferSummary->LowestNewPrice->Amount );
195
+ }
196
+
197
+ return $aalb_node;
198
+ }
199
+
200
+ /**
201
+ * Adds Prime node
202
+ * Adds Prime node if the item is eligible for prime
203
+ *
204
+ * @since 1.4.1
205
+ *
206
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
207
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
208
+ *
209
+ * @return SimpleXMLElement Node to which values are added
210
+ */
211
+ public function add_prime_node( $item, $aalb_node ) {
212
+ if ( ! empty( $item->Offers->Offer->OfferListing->IsEligibleForPrime ) ) {
213
+ $aalb_node = $this->add_xml_node( $aalb_node, 'Prime', $item->Offers->Offer->OfferListing->IsEligibleForPrime );
214
+ }
215
+
216
+ return $aalb_node;
217
+ }
218
+
219
+ /**
220
+ * Adds Merchant node
221
+ * Adds Merchant information inside the Merchant node
222
+ *
223
+ * @since 1.4.1
224
+ *
225
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
226
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
227
+ *
228
+ * @return SimpleXMLElement Node to which values are added
229
+ */
230
+ public function add_merchant_node( $item, $aalb_node ) {
231
+ if ( ! empty( $item->Offers->Offer->Merchant->Name ) ) {
232
+ $aalb_node = $this->add_xml_node( $aalb_node, 'Merchant', $item->Offers->Offer->Merchant->Name );
233
+ }
234
+
235
+ return $aalb_node;
236
+ }
237
+
238
+ /**
239
+ * Adds Current Price and Strike Price Nodes after applying logic
240
+ * Logic for Current Price and Strike Price
241
+ *
242
+ * @since 1.0.0
243
+ *
244
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
245
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
246
+ *
247
+ * @return SimpleXMLElement Node to which values are added
248
+ */
249
+ public function add_price_nodes( $item, $aalb_node ) {
250
+ $list_price = isset( $item->ItemAttributes->ListPrice->FormattedPrice ) ? $item->ItemAttributes->ListPrice->FormattedPrice : null;
251
+ $price = isset( $item->Offers->Offer->OfferListing->Price->FormattedPrice ) ? $item->Offers->Offer->OfferListing->Price->FormattedPrice : null;
252
+ $sale_price = isset( $item->Offers->Offer->OfferListing->SalePrice->FormattedPrice ) ? $item->Offers->Offer->OfferListing->SalePrice->FormattedPrice : null;
253
+ $list_price_amount = isset( $item->ItemAttributes->ListPrice->Amount ) ? $item->ItemAttributes->ListPrice->Amount : null;
254
+ $price_amount = isset( $item->Offers->Offer->OfferListing->Price->Amount ) ? $item->Offers->Offer->OfferListing->Price->Amount : null;
255
+ $sale_price_amount = isset( $item->Offers->Offer->OfferListing->SalePrice->Amount ) ? $item->Offers->Offer->OfferListing->SalePrice->Amount : null;
256
+ if ( ! empty( $sale_price_amount ) ) {
257
+ //If Sale Price is returned
258
+ $aalb_node->CurrentPrice = $sale_price;
259
+ $aalb_node->CurrentPriceValue = $sale_price_amount;
260
+ if ( (int) $aalb_node->SavingPercent > 1 ) {
261
+ $aalb_node->StrikePrice = $price;
262
+ $aalb_node->StrikePriceValue = $price_amount;
263
+ }
264
+ } else {
265
+ $aalb_node->CurrentPrice = $price;
266
+ $aalb_node->CurrentPriceValue = $price_amount;
267
+ if ( (int) $aalb_node->SavingPercent > 1 ) {
268
+ $aalb_node->StrikePrice = $list_price;
269
+ $aalb_node->StrikePriceValue = $list_price_amount;
270
+ }
271
+ }
272
+
273
+ return $aalb_node;
274
+ }
275
+
276
+ /**
277
+ * Adds InStock node if the item is in stock; Updates Current Price otherwise
278
+ *
279
+ * @since 1.0.0
280
+ *
281
+ * @param SimpleXMLElement $item Well formed XML String: The Parent item node
282
+ * @param SimpleXMLElement $aalb_node Node to which values are to be added
283
+ *
284
+ * @oaram string $marketplace
285
+ *
286
+ * @return SimpleXMLElement Node to which values are added
287
+ */
288
+ public function add_out_of_stock_node( $item, $aalb_node, $marketplace ) {
289
+ $total_new = isset( $item->OfferSummary->TotalNew ) ? $item->OfferSummary->TotalNew : null;
290
+ $availability = isset( $item->Offers->Offer->OfferListing->Availability ) ? $item->Offers->Offer->OfferListing->Availability : null;
291
+ if ( ( $total_new == '0' or $availability == "Out of Stock" ) ) {
292
+ //If the item is out of stock, update Buying Price
293
+ $aalb_node->CurrentPrice = $this->internationalization_helper->internationalize_by_marketplace( OUT_OF_STOCK, $marketplace );;
294
+ } else {
295
+ //If the item is in stock; add a xml node to identify values in stock
296
+ $aalb_node->InStock = 'Yes True';
297
+ }
298
+
299
+ return $aalb_node;
300
+ }
301
+
302
+ /**
303
+ * Adds Click URL Prefix to requierd hyperlinks
304
+ * TODO: Not used post v1.4. Impression Tracking plugged out for re-vamping purposes.
305
+ *
306
+ * @since 1.0.0
307
+ *
308
+ * @param SimpleXMLElement $items Well formed XML String
309
+ *
310
+ * @return SimpleXMLElement $items XML String with hyperlinks prefixed with click URL
311
+ */
312
+ public function prefix_click_URL( $items ) {
313
+ foreach ( $items->Item as $item ) {
314
+ $item->DetailPageURL = '[[CLICK_URL_PREFIX]]' . $item->DetailPageURL;
315
+ }
316
+
317
+ return $items;
318
+ }
319
+ }
320
+
321
+ ?>
readme.txt CHANGED
@@ -1,154 +1,159 @@
1
- === Amazon Associates Link Builder ===
2
- Contributors: amazonlinkbuilder
3
- Tags: Amazon, Affiliate, Associates, Amazon Associates, Amazon Associate, Product Advertising API, Amazon API, Amazon Link, Amazon Ad, Amazon Affiliate, eCommerce
4
- Requires at least: 3.0.1
5
- Tested up to: 4.7.3
6
- Stable tag: 1.4.2
7
- License: GPLv2
8
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
-
10
- The official plugin from the Amazon Associates Program.
11
-
12
- == Description ==
13
- = About Amazon Associates Program =
14
- The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies across the globe, the Amazon Associates Program has been partnering with content creators to help them monetize their passions since 1996. To learn more about the Amazon Associates Program, please click [here](https://affiliate-program.amazon.com/).
15
-
16
- = About Amazon Associates Link Builder =
17
- Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to search for products in the Amazon catalog, access real-time price and availability information, and easily create links in your posts to products on Amazon.com. You will be able to generate text links, create custom ad units, or take advantage of out-of-the-box widgets that we've designed and included with the plugin.
18
-
19
- = Note =
20
- * You must review and accept the Amazon Associates Link Builder [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf).
21
- * The plugin is currently in beta form. We intend to regularly add new features and enhancements throughout the beta period and beyond, and welcome your feedback and input.
22
-
23
- == Installation ==
24
-
25
- = Pre-requisites =
26
- __Requires PHP Version:__ 5.3 or higher
27
- <br />
28
-
29
- __Requires WordPress Version:__ 3.0.1 or higher
30
- <br />
31
-
32
- __Become an Associate__ <br />
33
- To become an Associate, create an Amazon Associates account using URL for your country: [Brazil](https://associados.amazon.com.br/), [Canada](https://associates.amazon.ca/), [China](https://associates.amazon.cn/), [France](https://partenaires.amazon.fr/), [Germany](http://partnernet.amazon.de/), [India](https://affiliate-program.amazon.in/), [Italy](https://programma-affiliazione.amazon.it/), [Japan](https://affiliate.amazon.co.jp/), [Mexico](https://afiliados.amazon.com.mx/), [Spain](https://afiliados.amazon.es/), [United Kingdom](https://affiliate-program.amazon.co.uk/), [United States](http://affiliate-program.amazon.com/)
34
- <br />
35
- Your Associate ID works only in the country in which you register. If you'd like to be an Associate in more than one country, please register separately for each country.
36
- <br />
37
-
38
- __Sign up for Product Advertising API__ <br />
39
- Sign up for the Amazon Product Advertising API by following the instructions listed [here](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html). The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences around the world, serving tens of thousands of applications and more than 1 billion API requests every day. It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access Amazon.com product catalog data without requiring additional software development.
40
-
41
- = Installing =
42
- To install the Amazon Associates Link Builder plugin: <br />
43
- 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New. <br />
44
- 2. In the search field type **Amazon Associates Link Builder** and click Search Plugins. You can install it by simply clicking **Install Now**.
45
-
46
- = Updating =
47
- Automatic updates should work like a charm. That said, it's always good practice to back up your templates just in case.
48
-
49
- = User Guide =
50
- You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin.
51
-
52
- = Configure plugin for first use =
53
- Use the Associates Link Builder->Settings screen to configure the plugin. <br />
54
- 1. Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke requests to the Amazon Product Advertising API for fetching information on an item. <br />
55
- 2. Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon. You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new tracking ID in your Amazon Associates account for using it as Associate ID in the plugin. <br />
56
- 3. Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered (for example, if you've signed up for the Amazon Associates Program in UK, then your default marketplace selection should be UK) and select an appropriate template for rendering your ads.
57
-
58
- <br />
59
- That's it! You're all set to start adding Amazon affiliate links to your posts using the Amazon Associates Link Builder plugin!
60
-
61
- = Support =
62
- If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder plugin forum](https://wordpress.org/support/plugin/amazon-link-builder).
63
-
64
- == Screenshots ==
65
- 1. Amazon Associates Link Builder settings console
66
- 2. Search for products in Amazon catalog directly from the WordPress toolbar while creating a new post or a page
67
- 3. Select the products you would like to advertise
68
- 4. Associate a template and Associates Id to your links
69
- 5. Product Carousel Template: Stylishly designed and responsive ad unit that automatically adapts for different device types and screen resolutions that can be placed within or at the end of your content
70
- 6. Product Ad Template: A variation of the product carousel template for advertising one product at a time
71
- 7. Product Grid Template: Another variation of the product carousel template that can be used to display a grid of products alongside your content
72
- 8. Price Link Template: Dynamic hyperlink containing the current price offered for buying the item on Amazon
73
- 9. Create custom ad templates native to your site' styling
74
-
75
- == Frequently Asked Questions ==
76
-
77
- = Where can I find more information on the Amazon Associates Program? =
78
- You can find more information on the Amazon Associates Program at [Amazon Associates Help](https://affiliate-program.amazon.com/help/node).
79
-
80
- = How does the plugin work? =
81
- The plugin makes real-time calls to the Amazon Product Advertising API to search for, and look up information on, items in Amazon.com's product catalog. Security credentials provided in the Settings console are used for signing API requests. The plugin also contains an in-build caching mechanism to cache the API results for optimizing the API usage and reducing the loading time of the link content.
82
-
83
- = Can I track the performance of the ad units created using the plugin? =
84
- Yes. You can track the performance of the ad unit by placement or section of your website by using tracking ids. You are recommended to use different tracking ids for different ad templates. This will allow you to track orders and earnings information for each type of ad using the reports section in Associates Central. You can create tracking ids [here](https://affiliate-program.amazon.com/home/account/tag/manage).
85
-
86
- = What information is shared with Amazon? =
87
- Information we learn from Amazon Associates Link Builder users helps us to evaluate performance of the plugin, troubleshoot technical issues, and generally improve the plugin. We only capture information on impressions, clicks, and sales for Amazon affiliate links in accordance with the [Amazon.com Privacy Notice](https://www.amazon.com/gp/help/customer/display.html?nodeId=468496).
88
-
89
- = Where can I find support? =
90
- You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin. If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder Plugin Forum](https://wordpress.org/support/plugin/amazon-associates-link-builder).
91
-
92
- = How can I add links to different Amazon sites in my blog? =
93
- You can search products using keywords in any supported country, but you have to join the Associates Program in those countries separately to be able to do this. For example - If you are a blogger in UK interested in linking to Amazon.com (US) site, then you will first need to join the Amazon Associates Program in US to be able to search for products on Amazon.com site.
94
-
95
- == Changelog ==
96
-
97
- = 1.4.2 - March 30, 2017 =
98
- * Changes to ensure minimum PHP version requirements are met before plugin activation.
99
- * Fix: Amazon search text box and button not showing for editors like Site Origin Page Builder and Advanced Custom Fields.
100
-
101
- = 1.4.1 - February 23, 2017 =
102
- * Updated error messages to provide more detailed information on how to troubleshoot errors
103
- * Fix: Amazon search button not working in text mode.
104
- * Fix: Amazon logo size with other plugin editors
105
- * Fix: Problem with shortcode creation modal dialog hanging in some cases.
106
- * Fix: General fixes to remove PHP notices.
107
-
108
- = 1.4 - January 18, 2017 =
109
- * Conditions of Use have been updated with a worldwide version. Please review the updated [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf) for the terms which are applicable to your use.
110
- * Enhancement: Now, you can create text links to Amazon products using amazon_textlink short code. Check [reference guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateTextLinks.pdf) for more details.
111
- * Fix: Display Amazon [buy box](https://www.amazon.com/gp/help/customer/display.html?nodeId=200401830) price.
112
- * General improvements to reduce the loading time of the links/ ad units created via the plugin.
113
- * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
114
-
115
- = 1.3.2 - December 30, 2016 =
116
- * If you are coming from any version other than v1.3 and are using custom templates, be sure to backup your custom templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template or if you are coming from v1.3, you can simply update the plugin using the update now link.
117
- * Fix: Problems with rendering ads when using custom templates.
118
-
119
- = 1.3 - December 27, 2016 =
120
- * If you have created custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template, you can simply update the plugin using the update now link.
121
- * Fix: Preserve custom templates with plugin updates. You will no longer need to back up your custom templates when updating the plugin in future.
122
- * Fix: Update tracking pixel to display:none.
123
- * Fix: Remove ! from PriceLink template.
124
- * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
125
-
126
-
127
- = 1.2 - December 19, 2016 =
128
- * If you have created custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template, you can simply update the plugin using the update now link.
129
- * Fix: Array dereference issue with PHP version 5.3. You will no longer get PHP syntax issues while activating the plugin.
130
- * Administration of the plugin over a secured network (HTTPS) is recommended and not required.
131
- * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
132
-
133
- = 1.1 - December 13, 2016 =
134
- * Fix: Rendering of search results in Apple Safari browser.
135
-
136
- = 1.0 - December 6, 2016 =
137
- * Plugin released for beta testing
138
-
139
- == Upgrade Notice ==
140
-
141
- = 1.4.2 =
142
- This update restricts plugin activation to supported PHP versions, and fixes bug of plugin not working with other editors.
143
-
144
- = 1.4.1 =
145
- This update includes minor bug fixes.
146
-
147
- = 1.4 =
148
- This update includes general performance improvements, and support for text links.
149
-
150
- = 1.3.2 =
151
- This update fixes the issue with improper rendering of ads using custom templates. If you are coming from v1.3, you don't need to take a backup of your templates before updating to v1.3.2.
152
-
153
- = 1.3 =
 
 
 
 
 
154
  This update includes a few minor fixes. In particular, you will no longer need to back up your custom templates when updating the plugin in future.
1
+ === Amazon Associates Link Builder ===
2
+ Contributors: amazonlinkbuilder
3
+ Tags: Amazon, Affiliate, Associates, Amazon Associates, Amazon Associate, Product Advertising API, Amazon API, Amazon Link, Amazon Ad, Amazon Affiliate, eCommerce
4
+ Requires at least: 3.0.1
5
+ Tested up to: 4.7.3
6
+ Stable tag: 1.4.3
7
+ License: GPLv2
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ The official plugin from the Amazon Associates Program.
11
+
12
+ == Description ==
13
+ = About Amazon Associates Program =
14
+ The Amazon Associates Program is one of the original affiliate marketing programs. Available in geographies across the globe, the Amazon Associates Program has been partnering with content creators to help them monetize their passions since 1996. To learn more about the Amazon Associates Program, please click [here](https://affiliate-program.amazon.com/).
15
+
16
+ = About Amazon Associates Link Builder =
17
+ Link Builder is the official free Amazon Associates Program plugin for WordPress. The plugin enables you to search for products in the Amazon catalog, access real-time price and availability information, and easily create links in your posts to products on Amazon.com. You will be able to generate text links, create custom ad units, or take advantage of out-of-the-box widgets that we've designed and included with the plugin.
18
+
19
+ = Note =
20
+ * You must review and accept the Amazon Associates Link Builder [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf).
21
+ * The plugin is currently in beta form. We intend to regularly add new features and enhancements throughout the beta period and beyond, and welcome your feedback and input.
22
+
23
+ == Installation ==
24
+
25
+ = Pre-requisites =
26
+ __Requires PHP Version:__ 5.3 or higher
27
+ <br />
28
+
29
+ __Requires WordPress Version:__ 3.0.1 or higher
30
+ <br />
31
+
32
+ __Become an Associate__ <br />
33
+ To become an Associate, create an Amazon Associates account using URL for your country: [Brazil](https://associados.amazon.com.br/), [Canada](https://associates.amazon.ca/), [China](https://associates.amazon.cn/), [France](https://partenaires.amazon.fr/), [Germany](http://partnernet.amazon.de/), [India](https://affiliate-program.amazon.in/), [Italy](https://programma-affiliazione.amazon.it/), [Japan](https://affiliate.amazon.co.jp/), [Mexico](https://afiliados.amazon.com.mx/), [Spain](https://afiliados.amazon.es/), [United Kingdom](https://affiliate-program.amazon.co.uk/), [United States](http://affiliate-program.amazon.com/)
34
+ <br />
35
+ Your Associate ID works only in the country in which you register. If you'd like to be an Associate in more than one country, please register separately for each country.
36
+ <br />
37
+
38
+ __Sign up for Product Advertising API__ <br />
39
+ Sign up for the Amazon Product Advertising API by following the instructions listed [here](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_GettingStarted.html). The Amazon Product Advertising API is a popular e-commerce service, powering Amazon-integrated experiences around the world, serving tens of thousands of applications and more than 1 billion API requests every day. It exposes a web-service, which allows Associates to programmatically search and look up items in the Amazon product catalog. The Link Builder plugin integrates the Product Advertising API, allowing you to access Amazon.com product catalog data without requiring additional software development.
40
+
41
+ = Installing =
42
+ To install the Amazon Associates Link Builder plugin: <br />
43
+ 1. Log in to your WordPress dashboard, navigate to the Plugins menu and click Add New. <br />
44
+ 2. In the search field type **Amazon Associates Link Builder** and click Search Plugins. You can install it by simply clicking **Install Now**.
45
+
46
+ = Updating =
47
+ Automatic updates should work like a charm. That said, it's always good practice to back up your templates just in case.
48
+
49
+ = User Guide =
50
+ You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin.
51
+
52
+ = Configure plugin for first use =
53
+ Use the Associates Link Builder->Settings screen to configure the plugin. <br />
54
+ 1. Set Access Key ID and Secret Access Key in the Settings section. These credentials are used to invoke requests to the Amazon Product Advertising API for fetching information on an item. <br />
55
+ 2. Set default Associate ID. Associate ID is used to monitor traffic and sales from your links to Amazon. You can also define a list of valid Associate IDs (store ids or tracking ids). You should create a new tracking ID in your Amazon Associates account for using it as Associate ID in the plugin. <br />
56
+ 3. Set the default Amazon marketplace based on the Amazon Associates Program for which you are registered (for example, if you've signed up for the Amazon Associates Program in UK, then your default marketplace selection should be UK) and select an appropriate template for rendering your ads.
57
+
58
+ <br />
59
+ That's it! You're all set to start adding Amazon affiliate links to your posts using the Amazon Associates Link Builder plugin!
60
+
61
+ = Support =
62
+ If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder plugin forum](https://wordpress.org/support/plugin/amazon-link-builder).
63
+
64
+ == Screenshots ==
65
+ 1. Amazon Associates Link Builder settings console
66
+ 2. Search for products in Amazon catalog directly from the WordPress toolbar while creating a new post or a page
67
+ 3. Select the products you would like to advertise
68
+ 4. Associate a template and Associates Id to your links
69
+ 5. Product Carousel Template: Stylishly designed and responsive ad unit that automatically adapts for different device types and screen resolutions that can be placed within or at the end of your content
70
+ 6. Product Ad Template: A variation of the product carousel template for advertising one product at a time
71
+ 7. Product Grid Template: Another variation of the product carousel template that can be used to display a grid of products alongside your content
72
+ 8. Price Link Template: Dynamic hyperlink containing the current price offered for buying the item on Amazon
73
+ 9. Create custom ad templates native to your site' styling
74
+
75
+ == Frequently Asked Questions ==
76
+
77
+ = Where can I find more information on the Amazon Associates Program? =
78
+ You can find more information on the Amazon Associates Program at [Amazon Associates Help](https://affiliate-program.amazon.com/help/node).
79
+
80
+ = How does the plugin work? =
81
+ The plugin makes real-time calls to the Amazon Product Advertising API to search for, and look up information on, items in Amazon.com's product catalog. Security credentials provided in the Settings console are used for signing API requests. The plugin also contains an in-build caching mechanism to cache the API results for optimizing the API usage and reducing the loading time of the link content.
82
+
83
+ = Can I track the performance of the ad units created using the plugin? =
84
+ Yes. You can track the performance of the ad unit by placement or section of your website by using tracking ids. You are recommended to use different tracking ids for different ad templates. This will allow you to track orders and earnings information for each type of ad using the reports section in Associates Central. You can create tracking ids [here](https://affiliate-program.amazon.com/home/account/tag/manage).
85
+
86
+ = What information is shared with Amazon? =
87
+ Information we learn from Amazon Associates Link Builder users helps us to evaluate performance of the plugin, troubleshoot technical issues, and generally improve the plugin. We only capture information on impressions, clicks, and sales for Amazon affiliate links in accordance with the [Amazon.com Privacy Notice](https://www.amazon.com/gp/help/customer/display.html?nodeId=468496).
88
+
89
+ = Where can I find support? =
90
+ You can review the **About** section under the Associates Link Builder menu bar or [Link Builder User Guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf) for more information on getting started and key features of the plugin. If you get stuck, or have any questions, you can ask for help in the [Amazon Associates Link Builder Plugin Forum](https://wordpress.org/support/plugin/amazon-associates-link-builder).
91
+
92
+ = How can I add links to different Amazon sites in my blog? =
93
+ You can search products using keywords in any supported country, but you have to join the Associates Program in those countries separately to be able to do this. For example - If you are a blogger in UK interested in linking to Amazon.com (US) site, then you will first need to join the Amazon Associates Program in US to be able to search for products on Amazon.com site.
94
+
95
+ == Changelog ==
96
+
97
+ = 1.4.3 - April 19, 2017 =
98
+ * Fix: Add shortcode button not clickable for some users after version 1.4.2.
99
+
100
+ = 1.4.2 - March 30, 2017 =
101
+ * Changes to ensure minimum PHP version requirements are met before plugin activation.
102
+ * Fix: Amazon search text box and button not showing for editors like Site Origin Page Builder and Advanced Custom Fields.
103
+
104
+ = 1.4.1 - February 23, 2017 =
105
+ * Updated error messages to provide more detailed information on how to troubleshoot errors
106
+ * Fix: Amazon search button not working in text mode.
107
+ * Fix: Amazon logo size with other plugin editors
108
+ * Fix: Problem with shortcode creation modal dialog hanging in some cases.
109
+ * Fix: General fixes to remove PHP notices.
110
+
111
+ = 1.4 - January 18, 2017 =
112
+ * Conditions of Use have been updated with a worldwide version. Please review the updated [Conditions of Use](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-ConditionsOfUse-2017-01-17.pdf) for the terms which are applicable to your use.
113
+ * Enhancement: Now, you can create text links to Amazon products using amazon_textlink short code. Check [reference guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToCreateTextLinks.pdf) for more details.
114
+ * Fix: Display Amazon [buy box](https://www.amazon.com/gp/help/customer/display.html?nodeId=200401830) price.
115
+ * General improvements to reduce the loading time of the links/ ad units created via the plugin.
116
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
117
+
118
+ = 1.3.2 - December 30, 2016 =
119
+ * If you are coming from any version other than v1.3 and are using custom templates, be sure to backup your custom templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template or if you are coming from v1.3, you can simply update the plugin using the update now link.
120
+ * Fix: Problems with rendering ads when using custom templates.
121
+
122
+ = 1.3 - December 27, 2016 =
123
+ * If you have created custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template, you can simply update the plugin using the update now link.
124
+ * Fix: Preserve custom templates with plugin updates. You will no longer need to back up your custom templates when updating the plugin in future.
125
+ * Fix: Update tracking pixel to display:none.
126
+ * Fix: Remove ! from PriceLink template.
127
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
128
+
129
+
130
+ = 1.2 - December 19, 2016 =
131
+ * If you have created custom templates, be sure to take a backup of your templates before updating the plugin by following [these instructions](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-Guide-HowToBackupCustomTemplates.pdf). If you have not created any custom template, you can simply update the plugin using the update now link.
132
+ * Fix: Array dereference issue with PHP version 5.3. You will no longer get PHP syntax issues while activating the plugin.
133
+ * Administration of the plugin over a secured network (HTTPS) is recommended and not required.
134
+ * Updated [plugin user guide](https://s3.amazonaws.com/aalb-public-resources/documents/AssociatesLinkBuilder-UserGuide.pdf).
135
+
136
+ = 1.1 - December 13, 2016 =
137
+ * Fix: Rendering of search results in Apple Safari browser.
138
+
139
+ = 1.0 - December 6, 2016 =
140
+ * Plugin released for beta testing
141
+
142
+ == Upgrade Notice ==
143
+ = 1.4.3 =
144
+ This update fixes the issue of add shortcode button not clickable for some users after v1.4.2.
145
+
146
+ = 1.4.2 =
147
+ This update restricts plugin activation to supported PHP versions, and fixes bug of plugin not working with other editors.
148
+
149
+ = 1.4.1 =
150
+ This update includes minor bug fixes.
151
+
152
+ = 1.4 =
153
+ This update includes general performance improvements, and support for text links.
154
+
155
+ = 1.3.2 =
156
+ This update fixes the issue with improper rendering of ads using custom templates. If you are coming from v1.3, you don't need to take a backup of your templates before updating to v1.3.2.
157
+
158
+ = 1.3 =
159
  This update includes a few minor fixes. In particular, you will no longer need to back up your custom templates when updating the plugin in future.
shortcode/aalb_shortcode.php CHANGED
@@ -1,104 +1,104 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Fired when a amazon_link shortcode is there in the post page.
17
- *
18
- * Gets the product information by making a Paapi request and renders the HTML
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
- */
24
- class Aalb_Shortcode {
25
- protected $paapi_helper;
26
- protected $template_engine;
27
- protected $helper;
28
- protected $tracking_api_helper;
29
- protected $shortcode_helper;
30
-
31
- public function __construct() {
32
- $this->template_engine = new Aalb_Template_Engine();
33
- $this->paapi_helper = new Aalb_Paapi_Helper();
34
- $this->helper = new Aalb_Helper();
35
- $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
36
- $this->shortcode_helper = new Aalb_Shortcode_Helper();
37
- }
38
-
39
- /**
40
- * Add basic styles
41
- *
42
- * @since 1.0.0
43
- */
44
- public function enqueue_styles() {
45
- wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
46
- }
47
-
48
- /**
49
- * The function responsible for rendering the shortcode.
50
- * Makes a GET request and calls the render_xml to render the response.
51
- *
52
- * @since 1.0.0
53
- *
54
- * @param array $atts Shortcode attribute and values.
55
- *
56
- * @return HTML Rendered html to display.
57
- */
58
- public function render( $atts ) {
59
- try {
60
- $shortcode_attributes = $this->get_shortcode_attributes( $atts );
61
-
62
- $validated_link_id = $this->shortcode_helper->get_validated_link_id( $shortcode_attributes['link_id'] );
63
- $validated_marketplace = $this->shortcode_helper->get_validated_marketplace( $shortcode_attributes['marketplace'] );
64
- $validated_asins = $this->shortcode_helper->get_validated_asins( $shortcode_attributes['asins'] );
65
- $validated_template = $this->shortcode_helper->get_validated_template( $shortcode_attributes['template'] );
66
- $validated_store_id = $this->shortcode_helper->get_validated_store_id( $shortcode_attributes['store'] );
67
-
68
- $marketplace = $this->shortcode_helper->get_marketplace_endpoint( $validated_marketplace );
69
- $url = $this->paapi_helper->get_item_lookup_url( $validated_asins, $marketplace, $validated_store_id );
70
- $asins = $this->shortcode_helper->format_asins( $validated_asins );
71
- $products_key = $this->helper->build_products_cache_key( $asins, $marketplace, $validated_store_id );
72
- $products_template_key = $this->helper->build_template_cache_key( $asins, $marketplace, $validated_store_id, $validated_template );
73
-
74
- $this->shortcode_helper->enqueue_template_styles( $validated_template );
75
-
76
- return str_replace( array( '[[UNIQUE_ID]]' ), array( str_replace( '.', '-', $products_template_key ) ), $this->template_engine->render( $products_template_key, $products_key, $validated_template, $url, $validated_marketplace ) );
77
- } catch ( Exception $e ) {
78
- error_log( $this->paapi_helper->get_error_message( $e->getMessage() ) );
79
- }
80
- }
81
-
82
- /**
83
- * Returns default shortcode attributes if not mentioned
84
- *
85
- * @since 1.0.0
86
- *
87
- * @param array $atts Shortcode attributes.
88
- *
89
- * @return array Default shortcode attributes if not mentioned.
90
- */
91
- private function get_shortcode_attributes( $atts ) {
92
- $shortcode_attributes = shortcode_atts( array(
93
- 'asins' => null,
94
- 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ),
95
- 'store' => get_option( AALB_DEFAULT_STORE_ID ),
96
- 'template' => get_option( AALB_DEFAULT_TEMPLATE ),
97
- 'link_id' => null
98
- ), $atts );
99
-
100
- return $shortcode_attributes;
101
- }
102
- }
103
-
104
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Fired when a amazon_link shortcode is there in the post page.
17
+ *
18
+ * Gets the product information by making a Paapi request and renders the HTML
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
+ */
24
+ class Aalb_Shortcode {
25
+ protected $paapi_helper;
26
+ protected $template_engine;
27
+ protected $helper;
28
+ protected $tracking_api_helper;
29
+ protected $shortcode_helper;
30
+
31
+ public function __construct() {
32
+ $this->template_engine = new Aalb_Template_Engine();
33
+ $this->paapi_helper = new Aalb_Paapi_Helper();
34
+ $this->helper = new Aalb_Helper();
35
+ $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
36
+ $this->shortcode_helper = new Aalb_Shortcode_Helper();
37
+ }
38
+
39
+ /**
40
+ * Add basic styles
41
+ *
42
+ * @since 1.0.0
43
+ */
44
+ public function enqueue_styles() {
45
+ wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
46
+ }
47
+
48
+ /**
49
+ * The function responsible for rendering the shortcode.
50
+ * Makes a GET request and calls the render_xml to render the response.
51
+ *
52
+ * @since 1.0.0
53
+ *
54
+ * @param array $atts Shortcode attribute and values.
55
+ *
56
+ * @return HTML Rendered html to display.
57
+ */
58
+ public function render( $atts ) {
59
+ try {
60
+ $shortcode_attributes = $this->get_shortcode_attributes( $atts );
61
+
62
+ $validated_link_id = $this->shortcode_helper->get_validated_link_id( $shortcode_attributes['link_id'] );
63
+ $validated_marketplace = $this->shortcode_helper->get_validated_marketplace( $shortcode_attributes['marketplace'] );
64
+ $validated_asins = $this->shortcode_helper->get_validated_asins( $shortcode_attributes['asins'] );
65
+ $validated_template = $this->shortcode_helper->get_validated_template( $shortcode_attributes['template'] );
66
+ $validated_store_id = $this->shortcode_helper->get_validated_store_id( $shortcode_attributes['store'] );
67
+
68
+ $marketplace = $this->shortcode_helper->get_marketplace_endpoint( $validated_marketplace );
69
+ $url = $this->paapi_helper->get_item_lookup_url( $validated_asins, $marketplace, $validated_store_id );
70
+ $asins = $this->shortcode_helper->format_asins( $validated_asins );
71
+ $products_key = $this->helper->build_products_cache_key( $asins, $marketplace, $validated_store_id );
72
+ $products_template_key = $this->helper->build_template_cache_key( $asins, $marketplace, $validated_store_id, $validated_template );
73
+
74
+ $this->shortcode_helper->enqueue_template_styles( $validated_template );
75
+
76
+ return str_replace( array( '[[UNIQUE_ID]]' ), array( str_replace( '.', '-', $products_template_key ) ), $this->template_engine->render( $products_template_key, $products_key, $validated_template, $url, $validated_marketplace ) );
77
+ } catch ( Exception $e ) {
78
+ error_log( $this->paapi_helper->get_error_message( $e->getMessage() ) );
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Returns default shortcode attributes if not mentioned
84
+ *
85
+ * @since 1.0.0
86
+ *
87
+ * @param array $atts Shortcode attributes.
88
+ *
89
+ * @return array Default shortcode attributes if not mentioned.
90
+ */
91
+ private function get_shortcode_attributes( $atts ) {
92
+ $shortcode_attributes = shortcode_atts( array(
93
+ 'asins' => null,
94
+ 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ),
95
+ 'store' => get_option( AALB_DEFAULT_STORE_ID ),
96
+ 'template' => get_option( AALB_DEFAULT_TEMPLATE ),
97
+ 'link_id' => null
98
+ ), $atts );
99
+
100
+ return $shortcode_attributes;
101
+ }
102
+ }
103
+
104
+ ?>
shortcode/aalb_shortcode_helper.php CHANGED
@@ -1,195 +1,195 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Helper class for AALB shortcodes.
17
- *
18
- * Contains helper functions used while rendering shortcodes
19
- *
20
- * @since 1.4
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
- */
24
- class Aalb_Shortcode_Helper {
25
-
26
- protected $helper;
27
- protected $config_loader;
28
- protected $validation_helper;
29
-
30
- public function __construct() {
31
- $this->helper = new Aalb_Helper();
32
- $this->config_loader = new Aalb_Config_Loader();
33
- $this->validation_helper = new Aalb_Validation_Helper();
34
- }
35
-
36
- /**
37
- * Add CSS for the template
38
- *
39
- * @since 1.0.0
40
- */
41
- public function enqueue_template_styles( $template_name ) {
42
- $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
43
- if ( in_array( $template_name, $aalb_default_templates ) ) {
44
- wp_enqueue_style( 'aalb_template' . $template_name . '_css', AALB_TEMPLATE_URL . $template_name . '.css' );
45
- } else {
46
- $aalb_template_upload_url = $this->helper->get_template_upload_directory_url();
47
- wp_enqueue_style( 'aalb_template' . $template_name . '_css', $aalb_template_upload_url . $template_name . '.css' );
48
- }
49
- }
50
-
51
- /**
52
- * Format comma separated asins into hypen separated asins for building key.
53
- * Checks for more spaces and trims it.
54
- *
55
- * @since 1.0.0
56
- *
57
- * @param string $asins Comma separated asins.
58
- *
59
- * @return string Hyphen separated asins.
60
- */
61
- public function format_asins( $asins ) {
62
- return preg_replace( '/[ ,]+/', '-', trim( $asins ) );
63
- }
64
-
65
- /**
66
- * Get marketplace endpoint for marketplace abbreviation
67
- *
68
- * @since 1.0.0
69
- *
70
- * @param string $marketplace_abbr Marketplace Abbreviation from shortcode
71
- *
72
- * @return string $marketplace_endpoint Marketplace endpoint
73
- */
74
- public function get_marketplace_endpoint( $marketplace_abbr ) {
75
- $marketplace_endpoint = "";
76
- $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
77
- $marketplace_endpoint = array_search( $marketplace_abbr, $aalb_marketplace_names );
78
-
79
- return $marketplace_endpoint;
80
- }
81
-
82
- /**
83
- * Get validated link-id
84
- * Checks if the link id we got from the api is valid or not and returns
85
- * validated link-id. In case of invalid marketplace, it returns empty string.
86
- *
87
- * @since 1.0.0
88
- *
89
- * @param string $marketplace Marketplace from shortcode
90
- *
91
- * @return string $validated_template Validated marketplace
92
- */
93
- public function get_validated_link_id( $link_id ) {
94
- $validated_link_id = $link_id;
95
- if ( ! $this->validation_helper->validate_link_id( $link_id ) ) {
96
- //If the link id is not valid, return empty string
97
- $validated_link_id = '';
98
- }
99
-
100
- return $validated_link_id;
101
- }
102
-
103
- /**
104
- * Get validated marketplace.
105
- * Checks if a marketplace abbreviation from shortcode is valid and returns
106
- * validated marketplace. In case of invalid marketplace, it returns default marketplace.
107
- *
108
- * @since 1.0.0
109
- *
110
- * @param string $marketplace Marketplace from shortcode
111
- *
112
- * @return string $validated_template Validated marketplace
113
- */
114
- public function get_validated_marketplace( $marketplace ) {
115
- //Changing case of the marketplace to upper. Ensures case insensitivity
116
- $validated_marketplace = strtoupper( $marketplace );
117
- if ( ! $this->validation_helper->validate_marketplace( $marketplace ) ) {
118
- //If the marketplace is not valid, return default marketplace
119
- $validated_marketplace = get_option( AALB_DEFAULT_MARKETPLACE );
120
- }
121
-
122
- return $validated_marketplace;
123
- }
124
-
125
- /**
126
- * Get validated asin list
127
- * Drops invalid asin from the list
128
- *
129
- * @since 1.0.0
130
- *
131
- * @param string $asins List of asins from shortcode
132
- *
133
- * @return string List of validated asins
134
- */
135
- public function get_validated_asins( $asins ) {
136
- //Creates array of asins in the shortcode
137
- $asins_array = explode( ',', $asins );
138
- foreach ( $asins_array as $asin ) {
139
- if ( ! $this->validation_helper->validate_asin( $asin ) ) {
140
- //Drop Invalid ASIN out of list of asins
141
- $asins_array = array_diff( $asins_array, array( $asin ) );
142
- //Show error message regarding incorrect asin in preview mode only
143
- $this->helper->show_error_in_preview( "The ASIN: '" . $asin . "' is invalid." );
144
- }
145
- }
146
-
147
- return implode( ',', $asins_array );
148
- }
149
-
150
- /**
151
- * Get validated template.
152
- * Checks if a template is valid, returns default template otherwise
153
- *
154
- * @since 1.0.0
155
- *
156
- * @param string $template Template name from shortcode
157
- *
158
- * @return string $validated_template Validated template name
159
- */
160
- public function get_validated_template( $template ) {
161
- $validated_template = $template;
162
- if ( ! $this->validation_helper->validate_template_name( $template ) ) {
163
- //Return Default template in case of invalid template name
164
- $validated_template = get_option( AALB_DEFAULT_TEMPLATE );
165
- //Show error message regarding incorrect asin in preview mode only
166
- $this->helper->show_error_in_preview( "The template: '" . $template . "' is invalid. Using default template '" . $validated_template . "'." );
167
- }
168
-
169
- return $validated_template;
170
- }
171
-
172
- /**
173
- * Get validated store id.
174
- * Checks if a store id is valid, returns default store id otherwise
175
- *
176
- * @since 1.0.0
177
- *
178
- * @param string $store_id Store ID from shortcode
179
- *
180
- * @return string $validated_store_id Validated Store ID
181
- */
182
- public function get_validated_store_id( $store_id ) {
183
- $validated_store_id = $store_id;
184
- if ( ! $this->validation_helper->validate_store_id( $store_id ) ) {
185
- //Return Default store id in case of invalid store id
186
- $validated_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME );
187
- //Show error message regarding incorrect asin in preview mode only
188
- $this->helper->show_error_in_preview( "The Associate tag '" . $store_id . "' is not present in the list of valid tags. Associate tag has been updated to '" . $validated_store_id . "'. Please check your Associate tag selection or contact the administrator to add a new tag." );
189
- }
190
-
191
- return $validated_store_id;
192
- }
193
- }
194
-
195
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Helper class for AALB shortcodes.
17
+ *
18
+ * Contains helper functions used while rendering shortcodes
19
+ *
20
+ * @since 1.4
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
+ */
24
+ class Aalb_Shortcode_Helper {
25
+
26
+ protected $helper;
27
+ protected $config_loader;
28
+ protected $validation_helper;
29
+
30
+ public function __construct() {
31
+ $this->helper = new Aalb_Helper();
32
+ $this->config_loader = new Aalb_Config_Loader();
33
+ $this->validation_helper = new Aalb_Validation_Helper();
34
+ }
35
+
36
+ /**
37
+ * Add CSS for the template
38
+ *
39
+ * @since 1.0.0
40
+ */
41
+ public function enqueue_template_styles( $template_name ) {
42
+ $aalb_default_templates = explode( ",", AALB_AMAZON_TEMPLATE_NAMES );
43
+ if ( in_array( $template_name, $aalb_default_templates ) ) {
44
+ wp_enqueue_style( 'aalb_template' . $template_name . '_css', AALB_TEMPLATE_URL . $template_name . '.css' );
45
+ } else {
46
+ $aalb_template_upload_url = $this->helper->get_template_upload_directory_url();
47
+ wp_enqueue_style( 'aalb_template' . $template_name . '_css', $aalb_template_upload_url . $template_name . '.css' );
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Format comma separated asins into hypen separated asins for building key.
53
+ * Checks for more spaces and trims it.
54
+ *
55
+ * @since 1.0.0
56
+ *
57
+ * @param string $asins Comma separated asins.
58
+ *
59
+ * @return string Hyphen separated asins.
60
+ */
61
+ public function format_asins( $asins ) {
62
+ return preg_replace( '/[ ,]+/', '-', trim( $asins ) );
63
+ }
64
+
65
+ /**
66
+ * Get marketplace endpoint for marketplace abbreviation
67
+ *
68
+ * @since 1.0.0
69
+ *
70
+ * @param string $marketplace_abbr Marketplace Abbreviation from shortcode
71
+ *
72
+ * @return string $marketplace_endpoint Marketplace endpoint
73
+ */
74
+ public function get_marketplace_endpoint( $marketplace_abbr ) {
75
+ $marketplace_endpoint = "";
76
+ $aalb_marketplace_names = $this->config_loader->fetch_marketplaces();
77
+ $marketplace_endpoint = array_search( $marketplace_abbr, $aalb_marketplace_names );
78
+
79
+ return $marketplace_endpoint;
80
+ }
81
+
82
+ /**
83
+ * Get validated link-id
84
+ * Checks if the link id we got from the api is valid or not and returns
85
+ * validated link-id. In case of invalid marketplace, it returns empty string.
86
+ *
87
+ * @since 1.0.0
88
+ *
89
+ * @param string $marketplace Marketplace from shortcode
90
+ *
91
+ * @return string $validated_template Validated marketplace
92
+ */
93
+ public function get_validated_link_id( $link_id ) {
94
+ $validated_link_id = $link_id;
95
+ if ( ! $this->validation_helper->validate_link_id( $link_id ) ) {
96
+ //If the link id is not valid, return empty string
97
+ $validated_link_id = '';
98
+ }
99
+
100
+ return $validated_link_id;
101
+ }
102
+
103
+ /**
104
+ * Get validated marketplace.
105
+ * Checks if a marketplace abbreviation from shortcode is valid and returns
106
+ * validated marketplace. In case of invalid marketplace, it returns default marketplace.
107
+ *
108
+ * @since 1.0.0
109
+ *
110
+ * @param string $marketplace Marketplace from shortcode
111
+ *
112
+ * @return string $validated_template Validated marketplace
113
+ */
114
+ public function get_validated_marketplace( $marketplace ) {
115
+ //Changing case of the marketplace to upper. Ensures case insensitivity
116
+ $validated_marketplace = strtoupper( $marketplace );
117
+ if ( ! $this->validation_helper->validate_marketplace( $marketplace ) ) {
118
+ //If the marketplace is not valid, return default marketplace
119
+ $validated_marketplace = get_option( AALB_DEFAULT_MARKETPLACE );
120
+ }
121
+
122
+ return $validated_marketplace;
123
+ }
124
+
125
+ /**
126
+ * Get validated asin list
127
+ * Drops invalid asin from the list
128
+ *
129
+ * @since 1.0.0
130
+ *
131
+ * @param string $asins List of asins from shortcode
132
+ *
133
+ * @return string List of validated asins
134
+ */
135
+ public function get_validated_asins( $asins ) {
136
+ //Creates array of asins in the shortcode
137
+ $asins_array = explode( ',', $asins );
138
+ foreach ( $asins_array as $asin ) {
139
+ if ( ! $this->validation_helper->validate_asin( $asin ) ) {
140
+ //Drop Invalid ASIN out of list of asins
141
+ $asins_array = array_diff( $asins_array, array( $asin ) );
142
+ //Show error message regarding incorrect asin in preview mode only
143
+ $this->helper->show_error_in_preview( "The ASIN: '" . $asin . "' is invalid." );
144
+ }
145
+ }
146
+
147
+ return implode( ',', $asins_array );
148
+ }
149
+
150
+ /**
151
+ * Get validated template.
152
+ * Checks if a template is valid, returns default template otherwise
153
+ *
154
+ * @since 1.0.0
155
+ *
156
+ * @param string $template Template name from shortcode
157
+ *
158
+ * @return string $validated_template Validated template name
159
+ */
160
+ public function get_validated_template( $template ) {
161
+ $validated_template = $template;
162
+ if ( ! $this->validation_helper->validate_template_name( $template ) ) {
163
+ //Return Default template in case of invalid template name
164
+ $validated_template = get_option( AALB_DEFAULT_TEMPLATE );
165
+ //Show error message regarding incorrect asin in preview mode only
166
+ $this->helper->show_error_in_preview( "The template: '" . $template . "' is invalid. Using default template '" . $validated_template . "'." );
167
+ }
168
+
169
+ return $validated_template;
170
+ }
171
+
172
+ /**
173
+ * Get validated store id.
174
+ * Checks if a store id is valid, returns default store id otherwise
175
+ *
176
+ * @since 1.0.0
177
+ *
178
+ * @param string $store_id Store ID from shortcode
179
+ *
180
+ * @return string $validated_store_id Validated Store ID
181
+ */
182
+ public function get_validated_store_id( $store_id ) {
183
+ $validated_store_id = $store_id;
184
+ if ( ! $this->validation_helper->validate_store_id( $store_id ) ) {
185
+ //Return Default store id in case of invalid store id
186
+ $validated_store_id = get_option( AALB_DEFAULT_STORE_ID, AALB_DEFAULT_STORE_ID_NAME );
187
+ //Show error message regarding incorrect asin in preview mode only
188
+ $this->helper->show_error_in_preview( "The Associate tag '" . $store_id . "' is not present in the list of valid tags. Associate tag has been updated to '" . $validated_store_id . "'. Please check your Associate tag selection or contact the administrator to add a new tag." );
189
+ }
190
+
191
+ return $validated_store_id;
192
+ }
193
+ }
194
+
195
+ ?>
shortcode/aalb_shortcode_loader.php CHANGED
@@ -1,109 +1,109 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- *
17
- * Registers the shortcode with the wordpress for rendering the product information.
18
- * Makes only a single instance of Aalb_Shortcode for rendering all the shortcodes.
19
- *
20
- * @since 1.0.0
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
- */
24
- class Aalb_Shortcode_Loader {
25
-
26
- public $shortcode_link = null;
27
- public $shortcode_textlink = null;
28
-
29
- /**
30
- * Register shortcode with Wordpress
31
- *
32
- * @since 1.0.0
33
- */
34
- public function add_shortcode() {
35
- add_shortcode( AALB_SHORTCODE_AMAZON_LINK, array( $this, 'amazon_link_shortcode_callback' ) );
36
- add_shortcode( AALB_SHORTCODE_AMAZON_TEXT, array( $this, 'amazon_textlink_shortcode_callback' ) );
37
- }
38
-
39
- /**
40
- * Disable shortcode
41
- *
42
- * @since 1.0.0
43
- */
44
- public function remove_shortcode() {
45
- remove_shortcode( AALB_SHORTCODE_AMAZON_LINK );
46
- remove_shortcode( AALB_SHORTCODE_AMAZON_TEXT );
47
- }
48
-
49
- /**
50
- * Callback function for rendering amazon_link shortcode
51
- *
52
- *
53
- * @since 1.0.0
54
- *
55
- * @param array $atts Shortcode attributes and values.
56
- *
57
- * @return HTML HTML for displaying the templates.
58
- */
59
- public function amazon_link_shortcode_callback( $atts ) {
60
- return $this->get_amazon_link_shortcode()->render( $atts );
61
- }
62
-
63
- /**
64
- * Create only a single instance of the Aalb Shortcode.
65
- * No need to create an instance for rendering each shortcode.
66
- *
67
- * @since 1.0.0
68
- * @return Aalb_Shortcode The instance of Aalb_Shortcode.
69
- */
70
- public function get_amazon_link_shortcode() {
71
- if ( is_null( $this->shortcode_link ) ) {
72
- return new Aalb_Shortcode();
73
- }
74
-
75
- return $this->shortcode_link;
76
- }
77
-
78
- /**
79
- * Callback function for rendering amazon_textlink shortcode
80
- *
81
- *
82
- * @since 1.4
83
- *
84
- * @param array $atts Shortcode attributes and values.
85
- *
86
- * @return HTML HTML for displaying the templates.
87
- */
88
- public function amazon_textlink_shortcode_callback( $atts ) {
89
- return $this->get_amazon_textlink_shortcode()->render( $atts );
90
- }
91
-
92
- /**
93
- * Create only a single instance of the Aalb TextLink Shortcode.
94
- * No need to create an instance for rendering each shortcode.
95
- *
96
- * @since 1.4
97
- * @return Aalb_Shortcode_Text The instance of Aalb_Shortcode_Text.
98
- */
99
- public function get_amazon_textlink_shortcode() {
100
- if ( is_null( $this->shortcode_textlink ) ) {
101
- return new Aalb_Shortcode_Text();
102
- }
103
-
104
- return $this->shortcode_textlink;
105
- }
106
-
107
- }
108
-
109
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ *
17
+ * Registers the shortcode with the wordpress for rendering the product information.
18
+ * Makes only a single instance of Aalb_Shortcode for rendering all the shortcodes.
19
+ *
20
+ * @since 1.0.0
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
+ */
24
+ class Aalb_Shortcode_Loader {
25
+
26
+ public $shortcode_link = null;
27
+ public $shortcode_textlink = null;
28
+
29
+ /**
30
+ * Register shortcode with Wordpress
31
+ *
32
+ * @since 1.0.0
33
+ */
34
+ public function add_shortcode() {
35
+ add_shortcode( AALB_SHORTCODE_AMAZON_LINK, array( $this, 'amazon_link_shortcode_callback' ) );
36
+ add_shortcode( AALB_SHORTCODE_AMAZON_TEXT, array( $this, 'amazon_textlink_shortcode_callback' ) );
37
+ }
38
+
39
+ /**
40
+ * Disable shortcode
41
+ *
42
+ * @since 1.0.0
43
+ */
44
+ public function remove_shortcode() {
45
+ remove_shortcode( AALB_SHORTCODE_AMAZON_LINK );
46
+ remove_shortcode( AALB_SHORTCODE_AMAZON_TEXT );
47
+ }
48
+
49
+ /**
50
+ * Callback function for rendering amazon_link shortcode
51
+ *
52
+ *
53
+ * @since 1.0.0
54
+ *
55
+ * @param array $atts Shortcode attributes and values.
56
+ *
57
+ * @return HTML HTML for displaying the templates.
58
+ */
59
+ public function amazon_link_shortcode_callback( $atts ) {
60
+ return $this->get_amazon_link_shortcode()->render( $atts );
61
+ }
62
+
63
+ /**
64
+ * Create only a single instance of the Aalb Shortcode.
65
+ * No need to create an instance for rendering each shortcode.
66
+ *
67
+ * @since 1.0.0
68
+ * @return Aalb_Shortcode The instance of Aalb_Shortcode.
69
+ */
70
+ public function get_amazon_link_shortcode() {
71
+ if ( is_null( $this->shortcode_link ) ) {
72
+ return new Aalb_Shortcode();
73
+ }
74
+
75
+ return $this->shortcode_link;
76
+ }
77
+
78
+ /**
79
+ * Callback function for rendering amazon_textlink shortcode
80
+ *
81
+ *
82
+ * @since 1.4
83
+ *
84
+ * @param array $atts Shortcode attributes and values.
85
+ *
86
+ * @return HTML HTML for displaying the templates.
87
+ */
88
+ public function amazon_textlink_shortcode_callback( $atts ) {
89
+ return $this->get_amazon_textlink_shortcode()->render( $atts );
90
+ }
91
+
92
+ /**
93
+ * Create only a single instance of the Aalb TextLink Shortcode.
94
+ * No need to create an instance for rendering each shortcode.
95
+ *
96
+ * @since 1.4
97
+ * @return Aalb_Shortcode_Text The instance of Aalb_Shortcode_Text.
98
+ */
99
+ public function get_amazon_textlink_shortcode() {
100
+ if ( is_null( $this->shortcode_textlink ) ) {
101
+ return new Aalb_Shortcode_Text();
102
+ }
103
+
104
+ return $this->shortcode_textlink;
105
+ }
106
+
107
+ }
108
+
109
+ ?>
shortcode/aalb_shortcode_text.php CHANGED
@@ -1,103 +1,103 @@
1
- <?php
2
-
3
- /*
4
- Copyright 2016-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
-
6
- Licensed under the GNU General Public License as published by the Free Software Foundation,
7
- Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
- A copy of the License is located in the "license" file accompanying this file.
9
-
10
- This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
- either express or implied. See the License for the specific language governing permissions
12
- and limitations under the License.
13
- */
14
-
15
- /**
16
- * Fired when a amazon_textlink is there in the post page.
17
- *
18
- * Gets the product information by making a Paapi request and renders the HTML
19
- *
20
- * @since 1.4
21
- * @package AmazonAssociatesLinkBuilder
22
- * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
- */
24
- class Aalb_Shortcode_Text {
25
-
26
- protected $paapi_helper;
27
- protected $template_engine;
28
- protected $helper;
29
- protected $tracking_api_helper;
30
- protected $shortcode_helper;
31
-
32
- public function __construct() {
33
- $this->template_engine = new Aalb_Template_Engine();
34
- $this->paapi_helper = new Aalb_Paapi_Helper();
35
- $this->helper = new Aalb_Helper();
36
- $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
37
- $this->shortcode_helper = new Aalb_Shortcode_Helper();
38
- }
39
-
40
- /**
41
- * Add basic styles
42
- *
43
- * @since 1.4
44
- */
45
- public function enqueue_styles() {
46
- wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
47
- }
48
-
49
- /**
50
- * The function responsible for rendering the shortcode.
51
- * Makes a GET request and calls the render_xml to render the response.
52
- *
53
- * @since 1.4
54
- *
55
- * @param array $atts Shortcode attribute and values.
56
- *
57
- * @return HTML Rendered html to display.
58
- */
59
-
60
- public function render( $atts ) {
61
- try {
62
- $shortcode_attributes = $this->get_shortcode_attributes( $atts );
63
-
64
- $validated_link_id = $this->shortcode_helper->get_validated_link_id( $shortcode_attributes['link_id'] );
65
- $validated_marketplace = $this->shortcode_helper->get_validated_marketplace( $shortcode_attributes['marketplace'] );
66
- $validated_asins = $this->shortcode_helper->get_validated_asins( $shortcode_attributes['asin'] );
67
- $validated_template = $this->shortcode_helper->get_validated_template( $shortcode_attributes['template'] );
68
- $validated_store_id = $this->shortcode_helper->get_validated_store_id( $shortcode_attributes['store'] );
69
- $link_text = $shortcode_attributes['text'];
70
-
71
- $marketplace = $this->shortcode_helper->get_marketplace_endpoint( $validated_marketplace );
72
- $url = $this->paapi_helper->get_item_lookup_url( $validated_asins, $marketplace, $validated_store_id );
73
- $asins = $this->shortcode_helper->format_asins( $validated_asins );
74
- $products_key = $this->helper->build_products_cache_key( $asins, $marketplace, $validated_store_id );
75
- $products_template_key = $this->helper->build_template_cache_key( $asins, $marketplace, $validated_store_id, $validated_template );
76
-
77
- $this->shortcode_helper->enqueue_template_styles( $validated_template );
78
-
79
- return str_replace( array( '[[UNIQUE_ID]]', '[[Amazon_Link_Text]]' ), array( str_replace( '.', '-', $products_template_key ), $link_text ), $this->template_engine->render( $products_template_key, $products_key, $validated_template, $url, $validated_marketplace ) );
80
- } catch ( Exception $e ) {
81
- error_log( $this->paapi_helper->get_error_message( $e->getMessage() ) );
82
- }
83
- }
84
-
85
- /**
86
- * Returns default shortcode attributes if not mentioned
87
- *w
88
- * @since 1.4
89
- *
90
- * @param array $atts Shortcode attributes.
91
- *
92
- * @return array Default shortcode attributes if not mentioned.
93
- */
94
- private function get_shortcode_attributes( $atts ) {
95
- $shortcode_attributes = shortcode_atts( array(
96
- 'asin' => null, 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ), 'store' => get_option( AALB_DEFAULT_STORE_ID ), 'template' => get_option( AALB_DEFAULT_TEMPLATE ), 'link_id' => null, 'text' => null
97
- ), $atts );
98
-
99
- return $shortcode_attributes;
100
- }
101
- }
102
-
103
- ?>
1
+ <?php
2
+
3
+ /*
4
+ Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+
6
+ Licensed under the GNU General Public License as published by the Free Software Foundation,
7
+ Version 2.0 (the "License"). You may not use this file except in compliance with the License.
8
+ A copy of the License is located in the "license" file accompanying this file.
9
+
10
+ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ either express or implied. See the License for the specific language governing permissions
12
+ and limitations under the License.
13
+ */
14
+
15
+ /**
16
+ * Fired when a amazon_textlink is there in the post page.
17
+ *
18
+ * Gets the product information by making a Paapi request and renders the HTML
19
+ *
20
+ * @since 1.4
21
+ * @package AmazonAssociatesLinkBuilder
22
+ * @subpackage AmazonAssociatesLinkBuilder/shortcode
23
+ */
24
+ class Aalb_Shortcode_Text {
25
+
26
+ protected $paapi_helper;
27
+ protected $template_engine;
28
+ protected $helper;
29
+ protected $tracking_api_helper;
30
+ protected $shortcode_helper;
31
+
32
+ public function __construct() {
33
+ $this->template_engine = new Aalb_Template_Engine();
34
+ $this->paapi_helper = new Aalb_Paapi_Helper();
35
+ $this->helper = new Aalb_Helper();
36
+ $this->tracking_api_helper = new Aalb_Tracking_Api_Helper();
37
+ $this->shortcode_helper = new Aalb_Shortcode_Helper();
38
+ }
39
+
40
+ /**
41
+ * Add basic styles
42
+ *
43
+ * @since 1.4
44
+ */
45
+ public function enqueue_styles() {
46
+ wp_enqueue_style( 'aalb_basics_css', AALB_BASICS_CSS );
47
+ }
48
+
49
+ /**
50
+ * The function responsible for rendering the shortcode.
51
+ * Makes a GET request and calls the render_xml to render the response.
52
+ *
53
+ * @since 1.4
54
+ *
55
+ * @param array $atts Shortcode attribute and values.
56
+ *
57
+ * @return HTML Rendered html to display.
58
+ */
59
+
60
+ public function render( $atts ) {
61
+ try {
62
+ $shortcode_attributes = $this->get_shortcode_attributes( $atts );
63
+
64
+ $validated_link_id = $this->shortcode_helper->get_validated_link_id( $shortcode_attributes['link_id'] );
65
+ $validated_marketplace = $this->shortcode_helper->get_validated_marketplace( $shortcode_attributes['marketplace'] );
66
+ $validated_asins = $this->shortcode_helper->get_validated_asins( $shortcode_attributes['asin'] );
67
+ $validated_template = $this->shortcode_helper->get_validated_template( $shortcode_attributes['template'] );
68
+ $validated_store_id = $this->shortcode_helper->get_validated_store_id( $shortcode_attributes['store'] );
69
+ $link_text = $shortcode_attributes['text'];
70
+
71
+ $marketplace = $this->shortcode_helper->get_marketplace_endpoint( $validated_marketplace );
72
+ $url = $this->paapi_helper->get_item_lookup_url( $validated_asins, $marketplace, $validated_store_id );
73
+ $asins = $this->shortcode_helper->format_asins( $validated_asins );
74
+ $products_key = $this->helper->build_products_cache_key( $asins, $marketplace, $validated_store_id );
75
+ $products_template_key = $this->helper->build_template_cache_key( $asins, $marketplace, $validated_store_id, $validated_template );
76
+
77
+ $this->shortcode_helper->enqueue_template_styles( $validated_template );
78
+
79
+ return str_replace( array( '[[UNIQUE_ID]]', '[[Amazon_Link_Text]]' ), array( str_replace( '.', '-', $products_template_key ), $link_text ), $this->template_engine->render( $products_template_key, $products_key, $validated_template, $url, $validated_marketplace ) );
80
+ } catch ( Exception $e ) {
81
+ error_log( $this->paapi_helper->get_error_message( $e->getMessage() ) );
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Returns default shortcode attributes if not mentioned
87
+ *w
88
+ * @since 1.4
89
+ *
90
+ * @param array $atts Shortcode attributes.
91
+ *
92
+ * @return array Default shortcode attributes if not mentioned.
93
+ */
94
+ private function get_shortcode_attributes( $atts ) {
95
+ $shortcode_attributes = shortcode_atts( array(
96
+ 'asin' => null, 'marketplace' => get_option( AALB_DEFAULT_MARKETPLACE ), 'store' => get_option( AALB_DEFAULT_STORE_ID ), 'template' => get_option( AALB_DEFAULT_TEMPLATE ), 'link_id' => null, 'text' => null
97
+ ), $atts );
98
+
99
+ return $shortcode_attributes;
100
+ }
101
+ }
102
+
103
+ ?>
template/PriceLink.mustache CHANGED
@@ -1,7 +1,7 @@
1
- {{#Items}}
2
- {{#Item}}
3
- {{#aalb}}
4
- <a href="{{DetailPageURL}}" target="_blank" rel="nofollow">{{CurrentPrice}}</a> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
5
- {{/aalb}}
6
- {{/Item}}
7
- {{/Items}}
1
+ {{#Items}}
2
+ {{#Item}}
3
+ {{#aalb}}
4
+ <a href="{{DetailPageURL}}" target="_blank" rel="nofollow">{{CurrentPrice}}</a> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
5
+ {{/aalb}}
6
+ {{/Item}}
7
+ {{/Items}}
template/ProductAd.css CHANGED
@@ -1,259 +1,259 @@
1
- .aalb-pa-ad-unit {
2
- /*Enable this border property to have a border around the ad unit*/
3
- /*border: 1px solid #d4d4c4;*/
4
- background: #ffffff;
5
- }
6
-
7
- /* Actual styles start below */
8
- .aalb-pa-ad-unit {
9
- position: relative;
10
- overflow: hidden;
11
- padding: 22px 40px;
12
- }
13
-
14
- .aalb-pa-ad-unit * {
15
- box-sizing: content-box;
16
- box-shadow: none;
17
- font-family: Arial, Helvetica, sans-serif;
18
- margin: 0;
19
- margin-bottom: 0;
20
- margin-left: 0;
21
- margin-right: 0;
22
- margin-top: 0;
23
- outline: 0;
24
- padding: 0;
25
- padding-bottom: 0;
26
- padding-left: 0;
27
- padding-right: 0;
28
- padding-top: 0;
29
- }
30
-
31
- .aalb-pa-ad-unit.pull-left {
32
- float: left;
33
- }
34
-
35
- .aalb-pa-ad-unit.pull-right {
36
- float: right;
37
- }
38
-
39
- .aalb-pa-ad-unit.pull-left .aalb-pa-product, .aalb-pa-ad-unit.pull-right .aalb-pa-product {
40
- width: 185px !important;
41
- }
42
-
43
- .aalb-pa-ad-unit a {
44
- box-shadow: none !important;
45
- }
46
-
47
- .aalb-pa-ad-unit a:hover {
48
- color: #c45500;
49
- }
50
-
51
- .aalb-pa-ad-unit .aalb-pa-ad-header {
52
- padding-left: 3px;
53
- padding-bottom: 9px;
54
- font-size: 17px;
55
- font-weight: normal;
56
- color: #111111;
57
- }
58
-
59
- .aalb-pa-ad-unit .aalb-pa-product-list {
60
- overflow: hidden;
61
- }
62
-
63
- .aalb-pa-ad-unit .aalb-pa-product {
64
- min-width: 185px;
65
- max-width: 385px;
66
- height: auto !important;
67
- padding-top: 22px;
68
- padding-bottom: 22px;
69
- margin-left: 10px;
70
- margin-right: 10px;
71
- float: left;
72
- list-style: none;
73
- text-align: center;
74
- }
75
-
76
- .aalb-pa-ad-unit .aalb-pa-product-image {
77
- display: table;
78
- width: 150px;
79
- height: 150px;
80
- margin: 0 auto;
81
- text-align: center;
82
- }
83
-
84
- .aalb-pa-ad-unit .aalb-pa-product-image-wrapper {
85
- display: table-cell;
86
- vertical-align: middle;
87
- }
88
-
89
- .aalb-pa-ad-unit .aalb-pa-product-image a {
90
- position: relative;
91
- display: inline-block;
92
- vertical-align: middle;
93
- }
94
-
95
- .aalb-pa-ad-unit .aalb-pa-product-image img {
96
- max-width: 150px;
97
- max-height: 150px;
98
- vertical-align: bottom;
99
- }
100
-
101
- .aalb-pa-ad-unit .aalb-pa-percent-off {
102
- display: block;
103
- width: 32px;
104
- height: 27px;
105
- padding-top: 5px;
106
- position: absolute;
107
- top: -16px;
108
- right: -16px;
109
- color: #ffffff;
110
- font-size: 12px;
111
- text-align: center;
112
- -webkit-border-radius: 50%;
113
- -moz-border-radius: 50%;
114
- -ms-border-radius: 50%;
115
- border-radius: 50%;
116
- background-color: #a50200;
117
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
118
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
119
- }
120
-
121
- .aalb-pa-ad-unit.hide-percent-off-badge .aalb-pa-percent-off {
122
- display: none;
123
- }
124
-
125
- .aalb-pa-ad-unit .aalb-pa-product-details {
126
- display: inline-block;
127
- max-width: 100%;
128
- margin-top: 11px;
129
- text-align: left;
130
- }
131
-
132
- .aalb-pa-ad-unit .aalb-pa-product-title a {
133
- display: block;
134
- width: 100%;
135
- overflow: hidden;
136
- white-space: nowrap;
137
- text-overflow: ellipsis;
138
- font-size: 13px;
139
- color: #111111;
140
- text-decoration: none;
141
- }
142
-
143
- .aalb-pa-ad-unit.no-truncate .aalb-pa-product-title a {
144
- text-overflow: initial;
145
- white-space: initial;
146
- }
147
-
148
- .aalb-pa-ad-unit .aalb-pa-product-offer-price {
149
- font-size: 13px;
150
- color: #111111;
151
- }
152
-
153
- .aalb-pa-ad-unit .aalb-pa-product-offer-price-value {
154
- color: #AB1700;
155
- font-weight: bold;
156
- }
157
-
158
- .aalb-pa-ad-unit .aalb-pa-product-list-price {
159
- font-size: 13px;
160
- color: #565656;
161
- }
162
-
163
- .aalb-pa-ad-unit .aalb-pa-product-list-price-value {
164
- text-decoration: line-through;
165
- }
166
-
167
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
168
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
169
- display: inline-block;
170
- margin-top: -1px;
171
- vertical-align: middle;
172
- background-position: -205px -246px;
173
- width: 47px;
174
- height: 15px;
175
- }
176
-
177
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
178
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
179
- display: inline-block;
180
- margin-top: -1px;
181
- vertical-align: middle;
182
- background-position: -205px -274px;
183
- width: 62px;
184
- height: 16px;
185
- }
186
-
187
- .aalb-pa-ad-unit .aalb-pa-product-offer-price,
188
- .aalb-pa-ad-unit .aalb-pa-product-list-price,
189
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon {
190
- display: inline-block;
191
- margin-right: 2px;
192
- }
193
-
194
- .aalb-pa-ad-unit .aalb-pa-btn-prev,
195
- .aalb-pa-ad-unit .aalb-pa-btn-next {
196
- position: absolute;
197
- top: 50%;
198
- margin-top: -52px;
199
- display: block;
200
- visibility: hidden;
201
- width: 43px;
202
- height: 105px;
203
- z-index: 2;
204
- line-height: 105px;
205
- background: #ffffff;
206
- color: #D0D0D0;
207
- font-size: 35px;
208
- text-align: center;
209
- text-decoration: none;
210
- border: 1px solid #e9e9e9;
211
- -webkit-box-shadow: 0 0 4px #e9e9e9;
212
- box-shadow: 0 0 4px #e9e9e9;
213
- }
214
-
215
- .aalb-pa-ad-unit .aalb-pa-btn-prev:hover,
216
- .aalb-pa-ad-unit .aalb-pa-btn-next:hover {
217
- color: #999999;
218
- }
219
-
220
- .aalb-pa-ad-unit .aalb-pa-btn-prev:focus,
221
- .aalb-pa-ad-unit .aalb-pa-btn-next:focus {
222
- outline: none;
223
- }
224
-
225
- .aalb-pa-ad-unit .aalb-pa-btn-prev {
226
- left: 0;
227
- border-left: 0;
228
- border-top-right-radius: 20px;
229
- border-bottom-right-radius: 20px;
230
- }
231
-
232
- .aalb-pa-ad-unit .aalb-pa-btn-next {
233
- right: 0;
234
- border-right: 0;
235
- border-top-left-radius: 20px;
236
- border-bottom-left-radius: 20px;
237
- }
238
-
239
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
240
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
241
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
242
- display: inline-block;
243
- margin-top: -1px;
244
- vertical-align: middle;
245
- background-position: -205px -246px;
246
- width: 47px;
247
- height: 15px;
248
- }
249
-
250
- .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
251
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
252
- display: inline-block;
253
- margin-top: -1px;
254
- vertical-align: middle;
255
- background-position: -205px -274px;
256
- width: 62px;
257
- height: 16px;
258
- }
259
- }
1
+ .aalb-pa-ad-unit {
2
+ /*Enable this border property to have a border around the ad unit*/
3
+ /*border: 1px solid #d4d4c4;*/
4
+ background: #ffffff;
5
+ }
6
+
7
+ /* Actual styles start below */
8
+ .aalb-pa-ad-unit {
9
+ position: relative;
10
+ overflow: hidden;
11
+ padding: 22px 40px;
12
+ }
13
+
14
+ .aalb-pa-ad-unit * {
15
+ box-sizing: content-box;
16
+ box-shadow: none;
17
+ font-family: Arial, Helvetica, sans-serif;
18
+ margin: 0;
19
+ margin-bottom: 0;
20
+ margin-left: 0;
21
+ margin-right: 0;
22
+ margin-top: 0;
23
+ outline: 0;
24
+ padding: 0;
25
+ padding-bottom: 0;
26
+ padding-left: 0;
27
+ padding-right: 0;
28
+ padding-top: 0;
29
+ }
30
+
31
+ .aalb-pa-ad-unit.pull-left {
32
+ float: left;
33
+ }
34
+
35
+ .aalb-pa-ad-unit.pull-right {
36
+ float: right;
37
+ }
38
+
39
+ .aalb-pa-ad-unit.pull-left .aalb-pa-product, .aalb-pa-ad-unit.pull-right .aalb-pa-product {
40
+ width: 185px !important;
41
+ }
42
+
43
+ .aalb-pa-ad-unit a {
44
+ box-shadow: none !important;
45
+ }
46
+
47
+ .aalb-pa-ad-unit a:hover {
48
+ color: #c45500;
49
+ }
50
+
51
+ .aalb-pa-ad-unit .aalb-pa-ad-header {
52
+ padding-left: 3px;
53
+ padding-bottom: 9px;
54
+ font-size: 17px;
55
+ font-weight: normal;
56
+ color: #111111;
57
+ }
58
+
59
+ .aalb-pa-ad-unit .aalb-pa-product-list {
60
+ overflow: hidden;
61
+ }
62
+
63
+ .aalb-pa-ad-unit .aalb-pa-product {
64
+ min-width: 185px;
65
+ max-width: 385px;
66
+ height: auto !important;
67
+ padding-top: 22px;
68
+ padding-bottom: 22px;
69
+ margin-left: 10px;
70
+ margin-right: 10px;
71
+ float: left;
72
+ list-style: none;
73
+ text-align: center;
74
+ }
75
+
76
+ .aalb-pa-ad-unit .aalb-pa-product-image {
77
+ display: table;
78
+ width: 150px;
79
+ height: 150px;
80
+ margin: 0 auto;
81
+ text-align: center;
82
+ }
83
+
84
+ .aalb-pa-ad-unit .aalb-pa-product-image-wrapper {
85
+ display: table-cell;
86
+ vertical-align: middle;
87
+ }
88
+
89
+ .aalb-pa-ad-unit .aalb-pa-product-image a {
90
+ position: relative;
91
+ display: inline-block;
92
+ vertical-align: middle;
93
+ }
94
+
95
+ .aalb-pa-ad-unit .aalb-pa-product-image img {
96
+ max-width: 150px;
97
+ max-height: 150px;
98
+ vertical-align: bottom;
99
+ }
100
+
101
+ .aalb-pa-ad-unit .aalb-pa-percent-off {
102
+ display: block;
103
+ width: 32px;
104
+ height: 27px;
105
+ padding-top: 5px;
106
+ position: absolute;
107
+ top: -16px;
108
+ right: -16px;
109
+ color: #ffffff;
110
+ font-size: 12px;
111
+ text-align: center;
112
+ -webkit-border-radius: 50%;
113
+ -moz-border-radius: 50%;
114
+ -ms-border-radius: 50%;
115
+ border-radius: 50%;
116
+ background-color: #a50200;
117
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
118
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
119
+ }
120
+
121
+ .aalb-pa-ad-unit.hide-percent-off-badge .aalb-pa-percent-off {
122
+ display: none;
123
+ }
124
+
125
+ .aalb-pa-ad-unit .aalb-pa-product-details {
126
+ display: inline-block;
127
+ max-width: 100%;
128
+ margin-top: 11px;
129
+ text-align: left;
130
+ }
131
+
132
+ .aalb-pa-ad-unit .aalb-pa-product-title a {
133
+ display: block;
134
+ width: 100%;
135
+ overflow: hidden;
136
+ white-space: nowrap;
137
+ text-overflow: ellipsis;
138
+ font-size: 13px;
139
+ color: #111111;
140
+ text-decoration: none;
141
+ }
142
+
143
+ .aalb-pa-ad-unit.no-truncate .aalb-pa-product-title a {
144
+ text-overflow: initial;
145
+ white-space: initial;
146
+ }
147
+
148
+ .aalb-pa-ad-unit .aalb-pa-product-offer-price {
149
+ font-size: 13px;
150
+ color: #111111;
151
+ }
152
+
153
+ .aalb-pa-ad-unit .aalb-pa-product-offer-price-value {
154
+ color: #AB1700;
155
+ font-weight: bold;
156
+ }
157
+
158
+ .aalb-pa-ad-unit .aalb-pa-product-list-price {
159
+ font-size: 13px;
160
+ color: #565656;
161
+ }
162
+
163
+ .aalb-pa-ad-unit .aalb-pa-product-list-price-value {
164
+ text-decoration: line-through;
165
+ }
166
+
167
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
168
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
169
+ display: inline-block;
170
+ margin-top: -1px;
171
+ vertical-align: middle;
172
+ background-position: -205px -246px;
173
+ width: 47px;
174
+ height: 15px;
175
+ }
176
+
177
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
178
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
179
+ display: inline-block;
180
+ margin-top: -1px;
181
+ vertical-align: middle;
182
+ background-position: -205px -274px;
183
+ width: 62px;
184
+ height: 16px;
185
+ }
186
+
187
+ .aalb-pa-ad-unit .aalb-pa-product-offer-price,
188
+ .aalb-pa-ad-unit .aalb-pa-product-list-price,
189
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon {
190
+ display: inline-block;
191
+ margin-right: 2px;
192
+ }
193
+
194
+ .aalb-pa-ad-unit .aalb-pa-btn-prev,
195
+ .aalb-pa-ad-unit .aalb-pa-btn-next {
196
+ position: absolute;
197
+ top: 50%;
198
+ margin-top: -52px;
199
+ display: block;
200
+ visibility: hidden;
201
+ width: 43px;
202
+ height: 105px;
203
+ z-index: 2;
204
+ line-height: 105px;
205
+ background: #ffffff;
206
+ color: #D0D0D0;
207
+ font-size: 35px;
208
+ text-align: center;
209
+ text-decoration: none;
210
+ border: 1px solid #e9e9e9;
211
+ -webkit-box-shadow: 0 0 4px #e9e9e9;
212
+ box-shadow: 0 0 4px #e9e9e9;
213
+ }
214
+
215
+ .aalb-pa-ad-unit .aalb-pa-btn-prev:hover,
216
+ .aalb-pa-ad-unit .aalb-pa-btn-next:hover {
217
+ color: #999999;
218
+ }
219
+
220
+ .aalb-pa-ad-unit .aalb-pa-btn-prev:focus,
221
+ .aalb-pa-ad-unit .aalb-pa-btn-next:focus {
222
+ outline: none;
223
+ }
224
+
225
+ .aalb-pa-ad-unit .aalb-pa-btn-prev {
226
+ left: 0;
227
+ border-left: 0;
228
+ border-top-right-radius: 20px;
229
+ border-bottom-right-radius: 20px;
230
+ }
231
+
232
+ .aalb-pa-ad-unit .aalb-pa-btn-next {
233
+ right: 0;
234
+ border-right: 0;
235
+ border-top-left-radius: 20px;
236
+ border-bottom-left-radius: 20px;
237
+ }
238
+
239
+ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
240
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-all {
241
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
242
+ display: inline-block;
243
+ margin-top: -1px;
244
+ vertical-align: middle;
245
+ background-position: -205px -246px;
246
+ width: 47px;
247
+ height: 15px;
248
+ }
249
+
250
+ .aalb-pa-ad-unit .aalb-pa-product-prime-icon .icon-prime-es {
251
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
252
+ display: inline-block;
253
+ margin-top: -1px;
254
+ vertical-align: middle;
255
+ background-position: -205px -274px;
256
+ width: 62px;
257
+ height: 16px;
258
+ }
259
+ }
template/ProductAd.mustache CHANGED
@@ -1,141 +1,141 @@
1
- {{#Items}} <!--Section tag for iterating through the list of items-->
2
- <!-- Single product Ad Template Layout. Position of the Ad can be configured by specifying pull-left or pull-right class below-->
3
- <div class="aalb-pa-ad-unit pull-left" id="{{ID}}">
4
- <div class="aalb-pa-wrapper">
5
- <div class="aalb-pa-product-container">
6
- <ul class="aalb-pa-product-list">
7
- {{#Item}} <!-- Section tag for beginning of information on one item -->
8
- {{#aalb}} <!-- Section tag for picking up information on attributes for the item -->
9
- <li class="aalb-pa-product">
10
- <div class="aalb-pa-product-image">
11
- <div class="aalb-pa-product-image-wrapper">
12
- <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow"> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
13
- <img src="{{MediumImageURL}}" srcset="{{LargeImageURL}}" alt="{{Title}}" />
14
- {{#SavingPercent}} <!-- The section tag ensures that percentage savings is displayed only if it is available -->
15
- <span class="aalb-pa-percent-off">
16
- -{{SavingPercent}}%
17
- </span>
18
- {{/SavingPercent}}
19
- </a>
20
- </div>
21
- </div>
22
- <div class="aalb-pa-product-details">
23
- <div class="aalb-pa-product-title">
24
- <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow">
25
- {{Title}}
26
- </a>
27
- </div>
28
- <div class="aalb-pa-product-offer-price">
29
- <!-- The section tag for different marketplaces ensures localization of static text. -->
30
- {{#MarketplaceUS}}Price{{/MarketplaceUS}}{{#MarketplaceFR}}Prix{{/MarketplaceFR}}{{#MarketplaceIT}}Prezzo{{/MarketplaceIT}}{{#MarketplaceDE}}Preis{{/MarketplaceDE}}{{#MarketplaceES}}Precio{{/MarketplaceES}}{{#MarketplaceBR}}Price{{/MarketplaceBR}}{{#MarketplaceCA}}Price{{/MarketplaceCA}}{{#MarketplaceCN}}Price{{/MarketplaceCN}}{{#MarketplaceIN}}Price{{/MarketplaceIN}}{{#MarketplaceJP}}Price{{/MarketplaceJP}}{{#MarketplaceMX}}Price{{/MarketplaceMX}}{{#MarketplaceUK}}Price{{/MarketplaceUK}}: <span class="aalb-pa-product-offer-price-value">{{CurrentPrice}}</span>
31
- </div>
32
- {{#StrikePrice}} <!-- The section tag ensures that strike price is displayed only if it is available -->
33
- <div class="aalb-pa-product-list-price">
34
- <!-- The section tag for different marketplaces ensures localization of static text. -->
35
- {{#MarketplaceUS}}Was{{/MarketplaceUS}}{{#MarketplaceFR}}Ancien prix{{/MarketplaceFR}}{{#MarketplaceIT}}Da{{/MarketplaceIT}}{{#MarketplaceDE}}statt{{/MarketplaceDE}}{{#MarketplaceES}}Precio recomendado{{/MarketplaceES}}{{#MarketplaceBR}}Was{{/MarketplaceBR}}{{#MarketplaceCA}}Was{{/MarketplaceCA}}{{#MarketplaceCN}}Was{{/MarketplaceCN}}{{#MarketplaceIN}}Was{{/MarketplaceIN}}{{#MarketplaceJP}}Was{{/MarketplaceJP}}{{#MarketplaceMX}}Was{{/MarketplaceMX}}{{#MarketplaceUK}}Was{{/MarketplaceUK}}: <span class="aalb-pa-product-list-price-value">{{StrikePrice}}</span>
36
- </div>
37
- {{/StrikePrice}}
38
- {{#Prime}} <!-- The section tag ensures that prime icon is displayed only if it is available -->
39
- <div class="aalb-pa-product-prime-icon">
40
- {{#MarketplaceES}} <!-- Display Prime Icon for ES if marketplace is ES -->
41
- <i class="icon-prime-es"></i>
42
- {{/MarketplaceES}}
43
- {{^MarketplaceES}} <!-- Display Common Prime Icon for all other marketplaces -->
44
- <i class="icon-prime-all"></i>
45
- {{/MarketplaceES}}
46
- </div>
47
- {{/Prime}}
48
- </div>
49
- </li>
50
- {{/aalb}}
51
- {{/Item}}
52
- </ul>
53
- </div>
54
- </div>
55
- <a href="javascript:void(0);" class="aalb-pa-btn-prev">‹</a>
56
- <a href="javascript:void(0);" class="aalb-pa-btn-next">›</a>
57
- </div>
58
- {{/Items}}
59
-
60
- <script>
61
- jQuery(document).ready(function() {
62
-
63
- var CONSTANTS = {
64
- productMinWidth : 185,
65
- productMargin : 20
66
- };
67
-
68
- var $adUnits = jQuery('.aalb-pa-ad-unit');
69
- $adUnits.each(function() {
70
- var $adUnit = jQuery(this),
71
- $wrapper = $adUnit.find('.aalb-pa-wrapper'),
72
- $productContainer = $adUnit.find('.aalb-pa-product-container'),
73
- $btnNext = $adUnit.find('.aalb-pa-btn-next'),
74
- $btnPrev = $adUnit.find('.aalb-pa-btn-prev'),
75
- $productList = $productContainer.find('.aalb-pa-product-list'),
76
- $products = $productList.find('.aalb-pa-product'),
77
- productCount = $products.length;
78
-
79
- if (!productCount) {
80
- return true;
81
- }
82
-
83
- var rows = $adUnit.find('input[name=rows]').length && parseInt($adUnit.find('input[name=rows]').val(), 10),
84
- columns = $adUnit.find('input[name=columns]').length && parseInt($adUnit.find('input[name=columns]').val(), 10),
85
- disableCarousel = $adUnit.find('input[name=disable-carousel]').length || rows || columns;
86
-
87
- if (columns) {
88
- var productContainerMinWidth = columns * (CONSTANTS.productMinWidth + CONSTANTS.productMargin) + 'px';
89
- $adUnit.css('min-width', productContainerMinWidth);
90
- $productContainer.css('min-width', productContainerMinWidth);
91
- $products.filter(':nth-child(' + columns + 'n + 1)').css('clear', 'both');
92
- }
93
-
94
- if (rows && columns) {
95
- var cutOffIndex = (rows * columns) - 1;
96
- $products.filter(':gt(' + cutOffIndex + ')').remove();
97
- }
98
-
99
- function updateLayout() {
100
- var wrapperWidth = $wrapper.width(),
101
- possibleColumns = columns || parseInt(wrapperWidth / (CONSTANTS.productMinWidth + CONSTANTS.productMargin), 10),
102
- actualColumns = columns || possibleColumns < productCount ? possibleColumns : productCount,
103
- productWidth = parseInt(wrapperWidth / actualColumns, 10) - CONSTANTS.productMargin;
104
-
105
- $products.css('width', productWidth + 'px');
106
-
107
- if (!disableCarousel) {
108
- if ((productCount * productWidth > wrapperWidth) && actualColumns !== 1) {
109
- $btnNext.css('visibility', 'visible').removeClass('disabled').unbind('click');
110
- $btnPrev.css('visibility', 'visible').removeClass('disabled').unbind('click');
111
- $productContainer.jCarouselLite({
112
- btnNext : '#' + $adUnit.attr('id') + ' .aalb-pa-btn-next',
113
- btnPrev : '#' + $adUnit.attr('id') + ' .aalb-pa-btn-prev',
114
- visible : actualColumns,
115
- circular : false
116
- });
117
- } else {
118
- $productContainer.css('width', 'auto');
119
- $productList.css('width', 'auto');
120
- $btnNext.css('visibility', 'hidden').unbind('click');
121
- $btnPrev.css('visibility', 'hidden').unbind('click');
122
- }
123
- }
124
- }
125
-
126
- updateLayout();
127
- jQuery(window).resize(updateLayout);
128
- });
129
- });
130
-
131
- /*!
132
- * jCarouselLite - v1.1 - 2014-09-28
133
- * http://www.gmarwaha.com/jquery/jcarousellite/
134
- * Copyright (c) 2014 Ganeshji Marwaha
135
- * Licensed MIT (https://github.com/ganeshmax/jcarousellite/blob/master/LICENSE)
136
- */
137
-
138
- !function(a){a.jCarouselLite={version:"1.1"},a.fn.jCarouselLite=function(b){return b=a.extend({},a.fn.jCarouselLite.options,b||{}),this.each(function(){function c(a){return n||(clearTimeout(A),z=a,b.beforeStart&&b.beforeStart.call(this,i()),b.circular?j(a):k(a),m({start:function(){n=!0},done:function(){b.afterEnd&&b.afterEnd.call(this,i()),b.auto&&h(),n=!1}}),b.circular||l()),!1}function d(){if(n=!1,o=b.vertical?"top":"left",p=b.vertical?"height":"width",q=B.find(">ul"),r=q.find(">li"),x=r.size(),w=x<b.visible?x:b.visible,b.circular){var c=r.slice(x-w).clone(),d=r.slice(0,w).clone();q.prepend(c).append(d),b.start+=w}s=a("li",q),y=s.size(),z=b.start}function e(){B.css("visibility","visible"),s.css({overflow:"hidden","float":b.vertical?"none":"left"}),q.css({margin:"0",padding:"0",position:"relative","list-style":"none","z-index":"1"}),B.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"}),!b.circular&&b.btnPrev&&0==b.start&&a(b.btnPrev).addClass("disabled")}function f(){t=b.vertical?s.outerHeight(!0):s.outerWidth(!0),u=t*y,v=t*w,s.css({width:s.width(),height:s.height()}),q.css(p,u+"px").css(o,-(z*t)),B.css(p,v+"px")}function g(){b.btnPrev&&a(b.btnPrev).click(function(){return c(z-b.scroll)}),b.btnNext&&a(b.btnNext).click(function(){return c(z+b.scroll)}),b.btnGo&&a.each(b.btnGo,function(d,e){a(e).click(function(){return c(b.circular?w+d:d)})}),b.mouseWheel&&B.mousewheel&&B.mousewheel(function(a,d){return c(d>0?z-b.scroll:z+b.scroll)}),b.auto&&h()}function h(){A=setTimeout(function(){c(z+b.scroll)},b.auto)}function i(){return s.slice(z).slice(0,w)}function j(a){var c;a<=b.start-w-1?(c=a+x+b.scroll,q.css(o,-(c*t)+"px"),z=c-b.scroll):a>=y-w+1&&(c=a-x-b.scroll,q.css(o,-(c*t)+"px"),z=c+b.scroll)}function k(a){0>a?z=0:a>y-w&&(z=y-w)}function l(){a(b.btnPrev+","+b.btnNext).removeClass("disabled"),a(z-b.scroll<0&&b.btnPrev||z+b.scroll>y-w&&b.btnNext||[]).addClass("disabled")}function m(c){n=!0,q.animate("left"==o?{left:-(z*t)}:{top:-(z*t)},a.extend({duration:b.speed,easing:b.easing},c))}var n,o,p,q,r,s,t,u,v,w,x,y,z,A,B=a(this);d(),e(),f(),g()})},a.fn.jCarouselLite.options={btnPrev:null,btnNext:null,btnGo:null,mouseWheel:!1,auto:null,speed:200,easing:null,vertical:!1,circular:!0,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null}}(jQuery);
139
-
140
-
141
- </script>
1
+ {{#Items}} <!--Section tag for iterating through the list of items-->
2
+ <!-- Single product Ad Template Layout. Position of the Ad can be configured by specifying pull-left or pull-right class below-->
3
+ <div class="aalb-pa-ad-unit pull-left" id="{{ID}}">
4
+ <div class="aalb-pa-wrapper">
5
+ <div class="aalb-pa-product-container">
6
+ <ul class="aalb-pa-product-list">
7
+ {{#Item}} <!-- Section tag for beginning of information on one item -->
8
+ {{#aalb}} <!-- Section tag for picking up information on attributes for the item -->
9
+ <li class="aalb-pa-product">
10
+ <div class="aalb-pa-product-image">
11
+ <div class="aalb-pa-product-image-wrapper">
12
+ <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow"> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
13
+ <img src="{{MediumImageURL}}" srcset="{{LargeImageURL}}" alt="{{Title}}" />
14
+ {{#SavingPercent}} <!-- The section tag ensures that percentage savings is displayed only if it is available -->
15
+ <span class="aalb-pa-percent-off">
16
+ -{{SavingPercent}}%
17
+ </span>
18
+ {{/SavingPercent}}
19
+ </a>
20
+ </div>
21
+ </div>
22
+ <div class="aalb-pa-product-details">
23
+ <div class="aalb-pa-product-title">
24
+ <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow">
25
+ {{Title}}
26
+ </a>
27
+ </div>
28
+ <div class="aalb-pa-product-offer-price">
29
+ <!-- The section tag for different marketplaces ensures localization of static text. -->
30
+ {{#MarketplaceUS}}Price{{/MarketplaceUS}}{{#MarketplaceFR}}Prix{{/MarketplaceFR}}{{#MarketplaceIT}}Prezzo{{/MarketplaceIT}}{{#MarketplaceDE}}Preis{{/MarketplaceDE}}{{#MarketplaceES}}Precio{{/MarketplaceES}}{{#MarketplaceBR}}Price{{/MarketplaceBR}}{{#MarketplaceCA}}Price{{/MarketplaceCA}}{{#MarketplaceCN}}Price{{/MarketplaceCN}}{{#MarketplaceIN}}Price{{/MarketplaceIN}}{{#MarketplaceJP}}Price{{/MarketplaceJP}}{{#MarketplaceMX}}Price{{/MarketplaceMX}}{{#MarketplaceUK}}Price{{/MarketplaceUK}}: <span class="aalb-pa-product-offer-price-value">{{CurrentPrice}}</span>
31
+ </div>
32
+ {{#StrikePrice}} <!-- The section tag ensures that strike price is displayed only if it is available -->
33
+ <div class="aalb-pa-product-list-price">
34
+ <!-- The section tag for different marketplaces ensures localization of static text. -->
35
+ {{#MarketplaceUS}}Was{{/MarketplaceUS}}{{#MarketplaceFR}}Ancien prix{{/MarketplaceFR}}{{#MarketplaceIT}}Da{{/MarketplaceIT}}{{#MarketplaceDE}}statt{{/MarketplaceDE}}{{#MarketplaceES}}Precio recomendado{{/MarketplaceES}}{{#MarketplaceBR}}Was{{/MarketplaceBR}}{{#MarketplaceCA}}Was{{/MarketplaceCA}}{{#MarketplaceCN}}Was{{/MarketplaceCN}}{{#MarketplaceIN}}Was{{/MarketplaceIN}}{{#MarketplaceJP}}Was{{/MarketplaceJP}}{{#MarketplaceMX}}Was{{/MarketplaceMX}}{{#MarketplaceUK}}Was{{/MarketplaceUK}}: <span class="aalb-pa-product-list-price-value">{{StrikePrice}}</span>
36
+ </div>
37
+ {{/StrikePrice}}
38
+ {{#Prime}} <!-- The section tag ensures that prime icon is displayed only if it is available -->
39
+ <div class="aalb-pa-product-prime-icon">
40
+ {{#MarketplaceES}} <!-- Display Prime Icon for ES if marketplace is ES -->
41
+ <i class="icon-prime-es"></i>
42
+ {{/MarketplaceES}}
43
+ {{^MarketplaceES}} <!-- Display Common Prime Icon for all other marketplaces -->
44
+ <i class="icon-prime-all"></i>
45
+ {{/MarketplaceES}}
46
+ </div>
47
+ {{/Prime}}
48
+ </div>
49
+ </li>
50
+ {{/aalb}}
51
+ {{/Item}}
52
+ </ul>
53
+ </div>
54
+ </div>
55
+ <a href="javascript:void(0);" class="aalb-pa-btn-prev">‹</a>
56
+ <a href="javascript:void(0);" class="aalb-pa-btn-next">›</a>
57
+ </div>
58
+ {{/Items}}
59
+
60
+ <script>
61
+ jQuery(document).ready(function() {
62
+
63
+ var CONSTANTS = {
64
+ productMinWidth : 185,
65
+ productMargin : 20
66
+ };
67
+
68
+ var $adUnits = jQuery('.aalb-pa-ad-unit');
69
+ $adUnits.each(function() {
70
+ var $adUnit = jQuery(this),
71
+ $wrapper = $adUnit.find('.aalb-pa-wrapper'),
72
+ $productContainer = $adUnit.find('.aalb-pa-product-container'),
73
+ $btnNext = $adUnit.find('.aalb-pa-btn-next'),
74
+ $btnPrev = $adUnit.find('.aalb-pa-btn-prev'),
75
+ $productList = $productContainer.find('.aalb-pa-product-list'),
76
+ $products = $productList.find('.aalb-pa-product'),
77
+ productCount = $products.length;
78
+
79
+ if (!productCount) {
80
+ return true;
81
+ }
82
+
83
+ var rows = $adUnit.find('input[name=rows]').length && parseInt($adUnit.find('input[name=rows]').val(), 10),
84
+ columns = $adUnit.find('input[name=columns]').length && parseInt($adUnit.find('input[name=columns]').val(), 10),
85
+ disableCarousel = $adUnit.find('input[name=disable-carousel]').length || rows || columns;
86
+
87
+ if (columns) {
88
+ var productContainerMinWidth = columns * (CONSTANTS.productMinWidth + CONSTANTS.productMargin) + 'px';
89
+ $adUnit.css('min-width', productContainerMinWidth);
90
+ $productContainer.css('min-width', productContainerMinWidth);
91
+ $products.filter(':nth-child(' + columns + 'n + 1)').css('clear', 'both');
92
+ }
93
+
94
+ if (rows && columns) {
95
+ var cutOffIndex = (rows * columns) - 1;
96
+ $products.filter(':gt(' + cutOffIndex + ')').remove();
97
+ }
98
+
99
+ function updateLayout() {
100
+ var wrapperWidth = $wrapper.width(),
101
+ possibleColumns = columns || parseInt(wrapperWidth / (CONSTANTS.productMinWidth + CONSTANTS.productMargin), 10),
102
+ actualColumns = columns || possibleColumns < productCount ? possibleColumns : productCount,
103
+ productWidth = parseInt(wrapperWidth / actualColumns, 10) - CONSTANTS.productMargin;
104
+
105
+ $products.css('width', productWidth + 'px');
106
+
107
+ if (!disableCarousel) {
108
+ if ((productCount * productWidth > wrapperWidth) && actualColumns !== 1) {
109
+ $btnNext.css('visibility', 'visible').removeClass('disabled').unbind('click');
110
+ $btnPrev.css('visibility', 'visible').removeClass('disabled').unbind('click');
111
+ $productContainer.jCarouselLite({
112
+ btnNext : '#' + $adUnit.attr('id') + ' .aalb-pa-btn-next',
113
+ btnPrev : '#' + $adUnit.attr('id') + ' .aalb-pa-btn-prev',
114
+ visible : actualColumns,
115
+ circular : false
116
+ });
117
+ } else {
118
+ $productContainer.css('width', 'auto');
119
+ $productList.css('width', 'auto');
120
+ $btnNext.css('visibility', 'hidden').unbind('click');
121
+ $btnPrev.css('visibility', 'hidden').unbind('click');
122
+ }
123
+ }
124
+ }
125
+
126
+ updateLayout();
127
+ jQuery(window).resize(updateLayout);
128
+ });
129
+ });
130
+
131
+ /*!
132
+ * jCarouselLite - v1.1 - 2014-09-28
133
+ * http://www.gmarwaha.com/jquery/jcarousellite/
134
+ * Copyright (c) 2014 Ganeshji Marwaha
135
+ * Licensed MIT (https://github.com/ganeshmax/jcarousellite/blob/master/LICENSE)
136
+ */
137
+
138
+ !function(a){a.jCarouselLite={version:"1.1"},a.fn.jCarouselLite=function(b){return b=a.extend({},a.fn.jCarouselLite.options,b||{}),this.each(function(){function c(a){return n||(clearTimeout(A),z=a,b.beforeStart&&b.beforeStart.call(this,i()),b.circular?j(a):k(a),m({start:function(){n=!0},done:function(){b.afterEnd&&b.afterEnd.call(this,i()),b.auto&&h(),n=!1}}),b.circular||l()),!1}function d(){if(n=!1,o=b.vertical?"top":"left",p=b.vertical?"height":"width",q=B.find(">ul"),r=q.find(">li"),x=r.size(),w=x<b.visible?x:b.visible,b.circular){var c=r.slice(x-w).clone(),d=r.slice(0,w).clone();q.prepend(c).append(d),b.start+=w}s=a("li",q),y=s.size(),z=b.start}function e(){B.css("visibility","visible"),s.css({overflow:"hidden","float":b.vertical?"none":"left"}),q.css({margin:"0",padding:"0",position:"relative","list-style":"none","z-index":"1"}),B.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"}),!b.circular&&b.btnPrev&&0==b.start&&a(b.btnPrev).addClass("disabled")}function f(){t=b.vertical?s.outerHeight(!0):s.outerWidth(!0),u=t*y,v=t*w,s.css({width:s.width(),height:s.height()}),q.css(p,u+"px").css(o,-(z*t)),B.css(p,v+"px")}function g(){b.btnPrev&&a(b.btnPrev).click(function(){return c(z-b.scroll)}),b.btnNext&&a(b.btnNext).click(function(){return c(z+b.scroll)}),b.btnGo&&a.each(b.btnGo,function(d,e){a(e).click(function(){return c(b.circular?w+d:d)})}),b.mouseWheel&&B.mousewheel&&B.mousewheel(function(a,d){return c(d>0?z-b.scroll:z+b.scroll)}),b.auto&&h()}function h(){A=setTimeout(function(){c(z+b.scroll)},b.auto)}function i(){return s.slice(z).slice(0,w)}function j(a){var c;a<=b.start-w-1?(c=a+x+b.scroll,q.css(o,-(c*t)+"px"),z=c-b.scroll):a>=y-w+1&&(c=a-x-b.scroll,q.css(o,-(c*t)+"px"),z=c+b.scroll)}function k(a){0>a?z=0:a>y-w&&(z=y-w)}function l(){a(b.btnPrev+","+b.btnNext).removeClass("disabled"),a(z-b.scroll<0&&b.btnPrev||z+b.scroll>y-w&&b.btnNext||[]).addClass("disabled")}function m(c){n=!0,q.animate("left"==o?{left:-(z*t)}:{top:-(z*t)},a.extend({duration:b.speed,easing:b.easing},c))}var n,o,p,q,r,s,t,u,v,w,x,y,z,A,B=a(this);d(),e(),f(),g()})},a.fn.jCarouselLite.options={btnPrev:null,btnNext:null,btnGo:null,mouseWheel:!1,auto:null,speed:200,easing:null,vertical:!1,circular:!0,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null}}(jQuery);
139
+
140
+
141
+ </script>
template/ProductCarousel.css CHANGED
@@ -1,261 +1,261 @@
1
- .aalb-pc-ad-unit {
2
- /*Enable this border property to have a border around the ad unit*/
3
- /*border: 1px solid #d4d4c4;*/
4
- background: #ffffff;
5
- }
6
-
7
- /* Actual styles start below */
8
- .aalb-pc-ad-unit {
9
- position: relative;
10
- overflow: hidden;
11
- padding: 22px 40px;
12
- }
13
-
14
- .aalb-pc-ad-unit * {
15
- box-sizing: content-box;
16
- box-shadow: none;
17
- font-family: Arial, Helvetica, sans-serif;
18
- margin: 0;
19
- margin-bottom: 0;
20
- margin-left: 0;
21
- margin-right: 0;
22
- margin-top: 0;
23
- outline: 0;
24
- padding: 0;
25
- padding-bottom: 0;
26
- padding-left: 0;
27
- padding-right: 0;
28
- padding-top: 0;
29
- }
30
-
31
- .aalb-pc-ad-unit.pull-left {
32
- float: left;
33
- }
34
-
35
- .aalb-pc-ad-unit.pull-right {
36
- float: right;
37
- }
38
-
39
- .aalb-pc-ad-unit.pull-left .aalb-pc-product, .aalb-pc-ad-unit.pull-right .aalb-pc-product {
40
- width: 185px !important;
41
- }
42
-
43
- .aalb-pc-ad-unit a {
44
- box-shadow: none !important;
45
- }
46
-
47
- .aalb-pc-ad-unit a:hover {
48
- color: #c45500;
49
- }
50
-
51
- .aalb-pc-ad-unit .aalb-pc-ad-header {
52
- padding-left: 3px;
53
- padding-bottom: 9px;
54
- font-size: 17px;
55
- font-weight: normal;
56
- color: #111111;
57
- }
58
-
59
- .aalb-pc-ad-unit .aalb-pc-product-list {
60
- /* Remove the border-top to remove the horizontal line after the Ad Header*/
61
- border-top: 2px solid #f7f7f7;
62
- overflow: hidden;
63
- }
64
-
65
- .aalb-pc-ad-unit .aalb-pc-product {
66
- min-width: 185px;
67
- max-width: 385px;
68
- height: auto !important;
69
- padding-top: 22px;
70
- padding-bottom: 22px;
71
- margin-left: 10px;
72
- margin-right: 10px;
73
- float: left;
74
- list-style: none;
75
- text-align: center;
76
- }
77
-
78
- .aalb-pc-ad-unit .aalb-pc-product-image {
79
- display: table;
80
- width: 150px;
81
- height: 150px;
82
- margin: 0 auto;
83
- text-align: center;
84
- }
85
-
86
- .aalb-pc-ad-unit .aalb-pc-product-image-wrapper {
87
- display: table-cell;
88
- vertical-align: middle;
89
- }
90
-
91
- .aalb-pc-ad-unit .aalb-pc-product-image a {
92
- position: relative;
93
- display: inline-block;
94
- vertical-align: middle;
95
- }
96
-
97
- .aalb-pc-ad-unit .aalb-pc-product-image img {
98
- max-width: 150px;
99
- max-height: 150px;
100
- vertical-align: bottom;
101
- }
102
-
103
- .aalb-pc-ad-unit .aalb-pc-percent-off {
104
- display: block;
105
- width: 32px;
106
- height: 27px;
107
- padding-top: 5px;
108
- position: absolute;
109
- top: -16px;
110
- right: -16px;
111
- color: #ffffff;
112
- font-size: 12px;
113
- text-align: center;
114
- -webkit-border-radius: 50%;
115
- -moz-border-radius: 50%;
116
- -ms-border-radius: 50%;
117
- border-radius: 50%;
118
- background-color: #a50200;
119
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
120
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
121
- }
122
-
123
- .aalb-pc-ad-unit.hide-percent-off-badge .aalb-pc-percent-off {
124
- display: none;
125
- }
126
-
127
- .aalb-pc-ad-unit .aalb-pc-product-details {
128
- display: inline-block;
129
- max-width: 100%;
130
- margin-top: 11px;
131
- text-align: left;
132
- }
133
-
134
- .aalb-pc-ad-unit .aalb-pc-product-title a {
135
- display: block;
136
- width: 100%;
137
- overflow: hidden;
138
- white-space: nowrap;
139
- text-overflow: ellipsis;
140
- font-size: 13px;
141
- color: #111111;
142
- text-decoration: none;
143
- }
144
-
145
- .aalb-pc-ad-unit.no-truncate .aalb-pc-product-title a {
146
- text-overflow: initial;
147
- white-space: initial;
148
- }
149
-
150
- .aalb-pc-ad-unit .aalb-pc-product-offer-price {
151
- font-size: 13px;
152
- color: #111111;
153
- }
154
-
155
- .aalb-pc-ad-unit .aalb-pc-product-offer-price-value {
156
- color: #AB1700;
157
- font-weight: bold;
158
- }
159
-
160
- .aalb-pc-ad-unit .aalb-pc-product-list-price {
161
- font-size: 13px;
162
- color: #565656;
163
- }
164
-
165
- .aalb-pc-ad-unit .aalb-pc-product-list-price-value {
166
- text-decoration: line-through;
167
- }
168
-
169
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
170
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
171
- display: inline-block;
172
- margin-top: -1px;
173
- vertical-align: middle;
174
- background-position: -205px -246px;
175
- width: 47px;
176
- height: 15px;
177
- }
178
-
179
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
180
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
181
- display: inline-block;
182
- margin-top: -1px;
183
- vertical-align: middle;
184
- background-position: -205px -274px;
185
- width: 62px;
186
- height: 16px;
187
- }
188
-
189
- .aalb-pc-ad-unit .aalb-pc-product-offer-price,
190
- .aalb-pc-ad-unit .aalb-pc-product-list-price,
191
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon {
192
- display: inline-block;
193
- margin-right: 2px;
194
- }
195
-
196
- .aalb-pc-ad-unit .aalb-pc-btn-prev,
197
- .aalb-pc-ad-unit .aalb-pc-btn-next {
198
- position: absolute;
199
- top: 50%;
200
- margin-top: -52px;
201
- display: block;
202
- visibility: hidden;
203
- width: 43px;
204
- height: 105px;
205
- z-index: 2;
206
- line-height: 105px;
207
- background: #ffffff;
208
- color: #D0D0D0;
209
- font-size: 35px;
210
- text-align: center;
211
- text-decoration: none;
212
- border: 1px solid #e9e9e9;
213
- -webkit-box-shadow: 0 0 4px #e9e9e9;
214
- box-shadow: 0 0 4px #e9e9e9;
215
- }
216
-
217
- .aalb-pc-ad-unit .aalb-pc-btn-prev:hover,
218
- .aalb-pc-ad-unit .aalb-pc-btn-next:hover {
219
- color: #999999;
220
- }
221
-
222
- .aalb-pc-ad-unit .aalb-pc-btn-prev:focus,
223
- .aalb-pc-ad-unit .aalb-pc-btn-next:focus {
224
- outline: none;
225
- }
226
-
227
- .aalb-pc-ad-unit .aalb-pc-btn-prev {
228
- left: 0;
229
- border-left: 0;
230
- border-top-right-radius: 20px;
231
- border-bottom-right-radius: 20px;
232
- }
233
-
234
- .aalb-pc-ad-unit .aalb-pc-btn-next {
235
- right: 0;
236
- border-right: 0;
237
- border-top-left-radius: 20px;
238
- border-bottom-left-radius: 20px;
239
- }
240
-
241
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
243
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
244
- display: inline-block;
245
- margin-top: -1px;
246
- vertical-align: middle;
247
- background-position: -205px -246px;
248
- width: 47px;
249
- height: 15px;
250
- }
251
-
252
- .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
253
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
254
- display: inline-block;
255
- margin-top: -1px;
256
- vertical-align: middle;
257
- background-position: -205px -274px;
258
- width: 62px;
259
- height: 16px;
260
- }
261
- }
1
+ .aalb-pc-ad-unit {
2
+ /*Enable this border property to have a border around the ad unit*/
3
+ /*border: 1px solid #d4d4c4;*/
4
+ background: #ffffff;
5
+ }
6
+
7
+ /* Actual styles start below */
8
+ .aalb-pc-ad-unit {
9
+ position: relative;
10
+ overflow: hidden;
11
+ padding: 22px 40px;
12
+ }
13
+
14
+ .aalb-pc-ad-unit * {
15
+ box-sizing: content-box;
16
+ box-shadow: none;
17
+ font-family: Arial, Helvetica, sans-serif;
18
+ margin: 0;
19
+ margin-bottom: 0;
20
+ margin-left: 0;
21
+ margin-right: 0;
22
+ margin-top: 0;
23
+ outline: 0;
24
+ padding: 0;
25
+ padding-bottom: 0;
26
+ padding-left: 0;
27
+ padding-right: 0;
28
+ padding-top: 0;
29
+ }
30
+
31
+ .aalb-pc-ad-unit.pull-left {
32
+ float: left;
33
+ }
34
+
35
+ .aalb-pc-ad-unit.pull-right {
36
+ float: right;
37
+ }
38
+
39
+ .aalb-pc-ad-unit.pull-left .aalb-pc-product, .aalb-pc-ad-unit.pull-right .aalb-pc-product {
40
+ width: 185px !important;
41
+ }
42
+
43
+ .aalb-pc-ad-unit a {
44
+ box-shadow: none !important;
45
+ }
46
+
47
+ .aalb-pc-ad-unit a:hover {
48
+ color: #c45500;
49
+ }
50
+
51
+ .aalb-pc-ad-unit .aalb-pc-ad-header {
52
+ padding-left: 3px;
53
+ padding-bottom: 9px;
54
+ font-size: 17px;
55
+ font-weight: normal;
56
+ color: #111111;
57
+ }
58
+
59
+ .aalb-pc-ad-unit .aalb-pc-product-list {
60
+ /* Remove the border-top to remove the horizontal line after the Ad Header*/
61
+ border-top: 2px solid #f7f7f7;
62
+ overflow: hidden;
63
+ }
64
+
65
+ .aalb-pc-ad-unit .aalb-pc-product {
66
+ min-width: 185px;
67
+ max-width: 385px;
68
+ height: auto !important;
69
+ padding-top: 22px;
70
+ padding-bottom: 22px;
71
+ margin-left: 10px;
72
+ margin-right: 10px;
73
+ float: left;
74
+ list-style: none;
75
+ text-align: center;
76
+ }
77
+
78
+ .aalb-pc-ad-unit .aalb-pc-product-image {
79
+ display: table;
80
+ width: 150px;
81
+ height: 150px;
82
+ margin: 0 auto;
83
+ text-align: center;
84
+ }
85
+
86
+ .aalb-pc-ad-unit .aalb-pc-product-image-wrapper {
87
+ display: table-cell;
88
+ vertical-align: middle;
89
+ }
90
+
91
+ .aalb-pc-ad-unit .aalb-pc-product-image a {
92
+ position: relative;
93
+ display: inline-block;
94
+ vertical-align: middle;
95
+ }
96
+
97
+ .aalb-pc-ad-unit .aalb-pc-product-image img {
98
+ max-width: 150px;
99
+ max-height: 150px;
100
+ vertical-align: bottom;
101
+ }
102
+
103
+ .aalb-pc-ad-unit .aalb-pc-percent-off {
104
+ display: block;
105
+ width: 32px;
106
+ height: 27px;
107
+ padding-top: 5px;
108
+ position: absolute;
109
+ top: -16px;
110
+ right: -16px;
111
+ color: #ffffff;
112
+ font-size: 12px;
113
+ text-align: center;
114
+ -webkit-border-radius: 50%;
115
+ -moz-border-radius: 50%;
116
+ -ms-border-radius: 50%;
117
+ border-radius: 50%;
118
+ background-color: #a50200;
119
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
120
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
121
+ }
122
+
123
+ .aalb-pc-ad-unit.hide-percent-off-badge .aalb-pc-percent-off {
124
+ display: none;
125
+ }
126
+
127
+ .aalb-pc-ad-unit .aalb-pc-product-details {
128
+ display: inline-block;
129
+ max-width: 100%;
130
+ margin-top: 11px;
131
+ text-align: left;
132
+ }
133
+
134
+ .aalb-pc-ad-unit .aalb-pc-product-title a {
135
+ display: block;
136
+ width: 100%;
137
+ overflow: hidden;
138
+ white-space: nowrap;
139
+ text-overflow: ellipsis;
140
+ font-size: 13px;
141
+ color: #111111;
142
+ text-decoration: none;
143
+ }
144
+
145
+ .aalb-pc-ad-unit.no-truncate .aalb-pc-product-title a {
146
+ text-overflow: initial;
147
+ white-space: initial;
148
+ }
149
+
150
+ .aalb-pc-ad-unit .aalb-pc-product-offer-price {
151
+ font-size: 13px;
152
+ color: #111111;
153
+ }
154
+
155
+ .aalb-pc-ad-unit .aalb-pc-product-offer-price-value {
156
+ color: #AB1700;
157
+ font-weight: bold;
158
+ }
159
+
160
+ .aalb-pc-ad-unit .aalb-pc-product-list-price {
161
+ font-size: 13px;
162
+ color: #565656;
163
+ }
164
+
165
+ .aalb-pc-ad-unit .aalb-pc-product-list-price-value {
166
+ text-decoration: line-through;
167
+ }
168
+
169
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
170
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
171
+ display: inline-block;
172
+ margin-top: -1px;
173
+ vertical-align: middle;
174
+ background-position: -205px -246px;
175
+ width: 47px;
176
+ height: 15px;
177
+ }
178
+
179
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
180
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
181
+ display: inline-block;
182
+ margin-top: -1px;
183
+ vertical-align: middle;
184
+ background-position: -205px -274px;
185
+ width: 62px;
186
+ height: 16px;
187
+ }
188
+
189
+ .aalb-pc-ad-unit .aalb-pc-product-offer-price,
190
+ .aalb-pc-ad-unit .aalb-pc-product-list-price,
191
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon {
192
+ display: inline-block;
193
+ margin-right: 2px;
194
+ }
195
+
196
+ .aalb-pc-ad-unit .aalb-pc-btn-prev,
197
+ .aalb-pc-ad-unit .aalb-pc-btn-next {
198
+ position: absolute;
199
+ top: 50%;
200
+ margin-top: -52px;
201
+ display: block;
202
+ visibility: hidden;
203
+ width: 43px;
204
+ height: 105px;
205
+ z-index: 2;
206
+ line-height: 105px;
207
+ background: #ffffff;
208
+ color: #D0D0D0;
209
+ font-size: 35px;
210
+ text-align: center;
211
+ text-decoration: none;
212
+ border: 1px solid #e9e9e9;
213
+ -webkit-box-shadow: 0 0 4px #e9e9e9;
214
+ box-shadow: 0 0 4px #e9e9e9;
215
+ }
216
+
217
+ .aalb-pc-ad-unit .aalb-pc-btn-prev:hover,
218
+ .aalb-pc-ad-unit .aalb-pc-btn-next:hover {
219
+ color: #999999;
220
+ }
221
+
222
+ .aalb-pc-ad-unit .aalb-pc-btn-prev:focus,
223
+ .aalb-pc-ad-unit .aalb-pc-btn-next:focus {
224
+ outline: none;
225
+ }
226
+
227
+ .aalb-pc-ad-unit .aalb-pc-btn-prev {
228
+ left: 0;
229
+ border-left: 0;
230
+ border-top-right-radius: 20px;
231
+ border-bottom-right-radius: 20px;
232
+ }
233
+
234
+ .aalb-pc-ad-unit .aalb-pc-btn-next {
235
+ right: 0;
236
+ border-right: 0;
237
+ border-top-left-radius: 20px;
238
+ border-bottom-left-radius: 20px;
239
+ }
240
+
241
+ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-all {
243
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
244
+ display: inline-block;
245
+ margin-top: -1px;
246
+ vertical-align: middle;
247
+ background-position: -205px -246px;
248
+ width: 47px;
249
+ height: 15px;
250
+ }
251
+
252
+ .aalb-pc-ad-unit .aalb-pc-product-prime-icon .icon-prime-es {
253
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
254
+ display: inline-block;
255
+ margin-top: -1px;
256
+ vertical-align: middle;
257
+ background-position: -205px -274px;
258
+ width: 62px;
259
+ height: 16px;
260
+ }
261
+ }
template/ProductCarousel.mustache CHANGED
@@ -1,142 +1,142 @@
1
- <!-- Ad Template with Carousel Layout-->
2
- {{#Items}} <!--Section tag for iterating through the list of items-->
3
- <div class="aalb-pc-ad-unit" id="{{ID}}">
4
- <h2 class="aalb-pc-ad-header">{{#AalbHeader}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/AalbHeader}}</h2> <!-- Title of the ad localized according to the marketplace picked from the AalbHeader tag-->
5
- <div class="aalb-pc-wrapper">
6
- <div class="aalb-pc-product-container">
7
- <ul class="aalb-pc-product-list">
8
- {{#Item}} <!-- Section tag for beginning of information on one item -->
9
- {{#aalb}} <!-- Section tag for picking up information on attributes for the item -->
10
- <li class="aalb-pc-product">
11
- <div class="aalb-pc-product-image">
12
- <div class="aalb-pc-product-image-wrapper">
13
- <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow"> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
14
- <img src="{{MediumImageURL}}" srcset="{{LargeImageURL}}" alt="{{Title}}" />
15
- {{#SavingPercent}} <!-- The section tag ensures that percentage savings is displayed only if it is available -->
16
- <span class="aalb-pc-percent-off">
17
- -{{SavingPercent}}%
18
- </span>
19
- {{/SavingPercent}}
20
- </a>
21
- </div>
22
- </div>
23
- <div class="aalb-pc-product-details">
24
- <div class="aalb-pc-product-title">
25
- <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow">
26
- {{Title}}
27
- </a>
28
- </div>
29
- <div class="aalb-pc-product-offer-price">
30
- <!-- The section tag for different marketplaces ensures localization of static text. -->
31
- {{#MarketplaceUS}}Price{{/MarketplaceUS}}{{#MarketplaceFR}}Prix{{/MarketplaceFR}}{{#MarketplaceIT}}Prezzo{{/MarketplaceIT}}{{#MarketplaceDE}}Preis{{/MarketplaceDE}}{{#MarketplaceES}}Precio{{/MarketplaceES}}{{#MarketplaceBR}}Price{{/MarketplaceBR}}{{#MarketplaceCA}}Price{{/MarketplaceCA}}{{#MarketplaceCN}}Price{{/MarketplaceCN}}{{#MarketplaceIN}}Price{{/MarketplaceIN}}{{#MarketplaceJP}}Price{{/MarketplaceJP}}{{#MarketplaceMX}}Price{{/MarketplaceMX}}{{#MarketplaceUK}}Price{{/MarketplaceUK}}: <span class="aalb-pc-product-offer-price-value">{{CurrentPrice}}</span>
32
- </div>
33
- {{#StrikePrice}} <!-- The section tag ensures that strike price is displayed only if it is available -->
34
- <div class="aalb-pc-product-list-price">
35
- <!-- The section tag for different marketplaces ensures localization of static text. -->
36
- {{#MarketplaceUS}}Was{{/MarketplaceUS}}{{#MarketplaceFR}}Ancien prix{{/MarketplaceFR}}{{#MarketplaceIT}}Da{{/MarketplaceIT}}{{#MarketplaceDE}}statt{{/MarketplaceDE}}{{#MarketplaceES}}Precio recomendado{{/MarketplaceES}}{{#MarketplaceBR}}Was{{/MarketplaceBR}}{{#MarketplaceCA}}Was{{/MarketplaceCA}}{{#MarketplaceCN}}Was{{/MarketplaceCN}}{{#MarketplaceIN}}Was{{/MarketplaceIN}}{{#MarketplaceJP}}Was{{/MarketplaceJP}}{{#MarketplaceMX}}Was{{/MarketplaceMX}}{{#MarketplaceUK}}Was{{/MarketplaceUK}}: <span class="aalb-pc-product-list-price-value">{{StrikePrice}}</span>
37
- </div>
38
- {{/StrikePrice}}
39
- {{#Prime}} <!-- The section tag ensures that prime icon is displayed only if it is available -->
40
- <div class="aalb-pc-product-prime-icon">
41
- {{#MarketplaceES}} <!-- Display Prime Icon for ES if marketplace is ES -->
42
- <i class="icon-prime-es"></i>
43
- {{/MarketplaceES}}
44
- {{^MarketplaceES}} <!-- Display Common Prime Icon for all other marketplaces -->
45
- <i class="icon-prime-all"></i>
46
- {{/MarketplaceES}}
47
- </div>
48
- {{/Prime}}
49
- </div>
50
- </li>
51
- {{/aalb}}
52
- {{/Item}}
53
- </ul>
54
- </div>
55
- </div>
56
- <a href="javascript:void(0);" class="aalb-pc-btn-prev">‹</a>
57
- <a href="javascript:void(0);" class="aalb-pc-btn-next">›</a>
58
- </div>
59
- {{/Items}}
60
-
61
- <script>
62
- jQuery(document).ready(function() {
63
-
64
- var CONSTANTS = {
65
- productMinWidth : 185,
66
- productMargin : 20
67
- };
68
-
69
- var $adUnits = jQuery('.aalb-pc-ad-unit');
70
- $adUnits.each(function() {
71
- var $adUnit = jQuery(this),
72
- $wrapper = $adUnit.find('.aalb-pc-wrapper'),
73
- $productContainer = $adUnit.find('.aalb-pc-product-container'),
74
- $btnNext = $adUnit.find('.aalb-pc-btn-next'),
75
- $btnPrev = $adUnit.find('.aalb-pc-btn-prev'),
76
- $productList = $productContainer.find('.aalb-pc-product-list'),
77
- $products = $productList.find('.aalb-pc-product'),
78
- productCount = $products.length;
79
-
80
- if (!productCount) {
81
- return true;
82
- }
83
-
84
- var rows = $adUnit.find('input[name=rows]').length && parseInt($adUnit.find('input[name=rows]').val(), 10),
85
- columns = $adUnit.find('input[name=columns]').length && parseInt($adUnit.find('input[name=columns]').val(), 10),
86
- disableCarousel = $adUnit.find('input[name=disable-carousel]').length || rows || columns;
87
-
88
- if (columns) {
89
- var productContainerMinWidth = columns * (CONSTANTS.productMinWidth + CONSTANTS.productMargin) + 'px';
90
- $adUnit.css('min-width', productContainerMinWidth);
91
- $productContainer.css('min-width', productContainerMinWidth);
92
- $products.filter(':nth-child(' + columns + 'n + 1)').css('clear', 'both');
93
- }
94
-
95
- if (rows && columns) {
96
- var cutOffIndex = (rows * columns) - 1;
97
- $products.filter(':gt(' + cutOffIndex + ')').remove();
98
- }
99
-
100
- function updateLayout() {
101
- var wrapperWidth = $wrapper.width(),
102
- possibleColumns = columns || parseInt(wrapperWidth / (CONSTANTS.productMinWidth + CONSTANTS.productMargin), 10),
103
- actualColumns = columns || possibleColumns < productCount ? possibleColumns : productCount,
104
- productWidth = parseInt(wrapperWidth / actualColumns, 10) - CONSTANTS.productMargin;
105
-
106
- $products.css('width', productWidth + 'px');
107
-
108
- if (!disableCarousel) {
109
- if ((productCount * productWidth > wrapperWidth) && actualColumns !== 1) {
110
- $btnNext.css('visibility', 'visible').removeClass('disabled').unbind('click');
111
- $btnPrev.css('visibility', 'visible').removeClass('disabled').unbind('click');
112
- $productContainer.jCarouselLite({
113
- btnNext : '#' + $adUnit.attr('id') + ' .aalb-pc-btn-next',
114
- btnPrev : '#' + $adUnit.attr('id') + ' .aalb-pc-btn-prev',
115
- visible : actualColumns,
116
- circular : false
117
- });
118
- } else {
119
- $productContainer.css('width', 'auto');
120
- $productList.css('width', 'auto');
121
- $btnNext.css('visibility', 'hidden').unbind('click');
122
- $btnPrev.css('visibility', 'hidden').unbind('click');
123
- }
124
- }
125
- }
126
-
127
- updateLayout();
128
- jQuery(window).resize(updateLayout);
129
- });
130
- });
131
-
132
- /*!
133
- * jCarouselLite - v1.1 - 2014-09-28
134
- * http://www.gmarwaha.com/jquery/jcarousellite/
135
- * Copyright (c) 2014 Ganeshji Marwaha
136
- * Licensed MIT (https://github.com/ganeshmax/jcarousellite/blob/master/LICENSE)
137
- */
138
-
139
- !function(a){a.jCarouselLite={version:"1.1"},a.fn.jCarouselLite=function(b){return b=a.extend({},a.fn.jCarouselLite.options,b||{}),this.each(function(){function c(a){return n||(clearTimeout(A),z=a,b.beforeStart&&b.beforeStart.call(this,i()),b.circular?j(a):k(a),m({start:function(){n=!0},done:function(){b.afterEnd&&b.afterEnd.call(this,i()),b.auto&&h(),n=!1}}),b.circular||l()),!1}function d(){if(n=!1,o=b.vertical?"top":"left",p=b.vertical?"height":"width",q=B.find(">ul"),r=q.find(">li"),x=r.size(),w=x<b.visible?x:b.visible,b.circular){var c=r.slice(x-w).clone(),d=r.slice(0,w).clone();q.prepend(c).append(d),b.start+=w}s=a("li",q),y=s.size(),z=b.start}function e(){B.css("visibility","visible"),s.css({overflow:"hidden","float":b.vertical?"none":"left"}),q.css({margin:"0",padding:"0",position:"relative","list-style":"none","z-index":"1"}),B.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"}),!b.circular&&b.btnPrev&&0==b.start&&a(b.btnPrev).addClass("disabled")}function f(){t=b.vertical?s.outerHeight(!0):s.outerWidth(!0),u=t*y,v=t*w,s.css({width:s.width(),height:s.height()}),q.css(p,u+"px").css(o,-(z*t)),B.css(p,v+"px")}function g(){b.btnPrev&&a(b.btnPrev).click(function(){return c(z-b.scroll)}),b.btnNext&&a(b.btnNext).click(function(){return c(z+b.scroll)}),b.btnGo&&a.each(b.btnGo,function(d,e){a(e).click(function(){return c(b.circular?w+d:d)})}),b.mouseWheel&&B.mousewheel&&B.mousewheel(function(a,d){return c(d>0?z-b.scroll:z+b.scroll)}),b.auto&&h()}function h(){A=setTimeout(function(){c(z+b.scroll)},b.auto)}function i(){return s.slice(z).slice(0,w)}function j(a){var c;a<=b.start-w-1?(c=a+x+b.scroll,q.css(o,-(c*t)+"px"),z=c-b.scroll):a>=y-w+1&&(c=a-x-b.scroll,q.css(o,-(c*t)+"px"),z=c+b.scroll)}function k(a){0>a?z=0:a>y-w&&(z=y-w)}function l(){a(b.btnPrev+","+b.btnNext).removeClass("disabled"),a(z-b.scroll<0&&b.btnPrev||z+b.scroll>y-w&&b.btnNext||[]).addClass("disabled")}function m(c){n=!0,q.animate("left"==o?{left:-(z*t)}:{top:-(z*t)},a.extend({duration:b.speed,easing:b.easing},c))}var n,o,p,q,r,s,t,u,v,w,x,y,z,A,B=a(this);d(),e(),f(),g()})},a.fn.jCarouselLite.options={btnPrev:null,btnNext:null,btnGo:null,mouseWheel:!1,auto:null,speed:200,easing:null,vertical:!1,circular:!0,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null}}(jQuery);
140
-
141
-
142
- </script>
1
+ <!-- Ad Template with Carousel Layout-->
2
+ {{#Items}} <!--Section tag for iterating through the list of items-->
3
+ <div class="aalb-pc-ad-unit" id="{{ID}}">
4
+ <h2 class="aalb-pc-ad-header">{{#AalbHeader}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/AalbHeader}}</h2> <!-- Title of the ad localized according to the marketplace picked from the AalbHeader tag-->
5
+ <div class="aalb-pc-wrapper">
6
+ <div class="aalb-pc-product-container">
7
+ <ul class="aalb-pc-product-list">
8
+ {{#Item}} <!-- Section tag for beginning of information on one item -->
9
+ {{#aalb}} <!-- Section tag for picking up information on attributes for the item -->
10
+ <li class="aalb-pc-product">
11
+ <div class="aalb-pc-product-image">
12
+ <div class="aalb-pc-product-image-wrapper">
13
+ <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow"> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
14
+ <img src="{{MediumImageURL}}" srcset="{{LargeImageURL}}" alt="{{Title}}" />
15
+ {{#SavingPercent}} <!-- The section tag ensures that percentage savings is displayed only if it is available -->
16
+ <span class="aalb-pc-percent-off">
17
+ -{{SavingPercent}}%
18
+ </span>
19
+ {{/SavingPercent}}
20
+ </a>
21
+ </div>
22
+ </div>
23
+ <div class="aalb-pc-product-details">
24
+ <div class="aalb-pc-product-title">
25
+ <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow">
26
+ {{Title}}
27
+ </a>
28
+ </div>
29
+ <div class="aalb-pc-product-offer-price">
30
+ <!-- The section tag for different marketplaces ensures localization of static text. -->
31
+ {{#MarketplaceUS}}Price{{/MarketplaceUS}}{{#MarketplaceFR}}Prix{{/MarketplaceFR}}{{#MarketplaceIT}}Prezzo{{/MarketplaceIT}}{{#MarketplaceDE}}Preis{{/MarketplaceDE}}{{#MarketplaceES}}Precio{{/MarketplaceES}}{{#MarketplaceBR}}Price{{/MarketplaceBR}}{{#MarketplaceCA}}Price{{/MarketplaceCA}}{{#MarketplaceCN}}Price{{/MarketplaceCN}}{{#MarketplaceIN}}Price{{/MarketplaceIN}}{{#MarketplaceJP}}Price{{/MarketplaceJP}}{{#MarketplaceMX}}Price{{/MarketplaceMX}}{{#MarketplaceUK}}Price{{/MarketplaceUK}}: <span class="aalb-pc-product-offer-price-value">{{CurrentPrice}}</span>
32
+ </div>
33
+ {{#StrikePrice}} <!-- The section tag ensures that strike price is displayed only if it is available -->
34
+ <div class="aalb-pc-product-list-price">
35
+ <!-- The section tag for different marketplaces ensures localization of static text. -->
36
+ {{#MarketplaceUS}}Was{{/MarketplaceUS}}{{#MarketplaceFR}}Ancien prix{{/MarketplaceFR}}{{#MarketplaceIT}}Da{{/MarketplaceIT}}{{#MarketplaceDE}}statt{{/MarketplaceDE}}{{#MarketplaceES}}Precio recomendado{{/MarketplaceES}}{{#MarketplaceBR}}Was{{/MarketplaceBR}}{{#MarketplaceCA}}Was{{/MarketplaceCA}}{{#MarketplaceCN}}Was{{/MarketplaceCN}}{{#MarketplaceIN}}Was{{/MarketplaceIN}}{{#MarketplaceJP}}Was{{/MarketplaceJP}}{{#MarketplaceMX}}Was{{/MarketplaceMX}}{{#MarketplaceUK}}Was{{/MarketplaceUK}}: <span class="aalb-pc-product-list-price-value">{{StrikePrice}}</span>
37
+ </div>
38
+ {{/StrikePrice}}
39
+ {{#Prime}} <!-- The section tag ensures that prime icon is displayed only if it is available -->
40
+ <div class="aalb-pc-product-prime-icon">
41
+ {{#MarketplaceES}} <!-- Display Prime Icon for ES if marketplace is ES -->
42
+ <i class="icon-prime-es"></i>
43
+ {{/MarketplaceES}}
44
+ {{^MarketplaceES}} <!-- Display Common Prime Icon for all other marketplaces -->
45
+ <i class="icon-prime-all"></i>
46
+ {{/MarketplaceES}}
47
+ </div>
48
+ {{/Prime}}
49
+ </div>
50
+ </li>
51
+ {{/aalb}}
52
+ {{/Item}}
53
+ </ul>
54
+ </div>
55
+ </div>
56
+ <a href="javascript:void(0);" class="aalb-pc-btn-prev">‹</a>
57
+ <a href="javascript:void(0);" class="aalb-pc-btn-next">›</a>
58
+ </div>
59
+ {{/Items}}
60
+
61
+ <script>
62
+ jQuery(document).ready(function() {
63
+
64
+ var CONSTANTS = {
65
+ productMinWidth : 185,
66
+ productMargin : 20
67
+ };
68
+
69
+ var $adUnits = jQuery('.aalb-pc-ad-unit');
70
+ $adUnits.each(function() {
71
+ var $adUnit = jQuery(this),
72
+ $wrapper = $adUnit.find('.aalb-pc-wrapper'),
73
+ $productContainer = $adUnit.find('.aalb-pc-product-container'),
74
+ $btnNext = $adUnit.find('.aalb-pc-btn-next'),
75
+ $btnPrev = $adUnit.find('.aalb-pc-btn-prev'),
76
+ $productList = $productContainer.find('.aalb-pc-product-list'),
77
+ $products = $productList.find('.aalb-pc-product'),
78
+ productCount = $products.length;
79
+
80
+ if (!productCount) {
81
+ return true;
82
+ }
83
+
84
+ var rows = $adUnit.find('input[name=rows]').length && parseInt($adUnit.find('input[name=rows]').val(), 10),
85
+ columns = $adUnit.find('input[name=columns]').length && parseInt($adUnit.find('input[name=columns]').val(), 10),
86
+ disableCarousel = $adUnit.find('input[name=disable-carousel]').length || rows || columns;
87
+
88
+ if (columns) {
89
+ var productContainerMinWidth = columns * (CONSTANTS.productMinWidth + CONSTANTS.productMargin) + 'px';
90
+ $adUnit.css('min-width', productContainerMinWidth);
91
+ $productContainer.css('min-width', productContainerMinWidth);
92
+ $products.filter(':nth-child(' + columns + 'n + 1)').css('clear', 'both');
93
+ }
94
+
95
+ if (rows && columns) {
96
+ var cutOffIndex = (rows * columns) - 1;
97
+ $products.filter(':gt(' + cutOffIndex + ')').remove();
98
+ }
99
+
100
+ function updateLayout() {
101
+ var wrapperWidth = $wrapper.width(),
102
+ possibleColumns = columns || parseInt(wrapperWidth / (CONSTANTS.productMinWidth + CONSTANTS.productMargin), 10),
103
+ actualColumns = columns || possibleColumns < productCount ? possibleColumns : productCount,
104
+ productWidth = parseInt(wrapperWidth / actualColumns, 10) - CONSTANTS.productMargin;
105
+
106
+ $products.css('width', productWidth + 'px');
107
+
108
+ if (!disableCarousel) {
109
+ if ((productCount * productWidth > wrapperWidth) && actualColumns !== 1) {
110
+ $btnNext.css('visibility', 'visible').removeClass('disabled').unbind('click');
111
+ $btnPrev.css('visibility', 'visible').removeClass('disabled').unbind('click');
112
+ $productContainer.jCarouselLite({
113
+ btnNext : '#' + $adUnit.attr('id') + ' .aalb-pc-btn-next',
114
+ btnPrev : '#' + $adUnit.attr('id') + ' .aalb-pc-btn-prev',
115
+ visible : actualColumns,
116
+ circular : false
117
+ });
118
+ } else {
119
+ $productContainer.css('width', 'auto');
120
+ $productList.css('width', 'auto');
121
+ $btnNext.css('visibility', 'hidden').unbind('click');
122
+ $btnPrev.css('visibility', 'hidden').unbind('click');
123
+ }
124
+ }
125
+ }
126
+
127
+ updateLayout();
128
+ jQuery(window).resize(updateLayout);
129
+ });
130
+ });
131
+
132
+ /*!
133
+ * jCarouselLite - v1.1 - 2014-09-28
134
+ * http://www.gmarwaha.com/jquery/jcarousellite/
135
+ * Copyright (c) 2014 Ganeshji Marwaha
136
+ * Licensed MIT (https://github.com/ganeshmax/jcarousellite/blob/master/LICENSE)
137
+ */
138
+
139
+ !function(a){a.jCarouselLite={version:"1.1"},a.fn.jCarouselLite=function(b){return b=a.extend({},a.fn.jCarouselLite.options,b||{}),this.each(function(){function c(a){return n||(clearTimeout(A),z=a,b.beforeStart&&b.beforeStart.call(this,i()),b.circular?j(a):k(a),m({start:function(){n=!0},done:function(){b.afterEnd&&b.afterEnd.call(this,i()),b.auto&&h(),n=!1}}),b.circular||l()),!1}function d(){if(n=!1,o=b.vertical?"top":"left",p=b.vertical?"height":"width",q=B.find(">ul"),r=q.find(">li"),x=r.size(),w=x<b.visible?x:b.visible,b.circular){var c=r.slice(x-w).clone(),d=r.slice(0,w).clone();q.prepend(c).append(d),b.start+=w}s=a("li",q),y=s.size(),z=b.start}function e(){B.css("visibility","visible"),s.css({overflow:"hidden","float":b.vertical?"none":"left"}),q.css({margin:"0",padding:"0",position:"relative","list-style":"none","z-index":"1"}),B.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"}),!b.circular&&b.btnPrev&&0==b.start&&a(b.btnPrev).addClass("disabled")}function f(){t=b.vertical?s.outerHeight(!0):s.outerWidth(!0),u=t*y,v=t*w,s.css({width:s.width(),height:s.height()}),q.css(p,u+"px").css(o,-(z*t)),B.css(p,v+"px")}function g(){b.btnPrev&&a(b.btnPrev).click(function(){return c(z-b.scroll)}),b.btnNext&&a(b.btnNext).click(function(){return c(z+b.scroll)}),b.btnGo&&a.each(b.btnGo,function(d,e){a(e).click(function(){return c(b.circular?w+d:d)})}),b.mouseWheel&&B.mousewheel&&B.mousewheel(function(a,d){return c(d>0?z-b.scroll:z+b.scroll)}),b.auto&&h()}function h(){A=setTimeout(function(){c(z+b.scroll)},b.auto)}function i(){return s.slice(z).slice(0,w)}function j(a){var c;a<=b.start-w-1?(c=a+x+b.scroll,q.css(o,-(c*t)+"px"),z=c-b.scroll):a>=y-w+1&&(c=a-x-b.scroll,q.css(o,-(c*t)+"px"),z=c+b.scroll)}function k(a){0>a?z=0:a>y-w&&(z=y-w)}function l(){a(b.btnPrev+","+b.btnNext).removeClass("disabled"),a(z-b.scroll<0&&b.btnPrev||z+b.scroll>y-w&&b.btnNext||[]).addClass("disabled")}function m(c){n=!0,q.animate("left"==o?{left:-(z*t)}:{top:-(z*t)},a.extend({duration:b.speed,easing:b.easing},c))}var n,o,p,q,r,s,t,u,v,w,x,y,z,A,B=a(this);d(),e(),f(),g()})},a.fn.jCarouselLite.options={btnPrev:null,btnNext:null,btnGo:null,mouseWheel:!1,auto:null,speed:200,easing:null,vertical:!1,circular:!0,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null}}(jQuery);
140
+
141
+
142
+ </script>
template/ProductGrid.css CHANGED
@@ -1,261 +1,261 @@
1
- .aalb-pg-ad-unit {
2
- /*Enable this border property to have a border around the ad unit*/
3
- /*border: 1px solid #d4d4c4;*/
4
- background: #ffffff;
5
- }
6
-
7
- /* Actual styles start below */
8
- .aalb-pg-ad-unit {
9
- position: relative;
10
- overflow: hidden;
11
- padding: 22px 40px;
12
- }
13
-
14
- .aalb-pg-ad-unit * {
15
- box-sizing: content-box;
16
- box-shadow: none;
17
- font-family: Arial, Helvetica, sans-serif;
18
- margin: 0;
19
- margin-bottom: 0;
20
- margin-left: 0;
21
- margin-right: 0;
22
- margin-top: 0;
23
- outline: 0;
24
- padding: 0;
25
- padding-bottom: 0;
26
- padding-left: 0;
27
- padding-right: 0;
28
- padding-top: 0;
29
- }
30
-
31
- .aalb-pg-ad-unit.pull-left {
32
- float: left;
33
- }
34
-
35
- .aalb-pg-ad-unit.pull-right {
36
- float: right;
37
- }
38
-
39
- .aalb-pg-ad-unit.pull-left .aalb-pg-product, .aalb-pg-ad-unit.pull-right .aalb-pg-product {
40
- width: 185px !important;
41
- }
42
-
43
- .aalb-pg-ad-unit a {
44
- box-shadow: none !important;
45
- }
46
-
47
- .aalb-pg-ad-unit a:hover {
48
- color: #c45500;
49
- }
50
-
51
- .aalb-pg-ad-unit .aalb-pg-ad-header {
52
- padding-left: 3px;
53
- padding-bottom: 9px;
54
- font-size: 17px;
55
- font-weight: normal;
56
- color: #111111;
57
- }
58
-
59
- .aalb-pg-ad-unit .aalb-pg-product-list {
60
- /* Remove the border-top to remove the horizontal line after the Ad Header*/
61
- border-top: 2px solid #f7f7f7;
62
- overflow: hidden;
63
- }
64
-
65
- .aalb-pg-ad-unit .aalb-pg-product {
66
- min-width: 185px;
67
- max-width: 385px;
68
- height: auto !important;
69
- padding-top: 22px;
70
- padding-bottom: 22px;
71
- margin-left: 10px;
72
- margin-right: 10px;
73
- float: left;
74
- list-style: none;
75
- text-align: center;
76
- }
77
-
78
- .aalb-pg-ad-unit .aalb-pg-product-image {
79
- display: table;
80
- width: 150px;
81
- height: 150px;
82
- margin: 0 auto;
83
- text-align: center;
84
- }
85
-
86
- .aalb-pg-ad-unit .aalb-pg-product-image-wrapper {
87
- display: table-cell;
88
- vertical-align: middle;
89
- }
90
-
91
- .aalb-pg-ad-unit .aalb-pg-product-image a {
92
- position: relative;
93
- display: inline-block;
94
- vertical-align: middle;
95
- }
96
-
97
- .aalb-pg-ad-unit .aalb-pg-product-image img {
98
- max-width: 150px;
99
- max-height: 150px;
100
- vertical-align: bottom;
101
- }
102
-
103
- .aalb-pg-ad-unit .aalb-pg-percent-off {
104
- display: block;
105
- width: 32px;
106
- height: 27px;
107
- padding-top: 5px;
108
- position: absolute;
109
- top: -16px;
110
- right: -16px;
111
- color: #ffffff;
112
- font-size: 12px;
113
- text-align: center;
114
- -webkit-border-radius: 50%;
115
- -moz-border-radius: 50%;
116
- -ms-border-radius: 50%;
117
- border-radius: 50%;
118
- background-color: #a50200;
119
- background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
120
- background-image: linear-gradient(to bottom, #cb0400, #a50200);
121
- }
122
-
123
- .aalb-pg-ad-unit.hide-percent-off-badge .aalb-pg-percent-off {
124
- display: none;
125
- }
126
-
127
- .aalb-pg-ad-unit .aalb-pg-product-details {
128
- display: inline-block;
129
- max-width: 100%;
130
- margin-top: 11px;
131
- text-align: left;
132
- }
133
-
134
- .aalb-pg-ad-unit .aalb-pg-product-title a {
135
- display: block;
136
- width: 100%;
137
- overflow: hidden;
138
- white-space: nowrap;
139
- text-overflow: ellipsis;
140
- font-size: 13px;
141
- color: #111111;
142
- text-decoration: none;
143
- }
144
-
145
- .aalb-pg-ad-unit.no-truncate .aalb-pg-product-title a {
146
- text-overflow: initial;
147
- white-space: initial;
148
- }
149
-
150
- .aalb-pg-ad-unit .aalb-pg-product-offer-price {
151
- font-size: 13px;
152
- color: #111111;
153
- }
154
-
155
- .aalb-pg-ad-unit .aalb-pg-product-offer-price-value {
156
- color: #AB1700;
157
- font-weight: bold;
158
- }
159
-
160
- .aalb-pg-ad-unit .aalb-pg-product-list-price {
161
- font-size: 13px;
162
- color: #565656;
163
- }
164
-
165
- .aalb-pg-ad-unit .aalb-pg-product-list-price-value {
166
- text-decoration: line-through;
167
- }
168
-
169
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
170
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
171
- display: inline-block;
172
- margin-top: -1px;
173
- vertical-align: middle;
174
- background-position: -205px -246px;
175
- width: 47px;
176
- height: 16px;
177
- }
178
-
179
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
180
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
181
- display: inline-block;
182
- margin-top: -1px;
183
- vertical-align: middle;
184
- background-position: -205px -274px;
185
- width: 62px;
186
- height: 15px;
187
- }
188
-
189
- .aalb-pg-ad-unit .aalb-pg-product-offer-price,
190
- .aalb-pg-ad-unit .aalb-pg-product-list-price,
191
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon {
192
- display: inline-block;
193
- margin-right: 2px;
194
- }
195
-
196
- .aalb-pg-ad-unit .aalb-pg-btn-prev,
197
- .aalb-pg-ad-unit .aalb-pg-btn-next {
198
- position: absolute;
199
- top: 50%;
200
- margin-top: -52px;
201
- display: block;
202
- visibility: hidden;
203
- width: 43px;
204
- height: 105px;
205
- z-index: 2;
206
- line-height: 105px;
207
- background: #ffffff;
208
- color: #D0D0D0;
209
- font-size: 35px;
210
- text-align: center;
211
- text-decoration: none;
212
- border: 1px solid #e9e9e9;
213
- -webkit-box-shadow: 0 0 4px #e9e9e9;
214
- box-shadow: 0 0 4px #e9e9e9;
215
- }
216
-
217
- .aalb-pg-ad-unit .aalb-pg-btn-prev:hover,
218
- .aalb-pg-ad-unit .aalb-pg-btn-next:hover {
219
- color: #999999;
220
- }
221
-
222
- .aalb-pg-ad-unit .aalb-pg-btn-prev:focus,
223
- .aalb-pg-ad-unit .aalb-pg-btn-next:focus {
224
- outline: none;
225
- }
226
-
227
- .aalb-pg-ad-unit .aalb-pg-btn-prev {
228
- left: 0;
229
- border-left: 0;
230
- border-top-right-radius: 20px;
231
- border-bottom-right-radius: 20px;
232
- }
233
-
234
- .aalb-pg-ad-unit .aalb-pg-btn-next {
235
- right: 0;
236
- border-right: 0;
237
- border-top-left-radius: 20px;
238
- border-bottom-left-radius: 20px;
239
- }
240
-
241
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
243
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
244
- display: inline-block;
245
- margin-top: -1px;
246
- vertical-align: middle;
247
- background-position: -205px -246px;
248
- width: 47px;
249
- height: 15px;
250
- }
251
-
252
- .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
253
- background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
254
- display: inline-block;
255
- margin-top: -1px;
256
- vertical-align: middle;
257
- background-position: -205px -274px;
258
- width: 62px;
259
- height: 16px;
260
- }
261
- }
1
+ .aalb-pg-ad-unit {
2
+ /*Enable this border property to have a border around the ad unit*/
3
+ /*border: 1px solid #d4d4c4;*/
4
+ background: #ffffff;
5
+ }
6
+
7
+ /* Actual styles start below */
8
+ .aalb-pg-ad-unit {
9
+ position: relative;
10
+ overflow: hidden;
11
+ padding: 22px 40px;
12
+ }
13
+
14
+ .aalb-pg-ad-unit * {
15
+ box-sizing: content-box;
16
+ box-shadow: none;
17
+ font-family: Arial, Helvetica, sans-serif;
18
+ margin: 0;
19
+ margin-bottom: 0;
20
+ margin-left: 0;
21
+ margin-right: 0;
22
+ margin-top: 0;
23
+ outline: 0;
24
+ padding: 0;
25
+ padding-bottom: 0;
26
+ padding-left: 0;
27
+ padding-right: 0;
28
+ padding-top: 0;
29
+ }
30
+
31
+ .aalb-pg-ad-unit.pull-left {
32
+ float: left;
33
+ }
34
+
35
+ .aalb-pg-ad-unit.pull-right {
36
+ float: right;
37
+ }
38
+
39
+ .aalb-pg-ad-unit.pull-left .aalb-pg-product, .aalb-pg-ad-unit.pull-right .aalb-pg-product {
40
+ width: 185px !important;
41
+ }
42
+
43
+ .aalb-pg-ad-unit a {
44
+ box-shadow: none !important;
45
+ }
46
+
47
+ .aalb-pg-ad-unit a:hover {
48
+ color: #c45500;
49
+ }
50
+
51
+ .aalb-pg-ad-unit .aalb-pg-ad-header {
52
+ padding-left: 3px;
53
+ padding-bottom: 9px;
54
+ font-size: 17px;
55
+ font-weight: normal;
56
+ color: #111111;
57
+ }
58
+
59
+ .aalb-pg-ad-unit .aalb-pg-product-list {
60
+ /* Remove the border-top to remove the horizontal line after the Ad Header*/
61
+ border-top: 2px solid #f7f7f7;
62
+ overflow: hidden;
63
+ }
64
+
65
+ .aalb-pg-ad-unit .aalb-pg-product {
66
+ min-width: 185px;
67
+ max-width: 385px;
68
+ height: auto !important;
69
+ padding-top: 22px;
70
+ padding-bottom: 22px;
71
+ margin-left: 10px;
72
+ margin-right: 10px;
73
+ float: left;
74
+ list-style: none;
75
+ text-align: center;
76
+ }
77
+
78
+ .aalb-pg-ad-unit .aalb-pg-product-image {
79
+ display: table;
80
+ width: 150px;
81
+ height: 150px;
82
+ margin: 0 auto;
83
+ text-align: center;
84
+ }
85
+
86
+ .aalb-pg-ad-unit .aalb-pg-product-image-wrapper {
87
+ display: table-cell;
88
+ vertical-align: middle;
89
+ }
90
+
91
+ .aalb-pg-ad-unit .aalb-pg-product-image a {
92
+ position: relative;
93
+ display: inline-block;
94
+ vertical-align: middle;
95
+ }
96
+
97
+ .aalb-pg-ad-unit .aalb-pg-product-image img {
98
+ max-width: 150px;
99
+ max-height: 150px;
100
+ vertical-align: bottom;
101
+ }
102
+
103
+ .aalb-pg-ad-unit .aalb-pg-percent-off {
104
+ display: block;
105
+ width: 32px;
106
+ height: 27px;
107
+ padding-top: 5px;
108
+ position: absolute;
109
+ top: -16px;
110
+ right: -16px;
111
+ color: #ffffff;
112
+ font-size: 12px;
113
+ text-align: center;
114
+ -webkit-border-radius: 50%;
115
+ -moz-border-radius: 50%;
116
+ -ms-border-radius: 50%;
117
+ border-radius: 50%;
118
+ background-color: #a50200;
119
+ background-image: -webkit-linear-gradient(top, #cb0400, #a50200);
120
+ background-image: linear-gradient(to bottom, #cb0400, #a50200);
121
+ }
122
+
123
+ .aalb-pg-ad-unit.hide-percent-off-badge .aalb-pg-percent-off {
124
+ display: none;
125
+ }
126
+
127
+ .aalb-pg-ad-unit .aalb-pg-product-details {
128
+ display: inline-block;
129
+ max-width: 100%;
130
+ margin-top: 11px;
131
+ text-align: left;
132
+ }
133
+
134
+ .aalb-pg-ad-unit .aalb-pg-product-title a {
135
+ display: block;
136
+ width: 100%;
137
+ overflow: hidden;
138
+ white-space: nowrap;
139
+ text-overflow: ellipsis;
140
+ font-size: 13px;
141
+ color: #111111;
142
+ text-decoration: none;
143
+ }
144
+
145
+ .aalb-pg-ad-unit.no-truncate .aalb-pg-product-title a {
146
+ text-overflow: initial;
147
+ white-space: initial;
148
+ }
149
+
150
+ .aalb-pg-ad-unit .aalb-pg-product-offer-price {
151
+ font-size: 13px;
152
+ color: #111111;
153
+ }
154
+
155
+ .aalb-pg-ad-unit .aalb-pg-product-offer-price-value {
156
+ color: #AB1700;
157
+ font-weight: bold;
158
+ }
159
+
160
+ .aalb-pg-ad-unit .aalb-pg-product-list-price {
161
+ font-size: 13px;
162
+ color: #565656;
163
+ }
164
+
165
+ .aalb-pg-ad-unit .aalb-pg-product-list-price-value {
166
+ text-decoration: line-through;
167
+ }
168
+
169
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
170
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
171
+ display: inline-block;
172
+ margin-top: -1px;
173
+ vertical-align: middle;
174
+ background-position: -205px -246px;
175
+ width: 47px;
176
+ height: 16px;
177
+ }
178
+
179
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
180
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
181
+ display: inline-block;
182
+ margin-top: -1px;
183
+ vertical-align: middle;
184
+ background-position: -205px -274px;
185
+ width: 62px;
186
+ height: 15px;
187
+ }
188
+
189
+ .aalb-pg-ad-unit .aalb-pg-product-offer-price,
190
+ .aalb-pg-ad-unit .aalb-pg-product-list-price,
191
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon {
192
+ display: inline-block;
193
+ margin-right: 2px;
194
+ }
195
+
196
+ .aalb-pg-ad-unit .aalb-pg-btn-prev,
197
+ .aalb-pg-ad-unit .aalb-pg-btn-next {
198
+ position: absolute;
199
+ top: 50%;
200
+ margin-top: -52px;
201
+ display: block;
202
+ visibility: hidden;
203
+ width: 43px;
204
+ height: 105px;
205
+ z-index: 2;
206
+ line-height: 105px;
207
+ background: #ffffff;
208
+ color: #D0D0D0;
209
+ font-size: 35px;
210
+ text-align: center;
211
+ text-decoration: none;
212
+ border: 1px solid #e9e9e9;
213
+ -webkit-box-shadow: 0 0 4px #e9e9e9;
214
+ box-shadow: 0 0 4px #e9e9e9;
215
+ }
216
+
217
+ .aalb-pg-ad-unit .aalb-pg-btn-prev:hover,
218
+ .aalb-pg-ad-unit .aalb-pg-btn-next:hover {
219
+ color: #999999;
220
+ }
221
+
222
+ .aalb-pg-ad-unit .aalb-pg-btn-prev:focus,
223
+ .aalb-pg-ad-unit .aalb-pg-btn-next:focus {
224
+ outline: none;
225
+ }
226
+
227
+ .aalb-pg-ad-unit .aalb-pg-btn-prev {
228
+ left: 0;
229
+ border-left: 0;
230
+ border-top-right-radius: 20px;
231
+ border-bottom-right-radius: 20px;
232
+ }
233
+
234
+ .aalb-pg-ad-unit .aalb-pg-btn-next {
235
+ right: 0;
236
+ border-right: 0;
237
+ border-top-left-radius: 20px;
238
+ border-bottom-left-radius: 20px;
239
+ }
240
+
241
+ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-all {
243
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
244
+ display: inline-block;
245
+ margin-top: -1px;
246
+ vertical-align: middle;
247
+ background-position: -205px -246px;
248
+ width: 47px;
249
+ height: 15px;
250
+ }
251
+
252
+ .aalb-pg-ad-unit .aalb-pg-product-prime-icon .icon-prime-es {
253
+ background: url('https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AmazonUIBaseCSS-sprite_1x-e1a6545ba46e2ced9fc835dbdec4fff037b5b6bf._V2_.png') no-repeat;
254
+ display: inline-block;
255
+ margin-top: -1px;
256
+ vertical-align: middle;
257
+ background-position: -205px -274px;
258
+ width: 62px;
259
+ height: 16px;
260
+ }
261
+ }
template/ProductGrid.mustache CHANGED
@@ -1,144 +1,144 @@
1
- <!-- A 2x5 Grid Template Layout. It can be configured by the two input fields below -->
2
- {{#Items}} <!--Section tag for iterating through the list of items-->
3
- <div class="aalb-pg-ad-unit" id="{{ID}}">
4
- <input type="hidden" name="columns" value="2" />
5
- <input type="hidden" name="rows" value="5" />
6
- <h2 class="aalb-pg-ad-header">{{#AalbHeader}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/AalbHeader}}</h2> <!-- Title of the ad localized according to the marketplace picked from the AalbHeader tag -->
7
- <div class="aalb-pg-wrapper">
8
- <div class="aalb-pg-product-container">
9
- <ul class="aalb-pg-product-list">
10
- {{#Item}} <!-- Section tag for beginning of information on one item -->
11
- {{#aalb}} <!-- Section tag for picking up information on attributes for the item -->
12
- <li class="aalb-pg-product">
13
- <div class="aalb-pg-product-image">
14
- <div class="aalb-pg-product-image-wrapper">
15
- <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow"> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
16
- <img src="{{MediumImageURL}}" srcset="{{LargeImageURL}}" alt="{{Title}}" />
17
- {{#SavingPercent}} <!-- The section tag ensures that percentage savings is displayed only if it is available -->
18
- <span class="aalb-pg-percent-off">
19
- -{{SavingPercent}}%
20
- </span>
21
- {{/SavingPercent}}
22
- </a>
23
- </div>
24
- </div>
25
- <div class="aalb-pg-product-details">
26
- <div class="aalb-pg-product-title">
27
- <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow">
28
- {{Title}}
29
- </a>
30
- </div>
31
- <div class="aalb-pg-product-offer-price">
32
- <!-- The section tag for different marketplaces ensures localization of static text. -->
33
- {{#MarketplaceUS}}Price{{/MarketplaceUS}}{{#MarketplaceFR}}Prix{{/MarketplaceFR}}{{#MarketplaceIT}}Prezzo{{/MarketplaceIT}}{{#MarketplaceDE}}Preis{{/MarketplaceDE}}{{#MarketplaceES}}Precio{{/MarketplaceES}}{{#MarketplaceBR}}Price{{/MarketplaceBR}}{{#MarketplaceCA}}Price{{/MarketplaceCA}}{{#MarketplaceCN}}Price{{/MarketplaceCN}}{{#MarketplaceIN}}Price{{/MarketplaceIN}}{{#MarketplaceJP}}Price{{/MarketplaceJP}}{{#MarketplaceMX}}Price{{/MarketplaceMX}}{{#MarketplaceUK}}Price{{/MarketplaceUK}}: <span class="aalb-pg-product-offer-price-value">{{CurrentPrice}}</span>
34
- </div>
35
- {{#StrikePrice}} <!-- The section tag ensures that strike price is displayed only if it is available -->
36
- <div class="aalb-pg-product-list-price">
37
- <!-- The section tag for different marketplaces ensures localization of static text. -->
38
- {{#MarketplaceUS}}Was{{/MarketplaceUS}}{{#MarketplaceFR}}Ancien prix{{/MarketplaceFR}}{{#MarketplaceIT}}Da{{/MarketplaceIT}}{{#MarketplaceDE}}statt{{/MarketplaceDE}}{{#MarketplaceES}}Precio recomendado{{/MarketplaceES}}{{#MarketplaceBR}}Was{{/MarketplaceBR}}{{#MarketplaceCA}}Was{{/MarketplaceCA}}{{#MarketplaceCN}}Was{{/MarketplaceCN}}{{#MarketplaceIN}}Was{{/MarketplaceIN}}{{#MarketplaceJP}}Was{{/MarketplaceJP}}{{#MarketplaceMX}}Was{{/MarketplaceMX}}{{#MarketplaceUK}}Was{{/MarketplaceUK}}: <span class="aalb-pg-product-list-price-value">{{StrikePrice}}</span>
39
- </div>
40
- {{/StrikePrice}}
41
- {{#Prime}} <!-- The section tag ensures that prime icon is displayed only if it is available -->
42
- <div class="aalb-pg-product-prime-icon">
43
- {{#MarketplaceES}} <!-- Display Prime Icon for ES if marketplace is ES -->
44
- <i class="icon-prime-es"></i>
45
- {{/MarketplaceES}}
46
- {{^MarketplaceES}} <!-- Display Common Prime Icon for all other marketplaces -->
47
- <i class="icon-prime-all"></i>
48
- {{/MarketplaceES}}
49
- </div>
50
- {{/Prime}}
51
- </div>
52
- </li>
53
- {{/aalb}}
54
- {{/Item}}
55
- </ul>
56
- </div>
57
- </div>
58
- <a href="javascript:void(0);" class="aalb-pg-btn-prev">‹</a>
59
- <a href="javascript:void(0);" class="aalb-pg-btn-next">›</a>
60
- </div>
61
- {{/Items}}
62
-
63
- <script>
64
- jQuery(document).ready(function() {
65
-
66
- var CONSTANTS = {
67
- productMinWidth : 185,
68
- productMargin : 20
69
- };
70
-
71
- var $adUnits = jQuery('.aalb-pg-ad-unit');
72
- $adUnits.each(function() {
73
- var $adUnit = jQuery(this),
74
- $wrapper = $adUnit.find('.aalb-pg-wrapper'),
75
- $productContainer = $adUnit.find('.aalb-pg-product-container'),
76
- $btnNext = $adUnit.find('.aalb-pg-btn-next'),
77
- $btnPrev = $adUnit.find('.aalb-pg-btn-prev'),
78
- $productList = $productContainer.find('.aalb-pg-product-list'),
79
- $products = $productList.find('.aalb-pg-product'),
80
- productCount = $products.length;
81
-
82
- if (!productCount) {
83
- return true;
84
- }
85
-
86
- var rows = $adUnit.find('input[name=rows]').length && parseInt($adUnit.find('input[name=rows]').val(), 10),
87
- columns = $adUnit.find('input[name=columns]').length && parseInt($adUnit.find('input[name=columns]').val(), 10),
88
- disableCarousel = $adUnit.find('input[name=disable-carousel]').length || rows || columns;
89
-
90
- if (columns) {
91
- var productContainerMinWidth = columns * (CONSTANTS.productMinWidth + CONSTANTS.productMargin) + 'px';
92
- $adUnit.css('min-width', productContainerMinWidth);
93
- $productContainer.css('min-width', productContainerMinWidth);
94
- $products.filter(':nth-child(' + columns + 'n + 1)').css('clear', 'both');
95
- }
96
-
97
- if (rows && columns) {
98
- var cutOffIndex = (rows * columns) - 1;
99
- $products.filter(':gt(' + cutOffIndex + ')').remove();
100
- }
101
-
102
- function updateLayout() {
103
- var wrapperWidth = $wrapper.width(),
104
- possibleColumns = columns || parseInt(wrapperWidth / (CONSTANTS.productMinWidth + CONSTANTS.productMargin), 10),
105
- actualColumns = columns || possibleColumns < productCount ? possibleColumns : productCount,
106
- productWidth = parseInt(wrapperWidth / actualColumns, 10) - CONSTANTS.productMargin;
107
-
108
- $products.css('width', productWidth + 'px');
109
-
110
- if (!disableCarousel) {
111
- if ((productCount * productWidth > wrapperWidth) && actualColumns !== 1) {
112
- $btnNext.css('visibility', 'visible').removeClass('disabled').unbind('click');
113
- $btnPrev.css('visibility', 'visible').removeClass('disabled').unbind('click');
114
- $productContainer.jCarouselLite({
115
- btnNext : '#' + $adUnit.attr('id') + ' .aalb-pg-btn-next',
116
- btnPrev : '#' + $adUnit.attr('id') + ' .aalb-pg-btn-prev',
117
- visible : actualColumns,
118
- circular : false
119
- });
120
- } else {
121
- $productContainer.css('width', 'auto');
122
- $productList.css('width', 'auto');
123
- $btnNext.css('visibility', 'hidden').unbind('click');
124
- $btnPrev.css('visibility', 'hidden').unbind('click');
125
- }
126
- }
127
- }
128
-
129
- updateLayout();
130
- jQuery(window).resize(updateLayout);
131
- });
132
- });
133
-
134
- /*!
135
- * jCarouselLite - v1.1 - 2014-09-28
136
- * http://www.gmarwaha.com/jquery/jcarousellite/
137
- * Copyright (c) 2014 Ganeshji Marwaha
138
- * Licensed MIT (https://github.com/ganeshmax/jcarousellite/blob/master/LICENSE)
139
- */
140
-
141
- !function(a){a.jCarouselLite={version:"1.1"},a.fn.jCarouselLite=function(b){return b=a.extend({},a.fn.jCarouselLite.options,b||{}),this.each(function(){function c(a){return n||(clearTimeout(A),z=a,b.beforeStart&&b.beforeStart.call(this,i()),b.circular?j(a):k(a),m({start:function(){n=!0},done:function(){b.afterEnd&&b.afterEnd.call(this,i()),b.auto&&h(),n=!1}}),b.circular||l()),!1}function d(){if(n=!1,o=b.vertical?"top":"left",p=b.vertical?"height":"width",q=B.find(">ul"),r=q.find(">li"),x=r.size(),w=x<b.visible?x:b.visible,b.circular){var c=r.slice(x-w).clone(),d=r.slice(0,w).clone();q.prepend(c).append(d),b.start+=w}s=a("li",q),y=s.size(),z=b.start}function e(){B.css("visibility","visible"),s.css({overflow:"hidden","float":b.vertical?"none":"left"}),q.css({margin:"0",padding:"0",position:"relative","list-style":"none","z-index":"1"}),B.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"}),!b.circular&&b.btnPrev&&0==b.start&&a(b.btnPrev).addClass("disabled")}function f(){t=b.vertical?s.outerHeight(!0):s.outerWidth(!0),u=t*y,v=t*w,s.css({width:s.width(),height:s.height()}),q.css(p,u+"px").css(o,-(z*t)),B.css(p,v+"px")}function g(){b.btnPrev&&a(b.btnPrev).click(function(){return c(z-b.scroll)}),b.btnNext&&a(b.btnNext).click(function(){return c(z+b.scroll)}),b.btnGo&&a.each(b.btnGo,function(d,e){a(e).click(function(){return c(b.circular?w+d:d)})}),b.mouseWheel&&B.mousewheel&&B.mousewheel(function(a,d){return c(d>0?z-b.scroll:z+b.scroll)}),b.auto&&h()}function h(){A=setTimeout(function(){c(z+b.scroll)},b.auto)}function i(){return s.slice(z).slice(0,w)}function j(a){var c;a<=b.start-w-1?(c=a+x+b.scroll,q.css(o,-(c*t)+"px"),z=c-b.scroll):a>=y-w+1&&(c=a-x-b.scroll,q.css(o,-(c*t)+"px"),z=c+b.scroll)}function k(a){0>a?z=0:a>y-w&&(z=y-w)}function l(){a(b.btnPrev+","+b.btnNext).removeClass("disabled"),a(z-b.scroll<0&&b.btnPrev||z+b.scroll>y-w&&b.btnNext||[]).addClass("disabled")}function m(c){n=!0,q.animate("left"==o?{left:-(z*t)}:{top:-(z*t)},a.extend({duration:b.speed,easing:b.easing},c))}var n,o,p,q,r,s,t,u,v,w,x,y,z,A,B=a(this);d(),e(),f(),g()})},a.fn.jCarouselLite.options={btnPrev:null,btnNext:null,btnGo:null,mouseWheel:!1,auto:null,speed:200,easing:null,vertical:!1,circular:!0,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null}}(jQuery);
142
-
143
-
144
- </script>
1
+ <!-- A 2x5 Grid Template Layout. It can be configured by the two input fields below -->
2
+ {{#Items}} <!--Section tag for iterating through the list of items-->
3
+ <div class="aalb-pg-ad-unit" id="{{ID}}">
4
+ <input type="hidden" name="columns" value="2" />
5
+ <input type="hidden" name="rows" value="5" />
6
+ <h2 class="aalb-pg-ad-header">{{#AalbHeader}}{{#MarketplaceUS}}Products from Amazon.com{{/MarketplaceUS}}{{#MarketplaceFR}}Produits disponibles sur Amazon.fr {{/MarketplaceFR}}{{#MarketplaceIT}}Acquista su Amazon.it{{/MarketplaceIT}}{{#MarketplaceDE}}Produkte von Amazon.de{{/MarketplaceDE}}{{#MarketplaceES}}Producto disponible en Amazon.es{{/MarketplaceES}}{{#MarketplaceBR}}Products from Amazon.com.br{{/MarketplaceBR}}{{#MarketplaceCA}}Products from Amazon.ca{{/MarketplaceCA}}{{#MarketplaceCN}}Products from Amazon.cn{{/MarketplaceCN}}{{#MarketplaceIN}}Products from Amazon.in{{/MarketplaceIN}}{{#MarketplaceJP}}Products from Amazon.co.jp{{/MarketplaceJP}}{{#MarketplaceMX}}Products from Amazon.com.mx{{/MarketplaceMX}}{{#MarketplaceUK}}Products from Amazon.co.uk{{/MarketplaceUK}}{{/AalbHeader}}</h2> <!-- Title of the ad localized according to the marketplace picked from the AalbHeader tag -->
7
+ <div class="aalb-pg-wrapper">
8
+ <div class="aalb-pg-product-container">
9
+ <ul class="aalb-pg-product-list">
10
+ {{#Item}} <!-- Section tag for beginning of information on one item -->
11
+ {{#aalb}} <!-- Section tag for picking up information on attributes for the item -->
12
+ <li class="aalb-pg-product">
13
+ <div class="aalb-pg-product-image">
14
+ <div class="aalb-pg-product-image-wrapper">
15
+ <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow"> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
16
+ <img src="{{MediumImageURL}}" srcset="{{LargeImageURL}}" alt="{{Title}}" />
17
+ {{#SavingPercent}} <!-- The section tag ensures that percentage savings is displayed only if it is available -->
18
+ <span class="aalb-pg-percent-off">
19
+ -{{SavingPercent}}%
20
+ </span>
21
+ {{/SavingPercent}}
22
+ </a>
23
+ </div>
24
+ </div>
25
+ <div class="aalb-pg-product-details">
26
+ <div class="aalb-pg-product-title">
27
+ <a href="{{DetailPageURL}}" title="{{Title}}" target="_blank" rel="nofollow">
28
+ {{Title}}
29
+ </a>
30
+ </div>
31
+ <div class="aalb-pg-product-offer-price">
32
+ <!-- The section tag for different marketplaces ensures localization of static text. -->
33
+ {{#MarketplaceUS}}Price{{/MarketplaceUS}}{{#MarketplaceFR}}Prix{{/MarketplaceFR}}{{#MarketplaceIT}}Prezzo{{/MarketplaceIT}}{{#MarketplaceDE}}Preis{{/MarketplaceDE}}{{#MarketplaceES}}Precio{{/MarketplaceES}}{{#MarketplaceBR}}Price{{/MarketplaceBR}}{{#MarketplaceCA}}Price{{/MarketplaceCA}}{{#MarketplaceCN}}Price{{/MarketplaceCN}}{{#MarketplaceIN}}Price{{/MarketplaceIN}}{{#MarketplaceJP}}Price{{/MarketplaceJP}}{{#MarketplaceMX}}Price{{/MarketplaceMX}}{{#MarketplaceUK}}Price{{/MarketplaceUK}}: <span class="aalb-pg-product-offer-price-value">{{CurrentPrice}}</span>
34
+ </div>
35
+ {{#StrikePrice}} <!-- The section tag ensures that strike price is displayed only if it is available -->
36
+ <div class="aalb-pg-product-list-price">
37
+ <!-- The section tag for different marketplaces ensures localization of static text. -->
38
+ {{#MarketplaceUS}}Was{{/MarketplaceUS}}{{#MarketplaceFR}}Ancien prix{{/MarketplaceFR}}{{#MarketplaceIT}}Da{{/MarketplaceIT}}{{#MarketplaceDE}}statt{{/MarketplaceDE}}{{#MarketplaceES}}Precio recomendado{{/MarketplaceES}}{{#MarketplaceBR}}Was{{/MarketplaceBR}}{{#MarketplaceCA}}Was{{/MarketplaceCA}}{{#MarketplaceCN}}Was{{/MarketplaceCN}}{{#MarketplaceIN}}Was{{/MarketplaceIN}}{{#MarketplaceJP}}Was{{/MarketplaceJP}}{{#MarketplaceMX}}Was{{/MarketplaceMX}}{{#MarketplaceUK}}Was{{/MarketplaceUK}}: <span class="aalb-pg-product-list-price-value">{{StrikePrice}}</span>
39
+ </div>
40
+ {{/StrikePrice}}
41
+ {{#Prime}} <!-- The section tag ensures that prime icon is displayed only if it is available -->
42
+ <div class="aalb-pg-product-prime-icon">
43
+ {{#MarketplaceES}} <!-- Display Prime Icon for ES if marketplace is ES -->
44
+ <i class="icon-prime-es"></i>
45
+ {{/MarketplaceES}}
46
+ {{^MarketplaceES}} <!-- Display Common Prime Icon for all other marketplaces -->
47
+ <i class="icon-prime-all"></i>
48
+ {{/MarketplaceES}}
49
+ </div>
50
+ {{/Prime}}
51
+ </div>
52
+ </li>
53
+ {{/aalb}}
54
+ {{/Item}}
55
+ </ul>
56
+ </div>
57
+ </div>
58
+ <a href="javascript:void(0);" class="aalb-pg-btn-prev">‹</a>
59
+ <a href="javascript:void(0);" class="aalb-pg-btn-next">›</a>
60
+ </div>
61
+ {{/Items}}
62
+
63
+ <script>
64
+ jQuery(document).ready(function() {
65
+
66
+ var CONSTANTS = {
67
+ productMinWidth : 185,
68
+ productMargin : 20
69
+ };
70
+
71
+ var $adUnits = jQuery('.aalb-pg-ad-unit');
72
+ $adUnits.each(function() {
73
+ var $adUnit = jQuery(this),
74
+ $wrapper = $adUnit.find('.aalb-pg-wrapper'),
75
+ $productContainer = $adUnit.find('.aalb-pg-product-container'),
76
+ $btnNext = $adUnit.find('.aalb-pg-btn-next'),
77
+ $btnPrev = $adUnit.find('.aalb-pg-btn-prev'),
78
+ $productList = $productContainer.find('.aalb-pg-product-list'),
79
+ $products = $productList.find('.aalb-pg-product'),
80
+ productCount = $products.length;
81
+
82
+ if (!productCount) {
83
+ return true;
84
+ }
85
+
86
+ var rows = $adUnit.find('input[name=rows]').length && parseInt($adUnit.find('input[name=rows]').val(), 10),
87
+ columns = $adUnit.find('input[name=columns]').length && parseInt($adUnit.find('input[name=columns]').val(), 10),
88
+ disableCarousel = $adUnit.find('input[name=disable-carousel]').length || rows || columns;
89
+
90
+ if (columns) {
91
+ var productContainerMinWidth = columns * (CONSTANTS.productMinWidth + CONSTANTS.productMargin) + 'px';
92
+ $adUnit.css('min-width', productContainerMinWidth);
93
+ $productContainer.css('min-width', productContainerMinWidth);
94
+ $products.filter(':nth-child(' + columns + 'n + 1)').css('clear', 'both');
95
+ }
96
+
97
+ if (rows && columns) {
98
+ var cutOffIndex = (rows * columns) - 1;
99
+ $products.filter(':gt(' + cutOffIndex + ')').remove();
100
+ }
101
+
102
+ function updateLayout() {
103
+ var wrapperWidth = $wrapper.width(),
104
+ possibleColumns = columns || parseInt(wrapperWidth / (CONSTANTS.productMinWidth + CONSTANTS.productMargin), 10),
105
+ actualColumns = columns || possibleColumns < productCount ? possibleColumns : productCount,
106
+ productWidth = parseInt(wrapperWidth / actualColumns, 10) - CONSTANTS.productMargin;
107
+
108
+ $products.css('width', productWidth + 'px');
109
+
110
+ if (!disableCarousel) {
111
+ if ((productCount * productWidth > wrapperWidth) && actualColumns !== 1) {
112
+ $btnNext.css('visibility', 'visible').removeClass('disabled').unbind('click');
113
+ $btnPrev.css('visibility', 'visible').removeClass('disabled').unbind('click');
114
+ $productContainer.jCarouselLite({
115
+ btnNext : '#' + $adUnit.attr('id') + ' .aalb-pg-btn-next',
116
+ btnPrev : '#' + $adUnit.attr('id') + ' .aalb-pg-btn-prev',
117
+ visible : actualColumns,
118
+ circular : false
119
+ });
120
+ } else {
121
+ $productContainer.css('width', 'auto');
122
+ $productList.css('width', 'auto');
123
+ $btnNext.css('visibility', 'hidden').unbind('click');
124
+ $btnPrev.css('visibility', 'hidden').unbind('click');
125
+ }
126
+ }
127
+ }
128
+
129
+ updateLayout();
130
+ jQuery(window).resize(updateLayout);
131
+ });
132
+ });
133
+
134
+ /*!
135
+ * jCarouselLite - v1.1 - 2014-09-28
136
+ * http://www.gmarwaha.com/jquery/jcarousellite/
137
+ * Copyright (c) 2014 Ganeshji Marwaha
138
+ * Licensed MIT (https://github.com/ganeshmax/jcarousellite/blob/master/LICENSE)
139
+ */
140
+
141
+ !function(a){a.jCarouselLite={version:"1.1"},a.fn.jCarouselLite=function(b){return b=a.extend({},a.fn.jCarouselLite.options,b||{}),this.each(function(){function c(a){return n||(clearTimeout(A),z=a,b.beforeStart&&b.beforeStart.call(this,i()),b.circular?j(a):k(a),m({start:function(){n=!0},done:function(){b.afterEnd&&b.afterEnd.call(this,i()),b.auto&&h(),n=!1}}),b.circular||l()),!1}function d(){if(n=!1,o=b.vertical?"top":"left",p=b.vertical?"height":"width",q=B.find(">ul"),r=q.find(">li"),x=r.size(),w=x<b.visible?x:b.visible,b.circular){var c=r.slice(x-w).clone(),d=r.slice(0,w).clone();q.prepend(c).append(d),b.start+=w}s=a("li",q),y=s.size(),z=b.start}function e(){B.css("visibility","visible"),s.css({overflow:"hidden","float":b.vertical?"none":"left"}),q.css({margin:"0",padding:"0",position:"relative","list-style":"none","z-index":"1"}),B.css({overflow:"hidden",position:"relative","z-index":"2",left:"0px"}),!b.circular&&b.btnPrev&&0==b.start&&a(b.btnPrev).addClass("disabled")}function f(){t=b.vertical?s.outerHeight(!0):s.outerWidth(!0),u=t*y,v=t*w,s.css({width:s.width(),height:s.height()}),q.css(p,u+"px").css(o,-(z*t)),B.css(p,v+"px")}function g(){b.btnPrev&&a(b.btnPrev).click(function(){return c(z-b.scroll)}),b.btnNext&&a(b.btnNext).click(function(){return c(z+b.scroll)}),b.btnGo&&a.each(b.btnGo,function(d,e){a(e).click(function(){return c(b.circular?w+d:d)})}),b.mouseWheel&&B.mousewheel&&B.mousewheel(function(a,d){return c(d>0?z-b.scroll:z+b.scroll)}),b.auto&&h()}function h(){A=setTimeout(function(){c(z+b.scroll)},b.auto)}function i(){return s.slice(z).slice(0,w)}function j(a){var c;a<=b.start-w-1?(c=a+x+b.scroll,q.css(o,-(c*t)+"px"),z=c-b.scroll):a>=y-w+1&&(c=a-x-b.scroll,q.css(o,-(c*t)+"px"),z=c+b.scroll)}function k(a){0>a?z=0:a>y-w&&(z=y-w)}function l(){a(b.btnPrev+","+b.btnNext).removeClass("disabled"),a(z-b.scroll<0&&b.btnPrev||z+b.scroll>y-w&&b.btnNext||[]).addClass("disabled")}function m(c){n=!0,q.animate("left"==o?{left:-(z*t)}:{top:-(z*t)},a.extend({duration:b.speed,easing:b.easing},c))}var n,o,p,q,r,s,t,u,v,w,x,y,z,A,B=a(this);d(),e(),f(),g()})},a.fn.jCarouselLite.options={btnPrev:null,btnNext:null,btnGo:null,mouseWheel:!1,auto:null,speed:200,easing:null,vertical:!1,circular:!0,visible:3,start:0,scroll:1,beforeStart:null,afterEnd:null}}(jQuery);
142
+
143
+
144
+ </script>
template/ProductLink.mustache CHANGED
@@ -1,7 +1,7 @@
1
- {{#Items}}
2
- {{#Item}}
3
- {{#aalb}}
4
- <a href="{{DetailPageURL}}" target="_blank" rel="nofollow">[[Amazon_Link_Text]]</a> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
5
- {{/aalb}}
6
- {{/Item}}
7
- {{/Items}}
1
+ {{#Items}}
2
+ {{#Item}}
3
+ {{#aalb}}
4
+ <a href="{{DetailPageURL}}" target="_blank" rel="nofollow">[[Amazon_Link_Text]]</a> <!--Individual attributes are provided as variable tags as {{[[attribute]]}}. Check documentation for list of supported variable tags.-->
5
+ {{/aalb}}
6
+ {{/Item}}
7
+ {{/Items}}