/** * Finds informations related to the user identifier. * * @param int $user_id * @param boolean $use_cache * @return array */ function getuserdata($user_id, $use_cache = false) { global $conf; // retrieve basic user data $query = ' SELECT '; $is_first = true; foreach ($conf['user_fields'] as $pwgfield => $dbfield) { if ($is_first) { $is_first = false; } else { $query .= ' , '; } $query .= $dbfield . ' AS ' . $pwgfield; } $query .= ' FROM ' . USERS_TABLE . ' WHERE ' . $conf['user_fields']['id'] . ' = \'' . $user_id . '\''; $row = pwg_db_fetch_assoc(pwg_query($query)); // retrieve additional user data ? if ($conf['external_authentification']) { $query = ' SELECT COUNT(1) AS counter FROM ' . USER_INFOS_TABLE . ' AS ui LEFT JOIN ' . USER_CACHE_TABLE . ' AS uc ON ui.user_id = uc.user_id LEFT JOIN ' . THEMES_TABLE . ' AS t ON t.id = ui.theme WHERE ui.user_id = ' . $user_id . ' GROUP BY ui.user_id ;'; list($counter) = pwg_db_fetch_row(pwg_query($query)); if ($counter != 1) { create_user_infos($user_id); } } // retrieve user info $query = ' SELECT ui.*, uc.*, t.name AS theme_name FROM ' . USER_INFOS_TABLE . ' AS ui LEFT JOIN ' . USER_CACHE_TABLE . ' AS uc ON ui.user_id = uc.user_id LEFT JOIN ' . THEMES_TABLE . ' AS t ON t.id = ui.theme WHERE ui.user_id = ' . $user_id . ' ;'; $result = pwg_query($query); $user_infos_row = pwg_db_fetch_assoc($result); // then merge basic + additional user data $userdata = array_merge($row, $user_infos_row); foreach ($userdata as &$value) { // If the field is true or false, the variable is transformed into a boolean value. if ($value == 'true') { $value = true; } elseif ($value == 'false') { $value = false; } } unset($value); if ($use_cache) { if (!isset($userdata['need_update']) or !is_bool($userdata['need_update']) or $userdata['need_update'] == true) { $userdata['cache_update_time'] = time(); // Set need update are done $userdata['need_update'] = false; $userdata['forbidden_categories'] = calculate_permissions($userdata['id'], $userdata['status']); /* now we build the list of forbidden images (this list does not contain images that are not in at least an authorized category)*/ $query = ' SELECT DISTINCT(id) FROM ' . IMAGES_TABLE . ' INNER JOIN ' . IMAGE_CATEGORY_TABLE . ' ON id=image_id WHERE category_id NOT IN (' . $userdata['forbidden_categories'] . ') AND level>' . $userdata['level']; $forbidden_ids = query2array($query, null, 'id'); if (empty($forbidden_ids)) { $forbidden_ids[] = 0; } $userdata['image_access_type'] = 'NOT IN'; //TODO maybe later $userdata['image_access_list'] = implode(',', $forbidden_ids); $query = ' SELECT COUNT(DISTINCT(image_id)) as total FROM ' . IMAGE_CATEGORY_TABLE . ' WHERE category_id NOT IN (' . $userdata['forbidden_categories'] . ') AND image_id ' . $userdata['image_access_type'] . ' (' . $userdata['image_access_list'] . ')'; list($userdata['nb_total_images']) = pwg_db_fetch_row(pwg_query($query)); // now we update user cache categories $user_cache_cats = get_computed_categories($userdata, null); if (!is_admin($userdata['status'])) { // for non admins we forbid categories with no image (feature 1053) $forbidden_ids = array(); foreach ($user_cache_cats as $cat) { if ($cat['count_images'] == 0) { $forbidden_ids[] = $cat['cat_id']; remove_computed_category($user_cache_cats, $cat); } } if (!empty($forbidden_ids)) { if (empty($userdata['forbidden_categories'])) { $userdata['forbidden_categories'] = implode(',', $forbidden_ids); } else { $userdata['forbidden_categories'] .= ',' . implode(',', $forbidden_ids); } } } // delete user cache $query = ' DELETE FROM ' . USER_CACHE_CATEGORIES_TABLE . ' WHERE user_id = ' . $userdata['id']; pwg_query($query); // Due to concurrency issues, we ask MySQL to ignore errors on // insert. This may happen when cache needs refresh and that Piwigo is // called "very simultaneously". mass_inserts(USER_CACHE_CATEGORIES_TABLE, array('user_id', 'cat_id', 'date_last', 'max_date_last', 'nb_images', 'count_images', 'nb_categories', 'count_categories'), $user_cache_cats, array('ignore' => true)); // update user cache $query = ' DELETE FROM ' . USER_CACHE_TABLE . ' WHERE user_id = ' . $userdata['id']; pwg_query($query); // for the same reason as user_cache_categories, we ignore error on // this insert $query = ' INSERT IGNORE INTO ' . USER_CACHE_TABLE . ' (user_id, need_update, cache_update_time, forbidden_categories, nb_total_images, last_photo_date, image_access_type, image_access_list) VALUES (' . $userdata['id'] . ',\'' . boolean_to_string($userdata['need_update']) . '\',' . $userdata['cache_update_time'] . ',\'' . $userdata['forbidden_categories'] . '\',' . $userdata['nb_total_images'] . ',' . (empty($userdata['last_photo_date']) ? 'NULL' : '\'' . $userdata['last_photo_date'] . '\'') . ',\'' . $userdata['image_access_type'] . '\',\'' . $userdata['image_access_list'] . '\')'; pwg_query($query); } } return $userdata; }
/** * Get computed array of categories, that means cache data of all categories * available for the current user (count_categories, count_images, etc.). * * @param array &$userdata * @param int $filter_days number of recent days to filter on or null * @return array */ function get_computed_categories(&$userdata, $filter_days = null) { $query = 'SELECT c.id AS cat_id, id_uppercat'; $query .= ', global_rank'; // Count by date_available to avoid count null $query .= ', MAX(date_available) AS date_last, COUNT(date_available) AS nb_images FROM ' . CATEGORIES_TABLE . ' as c LEFT JOIN ' . IMAGE_CATEGORY_TABLE . ' AS ic ON ic.category_id = c.id LEFT JOIN ' . IMAGES_TABLE . ' AS i ON ic.image_id = i.id AND i.level<=' . $userdata['level']; if (isset($filter_days)) { $query .= ' AND i.date_available > ' . pwg_db_get_recent_period_expression($filter_days); } if (!empty($userdata['forbidden_categories'])) { $query .= ' WHERE c.id NOT IN (' . $userdata['forbidden_categories'] . ')'; } $query .= ' GROUP BY c.id'; $result = pwg_query($query); $userdata['last_photo_date'] = null; $cats = array(); while ($row = pwg_db_fetch_assoc($result)) { $row['user_id'] = $userdata['id']; $row['nb_categories'] = 0; $row['count_categories'] = 0; $row['count_images'] = (int) $row['nb_images']; $row['max_date_last'] = $row['date_last']; if ($row['date_last'] > $userdata['last_photo_date']) { $userdata['last_photo_date'] = $row['date_last']; } $cats[$row['cat_id']] = $row; } // it is important to logically sort the albums because some operations // (like removal) rely on this logical order. Child album doesn't always // have a bigger id than its parent (if it was moved afterwards). uasort($cats, 'global_rank_compare'); foreach ($cats as $cat) { if (!isset($cat['id_uppercat'])) { continue; } // Piwigo before 2.5.3 may have generated inconsistent permissions, ie // private album A1/A2 permitted to user U1 but private album A1 not // permitted to U1. // // TODO 2.7: add an upgrade script to repair permissions and remove this // test if (!isset($cats[$cat['id_uppercat']])) { continue; } $parent =& $cats[$cat['id_uppercat']]; $parent['nb_categories']++; do { $parent['count_images'] += $cat['nb_images']; $parent['count_categories']++; if (empty($parent['max_date_last']) or $parent['max_date_last'] < $cat['date_last']) { $parent['max_date_last'] = $cat['date_last']; } if (!isset($parent['id_uppercat'])) { break; } $parent =& $cats[$parent['id_uppercat']]; } while (true); unset($parent); } if (isset($filter_days)) { foreach ($cats as $category) { if (empty($category['max_date_last'])) { remove_computed_category($cats, $category); } } } return $cats; }