0byt3m1n1-V2
Path:
/
home
/
magalijoj
/
www
/
blog
/
inc
/
core
/
[
Home
]
File: class.dc.media.php
<?php # ***** BEGIN LICENSE BLOCK ***** # This file is part of DotClear. # Copyright (c) 2005 Olivier Meunier and contributors. All rights # reserved. # # DotClear is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # DotClear is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with DotClear; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ***** END LICENSE BLOCK ***** /** @ingroup DC_CORE @brief Dotclear media manage This class handles Dotclear media items. */ class dcMedia extends filemanager { protected $core; ///< <b>dcCore</b> dcCore instance protected $con; ///< <b>connection</b> Database connection protected $table; ///< <b>string</b> Media table name protected $table_ref; ///< <b>string</b> Post-media relation table name protected $type; ///< <b>string</b> Media type filter protected $file_handler = array(); ///< <b>array</b> Array of callbacks public $thumb_tp = '%s/.%s_%s.jpg'; ///< <b>string</b> Thumbnail file pattern /** <b>array</b> Tubmnail sizes: - m: medium image - s: small image - t: thumbnail image - sq: square image */ public $thumb_sizes = array( 'm' => array(448,'ratio','medium'), 's' => array(240,'ratio','small'), 't' => array(100,'ratio','thumbnail'), 'sq' => array(48,'crop','square') ); public $icon_img = 'images/media/%s.png'; ///< <b>string</b> Icon file pattern /** Object constructor. @param core <b>dcCore</b> dcCore instance @param type <b>string</b> Media type filter */ public function __construct(&$core,$type='') { $this->core =& $core; $this->con =& $core->con; if ($this->core->blog == null) { throw new Exception(__('No blog defined.')); } $this->table = $this->core->prefix.'media'; $this->table_ref = $this->core->prefix.'post_media'; $root = $this->core->blog->public_path; $root_url = $this->core->blog->host.path::clean($this->core->blog->settings->public_url); if (!is_dir($root)) { throw new Exception(sprintf(__('Directory %s does not exist.'),$root)); } $this->type = $type; parent::__construct($root,$root_url); $this->chdir(''); $this->path = $this->core->blog->settings->public_path; $this->addExclusion(DC_RC_PATH); $this->addExclusion(dirname(__FILE__).'/../'); # Event handlers $this->addFileHandler('image/jpeg','create',array($this,'imageThumbCreate')); $this->addFileHandler('image/png','create',array($this,'imageThumbCreate')); $this->addFileHandler('image/gif','create',array($this,'imageThumbCreate')); $this->addFileHandler('image/png','update',array($this,'imageThumbUpdate')); $this->addFileHandler('image/jpeg','update',array($this,'imageThumbUpdate')); $this->addFileHandler('image/gif','update',array($this,'imageThumbUpdate')); $this->addFileHandler('image/png','remove',array($this,'imageThumbRemove')); $this->addFileHandler('image/jpeg','remove',array($this,'imageThumbRemove')); $this->addFileHandler('image/gif','remove',array($this,'imageThumbRemove')); $this->addFileHandler('image/jpeg','create',array($this,'imageMetaCreate')); } /** Changes working directory. @param dir <b>string</b> Directory name. */ public function chdir($dir) { parent::chdir($dir); $this->relpwd = preg_replace('/^'.preg_quote($this->root,'/').'\/?/','',$this->pwd); } /** Adds a new file handler for a given media type and event. Available events are: - create: file creation - update: file update - remove: file deletion @param type <b>string</b> Media type @param event <b>string</b> Event @param function <b>callback</b> */ public function addFileHandler($type,$event,$function) { if (is_callable($function)) { $this->file_handler[$type][$event][] = $function; } } protected function callFileHandler($type,$event) { if (!empty($this->file_handler[$type][$event])) { $args = func_get_args(); array_shift($args); array_shift($args); foreach ($this->file_handler[$type][$event] as $f) { call_user_func_array($f,$args); } } } /** Returns HTML breadCrumb for media manager navigation. @param href <b>string</b> URL pattern @return <b>string</b> HTML code */ public function breadCrumb($href) { $res = ''; if ($this->relpwd && $this->relpwd != '.') { $pwd = ''; foreach (explode('/',$this->relpwd) as $v) { $pwd .= rawurlencode($v).'/'; $res .= '<a href="'.sprintf($href,$pwd).'">'.$v.'</a> / '; } } return $res; } protected function fileRecord(&$rs) { if ($rs->isEmpty()) { return null; } if (is_file($this->root.'/'.$rs->media_file)) { $f = new fileItem($this->root.'/'.$rs->media_file,$this->root,$this->root_url); if ($this->type && $f->type_prefix != $this->type) { return null; } $f->editable = true; $f->media_id = $rs->media_id; $f->media_title = $rs->media_title; $f->media_meta = $rs->media_meta; $f->media_user = $rs->user_id; $f->media_priv = (boolean) $rs->media_private; $f->media_dt = strtotime($rs->media_dt); $f->media_dtstr = dt::str('%Y-%m-%d %H:%M',$f->media_dt); $f->media_image = false; if (!$this->core->auth->check('media_admin',$this->core->blog->id) && $this->core->auth->userID() != $f->media_user) { $f->del = false; $f->editable = false; } $type_prefix = explode('/',$f->type); $type_prefix = $type_prefix[0]; switch ($type_prefix) { case 'image': $f->media_image = true; $f->media_icon = 'image'; break; case 'audio': $f->media_icon = 'audio'; break; case 'text': $f->media_icon = 'text'; break; case 'video': $f->media_icon = 'video'; break; default: $f->media_icon = 'blank'; } switch ($f->type) { case 'application/msword': case 'application/vnd.oasis.opendocument.text': case 'application/vnd.sun.xml.writer': case 'application/pdf': case 'application/postscript': $f->media_icon = 'document'; break; case 'application/msexcel': case 'application/vnd.oasis.opendocument.spreadsheet': case 'application/vnd.sun.xml.calc': $f->media_icon = 'spreadsheet'; break; case 'application/mspowerpoint': case 'application/vnd.oasis.opendocument.presentation': case 'application/vnd.sun.xml.impress': $f->media_icon = 'presentation'; break; case 'application/x-debian-package': case 'application/x-gzip': case 'application/x-java-archive': case 'application/rar': case 'application/x-redhat-package-manager': case 'application/x-tar': case 'application/x-gtar': case 'application/zip': $f->media_icon = 'package'; break; case 'application/octet-stream': $f->media_icon = 'executable'; break; case 'application/x-shockwave-flash': $f->media_icon = 'video'; break; case 'application/ogg': $f->media_icon = 'audio'; break; case 'text/html': $f->media_icon = 'html'; break; } $f->media_type = $f->media_icon; $f->media_icon = sprintf($this->icon_img,$f->media_icon); # Thumbnails $f->media_thumb = array(); $p = path::info($f->relname); $thumb = sprintf($this->thumb_tp,$this->root.'/'.$p['dirname'],$p['base'],'%s'); $thumb_url = sprintf($this->thumb_tp,$this->root_url.$p['dirname'],$p['base'],'%s'); foreach ($this->thumb_sizes as $suffix => $s) { if (file_exists(sprintf($thumb,$suffix))) { $f->media_thumb[$suffix] = sprintf($thumb_url,$suffix); } } if (isset($f->media_thumb['sq'])) { $f->media_icon = $f->media_thumb['sq']; } return $f; } return null; } /** Gets current working directory content. @param type <b>string</b> Media type filter */ public function getDir($type=null) { if ($type) { $this->type = $type; } $media_dir = $this->relpwd ? $this->relpwd : '.'; $strReq = 'SELECT media_file, media_id, media_path, media_title, media_meta, media_dt, '. 'media_creadt, media_upddt, media_private, user_id '. 'FROM '.$this->table.' '. "WHERE media_path = '".$this->path."' ". "AND media_dir = '".$this->con->escape($media_dir)."' "; if (!$this->core->auth->check('media_admin',$this->core->blog->id)) { $strReq .= 'AND (media_private <> 1 '; if ($this->core->auth->userID()) { $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'"; } $strReq .= ') '; } $strReq .= 'ORDER BY LOWER(media_file) ASC'; $rs = $this->con->select($strReq); parent::getDir(); $f_res = array(); $p_dir = $this->dir; # If type is set, remove items from p_dir if ($this->type) { foreach ($p_dir['files'] as $k => $f) { if ($f->type_prefix != $this->type) { unset($p_dir['files'][$k]); } } } $f_reg = array(); while ($rs->fetch()) { # File in subdirectory, forget about it! if (dirname($rs->media_file) != '.' && dirname($rs->media_file) != $this->relpwd) { continue; } if ($this->inFiles($rs->media_file)) { $f = $this->fileRecord($rs); if ($f !== null) { $f_res[] = $this->fileRecord($rs); $f_reg[$rs->media_file] = 1; } } elseif (!empty($p_dir['files']) && $this->relpwd == '') { # Physica file does not exist remove it from DB # Because we don't want to erase everything on # dotclear upgrade, do it only if there are files # in directory and directory is root $this->con->execute( 'DELETE FROM '.$this->table.' '. "WHERE media_path = '".$this->con->escape($this->path)."' ". "AND media_file = '".$this->con->escape($rs->media_file)."' " ); $this->callFileHandler(files::getMimeType($rs->media_file),'remove',$this->pwd.'/'.$rs->media_file); } } $this->dir['files'] = $f_res; foreach ($this->dir['dirs'] as $k => $v) { $v->media_icon = sprintf($this->icon_img,'folder'); } # Check files that don't exist in database and create them foreach ($p_dir['files'] as $f) { if (!isset($f_reg[$f->relname])) { if (($id = $this->createFile($f->basename)) !== false) { $this->dir['files'][] = $this->getFile($id); } } } } /** Gets file by its id. Returns a filteItem object. @param id <b>integer</b> File ID @return <b>fileItem</b> */ public function getFile($id) { $strReq = 'SELECT media_id, media_path, media_title, '. 'media_file, media_meta, media_dt, media_creadt, '. 'media_upddt, media_private, user_id '. 'FROM '.$this->table.' '. "WHERE media_path = '".$this->path."' ". 'AND media_id = '.(integer) $id.' '; if (!$this->core->auth->check('media_admin',$this->core->blog->id)) { $strReq .= 'AND (media_private <> 1 '; if ($this->core->auth->userID()) { $strReq .= "OR user_id = '".$this->con->escape($this->core->auth->userID())."'"; } $strReq .= ') '; } $rs = $this->con->select($strReq); return $this->fileRecord($rs); } /** Returns media items attached to a blog post. Result is an array containing fileItems objects. @param post_id <b>integer</b> Post ID @param media_id <b>integer</b> Optionnal media ID @return <b>array</b> Array of fileItems */ public function getPostMedia($post_id,$media_id=null) { $post_id = (integer) $post_id; $strReq = 'SELECT media_file, M.media_id, media_path, media_title, media_meta, media_dt, '. 'media_creadt, media_upddt, media_private, user_id '. 'FROM '.$this->table.' M, '.$this->table_ref.' PM '. "WHERE media_path = '".$this->path."' ". 'AND M.media_id = PM.media_id '. 'AND post_id = '.$post_id.' '; if ($media_id) { $strReq .= 'AND M.media_id = '.(integer) $media_id.' '; } $rs = $this->con->select($strReq); $res = array(); while ($rs->fetch()) { $f = $this->fileRecord($rs); if ($f !== null) { $res[] = $f; } } return $res; } /** Attaches a media to a post. @param post_id <b>integer</b> Post ID @param media_id <b>integer</b> Optionnal media ID */ public function addPostMedia($post_id,$media_id) { $post_id = (integer) $post_id; $media_id = (integer) $media_id; $f = $this->getPostMedia($post_id,$media_id); if (!empty($f)) { return; } $cur = $this->con->openCursor($this->table_ref); $cur->post_id = $post_id; $cur->media_id = $media_id; $cur->insert(); $this->core->blog->triggerBlog(); } /** Detaches a media from a post. @param post_id <b>integer</b> Post ID @param media_id <b>integer</b> Optionnal media ID */ public function removePostMedia($post_id,$media_id) { $post_id = (integer) $post_id; $media_id = (integer) $media_id; $strReq = 'DELETE FROM '.$this->table_ref.' '. 'WHERE post_id = '.$post_id.' '. 'AND media_id = '.$media_id.' '; $this->con->execute($strReq); $this->core->blog->triggerBlog(); } /** Rebuilds database items collection. Optional <var>$pwd</var> parameter is the path where to start rebuild. @param pwd <b>string</b> Directory to rebuild */ public function rebuild($pwd='') { if (!$this->core->auth->isSuperAdmin()) { throw new Exception(__('You are not a super administrator.')); } $this->chdir($pwd); parent::getDir(); $dir = $this->dir; foreach ($dir['dirs'] as $d) { if (!$d->parent) { $this->rebuild($d->relname,false); } } foreach ($dir['files'] as $f) { $this->chdir(dirname($f->relname)); $this->createFile($f->basename); } $this->rebuildDB($pwd); } protected function rebuildDB($pwd) { $media_dir = $pwd ? $pwd : '.'; $strReq = 'SELECT media_file, media_id '. 'FROM '.$this->table.' '. "WHERE media_path = '".$this->path."' ". "AND media_dir = '".$this->con->escape($media_dir)."' "; $rs = $this->con->select($strReq); $delReq = 'DELETE FROM '.$this->table.' '. 'WHERE media_id IN (%s) '; $del_ids = array(); while ($rs->fetch()) { if (!is_file($this->root.'/'.$rs->media_file)) { $del_ids[] = (integer) $rs->media_id; } } if (!empty($del_ids)) { $this->con->execute(sprintf($delReq,implode(',',$del_ids))); } } /** Creates or updates a file in database. Returns new media ID or false if file does not exist. @param name <b>string</b> File name (relative to working directory) @param title <b>string</b> File title @param private <b>boolean</b> File is private @param dt <b>string</b> File date @return <b>integer</b> New media ID */ public function createFile($name,$title=null,$private=false,$dt=null) { if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { throw new Exception(__('Permission denied.')); } $file = $this->pwd.'/'.$name; if (!file_exists($file)) { return false; } $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$name) : path::clean($name); $media_type = files::getMimeType($name); $cur = $this->con->openCursor($this->table); $strReq = 'SELECT media_id '. 'FROM '.$this->table.' '. "WHERE media_path = '".$this->con->escape($this->path)."' ". "AND media_file = '".$this->con->escape($media_file)."' "; $rs = $this->con->select($strReq); if ($rs->isEmpty()) { $rs = $this->con->select('SELECT MAX(media_id) FROM '.$this->table); $media_id = (integer) $rs->f(0) + 1; $cur->media_id = $media_id; $cur->user_id = (string) $this->core->auth->userID(); $cur->media_path = (string) $this->path; $cur->media_file = (string) $media_file; $cur->media_dir = (string) dirname($media_file); $cur->media_creadt = array('NOW()'); $cur->media_upddt = array('NOW()'); $cur->media_title = !$title ? (string) $name : (string) $title; $cur->media_private = (integer) (boolean) $private; if ($dt) { $cur->media_dt = (string) $dt; } else { $cur->media_dt = strftime('%Y-%m-%d %H:%M:%S',filemtime($file)); } try { $cur->insert(); } catch (Exception $e) { @unlink($name); throw $e; } } else { $media_id = (integer) $rs->media_id; $cur->media_upddt = array('NOW()'); $cur->update('WHERE media_id = '.$media_id); } $this->callFileHandler($media_type,'create',$cur,$name,$media_id); return $media_id; } /** Updates a file in database. @param file <b>fileItem</b> Current fileItem object @param newFile <b>fileItem</b> New fileItem object */ public function updateFile($file,$newFile) { if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { throw new Exception(__('Permission denied.')); } $id = (integer) $file->media_id; if (!$id) { throw new Exception('No file ID'); } if (!$this->core->auth->check('media_admin',$this->core->blog->id) && $this->core->auth->userID() != $file->media_user) { throw new Exception(__('You are not the file owner.')); } $cur = $this->con->openCursor($this->table); # We need to tidy newFile basename. If dir isn't empty, concat to basename $newFile->relname = files::tidyFileName($newFile->basename); if ($newFile->dir) { $newFile->relname = $newFile->dir.'/'.$newFile->relname; } if ($file->relname != $newFile->relname) { $newFile->file = $this->root.'/'.$newFile->relname; if (file_exists($newFile->file)) { throw new Exception(__('New file already exists.')); } $this->moveFile($file->relname,$newFile->relname); $cur->media_file = (string) $newFile->relname; $cur->media_dir = (string) dirname($newFile->relname); } $cur->media_title = (string) $newFile->media_title; $cur->media_dt = (string) $newFile->media_dtstr; $cur->media_upddt = array('NOW()'); $cur->media_private = (integer) $newFile->media_priv; $cur->update('WHERE media_id = '.$id); $this->callFileHandler($file->type,'update',$file,$newFile); } /** Uploads a file. @param tmp <b>string</b> Full path of temporary uploaded file @param name <b>string</b> File name (relative to working directory) @param title <b>string</b> File title @param private <b>boolean</b> File is private */ public function uploadFile($tmp,$name,$title=null,$private=false) { if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { throw new Exception(__('Permission denied.')); } $name = files::tidyFileName($name); parent::uploadFile($tmp,$name); return $this->createFile($name,$title,$private); } /** Creates a file from binary content. @param name <b>string</b> File name (relative to working directory) @param bits <b>string</b> Binary file content */ public function uploadBits($name,$bits) { if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { throw new Exception(__('Permission denied.')); } $name = files::tidyFileName($name); parent::uploadBits($name,$bits); return $this->createFile($name,null,null); } /** Removes a file. @param f <b>fileItem</b> fileItem object */ public function removeFile($f) { if (!$this->core->auth->check('media,media_admin',$this->core->blog->id)) { throw new Exception(__('Permission denied.')); } $media_file = $this->relpwd ? path::clean($this->relpwd.'/'.$f) : path::clean($f); $strReq = 'DELETE FROM '.$this->table.' '. "WHERE media_path = '".$this->con->escape($this->path)."' ". "AND media_file = '".$this->con->escape($media_file)."' "; if (!$this->core->auth->check('media_admin',$this->core->blog->id)) { $strReq .= "AND user_id = '".$this->con->escape($this->core->auth->userID())."'"; } $this->con->execute($strReq); if ($this->con->changes() == 0) { throw new Exception(__('File does not exist in the database.')); } parent::removeFile($f); $this->callFileHandler(files::getMimeType($media_file),'remove',$f); } /* Image handlers ------------------------------------------------------- */ protected function imageThumbCreate(&$cur,$f) { $file = $this->pwd.'/'.$f; if (!file_exists($file)) { return false; } $p = path::info($file); $thumb = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); try { $img = new imageTools(); $img->loadImage($file); $w = $img->getW(); $h = $img->getH(); foreach ($this->thumb_sizes as $suffix => $s) { if ($suffix == 'sq' || ($w > $s[0] && $h > $s[0])) { $img->resize($s[0],$s[0],$s[1]); $img->output('jpeg',sprintf($thumb,$suffix),80); } } } catch (Exception $e) {} } protected function imageThumbUpdate(&$file,&$newFile) { if ($file->relname != $newFile->relname) { $p = path::info($file->relname); $thumb_old = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); $p = path::info($newFile->relname); $thumb_new = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s'); foreach ($this->thumb_sizes as $suffix => $s) { try { parent::moveFile(sprintf($thumb_old,$suffix),sprintf($thumb_new,$suffix)); } catch (Exception $e) {} } } } protected function imageThumbRemove($f) { $p = path::info($f); $thumb = sprintf($this->thumb_tp,'',$p['base'],'%s'); foreach ($this->thumb_sizes as $suffix => $s) { try { parent::removeFile(sprintf($thumb,$suffix)); } catch (Exception $e) {} } } protected function imageMetaCreate(&$cur,$f,$id) { $file = $this->pwd.'/'.$f; if (!file_exists($file)) { return false; } $xml = new xmlTag('meta'); $meta = imageMeta::readMeta($file); $xml->insertNode($meta); $c = $this->core->con->openCursor($this->table); $c->media_meta = $xml->toXML(); if ($meta['Title']) { $c->media_title = $meta['Title']; } elseif ($meta['Description']) { $c->media_title = $meta['Description']; } if ($meta['DateTimeOriginal']) { # We set picture time to user timezone $media_ts = strtotime($meta['DateTimeOriginal']); if ($media_ts !== false) { $o = dt::getTimeOffset($this->core->auth->getInfo('user_tz'),$media_ts); $c->media_dt = dt::str('%Y-%m-%d %H:%M:%S',$media_ts+$o); } } $c->update('WHERE media_id = '.$id); } /** Returns HTML code for MP3 player @param url <b>string</b> MP3 URL to play @param player <b>string</b> Player URL @return <b>string</b> */ public function mp3player($url,$player='player_mp3.swf') { $args = $player.'?mp3='.$url. '&loadingcolor=ff9900'. '&bgcolor1=eeeeee'. '&bgcolor2=cccccc'. '&buttoncolor=0066cc'. '&buttonovercolor=ff9900'. '&slidercolor1=cccccc'. '&slidercolor2=999999'. '&sliderovercolor=0066cc'; return '<object type="application/x-shockwave-flash" '. 'data="'.$args.'" '. 'width="200" height="20">'. '<param name="movie" value="'.$args.'" />'. '<param name="wmode" value="transparent" />'. '</object>'; } public function flvplayer($url,$player='player_flv.swf') { $args = 'flv='.$url. '&width=400'. '&height=300'. '&margin=1'. '&showvolume=1'. '&showtime=1'; return '<object type="application/x-shockwave-flash" '. 'data="'.$player.'" '. 'width="400" height="300">'. '<param name="movie" value="'.$player.'" />'. '<param name="FlashVars" value="'.$args.'" />'. '</object>'; } } ?>
©
2018.