/**
 * 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;
}
Exemple #2
0
        $template->append('related_categories', $name);
    }
}
// jump to link
//
// 1. find all linked categories that are reachable for the current user.
// 2. if a category is available in the URL, use it if reachable
// 3. if URL category not available or reachable, use the first reachable
//    linked category
// 4. if no category reachable, no jumpto link
$query = '
SELECT category_id
  FROM ' . IMAGE_CATEGORY_TABLE . '
  WHERE image_id = ' . $_GET['image_id'] . '
;';
$authorizeds = array_diff(array_from_query($query, 'category_id'), explode(',', calculate_permissions($user['id'], $user['status'])));
if (isset($_GET['cat_id']) and in_array($_GET['cat_id'], $authorizeds)) {
    $url_img = make_picture_url(array('image_id' => $_GET['image_id'], 'image_file' => $image_file, 'category' => $cache['cat_names'][$_GET['cat_id']]));
} else {
    foreach ($authorizeds as $category) {
        $url_img = make_picture_url(array('image_id' => $_GET['image_id'], 'image_file' => $image_file, 'category' => $cache['cat_names'][$category]));
        break;
    }
}
if (isset($url_img)) {
    $template->assign('U_JUMPTO', $url_img);
}
// associate to albums
$query = '
SELECT id
  FROM ' . CATEGORIES_TABLE . '
/**
 * API method
 * Returns a list of categories
 * @param mixed[] $params
 *    @option int cat_id (optional)
 *    @option bool recursive
 *    @option bool public
 *    @option bool tree_output
 *    @option bool fullname
 */
function ws_categories_getList($params, &$service)
{
    global $user, $conf;
    $where = array('1=1');
    $join_type = 'INNER';
    $join_user = $user['id'];
    if (!$params['recursive']) {
        if ($params['cat_id'] > 0) {
            $where[] = '(
        id_uppercat = ' . (int) $params['cat_id'] . '
        OR id=' . (int) $params['cat_id'] . '
      )';
        } else {
            $where[] = 'id_uppercat IS NULL';
        }
    } else {
        if ($params['cat_id'] > 0) {
            $where[] = 'uppercats ' . DB_REGEX_OPERATOR . ' \'(^|,)' . (int) $params['cat_id'] . '(,|$)\'';
        }
    }
    if ($params['public']) {
        $where[] = 'status = "public"';
        $where[] = 'visible = "true"';
        $join_user = $conf['guest_id'];
    } else {
        if (is_admin()) {
            // in this very specific case, we don't want to hide empty
            // categories. Function calculate_permissions will only return
            // categories that are either locked or private and not permitted
            //
            // calculate_permissions does not consider empty categories as forbidden
            $forbidden_categories = calculate_permissions($user['id'], $user['status']);
            $where[] = 'id NOT IN (' . $forbidden_categories . ')';
            $join_type = 'LEFT';
        }
    }
    $query = '
SELECT
    id, name, comment, permalink,
    uppercats, global_rank, id_uppercat,
    nb_images, count_images AS total_nb_images,
    representative_picture_id, user_representative_picture_id, count_images, count_categories,
    date_last, max_date_last, count_categories AS nb_categories
  FROM ' . CATEGORIES_TABLE . '
    ' . $join_type . ' JOIN ' . USER_CACHE_CATEGORIES_TABLE . '
    ON id=cat_id AND user_id=' . $join_user . '
  WHERE ' . implode("\n    AND ", $where) . '
