PluginProbe
Share a Draft / 1.4
Share a Draft v1.4
1.7 trunk 0.2 0.3 0.4 0.5 0.6 0.7 1.0 1.1 1.2 1.3 1.4 1.5 1.6
shareadraft / shareadraft.php

shareadraft.php in Share a Draft 1.4, at shareadraft.php

420 lines 12.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Share a Draft
4 Plugin URI: http://wordpress.org/extend/plugins/shareadraft/
5 Description: Let your friends preview one of your drafts, without giving them permissions to edit posts in your blog.
6 Author: Nikolay Bachiyski
7 Version: 1.4
8 Author URI: http://nikolay.bg/
9 Text Domain: shareadraft
10 Generated At: www.wp-fun.co.uk;
11 */
12
13 if (!class_exists('ShareADraft')):
14 class ShareADraft {
15 var $admin_options_name = "ShareADraft_options";
16
17 function __construct(){
18 add_action('init', array($this, 'init'));
19 }
20
21 function init() {
22 global $current_user;
23 add_action('admin_menu', array($this, 'add_admin_pages'));
24 add_filter('the_posts', array($this, 'the_posts_intercept'));
25 add_filter('posts_results', array($this, 'posts_results_intercept'));
26
27 $this->admin_options = $this->get_admin_options();
28 $this->admin_options = $this->clear_expired($this->admin_options);
29 $this->user_options = ($current_user->id > 0 && isset($this->admin_options[$current_user->id]))? $this->admin_options[$current_user->id] : array();
30
31 $this->save_admin_options();
32 load_plugin_textdomain('shareadraft', PLUGINDIR . '/shareadraft/languages');
33
34 if (isset($_GET['page']) && $_GET['page'] == plugin_basename(__FILE__))
35 $this->admin_page_init();
36 }
37
38 function admin_page_init() {
39 wp_enqueue_script('jquery');
40 add_action('admin_head', array($this, 'print_admin_css'));
41 add_action('admin_head', array($this, 'print_admin_js'));
42 }
43
44 function get_admin_options() {
45 $saved_options = get_option($this->admin_options_name);
46 return is_array($saved_options)? $saved_options : array();
47 }
48
49 function save_admin_options(){
50 global $current_user;
51 if ($current_user->id > 0) {
52 $this->admin_options[$current_user->id] = $this->user_options;
53 }
54 update_option($this->admin_options_name, $this->admin_options);
55 }
56
57 function clear_expired($all_options) {
58 $all = array();
59 foreach($all_options as $user_id => $options) {
60 $shared = array();
61 if (!isset($options['shared']) || !is_array($options['shared'])) {
62 continue;
63 }
64 foreach($options['shared'] as $share) {
65 if ($share['expires'] < time()) {
66 continue;
67 }
68 $shared[] = $share;
69 }
70 $options['shared'] = $shared;
71 $all[$user_id] = $options;
72 }
73 return $all;
74 }
75
76 function add_admin_pages(){
77 add_submenu_page("edit.php", __('Share a Draft', 'shareadraft'), __('Share a Draft', 'shareadraft'),
78 'edit_posts', __FILE__, array($this, 'output_existing_menu_sub_admin_page'));
79 }
80
81 function calculate_seconds($params) {
82 $exp = 60;
83 $multiply = 60;
84 if (isset($params['expires']) && ($e = intval($params['expires']))) {
85 $exp = $e;
86 }
87 $mults = array('s' => 1, 'm' => 60, 'h' => 3600, 'd' => 24*3600);
88 if (isset($params['measure']) && isset($mults[$params['measure']])) {
89 $multiply = $mults[$params['measure']];
90 }
91 return $exp * $multiply;
92 }
93
94 function process_post_options($params) {
95 global $current_user;
96 if (isset($params['post_id'])) {
97 $p = get_post($params['post_id']);
98 if (!$p) {
99 return __('There is no such post!', 'shareadraft');
100 }
101 if ('publish' == get_post_status($p)) {
102 return __('The post is published!', 'shareadraft');
103 }
104 $this->user_options['shared'][] = array('id' => $p->ID,
105 'expires' => time() + $this->calculate_seconds($params),
106 'key' => uniqid('baba'.$p->ID.'_'));
107 $this->save_admin_options();
108 }
109 }
110
111 function process_delete($params) {
112 if (!isset($params['key']) ||
113 !isset($this->user_options['shared']) ||
114 !is_array($this->user_options['shared'])) {
115 return '';
116 }
117 $shared = array();
118 foreach($this->user_options['shared'] as $share) {
119 if ($share['key'] == $params['key']) {
120 continue;
121 }
122 $shared[] = $share;
123 }
124 $this->user_options['shared'] = $shared;
125 $this->save_admin_options();
126 }
127
128 function process_extend($params) {
129 if (!isset($params['key']) ||
130 !isset($this->user_options['shared']) ||
131 !is_array($this->user_options['shared'])) {
132 return '';
133 }
134 $shared = array();
135 foreach($this->user_options['shared'] as $share) {
136 if ($share['key'] == $params['key']) {
137 $share['expires'] += $this->calculate_seconds($params);
138 }
139 $shared[] = $share;
140 }
141 $this->user_options['shared'] = $shared;
142 $this->save_admin_options();
143 }
144
145 function get_drafts() {
146 global $current_user;
147 $my_drafts = get_users_drafts($current_user->id);
148 $my_scheduled = $this->get_users_future($current_user->id);
149 $pending = get_others_pending($current_user->id);
150 $others_drafts = get_others_drafts($current_user->id);
151 $drafts_struct = array(
152 array(
153 __('Your Drafts:', 'shareadraft'),
154 count($my_drafts),
155 $my_drafts,
156 ),
157 array(
158 __('Your Scheduled Posts:', 'shareadraft'),
159 count($my_scheduled),
160 $my_scheduled,
161 ),
162 array(
163 __('Pending Review:', 'shareadraft'),
164 count($pending),
165 $pending,
166 ),
167 array(
168 __('Others&#8217; Drafts:', 'shareadraft'),
169 count($others_drafts),
170 $others_drafts,
171 ),
172 );
173 return $drafts_struct;
174 }
175
176 function get_users_future($user_id) {
177 global $wpdb;
178 $query = $wpdb->prepare("SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'future' AND post_author = %d ORDER BY post_modified DESC", $user_id);
179 return $wpdb->get_results( $query );
180 }
181
182 function get_shared() {
183 if (!isset($this->user_options['shared']) || !is_array($this->user_options['shared'])) {
184 return array();
185 }
186 return $this->user_options['shared'];
187 }
188
189 function friendly_delta($s) {
190 $m = (int)($s/60);
191 $free_s = $s - $m*60;
192 $h = (int)($s/3600);
193 $free_m = (int)(($s - $h*3600)/60);
194 $d = (int)($s/(24*3600));
195 $free_h = (int)(($s - $d*(24*3600))/3600);
196 if ($m < 1) {
197 $res = array($s);
198 } elseif ($h < 1) {
199 $res = array($free_s, $m);
200 } elseif ($d < 1) {
201 $res = array($free_s, $free_m, $h);
202 } else {
203 $res = array($free_s, $free_m, $free_h, $d);
204 }
205 $names = array();
206 if (isset($res[0]))
207 $names[] = sprintf(__ngettext('%d second', '%d seconds', $res[0], 'shareadraft'), $res[0]);
208 if (isset($res[1]))
209 $names[] = sprintf(__ngettext('%d minute', '%d minutes', $res[1], 'shareadraft'), $res[1]);
210 if (isset($res[2]))
211 $names[] = sprintf(__ngettext('%d hour', '%d hours', $res[2], 'shareadraft'), $res[2]);
212 if (isset($res[3]))
213 $names[] = sprintf(__ngettext('%d day', '%d days', $res[3], 'shareadraft'), $res[3]);
214 return implode(', ', array_reverse($names));
215 }
216
217 function output_existing_menu_sub_admin_page(){
218 if (isset($_POST['shareadraft_submit'])) {
219 $msg = $this->process_post_options($_POST);
220 } elseif (isset($_POST['action']) && $_POST['action'] == 'extend') {
221 $msg = $this->process_extend($_POST);
222 } elseif (isset($_GET['action']) && $_GET['action'] == 'delete') {
223 $msg = $this->process_delete($_GET);
224 }
225 $drafts_struct = $this->get_drafts();
226 ?>
227 <div class="wrap">
228 <h2><?php _e('Share a Draft', 'shareadraft'); ?></h2>
229 <?php if ($msg):?>
230 <div id="message" class="updated fade"><?php echo $msg; ?></div>
231 <?php endif;?>
232 <h3><?php _e('Currently shared drafts', 'shareadraft'); ?></h3>
233 <table class="widefat">
234 <thead>
235 <tr>
236 <th><?php _e('ID', 'shareadraft'); ?></th>
237 <th><?php _e('Title', 'shareadraft'); ?></th>
238 <th><?php _e('Link', 'shareadraft'); ?></th>
239 <th><?php _e('Expires after', 'shareadraft'); ?></th>
240 <th colspan="2" class="actions"><?php _e('Actions', 'shareadraft'); ?></th>
241 </tr>
242 </thead>
243 <tbody>
244 <?php
245 $s = $this->get_shared();
246 foreach($s as $share):
247 $p = get_post($share['id']);
248 $url = get_bloginfo('url') . '/?p=' . $p->ID . '&shareadraft='. $share['key'];
249 ?>
250 <tr>
251 <td><?php echo $p->ID; ?></td>
252 <td><?php echo $p->post_title; ?></td>
253 <!-- TODO: make the draft link selecatble -->
254 <td><a href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $url ); ?></a></td>
255 <td><?php echo $this->friendly_delta($share['expires'] - time()); ?></td>
256 <td class="actions">
257 <a class="shareadraft-extend edit" id="shareadraft-extend-link-<?php echo $share['key']; ?>"
258 href="javascript:shareadraft.toggle_extend('<?php echo $share['key']; ?>');">
259 <?php _e('Extend', 'shareadraft'); ?>
260 </a>
261 <form class="shareadraft-extend" id="shareadraft-extend-form-<?php echo $share['key']; ?>"
262 action="" method="post">
263 <input type="hidden" name="action" value="extend" />
264 <input type="hidden" name="key" value="<?php echo $share['key']; ?>" />
265 <input type="submit" class="button" name="shareadraft_extend_submit"
266 value="<?php echo attribute_escape(__('Extend', 'shareadraft')); ?>"/>
267 <?php _e('by', 'shareadraft');?>
268 <?php echo $this->tmpl_measure_select(); ?>
269 <a class="shareadraft-extend-cancel"
270 href="javascript:shareadraft.cancel_extend('<?php echo $share['key']; ?>');">
271 <?php _e('Cancel', 'shareadraft'); ?>
272 </a>
273 </form>
274 </td>
275 <td class="actions">
276 <a class="delete" href="edit.php?page=<?php echo plugin_basename(__FILE__); ?>&amp;action=delete&amp;key=<?php echo $share['key']; ?>"><?php _e('Delete', 'shareadraft'); ?></a>
277 </td>
278 </tr>
279 <?php
280 endforeach;
281 if (empty($s)):
282 ?>
283 <tr>
284 <td colspan="5"><?php _e('No shared drafts!', 'shareadraft'); ?></td>
285 </tr>
286 <?php
287 endif;
288 ?>
289 </tbody>
290 </table>
291 <h3><?php _e('Share a Draft', 'shareadraft'); ?></h3>
292 <form id="shareadraft-share" action="" method="post">
293 <p>
294 <select id="shareadraft-postid" name="post_id">
295 <option value=""><?php _e('Choose a draft', 'shareadraft'); ?></option>
296 <?php
297 foreach($drafts_struct as $draft_type):
298 if ($draft_type[1]):
299 ?>
300 <option value="" disabled="disabled"></option>
301 <option value="" disabled="disabled"><?php echo $draft_type[0]; ?></option>
302 <?php
303 foreach($draft_type[2] as $draft):
304 if (empty($draft->post_title)) continue;
305 ?>
306 <option value="<?php echo $draft->ID?>"><?php echo wp_specialchars($draft->post_title); ?></option>
307 <?php
308 endforeach;
309 endif;
310 endforeach;
311 ?>
312 </select>
313 </p>
314 <p>
315 <input type="submit" class="button" name="shareadraft_submit"
316 value="<?php echo attribute_escape(__('Share it', 'shareadraft')); ?>" />
317 <?php _e('for', 'shareadraft'); ?>
318 <?php echo $this->tmpl_measure_select(); ?>.
319 </p>
320 </form>
321 </div>
322 <?php
323 }
324
325 function can_view($post_id) {
326 if (!isset($_GET['shareadraft']) || !is_array($this->admin_options)) {
327 return false;
328 }
329 foreach($this->admin_options as $option) {
330 if (!is_array($option) || !isset($option['shared'])) continue;
331 $shares = $option['shared'];
332 foreach($shares as $share) {
333 if ($share['id'] == $post_id && $share['key'] == $_GET['shareadraft']) {
334 return true;
335 }
336 }
337 }
338 return false;
339 }
340
341 function posts_results_intercept($posts) {
342 if (1 != count($posts)) return $posts;
343 $post = $posts[0];
344 $status = get_post_status($post);
345 if ('publish' != $status && $this->can_view($post->ID)) {
346 $this->shared_post = $post;
347 }
348 return $posts;
349 }
350
351 function the_posts_intercept($posts){
352 if (empty($posts) && !is_null($this->shared_post)) {
353 return array($this->shared_post);
354 } else {
355 $this->shared_post = null;
356 return $posts;
357 }
358 }
359
360 function tmpl_measure_select() {
361 $secs = __('seconds', 'shareadraft');
362 $mins = __('minutes', 'shareadraft');
363 $hours = __('hours', 'shareadraft');
364 $days = __('days', 'shareadraft');
365 return <<<SELECT
366 <input name="expires" type="text" value="2" size="4"/>
367 <select name="measure">
368 <option value="s">$secs</option>
369 <option value="m">$mins</option>
370 <option value="h" selected="selected">$hours</option>
371 <option value="d">$days</option>
372 </select>
373 SELECT;
374 }
375
376 function print_admin_css() {
377 ?>
378 <style type="text/css">
379 a.shareadraft-extend, a.shareadraft-extend-cancel { display: none; }
380 form.shareadraft-extend { white-space: nowrap; }
381 form.shareadraft-extend, form.shareadraft-extend input, form.shareadraft-extend select { font-size: 11px; }
382 th.actions, td.actions { text-align: center; }
383 </style>
384 <?php
385 }
386
387 function print_admin_js() {
388 ?>
389 <script type="text/javascript">
390 //<![CDATA[
391 (function($) {
392 $(function() {
393 $('form.shareadraft-extend').hide();
394 $('a.shareadraft-extend').show();
395 $('a.shareadraft-extend-cancel').show();
396 $('a.shareadraft-extend-cancel').css('display', 'inline');
397 });
398 window.shareadraft = {
399 toggle_extend: function(key) {
400 $('#shareadraft-extend-form-'+key).show();
401 $('#shareadraft-extend-link-'+key).hide();
402 $('#shareadraft-extend-form-'+key+' input[name="expires"]').focus();
403 },
404 cancel_extend: function(key) {
405 $('#shareadraft-extend-form-'+key).hide();
406 $('#shareadraft-extend-link-'+key).show();
407 }
408 };
409 })(jQuery);
410 //]]>
411 </script>
412 <?php
413 }
414 }
415 endif;
416
417 if (class_exists('ShareADraft')) {
418 $__share_a_draft = new ShareADraft();
419 }
420