WP RSS Aggregator - Version 3.5.2

Version Description

(2013-11-11) = * Fixed bug: Invalid feed source url was producing an Undefined method notice. * Fixed bug: Custom feed was producing a 404 page. * Fixed bug: Presstrends code firing on admin_init, opt-in implementation coming soon

Download this release

Release Info

Developer jeangalea
Plugin Icon 128x128 WP RSS Aggregator
Version 3.5.2
Comparing to
See all releases

Version 3.5.2

Files changed (66) hide show
  1. changelog.txt +163 -0
  2. css/admin-editor.css +100 -0
  3. css/admin-styles.css +218 -0
  4. css/colorbox.css +93 -0
  5. css/styles.css +18 -0
  6. images/colorbox/border.png +0 -0
  7. images/colorbox/controls.png +0 -0
  8. images/colorbox/ie6/borderBottomCenter.png +0 -0
  9. images/colorbox/ie6/borderBottomLeft.png +0 -0
  10. images/colorbox/ie6/borderBottomRight.png +0 -0
  11. images/colorbox/ie6/borderMiddleLeft.png +0 -0
  12. images/colorbox/ie6/borderMiddleRight.png +0 -0
  13. images/colorbox/ie6/borderTopCenter.png +0 -0
  14. images/colorbox/ie6/borderTopLeft.png +0 -0
  15. images/colorbox/ie6/borderTopRight.png +0 -0
  16. images/colorbox/loading.gif +0 -0
  17. images/colorbox/loading_background.png +0 -0
  18. images/colorbox/overlay.png +0 -0
  19. images/facebook.png +0 -0
  20. images/icon-adminmenu16-sprite.png +0 -0
  21. images/icon-adminpage32.png +0 -0
  22. images/twitter.png +0 -0
  23. includes/admin-ajax-notice.php +131 -0
  24. includes/admin-dashboard.php +98 -0
  25. includes/admin-debugging.php +179 -0
  26. includes/admin-display.php +367 -0
  27. includes/admin-editor.php +145 -0
  28. includes/admin-import-export.php +162 -0
  29. includes/admin-metaboxes.php +356 -0
  30. includes/admin-options.php +627 -0
  31. includes/admin-welcome.php +121 -0
  32. includes/admin.php +110 -0
  33. includes/cron-jobs.php +80 -0
  34. includes/custom-feed.php +102 -0
  35. includes/custom-post-types.php +127 -0
  36. includes/deprecated-functions.php +83 -0
  37. includes/feed-display.php +304 -0
  38. includes/feed-processing.php +649 -0
  39. includes/libraries/WP_Logging.php +360 -0
  40. includes/libraries/browser.php +1082 -0
  41. includes/misc-functions.php +97 -0
  42. includes/opml-importer.php +231 -0
  43. includes/opml.php +126 -0
  44. includes/roles-capabilities.php +107 -0
  45. includes/scripts.php +122 -0
  46. includes/shortcodes.php +20 -0
  47. includes/system-info.php +140 -0
  48. includes/update.php +227 -0
  49. js/admin-addon-ajax.js +28 -0
  50. js/admin-custom.js +85 -0
  51. js/custom.js +7 -0
  52. js/editor.js +138 -0
  53. js/jquery.colorbox-min.js +7 -0
  54. languages/default.mo +0 -0
  55. languages/default.po +272 -0
  56. languages/it.mo +0 -0
  57. languages/it.po +274 -0
  58. readme.txt +308 -0
  59. screenshot-1.png +0 -0
  60. screenshot-2.png +0 -0
  61. screenshot-3.png +0 -0
  62. screenshot-4.png +0 -0
  63. screenshot-5.png +0 -0
  64. templates/wprss.css +9 -0
  65. uninstall.php +15 -0
  66. wp-rss-aggregator.php +281 -0
changelog.txt ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 3.5.2
2
+ Fixed bug: Invalid feed source url was producing an Undefined method notice.
3
+ Fixed bug: Custom feed was producing a 404 page.
4
+ Fixed bug: Presstrends code firing on admin_init, opt-in implementation coming soon
5
+
6
+ 3.5.1 (2013-11-09)
7
+ Enhanced: Increased compatibility with RSS sources.
8
+ Fixed bug: Pagination not working on home page
9
+
10
+ 3.5 (2013-11-6)
11
+ New Feature: Can delete feed items for a particular source
12
+ Enhanced: the 'Fetch feed items' row action for feed sources resets itself after 3.5 seconds.
13
+ Enhanced: The feed image is saved for each url.
14
+ Fixed bug: Link to source now links to correct url. Previously linked to site's feed.
15
+
16
+ 3.4.6 (2013-11-1)
17
+ Enhanced: Added more hooks to debugging page for the Feed to Post add-on.
18
+ Fixed bug: Uninitialized loop index
19
+
20
+ 3.4.5 (2013-10-30)
21
+ Bug Fix: Feed items were not being imported while the WPML plugin was active.
22
+
23
+ 3.4.4 (2013-10-26)
24
+ New feature: Pagination
25
+ New feature: First implementation of editor button for easy shortcode creation
26
+ Enhanced: Feed items and sources don't show up in link manager
27
+ Enhanced: Included Presstrends code for plugin usage monitoring
28
+
29
+ 3.4.3 (2013-10-20)
30
+ Fixed bug: Removed anonymous functions for backwards PHP compatibility
31
+ Bug fix: Added suppress_filters in feed-display.php to prevent a user reported error
32
+ Bug fix: Missing <li> in certain feed displays
33
+
34
+ 3.4.2 (2013-9-19)
35
+ Enhanced: Added some hooks for Feed to Post compatibility
36
+ Enhanced: Moved date settings to a more appropriate location
37
+
38
+ 3.4.1 (2013-9-16)
39
+ Fixed Bug: Minor issue with options page - PHP notice
40
+
41
+ 3.4 (2013-9-15)
42
+ New Feature: Saving/Updating a feed source triggers an update for that source's feed items.
43
+ New Feature: Option to change Youtube, Vimeo and Dailymotion feed item URLs to embedded video players URLs
44
+ New Feature: Facebook Pages URLs are automatically detected and changed into Atom Feed URLs using FB's Graph
45
+ Enhanced: Updated jQuery Colorbox library to 1.4.29
46
+ Fixed Bug: Some settings did not have a default value set, and were throwing an 'Undefined Index' error
47
+ Fixed Bug: Admin notices do not disappear immediately when dismissed.
48
+
49
+ 3.3.3 (2013-09-08)
50
+ Fixed bug: Better function handling on uninstall, should remove uninstall issues
51
+
52
+ 3.3.2 (2013-09-07)
53
+ New feature: Added exclude parameter to shortcode
54
+ Enhanced: Added metabox links to documentation and add-ons
55
+ Fixed bug: Custom feed linking to post on user site rather than original source
56
+ Fixed bug: Custom post types issues when activitating the plugin
57
+
58
+ 3.3.1 (2013-08-09)
59
+ Fixed bug: Roles and Capabilities file had not been included
60
+ Fixed bug: Error on install, function not found
61
+
62
+ 3.3 (2013-08-08)
63
+ New feature: OPML importer
64
+ New feature: Feed item limits for individual Feed Sources
65
+ New feature: Custom feed URL
66
+ New feature: Feed limit on custom feed
67
+ New feature: New 'Fetch feed items' action for each Feed Source in listing display
68
+ New feature: Option to enable link to source
69
+ Enhanced: Date strings now change according to locale being used (i.e. compatible with WPML)
70
+ Enhanced: Capabilities implemented
71
+ Enhanced: Feed Sources row action 'View' removed
72
+ Fixed Bug: Proxy feed URLs resulting in the permalink: example.com/url
73
+
74
+ 3.2 (2013-07-06)
75
+ New feature: Parameter to limit number of feeds displayed
76
+ New feature: Paramter to limit feeds displayed to particular sources (via ID)
77
+ New feature: Now handles licensing for add-ons
78
+ Enhanced: Better feed import handling to handle large number of feed sources
79
+
80
+ 3.1.1 (2013-06-06)
81
+ Fixed bug: Incompatibility with some other plugins due to function missing namespace
82
+
83
+ 3.1 (2013-06-06)
84
+ New feature: Option to set the number of feed items imported from every feed (default 5)
85
+ New feature: Import and Export aggregator settings and feed sources
86
+ New feature: Debugging page allowing manual feed refresh and feed reset
87
+ Enhanced: Faster handling of restoring sources from trash when feed limit is 0
88
+ Fixed bug: Limiter on number of overall feeds stored not working
89
+ Fixed bug: Incompatibility issue with Foobox plugin fixed
90
+ Fixed bug: Duplicate feeds sometimes imported
91
+
92
+ 3.0 (2013-03-16)
93
+ New feature: Option to select cron frequency
94
+ New feature: Code extensibility added to be compatible with add-ons
95
+ New feature: Option to set a limit to the number of feeds stored (previously 50, hard coded)
96
+ New feature: Option to define the format of the date shown below each feed item
97
+ New feature: Option to show or hide source of feed item
98
+ New feature: Option to show or hide publish date of feed item
99
+ New feature: Option to set text preceding publish date
100
+ New feature: Option to set text preceding source of feed item
101
+ New feature: Option to link title or not
102
+ New feature: Limit of 5 items imported for each source instead of 10
103
+ Enhanced: Performance improvement when publishing new feeds in admin
104
+ Enhanced: Query tuning for better performance
105
+ Enhanced: Major code rewrite, refactoring and inclusion of hooks
106
+ Enhanced: Updated Colorbox to v1.4.1
107
+ Enhanced: Better security implementations
108
+ Enhanced: Better feed preview display
109
+ Fixed bug: Deletion of items upon source deletion not working properly
110
+ Requires: WordPress 3.3
111
+
112
+ 2.2.3 (2012-11-01)
113
+ Fixed bug: Tab navigation preventing typing in input boxes
114
+ Removed: Feeds showing up in internal linking pop up
115
+
116
+ 2.2.2 (2012-10-30)
117
+ Removed: Feeds showing up in site search results
118
+ Enhanced: Better tab button navigation when adding a new feed
119
+ Enhanced: Better guidance when a feed URL is invalid
120
+
121
+ 2.2.1 (2012-10-17)
122
+ Fixed bug: wprss_feed_source_order assumes everyone is an admin
123
+
124
+ 2.2 (2012-10-01)
125
+ New feature: Italian translation added
126
+ Enhanced: Feed source order changed to alphabetical
127
+ Fixed bug: repeated entries when having a non-valid feed source
128
+ Fixed bug: all imported feeds deleted upon trashing a single feed source
129
+
130
+ 2.1 (2012-09-27)
131
+ New feature: Now localised for translations
132
+ Fixed bug: with date string
133
+ Fixed bug: $link_before and $link_after, now working
134
+ Enhanced: Added backwards compatibility for wp_rss_aggregator() function
135
+
136
+ 2.0 (2012-09-21)
137
+ Bulk of code rewritten and refactored
138
+ Added install and upgrade functions
139
+ Added DB version setting
140
+ Feed sources now stored as Custom Post Types
141
+ Feed source list sortable ascending or descending by name
142
+ Removed days subsections in feed display
143
+ Ability to limit total number of feeds displayed
144
+ Feeds now fetched via Cron
145
+ Cron job to delete old feed items, keeps max of 50 items in DB
146
+ Now requires WordPress 3.2
147
+ updated colorbox to v1.3.20.1
148
+ Limit of 15 items max imported for each source
149
+ Fixed issue of page content displaying incorrectly after feeds
150
+
151
+ 1.1 (2012-08-13)
152
+ Now requires WordPress 3.0
153
+ More flexible fetching of images directory
154
+ Has its own top level menu item
155
+ Added settings section
156
+ Ability to open in lightbox, new window or default browser behaviour
157
+ Ability to set links as follow or no follow
158
+ Using constants for oftenly used locations
159
+ Code refactoring
160
+ Changes in file and folder structure
161
+
162
+ 1.0 (2012-01-06)
163
+ First release
css/admin-editor.css ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* EDITOR BUTTON AND DIALOG STYLES */
2
+
3
+ #wprss-overlay {
4
+ position: fixed;
5
+ top: 0;
6
+ left: 0;
7
+ right: 0;
8
+ bottom: 0;
9
+ background: rgba(0,0,0,0.6);
10
+ z-index: 999;
11
+ }
12
+
13
+ #wprss-editor-dialog {
14
+ position: absolute;
15
+ top: 0;
16
+ bottom: 0;
17
+ left: 0;
18
+ right: 0;
19
+ width: 500px;
20
+ height: 450px;
21
+ margin: auto;
22
+ }
23
+
24
+ .wprss-dialog-header {
25
+ background: #464646;
26
+ position: absolute;
27
+ top: 0;
28
+ left: 0;
29
+ right: 0;
30
+ height: 30px;
31
+ }
32
+
33
+ .wprss-dialog-header h1 {
34
+ color: #ddd;
35
+ text-shadow: rgb(68, 68, 68) 0px -1px 0px;
36
+ font-size: 16px;
37
+ font-weight: normal;
38
+ margin: 7px 0 15px 6px;
39
+ }
40
+
41
+ .wprss-dialog-header .close-btn {
42
+ position: absolute;
43
+ top: 4px;
44
+ right: 10px;
45
+ color: #ccc;
46
+ font-size: 18px;
47
+ font-weight: bold;
48
+ padding: 0px 6px 2px;
49
+ border-radius: 20px;
50
+ cursor: pointer;
51
+ }
52
+ .wprss-dialog-header .close-btn:hover {
53
+ background: white;
54
+ color: black;
55
+ }
56
+
57
+
58
+ .wprss-dialog-inside {
59
+ position: absolute;
60
+ top: 30px;
61
+ bottom: 0;
62
+ left: 0;
63
+ right: 0;
64
+ overflow: auto;
65
+ }
66
+
67
+ .wprss-dialog-inside table {
68
+ position: absolute;
69
+ display: inline-block;
70
+ top: 0;
71
+ left: 0;
72
+ right: 0;
73
+ height: auto;
74
+ padding: 10px;
75
+ box-sizing: border-box;
76
+ -moz-box-sizing: border-box;
77
+ }
78
+
79
+ .wprss-dialog-inside table tr td:first-child {
80
+ font-weight: bold;
81
+ }
82
+
83
+
84
+ #wprss-dialog-sources-container {
85
+ margin-top: 10px;
86
+ }
87
+
88
+ #wprss-dialog-feed-source-list,
89
+ #wprss-dialog-exclude-list {
90
+ min-width: 100px;
91
+ min-height: 100px;
92
+ }
93
+
94
+ #wprss-dialog-exclude-row td p:first-child {
95
+ margin-top: 0;
96
+ }
97
+
98
+ #wprss-dialog-exclude-label {
99
+ vertical-align: top;
100
+ }
css/admin-styles.css ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wprss-input {
2
+ background: none repeat scroll 0 0 #EAF2FA;
3
+ margin-bottom: 20px;
4
+ padding-bottom: 10px;
5
+ padding-left: 10px;
6
+ padding-top: 10px;
7
+ width: 600px;
8
+ }
9
+
10
+ .wprss-input p { line-height: 28px; }
11
+
12
+ .wprss-input label {
13
+ float: left;
14
+ width: 95px !important;
15
+ }
16
+
17
+ .wprss-input input {
18
+ height: 28px;
19
+ margin-bottom: 0;
20
+ padding: 0 0 0 5px;
21
+ width: 400px;
22
+ }
23
+
24
+ #icon-wprss-aggregator {
25
+ background: transparent url( '../images/icon-adminpage32.png' ) no-repeat !important;
26
+ }
27
+
28
+ body.post-type-wprss_feed #titlediv div.inside { display: none !important; }
29
+
30
+ #misc-publishing-actions,
31
+ #minor-publishing-actions { display: none; }
32
+
33
+ #custom_meta_box .form-table th { width: 100px; }
34
+
35
+ body.post-type-wprss_feed_item .add-new-h2,
36
+ body.post-type-wprss_feed_item .tablenav select[name="m"],
37
+ body.post-type-wprss_feed_item #post-query-submit
38
+ { display: none; }
39
+
40
+ body.post-type-wprss_feed_item a.row-title {
41
+ cursor: default;
42
+ font-weight: normal;
43
+ color: #555;
44
+ }
45
+
46
+ #latest-news-cpac-settings li {
47
+ list-style: none;
48
+ line-height: 16px;
49
+ }
50
+
51
+ li.twitter a {
52
+ background: transparent url('../images/twitter.png') no-repeat 0;
53
+ padding-left: 20px;
54
+ }
55
+
56
+ li.facebook a {
57
+ background: transparent url('../images/facebook.png') no-repeat 0;
58
+ padding-left: 20px;
59
+ }
60
+
61
+ li.donate_link a:hover {
62
+ color: darkGreen;
63
+ }
64
+
65
+ #preview_meta_box ul {
66
+ list-style: disc;
67
+ margin-left: 16px;
68
+ }
69
+
70
+ #preview_meta_box .invalid-feed-url {
71
+ color: red;
72
+ }
73
+
74
+ #preview_meta_box .rss-date {
75
+ color: #666;
76
+
77
+ }
78
+
79
+ /*.rss-aggregator_page_wprss-aggregator-settings .form-table th { width: 80px; }*/
80
+
81
+
82
+ /* For excerpts and thumbnails admin screens */
83
+ .wprss_feed_page_wprss-aggregator-settings input,
84
+ .wprss_feed_page_wprss-aggregator-settings input[type="checkbox"],
85
+ .wprss_feed_page_wprss-aggregator-settings input[type="radio"] {
86
+ margin-right: 8px;
87
+ }
88
+
89
+ input#default-thumbnail,
90
+ input#wprss-et-license-key,
91
+ input#wprss-c-license-key,
92
+ input#wprss-kf-license-key,
93
+ input#wprss-ftp-license-key {
94
+ width: 300px;
95
+ }
96
+
97
+ input#thumbnails-height,
98
+ input#thumbnails-width {
99
+ /*width: 29px;*/
100
+ }
101
+
102
+
103
+ /* Red Button */
104
+
105
+ .wp-core-ui .button-red {
106
+ background-color: #9B2124;
107
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#C5292E), to(#9B2124));
108
+ background-image: -webkit-linear-gradient(top, #C5292E, #9B2124);
109
+ background-image: -moz-linear-gradient(top, #C5292E, #9B2124);
110
+ background-image: -ms-linear-gradient(top, #C5292E, #9B2124);
111
+ background-image: -o-linear-gradient(top, #C5292E, #9B2124);
112
+ background-image: linear-gradient(to bottom, #C5292E, #9B2124);
113
+ border-color: #9B2124;
114
+ border-bottom-color: #8D1F21;
115
+ -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
116
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
117
+ color: #fff;
118
+ text-decoration: none;
119
+ text-shadow: 0 1px 0 rgba(0,0,0,0.1);
120
+ /*float: right;*/
121
+ }
122
+
123
+ .wp-core-ui .button-red.hover,
124
+ .wp-core-ui .button-red:hover,
125
+ .wp-core-ui .button-red.focus,
126
+ .wp-core-ui .button-red:focus {
127
+ background-color: #B72629;
128
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#D22E30), to(#9B2124));
129
+ background-image: -webkit-linear-gradient(top, #D22E30, #9B2124);
130
+ background-image: -moz-linear-gradient(top, #D22E30, #9B2124);
131
+ background-image: -ms-linear-gradient(top, #D22E30, #9B2124);
132
+ background-image: -o-linear-gradient(top, #D22E30, #9B2124);
133
+ background-image: linear-gradient(to bottom, #D22E30, #9B2124);
134
+ border-color: #7F1C1F;
135
+ -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
136
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
137
+ color: #fff;
138
+ text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
139
+ }
140
+
141
+ .wp-core-ui .button-red.focus,
142
+ .wp-core-ui .button-red:focus {
143
+ border-color: #500F0E;
144
+ -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
145
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
146
+ }
147
+
148
+ .wp-core-ui .button-red.active,
149
+ .wp-core-ui .button-red.active:hover,
150
+ .wp-core-ui .button-red.active:focus,
151
+ .wp-core-ui .button-red:active {
152
+ background: #7F1C1F;
153
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#9B2124), to(#B72629));
154
+ background-image: -webkit-linear-gradient(top, #9B2124, #B72629);
155
+ background-image: -moz-linear-gradient(top, #9B2124, #B72629);
156
+ background-image: -ms-linear-gradient(top, #9B2124, #B72629);
157
+ background-image: -o-linear-gradient(top, #9B2124, #B72629);
158
+ background-image: linear-gradient(to bottom, #9B2124, #B72629);
159
+ border-color: #601312 #AE2426 #AE2426 #AE2426;
160
+ color: rgba(255,255,255,0.95);
161
+ -webkit-box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
162
+ box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
163
+ text-shadow: 0 1px 0 rgba(0,0,0,0.1);
164
+ }
165
+
166
+ .wp-core-ui .button-red[disabled],
167
+ .wp-core-ui .button-red:disabled,
168
+ .wp-core-ui .button-red-disabled {
169
+ color: #E79496 !important;
170
+ background: #BA292B !important;
171
+ border-color: #7F1C1F !important;
172
+ -webkit-box-shadow: none !important;
173
+ box-shadow: none !important;
174
+ text-shadow: 0 -1px 0 rgba(0,0,0,0.1) !important;
175
+ cursor: default;
176
+ }
177
+
178
+ #system-info-textarea {
179
+ width: 800px;
180
+ height: 400px;
181
+ font-family: Menlo, Monaco, monospace;
182
+ background: none;
183
+ white-space: pre;
184
+ overflow: auto;
185
+ display: block;
186
+ }
187
+
188
+
189
+ /* Number Roller for Feed Source Limit */
190
+ .wprss-number-roller {
191
+ width: 75px;
192
+ }
193
+
194
+ /* Welcome Screen */
195
+ .about-wrap ul {
196
+ list-style: disc;
197
+ padding-left: 30px;
198
+ }
199
+
200
+ /* Excerpts and Thumbnails */
201
+
202
+ input#thumbnails-height,
203
+ input#thumbnails-width {
204
+ margin-right: 2px;
205
+ }
206
+
207
+ label[for=thumbnails-height],
208
+ label[for=thumbnails-width] {
209
+ margin-left: 8px;
210
+ }
211
+
212
+ .wp-list-table > thead > tr > th#thumbnail[scope="col"] {
213
+ width: 95px;
214
+ }
215
+
216
+ select + label.description {
217
+ margin-left: 8px;
218
+ }
css/colorbox.css ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ ColorBox Core Style:
3
+ The following CSS is consistent between example themes and should not be altered.
4
+ */
5
+ #colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
6
+ #cboxOverlay{position:fixed; width:100%; height:100%;}
7
+ #cboxMiddleLeft, #cboxBottomLeft{clear:left;}
8
+ #cboxContent{position:relative;}
9
+ #cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
10
+ #cboxTitle{margin:0;}
11
+ #cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
12
+ #cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
13
+ .cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
14
+ .cboxIframe{width:100%; height:100%; display:block; border:0;}
15
+ #colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
16
+
17
+ /*
18
+ User Style:
19
+ Change the following styles to modify the appearance of ColorBox. They are
20
+ ordered & tabbed in a way that represents the nesting of the generated HTML.
21
+ */
22
+ #cboxOverlay{background:url(../images/colorbox/overlay.png) repeat 0 0;}
23
+ #colorbox{outline:0;}
24
+ #cboxTopLeft{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -101px 0;}
25
+ #cboxTopRight{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -130px 0;}
26
+ #cboxBottomLeft{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -101px -29px;}
27
+ #cboxBottomRight{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -130px -29px;}
28
+ #cboxMiddleLeft{width:21px; background:url(../images/colorbox/controls.png) left top repeat-y;}
29
+ #cboxMiddleRight{width:21px; background:url(../images/colorbox/controls.png) right top repeat-y;}
30
+ #cboxTopCenter{height:21px; background:url(../images/colorbox/border.png) 0 0 repeat-x;}
31
+ #cboxBottomCenter{height:21px; background:url(../images/colorbox/border.png) 0 -29px repeat-x;}
32
+ #cboxContent{background:#fff; overflow:hidden;}
33
+ .cboxIframe{background:#fff;}
34
+ #cboxError{padding:50px; border:1px solid #ccc;}
35
+ #cboxLoadedContent{margin-bottom:28px;}
36
+ #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}
37
+ #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}
38
+ #cboxLoadingOverlay{background:url(../images/colorbox/loading_background.png) no-repeat center center;}
39
+ #cboxLoadingGraphic{background:url(../images/colorbox/loading.gif) no-repeat center center;}
40
+
41
+ /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
42
+ #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
43
+
44
+ /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
45
+ #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
46
+
47
+ #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}
48
+ #cboxPrevious{position:absolute; bottom:0; left:0; background:url(../images/colorbox/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}
49
+ #cboxPrevious:hover{background-position:-75px -25px;}
50
+ #cboxNext{position:absolute; bottom:0; left:27px; background:url(../images/colorbox/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}
51
+ #cboxNext:hover{background-position:-50px -25px;}
52
+ #cboxClose{position:absolute; bottom:0; right:0; background:url(../images/colorbox/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
53
+ #cboxClose:hover{background-position:-25px -25px;}
54
+
55
+ /*
56
+ The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
57
+ when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9.
58
+ See: http://jacklmoore.com/notes/ie-transparency-problems/
59
+ */
60
+ .cboxIE #cboxTopLeft,
61
+ .cboxIE #cboxTopCenter,
62
+ .cboxIE #cboxTopRight,
63
+ .cboxIE #cboxBottomLeft,
64
+ .cboxIE #cboxBottomCenter,
65
+ .cboxIE #cboxBottomRight,
66
+ .cboxIE #cboxMiddleLeft,
67
+ .cboxIE #cboxMiddleRight {
68
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
69
+ }
70
+
71
+ /*
72
+ The following provides PNG transparency support for IE6
73
+ Feel free to remove this and the /ie6/ directory if you have dropped IE6 support.
74
+ */
75
+ .cboxIE6 #cboxTopLeft{background:url(../images/colorbox/ie6/borderTopLeft.png);}
76
+ .cboxIE6 #cboxTopCenter{background:url(../images/colorbox/ie6/borderTopCenter.png);}
77
+ .cboxIE6 #cboxTopRight{background:url(../images/colorbox/ie6/borderTopRight.png);}
78
+ .cboxIE6 #cboxBottomLeft{background:url(../images/colorbox/ie6/borderBottomLeft.png);}
79
+ .cboxIE6 #cboxBottomCenter{background:url(../images/colorbox/ie6/borderBottomCenter.png);}
80
+ .cboxIE6 #cboxBottomRight{background:url(../images/colorbox/ie6/borderBottomRight.png);}
81
+ .cboxIE6 #cboxMiddleLeft{background:url(../images/colorbox/ie6/borderMiddleLeft.png);}
82
+ .cboxIE6 #cboxMiddleRight{background:url(../images/colorbox/ie6/borderMiddleRight.png);}
83
+
84
+ .cboxIE6 #cboxTopLeft,
85
+ .cboxIE6 #cboxTopCenter,
86
+ .cboxIE6 #cboxTopRight,
87
+ .cboxIE6 #cboxBottomLeft,
88
+ .cboxIE6 #cboxBottomCenter,
89
+ .cboxIE6 #cboxBottomRight,
90
+ .cboxIE6 #cboxMiddleLeft,
91
+ .cboxIE6 #cboxMiddleRight {
92
+ _behavior: expression(this.src = this.src ? this.src : this.currentStyle.backgroundImage.split('"')[1], this.style.background = "none", this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.src + ", sizingMethod='scale')");
93
+ }
css/styles.css ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ li.feed-item { margin-bottom: 10px; }
2
+
3
+ .thumbnail-excerpt {
4
+ overflow:hidden;
5
+ margin-bottom: 5px;
6
+ }
7
+
8
+ .thumbnail-excerpt img {
9
+ max-width:100%; float:left; margin-top: 0.5em; margin-right:10px;
10
+ }
11
+
12
+ div.source-date { clear: both; }
13
+
14
+ span.feed-source { font-size: 90%; }
15
+
16
+ .green {
17
+ color: #0BD600;
18
+ }
images/colorbox/border.png ADDED
Binary file
images/colorbox/controls.png ADDED
Binary file
images/colorbox/ie6/borderBottomCenter.png ADDED
Binary file
images/colorbox/ie6/borderBottomLeft.png ADDED
Binary file
images/colorbox/ie6/borderBottomRight.png ADDED
Binary file
images/colorbox/ie6/borderMiddleLeft.png ADDED
Binary file
images/colorbox/ie6/borderMiddleRight.png ADDED
Binary file
images/colorbox/ie6/borderTopCenter.png ADDED
Binary file
images/colorbox/ie6/borderTopLeft.png ADDED
Binary file
images/colorbox/ie6/borderTopRight.png ADDED
Binary file
images/colorbox/loading.gif ADDED
Binary file
images/colorbox/loading_background.png ADDED
Binary file
images/colorbox/overlay.png ADDED
Binary file
images/facebook.png ADDED
Binary file
images/icon-adminmenu16-sprite.png ADDED
Binary file
images/icon-adminpage32.png ADDED
Binary file
images/twitter.png ADDED
Binary file
includes/admin-ajax-notice.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Serves up a notice to leave a review for this plugin
5
+ *
6
+ * @link http://wp.tutsplus.com/tutorials/creative-coding/a-primer-on-ajax-in-the-wordpress-dashboard-requesting-and-responding/
7
+ * @link http://wptheming.com/2011/08/admin-notices-in-wordpress/
8
+ *
9
+ * @since 3.0
10
+ *
11
+ */
12
+
13
+
14
+ add_action( 'admin_init', 'wprss_admin_notice' );
15
+ /**
16
+ * Serves up a notice to leave a review for this plugin
17
+ *
18
+ * @since 3.0
19
+ */
20
+ function wprss_admin_notice() {
21
+ global $pagenow, $typenow;
22
+ if ( empty( $typenow ) && !empty( $_GET['post'] ) ) {
23
+ $post = get_post( $_GET['post'] );
24
+ if ( $post !== NULL && !is_wp_error( $post ) )
25
+ $typenow = $post->post_type;
26
+ }
27
+ $notices_settings = get_option( 'wprss_settings_notices' );
28
+
29
+ // Display the admin notice only if it hasn't been hidden and we are on a screen of WP RSS Aggregator
30
+ if ( ( false == $notices_settings ) && ( ( $typenow == 'wprss_feed' ) || ( $typenow == 'wprss_feed_item' ) ) ) {
31
+ add_action( 'admin_notices', 'wprss_display_admin_notice' );
32
+ }
33
+
34
+ }
35
+
36
+
37
+ /**
38
+ * Renders the administration notice. Also renders a hidden nonce used for security when processing the Ajax request.
39
+ *
40
+ * @since 3.0
41
+ */
42
+ function wprss_display_admin_notice() {
43
+
44
+ $html = '<div id="ajax-notification" class="updated">';
45
+ $html .= '<p>';
46
+ $html .= __( 'Did you know that you can get more RSS features? Excerpts, thumbnails, keyword filtering, importing into posts and more... Check out the <a target="_blank" href="http://www.wprssaggregator.com/extensions"><strong>extensions</strong></a> page.
47
+ <a href="javascript:;" id="dismiss-ajax-notification" style="float:right;">Dismiss this notification</a>', 'wprss' );
48
+ $html .= '</p>';
49
+ $html .= '<span id="ajax-notification-nonce" class="hidden">' . wp_create_nonce( 'ajax-notification-nonce' ) . '</span>';
50
+ $html .= '</div><!-- /.updated -->';
51
+
52
+ echo $html;
53
+ }
54
+
55
+
56
+ add_action( 'wp_ajax_wprss_hide_admin_notification', 'wprss_hide_admin_notification' );
57
+ /**
58
+ * JavaScript callback used to hide the administration notice when the 'Dismiss' anchor is clicked on the front end.
59
+ *
60
+ * @since 3.0
61
+ */
62
+ function wprss_hide_admin_notification() {
63
+
64
+ // First, check the nonce to make sure it matches what we created when displaying the message.
65
+ // If not, we won't do anything.
66
+ if( wp_verify_nonce( $_REQUEST['nonce'], 'ajax-notification-nonce' ) ) {
67
+
68
+ // If the update to the option is successful, send 1 back to the browser;
69
+ // Otherwise, send 0.
70
+ $general_settings = get_option( 'wprss_settings_notices' );
71
+ $general_settings = true;
72
+
73
+ if( update_option( 'wprss_settings_notices', $general_settings ) ) {
74
+ die( '1' );
75
+ } else {
76
+ die( '0' );
77
+ }
78
+ }
79
+ }
80
+
81
+
82
+
83
+ /**
84
+ * Checks if the addon notices option exists in the database, and creates it
85
+ * if it does not.
86
+ *
87
+ * @return The addon notices option
88
+ * @since 3.4.2
89
+ */
90
+ function wprss_check_addon_notice_option() {
91
+ $option = get_option( 'wprss_addon_notices' );
92
+ if ( $option === FALSE ) {
93
+ update_option( 'wprss_addon_notices', array() );
94
+ return array();
95
+ }
96
+ return $option;
97
+ }
98
+
99
+
100
+
101
+ /**
102
+ * This function is called through AJAX to dismiss a particular addon notification.
103
+ *
104
+ * @since 3.4.2
105
+ */
106
+ function wprss_dismiss_addon_notice() {
107
+ $addon = ( isset( $_POST['addon'] ) === TRUE )? $_POST['addon'] : null;
108
+ if ( $addon === null ) {
109
+ echo 'false';
110
+ die();
111
+ }
112
+ $notice = ( isset( $_POST['notice'] ) === TRUE )? $_POST['notice'] : null;
113
+ if ( $notice === null ){
114
+ echo 'false';
115
+ die();
116
+ }
117
+
118
+ $notices = wprss_check_addon_notice_option();
119
+ if ( isset( $notices[$addon] ) === FALSE ) {
120
+ $notices[$addon] = array();
121
+ }
122
+ if ( isset( $notices[$addon][$addon] ) === FALSE ) {
123
+ $notices[$addon][$notice] = '1';
124
+ }
125
+ update_option( 'wprss_addon_notices', $notices );
126
+ echo 'true';
127
+
128
+ die();
129
+ }
130
+
131
+ add_action( 'wp_ajax_wprss_dismiss_addon_notice', 'wprss_dismiss_addon_notice' );
includes/admin-dashboard.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Adds a dashboard page for the admin
4
+ * It is triggered on plugin activation and upon
5
+ * update.
6
+ *
7
+ * @since 3.3
8
+ */
9
+
10
+
11
+ // Exit if the page is accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) exit;
13
+
14
+
15
+ add_action( 'admin_menu', 'wprss_admin_menu' );
16
+ /**
17
+ * Adds a dashboard page.
18
+ * Usde to add the Welcome Page to the dashboard.
19
+ *
20
+ * @since 3.3
21
+ */
22
+ function wprss_admin_menu() {
23
+ // Welcome Page
24
+ add_dashboard_page(
25
+ __( 'Welcome to WP RSS Aggregator', 'wprss' ),
26
+ __( 'Welcome to WP RSS Aggregator', 'wprss' ),
27
+ 'manage_options',
28
+ 'wprss-welcome',
29
+ 'wprss_show_welcome_screen'
30
+ );
31
+ }
32
+
33
+
34
+ /**
35
+ * Callback for the Welcome Dashboard page.
36
+ * It merely includes the contents of the admin-welcome.php file,
37
+ * which contains the markup for the welcome screen.
38
+ *
39
+ * @since 3.3
40
+ */
41
+ function wprss_show_welcome_screen() {
42
+ include_once( 'admin-welcome.php' );
43
+ }
44
+
45
+
46
+ add_action( 'admin_init', 'wprss_welcome' );
47
+ /**
48
+ * Detects an activation and redirects the user to
49
+ * the welcome page.
50
+ *
51
+ * @since 3.3
52
+ */
53
+ function wprss_welcome() {
54
+ // Bail if no activation redirect
55
+ if ( ! get_transient( '_wprss_activation_redirect' ) )
56
+ return;
57
+
58
+ // Delete the redirect transient
59
+ delete_transient( '_wprss_activation_redirect' );
60
+
61
+ // Bail if activating from network, or bulk
62
+ if ( is_network_admin() || isset( $_GET['activate-multi'] ) )
63
+ return;
64
+
65
+ wp_safe_redirect( admin_url( 'index.php?page=wprss-welcome' ) );
66
+ exit;
67
+ }
68
+
69
+
70
+ add_action( 'admin_head', 'wprss_admin_head' );
71
+ /**
72
+ * Removes the dashboard welcome page from the dashboard
73
+ * menu, and adds some styles for the welcome page.
74
+ *
75
+ * @since 3.3
76
+ */
77
+ function wprss_admin_head() {
78
+ remove_submenu_page( 'index.php', 'wprss-welcome' );
79
+ ?>
80
+ <style type="text/css" media="screen">
81
+ /*<![CDATA[*/
82
+
83
+ /*.wprss-welcome-table > tbody > tr > td {
84
+ line-height: 30px;
85
+ }
86
+ .wprss-welcome-table > tbody > tr {
87
+ font-size: 1.3em;
88
+ font-weight: normal;
89
+ }
90
+ .wprss-welcome-table > thead > tr > th{
91
+ font-size: 2em;
92
+ border-bottom: 8px solid #999;
93
+ }*/
94
+
95
+ /*]]>*/
96
+ </style>
97
+ <?php
98
+ }
includes/admin-debugging.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin debugging
4
+ *
5
+ * @package WPRSSAggregator
6
+ * @subpackage Includes
7
+ * @since 3.0
8
+ * @author Jean Galea <info@jeangalea.com>
9
+ * @copyright Copyright(c) 2012-2013, Jean Galea
10
+ * @link http://www.wpmayor.com
11
+ * @license http://www.gnu.org/licenses/gpl.html
12
+ */
13
+
14
+ /*
15
+ //allow redirection, even if my theme starts to send output to the browser
16
+ add_action( 'admin_init', 'wprss_do_output_buffer' );
17
+ function wprss_do_output_buffer() {
18
+ //ob_start();
19
+ }*/
20
+
21
+
22
+ /**
23
+ * Returns the debugging operations array
24
+ *
25
+ * @since 3.4.6
26
+ */
27
+ function wprss_get_debug_operations() {
28
+ return apply_filters(
29
+ 'wprss_debug_operations',
30
+ array(
31
+ 'update-feeds' => array(
32
+ 'nonce' => 'wprss-update-feed-items',
33
+ 'run' => 'wprss_fetch_insert_all_feed_items',
34
+ 'redirect' => 'edit.php?post_type=wprss_feed&page=wprss-debugging&debug_message=1',
35
+ 'render' => 'wprss_debug_update_feeds',
36
+ ),
37
+
38
+ 'reimport-feeds' => array(
39
+ 'nonce' => 'wprss-delete-import-feed-items',
40
+ 'run' => 'wprss_feed_reset',
41
+ 'redirect' => 'edit.php?post_type=wprss_feed&page=wprss-debugging&debug_message=2',
42
+ 'render' => 'wprss_debug_reimport_feeds',
43
+ )
44
+ )
45
+ );
46
+ }
47
+
48
+
49
+ add_action( 'init', 'wprss_debug_operations' );
50
+ /**
51
+ * Performs debug operations, depending on the POST request.
52
+ *
53
+ * @since 3.3
54
+ */
55
+ function wprss_debug_operations(){
56
+
57
+ // Define the debugging operations
58
+ $debug_operations = wprss_get_debug_operations();
59
+
60
+ // Check which of the operations needs to be run
61
+ foreach ( $debug_operations as $id => $operation ) {
62
+ // If page loading after having clicked 'Update all fields'
63
+ if ( isset( $_POST[ $id ] ) && check_admin_referer( $operation['nonce'] ) ) {
64
+ call_user_func( $operation['run'] );
65
+ wp_redirect( $operation['redirect'] );
66
+ break;
67
+ }
68
+ }
69
+ }
70
+
71
+
72
+ /**
73
+ * Build the Update Feeds section
74
+ *
75
+ * @since 3.4.6
76
+ */
77
+ function wprss_debug_update_feeds() {
78
+ ?>
79
+ <h3><?php _e( 'Update All Feeds Now', 'wprss' ); ?></h3>
80
+ <p><?php _e( 'Click the blue button to update all feed items now. This will check all feed sources for any new feed items.', 'wprss' ); ?>
81
+ <br><?php _e( 'Existing feed items will not be modified.', 'wprss' ); ?>
82
+ </p>
83
+ <p><?php _e( '<strong>Note:</strong> This might take more than a few seconds if you have many feed sources.', 'wprss' ); ?></p>
84
+
85
+ <form action="edit.php?post_type=wprss_feed&page=wprss-debugging" method="post">
86
+
87
+ <?php wp_nonce_field( 'wprss-update-feed-items' );
88
+ submit_button( __( 'Update all feeds', 'wprss' ), 'primary', 'update-feeds', true ); ?>
89
+
90
+ </form>
91
+ <?php
92
+ }
93
+
94
+
95
+ /**
96
+ * Build the Update Feeds section
97
+ *
98
+ * @since 3.4.6
99
+ */
100
+ function wprss_debug_reimport_feeds() {
101
+ ?>
102
+ <h3><?php _e( 'Delete and Re-import Feeds', 'wprss' ); ?></h3>
103
+ <p><?php _e( 'Click the red button to delete all imported feed items and re-import them.', 'wprss' ); ?></p>
104
+ <p><?php _e( '<em><strong>Note:</strong> This is a server-intensive process and should only be used when instructed to by support staff.</em>', 'wprss' ); ?></p>
105
+
106
+ <form action="edit.php?post_type=wprss_feed&page=wprss-debugging" method="post">
107
+
108
+ <?php wp_nonce_field( 'wprss-delete-import-feed-items' );
109
+ submit_button( __( 'Delete and Re-import all feeds', 'wprss' ), 'button-red', 'reimport-feeds', true ); ?>
110
+
111
+ </form>
112
+ <?php
113
+ }
114
+
115
+
116
+ /**
117
+ * Build the debugging page
118
+ *
119
+ * @since 3.0
120
+ */
121
+ function wprss_debugging_page_display() {
122
+ $debug_messages = apply_filters(
123
+ 'wprss_debug_messages',
124
+ array(
125
+ '1' => 'wprss_debugging_admin_notice_update_feeds',
126
+ '2' => 'wprss_debugging_admin_notice_reimport_feeds'
127
+ )
128
+ );
129
+
130
+ ?>
131
+
132
+ <div class="wrap">
133
+ <?php screen_icon( 'wprss-aggregator' ); ?>
134
+
135
+ <h2><?php _e( 'Debugging', 'wprss' ); ?></h2>
136
+ <?php
137
+ if ( isset( $_GET['debug_message'] )) {//&& ( check_admin_referer( 'wprss-delete-import-feed-items' ) || check_admin_referer( 'wprss-update-feed-items' ) ) ) {
138
+ $message = $_GET['debug_message'];
139
+
140
+ foreach ( $debug_messages as $id => $callback) {
141
+ if ( $message == $id ) {
142
+ call_user_func( $callback );
143
+ break;
144
+ }
145
+ }
146
+ }
147
+
148
+ do_action( 'wprss_debugging_before' );
149
+
150
+ $debug_operations = wprss_get_debug_operations();
151
+ foreach( $debug_operations as $id => $data ) {
152
+ if ( isset( $data['render'] ) )
153
+ call_user_func( $data['render'] );
154
+ }
155
+
156
+ do_action( 'wprss_debugging_after' );
157
+
158
+ wprss_system_info(); ?>
159
+ </div>
160
+ <?php
161
+ }
162
+
163
+ /**
164
+ * Output admin notice that feeds have been updated successfully
165
+ *
166
+ * @since 3.0
167
+ */
168
+ function wprss_debugging_admin_notice_update_feeds() {
169
+ echo '<div class="updated"><p>Feeds are being updated in the background.</p></div>';
170
+ }
171
+
172
+ /**
173
+ * Output admin notice that feeds have been deleted and re-imported successfully
174
+ *
175
+ * @since 3.0
176
+ */
177
+ function wprss_debugging_admin_notice_reimport_feeds() {
178
+ echo '<div class="updated"><p>Feeds deleted and are being re-imported in the background.</p></div>';
179
+ }
includes/admin-display.php ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_filter( 'manage_edit-wprss_feed_columns', 'wprss_set_feed_custom_columns');
4
+ /**
5
+ * Set up the custom columns for the wprss_feed list
6
+ *
7
+ * @since 2.0
8
+ */
9
+ function wprss_set_feed_custom_columns( $columns ) {
10
+
11
+ $columns = array(
12
+ 'cb' => '<input type="checkbox" />',
13
+ 'title' => __( 'Name', 'wprss' ),
14
+ 'url' => __( 'URL', 'wprss' ),
15
+ 'description' => __( 'Description', 'wprss' )
16
+ );
17
+ $columns = apply_filters( 'wprss_set_feed_custom_columns', $columns );
18
+ $columns['id'] = __( 'ID', 'wprss' );
19
+ return $columns;
20
+ }
21
+
22
+
23
+ add_action( "manage_wprss_feed_posts_custom_column", "wprss_show_custom_columns", 10, 2 );
24
+ /**
25
+ * Show up the custom columns for the wprss_feed list
26
+ *
27
+ * @since 2.0
28
+ */
29
+ function wprss_show_custom_columns( $column, $post_id ) {
30
+
31
+ switch ( $column ) {
32
+ case 'url':
33
+ $url = get_post_meta( $post_id, 'wprss_url', true);
34
+ echo '<a href="' . esc_url($url) . '">' . esc_url($url) . '</a>';
35
+ break;
36
+ case 'description':
37
+ $description = get_post_meta( $post_id, 'wprss_description', true);
38
+ echo esc_html( $description );
39
+ break;
40
+ case 'id':
41
+ echo esc_html( $post_id );
42
+ break;
43
+ }
44
+ }
45
+
46
+
47
+ /**
48
+ * Make the custom columns sortable for wprss_feed post type
49
+ *
50
+ * @since 2.0
51
+ */
52
+ function wprss_feed_sortable_columns() {
53
+ $sortable_columns = array(
54
+ // meta column id => sortby value used in query
55
+ 'title' => 'title',
56
+ );
57
+ return apply_filters( 'wprss_feed_sortable_columns', $sortable_columns );
58
+ }
59
+
60
+
61
+ add_action( 'pre_get_posts', 'wprss_feed_source_order' );
62
+ /**
63
+ * Change order of feed sources to alphabetical ascending according to feed name
64
+ *
65
+ * @since 2.2
66
+ */
67
+ function wprss_feed_source_order( $query ) {
68
+ if ( ! is_admin() ) {
69
+ return;
70
+ }
71
+
72
+ $post_type = $query->get('post_type');
73
+
74
+ if ( $post_type == 'wprss_feed' ) {
75
+ /* Post Column: e.g. title */
76
+ if ( $query->get( 'orderby' ) == '' ) {
77
+ $query->set( 'orderby', 'title' );
78
+ }
79
+ /* Post Order: ASC / DESC */
80
+ if( $query->get( 'order' ) == '' ){
81
+ $query->set( 'order', 'ASC' );
82
+ }
83
+ }
84
+ }
85
+
86
+
87
+ add_filter( 'manage_edit-wprss_feed_item_columns', 'wprss_set_feed_item_custom_columns');
88
+ /**
89
+ * Set up the custom columns for the wprss_feed source list
90
+ *
91
+ * @since 2.0
92
+ */
93
+ function wprss_set_feed_item_custom_columns( $columns ) {
94
+
95
+ $columns = array (
96
+ 'cb' => '<input type="checkbox" />',
97
+ 'title' => __( 'Name', 'wprss' ),
98
+ 'permalink' => __( 'Permalink', 'wprss' ),
99
+ 'publishdate' => __( 'Date published', 'wprss' ),
100
+ 'source' => __( 'Source', 'wprss' )
101
+ );
102
+ return apply_filters( 'wprss_set_feed_item_custom_columns', $columns );
103
+ }
104
+
105
+
106
+ add_action( "manage_wprss_feed_item_posts_custom_column", "wprss_show_feed_item_custom_columns", 10, 2 );
107
+ /**
108
+ * Show up the custom columns for the wprss_feed list
109
+ *
110
+ * @since 2.0
111
+ */
112
+ function wprss_show_feed_item_custom_columns( $column, $post_id ) {
113
+
114
+ switch ( $column ) {
115
+ case "permalink":
116
+ $url = get_post_meta( $post_id, 'wprss_item_permalink', true);
117
+ echo '<a href="' . $url . '">' . $url. '</a>';
118
+ break;
119
+
120
+ case "publishdate":
121
+ $publishdate = date( 'Y-m-d H:i:s', get_post_meta( get_the_ID(), 'wprss_item_date', true ) ) ;
122
+ echo $publishdate;
123
+ break;
124
+
125
+ case "source":
126
+ $query = new WP_Query();
127
+ $source = '<a href="' . get_edit_post_link( get_post_meta( $post_id, 'wprss_feed_id', true ) ) . '">' . get_the_title( get_post_meta( $post_id, 'wprss_feed_id', true ) ) . '</a>';
128
+ echo $source;
129
+ break;
130
+ }
131
+ }
132
+
133
+
134
+ add_filter( "manage_edit-wprss_feed_item_sortable_columns", "wprss_feed_item_sortable_columns" );
135
+ /**
136
+ * Make the custom columns sortable
137
+ *
138
+ * @since 2.0
139
+ */
140
+ function wprss_feed_item_sortable_columns() {
141
+ $sortable_columns = array(
142
+ // meta column id => sortby value used in query
143
+ 'publishdate' => 'publishdate',
144
+ 'source' => 'source'
145
+ );
146
+ return apply_filters( 'wprss_feed_item_sortable_columns', $sortable_columns );
147
+ }
148
+
149
+
150
+ add_action( 'pre_get_posts', 'wprss_feed_item_orderby' );
151
+ /**
152
+ * Change ordering of posts on wprss_feed_item screen
153
+ *
154
+ * @since 2.0
155
+ */
156
+ function wprss_feed_item_orderby( $query ) {
157
+ if( ! is_admin() )
158
+ return;
159
+
160
+ $post_type = $query->get('post_type');
161
+
162
+ // If we're on the feed listing admin page
163
+ if ( $post_type == 'wprss_feed_item') {
164
+ // Set general orderby to date the feed item was published
165
+ $query->set('orderby','publishdate');
166
+ // If user clicks on the reorder link, implement reordering
167
+ $orderby = $query->get( 'orderby');
168
+ if( 'publishdate' == $orderby ) {
169
+ $query->set( 'meta_key', 'wprss_item_date' );
170
+ $query->set( 'orderby', 'meta_value_num' );
171
+ }
172
+ }
173
+ }
174
+
175
+
176
+ add_filter( 'post_updated_messages', 'wprss_feed_updated_messages' );
177
+ /**
178
+ * Change default notification message when new feed is added or updated
179
+ *
180
+ * @since 2.0
181
+ */
182
+ function wprss_feed_updated_messages( $messages ) {
183
+ global $post, $post_ID;
184
+
185
+ $messages[ 'wprss_feed' ] = array(
186
+ 0 => '', // Unused. Messages start at index 1.
187
+ 1 => __( 'Feed source updated. ', 'wprss' ),
188
+ 2 => __( 'Custom field updated.', 'wprss' ),
189
+ 3 => __( 'Custom field deleted.', 'wprss' ),
190
+ 4 => __( 'Feed source updated.', 'wprss' ),
191
+ 5 => '',
192
+ 6 => __( 'Feed source saved.', 'wprss' ),
193
+ 7 => __( 'Feed source saved.', 'wprss' ),
194
+ 8 => __( 'Feed source submitted.', 'wprss' ),
195
+ 9 => '',
196
+ 10 => __( 'Feed source updated.', 'wprss' )
197
+ );
198
+
199
+ return apply_filters( 'wprss_feed_updated_messages', $messages );
200
+ }
201
+
202
+
203
+ add_filter( 'post_row_actions', 'wprss_remove_row_actions', 10, 1 );
204
+ /**
205
+ * Remove actions row for imported feed items, we don't want them to be editable or viewable
206
+ *
207
+ * @since 2.0
208
+ */
209
+ function wprss_remove_row_actions( $actions )
210
+ {
211
+ if ( get_post_type() === 'wprss_feed_item' ) {
212
+ unset( $actions[ 'edit' ] );
213
+ unset( $actions[ 'view' ] );
214
+ //unset( $actions[ 'trash' ] );
215
+ unset( $actions[ 'inline hide-if-no-js' ] );
216
+ }
217
+ elseif ( get_post_type() === 'wprss_feed' ) {
218
+ unset( $actions[ 'view'] );
219
+ if ( get_post_status( get_the_ID() ) !== 'trash' ) {
220
+ $actions[ 'fetch' ] = '<a href="javascript:;" class="wprss_ajax_action" pid="'. get_the_ID() .'" purl="'.home_url().'/wp-admin/admin-ajax.php" title="'. esc_attr( __( 'Fetch Feeds', 'wprss' ) ) .'" >' . __( 'Fetch Feeds', 'wprss' ) . '</a>';
221
+
222
+ $purge_feeds_row_action_text = apply_filters( 'wprss_purge_feeds_row_action_text ', 'Delete feed items' );
223
+ $purge_feeds_row_action_title = apply_filters( 'wprss_purge_feeds_row_action_title ', 'Delete feed items imported by this feed source' );
224
+ $actions['purge-posts'] = "<a href='".admin_url("edit.php?post_type=wprss_feed&purge-feed-items=" . get_the_ID() ) . "' title='" . __( $purge_feeds_row_action_title, 'wprss' ) . "' >" . __( $purge_feeds_row_action_text, 'wprss' ) . "</a>";
225
+ }
226
+ }
227
+ return apply_filters( 'wprss_remove_row_actions', $actions );
228
+ }
229
+
230
+
231
+ add_action( 'init', 'check_delete_for_feed_source' );
232
+ /**
233
+ * Checks the GET data for the delete per feed source action request
234
+ *
235
+ * @since 3.5
236
+ */
237
+ function check_delete_for_feed_source( $source_id = NULL ) {
238
+ // then we need to check the GET data for the request
239
+ if ( isset( $_GET['purge-feed-items'] ) ) {
240
+ $source_id = $_GET['purge-feed-items'];
241
+ // Schedule a job that runs this function with the source id parameter
242
+ wp_schedule_single_event( time(), 'wprss_delete_feed_items_from_source_hook', array( $source_id ) );
243
+ // Set a transient
244
+ set_transient( 'wprss_delete_posts_by_source_notif', 'true', 30 );
245
+ // Refresh the page without the GET parameter
246
+ header( 'Location: ' . admin_url( 'edit.php?post_type=wprss_feed' ) );
247
+ exit();
248
+ } else {
249
+ // Get the notification transient
250
+ $transient = get_transient( 'wprss_delete_posts_by_source_notif' );
251
+ // If the transient is set and is set to 'true'
252
+ if ( $transient !== FALSE && $transient === 'true' ) {
253
+ // delete it
254
+ delete_transient( 'wprss_delete_posts_by_source_notif' );
255
+ // Add an action to show the notification
256
+ add_action( 'all_admin_notices', 'wprss_notify_about_deleting_source_feed_items' );
257
+ }
258
+ }
259
+ }
260
+
261
+
262
+
263
+ add_action( 'wprss_delete_feed_items_from_source_hook', 'wprss_delete_feed_items_of_feed_source', 10 , 1 );
264
+ /**
265
+ * Deletes the feed items of the feed source identified by the given ID.
266
+ *
267
+ * @param $source_id The ID of the feed source
268
+ * @since 3.5
269
+ */
270
+ function wprss_delete_feed_items_of_feed_source( $source_id ) {
271
+ $force_delete = apply_filters( 'wprss_force_delete_when_by_source', TRUE );
272
+ // WPML fix: removes the current language from the query WHERE and JOIN clauses
273
+ global $sitepress;
274
+ if ( $sitepress !== NULL ) {
275
+ remove_filter( 'posts_join', array( $sitepress,'posts_join_filter') );
276
+ remove_filter( 'posts_where', array( $sitepress,'posts_where_filter') );
277
+ }
278
+ // Run the query
279
+ $query = new WP_Query(
280
+ array(
281
+ 'meta_key' => 'wprss_feed_id',
282
+ 'meta_value' => $source_id,
283
+ 'post_type' => 'wprss_feed_item',
284
+ 'post_status' => 'any',
285
+ 'posts_per_page' => -1
286
+ )
287
+ );
288
+ $query = apply_filters( 'wprss_delete_per_source_query', $query, $source_id );
289
+ // Delete the results of the query
290
+ while( $query->have_posts() ) {
291
+ $query->the_post();
292
+ wp_delete_post( get_the_ID(), $force_delete );
293
+ }
294
+ }
295
+
296
+
297
+
298
+ /**
299
+ * Shows a notification that tells the user that feed items for a particular source are being deleted
300
+ *
301
+ * @since 3.5
302
+ */
303
+ function wprss_notify_about_deleting_source_feed_items() {
304
+ $message = __( apply_filters( 'wprss_notify_about_deleting_source_feed_items_message', 'The feeds for this feed source are being deleted in the background.' ), 'wprss' );
305
+ echo '<div class="updated"><p>' . $message . '</p></div>';
306
+ }
307
+
308
+
309
+
310
+ add_action( 'wp_ajax_wprss_fetch_feeds_action', 'wprss_fetch_feeds_action_hook' );
311
+ /**
312
+ * The AJAX function for the 'Fetch Feed Items' row action on the
313
+ * 'All Feed Sources' page.
314
+ *
315
+ * @since 3.3
316
+ */
317
+ function wprss_fetch_feeds_action_hook() {
318
+ if ( isset( $_POST['id'] ) && !empty( $_POST['id'] ) ) {
319
+ wprss_fetch_insert_single_feed_items( $_POST['id'] );
320
+ die();
321
+ }
322
+ }
323
+
324
+
325
+ add_filter( 'bulk_actions-edit-wprss_feed_item', 'wprss_custom_feed_item_bulk_actions' );
326
+ /**
327
+ * Remove bulk action link to edit imported feed items
328
+ *
329
+ * @since 2.0
330
+ */
331
+ function wprss_custom_feed_item_bulk_actions( $actions ){
332
+ unset( $actions[ 'edit' ] );
333
+ return apply_filters( 'wprss_custom_feed_item_bulk_actions', $actions );
334
+ }
335
+
336
+
337
+ add_action( 'admin_footer-edit.php', 'wprss_remove_a_from_feed_title' );
338
+ /**
339
+ * Remove hyperlink from imported feed titles in list posts screen
340
+ *
341
+ * @since 2.0
342
+ */
343
+ function wprss_remove_a_from_feed_title() {
344
+ if ( 'edit-wprss_feed_item' !== get_current_screen()->id )
345
+ return;
346
+ ?>
347
+
348
+ <script type="text/javascript">
349
+ jQuery('table.wp-list-table a.row-title').contents().unwrap();
350
+ </script>
351
+ <?php
352
+ }
353
+
354
+
355
+ add_filter( 'gettext', 'wprss_change_publish_button_text', 10, 2 );
356
+ /**
357
+ * Modify 'Publish' button text when adding a new feed source
358
+ *
359
+ * @since 2.0
360
+ */
361
+ function wprss_change_publish_button_text( $translation, $text ) {
362
+ if ( 'wprss_feed' == get_post_type()) {
363
+ if ( $text == 'Publish' )
364
+ return __( 'Publish Feed', 'wprss' );
365
+ }
366
+ return apply_filters( 'wprss_change_publish_button_text', $translation );
367
+ }
includes/admin-editor.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file contains code related to the custom button added to Wordpress' TinyMCE editor.
4
+ *
5
+ * @since 3.5
6
+ */
7
+
8
+
9
+
10
+ add_action('init', 'wprss_add_editor_button');
11
+ /**
12
+ * Adds the WPRSS button to WordPress' editor
13
+ *
14
+ * @since 3.5
15
+ */
16
+ function wprss_add_editor_button() {
17
+ if ( !current_user_can( 'edit_posts' ) && !current_user_can( 'edit_pages' ) )
18
+ return;
19
+ if ( get_user_option( 'rich_editing' ) == 'true') {
20
+ add_filter('mce_external_plugins', 'wprss_register_tinymce_plugin');
21
+ add_filter('mce_buttons', 'wprss_register_tinymce_button');
22
+ }
23
+ }
24
+
25
+
26
+ /**
27
+ * Adds a separator and the wprss button to the buttons array.
28
+ *
29
+ * @since 3.5
30
+ */
31
+ function wprss_register_tinymce_button($buttons) {
32
+ array_push( $buttons, "|", "wprss" );
33
+ return $buttons;
34
+ }
35
+
36
+
37
+ /**
38
+ * Adds the button action JS file to TinyMCE's plugin list
39
+ *
40
+ * @since 3.5
41
+ */
42
+ function wprss_register_tinymce_plugin($plugin_array) {
43
+ $plugin_array['wprss'] = WPRSS_JS . 'editor.js';
44
+ return $plugin_array;
45
+ }
46
+
47
+
48
+ add_filter( 'tiny_mce_version', 'wprss_tinymce_version');
49
+ /**
50
+ * Intercepts TinyMCE's version check and increments its version by 3.
51
+ *
52
+ * This is a hack used to work around TinyMCE's caching, that might prevent the
53
+ * new wprss button from appearing on the editor.
54
+ *
55
+ * @since 3.5
56
+ */
57
+ function wprss_tinymce_version($ver) {
58
+ $ver += 3;
59
+ return $ver;
60
+ }
61
+
62
+
63
+
64
+
65
+
66
+
67
+ add_action( 'wp_ajax_wprss_editor_dialog', 'wprss_return_dialog_contents' );
68
+ /**
69
+ *
70
+ *
71
+ */
72
+ function wprss_return_dialog_contents() {
73
+ $feed_sources = get_posts( array(
74
+ 'post_type' => 'wprss_feed',
75
+ 'post_status' => 'publish',
76
+ 'posts_per_page' => -1,
77
+ 'no_found_rows' => true
78
+ ));
79
+ $feed_sources_select = '<select id="wprss-dialog-feed-source-list" multiple>';
80
+ $feed_sources_exclude_select = '<select id="wprss-dialog-exclude-list" multiple>';
81
+ $feed_sources_both_select = '';
82
+ foreach ( $feed_sources as $source ) {
83
+ $feed_sources_both_select .= '<option value="' . $source->ID . '" >' . $source->post_title . '</option>';
84
+ }
85
+ $feed_sources_both_select .= '</select><p>Hold Ctrl or Mac Command key when clicking to select more than one feed source.</p>';
86
+
87
+ $feed_sources_select .= $feed_sources_both_select;
88
+ $feed_sources_exclude_select .= $feed_sources_both_select;
89
+
90
+ ?>
91
+ <table cellspacing="20">
92
+ <tbody>
93
+
94
+ <tr>
95
+ <td id="wprss-dialog-all-sources-label">Feed Sources</td>
96
+ <td>
97
+ <input id="wprss-dialog-all-sources" type="checkbox" checked> <label for="wprss-dialog-all-sources">All feed sources</label>
98
+ <div id="wprss-dialog-sources-container" style="display:none">
99
+ <p>Choose the feed source to display:</p>
100
+ <?php echo $feed_sources_select; ?>
101
+ </div>
102
+ <script>
103
+ jQuery('#wprss-dialog-all-sources').click( function(){
104
+ if ( jQuery(this).is(':checked') ) {
105
+ jQuery( '#wprss-dialog-sources-container' ).hide();
106
+ jQuery( '#wprss-dialog-exclude-row' ).show();
107
+ jQuery( '#wprss-dialog-all-sources-label' ).css('vertical-align', 'middle');
108
+ } else {
109
+ jQuery( '#wprss-dialog-sources-container' ).show();
110
+ jQuery( '#wprss-dialog-exclude-row' ).hide();
111
+ jQuery( '#wprss-dialog-all-sources-label' ).css('vertical-align', 'top');
112
+ }
113
+ });
114
+ jQuery('#wprss-dialog-submit').click( wprss_dialog_submit );
115
+ </script>
116
+ </td>
117
+ </tr>
118
+
119
+ <tr id="wprss-dialog-exclude-row">
120
+ <td id="wprss-dialog-exclude-label">Exclude:</td>
121
+ <td>
122
+ <p>Choose the feed sources to exclude:</p>
123
+ <?php echo $feed_sources_exclude_select; ?>
124
+ </td>
125
+ </tr>
126
+
127
+ <tr>
128
+ <td>Feed Limit:</td>
129
+ <td> <input id="wprss-dialog-feed-limit" type="number" class="wprss-number-roller" placeholder="Ignore" min="0" /> </td>
130
+ </tr>
131
+
132
+ <?php do_action( 'wprss_return_dialog_contents' ); ?>
133
+
134
+ <tr>
135
+ <td></td>
136
+ <td>
137
+ <button id="wprss-dialog-submit">Add shortcode</button>
138
+ </td>
139
+ </tr>
140
+
141
+ </tbody>
142
+ </table>
143
+ <?php
144
+ die();
145
+ }
includes/admin-import-export.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Build the import/export settings page, used to import and export the plugin's settings
4
+ * Based on http://wp.tutsplus.com/tutorials/creative-coding/creating-a-simple-backuprestore-settings-feature/
5
+ *
6
+ * @since 3.1
7
+ */
8
+
9
+
10
+ add_action( 'admin_init', 'wp_rss_aggregator_export', 1 );
11
+
12
+ /**
13
+ * Handles exporting of aggregator settings
14
+ *
15
+ * @since 3.1
16
+ */
17
+ function wp_rss_aggregator_export() {
18
+ if ( isset( $_POST['export'] ) && check_admin_referer( 'wprss-settings-export' ) ) {
19
+ $blogname = str_replace( " ", "", get_option( 'blogname' ) );
20
+ $date = date( "m-d-Y" );
21
+ $json_name = $blogname . "-" . $date; // Naming the filename that will be generated.
22
+
23
+ header( 'Content-Description: File Transfer' );
24
+ header( "Content-Type: text/json; charset=" . get_option( 'blog_charset' ) );
25
+ header( "Content-Disposition: attachment; filename=$json_name.json" );
26
+ wp_rss_set_export_data();
27
+ die();
28
+ }
29
+ }
30
+
31
+
32
+ /**
33
+ * Gathers relevant options, encodes them in Json and echoes the file
34
+ *
35
+ * @since 3.1
36
+ */
37
+ function wp_rss_set_export_data() {
38
+ $options = apply_filters(
39
+ 'wprss_fields_export',
40
+ array( 'wprss_settings_general' => get_option( 'wprss_settings_general' ) )
41
+ );
42
+ $json_file = json_encode( $options );
43
+
44
+ foreach ( $options as $key => $value ) {
45
+ $value = maybe_unserialize( $value );
46
+ $need_options[ $key ] = $value;
47
+ }
48
+ $json_file = json_encode( $need_options ); // Encode data into json data
49
+ echo $json_file;
50
+ die();
51
+ }
52
+
53
+
54
+ /**
55
+ * Notice for a successful export
56
+ *
57
+ * @since 3.1
58
+ */
59
+ function wp_rss_aggregator_export_notice() {
60
+ echo '<div class="updated"><p>All options are export successfully.</p></div>';
61
+
62
+ }
63
+
64
+
65
+ /**
66
+ * Notice for a successful import
67
+ *
68
+ * @since 3.1
69
+ */
70
+ function wp_rss_aggregator_import_notice1() {
71
+ echo '<div class="updated"><p>' . __( 'All options are restored successfully.', 'wprss' ) . '</p></div>';
72
+
73
+ }
74
+
75
+
76
+ /**
77
+ * Notice for an unsuccessful import
78
+ *
79
+ * @since 3.1
80
+ */
81
+ function wp_rss_aggregator_import_notice2() {
82
+ echo '<div class="error"><p>' . __( 'Invalid file or file size too big.', 'wprss' ) . '</p></div>';
83
+
84
+ }
85
+
86
+
87
+ add_action( 'admin_init', 'wp_rss_aggregator_import' );
88
+ /**
89
+ * Handles the importing of settings
90
+ *
91
+ * @since 3.1
92
+ */
93
+ function wp_rss_aggregator_import(){
94
+ global $pagenow;
95
+ if( $pagenow == 'admin.php' ) {
96
+ //Hope this plugin don't use admin.php for anything
97
+ return;
98
+ }
99
+ if ( isset( $_FILES['import'] ) && check_admin_referer( 'wprss-settings-import' ) ) {
100
+ if ( $_FILES['import']['error'] > 0) {
101
+ wp_die( "Error during import" );
102
+ } else {
103
+ $file_name = $_FILES['import']['name'];
104
+ $file_ext = strtolower( end( explode( ".", $file_name ) ) );
105
+ $file_size = $_FILES['import']['size'];
106
+ if ( ( $file_ext == "json" ) && ( $file_size < 500000 ) ) {
107
+ $encode_options = file_get_contents( $_FILES['import']['tmp_name'] );
108
+ $options = json_decode( $encode_options, true );
109
+ foreach ( $options as $key => $value ) {
110
+ update_option( $key, $value );
111
+ }
112
+ add_action( 'admin_notices', 'wp_rss_aggregator_import_notice1' );
113
+ }
114
+ else {
115
+ add_action( 'admin_notices', 'wp_rss_aggregator_import_notice2' );
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+
122
+ /**
123
+ * Handles the import/export page display
124
+ *
125
+ * @since 3.1
126
+ */
127
+ function wprss_import_export_settings_page_display() {
128
+ if ( !isset( $_POST['export'] ) ) { ?>
129
+ <div class="wrap">
130
+ <?php screen_icon( 'wprss-aggregator' ); ?>
131
+ <h2><?php _e( 'Import & Export Settings', 'wprss' ); ?></h2>
132
+
133
+ <h3><?php _e( 'Export Settings', 'wprss' ); ?></h3>
134
+ <p><?php _e( 'Click the <strong>Export Settings</strong> button to generate a file containing all the settings used by WP RSS Aggregator', 'wprss' ); ?></p>
135
+ <p><?php _e( 'After exporting, you can either use the backup file to restore your settings to this site or to another WordPress site.</p>', 'wprss' ); ?></p>
136
+ <form method="post">
137
+ <p class="submit">
138
+ <?php wp_nonce_field( 'wprss-settings-export' ); ?>
139
+ <input type="submit" name="export" value="<?php _e( 'Export Settings', 'wprss' ); ?>" class="button" />
140
+ </p>
141
+ </form>
142
+
143
+ <h3><?php _e( 'Import Settings', 'wprss' ); ?></h3>
144
+ <p><?php _e( 'Click the <strong>Choose file</strong> button and choose a backup file.', 'wprss' ); ?></p>
145
+ <p><?php _e( 'Press the <strong>Import Settings</strong> button, and WordPress will do the rest for you.', 'wprss' ); ?></p>
146
+ <form method='post' enctype='multipart/form-data'>
147
+ <p class="submit">
148
+ <?php wp_nonce_field( 'wprss-settings-import' ); ?>
149
+ <input type='file' name='import' />
150
+ <input type='submit' name='import' value="<?php _e( 'Import Settings', 'wprss' ); ?>" class="button" />
151
+ </p>
152
+ </form>
153
+
154
+ <h3><?php _e( 'Importing/Exporting Feed Sources', 'wprss' ); ?></h3>
155
+ <p><?php _e( 'To import/export your feed sources, please use the standard WordPress <a href="' . get_admin_url() . 'import.php">Import</a> and <a href="' . get_admin_url() . 'export.php">Export</a> functionality.', 'wprss' ); ?></p>
156
+ <p><?php _e( 'On the <a href="' . get_admin_url() . 'export.php">Export</a> page, check the <strong>Feed Sources</strong> radio button and click the <strong>Download Export File</strong> button. WordPress will then create an XML file containing all the feed sources.', 'wprss' ); ?></p>
157
+ <p><?php _e( 'On the <a href="' . get_admin_url() . 'import.php">Import</a> page, choose the previously created file and click the <strong>Upload file and import</strong> button.', 'wprss' ); ?></p>
158
+
159
+ </div>
160
+ <?php
161
+ }
162
+ }
includes/admin-metaboxes.php ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_action( 'add_meta_boxes', 'wprss_add_meta_boxes');
4
+ /**
5
+ * Set up the input boxes for the wprss_feed post type
6
+ *
7
+ * @since 2.0
8
+ */
9
+ function wprss_add_meta_boxes() {
10
+ global $wprss_meta_fields;
11
+
12
+ // Remove the default WordPress Publish box, because we will be using custom ones
13
+ remove_meta_box( 'submitdiv', 'wprss_feed', 'side' );
14
+
15
+ add_meta_box(
16
+ 'submitdiv', // $id
17
+ __( 'Save Feed Source', 'wprss' ), // $title
18
+ 'post_submit_meta_box', // $callback
19
+ 'wprss_feed', // $page
20
+ 'side', // $context
21
+ 'high' // $priority
22
+ );
23
+
24
+ add_meta_box(
25
+ 'preview_meta_box',
26
+ __( 'Feed Preview', 'wprss' ),
27
+ 'wprss_preview_meta_box_callback',
28
+ 'wprss_feed',
29
+ 'side',
30
+ 'high'
31
+ );
32
+
33
+ add_meta_box(
34
+ 'wprss-help-meta',
35
+ __( 'WP RSS Aggregator Help', 'wprss' ),
36
+ 'wprss_help_meta_box_callback',
37
+ 'wprss_feed',
38
+ 'side',
39
+ 'low'
40
+ );
41
+
42
+ add_meta_box(
43
+ 'wprss-like-meta',
44
+ __( 'Like this plugin?', 'wprss' ),
45
+ 'wprss_like_meta_box_callback',
46
+ 'wprss_feed',
47
+ 'side',
48
+ 'low'
49
+ );
50
+
51
+ add_meta_box(
52
+ 'wprss-follow-meta',
53
+ __( 'Follow us', 'wprss' ),
54
+ 'wprss_follow_meta_box_callback',
55
+ 'wprss_feed',
56
+ 'side',
57
+ 'low'
58
+ );
59
+
60
+
61
+ add_meta_box(
62
+ 'custom_meta_box',
63
+ __( 'Feed Source Details', 'wprss' ),
64
+ 'wprss_show_meta_box_callback',
65
+ 'wprss_feed',
66
+ 'normal',
67
+ 'high'
68
+ );
69
+
70
+
71
+ }
72
+
73
+
74
+ /**
75
+ * Set up fields for the meta box for the wprss_feed post type
76
+ *
77
+ * @since 2.0
78
+ */
79
+ function wprss_get_custom_fields() {
80
+ $prefix = 'wprss_';
81
+
82
+ // Field Array
83
+ $wprss_meta_fields[ 'url' ] = array(
84
+ 'label' => __( 'URL', 'wprss' ),
85
+ 'desc' => __( 'Enter feed URL (including http://)', 'wprss' ),
86
+ 'id' => $prefix .'url',
87
+ 'type' => 'text'
88
+ );
89
+
90
+ $wprss_meta_fields[ 'description' ] = array(
91
+ 'label' => __( 'Description', 'wprss' ),
92
+ 'desc' => __( 'A short description about this feed source (optional)', 'wprss' ),
93
+ 'id' => $prefix .'description',
94
+ 'type' => 'textarea'
95
+ );
96
+
97
+ $wprss_meta_fields[ 'limit' ] = array(
98
+ 'label' => __( 'Limit', 'wprss' ),
99
+ 'desc' => __( 'Enter a feed item import/display limit. Leave blank to use the default setting.', 'wprss' ),
100
+ 'id' => $prefix . 'limit',
101
+ 'type' => 'number'
102
+ );
103
+
104
+ // for extensibility, allows more meta fields to be added
105
+ return apply_filters( 'wprss_fields', $wprss_meta_fields );
106
+ }
107
+
108
+
109
+ /**
110
+ * Set up the meta box for the wprss_feed post type
111
+ *
112
+ * @since 2.0
113
+ */
114
+ function wprss_show_meta_box_callback() {
115
+ global $post;
116
+ $meta_fields = wprss_get_custom_fields();
117
+
118
+ // Use nonce for verification
119
+ wp_nonce_field( basename( __FILE__ ), 'wprss_meta_box_nonce' );
120
+
121
+ // Begin the field table and loop
122
+ echo '<table class="form-table">';
123
+
124
+ foreach ( $meta_fields as $field ) {
125
+
126
+ // get value of this field if it exists for this post
127
+ $meta = get_post_meta( $post->ID, $field['id'], true );
128
+ // begin a table row with
129
+ echo '<tr>
130
+ <th><label for="' . $field['id'] . '">' . $field['label'] . '</label></th>
131
+ <td>';
132
+
133
+ switch( $field['type'] ) {
134
+
135
+ // text
136
+ case 'text':
137
+ echo '<input type="text" name="'.$field['id'].'" id="'.$field['id'].'" value="'. esc_attr( $meta ) .'" size="55" />
138
+ <br><span class="description">'.$field['desc'].'</span>';
139
+ break;
140
+
141
+ // textarea
142
+ case 'textarea':
143
+ echo '<textarea name="'.$field['id'].'" id="'.$field['id'].'" cols="60" rows="4">'. esc_attr( $meta ) .'</textarea>
144
+ <br><span class="description">'.$field['desc'].'</span>';
145
+ break;
146
+
147
+ // checkbox
148
+ case 'checkbox':
149
+ echo '<input type="checkbox" name="'.$field['id'].'" id="'.$field['id'].'" ', esc_attr( $meta ) ? ' checked="checked"' : '','/>
150
+ <label for="'.$field['id'].'">'.$field['desc'].'</label>';
151
+ break;
152
+
153
+ // select
154
+ case 'select':
155
+ echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
156
+ foreach ($field['options'] as $option) {
157
+ echo '<option', $meta == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
158
+ }
159
+ echo '</select><br><span class="description">'.$field['desc'].'</span>';
160
+ break;
161
+
162
+ // number
163
+ case 'number':
164
+ echo '<input class="wprss-number-roller" type="number" placeholder="Default" min="0" name="'.$field['id'].'" id="'.$field['id'].'" value="'.esc_attr( $meta ).'" />
165
+ <label for="'.$field['id'].'"><span class="description">'.$field['desc'].'</span></label>';
166
+
167
+ break;
168
+
169
+ } //end switch
170
+ echo '</td></tr>';
171
+ } // end foreach
172
+ echo '</table>'; // end table
173
+ }
174
+
175
+
176
+ add_action( 'save_post', 'wprss_save_custom_fields', 10, 2 );
177
+ /**
178
+ * Save the custom fields
179
+ *
180
+ * @since 2.0
181
+ */
182
+ function wprss_save_custom_fields( $post_id, $post ) {
183
+ $meta_fields = wprss_get_custom_fields();
184
+
185
+ /* Verify the nonce before proceeding. */
186
+ if ( !isset( $_POST['wprss_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['wprss_meta_box_nonce'], basename( __FILE__ ) ) )
187
+ return $post_id;
188
+
189
+ /* Get the post type object. */
190
+ $post_type = get_post_type_object( $post->post_type );
191
+
192
+ /* Check if the current user has permission to edit the post. */
193
+ if ( !current_user_can( $post_type->cap->edit_post, $post_id ) )
194
+ return $post_id;
195
+
196
+ /* // Stop WP from clearing custom fields on autosave - maybe not needed
197
+ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
198
+ return;
199
+
200
+ // Prevent quick edit from clearing custom fields - maybe not needed
201
+ if (defined('DOING_AJAX') && DOING_AJAX)
202
+ return; */
203
+
204
+ /** Bail out if running an autosave, ajax or a cron */
205
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
206
+ return;
207
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
208
+ return;
209
+ if ( defined( 'DOING_CRON' ) && DOING_CRON )
210
+ return;
211
+
212
+ // loop through fields and save the data
213
+ foreach ( $meta_fields as $field ) {
214
+ $old = get_post_meta( $post_id, $field[ 'id' ], true );
215
+ $new = $_POST[ $field[ 'id' ] ];
216
+ if ( $new && $new != $old ) {
217
+ update_post_meta( $post_id, $field[ 'id' ], $new );
218
+ } elseif ( '' == $new && $old ) {
219
+ delete_post_meta( $post_id, $field[ 'id' ], $old );
220
+ }
221
+ } // end foreach
222
+
223
+ wp_schedule_single_event( time(), 'wprss_fetch_single_feed_hook', array( $post_id ) );
224
+ }
225
+
226
+
227
+ /**
228
+ * Generate a preview of the latest 5 posts from the feed source being added/edited
229
+ *
230
+ * @since 2.0
231
+ */
232
+ function wprss_preview_meta_box_callback() {
233
+ global $post;
234
+ $feed_url = get_post_meta( $post->ID, 'wprss_url', true );
235
+
236
+ if( ! empty( $feed_url ) ) {
237
+ $feed = fetch_feed( $feed_url );
238
+ if ( ! is_wp_error( $feed ) ) {
239
+ $items = $feed->get_items();
240
+ // Figure out how many total items there are, but limit it to 5.
241
+ $maxitems = $feed->get_item_quantity(5);
242
+
243
+ // Build an array of all the items, starting with element 0 (first element).
244
+ $items = $feed->get_items( 0, $maxitems );
245
+ echo '<h4>Latest 5 feeds available from ' . get_the_title() . '</h4>';
246
+ echo '<ul>';
247
+ foreach ( $items as $item ) {
248
+ // Get human date (comment if you want to use non human date)
249
+ $item_date = human_time_diff( $item->get_date('U'), current_time('timestamp')).' '.__( 'ago', 'rc_mdm' );
250
+ // Start displaying item content within a <li> tag
251
+ echo '<li>';
252
+ // create item link
253
+ //echo '<a href="'.esc_url( $item->get_permalink() ).'" title="'.$item_date.'">';
254
+ // Get item title
255
+ echo esc_html( $item->get_title() );
256
+ //echo '</a>';
257
+ // Display date
258
+ echo ' <div class="rss-date"><small>'.$item_date.'</small></div>';
259
+ // End <li> tag
260
+ echo '</li>';
261
+ }
262
+ echo '</ul>';
263
+ }
264
+ else _e( '<span class="invalid-feed-url"><strong>Invalid feed URL</strong> - Double check the feed source URL setting above.</span>
265
+ <p>Not sure where to find the RSS feed on a website?
266
+ <a target="_blank" href="http://webtrends.about.com/od/webfeedsyndicationrss/ss/rss_howto.htm">Click here</a> for a visual guide' , 'wprss' );
267
+ }
268
+
269
+ else _e( 'No feed URL defined yet', 'wprss' );
270
+ }
271
+
272
+
273
+ /**
274
+ * Generate Help meta box
275
+ *
276
+ * @since 2.0
277
+ *
278
+ */
279
+ function wprss_help_meta_box_callback() {
280
+ echo '<p><a href="http://www.wprssaggregator.com/documentation/">View the documentation</p>';
281
+ echo '<p><strong>';
282
+ _e( 'Need help?', 'wprss' );
283
+ echo '</strong> <a target="_blank" href="http://wordpress.org/support/plugin/wp-rss-aggregator">';
284
+ _e( 'Check out the support forum', 'wprss' );
285
+ echo '</a></p>';
286
+ echo '</strong> <a target="_blank" href="http://www.wprssaggregator.com/feature-requests/">';
287
+ _e( 'Suggest a new feature', 'wprss' );
288
+ echo '</a></p>';
289
+ }
290
+
291
+ /**
292
+ * Generate Like this plugin meta box
293
+ *
294
+ * @since 2.0
295
+ *
296
+ */
297
+ function wprss_like_meta_box_callback() { ?>
298
+ <p><?php _e( 'Why not do any or all of the following', 'wprss' ) ?>:</p>
299
+ <ul>
300
+ <li><a href="http://wordpress.org/extend/plugins/wp-rss-aggregator/"><?php _e( 'Give it a 5 star rating on WordPress.org.', 'wprss' ) ?></a></li>
301
+ <li class="donate_link"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=X9GP6BL4BLXBJ"><?php _e('Donate a token of your appreciation.', 'wprss' ); ?></a></li>
302
+ </ul>
303
+ <?php
304
+ echo '<p><strong>';
305
+ _e( 'Check out the premium add-ons:', 'wprss' );
306
+ echo '</strong>'; ?>
307
+ <ul>
308
+ <li><a href="http://www.wprssaggregator.com/extension/feed-to-post/"><?php echo 'Feed to Post'; ?></a></li>
309
+ <li><a href="http://www.wprssaggregator.com/extension/excerpts-thumbnails/"><?php echo 'Excerpts & Thumbnails'; ?></a></li>
310
+ <li><a href="http://www.wprssaggregator.com/extension/categories/"><?php echo 'Categories'; ?></a></li>
311
+ <li><a href="http://www.wprssaggregator.com/extension/keyword-filtering/"><?php echo 'Keyword Filtering'; ?></a></li>
312
+ </ul>
313
+ </p>
314
+ <?php }
315
+
316
+
317
+ /**
318
+ * Generate Follow us plugin meta box
319
+ *
320
+ * @since 2.0
321
+ *
322
+ */
323
+ function wprss_follow_meta_box_callback() {
324
+ ?>
325
+ <ul>
326
+ <li class="twitter"><a href="http://twitter.com/wpmayor"><?php _e( 'Follow WP Mayor on Twitter.', 'wprss' ) ?></a></li>
327
+ <li class="facebook"><a href="https://www.facebook.com/wpmayor"><?php _e( 'Like WP Mayor on Facebook.', 'wprss' ) ?></a></li>
328
+ </ul>
329
+ <?php }
330
+
331
+
332
+ add_action( 'add_meta_boxes', 'wprss_remove_meta_boxes', 100 );
333
+ /**
334
+ * Remove unneeded meta boxes from add feed source screen
335
+ *
336
+ * @since 2.0
337
+ */
338
+ function wprss_remove_meta_boxes() {
339
+ if ( 'wprss_feed' !== get_current_screen()->id ) return;
340
+ // Remove meta boxes of other plugins that tend to appear on all posts
341
+ remove_meta_box( 'wpseo_meta', 'wprss_feed' ,'normal' );
342
+ remove_meta_box( 'postpsp', 'wprss_feed' ,'normal' );
343
+ remove_meta_box( 'su_postmeta', 'wprss_feed' ,'normal' );
344
+ remove_meta_box( 'woothemes-settings', 'wprss_feed' ,'normal' );
345
+ remove_meta_box( 'wpcf-post-relationship', 'wprss_feed' ,'normal' );
346
+ remove_meta_box( 'wpar_plugin_meta_box ', 'wprss_feed' ,'normal' );
347
+ remove_meta_box( 'sharing_meta', 'wprss_feed' ,'advanced' );
348
+ remove_meta_box( 'content-permissions-meta-box', 'wprss_feed' ,'advanced' );
349
+ remove_meta_box( 'theme-layouts-post-meta-box', 'wprss_feed' ,'side' );
350
+ remove_meta_box( 'post-stylesheets', 'wprss_feed' ,'side' );
351
+ remove_meta_box( 'hybrid-core-post-template', 'wprss_feed' ,'side' );
352
+ remove_meta_box( 'wpcf-marketing', 'wprss_feed' ,'side' );
353
+ remove_meta_box( 'trackbacksdiv22', 'wprss_feed' ,'advanced' );
354
+ remove_meta_box( 'aiosp', 'wprss_feed' ,'advanced' );
355
+ remove_action( 'post_submitbox_start', 'fpp_post_submitbox_start_action' );
356
+ }
includes/admin-options.php ADDED
@@ -0,0 +1,627 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin settings related functions
4
+ *
5
+ * Note: Wording of options and settings is confusing, due to the plugin originally only having
6
+ * an 'options' page to enter feed sources, and now needing two screens, one for feed sources and one for
7
+ * general settings. Might implement something cleaner in the future.
8
+ *
9
+ * @package WP PRSS Aggregator
10
+ */
11
+
12
+ add_action( 'admin_init', 'wprss_admin_init' );
13
+ /**
14
+ * Register and define options and settings
15
+ * @since 2.0
16
+ * @todo add option for cron frequency
17
+ *
18
+ * Note: In the future might change to
19
+ * the way EDD builds the settings pages, cleaner method.
20
+ */
21
+ function wprss_admin_init() {
22
+
23
+ register_setting(
24
+ 'wprss_settings_general', // A settings group name.
25
+ 'wprss_settings_general', // The name of an option to sanitize and save.
26
+ 'wprss_settings_general_validate' // A callback function that sanitizes the option's value.
27
+ );
28
+
29
+ // Licensing of add-ons
30
+ register_setting(
31
+ 'wprss_settings_license_keys',
32
+ 'wprss_settings_license_keys',
33
+ ''
34
+ );
35
+
36
+
37
+ $sections = apply_filters(
38
+ 'wprss_settings_sections_array',
39
+ array(
40
+ 'general' => __( 'General plugin settings', 'wprss' ),
41
+ 'display' => __( 'Display settings', 'wprss' ),
42
+ 'styles' => __( 'Styles', 'wprss' ),
43
+ )
44
+ );
45
+
46
+ // Define the settings per section
47
+ $settings = apply_filters(
48
+ 'wprss_settings_array',
49
+ array(
50
+ 'general' => array(
51
+ 'limit-feed-items-db' => array(
52
+ 'label' => __( 'Limit feed items stored', 'wprss' ),
53
+ 'callback' => 'wprss_setting_limit_feed_items_callback'
54
+ ),
55
+ 'limit-feed-items-imported' => array(
56
+ 'label' => __( 'Limit feed items per feed', 'wprss' ),
57
+ 'callback' => 'wprss_setting_limit_feed_items_imported_callback'
58
+ ),
59
+ 'cron-interval' => array(
60
+ 'label' => __( 'Feed processing interval', 'wprss' ),
61
+ 'callback' => 'wprss_setting_cron_interval_callback'
62
+ ),
63
+ 'custom-feed-url' => array(
64
+ 'label' => __( 'Custom feed URL', 'wprss' ),
65
+ 'callback' => 'wprss_setings_custom_feed_url_callback'
66
+ ),
67
+ 'custom-feed-limit' => array(
68
+ 'label' => __( 'Custom feed limit', 'wprss' ),
69
+ 'callback' => 'wprss_setings_custom_feed_limit_callback'
70
+ ),
71
+ ),
72
+
73
+ 'display' => array(
74
+ 'source-enable' => array(
75
+ 'label' => __( 'Show source', 'wprss' ),
76
+ 'callback' => 'wprss_setting_source_enable_callback'
77
+ ),
78
+ 'text-preceding-source' => array(
79
+ 'label' => __( 'Text preceding source', 'wprss' ),
80
+ 'callback' => 'wprss_setting_text_preceding_source_callback'
81
+ ),
82
+ 'source-link' => array(
83
+ 'label' => __( 'Link source', 'wprss' ),
84
+ 'callback' => 'wprss_setting_source_link_callback'
85
+ ),
86
+ 'open-dd' => array(
87
+ 'label' => __( 'Source link open behaviour', 'wprss' ),
88
+ 'callback' => 'wprss_setting_open_dd_callback'
89
+ ),
90
+
91
+ 'link-enable' => array(
92
+ 'label' => __( 'Link title', 'wprss' ),
93
+ 'callback' => 'wprss_setting_title_link_callback'
94
+ ),
95
+ 'video-links' => array(
96
+ 'label' => __( 'For video feed items use', 'wprss' ),
97
+ 'callback' => 'wprss_setting_video_links_callback'
98
+ ),
99
+ 'follow-dd' => array(
100
+ 'label' => __( 'Set links as nofollow', 'wprss' ),
101
+ 'callback' => 'wprss_setting_follow_dd_callback'
102
+ ),
103
+ 'date-enable' => array(
104
+ 'label' => __( 'Show date', 'wprss' ),
105
+ 'callback' => 'wprss_setting_date_enable_callback'
106
+ ),
107
+ 'date-format' => array(
108
+ 'label' => __( 'Date format', 'wprss' ),
109
+ 'callback' => 'wprss_setting_date_format_callback'
110
+ ),
111
+ 'text-preceding-date' => array(
112
+ 'label' => __( 'Text preceding date', 'wprss' ),
113
+ 'callback' => 'wprss_setting_text_preceding_date_callback'
114
+ ),
115
+
116
+ 'feed-limit' => array(
117
+ 'label' => __( 'Feed display limit', 'wprss' ),
118
+ 'callback' => 'wprss_setting_feed_limit_callback'
119
+ ),
120
+ ),
121
+
122
+ 'styles' => array(
123
+ 'styles-disable' => array(
124
+ 'label' => __( 'Disable Styles', 'wprss' ),
125
+ 'callback' => 'wprss_setting_styles_disable_callback'
126
+ )
127
+ )
128
+ )
129
+ );
130
+
131
+
132
+ // Loop through each setting field and register it
133
+ foreach( $settings as $section => $fields ) {
134
+ if ( count( $fields ) > 0 ) {
135
+ $section_desc = $sections[ $section ];
136
+ add_settings_section(
137
+ "wprss_settings_${section}_section",
138
+ $section_desc,
139
+ "wprss_settings_${section}_callback",
140
+ 'wprss_settings_general'
141
+ );
142
+
143
+ foreach ( $fields as $id => $data ) {
144
+
145
+ add_settings_field(
146
+ 'wprss-settings-' . $id,
147
+ $data['label'],
148
+ $data['callback'],
149
+ 'wprss_settings_general',
150
+ "wprss_settings_${section}_section"
151
+ );
152
+
153
+ }
154
+ }
155
+ }
156
+
157
+ do_action( 'wprss_admin_init' );
158
+ }
159
+
160
+
161
+ /**
162
+ * Build the plugin settings page, used to save general settings like whether a link should be follow or no follow
163
+ * @since 1.1
164
+ */
165
+ function wprss_settings_page_display() {
166
+ ?>
167
+ <div class="wrap">
168
+ <?php screen_icon( 'wprss-aggregator' ); ?>
169
+
170
+ <h2><?php _e( 'WP RSS Aggregator Settings', 'wprss' ); ?></h2>
171
+
172
+ <?php settings_errors(); ?>
173
+
174
+ <?php $active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'general_settings'; ?>
175
+
176
+ <?php
177
+
178
+ $default_tabs = array(
179
+ 'general' => array(
180
+ 'label' => __( 'General', 'wprss' ),
181
+ 'slug' => 'general_settings',
182
+ ),
183
+ 'licenses' => array(
184
+ 'label' => __( 'Licenses', 'wprss' ),
185
+ 'slug' => 'licenses_settings'
186
+ )
187
+ );
188
+
189
+ $addon_tabs = apply_filters( 'wprss_options_tabs', array() );
190
+
191
+ $tabs = array_merge( array( $default_tabs['general'] ), $addon_tabs , array( $default_tabs['licenses'] ) );
192
+
193
+ $show_tabs = ( count( $addon_tabs ) > 0 ) || apply_filters( 'wprss_show_settings_tabs_condition', FALSE );
194
+
195
+ if ( $show_tabs ) { ?>
196
+ <h2 class="nav-tab-wrapper">
197
+ <?php
198
+ foreach ( $tabs as $tab => $tab_property ) { ?>
199
+ <a href="?post_type=wprss_feed&page=wprss-aggregator-settings&tab=<?php echo esc_attr( $tab_property['slug'] ); ?>"
200
+ class="nav-tab <?php echo $active_tab == $tab_property['slug'] ? 'nav-tab-active' : ''; ?>"><?php echo esc_html( $tab_property['label'] ); ?></a>
201
+ <?php } ?>
202
+ <?php } ?>
203
+ </h2>
204
+
205
+ <form action="options.php" method="post">
206
+
207
+ <?php
208
+
209
+ if ( $active_tab === 'general_settings' ) {
210
+ settings_fields( 'wprss_settings_general' );
211
+ do_settings_sections( 'wprss_settings_general' );
212
+ }
213
+ elseif ( $show_tabs ) {
214
+
215
+ if ( $active_tab === 'licenses_settings' ) {
216
+ settings_fields( 'wprss_settings_license_keys' );
217
+ do_settings_sections( 'wprss_settings_license_keys' );
218
+ }
219
+
220
+ do_action( 'wprss_add_settings_fields_sections', $active_tab );
221
+ }
222
+
223
+ submit_button( __( 'Save Settings', 'wprss' ) );
224
+
225
+ ?>
226
+ </form>
227
+ </div>
228
+ <?php
229
+ }
230
+
231
+
232
+ /**
233
+ * General settings section header
234
+ * @since 3.0
235
+ */
236
+ function wprss_settings_general_callback() {
237
+ echo '<p>' . __( 'These are the general settings for WP RSS Aggregator.', 'wprss' ) . '</p>';
238
+ }
239
+
240
+
241
+ /**
242
+ * General settings section header
243
+ * @since 3.5
244
+ */
245
+ function wprss_settings_display_callback() {
246
+ echo '<p>' . __( 'In this section you can find the options that control how the feed items are displayed.', 'wprss' ) . '</p>';
247
+ }
248
+
249
+
250
+ /**
251
+ * General settings section header
252
+ * @since 3.0
253
+ */
254
+ function wprss_settings_styles_callback() {
255
+ echo '<p>' . __( 'If you would like to disable all styles used in this plugin, tick the checkbox.', 'wprss' ) . '</p>';
256
+ }
257
+
258
+
259
+ /**
260
+ * Follow or No Follow dropdown
261
+ * @since 1.1
262
+ */
263
+ function wprss_setting_follow_dd_callback() {
264
+ $options = get_option( 'wprss_settings_general' );
265
+
266
+ $checked = ( $options['follow_dd'] === 'no_follow' );
267
+ $checked_attr = ( $checked )? 'checked="checked"' : '';
268
+
269
+ echo "<input type='hidden' name='wprss_settings_general[follow_dd]' value='follow'>";
270
+ echo "<input type='checkbox' id='follow-dd' name='wprss_settings_general[follow_dd]' value='no_follow' $checked_attr>";
271
+
272
+ echo '<label class="description" id="follow-dd">';
273
+ echo '"Nofollow" provides a way for webmasters to tell search engines "Don\'t follow links on this page" or "Don\'t follow this specific link."';
274
+ echo '</label>';
275
+ }
276
+
277
+
278
+ /**
279
+ * Use original video link, or embedded video links dropwdown
280
+ * @since 3.4
281
+ */
282
+ function wprss_setting_video_links_callback() {
283
+ $options = get_option( 'wprss_settings_general' );
284
+ $video_link = ( isset($options['video_link']) )? $options['video_link'] : 'false';
285
+ $items = array(
286
+ 'false' => __( 'Original page link', 'wprss' ),
287
+ 'true' => __( 'Embedded video player link', 'wprss' )
288
+ );
289
+ echo "<select id='video-link' name='wprss_settings_general[video_link]'>";
290
+ foreach ( $items as $boolean => $text ) {
291
+ $selected = ( $video_link === $boolean )? 'selected="selected"' : '';
292
+ echo "<option value='$boolean' $selected>$text</option>";
293
+ }
294
+ echo "</select>";
295
+ echo "<label class='description' for='video-link'>This will not affect already imported feed items.</label>";
296
+ }
297
+
298
+
299
+ /**
300
+ * Link open setting dropdown
301
+ * @since 1.1
302
+ */
303
+ function wprss_setting_open_dd_callback() {
304
+ $options = get_option( 'wprss_settings_general' );
305
+ $items = array(
306
+ __( 'Lightbox', 'wprss' ),
307
+ __( 'New window', 'wprss' ),
308
+ __( 'Self', 'wprss' )
309
+ );
310
+ echo "<select id='open-dd' name='wprss_settings_general[open_dd]'>";
311
+ foreach( $items as $item ) {
312
+ $selected = ( $options['open_dd'] == $item ) ? 'selected="selected"' : '';
313
+ echo "<option value='$item' $selected>$item</option>";
314
+ }
315
+ echo "</select>";
316
+ }
317
+
318
+
319
+ /**
320
+ * Set limit for feeds on frontend
321
+ * @since 2.0
322
+ */
323
+ function wprss_setting_feed_limit_callback() {
324
+ $options = get_option( 'wprss_settings_general' );
325
+ echo "<input id='feed-limit' name='wprss_settings_general[feed_limit]' type='text' value='{$options['feed_limit']}' />";
326
+ echo "<label class='description' for='feed-limit'>Enter the number of feeds to display on the front end</label>";
327
+ }
328
+
329
+
330
+ /**
331
+ * Set date format
332
+ * @since 3.0
333
+ */
334
+ function wprss_setting_date_format_callback() {
335
+ $options = get_option( 'wprss_settings_general' );
336
+ echo "<input id='date-format' name='wprss_settings_general[date_format]' type='text' value='{$options['date_format']}' />";
337
+ echo "<label class='description' for='date-format'>Date formatting, using the <a href='http://codex.wordpress.org/Formatting_Date_and_Time'>PHP date formats</a></label>";
338
+ }
339
+
340
+
341
+
342
+ /**
343
+ * Enable linked title
344
+ * @since 3.0
345
+ */
346
+ function wprss_setting_title_link_callback( $args ) {
347
+ $options = get_option( 'wprss_settings_general' );
348
+ echo "<input id='title-link' name='wprss_settings_general[title_link]' type='checkbox' value='1' " . checked( 1, $options['title_link'], false ) . " />";
349
+ echo "<label class='description' for='title-link'>Check this box to enable linked titles</label>";
350
+ }
351
+
352
+
353
+ /**
354
+ * Enable source
355
+ * @since 3.0
356
+ */
357
+ function wprss_setting_source_enable_callback( $args ) {
358
+ $options = get_option( 'wprss_settings_general' );
359
+ echo "<input id='source-enable' name='wprss_settings_general[source_enable]' type='checkbox' value='1' " . checked( 1, $options['source_enable'], false ) . " />";
360
+ echo "<label class='description' for='source-enable'>Check this box to enable feed source display</label>";
361
+ }
362
+
363
+ /**
364
+ * Enable linked title
365
+ * @since 3.0
366
+ */
367
+ function wprss_setting_source_link_callback( $args ) {
368
+ $options = get_option( 'wprss_settings_general' );
369
+ echo "<input id='source-link' name='wprss_settings_general[source_link]' type='checkbox' value='1' " . checked( 1, $options['source_link'], false ) . " />";
370
+ echo "<label class='description' for='source-link'>Check this box to enable linked sources</label>";
371
+ }
372
+
373
+
374
+ /**
375
+ * Set text preceding source
376
+ * @since 3.0
377
+ */
378
+ function wprss_setting_text_preceding_source_callback() {
379
+ $options = get_option( 'wprss_settings_general' );
380
+ echo "<input id='text-preceding-source' name='wprss_settings_general[text_preceding_source]' type='text' value='{$options['text_preceding_source']}' />";
381
+ echo "<label class='description' for='text-preceding-source'>Enter the text you want shown before the feed item's source</label>";
382
+ }
383
+ /**
384
+ * Enable date
385
+ * @since 3.0
386
+ */
387
+ function wprss_setting_date_enable_callback( $args ) {
388
+ $options = get_option( 'wprss_settings_general' );
389
+ echo "<input id='date-enable' name='wprss_settings_general[date_enable]' type='checkbox' value='1' " . checked( 1, $options['date_enable'], false ) . " />";
390
+ echo "<label class='description' for='date-enable'>Check this box to enable display of date published</label>";
391
+ }
392
+
393
+ /**
394
+ * Set text preceding date
395
+ * @since 3.0
396
+ */
397
+ function wprss_setting_text_preceding_date_callback() {
398
+ $options = get_option( 'wprss_settings_general' );
399
+ echo "<input id='text-preceding-date' name='wprss_settings_general[text_preceding_date]' type='text' value='{$options['text_preceding_date']}' />";
400
+ echo "<label class='description' for='text-preceding-date'>Enter the text you want shown before the feed item's publish date</label>";
401
+ }
402
+
403
+
404
+
405
+ /**
406
+ * Limit number of feed items stored
407
+ * @since 3.0
408
+ */
409
+ function wprss_setting_limit_feed_items_callback() {
410
+ $options = get_option( 'wprss_settings_general' );
411
+ echo "<input id='limit-feed-items-db' name='wprss_settings_general[limit_feed_items_db]' type='text' value='{$options['limit_feed_items_db']}' />";
412
+ echo "<label class='description' for='limit-feed-items-db'>Enter the maximum number of feeds to store in the database; enter 0 for unlimited feed items</label>";
413
+ }
414
+
415
+
416
+ /**
417
+ * Limit number of feed items imported per feed
418
+ * @since 3.1
419
+ */
420
+ function wprss_setting_limit_feed_items_imported_callback() {
421
+ $options = get_option( 'wprss_settings_general' );
422
+ echo "<input id='limit-feed-items-imported' name='wprss_settings_general[limit_feed_items_imported]' type='text' value='{$options['limit_feed_items_imported']}' />";
423
+ echo "<label class='description' for='limit-feed-items-imported'>Enter the maximum number of feeds to import per feed source; enter 0 for unlimited feed items</label>";
424
+ }
425
+
426
+
427
+ /**
428
+ * Gets a sorted (according to interval) list of the cron schedules
429
+ * @since 3.0
430
+ */
431
+ function wprss_get_schedules() {
432
+ $schedules = wp_get_schedules();
433
+ uasort( $schedules, create_function( '$a,$b', 'return $a["interval"]-$b["interval"];' ) );
434
+ return $schedules;
435
+ }
436
+
437
+
438
+ /**
439
+ * Cron interval dropdown callback
440
+ * @since 3.0
441
+ */
442
+ function wprss_setting_cron_interval_callback() {
443
+ $options = get_option( 'wprss_settings_general' );
444
+ $current = $options['cron_interval'];
445
+
446
+ $schedules = wprss_get_schedules();
447
+ // Set the allowed Cron schedules, we don't want any intervals that can lead to issues with server load
448
+ $wprss_schedules = apply_filters(
449
+ 'wprss_schedules',
450
+ array( 'fifteen_min', 'thirty_min', 'hourly', 'two_hours', 'twicedaily', 'daily' )
451
+ );
452
+ echo "<select id='cron-interval' name='wprss_settings_general[cron_interval]'>";
453
+ foreach( $schedules as $schedule_name => $schedule_data ) {
454
+ if ( in_array( $schedule_name, $wprss_schedules ) ) { ?>
455
+ <option value="<?php echo $schedule_name; ?>" <?php selected( $current, $schedule_name ); ?> >
456
+ <?php echo $schedule_data['display']; ?> (<?php echo wprss_interval( $schedule_data['interval'] ); ?>)
457
+ </option>
458
+ <?php } ?>
459
+ <?php } ?>
460
+ </select><?php
461
+ }
462
+
463
+ /**
464
+ * Sets the custom feed URL
465
+ * @since 3.3
466
+ */
467
+ function wprss_setings_custom_feed_url_callback() {
468
+ $options = get_option( 'wprss_settings_general' );
469
+ echo "<input id='custom_feed_url' name='wprss_settings_general[custom_feed_url]' type='text' value='{$options['custom_feed_url']}' />";
470
+ echo "<label class='description' for='custom_feed_url'>" . __( 'Custom feed URL', 'wprss' ) . "</label>";
471
+ }
472
+
473
+ /**
474
+ * Sets the custom feed limit
475
+ * @since 3.3
476
+ */
477
+ function wprss_setings_custom_feed_limit_callback() {
478
+ $options = get_option( 'wprss_settings_general' );
479
+ echo "<input id='custom_feed_limit' name='wprss_settings_general[custom_feed_limit]' placeholder='Default' min='0' class='wprss-number-roller' type='number' value='{$options['custom_feed_limit']}' />";
480
+ echo "<label class='description' for='custom_feed_limit'>" . __( 'Number of items to show in the custom feed', 'wprss' ) . "</label>";
481
+ }
482
+
483
+ /**
484
+ * Disable styles
485
+ * @since 3.0
486
+ */
487
+ function wprss_setting_styles_disable_callback( $args ) {
488
+ $options = get_option( 'wprss_settings_general' );
489
+ echo "<input id='styles-disable' name='wprss_settings_general[styles_disable]' type='checkbox' value='1' " . checked( 1, $options['styles_disable'], false ) . " />";
490
+ echo "<label class='description' for='styles-disable'>Check this box to disable all plugin styles</label>";
491
+ echo "<p class='description'>You will then be responsible for providing your own CSS styles.</p>";
492
+ }
493
+
494
+
495
+ /**
496
+ * Pretty-prints the difference in two times.
497
+ *
498
+ * @since 3.0
499
+ * @param time $older_date
500
+ * @param time $newer_date
501
+ * @return string The pretty time_since value
502
+ * @link http://wordpress.org/extend/plugins/wp-crontrol/
503
+ */
504
+ function wprss_time_since( $older_date, $newer_date ) {
505
+ return wprss_interval( $newer_date - $older_date );
506
+ }
507
+
508
+ /**
509
+ * Calculates difference between times
510
+ *
511
+ * Taken from the WP-Crontrol plugin
512
+ * @link http://wordpress.org/extend/plugins/wp-crontrol/
513
+ * @since 3.0
514
+ *
515
+ */
516
+ function wprss_interval( $since ) {
517
+ // array of time period chunks
518
+ $chunks = array(
519
+ array(60 * 60 * 24 * 365 , _n_noop('%s year', '%s years', 'crontrol')),
520
+ array(60 * 60 * 24 * 30 , _n_noop('%s month', '%s months', 'crontrol')),
521
+ array(60 * 60 * 24 * 7, _n_noop('%s week', '%s weeks', 'crontrol')),
522
+ array(60 * 60 * 24 , _n_noop('%s day', '%s days', 'crontrol')),
523
+ array(60 * 60 , _n_noop('%s hour', '%s hours', 'crontrol')),
524
+ array(60 , _n_noop('%s minute', '%s minutes', 'crontrol')),
525
+ array( 1 , _n_noop('%s second', '%s seconds', 'crontrol')),
526
+ );
527
+
528
+
529
+ if( $since <= 0 ) {
530
+ return __( 'now', 'wprss' );
531
+ }
532
+
533
+ // we only want to output two chunks of time here, eg:
534
+ // x years, xx months
535
+ // x days, xx hours
536
+ // so there's only two bits of calculation below:
537
+
538
+ // step one: the first chunk
539
+ for ($i = 0, $j = count($chunks); $i < $j; $i++)
540
+ {
541
+ $seconds = $chunks[$i][0];
542
+ $name = $chunks[$i][1];
543
+
544
+ // finding the biggest chunk (if the chunk fits, break)
545
+ if (($count = floor($since / $seconds)) != 0)
546
+ {
547
+ break;
548
+ }
549
+ }
550
+
551
+ // set output var
552
+ $output = sprintf(_n($name[0], $name[1], $count, 'wprss'), $count);
553
+
554
+ // step two: the second chunk
555
+ if ($i + 1 < $j)
556
+ {
557
+ $seconds2 = $chunks[$i + 1][0];
558
+ $name2 = $chunks[$i + 1][1];
559
+
560
+ if (($count2 = floor(($since - ($seconds * $count)) / $seconds2)) != 0)
561
+ {
562
+ // add to output var
563
+ $output .= ' '.sprintf(_n($name2[0], $name2[1], $count2, 'wprss'), $count2);
564
+ }
565
+ }
566
+
567
+ return $output;
568
+ }
569
+
570
+
571
+ /**
572
+ * Validate inputs from the general settings page
573
+ * @since 3.0
574
+ */
575
+ function wprss_settings_general_validate( $input ) {
576
+ $options = get_option( 'wprss_settings_general' );
577
+ $current_cron_interval = $options['cron_interval'];
578
+
579
+ // Create our array for storing the validated options
580
+ $output = array();
581
+
582
+ // Loop through each of the incoming options
583
+ foreach( $input as $key => $value ) {
584
+
585
+ // Check to see if the current option has a value. If so, process it.
586
+ if( isset( $input[ $key ] ) ) {
587
+
588
+ // Strip all HTML and PHP tags and properly handle quoted strings
589
+ $output[ $key ] = strip_tags( stripslashes( $input[ $key ] ) );
590
+
591
+ } // end if
592
+
593
+ } // end foreach
594
+
595
+ if ( ! isset( $input['title_link'] ) || $input['title_link'] != '1' )
596
+ $output['title_link'] = 0;
597
+ else
598
+ $output['title_link'] = 1;
599
+
600
+ if ( ! isset( $input['source_enable'] ) || $input['source_enable'] != '1' )
601
+ $output['source_enable'] = 0;
602
+ else
603
+ $output['source_enable'] = 1;
604
+
605
+ if ( ! isset( $input['date_enable'] ) || $input['date_enable'] != '1' )
606
+ $output['date_enable'] = 0;
607
+ else
608
+ $output['date_enable'] = 1;
609
+
610
+ if ( ! isset( $input['styles_disable'] ) || $input['styles_disable'] != '1' )
611
+ $output['styles_disable'] = 0;
612
+ else
613
+ $output['styles_disable'] = 1;
614
+
615
+ if ( ! isset( $input['video_link'] ) || strtolower( $input['video_link'] ) !== 'true' )
616
+ $output['video_link'] = 'false';
617
+ else
618
+ $output['video_link'] = 'true';
619
+
620
+ if ( $input['cron_interval'] != $current_cron_interval ) {
621
+ wp_clear_scheduled_hook( 'wprss_fetch_all_feeds_hook' );
622
+ wp_schedule_event( time(), $input['cron_interval'], 'wprss_fetch_all_feeds_hook' );
623
+ }
624
+
625
+ // Return the array processing any additional functions filtered by this action
626
+ return apply_filters( 'wprss_settings_general_validate', $output, $input );
627
+ }
includes/admin-welcome.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @todo Localize
5
+ */
6
+
7
+ // Exit if the page is accessed directly
8
+ if ( ! defined( 'ABSPATH' ) ) exit;
9
+
10
+
11
+ // The tabs to be shown
12
+ $tabs = array(
13
+ /* 'cat' => 'Categories',
14
+ 'et' => 'Excerpts &amp; Thumbnails',
15
+ 'kf' => 'Keyword Filtering'*/
16
+ );
17
+
18
+ // Determine the tab currently being shown
19
+ $tab = null;
20
+ if ( isset( $_GET['tab'] ) && !empty( $_GET['tab'] ) ) {
21
+ $tab = $_GET['tab'];
22
+ }
23
+
24
+ ?>
25
+
26
+ <div class="wrap about-wrap">
27
+ <h1><?php printf( __( 'Welcome to WP RSS Aggregator %s !', 'wprss' ), WPRSS_VERSION ); ?></h1>
28
+ <div class="about-text">
29
+ Thank you for upgrading to the latest version!
30
+ </div>
31
+ <!-- <div class="wprss-badge">Version</div>-->
32
+
33
+ <!-- TAB WRAPPER -->
34
+ <h2 class="nav-tab-wrapper">
35
+ <a class="nav-tab <?php if ( $tab === null ) echo 'nav-tab-active'; ?>"
36
+ href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'wprss-welcome' ), 'index.php' ) ) ); ?>">
37
+ Overview
38
+ </a>
39
+
40
+ <!-- SHOW ALL TABS -->
41
+ <?php foreach ($tabs as $slug => $title) : ?>
42
+
43
+ <a class="nav-tab <?php if ( $tab === $slug ) echo 'nav-tab-active'; ?>"
44
+ href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'wprss-welcome', 'tab' => $slug ), 'index.php' ) ) ); ?>">
45
+ <?php echo $title; ?>
46
+ </a>
47
+
48
+ <?php endforeach; ?>
49
+
50
+ </h2>
51
+
52
+ <!-- TAB CONTENT -->
53
+ <?php
54
+ /* Show content depending on the current tab */
55
+ switch( $tab ) {
56
+
57
+ // Default tab. ( when tab = null )
58
+ default: ?>
59
+
60
+ <p class="about-description">
61
+ Check out our add-ons:</p>
62
+
63
+ <ul>
64
+ <li><strong><a href="http://www.wprssaggregator.com/extension/feed-post/" target="wprss_ftp">Feed to Post</a> <span style="color: green;">*New*</span></strong></li>
65
+ <li><strong><a href="http://www.wprssaggregator.com/extension/excerpts-thumbnails/" target="wprss_et">Excerpts &amp; Thumbnails</a></strong></li>
66
+ <li><strong><a href="http://www.wprssaggregator.com/extension/categories/" target="wprss_cat">Categories</a></strong></li>
67
+ <li><strong><a href="http://www.wprssaggregator.com/extension/keyword-filtering/" target="wprss_kf">Keyword Filtering</a></strong></li>
68
+ </ul>
69
+ </p>
70
+ <p>Plus we've got some other add-ons already being developed!</p>
71
+ <p>More information about add-ons can be found on our website <a href="http://www.wprssaggregator.com">www.wprssaggregator.com</a></p>
72
+
73
+ <h3> 3.5.1 (2013-11-09) </h3>
74
+ <ul>
75
+ <li>Enhanced: Increased compatibility with RSS sources.</li>
76
+ </ul>
77
+
78
+ </p>
79
+
80
+ <?php
81
+ break;
82
+
83
+ // Excerpts and Thumbnails tab
84
+ case 'et': ?>
85
+
86
+ <p class="about-description">
87
+ Fetch RSS feed excerpts to your blog and add thumbnails! Perfect for adding some life and color to your feeds.
88
+ </p>
89
+
90
+ <?php
91
+ break;
92
+
93
+ // Categories Tab
94
+ case 'cat': ?>
95
+
96
+ <p class="about-description">
97
+ Organize your feeds into custom categories. Filter feed items by category and make custom WordPress feeds for specific categories.
98
+ </p>
99
+
100
+ <?php
101
+ break;
102
+
103
+ // Keyword Filtering tab
104
+ case 'kf': ?>
105
+
106
+ <p class="about-description">
107
+ Import and store feeds that contain specific keywords in either the title or their content. Control what gets imported to your blog.
108
+ </p>
109
+
110
+ <?php
111
+ break;
112
+ }
113
+ ?>
114
+
115
+ <hr/>
116
+
117
+ <p><a href="<?php echo admin_url( 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings'); ?>">Go to WP RSS Aggregator settings</a></p>
118
+
119
+ </div>
120
+
121
+ <?php update_option( 'wprss_pwsv', WPRSS_VERSION ); // Update the previous welcome screen version ?>
includes/admin.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin administration related functions
4
+ *
5
+ * @package WPRSSAggregator
6
+ */
7
+
8
+ add_action( 'admin_head', 'wprss_custom_post_type_icon' );
9
+ /**
10
+ * Custom Post Type Icon for Admin Menu & Post Screen
11
+ * @since 2.0
12
+ */
13
+ function wprss_custom_post_type_icon() {
14
+ ?>
15
+ <style>
16
+ /* Post Screen - 32px */
17
+ .icon32-posts-wprss_feed {
18
+ background: transparent url( <?php echo WPRSS_IMG . 'icon-adminpage32.png'; ?> ) no-repeat left top !important;
19
+ }
20
+ /* Post Screen - 32px */
21
+ .icon32-posts-wprss_feed_item {
22
+ background: transparent url( <?php echo WPRSS_IMG . 'icon-adminpage32.png'; ?> ) no-repeat left top !important;
23
+ }
24
+ </style>
25
+ <?php }
26
+
27
+
28
+ add_action( 'admin_menu', 'wprss_register_menu_pages' );
29
+ /**
30
+ * Register menu and submenus
31
+ * @since 2.0
32
+ */
33
+
34
+ // Add the admin options pages as submenus to the Feed CPT
35
+ function wprss_register_menu_pages() {
36
+
37
+ //create submenu items
38
+ add_submenu_page( 'edit.php?post_type=wprss_feed', __( 'WP RSS Aggregator Settings', 'wprss' ), __( 'Settings', 'wprss' ), apply_filters( 'wprss_capability', 'manage_feed_settings' ), 'wprss-aggregator-settings', 'wprss_settings_page_display' );
39
+ add_submenu_page( 'edit.php?post_type=wprss_feed', __( 'Export & Import Settings', 'wprss' ), __( 'Import & Export', 'wprss' ), apply_filters( 'wprss_capability', 'manage_feed_settings' ), 'wprss-import-export-settings', 'wprss_import_export_settings_page_display' );
40
+ add_submenu_page( 'edit.php?post_type=wprss_feed', __( 'Debugging', 'wprss' ), __( 'Debugging', 'wprss' ), apply_filters( 'wprss_capability', 'manage_feed_settings'), 'wprss-debugging', 'wprss_debugging_page_display' );
41
+ }
42
+
43
+
44
+ add_filter('admin_body_class', 'wprss_base_admin_body_class');
45
+ /**
46
+ * Set body class for admin screens
47
+ * http://www.kevinleary.net/customizing-wordpress-admin-css-javascript/
48
+ * @since 2.0
49
+ */
50
+ function wprss_base_admin_body_class( $classes )
51
+ {
52
+ // Current action
53
+ if ( is_admin() && isset($_GET['action']) ) {
54
+ $classes .= 'action-'.$_GET['action'];
55
+ }
56
+ // Current post ID
57
+ if ( is_admin() && isset($_GET['post']) ) {
58
+ $classes .= ' ';
59
+ $classes .= 'post-'.$_GET['post'];
60
+ }
61
+ // New post type & listing page
62
+ if ( isset($_GET['post_type']) ) $post_type = $_GET['post_type'];
63
+ if ( isset($post_type) ) {
64
+ $classes .= ' ';
65
+ $classes .= 'post-type-'.$post_type;
66
+ }
67
+ // Editting a post type
68
+ if ( isset( $_GET['post'] ) ) {
69
+ $post_query = $_GET['post'];
70
+ }
71
+ if ( isset($post_query) ) {
72
+ $current_post_edit = get_post($post_query);
73
+ $current_post_type = $current_post_edit->post_type;
74
+ if ( !empty($current_post_type) ) {
75
+ $classes .= ' ';
76
+ $classes .= 'post-type-'.$current_post_type;
77
+ }
78
+ }
79
+ // Return the $classes array
80
+ return $classes;
81
+ }
82
+
83
+
84
+ /**
85
+ * Change title on wprss_feed post type screen
86
+ *
87
+ * @since 2.0
88
+ * @return void
89
+ */
90
+ function wprss_change_title_text() {
91
+ return __( 'Enter feed name here (e.g. WP Mayor)', 'wprss' );
92
+ }
93
+
94
+
95
+ add_filter( 'plugin_action_links', 'wprss_plugin_action_links', 10, 2 );
96
+ /**
97
+ * Add Settings action link in plugin listing
98
+ *
99
+ * @since 3.0
100
+ * @param array $action_links
101
+ * @param string $plugin_file
102
+ * @return array
103
+ */
104
+ function wprss_plugin_action_links( $action_links, $plugin_file ) {
105
+ if ( $plugin_file == plugin_basename( __FILE__ ) ) {
106
+ $settings_link = '<a href="' . get_admin_url() . 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings">' . __("Settings") . '</a>';
107
+ array_unshift( $action_links, $settings_link );
108
+ }
109
+ return $action_links;
110
+ }
includes/cron-jobs.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains all the cron jobs in use by WP RSS Aggregator
4
+ *
5
+ * @package WPRSSAggregator
6
+ */
7
+
8
+
9
+ add_action( 'init', 'wprss_schedule_fetch_all_feeds_cron' );
10
+ /**
11
+ * Creates the cron to fetch feeds every hour
12
+ *
13
+ * @since 2.0
14
+ */
15
+ function wprss_schedule_fetch_all_feeds_cron() {
16
+
17
+ $options = get_option( 'wprss_settings_general' );
18
+
19
+ $cron_interval = $options['cron_interval'];
20
+
21
+ // verify event has not been scheduled
22
+ if ( ! wp_next_scheduled( 'wprss_fetch_all_feeds_hook' ) ) {
23
+ // Schedule to run hourly
24
+ wp_schedule_event( time(), $cron_interval, 'wprss_fetch_all_feeds_hook' );
25
+ }
26
+
27
+ add_action( 'wprss_fetch_all_feeds_hook', 'wprss_fetch_insert_all_feed_items' );
28
+ }
29
+
30
+
31
+ add_action( 'init', 'wprss_schedule_truncate_posts_cron' );
32
+ /**
33
+ * Creates the cron to truncate wprss_feed_item posts daily
34
+ *
35
+ * @since 2.0
36
+ */
37
+ function wprss_schedule_truncate_posts_cron() {
38
+
39
+ // verify event has not been scheduled
40
+ if ( ! wp_next_scheduled( 'wprss_truncate_posts_hook') ) {
41
+ // Schedule to run daily
42
+ wp_schedule_event( time(), 'daily', 'wprss_truncate_posts_hook' );
43
+ }
44
+
45
+ add_action( 'wprss_truncate_posts_hook', 'wprss_truncate_posts' );
46
+ }
47
+
48
+
49
+ // filter to add new possible frequencies to the cron
50
+ add_filter( 'cron_schedules', 'wprss_filter_cron_schedules' );
51
+ /**
52
+ * Adding a few more handy cron schedules to the default ones
53
+ * @since 3.0
54
+ */
55
+ function wprss_filter_cron_schedules( $schedules) {
56
+ $frequencies = array(
57
+ 'five_min' => array(
58
+ 'interval' => 5 * MINUTE_IN_SECONDS,
59
+ 'display' => __( 'Once every five minutes', 'wprss' )
60
+ ),
61
+ 'ten_min' => array(
62
+ 'interval' => 10 * MINUTE_IN_SECONDS,
63
+ 'display' => __( 'Once every ten minutes', 'wprss' )
64
+ ),
65
+ 'fifteen_min' => array(
66
+ 'interval' => 15 * MINUTE_IN_SECONDS,
67
+ 'display' => __( 'Once every fifteen minutes', 'wprss' )
68
+ ),
69
+ 'thirty_min' => array(
70
+ 'interval' => 30 * MINUTE_IN_SECONDS,
71
+ 'display' => __( 'Once every thirty minutes', 'wprss' )
72
+ ),
73
+ 'two_hours' => array(
74
+ 'interval' => 2 * HOUR_IN_SECONDS,
75
+ 'display' => __( 'Once every two hours', 'wprss' )
76
+ ),
77
+ );
78
+
79
+ return array_merge( $schedules, $frequencies );
80
+ }
includes/custom-feed.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Function to create a custom feed with the latest imported feed items
4
+ *
5
+ * @package WP RSS Aggregator
6
+ */
7
+
8
+
9
+ add_filter( 'init', 'wprss_addfeed_add_feed' );
10
+ /**
11
+ * Adds feed named 'wprss'
12
+ *
13
+ * @since 3.3
14
+ */
15
+ function wprss_addfeed_add_feed() {
16
+ $general_settings = get_option( 'wprss_settings_general', 'wprss' );
17
+ if ( !empty( $general_settings ) && isset( $general_settings['custom_feed_url'] ) ) {
18
+ $url = $general_settings['custom_feed_url'];
19
+ }
20
+ else $url = 'wprss';
21
+ add_feed( $url, 'wprss_addfeed_do_feed' );
22
+ flush_rewrite_rules();
23
+ }
24
+
25
+
26
+ /**
27
+ * Generate the feed
28
+ *
29
+ * @since 3.3
30
+ */
31
+ function wprss_addfeed_do_feed( $in ) {
32
+
33
+ // Prepare the post query
34
+ $wprss_custom_feed_query = apply_filters(
35
+ 'wprss_custom_feed_query',
36
+ array(
37
+ 'post_type' => 'wprss_feed_item',
38
+ 'post_status' => 'publish',
39
+ 'cache_results' => false, // disable caching
40
+ )
41
+
42
+ );
43
+
44
+ // Get options
45
+ $options = get_option( 'wprss_settings_general' );
46
+ if ( $options !== FALSE ) {
47
+ // If options exist, get the limit
48
+ $limit = $options['custom_feed_limit'];
49
+ if ( $limit !== FALSE ) {
50
+ // if limit exists, set the query limit
51
+ $wprss_custom_feed_query['posts_per_page'] = $limit;
52
+ }
53
+ }
54
+
55
+ // Submit the query to get latest feed items
56
+ query_posts( $wprss_custom_feed_query );
57
+
58
+ // Send content header and start ATOM output
59
+ header('Content-Type: text/xml');
60
+ // Disabling caching
61
+ header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
62
+ header('Pragma: no-cache'); // HTTP 1.0.
63
+ header('Expires: 0'); // Proxies.
64
+ echo '<?xml version="1.0" encoding="' . get_option('blog_charset') . '"?' . '>';
65
+ ?>
66
+ <feed xmlns="http://www.w3.org/2005/Atom">
67
+ <title type="text">Latest imported feed items on <?php bloginfo_rss('name'); ?></title>
68
+ <?php
69
+ // Start the Loop
70
+ while ( have_posts() ) : the_post();
71
+ $permalink = get_post_meta( get_the_ID(), 'wprss_item_permalink', true );
72
+ ?>
73
+ <entry>
74
+ <title><![CDATA[<?php the_title_rss(); ?>]]></title>
75
+ <link href="<?php echo $permalink; ?>" />
76
+ <?php // Enable below to link to post on our site rather than original source ?>
77
+ <!--<link href="<?php the_permalink_rss(); ?>" />-->
78
+ <published><?php echo get_post_time( 'Y-m-d\TH:i:s\Z' ); ?></published>
79
+ <content type="html"><![CDATA[<?php the_content(); ?>]]></content>
80
+ </entry>
81
+ <?php
82
+ // End of the Loop
83
+ endwhile;
84
+ ?>
85
+ </feed>
86
+ <?php
87
+ }
88
+
89
+
90
+ add_filter( 'post_limits', 'wprss_custom_feed_limits' );
91
+ /**
92
+ * Set a different limit to our custom feeds
93
+ *
94
+ * @since 3.3
95
+ */
96
+ function wprss_custom_feed_limits( $limit ) {
97
+ if ( is_feed( ) ) {
98
+ // return 'LIMIT 0, 3';
99
+ return $limit;
100
+ }
101
+ return $limit;
102
+ }
includes/custom-post-types.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains all custom post type related functions
4
+ *
5
+ * @package WPRSSAggregator
6
+ */
7
+
8
+
9
+ add_action( 'init', 'wprss_register_post_types' );
10
+ /**
11
+ * Create Custom Post Types wprss_feed and wprss_feed_item
12
+ *
13
+ * @since 2.0
14
+ */
15
+ function wprss_register_post_types() {
16
+
17
+ // Set up labels for the 'wprss_feed' post type
18
+ $labels = apply_filters(
19
+ 'wprss_feed_post_type_labels',
20
+ array(
21
+ 'name' => __( 'Feed Sources', 'wprss' ),
22
+ 'singular_name' => __( 'Feed', 'wprss' ),
23
+ 'add_new' => __( 'Add New Feed Source', 'wprss' ),
24
+ 'all_items' => __( 'All Feed Sources', 'wprss' ),
25
+ 'add_new_item' => __( 'Add New Feed Source', 'wprss' ),
26
+ 'edit_item' => __( 'Edit Feed Source', 'wprss' ),
27
+ 'new_item' => __( 'New Feed Source', 'wprss' ),
28
+ 'view_item' => __( 'View Feed Source', 'wprss' ),
29
+ 'search_items' => __( 'Search Feeds', 'wprss' ),
30
+ 'not_found' => __( 'No Feed Sources Found', 'wprss' ),
31
+ 'not_found_in_trash' => __( 'No Feed Sources Found In Trash', 'wprss' ),
32
+ 'menu_name' => __( 'RSS Aggregator', 'wprss' )
33
+ )
34
+ );
35
+
36
+ // Set up the arguments for the 'wprss_feed' post type
37
+ $feed_args = apply_filters(
38
+ 'wprss_feed_post_type_args',
39
+ array(
40
+ 'exclude_from_search' => true,
41
+ 'publicly_querable' => false,
42
+ 'show_in_nav_menus' => false,
43
+ 'show_in_admin_bar' => true,
44
+ 'public' => true,
45
+ 'show_ui' => true,
46
+ 'query_var' => 'feed_source',
47
+ 'menu_position' => 100,
48
+ 'menu_icon' => WPRSS_IMG . 'icon-adminmenu16-sprite.png',
49
+ 'show_in_menu' => true,
50
+ 'show_in_admin_bar' => true,
51
+ 'rewrite' => array(
52
+ 'slug' => 'feeds',
53
+ 'with_front' => false
54
+ ),
55
+ 'capability_type' => 'feed',
56
+ 'supports' => array( 'title' ),
57
+ 'labels' => $labels
58
+ )
59
+ );
60
+
61
+ // Register the 'wprss_feed' post type
62
+ register_post_type( 'wprss_feed', $feed_args );
63
+
64
+ // Set up labels for the 'wprss_feed_item' post type
65
+ $labels = apply_filters(
66
+ 'wprss_feed_item_post_type_labels',
67
+ array(
68
+ 'name' => __( 'Imported Feeds', 'wprss' ),
69
+ 'singular_name' => __( 'Imported Feed', 'wprss' ),
70
+ 'all_items' => __( 'Imported Feeds', 'wprss' ),
71
+ 'view_item' => __( 'View Imported Feed', 'wprss' ),
72
+ 'search_items' => __( 'Search Imported Feeds', 'wprss' ),
73
+ 'not_found' => __( 'No Imported Feeds Found', 'wprss' ),
74
+ 'not_found_in_trash' => __( 'No Imported Feeds Found In Trash', 'wprss' )
75
+ )
76
+ );
77
+
78
+ // Set up the arguments for the 'wprss_feed_item' post type
79
+ $feed_item_args = apply_filters(
80
+ 'wprss_feed_item_post_type_args',
81
+ array(
82
+ 'exclude_from_search' => true,
83
+ 'publicly_querable' => false,
84
+ 'show_in_nav_menus' => false,
85
+ 'show_in_admin_bar' => true,
86
+ 'public' => true,
87
+ 'show_ui' => true,
88
+ 'query_var' => 'feed_item',
89
+ 'show_in_menu' => 'edit.php?post_type=wprss_feed',
90
+ 'show_in_admin_bar' => false,
91
+ 'rewrite' => array(
92
+ 'slug' => 'feeds/items',
93
+ 'with_front' => false,
94
+ ),
95
+ 'capability_type' => 'feed_source',
96
+ 'labels' => $labels
97
+ )
98
+ );
99
+
100
+ // Register the 'feed_item' post type
101
+ register_post_type( 'wprss_feed_item', $feed_item_args );
102
+ }
103
+
104
+
105
+ /**
106
+ * Filter the link query arguments to exclude the feed and feed item post types.
107
+ * This filter will only work for WordPress versions 3.7 or higher.
108
+ *
109
+ * @since 3.4.3
110
+ * @param array $query An array of WP_Query arguments.
111
+ * @return array $query
112
+ */
113
+ function wprss_modify_link_builder_query( $query ){
114
+
115
+ // custom post type slug to be removed
116
+ $to_remove = array( 'wprss_feed', 'wprss_feed_item' );
117
+
118
+ // find and remove the array keys
119
+ foreach( $to_remove as $post_type ) {
120
+ $key = array_search( $post_type, $query['post_type'] );
121
+ // remove the array item
122
+ if( $key ) unset( $query['post_type'][$key] );
123
+ }
124
+
125
+ return $query;
126
+ }
127
+ add_filter( 'wp_link_query_args', 'wprss_modify_link_builder_query' );
includes/deprecated-functions.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Fetches feed items from sources provided
5
+ * DEPRECATED - JUST FOR REFERENCE
6
+ *
7
+ * @since 2.0
8
+ * @deprecated 3.0
9
+ */
10
+ function wprss_fetch_all_feed_items( ) {
11
+
12
+ // Get all feed sources
13
+ $feed_sources = new WP_Query( array(
14
+ 'post_type' => 'wprss_feed',
15
+ 'post_status' => 'publish',
16
+ 'posts_per_page' => -1,
17
+ ) );
18
+
19
+ if( $feed_sources->have_posts() ) {
20
+ /* Start by getting one feed source, we will cycle through them one by one,
21
+ fetching feed items and adding them to the database in each pass */
22
+ while ( $feed_sources->have_posts() ) {
23
+ $feed_sources->the_post();
24
+
25
+ $feed_ID = get_the_ID();
26
+ $feed_url = get_post_meta( get_the_ID(), 'wprss_url', true );
27
+
28
+ // Use the URL custom field to fetch the feed items for this source
29
+ if( !empty( $feed_url ) ) {
30
+
31
+ add_filter( 'wp_feed_cache_transient_lifetime' , 'wprss_return_7200' );
32
+ //$feed = fetch_feed( $feed_url );
33
+ $feed = wprss_fetch_feed( $feed_url );
34
+ remove_filter( 'wp_feed_cache_transient_lifetime' , 'wprss_return_7200' );
35
+
36
+ // $feed->strip_htmltags( array_merge( $feed->strip_htmltags, array('h1', 'a', 'img') ) );
37
+
38
+ if ( !is_wp_error( $feed ) ) {
39
+ // Figure out how many total items there are, but limit it to 10.
40
+ $maxitems = $feed->get_item_quantity(10);
41
+
42
+ // Build an array of all the items, starting with element 0 (first element).
43
+ $items = $feed->get_items( 0, $maxitems );
44
+ }
45
+ else { return; }
46
+ }
47
+
48
+ if ( ! empty( $items ) ) {
49
+ // Gather the permalinks of existing feed item's related to this feed source
50
+ global $wpdb;
51
+ $existing_permalinks = $wpdb->get_col(
52
+ "SELECT meta_value
53
+ FROM $wpdb->postmeta
54
+ WHERE meta_key = 'wprss_item_permalink'
55
+ AND post_id IN ( SELECT post_id FROM $wpdb->postmeta WHERE meta_value = $feed_ID)
56
+ ");
57
+
58
+ foreach ( $items as $item ) {
59
+ // Check if newly fetched item already present in existing feed item item,
60
+ // if not insert it into wp_posts and insert post meta.
61
+ if ( ! ( in_array( $item->get_permalink(), $existing_permalinks ) ) ) {
62
+ // Create post object
63
+ $feed_item = array(
64
+ 'post_title' => $item->get_title(),
65
+ 'post_content' => '',
66
+ 'post_status' => 'publish',
67
+ 'post_type' => 'wprss_feed_item'
68
+ );
69
+ $inserted_ID = wp_insert_post( $feed_item );
70
+ wprss_items_create_post_meta( $inserted_ID, $item, $feed_ID );
71
+ } //end if
72
+ } //end foreach
73
+ } // end if
74
+ } // end $feed_sources while loop
75
+ wp_reset_postdata(); // Restore the $post global to the current post in the main query
76
+ // } // end if
77
+ } // end if
78
+ }
79
+
80
+ // For testing query speed
81
+ // $time_start = microtime( true );
82
+ // wp_die(number_format( microtime( true ) - $time_start, 10 ));
83
+
includes/feed-display.php ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Feed display related functions
4
+ *
5
+ * @package WPRSSAggregator
6
+ */
7
+
8
+
9
+ /**
10
+ * Retrieve settings and prepare them for use in the display function
11
+ *
12
+ * @since 3.0
13
+ */
14
+ function wprss_get_display_settings( $settings ) {
15
+
16
+ switch ( $settings['open_dd'] ) {
17
+
18
+ case 'Lightbox' :
19
+ $display_settings['open'] = 'class="colorbox"';
20
+ break;
21
+
22
+ case 'New window' :
23
+ $display_settings['open'] = 'target="_blank"';
24
+ break;
25
+ }
26
+
27
+ switch ( $settings['follow_dd'] ) {
28
+
29
+ case 'no_follow' :
30
+ $display_settings['follow'] = 'rel="nofollow"';
31
+ break;
32
+ }
33
+
34
+ do_action( 'wprss_get_settings' );
35
+
36
+ return $display_settings;
37
+ }
38
+
39
+
40
+ /**
41
+ * Merges the default arguments with the user set arguments
42
+ *
43
+ * @since 3.0
44
+ */
45
+ function wprss_get_shortcode_default_args( $args ) {
46
+ // Default shortcode/function arguments for displaying feed items
47
+ $shortcode_args = apply_filters(
48
+ 'wprss_shortcode_args',
49
+ array(
50
+ 'links_before' => '<ul class="rss-aggregator">',
51
+ 'links_after' => '</ul>',
52
+ 'link_before' => '<li class="feed-item">',
53
+ 'link_after' => '</li>'
54
+ )
55
+ );
56
+
57
+ // Parse incoming $args into an array and merge it with $shortcode_args
58
+ $args = wp_parse_args( $args, $shortcode_args );
59
+
60
+ return $args;
61
+ }
62
+
63
+
64
+ /**
65
+ * Prepares and builds the query for fetching the feed items
66
+ *
67
+ * @since 3.0
68
+ */
69
+ function wprss_get_feed_items_query( $settings ) {
70
+ $posts_per_page = ( isset( $settings['posts_per_page'] ) )? $settings['posts_per_page'] : $settings['feed_limit'];
71
+ $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
72
+ $feed_items_args = array(
73
+ 'post_type' => 'wprss_feed_item',
74
+ 'posts_per_page' => $posts_per_page,
75
+ 'orderby' => 'meta_value',
76
+ 'meta_key' => 'wprss_item_date',
77
+ 'order' => 'DESC',
78
+ 'paged' => $paged,
79
+ 'suppress_filters' => true
80
+ );
81
+
82
+ // If either the source or exclude arguments are set (but not both), prepare a meta query
83
+ if ( isset( $settings['source'] ) xor isset( $settings['exclude'] ) ) {
84
+ // Set the appropriate setting and operator
85
+ $setting = 'source';
86
+ $operator = 'IN';
87
+ if ( isset( $settings['exclude'] ) ) {
88
+ $setting = 'exclude';
89
+ $operator = 'NOT IN';
90
+ }
91
+ $feeds = array_filter( array_map( 'intval', explode( ',', $settings[$setting] ) ) );
92
+ foreach ( $feeds as $feed )
93
+ trim( $feed );
94
+ if ( !empty( $feeds ) ) {
95
+ $feed_items_args['meta_query'] = array(
96
+ array(
97
+ 'key' => 'wprss_feed_id',
98
+ 'value' => $feeds,
99
+ 'type' => 'numeric',
100
+ 'compare' => $operator,
101
+ ),
102
+ );
103
+ }
104
+ }
105
+
106
+ // Arguments for the next query to fetch all feed items
107
+ $feed_items_args = apply_filters( 'wprss_display_feed_items_query', $feed_items_args, $settings );
108
+
109
+ // Query to get all feed items for display
110
+ $feed_items = new WP_Query( $feed_items_args );
111
+
112
+ return $feed_items;
113
+ }
114
+
115
+
116
+ add_action( 'wprss_display_template', 'wprss_default_display_template', 10, 3 );
117
+ /**
118
+ * Default template for feed items display
119
+ *
120
+ * @since 3.0
121
+ */
122
+ function wprss_default_display_template( $display_settings, $args, $feed_items ) {
123
+ global $wp_query;
124
+ $old_wp_query = $wp_query;
125
+ $wp_query = $feed_items;
126
+ $general_settings = get_option( 'wprss_settings_general' );
127
+ $excerpts_settings = get_option( 'wprss_settings_excerpts' );
128
+ $thumbnails_settings = get_option( 'wprss_settings_thumbnails' );
129
+
130
+ $source_link = $general_settings['source_link'];
131
+ // Declare each item in $args as its own variable
132
+ extract( $args, EXTR_SKIP );
133
+
134
+ $output = '';
135
+
136
+
137
+ if( $feed_items->have_posts() ) {
138
+
139
+ $output .= "$links_before";
140
+
141
+ while ( $feed_items->have_posts() ) {
142
+ $feed_items->the_post();
143
+ $permalink = get_post_meta( get_the_ID(), 'wprss_item_permalink', true );
144
+ $feed_source_id = get_post_meta( get_the_ID(), 'wprss_feed_id', true );
145
+ $source_name = get_the_title( $feed_source_id );
146
+ $source_url = get_post_meta( $feed_source_id, 'wprss_site_url', true );
147
+ // Fallback for feeds created with older versions of the plugin
148
+ if ( $source_url === '' )
149
+ $source_url = get_post_meta( $feed_source_id, 'wprss_url', true );
150
+
151
+ do_action( 'wprss_get_post_data' );
152
+
153
+ // convert from Unix timestamp
154
+ $date = date_i18n( $general_settings['date_format'], intval( get_post_meta( get_the_ID(), 'wprss_item_date', true ) ) );
155
+
156
+ if ( $general_settings['title_link'] == 1 ) {
157
+ $output .= "$link_before" . '<a ' . $display_settings['open'] . ' ' . $display_settings['follow'] . ' href="'. $permalink . '">'. get_the_title(). '</a>';
158
+ }
159
+ else {
160
+ $output .= get_the_title();
161
+ }
162
+
163
+ if ( ( $general_settings['source_enable'] == 1 ) && ( $general_settings['date_enable'] == 1 ) ) {
164
+ $output .= '<div class="source-date"><span class="feed-source">' .
165
+ ( !empty( $general_settings['text_preceding_source'] ) ? $general_settings['text_preceding_source'] . ' ' : '' );
166
+
167
+ if ( $source_link == 1 ) {
168
+ $output .= '<a href="' . $source_url . '">' . $source_name . "</a>";
169
+ }
170
+ else $output .= $source_name;
171
+
172
+ $output .= ' | ' .
173
+ ( !empty( $general_settings['text_preceding_date'] ) ? $general_settings['text_preceding_date'] . ' ' : '' ) . $date .
174
+ '</span></div>' . "$link_after";
175
+ }
176
+
177
+ else if ( ( $general_settings['source_enable'] == 1 ) && ( $general_settings['date_enable'] == 0 ) ) {
178
+ $output .= '<div class="source-date"><span class="feed-source">' .
179
+ ( !empty( $general_settings['text_preceding_source'] ) ? $general_settings['text_preceding_source'] . ' ' : '' );
180
+
181
+ if ( $source_link == 1 ) {
182
+ $output .= '<a href="' . $source_url . '">' . $source_name . "</a>";
183
+ }
184
+ else $output .= $source_name;
185
+
186
+ $output .= '</span></div>' . "$link_after";
187
+ }
188
+
189
+ else if ( ( $general_settings['source_enable'] == 0 ) && ( $general_settings['date_enable'] == 1 ) ) {
190
+ $output .= '<div class="source-date"><span class="feed-source">' .
191
+ ( !empty( $general_settings['text_preceding_date'] ) ? $general_settings['text_preceding_date'] . ' ' : '' ) . $date .
192
+ '</span></div>' . "$link_after";
193
+ }
194
+
195
+ // No source, no date
196
+ else { $output .= "$link_after"; }
197
+
198
+
199
+ }
200
+ $output .= "$links_after";
201
+
202
+ $output = apply_filters( 'wprss_pagination', $output );
203
+
204
+ $output = apply_filters( 'feed_output', $output );
205
+
206
+ echo $output;
207
+
208
+ wp_reset_postdata();
209
+
210
+ } else {
211
+ $output = apply_filters( 'no_feed_items_found', __( 'No feed items found.', 'wprss' ) );
212
+ echo $output;
213
+ }
214
+ $wp_query = $old_wp_query;
215
+ }
216
+
217
+
218
+ add_filter( 'wprss_pagination', 'wprss_pagination_links' );
219
+
220
+ /**
221
+ * Display pagination links
222
+ *
223
+ * @since 3.5
224
+ */
225
+ function wprss_pagination_links( $output ) {
226
+ $output .= '<div class="nav-links">';
227
+ $output .= ' <div class="nav-previous alignleft">' . get_next_posts_link( 'Older posts' ) . '</div>';
228
+ $output .= ' <div class="nav-next alignright">' . get_previous_posts_link( 'Newer posts' ) . '</div>';
229
+ $output .= '</div>';
230
+ return $output;
231
+ }
232
+
233
+
234
+ /**
235
+ * Display feed items on the front end (via shortcode or function)
236
+ *
237
+ * @since 2.0
238
+ */
239
+ function wprss_display_feed_items( $args = array() ) {
240
+ $settings = get_option( 'wprss_settings_general' );
241
+ $display_settings = wprss_get_display_settings( $settings );
242
+ $args = wprss_get_shortcode_default_args( $args );
243
+
244
+ $args = apply_filters( 'wprss_shortcode_args', $args );
245
+
246
+ $query_args = $settings;
247
+ if ( isset( $args['limit'] ) ) {
248
+ $query_args['feed_limit'] = filter_var( $args['limit'], FILTER_VALIDATE_INT, array(
249
+ 'options' => array(
250
+ 'min_range' => 1,
251
+ 'default' => $query_args['feed_limit'],
252
+ ),
253
+ ) );
254
+ }
255
+
256
+ if ( isset( $args['source'] ) ) {
257
+ $query_args['source'] = $args['source'];
258
+ }
259
+ elseif ( isset( $args['exclude'] ) ) {
260
+ $query_args['exclude'] = $args['exclude'];
261
+ }
262
+
263
+ $feed_items = wprss_get_feed_items_query( $query_args );
264
+
265
+ do_action( 'wprss_display_template', $display_settings, $args, $feed_items );
266
+ }
267
+
268
+
269
+ /**
270
+ * Redirects to wprss_display_feed_items
271
+ * It is used for backwards compatibility to versions < 2.0
272
+ *
273
+ * @since 2.1
274
+ */
275
+ function wp_rss_aggregator( $args = array() ) {
276
+ wprss_display_feed_items( $args );
277
+ }
278
+
279
+
280
+ /**
281
+ * Limits a phrase/content to a defined number of words
282
+ *
283
+ * NOT BEING USED as we're using the native WP function, although the native one strips tags, so I'll
284
+ * probably revisit this one again soon.
285
+ *
286
+ * @since 3.0
287
+ * @param string $words
288
+ * @param integer $limit
289
+ * @param string $append
290
+ * @return string
291
+ */
292
+ function wprss_limit_words( $words, $limit, $append = '' ) {
293
+ /* Add 1 to the specified limit becuase arrays start at 0 */
294
+ $limit = $limit + 1;
295
+ /* Store each individual word as an array element
296
+ up to the limit */
297
+ $words = explode( ' ', $words, $limit );
298
+ /* Shorten the array by 1 because that final element will be the sum of all the words after the limit */
299
+ array_pop( $words );
300
+ /* Implode the array for output, and append an ellipse */
301
+ $words = implode( ' ', $words ) . $append;
302
+ /* Return the result */
303
+ return rtrim( $words );
304
+ }
includes/feed-processing.php ADDED
@@ -0,0 +1,649 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Feed processing related functions
4
+ *
5
+ * @package WPRSSAggregator
6
+ */
7
+
8
+
9
+ /**
10
+ * Change the default feed cache recreation period to 2 hours
11
+ *
12
+ * Probably not needed since we are now disabling caching altogether
13
+ *
14
+ * @since 2.1
15
+ */
16
+ function wprss_feed_cache_lifetime( $seconds )
17
+ {
18
+ return 1; // one second
19
+ }
20
+
21
+
22
+ /**
23
+ * Disable caching of feeds in transients, we don't need it as we are storing them in the wp_posts table
24
+ *
25
+ * @since 3.0
26
+ */
27
+ function wprss_do_not_cache_feeds( &$feed ) {
28
+ $feed->enable_cache( false );
29
+ }
30
+
31
+
32
+ /**
33
+ * Parameters for query to get all feed sources
34
+ *
35
+ * @since 3.0
36
+ */
37
+ function wprss_get_all_feed_sources() {
38
+ // Get all feed sources
39
+ $feed_sources = new WP_Query( apply_filters(
40
+ 'wprss_get_all_feed_sources',
41
+ array(
42
+ 'post_type' => 'wprss_feed',
43
+ 'post_status' => 'publish',
44
+ 'cache_results' => false, // Disable caching, used for one-off queries
45
+ 'no_found_rows' => true, // We don't need pagination, so disable it
46
+ 'posts_per_page' => -1
47
+ )
48
+ ) );
49
+ return $feed_sources;
50
+ }
51
+
52
+
53
+ /**
54
+ * Parameters for query to get feed sources
55
+ *
56
+ * @since 3.0
57
+ */
58
+ function wprss_get_feed_source() {
59
+ // Get all feed sources
60
+ $feed_sources = new WP_Query( apply_filters(
61
+ 'wprss_get_all_feed_sources',
62
+ array(
63
+ 'post_type' => 'wprss_feed',
64
+ 'post_status' => 'publish',
65
+ 'cache_results' => false, // Disable caching, used for one-off queries
66
+ 'no_found_rows' => true, // We don't need pagination, so disable it
67
+ 'posts_per_page' => -1
68
+ )
69
+ ) );
70
+ return $feed_sources;
71
+ }
72
+
73
+
74
+ /**
75
+ * Database query to get existing permalinks
76
+ *
77
+ * @since 3.0
78
+ */
79
+ function get_existing_permalinks( $feed_ID ) {
80
+ global $wpdb;
81
+
82
+ $existing_permalinks = $wpdb->get_col(
83
+ "SELECT meta_value
84
+ FROM $wpdb->postmeta
85
+ WHERE meta_key = 'wprss_item_permalink'
86
+ AND post_id IN ( SELECT post_id FROM $wpdb->postmeta WHERE meta_value = $feed_ID )"
87
+ );
88
+
89
+ return $existing_permalinks;
90
+ }
91
+
92
+
93
+ /**
94
+ * A clone of the function 'fetch_feed' in wp-includes/feed.php [line #529]
95
+ *
96
+ * @since 3.5
97
+ */
98
+ function wprss_fetch_feed( $url ) {
99
+ require_once ( ABSPATH . WPINC . '/class-feed.php' );
100
+
101
+ $feed = new SimplePie();
102
+
103
+ // Commented out Sanitization, due to a conflict with google RSS image URLS.
104
+ // With sanitization on, the urls get truncated from the front.
105
+
106
+ // $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' );
107
+ // We must manually overwrite $feed->sanitize because SimplePie's
108
+ // constructor sets it before we have a chance to set the sanitization class
109
+ // $feed->sanitize = new WP_SimplePie_Sanitize_KSES();
110
+
111
+ $feed->set_cache_class( 'WP_Feed_Cache' );
112
+ $feed->set_file_class( 'WP_SimplePie_File' );
113
+
114
+ $feed->set_feed_url( $url );
115
+
116
+ $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) );
117
+ do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
118
+ $feed->init();
119
+ $feed->handle_content_type();
120
+
121
+ if ( $feed->error() )
122
+ return new WP_Error( 'simplepie-error', $feed->error() );
123
+
124
+ return $feed;
125
+ }
126
+
127
+
128
+ /**
129
+ * Fetch the feeds from a feed item url
130
+ *
131
+ * @since 3.0
132
+ */
133
+ function wprss_get_feed_items( $feed_url ) {
134
+ $general_settings = get_option( 'wprss_settings_general' );
135
+ $feed_item_limit = $general_settings['limit_feed_items_imported'];
136
+
137
+ // Don't fetch the feed if feed item limit is 0, there's no need, huge speed improvement
138
+ if ( $feed_item_limit == 0 ) return;
139
+
140
+ add_filter( 'wp_feed_cache_transient_lifetime' , 'wprss_feed_cache_lifetime' );
141
+
142
+ /* Disable caching of feeds */
143
+ add_action( 'wp_feed_options', 'wprss_do_not_cache_feeds' );
144
+ /* Fetch the feed from the soure URL specified */
145
+ $feed = wprss_fetch_feed( $feed_url );
146
+ //$feed = new SimplePie();
147
+ //$feed->set_feed_url( $feed_url );
148
+ //$feed->init();
149
+ /* Remove action here because we only don't want it active feed imports outside of our plugin */
150
+ remove_action( 'wp_feed_options', 'wprss_do_not_cache_feeds' );
151
+
152
+ //$feed = wprss_fetch_feed( $feed_url );
153
+ remove_filter( 'wp_feed_cache_transient_lifetime' , 'wprss_feed_cache_lifetime' );
154
+
155
+ if ( !is_wp_error( $feed ) ) {
156
+
157
+ // Figure out how many total items there are, but limit it to the number of items set in options.
158
+ $maxitems = $feed->get_item_quantity( $feed_item_limit );
159
+
160
+ if ( $maxitems == 0 ) { return; }
161
+
162
+ // Build an array of all the items, starting with element 0 (first element).
163
+ $items = $feed->get_items( 0, $maxitems );
164
+ return $items;
165
+ }
166
+
167
+ else { return; }
168
+ }
169
+
170
+
171
+ /**
172
+ * Insert a WPRSS feed item post
173
+ *
174
+ * @since 3.0
175
+ */
176
+ function wprss_items_insert_post( $items, $feed_ID ) {
177
+
178
+ // Gather the permalinks of existing feed item's related to this feed source
179
+ $existing_permalinks = get_existing_permalinks( $feed_ID );
180
+
181
+ foreach ( $items as $item ) {
182
+
183
+ // normalize permalink to pass through feed proxy URL
184
+ $permalink = $item->get_permalink();
185
+
186
+ // CHECK PERMALINK FOR VIDEO HOSTS : YOUTUBE, VIMEO AND DAILYMOTION
187
+ $found_video_host = preg_match( '/http[s]?:\/\/(www\.)?(youtube|dailymotion|vimeo)\.com\/(.*)/i', $permalink, $matches );
188
+
189
+ // If video host was found
190
+ if ( $found_video_host !== 0 && $found_video_host !== FALSE ) {
191
+
192
+ // Get general options
193
+ $options = get_option( 'wprss_settings_general' );
194
+ // Get the video link option entry, or false if it does not exist
195
+ $video_link = ( isset($options['video_link']) )? $options['video_link'] : 'false';
196
+
197
+ // If the video link option is true, change the video URL to its repective host's embedded
198
+ // video player URL. Otherwise, leave the permalink as is.
199
+ if ( strtolower( $video_link ) === 'true' ) {
200
+ $host = $matches[2];
201
+ switch( $host ) {
202
+ case 'youtube':
203
+ preg_match( '/(&|\?)v=([^&]+)/', $permalink, $yt_matches );
204
+ $permalink = 'http://www.youtube.com/embed/' . $yt_matches[2];
205
+ break;
206
+ case 'vimeo':
207
+ preg_match( '/(\d*)$/i', $permalink, $vim_matches );
208
+ $permalink = 'http://player.vimeo.com/video/' . $vim_matches[0];
209
+ break;
210
+ case 'dailymotion':
211
+ preg_match( '/(\.com\/)(video\/)(.*)/i', $permalink, $dm_matches );
212
+ $permalink = 'http://www.dailymotion.com/embed/video/' . $dm_matches[3];
213
+ break;
214
+ }
215
+ }
216
+ }
217
+
218
+
219
+ /*
220
+ $response = wp_remote_head( $permalink );
221
+ if ( !is_wp_error( $response ) && isset( $response['headers']['location'] ) ) {
222
+ $permalink = current( explode( '?', $response['headers']['location'] ) );
223
+ }*/
224
+
225
+ // Check if newly fetched item already present in existing feed items,
226
+ // if not insert it into wp_posts and insert post meta.
227
+ if ( ! ( in_array( $permalink, $existing_permalinks ) ) ) {
228
+
229
+ // Apply filters that determine if the feed item should be inserted into the DB or not.
230
+ $item = apply_filters( 'wprss_insert_post_item_conditionals', $item, $feed_ID, $permalink );
231
+
232
+ // If the item is not NULL, continue to inserting the feed item post into the DB
233
+ if ( $item !== NULL ) {
234
+
235
+ $feed_item = apply_filters(
236
+ 'wprss_populate_post_data',
237
+ array(
238
+ 'post_title' => $item->get_title(),
239
+ 'post_content' => '',
240
+ 'post_status' => 'publish',
241
+ 'post_type' => 'wprss_feed_item',
242
+ ),
243
+ $item
244
+ );
245
+
246
+ if ( defined('ICL_SITEPRESS_VERSION') )
247
+ @include_once( WP_PLUGIN_DIR . '/sitepress-multilingual-cms/inc/wpml-api.php' );
248
+ if ( defined('ICL_LANGUAGE_CODE') )
249
+ $_POST['icl_post_language'] = $language_code = ICL_LANGUAGE_CODE;
250
+
251
+ // Create and insert post object into the DB
252
+ $inserted_ID = wp_insert_post( $feed_item );
253
+
254
+ if ( !is_wp_error( $inserted_ID ) ) {
255
+
256
+ if ( is_object( $inserted_ID ) ) {
257
+ if ( isset( $inserted_ID['ID'] ) ) {
258
+ $inserted_ID = $inserted_ID['ID'];
259
+ }
260
+ elseif ( isset( $inserted_ID->ID ) ) {
261
+ $inserted_ID = $inserted_ID->ID;
262
+ }
263
+ }
264
+
265
+ // Create and insert post meta into the DB
266
+ wprss_items_insert_post_meta( $inserted_ID, $item, $feed_ID, $permalink );
267
+
268
+ // Remember newly added permalink
269
+ $existing_permalinks[] = $permalink;
270
+ }
271
+ }
272
+ }
273
+ }
274
+ }
275
+
276
+
277
+ /**
278
+ * Creates meta entries for feed items while they are being imported
279
+ *
280
+ * @since 2.3
281
+ */
282
+ function wprss_items_insert_post_meta( $inserted_ID, $item, $feed_ID, $feed_url) {
283
+ update_post_meta( $inserted_ID, 'wprss_item_permalink', $feed_url );
284
+ update_post_meta( $inserted_ID, 'wprss_item_description', $item->get_description() );
285
+ update_post_meta( $inserted_ID, 'wprss_item_date', $item->get_date( 'U' ) ); // Save as Unix timestamp format
286
+ update_post_meta( $inserted_ID, 'wprss_feed_id', $feed_ID);
287
+ do_action( 'wprss_items_create_post_meta', $inserted_ID, $item, $feed_ID );
288
+ }
289
+
290
+
291
+ add_action( 'publish_wprss_feed', 'wprss_fetch_insert_feed_items', 10 );
292
+ /**
293
+ * Fetches feed items from source provided and inserts into db
294
+ *
295
+ * This function is used when inserting or untrashing a new feed source, it only gets feeds from that particular source
296
+ *
297
+ * @since 3.0
298
+ */
299
+ function wprss_fetch_insert_feed_items( $post_id ) {
300
+ wp_schedule_single_event( time(), 'wprss_fetch_single_feed_hook', array( $post_id ) );
301
+ }
302
+
303
+
304
+
305
+ /**
306
+ * Returns the image of the feed.
307
+ * The reason this function exists is for add-ons to be able to detect if the plugin core
308
+ * supports feed image functionality through a simple function_exists() call.
309
+ *
310
+ * @param $source_id The ID of the feed source
311
+ * @return string The link to the feed image
312
+ * @since 1.0
313
+ */
314
+ function wprss_get_feed_image( $source_id ) {
315
+ return get_post_meta( $source_id, 'wprss_feed_image', true );
316
+ }
317
+
318
+
319
+ add_action( 'post_updated', 'wprss_updated_feed_source', 10, 3 );
320
+ /**
321
+ * This function is triggered just after a post is updated.
322
+ * It checks if the updated post is a feed source, and carries out any
323
+ * updating necassary.
324
+ *
325
+ * @since 3.3
326
+ */
327
+ function wprss_updated_feed_source( $post_ID, $post_after, $post_before ) {
328
+ // Check if the post is a feed source and is published
329
+
330
+ if ( ( $post_after->post_type == 'wprss_feed' ) && ( $post_after->post_status == 'publish' ) ) {
331
+
332
+ if ( isset( $_POST['wprss_url'] ) && !empty( $_POST['wprss_url'] ) ) {
333
+ $url = $_POST['wprss_url'];
334
+ $feed = wprss_fetch_feed( $url );
335
+ if ( $feed !== NULL && !is_wp_error( $feed ) ) {
336
+ update_post_meta( $post_ID, 'wprss_site_url', $feed->get_permalink() );
337
+ update_post_meta( $post_ID, 'wprss_feed_image', $feed->get_image_url() );
338
+ }
339
+ }
340
+
341
+
342
+ if ( isset( $_POST['wprss_limit'] ) && !empty( $_POST['wprss_limit'] ) ) {
343
+ // Checking feed limit change
344
+ // Get the limit currently saved in db, and limit in POST request
345
+ //$limit = get_post_meta( $post_ID, 'wprss_limit', true );
346
+ $limit = $_POST['wprss_limit'];
347
+ // Get all feed items for this source
348
+ $feed_sources = new WP_Query(
349
+ array(
350
+ 'post_type' => 'wprss_feed_item',
351
+ 'post_status' => 'publish',
352
+ 'cache_results' => false, // Disable caching, used for one-off queries
353
+ 'no_found_rows' => true, // We don't need pagination, so disable it
354
+ 'posts_per_page' => -1,
355
+ 'orderby' => 'date',
356
+ 'order' => 'ASC',
357
+ 'meta_query' => array(
358
+ array(
359
+ 'key' => 'wprss_feed_id',
360
+ 'value' => $post_ID,
361
+ 'compare' => 'LIKE'
362
+ )
363
+ )
364
+ )
365
+ );
366
+ // If the limit is smaller than the number of found posts, delete the feed items
367
+ // and re-import, to ensure that most recent feed items are present.
368
+ $difference = intval( $feed_sources->post_count ) - intval( $limit );
369
+ if ( $difference > 0 ) {
370
+ // Loop and delete the excess feed items
371
+ while ( $feed_sources->have_posts() && $difference > 0 ) {
372
+ $feed_sources->the_post();
373
+ wp_delete_post( get_the_ID(), true );
374
+ $difference--;
375
+ }
376
+ }
377
+ }
378
+ }
379
+ }
380
+
381
+
382
+
383
+ add_action( 'wprss_fetch_single_feed_hook', 'wprss_fetch_insert_single_feed_items' );
384
+ /**
385
+ * Fetches feed items from source provided and inserts into db
386
+ *
387
+ * @since 3.2
388
+ */
389
+ function wprss_fetch_insert_single_feed_items( $feed_ID ) {
390
+
391
+ // Get the URL and Feed Limit post meta data
392
+ $feed_url = get_post_meta( $feed_ID, 'wprss_url', true );
393
+ $feed_limit = get_post_meta( $feed_ID, 'wprss_limit', true );
394
+
395
+ $feed_url = apply_filters( 'wprss_feed_source_url', $feed_url, $feed_ID );
396
+
397
+ // Use the URL custom field to fetch the feed items for this source
398
+ if ( filter_var( $feed_url, FILTER_VALIDATE_URL ) ) {
399
+ $items = wprss_get_feed_items( $feed_url );
400
+ if ( $items === NULL ) $items = array();
401
+
402
+ // If the feed has its own meta limit,
403
+ // slice the items array using the feed meta limit
404
+ if ( !empty( $feed_limit ) )
405
+ $items_to_insert = array_slice($items, 0, $feed_limit);
406
+ else $items_to_insert = $items;
407
+
408
+ // Insert the items into the db
409
+ if ( !empty( $items_to_insert ) ) {
410
+ wprss_items_insert_post( $items_to_insert, $feed_ID );
411
+ }
412
+ }
413
+ }
414
+
415
+
416
+ /**
417
+ * Fetches all feed items from sources provided and inserts into db
418
+ *
419
+ * This function is used by the cron job or the debugging functions to get all feeds from all feed sources
420
+ *
421
+ * @since 3.0
422
+ */
423
+ function wprss_fetch_insert_all_feed_items() {
424
+
425
+ // Get all feed sources
426
+ $feed_sources = wprss_get_all_feed_sources();
427
+
428
+ if( $feed_sources->have_posts() ) {
429
+ // Start by getting one feed source, we will cycle through them one by one,
430
+ // fetching feed items and adding them to the database in each pass
431
+ while ( $feed_sources->have_posts() ) {
432
+ $feed_sources->the_post();
433
+ wp_schedule_single_event( time(), 'wprss_fetch_single_feed_hook', array( get_the_ID() ) );
434
+ }
435
+ wp_reset_postdata(); // Restore the $post global to the current post in the main query
436
+ }
437
+ }
438
+
439
+
440
+
441
+ add_action( 'updated_post_meta', 'wprss_update_feed_meta', 10, 4 );
442
+ /**
443
+ * This function is run whenever a post is saved or updated.
444
+ *
445
+ * @since 3.4
446
+ */
447
+ function wprss_update_feed_meta( $meta_id, $post_id, $meta_key, $meta_value ) {
448
+ $post = get_post( $post_id );
449
+ if ( $post->post_status === 'publish' && $post->post_type === 'wprss_feed' ) {
450
+ if ( $meta_key === 'wprss_url' )
451
+ wprss_change_fb_url( $post_id, $meta_value );
452
+ }
453
+ }
454
+
455
+
456
+ function wprss_change_fb_url( $post_id, $url ) {
457
+ # Check if url begins with a known facebook hostname.
458
+ if ( stripos( $url, 'http://facebook.com' ) === 0
459
+ || stripos( $url, 'http://www.facebook.com' ) === 0
460
+ || stripos( $url, 'https://facebook.com' ) === 0
461
+ || stripos( $url, 'https://www.facebook.com' ) === 0
462
+ ) {
463
+ # Generate the new URL to FB Graph
464
+ $com_index = stripos( $url, '.com' );
465
+ $fb_page = substr( $url, $com_index + 4 ); # 4 = length of ".com"
466
+ $fb_graph_url = 'http://graph.facebook.com' . $fb_page;
467
+ # Contact FB Graph and get data
468
+ $response = wp_remote_get( $fb_graph_url );
469
+ # If the repsonse successful and has a body
470
+ if ( !is_wp_error( $response ) && isset( $response['body'] ) ) {
471
+ # Parse the body as a JSON string
472
+ $json = json_decode( $response['body'], true );
473
+ # If an id is present ...
474
+ if ( isset( $json['id'] ) ) {
475
+ # Generate the final URL for this feed and update the post meta
476
+ $final_url = "http://www.facebook.com/feeds/page.php?format=atom10&id=" . $json['id'];
477
+ update_post_meta( $post_id, 'wprss_url', $final_url, $url );
478
+ }
479
+ }
480
+ }
481
+ }
482
+
483
+
484
+ add_action( 'trash_wprss_feed', 'wprss_delete_feed_items' ); // maybe use wp_trash_post action? wp_trash_wprss_feed
485
+ /**
486
+ * Delete feed items on trashing of corresponding feed source
487
+ *
488
+ * @since 2.0
489
+ */
490
+ function wprss_delete_feed_items( $postid ) {
491
+
492
+ $args = array(
493
+ 'post_type' => 'wprss_feed_item',
494
+ // Next 3 parameters for performance, see http://thomasgriffinmedia.com/blog/2012/10/optimize-wordpress-queries
495
+ 'cache_results' => false, // Disable caching, used for one-off queries
496
+ 'no_found_rows' => true, // We don't need pagination, so disable it
497
+ 'fields' => 'ids', // Returns post IDs only
498
+ 'posts_per_page'=> -1,
499
+ 'meta_query' => array(
500
+ array(
501
+ 'key' => 'wprss_feed_id',
502
+ 'value' => $postid,
503
+ 'compare' => 'LIKE'
504
+ )
505
+ )
506
+ );
507
+
508
+ $feed_item_ids = get_posts( $args );
509
+ foreach( $feed_item_ids as $feed_item_id ) {
510
+ $purge = wp_delete_post( $feed_item_id, true ); // delete the feed item, skipping trash
511
+ }
512
+ wp_reset_postdata();
513
+ }
514
+
515
+
516
+ add_action( 'wprss_delete_all_feed_items_hook', 'wprss_delete_all_feed_items' );
517
+ /**
518
+ * Delete all feed items
519
+ *
520
+ * @since 3.0
521
+ */
522
+ function wprss_delete_all_feed_items() {
523
+ $args = array(
524
+ 'post_type' => 'wprss_feed_item',
525
+ 'cache_results' => false, // Disable caching, used for one-off queries
526
+ 'no_found_rows' => true, // We don't need pagination, so disable it
527
+ 'fields' => 'ids', // Returns post IDs only
528
+ 'posts_per_page' => -1,
529
+ );
530
+
531
+ //$feed_items = new WP_Query( $args );
532
+
533
+ $feed_item_ids = get_posts( $args );
534
+ foreach( $feed_item_ids as $feed_item_id ) {
535
+ $purge = wp_delete_post( $feed_item_id, true ); // delete the feed item, skipping trash
536
+ }
537
+ wp_reset_postdata();
538
+ }
539
+
540
+
541
+ /**
542
+ * Returns the given parameter as a string. Used in wprss_truncate_posts()
543
+ *
544
+ * @return string The given parameter as a string
545
+ * @since 3.5.1
546
+ */
547
+ function wprss_return_as_string( $item ) {
548
+ return "'$item'";
549
+ }
550
+
551
+ /**
552
+ * Delete old feed items from the database to avoid bloat
553
+ *
554
+ * @since 2.0
555
+ */
556
+ function wprss_truncate_posts() {
557
+ global $wpdb;
558
+ $general_settings = get_option( 'wprss_settings_general' );
559
+
560
+ if ( $general_settings['limit_feed_items_db'] == 0 ) {
561
+ return;
562
+ }
563
+
564
+ // Set your threshold of max posts and post_type name
565
+ $threshold = $general_settings['limit_feed_items_db'];
566
+ $post_types = apply_filters( 'wprss_truncation_post_types', array( 'wprss_feed_item' ) );
567
+ $post_types_str = array_map( 'wprss_return_as_string', $post_types );
568
+
569
+ $post_type_list = implode( ',' , $post_types_str );
570
+
571
+ // Query post type
572
+ // $wpdb query allows me to select specific columns instead of grabbing the entire post object.
573
+ $query = "
574
+ SELECT ID, post_title FROM $wpdb->posts
575
+ WHERE post_type IN ($post_type_list)
576
+ AND post_status = 'publish'
577
+ ORDER BY post_modified DESC
578
+ ";
579
+
580
+ $results = $wpdb->get_results( $query );
581
+
582
+ // Check if there are any results
583
+ $i = 0;
584
+ if ( count( $results ) ){
585
+ foreach ( $results as $post ) {
586
+ $i++;
587
+
588
+ // Skip any posts within our threshold
589
+ if ( $i <= $threshold )
590
+ continue;
591
+
592
+ // Let the WordPress API do the heavy lifting for cleaning up entire post trails
593
+ $purge = wp_delete_post( $post->ID, true );
594
+ }
595
+ }
596
+ }
597
+
598
+
599
+ /**
600
+ * Custom version of the WP fetch_feed() function, since we want custom sanitization of a feed
601
+ *
602
+ * Not being used at the moment, until we decide whether we can still use fetch_feed and modify its handling of sanitization
603
+ *
604
+ * @since 3.0
605
+ *
606
+ */
607
+ /*function wprss_fetch_feed($url) {
608
+ require_once (ABSPATH . WPINC . '/class-feed.php');
609
+
610
+ $feed = new SimplePie();
611
+
612
+ // $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' );
613
+ // We must manually overwrite $feed->sanitize because SimplePie's
614
+ // constructor sets it before we have a chance to set the sanitization class
615
+ // $feed->sanitize = new WP_SimplePie_Sanitize_KSES();
616
+
617
+ $feed->set_cache_class( 'WP_Feed_Cache' );
618
+ $feed->set_file_class( 'WP_SimplePie_File' );
619
+
620
+ $feed->set_feed_url($url);
621
+ $feed->strip_htmltags(array_merge($feed->strip_htmltags, array( 'h1', 'h2', 'h3', 'h4', 'h5', 'a' )));
622
+ $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) );
623
+ do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
624
+ $feed->init();
625
+ $feed->handle_content_type();
626
+
627
+ if ( $feed->error() )
628
+ return new WP_Error('simplepie-error', $feed->error());
629
+
630
+ return $feed;
631
+ }*/
632
+
633
+
634
+ /**
635
+ * Deletes all imported feeds and re-imports everything
636
+ *
637
+ * @since 3.0
638
+ */
639
+ function wprss_feed_reset() {
640
+ wp_schedule_single_event( time(), 'wprss_delete_all_feed_items_hook' );
641
+ wprss_fetch_insert_all_feed_items();
642
+ }
643
+
644
+ /* add_action( 'wp_feed_options', 'wprss_feed_options' );
645
+ function wprss_feed_options( $feed) {
646
+ $feed->strip_htmltags(array_merge($feed->strip_htmltags, array('h1', 'a', 'img','em')));
647
+ }
648
+
649
+ */
includes/libraries/WP_Logging.php ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class for logging events and errors
5
+ *
6
+ * @package WP Logging Class
7
+ * @copyright Copyright (c) 2012, Pippin Williamson
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ */
10
+
11
+ class WP_Logging {
12
+
13
+
14
+ /**
15
+ * Class constructor.
16
+ *
17
+ * @since 1.0
18
+ *
19
+ * @access public
20
+ * @return void
21
+ */
22
+ function __construct() {
23
+
24
+ // create the log post type
25
+ add_action( 'init', array( $this, 'register_post_type' ) );
26
+
27
+ // create types taxonomy and default types
28
+ add_action( 'init', array( $this, 'register_taxonomy' ) );
29
+
30
+ }
31
+
32
+
33
+ /**
34
+ * Log types
35
+ *
36
+ * Sets up the default log types and allows for new ones to be created
37
+ *
38
+ * @access private
39
+ * @since 1.0
40
+ *
41
+ * @return array
42
+ */
43
+
44
+ private function log_types() {
45
+ $terms = array(
46
+ 'error', 'event'
47
+ );
48
+
49
+ return apply_filters( 'wp_log_types', $terms );
50
+ }
51
+
52
+
53
+ /**
54
+ * Registers the wp_log Post Type
55
+ *
56
+ * @access public
57
+ * @since 1.0
58
+ *
59
+ * @uses register_post_type()
60
+ *
61
+ * @return void
62
+ */
63
+
64
+ public function register_post_type() {
65
+
66
+ /* logs post type */
67
+
68
+ $log_args = array(
69
+ 'labels' => array( 'name' => __( 'Logs', 'wp-logging' ) ),
70
+ 'public' => false,
71
+ 'query_var' => false,
72
+ 'rewrite' => false,
73
+ 'capability_type' => 'post',
74
+ 'supports' => array( 'title', 'editor' ),
75
+ 'can_export' => false
76
+ );
77
+ register_post_type( 'wp_log', apply_filters( 'wp_logging_post_type_args', $log_args ) );
78
+
79
+ }
80
+
81
+
82
+ /**
83
+ * Registers the Type Taxonomy
84
+ *
85
+ * The Type taxonomy is used to determine the type of log entry
86
+ *
87
+ * @access public
88
+ * @since 1.0
89
+ *
90
+ * @uses register_taxonomy()
91
+ * @uses term_exists()
92
+ * @uses wp_insert_term()
93
+ *
94
+ * @return void
95
+ */
96
+
97
+ public function register_taxonomy() {
98
+
99
+ register_taxonomy( 'wp_log_type', 'wp_log' );
100
+
101
+ $types = self::log_types();
102
+
103
+ foreach ( $types as $type ) {
104
+ if( ! term_exists( $type, 'wp_log_type' ) ) {
105
+ wp_insert_term( $type, 'wp_log_type' );
106
+ }
107
+ }
108
+ }
109
+
110
+
111
+ /**
112
+ * Check if a log type is valid
113
+ *
114
+ * Checks to see if the specified type is in the registered list of types
115
+ *
116
+ * @access private
117
+ * @since 1.0
118
+ *
119
+ *
120
+ * @return array
121
+ */
122
+
123
+ private function valid_type( $type ) {
124
+ return in_array( $type, self::log_types() );
125
+ }
126
+
127
+
128
+ /**
129
+ * Create new log entry
130
+ *
131
+ * This is just a simple and fast way to log something. Use self::insert_log()
132
+ * if you need to store custom meta data
133
+ *
134
+ * @access private
135
+ * @since 1.0
136
+ *
137
+ * @uses self::insert_log()
138
+ *
139
+ * @return int The ID of the new log entry
140
+ */
141
+
142
+ public static function add( $title = '', $message = '', $parent = 0, $type = null ) {
143
+
144
+ $log_data = array(
145
+ 'post_title' => $title,
146
+ 'post_content' => $message,
147
+ 'post_parent' => $parent,
148
+ 'log_type' => $type
149
+ );
150
+
151
+ return self::insert_log( $log_data );
152
+
153
+ }
154
+
155
+
156
+ /**
157
+ * Stores a log entry
158
+ *
159
+ * @access private
160
+ * @since 1.0
161
+ *
162
+ * @uses wp_parse_args()
163
+ * @uses wp_insert_post()
164
+ * @uses update_post_meta()
165
+ * @uses wp_set_object_terms()
166
+ * @uses sanitize_key()
167
+ *
168
+ * @return int The ID of the newly created log item
169
+ */
170
+
171
+ public static function insert_log( $log_data = array(), $log_meta = array() ) {
172
+
173
+ $defaults = array(
174
+ 'post_type' => 'wp_log',
175
+ 'post_status' => 'publish',
176
+ 'post_parent' => 0,
177
+ 'post_content' => '',
178
+ 'log_type' => false
179
+ );
180
+
181
+ $args = wp_parse_args( $log_data, $defaults );
182
+
183
+ do_action( 'wp_pre_insert_log' );
184
+
185
+ // store the log entry
186
+ $log_id = wp_insert_post( $args );
187
+
188
+ // set the log type, if any
189
+ if( $log_data['log_type'] && self::valid_type( $log_data['log_type'] ) ) {
190
+ wp_set_object_terms( $log_id, $log_data['log_type'], 'wp_log_type', false );
191
+ }
192
+
193
+
194
+ // set log meta, if any
195
+ if( $log_id && ! empty( $log_meta ) ) {
196
+ foreach( (array) $log_meta as $key => $meta ) {
197
+ update_post_meta( $log_id, '_wp_log_' . sanitize_key( $key ), $meta );
198
+ }
199
+ }
200
+
201
+ do_action( 'wp_post_insert_log', $log_id );
202
+
203
+ return $log_id;
204
+
205
+ }
206
+
207
+
208
+ /**
209
+ * Update and existing log item
210
+ *
211
+ * @access private
212
+ * @since 1.0
213
+ *
214
+ * @uses wp_parse_args()
215
+ * @uses wp_update_post()
216
+ * @uses update_post_meta()
217
+ *
218
+ * @return bool True if successful, false otherwise
219
+ */
220
+ public static function update_log( $log_data = array(), $log_meta = array() ) {
221
+
222
+ do_action( 'wp_pre_update_log', $log_id );
223
+
224
+ $defaults = array(
225
+ 'post_type' => 'wp_log',
226
+ 'post_status' => 'publish',
227
+ 'post_parent' => 0
228
+ );
229
+
230
+ $args = wp_parse_args( $log_data, $defaults );
231
+
232
+ // store the log entry
233
+ $log_id = wp_update_post( $args );
234
+
235
+ if( $log_id && ! empty( $log_meta ) ) {
236
+ foreach( (array) $log_meta as $key => $meta ) {
237
+ if( ! empty( $meta ) )
238
+ update_post_meta( $log_id, '_wp_log_' . sanitize_key( $key ), $meta );
239
+ }
240
+ }
241
+
242
+ do_action( 'wp_post_update_log', $log_id );
243
+
244
+ }
245
+
246
+
247
+ /**
248
+ * Easily retrieves log items for a particular object ID
249
+ *
250
+ * @access private
251
+ * @since 1.0
252
+ *
253
+ * @uses self::get_connected_logs()
254
+ *
255
+ * @return array
256
+ */
257
+
258
+ public static function get_logs( $object_id = 0, $type = null, $paged = null ) {
259
+ return self::get_connected_logs( array( 'post_parent' => $object_id, 'paged' => $paged, 'log_type' => $type ) );
260
+
261
+ }
262
+
263
+
264
+ /**
265
+ * Retrieve all connected logs
266
+ *
267
+ * Used for retrieving logs related to particular items, such as a specific purchase.
268
+ *
269
+ * @access private
270
+ * @since 1.0
271
+ *
272
+ * @uses wp_parse_args()
273
+ * @uses get_posts()
274
+ * @uses get_query_var()
275
+ * @uses self::valid_type()
276
+ *
277
+ * @return array / false
278
+ */
279
+
280
+ public static function get_connected_logs( $args = array() ) {
281
+
282
+ $defaults = array(
283
+ 'post_parent' => 0,
284
+ 'post_type' => 'wp_log',
285
+ 'posts_per_page' => 10,
286
+ 'post_status' => 'publish',
287
+ 'paged' => get_query_var( 'paged' ),
288
+ 'log_type' => false
289
+ );
290
+
291
+ $query_args = wp_parse_args( $args, $defaults );
292
+
293
+ if( $query_args['log_type'] && self::valid_type( $query_args['log_type'] ) ) {
294
+
295
+ $query_args['tax_query'] = array(
296
+ array(
297
+ 'taxonomy' => 'wp_log_type',
298
+ 'field' => 'slug',
299
+ 'terms' => $query_args['log_type']
300
+ )
301
+ );
302
+
303
+ }
304
+
305
+ $logs = get_posts( $query_args );
306
+
307
+ if( $logs )
308
+ return $logs;
309
+
310
+ // no logs found
311
+ return false;
312
+
313
+ }
314
+
315
+
316
+ /**
317
+ * Retrieves number of log entries connected to particular object ID
318
+ *
319
+ * @access private
320
+ * @since 1.0
321
+ *
322
+ * @uses WP_Query()
323
+ * @uses self::valid_type()
324
+ *
325
+ * @return int
326
+ */
327
+
328
+ public static function get_log_count( $object_id = 0, $type = null, $meta_query = null ) {
329
+
330
+ $query_args = array(
331
+ 'post_parent' => $object_id,
332
+ 'post_type' => 'wp_log',
333
+ 'posts_per_page' => -1,
334
+ 'post_status' => 'publish'
335
+ );
336
+
337
+ if( ! empty( $type ) && self::valid_type( $type ) ) {
338
+
339
+ $query_args['tax_query'] = array(
340
+ array(
341
+ 'taxonomy' => 'wp_log_type',
342
+ 'field' => 'slug',
343
+ 'terms' => $type
344
+ )
345
+ );
346
+
347
+ }
348
+
349
+ if( ! empty( $meta_query ) ) {
350
+ $query_args['meta_query'] = $meta_query;
351
+ }
352
+
353
+ $logs = new WP_Query( $query_args );
354
+
355
+ return (int) $logs->post_count;
356
+
357
+ }
358
+
359
+ }
360
+ $GLOBALS['wp_logs'] = new WP_Logging();
includes/libraries/browser.php ADDED
@@ -0,0 +1,1082 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Modified to remove var
4
+ * Chris Christoff on 12/26/2012
5
+ * Changes: Changes vars to publics
6
+ *
7
+ * Modified to work for EDD by
8
+ * Chris Christoff on 12/23/2012
9
+ * Changes: Removed the browser string return and added spacing. Also removed return HTML formatting.
10
+ *
11
+ * Modified to add formatted User Agent string for EDD System Info by
12
+ * Chris Christoff on 12/23/2012
13
+ * Changes: Split user string and add formatting so we can print a nicely
14
+ * formatted user agent string on the EDD System Info
15
+ *
16
+ * File: Browser.php
17
+ * Author: Chris Schuld (http://chrisschuld.com/)
18
+ * Last Modified: August 20th, 2010
19
+ * @version 1.9
20
+ * @package PegasusPHP
21
+ *
22
+ * Copyright (C) 2008-2010 Chris Schuld (chris@chrisschuld.com)
23
+ *
24
+ * This program is free software; you can redistribute it and/or
25
+ * modify it under the terms of the GNU General Public License as
26
+ * published by the Free Software Foundation; either version 2 of
27
+ * the License, or (at your option) any later version.
28
+ *
29
+ * This program is distributed in the hope that it will be useful,
30
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
+ * GNU General Public License for more details at:
33
+ * http://www.gnu.org/copyleft/gpl.html
34
+ *
35
+ *
36
+ * Typical Usage:
37
+ *
38
+ * $browser = new Browser();
39
+ * if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 2 ) {
40
+ * echo 'You have FireFox version 2 or greater';
41
+ * }
42
+ *
43
+ * User Agents Sampled from: http://www.useragentstring.com/
44
+ *
45
+ * This implementation is based on the original work from Gary White
46
+ * http://apptools.com/phptools/browser/
47
+ *
48
+ * UPDATES:
49
+ *
50
+ * 2010-08-20 (v1.9):
51
+ * + Added MSN Explorer Browser (legacy)
52
+ * + Added Bing/MSN Robot (Thanks Rob MacDonald)
53
+ * + Added the Android Platform (PLATFORM_ANDROID)
54
+ * + Fixed issue with Android 1.6/2.2 (Thanks Tom Hirashima)
55
+ *
56
+ * 2010-04-27 (v1.8):
57
+ * + Added iPad Support
58
+ *
59
+ * 2010-03-07 (v1.7):
60
+ * + *MAJOR* Rebuild (preg_match and other "slow" routine removal(s))
61
+ * + Almost allof Gary's original code has been replaced
62
+ * + Large PHPUNIT testing environment created to validate new releases and additions
63
+ * + Added FreeBSD Platform
64
+ * + Added OpenBSD Platform
65
+ * + Added NetBSD Platform
66
+ * + Added SunOS Platform
67
+ * + Added OpenSolaris Platform
68
+ * + Added support of the Iceweazel Browser
69
+ * + Added isChromeFrame() call to check if chromeframe is in use
70
+ * + Moved the Opera check in front of the Firefox check due to legacy Opera User Agents
71
+ * + Added the __toString() method (Thanks Deano)
72
+ *
73
+ * 2009-11-15:
74
+ * + Updated the checkes for Firefox
75
+ * + Added the NOKIA platform
76
+ * + Added Checks for the NOKIA brower(s)
77
+ *
78
+ * 2009-11-08:
79
+ * + PHP 5.3 Support
80
+ * + Added support for BlackBerry OS and BlackBerry browser
81
+ * + Added support for the Opera Mini browser
82
+ * + Added additional documenation
83
+ * + Added support for isRobot() and isMobile()
84
+ * + Added support for Opera version 10
85
+ * + Added support for deprecated Netscape Navigator version 9
86
+ * + Added support for IceCat
87
+ * + Added support for Shiretoko
88
+ *
89
+ * 2010-04-27 (v1.8):
90
+ * + Added iPad Support
91
+ *
92
+ * 2009-08-18:
93
+ * + Updated to support PHP 5.3 - removed all deprecated function calls
94
+ * + Updated to remove all double quotes (") -- converted to single quotes (')
95
+ *
96
+ * 2009-04-27:
97
+ * + Updated the IE check to remove a typo and bug (thanks John)
98
+ *
99
+ * 2009-04-22:
100
+ * + Added detection for GoogleBot
101
+ * + Added detection for the W3C Validator.
102
+ * + Added detection for Yahoo! Slurp
103
+ *
104
+ * 2009-03-14:
105
+ * + Added detection for iPods.
106
+ * + Added Platform detection for iPhones
107
+ * + Added Platform detection for iPods
108
+ *
109
+ * 2009-02-16: (Rick Hale)
110
+ * + Added version detection for Android phones.
111
+ *
112
+ * 2008-12-09:
113
+ * + Removed unused constant
114
+ *
115
+ * 2008-11-07:
116
+ * + Added Google's Chrome to the detection list
117
+ * + Added isBrowser(string) to the list of functions special thanks to
118
+ * Daniel 'mavrick' Lang for the function concept (http://mavrick.id.au)
119
+ *
120
+ *
121
+ * Gary White noted: "Since browser detection is so unreliable, I am
122
+ * no longer maintaining this script. You are free to use and or
123
+ * modify/update it as you want, however the author assumes no
124
+ * responsibility for the accuracy of the detected values."
125
+ *
126
+ * Anyone experienced with Gary's script might be interested in these notes:
127
+ *
128
+ * Added class constants
129
+ * Added detection and version detection for Google's Chrome
130
+ * Updated the version detection for Amaya
131
+ * Updated the version detection for Firefox
132
+ * Updated the version detection for Lynx
133
+ * Updated the version detection for WebTV
134
+ * Updated the version detection for NetPositive
135
+ * Updated the version detection for IE
136
+ * Updated the version detection for OmniWeb
137
+ * Updated the version detection for iCab
138
+ * Updated the version detection for Safari
139
+ * Updated Safari to remove mobile devices (iPhone)
140
+ * Added detection for iPhone
141
+ * Added detection for robots
142
+ * Added detection for mobile devices
143
+ * Added detection for BlackBerry
144
+ * Removed Netscape checks (matches heavily with firefox & mozilla)
145
+ *
146
+ */
147
+
148
+ class Browser {
149
+ public $_agent = '';
150
+ public $_browser_name = '';
151
+ public $_version = '';
152
+ public $_platform = '';
153
+ public $_os = '';
154
+ public $_is_aol = false;
155
+ public $_is_mobile = false;
156
+ public $_is_robot = false;
157
+ public $_aol_version = '';
158
+
159
+ public $BROWSER_UNKNOWN = 'unknown';
160
+ public $VERSION_UNKNOWN = 'unknown';
161
+
162
+ public $BROWSER_OPERA = 'Opera'; // Http://www.opera.com/
163
+ public $BROWSER_OPERA_MINI = 'Opera Mini'; // Http://www.opera.com/mini/
164
+ public $BROWSER_WEBTV = 'WebTV'; // Http://www.webtv.net/pc/
165
+ public $BROWSER_IE = 'Internet Explorer'; // Http://www.microsoft.com/ie/
166
+ public $BROWSER_POCKET_IE = 'Pocket Internet Explorer'; // Http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
167
+ public $BROWSER_KONQUEROR = 'Konqueror'; // Http://www.konqueror.org/
168
+ public $BROWSER_ICAB = 'iCab'; // Http://www.icab.de/
169
+ public $BROWSER_OMNIWEB = 'OmniWeb'; // Http://www.omnigroup.com/applications/omniweb/
170
+ public $BROWSER_FIREBIRD = 'Firebird'; // Http://www.ibphoenix.com/
171
+ public $BROWSER_FIREFOX = 'Firefox'; // Http://www.mozilla.com/en-US/firefox/firefox.html
172
+ public $BROWSER_ICEWEASEL = 'Iceweasel'; // Http://www.geticeweasel.org/
173
+ public $BROWSER_SHIRETOKO = 'Shiretoko'; // Http://wiki.mozilla.org/Projects/shiretoko
174
+ public $BROWSER_MOZILLA = 'Mozilla'; // Http://www.mozilla.com/en-US/
175
+ public $BROWSER_AMAYA = 'Amaya'; // Http://www.w3.org/Amaya/
176
+ public $BROWSER_LYNX = 'Lynx'; // Http://en.wikipedia.org/wiki/Lynx
177
+ public $BROWSER_SAFARI = 'Safari'; // Http://apple.com
178
+ public $BROWSER_IPHONE = 'iPhone'; // Http://apple.com
179
+ public $BROWSER_IPOD = 'iPod'; // Http://apple.com
180
+ public $BROWSER_IPAD = 'iPad'; // Http://apple.com
181
+ public $BROWSER_CHROME = 'Chrome'; // Http://www.google.com/chrome
182
+ public $BROWSER_ANDROID = 'Android'; // Http://www.android.com/
183
+ public $BROWSER_GOOGLEBOT = 'GoogleBot'; // Http://en.wikipedia.org/wiki/Googlebot
184
+ public $BROWSER_SLURP = 'Yahoo! Slurp'; // Http://en.wikipedia.org/wiki/Yahoo!_Slurp
185
+ public $BROWSER_W3CVALIDATOR = 'W3C Validator'; // Http://validator.w3.org/
186
+ public $BROWSER_BLACKBERRY = 'BlackBerry'; // Http://www.blackberry.com/
187
+ public $BROWSER_ICECAT = 'IceCat'; // Http://en.wikipedia.org/wiki/GNU_IceCat
188
+ public $BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser'; // Http://en.wikipedia.org/wiki/Web_Browser_for_S60
189
+ public $BROWSER_NOKIA = 'Nokia Browser'; // * all other WAP-based browsers on the Nokia Platform
190
+ public $BROWSER_MSN = 'MSN Browser'; // Http://explorer.msn.com/
191
+ public $BROWSER_MSNBOT = 'MSN Bot'; // Http://search.msn.com/msnbot.htm
192
+ // Http://en.wikipedia.org/wiki/Msnbot (used for Bing as well)
193
+
194
+ public $BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator'; // Http://browser.netscape.com/ (DEPRECATED)
195
+ public $BROWSER_GALEON = 'Galeon'; // Http://galeon.sourceforge.net/ (DEPRECATED)
196
+ public $BROWSER_NETPOSITIVE = 'NetPositive'; // Http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
197
+ public $BROWSER_PHOENIX = 'Phoenix'; // Http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
198
+
199
+ public $PLATFORM_UNKNOWN = 'unknown';
200
+ public $PLATFORM_WINDOWS = 'Windows';
201
+ public $PLATFORM_WINDOWS_CE = 'Windows CE';
202
+ public $PLATFORM_APPLE = 'Apple';
203
+ public $PLATFORM_LINUX = 'Linux';
204
+ public $PLATFORM_OS2 = 'OS/2';
205
+ public $PLATFORM_BEOS = 'BeOS';
206
+ public $PLATFORM_IPHONE = 'iPhone';
207
+ public $PLATFORM_IPOD = 'iPod';
208
+ public $PLATFORM_IPAD = 'iPad';
209
+ public $PLATFORM_BLACKBERRY = 'BlackBerry';
210
+ public $PLATFORM_NOKIA = 'Nokia';
211
+ public $PLATFORM_FREEBSD = 'FreeBSD';
212
+ public $PLATFORM_OPENBSD = 'OpenBSD';
213
+ public $PLATFORM_NETBSD = 'NetBSD';
214
+ public $PLATFORM_SUNOS = 'SunOS';
215
+ public $PLATFORM_OPENSOLARIS = 'OpenSolaris';
216
+ public $PLATFORM_ANDROID = 'Android';
217
+
218
+ public $OPERATING_SYSTEM_UNKNOWN = 'unknown';
219
+
220
+ function Browser($useragent="") {
221
+ $this->reset();
222
+ if( $useragent != "" ) {
223
+ $this->setUserAgent($useragent);
224
+ }
225
+ else {
226
+ $this->determine();
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Reset all properties
232
+ */
233
+ function reset() {
234
+ $this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
235
+ $this->_browser_name = $this->BROWSER_UNKNOWN;
236
+ $this->_version = $this->VERSION_UNKNOWN;
237
+ $this->_platform = $this->PLATFORM_UNKNOWN;
238
+ $this->_os = $this->OPERATING_SYSTEM_UNKNOWN;
239
+ $this->_is_aol = false;
240
+ $this->_is_mobile = false;
241
+ $this->_is_robot = false;
242
+ $this->_aol_version = $this->VERSION_UNKNOWN;
243
+ }
244
+
245
+ /**
246
+ * Check to see if the specific browser is valid
247
+ * @param string $browserName
248
+ * @return True if the browser is the specified browser
249
+ */
250
+ function isBrowser($browserName) { return( 0 == strcasecmp($this->_browser_name, trim($browserName))); }
251
+
252
+ /**
253
+ * The name of the browser. All return types are from the class contants
254
+ * @return string Name of the browser
255
+ */
256
+ function getBrowser() { return $this->_browser_name; }
257
+ /**
258
+ * Set the name of the browser
259
+ * @param $browser The name of the Browser
260
+ */
261
+ function setBrowser($browser) { return $this->_browser_name = $browser; }
262
+ /**
263
+ * The name of the platform. All return types are from the class contants
264
+ * @return string Name of the browser
265
+ */
266
+ function getPlatform() { return $this->_platform; }
267
+ /**
268
+ * Set the name of the platform
269
+ * @param $platform The name of the Platform
270
+ */
271
+ function setPlatform($platform) { return $this->_platform = $platform; }
272
+ /**
273
+ * The version of the browser.
274
+ * @return string Version of the browser (will only contain alpha-numeric characters and a period)
275
+ */
276
+ function getVersion() { return $this->_version; }
277
+ /**
278
+ * Set the version of the browser
279
+ * @param $version The version of the Browser
280
+ */
281
+ function setVersion($version) { $this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/','',$version); }
282
+ /**
283
+ * The version of AOL.
284
+ * @return string Version of AOL (will only contain alpha-numeric characters and a period)
285
+ */
286
+ function getAolVersion() { return $this->_aol_version; }
287
+ /**
288
+ * Set the version of AOL
289
+ * @param $version The version of AOL
290
+ */
291
+ function setAolVersion($version) { $this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/','',$version); }
292
+ /**
293
+ * Is the browser from AOL?
294
+ * @return boolean True if the browser is from AOL otherwise false
295
+ */
296
+ function isAol() { return $this->_is_aol; }
297
+ /**
298
+ * Is the browser from a mobile device?
299
+ * @return boolean True if the browser is from a mobile device otherwise false
300
+ */
301
+ function isMobile() { return $this->_is_mobile; }
302
+ /**
303
+ * Is the browser from a robot (ex Slurp,GoogleBot)?
304
+ * @return boolean True if the browser is from a robot otherwise false
305
+ */
306
+ function isRobot() { return $this->_is_robot; }
307
+ /**
308
+ * Set the browser to be from AOL
309
+ * @param $isAol
310
+ */
311
+ function setAol($isAol) { $this->_is_aol = $isAol; }
312
+ /**
313
+ * Set the Browser to be mobile
314
+ * @param boolean $value is the browser a mobile brower or not
315
+ */
316
+ function setMobile($value=true) { $this->_is_mobile = $value; }
317
+ /**
318
+ * Set the Browser to be a robot
319
+ * @param boolean $value is the browser a robot or not
320
+ */
321
+ function setRobot($value=true) { $this->_is_robot = $value; }
322
+ /**
323
+ * Get the user agent value in use to determine the browser
324
+ * @return string The user agent from the HTTP header
325
+ */
326
+ function getUserAgent() { return $this->_agent; }
327
+ /**
328
+ * Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
329
+ * @param $agent_string The value for the User Agent
330
+ */
331
+ function setUserAgent($agent_string) {
332
+ $this->reset();
333
+ $this->_agent = $agent_string;
334
+ $this->determine();
335
+ }
336
+ /**
337
+ * Used to determine if the browser is actually "chromeframe"
338
+ * @since 1.7
339
+ * @return boolean True if the browser is using chromeframe
340
+ */
341
+ function isChromeFrame() {
342
+ return( strpos($this->_agent,"chromeframe") !== false );
343
+ }
344
+ /**
345
+ * Returns a formatted string with a summary of the details of the browser.
346
+ * @return string formatted string with a summary of the browser
347
+ */
348
+ function __toString() {
349
+ $text1 = $this->getUserAgent(); //grabs the UA (user agent) string
350
+ $UAline1 = substr($text1, 0, 32); //the first line we print should only be the first 32 characters of the UA string
351
+ $text2 = $this->getUserAgent();//now we grab it again and save it to a string
352
+ $towrapUA = str_replace($UAline1, '', $text2);//the rest of the printoff (other than first line) is equivolent
353
+ // To the whole string minus the part we printed off. IE
354
+ // User Agent: thefirst32charactersfromUAline1
355
+ // the rest of it is now stored in
356
+ // $text2 to be printed off
357
+ // But we need to add spaces before each line that is split other than line 1
358
+ $space = '';
359
+ for($i = 0; $i < 25; $i++) {
360
+ $space .= ' ';
361
+ }
362
+ // Now we split the remaining string of UA ($text2) into lines that are prefixed by spaces for formatting
363
+ $wordwrapped = chunk_split($towrapUA, 32, "\n $space");
364
+ return "Platform: {$this->getPlatform()} \n".
365
+ "Browser Name: {$this->getBrowser()} \n" .
366
+ "Browser Version: {$this->getVersion()} \n" .
367
+ "User Agent String: $UAline1 \n\t\t\t " .
368
+ "$wordwrapped";
369
+ }
370
+ /**
371
+ * Protected routine to calculate and determine what the browser is in use (including platform)
372
+ */
373
+ function determine() {
374
+ $this->checkPlatform();
375
+ $this->checkBrowsers();
376
+ $this->checkForAol();
377
+ }
378
+ /**
379
+ * Protected routine to determine the browser type
380
+ * @return boolean True if the browser was detected otherwise false
381
+ */
382
+ function checkBrowsers() {
383
+ return (
384
+ // Well-known, well-used
385
+ // Special Notes:
386
+ // (1) Opera must be checked before FireFox due to the odd
387
+ // user agents used in some older versions of Opera
388
+ // (2) WebTV is strapped onto Internet Explorer so we must
389
+ // check for WebTV before IE
390
+ // (3) (deprecated) Galeon is based on Firefox and needs to be
391
+ // tested before Firefox is tested
392
+ // (4) OmniWeb is based on Safari so OmniWeb check must occur
393
+ // before Safari
394
+ // (5) Netscape 9+ is based on Firefox so Netscape checks
395
+ // before FireFox are necessary
396
+ $this->checkBrowserWebTv() ||
397
+ $this->checkBrowserInternetExplorer() ||
398
+ $this->checkBrowserOpera() ||
399
+ $this->checkBrowserGaleon() ||
400
+ $this->checkBrowserNetscapeNavigator9Plus() ||
401
+ $this->checkBrowserFirefox() ||
402
+ $this->checkBrowserChrome() ||
403
+ $this->checkBrowserOmniWeb() ||
404
+
405
+ // Common mobile
406
+ $this->checkBrowserAndroid() ||
407
+ $this->checkBrowseriPad() ||
408
+ $this->checkBrowseriPod() ||
409
+ $this->checkBrowseriPhone() ||
410
+ $this->checkBrowserBlackBerry() ||
411
+ $this->checkBrowserNokia() ||
412
+
413
+ // Common bots
414
+ $this->checkBrowserGoogleBot() ||
415
+ $this->checkBrowserMSNBot() ||
416
+ $this->checkBrowserSlurp() ||
417
+
418
+ // WebKit base check (post mobile and others)
419
+ $this->checkBrowserSafari() ||
420
+
421
+ // Everyone else
422
+ $this->checkBrowserNetPositive() ||
423
+ $this->checkBrowserFirebird() ||
424
+ $this->checkBrowserKonqueror() ||
425
+ $this->checkBrowserIcab() ||
426
+ $this->checkBrowserPhoenix() ||
427
+ $this->checkBrowserAmaya() ||
428
+ $this->checkBrowserLynx() ||
429
+
430
+ $this->checkBrowserShiretoko() ||
431
+ $this->checkBrowserIceCat() ||
432
+ $this->checkBrowserW3CValidator() ||
433
+ $this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
434
+ );
435
+ }
436
+
437
+ /**
438
+ * Determine if the user is using a BlackBerry (last updated 1.7)
439
+ * @return boolean True if the browser is the BlackBerry browser otherwise false
440
+ */
441
+ function checkBrowserBlackBerry() {
442
+ if( stripos($this->_agent,'blackberry') !== false ) {
443
+ $aresult = explode("/",stristr($this->_agent,"BlackBerry"));
444
+ $aversion = explode(' ',$aresult[1]);
445
+ $this->setVersion($aversion[0]);
446
+ $this->_browser_name = $this->BROWSER_BLACKBERRY;
447
+ $this->setMobile(true);
448
+ return true;
449
+ }
450
+ return false;
451
+ }
452
+
453
+ /**
454
+ * Determine if the user is using an AOL User Agent (last updated 1.7)
455
+ * @return boolean True if the browser is from AOL otherwise false
456
+ */
457
+ function checkForAol() {
458
+ $this->setAol(false);
459
+ $this->setAolVersion($this->VERSION_UNKNOWN);
460
+
461
+ if( stripos($this->_agent,'aol') !== false ) {
462
+ $aversion = explode(' ',stristr($this->_agent, 'AOL'));
463
+ $this->setAol(true);
464
+ $this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
465
+ return true;
466
+ }
467
+ return false;
468
+ }
469
+
470
+ /**
471
+ * Determine if the browser is the GoogleBot or not (last updated 1.7)
472
+ * @return boolean True if the browser is the GoogletBot otherwise false
473
+ */
474
+ function checkBrowserGoogleBot() {
475
+ if( stripos($this->_agent,'googlebot') !== false ) {
476
+ $aresult = explode('/',stristr($this->_agent,'googlebot'));
477
+ $aversion = explode(' ',$aresult[1]);
478
+ $this->setVersion(str_replace(';','',$aversion[0]));
479
+ $this->_browser_name = $this->BROWSER_GOOGLEBOT;
480
+ $this->setRobot(true);
481
+ return true;
482
+ }
483
+ return false;
484
+ }
485
+
486
+ /**
487
+ * Determine if the browser is the MSNBot or not (last updated 1.9)
488
+ * @return boolean True if the browser is the MSNBot otherwise false
489
+ */
490
+ function checkBrowserMSNBot() {
491
+ if( stripos($this->_agent,"msnbot") !== false ) {
492
+ $aresult = explode("/",stristr($this->_agent,"msnbot"));
493
+ $aversion = explode(" ",$aresult[1]);
494
+ $this->setVersion(str_replace(";","",$aversion[0]));
495
+ $this->_browser_name = $this->BROWSER_MSNBOT;
496
+ $this->setRobot(true);
497
+ return true;
498
+ }
499
+ return false;
500
+ }
501
+
502
+ /**
503
+ * Determine if the browser is the W3C Validator or not (last updated 1.7)
504
+ * @return boolean True if the browser is the W3C Validator otherwise false
505
+ */
506
+ function checkBrowserW3CValidator() {
507
+ if( stripos($this->_agent,'W3C-checklink') !== false ) {
508
+ $aresult = explode('/',stristr($this->_agent,'W3C-checklink'));
509
+ $aversion = explode(' ',$aresult[1]);
510
+ $this->setVersion($aversion[0]);
511
+ $this->_browser_name = $this->BROWSER_W3CVALIDATOR;
512
+ return true;
513
+ }
514
+ else if( stripos($this->_agent,'W3C_Validator') !== false ) {
515
+ // Some of the Validator versions do not delineate w/ a slash - add it back in
516
+ $ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
517
+ $aresult = explode('/',stristr($ua,'W3C_Validator'));
518
+ $aversion = explode(' ',$aresult[1]);
519
+ $this->setVersion($aversion[0]);
520
+ $this->_browser_name = $this->BROWSER_W3CVALIDATOR;
521
+ return true;
522
+ }
523
+ return false;
524
+ }
525
+
526
+ /**
527
+ * Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
528
+ * @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
529
+ */
530
+ function checkBrowserSlurp() {
531
+ if( stripos($this->_agent,'slurp') !== false ) {
532
+ $aresult = explode('/',stristr($this->_agent,'Slurp'));
533
+ $aversion = explode(' ',$aresult[1]);
534
+ $this->setVersion($aversion[0]);
535
+ $this->_browser_name = $this->BROWSER_SLURP;
536
+ $this->setRobot(true);
537
+ $this->setMobile(false);
538
+ return true;
539
+ }
540
+ return false;
541
+ }
542
+
543
+ /**
544
+ * Determine if the browser is Internet Explorer or not (last updated 1.7)
545
+ * @return boolean True if the browser is Internet Explorer otherwise false
546
+ */
547
+ function checkBrowserInternetExplorer() {
548
+
549
+ // Test for v1 - v1.5 IE
550
+ if( stripos($this->_agent,'microsoft internet explorer') !== false ) {
551
+ $this->setBrowser($this->BROWSER_IE);
552
+ $this->setVersion('1.0');
553
+ $aresult = stristr($this->_agent, '/');
554
+ if( preg_match('/308|425|426|474|0b1/i', $aresult) ) {
555
+ $this->setVersion('1.5');
556
+ }
557
+ return true;
558
+ }
559
+ // Test for versions > 1.5
560
+ else if( stripos($this->_agent,'msie') !== false && stripos($this->_agent,'opera') === false ) {
561
+ // See if the browser is the odd MSN Explorer
562
+ if( stripos($this->_agent,'msnb') !== false ) {
563
+ $aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'MSN'));
564
+ $this->setBrowser( $this->BROWSER_MSN );
565
+ $this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
566
+ return true;
567
+ }
568
+ $aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'msie'));
569
+ $this->setBrowser( $this->BROWSER_IE );
570
+ $this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
571
+ return true;
572
+ }
573
+ // Test for Pocket IE
574
+ else if( stripos($this->_agent,'mspie') !== false || stripos($this->_agent,'pocket') !== false ) {
575
+ $aresult = explode(' ',stristr($this->_agent,'mspie'));
576
+ $this->setPlatform( $this->PLATFORM_WINDOWS_CE );
577
+ $this->setBrowser( $this->BROWSER_POCKET_IE );
578
+ $this->setMobile(true);
579
+
580
+ if( stripos($this->_agent,'mspie') !== false ) {
581
+ $this->setVersion($aresult[1]);
582
+ }
583
+ else {
584
+ $aversion = explode('/',$this->_agent);
585
+ $this->setVersion($aversion[1]);
586
+ }
587
+ return true;
588
+ }
589
+ return false;
590
+ }
591
+
592
+ /**
593
+ * Determine if the browser is Opera or not (last updated 1.7)
594
+ * @return boolean True if the browser is Opera otherwise false
595
+ */
596
+ function checkBrowserOpera() {
597
+ if( stripos($this->_agent,'opera mini') !== false ) {
598
+ $resultant = stristr($this->_agent, 'opera mini');
599
+ if( preg_match('/\//',$resultant) ) {
600
+ $aresult = explode('/',$resultant);
601
+ $aversion = explode(' ',$aresult[1]);
602
+ $this->setVersion($aversion[0]);
603
+ }
604
+ else {
605
+ $aversion = explode(' ',stristr($resultant,'opera mini'));
606
+ $this->setVersion($aversion[1]);
607
+ }
608
+ $this->_browser_name = $this->BROWSER_OPERA_MINI;
609
+ $this->setMobile(true);
610
+ return true;
611
+ }
612
+ else if( stripos($this->_agent,'opera') !== false ) {
613
+ $resultant = stristr($this->_agent, 'opera');
614
+ if( preg_match('/Version\/(10.*)$/',$resultant,$matches) ) {
615
+ $this->setVersion($matches[1]);
616
+ }
617
+ else if( preg_match('/\//',$resultant) ) {
618
+ $aresult = explode('/',str_replace("("," ",$resultant));
619
+ $aversion = explode(' ',$aresult[1]);
620
+ $this->setVersion($aversion[0]);
621
+ }
622
+ else {
623
+ $aversion = explode(' ',stristr($resultant,'opera'));
624
+ $this->setVersion(isset($aversion[1])?$aversion[1]:"");
625
+ }
626
+ $this->_browser_name = $this->BROWSER_OPERA;
627
+ return true;
628
+ }
629
+ return false;
630
+ }
631
+
632
+ /**
633
+ * Determine if the browser is Chrome or not (last updated 1.7)
634
+ * @return boolean True if the browser is Chrome otherwise false
635
+ */
636
+ function checkBrowserChrome() {
637
+ if( stripos($this->_agent,'Chrome') !== false ) {
638
+ $aresult = explode('/',stristr($this->_agent,'Chrome'));
639
+ $aversion = explode(' ',$aresult[1]);
640
+ $this->setVersion($aversion[0]);
641
+ $this->setBrowser($this->BROWSER_CHROME);
642
+ return true;
643
+ }
644
+ return false;
645
+ }
646
+
647
+
648
+ /**
649
+ * Determine if the browser is WebTv or not (last updated 1.7)
650
+ * @return boolean True if the browser is WebTv otherwise false
651
+ */
652
+ function checkBrowserWebTv() {
653
+ if( stripos($this->_agent,'webtv') !== false ) {
654
+ $aresult = explode('/',stristr($this->_agent,'webtv'));
655
+ $aversion = explode(' ',$aresult[1]);
656
+ $this->setVersion($aversion[0]);
657
+ $this->setBrowser($this->BROWSER_WEBTV);
658
+ return true;
659
+ }
660
+ return false;
661
+ }
662
+
663
+ /**
664
+ * Determine if the browser is NetPositive or not (last updated 1.7)
665
+ * @return boolean True if the browser is NetPositive otherwise false
666
+ */
667
+ function checkBrowserNetPositive() {
668
+ if( stripos($this->_agent,'NetPositive') !== false ) {
669
+ $aresult = explode('/',stristr($this->_agent,'NetPositive'));
670
+ $aversion = explode(' ',$aresult[1]);
671
+ $this->setVersion(str_replace(array('(',')',';'),'',$aversion[0]));
672
+ $this->setBrowser($this->BROWSER_NETPOSITIVE);
673
+ return true;
674
+ }
675
+ return false;
676
+ }
677
+
678
+ /**
679
+ * Determine if the browser is Galeon or not (last updated 1.7)
680
+ * @return boolean True if the browser is Galeon otherwise false
681
+ */
682
+ function checkBrowserGaleon() {
683
+ if( stripos($this->_agent,'galeon') !== false ) {
684
+ $aresult = explode(' ',stristr($this->_agent,'galeon'));
685
+ $aversion = explode('/',$aresult[0]);
686
+ $this->setVersion($aversion[1]);
687
+ $this->setBrowser($this->BROWSER_GALEON);
688
+ return true;
689
+ }
690
+ return false;
691
+ }
692
+
693
+ /**
694
+ * Determine if the browser is Konqueror or not (last updated 1.7)
695
+ * @return boolean True if the browser is Konqueror otherwise false
696
+ */
697
+ function checkBrowserKonqueror() {
698
+ if( stripos($this->_agent,'Konqueror') !== false ) {
699
+ $aresult = explode(' ',stristr($this->_agent,'Konqueror'));
700
+ $aversion = explode('/',$aresult[0]);
701
+ $this->setVersion($aversion[1]);
702
+ $this->setBrowser($this->BROWSER_KONQUEROR);
703
+ return true;
704
+ }
705
+ return false;
706
+ }
707
+
708
+ /**
709
+ * Determine if the browser is iCab or not (last updated 1.7)
710
+ * @return boolean True if the browser is iCab otherwise false
711
+ */
712
+ function checkBrowserIcab() {
713
+ if( stripos($this->_agent,'icab') !== false ) {
714
+ $aversion = explode(' ',stristr(str_replace('/',' ',$this->_agent),'icab'));
715
+ $this->setVersion($aversion[1]);
716
+ $this->setBrowser($this->BROWSER_ICAB);
717
+ return true;
718
+ }
719
+ return false;
720
+ }
721
+
722
+ /**
723
+ * Determine if the browser is OmniWeb or not (last updated 1.7)
724
+ * @return boolean True if the browser is OmniWeb otherwise false
725
+ */
726
+ function checkBrowserOmniWeb() {
727
+ if( stripos($this->_agent,'omniweb') !== false ) {
728
+ $aresult = explode('/',stristr($this->_agent,'omniweb'));
729
+ $aversion = explode(' ',isset($aresult[1])?$aresult[1]:"");
730
+ $this->setVersion($aversion[0]);
731
+ $this->setBrowser($this->BROWSER_OMNIWEB);
732
+ return true;
733
+ }
734
+ return false;
735
+ }
736
+
737
+ /**
738
+ * Determine if the browser is Phoenix or not (last updated 1.7)
739
+ * @return boolean True if the browser is Phoenix otherwise false
740
+ */
741
+ function checkBrowserPhoenix() {
742
+ if( stripos($this->_agent,'Phoenix') !== false ) {
743
+ $aversion = explode('/',stristr($this->_agent,'Phoenix'));
744
+ $this->setVersion($aversion[1]);
745
+ $this->setBrowser($this->BROWSER_PHOENIX);
746
+ return true;
747
+ }
748
+ return false;
749
+ }
750
+
751
+ /**
752
+ * Determine if the browser is Firebird or not (last updated 1.7)
753
+ * @return boolean True if the browser is Firebird otherwise false
754
+ */
755
+ function checkBrowserFirebird() {
756
+ if( stripos($this->_agent,'Firebird') !== false ) {
757
+ $aversion = explode('/',stristr($this->_agent,'Firebird'));
758
+ $this->setVersion($aversion[1]);
759
+ $this->setBrowser($this->BROWSER_FIREBIRD);
760
+ return true;
761
+ }
762
+ return false;
763
+ }
764
+
765
+ /**
766
+ * Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
767
+ * NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
768
+ * @return boolean True if the browser is Netscape Navigator 9+ otherwise false
769
+ */
770
+ function checkBrowserNetscapeNavigator9Plus() {
771
+ if( stripos($this->_agent,'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i',$this->_agent,$matches) ) {
772
+ $this->setVersion($matches[1]);
773
+ $this->setBrowser($this->BROWSER_NETSCAPE_NAVIGATOR);
774
+ return true;
775
+ }
776
+ else if( stripos($this->_agent,'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i',$this->_agent,$matches) ) {
777
+ $this->setVersion($matches[1]);
778
+ $this->setBrowser($this->BROWSER_NETSCAPE_NAVIGATOR);
779
+ return true;
780
+ }
781
+ return false;
782
+ }
783
+
784
+ /**
785
+ * Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
786
+ * @return boolean True if the browser is Shiretoko otherwise false
787
+ */
788
+ function checkBrowserShiretoko() {
789
+ if( stripos($this->_agent,'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i',$this->_agent,$matches) ) {
790
+ $this->setVersion($matches[1]);
791
+ $this->setBrowser($this->BROWSER_SHIRETOKO);
792
+ return true;
793
+ }
794
+ return false;
795
+ }
796
+
797
+ /**
798
+ * Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
799
+ * @return boolean True if the browser is Ice Cat otherwise false
800
+ */
801
+ function checkBrowserIceCat() {
802
+ if( stripos($this->_agent,'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i',$this->_agent,$matches) ) {
803
+ $this->setVersion($matches[1]);
804
+ $this->setBrowser($this->BROWSER_ICECAT);
805
+ return true;
806
+ }
807
+ return false;
808
+ }
809
+
810
+ /**
811
+ * Determine if the browser is Nokia or not (last updated 1.7)
812
+ * @return boolean True if the browser is Nokia otherwise false
813
+ */
814
+ function checkBrowserNokia() {
815
+ if( preg_match("/Nokia([^\/]+)\/([^ SP]+)/i",$this->_agent,$matches) ) {
816
+ $this->setVersion($matches[2]);
817
+ if( stripos($this->_agent,'Series60') !== false || strpos($this->_agent,'S60') !== false ) {
818
+ $this->setBrowser($this->BROWSER_NOKIA_S60);
819
+ }
820
+ else {
821
+ $this->setBrowser( $this->BROWSER_NOKIA );
822
+ }
823
+ $this->setMobile(true);
824
+ return true;
825
+ }
826
+ return false;
827
+ }
828
+
829
+ /**
830
+ * Determine if the browser is Firefox or not (last updated 1.7)
831
+ * @return boolean True if the browser is Firefox otherwise false
832
+ */
833
+ function checkBrowserFirefox() {
834
+ if( stripos($this->_agent,'safari') === false ) {
835
+ if( preg_match("/Firefox[\/ \(]([^ ;\)]+)/i",$this->_agent,$matches) ) {
836
+ $this->setVersion($matches[1]);
837
+ $this->setBrowser($this->BROWSER_FIREFOX);
838
+ return true;
839
+ }
840
+ else if( preg_match("/Firefox$/i",$this->_agent,$matches) ) {
841
+ $this->setVersion("");
842
+ $this->setBrowser($this->BROWSER_FIREFOX);
843
+ return true;
844
+ }
845
+ }
846
+ return false;
847
+ }
848
+
849
+ /**
850
+ * Determine if the browser is Firefox or not (last updated 1.7)
851
+ * @return boolean True if the browser is Firefox otherwise false
852
+ */
853
+ function checkBrowserIceweasel() {
854
+ if( stripos($this->_agent,'Iceweasel') !== false ) {
855
+ $aresult = explode('/',stristr($this->_agent,'Iceweasel'));
856
+ $aversion = explode(' ',$aresult[1]);
857
+ $this->setVersion($aversion[0]);
858
+ $this->setBrowser($this->BROWSER_ICEWEASEL);
859
+ return true;
860
+ }
861
+ return false;
862
+ }
863
+ /**
864
+ * Determine if the browser is Mozilla or not (last updated 1.7)
865
+ * @return boolean True if the browser is Mozilla otherwise false
866
+ */
867
+ function checkBrowserMozilla() {
868
+ if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent) && stripos($this->_agent,'netscape') === false) {
869
+ $aversion = explode(' ',stristr($this->_agent,'rv:'));
870
+ preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent,$aversion);
871
+ $this->setVersion(str_replace('rv:','',$aversion[0]));
872
+ $this->setBrowser($this->BROWSER_MOZILLA);
873
+ return true;
874
+ }
875
+ else if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i',$this->_agent) && stripos($this->_agent,'netscape') === false ) {
876
+ $aversion = explode('',stristr($this->_agent,'rv:'));
877
+ $this->setVersion(str_replace('rv:','',$aversion[0]));
878
+ $this->setBrowser($this->BROWSER_MOZILLA);
879
+ return true;
880
+ }
881
+ else if( stripos($this->_agent,'mozilla') !== false && preg_match('/mozilla\/([^ ]*)/i',$this->_agent,$matches) && stripos($this->_agent,'netscape') === false ) {
882
+ $this->setVersion($matches[1]);
883
+ $this->setBrowser($this->BROWSER_MOZILLA);
884
+ return true;
885
+ }
886
+ return false;
887
+ }
888
+
889
+ /**
890
+ * Determine if the browser is Lynx or not (last updated 1.7)
891
+ * @return boolean True if the browser is Lynx otherwise false
892
+ */
893
+ function checkBrowserLynx() {
894
+ if( stripos($this->_agent,'lynx') !== false ) {
895
+ $aresult = explode('/',stristr($this->_agent,'Lynx'));
896
+ $aversion = explode(' ',(isset($aresult[1])?$aresult[1]:""));
897
+ $this->setVersion($aversion[0]);
898
+ $this->setBrowser($this->BROWSER_LYNX);
899
+ return true;
900
+ }
901
+ return false;
902
+ }
903
+
904
+ /**
905
+ * Determine if the browser is Amaya or not (last updated 1.7)
906
+ * @return boolean True if the browser is Amaya otherwise false
907
+ */
908
+ function checkBrowserAmaya() {
909
+ if( stripos($this->_agent,'amaya') !== false ) {
910
+ $aresult = explode('/',stristr($this->_agent,'Amaya'));
911
+ $aversion = explode(' ',$aresult[1]);
912
+ $this->setVersion($aversion[0]);
913
+ $this->setBrowser($this->BROWSER_AMAYA);
914
+ return true;
915
+ }
916
+ return false;
917
+ }
918
+
919
+ /**
920
+ * Determine if the browser is Safari or not (last updated 1.7)
921
+ * @return boolean True if the browser is Safari otherwise false
922
+ */
923
+ function checkBrowserSafari() {
924
+ if( stripos($this->_agent,'Safari') !== false && stripos($this->_agent,'iPhone') === false && stripos($this->_agent,'iPod') === false ) {
925
+ $aresult = explode('/',stristr($this->_agent,'Version'));
926
+ if( isset($aresult[1]) ) {
927
+ $aversion = explode(' ',$aresult[1]);
928
+ $this->setVersion($aversion[0]);
929
+ }
930
+ else {
931
+ $this->setVersion($this->VERSION_UNKNOWN);
932
+ }
933
+ $this->setBrowser($this->BROWSER_SAFARI);
934
+ return true;
935
+ }
936
+ return false;
937
+ }
938
+
939
+ /**
940
+ * Determine if the browser is iPhone or not (last updated 1.7)
941
+ * @return boolean True if the browser is iPhone otherwise false
942
+ */
943
+ function checkBrowseriPhone() {
944
+ if( stripos($this->_agent,'iPhone') !== false ) {
945
+ $aresult = explode('/',stristr($this->_agent,'Version'));
946
+ if( isset($aresult[1]) ) {
947
+ $aversion = explode(' ',$aresult[1]);
948
+ $this->setVersion($aversion[0]);
949
+ }
950
+ else {
951
+ $this->setVersion($this->VERSION_UNKNOWN);
952
+ }
953
+ $this->setMobile(true);
954
+ $this->setBrowser($this->BROWSER_IPHONE);
955
+ return true;
956
+ }
957
+ return false;
958
+ }
959
+
960
+ /**
961
+ * Determine if the browser is iPod or not (last updated 1.7)
962
+ * @return boolean True if the browser is iPod otherwise false
963
+ */
964
+ function checkBrowseriPad() {
965
+ if( stripos($this->_agent,'iPad') !== false ) {
966
+ $aresult = explode('/',stristr($this->_agent,'Version'));
967
+ if( isset($aresult[1]) ) {
968
+ $aversion = explode(' ',$aresult[1]);
969
+ $this->setVersion($aversion[0]);
970
+ }
971
+ else {
972
+ $this->setVersion($this->VERSION_UNKNOWN);
973
+ }
974
+ $this->setMobile(true);
975
+ $this->setBrowser($this->BROWSER_IPAD);
976
+ return true;
977
+ }
978
+ return false;
979
+ }
980
+
981
+ /**
982
+ * Determine if the browser is iPod or not (last updated 1.7)
983
+ * @return boolean True if the browser is iPod otherwise false
984
+ */
985
+ function checkBrowseriPod() {
986
+ if( stripos($this->_agent,'iPod') !== false ) {
987
+ $aresult = explode('/',stristr($this->_agent,'Version'));
988
+ if( isset($aresult[1]) ) {
989
+ $aversion = explode(' ',$aresult[1]);
990
+ $this->setVersion($aversion[0]);
991
+ }
992
+ else {
993
+ $this->setVersion($this->VERSION_UNKNOWN);
994
+ }
995
+ $this->setMobile(true);
996
+ $this->setBrowser($this->BROWSER_IPOD);
997
+ return true;
998
+ }
999
+ return false;
1000
+ }
1001
+
1002
+ /**
1003
+ * Determine if the browser is Android or not (last updated 1.7)
1004
+ * @return boolean True if the browser is Android otherwise false
1005
+ */
1006
+ function checkBrowserAndroid() {
1007
+ if( stripos($this->_agent,'Android') !== false ) {
1008
+ $aresult = explode(' ',stristr($this->_agent,'Android'));
1009
+ if( isset($aresult[1]) ) {
1010
+ $aversion = explode(' ',$aresult[1]);
1011
+ $this->setVersion($aversion[0]);
1012
+ }
1013
+ else {
1014
+ $this->setVersion($this->VERSION_UNKNOWN);
1015
+ }
1016
+ $this->setMobile(true);
1017
+ $this->setBrowser($this->BROWSER_ANDROID);
1018
+ return true;
1019
+ }
1020
+ return false;
1021
+ }
1022
+
1023
+ /**
1024
+ * Determine the user's platform (last updated 1.7)
1025
+ */
1026
+ function checkPlatform() {
1027
+ if( stripos($this->_agent, 'windows') !== false ) {
1028
+ $this->_platform = $this->PLATFORM_WINDOWS;
1029
+ }
1030
+ else if( stripos($this->_agent, 'iPad') !== false ) {
1031
+ $this->_platform = $this->PLATFORM_IPAD;
1032
+ }
1033
+ else if( stripos($this->_agent, 'iPod') !== false ) {
1034
+ $this->_platform = $this->PLATFORM_IPOD;
1035
+ }
1036
+ else if( stripos($this->_agent, 'iPhone') !== false ) {
1037
+ $this->_platform = $this->PLATFORM_IPHONE;
1038
+ }
1039
+ elseif( stripos($this->_agent, 'mac') !== false ) {
1040
+ $this->_platform = $this->PLATFORM_APPLE;
1041
+ }
1042
+ elseif( stripos($this->_agent, 'android') !== false ) {
1043
+ $this->_platform = $this->PLATFORM_ANDROID;
1044
+ }
1045
+ elseif( stripos($this->_agent, 'linux') !== false ) {
1046
+ $this->_platform = $this->PLATFORM_LINUX;
1047
+ }
1048
+ else if( stripos($this->_agent, 'Nokia') !== false ) {
1049
+ $this->_platform = $this->PLATFORM_NOKIA;
1050
+ }
1051
+ else if( stripos($this->_agent, 'BlackBerry') !== false ) {
1052
+ $this->_platform = $this->PLATFORM_BLACKBERRY;
1053
+ }
1054
+ elseif( stripos($this->_agent,'FreeBSD') !== false ) {
1055
+ $this->_platform = $this->PLATFORM_FREEBSD;
1056
+ }
1057
+ elseif( stripos($this->_agent,'OpenBSD') !== false ) {
1058
+ $this->_platform = $this->PLATFORM_OPENBSD;
1059
+ }
1060
+ elseif( stripos($this->_agent,'NetBSD') !== false ) {
1061
+ $this->_platform = $this->PLATFORM_NETBSD;
1062
+ }
1063
+ elseif( stripos($this->_agent, 'OpenSolaris') !== false ) {
1064
+ $this->_platform = $this->PLATFORM_OPENSOLARIS;
1065
+ }
1066
+ elseif( stripos($this->_agent, 'SunOS') !== false ) {
1067
+ $this->_platform = $this->PLATFORM_SUNOS;
1068
+ }
1069
+ elseif( stripos($this->_agent, 'OS\/2') !== false ) {
1070
+ $this->_platform = $this->PLATFORM_OS2;
1071
+ }
1072
+ elseif( stripos($this->_agent, 'BeOS') !== false ) {
1073
+ $this->_platform = $this->PLATFORM_BEOS;
1074
+ }
1075
+ elseif( stripos($this->_agent, 'win') !== false ) {
1076
+ $this->_platform = $this->PLATFORM_WINDOWS;
1077
+ }
1078
+
1079
+ }
1080
+ }
1081
+
1082
+ ?>
includes/misc-functions.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPRSS Let To Num
4
+ *
5
+ * Does Size Conversions
6
+ *
7
+ * @since 3.1
8
+ * @author Chris Christoff
9
+ * @return $ret
10
+ */
11
+ function wprss_let_to_num( $v ) {
12
+ $l = substr( $v, -1 );
13
+ $ret = substr( $v, 0, -1 );
14
+
15
+ switch ( strtoupper( $l ) ) {
16
+ case 'P':
17
+ $ret *= 1024;
18
+ case 'T':
19
+ $ret *= 1024;
20
+ case 'G':
21
+ $ret *= 1024;
22
+ case 'M':
23
+ $ret *= 1024;
24
+ case 'K':
25
+ $ret *= 1024;
26
+ break;
27
+ }
28
+
29
+ return $ret;
30
+ }
31
+
32
+
33
+
34
+
35
+ /**
36
+ * An enhanced version of WP's media_sideload_image function.
37
+ *
38
+ * If media_sideload_image fails, the file is downloaded manually
39
+ * as an image, inserted as an attachment, and attached to the post.
40
+ *
41
+ * @since 3.5.1
42
+ */
43
+ function wprss_media_sideload_image( $file, $post_id, $desc = null ) {
44
+ try {
45
+
46
+ if ( ! empty( $file ) ) {
47
+
48
+ // Download file to temp location
49
+ $tmp = download_url( $file );
50
+
51
+ // Set variables for storage
52
+ // fix file filename for query strings
53
+ preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
54
+
55
+ if ( count( $matches ) > 0 ) {
56
+ $file_array['name'] = basename( $matches[0] );
57
+ }
58
+ else {
59
+ preg_match( '/[\/\?\=\&]([^\/\?\=\&]*)[\?]*$/i', $file, $matches2 );
60
+ if ( count( $matches2 ) > 1 ) {
61
+ $file_array['name'] = $matches2[1] . '.png';
62
+ } else {
63
+ @unlink( $tmp );
64
+ return "<img src='$file' alt='' />";
65
+ }
66
+ }
67
+ $file_array['tmp_name'] = $tmp;
68
+
69
+ // If error storing temporarily, unlink
70
+ if ( is_wp_error( $tmp ) ) {
71
+ @unlink( $file_array['tmp_name'] );
72
+ $file_array['tmp_name'] = '';
73
+ }
74
+
75
+ // do the validation and storage stuff
76
+ $id = media_handle_sideload( $file_array, $post_id, $desc );
77
+ // If error storing permanently, unlink
78
+ if ( is_wp_error($id) ) {
79
+ @unlink( $file_array['tmp_name'] );
80
+ return "<img src='$file' alt='' />";
81
+ }
82
+
83
+ $src = wp_get_attachment_url( $id );
84
+ }
85
+
86
+ // Finally check to make sure the file has been saved, then return the html
87
+ if ( ! empty( $src ) ) {
88
+ $alt = isset( $desc )? esc_attr($desc) : '';
89
+ $html = "<img src='$src' alt='$alt' />";
90
+ return $html;
91
+ }
92
+
93
+ }
94
+ catch( Exception $e ) {
95
+ return "<img src='$file' alt='' />";
96
+ }
97
+ }
includes/opml-importer.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Define the WPRSS OPML Importer to set up the Import OPML Page
5
+ * and parse uploaded OPML files and import them into WPRSS'
6
+ * custom post types.
7
+ *
8
+ * @since 3.3
9
+ * @package WPRSSAggregator
10
+ */
11
+
12
+
13
+
14
+ /*
15
+ * Check if the WP_Importer Class is already loaded.
16
+ * If not, load it.
17
+ */
18
+ if ( !class_exists( 'WP_Importer' ) ) {
19
+ $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
20
+ if ( file_exists( $class_wp_importer ) )
21
+ require $class_wp_importer;
22
+ }
23
+
24
+ /**
25
+ * WPRSS_OPML_Importer Class handles the OPML Import Page and
26
+ * OPML file upload. It also constructs a WPRSS_OPML object
27
+ * for the uploaded file, which parses the file, and then
28
+ * imports it into WPRSS' custom post types.
29
+ *
30
+ * @since 3.3
31
+ */
32
+ class WPRSS_OPML_Importer extends WP_Importer {
33
+
34
+ /**
35
+ * The static Singleton Instance of the importer
36
+ */
37
+ public static $singleton;
38
+
39
+ /**
40
+ * The ID of the uploaded file to import
41
+ */
42
+ private $id;
43
+
44
+
45
+ /**
46
+ * Constructor: Prepares the Importer
47
+ */
48
+ public function __contruct() {
49
+ parent::__contruct();
50
+ }
51
+
52
+
53
+
54
+ /**
55
+ * Shows The Import Page and import form for step 1.
56
+ * Calls the parsing and importing function for step 2.
57
+ *
58
+ * @since 3.3
59
+ * @return void
60
+ */
61
+ public function opml_import() {
62
+ // Show the Icon and Title
63
+ echo '<div class="wrap">';
64
+ screen_icon();
65
+ echo '<h2>Import OPML</h2>';
66
+
67
+ // Get the current step from URL query string
68
+ $step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step'];
69
+
70
+ // Check the current step
71
+ switch ( $step ) {
72
+ default :
73
+ case 0 :
74
+ // Show the Import Message and the import upload form
75
+ echo '<p>' . __( 'Howdy! Import your feeds here from an OPML (.xml) export file.', 'wprss' ) . '</p>';
76
+ echo '<p>' . __( "Click the button below, choose your file, and click 'Upload'.", 'wprss' ) . '</p>';
77
+ echo '<p>' . __( 'We will take care of the rest.', 'wprss' ) . '</p>';
78
+
79
+ // Show an import upload form that submits to the same page, with GET parameter step=1
80
+ wp_import_upload_form( 'admin.php?import=wprss_opml_importer&amp;step=1' );
81
+ break;
82
+
83
+ case 1:
84
+ // Check referer
85
+ check_admin_referer( 'import-upload' );
86
+ // If the handle_upload function returns true
87
+ if ( $this->handle_upload() ) {
88
+ // Get the uploaded file
89
+ $file = get_attached_file( $this->id );
90
+ set_time_limit(0);
91
+ // Parse the File and Import the feeds
92
+ $this->parse_and_import( $file );
93
+ }
94
+ break;
95
+ }
96
+
97
+ echo '</div>';
98
+ }
99
+
100
+
101
+
102
+ private function handle_upload() {
103
+ // Get the upload file
104
+ $file = wp_import_handle_upload();
105
+
106
+ // If the 'error' property is set, show the error message and return FALSE
107
+ if ( isset( $file['error'] ) ) {
108
+ echo '<p><strong>' . __( 'Sorry, an error has been encountered.', 'wprss' ) . '</strong><br />';
109
+ echo esc_html( $file['error'] ) . '</p>';
110
+ return false;
111
+ // If the file does not exist, then show the error message and return FALSE
112
+ } else if ( ! file_exists( $file['file'] ) ) {
113
+ echo '<p><strong>' . __( 'Sorry, it seems your uploaded file has been misplaced!', 'wprss' ) . '</strong><br />';
114
+ echo __( 'The uploaded file could not be found at ', 'wprss') . '<code>' . esc_html( $file['file'] ) . '</code>';
115
+ echo __( 'It is likely that this was caused by a permissions problem.' , 'wprss' );
116
+ echo '</p>';
117
+ return false;
118
+ }
119
+
120
+
121
+ $this->id = (int) $file['id'];
122
+ return true;
123
+ }
124
+
125
+
126
+ /**
127
+ * Imports the give <outline> OPML element as a wprss_feed
128
+ *
129
+ * @since 3.3
130
+ * @param $outline The outline OPML element
131
+ */
132
+ private function import_opml_feed( $outline ) {
133
+ // Create an associative array, with the feed's properties
134
+ $feed = array(
135
+ 'post_title' => $outline['title'],
136
+ 'post_content' => '',
137
+ 'post_status' => 'publish',
138
+ 'post_type' => 'wprss_feed'
139
+ );
140
+ // Insert the post into the database and store the inserted ID
141
+ $inserted_id = wp_insert_post( $feed );
142
+ // Update the post's meta
143
+ update_post_meta( $inserted_id, 'wprss_url', $outline['xmlUrl'] );
144
+ // Return inserted ID
145
+ return $inserted_id;
146
+ }
147
+
148
+
149
+ /**
150
+ * Attempts to parse the given file as an OPML construct, and
151
+ * import each found feed.
152
+ *
153
+ * @since 3.3
154
+ * @param file The OPML file to parse and import
155
+ * @return void
156
+ * @todo Use the parsed $opml object to import the feeds AND remove var_dump
157
+ */
158
+ private function parse_and_import( $file ) {
159
+ try {
160
+ $opml = new WPRSS_OPML( $file );
161
+
162
+ // Show Success Message
163
+ echo '<h3>Feeds were imported successfully!</h3>';
164
+
165
+ // Show imported feeds
166
+ ?>
167
+ <table class="widefat">
168
+ <thead>
169
+ <tr>
170
+ <th>ID</th>
171
+ <th>Title</th>
172
+ <th>URL</th>
173
+ </tr>
174
+ </thead>
175
+
176
+ <tbody>
177
+ <?php
178
+ foreach ( $opml->body as $opml_feed ) :
179
+ $inserted_id = $this->import_opml_feed( $opml_feed );
180
+ ?>
181
+ <tr>
182
+ <td><?php echo $inserted_id; ?></td>
183
+ <td><?php echo $opml_feed['title']; ?> </td>
184
+ <td><?php echo $opml_feed['xmlUrl']; ?></td>
185
+ </tr>
186
+ <?php endforeach; ?>
187
+ </tbody>
188
+
189
+ <tfoot>
190
+ <tr>
191
+ <th>ID</th>
192
+ <th>Title</th>
193
+ <th>URL</th>
194
+ </tr>
195
+ </tfoot>
196
+
197
+ </table>
198
+ <?php
199
+
200
+ } catch (Exception $e) {
201
+ // Show Error Message
202
+ echo '<div class="error"><p>' . $e->getMessage() . '</p></div>';
203
+ }
204
+ }
205
+
206
+ }
207
+
208
+
209
+ /* Initialize the Singleton Instance of the Importer */
210
+ WPRSS_OPML_Importer::$singleton = new WPRSS_OPML_Importer();
211
+
212
+
213
+
214
+ add_action( 'admin_init', 'wprss_opml_register_import' );
215
+ /**
216
+ * Initializes and registers the OPML Importer
217
+ * @since 3.3
218
+ */
219
+ function wprss_opml_register_import() {
220
+
221
+ register_importer(
222
+ 'wprss_opml_importer',
223
+ 'WP RSS OPML',
224
+ 'Import Feeds from an OPML file into WP RSS Aggregator',
225
+ array( WPRSS_OPML_Importer::$singleton ,'opml_import' )
226
+ );
227
+
228
+ }
229
+
230
+
231
+ ?>
includes/opml.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The WPRSS_OPML Class represents an OPML document.
5
+ * It is constructed using a file, which it parses upon creation.
6
+ *
7
+ * @since 3.3
8
+ * @package WPRSSAggregator
9
+ */
10
+ class WPRSS_OPML {
11
+
12
+
13
+ public $file;
14
+ public $head;
15
+ public $body;
16
+
17
+ /**
18
+ * Constructor: Parses the given XML file as an OPML
19
+ *
20
+ * @since 3.3
21
+ * @param $file The file to be parsed into a WPRSS_OPML object
22
+ */
23
+ public function __construct( $file ) {
24
+ // Initialize Properties
25
+ $this->file = $file;
26
+ $this->head = array();
27
+ $this->body = array();
28
+ // Begin Parsing
29
+ try {
30
+ // Wrap file data in a SimpleXMLElement
31
+ $xml = simplexml_load_file( $this->file );
32
+
33
+ // Check if the head section exists before parsing it
34
+ if ( $xml->head )
35
+ $this->head = WPRSS_OPML::parse_opml_head( $xml->head->children() );
36
+ // Check if the body section exists before parsing it
37
+ if ( $xml->body )
38
+ $this->body = WPRSS_OPML::parse_opml_body_element( $xml->body->outline );
39
+
40
+ } catch (Exception $e) {
41
+ // If an exception is caught. Throw an error message
42
+ throw new Exception( __( 'An error occured: The file might not be a valid OPML file or is corrrupt. ', 'wprss' ), 1);
43
+ }
44
+ }
45
+
46
+
47
+ /**
48
+ * Parses the given variable as an OPML head section
49
+ *
50
+ * @since 3.3
51
+ * @param $head The head section of an OPML file ( SimpleXMLElement )
52
+ * @return array An associative array containing SimpleXMLElements for each tag in the given head section.
53
+ */
54
+ private static function parse_opml_head( $head ) {
55
+ $parsed_data = array();
56
+
57
+ foreach ( $head as $property ) {
58
+ $parsed_data[ $property->getName() ] = $property;
59
+ }
60
+
61
+ return $parsed_data;
62
+ }
63
+
64
+
65
+ /**
66
+ * Iterates through the elements given OPML/XML data and parses
67
+ * each element, and recurses where necessary, into an associative
68
+ * array that mimics OPML structure.
69
+ * @since 1.0
70
+ * @return array The Parsed OPML as an associative array
71
+ */
72
+ private static function parse_opml_body_element( $element ) {
73
+ $parsed_data = array();
74
+
75
+ // Iterates through each child element in the given element
76
+ foreach ( $element as $child_element ) {
77
+
78
+ // If child element has type attribute set to 'rss' or has the 'xmlUrl' attribute
79
+ if ( $child_element['type'] === 'rss' || isset( $child_element['xmlUrl'] ) ) {
80
+ // Parse the child element and add it to the parsed data array
81
+ $parsed_data[] = WPRSS_OPML::SimpleXMLElement_to_OPMLElement( $child_element );
82
+ }
83
+ // Otherwise, if the child element has children 'outline' elements
84
+ elseif ( $child_element->outline ) {
85
+ // Recurse using this child element as parameter, and add the result to the parsed data array
86
+ $parsed_data[ (string) $child_element['text'] ] = WPRSS_OPML::parse_opml_body_element( $child_element->outline );
87
+ }
88
+
89
+ }
90
+
91
+ return $parsed_data;
92
+ }
93
+
94
+
95
+ /**
96
+ * Parses a SimpleXMLElement Object into an OPML element compliant
97
+ * associative array.
98
+ * @since 1.0
99
+ * @return array An array in OPML element format
100
+ */
101
+ private static function SimpleXMLElement_to_OPMLElement( $element ) {
102
+ // Copy attribute data from $element to a new associative array
103
+ $result = array(
104
+ 'text' => (string) $element['text'],
105
+ 'title' => (string) $element['title'],
106
+ 'htmlUrl' => (string) $element['htmlUrl'],
107
+ 'xmlUrl' => (string) $element['xmlUrl'],
108
+ 'description' => (string) $element['description']
109
+ );
110
+
111
+ /*
112
+ * Check for existence of htmlUrl and xmlUrl.
113
+ * If not found, use lowercased attribute names.
114
+ */
115
+ if ( !isset( $element['htmlUrl'] ) )
116
+ $result['htmlUrl'] = $element['htmlurl'];
117
+ if ( !isset( $element['xmlUrl'] ) )
118
+ $result['xmlUrl'] = $element['xmlurl'];
119
+
120
+ // Return the result OPML Element
121
+ return $result;
122
+ }
123
+
124
+ }
125
+
126
+ ?>
includes/roles-capabilities.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Contains all roles and capabilities functions
5
+ *
6
+ * @package WPRSSAggregator
7
+ */
8
+
9
+
10
+ add_action('init', 'wprss_add_caps');
11
+ /**
12
+ * Add feed aggregator-specific capabilities
13
+ *
14
+ * @since 3.3
15
+ */
16
+ function wprss_add_caps() {
17
+ global $wp_roles;
18
+
19
+ if ( class_exists('WP_Roles') )
20
+ if ( ! isset( $wp_roles ) )
21
+ $wp_roles = new WP_Roles();
22
+
23
+ if ( is_object( $wp_roles ) ) {
24
+
25
+ $wp_roles->add_cap( 'administrator', 'manage_feed_settings' );
26
+ $wp_roles->add_cap( 'editor', 'manage_feed_settings' );
27
+
28
+ // Add the main post type capabilities
29
+ $capabilities = wprss_get_core_caps();
30
+ foreach ( $capabilities as $cap_group ) {
31
+ foreach ( $cap_group as $cap ) {
32
+ $wp_roles->add_cap( 'administrator', $cap );
33
+ $wp_roles->add_cap( 'editor', $cap );
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+
40
+ /**
41
+ * Gets the core post type capabilties
42
+ *
43
+ * @since 3.3
44
+ */
45
+ function wprss_get_core_caps() {
46
+ $capabilities = array();
47
+
48
+ $capability_types = array( 'feed', 'feed_source' );
49
+
50
+ foreach ( $capability_types as $capability_type ) {
51
+ $capabilities[ $capability_type ] = array(
52
+ // Post type
53
+ "edit_{$capability_type}",
54
+ "read_{$capability_type}",
55
+ "delete_{$capability_type}",
56
+ "edit_{$capability_type}s",
57
+ "edit_others_{$capability_type}s",
58
+ "publish_{$capability_type}s",
59
+ "read_private_{$capability_type}s",
60
+ "delete_{$capability_type}s",
61
+ "delete_private_{$capability_type}s",
62
+ "delete_published_{$capability_type}s",
63
+ "delete_others_{$capability_type}s",
64
+ "edit_private_{$capability_type}s",
65
+ "edit_published_{$capability_type}s",
66
+
67
+ // Terms
68
+ "manage_{$capability_type}_terms",
69
+ "edit_{$capability_type}_terms",
70
+ "delete_{$capability_type}_terms",
71
+ "assign_{$capability_type}_terms"
72
+ );
73
+ }
74
+
75
+ return $capabilities;
76
+ }
77
+
78
+
79
+ /**
80
+ * Remove core post type capabilities (called on uninstall)
81
+ *
82
+ * @since 3.3
83
+ * @return void
84
+ */
85
+ function wprss_remove_caps() {
86
+ if ( class_exists( 'WP_Roles' ) )
87
+ if ( ! isset( $wp_roles ) )
88
+ $wp_roles = new WP_Roles();
89
+
90
+ if ( is_object( $wp_roles ) ) {
91
+
92
+ /** Site Administrator Capabilities */
93
+ $wp_roles->remove_cap( 'administrator', 'manage_feed_settings' );
94
+ /** Editor Capabilities */
95
+ $wp_roles->remove_cap( 'editor', 'manage_feed_settings' );
96
+
97
+ /** Remove the Main Post Type Capabilities */
98
+ $capabilities = $this->get_core_caps();
99
+
100
+ foreach ( $capabilities as $cap_group ) {
101
+ foreach ( $cap_group as $cap ) {
102
+ $wp_roles->remove_cap( 'administrator', $cap );
103
+ $wp_roles->remove_cap( 'editor', $cap );
104
+ }
105
+ }
106
+ }
107
+ }
includes/scripts.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Scripts
4
+ *
5
+ * @package WPRSSAggregator
6
+ */
7
+
8
+
9
+ add_action( 'admin_enqueue_scripts', 'wprss_admin_scripts_styles' );
10
+ /**
11
+ * Insert required scripts, styles and filters on the admin side
12
+ *
13
+ * @since 2.0
14
+ */
15
+ function wprss_admin_scripts_styles() {
16
+
17
+ // Only load scripts if we are on this plugin's options or settings pages (admin)
18
+ if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'wprss-aggregator' || $_GET['page'] == 'wprss-aggregator-settings'
19
+ || $_GET['page'] == 'wprss-import-export-settings' || $_GET['page'] == 'wprss-debugging' ) ) {
20
+ wp_enqueue_style( 'styles', WPRSS_CSS . 'admin-styles.css' );
21
+ }
22
+
23
+ $screen = get_current_screen();
24
+
25
+ wp_enqueue_script( 'admin-addon-ajax', WPRSS_JS .'admin-addon-ajax.js', array('jquery') );
26
+ wp_enqueue_style( 'admin-editor-styles', WPRSS_CSS . 'admin-editor.css' );
27
+
28
+ if ( ( 'post' === $screen->base || 'edit' === $screen->base || 'wprss-debugging' === $screen->base ) &&
29
+ ( 'wprss_feed' === $screen->post_type || 'wprss_feed_item' === $screen->post_type ) || ( isset( $_GET['page'] ) &&
30
+ ( $_GET['page'] == 'wprss-aggregator-settings' ) ) ) {
31
+ wp_enqueue_style( 'admin-styles', WPRSS_CSS . 'admin-styles.css' );
32
+ wp_enqueue_script( 'admin-custom', WPRSS_JS .'admin-custom.js', array('jquery') );
33
+ if ( 'post' === $screen->base && 'wprss_feed' === $screen->post_type ) {
34
+ // Change text on post screen from 'Enter title here' to 'Enter feed name here'
35
+ add_filter( 'enter_title_here', 'wprss_change_title_text' );
36
+ }
37
+ }
38
+
39
+ else if ( 'dashboard_page_wprss-welcome' === $screen->base ) {
40
+ wp_enqueue_style( 'admin-styles', WPRSS_CSS . 'admin-styles.css' );
41
+ }
42
+
43
+ do_action( 'wprss_admin_scripts_styles' );
44
+ } // end wprss_admin_scripts_styles
45
+
46
+
47
+ add_action( 'wp_enqueue_scripts', 'wprss_load_scripts' );
48
+ /**
49
+ * Enqueues the required scripts.
50
+ *
51
+ * @since 3.0
52
+ */
53
+ function wprss_load_scripts() {
54
+ wp_enqueue_script( 'jquery.colorbox-min', WPRSS_JS . 'jquery.colorbox-min.js', array( 'jquery' ) );
55
+ wp_enqueue_script( 'custom', WPRSS_JS . 'custom.js', array( 'jquery', 'jquery.colorbox-min' ) );
56
+ do_action( 'wprss_register_scripts' );
57
+ } // end wprss_head_scripts_styles
58
+
59
+
60
+ /**
61
+ * Returns the path to the WPRSS templates directory
62
+ *
63
+ * @since 3.0
64
+ * @return string
65
+ */
66
+ function wprss_get_templates_dir() {
67
+ return WPRSS_DIR . 'templates';
68
+ }
69
+
70
+
71
+ /**
72
+ * Returns the URL to the WPRSS templates directory
73
+ *
74
+ * @since 3.0
75
+ * @return string
76
+ */
77
+ function wprss_get_templates_uri() {
78
+ return WPRSS_URI . 'templates';
79
+ }
80
+
81
+
82
+ add_action( 'wp_enqueue_scripts', 'wprss_register_styles' );
83
+ /**
84
+ * Register front end CSS styling files
85
+ * Inspiration from Easy Digital Downloads
86
+ *
87
+ * @since 3.0
88
+ */
89
+ function wprss_register_styles() {
90
+
91
+ $general_settings = get_option( 'wprss_settings_general' );
92
+
93
+ if( $general_settings['styles_disable'] == 1 )
94
+ return;
95
+ wp_enqueue_style( 'colorbox', WPRSS_CSS . 'colorbox.css', array(), '1.4.1' );
96
+ wp_enqueue_style( 'styles', WPRSS_CSS . 'styles.css', array(), '' );
97
+
98
+ /* If using DISABLE CSS option:
99
+ global $edd_options;
100
+
101
+ if( isset( $edd_options['disable_styles'] ) )
102
+ return;
103
+
104
+ */
105
+
106
+ /* $file = 'wprss.css';
107
+
108
+ // Check child theme first
109
+ if ( file_exists( trailingslashit( get_stylesheet_directory() ) . 'wprss_templates/' . $file ) ) {
110
+ $url = trailingslashit( get_stylesheet_directory_uri() ) . 'wprss_templates/' . $file;
111
+
112
+ // Check parent theme next
113
+ } elseif ( file_exists( trailingslashit( get_template_directory() ) . 'wprss_templates/' . $file ) ) {
114
+ $url = trailingslashit( get_template_directory_uri() ) . 'wprss_templates/' . $file;
115
+
116
+ // Check theme compatibility last
117
+ } elseif ( file_exists( trailingslashit( wprss_get_templates_dir() ) . $file ) ) {
118
+ $url = trailingslashit( wprss_get_templates_uri() ) . $file;
119
+ }
120
+
121
+ wp_enqueue_style( 'wprss-styles', $url, WPRSS_VERSION );*/
122
+ }
includes/shortcodes.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Set up shortcodes and call the main function for output
4
+ *
5
+ * @since 1.0
6
+ */
7
+ function wprss_shortcode( $atts ) {
8
+ if ( !empty ($atts) ) {
9
+ foreach ( $atts as $key => &$val ) {
10
+ $val = html_entity_decode($val);
11
+ }
12
+ }
13
+ ob_start(); //start an output buffer to output of the following function
14
+ wprss_display_feed_items( $atts );
15
+ return ob_get_clean(); //return the current buffer and clear it
16
+ }
17
+
18
+ // Register shortcodes
19
+ add_shortcode( 'wp_rss_aggregator', 'wprss_shortcode');
20
+ add_shortcode( 'wp-rss-aggregator', 'wprss_shortcode');
includes/system-info.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * System information
4
+ *
5
+ * @package WPRSSAggregator
6
+ * @subpackage Includes
7
+ * @since 3.1
8
+ * @author Jean Galea <info@jeangalea.com>
9
+ * @copyright Copyright(c) 2012-2013, Jean Galea. Adapted from Easy Digital Downloads by Pippin Williamson
10
+ * @link http://www.wpmayor.com
11
+ * @license http://www.gnu.org/licenses/gpl.html
12
+ */
13
+
14
+ /**
15
+ * Generate the system information
16
+ *
17
+ * @since 3.1
18
+ */
19
+ function wprss_system_info() {
20
+ global $wpdb;
21
+
22
+ if ( ! class_exists( 'Browser' ) )
23
+ require_once WPRSS_DIR . 'includes/libraries/browser.php';
24
+
25
+ $browser = new Browser();
26
+ ?>
27
+ <h3><?php _e( 'System Information', 'wprss' ) ?></h3>
28
+ <form action="<?php echo esc_url( admin_url( 'edit.php?post_type=wprss_feed&page=wprss-debugging' ) ); ?>" method="post">
29
+ <textarea readonly="readonly" onclick="this.focus();this.select()" id="system-info-textarea" name="wprss-sysinfo" title="<?php _e( 'To copy the system info, click below then press Ctrl + C (PC) or Cmd + C (Mac).', 'wprss' ); ?>">
30
+ ### Begin System Info ###
31
+
32
+ ## Please include this information when posting support requests ##
33
+
34
+ Multi-site: <?php echo is_multisite() ? 'Yes' . "\n" : 'No' . "\n" ?>
35
+
36
+ SITE_URL: <?php echo site_url() . "\n"; ?>
37
+ HOME_URL: <?php echo home_url() . "\n"; ?>
38
+
39
+ Plugin Version: <?php echo WPRSS_VERSION . "\n"; ?>
40
+ WordPress Version: <?php echo get_bloginfo( 'version' ) . "\n"; ?>
41
+
42
+ <?php echo $browser ; ?>
43
+
44
+ PHP Version: <?php echo PHP_VERSION . "\n"; ?>
45
+ MySQL Version: <?php echo mysql_get_server_info() . "\n"; ?>
46
+ Web Server Info: <?php echo $_SERVER['SERVER_SOFTWARE'] . "\n"; ?>
47
+
48
+ PHP Safe Mode: <?php echo ini_get( 'safe_mode' ) ? "Yes" : "No\n"; ?>
49
+ PHP Memory Limit: <?php echo ini_get( 'memory_limit' ) . "\n"; ?>
50
+ PHP Post Max Size: <?php echo ini_get( 'post_max_size' ) . "\n"; ?>
51
+ PHP Time Limit: <?php echo ini_get( 'max_execution_time' ) . "\n"; ?>
52
+
53
+ WP_DEBUG: <?php echo defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' . "\n" : 'Disabled' . "\n" : 'Not set' . "\n" ?>
54
+
55
+ WP Table Prefix: <?php echo "Length: ". strlen( $wpdb->prefix ); echo " Status:"; if ( strlen( $wpdb->prefix )>16 ) {echo " ERROR: Too Long";} else {echo " Acceptable";} echo "\n"; ?>
56
+
57
+ Show On Front: <?php echo get_option( 'show_on_front' ) . "\n" ?>
58
+ Page On Front: <?php $id = get_option( 'page_on_front' ); echo get_the_title( $id ) . ' #' . $id . "\n" ?>
59
+ Page For Posts: <?php $id = get_option( 'page_on_front' ); echo get_the_title( $id ) . ' #' . $id . "\n" ?>
60
+
61
+ Session: <?php echo isset( $_SESSION ) ? 'Enabled' : 'Disabled'; ?><?php echo "\n"; ?>
62
+ Session Name: <?php echo esc_html( ini_get( 'session.name' ) ); ?><?php echo "\n"; ?>
63
+ Cookie Path: <?php echo esc_html( ini_get( 'session.cookie_path' ) ); ?><?php echo "\n"; ?>
64
+ Save Path: <?php echo esc_html( ini_get( 'session.save_path' ) ); ?><?php echo "\n"; ?>
65
+ Use Cookies: <?php echo ini_get( 'session.use_cookies' ) ? 'On' : 'Off'; ?><?php echo "\n"; ?>
66
+ Use Only Cookies: <?php echo ini_get( 'session.use_only_cookies' ) ? 'On' : 'Off'; ?><?php echo "\n"; ?>
67
+
68
+ UPLOAD_MAX_FILESIZE: <?php if ( function_exists( 'phpversion' ) ) echo ( wprss_let_to_num( ini_get( 'upload_max_filesize' ) )/( 1024*1024 ) )."MB"; ?><?php echo "\n"; ?>
69
+ POST_MAX_SIZE: <?php if ( function_exists( 'phpversion' ) ) echo ( wprss_let_to_num( ini_get( 'post_max_size' ) )/( 1024*1024 ) )."MB"; ?><?php echo "\n"; ?>
70
+ WordPress Memory Limit: <?php echo ( wprss_let_to_num( WP_MEMORY_LIMIT )/( 1024*1024 ) )."MB"; ?><?php echo "\n"; ?>
71
+ DISPLAY ERRORS: <?php echo ( ini_get( 'display_errors' ) ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A'; ?><?php echo "\n"; ?>
72
+ FSOCKOPEN: <?php echo ( function_exists( 'fsockopen' ) ) ? __( 'Your server supports fsockopen.', 'wprss' ) : __( 'Your server does not support fsockopen.', 'wprss' ); ?><?php echo "\n"; ?>
73
+
74
+ ACTIVE PLUGINS:
75
+
76
+ <?php
77
+ $plugins = get_plugins();
78
+ $active_plugins = get_option( 'active_plugins', array() );
79
+
80
+ foreach ( $plugins as $plugin_path => $plugin ):
81
+ // If the plugin isn't active, don't show it.
82
+ if ( ! in_array( $plugin_path, $active_plugins ) ) {
83
+ $inactive_plugins[] = $plugin;
84
+ continue;
85
+ }
86
+
87
+ echo $plugin['Name']; ?>: <?php echo $plugin['Version'] ."\n";
88
+
89
+ endforeach; ?>
90
+
91
+ DEACTIVATED PLUGINS:
92
+
93
+ <?php
94
+
95
+ foreach ( $inactive_plugins as $inactive_plugin ):
96
+
97
+ echo $inactive_plugin['Name']; ?>: <?php echo $inactive_plugin['Version'] ."\n";
98
+
99
+ endforeach; ?>
100
+
101
+ CURRENT THEME:
102
+
103
+ <?php
104
+ if ( get_bloginfo( 'version' ) < '3.4' ) {
105
+ $theme_data = get_theme_data( get_stylesheet_directory() . '/style.css' );
106
+ echo $theme_data['Name'] . ': ' . $theme_data['Version'];
107
+ } else {
108
+ $theme_data = wp_get_theme();
109
+ echo $theme_data->Name . ': ' . $theme_data->Version;
110
+ }
111
+ ?>
112
+
113
+
114
+ ### End System Info ###
115
+ </textarea>
116
+ <p class="submit">
117
+ <input type="hidden" name="wprss-action" value="download_sysinfo" />
118
+ <?php submit_button( __( 'Download System Info File', 'wprss' ), 'primary', 'wprss-download-sysinfo', false ); ?>
119
+ </p>
120
+ </form>
121
+
122
+ <?php
123
+ }
124
+
125
+ /**
126
+ * Generates the System Info Download File
127
+ *
128
+ * @since 3.1
129
+ * @return void
130
+ */
131
+ function wprss_generate_sysinfo_download() {
132
+ nocache_headers();
133
+
134
+ header( "Content-type: text/plain" );
135
+ header( 'Content-Disposition: attachment; filename="wprss-system-info.txt"' );
136
+
137
+ echo wp_strip_all_tags( $_POST['wprss-sysinfo'] );
138
+ exit;
139
+ }
140
+ add_action( 'wprss_download_sysinfo', 'wprss_generate_sysinfo_download' );
includes/update.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains all the functions related to updating the plugin from
4
+ * one version to another
5
+ *
6
+ * @package WP RSS Aggregator
7
+ */
8
+
9
+ add_action( 'init', 'wprss_version_check' );
10
+ /**
11
+ * Checks the version number and runs install or update functions if needed.
12
+ *
13
+ * @since 2.0
14
+ */
15
+ function wprss_version_check() {
16
+
17
+ // Get the old database version.
18
+ $old_db_version = get_option( 'wprss_db_version' );
19
+
20
+ // Get the plugin settings.
21
+ $settings = get_option( 'wprss_settings' );
22
+
23
+ // Get the plugin options
24
+ $options = get_option( 'wprss_options' );
25
+
26
+ // For fresh installs
27
+ // If there is no old database version and no settings, run the install.
28
+ if ( empty( $old_db_version ) && false === $settings && false === $options ) {
29
+ wprss_install();
30
+ }
31
+
32
+ // For version 1.0 to 3.0
33
+ // If there is no old database version and no settings, but only options
34
+ elseif ( empty( $old_db_version ) && false === $settings && !empty( $options ) ) {
35
+ wp_clear_scheduled_hook( 'wprss_generate_hook' );
36
+ wprss_install();
37
+ wprss_migrate();
38
+ wprss_fetch_insert_all_feed_items();
39
+ }
40
+
41
+ // For version 1.1 to 3.0
42
+ // If there is no old database version, but only settings and options
43
+ elseif ( empty( $old_db_version ) && !empty( $settings ) && !empty( $options ) ) {
44
+ wp_clear_scheduled_hook( 'wprss_generate_hook' );
45
+ wprss_update();
46
+ wprss_migrate();
47
+ wprss_fetch_insert_all_feed_items();
48
+ }
49
+
50
+ // For version 2+ to 3.0
51
+ // We check if wprss_settings option exists, as this only exists prior to version 3.0
52
+ // Settings field changed, and another added
53
+ elseif ( intval( $old_db_version ) < intval( WPRSS_DB_VERSION ) && ( FALSE != get_option( 'wprss_settings' ) ) ) {
54
+ wprss_upgrade_30();
55
+ wprss_update();
56
+ wprss_fetch_insert_all_feed_items();
57
+ }
58
+
59
+ // For any future versions where DB changes
60
+ // If the old version is less than the new version, run the update.
61
+ elseif ( intval( $old_db_version ) < intval( WPRSS_DB_VERSION ) ) {
62
+ wprss_update();
63
+ wprss_fetch_insert_all_feed_items();
64
+
65
+ // NO FOLLOW CHANGE FIX
66
+ $options = get_option( 'wprss_settings_general' );
67
+ if ( $options['follow_dd'] === __( "No Follow", 'wprss' ) ) {
68
+ $options['follow_dd'] = 'no_follow';
69
+ } elseif ( $options['follow_dd'] === __( "Follow", 'wprss' ) ) {
70
+ $options['follow_dd'] = 'follow';
71
+ }
72
+ }
73
+
74
+ }
75
+
76
+
77
+ /**
78
+ * Adds the plugin settings on install.
79
+ *
80
+ * @since 2.0
81
+ */
82
+ function wprss_install() {
83
+
84
+ // Add the database version setting.
85
+ add_option( 'wprss_db_version', WPRSS_DB_VERSION );
86
+
87
+ // Add the default plugin settings.
88
+ add_option( 'wprss_settings_general', wprss_get_default_settings_general() );
89
+ }
90
+
91
+
92
+ /**
93
+ * Update settings of plugin to reflect new version
94
+ *
95
+ * @since 2.0
96
+ */
97
+ function wprss_update() {
98
+
99
+ // Update the database version setting.
100
+ update_option( 'wprss_db_version', WPRSS_DB_VERSION );
101
+ // Initialize settings
102
+ wprss_settings_initialize();
103
+ }
104
+
105
+
106
+ /**
107
+ * Initialize settings to default ones if they are not yet set
108
+ *
109
+ * @since 3.0
110
+ */
111
+ function wprss_settings_initialize() {
112
+ // Get the settings from the new field in the database
113
+ $settings = get_option( 'wprss_settings_general' );
114
+
115
+ // Get the default plugin settings.
116
+ $default_settings = wprss_get_default_settings_general();
117
+
118
+ // Loop through each of the default plugin settings.
119
+ foreach ( $default_settings as $setting_key => $setting_value ) {
120
+
121
+ // If the setting didn't previously exist, add the default value to the $settings array.
122
+ if ( ! isset( $settings[ $setting_key ] ) )
123
+ $settings[ $setting_key ] = $setting_value;
124
+ }
125
+
126
+ // Update the plugin settings.
127
+ update_option( 'wprss_settings_general', $settings );
128
+ }
129
+
130
+
131
+ /**
132
+ * Takes care of cron and DB changes between versions 2+ and 3
133
+ *
134
+ * @since 3.0
135
+ */
136
+ function wprss_upgrade_30() {
137
+ wp_clear_scheduled_hook( 'wprss_fetch_feeds_hook' );
138
+
139
+ // Get the settings from the database.
140
+ $settings = get_option( 'wprss_settings' );
141
+
142
+ // Put them into our new field
143
+ update_option( 'wprss_settings_general', $settings );
144
+
145
+ // Remove old options field, we are now using wprss_settings_general
146
+ delete_option( 'wprss_settings' );
147
+ }
148
+
149
+
150
+ /**
151
+ * Migrates the feed sources from the wprss_options field to the wp_posts table (for older versions)
152
+ *
153
+ * @since 2.0
154
+ */
155
+ function wprss_migrate() {
156
+
157
+ // Get the plugin options
158
+ $options = get_option( 'wprss_options' );
159
+
160
+ $feed_sources = array_chunk( $options, 2 );
161
+
162
+ foreach ( $feed_sources as $feed_source ) {
163
+ $feed_title = $feed_source[0];
164
+ $feed_url = $feed_source[1];
165
+
166
+ // Create post object
167
+ $feed_item = array(
168
+ 'post_title' => $feed_title,
169
+ 'post_content' => '',
170
+ 'post_status' => 'publish',
171
+ 'post_type' => 'wprss_feed'
172
+ );
173
+
174
+ $inserted_ID = wp_insert_post( $feed_item, $wp_error );
175
+ // insert post meta
176
+ update_post_meta( $inserted_ID, 'wprss_url', $feed_url );
177
+ }
178
+ // delete unneeded option
179
+ delete_option( 'wprss_options' );
180
+ }
181
+
182
+
183
+ /**
184
+ * Returns an array of the default plugin settings. These are only used on initial setup.
185
+ *
186
+ * @since 2.0
187
+ */
188
+ function wprss_get_default_settings_general() {
189
+
190
+ // Set up the default plugin settings
191
+ $settings = apply_filters(
192
+ 'wprss_default_settings_general',
193
+ array(
194
+ // from version 1.1
195
+ 'open_dd' => __( 'New window' ),
196
+ 'follow_dd' => 'no_follow',
197
+
198
+ // from version 2.0
199
+ 'feed_limit' => 15,
200
+
201
+ // from version 3.0
202
+ 'date_format' => 'Y-m-d',
203
+ 'limit_feed_items_db' => 200,
204
+ 'cron_interval' => 'hourly',
205
+ 'styles_disable' => 0,
206
+ 'title_link' => 1,
207
+ 'source_enable' => 1,
208
+ 'text_preceding_source' => 'Source:',
209
+ 'date_enable' => 1,
210
+ 'text_preceding_date' => 'Published on',
211
+
212
+ // from version 3.1
213
+ 'limit_feed_items_imported' => 200,
214
+
215
+ // from version 3.3
216
+ 'custom_feed_url' => 'wprss',
217
+ 'custom_feed_limit' => '',
218
+ 'source_link' => 0,
219
+
220
+ // from version 3.4
221
+ 'video_link' => 'false'
222
+ )
223
+ );
224
+
225
+ // Return the default settings
226
+ return $settings;
227
+ }
js/admin-addon-ajax.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function($) {
2
+
3
+ $('.ajax-close-addon-notice').click( function() {
4
+ addon = $(this).attr( 'data-addon' );
5
+ notice = $(this).attr( 'data-notice' );
6
+ element = $(this).parent().parent();
7
+ if ( addon !== false && typeof addon !== 'undefined' && notice !== false && typeof notice !== 'undefined' ) {
8
+ $.ajax({
9
+ url: ajaxurl,
10
+ type: 'POST',
11
+ data: {
12
+ action: 'wprss_dismiss_addon_notice',
13
+ addon: addon,
14
+ notice: notice,
15
+ },
16
+ success: function( data, status, jqXHR) {
17
+ if ( data === 'true' ) {
18
+ element.slideUp( 'fast', function(){
19
+ element.remove();
20
+ });
21
+ }
22
+ }
23
+ });
24
+ $(this).text('Please wait ...');
25
+ }
26
+ });
27
+
28
+ });
js/admin-custom.js ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // jQuery for 'Fetch Feed Items' Row Action in 'All Feed Sources' page
2
+ function fetch_items_row_action_callback(){
3
+ var link = jQuery(this);
4
+ var original_text = link.text();
5
+ var id = link.attr('pid');
6
+ var url = link.attr('purl');
7
+ jQuery.post(
8
+ url,
9
+ {
10
+ 'action': 'wprss_fetch_feeds_action',
11
+ 'id': id
12
+ },
13
+ function(response){
14
+ link.text('Feed items imported!');
15
+ setTimeout( function(){
16
+ link.text( original_text ).click( fetch_items_row_action_callback );
17
+ }, 3500 );
18
+ }
19
+ );
20
+ link.text('Please wait ...');
21
+ link.unbind('click');
22
+ };
23
+
24
+
25
+
26
+ jQuery(window).load( function(){
27
+
28
+ // On TAB pressed when on title input field, go to URL input field
29
+ jQuery('input#title').on( 'keydown', function( event ) {
30
+
31
+ if ( event.which == 9 ) {
32
+ event.preventDefault();
33
+ jQuery('input#wprss_url').focus();
34
+ }
35
+ }
36
+ );
37
+
38
+ // On TAB pressed when on description textarea field, go to Publish submit button
39
+ jQuery('textarea#wprss_description').on( 'keydown', function( event ) {
40
+
41
+ if ( event.which == 9 ) {
42
+ event.preventDefault();
43
+ jQuery('input#publish').focus();
44
+ }
45
+ }
46
+ );
47
+
48
+ jQuery('.wprss_ajax_action').click( fetch_items_row_action_callback );
49
+
50
+ // Make the number rollers change their value to empty string when value is 0, making
51
+ // them use the placeholder.
52
+ jQuery('.wprss-number-roller').on('change', function(){
53
+ if ( jQuery(this).val() == 0 )
54
+ jQuery(this).val('');
55
+ });
56
+
57
+
58
+ /* JS for admin notice - Leave a review */
59
+
60
+
61
+ // Check to see if the Ajax Notification is visible
62
+ if ( jQuery('#dismiss-ajax-notification').length > 0 ) {
63
+ NOTIFICATION = jQuery('#ajax-notification');
64
+ NOTIFICATION_DISMISS = jQuery('#dismiss-ajax-notification');
65
+ NOTIFICATION_DISMISS.click( function(evt){
66
+ evt.preventDefault();
67
+ evt.stopPropagation();
68
+
69
+ jQuery.post(ajaxurl, {
70
+ // The name of the function to fire on the server
71
+ action: 'wprss_hide_admin_notification',
72
+ // The nonce value to send for the security check
73
+ nonce: jQuery.trim( jQuery('#ajax-notification-nonce').text() )
74
+ }, function (response) {
75
+ // If the response was successful (that is, 1 was returned), hide the notification;
76
+ // Otherwise, we'll change the class name of the notification
77
+ if ( response !== '1' ) {
78
+ NOTIFICATION.removeClass('updated').addClass('error');
79
+ } // end if
80
+ });
81
+
82
+ NOTIFICATION.fadeOut(400);
83
+ });
84
+ }
85
+ });
js/custom.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function() {
2
+ if(jQuery.fn.colorbox) {
3
+ jQuery( 'a.colorbox' ).colorbox(
4
+ {iframe:true, width:'80%', height:'80%'}
5
+ );
6
+ }
7
+ });
js/editor.js ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var WPRSS_TMCE_PLUGIN_ID = 'wprss';
2
+ var WPRSS_ED = null;
3
+ var wprss_dialog_submit = null;
4
+
5
+ jQuery( document ).ready( function($) {
6
+
7
+ wprss_dialog_submit = function() {
8
+ all = $('#wprss-dialog-all-sources').is(':checked');
9
+
10
+ sources = [];
11
+ $('#wprss-dialog-feed-source-list :selected').each( function( i, selected ){
12
+ sources[i] = $(selected).val();
13
+ });
14
+ sources = sources.join(',');
15
+
16
+ excludes = [];
17
+ $('#wprss-dialog-exclude-list :selected').each( function( i, selected ){
18
+ excludes[i] = $(selected).val();
19
+ });
20
+ excludes = excludes.join(',');
21
+
22
+ limit = $('#wprss-dialog-feed-limit').val();
23
+
24
+ shortcode = '[wp-rss-aggregator';
25
+ if ( all ) {
26
+ if ( excludes.length > 0 )
27
+ shortcode += ' exclude="' + excludes + '"'
28
+ } else {
29
+ if ( sources.length > 0 )
30
+ shortcode += ' source="' + sources + '"'
31
+ }
32
+
33
+ if ( limit !== '' && limit !== '0' )
34
+ shortcode += ' limit="' + limit + '"';
35
+ shortcode += ']';
36
+
37
+ WPRSS_ED.execCommand('mceInsertContent', false, shortcode);
38
+ WPRSS_Dialog.close();
39
+ }
40
+
41
+ window.WPRSS_Dialog = new function() {
42
+ // Keep a reference to the current object
43
+ var base = this;
44
+ var dialog = null;
45
+ var dialog_head = null;
46
+ var dialog_head_close = null;
47
+ var dialog_inside = null;
48
+
49
+ var close = function( e ) {
50
+ overlay.fadeOut();
51
+ dialog_inside.empty();
52
+ };
53
+
54
+ base.close = close;
55
+
56
+ base.init = function() {
57
+ overlay = $('<div id="wprss-overlay"></div>');
58
+ dialog = $('<div id="wprss-editor-dialog" class="postbox"></div>');
59
+
60
+ dialog_head = $('<div class="wprss-dialog-header"> <h1>WPRSS Aggregator Shortcode</h1> </div>');
61
+ dialog_head_close = $('<span class="close-btn"></span>').html('&times;').appendTo( dialog_head );
62
+ dialog_inside = $('<div class="wprss-dialog-inside"></div>');
63
+ dialog.append( dialog_head );
64
+ dialog.append( dialog_inside );
65
+
66
+ overlay.hide().appendTo('body');
67
+ dialog.appendTo(overlay);
68
+
69
+ overlay.click( close );
70
+ dialog_head_close.click( close );
71
+
72
+ dialog.on( 'click', function( e ) {
73
+ e.stopPropagation();
74
+ });
75
+ };
76
+
77
+
78
+ base.getDialog = function() {
79
+ overlay.show();
80
+
81
+ $.ajax({
82
+ url: ajaxurl,
83
+ type: 'POST',
84
+ data: {
85
+ action: 'wprss_editor_dialog'
86
+ },
87
+ success: function( data, status, jqXHR) {
88
+ if ( data.length > 0 ) {
89
+ dialog_inside.html( data );
90
+ }
91
+ }
92
+ });
93
+
94
+
95
+ };
96
+ }
97
+
98
+
99
+ WPRSS_Dialog.init();
100
+
101
+
102
+
103
+
104
+ tinymce.create( 'tinymce.plugins.' + WPRSS_TMCE_PLUGIN_ID, {
105
+ // INITIALIZE THE BUTTON
106
+ init : function( ed, url ) {
107
+ // Add the button
108
+ ed.addButton( WPRSS_TMCE_PLUGIN_ID, {
109
+ title : 'WPRSS Aggregator shortcode',
110
+ image : url + '/../images/icon-adminpage32.png',
111
+ onclick : function() {
112
+ idPattern = /(?:(?:[^v]+)+v.)?([^&=]{11})(?=&|$)/;
113
+ WPRSS_Dialog.getDialog();
114
+ WPRSS_ED = ed;
115
+ /*
116
+ var vidId = prompt("WP RSS Aggregator", "Choose feed source");
117
+ var m = idPattern.exec(vidId);
118
+ if (m != null && m != 'undefined')
119
+ ed.execCommand('mceInsertContent', false, '[wprss source="'+m[1]+'"]');
120
+ */
121
+ }
122
+ });
123
+ },
124
+ createControl : function( n, cm ) {
125
+ return null;
126
+ },
127
+ getInfo : function() {
128
+ return {
129
+ longname : "WPRSS Aggregator Shortcode",
130
+ author : 'John Galea',
131
+ authorurl : 'http://profiles.wordpress.org/jeangalea/',
132
+ infourl : 'http://www.wprssaggregator.com/',
133
+ version : "1.0"
134
+ };
135
+ }
136
+ });
137
+ tinymce.PluginManager.add( WPRSS_TMCE_PLUGIN_ID, tinymce.plugins.wprss );
138
+ });
js/jquery.colorbox-min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ Colorbox v1.4.29 - 2013-09-10
3
+ jQuery lightbox and modal window plugin
4
+ (c) 2013 Jack Moore - http://www.jacklmoore.com/colorbox
5
+ license: http://www.opensource.org/licenses/mit-license.php
6
+ */
7
+ (function(t,e,i){function o(i,o,n){var r=e.createElement(i);return o&&(r.id=Z+o),n&&(r.style.cssText=n),t(r)}function n(){return i.innerHeight?i.innerHeight:t(i).height()}function r(t){var e=k.length,i=(A+t)%e;return 0>i?e+i:i}function h(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():n())/100:1)*parseInt(t,10))}function l(t,e){return t.photo||t.photoRegex.test(e)}function s(t,e){return t.retinaUrl&&i.devicePixelRatio>1?e.replace(t.photoRegex,t.retinaSuffix):e}function a(t){"contains"in g[0]&&!g[0].contains(t.target)&&(t.stopPropagation(),g.focus())}function d(){var e,i=t.data(z,Y);null==i?(B=t.extend({},X),console&&console.log&&console.log("Error: cboxElement missing settings object")):B=t.extend({},i);for(e in B)t.isFunction(B[e])&&"on"!==e.slice(0,2)&&(B[e]=B[e].call(z));B.rel=B.rel||z.rel||t(z).data("rel")||"nofollow",B.href=B.href||t(z).attr("href"),B.title=B.title||z.title,"string"==typeof B.href&&(B.href=t.trim(B.href))}function c(i,o){t(e).trigger(i),le.trigger(i),t.isFunction(o)&&o.call(z)}function u(i){q||(z=i,d(),k=t(z),A=0,"nofollow"!==B.rel&&(k=t("."+te).filter(function(){var e,i=t.data(this,Y);return i&&(e=t(this).data("rel")||i.rel||this.rel),e===B.rel}),A=k.index(z),-1===A&&(k=k.add(z),A=k.length-1)),w.css({opacity:parseFloat(B.opacity),cursor:B.overlayClose?"pointer":"auto",visibility:"visible"}).show(),J&&g.add(w).removeClass(J),B.className&&g.add(w).addClass(B.className),J=B.className,B.closeButton?K.html(B.close).appendTo(y):K.appendTo("<div/>"),U||(U=$=!0,g.css({visibility:"hidden",display:"block"}),H=o(se,"LoadedContent","width:0; height:0; overflow:hidden"),y.css({width:"",height:""}).append(H),O=x.height()+C.height()+y.outerHeight(!0)-y.height(),_=b.width()+T.width()+y.outerWidth(!0)-y.width(),D=H.outerHeight(!0),N=H.outerWidth(!0),B.w=h(B.initialWidth,"x"),B.h=h(B.initialHeight,"y"),H.css({width:"",height:B.h}),Q.position(),c(ee,B.onOpen),P.add(L).hide(),g.focus(),B.trapFocus&&e.addEventListener&&(e.addEventListener("focus",a,!0),le.one(re,function(){e.removeEventListener("focus",a,!0)})),B.returnFocus&&le.one(re,function(){t(z).focus()})),m())}function f(){!g&&e.body&&(V=!1,E=t(i),g=o(se).attr({id:Y,"class":t.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),w=o(se,"Overlay").hide(),F=t([o(se,"LoadingOverlay")[0],o(se,"LoadingGraphic")[0]]),v=o(se,"Wrapper"),y=o(se,"Content").append(L=o(se,"Title"),S=o(se,"Current"),I=t('<button type="button"/>').attr({id:Z+"Previous"}),R=t('<button type="button"/>').attr({id:Z+"Next"}),M=o("button","Slideshow"),F),K=t('<button type="button"/>').attr({id:Z+"Close"}),v.append(o(se).append(o(se,"TopLeft"),x=o(se,"TopCenter"),o(se,"TopRight")),o(se,!1,"clear:left").append(b=o(se,"MiddleLeft"),y,T=o(se,"MiddleRight")),o(se,!1,"clear:left").append(o(se,"BottomLeft"),C=o(se,"BottomCenter"),o(se,"BottomRight"))).find("div div").css({"float":"left"}),W=o(se,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),P=R.add(I).add(S).add(M),t(e.body).append(w,g.append(v,W)))}function p(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.ctrlKey||(t.preventDefault(),u(this))}return g?(V||(V=!0,R.click(function(){Q.next()}),I.click(function(){Q.prev()}),K.click(function(){Q.close()}),w.click(function(){B.overlayClose&&Q.close()}),t(e).bind("keydown."+Z,function(t){var e=t.keyCode;U&&B.escKey&&27===e&&(t.preventDefault(),Q.close()),U&&B.arrowKey&&k[1]&&!t.altKey&&(37===e?(t.preventDefault(),I.click()):39===e&&(t.preventDefault(),R.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+Z,"."+te,i):t("."+te).live("click."+Z,i)),!0):!1}function m(){var n,r,a,u=Q.prep,f=++ae;$=!0,j=!1,z=k[A],d(),c(he),c(ie,B.onLoad),B.h=B.height?h(B.height,"y")-D-O:B.innerHeight&&h(B.innerHeight,"y"),B.w=B.width?h(B.width,"x")-N-_:B.innerWidth&&h(B.innerWidth,"x"),B.mw=B.w,B.mh=B.h,B.maxWidth&&(B.mw=h(B.maxWidth,"x")-N-_,B.mw=B.w&&B.w<B.mw?B.w:B.mw),B.maxHeight&&(B.mh=h(B.maxHeight,"y")-D-O,B.mh=B.h&&B.h<B.mh?B.h:B.mh),n=B.href,G=setTimeout(function(){F.show()},100),B.inline?(a=o(se).hide().insertBefore(t(n)[0]),le.one(he,function(){a.replaceWith(H.children())}),u(t(n))):B.iframe?u(" "):B.html?u(B.html):l(B,n)?(n=s(B,n),j=e.createElement("img"),t(j).addClass(Z+"Photo").bind("error",function(){B.title=!1,u(o(se,"Error").html(B.imgError))}).one("load",function(){var e;f===ae&&(j.alt=t(z).attr("alt")||t(z).attr("data-alt")||"",B.retinaImage&&i.devicePixelRatio>1&&(j.height=j.height/i.devicePixelRatio,j.width=j.width/i.devicePixelRatio),B.scalePhotos&&(r=function(){j.height-=j.height*e,j.width-=j.width*e},B.mw&&j.width>B.mw&&(e=(j.width-B.mw)/j.width,r()),B.mh&&j.height>B.mh&&(e=(j.height-B.mh)/j.height,r())),B.h&&(j.style.marginTop=Math.max(B.mh-j.height,0)/2+"px"),k[1]&&(B.loop||k[A+1])&&(j.style.cursor="pointer",j.onclick=function(){Q.next()}),j.style.width=j.width+"px",j.style.height=j.height+"px",setTimeout(function(){u(j)},1))}),setTimeout(function(){j.src=n},1)):n&&W.load(n,B.data,function(e,i){f===ae&&u("error"===i?o(se,"Error").html(B.xhrError):t(this).contents())})}var w,g,v,y,x,b,T,C,k,E,H,W,F,L,S,M,R,I,K,P,B,O,_,D,N,z,A,j,U,$,q,G,Q,J,V,X={transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,inline:!1,html:!1,iframe:!1,fastIframe:!0,photo:!1,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",open:!1,returnFocus:!0,trapFocus:!0,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0},Y="colorbox",Z="cbox",te=Z+"Element",ee=Z+"_open",ie=Z+"_load",oe=Z+"_complete",ne=Z+"_cleanup",re=Z+"_closed",he=Z+"_purge",le=t("<a/>"),se="div",ae=0,de={},ce=function(){function t(){clearTimeout(h)}function e(){(B.loop||k[A+1])&&(t(),h=setTimeout(Q.next,B.slideshowSpeed))}function i(){M.html(B.slideshowStop).unbind(s).one(s,o),le.bind(oe,e).bind(ie,t),g.removeClass(l+"off").addClass(l+"on")}function o(){t(),le.unbind(oe,e).unbind(ie,t),M.html(B.slideshowStart).unbind(s).one(s,function(){Q.next(),i()}),g.removeClass(l+"on").addClass(l+"off")}function n(){r=!1,M.hide(),t(),le.unbind(oe,e).unbind(ie,t),g.removeClass(l+"off "+l+"on")}var r,h,l=Z+"Slideshow_",s="click."+Z;return function(){r?B.slideshow||(le.unbind(ne,n),n()):B.slideshow&&k[1]&&(r=!0,le.one(ne,n),B.slideshowAuto?i():o(),M.show())}}();t.colorbox||(t(f),Q=t.fn[Y]=t[Y]=function(e,i){var o=this;if(e=e||{},f(),p()){if(t.isFunction(o))o=t("<a/>"),e.open=!0;else if(!o[0])return o;i&&(e.onComplete=i),o.each(function(){t.data(this,Y,t.extend({},t.data(this,Y)||X,e))}).addClass(te),(t.isFunction(e.open)&&e.open.call(o)||e.open)&&u(o[0])}return o},Q.position=function(e,i){function o(){x[0].style.width=C[0].style.width=y[0].style.width=parseInt(g[0].style.width,10)-_+"px",y[0].style.height=b[0].style.height=T[0].style.height=parseInt(g[0].style.height,10)-O+"px"}var r,l,s,a=0,d=0,c=g.offset();if(E.unbind("resize."+Z),g.css({top:-9e4,left:-9e4}),l=E.scrollTop(),s=E.scrollLeft(),B.fixed?(c.top-=l,c.left-=s,g.css({position:"fixed"})):(a=l,d=s,g.css({position:"absolute"})),d+=B.right!==!1?Math.max(E.width()-B.w-N-_-h(B.right,"x"),0):B.left!==!1?h(B.left,"x"):Math.round(Math.max(E.width()-B.w-N-_,0)/2),a+=B.bottom!==!1?Math.max(n()-B.h-D-O-h(B.bottom,"y"),0):B.top!==!1?h(B.top,"y"):Math.round(Math.max(n()-B.h-D-O,0)/2),g.css({top:c.top,left:c.left,visibility:"visible"}),v[0].style.width=v[0].style.height="9999px",r={width:B.w+N+_,height:B.h+D+O,top:a,left:d},e){var u=0;t.each(r,function(t){return r[t]!==de[t]?(u=e,void 0):void 0}),e=u}de=r,e||g.css(r),g.dequeue().animate(r,{duration:e||0,complete:function(){o(),$=!1,v[0].style.width=B.w+N+_+"px",v[0].style.height=B.h+D+O+"px",B.reposition&&setTimeout(function(){E.bind("resize."+Z,Q.position)},1),i&&i()},step:o})},Q.resize=function(t){var e;U&&(t=t||{},t.width&&(B.w=h(t.width,"x")-N-_),t.innerWidth&&(B.w=h(t.innerWidth,"x")),H.css({width:B.w}),t.height&&(B.h=h(t.height,"y")-D-O),t.innerHeight&&(B.h=h(t.innerHeight,"y")),t.innerHeight||t.height||(e=H.scrollTop(),H.css({height:"auto"}),B.h=H.height()),H.css({height:B.h}),e&&H.scrollTop(e),Q.position("none"===B.transition?0:B.speed))},Q.prep=function(i){function n(){return B.w=B.w||H.width(),B.w=B.mw&&B.mw<B.w?B.mw:B.w,B.w}function h(){return B.h=B.h||H.height(),B.h=B.mh&&B.mh<B.h?B.mh:B.h,B.h}if(U){var a,d="none"===B.transition?0:B.speed;H.empty().remove(),H=o(se,"LoadedContent").append(i),H.hide().appendTo(W.show()).css({width:n(),overflow:B.scrolling?"auto":"hidden"}).css({height:h()}).prependTo(y),W.hide(),t(j).css({"float":"none"}),a=function(){function i(){t.support.opacity===!1&&g[0].style.removeAttribute("filter")}var n,h,a=k.length,u="frameBorder",f="allowTransparency";U&&(h=function(){clearTimeout(G),F.hide(),c(oe,B.onComplete)},L.html(B.title).add(H).show(),a>1?("string"==typeof B.current&&S.html(B.current.replace("{current}",A+1).replace("{total}",a)).show(),R[B.loop||a-1>A?"show":"hide"]().html(B.next),I[B.loop||A?"show":"hide"]().html(B.previous),ce(),B.preloading&&t.each([r(-1),r(1)],function(){var i,o,n=k[this],r=t.data(n,Y);r&&r.href?(i=r.href,t.isFunction(i)&&(i=i.call(n))):i=t(n).attr("href"),i&&l(r,i)&&(i=s(r,i),o=e.createElement("img"),o.src=i)})):P.hide(),B.iframe?(n=o("iframe")[0],u in n&&(n[u]=0),f in n&&(n[f]="true"),B.scrolling||(n.scrolling="no"),t(n).attr({src:B.href,name:(new Date).getTime(),"class":Z+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",h).appendTo(H),le.one(he,function(){n.src="//about:blank"}),B.fastIframe&&t(n).trigger("load")):h(),"fade"===B.transition?g.fadeTo(d,1,i):i())},"fade"===B.transition?g.fadeTo(d,0,function(){Q.position(0,a)}):Q.position(d,a)}},Q.next=function(){!$&&k[1]&&(B.loop||k[A+1])&&(A=r(1),u(k[A]))},Q.prev=function(){!$&&k[1]&&(B.loop||A)&&(A=r(-1),u(k[A]))},Q.close=function(){U&&!q&&(q=!0,U=!1,c(ne,B.onCleanup),E.unbind("."+Z),w.fadeTo(B.fadeOut||0,0),g.stop().fadeTo(B.fadeOut||0,0,function(){g.add(w).css({opacity:1,cursor:"auto"}).hide(),c(he),H.empty().remove(),setTimeout(function(){q=!1,c(re,B.onClosed)},1)}))},Q.remove=function(){g&&(g.stop(),t.colorbox.close(),g.stop().remove(),w.remove(),q=!1,g=null,t("."+te).removeData(Y).removeClass(te),t(e).unbind("click."+Z))},Q.element=function(){return t(z)},Q.settings=X)})(jQuery,document,window);
languages/default.mo ADDED
Binary file
languages/default.po ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: wprss\n"
4
+ "POT-Creation-Date: 2012-09-25 12:09+0100\n"
5
+ "PO-Revision-Date: 2012-09-25 13:52+0100\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.5.3\n"
12
+ "X-Poedit-KeywordsList: _;__;_e\n"
13
+ "X-Poedit-Basepath: ../\n"
14
+ "X-Poedit-SearchPath-0: .\n"
15
+
16
+ #: wp-rss-aggregator.php:152
17
+ msgid "Enter feed name here (e.g. WP Mayor)"
18
+ msgstr ""
19
+
20
+ #: wp-rss-aggregator.php:394
21
+ msgid "No feed items found"
22
+ msgstr ""
23
+
24
+ #: inc/activation.php:11
25
+ msgid "This plugin requires WordPress version 3.2 or higher."
26
+ msgstr ""
27
+
28
+ #: inc/admin-options.php:45 inc/admin-options.php:88
29
+ msgid "WP RSS Aggregator Settings"
30
+ msgstr ""
31
+
32
+ #: inc/admin-options.php:45
33
+ msgid "Settings"
34
+ msgstr ""
35
+
36
+ #: inc/admin-options.php:67
37
+ msgid "Open links behaviour"
38
+ msgstr ""
39
+
40
+ #: inc/admin-options.php:70
41
+ msgid "Set links as"
42
+ msgstr ""
43
+
44
+ #: inc/admin-options.php:73
45
+ msgid "Feed limit"
46
+ msgstr ""
47
+
48
+ #: inc/admin-options.php:93
49
+ msgid "Save Settings"
50
+ msgstr ""
51
+
52
+ #: inc/admin-options.php:113
53
+ msgid "No follow"
54
+ msgstr ""
55
+
56
+ #: inc/admin-options.php:114
57
+ msgid "Follow"
58
+ msgstr ""
59
+
60
+ #: inc/admin-options.php:132
61
+ msgid "Lightbox"
62
+ msgstr ""
63
+
64
+ #: inc/admin-options.php:133
65
+ msgid "New window"
66
+ msgstr ""
67
+
68
+ #: inc/admin-options.php:134
69
+ msgid "None"
70
+ msgstr ""
71
+
72
+ #: inc/cron-jobs.php:53
73
+ msgid "Once Weekly"
74
+ msgstr ""
75
+
76
+ #: inc/custom-post-types.php:30
77
+ msgid "Feed Sources"
78
+ msgstr ""
79
+
80
+ #: inc/custom-post-types.php:31
81
+ msgid "Feed"
82
+ msgstr ""
83
+
84
+ #: inc/custom-post-types.php:32 inc/custom-post-types.php:34
85
+ msgid "Add New Feed Source"
86
+ msgstr ""
87
+
88
+ #: inc/custom-post-types.php:33
89
+ msgid "All Feed Sources"
90
+ msgstr ""
91
+
92
+ #: inc/custom-post-types.php:35
93
+ msgid "Edit Feed Source"
94
+ msgstr ""
95
+
96
+ #: inc/custom-post-types.php:36
97
+ msgid "New Feed Source"
98
+ msgstr ""
99
+
100
+ #: inc/custom-post-types.php:37
101
+ msgid "View Feed Source"
102
+ msgstr ""
103
+
104
+ #: inc/custom-post-types.php:38
105
+ msgid "Search Feeds"
106
+ msgstr ""
107
+
108
+ #: inc/custom-post-types.php:39
109
+ msgid "No Feed Sources Found"
110
+ msgstr ""
111
+
112
+ #: inc/custom-post-types.php:40
113
+ msgid "No Feed Sources Found In Trash"
114
+ msgstr ""
115
+
116
+ #: inc/custom-post-types.php:41
117
+ msgid "RSS Aggregator"
118
+ msgstr ""
119
+
120
+ #: inc/custom-post-types.php:58 inc/custom-post-types.php:60
121
+ msgid "Imported Feeds"
122
+ msgstr ""
123
+
124
+ #: inc/custom-post-types.php:59
125
+ msgid "Imported Feed"
126
+ msgstr ""
127
+
128
+ #: inc/custom-post-types.php:61
129
+ msgid "View Imported Feed"
130
+ msgstr ""
131
+
132
+ #: inc/custom-post-types.php:62
133
+ msgid "Search Imported Feeds"
134
+ msgstr ""
135
+
136
+ #: inc/custom-post-types.php:63
137
+ msgid "No Imported Feeds Found"
138
+ msgstr ""
139
+
140
+ #: inc/custom-post-types.php:64
141
+ msgid "No Imported Feeds Found In Trash"
142
+ msgstr ""
143
+
144
+ #: inc/custom-post-types.php:83 inc/custom-post-types.php:135
145
+ msgid "Name"
146
+ msgstr ""
147
+
148
+ #: inc/custom-post-types.php:84 inc/custom-post-types.php:306
149
+ msgid "URL"
150
+ msgstr ""
151
+
152
+ #: inc/custom-post-types.php:85 inc/custom-post-types.php:313
153
+ msgid "Description"
154
+ msgstr ""
155
+
156
+ #: inc/custom-post-types.php:136
157
+ msgid "Permalink"
158
+ msgstr ""
159
+
160
+ #: inc/custom-post-types.php:137
161
+ msgid "Date published"
162
+ msgstr ""
163
+
164
+ #: inc/custom-post-types.php:138
165
+ msgid "Source"
166
+ msgstr ""
167
+
168
+ #: inc/custom-post-types.php:226
169
+ msgid "Save Feed Source"
170
+ msgstr ""
171
+
172
+ #: inc/custom-post-types.php:252
173
+ msgid "WP RSS Aggregator Help"
174
+ msgstr ""
175
+
176
+ #: inc/custom-post-types.php:261
177
+ msgid "Like this plugin?"
178
+ msgstr ""
179
+
180
+ #: inc/custom-post-types.php:270
181
+ msgid "Follow us"
182
+ msgstr ""
183
+
184
+ #: inc/custom-post-types.php:279
185
+ msgid "Feed Source Details"
186
+ msgstr ""
187
+
188
+ #: inc/custom-post-types.php:288
189
+ msgid "Feed Preview"
190
+ msgstr ""
191
+
192
+ #: inc/custom-post-types.php:307
193
+ msgid "Enter feed URL (including http://)"
194
+ msgstr ""
195
+
196
+ #: inc/custom-post-types.php:314
197
+ msgid "A short description about this feed source (optional)"
198
+ msgstr ""
199
+
200
+ #: inc/custom-post-types.php:438
201
+ msgid "Delete Permanently"
202
+ msgstr ""
203
+
204
+ #: inc/custom-post-types.php:440
205
+ msgid "Move to Trash"
206
+ msgstr ""
207
+
208
+ #: inc/custom-post-types.php:471
209
+ msgid ""
210
+ "<strong>Invalid feed URL</strong> - Double check the feed source URL setting "
211
+ "above."
212
+ msgstr ""
213
+
214
+ #: inc/custom-post-types.php:474
215
+ msgid "No feed URL defined yet"
216
+ msgstr ""
217
+
218
+ #: inc/custom-post-types.php:486
219
+ msgid "Need help?"
220
+ msgstr ""
221
+
222
+ #: inc/custom-post-types.php:488
223
+ msgid "Check out the support forum"
224
+ msgstr ""
225
+
226
+ #: inc/custom-post-types.php:499
227
+ msgid "Why not do any or all of the following"
228
+ msgstr ""
229
+
230
+ #: inc/custom-post-types.php:501
231
+ msgid "Give it a 5 star rating on WordPress.org."
232
+ msgstr ""
233
+
234
+ #: inc/custom-post-types.php:502
235
+ msgid "Donate a token of your appreciation."
236
+ msgstr ""
237
+
238
+ #: inc/custom-post-types.php:517
239
+ msgid "Follow WP Mayor on Twitter."
240
+ msgstr ""
241
+
242
+ #: inc/custom-post-types.php:518
243
+ msgid "Like WP Mayor on Facebook."
244
+ msgstr ""
245
+
246
+ #: inc/custom-post-types.php:535
247
+ msgid "Feed source updated. "
248
+ msgstr ""
249
+
250
+ #: inc/custom-post-types.php:536
251
+ msgid "Custom field updated."
252
+ msgstr ""
253
+
254
+ #: inc/custom-post-types.php:537
255
+ msgid "Custom field deleted."
256
+ msgstr ""
257
+
258
+ #: inc/custom-post-types.php:538 inc/custom-post-types.php:544
259
+ msgid "Feed source updated."
260
+ msgstr ""
261
+
262
+ #: inc/custom-post-types.php:540 inc/custom-post-types.php:541
263
+ msgid "Feed source saved."
264
+ msgstr ""
265
+
266
+ #: inc/custom-post-types.php:542
267
+ msgid "Feed source submitted."
268
+ msgstr ""
269
+
270
+ #: inc/custom-post-types.php:628
271
+ msgid "Publish Feed"
272
+ msgstr ""
languages/it.mo ADDED
Binary file
languages/it.po ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: wprss\n"
4
+ "POT-Creation-Date: 2012-09-25 12:09+0100\n"
5
+ "PO-Revision-Date: 2012-09-30 11:18+0100\n"
6
+ "Last-Translator: Davide De Maestri <davide.demaestri@gmail.com>\n"
7
+ "Language-Team: \n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.5.3\n"
12
+ "X-Poedit-KeywordsList: _;__;_e\n"
13
+ "X-Poedit-Basepath: ../\n"
14
+ "X-Poedit-SearchPath-0: .\n"
15
+
16
+ #: wp-rss-aggregator.php:152
17
+ msgid "Enter feed name here (e.g. WP Mayor)"
18
+ msgstr "Inserisci il nome del feed qui (es: WP Mayor)"
19
+
20
+ #: wp-rss-aggregator.php:394
21
+ msgid "No feed items found"
22
+ msgstr "Nessun feed trovato"
23
+
24
+ #: inc/activation.php:11
25
+ msgid "This plugin requires WordPress version 3.2 or higher."
26
+ msgstr "Questo plugin richiede la versione di WordPress 3.2 o superiore"
27
+
28
+ #: inc/admin-options.php:45 inc/admin-options.php:88
29
+ msgid "WP RSS Aggregator Settings"
30
+ msgstr "Impostazioni WP RSS Aggregator"
31
+
32
+ #: inc/admin-options.php:45
33
+ msgid "Settings"
34
+ msgstr "Impostazioni"
35
+
36
+ #: inc/admin-options.php:67
37
+ msgid "Open links behaviour"
38
+ msgstr "Comportamento di apertura dei links"
39
+
40
+ #: inc/admin-options.php:70
41
+ msgid "Set links as"
42
+ msgstr "Imposta links come"
43
+
44
+ #: inc/admin-options.php:73
45
+ msgid "Feed limit"
46
+ msgstr "Limite Feed"
47
+
48
+ #: inc/admin-options.php:93
49
+ msgid "Save Settings"
50
+ msgstr "Salva impostazioni"
51
+
52
+ #: inc/admin-options.php:113
53
+ msgid "No follow"
54
+ msgstr "No follow"
55
+
56
+ #: inc/admin-options.php:114
57
+ msgid "Follow"
58
+ msgstr "Follow"
59
+
60
+ #: inc/admin-options.php:132
61
+ msgid "Lightbox"
62
+ msgstr "Lightbox"
63
+
64
+ #: inc/admin-options.php:133
65
+ msgid "New window"
66
+ msgstr "Nuova finestra"
67
+
68
+ #: inc/admin-options.php:134
69
+ msgid "None"
70
+ msgstr "Nessuno"
71
+
72
+ #: inc/cron-jobs.php:53
73
+ msgid "Once Weekly"
74
+ msgstr "Una volta alla settimana"
75
+
76
+ #: inc/custom-post-types.php:30
77
+ msgid "Feed Sources"
78
+ msgstr "Sorgenti Feed"
79
+
80
+ #: inc/custom-post-types.php:31
81
+ msgid "Feed"
82
+ msgstr "Feed"
83
+
84
+ #: inc/custom-post-types.php:32 inc/custom-post-types.php:34
85
+ msgid "Add New Feed Source"
86
+ msgstr "Aggiungi nuova sorgente Feed"
87
+
88
+ #: inc/custom-post-types.php:33
89
+ msgid "All Feed Sources"
90
+ msgstr "Tutte le sorgenti feed"
91
+
92
+ #: inc/custom-post-types.php:35
93
+ msgid "Edit Feed Source"
94
+ msgstr "Modifica sorgente feed"
95
+
96
+ #: inc/custom-post-types.php:36
97
+ msgid "New Feed Source"
98
+ msgstr "Nuova sorgente feed"
99
+
100
+ #: inc/custom-post-types.php:37
101
+ msgid "View Feed Source"
102
+ msgstr "Visualizza sorgente feed"
103
+
104
+ #: inc/custom-post-types.php:38
105
+ msgid "Search Feeds"
106
+ msgstr "Cerca feeds"
107
+
108
+ #: inc/custom-post-types.php:39
109
+ msgid "No Feed Sources Found"
110
+ msgstr "Nessuna sorgente di feed trovata"
111
+
112
+ #: inc/custom-post-types.php:40
113
+ msgid "No Feed Sources Found In Trash"
114
+ msgstr "Nessuna sorgente di feed trovata nel cestino"
115
+
116
+ #: inc/custom-post-types.php:41
117
+ msgid "RSS Aggregator"
118
+ msgstr "Aggregatore RSS"
119
+
120
+ #: inc/custom-post-types.php:58 inc/custom-post-types.php:60
121
+ msgid "Imported Feeds"
122
+ msgstr "Feeds importati"
123
+
124
+ #: inc/custom-post-types.php:59
125
+ msgid "Imported Feed"
126
+ msgstr "Feed importato"
127
+
128
+ #: inc/custom-post-types.php:61
129
+ msgid "View Imported Feed"
130
+ msgstr "Visualizza feed importato"
131
+
132
+ #: inc/custom-post-types.php:62
133
+ msgid "Search Imported Feeds"
134
+ msgstr "Cerca feeds importati"
135
+
136
+ #: inc/custom-post-types.php:63
137
+ msgid "No Imported Feeds Found"
138
+ msgstr "Nessun feed importato trovato"
139
+
140
+ #: inc/custom-post-types.php:64
141
+ msgid "No Imported Feeds Found In Trash"
142
+ msgstr "Nessun feed importato trovato nel cestino"
143
+
144
+ #: inc/custom-post-types.php:83 inc/custom-post-types.php:135
145
+ msgid "Name"
146
+ msgstr "Nome"
147
+
148
+ #: inc/custom-post-types.php:84 inc/custom-post-types.php:306
149
+ msgid "URL"
150
+ msgstr "URL"
151
+
152
+ #: inc/custom-post-types.php:85 inc/custom-post-types.php:313
153
+ msgid "Description"
154
+ msgstr "Descrizione"
155
+
156
+ #: inc/custom-post-types.php:136
157
+ msgid "Permalink"
158
+ msgstr "Permalink"
159
+
160
+ #: inc/custom-post-types.php:137
161
+ msgid "Date published"
162
+ msgstr "Data di pubblicazione"
163
+
164
+ #: inc/custom-post-types.php:138
165
+ msgid "Source"
166
+ msgstr "Sorgente"
167
+
168
+ #: inc/custom-post-types.php:226
169
+ msgid "Save Feed Source"
170
+ msgstr "Salva sorgente feed"
171
+
172
+ #: inc/custom-post-types.php:252
173
+ msgid "WP RSS Aggregator Help"
174
+ msgstr "Aiuto WP RSS Aggregator"
175
+
176
+ #: inc/custom-post-types.php:261
177
+ msgid "Like this plugin?"
178
+ msgstr "Ti piace questo plugin?"
179
+
180
+ #: inc/custom-post-types.php:270
181
+ msgid "Follow us"
182
+ msgstr "Seguici"
183
+
184
+ #: inc/custom-post-types.php:279
185
+ msgid "Feed Source Details"
186
+ msgstr "Dettagli sorgente feed"
187
+
188
+ #: inc/custom-post-types.php:288
189
+ msgid "Feed Preview"
190
+ msgstr "Anteprima Feed"
191
+
192
+ #: inc/custom-post-types.php:307
193
+ msgid "Enter feed URL (including http://)"
194
+ msgstr "Inserisci l'URL del feed (includi http://)"
195
+
196
+ #: inc/custom-post-types.php:314
197
+ msgid "A short description about this feed source (optional)"
198
+ msgstr "Una breve descrizione di questa sorgente feed (opzionale)"
199
+
200
+ #: inc/custom-post-types.php:438
201
+ msgid "Delete Permanently"
202
+ msgstr "Elimina permanentemente"
203
+
204
+ #: inc/custom-post-types.php:440
205
+ msgid "Move to Trash"
206
+ msgstr "Sposta nel cestino"
207
+
208
+ #: inc/custom-post-types.php:471
209
+ msgid ""
210
+ "<strong>Invalid feed URL</strong> - Double check the feed source URL setting "
211
+ "above."
212
+ msgstr ""
213
+ "<strong>URL del feed non valido</strong> - Ricontrolla l'URL della sorgente "
214
+ "del feed nelle impostazioni sopra."
215
+
216
+ #: inc/custom-post-types.php:474
217
+ msgid "No feed URL defined yet"
218
+ msgstr "Nessun URL del feed ancora definito"
219
+
220
+ #: inc/custom-post-types.php:486
221
+ msgid "Need help?"
222
+ msgstr "Hai bisogno di aiuto?"
223
+
224
+ #: inc/custom-post-types.php:488
225
+ msgid "Check out the support forum"
226
+ msgstr "Controlla il forum di supporto"
227
+
228
+ #: inc/custom-post-types.php:499
229
+ msgid "Why not do any or all of the following"
230
+ msgstr "Perchè non fare alcuna o tutte delle seguenti cose"
231
+
232
+ #: inc/custom-post-types.php:501
233
+ msgid "Give it a 5 star rating on WordPress.org."
234
+ msgstr "Dare 5 stelle su WordPress.org"
235
+
236
+ #: inc/custom-post-types.php:502
237
+ msgid "Donate a token of your appreciation."
238
+ msgstr "Donare una moneta come ringraziamento."
239
+
240
+ #: inc/custom-post-types.php:517
241
+ msgid "Follow WP Mayor on Twitter."
242
+ msgstr "Segui WP Mayor su Twitter"
243
+
244
+ #: inc/custom-post-types.php:518
245
+ msgid "Like WP Mayor on Facebook."
246
+ msgstr "Segui WP Mayor su Facebook"
247
+
248
+ #: inc/custom-post-types.php:535
249
+ msgid "Feed source updated. "
250
+ msgstr "Sorgente feed aggiornata."
251
+
252
+ #: inc/custom-post-types.php:536
253
+ msgid "Custom field updated."
254
+ msgstr "Campo personalizzato aggiornato."
255
+
256
+ #: inc/custom-post-types.php:537
257
+ msgid "Custom field deleted."
258
+ msgstr "Campo personalizzato cancellato."
259
+
260
+ #: inc/custom-post-types.php:538 inc/custom-post-types.php:544
261
+ msgid "Feed source updated."
262
+ msgstr "Sorgente feed aggiornata."
263
+
264
+ #: inc/custom-post-types.php:540 inc/custom-post-types.php:541
265
+ msgid "Feed source saved."
266
+ msgstr "Sorgente feed salvata."
267
+
268
+ #: inc/custom-post-types.php:542
269
+ msgid "Feed source submitted."
270
+ msgstr "Sorgente feed inviata."
271
+
272
+ #: inc/custom-post-types.php:628
273
+ msgid "Publish Feed"
274
+ msgstr "Pubblica Feed"
readme.txt ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === WP RSS Aggregator ===
2
+ Contributors: jeangalea
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=X9GP6BL4BLXBJ
4
+ Plugin URI: http://www.wprssaggregator.com
5
+ Tags: rss, feeds, aggregation, aggregator, import, feed aggregator, rss aggregator, multiple rss feeds, multi rss feeds, multi rss, rss import, feed import, feed import, multiple feed import, feed aggregation, rss feader, feed reader, feed to post, multiple feeds, multi feed importer, multi feed import, multi import, autoblog, autoblogging, autoblogger
6
+ Requires at least: 3.3
7
+ Tested up to: 3.7.1
8
+ Stable tag: 3.5.2
9
+ License: GPLv2 or later
10
+ Imports and aggregates multiple RSS Feeds using SimplePie. Outputs feeds sorted by date (latest first).
11
+
12
+
13
+ == Description ==
14
+
15
+ WP RSS Aggregator is the most comprehensive and elegant RSS feed solution for WordPress.
16
+
17
+ The original plugin for importing, merging and displaying RSS and Atom feeds on your WordPress site.
18
+
19
+ With WP RSS Aggregator, you can:
20
+
21
+ * Display feeds from one or more sites on your blog
22
+ * Aggregate feeds from multiple sites
23
+
24
+ You can add any number of feeds through an administration panel, the plugin will then pull feed items from these sites, merge them and display them in date order.
25
+
26
+ To display your imported feed items, you can use a shortcode or call the display function directly from within your theme.
27
+
28
+ __More Features__:
29
+
30
+ * Export a custom RSS feed based on your feed sources
31
+ * Pagination
32
+ * Set the feed import time interval
33
+ * Various shortcode parameters you can use to further customize the output
34
+ * Choose whether to show/hide sources and dates
35
+ * Choose the date format
36
+ * Set the links as no-follow or not, or add no follow to meta tag
37
+ * Select how you would like the links to open (in a Lightbox, a new window, or the current window)
38
+ * Set the name of the feed source
39
+ * Select number of posts per feed you want to show and store
40
+ * Opens YouTube, DailyMotion and Vimeo videos directly
41
+ * Limit number of feed items stored in the database
42
+ * Feed autodiscovery, which lets you add feeds without even knowing the exact URL.
43
+ * Extendable via action and filter hooks
44
+ * Integrated with the Simplepie library that come with WordPress. This includes RSS 0.91 and RSS 1.0 formats, the popular RSS 2.0 format, Atom etc.
45
+
46
+ = Premium Add-Ons =
47
+ Add-Ons that add more functionality to the core plugin are now [available for purchase](http://www.wprssaggregator.com/extensions/).
48
+
49
+ * [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) - an advanced importer that lets you import feeds into post or custom post types. Populate a website in minutes (autoblog).
50
+ * [Keyword Filtering](http://www.wprssaggregator.com/extensions/keyword-filtering) - filter imported feeds based on keywords, so you only get items you're interested in.
51
+ * [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) - display excerpts and thumbnails together with the title, date and source.
52
+ * [Categories](http://www.wprssaggregator.com/extensions/categories) - categorise your feed sources and display items from a particular category at will within your site.
53
+
54
+ = Demo =
55
+ The plugin can be seen in use on the [demo page](http://www.wprssaggregator.com/demo/).
56
+
57
+ = Video Walkthrough =
58
+ [youtube http://www.youtube.com/watch?v=5J-S2vXtQ5w]
59
+
60
+ = Documentation =
61
+ Instructions for plugin usage are available on the plugin's [documentation page](http://www.wprssaggregator.com/documentation/).
62
+
63
+ = Credit =
64
+ Created by Jean Galea from [WP Mayor](http://www.wpmayor.com)
65
+
66
+ = Technical Stuff =
67
+ WP RSS Aggregator uses the SimplePie class to import and handle feeds, and stores all feed sources and feed items as custom post types in the WordPress default table structure, thus no custom tables are added.
68
+
69
+ = Translations =
70
+ Italian - Davide De Maestri
71
+
72
+
73
+ == Installation ==
74
+
75
+ 1. Upload the `wp-rss-aggregator` folder to the `/wp-content/plugins/` directory
76
+ 2. Activate the WP RSS Aggregator plugin through the 'Plugins' menu in WordPress
77
+ 3. Configure the plugin by going to the `RSS Aggregator` menu item that appears in your dashboard menu.
78
+ 3. Use the shortcode in your posts or pages: `[wp-rss-aggregator]`
79
+
80
+ The parameters accepted are:
81
+
82
+ * links_before
83
+ * links_after
84
+ * link_before
85
+ * link_after
86
+ * limit
87
+ * source
88
+
89
+ An example of a shortcode with parameters:
90
+ `[wp_rss_aggregator link_before='<li class="feed-link">' link_after='</li>']`
91
+ It is advisable to use the 'HTML' view of the editor when inserting the shortcode with paramters.
92
+
93
+ __Usage within theme files__
94
+
95
+ An example of a function call from within the theme's files:
96
+ `
97
+ <?php
98
+ wprss_display_feed_items( $args = array(
99
+ 'links_before' => '<ul>',
100
+ 'links_after' => '</ul>',
101
+ 'link_before' => '<li>',
102
+ 'link_after' => '</li>',
103
+ 'limit' => '8',
104
+ 'source' => '5,9'
105
+ ));
106
+ ?>
107
+ `
108
+
109
+ OR
110
+
111
+ `<?php do_shortcode('[wp-rss-aggregator]'); ?>`
112
+
113
+
114
+ == Frequently Asked Questions ==
115
+ = How can I output the feeds in my theme? =
116
+
117
+ You can either call the function directly within the theme:
118
+ `<?php wprss_display_feed_items(); ?>`
119
+
120
+ Or use the shortcode in your posts and pages:
121
+ [wp-rss-aggregator]
122
+
123
+ = Can I store imported feed items as posts? =
124
+
125
+ You can do that with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on. You will not only be able to store items as posts, but also as other custom post types, as well as set the author, auto set tags and categories, and much more.
126
+
127
+ = Some RSS feeds only give a short excerpt, any way around that? =
128
+
129
+ Yes, within the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on we have an advanced feature that can get the full content of those feeds that only supply a short excerpt.
130
+
131
+
132
+ == Screenshots ==
133
+
134
+ 1. The output of this plugin on the frontend.
135
+
136
+ 2. The output from the aggregator with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) add-on installed.
137
+
138
+ 3. Adding a new feed source.
139
+
140
+ 4. Imported feeds.
141
+
142
+ 5. Plugin settings page.
143
+
144
+
145
+ == Changelog ==
146
+
147
+ = 3.5.2 (2013-11-11) =
148
+ * Fixed bug: Invalid feed source url was producing an Undefined method notice.
149
+ * Fixed bug: Custom feed was producing a 404 page.
150
+ * Fixed bug: Presstrends code firing on admin_init, opt-in implementation coming soon
151
+
152
+ = 3.5.1 (2013-11-09) =
153
+ * Enhanced: Increased compatibility with RSS sources.
154
+ * Fixed bug: Pagination not working on home page
155
+
156
+ = 3.5 (2013-11-6) =
157
+ * New Feature: Can delete feed items for a particular source
158
+ * Enhanced: the 'Fetch feed items' row action for feed sources resets itself after 3.5 seconds.
159
+ * Enhanced: The feed image is saved for each url.
160
+ * Fixed bug: Link to source now links to correct url. Previously linked to site's feed.
161
+
162
+ = 3.4.6 (2013-11-1) =
163
+ * Enhanced: Added more hooks to debugging page for the Feed to Post add-on.
164
+ * Fixed bug: Uninitialized loop index
165
+
166
+ = 3.4.5 (2013-10-30) =
167
+ * Bug Fix: Feed items were not being imported while the WPML plugin was active.
168
+
169
+ = 3.4.4 (2013-10-26) =
170
+ * New feature: Pagination
171
+ * New feature: First implementation of editor button for easy shortcode creation
172
+ * Enhanced: Feed items and sources don't show up in link manager
173
+ * Enhanced: Included Presstrends code for plugin usage monitoring
174
+
175
+ = 3.4.3 (2013-10-20) =
176
+ * Fixed bug: Removed anonymous functions for backwards PHP compatibility
177
+ * Bug fix: Added suppress_filters in feed-display.php to prevent a user reported error
178
+ * Bug fix: Missing <li> in certain feed displays
179
+
180
+ = 3.4.2 (2013-9-19) =
181
+ * Enhanced: Added some hooks for Feed to Post compatibility
182
+ * Enhanced: Moved date settings to a more appropriate location
183
+
184
+ = 3.4.1 (2013-9-16) =
185
+ * Fixed Bug: Minor issue with options page - PHP notice
186
+
187
+ = 3.4 (2013-9-15) =
188
+ * New Feature: Saving/Updating a feed source triggers an update for that source's feed items.
189
+ * New Feature: Option to change Youtube, Vimeo and Dailymotion feed item URLs to embedded video players URLs
190
+ * New Feature: Facebook Pages URLs are automatically detected and changed into Atom Feed URLs using FB's Graph
191
+ * Enhanced: Updated jQuery Colorbox library to 1.4.29
192
+ * Fixed Bug: Some settings did not have a default value set, and were throwing an 'Undefined Index' error
193
+ * Fixed Bug: Admin notices do not disappear immediately when dismissed.
194
+
195
+ = Version 3.3.3 (2013-09-08) =
196
+ * Fixed bug: Better function handling on uninstall, should remove uninstall issues
197
+
198
+ = Version 3.3.2 (2013-09-07) =
199
+ * New feature: Added exclude parameter to shortcode
200
+ * Enhanced: Added metabox links to documentation and add-ons
201
+ * Fixed bug: Custom feed linking to post on user site rather than original source
202
+ * Fixed bug: Custom post types issues when activitating the plugin
203
+
204
+ = Version 3.3.1 (2013-08-09) =
205
+ * Fixed Bug: Roles and Capabilities file had not been included
206
+ * Fixed Bug: Error on install, function not found
207
+
208
+ = Version 3.3 (2013-08-08) =
209
+ * New feature: OPML importer
210
+ * New feature: Feed item limits for individual Feed Sources
211
+ * New feature: Custom feed URL
212
+ * New feature: Feed limit on custom feed
213
+ * New feature: New 'Fetch feed items' action for each Feed Source in listing display
214
+ * New feature: Option to enable link to source
215
+ * Enhanced: Date strings now change according to locale being used (i.e. compatible with WPML)
216
+ * Enhanced: Capabilities implemented
217
+ * Enhanced: Feed Sources row action 'View' removed
218
+ * Fixed Bug: Proxy feed URLs resulting in the permalink: example.com/url
219
+
220
+ = Version 3.2 (2013-07-06) =
221
+ * New feature: Parameter to limit number of feeds displayed
222
+ * New feature: Paramter to limit feeds displayed to particular sources (via ID)
223
+ * Enhanced: Better feed import handling to handle large number of feed sources
224
+
225
+ = Version 3.1.1 (2013-06-06) =
226
+ * Fixed bug: Incompatibility with some other plugins due to function missing namespace
227
+
228
+ = Version 3.1 (2013-06-06) =
229
+ * New feature: Option to set the number of feed items imported from every feed (default 5)
230
+ * New feature: Import and Export aggregator settings and feed sources
231
+ * New feature: Debugging page allowing manual feed refresh and feed reset
232
+ * Enhanced: Faster handling of restoring sources from trash when feed limit is 0
233
+ * Fixed bug: Limiter on number of overall feeds stored not working
234
+ * Fixed bug: Incompatibility issue with Foobox plugin fixed
235
+ * Fixed bug: Duplicate feeds sometimes imported
236
+
237
+ = Version 3.0 (2013-03-16) =
238
+ * New feature: Option to select cron frequency
239
+ * New feature: Code extensibility added to be compatible with add-ons
240
+ * New feature: Option to set a limit to the number of feeds stored (previously 50, hard coded)
241
+ * New feature: Option to define the format of the date shown below each feed item
242
+ * New feature: Option to show or hide source of feed item
243
+ * New feature: Option to show or hide publish date of feed item
244
+ * New feature: Option to set text preceding publish date
245
+ * New feature: Option to set text preceding source of feed item
246
+ * New feature: Option to link title or not
247
+ * New feature: Limit of 5 items imported for each source instead of 10
248
+ * Enhanced: Performance improvement when publishing * New feeds in admin
249
+ * Enhanced: Query tuning for better performance
250
+ * Enhanced: Major code rewrite, refactoring and inclusion of hooks
251
+ * Enhanced: Updated Colorbox to v1.4.1
252
+ * Enhanced: Better security implementations
253
+ * Enhanced: Better feed preview display
254
+ * Fixed bug: Deletion of items upon source deletion not working properly
255
+ * Requires: WordPress 3.3
256
+
257
+ = Version 2.2.3 (2012-11-01) =
258
+ * Fixed bug: Tab navigation preventing typing in input boxes
259
+ * Removed: Feeds showing up in internal linking pop up
260
+
261
+ = Version 2.2.2 (2012-10-30) =
262
+ * Removed: Feeds showing up in site search results
263
+ * Enhanced: Better tab button navigation when adding a new feed
264
+ * Enhanced: Better guidance when a feed URL is invalid
265
+
266
+ = Version 2.2.1 (2012-10-17) =
267
+ * Fixed bug: wprss_feed_source_order assumes everyone is an admin
268
+
269
+ = Version 2.2 (2012-10-01) =
270
+ * Italian translation added
271
+ * Feed source order changed to alphabetical
272
+ * Fixed bug - repeated entries when having a non-valid feed source
273
+ * Fixed bug - all imported feeds deleted upon trashing a single feed source
274
+
275
+ = Version 2.1 (2012-09-27) =
276
+ * Now localised for translations
277
+ * Fixed bug with date string
278
+ * Fixed $link_before and $link_after, now working
279
+ * Added backwards compatibility for wp_rss_aggregator() function
280
+
281
+ = Version 2.0 (2012-09-21) =
282
+ * Bulk of code rewritten and refactored
283
+ * Added install and upgrade functions
284
+ * Added DB version setting
285
+ * Feed sources now stored as Custom Post Types
286
+ * Feed source list sortable ascending or descending by name
287
+ * Removed days subsections in feed display
288
+ * Ability to limit total number of feeds displayed
289
+ * Feeds now fetched via Cron
290
+ * Cron job to delete old feed items, keeps max of 50 items in DB
291
+ * Now requires WordPress 3.2
292
+ * Updated colorbox to v1.3.20.1
293
+ * Limit of 15 items max imported for each source
294
+ * Fixed issue of page content displaying incorrectly after feeds
295
+
296
+ = Version 1.1 (2012-08-13) =
297
+ * Now requires WordPress 3.0
298
+ * More flexible fetching of images directory
299
+ * Has its own top level menu item
300
+ * Added settings section
301
+ * Ability to open in lightbox, new window or default browser behaviour
302
+ * Ability to set links as follow or no follow
303
+ * Using constants for oftenly used locations
304
+ * Code refactoring
305
+ * Changes in file and folder structure
306
+
307
+ = Version 1.0 (2012-01-06) =
308
+ * Initial release.
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file
templates/wprss.css ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * WP RSS Aggregator Styles
3
+ *
4
+ * @package WP RSS Aggregator
5
+ * @subpackage CSS
6
+ * @copyright Copyright (c) 2013, Jean Galea
7
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
+ */
9
+
uninstall.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // If uninstall not called from WordPress exit
3
+ if( ! defined( 'WP_UNINSTALL_PLUGIN' ) )
4
+ exit ();
5
+
6
+ // Remove capabilities
7
+ if ( function_exists( 'wprss_remove_caps' ) )
8
+ wprss_remove_caps();
9
+
10
+ // Delete option from options table
11
+ delete_option( 'wprss_options' );
12
+ delete_option( 'wprss_settings' );
13
+ delete_option( 'wprss_settings_general' );
14
+ delete_option( 'wprss_db_version' );
15
+ delete_option( 'wprss_settings_notices' );
wp-rss-aggregator.php ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: WP RSS Aggregator
4
+ Plugin URI: http://www.wprssaggregator.com
5
+ Description: Imports and aggregates multiple RSS Feeds using SimplePie
6
+ Version: 3.5.2
7
+ Author: Jean Galea
8
+ Author URI: http://www.wprssaggregator.com
9
+ License: GPLv2
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
+ */
12
+
13
+ /*
14
+ Copyright 2012-2013 Jean Galea (email : info@jeangalea.com)
15
+ This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License as published by
17
+ the Free Software Foundation; either version 2 of the License, or
18
+ (at your option) any later version.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program; if not, write to the Free Software
27
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
+ */
29
+
30
+ /**
31
+ * @package WPRSSAggregator
32
+ * @version 3.5.2
33
+ * @since 1.0
34
+ * @author Jean Galea <info@jeangalea.com>
35
+ * @copyright Copyright (c) 2012-2013, Jean Galea
36
+ * @link http://www.wpmayor.com/
37
+ * @license http://www.gnu.org/licenses/gpl.html
38
+ */
39
+
40
+ /**
41
+ * Define constants used by the plugin.
42
+ */
43
+
44
+ // Set the version number of the plugin.
45
+ if( !defined( 'WPRSS_VERSION' ) )
46
+ define( 'WPRSS_VERSION', '3.5.2', true );
47
+
48
+ // Set the database version number of the plugin.
49
+ if( !defined( 'WPRSS_DB_VERSION' ) )
50
+ define( 'WPRSS_DB_VERSION', 10 );
51
+
52
+ // Set the plugin prefix
53
+ if( !defined( 'WPRSS_PREFIX' ) )
54
+ define( 'WPRSS_PREFIX', 'wprss', true );
55
+
56
+ // Set constant path to the plugin directory.
57
+ if( !defined( 'WPRSS_DIR' ) )
58
+ define( 'WPRSS_DIR', plugin_dir_path( __FILE__ ) );
59
+
60
+ // Set constant URI to the plugin URL.
61
+ if( !defined( 'WPRSS_URI' ) )
62
+ define( 'WPRSS_URI', plugin_dir_url( __FILE__ ) );
63
+
64
+ // Set the constant path to the plugin's javascript directory.
65
+ if( !defined( 'WPRSS_JS' ) )
66
+ define( 'WPRSS_JS', WPRSS_URI . trailingslashit( 'js' ), true );
67
+
68
+ // Set the constant path to the plugin's CSS directory.
69
+ if( !defined( 'WPRSS_CSS' ) )
70
+ define( 'WPRSS_CSS', WPRSS_URI . trailingslashit( 'css' ), true );
71
+
72
+ // Set the constant path to the plugin's images directory.
73
+ if( !defined( 'WPRSS_IMG' ) )
74
+ define( 'WPRSS_IMG', WPRSS_URI . trailingslashit( 'images' ), true );
75
+
76
+ // Set the constant path to the plugin's includes directory.
77
+ if( !defined( 'WPRSS_INC' ) )
78
+ define( 'WPRSS_INC', WPRSS_DIR . trailingslashit( 'includes' ), true );
79
+
80
+
81
+ /**
82
+ * Load required files.
83
+ */
84
+
85
+ /* Load install, upgrade and migration code. */
86
+ require_once ( WPRSS_INC . 'update.php' );
87
+
88
+ /* Load the shortcodes functions file. */
89
+ require_once ( WPRSS_INC . 'shortcodes.php' );
90
+
91
+ /* Load the custom post types and taxonomies. */
92
+ require_once ( WPRSS_INC . 'custom-post-types.php' );
93
+
94
+ /* Load the file for setting capabilities of our post types */
95
+ require_once ( WPRSS_INC . 'roles-capabilities.php' );
96
+
97
+ /* Load the feed processing functions file */
98
+ require_once ( WPRSS_INC . 'feed-processing.php' );
99
+
100
+ /* Load the feed display functions file */
101
+ require_once ( WPRSS_INC . 'feed-display.php' );
102
+
103
+ /* Load the custom feed file */
104
+ require_once ( WPRSS_INC . 'custom-feed.php' );
105
+
106
+ /* Load the cron job scheduling functions. */
107
+ require_once ( WPRSS_INC . 'cron-jobs.php' );
108
+
109
+ /* Load the admin functions file. */
110
+ require_once ( WPRSS_INC . 'admin.php' );
111
+
112
+ /* Load the admin options functions file. */
113
+ require_once ( WPRSS_INC . 'admin-options.php' );
114
+
115
+ /* Load the settings import/export file */
116
+ require_once ( WPRSS_INC . 'admin-import-export.php' );
117
+
118
+ /* Load the debugging file */
119
+ require_once ( WPRSS_INC . 'system-info.php' );
120
+
121
+ /* Load the miscellaneous functions file */
122
+ require_once ( WPRSS_INC . 'misc-functions.php' );
123
+
124
+ /* Load the OPML Class file */
125
+ require_once ( WPRSS_INC . 'opml.php' );
126
+
127
+ /* Load the OPML Importer file */
128
+ require_once ( WPRSS_INC . 'opml-importer.php' );
129
+
130
+ /* Load the system info file */
131
+ require_once ( WPRSS_INC . 'admin-debugging.php' );
132
+
133
+ /* Load the admin display-related functions */
134
+ require_once ( WPRSS_INC . 'admin-display.php' );
135
+
136
+ /* Load the admin metaboxes functions */
137
+ require_once ( WPRSS_INC . 'admin-metaboxes.php' );
138
+
139
+ /* Load the scripts loading functions file */
140
+ require_once ( WPRSS_INC . 'scripts.php' );
141
+
142
+ /* Load the Ajax notification file */
143
+ require_once ( WPRSS_INC . 'admin-ajax-notice.php' );
144
+
145
+ /* Load the dashboard welcome screen file */
146
+ require_once ( WPRSS_INC . 'admin-dashboard.php' );
147
+
148
+ /* Load the logging class */
149
+ require_once ( WPRSS_INC . 'roles-capabilities.php' );
150
+
151
+ /* Load the logging class */
152
+ require_once ( WPRSS_INC . 'libraries/WP_Logging.php' );
153
+ require_once ( WPRSS_INC . 'admin-editor.php' );
154
+
155
+
156
+ register_activation_hook( __FILE__ , 'wprss_activate' );
157
+ register_deactivation_hook( __FILE__ , 'wprss_deactivate' );
158
+
159
+
160
+ add_action( 'init', 'wprss_init' );
161
+ /**
162
+ * Initialise the plugin
163
+ *
164
+ * @since 1.0
165
+ * @return void
166
+ */
167
+ function wprss_init() {
168
+ do_action( 'wprss_init' );
169
+ }
170
+
171
+
172
+ /**
173
+ * Plugin activation procedure
174
+ *
175
+ * @since 1.0
176
+ * @return void
177
+ */
178
+ function wprss_activate() {
179
+ /* Prevents activation of plugin if compatible version of WordPress not found */
180
+ if ( version_compare( get_bloginfo( 'version' ), '3.3', '<' ) ) {
181
+ deactivate_plugins ( basename( __FILE__ )); // Deactivate plugin
182
+ wp_die( __( 'This plugin requires WordPress version 3.3 or higher.' ), 'WP RSS Aggregator', array( 'back_link' => true ) );
183
+ }
184
+ wprss_settings_initialize();
185
+ flush_rewrite_rules();
186
+ wprss_schedule_fetch_all_feeds_cron();
187
+
188
+ // Get the previous welcome screen version
189
+ $pwsv = get_option( 'wprss_pwsv', '0.0' );
190
+ // If the aggregator version is higher than the previous version ...
191
+ if ( version_compare( WPRSS_VERSION, $pwsv, '>' ) ) {
192
+ // Sets a transient to trigger a redirect upon completion of activation procedure
193
+ set_transient( '_wprss_activation_redirect', true, 30 );
194
+ }
195
+ }
196
+
197
+
198
+ /**
199
+ * Plugin deactivation procedure
200
+ *
201
+ * @since 1.0
202
+ */
203
+ function wprss_deactivate() {
204
+ // on deactivation remove the cron job
205
+ if ( wp_next_scheduled( 'wprss_fetch_all_feeds_hook' ) ) {
206
+ wp_clear_scheduled_hook( 'wprss_fetch_all_feeds_hook' );
207
+ }
208
+ flush_rewrite_rules();
209
+ }
210
+
211
+
212
+ add_action( 'plugins_loaded', 'wprss_load_textdomain' );
213
+ /**
214
+ * Loads the plugin's translated strings.
215
+ *
216
+ * @since 2.1
217
+ * @return void
218
+ */
219
+ function wprss_load_textdomain() {
220
+ load_plugin_textdomain( 'wprss', false, plugin_dir_path( __FILE__ ) . '/languages/' );
221
+ }
222
+
223
+
224
+ // PressTrends WordPress Action
225
+ //add_action( 'admin_init', 'wprss_presstrends_plugin' );
226
+ /**
227
+ * Track plugin usage using PressTrends
228
+ *
229
+ * @since 3.5
230
+ * @return void
231
+ */
232
+ function wprss_presstrends_plugin() {
233
+ // PressTrends Account API Key
234
+ $api_key = 'znggu7vk7x2ddsiigkerzsca9q22xu1j53hp';
235
+ $auth = 'd8giw5yyux4noasmo8gua98n7fv2hrl11';
236
+ // Start of Metrics
237
+ global $wpdb;
238
+ $data = get_transient( 'presstrends_cache_data' );
239
+ if ( !$data || $data == '' ) {
240
+ $api_base = 'http://api.presstrends.io/index.php/api/pluginsites/update?auth=';
241
+ $url = $api_base . $auth . '&api=' . $api_key . '';
242
+ $count_posts = wp_count_posts();
243
+ $count_pages = wp_count_posts( 'page' );
244
+ $comments_count = wp_count_comments();
245
+ if ( function_exists( 'wp_get_theme' ) ) {
246
+ $theme_data = wp_get_theme();
247
+ $theme_name = urlencode( $theme_data->Name );
248
+ } else {
249
+ $theme_data = get_theme_data( get_stylesheet_directory() . '/style.css' );
250
+ $theme_name = $theme_data['Name'];
251
+ }
252
+ $plugin_name = '&';
253
+ foreach ( get_plugins() as $plugin_info ) {
254
+ $plugin_name .= $plugin_info['Name'] . '&';
255
+ }
256
+ // CHANGE __FILE__ PATH IF LOCATED OUTSIDE MAIN PLUGIN FILE
257
+ $plugin_data = get_plugin_data( __FILE__ );
258
+ $posts_with_comments = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type='post' AND comment_count > 0" );
259
+ $data = array(
260
+ 'url' => base64_encode(site_url()),
261
+ 'posts' => $count_posts->publish,
262
+ 'pages' => $count_pages->publish,
263
+ 'comments' => $comments_count->total_comments,
264
+ 'approved' => $comments_count->approved,
265
+ 'spam' => $comments_count->spam,
266
+ 'pingbacks' => $wpdb->get_var( "SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_type = 'pingback'" ),
267
+ 'post_conversion' => ( $count_posts->publish > 0 && $posts_with_comments > 0 ) ? number_format( ( $posts_with_comments / $count_posts->publish ) * 100, 0, '.', '' ) : 0,
268
+ 'theme_version' => $plugin_data['Version'],
269
+ 'theme_name' => $theme_name,
270
+ 'site_name' => str_replace( ' ', '', get_bloginfo( 'name' ) ),
271
+ 'plugins' => count( get_option( 'active_plugins' ) ),
272
+ 'plugin' => urlencode( $plugin_name ),
273
+ 'wpversion' => get_bloginfo( 'version' ),
274
+ );
275
+ foreach ( $data as $k => $v ) {
276
+ $url .= '&' . $k . '=' . $v . '';
277
+ }
278
+ wp_remote_get( $url );
279
+ set_transient( 'presstrends_cache_data', $data, 60 * 60 * 24 );
280
+ }
281
+ }