Skip to content

Commit

Permalink
Implement single media file moving (currently only in the helper)
Browse files Browse the repository at this point in the history
The media link correction code is still missing
  • Loading branch information
michitux committed Mar 30, 2013
1 parent 654addc commit 197c480
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 3 deletions.
26 changes: 25 additions & 1 deletion _test/mediamove.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,34 @@ public function test_movePageWithRelativeMedia() {
$opts['newname'] = 'foo';
/** @var helper_plugin_pagemove $pagemove */
$pagemove = plugin_load('helper', 'pagemove');
$pagemove->move_page($opts);
$this->assertTrue($pagemove->move_page($opts));

$this->assertEquals('{{ mediareltest:myimage.png}} [[:start|{{ mediareltest:testimage.png?200x800 }}]] [[mediareltest:bar|{{mediareltest:testimage.gif?400x200}}]]
[[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{mediareltest:testimage.jpg}}]]
[[doku>wiki:foo|{{mediareltest:foo.gif?200x3000}}]]', rawWiki('foo'));
}

public function test_moveSingleMedia() {
global $AUTH_ACL;

$AUTH_ACL[] = "wiki:*\t@ALL\t16";
$AUTH_ACL[] = "foobar:*\t@ALL\t8";

saveWikiText('wiki:movetest', '{{wiki:dokuwiki-128.png?200}}', 'Test initialized');
idx_addPage('wiki:movetest');

$opts = array();
$opts['ns'] = 'wiki';
$opts['name'] = 'dokuwiki-128.png';
$opts['newns'] = 'foobar';
$opts['newname'] = 'logo.png';

/** @var helper_plugin_pagemove $pagemove */
$pagemove = plugin_load('helper', 'pagemove');
$this->assertTrue($pagemove->move_media($opts));

$this->assertTrue(@file_exists(mediaFn('foobar:logo.png')));

//$this->assertEquals('{{foobar:logo.png?200}}', 'wiki:movetest');
}
}
147 changes: 146 additions & 1 deletion helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public function move_page(&$opts, $checkonly = false) {
// give plugins the option to add their own meta files to the list of files that need to be moved
// to the oldfiles/newfiles array or to adjust their own metadata, database, ...
// and to add other pages to the affected pages
// note that old_ids is in the form 'id' => timestamp of move and affected_pages is indexed by these ids
// note that old_ids is in the form 'id' => timestamp of move
$event = new Doku_Event('PAGEMOVE_PAGE_RENAME', $data);
if ($event->advise_before()) {
// Open the old document and change forward links
Expand Down Expand Up @@ -209,6 +209,149 @@ public function move_page(&$opts, $checkonly = false) {
return true;
}

/**
* Move media file
*
* @author Michael Hamann <[email protected]>
*
* @param array $opts
* @param bool $checkonly Only execute the checks if the media file can be moved
* @return bool If the move was executed
*/
public function move_media(&$opts, $checkonly = false) {
$opts['id'] = cleanID($opts['ns'].':'.$opts['name']);
$opts['path'] = mediaFN($opts['id']);

// Check we have rights to move this document
if ( !file_exists(mediaFN($opts['id']))) {
msg(sprintf($this->getLang('pm_medianotexist'), hsc($opts['id'])), -1);
return false;
}

if ( auth_quickaclcheck($opts['ns'].':*') < AUTH_DELETE ) {
msg(sprintf($this->getLang('pm_nomediarights'), hsc($opts['id'])), -1);
return false;
}

// Assemble media name and path
$opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']);
$opts['new_path'] = mediaFN($opts['new_id']);

// Has the document name and/or namespace changed?
if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) {
msg($this->getLang('pm_nomediachange'), -1);
return false;
}
// Check the page does not already exist
if ( @file_exists($opts['new_path']) ) {
msg(sprintf($this->getLang('pm_mediaexisting'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('pm_root') : $opts['newns'])), -1);
return false;
}

// Check if the current user can create the new page
if (auth_quickaclcheck($opts['new_ns'].':*') < AUTH_UPLOAD) {
msg(sprintf($this->getLang('pm_nomediatargetperms'), $opts['new_id']), -1);
return false;
}

if ($checkonly) return true;

/**
* End of init (checks)
*/

$affected_pages = idx_get_indexer()->lookupKey('pagemove_media', $opts['id']);

$data = array('opts' => &$opts, 'affected_pages' => &$affected_pages);
// give plugins the option to add their own meta files to the list of files that need to be moved
// to the oldfiles/newfiles array or to adjust their own metadata, database, ...
// and to add other pages to the affected pages
$event = new Doku_Event('PAGEMOVE_MEDIA_RENAME', $data);
if ($event->advise_before()) {
// Move the Subscriptions & Indexes
if (method_exists('Doku_Indexer', 'renamePage')) { // new feature since Spring 2013 release
$Indexer = idx_get_indexer();
} else {
$Indexer = new helper_plugin_pagemove_indexer(); // copy of the new code
}
if (($idx_msg = $Indexer->renameMetaValue('pagemove_media', $opts['id'], $opts['new_id'])) !== true) {
msg('Error while updating the search index '.$idx_msg, -1);
return false;
}
if (!$this->movemediameta($opts)) {
msg('The meta files of the media file '.$opts['id'].' couldn\'t be moved', -1);
return false;
}

// prepare directory
io_createNamespace($opts['new_id'], 'media');

if (!io_rename($opts['path'], $opts['new_path'])) {
msg('Moving the media file '.$opts['id'].' failed', -1);
return false;
}

// Move the old revisions
if (!$this->movemediaattic($opts)) {
// it's too late to stop the move, so just display a message.
msg('The attic files of media file '.$opts['id'].' couldn\'t be moved. Please move them manually.', -1);
}

foreach ($affected_pages as $id) {
if (!page_exists($id, '', false)) continue;
// we are only interested in persistent metadata, so no need to render anything.
$meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER);
if (!$meta) $meta = array('media_moves' => array());
if (!isset($meta['media_moves'])) $meta['media_moves'] = array();
$meta['media_moves'] = $this->resolve_moves($meta['media_moves'], '__');
$meta['media_moves'][$opts['id']] = $opts['new_id'];
//if (empty($meta['moves'])) unset($meta['moves']);
p_set_metadata($id, array('plugin_pagemove' => $meta), false, true);
}
}

$event->advise_after();
return true;
}

