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

Last change on this file since 23037 was 23037, checked in by plg, 8 years ago

manage quota (number of photos, disk usage)

File size: 15.6 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, $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
67/* Plugin admin */
68add_event_handler('get_admin_plugin_menu_links', 'community_admin_menu');
69function community_admin_menu($menu)
70{
71  global $page;
72 
73  $query = '
74SELECT
75    COUNT(*)
76  FROM '.COMMUNITY_PENDINGS_TABLE.'
77  WHERE state = \'moderation_pending\'
78;';
79  $result = pwg_query($query);
80  list($page['community_nb_pendings']) = pwg_db_fetch_row($result);
81
82  $name = 'Community';
83  if ($page['community_nb_pendings'] > 0)
84  {
85    $style = 'background-color:#666;';
86    $style.= 'color:white;';
87    $style.= 'padding:1px 5px;';
88    $style.= '-moz-border-radius:10px;';
89    $style.= '-webkit-border-radius:10px;';
90    $style.= '-border-radius:10px;';
91    $style.= 'margin-left:5px;';
92   
93    $name.= '<span style="'.$style.'">'.$page['community_nb_pendings'].'</span>';
94
95    if (defined('IN_ADMIN') and IN_ADMIN and $page['page'] == 'intro')
96    {
97      global $template;
98     
99      $template->set_prefilter('intro', 'community_pendings_on_intro');
100      $template->assign(
101        array(
102          'COMMUNITY_PENDINGS' => sprintf(
103            '<a href="%s">'.l10n('%u pending photos').'</a>',
104            get_root_url().'admin.php?page=plugin-community-pendings',
105            $page['community_nb_pendings']
106            ),
107          )
108        );
109    }
110  }
111
112  array_push(
113    $menu,
114    array(
115      'NAME' => $name,
116      'URL'  => get_root_url().'admin.php?page=plugin-community'
117      )
118    );
119
120  return $menu;
121}
122
123function community_pendings_on_intro($content, &$smarty)
124{
125  $pattern = '#<li>\s*{\$DB_ELEMENTS\}#ms';
126  $replacement = '<li>{$COMMUNITY_PENDINGS}</li><li>{$DB_ELEMENTS}';
127  return preg_replace($pattern, $replacement, $content);
128}
129
130add_event_handler('init', 'community_load_language');
131function community_load_language()
132{
133  if (!defined('IN_ADMIN') or !IN_ADMIN)
134  {
135    load_language('admin.lang');
136  }
137 
138  load_language('plugin.lang', COMMUNITY_PATH);
139}
140
141
142add_event_handler('loc_end_section_init', 'community_section_init');
143function community_section_init()
144{
145  global $tokens, $page;
146 
147  if ($tokens[0] == 'add_photos')
148  {
149    $page['section'] = 'add_photos';
150  }
151}
152
153add_event_handler('loc_end_index', 'community_index');
154function community_index()
155{
156  global $page;
157 
158  if (isset($page['section']) and $page['section'] == 'add_photos')
159  {
160    include(COMMUNITY_PATH.'add_photos.php');
161  }
162}
163
164add_event_handler('blockmanager_apply' , 'community_gallery_menu', EVENT_HANDLER_PRIORITY_NEUTRAL+10);
165function community_gallery_menu($menu_ref_arr)
166{
167  global $conf, $user;
168
169  // conditional : depending on community permissions, display the "Add
170  // photos" link in the gallery menu
171  $user_permissions = community_get_user_permissions($user['id']);
172
173  if (count($user_permissions['upload_categories']) == 0 and !$user_permissions ['create_whole_gallery'])
174  {
175    return;
176  }
177
178  $menu = & $menu_ref_arr[0];
179
180  if (($block = $menu->get_block('mbMenu')) != null )
181  {
182    load_language('plugin.lang', COMMUNITY_PATH);
183
184    array_splice(
185      $block->data,
186      count($block->data),
187      0,
188      array(
189        '' => array(
190          'URL' => make_index_url(array('section' => 'add_photos')),
191          'TITLE' => l10n('Upload your own photos'),
192          'NAME' => l10n('Upload Photos')
193          )
194        )
195      );
196  }
197}
198
199
200add_event_handler('ws_invoke_allowed', 'community_switch_user_to_admin', EVENT_HANDLER_PRIORITY_NEUTRAL, 3);
201function community_switch_user_to_admin($res, $methodName, $params)
202{
203  global $user, $community;
204
205  if (is_admin())
206  {
207    return $res;
208  }
209 
210  $community = array('method' => $methodName);
211
212  if ('pwg.images.addSimple' == $community['method'])
213  {
214    $community['category'] = $params['category'];
215  }
216  elseif ('pwg.images.add' == $community['method'])
217  {
218    $community['category'] = $params['categories'];
219    $community['md5sum'] = $params['original_sum'];
220  }
221
222  // $print_params = $params;
223  // unset($print_params['data']);
224  // file_put_contents('/tmp/community.log', '['.$methodName.'] '.json_encode($print_params)."\n" ,FILE_APPEND);
225
226  // conditional : depending on community permissions, display the "Add
227  // photos" link in the gallery menu
228  $user_permissions = community_get_user_permissions($user['id']);
229
230  if (count($user_permissions['upload_categories']) == 0 and !$user_permissions ['create_whole_gallery'])
231  {
232    return $res;
233  }
234
235  // if level of trust is low, then we have to set level to 16
236
237  $methods = array();
238  $methods[] = 'pwg.tags.add';
239  $methods[] = 'pwg.images.exist';
240  $methods[] = 'pwg.images.add';
241  $methods[] = 'pwg.images.addSimple';
242  $methods[] = 'pwg.images.addChunk';
243  $methods[] = 'pwg.images.checkUpload';
244  $methods[] = 'pwg.images.checkFiles';
245  $methods[] = 'pwg.images.setInfo';
246
247  if (in_array($methodName, $methods))
248  {
249    $user['status'] = 'admin';
250  }
251
252  if ('pwg.categories.add' == $methodName)
253  {
254    if (in_array($params['parent'], $user_permissions['create_categories'])
255        or $user_permissions['create_whole_gallery'])
256    {
257      $user['status'] = 'admin';
258    }
259  }
260
261  return $res;
262}
263
264add_event_handler('ws_add_methods', 'community_ws_replace_methods', EVENT_HANDLER_PRIORITY_NEUTRAL+5);
265function community_ws_replace_methods($arr)
266{
267  global $conf, $user;
268 
269  $service = &$arr[0];
270
271  if (is_admin())
272  {
273    return;
274  }
275
276  $user_permissions = community_get_user_permissions($user['id']);
277 
278  if (count($user_permissions['permission_ids']) == 0)
279  {
280    return;
281  }
282 
283  // the plugin Community is activated, the user has upload permissions, we
284  // use a specific function to list available categories, assuming the user
285  // wants to list categories where upload is possible for him
286 
287  $service->addMethod(
288    'pwg.categories.getList',
289    'community_ws_categories_getList',
290    array(
291      'cat_id' =>       array('default'=>0),
292      'recursive' =>    array('default'=>false),
293      'public' =>       array('default'=>false),
294      'tree_output' =>  array('default'=>false),
295      'fullname' =>     array('default'=>false),
296      ),
297    'retrieves a list of categories'
298    );
299 
300  $service->addMethod(
301    'pwg.tags.getAdminList',
302    'community_ws_tags_getAdminList',
303    array(),
304    'administration method only'
305    );
306}
307
308/**
309 * returns a list of categories (web service method)
310 */
311function community_ws_categories_getList($params, &$service)
312{
313  global $user, $conf;
314
315  if ($params['tree_output'])
316  {
317    if (!isset($_GET['format']) or !in_array($_GET['format'], array('php', 'json')))
318    {
319      // the algorithm used to build a tree from a flat list of categories
320      // keeps original array keys, which is not compatible with
321      // PwgNamedArray.
322      //
323      // PwgNamedArray is useful to define which data is an attribute and
324      // which is an element in the XML output. The "hierarchy" output is
325      // only compatible with json/php output.
326
327      return new PwgError(405, "The tree_output option is only compatible with json/php output formats");
328    }
329  }
330 
331  $where = array('1=1');
332  $join_type = 'LEFT';
333  $join_user = $user['id'];
334
335  if (!$params['recursive'])
336  {
337    if ($params['cat_id']>0)
338      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
339    OR id='.(int)($params['cat_id']).')';
340    else
341      $where[] = 'id_uppercat IS NULL';
342  }
343  else if ($params['cat_id']>0)
344  {
345    $where[] = 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.
346      (int)($params['cat_id'])
347      .'(,|$)\'';
348  }
349
350  if ($params['public'])
351  {
352    $where[] = 'status = "public"';
353    $where[] = 'visible = "true"';
354   
355    $join_user = $conf['guest_id'];
356  }
357
358  $user_permissions = community_get_user_permissions($user['id']);
359  $upload_categories = $user_permissions['upload_categories'];
360  if (count($upload_categories) == 0)
361  {
362    $upload_categories = array(-1);
363  }
364
365  $where[] = 'id IN ('.implode(',', $upload_categories).')';
366
367  $query = '
368SELECT
369    id,
370    name,
371    permalink,
372    uppercats,
373    global_rank,
374    comment,
375    nb_images,
376    count_images AS total_nb_images,
377    date_last,
378    max_date_last,
379    count_categories AS nb_categories
380  FROM '.CATEGORIES_TABLE.'
381   '.$join_type.' JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id AND user_id='.$join_user.'
382  WHERE '. implode('
383    AND ', $where);
384
385  $result = pwg_query($query);
386
387  $cats = array();
388  while ($row = pwg_db_fetch_assoc($result))
389  {
390    $row['url'] = make_index_url(
391        array(
392          'category' => $row
393          )
394      );
395    foreach( array('id','nb_images','total_nb_images','nb_categories') as $key)
396    {
397      $row[$key] = (int)$row[$key];
398    }
399
400    if ($params['fullname'])
401    {
402      $row['name'] = strip_tags(get_cat_display_name_cache($row['uppercats'], null, false));
403    }
404    else
405    {
406      $row['name'] = strip_tags(
407        trigger_event(
408          'render_category_name',
409          $row['name'],
410          'ws_categories_getList'
411          )
412        );
413    }
414   
415    $row['comment'] = strip_tags(
416      trigger_event(
417        'render_category_description',
418        $row['comment'],
419        'ws_categories_getList'
420        )
421      );
422   
423    array_push($cats, $row);
424  }
425  usort($cats, 'global_rank_compare');
426
427  if ($params['tree_output'])
428  {
429    return categories_flatlist_to_tree($cats);
430  }
431  else
432  {
433    return array(
434      'categories' => new PwgNamedArray(
435        $cats,
436        'category',
437        array(
438          'id',
439          'url',
440          'nb_images',
441          'total_nb_images',
442          'nb_categories',
443          'date_last',
444          'max_date_last',
445          )
446        )
447      );
448  }
449}
450
451function community_ws_tags_getAdminList($params, &$service)
452{
453  $tags = get_available_tags();
454
455  // keep orphan tags
456  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
457  $orphan_tags = get_orphan_tags();
458  if (count($orphan_tags) > 0)
459  {
460    $orphan_tag_ids = array();
461    foreach ($orphan_tags as $tag)
462    {
463      $orphan_tag_ids[] = $tag['id'];
464    }
465   
466    $query = '
467SELECT *
468  FROM '.TAGS_TABLE.'
469  WHERE id IN ('.implode(',', $orphan_tag_ids).')
470;';
471    $result = pwg_query($query);
472    while ($row = pwg_db_fetch_assoc($result))
473    {
474      $tags[] = $row;
475    }
476  }
477
478  usort($tags, 'tag_alpha_compare');
479 
480  return array(
481    'tags' => new PwgNamedArray(
482      $tags,
483      'tag',
484      array(
485        'name',
486        'id',
487        'url_name',
488        )
489      )
490    );
491}
492
493add_event_handler('sendResponse', 'community_sendResponse');
494function community_sendResponse($encodedResponse)
495{
496  global $community, $user;
497
498  if (!isset($community['method']))
499  {
500    return;
501  }
502
503  if ('pwg.images.addSimple' == $community['method'])
504  {
505    $response = json_decode($encodedResponse);
506    $image_id = $response->result->image_id;
507  }
508  elseif ('pwg.images.add' == $community['method'])
509  {   
510    $query = '
511SELECT
512    id
513  FROM '.IMAGES_TABLE.'
514  WHERE md5sum = \''.$community['md5sum'].'\'
515  ORDER BY id DESC
516  LIMIT 1
517;';
518    list($image_id) = pwg_db_fetch_row(pwg_query($query));
519  }
520  else
521  {
522    return;
523  }
524 
525  $image_ids = array($image_id);
526
527  // $category_id is set in the photos_add_direct_process.inc.php included script
528  $category_infos = get_cat_info($community['category']);
529
530  // should the photos be moderated?
531  //
532  // if one of the user community permissions is not moderated on the path
533  // to gallery root, then the upload is not moderated. For example, if the
534  // user is allowed to upload to events/parties with no admin moderation,
535  // then he's not moderated when uploading in
536  // events/parties/happyNewYear2011
537  $moderate = true;
538
539  $user_permissions = community_get_user_permissions($user['id']);
540  $query = '
541SELECT
542    cp.category_id,
543    c.uppercats
544  FROM '.COMMUNITY_PERMISSIONS_TABLE.' AS cp
545    LEFT JOIN '.CATEGORIES_TABLE.' AS c ON category_id = c.id
546  WHERE cp.id IN ('.implode(',', $user_permissions['permission_ids']).')
547    AND cp.moderated = \'false\'
548;';
549  $result = pwg_query($query);
550  while ($row = pwg_db_fetch_assoc($result))
551  {
552    if (empty($row['category_id']))
553    {
554      $moderate = false;
555    }
556    elseif (preg_match('/^'.$row['uppercats'].'(,|$)/', $category_infos['uppercats']))
557    {
558      $moderate = false;
559    }
560  }
561 
562  if ($moderate)
563  {
564    $inserts = array();
565
566    $query = '
567SELECT
568    id,
569    date_available
570  FROM '.IMAGES_TABLE.'
571  WHERE id IN ('.implode(',', $image_ids).')
572;';
573    $result = pwg_query($query);
574    while ($row = pwg_db_fetch_assoc($result))
575    {
576      array_push(
577        $inserts,
578        array(
579          'image_id' => $row['id'],
580          'added_on' => $row['date_available'],
581          'state' => 'moderation_pending',
582          )
583        );
584    }
585   
586    mass_inserts(
587      COMMUNITY_PENDINGS_TABLE,
588      array_keys($inserts[0]),
589      $inserts
590      );
591   
592    // the level of a user upload photo with moderation is 16
593    $level = 16;
594  }
595  else
596  {
597    // the level of a user upload photo with no moderation is 0
598    $level = 0;
599  }
600
601  $query = '
602UPDATE '.IMAGES_TABLE.'
603  SET level = '.$level.'
604  WHERE id IN ('.implode(',', $image_ids).')
605;';
606  pwg_query($query);
607
608  invalidate_user_cache();
609}
610
611add_event_handler('delete_user', 'community_delete_user');
612function community_delete_user($user_id)
613{
614  $query = '
615DELETE
616  FROM '.COMMUNITY_PERMISSIONS_TABLE.'
617  WHERE user_id = '.$user_id.'
618;';
619  pwg_query($query);
620
621  community_reject_user_pendings($user_id);
622}
623
624add_event_handler('delete_categories', 'community_delete_category');
625function community_delete_category($category_ids)
626{
627  // $category_ids includes all the sub-category ids
628  $query = '
629DELETE
630  FROM '.COMMUNITY_PERMISSIONS_TABLE.'
631  WHERE category_id IN ('.implode(',', $category_ids).')
632;';
633  pwg_query($query);
634 
635  community_update_cache_key();
636}
637
638add_event_handler('invalidate_user_cache', 'community_refresh_cache_update_time');
639function community_refresh_cache_update_time()
640{
641  community_update_cache_key();
642}
643
644add_event_handler('init', 'community_uploadify_privacy_level');
645function community_uploadify_privacy_level()
646{
647  if (script_basename() == 'uploadify' and !is_admin())
648  {
649    $_POST['level'] = 16;
650  }
651}
652?>
Note: See TracBrowser for help on using the repository browser.