Dotclear

source: inc/core/class.dc.media.php @ 0:54703be25dd6

Revision 0:54703be25dd6, 28.2 KB checked in by Dsls <dsls@…>, 15 years ago (diff)

2.3 branch (trunk) first checkin

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

Sites map