[plain text] [download]
  1. <?php
  2. /*
  3. Plugin Name: Multiply
  4. Version: 1.2.3
  5. Plugin URI: http://www.rephrase.net/box/word/multiply/
  6. Description: Allows multiple blogs from within the one administration interface. Includes one-click creation of new blogs, with per-blog user permissions, plugins, themes etc.
  7. Author: Sam Angove
  8. Author URI: http://rephrase.net/
  9. FOR WORDPRESS 1.5.x ONLY
  10. And God spake unto Noah, saying . . . be fruitful, and multiply.
  11. */
  12.  
  13.  
  14. // Remove tables from $mb_tables for greater integration between blogs,
  15. // i.e. categories to share categories, links and linkcategories to centralize
  16. // the link database.
  17. $mb_tables = array('categories', 'links', 'linkcategories', 'posts', 'post2cat', 'comments', 'postmeta', 'options');
  18.  
  19. $wpdb->multiply = $table_prefix . "multiply";
  20. $wpdb->muser = $table_prefix . "muser";
  21.  
  22. $mb_real_prefix = $table_prefix;
  23.  
  24. load_plugin_textdomain('Multiply');
  25.  
  26. // Run as soon as the plugin is loaded.
  27.  
  28. if (strstr($_SERVER['PHP_SELF'], 'wp-admin/')) {
  29.         mb_cookiemonster();
  30. } else {
  31.         mb_multiply();
  32. }
  33.  
  34. if (isset($mb_id)) {
  35.         $current_plugins = get_settings('active_plugins');
  36.         if (is_array($current_plugins)) {
  37.                 foreach ($current_plugins as $plugin) {
  38.                         if ('' != $plugin && file_exists(ABSPATH . 'wp-content/plugins/' . $plugin))
  39.                                 include_once(ABSPATH . 'wp-content/plugins/' . $plugin);
  40.                 }
  41.         }
  42.  
  43. }
  44.  
  45. // in wp-admin we use cookies to get the right press
  46. function mb_cookiemonster() {
  47.                
  48.         // If a new blog is selected, set the cookie.
  49.         if (isset($_GET['set_press_id'])) {
  50.                 $press_id = (int) $_GET['set_press_id'];
  51.                 mb_set_cookie($press_id);
  52.         } else {
  53.                 $press_id = mb_get_cookie();
  54.         }
  55.                
  56.         // Super dodgy hack to allow on-post edit/delete links to work.
  57.         // If you're referred to post.php & haven't come from a wp-admin
  58.         // page, look for the cookie that was set on the blog page view.
  59.         // See mb_multiply().
  60.         // It's pretty fragile, but I figured it was better than nothing.
  61.         // Or you could just edit the core, of course.
  62.         $referrer = $_SERVER['HTTP_REFERER'];
  63.         if (strlen($referrer) > 5 && !strstr($referrer, 'wp-admin')) {
  64.                 if (strstr($_SERVER['PHP_SELF'], 'post.php'))
  65.                         $press_id = mb_get_cookie('mbrid');
  66.         }
  67.                        
  68.         mb_set_press($press_id);
  69.        
  70. }       
  71.  
  72.  
  73.  
  74. // set press on page view
  75. function mb_multiply() {
  76.         global $mb_press_id;
  77.        
  78.         $press_id = (int) $_REQUEST['press_id'];
  79.        
  80.         // for those hapless fools using PATH_INFO
  81.         if (!$press_id && $mb_press_id) $press_id = $mb_press_id;
  82.        
  83.         mb_set_press($press_id);
  84.        
  85.         // Used to make on-post, GET-submitted edit and delete links work *sometimes*.
  86.         // That's the best I can do... See mb_cookiemonster()
  87.         mb_set_cookie($press_id, 'mbrid');
  88. }
  89.  
  90. // Add a hidden value to comment forms; without this, all comments
  91. // show up in the main blog.
  92. function mb_comment_form($post_id) {
  93.         global $mb_id;
  94.         echo '<input type="hidden" name="press_id" value="'. $mb_id .'" />';
  95.         return $post_id;       
  96. }
  97.  
  98.  
  99. function mb_set_cookie($press_id, $type = 'mbid', $expiration = '3000000') {
  100.         if ($press_id) {
  101.                 setcookie("wordpress_{$type}_" . COOKIEHASH, $press_id, time() + $expiration, '/');
  102.         } else {
  103.                 setcookie("wordpress_{$type}_" . COOKIEHASH, '0', time() + $expiration, '/');
  104.         }
  105. }
  106.  
  107.  
  108. function mb_set_press($press_id) {
  109.         global $wpdb, $table_prefix, $mb_id, $mb_tables, $mb_real_prefix, $cache_settings, $wp_rewrite;
  110.         global $tableposts, $tableusers, $tablecategories, $tablepost2cat, $tablecomments, $tablelinks, $tablelinkcategories, $tableoptions, $tablepostmeta;
  111.        
  112.         if (!$press_id) return;
  113.        
  114.         $press = $wpdb->get_var("SELECT press_id FROM $wpdb->multiply WHERE press_id = '$press_id'");
  115.        
  116.         if ($press) {
  117.                
  118.                 $table_prefix = $mb_real_prefix . $press_id . '_';
  119.                
  120.                 foreach ($mb_tables as $table) {
  121.                         $wpdb->$table = $table_prefix . $table;
  122.                        
  123.                         // reset "$tableposts" etc. for legacy purposes
  124.                         ${'table' . $table} = $table_prefix . $table;
  125.                 }
  126.                
  127.                 // The $mb_id global is used in almost every function.
  128.                 $mb_id = $press_id;
  129.                                
  130.                 // Reset the settings cache, since it's already been populated
  131.                 // with the default blog's options. Re-initialize $wp_rewrite
  132.                 // for the same reason.
  133.                 $cache_settings = array();
  134.                 $wp_rewrite->init();
  135.         }
  136. }
  137.  
  138. function mb_get_cookie($type = 'mbid') {
  139.         $press_id = (int) $_COOKIE["wordpress_{$type}_".COOKIEHASH];
  140.                
  141.         return $press_id;
  142. }
  143.  
  144. // Builds the array which is used to generate the list of
  145. // available presses.
  146. function mb_authorized_presses() {
  147.         global $user_ID, $user_level, $wpdb, $press_cache;
  148.        
  149.         $presses = array();
  150.        
  151.         // Presses with a default level below the user's.
  152.         $wpdb->hide_errors();
  153.         $results = $wpdb->get_results("
  154.                 SELECT
  155.                         press_id,
  156.                         press_name,
  157.                         min_level
  158.                 FROM
  159.                         $wpdb->multiply
  160.                 WHERE
  161.                         min_level <= '$user_level'
  162.                 ORDER BY press_id
  163.                 ");
  164.         $wpdb->show_errors();
  165.        
  166.         // Install on plugin first-load?
  167.         if (strpos(mysql_error(), $wpdb->multiply."' doesn't exist")) mb_install();
  168.        
  169.         if ($results) {
  170.                 foreach($results as $press) {
  171.                         $presses[$press->press_id]->name = $press->press_name;
  172.                         $presses[$press->press_id]->level = $user_level;
  173.                 }       
  174.         }
  175.        
  176.         // Presses for which the user is specifically authorized.
  177.         $results = $wpdb->get_results("
  178.                 SELECT
  179.                         mu.press_id,
  180.                         mu.level,
  181.                         mb.press_id AS 'press_id',
  182.                         mb.press_name AS 'press_name'
  183.                 FROM
  184.                         $wpdb->multiply mb,
  185.                         $wpdb->muser mu
  186.                 WHERE
  187.                         mu.user_id = '$user_ID' AND
  188.                         mu.press_id = mb.press_id
  189.                 ORDER BY mb.press_id
  190.                 ");
  191.  
  192.         if ($results) {
  193.                 foreach($results as $press) {
  194.                         // user level is never below their default, but it can be higher
  195.                         $level = ($press->level > $user_level) ? $press->level : $user_level;
  196.                                 
  197.                         $presses[$press->press_id]->level = $level;
  198.                         $presses[$press->press_id]->name = $press->press_name;
  199.                 }       
  200.         }
  201.         $press_cache = $presses;
  202.        
  203.         return $presses;
  204. }
  205.  
  206. // Sets the user level to what it should be for the selected press.
  207.  
  208. function mb_user_auth() {
  209.         global $userdata, $user_level, $mb_id;
  210.        
  211.         $presses = mb_authorized_presses();
  212.        
  213.         if (!$mb_id) return;
  214.        
  215.         if ($presses[$mb_id]) {
  216.                 $user_level = $presses[$mb_id]->level;
  217.         } else {
  218.                 $user_level = 0;
  219.         }
  220.         mb_airport_security();
  221.         $userdata->user_level = $user_level;
  222. }
  223.  
  224.  
  225. // As useful and robust as its namesake!
  226. // If it seems overly complicated for what it does, it's because it used to hide more files
  227. // than this. It hides files (i.e. shared files like users.php) and/or drops a magic user level
  228. // back down to normal. Can't figure out how to make it work with plugin files, so it's not
  229. // too useful.
  230. //
  231. function mb_airport_security() {
  232.         global $menu, $submenu, $userdata, $user_level, $mb_default_menu, $mb_default_submenu;
  233.                
  234.         $mb_default_menu = (array) $mb_default_menu;
  235.         $mb_default_submenu = (array) $mb_default_submenu;
  236.        
  237.         $mb_default_submenu['profile.php'] = array('users.php');
  238.        
  239.         $files = array();
  240.         foreach ($menu as $key => $value) {
  241.                 $file = $value[2];
  242.                 if (in_array($file, $mb_default_menu)) {
  243.                         $files[$file] = false;
  244.                         if ($value[1] > $userdata->user_level) {
  245.                                 unset($menu[$key]);
  246.                                 $files[$file] = true;
  247.                         }
  248.                 }
  249.         }
  250.  
  251.         foreach ($mb_default_submenu as $sub_of => $sub) {
  252.                 foreach ($submenu[$sub_of] as $key => $value) {
  253.                         $file = $value[2];
  254.                         if (in_array($file, $mb_default_submenu[$sub_of])) {
  255.                                 $files[$file] = false;
  256.                                 if ($value[1] > $userdata->user_level) {
  257.                                         unset($submenu[$sub_of][$key]);
  258.                                         $files[$file] = true;
  259.                                 }
  260.                         }
  261.                 }       
  262.         }
  263.        
  264.         foreach ($files as $file => $redirect) {
  265.                 if (strpos($_SERVER['PHP_SELF'], "/$file")) {
  266.                         $user_level = $userdata->user_level;
  267.                         if ($redirect) header('Location: index.php');
  268.                 }
  269.         }
  270. }
  271.  
  272. // Press selection widget in the top right
  273. function mb_select_press() {
  274.         global $press_cache, $mb_id;
  275.        
  276.         if ($press_cache) {
  277.        
  278.                 echo '<div id="mbdiv" style="position: absolute; top: 0px; right: 0px; text-align: right;">';
  279.  
  280.                 echo '<form id="multiply" method="get">';
  281.                 //echo '<fieldset>';
  282.                 echo '<select name="set_press_id">';
  283.                 echo '<option value="0">' . __('Default Press', 'Multiply') . '</option>';
  284.                 foreach ($press_cache as $id => $press) {
  285.                         echo '<option value="' . $id . '"';
  286.                         if ($id == $mb_id) echo ' selected="selected"';
  287.                         echo '>'.$id.'. '.$press->name.'&nbsp;&nbsp;</option>';
  288.                 }
  289.                 echo '</select>';
  290.                 echo '<input value="' . __('Select', 'Multiply') . '" type="submit">';
  291.                
  292.                 //echo '</fieldset>';
  293.                 echo '</form>';
  294.                 echo '</div>';
  295.         }
  296. }
  297.  
  298. function mb_login_redirect($link) {
  299.         global $user_ID, $mb_id;
  300.        
  301.         if (!isset($mb_id)) $mb_id = 0;
  302.        
  303.         if ('' == $user_ID) {
  304.                 $link = '<a href="' . get_settings('siteurl') . '/wp-login.php?redirect_to=' . urlencode("wp-admin/?set_press_id=$mb_id") . '">' . __('Login') . '</a>';
  305.         }
  306.         return $link;
  307. }
  308.  
  309. // get all presses
  310. function mb_presses() {
  311.         global $wpdb;
  312.        
  313.         $presses = $wpdb->get_results("
  314.                 SELECT
  315.                         press_id,
  316.                         press_name,
  317.                         min_level
  318.                 FROM
  319.                         $wpdb->multiply
  320.                 WHERE
  321.                         1
  322.                 ORDER BY press_id
  323.                 ");
  324.                
  325.         if ($presses) {
  326.                 $press_cache_all = array();
  327.                 foreach ($presses as $press) {
  328.                         $press_cache_all[$press->press_id]->press_name = $press->press_name;
  329.                         $press_cache_all[$press->press_id]->min_level = $press->min_level;     
  330.                 }
  331.                 return $press_cache_all;
  332.         }
  333. }
  334.  
  335. // get all users with magic user levels
  336. function mb_press_users() {
  337.         global $wpdb;
  338.  
  339.         $results = $wpdb->get_results("
  340.                 SELECT
  341.                         mu.user_id,
  342.                         mu.level,
  343.                         mb.press_id AS 'press_id',
  344.                         mb.press_name AS 'press_name'
  345.                                        
  346.                 FROM
  347.                         $wpdb->multiply mb,
  348.                         $wpdb->muser mu
  349.                 WHERE
  350.                         mu.press_id = mb.press_id
  351.                 ");
  352.        
  353.         if ($results) {
  354.                 $press_user_cache = array();
  355.                 foreach($results as $press) {
  356.                         $press_user_cache[$press->press_id][$press->user_id] = $press;
  357.                 }
  358.                 return $press_user_cache;       
  359.         }
  360.        
  361. }       
  362.  
  363.  
  364. function mb_management_page() {
  365.         global $wpdb, $user_level, $mb_tables;
  366.        
  367.         check_admin_referer();
  368.         if (!user_can_access_admin_page())
  369.                 die (__('Sorry, only the administrator can access this page.', 'Multiply'));
  370.         //if ($user_level < 10)
  371.        
  372.         $press_edit_id = (int) $_REQUEST['press_edit_id'];
  373.         $user_id = (int) $_REQUEST['user_id'];
  374.        
  375.         $action = $_REQUEST['action'];
  376.        
  377.         switch($action) {
  378.                
  379.                 case 'add_user':
  380.                         $level = (int) $_REQUEST['level'];
  381.                        
  382.                         if (!$level) $level = 0;
  383.                         if ($level > 9) $level = 9;
  384.                         $var = $wpdb->get_var("SELECT level FROM $wpdb->muser WHERE press_id = '$press_edit_id' AND user_id = '$user_id'");
  385.                         if ($var) {
  386.                                 $wpdb->query("UPDATE $wpdb->muser SET level = '$level' WHERE press_id = $press_edit_id AND user_id = $user_id");       
  387.                         } else {
  388.                                 $wpdb->query("INSERT INTO $wpdb->muser (press_id, user_id, level) VALUES ('$press_edit_id', '$user_id', '$level')");
  389.                         }
  390.                         $status = __('User updated.', 'Multiply');
  391.                 break;
  392.                
  393.                 case 'delete_user':
  394.                         $wpdb->query("DELETE FROM $wpdb->muser WHERE press_id = '$press_edit_id' AND user_id = '$user_id'");
  395.                         $status = __('User updated.', 'Multiply');
  396.                 break;
  397.        
  398.                 case 'promote':
  399.                 case 'demote':
  400.                         $var = $wpdb->get_var("SELECT level FROM $wpdb->muser WHERE press_id = '$press_edit_id' AND user_id = '$user_id'");
  401.                         if ($action == 'promote' && $var < 9) {
  402.                                 $dir = '+ 1';
  403.                         } elseif ($action == 'demote' && $var > 0) {
  404.                                 $dir = '- 1';   
  405.                         }
  406.                         $wpdb->query("UPDATE $wpdb->muser SET level = level $dir WHERE press_id = $press_edit_id AND user_id = $user_id");     
  407.                         $status = __("User updated.", 'Multiply');
  408.                 break;
  409.                
  410.                 case 'create':
  411.                         $name = addslashes($_POST['name']);
  412.                         $level = (int) $_POST['level'];
  413.                         $message = mb_create_press($name, $level);
  414.                         $status = $message . __("New press '$name' created! It can be accessed by users of level $level or greater, or by any user you add below.", 'Multiply');
  415.                 break;
  416.                
  417.                 case 'edit':
  418.                         $name = addslashes($_POST['name']);
  419.                         $level = (int) $_POST['level'];
  420.                         if ($level > 10) $level = 10;
  421.                         $wpdb->query("UPDATE $wpdb->multiply SET `press_name` = '$name', `min_level` = '$level' WHERE `press_id` = '$press_edit_id'");
  422.                 break;
  423.                
  424.                 case 'delete':
  425.                        
  426.                         $var = $wpdb->get_var("SELECT press_id FROM $wpdb->multiply WHERE press_id = $press_edit_id");
  427.                         if ($var) {
  428.                                 mb_set_press($press_edit_id);
  429.                                 foreach($mb_tables as $table) {
  430.                                         $table = $wpdb->$table;
  431.                                         $wpdb->query("DROP TABLE `$table`");
  432.                                 }
  433.                                 $wpdb->query("DELETE FROM `$wpdb->muser` WHERE press_id = $press_edit_id");
  434.                                 $wpdb->query("DELETE FROM `$wpdb->multiply` WHERE press_id = $press_edit_id");
  435.                                 $status = __('Press deleted. I hope you didn\'t need that...', 'Multiply');
  436.                                 //header('Location: edit.php?page=000-multiply.php');
  437.                                
  438.                         } else {
  439.                                 $status = __("Press ID #$press_edit_id does not exist.", 'Multiply');   
  440.                         }
  441.                         $press_edit_id = 0;
  442.                 break;
  443.                
  444.         }
  445.        
  446.         $presses = mb_presses();
  447.         $press_user_cache = mb_press_users();
  448.         $press_cache = mb_authorized_presses();
  449.        
  450.         if ($press_edit_id) {
  451.                 $header = __('Edit Press', 'Multiply')
  452.                 $press = $presses[$press_edit_id];
  453.                 $act = 'edit';
  454.         } else {
  455.                 $header = __('Add Press', 'Multiply')
  456.                 $act = 'create';
  457.         }
  458.         ?>                 
  459.        
  460.         <?php if ($status) { ?>
  461.                 <div class="updated">
  462.                         <p>
  463.                         <strong>
  464.                                 <?php
  465.                                         echo $status;
  466.                                 ?>
  467.                         </strong>
  468.                         </p>
  469.                 </div>
  470.         <?php } ?>
  471.  
  472.                 <div class="wrap">
  473.                 <form method="post" action="edit.php?page=000-multiply.php">
  474.                         <h2><?php echo $header; ?></h2>
  475.                        
  476.                         <fieldset>
  477.                        
  478.                                 <label for="name">
  479.                                         <?php _e('Press name', 'Multiply'); ?>
  480.                                 </label>
  481.                                 <input type="text" name="name" size="30" maxlength="50" value="<?php echo $press->press_name; ?>" />
  482.                                         <label for="level">
  483.                                                 <?php _e('Default access level', 'Multiply'); ?>
  484.                                         </label>
  485.                                 <select name="level">
  486.                                 <?php
  487.                                         for ($i=0; $i<=10; $i++) {
  488.                                                 echo "<option value='$i'";
  489.                                                 if ($i == $press->min_level) echo " selected='selected'";
  490.                                                 echo ">$i</option>";
  491.                                         }
  492.                                 ?>
  493.                                 </select>
  494.                                 <input type="hidden" name="press_edit_id" value="<?php echo $press_edit_id; ?>" />
  495.                                 <input type="hidden" name="action" value="<?php echo $act; ?>" />
  496.                                 <input type="submit" value="<?php _e('Update', 'Multiply'); ?>" />
  497.  
  498.                         </fieldset>
  499.                 </form>
  500.                 </div>
  501.                
  502.        
  503.         <?php if ($press_edit_id) : ?>
  504.                
  505.                 <div class="wrap">
  506.                 <h2><?php _e('Press Users', 'Multiply'); ?></h2>
  507.                 <?php
  508.                
  509.                 $users = $press_user_cache[$press_edit_id];
  510.                 if ($users) :
  511.                
  512.                 ?>     
  513.                        
  514.                 <table cellpadding="3" cellspacing="3" width="100%">
  515.                 <tr>
  516.                         <th scope="col">ID</th>
  517.                 <th scope="col"><?php _e('Name'); ?></th>
  518.                 <th scope="col"><?php _e('Default Level', 'Multiply'); ?></th>
  519.                 <th scope="col"><?php _e('Press Level', 'Multiply'); ?></th>
  520.             <th colspan="3"><?php _e('Action'); ?></th>
  521.                 </tr>
  522.                
  523.                         <?php
  524.                         foreach ($users as $id => $row) {
  525.                                 $user = get_userdata($id);
  526.                                 $level = $row->level;
  527.                                 ++$count;
  528.                                 if ( $count % 2 ) $style = ' class="alternate"';
  529.                                         else $style = '';
  530.                                        
  531.                                 echo "<tr$style>";
  532.                                 echo "<td align='center'>$id</td>";
  533.                                 echo "<td>$user->user_nickname ($user->user_firstname $user->user_lastname)</td>";
  534.                                 echo "<td align='center'>$user->user_level</td>";
  535.                                 echo "<td align='center'>" . $level . "</td>";
  536.                                
  537.                                 echo '<td align="center">';
  538.                                 if ($level > 0) echo '<a class="edit" href="edit.php?page=000-multiply.php&amp;action=demote&amp;press_edit_id='. $press_edit_id .'&amp;user_id='.$id.'">-</a>';
  539.                                 echo '</td>';
  540.                                 echo '<td align="center">';
  541.                                 if ($level < 9) echo '<a class="edit" href="edit.php?page=000-multiply.php&amp;action=promote&amp;press_edit_id='. $press_edit_id .'&amp;user_id='.$id.'">+</a>';
  542.                                 echo '</td>';
  543.                                 echo '<td align="center"><a class="delete" href="edit.php?page=000-multiply.php&amp;action=delete_user&amp;press_edit_id='. $press_edit_id .'&amp;user_id='.$id.'">'.__('Delete').'</a></td>';
  544.                         }
  545.                        
  546.                        
  547.                         ?>
  548.                 </table>
  549.                         <?php endif; ?>
  550.                        
  551.                        
  552.                         <form method="post">   
  553.                         <fieldset name="blog_name">
  554.                                 <legend><?php _e('Add User', 'Multiply'); ?></legend>
  555.                        
  556.                         <label for="user">
  557.                                 <?php _e('User', 'Multiply'); ?>
  558.                         </label>
  559.                
  560.                 <?php
  561.                 echo '<select name="user_id">';
  562.                 $users = $wpdb->get_results("SELECT * FROM $wpdb->users");
  563.                 foreach ($users as $user) :
  564.                         echo '<option value="' . $user->ID . '">'.$user->user_nickname.'</option>';
  565.                 endforeach;
  566.                 echo '</select>';
  567.                 ?>
  568.                         <label for="level">
  569.                                 <?php _e('Level', 'Multiply'); ?>
  570.                         </label>
  571.                         <select name="level">
  572.                         <!--<option value="0" selected="selected">0</option>-->
  573.                         <?php
  574.                                 for ($i=0; $i<=9; $i++) {
  575.                                         echo '<option value="'.$i.'">'.$i.'</option>';
  576.                                 }
  577.                         ?>
  578.                         </select>
  579.                         <input type="hidden" name="action" value="add_user" />
  580.                         <input type="hidden" name="press_edit_id" value="<?php echo $press_edit_id; ?>" />
  581.                         <input type="submit" value="<?php _e('Add', 'Multiply'); ?>" />
  582.                 </form>
  583.                        
  584.  
  585.                 </div>
  586.         <?php endif; ?>
  587.                
  588.                 <div class="wrap">
  589.                 <h2><?php _e('Presses', 'Multiply'); ?></h2>
  590.                 <form method="post">
  591.                 <table cellpadding="3" cellspacing="3" width="100%">
  592.                 <tr>
  593.                         <th scope="col">ID</th>
  594.                 <th scope="col"><?php _e('Name'); ?></th>
  595.                 <th scope="col"><?php _e('Users', 'Multiply'); ?></th>
  596.                 <th scope="col"><?php _e('Default Level', 'Multiply'); ?></th>
  597.             <th colspan="2"><?php _e('Action'); ?></th>
  598.                 </tr>
  599.                
  600.                 <?php
  601.        
  602.                 if ($presses) {
  603.                                                                        
  604.                         foreach ($presses as $id => $press) {
  605.                                 ++$count;
  606.                                 if ( $count % 2 ) $style = ' class="alternate"';
  607.                                         else $style = '';
  608.                                
  609.                                 echo "<tr$style>";
  610.                                 echo "<th scope='row'>$id</th>";
  611.                                 echo "<td>$press->press_name</td>";
  612.        
  613.                                 echo '<td>';
  614.                                
  615.                                 if ($users = $press_user_cache[$id]) {
  616.                                         $i = 0;
  617.                                         foreach ($users as $user_id => $row) {
  618.                                                 $user = get_userdata($user_id);
  619.                                                 echo "$user->user_nickname ($row->level)";
  620.                                                 if ($i < count($users)-1) echo ', ';
  621.                                                 $i++;
  622.                                         }                                   
  623.                                 }
  624.                                 echo '</td>';
  625.                                 echo '<td align="center">';
  626.                                 echo $press->min_level;
  627.                                 echo '</td>';
  628.                                 echo '<td><a href="edit.php?page=000-multiply.php&amp;press_edit_id='. $id .'" class="edit">Edit</a></td>';
  629.                                 echo '<td><a href="edit.php?page=000-multiply.php&amp;action=delete&amp;press_edit_id='. $id .'" onclick="return confirm(\''.__('Really delete this press?', 'Multiply') .'\')" class="delete">Delete</a></td>';
  630.                                 echo '</tr>';
  631.                        
  632.                         }
  633.                 }
  634.                
  635.                 ?>
  636.         </table>
  637.         </form>
  638.         </div>
  639.         <?
  640. }
  641.  
  642. function mb_admin() {
  643.         mb_user_auth();
  644.         add_management_page(__('Manage Presses', 'Multiply'), __('Presses', 'Multiply'), 10, __FILE__, 'mb_management_page'<