Dotclear

source: inc/core/class.dc.media.php @ 1718:5bbbd8bb73fb

Revision 1718:5bbbd8bb73fb, 30.4 KB checked in by franck <carnet.franck.paul@…>, 12 years ago (diff)

Merge 2.5 branch into default

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

Sites map