Assignment Desk -> Assignments */ # Wordpress require_once(ABSPATH . WPINC . '/registration.php'); # Edit-Flow require_once(ABSPATH . PLUGINDIR . '/edit-flow/php/util.php'); # Assignment Desk require_once('index-controller.php'); require_once('utils.php'); define(ASSIGNMENT_DESK_META_PREFIX, '_ad_'); class assignment_desk_assignment_controller { /** * Dispatch to the view specified by action HTTP parameter. */ function dispatch(){ // Default action $action = 'index'; // Map action functions to the minumum role needed to view. $actions = array("editor_assign", "search_user_ajax"); // Get action from the request if possible if($_GET['action']){ $action = $_GET['action']; } else if ($_POST['action']){ $action = $_POST['action']; } // Check that the action is supported by this controller. if (in_array($action, $actions)){ if(current_user_can('editor')){ return $this->$action(); } } echo 'You should never see this page. WHAT DID YOU DO?'; } /* ========================== Utility functions ======================== */ function create_user($user_login, $user_nicename, $user_email){ global $wpdb; $userdata = array(); $userdata['user_login'] = $user_login; $userdata['user_nicename'] = $user_nicename; $userdata['user_email'] = $user_email; // TODO - Talk to the NYTimes people about whether or not a password has to be set // in order to work with their authentication. $userdata['user_pass'] = strrev($user_login); // TODO - Add a setting for the default user role $userdata['role'] = 'contributor'; $user_id = wp_insert_user($userdata); $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE ID=%d", $user_id)); // Add usermeta marking them as community member update_usermeta($user_id, ASSIGNMENT_DESK_META_PREFIX . "origin", 'community'); /* TODO - Ask the times if we can get email addresses for nytimes logins. Users may volunteer with their nytimes id but we wont have an email unless nytimes id is email */ return $user; } /** * Lookup assignees for a post * @param $post_id the post. * @param $meta_key The meta key that determines which kind of assignee we're looking for. * */ public function get_assignees($post_id, $meta_key){ global $wpdb; $assignees = array(); $assigned_ids = get_post_meta($post_id, $meta_key); if($assigned_ids){ $assignee_ids_str = ""; foreach($assigned_ids as $a_id){ $assignee_ids_str .= "$a_id ,"; } // Strip off the last comma $assignee_sql = substr($assignee_sql, 0, strlen($assignee_sql) - 1); $assignee_sql = "SELECT * FROM $wpdb->users WHERE ID IN($assignee_ids_str)"; $assignees = $wpdb->get_results($assignee_sql); } return $assignees; } /** * Look for a user to assign a story in three places: * 1. The $wpdb->users table * 2. The $assignment_desk->tables['pitch_volunteer'] table to see if they volunteered for this pitch * 3. The $assignment_desk->tables['pitch_volunteer'] table to see if they signed up to be a contirbutor */ private function lookup_user($user_login, $pitch_id, &$volunteer){ global $wpdb, $assignment_desk; $user = 0; // Are they a WP user? $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->users} WHERE user_login=%s", $user_login)); $volunteer = False; // Are they a volunteer for this pitch? if (!$user){ $user = $wpdb->get_row($wpdb->prepare("SELECT user_login, user_email, user_nicename FROM {$assignment_desk->tables['pitch_volunteer']} WHERE pitch_id = %d AND user_login = %s", $pitch_id, $user_login)); $volunteer = True; } // Did they just sign up to be a contributor? NULL pitch if (!$user){ $user = $wpdb->get_row($wpdb->prepare("SELECT user_login, user_email, user_nicename FROM {$assignment_desk->tables['pitch_volunteer']} WHERE pitch_id = NULL AND user_login = %s", $user_login)); $volunteer = True; } return $user; } /** * Extract the Edit-Flow due date post meta_key-data from a POST * and save it in the post_metadata table * @param $post_d The id of the post. */ private function update_due_date($post_id){ // Get the assignment due date and save it to the Edit-Flow custom field $duedate_month = esc_html($_POST['ef_duedate_month']); $duedate_day = (int)$_POST['ef_duedate_day']; $duedate_year = (int)$_POST['ef_duedate_year']; $duedate = strtotime($duedate_month . ' ' . $duedate_day . ', ' . $duedate_year); update_post_meta($post_id, '_ef_duedate', $duedate); } /** * Assign a post to a user. Marks the post meta and post status as 'Waiting for Reply' * @param $post_id The id of the post. * @param $post_id The user id of the assignee. * @param $role_id The id of the term from the $assignment_desk->custom_user_roles. */ function assign_post($post_id, $user_id, $role_id){ $post = get_post($post_id); $user = get_userdata($user_id); if (!post || !$user){ return false; } add_post_meta($post_id, "_ad_waiting_for_reply", array($user_id, $role_id)); $post['post_status'] = __('Waiting for Reply'); return true; } /** * Assign a pitch to a user. */ function editor_assign(){ global $wpdb, $assignment_desk; $messages = array('errors' => array(), 'info' => array(),); // Fetch all of the pitch statusesfrom the database. $pitch_statuses = $wpdb->get_results("SELECT * FROM {$assignment_desk->tables['pitchstatus']}"); // Store them as an array indexed by name $statuses = array(); foreach($pitch_statuses as $status){ $statuses[$status->name] = $status->pitchstatus_id; } $post_id = 0; $post = 0; $disable_form = False; $show_user_form = False; // This is the initial page load FROM the pitch/editor-detail.php page. // They select a user to assign to and click continue. if (!empty($_GET)) { $post_id = intval($_GET['post_id']); // Fetch the pitch from the DB $post = wp_get_post($post_id); $user_login = $_GET['user_login_select']; if(!empty($_GET['user_login_text'])){ $user_login = $_GET['user_login_text']; } $volunteer = False; $user = $this->lookup_user($user_login, $post->ID, $volunteer); if (!$user){ $messages['errors'][] = '$user_login is not a valid user.'; $show_user_form = True; $disable_form = True; } // See if this has already been assigned to this user. if ($post->ID && $user){ $pending = get_post_meta($post->ID, '_ad_waiting_for_reply'); $coauthor = get_post_meta($post->ID, '_coauthor'); // This user is already assigned to the post associated with this pitch. if(in_array($user->ID, $pending) || in_array($user->ID, $coauthor)){ $disable_form = True; $show_user_form = True; // Display an error message back to the user. $messages["errors"][] = " $user_login is already assigned to this story. The form has been disabled."; } } } // When the editor clicks the assign button on the assignment/assign.php page. if(!empty($_POST)) { $_POST = array_map('stripslashes_deep', $_POST); $post_id = intval($_POST['post_id']); $user_login = $_POST['user_login']; // Is the user being assigned a pitch just a volunteer? // If so we need to create them $volunteer = False; // Save the pitch. $post = wp_get_post($post_id); $post['post_status'] = 'Assigned'; wp_update_post($post); $user = $this->lookup_user($user_login, $pitch_id, &$volunteer); // User not found the DB, create one. if($volunteer){ $user = $this->create_user($user->user_login, $user->user_nicename, $user->user_email); } // Get the origin of the user. Either a community member or staff (staff is NULL) $user_origin = get_usermeta($user->ID, ASSIGNMENT_DESK_META_PREFIX . 'origin'); if (!$user_origin){ $user_origin = 'staff'; update_usermeta($user->ID, ASSIGNMENT_DESK_META_PREFIX . 'origin', 'staff'); } if(!$pitch->post_id){ // Create a new post. $new_post = array( 'post_title' => $pitch->headline, 'post_content' => $pitch->summary, 'post_status' => 'Waiting for reply', 'post_date' => date('Y-m-d H:i:s'), 'post_author' => $user->ID, 'post_type' => 'post', 'post_category' => array(0) ); $post_id = wp_insert_post($new_post); // Mark the assignment with the user's origin (Either staff or community) update_post_meta($post_id, ASSIGNMENT_DESK_META_PREFIX . 'origin', $user_origin); $this->update_due_date($post_id); // Indicate that we are waiting for the reply. update_post_meta($post_id, ASSIGNMENT_DESK_META_PREFIX . 'waiting_for_reply', $user->ID); $messages["info"][] = "The pitch assignment was assigned to $user_login."; // Throw an event that a user was assigned a draft. create_event('assignment', $post_id, 'assigned', 'Assigned a story', $user->user_login); $email_body = $_POST['email_body']; // Replace the link placeholders in the email since we won't have the post_id until AFTER we save it! // Broken up so the lines aren't too long $link = admin_url('admin.php'); $link .= "?page=assignment_desk-contributor&action=accept_or_decline&post_id=$post_id&response="; $email_body = str_replace("AD_ACCEPT_URL", $link . 'accept', $email_body); $email_body = str_replace("AD_DECLINE_URL", $link . 'decline', $email_body); // Send out an email to the user. $headers = "From: East Village Local \r\n"; $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; $mail_result = wp_mail($user->user_email, 'A new assignment for you.', $email_body, $headers); // Display a message back to the user. if ($mail_result){ $messages['info'][] = "An email was sent to $user_login and we're awaiting their reply."; } else { $messages['errors'][] = "There was an error sending the email to $user_login."; } } } $assignees = $this->get_assignees($post_id, '_coauthor'); $pending_reply = $this->get_assignees($post_id, ASSIGNMENT_DESK_META_PREFIX . 'waiting_for_reply'); include_once($assignment_desk->templates_path . '/assignment/assign.php'); } /** * Return a list of user_logins to the ajax-enabled text field on the assign view. * TODO - Use a plugin that can handle more data with the full name as a "preview" */ function ajax_user_search(){ global $wpdb; // if nonce is not correct it returns -1 check_ajax_referer("assignment_desk-ajax-nonce"); if (!empty($_GET)){ $sql = "SELECT ID, user_login FROM $wpdb->users WHERE user_login LIKE '" . $wpdb->escape($_GET['q']) . "%' ORDER BY user_login ASC"; $users = $wpdb->get_results($sql); $ret = ""; $sql = "SELECT user_login FROM {$assignment_desk->tables['pitch']} WHERE user_login LIKE '" . $wpdb->escape($_GET['q']) . "%' ORDER BY user_login ASC"; $signed_up = $wpdb->get_results($sql); $users = array_merge($users, $signed_up); if($users){ foreach ($users as $user){ $ret = "$ret {$user->user_login}|{$user->ID}\n"; } } else { $ret .= 'Not found'; } echo $ret; } die(); } } ?>