source: extensions/UserCollections/include/UserCollection.class.php @ 27112

Last change on this file since 27112 was 26055, checked in by mistic100, 10 years ago

use of undefined constant, retard mobile detection

File size: 14.7 KB
RevLine 
[16591]1<?php
2defined('USER_COLLEC_PATH') or die('Hacking attempt!');
3
4class UserCollection
5{
6  private $data;
7  private $images;
[25678]8
[16591]9  /**
10   * __construct
[25678]11   * @throws Exception
12   *
13   * @param int|string $col_id or 'new'
14   * @param string $name
15   * @param string $comment
16   * @param int $user_id
[16591]17   */
[24421]18  function __construct($col_id, $name=null, $comment=null, $user_id=null)
[16591]19  {
[16625]20    global $user;
[25678]21
[24421]22    if (empty($user_id))
23    {
[20090]24      $user_id = $user['id'];
25    }
[25678]26
[16591]27    $this->data = array(
[16688]28      'id' => 0,
[20090]29      'user_id' => $user_id,
[16591]30      'name' => null,
31      'date_creation' => '0000-00-00 00:00:00',
[23552]32      'comment' => null,
[16591]33      'nb_images' => 0,
34      );
35    $this->images = array();
[25678]36
[16591]37    // load specific collection
38    if (preg_match('#^[0-9]+$#', $col_id))
39    {
40      $query = '
[23361]41SELECT *
[16591]42  FROM '.COLLECTIONS_TABLE.'
[24421]43  WHERE id = '.$col_id.'
[16591]44;';
45      $result = pwg_query($query);
[25678]46
[16591]47      if (pwg_db_num_rows($result))
48      {
[16658]49        $this->data = array_merge(
50          $this->data,
51          pwg_db_fetch_assoc($result)
52          );
[25678]53
[23551]54        // make sure all pictures of the collection exist
[16591]55        $query = '
56DELETE FROM '.COLLECTION_IMAGES_TABLE.'
57  WHERE image_id NOT IN (
58    SELECT id FROM '.IMAGES_TABLE.'
59    )
60;';
61        pwg_query($query);
[25678]62
[20090]63        // select images of the collection
[16591]64        $query = '
65SELECT image_id
66  FROM '.COLLECTION_IMAGES_TABLE.'
[16688]67  WHERE col_id = '.$this->data['id'].'
[16591]68;';
69        $this->images = array_from_query($query, 'image_id');
[25678]70
[20090]71        $this->updateParam('nb_images', count($this->images));
[16591]72      }
73      else
74      {
[26055]75        throw new Exception(l10n('Invalid collection'));
[16591]76      }
77    }
78    // create a new collection
79    else if ($col_id == 'new')
80    {
81      $this->data['name'] = $name;
[23551]82      $this->data['comment'] = $comment;
[25678]83
[16591]84      $query = '
85INSERT INTO '.COLLECTIONS_TABLE.'(
86    user_id,
87    name,
88    date_creation,
[24421]89    comment
[25678]90  )
[16591]91  VALUES(
92    '.$this->data['user_id'].',
93    "'.$this->data['name'].'",
94    NOW(),
[24421]95    "'.$this->data['comment'].'"
[16591]96  )
97;';
98      pwg_query($query);
[16688]99      $this->data['id'] = pwg_db_insert_id();
[25678]100
[20090]101      $date = pwg_query('SELECT NOW();');
[16591]102      list($this->data['date_creation']) = pwg_db_fetch_row($date);
103    }
104    else
105    {
106      trigger_error('UserCollection::__construct, invalid input parameter', E_USER_ERROR);
107    }
108  }
[25678]109
[16591]110  /**
[25678]111   * Check if current user is owner of the collection or admin
112   * @throws Exception
[24421]113   */
114  function checkUser()
115  {
116    global $user;
[25678]117
[24421]118    if (!is_admin() && $user['id'] != $this->data['user_id'])
119    {
120      throw new Exception('Forbidden', 403);
121    }
122  }
[25678]123
[24421]124  /**
[16591]125   * updateParam
[25678]126   *
127   * @param string $name
128   * @param mixed $value
[16591]129   */
130  function updateParam($name, $value)
131  {
[20090]132    if ($value != $this->data[$name])
133    {
134      $this->data[$name] = $value;
135      pwg_query('UPDATE '.COLLECTIONS_TABLE.' SET '.$name.' = "'.pwg_db_real_escape_string($value).'" WHERE id = '.$this->data['id'].';');
136    }
[16591]137  }
[25678]138
[16591]139  /**
140   * getParam
[25678]141   *
142   * @param string $name
143   * @return mixed
[16591]144   */
145  function getParam($name)
146  {
147    return $this->data[$name];
148  }
[25678]149
[16591]150  /**
151   * getImages
[25678]152   *
153   * @return int[]
[16591]154   */
155  function getImages()
156  {
157    return $this->images;
158  }
[25678]159
[16591]160  /**
[25678]161   * Check if an image is in the collection.
162   *
163   * @param int $image_id
164   * @return bool
[16591]165   */
166  function isInSet($image_id)
167  {
168    return in_array($image_id, $this->images);
169  }
[25678]170
[16591]171  /**
172   * removeImages
[25678]173   *
174   * @param int|int[] $image_ids
[16591]175   */
176  function removeImages($image_ids)
177  {
[25678]178    if (empty($image_ids)) return;
179    if (!is_array($image_ids)) $image_ids = array($image_ids);
180
[23361]181    $this->images = array_diff($this->images, $image_ids);
[25678]182
[16591]183    $query = '
184DELETE FROM '.COLLECTION_IMAGES_TABLE.'
[25678]185  WHERE
[16688]186    col_id = '.$this->data['id'].'
[16591]187    AND image_id IN('.implode(',', $image_ids).')
188;';
189    pwg_query($query);
[25678]190
[16591]191    $this->updateParam('nb_images', count($this->images));
192  }
[25678]193
[16591]194  /**
195   * addImages
[25678]196   *
197   * @param int|int[] $image_ids
[16591]198   */
199  function addImages($image_ids)
200  {
[25678]201    if (empty($image_ids)) return;
202    if (!is_array($image_ids)) $image_ids = array($image_ids);
203
[16591]204    $image_ids = array_unique($image_ids);
205    $inserts = array();
[25678]206
[16591]207    foreach ($image_ids as $image_id)
208    {
209      if ($this->isInSet($image_id)) continue;
[25678]210
[23361]211      $this->images[] = $image_id;
212      $inserts[] = array(
213        'col_id' => $this->data['id'],
214        'image_id' => $image_id,
215        );
[16591]216    }
[25678]217
[16591]218    mass_inserts(
219      COLLECTION_IMAGES_TABLE,
220      array('col_id', 'image_id'),
221      $inserts
222      );
[25678]223
[20090]224    $query = '
225UPDATE '.COLLECTION_IMAGES_TABLE.'
226  SET add_date = NOW()
227  WHERE
228    col_id = '.$this->data['id'].'
229    AND image_id IN ('.implode(',', $image_ids).')
230    AND add_date IS NULL
231';
232    pwg_query($query);
[25678]233
[16591]234    $this->updateParam('nb_images', count($this->images));
235  }
[25678]236
[16591]237  /**
238   * toggleImage
[25678]239   *
240   * @param int $image_id
[16591]241   */
242  function toggleImage($image_id)
243  {
244    if ($this->isInSet($image_id))
245    {
246      $this->removeImages(array($image_id));
247    }
248    else
249    {
250      $this->addImages(array($image_id));
251    }
252  }
[25678]253
[16591]254  /**
255   * clearImages
256   */
257  function clearImages()
258  {
259    $this->images = array();
260    $this->updateParam('nb_images', 0);
[25678]261
[16591]262    $query = '
263DELETE FROM '.COLLECTION_IMAGES_TABLE.'
[16688]264  WHERE col_id = '.$this->data['id'].'
[16591]265;';
266    pwg_query($query);
267  }
[25678]268
[16591]269  /**
270   * getCollectionInfo
[25678]271   *
272   * @return array
[16591]273   */
274  function getCollectionInfo()
275  {
276    $set = array(
[23361]277      'ID' => $this->data['id'],
[16591]278      'NAME' => $this->data['name'],
[23551]279      'COMMENT' => $this->data['comment'],
[16591]280      'NB_IMAGES' => $this->data['nb_images'],
[20090]281      'DATE_CREATION' => $this->data['date_creation'],
[16591]282      );
[25678]283
[16591]284    return $set;
285  }
[25678]286
[20090]287  /**
[25678]288   * Returns share links
289   *
290   * @return array
[24421]291   */
292  function getShares()
293  {
294    $query = '
295SELECT * FROM '.COLLECTION_SHARES_TABLE.'
296  WHERE col_id = '.$this->data['id'].'
297  ORDER BY add_date DESC
298;';
299    $result = pwg_query($query);
[25678]300
[24421]301    $shares = array();
302    while ($row = pwg_db_fetch_assoc($result))
303    {
304      $row['expired'] = false;
[25678]305
[24421]306      $row['params'] = unserialize($row['params']);
307      if (!empty($row['params']['deadline']))
308      {
309        $row['expired'] = strtotime($row['params']['deadline']) < time();
310        $row['params']['deadline_readable'] = format_date($row['params']['deadline'], true, false);
311      }
[25678]312
[24421]313      $row['url'] = USER_COLLEC_PUBLIC . 'view/' . $row['share_key'];
314      $row['u_delete'] = USER_COLLEC_PUBLIC . 'edit/' . $this->data['id'] . '&amp;delete_share=' . $row['id'];
315      $row['add_date_readable'] = format_date($row['add_date'], true, false);
[25678]316
[24421]317      $shares[] = $row;
318    }
[25678]319
[24421]320    return $shares;
321  }
[25678]322
[24421]323  /**
[25678]324   * Delete a share
325   *
326   * @param int $id
327   * @return bool
[24421]328   */
329  function deleteShare($id)
330  {
331    $query = '
332DELETE FROM '.COLLECTION_SHARES_TABLE.'
333  WHERE id = "'.pwg_db_real_escape_string($id).'"
334  AND col_id = '.$this->data['id'].'
335;';
336    pwg_query($query);
[25678]337
[24421]338    return pwg_db_changes() != 0;
339  }
[25678]340
[24421]341  /**
[25678]342   * Add a share link
343   *
344   * @param array &$share
345   *          - share_key (will be slugified)
346   *          - password (optional)
347   *          - deadline (optional)
348   * @param bool $abord_on_duplicate
349   * @return array|string errors or full share link
[24421]350   */
[25674]351  function addShare(&$share, $abord_on_duplicate=true)
[24421]352  {
353    global $conf, $page;
[25678]354
[24421]355    $errors = array();
[25678]356
[24421]357    $share = array_map('stripslashes', $share);
[25678]358
[24421]359    // check key
360    if (empty($share['share_key']) || strlen($share['share_key']) < 8)
361    {
362      $errors[] = l10n('The key must be at least 8 characters long');
363    }
364    else
365    {
[25674]366      $share['share_key'] = str2url($share['share_key']);
367      $share_key = $this->data['id'].'-'.$share['share_key'];
[25678]368
[24421]369      $query = '
370SELECT id FROM '.COLLECTION_SHARES_TABLE.'
371  WHERE col_id = '.$this->data['id'].'
[25674]372  AND share_key = "'.$share_key.'"
[24421]373;';
374      $result = pwg_query($query);
375      if (pwg_db_num_rows($result))
376      {
377        if ($abord_on_duplicate)
378        {
379          $errors[] = l10n('This key is already used');
380        }
381        else
382        {
[25674]383          return USER_COLLEC_PUBLIC . 'view/' . $share_key;
[24421]384        }
385      }
386    }
[25678]387
[24421]388    // filter date
389    if (!empty($share['deadline']))
390    {
[25678]391      $share['deadline'] = transform_date($share['deadline'], 'Y-m-d H:i', 'Y-m-d H:i');
[24421]392    }
[25678]393
[24421]394    // hash password
395    if (!empty($share['password']))
396    {
[25674]397      $share['password'] = sha1($conf['secret_key'].$share['password'].$share_key);
[24421]398    }
[25678]399
[24421]400    if (empty($errors))
401    {
402      $params = serialize(array(
403        'password' => @$share['password'],
404        'deadline' => @$share['deadline'],
405        ));
[25678]406
[24421]407      $query = '
408INSERT INTO '.COLLECTION_SHARES_TABLE.'(
409    col_id,
410    share_key,
411    params,
412    add_date
413  )
414  VALUES(
415    '.$this->data['id'].',
[25674]416    "'.$share_key.'",
[24421]417    "'.pwg_db_real_escape_string($params).'",
418    "'.date('Y-m-d H:i:s').'"
419  )
420;';
421      pwg_query($query);
[25678]422
[25674]423      return USER_COLLEC_PUBLIC . 'view/' . $share_key;
[24421]424    }
[25678]425
[24421]426    return $errors;
427  }
[25678]428
[24421]429  /**
[20090]430   * Send the collection by email
[25678]431   *
432   * @param array $comm
[20090]433   *          - sender_name
434   *          - sender_email
435   *          - recipient_email
436   *          - recipient_name
437   *          - nb_images
438   *          - message
[25678]439   * @return array|true array errors or true
[20090]440   */
[24421]441  function sendEmail($comm)
[20090]442  {
[25678]443    global $conf, $user;
444
[20090]445    $errors = array();
[25678]446
[20090]447    $comm = array_map('stripslashes', $comm);
448
[25678]449    $comment_action = 'validate';
[20090]450
451    // check author
452    if (empty($comm['sender_name']))
453    {
[25678]454      $errors[] = l10n('Please enter your name');
455      $comment_action = 'reject';
456    }
[20090]457    if (empty($comm['recipient_name']))
458    {
[25678]459      $errors[] = l10n('Please enter the recipient name');
460      $comment_action = 'reject';
[20090]461    }
[25678]462
[20090]463    // check email
464    if (empty($comm['sender_email']))
465    {
[25678]466      $errors[] = l10n('Please enter your e-mail');
467      $comment_action = 'reject';
[20090]468    }
[25678]469    else if (!empty($comm['sender_email']) and !email_check_format($comm['sender_email']))
[20090]470    {
[25678]471      $errors[] = l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)');
472      $comment_action = 'reject';
[20090]473    }
474    if (empty($comm['recipient_email']))
475    {
[25678]476      $errors[] = l10n('Please enter the recipient e-mail');
477      $comment_action = 'reject';
[20090]478    }
[25678]479    else if (!empty($comm['recipient_email']) and !email_check_format($comm['recipient_email']))
[20090]480    {
[25678]481      $errors[] = l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)');
482      $comment_action = 'reject';
[20090]483    }
[25678]484
[20090]485    // check content
486    if (!empty($comm['message']))
487    {
488      $comm['message'] = nl2br($comm['message']);
489    }
[25678]490
[20090]491    include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
[25678]492
[20090]493    if ($comment_action == 'validate')
494    {
[25678]495      // switch to guest user for get_sql_condition_FandF
496      $user_save = $user;
497      $user = build_user($conf['guest_id'], true);
498
499      // get pictures
500      $query = '
501SELECT
502    id, file, name, path
503  FROM '.IMAGES_TABLE.' AS i
504    JOIN '.IMAGE_CATEGORY_TABLE.' AS ci ON ci.image_id = i.id
505  WHERE id IN ('. implode(',', $this->images) .')
506    '.get_sql_condition_FandF(
507        array(
508          'forbidden_categories' => 'category_id',
509          'forbidden_images' => 'id'
510          ),
511        'AND'
512        ).'
513  GROUP BY i.id
514  ORDER BY '. DB_RANDOM_FUNCTION .'()
515  LIMIT '. $comm['nb_images'] .'
516;';
517      $pictures = hash_from_query($query, 'id');
518
519      // switch back to current user
520      $user = $user_save;
521      unset($user_save);
522
523      $share_key = array('share_key'=>'mail-' . substr(sha1($this->data['id'].$conf['secret_key']), 0, 11));
524
525      $tpl_vars = array(
526        'COL_URL' => $this->addShare($share_key, false),
527        'PARAMS' => $comm,
528        'derivative_params' => ImageStdParams::get_by_type(IMG_SQUARE),
[20090]529        );
[25678]530
531      // pictures infos
532      set_make_full_url();
533
534      foreach ($pictures as $row)
535      {
536        $name = render_element_name($row);
537
538        $tpl_vars['THUMBNAILS'][] = array(
539          'TN_ALT' => htmlspecialchars(strip_tags($name)),
540          'NAME' =>   $name,
541          'URL' =>    make_picture_url(array('image_id' => $row['id'])),
542          'THUMB' =>  DerivativeImage::url(IMG_SQUARE, $row),
543          );
544      }
545
546      unset_make_full_url();
547
548      $result = pwg_mail(
549        array(
550          'name' => $comm['recipient_name'],
551          'email' => $comm['recipient_email'],
552          ),
553        array(
554          'subject' => '['.$conf['gallery_title'].'] '.l10n('A photo collection by %s', $comm['sender_name']),
555          'mail_title' => $this->getParam('name'),
556          'mail_subtitle' => l10n('by %s', $comm['sender_name']),
557          'content_format' => 'text/html',
558          'from' => array(
559            'name' => $comm['sender_name'],
560            'email' => $comm['sender_email'],
561            )
562          ),
563        array(
564          'filename' => 'mail',
565          'dirname' => realpath(USER_COLLEC_PATH . 'template'),
566          'assign' => $tpl_vars,
567          )
568        );
569
[20090]570      if ($result == false)
571      {
[25678]572        $errors[] = l10n('Error while sending e-mail');
[20090]573      }
[24421]574      else
575      {
576        return true;
577      }
[20090]578    }
[25678]579
[20090]580    return $errors;
581  }
582
583  /**
[25678]584   * Generate a listing of the collection
585   *
586   * @param string[] $fields
587   * @return string
[20090]588   */
589  function serialize($params)
[20093]590  {
[25678]591    $fields = array_intersect($fields, array('id','file','name','url','path','date_creation','collection_add_date','filesize','width','height'));
592
[20090]593    $content = null;
[25678]594
[20090]595    // get images infos
596    $query = '
597SELECT
598    id,
599    file,
600    name,
[20099]601    path,
602    date_creation,
603    filesize,
604    width,
605    height,
606    add_date AS collection_add_date
[20090]607  FROM '.IMAGES_TABLE.'
[20099]608    JOIN '.COLLECTION_IMAGES_TABLE.' ON id = image_id
609  WHERE col_id = '.$this->data['id'].'
[20090]610  ORDER BY id
611;';
612    $pictures = hash_from_query($query, 'id');
[25678]613
[20090]614    if (count($pictures))
615    {
616      // generate csv
617      set_make_full_url();
618      $root_url = get_root_url();
[25678]619
[20090]620      $fp = fopen('php://temp', 'r+');
[25678]621      fputcsv($fp, $fields);
622
[20090]623      foreach ($pictures as $row)
624      {
625        $element = array();
[25678]626        foreach ($fields as $field)
[20090]627        {
628          switch ($field)
629          {
630          case 'name':
[24421]631            $element[] = render_element_name($row);
632            break;
[20090]633          case 'url':
[24421]634            $element[] = make_picture_url(array('image_id'=>$row['id'], 'image_file'=>$row['file']));
635            break;
[20090]636          case 'path':
[24421]637            $element[] = $root_url.ltrim($row['path'], './');
638            break;
[20099]639          default:
[24421]640            $element[] = $row[$field];
641            break;
[20090]642          }
643        }
644        if (!empty($element))
645        {
646          fputcsv($fp, $element);
647        }
648      }
[25678]649
[20090]650      rewind($fp);
651      $content = stream_get_contents($fp);
652      fclose($fp);
[25678]653
[20090]654      unset_make_full_url();
655    }
[25678]656
[20090]657    return $content;
658  }
[25678]659
[23361]660  /**
[25678]661   * Delete the collection
[23361]662   */
663  function delete()
664  {
665    $this->clearImages();
666    pwg_query('DELETE FROM '.COLLECTIONS_TABLE.' WHERE id = '.$this->data['id'].';');
667  }
[16591]668}
Note: See TracBrowser for help on using the repository browser.