Dotclear

source: plugins/gallery/trunk/class.dc.gallery.php @ 2264

Revision 2264, 38.6 KB checked in by bruno, 14 years ago (diff)

DC 2.1.7 support

  • Property svn:executable set to *
Line 
1<?php
2# -- BEGIN LICENSE BLOCK ----------------------------------
3#
4# This file is part of Dotclear 2 Gallery plugin.
5#
6# Copyright (c) 2004-2008 Bruno Hondelatte, and contributors.
7# Many, many thanks to Olivier Meunier and the Dotclear Team.
8# Licensed under the GPL version 2.0 license.
9# See LICENSE file or
10# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
11#
12# -- END LICENSE BLOCK ------------------------------------
13
14require_once (dirname(__FILE__).'/class.dc.rs.gallery.php');
15require_once (dirname(__FILE__).'/class.metaplus.php');
16
17/**
18 * Main Gallery class
19 *
20 * Handles database back-end requests to retrieve or update images as well as posts
21 *
22 * @uses dcMedia
23 * @package Gallery
24 */
25class dcGallery extends dcMedia
26{
27     /** @var array orderby order combo list for galeries */     
28     public $orderby;
29     /** @var array sortby sort combo list for galeries */ 
30     public $sortby;
31
32     /** @var boolean without_password Disallow entries password protection */ 
33     public $without_password = true;
34
35     public $settings;
36     /**
37      * Constructor
38      *
39      * Create a new gallery manager
40      *
41      * @param dcCore $core the core object
42      * @access public
43      * @return void
44      */
45     public function __construct($core)
46     {
47          parent::__construct($core);
48          $this->orderby= array(__('Date') => 'P.post_dt',
49           __('Title') => 'P.post_title',
50           __('Filename') => 'M.media_file',
51           __('URL') => 'P.post_url'
52          );
53          $this->sortby = array(__('Ascending') => 'ASC',
54          __('Descending') => 'DESC' );
55          if (!version_compare(DC_VERSION,'2.2alpha','>=')) {
56               $core->blog->settings->setNamespace('gallery');
57               $this->settings =& $core->blog->settings->gallery;
58          } else {
59               $core->blog->settings->setNamespace('gallery');
60               $this->settings =& $core->blog->settings;
61          }
62     }
63     
64     /**
65      * getGalleries
66      *
67      * Retrieves galleries from database.
68      *
69      * @param array $params  gallery parameters (see dcBlog->getPosts for available parameters)
70      * @param boolean $count_only  only count results
71      * @access public
72      * @return void
73      */
74     public function getGalleries ($params=array(), $count_only=false) {
75          $params['post_type']='gal';
76          $rs= $this->core->blog->getPosts($params,$count_only);
77          $rs->extend('rsExtGallery');
78          return $rs;
79     }
80
81     /**
82      * getGalItems
83      *
84      * Retrieves gallery items from database (simple select, no flourishes).
85      * @see getGalImageMedia for enhanced requests
86      *
87      * @param array $params  gallery parameters (see dcBlog->getPosts for available parameters)
88      * @param boolean $count_only  only count results
89      * @access public
90      * @return void
91      */
92     public function getGalItems ($params=array(), $count_only=false) {
93          $params['post_type']='galitem';
94          $rs=$this->core->blog->getPosts($params,$count_only);
95          $rs->extend('rsExtImage');
96          return $rs;
97     }
98
99     /**
100      * getGalTheme
101      *
102      * Retrieves gallery theme from gallery metadata
103      * Theme can be different according to context
104      * a wished theme can be specified, but it will be checked before
105      *
106      * @param record $gal the gallery record
107      * @param string $context context to fetch theme from (integ, gal)
108      * @param string $wished wished theme (theme switcher, for instance)
109      * @access public
110      * @return string the gallery theme name
111      */
112     public function getGalTheme ($gal,$context='gal',$wished=null) {
113          if ($wished != null) {
114               if ($this->themeExists($wished))
115                    return $wished;
116          }
117          $meta = $this->core->meta->getMetaArray($gal->post_meta);
118          if ($context == 'gal') {
119               if (isset($meta['galtheme']))
120                    return $meta['galtheme'][0];
121               return $this->settings->gallery_default_theme;
122          } else {
123               if (isset($meta['galtheme'.$context])) {
124                    $theme = $meta['galtheme'.$context][0];
125               } else {
126                    $theme =  $this->settings->gallery_default_integ_theme;
127               }
128
129               if ($theme == 'sameasgal') {
130                    if (isset($meta['galtheme']))
131                         return $meta['galtheme'][0];
132                    else
133                         return $this->settings->gallery_default_theme;
134
135               } else {
136                    return $theme;
137               }
138          }
139     }
140
141     /**
142      * getAllGalleryComments
143      *
144      * Retrieves number of comments/trackbacks for all images from a gallery.
145      *
146      * @param string $gal_id the gallery id, null to fetch for all galeries
147      * @access public
148      * @return recordSet the retrieved recordset
149      */
150     public function getAllGalleryComments($gal_id=null) {
151          $prefix=$this->core->prefix;
152          $strReq = "SELECT G.post_id, COALESCE(SUM(I.nb_comment),0) as nb_comment, ".
153               "COALESCE(SUM(I.nb_trackback),0) as nb_trackback ".
154               "FROM ".$prefix."post G ".
155               "LEFT JOIN (".$prefix."meta M ";
156          if (DC_DBDRIVER == 'pgsql')
157               $strReq .= "INNER JOIN ".$prefix."post I ON I.post_id=M.meta_id::bigint AND I.post_type='galitem') ";
158          else
159               $strReq .= "INNER JOIN ".$prefix."post I ON I.post_id=M.meta_id AND I.post_type='galitem') ";
160
161          $strReq .= "ON M.post_id=G.post_id AND M.meta_type='galitem' ".
162               "WHERE G.post_type='gal' and G.blog_id = '".$this->con->escape($this->core->blog->id)."' ";
163          if ($gal_id != null)
164               $strReq .= "AND G.post_id='".$this->con->escape($gal_id)."' ";
165          $strReq .= "GROUP BY G.post_id,G.post_type";
166          $rs = $this->con->select($strReq);
167          return $rs;
168     }
169
170     /**
171      * withoutPassword
172      * Disallows entries password protection. You need to set it to
173      * <var>false</var> while serving a public blog.
174      *
175      * @param boolean $v true to disallow password
176      * @access public
177      * @return void
178      */
179     public function withoutPassword($v)
180     {
181          $this->without_password = (boolean) $v;
182     }
183
184     /**
185          ### GALLERY FILTERS RETRIEVAL ###
186     */
187
188     /**
189      * getGalFilters
190      *
191      * Retrieve all gallery filters definition from a gallery recordset
192      *
193      * @param record $rs the record to retrieve filters from
194      * @access public
195      * @return void
196      */
197     public function getGalFilters($rs) {
198          $meta = $this->core->meta->getMetaArray($rs->post_meta);
199          $filters = array();
200          $filtered=false;
201          if (isset($meta['galrecursedir'])) {
202               $filters['recurse_dir']=$meta['galrecursedir'][0];
203               $filtered=true;
204          }
205          if (isset($meta['galsubcat'])) {
206               $filters['sub_cat']=$meta['galsubcat'][0];
207               $filtered=true;
208          }
209          if (isset($meta['galmediadir'])) {
210               $filters['media_dir']=$meta['galmediadir'];
211               $filtered=true;
212          }
213          if (isset($meta['galcat'])) {
214               $filters['cat_id']=$meta['galcat'][0];
215               $filtered=true;
216          }
217          if (isset($meta['galtag'])) {
218               $filters['tag']=$meta['galtag'][0];
219               $filtered=true;
220          }
221          if (isset($meta['galuser'])) {
222               $filters['user_id']=$meta['galuser'][0];
223               $filtered=true;
224          }
225          $filters['filter_enabled']=$filtered;
226          return $filters;
227     }
228
229     /**
230      * getGalOrder
231      *
232      * Retrieve all gallery ordering definition from a gallery recordset
233      *
234      * @param record $rs the record to retrieve filters from
235      * @access public
236      * @return void
237      */
238     public function getGalOrder($rs) {
239          $meta = $this->core->meta->getMetaArray($rs->post_meta);
240          $order = array();
241          if (isset($meta['galorderby'])){
242               $order['orderby']=$meta['galorderby'][0];
243          } else {
244               $order['orderby']="P.post_dt";
245          }
246          if (isset($meta['galsortby'])){
247               $order['sortby']=$meta['galsortby'][0];
248          } else {
249               $order['sortby']="ASC";
250          }
251          return $order;
252     }
253
254
255     /**
256      * getGalOrder
257      *
258      * Retrieve all gallery filters and ordering definition from a gallery
259      * recordset.
260      *
261      * @param record $rs the record to retrieve filters from
262      * @access public
263      * @return void
264      */
265     public function getGalParams($rs) {
266          return array_merge($this->getGalFilters($rs),$this->getGalOrder($rs));
267     }
268
269
270     /**
271          ### IMAGES RETRIEVAL ###
272     */
273
274     /**
275      * getGalImageMedia
276      *
277      * Retrieve all media & posts associated to a gallery id.
278      * <b>$params</b> is an array taking one of the following parameters :
279      * - no_content : dont retrieve entry contents (ie image description)
280      * - post_type: Get only entries with given type (default "post")
281      * - post_id: (integer) Get entry with given post_id
282      * - post_url: Get entry with given post_url field
283      * - user_id: (integer) Get entries belonging to given user ID
284      * - post_status: (integer) Get entries with given post_status
285      * - post_selected: (boolean) Get select flaged entries
286      * - post_year: (integer) Get entries with given year
287      * - post_month: (integer) Get entries with given month
288      * - post_day: (integer) Get entries with given day
289      * - post_lang: Get entries with given language code
290      * - search: Get entries corresponding of the following search string
291      * - sql: Append SQL string at the end of the query
292      * - from: Append SQL string after "FROM" statement in query
293      * - order: Order of results (default "ORDER BY post_dt DES")
294      * - limit: Limit parameter
295      *
296      * @param array $params  parameters (see above for values)
297      * @param mixed $count_only  only count items
298      * @access public
299      * @return record a recordset
300      */
301     public function getGalImageMedia ($params=array(),$count_only=false) {
302         
303          if ($count_only)
304          {
305               $strReq = 'SELECT count(P.post_id) ';
306          }
307          else
308          {
309               if (!empty($params['no_content'])) {
310                    $content_req = '';
311               } else {
312                    $content_req =
313                    'P.post_excerpt, P.post_excerpt_xhtml, '.
314                    'P.post_content, P.post_content_xhtml, P.post_notes, ';
315               }
316               
317               $fields =
318               'P.post_id, P.blog_id, P.user_id, P.cat_id, P.post_dt, '.
319               'P.post_tz, P.post_creadt, P.post_upddt, P.post_format, P.post_password, '.
320               'P.post_url, P.post_lang, P.post_title, '.$content_req.
321               'P.post_type, P.post_meta, P.post_status, P.post_selected, '.
322               'P.post_open_comment, P.post_open_tb, P.nb_comment, P.nb_trackback, '.
323               'U.user_name, U.user_firstname, U.user_displayname, U.user_email, '.
324               'U.user_url, '.
325               'C.cat_title, C.cat_url ';
326               $fields.=", M.media_file, M.media_id, M.media_path, M.media_title, M.media_meta, M.media_dt, M.media_creadt, M.media_upddt, M.media_private, M.media_dir ";
327               
328               $strReq = 'SELECT '.$fields;
329          }
330         
331          $strReq .=
332          'FROM '.$this->core->prefix.'post P ';
333
334          # Cut asap request with gallery id if requested
335          if (!empty($params['gal_id']) || !empty($params['gal_url'])) {
336               $strReq .= 'INNER JOIN '.$this->core->prefix.'meta GM ';
337               if (DC_DBDRIVER == 'pgsql')
338                    $strReq .= 'on GM.meta_type=\'galitem\' AND P.post_id=GM.meta_id::bigint ';
339               else
340                    $strReq .= 'on GM.meta_type=\'galitem\' AND P.post_id=GM.meta_id ';
341               $strReq .= 'INNER JOIN '.$this->core->prefix.'post G '.
342               'on GM.post_id = G.post_id AND G.post_type=\'gal\' ';
343               if (!empty($params['gal_id'])) {
344                    $strReq .= 'AND G.post_id=\''.$this->con->escape($params['gal_id']).'\' '; 
345               } else {
346                    $strReq .= 'AND G.post_url=\''.$this->con->escape($params['gal_url']).'\' '; 
347               }
348          }
349
350
351          $strReq .=
352          'INNER JOIN '.$this->core->prefix.'user U ON U.user_id = P.user_id and P.post_type=\'galitem\' '.
353          'LEFT JOIN '.$this->core->prefix.'category C ON P.cat_id = C.cat_id '.
354          'INNER JOIN '.$this->core->prefix.'post_media PM ON P.post_id = PM.post_id '.
355          'INNER JOIN '.$this->core->prefix.'media M on M.media_id = PM.media_id ';
356     
357                   
358          if (!empty($params['tag'])) {
359               $strReq .= 'INNER JOIN '.$this->core->prefix.'meta PT on P.post_id=PT.post_id and PT.meta_type=\'tag\' and PT.meta_id=\''
360                    .$this->con->escape($params['tag']).'\' ';
361          }
362          if (!empty($params['from'])) {
363               $strReq .= $params['from'].' ';
364          }
365         
366          $strReq .=
367          "WHERE P.blog_id = '".$this->con->escape($this->core->blog->id)."' ";
368         
369          if (!empty($params['gal_id']))
370               $strReq .= " AND G.post_id='".$this->con->escape($params['gal_id'])."' ";
371          if (!empty($params['gal_url']))
372               $strReq .= " AND G.post_url='".$this->con->escape($params['gal_url'])."' ";
373
374          if (!$this->core->auth->check('contentadmin',$this->core->blog->id)) {
375               $strReq .= 'AND ((P.post_status = 1 ';
376               
377               if ($this->without_password) {
378                    $strReq .= 'AND P.post_password IS NULL ';
379               }
380               $strReq .= ') ';
381               
382               if ($this->core->auth->userID()) {
383                    $strReq .= "OR P.user_id = '".$this->con->escape($this->core->auth->userID())."')";
384               } else {
385                    $strReq .= ') ';
386               }
387          }
388         
389          #Adding parameters
390               $strReq .= "AND P.post_type = 'galitem' ";
391         
392          if (!empty($params['post_id'])) {
393               $strReq .= 'AND P.post_id = '.(integer) $params['post_id'].' ';
394          }
395         
396          if (!empty($params['post_url'])) {
397               $strReq .= "AND P.post_url = '".$this->con->escape($params['post_url'])."' ";
398          }
399          if (!empty($params['user_id'])) {
400               $strReq .= "AND U.user_id = '".$this->con->escape($params['user_id'])."' ";
401          }
402          if (!empty($params['media_dir'])) {
403               if (!is_array($params['media_dir'])) {
404                    $params['media_dir'] = array($params['media_dir']);
405               }
406               if (!empty($params['recurse_dir'])) {
407                    if ($params['media_dir'][0] != '.') {
408                         $strReq .= "AND ( M.media_dir = '".$this->con->escape($params['media_dir'][0])."' ";
409                         $strReq .= "     OR M.media_dir LIKE '".$this->con->escape($params['media_dir'][0])."/%') ";
410                         }
411               } else {
412                    $strReq .= "AND M.media_dir ".$this->con->in($params['media_dir'])." ";
413               }
414          }
415
416          /* Categories filters */
417          $cat_subcond = '';
418          $cat_cond = '';
419          $cat_not = false;
420          if (!empty($params['cat_id']))
421          {
422               $cat_not = !empty($params['cat_id_not']);
423               
424               if (is_array($params['cat_id'])) {
425                    array_walk($params['cat_id'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}'));
426               } else {
427                    $params['cat_id'] = array((integer) $params['cat_id']);
428               }
429               
430               if (empty($params['sub_cat'])) {
431                    $cat_cond = 'P.cat_id '.$this->con->in($params['cat_id']);
432               } else {
433                    $cat_subcond = 'cat_id '.$this->con->in($params['cat_id']);
434               }
435          }
436          elseif (!empty($params['cat_url']))
437          {
438               $cat_not = !empty($params['cat_url_not']);
439               
440               if (is_array($params['cat_url'])) {
441                    array_walk($params['cat_url'],create_function('&$v,$k','$v=(string)$v;'));
442               } else {
443                    $params['cat_url'] = array((string) $params['cat_url']);
444               }
445               
446               if (empty($params['sub_cat'])) {
447                    $cat_cond = 'C.cat_url '.$this->con->in($params['cat_url']);
448               } else {
449                    $cat_subcond = 'cat_url '.$this->con->in($params['cat_url']);
450               }
451          }
452         
453          if ($cat_subcond) # we want posts from given categories and their children
454          {
455               $rs = $this->con->select(
456                    'SELECT cat_lft, cat_rgt FROM '.$this->core->prefix.'category '.
457                    "WHERE blog_id = '".$this->con->escape($this->core->blog->id)."' ".
458                    'AND '.$cat_subcond
459               );
460               $cat_borders = array();
461               while ($rs->fetch()) {
462                    $cat_borders[] = '(C.cat_lft BETWEEN '.$rs->cat_lft.' AND '.$rs->cat_rgt.')';
463               }
464               if (count($cat_borders) > 0) {
465                    $strReq .= ' AND '.($cat_not ? ' NOT' : '').'(P.cat_id IS NOT NULL AND('.implode(' OR ',$cat_borders).')) ';
466               }
467          } elseif ($cat_cond) { # without children
468               $strReq .= ' AND '.($cat_not ? ' NOT' : '').'(P.cat_id IS NOT NULL AND '.$cat_cond.') ';
469          }
470
471          if (isset($params['post_status'])) {
472               $strReq .= 'AND post_status = '.(integer) $params['post_status'].' ';
473          }
474         
475          if (isset($params['post_selected'])) {
476               $strReq .= 'AND post_selected = '.(integer) $params['post_selected'].' ';
477          }
478         
479          if (!empty($params['post_year'])) {
480               $strReq .= 'AND '.$this->con->dateFormat('post_dt','%Y').' = '.
481               "'".sprintf('%04d',$params['post_year'])."' ";
482          }
483         
484          if (!empty($params['post_month'])) {
485               $strReq .= 'AND '.$this->con->dateFormat('post_dt','%m').' = '.
486               "'".sprintf('%02d',$params['post_month'])."' ";
487          }
488         
489          if (!empty($params['post_day'])) {
490               $strReq .= 'AND '.$this->con->dateFormat('post_dt','%d').' = '.
491               "'".sprintf('%02d',$params['post_day'])."' ";
492          }
493         
494          if (!empty($params['post_lang'])) {
495               $strReq .= "AND P.post_lang = '".$this->con->escape($params['post_lang'])."' ";
496          }
497                if (!empty($params['sql'])) {
498                        $strReq .= $params['sql'].' ';
499                }
500
501
502          if (!$count_only)
503          {
504               if (!empty($params['order'])) {
505                    $order = $this->con->escape($params['order']);
506               } else if (!empty($params['orderby']) && !empty($params['sortby'])) {
507                    $order = $this->con->escape($params['orderby']).' '.
508                         $this->con->escape($params['sortby']);
509               } else {
510                    $order = "P.post_dt ASC, P.post_id ASC";
511               }
512
513               $strReq .= 'GROUP BY '.$fields.' ';
514               $strReq .= 'ORDER BY '.$order;
515               
516          }
517          if (!$count_only && !empty($params['limit'])) {
518               $strReq .= $this->con->limit($params['limit']);
519          }
520          if (!empty($params['debug']))
521               echo "*** DEBUG SQL : [".$strReq."]";
522          $rs = $this->con->select($strReq);
523          $rs->core = $this->core;
524
525          $rs->_nb_media = array();
526          $rs->extend('rsExtPost');
527                   
528         
529          # --BEHAVIOR-- coreBlogGetPosts
530          $this->core->callBehavior('coreBlogGetPosts',$rs);
531          $rs->extend('rsExtImage');
532          return $rs;
533
534     
535     }
536
537
538     /**
539          ### IMAGES & MEDIA MAINTENANCE RETRIEVAL ###
540     */
541     /* Image handlers
542     ------------------------------------------------------- */
543
544     /**
545      * getMediaForGalItems
546      *
547      * Creates thumbnails for a given media
548      *
549      * @param rs $cur current media item
550      * @param String $f file name
551      * @param boolean $force if true, force thumbnail regeneration
552      * @access public
553      * @return void
554      */
555     public function imageThumbCreate($cur,$f, $force=true)
556     {
557          $file = $this->pwd.'/'.$f;
558         
559          if (!file_exists($file)) {
560               return false;
561          }
562         
563          $p = path::info($file);
564          $thumb = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s');
565         
566          try
567          {
568               $img = new imageTools();
569               $img->loadImage($file);
570               
571               $w = $img->getW();
572               $h = $img->getH();
573               if ($force) {
574                    $this->imageThumbRemove($f);
575               }
576               
577               foreach ($this->thumb_sizes as $suffix => $s) {
578                    $thumb_file = sprintf($thumb,$suffix);
579                    if (!$force && file_exists($thumb_file))
580                         continue;
581                    if ($s[0] > 0 && ($suffix == 'sq' || $w > $s[0] || $h > $s[0])) {
582                         $img->resize($s[0],$s[0],$s[1]);
583                         $img->output('jpeg', $thumb_file, 80);
584                    }
585               }
586               $img->close();
587          }
588          catch (Exception $e)
589          {
590               if ($cur === null) { # Called only if cursor is null (public call)
591                    throw $e;
592               }
593          }
594     }
595
596     /**
597      * getMediaForGalItems
598      *
599      * Retrieve media ids for given item ids
600      *
601      * @param Array $post_ids  list of item ids
602      * @access public
603      * @return record the recordset
604      */
605     function getMediaForGalItems($post_ids) {
606               $strReq = 'SELECT P.post_id,M.media_id '.
607                    'FROM '.$this->core->prefix.'post P '.
608                    'INNER JOIN '.$this->core->prefix.'post_media PM on P.post_id=PM.post_id '.
609                    'INNER JOIN '.$this->core->prefix.'media M on PM.media_id=M.media_id '.
610                    "WHERE P.blog_id = '".$this->con->escape($this->core->blog->id)."' ".
611                    "AND P.post_id ".$this->con->in($post_ids);
612               $rs = $this->con->select($strReq);
613               return $rs;
614     }
615
616
617     /**
618      * getMediaWithoutGalItems
619      *
620      * Retrieve media items not associated to a image post in a given directory
621      *
622      * @param string $media_dir  mediai directory to parse
623      * @param boolean $subdirs if true, include subdirectories
624      * @access public
625      * @return record the recordset
626      */
627     function getMediaWithoutGalItems($media_dir,$subdirs=false) {
628          $strReq = 'SELECT M.media_id, M.media_dir, M.media_file '.
629               'FROM '.$this->core->prefix.'media M '.
630               'LEFT JOIN ('.
631                    'SELECT PM.post_id,PM.media_id FROM '.$this->core->prefix.'post_media PM '.
632                    'INNER JOIN '.$this->core->prefix.'post P '.
633                    'ON PM.post_id = P.post_id '.
634                    'AND P.blog_id = \''.$this->con->escape($this->core->blog->id).'\' '.
635                    'AND P.post_type = \'galitem\') PM2 '.
636               'ON M.media_id = PM2.media_id '.
637               'WHERE M.media_path="'.$this->path.'" and PM2.post_id IS NULL ';
638          if ($subdirs) {
639               if ($media_dir != '.') {
640                    $strReq .= "AND ( M.media_dir = '".$this->con->escape($media_dir)."' ";
641                    $strReq .= "     OR M.media_dir LIKE '".$this->con->escape($media_dir)."/%') ";
642               }
643          } else {
644               $strReq .= 'AND media_dir = \''.$this->con->escape($media_dir).'\'';
645          }
646          $rs = $this->con->select($strReq);
647          return $rs;
648     }
649
650     /**
651      * getImageFromMedia
652      *
653      * Retrieve image from a given media_id
654      *
655      * @param string $media_id the media id
656      * @access public
657      * @return record the recordset
658      */
659     function getImageFromMedia($media_id) {
660          $strReq =
661          'SELECT P.post_id '.
662          'FROM '.$this->core->prefix."post P, ".$this->table.' M, '.$this->table_ref.' PM '.
663          "WHERE P.post_id = PM.post_id AND M.media_id = PM.media_id ".
664          "AND M.media_id = '".$media_id."' AND P.post_type='galitem' ".
665          "AND P.blog_id = '".$this->con->escape($this->core->blog->id)."' ";
666         
667          $rs = $this->con->select($strReq);
668         
669          $res = array();
670         
671          while ($rs->fetch()) {
672               $res[] = $rs->post_id;
673          }
674         
675          return $res;
676     }
677
678     /**
679      * getNewMedia
680      *
681      * Retrieve media not yet created in a given directory
682      *
683      * @param mixed $media_dir  the media directory to scan
684      * @access public
685      * @return array list of new media file names
686      */
687     function getNewMedia($media_dir) {
688          $strReq =
689          'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '.
690          'media_creadt, media_upddt, media_private, user_id '.
691          'FROM '.$this->table.' '.
692          "WHERE media_path = '".$this->path."' ".
693          "AND media_dir = '".$this->con->escape($media_dir)."' ";
694         
695          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
696          {
697               $strReq .= 'AND (media_private <> 1 ';
698               
699               if ($this->core->auth->userID()) {
700                    $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'";
701               }
702               $strReq .= ') ';
703          }
704         
705          $strReq .= 'ORDER BY LOWER(media_file) ASC';
706         
707          $rs = $this->con->select($strReq);
708         
709          $this->chdir($media_dir);
710          filemanager::getDir();
711         
712          $p_dir = $this->dir;
713         
714          $f_reg = array();
715          $res=array();
716         
717          while ($rs->fetch())
718          {
719               # File in subdirectory, forget about it!
720               if (dirname($rs->media_file) != '.' && dirname($rs->media_file) != $this->relpwd) {
721                    continue;
722               }
723               
724               if ($this->inFiles($rs->media_file))
725               {
726                    $f_reg[$rs->media_file] = 1;
727               }
728          }
729         
730         
731          # Check files that don't exist in database and create them
732          foreach ($p_dir['files'] as $f)
733          {
734               if (!isset($f_reg[$f->relname])) {
735                    $res[]=$f->basename;
736               }
737          }
738          return $res;
739     }
740
741
742     /**
743      * getMediaWithoutThumbs
744      *
745      * Retrieve media with no thumbnails in the given directory
746      *
747      * @param mixed $media_dir  the media directory to scan
748      * @access public
749      * @return array the list of media IDs
750      */
751     function getMediaWithoutThumbs($media_dir) {
752          $this->chdir($media_dir);
753          $this->getDir('image');
754          $dir =& $this->dir;
755          $items=array_values($dir['files']);
756          $ids=array();
757          foreach ($items as $item) {
758               if (empty($item->media_thumb)) {
759                    $ids[$item->media_id]=$item->basename;
760               } else {
761                    foreach ($this->thumb_sizes as $suffix => $s) {
762                         if (empty($item->media_thumb[$suffix])) {
763                              $ids[$item->media_id]=$item->basename;
764                              continue(2);
765                         }
766                    }
767               }
768          }
769          return $ids;
770     }
771
772     /**
773          ### IMAGES & MEDIA ORPHANS REMOVAL ###
774     */
775
776
777     /**
778      * deleteOrphanMedia
779      *
780      * Delete media entries with no physical files associated
781      *
782      * @param string $media_dir the media directory to scan
783      * @param boolean $count_only if true, only return the number of orphan media
784      * @access public
785      * @return void
786      */
787     function deleteOrphanMedia($media_dir, $count_only=false) {
788          $strReq =
789          'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '.
790          'media_creadt, media_upddt, media_private, user_id '.
791          'FROM '.$this->table.' '.
792          "WHERE media_path = '".$this->path."' ".
793          "AND media_dir = '".$this->con->escape($media_dir)."' ";
794         
795          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
796          {
797               $strReq .= 'AND (media_private <> 1 ';
798               
799               if ($this->core->auth->userID()) {
800                    $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'";
801               }
802               $strReq .= ') ';
803          }
804          $rs = $this->con->select($strReq);
805          $count=0;
806          while ($rs->fetch())
807          {
808               if (!file_exists($this->pwd."/".$rs->media_file)) {
809                    # Physical file does not exist remove it from DB
810                    # Because we don't want to erase everything on
811                    # dotclear upgrade, do it only if there are files
812                    # in directory and directory is root
813                    if ($count_only) {
814                         $count++;
815                    } else {
816                         $this->con->execute(
817                              'DELETE FROM '.$this->table.' '.
818                              "WHERE media_path = '".$this->con->escape($this->path)."' ".
819                              "AND media_file = '".$this->con->escape($rs->media_file)."' "
820                         );
821                    }
822               }
823          }
824          return $count;
825     }
826
827     /**
828      * deleteOrphanItems
829      *
830      * Delete Items no more associated to media
831      *
832      * @access public
833      * @param boolean $count_only if true, only return the number of orphan items, do not delete
834      * @return void
835      */
836     function deleteOrphanItems($count_only=false) {
837          if (!$this->core->auth->check('usage',$this->core->blog->id)) {
838               return;
839          }
840          $strReq = 'SELECT P.post_id,P.post_title '.
841          'FROM '.$this->core->prefix.'post P '.
842               'LEFT JOIN '.$this->core->prefix.'post_media PM ON P.post_id = PM.post_id '.
843               'WHERE PM.media_id IS NULL AND P.post_type=\'galitem\' AND P.blog_id = \''.$this->con->escape($this->core->blog->id).'\'';
844          $rs = $this->con->select($strReq);
845          if ($count_only) {
846               return $rs->count();
847          }
848          $count=0;
849          while ($rs->fetch()) {
850               try {
851                    $this->core->blog->delPost($rs->post_id);
852                    $count++;
853               } catch (Exception $e) {
854                    // Ignore rights problems ...
855               }
856          }
857          return $count;
858     }
859
860     /**
861          ### IMAGES & MEDIA CREATION ###
862     */
863     /**
864      * getExifDate
865      *
866      * Returns the exif date from media metadata
867      *
868      * @param simpleXML $meta metadata
869      * @param date $default default date to return if exif date is not readable
870      * @access public
871      * @return string the exif date (converted to string)
872      */
873     function getExifDate($meta,$default) {
874          $post_dt=$default;
875          if ($meta !== false){
876               if (count($meta->xpath('DateTimeOriginal'))) {
877                    if ($meta->DateTimeOriginal != '') {
878                         $media_ts = strtotime($meta->DateTimeOriginal);
879                         $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts);
880                         $post_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o);
881                    }
882               }
883          }
884          return $post_dt;
885     }
886
887
888     /**
889      * fixImageExif
890      *
891      * Fix post date to media exif date
892      *
893      * @param string $img_id post-image id
894      * @access public
895      * @return void
896      */
897     function fixImageExif($img_id) {
898          $rs = $this->getGalImageMedia(array('post_id' => $img_id));
899          if ($rs->fetch()) {
900               $media=$this->readMedia($rs);
901               $new_dt=$this->getExifDate($media->media_meta,$rs->post_dt);
902         
903               $strReq =
904               "UPDATE ".$this->core->prefix."post ".
905               "SET post_dt = '".$this->con->escape($new_dt)."' ".
906               "WHERE post_id = '".$rs->post_id."'";
907               $this->con->execute($strReq);
908          }
909     }
910
911     /**
912      * createPostForMedia
913      *
914      * Creates a new Post for a given media
915      *
916      * @param dcMedia $media the media record
917      * @param boolean $update_timestamp if true, set the post date to the media exif date
918      * @access public
919      * @return string the new post ID
920      */
921     function createPostForMedia($media,$update_timestamp=false) {
922          $imgref = $this->getImageFromMedia($media->media_id);
923          if (sizeof($imgref)!=0)
924               return;
925          if (!$media->media_image)
926               return;
927         
928          $cur = $this->con->openCursor($this->core->prefix.'post'); 
929          $cur->post_type='galitem';
930          if (trim($media->media_title) != '')
931               $cur->post_title = $media->media_title;
932          else
933               $cur->post_title = basename($media->file);
934         
935          $cur->cat_id = null;
936          $post_dt = $media->media_dtstr;
937     
938          if ($update_timestamp && $media->type == 'image/jpeg') {
939               $post_dt = $this->getExifDate($media->media_meta,$post_dt);
940          }
941          $cur->post_dt = $post_dt;
942          $cur->post_format = 'wiki';
943          $cur->post_password = null;
944          $cur->post_lang = $this->core->auth->getInfo('user_lang');
945          $cur->post_excerpt = '';
946          $cur->post_excerpt_xhtml = '';
947          $cur->post_content = "///html\n<p></p>\n///";
948          $cur->post_content_xhtml = "";
949          $cur->post_notes = null;
950          $cur->post_status = 1;
951          $cur->post_selected = 0;
952          $cur->post_open_comment = 1;
953          $cur->post_open_tb = 1;
954          $cur->post_url = preg_replace('/\.[^.]+$/','',substr($media->file,strlen($this->root)+1));
955
956         
957          $cur->user_id = $this->core->auth->userID();
958          $return_id=0;
959     
960          try
961          {
962               $return_id = $this->core->blog->addPost($cur);
963               // Attach media to post
964               $this->addPostMedia($return_id,$media->media_id);
965               return $return_id;
966          }
967          catch (Exception $e)
968          {
969               $this->core->error->add($e->getMessage());
970               throw $e;
971          }
972
973     }
974
975     /**
976      * removeAllPostMedia
977      *
978      * remove all media links from a post
979      *
980      * @param string $post_id the post id
981      * @access public
982      * @return void
983      */
984     public function removeAllPostMedia($post_id) {
985          $media = $this->getPostMedia($post_id);
986          foreach ($media as $medium) {
987               $this->removePostMedia($post_id,$medium->media_id);
988          }
989     }
990
991     /**
992      * createThumbs
993      *
994      * creates all thumbs for a given media
995      * given its id
996      *
997      * @param string $media_id  the media id
998      * @access public
999      * @return void
1000      */
1001     public function createThumbs($media_id,$force=true) {
1002          $media = $this->getFile($media_id);
1003          if ($media == null) {
1004               throw new Exception (__('Media not found'));
1005          }
1006          $this->chdir(dirname($media->relname));
1007          if ($media->media_type == 'image')
1008               $this->imageThumbCreate($media,$media->basename,$force);
1009     }
1010
1011
1012     /**
1013      * getNextGallery
1014      *
1015      * Returns a record with post id, title and date for next or previous post
1016      * according to the post ID and timestamp given.
1017      * $dir can be 1 (next post) or -1 (previous post).
1018      *
1019      * @param integer $post_id  the post id
1020      * @param string $ts  post timestamp
1021      * @param integer $dir search direction
1022      * @access public
1023      * @return record the record
1024      */
1025     public function getNextGallery($post_id,$ts,$dir)
1026     {
1027          $dt = date('Y-m-d H:i:s',(integer) $ts);
1028          $post_id = (integer) $post_id;
1029         
1030          if($dir > 0) {
1031               $sign = '>';
1032               $order = 'ASC';
1033          }
1034          else {
1035               $sign = '<';
1036               $order = 'DESC';
1037          }
1038          $params['limit'] = 1;
1039          $params['order'] = 'post_dt '.$order.', P.post_id '.$order;
1040          $params['sql'] =
1041          'AND ( '.
1042          "    (post_dt = '".$this->con->escape($dt)."' AND P.post_id ".$sign." ".$post_id.") ".
1043          "    OR post_dt ".$sign." '".$this->con->escape($dt)."' ".
1044          ') ';
1045         
1046          $rs = $this->getGalleries($params);
1047          if ($rs->isEmpty()) {
1048               return null;
1049          }
1050         
1051          return $rs;
1052     }
1053
1054
1055
1056     /**
1057      * getNextGalleryItem
1058      *
1059      * retrieves next gallery item, optionnaly in a given gallery
1060      *
1061      * @param record $post current gallery item record
1062      * @param integer $dir direction (+1 for next, -1 for previous)
1063      * @param string $gal_url gallery url (null for no gallery)
1064      * @param integer $nb number of items to retrieve
1065      * @access public
1066      * @return record the next item(s)
1067      */
1068     public function getNextGalleryItem($post,$dir,$gal_url=null,$nb=1) {
1069          if ($gal_url != null) {
1070               $gal = $this->getGalleries(array('post_url' => $gal_url));
1071               $params = $this->getGalOrder($gal);
1072               if ($dir < 0) {
1073                    $sign= ($params['sortby']=='ASC') ? '<':'>';
1074                    $params['sortby'] = ($params['sortby']=='ASC') ? 'DESC' : 'ASC';
1075               } else {
1076                    $sign= ($params['sortby']=='ASC') ? '>':'<';;
1077               }
1078          } else {
1079               if($dir > 0) {
1080                    $sign = '>';
1081                    $params['orderby'] = 'P.post_dt';
1082                    $params['sortby'] = 'ASC';
1083               }
1084               else {
1085                    $sign = '<';
1086                    $params['orderby'] = 'P.post_dt';
1087                    $params['sortby'] = 'DESC';
1088               }
1089          }
1090          $params['order'] = $this->con->escape($params['orderby']).' '.
1091               $this->con->escape($params['sortby']).', P.post_id '.
1092               $this->con->escape($params['sortby']);
1093          switch($params['orderby']) {
1094               case "P.post_dt" : 
1095                    $field_value = $post->post_dt;
1096                    break;
1097               case "P.post_title" : 
1098                    $field_value = $post->post_title;
1099                    break;
1100               case "M.media_file" : 
1101                    $field_value = $post->media_file;
1102                    break;
1103               case "P.post_url" : 
1104                    $field_value = $post->post_url;
1105                    break;
1106               default:
1107                    $field_value = $post->post_dt;
1108                    break;
1109          }
1110          $post_id=$post->post_id;
1111          $params['sql'] =
1112               'AND ( '.
1113               "    (".$params['orderby']." = '".$this->con->escape($field_value).
1114               "' AND P.post_id ".$sign." ".$post_id.") ".
1115               "    OR ".$params['orderby']." ".$sign." '".$this->con->escape($field_value)."' ".
1116               ') ';
1117          $params['post_type'] = 'galitem';
1118          $params['limit'] = array(0,$nb);
1119          $params['gal_url'] = $gal_url;
1120          $rs = $this->getGalImageMedia($params,false);
1121          if ($rs->isEmpty()) {
1122               return null;
1123          }
1124
1125          return $rs;
1126     }
1127
1128     /**
1129      * getGalleryItemPage
1130      *
1131      * retrieves gallery page containing an image
1132      *
1133      * @param string $img_url image url
1134      * @param string $gal_url gallery url
1135      * @access public
1136      * @return int the page
1137      */
1138     public function getGalleryItemPage($img_url,$gal) {
1139          $params=$this->getGalOrder($gal);
1140          $params['gal_url'] = $gal->post_url;
1141          $params['no_content'] = true;
1142          //$params['debug'] = true;
1143          $rs = $this->getGalImageMedia($params,false);
1144          $pos=0;
1145          while ($rs->fetch() && $rs->post_url !== $img_url) {
1146               $pos++;
1147          }
1148          if ($rs->post_url !== $img_url || $this->settings->gallery_nb_images_per_page == 0)
1149               return 0;
1150          return (integer)($pos/$this->settings->gallery_nb_images_per_page)+1;
1151     }
1152
1153     /**
1154      * getGalItemCount
1155      *
1156      * Returns the number of items from a gallery
1157      *
1158      * @param record $rs the gallery record
1159      * @access public
1160      * @return int the image count
1161      */
1162     public function getGalItemCount($rs) {
1163          $image_ids = $this->core->meta->getMetaArray($rs->post_meta);
1164          $nb_images=isset($image_ids['galitem'])?sizeof($image_ids['galitem']):0;
1165          return $nb_images;
1166     }
1167
1168     /**
1169      * readMedia
1170      *
1171      * Reads a media from a record in database
1172      *
1173      * @param record $rs  the media record
1174      * @access public
1175      * @return record the decorated record
1176      */
1177     public function readMedia ($rs) {
1178          return $this->fileRecord($rs);
1179     }
1180
1181
1182     /**
1183      * getImageGalleries
1184      *
1185      * Retrives the list of galleries containinng a given image
1186      *
1187      * @param integer $img_id the image id
1188      * @access public
1189      * @return record the galleries record
1190      */
1191     public function getImageGalleries($img_id) {
1192          $params=array();
1193          $params["meta_id"]=$img_id;
1194          $params["meta_type"]='galitem';
1195          $params["post_type"]='gal';
1196          $gals = $this->core->meta->getPostsByMeta($params);
1197          $gals->extend('rsExtGallery');
1198          return $gals;
1199     }
1200
1201     // Refresh a gallery with its images (for performance purpose)
1202     /**
1203      * refreshGallery
1204      *
1205      * Refreshes a gallery content, from its filters
1206      *
1207      * @param integer $gal_id  the gallery id
1208      * @access public
1209      * @return void
1210      */
1211     public function refreshGallery($gal_id) {
1212
1213          // Step 1 : retrieve current gallery items
1214          $params['post_id'] = $gal_id;
1215          $params['no_content'] = 0;
1216          $gal = $this->getGalleries($params);
1217          $metaplus = new MetaPlus ($this->core);
1218         
1219          $meta = $this->core->meta->getMetaArray($gal->post_meta);
1220          if (isset($meta['galitem']))
1221               $current_ids = $meta['galitem'];
1222          else
1223               $current_ids = array();
1224
1225          // Step 2 : retrieve expected gallery items
1226          $new_ids=array();
1227          $params = $this->getGalParams($gal);
1228          if ($params['filter_enabled']) {
1229               $params['no_content']=1;
1230               $rs = $this->getGalImageMedia($params);
1231               while ($rs->fetch()) {
1232                    $new_ids[]=$rs->post_id;
1233               }
1234          }
1235
1236          sort($current_ids);
1237          sort($new_ids);
1238
1239          //print_r($current_ids);
1240          // Step 3 : find out items to add and items to remove
1241          $ids_to_add=array_diff($new_ids,$current_ids);
1242          $ids_to_remove = array_diff($current_ids,$new_ids);
1243
1244          // Perform database operations (number limited due to php timeouts)
1245          $template_insert = array(
1246               'post_id' => (integer) $gal_id,
1247               'meta_id' => 0,
1248               'meta_type'=>'galitem');
1249          $before_insert = '('.(integer)$gal_id.',';
1250          $after_insert = ",'galitem')";
1251
1252          $inserts=array();
1253          foreach ($ids_to_add as $id) {
1254               $inserts[]=array('post_id' => (integer) $gal_id,
1255                    'meta_id' => $id,
1256                    'meta_type' => 'galitem');
1257          }
1258          if (sizeof($inserts) != 0) {
1259               $metaplus->massSetPostMeta ($inserts);
1260          }
1261          if (sizeof($ids_to_remove) != 0) {
1262               $metaplus->massDelPostMeta($gal_id, 'galitem',$ids_to_remove);
1263          }
1264          return false;
1265     }
1266
1267     /**
1268      * addImage
1269      *
1270      * adds an image to a gallery
1271      *
1272      * @param integer $gal_id  gallery id
1273      * @param integer $img_id image id
1274      * @access public
1275      * @return void
1276      */
1277     public function addImage($gal_id,$img_id) {
1278          $this->core->meta->delPostMeta($gal_id,'galitem',$img_id);
1279          $this->core->meta->setPostMeta($gal_id,'galitem',$img_id);
1280     }
1281
1282     /**
1283      * unlinkImage
1284      *
1285      * remove an image from a gallery.
1286      *
1287      * @param integer $gal_id  gallery id
1288      * @param integer $img_id image id
1289      * @access public
1290      * @return void
1291      */
1292     public function unlinkImage($gal_id,$img_id) {
1293          $this->core->meta->delPostMeta($gal_id,'galitem',$img_id);
1294     }
1295
1296     /**
1297      * getRandomImage
1298      *
1299      * Retrieves a random image
1300      *
1301      * @param array $params_in retrieval parameters
1302      *   (see getRandomImage for details)
1303      * @access public
1304      * @return record The random image record
1305      */
1306     public function getRandomImage($params_in=null) {
1307          $params=$params_in;
1308          $count = $this->getGalImageMedia($params,true);
1309          $offset = rand(0, $count->f(0) - 1);
1310
1311
1312          $params['limit']=array($offset, 1);
1313          return $this->getGalImageMedia($params);
1314     }
1315
1316
1317     /**
1318      * checkThemesDir
1319      *
1320      * Checks whether themes dir is valid or not
1321      *
1322      * @access public
1323      * @return boolean true if themes dir is valid, false otherwise
1324      */
1325     public function checkThemesDir() {
1326          $themes_dir = path::fullFromRoot($this->settings->gallery_themes_path,DC_ROOT);
1327          if (!is_dir($themes_dir))
1328               return false;
1329          if (!is_dir($themes_dir.'/gal_simple'))
1330               return false;
1331          return true;
1332     }
1333
1334     /**
1335      * getThemes
1336      *
1337      * Retrieves all available gallery themes
1338      *
1339      * @access public
1340      * @return array the themes list
1341      */
1342     public function getThemes() {
1343          $themes = array();
1344          $themes_dir = path::fullFromRoot($this->settings->gallery_themes_path,DC_ROOT);
1345          if ($dh = opendir($themes_dir)) {
1346               while (($file = readdir($dh)) !== false) {
1347                    if(is_dir($themes_dir.'/'.$file) && (substr($file,0,1) != '.' ) && ($file !== 'gal_feed') && strpos($file,"gal_")===0 ) {
1348                         $name=substr($file,4);
1349                         $themes[$name]=$name;
1350                    }
1351               }
1352          }
1353          return $themes;
1354     }
1355
1356     /**
1357      * themeExists
1358      *
1359      * checks whether a gallery theme exists.
1360      *
1361      * @param string $theme the theme to check
1362      * @access public
1363      * @return boolean true if theme exits, false otherwise.
1364      */
1365     public function themeExists($theme) {
1366          $galtheme=basename($theme);
1367          if ($galtheme == "gal_feed")
1368               return false;
1369          $themes_dir = path::fullFromRoot($this->settings->gallery_themes_path,DC_ROOT);
1370          $theme_path = $themes_dir.'/gal_'.$galtheme;
1371          return file_exists($theme_path) && is_dir($theme_path);
1372     }
1373
1374     /**
1375      * fillGalleryContext
1376      *
1377      * Prefills public context with current gallery
1378      *
1379      * @param dcContext $_ctx current context
1380      * @access public
1381      * @return void
1382      */
1383     public function fillGalleryContext($_ctx,$theme_context='gal') {
1384          $gal_params = $this->core->gallery->getGalOrder($_ctx->posts);
1385          $gal_params["gal_url"]=$_ctx->posts->post_url;
1386          $_ctx->gal_params=$gal_params;
1387          $_ctx->gallery_url=$_ctx->posts->post_url;
1388          $_ctx->gallery_theme = $this->core->gallery->getGalTheme($_ctx->posts,$theme_context);
1389          $_ctx->prevent_recursion=true;
1390     }
1391
1392
1393     /**
1394      * emptyGalleryContext
1395      *
1396      * Empties public context previously filled
1397      *
1398      * @param dcContext $_ctx current context
1399      * @access public
1400      * @return void
1401      */
1402     public function emptyGalleryContext($_ctx) {
1403          $_ctx->prevent_recursion=false;
1404          $_ctx->gallery_theme=null;
1405          $_ctx->gallery_url = null; $_ctx->gal_params=null;
1406     }
1407
1408     /**
1409      * fillItemContext
1410      *
1411      * Prefills public context with current gallery item
1412      *
1413      * @param dcContext $_ctx current context
1414      * @access public
1415      * @return void
1416      * Retrieves all available gallery themes
1417      */
1418     public function fillItemContext($_ctx) {
1419          $myparams = array("post_url" => $_ctx->posts->post_url);
1420          $_ctx->posts = $this->getGalImageMedia($myparams); 
1421          unset($myparams);
1422          $_ctx->media = $this->readMedia($_ctx->posts);
1423          $_ctx->prevent_recursion=true;
1424     }
1425
1426     /**
1427      * emptyItemContext
1428      *
1429      * Empties public context previously filled
1430      *
1431      * @param dcContext $_ctx current context
1432      * @access public
1433      * @return void
1434      */
1435     public function emptyItemContext($_ctx) {
1436          $_ctx->prevent_recursion=false;
1437          $_ctx->posts = null;
1438          $_ctx->media = null;
1439     }
1440
1441
1442}
1443?>
Note: See TracBrowser for help on using the repository browser.

Sites map