/**
* Move the old revisions of the media file that is specified in the options
*
* @param array $opts Pagemove options (used here: name, newname, ns, newns)
* @return bool If the attic files were moved successfully
*/
public function movemediaattic($opts) {
global $conf;

$ext = mimetype($opts['name']);
if ($ext[0] !== false)
$name = substr($opts['name'],0, -1*strlen($ext[0])-1);
$newext = mimetype($opts['newname']);
if ($ext[0] !== false)
$newname = substr($opts['newname'],0, -1*strlen($ext[0])-1);
$regex = '\.\d+\.'.preg_quote((string)$ext[0], '/');

return $this->move_files($conf['mediaolddir'], array(
'ns' => $opts['ns'],
'newns' => $opts['newns'],
'name' => $name,
'newname' => $newname
), $regex);
}

/**
* Move the meta files of the page that is specified in the options.
*
* @param array $opts Pagemove options (used here: name, newname, ns, newns)
* @return bool If the meta files were moved successfully
*/
public function movemediameta($opts) {
global $conf;

$regex = '\.[^.]+';
return $this->move_files($conf['mediametadir'], $opts, $regex);
}

/**
* Move the old revisions of the page that is specified in the options.
*
Expand Down Expand Up @@ -250,6 +393,8 @@ private function move_files($dir, $opts, $extregex) {
if ($opts['newns'] != '') $new_path .= '/'.utf8_encodeFN(str_replace(':', '/', $opts['newns']));
$regex = '/^'.preg_quote(utf8_encodeFN($opts['name'])).'('.$extregex.')$/u';

if (!is_dir($old_path)) return true; // no media files found

$dh = @opendir($old_path);
if($dh) {
while(($file = readdir($dh)) !== false) {
Expand Down
7 changes: 6 additions & 1 deletion lang/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,24 @@
$lang['desc'] = 'Page/Namespace Move/Rename Plugin';

$lang['pm_notexist'] = 'The page %s does not exist';
$lang['pm_medianotexist'] = 'The media file %s does not exist';
$lang['pm_notwrite'] = 'You do not have sufficient permissions to modify this page';
$lang['pm_badns'] = 'Invalid characters in namespace.';
$lang['pm_badname'] = 'Invalid characters in pagename.';
$lang['pm_nochange'] = 'Page name and namespace are unchanged.';
$lang['pm_nomediachange'] = 'Media file name and namespace are unchanged.';
$lang['pm_existing'] = 'A page called %s already exists in %s';
$lang['pm_mediaexisting'] = 'A media file called %s already exists in %s';
$lang['pm_root'] = '[Root namespace]';
$lang['pm_current'] = '(Current)';
$lang['pm_renamed'] = 'Page name changed from %s to %s';
$lang['pm_moved'] = 'Page moved from %s to %s';
$lang['pm_move_rename'] = 'Page moved and renamed from %s to %s';
$lang['pm_delete'] = 'Deleted by PageMove plugin';
$lang['pm_norights'] = 'You have insufficient permissions to edit %s.';
$lang['pm_notargetperms'] = 'You don\'t have the permission to create %s.';
$lang['pm_nomediarights'] = 'You have insufficient permissions to delete %s.';
$lang['pm_notargetperms'] = 'You don\'t have the permission to create the page %s.';
$lang['pm_nomediatargetperms'] = 'You don\'t have the permission to create the media file %s.';
$lang['pm_filelocked'] = 'The page %s is locked. Try again later.';
$lang['pm_linkchange'] = 'Links to %s changed to %s';
// Form labels
Expand Down

0 comments on commit 197c480

Please sign in to comment.