557c3817 |
1 | <?php\r |
2 | /*\r |
3 | Plugin Name: danixland WPOrg Stats\r |
4 | Plugin URI: https://danix.xyz/?p=3745\r |
5 | Description: A simple plugin that shows useful stats about your plugins hosted on WordPress.org\r |
6 | Version: 0.1\r |
7 | Author: Danilo 'danix' Macri\r |
85e69c8e |
8 | Author URI: https://danix.xyz/author/danix\r |
557c3817 |
9 | Text Domain: dnxwporg\r |
10 | \r |
11 | This program is distributed in the hope that it will be useful,\r |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of\r |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r |
14 | */\r |
15 | \r |
16 | \r |
17 | /**\r |
18 | * Add plugin i18n domain: dnxwporg\r |
19 | * @since 0.1\r |
20 | */\r |
21 | load_plugin_textdomain('dnxwporg', plugins_url() . '/danixland-wporg-stats/i18n/', 'danixland-wporg-stats/i18n/');\r |
22 | \r |
23 | /**\r |
24 | * Function that installs our widget options\r |
25 | * @since 0.1\r |
26 | */\r |
27 | function dnxwporg_options_set() {\r |
28 | update_option( 'dnxwporg_author', 'danixland', '', 'yes' );\r |
29 | update_option( 'dnxwporg_plugins_stats', '', '', 'yes' );\r |
30 | update_option( 'dnxwporg_description', true, '', 'yes' );\r |
31 | update_option( 'dnxwporg_desc_content', '', '', 'yes' );\r |
32 | update_option( 'dnxwporg_linkto', true, '', 'yes' );\r |
33 | update_option( 'dnxwporg_use_icons', true, '', 'yes' );\r |
34 | }\r |
35 | \r |
36 | /**\r |
37 | * Function that deletes our widget options\r |
38 | * @since 0.1\r |
39 | */\r |
40 | function dnxwporg_options_unset() {\r |
41 | delete_option( 'dnxwporg_author' );\r |
42 | delete_option( 'dnxwporg_plugins_stats' );\r |
43 | delete_option( 'dnxwporg_description' );\r |
44 | delete_option( 'dnxwporg_desc_content' );\r |
45 | delete_option( 'dnxwporg_linkto' );\r |
46 | delete_option( 'dnxwporg_use_icons' );\r |
47 | }\r |
48 | \r |
49 | /**\r |
50 | * Add function on plugin activation that'll set our plugin options\r |
51 | * @since 0.1\r |
52 | */\r |
53 | register_activation_hook( __FILE__, 'dnxwporg_options_set' );\r |
54 | \r |
55 | /**\r |
56 | * Add function on plugin deactivation that'll unset our plugin options\r |
57 | * @since 0.3\r |
58 | */\r |
59 | register_deactivation_hook( __FILE__, 'dnxwporg_options_unset' );\r |
60 | \r |
61 | function dnxwporg_load_js($hook) {\r |
62 | // Load only on ?page=widgets.php\r |
63 | if($hook != 'widgets.php') {\r |
64 | return;\r |
65 | }\r |
66 | wp_enqueue_script( 'dnxwporg-utils-js', plugins_url('js/dnxwporg-utils.js', __FILE__), array('jquery'), false, true );\r |
67 | }\r |
68 | add_action( 'admin_enqueue_scripts', 'dnxwporg_load_js' );\r |
69 | \r |
70 | \r |
71 | /**\r |
72 | * Add function to retrieve the stats from api.wordpress.org\r |
73 | * @param $author - the plugin author nickname\r |
74 | * @return array - either the array with the info about the plugins or an empty array in case of failure\r |
75 | * @since 0.1\r |
76 | */\r |
77 | function dnxwporg_get_plugins_stats( $author ) {\r |
78 | $url = 'https://api.wordpress.org/plugins/info/1.0/';\r |
79 | $fields = array(\r |
80 | 'downloaded' => true,\r |
81 | 'rating' => false,\r |
82 | 'description' => false,\r |
83 | 'short_description' => false,\r |
84 | 'donate_link' => false,\r |
85 | 'tags' => false,\r |
86 | 'sections' => false,\r |
87 | 'homepage' => true,\r |
88 | 'added' => false,\r |
89 | 'last_updated' => false,\r |
90 | 'compatibility' => false,\r |
91 | 'tested' => false,\r |
92 | 'requires' => false,\r |
93 | 'downloadlink' => false,\r |
94 | );\r |
95 | $args = (object) array( 'author' => $author, 'fields' => $fields );\r |
96 | $request = array( 'action' => 'query_plugins', 'timeout' => 15, 'request' => serialize( $args) );\r |
97 | $response = wp_remote_post( $url, array( 'body' => $request ) );\r |
98 | $plugins_info = unserialize( $response['body'] );\r |
99 | $result = array();\r |
100 | $total_dl = '';\r |
101 | $total_avg = '';\r |
102 | if ( isset( $plugins_info ) ) {\r |
103 | # let's build our array of data to return\r |
104 | foreach ($plugins_info->plugins as $plugin) {\r |
105 | $pl_name = $plugin->slug;\r |
106 | $pl_dirlink = 'https://wordpress.org/plugins/' . $pl_name;\r |
107 | $pl_icon = 'https://ps.w.org/' . $pl_name . '/assets/icon-256x256.png';\r |
108 | $pl_download = $plugin->download_link;\r |
109 | $pl_downloaded = $plugin->downloaded;\r |
110 | $pl_home = $plugin->homepage;\r |
111 | $pl_voters = $plugin->num_ratings;\r |
112 | $pl_stars = $plugin->ratings;\r |
113 | $avg_vote = ($pl_stars[1] + $pl_stars[2] * 2 + $pl_stars[3] * 3 + $pl_stars[4] * 4 + $pl_stars[5] * 5) / $pl_voters;\r |
114 | $pl_avg_vote = ( ! is_int($avg_vote) ? 0 : $avg_vote );\r |
115 | $total_dl += $pl_downloaded;\r |
116 | $total_avg += $pl_avg_vote;\r |
117 | $result[$pl_name] = array(\r |
118 | 'dir_link' => $pl_dirlink,\r |
119 | 'dl_link' => $pl_download,\r |
120 | 'home_link' => $pl_home,\r |
121 | 'icon' => $pl_icon,\r |
122 | 'downloaded' => $pl_downloaded,\r |
123 | 'voters' => $pl_voters,\r |
124 | 'avg_rating' => $pl_avg_vote\r |
125 | );\r |
126 | }\r |
127 | $avg = $total_avg / count($plugins_info->plugins);\r |
128 | $result['total_plugins'] = count($plugins_info->plugins);\r |
129 | $result['total_downloads'] = $total_dl;\r |
130 | $result['average_rating'] = round( $avg, 2);\r |
131 | return $result;\r |
132 | }\r |
133 | return array();\r |
134 | }\r |
135 | \r |
136 | /**\r |
137 | * This function will execute with the scheduled cron job and update the data inside the option\r |
138 | * @since 0.1\r |
139 | */\r |
140 | function dnxwporg_save_plugins_stats() {\r |
141 | \r |
142 | $author = get_option('dnxwporg_author');\r |
143 | $plugins = dnxwporg_get_plugins_stats( $author );\r |
144 | update_option( 'dnxwporg_plugins_stats', $plugins );\r |
145 | }\r |
146 | add_action( 'dnxwporg_save_plugins_stats', 'dnxwporg_save_plugins_stats' );\r |
147 | \r |
148 | /**\r |
149 | * we schedule the cron if it's not yet scheduled\r |
150 | * @since 0.1\r |
151 | */\r |
152 | if ( ! wp_next_scheduled( 'dnxwporg_save_plugins_stats' ) ) {\r |
153 | wp_schedule_event( 1407110400, 'daily', 'dnxwporg_save_plugins_stats' ); // 1407110400 is 08 / 4 / 2014 @ 0:0:0 UTC\r |
154 | }\r |
155 | \r |
156 | /**\r |
157 | * Add function to widgets_init that'll load our widget.\r |
158 | * @since 0.1\r |
159 | */\r |
160 | add_action( 'widgets_init', 'danixland_wporg_widget' );\r |
161 | \r |
162 | /**\r |
163 | * Register our widget.\r |
164 | * 'dnx_WPOrg' is the widget class used below.\r |
165 | *\r |
166 | * @since 0.1\r |
167 | */\r |
168 | function danixland_wporg_widget() {\r |
169 | register_widget( 'dnx_WPOrg' );\r |
170 | }\r |
171 | \r |
172 | /**\r |
173 | * dnx_WPOrg class.\r |
174 | * This class handles everything that needs to be handled with the widget:\r |
175 | * the settings, form, display, and update. Nice!\r |
176 | *\r |
177 | * @since 0.1\r |
178 | */\r |
179 | class dnx_WPOrg extends WP_Widget {\r |
180 | \r |
181 | \r |
182 | /**\r |
183 | * Widget setup.\r |
184 | */\r |
185 | public function __construct() {\r |
186 | parent::__construct(\r |
187 | 'danixland-wporg-stats',\r |
188 | __( 'danixland WP.org Stats', 'dnxwporg' ),\r |
189 | array(\r |
190 | 'customize_selective_refresh' => true,\r |
191 | 'description' => __('Use this widget to display statistics about your WP.org hosted plugins on your site', 'dnxwporg'),\r |
192 | )\r |
193 | );\r |
194 | }\r |
195 | \r |
196 | /**\r |
197 | * Displays the setup form for the widget in the widgets page\r |
198 | */\r |
199 | public function form( $instance ) {\r |
200 | $defaults = array( \r |
201 | 'title' => __( 'WP.org Plugins Stats', 'dnxwporg' ),\r |
202 | 'author' => get_option( 'dnxwporg_author' ),\r |
203 | 'description' => get_option( 'dnxwporg_description' ),\r |
204 | 'desc_content' => get_option( 'dnxwporg_desc_content' ),\r |
205 | 'link_wporg' => get_option( 'dnxwporg_linkto' ),\r |
206 | 'use_icons' => get_option( 'dnxwporg_use_icons' )\r |
207 | );\r |
208 | $instance = wp_parse_args( (array) $instance, $defaults );\r |
209 | extract( $instance, EXTR_SKIP );\r |
210 | ?>\r |
211 | \r |
212 | <p>\r |
213 | <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'dnxwporg'); ?></label>\r |
214 | <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $title; ?>" style="width:100%;" />\r |
215 | </p>\r |
216 | <p>\r |
217 | <label for="<?php echo $this->get_field_id( 'author' ); ?>"><?php _e('The username of the Plugin\'s author on WP.org', 'dnxwporg'); ?></label>\r |
218 | <input type="text" class="widefat" id="<?php echo $this->get_field_id( 'author' ); ?>" name="<?php echo $this->get_field_name( 'author' ); ?>" value="<?php echo $author ?>" style="width:100%;" />\r |
219 | </p>\r |
220 | <p>\r |
221 | <input class="checkbox" type="checkbox" <?php checked( $description, true ); ?> id="dnxwporg_use_desc" name="<?php echo $this->get_field_name( 'description' ); ?>" />\r |
222 | <label for="<?php echo $this->get_field_id( 'description' ); ?>"><?php _e('Select this if you want to display a small description inside the widget.', 'dnxwporg'); ?></label>\r |
223 | <textarea id="dnxwporg_custom_desc" name="<?php echo $this->get_field_name( 'desc_content' ); ?>" rows="10" cols="30" <?php disabled( $description, false ); ?> /><?php echo $desc_content; ?></textarea>\r |
224 | <label for="<?php echo $this->get_field_id( 'desc_content' ); ?>"><?php _e('If active but empty, the standard plugin description will be used.', 'dnxwporg'); ?></label>\r |
225 | </p>\r |
226 | <p>\r |
227 | <input class="checkbox" type="checkbox" <?php checked( $link_wporg, true ); ?> id="<?php echo $this->get_field_id( 'link_wporg' ); ?>" name="<?php echo $this->get_field_name( 'link_wporg' ); ?>" />\r |
228 | <label for="<?php echo $this->get_field_id( 'link_wporg' ); ?>"><?php _e('If selected, your links will point to the WP.org plugin page, if not, the PLUGIN URI will be used instead.', 'dnxwporg'); ?></label>\r |
229 | </p>\r |
230 | <p>\r |
231 | <input class="checkbox" type="checkbox" <?php checked( $use_icons, true ); ?> id="<?php echo $this->get_field_id( 'use_icons' ); ?>" name="<?php echo $this->get_field_name( 'use_icons' ); ?>" />\r |
232 | <label for="<?php echo $this->get_field_id( 'use_icons' ); ?>"><?php _e('If selected, the widget will display the icon from the assets directory in your plugin svn folder.', 'dnxwporg'); ?></label>\r |
233 | </p>\r |
234 | <?php\r |
235 | }\r |
236 | \r |
237 | /**\r |
238 | * Update the widget content\r |
239 | */\r |
240 | public function update( $new_instance, $old_instance ) {\r |
241 | $instance = $old_instance;\r |
242 | \r |
243 | //Strip tags from title and name to remove HTML \r |
244 | $instance['title'] = sanitize_text_field( $new_instance['title'] );\r |
245 | $instance['author'] = strip_tags( $new_instance['author'] );\r |
246 | $instance['description'] = (bool) $new_instance['description'];\r |
247 | $instance['desc_content'] = sanitize_textarea_field( $new_instance['desc_content'] );\r |
248 | $instance['link_wporg'] = (bool) $new_instance['link_wporg'];\r |
249 | $instance['use_icons'] = (bool) $new_instance['use_icons'];\r |
250 | \r |
251 | update_option( 'dnxwporg_author', $instance['author'] );\r |
252 | if ($old_instance['author'] !== $new_instance['author']) {\r |
253 | update_option( 'dnxwporg_plugins_stats', dnxwporg_get_plugins_stats( $instance['author'] ) );\r |
254 | }\r |
255 | update_option( 'dnxwporg_linkto', $instance['link_wporg'] );\r |
256 | update_option( 'dnxwporg_use_icons', $instance['use_icons'] );\r |
257 | update_option( 'dnxwporg_description', $instance['description'] );\r |
258 | update_option( 'dnxwporg_desc_content', $instance['desc_content'] );\r |
259 | \r |
260 | return $instance;\r |
261 | }\r |
262 | \r |
263 | /**\r |
264 | * How to display the widget on the public side of the site.\r |
265 | */\r |
266 | public function widget( $args, $instance ) {\r |
267 | extract( $args );\r |
268 | \r |
269 | /* Our variables from the widget settings. */\r |
270 | $title = apply_filters('widget_title', $instance['title'] );\r |
271 | $author = sanitize_user(get_option('dnxwporg_author'), true);\r |
272 | $description = get_option('dnxwporg_description');\r |
273 | $desc_content = get_option('dnxwporg_desc_content');\r |
274 | $linkto = get_option('dnxwporg_linkto');\r |
275 | $use_icons = get_option('dnxwporg_use_icons');\r |
276 | \r |
277 | /* we recover the data from the option if it is set, otherwhise we call the retrieve function directly */\r |
278 | $option_stats = get_option('dnxwporg_plugins_stats');\r |
279 | $plugins = ( false === $option_stats ? dnxwporg_get_plugins_stats() : $option_stats );\r |
280 | \r |
281 | /* Before widget (defined by themes). */\r |
282 | echo $before_widget;\r |
283 | \r |
284 | /* Display the widget title if one was input (before and after defined by themes). */\r |
285 | if ( $title ) {\r |
286 | echo $before_title . $title . $after_title;\r |
287 | }\r |
288 | \r |
289 | ?>\r |
290 | <div class="dnxwporg_container">\r |
291 | <?php if ($description) { ?>\r |
292 | <div class="dnxwporg_description">\r |
293 | <?php if (empty($desc_content)) : ?>\r |
294 | <p class="dnxwporg-pl-standard-desc"><?php printf( _n('%s contributed <span class="dnxwporg-pl-count">%s</span> plugin with <span class="dnxwporg-pl-dloads">%s</span> total downloads and an average rating of <span class="dnxwporg-pl-avg-rating">%s</span>', '%s contributed <span class="dnxwporg-pl-count">%s</span> plugins with <span class="dnxwporg-pl-dloads">%s</span> total downloads and an average rating of <span class="dnxwporg-pl-avg-rating">%s</span>', $plugins['total_plugins'], 'dnxwporg' ), $author, $plugins['total_plugins'], $plugins['total_downloads'], $plugins['average_rating'] ); ?></p>\r |
295 | <?php else : ?>\r |
296 | <p class="dnxwporg-pl-custom-desc"><?php echo $desc_content; ?></p>\r |
297 | <?php endif; ?>\r |
298 | </div>\r |
299 | <?php } ?>\r |
300 | <div class="dnxwporg_pl_list_container">\r |
301 | <ul class="dnxwporg_pl_list">\r |
302 | <?php foreach ($plugins as $name => $data) { \r |
303 | if (is_array($data) ) : ?>\r |
304 | <li class="dnxwporg_pl_item">\r |
305 | <a class="dnxwporg-pl-link" href="<?php echo ($linkto ? $data['dir_link'] : $data['home_link']) ?>">\r |
306 | <?php if ($use_icons) : ?>\r |
307 | <img class="dnxwporg-pl-link-icon" src="<?php echo $data['icon']; ?>" alt="<?php echo $name; ?>">\r |
308 | <?php endif; ?>\r |
309 | <span class="dnxwporg-pl-link-name"><?php echo $name; ?></span>\r |
310 | </a>\r |
311 | <p class="dnxwporg-pl-stats">\r |
312 | <span class="dnxwporg-pl-tot-dloads"><?php echo $data['downloaded']; ?></span>\r |
313 | <span class="dnxwporg-pl-avg-vote"><?php echo $data['avg_rating']; ?></span>\r |
314 | </p>\r |
315 | </li>\r |
316 | <?php endif;\r |
317 | } ?>\r |
318 | </ul>\r |
319 | </div>\r |
320 | </div>\r |
321 | <?php\r |
322 | /* After widget (defined by themes). */\r |
323 | echo $after_widget;\r |
324 | }\r |
325 | }\r |
326 | \r |
327 | ?>\r |