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