Dotclear

source: inc/core/class.dc.media.php @ 1468:3132a0aca046

Revision 1468:3132a0aca046, 29.6 KB checked in by franck <carnet.franck.paul@…>, 12 years ago (diff)

Merge 2.5 commits into default branch (should be verified)

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

Sites map