Dotclear

source: inc/core/class.dc.media.php @ 1381:d91b07dc11eb

Revision 1381:d91b07dc11eb, 29.8 KB checked in by franck <carnet.franck.paul@…>, 12 years ago (diff)

Cope with alpha layer (in PNG images), fixes #1465 (including clearbricks rev 327)

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               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
302               $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$this->root.'/'.$p['dirname'],$p['base'],'%s');
303               $thumb_url = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$this->root_url.$p['dirname'],$p['base'],'%s');
304               
305               # Cleaner URLs
306               $thumb_url = preg_replace('#\./#','/',$thumb_url);
307               $thumb_url = preg_replace('#(?<!:)/+#','/',$thumb_url);
308               
309               foreach ($this->thumb_sizes as $suffix => $s) {
310                    if (file_exists(sprintf($thumb,$suffix))) {
311                         $f->media_thumb[$suffix] = sprintf($thumb_url,$suffix);
312                    }
313               }
314               
315               if (isset($f->media_thumb['sq']) && $f->media_type == 'image') {
316                    $f->media_icon = $f->media_thumb['sq'];
317               }
318               
319               return $f;
320          }
321         
322          return null;
323     }
324     
325     
326     public function setFileSort($type='name')
327     {
328          if (in_array($type,array('name-asc','name-desc','date-asc','date-desc'))) {
329               $this->file_sort = $type;
330          }
331     }
332     
333     protected function sortFileHandler($a,$b)
334     {
335          switch ($this->file_sort)
336          {
337               case 'date-asc':
338                    if ($a->media_dt == $b->media_dt) {
339                         return 0;
340                    }
341                    return ($a->media_dt < $b->media_dt) ? -1 : 1;
342               case 'date-desc':
343                    if ($a->media_dt == $b->media_dt) {
344                         return 0;
345                    }
346                    return ($a->media_dt > $b->media_dt) ? -1 : 1;
347               case 'name-desc':
348                    return strcasecmp($b->basename,$a->basename);
349               case 'name-asc':
350               default:
351                    return strcasecmp($a->basename,$b->basename);
352          }
353         
354     }
355     
356     /**
357     Gets current working directory content.
358     
359     @param    type      <b>string</b>       Media type filter
360     */
361     public function getDir($type=null)
362     {
363          if ($type) {
364               $this->type = $type;
365          }
366         
367          $media_dir = $this->relpwd ? $this->relpwd : '.';
368         
369          $strReq =
370          'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '.
371          'media_creadt, media_upddt, media_private, user_id '.
372          'FROM '.$this->table.' '.
373          "WHERE media_path = '".$this->path."' ".
374          "AND media_dir = '".$this->con->escape($media_dir)."' ";
375         
376          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
377          {
378               $strReq .= 'AND (media_private <> 1 ';
379               
380               if ($this->core->auth->userID()) {
381                    $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'";
382               }
383               $strReq .= ') ';
384          }
385         
386          $rs = $this->con->select($strReq);
387         
388          parent::getDir();
389         
390          $f_res = array();
391          $p_dir = $this->dir;
392         
393          # If type is set, remove items from p_dir
394          if ($this->type)
395          {
396               foreach ($p_dir['files'] as $k => $f) {
397                    if ($f->type_prefix != $this->type) {
398                         unset($p_dir['files'][$k]);
399                    }
400               }
401          }
402         
403          $f_reg = array();
404         
405          while ($rs->fetch())
406          {
407               # File in subdirectory, forget about it!
408               if (dirname($rs->media_file) != '.' && dirname($rs->media_file) != $this->relpwd) {
409                    continue;
410               }
411               
412               if ($this->inFiles($rs->media_file))
413               {
414                    $f = $this->fileRecord($rs);
415                    if ($f !== null) {
416                         if (isset($f_reg[$rs->media_file]))
417                         {
418                              # That media is duplicated in the database,
419                              # time to do a bit of house cleaning.
420                              $this->con->execute(
421                                   'DELETE FROM '.$this->table.' '.
422                                   "WHERE media_id = ".$this->fileRecord($rs)->media_id
423                              );
424                         } else {
425                              $f_res[] = $this->fileRecord($rs);
426                              $f_reg[$rs->media_file] = 1;
427                         }
428                    }
429               }
430               elseif (!empty($p_dir['files']) && $this->relpwd == '')
431               {
432                    # Physical file does not exist remove it from DB
433                    # Because we don't want to erase everything on
434                    # dotclear upgrade, do it only if there are files
435                    # in directory and directory is root
436                    $this->con->execute(
437                         'DELETE FROM '.$this->table.' '.
438                         "WHERE media_path = '".$this->con->escape($this->path)."' ".
439                         "AND media_file = '".$this->con->escape($rs->media_file)."' "
440                    );
441                    $this->callFileHandler(files::getMimeType($rs->media_file),'remove',$this->pwd.'/'.$rs->media_file);
442               }
443          }
444         
445          $this->dir['files'] = $f_res;
446          foreach ($this->dir['dirs'] as $k => $v) {
447               $v->media_icon = sprintf($this->icon_img,'folder');
448          }
449         
450          # Check files that don't exist in database and create them
451          if ($this->core->auth->check('media,media_admin',$this->core->blog->id))
452          {
453               foreach ($p_dir['files'] as $f)
454               {
455                    if (!isset($f_reg[$f->relname])) {
456                         if (($id = $this->createFile($f->basename,null,false,null,false)) !== false) {
457                              $this->dir['files'][] = $this->getFile($id);
458                         }
459                    }
460               }
461          }
462          usort($this->dir['files'],array($this,'sortFileHandler'));
463     }
464     
465     /**
466     Gets file by its id. Returns a filteItem object.
467     
468     @param    id        <b>integer</b>      File ID
469     @return   <b>fileItem</b>
470     */
471     public function getFile($id)
472     {
473          $strReq =
474          'SELECT media_id, media_path, media_title, '.
475          'media_file, media_meta, media_dt, media_creadt, '.
476          'media_upddt, media_private, user_id '.
477          'FROM '.$this->table.' '.
478          "WHERE media_path = '".$this->path."' ".
479          'AND media_id = '.(integer) $id.' ';
480         
481          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
482          {
483               $strReq .= 'AND (media_private <> 1 ';
484               
485               if ($this->core->auth->userID()) {
486                    $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'";
487               }
488               $strReq .= ') ';
489          }
490         
491          $rs = $this->con->select($strReq);
492          return $this->fileRecord($rs);
493     }
494     
495     /**
496     Returns media items attached to a blog post. Result is an array containing
497     fileItems objects.
498     
499     @param    post_id   <b>integer</b>      Post ID
500     @param    media_id  <b>integer</b>      Optionnal media ID
501     @param    return_rs <b>boolean</b>      Whether to return a resultset (true) or an array (false, default value).
502     @return   <b>array</b> Array or ResultSet of fileItems
503     */
504     public function getPostMedia($post_id,$media_id=null,$return_rs=false)
505     {
506          $params = array(
507               'post_id' => $post_id,
508               'media_path' => $this->path
509          );
510          if ($media_id) {
511               $params['media_id'] = (integer) $media_id;
512          }
513          $rs = $this->postmedia->getPostMedia($params);
514         
515          $res = array();
516         
517          while ($rs->fetch()) {
518               $f = $this->fileRecord($rs);
519               if ($f !== null) {
520                    $res[] = $return_rs ? new ArrayObject($f) : $f;
521               }
522          }
523         
524          return $return_rs ? staticRecord::newFromArray($res) : $res;
525     }
526     
527     /**
528     @deprecated since version 2.4
529     @see dcPostMedia::addPostMedia
530     */
531     public function addPostMedia($post_id,$media_id)
532     {
533          $this->postmedia->addPostMedia($post_id,$media_id);
534     }
535     
536     /**
537     @deprecated since version 2.4
538     @see dcPostMedia::removePostMedia
539     */
540     public function removePostMedia($post_id,$media_id)
541     {
542          $this->postmedia->removePostMedia($post_id,$media_id,"attachment");
543     }
544     
545     /**
546     Rebuilds database items collection. Optional <var>$pwd</var> parameter is
547     the path where to start rebuild.
548     
549     @param    pwd       <b>string</b>       Directory to rebuild
550     */
551     public function rebuild($pwd='')
552     {
553          if (!$this->core->auth->isSuperAdmin()) {
554               throw new Exception(__('You are not a super administrator.'));
555          }
556         
557          $this->chdir($pwd);
558          parent::getDir();
559         
560          $dir = $this->dir;
561         
562          foreach ($dir['dirs'] as $d) {
563               if (!$d->parent) {
564                    $this->rebuild($d->relname,false);
565               }
566          }
567         
568          foreach ($dir['files'] as $f) {
569               $this->chdir(dirname($f->relname));
570               $this->createFile($f->basename);
571          }
572         
573          $this->rebuildDB($pwd);
574     }
575     
576     protected function rebuildDB($pwd)
577     {
578          $media_dir = $pwd ? $pwd : '.';
579         
580          $strReq =
581          'SELECT media_file, media_id '.
582          'FROM '.$this->table.' '.
583          "WHERE media_path = '".$this->path."' ".
584          "AND media_dir = '".$this->con->escape($media_dir)."' ";
585         
586          $rs = $this->con->select($strReq);
587         
588          $delReq = 'DELETE FROM '.$this->table.' '.
589                    'WHERE media_id IN (%s) ';
590          $del_ids = array();
591         
592          while ($rs->fetch())
593          {
594               if (!is_file($this->root.'/'.$rs->media_file)) {
595                    $del_ids[] = (integer) $rs->media_id;
596               }
597          }
598         
599          if (!empty($del_ids)) {
600               $this->con->execute(sprintf($delReq,implode(',',$del_ids)));
601          }
602     }
603     
604     public function makeDir($d)
605     {
606          $d = files::tidyFileName($d);
607          parent::makeDir($d);
608     }
609     
610     /**
611     Creates or updates a file in database. Returns new media ID or false if
612     file does not exist.
613     
614     @param    name      <b>string</b>       File name (relative to working directory)
615     @param    title     <b>string</b>       File title
616     @param    private   <b>boolean</b>      File is private
617     @param    dt        <b>string</b>       File date
618     @return   <b>integer</b> New media ID
619     */
620     public function createFile($name,$title=null,$private=false,$dt=null,$force=true)
621     {
622          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
623               throw new Exception(__('Permission denied.'));
624          }
625         
626          $file = $this->pwd.'/'.$name;
627          if (!file_exists($file)) {
628               return false;
629          }
630         
631          $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$name) : path::clean($name);
632          $media_type = files::getMimeType($name);
633         
634          $cur = $this->con->openCursor($this->table);
635         
636          $strReq = 'SELECT media_id '.
637                    'FROM '.$this->table.' '.
638                    "WHERE media_path = '".$this->con->escape($this->path)."' ".
639                    "AND media_file = '".$this->con->escape($media_file)."' ";
640         
641          $rs = $this->con->select($strReq);
642         
643          if ($rs->isEmpty())
644          {
645               $this->con->writeLock($this->table);
646               try
647               {
648                    $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->table);
649                    $media_id = (integer) $rs->f(0) + 1;
650                   
651                    $cur->media_id = $media_id;
652                    $cur->user_id = (string) $this->core->auth->userID();
653                    $cur->media_path = (string) $this->path;
654                    $cur->media_file = (string) $media_file;
655                    $cur->media_dir = (string) dirname($media_file);
656                    $cur->media_creadt = date('Y-m-d H:i:s');
657                    $cur->media_upddt = date('Y-m-d H:i:s');
658                   
659                    $cur->media_title = !$title ? (string) $name : (string) $title;
660                    $cur->media_private = (integer) (boolean) $private;
661                   
662                    if ($dt) {
663                         $cur->media_dt = (string) $dt;
664                    } else {
665                         $cur->media_dt = strftime('%Y-%m-%d %H:%M:%S',filemtime($file));
666                    }
667                   
668                    try {
669                         $cur->insert();
670                    } catch (Exception $e) {
671                         @unlink($name);
672                         throw $e;
673                    }
674                    $this->con->unlock();
675               }
676               catch (Exception $e)
677               {
678                    $this->con->unlock();
679                    throw $e;
680               }
681          }
682          else
683          {
684               $media_id = (integer) $rs->media_id;
685               
686               $cur->media_upddt = date('Y-m-d H:i:s');
687               
688               $cur->update('WHERE media_id = '.$media_id);
689          }
690         
691          $this->callFileHandler($media_type,'create',$cur,$name,$media_id,$force);
692         
693          return $media_id;
694     }
695     
696     /**
697     Updates a file in database.
698     
699     @param    file      <b>fileItem</b>     Current fileItem object
700     @param    newFile   <b>fileItem</b>     New fileItem object
701     */
702     public function updateFile($file,$newFile)
703     {
704          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
705               throw new Exception(__('Permission denied.'));
706          }
707         
708          $id = (integer) $file->media_id;
709         
710          if (!$id) {
711               throw new Exception('No file ID');
712          }
713         
714          if (!$this->core->auth->check('media_admin',$this->core->blog->id)
715          && $this->core->auth->userID() != $file->media_user) {
716               throw new Exception(__('You are not the file owner.'));
717          }
718         
719          $cur = $this->con->openCursor($this->table);
720         
721          # We need to tidy newFile basename. If dir isn't empty, concat to basename
722          $newFile->relname = files::tidyFileName($newFile->basename);
723          if ($newFile->dir) {
724               $newFile->relname = $newFile->dir.'/'.$newFile->relname;
725          }
726         
727          if ($file->relname != $newFile->relname) {
728               $newFile->file = $this->root.'/'.$newFile->relname;
729               
730               if ($this->isFileExclude($newFile->relname)) {
731                    throw new Exception(__('This file is not allowed.'));
732               }
733               
734               if (file_exists($newFile->file)) {
735                    throw new Exception(__('New file already exists.'));
736               }
737               
738               $this->moveFile($file->relname,$newFile->relname);
739               
740               $cur->media_file = (string) $newFile->relname;
741               $cur->media_dir = (string) dirname($newFile->relname);
742          }
743         
744          $cur->media_title = (string) $newFile->media_title;
745          $cur->media_dt = (string) $newFile->media_dtstr;
746          $cur->media_upddt = date('Y-m-d H:i:s');
747          $cur->media_private = (integer) $newFile->media_priv;
748         
749          $cur->update('WHERE media_id = '.$id);
750         
751          $this->callFileHandler($file->type,'update',$file,$newFile);
752     }
753     
754     /**
755     Uploads a file.
756     
757     @param    tmp       <b>string</b>       Full path of temporary uploaded file
758     @param    name      <b>string</b>       File name (relative to working directory)
759     @param    title     <b>string</b>       File title
760     @param    private   <b>boolean</b>      File is private
761     */
762     public function uploadFile($tmp,$name,$title=null,$private=false,$overwrite=false)
763     {
764          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
765               throw new Exception(__('Permission denied.'));
766          }
767         
768          $name = files::tidyFileName($name);
769         
770          parent::uploadFile($tmp,$name,$overwrite);
771         
772          return $this->createFile($name,$title,$private);
773     }
774     
775     /**
776     Creates a file from binary content.
777     
778     @param    name      <b>string</b>       File name (relative to working directory)
779     @param    bits      <b>string</b>       Binary file content
780     */
781     public function uploadBits($name,$bits)
782     {
783          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
784               throw new Exception(__('Permission denied.'));
785          }
786         
787          $name = files::tidyFileName($name);
788         
789          parent::uploadBits($name,$bits);
790         
791          return $this->createFile($name,null,null);
792     }
793     
794     /**
795     Removes a file.
796     
797     @param    f         <b>fileItem</b>     fileItem object
798     */
799     public function removeFile($f)
800     {
801          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
802               throw new Exception(__('Permission denied.'));
803          }
804         
805          $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$f) : path::clean($f);
806         
807          $strReq = 'DELETE FROM '.$this->table.' '.
808                    "WHERE media_path = '".$this->con->escape($this->path)."' ".
809                    "AND media_file = '".$this->con->escape($media_file)."' ";
810         
811          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
812          {
813               $strReq .= "AND user_id = '".$this->con->escape($this->core->auth->userID())."'";
814          }
815         
816          $this->con->execute($strReq);
817         
818          if ($this->con->changes() == 0) {
819               throw new Exception(__('File does not exist in the database.'));
820          }
821         
822          parent::removeFile($f);
823         
824          $this->callFileHandler(files::getMimeType($media_file),'remove',$f);
825     }
826
827     /**
828     * Root directories
829     *
830     * Returns an array of directory under {@link $root} directory.
831     *
832     * @uses fileItem
833     * @return array
834     */
835     public function getDBDirs()
836     {
837          $media_dir = $this->relpwd ? $this->relpwd : '.';
838         
839          $strReq =
840          'SELECT distinct media_dir '.
841          'FROM '.$this->table.' '.
842          "WHERE media_path = '".$this->path."'";
843          $rs = $this->con->select($strReq);
844          while ($rs->fetch()) {
845               if (is_dir($this->root.'/'.$rs->media_dir))
846                    $dir[] = ($rs->media_dir == '.' ? '' : $rs->media_dir);
847          }
848         
849          return $dir;
850     }
851     
852     /**
853     Extract zip file in current location
854     
855     @param    f         <b>fileRecord</b>   fileRecord object
856     */
857     public function inflateZipFile($f,$create_dir=true)
858     {
859          $zip = new fileUnzip($f->file);
860          $zip->setExcludePattern($this->exclude_pattern);
861          $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#');
862         
863          if ($create_dir)
864          {
865               $zip_root_dir = $zip->getRootDir();
866               if ($zip_root_dir != false) {
867                    $destination = $zip_root_dir;
868                    $target = $f->dir;
869               } else {
870                    $destination = preg_replace('/\.([^.]+)$/','',$f->basename);
871                    $target = $f->dir.'/'.$destination;
872               }
873               
874               if (is_dir($f->dir.'/'.$destination)) {
875                    throw new Exception(sprintf(__('Extract destination directory %s already exists.'),dirname($f->relname).'/'.$destination)); 
876               }
877          }
878          else
879          {
880               $target = $f->dir;
881               $destination = '';
882          }
883         
884          $zip->unzipAll($target);
885          $zip->close();
886          return dirname($f->relname).'/'.$destination;
887     }
888     
889     /**
890     Returns zip file content
891     
892     @param    f         <b>fileRecord</b>   fileRecord object
893     @return <b>array</b>
894     */
895     public function getZipContent($f)
896     {
897          $zip = new fileUnzip($f->file);
898          $list = $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#');
899          $zip->close();
900          return $list;
901     }
902
903     /**
904     Calls file handlers registered for recreate event
905     
906     @param    f    <b>fileItem</b>     fileItem object
907     */
908     public function mediaFireRecreateEvent($f)
909     {
910          $media_type = files::getMimeType($f->basename);
911          $this->callFileHandler($media_type,'recreate',null,$f->basename); // Args list to be completed as necessary (Franck)
912     }
913     
914     /* Image handlers
915     ------------------------------------------------------- */
916     public function imageThumbCreate($cur,$f,$force=true)
917     {
918          $file = $this->pwd.'/'.$f;
919         
920          if (!file_exists($file)) {
921               return false;
922          }
923         
924          $p = path::info($file);
925          $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
926          $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
927         
928          try
929          {
930               $img = new imageTools();
931               $img->loadImage($file);
932               
933               $w = $img->getW();
934               $h = $img->getH();
935               
936               if ($force) $this->imageThumbRemove($f);
937               
938               foreach ($this->thumb_sizes as $suffix => $s) {
939                    $thumb_file = sprintf($thumb,$suffix);
940                    if (!file_exists($thumb_file) && $s[0] > 0 &&
941                         ($suffix == 'sq' || $w > $s[0] || $h > $s[0]))
942                    {
943                         $rate = ($s[0] < 100 ? 95 : ($s[0] < 600 ? 90 : 85));
944                         $img->resize($s[0],$s[0],$s[1]);
945                         $img->output(($alpha ? 'png' : 'jpeg'),$thumb_file,$rate);
946                         $img->loadImage($file);
947                    }
948               }
949               $img->close();
950          }
951          catch (Exception $e)
952          {
953               if ($cur === null) { # Called only if cursor is null (public call)
954                    throw $e;
955               }
956          }
957     }
958     
959     protected function imageThumbUpdate($file,$newFile)
960     {
961          if ($file->relname != $newFile->relname)
962          {
963               $p = path::info($file->relname);
964               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
965               $thumb_old = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
966               
967               $p = path::info($newFile->relname);
968               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
969               $thumb_new = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
970               
971               foreach ($this->thumb_sizes as $suffix => $s) {
972                    try {
973                         parent::moveFile(sprintf($thumb_old,$suffix),sprintf($thumb_new,$suffix));
974                    } catch (Exception $e) {}
975               }
976          }
977     }
978     
979     protected function imageThumbRemove($f)
980     {
981          $p = path::info($f);
982          $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
983          $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),'',$p['base'],'%s');
984         
985          foreach ($this->thumb_sizes as $suffix => $s) {
986               try {
987                    parent::removeFile(sprintf($thumb,$suffix));
988               } catch (Exception $e) {}
989          }
990     }
991     
992     protected function imageMetaCreate($cur,$f,$id)
993     {
994          $file = $this->pwd.'/'.$f;
995         
996          if (!file_exists($file)) {
997               return false;
998          }
999         
1000          $xml = new xmlTag('meta');
1001          $meta = imageMeta::readMeta($file);
1002          $xml->insertNode($meta);
1003         
1004          $c = $this->core->con->openCursor($this->table);
1005          $c->media_meta = $xml->toXML();
1006         
1007          if ($cur->media_title !== null && $cur->media_title == basename($cur->media_file))
1008          {
1009               if ($meta['Title']) {
1010                    $c->media_title = $meta['Title'];
1011               }
1012          }
1013         
1014          if ($meta['DateTimeOriginal'] && $cur->media_dt === '')
1015          {
1016               # We set picture time to user timezone
1017               $media_ts = strtotime($meta['DateTimeOriginal']);
1018               if ($media_ts !== false) {
1019                    $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts);
1020                    $c->media_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o);
1021               }
1022          }
1023         
1024          $c->update('WHERE media_id = '.$id);
1025     }
1026     
1027     /**
1028     Returns HTML code for MP3 player
1029     
1030     @param    url       <b>string</b>       MP3 URL to play
1031     @param    player    <b>string</b>       Player URL
1032     @param    args      <b>array</b>        Player parameters
1033     @return   <b>string</b>
1034     */
1035     public static function mp3player($url,$player=null,$args=null)
1036     {
1037          if (!$player) {
1038               $player = 'player_mp3.swf';
1039          }
1040         
1041          if (!is_array($args))
1042          {
1043               $args = array(
1044                    'showvolume' => 1,
1045                    'loadingcolor' => 'ff9900',
1046                    'bgcolor1' => 'eeeeee',
1047                    'bgcolor2' => 'cccccc',
1048                    'buttoncolor' => '0066cc',
1049                    'buttonovercolor' => 'ff9900',
1050                    'slidercolor1' => 'cccccc',
1051                    'slidercolor2' => '999999',
1052                    'sliderovercolor' => '0066cc'
1053               );
1054          }
1055         
1056          $args['mp3'] = $url;
1057         
1058          if (empty($args['width'])) {
1059               $args['width'] = 200;
1060          }
1061          if (empty($args['height'])) {
1062               $args['height'] = 20;
1063          }
1064         
1065          $vars = array();
1066          foreach ($args as $k => $v) {
1067               $vars[] = $k.'='.$v;
1068          }
1069         
1070          return
1071          '<object type="application/x-shockwave-flash" '.
1072          'data="'.$player.'" '.
1073          'width="'.$args['width'].'" height="'.$args['height'].'">'.
1074          '<param name="movie" value="'.$player.'" />'.
1075          '<param name="wmode" value="transparent" />'.
1076          '<param name="FlashVars" value="'.implode('&amp;',$vars).'" />'.
1077          __('Embedded Audio Player').
1078          '</object>';
1079     }
1080     
1081     public static function flvplayer($url,$player=null,$args=null)
1082     {
1083          if (!$player) {
1084               $player = 'player_flv.swf';
1085          }
1086         
1087          if (!is_array($args))
1088          {
1089               $args = array(
1090                    'margin' => 1,
1091                    'showvolume' => 1,
1092                    'showtime' => 1,
1093                    'showfullscreen' => 1,
1094                    'buttonovercolor' => 'ff9900',
1095                    'slidercolor1' => 'cccccc',
1096                    'slidercolor2' => '999999',
1097                    'sliderovercolor' => '0066cc'
1098               );
1099          }
1100         
1101          $args['flv'] = $url;
1102         
1103          if (empty($args['width'])) {
1104               $args['width'] = 400;
1105          }
1106          if (empty($args['height'])) {
1107               $args['height'] = 300;
1108          }
1109         
1110          $vars = array();
1111          foreach ($args as $k => $v) {
1112               $vars[] = $k.'='.$v;
1113          }
1114         
1115          return
1116          '<object type="application/x-shockwave-flash" '.
1117          'data="'.$player.'" '.
1118          'width="'.$args['width'].'" height="'.$args['height'].'">'.
1119          '<param name="movie" value="'.$player.'" />'.
1120          '<param name="wmode" value="transparent" />'.
1121          '<param name="allowFullScreen" value="true" />'.
1122          '<param name="FlashVars" value="'.implode('&amp;',$vars).'" />'.
1123          __('Embedded Video Player').
1124          '</object>';
1125     }
1126}
1127?>
Note: See TracBrowser for help on using the repository browser.

Sites map