diff options
Diffstat (limited to 'inc/media.php')
-rw-r--r-- | inc/media.php | 484 |
1 files changed, 484 insertions, 0 deletions
diff --git a/inc/media.php b/inc/media.php new file mode 100644 index 000000000..39f76e311 --- /dev/null +++ b/inc/media.php @@ -0,0 +1,484 @@ +<?php +/** + * All output and handler function needed for the media management popup + * + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Andreas Gohr <andi@splitbrain.org> + */ + +if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); +if(!defined('NL')) define('NL',"\n"); + +require_once(DOKU_INC.'inc/html.php'); +require_once(DOKU_INC.'inc/search.php'); +require_once(DOKU_INC.'inc/JpegMeta.php'); + +/** + * Lists pages which currently use a media file selected for deletion + * + * References uses the same visual as search results and share + * their CSS tags except pagenames won't be links. + * + * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> + */ +function media_filesinuse($data,$id){ + global $lang; + echo '<h1>'.$lang['reference'].' <code>'.hsc(noNS($id)).'</code></h1>'; + echo '<p>'.hsc($lang['ref_inuse']).'</p>'; + + $hidden=0; //count of hits without read permission + usort($data,'sort_search_fulltext'); + foreach($data as $row){ + if(auth_quickaclcheck($row['id']) >= AUTH_READ){ + echo '<div class="search_result">'; + echo '<span class="mediaref_ref">'.$row['id'].'</span>'; + echo ': <span class="search_cnt">'.$row['count'].' '.$lang['hits'].'</span><br />'; + echo '<div class="search_snippet">'.$row['snippet'].'</div>'; + echo '</div>'; + }else + $hidden++; + } + if ($hidden){ + print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>'; + } +} + +/** + * Handles the saving of image meta data + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_metasave($id,$auth,$data){ + if($auth < AUTH_UPLOAD) return false; + global $lang; + $src = mediaFN($id); + + $meta = new JpegMeta($src); + $meta->_parseAll(); + + foreach($data as $key => $val){ + $val=trim($val); + if(empty($val)){ + $meta->deleteField($key); + }else{ + $meta->setField($key,$val); + } + } + + if($meta->save()){ + msg($lang['metasaveok'],1); + return $id; + }else{ + msg($lang['metasaveerr'],-1); + return false; + } +} + +/** + * Display the form to edit image meta data + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_metaform($id,$auth){ + if($auth < AUTH_UPLOAD) return false; + global $lang; + + // load the field descriptions + static $fields = null; + if(is_null($fields)){ + include(DOKU_CONF.'mediameta.php'); + if(@file_exists(DOKU_CONF.'mediameta.local.php')){ + include(DOKU_CONF.'mediameta.local.php'); + } + } + + $src = mediaFN($id); + + // output + echo '<h1>'.hsc(noNS($id)).'</h1>'.NL; + echo '<form action="'.DOKU_BASE.'lib/exe/mediamanager.php" accept-charset="utf-8" method="post" class="meta">'.NL; + echo '<input type="hidden" name="img" value="'.hsc($id).'" />'.NL; + foreach($fields as $key => $field){ + // get current value + $tags = array($field[0]); + if(is_array($field[3])) $tags = array_merge($tags,$field[3]); + $value = tpl_img_getTag($tags,'',$src); + + // prepare attributes + $p = array(); + $p['class'] = 'edit'; + $p['id'] = 'meta__'.$key; + $p['name'] = 'meta['.$field[0].']'; + + // put label + echo '<div class="metafield">'; + echo '<label for="meta__'.$key.'">'; + echo ($lang[$field[1]]) ? $lang[$field[1]] : $field[1]; + echo '</label>'; + + // put input field + if($field[2] == 'text'){ + $p['value'] = $value; + $p['type'] = 'text'; + $att = buildAttributes($p); + echo "<input $att/>".NL; + }else{ + $att = buildAttributes($p); + echo "<textarea $att>".formText($value).'</textarea>'.NL; + } + echo '</div>'.NL; + } + echo '<div class="buttons">'.NL; + echo '<input name="do[save]" type="submit" value="'.$lang['btn_save']. + '" title="ALT+S" accesskey="s" class="button" />'.NL; + echo '<input name="do[cancel]" type="submit" value="'.$lang['btn_cancel']. + '" title="ALT+C" accesskey="c" class="button" />'.NL; + echo '</form>'.NL; + echo '</div>'; +} + +/** + * Handles media file deletions + * + * If configured, checks for media references before deletion + * + * @author Andreas Gohr <andi@splitbrain.org> + * @return mixed false on error, true on delete or array with refs + */ +function media_delete($id,$auth){ + if($auth < AUTH_DELETE) return false; + global $conf; + global $lang; + + $mediareferences = array(); + if($conf['refcheck']){ + search($mediareferences,$conf['datadir'],'search_reference',array('query' => $id)); + } + + if(!count($mediareferences)){ + $file = mediaFN($id); + if(@unlink($file)){ + msg(str_replace('%s',noNS($id),$lang['deletesucc']),1); + io_sweepNS($id,'mediadir'); + return true; + } + //something went wrong + msg(str_replace('%s',$file,$lang['deletefail']),-1); + return false; + }elseif(!$conf['refshow']){ + msg(str_replace('%s',noNS($id),$lang['mediainuse']),0); + return false; + } + + return $mediareferences; +} + +/** + * Handles media file uploads + * + * @author Andreas Gohr <andi@splitbrain.org> + * @return mixed false on error, id of the new file on success + */ +function media_upload($ns,$auth){ + if($auth < AUTH_UPLOAD) return false; + require_once(DOKU_INC.'inc/confutils.php'); + global $lang; + global $conf; + + // get file + $id = $_POST['id']; + $file = $_FILES['upload']; + // get id + if(empty($id)) $id = $file['name']; + $id = cleanID($ns.':'.$id); //FIXME handle relative and absolute names here + // get filename + $fn = mediaFN($id); + + // get filetype regexp + $types = array_keys(getMimeTypes()); + $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types); + $regex = join('|',$types); + + // because a temp file was created already + if(preg_match('/\.('.$regex.')$/i',$fn)){ + //check for overwrite + if(@file_exists($fn) && (!$_POST['ow'] || $auth < AUTH_DELETE)){ + msg($lang['uploadexist'],0); + return false; + } + // prepare directory + io_makeFileDir($fn); + if(move_uploaded_file($file['tmp_name'], $fn)) { + // set the correct permission here + if($conf['fperm']) chmod($fn, $conf['fperm']); + msg($lang['uploadsucc'],1); + return $id; + }else{ + msg($lang['uploadfail'],-1); + } + }else{ + msg($lang['uploadwrong'],-1); + } + return false; +} + + + +/** + * List all files in a given Media namespace + */ +function media_filelist($ns,$auth=null,$jump=''){ + global $conf; + global $lang; + $ns = cleanID($ns); + + // check auth our self if not given (needed for ajax calls) + if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); + + echo '<h1>:'.hsc($ns).'</h1>'.NL; + + if($auth < AUTH_READ){ + // FIXME: print permission warning here instead? + echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; + return; + } + + media_uploadform($ns, $auth); + + $dir = utf8_encodeFN(str_replace(':','/',$ns)); + $data = array(); + search($data,$conf['mediadir'],'search_media',array(),$dir); + + if(!count($data)){ + echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; + return; + } + + foreach($data as $item){ + media_printfile($item,$auth,$jump); + } +} + +/** + * Print action links for a file depending on filetype + * and available permissions + * + * @todo contains inline javascript + */ +function media_fileactions($item,$auth){ + global $lang; + + // no actions if not writable + if(!$item['writable']) return; + + // delete button + if($auth >= AUTH_DELETE){ + $ask = addslashes($lang['del_confirm']).'\\n'; + $ask .= addslashes($item['id']); + + echo ' <a href="'.DOKU_BASE.'lib/exe/mediamanager.php?delete='.rawurlencode($item['id']).'" '. + 'onclick="return confirm(\''.$ask.'\')" onkeypress="return confirm(\''.$ask.'\')">'. + '<img src="'.DOKU_BASE.'lib/images/trash.png" alt="'.$lang['btn_delete'].'" '. + 'title="'.$lang['btn_delete'].'" class="btn" /></a>'; + } + + // edit button + if($auth >= AUTH_UPLOAD && $item['isimg'] && $item['meta']->getField('File.Mime') == 'image/jpeg'){ + echo ' <a href="'.DOKU_BASE.'lib/exe/mediamanager.php?edit='.rawurlencode($item['id']).'">'. + '<img src="'.DOKU_BASE.'lib/images/pencil.png" alt="'.$lang['metaedit'].'" '. + 'title="'.$lang['metaedit'].'" class="btn" /></a>'; + } + +} + +/** + * Formats and prints one file in the list + */ +function media_printfile($item,$auth,$jump){ + // Prepare zebra coloring + // I always wanted to use this variable name :-D + static $twibble = 1; + $twibble *= -1; + $zebra = ($twibble == -1) ? 'odd' : 'even'; + + // Automatically jump to recent action + if($jump == $item['id']) { + $jump = ' id="scroll__here" '; + }else{ + $jump = ''; + } + + // Prepare fileicons + list($ext,$mime) = mimetype($item['file']); + $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext); + $class = 'select mediafile mf_'.$class; + + // Prepare filename + $file = utf8_decodeFN($item['file']); + + // Prepare info + $info = ''; + if($item['isimg']){ + $info .= (int) $item['meta']->getField('File.Width'); + $info .= '×'; + $info .= (int) $item['meta']->getField('File.Height'); + $info .= ' '; + } + $info .= filesize_h($item['size']); + + // ouput + echo '<div class="'.$zebra.'"'.$jump.'>'.NL; + echo '<a name="h_'.$item['id'].'" class="'.$class.'">'.$file.'</a> '; + echo '<span class="info">('.$info.')</span>'.NL; + media_fileactions($item,$auth); + if($item['isimg']) media_printimgdetail($item); + echo '<div class="clearer"></div>'.NL; + echo '</div>'.NL; +} + +/** + * Prints a thumbnail and metainfos + */ +function media_printimgdetail($item){ + // prepare thumbnail + $w = (int) $item['meta']->getField('File.Width'); + $h = (int) $item['meta']->getField('File.Height'); + if($w>120 || $h>120){ + $ratio = $item['meta']->getResizeRatio(120); + $w = floor($w * $ratio); + $h = floor($h * $ratio); + } + $src = ml($item['id'],array('w'=>$w,'h'=>$h)); + $p = array(); + $p['width'] = $w; + $p['height'] = $h; + $p['alt'] = $item['id']; + $p['class'] = 'thumb'; + $att = buildAttributes($p); + + // output + echo '<div class="detail">'; + echo '<div class="thumb">'; + echo '<a name="d_'.$item['id'].'" class="select">'; + echo '<img src="'.$src.'" '.$att.' />'; + echo '</a>'; + echo '</div>'; + + //read EXIF/IPTC data + echo '<p>'; + $t = $item['meta']->getField('IPTC.Headline'); + if($t) echo '<strong>'.htmlspecialchars($t).'</strong><br />'; + + $t = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment', + 'EXIF.TIFFImageDescription', + 'EXIF.TIFFUserComment')); + if($t) echo htmlspecialchars($t).'<br />'; + + $t = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category')); + if($t) echo '<em>'.htmlspecialchars($t).'</em>'; + echo '</p>'; + echo '</div>'; +} + +/** + * Print the media upload form if permissions are correct + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_uploadform($ns, $auth){ + global $lang; + + if($auth < AUTH_UPLOAD) return; //fixme print info on missing permissions? + + ?> + <form action="<?php echo DOKU_BASE?>lib/exe/mediamanager.php" + method="post" enctype="multipart/form-data" class="upload"> + <input type="hidden" name="ns" value="<?php echo hsc($ns)?>" /> + + <?php echo $lang['txt_upload']?>: + <input type="file" name="upload" class="edit" id="upload__file" /><br /> + + <?php echo $lang['txt_filename']?>: + <input type="text" name="id" class="edit" id="upload__name" /> + <input type="submit" class="button" value="<?php echo $lang['btn_upload']?>" accesskey="s" /> + + <?php if($auth >= AUTH_DELETE){?> + <br /> + <label for="dw__ow"> + <input type="checkbox" name="ow" value="1" id="dw__ow" /><?php echo $lang['txt_overwrt']?> + </label> + <?php }?> + </form> + <?php +} + + + +/** + * Build a tree outline of available media namespaces + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_nstree($ns){ + global $conf; + + // currently selected namespace + $ns = cleanID($ns); + if(empty($ns)){ + $ns = dirname(str_replace(':','/',$ID)); + if($ns == '.') $ns =''; + } + $ns = utf8_encodeFN(str_replace(':','/',$ns)); + + $data = array(); + search($data,$conf['mediadir'],'search_index',array('ns' => $ns)); + + // wrap a list with the root level around the other namespaces + $item = array( 'level' => 0, 'id' => '', 'open' =>'true', 'label' => ':*'); + + echo '<ul class="idx">'; + echo media_nstree_li($item); + echo media_nstree_item($item); + echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li'); + echo '</li>'; + echo '</ul>'; +} + +/** + * Userfunction for html_buildlist + * + * Prints a media namespace tree item + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_nstree_item($item){ + $pos = strrpos($item['id'], ':'); + $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); + if(!$item['label']) $item['label'] = $label; + + $ret = ''; + $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">'; + $ret .= $item['label']; + $ret .= '</a>'; + return $ret; +} + +/** + * Userfunction for html_buildlist + * + * Prints a media namespace tree item opener + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_nstree_li($item){ + $class='media level'.$item['level']; + if($item['open']){ + $class .= ' open'; + $img = DOKU_BASE.'lib/images/minus.gif'; + }else{ + $class .= ' closed'; + $img = DOKU_BASE.'lib/images/plus.gif'; + } + return '<li class="'.$class.'">'. + '<img src="'.$img.'" alt="*" />'; +} |