/** * Notify the experts that a new question was asked * * @param ElggQuestion $entity the question to notify about * @param bool $moving is this question being moved * * @return void */ function questions_notify_experts(ElggQuestion $entity, $moving = false) { // only if experts enabled if (!questions_experts_enabled()) { return; } // validate input if (!$entity instanceof ElggQuestion) { return; } $experts = []; $container = $entity->getContainerEntity(); if (!$container instanceof ElggGroup) { $container = elgg_get_site_entity(); } // get experts $options = ['type' => 'user', 'site_guids' => false, 'limit' => false, 'relationship' => QUESTIONS_EXPERT_ROLE, 'relationship_guid' => $container->getGUID(), 'inverse_relationship' => true]; $users = elgg_get_entities_from_relationship($options); if (!empty($users)) { $experts = $users; } // trigger a hook so others can extend the list $params = ['entity' => $entity, 'experts' => $experts, 'moving' => $moving]; $experts = elgg_trigger_plugin_hook('notify_experts', 'questions', $params, $experts); if (empty($experts) || !is_array($experts)) { return; } $subject_key = 'questions:notify_experts:create:subject'; $message_key = 'questions:notify_experts:create:message'; if ($moving) { $subject_key = 'questions:notify_experts:moving:subject'; $message_key = 'questions:notify_experts:moving:message'; } $subject = elgg_echo($subject_key); foreach ($experts as $expert) { if (!$expert instanceof ElggUser) { continue; } $message = elgg_echo($message_key, [$expert->name, $entity->title, $entity->getURL()]); notify_user($expert->getGUID(), $entity->getOwnerGUID(), $subject, $message, null, 'email'); } }
/** * Automaticly mark an answer as the correct answer, when created by an expert * * NOTE: for now this is only supported in groups * * @param ElggEntity $container the container of the questions (group or user) * @param ElggUser $user the user doing the action (default: current user) * * @return bool */ function questions_auto_mark_answer_correct(ElggEntity $container, ElggUser $user = null) { if (!$container instanceof ElggGroup) { // for now only supported in groups return false; } if (!$user instanceof ElggUser) { $user = elgg_get_logged_in_user_entity(); } if (!$user instanceof ElggUser) { return false; } if (!questions_experts_enabled()) { // only applies to experts return false; } if (!questions_is_expert($container, $user)) { // not an expert return false; } // check group setting $group_setting = $container->getPrivateSetting('questions_auto_mark_correct'); return $group_setting === 'yes'; }
} // comments $comments = elgg_format_element('label', ['for' => 'questions-comments'], elgg_echo('comments')); $comments .= elgg_view('input/select', $comment_options); echo elgg_format_element('div', [], $comments); // access options if ($show_access_options) { $access = elgg_format_element('label', ['for' => 'question_access_id'], elgg_echo('access')); $access .= '<br />'; $access .= elgg_view('input/access', $access_id); echo elgg_format_element('div', [], $access); } else { echo elgg_view('input/hidden', ['name' => 'access_id', 'value' => $access_setting]); } // container selection options if (!$editing || questions_experts_enabled() && questions_is_expert(elgg_get_page_owner_entity())) { if ($show_group_selector && elgg_is_active_plugin('groups')) { $group_options = ['type' => 'group', 'limit' => false, 'metadata_name_value_pairs' => ['name' => 'questions_enable', 'value' => 'yes'], 'joins' => ['JOIN ' . elgg_get_config('dbprefix') . 'groups_entity ge ON e.guid = ge.guid'], 'order_by' => 'ge.name ASC']; if (!$editing) { $owner = elgg_get_logged_in_user_entity(); $group_options['relationship'] = 'member'; $group_options['relationship_guid'] = elgg_get_logged_in_user_guid(); } else { $owner = $question->getOwnerEntity(); } // group selector $groups = new ElggBatch('elgg_get_entities_from_relationship', $group_options); // build group optgroup $group_optgroup = []; foreach ($groups as $group) { // can questions be asked in this group
<?php // categories support if (elgg_view_exists("input/categories")) { echo elgg_view("input/categories", $vars); } // access options if ($show_access_options) { echo "<div>"; echo "<label for='question_access_id'>" . elgg_echo("access") . "</label><br />"; echo elgg_view('input/access', $access_id); echo "</div>"; } else { echo elgg_view("input/hidden", array("name" => "access_id", "value" => $access_setting)); } // container selection options if (!$editing || questions_experts_enabled() && questions_is_expert()) { if (!$editing) { $owner = elgg_get_logged_in_user_entity(); } else { $owner = $question->getOwnerEntity(); } $container_options = true; $select = "<select name='container_guid' class='elgg-input-dropdown' id='questions-container-guid'>"; // add user to the list $selected = ""; if ($owner->getGUID() == $question->getContainerGUID()) { $selected = "selected='selected'"; } if (!questions_limited_to_groups()) { $select .= "<option value='" . $owner->getGUID() . "' " . $selected . ">" . $owner->name . "</option>"; } else {
/** * A plugin hook for the CRON, so we can send out notifications to the experts about there workload * * @param string $hook the name of the hook * @param string $type the type of the hook * @param string $returnvalue current return value * @param array $params supplied params * * @return void */ function questions_daily_cron_handler($hook, $type, $returnvalue, $params) { if (empty($params) || !is_array($params)) { return; } // are experts enabled if (!questions_experts_enabled()) { return; } $time = (int) elgg_extract('time', $params, time()); $dbprefix = elgg_get_config('dbprefix'); $site = elgg_get_site_entity(); // get all experts $expert_options = ['type' => 'user', 'site_guids' => false, 'limit' => false, 'joins' => ["JOIN {$dbprefix}entity_relationships re2 ON e.guid = re2.guid_one"], 'wheres' => ["(re2.guid_two = {$site->getGUID()} AND re2.relationship = 'member_of_site')"], 'relationship' => QUESTIONS_EXPERT_ROLE, 'inverse_relationship' => true]; $experts = new ElggBatch('elgg_get_entities_from_relationship', $expert_options); // sending could take a while set_time_limit(0); $status_id = elgg_get_metastring_id('status'); $closed_id = elgg_get_metastring_id('closed'); $status_where = "NOT EXISTS (\n\t\tSELECT 1\n\t\tFROM {$dbprefix}metadata md\n\t\tWHERE md.entity_guid = e.guid\n\t\tAND md.name_id = {$status_id}\n\t\tAND md.value_id = {$closed_id})"; $question_options = ['type' => 'object', 'subtype' => 'question', 'limit' => 3]; // loop through all experts foreach ($experts as $expert) { // fake a logged in user $backup_user = elgg_extract('user', $_SESSION); $_SESSION['user'] = $expert; $subject = elgg_echo('questions:daily:notification:subject', [], get_current_language()); $message = ''; $container_where = []; if (check_entity_relationship($expert->getGUID(), QUESTIONS_EXPERT_ROLE, $site->getGUID())) { $container_where[] = "(e.container_guid NOT IN (\n\t\t\t\tSELECT ge.guid\n\t\t\t\tFROM {$dbprefix}entities ge\n\t\t\t\tWHERE ge.type = 'group'\n\t\t\t\tAND ge.site_guid = {$site->getGUID()}\n\t\t\t\tAND ge.enabled = 'yes'\n\t\t\t))"; } $group_options = ['type' => 'group', 'limit' => false, 'relationship' => QUESTIONS_EXPERT_ROLE, 'relationship_guid' => $expert->getGUID(), 'callback' => 'questions_row_to_guid']; $groups = elgg_get_entities_from_relationship($group_options); if (!empty($groups)) { $container_where[] = '(e.container_guid IN (' . implode(',', $groups) . '))'; } if (empty($container_where)) { // no groups or site? then skip to next expert continue; } $container_where = '(' . implode(' OR ', $container_where) . ')'; // get overdue questions // eg: solution_time < $time && status != closed $question_options['metadata_name_value_pairs'] = ['name' => 'solution_time', 'value' => $time, 'operand' => '<']; $question_options['wheres'] = [$status_where, $container_where]; $question_options['order_by_metadata'] = ['name' => 'solution_time', 'direction' => 'ASC', 'as' => 'integer']; $questions = elgg_get_entities_from_metadata($question_options); if (!empty($questions)) { $message .= elgg_echo('questions:daily:notification:message:overdue', [], get_current_language()) . PHP_EOL; foreach ($questions as $question) { $message .= " - {$question->title} ({$question->getURL()})" . PHP_EOL; } $message .= elgg_echo('questions:daily:notification:message:more', [], get_current_language()); $message .= " {$site->url}questions/todo" . PHP_EOL . PHP_EOL; } // get due questions // eg: solution_time >= $time && solution_time < ($time + 1 day) && status != closed $question_options['metadata_name_value_pairs'] = [['name' => 'solution_time', 'value' => $time, 'operand' => '>='], ['name' => 'solution_time', 'value' => $time + 24 * 60 * 60, 'operand' => '<']]; $questions = elgg_get_entities_from_metadata($question_options); if (!empty($questions)) { $message .= elgg_echo('questions:daily:notification:message:due', [], get_current_language()) . PHP_EOL; foreach ($questions as $question) { $message .= " - {$question->title} ({$question->getURL()})" . PHP_EOL; } $message .= elgg_echo('questions:daily:notification:message:more', [], get_current_language()); $message .= " {$site->url}questions/todo" . PHP_EOL . PHP_EOL; } // get new questions // eg: time_created >= ($time - 1 day) unset($question_options['metadata_name_value_pairs']); unset($question_options['order_by_metadata']); $question_options['wheres'] = [$container_where, '(e.time_created > ' . ($time - 24 * 60 * 60) . ')']; $questions = elgg_get_entities_from_metadata($question_options); if (!empty($questions)) { $message .= elgg_echo('questions:daily:notification:message:new', [], get_current_language()) . PHP_EOL; foreach ($questions as $question) { $message .= " - {$question->title} ({$question->getURL()})" . PHP_EOL; } $message .= elgg_echo('questions:daily:notification:message:more', array(), get_current_language()); $message .= " {$site->url}questions/all" . PHP_EOL . PHP_EOL; } // is there content in the message if (!empty($message)) { // force to email notify_user($expert->getGUID(), $site->getGUID(), $subject, $message, null, 'email'); } // restore user $_SESSION['user'] = $backup_user; } }
/** * Notify the experts that a new question was asked * * @param ElggQuestion $entity the question to notify about * @param bool $moving is this question being moved * * @return void */ function questions_notify_experts(ElggQuestion $entity, $moving = false) { // only if experts enabled if (questions_experts_enabled() && elgg_get_plugin_setting("experts_notify", "questions") == "yes") { // validate input if (!empty($entity) && elgg_instanceof($entity, "object", "question")) { $experts = array(); $container = $entity->getContainerEntity(); if (!elgg_instanceof($container, "group")) { $container = elgg_get_site_entity(); } // get experts $options = array("type" => "user", "site_guids" => false, "limit" => false, "relationship" => QUESTIONS_EXPERT_ROLE, "relationship_guid" => $container->getGUID(), "inverse_relationship" => true); if ($users = elgg_get_entities_from_relationship($options)) { $experts = $users; } // trigger a hook so others can extend the list $params = array("entity" => $entity, "experts" => $experts, "moving" => $moving); $experts = elgg_trigger_plugin_hook("notify_experts", "questions", $params, $experts); if (!empty($experts) && is_array($experts)) { $subject_key = "questions:notify_experts:create:subject"; $message_key = "questions:notify_experts:create:message"; if ($moving) { $subject_key = "questions:notify_experts:moving:subject"; $message_key = "questions:notify_experts:moving:message"; } $subject = elgg_echo($subject_key); foreach ($experts as $expert) { $message = elgg_echo($message_key, array($expert->name, $entity->title, $entity->getURL())); notify_user($expert->getGUID(), $entity->getOwnerGUID(), $subject, $message, null, "email"); } } } } }
if (!$group->canEdit()) { return; } if ($group->questions_enable !== 'yes') { return; } // default solution time if (questions_can_groups_set_solution_time()) { $solution_time = questions_get_solution_time($group); $solution = []; $solution[] = elgg_echo('questions:settings:general:solution_time'); $solution[] = elgg_view('input/select', ['name' => 'solution_time', 'value' => $solution_time, 'options' => range(0, 30), 'class' => 'mls']); $solution[] = elgg_format_element('div', ['class' => 'elgg-subtext'], elgg_echo('questions:group_settings:solution_time:description')); $content .= elgg_format_element('div', [], implode('', $solution)); } if (questions_experts_enabled()) { $expert_options = ['members' => elgg_echo('questions:group_settings:who_can_ask:members'), 'experts' => elgg_echo('questions:group_settings:who_can_ask:experts')]; $noyes_options = ['no' => elgg_echo('option:no'), 'yes' => elgg_echo('option:yes')]; // who can ask? $who_can_ask = []; $who_can_ask[] = elgg_echo('questions:group_settings:who_can_ask'); $who_can_ask[] = elgg_view('input/select', ['name' => 'who_can_ask', 'value' => $group->getPrivateSetting('questions_who_can_ask'), 'options_values' => $expert_options, 'class' => 'mls']); $content .= elgg_format_element('div', [], implode('', $who_can_ask)); $who_can_answer = []; if (!questions_experts_only_answer()) { // who can answer $who_can_answer[] = elgg_echo('questions:group_settings:who_can_answer'); $who_can_answer[] = elgg_view('input/select', ['name' => 'who_can_answer', 'value' => $group->getPrivateSetting('questions_who_can_answer'), 'options_values' => $expert_options, 'class' => 'mls']); } else { $who_can_answer[] = elgg_view('output/longtext', ['value' => elgg_echo('questions:group_settings:who_can_answer:experts_only')]); }
/** * Add experts to the subscribers for a question * * @param string $hook the name of the hook * @param string $type the type of the hook * @param array $return_value current return value * @param array $params supplied params * * @return void|array */ public static function addExpertsToSubscribers($hook, $type, $return_value, $params) { $event = elgg_extract('event', $params); if (!$event instanceof \Elgg\Notifications\Event) { return; } $question = $event->getObject(); if (!$question instanceof \ElggQuestion) { return; } $moving = $event->getAction() === 'moving'; // when moving only notify experts if ($moving) { $return_value = []; } if (!questions_experts_enabled()) { // experts isn't enabled return $return_value; } $container = $question->getContainerEntity(); if (!$container instanceof \ElggGroup) { $container = elgg_get_site_entity(); } $experts = []; $options = ['type' => 'user', 'site_guids' => false, 'limit' => false, 'relationship' => QUESTIONS_EXPERT_ROLE, 'relationship_guid' => $container->getGUID(), 'inverse_relationship' => true]; $users = elgg_get_entities_from_relationship($options); if (!empty($users)) { $experts = $users; } // trigger a hook so others can extend the list $params = ['entity' => $question, 'experts' => $experts, 'moving' => $moving]; $experts = elgg_trigger_plugin_hook('notify_experts', 'questions', $params, $experts); if (empty($experts) || !is_array($experts)) { return; } foreach ($experts as $expert) { if (!isset($return_value[$expert->getGUID()])) { // no notification for this user, so add email notification $return_value[$expert->getGUID()] = ['email']; continue; } if (!in_array('email', $return_value[$expert->getGUID()])) { // user already got a notification, but not email so add that $return_value[$expert->getGUID()][] = 'email'; continue; } } // small bit of cleanup unset($experts); return $return_value; }
<?php echo elgg_view("input/access", $access_id); ?> </div> <?php } else { ?> <?php echo elgg_view("input/hidden", array("name" => "access_id", "value" => $access_setting)); } ?> <?php // container selection options $featured_groups = rijkshuisstijl_get_featured_groups(); if ($featured_groups && (!$editing || questions_experts_enabled() && questions_is_expert())) { if (!$editing) { $owner = elgg_get_logged_in_user_entity(); } else { $owner = $question->getOwnerEntity(); } $container_options = array(); if (!questions_limited_to_groups()) { $container_options[$owner->guid] = $owner->name; } foreach ($featured_groups as $group) { $container_options[$group->guid] = $group->name; } ?> <div class="rhs-form__element">
/** * A plugin hook for the CRON, so we can send out notifications to the experts about there workload * * @param string $hook the 'cron' hook * @param string $type the 'daily' interval * @param unknown_type $returnvalue default return value * @param array $params supplied params * * @return void */ function questions_daily_cron_handler($hook, $type, $returnvalue, $params) { // are experts enabled if (questions_experts_enabled()) { // validate input if (!empty($params) && is_array($params)) { $time = elgg_extract("time", $params, time()); $dbprefix = elgg_get_config("dbprefix"); $site = elgg_get_site_entity(); // get all experts $expert_options = array("type" => "user", "site_guids" => false, "limit" => false, "joins" => array("JOIN " . $dbprefix . "entity_relationships re2 ON e.guid = re2.guid_one"), "wheres" => array("(re2.guid_two = " . $site->getGUID() . " AND re2.relationship = 'member_of_site')"), "relationship" => QUESTIONS_EXPERT_ROLE, "inverse_relationship" => true); $experts = elgg_get_entities_from_relationship($expert_options); if (!empty($experts)) { // sending could take a while set_time_limit(0); $status_id = add_metastring("status"); $closed_id = add_metastring("closed"); $status_where = "NOT EXISTS (\n\t\t\t\t\tSELECT 1\n\t\t\t\t\tFROM " . $dbprefix . "metadata md\n\t\t\t\t\tWHERE md.entity_guid = e.guid\n\t\t\t\t\tAND md.name_id = " . $status_id . "\n\t\t\t\t\tAND md.value_id = " . $closed_id . ")"; $question_options = array("type" => "object", "subtype" => "question", "limit" => 3); // loop through all experts foreach ($experts as $expert) { // fake a logged in user $backup_user = elgg_extract("user", $_SESSION); $_SESSION["user"] = $expert; $subject = elgg_echo("questions:daily:notification:subject", array(), get_current_language()); $message = ""; $container_where = array(); if (check_entity_relationship($expert->getGUID(), QUESTIONS_EXPERT_ROLE, $site->getGUID())) { $container_where[] = "(e.container_guid NOT IN (\n\t\t\t\t\t\t\tSELECT ge.guid\n\t\t\t\t\t\t\tFROM " . $dbprefix . "entities ge\n\t\t\t\t\t\t\tWHERE ge.type = 'group'\n\t\t\t\t\t\t\tAND ge.site_guid = " . $site->getGUID() . "\n\t\t\t\t\t\t\tAND ge.enabled = 'yes'\n\t\t\t\t\t\t))"; } $group_options = array("type" => "group", "limit" => false, "relationship" => QUESTIONS_EXPERT_ROLE, "relationship_guid" => $expert->getGUID(), "callback" => "questions_row_to_guid"); $groups = elgg_get_entities_from_relationship($group_options); if (!empty($groups)) { $container_where[] = "(e.container_guid IN (" . implode(",", $groups) . "))"; } if (empty($container_where)) { // no groups or site? then skip to next expert continue; } $container_where = "(" . implode(" OR ", $container_where) . ")"; // get overdue questions // eg: solution_time < $time && status != closed $question_options["metadata_name_value_pairs"] = array("name" => "solution_time", "value" => $time, "operand" => "<"); $question_options["wheres"] = array($status_where, $container_where); $question_options["order_by_metadata"] = array("name" => "solution_time", "direction" => "ASC", "as" => "integer"); $questions = elgg_get_entities_from_metadata($question_options); if (!empty($questions)) { $message .= elgg_echo("questions:daily:notification:message:overdue", array(), get_current_language()) . PHP_EOL; foreach ($questions as $question) { $message .= " - " . $question->title . " (" . $question->getURL() . ")" . PHP_EOL; } $message .= elgg_echo("questions:daily:notification:message:more", array(), get_current_language()); $message .= " " . $site->url . "questions/todo" . PHP_EOL . PHP_EOL; } // get due questions // eg: solution_time >= $time && solution_time < ($time + 1 day) && status != closed $question_options["metadata_name_value_pairs"] = array(array("name" => "solution_time", "value" => $time, "operand" => ">="), array("name" => "solution_time", "value" => $time + 24 * 60 * 60, "operand" => "<")); $questions = elgg_get_entities_from_metadata($question_options); if (!empty($questions)) { $message .= elgg_echo("questions:daily:notification:message:due", array(), get_current_language()) . PHP_EOL; foreach ($questions as $question) { $message .= " - " . $question->title . " (" . $question->getURL() . ")" . PHP_EOL; } $message .= elgg_echo("questions:daily:notification:message:more", array(), get_current_language()); $message .= " " . $site->url . "questions/todo" . PHP_EOL . PHP_EOL; } // get new questions // eg: time_created >= ($time - 1 day) unset($question_options["metadata_name_value_pairs"]); unset($question_options["order_by_metadata"]); $question_options["wheres"] = array($container_where, "(e.time_created > " . ($time - 24 * 60 * 60) . ")"); $questions = elgg_get_entities_from_metadata($question_options); if (!empty($questions)) { $message .= elgg_echo("questions:daily:notification:message:new", array(), get_current_language()) . PHP_EOL; foreach ($questions as $question) { $message .= " - " . $question->title . " (" . $question->getURL() . ")" . PHP_EOL; } $message .= elgg_echo("questions:daily:notification:message:more", array(), get_current_language()); $message .= " " . $site->url . "questions/all" . PHP_EOL . PHP_EOL; } // is there content in the message if (!empty($message)) { // force to email notify_user($expert->getGUID(), $site->getGUID(), $subject, $message, null, "email"); } // restore user $_SESSION["user"] = $backup_user; } } } } }