Dotclear

source: inc/core/class.dc.media.php @ 1677:61b034ed28a6

Revision 1677:61b034ed28a6, 30.3 KB checked in by franck <carnet.franck.paul@…>, 12 years ago (diff)

Use jpg thumbnails if exist for png images. Addresses #1465

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14/**
15@ingroup DC_CORE
16@brief Dotclear media manage
17
18This class handles Dotclear media items.
19*/
20class dcMedia extends filemanager
21{
22     protected $core;         ///< <b>dcCore</b> dcCore instance
23     protected $con;          ///< <b>connection</b> Database connection
24     protected $table;        ///< <b>string</b> Media table name
25     protected $type;         ///< <b>string</b> Media type filter
26     protected $postmedia;
27     protected $file_sort = 'name-asc';
28     
29     protected $file_handler = array(); ///< <b>array</b> Array of callbacks
30     
31     public $thumb_tp = '%s/.%s_%s.jpg';     ///< <b>string</b> Thumbnail file pattern
32     public $thumb_tp_alpha = '%s/.%s_%s.png'; ///< <b>string</b> Thumbnail file pattern (with alpha layer)
33     
34     /**
35     <b>array</b> Tubmnail sizes:
36     - m: medium image
37     - s: small image
38     - t: thumbnail image
39     - sq: square image
40     */
41     public $thumb_sizes = array( 
42          'm' => array(448,'ratio','medium'),
43          's' => array(240,'ratio','small'),
44          't' => array(100,'ratio','thumbnail'),
45          'sq' => array(48,'crop','square')
46     );
47     
48     public $icon_img = 'images/media/%s.png';    ///< <b>string</b> Icon file pattern
49     
50     /**
51     Object constructor.
52     
53     @param    core      <b>dcCore</b>       dcCore instance
54     @param    type      <b>string</b>       Media type filter
55     */
56     public function __construct($core,$type='')
57     {
58          $this->core =& $core;
59          $this->con =& $core->con;
60          $this->postmedia = new dcPostMedia($core);
61         
62          if ($this->core->blog == null) {
63               throw new Exception(__('No blog defined.'));
64          }
65         
66          $this->table = $this->core->prefix.'media';
67          $root = $this->core->blog->public_path;
68         
69          if (preg_match('#^http(s)?://#',$this->core->blog->settings->system->public_url)) {
70               $root_url = rawurldecode($this->core->blog->settings->system->public_url);
71          } else {
72               $root_url = rawurldecode($this->core->blog->host.path::clean($this->core->blog->settings->system->public_url));
73          }
74         
75          if (!is_dir($root)) {
76               throw new Exception(sprintf(__('Directory %s does not exist.'),$root));
77          }
78         
79          $this->type = $type;
80         
81          parent::__construct($root,$root_url);
82          $this->chdir('');
83         
84          $this->path = $this->core->blog->settings->system->public_path;
85         
86          $this->addExclusion(DC_RC_PATH);
87          $this->addExclusion(dirname(__FILE__).'/../');
88         
89          $this->exclude_pattern = $core->blog->settings->system->media_exclusion;
90         
91          # Event handlers
92          $this->addFileHandler('image/jpeg','create',array($this,'imageThumbCreate'));
93          $this->addFileHandler('image/png','create',array($this,'imageThumbCreate'));
94          $this->addFileHandler('image/gif','create',array($this,'imageThumbCreate'));
95         
96          $this->addFileHandler('image/png','update',array($this,'imageThumbUpdate'));
97          $this->addFileHandler('image/jpeg','update',array($this,'imageThumbUpdate'));
98          $this->addFileHandler('image/gif','update',array($this,'imageThumbUpdate'));
99         
100          $this->addFileHandler('image/png','remove',array($this,'imageThumbRemove'));
101          $this->addFileHandler('image/jpeg','remove',array($this,'imageThumbRemove'));
102          $this->addFileHandler('image/gif','remove',array($this,'imageThumbRemove'));
103         
104          $this->addFileHandler('image/jpeg','create',array($this,'imageMetaCreate'));
105         
106          $this->addFileHandler('image/jpeg','recreate',array($this,'imageThumbCreate'));
107          $this->addFileHandler('image/png','recreate',array($this,'imageThumbCreate'));
108          $this->addFileHandler('image/gif','recreate',array($this,'imageThumbCreate'));
109         
110          $this->addFileHandler('image/jpeg','recreate',array($this,'imageThumbCreate'));
111          $this->addFileHandler('image/png','recreate',array($this,'imageThumbCreate'));
112          $this->addFileHandler('image/gif','recreate',array($this,'imageThumbCreate'));
113         
114          # Thumbnails sizes
115          $this->thumb_sizes['m'][0] = abs($core->blog->settings->system->media_img_m_size);
116          $this->thumb_sizes['s'][0] = abs($core->blog->settings->system->media_img_s_size);
117          $this->thumb_sizes['t'][0] = abs($core->blog->settings->system->media_img_t_size);
118         
119          # Thumbnails sizes names
120          $this->thumb_sizes['m'][2] = __($this->thumb_sizes['m'][2]);
121          $this->thumb_sizes['s'][2] = __($this->thumb_sizes['s'][2]);
122          $this->thumb_sizes['t'][2] = __($this->thumb_sizes['t'][2]);
123          $this->thumb_sizes['sq'][2] = __($this->thumb_sizes['sq'][2]);
124         
125          # --BEHAVIOR-- coreMediaConstruct
126          $this->core->callBehavior('coreMediaConstruct',$this); 
127     }
128     
129     /**
130     Changes working directory.
131     
132     @param    dir       <b>string</b>       Directory name.
133     */
134     public function chdir($dir)
135     {
136          parent::chdir($dir);
137          $this->relpwd = preg_replace('/^'.preg_quote($this->root,'/').'\/?/','',$this->pwd);
138     }
139     
140     /**
141     Adds a new file handler for a given media type and event.
142     
143     Available events are:
144     - create: file creation
145     - update: file update
146     - remove: file deletion
147     
148     @param    type      <b>string</b>       Media type
149     @param    event     <b>string</b>       Event
150     @param    function  <b>callback</b>
151     */
152     public function addFileHandler($type,$event,$function)
153     {
154          if (is_callable($function)) {
155               $this->file_handler[$type][$event][] = $function;
156          }
157     }
158     
159     protected function callFileHandler($type,$event)
160     {
161          if (!empty($this->file_handler[$type][$event]))
162          {
163               $args = func_get_args();
164               array_shift($args);
165               array_shift($args);
166               
167               foreach ($this->file_handler[$type][$event] as $f)
168               {
169                    call_user_func_array($f,$args);
170               }
171          }
172     }
173     
174     /**
175     Returns HTML breadCrumb for media manager navigation.
176     
177     @param    href      <b>string</b>       URL pattern
178     @param    last      <b>string</b>       Last item pattern
179     @return   <b>string</b> HTML code
180     */
181     public function breadCrumb($href,$last='')
182     {
183          $res = '';
184          if ($this->relpwd && $this->relpwd != '.') {
185               $pwd = '';
186               $arr = explode('/',$this->relpwd);
187               $count = count($arr);
188               foreach ($arr as $v) {
189                    if (($last != '') && (0 === --$count)) {
190                         $res .= sprintf($last,$v);
191                    } else {
192                         $pwd .= rawurlencode($v).'/';
193                         $res .= '<a href="'.sprintf($href,$pwd).'">'.$v.'</a> / ';
194                    }
195               }
196          }
197          return $res;
198         
199     }
200     
201     protected function fileRecord($rs)
202     {
203          if ($rs->isEmpty()) { return null; }
204         
205          if (!$this->isFileExclude($this->root.'/'.$rs->media_file) && is_file($this->root.'/'.$rs->media_file))
206          {
207               $f = new fileItem($this->root.'/'.$rs->media_file,$this->root,$this->root_url);
208               
209               if ($this->type && $f->type_prefix != $this->type) {
210                    return null;
211               }
212               
213               $meta = @simplexml_load_string($rs->media_meta);
214               
215               $f->editable = true;
216               $f->media_id = $rs->media_id;
217               $f->media_title = $rs->media_title;
218               $f->media_meta =  $meta instanceof SimpleXMLElement ? $meta : simplexml_load_string('<meta></meta>');
219               $f->media_user = $rs->user_id;
220               $f->media_priv = (boolean) $rs->media_private;
221               $f->media_dt = strtotime($rs->media_dt);
222               $f->media_dtstr = dt::str('%Y-%m-%d %H:%M',$f->media_dt);
223               
224               $f->media_image = false;
225               
226               if (!$this->core->auth->check('media_admin',$this->core->blog->id)
227               && $this->core->auth->userID() != $f->media_user) {
228                    $f->del = false;
229                    $f->editable = false;
230               }
231               
232               $type_prefix = explode('/',$f->type);
233               $type_prefix = $type_prefix[0];
234               
235               switch ($type_prefix) {
236                    case 'image':
237                         $f->media_image = true;
238                         $f->media_icon = 'image';
239                         break;
240                    case 'audio':
241                         $f->media_icon = 'audio';
242                         break;
243                    case 'text':
244                         $f->media_icon = 'text';
245                         break;
246                    case 'video':
247                         $f->media_icon = 'video';
248                         break;
249                    default:
250                         $f->media_icon = 'blank';
251               }
252               switch ($f->type) {
253                    case 'application/msword':
254                    case 'application/vnd.oasis.opendocument.text':
255                    case 'application/vnd.sun.xml.writer':
256                    case 'application/pdf':
257                    case 'application/postscript':
258                         $f->media_icon = 'document';
259                         break;
260                    case 'application/msexcel':
261                    case 'application/vnd.oasis.opendocument.spreadsheet':
262                    case 'application/vnd.sun.xml.calc':
263                         $f->media_icon = 'spreadsheet';
264                         break;
265                    case 'application/mspowerpoint':
266                    case 'application/vnd.oasis.opendocument.presentation':
267                    case 'application/vnd.sun.xml.impress':
268                         $f->media_icon = 'presentation';
269                         break;
270                    case 'application/x-debian-package':
271                    case 'application/x-bzip':
272                    case 'application/x-gzip':
273                    case 'application/x-java-archive':
274                    case 'application/rar':
275                    case 'application/x-redhat-package-manager':
276                    case 'application/x-tar':
277                    case 'application/x-gtar':
278                    case 'application/zip':
279                         $f->media_icon = 'package';
280                         break;
281                    case 'application/octet-stream':
282                         $f->media_icon = 'executable';
283                         break;
284                    case 'application/x-shockwave-flash':
285                         $f->media_icon = 'video';
286                         break;
287                    case 'application/ogg':
288                         $f->media_icon = 'audio';
289                         break;
290                    case 'text/html':
291                         $f->media_icon = 'html';
292                         break;
293               }
294               
295               $f->media_type = $f->media_icon;
296               $f->media_icon = sprintf($this->icon_img,$f->media_icon);
297               
298               # Thumbnails
299               $f->media_thumb = array();
300               $p = path::info($f->relname);
301
302               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
303
304               $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$this->root.'/'.$p['dirname'],$p['base'],'%s');
305               $thumb_url = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$this->root_url.$p['dirname'],$p['base'],'%s');
306               
307               # Cleaner URLs
308               $thumb_url = preg_replace('#\./#','/',$thumb_url);
309               $thumb_url = preg_replace('#(?<!:)/+#','/',$thumb_url);
310
311               if ($alpha) {
312                    $thumb_alt = sprintf($this->thumb_tp,$this->root.'/'.$p['dirname'],$p['base'],'%s');
313                    $thumb_url_alt = sprintf($this->thumb_tp,$this->root_url.$p['dirname'],$p['base'],'%s');
314                    # Cleaner URLs
315                    $thumb_url_alt = preg_replace('#\./#','/',$thumb_url_alt);
316                    $thumb_url_alt = preg_replace('#(?<!:)/+#','/',$thumb_url_alt);
317               }
318               
319               foreach ($this->thumb_sizes as $suffix => $s) {
320                    if (file_exists(sprintf($thumb,$suffix))) {
321                         $f->media_thumb[$suffix] = sprintf($thumb_url,$suffix);
322                    } elseif ($alpha && file_exists(sprintf($thumb_alt,$suffix))) {
323                         $f->media_thumb[$suffix] = sprintf($thumb_url_alt,$suffix);
324                    }
325               }
326               
327               if (isset($f->media_thumb['sq']) && $f->media_type == 'image') {
328                    $f->media_icon = $f->media_thumb['sq'];
329               }
330               
331               return $f;
332          }
333         
334          return null;
335     }
336     
337     
338     public function setFileSort($type='name')
339     {
340          if (in_array($type,array('name-asc','name-desc','date-asc','date-desc'))) {
341               $this->file_sort = $type;
342          }
343     }
344     
345     protected function sortFileHandler($a,$b)
346     {
347          switch ($this->file_sort)
348          {
349               case 'date-asc':
350                    if ($a->media_dt == $b->media_dt) {
351                         return 0;
352                    }
353                    return ($a->media_dt < $b->media_dt) ? -1 : 1;
354               case 'date-desc':
355                    if ($a->media_dt == $b->media_dt) {
356                         return 0;
357                    }
358                    return ($a->media_dt > $b->media_dt) ? -1 : 1;
359               case 'name-desc':
360                    return strcasecmp($b->basename,$a->basename);
361               case 'name-asc':
362               default:
363                    return strcasecmp($a->basename,$b->basename);
364          }
365         
366     }
367     
368     /**
369     Gets current working directory content.
370     
371     @param    type      <b>string</b>       Media type filter
372     */
373     public function getDir($type=null)
374     {
375          if ($type) {
376               $this->type = $type;
377          }
378         
379          $media_dir = $this->relpwd ? $this->relpwd : '.';
380         
381          $strReq =
382          'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '.
383          'media_creadt, media_upddt, media_private, user_id '.
384          'FROM '.$this->table.' '.
385          "WHERE media_path = '".$this->path."' ".
386          "AND media_dir = '".$this->con->escape($media_dir)."' ";
387         
388          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
389          {
390               $strReq .= 'AND (media_private <> 1 ';
391               
392               if ($this->core->auth->userID()) {
393                    $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'";
394               }
395               $strReq .= ') ';
396          }
397         
398          $rs = $this->con->select($strReq);
399         
400          parent::getDir();
401         
402          $f_res = array();
403          $p_dir = $this->dir;
404         
405          # If type is set, remove items from p_dir
406          if ($this->type)
407          {
408               foreach ($p_dir['files'] as $k => $f) {
409                    if ($f->type_prefix != $this->type) {
410                         unset($p_dir['files'][$k]);
411                    }
412               }
413          }
414         
415          $f_reg = array();
416         
417          while ($rs->fetch())
418          {
419               # File in subdirectory, forget about it!
420               if (dirname($rs->media_file) != '.' && dirname($rs->media_file) != $this->relpwd) {
421                    continue;
422               }
423               
424               if ($this->inFiles($rs->media_file))
425               {
426                    $f = $this->fileRecord($rs);
427                    if ($f !== null) {
428                         if (isset($f_reg[$rs->media_file]))
429                         {
430                              # That media is duplicated in the database,
431                              # time to do a bit of house cleaning.
432                              $this->con->execute(
433                                   'DELETE FROM '.$this->table.' '.
434                                   "WHERE media_id = ".$this->fileRecord($rs)->media_id
435                              );
436                         } else {
437                              $f_res[] = $this->fileRecord($rs);
438                              $f_reg[$rs->media_file] = 1;
439                         }
440                    }
441               }
442               elseif (!empty($p_dir['files']) && $this->relpwd == '')
443               {
444                    # Physical file does not exist remove it from DB
445                    # Because we don't want to erase everything on
446                    # dotclear upgrade, do it only if there are files
447                    # in directory and directory is root
448                    $this->con->execute(
449                         'DELETE FROM '.$this->table.' '.
450                         "WHERE media_path = '".$this->con->escape($this->path)."' ".
451                         "AND media_file = '".$this->con->escape($rs->media_file)."' "
452                    );
453                    $this->callFileHandler(files::getMimeType($rs->media_file),'remove',$this->pwd.'/'.$rs->media_file);
454               }
455          }
456         
457          $this->dir['files'] = $f_res;
458          foreach ($this->dir['dirs'] as $k => $v) {
459               $v->media_icon = sprintf($this->icon_img,'folder');
460          }
461         
462          # Check files that don't exist in database and create them
463          if ($this->core->auth->check('media,media_admin',$this->core->blog->id))
464          {
465               foreach ($p_dir['files'] as $f)
466               {
467                    if (!isset($f_reg[$f->relname])) {
468                         if (($id = $this->createFile($f->basename,null,false,null,false)) !== false) {
469                              $this->dir['files'][] = $this->getFile($id);
470                         }
471                    }
472               }
473          }
474          usort($this->dir['files'],array($this,'sortFileHandler'));
475     }
476     
477     /**
478     Gets file by its id. Returns a filteItem object.
479     
480     @param    id        <b>integer</b>      File ID
481     @return   <b>fileItem</b>
482     */
483     public function getFile($id)
484     {
485          $strReq =
486          'SELECT media_id, media_path, media_title, '.
487          'media_file, media_meta, media_dt, media_creadt, '.
488          'media_upddt, media_private, user_id '.
489          'FROM '.$this->table.' '.
490          "WHERE media_path = '".$this->path."' ".
491          'AND media_id = '.(integer) $id.' ';
492         
493          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
494          {
495               $strReq .= 'AND (media_private <> 1 ';
496               
497               if ($this->core->auth->userID()) {
498                    $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'";
499               }
500               $strReq .= ') ';
501          }
502         
503          $rs = $this->con->select($strReq);
504          return $this->fileRecord($rs);
505     }
506     
507     /**
508     Returns media items attached to a blog post. Result is an array containing
509     fileItems objects.
510     
511     @param    post_id   <b>integer</b>      Post ID
512     @param    media_id  <b>integer</b>      Optionnal media ID
513     @param    return_rs <b>boolean</b>      Whether to return a resultset (true) or an array (false, default value).
514     @return   <b>array</b> Array or ResultSet of fileItems
515     */
516     public function getPostMedia($post_id,$media_id=null,$return_rs=false)
517     {
518          $params = array(
519               'post_id' => $post_id,
520               'media_path' => $this->path
521          );
522          if ($media_id) {
523               $params['media_id'] = (integer) $media_id;
524          }
525          $rs = $this->postmedia->getPostMedia($params);
526         
527          $res = array();
528         
529          while ($rs->fetch()) {
530               $f = $this->fileRecord($rs);
531               if ($f !== null) {
532                    $res[] = $return_rs ? new ArrayObject($f) : $f;
533               }
534          }
535         
536          return $return_rs ? staticRecord::newFromArray($res) : $res;
537     }
538     
539     /**
540     @deprecated since version 2.4
541     @see dcPostMedia::addPostMedia
542     */
543     public function addPostMedia($post_id,$media_id)
544     {
545          $this->postmedia->addPostMedia($post_id,$media_id);
546     }
547     
548     /**
549     @deprecated since version 2.4
550     @see dcPostMedia::removePostMedia
551     */
552     public function removePostMedia($post_id,$media_id)
553     {
554          $this->postmedia->removePostMedia($post_id,$media_id,"attachment");
555     }
556     
557     /**
558     Rebuilds database items collection. Optional <var>$pwd</var> parameter is
559     the path where to start rebuild.
560     
561     @param    pwd       <b>string</b>       Directory to rebuild
562     */
563     public function rebuild($pwd='')
564     {
565          if (!$this->core->auth->isSuperAdmin()) {
566               throw new Exception(__('You are not a super administrator.'));
567          }
568         
569          $this->chdir($pwd);
570          parent::getDir();
571         
572          $dir = $this->dir;
573         
574          foreach ($dir['dirs'] as $d) {
575               if (!$d->parent) {
576                    $this->rebuild($d->relname,false);
577               }
578          }
579         
580          foreach ($dir['files'] as $f) {
581               $this->chdir(dirname($f->relname));
582               $this->createFile($f->basename);
583          }
584         
585          $this->rebuildDB($pwd);
586     }
587     
588     protected function rebuildDB($pwd)
589     {
590          $media_dir = $pwd ? $pwd : '.';
591         
592          $strReq =
593          'SELECT media_file, media_id '.
594          'FROM '.$this->table.' '.
595          "WHERE media_path = '".$this->path."' ".
596          "AND media_dir = '".$this->con->escape($media_dir)."' ";
597         
598          $rs = $this->con->select($strReq);
599         
600          $delReq = 'DELETE FROM '.$this->table.' '.
601                    'WHERE media_id IN (%s) ';
602          $del_ids = array();
603         
604          while ($rs->fetch())
605          {
606               if (!is_file($this->root.'/'.$rs->media_file)) {
607                    $del_ids[] = (integer) $rs->media_id;
608               }
609          }
610         
611          if (!empty($del_ids)) {
612               $this->con->execute(sprintf($delReq,implode(',',$del_ids)));
613          }
614     }
615     
616     public function makeDir($d)
617     {
618          $d = files::tidyFileName($d);
619          parent::makeDir($d);
620     }
621     
622     /**
623     Creates or updates a file in database. Returns new media ID or false if
624     file does not exist.
625     
626     @param    name      <b>string</b>       File name (relative to working directory)
627     @param    title     <b>string</b>       File title
628     @param    private   <b>boolean</b>      File is private
629     @param    dt        <b>string</b>       File date
630     @return   <b>integer</b> New media ID
631     */
632     public function createFile($name,$title=null,$private=false,$dt=null,$force=true)
633     {
634          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
635               throw new Exception(__('Permission denied.'));
636          }
637         
638          $file = $this->pwd.'/'.$name;
639          if (!file_exists($file)) {
640               return false;
641          }
642         
643          $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$name) : path::clean($name);
644          $media_type = files::getMimeType($name);
645         
646          $cur = $this->con->openCursor($this->table);
647         
648          $strReq = 'SELECT media_id '.
649                    'FROM '.$this->table.' '.
650                    "WHERE media_path = '".$this->con->escape($this->path)."' ".
651                    "AND media_file = '".$this->con->escape($media_file)."' ";
652         
653          $rs = $this->con->select($strReq);
654         
655          if ($rs->isEmpty())
656          {
657               $this->con->writeLock($this->table);
658               try
659               {
660                    $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->table);
661                    $media_id = (integer) $rs->f(0) + 1;
662                   
663                    $cur->media_id = $media_id;
664                    $cur->user_id = (string) $this->core->auth->userID();
665                    $cur->media_path = (string) $this->path;
666                    $cur->media_file = (string) $media_file;
667                    $cur->media_dir = (string) dirname($media_file);
668                    $cur->media_creadt = date('Y-m-d H:i:s');
669                    $cur->media_upddt = date('Y-m-d H:i:s');
670                   
671                    $cur->media_title = !$title ? (string) $name : (string) $title;
672                    $cur->media_private = (integer) (boolean) $private;
673                   
674                    if ($dt) {
675                         $cur->media_dt = (string) $dt;
676                    } else {
677                         $cur->media_dt = strftime('%Y-%m-%d %H:%M:%S',filemtime($file));
678                    }
679                   
680                    try {
681                         $cur->insert();
682                    } catch (Exception $e) {
683                         @unlink($name);
684                         throw $e;
685                    }
686                    $this->con->unlock();
687               }
688               catch (Exception $e)
689               {
690                    $this->con->unlock();
691                    throw $e;
692               }
693          }
694          else
695          {
696               $media_id = (integer) $rs->media_id;
697               
698               $cur->media_upddt = date('Y-m-d H:i:s');
699               
700               $cur->update('WHERE media_id = '.$media_id);
701          }
702         
703          $this->callFileHandler($media_type,'create',$cur,$name,$media_id,$force);
704         
705          return $media_id;
706     }
707     
708     /**
709     Updates a file in database.
710     
711     @param    file      <b>fileItem</b>     Current fileItem object
712     @param    newFile   <b>fileItem</b>     New fileItem object
713     */
714     public function updateFile($file,$newFile)
715     {
716          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
717               throw new Exception(__('Permission denied.'));
718          }
719         
720          $id = (integer) $file->media_id;
721         
722          if (!$id) {
723               throw new Exception('No file ID');
724          }
725         
726          if (!$this->core->auth->check('media_admin',$this->core->blog->id)
727          && $this->core->auth->userID() != $file->media_user) {
728               throw new Exception(__('You are not the file owner.'));
729          }
730         
731          $cur = $this->con->openCursor($this->table);
732         
733          # We need to tidy newFile basename. If dir isn't empty, concat to basename
734          $newFile->relname = files::tidyFileName($newFile->basename);
735          if ($newFile->dir) {
736               $newFile->relname = $newFile->dir.'/'.$newFile->relname;
737          }
738         
739          if ($file->relname != $newFile->relname) {
740               $newFile->file = $this->root.'/'.$newFile->relname;
741               
742               if ($this->isFileExclude($newFile->relname)) {
743                    throw new Exception(__('This file is not allowed.'));
744               }
745               
746               if (file_exists($newFile->file)) {
747                    throw new Exception(__('New file already exists.'));
748               }
749               
750               $this->moveFile($file->relname,$newFile->relname);
751               
752               $cur->media_file = (string) $newFile->relname;
753               $cur->media_dir = (string) dirname($newFile->relname);
754          }
755         
756          $cur->media_title = (string) $newFile->media_title;
757          $cur->media_dt = (string) $newFile->media_dtstr;
758          $cur->media_upddt = date('Y-m-d H:i:s');
759          $cur->media_private = (integer) $newFile->media_priv;
760         
761          $cur->update('WHERE media_id = '.$id);
762         
763          $this->callFileHandler($file->type,'update',$file,$newFile);
764     }
765     
766     /**
767     Uploads a file.
768     
769     @param    tmp       <b>string</b>       Full path of temporary uploaded file
770     @param    name      <b>string</b>       File name (relative to working directory)
771     @param    title     <b>string</b>       File title
772     @param    private   <b>boolean</b>      File is private
773     */
774     public function uploadFile($tmp,$name,$title=null,$private=false,$overwrite=false)
775     {
776          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
777               throw new Exception(__('Permission denied.'));
778          }
779         
780          $name = files::tidyFileName($name);
781         
782          parent::uploadFile($tmp,$name,$overwrite);
783         
784          return $this->createFile($name,$title,$private);
785     }
786     
787     /**
788     Creates a file from binary content.
789     
790     @param    name      <b>string</b>       File name (relative to working directory)
791     @param    bits      <b>string</b>       Binary file content
792     */
793     public function uploadBits($name,$bits)
794     {
795          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
796               throw new Exception(__('Permission denied.'));
797          }
798         
799          $name = files::tidyFileName($name);
800         
801          parent::uploadBits($name,$bits);
802         
803          return $this->createFile($name,null,null);
804     }
805     
806     /**
807     Removes a file.
808     
809     @param    f         <b>fileItem</b>     fileItem object
810     */
811     public function removeFile($f)
812     {
813          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
814               throw new Exception(__('Permission denied.'));
815          }
816         
817          $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$f) : path::clean($f);
818         
819          $strReq = 'DELETE FROM '.$this->table.' '.
820                    "WHERE media_path = '".$this->con->escape($this->path)."' ".
821                    "AND media_file = '".$this->con->escape($media_file)."' ";
822         
823          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
824          {
825               $strReq .= "AND user_id = '".$this->con->escape($this->core->auth->userID())."'";
826          }
827         
828          $this->con->execute($strReq);
829         
830          if ($this->con->changes() == 0) {
831               throw new Exception(__('File does not exist in the database.'));
832          }
833         
834          parent::removeFile($f);
835         
836          $this->callFileHandler(files::getMimeType($media_file),'remove',$f);
837     }
838
839     /**
840     * Root directories
841     *
842     * Returns an array of directory under {@link $root} directory.
843     *
844     * @uses fileItem
845     * @return array
846     */
847     public function getDBDirs()
848     {
849          $media_dir = $this->relpwd ? $this->relpwd : '.';
850         
851          $strReq =
852          'SELECT distinct media_dir '.
853          'FROM '.$this->table.' '.
854          "WHERE media_path = '".$this->path."'";
855          $rs = $this->con->select($strReq);
856          while ($rs->fetch()) {
857               if (is_dir($this->root.'/'.$rs->media_dir))
858                    $dir[] = ($rs->media_dir == '.' ? '' : $rs->media_dir);
859          }
860         
861          return $dir;
862     }
863     
864     /**
865     Extract zip file in current location
866     
867     @param    f         <b>fileRecord</b>   fileRecord object
868     */
869     public function inflateZipFile($f,$create_dir=true)
870     {
871          $zip = new fileUnzip($f->file);
872          $zip->setExcludePattern($this->exclude_pattern);
873          $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#');
874         
875          if ($create_dir)
876          {
877               $zip_root_dir = $zip->getRootDir();
878               if ($zip_root_dir != false) {
879                    $destination = $zip_root_dir;
880                    $target = $f->dir;
881               } else {
882                    $destination = preg_replace('/\.([^.]+)$/','',$f->basename);
883                    $target = $f->dir.'/'.$destination;
884               }
885               
886               if (is_dir($f->dir.'/'.$destination)) {
887                    throw new Exception(sprintf(__('Extract destination directory %s already exists.'),dirname($f->relname).'/'.$destination)); 
888               }
889          }
890          else
891          {
892               $target = $f->dir;
893               $destination = '';
894          }
895         
896          $zip->unzipAll($target);
897          $zip->close();
898          return dirname($f->relname).'/'.$destination;
899     }
900     
901     /**
902     Returns zip file content
903     
904     @param    f         <b>fileRecord</b>   fileRecord object
905     @return <b>array</b>
906     */
907     public function getZipContent($f)
908     {
909          $zip = new fileUnzip($f->file);
910          $list = $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#');
911          $zip->close();
912          return $list;
913     }
914
915     /**
916     Calls file handlers registered for recreate event
917     
918     @param    f    <b>fileItem</b>     fileItem object
919     */
920     public function mediaFireRecreateEvent($f)
921     {
922          $media_type = files::getMimeType($f->basename);
923          $this->callFileHandler($media_type,'recreate',null,$f->basename); // Args list to be completed as necessary (Franck)
924     }
925     
926     /* Image handlers
927     ------------------------------------------------------- */
928     public function imageThumbCreate($cur,$f,$force=true)
929     {
930          $file = $this->pwd.'/'.$f;
931         
932          if (!file_exists($file)) {
933               return false;
934          }
935         
936          $p = path::info($file);
937          $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
938          $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
939         
940          try
941          {
942               $img = new imageTools();
943               $img->loadImage($file);
944               
945               $w = $img->getW();
946               $h = $img->getH();
947               
948               if ($force) $this->imageThumbRemove($f);
949               
950               foreach ($this->thumb_sizes as $suffix => $s) {
951                    $thumb_file = sprintf($thumb,$suffix);
952                    if (!file_exists($thumb_file) && $s[0] > 0 &&
953                         ($suffix == 'sq' || $w > $s[0] || $h > $s[0]))
954                    {
955                         $rate = ($s[0] < 100 ? 95 : ($s[0] < 600 ? 90 : 85));
956                         $img->resize($s[0],$s[0],$s[1]);
957                         $img->output(($alpha ? 'png' : 'jpeg'),$thumb_file,$rate);
958                         $img->loadImage($file);
959                    }
960               }
961               $img->close();
962          }
963          catch (Exception $e)
964          {
965               if ($cur === null) { # Called only if cursor is null (public call)
966                    throw $e;
967               }
968          }
969     }
970     
971     protected function imageThumbUpdate($file,$newFile)
972     {
973          if ($file->relname != $newFile->relname)
974          {
975               $p = path::info($file->relname);
976               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
977               $thumb_old = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
978               
979               $p = path::info($newFile->relname);
980               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
981               $thumb_new = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
982               
983               foreach ($this->thumb_sizes as $suffix => $s) {
984                    try {
985                         parent::moveFile(sprintf($thumb_old,$suffix),sprintf($thumb_new,$suffix));
986                    } catch (Exception $e) {}
987               }
988          }
989     }
990     
991     protected function imageThumbRemove($f)
992     {
993          $p = path::info($f);
994          $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
995          $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),'',$p['base'],'%s');
996         
997          foreach ($this->thumb_sizes as $suffix => $s) {
998               try {
999                    parent::removeFile(sprintf($thumb,$suffix));
1000               } catch (Exception $e) {}
1001          }
1002     }
1003     
1004     protected function imageMetaCreate($cur,$f,$id)
1005     {
1006          $file = $this->pwd.'/'.$f;
1007         
1008          if (!file_exists($file)) {
1009               return false;
1010          }
1011         
1012          $xml = new xmlTag('meta');
1013          $meta = imageMeta::readMeta($file);
1014          $xml->insertNode($meta);
1015         
1016          $c = $this->core->con->openCursor($this->table);
1017          $c->media_meta = $xml->toXML();
1018         
1019          if ($cur->media_title !== null && $cur->media_title == basename($cur->media_file))
1020          {
1021               if ($meta['Title']) {
1022                    $c->media_title = $meta['Title'];
1023               }
1024          }
1025         
1026          if ($meta['DateTimeOriginal'] && $cur->media_dt === '')
1027          {
1028               # We set picture time to user timezone
1029               $media_ts = strtotime($meta['DateTimeOriginal']);
1030               if ($media_ts !== false) {
1031                    $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts);
1032                    $c->media_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o);
1033               }
1034          }
1035         
1036          $c->update('WHERE media_id = '.$id);
1037     }
1038     
1039     /**
1040     Returns HTML code for MP3 player
1041     
1042     @param    url       <b>string</b>       MP3 URL to play
1043     @param    player    <b>string</b>       Player URL
1044     @param    args      <b>array</b>        Player parameters
1045     @return   <b>string</b>
1046     */
1047     public static function mp3player($url,$player=null,$args=null)
1048     {
1049          if (!$player) {
1050               $player = 'player_mp3.swf';
1051          }
1052         
1053          if (!is_array($args))
1054          {
1055               $args = array(
1056                    'showvolume' => 1,
1057                    'loadingcolor' => 'ff9900',
1058                    'bgcolor1' => 'eeeeee',
1059                    'bgcolor2' => 'cccccc',
1060                    'buttoncolor' => '0066cc',
1061                    'buttonovercolor' => 'ff9900',
1062                    'slidercolor1' => 'cccccc',
1063                    'slidercolor2' => '999999',
1064                    'sliderovercolor' => '0066cc'
1065               );
1066          }
1067         
1068          $args['mp3'] = $url;
1069         
1070          if (empty($args['width'])) {
1071               $args['width'] = 200;
1072          }
1073          if (empty($args['height'])) {
1074               $args['height'] = 20;
1075          }
1076         
1077          $vars = array();
1078          foreach ($args as $k => $v) {
1079               $vars[] = $k.'='.$v;
1080          }
1081         
1082          return
1083          '<object type="application/x-shockwave-flash" '.
1084          'data="'.$player.'" '.
1085          'width="'.$args['width'].'" height="'.$args['height'].'">'.
1086          '<param name="movie" value="'.$player.'" />'.
1087          '<param name="wmode" value="transparent" />'.
1088          '<param name="FlashVars" value="'.implode('&amp;',$vars).'" />'.
1089          __('Embedded Audio Player').
1090          '</object>';
1091     }
1092     
1093     public static function flvplayer($url,$player=null,$args=null)
1094     {
1095          if (!$player) {
1096               $player = 'player_flv.swf';
1097          }
1098         
1099          if (!is_array($args))
1100          {
1101               $args = array(
1102                    'margin' => 1,
1103                    'showvolume' => 1,
1104                    'showtime' => 1,
1105                    'showfullscreen' => 1,
1106                    'buttonovercolor' => 'ff9900',
1107                    'slidercolor1' => 'cccccc',
1108                    'slidercolor2' => '999999',
1109                    'sliderovercolor' => '0066cc'
1110               );
1111          }
1112         
1113          $args['flv'] = $url;
1114         
1115          if (empty($args['width'])) {
1116               $args['width'] = 400;
1117          }
1118          if (empty($args['height'])) {
1119               $args['height'] = 300;
1120          }
1121         
1122          $vars = array();
1123          foreach ($args as $k => $v) {
1124               $vars[] = $k.'='.$v;
1125          }
1126         
1127          return
1128          '<object type="application/x-shockwave-flash" '.
1129          'data="'.$player.'" '.
1130          'width="'.$args['width'].'" height="'.$args['height'].'">'.
1131          '<param name="movie" value="'.$player.'" />'.
1132          '<param name="wmode" value="transparent" />'.
1133          '<param name="allowFullScreen" value="true" />'.
1134          '<param name="FlashVars" value="'.implode('&amp;',$vars).'" />'.
1135          __('Embedded Video Player').
1136          '</object>';
1137     }
1138}
1139?>
Note: See TracBrowser for help on using the repository browser.

Sites map