;';
    $result = pwg_query($query);
    // management of the album thumbnail -- starts here
    $image_ids = array();
    $categories = array();
    $user_representative_updates_for = array();
    // management of the album thumbnail -- stops here
    $cats = array();
    while ($row = pwg_db_fetch_assoc($result)) {
        $row['url'] = make_index_url(array('category' => $row));
        foreach (array('id', 'nb_images', 'total_nb_images', 'nb_categories') as $key) {
            $row[$key] = (int) $row[$key];
        }
        if ($params['fullname']) {
            $row['name'] = strip_tags(get_cat_display_name_cache($row['uppercats'], null));
        } else {
            $row['name'] = strip_tags(trigger_change('render_category_name', $row['name'], 'ws_categories_getList'));
        }
        $row['comment'] = strip_tags(trigger_change('render_category_description', $row['comment'], 'ws_categories_getList'));
        // management of the album thumbnail -- starts here
        //
        // on branch 2.3, the algorithm is duplicated from
        // include/category_cats, but we should use a common code for Piwigo 2.4
        //
        // warning : if the API method is called with $params['public'], the
        // album thumbnail may be not accurate. The thumbnail can be viewed by
        // the connected user, but maybe not by the guest. Changing the
        // filtering method would be too complicated for now. We will simply
        // avoid to persist the user_representative_picture_id in the database
        // if $params['public']
        if (!empty($row['user_representative_picture_id'])) {
            $image_id = $row['user_representative_picture_id'];
        } else {
            if (!empty($row['representative_picture_id'])) {
                // if a representative picture is set, it has priority
                $image_id = $row['representative_picture_id'];
            } else {
                if ($conf['allow_random_representative']) {
                    // searching a random representant among elements in sub-categories
                    $image_id = get_random_image_in_category($row);
                } else {
                    // searching a random representant among representant of sub-categories
                    if ($row['count_categories'] > 0 and $row['count_images'] > 0) {
                        $query = '
SELECT representative_picture_id
  FROM ' . CATEGORIES_TABLE . '
    INNER JOIN ' . USER_CACHE_CATEGORIES_TABLE . '
    ON id=cat_id AND user_id=' . $user['id'] . '
  WHERE uppercats LIKE \'' . $row['uppercats'] . ',%\'
    AND representative_picture_id IS NOT NULL
        ' . get_sql_condition_FandF(array('visible_categories' => 'id'), "\n  AND") . '
  ORDER BY ' . DB_RANDOM_FUNCTION . '()
  LIMIT 1
;';
                        $subresult = pwg_query($query);
                        if (pwg_db_num_rows($subresult) > 0) {
                            list($image_id) = pwg_db_fetch_row($subresult);
                        }
                    }
                }
            }
        }
        if (isset($image_id)) {
            if ($conf['representative_cache_on_subcats'] and $row['user_representative_picture_id'] != $image_id) {
                $user_representative_updates_for[$row['id']] = $image_id;
            }
            $row['representative_picture_id'] = $image_id;
            $image_ids[] = $image_id;
            $categories[] = $row;
        }
        unset($image_id);
        // management of the album thumbnail -- stops here
        $cats[] = $row;
    }
    usort($cats, 'global_rank_compare');
    // management of the album thumbnail -- starts here
    if (count($categories) > 0) {
        $thumbnail_src_of = array();
        $new_image_ids = array();
        $query = '
SELECT id, path, representative_ext, level
  FROM ' . IMAGES_TABLE . '
  WHERE id IN (' . implode(',', $image_ids) . ')
;';
        $result = pwg_query($query);
        while ($row = pwg_db_fetch_assoc($result)) {
            if ($row['level'] <= $user['level']) {
                $thumbnail_src_of[$row['id']] = DerivativeImage::thumb_url($row);
            } else {
                // problem: we must not display the thumbnail of a photo which has a
                // higher privacy level than user privacy level
                //
                // * what is the represented category?
                // * find a random photo matching user permissions
                // * register it at user_representative_picture_id
                // * set it as the representative_picture_id for the category
                foreach ($categories as &$category) {
                    if ($row['id'] == $category['representative_picture_id']) {
                        // searching a random representant among elements in sub-categories
                        $image_id = get_random_image_in_category($category);
                        if (isset($image_id) and !in_array($image_id, $image_ids)) {
                            $new_image_ids[] = $image_id;
                        }
                        if ($conf['representative_cache_on_level']) {
                            $user_representative_updates_for[$category['id']] = $image_id;
                        }
                        $category['representative_picture_id'] = $image_id;
                    }
                }
                unset($category);
            }
        }
        if (count($new_image_ids) > 0) {
            $query = '
SELECT id, path, representative_ext
  FROM ' . IMAGES_TABLE . '
  WHERE id IN (' . implode(',', $new_image_ids) . ')
;';
            $result = pwg_query($query);
            while ($row = pwg_db_fetch_assoc($result)) {
                $thumbnail_src_of[$row['id']] = DerivativeImage::thumb_url($row);
            }
        }
    }
    // compared to code in include/category_cats, we only persist the new
    // user_representative if we have used $user['id'] and not the guest id,
    // or else the real guest may see thumbnail that he should not
    if (!$params['public'] and count($user_representative_updates_for)) {
        $updates = array();
        foreach ($user_representative_updates_for as $cat_id => $image_id) {
            $updates[] = array('user_id' => $user['id'], 'cat_id' => $cat_id, 'user_representative_picture_id' => $image_id);
        }
        mass_updates(USER_CACHE_CATEGORIES_TABLE, array('primary' => array('user_id', 'cat_id'), 'update' => array('user_representative_picture_id')), $updates);
    }
    foreach ($cats as &$cat) {
        foreach ($categories as $category) {
            if ($category['id'] == $cat['id'] and isset($category['representative_picture_id'])) {
                $cat['tn_url'] = $thumbnail_src_of[$category['representative_picture_id']];
            }
        }
        // we don't want them in the output
        unset($cat['user_representative_picture_id'], $cat['count_images'], $cat['count_categories']);
    }
    unset($cat);
    // management of the album thumbnail -- stops here
    if ($params['tree_output']) {
        return categories_flatlist_to_tree($cats);
    }
    return array('categories' => new PwgNamedArray($cats, 'category', ws_std_get_category_xml_attributes()));
}
function pshare_section_init()
{
    global $tokens, $page, $conf, $user, $template;
    if ($tokens[0] == 'pshare') {
        $page['section'] = 'pshare';
        $page['title'] = l10n('Shared Picture');
        if (!isset($tokens[1])) {
            die("missing key");
        }
        if (!preg_match(PSHARE_KEY_PATTERN, $tokens[1])) {
            die("invalid key");
        }
        $page['pshare_key'] = $tokens[1];
        $query = '
SELECT
    *,
    NOW() AS dbnow
  FROM ' . PSHARE_KEYS_TABLE . '
  WHERE uuid = \'' . $page['pshare_key'] . '\'
;';
        $shares = query2array($query);
        if (count($shares) == 0) {
            die('unknown key');
        }
        $share = $shares[0];
        pshare_log($share['pshare_key_id'], 'visit');
        // is the key still valid?
        if (strtotime($share['expire_on']) < strtotime($share['dbnow'])) {
            die('expired key');
        }
        // if the user is permitted for this photo, let's redirect to
        // picture.php (with full details and actions)
        if (!is_a_guest() and pshare_is_photo_visible($share['image_id'])) {
            // find the first reachable category linked to the photo
            $query = '
SELECT category_id
  FROM ' . IMAGE_CATEGORY_TABLE . '
  WHERE image_id = ' . $share['image_id'] . '
;';
            $authorizeds = array_diff(array_from_query($query, 'category_id'), explode(',', calculate_permissions($user['id'], $user['status'])));
            foreach ($authorizeds as $category_id) {
                $url = make_picture_url(array('image_id' => $share['image_id'], 'category' => get_cat_info($category_id)));
                if (function_exists('Fotorama_is_replace_picture') and Fotorama_is_replace_picture()) {
                    $url .= '&slidestop';
                }
                redirect($url);
            }
            redirect(make_picture_url(array('image_id' => $share['image_id'])));
        }
        $query = '
SELECT *
  FROM ' . IMAGES_TABLE . '
  WHERE id = ' . $share['image_id'] . '
;';
        $rows = query2array($query);
        $image = $rows[0];
        $src_image = new SrcImage($image);
        if (isset($tokens[2]) && 'download' == $tokens[2]) {
            $format_id = null;
            if (isset($tokens[3]) && preg_match('/^f(\\d+)$/', $tokens[3], $matches)) {
                $format_id = $matches[1];
                $query = '
SELECT
    *
  FROM ' . IMAGE_FORMAT_TABLE . '
  WHERE format_id = ' . $format_id . '
    AND image_id = ' . $image['id'] . '
;';
                $formats = query2array($query);
                if (count($formats) == 0) {
                    do_error(400, 'Invalid request - format');
                }
                $format = $formats[0];
                $file = original_to_format(get_element_path($image), $format['ext']);
                $image['file'] = get_filename_wo_extension($image['file']) . '.' . $format['ext'];
            } else {
                $file = $image['path'];
            }
            $gmt_mtime = gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT';
            $http_headers = array('Content-Length: ' . @filesize($file), 'Last-Modified: ' . $gmt_mtime, 'Content-Type: ' . mime_content_type($file), 'Content-Disposition: attachment; filename="' . $image['file'] . '";', 'Content-Transfer-Encoding: binary');
            foreach ($http_headers as $header) {
                header($header);
            }
            readfile($file);
            pshare_log($share['pshare_key_id'], 'download', $format_id);
            exit;
        }
        $template->set_filename('shared_picture', realpath(PSHARE_PATH . 'template/shared_picture.tpl'));
        $derivative = new DerivativeImage(ImageStdParams::get_by_type(IMG_MEDIUM), $src_image);
        $derivative_size = $derivative->get_size();
        // a random string to avoid browser cache
        $rand = '&amp;download=' . substr(md5(time()), 0, 6);
        $template->assign(array('SRC' => $derivative->get_url(), 'IMG_WIDTH' => $derivative_size[0], 'IMG_HEIGHT' => $derivative_size[1], 'DOWNLOAD_URL' => duplicate_index_url() . '/' . $page['pshare_key'] . '/download' . $rand));
        // formats
        if (defined('IMAGE_FORMAT_TABLE')) {
            $query = '
SELECT *
  FROM ' . IMAGE_FORMAT_TABLE . '
  WHERE image_id = ' . $share['image_id'] . '
;';
            $formats = query2array($query);
            if (!empty($formats)) {
                foreach ($formats as &$format) {
                    $format['download_url'] = duplicate_index_url() . '/' . $page['pshare_key'] . '/download';
                    $format['download_url'] .= '/f' . $format['format_id'] . $rand;
                    $format['filesize'] = sprintf('%.1fMB', $format['filesize'] / 1024);
                }
            }
            $template->assign('formats', $formats);
        }
        $template->parse('shared_picture');
        $template->p();
        exit;
    }
}