Dotclear

source: inc/core/class.dc.media.php @ 2:4f1756320ee0

Revision 2:4f1756320ee0, 28.8 KB checked in by Franck, 14 years ago (diff)

Fix #1076 : a new recreate event is now fired when user asks for thumbnails recreation.

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

Sites map