First commit
@@ -0,0 +1,85 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Basic checks |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('cat_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
$admin_album_base_url = get_root_url().'admin.php?page=album-'.$_GET['cat_id'];
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id = '.$_GET['cat_id'].'
|
||||
;';
|
||||
$category = pwg_db_fetch_assoc(pwg_query($query));
|
||||
|
||||
if (!isset($category['id']))
|
||||
{
|
||||
die("unknown album");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$page['tab'] = 'properties';
|
||||
|
||||
if (isset($_GET['tab']))
|
||||
{
|
||||
$page['tab'] = $_GET['tab'];
|
||||
}
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('album');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Load the tab |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$category_name = trigger_change(
|
||||
'render_category_name',
|
||||
$category['name'],
|
||||
'get_cat_display_name_cache'
|
||||
);
|
||||
$template->assign(array(
|
||||
'ADMIN_PAGE_TITLE' => l10n('Edit album').' <strong>'.$category_name.'</strong>',
|
||||
'ADMIN_PAGE_OBJECT_ID' => '#'.$category['id'],
|
||||
));
|
||||
|
||||
if ('properties' == $page['tab'])
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/cat_modify.php');
|
||||
}
|
||||
elseif ('sort_order' == $page['tab'])
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/element_set_ranks.php');
|
||||
}
|
||||
elseif ('permissions' == $page['tab'])
|
||||
{
|
||||
$_GET['cat'] = $_GET['cat_id'];
|
||||
include(PHPWG_ROOT_PATH.'admin/cat_perm.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/album_'.$page['tab'].'.php');
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,331 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | variable initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$page['cat'] = $category['id'];
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | form submission |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// info by email to an access granted group of category informations
|
||||
if (isset($_POST['submitEmail']))
|
||||
{
|
||||
check_pwg_token();
|
||||
set_make_full_url();
|
||||
|
||||
$img = array();
|
||||
|
||||
/* TODO: if $category['representative_picture_id']
|
||||
is empty find child representative_picture_id */
|
||||
if (!empty($category['representative_picture_id']))
|
||||
{
|
||||
$query = '
|
||||
SELECT id, file, path, representative_ext
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id = '.$category['representative_picture_id'].'
|
||||
;';
|
||||
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) > 0)
|
||||
{
|
||||
$element = pwg_db_fetch_assoc($result);
|
||||
|
||||
$img = array(
|
||||
'link' => make_picture_url(
|
||||
array(
|
||||
'image_id' => $element['id'],
|
||||
'image_file' => $element['file'],
|
||||
'category' => $category
|
||||
)
|
||||
),
|
||||
'src' => DerivativeImage::url(IMG_THUMB, $element),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'subject' => l10n('[%s] Visit album %s', $conf['gallery_title'], trigger_change('render_category_name', $category['name'], 'admin_cat_list')),
|
||||
// TODO : change this language variable to 'Visit album %s'
|
||||
// TODO : 'language_selected' => ....
|
||||
);
|
||||
|
||||
$tpl = array(
|
||||
'filename' => 'cat_group_info',
|
||||
'assign' => array(
|
||||
'IMG' => $img,
|
||||
'CAT_NAME' => trigger_change('render_category_name', $category['name'], 'admin_cat_list'),
|
||||
'LINK' => make_index_url(
|
||||
array(
|
||||
'category' => array(
|
||||
'id' => $category['id'],
|
||||
'name' => trigger_change('render_category_name', $category['name'], 'admin_cat_list'),
|
||||
'permalink' => $category['permalink']
|
||||
)
|
||||
)
|
||||
),
|
||||
'CPL_CONTENT' => empty($_POST['mail_content']) ? '' : stripslashes($_POST['mail_content']),
|
||||
)
|
||||
);
|
||||
|
||||
if ('users' == $_POST['who'] and isset($_POST['users']) and count($_POST['users']) > 0)
|
||||
{
|
||||
check_input_parameter('users', $_POST, true, PATTERN_ID);
|
||||
|
||||
// TODO code very similar to function pwg_mail_group. We'd better create
|
||||
// a function pwg_mail_users that could be called from here and from
|
||||
// pwg_mail_group
|
||||
|
||||
// TODO to make checks even better, we should check that theses users
|
||||
// have access to this album. No real privacy issue here, even if we
|
||||
// send the email to a user without permission.
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
ui.user_id,
|
||||
ui.status,
|
||||
ui.language,
|
||||
u.'.$conf['user_fields']['email'].' AS email,
|
||||
u.'.$conf['user_fields']['username'].' AS username
|
||||
FROM '.USER_INFOS_TABLE.' AS ui
|
||||
JOIN '.USERS_TABLE.' AS u ON u.'.$conf['user_fields']['id'].' = ui.user_id
|
||||
WHERE ui.user_id IN ('.implode(',', $_POST['users']).')
|
||||
;';
|
||||
$users = query2array($query);
|
||||
$usernames = array();
|
||||
|
||||
foreach ($users as $u)
|
||||
{
|
||||
$usernames[] = $u['username'];
|
||||
|
||||
$authkey = create_user_auth_key($u['user_id'], $u['status']);
|
||||
|
||||
$user_tpl = $tpl;
|
||||
|
||||
if ($authkey !== false)
|
||||
{
|
||||
$user_tpl['assign']['LINK'] = add_url_params($tpl['assign']['LINK'], array('auth' => $authkey['auth_key']));
|
||||
|
||||
if (isset($user_tpl['assign']['IMG']['link']))
|
||||
{
|
||||
$user_tpl['assign']['IMG']['link'] = add_url_params(
|
||||
$user_tpl['assign']['IMG']['link'],
|
||||
array('auth' => $authkey['auth_key'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$user_args = $args;
|
||||
if (isset($authkey['auth_key']))
|
||||
{
|
||||
$user_args['auth_key'] = $authkey['auth_key'];
|
||||
}
|
||||
|
||||
switch_lang_to($u['language']);
|
||||
pwg_mail($u['email'], $user_args, $user_tpl);
|
||||
switch_lang_back();
|
||||
}
|
||||
|
||||
$message = l10n_dec('%d mail was sent.', '%d mails were sent.', count($users));
|
||||
$message.= ' ('.implode(', ', $usernames).')';
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' =>$message,
|
||||
)
|
||||
);
|
||||
}
|
||||
elseif ('group' == $_POST['who'] and !empty($_POST['group']))
|
||||
{
|
||||
check_input_parameter('group', $_POST, false, PATTERN_ID);
|
||||
|
||||
pwg_mail_group($_POST['group'], $args, $tpl);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
name
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
WHERE id = '.$_POST['group'].'
|
||||
;';
|
||||
list($group_name) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' =>l10n('An information email was sent to group "%s"', $group_name),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
unset_make_full_url();
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filename('album_notification', 'album_notification.tpl');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'CATEGORIES_NAV' =>
|
||||
trim(
|
||||
get_cat_display_name_from_id(
|
||||
$page['cat'],
|
||||
'admin.php?page=album-'
|
||||
)
|
||||
),
|
||||
'F_ACTION' => $admin_album_base_url.'-notification',
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
|
||||
if ($conf['auth_key_duration'] > 0)
|
||||
{
|
||||
$template->assign(
|
||||
'auth_key_duration',
|
||||
time_since(
|
||||
strtotime('now -'.$conf['auth_key_duration'].' second'),
|
||||
'second',
|
||||
null,
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | form construction |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id AS group_id
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
;';
|
||||
$all_group_ids = array_from_query($query, 'group_id');
|
||||
|
||||
if (count($all_group_ids) == 0)
|
||||
{
|
||||
$template->assign('no_group_in_gallery', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ('private' == $category['status'])
|
||||
{
|
||||
$template->assign('permission_url', $admin_album_base_url.'-permissions');
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
group_id
|
||||
FROM '.GROUP_ACCESS_TABLE.'
|
||||
WHERE cat_id = '.$category['id'].'
|
||||
;';
|
||||
$group_ids = array_from_query($query, 'group_id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$group_ids = $all_group_ids;
|
||||
}
|
||||
|
||||
if (count($group_ids) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
name
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
WHERE id IN ('.implode(',', $group_ids).')
|
||||
ORDER BY name ASC
|
||||
;';
|
||||
$template->assign(
|
||||
'group_mail_options',
|
||||
simple_hash_from_query($query, 'id', 'name')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// all users with status != guest and permitted to this this album (for a
|
||||
// perfect search, we should also check that album is not only filled with
|
||||
// private photos)
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE status != \'guest\'
|
||||
;';
|
||||
$all_user_ids = query2array($query, null, 'user_id');
|
||||
|
||||
if ('private' == $category['status'])
|
||||
{
|
||||
$user_ids_access_indirect = array();
|
||||
|
||||
if (isset($group_ids) and count($group_ids) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_GROUP_TABLE.'
|
||||
WHERE group_id IN ('.implode(',', $group_ids).')
|
||||
';
|
||||
$user_ids_access_indirect = query2array($query, null, 'user_id');
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_ACCESS_TABLE.'
|
||||
WHERE cat_id = '.$category['id'].'
|
||||
;';
|
||||
$user_ids_access_direct = query2array($query, null, 'user_id');
|
||||
|
||||
$user_ids_access = array_unique(array_merge($user_ids_access_direct, $user_ids_access_indirect));
|
||||
|
||||
$user_ids = array_intersect($user_ids_access, $all_user_ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
$user_ids = $all_user_ids;
|
||||
}
|
||||
|
||||
if (count($user_ids) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
'.$conf['user_fields']['id'].' AS id,
|
||||
'.$conf['user_fields']['username'].' AS username
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE id IN ('.implode(',', $user_ids).')
|
||||
;';
|
||||
|
||||
$users = query2array($query, 'id', 'username');
|
||||
|
||||
$template->assign('user_options', $users);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'album_notification');
|
||||
?>
|
||||
@@ -0,0 +1,356 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
list($albums_counter) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('parent_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$page['tab'] = 'list';
|
||||
include(PHPWG_ROOT_PATH.'admin/include/albums_tab.inc.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | categories auto order |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$open_cat = $_GET['parent_id'] ?? -1;
|
||||
|
||||
$sort_orders = array(
|
||||
'name ASC',
|
||||
'name DESC',
|
||||
'date_creation DESC',
|
||||
'date_creation ASC',
|
||||
'date_available DESC',
|
||||
'date_available ASC',
|
||||
'natural_order DESC',
|
||||
'natural_order ASC'
|
||||
);
|
||||
|
||||
if (isset($_POST['simpleAutoOrder']) || isset($_POST['recursiveAutoOrder']) )
|
||||
{
|
||||
|
||||
if (!in_array($_POST['order'],$sort_orders))
|
||||
{
|
||||
die('Invalid sort order');
|
||||
}
|
||||
check_input_parameter('id', $_POST, false, '/^-?\d+$/');
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id_uppercat '.
|
||||
(($_POST['id'] === '-1') ? 'IS NULL' : '= '.$_POST['id']).'
|
||||
;';
|
||||
$category_ids = array_from_query($query, 'id');
|
||||
|
||||
if (isset($_POST['recursiveAutoOrder']))
|
||||
{
|
||||
$category_ids = get_subcat_ids($category_ids);
|
||||
}
|
||||
|
||||
$categories = array();
|
||||
$sort = array();
|
||||
|
||||
list($order_by_field, $order_by_asc) = explode(' ', $_POST['order']);
|
||||
|
||||
$order_by_date = false;
|
||||
if (strpos($order_by_field, 'date_') === 0)
|
||||
{
|
||||
$order_by_date = true;
|
||||
|
||||
$ref_dates = get_categories_ref_date(
|
||||
$category_ids,
|
||||
$order_by_field,
|
||||
'ASC' == $order_by_asc ? 'min' : 'max'
|
||||
);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id, name, id_uppercat
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $category_ids).')
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['name'] = trigger_change('render_category_name', $row['name'], 'admin_cat_list');
|
||||
|
||||
if ($order_by_date)
|
||||
{
|
||||
$sort[] = $ref_dates[ $row['id'] ];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sort[] = remove_accents($row['name']);
|
||||
}
|
||||
|
||||
$categories[] = array(
|
||||
'id' => $row['id'],
|
||||
'id_uppercat' => $row['id_uppercat'],
|
||||
);
|
||||
}
|
||||
|
||||
array_multisort(
|
||||
$sort,
|
||||
$order_by_field === "natural_order" ? SORT_NATURAL : SORT_REGULAR,
|
||||
'ASC' == $order_by_asc ? SORT_ASC : SORT_DESC,
|
||||
$categories
|
||||
);
|
||||
|
||||
save_categories_order($categories);
|
||||
|
||||
$open_cat = $_POST['id'];
|
||||
}
|
||||
|
||||
$template->assign('open_cat', $open_cat);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filename('albums', 'albums.tpl');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ACTION' => get_root_url().'admin.php?page=albums',
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign('delay_before_autoOpen', $conf['album_move_delay_before_auto_opening']);
|
||||
|
||||
$template->assign("POS_PREF", $conf['newcat_default_position']); //TODO use user pref if it exists
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Album display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
//Get all albums
|
||||
$query = '
|
||||
SELECT id,name,`rank`,status, visible, uppercats, lastmodified
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
|
||||
$allAlbum = query2array($query);
|
||||
|
||||
//Make an id tree
|
||||
$associatedTree = array();
|
||||
|
||||
foreach ($allAlbum as $album)
|
||||
{
|
||||
$album['name'] = trigger_change('render_category_name', $album['name'], 'admin_cat_list');
|
||||
$album['lastmodified'] = time_since($album['lastmodified'], 'year');
|
||||
|
||||
$parents = explode(',',$album['uppercats']);
|
||||
$the_place = &$associatedTree[strval($parents[0])];
|
||||
for ($i=1; $i < count($parents); $i++)
|
||||
{
|
||||
$the_place = &$the_place['children'][strval($parents[$i])];
|
||||
}
|
||||
$the_place['cat'] = $album;
|
||||
}
|
||||
|
||||
// WARNING $user['forbidden_categories'] is 100% reliable only on gallery side because
|
||||
// it's a cache variable. On administration side, if you modify public/private status
|
||||
// of an album or change permissions, this variable is reset and not recalculated until
|
||||
// you open the gallery. As this situation doesn't occur each time you use the
|
||||
// administration, it's quite reliable but not as much as on gallery side.
|
||||
$is_forbidden = array_fill_keys(@explode(',', $user['forbidden_categories']), 1);
|
||||
|
||||
//Make an ordered tree
|
||||
function cmpCat($a, $b)
|
||||
{
|
||||
if ($a['rank'] == $b['rank'])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ($a['rank'] < $b['rank']) ? -1 : 1;
|
||||
}
|
||||
|
||||
function assocToOrderedTree($assocT)
|
||||
{
|
||||
global $nb_photos_in, $nb_sub_photos, $is_forbidden;
|
||||
|
||||
$orderedTree = array();
|
||||
|
||||
foreach($assocT as $cat)
|
||||
{
|
||||
$orderedCat = array();
|
||||
$orderedCat['rank'] = $cat['cat']['rank'];
|
||||
$orderedCat['name'] = $cat['cat']['name'];
|
||||
$orderedCat['status'] = $cat['cat']['status'];
|
||||
$orderedCat['id'] = $cat['cat']['id'];
|
||||
$orderedCat['visible'] = $cat['cat']['visible'];
|
||||
$orderedCat['uppercats'] = $cat['cat']['uppercats'];
|
||||
$orderedCat['nb_images'] = isset($nb_photos_in[$cat['cat']['id']]) ? $nb_photos_in[$cat['cat']['id']] : 0;
|
||||
$orderedCat['last_updates'] = $cat['cat']['lastmodified'];
|
||||
$orderedCat['has_not_access'] = isset($is_forbidden[$cat['cat']['id']]);
|
||||
$orderedCat['nb_sub_photos'] = isset($nb_sub_photos[$cat['cat']['id']]) ? $nb_sub_photos[$cat['cat']['id']] : 0;
|
||||
if (isset($cat['children']))
|
||||
{
|
||||
//Does not update when moving a node
|
||||
$orderedCat['nb_subcats'] = count($cat['children']);
|
||||
$orderedCat['children'] = assocToOrderedTree($cat['children']);
|
||||
}
|
||||
array_push($orderedTree, $orderedCat);
|
||||
}
|
||||
usort($orderedTree, 'cmpCat');
|
||||
return $orderedTree;
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
category_id,
|
||||
COUNT(*) AS nb_photos
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
GROUP BY category_id
|
||||
;';
|
||||
|
||||
$nb_photos_in = query2array($query, 'category_id', 'nb_photos');
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
uppercats
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
$all_categories = query2array($query, 'id', 'uppercats');
|
||||
|
||||
$subcats_of = array();
|
||||
|
||||
foreach ($all_categories as $id => $uppercats)
|
||||
{
|
||||
foreach (array_slice(explode(',', $uppercats), 0, -1) as $uppercat_id)
|
||||
{
|
||||
@$subcats_of[$uppercat_id][] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$nb_sub_photos = array();
|
||||
foreach ($subcats_of as $cat_id => $subcat_ids)
|
||||
{
|
||||
$nb_photos = 0;
|
||||
foreach ($subcat_ids as $id)
|
||||
{
|
||||
if (isset($nb_photos_in[$id]))
|
||||
{
|
||||
$nb_photos+= $nb_photos_in[$id];
|
||||
}
|
||||
}
|
||||
|
||||
$nb_sub_photos[$cat_id] = $nb_photos;
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'album_data' => assocToOrderedTree($associatedTree),
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'nb_albums' => count($allAlbum),
|
||||
'ADMIN_PAGE_TITLE' => l10n('Albums'),
|
||||
'light_album_manager' => ($albums_counter > $conf['light_album_manager_threshold']) ? 1 : 0,
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'albums');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | functions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
function get_categories_ref_date($ids, $field='date_available', $minmax='max')
|
||||
{
|
||||
// we need to work on the whole tree under each category, even if we don't
|
||||
// want to sort sub categories
|
||||
$category_ids = get_subcat_ids($ids);
|
||||
|
||||
// search for the reference date of each album
|
||||
$query = '
|
||||
SELECT
|
||||
category_id,
|
||||
'.$minmax.'('.$field.') as ref_date
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
JOIN '.IMAGES_TABLE.' ON image_id = id
|
||||
WHERE category_id IN ('.implode(',', $category_ids).')
|
||||
GROUP BY category_id
|
||||
;';
|
||||
$ref_dates = query2array($query, 'category_id', 'ref_date');
|
||||
|
||||
// the iterate on all albums (having a ref_date or not) to find the
|
||||
// reference_date, with a search on sub-albums
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
uppercats
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $category_ids).')
|
||||
;';
|
||||
$uppercats_of = query2array($query, 'id', 'uppercats');
|
||||
|
||||
foreach (array_keys($uppercats_of) as $cat_id)
|
||||
{
|
||||
// find the subcats
|
||||
$subcat_ids = array();
|
||||
|
||||
foreach ($uppercats_of as $id => $uppercats)
|
||||
{
|
||||
if (preg_match('/(^|,)'.$cat_id.'(,|$)/', $uppercats))
|
||||
{
|
||||
$subcat_ids[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$to_compare = array();
|
||||
foreach ($subcat_ids as $id)
|
||||
{
|
||||
if (isset($ref_dates[$id]))
|
||||
{
|
||||
$to_compare[] = $ref_dates[$id];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($to_compare) > 0)
|
||||
{
|
||||
$ref_dates[$cat_id] = 'max' == $minmax ? max($to_compare) : min($to_compare);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ref_dates[$cat_id] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// only return the list of $ids, not the sub-categories
|
||||
$return = array();
|
||||
foreach ($ids as $id)
|
||||
{
|
||||
$return[$id] = $ref_dates[$id];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,813 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Management of elements set. Elements can belong to a category or to the
|
||||
* user caddie.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('selection', $_POST, true, PATTERN_ID);
|
||||
check_input_parameter('display', $_REQUEST, false, '/^(\d+|all)$/');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | specific actions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['action']))
|
||||
{
|
||||
if ('empty_caddie' == $_GET['action'])
|
||||
{
|
||||
$query = '
|
||||
DELETE FROM '.CADDIE_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
redirect(get_root_url().'admin.php?page='.$_GET['page']);
|
||||
}
|
||||
|
||||
if ('delete_orphans' == $_GET['action'] and isset($_GET['nb_orphans_deleted']))
|
||||
{
|
||||
check_input_parameter('nb_orphans_deleted', $_GET, false, '/^\d+$/');
|
||||
|
||||
if ($_GET['nb_orphans_deleted'] > 0)
|
||||
{
|
||||
$_SESSION['page_infos'][] = l10n_dec(
|
||||
'%d photo was deleted', '%d photos were deleted',
|
||||
$_GET['nb_orphans_deleted']
|
||||
);
|
||||
|
||||
redirect(get_root_url().'admin.php?page='.$_GET['page']);
|
||||
}
|
||||
}
|
||||
|
||||
if ('sync_md5sum' == $_GET['action'] and isset($_GET['nb_md5sum_added']))
|
||||
{
|
||||
check_input_parameter('nb_md5sum_added', $_GET, false, '/^\d+$/');
|
||||
if ($_GET['nb_md5sum_added'] > 0)
|
||||
{
|
||||
$_SESSION['page_infos'][] = l10n_dec(
|
||||
'%d checksums were added', '%d checksums were added',
|
||||
$_GET['nb_md5sum_added']
|
||||
);
|
||||
|
||||
redirect(get_root_url().'admin.php?page='.$_GET['page']);
|
||||
}
|
||||
}
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | initialize current set |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// filters from form
|
||||
if (isset($_POST['submitFilter']))
|
||||
{
|
||||
// echo '<pre>'; print_r($_POST); echo '</pre>';
|
||||
unset($_REQUEST['start']); // new photo set must reset the page
|
||||
$_SESSION['bulk_manager_filter'] = array();
|
||||
|
||||
if (isset($_POST['filter_prefilter_use']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['prefilter'] = $_POST['filter_prefilter'];
|
||||
|
||||
if ('duplicates' == $_POST['filter_prefilter'])
|
||||
{
|
||||
$has_options = false;
|
||||
|
||||
if (isset($_POST['filter_duplicates_checksum']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['duplicates_checksum'] = true;
|
||||
$has_options = true;
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_duplicates_date']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['duplicates_date'] = true;
|
||||
$has_options = true;
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_duplicates_dimensions']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['duplicates_dimensions'] = true;
|
||||
$has_options = true;
|
||||
}
|
||||
|
||||
if (!$has_options or isset($_POST['filter_duplicates_filename']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['duplicates_filename'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_category_use']))
|
||||
{
|
||||
check_input_parameter('filter_category', $_POST, false, PATTERN_ID);
|
||||
|
||||
$_SESSION['bulk_manager_filter']['category'] = $_POST['filter_category'];
|
||||
|
||||
if (isset($_POST['filter_category_recursive']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['category_recursive'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_tags_use']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['tags'] = get_tag_ids($_POST['filter_tags'], false);
|
||||
|
||||
if (isset($_POST['tag_mode']) and in_array($_POST['tag_mode'], array('AND', 'OR')))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['tag_mode'] = $_POST['tag_mode'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_level_use']))
|
||||
{
|
||||
check_input_parameter('filter_level', $_POST, false, '/^\d+$/');
|
||||
|
||||
if (in_array($_POST['filter_level'], $conf['available_permission_levels']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['level'] = $_POST['filter_level'];
|
||||
|
||||
if (isset($_POST['filter_level_include_lower']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['level_include_lower'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_dimension_use']))
|
||||
{
|
||||
foreach (array('min_width','max_width','min_height','max_height') as $type)
|
||||
{
|
||||
if (filter_var($_POST['filter_dimension_'.$type], FILTER_VALIDATE_INT) !== false)
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['dimension'][$type] = $_POST['filter_dimension_'. $type ];
|
||||
}
|
||||
}
|
||||
foreach (array('min_ratio','max_ratio') as $type)
|
||||
{
|
||||
if (filter_var($_POST['filter_dimension_'.$type], FILTER_VALIDATE_FLOAT) !== false)
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['dimension'][$type] = $_POST['filter_dimension_'. $type ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_filesize_use']))
|
||||
{
|
||||
foreach (array('min','max') as $type)
|
||||
{
|
||||
if (filter_var($_POST['filter_filesize_'.$type], FILTER_VALIDATE_FLOAT) !== false)
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['filesize'][$type] = $_POST['filter_filesize_'. $type ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_search_use']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['search']['q'] = $_POST['q'];
|
||||
}
|
||||
|
||||
$_SESSION['bulk_manager_filter'] = trigger_change('batch_manager_register_filters', $_SESSION['bulk_manager_filter']);
|
||||
}
|
||||
// filters from url
|
||||
elseif (isset($_GET['filter']))
|
||||
{
|
||||
if (!is_array($_GET['filter']))
|
||||
{
|
||||
$_GET['filter'] = explode(',', $_GET['filter']);
|
||||
}
|
||||
|
||||
$_SESSION['bulk_manager_filter'] = array();
|
||||
|
||||
foreach ($_GET['filter'] as $filter)
|
||||
{
|
||||
list($type, $value) = explode('-', $filter, 2);
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 'prefilter':
|
||||
if (preg_match('/^duplicates-?/', $value))
|
||||
{
|
||||
list(, $duplicate_field) = explode('-', $value, 2);
|
||||
$_SESSION['bulk_manager_filter']['prefilter'] = 'duplicates';
|
||||
|
||||
if (in_array($duplicate_field, array('filename', 'checksum', 'date', 'dimensions')))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['duplicates_'.$duplicate_field] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['prefilter'] = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'album': case 'category': case 'cat':
|
||||
if (is_numeric($value))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['category'] = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
if (is_numeric($value))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['tags'] = array($value);
|
||||
$_SESSION['bulk_manager_filter']['tag_mode'] = 'AND';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'level':
|
||||
if (is_numeric($value) && in_array($value, $conf['available_permission_levels']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['level'] = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'search':
|
||||
$_SESSION['bulk_manager_filter']['search']['q'] = $value;
|
||||
break;
|
||||
|
||||
case 'dimension':
|
||||
$dim_map = array('w'=>'width','h'=>'height','r'=>'ratio');
|
||||
foreach (explode('-', $value) as $part)
|
||||
{
|
||||
$values = explode('..', substr($part, 1));
|
||||
if (isset($dim_map[$part[0]]))
|
||||
{
|
||||
$type = $dim_map[$part[0]];
|
||||
list(
|
||||
$_SESSION['bulk_manager_filter']['dimension']['min_'.$type],
|
||||
$_SESSION['bulk_manager_filter']['dimension']['max_'.$type]
|
||||
) = $values;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'filesize':
|
||||
list(
|
||||
$_SESSION['bulk_manager_filter']['filesize']['min'],
|
||||
$_SESSION['bulk_manager_filter']['filesize']['max']
|
||||
) = explode('..', $value);
|
||||
break;
|
||||
|
||||
default:
|
||||
$_SESSION['bulk_manager_filter'] = trigger_change('batch_manager_url_filter', $_SESSION['bulk_manager_filter'], $filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($_SESSION['bulk_manager_filter']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter'] = array(
|
||||
'prefilter' => 'caddie'
|
||||
);
|
||||
}
|
||||
|
||||
// echo '<pre>'; print_r($_SESSION['bulk_manager_filter']); echo '</pre>';
|
||||
|
||||
// depending on the current filter (in session), we find the appropriate photos
|
||||
$filter_sets = array();
|
||||
if (isset($_SESSION['bulk_manager_filter']['prefilter']))
|
||||
{
|
||||
switch ($_SESSION['bulk_manager_filter']['prefilter'])
|
||||
{
|
||||
case 'caddie':
|
||||
$query = '
|
||||
SELECT element_id
|
||||
FROM '.CADDIE_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
$filter_sets[] = query2array($query, null, 'element_id');
|
||||
|
||||
break;
|
||||
|
||||
case 'favorites':
|
||||
$query = '
|
||||
SELECT image_id
|
||||
FROM '.FAVORITES_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
$filter_sets[] = query2array($query, null, 'image_id');
|
||||
|
||||
break;
|
||||
|
||||
case 'last_import':
|
||||
$query = '
|
||||
SELECT MAX(date_available) AS date
|
||||
FROM '.IMAGES_TABLE.'
|
||||
;';
|
||||
$row = pwg_db_fetch_assoc(pwg_query($query));
|
||||
if (!empty($row['date']))
|
||||
{
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE date_available BETWEEN '.pwg_db_get_recent_period_expression(1, $row['date']).' AND \''.$row['date'].'\'
|
||||
;';
|
||||
$filter_sets[] = query2array($query, null, 'id');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'no_virtual_album':
|
||||
// we are searching elements not linked to any virtual category
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
;';
|
||||
$all_elements = query2array($query, null, 'id');
|
||||
|
||||
$linked_to_virtual = array();
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE dir IS NULL
|
||||
;';
|
||||
$virtual_categories = query2array($query, null, 'id');
|
||||
if (!empty($virtual_categories))
|
||||
{
|
||||
$query = '
|
||||
SELECT DISTINCT(image_id)
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
WHERE category_id IN ('.implode(',', $virtual_categories).')
|
||||
;';
|
||||
$linked_to_virtual = query2array($query, null, 'image_id');
|
||||
}
|
||||
|
||||
$filter_sets[] = array_diff($all_elements, $linked_to_virtual);
|
||||
|
||||
break;
|
||||
|
||||
case 'no_album':
|
||||
$filter_sets[] = get_orphans();
|
||||
break;
|
||||
case 'no_sync_md5sum':
|
||||
$filter_sets[] = get_photos_no_md5sum();
|
||||
break;
|
||||
|
||||
case 'no_tag':
|
||||
$query = '
|
||||
SELECT
|
||||
id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
LEFT JOIN '.IMAGE_TAG_TABLE.' ON id = image_id
|
||||
WHERE tag_id is null
|
||||
;';
|
||||
$filter_sets[] = query2array($query, null, 'id');
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'duplicates':
|
||||
$duplicates_on_fields = array();
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['duplicates_filename']))
|
||||
{
|
||||
$duplicates_on_fields[] = 'file';
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['duplicates_checksum']))
|
||||
{
|
||||
$duplicates_on_fields[] = 'md5sum';
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['duplicates_date']))
|
||||
{
|
||||
$duplicates_on_fields[] = 'date_creation';
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['duplicates_dimensions']))
|
||||
{
|
||||
$duplicates_on_fields[] = 'width';
|
||||
$duplicates_on_fields[] = 'height';
|
||||
}
|
||||
|
||||
// TODO improve this algorithm, because GROUP_CONCAT is truncated at
|
||||
// 1024 chars. So if you have more than ~250 duplicates for a given
|
||||
// combination of "duplicates_on_fields" you won't get all the
|
||||
// duplicates.
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
GROUP_CONCAT(id) AS ids
|
||||
FROM '.IMAGES_TABLE;
|
||||
|
||||
if (in_array('md5sum', $duplicates_on_fields))
|
||||
{
|
||||
$query.= '
|
||||
WHERE md5sum IS NOT NULL
|
||||
';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
GROUP BY '.implode(',', $duplicates_on_fields).'
|
||||
HAVING COUNT(*) > 1
|
||||
;';
|
||||
$array_of_ids_string = query2array($query, null, 'ids');
|
||||
|
||||
$ids = array();
|
||||
|
||||
foreach ($array_of_ids_string as $ids_string)
|
||||
{
|
||||
$ids_string = rtrim($ids_string,',');
|
||||
$ids = array_merge($ids, explode(',', $ids_string));
|
||||
}
|
||||
|
||||
$filter_sets[] = $ids;
|
||||
|
||||
break;
|
||||
|
||||
case 'all_photos':
|
||||
if ( count($_SESSION['bulk_manager_filter']) == 1 )
|
||||
{// make the query only if this is the only filter
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
'.$conf['order_by'];
|
||||
|
||||
$filter_sets[] = query2array($query, null, 'id');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$filter_sets = trigger_change('perform_batch_manager_prefilters', $filter_sets, $_SESSION['bulk_manager_filter']['prefilter']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['category']))
|
||||
{
|
||||
$categories = array();
|
||||
|
||||
// we need to check the category still exists (it may have been deleted since it was added in the session)
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id = '.$_SESSION['bulk_manager_filter']['category'].'
|
||||
;';
|
||||
list($counter) = pwg_db_fetch_row(pwg_query($query));
|
||||
if (0 == $counter)
|
||||
{
|
||||
unset($_SESSION['bulk_manager_filter']);
|
||||
redirect(get_root_url().'admin.php?page='.$_GET['page']);
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['category_recursive']))
|
||||
{
|
||||
$categories = get_subcat_ids(array($_SESSION['bulk_manager_filter']['category']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$categories = array($_SESSION['bulk_manager_filter']['category']);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT DISTINCT(image_id)
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
WHERE category_id IN ('.implode(',', $categories).')
|
||||
;';
|
||||
$filter_sets[] = query2array($query, null, 'image_id');
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['level']))
|
||||
{
|
||||
$operator = '=';
|
||||
if (isset($_SESSION['bulk_manager_filter']['level_include_lower']))
|
||||
{
|
||||
$operator = '<=';
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE level '.$operator.' '.$_SESSION['bulk_manager_filter']['level'].'
|
||||
'.$conf['order_by'];
|
||||
|
||||
$filter_sets[] = query2array($query, null, 'id');
|
||||
}
|
||||
|
||||
if (!empty($_SESSION['bulk_manager_filter']['tags']))
|
||||
{
|
||||
$filter_sets[] = get_image_ids_for_tags(
|
||||
$_SESSION['bulk_manager_filter']['tags'],
|
||||
$_SESSION['bulk_manager_filter']['tag_mode'],
|
||||
null,
|
||||
null,
|
||||
false // we don't apply permissions in administration screens
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']))
|
||||
{
|
||||
$where_clauses = array();
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']['min_width']))
|
||||
{
|
||||
$where_clause[] = 'width >= '.$_SESSION['bulk_manager_filter']['dimension']['min_width'];
|
||||
}
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']['max_width']))
|
||||
{
|
||||
$where_clause[] = 'width <= '.$_SESSION['bulk_manager_filter']['dimension']['max_width'];
|
||||
}
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']['min_height']))
|
||||
{
|
||||
$where_clause[] = 'height >= '.$_SESSION['bulk_manager_filter']['dimension']['min_height'];
|
||||
}
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']['max_height']))
|
||||
{
|
||||
$where_clause[] = 'height <= '.$_SESSION['bulk_manager_filter']['dimension']['max_height'];
|
||||
}
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']['min_ratio']))
|
||||
{
|
||||
$where_clause[] = 'width/height >= '.$_SESSION['bulk_manager_filter']['dimension']['min_ratio'];
|
||||
}
|
||||
if (isset($_SESSION['bulk_manager_filter']['dimension']['max_ratio']))
|
||||
{
|
||||
// max_ratio is a floor value, so must be a bit increased
|
||||
$where_clause[] = 'width/height < '.($_SESSION['bulk_manager_filter']['dimension']['max_ratio']+0.01);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE '.implode(' AND ',$where_clause).'
|
||||
'.$conf['order_by'];
|
||||
|
||||
$filter_sets[] = query2array($query, null, 'id');
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['filesize']))
|
||||
{
|
||||
$where_clauses = array();
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['filesize']['min']))
|
||||
{
|
||||
// to counter the effect of converting kB to mB and rounding, we need to go slightly lower for the minimum value
|
||||
$where_clause[] = 'filesize >= '.($_SESSION['bulk_manager_filter']['filesize']['min'] - 0.1)*1024;
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['filesize']['max']))
|
||||
{
|
||||
// to counter the effect of converting kB to mB and rounding, we need to go slightly higher for the maximum value
|
||||
$where_clause[] = 'filesize <= '.($_SESSION['bulk_manager_filter']['filesize']['max'] + 0.1)*1024;
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE '.implode(' AND ',$where_clause).'
|
||||
'.$conf['order_by'];
|
||||
|
||||
$filter_sets[] = query2array($query, null, 'id');
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['search']) &&
|
||||
strlen($_SESSION['bulk_manager_filter']['search']['q']))
|
||||
{
|
||||
include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
|
||||
$res = get_quick_search_results_no_cache($_SESSION['bulk_manager_filter']['search']['q'], array('permissions'=>false));
|
||||
if (!empty($res['items']) && !empty($res['qs']['unmatched_terms']))
|
||||
{
|
||||
$template->assign('no_search_results', array_map('htmlspecialchars', $res['qs']['unmatched_terms']) );
|
||||
}
|
||||
$filter_sets[] = $res['items'];
|
||||
}
|
||||
|
||||
$filter_sets = trigger_change('batch_manager_perform_filters', $filter_sets, $_SESSION['bulk_manager_filter']);
|
||||
|
||||
$current_set = array_shift($filter_sets);
|
||||
foreach ($filter_sets as $set)
|
||||
{
|
||||
$current_set = array_intersect($current_set, $set);
|
||||
}
|
||||
$page['cat_elements_id'] = empty($current_set) ? array() : $current_set;
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | first element to display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// $page['start'] contains the number of the first element in its
|
||||
// category. For exampe, $page['start'] = 12 means we must show elements #12
|
||||
// and $page['nb_images'] next elements
|
||||
|
||||
if (!isset($_REQUEST['start'])
|
||||
or !is_numeric($_REQUEST['start'])
|
||||
or $_REQUEST['start'] < 0
|
||||
or (isset($_REQUEST['display']) and 'all' == $_REQUEST['display']))
|
||||
{
|
||||
$page['start'] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['start'] = $_REQUEST['start'];
|
||||
}
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$manager_link = get_root_url().'admin.php?page=batch_manager&mode=';
|
||||
|
||||
if (isset($_GET['mode']))
|
||||
{
|
||||
check_input_parameter('mode', $_GET, false, '/^(global|unit)$/');
|
||||
$page['tab'] = $_GET['mode'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['tab'] = 'global';
|
||||
}
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('batch_manager');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | dimensions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$widths = array();
|
||||
$heights = array();
|
||||
$ratios = array();
|
||||
$dimensions = array();
|
||||
|
||||
// get all width, height and ratios
|
||||
$query = '
|
||||
SELECT
|
||||
DISTINCT width, height
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE width IS NOT NULL
|
||||
AND height IS NOT NULL
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
if (pwg_db_num_rows($result))
|
||||
{
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ($row['width']>0 && $row['height']>0)
|
||||
{
|
||||
$widths[] = $row['width'];
|
||||
$heights[] = $row['height'];
|
||||
$ratios[] = floor($row['width'] / $row['height'] * 100) / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($widths))
|
||||
{ // arbitrary values, only used when no photos on the gallery
|
||||
$widths = array(600, 1920, 3500);
|
||||
$heights = array(480, 1080, 2300);
|
||||
$ratios = array(1.25, 1.52, 1.78);
|
||||
}
|
||||
|
||||
foreach (array('widths','heights','ratios') as $type)
|
||||
{
|
||||
${$type} = array_unique(${$type});
|
||||
sort(${$type});
|
||||
$dimensions[$type] = implode(',', ${$type});
|
||||
}
|
||||
|
||||
$dimensions['bounds'] = array(
|
||||
'min_width' => $widths[0],
|
||||
'max_width' => end($widths),
|
||||
'min_height' => $heights[0],
|
||||
'max_height' => end($heights),
|
||||
'min_ratio' => $ratios[0],
|
||||
'max_ratio' => end($ratios),
|
||||
);
|
||||
|
||||
// find ratio categories
|
||||
$ratio_categories = array(
|
||||
'portrait' => array(),
|
||||
'square' => array(),
|
||||
'landscape' => array(),
|
||||
'panorama' => array(),
|
||||
);
|
||||
|
||||
foreach ($ratios as $ratio)
|
||||
{
|
||||
if ($ratio < 0.95)
|
||||
{
|
||||
$ratio_categories['portrait'][] = $ratio;
|
||||
}
|
||||
else if ($ratio >= 0.95 and $ratio <= 1.05)
|
||||
{
|
||||
$ratio_categories['square'][] = $ratio;
|
||||
}
|
||||
else if ($ratio > 1.05 and $ratio < 2)
|
||||
{
|
||||
$ratio_categories['landscape'][] = $ratio;
|
||||
}
|
||||
else if ($ratio >= 2)
|
||||
{
|
||||
$ratio_categories['panorama'][] = $ratio;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($ratio_categories) as $type)
|
||||
{
|
||||
if (count($ratio_categories[$type]) > 0)
|
||||
{
|
||||
$dimensions['ratio_'.$type] = array(
|
||||
'min' => $ratio_categories[$type][0],
|
||||
'max' => end($ratio_categories[$type]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// selected=bound if nothing selected
|
||||
foreach (array_keys($dimensions['bounds']) as $type)
|
||||
{
|
||||
$dimensions['selected'][$type] = isset($_SESSION['bulk_manager_filter']['dimension'][$type])
|
||||
? $_SESSION['bulk_manager_filter']['dimension'][$type]
|
||||
: $dimensions['bounds'][$type]
|
||||
;
|
||||
}
|
||||
|
||||
$template->assign('dimensions', $dimensions);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | filesize |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$filesizes = array();
|
||||
$filesize = array();
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
filesize
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE filesize IS NOT NULL
|
||||
GROUP BY filesize
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$filesizes[] = sprintf('%.1f', $row['filesize']/1024);
|
||||
}
|
||||
|
||||
if (empty($filesizes))
|
||||
{ // arbitrary values, only used when no photos on the gallery
|
||||
$filesizes = array(0, 1, 2, 5, 8, 15);
|
||||
}
|
||||
|
||||
$filesizes = array_unique($filesizes);
|
||||
sort($filesizes);
|
||||
|
||||
$filesize['list'] = implode(',', $filesizes);
|
||||
|
||||
$filesize['bounds'] = array(
|
||||
'min' => $filesizes[0],
|
||||
'max' => end($filesizes),
|
||||
);
|
||||
|
||||
// selected=bound if nothing selected
|
||||
foreach (array_keys($filesize['bounds']) as $type)
|
||||
{
|
||||
$filesize['selected'][$type] = isset($_SESSION['bulk_manager_filter']['filesize'][$type])
|
||||
? $_SESSION['bulk_manager_filter']['filesize'][$type]
|
||||
: $filesize['bounds'][$type]
|
||||
;
|
||||
}
|
||||
|
||||
$template->assign('filesize', $filesize);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | open specific mode |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include(PHPWG_ROOT_PATH.'admin/batch_manager_'.$page['tab'].'.php');
|
||||
?>
|
||||
@@ -0,0 +1,621 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Management of elements set. Elements can belong to a category or to the
|
||||
* user caddie.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!empty($_POST))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
trigger_notify('loc_begin_element_set_global');
|
||||
|
||||
check_input_parameter('del_tags', $_POST, true, PATTERN_ID);
|
||||
check_input_parameter('associate', $_POST, true, PATTERN_ID);
|
||||
check_input_parameter('move', $_POST, false, PATTERN_ID);
|
||||
check_input_parameter('dissociate', $_POST, false, PATTERN_ID);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | current selection |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$collection = array();
|
||||
if (isset($_POST['nb_photos_deleted']))
|
||||
{
|
||||
check_input_parameter('nb_photos_deleted', $_POST, false, '/^\d+$/');
|
||||
|
||||
// let's fake a collection (we don't know the image_ids so we use "null", we only
|
||||
// care about the number of items here)
|
||||
$collection = array_fill(0, $_POST['nb_photos_deleted'], null);
|
||||
}
|
||||
else if (isset($_POST['setSelected']))
|
||||
{
|
||||
// Here we don't use check_input_parameter because preg_match has a limit in
|
||||
// the repetitive pattern. Found a limit to 3276 but may depend on memory.
|
||||
//
|
||||
// check_input_parameter('whole_set', $_POST, false, '/^\d+(,\d+)*$/');
|
||||
//
|
||||
// Instead, let's break the input parameter into pieces and check pieces one by one.
|
||||
$collection = explode(',', $_POST['whole_set']);
|
||||
|
||||
foreach ($collection as $id)
|
||||
{
|
||||
if (!preg_match('/^\d+$/', $id))
|
||||
{
|
||||
fatal_error('[Hacking attempt] the input parameter "whole_set" is not valid');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isset($_POST['selection']))
|
||||
{
|
||||
$collection = $_POST['selection'];
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | global mode form submission |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// $page['prefilter'] is a shortcut to test if the current filter contains a
|
||||
// given prefilter. The idea is to make conditions simpler to write in the
|
||||
// code.
|
||||
$page['prefilter'] = 'none';
|
||||
if (isset($_SESSION['bulk_manager_filter']['prefilter']))
|
||||
{
|
||||
$page['prefilter'] = $_SESSION['bulk_manager_filter']['prefilter'];
|
||||
}
|
||||
|
||||
$redirect_url = get_root_url().'admin.php?page='.$_GET['page'];
|
||||
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
// if the user tries to apply an action, it means that there is at least 1
|
||||
// photo in the selection
|
||||
if (count($collection) == 0)
|
||||
{
|
||||
$page['errors'][] = l10n('Select at least one photo');
|
||||
}
|
||||
|
||||
$action = $_POST['selectAction'];
|
||||
$redirect = false;
|
||||
|
||||
if ('remove_from_caddie' == $action)
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.CADDIE_TABLE.'
|
||||
WHERE element_id IN ('.implode(',', $collection).')
|
||||
AND user_id = '.$user['id'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// remove from caddie action available only in caddie so reload content
|
||||
$redirect = true;
|
||||
}
|
||||
|
||||
else if ('add_tags' == $action)
|
||||
{
|
||||
if (empty($_POST['add_tags']))
|
||||
{
|
||||
$page['errors'][] = l10n('Select at least one tag');
|
||||
}
|
||||
else
|
||||
{
|
||||
$tag_ids = get_tag_ids($_POST['add_tags']);
|
||||
add_tags($tag_ids, $collection);
|
||||
|
||||
if ('no_tag' == $page['prefilter'])
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ('del_tags' == $action)
|
||||
{
|
||||
if (isset($_POST['del_tags']) and count($_POST['del_tags']) > 0)
|
||||
{
|
||||
$taglist_before = get_image_tag_ids($collection);
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.IMAGE_TAG_TABLE.'
|
||||
WHERE image_id IN ('.implode(',', $collection).')
|
||||
AND tag_id IN ('.implode(',', $_POST['del_tags']).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$taglist_after = get_image_tag_ids($collection);
|
||||
$images_to_update = compare_image_tag_lists($taglist_before, $taglist_after);
|
||||
update_images_lastmodified($images_to_update);
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['tags']) &&
|
||||
count(array_intersect($_SESSION['bulk_manager_filter']['tags'], $_POST['del_tags'])))
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('Select at least one tag');
|
||||
}
|
||||
}
|
||||
|
||||
if ('associate' == $action)
|
||||
{
|
||||
if (empty($_POST['associate']))
|
||||
{
|
||||
$page['errors'][] = l10n('Select at least one album');
|
||||
} else {
|
||||
associate_images_to_categories(
|
||||
$collection,
|
||||
$_POST['associate']
|
||||
);
|
||||
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
// let's refresh the page because we the current set might be modified
|
||||
if ('no_album' == $page['prefilter'])
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
|
||||
else if ('no_virtual_album' == $page['prefilter'])
|
||||
{
|
||||
$category_info = get_cat_info($_POST['associate']);
|
||||
if (empty($category_info['dir']))
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ('move' == $action)
|
||||
{
|
||||
move_images_to_categories($collection, array($_POST['move']));
|
||||
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
// let's refresh the page because we the current set might be modified
|
||||
if ('no_album' == $page['prefilter'])
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
|
||||
else if ('no_virtual_album' == $page['prefilter'])
|
||||
{
|
||||
$category_info = get_cat_info($_POST['move']);
|
||||
if (empty($category_info['dir']))
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (isset($_SESSION['bulk_manager_filter']['category'])
|
||||
and $_POST['move'] != $_SESSION['bulk_manager_filter']['category'])
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if ('dissociate' == $action)
|
||||
{
|
||||
$nb_dissociated = dissociate_images_from_category($collection, $_POST['dissociate']);
|
||||
|
||||
if ($nb_dissociated > 0)
|
||||
{
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
// let's refresh the page because the current set might be modified
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
|
||||
// author
|
||||
else if ('author' == $action)
|
||||
{
|
||||
if (isset($_POST['remove_author']))
|
||||
{
|
||||
$_POST['author'] = null;
|
||||
}
|
||||
|
||||
$datas = array();
|
||||
foreach ($collection as $image_id)
|
||||
{
|
||||
$datas[] = array(
|
||||
'id' => $image_id,
|
||||
'author' => $_POST['author']
|
||||
);
|
||||
}
|
||||
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array('primary' => array('id'), 'update' => array('author')),
|
||||
$datas
|
||||
);
|
||||
|
||||
pwg_activity('photo', $collection, 'edit', array('action'=>'author'));
|
||||
}
|
||||
|
||||
// title
|
||||
else if ('title' == $action)
|
||||
{
|
||||
if (isset($_POST['remove_title']))
|
||||
{
|
||||
$_POST['title'] = null;
|
||||
}
|
||||
|
||||
$datas = array();
|
||||
foreach ($collection as $image_id)
|
||||
{
|
||||
$datas[] = array(
|
||||
'id' => $image_id,
|
||||
'name' => $_POST['title']
|
||||
);
|
||||
}
|
||||
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array('primary' => array('id'), 'update' => array('name')),
|
||||
$datas
|
||||
);
|
||||
|
||||
pwg_activity('photo', $collection, 'edit', array('action'=>'title'));
|
||||
}
|
||||
|
||||
// date_creation
|
||||
else if ('date_creation' == $action)
|
||||
{
|
||||
if (isset($_POST['remove_date_creation']) || empty($_POST['date_creation']))
|
||||
{
|
||||
$date_creation = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$date_creation = $_POST['date_creation'];
|
||||
}
|
||||
|
||||
$datas = array();
|
||||
foreach ($collection as $image_id)
|
||||
{
|
||||
$datas[] = array(
|
||||
'id' => $image_id,
|
||||
'date_creation' => $date_creation
|
||||
);
|
||||
}
|
||||
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array('primary' => array('id'), 'update' => array('date_creation')),
|
||||
$datas
|
||||
);
|
||||
|
||||
pwg_activity('photo', $collection, 'edit', array('action'=>'date_creation'));
|
||||
}
|
||||
|
||||
// privacy_level
|
||||
else if ('level' == $action)
|
||||
{
|
||||
$datas = array();
|
||||
foreach ($collection as $image_id)
|
||||
{
|
||||
$datas[] = array(
|
||||
'id' => $image_id,
|
||||
'level' => $_POST['level']
|
||||
);
|
||||
}
|
||||
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array('primary' => array('id'), 'update' => array('level')),
|
||||
$datas
|
||||
);
|
||||
|
||||
pwg_activity('photo', $collection, 'edit', array('action'=>'privacy_level'));
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['level']))
|
||||
{
|
||||
if ($_POST['level'] < $_SESSION['bulk_manager_filter']['level'])
|
||||
{
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add_to_caddie
|
||||
else if ('add_to_caddie' == $action)
|
||||
{
|
||||
fill_caddie($collection);
|
||||
}
|
||||
|
||||
// delete
|
||||
else if ('delete' == $action)
|
||||
{
|
||||
if (isset($_POST['confirm_deletion']) and 1 == $_POST['confirm_deletion'])
|
||||
{
|
||||
// now done with ajax calls, with blocks
|
||||
// $deleted_count = delete_elements($collection, true);
|
||||
if (count($collection) > 0)
|
||||
{
|
||||
$_SESSION['page_infos'][] = l10n_dec(
|
||||
'%d photo was deleted', '%d photos were deleted',
|
||||
count($collection)
|
||||
);
|
||||
|
||||
$redirect_url = get_root_url().'admin.php?page='.$_GET['page'];
|
||||
$redirect = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('No photo can be deleted');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('You need to confirm deletion');
|
||||
}
|
||||
}
|
||||
|
||||
// synchronize metadata
|
||||
else if ('metadata' == $action)
|
||||
{
|
||||
$page['infos'][] = l10n('Metadata synchronized from file').' <span class="badge">'.count($collection).'</span>';
|
||||
}
|
||||
|
||||
else if ('delete_derivatives' == $action && !empty($_POST['del_derivatives_type']))
|
||||
{
|
||||
$query='SELECT path,representative_ext FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $collection).')';
|
||||
$result = pwg_query($query);
|
||||
while ($info = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
foreach( $_POST['del_derivatives_type'] as $type)
|
||||
{
|
||||
delete_element_derivatives($info, $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ('generate_derivatives' == $action)
|
||||
{
|
||||
if ($_POST['regenerateSuccess'] != '0')
|
||||
{
|
||||
$page['infos'][] = l10n('%s photos have been regenerated', $_POST['regenerateSuccess']);
|
||||
}
|
||||
if ($_POST['regenerateError'] != '0')
|
||||
{
|
||||
$page['warnings'][] = l10n('%s photos can not be regenerated', $_POST['regenerateError']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($action, array('remove_from_caddie','add_to_caddie','delete_derivatives','generate_derivatives')))
|
||||
{
|
||||
invalidate_user_cache();
|
||||
}
|
||||
|
||||
trigger_notify('element_set_global_action', $action, $collection);
|
||||
|
||||
if ($redirect)
|
||||
{
|
||||
redirect($redirect_url);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filenames(array('batch_manager_global' => 'batch_manager_global.tpl'));
|
||||
|
||||
$base_url = get_root_url().'admin.php';
|
||||
|
||||
include(PHPWG_ROOT_PATH.'admin/include/batch_manager_filters.inc.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | caddie options |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign('IN_CADDIE', 'caddie' == $page['prefilter']);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | global mode form |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (count($page['cat_elements_id']) > 0)
|
||||
{
|
||||
// remove tags
|
||||
$template->assign('associated_tags', get_common_tags($page['cat_elements_id'], -1));
|
||||
}
|
||||
|
||||
// creation date
|
||||
$template->assign('DATE_CREATION',
|
||||
empty($_POST['date_creation']) ? date('Y-m-d').' 00:00:00' : $_POST['date_creation']
|
||||
);
|
||||
|
||||
// image level options
|
||||
$template->assign(
|
||||
array(
|
||||
'level_options'=> get_privacy_level_options(),
|
||||
'level_options_selected' => 0,
|
||||
)
|
||||
);
|
||||
|
||||
// metadata
|
||||
include_once( PHPWG_ROOT_PATH.'admin/site_reader_local.php');
|
||||
$site_reader = new LocalSiteReader('./');
|
||||
$used_metadata = implode( ', ', $site_reader->get_metadata_attributes());
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'used_metadata' => $used_metadata,
|
||||
)
|
||||
);
|
||||
|
||||
//derivatives
|
||||
$del_deriv_map = array();
|
||||
foreach(ImageStdParams::get_defined_type_map() as $params)
|
||||
{
|
||||
$del_deriv_map[$params->type] = l10n($params->type);
|
||||
}
|
||||
$gen_deriv_map = $del_deriv_map;
|
||||
$del_deriv_map[IMG_CUSTOM] = l10n(IMG_CUSTOM);
|
||||
$template->assign(
|
||||
array(
|
||||
'del_derivatives_types' => $del_deriv_map,
|
||||
'generate_derivatives_types' => $gen_deriv_map,
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | global mode thumbnails |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// how many items to display on this page
|
||||
if (!empty($_GET['display']))
|
||||
{
|
||||
if ('all' == $_GET['display'])
|
||||
{
|
||||
$page['nb_images'] = count($page['cat_elements_id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['nb_images'] = intval($_GET['display']);
|
||||
}
|
||||
}
|
||||
elseif (in_array($conf['batch_manager_images_per_page_global'], array(20, 50, 100)))
|
||||
{
|
||||
$page['nb_images'] = $conf['batch_manager_images_per_page_global'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['nb_images'] = 20;
|
||||
}
|
||||
|
||||
$nb_thumbs_page = 0;
|
||||
|
||||
if (count($page['cat_elements_id']) > 0)
|
||||
{
|
||||
$nav_bar = create_navigation_bar(
|
||||
$base_url.get_query_string_diff(array('start')),
|
||||
count($page['cat_elements_id']),
|
||||
$page['start'],
|
||||
$page['nb_images']
|
||||
);
|
||||
$template->assign('navbar', $nav_bar);
|
||||
|
||||
$is_category = false;
|
||||
if (isset($_SESSION['bulk_manager_filter']['category'])
|
||||
and !isset($_SESSION['bulk_manager_filter']['category_recursive']))
|
||||
{
|
||||
$is_category = true;
|
||||
}
|
||||
|
||||
// If using the 'duplicates' filter,
|
||||
// order by the fields that are used to find duplicates.
|
||||
if (isset($_SESSION['bulk_manager_filter']['prefilter'])
|
||||
and 'duplicates' === $_SESSION['bulk_manager_filter']['prefilter']
|
||||
and isset($duplicates_on_fields))
|
||||
{
|
||||
// The $duplicates_on_fields variable is defined in ./batch_manager.php
|
||||
$order_by_fields = array_merge( $duplicates_on_fields, array( 'id' ) );
|
||||
$conf['order_by'] = ' ORDER BY '.join(', ', $order_by_fields);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id,path,representative_ext,file,filesize,level,name,width,height,rotation
|
||||
FROM '.IMAGES_TABLE;
|
||||
|
||||
if ($is_category)
|
||||
{
|
||||
$category_info = get_cat_info($_SESSION['bulk_manager_filter']['category']);
|
||||
|
||||
$conf['order_by'] = $conf['order_by_inside_category'];
|
||||
if (!empty($category_info['image_order']))
|
||||
{
|
||||
$conf['order_by'] = ' ORDER BY '.$category_info['image_order'];
|
||||
}
|
||||
|
||||
$query.= '
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
WHERE id IN ('.implode(',', $page['cat_elements_id']).')';
|
||||
|
||||
if ($is_category)
|
||||
{
|
||||
$query.= '
|
||||
AND category_id = '.$_SESSION['bulk_manager_filter']['category'];
|
||||
}
|
||||
|
||||
$query.= '
|
||||
'.$conf['order_by'].'
|
||||
LIMIT '.$page['nb_images'].' OFFSET '.$page['start'].'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
$thumb_params = ImageStdParams::get_by_type(IMG_SQUARE);
|
||||
// template thumbnail initialization
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$nb_thumbs_page++;
|
||||
$src_image = new SrcImage($row);
|
||||
|
||||
$ttitle = render_element_name($row);
|
||||
if ($ttitle != get_name_from_file($row['file']))
|
||||
{
|
||||
$ttitle.= ' ('.$row['file'].')';
|
||||
}
|
||||
|
||||
$ttitle.= '<br>'.$row['width'].'×'.$row['height'].' pixels, '.sprintf('%.2f', $row['filesize']/1024).'MB';
|
||||
|
||||
$template->append(
|
||||
'thumbnails', array_merge($row,
|
||||
array(
|
||||
'thumb' => new DerivativeImage($thumb_params, $src_image),
|
||||
'TITLE' => $ttitle,
|
||||
'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image),
|
||||
'U_EDIT' => get_root_url().'admin.php?page=photo-'.$row['id'],
|
||||
)
|
||||
));
|
||||
}
|
||||
$template->assign('thumb_params', $thumb_params);
|
||||
}
|
||||
|
||||
$template->assign(array(
|
||||
'nb_thumbs_page' => $nb_thumbs_page,
|
||||
'nb_thumbs_set' => count($page['cat_elements_id']),
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')),
|
||||
));
|
||||
|
||||
trigger_notify('loc_end_element_set_global');
|
||||
|
||||
//----------------------------------------------------------- sending html code
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'batch_manager_global');
|
||||
?>
|
||||
@@ -0,0 +1,424 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Management of elements set. Elements can belong to a category or to the
|
||||
* user caddie.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
trigger_notify('loc_begin_element_set_unit');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | unit mode form submission |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
check_pwg_token();
|
||||
check_input_parameter('element_ids', $_POST, false, '/^\d+(,\d+)*$/');
|
||||
$collection = explode(',', $_POST['element_ids']);
|
||||
|
||||
$datas = array();
|
||||
|
||||
$query = '
|
||||
SELECT id, date_creation
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $collection).')
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data['id'] = $row['id'];
|
||||
$data['name'] = $_POST['name-'.$row['id']];
|
||||
$data['author'] = $_POST['author-'.$row['id']];
|
||||
$data['level'] = $_POST['level-'.$row['id']];
|
||||
|
||||
if ($conf['allow_html_descriptions'])
|
||||
{
|
||||
$data['comment'] = @$_POST['description-'.$row['id']];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['comment'] = strip_tags(@$_POST['description-'.$row['id']]);
|
||||
}
|
||||
|
||||
if (!empty($_POST['date_creation-'.$row['id']]))
|
||||
{
|
||||
$data['date_creation'] = $_POST['date_creation-'.$row['id']];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['date_creation'] = null;
|
||||
}
|
||||
|
||||
$datas[] = $data;
|
||||
|
||||
// tags management
|
||||
$tag_ids = array();
|
||||
if (!empty($_POST[ 'tags-'.$row['id'] ]))
|
||||
{
|
||||
$tag_ids = get_tag_ids($_POST[ 'tags-'.$row['id'] ]);
|
||||
}
|
||||
set_tags($tag_ids, $row['id']);
|
||||
}
|
||||
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array(
|
||||
'primary' => array('id'),
|
||||
'update' => array('name','author','level','comment','date_creation')
|
||||
),
|
||||
$datas
|
||||
);
|
||||
|
||||
$page['infos'][] = l10n('Photo informations updated');
|
||||
invalidate_user_cache();
|
||||
}
|
||||
|
||||
//collection
|
||||
$collection = array();
|
||||
if (isset($_POST['nb_photos_deleted']))
|
||||
{
|
||||
check_input_parameter('nb_photos_deleted', $_POST, false, '/^\d+$/');
|
||||
|
||||
// let's fake a collection (we don't know the image_ids so we use "null", we only
|
||||
// care about the number of items here)
|
||||
$collection = array_fill(0, $_POST['nb_photos_deleted'], null);
|
||||
}
|
||||
else if (isset($_POST['setSelected']))
|
||||
{
|
||||
// Here we don't use check_input_parameter because preg_match has a limit in
|
||||
// the repetitive pattern. Found a limit to 3276 but may depend on memory.
|
||||
//
|
||||
// check_input_parameter('whole_set', $_POST, false, '/^\d+(,\d+)*$/');
|
||||
//
|
||||
// Instead, let's break the input parameter into pieces and check pieces one by one.
|
||||
$collection = explode(',', $_POST['whole_set']);
|
||||
|
||||
foreach ($collection as $id)
|
||||
{
|
||||
if (!preg_match('/^\d+$/', $id))
|
||||
{
|
||||
fatal_error('[Hacking attempt] the input parameter "whole_set" is not valid');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isset($_POST['selection']))
|
||||
{
|
||||
$collection = $_POST['selection'];
|
||||
}
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(
|
||||
array('batch_manager_unit' => 'batch_manager_unit.tpl'));
|
||||
|
||||
$base_url = PHPWG_ROOT_PATH.'admin.php';
|
||||
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
|
||||
'U_ELEMENTS_PAGE' => $base_url.get_query_string_diff(array('display','start')),
|
||||
'level_options' => get_privacy_level_options(),
|
||||
'ADMIN_PAGE_TITLE' => l10n('Batch Manager'),
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
include(PHPWG_ROOT_PATH.'admin/include/batch_manager_filters.inc.php');
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | global mode thumbnails |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign('ACTIVE_PLUGINS', array_keys($pwg_loaded_plugins));
|
||||
|
||||
// how many items to display on this page
|
||||
if (!empty($_GET['display']))
|
||||
{
|
||||
// conf_update_param('batch_manager_images_per_page_unit' , intval($_GET['display']));
|
||||
// $page['nb_images'] = $conf['batch_manager_images_per_page_unit'];
|
||||
$page['nb_images'] = intval($_GET['display']);
|
||||
}
|
||||
elseif (in_array($conf['batch_manager_images_per_page_unit'], array(5, 10, 50)))
|
||||
{
|
||||
$page['nb_images'] = $conf['batch_manager_images_per_page_unit'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['nb_images'] = 5;
|
||||
}
|
||||
$template->assign('per_page', $page['nb_images']);
|
||||
|
||||
if (count($page['cat_elements_id']) > 0)
|
||||
{
|
||||
$nav_bar = create_navigation_bar(
|
||||
$base_url.get_query_string_diff(array('start')),
|
||||
count($page['cat_elements_id']),
|
||||
$page['start'],
|
||||
$page['nb_images']
|
||||
);
|
||||
$template->assign(array('navbar' => $nav_bar));
|
||||
|
||||
$element_ids = array();
|
||||
|
||||
$is_category = false;
|
||||
if (isset($_SESSION['bulk_manager_filter']['category'])
|
||||
and !isset($_SESSION['bulk_manager_filter']['category_recursive']))
|
||||
{
|
||||
$is_category = true;
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['prefilter'])
|
||||
and 'duplicates' == $_SESSION['bulk_manager_filter']['prefilter'])
|
||||
{
|
||||
$conf['order_by'] = ' ORDER BY file, id';
|
||||
}
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.IMAGES_TABLE;
|
||||
|
||||
if ($is_category)
|
||||
{
|
||||
$category_info = get_cat_info($_SESSION['bulk_manager_filter']['category']);
|
||||
|
||||
$conf['order_by'] = $conf['order_by_inside_category'];
|
||||
if (!empty($category_info['image_order']))
|
||||
{
|
||||
$conf['order_by'] = ' ORDER BY '.$category_info['image_order'];
|
||||
}
|
||||
|
||||
$query.= '
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
WHERE id IN ('.implode(',', $page['cat_elements_id']).')';
|
||||
|
||||
if ($is_category)
|
||||
{
|
||||
$query.= '
|
||||
AND category_id = '.$_SESSION['bulk_manager_filter']['category'];
|
||||
}
|
||||
|
||||
$query.= '
|
||||
'.$conf['order_by'].'
|
||||
LIMIT '.$page['nb_images'].' OFFSET '.$page['start'].'
|
||||
;';
|
||||
// $result = pwg_query($query);
|
||||
$images = query2array($query);
|
||||
$added_by_ids = array_unique(array_column($images, 'added_by'));
|
||||
if (count($added_by_ids) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
'.$conf['user_fields']['username'].' AS username,
|
||||
'.$conf['user_fields']['id'].' AS id
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['id'].' IN ( '.implode(',', $added_by_ids).' )
|
||||
;';
|
||||
$added_by_username_of = query2array($query, 'id', 'username');
|
||||
}
|
||||
|
||||
$storage_category_id = null;
|
||||
if (!empty($row['storage_category_id']))
|
||||
{
|
||||
$storage_category_id = $row['storage_category_id'];
|
||||
}
|
||||
|
||||
foreach ($images as $row)
|
||||
{
|
||||
$element_ids[] = $row['id'];
|
||||
|
||||
$src_image = new SrcImage($row);
|
||||
|
||||
$image_file = $row['file'];
|
||||
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
name
|
||||
FROM '.IMAGE_TAG_TABLE.' AS it
|
||||
JOIN '.TAGS_TABLE.' AS t ON t.id = it.tag_id
|
||||
WHERE image_id = '.$row['id'].'
|
||||
;';
|
||||
|
||||
$tag_selection = get_taglist($query);
|
||||
|
||||
$legend = render_element_name($row);
|
||||
if ($legend != get_name_from_file($row['file']))
|
||||
{
|
||||
$legend.= ' ('.$row['file'].')';
|
||||
}
|
||||
$extTab = explode('.',$row['path']);
|
||||
|
||||
|
||||
|
||||
// represent
|
||||
|
||||
// categories
|
||||
|
||||
$query = '
|
||||
SELECT category_id, uppercats, dir
|
||||
FROM '.IMAGE_CATEGORY_TABLE.' AS ic
|
||||
INNER JOIN '.CATEGORIES_TABLE.' AS c
|
||||
ON c.id = ic.category_id
|
||||
WHERE image_id = '.$row['id'].'
|
||||
;';
|
||||
|
||||
$sub_result = pwg_query($query);
|
||||
$related_categories = array();
|
||||
$related_category_ids = array();
|
||||
$media['image'] = get_image_infos($row['id'], true);
|
||||
|
||||
while ($item = pwg_db_fetch_assoc($sub_result))
|
||||
{
|
||||
$name =
|
||||
get_cat_display_name_cache(
|
||||
$item['uppercats'],
|
||||
get_root_url().'admin.php?page=album-'
|
||||
);
|
||||
|
||||
if ($item['category_id'] == $storage_category_id)
|
||||
{
|
||||
$template->assign('STORAGE_CATEGORY', $name);
|
||||
}
|
||||
|
||||
$related_categories[$item['category_id']] = array('name' => $name, 'unlinkable' => $item['category_id'] != $storage_category_id);
|
||||
$related_category_ids[] = $item['category_id'];
|
||||
}
|
||||
|
||||
// jump to link
|
||||
$image_file = $row['file'];
|
||||
|
||||
$query = '
|
||||
SELECT category_id
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
WHERE image_id = '.$row['id'].'
|
||||
;';
|
||||
$authorizeds = array_diff(
|
||||
array_from_query($query, 'category_id'),
|
||||
explode(
|
||||
',',
|
||||
calculate_permissions($user['id'], $user['status'])
|
||||
)
|
||||
);
|
||||
|
||||
if (isset($row['cat_id'])
|
||||
and in_array($row['cat_id'], $authorizeds))
|
||||
{
|
||||
$url_img = make_picture_url(
|
||||
array(
|
||||
'image_id' => $row['id'],
|
||||
'image_file' => $image_file,
|
||||
'category' => $cache['cat_names'][ $row['cat_id'] ],
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($authorizeds as $category)
|
||||
{
|
||||
$url_img = make_picture_url(
|
||||
array(
|
||||
'image_id' => $row['id'], //utile ?
|
||||
'image_file' => $image_file,
|
||||
'category' => $cache['cat_names'][ $category ],
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$admin_photo_base_url = get_root_url().'admin.php?page=photo-'.$row['id'];
|
||||
$admin_url_start = $admin_photo_base_url.'-properties';
|
||||
$admin_url_start.= isset($row['cat_id']) ? '&cat_id='.$row['cat_id'] : '';
|
||||
$selected_level = isset($row['level']) ? $row['level'] : $row['level'];
|
||||
|
||||
|
||||
$template->append(
|
||||
'elements', array_merge($row,
|
||||
array(
|
||||
'ID' => $row['id'],
|
||||
'TN_SRC' => DerivativeImage::url(IMG_MEDIUM, $src_image),
|
||||
'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image),
|
||||
'LEGEND' => $legend,
|
||||
'U_EDIT' => get_root_url().'admin.php?page=photo-'.$row['id'],
|
||||
'NAME' => htmlspecialchars(isset($row['name']) ? $row['name'] : ""),
|
||||
'AUTHOR' => htmlspecialchars(isset($row['author']) ? $row['author'] : ""),
|
||||
'LEVEL' => !empty($row['level'])?$row['level']:'0',
|
||||
'DESCRIPTION' => htmlspecialchars(isset($row['comment']) ? $row['comment'] : ""),
|
||||
'DATE_CREATION' => $row['date_creation'],
|
||||
'TAGS' => $tag_selection,
|
||||
'is_svg' => (strtoupper(end($extTab)) == 'SVG'),
|
||||
'TITLE' => render_element_name($row),
|
||||
'DIMENSIONS' => @$row['width'].'x'.@$row['height'].' px',
|
||||
'FORMAT' => ($row['width'] >= $row['height'])? 1:0,//0:horizontal, 1:vertical
|
||||
'FILESIZE' => l10n('%.2f MB',$row['filesize']/1024),
|
||||
'REGISTRATION_DATE' => format_date($row['date_available']),
|
||||
'EXT' => l10n('%s file type',end($extTab)),
|
||||
'POST_DATE' => l10n('Added on %s', format_date($row['date_available'], array('day', 'month', 'year'))),
|
||||
'AGE' => l10n(ucfirst(time_since($row['date_available'], 'year'))),
|
||||
'ADDED_BY' => l10n('Added by %s', $added_by_username_of[ $row['added_by'] ] ?? l10n('N/A')),
|
||||
'STATS' => l10n('Visited %d times', $row['hit']),
|
||||
'FILE' => l10n('%s', $row['file']),
|
||||
'related_categories' => $related_categories,
|
||||
'related_category_ids' => json_encode($related_category_ids),
|
||||
'U_JUMPTO' => (isset($url_img) and $user['level'] >= $media['image']['level']) ? $url_img : null,
|
||||
'tag_selection' => $tag_selection,
|
||||
'U_DOWNLOAD' => 'action.php?id='.$row['id'].'&part=e&pwg_token='.get_pwg_token().'&download',
|
||||
'U_HISTORY' => get_root_url().'admin.php?page=history&filter_image_id='.$row['id'],
|
||||
'U_ACTIVITY' => get_root_url().'admin.php?page=user_activity&photo='.$row['id'],
|
||||
'U_DELETE' => $admin_url_start.'&delete=1&pwg_token='.get_pwg_token(),
|
||||
'U_SYNC' => $admin_url_start.'&sync_metadata=1',
|
||||
'PATH'=>$row['path'],
|
||||
'level_options_selected' => array($selected_level)
|
||||
|
||||
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
$template->assign(array(
|
||||
'ELEMENT_IDS' => implode(',', $element_ids),
|
||||
));
|
||||
}
|
||||
|
||||
$template->assign(array(
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')),
|
||||
));
|
||||
|
||||
trigger_notify('loc_end_element_set_unit');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'batch_manager_unit');
|
||||
?>
|
||||
@@ -0,0 +1,355 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
trigger_notify('loc_begin_cat_list');
|
||||
|
||||
if (!empty($_POST) or isset($_GET['delete']))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
$sort_orders = array(
|
||||
'name ASC' => l10n('Album name, A → Z'),
|
||||
'name DESC' => l10n('Album name, Z → A'),
|
||||
'date_creation DESC' => l10n('Date created, new → old').' '.l10n('(determined from photos)'),
|
||||
'date_creation ASC' => l10n('Date created, old → new').' '.l10n('(determined from photos)'),
|
||||
'date_available DESC' => l10n('Date posted, new → old').' '.l10n('(determined from photos)'),
|
||||
'date_available ASC' => l10n('Date posted, old → new').' '.l10n('(determined from photos)'),
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | functions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
function get_categories_ref_date($ids, $field='date_available', $minmax='max')
|
||||
{
|
||||
// we need to work on the whole tree under each category, even if we don't
|
||||
// want to sort sub categories
|
||||
$category_ids = get_subcat_ids($ids);
|
||||
|
||||
// search for the reference date of each album
|
||||
$query = '
|
||||
SELECT
|
||||
category_id,
|
||||
'.$minmax.'('.$field.') as ref_date
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
JOIN '.IMAGES_TABLE.' ON image_id = id
|
||||
WHERE category_id IN ('.implode(',', $category_ids).')
|
||||
GROUP BY category_id
|
||||
;';
|
||||
$ref_dates = query2array($query, 'category_id', 'ref_date');
|
||||
|
||||
// the iterate on all albums (having a ref_date or not) to find the
|
||||
// reference_date, with a search on sub-albums
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
uppercats
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $category_ids).')
|
||||
;';
|
||||
$uppercats_of = query2array($query, 'id', 'uppercats');
|
||||
|
||||
foreach (array_keys($uppercats_of) as $cat_id)
|
||||
{
|
||||
// find the subcats
|
||||
$subcat_ids = array();
|
||||
|
||||
foreach ($uppercats_of as $id => $uppercats)
|
||||
{
|
||||
if (preg_match('/(^|,)'.$cat_id.'(,|$)/', $uppercats))
|
||||
{
|
||||
$subcat_ids[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$to_compare = array();
|
||||
foreach ($subcat_ids as $id)
|
||||
{
|
||||
if (isset($ref_dates[$id]))
|
||||
{
|
||||
$to_compare[] = $ref_dates[$id];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($to_compare) > 0)
|
||||
{
|
||||
$ref_dates[$cat_id] = 'max' == $minmax ? max($to_compare) : min($to_compare);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ref_dates[$cat_id] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// only return the list of $ids, not the sub-categories
|
||||
$return = array();
|
||||
foreach ($ids as $id)
|
||||
{
|
||||
$return[$id] = $ref_dates[$id];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_input_parameter('parent_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
$categories = array();
|
||||
|
||||
$base_url = get_root_url().'admin.php?page=cat_list';
|
||||
$navigation = '<a href="'.$base_url.'">';
|
||||
$navigation.= l10n('Home');
|
||||
$navigation.= '</a>';
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$page['tab'] = 'list';
|
||||
include(PHPWG_ROOT_PATH.'admin/include/albums_tab.inc.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | virtual categories management |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// request to delete a virtual category
|
||||
if (isset($_GET['delete']) and is_numeric($_GET['delete']))
|
||||
{
|
||||
$photo_deletion_mode = 'no_delete';
|
||||
if (isset($_GET['photo_deletion_mode']))
|
||||
{
|
||||
$photo_deletion_mode = $_GET['photo_deletion_mode'];
|
||||
}
|
||||
delete_categories(array($_GET['delete']), $photo_deletion_mode);
|
||||
|
||||
$_SESSION['page_infos'] = array(l10n('Virtual album deleted'));
|
||||
update_global_rank();
|
||||
invalidate_user_cache();
|
||||
|
||||
$redirect_url = get_root_url().'admin.php?page=cat_list';
|
||||
if (isset($_GET['parent_id']))
|
||||
{
|
||||
$redirect_url.= '&parent_id='.$_GET['parent_id'];
|
||||
}
|
||||
redirect($redirect_url);
|
||||
}
|
||||
// request to add a virtual category
|
||||
elseif (isset($_POST['submitAdd']))
|
||||
{
|
||||
$output_create = create_virtual_category(
|
||||
$_POST['virtual_name'],
|
||||
@$_GET['parent_id']
|
||||
);
|
||||
|
||||
invalidate_user_cache();
|
||||
if (isset($output_create['error']))
|
||||
{
|
||||
$page['errors'][] = $output_create['error'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$edit_url = get_root_url().'admin.php?page=album-'.$output_create['id'];
|
||||
$page['infos'][] = $output_create['info'].' <a class="icon-pencil" href="'.$edit_url.'">'.l10n('Edit album').'</a>';
|
||||
}
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Navigation path |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['parent_id']))
|
||||
{
|
||||
$navigation.= $conf['level_separator'];
|
||||
|
||||
$navigation.= get_cat_display_name_from_id(
|
||||
$_GET['parent_id'],
|
||||
$base_url.'&parent_id='
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filename('categories', 'cat_list.tpl');
|
||||
|
||||
$form_action = PHPWG_ROOT_PATH.'admin.php?page=cat_list';
|
||||
if (isset($_GET['parent_id']))
|
||||
{
|
||||
$form_action.= '&parent_id='.$_GET['parent_id'];
|
||||
}
|
||||
$sort_orders_checked = array_keys($sort_orders);
|
||||
|
||||
$template->assign(array(
|
||||
'ADMIN_PAGE_TITLE' => l10n('Album list management'),
|
||||
'CATEGORIES_NAV'=> preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$navigation)),
|
||||
'F_ACTION'=>$form_action,
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'sort_orders' => $sort_orders,
|
||||
'sort_order_checked' => array_shift($sort_orders_checked),
|
||||
));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Categories display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$categories = array();
|
||||
|
||||
$query = '
|
||||
SELECT id, name, permalink, dir, `rank`, status
|
||||
FROM '.CATEGORIES_TABLE;
|
||||
if (!isset($_GET['parent_id']))
|
||||
{
|
||||
$query.= '
|
||||
WHERE id_uppercat IS NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= '
|
||||
WHERE id_uppercat = '.$_GET['parent_id'];
|
||||
}
|
||||
$query.= '
|
||||
ORDER BY `rank` ASC
|
||||
;';
|
||||
$categories = hash_from_query($query, 'id');
|
||||
|
||||
// get the categories containing images directly
|
||||
$categories_with_images = array();
|
||||
if (count($categories))
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
category_id,
|
||||
COUNT(*) AS nb_photos
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
GROUP BY category_id
|
||||
;';
|
||||
// WHERE category_id IN ('.implode(',', array_keys($categories)).')
|
||||
|
||||
$nb_photos_in = query2array($query, 'category_id', 'nb_photos');
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
uppercats
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
$all_categories = query2array($query, 'id', 'uppercats');
|
||||
$subcats_of = array();
|
||||
|
||||
foreach ($all_categories as $id => $uppercats)
|
||||
{
|
||||
foreach (array_slice(explode(',', $uppercats), 0, -1) as $uppercat_id)
|
||||
{
|
||||
@$subcats_of[$uppercat_id][] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$nb_sub_photos = array();
|
||||
foreach ($subcats_of as $cat_id => $subcat_ids)
|
||||
{
|
||||
$nb_photos = 0;
|
||||
foreach ($subcat_ids as $id)
|
||||
{
|
||||
if (isset($nb_photos_in[$id]))
|
||||
{
|
||||
$nb_photos+= $nb_photos_in[$id];
|
||||
}
|
||||
}
|
||||
|
||||
$nb_sub_photos[$cat_id] = $nb_photos;
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign('categories', array());
|
||||
$base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
if (isset($_GET['parent_id']))
|
||||
{
|
||||
$template->assign(
|
||||
'PARENT_EDIT',
|
||||
$base_url.'album-'.$_GET['parent_id']
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($categories as $category)
|
||||
{
|
||||
$cat_list_url = $base_url.'cat_list';
|
||||
|
||||
$self_url = $cat_list_url;
|
||||
if (isset($_GET['parent_id']))
|
||||
{
|
||||
$self_url.= '&parent_id='.$_GET['parent_id'];
|
||||
}
|
||||
|
||||
$tpl_cat =
|
||||
array(
|
||||
'NAME' =>
|
||||
trigger_change(
|
||||
'render_category_name',
|
||||
$category['name'],
|
||||
'admin_cat_list'
|
||||
),
|
||||
'NB_PHOTOS' => isset($nb_photos_in[$category['id']]) ? $nb_photos_in[$category['id']] : 0,
|
||||
'NB_SUB_PHOTOS' => isset($nb_sub_photos[$category['id']]) ? $nb_sub_photos[$category['id']] : 0,
|
||||
'NB_SUB_ALBUMS' => isset($subcats_of[$category['id']]) ? count($subcats_of[$category['id']]) : 0,
|
||||
'ID' => $category['id'],
|
||||
'RANK' => $category['rank']*10,
|
||||
|
||||
'U_JUMPTO' => make_index_url(
|
||||
array(
|
||||
'category' => $category
|
||||
)
|
||||
),
|
||||
|
||||
'U_CHILDREN' => $cat_list_url.'&parent_id='.$category['id'],
|
||||
'U_EDIT' => $base_url.'album-'.$category['id'],
|
||||
'U_ADD_PHOTOS_ALBUM' => $base_url.'photos_add&album='.$category['id'],
|
||||
'U_MOVE' => $base_url.'albums#cat-'.$category['id'],
|
||||
|
||||
'IS_VIRTUAL' => empty($category['dir']),
|
||||
'CAT_ADMIN_ACCESS' => cat_admin_access($category['id']),
|
||||
);
|
||||
|
||||
if (empty($category['dir']))
|
||||
{
|
||||
$tpl_cat['U_DELETE'] = $self_url.'&delete='.$category['id'];
|
||||
$tpl_cat['U_DELETE'].= '&pwg_token='.get_pwg_token();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($conf['enable_synchronization'])
|
||||
{
|
||||
$tpl_cat['U_SYNC'] = $base_url.'site_update&site=1&cat_id='.$category['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$template->append('categories', $tpl_cat);
|
||||
}
|
||||
|
||||
trigger_notify('loc_end_cat_list');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'categories');
|
||||
?>
|
||||
@@ -0,0 +1,394 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
|
||||
|
||||
// get_complete_dir returns the concatenation of get_site_url and
|
||||
// get_local_dir
|
||||
// Example : "pets > rex > 1_year_old" is on the the same site as the
|
||||
// Piwigo files and this category has 22 for identifier
|
||||
// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
|
||||
function get_complete_dir( $category_id )
|
||||
{
|
||||
return get_site_url($category_id).get_local_dir($category_id);
|
||||
}
|
||||
|
||||
// get_local_dir returns an array with complete path without the site url
|
||||
// Example : "pets > rex > 1_year_old" is on the the same site as the
|
||||
// Piwigo files and this category has 22 for identifier
|
||||
// get_local_dir(22) returns "pets/rex/1_year_old/"
|
||||
function get_local_dir( $category_id )
|
||||
{
|
||||
global $page;
|
||||
|
||||
$uppercats = '';
|
||||
$local_dir = '';
|
||||
|
||||
if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
|
||||
{
|
||||
$uppercats = $page['plain_structure'][$category_id]['uppercats'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = 'SELECT uppercats';
|
||||
$query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
|
||||
$query.= ';';
|
||||
$row = pwg_db_fetch_assoc( pwg_query( $query ) );
|
||||
$uppercats = $row['uppercats'];
|
||||
}
|
||||
|
||||
$upper_array = explode( ',', $uppercats );
|
||||
|
||||
$database_dirs = array();
|
||||
$query = 'SELECT id,dir';
|
||||
$query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
|
||||
$query.= ';';
|
||||
$result = pwg_query( $query );
|
||||
while( $row = pwg_db_fetch_assoc( $result ) )
|
||||
{
|
||||
$database_dirs[$row['id']] = $row['dir'];
|
||||
}
|
||||
foreach ($upper_array as $id)
|
||||
{
|
||||
$local_dir.= $database_dirs[$id].'/';
|
||||
}
|
||||
|
||||
return $local_dir;
|
||||
}
|
||||
|
||||
// retrieving the site url : "http://domain.com/gallery/" or
|
||||
// simply "./galleries/"
|
||||
function get_site_url($category_id)
|
||||
{
|
||||
global $page;
|
||||
|
||||
$query = '
|
||||
SELECT galleries_url
|
||||
FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
|
||||
WHERE s.id = c.site_id
|
||||
AND c.id = '.$category_id.'
|
||||
;';
|
||||
$row = pwg_db_fetch_assoc(pwg_query($query));
|
||||
return $row['galleries_url'];
|
||||
}
|
||||
|
||||
function get_min_local_dir($local_dir)
|
||||
{
|
||||
$full_dir = explode('/', $local_dir);
|
||||
if (count($full_dir) <= 3)
|
||||
{
|
||||
return $local_dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
$start = $full_dir[0] . '/' . $full_dir[1];
|
||||
$end = end($full_dir);
|
||||
$concat = $start . '/…/' . $end;
|
||||
return $concat;
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
trigger_notify('loc_begin_cat_modify');
|
||||
|
||||
//---------------------------------------------------------------- verification
|
||||
if ( !isset( $_GET['cat_id'] ) || !is_numeric( $_GET['cat_id'] ) )
|
||||
{
|
||||
trigger_error( 'missing cat_id param', E_USER_ERROR);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------- form criteria check
|
||||
|
||||
if (isset($redirect))
|
||||
{
|
||||
redirect($admin_album_base_url.'-properties');
|
||||
}
|
||||
|
||||
// nullable fields
|
||||
foreach (array('comment','dir','site_id', 'id_uppercat') as $nullable)
|
||||
{
|
||||
if (!isset($category[$nullable]))
|
||||
{
|
||||
$category[$nullable] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$category['is_virtual'] = empty($category['dir']) ? true : false;
|
||||
|
||||
$query = 'SELECT DISTINCT category_id
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
WHERE category_id = '.$_GET['cat_id'].'
|
||||
LIMIT 1';
|
||||
$result = pwg_query($query);
|
||||
$category['has_images'] = pwg_db_num_rows($result)>0 ? true : false;
|
||||
|
||||
// number of sub-categories
|
||||
$subcat_ids = get_subcat_ids(array($category['id']));
|
||||
|
||||
$category['nb_subcats'] = count($subcat_ids) - 1;
|
||||
|
||||
// Navigation path
|
||||
$navigation = get_cat_display_name_cache(
|
||||
$category['uppercats'],
|
||||
get_root_url().'admin.php?page=album-'
|
||||
);
|
||||
|
||||
// Parent navigation path
|
||||
$uppercats_array = explode(',', $category['uppercats']);
|
||||
if (count($uppercats_array) > 1)
|
||||
{
|
||||
array_pop($uppercats_array);
|
||||
$parent_navigation = get_cat_display_name_cache(
|
||||
implode(',', $uppercats_array),
|
||||
get_root_url().'admin.php?page=album-'
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$parent_navigation = l10n('Root');
|
||||
}
|
||||
|
||||
//----------------------------------------------------- template initialization
|
||||
$template->set_filename( 'album_properties', 'cat_modify.tpl');
|
||||
|
||||
$base_url = get_root_url().'admin.php?page=';
|
||||
$cat_list_url = $base_url.'albums';
|
||||
|
||||
$self_url = $cat_list_url;
|
||||
if (!empty($category['id_uppercat']))
|
||||
{
|
||||
$self_url.= '&parent_id='.$category['id_uppercat'];
|
||||
}
|
||||
|
||||
// We show or hide this warning in JS
|
||||
$page['warnings'][] = l10n('This album is currently locked, visible only to administrators.').'<span class="icon-cone unlock-album">'.l10n('Unlock it').'</span>';
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'CATEGORIES_NAV' => preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$navigation)),
|
||||
'CATEGORIES_PARENT_NAV' => preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$parent_navigation)),
|
||||
'PARENT_CAT_ID' => !empty($category['id_uppercat']) ? $category['id_uppercat'] : 0,
|
||||
'CAT_ID' => $category['id'],
|
||||
'CAT_NAME' => @htmlspecialchars($category['name']),
|
||||
'CAT_COMMENT' => @htmlspecialchars($category['comment']),
|
||||
'IS_VISIBLE' => boolean_to_string($category['visible']),
|
||||
'CAT_ADMIN_ACCESS' => cat_admin_access($category['id']),
|
||||
|
||||
'U_DELETE' => $base_url.'albums',
|
||||
|
||||
'U_JUMPTO' => make_index_url(
|
||||
array(
|
||||
'category' => $category
|
||||
)
|
||||
),
|
||||
|
||||
'U_ADD_PHOTOS_ALBUM' => $base_url.'photos_add&album='.$category['id'],
|
||||
'U_CHILDREN' => $cat_list_url.'&parent_id='.$category['id'],
|
||||
'U_MOVE' => $base_url.'albums&parent_id='.$category['id'],
|
||||
'U_ACTIVITY' => get_root_url().'admin.php?page=user_activity&album='.$category['id'],
|
||||
)
|
||||
);
|
||||
|
||||
if ($conf['activate_comments'])
|
||||
{
|
||||
$template->assign('CAT_COMMENTABLE', boolean_to_string($category['commentable']));
|
||||
}
|
||||
|
||||
// manage album elements link
|
||||
$image_count = 0;
|
||||
$info_title = "";
|
||||
if ($category['has_images'])
|
||||
{
|
||||
$template->assign(
|
||||
'U_MANAGE_ELEMENTS',
|
||||
$base_url.'batch_manager&filter=album-'.$category['id']
|
||||
);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(image_id),
|
||||
MIN(DATE(date_available)),
|
||||
MAX(DATE(date_available))
|
||||
FROM '.IMAGES_TABLE.'
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id
|
||||
WHERE category_id = '.$category['id'].'
|
||||
;';
|
||||
list($image_count, $min_date, $max_date) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
if ($min_date == $max_date)
|
||||
{
|
||||
$info_title = l10n(
|
||||
'This album contains %d photos, added on %s.',
|
||||
$image_count,
|
||||
format_date($min_date)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$info_title = l10n(
|
||||
'This album contains %d photos, added between %s and %s.',
|
||||
$image_count,
|
||||
format_date($min_date),
|
||||
format_date($max_date)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
$info_photos = l10n('%d photos', $image_count);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'INFO_PHOTO' => $info_photos,
|
||||
'INFO_TITLE' => $info_title
|
||||
)
|
||||
);
|
||||
|
||||
// total number of images under this category (including sub-categories)
|
||||
$query = '
|
||||
SELECT DISTINCT
|
||||
(image_id)
|
||||
FROM
|
||||
'.IMAGE_CATEGORY_TABLE.'
|
||||
WHERE
|
||||
category_id IN ('.implode(',', $subcat_ids).')
|
||||
;';
|
||||
$image_ids_recursive = query2array($query, null, 'image_id');
|
||||
|
||||
$category['nb_images_recursive'] = count($image_ids_recursive);
|
||||
|
||||
// date creation
|
||||
$query = '
|
||||
SELECT occured_on
|
||||
FROM `'.ACTIVITY_TABLE.'`
|
||||
WHERE object_id = '.$category['id'].'
|
||||
AND object = "album"
|
||||
AND action = "add"
|
||||
';
|
||||
$result = query2array($query);
|
||||
|
||||
if (count($result) > 0) {
|
||||
$template->assign(
|
||||
array(
|
||||
'INFO_CREATION_SINCE' => time_since($result[0]['occured_on'], 'day', $format=null, $with_text=true, $with_week=true, $only_last_unit=true),
|
||||
'INFO_CREATION' => format_date($result[0]['occured_on'], array('day', 'month','year'))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Sub Albums
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM `'.CATEGORIES_TABLE.'`
|
||||
WHERE id_uppercat = '.$category['id'].'
|
||||
';
|
||||
$result = query2array($query);
|
||||
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'INFO_DIRECT_SUB' => l10n(
|
||||
'%d sub-albums',
|
||||
$result[0]['COUNT(*)']
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign(array(
|
||||
'INFO_ID' => l10n('Numeric identifier : %d',$category['id']),
|
||||
'INFO_LAST_MODIFIED_SINCE' => time_since($category['lastmodified'], 'minute', $format=null, $with_text=true, $with_week=true, $only_last_unit=true),
|
||||
'INFO_LAST_MODIFIED'=> format_date($category['lastmodified'], array('day', 'month','year')),
|
||||
'INFO_IMAGES_RECURSIVE' => l10n(
|
||||
'%d including sub-albums',
|
||||
$category['nb_images_recursive']
|
||||
),
|
||||
'INFO_SUBCATS' => l10n(
|
||||
'%d in whole branch',
|
||||
$category['nb_subcats']
|
||||
),
|
||||
|
||||
'NB_SUBCATS' => $category['nb_subcats'],
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign(array(
|
||||
'U_MANAGE_RANKS' => $base_url.'element_set_ranks&cat_id='.$category['id'],
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('categories')),
|
||||
));
|
||||
|
||||
if (!$category['is_virtual'])
|
||||
{
|
||||
$category['cat_full_dir'] = get_complete_dir($_GET['cat_id']);
|
||||
$category_full_dir = preg_replace('/\/$/', '', $category['cat_full_dir']);
|
||||
$template->assign(
|
||||
array(
|
||||
'CAT_FULL_DIR' => $category_full_dir
|
||||
)
|
||||
);
|
||||
$template->assign('CAT_DIR_NAME', basename($category_full_dir));
|
||||
$template->assign('CAT_MIN_DIR', get_min_local_dir($category_full_dir));
|
||||
|
||||
if ($conf['enable_synchronization'])
|
||||
{
|
||||
$template->assign(
|
||||
'U_SYNC',
|
||||
$base_url.'site_update&site='.$category['site_id'].'&cat_id='.$category['id']
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// representant management
|
||||
if ($category['has_images'] or !empty($category['representative_picture_id']))
|
||||
{
|
||||
$tpl_representant = array();
|
||||
|
||||
// picture to display : the identified representant or the generic random
|
||||
// representant ?
|
||||
if (!empty($category['representative_picture_id']))
|
||||
{
|
||||
$tpl_representant['picture'] = get_category_representant_properties($category['representative_picture_id'], IMG_MEDIUM);
|
||||
}
|
||||
|
||||
// can the admin choose to set a new random representant ?
|
||||
$tpl_representant['ALLOW_SET_RANDOM'] = ($category['has_images'] ? true : false);
|
||||
|
||||
// can the admin delete the current representant ?
|
||||
if (
|
||||
($category['has_images']
|
||||
and $conf['allow_random_representative'])
|
||||
or
|
||||
(!$category['has_images']
|
||||
and !empty($category['representative_picture_id'])))
|
||||
{
|
||||
$tpl_representant['ALLOW_DELETE'] = true;
|
||||
}
|
||||
$template->assign('representant', $tpl_representant);
|
||||
}
|
||||
|
||||
if ($category['is_virtual'])
|
||||
{
|
||||
$template->assign('parent_category', empty($category['id_uppercat']) ? array() : array($category['id_uppercat']));
|
||||
}
|
||||
|
||||
$template->assign('PWG_TOKEN', get_pwg_token());
|
||||
|
||||
trigger_notify('loc_end_cat_modify');
|
||||
|
||||
//----------------------------------------------------------- sending html code
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'album_properties');
|
||||
?>
|
||||
@@ -0,0 +1,253 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!empty($_POST))
|
||||
{
|
||||
check_pwg_token();
|
||||
check_input_parameter('cat_true', $_POST, true, PATTERN_ID);
|
||||
check_input_parameter('cat_false', $_POST, true, PATTERN_ID);
|
||||
check_input_parameter('section', $_GET, false, '/^[a-z0-9_-]+$/i');
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | modification registration |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
|
||||
if (isset($_POST['falsify'])
|
||||
and isset($_POST['cat_true'])
|
||||
and count($_POST['cat_true']) > 0)
|
||||
{
|
||||
switch ($_GET['section'])
|
||||
{
|
||||
case 'comments' :
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET commentable = \'false\'
|
||||
WHERE id IN ('.implode(',', $_POST['cat_true']).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
case 'visible' :
|
||||
{
|
||||
set_cat_visible($_POST['cat_true'], 'false');
|
||||
break;
|
||||
}
|
||||
case 'status' :
|
||||
{
|
||||
set_cat_status($_POST['cat_true'], 'private');
|
||||
break;
|
||||
}
|
||||
case 'representative' :
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET representative_picture_id = NULL
|
||||
WHERE id IN ('.implode(',', $_POST['cat_true']).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pwg_activity('album', $_POST['cat_true'], 'edit', array('section'=>$_GET['section'], 'action'=>'falsify'));
|
||||
}
|
||||
else if (isset($_POST['trueify'])
|
||||
and isset($_POST['cat_false'])
|
||||
and count($_POST['cat_false']) > 0)
|
||||
{
|
||||
switch ($_GET['section'])
|
||||
{
|
||||
case 'comments' :
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET commentable = \'true\'
|
||||
WHERE id IN ('.implode(',', $_POST['cat_false']).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
case 'visible' :
|
||||
{
|
||||
set_cat_visible($_POST['cat_false'], 'true');
|
||||
break;
|
||||
}
|
||||
case 'status' :
|
||||
{
|
||||
set_cat_status($_POST['cat_false'], 'public');
|
||||
break;
|
||||
}
|
||||
case 'representative' :
|
||||
{
|
||||
// theoretically, all categories in $_POST['cat_false'] contain at
|
||||
// least one element, so Piwigo can find a representant.
|
||||
set_random_representant($_POST['cat_false']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pwg_activity('album', $_POST['cat_false'], 'edit', array('section'=>$_GET['section'], 'action'=>'trueify'));
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(
|
||||
array(
|
||||
'cat_options' => 'cat_options.tpl',
|
||||
'double_select' => 'double_select.tpl'
|
||||
)
|
||||
);
|
||||
|
||||
$page['section'] = isset($_GET['section']) ? $_GET['section'] : 'status';
|
||||
$base_url = PHPWG_ROOT_PATH.'admin.php?page=cat_options&section=';
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=cat_options',
|
||||
'F_ACTION'=>$base_url.$page['section']
|
||||
)
|
||||
);
|
||||
|
||||
// TabSheet
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('cat_options');
|
||||
$tabsheet->select($page['section']);
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | form display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// for each section, categories in the multiselect field can be :
|
||||
//
|
||||
// - true : commentable for comment section
|
||||
// - false : un-commentable for comment section
|
||||
// - NA : (not applicable) for virtual categories
|
||||
//
|
||||
// for true and false status, we associates an array of category ids,
|
||||
// function display_select_categories will use the given CSS class for each
|
||||
// option
|
||||
$cats_true = array();
|
||||
$cats_false = array();
|
||||
switch ($page['section'])
|
||||
{
|
||||
case 'comments' :
|
||||
{
|
||||
$query_true = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE commentable = \'true\'
|
||||
;';
|
||||
$query_false = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE commentable = \'false\'
|
||||
;';
|
||||
$template->assign(
|
||||
array(
|
||||
'L_SECTION' => l10n('Authorize users to add comments on selected albums'),
|
||||
'L_CAT_OPTIONS_TRUE' => l10n('Authorized'),
|
||||
'L_CAT_OPTIONS_FALSE' => l10n('Forbidden'),
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'visible' :
|
||||
{
|
||||
$query_true = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE visible = \'true\'
|
||||
;';
|
||||
$query_false = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE visible = \'false\'
|
||||
;';
|
||||
$template->assign(
|
||||
array(
|
||||
'L_SECTION' => l10n('Lock albums'),
|
||||
'L_CAT_OPTIONS_TRUE' => l10n('Unlocked'),
|
||||
'L_CAT_OPTIONS_FALSE' => l10n('Locked'),
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'status' :
|
||||
{
|
||||
$query_true = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE status = \'public\'
|
||||
;';
|
||||
$query_false = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE status = \'private\'
|
||||
;';
|
||||
$template->assign(
|
||||
array(
|
||||
'L_SECTION' => l10n('Manage authorizations for selected albums'),
|
||||
'L_CAT_OPTIONS_TRUE' => l10n('Public'),
|
||||
'L_CAT_OPTIONS_FALSE' => l10n('Private'),
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'representative' :
|
||||
{
|
||||
$query_true = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE representative_picture_id IS NOT NULL
|
||||
;';
|
||||
$query_false = '
|
||||
SELECT DISTINCT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=category_id
|
||||
WHERE representative_picture_id IS NULL
|
||||
;';
|
||||
$template->assign(
|
||||
array(
|
||||
'L_SECTION' => l10n('Representative'),
|
||||
'L_CAT_OPTIONS_TRUE' => l10n('singly represented'),
|
||||
'L_CAT_OPTIONS_FALSE' => l10n('randomly represented')
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
display_select_cat_wrapper($query_true,array(),'category_option_true');
|
||||
display_select_cat_wrapper($query_false,array(),'category_option_false');
|
||||
$template->assign('PWG_TOKEN',get_pwg_token());
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Properties of abums'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_options');
|
||||
?>
|
||||
@@ -0,0 +1,303 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | variable initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$page['cat'] = $category['id'];
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | form submission |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!empty($_POST))
|
||||
{
|
||||
check_pwg_token();
|
||||
|
||||
if ($category['status'] != $_POST['status'] or ($category['status'] != 'public' and isset($_POST['apply_on_sub'])))
|
||||
{
|
||||
$cat_ids = array($page['cat']);
|
||||
if (isset($_POST['apply_on_sub']))
|
||||
{
|
||||
$cat_ids = array_merge($cat_ids, get_subcat_ids(array($page['cat'])));
|
||||
}
|
||||
set_cat_status($cat_ids, $_POST['status']);
|
||||
$category['status'] = $_POST['status'];
|
||||
}
|
||||
|
||||
if ('private' == $_POST['status'])
|
||||
{
|
||||
//
|
||||
// manage groups
|
||||
//
|
||||
$query = '
|
||||
SELECT group_id
|
||||
FROM '.GROUP_ACCESS_TABLE.'
|
||||
WHERE cat_id = '.$page['cat'].'
|
||||
;';
|
||||
$groups_granted = array_from_query($query, 'group_id');
|
||||
|
||||
if (!isset($_POST['groups']))
|
||||
{
|
||||
$_POST['groups'] = array();
|
||||
}
|
||||
|
||||
//
|
||||
// remove permissions to groups
|
||||
//
|
||||
$deny_groups = array_diff($groups_granted, $_POST['groups']);
|
||||
if (count($deny_groups) > 0)
|
||||
{
|
||||
// if you forbid access to an album, all sub-albums become
|
||||
// automatically forbidden
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.GROUP_ACCESS_TABLE.'
|
||||
WHERE group_id IN ('.implode(',', $deny_groups).')
|
||||
AND cat_id IN ('.implode(',', get_subcat_ids(array($page['cat']))).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
//
|
||||
// add permissions to groups
|
||||
//
|
||||
$grant_groups = $_POST['groups'];
|
||||
if (count($grant_groups) > 0)
|
||||
{
|
||||
$cat_ids = get_uppercat_ids(array($page['cat']));
|
||||
if (isset($_POST['apply_on_sub']))
|
||||
{
|
||||
$cat_ids = array_merge($cat_ids, get_subcat_ids(array($page['cat'])));
|
||||
}
|
||||
|
||||
$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 ($grant_groups 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)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// users
|
||||
//
|
||||
$query = '
|
||||
SELECT user_id
|
||||
FROM '.USER_ACCESS_TABLE.'
|
||||
WHERE cat_id = '.$page['cat'].'
|
||||
;';
|
||||
$users_granted = array_from_query($query, 'user_id');
|
||||
|
||||
if (!isset($_POST['users']))
|
||||
{
|
||||
$_POST['users'] = array();
|
||||
}
|
||||
|
||||
//
|
||||
// remove permissions to users
|
||||
//
|
||||
$deny_users = array_diff($users_granted, $_POST['users']);
|
||||
if (count($deny_users) > 0)
|
||||
{
|
||||
// if you forbid access to an album, all sub-album become automatically
|
||||
// forbidden
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.USER_ACCESS_TABLE.'
|
||||
WHERE user_id IN ('.implode(',', $deny_users).')
|
||||
AND cat_id IN ('.implode(',', get_subcat_ids(array($page['cat']))).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
//
|
||||
// add permissions to users
|
||||
//
|
||||
$grant_users = $_POST['users'];
|
||||
if (count($grant_users) > 0)
|
||||
{
|
||||
add_permission_on_category($page['cat'], $grant_users);
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' =>l10n('Album updated successfully'),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filename('cat_perm', 'cat_perm.tpl');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'CATEGORIES_NAV' =>
|
||||
get_cat_display_name_from_id(
|
||||
$page['cat'],
|
||||
'admin.php?page=album-'
|
||||
),
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=cat_perm',
|
||||
'F_ACTION' => $admin_album_base_url.'-permissions',
|
||||
'private' => ('private' == $category['status']),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | form construction |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// groups denied are the groups not granted. So we need to find all groups
|
||||
// minus groups granted to find groups denied.
|
||||
|
||||
$groups = array();
|
||||
|
||||
$query = '
|
||||
SELECT id, name
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
ORDER BY name ASC
|
||||
;';
|
||||
$groups = simple_hash_from_query($query, 'id', 'name');
|
||||
$template->assign('groups', $groups);
|
||||
|
||||
// groups granted to access the category
|
||||
$query = '
|
||||
SELECT group_id
|
||||
FROM '.GROUP_ACCESS_TABLE.'
|
||||
WHERE cat_id = '.$page['cat'].'
|
||||
;';
|
||||
$group_granted_ids = array_from_query($query, 'group_id');
|
||||
$template->assign('groups_selected', $group_granted_ids);
|
||||
|
||||
// users...
|
||||
$users = array();
|
||||
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['id'].' AS id,
|
||||
'.$conf['user_fields']['username'].' AS username
|
||||
FROM '.USERS_TABLE.'
|
||||
;';
|
||||
$users = simple_hash_from_query($query, 'id', 'username');
|
||||
$template->assign('users', $users);
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT user_id
|
||||
FROM '.USER_ACCESS_TABLE.'
|
||||
WHERE cat_id = '.$page['cat'].'
|
||||
;';
|
||||
$user_granted_direct_ids = array_from_query($query, 'user_id');
|
||||
$template->assign('users_selected', $user_granted_direct_ids);
|
||||
|
||||
|
||||
$user_granted_indirect_ids = array();
|
||||
if (count($group_granted_ids) > 0)
|
||||
{
|
||||
$granted_groups = array();
|
||||
|
||||
$query = '
|
||||
SELECT user_id, group_id
|
||||
FROM '.USER_GROUP_TABLE.'
|
||||
WHERE group_id IN ('.implode(',', $group_granted_ids).')
|
||||
';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if (!isset($granted_groups[ $row['group_id'] ]))
|
||||
{
|
||||
$granted_groups[ $row['group_id'] ] = array();
|
||||
}
|
||||
$granted_groups[ $row['group_id'] ][] = $row['user_id'];
|
||||
}
|
||||
|
||||
$user_granted_by_group_ids = array();
|
||||
|
||||
foreach ($granted_groups as $group_users)
|
||||
{
|
||||
$user_granted_by_group_ids = array_merge($user_granted_by_group_ids, $group_users);
|
||||
}
|
||||
|
||||
$user_granted_by_group_ids = array_unique($user_granted_by_group_ids);
|
||||
|
||||
$user_granted_indirect_ids = array_diff(
|
||||
$user_granted_by_group_ids,
|
||||
$user_granted_direct_ids
|
||||
);
|
||||
|
||||
$template->assign('nb_users_granted_indirect', count($user_granted_indirect_ids));
|
||||
|
||||
foreach ($granted_groups as $group_id => $group_users)
|
||||
{
|
||||
$group_usernames = array();
|
||||
foreach ($group_users as $user_id)
|
||||
{
|
||||
if (in_array($user_id, $user_granted_indirect_ids))
|
||||
{
|
||||
$group_usernames[] = $users[$user_id];
|
||||
}
|
||||
}
|
||||
|
||||
$template->append(
|
||||
'user_granted_indirect_groups',
|
||||
array(
|
||||
'group_name' => $groups[$group_id],
|
||||
'group_users' => implode(', ', $group_usernames),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign(array(
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'INHERIT' => $conf['inheritance_by_default'],
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('groups', 'users')),
|
||||
));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_perm');
|
||||
?>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(array('comments'=>'comments.tpl'));
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ACTION' => get_root_url().'admin.php?page=comments',
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('comments');
|
||||
$tabsheet->select('');
|
||||
$tabsheet->assign();
|
||||
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('User comments'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'comments');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,707 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
//-------------------------------------------------------- sections definitions
|
||||
|
||||
check_input_parameter('section', $_GET, false, '/^[a-z]+$/i');
|
||||
|
||||
if (!isset($_GET['section']))
|
||||
{
|
||||
$page['section'] = 'main';
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['section'] = $_GET['section'];
|
||||
}
|
||||
|
||||
$main_checkboxes = array(
|
||||
'allow_user_registration',
|
||||
'obligatory_user_mail_address',
|
||||
'rate',
|
||||
'rate_anonymous',
|
||||
'allow_user_customization',
|
||||
'log',
|
||||
'history_admin',
|
||||
'history_guest',
|
||||
'show_mobile_app_banner_in_gallery',
|
||||
'show_mobile_app_banner_in_admin',
|
||||
'upload_detect_duplicate',
|
||||
'use_standard_pages',
|
||||
);
|
||||
|
||||
$sizes_checkboxes = array(
|
||||
'original_resize',
|
||||
);
|
||||
|
||||
$comments_checkboxes = array(
|
||||
'activate_comments',
|
||||
'comments_forall',
|
||||
'comments_validation',
|
||||
'email_admin_on_comment',
|
||||
'email_admin_on_comment_validation',
|
||||
'user_can_delete_comment',
|
||||
'user_can_edit_comment',
|
||||
'email_admin_on_comment_edition',
|
||||
'email_admin_on_comment_deletion',
|
||||
'comments_author_mandatory',
|
||||
'comments_email_mandatory',
|
||||
'comments_enable_website',
|
||||
);
|
||||
|
||||
$display_checkboxes = array(
|
||||
'menubar_filter_icon',
|
||||
'index_search_in_set_button',
|
||||
'index_search_in_set_action',
|
||||
'index_sort_order_input',
|
||||
'index_flat_icon',
|
||||
'index_posted_date_icon',
|
||||
'index_created_date_icon',
|
||||
'index_slideshow_icon',
|
||||
'index_sizes_icon',
|
||||
'index_new_icon',
|
||||
'index_edit_icon',
|
||||
'index_caddie_icon',
|
||||
'display_fromto',
|
||||
'picture_metadata_icon',
|
||||
'picture_slideshow_icon',
|
||||
'picture_favorite_icon',
|
||||
'picture_sizes_icon',
|
||||
'picture_download_icon',
|
||||
'picture_edit_icon',
|
||||
'picture_caddie_icon',
|
||||
'picture_representative_icon',
|
||||
'picture_navigation_icons',
|
||||
'picture_navigation_thumb',
|
||||
'picture_menu',
|
||||
);
|
||||
|
||||
$display_info_checkboxes = array(
|
||||
'author',
|
||||
'created_on',
|
||||
'posted_on',
|
||||
'dimensions',
|
||||
'file',
|
||||
'filesize',
|
||||
'tags',
|
||||
'categories',
|
||||
'visits',
|
||||
'rating_score',
|
||||
);
|
||||
|
||||
if (!isset($conf['filters_views']))
|
||||
{
|
||||
conf_update_param('filters_views', $conf['default_filters_views'], true);
|
||||
}
|
||||
|
||||
$filters_names_checkboxes = array_values(array_diff(array_keys(safe_unserialize($conf['filters_views'])), array('last_filters_conf')));
|
||||
|
||||
// image order management
|
||||
$sort_fields = array(
|
||||
'' => '',
|
||||
'file ASC' => l10n('File name, A → Z'),
|
||||
'file DESC' => l10n('File name, Z → A'),
|
||||
'name ASC' => l10n('Photo title, A → Z'),
|
||||
'name DESC' => l10n('Photo title, Z → A'),
|
||||
'date_creation DESC' => l10n('Date created, new → old'),
|
||||
'date_creation ASC' => l10n('Date created, old → new'),
|
||||
'date_available DESC' => l10n('Date posted, new → old'),
|
||||
'date_available ASC' => l10n('Date posted, old → new'),
|
||||
'rating_score DESC' => l10n('Rating score, high → low'),
|
||||
'rating_score ASC' => l10n('Rating score, low → high'),
|
||||
'hit DESC' => l10n('Visits, high → low'),
|
||||
'hit ASC' => l10n('Visits, low → high'),
|
||||
'id ASC' => l10n('Numeric identifier, 1 → 9'),
|
||||
'id DESC' => l10n('Numeric identifier, 9 → 1'),
|
||||
'`rank` ASC' => l10n('Manual sort order'),
|
||||
);
|
||||
|
||||
$comments_order = array(
|
||||
'ASC' => l10n('Show oldest comments first'),
|
||||
'DESC' => l10n('Show latest comments first'),
|
||||
);
|
||||
|
||||
$mail_themes = array(
|
||||
'clear' => 'Clear',
|
||||
'dark' => 'Dark',
|
||||
);
|
||||
|
||||
//------------------------------ verification and registration of modifications
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
check_pwg_token();
|
||||
$int_pattern = '/^\d+$/';
|
||||
|
||||
switch ($page['section'])
|
||||
{
|
||||
case 'main' :
|
||||
{
|
||||
if ( !isset($conf['order_by_custom']) and !isset($conf['order_by_inside_category_custom']) )
|
||||
{
|
||||
if ( !empty($_POST['order_by']) )
|
||||
{
|
||||
check_input_parameter('order_by', $_POST, true, '/^('.implode('|', array_keys($sort_fields)).')$/');
|
||||
|
||||
$used = array();
|
||||
foreach ($_POST['order_by'] as $i => $val)
|
||||
{
|
||||
if (empty($val) or isset($used[$val]))
|
||||
{
|
||||
unset($_POST['order_by'][$i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$used[$val] = true;
|
||||
}
|
||||
}
|
||||
if ( !count($_POST['order_by']) )
|
||||
{
|
||||
$page['errors'][] = l10n('No order field selected');
|
||||
}
|
||||
else
|
||||
{
|
||||
// limit to the number of available parameters
|
||||
$order_by = $order_by_inside_category = array_slice($_POST['order_by'], 0, ceil(count($sort_fields)/2));
|
||||
|
||||
// there is no rank outside categories
|
||||
if ( ($i = array_search('`rank` ASC', $order_by)) !== false)
|
||||
{
|
||||
unset($order_by[$i]);
|
||||
}
|
||||
|
||||
// must define a default order_by if user want to order by rank only
|
||||
if ( count($order_by) == 0 )
|
||||
{
|
||||
$order_by = array('id ASC');
|
||||
}
|
||||
|
||||
$_POST['order_by'] = 'ORDER BY '.implode(', ', $order_by);
|
||||
$_POST['order_by_inside_category'] = 'ORDER BY '.implode(', ', $order_by_inside_category);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('No order field selected');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($_POST['email_admin_on_new_user']))
|
||||
{
|
||||
$_POST['email_admin_on_new_user'] = 'none';
|
||||
}
|
||||
elseif ('all' == $_POST['email_admin_on_new_user_filter'])
|
||||
{
|
||||
$_POST['email_admin_on_new_user'] = 'all';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($_POST['email_admin_on_new_user_filter_group']))
|
||||
{
|
||||
$_POST['email_admin_on_new_user'] = 'all';
|
||||
}
|
||||
else
|
||||
{
|
||||
$_POST['email_admin_on_new_user'] = 'group:'.$_POST['email_admin_on_new_user_filter_group'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $main_checkboxes as $checkbox)
|
||||
{
|
||||
$_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'watermark' :
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/include/configuration_watermark_process.inc.php');
|
||||
break;
|
||||
}
|
||||
case 'sizes' :
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/include/configuration_sizes_process.inc.php');
|
||||
break;
|
||||
}
|
||||
case 'comments' :
|
||||
{
|
||||
// the number of comments per page must be an integer between 5 and 50
|
||||
// included
|
||||
if (!preg_match($int_pattern, $_POST['nb_comment_page'])
|
||||
or $_POST['nb_comment_page'] < 5
|
||||
or $_POST['nb_comment_page'] > 50)
|
||||
{
|
||||
$page['errors'][] = l10n('The number of comments a page must be between 5 and 50 included.');
|
||||
}
|
||||
foreach( $comments_checkboxes as $checkbox)
|
||||
{
|
||||
$_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'default' :
|
||||
{
|
||||
// Never go here
|
||||
break;
|
||||
}
|
||||
case 'display' :
|
||||
{
|
||||
if (!preg_match($int_pattern, $_POST['nb_categories_page'])
|
||||
or $_POST['nb_categories_page'] < 4)
|
||||
{
|
||||
$page['errors'][] = l10n('The number of albums a page must be above 4.');
|
||||
}
|
||||
foreach( $display_checkboxes as $checkbox)
|
||||
{
|
||||
$_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
|
||||
}
|
||||
foreach( $display_info_checkboxes as $checkbox)
|
||||
{
|
||||
$_POST['picture_informations'][$checkbox] =
|
||||
empty($_POST['picture_informations'][$checkbox])? false : true;
|
||||
}
|
||||
$_POST['picture_informations'] = addslashes(serialize($_POST['picture_informations']));
|
||||
break;
|
||||
}
|
||||
case 'search' :
|
||||
{
|
||||
foreach( $filters_names_checkboxes as $checkbox)
|
||||
{
|
||||
if (empty($_POST['filters_views_box'][$checkbox])){
|
||||
$_POST['filters_views'][$checkbox]['access'] = 'nobody';
|
||||
$_POST['filters_views'][$checkbox]['default'] = false;
|
||||
}
|
||||
else{
|
||||
$_POST['filters_views'][$checkbox]['default'] =
|
||||
empty($_POST['filters_views'][$checkbox]['default'])? false : true;
|
||||
}
|
||||
}
|
||||
$_POST['filters_views']['last_filters_conf'] =
|
||||
empty($_POST['filters_views']['last_filters_conf'])? false : true;
|
||||
$_POST['filters_views'] = addslashes(serialize($_POST['filters_views']));
|
||||
}
|
||||
}
|
||||
|
||||
// updating configuration if no error found
|
||||
if (!in_array($page['section'], array('sizes', 'watermark')) and count($page['errors']) == 0 and is_webmaster())
|
||||
{
|
||||
//echo '<pre>'; print_r($_POST); echo '</pre>';
|
||||
$result = pwg_query('SELECT param FROM '.CONFIG_TABLE);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if (isset($_POST[$row['param']]))
|
||||
{
|
||||
$value = $_POST[$row['param']];
|
||||
|
||||
if ('gallery_title' == $row['param'])
|
||||
{
|
||||
if (!$conf['allow_html_descriptions'])
|
||||
{
|
||||
$value = strip_tags($value);
|
||||
}
|
||||
}
|
||||
|
||||
$query = '
|
||||
UPDATE '.CONFIG_TABLE.'
|
||||
SET value = \''. str_replace("\'", "''", $value).'\'
|
||||
WHERE param = \''.$row['param'].'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n('Your configuration settings are saved'),
|
||||
)
|
||||
);
|
||||
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>$page['section']));
|
||||
}
|
||||
|
||||
//------------------------------------------------------ $conf reinitialization
|
||||
load_conf_from_db();
|
||||
}
|
||||
|
||||
// restore default derivatives settings
|
||||
if ('sizes' == $page['section'] and isset($_GET['action']) and 'restore_settings' == $_GET['action'])
|
||||
{
|
||||
ImageStdParams::restore_default();
|
||||
clear_derivative_cache();
|
||||
|
||||
// reset conf
|
||||
load_conf_from_db();
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n('Your configuration settings are saved'),
|
||||
)
|
||||
);
|
||||
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>$page['section'],'config_action'=>$_GET['action']));
|
||||
}
|
||||
|
||||
//----------------------------------------------------- template initialization
|
||||
$template->set_filename('config', 'configuration_' . $page['section'] . '.tpl');
|
||||
|
||||
// TabSheet
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('configuration');
|
||||
$tabsheet->select($page['section']);
|
||||
$tabsheet->assign();
|
||||
|
||||
$action = get_root_url().'admin.php?page=configuration';
|
||||
$action.= '&section='.$page['section'];
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=configuration',
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'F_ACTION'=>$action
|
||||
));
|
||||
|
||||
switch ($page['section'])
|
||||
{
|
||||
case 'main' :
|
||||
{
|
||||
|
||||
function order_by_is_local()
|
||||
{
|
||||
$conf = array();
|
||||
include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
|
||||
@include(PHPWG_ROOT_PATH. 'local/config/config.inc.php');
|
||||
if (isset($conf['local_dir_site']))
|
||||
{
|
||||
@include(PHPWG_ROOT_PATH.PWG_LOCAL_DIR. 'config/config.inc.php');
|
||||
}
|
||||
|
||||
return isset($conf['order_by']) or isset($conf['order_by_inside_category']);
|
||||
}
|
||||
|
||||
if (order_by_is_local())
|
||||
{
|
||||
$page['warnings'][] = l10n('You have specified <i>$conf[\'order_by\']</i> in your local configuration file, this parameter in deprecated, please remove it or rename it into <i>$conf[\'order_by_custom\']</i> !');
|
||||
}
|
||||
|
||||
if ( isset($conf['order_by_custom']) or isset($conf['order_by_inside_category_custom']) )
|
||||
{
|
||||
$order_by = array('');
|
||||
$template->assign('ORDER_BY_IS_CUSTOM', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$out = array();
|
||||
$order_by = trim($conf['order_by_inside_category']);
|
||||
$order_by = str_replace('ORDER BY ', false, $order_by);
|
||||
$order_by = explode(', ', $order_by);
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
'main',
|
||||
array(
|
||||
'CONF_GALLERY_TITLE' => htmlspecialchars($conf['gallery_title']),
|
||||
'CONF_PAGE_BANNER' => htmlspecialchars($conf['page_banner']),
|
||||
'week_starts_on_options' => array(
|
||||
'sunday' => $lang['day'][0],
|
||||
'monday' => $lang['day'][1],
|
||||
),
|
||||
'week_starts_on_options_selected' => $conf['week_starts_on'],
|
||||
'mail_theme' => $conf['mail_theme'],
|
||||
'mail_theme_options' => $mail_themes,
|
||||
'order_by' => $order_by,
|
||||
'order_by_options' => $sort_fields,
|
||||
'email_admin_on_new_user' => 'none' != $conf['email_admin_on_new_user'],
|
||||
'email_admin_on_new_user_filter' => in_array($conf['email_admin_on_new_user'], array('none', 'all')) ? 'all' : 'group',
|
||||
'email_admin_on_new_user_filter_group' => preg_match('/^group:(\d+)$/', $conf['email_admin_on_new_user'], $matches) ? $matches[1] : -1,
|
||||
)
|
||||
);
|
||||
|
||||
// list of groups
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
name
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
;';
|
||||
$groups = query2array($query, 'id', 'name');
|
||||
natcasesort($groups);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'group_options' => $groups,
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($main_checkboxes as $checkbox)
|
||||
{
|
||||
$template->append(
|
||||
'main',
|
||||
array(
|
||||
$checkbox => $conf[$checkbox]
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'comments' :
|
||||
{
|
||||
$template->assign(
|
||||
'comments',
|
||||
array(
|
||||
'NB_COMMENTS_PAGE'=>$conf['nb_comment_page'],
|
||||
'comments_order'=>$conf['comments_order'],
|
||||
'comments_order_options'=> $comments_order
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($comments_checkboxes as $checkbox)
|
||||
{
|
||||
$template->append(
|
||||
'comments',
|
||||
array(
|
||||
$checkbox => $conf[$checkbox]
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'default' :
|
||||
{
|
||||
$edit_user = build_user($conf['guest_id'], false);
|
||||
include_once(PHPWG_ROOT_PATH.'profile.php');
|
||||
|
||||
$errors = array();
|
||||
if (save_profile_from_post($edit_user, $errors))
|
||||
{
|
||||
// Reload user
|
||||
$edit_user = build_user($conf['guest_id'], false);
|
||||
$page['infos'][] = l10n('Information data registered in database');
|
||||
}
|
||||
$page['errors'] = array_merge($page['errors'], $errors);
|
||||
|
||||
load_profile_in_template(
|
||||
$action,
|
||||
'',
|
||||
$edit_user,
|
||||
'GUEST_'
|
||||
);
|
||||
$template->assign('default', array());
|
||||
break;
|
||||
}
|
||||
case 'display' :
|
||||
{
|
||||
foreach ($display_checkboxes as $checkbox)
|
||||
{
|
||||
$template->append(
|
||||
'display',
|
||||
array(
|
||||
$checkbox => $conf[$checkbox]
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
$template->append(
|
||||
'display',
|
||||
array(
|
||||
'picture_informations' => unserialize($conf['picture_informations']),
|
||||
'NB_CATEGORIES_PAGE' => $conf['nb_categories_page'],
|
||||
),
|
||||
true
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'sizes' :
|
||||
{
|
||||
// we only load the derivatives if it was not already loaded: it occurs
|
||||
// when submitting the form and an error remains
|
||||
if (!isset($page['sizes_loaded_in_tpl']))
|
||||
{
|
||||
$is_gd = (pwg_image::get_library()=='gd')? true : false;
|
||||
$template->assign('is_gd', $is_gd);
|
||||
$template->assign(
|
||||
'sizes',
|
||||
array(
|
||||
'original_resize_maxwidth' => $conf['original_resize_maxwidth'],
|
||||
'original_resize_maxheight' => $conf['original_resize_maxheight'],
|
||||
'original_resize_quality' => $conf['original_resize_quality'],
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($sizes_checkboxes as $checkbox)
|
||||
{
|
||||
$template->append(
|
||||
'sizes',
|
||||
array(
|
||||
$checkbox => $conf[$checkbox]
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// derivatives = multiple size
|
||||
$enabled = ImageStdParams::get_defined_type_map();
|
||||
$disabled = safe_unserialize(ImageStdParams::get_disabled_type_map());
|
||||
if ($disabled === false)
|
||||
{
|
||||
$disabled = array();
|
||||
}
|
||||
|
||||
$tpl_vars = array();
|
||||
foreach(ImageStdParams::get_all_types() as $type)
|
||||
{
|
||||
$tpl_var = array();
|
||||
|
||||
$tpl_var['must_square'] = ($type==IMG_SQUARE ? true : false);
|
||||
$tpl_var['must_enable'] = ($type==IMG_SQUARE || $type==IMG_THUMB || $type==$conf['derivative_default_size'])? true : false;
|
||||
|
||||
if ($params = @$enabled[$type])
|
||||
{
|
||||
$tpl_var['enabled'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tpl_var['enabled']=false;
|
||||
$params=@$disabled[$type];
|
||||
}
|
||||
|
||||
if ($params)
|
||||
{
|
||||
list($tpl_var['w'],$tpl_var['h']) = $params->sizing->ideal_size;
|
||||
if ( ($tpl_var['crop'] = round(100*$params->sizing->max_crop)) > 0)
|
||||
{
|
||||
list($tpl_var['minw'],$tpl_var['minh']) = $params->sizing->min_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tpl_var['minw'] = $tpl_var['minh'] = "";
|
||||
}
|
||||
$tpl_var['sharpen'] = $params->sharpen;
|
||||
}
|
||||
$tpl_vars[$type]=$tpl_var;
|
||||
}
|
||||
$template->assign('derivatives', $tpl_vars);
|
||||
$template->assign('resize_quality', ImageStdParams::$quality);
|
||||
|
||||
$tpl_vars = array();
|
||||
$now = time();
|
||||
foreach(ImageStdParams::$custom as $custom=>$time)
|
||||
{
|
||||
$tpl_vars[$custom] = ($now-$time<=24*3600) ? l10n('today') : time_since($time, 'day');
|
||||
}
|
||||
$template->assign('custom_derivatives', $tpl_vars);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'watermark' :
|
||||
{
|
||||
$watermark_files = array();
|
||||
foreach (glob(PHPWG_ROOT_PATH.'themes/default/watermarks/*.png') as $file)
|
||||
{
|
||||
$watermark_files[] = substr($file, strlen(PHPWG_ROOT_PATH));
|
||||
}
|
||||
if ( ($glob=glob(PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks/*.png')) !== false)
|
||||
{
|
||||
foreach ($glob as $file)
|
||||
{
|
||||
$watermark_files[] = substr($file, strlen(PHPWG_ROOT_PATH));
|
||||
}
|
||||
}
|
||||
$watermark_filemap = array( '' => '---' );
|
||||
foreach( $watermark_files as $file)
|
||||
{
|
||||
$display = basename($file);
|
||||
$watermark_filemap[$file] = $display;
|
||||
}
|
||||
$template->assign('watermark_files', $watermark_filemap);
|
||||
|
||||
if ($template->get_template_vars('watermark') === null)
|
||||
{
|
||||
$wm = ImageStdParams::get_watermark();
|
||||
|
||||
$position = 'custom';
|
||||
if ($wm->xpos == 0 and $wm->ypos == 0)
|
||||
{
|
||||
$position = 'topleft';
|
||||
}
|
||||
if ($wm->xpos == 100 and $wm->ypos == 0)
|
||||
{
|
||||
$position = 'topright';
|
||||
}
|
||||
if ($wm->xpos == 50 and $wm->ypos == 50)
|
||||
{
|
||||
$position = 'middle';
|
||||
}
|
||||
if ($wm->xpos == 0 and $wm->ypos == 100)
|
||||
{
|
||||
$position = 'bottomleft';
|
||||
}
|
||||
if ($wm->xpos == 100 and $wm->ypos == 100)
|
||||
{
|
||||
$position = 'bottomright';
|
||||
}
|
||||
|
||||
if ($wm->xrepeat != 0 || $wm->yrepeat != 0)
|
||||
{
|
||||
$position = 'custom';
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
'watermark',
|
||||
array(
|
||||
'file' => $wm->file,
|
||||
'minw' => $wm->min_size[0],
|
||||
'minh' => $wm->min_size[1],
|
||||
'xpos' => $wm->xpos,
|
||||
'ypos' => $wm->ypos,
|
||||
'xrepeat' => $wm->xrepeat,
|
||||
'yrepeat' => $wm->yrepeat,
|
||||
'opacity' => $wm->opacity,
|
||||
'position' => $position,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'search':
|
||||
{
|
||||
$template->assign(
|
||||
'search',
|
||||
array(
|
||||
'filters_views' => safe_unserialize($conf['filters_views']),
|
||||
'filters_names' => $filters_names_checkboxes,
|
||||
),
|
||||
);
|
||||
$template->assign('SHOW_FILTER_RATINGS', $conf['rate']);
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Configuration'));
|
||||
|
||||
//----------------------------------------------------------- sending html code
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'config');
|
||||
?>
|
||||
@@ -0,0 +1,234 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Change rank of images inside a category
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!isset($_GET['cat_id']) or !is_numeric($_GET['cat_id']))
|
||||
{
|
||||
trigger_error('missing cat_id param', E_USER_ERROR);
|
||||
}
|
||||
|
||||
$page['category_id'] = $_GET['cat_id'];
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | global mode form submission |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$image_order_choices = array('default', 'rank', 'user_define');
|
||||
$image_order_choice = 'default';
|
||||
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
if (isset($_POST['rank_of_image']))
|
||||
{
|
||||
asort($_POST['rank_of_image'], SORT_NUMERIC);
|
||||
|
||||
save_images_order(
|
||||
$page['category_id'],
|
||||
array_keys($_POST['rank_of_image'])
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($_POST['image_order_choice'])
|
||||
&& in_array($_POST['image_order_choice'], $image_order_choices))
|
||||
{
|
||||
$image_order_choice = $_POST['image_order_choice'];
|
||||
}
|
||||
|
||||
$message = l10n('Album updated successfully');
|
||||
|
||||
$image_order = null;
|
||||
if ($image_order_choice=='user_define')
|
||||
{
|
||||
for ($i=0; $i<3; $i++)
|
||||
{
|
||||
if (!empty($_POST['image_order'][$i]))
|
||||
{
|
||||
if (!empty($image_order)) $image_order.= ',';
|
||||
$image_order.= $_POST['image_order'][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($image_order_choice=='rank')
|
||||
{
|
||||
$image_order = '`rank` ASC';
|
||||
|
||||
$message = l10n('Images manual order was saved');
|
||||
}
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET image_order = '.(isset($image_order) ? '\''.$image_order.'\'' : 'NULL').'
|
||||
WHERE id='.$page['category_id'];
|
||||
pwg_query($query);
|
||||
|
||||
if (isset($_POST['image_order_subcats']))
|
||||
{
|
||||
$cat_info = get_cat_info($page['category_id']);
|
||||
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET image_order = '.(isset($image_order) ? '\''.$image_order.'\'' : 'NULL').'
|
||||
WHERE uppercats LIKE \''.$cat_info['uppercats'].',%\'';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => $message,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filenames(
|
||||
array('element_set_ranks' => 'element_set_ranks.tpl')
|
||||
);
|
||||
|
||||
$base_url = get_root_url().'admin.php';
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id = '.$page['category_id'].'
|
||||
;';
|
||||
$category = pwg_db_fetch_assoc(pwg_query($query));
|
||||
|
||||
if ($category['image_order']=='rank ASC' or $category['image_order']=='`rank` ASC')
|
||||
{
|
||||
$image_order_choice = 'rank';
|
||||
}
|
||||
elseif ($category['image_order']!='')
|
||||
{
|
||||
$image_order_choice = 'user_define';
|
||||
}
|
||||
|
||||
// Navigation path
|
||||
$navigation = get_cat_display_name_cache(
|
||||
$category['uppercats'],
|
||||
get_root_url().'admin.php?page=album-'
|
||||
);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'CATEGORIES_NAV' => preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$navigation)),
|
||||
'F_ACTION' => $base_url.get_query_string_diff(array()),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | thumbnails |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
file,
|
||||
path,
|
||||
representative_ext,
|
||||
width, height, rotation,
|
||||
name,
|
||||
`rank`
|
||||
FROM '.IMAGES_TABLE.'
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id
|
||||
WHERE category_id = '.$page['category_id'].'
|
||||
ORDER BY `rank`
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) > 0)
|
||||
{
|
||||
// template thumbnail initialization
|
||||
$current_rank = 1;
|
||||
$derivativeParams = ImageStdParams::get_by_type(IMG_SQUARE);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$derivative = new DerivativeImage($derivativeParams, new SrcImage($row));
|
||||
|
||||
if ( !empty( $row['name'] ) )
|
||||
{
|
||||
$thumbnail_name = $row['name'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$file_wo_ext = get_filename_wo_extension($row['file']);
|
||||
$thumbnail_name = str_replace('_', ' ', $file_wo_ext);
|
||||
}
|
||||
$current_rank++;
|
||||
$template->append(
|
||||
'thumbnails',
|
||||
array(
|
||||
'ID' => $row['id'],
|
||||
'NAME' => $thumbnail_name,
|
||||
'TN_SRC' => $derivative->get_url(),
|
||||
'RANK' => $current_rank * 10,
|
||||
'SIZE' => $derivative->get_size(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// image order management
|
||||
$sort_fields = array(
|
||||
'' => '',
|
||||
'file ASC' => l10n('File name, A → Z'),
|
||||
'file DESC' => l10n('File name, Z → A'),
|
||||
'name ASC' => l10n('Photo title, A → Z'),
|
||||
'name DESC' => l10n('Photo title, Z → A'),
|
||||
'date_creation DESC' => l10n('Date created, new → old'),
|
||||
'date_creation ASC' => l10n('Date created, old → new'),
|
||||
'date_available DESC' => l10n('Date posted, new → old'),
|
||||
'date_available ASC' => l10n('Date posted, old → new'),
|
||||
'rating_score DESC' => l10n('Rating score, high → low'),
|
||||
'rating_score ASC' => l10n('Rating score, low → high'),
|
||||
'hit DESC' => l10n('Visits, high → low'),
|
||||
'hit ASC' => l10n('Visits, low → high'),
|
||||
'id ASC' => l10n('Numeric identifier, 1 → 9'),
|
||||
'id DESC' => l10n('Numeric identifier, 9 → 1'),
|
||||
'rank ASC' => l10n('Manual sort order'),
|
||||
);
|
||||
|
||||
$template->assign('image_order_options', $sort_fields);
|
||||
|
||||
$image_order = explode(',', isset($category['image_order']) ? $category['image_order'] : "");
|
||||
|
||||
for ($i=0; $i<3; $i++) // 3 fields
|
||||
{
|
||||
if ( isset($image_order[$i]) )
|
||||
{
|
||||
$template->append('image_order', $image_order[$i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->append('image_order', '');
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign('image_order_choice', $image_order_choice);
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'element_set_ranks');
|
||||
?>
|
||||
@@ -0,0 +1,189 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Define replacement conditions for each template from template-extension
|
||||
* (template called "replacer").
|
||||
*
|
||||
* "original template" from ./template/yoga (or any other than yoga)
|
||||
* will be replaced by a "replacer" if the replacer is linked to this "original template"
|
||||
* (and optionally, when the requested URL contains an "optional URL keyword").
|
||||
*
|
||||
* "Optional URL keywords" are those you can find after the module name in URLs.
|
||||
*
|
||||
* Therefore "Optional URL keywords" can be an active "permalink"
|
||||
* (see permalinks in our documentation for further explanation).
|
||||
*/
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
$tpl_extension = isset($conf['extents_for_templates']) ?
|
||||
unserialize($conf['extents_for_templates']) : array();
|
||||
$new_extensions = get_extents();
|
||||
|
||||
/* Selective URLs keyword */
|
||||
$relevant_parameters = array(
|
||||
'----------',
|
||||
'category',
|
||||
'favorites',
|
||||
'most_visited',
|
||||
'best_rated',
|
||||
'recent_pics',
|
||||
'recent_cats',
|
||||
'created-monthly-calendar',
|
||||
'posted-monthly-calendar',
|
||||
'search',
|
||||
'flat',
|
||||
'list', /* <=> Random */
|
||||
'tags',
|
||||
);
|
||||
$query = '
|
||||
SELECT permalink
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE permalink IS NOT NULL
|
||||
';
|
||||
|
||||
/* Add active permalinks */
|
||||
$permalinks = array_from_query($query, 'permalink');
|
||||
$relevant_parameters = array_merge($relevant_parameters, $permalinks);
|
||||
|
||||
/* Link all supported templates to their respective handle */
|
||||
$eligible_templates = array(
|
||||
'----------' => 'N/A',
|
||||
'about.tpl' => 'about',
|
||||
'comments.tpl' => 'comments',
|
||||
'comment_list.tpl' => 'comment_list',
|
||||
'footer.tpl' => 'tail',
|
||||
'header.tpl' => 'header',
|
||||
'identification.tpl' => 'identification',
|
||||
'index.tpl' => 'index',
|
||||
'mainpage_categories.tpl' => 'index_category_thumbnails',
|
||||
'menubar.tpl' => 'menubar',
|
||||
'menubar_categories.tpl' => 'mbCategories',
|
||||
'menubar_identification.tpl' => 'mbIdentification',
|
||||
'menubar_links.tpl' => 'mbLinks',
|
||||
'menubar_menu.tpl' => 'mbMenu',
|
||||
'menubar_specials.tpl' => 'mbSpecials',
|
||||
'menubar_tags.tpl' => 'mbTags',
|
||||
'month_calendar.tpl' => 'month_calendar',
|
||||
'navigation_bar.tpl' => 'navbar',
|
||||
'nbm.tpl' => 'nbm',
|
||||
'notification.tpl' => 'notification',
|
||||
'password.tpl' => 'password',
|
||||
'picture.tpl' => 'picture',
|
||||
'picture_content.tpl' => 'default_content',
|
||||
'picture_nav_buttons.tpl' => 'picture_nav_buttons',
|
||||
'popuphelp.tpl' => 'popuphelp',
|
||||
'profile.tpl' => 'profile',
|
||||
'profile_content.tpl' => 'profile_content',
|
||||
'redirect.tpl' => 'redirect',
|
||||
'register.tpl' => 'register',
|
||||
'search.tpl' => 'search',
|
||||
'slideshow.tpl' => 'slideshow',
|
||||
'tags.tpl' => 'tags',
|
||||
'thumbnails.tpl' => 'index_thumbnails',
|
||||
);
|
||||
|
||||
$flip_templates = array_flip($eligible_templates);
|
||||
|
||||
$available_templates = array_merge(
|
||||
array('N/A' => '----------'),
|
||||
get_dirs(PHPWG_ROOT_PATH.'themes'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | selected templates |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
$replacements = array();
|
||||
$i = 0;
|
||||
while (isset($_POST['reptpl'][$i]))
|
||||
{
|
||||
$newtpl = $_POST['reptpl'][$i];
|
||||
$original = $_POST['original'][$i];
|
||||
$handle = $eligible_templates[$original];
|
||||
$url_keyword = $_POST['url'][$i];
|
||||
if ($url_keyword == '----------') $url_keyword = 'N/A';
|
||||
$bound_tpl = $_POST['bound'][$i];
|
||||
if ($bound_tpl == '----------') $bound_tpl = 'N/A';
|
||||
if ($handle != 'N/A')
|
||||
{
|
||||
$replacements[$newtpl] = array($handle, $url_keyword, $bound_tpl);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$conf['extents_for_templates'] = serialize($replacements);
|
||||
$tpl_extension = $replacements;
|
||||
/* ecrire la nouvelle conf */
|
||||
$query = '
|
||||
UPDATE '.CONFIG_TABLE.'
|
||||
SET value = \''. $conf['extents_for_templates'] .'\'
|
||||
WHERE param = \'extents_for_templates\';';
|
||||
if (pwg_query($query))
|
||||
{
|
||||
$page['infos'][] = l10n('Templates configuration has been recorded.');
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/* Clearing (remove old extents, add new ones) */
|
||||
foreach ($tpl_extension as $file => $conditions)
|
||||
{
|
||||
if ( !in_array($file,$new_extensions) ) unset($tpl_extension[$file]);
|
||||
else $new_extensions = array_diff($new_extensions,array($file));
|
||||
}
|
||||
foreach ($new_extensions as $file)
|
||||
{
|
||||
$tpl_extension[$file] = array('N/A', 'N/A', 'N/A');
|
||||
}
|
||||
|
||||
$template->set_filenames(array('extend_for_templates'
|
||||
=> 'extend_for_templates.tpl'));
|
||||
|
||||
$base_url = PHPWG_ROOT_PATH.'admin.php?page=extend_for_templates';
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=extend_for_templates',
|
||||
));
|
||||
ksort($tpl_extension);
|
||||
foreach ($tpl_extension as $file => $conditions)
|
||||
{
|
||||
$handle = $conditions[0];
|
||||
$url_keyword = $conditions[1];
|
||||
$bound_tpl = $conditions[2];
|
||||
{
|
||||
$template->append('extents',
|
||||
array(
|
||||
'replacer' => $file,
|
||||
'url_parameter' => $relevant_parameters,
|
||||
'original_tpl' => array_keys($eligible_templates),
|
||||
'bound_tpl' => $available_templates,
|
||||
'selected_tpl' => $flip_templates[$handle],
|
||||
'selected_url' => $url_keyword,
|
||||
'selected_bound' => $bound_tpl,)
|
||||
);
|
||||
}
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | html code display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Extend for templates'));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'extend_for_templates');
|
||||
?>
|
||||
@@ -0,0 +1,116 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('groups');
|
||||
$tabsheet->select('group_list');
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!empty($_POST) or isset($_GET['delete']) or isset($_GET['toggle_is_default']))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(array('group_list' => 'group_list.tpl'));
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ADD_ACTION' => get_root_url().'admin.php?page=group_list',
|
||||
// 'U_HELP' => get_root_url().'admin/popuphelp.php?page=group_list',
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('groups', 'users')),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | group list |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$query = '
|
||||
SELECT id, name, is_default
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
ORDER BY name ASC
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
$admin_url = get_root_url().'admin.php?page=';
|
||||
$perm_url = $admin_url.'group_perm&group_id=';
|
||||
$users_url = $admin_url.'user_list&group=';
|
||||
$del_url = $admin_url.'group_list&delete=';
|
||||
$toggle_is_default_url = $admin_url.'group_list&toggle_is_default=';
|
||||
|
||||
$group_counter = 0;
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$query = '
|
||||
SELECT u.'. $conf['user_fields']['username'].' AS username
|
||||
FROM '.USERS_TABLE.' AS u
|
||||
INNER JOIN '.USER_GROUP_TABLE.' AS ug
|
||||
ON u.'.$conf['user_fields']['id'].' = ug.user_id
|
||||
WHERE ug.group_id = '.$row['id'].'
|
||||
;';
|
||||
$members=array();
|
||||
$res=pwg_query($query);
|
||||
while ($us= pwg_db_fetch_assoc($res))
|
||||
{
|
||||
$members[]=$us['username'];
|
||||
}
|
||||
$template->append(
|
||||
'groups',
|
||||
array(
|
||||
'NAME' => $row['name'],
|
||||
'ID' => $row['id'],
|
||||
'IS_DEFAULT' => (get_boolean($row['is_default']) ? ' ['.l10n('default').']' : ''),
|
||||
'NB_MEMBERS' => count($members),
|
||||
'L_MEMBERS' => implode(' <span class="userSeparator">·</span> ', $members),
|
||||
'MEMBERS' => l10n_dec('%d member', '%d members', count($members)),
|
||||
'U_DELETE' => $del_url.$row['id'].'&pwg_token='.get_pwg_token(),
|
||||
'U_PERM' => $perm_url.$row['id'],
|
||||
'U_USERS' => $users_url.$row['id'],
|
||||
'U_ISDEFAULT' => $toggle_is_default_url.$row['id'].'&pwg_token='.get_pwg_token(),
|
||||
)
|
||||
);
|
||||
|
||||
$group_counter++;
|
||||
}
|
||||
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Groups').' <span class="badge-number">'.$group_counter.'</span>');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'group_list');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!empty($_POST))
|
||||
{
|
||||
check_pwg_token();
|
||||
check_input_parameter('cat_true', $_POST, true, PATTERN_ID);
|
||||
check_input_parameter('cat_false', $_POST, true, PATTERN_ID);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | variables init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!isset($_GET['group_id']))
|
||||
{
|
||||
fatal_error('group_id URL parameter is missing');
|
||||
}
|
||||
|
||||
check_input_parameter('group_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
$page['group'] = $_GET['group_id'];
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | updates |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_POST['falsify'])
|
||||
and isset($_POST['cat_true'])
|
||||
and count($_POST['cat_true']) > 0)
|
||||
{
|
||||
// if you forbid access to a category, all sub-categories become
|
||||
// automatically forbidden
|
||||
$subcats = get_subcat_ids($_POST['cat_true']);
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.GROUP_ACCESS_TABLE.'
|
||||
WHERE group_id = '.$page['group'].'
|
||||
AND cat_id IN ('.implode(',', $subcats).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
else if (isset($_POST['trueify'])
|
||||
and isset($_POST['cat_false'])
|
||||
and count($_POST['cat_false']) > 0)
|
||||
{
|
||||
$uppercats = get_uppercat_ids($_POST['cat_false']);
|
||||
$private_uppercats = array();
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $uppercats).')
|
||||
AND status = \'private\'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$private_uppercats[] = $row['id'];
|
||||
}
|
||||
|
||||
// retrying to authorize a category which is already authorized may cause
|
||||
// an error (in SQL statement), so we need to know which categories are
|
||||
// accesible
|
||||
$authorized_ids = array();
|
||||
|
||||
$query = '
|
||||
SELECT cat_id
|
||||
FROM '.GROUP_ACCESS_TABLE.'
|
||||
WHERE group_id = '.$page['group'].'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$authorized_ids[] = $row['cat_id'];
|
||||
}
|
||||
|
||||
$inserts = array();
|
||||
$to_autorize_ids = array_diff($private_uppercats, $authorized_ids);
|
||||
foreach ($to_autorize_ids as $to_autorize_id)
|
||||
{
|
||||
$inserts[] = array(
|
||||
'group_id' => $page['group'],
|
||||
'cat_id' => $to_autorize_id
|
||||
);
|
||||
}
|
||||
|
||||
mass_inserts(GROUP_ACCESS_TABLE, array('group_id','cat_id'), $inserts);
|
||||
invalidate_user_cache();
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(
|
||||
array(
|
||||
'group_perm' => 'group_perm.tpl',
|
||||
'double_select' => 'double_select.tpl'
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'TITLE' =>
|
||||
l10n(
|
||||
'Manage permissions for group "%s"',
|
||||
get_groupname($page['group'])
|
||||
),
|
||||
'L_CAT_OPTIONS_TRUE'=>l10n('Authorized'),
|
||||
'L_CAT_OPTIONS_FALSE'=>l10n('Forbidden'),
|
||||
|
||||
'F_ACTION' =>
|
||||
get_root_url().
|
||||
'admin.php?page=group_perm&group_id='.
|
||||
$page['group']
|
||||
)
|
||||
);
|
||||
|
||||
// only private categories are listed
|
||||
$query_true = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.' INNER JOIN '.GROUP_ACCESS_TABLE.' ON cat_id = id
|
||||
WHERE status = \'private\'
|
||||
AND group_id = '.$page['group'].'
|
||||
;';
|
||||
display_select_cat_wrapper($query_true,array(),'category_option_true');
|
||||
|
||||
$result = pwg_query($query_true);
|
||||
$authorized_ids = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$authorized_ids[] = $row['id'];
|
||||
}
|
||||
|
||||
$query_false = '
|
||||
SELECT id,name,uppercats,global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE status = \'private\'';
|
||||
if (count($authorized_ids) > 0)
|
||||
{
|
||||
$query_false.= '
|
||||
AND id NOT IN ('.implode(',', $authorized_ids).')';
|
||||
}
|
||||
$query_false.= '
|
||||
;';
|
||||
display_select_cat_wrapper($query_false,array(),'category_option_false');
|
||||
|
||||
$template->assign('PWG_TOKEN', get_pwg_token());
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | html code display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'group_perm');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
$help_link = get_root_url().'admin.php?page=help§ion=';
|
||||
$selected = null;
|
||||
|
||||
if (!isset($_GET['section']))
|
||||
{
|
||||
$selected = 'add_photos';
|
||||
}
|
||||
else
|
||||
{
|
||||
$selected = $_GET['section'];
|
||||
}
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('help');
|
||||
$tabsheet->select($selected);
|
||||
$tabsheet->assign();
|
||||
|
||||
trigger_notify('loc_end_help');
|
||||
|
||||
$template->set_filenames(array('help' => 'help.tpl'));
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'HELP_CONTENT' => load_language(
|
||||
'help/help_'.$tabsheet->selected.'.html',
|
||||
'',
|
||||
array('return'=>true)
|
||||
),
|
||||
'HELP_SECTION_TITLE' => $tabsheet->sheets[ $tabsheet->selected ]['caption'],
|
||||
)
|
||||
);
|
||||
|
||||
$language_prefix = substr($user['language'], 0, 3);
|
||||
if ('en_' == $language_prefix)
|
||||
{
|
||||
$page['messages'][] = sprintf(
|
||||
'Need help to use Piwigo? <a href="%s" target="_blank">Check the online documentation</a> !',
|
||||
'https://doc.piwigo.org/'
|
||||
);
|
||||
}
|
||||
elseif ('fr_' == $language_prefix)
|
||||
{
|
||||
$page['messages'][] = sprintf(
|
||||
'Besoin d\'aide pour utiliser Piwigo ? Consultez la <a href="%s" target="_blank">documentation en ligne</a> !',
|
||||
'https://doc-fr.piwigo.org/'
|
||||
);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'help');
|
||||
?>
|
||||
@@ -0,0 +1,150 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Display filtered history lines
|
||||
*/
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | functions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_history.inc.php');
|
||||
|
||||
$types = array_merge(array('none'), get_enums(HISTORY_TABLE, 'image_type'));
|
||||
|
||||
$display_thumbnails = array('no_display_thumbnail' => l10n('No display'),
|
||||
'display_thumbnail_classic' => l10n('Classic display'),
|
||||
'display_thumbnail_hoverbox' => l10n('Hoverbox display')
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('filter_ip', $_GET, false, '/^[0-9.]+$/');
|
||||
check_input_parameter('filter_image_id', $_GET, false, '/^\d+$/');
|
||||
check_input_parameter('filter_user_id', $_GET, false, '/^\d+$/');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filename('history', 'history.tpl');
|
||||
|
||||
// TabSheet initialization
|
||||
history_tabsheet();
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ACTION' => get_root_url().'admin.php?page=history',
|
||||
'API_METHOD' => 'ws.php?format=json&method=pwg.history.search'
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | navigation bar |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($page['search_id']))
|
||||
{
|
||||
$navbar = create_navigation_bar(
|
||||
get_root_url().'admin.php'.get_query_string_diff(array('start')),
|
||||
$page['nb_lines'],
|
||||
$page['start'],
|
||||
$conf['nb_logs_page']
|
||||
);
|
||||
|
||||
$template->assign('navbar', $navbar);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | filter form |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$form = array();
|
||||
|
||||
if (isset($page['search']))
|
||||
{
|
||||
if (isset($page['search']['fields']['date-after']))
|
||||
{
|
||||
$form['start'] = $page['search']['fields']['date-after'];
|
||||
}
|
||||
|
||||
if (isset($page['search']['fields']['date-before']))
|
||||
{
|
||||
$form['end'] = $page['search']['fields']['date-before'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// by default, at page load, we want the selected date to be the current
|
||||
// date
|
||||
$form['start'] = $form['end'] = date('Y-m-d');
|
||||
$form['types'] = $types;
|
||||
// Hoverbox by default
|
||||
$form['display_thumbnail'] =
|
||||
pwg_get_cookie_var('display_thumbnail', 'no_display_thumbnail');
|
||||
}
|
||||
|
||||
$form_param['ip'] = isset($_GET['filter_ip']) ? $_GET['filter_ip'] : @$form['ip'];
|
||||
$form_param['image_id'] = isset($_GET['filter_image_id']) ? $_GET['filter_image_id'] : @$form['image_id'];
|
||||
$form_param['user_id'] = isset($_GET['filter_user_id']) ? $_GET['filter_user_id'] : "-1";
|
||||
|
||||
if (isset($_GET['filter_ip']) or isset($_GET['filter_image_id']) or isset($_GET['filter_user_id']))
|
||||
{
|
||||
$form['start'] = '';
|
||||
}
|
||||
|
||||
if ($form_param['user_id'] != "-1") {
|
||||
$query = '
|
||||
SELECT
|
||||
username
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE id = '.$form_param['user_id'].'
|
||||
;';
|
||||
|
||||
list($form_param['user_name']) = pwg_db_fetch_row(pwg_query($query));
|
||||
$form_param['user_id'] = empty(pwg_db_fetch_row(pwg_query($query))) ? "-1" : $form_param['user_id'];
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'USER_ID' => $form_param['user_id'],
|
||||
'USER_NAME' => @$form_param['user_name'],
|
||||
'IMAGE_ID' => $form_param['image_id'],
|
||||
'FILENAME' => @$form['filename'],
|
||||
'IP' => $form_param['ip'],
|
||||
'START' => @$form['start'],
|
||||
'END' => @$form['end'],
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign('display_thumbnails', $display_thumbnails);
|
||||
$template->assign('display_thumbnail_selected', $form['display_thumbnail']);
|
||||
$template->assign('guest_id', $conf['guest_id']);
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('History'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | html code display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'history');
|
||||
?>
|
||||
@@ -0,0 +1,197 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
add_event_handler('tabsheet_before_select', 'add_core_tabs', 0);
|
||||
|
||||
function add_core_tabs($sheets, $tab_id)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
switch($tab_id)
|
||||
{
|
||||
case 'admin_home':
|
||||
$sheets[''] = array('caption' => l10n('Administration Home'), 'url' => 'admin.php');
|
||||
break;
|
||||
|
||||
case 'tags':
|
||||
global $my_base_url;
|
||||
$sheets[''] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'tags');
|
||||
break;
|
||||
|
||||
case 'album':
|
||||
global $admin_album_base_url;
|
||||
$sheets['properties'] = array('caption' => '<span class="icon-pencil"></span>'.l10n('Properties'), 'url' => $admin_album_base_url.'-properties');
|
||||
$sheets['sort_order'] = array('caption' => '<span class="icon-shuffle"></span>'.l10n('Manage photo ranks'), 'url' => $admin_album_base_url.'-sort_order');
|
||||
$sheets['permissions'] = array('caption' => '<span class="icon-lock"></span>'.l10n('Permissions'), 'url' => $admin_album_base_url.'-permissions');
|
||||
$sheets['notification'] = array('caption' => '<span class="icon-mail-alt"></span>'.l10n('Notification'), 'url' => $admin_album_base_url.'-notification');
|
||||
break;
|
||||
|
||||
case 'albums':
|
||||
global $my_base_url;
|
||||
$sheets['list'] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'albums');
|
||||
$sheets['permalinks'] = array('caption' => '<span class="icon-link-1"></span>'.l10n('Permalinks'), 'url' => $my_base_url.'permalinks');
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
global $my_base_url;
|
||||
$sheets['user_list'] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'user_list');
|
||||
$sheets['user_activity'] = array('caption' => '<span class="icon-pulse"></span>'.l10n('Activity'), 'url' => $my_base_url.'user_activity');
|
||||
break;
|
||||
|
||||
case 'batch_manager':
|
||||
global $manager_link;
|
||||
$sheets['global'] = array('caption' => '<span class="icon-th"></span>'.l10n('global mode'), 'url' => $manager_link.'global');
|
||||
$sheets['unit'] = array('caption' => '<span class="icon-th-list"></span>'.l10n('unit mode'), 'url' => $manager_link.'unit');
|
||||
break;
|
||||
|
||||
case 'cat_options':
|
||||
global $link_start;
|
||||
$sheets['status'] = array('caption' => '<span class="icon-lock"></span>'.l10n('Public / Private'), 'url' => $link_start.'cat_options&section=status');
|
||||
$sheets['visible'] = array('caption' => '<span class="icon-block"></span>'.l10n('Lock'), 'url' => $link_start.'cat_options&section=visible');
|
||||
if ($conf['activate_comments'])
|
||||
$sheets['comments'] = array('caption' => '<span class="icon-chat"></span>'.l10n('Comments'), 'url' => $link_start.'cat_options&section=comments');
|
||||
if ($conf['allow_random_representative'])
|
||||
$sheets['representative'] = array('caption' => l10n('Representative'), 'url' => $link_start.'cat_options&section=representative');
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
global $my_base_url;
|
||||
$sheets[''] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'comments');
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
global $my_base_url;
|
||||
$sheets[''] = array('caption' => '<span class="icon-users"> </span>'.l10n('User list'), 'url' => $my_base_url.'user_list');
|
||||
break;
|
||||
|
||||
case 'groups':
|
||||
global $my_base_url;
|
||||
$sheets[''] = array('caption' => '<span class="icon-menu"> </span>'.l10n('List'), 'url' => $my_base_url.'group_list');
|
||||
break;
|
||||
|
||||
case 'configuration':
|
||||
global $conf_link;
|
||||
$sheets['main'] = array('caption' => '<span class="icon-cog"></span>'.l10n('General'), 'url' => $conf_link.'main');
|
||||
$sheets['sizes'] = array('caption' => '<span class="icon-zoom-square"></span>'.l10n('Photo sizes'), 'url' => $conf_link.'sizes');
|
||||
$sheets['watermark'] = array('caption' => '<span class="icon-file-image"></span>'.l10n('Watermark'), 'url' => $conf_link.'watermark');
|
||||
$sheets['display'] = array('caption' => '<span class="icon-television"></span>'.l10n('Display'), 'url' => $conf_link.'display');
|
||||
$sheets['comments'] = array('caption' => '<span class="icon-chat"></span>'.l10n('Comments'), 'url' => $conf_link.'comments');
|
||||
$sheets['search'] = array('caption' => '<span class="icon-search"></span>'.l10n('Search'), 'url' => $conf_link.'search');
|
||||
// $sheets['default'] = array('caption' => l10n('Guest Settings'), 'url' => $conf_link.'default');
|
||||
break;
|
||||
|
||||
case 'help':
|
||||
global $help_link;
|
||||
$sheets['add_photos'] = array('caption' => l10n('Add Photos'), 'url' => $help_link.'add_photos');
|
||||
$sheets['permissions'] = array('caption' => l10n('Permissions'), 'url' => $help_link.'permissions');
|
||||
$sheets['groups'] = array('caption' => l10n('Groups'), 'url' => $help_link.'groups');
|
||||
$sheets['virtual_links'] = array('caption' => l10n('Virtual Links'), 'url' => $help_link.'virtual_links');
|
||||
$sheets['misc'] = array('caption' => l10n('Miscellaneous'), 'url' => $help_link.'misc');
|
||||
break;
|
||||
|
||||
case 'history':
|
||||
global $link_start;
|
||||
$sheets['stats'] = array('caption' => '<span class="icon-signal"></span>'.l10n('Statistics'), 'url' => $link_start.'stats');
|
||||
$sheets['history'] = array('caption' => '<span class="icon-search"></span>'.l10n('Search'), 'url' => $link_start.'history');
|
||||
break;
|
||||
|
||||
case 'languages':
|
||||
global $my_base_url;
|
||||
$sheets['installed'] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'&tab=installed');
|
||||
if ($conf['enable_extensions_install'])
|
||||
{
|
||||
$sheets['update'] = array('caption' => '<span class="icon-arrows-cw"></span>'.l10n('Check for updates'), 'url' => $my_base_url.'&tab=update');
|
||||
$sheets['new'] = array('caption' => '<span class="icon-plus-circled"></span>'.l10n('Add New Language'), 'url' => $my_base_url.'&tab=new');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'menus':
|
||||
global $my_base_url;
|
||||
$sheets[''] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'menubar');
|
||||
break;
|
||||
|
||||
case 'nbm':
|
||||
global $base_url;
|
||||
$sheets['param'] = array('caption' => l10n('Parameter'), 'url' => $base_url.'?page=notification_by_mail&mode=param');
|
||||
$sheets['subscribe'] = array('caption' => l10n('Subscribe'), 'url' => $base_url.'?page=notification_by_mail&mode=subscribe');
|
||||
$sheets['send'] = array('caption' => l10n('Send'), 'url' => $base_url.'?page=notification_by_mail&mode=send');
|
||||
break;
|
||||
|
||||
case 'photo':
|
||||
global $admin_photo_base_url, $conf;
|
||||
$sheets['properties'] = array('caption' => '<span class="icon-file-image"></span>'.l10n('Properties'), 'url' => $admin_photo_base_url.'-properties');
|
||||
$sheets['coi'] = array('caption' => '<span class="icon-crop"></span>'.l10n('Center of interest'), 'url' => $admin_photo_base_url.'-coi');
|
||||
if ($conf['enable_formats'])
|
||||
{
|
||||
$sheets['formats'] = array('caption' => '<span class="icon-docs"></span>'.l10n('Formats'), 'url' => $admin_photo_base_url.'-formats');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'photos_add':
|
||||
$sheets['direct'] = array('caption' => '<span class="icon-upload"></span>'.l10n('Web Form'), 'url' => PHOTOS_ADD_BASE_URL.'&section=direct');
|
||||
$sheets['applications'] = array('caption' => '<span class="icon-network"></span>'.l10n('Applications'), 'url' => PHOTOS_ADD_BASE_URL.'&section=applications');
|
||||
if ($conf['enable_synchronization'])
|
||||
$sheets['ftp'] = array('caption' => '<span class="icon-exchange"></span>'.l10n('FTP + Synchronization'), 'url' => PHOTOS_ADD_BASE_URL.'&section=ftp');
|
||||
break;
|
||||
|
||||
case 'plugins':
|
||||
global $my_base_url;
|
||||
$sheets['installed'] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'&tab=installed');
|
||||
if ($conf['enable_extensions_install'])
|
||||
{
|
||||
$sheets['update'] = array('caption' => '<span class="icon-arrows-cw"></span>'.l10n('Check for updates'), 'url' => $my_base_url.'&tab=update');
|
||||
$sheets['new'] = array('caption' => '<span class="icon-plus-circled"></span>'.l10n('Add New Plugin'), 'url' => $my_base_url.'&tab=new');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'rating':
|
||||
$sheets['rating'] = array('caption' => l10n('Photos'), 'url' => get_root_url().'admin.php?page=rating');
|
||||
$sheets['rating_user'] = array('caption' => l10n('Users'), 'url' => get_root_url().'admin.php?page=rating_user');
|
||||
break;
|
||||
|
||||
case 'themes':
|
||||
global $my_base_url;
|
||||
$sheets['installed'] = array('caption' => '<span class="icon-menu"></span>'.l10n('List'), 'url' => $my_base_url.'&tab=installed');
|
||||
if ($conf['enable_extensions_install'])
|
||||
{
|
||||
$sheets['update'] = array('caption' => '<span class="icon-arrows-cw"></span>'.l10n('Check for updates'), 'url' => $my_base_url.'&tab=update');
|
||||
$sheets['new'] = array('caption' => '<span class="icon-plus-circled"></span>'.l10n('Add New Theme'), 'url' => $my_base_url.'&tab=new');
|
||||
}
|
||||
$sheets['standard_pages'] = array('caption' => '<span class="icon-cog-alt"></span>'.l10n('Standard pages'), 'url' => $my_base_url.'&tab=standard_pages');
|
||||
break;
|
||||
|
||||
case 'updates':
|
||||
global $my_base_url;
|
||||
|
||||
if ($conf['enable_core_update'])
|
||||
{
|
||||
$sheets['pwg'] = array('caption' => l10n('Piwigo core'), 'url' => $my_base_url);
|
||||
}
|
||||
|
||||
if ($conf['enable_extensions_install'])
|
||||
{
|
||||
$sheets['ext'] = array('caption' => l10n('Extensions'), 'url' => $my_base_url.'&tab=ext');
|
||||
}
|
||||
break;
|
||||
case 'site_update':
|
||||
global $my_base_url;
|
||||
$sheets['synchronization'] = array('caption' => '<span class="icon-exchange"></span>'.l10n('Synchronization'), 'url' => $my_base_url.'site_update&site=1');
|
||||
$sheets['site_maager'] = array('caption' => '<span class="icon-flow-branch"></span>'.l10n('Site manager'), 'url' => $my_base_url.'site_manager');
|
||||
break;
|
||||
case 'maintenance':
|
||||
global $my_base_url;
|
||||
$sheets['actions'] = array('caption' => '<span class="icon-tools"></span>'.l10n('Actions'), 'url' => $my_base_url.'maintenance&tab=actions');
|
||||
$sheets['env'] = array('caption' => '<span class="icon-television"></span>'.l10n('Environment'), 'url' => $my_base_url.'maintenance&tab=env');
|
||||
$sheets['sys'] = array('caption' => '<span class="icon-pulse"></span>'.l10n('System Activities'), 'url' => $my_base_url.'maintenance&tab=sys');
|
||||
break;
|
||||
}
|
||||
|
||||
return $sheets;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('albums');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
|
||||
list($nb_cats) = pwg_db_fetch_row(pwg_query($query));
|
||||
$template->assign(
|
||||
array(
|
||||
'nb_cats' => $nb_cats,
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
$prefilters = array(
|
||||
array('ID' => 'caddie', 'NAME' => l10n('Caddie')),
|
||||
array('ID' => 'favorites', 'NAME' => l10n('Your favorites')),
|
||||
array('ID' => 'last_import', 'NAME' => l10n('Last import')),
|
||||
array('ID' => 'no_album', 'NAME' => l10n('With no album') . ' (' . l10n('Orphans') . ')'),
|
||||
array('ID' => 'no_tag', 'NAME' => l10n('With no tag')),
|
||||
array('ID' => 'duplicates', 'NAME' => l10n('Duplicates')),
|
||||
array('ID' => 'all_photos', 'NAME' => l10n('All'))
|
||||
);
|
||||
|
||||
if ($conf['enable_synchronization'])
|
||||
{
|
||||
$prefilters[] = array('ID' => 'no_virtual_album', 'NAME' => l10n('With no virtual album'));
|
||||
$prefilters[] = array('ID' => 'no_sync_md5sum', 'NAME' => l10n('With no checksum'));
|
||||
}
|
||||
|
||||
function UC_name_compare($a, $b)
|
||||
{
|
||||
return strcmp(strtolower($a['NAME']), strtolower($b['NAME']));
|
||||
}
|
||||
|
||||
$prefilters = trigger_change('get_batch_manager_prefilters', $prefilters);
|
||||
|
||||
// Sort prefilters by localized name.
|
||||
usort($prefilters, function ($a, $b) {
|
||||
return strcmp(strtolower($a['NAME']), strtolower($b['NAME']));
|
||||
});
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'conf_checksum_compute_blocksize' => $conf['checksum_compute_blocksize'],
|
||||
'prefilters' => $prefilters,
|
||||
'filter' => $_SESSION['bulk_manager_filter'],
|
||||
'selection' => $collection,
|
||||
'all_elements' => $page['cat_elements_id'],
|
||||
'START' => $page['start'],
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'U_DISPLAY' => $base_url . get_query_string_diff(array('display')),
|
||||
'F_ACTION' => $base_url . get_query_string_diff(array('cat', 'start', 'tag', 'filter')),
|
||||
'ADMIN_PAGE_TITLE' => l10n('Batch Manager'),
|
||||
)
|
||||
);
|
||||
|
||||
if (isset($page['no_md5sum_number']))
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'NB_NO_MD5SUM' => $page['no_md5sum_number'],
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$template->assign('NB_NO_MD5SUM', '');
|
||||
}
|
||||
|
||||
// privacy level
|
||||
foreach ($conf['available_permission_levels'] as $level)
|
||||
{
|
||||
$level_options[$level] = l10n(sprintf('Level %d', $level));
|
||||
|
||||
if (0 == $level) {
|
||||
$level_options[$level] = l10n('Everybody');
|
||||
}
|
||||
}
|
||||
$template->assign(
|
||||
array(
|
||||
'filter_level_options' => $level_options,
|
||||
'filter_level_options_selected' => isset($_SESSION['bulk_manager_filter']['level'])
|
||||
? $_SESSION['bulk_manager_filter']['level']
|
||||
: 0,
|
||||
)
|
||||
);
|
||||
|
||||
// tags
|
||||
$filter_tags = array();
|
||||
|
||||
if (!empty($_SESSION['bulk_manager_filter']['tags']))
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
name
|
||||
FROM ' . TAGS_TABLE . '
|
||||
WHERE id IN (' . implode(',', $_SESSION['bulk_manager_filter']['tags']) . ')
|
||||
;';
|
||||
|
||||
$filter_tags = get_taglist($query);
|
||||
}
|
||||
|
||||
$template->assign('filter_tags', $filter_tags);
|
||||
|
||||
// in the filter box, which category to select by default
|
||||
$selected_category = null;
|
||||
$selected_category_name = '';
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['category']))
|
||||
{
|
||||
$selected_category = intval($_SESSION['bulk_manager_filter']['category']);
|
||||
$selected_category_name = get_cat_display_name_from_id($selected_category);
|
||||
}
|
||||
|
||||
$template->assign('filter_category_selected_name', strip_tags($selected_category_name));
|
||||
$template->assign('filter_category_selected', $selected_category);
|
||||
|
||||
// Dissociate from a category : categories listed for dissociation can only
|
||||
// represent virtual links. We can't create orphans. Links to physical
|
||||
// categories can't be broken.
|
||||
$associated_categories = array();
|
||||
|
||||
if (count($page['cat_elements_id']) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
DISTINCT(category_id) AS id
|
||||
FROM ' . IMAGE_CATEGORY_TABLE . ' AS ic
|
||||
JOIN ' . IMAGES_TABLE . ' AS i ON i.id = ic.image_id
|
||||
WHERE ic.image_id IN (' . implode(',', $page['cat_elements_id']) . ')
|
||||
AND (
|
||||
ic.category_id != i.storage_category_id
|
||||
OR i.storage_category_id IS NULL
|
||||
)
|
||||
;';
|
||||
|
||||
$associated_categories = query2array($query, 'id', 'id');
|
||||
}
|
||||
|
||||
$template->assign('associated_categories', $associated_categories);
|
||||
|
||||
load_language('help_quick_search.lang');
|
||||
@@ -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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class c13y_internal
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
add_event_handler('list_check_integrity', array(&$this, 'c13y_version'));
|
||||
add_event_handler('list_check_integrity', array(&$this, 'c13y_exif'));
|
||||
add_event_handler('list_check_integrity', array(&$this, 'c13y_user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check version
|
||||
*
|
||||
* @param c13y object
|
||||
* @return void
|
||||
*/
|
||||
function c13y_version($c13y)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$check_list = array();
|
||||
|
||||
$check_list[] = array(
|
||||
'type' => 'PHP',
|
||||
'current' => phpversion(),
|
||||
'required' => REQUIRED_PHP_VERSION,
|
||||
);
|
||||
|
||||
$check_list[] = array(
|
||||
'type' => 'MySQL',
|
||||
'current' => pwg_get_db_version(),
|
||||
'required' => REQUIRED_MYSQL_VERSION,
|
||||
);
|
||||
|
||||
foreach ($check_list as $elem)
|
||||
{
|
||||
if (version_compare($elem['current'], $elem['required'], '<'))
|
||||
{
|
||||
$c13y->add_anomaly(
|
||||
sprintf(l10n('The version of %s [%s] installed is not compatible with the version required [%s]'), $elem['type'], $elem['current'], $elem['required']),
|
||||
null,
|
||||
null,
|
||||
l10n('You need to upgrade your system to take full advantage of the application else the application will not work correctly, or not at all')
|
||||
.'<br>'.
|
||||
$c13y->get_htlm_links_more_info());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check exif
|
||||
*
|
||||
* @param c13y object
|
||||
* @return void
|
||||
*/
|
||||
function c13y_exif($c13y)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
foreach (array('show_exif', 'use_exif') as $value)
|
||||
{
|
||||
if (($conf[$value]) and (!function_exists('exif_read_data')))
|
||||
{
|
||||
$c13y->add_anomaly(
|
||||
sprintf(l10n('%s value is not correct file because exif are not supported'), '$conf[\''.$value.'\']'),
|
||||
null,
|
||||
null,
|
||||
sprintf(l10n('%s must be to set to false in your local/config/config.inc.php file'), '$conf[\''.$value.'\']')
|
||||
.'<br>'.
|
||||
$c13y->get_htlm_links_more_info());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user
|
||||
*
|
||||
* @param c13y object
|
||||
* @return void
|
||||
*/
|
||||
function c13y_user($c13y)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$c13y_users = array();
|
||||
$c13y_users[$conf['guest_id']] = array(
|
||||
'status' => 'guest',
|
||||
'l10n_non_existent' => 'Main "guest" user does not exist',
|
||||
'l10n_bad_status' => 'Main "guest" user status is incorrect');
|
||||
|
||||
if ($conf['guest_id'] != $conf['default_user_id'])
|
||||
{
|
||||
$c13y_users[$conf['default_user_id']] = array(
|
||||
'password' => null,
|
||||
'l10n_non_existent' => 'Default user does not exist');
|
||||
}
|
||||
|
||||
$c13y_users[$conf['webmaster_id']] = array(
|
||||
'status' => 'webmaster',
|
||||
'l10n_non_existent' => 'Main "webmaster" user does not exist',
|
||||
'l10n_bad_status' => 'Main "webmaster" user status is incorrect');
|
||||
|
||||
$query = '
|
||||
select u.'.$conf['user_fields']['id'].' as id, ui.status
|
||||
from '.USERS_TABLE.' as u
|
||||
left join '.USER_INFOS_TABLE.' as ui
|
||||
on u.'.$conf['user_fields']['id'].' = ui.user_id
|
||||
where
|
||||
u.'.$conf['user_fields']['id'].' in ('.implode(',', array_keys($c13y_users)).')
|
||||
;';
|
||||
|
||||
|
||||
$status = array();
|
||||
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$status[$row['id']] = $row['status'];
|
||||
}
|
||||
|
||||
foreach ($c13y_users as $id => $data)
|
||||
{
|
||||
if (!array_key_exists($id, $status))
|
||||
{
|
||||
$c13y->add_anomaly(l10n($data['l10n_non_existent']), 'c13y_correction_user',
|
||||
array('id' => $id, 'action' => 'creation'));
|
||||
}
|
||||
else
|
||||
if (!empty($data['status']) and $status[$id] != $data['status'])
|
||||
{
|
||||
$c13y->add_anomaly(l10n($data['l10n_bad_status']), 'c13y_correction_user',
|
||||
array('id' => $id, 'action' => 'status'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do correction user
|
||||
*
|
||||
* @param user_id, action
|
||||
* @return boolean true if ok else false
|
||||
*/
|
||||
function c13y_correction_user($id, $action)
|
||||
{
|
||||
global $conf, $page;
|
||||
|
||||
$result = false;
|
||||
|
||||
if (!empty($id))
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
case 'creation':
|
||||
if ($id == $conf['guest_id'])
|
||||
{
|
||||
$name = 'guest';
|
||||
$password = null;
|
||||
}
|
||||
else if ($id == $conf['default_user_id'])
|
||||
{
|
||||
$name = 'guest';
|
||||
$password = null;
|
||||
}
|
||||
else if ($id == $conf['webmaster_id'])
|
||||
{
|
||||
$name = 'webmaster';
|
||||
$password = generate_key(6);
|
||||
}
|
||||
|
||||
if (isset($name))
|
||||
{
|
||||
$name_ok = false;
|
||||
while (!$name_ok)
|
||||
{
|
||||
$name_ok = (get_userid($name) === false);
|
||||
if (!$name_ok)
|
||||
{
|
||||
$name .= generate_key(1);
|
||||
}
|
||||
}
|
||||
|
||||
$inserts = array(
|
||||
array(
|
||||
'id' => $id,
|
||||
'username' => addslashes($name),
|
||||
'password' => $password
|
||||
),
|
||||
);
|
||||
mass_inserts(USERS_TABLE, array_keys($inserts[0]), $inserts);
|
||||
|
||||
create_user_infos($id);
|
||||
|
||||
$page['infos'][] = sprintf(l10n('User "%s" created with "%s" like password'), $name, $password);
|
||||
|
||||
$result = true;
|
||||
}
|
||||
break;
|
||||
case 'status':
|
||||
if ($id == $conf['guest_id'])
|
||||
{
|
||||
$status = 'guest';
|
||||
}
|
||||
else if ($id == $conf['default_user_id'])
|
||||
{
|
||||
$status = 'guest';
|
||||
}
|
||||
else if ($id == $conf['webmaster_id'])
|
||||
{
|
||||
$status = 'webmaster';
|
||||
}
|
||||
|
||||
if (isset($status))
|
||||
{
|
||||
$updates = array(
|
||||
array(
|
||||
'user_id' => $id,
|
||||
'status' => $status
|
||||
),
|
||||
);
|
||||
mass_updates(USER_INFOS_TABLE,
|
||||
array('primary' => array('user_id'),'update' => array('status')),
|
||||
$updates);
|
||||
|
||||
$page['infos'][] = sprintf(l10n('Status of user "%s" updated'), get_username($id));
|
||||
|
||||
$result = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,331 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class check_integrity
|
||||
{
|
||||
var $ignore_list;
|
||||
var $retrieve_list;
|
||||
var $build_ignore_list;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->ignore_list = array();
|
||||
$this->retrieve_list = array();
|
||||
$this->build_ignore_list = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check integrities
|
||||
*
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
function check()
|
||||
{
|
||||
global $page, $header_notes, $conf;
|
||||
|
||||
// Ignore list
|
||||
$conf_c13y_ignore = unserialize($conf['c13y_ignore']);
|
||||
if (
|
||||
is_array($conf_c13y_ignore) and
|
||||
isset($conf_c13y_ignore['version']) and
|
||||
($conf_c13y_ignore['version'] == PHPWG_VERSION) and
|
||||
is_array($conf_c13y_ignore['list'])
|
||||
)
|
||||
{
|
||||
$ignore_list_changed = false;
|
||||
$this->ignore_list = $conf_c13y_ignore['list'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$ignore_list_changed = true;
|
||||
$this->ignore_list = array();
|
||||
}
|
||||
|
||||
// Retrieve list
|
||||
$this->retrieve_list = array();
|
||||
$this->build_ignore_list = array();
|
||||
|
||||
trigger_notify('list_check_integrity', $this);
|
||||
|
||||
// Information
|
||||
if (count($this->retrieve_list) > 0)
|
||||
{
|
||||
$header_notes[] = l10n_dec(
|
||||
'%d anomaly has been detected.', '%d anomalies have been detected.',
|
||||
count($this->retrieve_list)
|
||||
);
|
||||
}
|
||||
|
||||
// Treatments
|
||||
if (isset($_POST['c13y_submit_correction']) and isset($_POST['c13y_selection']))
|
||||
{
|
||||
$corrected_count = 0;
|
||||
$not_corrected_count = 0;
|
||||
|
||||
foreach ($this->retrieve_list as $i => $c13y)
|
||||
{
|
||||
if (!empty($c13y['correction_fct']) and
|
||||
$c13y['is_callable'] and
|
||||
in_array($c13y['id'], $_POST['c13y_selection']))
|
||||
{
|
||||
if (is_array($c13y['correction_fct_args']))
|
||||
{
|
||||
$args = $c13y['correction_fct_args'];
|
||||
}
|
||||
else
|
||||
if (!is_null($c13y['correction_fct_args']))
|
||||
{
|
||||
$args = array($c13y['correction_fct_args']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$args = array();
|
||||
}
|
||||
$this->retrieve_list[$i]['corrected'] = call_user_func_array($c13y['correction_fct'], $args);
|
||||
|
||||
if ($this->retrieve_list[$i]['corrected'])
|
||||
{
|
||||
$corrected_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$not_corrected_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($corrected_count > 0)
|
||||
{
|
||||
$page['infos'][] = l10n_dec(
|
||||
'%d anomaly has been corrected.', '%d anomalies have been detected corrected.',
|
||||
$corrected_count
|
||||
);
|
||||
}
|
||||
if ($not_corrected_count > 0)
|
||||
{
|
||||
$page['errors'][] = l10n_dec(
|
||||
'%d anomaly has not been corrected.', '%d anomalies have not been corrected.',
|
||||
$not_corrected_count
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($_POST['c13y_submit_ignore']) and isset($_POST['c13y_selection']))
|
||||
{
|
||||
$ignored_count = 0;
|
||||
|
||||
foreach ($this->retrieve_list as $i => $c13y)
|
||||
{
|
||||
if (in_array($c13y['id'], $_POST['c13y_selection']))
|
||||
{
|
||||
$this->build_ignore_list[] = $c13y['id'];
|
||||
$this->retrieve_list[$i]['ignored'] = true;
|
||||
$ignored_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ignored_count > 0)
|
||||
{
|
||||
$page['infos'][] = l10n_dec(
|
||||
'%d anomaly has been ignored.', '%d anomalies have been ignored.',
|
||||
$ignored_count
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ignore_list_changed =
|
||||
(
|
||||
($ignore_list_changed) or
|
||||
(count(array_diff($this->ignore_list, $this->build_ignore_list)) > 0) or
|
||||
(count(array_diff($this->build_ignore_list, $this->ignore_list)) > 0)
|
||||
);
|
||||
|
||||
if ($ignore_list_changed)
|
||||
{
|
||||
$this->update_conf($this->build_ignore_list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display anomalies list
|
||||
*
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
function display()
|
||||
{
|
||||
global $template;
|
||||
|
||||
$check_automatic_correction = false;
|
||||
$submit_automatic_correction = false;
|
||||
$submit_ignore = false;
|
||||
|
||||
if (isset($this->retrieve_list) and count($this->retrieve_list) > 0)
|
||||
{
|
||||
$template->set_filenames(array('check_integrity' => 'check_integrity.tpl'));
|
||||
|
||||
foreach ($this->retrieve_list as $i => $c13y)
|
||||
{
|
||||
$can_select = false;
|
||||
$c13y_display = array(
|
||||
'id' => $c13y['id'],
|
||||
'anomaly' => $c13y['anomaly'],
|
||||
'show_ignore_msg' => false,
|
||||
'show_correction_success_fct' => false,
|
||||
'correction_error_fct' => '',
|
||||
'show_correction_fct' => false,
|
||||
'correction_error_fct' => '',
|
||||
'show_correction_bad_fct' => false,
|
||||
'correction_msg' => ''
|
||||
);
|
||||
|
||||
if (isset($c13y['ignored']))
|
||||
{
|
||||
if ($c13y['ignored'])
|
||||
{
|
||||
$c13y_display['show_ignore_msg'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
die('$c13y[\'ignored\'] cannot be false');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($c13y['correction_fct']))
|
||||
{
|
||||
if (isset($c13y['corrected']))
|
||||
{
|
||||
if ($c13y['corrected'])
|
||||
{
|
||||
$c13y_display['show_correction_success_fct'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c13y_display['correction_error_fct'] = $this->get_htlm_links_more_info();
|
||||
}
|
||||
}
|
||||
else if ($c13y['is_callable'])
|
||||
{
|
||||
$c13y_display['show_correction_fct'] = true;
|
||||
$template->append('c13y_do_check', $c13y['id']);
|
||||
$submit_automatic_correction = true;
|
||||
$can_select = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c13y_display['show_correction_bad_fct'] = true;
|
||||
$can_select = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$can_select = true;
|
||||
}
|
||||
|
||||
if (!empty($c13y['correction_msg']) and !isset($c13y['corrected']))
|
||||
{
|
||||
$c13y_display['correction_msg'] = $c13y['correction_msg'];
|
||||
}
|
||||
}
|
||||
|
||||
$c13y_display['can_select'] = $can_select;
|
||||
if ($can_select)
|
||||
{
|
||||
$submit_ignore = true;
|
||||
}
|
||||
|
||||
$template->append('c13y_list', $c13y_display);
|
||||
}
|
||||
|
||||
$template->assign('c13y_show_submit_automatic_correction', $submit_automatic_correction);
|
||||
$template->assign('c13y_show_submit_ignore', $submit_ignore);
|
||||
|
||||
$template->concat('ADMIN_CONTENT', $template->parse('check_integrity', true));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add anomaly data
|
||||
*
|
||||
* @param anomaly arguments
|
||||
* @return void
|
||||
*/
|
||||
function add_anomaly($anomaly, $correction_fct = null, $correction_fct_args = null, $correction_msg = null)
|
||||
{
|
||||
$id = md5($anomaly.$correction_fct.serialize($correction_fct_args).$correction_msg);
|
||||
|
||||
if (in_array($id, $this->ignore_list))
|
||||
{
|
||||
$this->build_ignore_list[] = $id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->retrieve_list[] =
|
||||
array(
|
||||
'id' => $id,
|
||||
'anomaly' => $anomaly,
|
||||
'correction_fct' => $correction_fct,
|
||||
'correction_fct_args' => $correction_fct_args,
|
||||
'correction_msg' => $correction_msg,
|
||||
'is_callable' => is_callable($correction_fct));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update table config
|
||||
*
|
||||
* @param ignore list array
|
||||
* @return void
|
||||
*/
|
||||
function update_conf($conf_ignore_list = array())
|
||||
{
|
||||
$conf_c13y_ignore = array();
|
||||
$conf_c13y_ignore['version'] = PHPWG_VERSION;
|
||||
$conf_c13y_ignore['list'] = $conf_ignore_list;
|
||||
$query = 'update '.CONFIG_TABLE.' set value =\''.serialize($conf_c13y_ignore).'\'where param = \'c13y_ignore\';';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply maintenance
|
||||
*
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
function maintenance()
|
||||
{
|
||||
$this->update_conf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns links more informations
|
||||
*
|
||||
* @param void
|
||||
* @return html links
|
||||
*/
|
||||
function get_htlm_links_more_info()
|
||||
{
|
||||
$pwg_links = pwg_URL();
|
||||
$link_fmt = '<a href="%s" onclick="window.open(this.href, \'\'); return false;">%s</a>';
|
||||
return
|
||||
sprintf
|
||||
(
|
||||
l10n('Go to %s or %s for more informations'),
|
||||
sprintf($link_fmt, $pwg_links['FORUM'], l10n('the forum')),
|
||||
sprintf($link_fmt, $pwg_links['WIKI'], l10n('the wiki'))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,267 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!is_webmaster())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
|
||||
// original resize
|
||||
$original_fields = array(
|
||||
'original_resize',
|
||||
'original_resize_maxwidth',
|
||||
'original_resize_maxheight',
|
||||
'original_resize_quality',
|
||||
);
|
||||
|
||||
$updates = array();
|
||||
|
||||
foreach ($original_fields as $field)
|
||||
{
|
||||
$value = !empty($_POST[$field]) ? $_POST[$field] : null;
|
||||
$updates[$field] = $value;
|
||||
}
|
||||
|
||||
save_upload_form_config($updates, $page['errors'], $errors);
|
||||
|
||||
if ($_POST['resize_quality'] < 50 or $_POST['resize_quality'] > 98)
|
||||
{
|
||||
$errors['resize_quality'] = '[50..98]';
|
||||
}
|
||||
|
||||
$pderivatives = $_POST['d'];
|
||||
|
||||
// step 1 - sanitize HTML input
|
||||
foreach ($pderivatives as $type => &$pderivative)
|
||||
{
|
||||
if ($pderivative['must_square'] = ($type==IMG_SQUARE ? true : false))
|
||||
{
|
||||
$pderivative['h'] = $pderivative['w'];
|
||||
$pderivative['minh'] = $pderivative['minw'] = $pderivative['w'];
|
||||
$pderivative['crop'] = 100;
|
||||
}
|
||||
$pderivative['must_enable'] = ($type==IMG_SQUARE || $type==IMG_THUMB || $type==$conf['derivative_default_size'])? true : false;
|
||||
$pderivative['enabled'] = isset($pderivative['enabled']) || $pderivative['must_enable'] ? true : false;
|
||||
|
||||
if (isset($pderivative['crop']))
|
||||
{
|
||||
$pderivative['crop'] = 100;
|
||||
$pderivative['minw'] = $pderivative['w'];
|
||||
$pderivative['minh'] = $pderivative['h'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$pderivative['crop'] = 0;
|
||||
$pderivative['minw'] = null;
|
||||
$pderivative['minh'] = null;
|
||||
}
|
||||
}
|
||||
unset($pderivative);
|
||||
|
||||
// step 2 - check validity
|
||||
$prev_w = $prev_h = 0;
|
||||
foreach(ImageStdParams::get_all_types() as $type)
|
||||
{
|
||||
$pderivative = $pderivatives[$type];
|
||||
if (!$pderivative['enabled'])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($type == IMG_THUMB)
|
||||
{
|
||||
$w = intval($pderivative['w']);
|
||||
if ($w <= 0)
|
||||
{
|
||||
$errors[$type]['w'] = '>0';
|
||||
}
|
||||
|
||||
$h = intval($pderivative['h']);
|
||||
if ($h <= 0)
|
||||
{
|
||||
$errors[$type]['h'] = '>0';
|
||||
}
|
||||
|
||||
if (max($w,$h) <= $prev_w)
|
||||
{
|
||||
$errors[$type]['w'] = $errors[$type]['h'] = '>'.$prev_w;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$v = intval($pderivative['w']);
|
||||
if ($v <= 0 or $v <= $prev_w)
|
||||
{
|
||||
$errors[$type]['w'] = '>'.$prev_w;
|
||||
}
|
||||
|
||||
$v = intval($pderivative['h']);
|
||||
if ($v <= 0 or $v <= $prev_h)
|
||||
{
|
||||
$errors[$type]['h'] = '>'.$prev_h;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($errors) == 0)
|
||||
{
|
||||
$prev_w = intval($pderivative['w']);
|
||||
$prev_h = intval($pderivative['h']);
|
||||
}
|
||||
|
||||
$v = intval($pderivative['sharpen']);
|
||||
if ($v<0 || $v>100)
|
||||
{
|
||||
$errors[$type]['sharpen'] = '[0..100]';
|
||||
}
|
||||
}
|
||||
|
||||
// step 3 - save data
|
||||
if (count($errors) == 0)
|
||||
{
|
||||
$quality_changed = ImageStdParams::$quality != intval($_POST['resize_quality']);
|
||||
ImageStdParams::$quality = intval($_POST['resize_quality']);
|
||||
|
||||
$enabled = ImageStdParams::get_defined_type_map();
|
||||
$disabled = safe_unserialize(ImageStdParams::get_disabled_type_map());
|
||||
if ($disabled === false)
|
||||
{
|
||||
$disabled = array();
|
||||
}
|
||||
$changed_types = array();
|
||||
|
||||
foreach (ImageStdParams::get_all_types() as $type)
|
||||
{
|
||||
$pderivative = $pderivatives[$type];
|
||||
|
||||
if ($pderivative['enabled'])
|
||||
{
|
||||
$new_params = new DerivativeParams(
|
||||
new SizingParams(
|
||||
array(intval($pderivative['w']), intval($pderivative['h'])),
|
||||
round($pderivative['crop'] / 100, 2),
|
||||
array(intval($pderivative['minw']), intval($pderivative['minh']))
|
||||
)
|
||||
);
|
||||
$new_params->sharpen = intval($pderivative['sharpen']);
|
||||
|
||||
ImageStdParams::apply_global($new_params);
|
||||
|
||||
if (isset($enabled[$type]))
|
||||
{
|
||||
$old_params = $enabled[$type];
|
||||
$same = true;
|
||||
if (!size_equals($old_params->sizing->ideal_size, $new_params->sizing->ideal_size)
|
||||
or $old_params->sizing->max_crop != $new_params->sizing->max_crop)
|
||||
{
|
||||
$same = false;
|
||||
}
|
||||
|
||||
if ($same
|
||||
and $new_params->sizing->max_crop != 0
|
||||
and !size_equals($old_params->sizing->min_size, $new_params->sizing->min_size))
|
||||
{
|
||||
$same = false;
|
||||
}
|
||||
|
||||
if ($quality_changed
|
||||
|| $new_params->sharpen != $old_params->sharpen)
|
||||
{
|
||||
$same = false;
|
||||
}
|
||||
|
||||
if (!$same)
|
||||
{
|
||||
$new_params->last_mod_time = time();
|
||||
$changed_types[] = $type;
|
||||
}
|
||||
else
|
||||
{
|
||||
$new_params->last_mod_time = $old_params->last_mod_time;
|
||||
}
|
||||
$enabled[$type] = $new_params;
|
||||
}
|
||||
else
|
||||
{// now enabled, before was disabled
|
||||
$enabled[$type] = $new_params;
|
||||
unset($disabled[$type]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{// disabled
|
||||
if (isset($enabled[$type]))
|
||||
{// now disabled, before was enabled
|
||||
$changed_types[] = $type;
|
||||
$disabled[$type] = $enabled[$type];
|
||||
unset($enabled[$type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$enabled_by = array(); // keys ordered by all types
|
||||
foreach(ImageStdParams::get_all_types() as $type)
|
||||
{
|
||||
if (isset($enabled[$type]))
|
||||
{
|
||||
$enabled_by[$type] = $enabled[$type];
|
||||
}
|
||||
}
|
||||
|
||||
foreach( array_keys(ImageStdParams::$custom) as $custom)
|
||||
{
|
||||
if (isset($_POST['delete_custom_derivative_'.$custom]))
|
||||
{
|
||||
$changed_types[] = $custom;
|
||||
unset(ImageStdParams::$custom[$custom]);
|
||||
}
|
||||
}
|
||||
|
||||
ImageStdParams::set_and_save($enabled_by);
|
||||
ImageStdParams::set_and_save_disabled($disabled);
|
||||
|
||||
if (count($changed_types))
|
||||
{
|
||||
clear_derivative_cache($changed_types);
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n('Your configuration settings are saved'),
|
||||
)
|
||||
);
|
||||
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>'sizes'));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($original_fields as $field)
|
||||
{
|
||||
if (isset($_POST[$field]))
|
||||
{
|
||||
$template->append(
|
||||
'sizes',
|
||||
array(
|
||||
$field => strip_tags($_POST[$field]) // strip_tags prevents from XSS attempt
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign('derivatives', $pderivatives);
|
||||
$template->assign('ferrors', $errors);
|
||||
$template->assign('resize_quality', $_POST['resize_quality']);
|
||||
$page['sizes_loaded_in_tpl'] = true;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,211 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!is_webmaster())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
function get_watermark_filename($list, $candidate, $step = 0)
|
||||
{
|
||||
global $change_name;
|
||||
$change_name = $candidate;
|
||||
if ($step != 0)
|
||||
{
|
||||
$change_name .= '-'.$step;
|
||||
}
|
||||
if (in_array($change_name, $list))
|
||||
{
|
||||
return get_watermark_filename($list, $candidate, $step+1);
|
||||
}
|
||||
return $change_name.'.png';
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
$pwatermark = $_POST['w'];
|
||||
|
||||
// step 0 - manage upload if any
|
||||
if (isset($_FILES['watermarkImage']) and !empty($_FILES['watermarkImage']['tmp_name']))
|
||||
{
|
||||
list($width, $height, $type) = getimagesize($_FILES['watermarkImage']['tmp_name']);
|
||||
if (IMAGETYPE_PNG != $type)
|
||||
{
|
||||
$errors['watermarkImage'] = sprintf(
|
||||
l10n('Allowed file types: %s.'),
|
||||
'PNG'
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$upload_dir = PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks';
|
||||
if (mkgetdir($upload_dir, MKGETDIR_DEFAULT&~MKGETDIR_DIE_ON_ERROR))
|
||||
{
|
||||
// file name may include exotic chars like single quote, we need a safe name
|
||||
$new_name = str2url(get_filename_wo_extension($_FILES['watermarkImage']['name']));
|
||||
|
||||
// we need existing watermarks to avoid overwritting one
|
||||
$watermark_files = array();
|
||||
if ( ($glob=glob(PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks/*.png')) !== false)
|
||||
{
|
||||
foreach ($glob as $file)
|
||||
{
|
||||
$watermark_files[] = get_filename_wo_extension(
|
||||
substr($file, strlen(PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks/'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$file_path = $upload_dir.'/'.get_watermark_filename($watermark_files, $new_name);
|
||||
|
||||
if (move_uploaded_file($_FILES['watermarkImage']['tmp_name'], $file_path))
|
||||
{
|
||||
$pwatermark['file'] = substr($file_path, strlen(PHPWG_ROOT_PATH));
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = $errors['watermarkImage'] = "$file_path " .l10n('no write access');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = $errors['watermarkImage'] = sprintf( l10n('Add write access to the "%s" directory'), $upload_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// step 1 - sanitize HTML input
|
||||
switch ($pwatermark['position'])
|
||||
{
|
||||
case 'topleft':
|
||||
{
|
||||
$pwatermark['xpos'] = 0;
|
||||
$pwatermark['ypos'] = 0;
|
||||
break;
|
||||
}
|
||||
case 'topright':
|
||||
{
|
||||
$pwatermark['xpos'] = 100;
|
||||
$pwatermark['ypos'] = 0;
|
||||
break;
|
||||
}
|
||||
case 'middle':
|
||||
{
|
||||
$pwatermark['xpos'] = 50;
|
||||
$pwatermark['ypos'] = 50;
|
||||
break;
|
||||
}
|
||||
case 'bottomleft':
|
||||
{
|
||||
$pwatermark['xpos'] = 0;
|
||||
$pwatermark['ypos'] = 100;
|
||||
break;
|
||||
}
|
||||
case 'bottomright':
|
||||
{
|
||||
$pwatermark['xpos'] = 100;
|
||||
$pwatermark['ypos'] = 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// step 2 - check validity
|
||||
$v = intval($pwatermark['xpos']);
|
||||
if ($v < 0 or $v > 100)
|
||||
{
|
||||
$errors['watermark']['xpos'] = '[0..100]';
|
||||
}
|
||||
|
||||
$v = intval($pwatermark['ypos']);
|
||||
if ($v < 0 or $v > 100)
|
||||
{
|
||||
$errors['watermark']['ypos'] = '[0..100]';
|
||||
}
|
||||
|
||||
$v = intval($pwatermark['opacity']);
|
||||
if ($v <= 0 or $v > 100)
|
||||
{
|
||||
$errors['watermark']['opacity'] = '(0..100]';
|
||||
}
|
||||
|
||||
// step 3 - save data
|
||||
if (count($errors) == 0)
|
||||
{
|
||||
$watermark = new WatermarkParams();
|
||||
$watermark->file = $pwatermark['file'];
|
||||
$watermark->xpos = intval($pwatermark['xpos']);
|
||||
$watermark->ypos = intval($pwatermark['ypos']);
|
||||
$watermark->xrepeat = intval($pwatermark['xrepeat']);
|
||||
$watermark->yrepeat = intval($pwatermark['yrepeat']);
|
||||
$watermark->opacity = intval($pwatermark['opacity']);
|
||||
$watermark->min_size = array(intval($pwatermark['minw']),intval($pwatermark['minh']));
|
||||
|
||||
$old_watermark = ImageStdParams::get_watermark();
|
||||
$watermark_changed =
|
||||
$watermark->file != $old_watermark->file
|
||||
|| $watermark->xpos != $old_watermark->xpos
|
||||
|| $watermark->ypos != $old_watermark->ypos
|
||||
|| $watermark->xrepeat != $old_watermark->xrepeat
|
||||
|| $watermark->yrepeat != $old_watermark->yrepeat
|
||||
|| $watermark->opacity != $old_watermark->opacity;
|
||||
|
||||
// save the new watermark configuration
|
||||
ImageStdParams::set_watermark($watermark);
|
||||
|
||||
// do we have to regenerate the derivatives (and which types)?
|
||||
$changed_types = array();
|
||||
|
||||
foreach (ImageStdParams::get_defined_type_map() as $type => $params)
|
||||
{
|
||||
$old_use_watermark = $params->use_watermark;
|
||||
ImageStdParams::apply_global($params);
|
||||
|
||||
$changed = $params->use_watermark != $old_use_watermark;
|
||||
if (!$changed and $params->use_watermark)
|
||||
{
|
||||
$changed = $watermark_changed;
|
||||
}
|
||||
if (!$changed and $params->use_watermark)
|
||||
{
|
||||
// if thresholds change and before/after the threshold is lower than the corresponding derivative side -> some derivatives might switch the watermark
|
||||
$changed |= $watermark->min_size[0]!=$old_watermark->min_size[0] and ($watermark->min_size[0]<$params->max_width() or $old_watermark->min_size[0]<$params->max_width());
|
||||
$changed |= $watermark->min_size[1]!=$old_watermark->min_size[1] and ($watermark->min_size[1]<$params->max_height() or $old_watermark->min_size[1]<$params->max_height());
|
||||
}
|
||||
|
||||
if ($changed)
|
||||
{
|
||||
$params->last_mod_time = time();
|
||||
$changed_types[] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
ImageStdParams::save();
|
||||
|
||||
if (count($changed_types))
|
||||
{
|
||||
clear_derivative_cache($changed_types);
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n('Your configuration settings are saved'),
|
||||
)
|
||||
);
|
||||
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>'watermark'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign('watermark', $pwatermark);
|
||||
$template->assign('ferrors', $errors);
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,506 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\admin\history
|
||||
*/
|
||||
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
/**
|
||||
* Init tabsheet for history pages
|
||||
* @ignore
|
||||
*/
|
||||
function history_tabsheet()
|
||||
{
|
||||
global $page, $link_start;
|
||||
|
||||
// TabSheet
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('history');
|
||||
$tabsheet->select($page['page']);
|
||||
$tabsheet->assign();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used to sort history entries
|
||||
*/
|
||||
function history_compare($a, $b)
|
||||
{
|
||||
return strcmp($a['date'].$a['time'], $b['date'].$b['time']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform history search.
|
||||
*
|
||||
* @param array $data - used in trigger_change
|
||||
* @param array $search
|
||||
* @param string[] $types
|
||||
* @param array
|
||||
*/
|
||||
function get_history($data, $search, $types)
|
||||
{
|
||||
if (isset($search['fields']['filename']))
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE file LIKE \''.$search['fields']['filename'].'\'
|
||||
;';
|
||||
$search['image_ids'] = array_from_query($query, 'id');
|
||||
}
|
||||
|
||||
// echo '<pre>'; print_r($search); echo '</pre>';
|
||||
|
||||
$clauses = array();
|
||||
|
||||
if (isset($search['fields']['date-after']))
|
||||
{
|
||||
$clauses[] = "date >= '".$search['fields']['date-after']."'";
|
||||
}
|
||||
|
||||
if (isset($search['fields']['date-before']))
|
||||
{
|
||||
$clauses[] = "date <= '".$search['fields']['date-before']."'";
|
||||
}
|
||||
|
||||
if (isset($search['fields']['types']))
|
||||
{
|
||||
$local_clauses = array();
|
||||
|
||||
foreach ($types as $type) {
|
||||
if (in_array($type, $search['fields']['types'])) {
|
||||
$clause = 'image_type ';
|
||||
if ($type == 'none')
|
||||
{
|
||||
$clause.= 'IS NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$clause.= "= '".$type."'";
|
||||
}
|
||||
|
||||
$local_clauses[] = $clause;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($local_clauses) > 0)
|
||||
{
|
||||
$clauses[] = implode(' OR ', $local_clauses);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($search['fields']['user'])
|
||||
and $search['fields']['user'] != -1)
|
||||
{
|
||||
$clauses[] = 'user_id = '.$search['fields']['user'];
|
||||
}
|
||||
|
||||
if (isset($search['fields']['image_id']))
|
||||
{
|
||||
$clauses[] = 'image_id = '.$search['fields']['image_id'];
|
||||
}
|
||||
|
||||
if (isset($search['fields']['filename']))
|
||||
{
|
||||
if (count($search['image_ids']) == 0)
|
||||
{
|
||||
// a clause that is always false
|
||||
$clauses[] = '1 = 2 ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$clauses[] = 'image_id IN ('.implode(', ', $search['image_ids']).')';
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($search['fields']['ip']))
|
||||
{
|
||||
$clauses[] = 'IP LIKE "'.$search['fields']['ip'].'"';
|
||||
}
|
||||
|
||||
$clauses = prepend_append_array_items($clauses, '(', ')');
|
||||
|
||||
$where_separator =
|
||||
implode(
|
||||
"\n AND ",
|
||||
$clauses
|
||||
);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
date,
|
||||
time,
|
||||
user_id,
|
||||
IP,
|
||||
section,
|
||||
category_id,
|
||||
search_id,
|
||||
tag_ids,
|
||||
image_id,
|
||||
image_type
|
||||
FROM '.HISTORY_TABLE.'
|
||||
WHERE '.$where_separator.'
|
||||
;';
|
||||
|
||||
// LIMIT '.$conf['nb_logs_page'].' OFFSET '.$page['start'].'
|
||||
|
||||
$result = pwg_query($query);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$data[] = $row;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute statistics from history table to history_summary table
|
||||
*
|
||||
* @param int $max_lines - to only compute the next X lines, not the whole remaining lines
|
||||
*/
|
||||
function history_summarize($max_lines=null)
|
||||
{
|
||||
// we need to know which was the last line "summarized"
|
||||
$query = '
|
||||
SELECT
|
||||
*
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
WHERE history_id_to IS NOT NULL
|
||||
ORDER BY history_id_to DESC
|
||||
LIMIT 1
|
||||
;';
|
||||
$summary_lines = query2array($query);
|
||||
|
||||
$history_min_id = 0;
|
||||
if (count($summary_lines) > 0)
|
||||
{
|
||||
$last_summary = $summary_lines[0];
|
||||
$history_min_id = $last_summary['history_id_to'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we have no "reference", ie "starting point", we need to find
|
||||
// one. And "0" is not the right answer here, because history table may
|
||||
// have been purged already.
|
||||
$query = '
|
||||
SELECT
|
||||
MIN(id) AS min_id
|
||||
FROM '.HISTORY_TABLE.'
|
||||
;';
|
||||
$history_lines = query2array($query);
|
||||
if (count($history_lines) > 0)
|
||||
{
|
||||
$history_min_id = $history_lines[0]['min_id'] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
date,
|
||||
'.pwg_db_get_hour('time').' AS hour,
|
||||
MIN(id) AS min_id,
|
||||
MAX(id) AS max_id,
|
||||
COUNT(*) AS nb_pages
|
||||
FROM '.HISTORY_TABLE.'
|
||||
WHERE id > '.$history_min_id;
|
||||
|
||||
if (isset($max_lines))
|
||||
{
|
||||
$query.= '
|
||||
AND id <= '.($history_min_id + $max_lines);
|
||||
}
|
||||
|
||||
$query.= '
|
||||
GROUP BY
|
||||
date,
|
||||
hour
|
||||
ORDER BY
|
||||
date ASC,
|
||||
hour ASC
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
$need_update = array();
|
||||
|
||||
$is_first = true;
|
||||
$first_time_key = null;
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$time_keys = array(
|
||||
substr($row['date'], 0, 4), //yyyy
|
||||
substr($row['date'], 0, 7), //yyyy-mm
|
||||
substr($row['date'], 0, 10),//yyyy-mm-dd
|
||||
sprintf(
|
||||
'%s-%02u',
|
||||
$row['date'], $row['hour']
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($time_keys as $time_key)
|
||||
{
|
||||
if (!isset($need_update[$time_key]))
|
||||
{
|
||||
$need_update[$time_key] = array(
|
||||
'nb_pages' => 0,
|
||||
'history_id_from' => $row['min_id'],
|
||||
'history_id_to' => $row['max_id'],
|
||||
);
|
||||
}
|
||||
$need_update[$time_key]['nb_pages'] += $row['nb_pages'];
|
||||
|
||||
if ($row['min_id'] < $need_update[$time_key]['history_id_from'])
|
||||
{
|
||||
$need_update[$time_key]['history_id_from'] = $row['min_id'];
|
||||
}
|
||||
|
||||
if ($row['max_id'] > $need_update[$time_key]['history_id_to'])
|
||||
{
|
||||
$need_update[$time_key]['history_id_to'] = $row['max_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_first)
|
||||
{
|
||||
$is_first = false;
|
||||
$first_time_key = $time_keys[3];
|
||||
}
|
||||
}
|
||||
|
||||
// Only the oldest time_key might be already summarized, so we have to
|
||||
// update the 4 corresponding lines instead of simply inserting them.
|
||||
//
|
||||
// For example, if the oldest unsummarized is 2005.08.25.21, the 4 lines
|
||||
// that can be updated are:
|
||||
//
|
||||
// +---------------+----------+
|
||||
// | id | nb_pages |
|
||||
// +---------------+----------+
|
||||
// | 2005 | 241109 |
|
||||
// | 2005-08 | 20133 |
|
||||
// | 2005-08-25 | 620 |
|
||||
// | 2005-08-25-21 | 151 |
|
||||
// +---------------+----------+
|
||||
|
||||
$updates = array();
|
||||
$inserts = array();
|
||||
|
||||
if (isset($first_time_key))
|
||||
{
|
||||
list($year, $month, $day, $hour) = explode('-', $first_time_key);
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
WHERE year='.$year.'
|
||||
AND ( month IS NULL
|
||||
OR ( month='.$month.'
|
||||
AND ( day is NULL
|
||||
OR (day='.$day.'
|
||||
AND (hour IS NULL OR hour='.$hour.')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$key = sprintf('%4u', $row['year']);
|
||||
if ( isset($row['month']) )
|
||||
{
|
||||
$key .= sprintf('-%02u', $row['month']);
|
||||
if ( isset($row['day']) )
|
||||
{
|
||||
$key .= sprintf('-%02u', $row['day']);
|
||||
if ( isset($row['hour']) )
|
||||
{
|
||||
$key .= sprintf('-%02u', $row['hour']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($need_update[$key]))
|
||||
{
|
||||
$row['nb_pages'] += $need_update[$key]['nb_pages'];
|
||||
$row['history_id_to'] = $need_update[$key]['history_id_to'];
|
||||
$updates[] = $row;
|
||||
unset($need_update[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($need_update as $time_key => $summary)
|
||||
{
|
||||
$time_tokens = explode('-', $time_key);
|
||||
|
||||
$inserts[] = array(
|
||||
'year' => $time_tokens[0],
|
||||
'month' => @$time_tokens[1],
|
||||
'day' => @$time_tokens[2],
|
||||
'hour' => @$time_tokens[3],
|
||||
'nb_pages' => $summary['nb_pages'],
|
||||
'history_id_from' => $summary['history_id_from'],
|
||||
'history_id_to' => $summary['history_id_to'],
|
||||
);
|
||||
}
|
||||
|
||||
if (count($updates) > 0)
|
||||
{
|
||||
mass_updates(
|
||||
HISTORY_SUMMARY_TABLE,
|
||||
array(
|
||||
'primary' => array('year','month','day','hour'),
|
||||
'update' => array('nb_pages','history_id_to'),
|
||||
),
|
||||
$updates
|
||||
);
|
||||
}
|
||||
|
||||
if (count($inserts) > 0)
|
||||
{
|
||||
mass_inserts(
|
||||
HISTORY_SUMMARY_TABLE,
|
||||
array_keys($inserts[0]),
|
||||
$inserts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart purge on history table. Keep some lines, purge only summarized lines
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
function history_autopurge()
|
||||
{
|
||||
global $conf, $logger;
|
||||
|
||||
if (0 == $conf['history_autopurge_keep_lines'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// we want to purge only if there are too many lines and if the lines are summarized
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.HISTORY_TABLE.'
|
||||
;';
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
if ($count <= $conf['history_autopurge_keep_lines'])
|
||||
{
|
||||
history_remove_summarized_column();
|
||||
return; // no need to purge for now
|
||||
}
|
||||
|
||||
// 1) find the last summarized history line
|
||||
$query = '
|
||||
SELECT
|
||||
*
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
WHERE history_id_to IS NOT NULL
|
||||
ORDER BY history_id_to DESC
|
||||
LIMIT 1
|
||||
;';
|
||||
$summary_lines = query2array($query);
|
||||
if (count($summary_lines) == 0)
|
||||
{
|
||||
return; // lines not summarized, no purge
|
||||
}
|
||||
|
||||
$history_id_last_summarized = $summary_lines[0]['history_id_to'];
|
||||
|
||||
// 2) find the latest history line (and substract the number of lines to keep)
|
||||
$query = '
|
||||
SELECT
|
||||
id
|
||||
FROM '.HISTORY_TABLE.'
|
||||
ORDER BY id DESC
|
||||
LIMIT 1
|
||||
;';
|
||||
$history_lines = query2array($query);
|
||||
if (count($history_lines) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$history_id_latest = $history_lines[0]['id'];
|
||||
|
||||
// 3) find the oldest history line (and add the number of lines to delete)
|
||||
$query = '
|
||||
SELECT
|
||||
id
|
||||
FROM '.HISTORY_TABLE.'
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
;';
|
||||
$history_lines = query2array($query);
|
||||
$history_id_oldest = $history_lines[0]['id'];
|
||||
|
||||
$search_min = array(
|
||||
$history_id_last_summarized,
|
||||
$history_id_latest - $conf['history_autopurge_keep_lines'],
|
||||
$history_id_oldest + $conf['history_autopurge_blocksize'],
|
||||
);
|
||||
|
||||
$history_id_delete_before = min($search_min);
|
||||
|
||||
$logger->debug(__FUNCTION__.', '.join('/', $search_min));
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.HISTORY_TABLE.'
|
||||
WHERE id < '.$history_id_delete_before.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
history_remove_summarized_column();
|
||||
}
|
||||
|
||||
function history_remove_summarized_column()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (isset($conf['history_summarized_dropped']) and $conf['history_summarized_dropped'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.HISTORY_TABLE.'
|
||||
;';
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
if ($count > $conf['history_autopurge_keep_lines']+$conf['history_autopurge_blocksize'])
|
||||
{
|
||||
// it's not yet time to remove history.summarized
|
||||
return;
|
||||
}
|
||||
|
||||
$result = pwg_query('SHOW COLUMNS FROM `'.HISTORY_TABLE.'` LIKE "summarized";');
|
||||
if (pwg_db_num_rows($result))
|
||||
{
|
||||
pwg_query('ALTER TABLE `'.HISTORY_TABLE.'` DROP COLUMN `summarized`;');
|
||||
}
|
||||
|
||||
conf_update_param('history_summarized_dropped', true);
|
||||
}
|
||||
|
||||
add_event_handler('get_history', 'get_history');
|
||||
trigger_notify('functions_history_included');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,113 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\admin\install
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Loads a SQL file and executes all queries.
|
||||
* Before executing a query, $replaced is... replaced by $replacing. This is
|
||||
* useful when the SQL file contains generic words. Drop table queries are
|
||||
* not executed.
|
||||
*
|
||||
* @param string $filepath
|
||||
* @param string $replaced
|
||||
* @param string $replacing
|
||||
*/
|
||||
function execute_sqlfile($filepath, $replaced, $replacing, $dblayer)
|
||||
{
|
||||
$sql_lines = file($filepath);
|
||||
$query = '';
|
||||
foreach ($sql_lines as $sql_line)
|
||||
{
|
||||
$sql_line = trim($sql_line);
|
||||
if (preg_match('/(^--|^$)/', $sql_line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$query.= ' '.$sql_line;
|
||||
// if we reached the end of query, we execute it and reinitialize the
|
||||
// variable "query"
|
||||
if (preg_match('/;$/', $sql_line))
|
||||
{
|
||||
$query = trim($query);
|
||||
$query = str_replace($replaced, $replacing, $query);
|
||||
// we don't execute "DROP TABLE" queries
|
||||
if (!preg_match('/^DROP TABLE/i', $query))
|
||||
{
|
||||
if ('mysql' == $dblayer)
|
||||
{
|
||||
if ( preg_match('/^(CREATE TABLE .*)[\s]*;[\s]*/im', $query, $matches) )
|
||||
{
|
||||
$query = $matches[1].' DEFAULT CHARACTER SET utf8'.';';
|
||||
}
|
||||
}
|
||||
pwg_query($query);
|
||||
}
|
||||
$query = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically activate all core themes in the "themes" directory.
|
||||
*/
|
||||
function activate_core_themes()
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/themes.class.php');
|
||||
$themes = new themes();
|
||||
foreach ($themes->fs_themes as $theme_id => $fs_theme)
|
||||
{
|
||||
if (in_array($theme_id, array('modus')))
|
||||
{
|
||||
$themes->perform_action('activate', $theme_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically activate some core plugins
|
||||
*/
|
||||
function activate_core_plugins()
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
|
||||
|
||||
$plugins = new plugins();
|
||||
|
||||
foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
|
||||
{
|
||||
if (in_array($plugin_id, array()))
|
||||
{
|
||||
$plugins->perform_action('activate', $plugin_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database during installation. Uses $_POST.
|
||||
*
|
||||
* @param array &$infos - populated with infos
|
||||
* @param array &$errors - populated with errors
|
||||
*/
|
||||
function install_db_connect(&$infos, &$errors)
|
||||
{
|
||||
try
|
||||
{
|
||||
pwg_db_connect($_POST['dbhost'], $_POST['dbuser'],
|
||||
$_POST['dbpasswd'], $_POST['dbname']);
|
||||
pwg_db_check_version();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$errors[] = l10n($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,437 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\admin\metadata
|
||||
*/
|
||||
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'/include/functions_metadata.inc.php');
|
||||
|
||||
|
||||
/**
|
||||
* Returns IPTC metadata to sync from a file, depending on IPTC mapping.
|
||||
* @toto : clean code (factorize foreach)
|
||||
*
|
||||
* @param string $file
|
||||
* @return array
|
||||
*/
|
||||
function get_sync_iptc_data($file)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$map = $conf['use_iptc_mapping'];
|
||||
|
||||
$iptc = get_iptc_data($file, $map);
|
||||
|
||||
foreach ($iptc as $pwg_key => $value)
|
||||
{
|
||||
if (in_array($pwg_key, array('date_creation', 'date_available')))
|
||||
{
|
||||
if (preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
|
||||
{
|
||||
$year = $matches[1];
|
||||
$month = $matches[2];
|
||||
$day = $matches[3];
|
||||
|
||||
if (!checkdate($month, $day, $year))
|
||||
{
|
||||
// we suppose the year is correct
|
||||
$month = 1;
|
||||
$day = 1;
|
||||
}
|
||||
|
||||
$iptc[$pwg_key] = $year.'-'.$month.'-'.$day;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($iptc['keywords']))
|
||||
{
|
||||
$iptc['keywords'] = metadata_normalize_keywords_string($iptc['keywords']);
|
||||
}
|
||||
|
||||
foreach ($iptc as $pwg_key => $value)
|
||||
{
|
||||
$iptc[$pwg_key] = addslashes($iptc[$pwg_key]);
|
||||
}
|
||||
|
||||
return $iptc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns EXIF metadata to sync from a file, depending on EXIF mapping.
|
||||
*
|
||||
* @param string $file
|
||||
* @return array
|
||||
*/
|
||||
function get_sync_exif_data($file)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$exif = get_exif_data($file, $conf['use_exif_mapping']);
|
||||
|
||||
foreach ($exif as $pwg_key => $value)
|
||||
{
|
||||
if (in_array($pwg_key, array('date_creation', 'date_available')))
|
||||
{
|
||||
if (preg_match('/^(\d{4}).(\d{2}).(\d{2}) (\d{2}).(\d{2}).(\d{2})/', $value, $matches))
|
||||
{
|
||||
$exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3].' '.$matches[4].':'.$matches[5].':'.$matches[6];
|
||||
if ($exif[$pwg_key] == '0000-00-00 00:00:00')
|
||||
{
|
||||
$exif[$pwg_key] = Null;
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/^(\d{4}).(\d{2}).(\d{2})/', $value, $matches))
|
||||
{
|
||||
$exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($exif[$pwg_key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($pwg_key, array('keywords', 'tags')))
|
||||
{
|
||||
$exif[$pwg_key] = metadata_normalize_keywords_string($exif[$pwg_key]);
|
||||
}
|
||||
|
||||
if (empty($exif[$pwg_key]))
|
||||
{
|
||||
unset($exif[$pwg_key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$exif[$pwg_key] = addslashes($exif[$pwg_key]);
|
||||
}
|
||||
|
||||
return $exif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all potential file metadata fields, including IPTC and EXIF.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
function get_sync_metadata_attributes()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$update_fields = array('filesize', 'width', 'height');
|
||||
|
||||
if ($conf['use_exif'])
|
||||
{
|
||||
$update_fields =
|
||||
array_merge(
|
||||
$update_fields,
|
||||
array_keys($conf['use_exif_mapping']),
|
||||
array('latitude', 'longitude')
|
||||
);
|
||||
}
|
||||
|
||||
if ($conf['use_iptc'])
|
||||
{
|
||||
$update_fields =
|
||||
array_merge(
|
||||
$update_fields,
|
||||
array_keys($conf['use_iptc_mapping'])
|
||||
);
|
||||
}
|
||||
|
||||
return array_unique($update_fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all metadata of a file.
|
||||
*
|
||||
* @param array $infos - (path[, representative_ext])
|
||||
* @return array - includes data provided in $infos
|
||||
*/
|
||||
function get_sync_metadata($infos)
|
||||
{
|
||||
global $conf;
|
||||
$file = PHPWG_ROOT_PATH.$infos['path'];
|
||||
$fs = @filesize($file);
|
||||
|
||||
if ($fs===false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$infos['filesize'] = floor($fs/1024);
|
||||
|
||||
$is_tiff = false;
|
||||
|
||||
if (isset($infos['representative_ext']))
|
||||
{
|
||||
if ($image_size = @getimagesize($file))
|
||||
{
|
||||
$type = $image_size[2];
|
||||
|
||||
if (IMAGETYPE_TIFF_MM == $type or IMAGETYPE_TIFF_II == $type)
|
||||
{
|
||||
// in case of TIFF files, we want to use the original file and not
|
||||
// the representative for EXIF/IPTC, but we need the representative
|
||||
// for width/height (to compute the multiple size dimensions)
|
||||
$is_tiff = true;
|
||||
}
|
||||
}
|
||||
|
||||
$file = original_to_representative($file, $infos['representative_ext']);
|
||||
}
|
||||
|
||||
if (function_exists('mime_content_type'))
|
||||
{
|
||||
$mime_type = mime_content_type($file);
|
||||
|
||||
if (str_starts_with($mime_type, 'image/'))
|
||||
{
|
||||
if (in_array($mime_type, array('image/svg+xml', 'image/svg')))
|
||||
{
|
||||
$xml = file_get_contents($file);
|
||||
|
||||
$xmlget = simplexml_load_string($xml);
|
||||
$xmlattributes = $xmlget->attributes();
|
||||
$width = $xmlattributes->width;
|
||||
$height = $xmlattributes->height;
|
||||
$vb = (string) $xmlattributes->viewBox;
|
||||
|
||||
if (isset($width) and $width != "")
|
||||
{
|
||||
$infos['width'] = (int) $width;
|
||||
} elseif (isset($vb))
|
||||
{
|
||||
$infos['width'] = round(explode(" ", $vb)[2]);
|
||||
}
|
||||
|
||||
if (isset($height) and $height != "")
|
||||
{
|
||||
$infos['height'] = (int) $height;
|
||||
} elseif (isset($vb))
|
||||
{
|
||||
$infos['height'] = round(explode(" ", $vb)[3]);
|
||||
}
|
||||
}
|
||||
if ($image_size = @getimagesize($file))
|
||||
{
|
||||
$infos['width'] = $image_size[0];
|
||||
$infos['height'] = $image_size[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_tiff)
|
||||
{
|
||||
// back to original file
|
||||
$file = PHPWG_ROOT_PATH.$infos['path'];
|
||||
}
|
||||
|
||||
if ($conf['use_exif'])
|
||||
{
|
||||
$exif = get_sync_exif_data($file);
|
||||
$infos = array_merge($infos, $exif);
|
||||
}
|
||||
|
||||
if ($conf['use_iptc'])
|
||||
{
|
||||
$iptc = get_sync_iptc_data($file);
|
||||
$infos = array_merge($infos, $iptc);
|
||||
}
|
||||
|
||||
foreach (array('name', 'author') as $single_line_field)
|
||||
{
|
||||
if (isset($infos[$single_line_field]))
|
||||
{
|
||||
foreach (array("\r\n", "\n", "\r") as $to_replace_string)
|
||||
{
|
||||
$infos[$single_line_field] = str_replace($to_replace_string, ' ', $infos[$single_line_field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $infos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync all metadata of a list of images.
|
||||
* Metadata are fetched from original files and saved in database.
|
||||
*
|
||||
* @param int[] $ids
|
||||
*/
|
||||
function sync_metadata($ids)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!defined('CURRENT_DATE'))
|
||||
{
|
||||
define('CURRENT_DATE', date('Y-m-d'));
|
||||
}
|
||||
|
||||
$datas = array();
|
||||
$tags_of = array();
|
||||
|
||||
$query = '
|
||||
SELECT id, path, representative_ext
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN (
|
||||
'.wordwrap(implode(', ', $ids), 160, "\n").'
|
||||
)
|
||||
;';
|
||||
|
||||
$result = pwg_query($query);
|
||||
while ($data = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$data = get_sync_metadata($data);
|
||||
if ($data === false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// print_r($data);
|
||||
$id = $data['id'];
|
||||
foreach (array('keywords', 'tags') as $key)
|
||||
{
|
||||
if (isset($data[$key]))
|
||||
{
|
||||
if (!isset($tags_of[$id]))
|
||||
{
|
||||
$tags_of[$id] = array();
|
||||
}
|
||||
|
||||
foreach (explode(',', $data[$key]) as $tag_name)
|
||||
{
|
||||
$tags_of[$id][] = tag_id_from_tag_name($tag_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data['date_metadata_update'] = CURRENT_DATE;
|
||||
|
||||
$datas[] = $data;
|
||||
}
|
||||
|
||||
if (count($datas) > 0)
|
||||
{
|
||||
$update_fields = get_sync_metadata_attributes();
|
||||
$update_fields[] = 'date_metadata_update';
|
||||
|
||||
$update_fields = array_diff(
|
||||
$update_fields,
|
||||
array('tags', 'keywords')
|
||||
);
|
||||
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array(
|
||||
'primary' => array('id'),
|
||||
'update' => $update_fields
|
||||
),
|
||||
$datas,
|
||||
MASS_UPDATES_SKIP_EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
set_tags_of($tags_of);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array associating element id (images.id) with its complete
|
||||
* path in the filesystem
|
||||
*
|
||||
* @param int $category_id
|
||||
* @param int $site_id
|
||||
* @param boolean $recursive
|
||||
* @param boolean $only_new
|
||||
* @return array
|
||||
*/
|
||||
function get_filelist($category_id = '', $site_id=1, $recursive = false,
|
||||
$only_new = false)
|
||||
{
|
||||
// filling $cat_ids : all categories required
|
||||
$cat_ids = array();
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE site_id = '.$site_id.'
|
||||
AND dir IS NOT NULL';
|
||||
if (is_numeric($category_id))
|
||||
{
|
||||
if ($recursive)
|
||||
{
|
||||
$query.= '
|
||||
AND uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'
|
||||
';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= '
|
||||
AND id = '.$category_id.'
|
||||
';
|
||||
}
|
||||
}
|
||||
$query.= '
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$cat_ids[] = $row['id'];
|
||||
}
|
||||
|
||||
if (count($cat_ids) == 0)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id, path, representative_ext
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE storage_category_id IN ('.implode(',', $cat_ids).')';
|
||||
if ($only_new)
|
||||
{
|
||||
$query.= '
|
||||
AND date_metadata_update IS NULL
|
||||
';
|
||||
}
|
||||
$query.= '
|
||||
;';
|
||||
return hash_from_query($query, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of keywords (future tags) correctly separated with
|
||||
* commas. Other separators are converted into commas.
|
||||
*
|
||||
* @param string $keywords_string
|
||||
* @return string
|
||||
*/
|
||||
function metadata_normalize_keywords_string($keywords_string)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$keywords_string = preg_replace($conf['metadata_keyword_separator_regex'], ',', $keywords_string);
|
||||
// new lines are always considered as keyword separators
|
||||
$keywords_string = str_replace(array("\r\n", "\n", "\r"), ',', $keywords_string);
|
||||
$keywords_string = preg_replace('/,+/', ',', $keywords_string);
|
||||
$keywords_string = preg_replace('/^,+|,+$/', '', $keywords_string);
|
||||
|
||||
$keywords_string = implode(
|
||||
',',
|
||||
array_unique(
|
||||
explode(
|
||||
',',
|
||||
$keywords_string
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return $keywords_string;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,531 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/* nbm_global_var */
|
||||
$env_nbm = array
|
||||
(
|
||||
'start_time' => get_moment(),
|
||||
'sendmail_timeout' => (intval(ini_get('max_execution_time')) * $conf['nbm_max_treatment_timeout_percent']),
|
||||
'is_sendmail_timeout' => false
|
||||
);
|
||||
|
||||
if
|
||||
(
|
||||
(!isset($env_nbm['sendmail_timeout'])) or
|
||||
(!is_numeric($env_nbm['sendmail_timeout'])) or
|
||||
($env_nbm['sendmail_timeout'] <= 0)
|
||||
)
|
||||
{
|
||||
$env_nbm['sendmail_timeout'] = $conf['nbm_treatment_timeout_default'];
|
||||
}
|
||||
|
||||
/*
|
||||
* Search an available check_key
|
||||
*
|
||||
* It's a copy of function find_available_feed_id
|
||||
*
|
||||
* @return string nbm identifier
|
||||
*/
|
||||
function find_available_check_key()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
$key = generate_key(16);
|
||||
$query = '
|
||||
select
|
||||
count(*)
|
||||
from
|
||||
'.USER_MAIL_NOTIFICATION_TABLE.'
|
||||
where
|
||||
check_key = \''.$key.'\';';
|
||||
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($count == 0)
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check sendmail timeout state
|
||||
*
|
||||
* @return true, if it's timeout
|
||||
*/
|
||||
function check_sendmail_timeout()
|
||||
{
|
||||
global $env_nbm;
|
||||
|
||||
$env_nbm['is_sendmail_timeout'] = ((get_moment() - $env_nbm['start_time']) > $env_nbm['sendmail_timeout']);
|
||||
|
||||
return $env_nbm['is_sendmail_timeout'];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add quote to all elements of check_key_list
|
||||
*
|
||||
* @return quoted check key list
|
||||
*/
|
||||
function quote_check_key_list($check_key_list = array())
|
||||
{
|
||||
return array_map(function($s) { return '\''.$s.'\''; } , $check_key_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute all main queries to get list of user
|
||||
*
|
||||
* Type are the type of list 'subscribe', 'send'
|
||||
*
|
||||
* return array of users
|
||||
*/
|
||||
function get_user_notifications($action, $check_key_list = array(), $enabled_filter_value = '')
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$data_users = array();
|
||||
|
||||
if (in_array($action, array('subscribe', 'send')))
|
||||
{
|
||||
$quoted_check_key_list = quote_check_key_list($check_key_list);
|
||||
if (count($quoted_check_key_list) != 0 )
|
||||
{
|
||||
$query_and_check_key = ' and
|
||||
check_key in ('.implode(",", $quoted_check_key_list).') ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query_and_check_key = '';
|
||||
}
|
||||
|
||||
$query = '
|
||||
select
|
||||
N.user_id,
|
||||
N.check_key,
|
||||
U.'.$conf['user_fields']['username'].' as username,
|
||||
U.'.$conf['user_fields']['email'].' as mail_address,
|
||||
N.enabled,
|
||||
N.last_send,
|
||||
UI.status
|
||||
from '.USER_MAIL_NOTIFICATION_TABLE.' as N
|
||||
JOIN '.USERS_TABLE.' as U on N.user_id = U.'.$conf['user_fields']['id'].'
|
||||
JOIN '.USER_INFOS_TABLE.' as UI on UI.user_id = N.user_id
|
||||
where 1=1';
|
||||
|
||||
if ($action == 'send')
|
||||
{
|
||||
// No mail empty and all users enabled
|
||||
$query .= ' and
|
||||
N.enabled = \'true\' and
|
||||
U.'.$conf['user_fields']['email'].' is not null';
|
||||
}
|
||||
|
||||
$query .= $query_and_check_key;
|
||||
|
||||
if (isset($enabled_filter_value) and ($enabled_filter_value != ''))
|
||||
{
|
||||
$query .= ' and
|
||||
N.enabled = \''.boolean_to_string($enabled_filter_value).'\'';
|
||||
}
|
||||
|
||||
$query .= '
|
||||
order by';
|
||||
|
||||
if ($action == 'send')
|
||||
{
|
||||
$query .= '
|
||||
last_send, username;';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= '
|
||||
username';
|
||||
}
|
||||
|
||||
$query .= ';';
|
||||
|
||||
$result = pwg_query($query);
|
||||
if (!empty($result))
|
||||
{
|
||||
while ($nbm_user = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$data_users[] = $nbm_user;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data_users;
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin of use nbm environment
|
||||
* Prepare and save current environment and initialize data in order to send mail
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function begin_users_env_nbm($is_to_send_mail = false)
|
||||
{
|
||||
global $user, $lang, $lang_info, $conf, $env_nbm;
|
||||
|
||||
// Save $user, $lang_info and $lang arrays (include/user.inc.php has been executed)
|
||||
$env_nbm['save_user'] = $user;
|
||||
// Save current language to stack, necessary because $user change during NBM
|
||||
switch_lang_to($user['language']);
|
||||
|
||||
$env_nbm['is_to_send_mail'] = $is_to_send_mail;
|
||||
|
||||
if ($is_to_send_mail)
|
||||
{
|
||||
// Init mail configuration
|
||||
$env_nbm['email_format'] = get_str_email_format($conf['nbm_send_html_mail']);
|
||||
$env_nbm['send_as_name'] = ((isset($conf['nbm_send_mail_as']) and !empty($conf['nbm_send_mail_as'])) ? $conf['nbm_send_mail_as'] : get_mail_sender_name());
|
||||
$env_nbm['send_as_mail_address'] = get_webmaster_mail_address();
|
||||
$env_nbm['send_as_mail_formated'] = format_email($env_nbm['send_as_name'], $env_nbm['send_as_mail_address']);
|
||||
// Init mail counter
|
||||
$env_nbm['error_on_mail_count'] = 0;
|
||||
$env_nbm['sent_mail_count'] = 0;
|
||||
// Save sendmail message info and error in the original language
|
||||
$env_nbm['msg_info'] = l10n('Mail sent to %s [%s].');
|
||||
$env_nbm['msg_error'] = l10n('Error when sending email to %s [%s].');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* End of use nbm environment
|
||||
* Restore environment
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function end_users_env_nbm()
|
||||
{
|
||||
global $user, $lang, $lang_info, $env_nbm;
|
||||
|
||||
// Restore $user, $lang_info and $lang arrays (include/user.inc.php has been executed)
|
||||
$user = $env_nbm['save_user'];
|
||||
// Restore current language to stack, necessary because $user change during NBM
|
||||
switch_lang_back();
|
||||
|
||||
if ($env_nbm['is_to_send_mail'])
|
||||
{
|
||||
unset($env_nbm['email_format']);
|
||||
unset($env_nbm['send_as_name']);
|
||||
unset($env_nbm['send_as_mail_address']);
|
||||
unset($env_nbm['send_as_mail_formated']);
|
||||
// Don t unset counter
|
||||
//unset($env_nbm['error_on_mail_count']);
|
||||
//unset($env_nbm['sent_mail_count']);
|
||||
unset($env_nbm['msg_info']);
|
||||
unset($env_nbm['msg_error']);
|
||||
}
|
||||
|
||||
unset($env_nbm['save_user']);
|
||||
unset($env_nbm['is_to_send_mail']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set user on nbm enviromnent
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function set_user_on_env_nbm(&$nbm_user, $is_action_send)
|
||||
{
|
||||
global $user, $lang, $lang_info, $env_nbm;
|
||||
|
||||
$user = build_user( $nbm_user['user_id'], true );
|
||||
|
||||
switch_lang_to($user['language']);
|
||||
|
||||
if ($is_action_send)
|
||||
{
|
||||
$env_nbm['mail_template'] = get_mail_template($env_nbm['email_format']);
|
||||
$env_nbm['mail_template']->set_filename('notification_by_mail', 'notification_by_mail.tpl');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unset user on nbm enviromnent
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function unset_user_on_env_nbm()
|
||||
{
|
||||
global $env_nbm;
|
||||
|
||||
switch_lang_back();
|
||||
unset($env_nbm['mail_template']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inc Counter success
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function inc_mail_sent_success($nbm_user)
|
||||
{
|
||||
global $page, $env_nbm;
|
||||
|
||||
$env_nbm['sent_mail_count'] += 1;
|
||||
$page['infos'][] = sprintf($env_nbm['msg_info'], stripslashes($nbm_user['username']), $nbm_user['mail_address']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inc Counter failed
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function inc_mail_sent_failed($nbm_user)
|
||||
{
|
||||
global $page, $env_nbm;
|
||||
|
||||
$env_nbm['error_on_mail_count'] += 1;
|
||||
$page['errors'][] = sprintf($env_nbm['msg_error'], stripslashes($nbm_user['username']), $nbm_user['mail_address']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display Counter Info
|
||||
*
|
||||
* Return none
|
||||
*/
|
||||
function display_counter_info()
|
||||
{
|
||||
global $page, $env_nbm;
|
||||
|
||||
if ($env_nbm['error_on_mail_count'] != 0)
|
||||
{
|
||||
$page['errors'][] = l10n_dec(
|
||||
'%d mail was not sent.', '%d mails were not sent.',
|
||||
$env_nbm['error_on_mail_count']
|
||||
);
|
||||
|
||||
if ($env_nbm['sent_mail_count'] != 0)
|
||||
{
|
||||
$page['infos'][] = l10n_dec(
|
||||
'%d mail was sent.', '%d mails were sent.',
|
||||
$env_nbm['sent_mail_count']
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($env_nbm['sent_mail_count'] == 0)
|
||||
{
|
||||
$page['infos'][] = l10n('No mail to send.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['infos'][] = l10n_dec(
|
||||
'%d mail was sent.', '%d mails were sent.',
|
||||
$env_nbm['sent_mail_count']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assign_vars_nbm_mail_content($nbm_user)
|
||||
{
|
||||
global $env_nbm;
|
||||
|
||||
set_make_full_url();
|
||||
|
||||
$env_nbm['mail_template']->assign
|
||||
(
|
||||
array
|
||||
(
|
||||
'USERNAME' => stripslashes($nbm_user['username']),
|
||||
|
||||
'SEND_AS_NAME' => $env_nbm['send_as_name'],
|
||||
|
||||
'UNSUBSCRIBE_LINK' => add_url_params(get_gallery_home_url().'/nbm.php', array('unsubscribe' => $nbm_user['check_key'])),
|
||||
'SUBSCRIBE_LINK' => add_url_params(get_gallery_home_url().'/nbm.php', array('subscribe' => $nbm_user['check_key'])),
|
||||
'CONTACT_EMAIL' => $env_nbm['send_as_mail_address']
|
||||
)
|
||||
);
|
||||
|
||||
unset_make_full_url();
|
||||
}
|
||||
|
||||
/*
|
||||
* Subscribe or unsubscribe notification by mail
|
||||
*
|
||||
* is_subscribe define if action=subscribe or unsubscribe
|
||||
* check_key list where action will be done
|
||||
*
|
||||
* @return check_key list treated
|
||||
*/
|
||||
function do_subscribe_unsubscribe_notification_by_mail($is_admin_request, $is_subscribe = false, $check_key_list = array())
|
||||
{
|
||||
global $conf, $page, $env_nbm, $conf;
|
||||
|
||||
set_make_full_url();
|
||||
|
||||
$check_key_treated = array();
|
||||
$updated_data_count = 0;
|
||||
$error_on_updated_data_count = 0;
|
||||
|
||||
if ($is_subscribe)
|
||||
{
|
||||
$msg_info = l10n('User %s [%s] was added to the subscription list.');
|
||||
$msg_error = l10n('User %s [%s] was not added to the subscription list.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg_info = l10n('User %s [%s] was removed from the subscription list.');
|
||||
$msg_error = l10n('User %s [%s] was not removed from the subscription list.');
|
||||
}
|
||||
|
||||
if (count($check_key_list) != 0)
|
||||
{
|
||||
$updates = array();
|
||||
$enabled_value = boolean_to_string($is_subscribe);
|
||||
$data_users = get_user_notifications('subscribe', $check_key_list, !$is_subscribe);
|
||||
|
||||
// Prepare message after change language
|
||||
$msg_break_timeout = l10n('Time to send mail is limited. Others mails are skipped.');
|
||||
|
||||
// Begin nbm users environment
|
||||
begin_users_env_nbm(true);
|
||||
|
||||
foreach ($data_users as $nbm_user)
|
||||
{
|
||||
if (check_sendmail_timeout())
|
||||
{
|
||||
// Stop fill list on 'send', if the quota is override
|
||||
$page['errors'][] = $msg_break_timeout;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fill return list
|
||||
$check_key_treated[] = $nbm_user['check_key'];
|
||||
|
||||
$do_update = true;
|
||||
if ($nbm_user['mail_address'] != '')
|
||||
{
|
||||
// set env nbm user
|
||||
set_user_on_env_nbm($nbm_user, true);
|
||||
|
||||
$subject = '['.$conf['gallery_title'].'] '.($is_subscribe ? l10n('Subscribe to notification by mail'): l10n('Unsubscribe from notification by mail'));
|
||||
|
||||
// Assign current var for nbm mail
|
||||
assign_vars_nbm_mail_content($nbm_user);
|
||||
|
||||
$section_action_by = ($is_subscribe ? 'subscribe_by_' : 'unsubscribe_by_');
|
||||
$section_action_by .= ($is_admin_request ? 'admin' : 'himself');
|
||||
$env_nbm['mail_template']->assign
|
||||
(
|
||||
array
|
||||
(
|
||||
$section_action_by => true,
|
||||
'GOTO_GALLERY_TITLE' => $conf['gallery_title'],
|
||||
'GOTO_GALLERY_URL' => get_gallery_home_url(),
|
||||
)
|
||||
);
|
||||
|
||||
$ret = pwg_mail(
|
||||
array(
|
||||
'name' => stripslashes($nbm_user['username']),
|
||||
'email' => $nbm_user['mail_address'],
|
||||
),
|
||||
array(
|
||||
'from' => $env_nbm['send_as_mail_formated'],
|
||||
'subject' => $subject,
|
||||
'email_format' => $env_nbm['email_format'],
|
||||
'content' => $env_nbm['mail_template']->parse('notification_by_mail', true),
|
||||
'content_format' => $env_nbm['email_format'],
|
||||
)
|
||||
);
|
||||
|
||||
if ($ret)
|
||||
{
|
||||
inc_mail_sent_success($nbm_user);
|
||||
}
|
||||
else
|
||||
{
|
||||
inc_mail_sent_failed($nbm_user);
|
||||
$do_update = false;
|
||||
}
|
||||
|
||||
// unset env nbm user
|
||||
unset_user_on_env_nbm();
|
||||
|
||||
}
|
||||
|
||||
if ($do_update)
|
||||
{
|
||||
$updates[] = array(
|
||||
'check_key' => $nbm_user['check_key'],
|
||||
'enabled' => $enabled_value
|
||||
);
|
||||
$updated_data_count += 1;
|
||||
$page['infos'][] = sprintf($msg_info, stripslashes($nbm_user['username']), $nbm_user['mail_address']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$error_on_updated_data_count += 1;
|
||||
$page['errors'][] = sprintf($msg_error, stripslashes($nbm_user['username']), $nbm_user['mail_address']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Restore nbm environment
|
||||
end_users_env_nbm();
|
||||
|
||||
display_counter_info();
|
||||
|
||||
mass_updates(
|
||||
USER_MAIL_NOTIFICATION_TABLE,
|
||||
array(
|
||||
'primary' => array('check_key'),
|
||||
'update' => array('enabled')
|
||||
),
|
||||
$updates
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
$page['infos'][] = l10n_dec(
|
||||
'%d user was updated.', '%d users were updated.',
|
||||
$updated_data_count
|
||||
);
|
||||
|
||||
if ($error_on_updated_data_count != 0)
|
||||
{
|
||||
$page['errors'][] = l10n_dec(
|
||||
'%d user was not updated.', '%d users were not updated.',
|
||||
$error_on_updated_data_count
|
||||
);
|
||||
}
|
||||
|
||||
unset_make_full_url();
|
||||
|
||||
return $check_key_treated;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsubscribe notification by mail
|
||||
*
|
||||
* check_key list where action will be done
|
||||
*
|
||||
* @return check_key list treated
|
||||
*/
|
||||
function unsubscribe_notification_by_mail($is_admin_request, $check_key_list = array())
|
||||
{
|
||||
return do_subscribe_unsubscribe_notification_by_mail($is_admin_request, false, $check_key_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Subscribe notification by mail
|
||||
*
|
||||
* check_key list where action will be done
|
||||
*
|
||||
* @return check_key list treated
|
||||
*/
|
||||
function subscribe_notification_by_mail($is_admin_request, $check_key_list = array())
|
||||
{
|
||||
return do_subscribe_unsubscribe_notification_by_mail($is_admin_request, true, $check_key_list);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,189 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/** returns a category id that corresponds to the given permalink (or null)
|
||||
* @param string permalink
|
||||
*/
|
||||
function get_cat_id_from_permalink( $permalink )
|
||||
{
|
||||
$query ='
|
||||
SELECT id FROM '.CATEGORIES_TABLE.'
|
||||
WHERE permalink=\''.$permalink.'\'';
|
||||
$ids = array_from_query($query, 'id');
|
||||
if (!empty($ids))
|
||||
{
|
||||
return $ids[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** returns a category id that has used before this permalink (or null)
|
||||
* @param string permalink
|
||||
* @param boolean is_hit if true update the usage counters on the old permalinks
|
||||
*/
|
||||
function get_cat_id_from_old_permalink($permalink)
|
||||
{
|
||||
$query='
|
||||
SELECT c.id
|
||||
FROM '.OLD_PERMALINKS_TABLE.' op INNER JOIN '.CATEGORIES_TABLE.' c
|
||||
ON op.cat_id=c.id
|
||||
WHERE op.permalink=\''.$permalink.'\'
|
||||
LIMIT 1';
|
||||
$result = pwg_query($query);
|
||||
$cat_id = null;
|
||||
if ( pwg_db_num_rows($result) )
|
||||
list( $cat_id ) = pwg_db_fetch_row($result);
|
||||
return $cat_id;
|
||||
}
|
||||
|
||||
|
||||
/** deletes the permalink associated with a category
|
||||
* returns true on success
|
||||
* @param int cat_id the target category id
|
||||
* @param boolean save if true, the current category-permalink association
|
||||
* is saved in the old permalinks table in case external links hit it
|
||||
*/
|
||||
function delete_cat_permalink( $cat_id, $save )
|
||||
{
|
||||
global $page, $cache;
|
||||
$query = '
|
||||
SELECT permalink
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id=\''.$cat_id.'\'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if ( pwg_db_num_rows($result) )
|
||||
{
|
||||
list($permalink) = pwg_db_fetch_row($result);
|
||||
}
|
||||
if ( !isset($permalink) )
|
||||
{// no permalink; nothing to do
|
||||
return true;
|
||||
}
|
||||
if ($save)
|
||||
{
|
||||
$old_cat_id = get_cat_id_from_old_permalink($permalink);
|
||||
if ( isset($old_cat_id) and $old_cat_id!=$cat_id )
|
||||
{
|
||||
$page['errors'][] =
|
||||
sprintf(
|
||||
l10n('Permalink %s has been previously used by album %s. Delete from the permalink history first'),
|
||||
$permalink, $old_cat_id
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET permalink=NULL
|
||||
WHERE id='.$cat_id.'
|
||||
LIMIT 1';
|
||||
pwg_query($query);
|
||||
|
||||
unset( $cache['cat_names'] ); //force regeneration
|
||||
if ($save)
|
||||
{
|
||||
if ( isset($old_cat_id) )
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.OLD_PERMALINKS_TABLE.'
|
||||
SET date_deleted=NOW()
|
||||
WHERE cat_id='.$cat_id.' AND permalink=\''.$permalink.'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '.OLD_PERMALINKS_TABLE.'
|
||||
(permalink, cat_id, date_deleted)
|
||||
VALUES
|
||||
( \''.$permalink.'\','.$cat_id.',NOW() )';
|
||||
}
|
||||
pwg_query( $query );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** sets a new permalink for a category
|
||||
* returns true on success
|
||||
* @param int cat_id the target category id
|
||||
* @param string permalink the new permalink
|
||||
* @param boolean save if true, the current category-permalink association
|
||||
* is saved in the old permalinks table in case external links hit it
|
||||
*/
|
||||
function set_cat_permalink( $cat_id, $permalink, $save )
|
||||
{
|
||||
global $page, $cache;
|
||||
|
||||
$sanitized_permalink = preg_replace( '#[^a-zA-Z0-9_/-]#', '' ,$permalink);
|
||||
$sanitized_permalink = trim($sanitized_permalink, '/');
|
||||
$sanitized_permalink = str_replace('//', '/', $sanitized_permalink);
|
||||
if ( $sanitized_permalink != $permalink
|
||||
or preg_match( '#^(\d)+(-.*)?$#', $permalink) )
|
||||
{
|
||||
$page['errors'][] = '{'.$permalink.'} '.l10n('The permalink name must be composed of a-z, A-Z, 0-9, "-", "_" or "/". It must not be numeric or start with number followed by "-"');
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the new permalink is actively used
|
||||
$existing_cat_id = get_cat_id_from_permalink( $permalink );
|
||||
if ( isset($existing_cat_id) )
|
||||
{
|
||||
if ( $existing_cat_id==$cat_id )
|
||||
{// no change required
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] =
|
||||
sprintf(
|
||||
l10n('Permalink %s is already used by album %s'),
|
||||
$permalink, $existing_cat_id
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if the new permalink was historically used
|
||||
$old_cat_id = get_cat_id_from_old_permalink($permalink);
|
||||
if ( isset($old_cat_id) and $old_cat_id!=$cat_id )
|
||||
{
|
||||
$page['errors'][] =
|
||||
sprintf(
|
||||
l10n('Permalink %s has been previously used by album %s. Delete from the permalink history first'),
|
||||
$permalink, $old_cat_id
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !delete_cat_permalink($cat_id, $save ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset($old_cat_id) )
|
||||
{// the new permalink must not be active and old at the same time
|
||||
assert( $old_cat_id==$cat_id );
|
||||
$query = '
|
||||
DELETE FROM '.OLD_PERMALINKS_TABLE.'
|
||||
WHERE cat_id='.$old_cat_id.' AND permalink=\''.$permalink.'\'';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET permalink=\''.$permalink.'\'
|
||||
WHERE id='.$cat_id;
|
||||
// LIMIT 1';
|
||||
pwg_query($query);
|
||||
|
||||
unset( $cache['cat_names'] ); //force regeneration
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Retrieves an url for a plugin page.
|
||||
* @param string file - php script full name
|
||||
*/
|
||||
function get_admin_plugin_menu_link($file)
|
||||
{
|
||||
global $page;
|
||||
$real_file = realpath($file);
|
||||
$url = get_root_url().'admin.php?page=plugin';
|
||||
if (false!==$real_file)
|
||||
{
|
||||
$real_plugin_path = rtrim(realpath(PHPWG_PLUGINS_PATH), '\\/');
|
||||
$file = substr($real_file, strlen($real_plugin_path)+1);
|
||||
$file = str_replace('\\', '/', $file);//Windows
|
||||
$url .= '&section='.urlencode($file);
|
||||
}
|
||||
else if (isset($page['errors']))
|
||||
{
|
||||
$page['errors'][] = 'PLUGIN ERROR: "'.$file.'" is not a valid file';
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,322 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
function check_upgrade()
|
||||
{
|
||||
if (defined('PHPWG_IN_UPGRADE'))
|
||||
{
|
||||
return PHPWG_IN_UPGRADE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// concerning upgrade, we use the default tables
|
||||
function prepare_conf_upgrade()
|
||||
{
|
||||
global $prefixeTable;
|
||||
|
||||
// $conf is not used for users tables
|
||||
// define cannot be re-defined
|
||||
define('CATEGORIES_TABLE', $prefixeTable.'categories');
|
||||
define('COMMENTS_TABLE', $prefixeTable.'comments');
|
||||
define('CONFIG_TABLE', $prefixeTable.'config');
|
||||
define('FAVORITES_TABLE', $prefixeTable.'favorites');
|
||||
define('GROUP_ACCESS_TABLE', $prefixeTable.'group_access');
|
||||
define('GROUPS_TABLE', $prefixeTable.'groups');
|
||||
define('HISTORY_TABLE', $prefixeTable.'history');
|
||||
define('HISTORY_SUMMARY_TABLE', $prefixeTable.'history_summary');
|
||||
define('IMAGE_CATEGORY_TABLE', $prefixeTable.'image_category');
|
||||
define('IMAGES_TABLE', $prefixeTable.'images');
|
||||
define('SESSIONS_TABLE', $prefixeTable.'sessions');
|
||||
define('SITES_TABLE', $prefixeTable.'sites');
|
||||
define('USER_ACCESS_TABLE', $prefixeTable.'user_access');
|
||||
define('USER_GROUP_TABLE', $prefixeTable.'user_group');
|
||||
define('USERS_TABLE', $prefixeTable.'users');
|
||||
define('USER_INFOS_TABLE', $prefixeTable.'user_infos');
|
||||
define('USER_FEED_TABLE', $prefixeTable.'user_feed');
|
||||
define('RATE_TABLE', $prefixeTable.'rate');
|
||||
define('USER_CACHE_TABLE', $prefixeTable.'user_cache');
|
||||
define('USER_CACHE_CATEGORIES_TABLE', $prefixeTable.'user_cache_categories');
|
||||
define('CADDIE_TABLE', $prefixeTable.'caddie');
|
||||
define('UPGRADE_TABLE', $prefixeTable.'upgrade');
|
||||
define('SEARCH_TABLE', $prefixeTable.'search');
|
||||
define('USER_MAIL_NOTIFICATION_TABLE', $prefixeTable.'user_mail_notification');
|
||||
define('TAGS_TABLE', $prefixeTable.'tags');
|
||||
define('IMAGE_TAG_TABLE', $prefixeTable.'image_tag');
|
||||
define('PLUGINS_TABLE', $prefixeTable.'plugins');
|
||||
define('OLD_PERMALINKS_TABLE', $prefixeTable.'old_permalinks');
|
||||
define('THEMES_TABLE', $prefixeTable.'themes');
|
||||
define('LANGUAGES_TABLE', $prefixeTable.'languages');
|
||||
}
|
||||
|
||||
// Deactivate all non-standard plugins
|
||||
function deactivate_non_standard_plugins()
|
||||
{
|
||||
global $page;
|
||||
|
||||
$standard_plugins = array(
|
||||
'AdminTools',
|
||||
'TakeATour',
|
||||
'language_switch',
|
||||
'LocalFilesEditor'
|
||||
);
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.PREFIX_TABLE.'plugins
|
||||
WHERE state = \'active\'
|
||||
AND id NOT IN (\'' . implode('\',\'', $standard_plugins) . '\')
|
||||
;';
|
||||
|
||||
$result = pwg_query($query);
|
||||
$plugins = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$plugins[] = $row['id'];
|
||||
}
|
||||
|
||||
if (!empty($plugins))
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.PREFIX_TABLE.'plugins
|
||||
SET state=\'inactive\'
|
||||
WHERE id IN (\'' . implode('\',\'', $plugins) . '\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$page['infos'][] = l10n('As a precaution, following plugins have been deactivated. You must check for plugins upgrade before reactiving them:')
|
||||
.'<p><i>'.implode(', ', $plugins).'</i></p>';
|
||||
}
|
||||
}
|
||||
|
||||
// Deactivate all non-standard themes
|
||||
function deactivate_non_standard_themes()
|
||||
{
|
||||
global $page, $conf;
|
||||
|
||||
$standard_themes = array(
|
||||
'modus',
|
||||
'elegant',
|
||||
'smartpocket',
|
||||
);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
name
|
||||
FROM '.PREFIX_TABLE.'themes
|
||||
WHERE id NOT IN (\''.implode("','", $standard_themes).'\')
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
$theme_ids = array();
|
||||
$theme_names = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$theme_ids[] = $row['id'];
|
||||
$theme_names[] = $row['name'];
|
||||
}
|
||||
|
||||
if (!empty($theme_ids))
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.PREFIX_TABLE.'themes
|
||||
WHERE id IN (\''.implode("','", $theme_ids).'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$page['infos'][] = l10n('As a precaution, following themes have been deactivated. You must check for themes upgrade before reactiving them:')
|
||||
.'<p><i>'.implode(', ', $theme_names).'</i></p>';
|
||||
|
||||
// what is the default theme?
|
||||
$query = '
|
||||
SELECT theme
|
||||
FROM '.PREFIX_TABLE.'user_infos
|
||||
WHERE user_id = '.$conf['default_user_id'].'
|
||||
;';
|
||||
list($default_theme) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
// if the default theme has just been deactivated, let's set another core theme as default
|
||||
if (in_array($default_theme, $theme_ids))
|
||||
{
|
||||
// make sure default Piwigo theme is active
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.PREFIX_TABLE.'themes
|
||||
WHERE id = \''.PHPWG_DEFAULT_TEMPLATE.'\'
|
||||
;';
|
||||
list($counter) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($counter < 1)
|
||||
{
|
||||
// we need to activate theme first
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/themes.class.php');
|
||||
$themes = new themes();
|
||||
$themes->perform_action('activate', PHPWG_DEFAULT_TEMPLATE);
|
||||
}
|
||||
|
||||
// then associate it to default user
|
||||
$query = '
|
||||
UPDATE '.PREFIX_TABLE.'user_infos
|
||||
SET theme = \''.PHPWG_DEFAULT_TEMPLATE.'\'
|
||||
WHERE user_id = '.$conf['default_user_id'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deactivate all templates
|
||||
function deactivate_templates()
|
||||
{
|
||||
conf_update_param('extents_for_templates', array());
|
||||
}
|
||||
|
||||
// Check access rights
|
||||
function check_upgrade_access_rights()
|
||||
{
|
||||
global $conf, $page, $current_release;
|
||||
|
||||
if (version_compare($current_release, '2.0', '>=') and isset($_COOKIE[session_name()]))
|
||||
{
|
||||
// Check if user is already connected as webmaster
|
||||
session_start();
|
||||
if (!empty($_SESSION['pwg_uid']))
|
||||
{
|
||||
$query = '
|
||||
SELECT status
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE user_id = '.$_SESSION['pwg_uid'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$row = pwg_db_fetch_assoc(pwg_query($query));
|
||||
if (isset($row['status']) and $row['status'] == 'webmaster')
|
||||
{
|
||||
define('PHPWG_IN_UPGRADE', true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($_POST['username']) or !isset($_POST['password']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$username = $_POST['username'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
if(function_exists('get_magic_quotes_gpc') && !@get_magic_quotes_gpc() )
|
||||
{
|
||||
$username = pwg_db_real_escape_string($username);
|
||||
}
|
||||
|
||||
if (version_compare($current_release, '2.0', '<'))
|
||||
{
|
||||
$username = utf8_decode($username);
|
||||
$password = utf8_decode($password);
|
||||
}
|
||||
|
||||
if (version_compare($current_release, '1.5', '<'))
|
||||
{
|
||||
$query = '
|
||||
SELECT password, status
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE username = \''.$username.'\'
|
||||
;';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = '
|
||||
SELECT u.password, ui.status
|
||||
FROM '.USERS_TABLE.' AS u
|
||||
INNER JOIN '.USER_INFOS_TABLE.' AS ui
|
||||
ON u.'.$conf['user_fields']['id'].'=ui.user_id
|
||||
WHERE '.$conf['user_fields']['username'].'=\''.$username.'\'
|
||||
;';
|
||||
}
|
||||
$row = pwg_db_fetch_assoc(pwg_query($query));
|
||||
|
||||
if (!$conf['password_verify']($password, $row['password']))
|
||||
{
|
||||
$page['errors'][] = l10n('Invalid password!');
|
||||
}
|
||||
elseif ($row['status'] != 'admin' and $row['status'] != 'webmaster')
|
||||
{
|
||||
$page['errors'][] = l10n('You do not have access rights to run upgrade');
|
||||
}
|
||||
else
|
||||
{
|
||||
define('PHPWG_IN_UPGRADE', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* which upgrades are available ?
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_available_upgrade_ids()
|
||||
{
|
||||
$upgrades_path = PHPWG_ROOT_PATH.'install/db';
|
||||
|
||||
$available_upgrade_ids = array();
|
||||
|
||||
if ($contents = opendir($upgrades_path))
|
||||
{
|
||||
while (($node = readdir($contents)) !== false)
|
||||
{
|
||||
if (is_file($upgrades_path.'/'.$node)
|
||||
and preg_match('/^(.*?)-database\.php$/', $node, $match))
|
||||
{
|
||||
$available_upgrade_ids[] = $match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
natcasesort($available_upgrade_ids);
|
||||
|
||||
return $available_upgrade_ids;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns true if there are available upgrade files
|
||||
*/
|
||||
function check_upgrade_feed()
|
||||
{
|
||||
// retrieve already applied upgrades
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.UPGRADE_TABLE.'
|
||||
;';
|
||||
$applied = array_from_query($query, 'id');
|
||||
|
||||
// retrieve existing upgrades
|
||||
$existing = get_available_upgrade_ids();
|
||||
|
||||
// which upgrades need to be applied?
|
||||
return (count(array_diff($existing, $applied)) > 0);
|
||||
}
|
||||
|
||||
function upgrade_db_connect()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
try
|
||||
{
|
||||
pwg_db_connect($conf['db_host'], $conf['db_user'],
|
||||
$conf['db_password'], $conf['db_base']);
|
||||
pwg_db_check_version();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
my_error(l10n($e->getMessage()), true);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,926 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Image Interface |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Define all needed methods for image class
|
||||
interface imageInterface
|
||||
{
|
||||
function get_width();
|
||||
|
||||
function get_height();
|
||||
|
||||
function set_compression_quality($quality);
|
||||
|
||||
function crop($width, $height, $x, $y);
|
||||
|
||||
function strip();
|
||||
|
||||
function rotate($rotation);
|
||||
|
||||
function resize($width, $height);
|
||||
|
||||
function sharpen($amount);
|
||||
|
||||
function compose($overlay, $x, $y, $opacity);
|
||||
|
||||
function write($destination_filepath);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Main Image Class |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class pwg_image
|
||||
{
|
||||
var $image;
|
||||
var $library = '';
|
||||
var $source_filepath = '';
|
||||
static $ext_imagick_version = '';
|
||||
|
||||
function __construct($source_filepath, $library=null)
|
||||
{
|
||||
global $conf;
|
||||
$this->source_filepath = $source_filepath;
|
||||
|
||||
trigger_notify('load_image_library', array(&$this) );
|
||||
|
||||
if (is_object($this->image))
|
||||
{
|
||||
return; // A plugin may have load its own library
|
||||
}
|
||||
|
||||
$extension = strtolower(get_extension($source_filepath));
|
||||
|
||||
if (!in_array($extension, $conf['picture_ext']))
|
||||
{
|
||||
die('[Image] unsupported file extension');
|
||||
}
|
||||
|
||||
if (!($this->library = self::get_library($library, $extension)))
|
||||
{
|
||||
die('No image library available on your server.');
|
||||
}
|
||||
|
||||
$class = 'image_'.$this->library;
|
||||
$this->image = new $class($source_filepath);
|
||||
}
|
||||
|
||||
// Unknow methods will be redirected to image object
|
||||
function __call($method, $arguments)
|
||||
{
|
||||
return call_user_func_array(array($this->image, $method), $arguments);
|
||||
}
|
||||
|
||||
// Piwigo resize function
|
||||
function pwg_resize($destination_filepath, $max_width, $max_height, $quality, $automatic_rotation=true, $strip_metadata=false, $crop=false, $follow_orientation=true)
|
||||
{
|
||||
$starttime = get_moment();
|
||||
|
||||
// width/height
|
||||
$source_width = $this->image->get_width();
|
||||
$source_height = $this->image->get_height();
|
||||
|
||||
$rotation = null;
|
||||
if ($automatic_rotation)
|
||||
{
|
||||
$rotation = self::get_rotation_angle($this->source_filepath);
|
||||
}
|
||||
$resize_dimensions = self::get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation, $crop, $follow_orientation);
|
||||
|
||||
// testing on height is useless in theory: if width is unchanged, there
|
||||
// should be no resize, because width/height ratio is not modified.
|
||||
if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height)
|
||||
{
|
||||
// the image doesn't need any resize! We just copy it to the destination
|
||||
copy($this->source_filepath, $destination_filepath);
|
||||
return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
|
||||
}
|
||||
|
||||
$this->image->set_compression_quality($quality);
|
||||
|
||||
if ($strip_metadata)
|
||||
{
|
||||
// we save a few kilobytes. For example a thumbnail with metadata weights 25KB, without metadata 7KB.
|
||||
$this->image->strip();
|
||||
}
|
||||
|
||||
if (isset($resize_dimensions['crop']))
|
||||
{
|
||||
$this->image->crop($resize_dimensions['crop']['width'], $resize_dimensions['crop']['height'], $resize_dimensions['crop']['x'], $resize_dimensions['crop']['y']);
|
||||
}
|
||||
|
||||
$this->image->resize($resize_dimensions['width'], $resize_dimensions['height']);
|
||||
|
||||
if (!empty($rotation))
|
||||
{
|
||||
$this->image->rotate($rotation);
|
||||
}
|
||||
|
||||
$this->image->write($destination_filepath);
|
||||
|
||||
// everything should be OK if we are here!
|
||||
return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
|
||||
}
|
||||
|
||||
static function get_resize_dimensions($width, $height, $max_width, $max_height, $rotation=null, $crop=false, $follow_orientation=true)
|
||||
{
|
||||
$rotate_for_dimensions = false;
|
||||
if (isset($rotation) and in_array(abs($rotation), array(90, 270)))
|
||||
{
|
||||
$rotate_for_dimensions = true;
|
||||
}
|
||||
|
||||
if ($rotate_for_dimensions)
|
||||
{
|
||||
list($width, $height) = array($height, $width);
|
||||
}
|
||||
|
||||
if ($crop)
|
||||
{
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
|
||||
if ($width < $height and $follow_orientation)
|
||||
{
|
||||
list($max_width, $max_height) = array($max_height, $max_width);
|
||||
}
|
||||
|
||||
$img_ratio = $width / $height;
|
||||
$dest_ratio = $max_width / $max_height;
|
||||
|
||||
if($dest_ratio > $img_ratio)
|
||||
{
|
||||
$destHeight = round($width * $max_height / $max_width);
|
||||
$y = round(($height - $destHeight) / 2 );
|
||||
$height = $destHeight;
|
||||
}
|
||||
elseif ($dest_ratio < $img_ratio)
|
||||
{
|
||||
$destWidth = round($height * $max_width / $max_height);
|
||||
$x = round(($width - $destWidth) / 2 );
|
||||
$width = $destWidth;
|
||||
}
|
||||
}
|
||||
|
||||
$ratio_width = $width / $max_width;
|
||||
$ratio_height = $height / $max_height;
|
||||
$destination_width = $width;
|
||||
$destination_height = $height;
|
||||
|
||||
// maximal size exceeded ?
|
||||
if ($ratio_width > 1 or $ratio_height > 1)
|
||||
{
|
||||
if ($ratio_width < $ratio_height)
|
||||
{
|
||||
$destination_width = round($width / $ratio_height);
|
||||
$destination_height = $max_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
$destination_width = $max_width;
|
||||
$destination_height = round($height / $ratio_width);
|
||||
}
|
||||
}
|
||||
|
||||
if ($rotate_for_dimensions)
|
||||
{
|
||||
list($destination_width, $destination_height) = array($destination_height, $destination_width);
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'width' => $destination_width,
|
||||
'height'=> $destination_height,
|
||||
);
|
||||
|
||||
if ($crop and ($x or $y))
|
||||
{
|
||||
$result['crop'] = array(
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'x' => $x,
|
||||
'y' => $y,
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function webp_info($source_filepath)
|
||||
{
|
||||
// function based on https://stackoverflow.com/questions/61221874/detect-if-a-webp-image-is-transparent-in-php
|
||||
//
|
||||
// https://github.com/webmproject/libwebp/blob/master/src/dec/webp_dec.c
|
||||
// https://developers.google.com/speed/webp/docs/riff_container
|
||||
// https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification
|
||||
// https://stackoverflow.com/questions/61221874/detect-if-a-webp-image-is-transparent-in-php
|
||||
|
||||
$fp = fopen($source_filepath, 'rb');
|
||||
if (!$fp) {
|
||||
throw new Exception("webp_info(): fopen($f): Failed");
|
||||
}
|
||||
$buf = fread($fp, 25);
|
||||
fclose($fp);
|
||||
|
||||
switch (true) {
|
||||
case!is_string($buf):
|
||||
case strlen($buf) < 25:
|
||||
case substr($buf, 0, 4) != 'RIFF':
|
||||
case substr($buf, 8, 4) != 'WEBP':
|
||||
case substr($buf, 12, 3) != 'VP8':
|
||||
throw new Exception("webp_info(): not a valid webp image");
|
||||
|
||||
case $buf[15] == ' ':
|
||||
// Simple File Format (Lossy)
|
||||
return array(
|
||||
'type' => 'VP8',
|
||||
'has-animation' => false,
|
||||
'has-transparent' => false,
|
||||
);
|
||||
|
||||
|
||||
case $buf[15] == 'L':
|
||||
// Simple File Format (Lossless)
|
||||
return array(
|
||||
'type' => 'VP8L',
|
||||
'has-animation' => false,
|
||||
'has-transparent' => (bool) (!!(ord($buf[24]) & 0x00000010)),
|
||||
);
|
||||
|
||||
case $buf[15] == 'X':
|
||||
// Extended File Format
|
||||
return array(
|
||||
'type' => 'VP8X',
|
||||
'has-animation' => (bool) (!!(ord($buf[20]) & 0x00000002)),
|
||||
'has-transparent' => (bool) (!!(ord($buf[20]) & 0x00000010)),
|
||||
);
|
||||
|
||||
default:
|
||||
throw new Exception("webp_info(): could not detect webp type");
|
||||
}
|
||||
}
|
||||
|
||||
static function get_rotation_angle($source_filepath)
|
||||
{
|
||||
list($width, $height, $type) = getimagesize($source_filepath);
|
||||
if (IMAGETYPE_JPEG != $type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!function_exists('exif_read_data'))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$rotation = 0;
|
||||
|
||||
$exif = @exif_read_data($source_filepath);
|
||||
|
||||
if (isset($exif['Orientation']) and preg_match('/^\s*(\d)/', $exif['Orientation'], $matches))
|
||||
{
|
||||
$orientation = $matches[1];
|
||||
if (in_array($orientation, array(3, 4)))
|
||||
{
|
||||
$rotation = 180;
|
||||
}
|
||||
elseif (in_array($orientation, array(5, 6)))
|
||||
{
|
||||
$rotation = 270;
|
||||
}
|
||||
elseif (in_array($orientation, array(7, 8)))
|
||||
{
|
||||
$rotation = 90;
|
||||
}
|
||||
}
|
||||
|
||||
return $rotation;
|
||||
}
|
||||
|
||||
static function get_rotation_code_from_angle($rotation_angle)
|
||||
{
|
||||
switch($rotation_angle)
|
||||
{
|
||||
case 0: return 0;
|
||||
case 90: return 1;
|
||||
case 180: return 2;
|
||||
case 270: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
static function get_rotation_angle_from_code($rotation_code)
|
||||
{
|
||||
switch($rotation_code%4)
|
||||
{
|
||||
case 0: return 0;
|
||||
case 1: return 90;
|
||||
case 2: return 180;
|
||||
case 3: return 270;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a normalized convolution kernel for sharpening*/
|
||||
static function get_sharpen_matrix($amount)
|
||||
{
|
||||
// Amount should be in the range of 48-10
|
||||
$amount = round(abs(-48 + ($amount * 0.38)), 2);
|
||||
|
||||
$matrix = array(
|
||||
array(-1, -1, -1),
|
||||
array(-1, $amount, -1),
|
||||
array(-1, -1, -1),
|
||||
);
|
||||
|
||||
$norm = array_sum(array_map('array_sum', $matrix));
|
||||
|
||||
for ($i=0; $i<3; $i++)
|
||||
{
|
||||
for ($j=0; $j<3; $j++)
|
||||
{
|
||||
$matrix[$i][$j] /= $norm;
|
||||
}
|
||||
}
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
protected function get_resize_result($destination_filepath, $width, $height, $time=null)
|
||||
{
|
||||
return array(
|
||||
'source' => $this->source_filepath,
|
||||
'destination' => $destination_filepath,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'size' => floor(filesize($destination_filepath) / 1024).' KB',
|
||||
'time' => $time ? number_format((get_moment() - $time) * 1000, 2, '.', ' ').' ms' : null,
|
||||
'library' => $this->library,
|
||||
);
|
||||
}
|
||||
|
||||
static function is_imagick()
|
||||
{
|
||||
return (extension_loaded('imagick') and class_exists('Imagick'));
|
||||
}
|
||||
|
||||
static function get_ext_imagick_command()
|
||||
{
|
||||
global $page, $conf;
|
||||
|
||||
if (!isset($page['ext_imagick_command']))
|
||||
{
|
||||
$retval=null;
|
||||
$cmd_out=null;
|
||||
// check if magick is in path
|
||||
exec('command -v '.$conf['ext_imagick_dir'].'magick', $cmd_out , $retval );
|
||||
if (0 == $retval)
|
||||
{
|
||||
$page['ext_imagick_command'] = 'magick';
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['ext_imagick_command'] = 'convert';
|
||||
}
|
||||
}
|
||||
|
||||
return $page['ext_imagick_command'];
|
||||
}
|
||||
|
||||
static function is_ext_imagick()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!function_exists('exec'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@exec($conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command().' -version', $returnarray);
|
||||
if (is_array($returnarray) and !empty($returnarray[0]) and preg_match('/ImageMagick/i', $returnarray[0]))
|
||||
{
|
||||
if (preg_match('/Version: ImageMagick (\d+\.\d+\.\d+-?\d*)/', $returnarray[0], $match))
|
||||
{
|
||||
self::$ext_imagick_version = $match[1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function is_gd()
|
||||
{
|
||||
return function_exists('gd_info');
|
||||
}
|
||||
|
||||
static function get_library($library=null, $extension=null)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (is_null($library))
|
||||
{
|
||||
$library = $conf['graphics_library'];
|
||||
}
|
||||
|
||||
// Choose image library
|
||||
switch (strtolower($library))
|
||||
{
|
||||
case 'auto':
|
||||
case 'ext_imagick':
|
||||
if ($extension != 'gif' and self::is_ext_imagick())
|
||||
{
|
||||
return 'ext_imagick';
|
||||
}
|
||||
case 'imagick':
|
||||
if ($extension != 'gif' and self::is_imagick())
|
||||
{
|
||||
return 'imagick';
|
||||
}
|
||||
case 'gd':
|
||||
if (self::is_gd())
|
||||
{
|
||||
return 'gd';
|
||||
}
|
||||
default:
|
||||
if ($library != 'auto')
|
||||
{
|
||||
// Requested library not available. Try another library
|
||||
return self::get_library('auto', $extension);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function destroy()
|
||||
{
|
||||
if (method_exists($this->image, 'destroy'))
|
||||
{
|
||||
return $this->image->destroy();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Class for Imagick extension |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class image_imagick implements imageInterface
|
||||
{
|
||||
var $image;
|
||||
|
||||
function __construct($source_filepath)
|
||||
{
|
||||
// A bug cause that Imagick class can not be extended
|
||||
$this->image = new Imagick($source_filepath);
|
||||
}
|
||||
|
||||
function get_width()
|
||||
{
|
||||
return $this->image->getImageWidth();
|
||||
}
|
||||
|
||||
function get_height()
|
||||
{
|
||||
return $this->image->getImageHeight();
|
||||
}
|
||||
|
||||
function set_compression_quality($quality)
|
||||
{
|
||||
return $this->image->setImageCompressionQuality($quality);
|
||||
}
|
||||
|
||||
function crop($width, $height, $x, $y)
|
||||
{
|
||||
return $this->image->cropImage($width, $height, $x, $y);
|
||||
}
|
||||
|
||||
function strip()
|
||||
{
|
||||
return $this->image->stripImage();
|
||||
}
|
||||
|
||||
function rotate($rotation)
|
||||
{
|
||||
$this->image->rotateImage(new ImagickPixel(), -$rotation);
|
||||
$this->image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
|
||||
return true;
|
||||
}
|
||||
|
||||
function resize($width, $height)
|
||||
{
|
||||
$this->image->setInterlaceScheme(Imagick::INTERLACE_LINE);
|
||||
|
||||
// TODO need to explain this condition
|
||||
if ($this->get_width()%2 == 0
|
||||
&& $this->get_height()%2 == 0
|
||||
&& $this->get_width() > 3*$width)
|
||||
{
|
||||
$this->image->scaleImage($this->get_width()/2, $this->get_height()/2);
|
||||
}
|
||||
|
||||
return $this->image->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 0.9);
|
||||
}
|
||||
|
||||
function sharpen($amount)
|
||||
{
|
||||
$m = pwg_image::get_sharpen_matrix($amount);
|
||||
return $this->image->convolveImage($m);
|
||||
}
|
||||
|
||||
function compose($overlay, $x, $y, $opacity)
|
||||
{
|
||||
$ioverlay = $overlay->image->image;
|
||||
/*if ($ioverlay->getImageAlphaChannel() !== Imagick::ALPHACHANNEL_OPAQUE)
|
||||
{
|
||||
// Force the image to have an alpha channel
|
||||
$ioverlay->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
|
||||
}*/
|
||||
|
||||
global $dirty_trick_xrepeat;
|
||||
if ( !isset($dirty_trick_xrepeat) && $opacity < 100)
|
||||
{// NOTE: Using setImageOpacity will destroy current alpha channels!
|
||||
$ioverlay->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity / 100, Imagick::CHANNEL_ALPHA);
|
||||
$dirty_trick_xrepeat = true;
|
||||
}
|
||||
|
||||
return $this->image->compositeImage($ioverlay, Imagick::COMPOSITE_DISSOLVE, $x, $y);
|
||||
}
|
||||
|
||||
function write($destination_filepath)
|
||||
{
|
||||
// use 4:2:2 chroma subsampling (reduce file size by 20-30% with "almost" no human perception)
|
||||
$this->image->setSamplingFactors( array(2,1) );
|
||||
return $this->image->writeImage($destination_filepath);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Class for ImageMagick external installation |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class image_ext_imagick implements imageInterface
|
||||
{
|
||||
var $imagickdir = '';
|
||||
var $source_filepath = '';
|
||||
var $width = '';
|
||||
var $height = '';
|
||||
var $is_animated_webp = false;
|
||||
var $commands = array();
|
||||
|
||||
function __construct($source_filepath)
|
||||
{
|
||||
global $conf;
|
||||
$this->source_filepath = $source_filepath;
|
||||
$this->imagickdir = $conf['ext_imagick_dir'];
|
||||
|
||||
if (strpos(@$_SERVER['SCRIPT_FILENAME'], '/kunden/') === 0) // 1and1
|
||||
{
|
||||
@putenv('MAGICK_THREAD_LIMIT=1');
|
||||
}
|
||||
|
||||
if ('webp' == strtolower(get_extension($source_filepath)))
|
||||
{
|
||||
$webp_info = pwg_image::webp_info($source_filepath);
|
||||
|
||||
if ($webp_info['has-animation'])
|
||||
{
|
||||
$this->is_animated_webp = true;
|
||||
|
||||
// ImageMagick "identify" returns the list of width x height for each
|
||||
// frame, such as "400x300400x300400x300" (3 frames of 400x300), as a big
|
||||
// string, impossible to parse :-/ So let's use the PHP embedded function
|
||||
// getimagesize here.
|
||||
list($this->width, $this->height) = getimagesize($source_filepath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$command = $this->imagickdir.'identify -format "%wx%h" "'.realpath($source_filepath).'"';
|
||||
@exec($command, $returnarray);
|
||||
if(!is_array($returnarray) or empty($returnarray[0]) or !preg_match('/^(\d+)x(\d+)$/', $returnarray[0], $match))
|
||||
{
|
||||
die("[External ImageMagick] Corrupt image\n" . var_export($returnarray, true));
|
||||
}
|
||||
|
||||
$this->width = $match[1];
|
||||
$this->height = $match[2];
|
||||
}
|
||||
|
||||
function add_command($command, $params=null)
|
||||
{
|
||||
$this->commands[$command] = $params;
|
||||
}
|
||||
|
||||
function get_width()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
function get_height()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
function crop($width, $height, $x, $y)
|
||||
{
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
|
||||
// the final "!" is added to crop the canva too, for animated picture (with WebP in mind)
|
||||
$this->add_command('crop', $width.'x'.$height.'+'.$x.'+'.$y.'!');
|
||||
return true;
|
||||
}
|
||||
|
||||
function strip()
|
||||
{
|
||||
$this->add_command('strip');
|
||||
return true;
|
||||
}
|
||||
|
||||
function rotate($rotation)
|
||||
{
|
||||
if (empty($rotation))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($rotation==90 || $rotation==270)
|
||||
{
|
||||
$tmp = $this->width;
|
||||
$this->width = $this->height;
|
||||
$this->height = $tmp;
|
||||
}
|
||||
$this->add_command('rotate', -$rotation);
|
||||
$this->add_command('orient', 'top-left');
|
||||
return true;
|
||||
}
|
||||
|
||||
function set_compression_quality($quality)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if ($this->is_animated_webp)
|
||||
{
|
||||
// in cas of animated WebP, we need to maximize quality to 70 to avoid
|
||||
// heavy thumbnails (or square or whatever is displayed on the thumbnails
|
||||
// page)
|
||||
$quality = min($quality, $conf['animated_webp_compression_quality']);
|
||||
}
|
||||
|
||||
$this->add_command('quality', $quality);
|
||||
return true;
|
||||
}
|
||||
|
||||
function resize($width, $height)
|
||||
{
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
|
||||
$this->add_command('filter', 'Lanczos');
|
||||
$this->add_command('resize', $width.'x'.$height.'!');
|
||||
return true;
|
||||
}
|
||||
|
||||
function sharpen($amount)
|
||||
{
|
||||
$m = pwg_image::get_sharpen_matrix($amount);
|
||||
|
||||
$param ='convolve "'.count($m).':';
|
||||
foreach ($m as $line)
|
||||
{
|
||||
$param .= ' ';
|
||||
$param .= implode(',', $line);
|
||||
}
|
||||
$param .= '"';
|
||||
$this->add_command('morphology', $param);
|
||||
return true;
|
||||
}
|
||||
|
||||
function compose($overlay, $x, $y, $opacity)
|
||||
{
|
||||
$param = 'compose dissolve -define compose:args='.$opacity;
|
||||
$param .= ' '.escapeshellarg(realpath($overlay->image->source_filepath));
|
||||
$param .= ' -gravity NorthWest -geometry +'.$x.'+'.$y;
|
||||
$param .= ' -composite';
|
||||
$this->add_command($param);
|
||||
return true;
|
||||
}
|
||||
|
||||
function write($destination_filepath)
|
||||
{
|
||||
global $logger;
|
||||
|
||||
$this->add_command('interlace', 'line'); // progressive rendering
|
||||
// use 4:2:2 chroma subsampling (reduce file size by 20-30% with "almost" no human perception)
|
||||
//
|
||||
// option deactivated for Piwigo 2.4.1, it doesn't work fo old versions
|
||||
// of ImageMagick, see bug:2672. To reactivate once we have a better way
|
||||
// to detect IM version and when we know which version supports this
|
||||
// option
|
||||
//
|
||||
if (version_compare(pwg_image::$ext_imagick_version, '6.6') > 0)
|
||||
{
|
||||
$this->add_command('sampling-factor', '4:2:2' );
|
||||
}
|
||||
|
||||
$exec = $this->imagickdir.pwg_image::get_ext_imagick_command();
|
||||
$exec .= ' "'.realpath($this->source_filepath).'"';
|
||||
|
||||
// If the image is animated webp add a filter to avoid breaking the animation
|
||||
if ($this->is_animated_webp)
|
||||
{
|
||||
$exec .= ' -layers coalesce ';
|
||||
}
|
||||
|
||||
foreach ($this->commands as $command => $params)
|
||||
{
|
||||
$exec .= ' -'.$command;
|
||||
if (!empty($params))
|
||||
{
|
||||
$exec .= ' '.$params;
|
||||
}
|
||||
}
|
||||
$dest = pathinfo($destination_filepath);
|
||||
$exec .= ' "'.realpath($dest['dirname']).'/'.$dest['basename'].'" 2>&1';
|
||||
$logger->debug($exec, 'i.php');
|
||||
@exec($exec, $returnarray);
|
||||
|
||||
if (is_array($returnarray) && (count($returnarray)>0) )
|
||||
{
|
||||
$logger->error('', 'i.php', $returnarray);
|
||||
foreach ($returnarray as $line)
|
||||
trigger_error($line, E_USER_WARNING);
|
||||
}
|
||||
return is_array($returnarray);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Class for GD library |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class image_gd implements imageInterface
|
||||
{
|
||||
var $image;
|
||||
var $quality = 95;
|
||||
|
||||
function __construct($source_filepath)
|
||||
{
|
||||
$gd_info = gd_info();
|
||||
$extension = strtolower(get_extension($source_filepath));
|
||||
|
||||
if (in_array($extension, array('jpg', 'jpeg')))
|
||||
{
|
||||
$this->image = imagecreatefromjpeg($source_filepath);
|
||||
}
|
||||
else if ($extension == 'png')
|
||||
{
|
||||
$this->image = imagecreatefrompng($source_filepath);
|
||||
}
|
||||
elseif ($extension == 'gif' and $gd_info['GIF Read Support'] and $gd_info['GIF Create Support'])
|
||||
{
|
||||
$this->image = imagecreatefromgif($source_filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
die('[Image GD] unsupported file extension');
|
||||
}
|
||||
}
|
||||
|
||||
function get_width()
|
||||
{
|
||||
return imagesx($this->image);
|
||||
}
|
||||
|
||||
function get_height()
|
||||
{
|
||||
return imagesy($this->image);
|
||||
}
|
||||
|
||||
function crop($width, $height, $x, $y)
|
||||
{
|
||||
$dest = imagecreatetruecolor($width, $height);
|
||||
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
if (function_exists('imageantialias'))
|
||||
{
|
||||
imageantialias($dest, true);
|
||||
}
|
||||
|
||||
$result = imagecopymerge($dest, $this->image, 0, 0, $x, $y, $width, $height, 100);
|
||||
|
||||
if ($result !== false)
|
||||
{
|
||||
imagedestroy($this->image);
|
||||
$this->image = $dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
imagedestroy($dest);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function strip()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function rotate($rotation)
|
||||
{
|
||||
$dest = imagerotate($this->image, $rotation, 0);
|
||||
imagedestroy($this->image);
|
||||
$this->image = $dest;
|
||||
return true;
|
||||
}
|
||||
|
||||
function set_compression_quality($quality)
|
||||
{
|
||||
$this->quality = $quality;
|
||||
return true;
|
||||
}
|
||||
|
||||
function resize($width, $height)
|
||||
{
|
||||
$dest = imagecreatetruecolor($width, $height);
|
||||
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
if (function_exists('imageantialias'))
|
||||
{
|
||||
imageantialias($dest, true);
|
||||
}
|
||||
|
||||
$result = imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $width, $height, $this->get_width(), $this->get_height());
|
||||
|
||||
if ($result !== false)
|
||||
{
|
||||
imagedestroy($this->image);
|
||||
$this->image = $dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
imagedestroy($dest);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function sharpen($amount)
|
||||
{
|
||||
$m = pwg_image::get_sharpen_matrix($amount);
|
||||
return imageconvolution($this->image, $m, 1, 0);
|
||||
}
|
||||
|
||||
function compose($overlay, $x, $y, $opacity)
|
||||
{
|
||||
$ioverlay = $overlay->image->image;
|
||||
/* A replacement for php's imagecopymerge() function that supports the alpha channel
|
||||
See php bug #23815: http://bugs.php.net/bug.php?id=23815 */
|
||||
|
||||
$ow = imagesx($ioverlay);
|
||||
$oh = imagesy($ioverlay);
|
||||
|
||||
// Create a new blank image the site of our source image
|
||||
$cut = imagecreatetruecolor($ow, $oh);
|
||||
|
||||
// Copy the blank image into the destination image where the source goes
|
||||
imagecopy($cut, $this->image, 0, 0, $x, $y, $ow, $oh);
|
||||
|
||||
// Place the source image in the destination image
|
||||
imagecopy($cut, $ioverlay, 0, 0, 0, 0, $ow, $oh);
|
||||
imagecopymerge($this->image, $cut, $x, $y, 0, 0, $ow, $oh, $opacity);
|
||||
imagedestroy($cut);
|
||||
return true;
|
||||
}
|
||||
|
||||
function write($destination_filepath)
|
||||
{
|
||||
$extension = strtolower(get_extension($destination_filepath));
|
||||
|
||||
if ($extension == 'png')
|
||||
{
|
||||
imagepng($this->image, $destination_filepath);
|
||||
}
|
||||
elseif ($extension == 'gif')
|
||||
{
|
||||
imagegif($this->image, $destination_filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
imagejpeg($this->image, $destination_filepath, $this->quality);
|
||||
}
|
||||
}
|
||||
|
||||
function destroy()
|
||||
{
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -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();
|
||||
?>
|
||||
@@ -0,0 +1,431 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class languages
|
||||
{
|
||||
var $fs_languages = array();
|
||||
var $db_languages = array();
|
||||
var $server_languages = array();
|
||||
|
||||
/**
|
||||
* Initialize $fs_languages and $db_languages
|
||||
*/
|
||||
function __construct($target_charset = null)
|
||||
{
|
||||
$this->get_fs_languages($target_charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform requested actions
|
||||
* @param string - action
|
||||
* @param string - language id
|
||||
* @param array - errors
|
||||
*/
|
||||
function perform_action($action, $language_id)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!$conf['enable_extensions_install'] and 'delete' == $action)
|
||||
{
|
||||
die('Piwigo extensions install/update/delete system is disabled');
|
||||
}
|
||||
|
||||
if (isset($this->db_languages[$language_id]))
|
||||
{
|
||||
$crt_db_language = $this->db_languages[$language_id];
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'activate':
|
||||
if (isset($crt_db_language))
|
||||
{
|
||||
$errors[] = 'CANNOT ACTIVATE - LANGUAGE IS ALREADY ACTIVATED';
|
||||
break;
|
||||
}
|
||||
|
||||
$query = '
|
||||
INSERT INTO '.LANGUAGES_TABLE.'
|
||||
(id, version, name)
|
||||
VALUES(\''.$language_id.'\',
|
||||
\''.$this->fs_languages[$language_id]['version'].'\',
|
||||
\''.$this->fs_languages[$language_id]['name'].'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
if (!isset($crt_db_language))
|
||||
{
|
||||
$errors[] = 'CANNOT DEACTIVATE - LANGUAGE IS ALREADY DEACTIVATED';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($language_id == get_default_language())
|
||||
{
|
||||
$errors[] = 'CANNOT DEACTIVATE - LANGUAGE IS DEFAULT LANGUAGE';
|
||||
break;
|
||||
}
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.LANGUAGES_TABLE.'
|
||||
WHERE id= \''.$language_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if (!empty($crt_db_language))
|
||||
{
|
||||
$errors[] = 'CANNOT DELETE - LANGUAGE IS ACTIVATED';
|
||||
break;
|
||||
}
|
||||
if (!isset($this->fs_languages[$language_id]))
|
||||
{
|
||||
$errors[] = 'CANNOT DELETE - LANGUAGE DOES NOT EXIST';
|
||||
break;
|
||||
}
|
||||
|
||||
// Set default language to user who are using this language
|
||||
$query = '
|
||||
UPDATE '.USER_INFOS_TABLE.'
|
||||
SET language = \''.get_default_language().'\'
|
||||
WHERE language = \''.$language_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
deltree(PHPWG_ROOT_PATH.'language/'.$language_id, PHPWG_ROOT_PATH.'language/trash');
|
||||
break;
|
||||
|
||||
case 'set_default':
|
||||
$query = '
|
||||
UPDATE '.USER_INFOS_TABLE.'
|
||||
SET language = \''.$language_id.'\'
|
||||
WHERE user_id IN ('.$conf['default_user_id'].', '.$conf['guest_id'].')
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get languages defined in the language directory
|
||||
*/
|
||||
function get_fs_languages($target_charset = null)
|
||||
{
|
||||
if ( empty($target_charset) )
|
||||
{
|
||||
$target_charset = get_pwg_charset();
|
||||
}
|
||||
$target_charset = strtolower($target_charset);
|
||||
|
||||
$dir = opendir(PHPWG_ROOT_PATH.'language');
|
||||
while ($file = readdir($dir))
|
||||
{
|
||||
if ($file!='.' and $file!='..')
|
||||
{
|
||||
$path = PHPWG_ROOT_PATH.'language/'.$file;
|
||||
if (is_dir($path) and !is_link($path)
|
||||
and preg_match('/^[a-zA-Z0-9-_]+$/', $file )
|
||||
and file_exists($path.'/common.lang.php')
|
||||
)
|
||||
{
|
||||
$language = array(
|
||||
'name'=>$file,
|
||||
'code'=>$file,
|
||||
'version'=>'0',
|
||||
'uri'=>'',
|
||||
'author'=>'',
|
||||
);
|
||||
$plg_data = implode( '', file($path.'/common.lang.php') );
|
||||
|
||||
if (preg_match("|Language Name:\\s*(.+)|", $plg_data, $val))
|
||||
{
|
||||
$language['name'] = trim( $val[1] );
|
||||
$language['name'] = convert_charset($language['name'], 'utf-8', $target_charset);
|
||||
}
|
||||
if (preg_match("|Version:\\s*([\\w.-]+)|", $plg_data, $val))
|
||||
{
|
||||
$language['version'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Language URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
|
||||
{
|
||||
$language['uri'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Author:\\s*(.+)|", $plg_data, $val))
|
||||
{
|
||||
$language['author'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Author URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
|
||||
{
|
||||
$language['author uri'] = trim($val[1]);
|
||||
}
|
||||
if (!empty($language['uri']) and strpos($language['uri'] , 'extension_view.php?eid='))
|
||||
{
|
||||
list( , $extension) = explode('extension_view.php?eid=', $language['uri']);
|
||||
if (is_numeric($extension)) $language['extension'] = $extension;
|
||||
}
|
||||
|
||||
// IMPORTANT SECURITY !
|
||||
$language = array_map('htmlspecialchars', $language);
|
||||
$this->fs_languages[$file] = $language;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
@uasort($this->fs_languages, 'name_compare');
|
||||
}
|
||||
|
||||
function get_db_languages()
|
||||
{
|
||||
$query = '
|
||||
SELECT id, name
|
||||
FROM '.LANGUAGES_TABLE.'
|
||||
ORDER BY name ASC
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$this->db_languages[ $row['id'] ] = $row['name'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve PEM server datas to $server_languages
|
||||
*/
|
||||
function get_server_languages($new=false)
|
||||
{
|
||||
global $user, $conf;
|
||||
|
||||
$get_data = array(
|
||||
'category_id' => $conf['pem_languages_category'],
|
||||
'format' => 'php',
|
||||
);
|
||||
|
||||
// Retrieve PEM versions
|
||||
$version = PHPWG_VERSION;
|
||||
$versions_to_check = array();
|
||||
$url = PEM_URL . '/api/get_version_list.php';
|
||||
if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
|
||||
{
|
||||
if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
|
||||
{
|
||||
$version = $pem_versions[0]['name'];
|
||||
}
|
||||
$branch = get_branch_from_version($version);
|
||||
foreach ($pem_versions as $pem_version)
|
||||
{
|
||||
if (strpos($pem_version['name'], $branch) === 0)
|
||||
{
|
||||
$versions_to_check[] = $pem_version['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($versions_to_check))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Languages to check
|
||||
$languages_to_check = array();
|
||||
foreach($this->fs_languages as $fs_language)
|
||||
{
|
||||
if (isset($fs_language['extension']))
|
||||
{
|
||||
$languages_to_check[] = $fs_language['extension'];
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve PEM languages infos
|
||||
$url = PEM_URL . '/api/get_revision_list.php';
|
||||
$get_data = array_merge($get_data, array(
|
||||
'last_revision_only' => 'true',
|
||||
'version' => implode(',', $versions_to_check),
|
||||
'lang' => $user['language'],
|
||||
'get_nb_downloads' => 'true',
|
||||
)
|
||||
);
|
||||
if (!empty($languages_to_check))
|
||||
{
|
||||
if ($new)
|
||||
{
|
||||
$get_data['extension_exclude'] = implode(',', $languages_to_check);
|
||||
}
|
||||
else
|
||||
{
|
||||
$get_data['extension_include'] = implode(',', $languages_to_check);
|
||||
}
|
||||
}
|
||||
|
||||
if (fetchRemote($url, $result, $get_data))
|
||||
{
|
||||
$pem_languages = @unserialize($result);
|
||||
if (!is_array($pem_languages))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foreach ($pem_languages as $language)
|
||||
{
|
||||
if (preg_match('/^.*? \[[A-Z]{2}\]$/', $language['extension_name']))
|
||||
{
|
||||
$this->server_languages[$language['extension_id']] = $language;
|
||||
}
|
||||
}
|
||||
@uasort($this->server_languages, array($this, 'extension_name_compare'));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract language files from archive
|
||||
*
|
||||
* @param string - install or upgrade
|
||||
* @param string - remote revision identifier (numeric)
|
||||
* @param string - language id or extension id
|
||||
*/
|
||||
function extract_language_files($action, $revision, $dest='')
|
||||
{
|
||||
global $logger;
|
||||
|
||||
if ($archive = tempnam( PHPWG_ROOT_PATH.'language', 'zip'))
|
||||
{
|
||||
$url = PEM_URL . '/download.php';
|
||||
$get_data = array(
|
||||
'rid' => $revision,
|
||||
'origin' => 'piwigo_'.$action,
|
||||
);
|
||||
|
||||
if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
|
||||
{
|
||||
fclose($handle);
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
|
||||
$zip = new PclZip($archive);
|
||||
if ($list = $zip->listContent())
|
||||
{
|
||||
foreach ($list as $file)
|
||||
{
|
||||
// we search common.lang.php in archive
|
||||
if (basename($file['filename']) == 'common.lang.php'
|
||||
and (!isset($main_filepath)
|
||||
or strlen($file['filename']) < strlen($main_filepath)))
|
||||
{
|
||||
$main_filepath = $file['filename'];
|
||||
}
|
||||
}
|
||||
|
||||
$logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
|
||||
|
||||
if (isset($main_filepath))
|
||||
{
|
||||
$root = basename(dirname($main_filepath)); // common.lang.php path in archive
|
||||
if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $root))
|
||||
{
|
||||
if ($action == 'install')
|
||||
{
|
||||
$dest = $root;
|
||||
}
|
||||
$extract_path = PHPWG_ROOT_PATH.'language/'.$dest;
|
||||
|
||||
$logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
|
||||
|
||||
if (
|
||||
$result = $zip->extract(
|
||||
PCLZIP_OPT_PATH, $extract_path,
|
||||
PCLZIP_OPT_REMOVE_PATH, $root,
|
||||
PCLZIP_OPT_REPLACE_NEWER
|
||||
)
|
||||
)
|
||||
{
|
||||
foreach ($result as $file)
|
||||
{
|
||||
if ($file['stored_filename'] == $main_filepath)
|
||||
{
|
||||
$status = $file['status'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($status == 'ok')
|
||||
{
|
||||
$this->get_fs_languages();
|
||||
if ($action == 'install')
|
||||
{
|
||||
$this->perform_action('activate', $dest);
|
||||
}
|
||||
}
|
||||
if (file_exists($extract_path.'/obsolete.list')
|
||||
and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
|
||||
and !empty($old_files))
|
||||
{
|
||||
$old_files[] = 'obsolete.list';
|
||||
$logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
|
||||
|
||||
$extract_path_realpath = realpath($extract_path);
|
||||
|
||||
foreach($old_files as $old_file)
|
||||
{
|
||||
$old_file = trim($old_file);
|
||||
$old_file = trim($old_file, '/'); // prevent path starting with a "/"
|
||||
|
||||
if (empty($old_file)) // empty here means the extension itself
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $extract_path.'/'.$old_file;
|
||||
|
||||
// make sure the obsolete file is withing the extension directory, prevent traversal path
|
||||
$realpath = realpath($path);
|
||||
if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$logger->debug(__FUNCTION__.', to delete = '.$path);
|
||||
|
||||
if (is_file($path))
|
||||
{
|
||||
@unlink($path);
|
||||
}
|
||||
elseif (is_dir($path))
|
||||
{
|
||||
deltree($path, PHPWG_ROOT_PATH.'language/trash');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else $status = 'extract_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'dl_archive_error';
|
||||
}
|
||||
else $status = 'temp_path_error';
|
||||
|
||||
@unlink($archive);
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort functions
|
||||
*/
|
||||
function extension_name_compare($a, $b)
|
||||
{
|
||||
return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,221 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Photo selection |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ADD_ACTION'=> PHOTOS_ADD_BASE_URL,
|
||||
'chunk_size' => $conf['upload_form_chunk_size'],
|
||||
'max_file_size' => $conf['upload_form_max_file_size'],
|
||||
'ADMIN_PAGE_TITLE' => l10n('Upload Photos'),
|
||||
)
|
||||
);
|
||||
|
||||
// what is the maximum number of pixels permitted by the memory_limit?
|
||||
if (pwg_image::get_library() == 'gd')
|
||||
{
|
||||
$fudge_factor = 1.7;
|
||||
$available_memory = get_ini_size('memory_limit') - memory_get_usage();
|
||||
$max_upload_width = round(sqrt($available_memory/(2 * $fudge_factor)));
|
||||
$max_upload_height = round(2 * $max_upload_width / 3);
|
||||
|
||||
// we don't want dimensions like 2995x1992 but 3000x2000
|
||||
$max_upload_width = round($max_upload_width/100)*100;
|
||||
$max_upload_height = round($max_upload_height/100)*100;
|
||||
|
||||
$max_upload_resolution = floor($max_upload_width * $max_upload_height / (1000000));
|
||||
|
||||
// no need to display a limitation warning if the limitation is huge like 20MP
|
||||
if ($max_upload_resolution < 25)
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'max_upload_width' => $max_upload_width,
|
||||
'max_upload_height' => $max_upload_height,
|
||||
'max_upload_resolution' => $max_upload_resolution,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//warn the user if the picture will be resized after upload
|
||||
if ($conf['original_resize'])
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'original_resize_maxwidth' => $conf['original_resize_maxwidth'],
|
||||
'original_resize_maxheight' => $conf['original_resize_maxheight'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'form_action' => PHOTOS_ADD_BASE_URL,
|
||||
'pwg_token' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
|
||||
$unique_exts = array_unique(
|
||||
array_map(
|
||||
'strtolower',
|
||||
$conf['upload_form_all_types'] ? $conf['file_ext'] : $conf['picture_ext']
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'upload_file_types' => implode(', ', $unique_exts),
|
||||
'file_exts' => implode(',', $unique_exts),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Categories |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// we need to know the category in which the last photo was added
|
||||
$selected_category = array();
|
||||
|
||||
if (isset($_GET['album']))
|
||||
{
|
||||
// set the category from get url or ...
|
||||
check_input_parameter('album', $_GET, false, PATTERN_ID);
|
||||
|
||||
// test if album really exists
|
||||
$query = '
|
||||
SELECT id, uppercats
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id = '.$_GET['album'].'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) == 1)
|
||||
{
|
||||
$selected_category = array($_GET['album']);
|
||||
|
||||
$cat = pwg_db_fetch_assoc($result);
|
||||
$template->assign('ADD_TO_ALBUM', get_cat_display_name_cache($cat['uppercats'], null));
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal_error('[Hacking attempt] the album id = "'.$_GET['album'].'" is not valid');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need to know the category in which the last photo was added
|
||||
$query = '
|
||||
SELECT category_id, c.uppercats
|
||||
FROM '.IMAGES_TABLE.' AS i
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON image_id = i.id
|
||||
JOIN '.CATEGORIES_TABLE.' AS c ON category_id = c.id
|
||||
ORDER BY i.id DESC
|
||||
LIMIT 1
|
||||
;
|
||||
';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) > 0)
|
||||
{
|
||||
$row = pwg_db_fetch_assoc($result);
|
||||
$selected_category = array($row['category_id']);
|
||||
$selected_category_name = get_cat_display_name_cache($row['uppercats'], null);
|
||||
$template->assign('selected_category_name', $selected_category_name);
|
||||
}
|
||||
}
|
||||
|
||||
// existing album
|
||||
$template->assign('selected_category', $selected_category);
|
||||
|
||||
// how many existing albums?
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
list($nb_albums) = pwg_db_fetch_row(pwg_query($query));
|
||||
// $nb_albums = 0;
|
||||
$template->assign('NB_ALBUMS', $nb_albums);
|
||||
|
||||
// image level options
|
||||
$selected_level = isset($_POST['level']) ? $_POST['level'] : 0;
|
||||
$template->assign(
|
||||
array(
|
||||
'level_options'=> get_privacy_level_options(),
|
||||
'level_options_selected' => array($selected_level)
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Setup errors/warnings |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Errors
|
||||
$setup_errors = array();
|
||||
|
||||
$error_message = ready_for_upload_message();
|
||||
if (!empty($error_message))
|
||||
{
|
||||
$setup_errors[] = $error_message;
|
||||
}
|
||||
|
||||
if (!function_exists('gd_info'))
|
||||
{
|
||||
$setup_errors[] = l10n('GD library is missing');
|
||||
}
|
||||
|
||||
$template->assign(array(
|
||||
'setup_errors'=> $setup_errors,
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('categories')),
|
||||
));
|
||||
|
||||
// Warnings
|
||||
if (isset($_GET['hide_warnings']))
|
||||
{
|
||||
$_SESSION['upload_hide_warnings'] = true;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['upload_hide_warnings']))
|
||||
{
|
||||
$setup_warnings = array();
|
||||
|
||||
if ($conf['use_exif'] and !function_exists('exif_read_data'))
|
||||
{
|
||||
$setup_warnings[] = l10n('Exif extension not available, admin should disable exif use');
|
||||
}
|
||||
|
||||
if (get_ini_size('upload_max_filesize') > get_ini_size('post_max_size'))
|
||||
{
|
||||
$setup_warnings[] = l10n(
|
||||
'In your php.ini file, the upload_max_filesize (%sB) is bigger than post_max_size (%sB), you should change this setting',
|
||||
get_ini_size('upload_max_filesize', false),
|
||||
get_ini_size('post_max_size', false)
|
||||
);
|
||||
}
|
||||
|
||||
if (get_ini_size('upload_max_filesize') < $conf['upload_form_chunk_size']*1024)
|
||||
{
|
||||
$setup_warnings[] = sprintf(
|
||||
'Piwigo setting upload_form_chunk_size (%ukB) should be smaller than PHP configuration setting upload_max_filesize (%ukB)',
|
||||
$conf['upload_form_chunk_size'],
|
||||
ceil(get_ini_size('upload_max_filesize') / 1024)
|
||||
);
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'setup_warnings' => $setup_warnings,
|
||||
'hide_warnings_link' => PHOTOS_ADD_BASE_URL.'&hide_warnings=1'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,843 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* class DummyPlugin_maintain
|
||||
* used when a plugin uses the old procedural declaration of maintenance methods
|
||||
*/
|
||||
class DummyPlugin_maintain extends PluginMaintain
|
||||
{
|
||||
function install($plugin_version, &$errors=array())
|
||||
{
|
||||
if (is_callable('plugin_install'))
|
||||
{
|
||||
return plugin_install($this->plugin_id, $plugin_version, $errors);
|
||||
}
|
||||
}
|
||||
function activate($plugin_version, &$errors=array())
|
||||
{
|
||||
if (is_callable('plugin_activate'))
|
||||
{
|
||||
return plugin_activate($this->plugin_id, $plugin_version, $errors);
|
||||
}
|
||||
}
|
||||
function deactivate()
|
||||
{
|
||||
if (is_callable('plugin_deactivate'))
|
||||
{
|
||||
return plugin_deactivate($this->plugin_id);
|
||||
}
|
||||
}
|
||||
function uninstall()
|
||||
{
|
||||
if (is_callable('plugin_uninstall'))
|
||||
{
|
||||
return plugin_uninstall($this->plugin_id);
|
||||
}
|
||||
}
|
||||
function update($old_version, $new_version, &$errors=array()) {}
|
||||
}
|
||||
|
||||
|
||||
class plugins
|
||||
{
|
||||
var $fs_plugins = array();
|
||||
var $db_plugins_by_id = array();
|
||||
var $server_plugins = array();
|
||||
var $default_plugins = array('LocalFilesEditor', 'language_switch', 'TakeATour', 'AdminTools');
|
||||
|
||||
/**
|
||||
* Initialize $fs_plugins and $db_plugins_by_id
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->get_fs_plugins();
|
||||
|
||||
foreach (get_db_plugins() as $db_plugin)
|
||||
{
|
||||
$this->db_plugins_by_id[$db_plugin['id']] = $db_plugin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maintain class of a plugin
|
||||
* or build a new class with the procedural methods
|
||||
* @param string $plugin_id
|
||||
*/
|
||||
private static function build_maintain_class($plugin_id)
|
||||
{
|
||||
$file_to_include = PHPWG_PLUGINS_PATH . $plugin_id . '/maintain';
|
||||
$classname = $plugin_id.'_maintain';
|
||||
|
||||
// piwigo-videojs and piwigo-openstreetmap unfortunately have a "-" in their folder
|
||||
// name (=plugin_id) and a class name can't have a "-". So we have to replace with a "_"
|
||||
$classname = str_replace('-', '_', $classname);
|
||||
|
||||
// 2.7 pattern (OO only)
|
||||
if (file_exists($file_to_include.'.class.php'))
|
||||
{
|
||||
include_once($file_to_include.'.class.php');
|
||||
return new $classname($plugin_id);
|
||||
}
|
||||
|
||||
// before 2.7 pattern (OO or procedural)
|
||||
if (file_exists($file_to_include.'.inc.php'))
|
||||
{
|
||||
include_once($file_to_include.'.inc.php');
|
||||
|
||||
if (class_exists($classname))
|
||||
{
|
||||
return new $classname($plugin_id);
|
||||
}
|
||||
}
|
||||
|
||||
return new DummyPlugin_maintain($plugin_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform requested actions
|
||||
* @param string - action
|
||||
* @param string - plugin id
|
||||
* @param array - errors
|
||||
*/
|
||||
function perform_action($action, $plugin_id, $options=array())
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!$conf['enable_extensions_install'] and 'delete' == $action)
|
||||
{
|
||||
die('Piwigo extensions install/update/delete system is disabled');
|
||||
}
|
||||
|
||||
if (isset($this->db_plugins_by_id[$plugin_id]))
|
||||
{
|
||||
$crt_db_plugin = $this->db_plugins_by_id[$plugin_id];
|
||||
}
|
||||
|
||||
if ($action !== 'update')
|
||||
{ // wait for files to be updated
|
||||
$plugin_maintain = self::build_maintain_class($plugin_id);
|
||||
}
|
||||
|
||||
$activity_details = array('plugin_id'=>$plugin_id);
|
||||
|
||||
$errors = array();
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'install':
|
||||
if (!empty($crt_db_plugin) or !isset($this->fs_plugins[$plugin_id]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$plugin_maintain->install($this->fs_plugins[$plugin_id]['version'], $errors);
|
||||
$activity_details['version'] = $this->fs_plugins[$plugin_id]['version'];
|
||||
|
||||
if (empty($errors))
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '. PLUGINS_TABLE .' (id,version)
|
||||
VALUES (\''. $plugin_id .'\', \''. $this->fs_plugins[$plugin_id]['version'] .'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
else
|
||||
{
|
||||
$activity_details['result'] = 'error';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$previous_version = $this->fs_plugins[$plugin_id]['version'];
|
||||
$activity_details['from_version'] = $previous_version;
|
||||
$errors[0] = $this->extract_plugin_files('upgrade', $options['revision'], $plugin_id);
|
||||
|
||||
if ($errors[0] === 'ok')
|
||||
{
|
||||
$this->get_fs_plugin($plugin_id); // refresh plugins list
|
||||
$new_version = $this->fs_plugins[$plugin_id]['version'];
|
||||
$activity_details['to_version'] = $new_version;
|
||||
|
||||
$plugin_maintain = self::build_maintain_class($plugin_id);
|
||||
$plugin_maintain->update($previous_version, $new_version, $errors);
|
||||
|
||||
if ($new_version != 'auto')
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. PLUGINS_TABLE .'
|
||||
SET version=\''. $new_version .'\'
|
||||
WHERE id=\''. $plugin_id .'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$activity_details['result'] = 'error';
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'activate':
|
||||
if (!isset($crt_db_plugin))
|
||||
{
|
||||
$errors = $this->perform_action('install', $plugin_id);
|
||||
list($crt_db_plugin) = get_db_plugins(null, $plugin_id);
|
||||
load_conf_from_db();
|
||||
}
|
||||
elseif ($crt_db_plugin['state'] == 'active')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty($errors))
|
||||
{
|
||||
$plugin_maintain->activate($crt_db_plugin['version'], $errors);
|
||||
$activity_details['version'] = $crt_db_plugin['version'];
|
||||
}
|
||||
|
||||
if (empty($errors))
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. PLUGINS_TABLE .'
|
||||
SET state=\'active\'
|
||||
WHERE id=\''. $plugin_id .'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
else
|
||||
{
|
||||
$activity_details['result'] = 'error';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
if (!isset($crt_db_plugin) or $crt_db_plugin['state'] != 'active')
|
||||
{
|
||||
$activity_details['result'] = 'error';
|
||||
break;
|
||||
}
|
||||
|
||||
$query = '
|
||||
UPDATE '. PLUGINS_TABLE .'
|
||||
SET state=\'inactive\'
|
||||
WHERE id=\''. $plugin_id .'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$plugin_maintain->deactivate();
|
||||
|
||||
if (isset($crt_db_plugin['version']))
|
||||
{
|
||||
$activity_details['version'] = $crt_db_plugin['version'];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'uninstall':
|
||||
if (!isset($crt_db_plugin))
|
||||
{
|
||||
$activity_details['result'] = 'error';
|
||||
$activity_details['error'] = 'plugin not installed';
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($crt_db_plugin['version']))
|
||||
{
|
||||
$activity_details['version'] = $crt_db_plugin['version'];
|
||||
}
|
||||
|
||||
if ($crt_db_plugin['state'] == 'active')
|
||||
{
|
||||
$this->perform_action('deactivate', $plugin_id);
|
||||
}
|
||||
|
||||
$query = '
|
||||
DELETE FROM '. PLUGINS_TABLE .'
|
||||
WHERE id=\''. $plugin_id .'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$plugin_maintain->uninstall();
|
||||
break;
|
||||
|
||||
case 'restore':
|
||||
$this->perform_action('uninstall', $plugin_id);
|
||||
unset($this->db_plugins_by_id[$plugin_id]);
|
||||
$errors = $this->perform_action('activate', $plugin_id);
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if (!empty($crt_db_plugin))
|
||||
{
|
||||
if (isset($crt_db_plugin['version']))
|
||||
{
|
||||
$activity_details['db_version'] = $crt_db_plugin['version'];
|
||||
}
|
||||
|
||||
$this->perform_action('uninstall', $plugin_id);
|
||||
}
|
||||
if (!isset($this->fs_plugins[$plugin_id]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$activity_details['fs_version'] = $this->fs_plugins[$plugin_id]['version'];
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
deltree(PHPWG_PLUGINS_PATH . $plugin_id, PHPWG_PLUGINS_PATH . 'trash');
|
||||
break;
|
||||
}
|
||||
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_PLUGIN, $action, $activity_details);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugins defined in the plugin directory
|
||||
*/
|
||||
function get_fs_plugins()
|
||||
{
|
||||
$dir = opendir(PHPWG_PLUGINS_PATH);
|
||||
while ($file = readdir($dir))
|
||||
{
|
||||
if ($file!='.' and $file!='..')
|
||||
{
|
||||
if (preg_match('/^[a-zA-Z0-9-_]+$/', $file))
|
||||
{
|
||||
$this->get_fs_plugin($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load metadata of a plugin in `fs_plugins` array
|
||||
* @from 2.7
|
||||
* @param $plugin_id
|
||||
* @return false|array
|
||||
*/
|
||||
function get_fs_plugin($plugin_id)
|
||||
{
|
||||
$path = PHPWG_PLUGINS_PATH.$plugin_id;
|
||||
|
||||
if (is_dir($path) and !is_link($path)
|
||||
and file_exists($path.'/main.inc.php')
|
||||
)
|
||||
{
|
||||
$plugin = array(
|
||||
'name'=>$plugin_id,
|
||||
'version'=>'0',
|
||||
'uri'=>'',
|
||||
'description'=>'',
|
||||
'author'=>'',
|
||||
'hasSettings'=>false,
|
||||
);
|
||||
$plg_data = file_get_contents($path.'/main.inc.php', false, null, 0, 2048);
|
||||
|
||||
if (preg_match("|Plugin Name:\\s*(.+)|", $plg_data, $val))
|
||||
{
|
||||
$plugin['name'] = trim( $val[1] );
|
||||
}
|
||||
if (preg_match("|Version:\\s*([\\w.-]+)|", $plg_data, $val))
|
||||
{
|
||||
$plugin['version'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Plugin URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
|
||||
{
|
||||
$plugin['uri'] = trim($val[1]);
|
||||
}
|
||||
if ($desc = load_language('description.txt', $path.'/', array('return' => true)))
|
||||
{
|
||||
$plugin['description'] = trim($desc);
|
||||
}
|
||||
elseif (preg_match("|Description:\\s*(.+)|", $plg_data, $val))
|
||||
{
|
||||
$plugin['description'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Author:\\s*(.+)|", $plg_data, $val))
|
||||
{
|
||||
$plugin['author'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Author URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
|
||||
{
|
||||
$plugin['author uri'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("/Has Settings:\\s*([Tt]rue|[Ww]ebmaster)/", $plg_data, $val))
|
||||
{
|
||||
if (strtolower($val[1]) == 'webmaster')
|
||||
{
|
||||
global $user;
|
||||
|
||||
if (isset($user) and 'webmaster' == $user['status'])
|
||||
{
|
||||
$plugin['hasSettings'] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$plugin['hasSettings'] = true;
|
||||
}
|
||||
}
|
||||
if (!empty($plugin['uri']) and strpos($plugin['uri'] , 'extension_view.php?eid='))
|
||||
{
|
||||
list( , $extension) = explode('extension_view.php?eid=', $plugin['uri']);
|
||||
if (is_numeric($extension)) $plugin['extension'] = $extension;
|
||||
}
|
||||
|
||||
// IMPORTANT SECURITY !
|
||||
$plugin = array_map('htmlspecialchars', $plugin);
|
||||
$this->fs_plugins[$plugin_id] = $plugin;
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort fs_plugins
|
||||
*/
|
||||
function sort_fs_plugins($order='name')
|
||||
{
|
||||
switch ($order)
|
||||
{
|
||||
case 'name':
|
||||
uasort($this->fs_plugins, 'name_compare');
|
||||
break;
|
||||
case 'status':
|
||||
$this->sort_plugins_by_state();
|
||||
break;
|
||||
case 'author':
|
||||
uasort($this->fs_plugins, array($this, 'plugin_author_compare'));
|
||||
break;
|
||||
case 'id':
|
||||
uksort($this->fs_plugins, 'strcasecmp');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve PEM versions
|
||||
// Beta test : return last version on PEM if the current version isn't known or else return the current and the last version
|
||||
function get_versions_to_check($beta_test=false, $version=PHPWG_VERSION)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$versions_to_check = array();
|
||||
$url = PEM_URL . '/api/get_version_list.php?category_id='. $conf['pem_plugins_category'] .'&format=php';
|
||||
if (fetchRemote($url, $result) and $pem_versions = @unserialize($result))
|
||||
{
|
||||
$i = 0;
|
||||
|
||||
// If the actual version exist, put the PEM id in $versions_to_check
|
||||
while ($i < count($pem_versions) && count($versions_to_check) == 0)
|
||||
{
|
||||
if (get_branch_from_version($pem_versions[$i]['name']) == get_branch_from_version($version))
|
||||
{
|
||||
$versions_to_check[] = $pem_versions[$i]['id'];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
// If $beta_test is true, search the previous version
|
||||
if ($beta_test)
|
||||
{
|
||||
// If the actual version is not in PEM, put the latest PEM version
|
||||
if (count($versions_to_check) == 0)
|
||||
{
|
||||
$versions_to_check[] = $pem_versions[0]['id'];
|
||||
}
|
||||
else // Else search the next version in PEM
|
||||
{
|
||||
$has_found_previous_version = false;
|
||||
while ($i < count($pem_versions) && !$has_found_previous_version)
|
||||
{
|
||||
if ($pem_versions[$i]['id'] != $versions_to_check[0])
|
||||
{
|
||||
$versions_to_check[] = $pem_versions[$i]['id'];
|
||||
$has_found_previous_version = true;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
|
||||
// {
|
||||
// $version = $pem_versions[0]['name'];
|
||||
// }
|
||||
// $branch = get_branch_from_version($version);
|
||||
// foreach ($pem_versions as $pem_version)
|
||||
// {
|
||||
// if (strpos($pem_version['name'], $branch) === 0)
|
||||
// {
|
||||
// $versions_to_check[] = $pem_version['id'];
|
||||
// }
|
||||
// }
|
||||
}
|
||||
return $versions_to_check;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve PEM server datas to $server_plugins
|
||||
* $beta_test parameter add plugins compatible with the previous version
|
||||
*/
|
||||
function get_server_plugins($new=false, $beta_test=false)
|
||||
{
|
||||
global $user, $conf;
|
||||
|
||||
$versions_to_check = $this->get_versions_to_check($beta_test);
|
||||
if (empty($versions_to_check))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Plugins to check
|
||||
$plugins_to_check = array();
|
||||
foreach($this->fs_plugins as $fs_plugin)
|
||||
{
|
||||
if (isset($fs_plugin['extension']))
|
||||
{
|
||||
$plugins_to_check[] = $fs_plugin['extension'];
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve PEM plugins infos
|
||||
$url = PEM_URL . '/api/get_revision_list-next.php';
|
||||
$get_data = array(
|
||||
'category_id' => $conf['pem_plugins_category'],
|
||||
'format' => 'php',
|
||||
'last_revision_only' => 'true',
|
||||
'version' => implode(',', $versions_to_check),
|
||||
'lang' => substr($user['language'], 0, 2),
|
||||
'get_nb_downloads' => 'true',
|
||||
);
|
||||
|
||||
if (!empty($plugins_to_check))
|
||||
{
|
||||
if ($new)
|
||||
{
|
||||
$get_data['extension_exclude'] = implode(',', $plugins_to_check);
|
||||
}
|
||||
else
|
||||
{
|
||||
$get_data['extension_include'] = implode(',', $plugins_to_check);
|
||||
}
|
||||
}
|
||||
if (fetchRemote($url, $result, $get_data))
|
||||
{
|
||||
$pem_plugins = @unserialize($result);
|
||||
if (!is_array($pem_plugins))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foreach ($pem_plugins as $plugin)
|
||||
{
|
||||
$this->server_plugins[$plugin['extension_id']] = $plugin;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_incompatible_plugins($actualize=false)
|
||||
{
|
||||
if (isset($_SESSION['incompatible_plugins']) and !$actualize
|
||||
and $_SESSION['incompatible_plugins']['~~expire~~'] > time())
|
||||
{
|
||||
return $_SESSION['incompatible_plugins'];
|
||||
}
|
||||
|
||||
$_SESSION['incompatible_plugins'] = array('~~expire~~' => time() + 300);
|
||||
|
||||
$versions_to_check = $this->get_versions_to_check();
|
||||
if (empty($versions_to_check))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
global $conf;
|
||||
|
||||
// Plugins to check
|
||||
$plugins_to_check = array();
|
||||
foreach($this->fs_plugins as $fs_plugin)
|
||||
{
|
||||
if (isset($fs_plugin['extension']))
|
||||
{
|
||||
$plugins_to_check[] = $fs_plugin['extension'];
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve PEM plugins infos
|
||||
$url = PEM_URL . '/api/get_revision_list.php';
|
||||
$get_data = array(
|
||||
'category_id' => $conf['pem_plugins_category'],
|
||||
'format' => 'php',
|
||||
'version' => implode(',', $versions_to_check),
|
||||
'extension_include' => implode(',', $plugins_to_check),
|
||||
);
|
||||
|
||||
if (fetchRemote($url, $result, $get_data))
|
||||
{
|
||||
$pem_plugins = @unserialize($result);
|
||||
if (!is_array($pem_plugins))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$server_plugins = array();
|
||||
foreach ($pem_plugins as $plugin)
|
||||
{
|
||||
if (!isset($server_plugins[$plugin['extension_id']]))
|
||||
{
|
||||
$server_plugins[$plugin['extension_id']] = array();
|
||||
}
|
||||
$server_plugins[$plugin['extension_id']][] = $plugin['revision_name'];
|
||||
}
|
||||
|
||||
foreach ($this->fs_plugins as $plugin_id => $fs_plugin)
|
||||
{
|
||||
if (isset($fs_plugin['extension'])
|
||||
and !in_array($plugin_id, $this->default_plugins)
|
||||
and $fs_plugin['version'] != 'auto'
|
||||
and (!isset($server_plugins[$fs_plugin['extension']]) or !in_array($fs_plugin['version'], $server_plugins[$fs_plugin['extension']])))
|
||||
{
|
||||
$_SESSION['incompatible_plugins'][$plugin_id] = $fs_plugin['version'];
|
||||
}
|
||||
}
|
||||
return $_SESSION['incompatible_plugins'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort $server_plugins
|
||||
*/
|
||||
function sort_server_plugins($order='date')
|
||||
{
|
||||
switch ($order)
|
||||
{
|
||||
case 'date':
|
||||
krsort($this->server_plugins);
|
||||
break;
|
||||
case 'revision':
|
||||
usort($this->server_plugins, array($this, 'extension_revision_compare'));
|
||||
break;
|
||||
case 'name':
|
||||
uasort($this->server_plugins, array($this, 'extension_name_compare'));
|
||||
break;
|
||||
case 'author':
|
||||
uasort($this->server_plugins, array($this, 'extension_author_compare'));
|
||||
break;
|
||||
case 'downloads':
|
||||
usort($this->server_plugins, array($this, 'extension_downloads_compare'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract plugin files from archive
|
||||
* @param string - install or upgrade
|
||||
* @param string - archive URL
|
||||
* @param string - plugin id or extension id
|
||||
*/
|
||||
function extract_plugin_files($action, $revision, $dest, &$plugin_id=null)
|
||||
{
|
||||
global $logger;
|
||||
|
||||
if ($archive = tempnam( PHPWG_PLUGINS_PATH, 'zip'))
|
||||
{
|
||||
$url = PEM_URL . '/download.php';
|
||||
$get_data = array(
|
||||
'rid' => $revision,
|
||||
'origin' => 'piwigo_'.$action,
|
||||
);
|
||||
|
||||
if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
|
||||
{
|
||||
fclose($handle);
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
|
||||
$zip = new PclZip($archive);
|
||||
if ($list = $zip->listContent())
|
||||
{
|
||||
foreach ($list as $file)
|
||||
{
|
||||
// we search main.inc.php in archive
|
||||
if (basename($file['filename']) == 'main.inc.php'
|
||||
and (!isset($main_filepath)
|
||||
or strlen($file['filename']) < strlen($main_filepath)))
|
||||
{
|
||||
$main_filepath = $file['filename'];
|
||||
}
|
||||
}
|
||||
|
||||
$logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
|
||||
|
||||
if (isset($main_filepath))
|
||||
{
|
||||
$root = dirname($main_filepath); // main.inc.php path in archive
|
||||
if ($action == 'upgrade')
|
||||
{
|
||||
$plugin_id = $dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
$plugin_id = ($root == '.' ? 'extension_' . $dest : basename($root));
|
||||
}
|
||||
$extract_path = PHPWG_PLUGINS_PATH . $plugin_id;
|
||||
$logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
|
||||
|
||||
if($result = $zip->extract(PCLZIP_OPT_PATH, $extract_path,
|
||||
PCLZIP_OPT_REMOVE_PATH, $root,
|
||||
PCLZIP_OPT_REPLACE_NEWER))
|
||||
{
|
||||
foreach ($result as $file)
|
||||
{
|
||||
if ($file['stored_filename'] == $main_filepath)
|
||||
{
|
||||
$status = $file['status'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (file_exists($extract_path.'/obsolete.list')
|
||||
and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
|
||||
and !empty($old_files))
|
||||
{
|
||||
$old_files[] = 'obsolete.list';
|
||||
$logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
|
||||
|
||||
$extract_path_realpath = realpath($extract_path);
|
||||
|
||||
foreach($old_files as $old_file)
|
||||
{
|
||||
$old_file = trim($old_file);
|
||||
$old_file = trim($old_file, '/'); // prevent path starting with a "/"
|
||||
|
||||
if (empty($old_file)) // empty here means the extension itself
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $extract_path.'/'.$old_file;
|
||||
|
||||
// make sure the obsolete file is withing the extension directory, prevent traversal path
|
||||
$realpath = realpath($path);
|
||||
if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$logger->debug(__FUNCTION__.', to delete = '.$path);
|
||||
|
||||
if (is_file($path))
|
||||
{
|
||||
@unlink($path);
|
||||
}
|
||||
elseif (is_dir($path))
|
||||
{
|
||||
deltree($path, PHPWG_PLUGINS_PATH . 'trash');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else $status = 'extract_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'dl_archive_error';
|
||||
}
|
||||
else $status = 'temp_path_error';
|
||||
|
||||
@unlink($archive);
|
||||
return $status;
|
||||
}
|
||||
|
||||
function get_merged_extensions($version=PHPWG_VERSION)
|
||||
{
|
||||
$file = PHPWG_ROOT_PATH.'install/obsolete_extensions.list';
|
||||
$merged_extensions = array();
|
||||
|
||||
if (file_exists($file) and $obsolete_ext = file($file, FILE_IGNORE_NEW_LINES) and !empty($obsolete_ext))
|
||||
{
|
||||
foreach ($obsolete_ext as $ext)
|
||||
{
|
||||
if (preg_match('/^(\d+) ?: ?(.*?)$/', $ext, $matches))
|
||||
{
|
||||
$merged_extensions[$matches[1]] = $matches[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $merged_extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort functions
|
||||
*/
|
||||
function extension_revision_compare($a, $b)
|
||||
{
|
||||
if ($a['revision_date'] < $b['revision_date']) return 1;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
function extension_name_compare($a, $b)
|
||||
{
|
||||
return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
|
||||
}
|
||||
|
||||
function extension_author_compare($a, $b)
|
||||
{
|
||||
$r = strcasecmp($a['author_name'], $b['author_name']);
|
||||
if ($r == 0) return $this->extension_name_compare($a, $b);
|
||||
else return $r;
|
||||
}
|
||||
|
||||
function plugin_author_compare($a, $b)
|
||||
{
|
||||
$r = strcasecmp($a['author'], $b['author']);
|
||||
if ($r == 0) return name_compare($a, $b);
|
||||
else return $r;
|
||||
}
|
||||
|
||||
function extension_downloads_compare($a, $b)
|
||||
{
|
||||
if ($a['extension_nb_downloads'] < $b['extension_nb_downloads']) return 1;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
function sort_plugins_by_state()
|
||||
{
|
||||
uasort($this->fs_plugins, 'name_compare');
|
||||
|
||||
$active_plugins = array();
|
||||
$inactive_plugins = array();
|
||||
$not_installed = array();
|
||||
|
||||
foreach($this->fs_plugins as $plugin_id => $plugin)
|
||||
{
|
||||
if (isset($this->db_plugins_by_id[$plugin_id]))
|
||||
{
|
||||
$this->db_plugins_by_id[$plugin_id]['state'] == 'active' ?
|
||||
$active_plugins[$plugin_id] = $plugin : $inactive_plugins[$plugin_id] = $plugin;
|
||||
}
|
||||
else
|
||||
{
|
||||
$not_installed[$plugin_id] = $plugin;
|
||||
}
|
||||
}
|
||||
$this->fs_plugins = $active_plugins + $inactive_plugins + $not_installed;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,144 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class tabsheet
|
||||
{
|
||||
var $sheets;
|
||||
var $uniqid;
|
||||
var $name;
|
||||
var $titlename;
|
||||
var $selected;
|
||||
|
||||
/*
|
||||
$name is the tabsheet's name inside the template .tpl file
|
||||
$titlename in the template is affected by $titlename value
|
||||
*/
|
||||
function __construct($name = 'TABSHEET', $titlename = 'TABSHEET_TITLE')
|
||||
{
|
||||
$this->sheets = array();
|
||||
$this->uniqid = null;
|
||||
$this->name = $name;
|
||||
$this->titlename = $titlename;
|
||||
$this->selected = "";
|
||||
}
|
||||
|
||||
function set_id($id)
|
||||
{
|
||||
$this->uniqid = $id;
|
||||
}
|
||||
|
||||
/*
|
||||
add a tab
|
||||
*/
|
||||
function add($name, $caption, $url, $selected = false)
|
||||
{
|
||||
if (!isset($this->sheets[$name]))
|
||||
{
|
||||
$this->sheets[$name] = array('caption' => $caption,
|
||||
'url' => $url);
|
||||
if($selected)
|
||||
{
|
||||
$this->selected=$name;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
remove a tab
|
||||
*/
|
||||
function delete($name)
|
||||
{
|
||||
if (isset($this->sheets[$name]))
|
||||
{
|
||||
array_splice($this->sheets, $name, 1);
|
||||
|
||||
if ($this->selected == $name)
|
||||
{
|
||||
$this->selected = "";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
select a tab to be active
|
||||
*/
|
||||
function select($name)
|
||||
{
|
||||
$this->sheets = trigger_change('tabsheet_before_select', $this->sheets, $this->uniqid);
|
||||
if (!array_key_exists($name, $this->sheets))
|
||||
{
|
||||
$keys = array_keys($this->sheets);
|
||||
$name = $keys[0];
|
||||
}
|
||||
$this->selected = $name;
|
||||
}
|
||||
|
||||
/*
|
||||
set $titlename value
|
||||
*/
|
||||
function set_titlename($titlename)
|
||||
{
|
||||
$this->titlename = $titlename;
|
||||
return $this->titlename;
|
||||
}
|
||||
|
||||
/*
|
||||
returns $titlename value
|
||||
*/
|
||||
function get_titlename()
|
||||
{
|
||||
return $this->titlename;
|
||||
}
|
||||
|
||||
/*
|
||||
returns properties of selected tab
|
||||
*/
|
||||
function get_selected()
|
||||
{
|
||||
if (!empty($this->selected))
|
||||
{
|
||||
return $this->sheets[$this->selected];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Build TabSheet and assign this content to current page
|
||||
*
|
||||
* Fill $this->$name {default value = TABSHEET} with HTML code for tabsheet
|
||||
* Fill $this->titlename {default value = TABSHEET_TITLE} with formated caption of the selected tab
|
||||
*/
|
||||
function assign()
|
||||
{
|
||||
global $template;
|
||||
|
||||
$template->set_filename('tabsheet', 'tabsheet.tpl');
|
||||
$template->assign('tabsheet', $this->sheets);
|
||||
$template->assign('tabsheet_selected', $this->selected);
|
||||
|
||||
$selected_tab = $this->get_selected();
|
||||
|
||||
if (isset($selected_tab))
|
||||
{
|
||||
$template->assign(
|
||||
array($this->titlename => '['.$selected_tab['caption'].']'));
|
||||
}
|
||||
|
||||
$template->assign_var_from_handle($this->name, 'tabsheet');
|
||||
$template->clear_assign('tabsheet');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,770 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* class DummyTheme_maintain
|
||||
* used when a theme uses the old procedural declaration of maintenance methods
|
||||
*/
|
||||
class DummyTheme_maintain extends ThemeMaintain
|
||||
{
|
||||
function activate($theme_version, &$errors=array())
|
||||
{
|
||||
if (is_callable('theme_activate'))
|
||||
{
|
||||
return theme_activate($this->theme_id, $theme_version, $errors);
|
||||
}
|
||||
}
|
||||
function deactivate()
|
||||
{
|
||||
if (is_callable('theme_deactivate'))
|
||||
{
|
||||
return theme_deactivate($this->theme_id);
|
||||
}
|
||||
}
|
||||
function delete()
|
||||
{
|
||||
if (is_callable('theme_delete'))
|
||||
{
|
||||
return theme_delete($this->theme_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class themes
|
||||
{
|
||||
var $fs_themes = array();
|
||||
var $db_themes_by_id = array();
|
||||
var $server_themes = array();
|
||||
|
||||
/**
|
||||
* Initialize $fs_themes and $db_themes_by_id
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->get_fs_themes();
|
||||
|
||||
foreach ($this->get_db_themes() as $db_theme)
|
||||
{
|
||||
$this->db_themes_by_id[$db_theme['id']] = $db_theme;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maintain class of a theme
|
||||
* or build a new class with the procedural methods
|
||||
* @param string $theme_id
|
||||
*/
|
||||
private static function build_maintain_class($theme_id)
|
||||
{
|
||||
$file_to_include = PHPWG_THEMES_PATH.'/'.$theme_id.'/admin/maintain.inc.php';
|
||||
$classname = $theme_id.'_maintain';
|
||||
|
||||
if (file_exists($file_to_include))
|
||||
{
|
||||
include_once($file_to_include);
|
||||
|
||||
if (class_exists($classname))
|
||||
{
|
||||
return new $classname($theme_id);
|
||||
}
|
||||
}
|
||||
|
||||
return new DummyTheme_maintain($theme_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform requested actions
|
||||
* @param string - action
|
||||
* @param string - theme id
|
||||
* @param array - errors
|
||||
*/
|
||||
function perform_action($action, $theme_id)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!$conf['enable_extensions_install'] and 'delete' == $action)
|
||||
{
|
||||
die('Piwigo extensions install/update/delete system is disabled');
|
||||
}
|
||||
|
||||
if (isset($this->db_themes_by_id[$theme_id]))
|
||||
{
|
||||
$crt_db_theme = $this->db_themes_by_id[$theme_id];
|
||||
}
|
||||
|
||||
$theme_maintain = self::build_maintain_class($theme_id);
|
||||
|
||||
$errors = array();
|
||||
$activity_details = array('theme_id'=>$theme_id);
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'activate':
|
||||
if (isset($crt_db_theme))
|
||||
{
|
||||
// the theme is already active
|
||||
break;
|
||||
}
|
||||
|
||||
if ('default' == $theme_id)
|
||||
{
|
||||
// you can't activate the "default" theme
|
||||
break;
|
||||
}
|
||||
|
||||
$missing_parent = $this->missing_parent_theme($theme_id);
|
||||
if (isset($missing_parent))
|
||||
{
|
||||
$errors[] = l10n(
|
||||
'Impossible to activate this theme, the parent theme is missing: %s',
|
||||
$missing_parent
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->fs_themes[$theme_id]['mobile']
|
||||
and !empty($conf['mobile_theme'])
|
||||
and $conf['mobile_theme'] != $theme_id)
|
||||
{
|
||||
$errors[] = l10n('You can activate only one mobile theme.');
|
||||
break;
|
||||
}
|
||||
|
||||
$theme_maintain->activate($this->fs_themes[$theme_id]['version'], $errors);
|
||||
|
||||
if (empty($errors))
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '.THEMES_TABLE.'
|
||||
(id, version, name)
|
||||
VALUES(\''.$theme_id.'\',
|
||||
\''.$this->fs_themes[$theme_id]['version'].'\',
|
||||
\''.$this->fs_themes[$theme_id]['name'].'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$activity_details['version'] = $this->fs_themes[$theme_id]['version'];
|
||||
|
||||
if ($this->fs_themes[$theme_id]['mobile'])
|
||||
{
|
||||
conf_update_param('mobile_theme', $theme_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
if (!isset($crt_db_theme))
|
||||
{
|
||||
// the theme is already inactive
|
||||
break;
|
||||
}
|
||||
|
||||
// you can't deactivate the last theme
|
||||
if (count($this->db_themes_by_id) <= 1)
|
||||
{
|
||||
$errors[] = l10n('Impossible to deactivate this theme, you need at least one theme.');
|
||||
break;
|
||||
}
|
||||
|
||||
if ($theme_id == get_default_theme())
|
||||
{
|
||||
// find a random theme to replace
|
||||
$new_theme = null;
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.THEMES_TABLE.'
|
||||
WHERE id != \''.$theme_id.'\'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) == 0)
|
||||
{
|
||||
$new_theme = 'default';
|
||||
}
|
||||
else
|
||||
{
|
||||
list($new_theme) = pwg_db_fetch_row($result);
|
||||
}
|
||||
|
||||
$this->set_default_theme($new_theme);
|
||||
}
|
||||
|
||||
$theme_maintain->deactivate();
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.THEMES_TABLE.'
|
||||
WHERE id= \''.$theme_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
if ($this->fs_themes[$theme_id]['mobile'])
|
||||
{
|
||||
conf_update_param('mobile_theme', '');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if (!empty($crt_db_theme))
|
||||
{
|
||||
$errors[] = 'CANNOT DELETE - THEME IS INSTALLED';
|
||||
break;
|
||||
}
|
||||
if (!isset($this->fs_themes[$theme_id]))
|
||||
{
|
||||
// nothing to do here
|
||||
break;
|
||||
}
|
||||
|
||||
$children = $this->get_children_themes($theme_id);
|
||||
if (count($children) > 0)
|
||||
{
|
||||
$errors[] = l10n(
|
||||
'Impossible to delete this theme. Other themes depends on it: %s',
|
||||
implode(', ', $children)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$theme_maintain->delete();
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
deltree(PHPWG_THEMES_PATH.$theme_id, PHPWG_THEMES_PATH . 'trash');
|
||||
break;
|
||||
|
||||
case 'set_default':
|
||||
// first we need to know which users are using the current default theme
|
||||
$this->set_default_theme($theme_id);
|
||||
break;
|
||||
}
|
||||
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_THEME, $action, $activity_details);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
function missing_parent_theme($theme_id)
|
||||
{
|
||||
if (!isset($this->fs_themes[$theme_id]['parent']))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = $this->fs_themes[$theme_id]['parent'];
|
||||
|
||||
if ('default' == $parent)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($this->fs_themes[$parent]))
|
||||
{
|
||||
return $parent;
|
||||
}
|
||||
|
||||
return $this->missing_parent_theme($parent);
|
||||
}
|
||||
|
||||
function get_children_themes($theme_id)
|
||||
{
|
||||
$children = array();
|
||||
|
||||
foreach ($this->fs_themes as $test_child)
|
||||
{
|
||||
if (isset($test_child['parent']) and $test_child['parent'] == $theme_id)
|
||||
{
|
||||
$children[] = $test_child['name'];
|
||||
}
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
function set_default_theme($theme_id)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
// first we need to know which users are using the current default theme
|
||||
$default_theme = get_default_theme();
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE theme = \''.$default_theme.'\'
|
||||
;';
|
||||
$user_ids = array_unique(
|
||||
array_merge(
|
||||
array_from_query($query, 'user_id'),
|
||||
array($conf['guest_id'], $conf['default_user_id'])
|
||||
)
|
||||
);
|
||||
|
||||
// $user_ids can't be empty, at least the default user has the default
|
||||
// theme
|
||||
|
||||
$query = '
|
||||
UPDATE '.USER_INFOS_TABLE.'
|
||||
SET theme = \''.$theme_id.'\'
|
||||
WHERE user_id IN ('.implode(',', $user_ids).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
function get_db_themes($id='')
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
*
|
||||
FROM '.THEMES_TABLE;
|
||||
|
||||
$clauses = array();
|
||||
if (!empty($id))
|
||||
{
|
||||
$clauses[] = 'id = \''.$id.'\'';
|
||||
}
|
||||
if (count($clauses) > 0)
|
||||
{
|
||||
$query .= '
|
||||
WHERE '. implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
$result = pwg_query($query);
|
||||
$themes = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$themes[] = $row;
|
||||
}
|
||||
return $themes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get themes defined in the theme directory
|
||||
*/
|
||||
function get_fs_themes()
|
||||
{
|
||||
$dir = opendir(PHPWG_THEMES_PATH);
|
||||
|
||||
while ($file = readdir($dir))
|
||||
{
|
||||
if ($file!='.' and $file!='..')
|
||||
{
|
||||
$path = PHPWG_THEMES_PATH.$file;
|
||||
if (is_dir($path)
|
||||
and preg_match('/^[a-zA-Z0-9-_]+$/', $file)
|
||||
and file_exists($path.'/themeconf.inc.php')
|
||||
)
|
||||
{
|
||||
$theme = array(
|
||||
'id' => $file,
|
||||
'name' => $file,
|
||||
'version' => '0',
|
||||
'uri' => '',
|
||||
'description' => '',
|
||||
'author' => '',
|
||||
'mobile' => false,
|
||||
);
|
||||
$theme_data = implode('', file($path.'/themeconf.inc.php'));
|
||||
if (preg_match("|Theme Name:\\s*(.+)|", $theme_data, $val))
|
||||
{
|
||||
$theme['name'] = trim( $val[1] );
|
||||
}
|
||||
if (preg_match("|Version:\\s*([\\w.-]+)|", $theme_data, $val))
|
||||
{
|
||||
$theme['version'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Theme URI:\\s*(https?:\\/\\/.+)|", $theme_data, $val))
|
||||
{
|
||||
$theme['uri'] = trim($val[1]);
|
||||
}
|
||||
if ($desc = load_language('description.txt', $path.'/', array('return' => true)))
|
||||
{
|
||||
$theme['description'] = trim($desc);
|
||||
}
|
||||
elseif (preg_match("|Description:\\s*(.+)|", $theme_data, $val))
|
||||
{
|
||||
$theme['description'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Author:\\s*(.+)|", $theme_data, $val))
|
||||
{
|
||||
$theme['author'] = trim($val[1]);
|
||||
}
|
||||
if (preg_match("|Author URI:\\s*(https?:\\/\\/.+)|", $theme_data, $val))
|
||||
{
|
||||
$theme['author uri'] = trim($val[1]);
|
||||
}
|
||||
if (!empty($theme['uri']) and strpos($theme['uri'] , 'extension_view.php?eid='))
|
||||
{
|
||||
list( , $extension) = explode('extension_view.php?eid=', $theme['uri']);
|
||||
if (is_numeric($extension)) $theme['extension'] = $extension;
|
||||
}
|
||||
if (preg_match('/["\']parent["\'][^"\']+["\']([^"\']+)["\']/', $theme_data, $val))
|
||||
{
|
||||
$theme['parent'] = $val[1];
|
||||
}
|
||||
if (preg_match('/["\']activable["\'].*?(true|false)/i', $theme_data, $val))
|
||||
{
|
||||
$theme['activable'] = get_boolean($val[1]);
|
||||
}
|
||||
if (preg_match('/["\']mobile["\'].*?(true|false)/i', $theme_data, $val))
|
||||
{
|
||||
$theme['mobile'] = get_boolean($val[1]);
|
||||
}
|
||||
if (preg_match('/["\']use_standard_pages["\'].*?(true|false)/i', $theme_data, $val))
|
||||
{
|
||||
$theme['use_standard_pages'] = get_boolean($val[1]);
|
||||
}
|
||||
|
||||
// screenshot
|
||||
$screenshot_path = $path.'/screenshot.png';
|
||||
if (file_exists($screenshot_path))
|
||||
{
|
||||
$theme['screenshot'] = $screenshot_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
global $conf;
|
||||
$theme['screenshot'] =
|
||||
PHPWG_ROOT_PATH.'admin/themes/'
|
||||
.userprefs_get_param('admin_theme', 'clear')
|
||||
.'/images/missing_screenshot.png'
|
||||
;
|
||||
}
|
||||
|
||||
$admin_file = $path.'/admin/admin.inc.php';
|
||||
if (file_exists($admin_file))
|
||||
{
|
||||
$theme['admin_uri'] = get_root_url().'admin.php?page=theme&theme='.$file;
|
||||
}
|
||||
|
||||
// IMPORTANT SECURITY !
|
||||
$theme = array_map('htmlspecialchars', $theme);
|
||||
$this->fs_themes[$file] = $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort fs_themes
|
||||
*/
|
||||
function sort_fs_themes($order='name')
|
||||
{
|
||||
switch ($order)
|
||||
{
|
||||
case 'name':
|
||||
uasort($this->fs_themes, 'name_compare');
|
||||
break;
|
||||
case 'status':
|
||||
$this->sort_themes_by_state();
|
||||
break;
|
||||
case 'author':
|
||||
uasort($this->fs_themes, array($this, 'theme_author_compare'));
|
||||
break;
|
||||
case 'id':
|
||||
uksort($this->fs_themes, 'strcasecmp');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve PEM server datas to $server_themes
|
||||
*/
|
||||
function get_server_themes($new=false)
|
||||
{
|
||||
global $user, $conf;
|
||||
|
||||
$get_data = array(
|
||||
'category_id' => $conf['pem_themes_category'],
|
||||
'format' => 'php',
|
||||
);
|
||||
|
||||
// Retrieve PEM versions
|
||||
$version = PHPWG_VERSION;
|
||||
$versions_to_check = array();
|
||||
$url = PEM_URL . '/api/get_version_list.php';
|
||||
if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
|
||||
{
|
||||
if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
|
||||
{
|
||||
$version = $pem_versions[0]['name'];
|
||||
}
|
||||
$branch = get_branch_from_version($version);
|
||||
foreach ($pem_versions as $pem_version)
|
||||
{
|
||||
if (strpos($pem_version['name'], $branch) === 0)
|
||||
{
|
||||
$versions_to_check[] = $pem_version['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($versions_to_check))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Themes to check
|
||||
$themes_to_check = array();
|
||||
foreach($this->fs_themes as $fs_theme)
|
||||
{
|
||||
if (isset($fs_theme['extension']))
|
||||
{
|
||||
$themes_to_check[] = $fs_theme['extension'];
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve PEM themes infos
|
||||
$url = PEM_URL . '/api/get_revision_list-next.php';
|
||||
$get_data = array_merge($get_data, array(
|
||||
'last_revision_only' => 'true',
|
||||
'version' => implode(',', $versions_to_check),
|
||||
'lang' => substr($user['language'], 0, 2),
|
||||
'get_nb_downloads' => 'true',
|
||||
)
|
||||
);
|
||||
|
||||
if (!empty($themes_to_check))
|
||||
{
|
||||
if ($new)
|
||||
{
|
||||
$get_data['extension_exclude'] = implode(',', $themes_to_check);
|
||||
}
|
||||
else
|
||||
{
|
||||
$get_data['extension_include'] = implode(',', $themes_to_check);
|
||||
}
|
||||
}
|
||||
if (fetchRemote($url, $result, $get_data))
|
||||
{
|
||||
$pem_themes = @unserialize($result);
|
||||
if (!is_array($pem_themes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foreach ($pem_themes as $theme)
|
||||
{
|
||||
$this->server_themes[$theme['extension_id']] = $theme;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort $server_themes
|
||||
*/
|
||||
function sort_server_themes($order='date')
|
||||
{
|
||||
switch ($order)
|
||||
{
|
||||
case 'date':
|
||||
krsort($this->server_themes);
|
||||
break;
|
||||
case 'revision':
|
||||
usort($this->server_themes, array($this, 'extension_revision_compare'));
|
||||
break;
|
||||
case 'name':
|
||||
uasort($this->server_themes, array($this, 'extension_name_compare'));
|
||||
break;
|
||||
case 'author':
|
||||
uasort($this->server_themes, array($this, 'extension_author_compare'));
|
||||
break;
|
||||
case 'downloads':
|
||||
usort($this->server_themes, array($this, 'extension_downloads_compare'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract theme files from archive
|
||||
*
|
||||
* @param string - install or upgrade
|
||||
* @param string - remote revision identifier (numeric)
|
||||
* @param string - theme id or extension id
|
||||
*/
|
||||
function extract_theme_files($action, $revision, $dest, &$theme_id=null)
|
||||
{
|
||||
global $logger;
|
||||
|
||||
if ($archive = tempnam( PHPWG_THEMES_PATH, 'zip'))
|
||||
{
|
||||
$url = PEM_URL . '/download.php';
|
||||
$get_data = array(
|
||||
'rid' => $revision,
|
||||
'origin' => 'piwigo_'.$action,
|
||||
);
|
||||
|
||||
if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
|
||||
{
|
||||
fclose($handle);
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
|
||||
$zip = new PclZip($archive);
|
||||
if ($list = $zip->listContent())
|
||||
{
|
||||
foreach ($list as $file)
|
||||
{
|
||||
// we search main.inc.php in archive
|
||||
if (basename($file['filename']) == 'themeconf.inc.php'
|
||||
and (!isset($main_filepath)
|
||||
or strlen($file['filename']) < strlen($main_filepath)))
|
||||
{
|
||||
$main_filepath = $file['filename'];
|
||||
}
|
||||
}
|
||||
|
||||
$logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
|
||||
|
||||
if (isset($main_filepath))
|
||||
{
|
||||
$root = dirname($main_filepath); // main.inc.php path in archive
|
||||
if ($action == 'upgrade')
|
||||
{
|
||||
$theme_id = $dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
$theme_id = ($root == '.' ? 'extension_' . $dest : basename($root));
|
||||
}
|
||||
$extract_path = PHPWG_THEMES_PATH . $theme_id;
|
||||
$logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
|
||||
|
||||
if (
|
||||
$result = $zip->extract(
|
||||
PCLZIP_OPT_PATH, $extract_path,
|
||||
PCLZIP_OPT_REMOVE_PATH, $root,
|
||||
PCLZIP_OPT_REPLACE_NEWER
|
||||
)
|
||||
)
|
||||
{
|
||||
foreach ($result as $file)
|
||||
{
|
||||
if ($file['stored_filename'] == $main_filepath)
|
||||
{
|
||||
$status = $file['status'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (file_exists($extract_path.'/obsolete.list')
|
||||
and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
|
||||
and !empty($old_files))
|
||||
{
|
||||
$old_files[] = 'obsolete.list';
|
||||
|
||||
$logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
|
||||
|
||||
$extract_path_realpath = realpath($extract_path);
|
||||
|
||||
foreach($old_files as $old_file)
|
||||
{
|
||||
$old_file = trim($old_file);
|
||||
$old_file = trim($old_file, '/'); // prevent path starting with a "/"
|
||||
|
||||
if (empty($old_file)) // empty here means the extension itself
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $extract_path.'/'.$old_file;
|
||||
|
||||
// make sure the obsolete file is withing the extension directory, prevent traversal path
|
||||
$realpath = realpath($path);
|
||||
if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$logger->debug(__FUNCTION__.', to delete = '.$path);
|
||||
|
||||
if (is_file($path))
|
||||
{
|
||||
@unlink($path);
|
||||
}
|
||||
elseif (is_dir($path))
|
||||
{
|
||||
deltree($path, PHPWG_THEMES_PATH . 'trash');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else $status = 'extract_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'archive_error';
|
||||
}
|
||||
else $status = 'dl_archive_error';
|
||||
}
|
||||
else $status = 'temp_path_error';
|
||||
|
||||
@unlink($archive);
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort functions
|
||||
*/
|
||||
function extension_revision_compare($a, $b)
|
||||
{
|
||||
if ($a['revision_date'] < $b['revision_date']) return 1;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
function extension_name_compare($a, $b)
|
||||
{
|
||||
return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
|
||||
}
|
||||
|
||||
function extension_author_compare($a, $b)
|
||||
{
|
||||
$r = strcasecmp($a['author_name'], $b['author_name']);
|
||||
if ($r == 0) return $this->extension_name_compare($a, $b);
|
||||
else return $r;
|
||||
}
|
||||
|
||||
function theme_author_compare($a, $b)
|
||||
{
|
||||
$r = strcasecmp($a['author'], $b['author']);
|
||||
if ($r == 0) return name_compare($a, $b);
|
||||
else return $r;
|
||||
}
|
||||
|
||||
function extension_downloads_compare($a, $b)
|
||||
{
|
||||
if ($a['extension_nb_downloads'] < $b['extension_nb_downloads']) return 1;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
function sort_themes_by_state()
|
||||
{
|
||||
uasort($this->fs_themes, 'name_compare');
|
||||
|
||||
$active_themes = array();
|
||||
$inactive_themes = array();
|
||||
$not_installed = array();
|
||||
|
||||
foreach($this->fs_themes as $theme_id => $theme)
|
||||
{
|
||||
if (isset($this->db_themes_by_id[$theme_id]))
|
||||
{
|
||||
$this->db_themes_by_id[$theme_id]['state'] == 'active' ?
|
||||
$active_themes[$theme_id] = $theme : $inactive_themes[$theme_id] = $theme;
|
||||
}
|
||||
else
|
||||
{
|
||||
$not_installed[$theme_id] = $theme;
|
||||
}
|
||||
}
|
||||
$this->fs_themes = $active_themes + $inactive_themes + $not_installed;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,668 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions.inc.php');
|
||||
|
||||
class updates
|
||||
{
|
||||
var $types = array();
|
||||
var $plugins;
|
||||
var $themes;
|
||||
var $languages;
|
||||
var $missing = array();
|
||||
var $default_plugins = array();
|
||||
var $default_themes = array();
|
||||
var $default_languages = array();
|
||||
var $merged_extensions = array();
|
||||
var $merged_extension_url = 'http://piwigo.org/download/merged_extensions.txt';
|
||||
|
||||
function __construct($page='updates')
|
||||
{
|
||||
$this->types = array('plugins', 'themes', 'languages');
|
||||
|
||||
if (in_array($page, $this->types))
|
||||
{
|
||||
$this->types = array($page);
|
||||
}
|
||||
$this->default_themes = array('modus', 'elegant', 'smartpocket');
|
||||
$this->default_plugins = array('AdminTools', 'TakeATour', 'language_switch', 'LocalFilesEditor');
|
||||
|
||||
foreach ($this->types as $type)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/'.$type.'.class.php');
|
||||
$this->$type = new $type();
|
||||
}
|
||||
}
|
||||
|
||||
static function check_piwigo_upgrade()
|
||||
{
|
||||
$_SESSION['need_update'.PHPWG_VERSION] = null;
|
||||
|
||||
if (preg_match('/(\d+\.\d+)\.(\d+)/', PHPWG_VERSION, $matches)
|
||||
and @fetchRemote(PHPWG_URL.'/download/all_versions.php?rand='.md5(uniqid(rand(), true)), $result))
|
||||
{
|
||||
$all_versions = @explode("\n", $result);
|
||||
$new_version = trim($all_versions[0]);
|
||||
$_SESSION['need_update'.PHPWG_VERSION] = version_compare(PHPWG_VERSION, $new_version, '<');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* finds new versions of Piwigo on Piwigo.org.
|
||||
*
|
||||
* @since 2.9
|
||||
* @return array (
|
||||
* 'piwigo.org-checked' => has piwigo.org been checked?,
|
||||
* 'is_dev' => are we on a dev version?,
|
||||
* 'minor_version' => new minor version available,
|
||||
* 'major_version' => new major version available,
|
||||
* )
|
||||
*/
|
||||
function get_piwigo_new_versions()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$new_versions = array(
|
||||
'piwigo.org-checked' => false,
|
||||
'is_dev' => true,
|
||||
);
|
||||
|
||||
list($env, $build_version) = get_container_info();
|
||||
if (preg_match('/^(\d+\.\d+)\.(\d+)$/', PHPWG_VERSION))
|
||||
{
|
||||
$new_versions['is_dev'] = false;
|
||||
$actual_branch = get_branch_from_version(('Official' === $env)
|
||||
? substr($build_version, 0, -1)
|
||||
: PHPWG_VERSION
|
||||
);
|
||||
|
||||
$url = PHPWG_URL.'/download/all_versions.php';
|
||||
$url.= '?rand='.md5(uniqid(rand(), true)); // Avoid server cache
|
||||
$url .= ('Official' === $env) ? '&docker' : '&show_requirements'; // Check docker version if in container
|
||||
$url.= '&origin_hash='.sha1($conf['secret_key'].get_absolute_root_url());
|
||||
|
||||
if (@fetchRemote($url, $result)
|
||||
and $all_versions = @explode("\n", $result)
|
||||
and is_array($all_versions))
|
||||
{
|
||||
$new_versions['piwigo.org-checked'] = true;
|
||||
$last_version = trim($all_versions[0]);
|
||||
if ('Official' === $env)
|
||||
{
|
||||
if ($this->container_version_compare($build_version, $last_version))
|
||||
{
|
||||
$last_branch = get_branch_from_version(substr($last_version, 0, -1));
|
||||
if ($last_branch == $actual_branch)
|
||||
{
|
||||
$new_versions['minor'] = $last_version;
|
||||
}
|
||||
else
|
||||
{
|
||||
$new_versions['major'] = $last_version;
|
||||
foreach ($all_versions as $version)
|
||||
{
|
||||
$branch = get_branch_from_version(substr($version, 0, -1));
|
||||
if ($branch == $actual_branch)
|
||||
{
|
||||
if ($this->container_version_compare($build_version, $version))
|
||||
{
|
||||
$new_versions['minor'] = $version;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list($last_version_number, $last_version_php) = explode('/', trim($all_versions[0]));
|
||||
|
||||
if (version_compare(PHPWG_VERSION, $last_version_number, '<'))
|
||||
{
|
||||
$last_branch = get_branch_from_version($last_version_number);
|
||||
|
||||
if ($last_branch == $actual_branch)
|
||||
{
|
||||
$new_versions['minor'] = $last_version_number;
|
||||
$new_versions['minor_php'] = $last_version_php;
|
||||
}
|
||||
else
|
||||
{
|
||||
$new_versions['major'] = $last_version_number;
|
||||
$new_versions['major_php'] = $last_version_php;
|
||||
|
||||
// Check if new version exists in same branch
|
||||
foreach ($all_versions as $version)
|
||||
{
|
||||
list($version_number, $version_php) = explode('/', trim($version));
|
||||
$branch = get_branch_from_version($version_number);
|
||||
|
||||
if ($branch == $actual_branch)
|
||||
{
|
||||
if (version_compare(PHPWG_VERSION, $version_number, '<'))
|
||||
{
|
||||
$new_versions['minor'] = $version_number;
|
||||
$new_versions['minor_php'] = $version_php;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $new_versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for new versions of Piwigo. Notify webmasters if new versions are available, but not too often, see
|
||||
* $conf['update_notify_reminder_period'] parameter.
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
function notify_piwigo_new_versions()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!pwg_is_dbconf_writeable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$new_versions = $this->get_piwigo_new_versions();
|
||||
conf_update_param('update_notify_last_check', date('c'));
|
||||
|
||||
if ($new_versions['is_dev'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$new_versions_string = join(
|
||||
' & ',
|
||||
array_intersect_key(
|
||||
$new_versions,
|
||||
array_fill_keys(array('minor', 'major'), 1)
|
||||
)
|
||||
);
|
||||
|
||||
if (empty($new_versions_string))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// In which case should we notify?
|
||||
// 1. never notified
|
||||
// 2. new versions
|
||||
// 3. no new versions but reminder needed
|
||||
|
||||
$notify = false;
|
||||
if (!isset($conf['update_notify_last_notification']))
|
||||
{
|
||||
$notify = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$conf['update_notify_last_notification'] = safe_unserialize($conf['update_notify_last_notification']);
|
||||
$last_notification = $conf['update_notify_last_notification']['notified_on'];
|
||||
|
||||
if ($new_versions_string != $conf['update_notify_last_notification']['version'])
|
||||
{
|
||||
$notify = true;
|
||||
}
|
||||
elseif (
|
||||
$conf['update_notify_reminder_period'] > 0
|
||||
and strtotime($last_notification) < strtotime($conf['update_notify_reminder_period'].' seconds ago')
|
||||
)
|
||||
{
|
||||
$notify = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($notify)
|
||||
{
|
||||
// send email
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
|
||||
switch_lang_to(get_default_language());
|
||||
|
||||
$content = l10n('Hello,');
|
||||
$content.= "\n\n".l10n(
|
||||
'Time has come to update your Piwigo with version %s, go to %s',
|
||||
$new_versions_string,
|
||||
get_absolute_root_url().'admin.php?page=updates'
|
||||
);
|
||||
$content.= "\n\n".l10n('It only takes a few clicks.');
|
||||
$content.= "\n\n".l10n('Running on an up-to-date Piwigo is important for security.');
|
||||
|
||||
pwg_mail_admins(
|
||||
array(
|
||||
'subject' => l10n('Piwigo %s is available, please update', $new_versions_string),
|
||||
'content' => $content,
|
||||
'content_format' => 'text/plain',
|
||||
),
|
||||
array(
|
||||
'filename' => 'notification_admin',
|
||||
),
|
||||
false, // do not exclude current user
|
||||
true // only webmasters
|
||||
);
|
||||
|
||||
switch_lang_back();
|
||||
|
||||
// save notify
|
||||
conf_update_param(
|
||||
'update_notify_last_notification',
|
||||
array(
|
||||
'version' => $new_versions_string,
|
||||
'notified_on' => date('c'),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function get_server_extensions($version=PHPWG_VERSION)
|
||||
{
|
||||
global $user;
|
||||
|
||||
$get_data = array(
|
||||
'format' => 'php',
|
||||
);
|
||||
|
||||
// Retrieve PEM versions
|
||||
$versions_to_check = array();
|
||||
$url = PEM_URL . '/api/get_version_list.php';
|
||||
if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
|
||||
{
|
||||
if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
|
||||
{
|
||||
$version = $pem_versions[0]['name'];
|
||||
}
|
||||
$branch = get_branch_from_version($version);
|
||||
foreach ($pem_versions as $pem_version)
|
||||
{
|
||||
if (strpos($pem_version['name'], $branch) === 0)
|
||||
{
|
||||
$versions_to_check[] = $pem_version['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($versions_to_check))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extensions to check
|
||||
$ext_to_check = array();
|
||||
foreach ($this->types as $type)
|
||||
{
|
||||
$fs = 'fs_'.$type;
|
||||
foreach ($this->$type->$fs as $ext)
|
||||
{
|
||||
if (isset($ext['extension']))
|
||||
{
|
||||
$ext_to_check[$ext['extension']] = $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve PEM plugins infos
|
||||
$url = PEM_URL . '/api/get_revision_list.php';
|
||||
$get_data = array_merge($get_data, array(
|
||||
'last_revision_only' => 'true',
|
||||
'version' => implode(',', $versions_to_check),
|
||||
'lang' => substr($user['language'], 0, 2),
|
||||
'get_nb_downloads' => 'true',
|
||||
)
|
||||
);
|
||||
|
||||
$post_data = array();
|
||||
if (!empty($ext_to_check))
|
||||
{
|
||||
$post_data['extension_include'] = implode(',', array_keys($ext_to_check));
|
||||
}
|
||||
|
||||
if (fetchRemote($url, $result, $get_data, $post_data))
|
||||
{
|
||||
$pem_exts = @unserialize($result);
|
||||
if (!is_array($pem_exts))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$servers = array();
|
||||
|
||||
foreach ($pem_exts as $ext)
|
||||
{
|
||||
if (isset($ext_to_check[$ext['extension_id']]))
|
||||
{
|
||||
$type = $ext_to_check[$ext['extension_id']];
|
||||
|
||||
if (!isset($servers[$type]))
|
||||
{
|
||||
$servers[$type] = array();
|
||||
}
|
||||
|
||||
$servers[$type][ $ext['extension_id'] ] = $ext;
|
||||
|
||||
unset($ext_to_check[$ext['extension_id']]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($servers as $server_type => $extension_list)
|
||||
{
|
||||
$server_string = 'server_'.$server_type;
|
||||
|
||||
$this->$server_type->$server_string = $extension_list;
|
||||
}
|
||||
|
||||
$this->check_missing_extensions($ext_to_check);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check all extensions upgrades
|
||||
function check_extensions()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!$this->get_server_extensions())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$_SESSION['extensions_need_update'] = array();
|
||||
|
||||
foreach ($this->types as $type)
|
||||
{
|
||||
$fs = 'fs_'.$type;
|
||||
$server = 'server_'.$type;
|
||||
$server_ext = $this->$type->$server;
|
||||
$fs_ext = $this->$type->$fs;
|
||||
|
||||
$ignore_list = array();
|
||||
$need_upgrade = array();
|
||||
|
||||
foreach($fs_ext as $ext_id => $fs_ext)
|
||||
{
|
||||
if (isset($fs_ext['extension']) and isset($server_ext[$fs_ext['extension']]))
|
||||
{
|
||||
$ext_info = $server_ext[$fs_ext['extension']];
|
||||
|
||||
if (!safe_version_compare($fs_ext['version'], $ext_info['revision_name'], '>='))
|
||||
{
|
||||
if (in_array($ext_id, $conf['updates_ignored'][$type]))
|
||||
{
|
||||
$ignore_list[] = $ext_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['extensions_need_update'][$type][$ext_id] = $ext_info['revision_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$conf['updates_ignored'][$type] = $ignore_list;
|
||||
}
|
||||
conf_update_param('updates_ignored', pwg_db_real_escape_string(serialize($conf['updates_ignored'])));
|
||||
}
|
||||
|
||||
// Check if extension have been upgraded since last check
|
||||
function check_updated_extensions()
|
||||
{
|
||||
foreach ($this->types as $type)
|
||||
{
|
||||
if (!empty($_SESSION['extensions_need_update'][$type]))
|
||||
{
|
||||
$fs = 'fs_'.$type;
|
||||
foreach($this->$type->$fs as $ext_id => $fs_ext)
|
||||
{
|
||||
if (isset($_SESSION['extensions_need_update'][$type][$ext_id])
|
||||
and safe_version_compare($fs_ext['version'], $_SESSION['extensions_need_update'][$type][$ext_id], '>='))
|
||||
{
|
||||
// Extension have been upgraded
|
||||
$this->check_extensions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function check_missing_extensions($missing)
|
||||
{
|
||||
foreach ($missing as $id => $type)
|
||||
{
|
||||
$fs = 'fs_'.$type;
|
||||
$default = 'default_'.$type;
|
||||
foreach ($this->$type->$fs as $ext_id => $ext)
|
||||
{
|
||||
if (isset($ext['extension']) and $id == $ext['extension']
|
||||
and !in_array($ext_id, $this->$default)
|
||||
and !in_array($ext['extension'], $this->merged_extensions))
|
||||
{
|
||||
$this->missing[$type][] = $ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get_merged_extensions($version)
|
||||
{
|
||||
if (fetchRemote($this->merged_extension_url, $result))
|
||||
{
|
||||
$rows = explode("\n", $result);
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
if (preg_match('/^(\d+\.\d+): *(.*)$/', $row, $match))
|
||||
{
|
||||
if (version_compare($version, $match[1], '>='))
|
||||
{
|
||||
$extensions = explode(',', trim($match[2]));
|
||||
$this->merged_extensions = array_merge($this->merged_extensions, $extensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function process_obsolete_list($file)
|
||||
{
|
||||
if (file_exists(PHPWG_ROOT_PATH.$file)
|
||||
and $old_files = file(PHPWG_ROOT_PATH.$file, FILE_IGNORE_NEW_LINES)
|
||||
and !empty($old_files))
|
||||
{
|
||||
$old_files[] = $file;
|
||||
foreach($old_files as $old_file)
|
||||
{
|
||||
$path = PHPWG_ROOT_PATH.$old_file;
|
||||
if (is_file($path))
|
||||
{
|
||||
@unlink($path);
|
||||
}
|
||||
elseif (is_dir($path))
|
||||
{
|
||||
deltree($path, PHPWG_ROOT_PATH.'_trash');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function upgrade_to($upgrade_to, &$step, $check_current_version=true)
|
||||
{
|
||||
global $page, $conf, $template;
|
||||
|
||||
if ($check_current_version and !version_compare($upgrade_to, PHPWG_VERSION, '>'))
|
||||
{
|
||||
// TODO why redirect to a plugin page? maybe a remaining code from when
|
||||
// the update system was provided as a plugin?
|
||||
redirect(get_root_url().'admin.php?page=plugin-'.basename(dirname(__FILE__)));
|
||||
}
|
||||
|
||||
$obsolete_list = null;
|
||||
|
||||
if ($step == 2)
|
||||
{
|
||||
$code = get_branch_from_version(PHPWG_VERSION).'.x_to_'.$upgrade_to;
|
||||
$dl_code = str_replace(array('.', '_'), '', $code);
|
||||
$remove_path = $code;
|
||||
// no longer try to delete files on a minor upgrade
|
||||
// $obsolete_list = 'obsolete.list';
|
||||
}
|
||||
else
|
||||
{
|
||||
$code = $upgrade_to;
|
||||
$dl_code = $code;
|
||||
$remove_path = version_compare($code, '2.0.8', '>=') ? 'piwigo' : 'piwigo-'.$code;
|
||||
$obsolete_list = PHPWG_ROOT_PATH.'install/obsolete.list';
|
||||
}
|
||||
|
||||
if (empty($page['errors']))
|
||||
{
|
||||
$path = PHPWG_ROOT_PATH.$conf['data_location'].'update';
|
||||
$filename = $path.'/'.$code.'.zip';
|
||||
@mkgetdir($path);
|
||||
|
||||
$chunk_num = 0;
|
||||
$end = false;
|
||||
$zip = @fopen($filename, 'w');
|
||||
|
||||
while (!$end)
|
||||
{
|
||||
$chunk_num++;
|
||||
if (@fetchRemote(PHPWG_URL.'/download/dlcounter.php?code='.$dl_code.'&chunk_num='.$chunk_num, $result)
|
||||
and $input = @unserialize($result))
|
||||
{
|
||||
if (0 == $input['remaining'])
|
||||
{
|
||||
$end = true;
|
||||
}
|
||||
@fwrite($zip, base64_decode($input['data']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$end = true;
|
||||
}
|
||||
}
|
||||
@fclose($zip);
|
||||
|
||||
if (@filesize($filename))
|
||||
{
|
||||
$zip = new PclZip($filename);
|
||||
if ($result = $zip->extract(PCLZIP_OPT_PATH, PHPWG_ROOT_PATH,
|
||||
PCLZIP_OPT_REMOVE_PATH, $remove_path,
|
||||
PCLZIP_OPT_SET_CHMOD, 0755,
|
||||
PCLZIP_OPT_REPLACE_NEWER))
|
||||
{
|
||||
//Check if all files were extracted
|
||||
$error = '';
|
||||
foreach($result as $extract)
|
||||
{
|
||||
if (!in_array($extract['status'], array('ok', 'filtered', 'already_a_directory')))
|
||||
{
|
||||
// Try to change chmod and extract
|
||||
if (@chmod(PHPWG_ROOT_PATH.$extract['filename'], 0777)
|
||||
and ($res = $zip->extract(PCLZIP_OPT_BY_NAME, $remove_path.'/'.$extract['filename'],
|
||||
PCLZIP_OPT_PATH, PHPWG_ROOT_PATH,
|
||||
PCLZIP_OPT_REMOVE_PATH, $remove_path,
|
||||
PCLZIP_OPT_SET_CHMOD, 0755,
|
||||
PCLZIP_OPT_REPLACE_NEWER))
|
||||
and isset($res[0]['status'])
|
||||
and $res[0]['status'] == 'ok')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$error .= $extract['filename'].': '.$extract['status']."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($error))
|
||||
{
|
||||
if (!empty($obsolete_list))
|
||||
{
|
||||
self::process_obsolete_list($obsolete_list);
|
||||
}
|
||||
|
||||
deltree(PHPWG_ROOT_PATH.$conf['data_location'].'update');
|
||||
invalidate_user_cache(true);
|
||||
conf_update_param('piwigo_installed_version', $upgrade_to);
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'update', array('from_version'=>PHPWG_VERSION, 'to_version'=>$upgrade_to));
|
||||
|
||||
if ($step == 2)
|
||||
{
|
||||
// only delete compiled templates on minor update. Doing this on
|
||||
// a major update might even encounter fatal error if Smarty
|
||||
// changes. Anyway, a compiled template purge will be performed
|
||||
// by upgrade.php
|
||||
$template->delete_compiled_templates();
|
||||
conf_delete_param('fs_quick_check_last_check');
|
||||
|
||||
$page['infos'][] = l10n('Update Complete');
|
||||
$page['infos'][] = $upgrade_to;
|
||||
$page['updated_version'] = $upgrade_to;
|
||||
$step = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect(PHPWG_ROOT_PATH.'upgrade.php?now=');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
file_put_contents(PHPWG_ROOT_PATH.$conf['data_location'].'update/log_error.txt', $error);
|
||||
|
||||
$page['errors'][] = l10n(
|
||||
'An error has occured during extract. Please check files permissions of your piwigo installation.<br><a href="%s">Click here to show log error</a>.',
|
||||
get_root_url().$conf['data_location'].'update/log_error.txt'
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deltree(PHPWG_ROOT_PATH.$conf['data_location'].'update');
|
||||
$page['errors'][] = l10n('An error has occured during upgrade.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('Piwigo cannot retrieve upgrade file from server');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compare version number with a letter suffix
|
||||
// Similar to version_compare with "<" sign
|
||||
function container_version_compare($v1,$v2)
|
||||
{
|
||||
// Split 16.2.0d into "16.2.0" as semantic_ver and "d" as sub_ver
|
||||
$v1_semantic_ver = substr($v1, 0, -1);
|
||||
$v1_sub_ver = substr($v1, -1);
|
||||
$v2_semantic_ver = substr($v2, 0, -1);
|
||||
$v2_sub_ver = substr($v2, -1);
|
||||
|
||||
$res = version_compare($v1_semantic_ver, $v2_semantic_ver);
|
||||
|
||||
// Return for any
|
||||
if ($res === 0)
|
||||
{
|
||||
return strcmp($v1_sub_ver, $v2_sub_ver) < 0;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('users');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
?>
|
||||
@@ -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();
|
||||
?>
|
||||
@@ -0,0 +1,472 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/c13y_internal.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['action']) and 'hide_newsletter_subscription' == $_GET['action'])
|
||||
{
|
||||
userprefs_update_param('show_newsletter_subscription', 'false');
|
||||
exit();
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('admin_home');
|
||||
$tabsheet->select('');
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | actions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($page['nb_pending_comments']))
|
||||
{
|
||||
$message = l10n('User comments').' <i class="icon-chat"></i> ';
|
||||
$message.= '<a href="'.$link_start.'comments">';
|
||||
$message.= l10n('%d waiting for validation', $page['nb_pending_comments']);
|
||||
$message.= ' <i class="icon-right"></i></a>';
|
||||
|
||||
$page['messages'][] = $message;
|
||||
}
|
||||
|
||||
// any orphan photo?
|
||||
$nb_orphans = $page['nb_orphans']; // already calculated in admin.php
|
||||
|
||||
if ($page['nb_photos_total'] >= 100000) // but has not been calculated on a big gallery, so force it now
|
||||
{
|
||||
$nb_orphans = count_orphans();
|
||||
}
|
||||
|
||||
if ($nb_orphans > 0)
|
||||
{
|
||||
$orphans_url = PHPWG_ROOT_PATH.'admin.php?page=batch_manager&filter=prefilter-no_album';
|
||||
|
||||
$message = '<a href="'.$orphans_url.'"><i class="icon-heart-broken"></i>';
|
||||
$message.= l10n('Orphans').'</a>';
|
||||
$message.= '<span class="adminMenubarCounter">'.$nb_orphans.'</span>';
|
||||
|
||||
$page['warnings'][] = $message;
|
||||
}
|
||||
|
||||
// locked album ?
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE visible =\'false\'
|
||||
;';
|
||||
list($locked_album) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($locked_album > 0)
|
||||
{
|
||||
$locked_album_url = PHPWG_ROOT_PATH.'admin.php?page=cat_options§ion=visible';
|
||||
|
||||
$message = '<a href="'.$locked_album_url.'"><i class="icon-cone"></i>';
|
||||
$message.= l10n('Locked album').'</a>';
|
||||
$message.= '<span class="adminMenubarCounter">'.$locked_album.'</span>';
|
||||
|
||||
$page['warnings'][] = $message;
|
||||
}
|
||||
|
||||
fs_quick_check();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(array('intro' => 'intro.tpl'));
|
||||
|
||||
if ($conf['show_newsletter_subscription'] and userprefs_get_param('show_newsletter_subscription', true)) {
|
||||
$query = '
|
||||
SELECT registration_date
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE registration_date IS NOT NULL
|
||||
ORDER BY user_id ASC
|
||||
LIMIT 1
|
||||
;';
|
||||
list($register_date) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
list($nb_cats) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
;';
|
||||
list($nb_images) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/mdetect.php');
|
||||
$uagent_obj = new uagent_info();
|
||||
// To see the newsletter promote, the account must have 2 weeks ancient, 3 albums created and 30 photos uploaded
|
||||
|
||||
if (!$uagent_obj->DetectIos() and strtotime($register_date) < strtotime('2 weeks ago') and $nb_cats >= 3 and $nb_images >= 30){
|
||||
$template->assign(
|
||||
array(
|
||||
'EMAIL' => $user['email'],
|
||||
'SUBSCRIBE_BASE_URL' => get_newsletter_subscribe_base_url($user['language']),
|
||||
'OLD_NEWSLETTERS_URL' => get_old_newsletters_base_url($user['language']),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$stats = get_pwg_general_statitics();
|
||||
|
||||
$du_decimals = 1;
|
||||
$du_gb = $stats['disk_usage']/(1024*1024);
|
||||
if ($du_gb > 100)
|
||||
{
|
||||
$du_decimals = 0;
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'NB_PHOTOS' => $stats['nb_photos'],
|
||||
'NB_ALBUMS' => $stats['nb_categories'],
|
||||
'NB_TAGS' => $stats['nb_tags'],
|
||||
'NB_IMAGE_TAG' => $stats['nb_image_tag'],
|
||||
'NB_USERS' => $stats['nb_users'],
|
||||
'NB_GROUPS' => $stats['nb_groups'],
|
||||
'NB_RATES' => $stats['nb_rates'],
|
||||
'NB_VIEWS' => number_format_human_readable($stats['nb_views']),
|
||||
'NB_PLUGINS' => count($pwg_loaded_plugins),
|
||||
'STORAGE_USED' => str_replace(' ', ' ', l10n('%sGB', number_format($du_gb, $du_decimals))),
|
||||
'U_QUICK_SYNC' => PHPWG_ROOT_PATH.'admin.php?page=site_update&site=1&quick_sync=1&pwg_token='.get_pwg_token(),
|
||||
'CHECK_FOR_UPDATES' => $conf['dashboard_check_for_updates'],
|
||||
)
|
||||
);
|
||||
|
||||
if ($conf['activate_comments'])
|
||||
{
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.COMMENTS_TABLE.'
|
||||
;';
|
||||
list($nb_comments) = pwg_db_fetch_row(pwg_query($query));
|
||||
$template->assign('NB_COMMENTS', $nb_comments);
|
||||
} else {
|
||||
$template->assign('NB_COMMENTS', 0);
|
||||
}
|
||||
|
||||
if ($conf['show_piwigo_latest_news'])
|
||||
{
|
||||
$latest_news = get_piwigo_news();
|
||||
|
||||
if (isset($latest_news['id']) and $latest_news['posted_on'] > time()-60*60*24*30)
|
||||
{
|
||||
$page['messages'][] = sprintf(
|
||||
'%s <a href="%s" title="%s" target="_blank"><i class="icon-bell"></i> %s</a>',
|
||||
l10n('Latest Piwigo news'),
|
||||
$latest_news['url'],
|
||||
time_since($latest_news['posted_on'], 'year').' ('.$latest_news['posted'].')',
|
||||
$latest_news['subject']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
trigger_notify('loc_end_intro');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | get activity data |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$nb_weeks = $conf['dashboard_activity_nb_weeks'];
|
||||
|
||||
//Count mondays
|
||||
$mondays = 0;
|
||||
//Get mondays number for the chart legend
|
||||
$week_number = array();
|
||||
//Array for sorting days in circle size
|
||||
$temp_data = array();
|
||||
|
||||
$activity_last_weeks = array();
|
||||
$date = new DateTime();
|
||||
|
||||
//Get data from $nb_weeks last weeks
|
||||
while ($mondays < $nb_weeks)
|
||||
{
|
||||
if ($date->format('D') == 'Mon')
|
||||
{
|
||||
$week_number[] = $date->format('W');
|
||||
$mondays += 1;
|
||||
}
|
||||
|
||||
$date->sub(new DateInterval('P1D'));
|
||||
}
|
||||
|
||||
$week_number = array_reverse($week_number);
|
||||
$date_string = $date->format('Y-m-d');
|
||||
|
||||
if (!isset($_SESSION['cache_activity_last_weeks']) or $_SESSION['cache_activity_last_weeks']['calculated_on'] < strtotime('5 minutes ago'))
|
||||
{
|
||||
$start_time = get_moment();
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
DATE_FORMAT(occured_on , \'%Y-%m-%d\') AS activity_day,
|
||||
object,
|
||||
action,
|
||||
COUNT(*) AS activity_counter
|
||||
FROM `'.ACTIVITY_TABLE.'`
|
||||
WHERE occured_on >= \''.$date_string.'\'
|
||||
GROUP BY activity_day, object, action
|
||||
;';
|
||||
$activity_actions = query2array($query);
|
||||
|
||||
foreach ($activity_actions as $action)
|
||||
{
|
||||
// set the time to 12:00 (midday) so that it doesn't goes to previous/next day due to timezone offset
|
||||
$day_date = new DateTime($action['activity_day'].' 12:00:00');
|
||||
|
||||
$week = 0;
|
||||
for ($i=0; $i < $nb_weeks; $i++)
|
||||
{
|
||||
if ($week_number[$i] == $day_date->format('W'))
|
||||
{
|
||||
$week = $i;
|
||||
}
|
||||
}
|
||||
$day_nb = $day_date->format('N');
|
||||
|
||||
@$activity_last_weeks[$week][$day_nb]['details'][ucfirst($action['object'])][ucfirst($action['action'])] = $action['activity_counter'];
|
||||
@$activity_last_weeks[$week][$day_nb]['number'] += $action['activity_counter'];
|
||||
@$activity_last_weeks[$week][$day_nb]['date'] = format_date($day_date->getTimestamp());
|
||||
}
|
||||
|
||||
$logger->debug('[admin/intro::'.__LINE__.'] recent activity calculated in '.get_elapsed_time($start_time, get_moment()));
|
||||
|
||||
$_SESSION['cache_activity_last_weeks'] = array(
|
||||
'calculated_on' => time(),
|
||||
'data' => $activity_last_weeks,
|
||||
);
|
||||
}
|
||||
|
||||
$activity_last_weeks = $_SESSION['cache_activity_last_weeks']['data'];
|
||||
|
||||
|
||||
foreach($activity_last_weeks as $week => $i)
|
||||
{
|
||||
foreach($i as $day => $j)
|
||||
{
|
||||
$details = $j['details'];
|
||||
ksort($details);
|
||||
$activity_last_weeks[$week][$day]['details'] = $details;
|
||||
if ($j['number'] > 0)
|
||||
{
|
||||
$temp_data[] = array('x' => $j['number'], 'd'=>$day, 'w'=>$week);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Algorithm to sort days in circle size :
|
||||
// * Get the difference between sorted numbers of activity per day (only not null numbers)
|
||||
// * Split days max $circle_sizes time on the biggest difference (but not below 120%)
|
||||
// * Set the sizes according to the groups created
|
||||
|
||||
//Function to sort days by number of activity
|
||||
function cmp_day($a, $b)
|
||||
{
|
||||
if ($a['x'] == $b['x'])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ($a['x'] < $b['x']) ? -1 : 1;
|
||||
}
|
||||
|
||||
usort($temp_data, 'cmp_day');
|
||||
|
||||
//Get the percent difference
|
||||
$diff_x = array();
|
||||
|
||||
for ($i=1; $i < count($temp_data); $i++)
|
||||
{
|
||||
$diff_x[] = $temp_data[$i]['x']/$temp_data[$i-1]['x']*100;
|
||||
}
|
||||
|
||||
$split = 0;
|
||||
//Split (split represented by -1)
|
||||
if (count($diff_x) > 0)
|
||||
{
|
||||
while (max($diff_x) > 120)
|
||||
{
|
||||
$diff_x[array_search(max($diff_x), $diff_x)] = -1;
|
||||
$split++;
|
||||
}
|
||||
}
|
||||
|
||||
//Fill empty chart data for the template
|
||||
$chart_data = array();
|
||||
for ($i=0; $i < $nb_weeks; $i++)
|
||||
{
|
||||
for ($j=1; $j <= 7; $j++)
|
||||
{
|
||||
$chart_data[$i][$j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$size = 1;
|
||||
|
||||
if (isset($temp_data[0]))
|
||||
{
|
||||
$chart_data[$temp_data[0]['w']][$temp_data[0]['d']] = $size;
|
||||
}
|
||||
|
||||
//Set sizes in chart data
|
||||
for ($i=1; $i < count($temp_data); $i++)
|
||||
{
|
||||
if ($diff_x[$i-1] == -1)
|
||||
{
|
||||
$size++;
|
||||
}
|
||||
$chart_data[$temp_data[$i]['w']][$temp_data[$i]['d']] = $size;
|
||||
}
|
||||
|
||||
//Assign data for the template
|
||||
$template->assign('ACTIVITY_WEEK_NUMBER',$week_number);
|
||||
$template->assign('ACTIVITY_LAST_WEEKS', $activity_last_weeks);
|
||||
$template->assign('ACTIVITY_CHART_DATA',$chart_data);
|
||||
$template->assign('ACTIVITY_CHART_NUMBER_SIZES',$size);
|
||||
|
||||
$day_labels = array();
|
||||
for ($i=0; $i<=6; $i++)
|
||||
{
|
||||
// first 3 letters of day name
|
||||
$day_labels[] = mb_substr($lang['day'][($i+1)%7], 0, 3);
|
||||
}
|
||||
$template->assign('DAY_LABELS', $day_labels);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | get storage data |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$video_format = array('webm','webmv','ogg','ogv','mp4','m4v', 'mov');
|
||||
$data_storage = array();
|
||||
|
||||
//Select files in Image_Table
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*) AS ext_counter,
|
||||
SUBSTRING_INDEX(path,".",-1) AS ext,
|
||||
SUM(filesize) AS filesize
|
||||
FROM `'.IMAGES_TABLE.'`
|
||||
GROUP BY ext
|
||||
;';
|
||||
|
||||
$file_extensions = query2array($query, 'ext');
|
||||
|
||||
foreach ($file_extensions as $ext => $ext_details)
|
||||
{
|
||||
$type = null;
|
||||
if (in_array(strtolower($ext), $conf['picture_ext']))
|
||||
{
|
||||
$type = 'Photos';
|
||||
}
|
||||
elseif (in_array(strtolower($ext), $video_format))
|
||||
{
|
||||
$type = 'Videos';
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = 'Other';
|
||||
}
|
||||
|
||||
@$data_storage[$type]['total']['filesize'] += $ext_details['filesize'];
|
||||
@$data_storage[$type]['total']['nb_files'] += $ext_details['ext_counter'];
|
||||
|
||||
@$data_storage[$type]['details'][strtoupper($ext)] = array(
|
||||
'filesize' => $ext_details['filesize'],
|
||||
'nb_files' => $ext_details['ext_counter'],
|
||||
);
|
||||
}
|
||||
|
||||
//Select files from format table
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*) AS ext_counter,
|
||||
ext,
|
||||
SUM(filesize) AS filesize
|
||||
FROM `'.IMAGE_FORMAT_TABLE.'`
|
||||
GROUP BY ext
|
||||
;';
|
||||
|
||||
$file_extensions = query2array($query, 'ext');
|
||||
foreach ($file_extensions as $ext => $ext_details)
|
||||
{
|
||||
$type = 'Formats';
|
||||
|
||||
@$data_storage[$type]['total']['filesize'] += $ext_details['filesize'];
|
||||
@$data_storage[$type]['total']['nb_files'] += $ext_details['ext_counter'];
|
||||
|
||||
@$data_storage[$type]['details'][strtoupper($ext)] = array(
|
||||
'filesize' => $ext_details['filesize'],
|
||||
'nb_files' => $ext_details['ext_counter'],
|
||||
);
|
||||
}
|
||||
|
||||
// Add cache size if requested and known.
|
||||
if ($conf['add_cache_to_storage_chart'] && isset($conf['cache_sizes']))
|
||||
{
|
||||
$cache_sizes = unserialize($conf['cache_sizes']);
|
||||
if (isset($cache_sizes))
|
||||
{
|
||||
if (isset($cache_sizes[0]) && isset($cache_sizes[0]['value']))
|
||||
{
|
||||
@$data_storage['Cache']['total']['filesize'] = $cache_sizes[0]['value']/1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate total storage
|
||||
$total_storage = 0;
|
||||
foreach ($data_storage as $value)
|
||||
{
|
||||
$total_storage += $value['total']['filesize'];
|
||||
}
|
||||
|
||||
//Pass data to HTML
|
||||
$template->assign('STORAGE_TOTAL',$total_storage);
|
||||
$template->assign('STORAGE_CHART_DATA',$data_storage);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'intro');
|
||||
|
||||
// Check integrity
|
||||
$c13y = new check_integrity();
|
||||
// add internal checks
|
||||
new c13y_internal();
|
||||
// check and display
|
||||
$c13y->check();
|
||||
$c13y->display();
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=languages';
|
||||
|
||||
if (isset($_GET['tab']))
|
||||
{
|
||||
check_input_parameter('tab', $_GET, false, '/^(installed|update|new)$/');
|
||||
$page['tab'] = $_GET['tab'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['tab'] = 'installed';
|
||||
}
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('languages');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
if ($page['tab'] == 'update') {
|
||||
include(PHPWG_ROOT_PATH.'admin/updates_ext.php');
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Languages'));
|
||||
}
|
||||
else
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/languages_'.$page['tab'].'.php');
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,123 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/languages.class.php');
|
||||
|
||||
$template->set_filenames(array('languages' => 'languages_installed.tpl'));
|
||||
|
||||
$base_url = get_root_url().'admin.php?page='.$page['page'];
|
||||
|
||||
$languages = new languages();
|
||||
$languages->get_db_languages();
|
||||
|
||||
//--------------------------------------------------perform requested actions
|
||||
check_input_parameter('action', $_GET, false, '/^(activate|deactivate|set_default|delete)$/');
|
||||
check_input_parameter('language', $_GET, false, '/^('.join('|', array_keys($languages->fs_languages)).')$/');
|
||||
|
||||
if (isset($_GET['action']) and isset($_GET['language']) and is_webmaster())
|
||||
{
|
||||
$page['errors'] = $languages->perform_action($_GET['action'], $_GET['language']);
|
||||
|
||||
if (empty($page['errors']))
|
||||
{
|
||||
redirect($base_url);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | start template output |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$default_language = get_default_language();
|
||||
|
||||
$tpl_languages = array();
|
||||
|
||||
foreach($languages->fs_languages as $language_id => $language)
|
||||
{
|
||||
$language['u_action'] = add_url_params($base_url, array('language' => $language_id));
|
||||
|
||||
if (in_array($language_id, array_keys($languages->db_languages)))
|
||||
{
|
||||
$language['state'] = 'active';
|
||||
$language['deactivable'] = true;
|
||||
|
||||
if (count($languages->db_languages) <= 1)
|
||||
{
|
||||
$language['deactivable'] = false;
|
||||
$language['deactivate_tooltip'] = l10n('Impossible to deactivate this language, you need at least one language.');
|
||||
}
|
||||
|
||||
if ($language_id == $default_language)
|
||||
{
|
||||
$language['deactivable'] = false;
|
||||
$language['deactivate_tooltip'] = l10n('Impossible to deactivate this language, first set another language as default.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$language['state'] = 'inactive';
|
||||
}
|
||||
|
||||
if ($language_id == $default_language)
|
||||
{
|
||||
$language['is_default'] = true;
|
||||
array_unshift($tpl_languages, $language);
|
||||
}
|
||||
else
|
||||
{
|
||||
$language['is_default'] = false;
|
||||
$tpl_languages[] = $language;
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'languages' => $tpl_languages,
|
||||
)
|
||||
);
|
||||
$template->append('language_states', 'active');
|
||||
$template->append('language_states', 'inactive');
|
||||
|
||||
|
||||
$missing_language_ids = array_diff(
|
||||
array_keys($languages->db_languages),
|
||||
array_keys($languages->fs_languages)
|
||||
);
|
||||
|
||||
foreach($missing_language_ids as $language_id)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.USER_INFOS_TABLE.'
|
||||
SET language = \''.get_default_language().'\'
|
||||
WHERE language = \''.$language_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.LANGUAGES_TABLE.'
|
||||
WHERE id= \''.$language_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Languages'));
|
||||
$template->assign('CONF_ENABLE_EXTENSIONS_INSTALL', $conf['enable_extensions_install']);
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'languages');
|
||||
?>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!$conf['enable_extensions_install'])
|
||||
{
|
||||
die('Piwigo extensions install/update system is disabled');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/languages.class.php');
|
||||
|
||||
$template->set_filenames(array('languages' => 'languages_new.tpl'));
|
||||
|
||||
$base_url = get_root_url().'admin.php?page='.$page['page'].'&tab='.$page['tab'];
|
||||
|
||||
$languages = new languages();
|
||||
$languages->get_db_languages();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | setup check |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$languages_dir = PHPWG_ROOT_PATH.'language';
|
||||
if (!is_writable($languages_dir))
|
||||
{
|
||||
$page['errors'][] = l10n('Add write access to the "%s" directory', 'language');
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | perform installation |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['revision']))
|
||||
{
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$page['errors'][] = l10n('Webmaster status is required.');
|
||||
}
|
||||
else
|
||||
{
|
||||
check_pwg_token();
|
||||
|
||||
$install_status = $languages->extract_language_files('install', $_GET['revision']);
|
||||
|
||||
redirect($base_url.'&installstatus='.$install_status);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | installation result |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (isset($_GET['installstatus']))
|
||||
{
|
||||
switch ($_GET['installstatus'])
|
||||
{
|
||||
case 'ok':
|
||||
$page['infos'][] = l10n('Language has been successfully installed');
|
||||
break;
|
||||
|
||||
case 'temp_path_error':
|
||||
$page['errors'][] = l10n('Can\'t create temporary file.');
|
||||
break;
|
||||
|
||||
case 'dl_archive_error':
|
||||
$page['errors'][] = l10n('Can\'t download archive.');
|
||||
break;
|
||||
|
||||
case 'archive_error':
|
||||
$page['errors'][] = l10n('Can\'t read or extract archive.');
|
||||
break;
|
||||
|
||||
default:
|
||||
$page['errors'][] = l10n('An error occured during extraction (%s).', htmlspecialchars($_GET['installstatus']));
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | start template output |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if ($languages->get_server_languages(true))
|
||||
{
|
||||
foreach($languages->server_languages as $language)
|
||||
{
|
||||
list($date, ) = explode(' ', $language['revision_date']);
|
||||
|
||||
$url_auto_install = htmlentities($base_url)
|
||||
. '&revision=' . $language['revision_id']
|
||||
. '&pwg_token='.get_pwg_token()
|
||||
;
|
||||
|
||||
$template->append('languages', array(
|
||||
'EXT_NAME' => $language['extension_name'],
|
||||
'EXT_DESC' => $language['extension_description'],
|
||||
'EXT_URL' => PEM_URL.'/extension_view.php?eid='.$language['extension_id'],
|
||||
'VERSION' => $language['revision_name'],
|
||||
'VER_DESC' => $language['revision_description'],
|
||||
'DATE' => $date,
|
||||
'AUTHOR' => $language['author_name'],
|
||||
'URL_INSTALL' => $url_auto_install,
|
||||
'URL_DOWNLOAD' => $language['download_url'] . '&origin=piwigo_download'));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('Can\'t connect to server.');
|
||||
}
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Languages'));
|
||||
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'languages');
|
||||
?>
|
||||
@@ -0,0 +1,125 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (isset($_GET['action']))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Commons parameters |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$maint_actions = array(
|
||||
'derivatives' => array(
|
||||
'icon' => 'icon-trash-1',
|
||||
'label' => l10n('Delete multiple size images'),
|
||||
),
|
||||
'lock_gallery' => array(
|
||||
'icon' => 'icon-lock',
|
||||
'label' => l10n('Lock gallery'),
|
||||
),
|
||||
'unlock_gallery' => array(
|
||||
'icon' => 'icon-lock',
|
||||
'label' => l10n('Unlock gallery'),
|
||||
),
|
||||
'categories' => array(
|
||||
'icon' => 'icon-folder-open',
|
||||
'label' => l10n('Update albums informations'),
|
||||
),
|
||||
'images' => array(
|
||||
'icon' => 'icon-info-circled-1',
|
||||
'label' => l10n('Update photos information'),
|
||||
),
|
||||
'empty_lounge' => array(
|
||||
'icon' => 'icon-thumbs-up',
|
||||
'label' => l10n('Empty lounge'),
|
||||
),
|
||||
'delete_orphan_tags' => array(
|
||||
'icon' => 'icon-tags',
|
||||
'label' => l10n('Delete orphan tags'),
|
||||
),
|
||||
'user_cache' => array(
|
||||
'icon' => 'icon-user-1',
|
||||
'label' => l10n('Purge user cache'),
|
||||
),
|
||||
'history_detail' => array(
|
||||
'icon' => 'icon-back-in-time',
|
||||
'label' => l10n('Purge history detail'),
|
||||
),
|
||||
'history_summary' => array(
|
||||
'icon' => 'icon-back-in-time',
|
||||
'label' => l10n('Purge history summary'),
|
||||
),
|
||||
'sessions' => array(
|
||||
'icon' => 'icon-th-list',
|
||||
'label' => l10n('Purge sessions'),
|
||||
),
|
||||
'feeds' => array(
|
||||
'icon' => 'icon-bell',
|
||||
'label' => l10n('Purge never used notification feeds'),
|
||||
),
|
||||
'database' => array(
|
||||
'icon' => 'icon-database',
|
||||
'label' => l10n('Repair and optimize database'),
|
||||
),
|
||||
'c13y' => array(
|
||||
'icon' => 'icon-ok',
|
||||
'label' => l10n('Reinitialize check integrity'),
|
||||
),
|
||||
'search' => array(
|
||||
'icon' => 'icon-search',
|
||||
'label' => l10n('Purge search history'),
|
||||
),
|
||||
'compiled-templates' => array(
|
||||
'icon' => 'icon-file-code',
|
||||
'label' => l10n('Purge compiled templates'),
|
||||
),
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
if (isset($_GET['tab']))
|
||||
{
|
||||
check_input_parameter('tab', $_GET, false, '/^(actions|env|sys)$/');
|
||||
$page['tab'] = $_GET['tab'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['tab'] = 'actions';
|
||||
}
|
||||
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('maintenance');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
include(PHPWG_ROOT_PATH.'admin/maintenance_'.$page['tab'].'.php');
|
||||
|
||||
$template->assign(
|
||||
array('ADMIN_PAGE_TITLE' => l10n('Maintenance'))
|
||||
);
|
||||
@@ -0,0 +1,409 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
fs_quick_check();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | actions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : '';
|
||||
$register_activity = true;
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'phpinfo' :
|
||||
{
|
||||
phpinfo();
|
||||
exit();
|
||||
}
|
||||
case 'lock_gallery' :
|
||||
{
|
||||
conf_update_param('gallery_locked', 'true');
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'maintenance', array('maintenance_action'=>$action));
|
||||
redirect(get_root_url().'admin.php?page=maintenance');
|
||||
break;
|
||||
}
|
||||
case 'unlock_gallery' :
|
||||
{
|
||||
conf_update_param('gallery_locked', 'false');
|
||||
$_SESSION['page_infos'] = array(l10n('Gallery unlocked'));
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'maintenance', array('maintenance_action'=>$action));
|
||||
redirect(get_root_url().'admin.php?page=maintenance');
|
||||
break;
|
||||
}
|
||||
case 'categories' :
|
||||
{
|
||||
images_integrity();
|
||||
categories_integrity();
|
||||
update_uppercats();
|
||||
update_category('all');
|
||||
update_global_rank();
|
||||
invalidate_user_cache(true);
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Update albums informations'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'images' :
|
||||
{
|
||||
images_integrity();
|
||||
update_path();
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
|
||||
update_rating_score();
|
||||
invalidate_user_cache();
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Update photos information'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'delete_orphan_tags' :
|
||||
{
|
||||
delete_orphan_tags();
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Delete orphan tags'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'user_cache' :
|
||||
{
|
||||
invalidate_user_cache();
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Purge user cache'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'history_detail' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.HISTORY_TABLE.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Purge history detail'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'history_summary' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Purge history summary'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'sessions' :
|
||||
{
|
||||
pwg_session_gc();
|
||||
|
||||
// delete all sessions associated to invalid user ids (it should never happen)
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
data
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
;';
|
||||
$sessions = query2array($query);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
'.$conf['user_fields']['id'].' AS id
|
||||
FROM '.USERS_TABLE.'
|
||||
;';
|
||||
$all_user_ids = query2array($query, 'id', null);
|
||||
|
||||
$sessions_to_delete = array();
|
||||
|
||||
foreach ($sessions as $session)
|
||||
{
|
||||
if (preg_match('/pwg_uid\|i:(\d+);/', $session['data'], $matches))
|
||||
{
|
||||
if (!isset($all_user_ids[ $matches[1] ]))
|
||||
{
|
||||
$sessions_to_delete[] = $session['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sessions_to_delete) > 0)
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
WHERE id IN (\''.implode("','", $sessions_to_delete).'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Purge sessions'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'feeds' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.USER_FEED_TABLE.'
|
||||
WHERE last_check IS NULL
|
||||
;';
|
||||
pwg_query($query);
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Purge never used notification feeds'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'database' :
|
||||
{
|
||||
do_maintenance_all_tables();
|
||||
break;
|
||||
}
|
||||
case 'c13y' :
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
|
||||
$c13y = new check_integrity();
|
||||
$c13y->maintenance();
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Reinitialize check integrity'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'empty_lounge':
|
||||
{
|
||||
$rows = empty_lounge();
|
||||
$page['infos'][] = sprintf('%d photos were moved from the upload lounge to their albums', count($rows));
|
||||
break;
|
||||
}
|
||||
case 'search' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SEARCH_TABLE.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
sprintf('%s : %s', l10n('Reinitialize check integrity'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'compiled-templates':
|
||||
{
|
||||
$template->delete_compiled_templates();
|
||||
FileCombiner::clear_combined_files();
|
||||
$persistent_cache->purge(true);
|
||||
$page['infos'][] = sprintf('%s : %s', l10n('Purge compiled templates'), l10n('action successfully performed.'));
|
||||
break;
|
||||
}
|
||||
case 'derivatives':
|
||||
{
|
||||
$types_str = $_GET['type'];
|
||||
if ($types_str == "all") {
|
||||
clear_derivative_cache($_GET['type']);
|
||||
} else {
|
||||
$types = explode('_', $types_str);
|
||||
foreach ($types as $type_to_clear) {
|
||||
clear_derivative_cache($type_to_clear);
|
||||
}
|
||||
}
|
||||
$page['infos'][] = l10n('action successfully performed.');
|
||||
break;
|
||||
}
|
||||
|
||||
case 'check_upgrade':
|
||||
{
|
||||
if (!fetchRemote(PHPWG_URL.'/download/latest_version', $result))
|
||||
{
|
||||
$page['errors'][] = l10n('Unable to check for upgrade.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$versions = array('current' => PHPWG_VERSION);
|
||||
$lines = @explode("\r\n", $result);
|
||||
|
||||
// if the current version is a BSF (development branch) build, we check
|
||||
// the first line, for stable versions, we check the second line
|
||||
if (preg_match('/^BSF/', $versions['current']))
|
||||
{
|
||||
$versions['latest'] = trim($lines[0]);
|
||||
|
||||
// because integer are limited to 4,294,967,296 we need to split BSF
|
||||
// versions in date.time
|
||||
foreach ($versions as $key => $value)
|
||||
{
|
||||
$versions[$key] =
|
||||
preg_replace('/BSF_(\d{8})(\d{4})/', '$1.$2', $value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$versions['latest'] = trim($lines[1]);
|
||||
}
|
||||
|
||||
if ('' == $versions['latest'])
|
||||
{
|
||||
$page['errors'][] = l10n('Check for upgrade failed for unknown reasons.');
|
||||
}
|
||||
// concatenation needed to avoid automatic transformation by release
|
||||
// script generator
|
||||
else if ('%'.'PWGVERSION'.'%' == $versions['current'])
|
||||
{
|
||||
$page['infos'][] = l10n('You are running on development sources, no check possible.');
|
||||
}
|
||||
else if (version_compare($versions['current'], $versions['latest']) < 0)
|
||||
{
|
||||
$page['infos'][] = l10n('A new version of Piwigo is available.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['infos'][] = l10n('You are running the latest version of Piwigo.');
|
||||
}
|
||||
}
|
||||
$page['infos'][] = l10n('action successfully performed.');
|
||||
}
|
||||
|
||||
default :
|
||||
{
|
||||
$register_activity = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($register_activity)
|
||||
{
|
||||
pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'maintenance', array('maintenance_action'=>$action));
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(array('maintenance'=>'maintenance_actions.tpl'));
|
||||
$pwg_token = get_pwg_token();
|
||||
$url_format = get_root_url().'admin.php?page=maintenance&action=%s&pwg_token='.get_pwg_token();
|
||||
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
|
||||
}
|
||||
|
||||
$purge_urls[l10n('All')] = 'all';
|
||||
foreach(ImageStdParams::get_defined_type_map() as $params)
|
||||
{
|
||||
$purge_urls[ l10n($params->type) ] = $params->type;
|
||||
}
|
||||
$purge_urls[ l10n(IMG_CUSTOM) ] = IMG_CUSTOM;
|
||||
|
||||
$php_current_timestamp = date("Y-m-d H:i:s");
|
||||
$db_version = pwg_get_db_version();
|
||||
list($db_current_date) = pwg_db_fetch_row(pwg_query('SELECT now();'));
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'maint_actions' => $maint_actions,
|
||||
'U_MAINT_CATEGORIES' => sprintf($url_format, 'categories'),
|
||||
'U_MAINT_IMAGES' => sprintf($url_format, 'images'),
|
||||
'U_MAINT_ORPHAN_TAGS' => sprintf($url_format, 'delete_orphan_tags'),
|
||||
'U_MAINT_USER_CACHE' => sprintf($url_format, 'user_cache'),
|
||||
'U_MAINT_HISTORY_DETAIL' => sprintf($url_format, 'history_detail'),
|
||||
'U_MAINT_HISTORY_SUMMARY' => sprintf($url_format, 'history_summary'),
|
||||
'U_MAINT_SESSIONS' => sprintf($url_format, 'sessions'),
|
||||
'U_MAINT_FEEDS' => sprintf($url_format, 'feeds'),
|
||||
'U_MAINT_DATABASE' => sprintf($url_format, 'database'),
|
||||
'U_MAINT_C13Y' => sprintf($url_format, 'c13y'),
|
||||
'U_MAINT_SEARCH' => sprintf($url_format, 'search'),
|
||||
'U_MAINT_COMPILED_TEMPLATES' => sprintf($url_format, 'compiled-templates'),
|
||||
'U_MAINT_DERIVATIVES' => sprintf($url_format, 'derivatives'),
|
||||
'purge_derivatives' => $purge_urls,
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=maintenance',
|
||||
|
||||
'PHPWG_URL' => PHPWG_URL,
|
||||
'PWG_VERSION' => PHPWG_VERSION,
|
||||
'U_CHECK_UPGRADE' => sprintf($url_format, 'check_upgrade'),
|
||||
'OS' => PHP_OS,
|
||||
'PHP_VERSION' => phpversion(),
|
||||
'DB_ENGINE' => 'MySQL',
|
||||
'DB_VERSION' => $db_version,
|
||||
'U_PHPINFO' => sprintf($url_format, 'phpinfo'),
|
||||
'PHP_DATATIME' => $php_current_timestamp,
|
||||
'DB_DATATIME' => $db_current_date,
|
||||
'pwg_token' => $pwg_token,
|
||||
'cache_sizes' => (isset($conf['cache_sizes'])) ? unserialize($conf['cache_sizes']) : null,
|
||||
'time_elapsed_since_last_calc' => (isset($conf['cache_sizes'])) ? time_since(unserialize($conf['cache_sizes'])[3]['value'], 'year') : null,
|
||||
)
|
||||
);
|
||||
|
||||
// graphics library
|
||||
switch (pwg_image::get_library())
|
||||
{
|
||||
case 'ext_imagick':
|
||||
$library = 'External ImageMagick';
|
||||
exec($conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command().' -version', $returnarray);
|
||||
if (preg_match('/Version: ImageMagick (\d+\.\d+\.\d+-?\d*)/', $returnarray[0], $match))
|
||||
{
|
||||
$library .= ' ' . $match[1];
|
||||
}
|
||||
$template->assign('GRAPHICS_LIBRARY', $library);
|
||||
break;
|
||||
|
||||
case 'imagick':
|
||||
$library = 'ImageMagick';
|
||||
$img = new Imagick();
|
||||
$version = $img->getVersion();
|
||||
if (preg_match('/ImageMagick \d+\.\d+\.\d+-?\d*/', $version['versionString'], $match))
|
||||
{
|
||||
$library = $match[0];
|
||||
}
|
||||
$template->assign('GRAPHICS_LIBRARY', $library);
|
||||
break;
|
||||
|
||||
case 'gd':
|
||||
$gd_info = gd_info();
|
||||
$template->assign('GRAPHICS_LIBRARY', 'GD '.@$gd_info['GD Version']);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($conf['gallery_locked'])
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'U_MAINT_UNLOCK_GALLERY' => sprintf($url_format, 'unlock_gallery'),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'U_MAINT_LOCK_GALLERY' => sprintf($url_format, 'lock_gallery'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.LOUNGE_TABLE.'
|
||||
;';
|
||||
list($nb_lounge) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
if ($nb_lounge > 0)
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'U_EMPTY_LOUNGE' => sprintf($url_format, 'empty_lounge'),
|
||||
'LOUNGE_COUNTER' => $nb_lounge,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Define advanced features |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$advanced_features = array();
|
||||
|
||||
//$advanced_features is array of array composed of CAPTION & URL
|
||||
$advanced_features = trigger_change(
|
||||
'get_admin_advanced_features_links',
|
||||
$advanced_features
|
||||
);
|
||||
|
||||
$template->assign('advanced_features', $advanced_features);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
|
||||
?>
|
||||
@@ -0,0 +1,365 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (isset($_GET['action']))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | actions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : '';
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'phpinfo' :
|
||||
{
|
||||
phpinfo();
|
||||
exit();
|
||||
}
|
||||
case 'lock_gallery' :
|
||||
{
|
||||
conf_update_param('gallery_locked', 'true');
|
||||
redirect(get_root_url().'admin.php?page=maintenance');
|
||||
break;
|
||||
}
|
||||
case 'unlock_gallery' :
|
||||
{
|
||||
conf_update_param('gallery_locked', 'false');
|
||||
$_SESSION['page_infos'] = array(l10n('Gallery unlocked'));
|
||||
redirect(get_root_url().'admin.php?page=maintenance');
|
||||
break;
|
||||
}
|
||||
case 'categories' :
|
||||
{
|
||||
images_integrity();
|
||||
categories_integrity();
|
||||
update_uppercats();
|
||||
update_category('all');
|
||||
update_global_rank();
|
||||
invalidate_user_cache(true);
|
||||
break;
|
||||
}
|
||||
case 'images' :
|
||||
{
|
||||
images_integrity();
|
||||
update_path();
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
|
||||
update_rating_score();
|
||||
invalidate_user_cache();
|
||||
break;
|
||||
}
|
||||
case 'delete_orphan_tags' :
|
||||
{
|
||||
delete_orphan_tags();
|
||||
break;
|
||||
}
|
||||
case 'user_cache' :
|
||||
{
|
||||
invalidate_user_cache();
|
||||
break;
|
||||
}
|
||||
case 'history_detail' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.HISTORY_TABLE.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
case 'history_summary' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
case 'sessions' :
|
||||
{
|
||||
pwg_session_gc();
|
||||
|
||||
// delete all sessions associated to invalid user ids (it should never happen)
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
data
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
;';
|
||||
$sessions = query2array($query);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
'.$conf['user_fields']['id'].' AS id
|
||||
FROM '.USERS_TABLE.'
|
||||
;';
|
||||
$all_user_ids = query2array($query, 'id', null);
|
||||
|
||||
$sessions_to_delete = array();
|
||||
|
||||
foreach ($sessions as $session)
|
||||
{
|
||||
if (preg_match('/pwg_uid\|i:(\d+);/', $session['data'], $matches))
|
||||
{
|
||||
if (!isset($all_user_ids[ $matches[1] ]))
|
||||
{
|
||||
$sessions_to_delete[] = $session['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sessions_to_delete) > 0)
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
WHERE id IN (\''.implode("','", $sessions_to_delete).'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'feeds' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.USER_FEED_TABLE.'
|
||||
WHERE last_check IS NULL
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
case 'database' :
|
||||
{
|
||||
do_maintenance_all_tables();
|
||||
break;
|
||||
}
|
||||
case 'c13y' :
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
|
||||
$c13y = new check_integrity();
|
||||
$c13y->maintenance();
|
||||
break;
|
||||
}
|
||||
case 'search' :
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SEARCH_TABLE.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
break;
|
||||
}
|
||||
case 'compiled-templates':
|
||||
{
|
||||
$template->delete_compiled_templates();
|
||||
FileCombiner::clear_combined_files();
|
||||
$persistent_cache->purge(true);
|
||||
break;
|
||||
}
|
||||
case 'derivatives':
|
||||
{
|
||||
clear_derivative_cache($_GET['type']);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'check_upgrade':
|
||||
{
|
||||
if (!fetchRemote(PHPWG_URL.'/download/latest_version', $result))
|
||||
{
|
||||
$page['errors'][] = l10n('Unable to check for upgrade.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$versions = array('current' => PHPWG_VERSION);
|
||||
$lines = @explode("\r\n", $result);
|
||||
|
||||
// if the current version is a BSF (development branch) build, we check
|
||||
// the first line, for stable versions, we check the second line
|
||||
if (preg_match('/^BSF/', $versions['current']))
|
||||
{
|
||||
$versions['latest'] = trim($lines[0]);
|
||||
|
||||
// because integer are limited to 4,294,967,296 we need to split BSF
|
||||
// versions in date.time
|
||||
foreach ($versions as $key => $value)
|
||||
{
|
||||
$versions[$key] =
|
||||
preg_replace('/BSF_(\d{8})(\d{4})/', '$1.$2', $value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$versions['latest'] = trim($lines[1]);
|
||||
}
|
||||
|
||||
if ('' == $versions['latest'])
|
||||
{
|
||||
$page['errors'][] = l10n('Check for upgrade failed for unknown reasons.');
|
||||
}
|
||||
// concatenation needed to avoid automatic transformation by release
|
||||
// script generator
|
||||
else if ('%'.'PWGVERSION'.'%' == $versions['current'])
|
||||
{
|
||||
$page['infos'][] = l10n('You are running on development sources, no check possible.');
|
||||
}
|
||||
else if (version_compare($versions['current'], $versions['latest']) < 0)
|
||||
{
|
||||
$page['infos'][] = l10n('A new version of Piwigo is available.');
|
||||
|
||||
$update_url = PHPWG_ROOT_PATH.'admin.php?page=updates';
|
||||
$page['infos'][] = '<a href="'. $update_url . '">' . l10n('Update to Piwigo %s', $versions['latest']) . '</a>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['infos'][] = l10n('You are running the latest version of Piwigo.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default :
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(array('maintenance'=>'maintenance_env.tpl'));
|
||||
|
||||
$url_format = get_root_url().'admin.php?page=maintenance&action=%s&pwg_token='.get_pwg_token();
|
||||
|
||||
$purge_urls[l10n('All')] = sprintf($url_format, 'derivatives').'&type=all';
|
||||
foreach(ImageStdParams::get_defined_type_map() as $params)
|
||||
{
|
||||
$purge_urls[ l10n($params->type) ] = sprintf($url_format, 'derivatives').'&type='.$params->type;
|
||||
}
|
||||
$purge_urls[ l10n(IMG_CUSTOM) ] = sprintf($url_format, 'derivatives').'&type='.IMG_CUSTOM;
|
||||
|
||||
$php_current_timestamp = date("Y-m-d H:i:s");
|
||||
$db_version = pwg_get_db_version();
|
||||
list($db_current_date) = pwg_db_fetch_row(pwg_query('SELECT now();'));
|
||||
|
||||
list($container_name,$container_version) = get_container_info();
|
||||
|
||||
if (!in_array($container_name, ['Official','none']))
|
||||
{
|
||||
$container_name = '(unofficial) '.$container_name;
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'U_MAINT_CATEGORIES' => sprintf($url_format, 'categories'),
|
||||
'U_MAINT_IMAGES' => sprintf($url_format, 'images'),
|
||||
'U_MAINT_ORPHAN_TAGS' => sprintf($url_format, 'delete_orphan_tags'),
|
||||
'U_MAINT_USER_CACHE' => sprintf($url_format, 'user_cache'),
|
||||
'U_MAINT_HISTORY_DETAIL' => sprintf($url_format, 'history_detail'),
|
||||
'U_MAINT_HISTORY_SUMMARY' => sprintf($url_format, 'history_summary'),
|
||||
'U_MAINT_SESSIONS' => sprintf($url_format, 'sessions'),
|
||||
'U_MAINT_FEEDS' => sprintf($url_format, 'feeds'),
|
||||
'U_MAINT_DATABASE' => sprintf($url_format, 'database'),
|
||||
'U_MAINT_C13Y' => sprintf($url_format, 'c13y'),
|
||||
'U_MAINT_SEARCH' => sprintf($url_format, 'search'),
|
||||
'U_MAINT_COMPILED_TEMPLATES' => sprintf($url_format, 'compiled-templates'),
|
||||
'U_MAINT_DERIVATIVES' => sprintf($url_format, 'derivatives'),
|
||||
'purge_derivatives' => $purge_urls,
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=maintenance',
|
||||
|
||||
'PHPWG_URL' => PHPWG_URL,
|
||||
'PWG_VERSION' => PHPWG_VERSION,
|
||||
'U_CHECK_UPGRADE' => sprintf($url_format, 'check_upgrade'),
|
||||
'OS' => PHP_OS,
|
||||
'CONTAINER_INFO' => $container_name.(!empty($container_version) ? ' '.$container_version : ''),
|
||||
'PHP_VERSION' => phpversion(),
|
||||
'DB_ENGINE' => 'MySQL',
|
||||
'DB_VERSION' => $db_version,
|
||||
'U_PHPINFO' => sprintf($url_format, 'phpinfo'),
|
||||
'PHP_DATATIME' => $php_current_timestamp,
|
||||
'DB_DATATIME' => $db_current_date,
|
||||
'cache_sizes' => (isset($conf['cache_sizes'])) ? unserialize($conf['cache_sizes']) : null,
|
||||
'time_elapsed_since_last_calc' => (isset($conf['cache_sizes'])) ? time_since(unserialize($conf['cache_sizes'])[3]['value'], 'year') : null,
|
||||
)
|
||||
);
|
||||
|
||||
// graphics library
|
||||
$graphics_library = get_graphics_library_label();
|
||||
if (!empty($graphics_library))
|
||||
{
|
||||
$template->assign('GRAPHICS_LIBRARY', $graphics_library);
|
||||
}
|
||||
|
||||
if ($conf['gallery_locked'])
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'U_MAINT_UNLOCK_GALLERY' => sprintf($url_format, 'unlock_gallery'),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'U_MAINT_LOCK_GALLERY' => sprintf($url_format, 'lock_gallery'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$installed_on = get_installation_date();
|
||||
if (!empty($installed_on))
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'INSTALLED_ON' => format_date($installed_on, array('day', 'month', 'year')),
|
||||
'INSTALLED_SINCE' => time_since($installed_on, 'day'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Define advanced features |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$advanced_features = array();
|
||||
|
||||
//$advanced_features is array of array composed of CAPTION & URL
|
||||
$advanced_features = trigger_change(
|
||||
'get_admin_advanced_features_links',
|
||||
$advanced_features
|
||||
);
|
||||
|
||||
$template->assign('advanced_features', $advanced_features);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
|
||||
?>
|
||||
@@ -0,0 +1,382 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Only Webmaster can see this tab |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (is_webmaster())
|
||||
{
|
||||
// Get system activities data
|
||||
if (isset($_GET['method']) && 'pwg.activity_sys.getList' == $_GET['method'])
|
||||
{
|
||||
$response = array();
|
||||
$data = array();
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
activity_id,
|
||||
object,
|
||||
object_id,
|
||||
action,
|
||||
performed_by,
|
||||
occured_on,
|
||||
details,
|
||||
IF(performed_by = 0, \'System\', '.$conf['user_fields']['username'].') AS username
|
||||
FROM '.ACTIVITY_TABLE.'
|
||||
LEFT JOIN '.USERS_TABLE.' ON performed_by = '.$conf['user_fields']['id'].'
|
||||
WHERE object = \'system\'
|
||||
ORDER BY activity_id DESC';
|
||||
|
||||
// Format our data for frontend
|
||||
$result = pwg_query($query);
|
||||
while ($rows = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$major_infos = false;
|
||||
$object = '';
|
||||
$object_icon = '';
|
||||
$action_icon = '';
|
||||
$action_color = '';
|
||||
$action = $rows['action'];
|
||||
$date = '';
|
||||
$hour = '';
|
||||
$details = unserialize($rows['details']);
|
||||
$detail = array(
|
||||
'type' => 'empty',
|
||||
);
|
||||
|
||||
// For each categories (Core, Plugin and Theme) we need to format theirs actions
|
||||
switch ($rows['object_id'])
|
||||
{
|
||||
case ACTIVITY_SYSTEM_CORE:
|
||||
$object_icon = 'icon-piwigo';
|
||||
$object = l10n('Core');
|
||||
|
||||
switch ($rows['action'])
|
||||
{
|
||||
case 'install':
|
||||
$action_icon = 'icon-download';
|
||||
$action_color = 'icon-green';
|
||||
$action = l10n('Install');
|
||||
break;
|
||||
|
||||
case 'config':
|
||||
$action_icon = 'icon-cog-alt';
|
||||
$action_color = 'icon-yellow';
|
||||
$action = l10n('Configuration');
|
||||
// for config we need to specific format details
|
||||
if (isset($details['config_section']))
|
||||
{
|
||||
$c_icon = '';
|
||||
$c_text = '';
|
||||
switch ($details['config_section'])
|
||||
{
|
||||
case 'main':
|
||||
$c_icon = 'icon-cog';
|
||||
$c_text = l10n('General');
|
||||
break;
|
||||
|
||||
case 'watermark':
|
||||
$c_icon = 'icon-file-image';
|
||||
$c_text = l10n('Watermark');
|
||||
break;
|
||||
|
||||
case 'sizes':
|
||||
$c_icon = 'icon-zoom-square';
|
||||
$c_text = l10n('Photo sizes');
|
||||
// sizes have 2 params always Photo sizes and sometimes config_action
|
||||
if (isset($details['config_action']) && 'restore_settings' == $details['config_action'])
|
||||
{
|
||||
$detail[] = array(
|
||||
'icon' => 'icon-back-in-time',
|
||||
'text' => l10n('Set as default')
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
$c_icon = 'icon-chat';
|
||||
$c_text = l10n('Comments');
|
||||
break;
|
||||
|
||||
case 'display':
|
||||
$c_icon = 'icon-television';
|
||||
$c_text = l10n('Display');
|
||||
break;
|
||||
|
||||
default:
|
||||
$c_icon = 'icon-cog-alt';
|
||||
$c_text = $details['config_section'];
|
||||
break;
|
||||
}
|
||||
|
||||
$detail['type'] = 'config_section';
|
||||
$detail[] = array(
|
||||
'icon' => $c_icon,
|
||||
'text' => $c_text
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'maintenance':
|
||||
$action_icon = 'icon-cone';
|
||||
$action_color = 'icon-yellow';
|
||||
$action = l10n('Maintenance');
|
||||
// for maintenance we need to specific format details
|
||||
if (isset($details['maintenance_action']))
|
||||
{
|
||||
$action_detail = $details['maintenance_action'];
|
||||
$detail = array(
|
||||
'type' => 'maintenance_action',
|
||||
'icon' => $maint_actions[$action_detail]['icon'] ?? 'icon-cone',
|
||||
'text' => $maint_actions[$action_detail]['label'] ?? $action_detail,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$action_icon = 'icon-arrows-cw';
|
||||
$action_color = 'icon-blue';
|
||||
$action = l10n('Update');
|
||||
$major_infos = true;
|
||||
break;
|
||||
|
||||
case 'autoupdate':
|
||||
$action_icon = 'icon-arrows-cw';
|
||||
$action_color = 'icon-blue';
|
||||
$action = l10n('Auto-update');
|
||||
$major_infos = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
$action_icon = 'icon-download';
|
||||
$action_color = 'icon-yellow';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTIVITY_SYSTEM_PLUGIN:
|
||||
$object_icon = 'icon-puzzle';
|
||||
$object = 'plugin';
|
||||
if (isset($details['plugin_id']))
|
||||
{
|
||||
$object = str_replace(['_', '-'], ' ', $details['plugin_id']);
|
||||
}
|
||||
switch ($rows['action'])
|
||||
{
|
||||
case 'install':
|
||||
$action_icon = 'icon-download';
|
||||
$action_color = 'icon-green';
|
||||
$action = l10n('Install');
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$action_icon = 'icon-arrows-cw';
|
||||
$action_color = 'icon-blue';
|
||||
$action = l10n('Update');
|
||||
break;
|
||||
|
||||
case 'activate':
|
||||
$action_icon = 'icon-check';
|
||||
$action_color = 'icon-green';
|
||||
$action = l10n('Activate');
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
$action_icon = 'icon-block';
|
||||
$action_color = 'icon-purple';
|
||||
$action = l10n('Deactivate');
|
||||
break;
|
||||
|
||||
case 'uninstall':
|
||||
$action_icon = 'icon-trash-1';
|
||||
$action_color = 'icon-red';
|
||||
$action = l10n('Uninstall');
|
||||
break;
|
||||
|
||||
case 'restore':
|
||||
$action_icon = 'icon-back-in-time';
|
||||
$action_color = 'icon-blue';
|
||||
$action = l10n('Restore');
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$action_icon = 'icon-trash-1';
|
||||
$action_color = 'icon-red';
|
||||
$action = l10n('Delete');
|
||||
// for delete we need to specific format details
|
||||
if (isset($details['db_version']))
|
||||
{
|
||||
$detail['type'] = 'db_fs_version';
|
||||
$detail[] = array(
|
||||
'icon' => 'icon-flow-branch',
|
||||
'text' => 'database : ' . $details['db_version']
|
||||
);
|
||||
}
|
||||
if (isset($details['fs_version']))
|
||||
{
|
||||
$detail['type'] = 'db_fs_version';
|
||||
$detail[] = array(
|
||||
'icon' => 'icon-flow-branch',
|
||||
'text' => 'filesystem : ' . $details['fs_version']
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'autoupdate':
|
||||
$action_icon = 'icon-arrows-cw';
|
||||
$action_color = 'icon-blue';
|
||||
$action = l10n('Auto-update');
|
||||
break;
|
||||
|
||||
default:
|
||||
$action_icon = 'icon-puzzle';
|
||||
$action_color = 'icon-yellow';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTIVITY_SYSTEM_THEME:
|
||||
$object_icon = 'icon-brush';
|
||||
$object = 'theme';
|
||||
if (isset($details['theme_id']))
|
||||
{
|
||||
$object = str_replace(['_', '-'], ' ', $details['theme_id']);
|
||||
}
|
||||
|
||||
switch ($rows['action'])
|
||||
{
|
||||
case 'install':
|
||||
$action_icon = 'icon-download';
|
||||
$action_color = 'icon-green';
|
||||
$action = l10n('Install');
|
||||
break;
|
||||
|
||||
case 'activate':
|
||||
$action_icon = 'icon-check';
|
||||
$action_color = 'icon-green';
|
||||
$action = l10n('Activate');
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
$action_icon = 'icon-block';
|
||||
$action_color = 'icon-purple';
|
||||
$action = l10n('Deactivate');
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$action_icon = 'icon-trash-1';
|
||||
$action_color = 'icon-red';
|
||||
$action = l10n('Delete');
|
||||
break;
|
||||
|
||||
case 'set_default':
|
||||
$action_icon = 'icon-star';
|
||||
$action_color = 'icon-yellow';
|
||||
$action = l10n('Set as default');
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$action_icon = 'icon-arrows-cw';
|
||||
$action_color = 'icon-blue';
|
||||
$action = l10n('Update');
|
||||
break;
|
||||
|
||||
default:
|
||||
$action_icon = 'icon-brush';
|
||||
$action_color = 'icon-yellow';
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// For each lines we need to format theirs details (general details)
|
||||
if (isset($details['from_version']))
|
||||
{
|
||||
$detail = array(
|
||||
'type' => 'from_to',
|
||||
array(
|
||||
'icon' => 'icon-flow-branch',
|
||||
'text' => $details['from_version'],
|
||||
),
|
||||
array(
|
||||
'icon' => isset($details['to_version']) ? 'icon-flow-branch' : 'icon-block',
|
||||
'text' => isset($details['to_version']) ? $details['to_version'] : ($details['result'] ?? ''),
|
||||
),
|
||||
);
|
||||
}
|
||||
else if (isset($details['version']))
|
||||
{
|
||||
$detail = array(
|
||||
'type' => 'version',
|
||||
'icon' => 'icon-flow-branch',
|
||||
'text' => $details['version']
|
||||
);
|
||||
}
|
||||
else if (isset($details['result']))
|
||||
{
|
||||
$detail = array(
|
||||
'type' => 'error',
|
||||
'icon' => 'icon-block',
|
||||
'text' => $details['result']
|
||||
);
|
||||
}
|
||||
|
||||
// Format our data before send
|
||||
// This data will be manipulate by maintenance_sys.js
|
||||
list($date, $hour) = explode(' ', $rows['occured_on']);
|
||||
$data[] = array(
|
||||
'major_infos' => $major_infos,
|
||||
'id' => $rows['activity_id'],
|
||||
'object_icon' => $object_icon,
|
||||
'object' => ucwords($object),
|
||||
'action_icon' => $action_icon,
|
||||
'action_color' => $action_color,
|
||||
'action' => $action,
|
||||
'user_id' => $rows['performed_by'],
|
||||
'username' => $rows['username'],
|
||||
'date' => format_date($date),
|
||||
'hour' => $hour,
|
||||
'detail' => $detail
|
||||
);
|
||||
}
|
||||
|
||||
// Now we good to send our response data
|
||||
$response = array(
|
||||
'data' => $data,
|
||||
);
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
|
||||
$template->set_filenames(array('maintenance'=>'maintenance_sys.tpl'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
|
||||
?>
|
||||
@@ -0,0 +1,167 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
|
||||
}
|
||||
|
||||
function abs_fn_cmp($a, $b)
|
||||
{
|
||||
return abs($a)-abs($b);
|
||||
}
|
||||
|
||||
function make_consecutive( &$orders, $step=50 )
|
||||
{
|
||||
uasort( $orders, 'abs_fn_cmp' );
|
||||
$crt = 1;
|
||||
foreach( $orders as $id=>$pos)
|
||||
{
|
||||
$orders[$id] = $step * ($pos<0 ? -$crt : $crt);
|
||||
$crt++;
|
||||
}
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/block.class.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('menus');
|
||||
$tabsheet->select('');
|
||||
$tabsheet->assign();
|
||||
|
||||
|
||||
$menu = new BlockManager('menubar');
|
||||
$menu->load_registered_blocks();
|
||||
$reg_blocks = $menu->get_registered_blocks();
|
||||
|
||||
$mb_conf = @$conf[ 'blk_'.$menu->get_id() ];
|
||||
if ( is_string($mb_conf) )
|
||||
$mb_conf = unserialize( $mb_conf );
|
||||
if ( !is_array($mb_conf) )
|
||||
$mb_conf=array();
|
||||
|
||||
foreach ($mb_conf as $id => $pos)
|
||||
{
|
||||
if (!isset($reg_blocks[$id]))
|
||||
unset($mb_conf[$id]);
|
||||
}
|
||||
|
||||
$idx=1;
|
||||
foreach ($reg_blocks as $id => $block)
|
||||
{
|
||||
if ( !isset($mb_conf[$id]) )
|
||||
$mb_conf[$id] = $idx*50;
|
||||
$idx++;
|
||||
}
|
||||
|
||||
|
||||
if ( isset($_POST['submit']) and is_webmaster())
|
||||
{
|
||||
foreach ( $mb_conf as $id => $pos )
|
||||
{
|
||||
$hide = isset($_POST['hide_'.$id]);
|
||||
$mb_conf[$id] = ($hide ? -1 : +1)*abs($pos);
|
||||
|
||||
$pos = (int)@$_POST['pos_'.$id];
|
||||
if ($pos>0)
|
||||
$mb_conf[$id] = $mb_conf[$id] > 0 ? $pos : -$pos;
|
||||
}
|
||||
make_consecutive( $mb_conf );
|
||||
|
||||
// BEGIN OPTIM - DONT ASK ABOUT THIS ALGO - but optimizes the size of the array we save in DB
|
||||
/* !!! OPTIM DISABLED UNTIL IT HAS BEEN FIXED !!!
|
||||
$reg_keys = array_keys($reg_blocks);
|
||||
$cnf_keys = array_keys($mb_conf);
|
||||
$best_slice = array( 'len'=>0 );
|
||||
for ($i=0; $i<count($reg_keys); $i++)
|
||||
{
|
||||
for ($j=0; $j<count($cnf_keys); $j++)
|
||||
{
|
||||
for ($k=0; max($i,$j)+$k<count($cnf_keys); $k++)
|
||||
{
|
||||
if ($cnf_keys[$j+$k] == $reg_keys[$i+$k] )
|
||||
{
|
||||
if ( 1+$k>$best_slice['len'])
|
||||
{
|
||||
$best_slice['len'] = 1+$k;
|
||||
$best_slice['start_cnf'] = $j;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
$mb_conf_db = $mb_conf;
|
||||
/*
|
||||
if ($best_slice['len'])
|
||||
{
|
||||
for ($j=0; $j<$best_slice['start_cnf']; $j++ )
|
||||
{
|
||||
$sign = $mb_conf_db[ $cnf_keys[$j] ] > 0 ? 1 : -1;
|
||||
$mb_conf_db[ $cnf_keys[$j] ] = $sign * ( ($best_slice['start_cnf'])*50 - ($best_slice['start_cnf']-$j) );
|
||||
}
|
||||
for ($j=$best_slice['start_cnf']; $j<$best_slice['start_cnf']+$best_slice['len']; $j++ )
|
||||
{
|
||||
if ($mb_conf_db[ $cnf_keys[$j] ] > 0)
|
||||
unset( $mb_conf_db[ $cnf_keys[$j] ] );
|
||||
}
|
||||
}
|
||||
//var_export( $best_slice ); var_export($mb_conf); var_export($mb_conf_db);
|
||||
// END OPTIM
|
||||
*/
|
||||
$query = '
|
||||
UPDATE '.CONFIG_TABLE.'
|
||||
SET value=\''.addslashes(serialize($mb_conf_db)).'\'
|
||||
WHERE param=\'blk_'.addslashes($menu->get_id()).'\'
|
||||
';
|
||||
pwg_query($query);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n('Order of menubar items has been updated successfully.'),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
make_consecutive( $mb_conf );
|
||||
|
||||
foreach ($mb_conf as $id => $pos )
|
||||
{
|
||||
$template->append( 'blocks',
|
||||
array(
|
||||
'pos' => $pos/5,
|
||||
'reg' => $reg_blocks[$id]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$action = get_root_url().'admin.php?page=menubar';
|
||||
$template->assign(array('F_ACTION'=>$action));
|
||||
|
||||
$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Menu Management'));
|
||||
|
||||
$template->set_filename( 'menubar_admin_content', 'menubar.tpl' );
|
||||
$template->assign_var_from_handle( 'ADMIN_CONTENT', 'menubar_admin_content');
|
||||
?>
|
||||
@@ -0,0 +1,739 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | include |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_notification_by_mail.inc.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_notification.inc.php');
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('mode', $_GET, false, '/^(param|subscribe|send)$/');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$base_url = get_root_url().'admin.php';
|
||||
$must_repost = false;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | functions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/*
|
||||
* Do timeout treatment in order to finish to send mails
|
||||
*
|
||||
* @param $post_keyname: key of check_key post array
|
||||
* @param check_key_treated: array of check_key treated
|
||||
* @return none
|
||||
*/
|
||||
function do_timeout_treatment($post_keyname, $check_key_treated = array())
|
||||
{
|
||||
global $env_nbm, $base_url, $page, $must_repost;
|
||||
|
||||
if ($env_nbm['is_sendmail_timeout'])
|
||||
{
|
||||
if (isset($_POST[$post_keyname]))
|
||||
{
|
||||
$post_count = count($_POST[$post_keyname]);
|
||||
$treated_count = count($check_key_treated);
|
||||
if ($treated_count != 0)
|
||||
{
|
||||
$time_refresh = ceil((get_moment() - $env_nbm['start_time']) * $post_count / $treated_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
$time_refresh = 0;
|
||||
}
|
||||
$_POST[$post_keyname] = array_diff($_POST[$post_keyname], $check_key_treated);
|
||||
|
||||
$must_repost = true;
|
||||
$page['errors'][] = l10n_dec(
|
||||
'Execution time is out, treatment must be continue [Estimated time: %d second].',
|
||||
'Execution time is out, treatment must be continue [Estimated time: %d seconds].',
|
||||
$time_refresh
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the authorized_status for each tab
|
||||
* return corresponding status
|
||||
*/
|
||||
function get_tab_status($mode)
|
||||
{
|
||||
$result = ACCESS_WEBMASTER;
|
||||
switch ($mode)
|
||||
{
|
||||
case 'param':
|
||||
case 'subscribe':
|
||||
$result = ACCESS_WEBMASTER;
|
||||
break;
|
||||
case 'send':
|
||||
$result = ACCESS_ADMINISTRATOR;
|
||||
break;
|
||||
default:
|
||||
$result = ACCESS_WEBMASTER;
|
||||
break;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserting News users
|
||||
*/
|
||||
function insert_new_data_user_mail_notification()
|
||||
{
|
||||
global $conf, $page, $env_nbm;
|
||||
|
||||
// Set null mail_address empty
|
||||
$query = '
|
||||
update
|
||||
'.USERS_TABLE.'
|
||||
set
|
||||
'.$conf['user_fields']['email'].' = null
|
||||
where
|
||||
trim('.$conf['user_fields']['email'].') = \'\';';
|
||||
pwg_query($query);
|
||||
|
||||
// null mail_address are not selected in the list
|
||||
$query = '
|
||||
select
|
||||
u.'.$conf['user_fields']['id'].' as user_id,
|
||||
u.'.$conf['user_fields']['username'].' as username,
|
||||
u.'.$conf['user_fields']['email'].' as mail_address
|
||||
from
|
||||
'.USERS_TABLE.' as u left join '.USER_MAIL_NOTIFICATION_TABLE.' as m on u.'.$conf['user_fields']['id'].' = m.user_id
|
||||
where
|
||||
u.'.$conf['user_fields']['email'].' is not null and
|
||||
m.user_id is null
|
||||
order by
|
||||
user_id;';
|
||||
|
||||
$result = pwg_query($query);
|
||||
|
||||
if (pwg_db_num_rows($result) > 0)
|
||||
{
|
||||
$inserts = array();
|
||||
$check_key_list = array();
|
||||
|
||||
while ($nbm_user = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
// Calculate key
|
||||
$nbm_user['check_key'] = find_available_check_key();
|
||||
|
||||
// Save key
|
||||
$check_key_list[] = $nbm_user['check_key'];
|
||||
|
||||
// Insert new nbm_users
|
||||
$inserts[] = array(
|
||||
'user_id' => $nbm_user['user_id'],
|
||||
'check_key' => $nbm_user['check_key'],
|
||||
'enabled' => 'false' // By default if false, set to true with specific functions
|
||||
);
|
||||
|
||||
$page['infos'][] = l10n(
|
||||
'User %s [%s] added.',
|
||||
stripslashes($nbm_user['username']),
|
||||
$nbm_user['mail_address']
|
||||
);
|
||||
}
|
||||
|
||||
// Insert new nbm_users
|
||||
mass_inserts(USER_MAIL_NOTIFICATION_TABLE, array('user_id', 'check_key', 'enabled'), $inserts);
|
||||
// Update field enabled with specific function
|
||||
$check_key_treated = do_subscribe_unsubscribe_notification_by_mail
|
||||
(
|
||||
true,
|
||||
$conf['nbm_default_value_user_enabled'],
|
||||
$check_key_list
|
||||
);
|
||||
|
||||
// On timeout simulate like tabsheet send
|
||||
if ($env_nbm['is_sendmail_timeout'])
|
||||
{
|
||||
$quoted_check_key_list = quote_check_key_list(array_diff($check_key_list, $check_key_treated));
|
||||
if (count($quoted_check_key_list) != 0 )
|
||||
{
|
||||
$query = 'delete from '.USER_MAIL_NOTIFICATION_TABLE.' where check_key in ('.implode(",", $quoted_check_key_list).');';
|
||||
$result = pwg_query($query);
|
||||
|
||||
redirect($base_url.get_query_string_diff(array(), false), l10n('Operation in progress')."\n".l10n('Please wait...'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply global functions to mail content
|
||||
* return customize mail content rendered
|
||||
*/
|
||||
function render_global_customize_mail_content($customize_mail_content)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if ($conf['nbm_send_html_mail'] and !(strpos($customize_mail_content, '<') === 0))
|
||||
{
|
||||
// On HTML mail, detects if the content are HTML format.
|
||||
// If it's plain text format, convert content to readable HTML
|
||||
return nl2br(htmlspecialchars($customize_mail_content));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $customize_mail_content;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send mail for notification to all users
|
||||
* Return list of "selected" users for 'list_to_send'
|
||||
* Return list of "treated" check_key for 'send'
|
||||
*/
|
||||
function do_action_send_mail_notification($action = 'list_to_send', $check_key_list = array(), $customize_mail_content = '')
|
||||
{
|
||||
global $conf, $page, $user, $lang_info, $lang, $env_nbm;
|
||||
$return_list = array();
|
||||
|
||||
if (in_array($action, array('list_to_send', 'send')))
|
||||
{
|
||||
list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
|
||||
|
||||
$is_action_send = ($action == 'send');
|
||||
|
||||
// disabled and null mail_address are not selected in the list
|
||||
$data_users = get_user_notifications('send', $check_key_list);
|
||||
|
||||
// List all if it's define on options or on timeout
|
||||
$is_list_all_without_test = ($env_nbm['is_sendmail_timeout'] or $conf['nbm_list_all_enabled_users_to_send']);
|
||||
|
||||
// Check if exist news to list user or send mails
|
||||
if ((!$is_list_all_without_test) or ($is_action_send))
|
||||
{
|
||||
if (count($data_users) > 0)
|
||||
{
|
||||
$datas = array();
|
||||
|
||||
if (!isset($customize_mail_content))
|
||||
{
|
||||
$customize_mail_content = $conf['nbm_complementary_mail_content'];
|
||||
}
|
||||
|
||||
$customize_mail_content =
|
||||
trigger_change('nbm_render_global_customize_mail_content', $customize_mail_content);
|
||||
|
||||
|
||||
// Prepare message after change language
|
||||
if ($is_action_send)
|
||||
{
|
||||
$msg_break_timeout = l10n('Time to send mail is limited. Others mails are skipped.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg_break_timeout = l10n('Prepared time for list of users to send mail is limited. Others users are not listed.');
|
||||
}
|
||||
|
||||
// Begin nbm users environment
|
||||
begin_users_env_nbm($is_action_send);
|
||||
|
||||
foreach ($data_users as $nbm_user)
|
||||
{
|
||||
if ((!$is_action_send) and check_sendmail_timeout())
|
||||
{
|
||||
// Stop fill list on 'list_to_send', if the quota is override
|
||||
$page['infos'][] = $msg_break_timeout;
|
||||
break;
|
||||
}
|
||||
if (($is_action_send) and check_sendmail_timeout())
|
||||
{
|
||||
// Stop fill list on 'send', if the quota is override
|
||||
$page['errors'][] = $msg_break_timeout;
|
||||
break;
|
||||
}
|
||||
|
||||
// set env nbm user
|
||||
set_user_on_env_nbm($nbm_user, $is_action_send);
|
||||
|
||||
if ($is_action_send)
|
||||
{
|
||||
$auth = null;
|
||||
$add_url_params = array();
|
||||
|
||||
$auth_key = create_user_auth_key($nbm_user['user_id'], $nbm_user['status']);
|
||||
|
||||
if ($auth_key !== false)
|
||||
{
|
||||
$auth = $auth_key['auth_key'];
|
||||
$add_url_params['auth'] = $auth;
|
||||
}
|
||||
|
||||
set_make_full_url();
|
||||
// Fill return list of "treated" check_key for 'send'
|
||||
$return_list[] = $nbm_user['check_key'];
|
||||
|
||||
if ($conf['nbm_send_detailed_content'])
|
||||
{
|
||||
$news = news($nbm_user['last_send'], $dbnow, false, $conf['nbm_send_html_mail'], $auth);
|
||||
$exist_data = count($news) > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$exist_data = news_exists($nbm_user['last_send'], $dbnow);
|
||||
}
|
||||
|
||||
if ($exist_data)
|
||||
{
|
||||
$subject = '['.$conf['gallery_title'].'] '.l10n('New photos added');
|
||||
|
||||
// Assign current var for nbm mail
|
||||
assign_vars_nbm_mail_content($nbm_user);
|
||||
|
||||
if (!is_null($nbm_user['last_send']))
|
||||
{
|
||||
$env_nbm['mail_template']->assign
|
||||
(
|
||||
'content_new_elements_between',
|
||||
array
|
||||
(
|
||||
'DATE_BETWEEN_1' => $nbm_user['last_send'],
|
||||
'DATE_BETWEEN_2' => $dbnow,
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$env_nbm['mail_template']->assign
|
||||
(
|
||||
'content_new_elements_single',
|
||||
array
|
||||
(
|
||||
'DATE_SINGLE' => $dbnow,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($conf['nbm_send_detailed_content'])
|
||||
{
|
||||
$env_nbm['mail_template']->assign('global_new_lines', $news);
|
||||
}
|
||||
|
||||
$nbm_user_customize_mail_content =
|
||||
trigger_change('nbm_render_user_customize_mail_content',
|
||||
$customize_mail_content, $nbm_user);
|
||||
if (!empty($nbm_user_customize_mail_content))
|
||||
{
|
||||
$env_nbm['mail_template']->assign
|
||||
(
|
||||
'custom_mail_content', $nbm_user_customize_mail_content
|
||||
);
|
||||
}
|
||||
|
||||
if ($conf['nbm_send_html_mail'] and $conf['nbm_send_recent_post_dates'])
|
||||
{
|
||||
$recent_post_dates = get_recent_post_dates_array(
|
||||
$conf['recent_post_dates']['NBM']);
|
||||
foreach ($recent_post_dates as $date_detail)
|
||||
{
|
||||
$env_nbm['mail_template']->append
|
||||
(
|
||||
'recent_posts',
|
||||
array
|
||||
(
|
||||
'TITLE' => get_title_recent_post_date($date_detail),
|
||||
'HTML_DATA' => get_html_description_recent_post_date($date_detail, $auth)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$env_nbm['mail_template']->assign
|
||||
(
|
||||
array
|
||||
(
|
||||
'GOTO_GALLERY_TITLE' => $conf['gallery_title'],
|
||||
'GOTO_GALLERY_URL' => add_url_params(get_gallery_home_url(), $add_url_params),
|
||||
'SEND_AS_NAME' => $env_nbm['send_as_name'],
|
||||
)
|
||||
);
|
||||
|
||||
$ret = pwg_mail(
|
||||
array(
|
||||
'name' => stripslashes($nbm_user['username']),
|
||||
'email' => $nbm_user['mail_address'],
|
||||
),
|
||||
array(
|
||||
'from' => $env_nbm['send_as_mail_formated'],
|
||||
'subject' => $subject,
|
||||
'email_format' => $env_nbm['email_format'],
|
||||
'content' => $env_nbm['mail_template']->parse('notification_by_mail', true),
|
||||
'content_format' => $env_nbm['email_format'],
|
||||
'auth_key' => $auth,
|
||||
)
|
||||
);
|
||||
|
||||
if ($ret)
|
||||
{
|
||||
inc_mail_sent_success($nbm_user);
|
||||
|
||||
$datas[] = array(
|
||||
'user_id' => $nbm_user['user_id'],
|
||||
'last_send' => $dbnow
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
inc_mail_sent_failed($nbm_user);
|
||||
}
|
||||
|
||||
unset_make_full_url();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (news_exists($nbm_user['last_send'], $dbnow))
|
||||
{
|
||||
// Fill return list of "selected" users for 'list_to_send'
|
||||
$return_list[] = $nbm_user;
|
||||
}
|
||||
}
|
||||
|
||||
// unset env nbm user
|
||||
unset_user_on_env_nbm();
|
||||
}
|
||||
|
||||
// Restore nbm environment
|
||||
end_users_env_nbm();
|
||||
|
||||
if ($is_action_send)
|
||||
{
|
||||
mass_updates(
|
||||
USER_MAIL_NOTIFICATION_TABLE,
|
||||
array(
|
||||
'primary' => array('user_id'),
|
||||
'update' => array('last_send')
|
||||
),
|
||||
$datas
|
||||
);
|
||||
|
||||
display_counter_info();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($is_action_send)
|
||||
{
|
||||
$page['errors'][] = l10n('No user to send notifications by mail.');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Quick List, don't check news
|
||||
// Fill return list of "selected" users for 'list_to_send'
|
||||
$return_list = $data_users;
|
||||
}
|
||||
}
|
||||
|
||||
// Return list of "selected" users for 'list_to_send'
|
||||
// Return list of "treated" check_key for 'send'
|
||||
return $return_list;
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Main |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (!isset($_GET['mode']))
|
||||
{
|
||||
$page['mode'] = 'send';
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['mode'] = $_GET['mode'];
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(get_tab_status($page['mode']));
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Add event handler |
|
||||
// +-----------------------------------------------------------------------+
|
||||
add_event_handler('nbm_render_global_customize_mail_content', 'render_global_customize_mail_content');
|
||||
trigger_notify('nbm_event_handler_added');
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Insert new users with mails |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (!isset($_POST) or (count($_POST) ==0))
|
||||
{
|
||||
// No insert data in post mode
|
||||
insert_new_data_user_mail_notification();
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Treatment of tab post |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!empty($_POST))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
switch ($page['mode'])
|
||||
{
|
||||
case 'param' :
|
||||
{
|
||||
if (isset($_POST['param_submit']))
|
||||
{
|
||||
$_POST['nbm_send_mail_as'] = strip_tags($_POST['nbm_send_mail_as']);
|
||||
|
||||
check_input_parameter('nbm_send_html_mail', $_POST, false, '/^(true|false)$/');
|
||||
check_input_parameter('nbm_send_detailed_content', $_POST, false, '/^(true|false)$/');
|
||||
check_input_parameter('nbm_send_recent_post_dates', $_POST, false, '/^(true|false)$/');
|
||||
|
||||
$updated_param_count = 0;
|
||||
// Update param
|
||||
$result = pwg_query('select param, value from '.CONFIG_TABLE.' where param like \'nbm\\_%\'');
|
||||
while ($nbm_user = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if (isset($_POST[$nbm_user['param']]))
|
||||
{
|
||||
conf_update_param($nbm_user['param'], $_POST[$nbm_user['param']], true);
|
||||
$updated_param_count++;
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n_dec(
|
||||
'%d parameter was updated.', '%d parameters were updated.',
|
||||
$updated_param_count
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
case 'subscribe' :
|
||||
{
|
||||
if (isset($_POST['falsify']) and isset($_POST['cat_true']))
|
||||
{
|
||||
$check_key_treated = unsubscribe_notification_by_mail(true, $_POST['cat_true']);
|
||||
do_timeout_treatment('cat_true', $check_key_treated);
|
||||
}
|
||||
else
|
||||
if (isset($_POST['trueify']) and isset($_POST['cat_false']))
|
||||
{
|
||||
$check_key_treated = subscribe_notification_by_mail(true, $_POST['cat_false']);
|
||||
do_timeout_treatment('cat_false', $check_key_treated);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'send' :
|
||||
{
|
||||
if (isset($_POST['send_submit']) and isset($_POST['send_selection']) and isset($_POST['send_customize_mail_content']))
|
||||
{
|
||||
$check_key_treated = do_action_send_mail_notification('send', $_POST['send_selection'], stripslashes($_POST['send_customize_mail_content']));
|
||||
do_timeout_treatment('send_selection', $check_key_treated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filenames
|
||||
(
|
||||
array
|
||||
(
|
||||
'double_select' => 'double_select.tpl',
|
||||
'notification_by_mail'=>'notification_by_mail.tpl'
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign
|
||||
(
|
||||
array
|
||||
(
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=notification_by_mail',
|
||||
'F_ACTION'=> $base_url.get_query_string_diff(array())
|
||||
)
|
||||
);
|
||||
|
||||
if (is_autorize_status(ACCESS_WEBMASTER))
|
||||
{
|
||||
// TabSheet
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('nbm');
|
||||
$tabsheet->select($page['mode']);
|
||||
$tabsheet->assign();
|
||||
}
|
||||
|
||||
if ($must_repost)
|
||||
{
|
||||
// Get name of submit button
|
||||
$repost_submit_name = '';
|
||||
if (isset($_POST['falsify']))
|
||||
{
|
||||
$repost_submit_name = 'falsify';
|
||||
}
|
||||
elseif (isset($_POST['trueify']))
|
||||
{
|
||||
$repost_submit_name = 'trueify';
|
||||
}
|
||||
elseif (isset($_POST['send_submit']))
|
||||
{
|
||||
$repost_submit_name = 'send_submit';
|
||||
}
|
||||
|
||||
$template->assign('REPOST_SUBMIT_NAME', $repost_submit_name);
|
||||
}
|
||||
|
||||
switch ($page['mode'])
|
||||
{
|
||||
case 'param' :
|
||||
{
|
||||
$template->assign(
|
||||
$page['mode'],
|
||||
array(
|
||||
'SEND_HTML_MAIL' => $conf['nbm_send_html_mail'],
|
||||
'SEND_MAIL_AS' => $conf['nbm_send_mail_as'],
|
||||
'SEND_DETAILED_CONTENT' => $conf['nbm_send_detailed_content'],
|
||||
'COMPLEMENTARY_MAIL_CONTENT' => $conf['nbm_complementary_mail_content'],
|
||||
'SEND_RECENT_POST_DATES' => $conf['nbm_send_recent_post_dates'],
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'subscribe' :
|
||||
{
|
||||
$template->assign( $page['mode'], true );
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'L_CAT_OPTIONS_TRUE' => l10n('Subscribed'),
|
||||
'L_CAT_OPTIONS_FALSE' => l10n('Unsubscribed')
|
||||
)
|
||||
);
|
||||
|
||||
$data_users = get_user_notifications('subscribe');
|
||||
|
||||
$opt_true = array();
|
||||
$opt_true_selected = array();
|
||||
$opt_false = array();
|
||||
$opt_false_selected = array();
|
||||
foreach ($data_users as $nbm_user)
|
||||
{
|
||||
if (get_boolean($nbm_user['enabled']))
|
||||
{
|
||||
$opt_true[ $nbm_user['check_key'] ] = stripslashes($nbm_user['username']).'['.$nbm_user['mail_address'].']';
|
||||
if ((isset($_POST['falsify']) and isset($_POST['cat_true']) and in_array($nbm_user['check_key'], $_POST['cat_true'])))
|
||||
{
|
||||
$opt_true_selected[] = $nbm_user['check_key'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$opt_false[ $nbm_user['check_key'] ] = stripslashes($nbm_user['username']).'['.$nbm_user['mail_address'].']';
|
||||
if (isset($_POST['trueify']) and isset($_POST['cat_false']) and in_array($nbm_user['check_key'], $_POST['cat_false']))
|
||||
{
|
||||
$opt_false_selected[] = $nbm_user['check_key'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$template->assign( array(
|
||||
'category_option_true' => $opt_true,
|
||||
'category_option_true_selected' => $opt_true_selected,
|
||||
'category_option_false' => $opt_false,
|
||||
'category_option_false_selected' => $opt_false_selected,
|
||||
)
|
||||
);
|
||||
$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
|
||||
break;
|
||||
}
|
||||
|
||||
case 'send' :
|
||||
{
|
||||
$tpl_var = array('users'=> array() );
|
||||
|
||||
$data_users = do_action_send_mail_notification('list_to_send');
|
||||
|
||||
$tpl_var['CUSTOMIZE_MAIL_CONTENT'] =
|
||||
isset($_POST['send_customize_mail_content'])
|
||||
? stripslashes($_POST['send_customize_mail_content'])
|
||||
: $conf['nbm_complementary_mail_content'];
|
||||
|
||||
if (count($data_users))
|
||||
{
|
||||
foreach ($data_users as $nbm_user)
|
||||
{
|
||||
if (
|
||||
(!$must_repost) or // Not timeout, normal treatment
|
||||
(($must_repost) and in_array($nbm_user['check_key'], $_POST['send_selection'])) // Must be repost, show only user to send
|
||||
)
|
||||
{
|
||||
$tpl_var['users'][] =
|
||||
array(
|
||||
'ID' => $nbm_user['check_key'],
|
||||
'CHECKED' => ( // not check if not selected, on init select<all
|
||||
isset($_POST['send_selection']) and // not init
|
||||
!in_array($nbm_user['check_key'], $_POST['send_selection']) // not selected
|
||||
) ? '' : 'checked="checked"',
|
||||
'USERNAME'=> stripslashes($nbm_user['username']),
|
||||
'EMAIL' => $nbm_user['mail_address'],
|
||||
'LAST_SEND'=> $nbm_user['last_send']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$template->assign($page['mode'], $tpl_var);
|
||||
|
||||
if ($conf['auth_key_duration'] > 0)
|
||||
{
|
||||
$template->assign(
|
||||
'auth_key_duration',
|
||||
time_since(
|
||||
strtotime('now -'.$conf['auth_key_duration'].' second'),
|
||||
'second',
|
||||
null,
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Send mail to users'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'notification_by_mail');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,190 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
function parse_sort_variables(
|
||||
$sortable_by, $default_field,
|
||||
$get_param, $get_rejects,
|
||||
$template_var,
|
||||
$anchor = '' )
|
||||
{
|
||||
global $template;
|
||||
|
||||
$url_components = parse_url( $_SERVER['REQUEST_URI'] );
|
||||
|
||||
$base_url = $url_components['path'];
|
||||
|
||||
parse_str($url_components['query'], $vars);
|
||||
$is_first = true;
|
||||
foreach ($vars as $key => $value)
|
||||
{
|
||||
if (!in_array($key, $get_rejects) and $key!=$get_param)
|
||||
{
|
||||
$base_url .= $is_first ? '?' : '&';
|
||||
$is_first = false;
|
||||
|
||||
if (!in_array($key, array('page', 'psf', 'dpsf', 'pwg_token')))
|
||||
{
|
||||
fatal_error('unexpected URL get key');
|
||||
}
|
||||
|
||||
$base_url .= urlencode($key).'='.urlencode($value);
|
||||
}
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
foreach( $sortable_by as $field)
|
||||
{
|
||||
$url = $base_url;
|
||||
$disp = '↓'; // TODO: an small image is better
|
||||
|
||||
if ( $field !== @$_GET[$get_param] )
|
||||
{
|
||||
if ( !isset($default_field) or $default_field!=$field )
|
||||
{ // the first should be the default
|
||||
$url = add_url_params($url, array($get_param=>$field) );
|
||||
}
|
||||
elseif (isset($default_field) and !isset($_GET[$get_param]) )
|
||||
{
|
||||
$ret[] = $field;
|
||||
$disp = '<em>'.$disp.'</em>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret[] = $field;
|
||||
$disp = '<em>'.$disp.'</em>';
|
||||
}
|
||||
if ( isset($template_var) )
|
||||
{
|
||||
$template->assign( $template_var.strtoupper($field),
|
||||
'<a href="'.$url.$anchor.'" title="'.l10n('Sort order').'">'.$disp.'</a>'
|
||||
);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_permalinks.php');
|
||||
|
||||
check_input_parameter('cat_id', $_POST, false, PATTERN_ID);
|
||||
|
||||
$selected_cat = array();
|
||||
if ( isset($_POST['set_permalink']) and $_POST['cat_id']>0 )
|
||||
{
|
||||
check_pwg_token();
|
||||
$permalink = $_POST['permalink'];
|
||||
if ( empty($permalink) )
|
||||
delete_cat_permalink($_POST['cat_id'], isset($_POST['save']) );
|
||||
else
|
||||
set_cat_permalink($_POST['cat_id'], $permalink, isset($_POST['save']) );
|
||||
$selected_cat = array( $_POST['cat_id'] );
|
||||
}
|
||||
elseif ( isset($_GET['delete_permanent']) )
|
||||
{
|
||||
check_pwg_token();
|
||||
$query = '
|
||||
DELETE FROM '.OLD_PERMALINKS_TABLE.'
|
||||
WHERE permalink=\''.pwg_db_real_escape_string($_GET['delete_permanent']).'\'
|
||||
LIMIT 1';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_changes($result)==0)
|
||||
{
|
||||
$page['errors'][] = l10n('Cannot delete the old permalink !');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$template->set_filename('permalinks', 'permalinks.tpl' );
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$page['tab'] = 'permalinks';
|
||||
include(PHPWG_ROOT_PATH.'admin/include/albums_tab.inc.php');
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
id, permalink,
|
||||
CONCAT(id, " - ", name, IF(permalink IS NULL, "", " √") ) AS name,
|
||||
uppercats, global_rank
|
||||
FROM '.CATEGORIES_TABLE;
|
||||
|
||||
display_select_cat_wrapper( $query, $selected_cat, 'categories', false );
|
||||
|
||||
$pwg_token = get_pwg_token();
|
||||
|
||||
// --- generate display of active permalinks -----------------------------------
|
||||
$sort_by = parse_sort_variables(
|
||||
array('id', 'name', 'permalink'), 'name',
|
||||
'psf',
|
||||
array('delete_permanent'),
|
||||
'SORT_' );
|
||||
|
||||
$query = '
|
||||
SELECT id, permalink, uppercats, global_rank
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE permalink IS NOT NULL
|
||||
';
|
||||
if ( $sort_by[0]=='id' or $sort_by[0]=='permalink' )
|
||||
{
|
||||
$query .= ' ORDER BY '.$sort_by[0];
|
||||
}
|
||||
$categories=array();
|
||||
$result=pwg_query($query);
|
||||
while ( $row = pwg_db_fetch_assoc($result) )
|
||||
{
|
||||
$row['name'] = get_cat_display_name_cache( $row['uppercats'] );
|
||||
$categories[] = $row;
|
||||
}
|
||||
|
||||
if ( $sort_by[0]=='name')
|
||||
{
|
||||
usort($categories, 'global_rank_compare');
|
||||
}
|
||||
$template->assign( 'permalinks', $categories );
|
||||
|
||||
// --- generate display of old permalinks --------------------------------------
|
||||
|
||||
$sort_by = parse_sort_variables(
|
||||
array('cat_id','permalink','date_deleted','last_hit','hit'), null,
|
||||
'dpsf',
|
||||
array('delete_permanent'),
|
||||
'SORT_OLD_', '#old_permalinks' );
|
||||
|
||||
$url_del_base = get_root_url().'admin.php?page=permalinks';
|
||||
$query = 'SELECT * FROM '.OLD_PERMALINKS_TABLE;
|
||||
if ( count($sort_by) )
|
||||
{
|
||||
$query .= ' ORDER BY '.$sort_by[0];
|
||||
}
|
||||
$result = pwg_query($query);
|
||||
$deleted_permalinks=array();
|
||||
while ( $row = pwg_db_fetch_assoc($result) )
|
||||
{
|
||||
$row['name'] = get_cat_display_name_cache($row['cat_id']);
|
||||
$row['U_DELETE'] =
|
||||
add_url_params(
|
||||
$url_del_base,
|
||||
array('delete_permanent'=> $row['permalink'],'pwg_token'=>$pwg_token)
|
||||
);
|
||||
$deleted_permalinks[] = $row;
|
||||
}
|
||||
|
||||
$template->assign(array(
|
||||
'PWG_TOKEN' => $pwg_token,
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=permalinks',
|
||||
'deleted_permalinks' => $deleted_permalinks,
|
||||
'ADMIN_PAGE_TITLE' => l10n('Albums'),
|
||||
));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'permalinks');
|
||||
?>
|
||||
@@ -0,0 +1,82 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Basic checks |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('cat_id', $_GET, false, PATTERN_ID);
|
||||
check_input_parameter('image_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
$admin_photo_base_url = get_root_url().'admin.php?page=photo-'.$_GET['image_id'];
|
||||
|
||||
// retrieving direct information about picture
|
||||
$page['image'] = get_image_infos($_GET['image_id'], true);
|
||||
|
||||
if (isset($_GET['cat_id']))
|
||||
{
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id = '.$_GET['cat_id'].'
|
||||
;';
|
||||
$category = pwg_db_fetch_assoc(pwg_query($query));
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$page['tab'] = 'properties';
|
||||
|
||||
if (isset($_GET['tab']))
|
||||
{
|
||||
$page['tab'] = $_GET['tab'];
|
||||
}
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('photo');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'ADMIN_PAGE_TITLE' => l10n('Edit photo').' <span class="image-id">#'.$_GET['image_id'].'</span>',
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Load the tab |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if ('properties' == $page['tab'])
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/picture_modify.php');
|
||||
}
|
||||
elseif ('coi' == $page['tab'])
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/picture_coi.php');
|
||||
}
|
||||
elseif ('formats' == $page['tab'] && $conf['enable_formats'])
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/picture_formats.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/photo_'.$page['tab'].'.php');
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
|
||||
|
||||
define(
|
||||
'PHOTOS_ADD_BASE_URL',
|
||||
get_root_url().'admin.php?page=photos_add'
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Load configuration |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$upload_form_config = get_upload_form_config();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (isset($_GET['section']))
|
||||
{
|
||||
$page['tab'] = $_GET['section'];
|
||||
|
||||
// backward compatibility
|
||||
if ('ploader' == $page['tab'])
|
||||
{
|
||||
$page['tab'] = 'applications';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['tab'] = 'direct';
|
||||
}
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('photos_add');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(
|
||||
array(
|
||||
'photos_add' => 'photos_add_'.$page['tab'].'.tpl'
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Load the tab |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include(PHPWG_ROOT_PATH.'admin/photos_add_'.$page['tab'].'.php');
|
||||
?>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHOTOS_ADD_BASE_URL'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Upload Photos'));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'photos_add');
|
||||
?>
|
||||
@@ -0,0 +1,164 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHOTOS_ADD_BASE_URL'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | batch management request |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['batch']))
|
||||
{
|
||||
check_input_parameter('batch', $_GET, false, '/^\d+(,\d+)*$/');
|
||||
|
||||
$query = '
|
||||
DELETE FROM '.CADDIE_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$inserts = array();
|
||||
foreach (array_unique(explode(',', $_GET['batch'])) as $image_id)
|
||||
{
|
||||
$inserts[] = array(
|
||||
'user_id' => $user['id'],
|
||||
'element_id' => $image_id,
|
||||
);
|
||||
}
|
||||
mass_inserts(
|
||||
CADDIE_TABLE,
|
||||
array_keys($inserts[0]),
|
||||
$inserts
|
||||
);
|
||||
|
||||
redirect(get_root_url().'admin.php?page=batch_manager&filter=prefilter-caddie');
|
||||
}
|
||||
|
||||
if (userprefs_get_param('promote-mobile-apps', true))
|
||||
{
|
||||
$query = '
|
||||
SELECT registration_date
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE registration_date IS NOT NULL
|
||||
ORDER BY user_id ASC
|
||||
LIMIT 1
|
||||
;';
|
||||
list($register_date) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
list($nb_cats) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
;';
|
||||
list($nb_images) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/mdetect.php');
|
||||
$uagent_obj = new uagent_info();
|
||||
// To see the mobile app promote, the account must have 2 weeks ancient, 3 albums created and 30 photos uploaded
|
||||
$template->assign("PROMOTE_MOBILE_APPS", (!$uagent_obj->DetectIos() and strtotime($register_date) < strtotime('2 weeks ago') and $nb_cats >= 3 and $nb_images >= 30));
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign("PROMOTE_MOBILE_APPS", false);
|
||||
}
|
||||
|
||||
$template->assign('PHPWG_URL', PHPWG_URL);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Formats Mode |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$display_formats = $conf['enable_formats'] && isset($_GET['formats']);
|
||||
|
||||
$have_formats_original = false;
|
||||
$formats_original_info = array();
|
||||
$formats_ext_info = null;
|
||||
|
||||
// If URL parameter isn't empty
|
||||
if ($display_formats && $_GET['formats'])
|
||||
{
|
||||
check_input_parameter('formats', $_GET, false, PATTERN_ID, false);
|
||||
|
||||
$formats_original_info = get_image_infos($_GET['formats']);
|
||||
if ($formats_original_info)
|
||||
{
|
||||
$src_image = new SrcImage($formats_original_info);
|
||||
|
||||
$formats_original_info['src'] = DerivativeImage::url(IMG_SQUARE, $src_image);
|
||||
|
||||
// Fetch actual formats
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.IMAGE_FORMAT_TABLE.'
|
||||
WHERE image_id = '.$formats_original_info['id'].'
|
||||
;';
|
||||
$formats = query2array($query);
|
||||
|
||||
if (!empty($formats))
|
||||
{
|
||||
$format_strings = array();
|
||||
$formats_exts = array();
|
||||
|
||||
foreach ($formats as $format)
|
||||
{
|
||||
$format_strings[] = sprintf('%s (%.2fMB)', $format['ext'], $format['filesize']/1024);
|
||||
$formats_exts[] = strtolower($format['ext']);
|
||||
}
|
||||
|
||||
$formats_original_info['formats'] = l10n('Formats: %s', implode(', ', $format_strings));
|
||||
$formats_ext_info = json_encode($formats_exts);
|
||||
}
|
||||
|
||||
$extTab = explode('.',$formats_original_info['file']);
|
||||
|
||||
$formats_original_info['ext'] = l10n('%s file type',strtoupper(end($extTab)));
|
||||
|
||||
$formats_original_info['u_edit'] = get_root_url().'admin.php?page=photo-'.$formats_original_info['id'];
|
||||
|
||||
$have_formats_original = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('The original picture selected dosen\'t exists.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | prepare form |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/photos_add_direct_prepare.inc.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
trigger_notify('loc_end_photo_add_direct');
|
||||
|
||||
$template->assign(array(
|
||||
'ENABLE_FORMATS' => $conf['enable_formats'],
|
||||
'DISPLAY_FORMATS' => $display_formats,
|
||||
'HAVE_FORMATS_ORIGINAL' => $have_formats_original,
|
||||
'FORMATS_ORIGINAL_INFO' => $formats_original_info,
|
||||
'FORMATS_EXT_INFO' => $formats_ext_info,
|
||||
'SWITCH_FORMAT_MODE_URL' => get_root_url().'admin.php?page=photos_add'.($display_formats ? '':'&formats'),
|
||||
'format_ext' => implode(',', $conf['format_ext']),
|
||||
'str_format_ext' => implode(', ', $conf['format_ext']),
|
||||
));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'photos_add');
|
||||
?>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHOTOS_ADD_BASE_URL'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign(
|
||||
'FTP_HELP_CONTENT',
|
||||
load_language(
|
||||
'help/photos_add_ftp.html',
|
||||
'',
|
||||
array('return'=>true)
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Upload Photos'));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'photos_add');
|
||||
?>
|
||||
@@ -0,0 +1,98 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if(!defined("PHPWG_ROOT_PATH"))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('image_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
$query = 'UPDATE '.IMAGES_TABLE;
|
||||
if (strlen($_POST['l'])==0)
|
||||
{
|
||||
$query .= ' SET coi=NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$coi = fraction_to_char($_POST['l'])
|
||||
.fraction_to_char($_POST['t'])
|
||||
.fraction_to_char($_POST['r'])
|
||||
.fraction_to_char($_POST['b']);
|
||||
$query .= ' SET coi=\''.$coi.'\'';
|
||||
}
|
||||
$query .= ' WHERE id='.$_GET['image_id'];
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM '.IMAGES_TABLE.' WHERE id='.$_GET['image_id'];
|
||||
$row = pwg_db_fetch_assoc( pwg_query($query) );
|
||||
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
foreach(ImageStdParams::get_defined_type_map() as $params)
|
||||
{
|
||||
if ($params->sizing->max_crop != 0)
|
||||
{
|
||||
delete_element_derivatives($row, $params->type);
|
||||
}
|
||||
}
|
||||
delete_element_derivatives($row, IMG_CUSTOM);
|
||||
$uid = '&b='.time();
|
||||
$conf['question_mark_in_urls'] = $conf['php_extension_in_urls'] = true;
|
||||
if ($conf['derivative_url_style']==1)
|
||||
{
|
||||
$conf['derivative_url_style']=0; //auto
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$uid = '';
|
||||
}
|
||||
|
||||
$tpl_var = array(
|
||||
'TITLE' => render_element_name($row),
|
||||
'ALT' => $row['file'],
|
||||
'U_IMG' => DerivativeImage::url(IMG_LARGE, $row),
|
||||
);
|
||||
|
||||
if (!empty($row['coi']))
|
||||
{
|
||||
$tpl_var['coi'] = array(
|
||||
'l'=> char_to_fraction($row['coi'][0]),
|
||||
't'=> char_to_fraction($row['coi'][1]),
|
||||
'r'=> char_to_fraction($row['coi'][2]),
|
||||
'b'=> char_to_fraction($row['coi'][3]),
|
||||
);
|
||||
}
|
||||
|
||||
foreach(ImageStdParams::get_defined_type_map() as $params)
|
||||
{
|
||||
if ($params->sizing->max_crop != 0)
|
||||
{
|
||||
$derivative = new DerivativeImage($params, new SrcImage($row) );
|
||||
$template->append( 'cropped_derivatives', array(
|
||||
'U_IMG' => $derivative->get_url().$uid,
|
||||
'HTM_SIZE' => $derivative->get_size_htm(),
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$template->assign($tpl_var);
|
||||
$template->set_filename('picture_coi', 'picture_coi.tpl');
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_coi');
|
||||
?>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if(!defined("PHPWG_ROOT_PATH"))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('image_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
$query='
|
||||
SELECT *
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id = '. $_GET['image_id'] .'
|
||||
;';
|
||||
$images = query2array($query);
|
||||
$image = $images[0];
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
*
|
||||
FROM '.IMAGE_FORMAT_TABLE.'
|
||||
WHERE image_id = '.$_GET['image_id'].'
|
||||
;';
|
||||
|
||||
$formats = query2array($query);
|
||||
|
||||
foreach ($formats as &$format)
|
||||
{
|
||||
$format['download_url'] = 'action.php?format='.$format['format_id'].'&download';
|
||||
|
||||
|
||||
$format['label'] = strtoupper($format['ext']);
|
||||
$lang_key = 'format '.strtoupper($format['ext']);
|
||||
if (isset($lang[$lang_key]))
|
||||
{
|
||||
$format['label'] = $lang[$lang_key];
|
||||
}
|
||||
|
||||
$format['filesize'] = round($format['filesize']/1024, 2);
|
||||
}
|
||||
|
||||
$template->assign(array(
|
||||
'ADD_FORMATS_URL' => get_root_url().'admin.php?page=photos_add&formats='.$_GET['image_id'],
|
||||
'IMG_SQUARE_SRC' => DerivativeImage::url(ImageStdParams::get_by_type(IMG_SQUARE), $image),
|
||||
'FORMATS' => $formats,
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
));
|
||||
|
||||
$template->set_filename('picture_formats', 'picture_formats.tpl');
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_formats');
|
||||
?>
|
||||
@@ -0,0 +1,430 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if(!defined("PHPWG_ROOT_PATH"))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('image_id', $_GET, false, PATTERN_ID);
|
||||
check_input_parameter('level', $_POST, false, '/^\d+$/');
|
||||
check_input_parameter('date_creation', $_POST, false, '/^\d\d\d\d-\d\d-\d\d( \d\d:\d\d:\d\d)?$/');
|
||||
|
||||
// retrieving direct information about picture. This may have been already
|
||||
// done on admin/photo.php but this page can also be accessed without
|
||||
// photo.php as proxy.
|
||||
if (!isset($page['image']))
|
||||
{
|
||||
$page['image'] = get_image_infos($_GET['image_id'], true);
|
||||
}
|
||||
|
||||
// represent
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE representative_picture_id = '.$_GET['image_id'].'
|
||||
;';
|
||||
$represented_albums = query2array($query, null, 'id');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | delete photo |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['delete']))
|
||||
{
|
||||
check_pwg_token();
|
||||
|
||||
delete_elements(array($_GET['image_id']), true);
|
||||
invalidate_user_cache();
|
||||
|
||||
// where to redirect the user now?
|
||||
//
|
||||
// 1. if a category is available in the URL, use it
|
||||
// 2. else use the first reachable linked category
|
||||
// 3. redirect to gallery root
|
||||
|
||||
if ($custom_context = get_edit_context($_GET['image_id']))
|
||||
{
|
||||
// considering we have a context available, we fake one to build the url
|
||||
// and we replace it with the context found in the session for this image_id
|
||||
redirect(str_replace('list/1,2', $custom_context, make_index_url(array('list'=>array(1,2)))));
|
||||
}
|
||||
|
||||
redirect(make_index_url());
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | synchronize metadata |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['sync_metadata']))
|
||||
{
|
||||
sync_metadata(array( intval($_GET['image_id'])));
|
||||
$page['infos'][] = l10n('Metadata synchronized from file');
|
||||
}
|
||||
|
||||
//--------------------------------------------------------- update informations
|
||||
if (isset($_POST['submit']))
|
||||
{
|
||||
check_pwg_token();
|
||||
|
||||
$data = array();
|
||||
$data['id'] = $_GET['image_id'];
|
||||
$data['level'] = $_POST['level'];
|
||||
|
||||
$to_sanitize_fields = array('name', 'author', 'comment');
|
||||
foreach ($to_sanitize_fields as $field)
|
||||
{
|
||||
$data[$field] = $conf['allow_html_descriptions'] ? @$_POST[$field] : strip_tags(@$_POST[$field]);
|
||||
}
|
||||
|
||||
if (!empty($_POST['date_creation']))
|
||||
{
|
||||
$data['date_creation'] = $_POST['date_creation'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['date_creation'] = null;
|
||||
}
|
||||
|
||||
$data = trigger_change('picture_modify_before_update', $data);
|
||||
|
||||
single_update(
|
||||
IMAGES_TABLE,
|
||||
$data,
|
||||
array('id' => $data['id'])
|
||||
);
|
||||
|
||||
// time to deal with tags
|
||||
$tag_ids = array();
|
||||
if (!empty($_POST['tags']))
|
||||
{
|
||||
$tag_ids = get_tag_ids($_POST['tags']);
|
||||
}
|
||||
set_tags($tag_ids, $_GET['image_id']);
|
||||
|
||||
// association to albums
|
||||
if (!isset($_POST['associate']))
|
||||
{
|
||||
$_POST['associate'] = array();
|
||||
}
|
||||
check_input_parameter('associate', $_POST, true, PATTERN_ID);
|
||||
move_images_to_categories(array($_GET['image_id']), $_POST['associate']);
|
||||
|
||||
invalidate_user_cache();
|
||||
|
||||
// thumbnail for albums
|
||||
if (!isset($_POST['represent']))
|
||||
{
|
||||
$_POST['represent'] = array();
|
||||
}
|
||||
check_input_parameter('represent', $_POST, true, PATTERN_ID);
|
||||
|
||||
$no_longer_thumbnail_for = array_diff($represented_albums, $_POST['represent']);
|
||||
if (count($no_longer_thumbnail_for) > 0)
|
||||
{
|
||||
set_random_representant($no_longer_thumbnail_for);
|
||||
}
|
||||
|
||||
$new_thumbnail_for = array_diff($_POST['represent'], $represented_albums);
|
||||
if (count($new_thumbnail_for) > 0)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.CATEGORIES_TABLE.'
|
||||
SET representative_picture_id = '.$_GET['image_id'].'
|
||||
WHERE id IN ('.implode(',', $new_thumbnail_for).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
$represented_albums = $_POST['represent'];
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'save_success' => l10n('Photo informations updated'),
|
||||
)
|
||||
);
|
||||
|
||||
pwg_activity('photo', $_GET['image_id'], 'edit');
|
||||
|
||||
// refresh page cache
|
||||
$page['image'] = get_image_infos($_GET['image_id'], true);
|
||||
}
|
||||
|
||||
// tags
|
||||
$query = '
|
||||
SELECT
|
||||
id,
|
||||
name
|
||||
FROM '.IMAGE_TAG_TABLE.' AS it
|
||||
JOIN '.TAGS_TABLE.' AS t ON t.id = it.tag_id
|
||||
WHERE image_id = '.$_GET['image_id'].'
|
||||
;';
|
||||
$tag_selection = get_taglist($query);
|
||||
|
||||
$row = $page['image'];
|
||||
|
||||
if (isset($data['date_creation']))
|
||||
{
|
||||
$row['date_creation'] = $data['date_creation'];
|
||||
}
|
||||
|
||||
$storage_category_id = null;
|
||||
if (!empty($row['storage_category_id']))
|
||||
{
|
||||
$storage_category_id = $row['storage_category_id'];
|
||||
}
|
||||
|
||||
$image_file = $row['file'];
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(
|
||||
array(
|
||||
'picture_modify' => 'picture_modify.tpl'
|
||||
)
|
||||
);
|
||||
|
||||
$admin_url_start = $admin_photo_base_url.'-properties';
|
||||
|
||||
$src_image = new SrcImage($row);
|
||||
|
||||
// in case the photo needs a rotation of 90 degrees (clockwise or counterclockwise), we switch width and height
|
||||
if (in_array($row['rotation'], array(1, 3)))
|
||||
{
|
||||
list($row['width'], $row['height']) = array($row['height'], $row['width']);
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'tag_selection' => $tag_selection,
|
||||
'U_DOWNLOAD' => 'action.php?id='.$_GET['image_id'].'&part=e&pwg_token='.get_pwg_token().'&download',
|
||||
'U_SYNC' => $admin_url_start.'&sync_metadata=1',
|
||||
'U_DELETE' => $admin_url_start.'&delete=1&pwg_token='.get_pwg_token(),
|
||||
'U_HISTORY' => get_root_url().'admin.php?page=history&filter_image_id='.$_GET['image_id'],
|
||||
'U_ACTIVITY' => get_root_url().'admin.php?page=user_activity&photo='.$_GET['image_id'],
|
||||
|
||||
'PATH'=>$row['path'],
|
||||
|
||||
'TN_SRC' => DerivativeImage::url(IMG_MEDIUM, $src_image),
|
||||
'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image),
|
||||
|
||||
'NAME' =>
|
||||
isset($_POST['name']) ?
|
||||
stripslashes($_POST['name']) : @$row['name'],
|
||||
|
||||
'TITLE' => render_element_name($row),
|
||||
|
||||
'DIMENSIONS' => @$row['width'].' * '.@$row['height'],
|
||||
|
||||
'FORMAT' => ($row['width'] >= $row['height'])? 1:0,//0:horizontal, 1:vertical
|
||||
|
||||
'FILESIZE' => @$row['filesize'].' KB',
|
||||
|
||||
'REGISTRATION_DATE' => format_date($row['date_available']),
|
||||
|
||||
'AUTHOR' => htmlspecialchars(
|
||||
isset($_POST['author'])
|
||||
? stripslashes($_POST['author'])
|
||||
: (empty($row['author']) ? '' : $row['author'])
|
||||
),
|
||||
|
||||
'DATE_CREATION' => $row['date_creation'],
|
||||
|
||||
'DESCRIPTION' =>
|
||||
htmlspecialchars( isset($_POST['comment']) ?
|
||||
stripslashes($_POST['comment']) : (empty($row['comment']) ? '' : $row['comment'])),
|
||||
|
||||
'F_ACTION' =>
|
||||
get_root_url().'admin.php'
|
||||
.get_query_string_diff(array('sync_metadata'))
|
||||
)
|
||||
);
|
||||
|
||||
$added_by = 'N/A';
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['username'].' AS username
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['id'].' = '.$row['added_by'].'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($user_row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['added_by'] = $user_row['username'];
|
||||
}
|
||||
|
||||
$extTab = explode('.',$row['file']);
|
||||
|
||||
$intro_vars = array(
|
||||
'file' => l10n('%s', $row['file']),
|
||||
'date' => l10n('Posted the %s', format_date($row['date_available'], array('day', 'month', 'year'))),
|
||||
'age' => l10n(ucfirst(time_since($row['date_available'], 'year'))),
|
||||
'added_by' => l10n('Added by %s', $row['added_by']),
|
||||
'size' => l10n('%s pixels, %.2f MB', $row['width'].'×'.$row['height'], $row['filesize']/1024),
|
||||
'stats' => l10n('Visited %d times', $row['hit']),
|
||||
'id' => l10n($row['id']),
|
||||
'ext' => l10n('%s file type',strtoupper(end($extTab))),
|
||||
'is_svg'=> (strtoupper(end($extTab)) == 'SVG'),
|
||||
);
|
||||
|
||||
if ($conf['rate'] and !empty($row['rating_score']))
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.RATE_TABLE.'
|
||||
WHERE element_id = '.$_GET['image_id'].'
|
||||
;';
|
||||
list($row['nb_rates']) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$intro_vars['stats'].= ', '.sprintf(l10n('Rated %d times, score : %.2f'), $row['nb_rates'], $row['rating_score']);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.IMAGE_FORMAT_TABLE.'
|
||||
WHERE image_id = '.$row['id'].'
|
||||
;';
|
||||
$formats = query2array($query);
|
||||
|
||||
if (!empty($formats))
|
||||
{
|
||||
$format_strings = array();
|
||||
|
||||
foreach ($formats as $format)
|
||||
{
|
||||
$format_strings[] = sprintf('%s (%.2fMB)', $format['ext'], $format['filesize']/1024);
|
||||
}
|
||||
|
||||
$intro_vars['formats'] = l10n('Formats: %s', implode(', ', $format_strings));
|
||||
}
|
||||
|
||||
$template->assign('INTRO', $intro_vars);
|
||||
|
||||
|
||||
if (in_array(get_extension($row['path']),$conf['picture_ext']))
|
||||
{
|
||||
$template->assign('U_COI', get_root_url().'admin.php?page=picture_coi&image_id='.$_GET['image_id']);
|
||||
}
|
||||
|
||||
// image level options
|
||||
$selected_level = isset($_POST['level']) ? $_POST['level'] : $row['level'];
|
||||
$template->assign(
|
||||
array(
|
||||
'level_options'=> get_privacy_level_options(),
|
||||
'level_options_selected' => array($selected_level)
|
||||
)
|
||||
);
|
||||
|
||||
// categories
|
||||
$query = '
|
||||
SELECT category_id, uppercats, dir
|
||||
FROM '.IMAGE_CATEGORY_TABLE.' AS ic
|
||||
INNER JOIN '.CATEGORIES_TABLE.' AS c
|
||||
ON c.id = ic.category_id
|
||||
WHERE image_id = '.$_GET['image_id'].'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
$related_categories = array();
|
||||
$related_categories_ids = array();
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$name =
|
||||
get_cat_display_name_cache(
|
||||
$row['uppercats'],
|
||||
get_root_url().'admin.php?page=album-'
|
||||
);
|
||||
|
||||
if ($row['category_id'] == $storage_category_id)
|
||||
{
|
||||
$template->assign('STORAGE_CATEGORY', $name);
|
||||
}
|
||||
|
||||
$related_categories[$row['category_id']] = array('name' => $name, 'unlinkable' => $row['category_id'] != $storage_category_id);
|
||||
$related_categories_ids[] = $row['category_id'];
|
||||
}
|
||||
|
||||
$template->assign('related_categories', $related_categories);
|
||||
$template->assign('related_categories_ids', $related_categories_ids);
|
||||
|
||||
// jump to link
|
||||
//
|
||||
// 1. if an edit_context is available, we use it (without checking permissions)
|
||||
// 2. else if user level is higher than image level, randomly find an authorized category
|
||||
// 3. else no jumpto link
|
||||
|
||||
if ($custom_context = get_edit_context($_GET['image_id']))
|
||||
{
|
||||
$template->assign('U_JUMPTO', make_picture_url(array('image_id' => $_GET['image_id'])).'/'.$custom_context);
|
||||
}
|
||||
elseif ($user['level'] >= $page['image']['level'])
|
||||
{
|
||||
$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 (count($authorizeds) > 0)
|
||||
{
|
||||
$category = $authorizeds[array_rand($authorizeds)];
|
||||
|
||||
$url_img = make_picture_url(
|
||||
array(
|
||||
'image_id' => $_GET['image_id'],
|
||||
'image_file' => $image_file,
|
||||
'category' => $cache['cat_names'][ $category ],
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign('U_JUMPTO', $url_img);
|
||||
}
|
||||
}
|
||||
|
||||
// associate to albums
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = category_id
|
||||
WHERE image_id = '.$_GET['image_id'].'
|
||||
;';
|
||||
$associated_albums = query2array($query, null, 'id');
|
||||
|
||||
$template->assign(array(
|
||||
'associated_albums' => $associated_albums,
|
||||
'represented_albums' => $represented_albums,
|
||||
'STORAGE_ALBUM' => $storage_category_id,
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')),
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
));
|
||||
|
||||
trigger_notify('loc_end_picture_modify');
|
||||
|
||||
//----------------------------------------------------------- sending html code
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_modify');
|
||||
?>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
$sections = explode('/', $_GET['section'] ?? '');
|
||||
for ($i=0; $i<count($sections); $i++)
|
||||
{
|
||||
if (empty($sections[$i]))
|
||||
{
|
||||
unset($sections[$i]);
|
||||
$i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($sections[$i] == '..' or !preg_match('/^[a-zA-Z0-9_\.-]+$/', $sections[$i]))
|
||||
{
|
||||
die('invalid section token ['.htmlentities($sections[$i]).']');
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sections)<2)
|
||||
{
|
||||
die('Invalid plugin URL');
|
||||
}
|
||||
|
||||
$plugin_id = $sections[0];
|
||||
|
||||
if (!preg_match('/^[\w-]+$/', $plugin_id))
|
||||
{
|
||||
die('Invalid plugin identifier');
|
||||
}
|
||||
|
||||
if ( !isset($pwg_loaded_plugins[$plugin_id]) )
|
||||
{
|
||||
die('Invalid URL - plugin '.$plugin_id.' not active');
|
||||
}
|
||||
|
||||
$filename = PHPWG_PLUGINS_PATH.implode('/', $sections);
|
||||
if (is_file($filename))
|
||||
{
|
||||
include_once($filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
die('Missing file '.htmlentities($filename));
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=plugins';
|
||||
|
||||
if (isset($_GET['tab']))
|
||||
$page['tab'] = $_GET['tab'];
|
||||
else
|
||||
$page['tab'] = 'installed';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('plugins');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
if ($page['tab'] == 'update') {
|
||||
include(PHPWG_ROOT_PATH.'admin/updates_ext.php');
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Plugins'));
|
||||
}
|
||||
else
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/plugins_'.$page['tab'].'.php');
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,219 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
|
||||
|
||||
$template->set_filenames(array('plugins' => 'plugins_installed.tpl'));
|
||||
|
||||
// should we display details on plugins?
|
||||
if (isset($_GET['show_details']))
|
||||
{
|
||||
if (1 == $_GET['show_details'])
|
||||
{
|
||||
$show_details = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_details = false;
|
||||
}
|
||||
|
||||
pwg_set_session_var('plugins_show_details', $show_details);
|
||||
}
|
||||
elseif (null != pwg_get_session_var('plugins_show_details'))
|
||||
{
|
||||
$show_details = pwg_get_session_var('plugins_show_details');
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_details = false;
|
||||
}
|
||||
|
||||
$base_url = get_root_url().'admin.php?page='.$page['page'];
|
||||
$pwg_token = get_pwg_token();
|
||||
$action_url = $base_url.'&plugin='.'%s'.'&pwg_token='.$pwg_token;
|
||||
|
||||
$plugins = new plugins();
|
||||
|
||||
//--------------------------------------------------------Incompatible Plugins
|
||||
if (isset($_GET['incompatible_plugins']))
|
||||
{
|
||||
$incompatible_plugins_raw = $plugins->get_incompatible_plugins();
|
||||
|
||||
if (false === $incompatible_plugins_raw)
|
||||
{
|
||||
echo json_encode(array());
|
||||
exit;
|
||||
}
|
||||
|
||||
$incompatible_plugins = array();
|
||||
|
||||
foreach ($incompatible_plugins_raw as $plugin => $version)
|
||||
{
|
||||
if ($plugin == '~~expire~~') continue;
|
||||
$incompatible_plugins[] = $plugin;
|
||||
|
||||
}
|
||||
echo json_encode($incompatible_plugins);
|
||||
exit;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------Get the menu with the depreciated version
|
||||
|
||||
$plugin_menu_links_deprec = trigger_change('get_admin_plugin_menu_links', array());
|
||||
|
||||
$settings_url_for_plugin_deprec = array();
|
||||
|
||||
foreach ($plugin_menu_links_deprec as $value)
|
||||
{
|
||||
if (preg_match('/^admin\.php\?page=plugin-(.*)$/', $value["URL"], $matches)) {
|
||||
$settings_url_for_plugin_deprec[$matches[1]] = $value["URL"];
|
||||
} elseif (preg_match('/^.*section=(.*?)[\/&%].*$/', $value["URL"], $matches)) {
|
||||
$settings_url_for_plugin_deprec[$matches[1]] = $value["URL"];
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | start template output |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$plugins->sort_fs_plugins('name');
|
||||
$merged_extensions = $plugins->get_merged_extensions();
|
||||
$merged_plugins = false;
|
||||
$tpl_plugins = array();
|
||||
$count_types_plugins = array("active"=>0, "inactive"=>0, "missing"=>0, "merged"=>0);
|
||||
|
||||
foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
|
||||
{
|
||||
if (isset($_SESSION['incompatible_plugins'][$plugin_id])
|
||||
and $fs_plugin['version'] != $_SESSION['incompatible_plugins'][$plugin_id])
|
||||
{
|
||||
// Incompatible plugins must be reinitilized
|
||||
unset($_SESSION['incompatible_plugins']);
|
||||
}
|
||||
|
||||
$setting_url = '';
|
||||
if (isset($settings_url_for_plugin_deprec[$plugin_id])) { //old version
|
||||
$setting_url = $settings_url_for_plugin_deprec[$plugin_id];
|
||||
} else if ($fs_plugin['hasSettings']) { // new version
|
||||
$setting_url = "admin.php?page=plugin-".$plugin_id;
|
||||
|
||||
if (preg_match('/^piwigo-(videojs|openstreetmap)$/', $plugin_id))
|
||||
{
|
||||
$setting_url = str_replace('piwigo-', 'piwigo_', $setting_url);
|
||||
}
|
||||
}
|
||||
|
||||
$url_to_replace = array(
|
||||
'http://piwigo.org/ext',
|
||||
'https://piwigo.org/ext'
|
||||
);
|
||||
$visit_url = str_replace($url_to_replace, PEM_URL, $fs_plugin['uri']);
|
||||
|
||||
$tpl_plugin = array(
|
||||
'ID' => $plugin_id,
|
||||
'NAME' => $fs_plugin['name'],
|
||||
'VISIT_URL' => $visit_url,
|
||||
'VERSION' => $fs_plugin['version'],
|
||||
'DESC' => $fs_plugin['description'],
|
||||
'AUTHOR' => $fs_plugin['author'],
|
||||
'AUTHOR_URL' => @$fs_plugin['author uri'],
|
||||
'U_ACTION' => sprintf($action_url, $plugin_id),
|
||||
'SETTINGS_URL' => $setting_url,
|
||||
);
|
||||
|
||||
if (isset($plugins->db_plugins_by_id[$plugin_id]))
|
||||
{
|
||||
$tpl_plugin['STATE'] = $plugins->db_plugins_by_id[$plugin_id]['state'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$tpl_plugin['STATE'] = 'inactive';
|
||||
}
|
||||
|
||||
if (isset($fs_plugin['extension']) and isset($merged_extensions[$fs_plugin['extension']]))
|
||||
{
|
||||
// Deactivate manually plugin from database
|
||||
$query = 'UPDATE '.PLUGINS_TABLE.' SET state=\'inactive\' WHERE id=\''.$plugin_id.'\'';
|
||||
pwg_query($query);
|
||||
|
||||
$tpl_plugin['STATE'] = 'merged';
|
||||
$tpl_plugin['DESC'] = l10n('THIS PLUGIN IS NOW PART OF PIWIGO CORE! DELETE IT NOW.');
|
||||
$merged_plugins = true;
|
||||
}
|
||||
|
||||
$count_types_plugins[$tpl_plugin['STATE']]++;
|
||||
|
||||
$tpl_plugins[] = $tpl_plugin;
|
||||
}
|
||||
|
||||
$template->append('plugin_states', 'active');
|
||||
$template->append('plugin_states', 'inactive');
|
||||
|
||||
if ($merged_plugins)
|
||||
{
|
||||
$template->append('plugin_states', 'merged');
|
||||
}
|
||||
|
||||
$missing_plugin_ids = array_diff(
|
||||
array_keys($plugins->db_plugins_by_id),
|
||||
array_keys($plugins->fs_plugins)
|
||||
);
|
||||
|
||||
if (count($missing_plugin_ids) > 0)
|
||||
{
|
||||
foreach ($missing_plugin_ids as $plugin_id)
|
||||
{
|
||||
$tpl_plugins[] = array(
|
||||
'NAME' => $plugin_id,
|
||||
'ID' => $plugin_id,
|
||||
'VERSION' => $plugins->db_plugins_by_id[$plugin_id]['version'],
|
||||
'DESC' => l10n('ERROR: THIS PLUGIN IS MISSING BUT IT IS INSTALLED! UNINSTALL IT NOW.'),
|
||||
'U_ACTION' => sprintf($action_url, $plugin_id),
|
||||
'STATE' => 'missing',
|
||||
);
|
||||
$count_types_plugins['missing']++;
|
||||
}
|
||||
$template->append('plugin_states', 'missing');
|
||||
}
|
||||
|
||||
// sort plugins by state then by name
|
||||
function cmp($a, $b)
|
||||
{
|
||||
$s = array('merged' => 0, 'missing' => 1, 'active' => 2, 'inactive' => 3);
|
||||
|
||||
if($a['STATE'] == $b['STATE'])
|
||||
return strcasecmp($a['NAME'], $b['NAME']);
|
||||
else
|
||||
return $s[$a['STATE']] >= $s[$b['STATE']];
|
||||
}
|
||||
|
||||
// Stoped plugin sorting for new plugin manager
|
||||
// usort($tpl_plugins, 'cmp');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'plugins' => $tpl_plugins,
|
||||
'count_types_plugins' => $count_types_plugins,
|
||||
'PWG_TOKEN' => $pwg_token,
|
||||
'base_url' => $base_url,
|
||||
'show_details' => $show_details,
|
||||
'max_inactive_before_hide' => isset($_GET['show_inactive']) ? 999 : 8,
|
||||
'isWebmaster' => (is_webmaster()) ? 1 : 0,
|
||||
'ADMIN_PAGE_TITLE' => l10n('Plugins'),
|
||||
'view_selector' => userprefs_get_param('plugin-manager-view', 'classic'),
|
||||
'CONF_ENABLE_EXTENSIONS_INSTALL' => $conf['enable_extensions_install'],
|
||||
)
|
||||
);
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
|
||||
?>
|
||||
@@ -0,0 +1,208 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
if (!$conf['enable_extensions_install'])
|
||||
{
|
||||
die('Piwigo extensions install/update system is disabled');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
|
||||
|
||||
$template->set_filenames(array('plugins' => 'plugins_new.tpl'));
|
||||
|
||||
$base_url = get_root_url().'admin.php?page='.$page['page'].'&tab='.$page['tab'];
|
||||
|
||||
$plugins = new plugins();
|
||||
|
||||
//------------------------------------------------------automatic installation
|
||||
if (isset($_GET['revision']) and isset($_GET['extension']))
|
||||
{
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$page['errors'][] = l10n('Webmaster status is required.');
|
||||
}
|
||||
else
|
||||
{
|
||||
check_pwg_token();
|
||||
|
||||
$install_status = $plugins->extract_plugin_files('install', $_GET['revision'], $_GET['extension'], $plugin_id);
|
||||
|
||||
redirect($base_url.'&installstatus='.$install_status.'&plugin_id='.$plugin_id);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------install result
|
||||
if (isset($_GET['installstatus']))
|
||||
{
|
||||
switch ($_GET['installstatus'])
|
||||
{
|
||||
case 'ok':
|
||||
// since Piwigo 12, you need to be on the page of installed plugins to active a plugin with
|
||||
// a JS action, no need to provide plugin_id in URL, just link to the page of installed
|
||||
// plugins, filtered on deactivated plugins. The webmaster will have to find its newly
|
||||
// installed plugin and click on the activation switch.
|
||||
$activate_url = get_root_url().'admin.php?page=plugins&filter=deactivated';
|
||||
|
||||
$page['infos'][] = l10n('Plugin has been successfully copied');
|
||||
$page['infos'][] = '<a href="'. $activate_url . '">' . l10n('Activate it now') . '</a>';
|
||||
|
||||
if (isset($plugins->fs_plugins[$_GET['plugin_id']]))
|
||||
{
|
||||
pwg_activity(
|
||||
'system',
|
||||
ACTIVITY_SYSTEM_PLUGIN,
|
||||
'install',
|
||||
array(
|
||||
'plugin_id' => $_GET['plugin_id'],
|
||||
'version' => $plugins->fs_plugins[$_GET['plugin_id']]['version'],
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'temp_path_error':
|
||||
$page['errors'][] = l10n('Can\'t create temporary file.');
|
||||
break;
|
||||
|
||||
case 'dl_archive_error':
|
||||
$page['errors'][] = l10n('Can\'t download archive.');
|
||||
break;
|
||||
|
||||
case 'archive_error':
|
||||
$page['errors'][] = l10n('Can\'t read or extract archive.');
|
||||
break;
|
||||
|
||||
default:
|
||||
$page['errors'][] = l10n('An error occured during extraction (%s).', htmlspecialchars($_GET['installstatus']));
|
||||
$page['errors'][] = l10n('Please check "plugins" folder and sub-folders permissions (CHMOD).');
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------Order options
|
||||
$template->assign('order_options',
|
||||
array(
|
||||
'date' => l10n('Post date'),
|
||||
'revision' => l10n('Last revisions'),
|
||||
'name' => l10n('Name'),
|
||||
'author' => l10n('Author'),
|
||||
'downloads' => l10n('Number of downloads')));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | start template output |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Beta test : show plugins of last version on PEM if the current version isn't present
|
||||
// If the current version in known, give the current and last version's compatible plugins
|
||||
$beta_test = false;
|
||||
|
||||
if(isset($_GET['beta-test']) && $_GET['beta-test'] == 'true')
|
||||
{
|
||||
$beta_test = true;
|
||||
}
|
||||
|
||||
if ($plugins->get_server_plugins(true, $beta_test))
|
||||
{
|
||||
/* order plugins */
|
||||
if (pwg_get_session_var('plugins_new_order') != null)
|
||||
{
|
||||
$order_selected = pwg_get_session_var('plugins_new_order');
|
||||
$plugins->sort_server_plugins($order_selected);
|
||||
$template->assign('order_selected', $order_selected);
|
||||
}
|
||||
else
|
||||
{
|
||||
$plugins->sort_server_plugins('date');
|
||||
$template->assign('order_selected', 'date');
|
||||
}
|
||||
|
||||
foreach($plugins->server_plugins as $plugin)
|
||||
{
|
||||
$ext_desc = trim($plugin['extension_description'], " \n\r");
|
||||
list($small_desc) = explode("\n", wordwrap($ext_desc, 200));
|
||||
|
||||
$url_auto_install = htmlentities($base_url)
|
||||
. '&revision=' . $plugin['revision_id']
|
||||
. '&extension=' . $plugin['extension_id']
|
||||
. '&pwg_token='.get_pwg_token()
|
||||
;
|
||||
|
||||
// get the age of the last revision in days
|
||||
$last_revision_diff = date_diff(date_create($plugin['revision_date']), date_create());
|
||||
|
||||
$certification = 1;
|
||||
$has_compatible_version = false;
|
||||
|
||||
// Check if the current version is in the compatible version (not necessary if we are in beta test)
|
||||
if ($beta_test) {
|
||||
foreach ($plugin['compatible_with_versions'] as $vers) {
|
||||
if (get_branch_from_version($vers) == get_branch_from_version(PHPWG_VERSION))
|
||||
{
|
||||
$has_compatible_version = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$has_compatible_version = true;
|
||||
}
|
||||
|
||||
if (!$has_compatible_version) {
|
||||
$certification = -1;
|
||||
}
|
||||
elseif ($last_revision_diff->days < 90) // if the last revision is new of 3 month or less
|
||||
{
|
||||
$certification = 3;
|
||||
}
|
||||
elseif ($last_revision_diff->days < 180) // 6 month or less
|
||||
{
|
||||
$certification = 2;
|
||||
}
|
||||
elseif ($last_revision_diff->y > 3) // 3 years or less
|
||||
{
|
||||
$certification = 0;
|
||||
}
|
||||
// Between 6 month and 3 years : certification = 1
|
||||
|
||||
$template->append('plugins', array(
|
||||
'ID' => $plugin['extension_id'],
|
||||
'EXT_NAME' => $plugin['extension_name'],
|
||||
'EXT_URL' => PEM_URL.'/extension_view.php?eid='.$plugin['extension_id'],
|
||||
'SMALL_DESC' => trim($small_desc, " \r\n"),
|
||||
'BIG_DESC' => $ext_desc,
|
||||
'VERSION' => $plugin['revision_name'],
|
||||
'REVISION_DATE' => preg_replace('/[^0-9]/', '', strtotime($plugin['revision_date'])),
|
||||
'REVISION_FORMATED_DATE' => format_date($plugin['revision_date'], array('day','month','year')).", ".time_since($plugin['revision_date'], "day"),
|
||||
'AUTHOR' => $plugin['author_name'],
|
||||
'DOWNLOADS' => $plugin['extension_nb_downloads'],
|
||||
'URL_INSTALL' => $url_auto_install,
|
||||
'CERTIFICATION' => $certification,
|
||||
'RATING' => $plugin['rating_score'],
|
||||
'NB_RATINGS' => $plugin['nb_ratings'],
|
||||
'SCREENSHOT' => (key_exists('screenshot_url', $plugin)) ? $plugin['screenshot_url']:'',
|
||||
'TAGS' => $plugin["tags"],
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('Can\'t connect to server.');
|
||||
}
|
||||
|
||||
if (!$beta_test and preg_match('/(beta|RC)/', PHPWG_VERSION))
|
||||
{
|
||||
$template->assign('BETA_URL', $base_url.'&beta-test=true');
|
||||
}
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Plugins'));
|
||||
$template->assign('BETA_TEST', $beta_test);
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
|
||||
?>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
define('PHPWG_ROOT_PATH', '../');
|
||||
define('PWG_HELP', true);
|
||||
define('IN_ADMIN', true);
|
||||
include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!isset($_GET['output']) or 'content_only' != $_GET['output'])
|
||||
{
|
||||
// Note on 2023-09-28 : calling popuphelp.php without output=content_only no longer occurs in Piwigo core.
|
||||
$page['body_id'] = 'thePopuphelpPage';
|
||||
$title = l10n('Piwigo Help');
|
||||
$page['page_banner'] = '<h1>'.$title.'</h1>';
|
||||
$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
|
||||
|
||||
// set required template variables to avoid "Undefined array key" with PHP 8
|
||||
$template->assign(
|
||||
array(
|
||||
'U_RETURN' => '',
|
||||
'USERNAME' => '',
|
||||
'U_FAQ'=> '',
|
||||
'U_CHANGE_THEME' => '',
|
||||
'U_LOGOUT' => '',
|
||||
)
|
||||
);
|
||||
|
||||
include(PHPWG_ROOT_PATH.'include/page_header.php');
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
isset($_GET['page'])
|
||||
and preg_match('/^[a-z_]*$/', $_GET['page'])
|
||||
)
|
||||
{
|
||||
$help_content = load_language(
|
||||
'help/'.$_GET['page'].'.html',
|
||||
'',
|
||||
array(
|
||||
'force_fallback' => 'en_UK',
|
||||
'return' => true,
|
||||
)
|
||||
);
|
||||
|
||||
if ($help_content == false)
|
||||
{
|
||||
$help_content = '';
|
||||
}
|
||||
|
||||
$help_content = trigger_change('get_popup_help_content', $help_content, $_GET['page']);
|
||||
}
|
||||
else
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
$template->set_filename('popuphelp','popuphelp.tpl');
|
||||
|
||||
$template->assign(
|
||||
array
|
||||
(
|
||||
'HELP_CONTENT' => $help_content
|
||||
));
|
||||
|
||||
if (isset($_GET['output']) and 'content_only' == $_GET['output'])
|
||||
{
|
||||
echo $help_content;
|
||||
exit();
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | html code display |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->pparse('popuphelp');
|
||||
|
||||
include(PHPWG_ROOT_PATH.'include/page_tail.php');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") ) die ("Hacking attempt!");
|
||||
|
||||
check_input_parameter('user_id', $_GET, false, PATTERN_ID);
|
||||
|
||||
$edit_user = build_user( $_GET['user_id'], false );
|
||||
|
||||
if (!empty($_POST))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'profile.php');
|
||||
|
||||
$errors = array();
|
||||
save_profile_from_post($edit_user, $errors);
|
||||
|
||||
load_profile_in_template(
|
||||
get_root_url().'admin.php?page=profile&user_id='.$edit_user['id'],
|
||||
get_root_url().'admin.php?page=user_list',
|
||||
$edit_user
|
||||
);
|
||||
$page['errors'] = array_merge($page['errors'], $errors);
|
||||
|
||||
$template->set_filename('profile', 'profile.tpl');
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'profile');
|
||||
?>
|
||||
@@ -0,0 +1,258 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
check_input_parameter('display', $_GET, false, PATTERN_ID);
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('rating');
|
||||
$tabsheet->select('rating');
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | initialization |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (isset($_GET['start']) and is_numeric($_GET['start']))
|
||||
{
|
||||
$start = $_GET['start'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$start = 0;
|
||||
}
|
||||
|
||||
$elements_per_page=10;
|
||||
if (isset($_GET['display']) and is_numeric($_GET['display']))
|
||||
{
|
||||
$elements_per_page = $_GET['display'];
|
||||
}
|
||||
|
||||
$order_by_index=0;
|
||||
if (isset($_GET['order_by']) and is_numeric($_GET['order_by']))
|
||||
{
|
||||
$order_by_index = $_GET['order_by'];
|
||||
}
|
||||
|
||||
$page['user_filter'] = '';
|
||||
if (isset($_GET['users']))
|
||||
{
|
||||
if ($_GET['users'] == 'user')
|
||||
{
|
||||
$page['user_filter'] = ' AND r.user_id <> '.$conf['guest_id'];
|
||||
}
|
||||
elseif ($_GET['users'] == 'guest')
|
||||
{
|
||||
$page['user_filter'] = ' AND r.user_id = '.$conf['guest_id'];
|
||||
}
|
||||
}
|
||||
|
||||
$page['cat_filter'] = '';
|
||||
if (isset($_GET['cat']) and is_numeric($_GET['cat']))
|
||||
{
|
||||
$cat_ids = get_subcat_ids(array($_GET['cat']));
|
||||
|
||||
if (count($cat_ids) > 0)
|
||||
{
|
||||
$page['cat_filter'] = ' AND ic.category_id IN ('.implode(',', $cat_ids).')';
|
||||
}
|
||||
}
|
||||
|
||||
$users = array();
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['username'].' as username, '.$conf['user_fields']['id'].' as id
|
||||
FROM '.USERS_TABLE.'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$users[$row['id']]=stripslashes($row['username']);
|
||||
}
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(DISTINCT(r.element_id))
|
||||
FROM '.RATE_TABLE.' AS r';
|
||||
|
||||
if (!empty($page['cat_filter']))
|
||||
{
|
||||
$query.= '
|
||||
JOIN '.IMAGES_TABLE.' AS i ON r.element_id = i.id
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
WHERE 1=1'. $page['user_filter'];
|
||||
list($nb_images) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.RATE_TABLE.
|
||||
';';
|
||||
list($nb_elements) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filename('rating', 'rating.tpl');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'navbar' => create_navigation_bar(
|
||||
PHPWG_ROOT_PATH.'admin.php'.get_query_string_diff(array('start','del')),
|
||||
$nb_images,
|
||||
$start,
|
||||
$elements_per_page
|
||||
),
|
||||
'F_ACTION' => PHPWG_ROOT_PATH.'admin.php',
|
||||
'DISPLAY' => $elements_per_page,
|
||||
'NB_ELEMENTS' => $nb_elements,
|
||||
'category' => (isset($_GET['cat']) ? array($_GET['cat']) : array()),
|
||||
'CACHE_KEYS' => get_admin_client_cache_keys(array('categories')),
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
$available_order_by= array(
|
||||
array(l10n('Rate date'), 'recently_rated DESC'),
|
||||
array(l10n('Rating score'), 'score DESC'),
|
||||
array(l10n('Average rate'), 'avg_rates DESC'),
|
||||
array(l10n('Number of rates'), 'nb_rates DESC'),
|
||||
array(l10n('Sum of rates'), 'sum_rates DESC'),
|
||||
array(l10n('File name'), 'file DESC'),
|
||||
array(l10n('Creation date'), 'date_creation DESC'),
|
||||
array(l10n('Post date'), 'date_available DESC'),
|
||||
);
|
||||
|
||||
for ($i=0; $i<count($available_order_by); $i++)
|
||||
{
|
||||
$template->append(
|
||||
'order_by_options',
|
||||
$available_order_by[$i][0]
|
||||
);
|
||||
}
|
||||
$template->assign('order_by_options_selected', array($order_by_index) );
|
||||
|
||||
|
||||
$user_options = array(
|
||||
'all' => l10n('all'),
|
||||
'user' => l10n('Users'),
|
||||
'guest' => l10n('Guests'),
|
||||
);
|
||||
|
||||
$template->assign('user_options', $user_options );
|
||||
$template->assign('user_options_selected', array(@$_GET['users']) );
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Rating'));
|
||||
|
||||
$query = '
|
||||
SELECT i.id,
|
||||
i.path,
|
||||
i.file,
|
||||
i.representative_ext,
|
||||
i.rating_score AS score,
|
||||
MAX(r.date) AS recently_rated,
|
||||
ROUND(AVG(r.rate),2) AS avg_rates,
|
||||
COUNT(r.rate) AS nb_rates,
|
||||
SUM(r.rate) AS sum_rates
|
||||
FROM '.RATE_TABLE.' AS r
|
||||
LEFT JOIN '.IMAGES_TABLE.' AS i ON r.element_id = i.id';
|
||||
|
||||
if (!empty($page['cat_filter']))
|
||||
{
|
||||
$query.= '
|
||||
JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
WHERE 1 = 1 ' . $page['user_filter'] . $page['cat_filter'] . '
|
||||
GROUP BY i.id,
|
||||
i.path,
|
||||
i.file,
|
||||
i.representative_ext,
|
||||
i.rating_score,
|
||||
r.element_id
|
||||
ORDER BY ' . $available_order_by[$order_by_index][1] .'
|
||||
LIMIT '.$elements_per_page.' OFFSET '.$start.'
|
||||
;';
|
||||
|
||||
$images = array();
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$images[] = $row;
|
||||
}
|
||||
|
||||
$template->assign( 'images', array() );
|
||||
foreach ($images as $image)
|
||||
{
|
||||
$thumbnail_src = DerivativeImage::thumb_url($image);
|
||||
|
||||
$image_url = get_root_url().'admin.php?page=photo-'.$image['id'];
|
||||
|
||||
$query = 'SELECT *
|
||||
FROM '.RATE_TABLE.' AS r
|
||||
WHERE r.element_id='.$image['id'] . '
|
||||
ORDER BY date DESC;';
|
||||
$result = pwg_query($query);
|
||||
$nb_rates = pwg_db_num_rows($result);
|
||||
|
||||
$tpl_image =
|
||||
array(
|
||||
'id' => $image['id'],
|
||||
'U_THUMB' => $thumbnail_src,
|
||||
'U_URL' => $image_url,
|
||||
'SCORE_RATE' => $image['score'],
|
||||
'AVG_RATE' => $image['avg_rates'],
|
||||
'SUM_RATE' => $image['sum_rates'],
|
||||
'NB_RATES' => (int)$image['nb_rates'],
|
||||
'NB_RATES_TOTAL' => (int)$nb_rates,
|
||||
'FILE' => $image['file'],
|
||||
'rates' => array()
|
||||
);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ( isset($users[$row['user_id']]) )
|
||||
{
|
||||
$user_rate = $users[$row['user_id']];
|
||||
}
|
||||
else
|
||||
{
|
||||
$user_rate = '? '. $row['user_id'];
|
||||
}
|
||||
if ( strlen($row['anonymous_id'])>0 )
|
||||
{
|
||||
$user_rate .= '('.$row['anonymous_id'].')';
|
||||
}
|
||||
|
||||
$row['USER'] = $user_rate;
|
||||
$tpl_image['rates'][] = $row;
|
||||
}
|
||||
$template->append( 'images', $tpl_image );
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'rating');
|
||||
?>
|
||||
@@ -0,0 +1,253 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
defined('PHPWG_ROOT_PATH') or die ("Hacking attempt!");
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('rating');
|
||||
$tabsheet->select('rating_user');
|
||||
$tabsheet->assign();
|
||||
|
||||
$filter_min_rates = 2;
|
||||
if (isset($_GET['f_min_rates']))
|
||||
{
|
||||
$filter_min_rates = (int)$_GET['f_min_rates'];
|
||||
}
|
||||
|
||||
$consensus_top_number = $conf['top_number'];
|
||||
if (isset($_GET['consensus_top_number']))
|
||||
{
|
||||
$consensus_top_number = (int)$_GET['consensus_top_number'];
|
||||
}
|
||||
|
||||
// build users
|
||||
global $conf;
|
||||
$query = 'SELECT DISTINCT
|
||||
u.'.$conf['user_fields']['id'].' AS id,
|
||||
u.'.$conf['user_fields']['username'].' AS name,
|
||||
ui.status
|
||||
FROM '.USERS_TABLE.' AS u INNER JOIN '.USER_INFOS_TABLE.' AS ui
|
||||
ON u.'.$conf['user_fields']['id'].' = ui.user_id';
|
||||
|
||||
$users_by_id = array();
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$users_by_id[(int)$row['id']] = array(
|
||||
'name' => $row['name'],
|
||||
'anon' => is_autorize_status(ACCESS_CLASSIC, $row['status']) ? false : true
|
||||
);
|
||||
}
|
||||
|
||||
$by_user_rating_model = array( 'rates' => array() );
|
||||
foreach($conf['rate_items'] as $rate)
|
||||
{
|
||||
$by_user_rating_model['rates'][$rate] = array();
|
||||
}
|
||||
|
||||
// by user aggregation
|
||||
$image_ids = array();
|
||||
$by_user_ratings = array();
|
||||
$query = '
|
||||
SELECT * FROM '.RATE_TABLE.' ORDER by date DESC';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if (!isset($users_by_id[$row['user_id']]))
|
||||
{
|
||||
$users_by_id[$row['user_id']] = array('name' => '???'.$row['user_id'], 'anon' => false);
|
||||
}
|
||||
$usr = $users_by_id[$row['user_id']];
|
||||
if ($usr['anon'])
|
||||
{
|
||||
$user_key = $usr['name'].'('.$row['anonymous_id'].')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$user_key = $usr['name'];
|
||||
}
|
||||
$rating = & $by_user_ratings[$user_key];
|
||||
if ( is_null($rating) )
|
||||
{
|
||||
$rating = $by_user_rating_model;
|
||||
$rating['uid'] = (int)$row['user_id'];
|
||||
$rating['aid'] = $usr['anon'] ? $row['anonymous_id'] : '';
|
||||
$rating['last_date'] = $rating['first_date'] = $row['date'];
|
||||
}
|
||||
else
|
||||
$rating['first_date'] = $row['date'];
|
||||
|
||||
$rating['rates'][$row['rate']][] = array(
|
||||
'id' => $row['element_id'],
|
||||
'date' => $row['date'],
|
||||
);
|
||||
$image_ids[$row['element_id']] = 1;
|
||||
unset($rating);
|
||||
}
|
||||
|
||||
// get image tn urls
|
||||
$image_urls = array();
|
||||
if (count($image_ids) > 0 )
|
||||
{
|
||||
$query = 'SELECT id, name, file, path, representative_ext, level
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN ('.implode(',', array_keys($image_ids)).')';
|
||||
$result = pwg_query($query);
|
||||
$params = ImageStdParams::get_by_type(IMG_SQUARE);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$image_urls[ $row['id'] ] = array(
|
||||
'tn' => DerivativeImage::url($params, $row),
|
||||
'page' => make_picture_url( array('image_id'=>$row['id'], 'image_file'=>$row['file']) ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//all image averages
|
||||
$query='SELECT element_id,
|
||||
AVG(rate) AS avg
|
||||
FROM '.RATE_TABLE.'
|
||||
GROUP BY element_id';
|
||||
$all_img_sum = array();
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$all_img_sum[(int)$row['element_id']] = array( 'avg'=>(float)$row['avg'] );
|
||||
}
|
||||
|
||||
$query='SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
ORDER by rating_score DESC
|
||||
LIMIT '.$consensus_top_number;
|
||||
$best_rated = array_flip( array_from_query($query, 'id'));
|
||||
|
||||
// by user stats
|
||||
foreach($by_user_ratings as $id => &$rating)
|
||||
{
|
||||
$c=0; $s=0; $ss=0; $consensus_dev=0; $consensus_dev_top=0; $consensus_dev_top_count=0;
|
||||
foreach($rating['rates'] as $rate => $rates)
|
||||
{
|
||||
$ct = count($rates);
|
||||
$c += $ct;
|
||||
$s += $ct * $rate;
|
||||
$ss += $ct * $rate * $rate;
|
||||
foreach($rates as $id_date)
|
||||
{
|
||||
$dev = abs($rate - $all_img_sum[$id_date['id']]['avg']);
|
||||
$consensus_dev += $dev;
|
||||
if (isset($best_rated[$id_date['id']]))
|
||||
{
|
||||
$consensus_dev_top += $dev;
|
||||
$consensus_dev_top_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$consensus_dev /= $c;
|
||||
if ($consensus_dev_top_count)
|
||||
$consensus_dev_top /= $consensus_dev_top_count;
|
||||
|
||||
$var = ($ss - $s*$s/$c)/$c;
|
||||
$rating += array(
|
||||
'id' => $id,
|
||||
'count' => $c,
|
||||
'avg' => $s/$c,
|
||||
'cv' => $s==0 ? -1 : sqrt($var)/($s/$c), // http://en.wikipedia.org/wiki/Coefficient_of_variation
|
||||
'cd' => $consensus_dev,
|
||||
'cdtop' => $consensus_dev_top_count ? $consensus_dev_top : '',
|
||||
);
|
||||
}
|
||||
unset($rating);
|
||||
|
||||
// filter
|
||||
foreach($by_user_ratings as $id => $rating)
|
||||
{
|
||||
if ($rating['count'] <= $filter_min_rates)
|
||||
{
|
||||
unset($by_user_ratings[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function avg_compare($a, $b)
|
||||
{
|
||||
$d = $a['avg'] - $b['avg'];
|
||||
return ($d==0) ? 0 : ($d<0 ? -1 : 1);
|
||||
}
|
||||
|
||||
function count_compare($a, $b)
|
||||
{
|
||||
$d = $a['count'] - $b['count'];
|
||||
return ($d==0) ? 0 : ($d<0 ? -1 : 1);
|
||||
}
|
||||
|
||||
function cv_compare($a, $b)
|
||||
{
|
||||
$d = $b['cv'] - $a['cv']; //desc
|
||||
return ($d==0) ? 0 : ($d<0 ? -1 : 1);
|
||||
}
|
||||
|
||||
function consensus_dev_compare($a, $b)
|
||||
{
|
||||
$d = $b['cd'] - $a['cd']; //desc
|
||||
return ($d==0) ? 0 : ($d<0 ? -1 : 1);
|
||||
}
|
||||
|
||||
function last_rate_compare($a, $b)
|
||||
{
|
||||
return -strcmp( $a['last_date'], $b['last_date']);
|
||||
}
|
||||
|
||||
$order_by_index=4;
|
||||
if (isset($_GET['order_by']) and is_numeric($_GET['order_by']))
|
||||
{
|
||||
$order_by_index = $_GET['order_by'];
|
||||
}
|
||||
|
||||
$available_order_by= array(
|
||||
array(l10n('Average rate'), 'avg_compare'),
|
||||
array(l10n('Number of rates'), 'count_compare'),
|
||||
array(l10n('Variation'), 'cv_compare'),
|
||||
array(l10n('Consensus deviation'), 'consensus_dev_compare'),
|
||||
array(l10n('Last'), 'last_rate_compare'),
|
||||
);
|
||||
|
||||
for ($i=0; $i<count($available_order_by); $i++)
|
||||
{
|
||||
$template->append(
|
||||
'order_by_options',
|
||||
$available_order_by[$i][0]
|
||||
);
|
||||
}
|
||||
$template->assign('order_by_options_selected', array($order_by_index) );
|
||||
|
||||
$x = uasort($by_user_ratings, $available_order_by[$order_by_index][1] );
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.RATE_TABLE.
|
||||
';';
|
||||
list($nb_elements) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
$template->assign( array(
|
||||
'F_ACTION' => get_root_url().'admin.php',
|
||||
'F_MIN_RATES' => $filter_min_rates,
|
||||
'CONSENSUS_TOP_NUMBER' => $consensus_top_number,
|
||||
'available_rates' => $conf['rate_items'],
|
||||
'ratings' => $by_user_ratings,
|
||||
'image_urls' => $image_urls,
|
||||
'TN_WIDTH' => ImageStdParams::get_by_type(IMG_SQUARE)->sizing->ideal_size[0],
|
||||
'NB_ELEMENTS' => $nb_elements,
|
||||
'ADMIN_PAGE_TITLE' => l10n('Rating'),
|
||||
));
|
||||
$template->set_filename('rating', 'rating_user.tpl');
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'rating');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,185 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!$conf['enable_synchronization'])
|
||||
{
|
||||
die('synchronization is disabled');
|
||||
}
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (!empty($_POST) or isset($_GET['action']))
|
||||
{
|
||||
check_pwg_token();
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filenames(array('site_manager'=>'site_manager.tpl'));
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('site_update');
|
||||
$tabsheet->select('site_maager');
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | new site creation form |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (isset($_POST['submit']) and !empty($_POST['galleries_url']))
|
||||
{
|
||||
$is_remote = url_is_remote( $_POST['galleries_url'] );
|
||||
if ($is_remote)
|
||||
{
|
||||
fatal_error('remote sites not supported');
|
||||
}
|
||||
$url = preg_replace('/[\/]*$/', '', $_POST['galleries_url']);
|
||||
$url.= '/';
|
||||
if ( ! (strpos($url, '.') === 0 ) )
|
||||
{
|
||||
$url = './' . $url;
|
||||
}
|
||||
|
||||
// site must not exists
|
||||
$query = '
|
||||
SELECT COUNT(id) AS count
|
||||
FROM '.SITES_TABLE.'
|
||||
WHERE galleries_url = \''.$url.'\'
|
||||
;';
|
||||
$row = pwg_db_fetch_assoc(pwg_query($query));
|
||||
if ($row['count'] > 0)
|
||||
{
|
||||
$page['errors'][] = l10n('This site already exists').' ['.$url.']';
|
||||
}
|
||||
if (count($page['errors']) == 0)
|
||||
{
|
||||
if ( ! file_exists($url) )
|
||||
{
|
||||
$page['errors'][] = l10n('Directory does not exist').' ['.$url.']';
|
||||
}
|
||||
}
|
||||
|
||||
if (count($page['errors']) == 0)
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '.SITES_TABLE.'
|
||||
(galleries_url)
|
||||
VALUES
|
||||
(\''.$url.'\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
$page['infos'][] = $url.' '.l10n('created');
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | actions on site |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (isset($_GET['site']) and is_numeric($_GET['site']))
|
||||
{
|
||||
$page['site'] = $_GET['site'];
|
||||
}
|
||||
if (isset($_GET['action']) and isset($page['site']))
|
||||
{
|
||||
$query = '
|
||||
SELECT galleries_url
|
||||
FROM '.SITES_TABLE.'
|
||||
WHERE id = '.$page['site'].'
|
||||
;';
|
||||
list($galleries_url) = pwg_db_fetch_row(pwg_query($query));
|
||||
switch($_GET['action'])
|
||||
{
|
||||
case 'delete' :
|
||||
{
|
||||
delete_site($page['site']);
|
||||
$page['infos'][] = $galleries_url.' '.l10n('deleted');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ACTION' => get_root_url().'admin.php'.get_query_string_diff(array('action','site','pwg_token')),
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
'ADMIN_PAGE_TITLE' => l10n('Synchronize'),
|
||||
)
|
||||
);
|
||||
|
||||
$query = '
|
||||
SELECT c.site_id, COUNT(DISTINCT c.id) AS nb_categories, COUNT(i.id) AS nb_images
|
||||
FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
|
||||
ON c.id=i.storage_category_id
|
||||
WHERE c.site_id IS NOT NULL
|
||||
GROUP BY c.site_id
|
||||
;';
|
||||
$sites_detail = hash_from_query($query, 'site_id');
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.SITES_TABLE.'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$is_remote = url_is_remote($row['galleries_url']);
|
||||
$base_url = PHPWG_ROOT_PATH.'admin.php';
|
||||
$base_url.= '?page=site_manager';
|
||||
$base_url.= '&site='.$row['id'];
|
||||
$base_url.= '&pwg_token='.get_pwg_token();
|
||||
$base_url.= '&action=';
|
||||
|
||||
$update_url = PHPWG_ROOT_PATH.'admin.php';
|
||||
$update_url.= '?page=site_update';
|
||||
$update_url.= '&site='.$row['id'];
|
||||
|
||||
$tpl_var =
|
||||
array(
|
||||
'NAME' => $row['galleries_url'],
|
||||
'TYPE' => l10n( $is_remote ? 'Remote' : 'Local' ),
|
||||
'CATEGORIES' => (int)@$sites_detail[$row['id']]['nb_categories'],
|
||||
'IMAGES' => (int)@$sites_detail[$row['id']]['nb_images'],
|
||||
'U_SYNCHRONIZE' => $update_url
|
||||
);
|
||||
|
||||
if ($row['id'] != 1)
|
||||
{
|
||||
$tpl_var['U_DELETE'] = $base_url.'delete';
|
||||
}
|
||||
|
||||
$plugin_links = array();
|
||||
//$plugin_links is array of array composed of U_HREF, U_HINT & U_CAPTION
|
||||
$plugin_links =
|
||||
trigger_change('get_admins_site_links',
|
||||
$plugin_links, $row['id'], $is_remote);
|
||||
$tpl_var['plugin_links'] = $plugin_links;
|
||||
|
||||
$template->append('sites', $tpl_var);
|
||||
}
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'site_manager');
|
||||
?>
|
||||
@@ -0,0 +1,197 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// provides data for site synchronization from the local file system
|
||||
class LocalSiteReader
|
||||
{
|
||||
|
||||
var $site_url;
|
||||
|
||||
function __construct($url)
|
||||
{
|
||||
$this->site_url = $url;
|
||||
global $conf;
|
||||
if (!isset($conf['flip_file_ext']))
|
||||
{
|
||||
$conf['flip_file_ext'] = array_flip($conf['file_ext']);
|
||||
}
|
||||
if (!isset($conf['flip_picture_ext']))
|
||||
{
|
||||
$conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this local site ok ?
|
||||
*
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
function open()
|
||||
{
|
||||
global $errors;
|
||||
|
||||
if (!is_dir($this->site_url))
|
||||
{
|
||||
$errors[] = array(
|
||||
'path' => $this->site_url,
|
||||
'type' => 'PWG-ERROR-NO-FS'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// retrieve file system sub-directories fulldirs
|
||||
function get_full_directories($basedir)
|
||||
{
|
||||
$fs_fulldirs = get_fs_directories($basedir);
|
||||
return $fs_fulldirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all file system files according to $conf['file_ext']
|
||||
* and $conf['picture_ext']
|
||||
* @param string $path recurse in this directory
|
||||
* @return array like "pic.jpg"=>array('representative_ext'=>'jpg' ... )
|
||||
*/
|
||||
function get_elements($path)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$subdirs = array();
|
||||
$fs = array();
|
||||
if (is_dir($path) && $contents = opendir($path) )
|
||||
{
|
||||
while (($node = readdir($contents)) !== false)
|
||||
{
|
||||
if ($node == '.' or $node == '..') continue;
|
||||
|
||||
if (is_file($path.'/'.$node))
|
||||
{
|
||||
$extension = strtolower(get_extension($node));
|
||||
$filename_wo_ext = get_filename_wo_extension($node);
|
||||
|
||||
if ( isset($conf['flip_file_ext'][$extension]) )
|
||||
{
|
||||
$representative_ext = null;
|
||||
if (! isset($conf['flip_picture_ext'][$extension]) )
|
||||
{
|
||||
$representative_ext = $this->get_representative_ext($path, $filename_wo_ext);
|
||||
}
|
||||
|
||||
$fs[ $path.'/'.$node ] = array('representative_ext' => $representative_ext);
|
||||
|
||||
if ($conf['enable_formats'])
|
||||
{
|
||||
$fs[ $path.'/'.$node ]['formats'] = $this->get_formats($path, $filename_wo_ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (is_dir($path.'/'.$node)
|
||||
and $node != 'pwg_high'
|
||||
and $node != 'pwg_representative'
|
||||
and $node != 'pwg_format'
|
||||
and $node != 'thumbnail' )
|
||||
{
|
||||
$subdirs[] = $node;
|
||||
}
|
||||
} //end while readdir
|
||||
closedir($contents);
|
||||
|
||||
foreach ($subdirs as $subdir)
|
||||
{
|
||||
$tmp_fs = $this->get_elements($path.'/'.$subdir);
|
||||
$fs = array_merge($fs, $tmp_fs);
|
||||
}
|
||||
ksort($fs);
|
||||
} //end if is_dir
|
||||
return $fs;
|
||||
}
|
||||
|
||||
// returns the name of the attributes that are supported for
|
||||
// files update/synchronization
|
||||
function get_update_attributes()
|
||||
{
|
||||
return array('representative_ext');
|
||||
}
|
||||
|
||||
function get_element_update_attributes($file)
|
||||
{
|
||||
global $conf;
|
||||
$data = array();
|
||||
|
||||
$filename = basename($file);
|
||||
$extension = get_extension($filename);
|
||||
|
||||
$representative_ext = null;
|
||||
if (! isset($conf['flip_picture_ext'][$extension]) )
|
||||
{
|
||||
$dirname = dirname($file);
|
||||
$filename_wo_ext = get_filename_wo_extension($filename);
|
||||
$representative_ext = $this->get_representative_ext($dirname, $filename_wo_ext);
|
||||
}
|
||||
|
||||
$data['representative_ext'] = $representative_ext;
|
||||
return $data;
|
||||
}
|
||||
|
||||
// returns the name of the attributes that are supported for
|
||||
// metadata update/synchronization according to configuration
|
||||
function get_metadata_attributes()
|
||||
{
|
||||
return get_sync_metadata_attributes();
|
||||
}
|
||||
|
||||
// returns a hash of attributes (metadata+filesize+width,...) for file
|
||||
function get_element_metadata($infos)
|
||||
{
|
||||
return get_sync_metadata($infos);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------- private functions --------
|
||||
function get_representative_ext($path, $filename_wo_ext)
|
||||
{
|
||||
global $conf;
|
||||
$base_test = $path.'/pwg_representative/'.$filename_wo_ext.'.';
|
||||
foreach ($conf['picture_ext'] as $ext)
|
||||
{
|
||||
$test = $base_test.$ext;
|
||||
if (is_file($test))
|
||||
{
|
||||
return $ext;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function get_formats($path, $filename_wo_ext)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$formats = array();
|
||||
|
||||
$base_test = $path.'/pwg_format/'.$filename_wo_ext.'.';
|
||||
|
||||
foreach ($conf['format_ext'] as $ext)
|
||||
{
|
||||
$test = $base_test.$ext;
|
||||
|
||||
if (is_file($test))
|
||||
{
|
||||
$formats[$ext] = floor(filesize($test) / 1024);
|
||||
}
|
||||
}
|
||||
|
||||
return $formats;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,399 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die ('Hacking attempt!');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_history.inc.php');
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Functions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
//Get the last unit of time for years, months, days and hours
|
||||
function get_last($last_number=60, $type='year')
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
nb_pages
|
||||
FROM '.HISTORY_SUMMARY_TABLE;
|
||||
|
||||
if ($type === 'hour')
|
||||
{
|
||||
$query.= '
|
||||
WHERE year IS NOT NULL
|
||||
AND month IS NOT NULL
|
||||
AND day IS NOT NULL
|
||||
AND hour IS NOT NULL
|
||||
ORDER BY
|
||||
year DESC,
|
||||
month DESC,
|
||||
day DESC,
|
||||
hour DESC
|
||||
LIMIT '.$last_number.'
|
||||
;';
|
||||
}
|
||||
elseif ($type === 'day')
|
||||
{
|
||||
$query.= '
|
||||
WHERE year IS NOT NULL
|
||||
AND month IS NOT NULL
|
||||
AND day IS NOT NULL
|
||||
AND hour IS NULL
|
||||
ORDER BY
|
||||
year DESC,
|
||||
month DESC,
|
||||
day DESC
|
||||
LIMIT '.$last_number.'
|
||||
;';
|
||||
}
|
||||
elseif ($type === 'month')
|
||||
{
|
||||
$query.= '
|
||||
WHERE year IS NOT NULL
|
||||
AND month IS NOT NULL
|
||||
AND day IS NULL
|
||||
ORDER BY
|
||||
year DESC,
|
||||
month DESC
|
||||
LIMIT '.$last_number.'
|
||||
;';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= '
|
||||
WHERE year IS NOT NULL
|
||||
AND month IS NULL
|
||||
ORDER BY
|
||||
year DESC
|
||||
LIMIT '.$last_number.'
|
||||
;';
|
||||
}
|
||||
|
||||
$result = pwg_query($query);
|
||||
|
||||
$output = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$output[] = $row;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function get_month_of_last_years ($last = 'all')
|
||||
{
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
nb_pages
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
WHERE month IS NOT NULL
|
||||
AND day IS NULL
|
||||
ORDER BY
|
||||
year DESC,
|
||||
month DESC';
|
||||
|
||||
if ($last !== 'all')
|
||||
{
|
||||
$date = new DateTime();
|
||||
$limit = ($last - 1)*12+$date->format('n') - 1;
|
||||
$query .=
|
||||
' LIMIT '.$limit;
|
||||
$result = query2array($query.';');
|
||||
$lastDate = $date->sub(new DateInterval('P'.($last - 1).'Y'.($date->format('n') - 1).'M'));
|
||||
return set_missing_values('month', $result, $lastDate, new DateTime());
|
||||
}
|
||||
|
||||
if (count(query2array($query.';')) > 1 )
|
||||
{
|
||||
return set_missing_values('month', query2array($query.';'));
|
||||
} else {
|
||||
$last_year_date = new DateTime();
|
||||
return set_missing_values(
|
||||
'month',
|
||||
query2array($query.';'),
|
||||
$last_year_date->sub(new DateInterval('P1Y')),
|
||||
new DateTime()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function get_month_stats()
|
||||
{
|
||||
$result = array();
|
||||
$date = new DateTime();
|
||||
$date_last_month = clone $date;
|
||||
$date_last_year = clone $date;
|
||||
$months = array();
|
||||
|
||||
$date_last_month->sub(new DateInterval('P1M'));
|
||||
$date_last_year->sub(new DateInterval('P1Y'));
|
||||
$query = '
|
||||
SELECT
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
nb_pages
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
WHERE
|
||||
(
|
||||
(year = '.$date->format('Y').' AND month = '.$date->format('n').')
|
||||
OR (year = '.$date_last_month->format('Y').' AND month = '.$date_last_month->format('n').')
|
||||
OR (year = '.$date_last_year->format('Y').' AND month = '.$date_last_year->format('n').')
|
||||
)
|
||||
AND day IS NOT NULL
|
||||
AND hour IS NULL
|
||||
ORDER BY
|
||||
year DESC,
|
||||
month DESC
|
||||
;';
|
||||
|
||||
foreach (query2array($query) as $value)
|
||||
{
|
||||
$date = get_date_object($value);
|
||||
@$months[$date->format('Y/m/1')][] = $value;
|
||||
}
|
||||
|
||||
$actual_date = new DateTime();
|
||||
if (!isset($months[$actual_date->format('Y/m/1')]))
|
||||
{
|
||||
@$months[$actual_date->format('Y/m/1')][] = array(
|
||||
'year' => $actual_date->format('Y'),
|
||||
'month'=> $actual_date->format('n'),
|
||||
'day'=> null,
|
||||
'hour'=> null,
|
||||
'nb_pages' => 0
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($months as $key => $val)
|
||||
{
|
||||
$lastDate = new DateTime($key);
|
||||
$lastDate = $lastDate->add(new DateInterval('P1M'));
|
||||
$lastDate = $lastDate->sub(new DateInterval('P1D'));
|
||||
if ($lastDate > new DateTime())
|
||||
{
|
||||
$lastDate = new DateTime();
|
||||
}
|
||||
$result['month'][] = set_missing_values('day',$val, new DateTime($key), $lastDate);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
AVG(nb_pages)
|
||||
FROM '.HISTORY_SUMMARY_TABLE.'
|
||||
WHERE
|
||||
(
|
||||
year = '.$date->format('Y').' OR
|
||||
(year = '.($date->format('Y')-1).' and month > '.$date->format('n').')
|
||||
)
|
||||
AND day IS NOT NULL
|
||||
AND hour IS NULL
|
||||
ORDER BY
|
||||
year DESC,
|
||||
month DESC
|
||||
;';
|
||||
|
||||
list($result['avg']) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Check Access and exit when user status is not ok |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Refresh summary from details |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
history_summarize();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Display statistics header |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filename('stats', 'stats.tpl');
|
||||
|
||||
// TabSheet initialization
|
||||
history_tabsheet();
|
||||
|
||||
$base_url = get_root_url().'admin.php?page=history';
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'U_HELP' => get_root_url().'admin/popuphelp.php?page=history',
|
||||
'F_ACTION' => $base_url,
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Set missing rows to 0 |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
function set_missing_values($unit, $data, $firstDate = null, $lastDate = null)
|
||||
{
|
||||
$limit = count($data);
|
||||
$result = array();
|
||||
|
||||
if ($firstDate == null)
|
||||
{
|
||||
$date = get_date_object($data[count($data) - 1]);
|
||||
} else {
|
||||
$date = $firstDate;
|
||||
}
|
||||
if ($lastDate == null)
|
||||
{
|
||||
$date_end = get_date_object($data[0]);
|
||||
} else {
|
||||
$date_end = $lastDate;
|
||||
}
|
||||
|
||||
//Declare variable according the unit
|
||||
if ($unit == 'year')
|
||||
{
|
||||
$date_format = 'Y';
|
||||
$date_add = 'P1Y';
|
||||
}
|
||||
else if ($unit == 'month')
|
||||
{
|
||||
$date_format = 'Y-m';
|
||||
$date_add = 'P1M';
|
||||
}
|
||||
else if ($unit == 'day')
|
||||
{
|
||||
$date_format = 'Y-m-d';
|
||||
$date_add = 'P1D';
|
||||
}
|
||||
else if ($unit == 'hour')
|
||||
{
|
||||
$date_format = 'Y-m-d\TH:00';
|
||||
$date_add = 'PT1H';
|
||||
}
|
||||
|
||||
//Fill an empty array with all the dates
|
||||
while ($date <= $date_end) {
|
||||
$result[$date->format($date_format)] = 0;
|
||||
$date->add(new DateInterval($date_add));
|
||||
}
|
||||
|
||||
//Overload with database rows
|
||||
foreach ($data as $value)
|
||||
{
|
||||
$str = get_date_object($value)->format($date_format);
|
||||
if (isset($result[$str]))
|
||||
{
|
||||
$result[$str] += $value['nb_pages'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//Get a DateTime object for a database row
|
||||
function get_date_object($row)
|
||||
{
|
||||
$date_string = $row['year'];
|
||||
if ($row['month'] != null)
|
||||
{
|
||||
$date_string = $date_string.'-'.$row['month'] ;
|
||||
if ($row['day'] != null)
|
||||
{
|
||||
$date_string = $date_string.'-'.$row['day'];
|
||||
if ($row['hour'] != null)
|
||||
{
|
||||
$date_string = $date_string.' '.$row['hour'].':00';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$date_string .= '-1';
|
||||
}
|
||||
|
||||
return new DateTime($date_string);
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Send data to template |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$actual_date = new DateTime();
|
||||
$actual_date->add(new DateInterval('PT1S'));
|
||||
|
||||
$first_date = new DateTime();
|
||||
$last_hours = set_missing_values(
|
||||
'hour',
|
||||
get_last(72, 'hour'),
|
||||
$first_date->sub(new DateInterval("P3D")),
|
||||
$actual_date
|
||||
);
|
||||
|
||||
$first_date = new DateTime();
|
||||
$last_days = set_missing_values(
|
||||
'day',
|
||||
get_last(90, 'day'),
|
||||
$first_date->sub(new DateInterval("P90D")),
|
||||
$actual_date
|
||||
);
|
||||
|
||||
$first_date = new DateTime();
|
||||
$last_months = set_missing_values(
|
||||
'month',
|
||||
get_last(60, 'month'),
|
||||
$first_date->sub(new DateInterval("P60M")),
|
||||
$actual_date
|
||||
);
|
||||
|
||||
if (count(get_last(60, 'year')) > 1 )
|
||||
{
|
||||
$last_years = set_missing_values(
|
||||
'year',
|
||||
get_last(60, 'year')
|
||||
);
|
||||
} else {
|
||||
$last_year_date = new DateTime();
|
||||
$last_years = set_missing_values(
|
||||
'year',
|
||||
get_last(60, 'year'),
|
||||
$last_year_date->sub(new DateInterval('P1Y')),
|
||||
new DateTime()
|
||||
);
|
||||
}
|
||||
|
||||
ksort($lang['month']);
|
||||
|
||||
$template->assign(array(
|
||||
'compareYears' => get_month_of_last_years($conf['stat_compare_year_displayed']),
|
||||
'monthStats' => get_month_stats(),
|
||||
'lastHours' => $last_hours,
|
||||
'lastDays' => $last_days,
|
||||
'lastMonths' => $last_months,
|
||||
'lastYears' => $last_years,
|
||||
'langCode' => strval($user['language']),
|
||||
'month_labels' => join('~', $lang['month']),
|
||||
'ADMIN_PAGE_TITLE' => l10n('History'),
|
||||
));
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'stats');
|
||||
?>
|
||||
@@ -0,0 +1,165 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tabs |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('tags');
|
||||
$tabsheet->select('');
|
||||
$tabsheet->assign();
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | delete orphan tags |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (isset($_GET['action']) and 'delete_orphans' == $_GET['action'])
|
||||
{
|
||||
check_pwg_token();
|
||||
|
||||
delete_orphan_tags();
|
||||
$_SESSION['message_tags'] = l10n('Orphan tags deleted');
|
||||
redirect(get_root_url().'admin.php?page=tags');
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | template init |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->set_filenames(array('tags' => 'tags.tpl'));
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'F_ACTION' => PHPWG_ROOT_PATH.'admin.php?page=tags',
|
||||
'PWG_TOKEN' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | orphan tags |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$warning_tags = "";
|
||||
|
||||
$orphan_tags = get_orphan_tags();
|
||||
|
||||
$orphan_tag_names_array = '[]';
|
||||
$orphan_tag_names = array();
|
||||
foreach ($orphan_tags as $tag)
|
||||
{
|
||||
$orphan_tag_names[] = trigger_change('render_tag_name', $tag['name'], $tag);
|
||||
}
|
||||
|
||||
if (count($orphan_tag_names) > 0)
|
||||
{
|
||||
$warning_tags = sprintf(
|
||||
l10n('You have %d orphan tags %s'),
|
||||
count($orphan_tag_names),
|
||||
'<a
|
||||
class="icon-eye"
|
||||
data-url="'.get_root_url().'admin.php?page=tags&action=delete_orphans&pwg_token='.get_pwg_token().'">'
|
||||
.l10n('Review').'</a>'
|
||||
);
|
||||
|
||||
$orphan_tag_names_array = '["';
|
||||
$orphan_tag_names_array.= implode(
|
||||
'" ,"',
|
||||
array_map(
|
||||
'htmlentities',
|
||||
$orphan_tag_names,
|
||||
array_fill(0 , count($orphan_tag_names) , ENT_QUOTES)
|
||||
)
|
||||
);
|
||||
$orphan_tag_names_array.= '"]';
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'orphan_tag_names_array' => $orphan_tag_names_array,
|
||||
'warning_tags' => $warning_tags,
|
||||
)
|
||||
);
|
||||
|
||||
$message_tags = '';
|
||||
if (isset($_SESSION['message_tags']))
|
||||
{
|
||||
$message_tags = $_SESSION['message_tags'];
|
||||
unset($_SESSION['message_tags']);
|
||||
}
|
||||
$template->assign('message_tags', $message_tags);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | form creation |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$per_page = 100;
|
||||
|
||||
// tag counters
|
||||
$query = '
|
||||
SELECT tag_id, COUNT(image_id) AS counter
|
||||
FROM '.IMAGE_TAG_TABLE.'
|
||||
GROUP BY tag_id';
|
||||
$tag_counters = simple_hash_from_query($query, 'tag_id', 'counter');
|
||||
|
||||
// all tags
|
||||
$query = '
|
||||
SELECT name, id, url_name
|
||||
FROM '.TAGS_TABLE.'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
$all_tags = array();
|
||||
while ($tag = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$raw_name = $tag['name'];
|
||||
$tag['raw_name'] = $raw_name;
|
||||
$tag['name'] = trigger_change('render_tag_name', $raw_name, $tag);
|
||||
$counter = intval(@$tag_counters[ $tag['id'] ]);
|
||||
if ($counter > 0)
|
||||
{
|
||||
$tag['counter'] = intval(@$tag_counters[ $tag['id'] ]);
|
||||
}
|
||||
|
||||
$alt_names = trigger_change('get_tag_alt_names', array(), $raw_name);
|
||||
$alt_names = array_diff( array_unique($alt_names), array($tag['name']) );
|
||||
if (count($alt_names))
|
||||
{
|
||||
$tag['alt_names'] = implode(', ', $alt_names);
|
||||
}
|
||||
$all_tags[] = $tag;
|
||||
}
|
||||
usort($all_tags, 'tag_alpha_compare');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'first_tags' => array_slice($all_tags, 0, $per_page),
|
||||
'data' => $all_tags,
|
||||
'total' => count($all_tags),
|
||||
'per_page' => $per_page,
|
||||
'ADMIN_PAGE_TITLE' => l10n('Tags'),
|
||||
)
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sending html code |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'tags');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
if (empty($_GET['theme']))
|
||||
{
|
||||
die('Invalid theme URL');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/themes.class.php');
|
||||
$themes = new themes();
|
||||
if (!in_array($_GET['theme'], array_keys($themes->fs_themes)))
|
||||
{
|
||||
die('Invalid theme');
|
||||
}
|
||||
|
||||
$filename = PHPWG_THEMES_PATH.$_GET['theme'].'/admin/admin.inc.php';
|
||||
if (is_file($filename))
|
||||
{
|
||||
include_once($filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
die('Missing file '.$filename);
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
|
||||
|
||||
$my_base_url = get_root_url().'admin.php?page=themes';
|
||||
|
||||
if (isset($_GET['tab']))
|
||||
$page['tab'] = $_GET['tab'];
|
||||
else
|
||||
$page['tab'] = 'installed';
|
||||
|
||||
$tabsheet = new tabsheet();
|
||||
$tabsheet->set_id('themes');
|
||||
$tabsheet->select($page['tab']);
|
||||
$tabsheet->assign();
|
||||
|
||||
if ($page['tab'] == 'update') {
|
||||
include(PHPWG_ROOT_PATH.'admin/updates_ext.php');
|
||||
$template->assign('ADMIN_PAGE_TITLE', l10n('Themes'));
|
||||
}
|
||||
else
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'admin/themes_'.$page['tab'].'.php');
|
||||
}
|
||||
?>
|
||||
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 367 B |
|
After Width: | Height: | Size: 965 B |
|
After Width: | Height: | Size: 585 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 443 B |
@@ -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();
|
||||
?>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 87 B |
|
After Width: | Height: | Size: 348 B |
|
After Width: | Height: | Size: 536 B |
|
After Width: | Height: | Size: 555 B |