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

Last change on this file since 22205 was 21751, checked in by plg, 11 years ago

bug fixed with iOS/Android app on pwg.categories.getList

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