Forked from
Stud.IP / Stud.IP
4149 commits behind, 4 commits ahead of the upstream repository.
-
Elmar Ludwig authoredElmar Ludwig authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
object.inc.php 15.40 KiB
<?php
# Lifter002: TODO
# Lifter007: TODO
# Lifter003: TEST
# Lifter010: TODO
/**
* object.inc.php
*
* functions for object operations (Stud.IP-ojects/modules) as get/set viewdate, rates, favourites and more
*
*
* @author Ralf Stockmann <rstockm@gwdg.de>, Cornelis Kater <kater@data-quest.de>, data-quest GmbH <info@data-quest.de>
* @access public
* @modulegroup functions
* @module object.inc.php
* @package studip_core
*/
//object.inc.php - Verwaltung von Objektoperationen
//Copyright (C) 2004 Ralf Stockmann <rstockm@gwdg.de>, Cornelis Kater <kater@data-quest.de>, data-quest GmbH <info@data-quest.de>
// This file is part of Stud.IP
// object.inc.php
// Funktionen fuer generische Objekt-Behandlungen (Stud.IP-Objekte/Module)
// Copyright (C) 2004 Cornelis Kater <ckater@gwdg.de>, Suchi & Berg GmbH <info@data-quest.de>
// +---------------------------------------------------------------------------+
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or any later version.
// +---------------------------------------------------------------------------+
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// +---------------------------------------------------------------------------+
function object_set_visit_module($plugin_id)
{
$plugin_id = object_type_to_id($plugin_id);
if (object_get_visit(Context::getId(), $plugin_id, false, false)
< object_get_visit(Context::getId(), 0, false, false)){
object_set_visit(Context::getId(), $plugin_id);
}
}
/**
* This function saves the actual time as last visitdate for the given object, user and type
*
* @param string the id of the object (i.e. seminar_id, news_id, vote_id)
* @param string the type of visited object or module (i.e. news, documents, wiki - see /lib/classes/Modules.class.php for definitions)
* @param string the user who visited the object - if not given, the actual user is used
*
*/
function object_set_visit($object_id, $plugin_id, $user_id = '')
{
global $user;
$plugin_id = object_type_to_id($plugin_id);
if (!$user_id) {
$user_id = $user->id;
}
$last_visit = object_get_visit($object_id, $plugin_id, FALSE, false , $user_id);
if ($last_visit === false) {
$last_visit = object_get_visit_threshold();
}
$query = "INSERT INTO object_user_visits (object_id, user_id, plugin_id, visitdate, last_visitdate)
VALUES (?, ?, ?, UNIX_TIMESTAMP(), ?) ON DUPLICATE KEY UPDATE visitdate=UNIX_TIMESTAMP(), last_visitdate=?";
$statement = DBManager::get()->prepare($query);
$statement->execute([$object_id, $user_id, $plugin_id, $last_visit, $last_visit]);
return object_get_visit($object_id, $plugin_id, FALSE, false, $user_id, true);
}
/**
* This function gets the (last) visit time for an object or module. If no information is found, the last visit of the open-object can bes used
*
* @param string the id of the object (i.e. seminar_id, news_id, vote_id)
* @param string the type of visited object or module (i.e. news, documents, wiki - see /lib/classes/Modules.class.php for definitions OR sem/inst, if the visit for the whole seminar was saved)
* @param string the return-mode: 'last' for the last visit, other for actual-visit
* @param string the user who visited the object - if not given, the actual user is used
* @param string the id of an open-object (seminar or inst), to gather information for last visit from the visit of the whole open-object
* @return int the timestamp of the last visit or FALSE
*
*/
function object_get_visit($object_id, $plugin_id, $mode = "last", $open_object_id = '', $user_id = '', $refresh_cache = false)
{
global $user;
static $cache;
$plugin_id = object_type_to_id($plugin_id);
if (!$user_id) {
$user_id = $user->id;
}
if (!$open_object_id && $open_object_id !== false) {
$open_object_id = $object_id;
}
if ($refresh_cache) {
$cache[$object_id][$plugin_id][$user_id] = null;
}
if ($cache[$object_id][$plugin_id][$user_id]) {
return $mode == 'last'
? $cache[$object_id][$plugin_id][$user_id]['last_visitdate']
: $cache[$object_id][$plugin_id][$user_id]['visitdate'];
}
$query = "SELECT visitdate, last_visitdate
FROM object_user_visits
WHERE object_id = ? AND user_id = ? AND plugin_id = ?";
$statement = DBManager::get()->prepare($query);
$statement->execute([$object_id, $user_id, $plugin_id]);
$temp = $statement->fetch(PDO::FETCH_ASSOC);
if ($temp) {
$cache[$object_id][$plugin_id][$user_id] = $temp;
return $mode == 'last'
? $temp['last_visitdate']
: $temp['visitdate'];
//no visitdate for the object or modul - we have to gather the information from the studip-object (seminar or institute)
} elseif ($open_object_id) {
$query = "SELECT visitdate, last_visitdate
FROM object_user_visits
WHERE object_id = ? AND user_id = ? AND plugin_id = 0";
$statement = DBManager::get()->prepare($query);
$statement->execute([$open_object_id, $user_id]);
$temp = $statement->fetch(PDO::FETCH_ASSOC);
if ($temp) {
return $mode == 'last'
? $temp['last_visitdate']
: $temp['visitdate'];
} else {
return object_get_visit_threshold();
}
} else {
return object_get_visit_threshold();
}
}
/**
* This function gets the (last) visit time for an array of objects.
* If no information is found, the last visit of the open-object can bes used
*
* @param array $object_ids The ids of the objects (i.e. seminar_id, news_id, vote_id)
* @param string $type The type of visited objects or module (i.e. news, documents, wiki)
* @param string|null $mode The return-mode: 'last' for the last visit, other for actual-visit;
* pass null to get an array of visit date and last visit date
* @param mixed $user_id User id to gather the data for, pass null for current user
* @param array $additional_plugins Additional types to get data for. The returned array is then enlarged
* by one dimension
* @return array associate array with the object id as key and the according data as value
*
* @note This function will respect the visit threshold defined in NEW_INDICATOR_THRESHOLD config.
*/
function get_objects_visits(array $object_ids, $plugin_id, $mode = 'last', $user_id = null, $additional_plugins = [])
{
$plugin_id = object_type_to_id($plugin_id);
// Combine types
$plugin_ids = array_merge([$plugin_id], $additional_plugins);
// Create result array with predefined values / defined threshold
$threshold = object_get_visit_threshold();
$thresholds = array_combine($plugin_ids, array_fill(
0,
count($plugin_ids),
$mode === null ? ['last_visitdate' => null, 'visitdate' => null] : null
));
$result = array_combine(
$object_ids,
array_fill(0, count($object_ids), $thresholds)
);
// Read data from database
$query = "SELECT `object_id`, `plugin_id`, `visitdate`, `last_visitdate`
FROM `object_user_visits`
WHERE `object_id` IN (:ids)
AND `plugin_id` IN (:plugin_ids)
AND `user_id` = :user_id";
$statement = DBManager::get()->prepare($query);
$statement->bindValue(':ids', $object_ids);
$statement->bindValue(':plugin_ids', $plugin_ids);
$statement->bindValue(':user_id', $user_id ?? $GLOBALS['user']->id);
$statement->execute();
$statement->setFetchMode(PDO::FETCH_ASSOC);
// Spread data from database into result array
foreach ($statement as $row) {
if ($mode === null) {
$return = [
'visitdate' => max($threshold, (int) $row['visitdate']),
'last_visitdate' => max($threshold, (int) $row['last_visitdate']),
];
} elseif ($mode === 'last') {
$return = max($threshold, (int) $row['last_visitdate']);
} else {
$return = max($threshold, (int) $row['visitdate']);
}
$result[$row['object_id']][$row['plugin_id']] = $return;
}
foreach ($result as $object_id => $plugins) {
$seminar_data = $plugins[0];
if ($mode === null && !isset($seminar_data['visitdate'])) {
$seminar_data = ['last_visitdate' => $threshold, 'visitdate' => $threshold];
$result[$object_id][0] = $seminar_data;
}
if ($mode !== null && !isset($seminar_data)) {
$seminar_data = $threshold;
$result[$object_id][0] = $seminar_data;
}
foreach ($plugins as $plugin_id => $data) {
if ($plugin_id == 0) continue;
if ($mode === null) {
if (isset($data['visitdate']) || object_id_to_type($plugin_id)) {
$result[$object_id][$plugin_id] = [
'visitdate' => $data['visitdate'] ?? max($threshold, (int)$data['visitdate']),
'last_visitdate' => $data['last_visitdate'] ?? max($threshold, (int)$data['last_visitdate'])
];
} else {
$result[$object_id][$plugin_id] = [
'visitdate' => $data['visitdate'] ?? max($seminar_data['visitdate'], (int)$data['visitdate']),
'last_visitdate' => $data['last_visitdate'] ?? max($seminar_data['last_visitdate'], (int)$data['last_visitdate'])
];
}
} elseif ($mode === 'last') {
if (isset($data) || object_id_to_type($plugin_id)) {
$result[$object_id][$plugin_id] = $data ?? max($threshold, (int)$data);
} else {
$result[$object_id][$plugin_id] = $data ?? max($seminar_data['last_visitdate'], (int)$data);
}
} else {
if (isset($data) || object_id_to_type($plugin_id)) {
$result[$object_id][$plugin_id] = $data ?? max($threshold, (int)$data);
} else {
$result[$object_id][$plugin_id] = $data ?? max($seminar_data['visitdate'], (int)$data);
}
}
}
}
// Reduce array if not additional types were passed
if (func_num_args() < 5) {
// Unfortunately array_column() will dispose the array key
$result = array_map(function ($row) use ($plugin_id) {
return $row[$plugin_id];
}, $result);
}
return $result;
}
/**
* This function gets the cutoff value for object visit dates as defined by the NEW_INDICATOR_THRESHOLD setting.
*
* @return int the timestamp of the oldest possible visit or 0
*/
function object_get_visit_threshold()
{
$threshold = Config::get()->NEW_INDICATOR_THRESHOLD;
return $threshold ? strtotime("-{$threshold} days 0:00:00") : 0;
}
function object_kill_visits($user_id, $object_ids = false)
{
if (!$user_id && !$object_ids) {
return false;
}
$query = "DELETE FROM object_user_visits WHERE ";
$parameters = [];
if ($user_id) {
$query .= "user_id = ?";
$parameters[] = $user_id;
} else {
$query .= "1";
}
if ($object_ids) {
if (!is_array($object_ids)) {
$object_ids = [$object_ids];
}
$query .= " AND object_id IN (?)";
$parameters[] = $object_ids;
}
$statement = DBManager::get()->prepare($query);
$statement->execute($parameters);
return $statement->rowCount();
}
function object_add_view ($object_id)
{
$count_view = !in_array($object_id, $_SESSION['object_cache']);
if (!$count_view) {
return;
}
$_SESSION['object_cache'][] = $object_id;
$query = "INSERT INTO object_views (object_id, views, chdate)
VALUES (?, 1, UNIX_TIMESTAMP())
ON DUPLICATE KEY UPDATE views = views + 1,
chdate = UNIX_TIMESTAMP()";
$statement = DBManager::get()->prepare($query);
$statement->execute([$object_id]);
$query = "SELECT views FROM object_views WHERE object_id = ?";
$statement = DBManager::get()->prepare($query);
$statement->execute([$object_id]);
return $statement->fetchColumn();
}
function object_kill_views($object_id)
{
if (!empty($object_id)) {
$query = "DELETE FROM object_views WHERE object_id IN (?)";
$statement = DBManager::get()->prepare($query);
$statement->execute([$object_id]);
return $statement->rowCount();
} else {
return 0;
}
}
function object_return_views ($object_id)
{
$query = "SELECT views FROM object_views WHERE object_id = ?";
$statement = DBManager::get()->prepare($query);
$statement->execute([$object_id]);
return $statement->fetchColumn() ?: 0;
}
/**
* converts a ouv type to an id
* @param $type string former used type of visited objects or module (i.e. news, documents, wiki)
* @return int
*/
function object_type_to_id($type)
{
if (is_numeric($type)) {
return $type;
}
$ouv_mapping = [
'sem' => 0,
'inst'=> 0,
'basicdata' => 0,
'vote' => -1,
'eval' => -2,
'news' => 'CoreOverview',
'documents' => 'CoreDocuments',
'schedule' => 'CoreSchedule',
'scm' => 'CoreScm',
'wiki' => 'CoreWiki',
'elearning_interface' => 'CoreElearningInterface',
'ilias_interface' => 'IliasInterfaceModule',
'participants' => 'CoreParticipants'
];
if (isset($ouv_mapping[$type])) {
$id = $ouv_mapping[$type];
if (is_numeric($id)) {
return $id;
}
$plugin = PluginEngine::getPlugin($id);
if ($plugin) {
return $plugin->getPluginId();
}
}
}
/**
* converts a plugin id to old ouv type
* @param $id int former used type of visited objects or module (i.e. news, documents, wiki)
* @return string
*/
function object_id_to_type($id)
{
if (!is_numeric($id)) {
return null;
}
$ouv_mapping = [
'sem' => 0,
'inst'=> 0,
'basicdata' => 0,
'vote' => -1,
'eval' => -2,
'news' => 'CoreOverview',
'documents' => 'CoreDocuments',
'schedule' => 'CoreSchedule',
'scm' => 'CoreScm',
'wiki' => 'CoreWiki',
'elearning_interface' => 'CoreElearningInterface',
'ilias_interface' => 'IliasInterfaceModule',
'participants' => 'CoreParticipants'
];
if (!in_array($id, [0, -1, -2])) {
$plugin = PluginManager::getInstance()->getPluginInfoById($id);
if ($plugin) {
$search = $plugin['class'];
}
} else {
$search = (int)$id;
}
if (isset($search)) {
return array_search($search, $ouv_mapping, true) ?: null;
} else {
return null;
}
}