summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/JpegMeta.php58
-rw-r--r--inc/lang/en/lang.php3
-rw-r--r--inc/template.php13
-rw-r--r--lib/exe/media.php70
-rw-r--r--lib/images/edit.gifbin0 -> 142 bytes
-rw-r--r--lib/tpl/default/design.css22
-rw-r--r--lib/tpl/default/mediaedit.php90
7 files changed, 227 insertions, 29 deletions
diff --git a/inc/JpegMeta.php b/inc/JpegMeta.php
index b9f0908d4..408f34589 100644
--- a/inc/JpegMeta.php
+++ b/inc/JpegMeta.php
@@ -3,9 +3,10 @@
* JPEG metadata reader/writer
*
* @license PHP license 2.0 (http://www.php.net/license/2_02.txt)
- * @link
+ * @link http://www.zonageek.com/software/php/jpeg/index.php
* @author Sebastian Delmont <sdelmont@zonageek.com>
* @author Andreas Gohr <andi@splitbrain.org>
+ * @todo Add support for Maker Notes, Extend for GIF and PNG metadata
*/
// This class is a modified and enhanced version of the JPEG class by
@@ -164,6 +165,40 @@ class JpegMeta
}
/**
+ * Convinience function to set nearly all available Data
+ * through one function
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function setField($field, $value)
+ {
+ if(strtolower(substr($field,0,5)) == 'iptc.'){
+ return $this->setIPTCField(substr($field,5),$value);
+ }elseif(strtolower(substr($field,0,5)) == 'exif.'){
+ return $this->setExifField(substr($field,5),$value);
+ }else{
+ return $this->setExifField($field,$value);
+ }
+ }
+
+ /**
+ * Convinience function to delete nearly all available Data
+ * through one function
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function deleteField($field)
+ {
+ if(strtolower(substr($field,0,5)) == 'iptc.'){
+ return $this->deleteIPTCField(substr($field,5));
+ }elseif(strtolower(substr($field,0,5)) == 'exif.'){
+ return $this->deleteExifField(substr($field,5));
+ }else{
+ return $this->deleteExifField($field);
+ }
+ }
+
+ /**
* Return a date field
*
* @author Andreas Gohr <andi@splitbrain.org>
@@ -770,18 +805,19 @@ class JpegMeta
* Save changed Metadata
*
* @author Sebastian Delmont <sdelmont@zonageek.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
function save($fileName = "") {
- if ($fileName == "") {
- $tmpName = $this->_fileName . ".tmp";
- $this->_writeJPEG($tmpName);
- if (file_exists($tmpName)) {
- rename($tmpName, $this->_fileName);
- }
- }
- else {
- $this->_writeJPEG($fileName);
- }
+ if ($fileName == "") {
+ $tmpName = tempnam(dirname($this->_fileName),'_metatemp_');
+ $this->_writeJPEG($tmpName);
+ if (@file_exists($tmpName)) {
+ return rename($tmpName, $this->_fileName);
+ }
+ } else {
+ return $this->_writeJPEG($fileName);
+ }
+ return false;
}
/*************************************************************/
diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php
index 16fc1b738..fcc4ed696 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -144,6 +144,9 @@ $lang['spell_noerr'] = 'No Mistakes found';
$lang['spell_nosug'] = 'No Suggestions';
$lang['spell_change']= 'Change';
+$lang['metaedit'] = 'Edit Metadata';
+$lang['metasaveerr'] = 'Writing metadata failed';
+$lang['metasaveok'] = 'Metadata saved';
$lang['img_backto'] = 'Back to';
$lang['img_title'] = 'Title';
$lang['img_caption'] = 'Caption';
diff --git a/inc/template.php b/inc/template.php
index 23123b452..b48a591f8 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -665,12 +665,21 @@ function tpl_mediafilelist(){
$t = $item['meta']->getField('IPTC.Headline');
if($t) print '<b>'.$t.'</b><br />';
- $t = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment','EXIF.TIFFImageDescription','EXIF.TIFFUserComment'));
+ $t = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment',
+ 'EXIF.TIFFImageDescription',
+ 'EXIF.TIFFUserComment'));
if($t) print $t.'<br />';
$t = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category'));
if($t) print '<i>'.$t.'</i><br />';
+ //add edit button
+ if($AUTH >= AUTH_UPLOAD && $item['meta']->getField('File.Mime') == 'image/jpeg'){
+ print '<a href="'.DOKU_BASE.'lib/exe/media.php?edit='.urlencode($item['id']).'">';
+ print '<img src="'.DOKU_BASE.'lib/images/edit.gif" alt="'.$lang['metaedit'].'" title="'.$lang['metaedit'].'" />';
+ print '</a>';
+ }
+
ptln('</div>',6);
}else{
ptln ('('.filesize_h($item['size']).')',6);
@@ -771,7 +780,7 @@ function tpl_pagetitle($id=null){
* and _iptcTagNames() in inc/jpeg.php (You need to prepend IPTC
* to the names of the latter one)
*
- * Only allowed in: detail.php
+ * Only allowed in: detail.php, mediaedit.php
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
diff --git a/lib/exe/media.php b/lib/exe/media.php
index c8db37153..cddf258db 100644
--- a/lib/exe/media.php
+++ b/lib/exe/media.php
@@ -14,8 +14,12 @@
//get namespace to display (either direct or from deletion order)
if($_REQUEST['delete']){
- $DEL = cleanID($_REQUEST['delete']);
+ $DEL = cleanID($_REQUEST['delete']);
$NS = getNS($DEL);
+ }elseif($_REQUEST['edit']){
+ $IMG = cleanID($_REQUEST['edit']);
+ $SRC = mediaFN($IMG);
+ $NS = getNS($IMG);
}else{
$NS = $_REQUEST['ns'];
$NS = cleanID($NS);
@@ -35,9 +39,9 @@
//handle deletion
$mediareferences = array();
if($DEL && $AUTH >= AUTH_DELETE){
- if($conf['refcheck']){
- search($mediareferences,$conf['datadir'],'search_reference',array('query' => $DEL));
- }
+ if($conf['refcheck']){
+ search($mediareferences,$conf['datadir'],'search_reference',array('query' => $DEL));
+ }
if(!count($mediareferences)){
media_delete($DEL);
}elseif(!$conf['refshow']){
@@ -45,6 +49,11 @@
}
}
+ //handle metadatasaving
+ if($UPLOADOK && $SRC && $_REQUEST['save']){
+ media_metasave($SRC,$_REQUEST['meta']);
+ }
+
//handle upload
if($_FILES['upload']['tmp_name'] && $UPLOADOK){
media_upload($NS,$AUTH);
@@ -54,6 +63,8 @@
header('Content-Type: text/html; charset=utf-8');
if($conf['refshow'] && count($mediareferences)){
include(template('mediaref.php'));
+ }elseif($IMG){
+ include(template('mediaedit.php'));
}else{
include(template('media.php'));
}
@@ -87,7 +98,7 @@ function media_delete($delid){
* @author Andreas Gohr <andi@splitbrain.org>
*/
function media_upload($NS,$AUTH){
- require_once(DOKU_INC.'inc/confutils.php');
+ require_once(DOKU_INC.'inc/confutils.php');
global $lang;
global $conf;
@@ -101,24 +112,24 @@ function media_upload($NS,$AUTH){
$fn = mediaFN($id);
// get filetype regexp
- $types = array_keys(getMimeTypes());
- $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types);
+ $types = array_keys(getMimeTypes());
+ $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types);
$regex = join('|',$types);
// we set the umask here but this doesn't really help
// because a temp file was created already
umask($conf['umask']);
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);
+ //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
- chmod($fn, 0777 - $conf['umask']);
+ // set the correct permission here
+ chmod($fn, 0777 - $conf['umask']);
msg($lang['uploadsucc'],1);
return true;
}else{
@@ -146,4 +157,31 @@ function media_html_list_namespaces($item){
return $ret;
}
+/**
+ * Saves image meta data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_metasave($src,$data){
+ global $lang;
+
+ $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);
+ }else{
+ msg($lang['metasaveerr'],-1);
+ }
+}
+
?>
diff --git a/lib/images/edit.gif b/lib/images/edit.gif
new file mode 100644
index 000000000..a2a23de7b
--- /dev/null
+++ b/lib/images/edit.gif
Binary files differ
diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css
index 48453a736..ee03815ff 100644
--- a/lib/tpl/default/design.css
+++ b/lib/tpl/default/design.css
@@ -733,3 +733,25 @@ div.mediaselect-right li, div.uploadform {
clear: both;
}
+div.mediaedit div.data label{
+ display: block;
+ text-align: right;
+ width: 20%;
+ float: left;
+ margin-right: 0.5em;
+}
+
+div.mediaedit div.data input, div.mediaedit div.data textarea{
+ width: 75%;
+ padding: 0.1em;
+ margin: 0.1em;
+}
+
+div.mediaedit div.data input.button {
+ width: 10em;
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+
diff --git a/lib/tpl/default/mediaedit.php b/lib/tpl/default/mediaedit.php
new file mode 100644
index 000000000..53a969e1b
--- /dev/null
+++ b/lib/tpl/default/mediaedit.php
@@ -0,0 +1,90 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?php
+/**
+ * DokuWiki Default Template
+ *
+ * This is the template for editing image meta data.
+ * It is displayed in the media popup.
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://wiki.splitbrain.org/wiki:tpl:templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+?>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
+<head>
+ <title><?php echo hsc($lang['mediaselect'])?> [<?php echo hsc($conf['title'])?>]</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <?php tpl_metaheaders()?>
+
+ <link rel="shortcut icon" href="<?php echo DOKU_BASE?>images/favicon.ico" />
+ <link rel="stylesheet" media="screen" type="text/css" href="<?php echo DOKU_TPL?>layout.css" />
+ <link rel="stylesheet" media="screen" type="text/css" href="<?php echo DOKU_TPL?>design.css" />
+</head>
+
+<body>
+<div class="dokuwiki">
+ <?php html_msgarea()?>
+
+ <h1><?php echo hsc($lang['metaedit'])?> <code><?php echo hsc(noNS($IMG))?></code></h1>
+
+ <div class="mediaedit">
+ <?php/* everything in meta array is tried to save and read */?>
+
+ <div class="data">
+ <form action="<?php echo DOKU_BASE?>lib/exe/media.php" accept-charset="utf-8" method="post">
+ <input type="hidden" name="edit" value="<?php echo hsc($IMG)?>" />
+ <input type="hidden" name="save" value="1" />
+
+ <label for="title"><?php echo $lang['img_title']?></label>
+ <input type="text" name="meta[Iptc.Headline]" id="title" class="edit"
+ value="<?php echo hsc(tpl_img_getTag('IPTC.Headline'))?>" /><br />
+
+ <label for="caption"><?php echo $lang['img_caption']?></label>
+ <textarea name="meta[Iptc.Caption]" id="caption" class="edit" rows="5"><?php
+ echo hsc(tpl_img_getTag(array('IPTC.Caption',
+ 'EXIF.UserComment',
+ 'EXIF.TIFFImageDescription',
+ 'EXIF.TIFFUserComment')));
+ ?></textarea><br />
+
+ <label for="artist"><?php echo $lang['img_artist']?></label>
+ <input type="text" name="meta[Iptc.Byline]" id="artist" class="edit"
+ value="<?php echo hsc(tpl_img_getTag(array('Iptc.Byline',
+ 'Exif.TIFFArtist',
+ 'Exif.Artist',
+ 'Iptc.Credit')))?>" /><br />
+
+ <label for="copy"><?php echo $lang['img_copyr']?></label>
+ <input type="text" name="meta[Iptc.CopyrightNotice]" id="copy" class="edit"
+ value="<?php echo hsc(tpl_img_getTag(array('Iptc.CopyrightNotice','Exif.TIFFCopyright','Exif.Copyright')))?>" /><br />
+
+
+ <label for="keywords"><?php echo $lang['img_keywords']?></label>
+ <textarea name="meta[Iptc.Keywords]" id="keywords" class="edit"><?php
+ echo hsc(tpl_img_getTag(array('IPTC.Keywords',
+ 'EXIF.Category')));
+ ?></textarea><br />
+
+
+ <input type="submit" value="<?php echo $lang['btn_save']?>" title="ALT+S"
+ accesskey="s" class="button" />
+
+ </form>
+ </div>
+
+
+ <div class="footer">
+ <hr>
+ <?php tpl_button('backtomedia')?>
+ </div>
+ </div>
+
+</div>
+</body>
+</html>
+