Changeset 16495


Ignore:
Timestamp:
07/08/12 17:02:01 (7 years ago)
Author:
icy
Message:

Version 2.0.0, advance ACL . Code copied from git/master.

I could not use merging with git svn . Stupidly copy-&-paste ;)

Location:
extensions/Icy_Picture_Modify
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • extensions/Icy_Picture_Modify/CHANGELOG

    r16357 r16495  
     12.0.0 2012-07-09 
     2 
     3  - Advance ACL support in local ZAML file 
     4  - Upload permission can be specified in new ACL 
     5  - Doesn't require any settings from the plugin `community` 
     6 
    171.1.2 2012-07-04 
    28 
    39  - Make plugin compatible with Piwigo 2.3.5 and Piwigo 2.4.1 
    410  - Fix minor bugs. Fix caching issue when updating images. 
     11 
     121.2.0 2012-01-07 
     13 
     14  - Support advanced ACL in local file <ROOT/local/config/icy_acl.php> 
     15    + Allow user to edit images in any set of categories 
     16    + Allow user to (dis)associate image (from)to any categories 
     17    + Allow user to upload images to any categories 
    518 
    6191.1.0 2011-09-02 
  • extensions/Icy_Picture_Modify/README.md

    r16494 r16495  
    1 NAME 
     1# NAME 
    22 
    3   icy_picture_modify -- Allow user to modify their pictures 
     3  `icy_picture_modify` -- Allow user to modify any pictures 
    44 
    5 DESCRIPTION 
     5# DESCRIPTION 
    66 
    7   A piwigo extension that allows users to modify pictures they uploaded. 
    8   This extension just works as the 'picture_modify.php' for administrator. 
     7  A piwigo extension that allows users to edit any set of images. 
     8  This extension just works as the `picture_modify.php` for administrator. 
    99 
    10   The code of this plugin is heavily based on the original source 
    11   'picture_modify.php' of the Piwigo distribution (version 2.2.3.) 
     10  The code of this plugin is based on the original source 
     11  `picture_modify.php` of the Piwigo distribution (version 2.2.3.) 
    1212 
    13 USAGE 
     13  Advanced ACL is supported since version 1.2.0. 
    1414 
    15   1. Install and enable the plugin "community" which allows users to 
    16      upload pictures to some albums. Please configure the plugin before 
    17      you install "icy_picture_modify". 
     15# FEATURES 
    1816 
    19   2. Install and enable this plugin 
     17  Normal users in Piwigo system can delete image or modify image's metadata 
     18  (author, date, tags, description, metada, linking/represented categories). 
     19  They can upload some images to some categories. 
    2020 
    21   3. When users view a picture they uploaded, they will be provided a link 
    22      to modify that picture's information. 
     21  Advanced ACL allows users to work with any set of images / categories. 
    2322 
    24 FEATURES 
     23# USAGE 
    2524 
    26   Users can delete image or modify image's properties (author, date, tags, 
    27   description, metada, associcate/aissociated/represented categories). 
     25  * Install and enable this plugin and the plugin `community`. 
     26  * Create and edit ACL file in `local/config/icy_acl.zml` in your Piwigo 
     27    installation. A sample file can be found in `doc/icy_acl.zml.sample`. 
     28    You don't have to modify any settings for the plugin `community`. 
     29    Moverover, any settings of the plugin `community` will be ignored. 
     30  * If you are using a development of the plugin, please clean up the 
     31    obsolete files (See `OBSOLETE FILES` below.) 
    2832 
    29 KNOWN PROBLEMS 
     33# OBSOLETE FILES 
    3034 
    31   * If an image is replaced by other version (using plugin 'Photo update') 
    32     the author of (new) image will be owned by administrator, not the 
    33     current user. Hence the image won't be editable anymore 
     35  The following files are obsolsete. They need to be ported to new format 
     36  and/or to be removed 
    3437 
     38  * `local/config/icy_acl.php`: 
     39    need to be ported to `local/config/icy_acl.zml`. After your old ACL 
     40    settings are ported to new format, you can safely delete this file; 
     41 
     42  * `_data/icy.log`: 
     43    if you are using `icy_picture_modify` version 2.0.0 or higher, you 
     44    can safely remove this file. 
     45 
     46# KNOWN PROBLEMS 
     47 
     48  * No webUI for ACL editting 
     49  * If an image is replaced by a new version (using plugin `Photo update`) 
     50    the new version is owned by administrator, not the current user. 
     51    Hence the image may not be editable by themself. 
    3552  * This plugin doesn't support all known templates 
    36  
    37   * This plugin may not work smoothly without the plugin 'community' 
    38  
     53  * This plugin may not work smoothly without the plugin `community`. 
    3954  * User can delete an image which is associated to some albums to which 
    4055    the user doesn't have permission to write/access. This is true as the 
    4156    plugin only checks owner of the image. 
    4257 
    43 AUTHOR 
     58# SUPPORT 
    4459 
    45   Anh K. Huỳnh (icy) 
     60  To get support, please create new issue at 
     61    https://github.com/icy/icy_picture_modify/issues 
    4662 
    47 LICENSE 
     63# DEVELOPMENT 
     64 
     65  The plugin requires a webUI for ACL editting. Unfortunately, the author 
     66  isn't good at template system used by Piwigo. Feel free to help us to 
     67  write a webUI :) 
     68 
     69# DONATION 
     70 
     71  If you know what `donation` is and how it works in Open source develoment, 
     72  feel free to donate ;) My Paypal email is `xkyanh@gmail.com`. 
     73 
     74# AUTHOR 
     75 
     76  The author's information 
     77 
     78  * Real name: Anh K. Huỳnh 
     79  * Email: kyanh@viettug.org, xkyanh@gmail.com 
     80  * Nickname on Piwigo's forum: icy 
     81 
     82# LICENSE 
    4883 
    4984  GPL2 
    5085 
    51 HOMGEPAGE 
     86# HOMGEPAGE 
    5287 
    53   At Github.com:  https://github.com/icy/icy_picture_modify 
    54   At Piwigo.com:  http://piwigo.org/ext/extension_view.php?eid=563 
    55   SVN repository: http://piwigo.org/svn/extensions/Icy_Picture_Modify/ 
    56   Forum link:     http://piwigo.org/forum/viewtopic.php?pid=131585#p131585 
     88  * At Github.com:  https://github.com/icy/icy_picture_modify 
     89  * At Piwigo.com:  http://piwigo.org/ext/extension_view.php?eid=563 
     90  * SVN repository: http://piwigo.org/svn/extensions/Icy_Picture_Modify/ 
     91  * Forum link:     http://piwigo.org/forum/viewtopic.php?pid=131585#p131585 
  • extensions/Icy_Picture_Modify/icy_picture_modify.php

    r16355 r16495  
    2525if (!defined('ICY_PICTURE_MODIFY_PATH')) die('Hacking attempt!'); 
    2626 
    27 include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); 
    28 include_once(ICY_PICTURE_MODIFY_PATH.'include/functions_icy_picture_modify.inc.php'); 
    29  
    30 global $template, $conf, $user, $page, $lang, $cache; 
    31  
    32 // <admin.php> 
    33 $page['errors'] = array(); 
    34 $page['infos']  = array(); 
    35 $page['warnings']  = array(); 
    36 // </admin.php> 
    37  
    38 // +-----------------------------------------------------------------------+ 
    39 // |                             check permission                          | 
    40 // +-----------------------------------------------------------------------+ 
    41  
    42 // redirect users to the index page or category page if 'image_id' isn't provided 
    43 if (!isset($_GET['image_id'])) 
    44 { 
    45   if (isset($_GET['cat_id'])) 
    46   { 
    47     redirect_http(get_root_url().'?/category/'.$_GET['cat_id']); 
    48   } 
    49   else 
    50   { 
    51     // FIXME: $_SESSION['page_infos'] = array(l10n('Permission denied')); 
    52     redirect_http(make_index_url()); 
    53   } 
    54 } 
    55  
    56 check_input_parameter('cat_id', $_GET, false, PATTERN_ID); 
    57 check_input_parameter('image_id', $_GET, false, PATTERN_ID); 
    58  
    59 // Simplify redirect to administrator page if current user == admin 
     27require_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); 
     28require_once(ICY_PICTURE_MODIFY_PATH.'include/functions_icy_picture_modify.inc.php'); 
     29 
     30// <ADMIN_ONLY> 
    6031if (is_admin()) 
    6132{ 
    62   if (icy_does_image_exist($_GET['image_id'])) 
     33  if (icy_image_exists($_GET['image_id'])) 
    6334  { 
    6435    $url = get_root_url().'admin.php?page=picture_modify'; 
     
    7041  else 
    7142  { 
     43    // FIXME: language support ^^ 
    7244    bad_request('invalid picture identifier'); 
    7345  } 
    7446} 
    75 elseif (!icy_check_image_owner($_GET['image_id'], $user['id'])) 
     47// </ADMIN_ONLY> 
     48 
     49global $template, $conf, $user, $page, $lang, $cache, $ICY_ACL; 
     50 
     51// <load_from_admin.php> 
     52$page['errors'] = array(); 
     53$page['infos']  = array(); 
     54$page['warnings']  = array(); 
     55// </load_from_admin.php> 
     56 
     57#! icy_log("body from icy_picture_modify.php"); 
     58icy_acl_load_configuration(); 
     59 
     60// +-----------------------------------------------------------------------+ 
     61// |                             check permission                          | 
     62// +-----------------------------------------------------------------------+ 
     63 
     64// <CHECK_IF_IMAGE_ID_IS_VALID> 
     65// redirect users to the index page or category page if 'image_id' isn't provided 
     66if (!isset($_GET['image_id'])) 
     67{ 
     68  if (isset($_GET['cat_id'])) 
     69  { 
     70    redirect_http(get_root_url().'?/category/'.$_GET['cat_id']); 
     71  } 
     72  else 
     73  { 
     74    // FIXME: $_SESSION['page_infos'] = array(l10n('Permission denied')); 
     75    redirect_http(make_index_url()); 
     76  } 
     77} 
     78// </CHECK_IF_IMAGE_ID_IS_VALID> 
     79 
     80// FIXME: check and then !? 
     81check_input_parameter('cat_id', $_GET, false, PATTERN_ID); 
     82check_input_parameter('image_id', $_GET, false, PATTERN_ID); 
     83 
     84// Return if the image isn't editable 
     85if (!icy_acl("edit_image_of", $_GET['image_id'], icy_get_user_owner_of_image($_GET['image_id']))) 
    7686{ 
    7787  $url = make_picture_url( 
     
    8696 
    8797// Update the page sessions 
     98// FIXME: why? 
    8899if (isset($_SESSION['page_infos'])) 
    89100{ 
     
    93104 
    94105// <find writable categories> 
    95  
    96 // * Purpose: Find all categories that are reachable for the current user. 
    97 // * FIXME:   This query will include all readable categories, included 
    98 //            the ones user can't write to them. 
    99  
    100106$my_categories = array(); 
    101 $my_permissions = null; 
    102 $has_plugin_community = false; 
    103  
    104 // <community support> 
    105 if (is_file(PHPWG_PLUGINS_PATH.'community/include/functions_community.inc.php')) 
    106 { 
    107   include_once(PHPWG_PLUGINS_PATH.'community/include/functions_community.inc.php'); 
    108   $has_plugin_community = true; 
    109  
    110   $user_permissions = community_get_user_permissions($user['id']); 
    111   $my_categories = $user_permissions['upload_categories']; 
    112 } 
    113 // </community support> 
    114  
    115 if (($has_plugin_community == false) or $user_permissions['create_whole_gallery']) 
    116 { 
    117   $query = ' 
    118   SELECT category_id 
    119     FROM '.IMAGE_CATEGORY_TABLE.' 
    120   ;'; 
    121  
    122   // list of categories to which the user can read 
    123   $my_categories = array_diff( 
    124     array_from_query($query, 'category_id'), 
    125     explode(',',calculate_permissions($user['id'], $user['status']))); 
    126 } 
    127 // </find writable categories> 
     107// FIXME: delete this line ^^ 
     108$my_categories = array_from_query('SELECT category_id FROM ' 
     109                        .IMAGE_CATEGORY_TABLE.';', 'category_id'); 
    128110 
    129111// +-----------------------------------------------------------------------+ 
     
    131113// +-----------------------------------------------------------------------+ 
    132114 
    133 if (isset($_GET['delete'])) 
     115// ACTION => :delete_image 
     116 
     117if (isset($_GET['delete']) 
     118      and icy_acl("delete_image_of", 
     119            $_GET['image_id'], 
     120            icy_get_user_owner_of_image($_GET['image_id']))) 
    134121{ 
    135122  check_pwg_token(); 
     
    183170// +-----------------------------------------------------------------------+ 
    184171 
    185 if (isset($_GET['sync_metadata'])) 
     172// ACTION => synchronize_image_metadata 
     173// This includes other sub-actions and other permissions 
     174//  (tag update, timestamp updated, ...) 
     175 
     176if (version_compare(PHPWG_VERSION, '2.4.0', '<') 
     177    and isset($_GET['sync_metadata'])) 
    186178{ 
    187179  $query = ' 
     
    246238  } 
    247239 
     240  // FIXME: why mass_updates here ? Used with a simple array? 
    248241  mass_updates( 
    249242    IMAGES_TABLE, 
     
    271264// associate the element to other categories than its storage category 
    272265// 
     266 
     267// SUB-ACTION => associate_image_to_gallery 
     268 
    273269if (isset($_POST['associate']) 
    274     and ($has_plugin_community == true) 
    275270    and isset($_POST['cat_dissociated']) 
    276     and count($_POST['cat_dissociated']) > 0 
     271    and (count($_POST['cat_dissociated']) > 0) 
    277272  ) 
    278273{ 
    279   associate_images_to_categories( 
    280     array($_GET['image_id']), 
    281     array_intersect($_POST['cat_dissociated'], $my_categories) 
    282     ); 
     274  $_categories = array_intersect($_POST['cat_dissociated'], 
     275                    icy_acl_get_categories("associate_image_to")); 
     276  //! $_categories = array_filter($_categories, 
     277  //!    create_function('$item', 'return icy_acl("associate_image_to", $item);')); 
     278 
     279  associate_images_to_categories(array($_GET['image_id']), $_categories); 
    283280  invalidate_user_cache(); 
    284281} 
    285282 
     283// SUB-ACTION => dissociate_image_from_gallery 
    286284 
    287285// dissociate the element from categories (but not from its storage category) 
    288286if (isset($_POST['dissociate']) 
    289     and ($has_plugin_community == true) 
    290287    and isset($_POST['cat_associated']) 
    291288    and count($_POST['cat_associated']) > 0 
    292289  ) 
    293290{ 
    294   $arr_dissociate = array_intersect($_POST['cat_associated'], $my_categories); 
     291 
     292  $_categories = array_intersect($_POST['cat_associated'], 
     293                    icy_acl_get_categories("associate_image_to")); 
     294  //! $_categories = array_filter($_categories, 
     295  //!    create_function('$item', 'return icy_acl("associate_image_to", $item);')); 
     296 
    295297  $query = ' 
    296298DELETE FROM '.IMAGE_CATEGORY_TABLE.' 
    297299  WHERE image_id = '.$_GET['image_id'].' 
    298     AND category_id IN ('.implode(',', $arr_dissociate).') 
     300    AND category_id IN (0'.join(',', $_categories).') 
    299301'; 
     302 
    300303  pwg_query($query); 
    301  
    302   update_category($arr_dissociate); 
     304  update_category($_categories); 
    303305  invalidate_user_cache(); 
    304306} 
     
    308310// +-----------------------------------------------------------------------+ 
    309311 
    310 // select the element to represent the given categories 
     312// SUB-ACTION => select the element to represent the given categories 
     313// FIXME: select or elect? 
     314 
    311315if (isset($_POST['elect']) 
    312     and ($has_plugin_community == true) 
    313316    and isset($_POST['cat_dismissed']) 
    314317    and count($_POST['cat_dismissed']) > 0 
     
    316319{ 
    317320  $datas = array(); 
    318   $arr_dimissed = array_intersect($_POST['cat_dismissed'], $my_categories); 
     321  $arr_dimissed = array_intersect($_POST['cat_dismissed'], 
     322                        icy_acl_get_categories("present_image_to")); 
     323 
    319324  if (count($arr_dimissed) > 0) 
    320325  { 
     
    332337} 
    333338 
    334 // dismiss the element as representant of the given categories 
     339// SUB-ACTION => dismiss the element as representant of the given categories 
     340 
    335341if (isset($_POST['dismiss']) 
    336     and ($has_plugin_community == true) 
    337342    and isset($_POST['cat_elected']) 
    338343    and count($_POST['cat_elected']) > 0 
    339344  ) 
    340345{ 
    341   $arr_dismiss = array_intersect($_POST['cat_elected'], $my_categories); 
     346  $arr_dismiss = array_intersect($_POST['cat_elected'], 
     347                        icy_acl_get_categories("present_image_to")); 
    342348  if (count($arr_dismiss) > 0) 
    343349  { 
     
    350356// |                             tagging support                           | 
    351357// +-----------------------------------------------------------------------+ 
     358 
     359// FIXME: tag is always updatable? 
    352360 
    353361if (version_compare(PHPWG_VERSION, '2.2.5', '<')) { 
     
    410418    'tag_selection' => $tag_selection, 
    411419    'tags' => $tags, 
    412     'U_SYNC' => $admin_url_start.'&amp;sync_metadata=1', 
    413     'U_DELETE' => $admin_url_start.'&amp;delete=1&amp;pwg_token='.get_pwg_token(), 
    414420 
    415421    'PATH'=>$row['path'], 
     
    436442      htmlspecialchars( isset($_POST['description']) ? 
    437443        stripslashes($_POST['description']) : @$row['comment'] ), 
    438  
    439     'F_ACTION' => 
    440         get_root_url() # .'index.php?/icy_picture_modify' 
    441         .get_query_string_diff(array('sync_metadata')) 
    442444    ) 
    443445  ); 
     446 
     447if (version_compare(PHPWG_VERSION, '2.4.0', '<')) { 
     448  $template->assign( 
     449    array( 
     450      'U_SYNC' => $admin_url_start.'&amp;sync_metadata=1', 
     451      'F_ACTION' => get_root_url() . get_query_string_diff(array('sync_metadata')) 
     452    ) 
     453  ); 
     454} 
     455 
     456if (icy_image_deletable($_GET['image_id'])) { 
     457  $template->assign( 
     458    'U_DELETE', $admin_url_start.'&amp;delete=1&amp;pwg_token='.get_pwg_token() 
     459  ); 
     460} 
    444461 
    445462if (array_key_exists('has_high', $row) and $row['has_high'] == 'true') 
     
    577594} 
    578595 
    579 // associate to another category ? 
     596$_categories = icy_acl_get_categories("associate_image_to"); 
     597// Select list of categories this image is associcated to 
    580598$query = ' 
    581599SELECT id,name,uppercats,global_rank 
     
    583601    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = category_id 
    584602  WHERE image_id = '.$_GET['image_id'] . ' 
    585     AND id IN ('. join(",", $my_categories).')'; 
    586 // if the image belongs to a physical storage, 
    587 // we simply ignore that storage album 
     603    AND id IN (0'.join(",",$_categories).')'; 
     604// FIMXE: if the image belongs to a physical storage, 
     605// FIXME: we simply ignore that storage album 
    588606if (isset($storage_category_id)) 
    589607{ 
     
    605623  array_push($associateds, $row['id']); 
    606624} 
     625  // FIXME: Also display some forbidden presentations 
    607626$query = ' 
    608627SELECT id,name,uppercats,global_rank 
    609628  FROM '.CATEGORIES_TABLE.' 
    610629  WHERE id NOT IN ('.implode(',', $associateds).') 
    611   AND id IN ('. join(",", $my_categories).') 
     630  AND id IN (0'.join(",", $_categories).') 
    612631;'; 
    613632display_select_cat_wrapper($query, array(), 'dissociated_options'); 
    614633 
    615634// display list of categories for representing 
     635$_categories = icy_acl_get_categories("present_image_to"); 
    616636$query = ' 
    617637SELECT id,name,uppercats,global_rank 
    618638  FROM '.CATEGORIES_TABLE.' 
    619639  WHERE representative_picture_id = '.$_GET['image_id'].' 
    620     AND id IN ('. join(",", $my_categories).') 
     640    AND id IN (0'. join(",", $_categories).') 
    621641;'; 
    622642display_select_cat_wrapper($query, array(), 'elected_options'); 
    623  
    624643$query = ' 
    625644SELECT id,name,uppercats,global_rank 
    626645  FROM '.CATEGORIES_TABLE.' 
    627   WHERE id IN ('. join(",", $my_categories).') 
     646  WHERE id IN (0'. join(",", $_categories).') 
    628647    AND (representative_picture_id != '.$_GET['image_id'].' 
    629648    OR representative_picture_id IS NULL) 
  • extensions/Icy_Picture_Modify/include/functions_icy_picture_modify.inc.php

    r11637 r16495  
    2929 * 
    3030*/ 
    31 function icy_check_image_owner($image_id, $user_id = 0) 
     31function icy_check_image_owner($image_id) 
    3232{ 
    33   if (!preg_match(PATTERN_ID, $image_id)) 
    34   { 
    35     bad_request('invalid picture identifier'); 
    36   } 
    37   if (!preg_match(PATTERN_ID, $user_id)) 
    38   { 
    39     bad_request('invalid category identifier'); 
    40   } 
    41  
    42   $query = ' 
    43 SELECT COUNT(id) 
    44   FROM '.IMAGES_TABLE.' 
    45   WHERE id = '.$image_id.' 
    46   AND added_by = '.$user_id.' 
    47 ;'; 
    48  
    49   list($count) = pwg_db_fetch_row(pwg_query($query)); 
    50  
    51   return ($count > 0 ? true: false); 
     33  global $user; 
     34  return $user['id'] == icy_get_user_owner_of_image($image_id); 
    5235} 
    5336 
     
    5841 * 
    5942*/ 
    60 function icy_does_image_exist($image_id) 
     43function icy_image_exists($image_id) 
    6144{ 
    6245  if (!preg_match(PATTERN_ID, $image_id)) 
     
    7255  return ($count > 0 ? true: false); 
    7356} 
     57 
     58/* 
     59 * Check if an image is editable by current user 
     60 * @icy_acl   access rules (provided by icy module) 
     61 * @image_id  identity of the image 
     62 * @return    boolean value 
     63 * @author    icy 
     64 */ 
     65function icy_image_editable($image_id) { 
     66  return icy_acl("edit_image_of", $image_id, icy_get_user_owner_of_image($image_id)); 
     67} 
     68 
     69function icy_image_deletable($image_id) { 
     70  return icy_acl("delete_image_of", $image_id, icy_get_user_owner_of_image($image_id)); 
     71} 
     72 
     73 
     74/* 
     75 * Return list of visible/uploadable categories 
     76 * @author  icy 
     77 */ 
     78function icy_acl_get_data($symbol) { 
     79  global $user, $ICY_ACL; 
     80 
     81  // Load ACL setting for this user 
     82  $this_user = $user['username']; 
     83  $my_acl = $ICY_ACL['default']; 
     84  if (array_key_exists($this_user, $ICY_ACL)) { 
     85    $my_acl = array_replace($my_acl, $ICY_ACL[$this_user]); 
     86  } 
     87 
     88  // Load ACL setting for the symbol 
     89  if (!array_key_exists($symbol, $my_acl)) { 
     90    return NULL; 
     91  } 
     92 
     93  return $my_acl[$symbol]; 
     94} 
     95 
     96/* 
     97 * 
     98 * visible: upload, assosiate,... 
     99 * @symbol    must be ended by "_to" or "_from" 
     100 */ 
     101function icy_acl_get_categories($symbol) { 
     102  global $user, $conf; 
     103 
     104  $all_categories = array(); 
     105  $symbol_categories = array(); 
     106  $symbol_settings = NULL; 
     107 
     108  // It's always EMPTY array for any kind of guests 
     109  if ($user['id'] == $conf['guest_id']) { 
     110    return $symbol_categories; 
     111  } 
     112 
     113  // check if $symbol is valid 
     114  if (!preg_match("/_(to|from)$/", $symbol)) { 
     115    return $symbol_categories; 
     116  } 
     117 
     118  $symbol_settings = icy_acl_get_data($symbol); 
     119  if (!$symbol_settings) { 
     120    return $symbol_categories; 
     121  } 
     122 
     123  // all known categories in the system 
     124  $query = 'SELECT id FROM '.CATEGORIES_TABLE.';'; 
     125  $all_categories = array_unique(array_from_query($query, 'id')); 
     126  $forbidden_categories = explode(',',calculate_permissions($user['id'], $user['status'])); 
     127 
     128  // ICY_ACL allows user to access all categories. In this case, 
     129  // the plugin 'community' plays an empty role (we just supress it) 
     130  if (icy_acl_symbol_data_wide_open($symbol_settings)) { 
     131    $symbol_categories = $all_categories; 
     132  } 
     133  elseif (is_array($symbol_settings)) { 
     134    $symbol_categories = array_values(array_intersect($symbol_settings, $all_categories)); 
     135  } 
     136  else { 
     137    // not wide-open, not an-array. So waht!? 
     138    $symbol_settings = array(); 
     139  } 
     140 
     141  // Make sure categories are in our sytem 
     142  // remove all forbidden categories from the list 
     143  if (in_array('sub', icy_acl_get_data($symbol))) { 
     144    // FIXME: (get_subcat_ids) requires a 0-based array 
     145    // FIXME: + array(0) is really a trick :) In Piwigo 2.4, (get_subcat_ids) 
     146    // FIXME: will generate NOTICE (SQL syntax error) if $symbol_categories is empty. 
     147    $symbol_categories = array_merge($symbol_categories, get_subcat_ids($symbol_categories + array(0))); 
     148  } 
     149  $symbol_categories = array_diff($symbol_categories, $forbidden_categories); 
     150  return array_values($symbol_categories); 
     151} 
     152/* 
     153 * FIXME: Test if current user is logged in 
     154 * FIXME: $guestowner must be provided explicitly 
     155 * 
     156 * Check if the current user has permission to do something 
     157 * @symbol     Action to be checked 
     158 * @guestdata  Object of the action 
     159 * @guestowner Owner of @guestdata 
     160 * 
     161 * There are two cases of @symbol: 
     162 * - _from/_to: action on an category 
     163 * - _of      : action on the author 
     164 * - others   : boolean flag 
     165 * 
     166 * There are three cases of symbol data 
     167 * - Array of categories (' identities)    [_from/_to] 
     168 *    $guestowner is simply ignored 
     169 * - Array of usernames (list of authors)  [_of] 
     170 *    $guestowner must be specified 
     171 * - Others: {"any", "owner", TRUE, FALSE} [others] 
     172 */ 
     173 function icy_acl($symbol, $guestdata = NULL, $guestowner = NULL) { 
     174  global $user, $ICY_ACL, $conf; 
     175 
     176  // Load ACL setting for this user 
     177  $this_user = $user['id']; 
     178 
     179  if ($user['id'] == $conf['guest_id']) { 
     180    return FALSE; 
     181  } 
     182  elseif (is_admin()) { 
     183    return TRUE; 
     184  } 
     185 
     186  $symbol_settings = icy_acl_get_data($symbol); 
     187 
     188 
     189  if (! preg_match("/_(to|from|of)$/", $symbol)) { 
     190    return is_bool($symbol_settings) ? $symbol_settings: FALSE; 
     191  } 
     192 
     193  if (! is_array($symbol_settings) ) { 
     194    return FALSE; 
     195  } elseif (icy_acl_symbol_data_wide_open($symbol_settings)) { 
     196    return TRUE; 
     197  } 
     198 
     199  if (preg_match("/_(to|from)$/", $symbol)) { 
     200    return in_array($guestdata, $symbol_settings); 
     201  } 
     202  elseif (preg_match("/_of$/", $symbol)) { 
     203    $guestowner = icy_get_username_of($guestowner); 
     204    // Replace 'owner' by the $guestowner. For example 
     205    //  array('owner','ruby', 12) => array($guestowner, 'ruby', 12) 
     206    array_walk($symbol_settings, 
     207     create_function('&$val, $key', 
     208       'if ($val == "owner") {$val = "'.$user['username'].'";}')); 
     209    return in_array($guestowner, $symbol_settings); 
     210  } 
     211} 
     212 
     213function icy_acl_symbol_data_wide_open($symbol_data) { 
     214  return (is_array($symbol_data) and in_array("any", $symbol_data)); 
     215} 
     216 
     217/* 
     218 * Write some logs for debugging 
     219 * @notes     Data will be written to STDERRR (default) 
     220 *            or to file `<ROOT>/_data/icy.log` 
     221 * @author    icy 
     222 */ 
     223function icy_log($st, $stderr = FALSE) { 
     224  if ($stderr === TRUE) { 
     225    $_f_log = "php://stderr"; 
     226  } 
     227  else { 
     228    $_f_log = PHPWG_ROOT_PATH.'_data/icy.log'; 
     229  } 
     230 
     231  $_f_handle = fopen($_f_log, 'a'); 
     232  if ($_f_handle) { 
     233    $new_line = "\n"; 
     234    fwrite($_f_handle, "piwigo/icy_picture_modify: $st". $new_line ); 
     235    if ($stderr !== TRUE) { 
     236      fclose($_f_handle); 
     237    } 
     238  } 
     239} 
     240 
     241/* 
     242 * Get UserId from their UserName 
     243 * @user_name   username as string 
     244 * @author      icy 
     245 */ 
     246function icy_get_user_id_from_name($user_name) { 
     247  $user_name = pwg_db_real_escape_string($user_name); 
     248 
     249  $query = ' 
     250SELECT id 
     251  FROM '.USERS_TABLE.' 
     252  WHERE username = "'.$user_name.'" 
     253  LIMIT 1 
     254;'; 
     255 
     256  list($user_id) = pwg_db_fetch_row(pwg_query($query)); 
     257 
     258  // FIXME: Is this the best way? 
     259  if ($user_id == NULL) $user_id = 0; 
     260 
     261  #! icy_log("icy_get_user_id_from_name: map userid <= username: $user_name <= $user_id"); 
     262  return $user_id; 
     263} 
     264 
     265/* 
     266 * Rerturn the owner id of an image 
     267 * @author    icy 
     268 * @image_id  identity of the image 
     269 */ 
     270function icy_get_user_owner_of_image($image_id) { 
     271  // FIXME: Clean this up!!! 
     272  if (!preg_match(PATTERN_ID, $image_id)) 
     273    bad_request('invalid picture identifier'); 
     274 
     275  $query = ' 
     276SELECT added_by 
     277  FROM '.IMAGES_TABLE.' 
     278  WHERE id = '.$image_id.' 
     279  LIMIT 1 
     280;'; 
     281 
     282  list($owner) = pwg_db_fetch_row(pwg_query($query)); 
     283  #! icy_log("icy_get_user_owner_of_image: image_id, added_by = $image_id, $owner"); 
     284  return $owner ? $owner : 0; 
     285} 
     286 
     287/* 
     288 * Return the username from user_id 
     289 */ 
     290function icy_get_username_of($user_id) { 
     291  if (!preg_match(PATTERN_ID, $user_id)) 
     292    bad_request('invalid user identifier'); 
     293 
     294  $query = ' 
     295SELECT username 
     296  FROM '.USERS_TABLE.' 
     297  WHERE id = '.$user_id.' 
     298  LIMIT 1 
     299;'; 
     300 
     301  list($username) = pwg_db_fetch_row(pwg_query($query)); 
     302  #! icy_log("icy_get_username_of: user_id, user_name = $user_id, $username"); 
     303  return $username; 
     304} 
     305 
     306/* 
     307 * Check if a plugin is enabled 
     308 * @plugin_name   name of the plugin 
     309 * @author        icy 
     310 */ 
     311function icy_plugin_enabled($plugin_name) { 
     312  $return = false; 
     313 
     314  $query = ' 
     315SELECT count(id) 
     316  FROM '.PLUGINS_TABLE.' 
     317  WHERE id = "'.pwg_db_real_escape_string($plugin_name).'" 
     318  AND state="active" 
     319  LIMIT 1 
     320;'; 
     321 
     322  list($count) = pwg_db_fetch_row(pwg_query($query)); 
     323  $return = ($count == 1 ? true : false); 
     324 
     325  // we need the file ^^ 
     326  if ($plugin_name == "community") 
     327    $return = $return 
     328                and is_file(PHPWG_PLUGINS_PATH 
     329                  .'community/include/functions_community.inc.php'); 
     330 
     331  return $return; 
     332} 
     333 
     334/* 
     335 * Load ICY_ACL configuration from files 
     336 * @author   icy 
     337 */ 
     338function icy_acl_load_configuration($force = FALSE) { 
     339  global $ICY_ACL; 
     340  $conf_path = PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'config/icy_acl.zml'; 
     341 
     342  if (($force == FALSE) 
     343      and isset($ICY_ACL['default']) 
     344      and isset($_SESSION['icy_picture_modify_acl_mtime']) 
     345      and ($_SESSION['icy_picture_modify_acl_mtime'] == filemtime($conf_path))) { 
     346    #! icy_log("icy_acl_load_configuration: configuration is up-to-date"); 
     347    return FALSE; 
     348  } 
     349 
     350  $ICY_ACL = icy_zml_parser(<<<EOF 
     351default: 
     352  edit_image_of: owner 
     353  delete_image_of: 
     354  upload_image_to: sub 
     355  moderate_image: no 
     356  create_gallery_to: sub 
     357  associate_image_to: 
     358  present_image_to: sub 
     359EOF 
     360); 
     361 
     362  if (file_exists($conf_path)) { 
     363    #! icy_log("icy_acl_load_configuration: now loading ACL from $conf_path"); 
     364    $ICY_ACL = array_replace($ICY_ACL, icy_zml_parser(file($conf_path))); 
     365    $_SESSION['icy_picture_modify_acl_mtime'] = filemtime($conf_path); 
     366  } 
     367 
     368  return TRUE; 
     369} 
     370 
     371/* 
     372 * Return array of variable from a `.zml` array  / string 
     373 * Syntax of the `.zml` file can be found in `doc/zaml.md` 
     374 * @author icy 
     375 */ 
     376function icy_zml_parser($data) { 
     377  $acl = array(); 
     378  $author = 'default'; 
     379  $acl[$author] = array(); 
     380 
     381  if (is_string($data)) { 
     382    $data = preg_split("/[\r\n]/", $data); 
     383  } 
     384 
     385  foreach($data as $line) { 
     386    # AUTHOR: 
     387    if (preg_match('/^([^[:space:]:]+):$/', $line, $gs)) { 
     388      $author = trim($gs[1]); 
     389      if (! array_key_exists($author, $acl)) { 
     390        $acl[$author] = array(); 
     391      } 
     392      continue; 
     393    } 
     394 
     395    # AUTHOR: @REFERENCE 
     396    if (preg_match('/^([^[:space:]:]+):[[:space:]]+@([^[:space:]:]+)$/', $line, $gs)) { 
     397      $ref_author = trim($gs[2]); 
     398      if (!array_key_exists($ref_author, $acl)) { 
     399        continue; 
     400      } 
     401      $author = trim($gs[1]); 
     402      if (! array_key_exists($author, $acl)) { 
     403        $acl[$author] = array(); 
     404      } 
     405      $acl[$author] = array_replace($acl[$ref_author], $acl[$author]); 
     406    } 
     407 
     408    # <two spaces> KEY: [VALUE] 
     409    if (preg_match('/  ([^:]+):(.*)$/', $line, $gs)) { 
     410      $key = $gs[1]; 
     411      $val = trim($gs[2]); 
     412      if (in_array($val, array("","false","no"))) { 
     413        $val = FALSE; 
     414      } 
     415      elseif (in_array($val, array("yes", "true"))) { 
     416        $val = TRUE; 
     417      } 
     418      else { 
     419        $val = array_unique(preg_split("/[[:space:],:;]+/", $val)); 
     420      } 
     421      $acl[$author][$key] = $val; 
     422    } 
     423 
     424    # Other line is ignored :) 
     425  } 
     426  return $acl; 
     427} 
     428 
     429/* 
     430 * Overwrite the ACl setings from community plugin 
     431 * @author: icy 
     432 */ 
     433function icy_acl_fix_community($force = FALSE) { 
     434  global $user, $_SESSION; 
     435 
     436  if (!icy_plugin_enabled("community")) { 
     437    return TRUE; 
     438  } 
     439 
     440  require_once(PHPWG_PLUGINS_PATH.'community/include/functions_community.inc.php'); 
     441 
     442  # <community_support> 
     443  $cache_key = community_get_cache_key(); 
     444  if (!isset($cache_key))  { 
     445    $cache_key = community_update_cache_key(); 
     446  } 
     447 
     448  if (($force == FALSE) 
     449      and isset($_SESSION['community_user_permissions']) 
     450      and isset($_SESSION['community_user_permissions']['icy_acl_fixed'])) { 
     451    #! icy_log("icy_fix_community_acl: the fix is up-to-date " . print_r($_SESSION['community_user_permissions'], true)); 
     452    return TRUE; 
     453  } 
     454 
     455  # icy_log("WARNING: icy_fix_community_acl: the fix is out-of-date. will fix it again"); 
     456  # </community_support> 
     457 
     458  $return = array( 
     459    'create_categories' => array(), 
     460    'upload_categories' => array(), 
     461    'permission_ids' => array(), 
     462    ); 
     463 
     464  $return['upload_whole_gallery'] = icy_acl_symbol_data_wide_open(icy_acl_get_data("upload_image_to")); 
     465  $return['create_whole_gallery'] = icy_acl_symbol_data_wide_open(icy_acl_get_data("create_gallery_to")); 
     466  $return['upload_categories'] = icy_acl_get_categories("upload_image_to"); 
     467  $return['create_categories'] = icy_acl_get_categories("create_gallery_to"); 
     468  $return['permission_ids'] = array(); 
     469  $return['icy_acl_fixed'] = 1; 
     470 
     471  $_SESSION['community_user_permissions'] = $return; 
     472  $_SESSION['community_cache_key'] = $cache_key; 
     473  $_SESSION['community_user_id'] = $user['id']; 
     474} 
     475 
     476 
     477if (!function_exists('array_replace')) { 
     478  function array_replace() { 
     479    $array=array(); 
     480    $n=func_num_args(); 
     481    while ($n-- >0) $array+=func_get_arg($n); 
     482    return $array; 
     483  } 
     484} 
    74485?> 
  • extensions/Icy_Picture_Modify/index.php

    r11610 r16495  
    44// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net | 
    55// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net | 
    6 // +-----------------------------------------------------------------------+ 
    7 // | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $ 
    8 // | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $ 
    9 // | last modifier : $Author: rub $ 
    10 // | revision      : $Revision: 1912 $ 
    116// +-----------------------------------------------------------------------+ 
    127// | This program is free software; you can redistribute it and/or modify  | 
  • extensions/Icy_Picture_Modify/main.inc.php

    r16356 r16495  
    22/* 
    33Plugin Name: Icy Modify Picture 
    4 Version: 1.1.2 
     4Version: 2.0.0 
    55Description: Allow users to modify pictures they uploaded 
    66Plugin URI: http://piwigo.org/ext/extension_view.php?eid=563 
     
    1414} 
    1515 
    16 # Should be ./plugins/icy_picture_modify/ 
    1716define('ICY_PICTURE_MODIFY_PATH' , PHPWG_PLUGINS_PATH.basename(dirname(__FILE__)).'/'); 
    18 include_once(ICY_PICTURE_MODIFY_PATH.'include/functions_icy_picture_modify.inc.php'); 
     17require_once(ICY_PICTURE_MODIFY_PATH.'include/functions_icy_picture_modify.inc.php'); 
    1918 
    20 # Hooks declaration 
     19# Variable declarations ################################################ 
     20 
     21global $ICY_ACL; 
     22 
     23# Hooks declarations ################################################### 
    2124 
    2225add_event_handler('loc_end_section_init', 'icy_picture_modify_section_init'); 
    23 add_event_handler('loc_end_index', 'icy_picture_modify_index'); 
     26remove_event_handler('loc_end_index', 'community_index'); 
     27add_event_handler('loc_end_index', 'icy_picture_modify_index', 40); 
     28 
    2429add_event_handler('loc_begin_picture', 'icy_picture_modify_loc_begin_picture'); 
     30add_event_handler('init','icy_picture_modify_fix_community_acl', 40); 
     31# add_event_handler('login_success', ); 
    2532 
    26 # Hooks definitions 
     33add_event_handler('blockmanager_apply', 'icy_picture_modify_fix_community_acl', 40); 
     34add_event_handler('ws_invoke_allowed', 'icy_picture_modify_fix_community_acl', 40); 
     35add_event_handler('ws_add_methods', 'icy_picture_modify_fix_community_acl', 40); 
     36add_event_handler('community_ws_categories_getList', 'icy_picture_modify_fix_community_acl', 40); 
     37add_event_handler('sendResponse', 'icy_picture_modify_fix_community_acl', 40); 
     38 
     39# Hooks definitions #################################################### 
     40 
     41function icy_picture_modify_fix_community_acl() 
     42{ 
     43  icy_acl_fix_community(icy_acl_load_configuration()); 
     44} 
    2745 
    2846function icy_picture_modify_section_init() 
     
    4058  global $page; 
    4159 
    42   if (isset($page['section']) and $page['section'] == 'icy_picture_modify') 
     60  if (! isset($page['section'])) { 
     61    return TRUE; 
     62  } 
     63 
     64  if ($page['section'] == 'icy_picture_modify') 
    4365  { 
    4466    include(ICY_PICTURE_MODIFY_PATH.'icy_picture_modify.php'); 
     67  } 
     68  elseif ($page['section'] == 'add_photos') { 
     69    icy_picture_modify_fix_community_acl(TRUE); 
     70    include(ICY_PICTURE_MODIFY_PATH.'add_photos.php'); 
    4571  } 
    4672} 
     
    5177{ 
    5278  global $conf, $template, $page, $user; 
    53   if ((!is_admin()) and icy_check_image_owner($page['image_id'], $user['id'])) 
     79 
     80  icy_acl_load_configuration(); 
     81 
     82  if (icy_image_editable($page['image_id'])) 
    5483  { 
    5584    $url_admin = 
  • extensions/Icy_Picture_Modify/template/icy_picture_modify.tpl

    r11934 r16495  
    4747  {/if} 
    4848  {if !url_is_remote($PATH)} 
     49  {if isset($U_SYNC) } 
    4950  <li><a href="{$U_SYNC}" title="{'synchronize'|@translate}"><img src="{$ICY_PICTURE_MODIFY_PATH}/template/icon/sync_metadata.png" class="button" alt="{'synchronize'|@translate}"></a></li> 
    50  
     51  {/if} 
     52  {if isset($U_IMAGE_DELETABLE) } 
    5153  <li><a href="{$U_DELETE}" title="{'delete photo'|@translate}"><img src="{$ICY_PICTURE_MODIFY_PATH}/template/icon/category_delete.png" class="button" alt="{'delete photo'|@translate}" onclick="return confirm('{'Are you sure?'|@translate|@escape:javascript}');"></a></li> 
     54  {/if} 
    5255  {/if} 
    5356</ul> 
Note: See TracChangeset for help on using the changeset viewer.