source: extensions/community/main.inc.php @ 23960

Last change on this file since 23960 was 23960, checked in by plg, 7 years ago

ability to set any album as a user album

File size: 18.5 KB
Line 
1<?php
2/*
3Plugin Name: Community
4Version: auto
5Description: Non admin users can add photos
6Plugin URI: http://piwigo.org/ext/extension_view.php?eid=303
7Author: plg
8Author URI: http://piwigo.wordpress.com
9*/
10
11if (!defined('PHPWG_ROOT_PATH'))
12{
13  die('Hacking attempt!');
14}
15
16global $prefixeTable;
17
18// +-----------------------------------------------------------------------+
19// | Define plugin constants                                               |
20// +-----------------------------------------------------------------------+
21
22defined('COMMUNITY_ID') or define('COMMUNITY_ID', basename(dirname(__FILE__)));
23define('COMMUNITY_PATH' , PHPWG_PLUGINS_PATH.basename(dirname(__FILE__)).'/');
24define('COMMUNITY_PERMISSIONS_TABLE', $prefixeTable.'community_permissions');
25define('COMMUNITY_PENDINGS_TABLE', $prefixeTable.'community_pendings');
26define('COMMUNITY_VERSION', 'auto');
27
28include_once(COMMUNITY_PATH.'include/functions_community.inc.php');
29
30// init the plugin
31add_event_handler('init', 'community_init');
32/**
33 * plugin initialization
34 *   - check for upgrades
35 *   - unserialize configuration
36 *   - load language
37 */
38function community_init()
39{
40  global $conf, $user, $pwg_loaded_plugins;
41
42  // apply upgrade if needed
43  if (
44    COMMUNITY_VERSION == 'auto' or
45    $pwg_loaded_plugins[COMMUNITY_ID]['version'] == 'auto' or
46    version_compare($pwg_loaded_plugins[COMMUNITY_ID]['version'], COMMUNITY_VERSION, '<')
47  )
48  {
49    // call install function
50    include_once(COMMUNITY_PATH.'include/install.inc.php');
51    community_install();
52
53    // update plugin version in database
54    if ( $pwg_loaded_plugins[COMMUNITY_ID]['version'] != 'auto' and COMMUNITY_VERSION != 'auto' )
55    {
56      $query = '
57UPDATE '. PLUGINS_TABLE .'
58SET version = "'. COMMUNITY_VERSION .'"
59WHERE id = "'. COMMUNITY_ID .'"';
60      pwg_query($query);
61
62      $pwg_loaded_plugins[COMMUNITY_ID]['version'] = COMMUNITY_VERSION;
63    }
64  }
65
66  // prepare plugin configuration
67  $conf['community'] = unserialize($conf['community']);
68
69  // TODO: generate permissions in $user['community_permissions'] if ws.php
70  // + remove all calls of community_get_user_permissions related to webservices
71  if (!defined('IN_ADMIN') or !IN_ADMIN)
72  {
73    $user['community_permissions'] = community_get_user_permissions($user['id']);
74  }
75}
76
77/* Plugin admin */
78add_event_handler('get_admin_plugin_menu_links', 'community_admin_menu');
79function community_admin_menu($menu)
80{
81  global $page;
82 
83  $query = '
84SELECT
85    COUNT(*)
86  FROM '.COMMUNITY_PENDINGS_TABLE.'
87  WHERE state = \'moderation_pending\'
88;';
89  $result = pwg_query($query);
90  list($page['community_nb_pendings']) = pwg_db_fetch_row($result);
91
92  $name = 'Community';
93  if ($page['community_nb_pendings'] > 0)
94  {
95    $style = 'background-color:#666;';
96    $style.= 'color:white;';
97    $style.= 'padding:1px 5px;';
98    $style.= 'border-radius:10px;';
99    $style.= 'margin-left:5px;';
100   
101    $name.= '<span style="'.$style.'">'.$page['community_nb_pendings'].'</span>';
102
103    if (defined('IN_ADMIN') and IN_ADMIN and $page['page'] == 'intro')
104    {
105      global $template;
106     
107      $template->set_prefilter('intro', 'community_pendings_on_intro');
108      $template->assign(
109        array(
110          'COMMUNITY_PENDINGS' => sprintf(
111            '<a href="%s">'.l10n('%u pending photos').'</a>',
112            get_root_url().'admin.php?page=plugin-community-pendings',
113            $page['community_nb_pendings']
114            ),
115          )
116        );
117    }
118  }
119
120  array_push(
121    $menu,
122    array(
123      'NAME' => $name,
124      'URL'  => get_root_url().'admin.php?page=plugin-community'
125      )
126    );
127
128  return $menu;
129}
130
131function community_pendings_on_intro($content, &$smarty)
132{
133  $pattern = '#<li>\s*{\$DB_ELEMENTS\}#ms';
134  $replacement = '<li>{$COMMUNITY_PENDINGS}</li><li>{$DB_ELEMENTS}';
135  return preg_replace($pattern, $replacement, $content);
136}
137
138add_event_handler('init', 'community_load_language');
139function community_load_language()
140{
141  if (!defined('IN_ADMIN') or !IN_ADMIN)
142  {
143    load_language('admin.lang');
144  }
145 
146  load_language('plugin.lang', COMMUNITY_PATH);
147}
148
149
150add_event_handler('loc_end_section_init', 'community_section_init');
151function community_section_init()
152{
153  global $tokens, $page;
154 
155  if ($tokens[0] == 'add_photos')
156  {
157    $page['section'] = 'add_photos';
158  }
159}
160
161add_event_handler('loc_end_index', 'community_index');
162function community_index()
163{
164  global $page;
165 
166  if (isset($page['section']) and $page['section'] == 'add_photos')
167  {
168    include(COMMUNITY_PATH.'add_photos.php');
169  }
170}
171
172add_event_handler('blockmanager_apply' , 'community_gallery_menu', EVENT_HANDLER_PRIORITY_NEUTRAL+10);
173function community_gallery_menu($menu_ref_arr)
174{
175  global $conf, $user;
176
177  // conditional : depending on community permissions, display the "Add
178  // photos" link in the gallery menu
179  $user_permissions = $user['community_permissions'];
180
181  if (!$user_permissions['community_enabled'])
182  {
183    return;
184  }
185
186  $menu = & $menu_ref_arr[0];
187
188  if (($block = $menu->get_block('mbMenu')) != null )
189  {
190    load_language('plugin.lang', COMMUNITY_PATH);
191
192    array_splice(
193      $block->data,
194      count($block->data),
195      0,
196      array(
197        '' => array(
198          'URL' => make_index_url(array('section' => 'add_photos')),
199          'TITLE' => l10n('Upload your own photos'),
200          'NAME' => l10n('Upload Photos')
201          )
202        )
203      );
204  }
205}
206
207
208add_event_handler('ws_invoke_allowed', 'community_switch_user_to_admin', EVENT_HANDLER_PRIORITY_NEUTRAL, 3);
209function community_switch_user_to_admin($res, $methodName, $params)
210{
211  global $user, $community;
212
213  if (is_admin())
214  {
215    return $res;
216  }
217 
218  $community = array('method' => $methodName);
219
220  if ('pwg.images.addSimple' == $community['method'])
221  {
222    $community['category'] = $params['category'];
223  }
224  elseif ('pwg.images.add' == $community['method'])
225  {
226    $community['category'] = $params['categories'];
227    $community['md5sum'] = $params['original_sum'];
228  }
229
230  // $print_params = $params;
231  // unset($print_params['data']);
232  // file_put_contents('/tmp/community.log', '['.$methodName.'] '.json_encode($print_params)."\n" ,FILE_APPEND);
233
234  // conditional : depending on community permissions, display the "Add
235  // photos" link in the gallery menu
236  $user_permissions = community_get_user_permissions($user['id']);
237
238  if (count($user_permissions['upload_categories']) == 0 and !$user_permissions ['create_whole_gallery'])
239  {
240    return $res;
241  }
242
243  // if level of trust is low, then we have to set level to 16
244
245  $methods = array();
246  $methods[] = 'pwg.tags.add';
247  $methods[] = 'pwg.images.exist';
248  $methods[] = 'pwg.images.add';
249  $methods[] = 'pwg.images.addSimple';
250  $methods[] = 'pwg.images.addChunk';
251  $methods[] = 'pwg.images.checkUpload';
252  $methods[] = 'pwg.images.checkFiles';
253  $methods[] = 'pwg.images.setInfo';
254
255  if (in_array($methodName, $methods))
256  {
257    $user['status'] = 'admin';
258  }
259
260  if ('pwg.categories.add' == $methodName)
261  {
262    if (in_array($params['parent'], $user_permissions['create_categories'])
263        or $user_permissions['create_whole_gallery'])
264    {
265      $user['status'] = 'admin';
266    }
267  }
268
269  return $res;
270}
271
272add_event_handler('ws_add_methods', 'community_ws_replace_methods', EVENT_HANDLER_PRIORITY_NEUTRAL+5);
273function community_ws_replace_methods($arr)
274{
275  global $conf, $user;
276 
277  $service = &$arr[0];
278
279  if (is_admin())
280  {
281    return;
282  }
283
284  $user_permissions = community_get_user_permissions($user['id']);
285 
286  if (count($user_permissions['permission_ids']) == 0)
287  {
288    return;
289  }
290 
291  // the plugin Community is activated, the user has upload permissions, we
292  // use a specific function to list available categories, assuming the user
293  // wants to list categories where upload is possible for him
294 
295  $service->addMethod(
296    'pwg.categories.getList',
297    'community_ws_categories_getList',
298    array(
299      'cat_id' =>       array('default'=>0),
300      'recursive' =>    array('default'=>false),
301      'public' =>       array('default'=>false),
302      'tree_output' =>  array('default'=>false),
303      'fullname' =>     array('default'=>false),
304      ),
305    'retrieves a list of categories'
306    );
307 
308  $service->addMethod(
309    'pwg.tags.getAdminList',
310    'community_ws_tags_getAdminList',
311    array(),
312    'administration method only'
313    );
314}
315
316/**
317 * returns a list of categories (web service method)
318 */
319function community_ws_categories_getList($params, &$service)
320{
321  global $user, $conf;
322
323  if ($params['tree_output'])
324  {
325    if (!isset($_GET['format']) or !in_array($_GET['format'], array('php', 'json')))
326    {
327      // the algorithm used to build a tree from a flat list of categories
328      // keeps original array keys, which is not compatible with
329      // PwgNamedArray.
330      //
331      // PwgNamedArray is useful to define which data is an attribute and
332      // which is an element in the XML output. The "hierarchy" output is
333      // only compatible with json/php output.
334
335      return new PwgError(405, "The tree_output option is only compatible with json/php output formats");
336    }
337  }
338 
339  $where = array('1=1');
340  $join_type = 'LEFT';
341  $join_user = $user['id'];
342
343  if (!$params['recursive'])
344  {
345    if ($params['cat_id']>0)
346      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
347    OR id='.(int)($params['cat_id']).')';
348    else
349      $where[] = 'id_uppercat IS NULL';
350  }
351  else if ($params['cat_id']>0)
352  {
353    $where[] = 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.
354      (int)($params['cat_id'])
355      .'(,|$)\'';
356  }
357
358  if ($params['public'])
359  {
360    $where[] = 'status = "public"';
361    $where[] = 'visible = "true"';
362   
363    $join_user = $conf['guest_id'];
364  }
365
366  $user_permissions = community_get_user_permissions($user['id']);
367  $upload_categories = $user_permissions['upload_categories'];
368  if (count($upload_categories) == 0)
369  {
370    $upload_categories = array(-1);
371  }
372
373  $where[] = 'id IN ('.implode(',', $upload_categories).')';
374
375  $query = '
376SELECT
377    id,
378    name,
379    permalink,
380    uppercats,
381    global_rank,
382    comment,
383    nb_images,
384    count_images AS total_nb_images,
385    date_last,
386    max_date_last,
387    count_categories AS nb_categories
388  FROM '.CATEGORIES_TABLE.'
389   '.$join_type.' JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id AND user_id='.$join_user.'
390  WHERE '. implode('
391    AND ', $where);
392
393  $result = pwg_query($query);
394
395  $cats = array();
396  while ($row = pwg_db_fetch_assoc($result))
397  {
398    $row['url'] = make_index_url(
399        array(
400          'category' => $row
401          )
402      );
403    foreach( array('id','nb_images','total_nb_images','nb_categories') as $key)
404    {
405      $row[$key] = (int)$row[$key];
406    }
407
408    if ($params['fullname'])
409    {
410      $row['name'] = strip_tags(get_cat_display_name_cache($row['uppercats'], null, false));
411    }
412    else
413    {
414      $row['name'] = strip_tags(
415        trigger_event(
416          'render_category_name',
417          $row['name'],
418          'ws_categories_getList'
419          )
420        );
421    }
422   
423    $row['comment'] = strip_tags(
424      trigger_event(
425        'render_category_description',
426        $row['comment'],
427        'ws_categories_getList'
428        )
429      );
430   
431    array_push($cats, $row);
432  }
433  usort($cats, 'global_rank_compare');
434
435  if ($params['tree_output'])
436  {
437    return categories_flatlist_to_tree($cats);
438  }
439  else
440  {
441    return array(
442      'categories' => new PwgNamedArray(
443        $cats,
444        'category',
445        array(
446          'id',
447          'url',
448          'nb_images',
449          'total_nb_images',
450          'nb_categories',
451          'date_last',
452          'max_date_last',
453          )
454        )
455      );
456  }
457}
458
459function community_ws_tags_getAdminList($params, &$service)
460{
461  $tags = get_available_tags();
462
463  // keep orphan tags
464  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
465  $orphan_tags = get_orphan_tags();
466  if (count($orphan_tags) > 0)
467  {
468    $orphan_tag_ids = array();
469    foreach ($orphan_tags as $tag)
470    {
471      $orphan_tag_ids[] = $tag['id'];
472    }
473   
474    $query = '
475SELECT *
476  FROM '.TAGS_TABLE.'
477  WHERE id IN ('.implode(',', $orphan_tag_ids).')
478;';
479    $result = pwg_query($query);
480    while ($row = pwg_db_fetch_assoc($result))
481    {
482      $tags[] = $row;
483    }
484  }
485
486  usort($tags, 'tag_alpha_compare');
487 
488  return array(
489    'tags' => new PwgNamedArray(
490      $tags,
491      'tag',
492      array(
493        'name',
494        'id',
495        'url_name',
496        )
497      )
498    );
499}
500
501add_event_handler('sendResponse', 'community_sendResponse');
502function community_sendResponse($encodedResponse)
503{
504  global $community, $user;
505
506  if (!isset($community['method']))
507  {
508    return;
509  }
510
511  if ('pwg.images.addSimple' == $community['method'])
512  {
513    $response = json_decode($encodedResponse);
514    $image_id = $response->result->image_id;
515  }
516  elseif ('pwg.images.add' == $community['method'])
517  {   
518    $query = '
519SELECT
520    id
521  FROM '.IMAGES_TABLE.'
522  WHERE md5sum = \''.$community['md5sum'].'\'
523  ORDER BY id DESC
524  LIMIT 1
525;';
526    list($image_id) = pwg_db_fetch_row(pwg_query($query));
527  }
528  else
529  {
530    return;
531  }
532 
533  $image_ids = array($image_id);
534
535  // $category_id is set in the photos_add_direct_process.inc.php included script
536  $category_infos = get_cat_info($community['category']);
537
538  // should the photos be moderated?
539  //
540  // if one of the user community permissions is not moderated on the path
541  // to gallery root, then the upload is not moderated. For example, if the
542  // user is allowed to upload to events/parties with no admin moderation,
543  // then he's not moderated when uploading in
544  // events/parties/happyNewYear2011
545  $moderate = true;
546
547  $user_permissions = community_get_user_permissions($user['id']);
548  $query = '
549SELECT
550    cp.category_id,
551    c.uppercats
552  FROM '.COMMUNITY_PERMISSIONS_TABLE.' AS cp
553    LEFT JOIN '.CATEGORIES_TABLE.' AS c ON category_id = c.id
554  WHERE cp.id IN ('.implode(',', $user_permissions['permission_ids']).')
555    AND cp.moderated = \'false\'
556;';
557  $result = pwg_query($query);
558  while ($row = pwg_db_fetch_assoc($result))
559  {
560    if (empty($row['category_id']))
561    {
562      $moderate = false;
563    }
564    elseif (preg_match('/^'.$row['uppercats'].'(,|$)/', $category_infos['uppercats']))
565    {
566      $moderate = false;
567    }
568  }
569 
570  if ($moderate)
571  {
572    $inserts = array();
573
574    $query = '
575SELECT
576    id,
577    date_available
578  FROM '.IMAGES_TABLE.'
579  WHERE id IN ('.implode(',', $image_ids).')
580;';
581    $result = pwg_query($query);
582    while ($row = pwg_db_fetch_assoc($result))
583    {
584      array_push(
585        $inserts,
586        array(
587          'image_id' => $row['id'],
588          'added_on' => $row['date_available'],
589          'state' => 'moderation_pending',
590          )
591        );
592    }
593   
594    mass_inserts(
595      COMMUNITY_PENDINGS_TABLE,
596      array_keys($inserts[0]),
597      $inserts
598      );
599   
600    // the level of a user upload photo with moderation is 16
601    $level = 16;
602  }
603  else
604  {
605    // the level of a user upload photo with no moderation is 0
606    $level = 0;
607  }
608
609  $query = '
610UPDATE '.IMAGES_TABLE.'
611  SET level = '.$level.'
612  WHERE id IN ('.implode(',', $image_ids).')
613;';
614  pwg_query($query);
615
616  invalidate_user_cache();
617}
618
619add_event_handler('delete_user', 'community_delete_user');
620function community_delete_user($user_id)
621{
622  $query = '
623DELETE
624  FROM '.COMMUNITY_PERMISSIONS_TABLE.'
625  WHERE user_id = '.$user_id.'
626;';
627  pwg_query($query);
628
629  community_reject_user_pendings($user_id);
630}
631
632add_event_handler('delete_categories', 'community_delete_category');
633function community_delete_category($category_ids)
634{
635  // $category_ids includes all the sub-category ids
636  $query = '
637DELETE
638  FROM '.COMMUNITY_PERMISSIONS_TABLE.'
639  WHERE category_id IN ('.implode(',', $category_ids).')
640;';
641  pwg_query($query);
642 
643  community_update_cache_key();
644}
645
646add_event_handler('invalidate_user_cache', 'community_refresh_cache_update_time');
647function community_refresh_cache_update_time()
648{
649  community_update_cache_key();
650}
651
652add_event_handler('init', 'community_uploadify_privacy_level');
653function community_uploadify_privacy_level()
654{
655  if (script_basename() == 'uploadify' and !is_admin())
656  {
657    $_POST['level'] = 16;
658  }
659}
660
661// +-----------------------------------------------------------------------+
662// | User Albums                                                           |
663// +-----------------------------------------------------------------------+
664
665add_event_handler('loc_end_cat_modify', 'community_set_prefilter_cat_modify', 50);
666// add_event_handler('loc_begin_admin_page', 'community_cat_modify_submit', 45);
667
668// Change the variables used by the function that changes the template
669// add_event_handler('loc_begin_admin_page', 'community_cat_modify_add_vars_to_template');
670
671function community_set_prefilter_cat_modify()
672{
673        global $template, $conf, $category;
674
675  if (!isset($conf['community']['user_albums']) or !$conf['community']['user_albums'])
676  {
677    return;
678  }
679 
680  $template->set_prefilter('album_properties', 'community_cat_modify_prefilter');
681
682  $query = '
683SELECT
684    '.$conf['user_fields']['id'].' AS id,
685    '.$conf['user_fields']['username'].' AS username
686  FROM '.USERS_TABLE.' AS u
687    INNER JOIN '.USER_INFOS_TABLE.' AS uf ON uf.user_id = id
688  WHERE uf.status IN (\'normal\',\'generic\')
689;';
690  $result = pwg_query($query);
691  $users = array();
692  while ($row = pwg_db_fetch_assoc($result))
693  {
694    $users[$row['id']] = $row['username'];
695  }
696
697  $template->assign(
698    array(
699      'community_user_options' => $users,
700      'community_user_selected' => $category['community_user'],
701      )
702    );
703}
704
705function community_cat_modify_prefilter($content, &$smarty)
706{
707        $search = "#<strong>{'Name'#";
708
709        // We use the <tr> from the Creation date, and give them a new <tr>
710        $replacement = '<strong>(Community) {\'Album of user\'|@translate}</strong>
711                <br>
712                        <select name="community_user">
713                                <option value="">--</option>
714                                {html_options options=$community_user_options selected=$community_user_selected}
715                        </select>
716      <em>{\'a user can own only one album\'|@translate}</em>
717                </p>
718       
719        </p>
720  <p>
721                <strong>{\'Name\'';
722
723  return preg_replace($search, $replacement, $content);
724}
725
726add_event_handler('loc_begin_cat_modify', 'community_cat_modify_submit');
727function community_cat_modify_submit()
728{
729  global $category, $conf;
730
731  if (!isset($conf['community']['user_albums']) or !$conf['community']['user_albums'])
732  {
733    return;
734  }
735 
736  if (isset($_POST['community_user']))
737  {
738    // echo '<pre>'; print_r($_POST); echo '</pre>'; exit();
739    // only one album for each user, first we remove ownership on any other album
740    single_update(
741      CATEGORIES_TABLE,
742      array('community_user' => null),
743      array('community_user' => $_POST['community_user'])
744      );
745
746    // then we give the album to the user
747    single_update(
748      CATEGORIES_TABLE,
749      array('community_user' => $_POST['community_user']),
750      array('id' => $category['id'])
751      );
752  }
753}
754?>
Note: See TracBrowser for help on using the repository browser.