Dotclear

source: inc/core/class.dc.media.php @ 1267:8f84bd93eb1d

Revision 1267:8f84bd93eb1d, 29.1 KB checked in by akewea, 12 years ago (diff)

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

Sites map