First commit

This commit is contained in:
Nathan
2026-09-18 20:29:17 -06:00
commit 3b09abe571
2840 changed files with 467153 additions and 0 deletions
@@ -0,0 +1,15 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
// Recursive call
$url = '../';
header( 'Request-URI: '.$url );
header( 'Content-Location: '.$url );
header( 'Location: '.$url );
exit();
?>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,243 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
/**
* API method
* Get comments
* @since 16
* @param mixed[] $params
*
*/
function ws_userComments_getList($params, &$service)
{
global $conf;
if (!$conf['activate_comments'])
{
return new PwgError(403, 'Comments are disabled');
}
// accepted status values
$accepted_status = array('all', 'pending', 'validated');
if (!in_array($params['status'], $accepted_status))
{
return new PwgError(401, 'Status must be: all, pending or validated');
}
// accepted values must match pagination options (5,10,25,50)
$items_number = array(5, 10, 25, 50);
if (!in_array($params['per_page'], $items_number))
{
return new PwgError(401, 'Per page must be: 5, 10, 25 or 50');
}
$where_clauses = array('1=1');
if (isset($params['author_id']) and !empty($params['author_id']))
{
$where_clauses['author_id'] = 'author_id = \''. pwg_db_real_escape_string($params['author_id']) .'\'';
}
if (isset($params['image_id']) and !empty($params['image_id']))
{
$where_clauses[] = 'image_id = \''. pwg_db_real_escape_string($params['image_id']) .'\'';
}
if (!empty($params['f_min_date']))
{
$min = date_format(date_create($params['f_min_date']), "Y-m-d 00:00:00");
$where_clauses[] = 'date >= \''. $min .'\'';
}
if (!empty($params['f_max_date']))
{
$max = date_format(date_create($params['f_max_date']), "Y-m-d 23:59:59");
$where_clauses[] = 'date <= \''. $max .'\'';
}
// reset all filters during search
if (!empty($params['search']))
{
$where_clauses = array('1=1');
$where_clauses[] = 'content LIKE "%'. pwg_db_real_escape_string($params['search']) .'%"';
}
// summary
$query = '
SELECT
count(*) as all_comments,
sum(validated = \'true\') as validated,
sum(validated = \'false\') as pending
FROM '.COMMENTS_TABLE.'
WHERE '.implode(' AND ', $where_clauses).'
;';
$summary = pwg_db_fetch_assoc(pwg_query($query));
$total_comments = $summary['all_comments'];
switch($params['status'])
{
case 'pending':
$where_clauses[] = 'validated = \'false\'';
$total_comments = $summary['pending'];
break;
case 'validated':
$where_clauses[] = 'validated = \'true\'';
$total_comments = $summary['validated'];
break;
}
// comments
$query = '
SELECT
c.id,
c.image_id,
c.date,
c.author,
c.author_id,
'.$conf['user_fields']['username'].' AS username,
ui.status,
c.content,
i.path,
i.representative_ext,
i.file,
i.date_available,
validated,
c.anonymous_id
FROM '.COMMENTS_TABLE.' AS c
INNER JOIN '.IMAGES_TABLE.' AS i
ON i.id = c.image_id
LEFT JOIN '.USERS_TABLE.' AS u
ON u.'.$conf['user_fields']['id'].' = c.author_id
LEFT JOIN '.USER_INFOS_TABLE.' AS ui
ON ui.user_id = c.author_id
WHERE '.implode(' AND ', $where_clauses).'
ORDER BY c.date DESC
LIMIT '.$params['per_page'] * $params['page'].', '.$params['per_page'].'
;';
$result = pwg_query($query);
$list = array();
while ($row = pwg_db_fetch_assoc($result))
{
$medium = DerivativeImage::get_one(
IMG_MEDIUM,
array(
'id' => $row['image_id'],
'path' => $row['path'],
'representative_ext' => $row['representative_ext'],
)
)->get_url();
if (empty($row['author_id']) or $row['author_id'] == $conf['guest_id'])
{
$author_name = $row['author'];
}
else
{
$author_name = stripslashes($row['username'] ?? $row['author'] ?? l10n('guest'));
}
$list[] = array(
'id' => $row['id'],
'admin_link' => get_root_url().'admin.php?page=photo-'.$row['image_id'],
'medium_url' => $medium,
'file' => $row['file'],
'image_date_available' => format_date($row['date_available'], array('day_name','day','month','year','time')),
'author' => trigger_change('render_comment_author', $author_name),
'author_status' => $conf['webmaster_id'] == $row['author_id'] ? 'main_user' : $row['status'],
'date' => format_date($row['date'], array('day_name','day','month','year','time')),
'content' => trigger_change('render_comment_content', $row['content']),
'raw_content' => $row['content'],
'is_pending' => ('false' == $row['validated']),
);
}
// filters
$query = '
SELECT
MIN(date) AS started_at,
MAX(date) AS ended_at
FROM '.COMMENTS_TABLE.'
WHERE '.implode(' AND ', $where_clauses).'
;';
$dates = pwg_db_fetch_assoc(pwg_query($query));
unset($where_clauses['author_id']);
$query = '
SELECT
author,
author_id,
count(*) as nb_authors
FROM '.COMMENTS_TABLE.'
WHERE '.implode(' AND ', $where_clauses).'
GROUP BY author_id
;';
$nb_authors_in = query2array($query);
return array(
'summary' => $summary,
'comments' => $list,
'filters' => array(
'nb_authors' => $nb_authors_in,
'started_at' => $dates['started_at'],
'ended_at' => $dates['ended_at']
),
'paging' => array(
'page' => $params['page'],
'per_page' => $params['per_page'],
'total_pages' => max(0, ceil($total_comments / $params['per_page']) - 1),
),
);
}
/**
* API method
* Delete comments
* @since 16
* @param mixed[] $params
*
*/
function ws_userComments_delete($params, &$service)
{
include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, l10n('Invalid security token'));
}
$params['comment_id'] = array_unique($params['comment_id']);
delete_user_comment($params['comment_id']);
return 'Comment successfully deleted';
}
/**
* API method
* Validate comments
* @since 16
* @param mixed[] $params
*
*/
function ws_userComments_validate($params, &$service)
{
include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, l10n('Invalid security token'));
}
$params['comment_id'] = array_unique($params['comment_id']);
validate_user_comment($params['comment_id']);
return 'Comment successfully validated';
}
@@ -0,0 +1,363 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
/**
* API method
* Returns the list of all plugins
* @param mixed[] $params
*/
function ws_plugins_getList($params, $service)
{
include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
$plugins = new plugins();
$plugins->sort_fs_plugins('name');
$plugin_list = array();
foreach ($plugins->fs_plugins as $plugin_id => $fs_plugin)
{
if (isset($plugins->db_plugins_by_id[$plugin_id]))
{
$state = $plugins->db_plugins_by_id[$plugin_id]['state'];
}
else
{
$state = 'uninstalled';
}
$plugin_list[] = array(
'id' => $plugin_id,
'name' => $fs_plugin['name'],
'version' => $fs_plugin['version'],
'state' => $state,
'description' => $fs_plugin['description'],
);
}
return $plugin_list;
}
/**
* API method
* Performs an action on a plugin
* @param mixed[] $params
* @option string action
* @option string plugin
* @option string pwg_token
*/
function ws_plugins_performAction($params, $service)
{
global $template, $conf;
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
if (!is_webmaster())
{
return new PwgError(403, l10n('Webmaster status is required.'));
}
if (!$conf['enable_extensions_install'] and 'delete' == $params['action'])
{
return new PwgError(401, 'Piwigo extensions install/update/delete system is disabled');
}
define('IN_ADMIN', true);
include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
$plugins = new plugins();
$errors = $plugins->perform_action($params['action'], $params['plugin']);
if (!empty($errors))
{
return new PwgError(500, $errors);
}
else
{
if (in_array($params['action'], array('activate', 'deactivate')))
{
$template->delete_compiled_templates();
}
return true;
}
}
/**
* API method
* Performs an action on a theme
* @param mixed[] $params
* @option string action
* @option string theme
* @option string pwg_token
*/
function ws_themes_performAction($params, $service)
{
global $template, $conf;
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
if (!$conf['enable_extensions_install'] and 'delete' == $params['action'])
{
return new PwgError(401, 'Piwigo extensions install/update/delete system is disabled');
}
define('IN_ADMIN', true);
include_once(PHPWG_ROOT_PATH.'admin/include/themes.class.php');
$themes = new themes();
$errors = $themes->perform_action($params['action'], $params['theme']);
if (!empty($errors))
{
return new PwgError(500, $errors);
}
else
{
if (in_array($params['action'], array('activate', 'deactivate')))
{
$template->delete_compiled_templates();
}
return true;
}
}
/**
* API method
* Updates an extension
* @param mixed[] $params
* @option string type
* @option string id
* @option string revision
* @option string pwg_token
* @option bool reactivate (optional - undocumented)
*/
function ws_extensions_update($params, $service)
{
global $conf;
if (!$conf['enable_extensions_install'])
{
return new PwgError(401, 'Piwigo extensions install/update system is disabled');
}
if (!is_webmaster())
{
return new PwgError(401, l10n('Webmaster status is required.'));
}
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
if (!in_array($params['type'], array('plugins', 'themes', 'languages')))
{
return new PwgError(403, "invalid extension type");
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
include_once(PHPWG_ROOT_PATH.'admin/include/'.$params['type'].'.class.php');
$type = $params['type'];
$extension_id = $params['id'];
$revision = $params['revision'];
$extension = new $type();
if ($type == 'plugins')
{
if (
isset($extension->db_plugins_by_id[$extension_id])
and $extension->db_plugins_by_id[$extension_id]['state'] == 'active'
)
{
$extension->perform_action('deactivate', $extension_id);
redirect(PHPWG_ROOT_PATH
. 'ws.php'
. '?method=pwg.extensions.update'
. '&type=plugins'
. '&id=' . $extension_id
. '&revision=' . $revision
. '&reactivate=true'
. '&pwg_token=' . get_pwg_token()
. '&format=json'
);
}
list($upgrade_status) = $extension->perform_action('update', $extension_id, array('revision'=>$revision));
$extension_name = $extension->fs_plugins[$extension_id]['name'];
if (isset($params['reactivate']))
{
$extension->perform_action('activate', $extension_id);
}
}
else if ($type == 'themes')
{
$upgrade_status = $extension->extract_theme_files('upgrade', $revision, $extension_id);
$extension_name = $extension->fs_themes[$extension_id]['name'];
$activity_details = array('theme_id'=>$extension_id, 'from_version'=>$extension->fs_themes[$extension_id]['version']);
if ('ok' == $upgrade_status)
{
$extension->get_fs_themes(); // refresh list
$activity_details['to_version'] = $extension->fs_themes[$extension_id]['version'];
}
else
{
$activity_details['result'] = 'error';
}
pwg_activity('system', ACTIVITY_SYSTEM_THEME, 'update', $activity_details);
}
else if ($type == 'languages')
{
$upgrade_status = $extension->extract_language_files('upgrade', $revision, $extension_id);
$extension_name = $extension->fs_languages[$extension_id]['name'];
}
global $template;
$template->delete_compiled_templates();
switch ($upgrade_status)
{
case 'ok':
return l10n('%s has been successfully updated.', $extension_name);
case 'temp_path_error':
return new PwgError(null, l10n('Can\'t create temporary file.'));
case 'dl_archive_error':
return new PwgError(null, l10n('Can\'t download archive.'));
case 'archive_error':
return new PwgError(null, l10n('Can\'t read or extract archive.'));
default:
return new PwgError(null, l10n('An error occured during extraction (%s).', $upgrade_status));
}
}
/**
* API method
* Ignore an update
* @param mixed[] $params
* @option string type (optional)
* @option string id (optional)
* @option bool reset
* @option string pwg_token
*/
function ws_extensions_ignoreupdate($params, $service)
{
global $conf;
define('IN_ADMIN', true);
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
if (!is_webmaster())
{
return new PwgError(401, 'Access denied');
}
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$conf['updates_ignored'] = unserialize($conf['updates_ignored']);
// Reset ignored extension
if ($params['reset'])
{
if (!empty($params['type']) and isset($conf['updates_ignored'][ $params['type'] ]))
{
$conf['updates_ignored'][$params['type']] = array();
}
else
{
$conf['updates_ignored'] = array(
'plugins'=>array(),
'themes'=>array(),
'languages'=>array()
);
}
conf_update_param('updates_ignored', pwg_db_real_escape_string(serialize($conf['updates_ignored'])));
unset($_SESSION['extensions_need_update']);
return true;
}
if (empty($params['id']) or empty($params['type']) or !in_array($params['type'], array('plugins', 'themes', 'languages')))
{
return new PwgError(403, 'Invalid parameters');
}
// Add or remove extension from ignore list
if (!in_array($params['id'], $conf['updates_ignored'][ $params['type'] ]))
{
$conf['updates_ignored'][ $params['type'] ][] = $params['id'];
}
conf_update_param('updates_ignored', pwg_db_real_escape_string(serialize($conf['updates_ignored'])));
unset($_SESSION['extensions_need_update']);
return true;
}
/**
* API method
* Checks for updates (core and extensions)
* @param mixed[] $params
*/
function ws_extensions_checkupdates($params, $service)
{
global $conf;
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
include_once(PHPWG_ROOT_PATH.'admin/include/updates.class.php');
$update = new updates();
$result = array();
if (!isset($_SESSION['need_update'.PHPWG_VERSION]))
{
$update->check_piwigo_upgrade();
}
$result['piwigo_need_update'] = $_SESSION['need_update'.PHPWG_VERSION];
$conf['updates_ignored'] = unserialize($conf['updates_ignored']);
if (!isset($_SESSION['extensions_need_update']))
{
$update->check_extensions();
}
else
{
$update->check_updated_extensions();
}
if (!is_array($_SESSION['extensions_need_update']))
{
$result['ext_need_update'] = null;
}
else
{
$result['ext_need_update'] = !empty($_SESSION['extensions_need_update']);
}
return $result;
}
?>
@@ -0,0 +1,468 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
/**
* API method
* Returns the list of groups
* @param mixed[] $params
* @option int[] group_id (optional)
* @option string name (optional)
*/
function ws_groups_getList($params, &$service)
{
if (!preg_match(PATTERN_ORDER, $params['order']))
{
return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid input parameter order');
}
$where_clauses = array('1=1');
if (!empty($params['name']))
{
$where_clauses[] = 'LOWER(name) LIKE \''. pwg_db_real_escape_string($params['name']) .'\'';
}
if (!empty($params['group_id']))
{
$where_clauses[] = 'id IN('. implode(',', $params['group_id']) .')';
}
$query = '
SELECT
g.*, COUNT(user_id) AS nb_users
FROM `'. GROUPS_TABLE .'` AS g
LEFT JOIN '. USER_GROUP_TABLE .' AS ug
ON ug.group_id = g.id
WHERE '. implode(' AND ', $where_clauses) .'
GROUP BY id
ORDER BY '. $params['order'] .'
LIMIT '. $params['per_page'] .'
OFFSET '. ($params['per_page']*$params['page']) .'
;';
$groups = array_from_query($query);
return array(
'paging' => new PwgNamedStruct(array(
'page' => $params['page'],
'per_page' => $params['per_page'],
'count' => count($groups)
)),
'groups' => new PwgNamedArray($groups, 'group')
);
}
/**
* API method
* Adds a group
* @param mixed[] $params
* @option string name
* @option bool is_default
*/
function ws_groups_add($params, &$service)
{
$params['name'] = pwg_db_real_escape_string(strip_tags(stripslashes($params['name'])));
// is the name not already used ?
$query = '
SELECT COUNT(*)
FROM `'.GROUPS_TABLE.'`
WHERE name = \''.$params['name'].'\'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This name is already used by another group.');
}
if (strlen(str_replace( " ", "", $params['name'])) == 0) {
return new PwgError(WS_ERR_INVALID_PARAM, 'Name field must not be empty');
}
// creating the group
single_insert(
GROUPS_TABLE,
array(
'name' => $params['name'],
'is_default' => boolean_to_string($params['is_default']),
)
);
$inserted_id = pwg_db_insert_id();
pwg_activity('group', $inserted_id, 'add');
return $service->invoke('pwg.groups.getList', array('group_id' => $inserted_id));
}
/**
* API method
* Deletes a group
* @param mixed[] $params
* @option int[] group_id
* @option string pwg_token
*/
function ws_groups_delete($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
$groupnames = array_values(delete_groups($params['group_id']));
invalidate_user_cache();
return new PwgNamedArray($groupnames, 'group_deleted');
}
/**
* API method
* Updates a group
* @param mixed[] $params
* @option int group_id
* @option string name (optional)
* @option bool is_default (optional)
*/
function ws_groups_setInfo($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
if (isset($params['name']) && strlen(str_replace( " ", "", $params['name'])) == 0) {
return new PwgError(WS_ERR_INVALID_PARAM, 'Name field must not be empty');
}
$updates = array();
// does the group exist ?
$query = '
SELECT COUNT(*)
FROM `'. GROUPS_TABLE .'`
WHERE id = '. $params['group_id'] .'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count == 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This group does not exist.');
}
if (!empty($params['name']))
{
$params['name'] = pwg_db_real_escape_string(strip_tags(stripslashes($params['name'])));
// is the name not already used ?
$query = '
SELECT COUNT(*)
FROM `'. GROUPS_TABLE .'`
WHERE name = \''. $params['name'] .'\'
AND id != '.$params['group_id'].'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This name is already used by another group.');
}
$updates['name'] = $params['name'];
}
if (!empty($params['is_default']) or @$params['is_default']===false)
{
$updates['is_default'] = boolean_to_string($params['is_default']);
}
single_update(
GROUPS_TABLE,
$updates,
array('id' => $params['group_id'])
);
pwg_activity('group', $params['group_id'], 'edit');
return $service->invoke('pwg.groups.getList', array('group_id' => $params['group_id']));
}
/**
* API method
* Adds user(s) to a group
* @param mixed[] $params
* @option int group_id
* @option int[] user_id
*/
function ws_groups_addUser($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
// does the group exist ?
$query = '
SELECT COUNT(*)
FROM `'. GROUPS_TABLE .'`
WHERE id = '. $params['group_id'] .'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count == 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This group does not exist.');
}
$inserts = array();
foreach ($params['user_id'] as $user_id)
{
$inserts[] = array(
'group_id' => $params['group_id'],
'user_id' => $user_id,
);
}
mass_inserts(
USER_GROUP_TABLE,
array('group_id', 'user_id'),
$inserts,
array('ignore' => true)
);
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
invalidate_user_cache();
pwg_activity('group', $params['group_id'], 'edit');
pwg_activity('user', $params['user_id'], 'edit');
return $service->invoke('pwg.groups.getList', array('group_id' => $params['group_id']));
}
/**
* API method
* Merge groups in one other group
* @param mixed[] $params
* @option int destination_group_id
* @option int[] merge_group_id
*/
function ws_groups_merge($params, &$service) {
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$all_groups = $params['merge_group_id'];
array_push($all_groups, $params['destination_group_id']);
$all_groups = array_unique($all_groups);
$merge_group = array_diff($params['merge_group_id'], array($params['destination_group_id']));
$merge_group_object = $service->invoke('pwg.groups.getList', array('group_id' => $params['merge_group_id']));
$query = '
SELECT COUNT(*)
FROM `'. GROUPS_TABLE .'`
WHERE id in ('.implode(',', $all_groups) .')
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != count($all_groups))
{
return new PwgError(WS_ERR_INVALID_PARAM, 'All groups does not exist.');
}
$user_in_merge_groups = array();
$user_in_dest = array();
$user_to_add = array();
$query = '
SELECT DISTINCT(user_id)
FROM `'. USER_GROUP_TABLE .'`
WHERE
group_id IN ('.implode(',', $merge_group) .')
;';
$user_in_merge_groups = query2array($query, null, 'user_id');
$query = '
SELECT user_id
FROM `'. USER_GROUP_TABLE .'`
WHERE group_id = '.$params['destination_group_id'].'
;';
$user_in_dest = query2array($query, null, 'user_id');;
$user_to_add = array_diff($user_in_merge_groups, $user_in_dest);
$inserts = array();
foreach ($user_to_add as $user)
{
$inserts[] = array(
'group_id' => $params['destination_group_id'],
'user_id' => $user,
);
}
mass_inserts(
USER_GROUP_TABLE,
array('group_id', 'user_id'),
$inserts,
array('ignore'=>true)
);
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
invalidate_user_cache();
pwg_activity('group', $params['destination_group_id'], 'edit');
foreach ($user_to_add as $user_id)
{
pwg_activity('user', $user_id, 'edit', array("associated" => $params['destination_group_id']));
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
delete_groups($merge_group);
return array(
"destination_group" => $service->invoke('pwg.groups.getList', array('group_id' => $params['destination_group_id'])),
"deleted_group" => $merge_group_object
);
}
/**
* API method
* Create a copy of a group
* @param mixed[] $params
* @option int group_id
* @option string copy_name
*/
function ws_groups_duplicate($params, &$service) {
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$query = '
SELECT COUNT(*)
FROM `'.GROUPS_TABLE.'`
WHERE name = \''.pwg_db_real_escape_string($params['copy_name']).'\'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This name is already used by another group.');
}
$query = '
SELECT COUNT(*)
FROM `'. GROUPS_TABLE .'`
WHERE id = '.$params["group_id"].'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count == 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This group does not exist.');
}
$query = '
SELECT is_default
FROM `'. GROUPS_TABLE .'`
WHERE id = '.$params['group_id'].'
;';
list($is_default) = pwg_db_fetch_row(pwg_query($query));
// creating the group
single_insert(
GROUPS_TABLE,
array(
'name' => $params['copy_name'],
'is_default' => boolean_to_string($is_default),
)
);
$inserted_id = pwg_db_insert_id();
pwg_activity('group', $inserted_id, 'add');
$query = '
SELECT user_id
FROM `'. USER_GROUP_TABLE .'`
WHERE group_id = '.$params['group_id'].'
;';
$users = query2array($query, null, 'user_id');
$inserts = array();
foreach ($users as $user)
{
$inserts[] = array(
'group_id' => $inserted_id,
'user_id' => $user,
);
}
mass_inserts(
USER_GROUP_TABLE,
array('group_id', 'user_id'),
$inserts,
array('ignore'=>true)
);
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
invalidate_user_cache();
foreach ($users as $user_id)
{
pwg_activity('user', $user_id, 'edit', array("associated" => $params['group_id']));
}
return $service->invoke('pwg.groups.getList', array('group_id' => $inserted_id));
}
/**
* API method
* Removes user(s) from a group
* @param mixed[] $params
* @option int group_id
* @option int[] user_id
*/
function ws_groups_deleteUser($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
// does the group exist ?
$query = '
SELECT COUNT(*)
FROM `'. GROUPS_TABLE .'`
WHERE id = '. $params['group_id'] .'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count == 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This group does not exist.');
}
$query = '
DELETE FROM '. USER_GROUP_TABLE .'
WHERE
group_id = '. $params['group_id'] .'
AND user_id IN('. implode(',', $params['user_id']) .')
;';
pwg_query($query);
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
invalidate_user_cache();
pwg_activity('group', $params['group_id'], 'edit');
pwg_activity('user', $params['user_id'], 'edit');
return $service->invoke('pwg.groups.getList', array('group_id' => $params['group_id']));
}
?>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,230 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
/**
* API method
* Returns permissions
* @param mixed[] $params
* @option int[] cat_id (optional)
* @option int[] group_id (optional)
* @option int[] user_id (optional)
*/
function ws_permissions_getList($params, &$service)
{
$my_params = array_intersect(array_keys($params), array('cat_id','group_id','user_id'));
if (count($my_params) > 1)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'Too many parameters, provide cat_id OR user_id OR group_id');
}
$cat_filter = '';
if (!empty($params['cat_id']))
{
$cat_filter = 'WHERE cat_id IN('. implode(',', $params['cat_id']) .')';
}
$perms = array();
// direct users
$query = '
SELECT user_id, cat_id
FROM '. USER_ACCESS_TABLE .'
'. $cat_filter .'
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
if (!isset($perms[ $row['cat_id'] ]))
{
$perms[ $row['cat_id'] ]['id'] = intval($row['cat_id']);
}
$perms[ $row['cat_id'] ]['users'][] = intval($row['user_id']);
}
// indirect users
$query = '
SELECT ug.user_id, ga.cat_id
FROM '. USER_GROUP_TABLE .' AS ug
INNER JOIN '. GROUP_ACCESS_TABLE .' AS ga
ON ug.group_id = ga.group_id
'. $cat_filter .'
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
if (!isset($perms[ $row['cat_id'] ]))
{
$perms[ $row['cat_id'] ]['id'] = intval($row['cat_id']);
}
$perms[ $row['cat_id'] ]['users_indirect'][] = intval($row['user_id']);
}
// groups
$query = '
SELECT group_id, cat_id
FROM '. GROUP_ACCESS_TABLE .'
'. $cat_filter .'
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
if (!isset($perms[ $row['cat_id'] ]))
{
$perms[ $row['cat_id'] ]['id'] = intval($row['cat_id']);
}
$perms[ $row['cat_id'] ]['groups'][] = intval($row['group_id']);
}
// filter by group and user
foreach ($perms as $cat_id => &$cat)
{
if (isset($params['group_id']))
{
if (empty($cat['groups']) or count(array_intersect($cat['groups'], $params['group_id'])) == 0)
{
unset($perms[$cat_id]);
continue;
}
}
if (isset($params['user_id']))
{
if (
(empty($cat['users_indirect']) or count(array_intersect($cat['users_indirect'], $params['user_id'])) == 0)
and (empty($cat['users']) or count(array_intersect($cat['users'], $params['user_id'])) == 0)
) {
unset($perms[$cat_id]);
continue;
}
}
$cat['groups'] = !empty($cat['groups']) ? array_values(array_unique($cat['groups'])) : array();
$cat['users'] = !empty($cat['users']) ? array_values(array_unique($cat['users'])) : array();
$cat['users_indirect'] = !empty($cat['users_indirect']) ? array_values(array_unique($cat['users_indirect'])) : array();
}
unset($cat);
return array(
'categories' => new PwgNamedArray(
array_values($perms),
'category',
array('id')
)
);
}
/**
* API method
* Add permissions
* @param mixed[] $params
* @option int[] cat_id
* @option int[] group_id (optional)
* @option int[] user_id (optional)
* @option bool recursive
*/
function ws_permissions_add($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
if (!empty($params['group_id']))
{
$cat_ids = get_uppercat_ids($params['cat_id']);
if ($params['recursive'])
{
$cat_ids = array_merge($cat_ids, get_subcat_ids($params['cat_id']));
}
$query = '
SELECT id
FROM '. CATEGORIES_TABLE .'
WHERE id IN ('. implode(',', $cat_ids) .')
AND status = \'private\'
;';
$private_cats = array_from_query($query, 'id');
$inserts = array();
foreach ($private_cats as $cat_id)
{
foreach ($params['group_id'] as $group_id)
{
$inserts[] = array(
'group_id' => $group_id,
'cat_id' => $cat_id
);
}
}
mass_inserts(
GROUP_ACCESS_TABLE,
array('group_id','cat_id'),
$inserts,
array('ignore'=>true)
);
}
if (!empty($params['user_id']))
{
if ($params['recursive']) $_POST['apply_on_sub'] = true;
add_permission_on_category($params['cat_id'], $params['user_id']);
}
return $service->invoke('pwg.permissions.getList', array('cat_id'=>$params['cat_id']));
}
/**
* API method
* Removes permissions
* @param mixed[] $params
* @option int[] cat_id
* @option int[] group_id (optional)
* @option int[] user_id (optional)
*/
function ws_permissions_remove($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
$cat_ids = get_subcat_ids($params['cat_id']);
if (!empty($params['group_id']))
{
$query = '
DELETE
FROM '. GROUP_ACCESS_TABLE .'
WHERE group_id IN ('. implode(',', $params['group_id']).')
AND cat_id IN ('. implode(',', $cat_ids).')
;';
pwg_query($query);
}
if (!empty($params['user_id']))
{
$query = '
DELETE
FROM '. USER_ACCESS_TABLE .'
WHERE user_id IN ('. implode(',', $params['user_id']) .')
AND cat_id IN ('. implode(',', $cat_ids) .')
;';
pwg_query($query);
}
return $service->invoke('pwg.permissions.getList', array('cat_id'=>$params['cat_id']));
}
?>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,523 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
/**
* API method
* Returns a list of tags
* @param mixed[] $params
* @option bool sort_by_counter
*/
function ws_tags_getList($params, &$service)
{
$tags = get_available_tags();
if ($params['sort_by_counter'])
{
usort($tags, function($a, $b) { return -$a["counter"]+$b["counter"]; });
}
else
{
usort($tags, 'tag_alpha_compare');
}
for ($i=0; $i<count($tags); $i++)
{
$tags[$i]['id'] = (int)$tags[$i]['id'];
$tags[$i]['counter'] = (int)$tags[$i]['counter'];
$tags[$i]['url'] = make_index_url(
array(
'section'=>'tags',
'tags'=>array($tags[$i])
)
);
}
return array(
'tags' => new PwgNamedArray(
$tags,
'tag',
ws_std_get_tag_xml_attributes()
)
);
}
/**
* API method
* Returns the list of tags as you can see them in administration
* @param mixed[] $params
*
* Only admin can run this method and permissions are not taken into
* account.
*/
function ws_tags_getAdminList($params, &$service)
{
return array(
'tags' => new PwgNamedArray(
get_all_tags(),
'tag',
ws_std_get_tag_xml_attributes()
)
);
}
/**
* API method
* Returns a list of images for tags
* @param mixed[] $params
* @option int[] tag_id (optional)
* @option string[] tag_url_name (optional)
* @option string[] tag_name (optional)
* @option bool tag_mode_and
* @option int per_page
* @option int page
* @option string order
*/
function ws_tags_getImages($params, &$service)
{
// first build all the tag_ids we are interested in
$tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
$tags_by_id = array();
foreach ($tags as $tag)
{
$tags['id'] = (int)$tag['id'];
$tags_by_id[ $tag['id'] ] = $tag;
}
unset($tags);
$tag_ids = array_keys($tags_by_id);
$where_clauses = ws_std_image_sql_filter($params);
if (!empty($where_clauses))
{
$where_clauses = implode(' AND ', $where_clauses);
}
$order_by = ws_std_image_sql_order($params, 'i.');
if (!empty($order_by))
{
$order_by = 'ORDER BY '.$order_by;
}
$image_ids = get_image_ids_for_tags(
$tag_ids,
$params['tag_mode_and'] ? 'AND' : 'OR',
$where_clauses,
$order_by
);
$count_set = count($image_ids);
$image_ids = array_slice($image_ids, $params['per_page']*$params['page'], $params['per_page'] );
$image_tag_map = array();
// build list of image ids with associated tags per image
if (!empty($image_ids) and !$params['tag_mode_and'])
{
$query = '
SELECT image_id, GROUP_CONCAT(tag_id) AS tag_ids
FROM '. IMAGE_TAG_TABLE .'
WHERE tag_id IN ('. implode(',', $tag_ids) .')
AND image_id IN ('. implode(',', $image_ids) .')
GROUP BY image_id
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
$row['image_id'] = (int)$row['image_id'];
$image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
}
}
$images = array();
if (!empty($image_ids))
{
$rank_of = array_flip($image_ids);
$favorite_ids = get_user_favorites();
$query = '
SELECT *
FROM '. IMAGES_TABLE .'
WHERE id IN ('. implode(',',$image_ids) .')
;';
$result = pwg_query($query);
while ($row = pwg_db_fetch_assoc($result))
{
$image = array();
$image['rank'] = $rank_of[ $row['id'] ];
$image['is_favorite'] = isset($favorite_ids[ $row['id'] ]);
foreach (array('id', 'width', 'height', 'hit') as $k)
{
if (isset($row[$k]))
{
$image[$k] = (int)$row[$k];
}
}
foreach (array('file', 'name', 'comment', 'date_creation', 'date_available') as $k)
{
$image[$k] = $row[$k];
}
$image['name'] = strip_tags(trigger_change('render_element_name', $image['name'], __FUNCTION__));
$image['comment'] = trigger_change('render_element_description', $image['comment'], __FUNCTION__);
$image = array_merge( $image, ws_std_get_urls($row) );
$image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
$image_tags = array();
foreach ($image_tag_ids as $tag_id)
{
$url = make_index_url(
array(
'section'=>'tags',
'tags'=> array($tags_by_id[$tag_id])
)
);
$page_url = make_picture_url(
array(
'section'=>'tags',
'tags'=> array($tags_by_id[$tag_id]),
'image_id' => $row['id'],
'image_file' => $row['file'],
)
);
$image_tags[] = array(
'id' => (int)$tag_id,
'url' => $url,
'page_url' => $page_url,
);
}
$image['tags'] = new PwgNamedArray($image_tags, 'tag', ws_std_get_tag_xml_attributes() );
$images[] = $image;
}
usort($images, 'rank_compare');
unset($rank_of);
}
return array(
'paging' => new PwgNamedStruct(
array(
'page' => $params['page'],
'per_page' => $params['per_page'],
'count' => count($images),
'total_count' => $count_set,
)
),
'images' => new PwgNamedArray(
$images,
'image',
ws_std_get_image_xml_attributes()
)
);
}
/**
* API method
* Adds a tag
* @param mixed[] $params
* @option string name
*/
function ws_tags_add($params, &$service)
{
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
$creation_output = create_tag($params['name']);
if (isset($creation_output['error']))
{
return new PwgError(WS_ERR_INVALID_PARAM, $creation_output['error']);
}
pwg_activity('tag', $creation_output['id'], 'add');
$query = '
SELECT name, url_name
FROM `'.TAGS_TABLE.'`
WHERE id = '.$creation_output['id'].';';
$new_tag = query2array($query);
return array(
'info' => $creation_output['info'],
'id' => $creation_output['id'],
'name' => $new_tag[0]['name'],
'url_name' => $new_tag[0]['url_name']
);
}
function ws_tags_delete($params, &$service)
{
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$query = '
SELECT COUNT(*)
FROM `'. TAGS_TABLE .'`
WHERE id in ('.implode(',', $params['tag_id']) .')
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != count($params['tag_id']))
{
return new PwgError(WS_ERR_INVALID_PARAM, 'All tags does not exist.');
}
$tag_ids = $params['tag_id'];
if (count($tag_ids) > 0)
{
delete_tags($params['tag_id']);
return array('id' => $tag_ids);
} else {
return array('id' => array());
}
}
function ws_tags_rename($params, &$service)
{
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$tag_id = $params['tag_id'];
$tag_name = strip_tags(stripslashes($params['new_name']));
// does the tag exist ?
$query = '
SELECT COUNT(*)
FROM `'. TAGS_TABLE .'`
WHERE id = '. $tag_id .'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count == 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This tag does not exist.');
}
$query = '
SELECT name
FROM '.TAGS_TABLE.'
WHERE id != '.$tag_id.'
;';
$existing_names = array_from_query($query, 'name');
$update = array();
if (in_array($tag_name, $existing_names))
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This name is already token');
}
else if (!empty($tag_name))
{
$update = array(
'name' => pwg_db_real_escape_string($tag_name),
'url_name' => trigger_change('render_tag_url', $tag_name),
);
}
pwg_activity('tag', $tag_id, 'edit');
single_update(
TAGS_TABLE,
$update,
array('id' => $tag_id)
);
$query = '
SELECT
id,
name,
url_name
FROM '.TAGS_TABLE.'
WHERE id = '.$tag_id.'
;';
$tag = query2array($query)[0];
$tag['raw_name'] = $tag['name'];
$tag['name'] = trigger_change('render_tag_name', $tag['raw_name'], $tag);
$tag['alt_names'] = trigger_change('get_tag_alt_names', array(), $tag['raw_name']);
return $tag;
}
function ws_tags_duplicate($params, &$service)
{
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$tag_id = $params['tag_id'];
$copy_name = $params['copy_name'];
// does the tag exist ?
$query = '
SELECT COUNT(*)
FROM `'. TAGS_TABLE .'`
WHERE id = '. $tag_id .'
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count == 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This tag does not exist.');
}
$query = '
SELECT COUNT(*)
FROM `'. TAGS_TABLE .'`
WHERE name = "'. $copy_name .'"
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != 0)
{
return new PwgError(WS_ERR_INVALID_PARAM, 'This name is already taken.');
}
single_insert(
TAGS_TABLE,
array(
'name' => $copy_name,
'url_name' => trigger_change('render_tag_url', $copy_name),
)
);
$destination_tag_id = pwg_db_insert_id(TAGS_TABLE);
pwg_activity('tag', $destination_tag_id, 'add', array('action'=>'duplicate', 'source_tag'=>$tag_id));
$query = '
SELECT image_id
FROM '.IMAGE_TAG_TABLE.'
WHERE tag_id = '.$tag_id.'
;';
$destination_tag_image_ids = array_from_query($query, 'image_id');
$inserts = array();
foreach ($destination_tag_image_ids as $image_id)
{
$inserts[] = array(
'tag_id' => $destination_tag_id,
'image_id' => $image_id
);
pwg_activity('photo', $image_id, 'edit', array("add-tag" => $destination_tag_id));
}
if (count($inserts) > 0)
{
mass_inserts(
IMAGE_TAG_TABLE,
array_keys($inserts[0]),
$inserts
);
}
return array(
'id' => $destination_tag_id,
'name' => $copy_name,
'url_name' => trigger_change('render_tag_url', $copy_name),
'count' => count($inserts)
);
}
function ws_tags_merge($params, &$service)
{
if (get_pwg_token() != $params['pwg_token'])
{
return new PwgError(403, 'Invalid security token');
}
$all_tags = $params['merge_tag_id'];
array_push($all_tags, $params['destination_tag_id']);
$all_tags = array_unique($all_tags);
$merge_tag = array_diff($params['merge_tag_id'], array($params['destination_tag_id']));
$query = '
SELECT COUNT(*)
FROM `'. TAGS_TABLE .'`
WHERE id in ('.implode(',', $all_tags) .')
;';
list($count) = pwg_db_fetch_row(pwg_query($query));
if ($count != count($all_tags))
{
return new PwgError(WS_ERR_INVALID_PARAM, 'All tags does not exist.');
}
$image_in_merge_tags = array();
$image_in_dest = array();
$image_to_add = array();
$query = '
SELECT DISTINCT(image_id)
FROM `'. IMAGE_TAG_TABLE .'`
WHERE
tag_id IN ('.implode(',', $merge_tag) .')
;';
$image_in_merge_tags = query2array($query, null, 'image_id');
$query = '
SELECT image_id
FROM `'. IMAGE_TAG_TABLE .'`
WHERE tag_id = '.$params['destination_tag_id'].'
;';
$image_in_dest = query2array($query, null, 'image_id');;
$image_to_add = array_diff($image_in_merge_tags, $image_in_dest);
$inserts = array();
foreach ($image_to_add as $image)
{
$inserts[] = array(
'tag_id' => $params['destination_tag_id'],
'image_id' => $image,
);
}
mass_inserts(
IMAGE_TAG_TABLE,
array('tag_id', 'image_id'),
$inserts,
array('ignore'=>true)
);
pwg_activity('tag', $params['destination_tag_id'], 'edit');
foreach ($image_to_add as $image_id)
{
pwg_activity('photo', $image_id, 'edit', array("tag-add" => $params['destination_tag_id']));
}
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
trigger_notify('merge_tags', $params['destination_tag_id'], $merge_tag);
delete_tags($merge_tag);
$image_in_merged = array_merge($image_in_dest, $image_to_add);
return array(
"destination_tag" => $params['destination_tag_id'],
"deleted_tag" => $params['merge_tag_id'],
"images_in_merged_tag" => $image_in_merged
);
}
?>
File diff suppressed because it is too large Load Diff