bpModBackend

Controls and display the backend part of bp-moderation.

Defined (1)

The class is defined in the following location(s).

/classes/bpModBackend.php  
  1. class bpModBackend extends bpModeration 
  2.  
  3. /** 
  4. * bpModBackend constructor 
  5. * hooks in wordpress backend 
  6. */ 
  7. function __construct() 
  8. if (version_compare(get_site_option('bp_moderation_db_version'), $this->db_ver, '<')) { 
  9. bpModLoader::load_class('bpModInstaller'); 
  10. $installer = new bpModInstaller(); 
  11. $installer->install(); 
  12.  
  13. parent::__construct(); 
  14.  
  15. add_action(is_multisite() ? 'network_admin_menu' : 'admin_menu', array(&$this, 'add_admin_menu')); 
  16. add_action('admin_head', array(&$this, 'print_page_icon_style')); 
  17. add_action('rightnow_end', array(&$this, 'rightnow_widget_section')); 
  18. add_action('admin_init', array(&$this, 'register_settings')); 
  19.  
  20. if (isset($this->options['generate_test_data'])) { 
  21. unset($this->options['generate_test_data']); 
  22. update_site_option('bp_moderation_options', $this->options); 
  23. add_action('admin_init', array(bpModLoader, 'test_data')); 
  24.  
  25. /** 
  26. * Add aubmenu page and hooks css and js functions 
  27. */ 
  28. function add_admin_menu() 
  29. $hook = add_menu_page(__('BuddyPress Moderation', 'bp-moderation'), __('BP Moderation', 'bp-moderation'),  
  30. 'manage_options', 'bp-moderation', array(&$this, 'admin_page'), 'div'); 
  31.  
  32. add_action("admin_print_styles-$hook", array(&$this, 'admin_css')); 
  33. add_action("admin_print_scripts-$hook", array(&$this, 'admin_js')); 
  34.  
  35. function print_page_icon_style() 
  36. echo <<<HTML 
  37. <style> 
  38. ul#adminmenu li.toplevel_page_bp-moderation .wp-menu-image { 
  39. background-image: url('{$this->plugin_url}/css/sprite.png'); 
  40. background-position: 6px 5px; 
  41. ul#adminmenu li.toplevel_page_bp-moderation:hover .wp-menu-image,  
  42. ul#adminmenu li.toplevel_page_bp-moderation.current .wp-menu-image { 
  43. background-position: 6px -61px; 
  44. </style> 
  45. HTML; 
  46.  
  47. /** 
  48. * Add info on moderation queue in the rightnow widget 
  49. */ 
  50. function rightnow_widget_section() 
  51. if (!is_super_admin()) { 
  52. return; 
  53.  
  54. global $wpdb; 
  55.  
  56. $text = __('BP Moderation: ', 'bp-moderation'); 
  57.  
  58. $sql = "SELECT COUNT(*) FROM {$this->contents_table}"; 
  59.  
  60. if ($awating = (int)$wpdb->get_var("$sql WHERE status IN ('new', 'warned')")) { 
  61. $link = 'admin.php?page=bp-moderation&view=contents&filters[active_filters][status]=on&filters[status][new]=on&filters[status][warned]=on&order[0][by]=last_flag&order[0][dir]=DESC&per_page=20&submit=1'; 
  62.  
  63. $text .= sprintf(_n( 
  64. '<a href="%1$s">%2$d content</a> is awaiting your moderation',  
  65. '<a href="%1$s">%2$d contents</a> are awaiting your moderation',  
  66. $awating, 'bp-moderation'), $link, $awating 
  67. ); 
  68.  
  69. if ($warned = (int)$wpdb->get_var("$sql WHERE status = 'warned'")) { 
  70. $link = 'admin.php?page=bp-moderation&view=contents&filters[active_filters][status]=on&filters[status][warned]=on&order[0][by]=last_flag&order[0][dir]=DESC&per_page=20&submit=1'; 
  71.  
  72. $text .= sprintf(_n( 
  73. ' and the owner of <a href="%1$s">%2$d of them</a> has already been warned',  
  74. ' and the owners of <a href="%1$s">%2$d of them</a> have already been warned',  
  75. $warned, 'bp-moderation'), $link, $warned 
  76. ); 
  77.  
  78. $text .= '.'; 
  79. } elseif ($total = (int)$wpdb->get_var($sql)) { 
  80. $link = 'admin.php?page=bp-moderation&view=contents'; 
  81.  
  82. $text .= sprintf(_n( 
  83. 'there are no contents awaiting your moderation, <a href="%1$s">%2$d reported content</a> has already been viewed.',  
  84. 'there are no contents awaiting your moderation, <a href="%1$s">%2$d reported contents</a> have already been viewed.',  
  85. $total, 'bp-moderation'), $link, $total 
  86. ); 
  87. } else { 
  88. $text .= __('no content has ever been reported.', 'bp-moderation'); 
  89.  
  90. echo "<p class='bp-mod-right-now'>$text</p>\n"; 
  91.  
  92. /** 
  93. * enqueues style 
  94. */ 
  95. function admin_css() 
  96. wp_enqueue_style('bpmod-admin', $this->plugin_url . '/css/bpmod-admin.css', false, $this->plugin_ver, 'screen'); 
  97.  
  98. /** 
  99. * enqueues styles 
  100. */ 
  101. function admin_js() 
  102. wp_enqueue_script('bpmod-admin', $this->plugin_url . '/js/bpmod-admin.js', array('jquery'), $this->plugin_ver, !'in footer'); 
  103.  
  104. //hotkeys script 
  105. if ((empty($_GET['view']) || 'contents' == $_GET['view'] || 'users' == $_GET['view']) 
  106. && get_user_option('bp_moderation_hotkeys') 
  107. ) { 
  108. wp_enqueue_script('jquery-table-hotkeys'); 
  109. wp_localize_script('bpmod-admin', 'adminBPModL10n', array( 
  110. 'hotkeys_highlight_first' => isset($_GET['hotkeys_highlight_first']),  
  111. 'hotkeys_highlight_last' => isset($_GET['hotkeys_highlight_last']) 
  112. )); 
  113.  
  114. /** 
  115. * print admin pages 
  116. * print common parts of admin pages and call the function for printing current view 
  117. * (specified by $_GET['view'], default is 'contents' view) 
  118. */ 
  119. function admin_page() 
  120.  
  121. if (!is_super_admin()) { 
  122. wp_die(__('Cheatin’ uh?')); 
  123.  
  124. echo "<div class='wrap'>\n"; 
  125.  
  126. $views = array( 
  127. 'contents' => __('Contents', 'bp-moderation'),  
  128. 'users' => __('Users', 'bp-moderation'),  
  129. 'settings' => __('Settings', 'bp-moderation') 
  130. ); 
  131. $defview = 'contents'; 
  132.  
  133. $view = (!empty($_GET['view']) && in_array($_GET['view'], array_keys($views))) 
  134. ? $_GET['view'] : $defview; 
  135.  
  136. $h2 = '<h2 class="nav-tab-wrapper"><span style="margin-right:.5em;">' . __('BP Moderation', 'bp-moderation') . '</span>'; 
  137. foreach ($views as $_view => $title) { 
  138. $current = ($_view == $view) ? ' nav-tab-active' : ''; 
  139. $h2 .= "<a href='admin.php?page=bp-moderation&view=$_view' class='nav-tab$current'>$title</a>"; 
  140. $h2 .= "</h2>\n"; 
  141. echo $h2; 
  142.  
  143. $messagges_strings = array( 
  144. 'marked_spammer' => _n_noop('%s has been marked as spammer.', '%d members have been marked as spammers.'),  
  145. 'unmarked_spammer' => _n_noop('%s has been marked as not spammer.', '%d members have been marked as not spammers.'),  
  146. 'content_ignored' => _n_noop('%d item has been ignored.', '%d items have been ignored.'),  
  147. 'content_moderated' => _n_noop('%d item has been marked as moderated.', '%d items have been marked as moderated.'),  
  148. 'content_deleted' => _n_noop('%d item has been deleted.', '%d items have been deleted.'),  
  149. ); 
  150.  
  151. foreach ($messagges_strings as $arg_key => $tr) { 
  152. if (isset($_GET[$arg_key])) { 
  153. $message = is_numeric($_GET[$arg_key]) 
  154. ? _n($tr[0], $tr[1], $_GET[$arg_key], 'bp-moderation') 
  155. : $tr[0]; 
  156. $message = sprintf($message, $_GET[$arg_key]); 
  157. if (isset($_GET['err_ids'])) { 
  158. $message .= '<br/>' . sprintf(__('Operation failed on these items: %s'), $_GET['err_ids']); 
  159. if (isset($_GET['err_msg'])) { 
  160. $message .= '<br/>' . $_GET['err_msg']; 
  161. break; 
  162. if (!empty($message)) { 
  163. echo '<div id="moderated" class="updated"><p>' . $message . '</p></div>'; 
  164.  
  165. call_user_func(array(&$this, "view_$view")); 
  166.  
  167. echo "</div> <!-- .wrap -->\n"; 
  168.  
  169.  
  170. /** 
  171. * print contents view (custom query + contents table) 
  172. */ 
  173. function view_contents() 
  174. global $bp; 
  175.  
  176. $chk = ' checked="checked"'; 
  177. $sel = ' selected="selected"'; 
  178. ?> 
  179. <form id="bpmod-contents-query" class="bpmod-form-query" action="admin.php" 
  180. method="get"> 
  181. <input type="hidden" name="page" value="bp-moderation"/> 
  182. <input type="hidden" name="view" value="contents"/> 
  183. <fieldset> 
  184. <legend><?php _e('Custom Query', 'bp-moderation') ?></legend> 
  185. <div class="column"> 
  186. <h4><?php _e('Filters', 'bp-moderation') ?></h4> 
  187. <dt> 
  188. <input 
  189. id='filter-item_type' <?php echo isset($_GET['filters']['active_filters']['item_type']) 
  190. ? $chk : '' 
  191. ?> name='filters[active_filters][item_type]' 
  192. type='checkbox'/> 
  193. <label 
  194. for='filter-item_type'><?php _e('Content types', 'bp-moderation') ?></label> 
  195. </dt> 
  196. <dd> 
  197. <ul> 
  198. <?php foreach ($this->content_types as $slug => $ct) : ?> 
  199. <li><input 
  200. id='type_<?php echo $slug ?>'<?php echo isset($_GET['filters']['item_type'][$slug]) 
  201. ? $chk : '' 
  202. ?> name='filters[item_type][<?php echo $slug ?>]' 
  203. type='checkbox'/> 
  204. <label 
  205. for='type_<?php echo $slug ?>'><?php echo $ct->label ?></label> 
  206. </li> 
  207. <?php endforeach ?> 
  208. </ul> 
  209. </dd> 
  210. <dt> 
  211. <input 
  212. id='filter-status' <?php echo isset($_GET['filters']['active_filters']['status']) 
  213. ? $chk : '' 
  214. ?> name='filters[active_filters][status]' 
  215. type='checkbox'/> 
  216. <label 
  217. for='filter-status'><?php _e('Status', 'bp-moderation') ?></label> 
  218. </dt> 
  219. <dd> 
  220. <ul> 
  221. <?php foreach ($this->content_stati as $slug => $label) : ?> 
  222. <li><input 
  223. id="<?php echo $slug ?>"<?php echo isset($_GET['filters']['status'][$slug]) 
  224. ? $chk : '' 
  225. ?> name="filters[status][<?php echo $slug ?>]" 
  226. type="checkbox"> 
  227. <label 
  228. for="<?php echo $slug ?>"><?php echo $label ?></label> 
  229. </li> 
  230. <?php endforeach ?> 
  231. </ul> 
  232. </dd> 
  233. <dt> 
  234. <input 
  235. id='filter-flags' <?php echo isset($_GET['filters']['active_filters']['flags']) 
  236. ? $chk : '' 
  237. ?> name='filters[active_filters][flags]' 
  238. type='checkbox'/> 
  239. <label 
  240. for='filter-flags'><?php _e('Times reported', 'bp-moderation') ?></label> 
  241. </dt> 
  242. <dd> 
  243. <label for='flags'><?php 
  244. $input = "<input id='flags' size='4' type='text' name='filters[flags]' value='" . (empty($_GET['filters']['flags']) 
  245. ? '0' : $_GET['filters']['flags']) . "' />"; 
  246. echo sprintf(__('Reported at least %s times', 'bp-moderation'), $input); ?></label> 
  247. </dd> 
  248. <dt> 
  249. <input 
  250. id='filter-item_author' <?php echo isset($_GET['filters']['active_filters']['item_author']) 
  251. ? $chk : '' 
  252. ?> name='filters[active_filters][item_author]' 
  253. type='checkbox'/> 
  254. <label 
  255. for='filter-item_author'><?php _e('Content posted by', 'bp-moderation') ?></label> 
  256. </dt> 
  257. <dd> 
  258. <input id='item_author' class='line' size='40' type='text' 
  259. name='filters[item_author]' value='<?php 
  260. echo empty($_GET['filters']['item_author']) ? '' 
  261. : $_GET['filters']['item_author'] ?>'/> 
  262. <label 
  263. for='item_author'><?php _e('User ids (comma separeted)', 'bp-moderation') ?></label> 
  264. </dd> 
  265. <dt> 
  266. <input 
  267. id='filter-reporters' <?php echo isset($_GET['filters']['active_filters']['reporters']) 
  268. ? $chk : '' 
  269. ?> name='filters[active_filters][reporters]' 
  270. type='checkbox'/> 
  271. <label 
  272. for='filter-reporters'><?php _e('Content reported by', 'bp-moderation') ?></label> 
  273. </dt> 
  274. <dd> 
  275. <input id='reporters' class='line' size='40' type='text' 
  276. name='filters[reporters]' value='<?php 
  277. echo empty($_GET['filters']['reporters']) ? '' 
  278. : $_GET['filters']['reporters'] ?>'/> 
  279. <label 
  280. for='reporters'><?php _e('User ids (comma separeted)', 'bp-moderation') ?></label> 
  281. </dd> 
  282. </div> 
  283. <div class="column"> 
  284. <h4 class="order-by"><?php _e('Order', 'bp-moderation') ?></h4> 
  285. <ol class="order-by"> 
  286. <?php $i = 0; 
  287. while (0 == $i || !empty($_GET['order'][$i])) : 
  288. ?> 
  289. <li><?php _e('Order by', 'bp-moderation'); 
  290. $orby = empty($_GET['order'][$i]['by']) ? 'none' 
  291. : $_GET['order'][$i]['by']; 
  292. $asc = 'DESC' == @$_GET['order'][$i]['dir'] ? 'DESC' 
  293. : 'ASC'; ?> 
  294.  
  295. <select name="order[<?php echo $i ?>][by]"> 
  296. <option<?php selected('none', $orby) ?> 
  297. value="none"><?php _e('none', 'bp-moderation') ?></option> 
  298. <option<?php selected('flags', $orby) ?> 
  299. value="flags"><?php _e('times reported', 'bp-moderation') ?></option> 
  300. <option<?php selected('first_flag', $orby) ?> 
  301. value="first_flag"><?php _e('first time reported', 'bp-moderation') ?></option> 
  302. <option<?php selected('last_flag', $orby) ?> 
  303. value="last_flag"><?php _e('last time reported', 'bp-moderation') ?></option> 
  304. <option<?php selected('item_id', $orby) ?> 
  305. value="item_id"><?php _e('item id', 'bp-moderation') ?></option> 
  306. <option<?php selected('item_id2', $orby) ?> 
  307. value="item_id2"><?php _e('secondary id', 'bp-moderation') ?></option> 
  308. </select> 
  309. <select name="order[<?php echo $i ?>][dir]"> 
  310. <option<?php selected('ASC', $asc) ?> 
  311. value="ASC">ASC 
  312. </option> 
  313. <option<?php selected('DESC', $asc) ?> 
  314. value="DESC">DESC 
  315. </option> 
  316. </select> 
  317. </li> 
  318. <?php $i++; 
  319. endwhile; 
  320. ?> 
  321. </ol> 
  322. <h4><?php _e('Limit', 'bp-moderation') ?></h4> 
  323.  
  324. <p><label for='limit'><?php 
  325. $input = "<input id='limit' size='4' type='text' name='per_page' value='" . (empty($_GET['per_page']) 
  326. ? '20' : $_GET['per_page']) . "' />"; 
  327. echo sprintf(__('Display at most %s contents', 'bp-moderation'), $input); ?></label> 
  328. </p> 
  329. <input name="submit" type="submit" class="button-primary" 
  330. value="<?php _e('Query Contents', 'bp-moderation'); ?>"/> 
  331. </div> 
  332. </fieldset> 
  333. </form> 
  334. <div class="clear"></div> 
  335. <?php 
  336. extract($this->query_contents()); 
  337.  
  338. if ($total) { 
  339. $page_links = paginate_links(array( 
  340. 'base' => add_query_arg('cpage', '%#%'),  
  341. 'format' => '',  
  342. 'prev_text' => __('«'),  
  343. 'next_text' => __('»'),  
  344. 'total' => ceil($total / $per_page),  
  345. 'current' => $page_index + 1 
  346. )); 
  347.  
  348. ?> 
  349. <form id="bpmod-contents-form" class="bpmod-bulk-form" 
  350. action="admin.php" method="post"> 
  351. <div class="tablenav"> 
  352. <div class="alignleft actions"> 
  353. <select name="bulk-action"> 
  354. <option value="-1" 
  355. selected="selected"><?php _e('Bulk Actions', 'bp-moderation') ?></option> 
  356. <option 
  357. value="ignore"><?php _e('Ignore', 'bp-moderation'); ?></option> 
  358. <option 
  359. value="mark_moderated"><?php _e('Mark as moderated', 'bp-moderation'); ?></option> 
  360. <option 
  361. value="delete"><?php _e('Delete', 'bp-moderation'); ?></option> 
  362. <option 
  363. value="mark_spammer"><?php _e('Mark authors as spammers', 'bp-moderation'); ?></option> 
  364. <option 
  365. value="unmark_spammer"><?php _e('Mark authors as not spammers', 'bp-moderation'); ?></option> 
  366. <!--<option value="authors_in_user_view"><?php _e('View authors in users view', 'bp-moderation'); ?></option>--> 
  367. </select> 
  368. <input type="hidden" name="bpmod-action" 
  369. value="bulk_contents"/> 
  370. <?php wp_nonce_field('bulk_contents'); ?> 
  371. <input type="submit" name="doaction" id="doaction" 
  372. value="<?php esc_attr_e('Apply', 'bp-moderation'); ?>" 
  373. class="button-secondary apply"/> 
  374. </div> 
  375. <div class="tablenav-pages"><?php 
  376. if ($page_links) { 
  377. echo '<span class="displaying-num">' . 
  378. sprintf(__('Displaying %s–%s of %s', 'bp-moderation'),  
  379. number_format_i18n($page_index * $per_page + 1),  
  380. number_format_i18n(min(($page_index + 1) * $per_page, $total)),  
  381. '<span class="total-type-count">' . number_format_i18n($total) . '</span>') 
  382. . "</span>$page_links"; 
  383. ?></div> 
  384. </div> 
  385. <div class="clear"></div> 
  386. <table id="bpmod-contents-table" class="widefat bpmod-table fixed" 
  387. cellspacing="0"> 
  388. <thead> 
  389. <tr> 
  390. <th class="manage-column column-cb check-column" 
  391. scope="col"><input type="checkbox"></th> 
  392. <th class="manage-column column-author" 
  393. scope="col"><?php _e('Author', 'bp-moderation') ?></th> 
  394. <th class="manage-column column-content" 
  395. scope="col"><?php _e('Content', 'bp-moderation') ?></th> 
  396. <th class="manage-column column-flags" 
  397. scope="col"><?php _e('Flags', 'bp-moderation') ?></th> 
  398. </tr> 
  399. </thead> 
  400. <tfoot> 
  401. <tr> 
  402. <th class="manage-column column-cb check-column" 
  403. scope="col"><input type="checkbox"></th> 
  404. <th class="manage-column column-author" 
  405. scope="col"><?php _e('Author', 'bp-moderation') ?></th> 
  406. <th class="manage-column column-content" 
  407. scope="col"><?php _e('Content', 'bp-moderation') ?></th> 
  408. <th class="manage-column column-flags" 
  409. scope="col"><?php _e('Flags', 'bp-moderation') ?></th> 
  410. </tr> 
  411. </tfoot> 
  412.  
  413. <tbody> 
  414. <?php 
  415. foreach ($results as $content) : 
  416. $ctype = isset($this->content_types[$content->item_type]) 
  417. ? $this->content_types[$content->item_type] : false; 
  418.  
  419. $content = apply_filters("bp_moderation_filter_content_backend_for_$content->item_type", $content); 
  420. $author = $this->author_details($content->item_author, $content); 
  421. $reporters = join(', ', array_map(array(&$this, 'show_in_users_table_link'), explode(', ', $content->reporters))); 
  422. ?> 
  423. <tr class="status-<?php echo $content->status ?>"> 
  424. <th class="check-column" 
  425. scope="row"><input 
  426. type="checkbox" 
  427. value="<?php echo $content->content_id ?>" 
  428. name="bulk_items[]"></th> 
  429. <td class="column-author"> 
  430. <strong><?php echo $author['avatar_img'] . $author['user_link'] ?></strong> 
  431. <br><?php echo $author['contact_link'] ?> 
  432. <div class="row-actions"> 
  433. <?php if ($content->item_author && get_userdata($content->item_author)): 
  434. if (bp_is_user_spammer($content->item_author)): ?> 
  435. <a class="unmark-spammer vim-u" 
  436. href="<?php echo wp_nonce_url("admin.php?bpmod-action=mark_unmark_spammer&user_id=$content->item_author&set_spam=0", 'mark_unmark_spammer') ?>" 
  437. title="<?php _e('Mark the author of this content as not spammer', 'bp-moderation') ?>"><?php _e('Mark as not spammer', 'bp-moderation') ?></a> 
  438. <?php else : ?> 
  439. <a class="mark-spammer vim-s" 
  440. href="<?php echo wp_nonce_url("admin.php?bpmod-action=mark_unmark_spammer&user_id=$content->item_author&set_spam=1", 'mark_unmark_spammer') ?>" 
  441. title="<?php _e('Mark the author of this content as spammer', 'bp-moderation') ?>"><?php _e('Mark as spammer', 'bp-moderation') ?></a> 
  442. <?php endif; elseif ($content->item_author): ?> 
  443. <span 
  444. class="not-a-member"><?php _e('Unregistered', 'bp-moderation') ?></span> 
  445. <?php else: ?> 
  446. <span 
  447. class="not-a-member"><?php _e('Not a member', 'bp-moderation') ?></span> 
  448. <?php endif; ?> 
  449. </div> 
  450. </td> 
  451. <td class="column-content"> 
  452. <strong><?php _e('Status:', 'bp-moderation') ?></strong> <?php echo $this->content_stati[$content->status] 
  453. ?> 
  454. <strong><?php _e('Type:', 'bp-moderation') ?></strong> <?php echo $ctype 
  455. ? $ctype->label 
  456. : $content->item_type . ' (' . __('not found', 'bp-moderation') . ')'; 
  457. ?> 
  458. <strong><?php _e('Item ID:', 'bp-moderation') ?></strong> <?php echo $content->item_id . ($content->item_id2 
  459. ? ' - ' . $content->item_id2 
  460. : '') 
  461. ?> 
  462. <strong><?php _e('Date:', 'bp-moderation') ?></strong> <?php echo $this->date_abbr($content->item_date) ?> 
  463.  
  464. <div class="row-actions"> 
  465. <a class="view-content vim-v" 
  466. href="<?php echo $content->item_url ?>" 
  467. title="<?php _e('View this content', 'bp-moderation') ?>"><?php _e('View', 'bp-moderation') ?></a> 
  468. <?php if ('ignored' != $content->status): ?> 
  469. | <a 
  470. class="ignore-content vim-a" 
  471. href="<?php echo wp_nonce_url("admin.php?bpmod-action=ignore&cont_id=$content->content_id", 'ignore') ?>" 
  472. title="<?php _e('Mark this content as clean', 'bp-moderation') ?>"><?php _e('Ignore', 'bp-moderation') ?></a> 
  473. <?php endif; 
  474. if ($ctype && $ctype->callbacks['edit'] && 'deleted' != $content->status): ?> 
  475. | <a 
  476. class="edit-content vim-e" 
  477. href="<?php echo wp_nonce_url("admin.php?bpmod-action=edit&cont_id=$content->content_id", 'edit') ?>" 
  478. title="<?php _e('Link to the edit page for this content', 'bp-moderation') ?>"><?php _e('Edit', 'bp-moderation') ?></a> 
  479. <?php endif; 
  480. if ('deleted' != $content->status && 'moderated' != $content->status): ?> 
  481. | <a 
  482. class="mark-moderated vim-m" 
  483. href="<?php echo wp_nonce_url("admin.php?bpmod-action=mark_moderated&cont_id=$content->content_id", 'mark_moderated') ?>" 
  484. title="<?php _e('Manually mark this content as moderated if it has already been edited/deleted without this plugin', 'bp-moderation') ?>"><?php _e('Mark as moderated', 'bp-moderation') ?></a> 
  485. <?php endif; 
  486. if ($ctype && $ctype->callbacks['delete'] && 'deleted' != $content->status): ?> 
  487. | <a 
  488. class="delete-content vim-d" 
  489. href="<?php echo wp_nonce_url("admin.php?bpmod-action=delete&cont_id=$content->content_id", 'delete') ?>" 
  490. title="<?php _e('Delete this content', 'bp-moderation') ?>"><?php _e('Delete', 'bp-moderation') ?></a> 
  491. <?php endif; ?> 
  492. </div> 
  493. </td> 
  494. <td class="column-flags"> 
  495. <strong><?php _e('Flags:', 'bp-moderation') ?></strong> <?php echo $content->flags 
  496. ?> 
  497. <strong><?php _e('First:', 'bp-moderation') ?></strong> <?php echo $this->date_abbr($content->first_flag) 
  498. ?> 
  499. <strong><?php _e('Last:', 'bp-moderation') ?></strong> <?php echo $this->date_abbr($content->last_flag) ?> 
  500.  
  501. <br/><strong><?php _e('Reporters:', 'bp-moderation') ?></strong> <?php echo $reporters ?> 
  502.  
  503. </td> 
  504. </tr> 
  505. <?php 
  506. endforeach; 
  507. ?> 
  508. </tbody> 
  509. </table> 
  510. </form> 
  511.  
  512. <?php $this->print_hotkeys_toggle(); ?> 
  513.  
  514. <?php 
  515.  
  516. } else { 
  517. _e('No content to display, try a different search', 'bp-moderation'); 
  518.  
  519. /** 
  520. * build html tags of contents author details (avatar, webpage, contact) 
  521. * @param int $uid user id if known or 0 
  522. * @param stdClass $content if in content view the current content is passed 
  523. * @return array avatar_img, user_link, contact_link: <img>avatar, <a>webpage, <a>contact 
  524. */ 
  525. function author_details($uid, $content = false) 
  526. if ($uid && $user = get_userdata($uid)) { //id refers to an existing user 
  527. $details = array( 
  528. 'avatar_img' => '<a href="' . bp_core_get_user_domain($uid) . '" >' . bp_core_fetch_avatar(array('item_id' => $uid, 'width' => 32, 'height' => 32)) . '</a>',  
  529. 'user_link' => $content ? $this->show_in_users_table_link($uid) 
  530. : bp_core_get_userlink($uid),  
  531. 'contact_link' => bp_is_active('messages') ? 
  532. '<a class="vim-c" href="' . bp_loggedin_user_domain() . $GLOBALS['bp']->messages->slug . '/compose/?r=' . bp_core_get_username($uid) . '" title="' . __('Send a private message to the author of this content', 'bp-moderation') . '">' . __('Send PM', 'bp-moderation') . '</a>' 
  533. : "<a class='vim-c' href='mailto:$user->user_email' title='" . __('Send an email to the author of this content', 'bp-moderation') . "' >" . __('Send email', 'bp-moderation') . "</a>" 
  534. ); 
  535. } elseif ($uid) { // the user has probably already been deleted 
  536. $details = array( 
  537. 'avatar_img' => get_avatar('', 32, 'mystery'),  
  538. 'user_link' => $content ? $this->show_in_users_table_link($uid) 
  539. : sprintf(__('User #%d', 'bp-moderation'), $uid),  
  540. 'contact_link' => '' 
  541. ); 
  542. } else { 
  543. $details = array( 
  544. 'avatar_img' => '',  
  545. 'user_link' => '',  
  546. 'contact_link' => '' 
  547. ); 
  548. // if some content types have non members authors they can add missing details hooking to this filter (e.g. blog comments) 
  549. $details = apply_filters("bp_moderation_author_details_for_$content->item_type", $details, $content); 
  550.  
  551. return $details; 
  552.  
  553. /** 
  554. * generate the links to see info about an user in the user view 
  555. * @param int $uid user id 
  556. * @return string <a> tag with webpage 
  557. */ 
  558. function show_in_users_table_link($uid) 
  559. $username = bp_core_get_user_displayname($uid); 
  560. $title = $username 
  561. ? __('See more details on this user in the users table', 'bp-moderation') 
  562. : __('This user is not registered anymore, but you can still see some details on it in the users table', 'bp-moderation'); 
  563. if (!$username) { 
  564. $username = sprintf(__('User #%d', 'bp-moderation'), $uid); 
  565. return "<a href='admin.php?page=bp-moderation&view=users&filters[active_filters][user]=on&filters[user]=$uid' title='$title'>$username</a>"; 
  566.  
  567.  
  568. /** 
  569. * format a mysql date in an <abbr> tag 
  570. * follow blog option for date format but has complete date and time in tooltip 
  571. * @param string $date mysql date 
  572. * @return string <abbr> tag with the date 
  573. */ 
  574. function date_abbr($date) 
  575. return '<abbr title="' . mysql2date('Y-m-d\TH:i:sO', $date) . '">' . mysql2date(get_option('date_format'), $date) . '</abbr>'; 
  576.  
  577. /** 
  578. * print the hotkeys enable/disable link 
  579. */ 
  580. function print_hotkeys_toggle() 
  581. if (get_user_option('bp_moderation_hotkeys')) { 
  582. $text = sprintf(__('Hotkeys are enabled. <a href="%s">Disable</a>'), wp_nonce_url('admin.php?bpmod-action=hotkeys&set_hotkeys=0', 'hotkeys')); 
  583. } else { 
  584. $text = sprintf(__('Hotkeys are disabled. <a href="%s">Enable</a>'), wp_nonce_url('admin.php?bpmod-action=hotkeys&set_hotkeys=1', 'hotkeys')); 
  585. echo "<p id='hotkeys-toggle'>$text</p>"; 
  586.  
  587. /** 
  588. * Query the contents for the contents page based on get vars 
  589. * TODO: reformat in more functions (parse get vars, do the query) 
  590. * @return array total, results 
  591. */ 
  592. function query_contents() 
  593. global $wpdb; 
  594.  
  595. $where = 'WHERE 1'; 
  596. $having = ''; 
  597.  
  598. //filters 
  599. $can_filter = array('item_type', 'status', 'item_author', 'reporters', 'flags'); 
  600. if (isset($_GET['filters']['active_filters']) && is_array($_GET['filters']['active_filters'])) { 
  601. $filters = array_intersect(array_keys($_GET['filters']['active_filters']), $can_filter); 
  602. foreach ($filters as $f) { 
  603. if (empty($_GET['filters'][$f])) { 
  604. continue; 
  605. } else { 
  606. $val = $_GET['filters'][$f]; 
  607.  
  608. switch ($f) { 
  609. case 'item_type': 
  610. case 'status': 
  611. if (!is_array($val)) { 
  612. continue; 
  613. $values = array_keys($val); 
  614. array_walk($values, array(&$wpdb, 'escape_by_ref')); 
  615. $where .= " AND $f IN ('" . join("', '", $values) . "')"; 
  616. break; 
  617. case 'item_author': 
  618. $authors = join(', ', array_filter(array_map('intval', explode(', ', $val)))); 
  619. if ($authors) { 
  620. $where .= " AND item_author IN (" . $authors . ")"; 
  621. break; 
  622. case 'reporters': 
  623. // TODO: check efficienty of this 
  624. $reporters = join(', ', array_filter(array_map('intval', explode(', ', $val)))); 
  625. if ($reporters) { 
  626. $where .= " AND content_id IN (SELECT content_id FROM {$this->flags_table} WHERE reporter_id IN (" . $reporters . ") )"; 
  627. break; 
  628. case 'flags': 
  629. $having .= " AND COUNT(*) >= " . (int)$val; 
  630. break; 
  631. default: 
  632. continue; 
  633.  
  634. //order 
  635. $can_order = array('item_id', 'item_id2', 'flags', 'first_flag', 'last_flag'); 
  636. $orders = array(); 
  637. if (isset($_GET['order']) && is_array($_GET['order'])) { 
  638. foreach ($_GET['order'] as $o) { 
  639. if (!isset($o['by']) || !in_array($o['by'], $can_order) 
  640. || !isset($o['dir']) 
  641. || ('ASC' != $o['dir'] && 'DESC' != $o['dir']) 
  642. ) { 
  643. continue; 
  644. $orders[] = $o['by'] . ' ' . $o['dir']; 
  645. if (count($orders)) { 
  646. $order = 'ORDER BY ' . join(', ', $orders); 
  647. } else { 
  648. $order = 'ORDER BY last_flag DESC'; 
  649.  
  650. //limits 
  651. $per_page = (isset($_GET['per_page']) && intval($_GET['per_page'])) 
  652. ? intval($_GET['per_page']) : 20; 
  653. $page_index = (isset($_GET['cpage']) && intval($_GET['cpage'])) 
  654. ? intval($_GET['cpage']) - 1 : 0; 
  655. $limits = 'LIMIT ' . ($page_index * $per_page) . ', ' . $per_page; 
  656.  
  657. $from = "FROM {$this->contents_table} c NATURAL JOIN {$this->flags_table} f"; 
  658. $groupby = 'GROUP BY content_id'; 
  659.  
  660. if ($having) { 
  661. $having = 'HAVING 1' . $having; 
  662. $sql = "SELECT content_id $from $where $groupby $having"; 
  663. $total = count($wpdb->get_results($sql)); 
  664. } else { 
  665. $sql = "SELECT COUNT(*) FROM {$this->contents_table} c $where"; 
  666. $total = (int)$wpdb->get_var($sql); 
  667.  
  668. if ($total) { 
  669. $sql = "SELECT content_id, c.*, COUNT(*) as flags, GROUP_CONCAT(CAST( f.reporter_id AS CHAR )) as reporters, MIN(f.date) as first_flag, MAX(f.date) as last_flag $from $where $groupby $having $order $limits"; 
  670. $results = $wpdb->get_results($sql); 
  671. } else { 
  672. $results = array(); 
  673.  
  674. return array('results' => $results, 'total' => $total, 'per_page' => $per_page, 'page_index' => $page_index); 
  675.  
  676. /** 
  677. * print users view (custom query + contents table) 
  678. */ 
  679. function view_users() 
  680. global $bp; 
  681.  
  682. $chk = ' checked="checked"'; 
  683. $sel = ' selected="selected"'; 
  684. ?> 
  685. <form id="bpmod-users-query" class="bpmod-form-query" action="admin.php" 
  686. method="get"> 
  687. <input type="hidden" name="page" value="bp-moderation"/> 
  688. <input type="hidden" name="view" value="users"/> 
  689. <fieldset> 
  690. <legend><?php _e('Custom Query', 'bp-moderation') ?></legend> 
  691. <div class="column"> 
  692. <h4><?php _e('Filters', 'bp-moderation') ?></h4> 
  693. <dt> 
  694. <input 
  695. id='filter-user' <?php echo isset($_GET['active_filters']['user']) 
  696. ? $chk : '' 
  697. ?> name='active_filters[user]' type='checkbox'/> 
  698. <label 
  699. for='filter-user'><?php _e('Specific users', 'bp-moderation') ?></label> 
  700. </dt> 
  701. <dd> 
  702. <input id='user' class='line' size='40' type='text' 
  703. name='filters[user]' value='<?php 
  704. echo empty($_GET['filters']['user']) ? '' 
  705. : $_GET['filters']['user'] ?>'/> 
  706. <label 
  707. for='user'><?php _e('User ids (comma separeted)', 'bp-moderation') ?></label> 
  708. </dd> 
  709. <?php 
  710. $filters = array( 
  711. array( 
  712. 'own_flags',  
  713. __('Total flags on own contents', 'bp-moderation'),  
  714. __('Own contents have been flagged for a total of at least %s flags', 'bp-moderation') 
  715. ),  
  716. array( 
  717. 'own_contents',  
  718. __('Total own contents reported', 'bp-moderation'),  
  719. __('Own contents have been reported at least %s times', 'bp-moderation') 
  720. ),  
  721. array( 
  722. 'own_ignored',  
  723. __('Ignored own contents', 'bp-moderation'),  
  724. __('Own contents have been ignored at least %s times', 'bp-moderation') 
  725. ),  
  726. array( 
  727. 'own_moderated',  
  728. __('Moderated own contents', 'bp-moderation'),  
  729. __('Own contents have been moderated at least %s times', 'bp-moderation') 
  730. ),  
  731. array( 
  732. 'others_contents',  
  733. __('Total contents reported by user', 'bp-moderation'),  
  734. __('User has been reported at least %s contents', 'bp-moderation') 
  735. ),  
  736. array( 
  737. 'others_ignored',  
  738. __('Ignored contents reported by user', 'bp-moderation'),  
  739. __('Contents reported by user have been ignored at least %s times', 'bp-moderation') 
  740. ),  
  741. array( 
  742. 'others_moderated',  
  743. __('Moderated contents reported by user', 'bp-moderation'),  
  744. __('Contents reported by user have been moderated at least %s times', 'bp-moderation') 
  745. ); 
  746. foreach ($filters as $filter): 
  747. list($slug, $title, $desc) = $filter; 
  748. ?> 
  749. <dt> 
  750. <input 
  751. id='filter-<?php echo $slug ?>' <?php echo checked('on', @$_GET['active_filters'][$slug]) 
  752. ?> name='active_filters[<?php echo $slug ?>]' 
  753. type='checkbox'/> 
  754. <label 
  755. for='filter-<?php echo $slug ?>'><?php echo $title ?></label> 
  756. </dt> 
  757. <dd> 
  758. <label 
  759. for='<?php echo $slug ?>'><?php echo sprintf($desc,  
  760. "<input id='$slug' size='4' type='text' name='filters[$slug]' value='" . ((int)@$_GET['filters'][$slug]) . "' />" 
  761. ); ?></label> 
  762. </dd> 
  763.  
  764. <?php endforeach; ?> 
  765. </div> 
  766. <div class="column"> 
  767. <h4 class="order-by"><?php _e('Order', 'bp-moderation') ?></h4> 
  768. <ol class="order-by"> 
  769. <?php $i = 0; 
  770. while (0 == $i || !empty($_GET['order'][$i])) : 
  771. ?> 
  772. <li><?php _e('Order by', 'bp-moderation'); 
  773. $orby = empty($_GET['order'][$i]['by']) ? 'none' 
  774. : $_GET['order'][$i]['by']; 
  775. $asc = 'DESC' == @$_GET['order'][$i]['dir'] ? 'DESC' 
  776. : 'ASC'; ?> 
  777.  
  778. <select name="order[<?php echo $i ?>][by]"> 
  779. <option<?php selected('none', $orby) ?> 
  780. value="none"><?php _e('none', 'bp-moderation') ?></option> 
  781. <option<?php selected('own_contents', $orby) ?> 
  782. value="own_contents"><?php _e('total own contents reported', 'bp-moderation') ?></option> 
  783. <option<?php selected('own_new', $orby) ?> 
  784. value="own_new"><?php _e('pending own contents') ?></option> 
  785. <option<?php selected('own_ignored', $orby) ?> 
  786. value="own_ignored"><?php _e('ignored own contents') ?></option> 
  787. <option<?php selected('own_moderated', $orby) ?> 
  788. value="own_moderated"><?php _e('moderated own contents') ?></option> 
  789. <option<?php selected('own_flags', $orby) ?> 
  790. value="own_flags"><?php _e('total flags on own contents') ?></option> 
  791. <option<?php selected('others_contents', $orby) ?> 
  792. value="others_contents"><?php _e('total contents reported by user', 'bp-moderation') ?></option> 
  793. <option<?php selected('others_new', $orby) ?> 
  794. value="others_new"><?php _e('pending contents reported by user', 'bp-moderation') ?></option> 
  795. <option<?php selected('others_ignored', $orby) ?> 
  796. value="others_ignored"><?php _e('ignored contents reported by user', 'bp-moderation') ?></option> 
  797. <option<?php selected('others_moderated', $orby) ?> 
  798. value="others_moderated"><?php _e('moderated contents reported by user', 'bp-moderation') ?></option> 
  799. </select> 
  800. <select name="order[<?php echo $i ?>][dir]"> 
  801. <option<?php selected('ASC', $asc) ?> 
  802. value="ASC">ASC 
  803. </option> 
  804. <option<?php selected('DESC', $asc) ?> 
  805. value="DESC">DESC 
  806. </option> 
  807. </select> 
  808. </li> 
  809. <?php $i++; 
  810. endwhile; 
  811. ?> 
  812. </ol> 
  813. <h4><?php _e('Limit', 'bp-moderation') ?></h4> 
  814.  
  815. <p><label for='limit'><?php 
  816. $input = "<input id='limit' size='4' type='text' name='per_page' value='" . (empty($_GET['per_page']) 
  817. ? '20' : $_GET['per_page']) . "' />"; 
  818. echo sprintf(__('Display at most %s users', 'bp-moderation'), $input); ?></label> 
  819. </p> 
  820. <input name="submit" type="submit" class="button-primary" 
  821. value="<?php _e('Query Users', 'bp-moderation'); ?>"/> 
  822. </div> 
  823. </fieldset> 
  824. </form> 
  825. <div class="clear"></div> 
  826. <?php 
  827. extract($this->query_users()); 
  828.  
  829. if ($total) { 
  830. $page_links = paginate_links(array( 
  831. 'base' => add_query_arg('page', '%#%'),  
  832. 'format' => '',  
  833. 'prev_text' => __('«'),  
  834. 'next_text' => __('»'),  
  835. 'total' => ceil($total / $per_page),  
  836. 'current' => $page_index + 1 
  837. )); 
  838.  
  839. ?> 
  840. <form id="bpmod-users-form" class="bpmod-bulk-form" action="admin.php" 
  841. method="post"> 
  842. <div class="tablenav"> 
  843. <div class="alignleft actions"> 
  844. <select name="bulk-action"> 
  845. <option value="-1" 
  846. selected="selected"><?php _e('Bulk Actions', 'bp-moderation') ?></option> 
  847. <option 
  848. value="mark_spammer"><?php _e('Mark users as spammers', 'bp-moderation'); ?></option> 
  849. <option 
  850. value="unmark_spammer"><?php _e('Mark users as not spammers', 'bp-moderation'); ?></option> 
  851. </select> 
  852. <input type="hidden" name="bpmod-action" 
  853. value="bulk_users"/> 
  854. <?php wp_nonce_field('bulk_users'); ?> 
  855. <input type="submit" name="doaction" id="doaction" 
  856. value="<?php esc_attr_e('Apply', 'bp-moderation'); ?>" 
  857. class="button-secondary apply"/> 
  858. </div> 
  859. <div class="tablenav-pages"><?php 
  860. if ($page_links) { 
  861. echo '<span class="displaying-num">' . 
  862. sprintf(__('Displaying %s–%s of %s', 'bp-moderation'),  
  863. number_format_i18n($page_index * $per_page + 1),  
  864. number_format_i18n(min(($page_index + 1) * $per_page, $total)),  
  865. '<span class="total-type-count">' . number_format_i18n($total) . '</span>') 
  866. . "</span>$page_links"; 
  867. ?></div> 
  868. </div> 
  869. <div class="clear"></div> 
  870. <table id="bpmod-users-table" class="widefat bpmod-table fixed" 
  871. cellspacing="0"> 
  872. <thead> 
  873. <tr> 
  874. <th class="manage-column column-cb check-column" 
  875. scope="col"><input type="checkbox"></th> 
  876. <th class="manage-column column-author" 
  877. scope="col"><?php _e('User', 'bp-moderation') ?></th> 
  878. <th class="manage-column column-own-contents" 
  879. scope="col"><?php _e('Own contents reported by others', 'bp-moderation') ?></th> 
  880. <th class="manage-column column-other-contents" 
  881. scope="col"><?php _e('Contents reported by user', 'bp-moderation') ?></th> 
  882. </tr> 
  883. </thead> 
  884. <tfoot> 
  885. <tr> 
  886. <th class="manage-column column-cb check-column" 
  887. scope="col"><input type="checkbox"></th> 
  888. <th class="manage-column column-author" 
  889. scope="col"><?php _e('User', 'bp-moderation') ?></th> 
  890. <th class="manage-column column-own-contents" 
  891. scope="col"><?php _e('Own contents reported by others', 'bp-moderation') ?></th> 
  892. <th class="manage-column column-other-contents" 
  893. scope="col"><?php _e('Contents reported by user', 'bp-moderation') ?></th> 
  894. </tr> 
  895. </tfoot> 
  896.  
  897. <tbody> 
  898. <?php 
  899. foreach ($results as $user) : 
  900. $author = $this->author_details($user->user_id); 
  901. ?> 
  902. <tr class=""> 
  903. <th class="check-column" 
  904. scope="row"><input 
  905. type="checkbox" 
  906. value="<?php echo $user->user_id ?>" 
  907. name="bulk_items[]"></th> 
  908. <td class="column-author"> 
  909. <strong><?php echo $author['avatar_img'] . $author['user_link'] ?></strong> 
  910. <br><?php echo $author['contact_link'] ?> 
  911. <div class="row-actions"> 
  912. <?php if (!get_userdata($user->user_id)): ?> 
  913. <span 
  914. class="not-a-member"><?php _e('Unregistered', 'bp-moderation') ?></span> 
  915. <?php elseif (bp_is_user_spammer($user->user_id)): ?> 
  916. <a class="unmark-spammer vim-u" 
  917. href="<?php echo wp_nonce_url("admin.php?bpmod-action=mark_unmark_spammer&user_id=$user->user_id&set_spam=0", 'mark_unmark_spammer') ?>" 
  918. title="<?php _e('Mark the author of this content as not spammer', 'bp-moderation') ?>"><?php _e('Mark as not spammer', 'bp-moderation') ?></a> 
  919. <?php else : ?> 
  920. <a class="mark-spammer vim-s" 
  921. href="<?php echo wp_nonce_url("admin.php?bpmod-action=mark_unmark_spammer&user_id=$user->user_id&set_spam=1", 'mark_unmark_spammer') ?>" 
  922. title="<?php _e('Mark the author of this content as spammer', 'bp-moderation') ?>"><?php _e('Mark as spammer', 'bp-moderation') ?></a> 
  923. <?php endif; ?> 
  924. </div> 
  925. </td> 
  926. <td class="column-own-contents"> 
  927. <?php echo sprintf(_n('%d content from this user has been reported', '%d contents from this user have been reported', $user->own_contents, 'bp-moderation'), $user->own_contents); 
  928. if ($user->own_contents):?> 
  929.  
  930. <br/> 
  931. <strong><?php _e('New:', 'bp-moderation') ?></strong> <?php echo $user->own_new; 
  932. ?> 
  933. <strong><?php _e('Ignored:', 'bp-moderation') ?></strong> <?php echo $user->own_ignored 
  934. ?> 
  935. <strong><?php _e('Moderated:', 'bp-moderation') ?></strong> <?php echo $user->own_moderated 
  936. ?> 
  937. <strong><?php _e('Total flags:', 'bp-moderation') ?></strong> <?php echo $user->own_flags; 
  938. endif; ?> 
  939. <div class="row-actions"> 
  940. <a class="vim-b" 
  941. href="admin.php?page=bp-moderation&view=contents&filters[active_filters][item_author]=on&filters[item_author]=<?php echo $user->user_id ?>" 
  942. title="<?php _e('Show the contents from this user that have been reported in the contents view', 'bp-moderation') ?>"><?php _e('Show in contents view', 'bp-moderation') ?></a> 
  943. </div> 
  944.  
  945. </td> 
  946. <td class="column-other-contents"> 
  947. <?php echo sprintf(_n('this user reported %d content', 'this user reported %d contents', $user->others_contents, 'bp-moderation'), $user->others_contents); 
  948. if ($user->others_contents):?> 
  949.  
  950. <br/> 
  951. <strong><?php _e('New:', 'bp-moderation') ?></strong> <?php echo $user->others_new; 
  952. ?> 
  953. <strong><?php _e('Ignored:', 'bp-moderation') ?></strong> <?php echo $user->others_ignored 
  954. ?> 
  955. <strong><?php _e('Moderated:', 'bp-moderation') ?></strong> <?php echo $user->others_moderated; 
  956. endif; ?> 
  957. <div class="row-actions"> 
  958. <a class="vim-g" 
  959. href="admin.php?page=bp-moderation&view=contents&filters[active_filters][reporters]=on&filters[reporters]=<?php echo $user->user_id ?>" 
  960. title="<?php _e('Show the contents from this user that have been reported in the contents view', 'bp-moderation') ?>"><?php _e('Show in contents view', 'bp-moderation') ?></a> 
  961. </div> 
  962.  
  963. </td> 
  964. </tr> 
  965. <?php 
  966. endforeach; 
  967. ?> 
  968. </tbody> 
  969. </table> 
  970. </form> 
  971.  
  972. <?php $this->print_hotkeys_toggle(); ?> 
  973.  
  974. <?php 
  975.  
  976. } else { 
  977. _e('No users to display, try a different search', 'bp-moderation'); 
  978.  
  979. /** 
  980. * Query the users for the users table based on get vars 
  981. * TODO: reformat in more functions (parse get vars, do the query) 
  982. * @return array total, results 
  983. */ 
  984. function query_users() 
  985. global $wpdb; 
  986.  
  987. $own_where = ''; 
  988. $others_where = ''; 
  989. $own_having = ''; 
  990. $others_having = ''; 
  991.  
  992. //filters 
  993. $can_filter = array('user', 'own_contents', 'own_ignored', 'own_moderated', 'own_flags', 'others_contents', 'others_ignored', 'others_moderated'); 
  994. if (isset($_GET['active_filters']) && is_array($_GET['active_filters'])) { 
  995. $filters = array_intersect(array_keys($_GET['active_filters']), $can_filter); 
  996. foreach ($filters as $f) { 
  997. if (empty($_GET['filters'][$f])) { 
  998. continue; 
  999. } else { 
  1000. $val = $_GET['filters'][$f]; 
  1001.  
  1002. switch ($f) { 
  1003. case 'user': 
  1004. $users = join(', ', array_filter(array_map('intval', explode(', ', $val)))); 
  1005. if ($users) { 
  1006. $own_where = " AND item_author IN ($users)"; 
  1007. $others_where = " AND reporter_id IN ($users)"; 
  1008. break; 
  1009. case 'own_flags': 
  1010. if ($val = (int)$val) { 
  1011. $own_having = " AND COUNT(*) >= $val"; 
  1012. break; 
  1013. case 'own_contents': 
  1014. if ($val = (int)$val) { 
  1015. $own_having = " AND COUNT(DISTINCT content_id) >= $val"; 
  1016. break; 
  1017. case 'own_ignored': 
  1018. if ($val = (int)$val) { 
  1019. $own_having = " AND COUNT(DISTINCT content_id, IF(c.status='ignored', 1, NULL)) >= $val"; 
  1020. break; 
  1021. case 'own_moderated': 
  1022. if ($val = (int)$val) { 
  1023. $own_having = " AND COUNT(DISTINCT content_id, IF(c.status IN('edited', 'deleted', 'moderated'), 1, NULL)) >= $val"; 
  1024. break; 
  1025. case 'others_contents': 
  1026. if ($val = (int)$val) { 
  1027. $others_having = " AND COUNT(DISTINCT content_id) >= $val"; 
  1028. break; 
  1029. case 'others_ignored': 
  1030. if ($val = (int)$val) { 
  1031. $others_having = " AND COUNT(DISTINCT content_id, IF(c.status='ignored', 1, NULL)) >= $val"; 
  1032. break; 
  1033. case 'others_moderated': 
  1034. if ($val = (int)$val) { 
  1035. $others_having = " AND COUNT(DISTINCT content_id, IF(c.status IN('edited', 'deleted', 'moderated'), 1, NULL)) >= $val"; 
  1036. break; 
  1037. default: 
  1038. continue; 
  1039.  
  1040. //order 
  1041. $can_order = array('own_contents', 'own_new', 'own_ignored', 'own_moderated', 'own_flags', 'others_contents', 'others_new', 'others_ignored', 'others_moderated'); 
  1042. $orders = array(); 
  1043. if (isset($_GET['order']) && is_array($_GET['order'])) { 
  1044. foreach ($_GET['order'] as $o) { 
  1045. if (!isset($o['by']) || !in_array($o['by'], $can_order) 
  1046. || !isset($o['dir']) 
  1047. || ('ASC' != $o['dir'] && 'DESC' != $o['dir']) 
  1048. ) { 
  1049. continue; 
  1050. $orders[] = $o['by'] . ' ' . $o['dir']; 
  1051. if (count($orders)) { 
  1052. $order = 'ORDER BY ' . join(', ', $orders); 
  1053. } else { 
  1054. $order = ''; 
  1055.  
  1056. //limits 
  1057. $per_page = (isset($_GET['per_page']) && intval($_GET['per_page'])) 
  1058. ? intval($_GET['per_page']) : 20; 
  1059. $page_index = (isset($_GET['page']) && intval($_GET['page'])) 
  1060. ? intval($_GET['page']) - 1 : 0; 
  1061. $limits = 'LIMIT ' . ($page_index * $per_page) . ', ' . $per_page; 
  1062.  
  1063. $from = "FROM {$this->contents_table} c NATURAL JOIN {$this->flags_table} f"; 
  1064.  
  1065. $own_sql = "SELECT item_author as user_id $from WHERE item_author >0 $own_where GROUP BY item_author"; 
  1066. $others_sql = "SELECT reporter_id as user_id $from WHERE reporter_id >0 $others_where GROUP BY reporter_id"; 
  1067.  
  1068. if ($own_having && $others_having) { 
  1069. //there are conditions on both sides, so no outer join is needed 
  1070. $sql = <<< SQL 
  1071. SELECT * FROM ( 
  1072. $own_sql HAVING 1 $own_having 
  1073. ) own NATURAL JOIN ( 
  1074. $others_sql HAVING 1 $others_having 
  1075. ) others 
  1076. SQL; 
  1077. } elseif ($own_having) { 
  1078. //there are conditions on own contents side, so outer join is needed on that table 
  1079. $sql = <<< SQL 
  1080. SELECT * FROM ( 
  1081. $own_sql HAVING 1 $own_having 
  1082. ) own NATURAL LEFT JOIN ( 
  1083. $others_sql 
  1084. ) others 
  1085. SQL; 
  1086. } elseif ($others_having) { 
  1087. //there are conditions on others contents side, so outer join is needed on that table 
  1088. $sql = <<< SQL 
  1089. SELECT * FROM ( 
  1090. $others_sql HAVING 1 $others_having 
  1091. ) others NATURAL LEFT JOIN ( 
  1092. $own_sql 
  1093. ) own 
  1094. SQL; 
  1095. } else { 
  1096. //there no conditions on any side, so a full outer join is needed but sadly not supported by mysql, using UNION workaround 
  1097. $sql = <<< SQL 
  1098. SELECT * FROM ( 
  1099. $own_sql 
  1100. ) own NATURAL LEFT JOIN ( 
  1101. $others_sql 
  1102. ) others 
  1103. ) UNION ALL ( 
  1104. SELECT * FROM ( 
  1105. $others_sql 
  1106. ) others NATURAL LEFT JOIN ( 
  1107. $own_sql 
  1108. ) own WHERE own.user_id IS NULL 
  1109. SQL; 
  1110. $total = count($wpdb->get_results($sql)); 
  1111.  
  1112. if (!$total) { 
  1113. return array('results' => array(), 'total' => 0, 'per_page' => $per_page, 'page_index' => $page_index); 
  1114.  
  1115.  
  1116. $own_sql = <<< SQL 
  1117. SELECT 
  1118. item_author as user_id,  
  1119. COUNT(DISTINCT content_id) as own_contents,  
  1120. COUNT(DISTINCT content_id, IF(c.status='new', 1, NULL)) as own_new,  
  1121. COUNT(DISTINCT content_id, IF(c.status='ignored', 1, NULL)) as own_ignored,  
  1122. COUNT(DISTINCT content_id, IF(c.status IN('edited', 'deleted', 'moderated'), 1, NULL)) as own_moderated,  
  1123. COUNT(*) as own_flags 
  1124. $from 
  1125. WHERE 
  1126. item_author >0 
  1127. $own_where 
  1128. GROUP BY 
  1129. item_author 
  1130. SQL; 
  1131. $others_sql = <<< SQL 
  1132. SELECT 
  1133. reporter_id as user_id,  
  1134. COUNT(DISTINCT content_id) as others_contents,  
  1135. COUNT(DISTINCT content_id, IF(c.status='new', 1, NULL)) as others_new,  
  1136. COUNT(DISTINCT content_id, IF(c.status='ignored', 1, NULL)) as others_ignored,  
  1137. COUNT(DISTINCT content_id, IF(c.status IN('edited', 'deleted', 'moderated'), 1, NULL)) as others_moderated 
  1138. $from 
  1139. WHERE 
  1140. reporter_id >0 
  1141. $others_where 
  1142. GROUP BY 
  1143. reporter_id 
  1144. SQL; 
  1145.  
  1146. if ($own_having && $others_having) { 
  1147. //there are conditions on both sides, so no outer join is needed 
  1148. $sql = <<< SQL 
  1149. SELECT * FROM ( 
  1150. $own_sql HAVING 1 $own_having 
  1151. ) own NATURAL JOIN ( 
  1152. $others_sql HAVING 1 $others_having 
  1153. ) others $order $limits 
  1154. SQL; 
  1155. } elseif ($own_having) { 
  1156. //there are conditions on own contents side, so outer join is needed on that table 
  1157. $sql = <<< SQL 
  1158. SELECT * FROM ( 
  1159. $own_sql HAVING 1 $own_having 
  1160. ) own NATURAL LEFT JOIN ( 
  1161. $others_sql 
  1162. ) others $order $limits 
  1163. SQL; 
  1164. } elseif ($others_having) { 
  1165. //there are conditions on others contents side, so outer join is needed on that table 
  1166. $sql = <<< SQL 
  1167. SELECT * FROM ( 
  1168. $others_sql HAVING 1 $others_having 
  1169. ) others NATURAL LEFT JOIN ( 
  1170. $own_sql 
  1171. ) own $order $limits 
  1172. SQL; 
  1173. } else { 
  1174. //there no conditions on any side, so a full outer join is needed but sadly not supported by mysql, using UNION workaround 
  1175.  
  1176. // all_fields is needed so both united select give same columns in same order 
  1177. $all_fields = 'user_id, own_contents, own_new, own_ignored, own_moderated, own_flags, others_contents, others_new, others_ignored, others_moderated'; 
  1178. $sql = <<< SQL 
  1179. SELECT $all_fields FROM ( 
  1180. $own_sql 
  1181. ) own NATURAL LEFT JOIN ( 
  1182. $others_sql 
  1183. ) others 
  1184. ) UNION ALL ( 
  1185. SELECT $all_fields FROM ( 
  1186. $others_sql 
  1187. ) others NATURAL LEFT JOIN ( 
  1188. $own_sql 
  1189. ) own WHERE own.user_id IS NULL 
  1190. ) $order $limits 
  1191. SQL; 
  1192. $results = $wpdb->get_results($sql); 
  1193.  
  1194. return array('results' => $results, 'total' => $total, 'per_page' => $per_page, 'page_index' => $page_index); 
  1195.  
  1196. /** 
  1197. * register plugin settings option with WP settings API 
  1198. */ 
  1199. function register_settings() 
  1200. register_setting('bpmod_options', 'bp_moderation_options'); 
  1201.  
  1202.  
  1203. /** 
  1204. * register settings and display them 
  1205. */ 
  1206. function view_settings() 
  1207.  
  1208. if (!empty($_POST['bp_moderation_options']) && is_array($_POST['bp_moderation_options'])) { 
  1209. check_admin_referer('bpmod_options'); 
  1210.  
  1211. $options = stripslashes_deep($_POST['bp_moderation_options']); 
  1212.  
  1213. $options['unflagged_text'] = wp_kses($options['unflagged_text'], array()); 
  1214. $options['flagged_text'] = wp_kses($options['flagged_text'], array()); 
  1215.  
  1216. $options['warning_threshold'] = (int)$options['warning_threshold']; 
  1217. $options['warning_forward'] = join(', ', array_filter(explode(', ', $options['warning_forward']), 'is_email')); 
  1218. $options['warning_message'] = wp_kses($options['warning_message'], array()); 
  1219.  
  1220. if ($options != $this->options) { 
  1221. update_site_option('bp_moderation_options', $options); 
  1222. $this->options = $options; 
  1223.  
  1224. echo '<div class="updated settings-error"><p><strong>' . __('Settings saved.', 'bp-moderation') . '</strong></p></div>'; 
  1225.  
  1226. //debugging secret, add 'dump' in get vars for dumping settings 
  1227. if (isset($_GET['dump'])) { 
  1228. echo '<pre>'; 
  1229. var_dump($this->options); 
  1230. echo '</pre>'; 
  1231.  
  1232. $this->add_settings_section('general', __('General Settings', 'bp-moderation')); 
  1233. $this->add_settings_field('unflagged_text', __('Link text when unflagged', 'bp-moderation'), 'general', 'text'); 
  1234. $this->add_settings_field('flagged_text', __('Link text when flagged', 'bp-moderation'), 'general', 'text'); 
  1235. //$this->add_settings_field('permit_unflag', __( 'Permit Unflagging', 'bp-moderation' ), 'general', 'checkbox'); 
  1236. //$this->add_settings_field('permit_anonym', __( 'Permit Flagging by Anonymous', 'bp-moderation' ), 'general', 'checkbox'); 
  1237. if ('localhost' == $_SERVER['HTTP_HOST']) { 
  1238. $this->add_settings_field('generate_test_data', __('Generate test data', 'bp-moderation'), 'general', 'checkbox',  
  1239. array('description' => ' <strong>' . __('NOTE: will destroy all users except #1 * USE ONLY ON WORTHLESS TEST INSTALLS', 'bp-moderation') . '</strong>')); 
  1240.  
  1241. $this->add_settings_section('content_types', __('Content Types', 'bp-moderation'),  
  1242. __('Choose which content types can be flagged by site members.', 'bp-moderation') . '<br/>' . 
  1243. __('Note: if you deactivate one that was previously active you will still see previously flagged contents of that type in the backend tables.', 'bp-moderation') 
  1244. ); 
  1245. foreach ($this->content_types as $slug => $ct) { 
  1246. $this->add_settings_field($slug, $ct->label, 'content_types', 'checkbox_content_type'); 
  1247.  
  1248. $this->add_settings_section('automation', __('Automatic Moderation', 'bp-moderation'), __('Automatic warnings and deletion.', 'bp-moderation')); 
  1249. $this->add_settings_field('warning_threshold', __('Automatic warning', 'bp-moderation'), 'automation', 'text',  
  1250. array('size' => 3, 'sprintf' => __('When a content is flagged %s times send a warning message to the author (0 = disabled).', 'bp-moderation'))); 
  1251. $this->add_settings_field('warning_forward', __('Forward warning', 'bp-moderation'), 'automation', 'text',  
  1252. array('size' => 60, 'sprintf' => __('Forward the warning also to these addresses (comma separated) <br/>%s', 'bp-moderation'))); 
  1253. $this->add_settings_field('warning_message', __('Warning message', 'bp-moderation'), 'automation', 'textarea', array('description' => __(' 
  1254. <br/>placeholders: 
  1255. <br/>%AUTHORNAME% : content author username 
  1256. <br/>%CONTENTURL% : reported content url 
  1257. <br/>%SITENAME% : wordpress site name 
  1258. <br/>%SITEURL% : wordpress site url 
  1259. ', 'bp-moderation'))); 
  1260.  
  1261. $this->add_settings_section('uninstall', __('Uninstall', 'bp-moderation'), __('If you check the field below all plugin data will be erased on plugin deactivation.', 'bp-moderation')); 
  1262. $this->add_settings_field('clean_up', __('Clean Up on Deactivation', 'bp-moderation'), 'uninstall', 'checkbox'); 
  1263.  
  1264. ?> 
  1265. <form action="#" method="post"> 
  1266. <?php wp_nonce_field('bpmod_options'); ?> 
  1267. <?php do_settings_sections(__FILE__); ?> 
  1268. <p class="submit"> 
  1269. <input name="Submit" type="submit" class="button-primary" 
  1270. value="<?php esc_attr_e('Save Changes'); ?>"/> 
  1271. </p> 
  1272. </form> 
  1273. <?php 
  1274.  
  1275. var $settings_section_texts = array(); 
  1276.  
  1277. /** 
  1278. * custom wrap of wp setting api 'add_settings_section' 
  1279. * @param string $slug 
  1280. * @param string $title 
  1281. * @param string $description 
  1282. */ 
  1283. function add_settings_section($slug, $title, $description = '') 
  1284. $this->settings_section_texts[$slug] = $description 
  1285. ? "<p>$description</p>" : $description; 
  1286. add_settings_section($slug, $title, array(&$this, 'print_settings_section_text'), __FILE__); 
  1287.  
  1288. /** 
  1289. * print a settings section description 
  1290. * @param array $section 
  1291. */ 
  1292. function print_settings_section_text($section) 
  1293. echo $this->settings_section_texts[$section['id']]; 
  1294.  
  1295. /** 
  1296. * custom wrap of wp setting api 'add_settings_field' 
  1297. * @param string $slug 
  1298. * @param string $title 
  1299. * @param string $parent 
  1300. * @param string $type 
  1301. * @param array $args 
  1302. */ 
  1303. function add_settings_field($slug, $title, $parent, $type, $args = array()) 
  1304. $args['id'] = $args['label_for'] = $slug; 
  1305. $args['input_type'] = $type; 
  1306.  
  1307. if (empty($args['name'])) { 
  1308. $args['name'] = $slug; 
  1309.  
  1310. add_settings_field($slug, $title, array(&$this, 'print_settings_field'), __FILE__, $parent, $args); 
  1311.  
  1312. /** 
  1313. * print a settings section field 
  1314. * @param array $args 
  1315. */ 
  1316. function print_settings_field($args) 
  1317. extract($args); 
  1318.  
  1319. switch ($input_type) { 
  1320. case 'text': 
  1321. $size = isset($size) && (int)$size ? (int)$size : 40; 
  1322. $input = "<input id='$id' name='bp_moderation_options[$name]' size='$size' type='text' value='{$this->options[$name]}' />"; 
  1323. break; 
  1324.  
  1325. case 'checkbox': 
  1326. $checked = checked('on', @$this->options[$name], false); 
  1327. $input = "<input id='$id' $checked name='bp_moderation_options[$name]' type='checkbox' />"; 
  1328. break; 
  1329.  
  1330. case 'checkbox_content_type': 
  1331. $checked = checked('on', @$this->options['active_types'][$name], false); 
  1332. $input = "<input id='$id' $checked name='bp_moderation_options[active_types][$name]' type='checkbox' />"; 
  1333. break; 
  1334.  
  1335. case 'textarea': 
  1336. $input = "<textarea id='$id' name='bp_moderation_options[$name]' rows='5' cols='60'>{$this->options[$name]}</textarea>"; 
  1337. break; 
  1338.  
  1339. default: 
  1340. return; 
  1341.  
  1342.  
  1343. if (!empty($sprintf)) { 
  1344. $input = sprintf($sprintf, $input); 
  1345.  
  1346. if (!empty($description)) { 
  1347. $input .= "$description"; 
  1348.  
  1349. echo $input;