Recent Facebook Posts - Version 2.0

Version Description

  • September 15, 2014 =

Fixes

  • Fixed an issue with Facebook statuses containing Emojis

Improvements

  • Better sanitizing throughout the plugin, using native WP functions.
  • Improved inline code documentation
  • Prevent direct file access
  • Changing thumbnail sizes does not require a cache refresh to fetch new video images

Additions

  • New FB configurations are now automatically tested.
Download this release

Release Info

Developer DvanKooten
Plugin Icon wp plugin Recent Facebook Posts
Version 2.0
Comparing to
See all releases

Code changes from version 1.8.5 to 2.0

LICENSE ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ {description}
294
+ Copyright (C) {year} {fullname}
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ {signature of Ty Coon}, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
README.md ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Recent Facebook Posts
2
+ ======================
3
+
4
+ Here you can browse the source of the [Recent Facebook Posts Plugin for WordPress](http://wordpress.org/plugins/recent-facebook-posts/) project, find and discuss open issues or contribute yourself.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ Here's a [guide on how to install the plugin in your WordPress site](http://wordpress.org/plugins/recent-facebook-posts/installation/).
10
+ If you want to run the Git version, you have two options:
11
+
12
+ * You can clone the GitHub repository: `https://github.com/dannyvankooten/wordpress-recent-facebook-posts.git`
13
+ * You can download the repository .zip file: [recent-facebook-posts.zip](https://github.com/dannyvankooten/wordpress-recent-facebook-posts/archive/master.zip)
14
+
15
+ This will download the latest development version of the Recent Facebook Posts plugin. While this version is usually stable,
16
+ it is not recommended for use in a production environment.
17
+
18
+ Bugs
19
+ ----
20
+ If you find an issue, [let us know here](https://github.com/dannyvankooten/wordpress-recent-facebook-posts/issues?state=open)!
21
+
22
+ Support
23
+ -------
24
+ This is a developer's portal for the Recent Facebook Posts plugin and should not be used for support. Please visit the
25
+ [plugin support forums on WordPress.org](http://wordpress.org/support/plugin/recent-facebook-posts).
26
+
27
+ Contributions
28
+ -------------
29
+ Anyone is welcome to contribute to the plugin. There are various ways you can contribute:
30
+
31
+ * [Raise an issue](https://github.com/dannyvankooten/wordpress-recent-facebook-posts/issues) on GitHub.
32
+ * Send us a Pull Request with your bug fixes and/or new features.
33
+ * Provide feedback and [suggestions on enhancements](https://github.com/dannyvankooten/wordpress-recent-facebook-posts/issues?direction=desc&labels=Enhancement&page=1&sort=created&state=open).
includes/class-admin.php CHANGED
@@ -1,5 +1,9 @@
1
  <?php
2
 
 
 
 
 
3
  class RFBP_Admin {
4
 
5
  private $cache_cleared = false;
@@ -22,85 +26,127 @@ class RFBP_Admin {
22
 
23
  public function on_init() {
24
 
25
- if(version_compare(RFBP_VERSION, get_option('rfbp_version', 0))) {
 
 
 
 
26
 
27
- // code is newer than database, run upgrade routine
28
  delete_transient('rfbp_posts');
29
  delete_transient('rfbp_posts_fallback');
30
 
31
- $settings = rfbp_get_settings();
 
32
 
33
- if(isset($settings['link_text'])) {
34
- $settings['page_link_text'] = $settings['link_text'];
35
- unset($settings['link_text']);
36
- }
37
 
38
- update_option('rfb_settings', $settings);
 
 
 
39
 
40
- update_option('rfbp_version', RFBP_VERSION);
 
 
 
41
  }
42
 
43
- // maybe renew cache file
44
- if ( isset( $_POST['rfbp-clear-cache'] ) ) {
 
45
 
46
- delete_transient('rfbp_posts');
47
- delete_transient('rfbp_posts_fallback');
48
 
49
- $this->cache_cleared = true;
50
- }
 
 
 
 
 
51
 
52
- if(isset($_POST['rfbp-test-config'])) {
53
- add_action( 'admin_init', array($this, 'test_facebook_api') );
54
  }
 
 
 
55
  }
56
 
 
 
 
57
  public function register_settings() {
58
  register_setting( 'rfb_settings_group', 'rfb_settings', array( $this, 'sanitize_settings' ) );
59
  }
60
 
 
 
 
 
 
 
 
61
  public function sanitize_settings( $opts ) {
62
  $old_opts = rfbp_get_settings();
63
 
64
  // fb config
65
- $opts['app_id'] = trim($opts['app_id']);
66
- $opts['app_secret'] = trim($opts['app_secret']);
67
- $opts['fb_id'] = trim($opts['fb_id']);
68
 
 
69
  if(($old_opts['fb_id'] !== $opts['fb_id']) || ($old_opts['app_id'] !== $opts['app_id']) || ($old_opts['app_secret'] !== $opts['app_secret'])) {
 
70
  // delete cache transients
71
  delete_transient('rfbp_posts');
72
  delete_transient('rfbp_posts_fallback');
 
 
 
73
  }
74
 
75
  // appearance opts
76
- $opts['page_link_text'] = strip_tags($opts['page_link_text'], '<span><strong><b><em><i><img>');
77
- $opts['img_height'] = ( !empty( $opts['img_height'] ) ) ? (int) $opts['img_height'] : '';
78
- $opts['img_width'] = ( !empty( $opts['img_width'] ) ) ? (int) $opts['img_width'] : '';
79
- $opts['load_css'] = ( isset( $opts['load_css'] ) ) ? 1 : 0;
80
- $opts['show_links'] = isset($opts['show_links']) ? 1 : 0;
81
 
82
  return $opts;
83
  }
84
 
 
 
 
85
  public function build_menu() {
86
  $page = add_options_page( 'Recent Facebook Posts - Settings', 'Recent Facebook Posts', 'manage_options', 'rfbp', array( $this, 'settings_page' ) );
87
  }
88
 
 
 
 
89
  public function load_css() {
90
  wp_enqueue_style( 'rfb_admin_css', plugins_url( 'recent-facebook-posts/assets/css/admin.css' ) );
91
  wp_enqueue_script( 'rfb_admin_js', plugins_url( 'recent-facebook-posts/assets/js/admin.js' ), array( 'jquery' ), null, true );
92
  }
93
 
 
 
 
94
  public function settings_page() {
95
 
96
  $opts = rfbp_get_settings();
97
 
98
  // show user-friendly error message
99
- if($this->cache_cleared) {
100
- $notice = __("<strong>Cache cleared!</strong> You succesfully cleared the cache.", 'recent-facebook-posts');
101
  }
102
 
103
- include_once RFBP_PLUGIN_DIR . 'includes/views/settings_page.html.php';
104
  }
105
 
106
  /**
@@ -112,19 +158,36 @@ class RFBP_Admin {
112
  public function add_settings_link( $links ) {
113
  $settings_link = '<a href="options-general.php?page=rfbp">'. __('Settings', 'recent-facebook-posts') . '</a>';
114
  array_unshift( $links, $settings_link );
115
-
116
  return $links;
117
  }
118
 
119
- public function test_facebook_api()
 
 
 
120
  {
121
- $api = rfbp_get_api();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  $ping = $api->ping();
123
 
124
- if($ping) {
125
- add_settings_error('rfbp', 'rfbp-api-success', __('Your configuration seems to be okay and working! Nice work.', 'recent-facebook-posts'), "updated");
126
  } else {
127
- add_settings_error('rfbp', 'rfbp-api-error', __('Facebook returned the following error when testing your configuration.', 'recent-facebook-posts') . '<pre>' . $api->get_error_message() . '</pre>');
128
  }
129
  }
130
  }
1
  <?php
2
 
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
  class RFBP_Admin {
8
 
9
  private $cache_cleared = false;
26
 
27
  public function on_init() {
28
 
29
+ // check if we should run upgrade routine
30
+ $this->upgrade();
31
+
32
+ // maybe renew cache file
33
+ if ( isset( $_POST['rfbp-clear-cache'] ) ) {
34
 
 
35
  delete_transient('rfbp_posts');
36
  delete_transient('rfbp_posts_fallback');
37
 
38
+ $this->cache_cleared = true;
39
+ }
40
 
41
+ if( isset( $_POST['rfbp-test-config'] ) ) {
42
+ add_action( 'admin_init', array( $this, 'test_facebook_api') );
43
+ }
44
+ }
45
 
46
+ /**
47
+ * Upgrade Routine
48
+ */
49
+ private function upgrade() {
50
 
51
+ // Only run if code is newer than stored DB version
52
+ $db_version = get_option( 'rfbp_version', 0 );
53
+ if( version_compare( RFBP_VERSION, $db_version, '>=' ) ) {
54
+ return;
55
  }
56
 
57
+ // Delete transients for good measure
58
+ delete_transient( 'rfbp_posts' );
59
+ delete_transient( 'rfbp_posts_fallback' );
60
 
61
+ // upgrade to 1.8.5
62
+ if( version_compare( $db_version, '1.8.5', '<' ) ) {
63
 
64
+ $settings = rfbp_get_settings();
65
+
66
+ // rename `link_text` index to `page_link_text`
67
+ if ( isset( $settings['link_text'] ) ) {
68
+ $settings['page_link_text'] = $settings['link_text'];
69
+ unset( $settings['link_text'] );
70
+ }
71
 
72
+ update_option( 'rfb_settings', $settings );
 
73
  }
74
+
75
+ // Update version in database
76
+ update_option('rfbp_version', RFBP_VERSION);
77
  }
78
 
79
+ /**
80
+ * Register settings
81
+ */
82
  public function register_settings() {
83
  register_setting( 'rfb_settings_group', 'rfb_settings', array( $this, 'sanitize_settings' ) );
84
  }
85
 
86
+ /**
87
+ * Sanitize settings
88
+ *
89
+ * @param $opts
90
+ *
91
+ * @return mixed
92
+ */
93
  public function sanitize_settings( $opts ) {
94
  $old_opts = rfbp_get_settings();
95
 
96
  // fb config
97
+ $opts['app_id'] = sanitize_text_field( $opts['app_id'] );
98
+ $opts['app_secret'] = sanitize_text_field( $opts['app_secret'] );
99
+ $opts['fb_id'] = sanitize_text_field( $opts['fb_id'] );
100
 
101
+ // If FB configuration changed, delete transients with posts cache so they'll be renewed
102
  if(($old_opts['fb_id'] !== $opts['fb_id']) || ($old_opts['app_id'] !== $opts['app_id']) || ($old_opts['app_secret'] !== $opts['app_secret'])) {
103
+
104
  // delete cache transients
105
  delete_transient('rfbp_posts');
106
  delete_transient('rfbp_posts_fallback');
107
+
108
+ // test facebook api
109
+ $this->test_facebook_api( $opts['app_id'], $opts['app_secret'], $opts['fb_id'] );
110
  }
111
 
112
  // appearance opts
113
+ $opts['page_link_text'] = strip_tags( trim( $opts['page_link_text'] ), '<span><strong><b><em><i><img>' );
114
+ $opts['img_height'] = ! empty( $opts['img_height'] ) ? intval( $opts['img_height'] ) : '';
115
+ $opts['img_width'] = ! empty( $opts['img_width'] ) ? intval( $opts['img_width'] ) : '';
116
+ $opts['load_css'] = isset( $opts['load_css'] ) ? 1 : 0;
117
+ $opts['show_links'] = isset($opts['show_links'] ) ? 1 : 0;
118
 
119
  return $opts;
120
  }
121
 
122
+ /**
123
+ * Add page to WP Admin > Settings
124
+ */
125
  public function build_menu() {
126
  $page = add_options_page( 'Recent Facebook Posts - Settings', 'Recent Facebook Posts', 'manage_options', 'rfbp', array( $this, 'settings_page' ) );
127
  }
128
 
129
+ /**
130
+ * Load CSS, only called on RFBP settings page.
131
+ */
132
  public function load_css() {
133
  wp_enqueue_style( 'rfb_admin_css', plugins_url( 'recent-facebook-posts/assets/css/admin.css' ) );
134
  wp_enqueue_script( 'rfb_admin_js', plugins_url( 'recent-facebook-posts/assets/js/admin.js' ), array( 'jquery' ), null, true );
135
  }
136
 
137
+ /**
138
+ * Shows the RFBP settings page
139
+ */
140
  public function settings_page() {
141
 
142
  $opts = rfbp_get_settings();
143
 
144
  // show user-friendly error message
145
+ if( $this->cache_cleared ) {
146
+ $notice = __( "<strong>Cache cleared!</strong> You succesfully cleared the cache.", 'recent-facebook-posts' );
147
  }
148
 
149
+ include RFBP_PLUGIN_DIR . 'includes/views/settings_page.html.php';
150
  }
151
 
152
  /**
158
  public function add_settings_link( $links ) {
159
  $settings_link = '<a href="options-general.php?page=rfbp">'. __('Settings', 'recent-facebook-posts') . '</a>';
160
  array_unshift( $links, $settings_link );
 
161
  return $links;
162
  }
163
 
164
+ /**
165
+ * Ping the Facebook API for a quick test
166
+ */
167
+ public function test_facebook_api( $app_id = '', $app_secret = '', $page_id = '' )
168
  {
169
+ $opts = rfbp_get_settings();
170
+
171
+ if( '' === $app_id ) {
172
+ $app_id = $opts['app_id'];
173
+ }
174
+
175
+ if( '' === $app_secret ) {
176
+ $app_secret = $opts['app_secret'];
177
+ }
178
+
179
+ if( '' === $page_id ) {
180
+ $page_id = $opts['fb_id'];
181
+ }
182
+
183
+ require_once RFBP_PLUGIN_DIR . 'includes/class-api.php';
184
+ $api = new RFBP_API( $app_id, $app_secret, $page_id );
185
  $ping = $api->ping();
186
 
187
+ if( $ping ) {
188
+ add_settings_error('rfbp', 'rfbp-api-success', __( 'Your configuration seems to be okay and working! Nice work.', 'recent-facebook-posts' ), "updated");
189
  } else {
190
+ add_settings_error('rfbp', 'rfbp-api-error', __(' Facebook returned the following error when testing your configuration.', 'recent-facebook-posts' ) . '<pre>' . $api->get_error_message() . '</pre>');
191
  }
192
  }
193
  }
includes/class-api.php CHANGED
@@ -1,27 +1,52 @@
1
  <?php
2
 
 
 
 
 
3
  class RFBP_API {
4
 
 
 
 
5
  private $app_id = '';
 
 
 
 
6
  private $app_secret = '';
 
 
 
 
7
  private $error;
8
-
9
- public function __construct($app_id, $app_secret, $fb_id = '')
 
 
 
 
 
10
  {
11
  $this->app_id = $app_id;
12
  $this->app_secret = $app_secret;
13
  $this->fb_id = $fb_id;
14
  }
15
 
 
 
 
 
 
16
  public function get_posts()
17
  {
18
  $result = $this->call("{$this->fb_id}/posts", array(
19
  'fields' => 'id,picture,type,from,message,status_type,object_id,picture,name,caption,description,link,created_time,comments.limit(1).summary(true),likes.limit(1).summary(true)'
20
  ));
21
 
22
- if($result) {
23
- if(isset($result->data)) {
24
- return $result->data;
25
  } else {
26
  $this->error = $result->error;
27
  return false;
@@ -31,11 +56,107 @@ class RFBP_API {
31
  return false;
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  public function ping()
35
  {
36
  $result = $this->call("{$this->fb_id}/posts", array('fields' => 'name', 'limit' => 1) );
37
 
38
- if($result) {
39
  if(isset($result->data)) {
40
  return true;
41
  } else {
@@ -45,14 +166,27 @@ class RFBP_API {
45
  }
46
  }
47
 
48
- private function call($endpoint, array $data = array())
 
 
 
 
 
 
49
  {
50
- if(empty($this->app_id) || empty($this->app_secret)) { return false; }
 
 
 
51
 
 
52
  $url = "https://graph.facebook.com/{$endpoint}";
 
 
53
  $data['access_token'] = "{$this->app_id}|{$this->app_secret}";
54
 
55
- $url = add_query_arg($data, $url);
 
56
 
57
  $response = wp_remote_get($url, array(
58
  'timeout' => 10,
@@ -61,22 +195,29 @@ class RFBP_API {
61
  )
62
  );
63
 
64
- if(is_wp_error($response)) {
 
65
  $this->error = $response->get_error_message();
66
  return false;
67
  } else {
68
  $body = wp_remote_retrieve_body($response);
69
- return json_decode($body);
70
  }
71
  }
72
-
 
 
 
73
  public function has_error() {
74
- return (!empty($this->error));
75
  }
76
 
 
 
 
77
  public function get_error_message()
78
  {
79
- if(is_object($this->error)) {
80
  return $this->error->message;
81
  }
82
 
1
  <?php
2
 
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
  class RFBP_API {
8
 
9
+ /**
10
+ * @var string
11
+ */
12
  private $app_id = '';
13
+
14
+ /**
15
+ * @var string
16
+ */
17
  private $app_secret = '';
18
+
19
+ /**
20
+ * @var
21
+ */
22
  private $error;
23
+
24
+ /**
25
+ * @param $app_id
26
+ * @param $app_secret
27
+ * @param string $fb_id
28
+ */
29
+ public function __construct( $app_id, $app_secret, $fb_id = '' )
30
  {
31
  $this->app_id = $app_id;
32
  $this->app_secret = $app_secret;
33
  $this->fb_id = $fb_id;
34
  }
35
 
36
+ /**
37
+ * Fetch posts from the given Facebook page.
38
+ *
39
+ * @return array|bool
40
+ */
41
  public function get_posts()
42
  {
43
  $result = $this->call("{$this->fb_id}/posts", array(
44
  'fields' => 'id,picture,type,from,message,status_type,object_id,picture,name,caption,description,link,created_time,comments.limit(1).summary(true),likes.limit(1).summary(true)'
45
  ));
46
 
47
+ if( is_object( $result ) ) {
48
+ if( isset( $result->data ) ) {
49
+ return $this->format_data( $result->data );
50
  } else {
51
  $this->error = $result->error;
52
  return false;
56
  return false;
57
  }
58
 
59
+ /**
60
+ * @param $data
61
+ *
62
+ * @return array
63
+ */
64
+ private function format_data( $data ) {
65
+
66
+ $posts = array();
67
+ foreach ( $data as $p ) {
68
+
69
+ // skip this "post" if it is not of one of the following types
70
+ if ( ! in_array( $p->type, array( 'status', 'photo', 'video', 'link' ) ) ) {
71
+ continue;
72
+ }
73
+
74
+ // skip empty status updates
75
+ if ( $p->type === 'status' && ( ! isset( $p->message ) || empty( $p->message ) ) ) {
76
+ continue;
77
+ }
78
+
79
+ // skip empty links.
80
+ if ( $p->type === 'link' && ! isset( $p->name ) && ( ! isset( $p->message ) || empty( $p->message ) ) ) {
81
+ continue;
82
+ }
83
+
84
+ // skip friend approvals
85
+ if ( $p->type === 'status' && $p->status_type === 'approved_friend' ) {
86
+ continue;
87
+ }
88
+
89
+ //split user and post ID (userID_postID)
90
+ $idArray = explode( "_", $p->id );
91
+
92
+ $post = array();
93
+ $post['type'] = sanitize_text_field( $p->type );
94
+ $post['content'] = '';
95
+ $post['image'] = null;
96
+
97
+ if( isset( $p->message ) ) {
98
+ // remove emoji's
99
+ $post['content'] = preg_replace( '/[\x{1F600}-\x{1F64F}]|[\x{1F300}-\x{1F5FF}]|[\x{1F680}-\x{1F6FF}]|[\x{1F1E0}-\x{1F1FF}]/u', '', $p->message );
100
+
101
+ // sanitize content
102
+ $post['content'] = sanitize_text_field( $post['content'] );
103
+ }
104
+
105
+ // set type specific content
106
+ switch( $p->type ) {
107
+
108
+ case 'photo':
109
+ // set post image, use protocol relative URL
110
+ $post['image'] = "//graph.facebook.com/". $p->object_id . '/picture';
111
+ break;
112
+
113
+ case 'video':
114
+ // set thumbnail
115
+ $post['image'] = $p->picture;
116
+ break;
117
+
118
+ case 'link':
119
+ $post['link_image'] = ( isset( $p->picture ) ) ? $p->picture : '';
120
+ $post['link_name'] = ( isset( $p->name ) ) ? sanitize_text_field( $p->name ) : '';
121
+ $post['link_caption'] = ( isset( $p->caption ) ) ? sanitize_text_field( $p->caption ) : '';
122
+ $post['link_description'] = ( isset( $p->description ) ) ? sanitize_text_field( $p->description ) : '';
123
+ $post['link_url'] = $p->link;
124
+ break;
125
+ }
126
+
127
+ // calculate post like and comment counts
128
+ if ( isset( $p->likes->summary->total_count ) ) {
129
+ $post['like_count'] = absint( $p->likes->summary->total_count );
130
+ } else {
131
+ $post['like_count'] = 0;
132
+ }
133
+
134
+ if ( isset( $p->comments->summary->total_count ) ) {
135
+ $post['comment_count'] = absint( $p->comments->summary->total_count );
136
+ } else {
137
+ $post['comment_count'] = 0;
138
+ }
139
+
140
+ $post['timestamp'] = strtotime( $p->created_time );
141
+ $post['url'] = "http://www.facebook.com/". $this->fb_id . "/posts/" . $idArray[1];
142
+
143
+ // add to posts array
144
+ $posts[] = $post;
145
+ }
146
+
147
+ return $posts;
148
+ }
149
+
150
+ /**
151
+ * Fetch 1 post from Facebook to see if the configuration works
152
+ *
153
+ * @return bool
154
+ */
155
  public function ping()
156
  {
157
  $result = $this->call("{$this->fb_id}/posts", array('fields' => 'name', 'limit' => 1) );
158
 
159
+ if( is_object( $result ) ) {
160
  if(isset($result->data)) {
161
  return true;
162
  } else {
166
  }
167
  }
168
 
169
+ /**
170
+ * @param string $endpoint
171
+ * @param array $data
172
+ *
173
+ * @return array|bool|mixed
174
+ */
175
+ private function call( $endpoint, array $data = array() )
176
  {
177
+ // Only do something if an App ID and Secret is given
178
+ if ( empty( $this->app_id ) || empty( $this->app_secret ) ) {
179
+ return false;
180
+ }
181
 
182
+ // Format URL
183
  $url = "https://graph.facebook.com/{$endpoint}";
184
+
185
+ // Add access token to data array
186
  $data['access_token'] = "{$this->app_id}|{$this->app_secret}";
187
 
188
+ // Add all data to URL
189
+ $url = add_query_arg( $data, $url );
190
 
191
  $response = wp_remote_get($url, array(
192
  'timeout' => 10,
195
  )
196
  );
197
 
198
+ // Did the request succeed?
199
+ if( is_wp_error( $response ) ) {
200
  $this->error = $response->get_error_message();
201
  return false;
202
  } else {
203
  $body = wp_remote_retrieve_body($response);
204
+ return json_decode( $body );
205
  }
206
  }
207
+
208
+ /**
209
+ * @return bool
210
+ */
211
  public function has_error() {
212
+ return ( ! empty( $this->error ) );
213
  }
214
 
215
+ /**
216
+ * @return mixed
217
+ */
218
  public function get_error_message()
219
  {
220
+ if( is_object( $this->error ) ) {
221
  return $this->error->message;
222
  }
223
 
includes/class-public.php CHANGED
@@ -1,5 +1,9 @@
1
  <?php
2
 
 
 
 
 
3
  class RFBP_Public {
4
 
5
  private static $instance = null;
@@ -17,8 +21,8 @@ class RFBP_Public {
17
 
18
  $opts = rfbp_get_settings();
19
 
20
- include_once RFBP_PLUGIN_DIR . 'includes/helper-functions.php';
21
- include_once RFBP_PLUGIN_DIR . 'includes/template-functions.php';
22
 
23
  add_shortcode( 'recent_facebook_posts', array( $this, 'output' ) );
24
  add_shortcode( 'recent-facebook-posts', array( $this, 'output' ) );
@@ -38,158 +42,92 @@ class RFBP_Public {
38
  wp_enqueue_style( 'recent-facebook-posts-css' );
39
  }
40
 
41
- public function get_fallback_posts() {
42
- $posts = get_transient( 'rfbp_posts_fallback' );
43
-
44
- if ( !$posts ) {
45
- return array();
46
- }
47
-
48
- return $posts;
49
- }
50
-
51
  public function get_posts() {
52
 
53
  // try to get posts from cache
54
- if ( ( $posts = get_transient( 'rfbp_posts' ) ) ) {
 
55
  return $posts;
56
  }
57
 
58
- $opts = rfbp_get_settings();
59
-
60
  $api = rfbp_get_api();
61
- $data = $api->get_posts();
62
-
63
- // did api call succeed?
64
- if ( !$data ) {
65
- return $this->get_fallback_posts();
66
- }
67
-
68
- $posts = array();
69
- foreach ( $data as $p ) {
70
-
71
- // skip this "post" if it is not of one of the following types
72
- if ( !in_array( $p->type, array( 'status', 'photo', 'video', 'link' ) ) ) {
73
- continue;
74
- }
75
-
76
- // skip empty status updates
77
- if ($p->type == 'status' && (!isset($p->message) || empty($p->message) ) ) {
78
- continue;
79
- }
80
-
81
- // skip empty links.
82
- if ($p->type == 'link' && !isset($p->name) && (!isset($p->message) || empty($p->message))) {
83
- continue;
84
- }
85
-
86
- // skip friend approvals
87
- if ( $p->type == 'status' && $p->status_type == 'approved_friend' ) { continue; }
88
-
89
- //split user and post ID (userID_postID)
90
- $idArray = explode( "_", $p->id );
91
-
92
- $post = array();
93
- $post['type'] = $p->type;
94
- $post['content'] = isset( $p->message ) ? utf8_encode( $p->message ) : '';
95
- $post['image'] = null;
96
 
97
- // set post content and image
98
- if ( $p->type == 'photo' ) {
99
 
100
- $image = "//graph.facebook.com/". $p->object_id . '/picture';
101
- $post['image'] = $image;
 
 
 
102
 
103
- } elseif ( $p->type == 'video' ) {
104
-
105
- $image = $p->picture;
106
-
107
- // hacky
108
- if ( $opts['img_size'] == 'normal' ) {
109
- $image = str_replace( array( "_s.jpg", "_s.png" ), array( "_n.jpg", "_n.png" ), $image );
110
- }
111
-
112
- $post['image'] = $image;
113
-
114
- } elseif ( $p->type == 'link' ) {
115
- $post['link_image'] = ( isset( $p->picture ) ) ? $p->picture : '';
116
- $post['link_name'] = ( isset( $p->name ) ) ? $p->name : '';
117
- $post['link_caption'] = ( isset( $p->caption ) ) ? $p->caption : '';
118
- $post['link_description'] = ( isset( $p->description ) ) ? $p->description : '';
119
- $post['link_url'] = $p->link;
120
- }
121
-
122
- // calculate post like and comment counts
123
- if ( isset( $p->likes->summary->total_count ) ) {
124
- $like_count = $p->likes->summary->total_count;
125
- } else {
126
- $like_count = 0;
127
- }
128
-
129
- if ( isset( $p->comments->summary->total_count ) ) {
130
- $comment_count = $p->comments->summary->total_count;
131
- } else {
132
- $comment_count = 0;
133
- }
134
 
135
- $post['timestamp'] = strtotime( $p->created_time );
136
- $post['like_count'] = $like_count;
137
- $post['comment_count'] = $comment_count;
138
- $post['url'] = "http://www.facebook.com/".$opts['fb_id']."/posts/".$idArray[1];
139
- $posts[] = $post;
140
 
 
 
 
141
  }
142
 
143
- // store results in cache for later use
144
- if ( $posts ) {
145
- set_transient( 'rfbp_posts', $posts, apply_filters( 'rfbp_cache_time', 3600 ) ); // user set cache time
146
- set_transient( 'rfbp_posts_fallback', $posts, 2629744 ); // 1 month
147
- }
148
 
149
- return $posts;
150
  }
151
 
 
 
 
 
 
 
 
152
  public function output( $atts = array() ) {
153
 
154
  $opts = rfbp_get_settings();
155
  $posts = $this->get_posts();
156
 
 
157
  if ( isset( $atts['show_link'] ) ) {
158
  $atts['show_page_link'] = $atts['show_link'];
159
  }
160
 
161
- extract( shortcode_atts( array(
162
- 'number' => '5',
163
- 'likes' => 1,
164
- 'comments' => 1,
165
- 'excerpt_length' => 140,
166
- 'el' => 'div',
167
- 'origin' => 'shortcode',
168
- 'show_page_link' => false,
169
- 'show_link_previews' => ( $opts['load_css'] )
170
- ), $atts ) );
 
 
171
 
172
  ob_start();
173
  ?>
174
  <!-- Recent Facebook Posts v<?php echo RFBP_VERSION; ?> - http://wordpress.org/plugins/recent-facebook-posts/ -->
175
- <div class="recent-facebook-posts rfbp rfbp-container rfbp-<?php echo $origin; ?>">
176
  <?php
177
 
178
- if ( $posts && !empty( $posts ) ) {
179
 
180
- if ( $el == 'li' ) { echo '<ul class="rfbp-posts-wrap">'; }
181
 
182
- $posts = array_slice( $posts, 0, $number );
183
  $link_target = ( $opts['link_new_window'] ) ? "_blank" : '';
184
 
185
  foreach ( $posts as $p ) {
186
 
187
- $content = utf8_decode($p['content']);
188
-
189
  $shortened = false;
 
190
 
191
- if ( strlen( $content ) > $excerpt_length ) {
192
- $limit = strpos( $content, ' ', $excerpt_length );
 
193
  if ( $limit ) {
194
  $content = substr( $content, 0, $limit );
195
  $shortened = true;
@@ -197,7 +135,7 @@ class RFBP_Public {
197
  }
198
  ?>
199
 
200
- <<?php echo $el; ?> class="rfbp-post">
201
  <div class="rfbp-text">
202
 
203
  <?php
@@ -209,7 +147,7 @@ class RFBP_Public {
209
 
210
  </div>
211
 
212
- <?php if ( $show_link_previews && isset( $p['link_url'] ) && !empty( $p['link_url'] ) && !empty( $p['link_name'] ) ) { ?>
213
 
214
  <p class="rfbp-link-wrap">
215
  <a class="rfbp-link" href="<?php echo $p['link_url']; ?>" rel="external nofollow" target="<?php echo $link_target; ?>">
@@ -220,47 +158,57 @@ class RFBP_Public {
220
  <?php } ?>
221
 
222
  <span class="rfbp-link-text-wrap">
223
- <span class="rfbp-link-name"><?php echo $p['link_name']; ?></span>
224
- <?php if ( isset( $p['link_caption'] ) ) { ?><span class="rfbp-link-caption"><?php echo $p['link_caption']; ?></span><?php } ?>
225
- <?php if ( isset( $p['link_description'] ) && !empty( $p['link_description'] ) ) { ?><span class="rfbp-link-description"><?php echo $p['link_description']; ?></span><?php } ?>
226
  </span>
227
  </a>
228
  </p>
229
 
230
  <?php } ?>
231
 
232
- <?php if ( $opts['img_size'] != 'dont_show' && isset( $p['image'] ) && !empty( $p['image'] ) ) { ?>
 
 
 
 
 
 
 
233
  <p class="rfbp-image-wrap">
234
  <a class="rfbp-image-link" target="<?php echo $link_target; ?>" href="<?php echo $p['url']; ?>" rel="external nofollow">
235
- <?php $max_img_width = ( !empty( $opts['img_width'] ) ) ? $opts['img_width'].'px' : '100%'; $max_img_height = ( !empty( $opts['img_height'] ) ) ? $opts['img_height'].'px' : 'none'; ?>
236
- <img class="rfbp-image" src="<?php echo esc_attr($p['image'] . '?type=' . $opts['img_size']); ?>" style="max-width: <?php echo $max_img_width; ?>; max-height: <?php echo $max_img_height; ?>" alt="" />
237
  </a>
238
  </p>
239
  <?php } ?>
240
  <p class="rfbp-post-link-wrap">
241
- <a target="<?php echo $link_target; ?>" class="rfbp-post-link" href="<?php echo $p['url']; ?>" rel="external nofolloW">
242
- <?php if ( $likes ) { ?><span class="rfbp-like-count"><?php echo $p['like_count']; ?> <span><?php _e( "likes", 'recent-facebook-posts' ); ?><?php if ( $comments ) { ?>, <?php } ?></span></span><?php } ?>
243
- <?php if ( $comments ) { ?><span class="rfbp-comment-count"><?php echo $p['comment_count']; ?> <span><?php _e( "comments", 'recent-facebook-posts' ); ?></span></span><?php } ?>
244
- <?php if ( $likes || $comments ) { ?> &sdot; <?php } ?>
245
  <span class="rfbp-timestamp" title="<?php printf( __( '%1$s at %2$s', 'recent-facebook-posts' ), date( 'l, F j, Y', $p['timestamp'] ), date( 'G:i', $p['timestamp'] ) ); ?>"><?php echo rfbp_time_ago( $p['timestamp'] ); ?></span>
246
  </a>
247
  </p>
248
- </<?php echo $el; ?>>
249
  <?php
250
 
251
  } // end foreach $posts
252
 
253
- if ( $el == 'li' ) { echo '</ul>'; }
 
 
 
254
 
255
  } else {
256
  ?><p><?php _e( "No recent Facebook posts to show", 'recent-facebook-posts' ); ?></p><?php
257
  if ( current_user_can( 'manage_options' ) ) {
258
- ?><p><strong><?php _e( "Admins only notice", 'recent-facebook-posts' ); ?>:</strong> Did you <a href="<?php echo admin_url( 'options-general.php?page=rfbp' ); ?>">configure the plugin</a> properly?</p><?php
259
  }
260
  } ?>
261
 
262
- <?php if ( $show_page_link ) { ?>
263
- <p class="rfbp-page-link-wrap"><a class="rfbp-page-link" href="http://www.facebook.com/<?php echo $opts['fb_id']; ?>/" rel="external nofollow" target="<?php echo $link_target; ?>"><?php echo $opts['page_link_text']; ?></a></p>
264
  <?php } ?>
265
 
266
  </div>
1
  <?php
2
 
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
  class RFBP_Public {
8
 
9
  private static $instance = null;
21
 
22
  $opts = rfbp_get_settings();
23
 
24
+ include_once RFBP_PLUGIN_DIR . 'includes/functions/helpers.php';
25
+ include_once RFBP_PLUGIN_DIR . 'includes/functions/template.php';
26
 
27
  add_shortcode( 'recent_facebook_posts', array( $this, 'output' ) );
28
  add_shortcode( 'recent-facebook-posts', array( $this, 'output' ) );
42
  wp_enqueue_style( 'recent-facebook-posts-css' );
43
  }
44
 
 
 
 
 
 
 
 
 
 
 
45
  public function get_posts() {
46
 
47
  // try to get posts from cache
48
+ $posts = json_decode( get_transient( 'rfbp_posts' ), true );
49
+ if ( is_array( $posts ) ) {
50
  return $posts;
51
  }
52
 
53
+ // fetch posts from FB API
 
54
  $api = rfbp_get_api();
55
+ $posts = $api->get_posts();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ if( is_array( $posts ) ) {
 
58
 
59
+ // API call succeeded, store posts in cache
60
+ // JSON encode posts before storing
61
+ $encoded_posts = json_encode( $posts );
62
+ set_transient( 'rfbp_posts', $encoded_posts, apply_filters( 'rfbp_cache_time', 3600 ) ); // user set cache time
63
+ set_transient( 'rfbp_posts_fallback', $encoded_posts, 2629744 ); // 1 month
64
 
65
+ return $posts;
66
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
+ // API call failed, get posts from fallback transient
69
+ $posts = json_decode( get_transient( 'rfbp_posts_fallback' ), true );
 
 
 
70
 
71
+ // If fallback also failed, return empty array
72
+ if( is_array( $posts ) ) {
73
+ return $posts;
74
  }
75
 
76
+ return array();
 
 
 
 
77
 
 
78
  }
79
 
80
+ /**
81
+ * Outputs the HTML with the facebook posts
82
+ *
83
+ * @param array $atts
84
+ *
85
+ * @return string
86
+ */
87
  public function output( $atts = array() ) {
88
 
89
  $opts = rfbp_get_settings();
90
  $posts = $this->get_posts();
91
 
92
+ // upgrade from old `show_link` parameter.
93
  if ( isset( $atts['show_link'] ) ) {
94
  $atts['show_page_link'] = $atts['show_link'];
95
  }
96
 
97
+ $defaults = array(
98
+ 'number' => '5',
99
+ 'likes' => 1,
100
+ 'comments' => 1,
101
+ 'excerpt_length' => 140,
102
+ 'el' => 'div',
103
+ 'origin' => 'shortcode',
104
+ 'show_page_link' => false,
105
+ 'show_link_previews' => $opts['load_css']
106
+ );
107
+
108
+ $atts = shortcode_atts( $defaults, $atts );
109
 
110
  ob_start();
111
  ?>
112
  <!-- Recent Facebook Posts v<?php echo RFBP_VERSION; ?> - http://wordpress.org/plugins/recent-facebook-posts/ -->
113
+ <div class="recent-facebook-posts rfbp rfbp-container rfbp-<?php echo $atts['origin']; ?>">
114
  <?php
115
 
116
+ if ( $posts && ! empty( $posts ) ) {
117
 
118
+ if ( $atts['el'] == 'li' ) { echo '<ul class="rfbp-posts-wrap">'; }
119
 
120
+ $posts = array_slice( $posts, 0, $atts['number'] );
121
  $link_target = ( $opts['link_new_window'] ) ? "_blank" : '';
122
 
123
  foreach ( $posts as $p ) {
124
 
 
 
125
  $shortened = false;
126
+ $content = $p['content'];
127
 
128
+ // shorten content if it exceed the set excerpt length
129
+ if ( strlen( $content ) > $atts['excerpt_length'] ) {
130
+ $limit = strpos( $content, ' ', $atts['excerpt_length'] );
131
  if ( $limit ) {
132
  $content = substr( $content, 0, $limit );
133
  $shortened = true;
135
  }
136
  ?>
137
 
138
+ <<?php echo $atts['el']; ?> class="rfbp-post">
139
  <div class="rfbp-text">
140
 
141
  <?php
147
 
148
  </div>
149
 
150
+ <?php if ( $atts['show_link_previews'] && isset( $p['link_url'] ) && !empty( $p['link_url'] ) && !empty( $p['link_name'] ) ) { ?>
151
 
152
  <p class="rfbp-link-wrap">
153
  <a class="rfbp-link" href="<?php echo $p['link_url']; ?>" rel="external nofollow" target="<?php echo $link_target; ?>">
158
  <?php } ?>
159
 
160
  <span class="rfbp-link-text-wrap">
161
+ <span class="rfbp-link-name"><?php echo esc_html( $p['link_name'] ); ?></span>
162
+ <?php if ( isset( $p['link_caption'] ) ) { ?><span class="rfbp-link-caption"><?php echo esc_html( $p['link_caption'] ); ?></span><?php } ?>
163
+ <?php if ( isset( $p['link_description'] ) && !empty( $p['link_description'] ) ) { ?><span class="rfbp-link-description"><?php echo esc_html( $p['link_description'] ); ?></span><?php } ?>
164
  </span>
165
  </a>
166
  </p>
167
 
168
  <?php } ?>
169
 
170
+ <?php if ( $opts['img_size'] !== 'dont_show' && isset( $p['image'] ) && ! empty( $p['image'] ) ) {
171
+
172
+ // grab bigger video thumbnail (hacky)
173
+ if ( $p['type'] === 'video' && $opts['img_size'] == 'normal' ) {
174
+ $p['image'] = str_ireplace( array( "_s.jpg", "_s.png" ), array( "_n.jpg", "_n.png" ), $p['image'] );
175
+ }
176
+
177
+ ?>
178
  <p class="rfbp-image-wrap">
179
  <a class="rfbp-image-link" target="<?php echo $link_target; ?>" href="<?php echo $p['url']; ?>" rel="external nofollow">
180
+ <?php $max_img_width = ( ! empty( $opts['img_width'] ) ) ? $opts['img_width'].'px' : '100%'; $max_img_height = ( !empty( $opts['img_height'] ) ) ? $opts['img_height'].'px' : 'none'; ?>
181
+ <img class="rfbp-image" src="<?php echo esc_attr( $p['image'] . '?type=' . $opts['img_size'] ); ?>" style="<?php echo esc_attr( "max-width: {$max_img_width}; max-height: {$max_img_height}" ); ?>" alt="" />
182
  </a>
183
  </p>
184
  <?php } ?>
185
  <p class="rfbp-post-link-wrap">
186
+ <a target="<?php echo $link_target; ?>" class="rfbp-post-link" href="<?php echo esc_url( $p['url'] ); ?>" rel="external nofolloW">
187
+ <?php if ( $atts['likes'] ) { ?><span class="rfbp-like-count"><?php echo absint( $p['like_count'] ); ?> <span><?php _e( "likes", 'recent-facebook-posts' ); ?><?php if ( $atts['comments'] ) { ?>, <?php } ?></span></span><?php } ?>
188
+ <?php if ( $atts['comments'] ) { ?><span class="rfbp-comment-count"><?php echo absint( $p['comment_count'] ); ?> <span><?php _e( "comments", 'recent-facebook-posts' ); ?></span></span><?php } ?>
189
+ <?php if ( $atts['likes'] || $atts['comments'] ) { ?> &sdot; <?php } ?>
190
  <span class="rfbp-timestamp" title="<?php printf( __( '%1$s at %2$s', 'recent-facebook-posts' ), date( 'l, F j, Y', $p['timestamp'] ), date( 'G:i', $p['timestamp'] ) ); ?>"><?php echo rfbp_time_ago( $p['timestamp'] ); ?></span>
191
  </a>
192
  </p>
193
+ </<?php echo $atts['el']; ?>>
194
  <?php
195
 
196
  } // end foreach $posts
197
 
198
+ // close list
199
+ if ( $atts['el'] === 'li' ) {
200
+ echo '</ul>';
201
+ }
202
 
203
  } else {
204
  ?><p><?php _e( "No recent Facebook posts to show", 'recent-facebook-posts' ); ?></p><?php
205
  if ( current_user_can( 'manage_options' ) ) {
206
+ ?><p><strong><?php _e( "Admins only notice", 'recent-facebook-posts' ); ?>:</strong> <?php printf( __( 'Did you <a href="%s">configure the plugin</a> properly?', 'recent-facebook-posts' ), admin_url( 'options-general.php?page=rfbp' ) ); ?></p><?php
207
  }
208
  } ?>
209
 
210
+ <?php if ( $atts['show_page_link'] ) { ?>
211
+ <p class="rfbp-page-link-wrap"><a class="rfbp-page-link" href="<?php echo esc_url( 'http://www.facebook.com/' . $opts['fb_id'] . '/' ); ?>" rel="external nofollow" target="<?php echo esc_attr( $link_target ); ?>"><?php echo esc_html( $opts['page_link_text'] ); ?></a></p>
212
  <?php } ?>
213
 
214
  </div>
includes/class-widget.php CHANGED
@@ -1,5 +1,9 @@
1
  <?php
2
 
 
 
 
 
3
  class RFBP_Widget extends WP_Widget {
4
 
5
  private $defaults;
1
  <?php
2
 
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
  class RFBP_Widget extends WP_Widget {
8
 
9
  private $defaults;
includes/{plugin.php → functions/global.php} RENAMED
@@ -1,5 +1,9 @@
1
  <?php
2
 
 
 
 
 
3
  function rfbp_get_settings() {
4
  static $settings;
5
 
@@ -56,7 +60,7 @@ function rfbp_get_class() {
56
  function rfbp_get_api() {
57
  static $api;
58
 
59
- if(!$api) {
60
  $opts = rfbp_get_settings();
61
  require_once RFBP_PLUGIN_DIR . 'includes/class-api.php';
62
  $api = new RFBP_API( $opts['app_id'], $opts['app_secret'], $opts['fb_id'] );
1
  <?php
2
 
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
  function rfbp_get_settings() {
8
  static $settings;
9
 
60
  function rfbp_get_api() {
61
  static $api;
62
 
63
+ if( ! $api ) {
64
  $opts = rfbp_get_settings();
65
  require_once RFBP_PLUGIN_DIR . 'includes/class-api.php';
66
  $api = new RFBP_API( $opts['app_id'], $opts['app_secret'], $opts['fb_id'] );
includes/{helper-functions.php → functions/helpers.php} RENAMED
@@ -1,5 +1,9 @@
1
  <?php
2
 
 
 
 
 
3
  function rfbp_make_clickable($text, $target)
4
  {
5
  $clickable_text = make_clickable($text);
1
  <?php
2
 
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
  function rfbp_make_clickable($text, $target)
8
  {
9
  $clickable_text = make_clickable($text);
includes/functions/template.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if( ! defined( 'RFBP_VERSION' ) ) {
4
+ exit;
5
+ }
6
+
7
+ function recent_facebook_posts( $args = array() )
8
+ {
9
+ $rfbp = rfbp_get_class();
10
+ echo $rfbp->output($args);
11
+ }
includes/template-functions.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
-
3
- function recent_facebook_posts($args = array())
4
- {
5
- $rfbp = rfbp_get_class();
6
- echo $rfbp->output($args);
7
- }
 
 
 
 
 
 
 
includes/views/settings_page.html.php CHANGED
@@ -5,7 +5,7 @@
5
 
6
  <h2>Recent Facebook Posts</h2>
7
 
8
- <?php if(isset($notice)) { ?>
9
  <div id="setting-error-settings_updated" class="updated settings-error">
10
  <p>
11
  <?php echo $notice; ?>
@@ -17,43 +17,43 @@
17
  <form method="post" action="options.php">
18
  <?php settings_fields( 'rfb_settings_group' ); ?>
19
 
20
- <div class="rfbp-facebook-settings rfbp-<?php echo (rfbp_valid_config()) ? 'valid' : 'invalid'; ?>">
21
  <h3><?php _e('Facebook Settings', 'recent-facebook-posts'); ?></h3>
22
 
23
- <?php if(!rfbp_valid_config()) { ?>
24
  <div class="rfbp-info">
25
  <p>
26
  <?php _e('This plugin needs a Facebook application to work.', 'recent-facebook-posts'); ?>
27
  <?php _e('Please fill in the Facebook Settings fields after creating your application.', 'recent-facebook-posts'); ?>
28
  </p>
29
  <p>
30
- <?php printf(__('Not sure how to proceed? Please take a close look at the %sInstallation Instructions%s on my website.', 'recent-facebook-posts'), '<a href="http://dannyvankooten.com/wordpress-plugins/recent-facebook-posts/">', '</a>'); ?>
31
  </p>
32
  </div>
33
  <?php } ?>
34
 
35
  <table class="form-table">
36
- <tr valign="top" <?php if(empty($opts['app_id'])) echo 'class="rfbp-row-error"'; ?>>
37
  <th scope="row"><label for="rfb_app_id"><?php _e('Facebook App ID/API Key', 'recent-facebook-posts'); ?></label></th>
38
  <td>
39
  <input type="text" class="widefat" placeholder="Eg: 123456789012345" id="rfb_app_id" name="rfb_settings[app_id]" value="<?php echo esc_attr($opts['app_id']); ?>" required />
40
- <small class="help"><a href="https://developers.facebook.com/apps">get from developers.facebook.com/apps</a></small>
41
  </td>
42
  </tr>
43
 
44
- <tr valign="top" <?php if(empty($opts['app_secret'])) echo 'class="rfbp-row-error"'; ?>>
45
  <th scope="row"><label for="rfb_app_secret"><?php _e('Facebook App Secret', 'recent-facebook-posts'); ?></label></th>
46
  <td>
47
  <input type="text" class="widefat" placeholder="Eg: 16vgrz4hk45wvh29k2puk45wvk2h29pu" id="rfb_app_secret" name="rfb_settings[app_secret]" value="<?php echo esc_attr($opts['app_secret']); ?>" required />
48
- <small class="help"><a href="https://developers.facebook.com/apps">get from developers.facebook.com/apps</a></small>
49
  </td>
50
  </tr>
51
 
52
- <tr valign="top" <?php if(empty($opts['fb_id'])) echo 'class="rfbp-row-error"'; ?>>
53
  <th scope="row"><label for="rfb_fb_id"><?php _e('Facebook Page ID or Slug', 'recent-facebook-posts'); ?></label></th>
54
  <td>
55
  <input type="text" class="widefat" placeholder="Eg: DannyvanKootenCOM" id="rfb_fb_id" name="rfb_settings[fb_id]" value="<?php echo esc_attr($opts['fb_id']); ?>" required />
56
- <small><a target="_blank" href="http://findmyfacebookid.com/"><?php _e('Use this tool to find the numeric ID of the Facebook page you want to fetch posts from', 'recent-facebook-posts'); ?></a></small>
57
  </td>
58
  </tr>
59
  </table>
@@ -69,12 +69,12 @@
69
 
70
  <tr valign="top">
71
  <th scope="row"><label for="rfb_link_new_window"><?php _e('Open links in new window?', 'recent-facebook-posts'); ?></label></th>
72
- <td><input type="checkbox" id="rfb_link_new_window" name="rfb_settings[link_new_window]" value="1" <?php checked($opts['link_new_window'], 1); ?> /></td>
73
  </tr>
74
 
75
  <tr valign="top">
76
- <th scope="row"><label for="rfb_load_css"><?php _e('Load some default CSS?', 'recent-facebook-posts'); ?></label></th>
77
- <td><input type="checkbox" id="rfb_load_css" name="rfb_settings[load_css]" value="1" <?php checked($opts['load_css'], 1); ?> /></td>
78
  </tr>
79
  </tbody>
80
  <tbody>
@@ -91,15 +91,15 @@
91
  </tbody>
92
  <tbody id="rfb_img_options" <?php if($opts['img_size'] == 'dont_show') echo 'style="display:none;"'; ?>>
93
  <tr valign="top">
94
- <th><?php _e('Image dimensions', 'recent-facebook-posts'); ?><br /><small>(in pixels, optional)</small></th>
95
  <td>
96
  <label style="float:left; margin-right:20px; ">
97
  <?php _e('Max Width', 'recent-facebook-posts'); ?><br />
98
- <input type="number" min="0" max="1600" size="3" id="rfb_img_width" name="rfb_settings[img_width]" value="<?php echo esc_attr($opts['img_width']); ?>" />
99
  </label>
100
  <label style="float:left; margin-right:20px;">
101
  <?php _e('Max Height', 'recent-facebook-posts'); ?><br />
102
- <input type="number" min="0" max="1600" size="3" id="rfb_img_height" name="rfb_settings[img_height]" value="<?php echo esc_attr($opts['img_height']); ?>" />
103
  </label>
104
  <br />
105
  <small class="help"><?php _e('Leave empty for default sizing', 'recent-facebook-posts'); ?></small>
@@ -123,7 +123,7 @@
123
  </form>
124
 
125
  <h3 class="rfbp-title">Facebook Posts Cache</h3>
126
- <p><?php _e('Because fetching posts from Facebook is slow the posts are cached for <strong>30 minutes</strong>. You can manually clear the cache using the button below.', 'recent-facebook-posts'); ?></p>
127
  <form action="<?php echo admin_url('options-general.php?page=rfbp'); ?>" method="post">
128
  <input type="hidden" name="rfbp-clear-cache" value="1" />
129
  <input type="submit" class="button-primary" value="<?php _e('Clear Cache', 'recent-facebook-posts'); ?>" />
@@ -177,11 +177,11 @@
177
  </div>
178
 
179
  <div class="rfbp-box">
180
- <h3 class="rfbp-title">About the developer</h3>
181
- <p>My name is <a href="http://dannyvankooten.com/">Danny van Kooten</a>. I develop WordPress plugins which help you build your websites. I love simplicity, happy customers and clean code.</p>
182
- <p>Take a look at my other <a href="http://dannyvankooten.com/wordpress-plugins/">plugins for WordPress</a> or <em>like</em> my Facebook page to stay updated.</p>
183
- <p><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.facebook.com%2FCodeToTheChase&amp;width&amp;layout=standard&amp;action=like&amp;show_faces=true&amp;share=false&amp;appId=225994527565061" scrolling="no" frameborder="0" style="border:none; width: 100%; overflow:hidden; height: 80px;" allowTransparency="true"></iframe></p>
184
- <p>You can also follow me on twitter <a href="http://twitter.com/dannyvankooten">here</a>.</p>
185
  </div>
186
  </div>
187
  <!-- End RFBP Sidebar -->
5
 
6
  <h2>Recent Facebook Posts</h2>
7
 
8
+ <?php if( isset( $notice ) ) { ?>
9
  <div id="setting-error-settings_updated" class="updated settings-error">
10
  <p>
11
  <?php echo $notice; ?>
17
  <form method="post" action="options.php">
18
  <?php settings_fields( 'rfb_settings_group' ); ?>
19
 
20
+ <div class="rfbp-facebook-settings rfbp-<?php echo ( rfbp_valid_config() ) ? 'valid' : 'invalid'; ?>">
21
  <h3><?php _e('Facebook Settings', 'recent-facebook-posts'); ?></h3>
22
 
23
+ <?php if( ! rfbp_valid_config() ) { ?>
24
  <div class="rfbp-info">
25
  <p>
26
  <?php _e('This plugin needs a Facebook application to work.', 'recent-facebook-posts'); ?>
27
  <?php _e('Please fill in the Facebook Settings fields after creating your application.', 'recent-facebook-posts'); ?>
28
  </p>
29
  <p>
30
+ <?php printf(__('Not sure how to proceed? Please take a close look at the <a href="%s">installation instructions</a>.', 'recent-facebook-posts'), 'http://wordpress.org/plugins/recent-facebook-posts/installation/' ); ?>
31
  </p>
32
  </div>
33
  <?php } ?>
34
 
35
  <table class="form-table">
36
+ <tr valign="top" <?php if( empty( $opts['app_id'] ) ) echo 'class="rfbp-row-error"'; ?>>
37
  <th scope="row"><label for="rfb_app_id"><?php _e('Facebook App ID/API Key', 'recent-facebook-posts'); ?></label></th>
38
  <td>
39
  <input type="text" class="widefat" placeholder="Eg: 123456789012345" id="rfb_app_id" name="rfb_settings[app_id]" value="<?php echo esc_attr($opts['app_id']); ?>" required />
40
+ <p class="help"><?php printf( __( 'Get your App ID from %s.', 'recent-facebook-posts' ), '<a href="https://developers.facebook.com/apps">developers.facebook.com/apps</a>' ); ?></p>
41
  </td>
42
  </tr>
43
 
44
+ <tr valign="top" <?php if( empty( $opts['app_secret'] ) ) echo 'class="rfbp-row-error"'; ?>>
45
  <th scope="row"><label for="rfb_app_secret"><?php _e('Facebook App Secret', 'recent-facebook-posts'); ?></label></th>
46
  <td>
47
  <input type="text" class="widefat" placeholder="Eg: 16vgrz4hk45wvh29k2puk45wvk2h29pu" id="rfb_app_secret" name="rfb_settings[app_secret]" value="<?php echo esc_attr($opts['app_secret']); ?>" required />
48
+ <p class="help"><?php printf( __( 'Get your App Secret from %s.', 'recent-facebook-posts' ), '<a href="https://developers.facebook.com/apps">developers.facebook.com/apps</a>' ); ?></p>
49
  </td>
50
  </tr>
51
 
52
+ <tr valign="top" <?php if( empty( $opts['fb_id'] ) ) echo 'class="rfbp-row-error"'; ?>>
53
  <th scope="row"><label for="rfb_fb_id"><?php _e('Facebook Page ID or Slug', 'recent-facebook-posts'); ?></label></th>
54
  <td>
55
  <input type="text" class="widefat" placeholder="Eg: DannyvanKootenCOM" id="rfb_fb_id" name="rfb_settings[fb_id]" value="<?php echo esc_attr($opts['fb_id']); ?>" required />
56
+ <p class="help"><?php printf( __( 'Use <a href="%s">this tool</a> to find the numeric ID of your Facebook page.', 'recent-facebook-posts' ), 'http://findmyfacebookid.com' ); ?></p>
57
  </td>
58
  </tr>
59
  </table>
69
 
70
  <tr valign="top">
71
  <th scope="row"><label for="rfb_link_new_window"><?php _e('Open links in new window?', 'recent-facebook-posts'); ?></label></th>
72
+ <td><input type="checkbox" id="rfb_link_new_window" name="rfb_settings[link_new_window]" value="1" <?php checked( $opts['link_new_window'], 1 ); ?> /></td>
73
  </tr>
74
 
75
  <tr valign="top">
76
+ <th scope="row"><label for="rfb_load_css"><?php _e('Load some default styles?', 'recent-facebook-posts'); ?></label></th>
77
+ <td><input type="checkbox" id="rfb_load_css" name="rfb_settings[load_css]" value="1" <?php checked( $opts['load_css'], 1 ); ?> /></td>
78
  </tr>
79
  </tbody>
80
  <tbody>
91
  </tbody>
92
  <tbody id="rfb_img_options" <?php if($opts['img_size'] == 'dont_show') echo 'style="display:none;"'; ?>>
93
  <tr valign="top">
94
+ <th><?php _e('Image dimensions', 'recent-facebook-posts'); ?><br /><small><?php _e( '(in pixels, optional)', 'recent-facebook-posts' ); ?></small></th>
95
  <td>
96
  <label style="float:left; margin-right:20px; ">
97
  <?php _e('Max Width', 'recent-facebook-posts'); ?><br />
98
+ <input type="number" min="0" max="1600" size="3" id="rfb_img_width" name="rfb_settings[img_width]" value="<?php echo esc_attr( $opts['img_width'] ); ?>" />
99
  </label>
100
  <label style="float:left; margin-right:20px;">
101
  <?php _e('Max Height', 'recent-facebook-posts'); ?><br />
102
+ <input type="number" min="0" max="1600" size="3" id="rfb_img_height" name="rfb_settings[img_height]" value="<?php echo esc_attr( $opts['img_height'] ); ?>" />
103
  </label>
104
  <br />
105
  <small class="help"><?php _e('Leave empty for default sizing', 'recent-facebook-posts'); ?></small>
123
  </form>
124
 
125
  <h3 class="rfbp-title">Facebook Posts Cache</h3>
126
+ <p><?php _e('Because fetching posts from Facebook is relatively slow the posts are cached for <strong>30 minutes</strong>. You can manually clear the cache using the button below.', 'recent-facebook-posts'); ?></p>
127
  <form action="<?php echo admin_url('options-general.php?page=rfbp'); ?>" method="post">
128
  <input type="hidden" name="rfbp-clear-cache" value="1" />
129
  <input type="submit" class="button-primary" value="<?php _e('Clear Cache', 'recent-facebook-posts'); ?>" />
177
  </div>
178
 
179
  <div class="rfbp-box">
180
+ <h3 class="rfbp-title">About <a href="http://dannyvankooten.com/">Danny van Kooten</a></h3>
181
+ <p>A twenty-something Dutch guy writing code and emails for a living.</p>
182
+ <p>I developed <a href="http://dannyvankooten.com/wordpress-plugins/">a few WordPress plugins</a> together totaling well over a million downloads, one of which you're using right now.</p>
183
+ <p>If you like to stay updated of what I'm doing, consider following <a href="http://twitter.com/dannyvankooten">@DannyvanKooten</a> on Twitter.</p>
184
+ <p>Hope you enjoy the plugin!</p>
185
  </div>
186
  </div>
187
  <!-- End RFBP Sidebar -->
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: DvanKooten
3
  Donate link: http://dannyvankooten.com/donate/
4
  Tags: facebook,posts,fanpage,recent posts,fb,like box alternative,widget,facebook widget,widgets,facebook updates,like button,fb posts
5
- Requires at least: 3.1
6
- Tested up to: 3.7.1
7
- Stable tag: 1.8.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -146,6 +146,23 @@ add_filter('rfbp_cache_time', 'my_rfbp_cache_time');
146
 
147
  == Changelog ==
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  = 1.8.5 - December 3, 2013 =
150
  * Fixed: Character encoding for scandinavian languages etc.
151
 
@@ -320,14 +337,5 @@ add_filter('rfbp_cache_time', 'my_rfbp_cache_time');
320
 
321
  == Upgrade Notice ==
322
 
323
- = 1.8.5 =
324
- Fixed character encoding for Scandinavian characters plus many improvements to the configuration process.
325
-
326
- = 1.8.1 =
327
- Added link previews (like Facebook) and Dutch translations. Please update your settings after updating.
328
-
329
- = 1.8 =
330
- Added link previews (like Facebook) and Dutch translations. Please update your settings after updating.
331
-
332
- = 1.6 =
333
- CSS and HTML output have changed. If you're using custom CSS styles you will have to edit them after updating.
2
  Contributors: DvanKooten
3
  Donate link: http://dannyvankooten.com/donate/
4
  Tags: facebook,posts,fanpage,recent posts,fb,like box alternative,widget,facebook widget,widgets,facebook updates,like button,fb posts
5
+ Requires at least: 3.5
6
+ Tested up to: 4.0
7
+ Stable tag: 2.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
146
 
147
  == Changelog ==
148
 
149
+ = 2.0 - September 15, 2014 =
150
+
151
+ **Fixes**
152
+
153
+ - Fixed an issue with Facebook statuses containing Emojis
154
+
155
+ **Improvements**
156
+
157
+ - Better sanitizing throughout the plugin, using native WP functions.
158
+ - Improved inline code documentation
159
+ - Prevent direct file access
160
+ - Changing thumbnail sizes does not require a cache refresh to fetch new video images
161
+
162
+ **Additions**
163
+
164
+ - New FB configurations are now automatically tested.
165
+
166
  = 1.8.5 - December 3, 2013 =
167
  * Fixed: Character encoding for scandinavian languages etc.
168
 
337
 
338
  == Upgrade Notice ==
339
 
340
+ = 2.0 =
341
+ Fixed issue with Emojis breaking all posts. Various other code improvements.
 
 
 
 
 
 
 
 
 
recent-facebook-posts.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Recent Facebook Posts
4
  Plugin URI: http://dannyvankooten.com/wordpress-plugins/recent-facebook-posts/
5
  Description: Lists most recent posts from a public Facebook page.
6
- Version: 1.8.5
7
  Author: Danny van Kooten
8
  Author URI: http://dannyvankooten.com/
9
  Text Domain: recent-facebook-posts
@@ -27,23 +27,22 @@ You should have received a copy of the GNU General Public License
27
  along with this program. If not, see <http://www.gnu.org/licenses/>.
28
  */
29
 
30
- if(! defined("ABSPATH") ) {
31
  exit;
32
  }
33
 
34
- define("RFBP_VERSION", "1.8.5");
35
- define("RFBP_PLUGIN_DIR", plugin_dir_path(__FILE__));
 
36
 
37
- // define WP_CONTENT_DIR since we're using it..
38
- if ( ! defined( 'WP_CONTENT_DIR' ) ) { define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); }
39
 
40
- require RFBP_PLUGIN_DIR . 'includes/plugin.php';
41
-
42
- if(!is_admin()) {
43
 
44
  rfbp_get_class();
45
 
46
- } elseif(!defined("DOING_AJAX") || !DOING_AJAX) {
47
 
48
  require RFBP_PLUGIN_DIR . 'includes/class-admin.php';
49
  new RFBP_Admin();
3
  Plugin Name: Recent Facebook Posts
4
  Plugin URI: http://dannyvankooten.com/wordpress-plugins/recent-facebook-posts/
5
  Description: Lists most recent posts from a public Facebook page.
6
+ Version: 2.0
7
  Author: Danny van Kooten
8
  Author URI: http://dannyvankooten.com/
9
  Text Domain: recent-facebook-posts
27
  along with this program. If not, see <http://www.gnu.org/licenses/>.
28
  */
29
 
30
+ if( ! defined( 'ABSPATH' ) ) {
31
  exit;
32
  }
33
 
34
+ // Plugin Constants
35
+ define( 'RFBP_VERSION', '2.0' );
36
+ define( 'RFBP_PLUGIN_DIR', dirname( __FILE__ ) . '/' );
37
 
38
+ // Include Global code
39
+ require RFBP_PLUGIN_DIR . 'includes/functions/global.php';
40
 
41
+ if( ! is_admin() ) {
 
 
42
 
43
  rfbp_get_class();
44
 
45
+ } elseif( ! defined("DOING_AJAX") || ! DOING_AJAX ) {
46
 
47
  require RFBP_PLUGIN_DIR . 'includes/class-admin.php';
48
  new RFBP_Admin();
uninstall.php CHANGED
@@ -1,7 +1,9 @@
1
  <?php
2
 
3
  //if uninstall not called from WordPress exit
4
- if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) { exit(); }
 
 
5
 
6
  delete_transient('rfbp_posts');
7
  delete_transient('rfbp_posts_fallback');
1
  <?php
2
 
3
  //if uninstall not called from WordPress exit
4
+ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
5
+ exit();
6
+ }
7
 
8
  delete_transient('rfbp_posts');
9
  delete_transient('rfbp_posts_fallback');