Dotclear

source: inc/core/class.dc.media.php @ 1123:0eee9bcfc116

Revision 1123:0eee9bcfc116, 29.0 KB checked in by franck <carnet.franck.paul@…>, 11 years ago (diff)

Cope with media in root media folder, fixes #1388

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

Sites map