Dotclear

source: inc/core/class.dc.media.php @ 1705:0f4123c4d1c5

Revision 1705:0f4123c4d1c5, 30.8 KB checked in by kevin@…, 12 years ago (diff)

Ticket #1406 : nouveaux messages d'erreur.

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 directory /public/ write to the location indicated in about:config \"public_path\". You must create this directory in the specified location, or change the settings and assign permissions to read, write and execute for everyone."));
79               } else {
80                    throw new Exception(__("There is no directory /public/ write to the location indicated in about:config \"public_path\". You must 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     @param    return_rs <b>boolean</b>      Whether to return a resultset (true) or an array (false, default value).
519     @return   <b>array</b> Array or ResultSet of fileItems
520     */
521     public function getPostMedia($post_id,$media_id=null,$return_rs=false)
522     {
523          $params = array(
524               'post_id' => $post_id,
525               'media_path' => $this->path
526          );
527          if ($media_id) {
528               $params['media_id'] = (integer) $media_id;
529          }
530          $rs = $this->postmedia->getPostMedia($params);
531         
532          $res = array();
533         
534          while ($rs->fetch()) {
535               $f = $this->fileRecord($rs);
536               if ($f !== null) {
537                    $res[] = $return_rs ? new ArrayObject($f) : $f;
538               }
539          }
540         
541          return $return_rs ? staticRecord::newFromArray($res) : $res;
542     }
543     
544     /**
545     @deprecated since version 2.4
546     @see dcPostMedia::addPostMedia
547     */
548     public function addPostMedia($post_id,$media_id)
549     {
550          $this->postmedia->addPostMedia($post_id,$media_id);
551     }
552     
553     /**
554     @deprecated since version 2.4
555     @see dcPostMedia::removePostMedia
556     */
557     public function removePostMedia($post_id,$media_id)
558     {
559          $this->postmedia->removePostMedia($post_id,$media_id,"attachment");
560     }
561     
562     /**
563     Rebuilds database items collection. Optional <var>$pwd</var> parameter is
564     the path where to start rebuild.
565     
566     @param    pwd       <b>string</b>       Directory to rebuild
567     */
568     public function rebuild($pwd='')
569     {
570          if (!$this->core->auth->isSuperAdmin()) {
571               throw new Exception(__('You are not a super administrator.'));
572          }
573         
574          $this->chdir($pwd);
575          parent::getDir();
576         
577          $dir = $this->dir;
578         
579          foreach ($dir['dirs'] as $d) {
580               if (!$d->parent) {
581                    $this->rebuild($d->relname,false);
582               }
583          }
584         
585          foreach ($dir['files'] as $f) {
586               $this->chdir(dirname($f->relname));
587               $this->createFile($f->basename);
588          }
589         
590          $this->rebuildDB($pwd);
591     }
592     
593     protected function rebuildDB($pwd)
594     {
595          $media_dir = $pwd ? $pwd : '.';
596         
597          $strReq =
598          'SELECT media_file, media_id '.
599          'FROM '.$this->table.' '.
600          "WHERE media_path = '".$this->path."' ".
601          "AND media_dir = '".$this->con->escape($media_dir)."' ";
602         
603          $rs = $this->con->select($strReq);
604         
605          $delReq = 'DELETE FROM '.$this->table.' '.
606                    'WHERE media_id IN (%s) ';
607          $del_ids = array();
608         
609          while ($rs->fetch())
610          {
611               if (!is_file($this->root.'/'.$rs->media_file)) {
612                    $del_ids[] = (integer) $rs->media_id;
613               }
614          }
615         
616          if (!empty($del_ids)) {
617               $this->con->execute(sprintf($delReq,implode(',',$del_ids)));
618          }
619     }
620     
621     public function makeDir($d)
622     {
623          $d = files::tidyFileName($d);
624          parent::makeDir($d);
625     }
626     
627     /**
628     Creates or updates a file in database. Returns new media ID or false if
629     file does not exist.
630     
631     @param    name      <b>string</b>       File name (relative to working directory)
632     @param    title     <b>string</b>       File title
633     @param    private   <b>boolean</b>      File is private
634     @param    dt        <b>string</b>       File date
635     @return   <b>integer</b> New media ID
636     */
637     public function createFile($name,$title=null,$private=false,$dt=null,$force=true)
638     {
639          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
640               throw new Exception(__('Permission denied.'));
641          }
642         
643          $file = $this->pwd.'/'.$name;
644          if (!file_exists($file)) {
645               return false;
646          }
647         
648          $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$name) : path::clean($name);
649          $media_type = files::getMimeType($name);
650         
651          $cur = $this->con->openCursor($this->table);
652         
653          $strReq = 'SELECT media_id '.
654                    'FROM '.$this->table.' '.
655                    "WHERE media_path = '".$this->con->escape($this->path)."' ".
656                    "AND media_file = '".$this->con->escape($media_file)."' ";
657         
658          $rs = $this->con->select($strReq);
659         
660          if ($rs->isEmpty())
661          {
662               $this->con->writeLock($this->table);
663               try
664               {
665                    $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->table);
666                    $media_id = (integer) $rs->f(0) + 1;
667                   
668                    $cur->media_id = $media_id;
669                    $cur->user_id = (string) $this->core->auth->userID();
670                    $cur->media_path = (string) $this->path;
671                    $cur->media_file = (string) $media_file;
672                    $cur->media_dir = (string) dirname($media_file);
673                    $cur->media_creadt = date('Y-m-d H:i:s');
674                    $cur->media_upddt = date('Y-m-d H:i:s');
675                   
676                    $cur->media_title = !$title ? (string) $name : (string) $title;
677                    $cur->media_private = (integer) (boolean) $private;
678                   
679                    if ($dt) {
680                         $cur->media_dt = (string) $dt;
681                    } else {
682                         $cur->media_dt = strftime('%Y-%m-%d %H:%M:%S',filemtime($file));
683                    }
684                   
685                    try {
686                         $cur->insert();
687                    } catch (Exception $e) {
688                         @unlink($name);
689                         throw $e;
690                    }
691                    $this->con->unlock();
692               }
693               catch (Exception $e)
694               {
695                    $this->con->unlock();
696                    throw $e;
697               }
698          }
699          else
700          {
701               $media_id = (integer) $rs->media_id;
702               
703               $cur->media_upddt = date('Y-m-d H:i:s');
704               
705               $cur->update('WHERE media_id = '.$media_id);
706          }
707         
708          $this->callFileHandler($media_type,'create',$cur,$name,$media_id,$force);
709         
710          return $media_id;
711     }
712     
713     /**
714     Updates a file in database.
715     
716     @param    file      <b>fileItem</b>     Current fileItem object
717     @param    newFile   <b>fileItem</b>     New fileItem object
718     */
719     public function updateFile($file,$newFile)
720     {
721          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
722               throw new Exception(__('Permission denied.'));
723          }
724         
725          $id = (integer) $file->media_id;
726         
727          if (!$id) {
728               throw new Exception('No file ID');
729          }
730         
731          if (!$this->core->auth->check('media_admin',$this->core->blog->id)
732          && $this->core->auth->userID() != $file->media_user) {
733               throw new Exception(__('You are not the file owner.'));
734          }
735         
736          $cur = $this->con->openCursor($this->table);
737         
738          # We need to tidy newFile basename. If dir isn't empty, concat to basename
739          $newFile->relname = files::tidyFileName($newFile->basename);
740          if ($newFile->dir) {
741               $newFile->relname = $newFile->dir.'/'.$newFile->relname;
742          }
743         
744          if ($file->relname != $newFile->relname) {
745               $newFile->file = $this->root.'/'.$newFile->relname;
746               
747               if ($this->isFileExclude($newFile->relname)) {
748                    throw new Exception(__('This file is not allowed.'));
749               }
750               
751               if (file_exists($newFile->file)) {
752                    throw new Exception(__('New file already exists.'));
753               }
754               
755               $this->moveFile($file->relname,$newFile->relname);
756               
757               $cur->media_file = (string) $newFile->relname;
758               $cur->media_dir = (string) dirname($newFile->relname);
759          }
760         
761          $cur->media_title = (string) $newFile->media_title;
762          $cur->media_dt = (string) $newFile->media_dtstr;
763          $cur->media_upddt = date('Y-m-d H:i:s');
764          $cur->media_private = (integer) $newFile->media_priv;
765         
766          $cur->update('WHERE media_id = '.$id);
767         
768          $this->callFileHandler($file->type,'update',$file,$newFile);
769     }
770     
771     /**
772     Uploads a file.
773     
774     @param    tmp       <b>string</b>       Full path of temporary uploaded file
775     @param    name      <b>string</b>       File name (relative to working directory)
776     @param    title     <b>string</b>       File title
777     @param    private   <b>boolean</b>      File is private
778     */
779     public function uploadFile($tmp,$name,$title=null,$private=false,$overwrite=false)
780     {
781          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
782               throw new Exception(__('Permission denied.'));
783          }
784         
785          $name = files::tidyFileName($name);
786         
787          parent::uploadFile($tmp,$name,$overwrite);
788         
789          return $this->createFile($name,$title,$private);
790     }
791     
792     /**
793     Creates a file from binary content.
794     
795     @param    name      <b>string</b>       File name (relative to working directory)
796     @param    bits      <b>string</b>       Binary file content
797     */
798     public function uploadBits($name,$bits)
799     {
800          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
801               throw new Exception(__('Permission denied.'));
802          }
803         
804          $name = files::tidyFileName($name);
805         
806          parent::uploadBits($name,$bits);
807         
808          return $this->createFile($name,null,null);
809     }
810     
811     /**
812     Removes a file.
813     
814     @param    f         <b>fileItem</b>     fileItem object
815     */
816     public function removeFile($f)
817     {
818          if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) {
819               throw new Exception(__('Permission denied.'));
820          }
821         
822          $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$f) : path::clean($f);
823         
824          $strReq = 'DELETE FROM '.$this->table.' '.
825                    "WHERE media_path = '".$this->con->escape($this->path)."' ".
826                    "AND media_file = '".$this->con->escape($media_file)."' ";
827         
828          if (!$this->core->auth->check('media_admin',$this->core->blog->id))
829          {
830               $strReq .= "AND user_id = '".$this->con->escape($this->core->auth->userID())."'";
831          }
832         
833          $this->con->execute($strReq);
834         
835          if ($this->con->changes() == 0) {
836               throw new Exception(__('File does not exist in the database.'));
837          }
838         
839          parent::removeFile($f);
840         
841          $this->callFileHandler(files::getMimeType($media_file),'remove',$f);
842     }
843
844     /**
845     * Root directories
846     *
847     * Returns an array of directory under {@link $root} directory.
848     *
849     * @uses fileItem
850     * @return array
851     */
852     public function getDBDirs()
853     {
854          $media_dir = $this->relpwd ? $this->relpwd : '.';
855         
856          $strReq =
857          'SELECT distinct media_dir '.
858          'FROM '.$this->table.' '.
859          "WHERE media_path = '".$this->path."'";
860          $rs = $this->con->select($strReq);
861          while ($rs->fetch()) {
862               if (is_dir($this->root.'/'.$rs->media_dir))
863                    $dir[] = ($rs->media_dir == '.' ? '' : $rs->media_dir);
864          }
865         
866          return $dir;
867     }
868     
869     /**
870     Extract zip file in current location
871     
872     @param    f         <b>fileRecord</b>   fileRecord object
873     */
874     public function inflateZipFile($f,$create_dir=true)
875     {
876          $zip = new fileUnzip($f->file);
877          $zip->setExcludePattern($this->exclude_pattern);
878          $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#');
879         
880          if ($create_dir)
881          {
882               $zip_root_dir = $zip->getRootDir();
883               if ($zip_root_dir != false) {
884                    $destination = $zip_root_dir;
885                    $target = $f->dir;
886               } else {
887                    $destination = preg_replace('/\.([^.]+)$/','',$f->basename);
888                    $target = $f->dir.'/'.$destination;
889               }
890               
891               if (is_dir($f->dir.'/'.$destination)) {
892                    throw new Exception(sprintf(__('Extract destination directory %s already exists.'),dirname($f->relname).'/'.$destination)); 
893               }
894          }
895          else
896          {
897               $target = $f->dir;
898               $destination = '';
899          }
900         
901          $zip->unzipAll($target);
902          $zip->close();
903          return dirname($f->relname).'/'.$destination;
904     }
905     
906     /**
907     Returns zip file content
908     
909     @param    f         <b>fileRecord</b>   fileRecord object
910     @return <b>array</b>
911     */
912     public function getZipContent($f)
913     {
914          $zip = new fileUnzip($f->file);
915          $list = $zip->getList(false,'#(^|/)(__MACOSX|\.svn|\.DS_Store|\.directory|Thumbs\.db)(/|$)#');
916          $zip->close();
917          return $list;
918     }
919
920     /**
921     Calls file handlers registered for recreate event
922     
923     @param    f    <b>fileItem</b>     fileItem object
924     */
925     public function mediaFireRecreateEvent($f)
926     {
927          $media_type = files::getMimeType($f->basename);
928          $this->callFileHandler($media_type,'recreate',null,$f->basename); // Args list to be completed as necessary (Franck)
929     }
930     
931     /* Image handlers
932     ------------------------------------------------------- */
933     public function imageThumbCreate($cur,$f,$force=true)
934     {
935          $file = $this->pwd.'/'.$f;
936         
937          if (!file_exists($file)) {
938               return false;
939          }
940         
941          $p = path::info($file);
942          $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
943          $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
944         
945          try
946          {
947               $img = new imageTools();
948               $img->loadImage($file);
949               
950               $w = $img->getW();
951               $h = $img->getH();
952               
953               if ($force) $this->imageThumbRemove($f);
954               
955               foreach ($this->thumb_sizes as $suffix => $s) {
956                    $thumb_file = sprintf($thumb,$suffix);
957                    if (!file_exists($thumb_file) && $s[0] > 0 &&
958                         ($suffix == 'sq' || $w > $s[0] || $h > $s[0]))
959                    {
960                         $rate = ($s[0] < 100 ? 95 : ($s[0] < 600 ? 90 : 85));
961                         $img->resize($s[0],$s[0],$s[1]);
962                         $img->output(($alpha ? 'png' : 'jpeg'),$thumb_file,$rate);
963                         $img->loadImage($file);
964                    }
965               }
966               $img->close();
967          }
968          catch (Exception $e)
969          {
970               if ($cur === null) { # Called only if cursor is null (public call)
971                    throw $e;
972               }
973          }
974     }
975     
976     protected function imageThumbUpdate($file,$newFile)
977     {
978          if ($file->relname != $newFile->relname)
979          {
980               $p = path::info($file->relname);
981               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
982               $thumb_old = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
983               
984               $p = path::info($newFile->relname);
985               $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
986               $thumb_new = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
987               
988               foreach ($this->thumb_sizes as $suffix => $s) {
989                    try {
990                         parent::moveFile(sprintf($thumb_old,$suffix),sprintf($thumb_new,$suffix));
991                    } catch (Exception $e) {}
992               }
993          }
994     }
995     
996     protected function imageThumbRemove($f)
997     {
998          $p = path::info($f);
999          $alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
1000          $thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),'',$p['base'],'%s');
1001         
1002          foreach ($this->thumb_sizes as $suffix => $s) {
1003               try {
1004                    parent::removeFile(sprintf($thumb,$suffix));
1005               } catch (Exception $e) {}
1006          }
1007     }
1008     
1009     protected function imageMetaCreate($cur,$f,$id)
1010     {
1011          $file = $this->pwd.'/'.$f;
1012         
1013          if (!file_exists($file)) {
1014               return false;
1015          }
1016         
1017          $xml = new xmlTag('meta');
1018          $meta = imageMeta::readMeta($file);
1019          $xml->insertNode($meta);
1020         
1021          $c = $this->core->con->openCursor($this->table);
1022          $c->media_meta = $xml->toXML();
1023         
1024          if ($cur->media_title !== null && $cur->media_title == basename($cur->media_file))
1025          {
1026               if ($meta['Title']) {
1027                    $c->media_title = $meta['Title'];
1028               }
1029          }
1030         
1031          if ($meta['DateTimeOriginal'] && $cur->media_dt === '')
1032          {
1033               # We set picture time to user timezone
1034               $media_ts = strtotime($meta['DateTimeOriginal']);
1035               if ($media_ts !== false) {
1036                    $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts);
1037                    $c->media_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o);
1038               }
1039          }
1040         
1041          $c->update('WHERE media_id = '.$id);
1042     }
1043     
1044     /**
1045     Returns HTML code for MP3 player
1046     
1047     @param    url       <b>string</b>       MP3 URL to play
1048     @param    player    <b>string</b>       Player URL
1049     @param    args      <b>array</b>        Player parameters
1050     @return   <b>string</b>
1051     */
1052     public static function mp3player($url,$player=null,$args=null)
1053     {
1054          if (!$player) {
1055               $player = 'player_mp3.swf';
1056          }
1057         
1058          if (!is_array($args))
1059          {
1060               $args = array(
1061                    'showvolume' => 1,
1062                    'loadingcolor' => 'ff9900',
1063                    'bgcolor1' => 'eeeeee',
1064                    'bgcolor2' => 'cccccc',
1065                    'buttoncolor' => '0066cc',
1066                    'buttonovercolor' => 'ff9900',
1067                    'slidercolor1' => 'cccccc',
1068                    'slidercolor2' => '999999',
1069                    'sliderovercolor' => '0066cc'
1070               );
1071          }
1072         
1073          $args['mp3'] = $url;
1074         
1075          if (empty($args['width'])) {
1076               $args['width'] = 200;
1077          }
1078          if (empty($args['height'])) {
1079               $args['height'] = 20;
1080          }
1081         
1082          $vars = array();
1083          foreach ($args as $k => $v) {
1084               $vars[] = $k.'='.$v;
1085          }
1086         
1087          return
1088          '<object type="application/x-shockwave-flash" '.
1089          'data="'.$player.'" '.
1090          'width="'.$args['width'].'" height="'.$args['height'].'">'.
1091          '<param name="movie" value="'.$player.'" />'.
1092          '<param name="wmode" value="transparent" />'.
1093          '<param name="FlashVars" value="'.implode('&amp;',$vars).'" />'.
1094          __('Embedded Audio Player').
1095          '</object>';
1096     }
1097     
1098     public static function flvplayer($url,$player=null,$args=null)
1099     {
1100          if (!$player) {
1101               $player = 'player_flv.swf';
1102          }
1103         
1104          if (!is_array($args))
1105          {
1106               $args = array(
1107                    'margin' => 1,
1108                    'showvolume' => 1,
1109                    'showtime' => 1,
1110                    'showfullscreen' => 1,
1111                    'buttonovercolor' => 'ff9900',
1112                    'slidercolor1' => 'cccccc',
1113                    'slidercolor2' => '999999',
1114                    'sliderovercolor' => '0066cc'
1115               );
1116          }
1117         
1118          $args['flv'] = $url;
1119         
1120          if (empty($args['width'])) {
1121               $args['width'] = 400;
1122          }
1123          if (empty($args['height'])) {
1124               $args['height'] = 300;
1125          }
1126         
1127          $vars = array();
1128          foreach ($args as $k => $v) {
1129               $vars[] = $k.'='.$v;
1130          }
1131         
1132          return
1133          '<object type="application/x-shockwave-flash" '.
1134          'data="'.$player.'" '.
1135          'width="'.$args['width'].'" height="'.$args['height'].'">'.
1136          '<param name="movie" value="'.$player.'" />'.
1137          '<param name="wmode" value="transparent" />'.
1138          '<param name="allowFullScreen" value="true" />'.
1139          '<param name="FlashVars" value="'.implode('&amp;',$vars).'" />'.
1140          __('Embedded Video Player').
1141          '</object>';
1142     }
1143}
1144?>
Note: See TracBrowser for help on using the repository browser.

Sites map