From 4e15b85e9b1b52f8f34ef60db8fc9979ae793521 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 2 Nov 2012 00:46:59 +0100 Subject: [PATCH 001/338] Add new link rewriting code, some code cleanup This includes: - test cases adapted for PHPUnit - use metadata search index for finding backlinks - new code for rewriting links, media references and plugin syntax - backlinks aren't corrected immediately anymore but instead a queue is filled with all moves that need to be considered --- _test/pagemove.group.php | 10 - _test/pagemove.test.php | 107 ++++---- action.php | 72 ++++++ admin.php | 513 ++++++--------------------------------- helper.php | 380 +++++++++++++++++++++++++++++ 5 files changed, 578 insertions(+), 504 deletions(-) delete mode 100644 _test/pagemove.group.php create mode 100644 action.php create mode 100644 helper.php diff --git a/_test/pagemove.group.php b/_test/pagemove.group.php deleted file mode 100644 index 8c3a2e2..0000000 --- a/_test/pagemove.group.php +++ /dev/null @@ -1,10 +0,0 @@ -GroupTest('pagemove_group_test'); - $this->addTestFile($dir . 'pagemove.test.php'); - } -} diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index be19f58..8787d29 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -1,23 +1,24 @@ pluginsEnabled[] = 'pagemove'; global $ID; global $INFO; @@ -41,6 +42,9 @@ function setUp() { saveWikiText($this->movedId, $text, $summary); $INFO = pageinfo(); + $references = array_keys(p_get_metadata($this->movedId, 'relation references', METADATA_RENDER_UNLIMITED)); + idx_get_indexer()->addMetaKeys($this->movedId, 'relation_references', $references); + $text = <<movedId|$this->movedId]] [[:$this->movedId|:$this->movedId]] @@ -66,6 +70,8 @@ function setUp() { [[/start|/start]] EOT; saveWikiText($this->parentBacklinkingId, $text, $summary); + $references = array_keys(p_get_metadata($this->parentBacklinkingId, 'relation references', METADATA_RENDER_UNLIMITED)); + idx_get_indexer()->addMetaKeys($this->parentBacklinkingId, 'relation_references', $references); $text = <<movedId|$this->movedId]] @@ -96,6 +102,8 @@ function setUp() { [[/start|/start]] EOT; saveWikiText($this->currentNsBacklinkingId, $text, $summary); + $references = array_keys(p_get_metadata($this->currentNsBacklinkingId, 'relation references', METADATA_RENDER_UNLIMITED)); + idx_get_indexer()->addMetaKeys($this->currentNsBacklinkingId, 'relation_references', $references); $text = <<movedId|$this->movedId]] @@ -121,6 +129,8 @@ function setUp() { [[/start|/start]] EOT; saveWikiText($this->otherBacklinkingId, $text, $summary); + $references = array_keys(p_get_metadata($this->otherBacklinkingId, 'relation references', METADATA_RENDER_UNLIMITED)); + idx_get_indexer()->addMetaKeys($this->otherBacklinkingId, 'relation_references', $references); $text = <<movedId|$this->movedId]] @@ -150,8 +160,11 @@ function setUp() { [[/start|/start]] EOT; saveWikiText($this->subNsPage, $text, $summary); + $references = array_keys(p_get_metadata($this->subNsPage, 'relation references', METADATA_RENDER_UNLIMITED)); + idx_get_indexer()->addMetaKeys($this->subNsPage, 'relation_references', $references); $this->pagemove = new admin_plugin_pagemove(); + parent::setUp(); } # function testPagemove() { @@ -181,18 +194,18 @@ function test_move_page_in_same_ns() { $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->parentBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->currentNsBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->otherBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); } @@ -299,18 +312,18 @@ function test_move_page_to_parallel_ns() { $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->parentBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->currentNsBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->otherBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); } @@ -418,18 +431,18 @@ function test_move_page_to_parent_ns() { $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); // page is moved to same NS as backlinking page (parent_ns) $newContent = rawWiki($this->parentBacklinkingId); @@ -457,7 +470,7 @@ function test_move_page_to_parent_ns() { [[parent_ns/new_page|parent_ns/new_page]] [[/start|/start]] EOT; - $this->assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->currentNsBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); $newContent = rawWiki($this->otherBacklinkingId); $expectedContent = <<assertEqual($expectedContent, $newContent); + $this->assertEquals($expectedContent, $newContent); } function test_move_ns_in_same_ns() { - global $ID; $newNamespace = 'new_ns'; + $newPagename = ''; $opts = array(); $opts['page_ns'] = 'ns'; @@ -533,15 +546,5 @@ function test_move_ns_in_same_ns() { } - function tearDown() { - saveWikiText($this->movedId, '', 'removed'); - saveWikiText($this->movedToId, '', 'removed'); - saveWikiText($this->parentBacklinkingId, '', 'removed'); - saveWikiText($this->currentNsBacklinkingId, '', 'removed'); - saveWikiText($this->otherBacklinkingId, '', 'removed'); - saveWikiText($this->subNsPage, '', 'removed'); - } - } -?> \ No newline at end of file diff --git a/action.php b/action.php new file mode 100644 index 0000000..31169ed --- /dev/null +++ b/action.php @@ -0,0 +1,72 @@ + + */ +class action_plugin_pagemove extends DokuWiki_Action_Plugin { + /** + * Register event handlers. + * + * @param Doku_Event_Handler $controller The plugin controller + */ + public function register($controller) { + $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_read', array()); + $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache', array()); + } + + /** + * Rewrite pages when they are read and they need to be updated. + * + * @param Doku_Event $event The event object + * @param mixed $param Optional parameters (not used) + */ + function handle_read(Doku_Event $event, $param) { + static $stack = array(); + // handle only reads of the current revision + if ($event->data[3]) return; + + $id = $event->data[2]; + if ($event->data[1]) $id = $event->data[1].':'.$id; + if (isset($stack[$id])) return; + $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); + if ($meta && isset($meta['moves'])) { + $stack[$id] = true; + $helper = $this->loadHelper('pagemove', true); + if (!is_null($helper)) { + $event->result = $helper->rewrite_content($event->result, $id, $meta['moves']); + } + $file = wikiFN($id, '', false); + if (is_writable($file)) { + saveWikiText($id,$event->result,$this->getLang('pm_linkchange')); + unset($meta['moves']); + p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); + } else { // FIXME: print error here or fail silently? + msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + } + unset($stack[$id]); + } + } + + /** + * Handle the cache events, it looks if a page needs to be rewritten so it can expire the cache of the page + * + * @param Doku_Event $event The even object + * @param mixed $param Optional parameters (not used) + */ + function handle_cache(Doku_Event $event, $param) { + /** @var $cache cache_parser */ + $cache = $event->data; + $id = $cache->page; + if ($id) { + $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); + if ($meta && isset($meta['moves'])) { + $file = wikiFN($id, '', false); + if (is_writable($file)) + $cache->depends['purge'] = true; + else // FIXME: print error here or fail silently? + msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + } + } + } +} \ No newline at end of file diff --git a/admin.php b/admin.php index e6d7c94..0930bb0 100644 --- a/admin.php +++ b/admin.php @@ -16,9 +16,6 @@ require_once DOKU_PLUGIN.'admin.php'; -require_once(DOKU_INC.'inc/search.php'); - - class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { var $show_form = true; @@ -26,11 +23,10 @@ class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { var $locked_files = array(); var $errors = array(); var $opts = array(); - var $text = ''; var $idsToDelete = array(); - function getMenuSort() { return FIXME; } + function getMenuSort() { return 1000; } function forAdminOnly() { return false; } /** @@ -81,6 +77,7 @@ function getMenuText() { * @author Gary Owen */ function html() { + global $ID; global $lang; ptln(''); @@ -111,7 +108,7 @@ function html() { } else { // display the moved/renamed page - ptln( $this->render($this->text) ); + p_wiki_xhtml($ID); } ptln(''); } @@ -236,7 +233,7 @@ function _pm_form() { function _pm_form_create_list_ns($ns) { global $conf; - $namesp = array( 0 => '' ); //Include root + $namesp = array( 0 => array('id' => '') ); //Include root search($namesp, $conf['datadir'], 'search_namespaces', array()); sort($namesp); foreach($namesp as $row) { @@ -310,24 +307,8 @@ function handle() { $this->opts['newns'] = $_REQUEST['ns'].':'.$this->opts['newnsname']; } - // check the NS if a recursion is needed - // @fixme Is this still needed? - $pagelist = array(); - $needrecursion = false; - $nsRelPath = utf8_encodeFN(str_replace(':', '/', $this->opts['ns'])); - search($items, $conf['datadir'], 'search_index', '', $nsRelPath); - foreach ($items as $item) { - if ($item['type'] == 'd') { - $needrecursion = true; - break; - } - } - $nsRelPath = utf8_encodeFN(str_replace(':', '/', $this->opts['ns'])); $this->_pm_move_recursive($nsRelPath, $this->opts); - - $newNsAbsPath = $conf['datadir'].'/'.str_replace(':', '/', $this->opts['newns']); - $this->_pm_disable_cache($newNsAbsPath); } elseif( $this->opts['page_ns'] == 'page' ) { if( $_REQUEST['pagename'] == '' ) { @@ -369,8 +350,7 @@ function handle() { // @todo if the namespace is now empty, delete it // Set things up to display the new page. - io_saveFile($conf['cachedir'].'/purgefile', time()); - $ID = $opts['new_id']; + $ID = $this->opts['new_id']; $ACT = 'show'; $INFO = pageinfo(); $this->show_form = false; @@ -394,31 +374,6 @@ function handle() { } - /** - * touch every file which was moved, because of cached backlinks inside of moved namespace - * - * @author Arno Puschmann 2010-01-29 - * @param $pathToSearch - * @return unknown_type - */ - function _pm_disable_cache($pathToSearch) { - $files = scandir($pathToSearch); - if( !empty($files) ) { - foreach($files as $file) { - if( $file == '.' || $file == '..' ) continue; - if( is_dir($pathToSearch.'/'.$file) ) { - $this->_pm_disable_cache($pathToSearch.'/'.$file); - } - else { - if( preg_match('#\.txt$#', $file) ) { - touch($pathToSearch.'/'.$file, time()+1); - } - } - } - } - } - - /** * * @author Bastian Wolf @@ -431,7 +386,7 @@ function _pm_move_recursive($pathToSearch, $opts) { global $conf; $pagelist = array(); - search($pagelist, $conf['datadir'], 'search_index', '', $pathToSearch); + search($pagelist, $conf['datadir'], 'search_index', array(), $pathToSearch); foreach ($pagelist as $page) { if ($page['type'] == 'd') { @@ -501,20 +456,6 @@ function _pm_move_page($opts) { $this->locked_files[] = $ID; } - // get all backlink information - $backlinksById = array(); - $this->_pm_search($backlinksById, $conf['datadir'], '_pm_search_backlinks', $opts); - - // Check we have edit rights on the backlinks and they are not locked - foreach($backlinksById as $backlinkingId=>$backlinks) { - if (auth_quickaclcheck($backlinkingId) < AUTH_EDIT) { - $this->have_rights = false; - } - if (checklock($backlinkingId)) { - $this->locked_files[] = $backlinkingId; - } - } - // Assemble fill document name and path $opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']); $opts['new_path'] = wikiFN($opts['new_id']); @@ -539,296 +480,89 @@ function _pm_move_page($opts) { * End of init (checks) */ - // Open the old document and change forward links - lock($ID); - $this->text = io_readFile(wikiFN($ID), True); + $page_meta = p_get_metadata($ID, 'plugin_pagemove', METADATA_DONT_RENDER); + if (!$page_meta) $page_meta = array(); + if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); + $page_meta['old_ids'][$ID] = time(); - // Get an array of forward links from the document - $forward = $this->_pm_getforwardlinks($ID); + // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages + $affected_pages = idx_get_indexer()->lookupKey('relation_references', array_keys($page_meta['old_ids'])); - // Change the forward links - foreach($forward as $lnk => $lid) { - // Get namespace of target document - $tns = getNS($lid); - $tname = noNS($lid); - // Form new document ID for the target + $data = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], '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 + // note that old_ids is in the form 'id' => timestamp of move and affected_pages is indexed by these ids + $event = new Doku_Event('PAGEMOVE_PAGE_RENAME', $data); + if ($event->advise_before()) { + // Open the old document and change forward links + lock($ID); + $text = rawWiki($ID); - $matches = array(); - if ( $tns == $opts['newns'] ) { - // Document is in same namespace as target - $this->_pm_updatelinks($this->text, array($lnk => $tname)); - } - elseif ( preg_match('#^'.$opts['newns'].':(.*:)$#', $tns, $matches) ) { - // Target is in a sub-namespace - $this->_pm_updatelinks($this->text, array($lnk => '.:'.$matches[1].':'.$tname)); + /** @var helper_plugin_pagemove $helper */ + $helper = $this->loadHelper('pagemove', true); + if (is_null($helper)) return; + + $text = $helper->rewrite_content($text, $ID, array($ID => $opts['new_id'])); + + // Move the Subscriptions & Indexes + $this->_pm_movemeta('metadir', '/^'.$opts['name'].'\.\w*?$/', $opts); + + // Save the updated document in its new location + if ($opts['ns'] == $opts['newns']) { + $lang_key = 'pm_renamed'; } - elseif ( $tns == "" ) { - // Target is in root namespace - $this->_pm_updatelinks($this->text, array($lnk => $lid )); + elseif ( $opts['name'] == $opts['newname'] ) { + $lang_key = 'pm_moved'; } else { - $this->_pm_updatelinks($this->text, array($lnk => $lid )); + $lang_key = 'pm_move_rename'; } - } + $summary = sprintf($this->lang[$lang_key], $ID, $opts['new_id']); + saveWikiText($opts['new_id'], $text, $summary); - if ( $opts['ns'] != $opts['newns'] ) { - // Change media links when moving between namespaces - $media = $this->_pm_getmedialinks($ID); - foreach($media as $lnk => $lid) { - $tns = getNS($lid); - $tname = noNS($lid); - // Form new document id for the target - $matches = array(); - if ( $tns == $opts['newns'] ) { - // Document is in same namespace as target - $this->_pm_updatemedialinks($this->text, $lnk, $tname ); - } - elseif ( preg_match('#^'.$opts['newns'].':(.*:)$#', $tns, $matches) ) { - // Target is in a sub-namespace - $this->_pm_updatemedialinks($this->text, $lnk, '.:'.$matches[1].':'.$tname ); - } - elseif ( $tns == "" ) { - // Target is in root namespace - $this->_pm_updatemedialinks($this->text, $lnk, ':'.$lid ); - } - else { - $this->_pm_updatemedialinks($this->text, $lnk, $lid ); - } + // Delete the orginal file + if (@file_exists(wikiFN($opts['new_id']))) { + saveWikiText($ID, '', $this->lang['pm_delete'] ); } - } - - // Move the Subscriptions & Indexes - $this->_pm_movemeta('metadir', '/^'.$opts['name'].'\.\w*?$/', $opts); - - // Save the updated document in its new location - if ($opts['ns'] == $opts['newns']) { - $lang_key = 'pm_renamed'; - } - elseif ( $opts['name'] == $opts['newname'] ) { - $lang_key = 'pm_moved'; - } - else { - $lang_key = 'pm_move_rename'; - } - $summary = sprintf($this->lang[$lang_key], $ID, $opts['new_id']); - saveWikiText($opts['new_id'], $this->text, $summary); - - // Delete the orginal file - if (@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($ID, '', $this->lang['pm_delete'] ); - } - - // Loop through backlinks - foreach($backlinksById as $backlinkingId => $backlinks) { - $this->_pm_updatebacklinks($backlinkingId, $backlinks, $opts, $brackets); - } - - // Move the old revisions - $this->_pm_movemeta('olddir', '/^'.$opts['name'].'\.[0-9]{10}\.txt(\.gz)?$/', $opts); - - } + // Move the old revisions + $this->_pm_movemeta('olddir', '/^'.$ID.'\.[0-9]{10}\.txt(\.gz)?$/', $opts); - /** - * Modify the links in a backlink. - * - * @param id Page ID of the backlinking page - * @param links Array of page names on this page. - * - * @author Gary Owen - */ - function _pm_updatebacklinks($backlinkingId, $links, $opts, &$brackets) { - global $ID; - - // Get namespace of document we are editing - $bns = getNS($backlinkingId); - - // Create a clean version of the new name - $cleanname = cleanID($opts['newname']); + asort($page_meta['old_ids']); - // Open backlink - lock($backlinkingId); - $text = io_readFile(wikiFN($backlinkingId),True); - - // Form new document ID for this backlink - $matches = array(); - // new page is in same namespace as backlink - if ( $bns == $opts['newns'] ) { - $replacementNamespace = ''; - } - // new page is in sub-namespace of backlink - elseif ( preg_match('#^'.$bns.':(.*)$#', $opts['newns'], $matches) ) { - $replacementNamespace = '.:'.$matches[1].':'; - } - // not same or sub namespace: use absolute reference - else { - $replacementNamespace = $opts['newns'].':'; - } - - // @fixme stupid: for each page get original backlink and its replacement - $matches = array(); - // get an array of: backlinks => replacement - $oid = array(); - if ( $bns == $opts['ns'] ) { - // old page was in same namespace as backlink - foreach ( $links as $link ) { - $oid[$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - $oid['.:'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - $oid['.'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - } - } - if ( preg_match('#^'.$bns.':(.*)$#', $opts['ns'], $matches) ) { - // old page was in sub namespace of backlink namespace - foreach ( $links as $link ) { - $oid['.:'.$matches[1].':'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - $oid['.'.$matches[1].':'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - } - } - if ( preg_match('#^'.$opts['ns'].':(.*)$#', $bns , $matches) && $opts['page_ns'] == 'page' ) { - // old page was in upper namespace of backlink - foreach ( $links as $link ) { - $oid['..:'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - $oid['..'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - $oid['.:..:'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - } - } - // replace all other links - foreach ( $links as $link ) { - // absolute links - $oid[$opts['ns'].':'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - //$oid['.:'.$opts['ns'].':'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - - // check backwards relative links - $relLink = $link; - $relDots = '..'; - $backlinkingNamespaceCount = count(explode(':', $bns)); - $oldNamespaces = explode(':', $opts['ns'], $backlinkingNamespaceCount); - $oldNamespaceCount = count($oldNamespaces); - if ($backlinkingNamespaceCount > $oldNamespaceCount) { - $levelDiff = $backlinkingNamespaceCount - $oldNamespaceCount; - for ($i = 0; $i < $levelDiff; $i++) { - $relDots .= ':..'; + // additional pages that should be considered because they were affected by moves from previous names + // if the page has been rendered in the meantime and but the new links aren't in the index yet the + // page might need information about a more recent rename even though it is not listed for this more recent link + $additional_pages = array(); + foreach ($page_meta['old_ids'] as $page_id => $time) { + if (!isset($affected_pages[$page_id])) { + $affected_pages[$page_id] = $additional_pages; + } else { + $affected_pages[$page_id] = array_unique(array_merge($affected_pages[$page_id], $additional_pages)); } - } - - foreach (array_reverse($oldNamespaces) as $nextUpperNs) { - $relLink = $nextUpperNs.':'.$relLink; - foreach (array($relDots.$relLink, $relDots.':'.$relLink) as $dottedRelLink) { - $absLink=$dottedRelLink; - resolve_pageid($bns, $absLink, $exists); - if ($absLink == $ID) { - $oid[$dottedRelLink] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - } + foreach ($affected_pages[$page_id] as $id) { + if (!page_exists($id, '', false) || $id == $page_id || $id == $opts['new_id']) continue; + // if the page has been modified since the rename of the old page, the link in the new page is most + // probably intentionally to the old page and shouldn't be changed + if (filemtime(wikiFN($id, '', false)) > $time) continue; + $additional_pages[] = $id; + // 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('moves' => array()); + if (!isset($meta['moves'])) $meta['moves'] = array(); + $meta['moves'][$page_id] = $opts['new_id']; + // remove redundant moves (can happen when a page is moved back to its old id) + if ($page_id == $opts['new_id']) unset($meta['moves'][$page_id]); + if (empty($meta['moves'])) unset($meta['moves']); + p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); } - $relDots = '..:'.$relDots; } - //$oid['..:'.$opts['ns'].':'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - //$oid['..'.$opts['ns'].':'.$link] = $replacementNamespace.(($cleanname == cleanID($link)) ? $link : $opts['newname']); - } - - // Make the changes - $this->_pm_updatelinks($text, $oid); - - // Save backlink and release lock - saveWikiText($backlinkingId, $text, sprintf($this->lang['pm_linkchange'], $ID, $opts['new_id'])); - unlock($backlinkingId); - } - - /** - * modify the links using the pairs in $links - * - * @author Gary Owen - */ - function _pm_updatelinks(&$text, $links) { - foreach( $links as $old => $new ) { - $text = preg_replace( '#\[\[:?' . $old . '((\]\])|[\|\#])#i', '[[' . $new . '\1', $text); - } - } - - /** - * modify the medialinks from namepspace $old to namespace $new - * - * @author Gary Owen - */ - function _pm_updatemedialinks(&$text, $old, $new) { - // Question marks in media links need some extra handling - $text = preg_replace('#\{\{' . $old . '([\?\|]|(\}\}))#i', '{{' . $new . '\1', $text); - } - - /** - * Get forward links in a given page which need to be changed. - * - * Not changed: local sections, absolute links - * Changed need to be - * - * @author Gary Owen - */ - function _pm_getforwardlinks($id) { - $data = array(); - $text = io_readfile(wikiFN($id)); - - // match all links - // FIXME may be incorrect because of code blocks - // TODO CamelCase isn't supported, too - preg_match_all('#\[\[(.+?)\]\]#si', $text, $matches, PREG_SET_ORDER); - foreach($matches as $match) { - // ignore local headings [[#some_heading]] - if ( preg_match('/^#/', $match[1])) continue; - - // get ID from link and discard most non wikilinks - list($mid) = split('[\|#]', $match[1], 2); - // ignore links with URL schema prefix ([[prefix://]]) - if(preg_match('#^\w+://#', $mid)) continue; - // if(preg_match('#^(https?|telnet|gopher|file|wais|ftp|ed2k|irc)://#',$mid)) continue; - // inter-wiki link - if(preg_match('#\w+>#', $mid)) continue; - // baselink ([[/some_link]]) - if(preg_match('#^/#', $mid)) continue; - // email addresses - if(strpos($mid, '@') !== FALSE) continue; - // ignore absolute links - if( strpos($mid, ':') === 0 ) continue; - - $absoluteMatchId = $mid; - $exists = FALSE; - resolve_pageid(getNS($id), $absoluteMatchId, $exists); - if($absoluteMatchId != FALSE) { - $data[$mid] = $absoluteMatchId; - } + p_set_metadata($opts['new_id'], array('plugin_pagemove' => $page_meta), false, true); } - return $data; - } - /** - * Get media links in a given page - * - * @author Gary Owen - */ - function _pm_getmedialinks($id) { - $data = array(); - $text = io_readfile(wikiFN($id)); - // match all links - // FIXME may be incorrect because of code blocks - // TODO CamelCase isn't supported, too - preg_match_all('#{{(.[^>]+?)}}#si', $text, $matches, PREG_SET_ORDER); - foreach($matches as $match) { - // get ID from link and discard most non wikilinks - list($mid) = split('(\?|\|)', $match[1], 2); - $mns = getNS($mid); - $lnk = $mid; - - // namespace starting with "." - prepend current namespace - if(strpos($mns, '.')===0) { - $mid = getNS($id).':'.substr($mid, 1); - } - elseif($mns === FALSE){ - // no namespace in link? add current - $mid = getNS($id) . ':' . $mid; - } - $data[$lnk] = preg_replace('#:+#', ':', $mid); - } - return $data; + $event->advise_after(); } /** @@ -857,109 +591,4 @@ function _pm_movemeta($dir, $regex, $opts) { closedir($dh); } } - - - /** - * recurse directory - * - * This function recurses into a given base directory - * and calls the supplied function for each file and directory - * - * @author Andreas Gohr - * @param array $data Found data is collected - * @param string $base Directory to be searched in - * @param string $func Name of real search function - * @param array $opts Options to the search functions - * @param string $dir Current relative directory - * @param integer $lvl Level of recursion - */ - function _pm_search(&$data, $base, $func, $opts, $dir='' ,$lvl=1) { - $dirs = array(); - $files = array(); - - // read in directories and files - $dh = @opendir($base.'/'.$dir); - if(!$dh) return; - while(($file = readdir($dh)) !== false) { - // skip hidden files and upper dirs - if(preg_match('/^\./',$file)) continue; - if(is_dir($base.'/'.$dir.'/'.$file)) { - $dirs[] = $dir.'/'.$file; - continue; - } - $files[] = $dir.'/'.$file; - } - closedir($dh); - sort($files); - sort($dirs); - - // give directories to userfunction then recurse - foreach($dirs as $dir) { - if ($this->$func($data, $base, $dir, 'd', $lvl, $opts)) { - $this->_pm_search($data, $base, $func, $opts, $dir, $lvl+1); - } - } - // now handle the files - foreach($files as $file) { - $this->$func($data, $base, $file, 'f', $lvl, $opts); - } - } - - /** - * Search for backlinks to a given page - * - * $opts['ns'] namespace of the page - * $opts['name'] name of the page without namespace - * - * @author Andreas Gohr - * @author Gary Owen - */ - function _pm_search_backlinks(&$data, $base, $file, $type, $lvl, $opts) { - // we do nothing with directories - if($type == 'd') return true; - // only search txt files - if(!preg_match('#\.txt$#', $file)) return true; - - $text = io_readfile($base.'/'.$file); - // absolute search ID -// $absSearchedId = cleanID($opts['ns'].':'.$opts['name']); - $absSearchedId = $opts['name']; - resolve_pageid($opts['ns'], $absSearchedId, $exists); - - // construct current namespace - $cid = pathID($file); - $cns = getNS($cid); - - // match all links - // FIXME may be incorrect because of code blocks - // FIXME CamelCase isn't supported, too - preg_match_all('#\[\[(.+?)\]\]#si', $text, $matches, PREG_SET_ORDER); - foreach($matches as $match) { - // get ID from link and discard most non wikilinks - list($matchLink) = split('[\|#]', $match[1], 2); - // all URLs with a scheme - if(preg_match('#^\w+://#', $matchLink)) continue; -// if(preg_match('#^(https?|telnet|gopher|file|wais|ftp|ed2k|irc)://#',$matchLink)) continue; - // baselinks - if(preg_match('#^/#', $matchLink)) continue; - // inter-wiki links - if(preg_match('#\w+>#', $matchLink)) continue; - // email addresses - if(strpos($matchLink, '@') !== FALSE) continue; - - // get the ID the link refers to by cleaning and resolving it - $matchId = cleanID($matchLink); - resolve_pageid($cns, $matchId, $exists); - $matchPagename = ltrim(noNS($matchId), '.:'); - - // only collect IDs not in collected $data already - if ($matchId == $absSearchedId // matching link refers to the searched ID - && (! array_key_exists($cid, $data) // not in $data already - || empty($data[$cid]) - || ! in_array($matchPagename, $data[$cid]))) { - // @fixme return original link and its replacement - $data[$cid][] = $matchPagename; - } - } - } } \ No newline at end of file diff --git a/helper.php b/helper.php new file mode 100644 index 0000000..dcada54 --- /dev/null +++ b/helper.php @@ -0,0 +1,380 @@ + + */ +class helper_plugin_pagemove extends DokuWiki_Plugin { + /** + * Rewrite a text in order to fix the content after the given moves. + * + * @param string $text The wiki text that shall be rewritten + * @param string $id The id of the wiki page, if the page itself was moved the old id + * @param array $moves Array of all moves, the keys are the old ids, the values the new ids + * @return string The rewritten wiki text + */ + function rewrite_content($text, $id, $moves) { + // resolve moves of pages that were moved more than once + $tmp_moves = array(); + foreach($moves as $old => $new) { + if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { + // write to temp array in order to correctly handle rename circles + $tmp_moves[$old] = $moves[$new]; + } + } + + $changed = !empty($tmp_moves); + + // this correctly resolves rename circles by moving forward one step a time + while($changed) { + $changed = false; + foreach($tmp_moves as $old => $new) { + if(isset($moves[$new]) && $moves[$new] != $new) { + $tmp_moves[$old] = $moves[$new]; + $changed = true; + } + } + } + + // manual merge, we can't use array_merge here as ids can be numeric + foreach($tmp_moves as $old => $new) { + $moves[$old] = $new; + } + + $handlers = array(); + $data = array('id' => $id, 'moves' => &$moves, 'handlers' => &$handlers); + + /* + * PAGEMOVE_HANDLERS REGISTER event: + * + * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler + * The handler needs to be a valid callback, it will get the following parameters: + * $match, $state, $pos, $pluginname, $handler. The first three parameters are equivalent to the parameters + * of the handle()-function of syntax plugins, the $pluginname is just the plugin name again so handler functions + * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object. + * It has the following properties and functions that can be used: + * - id, ns: id and namespace of the old page + * - new_id, new_ns: new id and namespace (can be identical to id and ns) + * - moves: array of moves, the same as $moves in the event + * - adaptRelativeId($id): adapts the relative $id according to the moves + */ + trigger_event('PAGEMOVE_HANDLERS_REGISTER', $data); + + $modes = p_get_parsermodes(); + + // Create the parser + $Parser = new Doku_Parser(); + + // Add the Handler + $Parser->Handler = new helper_plugin_pagemove_handler($id, $moves, $handlers); + + //add modes to parser + foreach($modes as $mode) { + $Parser->addMode($mode['mode'], $mode['obj']); + } + + return $Parser->parse($text); + } +} + +/** + * Handler class for pagemove. It does the actual rewriting of the content. + */ +class helper_plugin_pagemove_handler { + public $calls = ''; + public $id; + public $ns; + public $new_id; + public $new_ns; + public $moves; + private $handlers; + + /** + * Construct the pagemove handler. + * + * @param string $id The id of the text that is passed to the handler + * @param array $moves Moves that shall be considered in the form $old => $new ($old can be $id) + * @param array $handlers Handlers for plugin content in the form $plugin_anme => $callback + */ + public function __construct($id, $moves, $handlers) { + $this->id = $id; + $this->ns = getNS($id); + $this->moves = $moves; + $this->handlers = $handlers; + if (isset($moves[$id])) { + $this->new_id = $moves[$id]; + $this->new_ns = getNS($moves[$id]); + } else { + $this->new_id = $id; + $this->new_ns = $this->ns; + } + } + + /** + * Handle camelcase links + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @return bool If parsing should be continued + */ + public function camelcaselink($match, $state, $pos) { + if ($this->ns) + $old = cleanID($this->ns.':'.$match); + else + $old = cleanID($match); + if (isset($this->moves[$old]) || $this->id != $this->new_id) { + if (isset($this->moves[$old])) { + $new = $this->moves[$old]; + } else { + $new = $old; + } + $new_ns = getNS($new); + // preserve capitalization either in the link or in the title + if (noNS($new) == noNS($old)) { + // camelcase link still seems to work + if ($new_ns == $this->new_ns) { + $this->calls .= $match; + } else { // just the namespace was changed, the camelcase word is a valid id + $this->calls .= "[[$new_ns:$match]]"; + } + } else { + $this->calls .= "[[$new|$match]]"; + } + } else { + $this->calls .= $match; + } + return true; + } + + /** + * Handle rewriting of internal links + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @return bool If parsing should be continued + */ + public function internallink($match, $state, $pos) { + // Strip the opening and closing markup + $link = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match); + + // Split title from URL + $link = explode('|',$link,2); + if ( !isset($link[1]) ) { + $link[1] = NULL; + } + $link[0] = trim($link[0]); + + + //decide which kind of link it is + + if ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$link[0]) ) { + // Interwiki + $this->calls .= $match; + }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) { + // Windows Share + $this->calls .= $match; + }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) { + // external link (accepts all protocols) + $this->calls .= $match; + }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) { + // E-Mail (pattern above is defined in inc/mail.php) + $this->calls .= $match; + }elseif ( preg_match('!^#.+!',$link[0]) ){ + // local link + $this->calls .= $match; + }else{ + $id = $link[0]; + + $hash = ''; + $parts = explode('#', $id, 2); + if (count($parts) === 2) { + $id = $parts[0]; + $hash = $parts[1]; + } + + $params = ''; + $parts = explode('?', $id, 2); + if (count($parts) === 2) { + $id = $parts[0]; + $params = $parts[1]; + } + + + $new_id = $this->adaptRelativeId($id); + + if ($id == $new_id) { + $this->calls .= $match; + } else { + if ($params !== '') { + $new_id.= '?'.$params; + } + + if ($hash !== '') { + $new_id .= '#'.$hash; + } + + if ($link[1] != NULL) { + $new_id .= '|'.$link[1]; + } + + $this->calls .= '[['.$new_id.']]'; + } + + } + + return true; + + } + + /** + * Handle rewriting of media links + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @return bool If parsing should be continued + */ + public function media($match, $state, $pos) { + $p = Doku_Handler_Parse_Media($match); + if ($p['type'] == 'internalmedia') { + $new_src = $this->adaptRelativeId($p['src']); + if ($new_src == $p['src']) { + $this->calls .= $match; + } else { + // do a simple replace of the first match so really only the id is changed and not e.g. the alignment + $srcpos = strpos($match, $p['src']); + $srclen = strlen($p['src']); + $this->calls .= substr_replace($match, $new_src, $srcpos, $srclen); + } + } else { // external media + $this->calls .= $match; + } + return true; + } + + /** + * Handle rewriting of plugin syntax, calls the registered handlers + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @param string $pluginname The name of the plugin + * @return bool If parsing should be continued + */ + public function plugin($match, $state, $pos, $pluginname) { + if (isset($this->handlers[$pluginname])) { + $this->calls .= call_user_func($this->handlers[$pluginname], $match, $state, $pos, $pluginname, $this); + } else { + $this->calls .= $match; + } + return true; + } + + /** + * Catchall handler for the remaining syntax + * + * @param string $name Function name that was called + * @param array $params Original parameters + * @return bool If parsing should be continue + */ + public function __call($name, $params) { + if (count($params) == 3) { + $this->calls .= $params[0]; + return true; + } else { + trigger_error('Error, handler function '.hsc($name).' with '.count($params).' parameters called which isn\'t implemented', E_USER_ERROR); + return false; + } + } + + public function _finalize() { + // remove padding that is added by the parser in parse() + $this->calls = substr($this->calls, 1, -1); + } + + /** + * Adapts a link respecting all moves and making it a relative link according to the new id + * + * @param string $id A relative id + * @return string The relative id, adapted according to the new/old id and the moves + */ + public function adaptRelativeId($id) { + global $conf; + + if ($id === '') { + return $id; + } + + $abs_id = str_replace('/', ':', $id); + $abs_id = resolve_id($this->ns, $abs_id, false); + if (substr($abs_id, -1) === ':') + $abs_id .= $conf['start']; + $clean_id = cleanID($abs_id); + // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page + // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been + // deleted already + if (substr($clean_id, -1) === ':') + $clean_id .= $conf['start']; + + if (isset($this->moves[$clean_id]) || $this->ns !== $this->new_ns) { + if (isset($this->moves[$clean_id])) { + $new = $this->moves[$clean_id]; + } else { + $new = $clean_id; + + // only the namespace was changed so if the link still resolves to the same absolute id, we can skip the rest + $new_abs_id = str_replace('/', ':', $id); + $new_abs_id = resolve_id($this->new_ns, $new_abs_id, false); + if (substr($new_abs_id, -1) === ':') + $new_abs_id .= $conf['start']; + if ($new_abs_id == $abs_id) return $id; + } + $new_link = $new; + $new_ns = getNS($new); + // try to keep original pagename + if ($this->noNS($new) == $this->noNS($clean_id)) { + if ($new_ns == $this->new_ns) { + $new_link = $this->noNS($id); + if ($new_link === false) $new_link = $this->noNS($new); + if ($id == ':') + $new_link = ':'; + else if ($id == '/') + $new_link = '/'; + } else if ($new_ns != false) { + $new_link = $new_ns.':'.$this->noNS($id); + } else { + $new_link = $this->noNS($id); + if ($new_link === false) $new_link = $new; + } + } else if ($new_ns == $this->new_ns) { + $new_link = $this->noNS($new_link); + } else if (strpos($new_ns, $this->ns.':') === 0) { + $new_link = '.:'.substr($new_link, strlen($this->ns)+1); + } + + if ($this->new_ns != '' && $new_ns == false) { + $new_link = ':'.$new_link; + } + + return $new_link; + } else { + return $id; + } + } + + private function noNS($id) { + $pos = strrpos($id, ':'); + $spos = strrpos($id, '/'); + if ($pos === false) $pos = $spos; + if ($spos === false) $spos = $pos; + $pos = max($pos, $spos); + if ($pos!==false) { + return substr($id, $pos+1); + } else { + return $id; + } + } +} + From 45ec917bc5ee8755aba67ce3158340d1d1fbcc7f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 21:09:06 +0100 Subject: [PATCH 002/338] Only rewrite pages that are not currently edited Pages that are currently edited will be rewritten after they were saved. --- action.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/action.php b/action.php index 31169ed..4786ff6 100644 --- a/action.php +++ b/action.php @@ -22,6 +22,7 @@ public function register($controller) { * @param mixed $param Optional parameters (not used) */ function handle_read(Doku_Event $event, $param) { + global $ACT; static $stack = array(); // handle only reads of the current revision if ($event->data[3]) return; @@ -29,6 +30,11 @@ function handle_read(Doku_Event $event, $param) { $id = $event->data[2]; if ($event->data[1]) $id = $event->data[1].':'.$id; if (isset($stack[$id])) return; + + // Don't change the page when the user is currently changing the page content or the page is locked by another user + if ((isset($ACT) && (in_array($ACT, array('save', 'preview', 'recover', 'revert')))) + || checklock($id) !== false) return; + $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); if ($meta && isset($meta['moves'])) { $stack[$id] = true; From ab183b6e3114ad897610f0627c7b2b527c6d456d Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 21:12:28 +0100 Subject: [PATCH 003/338] Use plugin.info.txt information in getInfo() There is still a getInfo()-function as it provides a localized description text. --- admin.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/admin.php b/admin.php index 0930bb0..43befcc 100644 --- a/admin.php +++ b/admin.php @@ -41,14 +41,9 @@ function admin_plugin_pagemove(){ * return some info */ function getInfo(){ - return array( - 'author' => 'Gary Owen, Arno Puschmann, Christoph Jähnigen', - 'email' => 'pagemove@gmail.com', - 'date' => '2011-08-11', - 'name' => 'Pagemove', - 'desc' => $this->lang['desc'], - 'url' => 'http://www.dokuwiki.org/plugin:pagemove', - ); + $result = parent::getInfo(); + $result['desc'] = $this->getLang('desc'); + return $result; } /** From 7b5f66e5ab9c4f1e43f2483eab83b394370c8936 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 23:15:27 +0100 Subject: [PATCH 004/338] New error handling for _pm_move_page() - return parameter shows success --- admin.php | 52 ++++++++++++++++++++---------------------------- lang/en/lang.php | 7 ++++--- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/admin.php b/admin.php index 43befcc..4a277f4 100644 --- a/admin.php +++ b/admin.php @@ -420,35 +420,25 @@ function _pm_move_recursive($pathToSearch, $opts) { * @author Gary Owen , modified by Kay Roesler * * @param array $opts + * @return bool If the move was executed */ - function _pm_move_page($opts) { - - global $conf; - global $lang; + function _pm_move_page(&$opts) { global $ID; - global $INFO; - global $ACT; // Check we have rights to move this document - if ( !$INFO['exists']) { - $this->have_rights = false; - $this->errors[] = $this->lang['pm_notexist']; - return; - } - if ( $ID == $conf['start']) { - $this->have_rights = false; - $this->errors[] = $this->lang['pm_notstart']; - return; + if ( !page_exists($ID)) { + msg($this->getLang('pm_notexist'), -1); + return false; } if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { - $this->have_rights = false; - $this->errors[] = $this->lang['pm_norights']; - return; + msg(sprintf($this->getLang('pm_norights'), hsc($ID)), -1); + return false; } // Check file is not locked - if (checklock($ID)) { - $this->locked_files[] = $ID; + if (checklock($ID) !== false) { + msg( sprintf($this->getLang('pm_filelocked'), hsc($ID)), -1); + return false; } // Assemble fill document name and path @@ -457,18 +447,20 @@ function _pm_move_page($opts) { // Has the document name and/or namespace changed? if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { - $this->errors[] = $this->lang['pm_nochange']; - return; + msg($this->getLang('pm_nochange'), -1); + return false; } // Check the page does not already exist if ( @file_exists($opts['new_path']) ) { - $this->errors[] = sprintf($this->lang['pm_existing'], $opts['newname'], - ($opts['newns'] == '' ? $this->lang['pm_root'] : $opts['newns'])); - return; + msg(sprintf($this->getLang('pm_existing'), $opts['newname'], + ($opts['newns'] == '' ? $this->getLang('pm_root') : $opts['newns'])), -1); + return false; } - if ( count($this->errors) != 0 ) { - return; + // Check if the current user can create the new page + if (auth_quickaclcheck($opts['new_id']) < AUTH_CREATE) { + msg(sprintf($this->getLang('pm_notargetperms'), $opts['new_id']), -1); + return false; } /** @@ -496,7 +488,7 @@ function _pm_move_page($opts) { /** @var helper_plugin_pagemove $helper */ $helper = $this->loadHelper('pagemove', true); - if (is_null($helper)) return; + if (is_null($helper)) return false; $text = $helper->rewrite_content($text, $ID, array($ID => $opts['new_id'])); @@ -513,12 +505,12 @@ function _pm_move_page($opts) { else { $lang_key = 'pm_move_rename'; } - $summary = sprintf($this->lang[$lang_key], $ID, $opts['new_id']); + $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); saveWikiText($opts['new_id'], $text, $summary); // Delete the orginal file if (@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($ID, '', $this->lang['pm_delete'] ); + saveWikiText($ID, '', $this->getLang('pm_delete') ); } // Move the old revisions diff --git a/lang/en/lang.php b/lang/en/lang.php index 1432f5b..c02adcd 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -29,10 +29,11 @@ $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_norights'] = 'You have insufficient permissions to edit one or more backlinks for this document.'; -$lang['pm_tryagain'] = 'Try again latter.'; -$lang['pm_filelocked'] = 'This file is locked - '; $lang['pm_fileslocked'] = 'These files are locked - '; +$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_filelocked'] = 'The page %s is locked. Try again later.'; $lang['pm_linkchange'] = 'Links to %s changed to %s'; $lang['pm_newname'] = 'New document name :'; $lang['pm_newnsname'] = 'Use new Name for Namespace:'; From 46e6e72b491c3ed4b2e01b9202300623919ef22c Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 23:22:41 +0100 Subject: [PATCH 005/338] Build page list before moving pages, add $checkonly parameter --- admin.php | 74 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/admin.php b/admin.php index 4a277f4..1677beb 100644 --- a/admin.php +++ b/admin.php @@ -373,44 +373,52 @@ function handle() { * * @author Bastian Wolf * @param $pathToSearch - * @param $opts - * @return unknown_type + * @param array $opts Options for moving the page + * @param bool $checkonly If only the checks if all pages can be moved shall be executed + * @return bool if the move was executed */ - function _pm_move_recursive($pathToSearch, $opts) { + function _pm_move_recursive($pathToSearch, &$opts, $checkonly = false) { global $ID; global $conf; $pagelist = array(); - search($pagelist, $conf['datadir'], 'search_index', array(), $pathToSearch); + $searchOpts = array('depth' => 0, 'skipacl' => true); + search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); + // FIXME: either use ajax for executing the queue and/or store the queue so it can be resumed when the execution + // is aborted. foreach ($pagelist as $page) { - if ($page['type'] == 'd') { - $pathToSearch = utf8_encodeFN(str_replace(':', '/', $page['id'])); - // @fixme shouldn't be necessary as ID already exists - io_createNamespace($page['id']); - // NS to move is this one - $nsOpts = $opts; - $nsOpts['ns'] = $page['id']; - // target NS is this folder under the current target NS - $thisFolder = end(explode(':', $page['id'])); - $nsOpts['newns'] .= ':'.$thisFolder; - array_push($this->idsToDelete, $page['id']); - // Recursion - $this->_pm_move_recursive($pathToSearch, $nsOpts); - } - elseif ($page['type'] == 'f') { - $ID = $page['id']; - $pageOpts = $opts; - $pageOpts['ns'] = getNS($ID); - $pageOpts['name'] = noNS($ID); - $pageOpts['newname'] = noNS($ID); - $this->_pm_move_page($pageOpts); - } - else { - $this->errors[] = $this->lang['pm_unknown_file_type']; - return; - } + $ID = $page['id']; + $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); + $pageOpts = $opts; + $pageOpts['ns'] = getNS($ID); + $pageOpts['name'] = noNS($ID); + $pageOpts['newname'] = noNS($ID); + $pageOpts['newns'] = getNS($newID); + if (!$this->_pm_move_page($pageOpts, $checkonly)) return false; } + return true; + } + + /** + * Get the id of a page after a namespace move + * + * @param string $oldid The old id of the page + * @param string $oldns The old namespace. $oldid needs to be inside $oldns + * @param string $newns The new namespace + * @return string The new id + */ + function getNewID($oldid, $oldns, $newns) { + $newid = $oldid; + if ($oldns != '') { + $newid = substr($oldid, strlen($oldns)+1); + } + + if ($newns != '') { + $newid = $newns.':'.$newid; + } + + return $newid; } @@ -420,9 +428,10 @@ function _pm_move_recursive($pathToSearch, $opts) { * @author Gary Owen , modified by Kay Roesler * * @param array $opts + * @param bool $checkonly Only execute the checks if the page can be moved * @return bool If the move was executed */ - function _pm_move_page(&$opts) { + function _pm_move_page(&$opts, $checkonly = false) { global $ID; // Check we have rights to move this document @@ -463,6 +472,8 @@ function _pm_move_page(&$opts) { return false; } + if ($checkonly) return true; + /** * End of init (checks) */ @@ -550,6 +561,7 @@ function _pm_move_page(&$opts) { } $event->advise_after(); + return true; } /** From cb47e1e2e775ea1ae0f262e8ae47c8f00c671da6 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 23:24:32 +0100 Subject: [PATCH 006/338] Fix problems with unicode characters when moving meta files --- admin.php | 51 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/admin.php b/admin.php index 1677beb..19c660a 100644 --- a/admin.php +++ b/admin.php @@ -504,7 +504,7 @@ function _pm_move_page(&$opts, $checkonly = false) { $text = $helper->rewrite_content($text, $ID, array($ID => $opts['new_id'])); // Move the Subscriptions & Indexes - $this->_pm_movemeta('metadir', '/^'.$opts['name'].'\.\w*?$/', $opts); + $this->movemeta($opts); // Save the updated document in its new location if ($opts['ns'] == $opts['newns']) { @@ -525,7 +525,7 @@ function _pm_move_page(&$opts, $checkonly = false) { } // Move the old revisions - $this->_pm_movemeta('olddir', '/^'.$ID.'\.[0-9]{10}\.txt(\.gz)?$/', $opts); + $this->moveattic($opts); asort($page_meta['old_ids']); @@ -565,26 +565,49 @@ function _pm_move_page(&$opts, $checkonly = false) { } /** - * move meta files (Old Revs, Subscriptions, Meta, etc) + * Move the old revisions of the page that is specified in the options. * - * This function meta files between directories + * @param array $opts Pagemove options (used here: name, newname, ns, newns) + */ + function moveattic($opts) { + global $conf; + + $regex = '\.\d+\.txt(?:\.gz|\.bz2)?'; + $this->move_files($conf['olddir'], $opts, $regex); + } + + /** + * Move the meta files of the page that is specified in the options. * - * @author Gary Owen + * @param array $opts Pagemove options (used here: name, newname, ns, newns) */ - function _pm_movemeta($dir, $regex, $opts) { + function movemeta($opts) { global $conf; - $old_path = $conf[$dir].'/'.str_replace(':','/',$opts['ns']).'/'; - $new_path = $conf[$dir].'/'.str_replace(':','/',$opts['newns']).'/'; + $regex = '\.[^.]+'; + $this->move_files($conf['metadir'], $opts, $regex); + } + + /** + * Internal function for moving and renaming meta/attic files between namespaces + * + * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] + * @param array $opts Pagemove options (used here: ns, newns, name, newname) + * @param string $extregex Regular expression for matching the extension of the file that shall be moved + */ + private function move_files($dir, $opts, $extregex) { + $old_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['ns'])).'/'; + $new_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['newns'])).'/'; + $regex = '/^'.preg_quote(utf8_encodeFN($opts['name'])).'('.$extregex.')$/u'; + $dh = @opendir($old_path); if($dh) { while(($file = readdir($dh)) !== false) { - // skip hidden files and upper dirs - if(preg_match('/^\./',$file)) continue; - if(is_file($old_path.$file) and preg_match($regex,$file)) { - io_mkdir_p($new_path); - io_rename($old_path.$file,$new_path.str_replace($opts['name'], $opts['newname'], $file)); - continue; + if (substr($file, 0, 1) == '.') continue; + $match = array(); + if (is_file($old_path.$file) && preg_match($regex, $file, $match)) { + if (!is_dir($new_path)) io_mkdir_p($new_path); + io_rename($old_path.$file, $new_path.utf8_encodeFN($opts['newname'].$match[1])); } } closedir($dh); From 77e946e392dc585196e826722d55c8734b66fe93 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 23:26:02 +0100 Subject: [PATCH 007/338] New user interface and handler for changed backend This updates the (English) user interface because of the changed functionality of the backend. --- admin.php | 325 +++++++++++-------------------------------- lang/en/lang.php | 31 ++--- lang/en/pagemove.txt | 15 +- script.js | 42 ++++++ 4 files changed, 144 insertions(+), 269 deletions(-) create mode 100644 script.js diff --git a/admin.php b/admin.php index 19c660a..105d89b 100644 --- a/admin.php +++ b/admin.php @@ -51,17 +51,13 @@ function getInfo(){ */ function getMenuText() { global $INFO; - global $ID; - global $conf; if( !$INFO['exists'] ) - return $this->lang['menu'].' ('.$this->lang['pm_notexist'].')'; - elseif( $ID == $conf['start'] ) - return $this->lang['menu'].' ('.$this->lang['pm_notstart'].')'; + return $this->getLang('menu').' ('.$this->getLang('pm_notexist').')'; elseif( !$INFO['writable'] ) - return $this->lang['menu'].' ('.$this->lang['pm_notwrite'].')'; + return $this->getLang('menu').' ('.$this->getLang('pm_notwrite').')'; else - return $this->lang['menu']; + return $this->getLang('menu'); } @@ -72,39 +68,9 @@ function getMenuText() { * @author Gary Owen */ function html() { - global $ID; - global $lang; - ptln(''); - if( $this->show_form ) { - ptln( $this->locale_xhtml('pagemove') ); - //We didn't get here from submit. - if( $this->have_rights && count($this->locked_files) == 0 ) { - $this->_pm_form(); - } - else { - ptln( '

' ); - if ( !$this->have_rights ) { - ptln( $this->errors[0].'
' ); - } - $c = count($this->locked_files); - if ( $c == 1 ) { - ptln( $this->lang['pm_filelocked'].$this->locked_files[0].'
'.$this->lang['pm_tryagain'] ); - } - elseif ( $c > 1 ) { - ptln( $this->lang['pm_fileslocked'] ); - for ( $i = 0 ; $i < $c ; $i++ ) { - ptln ( ($i > 0 ? ', ' : '').$this->locked_files[$i] ); - } - ptln( '
'.$this->lang['pm_tryagain'] ); - } - ptln ( '

' ); - } - } - else { - // display the moved/renamed page - p_wiki_xhtml($ID); - } + ptln( $this->locale_xhtml('pagemove') ); + $this->_pm_form(); ptln(''); } @@ -115,273 +81,148 @@ function html() { */ function _pm_form() { global $ID; - global $lang; - global $conf; $ns = getNS($ID); - $name = noNS($ID); - - ptln('
'); - ptln(' '); - ptln('
'); - // output hidden values to ensure dokuwiki will return back to this plugin - ptln(' '); - ptln(' '); - ptln(' '); - ptln('
'); - ptln(' '. $this->lang['pm_movepage'] .''); - ptln(' '); - - //Show any errors - if (count($this->errors) > 0) { - ptln (''); - } - //create a list of namespaces - ptln( ' '); - ptln( ' '); - ptln( ' \n "); - - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln(' '); // - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( '
'); - foreach($this->errors as $error) { - ptln ($error.'
'); - } - ptln ('
' ? 'CHECKED' : '').'>
'); - ptln( '
'); - - ptln('
'); - ptln('
'); - ptln(' '. $this->lang['pm_movens'] .''); - ptln(' '); - ptln( ' '); - ptln( ' \n "); - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( ' '); - ptln( '
'); - ptln('
'); - ptln( '
'); - ptln( '
'); - - ptln(''); - - ptln(' "); - - ptln( '
'); + + $ns_select_data = $this->build_namespace_select_content($ns); + + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('move_type', 'page'); + $form->startFieldset($this->getLang('pm_movepage')); + $form->addElement(form_makeMenuField('ns_for_page', $ns_select_data, $this->opts['ns_for_page'], $this->getLang('pm_targetns'), '', 'block')); + $form->addElement(form_makeTextField('newns', $this->opts['newns'], $this->getLang('pm_newtargetns'), '', 'block')); + $form->addElement(form_makeTextField('newname', $this->opts['newname'], $this->getLang('pm_newname'), '', 'block')); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); + $form->endFieldset(); + $form->printForm(); + + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('move_type', 'namespace'); + $form->startFieldset($this->getLang('pm_movens')); + $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('pm_targetns'), '', 'block')); + $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('pm_newnsname'), '', 'block')); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); + $form->endFieldset(); + $form->printForm(); } /** * create a list of namespaces for the html form * + * @author Michael Hamann * @author Gary Owen * @author Arno Puschmann (bin out of _pm_form) */ - function _pm_form_create_list_ns($ns) { + private function build_namespace_select_content($ns) { global $conf; + $result = array(); + $namesp = array( 0 => array('id' => '') ); //Include root search($namesp, $conf['datadir'], 'search_namespaces', array()); sort($namesp); foreach($namesp as $row) { if ( auth_quickaclcheck($row['id'].':*') >= AUTH_CREATE || $row['id'] == $ns ) { - ptln ( ' " ); + + $result[($row['id'] ? $row['id'] : ':')] = ($row['id'] ? $row['id'].':' : ": ".$this->getLang('pm_root')). + ($row['id'] == $ns ? ' '.$this->getLang('pm_current') : ''); } } + return $result; } /** * handle user request * + * @author Michael Hamann * @author Gary Owen */ function handle() { - - global $conf; - global $lang; global $ID; - global $INFO; global $ACT; + global $INFO; - // check we have rights to move this document - if( !$INFO['exists'] ) { - $this->have_rights = false; - $this->errors[] = $this->lang['pm_notexist']; - return; - } - // do not move start page - if( $ID == $conf['start'] ) { - $this->have_rights = false; - $this->errors[] = $this->lang['pm_notstart']; - return; - } - - // was a form send? - if (! array_key_exists('page_ns', $_REQUEST)) { - // @fixme do something more intelligent like showing in message + // populate options with default values + $this->opts['ns'] = getNS($ID); + $this->opts['name'] = noNS($ID); + $this->opts['ns_for_page'] = $INFO['namespace']; + $this->opts['newns'] = ''; + $this->opts['newname'] = noNS($ID); + $this->opts['targetns'] = getNS($ID); + $this->opts['newnsname'] = ''; + $this->opts['move_type'] = 'page'; + + // Only continue when the form was submitted + if ($_SERVER['REQUEST_METHOD'] != 'POST') { return; } - // extract namespace and document name from ID - $this->opts['ns'] = getNS($ID); - $this->opts['name'] = noNS($ID); - $this->opts['page_ns'] = $_REQUEST['page_ns']; + // Store the form data in the options and clean the submitted data. + if (isset($_POST['ns_for_page'])) $this->opts['ns_for_page'] = cleanID((string)$_POST['ns_for_page']); + if (isset($_POST['newns'])) $this->opts['newns'] = cleanID((string)$_POST['newns']); + if (isset($_POST['newname'])) $this->opts['newname'] = cleanID((string)$_POST['newname']); + if (isset($_POST['targetns'])) $this->opts['targetns'] = cleanID((string)$_POST['targetns']); + if (isset($_POST['newnsname'])) $this->opts['newnsname'] = cleanID((string)$_POST['newnsname']); + if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; // check the input for completeness - if( $this->opts['page_ns'] == 'ns' ) { - // @todo Target namespace needn't be new (check pages for overwrite!) - if( $_REQUEST['namespacename'] == '' ) { - $this->errors[] = $this->lang['pm_emptynamespace']; - return; - } - $this->opts['newnsname'] = $_REQUEST['namespacename']; - if ( cleanID($this->opts['newnsname']) == '' ) { - $this->errors[] = $this->lang['pm_badns']; - return; - } - if ($_REQUEST['ns'] == ':') { + if( $this->opts['move_type'] == 'namespace' ) { + if ($this->opts['targetns'] == '') { $this->opts['newns'] = $this->opts['newnsname']; - } - else { - $this->opts['newns'] = $_REQUEST['ns'].':'.$this->opts['newnsname']; + } else { + $this->opts['newns'] = $this->opts['targetns'].':'.$this->opts['newnsname']; } - $nsRelPath = utf8_encodeFN(str_replace(':', '/', $this->opts['ns'])); - $this->_pm_move_recursive($nsRelPath, $this->opts); - } - elseif( $this->opts['page_ns'] == 'page' ) { - if( $_REQUEST['pagename'] == '' ) { - $this->errors[] = $this->lang['pm_emptypagename']; + if ($this->_pm_move_recursive($this->opts, true) && + $this->_pm_move_recursive($this->opts)) { + $ID = $this->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); + $ACT = 'show'; + } else { return; } - $this->opts['newname'] = $_REQUEST['pagename']; + } else { // check that the pagename is valid - if ( cleanID($this->opts['newname']) == '' ) { - $this->errors[] = $this->lang['pm_badname']; + if ($this->opts['newname'] == '' ) { + msg($this->getLang('pm_badname'), -1); return; } - if ($_REQUEST['nsr'] == '') { - $this->opts['newns'] = ($_REQUEST['ns_for_page'] == ':' ? '' : $_REQUEST['ns_for_page']); - } - elseif ($_REQUEST['nsr'] =='') { - // if a new namespace was requested, check and use it - if ($_REQUEST['newns'] != '') { - $this->opts['newns'] = $_REQUEST['newns']; - // check that the new namespace is valid - if ( cleanID($this->opts['newns']) == '' ) { - $this->errors[] = $this->lang['pm_badns']; - return; - } - } - else { - $this->errors[] = $this->lang['pm_badns']; - return; - } - } - else { - $this->errors[] = $this->lang['pm_fatal']; - return; + if ($this->opts['newns'] === '') { + $this->opts['newns'] = $this->opts['ns_for_page']; } - $this->_pm_move_page($this->opts); - - // @todo if the namespace is now empty, delete it - - // Set things up to display the new page. - $ID = $this->opts['new_id']; - $ACT = 'show'; - $INFO = pageinfo(); - $this->show_form = false; - } - else { - $this->errors[] = $this->lang['pm_fatal']; - return; - } + if ($this->_pm_move_page($this->opts)) { + // @todo if the namespace is now empty, delete it - - // only go on if no errors occured and inputs are not empty - if (count($this->errors) != 0 ) { - return; - } - // delete empty namespaces if possible - // @fixme does not work like that - foreach ($this->idsToDelete as $idToDelete) { - io_sweepNS($idToDelete); + // Set things up to display the new page. + $ID = $this->opts['new_id']; + $ACT = 'show'; // this triggers a redirect to the page + } else { + return; + } } - } /** * * @author Bastian Wolf - * @param $pathToSearch * @param array $opts Options for moving the page * @param bool $checkonly If only the checks if all pages can be moved shall be executed * @return bool if the move was executed */ - function _pm_move_recursive($pathToSearch, &$opts, $checkonly = false) { + function _pm_move_recursive(&$opts, $checkonly = false) { global $ID; global $conf; $pagelist = array(); + $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); $searchOpts = array('depth' => 0, 'skipacl' => true); search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); diff --git a/lang/en/lang.php b/lang/en/lang.php index c02adcd..4659d70 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -15,35 +15,30 @@ $lang['menu'] = 'Page/Namespace Move/Rename...'; $lang['desc'] = 'Page/Namespace Move/Rename Plugin'; -$lang['pm_notexist'] = 'This topic does not exist yet'; -$lang['pm_notstart'] = 'The Start page cannot be moved or renamed'; -$lang['pm_notwrite'] = 'You do not have sufficient rights to modify this page'; +$lang['pm_notexist'] = 'This page 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'] = 'Document name and namespace are unchanged.'; -$lang['pm_existing'] = 'A document called %s already exists in %s'; +$lang['pm_nochange'] = 'Page name and namespace are unchanged.'; +$lang['pm_existing'] = 'A page called %s already exists in %s'; $lang['pm_root'] = '[Root namespace]'; $lang['pm_current'] = '(Current)'; -$lang['pm_movedfrom'] = 'Document moved from '; -$lang['pm_movedto'] = 'Document moved to '; $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_fileslocked'] = 'These files are locked - '; $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_filelocked'] = 'The page %s is locked. Try again later.'; $lang['pm_linkchange'] = 'Links to %s changed to %s'; -$lang['pm_newname'] = 'New document name :'; -$lang['pm_newnsname'] = 'Use new Name for Namespace:'; -$lang['pm_targetns'] = 'Select new Namespace :'; -$lang['pm_newtargetns'] = 'Create a new Namespace'; +// Form labels +$lang['pm_newname'] = 'New page name:'; +$lang['pm_newnsname'] = 'New namespace name:'; +$lang['pm_targetns'] = 'Select new namespace:'; +$lang['pm_newtargetns'] = 'Create a new namespace:'; $lang['pm_movepage'] = 'Move page'; -$lang['pm_movens'] = 'Move Namespace'; -$lang['pm_previewpage'] = ' get moved to '; -$lang['pm_previewns'] = 'All pages and namespaces in the namespace %s: get moved in the namespace'; -$lang['pm_delete'] = 'Deleted by PageMove plugin'; -$lang['pm_preview'] = 'Preview'; +$lang['pm_movens'] = 'Move namespace'; $lang['pm_submit'] = 'Submit'; -?> \ No newline at end of file +// JavaScript preview +$lang['js']['pm_previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; +$lang['js']['pm_previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; diff --git a/lang/en/pagemove.txt b/lang/en/pagemove.txt index f801b3f..cfc7faa 100644 --- a/lang/en/pagemove.txt +++ b/lang/en/pagemove.txt @@ -1,13 +1,10 @@ ====== Pagemove ====== -This plugin allows you to move and/or rename the current document or move and/or rename the current namespace within the following restrictions. +This plugin allows you to move and/or rename the current page or move and/or rename the current namespace within the following restrictions: - * You cannot move the start page. - * You must have edit permission for the document and any documents that point to it (backlinks). - * The document and its' backlinks cannot be locked for editing. - * For moving a file you also need create permission in the target directory. - * You cannot move the document to a namespace where a document with the same name already exists. + * You must have edit permission for the current page/all pages in the current namespace + * The pages that are moved must not be locked for editing. + * For moving a page you also need create permission in the target namespace. + * You cannot move a page to a namespace where a page with the same name already exists. -All links to and from the page will be updated to reflect the new location and/or name. -\\ -\\ \ No newline at end of file +All links to and from the pages that are moved will be updated to reflect the new location and/or name. diff --git a/script.js b/script.js new file mode 100644 index 0000000..853d067 --- /dev/null +++ b/script.js @@ -0,0 +1,42 @@ +/** + * JavasScript code for the preview in the pagemove plugin + * + * @author Michael Hamann + */ + +jQuery(function() { + jQuery('form.pagemove__form').each(function() { + var $this = jQuery(this); + var $preview = jQuery('

'); + $this.find('input[type=submit]').before($preview); + var updatePreview = function() { + if ($this.find('input[name=move_type]').attr('value') == 'namespace') { + var targetns = $this.find('select[name=targetns]').attr('value'); + var newnsname = $this.find('input[name=newnsname]').attr('value'); + var previewns; + if (targetns == ':') { + previewns = newnsname; + } else { + previewns = targetns + ':' + newnsname; + } + $preview.text(LANG['plugins']['pagemove']['pm_previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); + } else { + var ns_for_page = $this.find('select[name=ns_for_page]').attr('value'); + var newns = $this.find('input[name=newns]').attr('value'); + var newname = $this.find('input[name=newname]').attr('value'); + var newid = ''; + if (newns.replace(/\s/g) != '') { + newid = newns + ':'; + } else if (ns_for_page != ':') { + newid = ns_for_page + ':'; + } + newid += newname; + $preview.text(LANG['plugins']['pagemove']['pm_previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); + + } + }; + updatePreview(); + $this.find('input,select').change(updatePreview); + $this.find('input').keyup(updatePreview); + }); +}); \ No newline at end of file From c17ae02dd87c03678be910a1d8dd77c3a2d98919 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 23:27:05 +0100 Subject: [PATCH 008/338] Add more PHPDoc comments and remove no longer used variables --- admin.php | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/admin.php b/admin.php index 105d89b..873b31f 100644 --- a/admin.php +++ b/admin.php @@ -1,9 +1,9 @@ * @author Gary Owen, */ @@ -14,28 +14,25 @@ if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); -require_once DOKU_PLUGIN.'admin.php'; - +/** + * Admin component of the pagemove plugin. Provides the user interface. + */ class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { - var $show_form = true; - var $have_rights = true; - var $locked_files = array(); - var $errors = array(); var $opts = array(); - var $idsToDelete = array(); - + /** + * Get the sort number that defines the position in the admin menu. + * + * @return int The sort number + */ function getMenuSort() { return 1000; } - function forAdminOnly() { return false; } /** - * function constructor + * If this admin plugin is for admins only + * @return bool false */ - function admin_plugin_pagemove(){ - // enable direct access to language strings - $this->setupLocale(); - } + function forAdminOnly() { return false; } /** * return some info From f97089280f40a301bebffda725803461e46eef1b Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 29 Dec 2012 23:51:21 +0100 Subject: [PATCH 009/338] Move page/namespace move functions into the helper This separates the UI (admin.php) and the functionality (helper.php) so the main functions of the pagemove plugin can also be used by other plugins or a possible ajax backend (for moving big namespaces). --- _test/pagemove.test.php | 10 +- admin.php | 258 ++-------------------------------------- helper.php | 247 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+), 255 deletions(-) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 8787d29..9bce88b 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -11,7 +11,7 @@ class PagemovePageTest extends DokuWikiTest { var $currentNsBacklinkingId = 'parent_ns:current_ns:some_page'; var $otherBacklinkingId = 'level0:level1:other_backlinking_page'; var $subNsPage = 'parent_ns:current_ns:sub_ns:some_page'; - /** @var admin_plugin_pagemove $pagemove */ + /** @var helper_plugin_pagemove $pagemove */ private $pagemove = NULL; // @todo Move page to an ID which already exists @@ -163,7 +163,7 @@ function setUp() { $references = array_keys(p_get_metadata($this->subNsPage, 'relation references', METADATA_RENDER_UNLIMITED)); idx_get_indexer()->addMetaKeys($this->subNsPage, 'relation_references', $references); - $this->pagemove = new admin_plugin_pagemove(); + $this->pagemove = new helper_plugin_pagemove(); parent::setUp(); } @@ -187,7 +187,7 @@ function test_move_page_in_same_ns() { $opts['newns'] = $opts['ns']; $opts['newname'] = $newPagename; $this->movedToId = $opts['newns'].':'.$newPagename; - $this->pagemove->_pm_move_page($opts); + $this->pagemove->move_page($opts); $newId = $opts['newns'].':'.$opts['newname']; $newContent = rawWiki($newId); @@ -305,7 +305,7 @@ function test_move_page_to_parallel_ns() { $opts['newns'] = 'parent_ns:parallel_ns'; $opts['newname'] = $newPagename; $this->movedToId = $opts['newns'].':'.$newPagename; - $this->pagemove->_pm_move_page($opts); + $this->pagemove->move_page($opts); $newId = $opts['newns'].':'.$opts['newname']; $newContent = rawWiki($newId); @@ -425,7 +425,7 @@ function test_move_page_to_parent_ns() { $newId = $opts['newns'].':'.$opts['newname']; $this->movedToId = $opts['newns'].':'.$newPagename; - $this->pagemove->_pm_move_page($opts); + $this->pagemove->move_page($opts); $newContent = rawWiki($newId); $expectedContent = <<opts['newnsname'] = cleanID((string)$_POST['newnsname']); if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; + /** @var helper_plugin_pagemove $helper */ + $helper = $this->loadHelper('pagemove', true); + if (!$helper) return; + // check the input for completeness if( $this->opts['move_type'] == 'namespace' ) { if ($this->opts['targetns'] == '') { @@ -176,9 +180,9 @@ function handle() { $this->opts['newns'] = $this->opts['targetns'].':'.$this->opts['newnsname']; } - if ($this->_pm_move_recursive($this->opts, true) && - $this->_pm_move_recursive($this->opts)) { - $ID = $this->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); + if ($helper->move_namespace($this->opts, true) && + $helper->move_namespace($this->opts)) { + $ID = $helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); $ACT = 'show'; } else { return; @@ -194,7 +198,7 @@ function handle() { $this->opts['newns'] = $this->opts['ns_for_page']; } - if ($this->_pm_move_page($this->opts)) { + if ($helper->move_page($this->opts)) { // @todo if the namespace is now empty, delete it // Set things up to display the new page. @@ -205,250 +209,4 @@ function handle() { } } } - - - /** - * - * @author Bastian Wolf - * @param array $opts Options for moving the page - * @param bool $checkonly If only the checks if all pages can be moved shall be executed - * @return bool if the move was executed - */ - function _pm_move_recursive(&$opts, $checkonly = false) { - global $ID; - global $conf; - - $pagelist = array(); - $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); - $searchOpts = array('depth' => 0, 'skipacl' => true); - search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); - - // FIXME: either use ajax for executing the queue and/or store the queue so it can be resumed when the execution - // is aborted. - foreach ($pagelist as $page) { - $ID = $page['id']; - $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); - $pageOpts = $opts; - $pageOpts['ns'] = getNS($ID); - $pageOpts['name'] = noNS($ID); - $pageOpts['newname'] = noNS($ID); - $pageOpts['newns'] = getNS($newID); - if (!$this->_pm_move_page($pageOpts, $checkonly)) return false; - } - return true; - } - - /** - * Get the id of a page after a namespace move - * - * @param string $oldid The old id of the page - * @param string $oldns The old namespace. $oldid needs to be inside $oldns - * @param string $newns The new namespace - * @return string The new id - */ - function getNewID($oldid, $oldns, $newns) { - $newid = $oldid; - if ($oldns != '') { - $newid = substr($oldid, strlen($oldns)+1); - } - - if ($newns != '') { - $newid = $newns.':'.$newid; - } - - return $newid; - } - - - /** - * move page - * - * @author Gary Owen , modified by Kay Roesler - * - * @param array $opts - * @param bool $checkonly Only execute the checks if the page can be moved - * @return bool If the move was executed - */ - function _pm_move_page(&$opts, $checkonly = false) { - global $ID; - - // Check we have rights to move this document - if ( !page_exists($ID)) { - msg($this->getLang('pm_notexist'), -1); - return false; - } - if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { - msg(sprintf($this->getLang('pm_norights'), hsc($ID)), -1); - return false; - } - - // Check file is not locked - if (checklock($ID) !== false) { - msg( sprintf($this->getLang('pm_filelocked'), hsc($ID)), -1); - return false; - } - - // Assemble fill document name and path - $opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']); - $opts['new_path'] = wikiFN($opts['new_id']); - - // Has the document name and/or namespace changed? - if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { - msg($this->getLang('pm_nochange'), -1); - return false; - } - // Check the page does not already exist - if ( @file_exists($opts['new_path']) ) { - msg(sprintf($this->getLang('pm_existing'), $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_id']) < AUTH_CREATE) { - msg(sprintf($this->getLang('pm_notargetperms'), $opts['new_id']), -1); - return false; - } - - if ($checkonly) return true; - - /** - * End of init (checks) - */ - - $page_meta = p_get_metadata($ID, 'plugin_pagemove', METADATA_DONT_RENDER); - if (!$page_meta) $page_meta = array(); - if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); - $page_meta['old_ids'][$ID] = time(); - - // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages - $affected_pages = idx_get_indexer()->lookupKey('relation_references', array_keys($page_meta['old_ids'])); - - $data = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], '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 - // note that old_ids is in the form 'id' => timestamp of move and affected_pages is indexed by these ids - $event = new Doku_Event('PAGEMOVE_PAGE_RENAME', $data); - if ($event->advise_before()) { - // Open the old document and change forward links - lock($ID); - $text = rawWiki($ID); - - /** @var helper_plugin_pagemove $helper */ - $helper = $this->loadHelper('pagemove', true); - if (is_null($helper)) return false; - - $text = $helper->rewrite_content($text, $ID, array($ID => $opts['new_id'])); - - // Move the Subscriptions & Indexes - $this->movemeta($opts); - - // Save the updated document in its new location - if ($opts['ns'] == $opts['newns']) { - $lang_key = 'pm_renamed'; - } - elseif ( $opts['name'] == $opts['newname'] ) { - $lang_key = 'pm_moved'; - } - else { - $lang_key = 'pm_move_rename'; - } - $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); - saveWikiText($opts['new_id'], $text, $summary); - - // Delete the orginal file - if (@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($ID, '', $this->getLang('pm_delete') ); - } - - // Move the old revisions - $this->moveattic($opts); - - asort($page_meta['old_ids']); - - // additional pages that should be considered because they were affected by moves from previous names - // if the page has been rendered in the meantime and but the new links aren't in the index yet the - // page might need information about a more recent rename even though it is not listed for this more recent link - $additional_pages = array(); - foreach ($page_meta['old_ids'] as $page_id => $time) { - if (!isset($affected_pages[$page_id])) { - $affected_pages[$page_id] = $additional_pages; - } else { - $affected_pages[$page_id] = array_unique(array_merge($affected_pages[$page_id], $additional_pages)); - } - foreach ($affected_pages[$page_id] as $id) { - if (!page_exists($id, '', false) || $id == $page_id || $id == $opts['new_id']) continue; - // if the page has been modified since the rename of the old page, the link in the new page is most - // probably intentionally to the old page and shouldn't be changed - if (filemtime(wikiFN($id, '', false)) > $time) continue; - $additional_pages[] = $id; - // 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('moves' => array()); - if (!isset($meta['moves'])) $meta['moves'] = array(); - $meta['moves'][$page_id] = $opts['new_id']; - // remove redundant moves (can happen when a page is moved back to its old id) - if ($page_id == $opts['new_id']) unset($meta['moves'][$page_id]); - if (empty($meta['moves'])) unset($meta['moves']); - p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); - } - } - - p_set_metadata($opts['new_id'], array('plugin_pagemove' => $page_meta), false, true); - } - - $event->advise_after(); - return true; - } - - /** - * Move the old revisions of the page that is specified in the options. - * - * @param array $opts Pagemove options (used here: name, newname, ns, newns) - */ - function moveattic($opts) { - global $conf; - - $regex = '\.\d+\.txt(?:\.gz|\.bz2)?'; - $this->move_files($conf['olddir'], $opts, $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) - */ - function movemeta($opts) { - global $conf; - - $regex = '\.[^.]+'; - $this->move_files($conf['metadir'], $opts, $regex); - } - - /** - * Internal function for moving and renaming meta/attic files between namespaces - * - * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] - * @param array $opts Pagemove options (used here: ns, newns, name, newname) - * @param string $extregex Regular expression for matching the extension of the file that shall be moved - */ - private function move_files($dir, $opts, $extregex) { - $old_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['ns'])).'/'; - $new_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['newns'])).'/'; - $regex = '/^'.preg_quote(utf8_encodeFN($opts['name'])).'('.$extregex.')$/u'; - - $dh = @opendir($old_path); - if($dh) { - while(($file = readdir($dh)) !== false) { - if (substr($file, 0, 1) == '.') continue; - $match = array(); - if (is_file($old_path.$file) && preg_match($regex, $file, $match)) { - if (!is_dir($new_path)) io_mkdir_p($new_path); - io_rename($old_path.$file, $new_path.utf8_encodeFN($opts['newname'].$match[1])); - } - } - closedir($dh); - } - } } \ No newline at end of file diff --git a/helper.php b/helper.php index dcada54..1b4b0a3 100644 --- a/helper.php +++ b/helper.php @@ -5,6 +5,248 @@ * @author Michael Hamann */ class helper_plugin_pagemove extends DokuWiki_Plugin { + /** + * Move a namespace according to the given options + * + * @author Bastian Wolf + * @param array $opts Options for moving the namespace + * @param bool $checkonly If only the checks if all pages can be moved shall be executed + * @return bool if the move was executed + */ + function move_namespace(&$opts, $checkonly = false) { + global $ID; + global $conf; + + $pagelist = array(); + $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); + $searchOpts = array('depth' => 0, 'skipacl' => true); + search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); + + // FIXME: either use ajax for executing the queue and/or store the queue so it can be resumed when the execution + // is aborted. + foreach ($pagelist as $page) { + $ID = $page['id']; + $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); + $pageOpts = $opts; + $pageOpts['ns'] = getNS($ID); + $pageOpts['name'] = noNS($ID); + $pageOpts['newname'] = noNS($ID); + $pageOpts['newns'] = getNS($newID); + if (!$this->move_page($pageOpts, $checkonly)) return false; + } + return true; + } + + /** + * Get the id of a page after a namespace move + * + * @param string $oldid The old id of the page + * @param string $oldns The old namespace. $oldid needs to be inside $oldns + * @param string $newns The new namespace + * @return string The new id + */ + function getNewID($oldid, $oldns, $newns) { + $newid = $oldid; + if ($oldns != '') { + $newid = substr($oldid, strlen($oldns)+1); + } + + if ($newns != '') { + $newid = $newns.':'.$newid; + } + + return $newid; + } + + + /** + * move page + * + * @author Gary Owen , modified by Kay Roesler + * @author Michael Hamann + * + * @param array $opts + * @param bool $checkonly Only execute the checks if the page can be moved + * @return bool If the move was executed + */ + public function move_page(&$opts, $checkonly = false) { + global $ID; + + // Check we have rights to move this document + if ( !page_exists($ID)) { + msg($this->getLang('pm_notexist'), -1); + return false; + } + if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { + msg(sprintf($this->getLang('pm_norights'), hsc($ID)), -1); + return false; + } + + // Check file is not locked + if (checklock($ID) !== false) { + msg( sprintf($this->getLang('pm_filelocked'), hsc($ID)), -1); + return false; + } + + // Assemble fill document name and path + $opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']); + $opts['new_path'] = wikiFN($opts['new_id']); + + // Has the document name and/or namespace changed? + if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { + msg($this->getLang('pm_nochange'), -1); + return false; + } + // Check the page does not already exist + if ( @file_exists($opts['new_path']) ) { + msg(sprintf($this->getLang('pm_existing'), $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_id']) < AUTH_CREATE) { + msg(sprintf($this->getLang('pm_notargetperms'), $opts['new_id']), -1); + return false; + } + + if ($checkonly) return true; + + /** + * End of init (checks) + */ + + $page_meta = p_get_metadata($ID, 'plugin_pagemove', METADATA_DONT_RENDER); + if (!$page_meta) $page_meta = array(); + if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); + $page_meta['old_ids'][$ID] = time(); + + // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages + $affected_pages = idx_get_indexer()->lookupKey('relation_references', array_keys($page_meta['old_ids'])); + + $data = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], '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 + // note that old_ids is in the form 'id' => timestamp of move and affected_pages is indexed by these ids + $event = new Doku_Event('PAGEMOVE_PAGE_RENAME', $data); + if ($event->advise_before()) { + // Open the old document and change forward links + lock($ID); + $text = rawWiki($ID); + + $text = $this->rewrite_content($text, $ID, array($ID => $opts['new_id'])); + + // Move the Subscriptions & Indexes + $this->movemeta($opts); + + // Save the updated document in its new location + if ($opts['ns'] == $opts['newns']) { + $lang_key = 'pm_renamed'; + } + elseif ( $opts['name'] == $opts['newname'] ) { + $lang_key = 'pm_moved'; + } + else { + $lang_key = 'pm_move_rename'; + } + $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); + saveWikiText($opts['new_id'], $text, $summary); + + // Delete the orginal file + if (@file_exists(wikiFN($opts['new_id']))) { + saveWikiText($ID, '', $this->getLang('pm_delete') ); + } + + // Move the old revisions + $this->moveattic($opts); + + asort($page_meta['old_ids']); + + // additional pages that should be considered because they were affected by moves from previous names + // if the page has been rendered in the meantime and but the new links aren't in the index yet the + // page might need information about a more recent rename even though it is not listed for this more recent link + $additional_pages = array(); + foreach ($page_meta['old_ids'] as $page_id => $time) { + if (!isset($affected_pages[$page_id])) { + $affected_pages[$page_id] = $additional_pages; + } else { + $affected_pages[$page_id] = array_unique(array_merge($affected_pages[$page_id], $additional_pages)); + } + foreach ($affected_pages[$page_id] as $id) { + if (!page_exists($id, '', false) || $id == $page_id || $id == $opts['new_id']) continue; + // if the page has been modified since the rename of the old page, the link in the new page is most + // probably intentionally to the old page and shouldn't be changed + if (filemtime(wikiFN($id, '', false)) > $time) continue; + $additional_pages[] = $id; + // 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('moves' => array()); + if (!isset($meta['moves'])) $meta['moves'] = array(); + $meta['moves'][$page_id] = $opts['new_id']; + // remove redundant moves (can happen when a page is moved back to its old id) + if ($page_id == $opts['new_id']) unset($meta['moves'][$page_id]); + if (empty($meta['moves'])) unset($meta['moves']); + p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); + } + } + + p_set_metadata($opts['new_id'], array('plugin_pagemove' => $page_meta), false, true); + } + + $event->advise_after(); + return true; + } + + /** + * Move the old revisions of the page that is specified in the options. + * + * @param array $opts Pagemove options (used here: name, newname, ns, newns) + */ + public function moveattic($opts) { + global $conf; + + $regex = '\.\d+\.txt(?:\.gz|\.bz2)?'; + $this->move_files($conf['olddir'], $opts, $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) + */ + public function movemeta($opts) { + global $conf; + + $regex = '\.[^.]+'; + $this->move_files($conf['metadir'], $opts, $regex); + } + + /** + * Internal function for moving and renaming meta/attic files between namespaces + * + * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] + * @param array $opts Pagemove options (used here: ns, newns, name, newname) + * @param string $extregex Regular expression for matching the extension of the file that shall be moved + */ + private function move_files($dir, $opts, $extregex) { + $old_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['ns'])).'/'; + $new_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['newns'])).'/'; + $regex = '/^'.preg_quote(utf8_encodeFN($opts['name'])).'('.$extregex.')$/u'; + + $dh = @opendir($old_path); + if($dh) { + while(($file = readdir($dh)) !== false) { + if (substr($file, 0, 1) == '.') continue; + $match = array(); + if (is_file($old_path.$file) && preg_match($regex, $file, $match)) { + if (!is_dir($new_path)) io_mkdir_p($new_path); + io_rename($old_path.$file, $new_path.utf8_encodeFN($opts['newname'].$match[1])); + } + } + closedir($dh); + } + } + /** * Rewrite a text in order to fix the content after the given moves. * @@ -364,6 +606,11 @@ public function adaptRelativeId($id) { } } + /** + * Remove the namespace from the given id like noNS(), but handles '/' as namespace separator + * @param string $id the id + * @return string the id without the namespace + */ private function noNS($id) { $pos = strrpos($id, ':'); $spos = strrpos($id, '/'); From 38d04ae1d02ba4c97ded7675d03b76be5ff865e9 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 13:30:46 +0100 Subject: [PATCH 010/338] Cleanup: rename function, remove useless code, update documentation Namespace cleanup isn't needed, DokuWiki tries to clean the namespace when the page is deleted. --- admin.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/admin.php b/admin.php index 223e6af..b89107e 100644 --- a/admin.php +++ b/admin.php @@ -62,21 +62,23 @@ function getMenuText() { /** * output appropriate html * + * @author Michael Hamann * @author Gary Owen */ function html() { ptln(''); ptln( $this->locale_xhtml('pagemove') ); - $this->_pm_form(); + $this->printForm(); ptln(''); } /** * show the move and/or rename a page form * + * @author Michael Hamann * @author Gary Owen */ - function _pm_form() { + function printForm() { global $ID; $ns = getNS($ID); @@ -184,8 +186,6 @@ function handle() { $helper->move_namespace($this->opts)) { $ID = $helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); $ACT = 'show'; - } else { - return; } } else { // check that the pagename is valid @@ -199,13 +199,9 @@ function handle() { } if ($helper->move_page($this->opts)) { - // @todo if the namespace is now empty, delete it - // Set things up to display the new page. $ID = $this->opts['new_id']; $ACT = 'show'; // this triggers a redirect to the page - } else { - return; } } } From 1eefdb1c5b03e22f80fbcb5e49eeefcd5b2dd767 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 17:06:01 +0100 Subject: [PATCH 011/338] Extract the page rewriting code into a helper function --- action.php | 19 ++++--------------- helper.php | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/action.php b/action.php index 4786ff6..a80e8a2 100644 --- a/action.php +++ b/action.php @@ -35,21 +35,10 @@ function handle_read(Doku_Event $event, $param) { if ((isset($ACT) && (in_array($ACT, array('save', 'preview', 'recover', 'revert')))) || checklock($id) !== false) return; - $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); - if ($meta && isset($meta['moves'])) { - $stack[$id] = true; - $helper = $this->loadHelper('pagemove', true); - if (!is_null($helper)) { - $event->result = $helper->rewrite_content($event->result, $id, $meta['moves']); - } - $file = wikiFN($id, '', false); - if (is_writable($file)) { - saveWikiText($id,$event->result,$this->getLang('pm_linkchange')); - unset($meta['moves']); - p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); - } else { // FIXME: print error here or fail silently? - msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); - } + $helper = $this->loadHelper('pagemove', true); + if(!is_null($helper)) { + $stack[$id] = true; + $event->result = $helper->execute_rewrites($id, $event->result); unset($stack[$id]); } } diff --git a/helper.php b/helper.php index 1b4b0a3..fa85983 100644 --- a/helper.php +++ b/helper.php @@ -247,6 +247,32 @@ private function move_files($dir, $opts, $extregex) { } } + /** + * Rewrite the text of a page according to the recorded moves, the rewritten text is saved + * + * @param string $id The id of the page that shall be rewritten + * @param string|null $text Old content of the page. When null is given the content is loaded from disk. + * @return string The rewritten content + */ + public function execute_rewrites($id, $text = null) { + $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); + if($meta && isset($meta['moves'])) { + if(is_null($text)) $text = rawWiki($id); + + $text = $this->rewrite_content($text, $id, $meta['moves']); + $file = wikiFN($id, '', false); + if(is_writable($file)) { + saveWikiText($id, $text, $this->getLang('pm_linkchange')); + unset($meta['moves']); + p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); + } else { // FIXME: print error here or fail silently? + msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + } + } + + return $text; + } + /** * Rewrite a text in order to fix the content after the given moves. * From 89da326fe1e2a1aecc36eb4369d10bad8839b844 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 17:20:04 +0100 Subject: [PATCH 012/338] Remove unused defines --- admin.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/admin.php b/admin.php index b89107e..d21166f 100644 --- a/admin.php +++ b/admin.php @@ -10,10 +10,6 @@ // must be run within Dokuwiki if (!defined('DOKU_INC')) die(); -if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); -if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); -if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); - /** * Admin component of the pagemove plugin. Provides the user interface. */ From 7363e4a73da4f6622577482881fdaaa2353922c1 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 17:22:23 +0100 Subject: [PATCH 013/338] Add license and check for DOKU_INC in action and helper part --- action.php | 11 +++++++++-- helper.php | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/action.php b/action.php index a80e8a2..9aab30a 100644 --- a/action.php +++ b/action.php @@ -1,8 +1,15 @@ + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Michael Hamann + */ +// must be run within Dokuwiki +if (!defined('DOKU_INC')) die(); + +/** + * Action part of the pagemove plugin */ class action_plugin_pagemove extends DokuWiki_Action_Plugin { /** diff --git a/helper.php b/helper.php index fa85983..56bd22d 100644 --- a/helper.php +++ b/helper.php @@ -1,8 +1,15 @@ + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Michael Hamann + */ +// must be run within Dokuwiki +if (!defined('DOKU_INC')) die(); + +/** + * Helper part of the pagemove plugin. */ class helper_plugin_pagemove extends DokuWiki_Plugin { /** From 493bca2c4f4655be4acf103ac017ecf6446d2c0a Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 19:20:42 +0100 Subject: [PATCH 014/338] Prevent creation of more than one revision/second --- helper.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/helper.php b/helper.php index 56bd22d..92cd7e5 100644 --- a/helper.php +++ b/helper.php @@ -141,7 +141,8 @@ public function move_page(&$opts, $checkonly = false) { lock($ID); $text = rawWiki($ID); - $text = $this->rewrite_content($text, $ID, array($ID => $opts['new_id'])); + $text = $this->rewrite_content($text, $ID, array($ID => $opts['new_id'])); + $oldRev = getRevisions($ID, -1, 1, 1024); // from changelog // Move the Subscriptions & Indexes $this->movemeta($opts); @@ -156,6 +157,10 @@ public function move_page(&$opts, $checkonly = false) { else { $lang_key = 'pm_move_rename'; } + + // Wait a second when the page has just been rewritten + if ($oldRev == time()) sleep(1); + $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); saveWikiText($opts['new_id'], $text, $summary); @@ -269,6 +274,9 @@ public function execute_rewrites($id, $text = null) { $text = $this->rewrite_content($text, $id, $meta['moves']); $file = wikiFN($id, '', false); if(is_writable($file)) { + // Wait a seconf if page has just been saved + $oldRev = getRevisions($id, -1, 1, 1024); // from changelog + if ($oldRev == time()) sleep(1); saveWikiText($id, $text, $this->getLang('pm_linkchange')); unset($meta['moves']); p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); From 947ab47dcef27d1bd61c76bb443bac6f9fddd79f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 19:21:33 +0100 Subject: [PATCH 015/338] Unlock the old page after moving --- helper.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helper.php b/helper.php index 92cd7e5..0a225fe 100644 --- a/helper.php +++ b/helper.php @@ -203,6 +203,8 @@ public function move_page(&$opts, $checkonly = false) { } p_set_metadata($opts['new_id'], array('plugin_pagemove' => $page_meta), false, true); + + unlock($ID); } $event->advise_after(); From 45dd5ba8aae8b12aaf3e1e2573f4bca1edd00b90 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 23:06:59 +0100 Subject: [PATCH 016/338] Print the id in the "page does not exist" message --- admin.php | 2 +- helper.php | 2 +- lang/en/lang.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/admin.php b/admin.php index d21166f..07b41bd 100644 --- a/admin.php +++ b/admin.php @@ -46,7 +46,7 @@ function getMenuText() { global $INFO; if( !$INFO['exists'] ) - return $this->getLang('menu').' ('.$this->getLang('pm_notexist').')'; + return $this->getLang('menu').' ('.sprintf($this->getLang('pm_notexist'), $INFO['id']).')'; elseif( !$INFO['writable'] ) return $this->getLang('menu').' ('.$this->getLang('pm_notwrite').')'; else diff --git a/helper.php b/helper.php index 0a225fe..c04e0dd 100644 --- a/helper.php +++ b/helper.php @@ -81,7 +81,7 @@ public function move_page(&$opts, $checkonly = false) { // Check we have rights to move this document if ( !page_exists($ID)) { - msg($this->getLang('pm_notexist'), -1); + msg(sprintf($this->getLang('pm_notexist'), $ID), -1); return false; } if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { diff --git a/lang/en/lang.php b/lang/en/lang.php index 4659d70..235e13d 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -15,7 +15,7 @@ $lang['menu'] = 'Page/Namespace Move/Rename...'; $lang['desc'] = 'Page/Namespace Move/Rename Plugin'; -$lang['pm_notexist'] = 'This page does not exist'; +$lang['pm_notexist'] = 'The page %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.'; From c6239d0e996fa296864bf5195ac67c0d5addc84d Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 23:07:33 +0100 Subject: [PATCH 017/338] Special handling of root namespace in file moves --- helper.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/helper.php b/helper.php index c04e0dd..dec5152 100644 --- a/helper.php +++ b/helper.php @@ -243,8 +243,10 @@ public function movemeta($opts) { * @param string $extregex Regular expression for matching the extension of the file that shall be moved */ private function move_files($dir, $opts, $extregex) { - $old_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['ns'])).'/'; - $new_path = $dir.'/'.utf8_encodeFN(str_replace(':', '/', $opts['newns'])).'/'; + $old_path = $dir.'/'; + if ($opts['ns'] != '') $old_path .= utf8_encodeFN(str_replace(':', '/', $opts['ns'])).'/'; + $new_path = $dir.'/'; + if ($opts['newns'] != '') $new_path .= utf8_encodeFN(str_replace(':', '/', $opts['newns'])).'/'; $regex = '/^'.preg_quote(utf8_encodeFN($opts['name'])).'('.$extregex.')$/u'; $dh = @opendir($old_path); From b4ce49990251283fede5f6fc4f8524d93353e34e Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 23:08:16 +0100 Subject: [PATCH 018/338] Prevent infinite loop when pages have been moved in a loop --- helper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/helper.php b/helper.php index dec5152..801a7f7 100644 --- a/helper.php +++ b/helper.php @@ -316,7 +316,7 @@ function rewrite_content($text, $id, $moves) { while($changed) { $changed = false; foreach($tmp_moves as $old => $new) { - if(isset($moves[$new]) && $moves[$new] != $new) { + if($old != $new && isset($moves[$new]) && $moves[$new] != $new) { $tmp_moves[$old] = $moves[$new]; $changed = true; } @@ -325,7 +325,8 @@ function rewrite_content($text, $id, $moves) { // manual merge, we can't use array_merge here as ids can be numeric foreach($tmp_moves as $old => $new) { - $moves[$old] = $new; + if ($old == $new) unset($moves[$old]); + else $moves[$old] = $new; } $handlers = array(); From 542edaacaeaddd3bbfc46bfbeb081f00abcc7b24 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 30 Dec 2012 23:17:30 +0100 Subject: [PATCH 019/338] Add more move information so pages can be corrected in more cases --- helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper.php b/helper.php index 801a7f7..8971ace 100644 --- a/helper.php +++ b/helper.php @@ -186,10 +186,10 @@ public function move_page(&$opts, $checkonly = false) { } foreach ($affected_pages[$page_id] as $id) { if (!page_exists($id, '', false) || $id == $page_id || $id == $opts['new_id']) continue; + $additional_pages[] = $id; // if the page has been modified since the rename of the old page, the link in the new page is most // probably intentionally to the old page and shouldn't be changed if (filemtime(wikiFN($id, '', false)) > $time) continue; - $additional_pages[] = $id; // 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('moves' => array()); From 166689041fc4f8aacc4de5365193346c392a5a1f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 1 Jan 2013 12:24:25 +0100 Subject: [PATCH 020/338] Update the search index while moving pages, assume the index is correct This simplifies the search for links because now it can be assumed that the search index is always correct and contains even link updates that haven't been executed yet. The problem before this change was that the search index became unusable after a namespace move. --- helper.php | 205 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 149 insertions(+), 56 deletions(-) diff --git a/helper.php b/helper.php index 8971ace..45d76bb 100644 --- a/helper.php +++ b/helper.php @@ -128,7 +128,7 @@ public function move_page(&$opts, $checkonly = false) { $page_meta['old_ids'][$ID] = time(); // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages - $affected_pages = idx_get_indexer()->lookupKey('relation_references', array_keys($page_meta['old_ids'])); + $affected_pages = idx_get_indexer()->lookupKey('relation_references', $ID); $data = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], 'affected_pages' => &$affected_pages); // give plugins the option to add their own meta files to the list of files that need to be moved @@ -145,6 +145,11 @@ public function move_page(&$opts, $checkonly = false) { $oldRev = getRevisions($ID, -1, 1, 1024); // from changelog // Move the Subscriptions & Indexes + $Indexer = new helper_plugin_pagemove_indexer(); + if (($idx_msg = $Indexer->renamePage($ID, $opts['new_id'])) !== true) { + msg('Error while updating the search index '.$idx_msg, -1); + return false; + } $this->movemeta($opts); // Save the updated document in its new location @@ -172,34 +177,16 @@ public function move_page(&$opts, $checkonly = false) { // Move the old revisions $this->moveattic($opts); - asort($page_meta['old_ids']); - - // additional pages that should be considered because they were affected by moves from previous names - // if the page has been rendered in the meantime and but the new links aren't in the index yet the - // page might need information about a more recent rename even though it is not listed for this more recent link - $additional_pages = array(); - foreach ($page_meta['old_ids'] as $page_id => $time) { - if (!isset($affected_pages[$page_id])) { - $affected_pages[$page_id] = $additional_pages; - } else { - $affected_pages[$page_id] = array_unique(array_merge($affected_pages[$page_id], $additional_pages)); - } - foreach ($affected_pages[$page_id] as $id) { - if (!page_exists($id, '', false) || $id == $page_id || $id == $opts['new_id']) continue; - $additional_pages[] = $id; - // if the page has been modified since the rename of the old page, the link in the new page is most - // probably intentionally to the old page and shouldn't be changed - if (filemtime(wikiFN($id, '', false)) > $time) 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('moves' => array()); - if (!isset($meta['moves'])) $meta['moves'] = array(); - $meta['moves'][$page_id] = $opts['new_id']; - // remove redundant moves (can happen when a page is moved back to its old id) - if ($page_id == $opts['new_id']) unset($meta['moves'][$page_id]); - if (empty($meta['moves'])) unset($meta['moves']); - p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); - } + foreach ($affected_pages as $id) { + if (!page_exists($id, '', false) || $id == $ID || $id == $opts['new_id']) 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('moves' => array()); + if (!isset($meta['moves'])) $meta['moves'] = array(); + $meta['moves'] = $this->resolve_moves($meta['moves'], $id); + $meta['moves'][$ID] = $opts['new_id']; + //if (empty($meta['moves'])) unset($meta['moves']); + p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); } p_set_metadata($opts['new_id'], array('plugin_pagemove' => $page_meta), false, true); @@ -301,33 +288,7 @@ public function execute_rewrites($id, $text = null) { * @return string The rewritten wiki text */ function rewrite_content($text, $id, $moves) { - // resolve moves of pages that were moved more than once - $tmp_moves = array(); - foreach($moves as $old => $new) { - if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { - // write to temp array in order to correctly handle rename circles - $tmp_moves[$old] = $moves[$new]; - } - } - - $changed = !empty($tmp_moves); - - // this correctly resolves rename circles by moving forward one step a time - while($changed) { - $changed = false; - foreach($tmp_moves as $old => $new) { - if($old != $new && isset($moves[$new]) && $moves[$new] != $new) { - $tmp_moves[$old] = $moves[$new]; - $changed = true; - } - } - } - - // manual merge, we can't use array_merge here as ids can be numeric - foreach($tmp_moves as $old => $new) { - if ($old == $new) unset($moves[$old]); - else $moves[$old] = $new; - } + $moves = $this->resolve_moves($moves, $id); $handlers = array(); $data = array('id' => $id, 'moves' => &$moves, 'handlers' => &$handlers); @@ -363,6 +324,138 @@ function rewrite_content($text, $id, $moves) { return $Parser->parse($text); } + + /** + * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. + * + * @param array $moves The moves + * @param string $id + * @return array The resolved moves + */ + protected function resolve_moves($moves, $id) { + // resolve moves of pages that were moved more than once + $tmp_moves = array(); + foreach($moves as $old => $new) { + if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { + // write to temp array in order to correctly handle rename circles + $tmp_moves[$old] = $moves[$new]; + } + } + + $changed = !empty($tmp_moves); + + // this correctly resolves rename circles by moving forward one step a time + while($changed) { + $changed = false; + foreach($tmp_moves as $old => $new) { + if($old != $new && isset($moves[$new]) && $moves[$new] != $new) { + $tmp_moves[$old] = $moves[$new]; + $changed = true; + } + } + } + + // manual merge, we can't use array_merge here as ids can be numeric + foreach($tmp_moves as $old => $new) { + if($old == $new) unset($moves[$old]); + else $moves[$old] = $new; + } + return $moves; + } +} + +/** + * Indexer class extended by pagemove features + */ +class helper_plugin_pagemove_indexer extends Doku_Indexer { + /** + * Rename a page in the search index without changing the indexed content + * + * @param string $oldpage The old page name + * @param string $newpage The new page name + * @return string|bool If the page was successfully renamed, can be a message in the case of an error + */ + public function renamePage($oldpage, $newpage) { + if (!$this->lock()) return 'locked'; + + $pages = $this->getPages(); + + $id = array_search($oldpage, $pages); + if ($id === false) { + $this->unlock(); + return 'page is not in index'; + } + + $new_id = array_search($newpage, $pages); + if ($new_id !== false) { + $this->unlock(); + // make sure the page is not in the index anymore + $this->deletePage($newpage); + if (!$this->lock()) return 'locked'; + + $pages[$new_id] = 'deleted:'.time().rand(0, 9999); + } + + $pages[$id] = $newpage; + + // update index + if (!$this->saveIndex('page', '', $pages)) { + $this->unlock(); + return false; + } + + if (isset($this->pidCache)) + $this->pidCache = array(); + + unset($pages); + + + // change the relation references index + $linktargets = $this->getIndex('relation_references', '_w'); + $linktargetid = array_search($oldpage, $linktargets); + if ($linktargetid !== false) { + $newlinktargetid = array_search($newpage, $linktargets); + if ($newlinktargetid !== false) { + // free memory + unset ($linktargets); + + // okay, now we have two entries for the same page. we need to merge them. + $indexline = $this->getIndexKey('relation_references', '_i', $linktargetid); + if ($indexline != '') { + $newindexline = $this->getIndexKey('relation_references', '_i', $newlinktargetid); + $pagekeys = $this->getIndex('relation_references', '_p'); + $parts = explode(':', $indexline); + foreach ($parts as $part) { + list($id, $count) = explode('*', $part); + $newindexline = $this->updateTuple($newindexline, $id, $count); + + $keyline = explode(':', $pagekeys[$id]); + // remove old link target + $keyline = array_diff($keyline, array($linktargetid)); + // add new link target when not already present + if (!in_array($newlinktargetid, $keyline)) { + array_push($keyline, $newlinktargetid); + } + $pagekeys[$id] = implode(':', $keyline); + } + $this->saveIndex('relation_references', '_p', $pagekeys); + unset($pagekeys); + $this->saveIndexKey('relation_references', '_i', $linktargetid, ''); + $this->saveIndexKey('relation_references', '_i', $newlinktargetid, $newindexline); + } + } else { + $linktargets[$linktargetid] = $newpage; + if (!$this->saveIndex('relation_references', '_w', $linktargets)) { + $this->unlock(); + return false; + } + } + } + + $this->unlock(); + return true; + } + } /** From 63f4c24a0e28972284b35159430ed3466a71f63f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 1 Jan 2013 12:32:34 +0100 Subject: [PATCH 021/338] Reconstruct missing id in IO_WIKIPAGE_READ and PARSER_CACHE_USE events When p_cached_instructions() is called without the $id parameter the id is also missing in the IO_WIKIPAGE_READ and PARSER_CACHE_USE events. However in both events the file path is supplied and using pathID() the path can be used for getting the id. --- action.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/action.php b/action.php index 9aab30a..2071697 100644 --- a/action.php +++ b/action.php @@ -29,13 +29,23 @@ public function register($controller) { * @param mixed $param Optional parameters (not used) */ function handle_read(Doku_Event $event, $param) { - global $ACT; + global $ACT, $conf; static $stack = array(); // handle only reads of the current revision if ($event->data[3]) return; $id = $event->data[2]; if ($event->data[1]) $id = $event->data[1].':'.$id; + + if (!$id) { + // try to reconstruct the id from the filename + $path = $event->data[0][0]; + if (strpos($path, $conf['datadir']) === 0) { + $path = substr($path, strlen($conf['datadir'])+1); + $id = pathID($path); + } + } + if (isset($stack[$id])) return; // Don't change the page when the user is currently changing the page content or the page is locked by another user @@ -57,9 +67,18 @@ function handle_read(Doku_Event $event, $param) { * @param mixed $param Optional parameters (not used) */ function handle_cache(Doku_Event $event, $param) { + global $conf; /** @var $cache cache_parser */ $cache = $event->data; $id = $cache->page; + if (!$id) { + // try to reconstruct the id from the filename + $path = $cache->file; + if (strpos($path, $conf['datadir']) === 0) { + $path = substr($path, strlen($conf['datadir'])+1); + $id = pathID($path); + } + } if ($id) { $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); if ($meta && isset($meta['moves'])) { From 259aea9d44d757a42280719264426c2ab8223e7c Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 1 Jan 2013 15:12:47 +0100 Subject: [PATCH 022/338] Abort move when meta files can't be moved --- helper.php | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/helper.php b/helper.php index 45d76bb..bf8de11 100644 --- a/helper.php +++ b/helper.php @@ -150,7 +150,10 @@ public function move_page(&$opts, $checkonly = false) { msg('Error while updating the search index '.$idx_msg, -1); return false; } - $this->movemeta($opts); + if (!$this->movemeta($opts)) { + msg('The meta files of page '.$ID.' couldn\'t be moved', -1); + return false; + } // Save the updated document in its new location if ($opts['ns'] == $opts['newns']) { @@ -175,7 +178,10 @@ public function move_page(&$opts, $checkonly = false) { } // Move the old revisions - $this->moveattic($opts); + if (!$this->moveattic($opts)) { + // it's too late to stop the move, so just display a message. + msg('The attic files of page '.$ID.' couldn\'t be moved. Please move them manually.', -1); + } foreach ($affected_pages as $id) { if (!page_exists($id, '', false) || $id == $ID || $id == $opts['new_id']) continue; @@ -202,24 +208,26 @@ public function move_page(&$opts, $checkonly = false) { * Move the old revisions of the page 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 moveattic($opts) { global $conf; $regex = '\.\d+\.txt(?:\.gz|\.bz2)?'; - $this->move_files($conf['olddir'], $opts, $regex); + return $this->move_files($conf['olddir'], $opts, $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 movemeta($opts) { global $conf; $regex = '\.[^.]+'; - $this->move_files($conf['metadir'], $opts, $regex); + return $this->move_files($conf['metadir'], $opts, $regex); } /** @@ -228,6 +236,7 @@ public function movemeta($opts) { * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] * @param array $opts Pagemove options (used here: ns, newns, name, newname) * @param string $extregex Regular expression for matching the extension of the file that shall be moved + * @return bool If the files were moved successfully */ private function move_files($dir, $opts, $extregex) { $old_path = $dir.'/'; @@ -242,12 +251,24 @@ private function move_files($dir, $opts, $extregex) { if (substr($file, 0, 1) == '.') continue; $match = array(); if (is_file($old_path.$file) && preg_match($regex, $file, $match)) { - if (!is_dir($new_path)) io_mkdir_p($new_path); - io_rename($old_path.$file, $new_path.utf8_encodeFN($opts['newname'].$match[1])); + if (!is_dir($new_path)) { + if (!io_mkdir_p($new_path)) { + msg('Creating directory '.hsc($new_path).' failed.', -1); + return false; + } + } + if (!io_rename($old_path.$file, $new_path.utf8_encodeFN($opts['newname'].$match[1]))) { + msg('Moving '.hsc($old_path.$file).' to '.hsc($new_path.utf8_encodeFN($opts['newname'].$match[1])).' failed.', -1); + return false; + } } } closedir($dh); + } else { + msg('Directory '.hsc($old_path).' couldn\'t be opened.', -1); + return false; } + return true; } /** From 2167aeadf902c4c5d400383790307f98ff2853b1 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 1 Jan 2013 15:13:13 +0100 Subject: [PATCH 023/338] Only write page when it has been changed --- helper.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/helper.php b/helper.php index bf8de11..2991172 100644 --- a/helper.php +++ b/helper.php @@ -283,13 +283,17 @@ public function execute_rewrites($id, $text = null) { if($meta && isset($meta['moves'])) { if(is_null($text)) $text = rawWiki($id); + $old_text = $text; $text = $this->rewrite_content($text, $id, $meta['moves']); + $changed = ($old_text != $text); $file = wikiFN($id, '', false); - if(is_writable($file)) { - // Wait a seconf if page has just been saved - $oldRev = getRevisions($id, -1, 1, 1024); // from changelog - if ($oldRev == time()) sleep(1); - saveWikiText($id, $text, $this->getLang('pm_linkchange')); + if(is_writable($file) || !$changed) { + if ($changed) { + // Wait a second if page has just been saved + $oldRev = getRevisions($id, -1, 1, 1024); // from changelog + if ($oldRev == time()) sleep(1); + saveWikiText($id, $text, $this->getLang('pm_linkchange')); + } unset($meta['moves']); p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); } else { // FIXME: print error here or fail silently? From 51892c2c3dccf1c805d37e3a90b898a820eea2c2 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 19 Jan 2013 20:45:24 +0100 Subject: [PATCH 024/338] Fix directory creation during metadata move --- helper.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/helper.php b/helper.php index 2991172..176098d 100644 --- a/helper.php +++ b/helper.php @@ -239,10 +239,10 @@ public function movemeta($opts) { * @return bool If the files were moved successfully */ private function move_files($dir, $opts, $extregex) { - $old_path = $dir.'/'; - if ($opts['ns'] != '') $old_path .= utf8_encodeFN(str_replace(':', '/', $opts['ns'])).'/'; - $new_path = $dir.'/'; - if ($opts['newns'] != '') $new_path .= utf8_encodeFN(str_replace(':', '/', $opts['newns'])).'/'; + $old_path = $dir; + if ($opts['ns'] != '') $old_path .= '/'.utf8_encodeFN(str_replace(':', '/', $opts['ns'])); + $new_path = $dir; + if ($opts['newns'] != '') $new_path .= '/'.utf8_encodeFN(str_replace(':', '/', $opts['newns'])); $regex = '/^'.preg_quote(utf8_encodeFN($opts['name'])).'('.$extregex.')$/u'; $dh = @opendir($old_path); @@ -250,15 +250,15 @@ private function move_files($dir, $opts, $extregex) { while(($file = readdir($dh)) !== false) { if (substr($file, 0, 1) == '.') continue; $match = array(); - if (is_file($old_path.$file) && preg_match($regex, $file, $match)) { + if (is_file($old_path.'/'.$file) && preg_match($regex, $file, $match)) { if (!is_dir($new_path)) { if (!io_mkdir_p($new_path)) { msg('Creating directory '.hsc($new_path).' failed.', -1); return false; } } - if (!io_rename($old_path.$file, $new_path.utf8_encodeFN($opts['newname'].$match[1]))) { - msg('Moving '.hsc($old_path.$file).' to '.hsc($new_path.utf8_encodeFN($opts['newname'].$match[1])).' failed.', -1); + if (!io_rename($old_path.'/'.$file, $new_path.'/'.utf8_encodeFN($opts['newname'].$match[1]))) { + msg('Moving '.hsc($old_path.'/'.$file).' to '.hsc($new_path.'/'.utf8_encodeFN($opts['newname'].$match[1])).' failed.', -1); return false; } } From e940890265e72b9b6e3af0a85a1702eca7d0778f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 25 Jan 2013 01:06:50 +0100 Subject: [PATCH 025/338] Updated translations Removed no longer used language strings, corrected the names of some language files and updated the language strings where possible. Some lines were replaced by the English version or commented out. The Chinese pagemove.txt help file was unreadable, I didn't find the correct encoding options in order to fix it so I deleted it. --- lang/cs/{lang.php.txt => lang.php} | 22 +++++---------- lang/cs/{pagemove.txt.txt => pagemove.txt} | 5 ++-- lang/de/lang.php | 32 ++++++++++------------ lang/de/pagemove.txt | 5 ++-- lang/es/{lang.php.txt => lang.php} | 20 ++++---------- lang/es/{pagemove.txt.txt => pagemove.txt} | 7 ++--- lang/fr/lang.php | 18 ++++-------- lang/fr/pagemove.txt | 7 ++--- lang/lv/lang.php | 18 ++++-------- lang/lv/pagemove.txt | 7 ++--- lang/nl/lang.php | 18 ++++-------- lang/nl/pagemove.txt | 3 +- lang/pl/{lang.php.txt => lang.php} | 20 ++++---------- lang/pl/{pagemove.txt.txt => pagemove.txt} | 7 ++--- lang/ru/lang.php | 18 ++++-------- lang/ru/pagemove.txt | 7 ++--- lang/sl/lang.php | 18 ++++-------- lang/sl/pagemove.txt | 7 ++--- lang/zh/lang.php | 18 ++++-------- lang/zh/pagemove.txt | 14 ---------- 20 files changed, 78 insertions(+), 193 deletions(-) rename lang/cs/{lang.php.txt => lang.php} (60%) rename lang/cs/{pagemove.txt.txt => pagemove.txt} (65%) rename lang/es/{lang.php.txt => lang.php} (61%) rename lang/es/{pagemove.txt.txt => pagemove.txt} (63%) rename lang/pl/{lang.php.txt => lang.php} (59%) rename lang/pl/{pagemove.txt.txt => pagemove.txt} (61%) delete mode 100644 lang/zh/pagemove.txt diff --git a/lang/cs/lang.php.txt b/lang/cs/lang.php similarity index 60% rename from lang/cs/lang.php.txt rename to lang/cs/lang.php index 26d3668..5995062 100644 --- a/lang/cs/lang.php.txt +++ b/lang/cs/lang.php @@ -1,4 +1,3 @@ - - \ No newline at end of file + + diff --git a/lang/cs/pagemove.txt.txt b/lang/cs/pagemove.txt similarity index 65% rename from lang/cs/pagemove.txt.txt rename to lang/cs/pagemove.txt index 8d84cf9..3e1c958 100644 --- a/lang/cs/pagemove.txt.txt +++ b/lang/cs/pagemove.txt @@ -2,9 +2,8 @@ Pomocí tohoto pluginu lze přesunout nebo přejmenovat aktuální stránku. Platí však jistá omezení: - * Nelze přesouvat titulní stránku. - * Musíte mít práva na danou stránku a na všechny, které se na ní odkazují. - * Tato stránka a na ni odkazující stránky nesmí být zamčené. + * Musíte mít práva na danou stránku. + * The pages that are moved must not be locked for editing. * Pro přesun stránky potřebujete práva pro zápis v cílovém místě. * Nelze přesunout stránku někam, kde již existuje stránka stejného jména. diff --git a/lang/de/lang.php b/lang/de/lang.php index 5144573..ab31995 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -15,8 +15,7 @@ $lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; $lang['desc'] = 'Seite/Namespace verschieben/umbenennen... Plugin'; -$lang['pm_notexist'] = 'Dieses Thema existiert noch nicht'; -$lang['pm_notstart'] = 'Die Startseite kann nicht verschoben oder umbenannt werden'; +$lang['pm_notexist'] = 'Die Seite %s existiert nicht.'; $lang['pm_notwrite'] = 'Sie haben unzureichende Rechte um diese Seite zu ändern'; $lang['pm_badns'] = 'Ungültige Zeichen in der Namensraum-Bezeichnung.'; $lang['pm_badname'] = 'Ungültiges Zeichen im Seitennamen.'; @@ -24,25 +23,22 @@ $lang['pm_existing'] = 'Eine Seite mit der Bezeichnung %s existiert bereits in %s'; $lang['pm_root'] = '[Wurzel des Namensraumes / Root namespace]'; $lang['pm_current'] = '(Aktueller)'; -$lang['pm_movedfrom'] = 'Seite verschoben von '; -$lang['pm_movedto'] = 'Seite verschoben nach '; -$lang['pm_renamed'] = 'Seitename wurde geändert von %s auf %s'; -$lang['pm_moved'] = 'Seite verschoben von %s nach %s'; -$lang['pm_move_rename'] = 'Seite verschoben und umbenannt von %s nach %s'; -$lang['pm_norights'] = 'Sie haben unzureichende Rechte, einen oder mehrere Rückverweise mit diesem Dokument zu verändern.'; -$lang['pm_tryagain'] = 'Versuchen Sie es später nochmal.'; -$lang['pm_filelocked'] = 'Diese Datei ist gesperrt - '; -$lang['pm_fileslocked'] = 'Diese Dateien sind gesperrt - '; -$lang['pm_linkchange'] = 'Link mit %s geändert zu %s'; +$lang['pm_renamed'] = 'Seitename wurde von %s auf %s geändert'; +$lang['pm_moved'] = 'Seite von %s nach %s verschoben'; +$lang['pm_move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; +$lang['pm_delete'] = 'Gelöscht durch das pagemove Plugin'; +$lang['pm_norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; +$lang['pm_notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; +$lang['pm_filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; +$lang['pm_linkchange'] = 'Link zu %s geändert zu %s'; +// Form labels $lang['pm_newname'] = 'Neuer Seitenname:'; -$lang['pm_newnsname'] = 'Neuen Namen für Namensraum verwenden:'; +$lang['pm_newnsname'] = 'Neuer Name für Namensraum:'; $lang['pm_targetns'] = 'Wählen Sie einen neuen Namensraum: '; $lang['pm_newtargetns'] = 'Erstellen Sie einen neuen Namensraum'; $lang['pm_movepage'] = 'Seite verschieben'; $lang['pm_movens'] = 'Namensraum verschieben'; -$lang['pm_previewpage'] = ' wird verschoben nach '; -$lang['pm_previewns'] = 'Alle Seiten und Namensräume im Namensraum %s: werden verschoben in den Namensraum'; -$lang['pm_preview'] = 'Vorschau'; -$lang['pm_delete'] = 'Gelöscht durch pagemove Plugin'; $lang['pm_submit'] = 'Übernehmen'; -?> +// JavaScript preview +$lang['js']['pm_previewpage'] = 'OLDPAGE wird in NEWPAGE umbenannt'; +$lang['js']['pm_previewns'] = 'Alle Seiten und Namensräume im Namensraum OLDNS werden in den Namensraum NEWNS verschoben'; diff --git a/lang/de/pagemove.txt b/lang/de/pagemove.txt index 9a33ea7..1db0ea2 100644 --- a/lang/de/pagemove.txt +++ b/lang/de/pagemove.txt @@ -4,9 +4,8 @@ Mit diesem Plugin kann die aktuelle Seite verschoben/umbenannt oder ein gesamter Folgende Einschränkungen/Bedingungen gelten: - * Die Startseite kann nicht verschoben werden. - * Man benötigt die Bearbeiten-Rechte für die Seite und für alle Seiten die darauf verlinkt sind (Rückverweise). - * Die Seite und deren Rückverweise dürfen nicht gesperrt sein, d.h. sich im Bearbeitungsmodus befinden. + * Sie müssen die Bearbeiten-Rechte für die Seite/alle Seiten im aktuellen Namensraum haben. + * Die Seiten, die verschoben werden, dürfen nicht gesperrt sein, d.h. sich im Bearbeitungsmodus befinden. * Um eine Seite zu verschieben, benötigt man das Erstellen-Recht im Ziel-Namensraum. * Eine Seite kann nicht in einen Namensraum verschoben werden, in der bereits eine Seite gleichen Namens existiert. diff --git a/lang/es/lang.php.txt b/lang/es/lang.php similarity index 61% rename from lang/es/lang.php.txt rename to lang/es/lang.php index 7a0f6e2..f97c31c 100644 --- a/lang/es/lang.php.txt +++ b/lang/es/lang.php @@ -1,4 +1,3 @@ - - \ No newline at end of file diff --git a/lang/es/pagemove.txt.txt b/lang/es/pagemove.txt similarity index 63% rename from lang/es/pagemove.txt.txt rename to lang/es/pagemove.txt index 421d26d..16f5035 100644 --- a/lang/es/pagemove.txt.txt +++ b/lang/es/pagemove.txt @@ -2,12 +2,9 @@ Esta extensión le permite mover y/o renombrar el documento actual respetando las siguientes restricciones. - * No puede mover la página de Inicio. - * Debe tener permisos de edición sobre el documento actual y sobre todos los documentos que enlazan con éste. - * El documento actual y los que hacen referencia a éste no pueden ser bloqueados para la edición. + * Debe tener permisos de edición sobre el documento actual. + * El documento actual no puede ser bloqueados para la edición. * Para mover un documento también necesita permiso de creación sobre el directorio de destino. * No puede mover el documento a un Espacio de Nombres donde ya existe un documento con el mismo nombre. Todos los enlaces desde y hacia esta página serán actualizados para reflejar la nueva ubicación y/o nombre. -\\ -\\ \ No newline at end of file diff --git a/lang/fr/lang.php b/lang/fr/lang.php index d239c32..b26452c 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -16,25 +16,17 @@ $lang['menu'] = 'Déplacer/Renommer la page...'; $lang['desc'] = 'Plugin de Déplacement/Renommage'; -$lang['pm_notexist'] = 'Ce sujet n\'existe pas encore'; -$lang['pm_notstart'] = 'La page de démarrage (Start) ne peut être déplacée ou renommée'; +$lang['pm_notexist'] = 'Le sujet %s n\'existe pas encore'; $lang['pm_notwrite'] = 'Vous ne disposez pas des droits suffisants pour modifier cette page'; $lang['pm_badns'] = "Caractères invalides dans l'espace de nommage."; $lang['pm_badname'] = 'Caractères invalides dans le nom de la page.'; $lang['pm_nochange'] = "Le nom du document et l'espace de nomage sont inchangés."; -$lang['pm_existing1'] = 'Un document appelé '; -$lang['pm_existing2'] = ' existe déjà dans '; +$lang['pm_existing'] = 'Un document appelé %s existe déjà dans %s'; $lang['pm_root'] = '[Espace de nom racine]'; $lang['pm_current'] = '(Courant)'; -$lang['pm_movedfrom'] = 'Document déplacé depuis '; -$lang['pm_movedto'] = 'Document déplacé vers '; -$lang['pm_norights'] = 'Vos permissions sont insufisante pour éditer un ou plusieurs liens pointant vers cette page.'; -$lang['pm_tryagain'] = 'Réessayez plus tard.'; -$lang['pm_filelocked'] = 'Ce fichier est verrouillé - '; -$lang['pm_fileslocked'] = 'Ces fichiers sont verrouillés - '; -$lang['pm_linkchange1'] = 'Les liens vers '; -$lang['pm_linkchange2'] = ' ont été changés vers '; +$lang['pm_norights'] = 'Vos permissions sont insufisante pour éditer %s.'; +$lang['pm_filelocked'] = 'Ce fichier est verrouillé - réessayez plus tard.'; +$lang['pm_linkchange'] = 'Les liens vers %s ont été changés vers %s'; $lang['pm_newname'] = 'Nouveau nom du document :'; $lang['pm_targetns'] = 'Sélectionnez le nouvel espace de nommage :'; -?> diff --git a/lang/fr/pagemove.txt b/lang/fr/pagemove.txt index e9306df..5e588bc 100644 --- a/lang/fr/pagemove.txt +++ b/lang/fr/pagemove.txt @@ -1,13 +1,10 @@ ====== Pagemove ====== Ce plugin permet de déplacer et/ou renommer le document courant, avec les limitations suivantes : - * Il est impossible de déplacer la page d'accueil (start) - * Il faut avoir les droits d'édition sur le document et sur chaque document qui pointe dessus (backlinks) - * Le document et les liens pointant dessus ne peuvent être verrouillés pour l'édition + * Il faut avoir les droits d'édition sur le document + * Le document ne peut être verrouillés pour l'édition * Pour déplacer une page il faut également disposer du droit de création dans le répertoire de destination * Il est impossible de déplacer le document vers un espace de nommage où un document du même nom existe déjà. Tous les liens depuis et vers la page seront mis à jour pour refléter le nouvel emplacement et/ou le nouveau nom. -\\ -\\ \ No newline at end of file diff --git a/lang/lv/lang.php b/lang/lv/lang.php index 5d4f6c5..b1f549f 100644 --- a/lang/lv/lang.php +++ b/lang/lv/lang.php @@ -15,25 +15,17 @@ $lang['menu'] = 'Lapas pārdēvēšana/pārvietošana...'; $lang['desc'] = 'Page Move/Rename Plugin'; -$lang['pm_notexist'] = 'This topic does not exist yet'; -$lang['pm_notstart'] = 'Ievadlapu nevar nedz pārdēvēt, nedz pārvietot'; +//$lang['pm_notexist'] = 'This topic does not exist yet'; $lang['pm_notwrite'] = 'Tev nav tiesību labot šo lapu'; $lang['pm_badns'] = 'Neatļautas rakstzīmes nodaļas vārdā.'; $lang['pm_badname'] = 'Neatļautas rakstzīmes lapas vārdā.'; $lang['pm_nochange'] = 'Vārds un nodaļa nav mainīti.'; -$lang['pm_existing1'] = 'Dokuments '; -$lang['pm_existing2'] = ' jau ir nodaļā '; +$lang['pm_existing1'] = 'Dokuments %s jau ir nodaļā %s'; $lang['pm_root'] = '[Saknes direktorija]'; $lang['pm_current'] = '(Tekošais)'; -$lang['pm_movedfrom'] = 'Dokuments pārvietots no '; -$lang['pm_movedto'] = 'Dokuments pārvietos uz '; -$lang['pm_norights'] = 'Tev nav tiesību labot kādu lapu, kas norāda uz šo dokumentu.'; -$lang['pm_tryagain'] = 'Mēģini vēlāk vēlreiz.'; -$lang['pm_filelocked'] = 'Bloķēts fails '; -$lang['pm_fileslocked'] = 'Bloķēti faili '; -$lang['pm_linkchange1'] = 'Norādes uz '; -$lang['pm_linkchange2'] = ' nomainītas ar '; +//$lang['pm_norights'] = 'Tev nav tiesību labot kādu lapu, kas norāda uz šo dokumentu.'; +$lang['pm_filelocked'] = 'Bloķēts fails - mēģini vēlāk vēlreiz.'; +$lang['pm_linkchange1'] = 'Norādes uz %s nomainītas ar %s'; $lang['pm_newname'] = 'Jaunais dokumenta vārds :'; $lang['pm_targetns'] = 'Nodaļa, kurp pārvietot :'; $lang['pm_submit'] = 'Darīt!'; -?> diff --git a/lang/lv/pagemove.txt b/lang/lv/pagemove.txt index 2507792..29cfc54 100644 --- a/lang/lv/pagemove.txt +++ b/lang/lv/pagemove.txt @@ -3,12 +3,9 @@ Šis modulis ļauj pārvietot un/vai pārdēvēt tekošo lapu. \\ Ar nosacījumiem: - * Nevar pārvietot ievadlapu. - * Tev vajag tiesības labot šo lapu un visas lapas, kas uz to norāda. - * Šī lapa un lapas, kas uz to norāda, nav bloķētas labošanai. + * You must have edit permission for the current page/all pages in the current namespace + * The pages that are moved must not be locked for editing. * Lai pārvietotu, tev vajag attiecīgās tiesības mērķa direktorijā. * Nevar pārvietot lapu uz nodaļu, kurā jau ir šāda nosaukuma lapa. Visas saites uz šo lapu un no tās tiks automātiski nomainītas atbilstoši jaunajam lapas nosaukumam un/vai vietai. -\\ -\\ \ No newline at end of file diff --git a/lang/nl/lang.php b/lang/nl/lang.php index f50471e..c917637 100644 --- a/lang/nl/lang.php +++ b/lang/nl/lang.php @@ -15,25 +15,17 @@ $lang['menu'] = 'Pagina Verplaatsen/Hernoemen...'; $lang['desc'] = 'Pagina Verplaatsen/Hernoemen Plugin'; -$lang['pm_notexist'] = 'Dit onderwerp bestaat nog niet'; -$lang['pm_notstart'] = 'De startpagina kan niet worden verplaatst of hernoemd'; +//$lang['pm_notexist'] = 'Dit onderwerp bestaat nog niet'; $lang['pm_notwrite'] = 'U heeft niet voldoende rechten om deze pagina te wijzigen'; $lang['pm_badns'] = 'De namespace bevat een niet-toegestaan teken.'; $lang['pm_badname'] = 'De paginanaam bevat een niet-toegestaan teken.'; $lang['pm_nochange'] = 'De paginanaam en -namespace zijn ongewijzigd.'; -$lang['pm_existing1'] = 'Het document met naam '; -$lang['pm_existing2'] = ' bestaat al in '; +$lang['pm_existing1'] = 'Het document met naam %s bestaat al in %s'; $lang['pm_root'] = '[Hoofdnamespace]'; $lang['pm_current'] = '(Huidig)'; -$lang['pm_movedfrom'] = 'Document verplaatst van '; -$lang['pm_movedto'] = 'Document verplaatst naar '; -$lang['pm_norights'] = 'U heeft niet voldoende rechten om een of meerdere referenties aan te passen.'; -$lang['pm_tryagain'] = 'Probeer later opnieuw.'; -$lang['pm_filelocked'] = 'Deze file is geblokkeerd - '; -$lang['pm_fileslocked'] = 'Deze files zijn geblokeerd - '; -$lang['pm_linkchange1'] = 'Gelinkt aan '; -$lang['pm_linkchange2'] = ' gewijzigd naar '; +//$lang['pm_norights'] = 'U heeft niet voldoende rechten om een of meerdere referenties aan te passen.'; +$lang['pm_filelocked'] = 'Deze file is geblokkeerd - probeer later opnieuw.'; +$lang['pm_linkchange1'] = 'Gelinkt aan %s gewijzigd naar %s'; $lang['pm_newname'] = 'Nieuwe naam document:'; $lang['pm_targetns'] = 'Selecteer namespace van het doel:'; -?> diff --git a/lang/nl/pagemove.txt b/lang/nl/pagemove.txt index 5184031..4b9cc43 100644 --- a/lang/nl/pagemove.txt +++ b/lang/nl/pagemove.txt @@ -1,8 +1,7 @@ ====== Pagina's verplaatsen ====== Deze plugin stelt je in staat pagina's te verplaatsen en/of te hernoemen binnen volgende beperkingen: - * Het is onmogelijk om de startpagina te verplaatsen - * Je moest toestemming hebben om wijzigingen aan te brengen aan al de documenten die verwijzen naar de te verplaatsen pagina (backlinks) + * You must have edit permission for the current page/all pages in the current namespace * De pagina en zijn referenties kunnen niet geblokkeerd worden tijdens het verplaatsen * Om pagina's te verplaatsen heb je ook schrijfrechten nodig in de folder van bestemming * Je kan een pagina niet plaatsen in een namespace waar al een pagina bestaat met dezelfde naam diff --git a/lang/pl/lang.php.txt b/lang/pl/lang.php similarity index 59% rename from lang/pl/lang.php.txt rename to lang/pl/lang.php index 436efce..c3c8213 100644 --- a/lang/pl/lang.php.txt +++ b/lang/pl/lang.php @@ -1,4 +1,3 @@ - - \ No newline at end of file diff --git a/lang/pl/pagemove.txt.txt b/lang/pl/pagemove.txt similarity index 61% rename from lang/pl/pagemove.txt.txt rename to lang/pl/pagemove.txt index 1c0c46e..73705f0 100644 --- a/lang/pl/pagemove.txt.txt +++ b/lang/pl/pagemove.txt @@ -2,12 +2,9 @@ Ta wtyczka umożliwia przeniesienie lub zmianę nazwy dokumentu z poniższymi zastrzeżeniami: - * Nie można przenieść strony start. - * Musisz mieć uprawnienia do tego dokumentu i tych które na niego wskazują (linki wsteczne). - * Dokument i jego wsteczne linki nie mogą być w trakcie edycji (założona blokada). + * You must have edit permission for the current page/all pages in the current namespace + * The pages that are moved must not be locked for editing. * Do utworzenia pliku niezbędne jest uprawnienie w docelowym katalogu. * Nie można przesunąć dokumentu do katalogu, w którym już jest dokument o tej samej nazwie. We wszystkich linkach z i do zmienianej strony będzie użyta nowa lokalizacja. -\\ -\\ diff --git a/lang/ru/lang.php b/lang/ru/lang.php index 3b76460..a9d4db1 100644 --- a/lang/ru/lang.php +++ b/lang/ru/lang.php @@ -15,25 +15,17 @@ $lang['menu'] = 'Перемещение/переименование страницы...'; $lang['desc'] = 'Page Move/Rename Plugin'; -$lang['pm_notexist'] = 'Эта страница еще не существует'; -$lang['pm_notstart'] = 'Недоступно для стартовой страницы'; +//$lang['pm_notexist'] = 'Эта страница еще не существует'; $lang['pm_notwrite'] = 'Ваши права доступа не позволяют Вам изменять эту страницу'; $lang['pm_badns'] = 'В названии пространства имён присутствуют недопустимые символы.'; $lang['pm_badname'] = 'Недопустимые символы в названии страниц.'; $lang['pm_nochange'] = 'Параметры страницы не изменены.'; -$lang['pm_existing1'] = 'Страница с именем '; -$lang['pm_existing2'] = ' уже существует в '; +$lang['pm_existing1'] = 'Страница с именем %s уже существует в %s'; $lang['pm_root'] = '[Корневой каталог]'; $lang['pm_current'] = '(Текущий)'; -$lang['pm_movedfrom'] = 'Документ перемещён из '; -$lang['pm_movedto'] = 'Документ перемещён в '; -$lang['pm_norights'] = 'У Вас нет прав на редактирование одной из страниц, ссылающихся на данный документ.'; -$lang['pm_tryagain'] = 'Попробуйте позже.'; -$lang['pm_filelocked'] = 'Изменение данного файла запрещено - '; -$lang['pm_fileslocked'] = 'Изменение данных файлов запрещено - '; -$lang['pm_linkchange1'] = 'Ссылки на страницу '; -$lang['pm_linkchange2'] = ' изменены на '; +//$lang['pm_norights'] = 'У Вас нет прав на редактирование одной из страниц, ссылающихся на данный документ.'; +$lang['pm_filelocked'] = 'Изменение данного файла запрещено - попробуйте позже.'; +$lang['pm_linkchange1'] = 'Ссылки на страницу %s изменены на %s'; $lang['pm_newname'] = 'Новое название документа :'; $lang['pm_targetns'] = 'Переместить в пространство :'; $lang['pm_submit'] = 'Применить'; -?> \ No newline at end of file diff --git a/lang/ru/pagemove.txt b/lang/ru/pagemove.txt index 9b9e50e..1fe7e17 100644 --- a/lang/ru/pagemove.txt +++ b/lang/ru/pagemove.txt @@ -2,12 +2,9 @@ Этот плагин позволяет перемещать и/или переименовывать текущую страницу со следующими ограничениями: - * Стартовая страница не может быть перемещена. - * Вы должны обладать правом редактировать эту страницу и все другие, ссылающиеся на неё. - * Текущая страница и ссылающиеся на неё не должны быть заблокированы для редактирования. + * You must have edit permission for the current page/all pages in the current namespace + * The pages that are moved must not be locked for editing. * Вы должны обладать соответствующими правами доступа в директории, куда Вы планируете переместить файл. * Вы не можете переместить страницу в пространство имён, уже содержащее страницу с таким же названием. Все ссылки, ведущие с этой страницы и на неё, будут обновлены в соответствии с внесёнными изменениями. -\\ -\\ diff --git a/lang/sl/lang.php b/lang/sl/lang.php index a55a701..b053228 100644 --- a/lang/sl/lang.php +++ b/lang/sl/lang.php @@ -15,25 +15,17 @@ $lang['menu'] = 'Premakni/preimenuj stran...'; $lang['desc'] = 'Plugin za premikanje/preimenovanje strani'; -$lang['pm_notexist'] = 'Ta stran še ne obstaja'; -$lang['pm_notstart'] = 'Začetne strani ne morete premakniti/preimenovati'; +//$lang['pm_notexist'] = 'Ta stran še ne obstaja'; $lang['pm_notwrite'] = 'Nimate zadostnih pravic za urejanje te strani'; $lang['pm_badns'] = 'Neveljavni znaki v imenskem prostoru.'; $lang['pm_badname'] = 'Neveljavni znaki v imenu strani.'; $lang['pm_nochange'] = 'Ime dokumenta in imenski prostor sta nespremenjena.'; -$lang['pm_existing1'] = 'Dokument imenovan '; -$lang['pm_existing2'] = ' že obstaja v '; +$lang['pm_existing1'] = 'Dokument imenovan %s že obstaja v %s'; $lang['pm_root'] = '[Korenski imenski prostor/Root namespace]'; $lang['pm_current'] = '(Trenutno)'; -$lang['pm_movedfrom'] = 'Dokument premaknjen iz '; -$lang['pm_movedto'] = 'Dokument premaknjen na '; -$lang['pm_norights'] = 'Nimate zadostnih pravic za urejanje enega ali več backlinkov za ta dokument.'; -$lang['pm_tryagain'] = 'Poskusite ponovno kasneje.'; -$lang['pm_filelocked'] = 'Ta datoteka je zaklenjena - '; -$lang['pm_fileslocked'] = 'Te datoteke so zaklenjene - '; -$lang['pm_linkchange1'] = 'Kaže na '; -$lang['pm_linkchange2'] = ' spremenjeno na '; +//$lang['pm_norights'] = 'Nimate zadostnih pravic za urejanje enega ali več backlinkov za ta dokument.'; +$lang['pm_filelocked'] = 'Ta datoteka je zaklenjena - poskusite ponovno kasneje.'; +$lang['pm_linkchange1'] = 'Kaže na %s spremenjeno na %s'; $lang['pm_newname'] = 'Novo ime dokumenta :'; $lang['pm_targetns'] = 'Izberite ciljni imenski prostor :'; $lang['pm_submit'] = 'Potrdi'; -?> diff --git a/lang/sl/pagemove.txt b/lang/sl/pagemove.txt index 3aea1d6..c466208 100644 --- a/lang/sl/pagemove.txt +++ b/lang/sl/pagemove.txt @@ -2,12 +2,9 @@ Ta plugin omogoča premikanje in/ali preimenovanje trenutnega dokumenta v okviru naslednjih omejitev: - * Začetne strani ne morete premakniti. - * Morate imeti pravico do urejanja dokumenta in vseh dokumentov, ki kažejo na ta dokument (backlinki). - * Dokument in njegovi backlinki ne smejo biti zaklenjeni za urejanje. + * You must have edit permission for the current page/all pages in the current namespace + * The pages that are moved must not be locked for editing. * Za premikanje datoteke potrebujete pravico za ustvarjanje v ciljni mapi. * Ne morete premakniti dokumenta v imenski prostor, kjer dokument z istim imenom že obstaja. Vsi linki na in z strani bodo posodobljeni, da bodo kazali na novo lokacijo in/ali ime. -\\ -\\ \ No newline at end of file diff --git a/lang/zh/lang.php b/lang/zh/lang.php index cf4b887..6e481eb 100644 --- a/lang/zh/lang.php +++ b/lang/zh/lang.php @@ -15,25 +15,17 @@ $lang['menu'] = '页面移动/重命名……'; $lang['desc'] = '页面移动/重命名插件'; -$lang['pm_notexist'] = '这个主题还不存在'; -$lang['pm_notstart'] = '不能移动或重命名起始页面'; +//$lang['pm_notexist'] = '这个主题还不存在'; $lang['pm_notwrite'] = '您无权修改这个页面'; $lang['pm_badns'] = '分类名中存在无效字符'; $lang['pm_badname'] = '页面名中存在无效字符'; $lang['pm_nochange'] = '不能更改文件名和分类名'; -$lang['pm_existing1'] = '文件 '; -$lang['pm_existing2'] = ' 已经存在于 '; +$lang['pm_existing1'] = '文件 %s 已经存在于 %s'; $lang['pm_root'] = '[跟目录]'; $lang['pm_current'] = '(当前)'; -$lang['pm_movedfrom'] = '文件移动自 '; -$lang['pm_movedto'] = '文件移动至 '; -$lang['pm_norights'] = '您无权编辑此文件的 backlinks'; -$lang['pm_tryagain'] = '请稍后重试'; -$lang['pm_filelocked'] = '此文件被锁定 - '; -$lang['pm_fileslocked'] = '这些文件被锁定 - '; -$lang['pm_linkchange1'] = '链接到 '; -$lang['pm_linkchange2'] = ' 更改到 '; +//$lang['pm_norights'] = '您无权编辑此文件的 backlinks'; +$lang['pm_filelocked'] = '此文件被锁定 - 请稍后重试'; +$lang['pm_linkchange1'] = '链接到 %s 更改到 %s'; $lang['pm_newname'] = '新的文件名 :'; $lang['pm_targetns'] = '选择目标分类 :'; $lang['pm_submit'] = '提交'; -?> \ No newline at end of file diff --git a/lang/zh/pagemove.txt b/lang/zh/pagemove.txt deleted file mode 100644 index fcaab5c..0000000 --- a/lang/zh/pagemove.txt +++ /dev/null @@ -1,14 +0,0 @@ -
====== Pagemove ====== - -ƶǰļע⣺ - - * ޷ƶʼҳ档 - * ༭ӵҳļbacklinksȨޡ - * ļ backlinks ֹ༭ - * ҪƶһļҪĿĿ¼Ȩޡ - * ܽļƶһѾӵͬļĿ¼¡ - -ָҳҳӽԶ¡ -\\ -\\ -
\ No newline at end of file From 50d5c595dcc2861139e9c166c331296d6d789e54 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 25 Jan 2013 21:29:33 +0100 Subject: [PATCH 026/338] Update indexer code, use core code if possible The indexer page/meta key rename code will be merged in DokuWiki and thus part of the spring 2013 release. If possible this code is used by the plugin. If this is not possible a copy of exactly this code is used. --- helper.php | 70 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/helper.php b/helper.php index 176098d..56da3a9 100644 --- a/helper.php +++ b/helper.php @@ -145,8 +145,13 @@ public function move_page(&$opts, $checkonly = false) { $oldRev = getRevisions($ID, -1, 1, 1024); // from changelog // Move the Subscriptions & Indexes - $Indexer = new helper_plugin_pagemove_indexer(); - if (($idx_msg = $Indexer->renamePage($ID, $opts['new_id'])) !== true) { + 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->renamePage($ID, $opts['new_id'])) !== true + || ($idx_msg = $Indexer->renameMetaValue('relation_references', $ID, $opts['new_id'])) !== true) { msg('Error while updating the search index '.$idx_msg, -1); return false; } @@ -390,7 +395,7 @@ protected function resolve_moves($moves, $id) { } /** - * Indexer class extended by pagemove features + * Indexer class extended by pagemove features, only needed and used in releases older than Spring 2013 */ class helper_plugin_pagemove_indexer extends Doku_Indexer { /** @@ -429,48 +434,58 @@ public function renamePage($oldpage, $newpage) { return false; } - if (isset($this->pidCache)) - $this->pidCache = array(); - - unset($pages); + $this->unlock(); + return true; + } + /** + * Renames a meta value in the index. This doesn't change the meta value in the pages, it assumes that all pages + * will be updated. + * + * @param string $key The metadata key of which a value shall be changed + * @param string $oldvalue The old value that shall be renamed + * @param string $newvalue The new value to which the old value shall be renamed, can exist (then values will be merged) + * @return bool|string If renaming the value has been successful, false or error message on error. + */ + public function renameMetaValue($key, $oldvalue, $newvalue) { + if (!$this->lock()) return 'locked'; // change the relation references index - $linktargets = $this->getIndex('relation_references', '_w'); - $linktargetid = array_search($oldpage, $linktargets); - if ($linktargetid !== false) { - $newlinktargetid = array_search($newpage, $linktargets); - if ($newlinktargetid !== false) { + $metavalues = $this->getIndex($key, '_w'); + $oldid = array_search($oldvalue, $metavalues); + if ($oldid !== false) { + $newid = array_search($newvalue, $metavalues); + if ($newid !== false) { // free memory - unset ($linktargets); + unset ($metavalues); - // okay, now we have two entries for the same page. we need to merge them. - $indexline = $this->getIndexKey('relation_references', '_i', $linktargetid); + // okay, now we have two entries for the same value. we need to merge them. + $indexline = $this->getIndexKey($key, '_i', $oldid); if ($indexline != '') { - $newindexline = $this->getIndexKey('relation_references', '_i', $newlinktargetid); - $pagekeys = $this->getIndex('relation_references', '_p'); + $newindexline = $this->getIndexKey($key, '_i', $newid); + $pagekeys = $this->getIndex($key, '_p'); $parts = explode(':', $indexline); foreach ($parts as $part) { list($id, $count) = explode('*', $part); $newindexline = $this->updateTuple($newindexline, $id, $count); $keyline = explode(':', $pagekeys[$id]); - // remove old link target - $keyline = array_diff($keyline, array($linktargetid)); - // add new link target when not already present - if (!in_array($newlinktargetid, $keyline)) { - array_push($keyline, $newlinktargetid); + // remove old meta value + $keyline = array_diff($keyline, array($oldid)); + // add new meta value when not already present + if (!in_array($newid, $keyline)) { + array_push($keyline, $newid); } $pagekeys[$id] = implode(':', $keyline); } - $this->saveIndex('relation_references', '_p', $pagekeys); + $this->saveIndex($key, '_p', $pagekeys); unset($pagekeys); - $this->saveIndexKey('relation_references', '_i', $linktargetid, ''); - $this->saveIndexKey('relation_references', '_i', $newlinktargetid, $newindexline); + $this->saveIndexKey($key, '_i', $oldid, ''); + $this->saveIndexKey($key, '_i', $newid, $newindexline); } } else { - $linktargets[$linktargetid] = $newpage; - if (!$this->saveIndex('relation_references', '_w', $linktargets)) { + $metavalues[$oldid] = $newvalue; + if (!$this->saveIndex($key, '_w', $metavalues)) { $this->unlock(); return false; } @@ -480,7 +495,6 @@ public function renamePage($oldpage, $newpage) { $this->unlock(); return true; } - } /** From b4f6d8fdd2906ad8a9f941b4e3dbfebd934207b1 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 29 Mar 2013 18:22:55 +0100 Subject: [PATCH 027/338] Add media reference adaption support for images inside other links --- _test/mediamove.test.php | 36 ++++++++++++++++++++++++++++++++++++ helper.php | 31 +++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 _test/mediamove.test.php diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php new file mode 100644 index 0000000..1d044f3 --- /dev/null +++ b/_test/mediamove.test.php @@ -0,0 +1,36 @@ +pluginsEnabled[] = 'pagemove'; + parent::setUp(); + } + + public function test_movePageWithRelativeMedia() { + global $ID; + + $ID = 'mediareltest:foo'; + saveWikiText($ID, + '{{ myimage.png}} [[:start|{{ testimage.png?200x800 }}]] [[bar|{{testimage.gif?400x200}}]] +[[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{testimage.jpg}}]] +[[doku>wiki:foo|{{foo.gif?200x3000}}]]', 'Test setup'); + idx_addPage($ID); + + $opts = array(); + $opts['ns'] = getNS($ID); + $opts['name'] = noNS($ID); + $opts['newns'] = ''; + $opts['newname'] = 'foo'; + /** @var helper_plugin_pagemove $pagemove */ + $pagemove = plugin_load('helper', 'pagemove'); + $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')); + } +} diff --git a/helper.php b/helper.php index 56da3a9..a9960ca 100644 --- a/helper.php +++ b/helper.php @@ -583,6 +583,14 @@ public function internallink($match, $state, $pos) { $link = explode('|',$link,2); if ( !isset($link[1]) ) { $link[1] = NULL; + } else if ( preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) { + // If the title is an image, rewrite it + $old_title = $link[1]; + $link[1] = $this->rewrite_media($link[1]); + // do a simple replace of the first match so really only the id is changed and not e.g. the alignment + $oldpos = strpos($match, $old_title); + $oldlen = strlen($old_title); + $match = substr_replace($match, $link[1], $oldpos, $oldlen); } $link[0] = trim($link[0]); @@ -657,21 +665,28 @@ public function internallink($match, $state, $pos) { * @return bool If parsing should be continued */ public function media($match, $state, $pos) { + $this->calls .= $this->rewrite_media($match); + return true; + } + + /** + * Rewrite a media syntax + * + * @param string $match The text match of the media syntax + * @return string The rewritten syntax + */ + protected function rewrite_media($match) { $p = Doku_Handler_Parse_Media($match); - if ($p['type'] == 'internalmedia') { + if ($p['type'] == 'internalmedia') { // else: external media $new_src = $this->adaptRelativeId($p['src']); - if ($new_src == $p['src']) { - $this->calls .= $match; - } else { + if ($new_src !== $p['src']) { // do a simple replace of the first match so really only the id is changed and not e.g. the alignment $srcpos = strpos($match, $p['src']); $srclen = strlen($p['src']); - $this->calls .= substr_replace($match, $new_src, $srcpos, $srclen); + return substr_replace($match, $new_src, $srcpos, $srclen); } - } else { // external media - $this->calls .= $match; } - return true; + return $match; } /** From 38b4334a2360e51c9eb73f6eaba107bffc9db812 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 29 Mar 2013 23:55:31 +0100 Subject: [PATCH 028/338] Add index for media usage (will be used for media moves later) --- _test/mediaindex.test.php | 46 +++++++++++++++++++++++++++++ action.php | 61 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 _test/mediaindex.test.php diff --git a/_test/mediaindex.test.php b/_test/mediaindex.test.php new file mode 100644 index 0000000..eded7bb --- /dev/null +++ b/_test/mediaindex.test.php @@ -0,0 +1,46 @@ + + */ +class plugin_pagemove_mediaindex_test extends DokuWikiTest { + + public function setUp() { + $this->pluginsEnabled[] = 'pagemove'; + parent::setUp(); + } + + public function test_internalmedia() { + saveWikiText('test:internalmedia_usage', '{{internalmedia.png}} {{..:internal media.png}}', 'Test initialization'); + idx_addPage('test:internalmedia_usage'); + + $query = array('test:internalmedia.png', 'internal_media.png'); + $this->assertEquals( array( + 'test:internalmedia.png' => array('test:internalmedia_usage'), + 'internal_media.png' => array('test:internalmedia_usage') + ), idx_get_indexer()->lookupKey('pagemove_media', $query)); + } + + public function test_media_in_links() { + saveWikiText('test:medialinks', '[[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{example.png?200x800}}]]', 'Test init'); + idx_addPage('test:medialinks'); + + $query = array('wiki:logo.png', 'test:example.png'); + $this->assertEquals(array( + 'wiki:logo.png' => array('test:medialinks'), + 'test:example.png' => array('test:medialinks') + ), idx_get_indexer()->lookupKey('pagemove_media', $query)); + } + + public function test_media_in_footnotes() { + saveWikiText('test:media_footnotes', '(({{footnote.png?20x50}} [[foonote|{{:footlink.png}}]]))', 'Test initialization'); + idx_addPage('test:media_footnotes'); + + $query = array('test:footnote.png', 'footlink.png'); + $this->assertEquals(array( + 'test:footnote.png' => array('test:media_footnotes'), + 'footlink.png' => array('test:media_footnotes') + ), idx_get_indexer()->lookupKey('pagemove_media', $query)); + } +} diff --git a/action.php b/action.php index 2071697..ebd7587 100644 --- a/action.php +++ b/action.php @@ -20,6 +20,8 @@ class action_plugin_pagemove extends DokuWiki_Action_Plugin { public function register($controller) { $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_read', array()); $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache', array()); + $controller->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, 'handle_index_version'); + $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'index_media_use'); } /** @@ -90,4 +92,63 @@ function handle_cache(Doku_Event $event, $param) { } } } + + /** + * Add the pagemove version to theindex version + * + * @param Doku_Event $event The event object + * @param array $param Optional parameters (unused) + */ + public function handle_index_version(Doku_Event $event, $param) { + $event->data['plugin_pagemove'] = 0.1; + } + + /** + * Index media usage data + * + * @param Doku_Event $event The event object + * @param array $param Optional parameters (unused) + */ + public function index_media_use(Doku_Event $event, $param) { + $id = $event->data['page']; + $media_references = array(); + $instructions = p_cached_instructions(wikiFn($id), false, $id); + if (is_array($instructions)) { + $this->get_media_references_from_instructions($instructions, $media_references, $id); + } + $media_references = array_unique($media_references); + $event->data['metadata']['pagemove_media'] = $media_references; + } + + /** + * Helper function for getting all media references from an instruction array + * + * @param array $instructions The instructions to scan + * @param array $media_references The array of media references + * @param string $id The reference id for resolving media ids + */ + private function get_media_references_from_instructions($instructions, &$media_references, $id) { + foreach ($instructions as $ins) { + if ($ins[0] === 'internalmedia') { + $src = $ins[1][0]; + list($src,$hash) = explode('#',$src,2); + resolve_mediaid(getNS($id),$src, $exists); + $media_references[] = $src; + } elseif (in_array($ins[0], array('interwikilink', 'windowssharelink', 'externallink', 'emaillink', 'locallink', 'internallink'))) { + $img = $ins[1][1]; + if (is_array($img) && $img['type'] === 'internalmedia') { + list($src,$hash) = explode('#',$img['src'],2); + resolve_mediaid(getNS($id), $src, $exists); + $media_references[] = $src; + } + } elseif ($ins[0] === 'nest') { + // nested instructions + $this->get_media_references_from_instructions($ins[1][0], $media_references, $id); + } elseif ($ins[0] === 'plugin' && $ins[1][0] === 'variants_variants') { + // the variants plugin has two branches with nested instructions, both need to be rewritten + $this->get_media_references_from_instructions($ins[1][1][1], $media_references, $id); + $this->get_media_references_from_instructions($ins[1][1][2], $media_references, $id); + } + } + } } \ No newline at end of file From 654addc0610b25501cc31cb3931d35773ee0af5c Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 30 Mar 2013 11:31:45 +0100 Subject: [PATCH 029/338] Add missing check if the file is run from inside DokuWiki --- _test/mediaindex.test.php | 4 ++++ _test/mediamove.test.php | 3 +++ _test/pagemove.test.php | 3 +++ 3 files changed, 10 insertions(+) diff --git a/_test/mediaindex.test.php b/_test/mediaindex.test.php index eded7bb..2563ba6 100644 --- a/_test/mediaindex.test.php +++ b/_test/mediaindex.test.php @@ -1,4 +1,8 @@ Date: Sat, 30 Mar 2013 12:36:17 +0100 Subject: [PATCH 030/338] Implement single media file moving (currently only in the helper) The media link correction code is still missing --- _test/mediamove.test.php | 26 ++++++- helper.php | 147 ++++++++++++++++++++++++++++++++++++++- lang/en/lang.php | 7 +- 3 files changed, 177 insertions(+), 3 deletions(-) diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index d0be785..1612eba 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -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'); + } } diff --git a/helper.php b/helper.php index a9960ca..46c7044 100644 --- a/helper.php +++ b/helper.php @@ -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 @@ -209,6 +209,149 @@ public function move_page(&$opts, $checkonly = false) { return true; } + /** + * Move media file + * + * @author Michael Hamann + * + * @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. * @@ -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) { diff --git a/lang/en/lang.php b/lang/en/lang.php index 235e13d..73f1375 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -16,11 +16,14 @@ $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'; @@ -28,7 +31,9 @@ $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 From e1bff2ebebd3d24262b18925df77e09319809598 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 30 Mar 2013 12:54:38 +0100 Subject: [PATCH 031/338] Add media link adaption support for media moves --- _test/mediamove.test.php | 2 +- action.php | 2 +- helper.php | 45 +++++++++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index 1612eba..d7f099d 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -58,6 +58,6 @@ public function test_moveSingleMedia() { $this->assertTrue(@file_exists(mediaFn('foobar:logo.png'))); - //$this->assertEquals('{{foobar:logo.png?200}}', 'wiki:movetest'); + $this->assertEquals('{{foobar:logo.png?200}}', rawWiki('wiki:movetest')); } } diff --git a/action.php b/action.php index ebd7587..3033301 100644 --- a/action.php +++ b/action.php @@ -83,7 +83,7 @@ function handle_cache(Doku_Event $event, $param) { } if ($id) { $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); - if ($meta && isset($meta['moves'])) { + if ($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { $file = wikiFN($id, '', false); if (is_writable($file)) $cache->depends['purge'] = true; diff --git a/helper.php b/helper.php index 46c7044..17a8d78 100644 --- a/helper.php +++ b/helper.php @@ -324,11 +324,17 @@ public function movemediaattic($opts) { global $conf; $ext = mimetype($opts['name']); - if ($ext[0] !== false) + if ($ext[0] !== false) { $name = substr($opts['name'],0, -1*strlen($ext[0])-1); + } else { + $name = $opts['name']; + } $newext = mimetype($opts['newname']); - if ($ext[0] !== false) + if ($ext[0] !== false) { $newname = substr($opts['newname'],0, -1*strlen($ext[0])-1); + } else { + $newname = $opts['newname']; + } $regex = '\.\d+\.'.preg_quote((string)$ext[0], '/'); return $this->move_files($conf['mediaolddir'], array( @@ -430,11 +436,13 @@ private function move_files($dir, $opts, $extregex) { */ public function execute_rewrites($id, $text = null) { $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); - if($meta && isset($meta['moves'])) { + if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { if(is_null($text)) $text = rawWiki($id); + $moves = isset($meta['moves']) ? $meta['moves'] : array(); + $media_moves = isset($meta['media_moves']) ? $meta['media_moves'] : array(); $old_text = $text; - $text = $this->rewrite_content($text, $id, $meta['moves']); + $text = $this->rewrite_content($text, $id, $moves, $media_moves); $changed = ($old_text != $text); $file = wikiFN($id, '', false); if(is_writable($file) || !$changed) { @@ -445,6 +453,7 @@ public function execute_rewrites($id, $text = null) { saveWikiText($id, $text, $this->getLang('pm_linkchange')); } unset($meta['moves']); + unset($meta['media_moves']); p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); } else { // FIXME: print error here or fail silently? msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); @@ -459,11 +468,13 @@ public function execute_rewrites($id, $text = null) { * * @param string $text The wiki text that shall be rewritten * @param string $id The id of the wiki page, if the page itself was moved the old id - * @param array $moves Array of all moves, the keys are the old ids, the values the new ids + * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids + * @param array $media_moves Array of all media moves. * @return string The rewritten wiki text */ - function rewrite_content($text, $id, $moves) { + function rewrite_content($text, $id, $moves, $media_moves = array()) { $moves = $this->resolve_moves($moves, $id); + $media_moves = $this->resolve_moves($media_moves, $id); $handlers = array(); $data = array('id' => $id, 'moves' => &$moves, 'handlers' => &$handlers); @@ -490,7 +501,7 @@ function rewrite_content($text, $id, $moves) { $Parser = new Doku_Parser(); // Add the Handler - $Parser->Handler = new helper_plugin_pagemove_handler($id, $moves, $handlers); + $Parser->Handler = new helper_plugin_pagemove_handler($id, $moves, $media_moves, $handlers); //add modes to parser foreach($modes as $mode) { @@ -652,19 +663,22 @@ class helper_plugin_pagemove_handler { public $new_id; public $new_ns; public $moves; + public $media_moves; private $handlers; /** * Construct the pagemove handler. * * @param string $id The id of the text that is passed to the handler - * @param array $moves Moves that shall be considered in the form $old => $new ($old can be $id) - * @param array $handlers Handlers for plugin content in the form $plugin_anme => $callback + * @param array $moves Moves that shall be considered in the form $old => $new ($old can be $id) + * @param array $media_moves Moves of media files that shall be considered in the form $old => $new + * @param array $handlers Handlers for plugin content in the form $plugin_anme => $callback */ - public function __construct($id, $moves, $handlers) { + public function __construct($id, $moves, $media_moves, $handlers) { $this->id = $id; $this->ns = getNS($id); $this->moves = $moves; + $this->media_moves = $media_moves; $this->handlers = $handlers; if (isset($moves[$id])) { $this->new_id = $moves[$id]; @@ -823,7 +837,7 @@ public function media($match, $state, $pos) { protected function rewrite_media($match) { $p = Doku_Handler_Parse_Media($match); if ($p['type'] == 'internalmedia') { // else: external media - $new_src = $this->adaptRelativeId($p['src']); + $new_src = $this->adaptRelativeId($p['src'], true); if ($new_src !== $p['src']) { // do a simple replace of the first match so really only the id is changed and not e.g. the alignment $srcpos = strpos($match, $p['src']); @@ -878,9 +892,10 @@ public function _finalize() { * Adapts a link respecting all moves and making it a relative link according to the new id * * @param string $id A relative id + * @param bool $media If the id is a media id * @return string The relative id, adapted according to the new/old id and the moves */ - public function adaptRelativeId($id) { + public function adaptRelativeId($id, $media = false) { global $conf; if ($id === '') { @@ -898,9 +913,11 @@ public function adaptRelativeId($id) { if (substr($clean_id, -1) === ':') $clean_id .= $conf['start']; - if (isset($this->moves[$clean_id]) || $this->ns !== $this->new_ns) { - if (isset($this->moves[$clean_id])) { + if (($media ? isset($this->media_moves[$clean_id]) : isset($this->moves[$clean_id])) || $this->ns !== $this->new_ns) { + if (!$media && isset($this->moves[$clean_id])) { $new = $this->moves[$clean_id]; + } elseif ($media && isset($this->media_moves[$clean_id])) { + $new = $this->media_moves[$clean_id]; } else { $new = $clean_id; From dbd73195a969b428df7d3b8470fc4f225f193326 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 30 Mar 2013 23:22:31 +0100 Subject: [PATCH 032/338] Add new namespace move functionality including ajax Namespace moves are now split into junks of at maximum 10 pages --- _test/namespace_move.test.php | 40 +++++++ action.php | 68 ++++++++++++ admin.php | 146 ++++++++++++++++++++---- helper.php | 202 ++++++++++++++++++++++++++++++++++ lang/en/lang.php | 9 ++ script.js | 58 +++++++++- 6 files changed, 498 insertions(+), 25 deletions(-) create mode 100644 _test/namespace_move.test.php diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php new file mode 100644 index 0000000..d6d51d1 --- /dev/null +++ b/_test/namespace_move.test.php @@ -0,0 +1,40 @@ +pluginsEnabled[] = 'pagemove'; + parent::setUp(); + } + + public function test_move_wiki_namespace() { + global $AUTH_ACL; + + $AUTH_ACL[] = "wiki:*\t@ALL\t16"; + + idx_addPage('wiki:dokuwiki'); + idx_addPage('wiki:syntax'); + + /** @var helper_plugin_pagemove $pagemove */ + $pagemove = plugin_load('helper', 'pagemove'); + $opts = array( + 'ns' => 'wiki', + 'newns' => 'foo', + 'media' => true + ); + + $this->assertSame(3, $pagemove->start_namespace_move($opts)); + $this->assertSame(1, $pagemove->continue_namespace_move()); + $this->assertSame(0, $pagemove->continue_namespace_move()); + + $this->assertFileExists(wikiFN('foo:dokuwiki')); + $this->assertFileNotExists(wikiFN('wiki:syntax')); + $this->assertFileExists(mediaFN('foo:dokuwiki-128.png')); + } +} diff --git a/action.php b/action.php index 3033301..09ae870 100644 --- a/action.php +++ b/action.php @@ -22,6 +22,7 @@ public function register($controller) { $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache', array()); $controller->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, 'handle_index_version'); $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'index_media_use'); + $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call'); } /** @@ -151,4 +152,71 @@ private function get_media_references_from_instructions($instructions, &$media_r } } } + + /** + * Handle the plugin_pagemove_ns_continue ajax call + * + * @param Doku_Event $event The event that is handled + * @param array $params Optional parameters (unused) + */ + public function handle_ajax_call(Doku_Event $event, $params) { + if ($event->data == 'plugin_pagemove_ns_continue') { + $event->preventDefault(); + $event->stopPropagation(); + + /** @var helper_plugin_pagemove $helper */ + $helper = $this->loadHelper('pagemove', false); + $opts = $helper->get_namespace_move_opts(); + $id = cleanID((string)$_POST['id']); + $skip = (int)$_POST['skip']; + if ($opts !== false) { + if ($skip) { + $helper->skip_namespace_move_item(); + } + $remaining = $helper->continue_namespace_move(); + $newid = $helper->getNewID($id, $opts['ns'], $opts['newns']); + + $result = array(); + $result['remaining'] = $remaining; + $result['pages'] = $opts['num_pages']; + $result['media'] = $opts['num_media']; + $result['redirect_url'] = wl($newid, '', true); + ob_start(); + html_msgarea(); + if ($remaining === false) { + $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $id); + $form->addHidden('continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_tryagain'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $id); + $form->addHidden('abort_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nsskip')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $id); + $form->addHidden('skip_continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_skip'))); + $form->printForm(); + ptln('

'.sprintf($this->getLang('pm_ns_move_error'), $opts['ns'], $opts['newns']).'

'); + } else { + ptln('

'.sprintf($this->getLang('pm_ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

'); + } + $result['html'] = ob_get_clean(); + } else { + $result = array(); + $result['remaining'] = 0; + $result['pages'] = 0; + $result['media'] = 0; + $result['redirect_url'] = wl('', '', true); + $result['html'] = ''; + } + $json = new JSON(); + echo $json->encode($result); + } + } } \ No newline at end of file diff --git a/admin.php b/admin.php index 07b41bd..f6a723e 100644 --- a/admin.php +++ b/admin.php @@ -16,6 +16,7 @@ class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { var $opts = array(); + private $ns_opts = false; /** * Get the sort number that defines the position in the admin menu. @@ -62,9 +63,71 @@ function getMenuText() { * @author Gary Owen */ function html() { + global $ID; ptln(''); ptln( $this->locale_xhtml('pagemove') ); - $this->printForm(); + ptln('
'); + if ($this->ns_opts !== false && isset($this->ns_opts['started'])) { + ptln('

'); + ptln(sprintf($this->getLang('pm_ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); + ptln('

'); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('abort_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + $form->printForm(); + } elseif ($this->ns_opts !== false && isset($this->ns_opts['remaining'])) { + if ($this->ns_opts['remaining'] === false) { + ptln('

'); + ptln(sprintf($this->getLang('pm_ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); + ptln('

'); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_tryagain'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('abort_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('skip_continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_skip'))); + $form->printForm(); + } else { + ptln('

'); + ptln(sprintf($this->getLang('pm_ns_move_continued'), $this->ns_opts['ns'], $this->ns_opts['newns'], $this->ns_opts['remaining'])); + ptln('

'); + + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('abort_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + $form->printForm(); + } + } else { + $this->printForm(); + } + ptln('
'); ptln(''); } @@ -93,16 +156,39 @@ function printForm() { $form->endFieldset(); $form->printForm(); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('move_type', 'namespace'); - $form->startFieldset($this->getLang('pm_movens')); - $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('pm_targetns'), '', 'block')); - $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('pm_newnsname'), '', 'block')); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); - $form->endFieldset(); - $form->printForm(); + if ($this->ns_opts !== false && !isset($this->ns_opts['remaining'])) { + ptln('
'); + ptln(''); + ptln($this->getLang('pm_movens')); + ptln(''); + ptln('

'); + ptln(sprintf($this->getLang('pm_ns_move_in_progress'), $this->ns_opts['num_pages'], $this->ns_opts['num_media'], ':'.hsc($this->ns_opts['ns']), ':'.hsc($this->ns_opts['newns']))); + ptln('

'); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); + $form->printForm(); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('abort_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + $form->printForm(); + ptln('
'); + } else { + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $ID); + $form->addHidden('move_type', 'namespace'); + $form->startFieldset($this->getLang('pm_movens')); + $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('pm_targetns'), '', 'block')); + $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('pm_newnsname'), '', 'block')); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); + $form->endFieldset(); + $form->printForm(); + } } @@ -153,11 +239,35 @@ function handle() { $this->opts['newnsname'] = ''; $this->opts['move_type'] = 'page'; + /** @var helper_plugin_pagemove $helper */ + $helper = $this->loadHelper('pagemove', true); + if (!$helper) return; + + $this->ns_opts = $helper->get_namespace_move_opts(); + // Only continue when the form was submitted if ($_SERVER['REQUEST_METHOD'] != 'POST') { return; } + if (isset($_POST['continue_namespace_move']) || isset($_POST['skip_continue_namespace_move'])) { + if (isset($_POST['skip_continue_namespace_move'])) { + $helper->skip_namespace_move_item(); + } + $this->ns_opts['remaining'] = $helper->continue_namespace_move(); + if ($this->ns_opts['remaining'] === 0) { + $ID = $helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); + $ACT = 'show'; + } + + return; + } elseif (isset($_POST['abort_namespace_move'])) { + $helper->abort_namespace_move(); + $this->ns_opts = false; + + return; + } + // Store the form data in the options and clean the submitted data. if (isset($_POST['ns_for_page'])) $this->opts['ns_for_page'] = cleanID((string)$_POST['ns_for_page']); if (isset($_POST['newns'])) $this->opts['newns'] = cleanID((string)$_POST['newns']); @@ -166,22 +276,20 @@ function handle() { if (isset($_POST['newnsname'])) $this->opts['newnsname'] = cleanID((string)$_POST['newnsname']); if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; - /** @var helper_plugin_pagemove $helper */ - $helper = $this->loadHelper('pagemove', true); - if (!$helper) return; - // check the input for completeness if( $this->opts['move_type'] == 'namespace' ) { + $this->opts['media'] = true; // FIXME: add checkbox later! + if ($this->opts['targetns'] == '') { $this->opts['newns'] = $this->opts['newnsname']; } else { $this->opts['newns'] = $this->opts['targetns'].':'.$this->opts['newnsname']; } - if ($helper->move_namespace($this->opts, true) && - $helper->move_namespace($this->opts)) { - $ID = $helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); - $ACT = 'show'; + $started = $helper->start_namespace_move($this->opts); + if ($started !== false) { + $this->ns_opts = $helper->get_namespace_move_opts(); + $this->ns_opts['started'] = $started; } } else { // check that the pagename is valid diff --git a/helper.php b/helper.php index 17a8d78..8fe8e15 100644 --- a/helper.php +++ b/helper.php @@ -44,6 +44,208 @@ function move_namespace(&$opts, $checkonly = false) { return true; } + /** + * Start a namespace move by creating the list of all pages and media files that shall be moved + * + * @param array $opts The options for the namespace move + * @return int The number of items to move + */ + public function start_namespace_move(&$opts) { + global $conf; + + // generate and save a list of all pages + $pagelist = array(); + $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); + $searchOpts = array('depth' => 0, 'skipacl' => true); + search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); + $pages = array(); + foreach ($pagelist as $page) { + $pages[] = $page['id']; + } + unset($pagelist); + + $opts['num_pages'] = count($pages); + + $files = $this->get_namespace_meta_files(); + io_saveFile($files['pagelist'], implode("\n", $pages)); + unset($pages); + + // generate and save a list of all media files + $medialist = array(); + if (isset($opts['media']) && $opts['media']) { + search($medialist, $conf['mediadir'], 'search_media', $searchOpts, $pathToSearch); + } + + $media_files = array(); + foreach ($medialist as $media) { + $media_files[] = $media['id']; + } + unset ($medialist); + + $opts['num_media'] = count($media_files); + + io_saveFile($files['medialist'], implode("\n", $media_files)); + + // save the options + io_saveFile($files['opts'], serialize($opts)); + + return $opts['num_pages'] + $opts['num_media']; + } + + /** + * Execute the next steps (moving up to 10 pages or media files) of the currently running namespace move + * + * @return bool|int False if an error occurred, otherwise the number of remaining moves + */ + public function continue_namespace_move() { + global $ID; + $files = $this->get_namespace_meta_files(); + + if (!@file_exists($files['opts'])) { + msg('Error: there are no saved options', -1); + return false; + } + + $opts = unserialize(file_get_contents($files['opts'])); + + if (@file_exists($files['pagelist'])) { + $pagelist = file($files['pagelist'], FILE_IGNORE_NEW_LINES); + + $limit = min(10, count($pagelist)); + for ($i = 0; $i < $limit; ++$i) { + $ID = array_pop($pagelist); + $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); + $pageOpts = $opts; + $pageOpts['ns'] = getNS($ID); + $pageOpts['name'] = noNS($ID); + $pageOpts['newname'] = noNS($ID); + $pageOpts['newns'] = getNS($newID); + if (!$this->move_page($pageOpts)) return false; + + // save the list of pages after every move + if (empty($pagelist)) { + unlink($files['pagelist']); + } else { + io_saveFile($files['pagelist'], implode("\n", $pagelist)); + } + } + return count($pagelist) + $opts['num_media']; + } elseif (@file_exists($files['medialist'])) { + $medialist = file($files['medialist'], FILE_IGNORE_NEW_LINES); + + $limit = min(10, count($medialist)); + for ($i = 0; $i < $limit; ++$i) { + $ID = array_pop($medialist); + $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); + $pageOpts = $opts; + $pageOpts['ns'] = getNS($ID); + $pageOpts['name'] = noNS($ID); + $pageOpts['newname'] = noNS($ID); + $pageOpts['newns'] = getNS($newID); + if (!$this->move_media($pageOpts)) return false; + + // save the list of media files after every move + if (empty($medialist)) { + unlink($files['medialist']); + unlink($files['opts']); + } else { + io_saveFile($files['medialist'], implode("\n", $medialist)); + } + } + return count($medialist); + } else { + unlink($files['opts']); + return 0; + } + } + + /** + * Skip the item that would be executed next in the current namespace move + * + * @return bool|int False if an error occurred, otherwise the number of remaining moves + */ + public function skip_namespace_move_item() { + global $ID; + $files = $this->get_namespace_meta_files(); + + if (!@file_exists($files['opts'])) { + msg('Error: there are no saved options', -1); + return false; + } + + $opts = unserialize(file_get_contents($files['opts'])); + + if (@file_exists($files['pagelist'])) { + $pagelist = file($files['pagelist'], FILE_IGNORE_NEW_LINES); + + $ID = array_pop($pagelist); + // save the list of pages after every move + if (empty($pagelist)) { + unlink($files['pagelist']); + } else { + io_saveFile($files['pagelist'], implode("\n", $pagelist)); + } + return count($pagelist) + $opts['num_media']; + } elseif (@file_exists($files['medialist'])) { + $medialist = file($files['medialist'], FILE_IGNORE_NEW_LINES); + + $ID = array_pop($medialist); + // save the list of media files after every move + if (empty($medialist)) { + unlink($files['medialist']); + unlink($files['opts']); + } else { + io_saveFile($files['medialist'], implode("\n", $medialist)); + } + + return count($medialist); + } else { + unlink($files['opts']); + return 0; + } + } + + /** + * Abort the currently running namespace move + */ + public function abort_namespace_move() { + $files = $this->get_namespace_meta_files(); + foreach ($files as $file) { + @unlink($file); + } + } + + /** + * Get the options for the namespace move that is currently in progress if there is any + * + * @return bool|array False if there is no namespace move in progress, otherwise the array of options + */ + public function get_namespace_move_opts() { + $files = $this->get_namespace_meta_files(); + + if (!@file_exists($files['opts'])) { + return false; + } + + $opts = unserialize(file_get_contents($files['opts'])); + + return $opts; + } + + /** + * Get the filenames for the metadata of the pagemove plugin + * + * @return array The file names for opts, pagelist and medialist + */ + protected function get_namespace_meta_files() { + global $conf; + return array( + 'opts' => $conf['metadir'].'/__pagemove_opts', + 'pagelist' => $conf['metadir'].'/__pagemove_pagelist', + 'medialist' => $conf['metadir'].'/__pagemove_medialist' + ); + } + /** * Get the id of a page after a namespace move * diff --git a/lang/en/lang.php b/lang/en/lang.php index 73f1375..c6b5bdc 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -36,6 +36,15 @@ $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'; + +$lang['pm_ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; +$lang['pm_ns_move_continue'] = 'Continue the namespace move'; +$lang['pm_ns_move_abort'] = 'Abort the namespace move'; +$lang['pm_ns_move_continued'] = 'The namespace move from namespace %s to namespace %s was continued, %s items are still remaining.'; +$lang['pm_ns_move_started'] = 'A namespace move from namespace %s to namespace %s was started, %s pages and %s media files will be moved.'; +$lang['pm_ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; +$lang['pm_ns_move_tryagain'] = 'Try again'; +$lang['pm_ns_move_skip'] = 'Skip the current item'; // Form labels $lang['pm_newname'] = 'New page name:'; $lang['pm_newnsname'] = 'New namespace name:'; diff --git a/script.js b/script.js index 853d067..312f655 100644 --- a/script.js +++ b/script.js @@ -10,9 +10,9 @@ jQuery(function() { var $preview = jQuery('

'); $this.find('input[type=submit]').before($preview); var updatePreview = function() { - if ($this.find('input[name=move_type]').attr('value') == 'namespace') { - var targetns = $this.find('select[name=targetns]').attr('value'); - var newnsname = $this.find('input[name=newnsname]').attr('value'); + if ($this.find('input[name=move_type]').val() == 'namespace') { + var targetns = $this.find('select[name=targetns]').val(); + var newnsname = $this.find('input[name=newnsname]').val(); var previewns; if (targetns == ':') { previewns = newnsname; @@ -21,10 +21,13 @@ jQuery(function() { } $preview.text(LANG['plugins']['pagemove']['pm_previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); } else { - var ns_for_page = $this.find('select[name=ns_for_page]').attr('value'); - var newns = $this.find('input[name=newns]').attr('value'); - var newname = $this.find('input[name=newname]').attr('value'); + var ns_for_page = $this.find('select[name=ns_for_page]').val(); + var newns = $this.find('input[name=newns]').val(); + var newname = $this.find('input[name=newname]').val(); var newid = ''; + if (typeof newns == 'undefined') { + return; + } if (newns.replace(/\s/g) != '') { newid = newns + ':'; } else if (ns_for_page != ':') { @@ -39,4 +42,47 @@ jQuery(function() { $this.find('input,select').change(updatePreview); $this.find('input').keyup(updatePreview); }); + + jQuery('form.pagemove__nscontinue').each(function() { + var $this = jQuery(this); + var $container = jQuery('div.plugin__pagemove_forms'); + var submit_handler = function() { + $container.empty(); + var $progressbar = jQuery('
'); + $container.append($progressbar); + $progressbar.progressbar({value: false}); + var $message = jQuery('
'); + $container.append($message); + var skip = jQuery(this).hasClass('pagemove__nsskip'); + + var continue_move = function() { + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_pagemove_ns_continue', + id: JSINFO['id'], + skip: skip + }, + function(data) { + $progressbar.progressbar('option', 'value', data.pages + data.media - data.remaining); + $progressbar.progressbar('option', 'max', data.pages + data.media); + $message.html(data.html); + if (data.remaining === false) { + $container.find('form.pagemove__nscontinue, form.pagemove__nsskip').submit(submit_handler); + } else if (data.remaining === 0) { + window.location.href = data.redirect_url; + } else { + window.setTimeout(continue_move, 200); + } + }, + 'json' + ); + skip = false; + }; + + continue_move(); + return false; + }; + $this.submit(submit_handler); + }); }); \ No newline at end of file From f4e4c17ed84bcc3f0dfcb67bd73dd03574014419 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 30 Mar 2013 23:23:03 +0100 Subject: [PATCH 033/338] Remove page names form link adaption change message --- lang/de/lang.php | 2 +- lang/en/lang.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/de/lang.php b/lang/de/lang.php index ab31995..8f2eb4b 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -30,7 +30,7 @@ $lang['pm_norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; $lang['pm_notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; $lang['pm_filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; -$lang['pm_linkchange'] = 'Link zu %s geändert zu %s'; +$lang['pm_linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; // Form labels $lang['pm_newname'] = 'Neuer Seitenname:'; $lang['pm_newnsname'] = 'Neuer Name für Namensraum:'; diff --git a/lang/en/lang.php b/lang/en/lang.php index c6b5bdc..9e359cf 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -35,7 +35,7 @@ $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'; +$lang['pm_linkchange'] = 'Links adapted because of a pagemove operation'; $lang['pm_ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; $lang['pm_ns_move_continue'] = 'Continue the namespace move'; From f102d50d401ca2552dbb7720f911eb766badba87 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 30 Mar 2013 23:23:46 +0100 Subject: [PATCH 034/338] Delete empty media namespaces --- helper.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helper.php b/helper.php index 8fe8e15..c5a1139 100644 --- a/helper.php +++ b/helper.php @@ -493,6 +493,8 @@ public function move_media(&$opts, $checkonly = false) { return false; } + io_sweepNS($opts['id'], 'mediadir'); + // Move the old revisions if (!$this->movemediaattic($opts)) { // it's too late to stop the move, so just display a message. From 34b1e380b43bf9a228d9278b9766e0a3a188014e Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 30 Mar 2013 23:23:59 +0100 Subject: [PATCH 035/338] Fix infinite loop in some move scenarios --- helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper.php b/helper.php index c5a1139..8c15517 100644 --- a/helper.php +++ b/helper.php @@ -738,7 +738,7 @@ protected function resolve_moves($moves, $id) { while($changed) { $changed = false; foreach($tmp_moves as $old => $new) { - if($old != $new && isset($moves[$new]) && $moves[$new] != $new) { + if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { $tmp_moves[$old] = $moves[$new]; $changed = true; } From e1d9483646265688e27c23dfba3a97e6cd8d94ca Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 31 Mar 2013 22:12:35 +0200 Subject: [PATCH 036/338] Updated the German translation for the new namespace move code --- lang/de/lang.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lang/de/lang.php b/lang/de/lang.php index 8f2eb4b..b3f5559 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -16,11 +16,14 @@ $lang['desc'] = 'Seite/Namespace verschieben/umbenennen... Plugin'; $lang['pm_notexist'] = 'Die Seite %s existiert nicht.'; +$lang['pm_medianotexist'] = 'Die Mediendatei %s existiert nicht'; $lang['pm_notwrite'] = 'Sie haben unzureichende Rechte um diese Seite zu ändern'; $lang['pm_badns'] = 'Ungültige Zeichen in der Namensraum-Bezeichnung.'; $lang['pm_badname'] = 'Ungültiges Zeichen im Seitennamen.'; $lang['pm_nochange'] = 'Name und Namensraum der Seite sind unverändert.'; +$lang['pm_nomediachange'] = 'Name und Namensraum der Mediendatei sind unverändert.'; $lang['pm_existing'] = 'Eine Seite mit der Bezeichnung %s existiert bereits in %s'; +$lang['pm_mediaexisting'] = 'Eine Mediendatei mit der Bezeichnung %s existiert bereits in %s'; $lang['pm_root'] = '[Wurzel des Namensraumes / Root namespace]'; $lang['pm_current'] = '(Aktueller)'; $lang['pm_renamed'] = 'Seitename wurde von %s auf %s geändert'; @@ -28,9 +31,20 @@ $lang['pm_move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; $lang['pm_delete'] = 'Gelöscht durch das pagemove Plugin'; $lang['pm_norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; +$lang['pm_nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; $lang['pm_notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; +$lang['pm_nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; $lang['pm_filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; $lang['pm_linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; + +$lang['pm_ns_move_in_progress'] = 'Das Verschieben von %s Seiten und %s Mediendateien vom Namensraum %s nach %s ist derzeit im Gange.'; +$lang['pm_ns_move_continue'] = 'Das Verschieben des Namensraumes fortsetzen'; +$lang['pm_ns_move_abort'] = 'Das Verschieben des Namensraumes abbrechen'; +$lang['pm_ns_move_continued'] = 'Das Verschieben des Namensraumes %s nach %s wurde fortgesetzt, %s Einträge müssen noch verschoben werden.'; +$lang['pm_ns_move_started'] = 'Das Verschieben des Namensraumes %s nach %s wurde begonnen, %s Seiten und %s Mediendateien werden verschoben werden.'; +$lang['pm_ns_move_error'] = 'Ein Fehler ist beim Verschieben des Namensraumes %s nach %s aufgetreten.'; +$lang['pm_ns_move_tryagain'] = 'Nochmal versuchen'; +$lang['pm_ns_move_skip'] = 'Den aktuellen Eintrag überspringen'; // Form labels $lang['pm_newname'] = 'Neuer Seitenname:'; $lang['pm_newnsname'] = 'Neuer Name für Namensraum:'; From 68f1b01902f5246e2e321cdfcf2730fe7327ed67 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 31 Mar 2013 22:58:03 +0200 Subject: [PATCH 037/338] Set the progressbar to undefined when an error occurred --- script.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/script.js b/script.js index 312f655..39bd671 100644 --- a/script.js +++ b/script.js @@ -64,8 +64,12 @@ jQuery(function() { skip: skip }, function(data) { - $progressbar.progressbar('option', 'value', data.pages + data.media - data.remaining); - $progressbar.progressbar('option', 'max', data.pages + data.media); + if (data.remaining === false) { + $progressbar.progressbar('option', 'value', false); + } else { + $progressbar.progressbar('option', 'value', data.pages + data.media - data.remaining); + $progressbar.progressbar('option', 'max', data.pages + data.media); + } $message.html(data.html); if (data.remaining === false) { $container.find('form.pagemove__nscontinue, form.pagemove__nsskip').submit(submit_handler); From e4d6c6aa85a49d04670089620962167cbaf9290e Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 31 Mar 2013 22:59:12 +0200 Subject: [PATCH 038/338] Code cleanup: Add new helper function for creating a namespace move button --- action.php | 21 ++----------- admin.php | 89 ++++++++++++++---------------------------------------- helper.php | 50 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 84 deletions(-) diff --git a/action.php b/action.php index 09ae870..1fe9244 100644 --- a/action.php +++ b/action.php @@ -184,25 +184,10 @@ public function handle_ajax_call(Doku_Event $event, $params) { ob_start(); html_msgarea(); if ($remaining === false) { - $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $id); - $form->addHidden('continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_tryagain'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $id); - $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nsskip')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $id); - $form->addHidden('skip_continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_skip'))); - $form->printForm(); ptln('

'.sprintf($this->getLang('pm_ns_move_error'), $opts['ns'], $opts['newns']).'

'); + echo $helper->getNSMoveButton('tryagain', $id); + echo $helper->getNSMoveButton('skip', $id); + echo $helper->getNSMoveButton('abort', $id); } else { ptln('

'.sprintf($this->getLang('pm_ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

'); } diff --git a/admin.php b/admin.php index f6a723e..e8b8f7c 100644 --- a/admin.php +++ b/admin.php @@ -17,6 +17,8 @@ class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { var $opts = array(); private $ns_opts = false; + /** @var helper_plugin_pagemove $helper */ + private $helper = null; /** * Get the sort number that defines the position in the admin menu. @@ -63,66 +65,32 @@ function getMenuText() { * @author Gary Owen */ function html() { - global $ID; + if (!$this->helper) return; ptln(''); ptln( $this->locale_xhtml('pagemove') ); ptln('
'); + if ($this->ns_opts !== false && isset($this->ns_opts['started'])) { ptln('

'); ptln(sprintf($this->getLang('pm_ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); ptln('

'); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); - $form->printForm(); + ptln($this->helper->getNSMoveButton('continue')); + ptln($this->helper->getNSMoveButton('abort')); } elseif ($this->ns_opts !== false && isset($this->ns_opts['remaining'])) { if ($this->ns_opts['remaining'] === false) { ptln('

'); ptln(sprintf($this->getLang('pm_ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); ptln('

'); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_tryagain'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('skip_continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_skip'))); - $form->printForm(); + ptln($this->helper->getNSMoveButton('tryagain')); + ptln($this->helper->getNSMoveButton('skip')); + ptln($this->helper->getNSMoveButton('abort')); } else { ptln('

'); ptln(sprintf($this->getLang('pm_ns_move_continued'), $this->ns_opts['ns'], $this->ns_opts['newns'], $this->ns_opts['remaining'])); ptln('

'); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); - $form->printForm(); + ptln($this->helper->getNSMoveButton('continue')); + ptln($this->helper->getNSMoveButton('abort')); } } else { $this->printForm(); @@ -164,18 +132,8 @@ function printForm() { ptln('

'); ptln(sprintf($this->getLang('pm_ns_move_in_progress'), $this->ns_opts['num_pages'], $this->ns_opts['num_media'], ':'.hsc($this->ns_opts['ns']), ':'.hsc($this->ns_opts['newns']))); ptln('

'); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform pagemove__nscontinue')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); - $form->printForm(); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__nsform')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); - $form->printForm(); + ptln($this->helper->getNSMoveButton('continue')); + ptln($this->helper->getNSMoveButton('abort')); ptln(''); } else { $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); @@ -239,11 +197,10 @@ function handle() { $this->opts['newnsname'] = ''; $this->opts['move_type'] = 'page'; - /** @var helper_plugin_pagemove $helper */ - $helper = $this->loadHelper('pagemove', true); - if (!$helper) return; + $this->helper = $this->loadHelper('pagemove', true); + if (!$this->helper) return; - $this->ns_opts = $helper->get_namespace_move_opts(); + $this->ns_opts = $this->helper->get_namespace_move_opts(); // Only continue when the form was submitted if ($_SERVER['REQUEST_METHOD'] != 'POST') { @@ -252,17 +209,17 @@ function handle() { if (isset($_POST['continue_namespace_move']) || isset($_POST['skip_continue_namespace_move'])) { if (isset($_POST['skip_continue_namespace_move'])) { - $helper->skip_namespace_move_item(); + $this->helper->skip_namespace_move_item(); } - $this->ns_opts['remaining'] = $helper->continue_namespace_move(); + $this->ns_opts['remaining'] = $this->helper->continue_namespace_move(); if ($this->ns_opts['remaining'] === 0) { - $ID = $helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); + $ID = $this->helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); $ACT = 'show'; } return; } elseif (isset($_POST['abort_namespace_move'])) { - $helper->abort_namespace_move(); + $this->helper->abort_namespace_move(); $this->ns_opts = false; return; @@ -286,9 +243,9 @@ function handle() { $this->opts['newns'] = $this->opts['targetns'].':'.$this->opts['newnsname']; } - $started = $helper->start_namespace_move($this->opts); + $started = $this->helper->start_namespace_move($this->opts); if ($started !== false) { - $this->ns_opts = $helper->get_namespace_move_opts(); + $this->ns_opts = $this->helper->get_namespace_move_opts(); $this->ns_opts['started'] = $started; } } else { @@ -302,7 +259,7 @@ function handle() { $this->opts['newns'] = $this->opts['ns_for_page']; } - if ($helper->move_page($this->opts)) { + if ($this->helper->move_page($this->opts)) { // Set things up to display the new page. $ID = $this->opts['new_id']; $ACT = 'show'; // this triggers a redirect to the page diff --git a/helper.php b/helper.php index 8c15517..f81c8ea 100644 --- a/helper.php +++ b/helper.php @@ -752,6 +752,56 @@ protected function resolve_moves($moves, $id) { } return $moves; } + + /** + * Get the HTML code of a namespace move button + * @param string $action The desired action of the button (continue, tryagain, skip, abort) + * @param string|null $id The id of the target page, null if $ID shall be used + * @return bool|string The HTML of code of the form or false if an invalid action was supplied + */ + public function getNSMoveButton($action, $id = NULL) { + if ($id === NULL) { + global $ID; + $id = $ID; + } + + $class = 'pagemove__nsform'; + switch ($action) { + case 'continue': + case 'tryagain': + $class .= ' pagemove__nscontinue'; + break; + case 'skip': + $class .= ' pagemove__nsskip'; + break; + } + + $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => $class)); + $form->addHidden('page', $this->getPluginName()); + $form->addHidden('id', $id); + switch ($action) { + case 'continue': + case 'tryagain': + $form->addHidden('continue_namespace_move', true); + if ($action == 'tryagain') { + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_tryagain'))); + } else { + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); + } + break; + case 'skip': + $form->addHidden('skip_continue_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_skip'))); + break; + case 'abort': + $form->addHidden('abort_namespace_move', true); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + break; + default: + return false; + } + return $form->getForm(); + } } /** From b57a8d493f33687aca059775e24687b2542262da Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 31 Mar 2013 23:00:02 +0200 Subject: [PATCH 039/338] Fix the ajax skip option, add FIXME that page changes can occur during saves --- action.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/action.php b/action.php index 1fe9244..fdea668 100644 --- a/action.php +++ b/action.php @@ -52,6 +52,7 @@ function handle_read(Doku_Event $event, $param) { if (isset($stack[$id])) return; // Don't change the page when the user is currently changing the page content or the page is locked by another user + // FIXME: this doesn't work, most probably because $ACT is an array or not yet set if ((isset($ACT) && (in_array($ACT, array('save', 'preview', 'recover', 'revert')))) || checklock($id) !== false) return; @@ -168,9 +169,9 @@ public function handle_ajax_call(Doku_Event $event, $params) { $helper = $this->loadHelper('pagemove', false); $opts = $helper->get_namespace_move_opts(); $id = cleanID((string)$_POST['id']); - $skip = (int)$_POST['skip']; + $skip = (string)$_POST['skip']; if ($opts !== false) { - if ($skip) { + if ($skip == 'true') { $helper->skip_namespace_move_item(); } $remaining = $helper->continue_namespace_move(); From cb274157a4ced81329418952956b74591b06bd0f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 1 Apr 2013 01:04:04 +0200 Subject: [PATCH 040/338] Avoid reading and writing the whole media/page list for each move This makes sure that only the necessary parts of the media/page list are read and the file is efficiently truncated. In order to calculate the number of remaining items this number is stored and updated in the options. --- admin.php | 33 ++++++++------ helper.php | 124 +++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 106 insertions(+), 51 deletions(-) diff --git a/admin.php b/admin.php index e8b8f7c..c065b7d 100644 --- a/admin.php +++ b/admin.php @@ -19,6 +19,8 @@ class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { private $ns_opts = false; /** @var helper_plugin_pagemove $helper */ private $helper = null; + /** @var string $ns_move_state The state of the current namespace move (none, started, continued, error) */ + private $ns_move_state = 'none'; /** * Get the sort number that defines the position in the admin menu. @@ -70,30 +72,32 @@ function html() { ptln( $this->locale_xhtml('pagemove') ); ptln('
'); - if ($this->ns_opts !== false && isset($this->ns_opts['started'])) { - ptln('

'); - ptln(sprintf($this->getLang('pm_ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); - ptln('

'); - ptln($this->helper->getNSMoveButton('continue')); - ptln($this->helper->getNSMoveButton('abort')); - } elseif ($this->ns_opts !== false && isset($this->ns_opts['remaining'])) { - if ($this->ns_opts['remaining'] === false) { + switch ($this->ns_move_state) { + case 'started': + ptln('

'); + ptln(sprintf($this->getLang('pm_ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); + ptln('

'); + ptln($this->helper->getNSMoveButton('continue')); + ptln($this->helper->getNSMoveButton('abort')); + break; + case 'error': ptln('

'); ptln(sprintf($this->getLang('pm_ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); ptln('

'); ptln($this->helper->getNSMoveButton('tryagain')); ptln($this->helper->getNSMoveButton('skip')); ptln($this->helper->getNSMoveButton('abort')); - } else { + break; + case 'continued': ptln('

'); ptln(sprintf($this->getLang('pm_ns_move_continued'), $this->ns_opts['ns'], $this->ns_opts['newns'], $this->ns_opts['remaining'])); ptln('

'); ptln($this->helper->getNSMoveButton('continue')); ptln($this->helper->getNSMoveButton('abort')); - } - } else { - $this->printForm(); + break; + default: + $this->printForm(); } ptln('
'); ptln(''); @@ -124,7 +128,7 @@ function printForm() { $form->endFieldset(); $form->printForm(); - if ($this->ns_opts !== false && !isset($this->ns_opts['remaining'])) { + if ($this->ns_opts !== false) { ptln('
'); ptln(''); ptln($this->getLang('pm_movens')); @@ -212,6 +216,7 @@ function handle() { $this->helper->skip_namespace_move_item(); } $this->ns_opts['remaining'] = $this->helper->continue_namespace_move(); + $this->ns_move_state = ($this->ns_opts['remaining'] === false ? 'error': 'continued'); if ($this->ns_opts['remaining'] === 0) { $ID = $this->helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); $ACT = 'show'; @@ -246,7 +251,7 @@ function handle() { $started = $this->helper->start_namespace_move($this->opts); if ($started !== false) { $this->ns_opts = $this->helper->get_namespace_move_opts(); - $this->ns_opts['started'] = $started; + $this->ns_move_state = 'started'; } } else { // check that the pagename is valid diff --git a/helper.php b/helper.php index f81c8ea..65f71a2 100644 --- a/helper.php +++ b/helper.php @@ -86,6 +86,8 @@ public function start_namespace_move(&$opts) { io_saveFile($files['medialist'], implode("\n", $media_files)); + $opts['remaining'] = $opts['num_media'] + $opts['num_pages']; + // save the options io_saveFile($files['opts'], serialize($opts)); @@ -109,54 +111,68 @@ public function continue_namespace_move() { $opts = unserialize(file_get_contents($files['opts'])); if (@file_exists($files['pagelist'])) { - $pagelist = file($files['pagelist'], FILE_IGNORE_NEW_LINES); + $pagelist = fopen($files['pagelist'], 'a+');; - $limit = min(10, count($pagelist)); - for ($i = 0; $i < $limit; ++$i) { - $ID = array_pop($pagelist); + for ($i = 0; $i < 10; ++$i) { + $ID = $this->get_last_id($pagelist); + if ($ID === false) { + break; + } $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); $pageOpts = $opts; $pageOpts['ns'] = getNS($ID); $pageOpts['name'] = noNS($ID); $pageOpts['newname'] = noNS($ID); $pageOpts['newns'] = getNS($newID); - if (!$this->move_page($pageOpts)) return false; - - // save the list of pages after every move - if (empty($pagelist)) { - unlink($files['pagelist']); - } else { - io_saveFile($files['pagelist'], implode("\n", $pagelist)); + if (!$this->move_page($pageOpts)) { + fclose($pagelist); + return false; } + + // update the list of pages and the options after every move + ftruncate($pagelist, ftell($pagelist)); + $opts['remaining']--; + io_saveFile($files['opts'], serialize($opts)); } - return count($pagelist) + $opts['num_media']; + + fclose($pagelist); + if ($ID === false) unlink($files['pagelist']); } elseif (@file_exists($files['medialist'])) { - $medialist = file($files['medialist'], FILE_IGNORE_NEW_LINES); + $medialist = fopen($files['medialist'], 'a+'); - $limit = min(10, count($medialist)); - for ($i = 0; $i < $limit; ++$i) { - $ID = array_pop($medialist); + for ($i = 0; $i < 10; ++$i) { + $ID = $this->get_last_id($medialist); + if ($ID === false) { + break; + } $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); $pageOpts = $opts; $pageOpts['ns'] = getNS($ID); $pageOpts['name'] = noNS($ID); $pageOpts['newname'] = noNS($ID); $pageOpts['newns'] = getNS($newID); - if (!$this->move_media($pageOpts)) return false; - - // save the list of media files after every move - if (empty($medialist)) { - unlink($files['medialist']); - unlink($files['opts']); - } else { - io_saveFile($files['medialist'], implode("\n", $medialist)); + if (!$this->move_media($pageOpts)) { + fclose($medialist); + return false; } + + // update the list of media files and the options after every move + ftruncate($medialist, ftell($medialist)); + $opts['remaining']--; + io_saveFile($files['opts'], serialize($opts)); + } + + fclose($medialist); + if ($ID === false) { + unlink($files['medialist']); + unlink($files['opts']); } - return count($medialist); } else { unlink($files['opts']); return 0; } + + return $opts['remaining']; } /** @@ -176,33 +192,67 @@ public function skip_namespace_move_item() { $opts = unserialize(file_get_contents($files['opts'])); if (@file_exists($files['pagelist'])) { - $pagelist = file($files['pagelist'], FILE_IGNORE_NEW_LINES); + $pagelist = fopen($files['pagelist'], 'a+'); - $ID = array_pop($pagelist); + $ID = $this->get_last_id($pagelist); // save the list of pages after every move - if (empty($pagelist)) { + if ($ID === false || ftell($pagelist) == 0) { + fclose($pagelist); unlink($files['pagelist']); } else { - io_saveFile($files['pagelist'], implode("\n", $pagelist)); + ftruncate($pagelist, ftell($pagelist));; + fclose($pagelist); } - return count($pagelist) + $opts['num_media']; } elseif (@file_exists($files['medialist'])) { - $medialist = file($files['medialist'], FILE_IGNORE_NEW_LINES); + $medialist = fopen($files['medialist'], 'a+'); - $ID = array_pop($medialist); + $ID = $this->get_last_id($medialist);; // save the list of media files after every move - if (empty($medialist)) { + if ($ID === false || ftell($medialist) == 0) { + fclose($medialist); unlink($files['medialist']); unlink($files['opts']); } else { - io_saveFile($files['medialist'], implode("\n", $medialist)); + ftruncate($medialist, ftell($medialist)); } - - return count($medialist); } else { unlink($files['opts']); - return 0; } + if ($opts['remaining'] == 0) return 0; + else { + $opts['remaining']--; + // save the options + io_saveFile($files['opts'], serialize($opts)); + return $opts['remaining']; + } + } + + /** + * Get last file id from the list that is stored in the file that is referenced by the handle + * The handle is set to the newline before the file id + * + * @param resource $handle The file handle to read from + * @return string|bool the last id from the list or false if there is none + */ + private function get_last_id($handle) { + // begin the seek at the end of the file + fseek($handle, 0, SEEK_END); + $id = ''; + + // seek one backwards as long as it's possible + while (fseek($handle, -1, SEEK_CUR) >= 0) { + $c = fgetc($handle); + fseek($handle, -1, SEEK_CUR); // reset the position to the character that was read + + if ($c == "\n") { + break; + } + if ($c === false) return false; // EOF, i.e. the file is empty + $id = $c.$id; + } + + if ($id === '') return false; // nothing was read i.e. the file is empty + else return $id; } /** From 229822daf876a1e47d2fe96fa7c7241418dff242 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 1 Apr 2013 01:19:37 +0200 Subject: [PATCH 041/338] New release 2013-04-01 --- plugin.info.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin.info.txt b/plugin.info.txt index 7181002..7abda2b 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base pagemove -author Gary Owen, Arno Puschmann, Christoph Jähnigen -email pagemove@gmail.com -date 2010-06-17 +author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen +email michael@content-space.de +date 2013-04-01 name Pagemove plugin desc Move and rename pages and namespaces whilst maintaining the links. url http://www.dokuwiki.org/plugin:pagemove From 4f5f2d39faa40a00a1979022b99c354796ba29b7 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 29 Oct 2013 20:13:19 +0100 Subject: [PATCH 042/338] Added selection which content (pages, media files or both) should be moved --- admin.php | 4 +++- helper.php | 6 ++++-- lang/en/lang.php | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/admin.php b/admin.php index c065b7d..582570d 100644 --- a/admin.php +++ b/admin.php @@ -147,6 +147,7 @@ function printForm() { $form->startFieldset($this->getLang('pm_movens')); $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('pm_targetns'), '', 'block')); $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('pm_newnsname'), '', 'block')); + $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('pm_move_pages'), 'media' => $this->getLang('pm_move_media'), 'both' => $this->getLang('pm_move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('pm_content_to_move'), '', 'block')); $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); $form->endFieldset(); $form->printForm(); @@ -200,6 +201,7 @@ function handle() { $this->opts['targetns'] = getNS($ID); $this->opts['newnsname'] = ''; $this->opts['move_type'] = 'page'; + $this->opts['contenttomove'] = 'pages'; $this->helper = $this->loadHelper('pagemove', true); if (!$this->helper) return; @@ -237,10 +239,10 @@ function handle() { if (isset($_POST['targetns'])) $this->opts['targetns'] = cleanID((string)$_POST['targetns']); if (isset($_POST['newnsname'])) $this->opts['newnsname'] = cleanID((string)$_POST['newnsname']); if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; + if (isset($_POST['contenttomove']) && in_array($_POST['contenttomove'], array('pages', 'media', 'both'), true)) $this->opts['contenttomove'] = $_POST['contenttomove']; // check the input for completeness if( $this->opts['move_type'] == 'namespace' ) { - $this->opts['media'] = true; // FIXME: add checkbox later! if ($this->opts['targetns'] == '') { $this->opts['newns'] = $this->opts['newnsname']; diff --git a/helper.php b/helper.php index 65f71a2..083fe98 100644 --- a/helper.php +++ b/helper.php @@ -57,7 +57,9 @@ public function start_namespace_move(&$opts) { $pagelist = array(); $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); $searchOpts = array('depth' => 0, 'skipacl' => true); - search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); + if (in_array($opts['contenttomove'], array('pages', 'both'))) { + search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); + } $pages = array(); foreach ($pagelist as $page) { $pages[] = $page['id']; @@ -72,7 +74,7 @@ public function start_namespace_move(&$opts) { // generate and save a list of all media files $medialist = array(); - if (isset($opts['media']) && $opts['media']) { + if (in_array($opts['contenttomove'], array('media,', 'both'))) { search($medialist, $conf['mediadir'], 'search_media', $searchOpts, $pathToSearch); } diff --git a/lang/en/lang.php b/lang/en/lang.php index 9e359cf..10280f9 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -53,6 +53,10 @@ $lang['pm_movepage'] = 'Move page'; $lang['pm_movens'] = 'Move namespace'; $lang['pm_submit'] = 'Submit'; +$lang['pm_content_to_move'] = 'Content to move'; +$lang['pm_move_pages'] = 'Pages'; +$lang['pm_move_media'] = 'Media files'; +$lang['pm_move_media_and_pages'] = 'Pages and media files'; // JavaScript preview $lang['js']['pm_previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; $lang['js']['pm_previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; From ec7eb75a6b05cf93a7691bed138c8ba95c37f1dd Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 29 Oct 2013 20:39:07 +0100 Subject: [PATCH 043/338] Fix the prevention of automatic edits for pages that are currently locked or edited This makes the lock check more strict by reporting pages as locked that are locked by the current user in order to prevent accidently moving or modifying pages that are currently edited. --- action.php | 13 +++++++++---- helper.php | 5 ++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/action.php b/action.php index fdea668..dcb4200 100644 --- a/action.php +++ b/action.php @@ -51,10 +51,15 @@ function handle_read(Doku_Event $event, $param) { if (isset($stack[$id])) return; - // Don't change the page when the user is currently changing the page content or the page is locked by another user - // FIXME: this doesn't work, most probably because $ACT is an array or not yet set - if ((isset($ACT) && (in_array($ACT, array('save', 'preview', 'recover', 'revert')))) - || checklock($id) !== false) return; + // Don't change the page when the user is currently changing the page content or the page is locked + $forbidden_actions = array('save', 'preview', 'recover', 'revert'); + if ((isset($ACT) && ( + in_array($ACT, $forbidden_actions) || (is_array($ACT) && in_array(key($ACT), $forbidden_actions) + ))) + // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user + // the file exists check checks if the page is reported unlocked if a lock exists which means that + // the page is locked by the current user + || checklock($id) !== false || @file_exists(wikiLockFN($id))) return; $helper = $this->loadHelper('pagemove', true); if(!is_null($helper)) { diff --git a/helper.php b/helper.php index 083fe98..5ddda97 100644 --- a/helper.php +++ b/helper.php @@ -344,7 +344,10 @@ public function move_page(&$opts, $checkonly = false) { } // Check file is not locked - if (checklock($ID) !== false) { + // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user + // the file exists check checks if the page is reported unlocked if a lock exists which means that + // the page is locked by the current user + if (checklock($ID) !== false || @file_exists(wikiLockFN($ID))) { msg( sprintf($this->getLang('pm_filelocked'), hsc($ID)), -1); return false; } From fa5ce2caec7b02834d4b3e57e67faa17163df565 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 29 Oct 2013 22:52:57 +0100 Subject: [PATCH 044/338] Use the new media usage index from DokuWiki core if available Note that you need to rebuild the search index after this change in order to get correct link updates after media moves, this should happen automatically for visited pages. The index that is created in the pagemove plugin is now identical to the one that is created in DokuWiki core from the Autumn 2013 release on so you won't need to manually rebuild the index after updating DokuWiki. --- action.php | 8 ++++++-- helper.php | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/action.php b/action.php index dcb4200..a889cfc 100644 --- a/action.php +++ b/action.php @@ -107,7 +107,9 @@ function handle_cache(Doku_Event $event, $param) { * @param array $param Optional parameters (unused) */ public function handle_index_version(Doku_Event $event, $param) { - $event->data['plugin_pagemove'] = 0.1; + // From indexer version 6 on the media references are indexed by DokuWiki itself + if ($event->data['dokuwiki'] < 6) + $event->data['plugin_pagemove'] = 0.2; } /** @@ -117,6 +119,8 @@ public function handle_index_version(Doku_Event $event, $param) { * @param array $param Optional parameters (unused) */ public function index_media_use(Doku_Event $event, $param) { + // From indexer version 6 on the media references are indexed by DokuWiki itself + if (INDEXER_VERSION >= 6) return; $id = $event->data['page']; $media_references = array(); $instructions = p_cached_instructions(wikiFn($id), false, $id); @@ -124,7 +128,7 @@ public function index_media_use(Doku_Event $event, $param) { $this->get_media_references_from_instructions($instructions, $media_references, $id); } $media_references = array_unique($media_references); - $event->data['metadata']['pagemove_media'] = $media_references; + $event->data['metadata']['relation_media'] = $media_references; } /** diff --git a/helper.php b/helper.php index 5ddda97..13d96ee 100644 --- a/helper.php +++ b/helper.php @@ -517,7 +517,7 @@ public function move_media(&$opts, $checkonly = false) { * End of init (checks) */ - $affected_pages = idx_get_indexer()->lookupKey('pagemove_media', $opts['id']); + $affected_pages = idx_get_indexer()->lookupKey('relation_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 @@ -531,7 +531,7 @@ public function move_media(&$opts, $checkonly = false) { } 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) { + if (($idx_msg = $Indexer->renameMetaValue('relation_media', $opts['id'], $opts['new_id'])) !== true) { msg('Error while updating the search index '.$idx_msg, -1); return false; } From 6b3568277b2b8f039e40373a8d5fc9c9693261e2 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 29 Oct 2013 23:05:20 +0100 Subject: [PATCH 045/338] New version 2013-10-29 released Changes: * Added option to select between media and page namespace moves * Use the media usage index that was introduced in DokuWiki itself * Better lock/editing detection avoids changing pages while they are edited --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index 7abda2b..233e5d9 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base pagemove author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2013-04-01 +date 2013-10-29 name Pagemove plugin desc Move and rename pages and namespaces whilst maintaining the links. url http://www.dokuwiki.org/plugin:pagemove From 96457ccde6f125a2969abf923d2657d8a955adb0 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Wed, 20 Nov 2013 22:00:39 +0100 Subject: [PATCH 046/338] Fix the media index test cases for the new index name --- _test/mediaindex.test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_test/mediaindex.test.php b/_test/mediaindex.test.php index 2563ba6..b492f83 100644 --- a/_test/mediaindex.test.php +++ b/_test/mediaindex.test.php @@ -23,7 +23,7 @@ public function test_internalmedia() { $this->assertEquals( array( 'test:internalmedia.png' => array('test:internalmedia_usage'), 'internal_media.png' => array('test:internalmedia_usage') - ), idx_get_indexer()->lookupKey('pagemove_media', $query)); + ), idx_get_indexer()->lookupKey('relation_media', $query)); } public function test_media_in_links() { @@ -34,7 +34,7 @@ public function test_media_in_links() { $this->assertEquals(array( 'wiki:logo.png' => array('test:medialinks'), 'test:example.png' => array('test:medialinks') - ), idx_get_indexer()->lookupKey('pagemove_media', $query)); + ), idx_get_indexer()->lookupKey('relation_media', $query)); } public function test_media_in_footnotes() { @@ -45,6 +45,6 @@ public function test_media_in_footnotes() { $this->assertEquals(array( 'test:footnote.png' => array('test:media_footnotes'), 'footlink.png' => array('test:media_footnotes') - ), idx_get_indexer()->lookupKey('pagemove_media', $query)); + ), idx_get_indexer()->lookupKey('relation_media', $query)); } } From 689122ac5529db7caef0a02d5bab0902deb519c7 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Wed, 20 Nov 2013 22:01:09 +0100 Subject: [PATCH 047/338] Adapt the namespace move test to the new options for media files --- _test/namespace_move.test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index d6d51d1..a9c10e4 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -26,7 +26,7 @@ public function test_move_wiki_namespace() { $opts = array( 'ns' => 'wiki', 'newns' => 'foo', - 'media' => true + 'contenttomove' => 'both' ); $this->assertSame(3, $pagemove->start_namespace_move($opts)); From 6d7bd5c515513723c0fbefbcff73de22457b29c6 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Wed, 20 Nov 2013 22:01:27 +0100 Subject: [PATCH 048/338] Fix a strict standards error in action.php --- action.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.php b/action.php index a889cfc..967d161 100644 --- a/action.php +++ b/action.php @@ -17,7 +17,7 @@ class action_plugin_pagemove extends DokuWiki_Action_Plugin { * * @param Doku_Event_Handler $controller The plugin controller */ - public function register($controller) { + public function register(Doku_Event_Handler $controller) { $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_read', array()); $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache', array()); $controller->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, 'handle_index_version'); From bcaa37bd5dca5fbf0fc764597ecd5eca0fa3cdda Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Wed, 20 Nov 2013 21:59:41 +0100 Subject: [PATCH 049/338] Renamed the pagemove plugin to "move" Note that all class and event names that contained the name "pagemove" have been renamed to the same name without "page". --- README | 2 +- _test/mediaindex.test.php | 4 +- _test/mediamove.test.php | 18 ++++---- _test/namespace_move.test.php | 16 +++---- _test/pagemove.test.php | 22 +++++----- action.php | 22 +++++----- admin.php | 22 +++++----- helper.php | 70 +++++++++++++++--------------- lang/cs/{pagemove.txt => move.txt} | 2 +- lang/de/lang.php | 2 +- lang/de/{pagemove.txt => move.txt} | 0 lang/en/lang.php | 4 +- lang/en/{pagemove.txt => move.txt} | 2 +- lang/es/{pagemove.txt => move.txt} | 2 +- lang/fr/{pagemove.txt => move.txt} | 2 +- lang/lv/{pagemove.txt => move.txt} | 0 lang/nl/{pagemove.txt => move.txt} | 0 lang/pl/{pagemove.txt => move.txt} | 2 +- lang/ru/{pagemove.txt => move.txt} | 0 lang/sl/{pagemove.txt => move.txt} | 2 +- plugin.info.txt | 8 ++-- script.js | 18 ++++---- 22 files changed, 110 insertions(+), 110 deletions(-) rename lang/cs/{pagemove.txt => move.txt} (95%) rename lang/de/{pagemove.txt => move.txt} (100%) rename lang/en/{pagemove.txt => move.txt} (96%) rename lang/es/{pagemove.txt => move.txt} (96%) rename lang/fr/{pagemove.txt => move.txt} (96%) rename lang/lv/{pagemove.txt => move.txt} (100%) rename lang/nl/{pagemove.txt => move.txt} (100%) rename lang/pl/{pagemove.txt => move.txt} (95%) rename lang/ru/{pagemove.txt => move.txt} (100%) rename lang/sl/{pagemove.txt => move.txt} (95%) diff --git a/README b/README index b24492a..44b8df2 100644 --- a/README +++ b/README @@ -1 +1 @@ -A DokuWiki pagemove plugin +A DokuWiki move plugin diff --git a/_test/mediaindex.test.php b/_test/mediaindex.test.php index b492f83..f5944ab 100644 --- a/_test/mediaindex.test.php +++ b/_test/mediaindex.test.php @@ -8,10 +8,10 @@ * * @author Michael Hamann */ -class plugin_pagemove_mediaindex_test extends DokuWikiTest { +class plugin_move_mediaindex_test extends DokuWikiTest { public function setUp() { - $this->pluginsEnabled[] = 'pagemove'; + $this->pluginsEnabled[] = 'move'; parent::setUp(); } diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index d7f099d..9b0c8ee 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -4,12 +4,12 @@ if (!defined('DOKU_INC')) die(); /** - * Test cases for the pagemove plugin + * Test cases for the move plugin */ -class plugin_pagemove_mediamove_test extends DokuWikiTest { +class plugin_move_mediamove_test extends DokuWikiTest { public function setUp() { - $this->pluginsEnabled[] = 'pagemove'; + $this->pluginsEnabled[] = 'move'; parent::setUp(); } @@ -28,9 +28,9 @@ public function test_movePageWithRelativeMedia() { $opts['name'] = noNS($ID); $opts['newns'] = ''; $opts['newname'] = 'foo'; - /** @var helper_plugin_pagemove $pagemove */ - $pagemove = plugin_load('helper', 'pagemove'); - $this->assertTrue($pagemove->move_page($opts)); + /** @var helper_plugin_move $move */ + $move = plugin_load('helper', 'move'); + $this->assertTrue($move->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}}]] @@ -52,9 +52,9 @@ public function test_moveSingleMedia() { $opts['newns'] = 'foobar'; $opts['newname'] = 'logo.png'; - /** @var helper_plugin_pagemove $pagemove */ - $pagemove = plugin_load('helper', 'pagemove'); - $this->assertTrue($pagemove->move_media($opts)); + /** @var helper_plugin_move $move */ + $move = plugin_load('helper', 'move'); + $this->assertTrue($move->move_media($opts)); $this->assertTrue(@file_exists(mediaFn('foobar:logo.png'))); diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index a9c10e4..2767d25 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -4,12 +4,12 @@ if (!defined('DOKU_INC')) die(); /** - * Test cases for namespace move functionality of the pagemove plugin + * Test cases for namespace move functionality of the move plugin */ -class plugin_pagemove_namespace_move_test extends DokuWikiTest { +class plugin_move_namespace_move_test extends DokuWikiTest { public function setUp() { - $this->pluginsEnabled[] = 'pagemove'; + $this->pluginsEnabled[] = 'move'; parent::setUp(); } @@ -21,17 +21,17 @@ public function test_move_wiki_namespace() { idx_addPage('wiki:dokuwiki'); idx_addPage('wiki:syntax'); - /** @var helper_plugin_pagemove $pagemove */ - $pagemove = plugin_load('helper', 'pagemove'); + /** @var helper_plugin_move $move */ + $move = plugin_load('helper', 'move'); $opts = array( 'ns' => 'wiki', 'newns' => 'foo', 'contenttomove' => 'both' ); - $this->assertSame(3, $pagemove->start_namespace_move($opts)); - $this->assertSame(1, $pagemove->continue_namespace_move()); - $this->assertSame(0, $pagemove->continue_namespace_move()); + $this->assertSame(3, $move->start_namespace_move($opts)); + $this->assertSame(1, $move->continue_namespace_move()); + $this->assertSame(0, $move->continue_namespace_move()); $this->assertFileExists(wikiFN('foo:dokuwiki')); $this->assertFileNotExists(wikiFN('wiki:syntax')); diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index db1d317..de7a80e 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -4,9 +4,9 @@ if (!defined('DOKU_INC')) die(); /** - * Test cases for the pagemove plugin + * Test cases for the move plugin */ -class PagemovePageTest extends DokuWikiTest { +class plugin_move_pagemove_test extends DokuWikiTest { var $movedToId = ''; var $movedId = 'parent_ns:current_ns:test_page'; @@ -14,14 +14,14 @@ class PagemovePageTest extends DokuWikiTest { var $currentNsBacklinkingId = 'parent_ns:current_ns:some_page'; var $otherBacklinkingId = 'level0:level1:other_backlinking_page'; var $subNsPage = 'parent_ns:current_ns:sub_ns:some_page'; - /** @var helper_plugin_pagemove $pagemove */ - private $pagemove = NULL; + /** @var helper_plugin_move $move */ + private $move = NULL; // @todo Move page to an ID which already exists // @todo Check backlinks of a sub-namespace page (moving same, up, down, different) function setUp() { - $this->pluginsEnabled[] = 'pagemove'; + $this->pluginsEnabled[] = 'move'; global $ID; global $INFO; @@ -166,7 +166,7 @@ function setUp() { $references = array_keys(p_get_metadata($this->subNsPage, 'relation references', METADATA_RENDER_UNLIMITED)); idx_get_indexer()->addMetaKeys($this->subNsPage, 'relation_references', $references); - $this->pagemove = new helper_plugin_pagemove(); + $this->move = new helper_plugin_move(); parent::setUp(); } @@ -175,7 +175,7 @@ function setUp() { # } // function test_pm_getforwardlinks() { -// $origLinkAbsLinkArray = $this->pagemove->_pm_getforwardlinks($this->movedId); +// $origLinkAbsLinkArray = $this->move->_pm_getforwardlinks($this->movedId); // } function test_move_page_in_same_ns() { @@ -190,7 +190,7 @@ function test_move_page_in_same_ns() { $opts['newns'] = $opts['ns']; $opts['newname'] = $newPagename; $this->movedToId = $opts['newns'].':'.$newPagename; - $this->pagemove->move_page($opts); + $this->move->move_page($opts); $newId = $opts['newns'].':'.$opts['newname']; $newContent = rawWiki($newId); @@ -308,7 +308,7 @@ function test_move_page_to_parallel_ns() { $opts['newns'] = 'parent_ns:parallel_ns'; $opts['newname'] = $newPagename; $this->movedToId = $opts['newns'].':'.$newPagename; - $this->pagemove->move_page($opts); + $this->move->move_page($opts); $newId = $opts['newns'].':'.$opts['newname']; $newContent = rawWiki($newId); @@ -428,7 +428,7 @@ function test_move_page_to_parent_ns() { $newId = $opts['newns'].':'.$opts['newname']; $this->movedToId = $opts['newns'].':'.$newPagename; - $this->pagemove->move_page($opts); + $this->move->move_page($opts); $newContent = rawWiki($newId); $expectedContent = <<movedToId = $opts['newns'].':'.$newPagename; - //$this->pagemove->_pm_move_recursive($opts); + //$this->move->_pm_move_recursive($opts); } diff --git a/action.php b/action.php index 967d161..f50166b 100644 --- a/action.php +++ b/action.php @@ -1,6 +1,6 @@ @@ -9,9 +9,9 @@ if (!defined('DOKU_INC')) die(); /** - * Action part of the pagemove plugin + * Action part of the move plugin */ -class action_plugin_pagemove extends DokuWiki_Action_Plugin { +class action_plugin_move extends DokuWiki_Action_Plugin { /** * Register event handlers. * @@ -61,7 +61,7 @@ function handle_read(Doku_Event $event, $param) { // the page is locked by the current user || checklock($id) !== false || @file_exists(wikiLockFN($id))) return; - $helper = $this->loadHelper('pagemove', true); + $helper = $this->loadHelper('move', true); if(!is_null($helper)) { $stack[$id] = true; $event->result = $helper->execute_rewrites($id, $event->result); @@ -89,7 +89,7 @@ function handle_cache(Doku_Event $event, $param) { } } if ($id) { - $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); + $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); if ($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { $file = wikiFN($id, '', false); if (is_writable($file)) @@ -101,7 +101,7 @@ function handle_cache(Doku_Event $event, $param) { } /** - * Add the pagemove version to theindex version + * Add the move version to theindex version * * @param Doku_Event $event The event object * @param array $param Optional parameters (unused) @@ -109,7 +109,7 @@ function handle_cache(Doku_Event $event, $param) { public function handle_index_version(Doku_Event $event, $param) { // From indexer version 6 on the media references are indexed by DokuWiki itself if ($event->data['dokuwiki'] < 6) - $event->data['plugin_pagemove'] = 0.2; + $event->data['plugin_move'] = 0.2; } /** @@ -164,18 +164,18 @@ private function get_media_references_from_instructions($instructions, &$media_r } /** - * Handle the plugin_pagemove_ns_continue ajax call + * Handle the plugin_move_ns_continue ajax call * * @param Doku_Event $event The event that is handled * @param array $params Optional parameters (unused) */ public function handle_ajax_call(Doku_Event $event, $params) { - if ($event->data == 'plugin_pagemove_ns_continue') { + if ($event->data == 'plugin_move_ns_continue') { $event->preventDefault(); $event->stopPropagation(); - /** @var helper_plugin_pagemove $helper */ - $helper = $this->loadHelper('pagemove', false); + /** @var helper_plugin_move $helper */ + $helper = $this->loadHelper('move', false); $opts = $helper->get_namespace_move_opts(); $id = cleanID((string)$_POST['id']); $skip = (string)$_POST['skip']; diff --git a/admin.php b/admin.php index 582570d..5af8747 100644 --- a/admin.php +++ b/admin.php @@ -1,6 +1,6 @@ @@ -11,13 +11,13 @@ if (!defined('DOKU_INC')) die(); /** - * Admin component of the pagemove plugin. Provides the user interface. + * Admin component of the move plugin. Provides the user interface. */ -class admin_plugin_pagemove extends DokuWiki_Admin_Plugin { +class admin_plugin_move extends DokuWiki_Admin_Plugin { var $opts = array(); private $ns_opts = false; - /** @var helper_plugin_pagemove $helper */ + /** @var helper_plugin_move $helper */ private $helper = null; /** @var string $ns_move_state The state of the current namespace move (none, started, continued, error) */ private $ns_move_state = 'none'; @@ -68,9 +68,9 @@ function getMenuText() { */ function html() { if (!$this->helper) return; - ptln(''); - ptln( $this->locale_xhtml('pagemove') ); - ptln('
'); + ptln(''); + ptln( $this->locale_xhtml('move') ); + ptln('
'); switch ($this->ns_move_state) { case 'started': @@ -100,7 +100,7 @@ function html() { $this->printForm(); } ptln('
'); - ptln(''); + ptln(''); } /** @@ -116,7 +116,7 @@ function printForm() { $ns_select_data = $this->build_namespace_select_content($ns); - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__form')); $form->addHidden('page', $this->getPluginName()); $form->addHidden('id', $ID); $form->addHidden('move_type', 'page'); @@ -140,7 +140,7 @@ function printForm() { ptln($this->helper->getNSMoveButton('abort')); ptln('
'); } else { - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'pagemove__form')); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__form')); $form->addHidden('page', $this->getPluginName()); $form->addHidden('id', $ID); $form->addHidden('move_type', 'namespace'); @@ -203,7 +203,7 @@ function handle() { $this->opts['move_type'] = 'page'; $this->opts['contenttomove'] = 'pages'; - $this->helper = $this->loadHelper('pagemove', true); + $this->helper = $this->loadHelper('move', true); if (!$this->helper) return; $this->ns_opts = $this->helper->get_namespace_move_opts(); diff --git a/helper.php b/helper.php index 13d96ee..ccb7359 100644 --- a/helper.php +++ b/helper.php @@ -1,6 +1,6 @@ @@ -9,9 +9,9 @@ if (!defined('DOKU_INC')) die(); /** - * Helper part of the pagemove plugin. + * Helper part of the move plugin. */ -class helper_plugin_pagemove extends DokuWiki_Plugin { +class helper_plugin_move extends DokuWiki_Plugin { /** * Move a namespace according to the given options * @@ -285,16 +285,16 @@ public function get_namespace_move_opts() { } /** - * Get the filenames for the metadata of the pagemove plugin + * Get the filenames for the metadata of the move plugin * * @return array The file names for opts, pagelist and medialist */ protected function get_namespace_meta_files() { global $conf; return array( - 'opts' => $conf['metadir'].'/__pagemove_opts', - 'pagelist' => $conf['metadir'].'/__pagemove_pagelist', - 'medialist' => $conf['metadir'].'/__pagemove_medialist' + 'opts' => $conf['metadir'].'/__move_opts', + 'pagelist' => $conf['metadir'].'/__move_pagelist', + 'medialist' => $conf['metadir'].'/__move_medialist' ); } @@ -379,7 +379,7 @@ public function move_page(&$opts, $checkonly = false) { * End of init (checks) */ - $page_meta = p_get_metadata($ID, 'plugin_pagemove', METADATA_DONT_RENDER); + $page_meta = p_get_metadata($ID, 'plugin_move', METADATA_DONT_RENDER); if (!$page_meta) $page_meta = array(); if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); $page_meta['old_ids'][$ID] = time(); @@ -392,7 +392,7 @@ public function move_page(&$opts, $checkonly = false) { // 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 - $event = new Doku_Event('PAGEMOVE_PAGE_RENAME', $data); + $event = new Doku_Event('MOVE_PAGE_RENAME', $data); if ($event->advise_before()) { // Open the old document and change forward links lock($ID); @@ -405,7 +405,7 @@ public function move_page(&$opts, $checkonly = false) { 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 + $Indexer = new helper_plugin_move_indexer(); // copy of the new code } if (($idx_msg = $Indexer->renamePage($ID, $opts['new_id'])) !== true || ($idx_msg = $Indexer->renameMetaValue('relation_references', $ID, $opts['new_id'])) !== true) { @@ -448,16 +448,16 @@ public function move_page(&$opts, $checkonly = false) { foreach ($affected_pages as $id) { if (!page_exists($id, '', false) || $id == $ID || $id == $opts['new_id']) continue; // we are only interested in persistent metadata, so no need to render anything. - $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); + $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); if (!$meta) $meta = array('moves' => array()); if (!isset($meta['moves'])) $meta['moves'] = array(); $meta['moves'] = $this->resolve_moves($meta['moves'], $id); $meta['moves'][$ID] = $opts['new_id']; //if (empty($meta['moves'])) unset($meta['moves']); - p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); + p_set_metadata($id, array('plugin_move' => $meta), false, true); } - p_set_metadata($opts['new_id'], array('plugin_pagemove' => $page_meta), false, true); + p_set_metadata($opts['new_id'], array('plugin_move' => $page_meta), false, true); unlock($ID); } @@ -523,13 +523,13 @@ public function move_media(&$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 - $event = new Doku_Event('PAGEMOVE_MEDIA_RENAME', $data); + $event = new Doku_Event('MOVE_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 + $Indexer = new helper_plugin_move_indexer(); // copy of the new code } if (($idx_msg = $Indexer->renameMetaValue('relation_media', $opts['id'], $opts['new_id'])) !== true) { msg('Error while updating the search index '.$idx_msg, -1); @@ -559,13 +559,13 @@ public function move_media(&$opts, $checkonly = false) { 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); + $meta = p_get_metadata($id, 'plugin_move', 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); + p_set_metadata($id, array('plugin_move' => $meta), false, true); } } @@ -576,7 +576,7 @@ public function move_media(&$opts, $checkonly = false) { /** * 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) + * @param array $opts Move options (used here: name, newname, ns, newns) * @return bool If the attic files were moved successfully */ public function movemediaattic($opts) { @@ -607,7 +607,7 @@ public function movemediaattic($opts) { /** * Move the meta files of the page that is specified in the options. * - * @param array $opts Pagemove options (used here: name, newname, ns, newns) + * @param array $opts Move options (used here: name, newname, ns, newns) * @return bool If the meta files were moved successfully */ public function movemediameta($opts) { @@ -620,7 +620,7 @@ public function movemediameta($opts) { /** * Move the old revisions of the page that is specified in the options. * - * @param array $opts Pagemove options (used here: name, newname, ns, newns) + * @param array $opts Move options (used here: name, newname, ns, newns) * @return bool If the attic files were moved successfully */ public function moveattic($opts) { @@ -633,7 +633,7 @@ public function moveattic($opts) { /** * Move the meta files of the page that is specified in the options. * - * @param array $opts Pagemove options (used here: name, newname, ns, newns) + * @param array $opts Move options (used here: name, newname, ns, newns) * @return bool If the meta files were moved successfully */ public function movemeta($opts) { @@ -647,7 +647,7 @@ public function movemeta($opts) { * Internal function for moving and renaming meta/attic files between namespaces * * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] - * @param array $opts Pagemove options (used here: ns, newns, name, newname) + * @param array $opts Move options (used here: ns, newns, name, newname) * @param string $extregex Regular expression for matching the extension of the file that shall be moved * @return bool If the files were moved successfully */ @@ -694,7 +694,7 @@ private function move_files($dir, $opts, $extregex) { * @return string The rewritten content */ public function execute_rewrites($id, $text = null) { - $meta = p_get_metadata($id, 'plugin_pagemove', METADATA_DONT_RENDER); + $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { if(is_null($text)) $text = rawWiki($id); $moves = isset($meta['moves']) ? $meta['moves'] : array(); @@ -713,7 +713,7 @@ public function execute_rewrites($id, $text = null) { } unset($meta['moves']); unset($meta['media_moves']); - p_set_metadata($id, array('plugin_pagemove' => $meta), false, true); + p_set_metadata($id, array('plugin_move' => $meta), false, true); } else { // FIXME: print error here or fail silently? msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); } @@ -739,7 +739,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { $data = array('id' => $id, 'moves' => &$moves, 'handlers' => &$handlers); /* - * PAGEMOVE_HANDLERS REGISTER event: + * MOVE_HANDLERS REGISTER event: * * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler * The handler needs to be a valid callback, it will get the following parameters: @@ -752,7 +752,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { * - moves: array of moves, the same as $moves in the event * - adaptRelativeId($id): adapts the relative $id according to the moves */ - trigger_event('PAGEMOVE_HANDLERS_REGISTER', $data); + trigger_event('MOVE_HANDLERS_REGISTER', $data); $modes = p_get_parsermodes(); @@ -760,7 +760,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { $Parser = new Doku_Parser(); // Add the Handler - $Parser->Handler = new helper_plugin_pagemove_handler($id, $moves, $media_moves, $handlers); + $Parser->Handler = new helper_plugin_move_handler($id, $moves, $media_moves, $handlers); //add modes to parser foreach($modes as $mode) { @@ -820,14 +820,14 @@ public function getNSMoveButton($action, $id = NULL) { $id = $ID; } - $class = 'pagemove__nsform'; + $class = 'move__nsform'; switch ($action) { case 'continue': case 'tryagain': - $class .= ' pagemove__nscontinue'; + $class .= ' move__nscontinue'; break; case 'skip': - $class .= ' pagemove__nsskip'; + $class .= ' move__nsskip'; break; } @@ -860,9 +860,9 @@ public function getNSMoveButton($action, $id = NULL) { } /** - * Indexer class extended by pagemove features, only needed and used in releases older than Spring 2013 + * Indexer class extended by move features, only needed and used in releases older than Spring 2013 */ -class helper_plugin_pagemove_indexer extends Doku_Indexer { +class helper_plugin_move_indexer extends Doku_Indexer { /** * Rename a page in the search index without changing the indexed content * @@ -963,9 +963,9 @@ public function renameMetaValue($key, $oldvalue, $newvalue) { } /** - * Handler class for pagemove. It does the actual rewriting of the content. + * Handler class for move. It does the actual rewriting of the content. */ -class helper_plugin_pagemove_handler { +class helper_plugin_move_handler { public $calls = ''; public $id; public $ns; @@ -976,7 +976,7 @@ class helper_plugin_pagemove_handler { private $handlers; /** - * Construct the pagemove handler. + * Construct the move handler. * * @param string $id The id of the text that is passed to the handler * @param array $moves Moves that shall be considered in the form $old => $new ($old can be $id) diff --git a/lang/cs/pagemove.txt b/lang/cs/move.txt similarity index 95% rename from lang/cs/pagemove.txt rename to lang/cs/move.txt index 3e1c958..d91f12d 100644 --- a/lang/cs/pagemove.txt +++ b/lang/cs/move.txt @@ -1,4 +1,4 @@ -====== Pagemove ====== +====== Move ====== Pomocí tohoto pluginu lze přesunout nebo přejmenovat aktuální stránku. Platí však jistá omezení: diff --git a/lang/de/lang.php b/lang/de/lang.php index b3f5559..15417d9 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -29,7 +29,7 @@ $lang['pm_renamed'] = 'Seitename wurde von %s auf %s geändert'; $lang['pm_moved'] = 'Seite von %s nach %s verschoben'; $lang['pm_move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; -$lang['pm_delete'] = 'Gelöscht durch das pagemove Plugin'; +$lang['pm_delete'] = 'Gelöscht durch das move Plugin'; $lang['pm_norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; $lang['pm_nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; $lang['pm_notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; diff --git a/lang/de/pagemove.txt b/lang/de/move.txt similarity index 100% rename from lang/de/pagemove.txt rename to lang/de/move.txt diff --git a/lang/en/lang.php b/lang/en/lang.php index 10280f9..5549b05 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -29,13 +29,13 @@ $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_delete'] = 'Deleted by move plugin'; $lang['pm_norights'] = 'You have insufficient permissions to edit %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 adapted because of a pagemove operation'; +$lang['pm_linkchange'] = 'Links adapted because of a move operation'; $lang['pm_ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; $lang['pm_ns_move_continue'] = 'Continue the namespace move'; diff --git a/lang/en/pagemove.txt b/lang/en/move.txt similarity index 96% rename from lang/en/pagemove.txt rename to lang/en/move.txt index cfc7faa..59bceff 100644 --- a/lang/en/pagemove.txt +++ b/lang/en/move.txt @@ -1,4 +1,4 @@ -====== Pagemove ====== +====== Move ====== This plugin allows you to move and/or rename the current page or move and/or rename the current namespace within the following restrictions: diff --git a/lang/es/pagemove.txt b/lang/es/move.txt similarity index 96% rename from lang/es/pagemove.txt rename to lang/es/move.txt index 16f5035..d1f364f 100644 --- a/lang/es/pagemove.txt +++ b/lang/es/move.txt @@ -1,4 +1,4 @@ -====== Pagemove ====== +====== Move ====== Esta extensión le permite mover y/o renombrar el documento actual respetando las siguientes restricciones. diff --git a/lang/fr/pagemove.txt b/lang/fr/move.txt similarity index 96% rename from lang/fr/pagemove.txt rename to lang/fr/move.txt index 5e588bc..f9a5c69 100644 --- a/lang/fr/pagemove.txt +++ b/lang/fr/move.txt @@ -1,4 +1,4 @@ -====== Pagemove ====== +====== Move ====== Ce plugin permet de déplacer et/ou renommer le document courant, avec les limitations suivantes : * Il faut avoir les droits d'édition sur le document diff --git a/lang/lv/pagemove.txt b/lang/lv/move.txt similarity index 100% rename from lang/lv/pagemove.txt rename to lang/lv/move.txt diff --git a/lang/nl/pagemove.txt b/lang/nl/move.txt similarity index 100% rename from lang/nl/pagemove.txt rename to lang/nl/move.txt diff --git a/lang/pl/pagemove.txt b/lang/pl/move.txt similarity index 95% rename from lang/pl/pagemove.txt rename to lang/pl/move.txt index 73705f0..f20ba9e 100644 --- a/lang/pl/pagemove.txt +++ b/lang/pl/move.txt @@ -1,4 +1,4 @@ -====== Pagemove ====== +====== Move ====== Ta wtyczka umożliwia przeniesienie lub zmianę nazwy dokumentu z poniższymi zastrzeżeniami: diff --git a/lang/ru/pagemove.txt b/lang/ru/move.txt similarity index 100% rename from lang/ru/pagemove.txt rename to lang/ru/move.txt diff --git a/lang/sl/pagemove.txt b/lang/sl/move.txt similarity index 95% rename from lang/sl/pagemove.txt rename to lang/sl/move.txt index c466208..b856c15 100644 --- a/lang/sl/pagemove.txt +++ b/lang/sl/move.txt @@ -1,4 +1,4 @@ -====== Pagemove ====== +====== Move ====== Ta plugin omogoča premikanje in/ali preimenovanje trenutnega dokumenta v okviru naslednjih omejitev: diff --git a/plugin.info.txt b/plugin.info.txt index 233e5d9..9927193 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ -base pagemove +base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de date 2013-10-29 -name Pagemove plugin -desc Move and rename pages and namespaces whilst maintaining the links. -url http://www.dokuwiki.org/plugin:pagemove +name Move plugin +desc Move and rename pages and media files whilst maintaining the links. +url http://www.dokuwiki.org/plugin:move diff --git a/script.js b/script.js index 39bd671..de828b1 100644 --- a/script.js +++ b/script.js @@ -1,11 +1,11 @@ /** - * JavasScript code for the preview in the pagemove plugin + * JavasScript code for the preview in the move plugin * * @author Michael Hamann */ jQuery(function() { - jQuery('form.pagemove__form').each(function() { + jQuery('form.move__form').each(function() { var $this = jQuery(this); var $preview = jQuery('

'); $this.find('input[type=submit]').before($preview); @@ -19,7 +19,7 @@ jQuery(function() { } else { previewns = targetns + ':' + newnsname; } - $preview.text(LANG['plugins']['pagemove']['pm_previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); + $preview.text(LANG['plugins']['move']['pm_previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); } else { var ns_for_page = $this.find('select[name=ns_for_page]').val(); var newns = $this.find('input[name=newns]').val(); @@ -34,7 +34,7 @@ jQuery(function() { newid = ns_for_page + ':'; } newid += newname; - $preview.text(LANG['plugins']['pagemove']['pm_previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); + $preview.text(LANG['plugins']['move']['pm_previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); } }; @@ -43,9 +43,9 @@ jQuery(function() { $this.find('input').keyup(updatePreview); }); - jQuery('form.pagemove__nscontinue').each(function() { + jQuery('form.move__nscontinue').each(function() { var $this = jQuery(this); - var $container = jQuery('div.plugin__pagemove_forms'); + var $container = jQuery('div.plugin__move_forms'); var submit_handler = function() { $container.empty(); var $progressbar = jQuery('
'); @@ -53,13 +53,13 @@ jQuery(function() { $progressbar.progressbar({value: false}); var $message = jQuery('
'); $container.append($message); - var skip = jQuery(this).hasClass('pagemove__nsskip'); + var skip = jQuery(this).hasClass('move__nsskip'); var continue_move = function() { jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { - call: 'plugin_pagemove_ns_continue', + call: 'plugin_move_ns_continue', id: JSINFO['id'], skip: skip }, @@ -72,7 +72,7 @@ jQuery(function() { } $message.html(data.html); if (data.remaining === false) { - $container.find('form.pagemove__nscontinue, form.pagemove__nsskip').submit(submit_handler); + $container.find('form.move__nscontinue, form.move__nsskip').submit(submit_handler); } else if (data.remaining === 0) { window.location.href = data.redirect_url; } else { From d778d3fefa652474e7b6fca3c7bdec13bf139069 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Wed, 20 Nov 2013 22:07:12 +0100 Subject: [PATCH 050/338] Remove the "pm_" prefix from all language string identifiers The prefix was still a leftover from the old pagemove plugin and isn't needed at all. --- action.php | 4 +-- admin.php | 42 ++++++++++++------------ helper.php | 40 +++++++++++------------ lang/cs/lang.php | 28 ++++++++-------- lang/de/lang.php | 76 +++++++++++++++++++++---------------------- lang/en/lang.php | 84 ++++++++++++++++++++++++------------------------ lang/es/lang.php | 28 ++++++++-------- lang/fr/lang.php | 26 +++++++-------- lang/lv/lang.php | 28 ++++++++-------- lang/nl/lang.php | 26 +++++++-------- lang/pl/lang.php | 28 ++++++++-------- lang/ru/lang.php | 28 ++++++++-------- lang/sl/lang.php | 28 ++++++++-------- lang/zh/lang.php | 28 ++++++++-------- script.js | 4 +-- 15 files changed, 249 insertions(+), 249 deletions(-) diff --git a/action.php b/action.php index f50166b..7e4fc06 100644 --- a/action.php +++ b/action.php @@ -194,12 +194,12 @@ public function handle_ajax_call(Doku_Event $event, $params) { ob_start(); html_msgarea(); if ($remaining === false) { - ptln('

'.sprintf($this->getLang('pm_ns_move_error'), $opts['ns'], $opts['newns']).'

'); + ptln('

'.sprintf($this->getLang('ns_move_error'), $opts['ns'], $opts['newns']).'

'); echo $helper->getNSMoveButton('tryagain', $id); echo $helper->getNSMoveButton('skip', $id); echo $helper->getNSMoveButton('abort', $id); } else { - ptln('

'.sprintf($this->getLang('pm_ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

'); + ptln('

'.sprintf($this->getLang('ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

'); } $result['html'] = ob_get_clean(); } else { diff --git a/admin.php b/admin.php index 5af8747..dcbf2be 100644 --- a/admin.php +++ b/admin.php @@ -51,9 +51,9 @@ function getMenuText() { global $INFO; if( !$INFO['exists'] ) - return $this->getLang('menu').' ('.sprintf($this->getLang('pm_notexist'), $INFO['id']).')'; + return $this->getLang('menu').' ('.sprintf($this->getLang('notexist'), $INFO['id']).')'; elseif( !$INFO['writable'] ) - return $this->getLang('menu').' ('.$this->getLang('pm_notwrite').')'; + return $this->getLang('menu').' ('.$this->getLang('notwrite').')'; else return $this->getLang('menu'); } @@ -75,14 +75,14 @@ function html() { switch ($this->ns_move_state) { case 'started': ptln('

'); - ptln(sprintf($this->getLang('pm_ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); + ptln(sprintf($this->getLang('ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); ptln('

'); ptln($this->helper->getNSMoveButton('continue')); ptln($this->helper->getNSMoveButton('abort')); break; case 'error': ptln('

'); - ptln(sprintf($this->getLang('pm_ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); + ptln(sprintf($this->getLang('ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); ptln('

'); ptln($this->helper->getNSMoveButton('tryagain')); ptln($this->helper->getNSMoveButton('skip')); @@ -90,7 +90,7 @@ function html() { break; case 'continued': ptln('

'); - ptln(sprintf($this->getLang('pm_ns_move_continued'), $this->ns_opts['ns'], $this->ns_opts['newns'], $this->ns_opts['remaining'])); + ptln(sprintf($this->getLang('ns_move_continued'), $this->ns_opts['ns'], $this->ns_opts['newns'], $this->ns_opts['remaining'])); ptln('

'); ptln($this->helper->getNSMoveButton('continue')); @@ -120,21 +120,21 @@ function printForm() { $form->addHidden('page', $this->getPluginName()); $form->addHidden('id', $ID); $form->addHidden('move_type', 'page'); - $form->startFieldset($this->getLang('pm_movepage')); - $form->addElement(form_makeMenuField('ns_for_page', $ns_select_data, $this->opts['ns_for_page'], $this->getLang('pm_targetns'), '', 'block')); - $form->addElement(form_makeTextField('newns', $this->opts['newns'], $this->getLang('pm_newtargetns'), '', 'block')); - $form->addElement(form_makeTextField('newname', $this->opts['newname'], $this->getLang('pm_newname'), '', 'block')); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); + $form->startFieldset($this->getLang('movepage')); + $form->addElement(form_makeMenuField('ns_for_page', $ns_select_data, $this->opts['ns_for_page'], $this->getLang('targetns'), '', 'block')); + $form->addElement(form_makeTextField('newns', $this->opts['newns'], $this->getLang('newtargetns'), '', 'block')); + $form->addElement(form_makeTextField('newname', $this->opts['newname'], $this->getLang('newname'), '', 'block')); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); $form->endFieldset(); $form->printForm(); if ($this->ns_opts !== false) { ptln('
'); ptln(''); - ptln($this->getLang('pm_movens')); + ptln($this->getLang('movens')); ptln(''); ptln('

'); - ptln(sprintf($this->getLang('pm_ns_move_in_progress'), $this->ns_opts['num_pages'], $this->ns_opts['num_media'], ':'.hsc($this->ns_opts['ns']), ':'.hsc($this->ns_opts['newns']))); + ptln(sprintf($this->getLang('ns_move_in_progress'), $this->ns_opts['num_pages'], $this->ns_opts['num_media'], ':'.hsc($this->ns_opts['ns']), ':'.hsc($this->ns_opts['newns']))); ptln('

'); ptln($this->helper->getNSMoveButton('continue')); ptln($this->helper->getNSMoveButton('abort')); @@ -144,11 +144,11 @@ function printForm() { $form->addHidden('page', $this->getPluginName()); $form->addHidden('id', $ID); $form->addHidden('move_type', 'namespace'); - $form->startFieldset($this->getLang('pm_movens')); - $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('pm_targetns'), '', 'block')); - $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('pm_newnsname'), '', 'block')); - $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('pm_move_pages'), 'media' => $this->getLang('pm_move_media'), 'both' => $this->getLang('pm_move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('pm_content_to_move'), '', 'block')); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_submit'))); + $form->startFieldset($this->getLang('movens')); + $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('targetns'), '', 'block')); + $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('newnsname'), '', 'block')); + $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); $form->endFieldset(); $form->printForm(); } @@ -160,7 +160,7 @@ function printForm() { * * @author Michael Hamann * @author Gary Owen - * @author Arno Puschmann (bin out of _pm_form) + * @author Arno Puschmann (bin out of _form) */ private function build_namespace_select_content($ns) { global $conf; @@ -173,8 +173,8 @@ private function build_namespace_select_content($ns) { foreach($namesp as $row) { if ( auth_quickaclcheck($row['id'].':*') >= AUTH_CREATE || $row['id'] == $ns ) { - $result[($row['id'] ? $row['id'] : ':')] = ($row['id'] ? $row['id'].':' : ": ".$this->getLang('pm_root')). - ($row['id'] == $ns ? ' '.$this->getLang('pm_current') : ''); + $result[($row['id'] ? $row['id'] : ':')] = ($row['id'] ? $row['id'].':' : ": ".$this->getLang('root')). + ($row['id'] == $ns ? ' '.$this->getLang('current') : ''); } } return $result; @@ -258,7 +258,7 @@ function handle() { } else { // check that the pagename is valid if ($this->opts['newname'] == '' ) { - msg($this->getLang('pm_badname'), -1); + msg($this->getLang('badname'), -1); return; } diff --git a/helper.php b/helper.php index ccb7359..b9d07a0 100644 --- a/helper.php +++ b/helper.php @@ -335,11 +335,11 @@ public function move_page(&$opts, $checkonly = false) { // Check we have rights to move this document if ( !page_exists($ID)) { - msg(sprintf($this->getLang('pm_notexist'), $ID), -1); + msg(sprintf($this->getLang('notexist'), $ID), -1); return false; } if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { - msg(sprintf($this->getLang('pm_norights'), hsc($ID)), -1); + msg(sprintf($this->getLang('norights'), hsc($ID)), -1); return false; } @@ -348,7 +348,7 @@ public function move_page(&$opts, $checkonly = false) { // the file exists check checks if the page is reported unlocked if a lock exists which means that // the page is locked by the current user if (checklock($ID) !== false || @file_exists(wikiLockFN($ID))) { - msg( sprintf($this->getLang('pm_filelocked'), hsc($ID)), -1); + msg( sprintf($this->getLang('filelocked'), hsc($ID)), -1); return false; } @@ -358,18 +358,18 @@ public function move_page(&$opts, $checkonly = false) { // Has the document name and/or namespace changed? if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { - msg($this->getLang('pm_nochange'), -1); + msg($this->getLang('nochange'), -1); return false; } // Check the page does not already exist if ( @file_exists($opts['new_path']) ) { - msg(sprintf($this->getLang('pm_existing'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('pm_root') : $opts['newns'])), -1); + msg(sprintf($this->getLang('existing'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('root') : $opts['newns'])), -1); return false; } // Check if the current user can create the new page if (auth_quickaclcheck($opts['new_id']) < AUTH_CREATE) { - msg(sprintf($this->getLang('pm_notargetperms'), $opts['new_id']), -1); + msg(sprintf($this->getLang('notargetperms'), $opts['new_id']), -1); return false; } @@ -419,13 +419,13 @@ public function move_page(&$opts, $checkonly = false) { // Save the updated document in its new location if ($opts['ns'] == $opts['newns']) { - $lang_key = 'pm_renamed'; + $lang_key = 'renamed'; } elseif ( $opts['name'] == $opts['newname'] ) { - $lang_key = 'pm_moved'; + $lang_key = 'moved'; } else { - $lang_key = 'pm_move_rename'; + $lang_key = 'move_rename'; } // Wait a second when the page has just been rewritten @@ -436,7 +436,7 @@ public function move_page(&$opts, $checkonly = false) { // Delete the orginal file if (@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($ID, '', $this->getLang('pm_delete') ); + saveWikiText($ID, '', $this->getLang('delete') ); } // Move the old revisions @@ -481,12 +481,12 @@ public function move_media(&$opts, $checkonly = false) { // Check we have rights to move this document if ( !file_exists(mediaFN($opts['id']))) { - msg(sprintf($this->getLang('pm_medianotexist'), hsc($opts['id'])), -1); + msg(sprintf($this->getLang('medianotexist'), hsc($opts['id'])), -1); return false; } if ( auth_quickaclcheck($opts['ns'].':*') < AUTH_DELETE ) { - msg(sprintf($this->getLang('pm_nomediarights'), hsc($opts['id'])), -1); + msg(sprintf($this->getLang('nomediarights'), hsc($opts['id'])), -1); return false; } @@ -496,18 +496,18 @@ public function move_media(&$opts, $checkonly = false) { // Has the document name and/or namespace changed? if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { - msg($this->getLang('pm_nomediachange'), -1); + msg($this->getLang('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); + msg(sprintf($this->getLang('mediaexisting'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('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); + msg(sprintf($this->getLang('nomediatargetperms'), $opts['new_id']), -1); return false; } @@ -709,7 +709,7 @@ public function execute_rewrites($id, $text = null) { // Wait a second if page has just been saved $oldRev = getRevisions($id, -1, 1, 1024); // from changelog if ($oldRev == time()) sleep(1); - saveWikiText($id, $text, $this->getLang('pm_linkchange')); + saveWikiText($id, $text, $this->getLang('linkchange')); } unset($meta['moves']); unset($meta['media_moves']); @@ -839,18 +839,18 @@ public function getNSMoveButton($action, $id = NULL) { case 'tryagain': $form->addHidden('continue_namespace_move', true); if ($action == 'tryagain') { - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_tryagain'))); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_tryagain'))); } else { - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_continue'))); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_continue'))); } break; case 'skip': $form->addHidden('skip_continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_skip'))); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_skip'))); break; case 'abort': $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('pm_ns_move_abort'))); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_abort'))); break; default: return false; diff --git a/lang/cs/lang.php b/lang/cs/lang.php index 5995062..8ee528e 100644 --- a/lang/cs/lang.php +++ b/lang/cs/lang.php @@ -15,19 +15,19 @@ $lang['menu'] = 'Přesun/přejmenování stránky'; $lang['desc'] = 'Plugin pro přesun/přejmenování stránku'; -//$lang['pm_notexist'] = 'Toto téma ještě neexistuje'; -$lang['pm_notwrite'] = 'Nemáte dostatečná oprávnění pro úpravu stránky'; -$lang['pm_badns'] = 'Neplatný název jmenného prostoru'; -$lang['pm_badname'] = 'Neplatný název stránky'; -$lang['pm_nochange'] = 'Jméno stránky a jmenného prostoru se nezměnilo'; -$lang['pm_existing1'] = 'Stránka %s již existuje v %s'; -$lang['pm_root'] = '[Kořen]'; -$lang['pm_current'] = '(Současný)'; -//$lang['pm_norights'] = 'Nemáte právo editovat jednu nebo více odkazujících stránek'; -$lang['pm_filelocked'] = 'Tento soubor je uzamčen - zkuste prosím znovu později'; -$lang['pm_linkchange1'] = 'Odkazy na %s změněny na %s'; -$lang['pm_newname'] = 'Nový název stránky :'; -$lang['pm_targetns'] = 'Cílový jmenný prostor :'; -$lang['pm_submit'] = 'Potvrdit'; +//$lang['notexist'] = 'Toto téma ještě neexistuje'; +$lang['notwrite'] = 'Nemáte dostatečná oprávnění pro úpravu stránky'; +$lang['badns'] = 'Neplatný název jmenného prostoru'; +$lang['badname'] = 'Neplatný název stránky'; +$lang['nochange'] = 'Jméno stránky a jmenného prostoru se nezměnilo'; +$lang['existing1'] = 'Stránka %s již existuje v %s'; +$lang['root'] = '[Kořen]'; +$lang['current'] = '(Současný)'; +//$lang['norights'] = 'Nemáte právo editovat jednu nebo více odkazujících stránek'; +$lang['filelocked'] = 'Tento soubor je uzamčen - zkuste prosím znovu později'; +$lang['linkchange1'] = 'Odkazy na %s změněny na %s'; +$lang['newname'] = 'Nový název stránky :'; +$lang['targetns'] = 'Cílový jmenný prostor :'; +$lang['submit'] = 'Potvrdit'; diff --git a/lang/de/lang.php b/lang/de/lang.php index 15417d9..e2d2b30 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -15,44 +15,44 @@ $lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; $lang['desc'] = 'Seite/Namespace verschieben/umbenennen... Plugin'; -$lang['pm_notexist'] = 'Die Seite %s existiert nicht.'; -$lang['pm_medianotexist'] = 'Die Mediendatei %s existiert nicht'; -$lang['pm_notwrite'] = 'Sie haben unzureichende Rechte um diese Seite zu ändern'; -$lang['pm_badns'] = 'Ungültige Zeichen in der Namensraum-Bezeichnung.'; -$lang['pm_badname'] = 'Ungültiges Zeichen im Seitennamen.'; -$lang['pm_nochange'] = 'Name und Namensraum der Seite sind unverändert.'; -$lang['pm_nomediachange'] = 'Name und Namensraum der Mediendatei sind unverändert.'; -$lang['pm_existing'] = 'Eine Seite mit der Bezeichnung %s existiert bereits in %s'; -$lang['pm_mediaexisting'] = 'Eine Mediendatei mit der Bezeichnung %s existiert bereits in %s'; -$lang['pm_root'] = '[Wurzel des Namensraumes / Root namespace]'; -$lang['pm_current'] = '(Aktueller)'; -$lang['pm_renamed'] = 'Seitename wurde von %s auf %s geändert'; -$lang['pm_moved'] = 'Seite von %s nach %s verschoben'; -$lang['pm_move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; -$lang['pm_delete'] = 'Gelöscht durch das move Plugin'; -$lang['pm_norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; -$lang['pm_nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; -$lang['pm_notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; -$lang['pm_nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; -$lang['pm_filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; -$lang['pm_linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; +$lang['notexist'] = 'Die Seite %s existiert nicht.'; +$lang['medianotexist'] = 'Die Mediendatei %s existiert nicht'; +$lang['notwrite'] = 'Sie haben unzureichende Rechte um diese Seite zu ändern'; +$lang['badns'] = 'Ungültige Zeichen in der Namensraum-Bezeichnung.'; +$lang['badname'] = 'Ungültiges Zeichen im Seitennamen.'; +$lang['nochange'] = 'Name und Namensraum der Seite sind unverändert.'; +$lang['nomediachange'] = 'Name und Namensraum der Mediendatei sind unverändert.'; +$lang['existing'] = 'Eine Seite mit der Bezeichnung %s existiert bereits in %s'; +$lang['mediaexisting'] = 'Eine Mediendatei mit der Bezeichnung %s existiert bereits in %s'; +$lang['root'] = '[Wurzel des Namensraumes / Root namespace]'; +$lang['current'] = '(Aktueller)'; +$lang['renamed'] = 'Seitename wurde von %s auf %s geändert'; +$lang['moved'] = 'Seite von %s nach %s verschoben'; +$lang['move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; +$lang['delete'] = 'Gelöscht durch das move Plugin'; +$lang['norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; +$lang['nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; +$lang['notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; +$lang['nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; +$lang['filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; +$lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; -$lang['pm_ns_move_in_progress'] = 'Das Verschieben von %s Seiten und %s Mediendateien vom Namensraum %s nach %s ist derzeit im Gange.'; -$lang['pm_ns_move_continue'] = 'Das Verschieben des Namensraumes fortsetzen'; -$lang['pm_ns_move_abort'] = 'Das Verschieben des Namensraumes abbrechen'; -$lang['pm_ns_move_continued'] = 'Das Verschieben des Namensraumes %s nach %s wurde fortgesetzt, %s Einträge müssen noch verschoben werden.'; -$lang['pm_ns_move_started'] = 'Das Verschieben des Namensraumes %s nach %s wurde begonnen, %s Seiten und %s Mediendateien werden verschoben werden.'; -$lang['pm_ns_move_error'] = 'Ein Fehler ist beim Verschieben des Namensraumes %s nach %s aufgetreten.'; -$lang['pm_ns_move_tryagain'] = 'Nochmal versuchen'; -$lang['pm_ns_move_skip'] = 'Den aktuellen Eintrag überspringen'; +$lang['ns_move_in_progress'] = 'Das Verschieben von %s Seiten und %s Mediendateien vom Namensraum %s nach %s ist derzeit im Gange.'; +$lang['ns_move_continue'] = 'Das Verschieben des Namensraumes fortsetzen'; +$lang['ns_move_abort'] = 'Das Verschieben des Namensraumes abbrechen'; +$lang['ns_move_continued'] = 'Das Verschieben des Namensraumes %s nach %s wurde fortgesetzt, %s Einträge müssen noch verschoben werden.'; +$lang['ns_move_started'] = 'Das Verschieben des Namensraumes %s nach %s wurde begonnen, %s Seiten und %s Mediendateien werden verschoben werden.'; +$lang['ns_move_error'] = 'Ein Fehler ist beim Verschieben des Namensraumes %s nach %s aufgetreten.'; +$lang['ns_move_tryagain'] = 'Nochmal versuchen'; +$lang['ns_move_skip'] = 'Den aktuellen Eintrag überspringen'; // Form labels -$lang['pm_newname'] = 'Neuer Seitenname:'; -$lang['pm_newnsname'] = 'Neuer Name für Namensraum:'; -$lang['pm_targetns'] = 'Wählen Sie einen neuen Namensraum: '; -$lang['pm_newtargetns'] = 'Erstellen Sie einen neuen Namensraum'; -$lang['pm_movepage'] = 'Seite verschieben'; -$lang['pm_movens'] = 'Namensraum verschieben'; -$lang['pm_submit'] = 'Übernehmen'; +$lang['newname'] = 'Neuer Seitenname:'; +$lang['newnsname'] = 'Neuer Name für Namensraum:'; +$lang['targetns'] = 'Wählen Sie einen neuen Namensraum: '; +$lang['newtargetns'] = 'Erstellen Sie einen neuen Namensraum'; +$lang['movepage'] = 'Seite verschieben'; +$lang['movens'] = 'Namensraum verschieben'; +$lang['submit'] = 'Übernehmen'; // JavaScript preview -$lang['js']['pm_previewpage'] = 'OLDPAGE wird in NEWPAGE umbenannt'; -$lang['js']['pm_previewns'] = 'Alle Seiten und Namensräume im Namensraum OLDNS werden in den Namensraum NEWNS verschoben'; +$lang['js']['previewpage'] = 'OLDPAGE wird in NEWPAGE umbenannt'; +$lang['js']['previewns'] = 'Alle Seiten und Namensräume im Namensraum OLDNS werden in den Namensraum NEWNS verschoben'; diff --git a/lang/en/lang.php b/lang/en/lang.php index 5549b05..0ed8aa5 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -15,48 +15,48 @@ $lang['menu'] = 'Page/Namespace Move/Rename...'; $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 move plugin'; -$lang['pm_norights'] = 'You have insufficient permissions to edit %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 adapted because of a move operation'; +$lang['notexist'] = 'The page %s does not exist'; +$lang['medianotexist'] = 'The media file %s does not exist'; +$lang['notwrite'] = 'You do not have sufficient permissions to modify this page'; +$lang['badns'] = 'Invalid characters in namespace.'; +$lang['badname'] = 'Invalid characters in pagename.'; +$lang['nochange'] = 'Page name and namespace are unchanged.'; +$lang['nomediachange'] = 'Media file name and namespace are unchanged.'; +$lang['existing'] = 'A page called %s already exists in %s'; +$lang['mediaexisting'] = 'A media file called %s already exists in %s'; +$lang['root'] = '[Root namespace]'; +$lang['current'] = '(Current)'; +$lang['renamed'] = 'Page name changed from %s to %s'; +$lang['moved'] = 'Page moved from %s to %s'; +$lang['move_rename'] = 'Page moved and renamed from %s to %s'; +$lang['delete'] = 'Deleted by move plugin'; +$lang['norights'] = 'You have insufficient permissions to edit %s.'; +$lang['nomediarights'] = 'You have insufficient permissions to delete %s.'; +$lang['notargetperms'] = 'You don\'t have the permission to create the page %s.'; +$lang['nomediatargetperms'] = 'You don\'t have the permission to create the media file %s.'; +$lang['filelocked'] = 'The page %s is locked. Try again later.'; +$lang['linkchange'] = 'Links adapted because of a move operation'; -$lang['pm_ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; -$lang['pm_ns_move_continue'] = 'Continue the namespace move'; -$lang['pm_ns_move_abort'] = 'Abort the namespace move'; -$lang['pm_ns_move_continued'] = 'The namespace move from namespace %s to namespace %s was continued, %s items are still remaining.'; -$lang['pm_ns_move_started'] = 'A namespace move from namespace %s to namespace %s was started, %s pages and %s media files will be moved.'; -$lang['pm_ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; -$lang['pm_ns_move_tryagain'] = 'Try again'; -$lang['pm_ns_move_skip'] = 'Skip the current item'; +$lang['ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; +$lang['ns_move_continue'] = 'Continue the namespace move'; +$lang['ns_move_abort'] = 'Abort the namespace move'; +$lang['ns_move_continued'] = 'The namespace move from namespace %s to namespace %s was continued, %s items are still remaining.'; +$lang['ns_move_started'] = 'A namespace move from namespace %s to namespace %s was started, %s pages and %s media files will be moved.'; +$lang['ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; +$lang['ns_move_tryagain'] = 'Try again'; +$lang['ns_move_skip'] = 'Skip the current item'; // Form labels -$lang['pm_newname'] = 'New page name:'; -$lang['pm_newnsname'] = 'New namespace name:'; -$lang['pm_targetns'] = 'Select new namespace:'; -$lang['pm_newtargetns'] = 'Create a new namespace:'; -$lang['pm_movepage'] = 'Move page'; -$lang['pm_movens'] = 'Move namespace'; -$lang['pm_submit'] = 'Submit'; -$lang['pm_content_to_move'] = 'Content to move'; -$lang['pm_move_pages'] = 'Pages'; -$lang['pm_move_media'] = 'Media files'; -$lang['pm_move_media_and_pages'] = 'Pages and media files'; +$lang['newname'] = 'New page name:'; +$lang['newnsname'] = 'New namespace name:'; +$lang['targetns'] = 'Select new namespace:'; +$lang['newtargetns'] = 'Create a new namespace:'; +$lang['movepage'] = 'Move page'; +$lang['movens'] = 'Move namespace'; +$lang['submit'] = 'Submit'; +$lang['content_to_move'] = 'Content to move'; +$lang['move_pages'] = 'Pages'; +$lang['move_media'] = 'Media files'; +$lang['move_media_and_pages'] = 'Pages and media files'; // JavaScript preview -$lang['js']['pm_previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; -$lang['js']['pm_previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; +$lang['js']['previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; +$lang['js']['previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; diff --git a/lang/es/lang.php b/lang/es/lang.php index f97c31c..e94fe86 100644 --- a/lang/es/lang.php +++ b/lang/es/lang.php @@ -16,17 +16,17 @@ $lang['menu'] = 'Mover/Renombrar página...'; $lang['desc'] = 'Extensión para Mover/Renombrar páginas'; -//$lang['pm_notexist'] = 'Este tema no existe aún'; -$lang['pm_notwrite'] = 'No tiene suficientes derechos para modificar esta página'; -$lang['pm_badns'] = 'Caractéres inválidos en el Espacio de Nombres.'; -$lang['pm_badname'] = 'Caractéres inválidos en el nombre de la página.'; -$lang['pm_nochange'] = 'Los cambios en el nombre de la página y del espacio no fueron cambiados.'; -$lang['pm_existing'] = 'Un documento llamado %s ya existe en %s'; -$lang['pm_root'] = '[Espacio de Nombres Raiz]'; -$lang['pm_current'] = '(Actual)'; -//$lang['pm_norights'] = 'No tiene suficientes permisos para editar uno o mas de los punteros a este documento.'; -$lang['pm_filelocked'] = 'Este documento está bloqueado - trate de nuevo en unos minutos.'; -$lang['pm_linkchange1'] = 'Enlaces a %s cambiados a %s'; -$lang['pm_newname'] = 'Nombre del nuevo documento :'; -$lang['pm_targetns'] = 'Seleccione el Espacio de Nombres de Destino :'; -$lang['pm_submit'] = 'Enviar'; +//$lang['notexist'] = 'Este tema no existe aún'; +$lang['notwrite'] = 'No tiene suficientes derechos para modificar esta página'; +$lang['badns'] = 'Caractéres inválidos en el Espacio de Nombres.'; +$lang['badname'] = 'Caractéres inválidos en el nombre de la página.'; +$lang['nochange'] = 'Los cambios en el nombre de la página y del espacio no fueron cambiados.'; +$lang['existing'] = 'Un documento llamado %s ya existe en %s'; +$lang['root'] = '[Espacio de Nombres Raiz]'; +$lang['current'] = '(Actual)'; +//$lang['norights'] = 'No tiene suficientes permisos para editar uno o mas de los punteros a este documento.'; +$lang['filelocked'] = 'Este documento está bloqueado - trate de nuevo en unos minutos.'; +$lang['linkchange1'] = 'Enlaces a %s cambiados a %s'; +$lang['newname'] = 'Nombre del nuevo documento :'; +$lang['targetns'] = 'Seleccione el Espacio de Nombres de Destino :'; +$lang['submit'] = 'Enviar'; diff --git a/lang/fr/lang.php b/lang/fr/lang.php index b26452c..fb1fac7 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -16,17 +16,17 @@ $lang['menu'] = 'Déplacer/Renommer la page...'; $lang['desc'] = 'Plugin de Déplacement/Renommage'; -$lang['pm_notexist'] = 'Le sujet %s n\'existe pas encore'; -$lang['pm_notwrite'] = 'Vous ne disposez pas des droits suffisants pour modifier cette page'; -$lang['pm_badns'] = "Caractères invalides dans l'espace de nommage."; -$lang['pm_badname'] = 'Caractères invalides dans le nom de la page.'; -$lang['pm_nochange'] = "Le nom du document et l'espace de nomage sont inchangés."; -$lang['pm_existing'] = 'Un document appelé %s existe déjà dans %s'; -$lang['pm_root'] = '[Espace de nom racine]'; -$lang['pm_current'] = '(Courant)'; -$lang['pm_norights'] = 'Vos permissions sont insufisante pour éditer %s.'; -$lang['pm_filelocked'] = 'Ce fichier est verrouillé - réessayez plus tard.'; -$lang['pm_linkchange'] = 'Les liens vers %s ont été changés vers %s'; -$lang['pm_newname'] = 'Nouveau nom du document :'; -$lang['pm_targetns'] = 'Sélectionnez le nouvel espace de nommage :'; +$lang['notexist'] = 'Le sujet %s n\'existe pas encore'; +$lang['notwrite'] = 'Vous ne disposez pas des droits suffisants pour modifier cette page'; +$lang['badns'] = "Caractères invalides dans l'espace de nommage."; +$lang['badname'] = 'Caractères invalides dans le nom de la page.'; +$lang['nochange'] = "Le nom du document et l'espace de nomage sont inchangés."; +$lang['existing'] = 'Un document appelé %s existe déjà dans %s'; +$lang['root'] = '[Espace de nom racine]'; +$lang['current'] = '(Courant)'; +$lang['norights'] = 'Vos permissions sont insufisante pour éditer %s.'; +$lang['filelocked'] = 'Ce fichier est verrouillé - réessayez plus tard.'; +$lang['linkchange'] = 'Les liens vers %s ont été changés vers %s'; +$lang['newname'] = 'Nouveau nom du document :'; +$lang['targetns'] = 'Sélectionnez le nouvel espace de nommage :'; diff --git a/lang/lv/lang.php b/lang/lv/lang.php index b1f549f..6d7617b 100644 --- a/lang/lv/lang.php +++ b/lang/lv/lang.php @@ -15,17 +15,17 @@ $lang['menu'] = 'Lapas pārdēvēšana/pārvietošana...'; $lang['desc'] = 'Page Move/Rename Plugin'; -//$lang['pm_notexist'] = 'This topic does not exist yet'; -$lang['pm_notwrite'] = 'Tev nav tiesību labot šo lapu'; -$lang['pm_badns'] = 'Neatļautas rakstzīmes nodaļas vārdā.'; -$lang['pm_badname'] = 'Neatļautas rakstzīmes lapas vārdā.'; -$lang['pm_nochange'] = 'Vārds un nodaļa nav mainīti.'; -$lang['pm_existing1'] = 'Dokuments %s jau ir nodaļā %s'; -$lang['pm_root'] = '[Saknes direktorija]'; -$lang['pm_current'] = '(Tekošais)'; -//$lang['pm_norights'] = 'Tev nav tiesību labot kādu lapu, kas norāda uz šo dokumentu.'; -$lang['pm_filelocked'] = 'Bloķēts fails - mēģini vēlāk vēlreiz.'; -$lang['pm_linkchange1'] = 'Norādes uz %s nomainītas ar %s'; -$lang['pm_newname'] = 'Jaunais dokumenta vārds :'; -$lang['pm_targetns'] = 'Nodaļa, kurp pārvietot :'; -$lang['pm_submit'] = 'Darīt!'; +//$lang['notexist'] = 'This topic does not exist yet'; +$lang['notwrite'] = 'Tev nav tiesību labot šo lapu'; +$lang['badns'] = 'Neatļautas rakstzīmes nodaļas vārdā.'; +$lang['badname'] = 'Neatļautas rakstzīmes lapas vārdā.'; +$lang['nochange'] = 'Vārds un nodaļa nav mainīti.'; +$lang['existing1'] = 'Dokuments %s jau ir nodaļā %s'; +$lang['root'] = '[Saknes direktorija]'; +$lang['current'] = '(Tekošais)'; +//$lang['norights'] = 'Tev nav tiesību labot kādu lapu, kas norāda uz šo dokumentu.'; +$lang['filelocked'] = 'Bloķēts fails - mēģini vēlāk vēlreiz.'; +$lang['linkchange1'] = 'Norādes uz %s nomainītas ar %s'; +$lang['newname'] = 'Jaunais dokumenta vārds :'; +$lang['targetns'] = 'Nodaļa, kurp pārvietot :'; +$lang['submit'] = 'Darīt!'; diff --git a/lang/nl/lang.php b/lang/nl/lang.php index c917637..1e71d42 100644 --- a/lang/nl/lang.php +++ b/lang/nl/lang.php @@ -15,17 +15,17 @@ $lang['menu'] = 'Pagina Verplaatsen/Hernoemen...'; $lang['desc'] = 'Pagina Verplaatsen/Hernoemen Plugin'; -//$lang['pm_notexist'] = 'Dit onderwerp bestaat nog niet'; -$lang['pm_notwrite'] = 'U heeft niet voldoende rechten om deze pagina te wijzigen'; -$lang['pm_badns'] = 'De namespace bevat een niet-toegestaan teken.'; -$lang['pm_badname'] = 'De paginanaam bevat een niet-toegestaan teken.'; -$lang['pm_nochange'] = 'De paginanaam en -namespace zijn ongewijzigd.'; -$lang['pm_existing1'] = 'Het document met naam %s bestaat al in %s'; -$lang['pm_root'] = '[Hoofdnamespace]'; -$lang['pm_current'] = '(Huidig)'; -//$lang['pm_norights'] = 'U heeft niet voldoende rechten om een of meerdere referenties aan te passen.'; -$lang['pm_filelocked'] = 'Deze file is geblokkeerd - probeer later opnieuw.'; -$lang['pm_linkchange1'] = 'Gelinkt aan %s gewijzigd naar %s'; -$lang['pm_newname'] = 'Nieuwe naam document:'; -$lang['pm_targetns'] = 'Selecteer namespace van het doel:'; +//$lang['notexist'] = 'Dit onderwerp bestaat nog niet'; +$lang['notwrite'] = 'U heeft niet voldoende rechten om deze pagina te wijzigen'; +$lang['badns'] = 'De namespace bevat een niet-toegestaan teken.'; +$lang['badname'] = 'De paginanaam bevat een niet-toegestaan teken.'; +$lang['nochange'] = 'De paginanaam en -namespace zijn ongewijzigd.'; +$lang['existing1'] = 'Het document met naam %s bestaat al in %s'; +$lang['root'] = '[Hoofdnamespace]'; +$lang['current'] = '(Huidig)'; +//$lang['norights'] = 'U heeft niet voldoende rechten om een of meerdere referenties aan te passen.'; +$lang['filelocked'] = 'Deze file is geblokkeerd - probeer later opnieuw.'; +$lang['linkchange1'] = 'Gelinkt aan %s gewijzigd naar %s'; +$lang['newname'] = 'Nieuwe naam document:'; +$lang['targetns'] = 'Selecteer namespace van het doel:'; diff --git a/lang/pl/lang.php b/lang/pl/lang.php index c3c8213..07fbeb4 100644 --- a/lang/pl/lang.php +++ b/lang/pl/lang.php @@ -17,17 +17,17 @@ $lang['menu'] = 'Przenieś / Zmień nazwę strony'; $lang['desc'] = 'Wtyczka Przenieś/Zmień nazwę'; -//$lang['pm_notexist'] = 'Ten temat jeszcze nie istnieje'; -$lang['pm_notwrite'] = 'Niewystarczające uprawnienia by wykonać operację'; -$lang['pm_badns'] = 'Nieprawidłowy znak w nazwie katalogu'; -$lang['pm_badname'] = 'Nieprawidłowy znak w nazwie dokumentu'; -$lang['pm_nochange'] = 'Nazwa dokumentu i katalogu niezmieniona'; -$lang['pm_existing'] = 'Dokument o nazwie %s już istnieje %s'; -$lang['pm_root'] = '[katalog bazowy]'; -$lang['pm_current'] = '(Bieżący)'; -//$lang['pm_norights'] = 'Nie masz wystarczających uprawnień do zmiany co najmniej jednego z linków do tej strony'; -$lang['pm_filelocked'] = 'Ten plik jest zablokowany - spróbuj ponownie później'; -$lang['pm_linkchange1'] = 'Linki do %s zmienione na %s'; -$lang['pm_newname'] = 'Nowa nazwa dokumentu:'; -$lang['pm_targetns'] = 'Nazwa docelowego katalogu:'; -$lang['pm_submit'] = 'Zmień'; +//$lang['notexist'] = 'Ten temat jeszcze nie istnieje'; +$lang['notwrite'] = 'Niewystarczające uprawnienia by wykonać operację'; +$lang['badns'] = 'Nieprawidłowy znak w nazwie katalogu'; +$lang['badname'] = 'Nieprawidłowy znak w nazwie dokumentu'; +$lang['nochange'] = 'Nazwa dokumentu i katalogu niezmieniona'; +$lang['existing'] = 'Dokument o nazwie %s już istnieje %s'; +$lang['root'] = '[katalog bazowy]'; +$lang['current'] = '(Bieżący)'; +//$lang['norights'] = 'Nie masz wystarczających uprawnień do zmiany co najmniej jednego z linków do tej strony'; +$lang['filelocked'] = 'Ten plik jest zablokowany - spróbuj ponownie później'; +$lang['linkchange1'] = 'Linki do %s zmienione na %s'; +$lang['newname'] = 'Nowa nazwa dokumentu:'; +$lang['targetns'] = 'Nazwa docelowego katalogu:'; +$lang['submit'] = 'Zmień'; diff --git a/lang/ru/lang.php b/lang/ru/lang.php index a9d4db1..34f213c 100644 --- a/lang/ru/lang.php +++ b/lang/ru/lang.php @@ -15,17 +15,17 @@ $lang['menu'] = 'Перемещение/переименование страницы...'; $lang['desc'] = 'Page Move/Rename Plugin'; -//$lang['pm_notexist'] = 'Эта страница еще не существует'; -$lang['pm_notwrite'] = 'Ваши права доступа не позволяют Вам изменять эту страницу'; -$lang['pm_badns'] = 'В названии пространства имён присутствуют недопустимые символы.'; -$lang['pm_badname'] = 'Недопустимые символы в названии страниц.'; -$lang['pm_nochange'] = 'Параметры страницы не изменены.'; -$lang['pm_existing1'] = 'Страница с именем %s уже существует в %s'; -$lang['pm_root'] = '[Корневой каталог]'; -$lang['pm_current'] = '(Текущий)'; -//$lang['pm_norights'] = 'У Вас нет прав на редактирование одной из страниц, ссылающихся на данный документ.'; -$lang['pm_filelocked'] = 'Изменение данного файла запрещено - попробуйте позже.'; -$lang['pm_linkchange1'] = 'Ссылки на страницу %s изменены на %s'; -$lang['pm_newname'] = 'Новое название документа :'; -$lang['pm_targetns'] = 'Переместить в пространство :'; -$lang['pm_submit'] = 'Применить'; +//$lang['notexist'] = 'Эта страница еще не существует'; +$lang['notwrite'] = 'Ваши права доступа не позволяют Вам изменять эту страницу'; +$lang['badns'] = 'В названии пространства имён присутствуют недопустимые символы.'; +$lang['badname'] = 'Недопустимые символы в названии страниц.'; +$lang['nochange'] = 'Параметры страницы не изменены.'; +$lang['existing1'] = 'Страница с именем %s уже существует в %s'; +$lang['root'] = '[Корневой каталог]'; +$lang['current'] = '(Текущий)'; +//$lang['norights'] = 'У Вас нет прав на редактирование одной из страниц, ссылающихся на данный документ.'; +$lang['filelocked'] = 'Изменение данного файла запрещено - попробуйте позже.'; +$lang['linkchange1'] = 'Ссылки на страницу %s изменены на %s'; +$lang['newname'] = 'Новое название документа :'; +$lang['targetns'] = 'Переместить в пространство :'; +$lang['submit'] = 'Применить'; diff --git a/lang/sl/lang.php b/lang/sl/lang.php index b053228..64cfea5 100644 --- a/lang/sl/lang.php +++ b/lang/sl/lang.php @@ -15,17 +15,17 @@ $lang['menu'] = 'Premakni/preimenuj stran...'; $lang['desc'] = 'Plugin za premikanje/preimenovanje strani'; -//$lang['pm_notexist'] = 'Ta stran še ne obstaja'; -$lang['pm_notwrite'] = 'Nimate zadostnih pravic za urejanje te strani'; -$lang['pm_badns'] = 'Neveljavni znaki v imenskem prostoru.'; -$lang['pm_badname'] = 'Neveljavni znaki v imenu strani.'; -$lang['pm_nochange'] = 'Ime dokumenta in imenski prostor sta nespremenjena.'; -$lang['pm_existing1'] = 'Dokument imenovan %s že obstaja v %s'; -$lang['pm_root'] = '[Korenski imenski prostor/Root namespace]'; -$lang['pm_current'] = '(Trenutno)'; -//$lang['pm_norights'] = 'Nimate zadostnih pravic za urejanje enega ali več backlinkov za ta dokument.'; -$lang['pm_filelocked'] = 'Ta datoteka je zaklenjena - poskusite ponovno kasneje.'; -$lang['pm_linkchange1'] = 'Kaže na %s spremenjeno na %s'; -$lang['pm_newname'] = 'Novo ime dokumenta :'; -$lang['pm_targetns'] = 'Izberite ciljni imenski prostor :'; -$lang['pm_submit'] = 'Potrdi'; +//$lang['notexist'] = 'Ta stran še ne obstaja'; +$lang['notwrite'] = 'Nimate zadostnih pravic za urejanje te strani'; +$lang['badns'] = 'Neveljavni znaki v imenskem prostoru.'; +$lang['badname'] = 'Neveljavni znaki v imenu strani.'; +$lang['nochange'] = 'Ime dokumenta in imenski prostor sta nespremenjena.'; +$lang['existing1'] = 'Dokument imenovan %s že obstaja v %s'; +$lang['root'] = '[Korenski imenski prostor/Root namespace]'; +$lang['current'] = '(Trenutno)'; +//$lang['norights'] = 'Nimate zadostnih pravic za urejanje enega ali več backlinkov za ta dokument.'; +$lang['filelocked'] = 'Ta datoteka je zaklenjena - poskusite ponovno kasneje.'; +$lang['linkchange1'] = 'Kaže na %s spremenjeno na %s'; +$lang['newname'] = 'Novo ime dokumenta :'; +$lang['targetns'] = 'Izberite ciljni imenski prostor :'; +$lang['submit'] = 'Potrdi'; diff --git a/lang/zh/lang.php b/lang/zh/lang.php index 6e481eb..7e8cd61 100644 --- a/lang/zh/lang.php +++ b/lang/zh/lang.php @@ -15,17 +15,17 @@ $lang['menu'] = '页面移动/重命名……'; $lang['desc'] = '页面移动/重命名插件'; -//$lang['pm_notexist'] = '这个主题还不存在'; -$lang['pm_notwrite'] = '您无权修改这个页面'; -$lang['pm_badns'] = '分类名中存在无效字符'; -$lang['pm_badname'] = '页面名中存在无效字符'; -$lang['pm_nochange'] = '不能更改文件名和分类名'; -$lang['pm_existing1'] = '文件 %s 已经存在于 %s'; -$lang['pm_root'] = '[跟目录]'; -$lang['pm_current'] = '(当前)'; -//$lang['pm_norights'] = '您无权编辑此文件的 backlinks'; -$lang['pm_filelocked'] = '此文件被锁定 - 请稍后重试'; -$lang['pm_linkchange1'] = '链接到 %s 更改到 %s'; -$lang['pm_newname'] = '新的文件名 :'; -$lang['pm_targetns'] = '选择目标分类 :'; -$lang['pm_submit'] = '提交'; +//$lang['notexist'] = '这个主题还不存在'; +$lang['notwrite'] = '您无权修改这个页面'; +$lang['badns'] = '分类名中存在无效字符'; +$lang['badname'] = '页面名中存在无效字符'; +$lang['nochange'] = '不能更改文件名和分类名'; +$lang['existing1'] = '文件 %s 已经存在于 %s'; +$lang['root'] = '[跟目录]'; +$lang['current'] = '(当前)'; +//$lang['norights'] = '您无权编辑此文件的 backlinks'; +$lang['filelocked'] = '此文件被锁定 - 请稍后重试'; +$lang['linkchange1'] = '链接到 %s 更改到 %s'; +$lang['newname'] = '新的文件名 :'; +$lang['targetns'] = '选择目标分类 :'; +$lang['submit'] = '提交'; diff --git a/script.js b/script.js index de828b1..f2eebf1 100644 --- a/script.js +++ b/script.js @@ -19,7 +19,7 @@ jQuery(function() { } else { previewns = targetns + ':' + newnsname; } - $preview.text(LANG['plugins']['move']['pm_previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); + $preview.text(LANG['plugins']['move']['previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); } else { var ns_for_page = $this.find('select[name=ns_for_page]').val(); var newns = $this.find('input[name=newns]').val(); @@ -34,7 +34,7 @@ jQuery(function() { newid = ns_for_page + ':'; } newid += newname; - $preview.text(LANG['plugins']['move']['pm_previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); + $preview.text(LANG['plugins']['move']['previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); } }; From 814f83ba2fa377ac54159f0873b86f2618132a19 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 24 Nov 2013 22:00:21 +0100 Subject: [PATCH 051/338] Import metadata of the pagemove plugin (from before the rename) --- action.php | 1 + helper.php | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/action.php b/action.php index 7e4fc06..95e8faa 100644 --- a/action.php +++ b/action.php @@ -61,6 +61,7 @@ function handle_read(Doku_Event $event, $param) { // the page is locked by the current user || checklock($id) !== false || @file_exists(wikiLockFN($id))) return; + /** @var helper_plugin_move $helper */ $helper = $this->loadHelper('move', true); if(!is_null($helper)) { $stack[$id] = true; diff --git a/helper.php b/helper.php index b9d07a0..6539c24 100644 --- a/helper.php +++ b/helper.php @@ -379,7 +379,7 @@ public function move_page(&$opts, $checkonly = false) { * End of init (checks) */ - $page_meta = p_get_metadata($ID, 'plugin_move', METADATA_DONT_RENDER); + $page_meta = $this->getMoveMeta($ID); if (!$page_meta) $page_meta = array(); if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); $page_meta['old_ids'][$ID] = time(); @@ -448,7 +448,7 @@ public function move_page(&$opts, $checkonly = false) { foreach ($affected_pages as $id) { if (!page_exists($id, '', false) || $id == $ID || $id == $opts['new_id']) continue; // we are only interested in persistent metadata, so no need to render anything. - $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); + $meta = $this->getMoveMeta($id); if (!$meta) $meta = array('moves' => array()); if (!isset($meta['moves'])) $meta['moves'] = array(); $meta['moves'] = $this->resolve_moves($meta['moves'], $id); @@ -558,8 +558,7 @@ public function move_media(&$opts, $checkonly = false) { 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_move', METADATA_DONT_RENDER); + $meta = $this->getMoveMeta($id); 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'], '__'); @@ -694,7 +693,7 @@ private function move_files($dir, $opts, $extregex) { * @return string The rewritten content */ public function execute_rewrites($id, $text = null) { - $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); + $meta = $this->getMoveMeta($id); if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { if(is_null($text)) $text = rawWiki($id); $moves = isset($meta['moves']) ? $meta['moves'] : array(); @@ -857,6 +856,27 @@ public function getNSMoveButton($action, $id = NULL) { } return $form->getForm(); } + + /** + * This function loads and returns the persistent metadata for the move plugin. If there is metadata for the + * pagemove plugin (not the old one but the version that immediately preceeded the move plugin) it will be migrated. + * + * @param string $id The id of the page the metadata shall be loaded for + * @return array|null The metadata of the page + */ + public function getMoveMeta($id) { + $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); + // migrate old metadata from the pagemove plugin + if (isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { + if (isset($all_meta['plugin_move'])) { + $all_meta['plugin_move'] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta['plugin_move']); + } else { + $all_meta['plugin_move'] = $all_meta['plugin_pagemove']; + } + p_set_metadata($id, array('plugin_move' => $all_meta['plugin_move'], 'plugin_pagemove' => null), false, true); + } + return isset($all_meta['plugin_move']) ? $all_meta['plugin_move'] : null; + } } /** From cdb54a14cc8761f8748199ae140531842bd768b9 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 24 Nov 2013 23:47:17 +0100 Subject: [PATCH 052/338] New version released, first version of the move plugin --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index 9927193..be325c1 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2013-10-29 +date 2013-11-24 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 45f9dd91c7936e4e88b614d51cccb90fc3bbf948 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 25 Nov 2013 00:26:25 +0100 Subject: [PATCH 053/338] Add media moves to the MOVE_HANDLERS_REGISTER event --- helper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helper.php b/helper.php index 6539c24..1e3b5ff 100644 --- a/helper.php +++ b/helper.php @@ -735,7 +735,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { $media_moves = $this->resolve_moves($media_moves, $id); $handlers = array(); - $data = array('id' => $id, 'moves' => &$moves, 'handlers' => &$handlers); + $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); /* * MOVE_HANDLERS REGISTER event: @@ -749,6 +749,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { * - id, ns: id and namespace of the old page * - new_id, new_ns: new id and namespace (can be identical to id and ns) * - moves: array of moves, the same as $moves in the event + * - media_moves: array of media moves, same as $media_moves in the event * - adaptRelativeId($id): adapts the relative $id according to the moves */ trigger_event('MOVE_HANDLERS_REGISTER', $data); From 2415d0ab3b3a13538846cf5951414cd6d197c513 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 25 Nov 2013 14:10:02 +0100 Subject: [PATCH 054/338] Prefix events by "PLUGIN_", fixes #1 --- helper.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/helper.php b/helper.php index 1e3b5ff..1f3c1df 100644 --- a/helper.php +++ b/helper.php @@ -392,7 +392,7 @@ public function move_page(&$opts, $checkonly = false) { // 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 - $event = new Doku_Event('MOVE_PAGE_RENAME', $data); + $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $data); if ($event->advise_before()) { // Open the old document and change forward links lock($ID); @@ -523,7 +523,7 @@ public function move_media(&$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 - $event = new Doku_Event('MOVE_MEDIA_RENAME', $data); + $event = new Doku_Event('PLUGIN_MOVE_MEDIA_RENAME', $data); if ($event->advise_before()) { // Move the Subscriptions & Indexes if (method_exists('Doku_Indexer', 'renamePage')) { // new feature since Spring 2013 release @@ -738,7 +738,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); /* - * MOVE_HANDLERS REGISTER event: + * PLUGIN_MOVE_HANDLERS REGISTER event: * * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler * The handler needs to be a valid callback, it will get the following parameters: @@ -752,7 +752,7 @@ function rewrite_content($text, $id, $moves, $media_moves = array()) { * - media_moves: array of media moves, same as $media_moves in the event * - adaptRelativeId($id): adapts the relative $id according to the moves */ - trigger_event('MOVE_HANDLERS_REGISTER', $data); + trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data); $modes = p_get_parsermodes(); From 5958b6b8767317cdbf814998dd93cf7e9befdd49 Mon Sep 17 00:00:00 2001 From: Myeongjin Date: Sat, 4 Jan 2014 15:36:20 +0900 Subject: [PATCH 055/338] update language files --- lang/cs/lang.php | 6 ++---- lang/cs/move.txt | 2 +- lang/de/lang.php | 4 ++-- lang/de/move.txt | 2 -- lang/en/lang.php | 4 ++-- lang/en/move.txt | 2 +- lang/es/lang.php | 4 ++-- lang/fr/lang.php | 9 ++++----- lang/fr/move.txt | 2 +- lang/lv/lang.php | 4 ++-- lang/lv/move.txt | 4 ++-- lang/nl/lang.php | 3 +-- lang/nl/move.txt | 4 +++- lang/pl/lang.php | 7 +++---- lang/ru/lang.php | 6 +++--- lang/ru/move.txt | 2 +- lang/sl/lang.php | 6 +++--- lang/sl/move.txt | 2 +- lang/zh/lang.php | 10 +++++----- 19 files changed, 39 insertions(+), 44 deletions(-) diff --git a/lang/cs/lang.php b/lang/cs/lang.php index 8ee528e..19d79ea 100644 --- a/lang/cs/lang.php +++ b/lang/cs/lang.php @@ -5,11 +5,11 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Tomáš Borland Valenta */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Přesun/přejmenování stránky'; @@ -29,5 +29,3 @@ $lang['newname'] = 'Nový název stránky :'; $lang['targetns'] = 'Cílový jmenný prostor :'; $lang['submit'] = 'Potvrdit'; - - diff --git a/lang/cs/move.txt b/lang/cs/move.txt index d91f12d..29d1c4d 100644 --- a/lang/cs/move.txt +++ b/lang/cs/move.txt @@ -6,5 +6,5 @@ Pomocí tohoto pluginu lze přesunout nebo přejmenovat aktuální stránku. Pla * The pages that are moved must not be locked for editing. * Pro přesun stránky potřebujete práva pro zápis v cílovém místě. * Nelze přesunout stránku někam, kde již existuje stránka stejného jména. - + Všechny odkazy na a ze stránky budou upraveny podle nového umístění stránky. diff --git a/lang/de/lang.php b/lang/de/lang.php index e2d2b30..9805bc9 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -5,11 +5,11 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author picsar <> */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; diff --git a/lang/de/move.txt b/lang/de/move.txt index 1db0ea2..8d4da83 100644 --- a/lang/de/move.txt +++ b/lang/de/move.txt @@ -1,7 +1,6 @@ ====== Seite/Namespace verschieben/umbenennen ====== Mit diesem Plugin kann die aktuelle Seite verschoben/umbenannt oder ein gesamter Namensraum verschoben/umbenannt werden. - Folgende Einschränkungen/Bedingungen gelten: * Sie müssen die Bearbeiten-Rechte für die Seite/alle Seiten im aktuellen Namensraum haben. @@ -10,4 +9,3 @@ Folgende Einschränkungen/Bedingungen gelten: * Eine Seite kann nicht in einen Namensraum verschoben werden, in der bereits eine Seite gleichen Namens existiert. Alle Links von und auf die Seite werden aktualisiert, um dem neuen Namen bzw. dem neuen Namensraum zu entsprechen. - diff --git a/lang/en/lang.php b/lang/en/lang.php index 0ed8aa5..59f773e 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -5,11 +5,11 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Gary Owen <> */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Page/Namespace Move/Rename...'; diff --git a/lang/en/move.txt b/lang/en/move.txt index 59bceff..fe04cb7 100644 --- a/lang/en/move.txt +++ b/lang/en/move.txt @@ -2,7 +2,7 @@ This plugin allows you to move and/or rename the current page or move and/or rename the current namespace within the following restrictions: - * You must have edit permission for the current page/all pages in the current namespace + * You must have edit permission for the current page/all pages in the current namespace. * The pages that are moved must not be locked for editing. * For moving a page you also need create permission in the target namespace. * You cannot move a page to a namespace where a page with the same name already exists. diff --git a/lang/es/lang.php b/lang/es/lang.php index e94fe86..8d50c71 100644 --- a/lang/es/lang.php +++ b/lang/es/lang.php @@ -6,11 +6,11 @@ * @author Gary Owen <> * @translation Ruben Squartini <> */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Mover/Renombrar página...'; diff --git a/lang/fr/lang.php b/lang/fr/lang.php index fb1fac7..fa36bf9 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -1,16 +1,16 @@ + * @author Gary Owen <> * @translator Clement Hermann (nodens) */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Déplacer/Renommer la page...'; @@ -29,4 +29,3 @@ $lang['linkchange'] = 'Les liens vers %s ont été changés vers %s'; $lang['newname'] = 'Nouveau nom du document :'; $lang['targetns'] = 'Sélectionnez le nouvel espace de nommage :'; - diff --git a/lang/fr/move.txt b/lang/fr/move.txt index f9a5c69..6fb801a 100644 --- a/lang/fr/move.txt +++ b/lang/fr/move.txt @@ -1,10 +1,10 @@ ====== Move ====== Ce plugin permet de déplacer et/ou renommer le document courant, avec les limitations suivantes : + * Il faut avoir les droits d'édition sur le document * Le document ne peut être verrouillés pour l'édition * Pour déplacer une page il faut également disposer du droit de création dans le répertoire de destination * Il est impossible de déplacer le document vers un espace de nommage où un document du même nom existe déjà. Tous les liens depuis et vers la page seront mis à jour pour refléter le nouvel emplacement et/ou le nouveau nom. - diff --git a/lang/lv/lang.php b/lang/lv/lang.php index 6d7617b..b870863 100644 --- a/lang/lv/lang.php +++ b/lang/lv/lang.php @@ -5,11 +5,11 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Aivars Miška <> */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Lapas pārdēvēšana/pārvietošana...'; diff --git a/lang/lv/move.txt b/lang/lv/move.txt index 29cfc54..23ea936 100644 --- a/lang/lv/move.txt +++ b/lang/lv/move.txt @@ -1,9 +1,9 @@ ====== Lapas pārvietošana ====== -Šis modulis ļauj pārvietot un/vai pārdēvēt tekošo lapu. \\ +Šis modulis ļauj pārvietot un/vai pārdēvēt tekošo lapu. Ar nosacījumiem: - * You must have edit permission for the current page/all pages in the current namespace + * You must have edit permission for the current page/all pages in the current namespace. * The pages that are moved must not be locked for editing. * Lai pārvietotu, tev vajag attiecīgās tiesības mērķa direktorijā. * Nevar pārvietot lapu uz nodaļu, kurā jau ir šāda nosaukuma lapa. diff --git a/lang/nl/lang.php b/lang/nl/lang.php index 1e71d42..8f0f373 100644 --- a/lang/nl/lang.php +++ b/lang/nl/lang.php @@ -1,6 +1,6 @@ @@ -28,4 +28,3 @@ $lang['linkchange1'] = 'Gelinkt aan %s gewijzigd naar %s'; $lang['newname'] = 'Nieuwe naam document:'; $lang['targetns'] = 'Selecteer namespace van het doel:'; - diff --git a/lang/nl/move.txt b/lang/nl/move.txt index 4b9cc43..5705529 100644 --- a/lang/nl/move.txt +++ b/lang/nl/move.txt @@ -1,8 +1,10 @@ ====== Pagina's verplaatsen ====== Deze plugin stelt je in staat pagina's te verplaatsen en/of te hernoemen binnen volgende beperkingen: + * You must have edit permission for the current page/all pages in the current namespace * De pagina en zijn referenties kunnen niet geblokkeerd worden tijdens het verplaatsen * Om pagina's te verplaatsen heb je ook schrijfrechten nodig in de folder van bestemming * Je kan een pagina niet plaatsen in een namespace waar al een pagina bestaat met dezelfde naam -Al de links van en naar de pagina zullen geupdated worden naar de nieuwe naam/locatie. \ No newline at end of file + +Al de links van en naar de pagina zullen geupdated worden naar de nieuwe naam/locatie. diff --git a/lang/pl/lang.php b/lang/pl/lang.php index 07fbeb4..6c0e162 100644 --- a/lang/pl/lang.php +++ b/lang/pl/lang.php @@ -1,11 +1,10 @@ - * @translator Wojciech Kazimierczak - + * @author Gary Owen <> + * @auther Wojciech Kazimierczak */ // settings must be present and set appropriately for the language diff --git a/lang/ru/lang.php b/lang/ru/lang.php index 34f213c..47c8869 100644 --- a/lang/ru/lang.php +++ b/lang/ru/lang.php @@ -1,15 +1,15 @@ */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Перемещение/переименование страницы...'; diff --git a/lang/ru/move.txt b/lang/ru/move.txt index 1fe7e17..1417219 100644 --- a/lang/ru/move.txt +++ b/lang/ru/move.txt @@ -2,7 +2,7 @@ Этот плагин позволяет перемещать и/или переименовывать текущую страницу со следующими ограничениями: - * You must have edit permission for the current page/all pages in the current namespace + * You must have edit permission for the current page/all pages in the current namespace. * The pages that are moved must not be locked for editing. * Вы должны обладать соответствующими правами доступа в директории, куда Вы планируете переместить файл. * Вы не можете переместить страницу в пространство имён, уже содержащее страницу с таким же названием. diff --git a/lang/sl/lang.php b/lang/sl/lang.php index 64cfea5..9dbf223 100644 --- a/lang/sl/lang.php +++ b/lang/sl/lang.php @@ -1,15 +1,15 @@ */ - + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Premakni/preimenuj stran...'; diff --git a/lang/sl/move.txt b/lang/sl/move.txt index b856c15..e4000e0 100644 --- a/lang/sl/move.txt +++ b/lang/sl/move.txt @@ -2,7 +2,7 @@ Ta plugin omogoča premikanje in/ali preimenovanje trenutnega dokumenta v okviru naslednjih omejitev: - * You must have edit permission for the current page/all pages in the current namespace + * You must have edit permission for the current page/all pages in the current namespace. * The pages that are moved must not be locked for editing. * Za premikanje datoteke potrebujete pravico za ustvarjanje v ciljni mapi. * Ne morete premakniti dokumenta v imenski prostor, kjer dokument z istim imenom že obstaja. diff --git a/lang/zh/lang.php b/lang/zh/lang.php index 7e8cd61..08ca0f8 100644 --- a/lang/zh/lang.php +++ b/lang/zh/lang.php @@ -2,15 +2,15 @@ /** * 中文文件 * - * @许可协议 GPL 2 (http://www.gnu.org/licenses/gpl.html) - * @作者 Gary Owen <> - * @翻译 TombCrow + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Gary Owen <> + * @author TombCrow */ - + // 此处设置用户语言 $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; - + // 若在此处设置,插件不必要求 getMenuText() 模式 $lang['menu'] = '页面移动/重命名……'; $lang['desc'] = '页面移动/重命名插件'; From d823684c1f94de4a99b71e459df08fcbf77a8dc8 Mon Sep 17 00:00:00 2001 From: Myeongjin Date: Sat, 4 Jan 2014 15:36:44 +0900 Subject: [PATCH 056/338] Add Korean translation --- lang/ko/lang.php | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ lang/ko/move.txt | 10 ++++++++ 2 files changed, 73 insertions(+) create mode 100644 lang/ko/lang.php create mode 100644 lang/ko/move.txt diff --git a/lang/ko/lang.php b/lang/ko/lang.php new file mode 100644 index 0000000..9e167aa --- /dev/null +++ b/lang/ko/lang.php @@ -0,0 +1,63 @@ + + * @author Myeongjin + */ + +// settings must be present and set appropriately for the language +$lang['encoding'] = 'utf-8'; +$lang['direction'] = 'ltr'; + +// for admin plugins, the menu prompt to be displayed in the admin menu +// if set here, the plugin doesn't need to override the getMenuText() method +$lang['menu'] = '문서/이름공간 옮기기/이름 바꾸기...'; +$lang['desc'] = '문서/이름공간 옮기기/이름 바꾸기 플러그인'; + +$lang['notexist'] = '%s 문서가 존재하지 않습니다'; +$lang['medianotexist'] = '%s 미디어 파일이 존재하지 않습니다'; +$lang['notwrite'] = '이 문서를 수정할 충분한 권한이 없습니다'; +$lang['badns'] = '이름공간에 잘못된 글자가 있습니다.'; +$lang['badname'] = '문서 이름에 잘못된 글자가 있습니다.'; +$lang['nochange'] = '문서 이름과 이름공간이 바뀌지 않습니다.'; +$lang['nomediachange'] = '미디어 파일 이름과 이름공간이 바뀌지 않습니다.'; +$lang['existing'] = '%s인 문서는 이미 %s에 존재합니다'; +$lang['mediaexisting'] = '%s인 미디어 파일은 이미 %s에 존재합니다'; +$lang['root'] = '[루트 이름공간]'; +$lang['current'] = '(현재)'; +$lang['renamed'] = '문서 이름이 %s에서 %s(으)로 바뀌었습니다'; +$lang['moved'] = '문서가 %s에서 %s(으)로 옮겨졌습니다'; +$lang['move_rename'] = '문서가 %s에서 %s(으)로 옮겨지고 이름이 바뀌었습니다'; +$lang['delete'] = '옮기기 플러그인에 의해 삭제됨'; +$lang['norights'] = '%s(을)를 편집할 충분하지 않은 권한이 있습니다.'; +$lang['nomediarights'] = '%s(을)를 삭제할 충분하지 않은 권한이 있습니다.'; +$lang['notargetperms'] = '%s 문서를 만들 권한이 없습니다.'; +$lang['nomediatargetperms'] = '%s 미디어 파일을 만들 권한이 없습니다.'; +$lang['filelocked'] = '%s 문서가 잠겨 있습니다. 나중에 다시 시도하세요.'; +$lang['linkchange'] = '링크가 옮기기 작업 때문에 적응했습니다'; + +$lang['ns_move_in_progress'] = '여기에 현재 문서 %s개와 미디어 파일 %s개가 %s 이름공간에서 %s 이름공간으로 옮겨지고 있습니다.'; +$lang['ns_move_continue'] = '이름공간 옮기기 계속'; +$lang['ns_move_abort'] = '이름공간 옮기기 중단'; +$lang['ns_move_continued'] = '이름공간 옮기기가 %s 이름공간에서 %s 이름공간으로 계속되었으며, 항목 %s개가 여전히 남아 있습니다.'; +$lang['ns_move_started'] = '이름공간 옮기기가 %s 이름공간에서 %s 이름공간으로 시작되었으며, 문서 %s개와 미디어 파일 %s개가 옮겨집니다.'; +$lang['ns_move_error'] = '이름공간 옮기기를 %s에서 %s(으)로 계속하는 동안 오류가 발생했습니다.'; +$lang['ns_move_tryagain'] = '다시 시도'; +$lang['ns_move_skip'] = '현재 항목을 건너뛰기'; +// Form labels +$lang['newname'] = '새 문서 이름:'; +$lang['newnsname'] = '새 이름공간 이름:'; +$lang['targetns'] = '새 이름공간 선택:'; +$lang['newtargetns'] = '새 이름공간 만들기:'; +$lang['movepage'] = '문서 옮기기'; +$lang['movens'] = '이름공간 옮기기'; +$lang['submit'] = '제출'; +$lang['content_to_move'] = '옮길 내용'; +$lang['move_pages'] = '문서'; +$lang['move_media'] = '미디어 파일'; +$lang['move_media_and_pages'] = '문서와 미디어 파일'; +// JavaScript preview +$lang['js']['previewpage'] = 'OLDPAGE(은)는 NEWPAGE(으)로 옮겨집니다'; +$lang['js']['previewns'] = 'OLDNS 이름공간 안에 모든 문서와 이름공간은 NEWNS 이름공간 안으로 옮겨집니다'; diff --git a/lang/ko/move.txt b/lang/ko/move.txt new file mode 100644 index 0000000..eae25c2 --- /dev/null +++ b/lang/ko/move.txt @@ -0,0 +1,10 @@ +====== 옮기기 ====== + +이 플러그인은 다음 제한 안에서 현재 문서를 옮기고/거나 이름을 바꾸거나 현재 이름공간을 옮기고/거나 이름을 바꿀 수 있습니다: + + * 현재 이름공간에서 현재 문서/모든 문서에 대한 편집 권한이 있어야 합니다. + * 옮겨지는 문서는 편집을 위해 잠겨 있지 않아야 합니다. + * 문서 옮기기를 위해서는 대상 이름공간에서 만들기 권한도 필요합니다. + * 같은 이름으로 된 문서가 이미 존재하는 이름공간으로 문서를 옮길 수 없습니다. + +기존에서 새로 옮겨지는 문서의 모든 링크는 새 위치와/나 이름을 반영하도록 바뀝니다. From aea4a6bd2efd53e757aa2d630c54a30f22c2fadf Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 17 Mar 2014 10:45:49 +0100 Subject: [PATCH 057/338] removed seemingly dead code --- helper.php | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/helper.php b/helper.php index 1f3c1df..5b71145 100644 --- a/helper.php +++ b/helper.php @@ -12,37 +12,6 @@ * Helper part of the move plugin. */ class helper_plugin_move extends DokuWiki_Plugin { - /** - * Move a namespace according to the given options - * - * @author Bastian Wolf - * @param array $opts Options for moving the namespace - * @param bool $checkonly If only the checks if all pages can be moved shall be executed - * @return bool if the move was executed - */ - function move_namespace(&$opts, $checkonly = false) { - global $ID; - global $conf; - - $pagelist = array(); - $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); - $searchOpts = array('depth' => 0, 'skipacl' => true); - search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); - - // FIXME: either use ajax for executing the queue and/or store the queue so it can be resumed when the execution - // is aborted. - foreach ($pagelist as $page) { - $ID = $page['id']; - $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); - $pageOpts = $opts; - $pageOpts['ns'] = getNS($ID); - $pageOpts['name'] = noNS($ID); - $pageOpts['newname'] = noNS($ID); - $pageOpts['newns'] = getNS($newID); - if (!$this->move_page($pageOpts, $checkonly)) return false; - } - return true; - } /** * Start a namespace move by creating the list of all pages and media files that shall be moved From 53cabe775e34e44de1c0162143df1cb50d1e93a9 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 17 Mar 2014 14:14:58 +0100 Subject: [PATCH 058/338] preview changes before executing namespace moves --- admin.php | 8 ++++++++ helper.php | 42 ++++++++++++++++++++++++++++++++++++++++++ lang/en/lang.php | 2 ++ script.js | 14 ++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/admin.php b/admin.php index dcbf2be..6f564e9 100644 --- a/admin.php +++ b/admin.php @@ -77,8 +77,16 @@ function html() { ptln('

'); ptln(sprintf($this->getLang('ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); ptln('

'); + + ptln('
'); + ptln(''.$this->getLang('preview').''); + $this->helper->preview_namespace_move($this->ns_opts); + ptln('
'); + + ptln('

'); ptln($this->helper->getNSMoveButton('continue')); ptln($this->helper->getNSMoveButton('abort')); + ptln('

'); break; case 'error': ptln('

'); diff --git a/helper.php b/helper.php index 5b71145..293e741 100644 --- a/helper.php +++ b/helper.php @@ -146,6 +146,48 @@ public function continue_namespace_move() { return $opts['remaining']; } + /** + * Preview all single move operations in a namespace move operation + */ + public function preview_namespace_move() { + $files = $this->get_namespace_meta_files(); + + if (!@file_exists($files['opts'])) { + msg('Error: there are no saved options', -1); + return; + } + $opts = unserialize(file_get_contents($files['opts'])); + + echo '

    '; + if (@file_exists($files['pagelist'])) { + $pagelist = file($files['pagelist']); + foreach($pagelist as $old) { + $new = $this->getNewID($old, $opts['ns'], $opts['newns']); + + echo '
  • '; + echo hsc($old); + echo '→'; + echo hsc($new); + echo '
  • '; + } + } + if (@file_exists($files['medialist'])) { + $medialist = file($files['medialist']); + foreach($medialist as $old) { + $new = $this->getNewID($old, $opts['ns'], $opts['newns']); + + echo '
  • '; + echo hsc($old); + echo '→'; + echo hsc($new); + echo '
  • '; + } + } + echo '
'; + } + + + /** * Skip the item that would be executed next in the current namespace move * diff --git a/lang/en/lang.php b/lang/en/lang.php index 59f773e..13f5719 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -37,6 +37,8 @@ $lang['filelocked'] = 'The page %s is locked. Try again later.'; $lang['linkchange'] = 'Links adapted because of a move operation'; +$lang['preview'] = 'Preview changes to be executed'; + $lang['ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; $lang['ns_move_continue'] = 'Continue the namespace move'; $lang['ns_move_abort'] = 'Abort the namespace move'; diff --git a/script.js b/script.js index f2eebf1..f76fcc1 100644 --- a/script.js +++ b/script.js @@ -89,4 +89,18 @@ jQuery(function() { }; $this.submit(submit_handler); }); + + // hide preview list on namespace move + jQuery('#move__preview_list').each(function(){ + var $this = jQuery(this); + $this.find('ul').hide(); + $this.find('span') + .click(function(){ + console.log('woah'); + $this.find('ul').dw_toggle(); + $this.find('span').toggleClass('closed'); + }) + .addClass('closed'); + }); + }); \ No newline at end of file From 20f2d8e6a10e1ae9a9b157f565ad3af03402204b Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 17 Mar 2014 14:15:26 +0100 Subject: [PATCH 059/338] log all moves during a namespace move logs are stored in the cache directory named after the timestamp the move was started in --- helper.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/helper.php b/helper.php index 293e741..ea090d7 100644 --- a/helper.php +++ b/helper.php @@ -53,6 +53,7 @@ public function start_namespace_move(&$opts) { } unset ($medialist); + $opts['started'] = time(); // remember when this move started $opts['num_media'] = count($media_files); io_saveFile($files['medialist'], implode("\n", $media_files)); @@ -97,8 +98,10 @@ public function continue_namespace_move() { $pageOpts['newns'] = getNS($newID); if (!$this->move_page($pageOpts)) { fclose($pagelist); + $this->log($opts['started'], 'P', $ID, $newID, false); return false; } + $this->log($opts['started'], 'P', $ID, $newID, true); // update the list of pages and the options after every move ftruncate($pagelist, ftell($pagelist)); @@ -124,8 +127,10 @@ public function continue_namespace_move() { $pageOpts['newns'] = getNS($newID); if (!$this->move_media($pageOpts)) { fclose($medialist); + $this->log($opts['started'], 'M', $ID, $newID, false); return false; } + $this->log($opts['started'], 'M', $ID, $newID, true); // update the list of media files and the options after every move ftruncate($medialist, ftell($medialist)); @@ -240,6 +245,37 @@ public function skip_namespace_move_item() { } } + /** + * Log result of an operation + * + * @param int $optime + * @param string $type + * @param string $from + * @param string $to + * @param bool $success + * @author Andreas Gohr + */ + private function log($optime, $type, $from, $to, $success){ + global $conf; + global $MSG; + + + $file = $conf['cachedir'].'/move-'.$optime.'.log'; + $now = time(); + $date = date('Y-m-d H:i:s', $now); // for human readability + + if($success) { + $ok = 'success'; + $msg = ''; + }else { + $ok = 'failed'; + $msg = $MSG[count($MSG)-1]['msg']; // get detail from message array + } + + $log = "$now\t$date\t$type\t$from\t$to\t$ok\t$msg\n"; + io_saveFile($file, $log, true); + } + /** * Get last file id from the list that is stored in the file that is referenced by the handle * The handle is set to the newline before the file id From f861d4acab449b97aa78bc9ce1211274289c3632 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 24 Mar 2014 10:40:42 +0100 Subject: [PATCH 060/338] added missing style --- style.less | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 style.less diff --git a/style.less b/style.less new file mode 100644 index 0000000..9d402c7 --- /dev/null +++ b/style.less @@ -0,0 +1,6 @@ +#move__preview_list { + span { + cursor: pointer; + color: @ini_link; + } +} \ No newline at end of file From 9711c8b0cb8ac65dc3633dc5ee1277bb8d14f16d Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 24 Mar 2014 10:40:53 +0100 Subject: [PATCH 061/338] allow auto skipping of errors --- admin.php | 2 ++ helper.php | 10 ++++++++++ lang/en/lang.php | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/admin.php b/admin.php index 6f564e9..9825d27 100644 --- a/admin.php +++ b/admin.php @@ -156,6 +156,7 @@ function printForm() { $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('targetns'), '', 'block')); $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('newnsname'), '', 'block')); $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); + $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', '')); $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); $form->endFieldset(); $form->printForm(); @@ -247,6 +248,7 @@ function handle() { if (isset($_POST['targetns'])) $this->opts['targetns'] = cleanID((string)$_POST['targetns']); if (isset($_POST['newnsname'])) $this->opts['newnsname'] = cleanID((string)$_POST['newnsname']); if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; + if (isset($_POST['autoskip'])) $this->opts['autoskip'] = true; if (isset($_POST['contenttomove']) && in_array($_POST['contenttomove'], array('pages', 'media', 'both'), true)) $this->opts['contenttomove'] = $_POST['contenttomove']; // check the input for completeness diff --git a/helper.php b/helper.php index ea090d7..2b751d6 100644 --- a/helper.php +++ b/helper.php @@ -99,6 +99,11 @@ public function continue_namespace_move() { if (!$this->move_page($pageOpts)) { fclose($pagelist); $this->log($opts['started'], 'P', $ID, $newID, false); + + // automatically skip this item if wanted + if($opts['autoskip']) { + return $this->skip_namespace_move_item(); + } return false; } $this->log($opts['started'], 'P', $ID, $newID, true); @@ -128,6 +133,11 @@ public function continue_namespace_move() { if (!$this->move_media($pageOpts)) { fclose($medialist); $this->log($opts['started'], 'M', $ID, $newID, false); + + // automatically skip this item if wanted + if($opts['autoskip']) { + return $this->skip_namespace_move_item(); + } return false; } $this->log($opts['started'], 'M', $ID, $newID, true); diff --git a/lang/en/lang.php b/lang/en/lang.php index 13f5719..de17e23 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -55,7 +55,8 @@ $lang['movepage'] = 'Move page'; $lang['movens'] = 'Move namespace'; $lang['submit'] = 'Submit'; -$lang['content_to_move'] = 'Content to move'; +$lang['content_to_move'] = 'Content to move:'; +$lang['autoskip'] = 'ignore errors'; $lang['move_pages'] = 'Pages'; $lang['move_media'] = 'Media files'; $lang['move_media_and_pages'] = 'Pages and media files'; From 9d1f4c04fcedcd6e224ece8010e5d248af873abd Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 24 Mar 2014 10:55:43 +0100 Subject: [PATCH 062/338] added config option autoskip default --- admin.php | 2 +- conf/metadata.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 conf/metadata.php diff --git a/admin.php b/admin.php index 9825d27..bee3f59 100644 --- a/admin.php +++ b/admin.php @@ -156,7 +156,7 @@ function printForm() { $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('targetns'), '', 'block')); $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('newnsname'), '', 'block')); $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); - $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', '')); + $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', '', ($this->getConf('autoskip') ? array('checked'=>'checked') : array()))); $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); $form->endFieldset(); $form->printForm(); diff --git a/conf/metadata.php b/conf/metadata.php new file mode 100644 index 0000000..10ceef2 --- /dev/null +++ b/conf/metadata.php @@ -0,0 +1,3 @@ + Date: Mon, 24 Mar 2014 12:11:00 +0100 Subject: [PATCH 063/338] correctly finish a ns move when less than 10 pages were moved --- helper.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/helper.php b/helper.php index 2b751d6..42f9931 100644 --- a/helper.php +++ b/helper.php @@ -82,7 +82,8 @@ public function continue_namespace_move() { $opts = unserialize(file_get_contents($files['opts'])); - if (@file_exists($files['pagelist'])) { + $nope = false; + if (@file_exists($files['pagelist']) && (filesize($files['pagelist']) > 1) ) { $pagelist = fopen($files['pagelist'], 'a+');; for ($i = 0; $i < 10; ++$i) { @@ -115,8 +116,7 @@ public function continue_namespace_move() { } fclose($pagelist); - if ($ID === false) unlink($files['pagelist']); - } elseif (@file_exists($files['medialist'])) { + } elseif (@file_exists($files['medialist']) && (filesize($files['medialist']) > 1) ) { $medialist = fopen($files['medialist'], 'a+'); for ($i = 0; $i < 10; ++$i) { @@ -149,12 +149,13 @@ public function continue_namespace_move() { } fclose($medialist); - if ($ID === false) { - unlink($files['medialist']); - unlink($files['opts']); - } } else { - unlink($files['opts']); + $nope = true; + } + + if ($nope || $opts['remaining'] == 0){ + // nothing more to do, finish the move + $this->abort_namespace_move(); return 0; } From 29b99c9a066e63284ca6d04a3439f7ce7885b6c5 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 24 Mar 2014 14:30:45 +0100 Subject: [PATCH 064/338] added missing files for the config option --- conf/default.php | 3 +++ lang/en/settings.php | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 conf/default.php create mode 100644 lang/en/settings.php diff --git a/conf/default.php b/conf/default.php new file mode 100644 index 0000000..27593d2 --- /dev/null +++ b/conf/default.php @@ -0,0 +1,3 @@ + Date: Mon, 24 Mar 2014 14:31:53 +0100 Subject: [PATCH 065/338] execute page adjustments right after a namespace move --- helper.php | 88 ++++++++++++++++++++++++++++++++++++++++++++---------- script.js | 4 +-- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/helper.php b/helper.php index 42f9931..26f369f 100644 --- a/helper.php +++ b/helper.php @@ -13,6 +13,15 @@ */ class helper_plugin_move extends DokuWiki_Plugin { + /** + * @var array access to the info the last move in execution + * + * the same as the data passed to the PLUGIN_MOVE_PAGE_RENAME and PLUGIN_MOVE_MEDIA_RENAME events, + * used for internal introspection in the move plugin. This is ephemeral data and may be outdated or + * misleading when not read directly after a page or media move operation + */ + public $lastmove = array(); + /** * Start a namespace move by creating the list of all pages and media files that shall be moved * @@ -54,6 +63,7 @@ public function start_namespace_move(&$opts) { unset ($medialist); $opts['started'] = time(); // remember when this move started + $opts['affected'] = 0; // will be filled in later $opts['num_media'] = count($media_files); io_saveFile($files['medialist'], implode("\n", $media_files)); @@ -67,7 +77,10 @@ public function start_namespace_move(&$opts) { } /** - * Execute the next steps (moving up to 10 pages or media files) of the currently running namespace move + * Execute the next steps of the currently running namespace move + * + * This function will move up to 10 pages or media files or adjust the links of affected pages. + * It is repeatedly called via AJAX (or several clicks from the user if JavaScript is missing) * * @return bool|int False if an error occurred, otherwise the number of remaining moves */ @@ -82,7 +95,7 @@ public function continue_namespace_move() { $opts = unserialize(file_get_contents($files['opts'])); - $nope = false; + // handle page moves if (@file_exists($files['pagelist']) && (filesize($files['pagelist']) > 1) ) { $pagelist = fopen($files['pagelist'], 'a+');; @@ -109,6 +122,9 @@ public function continue_namespace_move() { } $this->log($opts['started'], 'P', $ID, $newID, true); + // remember affected pages + io_saveFile($files['affected'], join("\n", $this->lastmove['affected_pages'])."\n", true); + // update the list of pages and the options after every move ftruncate($pagelist, ftell($pagelist)); $opts['remaining']--; @@ -116,7 +132,11 @@ public function continue_namespace_move() { } fclose($pagelist); - } elseif (@file_exists($files['medialist']) && (filesize($files['medialist']) > 1) ) { + return max(1, $opts['remaining']); // force one more call + } + + // handle media moves + if (@file_exists($files['medialist']) && (filesize($files['medialist']) > 1) ) { $medialist = fopen($files['medialist'], 'a+'); for ($i = 0; $i < 10; ++$i) { @@ -142,6 +162,9 @@ public function continue_namespace_move() { } $this->log($opts['started'], 'M', $ID, $newID, true); + // remember affected pages + io_saveFile($files['affected'], join("\n", $this->lastmove['affected_pages'])."\n", true); + // update the list of media files and the options after every move ftruncate($medialist, ftell($medialist)); $opts['remaining']--; @@ -149,17 +172,51 @@ public function continue_namespace_move() { } fclose($medialist); - } else { - $nope = true; + return max(1, $opts['remaining']); // force one more call } - if ($nope || $opts['remaining'] == 0){ - // nothing more to do, finish the move - $this->abort_namespace_move(); - return 0; + // update affected pages + if(@file_exists($files['affected']) && (filesize($files['affected']) > 1)) { + if(!$opts['affected']) { + // this is the first run, clean up the file + $affected = io_readFile($files['affected']); + $affected = explode("\n", $affected); + $affected = array_unique($affected); + $affected = array_filter($affected); + sort($affected); + if($affected[0] === '') array_shift($affected); + io_saveFile($files['affected'], join("\n", $affected)); + + $opts['affected'] = count($affected); + $opts['remaining'] = $opts['affected']; // something to do again + io_saveFile($files['opts'], serialize($opts)); + + return max(1, $opts['remaining']); // force one more call + } + + // handle affected pages + $affectedlist = fopen($files['affected'], 'a+'); + for ($i = 0; $i < 10; ++$i) { + $ID = $this->get_last_id($affectedlist); + if ($ID === false) { + break; + } + + // rewrite it + $this->execute_rewrites($ID, null); + + // update the list of media files and the options after every move + ftruncate($affectedlist, ftell($affectedlist)); + $opts['remaining']--; + io_saveFile($files['opts'], serialize($opts)); + } + + return max(1, $opts['remaining']); // force one more call } - return $opts['remaining']; + // still here? the move is completed + $this->abort_namespace_move(); + return 0; } /** @@ -352,7 +409,8 @@ protected function get_namespace_meta_files() { return array( 'opts' => $conf['metadir'].'/__move_opts', 'pagelist' => $conf['metadir'].'/__move_pagelist', - 'medialist' => $conf['metadir'].'/__move_medialist' + 'medialist' => $conf['metadir'].'/__move_medialist', + 'affected' => $conf['metadir'].'/__move_affected', ); } @@ -445,12 +503,12 @@ public function move_page(&$opts, $checkonly = false) { // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages $affected_pages = idx_get_indexer()->lookupKey('relation_references', $ID); - $data = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], 'affected_pages' => &$affected_pages); + $this->lastmove = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], '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 // note that old_ids is in the form 'id' => timestamp of move - $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $data); + $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $this->lastmove); if ($event->advise_before()) { // Open the old document and change forward links lock($ID); @@ -577,11 +635,11 @@ public function move_media(&$opts, $checkonly = false) { $affected_pages = idx_get_indexer()->lookupKey('relation_media', $opts['id']); - $data = array('opts' => &$opts, 'affected_pages' => &$affected_pages); + $this->lastmove = 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('PLUGIN_MOVE_MEDIA_RENAME', $data); + $event = new Doku_Event('PLUGIN_MOVE_MEDIA_RENAME', $this->lastmove); if ($event->advise_before()) { // Move the Subscriptions & Indexes if (method_exists('Doku_Indexer', 'renamePage')) { // new feature since Spring 2013 release diff --git a/script.js b/script.js index f76fcc1..529ef26 100644 --- a/script.js +++ b/script.js @@ -67,8 +67,8 @@ jQuery(function() { if (data.remaining === false) { $progressbar.progressbar('option', 'value', false); } else { - $progressbar.progressbar('option', 'value', data.pages + data.media - data.remaining); - $progressbar.progressbar('option', 'max', data.pages + data.media); + $progressbar.progressbar('option', 'value', data.pages + data.media + data.affected - data.remaining); + $progressbar.progressbar('option', 'max', data.pages + data.media + data.affected); } $message.html(data.html); if (data.remaining === false) { From 53cc00aaab62b100df641a3bb1ccbe37ae4edbfb Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 24 Mar 2014 14:44:22 +0100 Subject: [PATCH 066/338] make automatic link rewriting configurable --- admin.php | 4 +++- conf/default.php | 3 ++- conf/metadata.php | 3 ++- helper.php | 4 ++-- lang/en/lang.php | 3 ++- lang/en/settings.php | 3 ++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/admin.php b/admin.php index bee3f59..03b317b 100644 --- a/admin.php +++ b/admin.php @@ -156,7 +156,8 @@ function printForm() { $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('targetns'), '', 'block')); $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('newnsname'), '', 'block')); $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); - $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', '', ($this->getConf('autoskip') ? array('checked'=>'checked') : array()))); + $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', 'block', ($this->getConf('autoskip') ? array('checked'=>'checked') : array()))); + $form->addElement(form_makeCheckboxField('autorewrite', '1', $this->getLang('autorewrite'), '', 'block', ($this->getConf('autorewrite') ? array('checked'=>'checked') : array()))); $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); $form->endFieldset(); $form->printForm(); @@ -249,6 +250,7 @@ function handle() { if (isset($_POST['newnsname'])) $this->opts['newnsname'] = cleanID((string)$_POST['newnsname']); if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; if (isset($_POST['autoskip'])) $this->opts['autoskip'] = true; + if (isset($_POST['autorewrite'])) $this->opts['autorewrite'] = true; if (isset($_POST['contenttomove']) && in_array($_POST['contenttomove'], array('pages', 'media', 'both'), true)) $this->opts['contenttomove'] = $_POST['contenttomove']; // check the input for completeness diff --git a/conf/default.php b/conf/default.php index 27593d2..f6c5aae 100644 --- a/conf/default.php +++ b/conf/default.php @@ -1,3 +1,4 @@ 1)) { + if($opts['autorewrite'] && @file_exists($files['affected']) && (filesize($files['affected']) > 1)) { if(!$opts['affected']) { // this is the first run, clean up the file $affected = io_readFile($files['affected']); @@ -806,7 +806,7 @@ private function move_files($dir, $opts, $extregex) { * * @param string $id The id of the page that shall be rewritten * @param string|null $text Old content of the page. When null is given the content is loaded from disk. - * @return string The rewritten content + * @return string|bool The rewritten content, false on error */ public function execute_rewrites($id, $text = null) { $meta = $this->getMoveMeta($id); diff --git a/lang/en/lang.php b/lang/en/lang.php index de17e23..6bc18a1 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -56,7 +56,8 @@ $lang['movens'] = 'Move namespace'; $lang['submit'] = 'Submit'; $lang['content_to_move'] = 'Content to move:'; -$lang['autoskip'] = 'ignore errors'; +$lang['autoskip'] = 'Ignore errors and skip pages that can\'t be moved'; +$lang['autorewrite'] = 'Rewrite links right after the move completed'; $lang['move_pages'] = 'Pages'; $lang['move_media'] = 'Media files'; $lang['move_media_and_pages'] = 'Pages and media files'; diff --git a/lang/en/settings.php b/lang/en/settings.php index 7438d57..e86b6c6 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -1,3 +1,4 @@ Date: Wed, 26 Mar 2014 11:10:18 +0100 Subject: [PATCH 067/338] move namespace subscriptions when moving namespaces --- helper.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/helper.php b/helper.php index 3e6ecaa..3e646b7 100644 --- a/helper.php +++ b/helper.php @@ -86,6 +86,8 @@ public function start_namespace_move(&$opts) { */ public function continue_namespace_move() { global $ID; + global $conf; + $files = $this->get_namespace_meta_files(); if (!@file_exists($files['opts'])) { @@ -214,6 +216,18 @@ public function continue_namespace_move() { return max(1, $opts['remaining']); // force one more call } + // move all namespace subscriptions + $this->move_files( + $conf['metadir'], + array( + 'ns' => $opts['ns'], + 'newns' => $opts['newns'], + 'name' => '', + 'newname' => '' + ), + '\.mlist' + ); + // still here? the move is completed $this->abort_namespace_move(); return 0; @@ -778,7 +792,7 @@ private function move_files($dir, $opts, $extregex) { $dh = @opendir($old_path); if($dh) { while(($file = readdir($dh)) !== false) { - if (substr($file, 0, 1) == '.') continue; + if ($file == '.' || $file == '..') continue; $match = array(); if (is_file($old_path.'/'.$file) && preg_match($regex, $file, $match)) { if (!is_dir($new_path)) { From 4ae5c02ec6cb85740918b1a7c09ba2bb9e5333b1 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 26 Mar 2014 11:53:40 +0100 Subject: [PATCH 068/338] make commit messages more easy recognizable the added symbol makes it easier to mentally filter out automatic changes when looking at the changelog --- helper.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/helper.php b/helper.php index 3e646b7..02b18c3 100644 --- a/helper.php +++ b/helper.php @@ -13,6 +13,11 @@ */ class helper_plugin_move extends DokuWiki_Plugin { + /** + * @var string symbol to make move operations easily recognizable in change log + */ + public $symbol = '↷'; + /** * @var array access to the info the last move in execution * @@ -562,11 +567,11 @@ public function move_page(&$opts, $checkonly = false) { if ($oldRev == time()) sleep(1); $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); - saveWikiText($opts['new_id'], $text, $summary); + saveWikiText($opts['new_id'], $text, $this->symbol.' '.$summary); // Delete the orginal file if (@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($ID, '', $this->getLang('delete') ); + saveWikiText($ID, '', $this->symbol.' '.$summary ); } // Move the old revisions @@ -838,7 +843,7 @@ public function execute_rewrites($id, $text = null) { // Wait a second if page has just been saved $oldRev = getRevisions($id, -1, 1, 1024); // from changelog if ($oldRev == time()) sleep(1); - saveWikiText($id, $text, $this->getLang('linkchange')); + saveWikiText($id, $text, $this->symbol.' '.$this->getLang('linkchange')); } unset($meta['moves']); unset($meta['media_moves']); From 59486812efa2488502ec8026488d4a7d823b3876 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 26 Mar 2014 12:24:10 +0100 Subject: [PATCH 069/338] allow link adjustments to be minor --- conf/default.php | 1 + conf/metadata.php | 1 + helper.php | 4 ++-- lang/en/settings.php | 5 +++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/conf/default.php b/conf/default.php index f6c5aae..5bbc4a7 100644 --- a/conf/default.php +++ b/conf/default.php @@ -1,4 +1,5 @@ symbol.' '.$summary ); + saveWikiText($ID, '', $this->symbol.' '.$summary); } // Move the old revisions @@ -843,7 +843,7 @@ public function execute_rewrites($id, $text = null) { // Wait a second if page has just been saved $oldRev = getRevisions($id, -1, 1, 1024); // from changelog if ($oldRev == time()) sleep(1); - saveWikiText($id, $text, $this->symbol.' '.$this->getLang('linkchange')); + saveWikiText($id, $text, $this->symbol.' '.$this->getLang('linkchange'), $this->getConf('minor')); } unset($meta['moves']); unset($meta['media_moves']); diff --git a/lang/en/settings.php b/lang/en/settings.php index e86b6c6..cc91d11 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -1,4 +1,5 @@ Date: Wed, 26 Mar 2014 16:35:57 +0100 Subject: [PATCH 070/338] added renaming of pages for normal users This is just the first step. A config for who is allowed to use this feature is still missing. Also a way to add the trigger to any template other than the default dokuwiki one is missing. --- action.php | 138 ++++++++++++++++++++++++++++++++++------------- lang/en/lang.php | 6 +++ script.js | 78 +++++++++++++++++++++++++++ sprite.png | Bin 0 -> 303 bytes style.less | 26 +++++++++ 5 files changed, 211 insertions(+), 37 deletions(-) create mode 100644 sprite.png diff --git a/action.php b/action.php index 95e8faa..c54f86a 100644 --- a/action.php +++ b/action.php @@ -23,6 +23,7 @@ public function register(Doku_Event_Handler $controller) { $controller->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, 'handle_index_version'); $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'index_media_use'); $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call'); + $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'addbutton'); } /** @@ -165,7 +166,7 @@ private function get_media_references_from_instructions($instructions, &$media_r } /** - * Handle the plugin_move_ns_continue ajax call + * Handle the AJAX calls for our plugin * * @param Doku_Event $event The event that is handled * @param array $params Optional parameters (unused) @@ -174,45 +175,108 @@ public function handle_ajax_call(Doku_Event $event, $params) { if ($event->data == 'plugin_move_ns_continue') { $event->preventDefault(); $event->stopPropagation(); + $this->ajax_continue(); + } elseif($event->data == 'plugin_move_rename') { + $event->preventDefault(); + $event->stopPropagation(); + $this->ajax_rename(); + } + } - /** @var helper_plugin_move $helper */ - $helper = $this->loadHelper('move', false); - $opts = $helper->get_namespace_move_opts(); - $id = cleanID((string)$_POST['id']); - $skip = (string)$_POST['skip']; - if ($opts !== false) { - if ($skip == 'true') { - $helper->skip_namespace_move_item(); - } - $remaining = $helper->continue_namespace_move(); - $newid = $helper->getNewID($id, $opts['ns'], $opts['newns']); - - $result = array(); - $result['remaining'] = $remaining; - $result['pages'] = $opts['num_pages']; - $result['media'] = $opts['num_media']; - $result['redirect_url'] = wl($newid, '', true); - ob_start(); - html_msgarea(); - if ($remaining === false) { - ptln('

'.sprintf($this->getLang('ns_move_error'), $opts['ns'], $opts['newns']).'

'); - echo $helper->getNSMoveButton('tryagain', $id); - echo $helper->getNSMoveButton('skip', $id); - echo $helper->getNSMoveButton('abort', $id); - } else { - ptln('

'.sprintf($this->getLang('ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

'); - } - $result['html'] = ob_get_clean(); + /** + * Run the next step during a namespace move + */ + protected function ajax_continue() { + /** @var helper_plugin_move $helper */ + $helper = $this->loadHelper('move', false); + $opts = $helper->get_namespace_move_opts(); + $id = cleanID((string)$_POST['id']); + $skip = (string)$_POST['skip']; + if ($opts !== false) { + if ($skip == 'true') { + $helper->skip_namespace_move_item(); + } + $remaining = $helper->continue_namespace_move(); + $newid = $helper->getNewID($id, $opts['ns'], $opts['newns']); + + $result = array(); + $result['remaining'] = $remaining; + $result['pages'] = $opts['num_pages']; + $result['media'] = $opts['num_media']; + $result['redirect_url'] = wl($newid, '', true); + ob_start(); + html_msgarea(); + if ($remaining === false) { + ptln('

'.sprintf($this->getLang('ns_move_error'), $opts['ns'], $opts['newns']).'

'); + echo $helper->getNSMoveButton('tryagain', $id); + echo $helper->getNSMoveButton('skip', $id); + echo $helper->getNSMoveButton('abort', $id); } else { - $result = array(); - $result['remaining'] = 0; - $result['pages'] = 0; - $result['media'] = 0; - $result['redirect_url'] = wl('', '', true); - $result['html'] = ''; + ptln('

'.sprintf($this->getLang('ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

'); } - $json = new JSON(); - echo $json->encode($result); + $result['html'] = ob_get_clean(); + } else { + $result = array(); + $result['remaining'] = 0; + $result['pages'] = 0; + $result['media'] = 0; + $result['redirect_url'] = wl('', '', true); + $result['html'] = ''; } + $json = new JSON(); + echo $json->encode($result); + } + + /** + * Rename a single page + */ + protected function ajax_rename() { + global $ID; + global $MSG; + + $json = new JSON(); + + /** @var helper_plugin_move $helper */ + $helper = $this->loadHelper('move', false); + $ID = cleanID((string) $_POST['id']); + $newid = cleanID((string) $_POST['newid']); + + $opts = array( + 'newns' => getNS($newid), + 'newname' => noNS($newid), + ); + + header('Content-Type: application/json'); + if(!$helper->move_page($opts)){ + echo $json->encode( + array( + 'error' => $MSG[0]['msg'] // first error + ) + ); + } else { + echo $json->encode( + array( + 'redirect_url' => wl($newid, '', true, '&') + ) + ); + } + } + + public function addbutton(Doku_Event $event, $params) { + global $conf; + if ($event->data['view'] != 'main') return; + + switch($conf['template']) { + case 'dokuwiki': + case 'arago': + + $newitem = '
  • '.$this->getLang('renamepage').'
  • '; + $offset = count($event->data['items']) - 1; + $event->data['items'] = + array_slice($event->data['items'], 0, $offset, true) + + array( 'plugin_move' => $newitem) + + array_slice($event->data['items'], $offset, NULL, true); + break; + } } } \ No newline at end of file diff --git a/lang/en/lang.php b/lang/en/lang.php index 6bc18a1..b225ed8 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -64,3 +64,9 @@ // JavaScript preview $lang['js']['previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; $lang['js']['previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; + +$lang['renamepage'] = 'Rename Page'; +$lang['js']['rename'] = 'Rename'; +$lang['js']['cancel'] = 'Cancel'; +$lang['js']['newname'] = 'New name:'; +$lang['js']['inprogress'] = 'renaming page and adjusting links...'; diff --git a/script.js b/script.js index 529ef26..c23f532 100644 --- a/script.js +++ b/script.js @@ -103,4 +103,82 @@ jQuery(function() { .addClass('closed'); }); + // page move dialog + // FIXME check permissions + jQuery('.plugin_move_page') + .show() + .click(function(e) { + e.preventDefault(); + + var renameFN = function () { + var self = this; + var newid = $dialog.find('input[name=id]').val(); + if (!newid) return; + + // remove buttons and show throbber + $dialog.html( + ' '+ + LANG.plugins.move.inprogress + ); + $dialog.dialog('option', 'buttons', []); + + // post the data + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_rename', + id: JSINFO.id, + newid: newid + }, + // redirect or display error + function (result) { + if(result.error){ + $dialog.html(result.error); + } else { + window.location.href = result.redirect_url; + } + } + ); + + return false; + }; + + // basic dialog template + var $dialog = jQuery( + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + ); + $dialog.find('input[name=id]').val(JSINFO.id); + $dialog.find('form').submit(renameFN); + + // set up the dialog + $dialog.dialog({ + title: LANG.plugins.move.rename+' '+JSINFO.id, + width: 340, + height: 180, + dialogClass: 'plugin_move_dialog', + modal: true, + buttons: [ + { + text: LANG.plugins.move.cancel, + click: function () { + $dialog.dialog("close"); + } + }, + { + text: LANG.plugins.move.rename, + click: renameFN + } + ], + // remove HTML from DOM again + close: function () { + jQuery(this).remove(); + } + }) + }); }); \ No newline at end of file diff --git a/sprite.png b/sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..b9a5faab76be4bdbbe0f76e5bf978fe26338bf93 GIT binary patch literal 303 zcmV+~0nq-5P)ST5Czb4lmU`KGJ;oNlB?aOr)CmXV1x`3Hb{zq6da6v#vCU4uL30eeKsI*M4-g@ z7n-Jd6452o_&qaUV}oBrbjuL>_&#CgN!B^$rZt$^48=^Gas@~g72IbWKj&C-MeT9u zsa`Z!flBbme>Wv|Tk742mMXNjYnEJ{c&2{Usnr(s$wV-M5v&$`4;%vk0001d{QP28 zb(gh?+BzH8M6K#>lO}5GtZoyvb=C~UOdRS@Vzc1?X`&Xj$4R}+xe8Q*NB+AhfhOvr z(B7_Da&_XF`cZZ0001RP;dIJK@jvO!o>gp002ovPDHLkV1m2s Bf#?7L literal 0 HcmV?d00001 diff --git a/style.less b/style.less index 9d402c7..53738fa 100644 --- a/style.less +++ b/style.less @@ -3,4 +3,30 @@ cursor: pointer; color: @ini_link; } +} + +.plugin_move_page { + display: none; // will be shown by JavaScript +} + + +/** + * Pagetool icon + */ +#dokuwiki__pagetools ul li.plugin_move_page a { + background-position: right 0; +} +#dokuwiki__pagetools ul li.plugin_move_page a:before { + content: url(sprite.png); + margin-top: 0; +} +#dokuwiki__pagetools:hover ul li.plugin_move_page a, +#dokuwiki__pagetools ul li.plugin_move_page a:focus, +#dokuwiki__pagetools ul li.plugin_move_page a:active { + background-image: url(sprite.png); +} +#dokuwiki__pagetools ul li.plugin_move_page a:hover, +#dokuwiki__pagetools ul li.plugin_move_page a:active, +#dokuwiki__pagetools ul li.plugin_move_page a:focus { + background-position: right -45px; } \ No newline at end of file From 9cf66b58fc989543674e61de27f9a63afaae7388 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 27 Mar 2014 12:11:53 +0100 Subject: [PATCH 071/338] allow renaming of pages for certain groups only also adds a tpl function for easier integration --- action.php | 35 +++++++++++++++++++++++++++++++++-- conf/default.php | 1 + conf/metadata.php | 1 + helper.php | 31 ++++++++++++++++++++++++++++++- lang/en/settings.php | 1 + script.js | 4 ++-- 6 files changed, 68 insertions(+), 5 deletions(-) diff --git a/action.php b/action.php index c54f86a..380f4e0 100644 --- a/action.php +++ b/action.php @@ -24,7 +24,19 @@ public function register(Doku_Event_Handler $controller) { $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'index_media_use'); $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call'); $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'addbutton'); - } + $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'initJS'); + } + + /** + * set JavaScript info if renaming of current page is possible + */ + public function initJS() { + global $JSINFO; + global $INFO; + /** @var helper_plugin_move $hlp */ + $hlp = plugin_load('helper', 'move'); + $JSINFO['move_renameokay'] = $hlp->renameOkay($INFO['id']); + } /** * Rewrite pages when they are read and they need to be updated. @@ -233,6 +245,7 @@ protected function ajax_continue() { protected function ajax_rename() { global $ID; global $MSG; + global $USERINFO; $json = new JSON(); @@ -241,13 +254,25 @@ protected function ajax_rename() { $ID = cleanID((string) $_POST['id']); $newid = cleanID((string) $_POST['newid']); + + $opts = array( 'newns' => getNS($newid), 'newname' => noNS($newid), ); header('Content-Type: application/json'); - if(!$helper->move_page($opts)){ + + + if(!auth_isMember($this->getConf('allowrename'), + $_SERVER['REMOTE_USER'], + $USERINFO['grps'])) { + echo $json->encode( + array( + 'error' => 'no permission' // should have never been called - no localization + ) + ); + } elseif(!$helper->move_page($opts)){ echo $json->encode( array( 'error' => $MSG[0]['msg'] // first error @@ -262,6 +287,12 @@ protected function ajax_rename() { } } + /** + * Adds a button to the default template + * + * @param Doku_Event $event + * @param $params + */ public function addbutton(Doku_Event $event, $params) { global $conf; if ($event->data['view'] != 'main') return; diff --git a/conf/default.php b/conf/default.php index 5bbc4a7..d5cccd3 100644 --- a/conf/default.php +++ b/conf/default.php @@ -1,5 +1,6 @@ getConf('allowrename'), $_SERVER['REMOTE_USER'], $USERINFO['grps'])) return false; + + return true; + } + + /** + * Use this in your template to add a simple "move this page" link + * + * Alternatively give anything the class "plugin_move_page" - it will automatically be hidden and shown and + * trigger the page move dialog. + */ + public function tpl() { + echo ''; + echo $this->getLang('renamepage'); + echo ''; + } } /** diff --git a/lang/en/settings.php b/lang/en/settings.php index cc91d11..b4b5328 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -1,5 +1,6 @@ Date: Thu, 27 Mar 2014 12:27:45 +0100 Subject: [PATCH 072/338] adjusted gamma of sprite to match the other images --- sprite.png | Bin 303 -> 343 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/sprite.png b/sprite.png index b9a5faab76be4bdbbe0f76e5bf978fe26338bf93..ed8cc3cdaa6557b269778f3cfaa582bf94d5ac96 100644 GIT binary patch delta 316 zcmV-C0mJ^U0@nhNB!32COGiWi{{a60|De66lK=n!32;bRa{vGf6951U69E94oEQKA z00(qQO+^RZ0~-q&IqV3tKmY&$KYj6!6pKJ1!taN!>s}&qHh+rWt7<)0_$?wA1JTF# zi>i*asyRO`K~=+GX2fZ$9J>&UYtKFujW)fClgbWfk zNQ!_I9E^O%947j&0wnx>HXw0Cpv3qWnx=UY(IwOPJu_cpgI`2+%MkkbK4Iob);Z>; zHJI59#Y~)X1xOVY+-Dp==U8$@?Q!U-UNl#MO7O^kHzjsk>VMscmMXNjYnEJ{c&2{U zsnr(s$wV-M5v&$`4;%vk0001d{QP28b(gh?+BzH8M6K#>lO}5GtZoyvb=C~UOdRS@ zVzc1?X`&Xj$4R}+xe8Q*NB+AhfhOvr(B7_Da&_XF`cZZ0001R aP;dIJK@jvO!VSd$0000 Date: Wed, 9 Apr 2014 16:09:48 +0200 Subject: [PATCH 073/338] this is some very rough catch all commit it started to restructure the plugin's file structure and added a first tree manager GUI --- action.php | 23 ++ admin.php => admin/simple.php | 2 +- admin/tree.php | 104 ++++++++ lang/en/lang.php | 2 + script.js | 184 +------------ script/json2.js | 486 ++++++++++++++++++++++++++++++++++ script/move.js | 103 +++++++ script/rename.js | 82 ++++++ script/tree.js | 69 +++++ style.less | 7 + 10 files changed, 883 insertions(+), 179 deletions(-) rename admin.php => admin/simple.php (99%) create mode 100644 admin/tree.php create mode 100644 script/json2.js create mode 100644 script/move.js create mode 100644 script/rename.js create mode 100644 script/tree.js diff --git a/action.php b/action.php index 380f4e0..7286b6a 100644 --- a/action.php +++ b/action.php @@ -192,6 +192,10 @@ public function handle_ajax_call(Doku_Event $event, $params) { $event->preventDefault(); $event->stopPropagation(); $this->ajax_rename(); + } elseif($event->data == 'plugin_move_tree') { + $event->preventDefault(); + $event->stopPropagation(); + $this->ajax_tree(); } } @@ -287,6 +291,25 @@ protected function ajax_rename() { } } + protected function ajax_tree() { + + //FIXME user auth + + global $INPUT; + $ns = cleanID($INPUT->str('ns')); + + /** @var admin_plugin_move_tree $plugin */ + $plugin = plugin_load('admin', 'move_tree'); + + $data = $plugin->tree($ns, $ns); + + echo html_buildlist( + $data, 'plugin_move_tree', + array($plugin, 'html_list'), + array($plugin, 'html_li') + ); + } + /** * Adds a button to the default template * diff --git a/admin.php b/admin/simple.php similarity index 99% rename from admin.php rename to admin/simple.php index 03b317b..03c2494 100644 --- a/admin.php +++ b/admin/simple.php @@ -13,7 +13,7 @@ /** * Admin component of the move plugin. Provides the user interface. */ -class admin_plugin_move extends DokuWiki_Admin_Plugin { +class admin_plugin_move_simple extends DokuWiki_Admin_Plugin { var $opts = array(); private $ns_opts = false; diff --git a/admin/tree.php b/admin/tree.php new file mode 100644 index 0000000..72e7f42 --- /dev/null +++ b/admin/tree.php @@ -0,0 +1,104 @@ +getLang('treemanager'); + } + + public function handle() { + + } + + public function html() { + + $data = $this->tree(); + + // wrap a list with the root level around the other namespaces + array_unshift( + $data, array( + 'level' => 0, 'id' => '*', 'type' => 'd', + 'open' => 'true', 'label' => $this->getLang('root') + ) + ); + + echo html_buildlist( + $data, 'plugin_move_tree', + array($this, 'html_list'), + array($this, 'html_li') + ); + + + echo ''; + } + + /** + * Build a tree info structure from media and page directories + * + * We reuse some code from the ACL plugin here + * + * @param string $open The hierarchy to open + * @param string $base The namespace to start from + * @return array + */ + function tree($open = '', $base = '') { + $opendir = utf8_encodeFN(str_replace(':', '/', $open)); + $basedir = utf8_encodeFN(str_replace(':', '/', $base)); + + /** @var admin_plugin_acl $aclplugin */ + $aclplugin = plugin_load('admin', 'acl'); + + return $aclplugin->_get_tree($opendir, $basedir); + } + + /** + * Item formatter for the tree view + * + * User function for html_buildlist() + * + * @author Andreas Gohr + */ + function html_list($item) { + $ret = ''; + // what to display + if(!empty($item['label'])) { + $base = $item['label']; + } else { + $base = ':' . $item['id']; + $base = substr($base, strrpos($base, ':') + 1); + } + + if($item['id'] == '*') $item['id'] = ''; + + // namespace or page? + if($item['type'] == 'd') { + $ret .= ''; + $ret .= $base; + $ret .= ''; + } else { + $ret .= ''; + $ret .= noNS($item['id']); + $ret .= ''; + } + return $ret; + } + + /** + * print the opening LI for a list item + * + * @param array $item + * @return string + */ + function html_li($item) { + if($item['id'] == '*') $item['id'] = ''; + + $params = array(); + $params['class'] = ($item['open'] ? 'open' : 'closed') . ' type-' . $item['type']; + $params['data-parent'] = getNS($item['id']); + $params['data-name'] = noNS($item['id']); + $params['data-id'] = $item['id']; + $attr = buildAttributes($params); + return "
  • "; + } + +} \ No newline at end of file diff --git a/lang/en/lang.php b/lang/en/lang.php index b225ed8..b4c51bb 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -15,6 +15,8 @@ $lang['menu'] = 'Page/Namespace Move/Rename...'; $lang['desc'] = 'Page/Namespace Move/Rename Plugin'; +$lang['treemanager'] = 'Page Move Manager'; + $lang['notexist'] = 'The page %s does not exist'; $lang['medianotexist'] = 'The media file %s does not exist'; $lang['notwrite'] = 'You do not have sufficient permissions to modify this page'; diff --git a/script.js b/script.js index 06bd267..1963ad3 100644 --- a/script.js +++ b/script.js @@ -1,184 +1,12 @@ /** - * JavasScript code for the preview in the move plugin + * includes all needed JavaScript for the move plugin * - * @author Michael Hamann + * be sure to touch this file when one of the scripts has been updated to refresh caching */ +/* DOKUWIKI:include_once script/json2.js */ jQuery(function() { - jQuery('form.move__form').each(function() { - var $this = jQuery(this); - var $preview = jQuery('

    '); - $this.find('input[type=submit]').before($preview); - var updatePreview = function() { - if ($this.find('input[name=move_type]').val() == 'namespace') { - var targetns = $this.find('select[name=targetns]').val(); - var newnsname = $this.find('input[name=newnsname]').val(); - var previewns; - if (targetns == ':') { - previewns = newnsname; - } else { - previewns = targetns + ':' + newnsname; - } - $preview.text(LANG['plugins']['move']['previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); - } else { - var ns_for_page = $this.find('select[name=ns_for_page]').val(); - var newns = $this.find('input[name=newns]').val(); - var newname = $this.find('input[name=newname]').val(); - var newid = ''; - if (typeof newns == 'undefined') { - return; - } - if (newns.replace(/\s/g) != '') { - newid = newns + ':'; - } else if (ns_for_page != ':') { - newid = ns_for_page + ':'; - } - newid += newname; - $preview.text(LANG['plugins']['move']['previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); - - } - }; - updatePreview(); - $this.find('input,select').change(updatePreview); - $this.find('input').keyup(updatePreview); - }); - - jQuery('form.move__nscontinue').each(function() { - var $this = jQuery(this); - var $container = jQuery('div.plugin__move_forms'); - var submit_handler = function() { - $container.empty(); - var $progressbar = jQuery('
    '); - $container.append($progressbar); - $progressbar.progressbar({value: false}); - var $message = jQuery('
    '); - $container.append($message); - var skip = jQuery(this).hasClass('move__nsskip'); - - var continue_move = function() { - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - { - call: 'plugin_move_ns_continue', - id: JSINFO['id'], - skip: skip - }, - function(data) { - if (data.remaining === false) { - $progressbar.progressbar('option', 'value', false); - } else { - $progressbar.progressbar('option', 'value', data.pages + data.media + data.affected - data.remaining); - $progressbar.progressbar('option', 'max', data.pages + data.media + data.affected); - } - $message.html(data.html); - if (data.remaining === false) { - $container.find('form.move__nscontinue, form.move__nsskip').submit(submit_handler); - } else if (data.remaining === 0) { - window.location.href = data.redirect_url; - } else { - window.setTimeout(continue_move, 200); - } - }, - 'json' - ); - skip = false; - }; - - continue_move(); - return false; - }; - $this.submit(submit_handler); - }); - - // hide preview list on namespace move - jQuery('#move__preview_list').each(function(){ - var $this = jQuery(this); - $this.find('ul').hide(); - $this.find('span') - .click(function(){ - console.log('woah'); - $this.find('ul').dw_toggle(); - $this.find('span').toggleClass('closed'); - }) - .addClass('closed'); - }); - - // page move dialog - if(JSINFO.move_renameokay) - jQuery('.plugin_move_page') - .show() - .click(function(e) { - e.preventDefault(); - - var renameFN = function () { - var self = this; - var newid = $dialog.find('input[name=id]').val(); - if (!newid) return; - - // remove buttons and show throbber - $dialog.html( - ' '+ - LANG.plugins.move.inprogress - ); - $dialog.dialog('option', 'buttons', []); - - // post the data - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - { - call: 'plugin_move_rename', - id: JSINFO.id, - newid: newid - }, - // redirect or display error - function (result) { - if(result.error){ - $dialog.html(result.error); - } else { - window.location.href = result.redirect_url; - } - } - ); - - return false; - }; - - // basic dialog template - var $dialog = jQuery( - '
    ' + - '
    ' + - '' + - '
    ' + - '
    ' - ); - $dialog.find('input[name=id]').val(JSINFO.id); - $dialog.find('form').submit(renameFN); - - // set up the dialog - $dialog.dialog({ - title: LANG.plugins.move.rename+' '+JSINFO.id, - width: 340, - height: 180, - dialogClass: 'plugin_move_dialog', - modal: true, - buttons: [ - { - text: LANG.plugins.move.cancel, - click: function () { - $dialog.dialog("close"); - } - }, - { - text: LANG.plugins.move.rename, - click: renameFN - } - ], - // remove HTML from DOM again - close: function () { - jQuery(this).remove(); - } - }) - }); + /* DOKUWIKI:include script/tree.js */ + /* DOKUWIKI:include script/move.js */ + /* DOKUWIKI:include script/rename.js */ }); \ No newline at end of file diff --git a/script/json2.js b/script/json2.js new file mode 100644 index 0000000..d89ecc7 --- /dev/null +++ b/script/json2.js @@ -0,0 +1,486 @@ +/* + json2.js + 2013-05-26 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function () { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/script/move.js b/script/move.js new file mode 100644 index 0000000..a0c4980 --- /dev/null +++ b/script/move.js @@ -0,0 +1,103 @@ +/** + * JavasScript code for the preview in the move plugin + * + * @author Michael Hamann + */ + +jQuery('form.move__form').each(function() { + var $this = jQuery(this); + var $preview = jQuery('

    '); + $this.find('input[type=submit]').before($preview); + var updatePreview = function() { + if ($this.find('input[name=move_type]').val() == 'namespace') { + var targetns = $this.find('select[name=targetns]').val(); + var newnsname = $this.find('input[name=newnsname]').val(); + var previewns; + if (targetns == ':') { + previewns = newnsname; + } else { + previewns = targetns + ':' + newnsname; + } + $preview.text(LANG['plugins']['move']['previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); + } else { + var ns_for_page = $this.find('select[name=ns_for_page]').val(); + var newns = $this.find('input[name=newns]').val(); + var newname = $this.find('input[name=newname]').val(); + var newid = ''; + if (typeof newns == 'undefined') { + return; + } + if (newns.replace(/\s/g) != '') { + newid = newns + ':'; + } else if (ns_for_page != ':') { + newid = ns_for_page + ':'; + } + newid += newname; + $preview.text(LANG['plugins']['move']['previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); + + } + }; + updatePreview(); + $this.find('input,select').change(updatePreview); + $this.find('input').keyup(updatePreview); +}); + +jQuery('form.move__nscontinue').each(function() { + var $this = jQuery(this); + var $container = jQuery('div.plugin__move_forms'); + var submit_handler = function() { + $container.empty(); + var $progressbar = jQuery('
    '); + $container.append($progressbar); + $progressbar.progressbar({value: false}); + var $message = jQuery('
    '); + $container.append($message); + var skip = jQuery(this).hasClass('move__nsskip'); + + var continue_move = function() { + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_ns_continue', + id: JSINFO['id'], + skip: skip + }, + function(data) { + if (data.remaining === false) { + $progressbar.progressbar('option', 'value', false); + } else { + $progressbar.progressbar('option', 'value', data.pages + data.media + data.affected - data.remaining); + $progressbar.progressbar('option', 'max', data.pages + data.media + data.affected); + } + $message.html(data.html); + if (data.remaining === false) { + $container.find('form.move__nscontinue, form.move__nsskip').submit(submit_handler); + } else if (data.remaining === 0) { + window.location.href = data.redirect_url; + } else { + window.setTimeout(continue_move, 200); + } + }, + 'json' + ); + skip = false; + }; + + continue_move(); + return false; + }; + $this.submit(submit_handler); +}); + +// hide preview list on namespace move +jQuery('#move__preview_list').each(function(){ + var $this = jQuery(this); + $this.find('ul').hide(); + $this.find('span') + .click(function(){ + console.log('woah'); + $this.find('ul').dw_toggle(); + $this.find('span').toggleClass('closed'); + }) + .addClass('closed'); +}); diff --git a/script/rename.js b/script/rename.js new file mode 100644 index 0000000..7091871 --- /dev/null +++ b/script/rename.js @@ -0,0 +1,82 @@ +/** + * Rename dialog for end users + * + * @author Andreas Gohr + */ +if(JSINFO.move_renameokay) + jQuery('.plugin_move_page') + .show() + .click(function(e) { + e.preventDefault(); + + var renameFN = function () { + var self = this; + var newid = $dialog.find('input[name=id]').val(); + if (!newid) return; + + // remove buttons and show throbber + $dialog.html( + ' '+ + LANG.plugins.move.inprogress + ); + $dialog.dialog('option', 'buttons', []); + + // post the data + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_rename', + id: JSINFO.id, + newid: newid + }, + // redirect or display error + function (result) { + if(result.error){ + $dialog.html(result.error); + } else { + window.location.href = result.redirect_url; + } + } + ); + + return false; + }; + + // basic dialog template + var $dialog = jQuery( + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + ); + $dialog.find('input[name=id]').val(JSINFO.id); + $dialog.find('form').submit(renameFN); + + // set up the dialog + $dialog.dialog({ + title: LANG.plugins.move.rename+' '+JSINFO.id, + width: 340, + height: 180, + dialogClass: 'plugin_move_dialog', + modal: true, + buttons: [ + { + text: LANG.plugins.move.cancel, + click: function () { + $dialog.dialog("close"); + } + }, + { + text: LANG.plugins.move.rename, + click: renameFN + } + ], + // remove HTML from DOM again + close: function () { + jQuery(this).remove(); + } + }) + }); diff --git a/script/tree.js b/script/tree.js new file mode 100644 index 0000000..ede9aa8 --- /dev/null +++ b/script/tree.js @@ -0,0 +1,69 @@ +/** + * Script for the tree management interface + */ + + +jQuery('ul.plugin_move_tree') + // make folders open and close via AJAX + .click(function (e) { + var $link = jQuery(e.target); + if ($link.attr('href')) { + e.stopPropagation(); + var $li = $link.parent().parent('li'); + + if ($li.hasClass('open')) { + $li + .removeClass('open') + .addClass('closed') + .find('ul').remove(); + } else { + $li + .removeClass('closed') + .addClass('open'); + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_tree', + ns: $link.attr('href') + }, + function (data) { + $li.append(data); + } + ); + } + } + e.preventDefault(); + }) + // initialize sortable + .sortable({ + items: 'li', + stop: function (e, ui) { + var newparent = ui.item.parent().closest('li').attr('data-id'); + var oldparent = ui.item.attr('data-parent'); + + console.log(newparent); + + if (newparent != oldparent) { + ui.item.addClass('moved'); + } else { + ui.item.removeClass('moved'); + } + } + }); + +jQuery('button.plugin_move_tree_exec').click(function(e){ + var data = []; + + jQuery('ul.plugin_move_tree .moved').each(function(idx, el){ + var $el = jQuery(el); + var newparent = $el.parent().closest('li').attr('data-id'); + + data[data.length] = { + type: $el.hasClass('type-d') ? 'd' : 'f', + from: $el.attr('data-id'), + to: newparent + ':' + $el.attr('data-name') + }; + }); + + console.log(JSON.stringify(data)); +}); \ No newline at end of file diff --git a/style.less b/style.less index 53738fa..34794d7 100644 --- a/style.less +++ b/style.less @@ -10,6 +10,13 @@ } +ul.plugin_move_tree { + .moved { + background-color: #b1b100; + } +} + + /** * Pagetool icon */ From b830dfd1ffe02f88ee5d75e56589865e174b18df Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 9 Apr 2014 18:19:05 +0200 Subject: [PATCH 074/338] started major refactoring --- action.php | 16 +- admin/simple.php | 4 +- helper.php => helper/general.php | 3 +- helper/plan.php | 305 +++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 11 deletions(-) rename helper.php => helper/general.php (99%) create mode 100644 helper/plan.php diff --git a/action.php b/action.php index 7286b6a..41321d2 100644 --- a/action.php +++ b/action.php @@ -33,8 +33,8 @@ public function register(Doku_Event_Handler $controller) { public function initJS() { global $JSINFO; global $INFO; - /** @var helper_plugin_move $hlp */ - $hlp = plugin_load('helper', 'move'); + /** @var helper_plugin_move_general $hlp */ + $hlp = plugin_load('helper', 'move_general'); $JSINFO['move_renameokay'] = $hlp->renameOkay($INFO['id']); } @@ -74,8 +74,8 @@ function handle_read(Doku_Event $event, $param) { // the page is locked by the current user || checklock($id) !== false || @file_exists(wikiLockFN($id))) return; - /** @var helper_plugin_move $helper */ - $helper = $this->loadHelper('move', true); + /** @var helper_plugin_move_general $helper */ + $helper = $this->loadHelper('move_general', true); if(!is_null($helper)) { $stack[$id] = true; $event->result = $helper->execute_rewrites($id, $event->result); @@ -203,8 +203,8 @@ public function handle_ajax_call(Doku_Event $event, $params) { * Run the next step during a namespace move */ protected function ajax_continue() { - /** @var helper_plugin_move $helper */ - $helper = $this->loadHelper('move', false); + /** @var helper_plugin_move_general $helper */ + $helper = $this->loadHelper('move_general', false); $opts = $helper->get_namespace_move_opts(); $id = cleanID((string)$_POST['id']); $skip = (string)$_POST['skip']; @@ -253,8 +253,8 @@ protected function ajax_rename() { $json = new JSON(); - /** @var helper_plugin_move $helper */ - $helper = $this->loadHelper('move', false); + /** @var helper_plugin_move_general $helper */ + $helper = $this->loadHelper('move_general', false); $ID = cleanID((string) $_POST['id']); $newid = cleanID((string) $_POST['newid']); diff --git a/admin/simple.php b/admin/simple.php index 03c2494..1e2db57 100644 --- a/admin/simple.php +++ b/admin/simple.php @@ -17,7 +17,7 @@ class admin_plugin_move_simple extends DokuWiki_Admin_Plugin { var $opts = array(); private $ns_opts = false; - /** @var helper_plugin_move $helper */ + /** @var helper_plugin_move_general $helper */ private $helper = null; /** @var string $ns_move_state The state of the current namespace move (none, started, continued, error) */ private $ns_move_state = 'none'; @@ -213,7 +213,7 @@ function handle() { $this->opts['move_type'] = 'page'; $this->opts['contenttomove'] = 'pages'; - $this->helper = $this->loadHelper('move', true); + $this->helper = $this->loadHelper('move_general', true); if (!$this->helper) return; $this->ns_opts = $this->helper->get_namespace_move_opts(); diff --git a/helper.php b/helper/general.php similarity index 99% rename from helper.php rename to helper/general.php index eae77ee..37b02e9 100644 --- a/helper.php +++ b/helper/general.php @@ -11,7 +11,7 @@ /** * Helper part of the move plugin. */ -class helper_plugin_move extends DokuWiki_Plugin { +class helper_plugin_move_general extends DokuWiki_Plugin { /** * @var string symbol to make move operations easily recognizable in change log @@ -422,6 +422,7 @@ public function get_namespace_move_opts() { * Get the filenames for the metadata of the move plugin * * @return array The file names for opts, pagelist and medialist + * @moved */ protected function get_namespace_meta_files() { global $conf; diff --git a/helper/plan.php b/helper/plan.php new file mode 100644 index 0000000..f9590bd --- /dev/null +++ b/helper/plan.php @@ -0,0 +1,305 @@ + + * @author Andreas Gohr + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +define('PLUGIN_MOVE_TYPE_PAGES', 1); +define('PLUGIN_MOVE_TYPE_MEDIA', 2); +define('PLUGIN_MOVE_CLASS_NS', 4); +define('PLUGIN_MOVE_CLASS_DOC', 8); + +/** + * Class helper_plugin_move_plan + * + * This thing prepares and keeps progress info on complex move operations (eg. where more than a single + * object is affected. + * + * Glossary: + * + * document - refers to either a page or a media file here + */ +class helper_plugin_move_plan extends DokuWiki_Plugin { + + + /** + * @var array the options for this move plan + */ + protected $options = array( + // status + 'committed' => false, + 'started' => 0, + + // counters + 'pages' => 0, + 'media' => 0, + 'affected' => 0, + ); + + /** + * @var array holds the location of the different list and state files + */ + protected $files = array(); + + /** + * @var array the planned moves + */ + protected $plan = array(); + + /** + * Constructor + * + * initializes state (if any) for continuiation of a running move op + */ + public function __construct() { + global $conf; + + // set the file locations + $this->files = array( + 'opts' => $conf['metadir'] . '/__move_opts', + 'pagelist' => $conf['metadir'] . '/__move_pagelist', + 'medialist' => $conf['metadir'] . '/__move_medialist', + 'affected' => $conf['metadir'] . '/__move_affected', + ); + + $this->loadOptions(); + } + + /** + * Check if there is a move in progress currently + * + * @return bool + */ + public function inProgress() { + return $this->options['committed']; + } + + /** + * Plans the move of a namespace or document + * + * @param string $src ID of the item to move + * @param string $dst new ID of item namespace + * @param int $class (PLUGIN_MOVE_CLASS_NS|PLUGIN_MOVE_CLASS_DOC) + * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) + * @throws Exception + */ + public function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGIN_MOVE_TYPE_PAGES) { + if($this->options['commited']) throw new Exception('plan is commited already, can not be added to'); + + $src = cleanID($src); + $dst = cleanID($dst); + + // FIXME make sure source exists + + $this->plan[] = array( + 'src' => $src, + 'dst' => $dst, + 'class' => $class, + 'type' => $type + ); + } + + /** + * This locks up the plan and prepares execution + * + * the plan is reordered an the needed move operations are gathered and stored in the appropriate + * list files + */ + public function commit() { + global $conf; + + if($this->options['commited']) throw new Exception('plan is commited already, can not be commited again'); + + usort($this->plan, array($this, 'planSorter')); + + // get all the documents to be moved and store them in their lists + foreach($this->plan as $move) { + if($move['class'] == PLUGIN_MOVE_CLASS_DOC) { + // these can just be added + if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + $this->addToPageList($move['src'], $move['dst']); + } else { + $this->addToMediaList($move['src'], $move['dst']); + } + } else { + // here we need a list of content first, search for it + $docs = array(); + $path = utf8_encodeFN(str_replace(':', '/', $move['src'])); + $opts = array('depth' => 0, 'skipacl' => true); + if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + search($docs, $conf['datadir'], 'search_allpages', $opts, $path); + } else { + search($docs, $conf['mediadir'], 'search_media', $opts, $path); + } + + // how much namespace to strip? + if($move['src'] !== '') { + $strip = strlen($move['src']) + 1; + } else { + $strip = 0; + } + if($move['dst']) $move['dst'] .= ':'; + + // now add all the found documents to our lists + foreach($docs as $doc) { + $from = $doc['id']; + $to = $move['dst'] . substr($doc['id'], $strip); + + if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + $this->addToPageList($from, $to); + } else { + $this->addToMediaList($from, $to); + } + } + } + } + + $this->options['committed'] = true; + $this->options['started'] = time(); + } + + public function nextStep() { + if(!$this->options['commited']) throw new Exception('plan is not committed yet!'); + } + + /** + * Save the current options + * + * @return bool + */ + protected function saveOptions(){ + return io_saveFile($this->files['opts'], serialize($this->options)); + } + + /** + * Load the current options if any + * + * @return bool + */ + protected function loadOptions() { + $file = $this->files['opts']; + if(!file_exists($file)) return false; + $this->options = unserialize(io_readFile($file, false)); + return true; + } + + /** + * Appends a page move operation in the list file + * + * @param string $src + * @param string $dst + * @return bool + */ + protected function addToPageList($src, $dst) { + $file = $this->files['pagelist']; + + if(io_saveFile($file, "$src\t$dst\n", true)) { + $this->options['pages']++; + return true; + } + return false; + } + + /** + * Appends a media move operation in the list file + * + * @param string $src + * @param string $dst + * @return bool + */ + protected function addToMediaList($src, $dst) { + $file = $this->files['medialist']; + + if(io_saveFile($file, "$src\t$dst\n", true)) { + $this->options['media']++; + return true; + } + return false; + } + + /** + * Get the last line from the list that is stored in the file that is referenced by the handle + * The handle is set to the newline before the file id + * + * @param resource $handle The file handle to read from + * @return string|bool the last id from the list or false if there is none + */ + protected function getLastLine($handle) { + // begin the seek at the end of the file + fseek($handle, 0, SEEK_END); + $line = ''; + + // seek one backwards as long as it's possible + while (fseek($handle, -1, SEEK_CUR) >= 0) { + $c = fgetc($handle); + fseek($handle, -1, SEEK_CUR); // reset the position to the character that was read + + if ($c == "\n") { + break; + } + if ($c === false) return false; // EOF, i.e. the file is empty + $line = $c.$line; + } + + if ($line === '') return false; // nothing was read i.e. the file is empty + return $line; + } + + + /** + * Callback for usort to sort the move plan + * + * Note that later on all lists will be worked on in reversed order, so we reverse what we + * do from what we want here + * + * @param $a + * @param $b + * @return int + */ + public function planSorter($a, $b) { + // do page moves before namespace moves + if($a['class'] == PLUGIN_MOVE_CLASS_DOC && $b['class'] == PLUGIN_MOVE_CLASS_NS) { + return 1; + } + if($a['class'] == PLUGIN_MOVE_CLASS_NS && $b['class'] == PLUGIN_MOVE_CLASS_DOC) { + return -1; + } + + // do pages before media + if($a['type'] == PLUGIN_MOVE_TYPE_PAGES && $b['type'] == PLUGIN_MOVE_TYPE_MEDIA) { + return 1; + } + if($a['type'] == PLUGIN_MOVE_TYPE_MEDIA && $b['type'] == PLUGIN_MOVE_TYPE_PAGES) { + return -1; + } + + // from here on we compare only apples to apples + // we sort by depth of namespace, deepest namespaces first + + $alen = substr_count($a['src'], ':'); + $blen = substr_count($a['src'], ':'); + + if($alen > $blen) { + return 1; + } elseif($alen < $blen) { + return -1; + } + return 0; + } + + /** + * Get the filenames for the metadata of the move plugin + * + * @return array The file names for opts, pagelist and medialist + */ + protected function get_namespace_meta_files() { + global $conf; + + } + +} \ No newline at end of file From f8f27cb43f9b0a8c9c9d508f9ba8bc3198aec1dc Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 9 Apr 2014 18:58:21 +0200 Subject: [PATCH 075/338] started moving move ops to it's own class --- helper/op.php | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 helper/op.php diff --git a/helper/op.php b/helper/op.php new file mode 100644 index 0000000..a86850a --- /dev/null +++ b/helper/op.php @@ -0,0 +1,287 @@ + + * @author Gary Owen + * @author Andreas Gohr + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +class helper_plugin_move_op extends DokuWiki_Plugin { + + /** + * @var string symbol to make move operations easily recognizable in change log + */ + public $symbol = '↷'; + + /** + * Check if the given page can be moved to the given destination + * + * @param $src + * @param $dst + * @return bool + */ + public function checkPage($src, $dst) { + // Check we have rights to move this document + if(!page_exists($src)) { + msg(sprintf($this->getLang('notexist'), $src), -1); + return false; + } + if(auth_quickaclcheck($src) < AUTH_EDIT) { + msg(sprintf($this->getLang('norights'), hsc($src)), -1); + return false; + } + + // Check file is not locked + // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user + // the file exists check checks if the page is reported unlocked if a lock exists which means that + // the page is locked by the current user + if(checklock($src) !== false || @file_exists(wikiLockFN($src))) { + msg(sprintf($this->getLang('filelocked'), hsc($src)), -1); + return false; + } + + // Has the document name and/or namespace changed? + if($src == $dst) { + msg($this->getLang('nochange'), -1); + return false; + } + + // Check the page does not already exist + if(page_exists($dst)) { + msg(sprintf($this->getLang('existing'), $dst), -1); + return false; + } + + // Check if the current user can create the new page + if(auth_quickaclcheck($dst) < AUTH_CREATE) { + msg(sprintf($this->getLang('notargetperms'), $dst), -1); + return false; + } + + return true; + } + + /** + * Execute a page rename + * + * @param string $src + * @param string $dst + * @return bool + */ + public function movePage($src, $dst) { + if(!$this->checkPage($src, $dst)) return false; + + // remember what this page was called before the move in meta data + $page_meta = $this->getMoveMeta($src); + if(!$page_meta) $page_meta = array(); + if(!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); + $page_meta['old_ids'][$src] = time(); + + // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages + $affected_pages = idx_get_indexer()->lookupKey('relation_references', $src); + + // pass this info on to other plugins + $eventdata = array( + // this is for compatibility to old plugin + 'opts' => array( + 'ns' => getNS($src), + 'name' => noNS($src), + 'newns' => getNS($dst), + 'newname' => noNS($dst), + ), + 'old_ids' => $page_meta['old_ids'], + 'affected_pages' => &$affected_pages, + 'src_id' => $src, + 'dst_id' => $dst, + ); + + // 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 + $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $eventdata); + if($event->advise_before()) { + // Open the old document and change forward links + lock($src); + $text = rawWiki($src); + + $text = $this->rewrite_content($text, $src, array($src => $dst)); + $oldRev = getRevisions($src, -1, 1, 1024); // from changelog + + // 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_move_indexer(); // copy of the new code + } + if(($idx_msg = $Indexer->renamePage($src, $dst)) !== true + || ($idx_msg = $Indexer->renameMetaValue('relation_references', $src, $dst)) !== true + ) { + msg('Error while updating the search index ' . $idx_msg, -1); + return false; + } + if(!$this->movemeta($opts)) { + msg('The meta files of page ' . $src . ' couldn\'t be moved', -1); + return false; + } + + // Save the updated document in its new location + if($opts['ns'] == $opts['newns']) { + $lang_key = 'renamed'; + } elseif($opts['name'] == $opts['newname']) { + $lang_key = 'moved'; + } else { + $lang_key = 'move_rename'; + } + + // Wait a second when the page has just been rewritten + if($oldRev == time()) sleep(1); + + $summary = sprintf($this->getLang($lang_key), $src, $opts['new_id']); + saveWikiText($opts['new_id'], $text, $this->symbol . ' ' . $summary); + + // Delete the orginal file + if(@file_exists(wikiFN($opts['new_id']))) { + saveWikiText($src, '', $this->symbol . ' ' . $summary); + } + + // Move the old revisions + if(!$this->moveattic($opts)) { + // it's too late to stop the move, so just display a message. + msg('The attic files of page ' . $src . ' couldn\'t be moved. Please move them manually.', -1); + } + + foreach($affected_pages as $id) { + if(!page_exists($id, '', false) || $id == $src || $id == $opts['new_id']) continue; + // we are only interested in persistent metadata, so no need to render anything. + $meta = $this->getMoveMeta($id); + if(!$meta) $meta = array('moves' => array()); + if(!isset($meta['moves'])) $meta['moves'] = array(); + $meta['moves'] = $this->resolve_moves($meta['moves'], $id); + $meta['moves'][$src] = $opts['new_id']; + //if (empty($meta['moves'])) unset($meta['moves']); + p_set_metadata($id, array('plugin_move' => $meta), false, true); + } + + p_set_metadata($opts['new_id'], array('plugin_move' => $page_meta), false, true); + + unlock($src); + } + + $event->advise_after(); + return true; + } + + /** + * This function loads and returns the persistent metadata for the move plugin. If there is metadata for the + * pagemove plugin (not the old one but the version that immediately preceeded the move plugin) it will be migrated. + * + * @param string $id The id of the page the metadata shall be loaded for + * @return array|null The metadata of the page + */ + public function getMoveMeta($id) { + $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); + // migrate old metadata from the pagemove plugin + if(isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { + if(isset($all_meta['plugin_move'])) { + $all_meta['plugin_move'] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta['plugin_move']); + } else { + $all_meta['plugin_move'] = $all_meta['plugin_pagemove']; + } + p_set_metadata($id, array('plugin_move' => $all_meta['plugin_move'], 'plugin_pagemove' => null), false, true); + } + return isset($all_meta['plugin_move']) ? $all_meta['plugin_move'] : null; + } + + /** + * Rewrite a text in order to fix the content after the given moves. + * + * @param string $text The wiki text that shall be rewritten + * @param string $id The id of the wiki page, if the page itself was moved the old id + * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids + * @param array $media_moves Array of all media moves. + * @return string The rewritten wiki text + */ + protected function rewrite_content($text, $id, $moves, $media_moves = array()) { + $moves = $this->resolve_moves($moves, $id); + $media_moves = $this->resolve_moves($media_moves, $id); + + $handlers = array(); + $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); + + /* + * PLUGIN_MOVE_HANDLERS REGISTER event: + * + * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler + * The handler needs to be a valid callback, it will get the following parameters: + * $match, $state, $pos, $pluginname, $handler. The first three parameters are equivalent to the parameters + * of the handle()-function of syntax plugins, the $pluginname is just the plugin name again so handler functions + * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object. + * It has the following properties and functions that can be used: + * - id, ns: id and namespace of the old page + * - new_id, new_ns: new id and namespace (can be identical to id and ns) + * - moves: array of moves, the same as $moves in the event + * - media_moves: array of media moves, same as $media_moves in the event + * - adaptRelativeId($id): adapts the relative $id according to the moves + */ + trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data); + + $modes = p_get_parsermodes(); + + // Create the parser + $Parser = new Doku_Parser(); + + // Add the Handler + $Parser->Handler = new helper_plugin_move_handler($id, $moves, $media_moves, $handlers); + + //add modes to parser + foreach($modes as $mode) { + $Parser->addMode($mode['mode'], $mode['obj']); + } + + return $Parser->parse($text); + } + + /** + * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. + * + * @param array $moves The moves + * @param string $id + * @return array The resolved moves + */ + protected function resolve_moves($moves, $id) { + // resolve moves of pages that were moved more than once + $tmp_moves = array(); + foreach($moves as $old => $new) { + if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { + // write to temp array in order to correctly handle rename circles + $tmp_moves[$old] = $moves[$new]; + } + } + + $changed = !empty($tmp_moves); + + // this correctly resolves rename circles by moving forward one step a time + while($changed) { + $changed = false; + foreach($tmp_moves as $old => $new) { + if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { + $tmp_moves[$old] = $moves[$new]; + $changed = true; + } + } + } + + // manual merge, we can't use array_merge here as ids can be numeric + foreach($tmp_moves as $old => $new) { + if($old == $new) unset($moves[$old]); + else $moves[$old] = $new; + } + return $moves; + } + +} \ No newline at end of file From 60bde356b2673f9e64254cdd0056565a86ade93c Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 11:09:52 +0200 Subject: [PATCH 076/338] more ongoing refactoring single object move ops should be moved to the new helper completely, the opaque $opts array is gone and everything works on IDs now. completely untested and most probably buggy though --- helper/file.php | 142 ++++++++++++++++++++++++++++++ helper/op.php | 230 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 331 insertions(+), 41 deletions(-) create mode 100644 helper/file.php diff --git a/helper/file.php b/helper/file.php new file mode 100644 index 0000000..06f903a --- /dev/null +++ b/helper/file.php @@ -0,0 +1,142 @@ + + * @author Andreas Gohr + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class helper_plugin_move_file + * + * This helps with moving files from one folder to another. It simply matches files and moves them + * arround. No fancy rewriting happens here. + */ +class helper_plugin_move_file extends DokuWiki_Plugin { + + /** + * Move the meta files of a page + * + * @param string $src_ns The original namespace + * @param string $src_name The original basename of the moved doc (empty for namespace moves) + * @param string $dst_ns The namespace after the move + * @param string $dst_name The basename after the move (empty for namespace moves) + * @return bool If the meta files were moved successfully + */ + public function movePageMeta($src_ns, $src_name, $dst_ns, $dst_name) { + global $conf; + + $regex = '\.[^.]+'; + return $this->execute($conf['metadir'], $src_ns, $src_name, $dst_ns, $dst_name, $regex); + } + + /** + * Move the old revisions of a page + * + * @param string $src_ns The original namespace + * @param string $src_name The original basename of the moved doc (empty for namespace moves) + * @param string $dst_ns The namespace after the move + * @param string $dst_name The basename after the move (empty for namespace moves) + * @return bool If the attic files were moved successfully + */ + public function movePageAttic($src_ns, $src_name, $dst_ns, $dst_name) { + global $conf; + + $regex = '\.\d+\.txt(?:\.gz|\.bz2)?'; + return $this->execute($conf['olddir'], $src_ns, $src_name, $dst_ns, $dst_name, $regex); + } + + /** + * Move the meta files of the page that is specified in the options. + * + * @param string $src_ns The original namespace + * @param string $src_name The original basename of the moved doc (empty for namespace moves) + * @param string $dst_ns The namespace after the move + * @param string $dst_name The basename after the move (empty for namespace moves) + * @return bool If the meta files were moved successfully + */ + public function moveMediaMeta($src_ns, $src_name, $dst_ns, $dst_name) { + global $conf; + + $regex = '\.[^.]+'; + return $this->execute($conf['mediametadir'], $src_ns, $src_name, $dst_ns, $dst_name, $regex); + } + + /** + * Move the old revisions of the media file that is specified in the options + * + * @param string $src_ns The original namespace + * @param string $src_name The original basename of the moved doc (empty for namespace moves) + * @param string $dst_ns The namespace after the move + * @param string $dst_name The basename after the move (empty for namespace moves) + * @return bool If the attic files were moved successfully + */ + public function moveMediaAttic($src_ns, $src_name, $dst_ns, $dst_name) { + global $conf; + + $ext = mimetype($src_name); + if($ext[0] !== false) { + $name = substr($src_name, 0, -1 * strlen($ext[0]) - 1); + } else { + $name = $src_name; + } + $newext = mimetype($dst_name); + if($newext[0] !== false) { + $newname = substr($dst_name, 0, -1 * strlen($newext[0]) - 1); + } else { + $newname = $dst_name; + } + $regex = '\.\d+\.' . preg_quote((string) $ext[0], '/'); + + return $this->execute($conf['mediaolddir'], $src_ns, $name, $dst_ns, $newname, $regex); + } + + /** + * Executes the move op + * + * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] + * @param string $src_ns The original namespace + * @param string $src_name The original basename of the moved doc (empty for namespace moves) + * @param string $dst_ns The namespace after the move + * @param string $dst_name The basename after the move (empty for namespace moves) + * @param string $extregex Regular expression for matching the extension of the file that shall be moved + * @return bool If the files were moved successfully + */ + protected function execute($dir, $src_ns, $src_name, $dst_ns, $dst_name, $extregex) { + $old_path = $dir; + if($src_ns != '') $old_path .= '/' . utf8_encodeFN(str_replace(':', '/', $src_ns)); + $new_path = $dir; + if($dst_ns != '') $new_path .= '/' . utf8_encodeFN(str_replace(':', '/', $dst_ns)); + $regex = '/^' . preg_quote(utf8_encodeFN($src_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) { + if($file == '.' || $file == '..') continue; + $match = array(); + if(is_file($old_path . '/' . $file) && preg_match($regex, $file, $match)) { + if(!is_dir($new_path)) { + if(!io_mkdir_p($new_path)) { + msg('Creating directory ' . hsc($new_path) . ' failed.', -1); + return false; + } + } + if(!io_rename($old_path . '/' . $file, $new_path . '/' . utf8_encodeFN($dst_name . $match[1]))) { + msg('Moving ' . hsc($old_path . '/' . $file) . ' to ' . hsc($new_path . '/' . utf8_encodeFN($dst_name . $match[1])) . ' failed.', -1); + return false; + } + } + } + closedir($dh); + } else { + msg('Directory ' . hsc($old_path) . ' couldn\'t be opened.', -1); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/helper/op.php b/helper/op.php index a86850a..889304b 100644 --- a/helper/op.php +++ b/helper/op.php @@ -17,6 +17,11 @@ class helper_plugin_move_op extends DokuWiki_Plugin { */ public $symbol = '↷'; + /** + * @var array stores the affected pages of the last operation + */ + protected $affectedPages = array(); + /** * Check if the given page can be moved to the given destination * @@ -27,7 +32,7 @@ class helper_plugin_move_op extends DokuWiki_Plugin { public function checkPage($src, $dst) { // Check we have rights to move this document if(!page_exists($src)) { - msg(sprintf($this->getLang('notexist'), $src), -1); + msg(sprintf($this->getLang('notexist'), hsc($src)), -1); return false; } if(auth_quickaclcheck($src) < AUTH_EDIT) { @@ -52,7 +57,7 @@ public function checkPage($src, $dst) { // Check the page does not already exist if(page_exists($dst)) { - msg(sprintf($this->getLang('existing'), $dst), -1); + msg(sprintf($this->getLang('existing'), $dst), -1); // FIXME adjust string return false; } @@ -66,10 +71,49 @@ public function checkPage($src, $dst) { } /** - * Execute a page rename + * Check if the given media file can be moved to the given destination + * + * @param $src + * @param $dst + * @return bool + */ + public function checkMedia($src, $dst) { + // Check we have rights to move this document + if(!file_exists(mediaFN($src))) { + msg(sprintf($this->getLang('medianotexist'), hsc($src)), -1); + return false; + } + if(auth_quickaclcheck($dst) < AUTH_DELETE) { + msg(sprintf($this->getLang('nomediarights'), hsc($src)), -1); + return false; + } + + // Has the document name and/or namespace changed? + if($src == $dst) { + msg($this->getLang('nomediachange'), -1); + return false; + } + + // Check the page does not already exist + if(@file_exists(mediaFN($dst))) { + msg(sprintf($this->getLang('mediaexisting'), $dst), -1); // FIXME adjust string + return false; + } + + // Check if the current user can create the new page + if(auth_quickaclcheck($dst) < AUTH_UPLOAD) { + msg(sprintf($this->getLang('nomediatargetperms'), $dst), -1); + return false; + } + + return true; + } + + /** + * Execute a page move/rename * - * @param string $src - * @param string $dst + * @param string $src original ID + * @param string $dst new ID * @return bool */ public function movePage($src, $dst) { @@ -84,19 +128,24 @@ public function movePage($src, $dst) { // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages $affected_pages = idx_get_indexer()->lookupKey('relation_references', $src); + $src_ns = getNS($src); + $src_name = noNS($src); + $dst_ns = getNS($dst); + $dst_name = noNS($dst); + // pass this info on to other plugins $eventdata = array( // this is for compatibility to old plugin - 'opts' => array( - 'ns' => getNS($src), - 'name' => noNS($src), - 'newns' => getNS($dst), - 'newname' => noNS($dst), + 'opts' => array( + 'ns' => $src_ns, + 'name' => $src_name, + 'newns' => $dst_ns, + 'newname' => $dst_name, ), - 'old_ids' => $page_meta['old_ids'], + 'old_ids' => $page_meta['old_ids'], 'affected_pages' => &$affected_pages, - 'src_id' => $src, - 'dst_id' => $dst, + 'src_id' => $src, + 'dst_id' => $dst, ); // give plugins the option to add their own meta files to the list of files that need to be moved @@ -105,77 +154,176 @@ public function movePage($src, $dst) { // note that old_ids is in the form 'id' => timestamp of move $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $eventdata); if($event->advise_before()) { - // Open the old document and change forward links lock($src); - $text = rawWiki($src); + /** @var helper_plugin_move_file $FileMover */ + $FileMover = plugin_load('helper', 'move_file'); + + // Open the old document and change forward links + $text = rawWiki($src); $text = $this->rewrite_content($text, $src, array($src => $dst)); - $oldRev = getRevisions($src, -1, 1, 1024); // from changelog - // 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_move_indexer(); // copy of the new code - } + // Move the Subscriptions & Indexes (new feature since Spring 2013 release) + $Indexer = idx_get_indexer(); if(($idx_msg = $Indexer->renamePage($src, $dst)) !== true || ($idx_msg = $Indexer->renameMetaValue('relation_references', $src, $dst)) !== true ) { msg('Error while updating the search index ' . $idx_msg, -1); return false; } - if(!$this->movemeta($opts)) { + if(!$FileMover->movePageMeta($src_ns, $src_name, $dst_ns, $dst_name)) { msg('The meta files of page ' . $src . ' couldn\'t be moved', -1); return false; } - // Save the updated document in its new location - if($opts['ns'] == $opts['newns']) { + // prepare the summary for the changelog entry + if($src_ns == $dst_ns) { $lang_key = 'renamed'; - } elseif($opts['name'] == $opts['newname']) { + } elseif($src_name == $dst_name) { $lang_key = 'moved'; } else { $lang_key = 'move_rename'; } + $summary = $this->symbol . ' ' . sprintf($this->getLang($lang_key), $src, $dst); // Wait a second when the page has just been rewritten + $oldRev = filemtime(wikiFN($src)); if($oldRev == time()) sleep(1); - $summary = sprintf($this->getLang($lang_key), $src, $opts['new_id']); - saveWikiText($opts['new_id'], $text, $this->symbol . ' ' . $summary); + // Save the updated document in its new location + saveWikiText($dst, $text, $summary); // Delete the orginal file - if(@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($src, '', $this->symbol . ' ' . $summary); + if(@file_exists(wikiFN($dst))) { + saveWikiText($src, '', $summary); } // Move the old revisions - if(!$this->moveattic($opts)) { + if(!$FileMover->movePageAttic($src_ns, $src_name, $dst_ns, $dst_name)) { // it's too late to stop the move, so just display a message. msg('The attic files of page ' . $src . ' couldn\'t be moved. Please move them manually.', -1); } + // Add meta data to all affected pages, so links get updated later foreach($affected_pages as $id) { - if(!page_exists($id, '', false) || $id == $src || $id == $opts['new_id']) continue; + if(!page_exists($id, '', false) || $id == $src || $id == $dst) continue; // we are only interested in persistent metadata, so no need to render anything. $meta = $this->getMoveMeta($id); if(!$meta) $meta = array('moves' => array()); if(!isset($meta['moves'])) $meta['moves'] = array(); - $meta['moves'] = $this->resolve_moves($meta['moves'], $id); - $meta['moves'][$src] = $opts['new_id']; - //if (empty($meta['moves'])) unset($meta['moves']); + $meta['moves'] = $this->resolve_moves($meta['moves'], $id); + $meta['moves'][$src] = $dst; p_set_metadata($id, array('plugin_move' => $meta), false, true); } - - p_set_metadata($opts['new_id'], array('plugin_move' => $page_meta), false, true); + p_set_metadata($dst, array('plugin_move' => $page_meta), false, true); unlock($src); } + $event->advise_after(); + + // store this for later use + $this->affectedPages = $affected_pages; + + return true; + } + + /** + * Execute a media file move/rename + * + * @param string $src original ID + * @param string $dst new ID + * @return bool true if the move was successfully executed + */ + public function move_media($src, $dst) { + if(!$this->checkMedia($src, $dst)) return false; + + // get all pages using this media + $affected_pages = idx_get_indexer()->lookupKey('relation_media', $src); + + $src_ns = getNS($src); + $src_name = noNS($src); + $dst_ns = getNS($dst); + $dst_name = noNS($dst); + + // pass this info on to other plugins + $eventdata = array( + // this is for compatibility to old plugin + 'opts' => array( + 'ns' => $src_ns, + 'name' => $src_name, + 'newns' => $dst_ns, + 'newname' => $dst_name, + ), + 'affected_pages' => &$affected_pages, + 'src_id' => $src, + 'dst_id' => $dst, + ); + + // 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('PLUGIN_MOVE_MEDIA_RENAME', $eventdata); + if($event->advise_before()) { + /** @var helper_plugin_move_file $FileMover */ + $FileMover = plugin_load('helper', 'move_file'); + + // Move the Subscriptions & Indexes (new feature since Spring 2013 release) + $Indexer = idx_get_indexer(); + if(($idx_msg = $Indexer->renameMetaValue('relation_media', $src, $dst)) !== true) { + msg('Error while updating the search index ' . $idx_msg, -1); + return false; + } + if(!$FileMover->moveMediaMeta($src_ns, $src_name, $dst_ns, $dst_name)) { + msg('The meta files of the media file ' . $src . ' couldn\'t be moved', -1); + return false; + } + + // prepare directory + io_createNamespace($src, 'media'); + + // move it FIXME this does not create a changelog entry! + if(!io_rename(mediaFN($src), mediaFN($dst))) { + msg('Moving the media file ' . $src . ' failed', -1); + return false; + } + // clean up old ns + io_sweepNS($src, 'mediadir'); + + // Move the old revisions + if(!$FileMover->moveMediaAttic($src_ns, $src_name, $dst_ns, $dst_name)) { + // it's too late to stop the move, so just display a message. + msg('The attic files of media file ' . $src . ' couldn\'t be moved. Please move them manually.', -1); + } + + // Add meta data to all affected pages, so links get updated later + foreach($affected_pages as $id) { + if(!page_exists($id, '', false)) continue; + $meta = $this->getMoveMeta($id); + 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'][$src] = $dst; + p_set_metadata($id, array('plugin_move' => $meta), false, true); + } + } $event->advise_after(); + + // store this for later use + $this->affectedPages = $affected_pages; + return true; } + /** + * Get a list of pages that where affected by the last successful move operation + * + * @return array + */ + public function getAffectedPages() { + return $this->affectedPages; + } + /** * This function loads and returns the persistent metadata for the move plugin. If there is metadata for the * pagemove plugin (not the old one but the version that immediately preceeded the move plugin) it will be migrated. @@ -183,7 +331,7 @@ public function movePage($src, $dst) { * @param string $id The id of the page the metadata shall be loaded for * @return array|null The metadata of the page */ - public function getMoveMeta($id) { + protected function getMoveMeta($id) { $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); // migrate old metadata from the pagemove plugin if(isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { @@ -207,11 +355,11 @@ public function getMoveMeta($id) { * @return string The rewritten wiki text */ protected function rewrite_content($text, $id, $moves, $media_moves = array()) { - $moves = $this->resolve_moves($moves, $id); + $moves = $this->resolve_moves($moves, $id); $media_moves = $this->resolve_moves($media_moves, $id); $handlers = array(); - $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); + $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); /* * PLUGIN_MOVE_HANDLERS REGISTER event: @@ -271,7 +419,7 @@ protected function resolve_moves($moves, $id) { foreach($tmp_moves as $old => $new) { if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { $tmp_moves[$old] = $moves[$new]; - $changed = true; + $changed = true; } } } From 700bf761239bc82fa300fad0b478c228d5fe0c9a Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 17:04:59 +0200 Subject: [PATCH 077/338] more refactoring the backend system is now nearly finished, though still untested --- helper/op.php | 130 +++--------------------- helper/plan.php | 241 +++++++++++++++++++++++++++++++++++++++------ helper/rewrite.php | 171 ++++++++++++++++++++++++++++++++ 3 files changed, 394 insertions(+), 148 deletions(-) create mode 100644 helper/rewrite.php diff --git a/helper/op.php b/helper/op.php index 889304b..39b6dc2 100644 --- a/helper/op.php +++ b/helper/op.php @@ -1,6 +1,6 @@ @@ -119,8 +119,11 @@ public function checkMedia($src, $dst) { public function movePage($src, $dst) { if(!$this->checkPage($src, $dst)) return false; + /** @var helper_plugin_move_rewrite $Rewriter */ + $Rewriter = plugin_load('helper', 'move_rewrite'); + // remember what this page was called before the move in meta data - $page_meta = $this->getMoveMeta($src); + $page_meta = $Rewriter->getMoveMeta($src); if(!$page_meta) $page_meta = array(); if(!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); $page_meta['old_ids'][$src] = time(); @@ -161,7 +164,7 @@ public function movePage($src, $dst) { // Open the old document and change forward links $text = rawWiki($src); - $text = $this->rewrite_content($text, $src, array($src => $dst)); + $text = $Rewriter->rewrite_content($text, $src, array($src => $dst)); // Move the Subscriptions & Indexes (new feature since Spring 2013 release) $Indexer = idx_get_indexer(); @@ -208,10 +211,10 @@ public function movePage($src, $dst) { foreach($affected_pages as $id) { if(!page_exists($id, '', false) || $id == $src || $id == $dst) continue; // we are only interested in persistent metadata, so no need to render anything. - $meta = $this->getMoveMeta($id); + $meta = $Rewriter->getMoveMeta($id); if(!$meta) $meta = array('moves' => array()); if(!isset($meta['moves'])) $meta['moves'] = array(); - $meta['moves'] = $this->resolve_moves($meta['moves'], $id); + $meta['moves'] = $Rewriter->resolve_moves($meta['moves'], $id); $meta['moves'][$src] = $dst; p_set_metadata($id, array('plugin_move' => $meta), false, true); } @@ -234,7 +237,7 @@ public function movePage($src, $dst) { * @param string $dst new ID * @return bool true if the move was successfully executed */ - public function move_media($src, $dst) { + public function moveMedia($src, $dst) { if(!$this->checkMedia($src, $dst)) return false; // get all pages using this media @@ -266,6 +269,8 @@ public function move_media($src, $dst) { if($event->advise_before()) { /** @var helper_plugin_move_file $FileMover */ $FileMover = plugin_load('helper', 'move_file'); + /** @var helper_plugin_move_rewrite $Rewriter */ + $Rewriter = plugin_load('helper', 'move_rewrite'); // Move the Subscriptions & Indexes (new feature since Spring 2013 release) $Indexer = idx_get_indexer(); @@ -299,10 +304,10 @@ public function move_media($src, $dst) { // Add meta data to all affected pages, so links get updated later foreach($affected_pages as $id) { if(!page_exists($id, '', false)) continue; - $meta = $this->getMoveMeta($id); + $meta = $Rewriter->getMoveMeta($id); 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'] = $Rewriter->resolve_moves($meta['media_moves'], '__'); $meta['media_moves'][$src] = $dst; p_set_metadata($id, array('plugin_move' => $meta), false, true); } @@ -323,113 +328,4 @@ public function move_media($src, $dst) { public function getAffectedPages() { return $this->affectedPages; } - - /** - * This function loads and returns the persistent metadata for the move plugin. If there is metadata for the - * pagemove plugin (not the old one but the version that immediately preceeded the move plugin) it will be migrated. - * - * @param string $id The id of the page the metadata shall be loaded for - * @return array|null The metadata of the page - */ - protected function getMoveMeta($id) { - $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); - // migrate old metadata from the pagemove plugin - if(isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { - if(isset($all_meta['plugin_move'])) { - $all_meta['plugin_move'] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta['plugin_move']); - } else { - $all_meta['plugin_move'] = $all_meta['plugin_pagemove']; - } - p_set_metadata($id, array('plugin_move' => $all_meta['plugin_move'], 'plugin_pagemove' => null), false, true); - } - return isset($all_meta['plugin_move']) ? $all_meta['plugin_move'] : null; - } - - /** - * Rewrite a text in order to fix the content after the given moves. - * - * @param string $text The wiki text that shall be rewritten - * @param string $id The id of the wiki page, if the page itself was moved the old id - * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids - * @param array $media_moves Array of all media moves. - * @return string The rewritten wiki text - */ - protected function rewrite_content($text, $id, $moves, $media_moves = array()) { - $moves = $this->resolve_moves($moves, $id); - $media_moves = $this->resolve_moves($media_moves, $id); - - $handlers = array(); - $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); - - /* - * PLUGIN_MOVE_HANDLERS REGISTER event: - * - * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler - * The handler needs to be a valid callback, it will get the following parameters: - * $match, $state, $pos, $pluginname, $handler. The first three parameters are equivalent to the parameters - * of the handle()-function of syntax plugins, the $pluginname is just the plugin name again so handler functions - * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object. - * It has the following properties and functions that can be used: - * - id, ns: id and namespace of the old page - * - new_id, new_ns: new id and namespace (can be identical to id and ns) - * - moves: array of moves, the same as $moves in the event - * - media_moves: array of media moves, same as $media_moves in the event - * - adaptRelativeId($id): adapts the relative $id according to the moves - */ - trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data); - - $modes = p_get_parsermodes(); - - // Create the parser - $Parser = new Doku_Parser(); - - // Add the Handler - $Parser->Handler = new helper_plugin_move_handler($id, $moves, $media_moves, $handlers); - - //add modes to parser - foreach($modes as $mode) { - $Parser->addMode($mode['mode'], $mode['obj']); - } - - return $Parser->parse($text); - } - - /** - * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. - * - * @param array $moves The moves - * @param string $id - * @return array The resolved moves - */ - protected function resolve_moves($moves, $id) { - // resolve moves of pages that were moved more than once - $tmp_moves = array(); - foreach($moves as $old => $new) { - if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { - // write to temp array in order to correctly handle rename circles - $tmp_moves[$old] = $moves[$new]; - } - } - - $changed = !empty($tmp_moves); - - // this correctly resolves rename circles by moving forward one step a time - while($changed) { - $changed = false; - foreach($tmp_moves as $old => $new) { - if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { - $tmp_moves[$old] = $moves[$new]; - $changed = true; - } - } - } - - // manual merge, we can't use array_merge here as ids can be numeric - foreach($tmp_moves as $old => $new) { - if($old == $new) unset($moves[$old]); - else $moves[$old] = $new; - } - return $moves; - } - } \ No newline at end of file diff --git a/helper/plan.php b/helper/plan.php index f9590bd..3efd083 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -25,7 +25,8 @@ * document - refers to either a page or a media file here */ class helper_plugin_move_plan extends DokuWiki_Plugin { - + /** Number of operations per step */ + const OPS_PER_RUN = 10; /** * @var array the options for this move plan @@ -36,9 +37,16 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { 'started' => 0, // counters - 'pages' => 0, - 'media' => 0, - 'affected' => 0, + 'pages_all' => 0, + 'pages_run' => 0, + 'media_all' => 0, + 'media_run' => 0, + 'affpg_all' => 0, + 'affpg_run' => 0, + + // options + 'autoskip' => false, + 'autorewrite' => false ); /** @@ -61,10 +69,10 @@ public function __construct() { // set the file locations $this->files = array( - 'opts' => $conf['metadir'] . '/__move_opts', - 'pagelist' => $conf['metadir'] . '/__move_pagelist', + 'opts' => $conf['metadir'] . '/__move_opts', + 'pagelist' => $conf['metadir'] . '/__move_pagelist', 'medialist' => $conf['metadir'] . '/__move_medialist', - 'affected' => $conf['metadir'] . '/__move_affected', + 'affected' => $conf['metadir'] . '/__move_affected', ); $this->loadOptions(); @@ -97,10 +105,10 @@ public function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGI // FIXME make sure source exists $this->plan[] = array( - 'src' => $src, - 'dst' => $dst, + 'src' => $src, + 'dst' => $dst, 'class' => $class, - 'type' => $type + 'type' => $type ); } @@ -148,7 +156,7 @@ public function commit() { // now add all the found documents to our lists foreach($docs as $doc) { $from = $doc['id']; - $to = $move['dst'] . substr($doc['id'], $strip); + $to = $move['dst'] . substr($doc['id'], $strip); if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { $this->addToPageList($from, $to); @@ -160,11 +168,141 @@ public function commit() { } $this->options['committed'] = true; - $this->options['started'] = time(); + $this->options['started'] = time(); } - public function nextStep() { + public function nextStep($skip = false) { if(!$this->options['commited']) throw new Exception('plan is not committed yet!'); + + if (@filesize($this->files['pagelist']) > 1) { + $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_PAGES, $skip); + if($todo === false) return false; + return max($todo, 1); // force one more call + } + + if (@filesize($this->files['medialist']) > 1) { + $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_MEDIA, $skip); + if($todo === false) return false; + return max($todo, 1); // force one more call + } + + if ($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { + $todo = $this->stepThroughAffectedPages(); + if($todo === false) return false; + return max($todo, 1); // force one more call + } + + // FIXME handle namespace subscription moves + + // FIXME call abort function here + return 0; + } + + /** + * Step through the next bunch of pages or media files + * + * @param int $type (PLUGIN_MOVE_TYPE_PAGES|PLUGIN_MOVE_TYPE_MEDIA) + * @param bool $skip should the first item be skipped? + * @return bool|int false on error, otherwise the number of remaining documents + */ + protected function stepThroughDocuments($type = PLUGIN_MOVE_TYPE_PAGES, &$skip = false) { + /** @var helper_plugin_move_op $MoveOperator */ + $MoveOperator = plugin_load('helper', 'move_op'); + + if($type == PLUGIN_MOVE_TYPE_PAGES) { + $file = $this->files['pagelist']; + $mark = 'P'; + $call = 'movePage'; + $counter = 'pages_num'; + } else { + $file = $this->files['medialist']; + $mark = 'M'; + $call = 'moveMedia'; + $counter = 'media_num'; + } + + $doclist = fopen($file, 'a+'); + for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { + $line = $this->getLastLine($doclist); + if($line === false) break; + list($src, $dst) = explode("\t", trim($line)); + + // should this item be skipped? + if($skip) goto FINALLY; + + // move the page + if(!$MoveOperator->$call($src, $dst)) { + $this->log($mark, $src, $dst, false); // FAILURE! + + // automatically skip this item if wanted... + if($this->options['autoskip']) goto FINALLY; + // ...otherwise abort the operation + fclose($doclist); + return false; + } else { + $this->log($mark, $src, $dst, true); // SUCCESS! + + // remember affected pages + $this->addToAffectedPagesList($MoveOperator->getAffectedPages()); + } + + /* + * This adjusts counters and truncates the document list correctly + * It is used to finalize a successful or skipped move + */ + FINALLY: + $skip = false; + ftruncate($doclist, ftell($doclist)); + $this->options[$counter]--; + $this->saveOptions(); + } + + fclose($doclist); + return $this->options[$counter]; + } + + /** + * Step through the next bunch of pages that need link corrections + * + * @return bool|int false on error, otherwise the number of remaining documents + */ + protected function stepThroughAffectedPages() { + /** @var helper_plugin_move_rewrite $Rewriter */ + $Rewriter = plugin_load('helper', 'move_rewrite'); + + // if this is the first run, clean up the file and remove duplicates + if($this->options['affpg_all'] == $this->options['affpg_num']) { + $affected = io_readFile($this->files['affected']); + $affected = explode("\n", $affected); + $affected = array_unique($affected); + $affected = array_filter($affected); + sort($affected); + if($affected[0] === '') array_shift($affected); + io_saveFile($this->files['affected'], join("\n", $affected)); + + $this->options['affpg_all'] = count($affected); + $this->options['affpg_num'] = $this->options['affpg_all']; + + $this->saveOptions(); + } + + // handle affected pages + $doclist = fopen($this->files['affected'], 'a+'); + for ($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { + $page = $this->getLastLine($doclist); + if ($page === false) break; + + // rewrite it + $Rewriter->execute_rewrites($page, null); + + // update the list file + ftruncate($doclist, ftell($doclist)); + $this->options['affpg_num']--; + $this->saveOptions(); + } + + fclose($doclist); + return $this->options['affpg_num']; } /** @@ -172,20 +310,24 @@ public function nextStep() { * * @return bool */ - protected function saveOptions(){ + protected function saveOptions() { return io_saveFile($this->files['opts'], serialize($this->options)); } /** * Load the current options if any * - * @return bool + * If no options are found, the default options will be extended by any available + * config options */ protected function loadOptions() { $file = $this->files['opts']; - if(!file_exists($file)) return false; - $this->options = unserialize(io_readFile($file, false)); - return true; + if(file_exists($file)) { + $this->options = unserialize(io_readFile($file, false)); + } else { + $this->options['autoskip'] = $this->getConf('autoskip'); + $this->options['autorewrite'] = $this->getConf('autorewrite'); + } } /** @@ -199,7 +341,8 @@ protected function addToPageList($src, $dst) { $file = $this->files['pagelist']; if(io_saveFile($file, "$src\t$dst\n", true)) { - $this->options['pages']++; + $this->options['pages_all']++; + $this->options['pages_run']++; return true; } return false; @@ -216,12 +359,30 @@ protected function addToMediaList($src, $dst) { $file = $this->files['medialist']; if(io_saveFile($file, "$src\t$dst\n", true)) { - $this->options['media']++; + $this->options['media_all']++; + $this->options['media_run']++; return true; } return false; } + /** + * Add the list of pages to the list of affected pages whose links need adjustment + * + * This is only done when autorewrite is enabled, otherwise we don't need to track + * those pages + * + * @param array $pages + * @return bool + */ + protected function addToAffectedPagesList($pages) { + if(!$this->options['autorewrite']) return false; + + $this->options['affpg_all'] += count($pages); + $this->options['affpg_num'] = $this->options['affpg_all']; + return io_saveFile($this->files['affected'], join("\n", $pages) . "\n", true); + } + /** * Get the last line from the list that is stored in the file that is referenced by the handle * The handle is set to the newline before the file id @@ -235,22 +396,21 @@ protected function getLastLine($handle) { $line = ''; // seek one backwards as long as it's possible - while (fseek($handle, -1, SEEK_CUR) >= 0) { + while(fseek($handle, -1, SEEK_CUR) >= 0) { $c = fgetc($handle); fseek($handle, -1, SEEK_CUR); // reset the position to the character that was read - if ($c == "\n") { + if($c == "\n") { break; } - if ($c === false) return false; // EOF, i.e. the file is empty - $line = $c.$line; + if($c === false) return false; // EOF, i.e. the file is empty + $line = $c . $line; } - if ($line === '') return false; // nothing was read i.e. the file is empty - return $line; + if($line === '') return false; // nothing was read i.e. the file is empty + return trim($line); } - /** * Callback for usort to sort the move plan * @@ -293,13 +453,32 @@ public function planSorter($a, $b) { } /** - * Get the filenames for the metadata of the move plugin + * Log result of an operation * - * @return array The file names for opts, pagelist and medialist + * @param string $type + * @param string $from + * @param string $to + * @param bool $success + * @author Andreas Gohr */ - protected function get_namespace_meta_files() { + private function log($type, $from, $to, $success) { global $conf; + global $MSG; + + $optime = $this->options['started']; + $file = $conf['cachedir'] . '/move-' . $optime . '.log'; + $now = time(); + $date = date('Y-m-d H:i:s', $now); // for human readability + + if($success) { + $ok = 'success'; + $msg = ''; + } else { + $ok = 'failed'; + $msg = $MSG[count($MSG) - 1]['msg']; // get detail from message array + } + $log = "$now\t$date\t$type\t$from\t$to\t$ok\t$msg\n"; + io_saveFile($file, $log, true); } - } \ No newline at end of file diff --git a/helper/rewrite.php b/helper/rewrite.php new file mode 100644 index 0000000..ecd48f4 --- /dev/null +++ b/helper/rewrite.php @@ -0,0 +1,171 @@ + + * @author Gary Owen + * @author Andreas Gohr + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class helper_plugin_move_rewrite + * + * This class handles the rewriting of wiki text to update the links + */ +class helper_plugin_move_rewrite extends DokuWiki_Plugin { + + /** + * @var string symbol to make move operations easily recognizable in change log + */ + public $symbol = '↷'; + + /** + * This function loads and returns the persistent metadata for the move plugin. If there is metadata for the + * pagemove plugin (not the old one but the version that immediately preceeded the move plugin) it will be migrated. + * + * @param string $id The id of the page the metadata shall be loaded for + * @return array|null The metadata of the page + */ + public function getMoveMeta($id) { + $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); + // migrate old metadata from the pagemove plugin + if(isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { + if(isset($all_meta['plugin_move'])) { + $all_meta['plugin_move'] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta['plugin_move']); + } else { + $all_meta['plugin_move'] = $all_meta['plugin_pagemove']; + } + p_set_metadata($id, array('plugin_move' => $all_meta['plugin_move'], 'plugin_pagemove' => null), false, true); + } + return isset($all_meta['plugin_move']) ? $all_meta['plugin_move'] : null; + } + + /** + * Rewrite a text in order to fix the content after the given moves. + * + * @param string $text The wiki text that shall be rewritten + * @param string $id The id of the wiki page, if the page itself was moved the old id + * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids + * @param array $media_moves Array of all media moves. + * @return string The rewritten wiki text + */ + public function rewrite_content($text, $id, $moves, $media_moves = array()) { + $moves = $this->resolve_moves($moves, $id); + $media_moves = $this->resolve_moves($media_moves, $id); + + $handlers = array(); + $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); + + /* + * PLUGIN_MOVE_HANDLERS REGISTER event: + * + * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler + * The handler needs to be a valid callback, it will get the following parameters: + * $match, $state, $pos, $pluginname, $handler. The first three parameters are equivalent to the parameters + * of the handle()-function of syntax plugins, the $pluginname is just the plugin name again so handler functions + * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object. + * It has the following properties and functions that can be used: + * - id, ns: id and namespace of the old page + * - new_id, new_ns: new id and namespace (can be identical to id and ns) + * - moves: array of moves, the same as $moves in the event + * - media_moves: array of media moves, same as $media_moves in the event + * - adaptRelativeId($id): adapts the relative $id according to the moves + */ + trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data); + + $modes = p_get_parsermodes(); + + // Create the parser + $Parser = new Doku_Parser(); + + // Add the Handler + $Parser->Handler = new helper_plugin_move_handler($id, $moves, $media_moves, $handlers); + + //add modes to parser + foreach($modes as $mode) { + $Parser->addMode($mode['mode'], $mode['obj']); + } + + return $Parser->parse($text); + } + + /** + * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. + * + * @param array $moves The moves + * @param string $id + * @return array The resolved moves + */ + public function resolve_moves($moves, $id) { + // resolve moves of pages that were moved more than once + $tmp_moves = array(); + foreach($moves as $old => $new) { + if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { + // write to temp array in order to correctly handle rename circles + $tmp_moves[$old] = $moves[$new]; + } + } + + $changed = !empty($tmp_moves); + + // this correctly resolves rename circles by moving forward one step a time + while($changed) { + $changed = false; + foreach($tmp_moves as $old => $new) { + if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { + $tmp_moves[$old] = $moves[$new]; + $changed = true; + } + } + } + + // manual merge, we can't use array_merge here as ids can be numeric + foreach($tmp_moves as $old => $new) { + if($old == $new) unset($moves[$old]); + else $moves[$old] = $new; + } + return $moves; + } + + /** + * Rewrite the text of a page according to the recorded moves, the rewritten text is saved + * + * @param string $id The id of the page that shall be rewritten + * @param string|null $text Old content of the page. When null is given the content is loaded from disk. + * @return string|bool The rewritten content, false on error + */ + public function execute_rewrites($id, $text = null) { + $meta = $this->getMoveMeta($id); + if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { + if(is_null($text)) $text = rawWiki($id); + $moves = isset($meta['moves']) ? $meta['moves'] : array(); + $media_moves = isset($meta['media_moves']) ? $meta['media_moves'] : array(); + + $old_text = $text; + $text = $this->rewrite_content($text, $id, $moves, $media_moves); + $changed = ($old_text != $text); + $file = wikiFN($id, '', false); + if(is_writable($file) || !$changed) { + if ($changed) { + // Wait a second when the page has just been rewritten + $oldRev = filemtime(wikiFN($id)); + if($oldRev == time()) sleep(1); + + saveWikiText($id, $text, $this->symbol.' '.$this->getLang('linkchange'), $this->getConf('minor')); + } + unset($meta['moves']); + unset($meta['media_moves']); + p_set_metadata($id, array('plugin_move' => $meta), false, true); + } else { // FIXME: print error here or fail silently? + msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + } + } + + return $text; + } + + +} \ No newline at end of file From 6b02bfbed7aa7f7cd4ef05e2ad674eb4f1746757 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 17:14:34 +0200 Subject: [PATCH 078/338] have a way to properly reset the plan --- helper/plan.php | 117 ++++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 48 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 3efd083..1e40a24 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -31,23 +31,7 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { /** * @var array the options for this move plan */ - protected $options = array( - // status - 'committed' => false, - 'started' => 0, - - // counters - 'pages_all' => 0, - 'pages_run' => 0, - 'media_all' => 0, - 'media_run' => 0, - 'affpg_all' => 0, - 'affpg_run' => 0, - - // options - 'autoskip' => false, - 'autorewrite' => false - ); + protected $options = array(); // defaults are set in loadOptions() /** * @var array holds the location of the different list and state files @@ -78,6 +62,49 @@ public function __construct() { $this->loadOptions(); } + /** + * Load the current options if any + * + * If no options are found, the default options will be extended by any available + * config options + */ + protected function loadOptions() { + // (re)set defaults + $this->options = array( + // status + 'committed' => false, + 'started' => 0, + + // counters + 'pages_all' => 0, + 'pages_run' => 0, + 'media_all' => 0, + 'media_run' => 0, + 'affpg_all' => 0, + 'affpg_run' => 0, + + // options + 'autoskip' => $this->getConf('autoskip'), + 'autorewrite' => $this->getConf('autorewrite') + ); + + // merge whatever options are saved currently + $file = $this->files['opts']; + if(file_exists($file)) { + $options = unserialize(io_readFile($file, false)); + $this->options = array_merge($this->options, $options); + } + } + + /** + * Save the current options + * + * @return bool + */ + protected function saveOptions() { + return io_saveFile($this->files['opts'], serialize($this->options)); + } + /** * Check if there is a move in progress currently * @@ -112,6 +139,17 @@ public function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGI ); } + /** + * Abort any move or plan in progress and reset the helper + */ + public function abort() { + foreach ($this->files as $file) { + @unlink($file); + } + $this->plan = array(); + $this->loadOptions(); + } + /** * This locks up the plan and prepares execution * @@ -171,22 +209,29 @@ public function commit() { $this->options['started'] = time(); } + /** + * Execute the next steps + * + * @param bool $skip set to true to skip the next first step (skip error) + * @return bool|int false on errors, otherwise the number of remaining steps + * @throws Exception + */ public function nextStep($skip = false) { if(!$this->options['commited']) throw new Exception('plan is not committed yet!'); - if (@filesize($this->files['pagelist']) > 1) { + if(@filesize($this->files['pagelist']) > 1) { $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_PAGES, $skip); if($todo === false) return false; return max($todo, 1); // force one more call } - if (@filesize($this->files['medialist']) > 1) { + if(@filesize($this->files['medialist']) > 1) { $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_MEDIA, $skip); if($todo === false) return false; return max($todo, 1); // force one more call } - if ($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { + if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { $todo = $this->stepThroughAffectedPages(); if($todo === false) return false; return max($todo, 1); // force one more call @@ -194,7 +239,8 @@ public function nextStep($skip = false) { // FIXME handle namespace subscription moves - // FIXME call abort function here + // we're done here, clean up + $this->abort(); return 0; } @@ -288,9 +334,9 @@ protected function stepThroughAffectedPages() { // handle affected pages $doclist = fopen($this->files['affected'], 'a+'); - for ($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { + for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { $page = $this->getLastLine($doclist); - if ($page === false) break; + if($page === false) break; // rewrite it $Rewriter->execute_rewrites($page, null); @@ -305,31 +351,6 @@ protected function stepThroughAffectedPages() { return $this->options['affpg_num']; } - /** - * Save the current options - * - * @return bool - */ - protected function saveOptions() { - return io_saveFile($this->files['opts'], serialize($this->options)); - } - - /** - * Load the current options if any - * - * If no options are found, the default options will be extended by any available - * config options - */ - protected function loadOptions() { - $file = $this->files['opts']; - if(file_exists($file)) { - $this->options = unserialize(io_readFile($file, false)); - } else { - $this->options['autoskip'] = $this->getConf('autoskip'); - $this->options['autorewrite'] = $this->getConf('autorewrite'); - } - } - /** * Appends a page move operation in the list file * From 8481da9ce36a190e77b1cdfe6d42d4f66ef173a8 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 18:58:27 +0200 Subject: [PATCH 079/338] fixed first test file --- _test/pagemove.test.php | 66 +++----- helper/general.php | 326 -------------------------------------- helper/handler.php | 339 ++++++++++++++++++++++++++++++++++++++++ helper/rewrite.php | 3 + 4 files changed, 364 insertions(+), 370 deletions(-) create mode 100644 helper/handler.php diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index de7a80e..67aaecc 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -14,8 +14,6 @@ class plugin_move_pagemove_test extends DokuWikiTest { var $currentNsBacklinkingId = 'parent_ns:current_ns:some_page'; var $otherBacklinkingId = 'level0:level1:other_backlinking_page'; var $subNsPage = 'parent_ns:current_ns:sub_ns:some_page'; - /** @var helper_plugin_move $move */ - private $move = NULL; // @todo Move page to an ID which already exists // @todo Check backlinks of a sub-namespace page (moving same, up, down, different) @@ -166,34 +164,22 @@ function setUp() { $references = array_keys(p_get_metadata($this->subNsPage, 'relation references', METADATA_RENDER_UNLIMITED)); idx_get_indexer()->addMetaKeys($this->subNsPage, 'relation_references', $references); - $this->move = new helper_plugin_move(); parent::setUp(); } -# function testPagemove() { -# $this->assertEqual(1,1); -# } - -// function test_pm_getforwardlinks() { -// $origLinkAbsLinkArray = $this->move->_pm_getforwardlinks($this->movedId); -// } function test_move_page_in_same_ns() { global $ID; + $newId = getNS($ID).':new_page'; + $this->movedToId = $newId; - $newPagename = 'new_page'; + /** @var helper_plugin_move_op $MoveOp */ + $MoveOp = plugin_load('helper', 'move_op'); - $opts = array(); - $opts['page_ns'] = 'page'; - $opts['ns'] = getNS($ID); - $opts['name'] = noNS($ID); - $opts['newns'] = $opts['ns']; - $opts['newname'] = $newPagename; - $this->movedToId = $opts['newns'].':'.$newPagename; - $this->move->move_page($opts); - - $newId = $opts['newns'].':'.$opts['newname']; - $newContent = rawWiki($newId); + $result = $MoveOp->movePage($ID, $this->movedToId); + $this->assertTrue($result); + + $newContent = rawWiki($this->movedToId); $expectedContent = <<movedToId = $newId; - $newPagename = 'new_page'; + /** @var helper_plugin_move_op $MoveOp */ + $MoveOp = plugin_load('helper', 'move_op'); - $opts = array(); - $opts['page_ns'] = 'page'; - $opts['ns'] = getNS($ID); - $opts['name'] = noNS($ID); - $opts['newns'] = 'parent_ns:parallel_ns'; - $opts['newname'] = $newPagename; - $this->movedToId = $opts['newns'].':'.$newPagename; - $this->move->move_page($opts); + $result = $MoveOp->movePage($ID, $newId); + $this->assertTrue($result); - $newId = $opts['newns'].':'.$opts['newname']; - $newContent = rawWiki($newId); + $newContent = rawWiki($this->movedToId); $expectedContent = <<movedToId = $newId; - $opts = array(); - $opts['page_ns'] = 'page'; - $opts['ns'] = getNS($ID); - $opts['name'] = noNS($ID); - $opts['newns'] = 'parent_ns'; - $opts['newname'] = $newPagename; - $newId = $opts['newns'].':'.$opts['newname']; - $this->movedToId = $opts['newns'].':'.$newPagename; + /** @var helper_plugin_move_op $MoveOp */ + $MoveOp = plugin_load('helper', 'move_op'); - $this->move->move_page($opts); + $result = $MoveOp->movePage($ID, $newId); + $this->assertTrue($result); - $newContent = rawWiki($newId); + $newContent = rawWiki($this->movedToId); $expectedContent = << $new ($old can be $id) - * @param array $media_moves Moves of media files that shall be considered in the form $old => $new - * @param array $handlers Handlers for plugin content in the form $plugin_anme => $callback - */ - public function __construct($id, $moves, $media_moves, $handlers) { - $this->id = $id; - $this->ns = getNS($id); - $this->moves = $moves; - $this->media_moves = $media_moves; - $this->handlers = $handlers; - if (isset($moves[$id])) { - $this->new_id = $moves[$id]; - $this->new_ns = getNS($moves[$id]); - } else { - $this->new_id = $id; - $this->new_ns = $this->ns; - } - } - - /** - * Handle camelcase links - * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input - * @return bool If parsing should be continued - */ - public function camelcaselink($match, $state, $pos) { - if ($this->ns) - $old = cleanID($this->ns.':'.$match); - else - $old = cleanID($match); - if (isset($this->moves[$old]) || $this->id != $this->new_id) { - if (isset($this->moves[$old])) { - $new = $this->moves[$old]; - } else { - $new = $old; - } - $new_ns = getNS($new); - // preserve capitalization either in the link or in the title - if (noNS($new) == noNS($old)) { - // camelcase link still seems to work - if ($new_ns == $this->new_ns) { - $this->calls .= $match; - } else { // just the namespace was changed, the camelcase word is a valid id - $this->calls .= "[[$new_ns:$match]]"; - } - } else { - $this->calls .= "[[$new|$match]]"; - } - } else { - $this->calls .= $match; - } - return true; - } - - /** - * Handle rewriting of internal links - * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input - * @return bool If parsing should be continued - */ - public function internallink($match, $state, $pos) { - // Strip the opening and closing markup - $link = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match); - - // Split title from URL - $link = explode('|',$link,2); - if ( !isset($link[1]) ) { - $link[1] = NULL; - } else if ( preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) { - // If the title is an image, rewrite it - $old_title = $link[1]; - $link[1] = $this->rewrite_media($link[1]); - // do a simple replace of the first match so really only the id is changed and not e.g. the alignment - $oldpos = strpos($match, $old_title); - $oldlen = strlen($old_title); - $match = substr_replace($match, $link[1], $oldpos, $oldlen); - } - $link[0] = trim($link[0]); - - - //decide which kind of link it is - - if ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$link[0]) ) { - // Interwiki - $this->calls .= $match; - }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) { - // Windows Share - $this->calls .= $match; - }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) { - // external link (accepts all protocols) - $this->calls .= $match; - }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) { - // E-Mail (pattern above is defined in inc/mail.php) - $this->calls .= $match; - }elseif ( preg_match('!^#.+!',$link[0]) ){ - // local link - $this->calls .= $match; - }else{ - $id = $link[0]; - - $hash = ''; - $parts = explode('#', $id, 2); - if (count($parts) === 2) { - $id = $parts[0]; - $hash = $parts[1]; - } - - $params = ''; - $parts = explode('?', $id, 2); - if (count($parts) === 2) { - $id = $parts[0]; - $params = $parts[1]; - } - - - $new_id = $this->adaptRelativeId($id); - - if ($id == $new_id) { - $this->calls .= $match; - } else { - if ($params !== '') { - $new_id.= '?'.$params; - } - - if ($hash !== '') { - $new_id .= '#'.$hash; - } - - if ($link[1] != NULL) { - $new_id .= '|'.$link[1]; - } - - $this->calls .= '[['.$new_id.']]'; - } - - } - - return true; - - } - - /** - * Handle rewriting of media links - * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input - * @return bool If parsing should be continued - */ - public function media($match, $state, $pos) { - $this->calls .= $this->rewrite_media($match); - return true; - } - - /** - * Rewrite a media syntax - * - * @param string $match The text match of the media syntax - * @return string The rewritten syntax - */ - protected function rewrite_media($match) { - $p = Doku_Handler_Parse_Media($match); - if ($p['type'] == 'internalmedia') { // else: external media - $new_src = $this->adaptRelativeId($p['src'], true); - if ($new_src !== $p['src']) { - // do a simple replace of the first match so really only the id is changed and not e.g. the alignment - $srcpos = strpos($match, $p['src']); - $srclen = strlen($p['src']); - return substr_replace($match, $new_src, $srcpos, $srclen); - } - } - return $match; - } - - /** - * Handle rewriting of plugin syntax, calls the registered handlers - * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input - * @param string $pluginname The name of the plugin - * @return bool If parsing should be continued - */ - public function plugin($match, $state, $pos, $pluginname) { - if (isset($this->handlers[$pluginname])) { - $this->calls .= call_user_func($this->handlers[$pluginname], $match, $state, $pos, $pluginname, $this); - } else { - $this->calls .= $match; - } - return true; - } - - /** - * Catchall handler for the remaining syntax - * - * @param string $name Function name that was called - * @param array $params Original parameters - * @return bool If parsing should be continue - */ - public function __call($name, $params) { - if (count($params) == 3) { - $this->calls .= $params[0]; - return true; - } else { - trigger_error('Error, handler function '.hsc($name).' with '.count($params).' parameters called which isn\'t implemented', E_USER_ERROR); - return false; - } - } - - public function _finalize() { - // remove padding that is added by the parser in parse() - $this->calls = substr($this->calls, 1, -1); - } - - /** - * Adapts a link respecting all moves and making it a relative link according to the new id - * - * @param string $id A relative id - * @param bool $media If the id is a media id - * @return string The relative id, adapted according to the new/old id and the moves - */ - public function adaptRelativeId($id, $media = false) { - global $conf; - - if ($id === '') { - return $id; - } - - $abs_id = str_replace('/', ':', $id); - $abs_id = resolve_id($this->ns, $abs_id, false); - if (substr($abs_id, -1) === ':') - $abs_id .= $conf['start']; - $clean_id = cleanID($abs_id); - // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page - // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been - // deleted already - if (substr($clean_id, -1) === ':') - $clean_id .= $conf['start']; - - if (($media ? isset($this->media_moves[$clean_id]) : isset($this->moves[$clean_id])) || $this->ns !== $this->new_ns) { - if (!$media && isset($this->moves[$clean_id])) { - $new = $this->moves[$clean_id]; - } elseif ($media && isset($this->media_moves[$clean_id])) { - $new = $this->media_moves[$clean_id]; - } else { - $new = $clean_id; - - // only the namespace was changed so if the link still resolves to the same absolute id, we can skip the rest - $new_abs_id = str_replace('/', ':', $id); - $new_abs_id = resolve_id($this->new_ns, $new_abs_id, false); - if (substr($new_abs_id, -1) === ':') - $new_abs_id .= $conf['start']; - if ($new_abs_id == $abs_id) return $id; - } - $new_link = $new; - $new_ns = getNS($new); - // try to keep original pagename - if ($this->noNS($new) == $this->noNS($clean_id)) { - if ($new_ns == $this->new_ns) { - $new_link = $this->noNS($id); - if ($new_link === false) $new_link = $this->noNS($new); - if ($id == ':') - $new_link = ':'; - else if ($id == '/') - $new_link = '/'; - } else if ($new_ns != false) { - $new_link = $new_ns.':'.$this->noNS($id); - } else { - $new_link = $this->noNS($id); - if ($new_link === false) $new_link = $new; - } - } else if ($new_ns == $this->new_ns) { - $new_link = $this->noNS($new_link); - } else if (strpos($new_ns, $this->ns.':') === 0) { - $new_link = '.:'.substr($new_link, strlen($this->ns)+1); - } - - if ($this->new_ns != '' && $new_ns == false) { - $new_link = ':'.$new_link; - } - - return $new_link; - } else { - return $id; - } - } - - /** - * Remove the namespace from the given id like noNS(), but handles '/' as namespace separator - * @param string $id the id - * @return string the id without the namespace - */ - private function noNS($id) { - $pos = strrpos($id, ':'); - $spos = strrpos($id, '/'); - if ($pos === false) $pos = $spos; - if ($spos === false) $spos = $pos; - $pos = max($pos, $spos); - if ($pos!==false) { - return substr($id, $pos+1); - } else { - return $id; - } - } -} diff --git a/helper/handler.php b/helper/handler.php new file mode 100644 index 0000000..694672e --- /dev/null +++ b/helper/handler.php @@ -0,0 +1,339 @@ + + */ + +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Handler class for move. It does the actual rewriting of the content. + * + * Note: This is not actually a valid DokuWiki Helper plugin and can not be loaded via plugin_load() + */ +class helper_plugin_move_handler { + public $calls = ''; + public $id; + public $ns; + public $new_id; + public $new_ns; + public $moves; + public $media_moves; + private $handlers; + + /** + * Construct the move handler. + * + * @param string $id The id of the text that is passed to the handler + * @param array $moves Moves that shall be considered in the form $old => $new ($old can be $id) + * @param array $media_moves Moves of media files that shall be considered in the form $old => $new + * @param array $handlers Handlers for plugin content in the form $plugin_anme => $callback + */ + public function __construct($id, $moves, $media_moves, $handlers) { + $this->id = $id; + $this->ns = getNS($id); + $this->moves = $moves; + $this->media_moves = $media_moves; + $this->handlers = $handlers; + if (isset($moves[$id])) { + $this->new_id = $moves[$id]; + $this->new_ns = getNS($moves[$id]); + } else { + $this->new_id = $id; + $this->new_ns = $this->ns; + } + } + + /** + * Handle camelcase links + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @return bool If parsing should be continued + */ + public function camelcaselink($match, $state, $pos) { + if ($this->ns) + $old = cleanID($this->ns.':'.$match); + else + $old = cleanID($match); + if (isset($this->moves[$old]) || $this->id != $this->new_id) { + if (isset($this->moves[$old])) { + $new = $this->moves[$old]; + } else { + $new = $old; + } + $new_ns = getNS($new); + // preserve capitalization either in the link or in the title + if (noNS($new) == noNS($old)) { + // camelcase link still seems to work + if ($new_ns == $this->new_ns) { + $this->calls .= $match; + } else { // just the namespace was changed, the camelcase word is a valid id + $this->calls .= "[[$new_ns:$match]]"; + } + } else { + $this->calls .= "[[$new|$match]]"; + } + } else { + $this->calls .= $match; + } + return true; + } + + /** + * Handle rewriting of internal links + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @return bool If parsing should be continued + */ + public function internallink($match, $state, $pos) { + // Strip the opening and closing markup + $link = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match); + + // Split title from URL + $link = explode('|',$link,2); + if ( !isset($link[1]) ) { + $link[1] = NULL; + } else if ( preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) { + // If the title is an image, rewrite it + $old_title = $link[1]; + $link[1] = $this->rewrite_media($link[1]); + // do a simple replace of the first match so really only the id is changed and not e.g. the alignment + $oldpos = strpos($match, $old_title); + $oldlen = strlen($old_title); + $match = substr_replace($match, $link[1], $oldpos, $oldlen); + } + $link[0] = trim($link[0]); + + + //decide which kind of link it is + + if ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$link[0]) ) { + // Interwiki + $this->calls .= $match; + }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) { + // Windows Share + $this->calls .= $match; + }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) { + // external link (accepts all protocols) + $this->calls .= $match; + }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) { + // E-Mail (pattern above is defined in inc/mail.php) + $this->calls .= $match; + }elseif ( preg_match('!^#.+!',$link[0]) ){ + // local link + $this->calls .= $match; + }else{ + $id = $link[0]; + + $hash = ''; + $parts = explode('#', $id, 2); + if (count($parts) === 2) { + $id = $parts[0]; + $hash = $parts[1]; + } + + $params = ''; + $parts = explode('?', $id, 2); + if (count($parts) === 2) { + $id = $parts[0]; + $params = $parts[1]; + } + + + $new_id = $this->adaptRelativeId($id); + + if ($id == $new_id) { + $this->calls .= $match; + } else { + if ($params !== '') { + $new_id.= '?'.$params; + } + + if ($hash !== '') { + $new_id .= '#'.$hash; + } + + if ($link[1] != NULL) { + $new_id .= '|'.$link[1]; + } + + $this->calls .= '[['.$new_id.']]'; + } + + } + + return true; + + } + + /** + * Handle rewriting of media links + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @return bool If parsing should be continued + */ + public function media($match, $state, $pos) { + $this->calls .= $this->rewrite_media($match); + return true; + } + + /** + * Rewrite a media syntax + * + * @param string $match The text match of the media syntax + * @return string The rewritten syntax + */ + protected function rewrite_media($match) { + $p = Doku_Handler_Parse_Media($match); + if ($p['type'] == 'internalmedia') { // else: external media + $new_src = $this->adaptRelativeId($p['src'], true); + if ($new_src !== $p['src']) { + // do a simple replace of the first match so really only the id is changed and not e.g. the alignment + $srcpos = strpos($match, $p['src']); + $srclen = strlen($p['src']); + return substr_replace($match, $new_src, $srcpos, $srclen); + } + } + return $match; + } + + /** + * Handle rewriting of plugin syntax, calls the registered handlers + * + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input + * @param string $pluginname The name of the plugin + * @return bool If parsing should be continued + */ + public function plugin($match, $state, $pos, $pluginname) { + if (isset($this->handlers[$pluginname])) { + $this->calls .= call_user_func($this->handlers[$pluginname], $match, $state, $pos, $pluginname, $this); + } else { + $this->calls .= $match; + } + return true; + } + + /** + * Catchall handler for the remaining syntax + * + * @param string $name Function name that was called + * @param array $params Original parameters + * @return bool If parsing should be continue + */ + public function __call($name, $params) { + if (count($params) == 3) { + $this->calls .= $params[0]; + return true; + } else { + trigger_error('Error, handler function '.hsc($name).' with '.count($params).' parameters called which isn\'t implemented', E_USER_ERROR); + return false; + } + } + + public function _finalize() { + // remove padding that is added by the parser in parse() + $this->calls = substr($this->calls, 1, -1); + } + + /** + * Adapts a link respecting all moves and making it a relative link according to the new id + * + * @param string $id A relative id + * @param bool $media If the id is a media id + * @return string The relative id, adapted according to the new/old id and the moves + */ + public function adaptRelativeId($id, $media = false) { + global $conf; + + if ($id === '') { + return $id; + } + + $abs_id = str_replace('/', ':', $id); + $abs_id = resolve_id($this->ns, $abs_id, false); + if (substr($abs_id, -1) === ':') + $abs_id .= $conf['start']; + $clean_id = cleanID($abs_id); + // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page + // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been + // deleted already + if (substr($clean_id, -1) === ':') + $clean_id .= $conf['start']; + + if (($media ? isset($this->media_moves[$clean_id]) : isset($this->moves[$clean_id])) || $this->ns !== $this->new_ns) { + if (!$media && isset($this->moves[$clean_id])) { + $new = $this->moves[$clean_id]; + } elseif ($media && isset($this->media_moves[$clean_id])) { + $new = $this->media_moves[$clean_id]; + } else { + $new = $clean_id; + + // only the namespace was changed so if the link still resolves to the same absolute id, we can skip the rest + $new_abs_id = str_replace('/', ':', $id); + $new_abs_id = resolve_id($this->new_ns, $new_abs_id, false); + if (substr($new_abs_id, -1) === ':') + $new_abs_id .= $conf['start']; + if ($new_abs_id == $abs_id) return $id; + } + $new_link = $new; + $new_ns = getNS($new); + // try to keep original pagename + if ($this->noNS($new) == $this->noNS($clean_id)) { + if ($new_ns == $this->new_ns) { + $new_link = $this->noNS($id); + if ($new_link === false) $new_link = $this->noNS($new); + if ($id == ':') + $new_link = ':'; + else if ($id == '/') + $new_link = '/'; + } else if ($new_ns != false) { + $new_link = $new_ns.':'.$this->noNS($id); + } else { + $new_link = $this->noNS($id); + if ($new_link === false) $new_link = $new; + } + } else if ($new_ns == $this->new_ns) { + $new_link = $this->noNS($new_link); + } else if (strpos($new_ns, $this->ns.':') === 0) { + $new_link = '.:'.substr($new_link, strlen($this->ns)+1); + } + + if ($this->new_ns != '' && $new_ns == false) { + $new_link = ':'.$new_link; + } + + return $new_link; + } else { + return $id; + } + } + + /** + * Remove the namespace from the given id like noNS(), but handles '/' as namespace separator + * @param string $id the id + * @return string the id without the namespace + */ + private function noNS($id) { + $pos = strrpos($id, ':'); + $spos = strrpos($id, '/'); + if ($pos === false) $pos = $spos; + if ($spos === false) $spos = $pos; + $pos = max($pos, $spos); + if ($pos!==false) { + return substr($id, $pos+1); + } else { + return $id; + } + } +} diff --git a/helper/rewrite.php b/helper/rewrite.php index ecd48f4..1b1b1ba 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -10,6 +10,9 @@ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); +// load required handler class +require_once(__DIR__ . '/handler.php'); + /** * Class helper_plugin_move_rewrite * From 599a3cb63a907a6be5c34cad63690e8586e62107 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 19:36:09 +0200 Subject: [PATCH 080/338] can't use FINALLY as a label name --- helper/plan.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 1e40a24..d8e24aa 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -274,14 +274,14 @@ protected function stepThroughDocuments($type = PLUGIN_MOVE_TYPE_PAGES, &$skip = list($src, $dst) = explode("\t", trim($line)); // should this item be skipped? - if($skip) goto FINALLY; + if($skip) goto FINISH; // move the page if(!$MoveOperator->$call($src, $dst)) { $this->log($mark, $src, $dst, false); // FAILURE! // automatically skip this item if wanted... - if($this->options['autoskip']) goto FINALLY; + if($this->options['autoskip']) goto FINISH; // ...otherwise abort the operation fclose($doclist); return false; @@ -296,7 +296,7 @@ protected function stepThroughDocuments($type = PLUGIN_MOVE_TYPE_PAGES, &$skip = * This adjusts counters and truncates the document list correctly * It is used to finalize a successful or skipped move */ - FINALLY: + FINISH: $skip = false; ftruncate($doclist, ftell($doclist)); $this->options[$counter]--; From a933a64c31d24b6e9f8037ea15c23440768f3c9e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 22:31:56 +0200 Subject: [PATCH 081/338] added namespace subscription moves again --- helper/file.php | 14 ++++++++++++ helper/plan.php | 60 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/helper/file.php b/helper/file.php index 06f903a..fa57101 100644 --- a/helper/file.php +++ b/helper/file.php @@ -94,6 +94,20 @@ public function moveMediaAttic($src_ns, $src_name, $dst_ns, $dst_name) { return $this->execute($conf['mediaolddir'], $src_ns, $name, $dst_ns, $newname, $regex); } + /** + * Moves the subscription file for a namespace + * + * @param string $src_ns + * @param string $dst_ns + * @return bool + */ + public function moveNamespaceSubscription($src_ns, $dst_ns){ + global $conf; + + $regex = '\.mlist'; + return $this->execute($conf['metadir'], $src_ns, '', $dst_ns, '', $regex); + } + /** * Executes the move op * diff --git a/helper/plan.php b/helper/plan.php index d8e24aa..2b3f3a4 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -53,10 +53,11 @@ public function __construct() { // set the file locations $this->files = array( - 'opts' => $conf['metadir'] . '/__move_opts', - 'pagelist' => $conf['metadir'] . '/__move_pagelist', - 'medialist' => $conf['metadir'] . '/__move_medialist', - 'affected' => $conf['metadir'] . '/__move_affected', + 'opts' => $conf['metadir'] . '/__move_opts', + 'pagelist' => $conf['metadir'] . '/__move_pagelist', + 'medialist' => $conf['metadir'] . '/__move_medialist', + 'affected' => $conf['metadir'] . '/__move_affected', + 'namespaces' => $conf['metadir'] . '/__move_namespaces' ); $this->loadOptions(); @@ -202,6 +203,14 @@ public function commit() { $this->addToMediaList($from, $to); } } + + // remember the namespace move itself + if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + // FIXME we use this to move namespace subscriptions later on and for now only do it on + // page namespace moves, but subscriptions work for both, but what when only one of + // them is moved? Should it be copied then? Complicated. This is good enough for now + $this->addToNamespaceList($move['src'], $move['dst']); + } } } @@ -237,7 +246,11 @@ public function nextStep($skip = false) { return max($todo, 1); // force one more call } - // FIXME handle namespace subscription moves + if(@filesize($this->files['namespaces']) > 1) { + $todo = $this->stepThroughNamespaces(); + if($todo === false) return false; + return max($todo, 1); // force one more call + } // we're done here, clean up $this->abort(); @@ -351,6 +364,31 @@ protected function stepThroughAffectedPages() { return $this->options['affpg_num']; } + /** + * Step through all the namespace moves + * + * Currently moves namespace subscriptions only. This does not step, but handles all namespaces + * in one step. + * + * @return int always 0 + * @todo maybe add an event so plugins can move more stuff? + */ + protected function stepThroughNamespaces() { + /** @var helper_plugin_move_file $FileMover */ + $FileMover = plugin_load('helper', 'move_file'); + + $lines = io_readFile($this->files['namespaces']); + $lines = explode("\n", $lines); + + foreach($lines as $line) { + list($src, $dst) = explode("\n", trim($line)); + $FileMover->moveNamespaceSubscription($src, $dst); + } + + @unlink($this->files['namespaces']); + return 0; + } + /** * Appends a page move operation in the list file * @@ -387,6 +425,18 @@ protected function addToMediaList($src, $dst) { return false; } + /** + * Appends a namespace move operation in the list file + * + * @param string $src + * @param string $dst + * @return bool + */ + protected function addToNamespaceList($src, $dst) { + $file = $this->files['namespaces']; + return io_saveFile($file, "$src\t$dst\n", true); + } + /** * Add the list of pages to the list of affected pages whose links need adjustment * From 4b709ac442fb9ef14f7fee4838ce3ffe0c90f989 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 10 Apr 2014 23:03:53 +0200 Subject: [PATCH 082/338] started refactoring the action parts --- action/rename.php | 120 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 action/rename.php diff --git a/action/rename.php b/action/rename.php new file mode 100644 index 0000000..29b4ddc --- /dev/null +++ b/action/rename.php @@ -0,0 +1,120 @@ + + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +class action_plugin_move_rename extends DokuWiki_Action_Plugin { + + /** + * Register event handlers. + * + * @param Doku_Event_Handler $controller The plugin controller + */ + public function register(Doku_Event_Handler $controller) { + $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'handle_init'); + $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'handle_pagetools'); + $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); + } + + /** + * set JavaScript info if renaming of current page is possible + */ + public function handle_init() { + global $JSINFO; + global $INFO; + $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']); + } + + /** + * Adds a button to the default template + * + * @param Doku_Event $event + */ + public function handle_pagetools(Doku_Event $event) { + global $conf; + if($event->data['view'] != 'main') return; + + switch($conf['template']) { + case 'dokuwiki': + case 'arago': + + $newitem = '
  • ' . $this->getLang('renamepage') . '
  • '; + $offset = count($event->data['items']) - 1; + $event->data['items'] = + array_slice($event->data['items'], 0, $offset, true) + + array('plugin_move' => $newitem) + + array_slice($event->data['items'], $offset, null, true); + break; + } + } + + /** + * Rename a single page + */ + public function handle_ajax(Doku_Event $event) { + if($event->data != 'plugin_move_rename') return; + $event->preventDefault(); + $event->stopPropagation(); + + global $MSG; + global $INPUT; + + $src = cleanID($INPUT->str('id')); + $dst = cleanID($INPUT->str('newid')); + + /** @var helper_plugin_move_op $MoveOperator */ + $MoveOperator = plugin_load('helper', 'move_op'); + + $JSON = new JSON(); + + header('Content-Type: application/json'); + + if($this->renameOkay($dst) && $MoveOperator->movePage($src, $dst)) { + // all went well, redirect + echo $JSON->encode(array('redirect_url' => wl($dst, '', true, '&'))); + } else { + if(isset($MSG[0])) { + $error = $MSG[0]; // first error + } else { + $error = 'Page can\'t be moved right now'; // FIXME localize + } + echo $JSON->encode(array('error' => $error)); + } + } + + /** + * Determines if it would be okay to show a rename page button for the given page and current user + * + * @param $id + * @return bool + */ + public function renameOkay($id) { + global $ACT; + global $USERINFO; + if(!($ACT == 'show' || empty($ACT))) return false; + if(!page_exists($id)) return false; + if(auth_quickaclcheck($id) < AUTH_EDIT) return false; + if(checklock($id) !== false || @file_exists(wikiLockFN($id))) return false; + if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], $USERINFO['grps'])) return false; + + return true; + } + + /** + * Use this in your template to add a simple "move this page" link + * + * Alternatively give anything the class "plugin_move_page" - it will automatically be hidden and shown and + * trigger the page move dialog. + */ + public function tpl() { + echo ''; + echo $this->getLang('renamepage'); + echo ''; + } + +} \ No newline at end of file From 996175ef69793c737bbaf0c55127a67eadf5b19d Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 11 Apr 2014 09:01:04 +0200 Subject: [PATCH 083/338] clean up of moved functions --- action.php | 87 ------------------------------------------------------ 1 file changed, 87 deletions(-) diff --git a/action.php b/action.php index 41321d2..74c6634 100644 --- a/action.php +++ b/action.php @@ -23,20 +23,8 @@ public function register(Doku_Event_Handler $controller) { $controller->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, 'handle_index_version'); $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'index_media_use'); $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call'); - $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'addbutton'); - $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'initJS'); } - /** - * set JavaScript info if renaming of current page is possible - */ - public function initJS() { - global $JSINFO; - global $INFO; - /** @var helper_plugin_move_general $hlp */ - $hlp = plugin_load('helper', 'move_general'); - $JSINFO['move_renameokay'] = $hlp->renameOkay($INFO['id']); - } /** * Rewrite pages when they are read and they need to be updated. @@ -188,10 +176,6 @@ public function handle_ajax_call(Doku_Event $event, $params) { $event->preventDefault(); $event->stopPropagation(); $this->ajax_continue(); - } elseif($event->data == 'plugin_move_rename') { - $event->preventDefault(); - $event->stopPropagation(); - $this->ajax_rename(); } elseif($event->data == 'plugin_move_tree') { $event->preventDefault(); $event->stopPropagation(); @@ -243,54 +227,6 @@ protected function ajax_continue() { echo $json->encode($result); } - /** - * Rename a single page - */ - protected function ajax_rename() { - global $ID; - global $MSG; - global $USERINFO; - - $json = new JSON(); - - /** @var helper_plugin_move_general $helper */ - $helper = $this->loadHelper('move_general', false); - $ID = cleanID((string) $_POST['id']); - $newid = cleanID((string) $_POST['newid']); - - - - $opts = array( - 'newns' => getNS($newid), - 'newname' => noNS($newid), - ); - - header('Content-Type: application/json'); - - - if(!auth_isMember($this->getConf('allowrename'), - $_SERVER['REMOTE_USER'], - $USERINFO['grps'])) { - echo $json->encode( - array( - 'error' => 'no permission' // should have never been called - no localization - ) - ); - } elseif(!$helper->move_page($opts)){ - echo $json->encode( - array( - 'error' => $MSG[0]['msg'] // first error - ) - ); - } else { - echo $json->encode( - array( - 'redirect_url' => wl($newid, '', true, '&') - ) - ); - } - } - protected function ajax_tree() { //FIXME user auth @@ -310,27 +246,4 @@ protected function ajax_tree() { ); } - /** - * Adds a button to the default template - * - * @param Doku_Event $event - * @param $params - */ - public function addbutton(Doku_Event $event, $params) { - global $conf; - if ($event->data['view'] != 'main') return; - - switch($conf['template']) { - case 'dokuwiki': - case 'arago': - - $newitem = '
  • '.$this->getLang('renamepage').'
  • '; - $offset = count($event->data['items']) - 1; - $event->data['items'] = - array_slice($event->data['items'], 0, $offset, true) + - array( 'plugin_move' => $newitem) + - array_slice($event->data['items'], $offset, NULL, true); - break; - } - } } \ No newline at end of file From 11e155f1dde97d5ca1d1e7307e8d8840ec666941 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 11 Apr 2014 09:21:45 +0200 Subject: [PATCH 084/338] more stuff moved out of action.php --- action.php | 75 --------------------------------- action/rename.php | 3 ++ action/rewrite.php | 102 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 75 deletions(-) create mode 100644 action/rewrite.php diff --git a/action.php b/action.php index 74c6634..985a172 100644 --- a/action.php +++ b/action.php @@ -26,81 +26,6 @@ public function register(Doku_Event_Handler $controller) { } - /** - * Rewrite pages when they are read and they need to be updated. - * - * @param Doku_Event $event The event object - * @param mixed $param Optional parameters (not used) - */ - function handle_read(Doku_Event $event, $param) { - global $ACT, $conf; - static $stack = array(); - // handle only reads of the current revision - if ($event->data[3]) return; - - $id = $event->data[2]; - if ($event->data[1]) $id = $event->data[1].':'.$id; - - if (!$id) { - // try to reconstruct the id from the filename - $path = $event->data[0][0]; - if (strpos($path, $conf['datadir']) === 0) { - $path = substr($path, strlen($conf['datadir'])+1); - $id = pathID($path); - } - } - - if (isset($stack[$id])) return; - - // Don't change the page when the user is currently changing the page content or the page is locked - $forbidden_actions = array('save', 'preview', 'recover', 'revert'); - if ((isset($ACT) && ( - in_array($ACT, $forbidden_actions) || (is_array($ACT) && in_array(key($ACT), $forbidden_actions) - ))) - // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user - // the file exists check checks if the page is reported unlocked if a lock exists which means that - // the page is locked by the current user - || checklock($id) !== false || @file_exists(wikiLockFN($id))) return; - - /** @var helper_plugin_move_general $helper */ - $helper = $this->loadHelper('move_general', true); - if(!is_null($helper)) { - $stack[$id] = true; - $event->result = $helper->execute_rewrites($id, $event->result); - unset($stack[$id]); - } - } - - /** - * Handle the cache events, it looks if a page needs to be rewritten so it can expire the cache of the page - * - * @param Doku_Event $event The even object - * @param mixed $param Optional parameters (not used) - */ - function handle_cache(Doku_Event $event, $param) { - global $conf; - /** @var $cache cache_parser */ - $cache = $event->data; - $id = $cache->page; - if (!$id) { - // try to reconstruct the id from the filename - $path = $cache->file; - if (strpos($path, $conf['datadir']) === 0) { - $path = substr($path, strlen($conf['datadir'])+1); - $id = pathID($path); - } - } - if ($id) { - $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); - if ($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { - $file = wikiFN($id, '', false); - if (is_writable($file)) - $cache->depends['purge'] = true; - else // FIXME: print error here or fail silently? - msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); - } - } - } /** * Add the move version to theindex version diff --git a/action/rename.php b/action/rename.php index 29b4ddc..40c8655 100644 --- a/action/rename.php +++ b/action/rename.php @@ -8,6 +8,9 @@ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); +/** + * Class action_plugin_move_rename + */ class action_plugin_move_rename extends DokuWiki_Action_Plugin { /** diff --git a/action/rewrite.php b/action/rewrite.php new file mode 100644 index 0000000..f2ddcc0 --- /dev/null +++ b/action/rewrite.php @@ -0,0 +1,102 @@ + + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class action_plugin_move_rewrite + */ +class action_plugin_move_rewrite extends DokuWiki_Action_Plugin { + + /** + * Register event handlers. + * + * @param Doku_Event_Handler $controller The plugin controller + */ + public function register(Doku_Event_Handler $controller) { + $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_read', array()); + $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache', array()); + } + + /** + * Rewrite pages when they are read and they need to be updated. + * + * @param Doku_Event $event The event object + * @param mixed $param Optional parameters (not used) + */ + function handle_read(Doku_Event $event, $param) { + global $ACT, $conf; + static $stack = array(); + // handle only reads of the current revision + if($event->data[3]) return; + + $id = $event->data[2]; + if($event->data[1]) $id = $event->data[1].':'.$id; + + if(!$id) { + // try to reconstruct the id from the filename + $path = $event->data[0][0]; + if(strpos($path, $conf['datadir']) === 0) { + $path = substr($path, strlen($conf['datadir']) + 1); + $id = pathID($path); + } + } + + if(isset($stack[$id])) return; + + // Don't change the page when the user is currently changing the page content or the page is locked + $forbidden_actions = array('save', 'preview', 'recover', 'revert'); + if((isset($ACT) && ( + in_array($ACT, $forbidden_actions) || (is_array($ACT) && in_array(key($ACT), $forbidden_actions) + ))) + // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user + // the file exists check checks if the page is reported unlocked if a lock exists which means that + // the page is locked by the current user + || checklock($id) !== false || @file_exists(wikiLockFN($id)) + ) return; + + /** @var helper_plugin_move_rewrite $helper */ + $helper = plugin_load('helper', 'move_rewrite', true); + if(!is_null($helper)) { + $stack[$id] = true; + $event->result = $helper->execute_rewrites($id, $event->result); + unset($stack[$id]); + } + } + + /** + * Handle the cache events, it looks if a page needs to be rewritten so it can expire the cache of the page + * + * @param Doku_Event $event The even object + * @param mixed $param Optional parameters (not used) + */ + function handle_cache(Doku_Event $event, $param) { + global $conf; + /** @var $cache cache_parser */ + $cache = $event->data; + $id = $cache->page; + if(!$id) { + // try to reconstruct the id from the filename + $path = $cache->file; + if(strpos($path, $conf['datadir']) === 0) { + $path = substr($path, strlen($conf['datadir']) + 1); + $id = pathID($path); + } + } + if($id) { + $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); + if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { + $file = wikiFN($id, '', false); + if(is_writable($file)) + $cache->depends['purge'] = true; + else // FIXME: print error here or fail silently? + msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + } + } + } +} \ No newline at end of file From 9eea5e2f6b5b196535d25fd26199837879ca73eb Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 11 Apr 2014 09:39:21 +0200 Subject: [PATCH 085/338] fixed another test file --- action.php => _action.php | 0 _test/mediamove.test.php | 35 +++++++++++++---------------------- helper/op.php | 4 ++-- 3 files changed, 15 insertions(+), 24 deletions(-) rename action.php => _action.php (100%) diff --git a/action.php b/_action.php similarity index 100% rename from action.php rename to _action.php diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index 9b0c8ee..f70850c 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -14,23 +14,18 @@ public function setUp() { } public function test_movePageWithRelativeMedia() { - global $ID; - - $ID = 'mediareltest:foo'; - saveWikiText($ID, + $src = 'mediareltest:foo'; + saveWikiText($src, '{{ myimage.png}} [[:start|{{ testimage.png?200x800 }}]] [[bar|{{testimage.gif?400x200}}]] [[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{testimage.jpg}}]] [[doku>wiki:foo|{{foo.gif?200x3000}}]]', 'Test setup'); - idx_addPage($ID); + idx_addPage($src); + + $dst = 'foo'; - $opts = array(); - $opts['ns'] = getNS($ID); - $opts['name'] = noNS($ID); - $opts['newns'] = ''; - $opts['newname'] = 'foo'; - /** @var helper_plugin_move $move */ - $move = plugin_load('helper', 'move'); - $this->assertTrue($move->move_page($opts)); + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + $this->assertTrue($move->movePage($src, $dst)); $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}}]] @@ -39,22 +34,18 @@ public function test_movePageWithRelativeMedia() { 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'; + $src = 'wiki:dokuwiki-128.png'; + $dst = 'foobar:logo.png'; - /** @var helper_plugin_move $move */ - $move = plugin_load('helper', 'move'); - $this->assertTrue($move->move_media($opts)); + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + $this->assertTrue($move->moveMedia($src, $dst)); $this->assertTrue(@file_exists(mediaFn('foobar:logo.png'))); diff --git a/helper/op.php b/helper/op.php index 39b6dc2..b9febed 100644 --- a/helper/op.php +++ b/helper/op.php @@ -83,7 +83,7 @@ public function checkMedia($src, $dst) { msg(sprintf($this->getLang('medianotexist'), hsc($src)), -1); return false; } - if(auth_quickaclcheck($dst) < AUTH_DELETE) { + if(auth_quickaclcheck($src) < AUTH_DELETE) { msg(sprintf($this->getLang('nomediarights'), hsc($src)), -1); return false; } @@ -284,7 +284,7 @@ public function moveMedia($src, $dst) { } // prepare directory - io_createNamespace($src, 'media'); + io_createNamespace($dst, 'media'); // move it FIXME this does not create a changelog entry! if(!io_rename(mediaFN($src), mediaFN($dst))) { From d13225c420e1921e29187c5319dea1fe615574cc Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 11 Apr 2014 11:39:55 +0200 Subject: [PATCH 086/338] fixed another test this should now generally cover all backend functionality. not in detail but the most basic stuff --- _test/namespace_move.test.php | 26 ++++++++------- helper/plan.php | 60 +++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 2767d25..3966fd3 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -21,17 +21,21 @@ public function test_move_wiki_namespace() { idx_addPage('wiki:dokuwiki'); idx_addPage('wiki:syntax'); - /** @var helper_plugin_move $move */ - $move = plugin_load('helper', 'move'); - $opts = array( - 'ns' => 'wiki', - 'newns' => 'foo', - 'contenttomove' => 'both' - ); - - $this->assertSame(3, $move->start_namespace_move($opts)); - $this->assertSame(1, $move->continue_namespace_move()); - $this->assertSame(0, $move->continue_namespace_move()); + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('wiki', 'foo'); + $plan->addMediaNamespaceMove('wiki', 'foo'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep()); // pages + $this->assertSame(1, $plan->nextStep()); // media + $this->assertSame(1, $plan->nextStep()); // links + $this->assertSame(1, $plan->nextStep()); // namepaces + $this->assertSame(0, $plan->nextStep()); // done $this->assertFileExists(wikiFN('foo:dokuwiki')); $this->assertFileNotExists(wikiFN('wiki:syntax')); diff --git a/helper/plan.php b/helper/plan.php index 2b3f3a4..db9f8d8 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -115,6 +115,46 @@ public function inProgress() { return $this->options['committed']; } + /** + * Add a single page to be moved to the plan + * + * @param string $src + * @param string $dst + */ + public function addPageMove($src, $dst) { + $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_DOC, PLUGIN_MOVE_TYPE_PAGES); + } + + /** + * Add a single media file to be moved to the plan + * + * @param string $src + * @param string $dst + */ + public function addMediaMove($src, $dst) { + $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_DOC, PLUGIN_MOVE_TYPE_MEDIA); + } + + /** + * Add a page namespace to be moved to the plan + * + * @param string $src + * @param string $dst + */ + public function addPageNamespaceMove($src, $dst) { + $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_NS, PLUGIN_MOVE_TYPE_PAGES); + } + + /** + * Add a media namespace to be moved to the plan + * + * @param string $src + * @param string $dst + */ + public function addMediaNamespaceMove($src, $dst) { + $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_NS, PLUGIN_MOVE_TYPE_MEDIA); + } + /** * Plans the move of a namespace or document * @@ -124,7 +164,7 @@ public function inProgress() { * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) * @throws Exception */ - public function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGIN_MOVE_TYPE_PAGES) { + protected function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGIN_MOVE_TYPE_PAGES) { if($this->options['commited']) throw new Exception('plan is commited already, can not be added to'); $src = cleanID($src); @@ -214,7 +254,7 @@ public function commit() { } } - $this->options['committed'] = true; + $this->options['commited'] = true; $this->options['started'] = time(); } @@ -469,17 +509,23 @@ protected function getLastLine($handle) { // seek one backwards as long as it's possible while(fseek($handle, -1, SEEK_CUR) >= 0) { $c = fgetc($handle); + if($c === false) return false; // EOF, i.e. the file is empty fseek($handle, -1, SEEK_CUR); // reset the position to the character that was read if($c == "\n") { - break; + if($line === '') { + continue; // this line was empty, continue + } else { + break; // we have a line, finish + } } - if($c === false) return false; // EOF, i.e. the file is empty - $line = $c . $line; + + $line = $c . $line; // prepend char to line } - if($line === '') return false; // nothing was read i.e. the file is empty - return trim($line); + if($line === '') return false; // beginning of file reached and no content + + return $line; } /** From ef12c06b1e142abbfea7cc33dbf189d5f1af702e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 11 Apr 2014 11:47:52 +0200 Subject: [PATCH 087/338] travis setup this adds the correct group headers to the tests and sets up a travis config. the indexer test has been removed as this is now core functionality --- .travis.yml | 11 ++++++++ _test/mediaindex.test.php | 50 ----------------------------------- _test/mediamove.test.php | 3 +++ _test/namespace_move.test.php | 3 +++ _test/pagemove.test.php | 3 +++ 5 files changed, 20 insertions(+), 50 deletions(-) create mode 100644 .travis.yml delete mode 100644 _test/mediaindex.test.php diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..257209f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: php +php: + - "5.5" + - "5.4" + - "5.3" +env: + - DOKUWIKI=master + - DOKUWIKI=stable +before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh +install: sh travis.sh +script: cd _test && phpunit --stderr --group plugin_move diff --git a/_test/mediaindex.test.php b/_test/mediaindex.test.php deleted file mode 100644 index f5944ab..0000000 --- a/_test/mediaindex.test.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ -class plugin_move_mediaindex_test extends DokuWikiTest { - - public function setUp() { - $this->pluginsEnabled[] = 'move'; - parent::setUp(); - } - - public function test_internalmedia() { - saveWikiText('test:internalmedia_usage', '{{internalmedia.png}} {{..:internal media.png}}', 'Test initialization'); - idx_addPage('test:internalmedia_usage'); - - $query = array('test:internalmedia.png', 'internal_media.png'); - $this->assertEquals( array( - 'test:internalmedia.png' => array('test:internalmedia_usage'), - 'internal_media.png' => array('test:internalmedia_usage') - ), idx_get_indexer()->lookupKey('relation_media', $query)); - } - - public function test_media_in_links() { - saveWikiText('test:medialinks', '[[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{example.png?200x800}}]]', 'Test init'); - idx_addPage('test:medialinks'); - - $query = array('wiki:logo.png', 'test:example.png'); - $this->assertEquals(array( - 'wiki:logo.png' => array('test:medialinks'), - 'test:example.png' => array('test:medialinks') - ), idx_get_indexer()->lookupKey('relation_media', $query)); - } - - public function test_media_in_footnotes() { - saveWikiText('test:media_footnotes', '(({{footnote.png?20x50}} [[foonote|{{:footlink.png}}]]))', 'Test initialization'); - idx_addPage('test:media_footnotes'); - - $query = array('test:footnote.png', 'footlink.png'); - $this->assertEquals(array( - 'test:footnote.png' => array('test:media_footnotes'), - 'footlink.png' => array('test:media_footnotes') - ), idx_get_indexer()->lookupKey('relation_media', $query)); - } -} diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index f70850c..17efa86 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -5,6 +5,9 @@ /** * Test cases for the move plugin + * + * @group plugin_move + * @group plugins */ class plugin_move_mediamove_test extends DokuWikiTest { diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 3966fd3..e3ad49a 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -5,6 +5,9 @@ /** * Test cases for namespace move functionality of the move plugin + * + * @group plugin_move + * @group plugins */ class plugin_move_namespace_move_test extends DokuWikiTest { diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 67aaecc..d38b15a 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -5,6 +5,9 @@ /** * Test cases for the move plugin + * + * @group plugin_move + * @group plugins */ class plugin_move_pagemove_test extends DokuWikiTest { From a49f4c0f960709c910e47f70b19e986c2f0c356e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 11 Apr 2014 11:53:10 +0200 Subject: [PATCH 088/338] added some beef to the README --- README | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README b/README index 44b8df2..8028d59 100644 --- a/README +++ b/README @@ -1 +1,29 @@ -A DokuWiki move plugin +move Plugin for DokuWiki + +Move and rename pages and media files while maintaining the links. + +All documentation for this plugin can be found at +http://www.dokuwiki.org/plugin:move + +If you install this plugin manually, make sure it is installed in +lib/plugins/move/ - if the folder is called different it +will not work! + +Please refer to http://www.dokuwiki.org/plugins for additional info +on how to install plugins in DokuWiki. + +---- +Copyright (C) Michael Hamann , + Andreas Gohr , + and others + +This program 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; version 2 of the License + +This program 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. + +See the COPYING file in your DokuWiki folder for details \ No newline at end of file From 146500c608acc41e904c8842667c5e5986700eca Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 13 Apr 2014 21:32:37 +0200 Subject: [PATCH 089/338] started work on the admin interface makeing it a little simpler and hopefully less confusing --- admin/main.php | 196 +++++++++++++++++++++++++++++++++++++++++++++ admin/simple.php | 31 ++++--- helper/general.php | 2 +- helper/plan.php | 154 ++++++++++++++++++++++++++++------- lang/en/lang.php | 9 +++ 5 files changed, 352 insertions(+), 40 deletions(-) create mode 100644 admin/main.php diff --git a/admin/main.php b/admin/main.php new file mode 100644 index 0000000..d356516 --- /dev/null +++ b/admin/main.php @@ -0,0 +1,196 @@ + + * @author Gary Owen, + */ + +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Admin component of the move plugin. Provides the user interface. + */ +class admin_plugin_move_main extends DokuWiki_Admin_Plugin { + + /** @var helper_plugin_move_plan $plan */ + protected $plan; + + public function __construct() { + $this->plan = plugin_load('helper', 'move_plan'); + } + + /** + * Get the sort number that defines the position in the admin menu. + * + * @return int The sort number + */ + function getMenuSort() { + return 1000; + } + + /** + * If this admin plugin is for admins only + * @return bool false + */ + function forAdminOnly() { + return false; + } + + function handle() { + global $INPUT; + + // create a new plan if possible and sufficient data was given + $this->createPlanFromInput(); + + // handle workflow button presses + if($this->plan->isCommited()) { + switch($INPUT->str('ctl')) { + case 'continue': + $this->plan->nextStep(); + break; + case 'skip': + $this->plan->nextStep(true); + break; + case 'abort': + $this->plan->abort(); + break; + } + } + } + + function html() { + // decide what to do based on the plan's state + if($this->plan->isCommited()) { + $this->GUI_progress(); + } else { + // display form + $this->GUI_simpleForm(); + } + } + + /** + * Create a plan from input + * + * @return bool + */ + protected function createPlanFromInput() { + global $INPUT; + global $ID; + + if($this->plan->isCommited()) return false; + + $this->plan->setOption('autoskip', $INPUT->bool('autoskip')); + $this->plan->setOption('autorewrite', $INPUT->bool('autorewrite')); + + if($ID && $INPUT->has('dst')) { + // input came from form + if($INPUT->str('class') == 'namespace') { + $src = getNS($ID); + + if($INPUT->str('type') == 'both') { + $this->plan->addPageNamespaceMove($src, $INPUT->str('dst')); + $this->plan->addMediaNamespaceMove($src, $INPUT->str('dst')); + } else if($INPUT->str('type') == 'page') { + $this->plan->addPageNamespaceMove($src, $INPUT->str('dst')); + } else if($INPUT->str('type') == 'media') { + $this->plan->addMediaNamespaceMove($src, $INPUT->str('dst')); + } + } else { + $this->plan->addPageMove($ID, $INPUT->str('dst')); + } + $this->plan->commit(); + return true; + } elseif($INPUT->has('json')) { + // input came via JSON from tree manager + // FIXME + $this->plan->commit(); + return true; + } + + return false; + } + + protected function GUI_simpleForm() { + global $ID; + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__form')); + $form->addHidden('page', 'move_main'); + $form->addHidden('id', $ID); + + $form->startFieldset('FIMXE'); + + $form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage'))); + $form->addElement(form_makeRadioField('class', 'namepsace', $this->getLang('movens'))); + $form->addElement(form_makeTextField('dst', $ID, 'new name*')); + + $form->addElement(form_makeMenuField('type', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); + $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', 'block', ($this->getConf('autoskip') ? array('checked' => 'checked') : array()))); + $form->addElement(form_makeCheckboxField('autorewrite', '1', $this->getLang('autorewrite'), '', 'block', ($this->getConf('autorewrite') ? array('checked' => 'checked') : array()))); + + $form->addElement(form_makeButton('submit', 'admin', 'preview')); + $form->endFieldset(); + $form->printForm(); + } + + protected function GUI_previewPlan() { + $this->createPlanFromInput(); + + } + + /** + * Display the GUI while the move progresses + */ + protected function GUI_progress() { + $progress = $this->plan->getProgress(); + + // FIXME add intro here depending on start or progress + + echo '
    ' . $progress . '%
    '; + + + echo '
    '; + if($this->plan->getLastError()) { + echo '
    ' . $this->plan->getLastError() . '
    '; + } + echo '
    '; + + + echo '
    '; + if(!$this->plan->inProgress()) { + $this->btn('start'); + } else if($this->plan->getLastError()) { + $this->btn('skip'); + $this->btn('retry'); + } else { + $this->btn('continue'); + } + $this->btn('abort'); + echo '
    '; + } + + /** + * Display a move workflow button + * + * continue, start, retry - continue next steps + * abort - abort the whole move + * skip - skip error and continue + * + * @param string $control + */ + protected function btn($control) { + global $ID; + + $label = $this->getLang('btn_' . $control); + if($control == 'start') $control = 'continue'; + if($control == 'retry') $control = 'continue'; + + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__control')); + $form->addHidden('page', 'move_main'); + $form->addHidden('id', $ID); + $form->addHidden('ctl', $control); + $form->addElement(form_makeButton('submit', 'admin', $label)); + $form->printForm(); + } +} \ No newline at end of file diff --git a/admin/simple.php b/admin/simple.php index 1e2db57..87bb566 100644 --- a/admin/simple.php +++ b/admin/simple.php @@ -15,12 +15,8 @@ */ class admin_plugin_move_simple extends DokuWiki_Admin_Plugin { - var $opts = array(); - private $ns_opts = false; - /** @var helper_plugin_move_general $helper */ - private $helper = null; /** @var string $ns_move_state The state of the current namespace move (none, started, continued, error) */ - private $ns_move_state = 'none'; + protected $ns_move_state = 'none'; /** * Get the sort number that defines the position in the admin menu. @@ -67,11 +63,27 @@ function getMenuText() { * @author Gary Owen */ function html() { - if (!$this->helper) return; + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + ptln(''); ptln( $this->locale_xhtml('move') ); ptln('
    '); + if($plan->inProgress()){ + if($plan->getLastError()) { + ptln('

    '); + ptln(sprintf($this->getLang('ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); + ptln('

    '); + ptln($this->helper->getNSMoveButton('tryagain')); + ptln($this->helper->getNSMoveButton('skip')); + ptln($this->helper->getNSMoveButton('abort')); + } else { + + } + + } + switch ($this->ns_move_state) { case 'started': ptln('

    '); @@ -89,12 +101,7 @@ function html() { ptln('

    '); break; case 'error': - ptln('

    '); - ptln(sprintf($this->getLang('ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); - ptln('

    '); - ptln($this->helper->getNSMoveButton('tryagain')); - ptln($this->helper->getNSMoveButton('skip')); - ptln($this->helper->getNSMoveButton('abort')); + break; case 'continued': ptln('

    '); diff --git a/helper/general.php b/helper/general.php index 0e246f8..4ebc87f 100644 --- a/helper/general.php +++ b/helper/general.php @@ -11,7 +11,7 @@ /** * Helper part of the move plugin. */ -class helper_plugin_move_general extends DokuWiki_Plugin { +class helper_plugin_move_generalXXX extends DokuWiki_Plugin { /** * @var string symbol to make move operations easily recognizable in change log diff --git a/helper/plan.php b/helper/plan.php index db9f8d8..843ea34 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -86,13 +86,16 @@ protected function loadOptions() { // options 'autoskip' => $this->getConf('autoskip'), - 'autorewrite' => $this->getConf('autorewrite') + 'autorewrite' => $this->getConf('autorewrite'), + + // errors + 'lasterror' => false ); // merge whatever options are saved currently $file = $this->files['opts']; if(file_exists($file)) { - $options = unserialize(io_readFile($file, false)); + $options = unserialize(io_readFile($file, false)); $this->options = array_merge($this->options, $options); } } @@ -106,13 +109,68 @@ protected function saveOptions() { return io_saveFile($this->files['opts'], serialize($this->options)); } + /** + * Return the current state of an option, null for unknown options + * + * @param $name + * @return mixed|null + */ + public function getOption($name) { + if(isset($this->options[$name])) { + return $this->options[$name]; + } + return null; + } + + /** + * Set an option + * + * Note, this otpion will only be set to the current instance of this helper object. It will only + * be written to the option file once the plan gets committed + * + * @param $name + * @param $value + */ + public function setOption($name, $value) { + $this->options[$name] = $value; + } + + /** + * Returns the progress of this plan in percent + * + * @return float + */ + public function getProgress() { + $max = + $this->options['pages_all'] + + $this->options['media_all'] + + $this->options['affpg_all']; + + $remain = + $this->options['pages_run'] + + $this->options['media_run'] + + $this->options['affpg_run']; + + if($max == 0) return 0; + return round((($max-$remain) * 100) / $max, 2); + } + /** * Check if there is a move in progress currently * * @return bool */ public function inProgress() { - return $this->options['committed']; + return (bool) $this->options['started']; + } + + /** + * Check if this plan has been commited, yet + * + * @return bool + */ + public function isCommited() { + return $this->options['commited']; } /** @@ -158,10 +216,10 @@ public function addMediaNamespaceMove($src, $dst) { /** * Plans the move of a namespace or document * - * @param string $src ID of the item to move + * @param string $src ID of the item to move * @param string $dst new ID of item namespace - * @param int $class (PLUGIN_MOVE_CLASS_NS|PLUGIN_MOVE_CLASS_DOC) - * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) + * @param int $class (PLUGIN_MOVE_CLASS_NS|PLUGIN_MOVE_CLASS_DOC) + * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) * @throws Exception */ protected function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGIN_MOVE_TYPE_PAGES) { @@ -184,7 +242,7 @@ protected function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PL * Abort any move or plan in progress and reset the helper */ public function abort() { - foreach ($this->files as $file) { + foreach($this->files as $file) { @unlink($file); } $this->plan = array(); @@ -235,7 +293,7 @@ public function commit() { // now add all the found documents to our lists foreach($docs as $doc) { $from = $doc['id']; - $to = $move['dst'] . substr($doc['id'], $strip); + $to = $move['dst'] . substr($doc['id'], $strip); if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { $this->addToPageList($from, $to); @@ -255,7 +313,7 @@ public function commit() { } $this->options['commited'] = true; - $this->options['started'] = time(); + $this->saveOptions(); } /** @@ -268,27 +326,30 @@ public function commit() { public function nextStep($skip = false) { if(!$this->options['commited']) throw new Exception('plan is not committed yet!'); + // execution has started + if(!$this->options['started']) $this->options['started'] = time(); + if(@filesize($this->files['pagelist']) > 1) { $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_PAGES, $skip); - if($todo === false) return false; + if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['medialist']) > 1) { $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_MEDIA, $skip); - if($todo === false) return false; + if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { $todo = $this->stepThroughAffectedPages(); - if($todo === false) return false; + if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['namespaces']) > 1) { $todo = $this->stepThroughNamespaces(); - if($todo === false) return false; + if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } @@ -300,7 +361,7 @@ public function nextStep($skip = false) { /** * Step through the next bunch of pages or media files * - * @param int $type (PLUGIN_MOVE_TYPE_PAGES|PLUGIN_MOVE_TYPE_MEDIA) + * @param int $type (PLUGIN_MOVE_TYPE_PAGES|PLUGIN_MOVE_TYPE_MEDIA) * @param bool $skip should the first item be skipped? * @return bool|int false on error, otherwise the number of remaining documents */ @@ -309,14 +370,14 @@ protected function stepThroughDocuments($type = PLUGIN_MOVE_TYPE_PAGES, &$skip = $MoveOperator = plugin_load('helper', 'move_op'); if($type == PLUGIN_MOVE_TYPE_PAGES) { - $file = $this->files['pagelist']; - $mark = 'P'; - $call = 'movePage'; + $file = $this->files['pagelist']; + $mark = 'P'; + $call = 'movePage'; $counter = 'pages_num'; } else { - $file = $this->files['medialist']; - $mark = 'M'; - $call = 'moveMedia'; + $file = $this->files['medialist']; + $mark = 'M'; + $call = 'moveMedia'; $counter = 'media_num'; } @@ -429,6 +490,45 @@ protected function stepThroughNamespaces() { return 0; } + /** + * Retrieve the last error from the MSG array and store it in the options + * + * @todo rebuild error handling based on exceptions + * + * @return bool always false + */ + protected function storeError() { + global $MSG; + + if(is_array($MSG) && count($MSG)) { + $last = array_shift($MSG); + $this->options['lasterror'] = $last['msg']; + unset($GLOBALS['MSG']); + } else { + $this->options['lasterror'] = 'Unknown error'; + } + $this->saveOptions(); + + return false; + } + + /** + * Reset the error state + */ + protected function clearError() { + $this->options['lasterror'] = false; + $this->saveOptions(); + } + + /** + * Get the last error message or false if no error occured + * + * @return bool|string + */ + public function getLastError() { + return $this->options['lasterror']; + } + /** * Appends a page move operation in the list file * @@ -575,23 +675,23 @@ public function planSorter($a, $b) { * @param string $type * @param string $from * @param string $to - * @param bool $success + * @param bool $success * @author Andreas Gohr */ - private function log($type, $from, $to, $success) { + protected function log($type, $from, $to, $success) { global $conf; global $MSG; $optime = $this->options['started']; - $file = $conf['cachedir'] . '/move-' . $optime . '.log'; - $now = time(); - $date = date('Y-m-d H:i:s', $now); // for human readability + $file = $conf['cachedir'] . '/move-' . $optime . '.log'; + $now = time(); + $date = date('Y-m-d H:i:s', $now); // for human readability if($success) { - $ok = 'success'; + $ok = 'success'; $msg = ''; } else { - $ok = 'failed'; + $ok = 'failed'; $msg = $MSG[count($MSG) - 1]['msg']; // get detail from message array } diff --git a/lang/en/lang.php b/lang/en/lang.php index b4c51bb..618e3b5 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -49,6 +49,15 @@ $lang['ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; $lang['ns_move_tryagain'] = 'Try again'; $lang['ns_move_skip'] = 'Skip the current item'; + +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Continue'; +$lang['btn_retry'] = 'Retry item'; +$lang['btn_skip'] = 'Skip item'; +$lang['btn_abort'] = 'Abort'; + + + // Form labels $lang['newname'] = 'New page name:'; $lang['newnsname'] = 'New namespace name:'; From e4de322f3b253d9b857eeb38015b19b7f592dacf Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 14 Apr 2014 09:37:27 +0200 Subject: [PATCH 090/338] fixed up the form --- admin/main.php | 32 +++++++++++++++++++++----------- lang/en/lang.php | 11 ++++++----- script.js | 2 ++ script/form.js | 14 ++++++++++++++ style.less | 16 ++++++++++++++++ 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 script/form.js diff --git a/admin/main.php b/admin/main.php index d356516..223cfee 100644 --- a/admin/main.php +++ b/admin/main.php @@ -86,17 +86,23 @@ protected function createPlanFromInput() { $this->plan->setOption('autorewrite', $INPUT->bool('autorewrite')); if($ID && $INPUT->has('dst')) { + $dst = trim($INPUT->str('dst')); + if($dst == '') { + msg($this->getLang('nodst'), -1); + return false; + } + // input came from form if($INPUT->str('class') == 'namespace') { $src = getNS($ID); if($INPUT->str('type') == 'both') { - $this->plan->addPageNamespaceMove($src, $INPUT->str('dst')); - $this->plan->addMediaNamespaceMove($src, $INPUT->str('dst')); + $this->plan->addPageNamespaceMove($src, $dst); + $this->plan->addMediaNamespaceMove($src, $dst); } else if($INPUT->str('type') == 'page') { - $this->plan->addPageNamespaceMove($src, $INPUT->str('dst')); + $this->plan->addPageNamespaceMove($src, $dst); } else if($INPUT->str('type') == 'media') { - $this->plan->addMediaNamespaceMove($src, $INPUT->str('dst')); + $this->plan->addMediaNamespaceMove($src, $dst); } } else { $this->plan->addPageMove($ID, $INPUT->str('dst')); @@ -113,23 +119,27 @@ protected function createPlanFromInput() { return false; } + /** + * Display the simple move form + */ protected function GUI_simpleForm() { global $ID; - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__form')); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'plugin_move_form')); $form->addHidden('page', 'move_main'); $form->addHidden('id', $ID); - $form->startFieldset('FIMXE'); + $form->startFieldset($this->getLang('legend')); + + $form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage') . ' '.$ID.'', '', 'block radio click-page', array('checked' => 'checked'))); + $form->addElement(form_makeRadioField('class', 'namepsace', $this->getLang('movens') . ' '.getNS($ID).'', '', 'block radio click-ns')); + $form->addElement(form_makeTextField('dst', $ID, $this->getLang('dst'), '', 'block indent')); - $form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage'))); - $form->addElement(form_makeRadioField('class', 'namepsace', $this->getLang('movens'))); - $form->addElement(form_makeTextField('dst', $ID, 'new name*')); + $form->addElement(form_makeMenuField('type', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), 'both', $this->getLang('content_to_move'), '', 'block indent select')); - $form->addElement(form_makeMenuField('type', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', 'block', ($this->getConf('autoskip') ? array('checked' => 'checked') : array()))); $form->addElement(form_makeCheckboxField('autorewrite', '1', $this->getLang('autorewrite'), '', 'block', ($this->getConf('autorewrite') ? array('checked' => 'checked') : array()))); - $form->addElement(form_makeButton('submit', 'admin', 'preview')); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('btn_start'))); $form->endFieldset(); $form->printForm(); } diff --git a/lang/en/lang.php b/lang/en/lang.php index 618e3b5..30c3e9c 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -39,6 +39,8 @@ $lang['filelocked'] = 'The page %s is locked. Try again later.'; $lang['linkchange'] = 'Links adapted because of a move operation'; +$lang['nodst'] = 'No new name given'; + $lang['preview'] = 'Preview changes to be executed'; $lang['ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; @@ -59,19 +61,18 @@ // Form labels -$lang['newname'] = 'New page name:'; -$lang['newnsname'] = 'New namespace name:'; -$lang['targetns'] = 'Select new namespace:'; -$lang['newtargetns'] = 'Create a new namespace:'; +$lang['legend'] = 'Move current page or namespace'; + $lang['movepage'] = 'Move page'; $lang['movens'] = 'Move namespace'; -$lang['submit'] = 'Submit'; +$lang['dst'] = 'New name:'; $lang['content_to_move'] = 'Content to move:'; $lang['autoskip'] = 'Ignore errors and skip pages that can\'t be moved'; $lang['autorewrite'] = 'Rewrite links right after the move completed'; $lang['move_pages'] = 'Pages'; $lang['move_media'] = 'Media files'; $lang['move_media_and_pages'] = 'Pages and media files'; + // JavaScript preview $lang['js']['previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; $lang['js']['previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; diff --git a/script.js b/script.js index 1963ad3..c809b03 100644 --- a/script.js +++ b/script.js @@ -6,6 +6,8 @@ /* DOKUWIKI:include_once script/json2.js */ jQuery(function() { + /* DOKUWIKI:include script/form.js */ + /* DOKUWIKI:include script/tree.js */ /* DOKUWIKI:include script/move.js */ /* DOKUWIKI:include script/rename.js */ diff --git a/script/form.js b/script/form.js new file mode 100644 index 0000000..31e8de5 --- /dev/null +++ b/script/form.js @@ -0,0 +1,14 @@ +jQuery('form.plugin_move_form').each(function(){ + var $form = jQuery(this); + + $form.find('.click-page').click(function() { + $form.find('input[name=dst]').val($form.find('.click-page code').text()); + $form.find('.select').hide(); + }).click(); + + $form.find('.click-ns').click(function() { + $form.find('input[name=dst]').val($form.find('.click-ns code').text()); + $form.find('.select').show(); + }); + +}); \ No newline at end of file diff --git a/style.less b/style.less index 34794d7..bf4c033 100644 --- a/style.less +++ b/style.less @@ -17,6 +17,22 @@ ul.plugin_move_tree { } +.dokuwiki .plugin_move_form { + label.block { + text-align: left; + } + + label.indent { + padding-left: 15px; + + select, + input { + float: right; + } + } +} + + /** * Pagetool icon */ From 1df3cb9f5d1a55e40e337c5a0c2a93c606aefadd Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 14 Apr 2014 12:43:23 +0200 Subject: [PATCH 091/338] progressing through a plan now roughly works again --- _action.php | 174 -------------------------------------------- action/progress.php | 60 +++++++++++++++ admin/main.php | 57 +++++++++------ helper/plan.php | 76 ++++++++++++++----- lang/en/lang.php | 2 + script.js | 3 +- script/move.js | 103 -------------------------- script/progress.js | 94 ++++++++++++++++++++++++ style.less | 26 +++++-- 9 files changed, 270 insertions(+), 325 deletions(-) delete mode 100644 _action.php create mode 100644 action/progress.php delete mode 100644 script/move.js create mode 100644 script/progress.js diff --git a/_action.php b/_action.php deleted file mode 100644 index 985a172..0000000 --- a/_action.php +++ /dev/null @@ -1,174 +0,0 @@ - - */ -// must be run within Dokuwiki -if (!defined('DOKU_INC')) die(); - -/** - * Action part of the move plugin - */ -class action_plugin_move extends DokuWiki_Action_Plugin { - /** - * Register event handlers. - * - * @param Doku_Event_Handler $controller The plugin controller - */ - public function register(Doku_Event_Handler $controller) { - $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_read', array()); - $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache', array()); - $controller->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, 'handle_index_version'); - $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'index_media_use'); - $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call'); - } - - - - /** - * Add the move version to theindex version - * - * @param Doku_Event $event The event object - * @param array $param Optional parameters (unused) - */ - public function handle_index_version(Doku_Event $event, $param) { - // From indexer version 6 on the media references are indexed by DokuWiki itself - if ($event->data['dokuwiki'] < 6) - $event->data['plugin_move'] = 0.2; - } - - /** - * Index media usage data - * - * @param Doku_Event $event The event object - * @param array $param Optional parameters (unused) - */ - public function index_media_use(Doku_Event $event, $param) { - // From indexer version 6 on the media references are indexed by DokuWiki itself - if (INDEXER_VERSION >= 6) return; - $id = $event->data['page']; - $media_references = array(); - $instructions = p_cached_instructions(wikiFn($id), false, $id); - if (is_array($instructions)) { - $this->get_media_references_from_instructions($instructions, $media_references, $id); - } - $media_references = array_unique($media_references); - $event->data['metadata']['relation_media'] = $media_references; - } - - /** - * Helper function for getting all media references from an instruction array - * - * @param array $instructions The instructions to scan - * @param array $media_references The array of media references - * @param string $id The reference id for resolving media ids - */ - private function get_media_references_from_instructions($instructions, &$media_references, $id) { - foreach ($instructions as $ins) { - if ($ins[0] === 'internalmedia') { - $src = $ins[1][0]; - list($src,$hash) = explode('#',$src,2); - resolve_mediaid(getNS($id),$src, $exists); - $media_references[] = $src; - } elseif (in_array($ins[0], array('interwikilink', 'windowssharelink', 'externallink', 'emaillink', 'locallink', 'internallink'))) { - $img = $ins[1][1]; - if (is_array($img) && $img['type'] === 'internalmedia') { - list($src,$hash) = explode('#',$img['src'],2); - resolve_mediaid(getNS($id), $src, $exists); - $media_references[] = $src; - } - } elseif ($ins[0] === 'nest') { - // nested instructions - $this->get_media_references_from_instructions($ins[1][0], $media_references, $id); - } elseif ($ins[0] === 'plugin' && $ins[1][0] === 'variants_variants') { - // the variants plugin has two branches with nested instructions, both need to be rewritten - $this->get_media_references_from_instructions($ins[1][1][1], $media_references, $id); - $this->get_media_references_from_instructions($ins[1][1][2], $media_references, $id); - } - } - } - - /** - * Handle the AJAX calls for our plugin - * - * @param Doku_Event $event The event that is handled - * @param array $params Optional parameters (unused) - */ - public function handle_ajax_call(Doku_Event $event, $params) { - if ($event->data == 'plugin_move_ns_continue') { - $event->preventDefault(); - $event->stopPropagation(); - $this->ajax_continue(); - } elseif($event->data == 'plugin_move_tree') { - $event->preventDefault(); - $event->stopPropagation(); - $this->ajax_tree(); - } - } - - /** - * Run the next step during a namespace move - */ - protected function ajax_continue() { - /** @var helper_plugin_move_general $helper */ - $helper = $this->loadHelper('move_general', false); - $opts = $helper->get_namespace_move_opts(); - $id = cleanID((string)$_POST['id']); - $skip = (string)$_POST['skip']; - if ($opts !== false) { - if ($skip == 'true') { - $helper->skip_namespace_move_item(); - } - $remaining = $helper->continue_namespace_move(); - $newid = $helper->getNewID($id, $opts['ns'], $opts['newns']); - - $result = array(); - $result['remaining'] = $remaining; - $result['pages'] = $opts['num_pages']; - $result['media'] = $opts['num_media']; - $result['redirect_url'] = wl($newid, '', true); - ob_start(); - html_msgarea(); - if ($remaining === false) { - ptln('

    '.sprintf($this->getLang('ns_move_error'), $opts['ns'], $opts['newns']).'

    '); - echo $helper->getNSMoveButton('tryagain', $id); - echo $helper->getNSMoveButton('skip', $id); - echo $helper->getNSMoveButton('abort', $id); - } else { - ptln('

    '.sprintf($this->getLang('ns_move_continued'), $opts['ns'], $opts['newns'], $remaining).'

    '); - } - $result['html'] = ob_get_clean(); - } else { - $result = array(); - $result['remaining'] = 0; - $result['pages'] = 0; - $result['media'] = 0; - $result['redirect_url'] = wl('', '', true); - $result['html'] = ''; - } - $json = new JSON(); - echo $json->encode($result); - } - - protected function ajax_tree() { - - //FIXME user auth - - global $INPUT; - $ns = cleanID($INPUT->str('ns')); - - /** @var admin_plugin_move_tree $plugin */ - $plugin = plugin_load('admin', 'move_tree'); - - $data = $plugin->tree($ns, $ns); - - echo html_buildlist( - $data, 'plugin_move_tree', - array($plugin, 'html_list'), - array($plugin, 'html_li') - ); - } - -} \ No newline at end of file diff --git a/action/progress.php b/action/progress.php new file mode 100644 index 0000000..274ee3f --- /dev/null +++ b/action/progress.php @@ -0,0 +1,60 @@ + + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class action_plugin_move_rename + */ +class action_plugin_move_progress extends DokuWiki_Action_Plugin { + + /** + * Register event handlers. + * + * @param Doku_Event_Handler $controller The plugin controller + */ + public function register(Doku_Event_Handler $controller) { + $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); + } + + /** + * Step up + * + * @param Doku_Event $event + */ + public function handle_ajax(Doku_Event $event) { + if($event->data != 'plugin_move_progress') return; + $event->preventDefault(); + $event->stopPropagation(); + + global $INPUT; + + $return = array( + 'error' => '', + 'complete' => false, + 'progress' => 0 + ); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + if(!$plan->isCommited()) { + // There is no plan. Something went wrong + $return['complete'] = true; + } else { + $todo = $plan->nextStep($INPUT->bool('skip')); + $return['progress'] = $plan->getProgress(); + $return['error'] = $plan->getLastError(); + if($todo === 0) $return['complete'] = true; + } + + $json = new JSON(); + header('Content-Type: application/json'); + echo $json->encode($return); + } +} \ No newline at end of file diff --git a/admin/main.php b/admin/main.php index 223cfee..bea5c2f 100644 --- a/admin/main.php +++ b/admin/main.php @@ -131,9 +131,9 @@ protected function GUI_simpleForm() { $form->startFieldset($this->getLang('legend')); $form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage') . ' '.$ID.'', '', 'block radio click-page', array('checked' => 'checked'))); - $form->addElement(form_makeRadioField('class', 'namepsace', $this->getLang('movens') . ' '.getNS($ID).'', '', 'block radio click-ns')); - $form->addElement(form_makeTextField('dst', $ID, $this->getLang('dst'), '', 'block indent')); + $form->addElement(form_makeRadioField('class', 'namespace', $this->getLang('movens') . ' '.getNS($ID).'', '', 'block radio click-ns')); + $form->addElement(form_makeTextField('dst', $ID, $this->getLang('dst'), '', 'block indent')); $form->addElement(form_makeMenuField('type', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), 'both', $this->getLang('content_to_move'), '', 'block indent select')); $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', 'block', ($this->getConf('autoskip') ? array('checked' => 'checked') : array()))); @@ -144,18 +144,25 @@ protected function GUI_simpleForm() { $form->printForm(); } - protected function GUI_previewPlan() { - $this->createPlanFromInput(); - - } - /** * Display the GUI while the move progresses */ protected function GUI_progress() { + echo '
    '; + $progress = $this->plan->getProgress(); - // FIXME add intro here depending on start or progress + if(!$this->plan->inProgress()) { + echo 'Execut plan'; + + echo '
    '; + echo ''.$this->getLang('preview').''; + echo $this->plan->previewHTML(); + echo '
    '; + + } else { + echo "continue plan"; + } echo '
    ' . $progress . '%
    '; @@ -166,18 +173,16 @@ protected function GUI_progress() { } echo '
    '; - + // display all buttons but toggle visibility according to state echo '
    '; - if(!$this->plan->inProgress()) { - $this->btn('start'); - } else if($this->plan->getLastError()) { - $this->btn('skip'); - $this->btn('retry'); - } else { - $this->btn('continue'); - } + $this->btn('start', !$this->plan->inProgress()); + $this->btn('retry', $this->plan->getLastError()); + $this->btn('skip', $this->plan->getLastError()); + $this->btn('continue', $this->plan->inProgress() && !$this->plan->getLastError()); $this->btn('abort'); echo '
    '; + + echo '
    '; } /** @@ -188,19 +193,29 @@ protected function GUI_progress() { * skip - skip error and continue * * @param string $control + * @param bool $show should this control be visible? */ - protected function btn($control) { + protected function btn($control, $show=true) { global $ID; + $skip = 0; $label = $this->getLang('btn_' . $control); + $id = $control; if($control == 'start') $control = 'continue'; - if($control == 'retry') $control = 'continue'; + if($control == 'retry'){ + $control = 'continue'; + $skip = 1; + } + + $class = 'move__control ctlfrm-'.$id; + if(!$show) $class .= ' hide'; - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__control')); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => $class)); $form->addHidden('page', 'move_main'); $form->addHidden('id', $ID); $form->addHidden('ctl', $control); - $form->addElement(form_makeButton('submit', 'admin', $label)); + $form->addHidden('skip', $skip); + $form->addElement(form_makeButton('submit', 'admin', $label, array('class' => 'btn ctl-'.$control))); $form->printForm(); } } \ No newline at end of file diff --git a/helper/plan.php b/helper/plan.php index 843ea34..fd6cee3 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -95,7 +95,7 @@ protected function loadOptions() { // merge whatever options are saved currently $file = $this->files['opts']; if(file_exists($file)) { - $options = unserialize(io_readFile($file, false)); + $options = unserialize(io_readFile($file, false)); $this->options = array_merge($this->options, $options); } } @@ -152,7 +152,7 @@ public function getProgress() { $this->options['affpg_run']; if($max == 0) return 0; - return round((($max-$remain) * 100) / $max, 2); + return round((($max - $remain) * 100) / $max, 2); } /** @@ -218,8 +218,8 @@ public function addMediaNamespaceMove($src, $dst) { * * @param string $src ID of the item to move * @param string $dst new ID of item namespace - * @param int $class (PLUGIN_MOVE_CLASS_NS|PLUGIN_MOVE_CLASS_DOC) - * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) + * @param int $class (PLUGIN_MOVE_CLASS_NS|PLUGIN_MOVE_CLASS_DOC) + * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) * @throws Exception */ protected function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGIN_MOVE_TYPE_PAGES) { @@ -293,7 +293,7 @@ public function commit() { // now add all the found documents to our lists foreach($docs as $doc) { $from = $doc['id']; - $to = $move['dst'] . substr($doc['id'], $strip); + $to = $move['dst'] . substr($doc['id'], $strip); if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { $this->addToPageList($from, $to); @@ -358,10 +358,48 @@ public function nextStep($skip = false) { return 0; } + /** + * Returns the list of page and media moves as a HTML list + * + * @return string + */ + public function previewHTML() { + $html = ''; + + $html .= '
      '; + if(@file_exists($this->files['pagelist'])) { + $pagelist = file($this->files['pagelist']); + foreach($pagelist as $line) { + list($old, $new) = explode("\t", trim($line)); + + $html .= '
    • '; + $html .= hsc($old); + $html .= '→'; + $html .= hsc($new); + $html .= '
    • '; + } + } + if(@file_exists($this->files['medialist'])) { + $medialist = file($this->files['medialist']); + foreach($medialist as $line) { + list($old, $new) = explode("\t", trim($line)); + + $html .= '
    • '; + $html .= hsc($old); + $html .= '→'; + $html .= hsc($new); + $html .= '
    • '; + } + } + $html .= '
    '; + + return $html; + } + /** * Step through the next bunch of pages or media files * - * @param int $type (PLUGIN_MOVE_TYPE_PAGES|PLUGIN_MOVE_TYPE_MEDIA) + * @param int $type (PLUGIN_MOVE_TYPE_PAGES|PLUGIN_MOVE_TYPE_MEDIA) * @param bool $skip should the first item be skipped? * @return bool|int false on error, otherwise the number of remaining documents */ @@ -370,14 +408,14 @@ protected function stepThroughDocuments($type = PLUGIN_MOVE_TYPE_PAGES, &$skip = $MoveOperator = plugin_load('helper', 'move_op'); if($type == PLUGIN_MOVE_TYPE_PAGES) { - $file = $this->files['pagelist']; - $mark = 'P'; - $call = 'movePage'; + $file = $this->files['pagelist']; + $mark = 'P'; + $call = 'movePage'; $counter = 'pages_num'; } else { - $file = $this->files['medialist']; - $mark = 'M'; - $call = 'moveMedia'; + $file = $this->files['medialist']; + $mark = 'M'; + $call = 'moveMedia'; $counter = 'media_num'; } @@ -501,7 +539,7 @@ protected function storeError() { global $MSG; if(is_array($MSG) && count($MSG)) { - $last = array_shift($MSG); + $last = array_shift($MSG); $this->options['lasterror'] = $last['msg']; unset($GLOBALS['MSG']); } else { @@ -675,7 +713,7 @@ public function planSorter($a, $b) { * @param string $type * @param string $from * @param string $to - * @param bool $success + * @param bool $success * @author Andreas Gohr */ protected function log($type, $from, $to, $success) { @@ -683,15 +721,15 @@ protected function log($type, $from, $to, $success) { global $MSG; $optime = $this->options['started']; - $file = $conf['cachedir'] . '/move-' . $optime . '.log'; - $now = time(); - $date = date('Y-m-d H:i:s', $now); // for human readability + $file = $conf['cachedir'] . '/move-' . $optime . '.log'; + $now = time(); + $date = date('Y-m-d H:i:s', $now); // for human readability if($success) { - $ok = 'success'; + $ok = 'success'; $msg = ''; } else { - $ok = 'failed'; + $ok = 'failed'; $msg = $MSG[count($MSG) - 1]['msg']; // get detail from message array } diff --git a/lang/en/lang.php b/lang/en/lang.php index 30c3e9c..d6500c1 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -82,3 +82,5 @@ $lang['js']['cancel'] = 'Cancel'; $lang['js']['newname'] = 'New name:'; $lang['js']['inprogress'] = 'renaming page and adjusting links...'; + +$lang['js']['complete'] = 'Move operation finished.'; diff --git a/script.js b/script.js index c809b03..98913b5 100644 --- a/script.js +++ b/script.js @@ -7,8 +7,7 @@ /* DOKUWIKI:include_once script/json2.js */ jQuery(function() { /* DOKUWIKI:include script/form.js */ - + /* DOKUWIKI:include script/progress.js */ /* DOKUWIKI:include script/tree.js */ - /* DOKUWIKI:include script/move.js */ /* DOKUWIKI:include script/rename.js */ }); \ No newline at end of file diff --git a/script/move.js b/script/move.js deleted file mode 100644 index a0c4980..0000000 --- a/script/move.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * JavasScript code for the preview in the move plugin - * - * @author Michael Hamann - */ - -jQuery('form.move__form').each(function() { - var $this = jQuery(this); - var $preview = jQuery('

    '); - $this.find('input[type=submit]').before($preview); - var updatePreview = function() { - if ($this.find('input[name=move_type]').val() == 'namespace') { - var targetns = $this.find('select[name=targetns]').val(); - var newnsname = $this.find('input[name=newnsname]').val(); - var previewns; - if (targetns == ':') { - previewns = newnsname; - } else { - previewns = targetns + ':' + newnsname; - } - $preview.text(LANG['plugins']['move']['previewns'].replace('OLDNS', JSINFO['namespace']).replace('NEWNS', previewns)); - } else { - var ns_for_page = $this.find('select[name=ns_for_page]').val(); - var newns = $this.find('input[name=newns]').val(); - var newname = $this.find('input[name=newname]').val(); - var newid = ''; - if (typeof newns == 'undefined') { - return; - } - if (newns.replace(/\s/g) != '') { - newid = newns + ':'; - } else if (ns_for_page != ':') { - newid = ns_for_page + ':'; - } - newid += newname; - $preview.text(LANG['plugins']['move']['previewpage'].replace('OLDPAGE', JSINFO['id']).replace('NEWPAGE', newid)); - - } - }; - updatePreview(); - $this.find('input,select').change(updatePreview); - $this.find('input').keyup(updatePreview); -}); - -jQuery('form.move__nscontinue').each(function() { - var $this = jQuery(this); - var $container = jQuery('div.plugin__move_forms'); - var submit_handler = function() { - $container.empty(); - var $progressbar = jQuery('
    '); - $container.append($progressbar); - $progressbar.progressbar({value: false}); - var $message = jQuery('
    '); - $container.append($message); - var skip = jQuery(this).hasClass('move__nsskip'); - - var continue_move = function() { - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - { - call: 'plugin_move_ns_continue', - id: JSINFO['id'], - skip: skip - }, - function(data) { - if (data.remaining === false) { - $progressbar.progressbar('option', 'value', false); - } else { - $progressbar.progressbar('option', 'value', data.pages + data.media + data.affected - data.remaining); - $progressbar.progressbar('option', 'max', data.pages + data.media + data.affected); - } - $message.html(data.html); - if (data.remaining === false) { - $container.find('form.move__nscontinue, form.move__nsskip').submit(submit_handler); - } else if (data.remaining === 0) { - window.location.href = data.redirect_url; - } else { - window.setTimeout(continue_move, 200); - } - }, - 'json' - ); - skip = false; - }; - - continue_move(); - return false; - }; - $this.submit(submit_handler); -}); - -// hide preview list on namespace move -jQuery('#move__preview_list').each(function(){ - var $this = jQuery(this); - $this.find('ul').hide(); - $this.find('span') - .click(function(){ - console.log('woah'); - $this.find('ul').dw_toggle(); - $this.find('span').toggleClass('closed'); - }) - .addClass('closed'); -}); diff --git a/script/progress.js b/script/progress.js new file mode 100644 index 0000000..1cab422 --- /dev/null +++ b/script/progress.js @@ -0,0 +1,94 @@ +jQuery('#plugin_move__progress').each(function () { + var $this = jQuery(this); + + // initialize the progress bar + var $progressbar = $this.find('.progress'); + $progressbar.html(''); + $progressbar.progressbar({ + value: $progressbar.attr('data-progress') + }); + + /** + * Set visibility of buttons according to current error state + * + * @param isError + */ + var setButtons = function(isError) { + $this.find('.ctlfrm-start').addClass('hide'); + + if(isError) { + $this.find('.ctlfrm-skip').removeClass('hide'); + $this.find('.ctlfrm-retry').removeClass('hide'); + $this.find('.ctlfrm-continue').addClass('hide'); + }else { + $this.find('.ctlfrm-skip').addClass('hide'); + $this.find('.ctlfrm-retry').addClass('hide'); + $this.find('.ctlfrm-continue').addClass('hide'); + } + }; + + /** + * Execute the next steps + * + * @param {bool} skip should an error be skipped? + */ + var nextStep = function(skip) { + // clear error output + $this.find('.output').html(''); + + // execute AJAX + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_progress', + skip: skip + }, + function (data) { + $progressbar.progressbar('option', 'value', data.progress); + + if (data.error) { + $this.find('.output').html('
    ' + data.error + '
    '); + setButtons(true); + } else if (data.complete) { + // redirect to start page + alert(LANG.plugins.move.complete); + window.location.href = DOKU_BASE; + } else { + // do it again + setButtons(false); + nextStep(skip); + } + } + ); + }; + + + + // attach AJAX actions to buttons + $this.find('.ctl-continue').click(function (e) { + e.preventDefault(); + + // move in progress, no more preview + jQuery('#plugin_move__preview').remove(); + + // should the next error be skipped? + var skip = e.target.form.skip.value; + + // step on it + nextStep(skip); + }); + +}); + + +// hide preview list on namespace move +jQuery('#plugin_move__preview').each(function () { + var $this = jQuery(this); + $this.find('ul').hide(); + $this.find('span') + .click(function () { + $this.find('ul').dw_toggle(); + $this.find('span').toggleClass('closed'); + }) + .addClass('closed'); +}); diff --git a/style.less b/style.less index bf4c033..6249231 100644 --- a/style.less +++ b/style.less @@ -1,9 +1,3 @@ -#move__preview_list { - span { - cursor: pointer; - color: @ini_link; - } -} .plugin_move_page { display: none; // will be shown by JavaScript @@ -16,7 +10,27 @@ ul.plugin_move_tree { } } +/** + * The progress page + */ +#plugin_move__progress { + + .hide { + display: none; + } + + #plugin_move__preview { + span { + cursor: pointer; + color: @ini_link; + } + } +} + +/** + * The admin form + */ .dokuwiki .plugin_move_form { label.block { text-align: left; From 84b144ebbe9ec3fef24d64aa5c7dbb51045dda8d Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 14 Apr 2014 14:24:58 +0200 Subject: [PATCH 092/338] some cosmetic updates and a throbber --- admin/main.php | 14 +++++++++++--- lang/en/lang.php | 3 ++- lang/en/progress.txt | 3 +++ script/progress.js | 8 ++++++-- 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 lang/en/progress.txt diff --git a/admin/main.php b/admin/main.php index bea5c2f..9b8446f 100644 --- a/admin/main.php +++ b/admin/main.php @@ -124,6 +124,9 @@ protected function createPlanFromInput() { */ protected function GUI_simpleForm() { global $ID; + + echo $this->locale_xhtml('move'); + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'plugin_move_form')); $form->addHidden('page', 'move_main'); $form->addHidden('id', $ID); @@ -150,13 +153,16 @@ protected function GUI_simpleForm() { protected function GUI_progress() { echo '
    '; + echo $this->locale_xhtml('progress'); + $progress = $this->plan->getProgress(); if(!$this->plan->inProgress()) { - echo 'Execut plan'; - echo '
    '; + echo '

    '; + echo ''.$this->getLang('intro').' '; echo ''.$this->getLang('preview').''; + echo '

    '; echo $this->plan->previewHTML(); echo '
    '; @@ -169,12 +175,14 @@ protected function GUI_progress() { echo '
    '; if($this->plan->getLastError()) { - echo '
    ' . $this->plan->getLastError() . '
    '; + echo '

    ' . $this->plan->getLastError() . '

    '; } echo '
    '; // display all buttons but toggle visibility according to state + echo '

    '; echo '
    '; + echo ''; $this->btn('start', !$this->plan->inProgress()); $this->btn('retry', $this->plan->getLastError()); $this->btn('skip', $this->plan->getLastError()); diff --git a/lang/en/lang.php b/lang/en/lang.php index d6500c1..57e6661 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -41,7 +41,8 @@ $lang['nodst'] = 'No new name given'; -$lang['preview'] = 'Preview changes to be executed'; +$lang['intro'] = 'The move operation has not been started, yet!'; +$lang['preview'] = 'Preview changes to be executed.'; $lang['ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; $lang['ns_move_continue'] = 'Continue the namespace move'; diff --git a/lang/en/progress.txt b/lang/en/progress.txt new file mode 100644 index 0000000..cd3432d --- /dev/null +++ b/lang/en/progress.txt @@ -0,0 +1,3 @@ +====== Move in Progress... ====== + +Please keep this page open while the move progresses. \ No newline at end of file diff --git a/script/progress.js b/script/progress.js index 1cab422..533085b 100644 --- a/script/progress.js +++ b/script/progress.js @@ -36,6 +36,9 @@ jQuery('#plugin_move__progress').each(function () { // clear error output $this.find('.output').html(''); + $this.find('.controls img').removeClass('hide'); + setButtons(false); + // execute AJAX jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', @@ -45,17 +48,18 @@ jQuery('#plugin_move__progress').each(function () { }, function (data) { $progressbar.progressbar('option', 'value', data.progress); + $this.find('.controls img').addClass('hide'); if (data.error) { - $this.find('.output').html('
    ' + data.error + '
    '); + $this.find('.output').html('

    ' + data.error + '

    '); setButtons(true); } else if (data.complete) { + $progressbar.progressbar('option', 'value', 100); // redirect to start page alert(LANG.plugins.move.complete); window.location.href = DOKU_BASE; } else { // do it again - setButtons(false); nextStep(skip); } } From 169a65226a1e2cf280815e18d1ab4a6d64e46a63 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 14 Apr 2014 14:37:12 +0200 Subject: [PATCH 093/338] fixed the quick rename function --- action/rename.php | 4 ++-- lang/en/lang.php | 1 + script/rename.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/action/rename.php b/action/rename.php index 40c8655..0d3c7a0 100644 --- a/action/rename.php +++ b/action/rename.php @@ -77,14 +77,14 @@ public function handle_ajax(Doku_Event $event) { header('Content-Type: application/json'); - if($this->renameOkay($dst) && $MoveOperator->movePage($src, $dst)) { + if($this->renameOkay($src) && $MoveOperator->movePage($src, $dst)) { // all went well, redirect echo $JSON->encode(array('redirect_url' => wl($dst, '', true, '&'))); } else { if(isset($MSG[0])) { $error = $MSG[0]; // first error } else { - $error = 'Page can\'t be moved right now'; // FIXME localize + $error = $this->getLang('cantrename'); } echo $JSON->encode(array('error' => $error)); } diff --git a/lang/en/lang.php b/lang/en/lang.php index 57e6661..7c452ba 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -83,5 +83,6 @@ $lang['js']['cancel'] = 'Cancel'; $lang['js']['newname'] = 'New name:'; $lang['js']['inprogress'] = 'renaming page and adjusting links...'; +$lang['cantrename'] = 'The page can\'t be renamed right now. Please try later.'; $lang['js']['complete'] = 'Move operation finished.'; diff --git a/script/rename.js b/script/rename.js index 7091871..f5708eb 100644 --- a/script/rename.js +++ b/script/rename.js @@ -12,7 +12,7 @@ if(JSINFO.move_renameokay) var renameFN = function () { var self = this; var newid = $dialog.find('input[name=id]').val(); - if (!newid) return; + if (!newid) return false; // remove buttons and show throbber $dialog.html( From 9fd69087b827f0ded14ba13ff50406d3510dc335 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 14 Apr 2014 18:40:49 +0200 Subject: [PATCH 094/338] make defines internal constants instead --- helper/plan.php | 82 ++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index fd6cee3..adc5fb6 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -9,11 +9,6 @@ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); -define('PLUGIN_MOVE_TYPE_PAGES', 1); -define('PLUGIN_MOVE_TYPE_MEDIA', 2); -define('PLUGIN_MOVE_CLASS_NS', 4); -define('PLUGIN_MOVE_CLASS_DOC', 8); - /** * Class helper_plugin_move_plan * @@ -28,6 +23,11 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { /** Number of operations per step */ const OPS_PER_RUN = 10; + const TYPE_PAGES = 1; + const TYPE_MEDIA = 2; + const CLASS_NS = 4; + const CLASS_DOC = 8; + /** * @var array the options for this move plan */ @@ -95,7 +95,7 @@ protected function loadOptions() { // merge whatever options are saved currently $file = $this->files['opts']; if(file_exists($file)) { - $options = unserialize(io_readFile($file, false)); + $options = unserialize(io_readFile($file, false)); $this->options = array_merge($this->options, $options); } } @@ -180,7 +180,7 @@ public function isCommited() { * @param string $dst */ public function addPageMove($src, $dst) { - $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_DOC, PLUGIN_MOVE_TYPE_PAGES); + $this->addMove($src, $dst, self::CLASS_DOC, self::TYPE_PAGES); } /** @@ -190,7 +190,7 @@ public function addPageMove($src, $dst) { * @param string $dst */ public function addMediaMove($src, $dst) { - $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_DOC, PLUGIN_MOVE_TYPE_MEDIA); + $this->addMove($src, $dst, self::CLASS_DOC, self::TYPE_MEDIA); } /** @@ -200,7 +200,7 @@ public function addMediaMove($src, $dst) { * @param string $dst */ public function addPageNamespaceMove($src, $dst) { - $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_NS, PLUGIN_MOVE_TYPE_PAGES); + $this->addMove($src, $dst, self::CLASS_NS, self::TYPE_PAGES); } /** @@ -210,7 +210,7 @@ public function addPageNamespaceMove($src, $dst) { * @param string $dst */ public function addMediaNamespaceMove($src, $dst) { - $this->addMove($src, $dst, PLUGIN_MOVE_CLASS_NS, PLUGIN_MOVE_TYPE_MEDIA); + $this->addMove($src, $dst, self::CLASS_NS, self::TYPE_MEDIA); } /** @@ -218,11 +218,11 @@ public function addMediaNamespaceMove($src, $dst) { * * @param string $src ID of the item to move * @param string $dst new ID of item namespace - * @param int $class (PLUGIN_MOVE_CLASS_NS|PLUGIN_MOVE_CLASS_DOC) - * @param int $type (PLUGIN_MOVE_TYPE_PAGE|PLUGIN_MOVE_TYPE_MEDIA) + * @param int $class (self::CLASS_NS|self::CLASS_DOC) + * @param int $type (PLUGIN_MOVE_TYPE_PAGE|self::TYPE_MEDIA) * @throws Exception */ - protected function addMove($src, $dst, $class = PLUGIN_MOVE_CLASS_NS, $type = PLUGIN_MOVE_TYPE_PAGES) { + protected function addMove($src, $dst, $class = self::CLASS_NS, $type = self::TYPE_PAGES) { if($this->options['commited']) throw new Exception('plan is commited already, can not be added to'); $src = cleanID($src); @@ -264,9 +264,9 @@ public function commit() { // get all the documents to be moved and store them in their lists foreach($this->plan as $move) { - if($move['class'] == PLUGIN_MOVE_CLASS_DOC) { + if($move['class'] == self::CLASS_DOC) { // these can just be added - if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + if($move['type'] == self::TYPE_PAGES) { $this->addToPageList($move['src'], $move['dst']); } else { $this->addToMediaList($move['src'], $move['dst']); @@ -276,7 +276,7 @@ public function commit() { $docs = array(); $path = utf8_encodeFN(str_replace(':', '/', $move['src'])); $opts = array('depth' => 0, 'skipacl' => true); - if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + if($move['type'] == self::TYPE_PAGES) { search($docs, $conf['datadir'], 'search_allpages', $opts, $path); } else { search($docs, $conf['mediadir'], 'search_media', $opts, $path); @@ -293,9 +293,9 @@ public function commit() { // now add all the found documents to our lists foreach($docs as $doc) { $from = $doc['id']; - $to = $move['dst'] . substr($doc['id'], $strip); + $to = $move['dst'] . substr($doc['id'], $strip); - if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + if($move['type'] == self::TYPE_PAGES) { $this->addToPageList($from, $to); } else { $this->addToMediaList($from, $to); @@ -303,7 +303,7 @@ public function commit() { } // remember the namespace move itself - if($move['type'] == PLUGIN_MOVE_TYPE_PAGES) { + if($move['type'] == self::TYPE_PAGES) { // FIXME we use this to move namespace subscriptions later on and for now only do it on // page namespace moves, but subscriptions work for both, but what when only one of // them is moved? Should it be copied then? Complicated. This is good enough for now @@ -330,13 +330,13 @@ public function nextStep($skip = false) { if(!$this->options['started']) $this->options['started'] = time(); if(@filesize($this->files['pagelist']) > 1) { - $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_PAGES, $skip); + $todo = $this->stepThroughDocuments(self::TYPE_PAGES, $skip); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['medialist']) > 1) { - $todo = $this->stepThroughDocuments(PLUGIN_MOVE_TYPE_MEDIA, $skip); + $todo = $this->stepThroughDocuments(self::TYPE_MEDIA, $skip); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } @@ -399,23 +399,23 @@ public function previewHTML() { /** * Step through the next bunch of pages or media files * - * @param int $type (PLUGIN_MOVE_TYPE_PAGES|PLUGIN_MOVE_TYPE_MEDIA) + * @param int $type (self::TYPE_PAGES|self::TYPE_MEDIA) * @param bool $skip should the first item be skipped? * @return bool|int false on error, otherwise the number of remaining documents */ - protected function stepThroughDocuments($type = PLUGIN_MOVE_TYPE_PAGES, &$skip = false) { + protected function stepThroughDocuments($type = self::TYPE_PAGES, &$skip = false) { /** @var helper_plugin_move_op $MoveOperator */ $MoveOperator = plugin_load('helper', 'move_op'); - if($type == PLUGIN_MOVE_TYPE_PAGES) { - $file = $this->files['pagelist']; - $mark = 'P'; - $call = 'movePage'; + if($type == self::TYPE_PAGES) { + $file = $this->files['pagelist']; + $mark = 'P'; + $call = 'movePage'; $counter = 'pages_num'; } else { - $file = $this->files['medialist']; - $mark = 'M'; - $call = 'moveMedia'; + $file = $this->files['medialist']; + $mark = 'M'; + $call = 'moveMedia'; $counter = 'media_num'; } @@ -539,7 +539,7 @@ protected function storeError() { global $MSG; if(is_array($MSG) && count($MSG)) { - $last = array_shift($MSG); + $last = array_shift($MSG); $this->options['lasterror'] = $last['msg']; unset($GLOBALS['MSG']); } else { @@ -678,18 +678,18 @@ protected function getLastLine($handle) { */ public function planSorter($a, $b) { // do page moves before namespace moves - if($a['class'] == PLUGIN_MOVE_CLASS_DOC && $b['class'] == PLUGIN_MOVE_CLASS_NS) { + if($a['class'] == self::CLASS_DOC && $b['class'] == self::CLASS_NS) { return 1; } - if($a['class'] == PLUGIN_MOVE_CLASS_NS && $b['class'] == PLUGIN_MOVE_CLASS_DOC) { + if($a['class'] == self::CLASS_NS && $b['class'] == self::CLASS_DOC) { return -1; } // do pages before media - if($a['type'] == PLUGIN_MOVE_TYPE_PAGES && $b['type'] == PLUGIN_MOVE_TYPE_MEDIA) { + if($a['type'] == self::TYPE_PAGES && $b['type'] == self::TYPE_MEDIA) { return 1; } - if($a['type'] == PLUGIN_MOVE_TYPE_MEDIA && $b['type'] == PLUGIN_MOVE_TYPE_PAGES) { + if($a['type'] == self::TYPE_MEDIA && $b['type'] == self::TYPE_PAGES) { return -1; } @@ -713,7 +713,7 @@ public function planSorter($a, $b) { * @param string $type * @param string $from * @param string $to - * @param bool $success + * @param bool $success * @author Andreas Gohr */ protected function log($type, $from, $to, $success) { @@ -721,15 +721,15 @@ protected function log($type, $from, $to, $success) { global $MSG; $optime = $this->options['started']; - $file = $conf['cachedir'] . '/move-' . $optime . '.log'; - $now = time(); - $date = date('Y-m-d H:i:s', $now); // for human readability + $file = $conf['cachedir'] . '/move-' . $optime . '.log'; + $now = time(); + $date = date('Y-m-d H:i:s', $now); // for human readability if($success) { - $ok = 'success'; + $ok = 'success'; $msg = ''; } else { - $ok = 'failed'; + $ok = 'failed'; $msg = $MSG[count($MSG) - 1]['msg']; // get detail from message array } From 2fef744272ef4b3967030f5c43282ad82646510c Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 14 Apr 2014 20:19:43 +0200 Subject: [PATCH 095/338] continued working on the tree interface --- action/tree.php | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ admin/tree.php | 60 ++++++++++++++++++++++++++++++++++++------------- script/tree.js | 7 ++++-- style.less | 29 ++++++++++++++++++------ 4 files changed, 130 insertions(+), 25 deletions(-) create mode 100644 action/tree.php diff --git a/action/tree.php b/action/tree.php new file mode 100644 index 0000000..f3ce0ab --- /dev/null +++ b/action/tree.php @@ -0,0 +1,59 @@ + + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class action_plugin_move_rewrite + */ +class action_plugin_move_tree extends DokuWiki_Action_Plugin { + + /** + * Register event handlers. + * + * @param Doku_Event_Handler $controller The plugin controller + */ + public function register(Doku_Event_Handler $controller) { + $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call'); + } + + /** + * Render a subtree + * + * @param Doku_Event $event + * @param $params + */ + public function handle_ajax_call(Doku_Event $event, $params) { + if($event->data != 'plugin_move_tree') return; + $event->preventDefault(); + $event->stopPropagation(); + + //FIXME user auth + + global $INPUT; + + /** @var admin_plugin_move_tree $plugin */ + $plugin = plugin_load('admin', 'move_tree'); + + $ns = cleanID($INPUT->str('ns')); + if($INPUT->bool('is_media')){ + $type = admin_plugin_move_tree::TYPE_MEDIA; + } else { + $type = admin_plugin_move_tree::TYPE_PAGES; + } + + $data = $plugin->tree($type, $ns, $ns); + + echo html_buildlist( + $data, 'tree_list', + array($plugin, 'html_list'), + array($plugin, 'html_li') + ); + } + +} \ No newline at end of file diff --git a/admin/tree.php b/admin/tree.php index 72e7f42..53d4274 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -2,6 +2,9 @@ class admin_plugin_move_tree extends DokuWiki_Admin_Plugin { + const TYPE_PAGES = 1; + const TYPE_MEDIA = 2; + public function getMenuText($language) { return $this->getLang('treemanager'); } @@ -11,44 +14,69 @@ public function handle() { } public function html() { + echo '
    '; + + echo '
    '; + echo '

    Pages

    '; // FIXME localize + $this->htmlTree(self::TYPE_PAGES); + echo '
    '; - $data = $this->tree(); + echo '
    '; + echo '

    Media

    '; // FIXME localize + $this->htmlTree(self::TYPE_MEDIA); + echo '
    '; + + echo '
    '; + echo ''; + echo '
    '; + + echo '
    '; + } + + /** + * print the HTML tree structure + * + * @param int $type + */ + protected function htmlTree($type = self::TYPE_PAGES) { + $data = $this->tree($type); // wrap a list with the root level around the other namespaces array_unshift( $data, array( - 'level' => 0, 'id' => '*', 'type' => 'd', - 'open' => 'true', 'label' => $this->getLang('root') - ) + 'level' => 0, 'id' => '*', 'type' => 'd', + 'open' => 'true', 'label' => $this->getLang('root') + ) ); - echo html_buildlist( - $data, 'plugin_move_tree', + $data, 'tree_list', array($this, 'html_list'), array($this, 'html_li') ); - - - echo ''; } /** - * Build a tree info structure from media and page directories - * - * We reuse some code from the ACL plugin here + * Build a tree info structure from media or page directories * + * @param int $type * @param string $open The hierarchy to open * @param string $base The namespace to start from * @return array */ - function tree($open = '', $base = '') { + public function tree($type = self::TYPE_PAGES, $open = '', $base = '') { + global $conf; + $opendir = utf8_encodeFN(str_replace(':', '/', $open)); $basedir = utf8_encodeFN(str_replace(':', '/', $base)); - /** @var admin_plugin_acl $aclplugin */ - $aclplugin = plugin_load('admin', 'acl'); + $data = array(); + if($type == self::TYPE_PAGES) { + search($data, $conf['datadir'], 'search_index', array('ns' => $opendir), $basedir); + } elseif($type == self::TYPE_MEDIA) { + search($data, $conf['mediadir'], 'search_index', array('ns' => $opendir), $basedir); + } - return $aclplugin->_get_tree($opendir, $basedir); + return $data; } /** diff --git a/script/tree.js b/script/tree.js index ede9aa8..b3527c5 100644 --- a/script/tree.js +++ b/script/tree.js @@ -3,7 +3,7 @@ */ -jQuery('ul.plugin_move_tree') +jQuery('#plugin_move__tree').find('ul.tree_list') // make folders open and close via AJAX .click(function (e) { var $link = jQuery(e.target); @@ -20,11 +20,14 @@ jQuery('ul.plugin_move_tree') $li .removeClass('closed') .addClass('open'); + + var is_media = $li.closest('div.tree_root').hasClass('tree_media') ? 1 : 0; jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_move_tree', - ns: $link.attr('href') + ns: $link.attr('href'), + is_media: is_media }, function (data) { $li.append(data); diff --git a/style.less b/style.less index 6249231..8a077cf 100644 --- a/style.less +++ b/style.less @@ -1,13 +1,21 @@ +#plugin_move__tree { -.plugin_move_page { - display: none; // will be shown by JavaScript -} + .tree_pages, + .tree_media { + width: 49%; + float: left; + } + .controls { + clear: left; + } -ul.plugin_move_tree { - .moved { - background-color: #b1b100; + ul { + .moved { + background-color: #b1b100; + } } + } /** @@ -66,4 +74,11 @@ ul.plugin_move_tree { #dokuwiki__pagetools ul li.plugin_move_page a:active, #dokuwiki__pagetools ul li.plugin_move_page a:focus { background-position: right -45px; -} \ No newline at end of file +} + +/** + * page rename link + */ +.plugin_move_page { + display: none; // will be shown by JavaScript +} From 007773d4704d98584690e525bc604d74dc093301 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 15 Apr 2014 12:04:51 +0200 Subject: [PATCH 096/338] tree interface basically works --- admin/main.php | 54 ++++++--- admin/simple.php | 295 ----------------------------------------------- admin/tree.php | 57 ++++++--- helper/plan.php | 11 +- lang/en/lang.php | 110 +++++++++--------- lang/en/tree.txt | 3 + script/tree.js | 67 +++++++---- style.less | 25 +++- 8 files changed, 215 insertions(+), 407 deletions(-) delete mode 100644 admin/simple.php create mode 100644 lang/en/tree.txt diff --git a/admin/main.php b/admin/main.php index 9b8446f..1b516f6 100644 --- a/admin/main.php +++ b/admin/main.php @@ -33,12 +33,16 @@ function getMenuSort() { /** * If this admin plugin is for admins only + * * @return bool false */ function forAdminOnly() { return false; } + /** + * Handle the input + */ function handle() { global $INPUT; @@ -61,6 +65,9 @@ function handle() { } } + /** + * Display the interface + */ function html() { // decide what to do based on the plan's state if($this->plan->isCommited()) { @@ -72,7 +79,7 @@ function html() { } /** - * Create a plan from input + * Get input variables and create a move plan from them * * @return bool */ @@ -111,7 +118,25 @@ protected function createPlanFromInput() { return true; } elseif($INPUT->has('json')) { // input came via JSON from tree manager - // FIXME + $json = new JSON(JSON_LOOSE_TYPE); + $data = $json->decode($INPUT->str('json')); + + foreach((array) $data as $entry) { + if($entry['class'] == 'ns') { + if($entry['type'] == 'page') { + $this->plan->addPageNamespaceMove($entry['src'], $entry['dst']); + } elseif($entry['type'] == 'media') { + $this->plan->addMediaNamespaceMove($entry['src'], $entry['dst']); + } + } elseif($entry['class'] == 'doc') { + if($entry['type'] == 'page') { + $this->plan->addPageMove($entry['src'], $entry['dst']); + } elseif($entry['type'] == 'media') { + $this->plan->addMediaMove($entry['src'], $entry['dst']); + } + } + } + $this->plan->commit(); return true; } @@ -133,8 +158,8 @@ protected function GUI_simpleForm() { $form->startFieldset($this->getLang('legend')); - $form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage') . ' '.$ID.'', '', 'block radio click-page', array('checked' => 'checked'))); - $form->addElement(form_makeRadioField('class', 'namespace', $this->getLang('movens') . ' '.getNS($ID).'', '', 'block radio click-ns')); + $form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage') . ' ' . $ID . '', '', 'block radio click-page', array('checked' => 'checked'))); + $form->addElement(form_makeRadioField('class', 'namespace', $this->getLang('movens') . ' ' . getNS($ID) . '', '', 'block radio click-ns')); $form->addElement(form_makeTextField('dst', $ID, $this->getLang('dst'), '', 'block indent')); $form->addElement(form_makeMenuField('type', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), 'both', $this->getLang('content_to_move'), '', 'block indent select')); @@ -160,8 +185,8 @@ protected function GUI_progress() { if(!$this->plan->inProgress()) { echo '
    '; echo '

    '; - echo ''.$this->getLang('intro').' '; - echo ''.$this->getLang('preview').''; + echo '' . $this->getLang('intro') . ' '; + echo '' . $this->getLang('preview') . ''; echo '

    '; echo $this->plan->previewHTML(); echo '
    '; @@ -172,7 +197,6 @@ protected function GUI_progress() { echo '
    ' . $progress . '%
    '; - echo '
    '; if($this->plan->getLastError()) { echo '

    ' . $this->plan->getLastError() . '

    '; @@ -182,7 +206,7 @@ protected function GUI_progress() { // display all buttons but toggle visibility according to state echo '

    '; echo '
    '; - echo ''; + echo ''; $this->btn('start', !$this->plan->inProgress()); $this->btn('retry', $this->plan->getLastError()); $this->btn('skip', $this->plan->getLastError()); @@ -201,21 +225,21 @@ protected function GUI_progress() { * skip - skip error and continue * * @param string $control - * @param bool $show should this control be visible? + * @param bool $show should this control be visible? */ - protected function btn($control, $show=true) { + protected function btn($control, $show = true) { global $ID; - $skip = 0; + $skip = 0; $label = $this->getLang('btn_' . $control); $id = $control; if($control == 'start') $control = 'continue'; - if($control == 'retry'){ + if($control == 'retry') { $control = 'continue'; - $skip = 1; + $skip = 1; } - $class = 'move__control ctlfrm-'.$id; + $class = 'move__control ctlfrm-' . $id; if(!$show) $class .= ' hide'; $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => $class)); @@ -223,7 +247,7 @@ protected function btn($control, $show=true) { $form->addHidden('id', $ID); $form->addHidden('ctl', $control); $form->addHidden('skip', $skip); - $form->addElement(form_makeButton('submit', 'admin', $label, array('class' => 'btn ctl-'.$control))); + $form->addElement(form_makeButton('submit', 'admin', $label, array('class' => 'btn ctl-' . $control))); $form->printForm(); } } \ No newline at end of file diff --git a/admin/simple.php b/admin/simple.php deleted file mode 100644 index 87bb566..0000000 --- a/admin/simple.php +++ /dev/null @@ -1,295 +0,0 @@ - - * @author Gary Owen, - */ - -// must be run within Dokuwiki -if (!defined('DOKU_INC')) die(); - -/** - * Admin component of the move plugin. Provides the user interface. - */ -class admin_plugin_move_simple extends DokuWiki_Admin_Plugin { - - /** @var string $ns_move_state The state of the current namespace move (none, started, continued, error) */ - protected $ns_move_state = 'none'; - - /** - * Get the sort number that defines the position in the admin menu. - * - * @return int The sort number - */ - function getMenuSort() { return 1000; } - - /** - * If this admin plugin is for admins only - * @return bool false - */ - function forAdminOnly() { return false; } - - /** - * return some info - */ - function getInfo(){ - $result = parent::getInfo(); - $result['desc'] = $this->getLang('desc'); - return $result; - } - - /** - * Only show the menu text for pages we can move or rename. - */ - function getMenuText() { - global $INFO; - - if( !$INFO['exists'] ) - return $this->getLang('menu').' ('.sprintf($this->getLang('notexist'), $INFO['id']).')'; - elseif( !$INFO['writable'] ) - return $this->getLang('menu').' ('.$this->getLang('notwrite').')'; - else - return $this->getLang('menu'); - } - - - - /** - * output appropriate html - * - * @author Michael Hamann - * @author Gary Owen - */ - function html() { - /** @var helper_plugin_move_plan $plan */ - $plan = plugin_load('helper', 'move_plan'); - - ptln(''); - ptln( $this->locale_xhtml('move') ); - ptln('
    '); - - if($plan->inProgress()){ - if($plan->getLastError()) { - ptln('

    '); - ptln(sprintf($this->getLang('ns_move_error'), $this->ns_opts['ns'], $this->ns_opts['newns'])); - ptln('

    '); - ptln($this->helper->getNSMoveButton('tryagain')); - ptln($this->helper->getNSMoveButton('skip')); - ptln($this->helper->getNSMoveButton('abort')); - } else { - - } - - } - - switch ($this->ns_move_state) { - case 'started': - ptln('

    '); - ptln(sprintf($this->getLang('ns_move_started'), hsc($this->ns_opts['ns']), hsc($this->ns_opts['newns']), $this->ns_opts['num_pages'], $this->ns_opts['num_media'])); - ptln('

    '); - - ptln('
    '); - ptln(''.$this->getLang('preview').''); - $this->helper->preview_namespace_move($this->ns_opts); - ptln('
    '); - - ptln('

    '); - ptln($this->helper->getNSMoveButton('continue')); - ptln($this->helper->getNSMoveButton('abort')); - ptln('

    '); - break; - case 'error': - - break; - case 'continued': - ptln('

    '); - ptln(sprintf($this->getLang('ns_move_continued'), $this->ns_opts['ns'], $this->ns_opts['newns'], $this->ns_opts['remaining'])); - ptln('

    '); - - ptln($this->helper->getNSMoveButton('continue')); - ptln($this->helper->getNSMoveButton('abort')); - break; - default: - $this->printForm(); - } - ptln('
    '); - ptln(''); - } - - /** - * show the move and/or rename a page form - * - * @author Michael Hamann - * @author Gary Owen - */ - function printForm() { - global $ID; - - $ns = getNS($ID); - - $ns_select_data = $this->build_namespace_select_content($ns); - - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__form')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('move_type', 'page'); - $form->startFieldset($this->getLang('movepage')); - $form->addElement(form_makeMenuField('ns_for_page', $ns_select_data, $this->opts['ns_for_page'], $this->getLang('targetns'), '', 'block')); - $form->addElement(form_makeTextField('newns', $this->opts['newns'], $this->getLang('newtargetns'), '', 'block')); - $form->addElement(form_makeTextField('newname', $this->opts['newname'], $this->getLang('newname'), '', 'block')); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); - $form->endFieldset(); - $form->printForm(); - - if ($this->ns_opts !== false) { - ptln('
    '); - ptln(''); - ptln($this->getLang('movens')); - ptln(''); - ptln('

    '); - ptln(sprintf($this->getLang('ns_move_in_progress'), $this->ns_opts['num_pages'], $this->ns_opts['num_media'], ':'.hsc($this->ns_opts['ns']), ':'.hsc($this->ns_opts['newns']))); - ptln('

    '); - ptln($this->helper->getNSMoveButton('continue')); - ptln($this->helper->getNSMoveButton('abort')); - ptln('
    '); - } else { - $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'move__form')); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $ID); - $form->addHidden('move_type', 'namespace'); - $form->startFieldset($this->getLang('movens')); - $form->addElement(form_makeMenuField('targetns', $ns_select_data, $this->opts['targetns'], $this->getLang('targetns'), '', 'block')); - $form->addElement(form_makeTextField('newnsname', $this->opts['newnsname'], $this->getLang('newnsname'), '', 'block')); - $form->addElement(form_makeMenuField('contenttomove', array('pages' => $this->getLang('move_pages'), 'media' => $this->getLang('move_media'), 'both' => $this->getLang('move_media_and_pages')), $this->opts['contenttomove'], $this->getLang('content_to_move'), '', 'block')); - $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', 'block', ($this->getConf('autoskip') ? array('checked'=>'checked') : array()))); - $form->addElement(form_makeCheckboxField('autorewrite', '1', $this->getLang('autorewrite'), '', 'block', ($this->getConf('autorewrite') ? array('checked'=>'checked') : array()))); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); - $form->endFieldset(); - $form->printForm(); - } - } - - - /** - * create a list of namespaces for the html form - * - * @author Michael Hamann - * @author Gary Owen - * @author Arno Puschmann (bin out of _form) - */ - private function build_namespace_select_content($ns) { - global $conf; - - $result = array(); - - $namesp = array( 0 => array('id' => '') ); //Include root - search($namesp, $conf['datadir'], 'search_namespaces', array()); - sort($namesp); - foreach($namesp as $row) { - if ( auth_quickaclcheck($row['id'].':*') >= AUTH_CREATE || $row['id'] == $ns ) { - - $result[($row['id'] ? $row['id'] : ':')] = ($row['id'] ? $row['id'].':' : ": ".$this->getLang('root')). - ($row['id'] == $ns ? ' '.$this->getLang('current') : ''); - } - } - return $result; - } - - - /** - * handle user request - * - * @author Michael Hamann - * @author Gary Owen - */ - function handle() { - global $ID; - global $ACT; - global $INFO; - - // populate options with default values - $this->opts['ns'] = getNS($ID); - $this->opts['name'] = noNS($ID); - $this->opts['ns_for_page'] = $INFO['namespace']; - $this->opts['newns'] = ''; - $this->opts['newname'] = noNS($ID); - $this->opts['targetns'] = getNS($ID); - $this->opts['newnsname'] = ''; - $this->opts['move_type'] = 'page'; - $this->opts['contenttomove'] = 'pages'; - - $this->helper = $this->loadHelper('move_general', true); - if (!$this->helper) return; - - $this->ns_opts = $this->helper->get_namespace_move_opts(); - - // Only continue when the form was submitted - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - return; - } - - if (isset($_POST['continue_namespace_move']) || isset($_POST['skip_continue_namespace_move'])) { - if (isset($_POST['skip_continue_namespace_move'])) { - $this->helper->skip_namespace_move_item(); - } - $this->ns_opts['remaining'] = $this->helper->continue_namespace_move(); - $this->ns_move_state = ($this->ns_opts['remaining'] === false ? 'error': 'continued'); - if ($this->ns_opts['remaining'] === 0) { - $ID = $this->helper->getNewID($INFO['id'], $this->opts['ns'], $this->opts['newns']); - $ACT = 'show'; - } - - return; - } elseif (isset($_POST['abort_namespace_move'])) { - $this->helper->abort_namespace_move(); - $this->ns_opts = false; - - return; - } - - // Store the form data in the options and clean the submitted data. - if (isset($_POST['ns_for_page'])) $this->opts['ns_for_page'] = cleanID((string)$_POST['ns_for_page']); - if (isset($_POST['newns'])) $this->opts['newns'] = cleanID((string)$_POST['newns']); - if (isset($_POST['newname'])) $this->opts['newname'] = cleanID((string)$_POST['newname']); - if (isset($_POST['targetns'])) $this->opts['targetns'] = cleanID((string)$_POST['targetns']); - if (isset($_POST['newnsname'])) $this->opts['newnsname'] = cleanID((string)$_POST['newnsname']); - if (isset($_POST['move_type'])) $this->opts['move_type'] = (string)$_POST['move_type']; - if (isset($_POST['autoskip'])) $this->opts['autoskip'] = true; - if (isset($_POST['autorewrite'])) $this->opts['autorewrite'] = true; - if (isset($_POST['contenttomove']) && in_array($_POST['contenttomove'], array('pages', 'media', 'both'), true)) $this->opts['contenttomove'] = $_POST['contenttomove']; - - // check the input for completeness - if( $this->opts['move_type'] == 'namespace' ) { - - if ($this->opts['targetns'] == '') { - $this->opts['newns'] = $this->opts['newnsname']; - } else { - $this->opts['newns'] = $this->opts['targetns'].':'.$this->opts['newnsname']; - } - - $started = $this->helper->start_namespace_move($this->opts); - if ($started !== false) { - $this->ns_opts = $this->helper->get_namespace_move_opts(); - $this->ns_move_state = 'started'; - } - } else { - // check that the pagename is valid - if ($this->opts['newname'] == '' ) { - msg($this->getLang('badname'), -1); - return; - } - - if ($this->opts['newns'] === '') { - $this->opts['newns'] = $this->opts['ns_for_page']; - } - - if ($this->helper->move_page($this->opts)) { - // Set things up to display the new page. - $ID = $this->opts['new_id']; - $ACT = 'show'; // this triggers a redirect to the page - } - } - } -} \ No newline at end of file diff --git a/admin/tree.php b/admin/tree.php index 53d4274..06ce473 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -14,20 +14,37 @@ public function handle() { } public function html() { + global $ID; + + echo $this->locale_xhtml('tree'); + + echo ''; + echo '
    '; echo '
    '; - echo '

    Pages

    '; // FIXME localize + echo '

    ' . $this->getLang('pages') . '

    '; $this->htmlTree(self::TYPE_PAGES); echo '
    '; echo '
    '; - echo '

    Media

    '; // FIXME localize + echo '

    ' . $this->getLang('media') . '

    '; $this->htmlTree(self::TYPE_MEDIA); echo '
    '; + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); echo '
    '; - echo ''; + if($plan->isCommited()) { + echo '
    ' . $this->getLang('moveinprogress') . '
    '; + } else { + $form = new Doku_Form(array('action' => wl($ID), 'id' => 'plugin_move__tree_execute')); + $form->addHidden('id', $ID); + $form->addHidden('page', 'move_main'); + $form->addHidden('json', ''); + $form->addElement(form_makeButton('submit', 'admin', $this->getLang('btn_start'))); + $form->printForm(); + } echo '
    '; echo '
    '; @@ -44,12 +61,12 @@ protected function htmlTree($type = self::TYPE_PAGES) { // wrap a list with the root level around the other namespaces array_unshift( $data, array( - 'level' => 0, 'id' => '*', 'type' => 'd', - 'open' => 'true', 'label' => $this->getLang('root') - ) + 'level' => 0, 'id' => '*', 'type' => 'd', + 'open' => 'true', 'label' => $this->getLang('root') + ) ); echo html_buildlist( - $data, 'tree_list', + $data, 'tree_list idx', array($this, 'html_list'), array($this, 'html_li') ); @@ -59,7 +76,7 @@ protected function htmlTree($type = self::TYPE_PAGES) { * Build a tree info structure from media or page directories * * @param int $type - * @param string $open The hierarchy to open + * @param string $open The hierarchy to open FIXME not supported yet * @param string $base The namespace to start from * @return array */ @@ -69,11 +86,20 @@ public function tree($type = self::TYPE_PAGES, $open = '', $base = '') { $opendir = utf8_encodeFN(str_replace(':', '/', $open)); $basedir = utf8_encodeFN(str_replace(':', '/', $base)); + $opts = array( + 'pagesonly' => ($type == self::TYPE_PAGES), + 'listdirs' => true, + 'listfiles' => true, + 'sneakyacl' => $conf['sneaky_index'], + 'showmsg' => false, + 'depth' => 1 + ); + $data = array(); if($type == self::TYPE_PAGES) { - search($data, $conf['datadir'], 'search_index', array('ns' => $opendir), $basedir); + search($data, $conf['datadir'], 'search_universal', $opts, $basedir); } elseif($type == self::TYPE_MEDIA) { - search($data, $conf['mediadir'], 'search_index', array('ns' => $opendir), $basedir); + search($data, $conf['mediadir'], 'search_universal', $opts, $basedir); } return $data; @@ -120,12 +146,13 @@ function html_list($item) { function html_li($item) { if($item['id'] == '*') $item['id'] = ''; - $params = array(); - $params['class'] = ($item['open'] ? 'open' : 'closed') . ' type-' . $item['type']; + $params = array(); + $params['class'] = ' type-' . $item['type']; + if($item['type'] == 'd') $params['class'] .= ' ' . ($item['open'] ? 'open' : 'closed'); $params['data-parent'] = getNS($item['id']); - $params['data-name'] = noNS($item['id']); - $params['data-id'] = $item['id']; - $attr = buildAttributes($params); + $params['data-name'] = noNS($item['id']); + $params['data-id'] = $item['id']; + $attr = buildAttributes($params); return "
  • "; } diff --git a/helper/plan.php b/helper/plan.php index adc5fb6..8d7afdc 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -228,8 +228,6 @@ protected function addMove($src, $dst, $class = self::CLASS_NS, $type = self::TY $src = cleanID($src); $dst = cleanID($dst); - // FIXME make sure source exists - $this->plan[] = array( 'src' => $src, 'dst' => $dst, @@ -254,6 +252,9 @@ public function abort() { * * the plan is reordered an the needed move operations are gathered and stored in the appropriate * list files + * + * @throws Exception if you try to commit a plan twice + * @return bool true if the plan was commited */ public function commit() { global $conf; @@ -312,8 +313,14 @@ public function commit() { } } + if(!$this->options['pages_all'] && !$this->options['media_all']) { + msg($this->getLang('noaction'), -1); + return false; + } + $this->options['commited'] = true; $this->saveOptions(); + return true; } /** diff --git a/lang/en/lang.php b/lang/en/lang.php index 7c452ba..62089e0 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -7,82 +7,84 @@ */ // settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; +$lang['encoding'] = 'utf-8'; +$lang['direction'] = 'ltr'; // for admin plugins, the menu prompt to be displayed in the admin menu // if set here, the plugin doesn't need to override the getMenuText() method $lang['menu'] = 'Page/Namespace Move/Rename...'; $lang['desc'] = 'Page/Namespace Move/Rename Plugin'; - $lang['treemanager'] = 'Page Move Manager'; -$lang['notexist'] = 'The page %s does not exist'; -$lang['medianotexist'] = 'The media file %s does not exist'; -$lang['notwrite'] = 'You do not have sufficient permissions to modify this page'; -$lang['badns'] = 'Invalid characters in namespace.'; -$lang['badname'] = 'Invalid characters in pagename.'; -$lang['nochange'] = 'Page name and namespace are unchanged.'; -$lang['nomediachange'] = 'Media file name and namespace are unchanged.'; -$lang['existing'] = 'A page called %s already exists in %s'; -$lang['mediaexisting'] = 'A media file called %s already exists in %s'; -$lang['root'] = '[Root namespace]'; -$lang['current'] = '(Current)'; -$lang['renamed'] = 'Page name changed from %s to %s'; -$lang['moved'] = 'Page moved from %s to %s'; -$lang['move_rename'] = 'Page moved and renamed from %s to %s'; -$lang['delete'] = 'Deleted by move plugin'; -$lang['norights'] = 'You have insufficient permissions to edit %s.'; -$lang['nomediarights'] = 'You have insufficient permissions to delete %s.'; -$lang['notargetperms'] = 'You don\'t have the permission to create the page %s.'; + + +$lang['notexist'] = 'The page %s does not exist'; +$lang['medianotexist'] = 'The media file %s does not exist'; +$lang['notwrite'] = 'You do not have sufficient permissions to modify this page'; +$lang['badns'] = 'Invalid characters in namespace.'; +$lang['badname'] = 'Invalid characters in pagename.'; +$lang['nochange'] = 'Page name and namespace are unchanged.'; +$lang['nomediachange'] = 'Media file name and namespace are unchanged.'; +$lang['existing'] = 'A page called %s already exists in %s'; +$lang['mediaexisting'] = 'A media file called %s already exists in %s'; +$lang['root'] = '[Root namespace]'; +$lang['current'] = '(Current)'; +$lang['renamed'] = 'Page name changed from %s to %s'; +$lang['moved'] = 'Page moved from %s to %s'; +$lang['move_rename'] = 'Page moved and renamed from %s to %s'; +$lang['delete'] = 'Deleted by move plugin'; +$lang['norights'] = 'You have insufficient permissions to edit %s.'; +$lang['nomediarights'] = 'You have insufficient permissions to delete %s.'; +$lang['notargetperms'] = 'You don\'t have the permission to create the page %s.'; $lang['nomediatargetperms'] = 'You don\'t have the permission to create the media file %s.'; -$lang['filelocked'] = 'The page %s is locked. Try again later.'; -$lang['linkchange'] = 'Links adapted because of a move operation'; +$lang['filelocked'] = 'The page %s is locked. Try again later.'; +$lang['linkchange'] = 'Links adapted because of a move operation'; $lang['nodst'] = 'No new name given'; +$lang['noaction'] = 'There were no moves defined'; $lang['intro'] = 'The move operation has not been started, yet!'; $lang['preview'] = 'Preview changes to be executed.'; $lang['ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; -$lang['ns_move_continue'] = 'Continue the namespace move'; -$lang['ns_move_abort'] = 'Abort the namespace move'; -$lang['ns_move_continued'] = 'The namespace move from namespace %s to namespace %s was continued, %s items are still remaining.'; -$lang['ns_move_started'] = 'A namespace move from namespace %s to namespace %s was started, %s pages and %s media files will be moved.'; -$lang['ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; -$lang['ns_move_tryagain'] = 'Try again'; -$lang['ns_move_skip'] = 'Skip the current item'; +$lang['ns_move_continue'] = 'Continue the namespace move'; +$lang['ns_move_abort'] = 'Abort the namespace move'; +$lang['ns_move_continued'] = 'The namespace move from namespace %s to namespace %s was continued, %s items are still remaining.'; +$lang['ns_move_started'] = 'A namespace move from namespace %s to namespace %s was started, %s pages and %s media files will be moved.'; +$lang['ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; +$lang['ns_move_tryagain'] = 'Try again'; +$lang['ns_move_skip'] = 'Skip the current item'; -$lang['btn_start'] = 'Start'; +$lang['btn_start'] = 'Start'; $lang['btn_continue'] = 'Continue'; -$lang['btn_retry'] = 'Retry item'; -$lang['btn_skip'] = 'Skip item'; -$lang['btn_abort'] = 'Abort'; - - +$lang['btn_retry'] = 'Retry item'; +$lang['btn_skip'] = 'Skip item'; +$lang['btn_abort'] = 'Abort'; // Form labels $lang['legend'] = 'Move current page or namespace'; -$lang['movepage'] = 'Move page'; -$lang['movens'] = 'Move namespace'; -$lang['dst'] = 'New name:'; -$lang['content_to_move'] = 'Content to move:'; -$lang['autoskip'] = 'Ignore errors and skip pages that can\'t be moved'; -$lang['autorewrite'] = 'Rewrite links right after the move completed'; -$lang['move_pages'] = 'Pages'; -$lang['move_media'] = 'Media files'; +$lang['movepage'] = 'Move page'; +$lang['movens'] = 'Move namespace'; +$lang['dst'] = 'New name:'; +$lang['content_to_move'] = 'Content to move:'; +$lang['autoskip'] = 'Ignore errors and skip pages that can\'t be moved'; +$lang['autorewrite'] = 'Rewrite links right after the move completed'; +$lang['move_pages'] = 'Pages'; +$lang['move_media'] = 'Media files'; $lang['move_media_and_pages'] = 'Pages and media files'; -// JavaScript preview -$lang['js']['previewpage'] = 'OLDPAGE will be moved to NEWPAGE'; -$lang['js']['previewns'] = 'All pages and namespaces in the namespace OLDNS will be moved in the namespace NEWNS'; - -$lang['renamepage'] = 'Rename Page'; -$lang['js']['rename'] = 'Rename'; -$lang['js']['cancel'] = 'Cancel'; -$lang['js']['newname'] = 'New name:'; +// Rename feature +$lang['renamepage'] = 'Rename Page'; +$lang['cantrename'] = 'The page can\'t be renamed right now. Please try later.'; +$lang['js']['rename'] = 'Rename'; +$lang['js']['cancel'] = 'Cancel'; +$lang['js']['newname'] = 'New name:'; $lang['js']['inprogress'] = 'renaming page and adjusting links...'; -$lang['cantrename'] = 'The page can\'t be renamed right now. Please try later.'; +$lang['js']['complete'] = 'Move operation finished.'; -$lang['js']['complete'] = 'Move operation finished.'; +// Tree Manager +$lang['pages'] = 'Pages'; +$lang['media'] = 'Media'; +$lang['noscript'] = 'This feature requires JavaScript'; +$lang['moveinprogress'] = 'There is another move operation in progress currently, you can\'t use this tool right now.'; diff --git a/lang/en/tree.txt b/lang/en/tree.txt new file mode 100644 index 0000000..16a4427 --- /dev/null +++ b/lang/en/tree.txt @@ -0,0 +1,3 @@ +====== Move Manager ===== + +This interface allows you to rearrange your wiki's namespaces, pages and media files via Drag'n'Drop. \ No newline at end of file diff --git a/script/tree.js b/script/tree.js index b3527c5..41d2751 100644 --- a/script/tree.js +++ b/script/tree.js @@ -2,43 +2,49 @@ * Script for the tree management interface */ +var $GUI = jQuery('#plugin_move__tree'); -jQuery('#plugin_move__tree').find('ul.tree_list') +$GUI.show(); + +$GUI.find('ul.tree_list') // make folders open and close via AJAX .click(function (e) { var $link = jQuery(e.target); if ($link.attr('href')) { e.stopPropagation(); - var $li = $link.parent().parent('li'); + var $li = $link.parent().parent(); if ($li.hasClass('open')) { $li .removeClass('open') - .addClass('closed') - .find('ul').remove(); + .addClass('closed'); + } else { $li .removeClass('closed') .addClass('open'); - var is_media = $li.closest('div.tree_root').hasClass('tree_media') ? 1 : 0; - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - { - call: 'plugin_move_tree', - ns: $link.attr('href'), - is_media: is_media - }, - function (data) { - $li.append(data); - } - ); + // if had not been loaded before, load via AJAX + if (!$li.find('ul').length) { + var is_media = $li.closest('div.tree_root').hasClass('tree_media') ? 1 : 0; + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_tree', + ns: $link.attr('href'), + is_media: is_media + }, + function (data) { + $li.append(data); + } + ); + } } } e.preventDefault(); }) // initialize sortable - .sortable({ + .find('ul').sortable({ items: 'li', stop: function (e, ui) { var newparent = ui.item.parent().closest('li').attr('data-id'); @@ -54,19 +60,34 @@ jQuery('#plugin_move__tree').find('ul.tree_list') } }); -jQuery('button.plugin_move_tree_exec').click(function(e){ +/** + * Gather all moves from the trees and put them as JSON into the form before submit + */ +jQuery('#plugin_move__tree_execute').submit(function (e) { var data = []; - jQuery('ul.plugin_move_tree .moved').each(function(idx, el){ + $GUI.find('.tree_pages .moved').each(function (idx, el) { + var $el = jQuery(el); + var newparent = $el.parent().closest('li').attr('data-id'); + + data[data.length] = { + class: $el.hasClass('type-d') ? 'ns' : 'doc', + type: 'page', + src: $el.attr('data-id'), + dst: newparent + ':' + $el.attr('data-name') + }; + }); + $GUI.find('.tree_media .moved').each(function (idx, el) { var $el = jQuery(el); var newparent = $el.parent().closest('li').attr('data-id'); data[data.length] = { - type: $el.hasClass('type-d') ? 'd' : 'f', - from: $el.attr('data-id'), - to: newparent + ':' + $el.attr('data-name') + class: $el.hasClass('type-d') ? 'ns' : 'doc', + type: 'media', + src: $el.attr('data-id'), + dst: newparent + ':' + $el.attr('data-name') }; }); - console.log(JSON.stringify(data)); + jQuery(this).find('input[name=json]').val(JSON.stringify(data)); }); \ No newline at end of file diff --git a/style.less b/style.less index 8a077cf..8101555 100644 --- a/style.less +++ b/style.less @@ -1,5 +1,7 @@ #plugin_move__tree { + display: none; // will be enabled via JavaScript + .tree_pages, .tree_media { width: 49%; @@ -8,14 +10,31 @@ .controls { clear: left; + display: block; } - ul { - .moved { - background-color: #b1b100; + ul.tree_list ul { + .moved div { + background-color: @ini_background_neu; + } + + li { + cursor: move; + } + + li div:hover { + background-color: @ini_background_alt; + } + + li.closed { + ul { + display: none; + } } } + + } /** From 0ddda9edd1ed06828464118bc0ca71fe55c10471 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 15 Apr 2014 15:43:00 +0200 Subject: [PATCH 097/338] Only show one thing in the admin menu The tree manager is now reachable from the main view only. This avoids showing the entry when there's a move in progress. --- admin/main.php | 18 +++++++++++++++++- admin/tree.php | 10 ++++++++-- lang/en/lang.php | 10 +++------- script/tree.js | 1 + style.less | 7 ++++--- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/admin/main.php b/admin/main.php index 1b516f6..4365ed5 100644 --- a/admin/main.php +++ b/admin/main.php @@ -22,13 +22,24 @@ public function __construct() { $this->plan = plugin_load('helper', 'move_plan'); } + /** + * @param $language + * @return string + */ + public function getMenuText($language) { + $label = $this->getLang('menu'); + if($this->plan->isCommited()) $label .= ' '.$this->getLang('inprogress'); + return $label; + } + + /** * Get the sort number that defines the position in the admin menu. * * @return int The sort number */ function getMenuSort() { - return 1000; + return 1011; } /** @@ -152,6 +163,11 @@ protected function GUI_simpleForm() { echo $this->locale_xhtml('move'); + $treelink = wl($ID, array('do'=>'admin', 'page'=>'move_tree')); + echo ''; + $form = new Doku_Form(array('action' => wl($ID), 'method' => 'post', 'class' => 'plugin_move_form')); $form->addHidden('page', 'move_main'); $form->addHidden('id', $ID); diff --git a/admin/tree.php b/admin/tree.php index 06ce473..4e3df96 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -5,12 +5,18 @@ class admin_plugin_move_tree extends DokuWiki_Admin_Plugin { const TYPE_PAGES = 1; const TYPE_MEDIA = 2; + /** + * @param $language + * @return bool + */ public function getMenuText($language) { - return $this->getLang('treemanager'); + return false; // do not show in Admin menu } + /** + * no-op + */ public function handle() { - } public function html() { diff --git a/lang/en/lang.php b/lang/en/lang.php index 62089e0..dbfaa83 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -10,13 +10,9 @@ $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Page/Namespace Move/Rename...'; -$lang['desc'] = 'Page/Namespace Move/Rename Plugin'; -$lang['treemanager'] = 'Page Move Manager'; - - +$lang['menu'] = 'Move pages and namespaces'; +$lang['inprogress'] = '(move pending)'; +$lang['treelink'] = 'Alternatively to this simple form you can manage complex restructuring of your wiki using the tree-based move manager.'; $lang['notexist'] = 'The page %s does not exist'; $lang['medianotexist'] = 'The media file %s does not exist'; diff --git a/script/tree.js b/script/tree.js index 41d2751..d255276 100644 --- a/script/tree.js +++ b/script/tree.js @@ -5,6 +5,7 @@ var $GUI = jQuery('#plugin_move__tree'); $GUI.show(); +jQuery('#plugin_move__treelink').show(); $GUI.find('ul.tree_list') // make folders open and close via AJAX diff --git a/style.less b/style.less index 8101555..47b0394 100644 --- a/style.less +++ b/style.less @@ -32,10 +32,11 @@ } } } - - - } +#plugin_move__treelink { + display: none; // will be enabled via JavaScript +} + /** * The progress page From 36eec40fc156aba063fdf18fc36170a8f4b263a0 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 15 Apr 2014 17:10:29 +0200 Subject: [PATCH 098/338] added rename functionality to tree manager --- admin/tree.php | 6 +++++- lang/en/lang.php | 1 + rename.png | Bin 0 -> 231 bytes script/tree.js | 52 +++++++++++++++++++++++++++++++---------------- style.less | 12 ++++++++++- 5 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 rename.png diff --git a/admin/tree.php b/admin/tree.php index 4e3df96..7c5a2e6 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -140,6 +140,9 @@ function html_list($item) { $ret .= noNS($item['id']); $ret .= ''; } + + if($item['id']) $ret .= ''; + return $ret; } @@ -159,7 +162,8 @@ function html_li($item) { $params['data-name'] = noNS($item['id']); $params['data-id'] = $item['id']; $attr = buildAttributes($params); - return "
  • "; + + return "
  • "; } } \ No newline at end of file diff --git a/lang/en/lang.php b/lang/en/lang.php index dbfaa83..d396de1 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -84,3 +84,4 @@ $lang['media'] = 'Media'; $lang['noscript'] = 'This feature requires JavaScript'; $lang['moveinprogress'] = 'There is another move operation in progress currently, you can\'t use this tool right now.'; +$lang['js']['renameitem'] = 'Rename this item'; diff --git a/rename.png b/rename.png new file mode 100644 index 0000000000000000000000000000000000000000..8943caff2449a54d06c6eb2f3f26728d6c86a851 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i<*db&7v6=@u3D524(Tk}+wqe)hiGqi@ zHQ&i3?0T%!q^qadpXiYBbMrwdZcE{JjhT`vX3U3eZyjS2URTmENA3gTv4!)+HOv?k a4lwwhZ748aZZHez2nJ7AKbLh*2~7b0>QK!9 literal 0 HcmV?d00001 diff --git a/script/tree.js b/script/tree.js index d255276..2c198cf 100644 --- a/script/tree.js +++ b/script/tree.js @@ -7,14 +7,29 @@ var $GUI = jQuery('#plugin_move__tree'); $GUI.show(); jQuery('#plugin_move__treelink').show(); +var checkForMovement = function($li) { + var newparent = $li.parent().closest('li').attr('data-id'); + var newname = $li.attr('data-name'); + var oldid = $li.attr('data-id'); + var newid = (newparent+':'+newname).replace(/^:+/, ''); + + if (newid != oldid) { + $li.addClass('moved'); + $li.children('div').attr('title', oldid+' -> '+newid); + } else { + $li.removeClass('moved'); + $li.children('div').attr('title', ''); + } +}; + + $GUI.find('ul.tree_list') - // make folders open and close via AJAX .click(function (e) { - var $link = jQuery(e.target); - if ($link.attr('href')) { - e.stopPropagation(); - var $li = $link.parent().parent(); + var $clicky = jQuery(e.target); + var $li = $clicky.parent().parent(); + if ($clicky.attr('href')) { // Click on folder - open and close via AJAX + e.stopPropagation(); if ($li.hasClass('open')) { $li .removeClass('open') @@ -32,7 +47,7 @@ $GUI.find('ul.tree_list') DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_move_tree', - ns: $link.attr('href'), + ns: $clicky.attr('href'), is_media: is_media }, function (data) { @@ -41,6 +56,16 @@ $GUI.find('ul.tree_list') ); } } + } else if ($clicky[0].tagName == 'IMG') { // Click on IMG - do rename + e.stopPropagation(); + var $a = $clicky.parent().find('a'); + + var newname = window.prompt(LANG.plugins.move.renameitem, $li.attr('data-name')); + if(newname) { + $li.attr('data-name', newname); + $a.text(newname); + checkForMovement($li); + } } e.preventDefault(); }) @@ -48,18 +73,11 @@ $GUI.find('ul.tree_list') .find('ul').sortable({ items: 'li', stop: function (e, ui) { - var newparent = ui.item.parent().closest('li').attr('data-id'); - var oldparent = ui.item.attr('data-parent'); - - console.log(newparent); - - if (newparent != oldparent) { - ui.item.addClass('moved'); - } else { - ui.item.removeClass('moved'); - } + checkForMovement(ui.item); } - }); + }) + // add title to rename icon + .find('img').attr('title', LANG.plugins.move.renameitem); /** * Gather all moves from the trees and put them as JSON into the form before submit diff --git a/style.less b/style.less index 47b0394..9b57883 100644 --- a/style.less +++ b/style.less @@ -14,16 +14,26 @@ } ul.tree_list ul { - .moved div { + .moved > div { background-color: @ini_background_neu; } li { cursor: move; + + img { + float: right; + cursor: pointer; + display: none; + } } li div:hover { background-color: @ini_background_alt; + + img { + display: block; + } } li.closed { From 44cdf6e69829667df443a8ac047c795a8d1f6efb Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 10:36:54 +0200 Subject: [PATCH 099/338] removed obsolete file --- helper/general.php | 1151 -------------------------------------------- 1 file changed, 1151 deletions(-) delete mode 100644 helper/general.php diff --git a/helper/general.php b/helper/general.php deleted file mode 100644 index 4ebc87f..0000000 --- a/helper/general.php +++ /dev/null @@ -1,1151 +0,0 @@ - - */ -// must be run within Dokuwiki -if (!defined('DOKU_INC')) die(); - -/** - * Helper part of the move plugin. - */ -class helper_plugin_move_generalXXX extends DokuWiki_Plugin { - - /** - * @var string symbol to make move operations easily recognizable in change log - */ - public $symbol = '↷'; - - /** - * @var array access to the info the last move in execution - * - * the same as the data passed to the PLUGIN_MOVE_PAGE_RENAME and PLUGIN_MOVE_MEDIA_RENAME events, - * used for internal introspection in the move plugin. This is ephemeral data and may be outdated or - * misleading when not read directly after a page or media move operation - */ - public $lastmove = array(); - - /** - * Start a namespace move by creating the list of all pages and media files that shall be moved - * - * @param array $opts The options for the namespace move - * @return int The number of items to move - */ - public function start_namespace_move(&$opts) { - global $conf; - - // generate and save a list of all pages - $pagelist = array(); - $pathToSearch = utf8_encodeFN(str_replace(':', '/', $opts['ns'])); - $searchOpts = array('depth' => 0, 'skipacl' => true); - if (in_array($opts['contenttomove'], array('pages', 'both'))) { - search($pagelist, $conf['datadir'], 'search_allpages', $searchOpts, $pathToSearch); - } - $pages = array(); - foreach ($pagelist as $page) { - $pages[] = $page['id']; - } - unset($pagelist); - - $opts['num_pages'] = count($pages); - - $files = $this->get_namespace_meta_files(); - io_saveFile($files['pagelist'], implode("\n", $pages)); - unset($pages); - - // generate and save a list of all media files - $medialist = array(); - if (in_array($opts['contenttomove'], array('media,', 'both'))) { - search($medialist, $conf['mediadir'], 'search_media', $searchOpts, $pathToSearch); - } - - $media_files = array(); - foreach ($medialist as $media) { - $media_files[] = $media['id']; - } - unset ($medialist); - - $opts['started'] = time(); // remember when this move started - $opts['affected'] = 0; // will be filled in later - $opts['num_media'] = count($media_files); - - io_saveFile($files['medialist'], implode("\n", $media_files)); - - $opts['remaining'] = $opts['num_media'] + $opts['num_pages']; - - // save the options - io_saveFile($files['opts'], serialize($opts)); - - return $opts['num_pages'] + $opts['num_media']; - } - - /** - * Execute the next steps of the currently running namespace move - * - * This function will move up to 10 pages or media files or adjust the links of affected pages. - * It is repeatedly called via AJAX (or several clicks from the user if JavaScript is missing) - * - * @return bool|int False if an error occurred, otherwise the number of remaining moves - */ - public function continue_namespace_move() { - global $ID; - global $conf; - - $files = $this->get_namespace_meta_files(); - - if (!@file_exists($files['opts'])) { - msg('Error: there are no saved options', -1); - return false; - } - - $opts = unserialize(file_get_contents($files['opts'])); - - // handle page moves - if (@file_exists($files['pagelist']) && (filesize($files['pagelist']) > 1) ) { - $pagelist = fopen($files['pagelist'], 'a+');; - - for ($i = 0; $i < 10; ++$i) { - $ID = $this->get_last_id($pagelist); - if ($ID === false) { - break; - } - $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); - $pageOpts = $opts; - $pageOpts['ns'] = getNS($ID); - $pageOpts['name'] = noNS($ID); - $pageOpts['newname'] = noNS($ID); - $pageOpts['newns'] = getNS($newID); - if (!$this->move_page($pageOpts)) { - fclose($pagelist); - $this->log($opts['started'], 'P', $ID, $newID, false); - - // automatically skip this item if wanted - if($opts['autoskip']) { - return $this->skip_namespace_move_item(); - } - return false; - } - $this->log($opts['started'], 'P', $ID, $newID, true); - - // remember affected pages - io_saveFile($files['affected'], join("\n", $this->lastmove['affected_pages'])."\n", true); - - // update the list of pages and the options after every move - ftruncate($pagelist, ftell($pagelist)); - $opts['remaining']--; - io_saveFile($files['opts'], serialize($opts)); - } - - fclose($pagelist); - return max(1, $opts['remaining']); // force one more call - } - - // handle media moves - if (@file_exists($files['medialist']) && (filesize($files['medialist']) > 1) ) { - $medialist = fopen($files['medialist'], 'a+'); - - for ($i = 0; $i < 10; ++$i) { - $ID = $this->get_last_id($medialist); - if ($ID === false) { - break; - } - $newID = $this->getNewID($ID, $opts['ns'], $opts['newns']); - $pageOpts = $opts; - $pageOpts['ns'] = getNS($ID); - $pageOpts['name'] = noNS($ID); - $pageOpts['newname'] = noNS($ID); - $pageOpts['newns'] = getNS($newID); - if (!$this->move_media($pageOpts)) { - fclose($medialist); - $this->log($opts['started'], 'M', $ID, $newID, false); - - // automatically skip this item if wanted - if($opts['autoskip']) { - return $this->skip_namespace_move_item(); - } - return false; - } - $this->log($opts['started'], 'M', $ID, $newID, true); - - // remember affected pages - io_saveFile($files['affected'], join("\n", $this->lastmove['affected_pages'])."\n", true); - - // update the list of media files and the options after every move - ftruncate($medialist, ftell($medialist)); - $opts['remaining']--; - io_saveFile($files['opts'], serialize($opts)); - } - - fclose($medialist); - return max(1, $opts['remaining']); // force one more call - } - - // update affected pages - if($opts['autorewrite'] && @file_exists($files['affected']) && (filesize($files['affected']) > 1)) { - if(!$opts['affected']) { - // this is the first run, clean up the file - $affected = io_readFile($files['affected']); - $affected = explode("\n", $affected); - $affected = array_unique($affected); - $affected = array_filter($affected); - sort($affected); - if($affected[0] === '') array_shift($affected); - io_saveFile($files['affected'], join("\n", $affected)); - - $opts['affected'] = count($affected); - $opts['remaining'] = $opts['affected']; // something to do again - io_saveFile($files['opts'], serialize($opts)); - - return max(1, $opts['remaining']); // force one more call - } - - // handle affected pages - $affectedlist = fopen($files['affected'], 'a+'); - for ($i = 0; $i < 10; ++$i) { - $ID = $this->get_last_id($affectedlist); - if ($ID === false) { - break; - } - - // rewrite it - $this->execute_rewrites($ID, null); - - // update the list of media files and the options after every move - ftruncate($affectedlist, ftell($affectedlist)); - $opts['remaining']--; - io_saveFile($files['opts'], serialize($opts)); - } - - return max(1, $opts['remaining']); // force one more call - } - - // move all namespace subscriptions - $this->move_files( - $conf['metadir'], - array( - 'ns' => $opts['ns'], - 'newns' => $opts['newns'], - 'name' => '', - 'newname' => '' - ), - '\.mlist' - ); - - // still here? the move is completed - $this->abort_namespace_move(); - return 0; - } - - /** - * Preview all single move operations in a namespace move operation - */ - public function preview_namespace_move() { - $files = $this->get_namespace_meta_files(); - - if (!@file_exists($files['opts'])) { - msg('Error: there are no saved options', -1); - return; - } - $opts = unserialize(file_get_contents($files['opts'])); - - echo '
      '; - if (@file_exists($files['pagelist'])) { - $pagelist = file($files['pagelist']); - foreach($pagelist as $old) { - $new = $this->getNewID($old, $opts['ns'], $opts['newns']); - - echo '
    • '; - echo hsc($old); - echo '→'; - echo hsc($new); - echo '
    • '; - } - } - if (@file_exists($files['medialist'])) { - $medialist = file($files['medialist']); - foreach($medialist as $old) { - $new = $this->getNewID($old, $opts['ns'], $opts['newns']); - - echo '
    • '; - echo hsc($old); - echo '→'; - echo hsc($new); - echo '
    • '; - } - } - echo '
    '; - } - - - - /** - * Skip the item that would be executed next in the current namespace move - * - * @return bool|int False if an error occurred, otherwise the number of remaining moves - */ - public function skip_namespace_move_item() { - global $ID; - $files = $this->get_namespace_meta_files(); - - if (!@file_exists($files['opts'])) { - msg('Error: there are no saved options', -1); - return false; - } - - $opts = unserialize(file_get_contents($files['opts'])); - - if (@file_exists($files['pagelist'])) { - $pagelist = fopen($files['pagelist'], 'a+'); - - $ID = $this->get_last_id($pagelist); - // save the list of pages after every move - if ($ID === false || ftell($pagelist) == 0) { - fclose($pagelist); - unlink($files['pagelist']); - } else { - ftruncate($pagelist, ftell($pagelist));; - fclose($pagelist); - } - } elseif (@file_exists($files['medialist'])) { - $medialist = fopen($files['medialist'], 'a+'); - - $ID = $this->get_last_id($medialist);; - // save the list of media files after every move - if ($ID === false || ftell($medialist) == 0) { - fclose($medialist); - unlink($files['medialist']); - unlink($files['opts']); - } else { - ftruncate($medialist, ftell($medialist)); - } - } else { - unlink($files['opts']); - } - if ($opts['remaining'] == 0) return 0; - else { - $opts['remaining']--; - // save the options - io_saveFile($files['opts'], serialize($opts)); - return $opts['remaining']; - } - } - - /** - * Log result of an operation - * - * @param int $optime - * @param string $type - * @param string $from - * @param string $to - * @param bool $success - * @author Andreas Gohr - */ - private function log($optime, $type, $from, $to, $success){ - global $conf; - global $MSG; - - - $file = $conf['cachedir'].'/move-'.$optime.'.log'; - $now = time(); - $date = date('Y-m-d H:i:s', $now); // for human readability - - if($success) { - $ok = 'success'; - $msg = ''; - }else { - $ok = 'failed'; - $msg = $MSG[count($MSG)-1]['msg']; // get detail from message array - } - - $log = "$now\t$date\t$type\t$from\t$to\t$ok\t$msg\n"; - io_saveFile($file, $log, true); - } - - /** - * Get last file id from the list that is stored in the file that is referenced by the handle - * The handle is set to the newline before the file id - * - * @param resource $handle The file handle to read from - * @return string|bool the last id from the list or false if there is none - */ - private function get_last_id($handle) { - // begin the seek at the end of the file - fseek($handle, 0, SEEK_END); - $id = ''; - - // seek one backwards as long as it's possible - while (fseek($handle, -1, SEEK_CUR) >= 0) { - $c = fgetc($handle); - fseek($handle, -1, SEEK_CUR); // reset the position to the character that was read - - if ($c == "\n") { - break; - } - if ($c === false) return false; // EOF, i.e. the file is empty - $id = $c.$id; - } - - if ($id === '') return false; // nothing was read i.e. the file is empty - else return $id; - } - - /** - * Abort the currently running namespace move - */ - public function abort_namespace_move() { - $files = $this->get_namespace_meta_files(); - foreach ($files as $file) { - @unlink($file); - } - } - - /** - * Get the options for the namespace move that is currently in progress if there is any - * - * @return bool|array False if there is no namespace move in progress, otherwise the array of options - */ - public function get_namespace_move_opts() { - $files = $this->get_namespace_meta_files(); - - if (!@file_exists($files['opts'])) { - return false; - } - - $opts = unserialize(file_get_contents($files['opts'])); - - return $opts; - } - - /** - * Get the filenames for the metadata of the move plugin - * - * @return array The file names for opts, pagelist and medialist - * @moved - */ - protected function get_namespace_meta_files() { - global $conf; - return array( - 'opts' => $conf['metadir'].'/__move_opts', - 'pagelist' => $conf['metadir'].'/__move_pagelist', - 'medialist' => $conf['metadir'].'/__move_medialist', - 'affected' => $conf['metadir'].'/__move_affected', - ); - } - - /** - * Get the id of a page after a namespace move - * - * @param string $oldid The old id of the page - * @param string $oldns The old namespace. $oldid needs to be inside $oldns - * @param string $newns The new namespace - * @return string The new id - */ - function getNewID($oldid, $oldns, $newns) { - $newid = $oldid; - if ($oldns != '') { - $newid = substr($oldid, strlen($oldns)+1); - } - - if ($newns != '') { - $newid = $newns.':'.$newid; - } - - return $newid; - } - - /** - * move page - * - * @author Gary Owen , modified by Kay Roesler - * @author Michael Hamann - * - * @param array $opts - * @param bool $checkonly Only execute the checks if the page can be moved - * @return bool If the move was executed - */ - public function move_page(&$opts, $checkonly = false) { - global $ID; - - // Check we have rights to move this document - if ( !page_exists($ID)) { - msg(sprintf($this->getLang('notexist'), $ID), -1); - return false; - } - if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { - msg(sprintf($this->getLang('norights'), hsc($ID)), -1); - return false; - } - - // Check file is not locked - // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user - // the file exists check checks if the page is reported unlocked if a lock exists which means that - // the page is locked by the current user - if (checklock($ID) !== false || @file_exists(wikiLockFN($ID))) { - msg( sprintf($this->getLang('filelocked'), hsc($ID)), -1); - return false; - } - - // Assemble fill document name and path - $opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']); - $opts['new_path'] = wikiFN($opts['new_id']); - - // Has the document name and/or namespace changed? - if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { - msg($this->getLang('nochange'), -1); - return false; - } - // Check the page does not already exist - if ( @file_exists($opts['new_path']) ) { - msg(sprintf($this->getLang('existing'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('root') : $opts['newns'])), -1); - return false; - } - - // Check if the current user can create the new page - if (auth_quickaclcheck($opts['new_id']) < AUTH_CREATE) { - msg(sprintf($this->getLang('notargetperms'), $opts['new_id']), -1); - return false; - } - - if ($checkonly) return true; - - /** - * End of init (checks) - */ - - $page_meta = $this->getMoveMeta($ID); - if (!$page_meta) $page_meta = array(); - if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); - $page_meta['old_ids'][$ID] = time(); - - // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages - $affected_pages = idx_get_indexer()->lookupKey('relation_references', $ID); - - $this->lastmove = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], '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 - // note that old_ids is in the form 'id' => timestamp of move - $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $this->lastmove); - if ($event->advise_before()) { - // Open the old document and change forward links - lock($ID); - $text = rawWiki($ID); - - $text = $this->rewrite_content($text, $ID, array($ID => $opts['new_id'])); - $oldRev = getRevisions($ID, -1, 1, 1024); // from changelog - - // 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_move_indexer(); // copy of the new code - } - if (($idx_msg = $Indexer->renamePage($ID, $opts['new_id'])) !== true - || ($idx_msg = $Indexer->renameMetaValue('relation_references', $ID, $opts['new_id'])) !== true) { - msg('Error while updating the search index '.$idx_msg, -1); - return false; - } - if (!$this->movemeta($opts)) { - msg('The meta files of page '.$ID.' couldn\'t be moved', -1); - return false; - } - - // Save the updated document in its new location - if ($opts['ns'] == $opts['newns']) { - $lang_key = 'renamed'; - } - elseif ( $opts['name'] == $opts['newname'] ) { - $lang_key = 'moved'; - } - else { - $lang_key = 'move_rename'; - } - - // Wait a second when the page has just been rewritten - if ($oldRev == time()) sleep(1); - - $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); - saveWikiText($opts['new_id'], $text, $this->symbol.' '.$summary); - - // Delete the orginal file - if (@file_exists(wikiFN($opts['new_id']))) { - saveWikiText($ID, '', $this->symbol.' '.$summary); - } - - // Move the old revisions - if (!$this->moveattic($opts)) { - // it's too late to stop the move, so just display a message. - msg('The attic files of page '.$ID.' couldn\'t be moved. Please move them manually.', -1); - } - - foreach ($affected_pages as $id) { - if (!page_exists($id, '', false) || $id == $ID || $id == $opts['new_id']) continue; - // we are only interested in persistent metadata, so no need to render anything. - $meta = $this->getMoveMeta($id); - if (!$meta) $meta = array('moves' => array()); - if (!isset($meta['moves'])) $meta['moves'] = array(); - $meta['moves'] = $this->resolve_moves($meta['moves'], $id); - $meta['moves'][$ID] = $opts['new_id']; - //if (empty($meta['moves'])) unset($meta['moves']); - p_set_metadata($id, array('plugin_move' => $meta), false, true); - } - - p_set_metadata($opts['new_id'], array('plugin_move' => $page_meta), false, true); - - unlock($ID); - } - - $event->advise_after(); - return true; - } - - /** - * Move media file - * - * @author Michael Hamann - * - * @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('medianotexist'), hsc($opts['id'])), -1); - return false; - } - - if ( auth_quickaclcheck($opts['ns'].':*') < AUTH_DELETE ) { - msg(sprintf($this->getLang('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('nomediachange'), -1); - return false; - } - // Check the page does not already exist - if ( @file_exists($opts['new_path']) ) { - msg(sprintf($this->getLang('mediaexisting'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('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('nomediatargetperms'), $opts['new_id']), -1); - return false; - } - - if ($checkonly) return true; - - /** - * End of init (checks) - */ - - $affected_pages = idx_get_indexer()->lookupKey('relation_media', $opts['id']); - - $this->lastmove = 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('PLUGIN_MOVE_MEDIA_RENAME', $this->lastmove); - 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_move_indexer(); // copy of the new code - } - if (($idx_msg = $Indexer->renameMetaValue('relation_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; - } - - io_sweepNS($opts['id'], 'mediadir'); - - // 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; - $meta = $this->getMoveMeta($id); - 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_move' => $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 Move 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); - } else { - $name = $opts['name']; - } - $newext = mimetype($opts['newname']); - if ($ext[0] !== false) { - $newname = substr($opts['newname'],0, -1*strlen($ext[0])-1); - } else { - $newname = $opts['newname']; - } - $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 Move 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. - * - * @param array $opts Move options (used here: name, newname, ns, newns) - * @return bool If the attic files were moved successfully - */ - public function moveattic($opts) { - global $conf; - - $regex = '\.\d+\.txt(?:\.gz|\.bz2)?'; - return $this->move_files($conf['olddir'], $opts, $regex); - } - - /** - * Move the meta files of the page that is specified in the options. - * - * @param array $opts Move options (used here: name, newname, ns, newns) - * @return bool If the meta files were moved successfully - */ - public function movemeta($opts) { - global $conf; - - $regex = '\.[^.]+'; - return $this->move_files($conf['metadir'], $opts, $regex); - } - - /** - * Internal function for moving and renaming meta/attic files between namespaces - * - * @param string $dir The root path of the files (e.g. $conf['metadir'] or $conf['olddir'] - * @param array $opts Move options (used here: ns, newns, name, newname) - * @param string $extregex Regular expression for matching the extension of the file that shall be moved - * @return bool If the files were moved successfully - */ - private function move_files($dir, $opts, $extregex) { - $old_path = $dir; - if ($opts['ns'] != '') $old_path .= '/'.utf8_encodeFN(str_replace(':', '/', $opts['ns'])); - $new_path = $dir; - 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) { - if ($file == '.' || $file == '..') continue; - $match = array(); - if (is_file($old_path.'/'.$file) && preg_match($regex, $file, $match)) { - if (!is_dir($new_path)) { - if (!io_mkdir_p($new_path)) { - msg('Creating directory '.hsc($new_path).' failed.', -1); - return false; - } - } - if (!io_rename($old_path.'/'.$file, $new_path.'/'.utf8_encodeFN($opts['newname'].$match[1]))) { - msg('Moving '.hsc($old_path.'/'.$file).' to '.hsc($new_path.'/'.utf8_encodeFN($opts['newname'].$match[1])).' failed.', -1); - return false; - } - } - } - closedir($dh); - } else { - msg('Directory '.hsc($old_path).' couldn\'t be opened.', -1); - return false; - } - return true; - } - - /** - * Rewrite the text of a page according to the recorded moves, the rewritten text is saved - * - * @param string $id The id of the page that shall be rewritten - * @param string|null $text Old content of the page. When null is given the content is loaded from disk. - * @return string|bool The rewritten content, false on error - */ - public function execute_rewrites($id, $text = null) { - $meta = $this->getMoveMeta($id); - if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { - if(is_null($text)) $text = rawWiki($id); - $moves = isset($meta['moves']) ? $meta['moves'] : array(); - $media_moves = isset($meta['media_moves']) ? $meta['media_moves'] : array(); - - $old_text = $text; - $text = $this->rewrite_content($text, $id, $moves, $media_moves); - $changed = ($old_text != $text); - $file = wikiFN($id, '', false); - if(is_writable($file) || !$changed) { - if ($changed) { - // Wait a second if page has just been saved - $oldRev = getRevisions($id, -1, 1, 1024); // from changelog - if ($oldRev == time()) sleep(1); - saveWikiText($id, $text, $this->symbol.' '.$this->getLang('linkchange'), $this->getConf('minor')); - } - unset($meta['moves']); - unset($meta['media_moves']); - p_set_metadata($id, array('plugin_move' => $meta), false, true); - } else { // FIXME: print error here or fail silently? - msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); - } - } - - return $text; - } - - /** - * Rewrite a text in order to fix the content after the given moves. - * - * @param string $text The wiki text that shall be rewritten - * @param string $id The id of the wiki page, if the page itself was moved the old id - * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids - * @param array $media_moves Array of all media moves. - * @return string The rewritten wiki text - */ - function rewrite_content($text, $id, $moves, $media_moves = array()) { - $moves = $this->resolve_moves($moves, $id); - $media_moves = $this->resolve_moves($media_moves, $id); - - $handlers = array(); - $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); - - /* - * PLUGIN_MOVE_HANDLERS REGISTER event: - * - * Plugin handlers can be registered in the $handlers array, the key is the plugin name as it is given to the handler - * The handler needs to be a valid callback, it will get the following parameters: - * $match, $state, $pos, $pluginname, $handler. The first three parameters are equivalent to the parameters - * of the handle()-function of syntax plugins, the $pluginname is just the plugin name again so handler functions - * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object. - * It has the following properties and functions that can be used: - * - id, ns: id and namespace of the old page - * - new_id, new_ns: new id and namespace (can be identical to id and ns) - * - moves: array of moves, the same as $moves in the event - * - media_moves: array of media moves, same as $media_moves in the event - * - adaptRelativeId($id): adapts the relative $id according to the moves - */ - trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data); - - $modes = p_get_parsermodes(); - - // Create the parser - $Parser = new Doku_Parser(); - - // Add the Handler - $Parser->Handler = new helper_plugin_move_handler($id, $moves, $media_moves, $handlers); - - //add modes to parser - foreach($modes as $mode) { - $Parser->addMode($mode['mode'], $mode['obj']); - } - - return $Parser->parse($text); - } - - /** - * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. - * - * @param array $moves The moves - * @param string $id - * @return array The resolved moves - */ - protected function resolve_moves($moves, $id) { - // resolve moves of pages that were moved more than once - $tmp_moves = array(); - foreach($moves as $old => $new) { - if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { - // write to temp array in order to correctly handle rename circles - $tmp_moves[$old] = $moves[$new]; - } - } - - $changed = !empty($tmp_moves); - - // this correctly resolves rename circles by moving forward one step a time - while($changed) { - $changed = false; - foreach($tmp_moves as $old => $new) { - if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { - $tmp_moves[$old] = $moves[$new]; - $changed = true; - } - } - } - - // manual merge, we can't use array_merge here as ids can be numeric - foreach($tmp_moves as $old => $new) { - if($old == $new) unset($moves[$old]); - else $moves[$old] = $new; - } - return $moves; - } - - /** - * Get the HTML code of a namespace move button - * @param string $action The desired action of the button (continue, tryagain, skip, abort) - * @param string|null $id The id of the target page, null if $ID shall be used - * @return bool|string The HTML of code of the form or false if an invalid action was supplied - */ - public function getNSMoveButton($action, $id = NULL) { - if ($id === NULL) { - global $ID; - $id = $ID; - } - - $class = 'move__nsform'; - switch ($action) { - case 'continue': - case 'tryagain': - $class .= ' move__nscontinue'; - break; - case 'skip': - $class .= ' move__nsskip'; - break; - } - - $form = new Doku_Form(array('action' => wl($id), 'method' => 'post', 'class' => $class)); - $form->addHidden('page', $this->getPluginName()); - $form->addHidden('id', $id); - switch ($action) { - case 'continue': - case 'tryagain': - $form->addHidden('continue_namespace_move', true); - if ($action == 'tryagain') { - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_tryagain'))); - } else { - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_continue'))); - } - break; - case 'skip': - $form->addHidden('skip_continue_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_skip'))); - break; - case 'abort': - $form->addHidden('abort_namespace_move', true); - $form->addElement(form_makeButton('submit', 'admin', $this->getLang('ns_move_abort'))); - break; - default: - return false; - } - return $form->getForm(); - } - - /** - * This function loads and returns the persistent metadata for the move plugin. If there is metadata for the - * pagemove plugin (not the old one but the version that immediately preceeded the move plugin) it will be migrated. - * - * @param string $id The id of the page the metadata shall be loaded for - * @return array|null The metadata of the page - */ - public function getMoveMeta($id) { - $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); - // migrate old metadata from the pagemove plugin - if (isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { - if (isset($all_meta['plugin_move'])) { - $all_meta['plugin_move'] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta['plugin_move']); - } else { - $all_meta['plugin_move'] = $all_meta['plugin_pagemove']; - } - p_set_metadata($id, array('plugin_move' => $all_meta['plugin_move'], 'plugin_pagemove' => null), false, true); - } - return isset($all_meta['plugin_move']) ? $all_meta['plugin_move'] : null; - } - - /** - * Determines if it would be okay to show a rename page button for the given page and current user - * - * @param $id - * @return bool - */ - public function renameOkay($id) { - global $ACT; - global $USERINFO; - if ( !($ACT == 'show' || empty($ACT)) ) return false; - if (!page_exists($id)) return false; - if (auth_quickaclcheck($id) < AUTH_EDIT ) return false; - if (checklock($id) !== false || @file_exists(wikiLockFN($id))) return false; - if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], $USERINFO['grps'])) return false; - - return true; - } - - /** - * Use this in your template to add a simple "move this page" link - * - * Alternatively give anything the class "plugin_move_page" - it will automatically be hidden and shown and - * trigger the page move dialog. - */ - public function tpl() { - echo ''; - echo $this->getLang('renamepage'); - echo ''; - } -} - -/** - * Indexer class extended by move features, only needed and used in releases older than Spring 2013 - */ -class helper_plugin_move_indexer extends Doku_Indexer { - /** - * Rename a page in the search index without changing the indexed content - * - * @param string $oldpage The old page name - * @param string $newpage The new page name - * @return string|bool If the page was successfully renamed, can be a message in the case of an error - */ - public function renamePage($oldpage, $newpage) { - if (!$this->lock()) return 'locked'; - - $pages = $this->getPages(); - - $id = array_search($oldpage, $pages); - if ($id === false) { - $this->unlock(); - return 'page is not in index'; - } - - $new_id = array_search($newpage, $pages); - if ($new_id !== false) { - $this->unlock(); - // make sure the page is not in the index anymore - $this->deletePage($newpage); - if (!$this->lock()) return 'locked'; - - $pages[$new_id] = 'deleted:'.time().rand(0, 9999); - } - - $pages[$id] = $newpage; - - // update index - if (!$this->saveIndex('page', '', $pages)) { - $this->unlock(); - return false; - } - - $this->unlock(); - return true; - } - - /** - * Renames a meta value in the index. This doesn't change the meta value in the pages, it assumes that all pages - * will be updated. - * - * @param string $key The metadata key of which a value shall be changed - * @param string $oldvalue The old value that shall be renamed - * @param string $newvalue The new value to which the old value shall be renamed, can exist (then values will be merged) - * @return bool|string If renaming the value has been successful, false or error message on error. - */ - public function renameMetaValue($key, $oldvalue, $newvalue) { - if (!$this->lock()) return 'locked'; - - // change the relation references index - $metavalues = $this->getIndex($key, '_w'); - $oldid = array_search($oldvalue, $metavalues); - if ($oldid !== false) { - $newid = array_search($newvalue, $metavalues); - if ($newid !== false) { - // free memory - unset ($metavalues); - - // okay, now we have two entries for the same value. we need to merge them. - $indexline = $this->getIndexKey($key, '_i', $oldid); - if ($indexline != '') { - $newindexline = $this->getIndexKey($key, '_i', $newid); - $pagekeys = $this->getIndex($key, '_p'); - $parts = explode(':', $indexline); - foreach ($parts as $part) { - list($id, $count) = explode('*', $part); - $newindexline = $this->updateTuple($newindexline, $id, $count); - - $keyline = explode(':', $pagekeys[$id]); - // remove old meta value - $keyline = array_diff($keyline, array($oldid)); - // add new meta value when not already present - if (!in_array($newid, $keyline)) { - array_push($keyline, $newid); - } - $pagekeys[$id] = implode(':', $keyline); - } - $this->saveIndex($key, '_p', $pagekeys); - unset($pagekeys); - $this->saveIndexKey($key, '_i', $oldid, ''); - $this->saveIndexKey($key, '_i', $newid, $newindexline); - } - } else { - $metavalues[$oldid] = $newvalue; - if (!$this->saveIndex($key, '_w', $metavalues)) { - $this->unlock(); - return false; - } - } - } - - $this->unlock(); - return true; - } -} - - From d31a836e24bdab02342f4bf50c30422aaead5e70 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 10:38:55 +0200 Subject: [PATCH 100/338] cleaned up english language file --- admin/tree.php | 4 +-- helper/op.php | 18 ++++++------ lang/en/lang.php | 72 +++++++++++++++++++----------------------------- 3 files changed, 39 insertions(+), 55 deletions(-) diff --git a/admin/tree.php b/admin/tree.php index 7c5a2e6..2588d90 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -29,12 +29,12 @@ public function html() { echo '
    '; echo '
    '; - echo '

    ' . $this->getLang('pages') . '

    '; + echo '

    ' . $this->getLang('move_pages') . '

    '; $this->htmlTree(self::TYPE_PAGES); echo '
    '; echo '
    '; - echo '

    ' . $this->getLang('media') . '

    '; + echo '

    ' . $this->getLang('move_media') . '

    '; $this->htmlTree(self::TYPE_MEDIA); echo '
    '; diff --git a/helper/op.php b/helper/op.php index b9febed..c2917fe 100644 --- a/helper/op.php +++ b/helper/op.php @@ -32,11 +32,11 @@ class helper_plugin_move_op extends DokuWiki_Plugin { public function checkPage($src, $dst) { // Check we have rights to move this document if(!page_exists($src)) { - msg(sprintf($this->getLang('notexist'), hsc($src)), -1); + msg(sprintf($this->getLang('notexist'), $src), -1); return false; } if(auth_quickaclcheck($src) < AUTH_EDIT) { - msg(sprintf($this->getLang('norights'), hsc($src)), -1); + msg(sprintf($this->getLang('norights'), $src), -1); return false; } @@ -45,19 +45,19 @@ public function checkPage($src, $dst) { // the file exists check checks if the page is reported unlocked if a lock exists which means that // the page is locked by the current user if(checklock($src) !== false || @file_exists(wikiLockFN($src))) { - msg(sprintf($this->getLang('filelocked'), hsc($src)), -1); + msg(sprintf($this->getLang('filelocked'), $src), -1); return false; } // Has the document name and/or namespace changed? if($src == $dst) { - msg($this->getLang('nochange'), -1); + msg(sprintf($this->getLang('notchanged'), $src), -1); return false; } // Check the page does not already exist if(page_exists($dst)) { - msg(sprintf($this->getLang('existing'), $dst), -1); // FIXME adjust string + msg(sprintf($this->getLang('exists'), $src, $dst), -1); return false; } @@ -80,23 +80,23 @@ public function checkPage($src, $dst) { public function checkMedia($src, $dst) { // Check we have rights to move this document if(!file_exists(mediaFN($src))) { - msg(sprintf($this->getLang('medianotexist'), hsc($src)), -1); + msg(sprintf($this->getLang('medianotexist'), $src), -1); return false; } if(auth_quickaclcheck($src) < AUTH_DELETE) { - msg(sprintf($this->getLang('nomediarights'), hsc($src)), -1); + msg(sprintf($this->getLang('nomediarights'), $src), -1); return false; } // Has the document name and/or namespace changed? if($src == $dst) { - msg($this->getLang('nomediachange'), -1); + msg(sprintf($this->getLang('medianotchanged'), $src), -1); return false; } // Check the page does not already exist if(@file_exists(mediaFN($dst))) { - msg(sprintf($this->getLang('mediaexisting'), $dst), -1); // FIXME adjust string + msg(sprintf($this->getLang('mediaexists'), $src, $dst), -1); return false; } diff --git a/lang/en/lang.php b/lang/en/lang.php index d396de1..b5833db 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -6,51 +6,35 @@ * @author Gary Owen <> */ -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; +$lang['menu'] = 'Move pages and namespaces'; +$lang['inprogress'] = '(move pending)'; +$lang['treelink'] = 'Alternatively to this simple form you can manage complex restructuring of your wiki using the tree-based move manager.'; -$lang['menu'] = 'Move pages and namespaces'; -$lang['inprogress'] = '(move pending)'; -$lang['treelink'] = 'Alternatively to this simple form you can manage complex restructuring of your wiki using the tree-based move manager.'; +// page errors +$lang['notexist'] = 'The page %s does not exist'; +$lang['norights'] = 'You have insufficient permissions to edit %s.'; +$lang['filelocked'] = 'The page %s is locked. Try again later.'; +$lang['notchanged'] = 'No new destination given for page %s (location unchanged).'; +$lang['exists'] = 'Page %s can\'t be moved to %s, the target already exists.'; +$lang['notargetperms'] = 'You don\'t have the permission to create the page %s.'; -$lang['notexist'] = 'The page %s does not exist'; +// media errors $lang['medianotexist'] = 'The media file %s does not exist'; -$lang['notwrite'] = 'You do not have sufficient permissions to modify this page'; -$lang['badns'] = 'Invalid characters in namespace.'; -$lang['badname'] = 'Invalid characters in pagename.'; -$lang['nochange'] = 'Page name and namespace are unchanged.'; -$lang['nomediachange'] = 'Media file name and namespace are unchanged.'; -$lang['existing'] = 'A page called %s already exists in %s'; -$lang['mediaexisting'] = 'A media file called %s already exists in %s'; -$lang['root'] = '[Root namespace]'; -$lang['current'] = '(Current)'; -$lang['renamed'] = 'Page name changed from %s to %s'; -$lang['moved'] = 'Page moved from %s to %s'; -$lang['move_rename'] = 'Page moved and renamed from %s to %s'; -$lang['delete'] = 'Deleted by move plugin'; -$lang['norights'] = 'You have insufficient permissions to edit %s.'; $lang['nomediarights'] = 'You have insufficient permissions to delete %s.'; -$lang['notargetperms'] = 'You don\'t have the permission to create the page %s.'; +$lang['medianotchanged'] = 'No new destination given for page %s (location unchanged).'; +$lang['mediaexists'] = 'Media %s can\'t be moved to %s, the target already exists.'; $lang['nomediatargetperms'] = 'You don\'t have the permission to create the media file %s.'; -$lang['filelocked'] = 'The page %s is locked. Try again later.'; -$lang['linkchange'] = 'Links adapted because of a move operation'; -$lang['nodst'] = 'No new name given'; -$lang['noaction'] = 'There were no moves defined'; - -$lang['intro'] = 'The move operation has not been started, yet!'; -$lang['preview'] = 'Preview changes to be executed.'; - -$lang['ns_move_in_progress'] = 'There is currently a namespace move of %s page and %s media files from namespace %s to namespace %s in progress.'; -$lang['ns_move_continue'] = 'Continue the namespace move'; -$lang['ns_move_abort'] = 'Abort the namespace move'; -$lang['ns_move_continued'] = 'The namespace move from namespace %s to namespace %s was continued, %s items are still remaining.'; -$lang['ns_move_started'] = 'A namespace move from namespace %s to namespace %s was started, %s pages and %s media files will be moved.'; -$lang['ns_move_error'] = 'An error occurred while continueing the namespace move from %s to %s.'; -$lang['ns_move_tryagain'] = 'Try again'; -$lang['ns_move_skip'] = 'Skip the current item'; +// changelog summaries +$lang['renamed'] = 'Page name changed from %s to %s'; +$lang['moved'] = 'Page moved from %s to %s'; +$lang['move_rename'] = 'Page moved and renamed from %s to %s'; +$lang['delete'] = 'Deleted by move plugin'; +$lang['linkchange'] = 'Links adapted because of a move operation'; +// progress view +$lang['intro'] = 'The move operation has not been started, yet!'; +$lang['preview'] = 'Preview changes to be executed.'; $lang['btn_start'] = 'Start'; $lang['btn_continue'] = 'Continue'; $lang['btn_retry'] = 'Retry item'; @@ -58,8 +42,7 @@ $lang['btn_abort'] = 'Abort'; // Form labels -$lang['legend'] = 'Move current page or namespace'; - +$lang['legend'] = 'Move current page or namespace'; $lang['movepage'] = 'Move page'; $lang['movens'] = 'Move namespace'; $lang['dst'] = 'New name:'; @@ -69,6 +52,8 @@ $lang['move_pages'] = 'Pages'; $lang['move_media'] = 'Media files'; $lang['move_media_and_pages'] = 'Pages and media files'; +$lang['nodst'] = 'No new name given'; +$lang['noaction'] = 'There were no moves defined'; // Rename feature $lang['renamepage'] = 'Rename Page'; @@ -80,8 +65,7 @@ $lang['js']['complete'] = 'Move operation finished.'; // Tree Manager -$lang['pages'] = 'Pages'; -$lang['media'] = 'Media'; -$lang['noscript'] = 'This feature requires JavaScript'; -$lang['moveinprogress'] = 'There is another move operation in progress currently, you can\'t use this tool right now.'; +$lang['root'] = '[Root namespace]'; +$lang['noscript'] = 'This feature requires JavaScript'; +$lang['moveinprogress'] = 'There is another move operation in progress currently, you can\'t use this tool right now.'; $lang['js']['renameitem'] = 'Rename this item'; From a707083bee5ffab58b2dffc88f7f3bd0c77fc90c Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 11:25:15 +0200 Subject: [PATCH 101/338] preview affected pages as well --- helper/plan.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index 8d7afdc..bcc0b4f 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -366,13 +366,18 @@ public function nextStep($skip = false) { } /** - * Returns the list of page and media moves as a HTML list + * Returns the list of page and media moves and the affected pages as a HTML list + * + * @fixme This will gather affected pages on its own, maybe it would be better to make this somehow part of + * commit() process as it would also make the progress bar behave better * * @return string */ public function previewHTML() { $html = ''; + $affected = array(); + $html .= '
      '; if(@file_exists($this->files['pagelist'])) { $pagelist = file($this->files['pagelist']); @@ -384,6 +389,9 @@ public function previewHTML() { $html .= '→'; $html .= hsc($new); $html .= '
  • '; + + // get all pages linking to the original page + $affected = array_merge($affected, idx_get_indexer()->lookupKey('relation_references', $old)); } } if(@file_exists($this->files['medialist'])) { @@ -396,8 +404,19 @@ public function previewHTML() { $html .= '→'; $html .= hsc($new); $html .= '
    '; + + // get all pages using this media + $affected = array_merge($affected, idx_get_indexer()->lookupKey('relation_media', $old)); } } + $affected = array_unique($affected); + sort($affected); + foreach($affected as $page) { + $html .= '
  • '; + $html .= '↷'; + $html .= hsc($page); + $html .= '
  • '; + } $html .= ''; return $html; From 6ceabb1fe539ab8bd4c11feb30108df6a30f1c18 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 11:41:20 +0200 Subject: [PATCH 102/338] added icons to preview, introduced images folder --- admin/tree.php | 2 +- images/disk.png | Bin 0 -> 620 bytes images/page.png | Bin 0 -> 635 bytes images/page_link.png | Bin 0 -> 830 bytes rename.png => images/rename.png | Bin sprite.png => images/sprite.png | Bin style.less | 20 +++++++++++++++++--- 7 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 images/disk.png create mode 100644 images/page.png create mode 100644 images/page_link.png rename rename.png => images/rename.png (100%) rename sprite.png => images/sprite.png (100%) diff --git a/admin/tree.php b/admin/tree.php index 2588d90..4f3454c 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -141,7 +141,7 @@ function html_list($item) { $ret .= ''; } - if($item['id']) $ret .= ''; + if($item['id']) $ret .= ''; return $ret; } diff --git a/images/disk.png b/images/disk.png new file mode 100644 index 0000000000000000000000000000000000000000..99d532e8b1750115952f97302a92d713c0486f97 GIT binary patch literal 620 zcmV-y0+aoTP)~H+MJzd|s z^YP1Hc07G_>)Lgir!F1{Qn4GcTg%?koHo<=1qRN{}nPDolOeI^o4N5I>! zU$N=L=sg~ zDx#dOA*B0N~cqPsWI(^rbbkh)DS0_H_UN0C4l_kvWIm2#Kyy6%BCh z(yIUf003&1xdx>t$*eR2ZvXxT0001Z_R$y3Iju92q*wg58};}zm(OaAH=p|y0002M zh5O5#fxp|~jc?yi@+7$`d4Q6Hl%z;WiWG??NXR{Hx%)pMd~SE0000OQI literal 0 HcmV?d00001 diff --git a/images/page.png b/images/page.png new file mode 100644 index 0000000000000000000000000000000000000000..03ddd799fa0a3aec561c75d4221f195db65d6eb9 GIT binary patch literal 635 zcmV->0)+jEP);68^d)m`eN0o>(5%D`Q(1;j>g@G;xlf`0VBQ`PFY?6)!N&f?*K}$p; zB!U=NBn{eB8${1}&-2_L*HuZp@ZP1@clS@cHp)4iM1ewzw59vko7eMM{e9z|%NNdX z0V;`?KKSzTCvTm5bc{L^CIKLUxc2X{i{ISz$8Sgf{q)1nXTP{`{s?9mQ$4&hPiKC- zY8q7(Y1Xu5iCf33=O4Vy(+|zQ?rW#gkKB0f%}?+6{G*qT22|DQB-73`YzA{N4W^=s zq0kQYcbtFfz zLz)H<&|z(Y4kP)VWgGzD=Y79#JI$lhEn`|2MpRa?Bt#-nSD~P0P(mbVe{KrOBoKnSsk>m|ML{6l zBosu@om4j#WzNLRAk+{k1JRvL(MfE&vvbb->v>W{*z*1_uMP}0cIRX*?mz+wk%*#O z%0D-+$B*g1nRkvI+_3E8Pr1NC6@5M&4vWaLCnNlr;lNlr4i91z&)eBGqL{L{GNu;Fof}GS9{gM5BJuH;2QWk8yuOZdB3pGR#s8bd~ zAmt<>3Q=YH$t5YJ5;7@+8Uh6=ktBgY6#6Pa%2F?h910?U8cLT43KAj$Z1*==ra&gILO{WkHfs(--F=bly9l~${z@AT>V$oat!YAD@M zBE0v_F{`g#^wOSP-u~!wvlmXdd*uqFqoZ0^{&nEMDU+=!>({S0wrQhFmoB}Yq1)~0 z^{A)L8Xjzdr(W4_exYO6u3a{4*kIeXZMJUR>Q=ksjW_p!rAwDKYUs90>6Q|C>56o@ zbrSq^Xk7Gq#>dAsn@un`Hz$?w$;Ss`%jV7L%9ShgHFV~C)6M>B`Tp%|nqPc&G*A3| z)Qe+}vT4-x^t1~XE@(6wR;^lPWMo9n*~E!cy~)YRsT2{`?fqeIw-e7N@mOA%UcCIq z_kH(_EK7|>pM*1Wt2^DaDAp|cvp*@(ZZDKpYkKC^?97(`0sb&XTXy7N#sB~S07*qo IM6N<$f;YmCWB>pF literal 0 HcmV?d00001 diff --git a/rename.png b/images/rename.png similarity index 100% rename from rename.png rename to images/rename.png diff --git a/sprite.png b/images/sprite.png similarity index 100% rename from sprite.png rename to images/sprite.png diff --git a/style.less b/style.less index 9b57883..d6b3794 100644 --- a/style.less +++ b/style.less @@ -1,3 +1,6 @@ +/** + * Tree Manager + */ #plugin_move__tree { display: none; // will be enabled via JavaScript @@ -47,7 +50,6 @@ display: none; // will be enabled via JavaScript } - /** * The progress page */ @@ -63,6 +65,18 @@ cursor: pointer; color: @ini_link; } + + ul { + li.page { + list-style-image: url(images/page.png); + } + li.media { + list-style-image: url(images/disk.png); + } + li.affected { + list-style-image: url(images/page_link.png); + } + } } } @@ -92,13 +106,13 @@ background-position: right 0; } #dokuwiki__pagetools ul li.plugin_move_page a:before { - content: url(sprite.png); + content: url(images/sprite.png); margin-top: 0; } #dokuwiki__pagetools:hover ul li.plugin_move_page a, #dokuwiki__pagetools ul li.plugin_move_page a:focus, #dokuwiki__pagetools ul li.plugin_move_page a:active { - background-image: url(sprite.png); + background-image: url(images/sprite.png); } #dokuwiki__pagetools ul li.plugin_move_page a:hover, #dokuwiki__pagetools ul li.plugin_move_page a:active, From 045e3f217082d2338dfb24ce17e4feb0b93c70bd Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 12:15:57 +0200 Subject: [PATCH 103/338] add move options to tree manager as well --- admin/tree.php | 5 +++++ lang/en/lang.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/admin/tree.php b/admin/tree.php index 4f3454c..adb8c36 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -48,6 +48,11 @@ public function html() { $form->addHidden('id', $ID); $form->addHidden('page', 'move_main'); $form->addHidden('json', ''); + $form->addElement(form_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', '', ($this->getConf('autoskip') ? array('checked' => 'checked') : array()))); + $form->addElement('
    '); + $form->addElement(form_makeCheckboxField('autorewrite', '1', $this->getLang('autorewrite'), '', '', ($this->getConf('autorewrite') ? array('checked' => 'checked') : array()))); + $form->addElement('
    '); + $form->addElement('
    '); $form->addElement(form_makeButton('submit', 'admin', $this->getLang('btn_start'))); $form->printForm(); } diff --git a/lang/en/lang.php b/lang/en/lang.php index b5833db..8aac2cd 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -47,7 +47,7 @@ $lang['movens'] = 'Move namespace'; $lang['dst'] = 'New name:'; $lang['content_to_move'] = 'Content to move:'; -$lang['autoskip'] = 'Ignore errors and skip pages that can\'t be moved'; +$lang['autoskip'] = 'Ignore errors and skip pages or files that can\'t be moved'; $lang['autorewrite'] = 'Rewrite links right after the move completed'; $lang['move_pages'] = 'Pages'; $lang['move_media'] = 'Media files'; From d49f5bf870e92cccc2257d69845c6feaebc19b04 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 13:07:18 +0200 Subject: [PATCH 104/338] correctly determine new IDs from tree operations --- admin/tree.php | 1 - script/tree.js | 61 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/admin/tree.php b/admin/tree.php index adb8c36..a218c0b 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -163,7 +163,6 @@ function html_li($item) { $params = array(); $params['class'] = ' type-' . $item['type']; if($item['type'] == 'd') $params['class'] .= ' ' . ($item['open'] ? 'open' : 'closed'); - $params['data-parent'] = getNS($item['id']); $params['data-name'] = noNS($item['id']); $params['data-id'] = $item['id']; $attr = buildAttributes($params); diff --git a/script/tree.js b/script/tree.js index 2c198cf..0003e5d 100644 --- a/script/tree.js +++ b/script/tree.js @@ -7,22 +7,51 @@ var $GUI = jQuery('#plugin_move__tree'); $GUI.show(); jQuery('#plugin_move__treelink').show(); +/** + * Checks if the given list item was moved in the tree + * + * Moved elements are highlighted and a title shows where they came from + * + * @param $li + */ var checkForMovement = function($li) { - var newparent = $li.parent().closest('li').attr('data-id'); - var newname = $li.attr('data-name'); - var oldid = $li.attr('data-id'); - var newid = (newparent+':'+newname).replace(/^:+/, ''); - - if (newid != oldid) { - $li.addClass('moved'); - $li.children('div').attr('title', oldid+' -> '+newid); + // we need to check this LI and all previously moved sub LIs + var $all = $li.add($li.find('li.moved')); + $all.each(function(){ + var $this = jQuery(this); + var oldid = $this.attr('data-id'); + var newid = determineNewID($this); + + if (newid != oldid) { + $this.addClass('moved'); + $this.children('div').attr('title', oldid+' -> '+newid); + } else { + $this.removeClass('moved'); + $this.children('div').attr('title', ''); + } + }); +}; + +/** + * Returns the new ID of a given list item + * + * @param $li + * @returns {string} + */ +var determineNewID = function($li) { + var myname = $li.attr('data-name'); + + var $parent = $li.parent().closest('li'); + if($parent.length) { + return (determineNewID($parent) + ':' + myname).replace(/^:/, ''); } else { - $li.removeClass('moved'); - $li.children('div').attr('title', ''); + return myname; } }; - +/** + * Attach event listeners to the tree + */ $GUI.find('ul.tree_list') .click(function (e) { var $clicky = jQuery(e.target); @@ -81,30 +110,32 @@ $GUI.find('ul.tree_list') /** * Gather all moves from the trees and put them as JSON into the form before submit + * + * @fixme has some duplicate code */ jQuery('#plugin_move__tree_execute').submit(function (e) { var data = []; $GUI.find('.tree_pages .moved').each(function (idx, el) { var $el = jQuery(el); - var newparent = $el.parent().closest('li').attr('data-id'); + var newid = determineNewID($el); data[data.length] = { class: $el.hasClass('type-d') ? 'ns' : 'doc', type: 'page', src: $el.attr('data-id'), - dst: newparent + ':' + $el.attr('data-name') + dst: newid }; }); $GUI.find('.tree_media .moved').each(function (idx, el) { var $el = jQuery(el); - var newparent = $el.parent().closest('li').attr('data-id'); + var newid = determineNewID($el); data[data.length] = { class: $el.hasClass('type-d') ? 'ns' : 'doc', type: 'media', src: $el.attr('data-id'), - dst: newparent + ':' + $el.attr('data-name') + dst: newid }; }); From 4edb5e4cc447b956661c833732e69e31a79facc6 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 15:01:33 +0200 Subject: [PATCH 105/338] added a test for plan sorting and fixed a bug --- _test/plan.test.php | 70 +++++++++++++++++++++++++++++++++++++++++++++ helper/plan.php | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 _test/plan.test.php diff --git a/_test/plan.test.php b/_test/plan.test.php new file mode 100644 index 0000000..96e1f9b --- /dev/null +++ b/_test/plan.test.php @@ -0,0 +1,70 @@ +addPageNamespaceMove('animals:mammals:bear', 'animals:mammals:cute:bear'); + $plan->addPageNamespaceMove('humans:programmers', 'animals:mammals:cute:programmers'); + $plan->addPageMove('humans:programmers:andi', 'animals:insects:butterfly:andi'); + $plan->addPageMove('yeti', 'humans:yeti'); + $plan->addPageMove('animals:monkey', 'monkey'); + + $sorted = $plan->sortedPlan(); + + $this->assertEquals(5, count($sorted)); + $this->assertEquals('humans:programmers:andi', $sorted[4]['src']); + $this->assertEquals('animals:monkey', $sorted[3]['src']); + $this->assertEquals('yeti', $sorted[2]['src']); + $this->assertEquals('animals:mammals:bear', $sorted[1]['src']); + $this->assertEquals('humans:programmers', $sorted[0]['src']); + } + +} + +/** + * Class test_helper_plugin_move_plan + * + * gives access to some internal stuff of the class + */ +class test_helper_plugin_move_plan extends helper_plugin_move_plan { + + /** + * Access the sorted plan + * + * @return array + */ + function sortedPlan() { + usort($this->plan, array($this, 'planSorter')); + return $this->plan; + } +} \ No newline at end of file diff --git a/helper/plan.php b/helper/plan.php index bcc0b4f..d423a8e 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -723,7 +723,7 @@ public function planSorter($a, $b) { // we sort by depth of namespace, deepest namespaces first $alen = substr_count($a['src'], ':'); - $blen = substr_count($a['src'], ':'); + $blen = substr_count($b['src'], ':'); if($alen > $blen) { return 1; From 7d5764346e14d8323489110b38045bbd793a9cac Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 16:12:42 +0200 Subject: [PATCH 106/338] some tests for the plan and some remodeling of the same --- _test/plan.test.php | 92 +++++++++++++++++-------- helper/plan.php | 159 +++++++++++++++++++++++++------------------- 2 files changed, 156 insertions(+), 95 deletions(-) diff --git a/_test/plan.test.php b/_test/plan.test.php index 96e1f9b..542cd54 100644 --- a/_test/plan.test.php +++ b/_test/plan.test.php @@ -1,31 +1,41 @@ sortedPlan(); + // the plan is sorted FORWARD (first things first) $this->assertEquals(5, count($sorted)); - $this->assertEquals('humans:programmers:andi', $sorted[4]['src']); - $this->assertEquals('animals:monkey', $sorted[3]['src']); + $this->assertEquals('humans:programmers:andi', $sorted[0]['src']); + $this->assertEquals('animals:monkey', $sorted[1]['src']); $this->assertEquals('yeti', $sorted[2]['src']); - $this->assertEquals('animals:mammals:bear', $sorted[1]['src']); - $this->assertEquals('humans:programmers', $sorted[0]['src']); + $this->assertEquals('animals:mammals:bear', $sorted[3]['src']); + $this->assertEquals('humans:programmers', $sorted[4]['src']); } + /** + * Move a page out of a namespace and then move the namespace elsewhere + */ + function test_pageinnamespace() { + $plan = new test_helper_plugin_move_plan(); + + $plan->addPageNamespaceMove('animals:mammals:cute', 'animals:mammals:funny'); + $plan->addPageMove('animals:mammals:cute:otter', 'animals:mammals:otter'); + + $plan->commit(); + $list = $plan->getList('pagelist'); + + // the files are sorted BACKWARDS (first things last) + $this->assertEquals(3, count($list)); + $this->assertEquals("animals:mammals:cute:otter\tanimals:mammals:otter", trim($list[2])); + $this->assertEquals("animals:mammals:cute:cat\tanimals:mammals:funny:cat", trim($list[1])); + $this->assertEquals("animals:mammals:cute:dog\tanimals:mammals:funny:dog", trim($list[0])); + + } } /** @@ -67,4 +97,14 @@ function sortedPlan() { usort($this->plan, array($this, 'planSorter')); return $this->plan; } + + /** + * Get the full saved list specified by name + * + * @param $name + * @return array + */ + function getList($name) { + return file($this->files[$name]); + } } \ No newline at end of file diff --git a/helper/plan.php b/helper/plan.php index d423a8e..77bcd84 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -13,7 +13,13 @@ * Class helper_plugin_move_plan * * This thing prepares and keeps progress info on complex move operations (eg. where more than a single - * object is affected. + * object is affected). + * + * Please note: this has not a complex move resolver. Move operations may not depend on each other (eg. you + * can not use a namespace as source that will only be created by a different move operation) instead all given + * operations should be operations on the current state to come to a wanted future state. The tree manager takes + * care of that by abstracting all moves on a DOM representation first, then submitting the needed changes (eg. + * differences between now and wanted). * * Glossary: * @@ -25,8 +31,8 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { const TYPE_PAGES = 1; const TYPE_MEDIA = 2; - const CLASS_NS = 4; - const CLASS_DOC = 8; + const CLASS_NS = 4; + const CLASS_DOC = 8; /** * @var array the options for this move plan @@ -43,6 +49,15 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { */ protected $plan = array(); + /** + * @var array temporary holder of document lists + */ + protected $tmpstore = array( + 'pages' => array(), + 'media' => array(), + 'ns' => array(), + ); + /** * Constructor * @@ -95,7 +110,7 @@ protected function loadOptions() { // merge whatever options are saved currently $file = $this->files['opts']; if(file_exists($file)) { - $options = unserialize(io_readFile($file, false)); + $options = unserialize(io_readFile($file, false)); $this->options = array_merge($this->options, $options); } } @@ -267,11 +282,7 @@ public function commit() { foreach($this->plan as $move) { if($move['class'] == self::CLASS_DOC) { // these can just be added - if($move['type'] == self::TYPE_PAGES) { - $this->addToPageList($move['src'], $move['dst']); - } else { - $this->addToMediaList($move['src'], $move['dst']); - } + $this->addToDocumentList($move['src'], $move['dst'], $move['type']); } else { // here we need a list of content first, search for it $docs = array(); @@ -294,13 +305,8 @@ public function commit() { // now add all the found documents to our lists foreach($docs as $doc) { $from = $doc['id']; - $to = $move['dst'] . substr($doc['id'], $strip); - - if($move['type'] == self::TYPE_PAGES) { - $this->addToPageList($from, $to); - } else { - $this->addToMediaList($from, $to); - } + $to = $move['dst'] . substr($doc['id'], $strip); + $this->addToDocumentList($from, $to, $move['type']); } // remember the namespace move itself @@ -308,11 +314,13 @@ public function commit() { // FIXME we use this to move namespace subscriptions later on and for now only do it on // page namespace moves, but subscriptions work for both, but what when only one of // them is moved? Should it be copied then? Complicated. This is good enough for now - $this->addToNamespaceList($move['src'], $move['dst']); + $this->addToDocumentList($move['src'], $move['dst'], self::CLASS_NS); } } } + $this->storeDocumentLists(); + if(!$this->options['pages_all'] && !$this->options['media_all']) { msg($this->getLang('noaction'), -1); return false; @@ -320,6 +328,7 @@ public function commit() { $this->options['commited'] = true; $this->saveOptions(); + return true; } @@ -434,14 +443,14 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, &$skip = false $MoveOperator = plugin_load('helper', 'move_op'); if($type == self::TYPE_PAGES) { - $file = $this->files['pagelist']; - $mark = 'P'; - $call = 'movePage'; + $file = $this->files['pagelist']; + $mark = 'P'; + $call = 'movePage'; $counter = 'pages_num'; } else { - $file = $this->files['medialist']; - $mark = 'M'; - $call = 'moveMedia'; + $file = $this->files['medialist']; + $mark = 'M'; + $call = 'moveMedia'; $counter = 'media_num'; } @@ -565,7 +574,7 @@ protected function storeError() { global $MSG; if(is_array($MSG) && count($MSG)) { - $last = array_shift($MSG); + $last = array_shift($MSG); $this->options['lasterror'] = $last['msg']; unset($GLOBALS['MSG']); } else { @@ -596,49 +605,64 @@ public function getLastError() { /** * Appends a page move operation in the list file * + * If the src has been added before, this is ignored. This makes sure you can move a single page + * out of a namespace first, then move the namespace somewhere else. + * * @param string $src * @param string $dst - * @return bool + * @param int $type + * @throws Exception */ - protected function addToPageList($src, $dst) { - $file = $this->files['pagelist']; + protected function addToDocumentList($src, $dst, $type = self::TYPE_PAGES) { + if($type == self::TYPE_PAGES) { + $store = 'pages'; + } else if($type == self::TYPE_MEDIA) { + $store = 'media'; + } else if($type == self::CLASS_NS) { + $store = 'ns'; + } else { + throw new Exception('Unknown type '.$type); + } - if(io_saveFile($file, "$src\t$dst\n", true)) { - $this->options['pages_all']++; - $this->options['pages_run']++; - return true; + if(!isset($this->tmpstore[$store][$src])) { + $this->tmpstore[$store][$src] = $dst; } - return false; } /** - * Appends a media move operation in the list file + * Store the aggregated document lists in the file system and reset the internal storage * - * @param string $src - * @param string $dst - * @return bool + * @throws Exception */ - protected function addToMediaList($src, $dst) { - $file = $this->files['medialist']; + protected function storeDocumentLists() { + $lists = array( + 'pages' => $this->files['pagelist'], + 'media' => $this->files['medialist'], + 'ns' => $this->files['namespaces'] + ); - if(io_saveFile($file, "$src\t$dst\n", true)) { - $this->options['media_all']++; - $this->options['media_run']++; - return true; - } - return false; - } + foreach($lists as $store => $file) { + // anything to do? + $count = count($this->tmpstore[$store]); + if(!$count) continue; - /** - * Appends a namespace move operation in the list file - * - * @param string $src - * @param string $dst - * @return bool - */ - protected function addToNamespaceList($src, $dst) { - $file = $this->files['namespaces']; - return io_saveFile($file, "$src\t$dst\n", true); + // prepare and save content + $data = ''; + $this->tmpstore[$store] = array_reverse($this->tmpstore[$store]); // store in reverse order + foreach($this->tmpstore[$store] as $src => $dst) { + $data .= "$src\t$dst\n"; + } + io_saveFile($file, $data); + + // set counters + if($store != 'ns') { + $this->options[$store . '_all'] = $count; + $this->options[$store . '_run'] = $count; + } + + // reset the list + $this->tmpstore[$store] = array(); + } } /** @@ -695,9 +719,6 @@ protected function getLastLine($handle) { /** * Callback for usort to sort the move plan * - * Note that later on all lists will be worked on in reversed order, so we reverse what we - * do from what we want here - * * @param $a * @param $b * @return int @@ -705,18 +726,18 @@ protected function getLastLine($handle) { public function planSorter($a, $b) { // do page moves before namespace moves if($a['class'] == self::CLASS_DOC && $b['class'] == self::CLASS_NS) { - return 1; + return -1; } if($a['class'] == self::CLASS_NS && $b['class'] == self::CLASS_DOC) { - return -1; + return 1; } // do pages before media if($a['type'] == self::TYPE_PAGES && $b['type'] == self::TYPE_MEDIA) { - return 1; + return -1; } if($a['type'] == self::TYPE_MEDIA && $b['type'] == self::TYPE_PAGES) { - return -1; + return 1; } // from here on we compare only apples to apples @@ -726,9 +747,9 @@ public function planSorter($a, $b) { $blen = substr_count($b['src'], ':'); if($alen > $blen) { - return 1; - } elseif($alen < $blen) { return -1; + } elseif($alen < $blen) { + return 1; } return 0; } @@ -747,15 +768,15 @@ protected function log($type, $from, $to, $success) { global $MSG; $optime = $this->options['started']; - $file = $conf['cachedir'] . '/move-' . $optime . '.log'; - $now = time(); - $date = date('Y-m-d H:i:s', $now); // for human readability + $file = $conf['cachedir'] . '/move-' . $optime . '.log'; + $now = time(); + $date = date('Y-m-d H:i:s', $now); // for human readability if($success) { - $ok = 'success'; + $ok = 'success'; $msg = ''; } else { - $ok = 'failed'; + $ok = 'failed'; $msg = $MSG[count($MSG) - 1]['msg']; // get detail from message array } From 8f940a7d8413fb31566339ef7648980903e886a1 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 16:37:05 +0200 Subject: [PATCH 107/338] make sure AJAX backends are only available for managers --- action/progress.php | 12 +++++++++--- action/tree.php | 10 +++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/action/progress.php b/action/progress.php index 274ee3f..5120a15 100644 --- a/action/progress.php +++ b/action/progress.php @@ -33,9 +33,15 @@ public function handle_ajax(Doku_Event $event) { $event->stopPropagation(); global $INPUT; + global $USERINFO; + + if(!auth_ismanager($_SERVER['REMOTE_USER'], $USERINFO['grps'])) { + http_status(403); + exit; + } $return = array( - 'error' => '', + 'error' => '', 'complete' => false, 'progress' => 0 ); @@ -47,9 +53,9 @@ public function handle_ajax(Doku_Event $event) { // There is no plan. Something went wrong $return['complete'] = true; } else { - $todo = $plan->nextStep($INPUT->bool('skip')); + $todo = $plan->nextStep($INPUT->bool('skip')); $return['progress'] = $plan->getProgress(); - $return['error'] = $plan->getLastError(); + $return['error'] = $plan->getLastError(); if($todo === 0) $return['complete'] = true; } diff --git a/action/tree.php b/action/tree.php index f3ce0ab..644c978 100644 --- a/action/tree.php +++ b/action/tree.php @@ -33,15 +33,19 @@ public function handle_ajax_call(Doku_Event $event, $params) { $event->preventDefault(); $event->stopPropagation(); - //FIXME user auth - global $INPUT; + global $USERINFO; + + if(!auth_ismanager($_SERVER['REMOTE_USER'], $USERINFO['grps'])) { + http_status(403); + exit; + } /** @var admin_plugin_move_tree $plugin */ $plugin = plugin_load('admin', 'move_tree'); $ns = cleanID($INPUT->str('ns')); - if($INPUT->bool('is_media')){ + if($INPUT->bool('is_media')) { $type = admin_plugin_move_tree::TYPE_MEDIA; } else { $type = admin_plugin_move_tree::TYPE_PAGES; From d8376248854319330c3c97334758d220ff437050 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 16 Apr 2014 16:59:44 +0200 Subject: [PATCH 108/338] added simple ID cleaning in the tree script --- script/tree.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/script/tree.js b/script/tree.js index 0003e5d..8b06fa2 100644 --- a/script/tree.js +++ b/script/tree.js @@ -49,6 +49,22 @@ var determineNewID = function($li) { } }; +/** + * Very simplistic cleanID() in JavaScript + * + * Strips out namespaces + */ +var cleanID = function (id) { + if (!id) return ''; + + id = id.replace(/[!"#$%§&\'()+,/;<=>?@\[\]^`\{|\}~\\;:\/\*]+/g, '_'); + id = id.replace(/^_+/, ''); + id = id.replace(/_+$/, ''); + id = id.toLowerCase(); + + return id; +}; + /** * Attach event listeners to the tree */ @@ -90,6 +106,7 @@ $GUI.find('ul.tree_list') var $a = $clicky.parent().find('a'); var newname = window.prompt(LANG.plugins.move.renameitem, $li.attr('data-name')); + newname = cleanID(newname); if(newname) { $li.attr('data-name', newname); $a.text(newname); From a2a801eef43266e94e39d3b3b655c91ecc2d9292 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 17 Apr 2014 10:41:02 +0200 Subject: [PATCH 109/338] gather affected pages on plan commit this fixes the weirdness of the progress bar it also should take links to missing pages into account on the preview already, but the actual implementation is still missing --- helper/plan.php | 149 +++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 71 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 77bcd84..8e467e7 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -158,13 +158,16 @@ public function setOption($name, $value) { public function getProgress() { $max = $this->options['pages_all'] + - $this->options['media_all'] + - $this->options['affpg_all']; + $this->options['media_all']; $remain = $this->options['pages_run'] + - $this->options['media_run'] + - $this->options['affpg_run']; + $this->options['media_run']; + + if($this->options['autorewrite']) { + $max += $this->options['affpg_all']; + $remain += $this->options['affpg_run']; + } if($max == 0) return 0; return round((($max - $remain) * 100) / $max, 2); @@ -317,6 +320,8 @@ public function commit() { $this->addToDocumentList($move['src'], $move['dst'], self::CLASS_NS); } } + // store what pages are affected by this move + $this->findAffectedPages($move['src'], $move['class'], $move['type']); } $this->storeDocumentLists(); @@ -357,14 +362,14 @@ public function nextStep($skip = false) { return max($todo, 1); // force one more call } - if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { - $todo = $this->stepThroughAffectedPages(); + if(@filesize($this->files['namespaces']) > 1) { + $todo = $this->stepThroughNamespaces(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } - if(@filesize($this->files['namespaces']) > 1) { - $todo = $this->stepThroughNamespaces(); + if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { + $todo = $this->stepThroughAffectedPages(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } @@ -377,16 +382,11 @@ public function nextStep($skip = false) { /** * Returns the list of page and media moves and the affected pages as a HTML list * - * @fixme This will gather affected pages on its own, maybe it would be better to make this somehow part of - * commit() process as it would also make the progress bar behave better - * * @return string */ public function previewHTML() { $html = ''; - $affected = array(); - $html .= '
      '; if(@file_exists($this->files['pagelist'])) { $pagelist = file($this->files['pagelist']); @@ -398,9 +398,6 @@ public function previewHTML() { $html .= '→'; $html .= hsc($new); $html .= '
    '; - - // get all pages linking to the original page - $affected = array_merge($affected, idx_get_indexer()->lookupKey('relation_references', $old)); } } if(@file_exists($this->files['medialist'])) { @@ -413,18 +410,16 @@ public function previewHTML() { $html .= '→'; $html .= hsc($new); $html .= '
    '; - - // get all pages using this media - $affected = array_merge($affected, idx_get_indexer()->lookupKey('relation_media', $old)); } } - $affected = array_unique($affected); - sort($affected); - foreach($affected as $page) { - $html .= '
  • '; - $html .= '↷'; - $html .= hsc($page); - $html .= '
  • '; + if(@file_exists($this->files['affected'])) { + $medialist = file($this->files['affected']); + foreach($medialist as $page) { + $html .= '
  • '; + $html .= '↷'; + $html .= hsc($page); + $html .= '
  • '; + } } $html .= ''; @@ -446,12 +441,12 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, &$skip = false $file = $this->files['pagelist']; $mark = 'P'; $call = 'movePage'; - $counter = 'pages_num'; + $counter = 'pages_run'; } else { $file = $this->files['medialist']; $mark = 'M'; $call = 'moveMedia'; - $counter = 'media_num'; + $counter = 'media_run'; } $doclist = fopen($file, 'a+'); @@ -474,9 +469,6 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, &$skip = false return false; } else { $this->log($mark, $src, $dst, true); // SUCCESS! - - // remember affected pages - $this->addToAffectedPagesList($MoveOperator->getAffectedPages()); } /* @@ -503,22 +495,6 @@ protected function stepThroughAffectedPages() { /** @var helper_plugin_move_rewrite $Rewriter */ $Rewriter = plugin_load('helper', 'move_rewrite'); - // if this is the first run, clean up the file and remove duplicates - if($this->options['affpg_all'] == $this->options['affpg_num']) { - $affected = io_readFile($this->files['affected']); - $affected = explode("\n", $affected); - $affected = array_unique($affected); - $affected = array_filter($affected); - sort($affected); - if($affected[0] === '') array_shift($affected); - io_saveFile($this->files['affected'], join("\n", $affected)); - - $this->options['affpg_all'] = count($affected); - $this->options['affpg_num'] = $this->options['affpg_all']; - - $this->saveOptions(); - } - // handle affected pages $doclist = fopen($this->files['affected'], 'a+'); for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { @@ -530,19 +506,20 @@ protected function stepThroughAffectedPages() { // update the list file ftruncate($doclist, ftell($doclist)); - $this->options['affpg_num']--; + $this->options['affpg_run']--; $this->saveOptions(); } fclose($doclist); - return $this->options['affpg_num']; + return $this->options['affpg_run']; } /** * Step through all the namespace moves * - * Currently moves namespace subscriptions only. This does not step, but handles all namespaces - * in one step. + * This does not step currently, but handles all namespaces in one step. + * + * Currently moves namespace subscriptions only. * * @return int always 0 * @todo maybe add an event so plugins can move more stuff? @@ -621,7 +598,7 @@ protected function addToDocumentList($src, $dst, $type = self::TYPE_PAGES) { } else if($type == self::CLASS_NS) { $store = 'ns'; } else { - throw new Exception('Unknown type '.$type); + throw new Exception('Unknown type ' . $type); } if(!isset($this->tmpstore[$store][$src])) { @@ -629,6 +606,47 @@ protected function addToDocumentList($src, $dst, $type = self::TYPE_PAGES) { } } + /** + * Add the list of pages to the list of affected pages whose links need adjustment + * + * @param string|array $pages + */ + protected function addToAffectedPagesList($pages) { + if(!is_array($pages)) $pages = array($pages); + + foreach($pages as $page) { + if(!isset($this->tmpstore['affpg'][$page])) { + $this->tmpstore['affpg'][$page] = true; + } + } + } + + /** + * Looks up pages that will be affected by a move of $src + * + * Calls addToAffectedPagesList() directly to store the result + * + * @param string $src + * @param int $class + * @param int $type + */ + protected function findAffectedPages($src, $class, $type) { + $idx = idx_get_indexer(); + + if($class == self::CLASS_NS) { + $src = "$src:*"; // use wildcard lookup for namespaces + } + + $pages = array(); + if($type == self::TYPE_PAGES) { + $pages = $idx->lookupKey('relation_references', $src); + } else if($type == self::TYPE_MEDIA) { + $pages = $idx->lookupKey('relation_media', $src); + } + + $this->addToAffectedPagesList($pages); + } + /** * Store the aggregated document lists in the file system and reset the internal storage * @@ -638,7 +656,8 @@ protected function storeDocumentLists() { $lists = array( 'pages' => $this->files['pagelist'], 'media' => $this->files['medialist'], - 'ns' => $this->files['namespaces'] + 'ns' => $this->files['namespaces'], + 'affpg' => $this->files['affected'] ); foreach($lists as $store => $file) { @@ -650,7 +669,12 @@ protected function storeDocumentLists() { $data = ''; $this->tmpstore[$store] = array_reverse($this->tmpstore[$store]); // store in reverse order foreach($this->tmpstore[$store] as $src => $dst) { - $data .= "$src\t$dst\n"; + if($dst === true) { + $data .= "$src\n"; // for affected pages only one ID is saved + } else { + $data .= "$src\t$dst\n"; + } + } io_saveFile($file, $data); @@ -665,23 +689,6 @@ protected function storeDocumentLists() { } } - /** - * Add the list of pages to the list of affected pages whose links need adjustment - * - * This is only done when autorewrite is enabled, otherwise we don't need to track - * those pages - * - * @param array $pages - * @return bool - */ - protected function addToAffectedPagesList($pages) { - if(!$this->options['autorewrite']) return false; - - $this->options['affpg_all'] += count($pages); - $this->options['affpg_num'] = $this->options['affpg_all']; - return io_saveFile($this->files['affected'], join("\n", $pages) . "\n", true); - } - /** * Get the last line from the list that is stored in the file that is referenced by the handle * The handle is set to the newline before the file id From bd13134c8c38fc5b968c52cbee493283087088e2 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 17 Apr 2014 16:01:41 +0200 Subject: [PATCH 110/338] make sure the tree manager does not create duplicate entries --- lang/en/lang.php | 1 + script/tree.js | 59 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/lang/en/lang.php b/lang/en/lang.php index 8aac2cd..b7a4b38 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -69,3 +69,4 @@ $lang['noscript'] = 'This feature requires JavaScript'; $lang['moveinprogress'] = 'There is another move operation in progress currently, you can\'t use this tool right now.'; $lang['js']['renameitem'] = 'Rename this item'; +$lang['js']['duplicate'] = 'Sorry, "%s" already exists in this namespace.'; diff --git a/script/tree.js b/script/tree.js index 8b06fa2..fccab69 100644 --- a/script/tree.js +++ b/script/tree.js @@ -12,19 +12,19 @@ jQuery('#plugin_move__treelink').show(); * * Moved elements are highlighted and a title shows where they came from * - * @param $li + * @param {jQuery} $li */ -var checkForMovement = function($li) { +var checkForMovement = function ($li) { // we need to check this LI and all previously moved sub LIs var $all = $li.add($li.find('li.moved')); - $all.each(function(){ + $all.each(function () { var $this = jQuery(this); var oldid = $this.attr('data-id'); var newid = determineNewID($this); if (newid != oldid) { $this.addClass('moved'); - $this.children('div').attr('title', oldid+' -> '+newid); + $this.children('div').attr('title', oldid + ' -> ' + newid); } else { $this.removeClass('moved'); $this.children('div').attr('title', ''); @@ -32,18 +32,40 @@ var checkForMovement = function($li) { }); }; +/** + * Check if the given name is allowed in the given parent + * + * @param {jQuery} $li the edited or moved LI + * @param {string} name the (new) name to check + * @returns {boolean} + */ +var checkNameAllowed = function ($li, name) { + $parent = $li.parent(); + + var ok = true; + $parent.children('li').each(function () { + if (this === $li[0]) return; + var cname = 'type-f'; + if ($li.hasClass('type-d')) cname = 'type-d'; + + var $this = jQuery(this); + if ($this.attr('data-name') == name && $this.hasClass(cname)) ok = false; + }); + return ok; +}; + /** * Returns the new ID of a given list item * - * @param $li + * @param {jQuery} $li * @returns {string} */ -var determineNewID = function($li) { +var determineNewID = function ($li) { var myname = $li.attr('data-name'); var $parent = $li.parent().closest('li'); - if($parent.length) { - return (determineNewID($parent) + ':' + myname).replace(/^:/, ''); + if ($parent.length) { + return (determineNewID($parent) + ':' + myname).replace(/^:/, ''); } else { return myname; } @@ -53,6 +75,8 @@ var determineNewID = function($li) { * Very simplistic cleanID() in JavaScript * * Strips out namespaces + * + * @param {string} id */ var cleanID = function (id) { if (!id) return ''; @@ -103,14 +127,18 @@ $GUI.find('ul.tree_list') } } else if ($clicky[0].tagName == 'IMG') { // Click on IMG - do rename e.stopPropagation(); - var $a = $clicky.parent().find('a'); + var $a = $clicky.parent().find('a'); var newname = window.prompt(LANG.plugins.move.renameitem, $li.attr('data-name')); newname = cleanID(newname); - if(newname) { - $li.attr('data-name', newname); - $a.text(newname); - checkForMovement($li); + if (newname) { + if (checkNameAllowed($li, newname)) { + $li.attr('data-name', newname); + $a.text(newname); + checkForMovement($li); + } else { + alert(LANG.plugins.move.duplicate.replace('%s', newname)); + } } } e.preventDefault(); @@ -119,6 +147,11 @@ $GUI.find('ul.tree_list') .find('ul').sortable({ items: 'li', stop: function (e, ui) { + if (!checkNameAllowed(ui.item, ui.item.attr('data-name'))) { + jQuery(this).sortable('cancel'); + alert(LANG.plugins.move.duplicate.replace('%s', ui.item.attr('data-name'))); + } + checkForMovement(ui.item); } }) From 43da6fb56e2acca4d3d741eb2007bb493640fee4 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 23 Apr 2014 14:43:31 +0200 Subject: [PATCH 111/338] first go at changing the link rewriting this needs a bunch of tests next --- helper/handler.php | 316 ++++++++++++++++++++------------------------- helper/op.php | 30 +---- helper/rewrite.php | 77 ++++++++--- 3 files changed, 205 insertions(+), 218 deletions(-) diff --git a/helper/handler.php b/helper/handler.php index 694672e..677d684 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -16,35 +16,101 @@ */ class helper_plugin_move_handler { public $calls = ''; - public $id; - public $ns; - public $new_id; - public $new_ns; - public $moves; - public $media_moves; - private $handlers; + + protected $id; + protected $ns; + protected $origID; + protected $origNS; + protected $page_moves; + protected $media_moves; + protected $handlers; /** * Construct the move handler. * - * @param string $id The id of the text that is passed to the handler - * @param array $moves Moves that shall be considered in the form $old => $new ($old can be $id) - * @param array $media_moves Moves of media files that shall be considered in the form $old => $new - * @param array $handlers Handlers for plugin content in the form $plugin_anme => $callback + * @param string $id The id of the text that is passed to the handler + * @param string $original The name of the original ID of this page. Same as $id if this page wasn't moved + * @param array $page_moves Moves that shall be considered in the form [[$old,$new],...] ($old can be $original) + * @param array $media_moves Moves of media files that shall be considered in the form $old => $new + * @param array $handlers Handlers for plugin content in the form $plugin_name => $callback */ - public function __construct($id, $moves, $media_moves, $handlers) { - $this->id = $id; - $this->ns = getNS($id); - $this->moves = $moves; + public function __construct($id, $original, $page_moves, $media_moves, $handlers) { + $this->id = $id; + $this->ns = getNS($id); + $this->origID = $original; + $this->origNS = getNS($original); + $this->page_moves = $page_moves; $this->media_moves = $media_moves; - $this->handlers = $handlers; - if (isset($moves[$id])) { - $this->new_id = $moves[$id]; - $this->new_ns = getNS($moves[$id]); + $this->handlers = $handlers; + } + + /** + * Go through the list of moves and find the new value for the given old ID + * + * @param string $old the old, full qualified ID + * @param string $type 'media' or 'page' + * @throws Exception on bad argument + * @return string the new full qualified ID + */ + protected function resolveMoves($old, $type) { + global $conf; + + if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); + + $old = str_replace('/', ':', $old); + $old = resolve_id($this->ns, $old, false); + // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page + // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been + // deleted already + if(substr($old, -1) === ':') $old .= $conf['start']; + $old = cleanID($old); + + foreach($this->page_moves as $move) { + if($move[0] == $old) $old = $move[1]; + } + return $old; // this is now new + } + + /** + * Construct a new ID relative to the current page's location + * + * Uses a relative link only if the original was relative, too. This function is for + * pages and media files. + * + * @param string $relold the old, possibly relative ID + * @param string $new the new, full qualified ID + * @return string + */ + protected function relativeLink($relold, $new) { + // check if the link was relative + if(strpos($relold, ':') === false || $relold{0} == '.') { + $wasrel = true; } else { - $this->new_id = $id; - $this->new_ns = $this->ns; + $wasrel = false; } + // if it wasn't relative then, leave it absolute now, too + if(!$wasrel) return $new; + + // split the paths and see how much common parts there are + $selfpath = explode(':', $this->ns); + $goalpath = explode(':', getNS($new)); + $min = min(count($selfpath), count($goalpath)); + for($common = 0; $common < $min; $common++) { + if($selfpath[$common] != $goalpath[$common]) break; + } + // we now have the non-common part and a number of uppers + $remainder = array_slice($goalpath, $common); + $upper = array_fill(0, $common, '..'); + + // build the new relative path + $newrel = join(':', $upper) . ':' . join(':', $remainder) . ':' . noNS($new); + $newrel = cleanID($newrel); + if($this->ns) $newrel = '.' . $newrel; + + // don't use relative paths if it is ridicoulus: + if(strlen($newrel) > strlen($new)) $newrel = $new; + + return $newrel; } /** @@ -56,30 +122,21 @@ public function __construct($id, $moves, $media_moves, $handlers) { * @return bool If parsing should be continued */ public function camelcaselink($match, $state, $pos) { - if ($this->ns) - $old = cleanID($this->ns.':'.$match); - else - $old = cleanID($match); - if (isset($this->moves[$old]) || $this->id != $this->new_id) { - if (isset($this->moves[$old])) { - $new = $this->moves[$old]; - } else { - $new = $old; - } - $new_ns = getNS($new); - // preserve capitalization either in the link or in the title - if (noNS($new) == noNS($old)) { - // camelcase link still seems to work - if ($new_ns == $this->new_ns) { - $this->calls .= $match; - } else { // just the namespace was changed, the camelcase word is a valid id - $this->calls .= "[[$new_ns:$match]]"; - } + $oldID = cleanID($this->origNS . ':' . $match); + $newID = $this->resolveMoves($oldID, 'page'); + $newNS = getNS($newID); + + if($oldID == $newID || $this->origNS == $newNS) { + // link is still valid as is + $this->calls .= $match; + } else { + if(noNS($oldID) == noNS($newID)) { + // only namespace changed, keep CamelCase in link + $this->calls .= "[[$newNS:$match]]"; } else { - $this->calls .= "[[$new|$match]]"; + // all new, keep CamelCase in title + $this->calls .= "[[$newID|$match]]"; } - } else { - $this->calls .= $match; } return true; } @@ -94,16 +151,16 @@ public function camelcaselink($match, $state, $pos) { */ public function internallink($match, $state, $pos) { // Strip the opening and closing markup - $link = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match); + $link = preg_replace(array('/^\[\[/', '/\]\]$/u'), '', $match); // Split title from URL - $link = explode('|',$link,2); - if ( !isset($link[1]) ) { - $link[1] = NULL; - } else if ( preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) { + $link = explode('|', $link, 2); + if(!isset($link[1])) { + $link[1] = null; + } else if(preg_match('/^\{\{[^\}]+\}\}$/', $link[1])) { // If the title is an image, rewrite it $old_title = $link[1]; - $link[1] = $this->rewrite_media($link[1]); + $link[1] = $this->rewrite_media($link[1]); // do a simple replace of the first match so really only the id is changed and not e.g. the alignment $oldpos = strpos($match, $old_title); $oldlen = strlen($old_title); @@ -111,66 +168,64 @@ public function internallink($match, $state, $pos) { } $link[0] = trim($link[0]); - //decide which kind of link it is - if ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$link[0]) ) { + if(preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u', $link[0])) { // Interwiki $this->calls .= $match; - }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) { + } elseif(preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u', $link[0])) { // Windows Share $this->calls .= $match; - }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) { + } elseif(preg_match('#^([a-z0-9\-\.+]+?)://#i', $link[0])) { // external link (accepts all protocols) $this->calls .= $match; - }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) { + } elseif(preg_match('<' . PREG_PATTERN_VALID_EMAIL . '>', $link[0])) { // E-Mail (pattern above is defined in inc/mail.php) $this->calls .= $match; - }elseif ( preg_match('!^#.+!',$link[0]) ){ - // local link + } elseif(preg_match('!^#.+!', $link[0])) { + // local hash link $this->calls .= $match; - }else{ + } else { $id = $link[0]; - $hash = ''; + $hash = ''; $parts = explode('#', $id, 2); - if (count($parts) === 2) { - $id = $parts[0]; + if(count($parts) === 2) { + $id = $parts[0]; $hash = $parts[1]; } $params = ''; - $parts = explode('?', $id, 2); - if (count($parts) === 2) { - $id = $parts[0]; + $parts = explode('?', $id, 2); + if(count($parts) === 2) { + $id = $parts[0]; $params = $parts[1]; } + $new_id = $this->resolveMoves($id, 'page'); + $new_id = $this->relativeLink($id, $new_id); - $new_id = $this->adaptRelativeId($id); - - if ($id == $new_id) { + if($id == $new_id) { $this->calls .= $match; } else { - if ($params !== '') { - $new_id.= '?'.$params; + if($params !== '') { + $new_id .= '?' . $params; } - if ($hash !== '') { - $new_id .= '#'.$hash; + if($hash !== '') { + $new_id .= '#' . $hash; } - if ($link[1] != NULL) { - $new_id .= '|'.$link[1]; + if($link[1] != null) { + $new_id .= '|' . $link[1]; } - $this->calls .= '[['.$new_id.']]'; + $this->calls .= '[[' . $new_id . ']]'; } } return true; - } /** @@ -194,9 +249,12 @@ public function media($match, $state, $pos) { */ protected function rewrite_media($match) { $p = Doku_Handler_Parse_Media($match); - if ($p['type'] == 'internalmedia') { // else: external media - $new_src = $this->adaptRelativeId($p['src'], true); - if ($new_src !== $p['src']) { + if($p['type'] == 'internalmedia') { // else: external media + + $new_src = $this->resolveMoves($p['src'], 'media'); + $new_src = $this->relativeLink($p['src'], $new_src); + + if($new_src !== $p['src']) { // do a simple replace of the first match so really only the id is changed and not e.g. the alignment $srcpos = strpos($match, $p['src']); $srclen = strlen($p['src']); @@ -209,14 +267,14 @@ protected function rewrite_media($match) { /** * Handle rewriting of plugin syntax, calls the registered handlers * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input * @param string $pluginname The name of the plugin * @return bool If parsing should be continued */ public function plugin($match, $state, $pos, $pluginname) { - if (isset($this->handlers[$pluginname])) { + if(isset($this->handlers[$pluginname])) { $this->calls .= call_user_func($this->handlers[$pluginname], $match, $state, $pos, $pluginname, $this); } else { $this->calls .= $match; @@ -227,16 +285,16 @@ public function plugin($match, $state, $pos, $pluginname) { /** * Catchall handler for the remaining syntax * - * @param string $name Function name that was called + * @param string $name Function name that was called * @param array $params Original parameters * @return bool If parsing should be continue */ public function __call($name, $params) { - if (count($params) == 3) { + if(count($params) == 3) { $this->calls .= $params[0]; return true; } else { - trigger_error('Error, handler function '.hsc($name).' with '.count($params).' parameters called which isn\'t implemented', E_USER_ERROR); + trigger_error('Error, handler function ' . hsc($name) . ' with ' . count($params) . ' parameters called which isn\'t implemented', E_USER_ERROR); return false; } } @@ -246,94 +304,4 @@ public function _finalize() { $this->calls = substr($this->calls, 1, -1); } - /** - * Adapts a link respecting all moves and making it a relative link according to the new id - * - * @param string $id A relative id - * @param bool $media If the id is a media id - * @return string The relative id, adapted according to the new/old id and the moves - */ - public function adaptRelativeId($id, $media = false) { - global $conf; - - if ($id === '') { - return $id; - } - - $abs_id = str_replace('/', ':', $id); - $abs_id = resolve_id($this->ns, $abs_id, false); - if (substr($abs_id, -1) === ':') - $abs_id .= $conf['start']; - $clean_id = cleanID($abs_id); - // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page - // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been - // deleted already - if (substr($clean_id, -1) === ':') - $clean_id .= $conf['start']; - - if (($media ? isset($this->media_moves[$clean_id]) : isset($this->moves[$clean_id])) || $this->ns !== $this->new_ns) { - if (!$media && isset($this->moves[$clean_id])) { - $new = $this->moves[$clean_id]; - } elseif ($media && isset($this->media_moves[$clean_id])) { - $new = $this->media_moves[$clean_id]; - } else { - $new = $clean_id; - - // only the namespace was changed so if the link still resolves to the same absolute id, we can skip the rest - $new_abs_id = str_replace('/', ':', $id); - $new_abs_id = resolve_id($this->new_ns, $new_abs_id, false); - if (substr($new_abs_id, -1) === ':') - $new_abs_id .= $conf['start']; - if ($new_abs_id == $abs_id) return $id; - } - $new_link = $new; - $new_ns = getNS($new); - // try to keep original pagename - if ($this->noNS($new) == $this->noNS($clean_id)) { - if ($new_ns == $this->new_ns) { - $new_link = $this->noNS($id); - if ($new_link === false) $new_link = $this->noNS($new); - if ($id == ':') - $new_link = ':'; - else if ($id == '/') - $new_link = '/'; - } else if ($new_ns != false) { - $new_link = $new_ns.':'.$this->noNS($id); - } else { - $new_link = $this->noNS($id); - if ($new_link === false) $new_link = $new; - } - } else if ($new_ns == $this->new_ns) { - $new_link = $this->noNS($new_link); - } else if (strpos($new_ns, $this->ns.':') === 0) { - $new_link = '.:'.substr($new_link, strlen($this->ns)+1); - } - - if ($this->new_ns != '' && $new_ns == false) { - $new_link = ':'.$new_link; - } - - return $new_link; - } else { - return $id; - } - } - - /** - * Remove the namespace from the given id like noNS(), but handles '/' as namespace separator - * @param string $id the id - * @return string the id without the namespace - */ - private function noNS($id) { - $pos = strrpos($id, ':'); - $spos = strrpos($id, '/'); - if ($pos === false) $pos = $spos; - if ($spos === false) $spos = $pos; - $pos = max($pos, $spos); - if ($pos!==false) { - return substr($id, $pos+1); - } else { - return $id; - } - } } diff --git a/helper/op.php b/helper/op.php index c2917fe..3e2bfae 100644 --- a/helper/op.php +++ b/helper/op.php @@ -123,10 +123,7 @@ public function movePage($src, $dst) { $Rewriter = plugin_load('helper', 'move_rewrite'); // remember what this page was called before the move in meta data - $page_meta = $Rewriter->getMoveMeta($src); - if(!$page_meta) $page_meta = array(); - if(!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); - $page_meta['old_ids'][$src] = time(); + $Rewriter->setSelfMoveMeta($src); // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages $affected_pages = idx_get_indexer()->lookupKey('relation_references', $src); @@ -145,7 +142,6 @@ public function movePage($src, $dst) { 'newns' => $dst_ns, 'newname' => $dst_name, ), - 'old_ids' => $page_meta['old_ids'], 'affected_pages' => &$affected_pages, 'src_id' => $src, 'dst_id' => $dst, @@ -154,7 +150,6 @@ public function movePage($src, $dst) { // 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 $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $eventdata); if($event->advise_before()) { lock($src); @@ -162,10 +157,6 @@ public function movePage($src, $dst) { /** @var helper_plugin_move_file $FileMover */ $FileMover = plugin_load('helper', 'move_file'); - // Open the old document and change forward links - $text = rawWiki($src); - $text = $Rewriter->rewrite_content($text, $src, array($src => $dst)); - // Move the Subscriptions & Indexes (new feature since Spring 2013 release) $Indexer = idx_get_indexer(); if(($idx_msg = $Indexer->renamePage($src, $dst)) !== true @@ -194,6 +185,7 @@ public function movePage($src, $dst) { if($oldRev == time()) sleep(1); // Save the updated document in its new location + $text = rawWiki($src); saveWikiText($dst, $text, $summary); // Delete the orginal file @@ -209,16 +201,8 @@ public function movePage($src, $dst) { // Add meta data to all affected pages, so links get updated later foreach($affected_pages as $id) { - if(!page_exists($id, '', false) || $id == $src || $id == $dst) continue; - // we are only interested in persistent metadata, so no need to render anything. - $meta = $Rewriter->getMoveMeta($id); - if(!$meta) $meta = array('moves' => array()); - if(!isset($meta['moves'])) $meta['moves'] = array(); - $meta['moves'] = $Rewriter->resolve_moves($meta['moves'], $id); - $meta['moves'][$src] = $dst; - p_set_metadata($id, array('plugin_move' => $meta), false, true); + $Rewriter->setMoveMeta($id, $src, $dst, 'page'); } - p_set_metadata($dst, array('plugin_move' => $page_meta), false, true); unlock($src); } @@ -303,13 +287,7 @@ public function moveMedia($src, $dst) { // Add meta data to all affected pages, so links get updated later foreach($affected_pages as $id) { - if(!page_exists($id, '', false)) continue; - $meta = $Rewriter->getMoveMeta($id); - if(!$meta) $meta = array('media_moves' => array()); - if(!isset($meta['media_moves'])) $meta['media_moves'] = array(); - $meta['media_moves'] = $Rewriter->resolve_moves($meta['media_moves'], '__'); - $meta['media_moves'][$src] = $dst; - p_set_metadata($id, array('plugin_move' => $meta), false, true); + $Rewriter->setMoveMeta($id, $src, $dst, 'media'); } } $event->advise_after(); diff --git a/helper/rewrite.php b/helper/rewrite.php index 1b1b1ba..8638040 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -20,6 +20,11 @@ */ class helper_plugin_move_rewrite extends DokuWiki_Plugin { + /** + * Under what key is move data to be saved in metadata + */ + const METAKEY = 'plugin_move'; + /** * @var string symbol to make move operations easily recognizable in change log */ @@ -36,23 +41,60 @@ public function getMoveMeta($id) { $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); // migrate old metadata from the pagemove plugin if(isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { - if(isset($all_meta['plugin_move'])) { - $all_meta['plugin_move'] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta['plugin_move']); + if(isset($all_meta[self::METAKEY])) { + $all_meta[self::METAKEY] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta[self::METAKEY]); } else { - $all_meta['plugin_move'] = $all_meta['plugin_pagemove']; + $all_meta[self::METAKEY] = $all_meta['plugin_pagemove']; } - p_set_metadata($id, array('plugin_move' => $all_meta['plugin_move'], 'plugin_pagemove' => null), false, true); + p_set_metadata($id, array(self::METAKEY => $all_meta[self::METAKEY], 'plugin_pagemove' => null), false, true); } - return isset($all_meta['plugin_move']) ? $all_meta['plugin_move'] : null; + return isset($all_meta[self::METAKEY]) ? $all_meta[self::METAKEY] : null; + } + + /** + * Add info about a moved document to the metadata of an affected page + * + * @param string $id affected page + * @param string $src moved document's original id + * @param string $dst moved document's new id + * @param string $type 'media' or 'page' + * @throws Exception on wrong argument + */ + public function setMoveMeta($id, $src, $dst, $type) { + if($type != 'page' && $type != 'media') throw new Exception('wrong type specified'); + if(!page_exists($id, '', false)) return; + + $meta = $this->getMoveMeta($id); + if(!isset($meta[$type])) $meta[$type] = array(); + // FIXME resolve here? + $meta[$type][] = array($src, $dst); + + p_set_metadata($id, array(self::METAKEY => $meta), false, true); + } + + /** + * Store info about the move of a page in its own meta data + * + * This has to be called before the move is executed + * + * @param string $id moved page's original (and still current) id + */ + public function setSelfMoveMeta($id) { + $meta = $this->getMoveMeta($id); + // was this page moved multiple times? keep the orignal name til rewriting occured + if(isset($meta['original']) && $meta['original'] !== '') return; + $meta['original'] = $id; + + p_set_metadata($id, array(self::METAKEY => $meta), false, true); } /** * Rewrite a text in order to fix the content after the given moves. * - * @param string $text The wiki text that shall be rewritten - * @param string $id The id of the wiki page, if the page itself was moved the old id - * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids - * @param array $media_moves Array of all media moves. + * @param string $text The wiki text that shall be rewritten + * @param string $id The id of the wiki page, if the page itself was moved the old id + * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids + * @param array $media_moves Array of all media moves. * @return string The rewritten wiki text */ public function rewrite_content($text, $id, $moves, $media_moves = array()) { @@ -98,7 +140,7 @@ public function rewrite_content($text, $id, $moves, $media_moves = array()) { /** * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. * - * @param array $moves The moves + * @param array $moves The moves * @param string $id * @return array The resolved moves */ @@ -144,31 +186,30 @@ public function execute_rewrites($id, $text = null) { $meta = $this->getMoveMeta($id); if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { if(is_null($text)) $text = rawWiki($id); - $moves = isset($meta['moves']) ? $meta['moves'] : array(); + $moves = isset($meta['moves']) ? $meta['moves'] : array(); $media_moves = isset($meta['media_moves']) ? $meta['media_moves'] : array(); $old_text = $text; - $text = $this->rewrite_content($text, $id, $moves, $media_moves); - $changed = ($old_text != $text); - $file = wikiFN($id, '', false); + $text = $this->rewrite_content($text, $id, $moves, $media_moves); + $changed = ($old_text != $text); + $file = wikiFN($id, '', false); if(is_writable($file) || !$changed) { - if ($changed) { + if($changed) { // Wait a second when the page has just been rewritten $oldRev = filemtime(wikiFN($id)); if($oldRev == time()) sleep(1); - saveWikiText($id, $text, $this->symbol.' '.$this->getLang('linkchange'), $this->getConf('minor')); + saveWikiText($id, $text, $this->symbol . ' ' . $this->getLang('linkchange'), $this->getConf('minor')); } unset($meta['moves']); unset($meta['media_moves']); p_set_metadata($id, array('plugin_move' => $meta), false, true); } else { // FIXME: print error here or fail silently? - msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); } } return $text; } - } \ No newline at end of file From 0377c50e3d3356be61938ba7cf1a3d1ffcd30c0f Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 23 Apr 2014 15:41:13 +0200 Subject: [PATCH 112/338] added test for relative link building --- _test/handler.test.php | 46 ++++++++++++++++++++++++++++++++++++++++++ helper/handler.php | 13 ++++++++---- 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 _test/handler.test.php diff --git a/_test/handler.test.php b/_test/handler.test.php new file mode 100644 index 0000000..81de83a --- /dev/null +++ b/_test/handler.test.php @@ -0,0 +1,46 @@ + 'new1', + 'deep:new2' => '..:new2', + 'new3' => ':new3', // absolute is shorter than relative + 'deep:namespace:deeper:new4' => '.deeper:new4', + 'deep:namespace:deeper:deepest:new5' => '.deeper:deepest:new5', + ); + + foreach($tests as $new => $rel) { + $this->assertEquals($rel, $handler->relativeLink('foo', $new)); + } + + } + + +} + + +/** + * Class test_helper_plugin_move_handler + * + * gives access to some internal stuff of the class + */ +class test_helper_plugin_move_handler extends helper_plugin_move_handler { + public function relativeLink($relold, $new) { + return parent::relativeLink($relold, $new); + } +} \ No newline at end of file diff --git a/helper/handler.php b/helper/handler.php index 677d684..b6f2327 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -98,17 +98,22 @@ protected function relativeLink($relold, $new) { for($common = 0; $common < $min; $common++) { if($selfpath[$common] != $goalpath[$common]) break; } + // we now have the non-common part and a number of uppers + $ups = max(count($selfpath) - $common, 0); $remainder = array_slice($goalpath, $common); - $upper = array_fill(0, $common, '..'); + $upper = $ups ? array_fill(0, $ups, '..') : array(); // build the new relative path $newrel = join(':', $upper) . ':' . join(':', $remainder) . ':' . noNS($new); - $newrel = cleanID($newrel); - if($this->ns) $newrel = '.' . $newrel; + $newrel = str_replace('::', ':', trim($newrel, ':')); + if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; // don't use relative paths if it is ridicoulus: - if(strlen($newrel) > strlen($new)) $newrel = $new; + if(strlen($newrel) > strlen($new)){ + $newrel = $new; + if($this->ns && !getNS($new)) $newrel = ':'.$newrel; + } return $newrel; } From 1028115c6bd8f99214d22a12848d09811bc892cc Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 23 Apr 2014 16:24:48 +0200 Subject: [PATCH 113/338] added test for page resolving --- _test/handler.test.php | 39 ++++++++++++++++++++++++++++++++++++--- helper/handler.php | 11 +++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index 81de83a..f7ce87c 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -13,8 +13,7 @@ class plugin_move_handler_test extends DokuWikiTest { public function test_relativeLink() { - - $handler = new test_helper_plugin_move_handler('deep:namespace:page', 'deep:namespace:page', array(), array(), array()); + $handler = new test_helper_plugin_move_handler('deep:namespace:page', 'used:to:be:here', array(), array(), array()); $tests = array( 'deep:namespace:new1' => 'new1', @@ -27,9 +26,38 @@ public function test_relativeLink() { foreach($tests as $new => $rel) { $this->assertEquals($rel, $handler->relativeLink('foo', $new)); } - } + public function test_resolveMoves() { + $handler = new test_helper_plugin_move_handler( + 'deep:namespace:page', + 'used:to:be:here', + array( + array('used:to:be:here', 'deep:namespace:page'), + array('foo', 'bar'), + array('used:to:be:this1', 'used:to:be:that1'), + array('used:to:be:this2', 'deep:namespace:that1'), + array('used:to:be:this3', 'deep:that3'), + array('deep:that3', 'but:got:moved3'), + ), + array(), + array() + ); + + $tests = array( + 'used:to:be:here' => 'deep:namespace:page', // full link to self + ':foo' => 'bar', // absolute link that moved + ':bang' => 'bang', // absolute link that did not move + 'foo' => 'used:to:be:foo', // relative link that did not move + 'this1' => 'used:to:be:that1', // relative link that did not move but is in move list + 'this2' => 'deep:namespace:that1', // relative link that moved + 'this3' => 'but:got:moved3', // relative link that moved twice + ); + + foreach($tests as $match => $id) { + $this->assertEquals($id, $handler->resolveMoves($match, 'page')); + } + } } @@ -43,4 +71,9 @@ class test_helper_plugin_move_handler extends helper_plugin_move_handler { public function relativeLink($relold, $new) { return parent::relativeLink($relold, $new); } + + public function resolveMoves($old, $type) { + return parent::resolveMoves($old, $type); + } + } \ No newline at end of file diff --git a/helper/handler.php b/helper/handler.php index b6f2327..6f96633 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -58,14 +58,21 @@ protected function resolveMoves($old, $type) { if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); $old = str_replace('/', ':', $old); - $old = resolve_id($this->ns, $old, false); + $old = resolve_id($this->origNS, $old, false); + // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been // deleted already if(substr($old, -1) === ':') $old .= $conf['start']; $old = cleanID($old); - foreach($this->page_moves as $move) { + if($type == 'page') { + $moves = $this->page_moves; + } else { + $moves = $this->media_moves; + } + + foreach($moves as $move) { if($move[0] == $old) $old = $move[1]; } return $old; // this is now new From a7fb2e9fb1dc90d038b0acd4649ad9885b17c778 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 23 Apr 2014 19:30:53 +0200 Subject: [PATCH 114/338] some more reworkig the rewrite stuff --- _test/handler.test.php | 21 +------ action/rewrite.php | 6 +- helper/handler.php | 42 +++++++------- helper/op.php | 2 +- helper/plan.php | 2 +- helper/rewrite.php | 125 +++++++++++++++++------------------------ 6 files changed, 81 insertions(+), 117 deletions(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index f7ce87c..4b1f5f3 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -13,7 +13,7 @@ class plugin_move_handler_test extends DokuWikiTest { public function test_relativeLink() { - $handler = new test_helper_plugin_move_handler('deep:namespace:page', 'used:to:be:here', array(), array(), array()); + $handler = new helper_plugin_move_handler('deep:namespace:page', 'used:to:be:here', array(), array(), array()); $tests = array( 'deep:namespace:new1' => 'new1', @@ -29,7 +29,7 @@ public function test_relativeLink() { } public function test_resolveMoves() { - $handler = new test_helper_plugin_move_handler( + $handler = new helper_plugin_move_handler( 'deep:namespace:page', 'used:to:be:here', array( @@ -60,20 +60,3 @@ public function test_resolveMoves() { } } - - -/** - * Class test_helper_plugin_move_handler - * - * gives access to some internal stuff of the class - */ -class test_helper_plugin_move_handler extends helper_plugin_move_handler { - public function relativeLink($relold, $new) { - return parent::relativeLink($relold, $new); - } - - public function resolveMoves($old, $type) { - return parent::resolveMoves($old, $type); - } - -} \ No newline at end of file diff --git a/action/rewrite.php b/action/rewrite.php index f2ddcc0..d6eff96 100644 --- a/action/rewrite.php +++ b/action/rewrite.php @@ -36,7 +36,7 @@ function handle_read(Doku_Event $event, $param) { if($event->data[3]) return; $id = $event->data[2]; - if($event->data[1]) $id = $event->data[1].':'.$id; + if($event->data[1]) $id = $event->data[1] . ':' . $id; if(!$id) { // try to reconstruct the id from the filename @@ -64,7 +64,7 @@ function handle_read(Doku_Event $event, $param) { $helper = plugin_load('helper', 'move_rewrite', true); if(!is_null($helper)) { $stack[$id] = true; - $event->result = $helper->execute_rewrites($id, $event->result); + $event->result = $helper->rewritePage($id, $event->result); unset($stack[$id]); } } @@ -95,7 +95,7 @@ function handle_cache(Doku_Event $event, $param) { if(is_writable($file)) $cache->depends['purge'] = true; else // FIXME: print error here or fail silently? - msg('Error: Page '.hsc($id).' needs to be rewritten because of page renames but is not writable.', -1); + msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); } } } diff --git a/helper/handler.php b/helper/handler.php index 6f96633..c4270b9 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -28,11 +28,11 @@ class helper_plugin_move_handler { /** * Construct the move handler. * - * @param string $id The id of the text that is passed to the handler - * @param string $original The name of the original ID of this page. Same as $id if this page wasn't moved - * @param array $page_moves Moves that shall be considered in the form [[$old,$new],...] ($old can be $original) - * @param array $media_moves Moves of media files that shall be considered in the form $old => $new - * @param array $handlers Handlers for plugin content in the form $plugin_name => $callback + * @param string $id The id of the text that is passed to the handler + * @param string $original The name of the original ID of this page. Same as $id if this page wasn't moved + * @param array $page_moves Moves that shall be considered in the form [[$old,$new],...] ($old can be $original) + * @param array $media_moves Moves of media files that shall be considered in the form $old => $new + * @param array $handlers Handlers for plugin content in the form $plugin_name => $callback */ public function __construct($id, $original, $page_moves, $media_moves, $handlers) { $this->id = $id; @@ -52,7 +52,7 @@ public function __construct($id, $original, $page_moves, $media_moves, $handlers * @throws Exception on bad argument * @return string the new full qualified ID */ - protected function resolveMoves($old, $type) { + public function resolveMoves($old, $type) { global $conf; if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); @@ -84,11 +84,11 @@ protected function resolveMoves($old, $type) { * Uses a relative link only if the original was relative, too. This function is for * pages and media files. * - * @param string $relold the old, possibly relative ID - * @param string $new the new, full qualified ID + * @param string $relold the old, possibly relative ID + * @param string $new the new, full qualified ID * @return string */ - protected function relativeLink($relold, $new) { + public function relativeLink($relold, $new) { // check if the link was relative if(strpos($relold, ':') === false || $relold{0} == '.') { $wasrel = true; @@ -107,7 +107,7 @@ protected function relativeLink($relold, $new) { } // we now have the non-common part and a number of uppers - $ups = max(count($selfpath) - $common, 0); + $ups = max(count($selfpath) - $common, 0); $remainder = array_slice($goalpath, $common); $upper = $ups ? array_fill(0, $ups, '..') : array(); @@ -117,9 +117,9 @@ protected function relativeLink($relold, $new) { if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; // don't use relative paths if it is ridicoulus: - if(strlen($newrel) > strlen($new)){ + if(strlen($newrel) > strlen($new)) { $newrel = $new; - if($this->ns && !getNS($new)) $newrel = ':'.$newrel; + if($this->ns && !getNS($new)) $newrel = ':' . $newrel; } return $newrel; @@ -128,9 +128,9 @@ protected function relativeLink($relold, $new) { /** * Handle camelcase links * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input * @return bool If parsing should be continued */ public function camelcaselink($match, $state, $pos) { @@ -156,9 +156,9 @@ public function camelcaselink($match, $state, $pos) { /** * Handle rewriting of internal links * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input * @return bool If parsing should be continued */ public function internallink($match, $state, $pos) { @@ -243,9 +243,9 @@ public function internallink($match, $state, $pos) { /** * Handle rewriting of media links * - * @param string $match The text match - * @param string $state The starte of the parser - * @param int $pos The position in the input + * @param string $match The text match + * @param string $state The starte of the parser + * @param int $pos The position in the input * @return bool If parsing should be continued */ public function media($match, $state, $pos) { diff --git a/helper/op.php b/helper/op.php index 3e2bfae..1812c13 100644 --- a/helper/op.php +++ b/helper/op.php @@ -201,7 +201,7 @@ public function movePage($src, $dst) { // Add meta data to all affected pages, so links get updated later foreach($affected_pages as $id) { - $Rewriter->setMoveMeta($id, $src, $dst, 'page'); + $Rewriter->setMoveMeta($id, $src, $dst, 'pages'); } unlock($src); diff --git a/helper/plan.php b/helper/plan.php index 8e467e7..10fb51e 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -502,7 +502,7 @@ protected function stepThroughAffectedPages() { if($page === false) break; // rewrite it - $Rewriter->execute_rewrites($page, null); + $Rewriter->rewritePage($page); // update the list file ftruncate($doclist, ftell($doclist)); diff --git a/helper/rewrite.php b/helper/rewrite.php index 8638040..cd1451f 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -39,7 +39,8 @@ class helper_plugin_move_rewrite extends DokuWiki_Plugin { */ public function getMoveMeta($id) { $all_meta = p_get_metadata($id, '', METADATA_DONT_RENDER); - // migrate old metadata from the pagemove plugin + + /* todo migrate old move data if(isset($all_meta['plugin_pagemove']) && !is_null($all_meta['plugin_pagemove'])) { if(isset($all_meta[self::METAKEY])) { $all_meta[self::METAKEY] = array_merge_recursive($all_meta['plugin_pagemove'], $all_meta[self::METAKEY]); @@ -48,7 +49,23 @@ public function getMoveMeta($id) { } p_set_metadata($id, array(self::METAKEY => $all_meta[self::METAKEY], 'plugin_pagemove' => null), false, true); } - return isset($all_meta[self::METAKEY]) ? $all_meta[self::METAKEY] : null; + */ + + $meta = isset($all_meta[self::METAKEY]) ? $all_meta[self::METAKEY] : array(); + if(!isset($meta['origin'])) $meta['origin'] = ''; + if(!isset($meta['pages'])) $meta['pages'] = array(); + if(!isset($meta['media'])) $meta['media'] = array(); + + return $meta; + } + + /** + * Remove any existing move meta data for the given page + * + * @param $id + */ + public function unsetMoveMeta($id) { + p_set_metadata($id, array(self::METAKEY => array()), false, true); } /** @@ -61,7 +78,7 @@ public function getMoveMeta($id) { * @throws Exception on wrong argument */ public function setMoveMeta($id, $src, $dst, $type) { - if($type != 'page' && $type != 'media') throw new Exception('wrong type specified'); + if($type != 'pages' && $type != 'media') throw new Exception('wrong type specified'); if(!page_exists($id, '', false)) return; $meta = $this->getMoveMeta($id); @@ -82,8 +99,8 @@ public function setMoveMeta($id, $src, $dst, $type) { public function setSelfMoveMeta($id) { $meta = $this->getMoveMeta($id); // was this page moved multiple times? keep the orignal name til rewriting occured - if(isset($meta['original']) && $meta['original'] !== '') return; - $meta['original'] = $id; + if(isset($meta['origin']) && $meta['origin'] !== '') return; + $meta['origin'] = $id; p_set_metadata($id, array(self::METAKEY => $meta), false, true); } @@ -91,18 +108,26 @@ public function setSelfMoveMeta($id) { /** * Rewrite a text in order to fix the content after the given moves. * - * @param string $text The wiki text that shall be rewritten - * @param string $id The id of the wiki page, if the page itself was moved the old id - * @param array $moves Array of all page moves, the keys are the old ids, the values the new ids - * @param array $media_moves Array of all media moves. + * @param string $id The id of the wiki page, if the page itself was moved the old id + * @param string $text The text to be rewritten * @return string The rewritten wiki text */ - public function rewrite_content($text, $id, $moves, $media_moves = array()) { - $moves = $this->resolve_moves($moves, $id); - $media_moves = $this->resolve_moves($media_moves, $id); + public function rewrite($id, $text) { + $meta = $this->getMoveMeta($id); $handlers = array(); - $data = array('id' => $id, 'moves' => &$moves, 'media_moves' => &$media_moves, 'handlers' => &$handlers); + $pages = $meta['pages']; + $media = $meta['media']; + $origin = $meta['origin']; + if($origin == '') $origin = $id; + + $data = array( + 'id' => $id, + 'origin' => &$origin, + 'pages' => &$pages, + 'media_moves' => &$media, + 'handlers' => &$handlers + ); /* * PLUGIN_MOVE_HANDLERS REGISTER event: @@ -111,13 +136,8 @@ public function rewrite_content($text, $id, $moves, $media_moves = array()) { * The handler needs to be a valid callback, it will get the following parameters: * $match, $state, $pos, $pluginname, $handler. The first three parameters are equivalent to the parameters * of the handle()-function of syntax plugins, the $pluginname is just the plugin name again so handler functions - * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object. - * It has the following properties and functions that can be used: - * - id, ns: id and namespace of the old page - * - new_id, new_ns: new id and namespace (can be identical to id and ns) - * - moves: array of moves, the same as $moves in the event - * - media_moves: array of media moves, same as $media_moves in the event - * - adaptRelativeId($id): adapts the relative $id according to the moves + * that handle multiple plugins can distinguish for which the match is. The last parameter is the handler object + * which is an instance of helper_plugin_move_handle */ trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data); @@ -127,7 +147,7 @@ public function rewrite_content($text, $id, $moves, $media_moves = array()) { $Parser = new Doku_Parser(); // Add the Handler - $Parser->Handler = new helper_plugin_move_handler($id, $moves, $media_moves, $handlers); + $Parser->Handler = new helper_plugin_move_handler($id, $origin, $pages, $media, $handlers); //add modes to parser foreach($modes as $mode) { @@ -137,62 +157,23 @@ public function rewrite_content($text, $id, $moves, $media_moves = array()) { return $Parser->parse($text); } - /** - * Resolves the provided moves, i.e. it calculates for each page the final page it was moved to. - * - * @param array $moves The moves - * @param string $id - * @return array The resolved moves - */ - public function resolve_moves($moves, $id) { - // resolve moves of pages that were moved more than once - $tmp_moves = array(); - foreach($moves as $old => $new) { - if($old != $id && isset($moves[$new]) && $moves[$new] != $new) { - // write to temp array in order to correctly handle rename circles - $tmp_moves[$old] = $moves[$new]; - } - } - - $changed = !empty($tmp_moves); - - // this correctly resolves rename circles by moving forward one step a time - while($changed) { - $changed = false; - foreach($tmp_moves as $old => $new) { - if($old != $new && isset($moves[$new]) && $moves[$new] != $new && $tmp_moves[$new] != $new) { - $tmp_moves[$old] = $moves[$new]; - $changed = true; - } - } - } - - // manual merge, we can't use array_merge here as ids can be numeric - foreach($tmp_moves as $old => $new) { - if($old == $new) unset($moves[$old]); - else $moves[$old] = $new; - } - return $moves; - } - /** * Rewrite the text of a page according to the recorded moves, the rewritten text is saved * * @param string $id The id of the page that shall be rewritten - * @param string|null $text Old content of the page. When null is given the content is loaded from disk. + * @param string|null $text Old content of the page. When null is given the content is loaded from disk * @return string|bool The rewritten content, false on error */ - public function execute_rewrites($id, $text = null) { + public function rewritePage($id, $text = null) { $meta = $this->getMoveMeta($id); - if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { - if(is_null($text)) $text = rawWiki($id); - $moves = isset($meta['moves']) ? $meta['moves'] : array(); - $media_moves = isset($meta['media_moves']) ? $meta['media_moves'] : array(); + if(is_null($text)) $text = rawWiki($id); + if($meta['pages'] || $meta['media']) { $old_text = $text; - $text = $this->rewrite_content($text, $id, $moves, $media_moves); - $changed = ($old_text != $text); - $file = wikiFN($id, '', false); + $text = $this->rewrite($id, $text); + + $changed = ($old_text != $text); + $file = wikiFN($id, '', false); if(is_writable($file) || !$changed) { if($changed) { // Wait a second when the page has just been rewritten @@ -201,11 +182,11 @@ public function execute_rewrites($id, $text = null) { saveWikiText($id, $text, $this->symbol . ' ' . $this->getLang('linkchange'), $this->getConf('minor')); } - unset($meta['moves']); - unset($meta['media_moves']); - p_set_metadata($id, array('plugin_move' => $meta), false, true); - } else { // FIXME: print error here or fail silently? + $this->unsetMoveMeta($id); + } else { + // FIXME: print error here or fail silently? msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); + return false; } } From cf78eb68c576dfbaa96e6ce0c6273bb6e238f2bd Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 24 Apr 2014 11:58:36 +0200 Subject: [PATCH 115/338] handle relative start pages --- _test/handler.test.php | 3 +++ helper/handler.php | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index 4b1f5f3..5bcc66a 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -26,6 +26,9 @@ public function test_relativeLink() { foreach($tests as $new => $rel) { $this->assertEquals($rel, $handler->relativeLink('foo', $new)); } + + $this->assertEquals('.deeper:', $handler->relativeLink('deep:namespace:deeper:', 'deep:namespace:deeper:start')); + $this->assertEquals('.:', $handler->relativeLink('deep:namespace:', 'deep:namespace:start')); } public function test_resolveMoves() { diff --git a/helper/handler.php b/helper/handler.php index c4270b9..49d2d7b 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -89,8 +89,12 @@ public function resolveMoves($old, $type) { * @return string */ public function relativeLink($relold, $new) { + global $conf; + + $relold = str_replace('/', ':', $relold); + // check if the link was relative - if(strpos($relold, ':') === false || $relold{0} == '.') { + if(strpos($relold, ':') === false || $relold{0} == '.' || substr($relold, -1) == ':') { $wasrel = true; } else { $wasrel = false; @@ -116,6 +120,16 @@ public function relativeLink($relold, $new) { $newrel = str_replace('::', ':', trim($newrel, ':')); if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; + // if the old link ended with a colon and the new one is a start page, adjust + if(substr($relold, -1) == ':') { + $len = strlen($conf['start']); + if($newrel == $conf['start']) { + $newrel = '.:'; + } else if(substr($newrel, -1 * ($len + 1)) == ':' . $conf['start']) { + $newrel = substr($newrel, 0, -1 * $len); + } + } + // don't use relative paths if it is ridicoulus: if(strlen($newrel) > strlen($new)) { $newrel = $new; From fd9b651b40353de8f315a0b650faed36a22c6e06 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 24 Apr 2014 12:05:59 +0200 Subject: [PATCH 116/338] omit unneeded colons in relative links --- _test/handler.test.php | 3 ++- helper/handler.php | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index 5bcc66a..dc2e40f 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -17,10 +17,11 @@ public function test_relativeLink() { $tests = array( 'deep:namespace:new1' => 'new1', - 'deep:new2' => '..:new2', + 'deep:new2' => '..new2', 'new3' => ':new3', // absolute is shorter than relative 'deep:namespace:deeper:new4' => '.deeper:new4', 'deep:namespace:deeper:deepest:new5' => '.deeper:deepest:new5', + 'deep:foobar:new6' => '..foobar:new6', ); foreach($tests as $new => $rel) { diff --git a/helper/handler.php b/helper/handler.php index 49d2d7b..bd3ca27 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -116,7 +116,9 @@ public function relativeLink($relold, $new) { $upper = $ups ? array_fill(0, $ups, '..') : array(); // build the new relative path - $newrel = join(':', $upper) . ':' . join(':', $remainder) . ':' . noNS($new); + $newrel = join(':', $upper); + if($remainder) $newrel .= join(':', $remainder) . ':'; + $newrel .= noNS($new); $newrel = str_replace('::', ':', trim($newrel, ':')); if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; From d87bea56d7fb1f6bac3597a47d8c6d3847a1a85e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 24 Apr 2014 12:31:08 +0200 Subject: [PATCH 117/338] keep old links as is when they still work --- _test/handler.test.php | 6 +++--- helper/handler.php | 35 +++++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index dc2e40f..2555e3e 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -25,11 +25,11 @@ public function test_relativeLink() { ); foreach($tests as $new => $rel) { - $this->assertEquals($rel, $handler->relativeLink('foo', $new)); + $this->assertEquals($rel, $handler->relativeLink('foo', $new, 'page')); } - $this->assertEquals('.deeper:', $handler->relativeLink('deep:namespace:deeper:', 'deep:namespace:deeper:start')); - $this->assertEquals('.:', $handler->relativeLink('deep:namespace:', 'deep:namespace:start')); + $this->assertEquals('.deeper:', $handler->relativeLink('.deeper:', 'deep:namespace:deeper:start', 'page')); + $this->assertEquals('.:', $handler->relativeLink('.:', 'deep:namespace:start', 'page')); } public function test_resolveMoves() { diff --git a/helper/handler.php b/helper/handler.php index bd3ca27..8066795 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -60,13 +60,13 @@ public function resolveMoves($old, $type) { $old = str_replace('/', ':', $old); $old = resolve_id($this->origNS, $old, false); - // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page - // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been - // deleted already - if(substr($old, -1) === ':') $old .= $conf['start']; - $old = cleanID($old); - if($type == 'page') { + // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page + // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been + // deleted already + if(substr($old, -1) === ':') $old .= $conf['start']; + $old = cleanID($old); + $moves = $this->page_moves; } else { $moves = $this->media_moves; @@ -86,13 +86,28 @@ public function resolveMoves($old, $type) { * * @param string $relold the old, possibly relative ID * @param string $new the new, full qualified ID + * @param string $type 'media' or 'page' + * @throws Exception on bad argument * @return string */ - public function relativeLink($relold, $new) { + public function relativeLink($relold, $new, $type) { global $conf; + if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); $relold = str_replace('/', ':', $relold); + // first check if the old link still resolves + $exists = false; + $old = $relold; + if($type == 'page') { + resolve_pageid($this->ns, $old, $exists); + } else { + resolve_mediaid($this->ns, $old, $exists); + } + if($old == $new) { + return $relold; // old link still resolves, keep as is + } + // check if the link was relative if(strpos($relold, ':') === false || $relold{0} == '.' || substr($relold, -1) == ':') { $wasrel = true; @@ -123,7 +138,7 @@ public function relativeLink($relold, $new) { if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; // if the old link ended with a colon and the new one is a start page, adjust - if(substr($relold, -1) == ':') { + if($type == 'page' && substr($relold, -1) == ':') { $len = strlen($conf['start']); if($newrel == $conf['start']) { $newrel = '.:'; @@ -231,7 +246,7 @@ public function internallink($match, $state, $pos) { } $new_id = $this->resolveMoves($id, 'page'); - $new_id = $this->relativeLink($id, $new_id); + $new_id = $this->relativeLink($id, $new_id, 'page'); if($id == $new_id) { $this->calls .= $match; @@ -280,7 +295,7 @@ protected function rewrite_media($match) { if($p['type'] == 'internalmedia') { // else: external media $new_src = $this->resolveMoves($p['src'], 'media'); - $new_src = $this->relativeLink($p['src'], $new_src); + $new_src = $this->relativeLink($p['src'], $new_src, 'media'); if($new_src !== $p['src']) { // do a simple replace of the first match so really only the id is changed and not e.g. the alignment From 81cb591f962725a5f1f9bdba2bdc42c1c10b1cd4 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 24 Apr 2014 15:48:30 +0200 Subject: [PATCH 118/338] fixed pagemove tests for new relativeID calculation --- _test/pagemove.test.php | 76 ++++++++++++++++++++++------------------- helper/handler.php | 8 ++--- helper/op.php | 2 ++ helper/rewrite.php | 2 +- 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index d38b15a..39a87cc 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -25,6 +25,7 @@ function setUp() { $this->pluginsEnabled[] = 'move'; global $ID; global $INFO; + global $conf; $ID = $this->movedId; @@ -168,6 +169,9 @@ function setUp() { idx_get_indexer()->addMetaKeys($this->subNsPage, 'relation_references', $references); parent::setUp(); + + // we test under useslash conditions + $conf['useslash'] = 1; } @@ -201,11 +205,11 @@ function test_move_page_in_same_ns() { $newContent = rawWiki($this->parentBacklinkingId); $expectedContent = <<movedId]] -[[.:current_ns:new_page|:$this->movedId]] -[[.:current_ns:new_page|.current_ns:test_page]] -[[.:current_ns:new_page|.:current_ns:test_page]] -[[.:current_ns:new_page|..parent_ns:current_ns:test_page]] +[[parent_ns:current_ns:new_page|$this->movedId]] +[[parent_ns:current_ns:new_page|:$this->movedId]] +[[.current_ns:new_page|.current_ns:test_page]] +[[.current_ns:new_page|.:current_ns:test_page]] +[[.current_ns:new_page|..parent_ns:current_ns:test_page]] [[test_page|test_page]] [[new_page|new_page]] [[ftp://somewhere.com|ftp://somewhere.com]] @@ -228,8 +232,8 @@ function test_move_page_in_same_ns() { $newContent = rawWiki($this->currentNsBacklinkingId); $expectedContent = <<movedId]] -[[new_page|:$this->movedId]] +[[parent_ns:current_ns:new_page|$this->movedId]] +[[parent_ns:current_ns:new_page|:$this->movedId]] [[new_page|..current_ns:test_page]] [[new_page|..:current_ns:test_page]] [[new_page|test_page]] @@ -298,9 +302,9 @@ function test_move_page_to_parallel_ns() { $newContent = rawWiki($this->movedToId); $expectedContent = <<parentBacklinkingId); $expectedContent = <<movedId]] -[[.:parallel_ns:new_page|:$this->movedId]] -[[.:parallel_ns:new_page|.current_ns:test_page]] -[[.:parallel_ns:new_page|.:current_ns:test_page]] -[[.:parallel_ns:new_page|..parent_ns:current_ns:test_page]] +[[parent_ns:parallel_ns:new_page|$this->movedId]] +[[parent_ns:parallel_ns:new_page|:$this->movedId]] +[[.parallel_ns:new_page|.current_ns:test_page]] +[[.parallel_ns:new_page|.:current_ns:test_page]] +[[.parallel_ns:new_page|..parent_ns:current_ns:test_page]] [[test_page|test_page]] [[new_page|new_page]] [[ftp://somewhere.com|ftp://somewhere.com]] @@ -344,11 +348,11 @@ function test_move_page_to_parallel_ns() { $expectedContent = <<movedId]] [[$newId|:$this->movedId]] -[[parent_ns:parallel_ns:new_page|..current_ns:test_page]] -[[parent_ns:parallel_ns:new_page|..:current_ns:test_page]] -[[parent_ns:parallel_ns:new_page|test_page]] -[[parent_ns:parallel_ns:new_page|.test_page]] -[[parent_ns:parallel_ns:new_page|.:test_page]] +[[..parallel_ns:new_page|..current_ns:test_page]] +[[..parallel_ns:new_page|..:current_ns:test_page]] +[[..parallel_ns:new_page|test_page]] +[[..parallel_ns:new_page|.test_page]] +[[..parallel_ns:new_page|.:test_page]] [[..test_page|..test_page]] [[..:test_page|..:test_page]] [[.:..:test_page|.:..:test_page]] @@ -408,20 +412,20 @@ function test_move_page_to_parent_ns() { /** @var helper_plugin_move_op $MoveOp */ $MoveOp = plugin_load('helper', 'move_op'); - $result = $MoveOp->movePage($ID, $newId); + $result = $MoveOp->movePage($ID, $newId); //parent_ns:current_ns:test_page -> parent_ns:new_page $this->assertTrue($result); $newContent = rawWiki($this->movedToId); $expectedContent = <<parentBacklinkingId); $expectedContent = <<movedId]] -[[new_page|:$this->movedId]] +[[parent_ns:new_page|$this->movedId]] +[[parent_ns:new_page|:$this->movedId]] [[new_page|.current_ns:test_page]] [[new_page|.:current_ns:test_page]] [[new_page|..parent_ns:current_ns:test_page]] @@ -460,11 +464,11 @@ function test_move_page_to_parent_ns() { $expectedContent = <<movedId]] [[$newId|:$this->movedId]] -[[parent_ns:new_page|..current_ns:test_page]] -[[parent_ns:new_page|..:current_ns:test_page]] -[[parent_ns:new_page|test_page]] -[[parent_ns:new_page|.test_page]] -[[parent_ns:new_page|.:test_page]] +[[..new_page|..current_ns:test_page]] +[[..new_page|..:current_ns:test_page]] +[[..new_page|test_page]] +[[..new_page|.test_page]] +[[..new_page|.:test_page]] [[..test_page|..test_page]] [[..:test_page|..:test_page]] [[.:..:test_page|.:..:test_page]] diff --git a/helper/handler.php b/helper/handler.php index 8066795..fecf4f3 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -57,7 +57,7 @@ public function resolveMoves($old, $type) { if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); - $old = str_replace('/', ':', $old); + if($conf['useslash']) $old = str_replace('/', ':', $old); $old = resolve_id($this->origNS, $old, false); if($type == 'page') { @@ -94,8 +94,6 @@ public function relativeLink($relold, $new, $type) { global $conf; if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); - $relold = str_replace('/', ':', $relold); - // first check if the old link still resolves $exists = false; $old = $relold; @@ -108,8 +106,10 @@ public function relativeLink($relold, $new, $type) { return $relold; // old link still resolves, keep as is } + if($conf['useslash']) $relold = str_replace('/', ':', $relold); + // check if the link was relative - if(strpos($relold, ':') === false || $relold{0} == '.' || substr($relold, -1) == ':') { + if(strpos($relold, ':') === false ||$relold{0} == '.' || substr($relold, -1) == ':') { $wasrel = true; } else { $wasrel = false; diff --git a/helper/op.php b/helper/op.php index 1812c13..a2f7410 100644 --- a/helper/op.php +++ b/helper/op.php @@ -127,6 +127,8 @@ public function movePage($src, $dst) { // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages $affected_pages = idx_get_indexer()->lookupKey('relation_references', $src); + $affected_pages[] = $dst; // the current page is always affected, because all relative links may have changed + $affected_pages = array_unique($affected_pages); $src_ns = getNS($src); $src_name = noNS($src); diff --git a/helper/rewrite.php b/helper/rewrite.php index cd1451f..f76b216 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -167,8 +167,8 @@ public function rewrite($id, $text) { public function rewritePage($id, $text = null) { $meta = $this->getMoveMeta($id); if(is_null($text)) $text = rawWiki($id); - if($meta['pages'] || $meta['media']) { + if($meta['pages'] || $meta['media']) { $old_text = $text; $text = $this->rewrite($id, $text); From 99af2d2ca4a92ac310b93c2e034795233ae44973 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 28 Apr 2014 12:14:12 +0200 Subject: [PATCH 119/338] do not execute rewrites during moves This finally adds the delayed link adjustments. Links will not automatically adjusted when a page is read, when it happens during a page move operation. State of this is tracked through a global variable $PLUGIN_MOVE_WORKING. --- action/rewrite.php | 4 ++++ helper/op.php | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/action/rewrite.php b/action/rewrite.php index d6eff96..0b8a164 100644 --- a/action/rewrite.php +++ b/action/rewrite.php @@ -35,6 +35,10 @@ function handle_read(Doku_Event $event, $param) { // handle only reads of the current revision if($event->data[3]) return; + // only rewrite if not in move already + global $PLUGIN_MOVE_WORKING; + if(!empty($PLUGIN_MOVE_WORKING)) return; + $id = $event->data[2]; if($event->data[1]) $id = $event->data[1] . ':' . $id; diff --git a/helper/op.php b/helper/op.php index a2f7410..13ad852 100644 --- a/helper/op.php +++ b/helper/op.php @@ -119,6 +119,10 @@ public function checkMedia($src, $dst) { public function movePage($src, $dst) { if(!$this->checkPage($src, $dst)) return false; + // lock rewrites + global $PLUGIN_MOVE_WORKING; + $PLUGIN_MOVE_WORKING = true; + /** @var helper_plugin_move_rewrite $Rewriter */ $Rewriter = plugin_load('helper', 'move_rewrite'); @@ -213,6 +217,9 @@ public function movePage($src, $dst) { // store this for later use $this->affectedPages = $affected_pages; + // unlock rewrites + $PLUGIN_MOVE_WORKING = false; + return true; } From a8b01c79a6eac9f3833596b0c93c8ba926af7b28 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 28 Apr 2014 12:29:40 +0200 Subject: [PATCH 120/338] removed outdated fixme --- helper/rewrite.php | 1 - 1 file changed, 1 deletion(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index f76b216..9336ec4 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -83,7 +83,6 @@ public function setMoveMeta($id, $src, $dst, $type) { $meta = $this->getMoveMeta($id); if(!isset($meta[$type])) $meta[$type] = array(); - // FIXME resolve here? $meta[$type][] = array($src, $dst); p_set_metadata($id, array(self::METAKEY => $meta), false, true); From 1039b980cae9361ac31b68e922ce6d577d8cb2ba Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 28 Apr 2014 16:46:15 +0200 Subject: [PATCH 121/338] find missing pages affected by a page move --- helper/plan.php | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 10fb51e..cbea2e5 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -56,6 +56,7 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { 'pages' => array(), 'media' => array(), 'ns' => array(), + 'miss' => array(), ); /** @@ -72,7 +73,8 @@ public function __construct() { 'pagelist' => $conf['metadir'] . '/__move_pagelist', 'medialist' => $conf['metadir'] . '/__move_medialist', 'affected' => $conf['metadir'] . '/__move_affected', - 'namespaces' => $conf['metadir'] . '/__move_namespaces' + 'namespaces' => $conf['metadir'] . '/__move_namespaces', + 'missing' => $conf['metadir'] . '/__move_missing' ); $this->loadOptions(); @@ -318,6 +320,8 @@ public function commit() { // page namespace moves, but subscriptions work for both, but what when only one of // them is moved? Should it be copied then? Complicated. This is good enough for now $this->addToDocumentList($move['src'], $move['dst'], self::CLASS_NS); + + $this->findMissingPages($move['src'], $move['dst']); } } // store what pages are affected by this move @@ -647,6 +651,34 @@ protected function findAffectedPages($src, $class, $type) { $this->addToAffectedPagesList($pages); } + /** + * Find missing pages in the $src namespace + * + * @param $src + * @param $dst + */ + protected function findMissingPages($src, $dst) { + static $pages = null; + if(is_null($pages)) { + $Indexer = idx_get_indexer(); + $pages = $Indexer->getPages(); + } + + $len = strlen($src); + foreach($pages as $idx => $page) { + if(substr($page, 0, $len+1) != "$src:") continue; + + // remember missing pages + if(!page_exists($page)) { + $newpage = $dst .':' .substr($page, $len+1); + $this->tmpstore['miss'][$page] = $newpage; + } + + // we never need to look at this page again + unset($pages[$idx]); + } + } + /** * Store the aggregated document lists in the file system and reset the internal storage * @@ -657,7 +689,8 @@ protected function storeDocumentLists() { 'pages' => $this->files['pagelist'], 'media' => $this->files['medialist'], 'ns' => $this->files['namespaces'], - 'affpg' => $this->files['affected'] + 'affpg' => $this->files['affected'], + 'miss' => $this->files['missing'] ); foreach($lists as $store => $file) { From 93b0c4b08414874412977464e2f2456d09c1a09e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 10:09:39 +0200 Subject: [PATCH 122/338] handle links to missing pages by adding their move info to all affected pages --- helper/plan.php | 40 ++++++++++++++++++++++++++++++++++++++++ helper/rewrite.php | 16 +++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index cbea2e5..d7315a8 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -366,6 +366,12 @@ public function nextStep($skip = false) { return max($todo, 1); // force one more call } + if(@filesize($this->files['missing']) > 1 && @filesize($this->files['affected']) > 1) { + $todo = $this->stepThroughMissingPages(); + if($todo === false) return $this->storeError(); + return max($todo, 1); // force one more call + } + if(@filesize($this->files['namespaces']) > 1) { $todo = $this->stepThroughNamespaces(); if($todo === false) return $this->storeError(); @@ -518,6 +524,40 @@ protected function stepThroughAffectedPages() { return $this->options['affpg_run']; } + /** + * Step through all the links to missing pages that should be moved + * + * This simply adds the moved missing pages to all affected pages meta data. This will add + * the meta data to pages not linking to the affected pages but this should still be faster + * than figuring out which pages need this info. + * + * This does not step currently, but handles all pages in one step. + * + * @return int always 0 + */ + protected function stepThroughMissingPages() { + /** @var helper_plugin_move_rewrite $Rewriter */ + $Rewriter = plugin_load('helper', 'move_rewrite'); + + $miss = array(); + $missing = file($this->files['missing']); + foreach($missing as $line) { + $line = trim($line); + if($line == '') continue; + list($src, $dst) = explode("\t", $line); + $miss[$src] = $dst; + } + + $affected = file($this->files['affected']); + foreach($affected as $page){ + $page = trim($page); + + $Rewriter->setMoveMetas($page, $miss, 'page'); + } + + return 0; + } + /** * Step through all the namespace moves * diff --git a/helper/rewrite.php b/helper/rewrite.php index 9336ec4..8017690 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -78,12 +78,26 @@ public function unsetMoveMeta($id) { * @throws Exception on wrong argument */ public function setMoveMeta($id, $src, $dst, $type) { + $this->setMoveMetas($id, array($src => $dst), $type); + } + + /** + * Add info about several moved documents to the metadata of an affected page + * + * @param string $id affected page + * @param array $moves list of moves (src is key, dst is value) + * @param string $type 'media' or 'page' + * @throws Exception + */ + public function setMoveMetas($id, $moves, $type) { if($type != 'pages' && $type != 'media') throw new Exception('wrong type specified'); if(!page_exists($id, '', false)) return; $meta = $this->getMoveMeta($id); if(!isset($meta[$type])) $meta[$type] = array(); - $meta[$type][] = array($src, $dst); + foreach($moves as $src => $dst) { + $meta[$type][] = array($src, $dst); + } p_set_metadata($id, array(self::METAKEY => $meta), false, true); } From c566d3fd8d83ff154a67bc740da914b9bc70ff06 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 11:19:38 +0200 Subject: [PATCH 123/338] fix error when not logged in --- action/rename.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/action/rename.php b/action/rename.php index 0d3c7a0..c609d07 100644 --- a/action/rename.php +++ b/action/rename.php @@ -103,7 +103,8 @@ public function renameOkay($id) { if(!page_exists($id)) return false; if(auth_quickaclcheck($id) < AUTH_EDIT) return false; if(checklock($id) !== false || @file_exists(wikiLockFN($id))) return false; - if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], $USERINFO['grps'])) return false; + if(!isset($_SERVER['REMOTE_USER'])) return false; + if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], (array) $USERINFO['grps'])) return false; return true; } From d8e701590241b01bd4818ae244c1597008879533 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 11:40:39 +0200 Subject: [PATCH 124/338] use correct index to find missing pages --- helper/plan.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index d7315a8..9a29a8e 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -700,8 +700,14 @@ protected function findAffectedPages($src, $class, $type) { protected function findMissingPages($src, $dst) { static $pages = null; if(is_null($pages)) { - $Indexer = idx_get_indexer(); - $pages = $Indexer->getPages(); + global $conf; + // FIXME this duplicates Doku_Indexer::getIndex() + $fn = $conf['indexdir'].'/relation_references_w.idx'; + if (!@file_exists($fn)){ + $pages = array(); + } else { + $pages = file($fn, FILE_IGNORE_NEW_LINES); + } } $len = strlen($src); @@ -710,7 +716,7 @@ protected function findMissingPages($src, $dst) { // remember missing pages if(!page_exists($page)) { - $newpage = $dst .':' .substr($page, $len+1); + $newpage = $dst . substr($page, $len+1); $this->tmpstore['miss'][$page] = $newpage; } From 75142ab2b872257a452bf4d3eb05215d40506e0e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 12:10:00 +0200 Subject: [PATCH 125/338] proper info on continuing an interrupted move --- admin/main.php | 4 ++-- lang/en/lang.php | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/admin/main.php b/admin/main.php index 4365ed5..2ed3847 100644 --- a/admin/main.php +++ b/admin/main.php @@ -207,8 +207,6 @@ protected function GUI_progress() { echo $this->plan->previewHTML(); echo '
    '; - } else { - echo "continue plan"; } echo '
    ' . $progress . '%
    '; @@ -216,6 +214,8 @@ protected function GUI_progress() { echo '
    '; if($this->plan->getLastError()) { echo '

    ' . $this->plan->getLastError() . '

    '; + } elseif ($this->plan->inProgress()) { + echo '

    ' . $this->getLang('inexecution') . '

    '; } echo '
    '; diff --git a/lang/en/lang.php b/lang/en/lang.php index b7a4b38..042cfa4 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -35,6 +35,7 @@ // progress view $lang['intro'] = 'The move operation has not been started, yet!'; $lang['preview'] = 'Preview changes to be executed.'; +$lang['inexecution'] = 'A previous move was not completed - use the buttons below to continue or abort the execution.'; $lang['btn_start'] = 'Start'; $lang['btn_continue'] = 'Continue'; $lang['btn_retry'] = 'Retry item'; From e4b4f5fd8e2d056d27343fb880388340402e7d3e Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 12:10:21 +0200 Subject: [PATCH 126/338] fix another endless loop --- helper/plan.php | 1 + script/progress.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index 9a29a8e..4b14883 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -555,6 +555,7 @@ protected function stepThroughMissingPages() { $Rewriter->setMoveMetas($page, $miss, 'page'); } + unlink($this->files['missing']); return 0; } diff --git a/script/progress.js b/script/progress.js index 533085b..2a32d8b 100644 --- a/script/progress.js +++ b/script/progress.js @@ -5,7 +5,7 @@ jQuery('#plugin_move__progress').each(function () { var $progressbar = $this.find('.progress'); $progressbar.html(''); $progressbar.progressbar({ - value: $progressbar.attr('data-progress') + value: $progressbar.data('progress') }); /** From 6b8db6bf7d4c1ad383655cc7f1f09b2646a4ceb4 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 13:40:33 +0200 Subject: [PATCH 127/338] fixed wrong type passed --- helper/plan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index 4b14883..269e057 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -552,7 +552,7 @@ protected function stepThroughMissingPages() { foreach($affected as $page){ $page = trim($page); - $Rewriter->setMoveMetas($page, $miss, 'page'); + $Rewriter->setMoveMetas($page, $miss, 'pages'); } unlink($this->files['missing']); From a3a202e47197a547da5fc7875b89f91cd69faf91 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 13:45:55 +0200 Subject: [PATCH 128/338] one more step in test --- _test/namespace_move.test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index e3ad49a..493c862 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -37,6 +37,7 @@ public function test_move_wiki_namespace() { $this->assertSame(1, $plan->nextStep()); // pages $this->assertSame(1, $plan->nextStep()); // media $this->assertSame(1, $plan->nextStep()); // links + $this->assertSame(1, $plan->nextStep()); // missing $this->assertSame(1, $plan->nextStep()); // namepaces $this->assertSame(0, $plan->nextStep()); // done From d791aa26159b5c061bbe4fc5328d5b6db9e343d3 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 14:36:43 +0200 Subject: [PATCH 129/338] rewriting missing links should work now this introduces stacked locking of the rewrite process which is needed to keep pages from being rewritten before the missing link info is added to their metadata. This works fine for the newly added test case. However in real world scenarios it might happen that a page is access by someone while the move operation is in progress. This would still trigger a rewrite, rendering addition of missing link info too late and create wrong second rewrites (as seen before this patch in normal operation). There are multiple ways to fix this: 1) allow absolutely no rewrites during a move (using a file based locking instead of process based). This would have the disadvantage of exposing pages with wrong links to end users during a move 2) pass the missing link info over to the ops class so that each moved page has the info right away and saves it with the other (existing link) move data in one go. The problem would then be to apply the missing link move data to all pages that were not affected by any other link changes. It would need some tracking of already processed affected pages vs. all affected pages. Option 2 is most probably the better way to do it. However this is left for a later iteration for now as the scope of this project is already slighly out of bounds. @michitux I'd be happy about any comments, suggestion or - even better - code here. --- _test/namespace_move.test.php | 27 ++++++++++++++++++++++++++- action/rewrite.php | 3 +-- helper/op.php | 5 ++--- helper/plan.php | 21 +++++++++++++++------ helper/rewrite.php | 27 +++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 12 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 493c862..df5e8f3 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -36,8 +36,8 @@ public function test_move_wiki_namespace() { $this->assertSame(1, $plan->nextStep()); // pages $this->assertSame(1, $plan->nextStep()); // media - $this->assertSame(1, $plan->nextStep()); // links $this->assertSame(1, $plan->nextStep()); // missing + $this->assertSame(1, $plan->nextStep()); // links $this->assertSame(1, $plan->nextStep()); // namepaces $this->assertSame(0, $plan->nextStep()); // done @@ -45,4 +45,29 @@ public function test_move_wiki_namespace() { $this->assertFileNotExists(wikiFN('wiki:syntax')); $this->assertFileExists(mediaFN('foo:dokuwiki-128.png')); } + + public function test_move_missing() { + saveWikiText('oldspace:page', '[[missing]]', 'setup'); + idx_addPage('oldspace:page'); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('oldspace', 'newspace'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep()); // pages + $this->assertSame(1, $plan->nextStep()); // missing + $this->assertSame(1, $plan->nextStep()); // links + $this->assertSame(1, $plan->nextStep()); // namepaces + $this->assertSame(0, $plan->nextStep()); // done + + $this->assertFileExists(wikiFN('newspace:page')); + $this->assertFileNotExists(wikiFN('oldspace:page')); + + $this->assertEquals('[[missing]]', rawWiki('newspace:page')); + } } diff --git a/action/rewrite.php b/action/rewrite.php index 0b8a164..ada8bc8 100644 --- a/action/rewrite.php +++ b/action/rewrite.php @@ -36,8 +36,7 @@ function handle_read(Doku_Event $event, $param) { if($event->data[3]) return; // only rewrite if not in move already - global $PLUGIN_MOVE_WORKING; - if(!empty($PLUGIN_MOVE_WORKING)) return; + if(helper_plugin_move_rewrite::isLocked()) return; $id = $event->data[2]; if($event->data[1]) $id = $event->data[1] . ':' . $id; diff --git a/helper/op.php b/helper/op.php index 13ad852..c962267 100644 --- a/helper/op.php +++ b/helper/op.php @@ -120,8 +120,7 @@ public function movePage($src, $dst) { if(!$this->checkPage($src, $dst)) return false; // lock rewrites - global $PLUGIN_MOVE_WORKING; - $PLUGIN_MOVE_WORKING = true; + helper_plugin_move_rewrite::addLock(); /** @var helper_plugin_move_rewrite $Rewriter */ $Rewriter = plugin_load('helper', 'move_rewrite'); @@ -218,7 +217,7 @@ public function movePage($src, $dst) { $this->affectedPages = $affected_pages; // unlock rewrites - $PLUGIN_MOVE_WORKING = false; + helper_plugin_move_rewrite::removeLock(); return true; } diff --git a/helper/plan.php b/helper/plan.php index 269e057..130f28e 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -59,6 +59,9 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { 'miss' => array(), ); + /** @var array|null keeps reference list */ + protected $referenceidx = null; + /** * Constructor * @@ -115,6 +118,9 @@ protected function loadOptions() { $options = unserialize(io_readFile($file, false)); $this->options = array_merge($this->options, $options); } + + // reset index for next run (happens in tests only) + $this->referenceidx = null; } /** @@ -354,6 +360,8 @@ public function nextStep($skip = false) { // execution has started if(!$this->options['started']) $this->options['started'] = time(); + helper_plugin_move_rewrite::addLock(); + if(@filesize($this->files['pagelist']) > 1) { $todo = $this->stepThroughDocuments(self::TYPE_PAGES, $skip); if($todo === false) return $this->storeError(); @@ -378,6 +386,8 @@ public function nextStep($skip = false) { return max($todo, 1); // force one more call } + helper_plugin_move_rewrite::removeLock(); + if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { $todo = $this->stepThroughAffectedPages(); if($todo === false) return $this->storeError(); @@ -699,20 +709,19 @@ protected function findAffectedPages($src, $class, $type) { * @param $dst */ protected function findMissingPages($src, $dst) { - static $pages = null; - if(is_null($pages)) { + if(is_null($this->referenceidx)) { global $conf; // FIXME this duplicates Doku_Indexer::getIndex() $fn = $conf['indexdir'].'/relation_references_w.idx'; if (!@file_exists($fn)){ - $pages = array(); + $this->referenceidx = array(); } else { - $pages = file($fn, FILE_IGNORE_NEW_LINES); + $this->referenceidx = file($fn, FILE_IGNORE_NEW_LINES); } } $len = strlen($src); - foreach($pages as $idx => $page) { + foreach($this->referenceidx as $idx => $page) { if(substr($page, 0, $len+1) != "$src:") continue; // remember missing pages @@ -722,7 +731,7 @@ protected function findMissingPages($src, $dst) { } // we never need to look at this page again - unset($pages[$idx]); + unset($this->referenceidx[$idx]); } } diff --git a/helper/rewrite.php b/helper/rewrite.php index 8017690..c79343e 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -118,6 +118,33 @@ public function setSelfMoveMeta($id) { p_set_metadata($id, array(self::METAKEY => $meta), false, true); } + /** + * Check if rewrites may be executed within this process right now + * + * @return bool + */ + public static function isLocked() { + global $PLUGIN_MOVE_WORKING; + return (isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0); + } + + /** + * Do not allow any rewrites in this process right now + */ + public static function addLock() { + global $PLUGIN_MOVE_WORKING; + $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING + 1 : 1; + } + + /** + * Allow rerites in this process again, unless some other lock exists + */ + public static function removeLock() { + global $PLUGIN_MOVE_WORKING; + $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING - 1 : 0; + } + + /** * Rewrite a text in order to fix the content after the given moves. * From 2281275744f8434d279121ca5a687e0ae92a921b Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 29 Apr 2014 15:11:30 +0200 Subject: [PATCH 130/338] make use of jQuery's data() function as @Klap-in suggested --- script/tree.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/script/tree.js b/script/tree.js index fccab69..1eda19a 100644 --- a/script/tree.js +++ b/script/tree.js @@ -19,7 +19,7 @@ var checkForMovement = function ($li) { var $all = $li.add($li.find('li.moved')); $all.each(function () { var $this = jQuery(this); - var oldid = $this.attr('data-id'); + var oldid = $this.data('id'); var newid = determineNewID($this); if (newid != oldid) { @@ -49,7 +49,7 @@ var checkNameAllowed = function ($li, name) { if ($li.hasClass('type-d')) cname = 'type-d'; var $this = jQuery(this); - if ($this.attr('data-name') == name && $this.hasClass(cname)) ok = false; + if ($this.data('name') == name && $this.hasClass(cname)) ok = false; }); return ok; }; @@ -61,7 +61,7 @@ var checkNameAllowed = function ($li, name) { * @returns {string} */ var determineNewID = function ($li) { - var myname = $li.attr('data-name'); + var myname = $li.data('name'); var $parent = $li.parent().closest('li'); if ($parent.length) { @@ -129,11 +129,11 @@ $GUI.find('ul.tree_list') e.stopPropagation(); var $a = $clicky.parent().find('a'); - var newname = window.prompt(LANG.plugins.move.renameitem, $li.attr('data-name')); + var newname = window.prompt(LANG.plugins.move.renameitem, $li.data('name')); newname = cleanID(newname); if (newname) { if (checkNameAllowed($li, newname)) { - $li.attr('data-name', newname); + $li.data('name', newname); $a.text(newname); checkForMovement($li); } else { @@ -147,9 +147,9 @@ $GUI.find('ul.tree_list') .find('ul').sortable({ items: 'li', stop: function (e, ui) { - if (!checkNameAllowed(ui.item, ui.item.attr('data-name'))) { + if (!checkNameAllowed(ui.item, ui.item.data('name'))) { jQuery(this).sortable('cancel'); - alert(LANG.plugins.move.duplicate.replace('%s', ui.item.attr('data-name'))); + alert(LANG.plugins.move.duplicate.replace('%s', ui.item.data('name'))); } checkForMovement(ui.item); @@ -173,7 +173,7 @@ jQuery('#plugin_move__tree_execute').submit(function (e) { data[data.length] = { class: $el.hasClass('type-d') ? 'ns' : 'doc', type: 'page', - src: $el.attr('data-id'), + src: $el.data('id'), dst: newid }; }); @@ -184,7 +184,7 @@ jQuery('#plugin_move__tree_execute').submit(function (e) { data[data.length] = { class: $el.hasClass('type-d') ? 'ns' : 'doc', type: 'media', - src: $el.attr('data-id'), + src: $el.data('id'), dst: newid }; }); From 35b0b498b5b9420537971cbc821c12c96dd24057 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 14 May 2014 15:59:43 +0200 Subject: [PATCH 131/338] some IE8 JavaScript fix --- script/tree.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script/tree.js b/script/tree.js index 1eda19a..6a49bb7 100644 --- a/script/tree.js +++ b/script/tree.js @@ -171,7 +171,7 @@ jQuery('#plugin_move__tree_execute').submit(function (e) { var newid = determineNewID($el); data[data.length] = { - class: $el.hasClass('type-d') ? 'ns' : 'doc', + 'class': $el.hasClass('type-d') ? 'ns' : 'doc', type: 'page', src: $el.data('id'), dst: newid @@ -182,7 +182,7 @@ jQuery('#plugin_move__tree_execute').submit(function (e) { var newid = determineNewID($el); data[data.length] = { - class: $el.hasClass('type-d') ? 'ns' : 'doc', + 'class': $el.hasClass('type-d') ? 'ns' : 'doc', type: 'media', src: $el.data('id'), dst: newid @@ -190,4 +190,4 @@ jQuery('#plugin_move__tree_execute').submit(function (e) { }); jQuery(this).find('input[name=json]').val(JSON.stringify(data)); -}); \ No newline at end of file +}); From f9e55854f1f0001903d1ccbbe8b72f397f43d6d5 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 2 Jul 2014 14:18:09 +0200 Subject: [PATCH 132/338] prevent overlaps in tree manager --- style.less | 2 ++ 1 file changed, 2 insertions(+) diff --git a/style.less b/style.less index d6b3794..8f5e3c1 100644 --- a/style.less +++ b/style.less @@ -9,6 +9,8 @@ .tree_media { width: 49%; float: left; + overflow-wrap: break-word; + overflow: hidden; } .controls { From e65e7ea75cbcb6f30950fb40ae5730ed3887e2b1 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 2 Jul 2014 14:38:02 +0200 Subject: [PATCH 133/338] less subtle move marker in tree manager the previous choice of background color was hard to see in some templates. --- style.less | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/style.less b/style.less index 8f5e3c1..bbcfa5b 100644 --- a/style.less +++ b/style.less @@ -20,7 +20,11 @@ ul.tree_list ul { .moved > div { - background-color: @ini_background_neu; + border: 1px dashed lighten(@ini_text, 30%); + border-radius: 3px; + margin-left: -3px; + padding-left: 3px; + margin-top: 1px; } li { From 9d98adb7c3507d3049d972719b3193b1c311d776 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 2 Jul 2014 15:10:42 +0200 Subject: [PATCH 134/338] adjusted log file naming logs are now saved in their own folder within the cache directory and have human readable timestamp --- helper/plan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index 130f28e..58b1300 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -864,7 +864,7 @@ protected function log($type, $from, $to, $success) { global $MSG; $optime = $this->options['started']; - $file = $conf['cachedir'] . '/move-' . $optime . '.log'; + $file = $conf['cachedir'] . '/move/' . strftime('%Y%m%d-%H%M%S', $optime) . '.log'; $now = time(); $date = date('Y-m-d H:i:s', $now); // for human readability From 5eee52d50a9a3f2903c5dd278da6993ea6968f6b Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 2 Jul 2014 15:31:05 +0200 Subject: [PATCH 135/338] upped version --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index be325c1..6db5c16 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2013-11-24 +date 2014-07-02 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 7c0853663f8fd0b3c8d9d2a6e6b7be6cfb2e6208 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 1 Aug 2014 14:19:01 +0200 Subject: [PATCH 136/338] made variable local --- script/tree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/tree.js b/script/tree.js index 6a49bb7..4532bb8 100644 --- a/script/tree.js +++ b/script/tree.js @@ -40,7 +40,7 @@ var checkForMovement = function ($li) { * @returns {boolean} */ var checkNameAllowed = function ($li, name) { - $parent = $li.parent(); + var $parent = $li.parent(); var ok = true; $parent.children('li').each(function () { From 2b7004ca533a623201381c2fbd719dd23adc2f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 16 Mar 2015 12:39:55 +0100 Subject: [PATCH 137/338] Test that absolute tests remain absolute --- _test/pagemove.test.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 39a87cc..0b01b97 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -518,6 +518,24 @@ function test_move_page_to_parent_ns() { $this->assertEquals($expectedContent, $newContent); } + /** + * Ensure that absolute links stay absolute. See https://github.com/michitux/dokuwiki-plugin-move/pull/6#discussion_r15698440 + */ + function test_move_startpage_of_ns() { + saveWikiText('wiki:bar:test', + '[[wiki:foo:]]', 'Test setup'); + idx_addPage('wiki:bar:test'); + saveWikiText('wiki:foo:start', + 'bar', 'Test setup'); + idx_addPage('wiki:foo:start'); + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + $this->assertTrue($move->movePage('wiki:foo:start', 'wiki:foo2:start')); + + $this->assertEquals('[[wiki:foo2:]]', rawWiki('wiki:bar:test')); + } + function test_move_ns_in_same_ns() { From ae907faa23a1c29860f04ea46a0c0eb8dea74861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 16 Mar 2015 17:27:00 +0100 Subject: [PATCH 138/338] Handle relative and absolute links w/ ending colon --- _test/pagemove.test.php | 16 ++++++++++++++++ helper/handler.php | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 0b01b97..01a0ba9 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -536,6 +536,22 @@ function test_move_startpage_of_ns() { $this->assertEquals('[[wiki:foo2:]]', rawWiki('wiki:bar:test')); } + /** + * If the relative part would be too large, create an absolute link instead. + * If the original link ended with a colon and the new link also points to a namespace's startpage: keep the colon. + */ + function test_move_no_long_rel_links_keep_colon() { + saveWikiText('wiki:foo:start', '[[..:..:one_ns_up:]]', 'Test setup'); + idx_addPage('wiki:foo:start'); + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + + $this->assertTrue($move->movePage('wiki:foo:start', 'wiki:foo:bar:start')); + $this->assertEquals('[[one_ns_up:]]', rawWiki('wiki:foo:bar:start')); + + } + function test_move_ns_in_same_ns() { diff --git a/helper/handler.php b/helper/handler.php index fecf4f3..09227b2 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -78,6 +78,27 @@ public function resolveMoves($old, $type) { return $old; // this is now new } + /** + * if the old link ended with a colon and the new one is a start page, adjust + * + * @param $relold the old, possibly relative ID + * @param $new the new, full qualified ID + * @param $type 'media' or 'page' + * @return string + */ + protected function _nsStartCheck($relold, $new, $type) { + global $conf; + if($type == 'page' && substr($relold, -1) == ':') { + $len = strlen($conf['start']); + if($new == $conf['start']) { + $new = '.:'; + } else if(substr($new, -1 * ($len + 1)) == ':' . $conf['start']) { + $new = substr($new, 0, -1 * $len); + } + } + return $new; + } + /** * Construct a new ID relative to the current page's location * @@ -109,13 +130,17 @@ public function relativeLink($relold, $new, $type) { if($conf['useslash']) $relold = str_replace('/', ':', $relold); // check if the link was relative - if(strpos($relold, ':') === false ||$relold{0} == '.' || substr($relold, -1) == ':') { + if(strpos($relold, ':') === false ||$relold{0} == '.') { $wasrel = true; } else { $wasrel = false; } + // if it wasn't relative then, leave it absolute now, too - if(!$wasrel) return $new; + if(!$wasrel) { + $new = $this->_nsStartCheck($relold, $new, $type); + return $new; + } // split the paths and see how much common parts there are $selfpath = explode(':', $this->ns); @@ -138,19 +163,13 @@ public function relativeLink($relold, $new, $type) { if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; // if the old link ended with a colon and the new one is a start page, adjust - if($type == 'page' && substr($relold, -1) == ':') { - $len = strlen($conf['start']); - if($newrel == $conf['start']) { - $newrel = '.:'; - } else if(substr($newrel, -1 * ($len + 1)) == ':' . $conf['start']) { - $newrel = substr($newrel, 0, -1 * $len); - } - } + $newrel = $this->_nsStartCheck($relold,$newrel,$type); // don't use relative paths if it is ridicoulus: if(strlen($newrel) > strlen($new)) { $newrel = $new; if($this->ns && !getNS($new)) $newrel = ':' . $newrel; + $newrel = $this->_nsStartCheck($relold,$newrel,$type); } return $newrel; From b38aa59a4a5ced1beaebd79968f590e22938ba8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 16 Mar 2015 17:38:12 +0100 Subject: [PATCH 139/338] When adding .. to relative links, also add a colon Using the notation with an extra colon as opposed to the shorthand is clearer The shorthand is broken for more than one level, see Dokuwiki Issue \#1076: https://github.com/splitbrain/dokuwiki/issues/1076 --- _test/handler.test.php | 4 ++-- _test/pagemove.test.php | 27 ++++++++++++++------------- helper/handler.php | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index 2555e3e..4a2318b 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -17,11 +17,11 @@ public function test_relativeLink() { $tests = array( 'deep:namespace:new1' => 'new1', - 'deep:new2' => '..new2', + 'deep:new2' => '..:new2', 'new3' => ':new3', // absolute is shorter than relative 'deep:namespace:deeper:new4' => '.deeper:new4', 'deep:namespace:deeper:deepest:new5' => '.deeper:deepest:new5', - 'deep:foobar:new6' => '..foobar:new6', + 'deep:foobar:new6' => '..:foobar:new6', ); foreach($tests as $new => $rel) { diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 01a0ba9..01838e7 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -22,6 +22,7 @@ class plugin_move_pagemove_test extends DokuWikiTest { // @todo Check backlinks of a sub-namespace page (moving same, up, down, different) function setUp() { + parent::setUpBeforeClass(); $this->pluginsEnabled[] = 'move'; global $ID; global $INFO; @@ -302,9 +303,9 @@ function test_move_page_to_parallel_ns() { $newContent = rawWiki($this->movedToId); $expectedContent = <<movedId]] [[$newId|:$this->movedId]] -[[..parallel_ns:new_page|..current_ns:test_page]] -[[..parallel_ns:new_page|..:current_ns:test_page]] -[[..parallel_ns:new_page|test_page]] -[[..parallel_ns:new_page|.test_page]] -[[..parallel_ns:new_page|.:test_page]] +[[..:parallel_ns:new_page|..current_ns:test_page]] +[[..:parallel_ns:new_page|..:current_ns:test_page]] +[[..:parallel_ns:new_page|test_page]] +[[..:parallel_ns:new_page|.test_page]] +[[..:parallel_ns:new_page|.:test_page]] [[..test_page|..test_page]] [[..:test_page|..:test_page]] [[.:..:test_page|.:..:test_page]] @@ -464,11 +465,11 @@ function test_move_page_to_parent_ns() { $expectedContent = <<movedId]] [[$newId|:$this->movedId]] -[[..new_page|..current_ns:test_page]] -[[..new_page|..:current_ns:test_page]] -[[..new_page|test_page]] -[[..new_page|.test_page]] -[[..new_page|.:test_page]] +[[..:new_page|..current_ns:test_page]] +[[..:new_page|..:current_ns:test_page]] +[[..:new_page|test_page]] +[[..:new_page|.test_page]] +[[..:new_page|.:test_page]] [[..test_page|..test_page]] [[..:test_page|..:test_page]] [[.:..:test_page|.:..:test_page]] diff --git a/helper/handler.php b/helper/handler.php index 09227b2..764270d 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -153,7 +153,7 @@ public function relativeLink($relold, $new, $type) { // we now have the non-common part and a number of uppers $ups = max(count($selfpath) - $common, 0); $remainder = array_slice($goalpath, $common); - $upper = $ups ? array_fill(0, $ups, '..') : array(); + $upper = $ups ? array_fill(0, $ups, '..:') : array(); // build the new relative path $newrel = join(':', $upper); From 0bdd57d722bafadf978c91015c7f8fd457809dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 17 Mar 2015 14:57:08 +0100 Subject: [PATCH 140/338] Remove redundant code. This is already done by the line before: $meta = $this->getMoveMeta($id); --- helper/rewrite.php | 1 - 1 file changed, 1 deletion(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index c79343e..7c9bea1 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -94,7 +94,6 @@ public function setMoveMetas($id, $moves, $type) { if(!page_exists($id, '', false)) return; $meta = $this->getMoveMeta($id); - if(!isset($meta[$type])) $meta[$type] = array(); foreach($moves as $src => $dst) { $meta[$type][] = array($src, $dst); } From 35aedf104f602b71c9e1b35480273d7092b7c16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 17 Mar 2015 14:57:59 +0100 Subject: [PATCH 141/338] Do not write if statements on one line. Writing if statements on one line is bad for code coverage, because the line will always show up as covered, whether the then statement was actually executed or note. --- helper/rewrite.php | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index 7c9bea1..10a714f 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -52,9 +52,15 @@ public function getMoveMeta($id) { */ $meta = isset($all_meta[self::METAKEY]) ? $all_meta[self::METAKEY] : array(); - if(!isset($meta['origin'])) $meta['origin'] = ''; - if(!isset($meta['pages'])) $meta['pages'] = array(); - if(!isset($meta['media'])) $meta['media'] = array(); + if(!isset($meta['origin'])) { + $meta['origin'] = ''; + } + if(!isset($meta['pages'])) { + $meta['pages'] = array(); + } + if(!isset($meta['media'])) { + $meta['media'] = array(); + } return $meta; } @@ -90,8 +96,12 @@ public function setMoveMeta($id, $src, $dst, $type) { * @throws Exception */ public function setMoveMetas($id, $moves, $type) { - if($type != 'pages' && $type != 'media') throw new Exception('wrong type specified'); - if(!page_exists($id, '', false)) return; + if($type != 'pages' && $type != 'media') { + throw new Exception('wrong type specified'); + } + if(!page_exists($id, '', false)) { + return; + } $meta = $this->getMoveMeta($id); foreach($moves as $src => $dst) { @@ -111,7 +121,9 @@ public function setMoveMetas($id, $moves, $type) { public function setSelfMoveMeta($id) { $meta = $this->getMoveMeta($id); // was this page moved multiple times? keep the orignal name til rewriting occured - if(isset($meta['origin']) && $meta['origin'] !== '') return; + if(isset($meta['origin']) && $meta['origin'] !== '') { + return; + } $meta['origin'] = $id; p_set_metadata($id, array(self::METAKEY => $meta), false, true); @@ -205,7 +217,9 @@ public function rewrite($id, $text) { */ public function rewritePage($id, $text = null) { $meta = $this->getMoveMeta($id); - if(is_null($text)) $text = rawWiki($id); + if(is_null($text)) { + $text = rawWiki($id); + } if($meta['pages'] || $meta['media']) { $old_text = $text; @@ -232,4 +246,4 @@ public function rewritePage($id, $text = null) { return $text; } -} \ No newline at end of file +} From 226280c61f49da109b8229ac4ace2668230e27ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 17 Mar 2015 15:09:31 +0100 Subject: [PATCH 142/338] Add test to close uncovered case --- _test/pagemove.test.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 01838e7..f3c626a 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -553,6 +553,21 @@ function test_move_no_long_rel_links_keep_colon() { } + /** + * @covers helper_plugin_move_handler::_nsStartCheck + */ + function test_move_to_thisns_start(){ + saveWikiText('wiki:foo:test_page', '[[..:..:bar:]]', 'Test setup'); + idx_addPage('wiki:foo:test_page'); + saveWikiText('bar:start', 'foo', 'Test setup'); + idx_addPage('bar:start'); + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + + $this->assertTrue($move->movePage('bar:start', 'wiki:foo:start')); + $this->assertEquals('[[.:]]', rawWiki('wiki:foo:test_page')); + } function test_move_ns_in_same_ns() { From f67764696076d8b647955f929118e9f362d56967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Wed, 18 Mar 2015 15:18:33 +0100 Subject: [PATCH 143/338] Create and remove general move-lockfile --- helper/plan.php | 5 ++++- helper/rewrite.php | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index 58b1300..c1985ef 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -271,6 +271,9 @@ public function abort() { } $this->plan = array(); $this->loadOptions(); + if (file_exists(DOKU_INC . "data/locks/move.lock")) { + unlink(DOKU_INC . "data/locks/move.lock"); + } } /** @@ -879,4 +882,4 @@ protected function log($type, $from, $to, $success) { $log = "$now\t$date\t$type\t$from\t$to\t$ok\t$msg\n"; io_saveFile($file, $log, true); } -} \ No newline at end of file +} diff --git a/helper/rewrite.php b/helper/rewrite.php index 10a714f..9fbd4e4 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -137,6 +137,7 @@ public function setSelfMoveMeta($id) { public static function isLocked() { global $PLUGIN_MOVE_WORKING; return (isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0); + //return ((isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0) || file_exists(DOKU_INC . 'data/locks/move.lock')); } /** @@ -144,7 +145,17 @@ public static function isLocked() { */ public static function addLock() { global $PLUGIN_MOVE_WORKING; + dbglog("addLock: PLUGIN_MOVE_WORKING: " . $PLUGIN_MOVE_WORKING . "\n"); $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING + 1 : 1; + $lockfile = DOKU_INC . 'data/locks/move.lock'; + if (!file_exists($lockfile)) { + file_put_contents($lockfile, "1\n"); + } else { + $stack = intval(file_get_contents($lockfile)); + dbglog("addLock: " . $stack . "\n"); + ++$stack; + file_put_contents($lockfile, strval($stack)); + } } /** @@ -152,7 +163,21 @@ public static function addLock() { */ public static function removeLock() { global $PLUGIN_MOVE_WORKING; + dbglog("removeLock: PLUGIN_MOVE_WORKING: " . $PLUGIN_MOVE_WORKING . "\n"); $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING - 1 : 0; + $lockfile = DOKU_INC . 'data/locks/move.lock'; + if (!file_exists($lockfile)) { + throw new Exception("removeLock failed: lockfile missing"); + } else { + $stack = intval(file_get_contents($lockfile)); + dbglog("removeLock: " . $stack . "\n"); + if($stack === 1) { + unlink($lockfile); + } else { + --$stack; + file_put_contents($lockfile, strval($stack)); + } + } } From 2dcfcb8a68d04787defe45b90685ad657f4b3abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 19 Mar 2015 17:46:16 +0100 Subject: [PATCH 144/338] Dirty snapshot of a unittest, things are still unclear Unclear why metadata behaves differently for start and :start --- _test/namespace_move.test.php | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index df5e8f3..146d5cd 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -70,4 +70,113 @@ public function test_move_missing() { $this->assertEquals('[[missing]]', rawWiki('newspace:page')); } + + function test_move_large_ns(){ + global $conf; + + $test = '[[testns:start]] [[testns:test_page17]]'; + $summary = 'testsetup'; + + + saveWikiText(':start', $test, $summary); + idx_addPage(':start'); + saveWikiText('testns:start', $test, $summary); + idx_addPage('testns:start'); + saveWikiText('testns:test_page1', $test, $summary); + idx_addPage('testns:test_page1'); + saveWikiText('testns:test_page2', $test, $summary); + idx_addPage('testns:test_page2'); + saveWikiText('testns:test_page3', $test, $summary); + idx_addPage('testns:test_page3'); + saveWikiText('testns:test_page4', $test, $summary); + idx_addPage('testns:test_page4'); + saveWikiText('testns:test_page5', $test, $summary); + idx_addPage('testns:test_page5'); + saveWikiText('testns:test_page6', $test, $summary); + idx_addPage('testns:test_page6'); + saveWikiText('testns:test_page7', $test, $summary); + idx_addPage('testns:test_page7'); + saveWikiText('testns:test_page8', $test, $summary); + idx_addPage('testns:test_page8'); + saveWikiText('testns:test_page9', $test, $summary); + idx_addPage('testns:test_page9'); + saveWikiText('testns:test_page10', $test, $summary); + idx_addPage('testns:test_page10'); + saveWikiText('testns:test_page11', $test, $summary); + idx_addPage('testns:test_page11'); + saveWikiText('testns:test_page12', $test, $summary); + idx_addPage('testns:test_page12'); + saveWikiText('testns:test_page13', $test, $summary); + idx_addPage('testns:test_page13'); + saveWikiText('testns:test_page14', $test, $summary); + idx_addPage('testns:test_page14'); + saveWikiText('testns:test_page15', $test, $summary); + idx_addPage('testns:test_page15'); + saveWikiText('testns:test_page16', $test, $summary); + idx_addPage('testns:test_page16'); + saveWikiText('testns:test_page17', $test, $summary); + idx_addPage('testns:test_page17'); + saveWikiText('testns:test_page18', $test, $summary); + idx_addPage('testns:test_page18'); + saveWikiText('testns:test_page19', $test, $summary); + idx_addPage('testns:test_page19'); + + $conf['plugin']['move']['autorewrite'] = 0; + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('testns', 'foo:testns'); + + $plan->commit(); + global $conf; + $lockfile = $conf['lockdir'] . 'move.lock'; + file_exists($lockfile) ? print_r(file($lockfile)) :print_r('lockfile not found' . "\n"); + + print_r("\n" . "\n"); + $this->assertSame(10, $plan->nextStep(),"After processing first chunk of pages, 10 stepsshould be left"); + print_r(':start ' . rawWiki(':start') . "\n"); + $start_file = file(TMP_DIR . '/data/pages/start.txt'); + print_r($start_file[0]); + + print_r("\n" . "\n"); + $this->assertSame(1, $plan->nextStep(),"pages2"); + print_r(':start ' . rawWiki(':start') . "\n"); + $start_file = file(TMP_DIR . '/data/pages/start.txt'); + print_r($start_file[0]); + + print_r("\n" . "\n"); + $this->assertSame(1, $plan->nextStep(),"pages3"); + print_r(':start ' . rawWiki(':start') . "\n"); + $start_file = file(TMP_DIR . '/data/pages/start.txt'); + print_r($start_file[0]); + + $this->assertSame(0, $plan->nextStep()); + print_r("\n" . "\n" . "done?\n"); + $start_file = file(TMP_DIR . '/data/pages/start.txt'); + print_r($start_file[0] . "\n"); + print_r(':start ' . rawWiki(':start') . "\n"); + $start_file = file(TMP_DIR . '/data/pages/start.txt'); + print_r($start_file[0] . "\n". "\n"); + + /*$this->assertFileNotExists(wikiFN('testns:start')); + $this->assertFileExists(wikiFN('foo:testns:start')); + $this->assertFileExists(wikiFN('testns:test_page17'))*/; + print_r(':start ' . rawWiki(':start') . "\n"); + print_r('testns:start ' . rawWiki('testns:start') . "\n"); + print_r('foo:testns:start ' . rawWiki('foo:testns:start') . "\n"); + print_r('testns:test_page17 ' . rawWiki('testns:test_page17') . "\n"); + $start_file = file(TMP_DIR . '/data/pages/start.txt'); + print_r($start_file[0]); + file_exists($lockfile) ? print_r(file($lockfile)) :print_r('lockfile not found' . "\n"); + + $rewrite = plugin_load('helper', 'move_rewrite'); + print_r($rewrite->getMoveMeta(':start')); //todo: ':start' still has metadata, 'start' does not -- why? + print_r(':start ' . rawWiki(':start') . "\n"); + + + } + } From 839082238f607549abff20ea3f5214ffa1dc3db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 19 Mar 2015 17:50:00 +0100 Subject: [PATCH 145/338] Fix skipping on retry and add possible lock position --- admin/main.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/admin/main.php b/admin/main.php index 2ed3847..364e4b2 100644 --- a/admin/main.php +++ b/admin/main.php @@ -62,6 +62,7 @@ function handle() { // handle workflow button presses if($this->plan->isCommited()) { + helper_plugin_move_rewrite::addLock(); //todo: right place? switch($INPUT->str('ctl')) { case 'continue': $this->plan->nextStep(); @@ -252,7 +253,7 @@ protected function btn($control, $show = true) { if($control == 'start') $control = 'continue'; if($control == 'retry') { $control = 'continue'; - $skip = 1; + $skip = 0; //todo: this should be 0 for retry and 1 for skip } $class = 'move__control ctlfrm-' . $id; @@ -266,4 +267,4 @@ protected function btn($control, $show = true) { $form->addElement(form_makeButton('submit', 'admin', $label, array('class' => 'btn ctl-' . $control))); $form->printForm(); } -} \ No newline at end of file +} From ce36881ee56f655fd859461900b53f8417d5faba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 19 Mar 2015 17:54:21 +0100 Subject: [PATCH 146/338] Use conf-value for lock-dir and print-outs --- helper/plan.php | 16 ++++++++++++++-- helper/rewrite.php | 6 ++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index c1985ef..66d4dff 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -271,9 +271,13 @@ public function abort() { } $this->plan = array(); $this->loadOptions(); - if (file_exists(DOKU_INC . "data/locks/move.lock")) { - unlink(DOKU_INC . "data/locks/move.lock"); + global $conf; + $lockfile = $conf['lockdir'] . 'move.lock'; + if (file_exists($lockfile)) { + unlink($lockfile); } + global $PLUGIN_MOVE_WORKING; + $PLUGIN_MOVE_WORKING = 0; } /** @@ -290,6 +294,9 @@ public function commit() { if($this->options['commited']) throw new Exception('plan is commited already, can not be commited again'); + helper_plugin_move_rewrite::addLock(); + + usort($this->plan, array($this, 'planSorter')); // get all the documents to be moved and store them in their lists @@ -366,24 +373,28 @@ public function nextStep($skip = false) { helper_plugin_move_rewrite::addLock(); if(@filesize($this->files['pagelist']) > 1) { + print_r("pagelist\n"); $todo = $this->stepThroughDocuments(self::TYPE_PAGES, $skip); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['medialist']) > 1) { + print_r("medialist\n"); $todo = $this->stepThroughDocuments(self::TYPE_MEDIA, $skip); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['missing']) > 1 && @filesize($this->files['affected']) > 1) { + print_r("missing\n"); $todo = $this->stepThroughMissingPages(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['namespaces']) > 1) { + print_r("namespaces\n"); $todo = $this->stepThroughNamespaces(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call @@ -392,6 +403,7 @@ public function nextStep($skip = false) { helper_plugin_move_rewrite::removeLock(); if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { + print_r("rewrite pages\n"); $todo = $this->stepThroughAffectedPages(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call diff --git a/helper/rewrite.php b/helper/rewrite.php index 9fbd4e4..b37ce56 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -146,8 +146,9 @@ public static function isLocked() { public static function addLock() { global $PLUGIN_MOVE_WORKING; dbglog("addLock: PLUGIN_MOVE_WORKING: " . $PLUGIN_MOVE_WORKING . "\n"); + global $conf; $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING + 1 : 1; - $lockfile = DOKU_INC . 'data/locks/move.lock'; + $lockfile = $conf['lockdir'] . 'move.lock'; if (!file_exists($lockfile)) { file_put_contents($lockfile, "1\n"); } else { @@ -164,8 +165,9 @@ public static function addLock() { public static function removeLock() { global $PLUGIN_MOVE_WORKING; dbglog("removeLock: PLUGIN_MOVE_WORKING: " . $PLUGIN_MOVE_WORKING . "\n"); + global $conf; $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING - 1 : 0; - $lockfile = DOKU_INC . 'data/locks/move.lock'; + $lockfile = $conf['lockdir'] . 'move.lock'; if (!file_exists($lockfile)) { throw new Exception("removeLock failed: lockfile missing"); } else { From e9f45a3f6075b3a7d0c17289f88c1d4d6b2d7a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 15:58:05 +0200 Subject: [PATCH 147/338] Only actual unit tests should add coverage --- _test/namespace_move.test.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 146d5cd..d658ea0 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -16,6 +16,10 @@ public function setUp() { parent::setUp(); } + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + */ public function test_move_wiki_namespace() { global $AUTH_ACL; @@ -46,6 +50,10 @@ public function test_move_wiki_namespace() { $this->assertFileExists(mediaFN('foo:dokuwiki-128.png')); } + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + */ public function test_move_missing() { saveWikiText('oldspace:page', '[[missing]]', 'setup'); idx_addPage('oldspace:page'); @@ -71,6 +79,10 @@ public function test_move_missing() { $this->assertEquals('[[missing]]', rawWiki('newspace:page')); } + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + */ function test_move_large_ns(){ global $conf; From 1801385b3f15dbf06e70f3e7fc174d52835a3511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 16:00:40 +0200 Subject: [PATCH 148/338] Add unit test for helper_plugin_move_plan::findAffectedPages --- _test/namespace_move.test.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index d658ea0..6654bbd 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -16,6 +16,16 @@ public function setUp() { parent::setUp(); } + /** + * @coversNothing + */ + public function tearDown() { + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + $plan->abort(); + parent::tearDown(); + } + /** * This is an integration test, which checks the correct working of an entire namespace move. * Hence it is not an unittest, hence it @coversNothing @@ -79,6 +89,28 @@ public function test_move_missing() { $this->assertEquals('[[missing]]', rawWiki('newspace:page')); } + /** + * @covers helper_plugin_move_plan::findAffectedPages + * @uses Doku_Indexer + */ + public function test_move_affected() { + saveWikiText('oldaffectedspace:page', '[[missing]]', 'setup'); + idx_addPage('oldaffectedspace:page'); + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('oldaffectedspace', 'newaffectedspace'); + + $plan->commit(); + + $affected_file = file(TMP_DIR . '/data/meta/__move_affected'); + $this->assertSame('newaffectedspace:page',trim($affected_file[0])); + + + } + /** * This is an integration test, which checks the correct working of an entire namespace move. * Hence it is not an unittest, hence it @coversNothing From 41faadc6a4b95f06cd588716bb27a62af93536b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 16:08:30 +0200 Subject: [PATCH 149/338] global $PLUGIN_MOVE_WORKING should be unset, not 0 --- helper/plan.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 66d4dff..e7fcf83 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -276,8 +276,7 @@ public function abort() { if (file_exists($lockfile)) { unlink($lockfile); } - global $PLUGIN_MOVE_WORKING; - $PLUGIN_MOVE_WORKING = 0; + unset($GLOBALS['PLUGIN_MOVE_WORKING']); } /** From fa136bbb7a1f6cc0f49b4df72436b0d9ea374d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 16:15:36 +0200 Subject: [PATCH 150/338] src ns is not affected, it's gone. dst ns is affected --- helper/plan.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index e7fcf83..ea0afbd 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -340,7 +340,7 @@ public function commit() { } } // store what pages are affected by this move - $this->findAffectedPages($move['src'], $move['class'], $move['type']); + $this->findAffectedPages($move['src'], $move['dst'], $move['class'], $move['type']); } $this->storeDocumentLists(); @@ -695,22 +695,31 @@ protected function addToAffectedPagesList($pages) { * * Calls addToAffectedPagesList() directly to store the result * - * @param string $src + * @param string $src source namespace + * @param string $dst destination namespace * @param int $class * @param int $type */ - protected function findAffectedPages($src, $class, $type) { + protected function findAffectedPages($src, $dst, $class, $type) { $idx = idx_get_indexer(); if($class == self::CLASS_NS) { - $src = "$src:*"; // use wildcard lookup for namespaces + $src_ = "$src:*"; // use wildcard lookup for namespaces } $pages = array(); if($type == self::TYPE_PAGES) { - $pages = $idx->lookupKey('relation_references', $src); + $pages = $idx->lookupKey('relation_references', $src_); + $len = strlen($src); + foreach($pages as &$page) { + if (substr($page, 0, $len + 1) === "$src:") { + $page = $dst . substr($page, $len + 1); + } + } + unset($page); } else if($type == self::TYPE_MEDIA) { - $pages = $idx->lookupKey('relation_media', $src); + $pages = $idx->lookupKey('relation_media', $src_); + //todo: we may have to rewrite src -> dst here as well. tests needed } $this->addToAffectedPagesList($pages); From e20e391fe021baf20bd0911c099ca45ae33e31e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 18:15:13 +0200 Subject: [PATCH 151/338] Also check lockfile and remove debug output Currently there is no use-case for the process-based lock, where the lockfile alone would not be enough. Maybe the process-based lock can be removed? --- helper/rewrite.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index b37ce56..5823e36 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -136,8 +136,9 @@ public function setSelfMoveMeta($id) { */ public static function isLocked() { global $PLUGIN_MOVE_WORKING; - return (isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0); - //return ((isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0) || file_exists(DOKU_INC . 'data/locks/move.lock')); + global $conf; + $lockfile = $conf['lockdir'] . 'move.lock'; + return ((isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0) || file_exists($lockfile)); } /** @@ -145,7 +146,6 @@ public static function isLocked() { */ public static function addLock() { global $PLUGIN_MOVE_WORKING; - dbglog("addLock: PLUGIN_MOVE_WORKING: " . $PLUGIN_MOVE_WORKING . "\n"); global $conf; $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING + 1 : 1; $lockfile = $conf['lockdir'] . 'move.lock'; @@ -153,7 +153,6 @@ public static function addLock() { file_put_contents($lockfile, "1\n"); } else { $stack = intval(file_get_contents($lockfile)); - dbglog("addLock: " . $stack . "\n"); ++$stack; file_put_contents($lockfile, strval($stack)); } @@ -164,7 +163,6 @@ public static function addLock() { */ public static function removeLock() { global $PLUGIN_MOVE_WORKING; - dbglog("removeLock: PLUGIN_MOVE_WORKING: " . $PLUGIN_MOVE_WORKING . "\n"); global $conf; $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING - 1 : 0; $lockfile = $conf['lockdir'] . 'move.lock'; @@ -172,7 +170,6 @@ public static function removeLock() { throw new Exception("removeLock failed: lockfile missing"); } else { $stack = intval(file_get_contents($lockfile)); - dbglog("removeLock: " . $stack . "\n"); if($stack === 1) { unlink($lockfile); } else { From c50d2a48e18f43f87725c9a868eba421bb1e6baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 18:19:54 +0200 Subject: [PATCH 152/338] When the page is locked, rewrite it for show only --- action/rewrite.php | 9 ++++++--- helper/rewrite.php | 28 +++++++++++++++------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/action/rewrite.php b/action/rewrite.php index ada8bc8..3d65aa8 100644 --- a/action/rewrite.php +++ b/action/rewrite.php @@ -36,7 +36,10 @@ function handle_read(Doku_Event $event, $param) { if($event->data[3]) return; // only rewrite if not in move already - if(helper_plugin_move_rewrite::isLocked()) return; + $save = true; + if(helper_plugin_move_rewrite::isLocked()) { + $save = false; + } $id = $event->data[2]; if($event->data[1]) $id = $event->data[1] . ':' . $id; @@ -67,7 +70,7 @@ function handle_read(Doku_Event $event, $param) { $helper = plugin_load('helper', 'move_rewrite', true); if(!is_null($helper)) { $stack[$id] = true; - $event->result = $helper->rewritePage($id, $event->result); + $event->result = $helper->rewritePage($id, $event->result, $save); unset($stack[$id]); } } @@ -102,4 +105,4 @@ function handle_cache(Doku_Event $event, $param) { } } } -} \ No newline at end of file +} diff --git a/helper/rewrite.php b/helper/rewrite.php index 5823e36..8ad4d72 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -239,7 +239,7 @@ public function rewrite($id, $text) { * @param string|null $text Old content of the page. When null is given the content is loaded from disk * @return string|bool The rewritten content, false on error */ - public function rewritePage($id, $text = null) { + public function rewritePage($id, $text = null, $save = true) { $meta = $this->getMoveMeta($id); if(is_null($text)) { $text = rawWiki($id); @@ -251,19 +251,21 @@ public function rewritePage($id, $text = null) { $changed = ($old_text != $text); $file = wikiFN($id, '', false); - if(is_writable($file) || !$changed) { - if($changed) { - // Wait a second when the page has just been rewritten - $oldRev = filemtime(wikiFN($id)); - if($oldRev == time()) sleep(1); - - saveWikiText($id, $text, $this->symbol . ' ' . $this->getLang('linkchange'), $this->getConf('minor')); + if ($save === true) { + if(is_writable($file) || !$changed) { + if($changed) { + // Wait a second when the page has just been rewritten + $oldRev = filemtime(wikiFN($id)); + if($oldRev == time()) sleep(1); + + saveWikiText($id, $text, $this->symbol . ' ' . $this->getLang('linkchange'), $this->getConf('minor')); + } + $this->unsetMoveMeta($id); + } else { + // FIXME: print error here or fail silently? + msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); + return false; } - $this->unsetMoveMeta($id); - } else { - // FIXME: print error here or fail silently? - msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); - return false; } } From e1df79b23ef31ddeda1f2b2631f09132b2eb3c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 18:59:45 +0200 Subject: [PATCH 153/338] Test for requests during move However this does not test for a request request which starts a new process. So pure process-based locking still lets this test pass. --- _test/namespace_move.test.php | 57 +++++++++++++---------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 6654bbd..f33ad4c 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -177,49 +177,34 @@ function test_move_large_ns(){ $plan->commit(); global $conf; $lockfile = $conf['lockdir'] . 'move.lock'; - file_exists($lockfile) ? print_r(file($lockfile)) :print_r('lockfile not found' . "\n"); - print_r("\n" . "\n"); - $this->assertSame(10, $plan->nextStep(),"After processing first chunk of pages, 10 stepsshould be left"); - print_r(':start ' . rawWiki(':start') . "\n"); - $start_file = file(TMP_DIR . '/data/pages/start.txt'); - print_r($start_file[0]); + $this->assertSame(10, $plan->nextStep(),"After processing first chunk of pages, 10 steps should be left"); - print_r("\n" . "\n"); - $this->assertSame(1, $plan->nextStep(),"pages2"); - print_r(':start ' . rawWiki(':start') . "\n"); - $start_file = file(TMP_DIR . '/data/pages/start.txt'); - print_r($start_file[0]); + $request = new TestRequest(); + $response = $request->get(); + $actual_response = $response->getContent(); + //clean away clutter + $actual_response = substr($actual_response,strpos($actual_response,"") + 23); + $actual_response = substr($actual_response,0,strpos($actual_response,"")); + $actual_response = trim($actual_response); + $actual_response = ltrim($actual_response,"

    "); + $actual_response = rtrim($actual_response,"

    "); + $actual_response = trim($actual_response); - print_r("\n" . "\n"); - $this->assertSame(1, $plan->nextStep(),"pages3"); - print_r(':start ' . rawWiki(':start') . "\n"); - $start_file = file(TMP_DIR . '/data/pages/start.txt'); - print_r($start_file[0]); + $expected_response = 'testns test_page17'; + $this->assertSame($expected_response,$actual_response); - $this->assertSame(0, $plan->nextStep()); - print_r("\n" . "\n" . "done?\n"); + $expected_file_contents = '[[testns:start]] [[testns:test_page17]]'; $start_file = file(TMP_DIR . '/data/pages/start.txt'); - print_r($start_file[0] . "\n"); - print_r(':start ' . rawWiki(':start') . "\n"); - $start_file = file(TMP_DIR . '/data/pages/start.txt'); - print_r($start_file[0] . "\n". "\n"); - - /*$this->assertFileNotExists(wikiFN('testns:start')); - $this->assertFileExists(wikiFN('foo:testns:start')); - $this->assertFileExists(wikiFN('testns:test_page17'))*/; - print_r(':start ' . rawWiki(':start') . "\n"); - print_r('testns:start ' . rawWiki('testns:start') . "\n"); - print_r('foo:testns:start ' . rawWiki('foo:testns:start') . "\n"); - print_r('testns:test_page17 ' . rawWiki('testns:test_page17') . "\n"); - $start_file = file(TMP_DIR . '/data/pages/start.txt'); - print_r($start_file[0]); - file_exists($lockfile) ? print_r(file($lockfile)) :print_r('lockfile not found' . "\n"); + $actual_file_contents = $start_file[0]; + $this->assertSame($expected_file_contents,$actual_file_contents); + /** @var helper_plugin_move_rewrite $rewrite */ $rewrite = plugin_load('helper', 'move_rewrite'); - print_r($rewrite->getMoveMeta(':start')); //todo: ':start' still has metadata, 'start' does not -- why? - print_r(':start ' . rawWiki(':start') . "\n"); - + $expected_move_meta = array('origin'=> 'testns:start', 'pages' => array(array('testns:start','foo:testns:start')),'media' => array()); + $actual_move_media = $rewrite->getMoveMeta('foo:testns:start'); + $this->assertSame($expected_move_meta,$actual_move_media); + $this->assertFileExists($lockfile); } From e45cf51497ef41ec45157d516ad2d01f06b281ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Mar 2015 19:04:26 +0200 Subject: [PATCH 154/338] Remove debug printouts --- helper/plan.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index ea0afbd..72b141c 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -372,28 +372,24 @@ public function nextStep($skip = false) { helper_plugin_move_rewrite::addLock(); if(@filesize($this->files['pagelist']) > 1) { - print_r("pagelist\n"); $todo = $this->stepThroughDocuments(self::TYPE_PAGES, $skip); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['medialist']) > 1) { - print_r("medialist\n"); $todo = $this->stepThroughDocuments(self::TYPE_MEDIA, $skip); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['missing']) > 1 && @filesize($this->files['affected']) > 1) { - print_r("missing\n"); $todo = $this->stepThroughMissingPages(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } if(@filesize($this->files['namespaces']) > 1) { - print_r("namespaces\n"); $todo = $this->stepThroughNamespaces(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call @@ -402,7 +398,6 @@ public function nextStep($skip = false) { helper_plugin_move_rewrite::removeLock(); if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { - print_r("rewrite pages\n"); $todo = $this->stepThroughAffectedPages(); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call From ee2d4af6ba3733df9d63cf8f0a03ceea3847647a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 15:15:39 +0200 Subject: [PATCH 155/338] Make helper_plugin_move_plan::stepThroughDocuments unit-testable The helper_plugin_move_op class-instance was moved to a class object so we are able to replace it with an mock object in unit-tests. Doing this we are both able to break the dependency and prevent any pages from actually being moved and sense the values handed to the helper_plugin_move_op instance. The stepThroughDocuments function has now suffcient unit-test coverage to begin refactoring. --- _test/stepThroughDocuments.test.php | 252 ++++++++++++++++++++++++++++ helper/plan.php | 19 ++- 2 files changed, 265 insertions(+), 6 deletions(-) create mode 100644 _test/stepThroughDocuments.test.php diff --git a/_test/stepThroughDocuments.test.php b/_test/stepThroughDocuments.test.php new file mode 100644 index 0000000..15ace6b --- /dev/null +++ b/_test/stepThroughDocuments.test.php @@ -0,0 +1,252 @@ +MoveOperator = new helper_plugin_move_op_mock; + } + + public function stepThroughDocumentsCall($type = parent::TYPE_PAGES, $skip = false) { + return $this->stepThroughDocuments($type, $skip); + } + + public function getMoveOperator() { + return $this->MoveOperator; + } + + public function setMoveOperator($newMoveOPerator) { + $this->MoveOperator = $newMoveOPerator; + } + + protected function log($type, $from, $to, $success) { + $logEntry = array($type,$from,$to,$success); + array_push($this->moveLog,$logEntry); + } + + + +} + +class helper_plugin_move_op_mock extends helper_plugin_move_op { + + public $movedPages = array(); + public $fail = false; + + public function movePage($src, $dst) { + if ($this->fail !== false && count($this->movedPages) == $this->fail) { + $this->fail=false; + return false; + } + $moveOperation = array($src => $dst); + array_push($this->movedPages,$moveOperation); + return true; + } +} + + + + +/** + * Test cases for namespace move functionality of the move plugin + * + * @group plugin_move + * @group plugins + */ +class plugin_move_stepThroughDocuments_test extends DokuWikiTest { + + public function setUp() { + parent::setUp(); + $opts_file = dirname(DOKU_CONF) . '/data/meta/__move_opts'; + if(file_exists($opts_file)){ + unlink($opts_file); + } + + $file = "oldns:page01\tnewns:page01\n" + . "oldns:page02\tnewns:page02\n" + . "oldns:page03\tnewns:page03\n" + . "oldns:page04\tnewns:page04\n" + . "oldns:page05\tnewns:page05\n" + . "oldns:page06\tnewns:page06\n" + . "oldns:page07\tnewns:page07\n" + . "oldns:page08\tnewns:page08\n" + . "oldns:page09\tnewns:page09\n" + . "oldns:page10\tnewns:page10\n" + . "oldns:page11\tnewns:page11\n" + . "oldns:page12\tnewns:page12\n" + . "oldns:page13\tnewns:page13\n" + . "oldns:page14\tnewns:page14\n" + . "oldns:page15\tnewns:page15\n" + . "oldns:page16\tnewns:page16\n" + . "oldns:page17\tnewns:page17\n" + . "oldns:page18\tnewns:page18"; + $file_path = dirname(DOKU_CONF) . '/data/meta/__move_pagelist'; + io_saveFile($file_path,$file); + } + + + /** + * @covers helper_plugin_move_plan::stepThroughDocuments + */ + public function test_stepThroughPages() { + + $file_path = dirname(DOKU_CONF) . '/data/meta/__move_pagelist'; + $mock = new helper_plugin_move_plan_mock(); + $actual_return = $mock->stepThroughDocumentsCall(); + $actual_file = file_get_contents($file_path); + $expected_file = "oldns:page01\tnewns:page01\n" + . "oldns:page02\tnewns:page02\n" + . "oldns:page03\tnewns:page03\n" + . "oldns:page04\tnewns:page04\n" + . "oldns:page05\tnewns:page05\n" + . "oldns:page06\tnewns:page06\n" + . "oldns:page07\tnewns:page07\n" + . "oldns:page08\tnewns:page08"; + + $expected_pages_run = -10; + $this->assertSame($expected_pages_run,$actual_return,"return values differ"); + $this->assertSame($expected_file,$actual_file, "files differ"); + $actual_move_Operator = $mock->getMoveOperator(); + $this->assertSame(array('oldns:page18' => 'newns:page18',),$actual_move_Operator->movedPages[0]); + $this->assertSame(array('oldns:page09' => 'newns:page09',),$actual_move_Operator->movedPages[9]); + $this->assertTrue(!isset($actual_move_Operator->movedPages[10])); + + $expected_log = array('P','oldns:page18','newns:page18',true); + $this->assertSame($expected_log,$mock->moveLog[0]); + + $expected_log = array('P','oldns:page09','newns:page09',true); + $this->assertSame($expected_log,$mock->moveLog[9]); + $this->assertTrue(!isset($mock->moveLog[10])); + } + + /** + * @covers helper_plugin_move_plan::stepThroughDocuments + */ + public function test_stepThroughPages_skip() { + + $file_path = dirname(DOKU_CONF) . '/data/meta/__move_pagelist'; + $mock = new helper_plugin_move_plan_mock(); + $actual_return = $mock->stepThroughDocumentsCall(1,true); + $actual_file = file_get_contents($file_path); + $expected_file = "oldns:page01\tnewns:page01\n" + . "oldns:page02\tnewns:page02\n" + . "oldns:page03\tnewns:page03\n" + . "oldns:page04\tnewns:page04\n" + . "oldns:page05\tnewns:page05\n" + . "oldns:page06\tnewns:page06\n" + . "oldns:page07\tnewns:page07\n" + . "oldns:page08\tnewns:page08"; + $expected_pages_run = -10; + $this->assertSame($expected_pages_run,$actual_return,"return values differ"); + $this->assertSame($expected_file,$actual_file, "files differ"); + $actual_move_Operator = $mock->getMoveOperator(); + $this->assertSame(array('oldns:page17' => 'newns:page17',),$actual_move_Operator->movedPages[0]); + $this->assertSame(array('oldns:page09' => 'newns:page09',),$actual_move_Operator->movedPages[8]); + $this->assertTrue(!isset($actual_move_Operator->movedPages[9])); + + $expected_log = array('P','oldns:page17','newns:page17',true); + $this->assertSame($expected_log,$mock->moveLog[0]); + + $expected_log = array('P','oldns:page09','newns:page09',true); + $this->assertSame($expected_log,$mock->moveLog[8]); + $this->assertTrue(!isset($mock->moveLog[9])); + } + + /** + * @covers helper_plugin_move_plan::stepThroughDocuments + */ + public function test_stepThroughPages_fail() { + + $file_path = dirname(DOKU_CONF) . '/data/meta/__move_pagelist'; + $mock = new helper_plugin_move_plan_mock(); + $actual_move_Operator = $mock->getMoveOperator(); + $actual_move_Operator->fail = 5; + $mock->setMoveOperator($actual_move_Operator); + $actual_return = $mock->stepThroughDocumentsCall(); + $actual_file = file_get_contents($file_path); + $expected_file = "oldns:page01\tnewns:page01\n" + . "oldns:page02\tnewns:page02\n" + . "oldns:page03\tnewns:page03\n" + . "oldns:page04\tnewns:page04\n" + . "oldns:page05\tnewns:page05\n" + . "oldns:page06\tnewns:page06\n" + . "oldns:page07\tnewns:page07\n" + . "oldns:page08\tnewns:page08\n" + . "oldns:page09\tnewns:page09\n" + . "oldns:page10\tnewns:page10\n" + . "oldns:page11\tnewns:page11\n" + . "oldns:page12\tnewns:page12\n" + . "oldns:page13\tnewns:page13"; + + $expected_pages_run = false; + $this->assertSame($expected_pages_run,$actual_return,"return values differ"); + $this->assertSame($expected_file,$actual_file, "files differ"); + $actual_move_Operator = $mock->getMoveOperator(); + $this->assertSame(array('oldns:page18' => 'newns:page18',),$actual_move_Operator->movedPages[0]); + $lastIndex = 4; + $this->assertSame(array('oldns:page14' => 'newns:page14',),$actual_move_Operator->movedPages[$lastIndex]); + $this->assertTrue(!isset($actual_move_Operator->movedPages[$lastIndex + 1])); + + $expected_log = array('P','oldns:page13','newns:page13',false); + $this->assertSame($expected_log,$mock->moveLog[5]); + $this->assertTrue(!isset($mock->moveLog[6])); + } + + + /** + * @covers helper_plugin_move_plan::stepThroughDocuments + */ + public function test_stepThroughPages_fail_autoskip() { + global $conf; + $conf['plugin']['move']['autoskip'] = '1'; + + $file_path = dirname(DOKU_CONF) . '/data/meta/__move_pagelist'; + $mock = new helper_plugin_move_plan_mock(); + $actual_move_Operator = $mock->getMoveOperator(); + $actual_move_Operator->fail = 5; + $mock->setMoveOperator($actual_move_Operator); + $actual_return = $mock->stepThroughDocumentsCall(); + + $expected_pages_run = -10; + $this->assertSame($expected_pages_run,$actual_return,"return values differ"); + + $actual_file = file_get_contents($file_path); + $expected_file = "oldns:page01\tnewns:page01\n" + . "oldns:page02\tnewns:page02\n" + . "oldns:page03\tnewns:page03\n" + . "oldns:page04\tnewns:page04\n" + . "oldns:page05\tnewns:page05\n" + . "oldns:page06\tnewns:page06\n" + . "oldns:page07\tnewns:page07\n" + . "oldns:page08\tnewns:page08"; + + $this->assertSame($expected_file,$actual_file, "files differ"); + + + $actual_move_Operator = $mock->getMoveOperator(); + $this->assertSame(array('oldns:page18' => 'newns:page18',),$actual_move_Operator->movedPages[0]); + + $lastIndex = 8; + $this->assertSame(array('oldns:page09' => 'newns:page09',),$actual_move_Operator->movedPages[$lastIndex]); + $this->assertTrue(!isset($actual_move_Operator->movedPages[$lastIndex + 1]), "The number of moved pages is incorrect"); + + + $expected_log = array('P','oldns:page18','newns:page18',true); + $this->assertSame($expected_log,$mock->moveLog[0]); + + $expected_log = array('P','oldns:page13','newns:page13',false); + $this->assertSame($expected_log,$mock->moveLog[5]); + + $expected_log = array('P','oldns:page09','newns:page09',true); + $this->assertSame($expected_log,$mock->moveLog[9]); + + $this->assertTrue(!isset($mock->moveLog[10]), "The number of logged items is incorrect"); + } + + +} diff --git a/helper/plan.php b/helper/plan.php index 72b141c..20b1014 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -62,6 +62,9 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { /** @var array|null keeps reference list */ protected $referenceidx = null; + /** @var helper_plugin_move_op $MoveOperator */ + protected $MoveOperator = null; + /** * Constructor * @@ -80,6 +83,8 @@ public function __construct() { 'missing' => $conf['metadir'] . '/__move_missing' ); + $this->MoveOperator = plugin_load('helper', 'move_op'); + $this->loadOptions(); } @@ -462,9 +467,7 @@ public function previewHTML() { * @param bool $skip should the first item be skipped? * @return bool|int false on error, otherwise the number of remaining documents */ - protected function stepThroughDocuments($type = self::TYPE_PAGES, &$skip = false) { - /** @var helper_plugin_move_op $MoveOperator */ - $MoveOperator = plugin_load('helper', 'move_op'); + protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) { if($type == self::TYPE_PAGES) { $file = $this->files['pagelist']; @@ -485,14 +488,18 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, &$skip = false list($src, $dst) = explode("\t", trim($line)); // should this item be skipped? - if($skip) goto FINISH; + if($skip) { + goto FINISH; + } // move the page - if(!$MoveOperator->$call($src, $dst)) { + if(!$this->MoveOperator->$call($src, $dst)) { $this->log($mark, $src, $dst, false); // FAILURE! // automatically skip this item if wanted... - if($this->options['autoskip']) goto FINISH; + if($this->options['autoskip']) { + goto FINISH; + } // ...otherwise abort the operation fclose($doclist); return false; From 5dbb9073bce3affa5b4b4784a80d99fdc7639eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 15:26:59 +0200 Subject: [PATCH 156/338] Refactor stepThroughDocuments to remove GOTOs --- helper/plan.php | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 20b1014..a6d9253 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -488,30 +488,26 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) list($src, $dst) = explode("\t", trim($line)); // should this item be skipped? - if($skip) { - goto FINISH; - } - - // move the page - if(!$this->MoveOperator->$call($src, $dst)) { - $this->log($mark, $src, $dst, false); // FAILURE! - - // automatically skip this item if wanted... - if($this->options['autoskip']) { - goto FINISH; + if(!$skip) { + // move the page + if(!$this->MoveOperator->$call($src, $dst)) { + $this->log($mark, $src, $dst, false); // FAILURE! + + // automatically skip this item if wanted... + if(!$this->options['autoskip']) { + // ...otherwise abort the operation + fclose($doclist); + return false; + } + } else { + $this->log($mark, $src, $dst, true); // SUCCESS! } - // ...otherwise abort the operation - fclose($doclist); - return false; - } else { - $this->log($mark, $src, $dst, true); // SUCCESS! } /* * This adjusts counters and truncates the document list correctly * It is used to finalize a successful or skipped move */ - FINISH: $skip = false; ftruncate($doclist, ftell($doclist)); $this->options[$counter]--; From eae34e223142b2a4379055251f5bd627e998e494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 16:13:59 +0200 Subject: [PATCH 157/338] Check that the correct values are save to file --- _test/stepThroughDocuments.test.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/_test/stepThroughDocuments.test.php b/_test/stepThroughDocuments.test.php index 15ace6b..6d529e7 100644 --- a/_test/stepThroughDocuments.test.php +++ b/_test/stepThroughDocuments.test.php @@ -56,7 +56,9 @@ public function movePage($src, $dst) { * Test cases for namespace move functionality of the move plugin * * @group plugin_move + * @group plugin_move_unittests * @group plugins + * @group unittests */ class plugin_move_stepThroughDocuments_test extends DokuWikiTest { @@ -122,6 +124,10 @@ public function test_stepThroughPages() { $expected_log = array('P','oldns:page09','newns:page09',true); $this->assertSame($expected_log,$mock->moveLog[9]); $this->assertTrue(!isset($mock->moveLog[10])); + + $opts_file = dirname(DOKU_CONF) . '/data/meta/__move_opts'; + $actual_options = unserialize(io_readFile($opts_file)); + $this->assertSame($expected_pages_run,$actual_options['pages_run'],'saved options are wrong'); } /** @@ -155,6 +161,10 @@ public function test_stepThroughPages_skip() { $expected_log = array('P','oldns:page09','newns:page09',true); $this->assertSame($expected_log,$mock->moveLog[8]); $this->assertTrue(!isset($mock->moveLog[9])); + + $opts_file = dirname(DOKU_CONF) . '/data/meta/__move_opts'; + $actual_options = unserialize(io_readFile($opts_file)); + $this->assertSame($expected_pages_run,$actual_options['pages_run'],'saved options are wrong'); } /** @@ -164,8 +174,9 @@ public function test_stepThroughPages_fail() { $file_path = dirname(DOKU_CONF) . '/data/meta/__move_pagelist'; $mock = new helper_plugin_move_plan_mock(); + $fail_at_item = 5; $actual_move_Operator = $mock->getMoveOperator(); - $actual_move_Operator->fail = 5; + $actual_move_Operator->fail = $fail_at_item; $mock->setMoveOperator($actual_move_Operator); $actual_return = $mock->stepThroughDocumentsCall(); $actual_file = file_get_contents($file_path); @@ -195,6 +206,10 @@ public function test_stepThroughPages_fail() { $expected_log = array('P','oldns:page13','newns:page13',false); $this->assertSame($expected_log,$mock->moveLog[5]); $this->assertTrue(!isset($mock->moveLog[6])); + + $opts_file = dirname(DOKU_CONF) . '/data/meta/__move_opts'; + $actual_options = unserialize(io_readFile($opts_file)); + $this->assertSame(-$fail_at_item,$actual_options['pages_run'],'saved options are wrong'); } @@ -246,6 +261,10 @@ public function test_stepThroughPages_fail_autoskip() { $this->assertSame($expected_log,$mock->moveLog[9]); $this->assertTrue(!isset($mock->moveLog[10]), "The number of logged items is incorrect"); + + $opts_file = dirname(DOKU_CONF) . '/data/meta/__move_opts'; + $actual_options = unserialize(io_readFile($opts_file)); + $this->assertSame($expected_pages_run,$actual_options['pages_run'],'saved options are wrong'); } From 6a547a97d3e21800c28568882ec1cde0f2ce79dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 16:18:29 +0200 Subject: [PATCH 158/338] Adjust structure to comments and vice versa --- helper/plan.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index a6d9253..16f271f 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -484,16 +484,20 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) $doclist = fopen($file, 'a+'); for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { $line = $this->getLastLine($doclist); - if($line === false) break; + if($line === false) { + break; + } list($src, $dst) = explode("\t", trim($line)); // should this item be skipped? - if(!$skip) { - // move the page + if($skip === true) { + $skip = false; + } else { + // move the page if(!$this->MoveOperator->$call($src, $dst)) { $this->log($mark, $src, $dst, false); // FAILURE! - // automatically skip this item if wanted... + // automatically skip this item only if wanted... if(!$this->options['autoskip']) { // ...otherwise abort the operation fclose($doclist); @@ -508,7 +512,7 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) * This adjusts counters and truncates the document list correctly * It is used to finalize a successful or skipped move */ - $skip = false; + ftruncate($doclist, ftell($doclist)); $this->options[$counter]--; $this->saveOptions(); From 9a84ee74e7e8d5873402ef0f20dfbeb96e26e119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 16:25:48 +0200 Subject: [PATCH 159/338] Use more elaborate and precise variable names --- helper/plan.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 16f271f..1d43459 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -473,12 +473,12 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) $file = $this->files['pagelist']; $mark = 'P'; $call = 'movePage'; - $counter = 'pages_run'; + $items_run_counter = 'pages_run'; } else { $file = $this->files['medialist']; $mark = 'M'; $call = 'moveMedia'; - $counter = 'media_run'; + $items_run_counter = 'media_run'; } $doclist = fopen($file, 'a+'); @@ -514,12 +514,13 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) */ ftruncate($doclist, ftell($doclist)); - $this->options[$counter]--; + $this->options[$items_run_counter]--; $this->saveOptions(); + $return_items_run = $this->options[$items_run_counter]; } fclose($doclist); - return $this->options[$counter]; + return $return_items_run; } /** From 77c1bbbe5c43559bc7204c30ee6b8537b65db409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 16:26:39 +0200 Subject: [PATCH 160/338] Ensure that the function has only 1 exit --- helper/plan.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 1d43459..1db5958 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -501,7 +501,8 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) if(!$this->options['autoskip']) { // ...otherwise abort the operation fclose($doclist); - return false; + $return_items_run = false; + break; } } else { $this->log($mark, $src, $dst, true); // SUCCESS! @@ -519,7 +520,9 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) $return_items_run = $this->options[$items_run_counter]; } - fclose($doclist); + if ($return_items_run !== false) { + fclose($doclist); + } return $return_items_run; } From 89e29fdfab4ff97d58cf05926ec6848b7a7358eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 16:27:17 +0200 Subject: [PATCH 161/338] Save options only once, at the end of the function --- helper/plan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index 1db5958..8e46881 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -516,9 +516,9 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) ftruncate($doclist, ftell($doclist)); $this->options[$items_run_counter]--; - $this->saveOptions(); $return_items_run = $this->options[$items_run_counter]; } + $this->saveOptions(); if ($return_items_run !== false) { fclose($doclist); From af5c860e8e61d2a3970a10661e334573c9efb474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 18:51:58 +0200 Subject: [PATCH 162/338] Reduce filesytem writes by splitting log function --- _test/log.test.php | 46 +++++++++++++++++++++++++++++ _test/stepThroughDocuments.test.php | 5 ++-- helper/plan.php | 33 +++++++++++++++------ 3 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 _test/log.test.php diff --git a/_test/log.test.php b/_test/log.test.php new file mode 100644 index 0000000..07582fa --- /dev/null +++ b/_test/log.test.php @@ -0,0 +1,46 @@ +build_log_line('P','oldpage','newpage',true); + + $expected_log = "$now\t$date\tP\toldpage\tnewpage\tsuccess\t\n"; + + $this->assertSame($expected_log, $actual_log); + } + + public function test_log_build_line_failure() { + global $MSG; + $MSG = array(); + $msg = array('msg'=>"TestMessage01",); + array_push($MSG,$msg); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + $now = time(); + $date = date('Y-m-d H:i:s', $now); + + $actual_log = $plan->build_log_line('P','oldpage','newpage',false); + + $expected_log = "$now\t$date\tP\toldpage\tnewpage\tfailed\tTestMessage01\n"; + + $this->assertSame($expected_log, $actual_log); + } + +} diff --git a/_test/stepThroughDocuments.test.php b/_test/stepThroughDocuments.test.php index 6d529e7..928c387 100644 --- a/_test/stepThroughDocuments.test.php +++ b/_test/stepThroughDocuments.test.php @@ -24,9 +24,10 @@ public function setMoveOperator($newMoveOPerator) { $this->MoveOperator = $newMoveOPerator; } - protected function log($type, $from, $to, $success) { + public function build_log_line($type, $from, $to, $success) { $logEntry = array($type,$from,$to,$success); array_push($this->moveLog,$logEntry); + return parent::build_log_line($type, $from, $to, $success); } @@ -53,7 +54,7 @@ public function movePage($src, $dst) { /** - * Test cases for namespace move functionality of the move plugin + * Test cases for helper_plugin_move_plan::stepThroughDocuments function of the move plugin * * @group plugin_move * @group plugin_move_unittests diff --git a/helper/plan.php b/helper/plan.php index 8e46881..d12232c 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -482,6 +482,7 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) } $doclist = fopen($file, 'a+'); + $log = ""; for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { $line = $this->getLastLine($doclist); if($line === false) { @@ -495,7 +496,7 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) } else { // move the page if(!$this->MoveOperator->$call($src, $dst)) { - $this->log($mark, $src, $dst, false); // FAILURE! + $log .= $this->build_log_line($mark, $src, $dst, false); // FAILURE! // automatically skip this item only if wanted... if(!$this->options['autoskip']) { @@ -505,7 +506,7 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) break; } } else { - $this->log($mark, $src, $dst, true); // SUCCESS! + $log .= $this->build_log_line($mark, $src, $dst, true); // SUCCESS! } } @@ -518,6 +519,7 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) $this->options[$items_run_counter]--; $return_items_run = $this->options[$items_run_counter]; } + $this->write_log($log); $this->saveOptions(); if ($return_items_run !== false) { @@ -880,23 +882,23 @@ public function planSorter($a, $b) { } /** - * Log result of an operation + * Create line to log result of an operation * * @param string $type * @param string $from * @param string $to * @param bool $success + * + * @return string + * * @author Andreas Gohr + * @author Michael Große */ - protected function log($type, $from, $to, $success) { - global $conf; + public function build_log_line ($type, $from, $to, $success) { global $MSG; - $optime = $this->options['started']; - $file = $conf['cachedir'] . '/move/' . strftime('%Y%m%d-%H%M%S', $optime) . '.log'; - $now = time(); + $now = time(); $date = date('Y-m-d H:i:s', $now); // for human readability - if($success) { $ok = 'success'; $msg = ''; @@ -906,6 +908,19 @@ protected function log($type, $from, $to, $success) { } $log = "$now\t$date\t$type\t$from\t$to\t$ok\t$msg\n"; + return $log; + } + + /** + * write log to file + * + * @param $log + */ + protected function write_log ($log) { + global $conf; + $optime = $this->options['started']; + $file = $conf['cachedir'] . '/move/' . strftime('%Y%m%d-%H%M%S', $optime) . '.log'; io_saveFile($file, $log, true); } + } From d199cab1d04c7ccf55e16d40634d487636e62195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 14 Apr 2015 19:25:59 +0200 Subject: [PATCH 163/338] fix .travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 257209f..6540e22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,6 @@ php: env: - DOKUWIKI=master - DOKUWIKI=stable -before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh +before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh && rm .gitignore install: sh travis.sh script: cd _test && phpunit --stderr --group plugin_move From 5b4ea835eae4e27903d1c8adc17322151f208f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 16 Apr 2015 17:57:36 +0200 Subject: [PATCH 164/338] Test that links are correctly rewritten when moving a namespace --- _test/namespace_move.test.php | 98 +++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index f33ad4c..a8cb1c3 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -29,6 +29,8 @@ public function tearDown() { /** * This is an integration test, which checks the correct working of an entire namespace move. * Hence it is not an unittest, hence it @coversNothing + * + * @group slow */ public function test_move_wiki_namespace() { global $AUTH_ACL; @@ -63,6 +65,8 @@ public function test_move_wiki_namespace() { /** * This is an integration test, which checks the correct working of an entire namespace move. * Hence it is not an unittest, hence it @coversNothing + * + * @group slow */ public function test_move_missing() { saveWikiText('oldspace:page', '[[missing]]', 'setup'); @@ -107,13 +111,13 @@ public function test_move_affected() { $affected_file = file(TMP_DIR . '/data/meta/__move_affected'); $this->assertSame('newaffectedspace:page',trim($affected_file[0])); - - } /** * This is an integration test, which checks the correct working of an entire namespace move. * Hence it is not an unittest, hence it @coversNothing + * + * @group slow */ function test_move_large_ns(){ global $conf; @@ -192,7 +196,7 @@ function test_move_large_ns(){ $actual_response = trim($actual_response); $expected_response = 'testns test_page17'; - $this->assertSame($expected_response,$actual_response); + $this->assertSame($expected_response,$actual_response); // todo: this assert fails occaisionally, but not reproduciably. It then has the following oputput: testns test_page17 $expected_file_contents = '[[testns:start]] [[testns:test_page17]]'; $start_file = file(TMP_DIR . '/data/pages/start.txt'); @@ -208,4 +212,92 @@ function test_move_large_ns(){ } + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + * + * @group slow + */ + public function test_move_small_namespace_pages() { + global $AUTH_ACL; + + $AUTH_ACL[] = "oldns:*\t@ALL\t16"; + $AUTH_ACL[] = "newns:*\t@ALL\t16"; + + saveWikiText('start', '[[oldns:start]] [[oldns:page]] [[oldns:missing]]', 'setup'); + idx_addPage('start'); + saveWikiText('oldns:start', '[[oldns:start]] [[oldns:page]] [[oldns:missing]] [[missing]] [[page]]', 'setup'); + idx_addPage('oldns:start'); + saveWikiText('oldns:page', '[[oldns:start]] [[oldns:page]] [[oldns:missing]] [[missing]] [[start]]', 'setup'); + idx_addPage('oldns:page'); + + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('oldns', 'newns'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep(), 'pages'); // pages + $this->assertSame(1, $plan->nextStep(), 'missing'); // missing + $this->assertSame(1, $plan->nextStep(), 'links'); // links + $this->assertSame(1, $plan->nextStep(), 'autorewrite'); // autorewrite + $this->assertSame(0, $plan->nextStep(), 'done'); // done + + $this->assertFileExists(wikiFN('newns:start')); + $this->assertFileExists(wikiFN('newns:page')); + $this->assertFileNotExists(wikiFN('oldns:start')); + $this->assertFileNotExists(wikiFN('oldns:page')); + + $this->assertSame('[[newns:start]] [[newns:page]] [[newns:missing]] [[missing]] [[page]]',rawWiki('newns:start')); + $this->assertSame('[[newns:start]] [[newns:page]] [[newns:missing]] [[missing]] [[start]]',rawWiki('newns:page')); + $this->assertSame('[[newns:start]] [[newns:page]] [[newns:missing]]',rawWiki('start')); + } + + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + * + * @group slow + */ + public function test_move_small_namespace_media() { + global $AUTH_ACL; + + $AUTH_ACL[] = "oldns:*\t@ALL\t16"; + $AUTH_ACL[] = "newns:*\t@ALL\t16"; + + $filepath = DOKU_TMP_DATA.'media/oldns/oldnsimage.png'; + io_makeFileDir($filepath); + io_saveFile($filepath,''); + saveWikiText('start', '{{oldns:oldnsimage.png}} {{oldns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}', 'setup'); + idx_addPage('start'); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addMediaNamespaceMove('oldns', 'newns'); + //todo: it apears that only existing mediafiles are checked, but there is no checking for links to missing media files in that namespace + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep(), 'pages'); // pages + $this->assertSame(1, $plan->nextStep(), 'media'); // media +// $this->assertSame(1, $plan->nextStep(), 'missing'); // missing +// $this->assertSame(1, $plan->nextStep(), 'links'); // links +// $this->assertSame(1, $plan->nextStep(), 'autorewrite'); // autorewrite + $this->assertSame(0, $plan->nextStep(), 'done'); // done + + $this->assertFileExists(mediaFN('newns:oldnsimage.png')); + $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); + + $this->assertSame('{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}',rawWiki('start')); + + $this->markTestIncomplete('It is not yet clear, which nextSteps should actually be taken and hence be tested for.'); + } + } From 97cecfe2b15f0733dc937fba1bf36eaeef4e0d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 16 Apr 2015 18:02:10 +0200 Subject: [PATCH 165/338] Fix failing rewrites because the page was still locked The change introduced in c50d2a48e18f43f87725c9a868eba421bb1e6baf caused the rewrite function to delete the move meta data, even so the change hasn't yet been written to disk. --- helper/plan.php | 9 ++------- helper/rewrite.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index d12232c..6a2213b 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -276,12 +276,7 @@ public function abort() { } $this->plan = array(); $this->loadOptions(); - global $conf; - $lockfile = $conf['lockdir'] . 'move.lock'; - if (file_exists($lockfile)) { - unlink($lockfile); - } - unset($GLOBALS['PLUGIN_MOVE_WORKING']); + helper_plugin_move_rewrite::removeAllLocks(); } /** @@ -400,7 +395,7 @@ public function nextStep($skip = false) { return max($todo, 1); // force one more call } - helper_plugin_move_rewrite::removeLock(); + helper_plugin_move_rewrite::removeAllLocks(); if($this->options['autorewrite'] && @filesize($this->files['affected']) > 1) { $todo = $this->stepThroughAffectedPages(); diff --git a/helper/rewrite.php b/helper/rewrite.php index 8ad4d72..8bb0241 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -179,6 +179,20 @@ public static function removeLock() { } } + /** + * Allow rewrites in this process again. + * + * @author Michael Große + */ + public static function removeAllLocks() { + global $conf; + $lockfile = $conf['lockdir'] . 'move.lock'; + if (file_exists($lockfile)) { + unlink($lockfile); + } + unset($GLOBALS['PLUGIN_MOVE_WORKING']); + } + /** * Rewrite a text in order to fix the content after the given moves. From 1c31b1305277f614979036b02344015be9afaadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 16 Apr 2015 18:05:56 +0200 Subject: [PATCH 166/338] Fix findAffectedPages for media files --- helper/plan.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/helper/plan.php b/helper/plan.php index 6a2213b..9b45f1a 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -722,6 +722,13 @@ protected function findAffectedPages($src, $dst, $class, $type) { unset($page); } else if($type == self::TYPE_MEDIA) { $pages = $idx->lookupKey('relation_media', $src_); + $len = strlen($src); + foreach($pages as &$page) { + if (substr($page, 0, $len + 1) === "$src:") { + $page = $dst . substr($page, $len + 1); + } + } + unset($page); //todo: we may have to rewrite src -> dst here as well. tests needed } From d39c7c9186a3518daeb21cfcca3ec77a512050bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Thu, 16 Apr 2015 18:08:12 +0200 Subject: [PATCH 167/338] Mark an incomplete test as incomplete --- _test/pagemove.test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index f3c626a..39d95fa 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -581,6 +581,7 @@ function test_move_ns_in_same_ns() { $this->movedToId = $opts['newns'].':'.$newPagename; //$this->move->_pm_move_recursive($opts); + $this->markTestIncomplete('Test must yet be implemented.'); } From 2543b10d979cc252c7313fb248c900582113320c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 20 Apr 2015 14:40:12 +0200 Subject: [PATCH 168/338] Check for missing media links findMissingPages and stepThroughMissingPages were generalized to findMissingDocuments and stepThroughMissingDocuments and now also expect the type parameter. Added a step in nextStep for stepThroughMissingDocuments with media type $referenceidx is solely used inside findMissingDocuments and hence I made it a local variable instead of a class variable. --- helper/plan.php | 85 +++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 9b45f1a..f21f95e 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -57,11 +57,9 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { 'media' => array(), 'ns' => array(), 'miss' => array(), + 'miss_media' => array(), ); - /** @var array|null keeps reference list */ - protected $referenceidx = null; - /** @var helper_plugin_move_op $MoveOperator */ protected $MoveOperator = null; @@ -80,7 +78,8 @@ public function __construct() { 'medialist' => $conf['metadir'] . '/__move_medialist', 'affected' => $conf['metadir'] . '/__move_affected', 'namespaces' => $conf['metadir'] . '/__move_namespaces', - 'missing' => $conf['metadir'] . '/__move_missing' + 'missing' => $conf['metadir'] . '/__move_missing', + 'missing_media' => $conf['metadir'] . '/__move_missing_media', ); $this->MoveOperator = plugin_load('helper', 'move_op'); @@ -123,9 +122,6 @@ protected function loadOptions() { $options = unserialize(io_readFile($file, false)); $this->options = array_merge($this->options, $options); } - - // reset index for next run (happens in tests only) - $this->referenceidx = null; } /** @@ -335,9 +331,8 @@ public function commit() { // page namespace moves, but subscriptions work for both, but what when only one of // them is moved? Should it be copied then? Complicated. This is good enough for now $this->addToDocumentList($move['src'], $move['dst'], self::CLASS_NS); - - $this->findMissingPages($move['src'], $move['dst']); } + $this->findMissingDocuments($move['src'], $move['dst'],$move['type']); } // store what pages are affected by this move $this->findAffectedPages($move['src'], $move['dst'], $move['class'], $move['type']); @@ -384,11 +379,17 @@ public function nextStep($skip = false) { } if(@filesize($this->files['missing']) > 1 && @filesize($this->files['affected']) > 1) { - $todo = $this->stepThroughMissingPages(); + $todo = $this->stepThroughMissingDocuments(self::TYPE_PAGES); if($todo === false) return $this->storeError(); return max($todo, 1); // force one more call } + if(@filesize($this->files['missing_media']) > 1 && @filesize($this->files['affected']) > 1) { + $todo = $this->stepThroughMissingDocuments(self::TYPE_MEDIA); + if($todo === false)return $this->storeError(); + return max($todo, 1); // force one more call + } + if(@filesize($this->files['namespaces']) > 1) { $todo = $this->stepThroughNamespaces(); if($todo === false) return $this->storeError(); @@ -560,14 +561,25 @@ protected function stepThroughAffectedPages() { * * This does not step currently, but handles all pages in one step. * + * @param int $type + * * @return int always 0 + * @throws Exception */ - protected function stepThroughMissingPages() { + protected function stepThroughMissingDocuments($type = self::TYPE_PAGES) { + if($type != self::TYPE_PAGES && $type != self::TYPE_MEDIA) { + throw new Exception('wrong type specified'); + } /** @var helper_plugin_move_rewrite $Rewriter */ $Rewriter = plugin_load('helper', 'move_rewrite'); $miss = array(); - $missing = file($this->files['missing']); + if ($type == self::TYPE_PAGES) { + $missing_fn = $this->files['missing']; + } else { + $missing_fn = $this->files['missing_media']; + } + $missing = file($missing_fn); foreach($missing as $line) { $line = trim($line); if($line == '') continue; @@ -579,10 +591,14 @@ protected function stepThroughMissingPages() { foreach($affected as $page){ $page = trim($page); - $Rewriter->setMoveMetas($page, $miss, 'pages'); + if ($type == self::TYPE_PAGES) { + $Rewriter->setMoveMetas($page, $miss, 'pages'); + } else { + $Rewriter->setMoveMetas($page, $miss, 'media'); + } } - unlink($this->files['missing']); + unlink($missing_fn); return 0; } @@ -738,33 +754,39 @@ protected function findAffectedPages($src, $dst, $class, $type) { /** * Find missing pages in the $src namespace * - * @param $src - * @param $dst + * @param string $src source namespace + * @param string $dst destination namespace + * @param int $type either self::TYPE_PAGES or self::TYPE_MEDIA */ - protected function findMissingPages($src, $dst) { - if(is_null($this->referenceidx)) { - global $conf; - // FIXME this duplicates Doku_Indexer::getIndex() - $fn = $conf['indexdir'].'/relation_references_w.idx'; - if (!@file_exists($fn)){ - $this->referenceidx = array(); - } else { - $this->referenceidx = file($fn, FILE_IGNORE_NEW_LINES); - } + protected function findMissingDocuments($src, $dst, $type = self::TYPE_PAGES) { //FIXME: expects $src without colon, but $dst with colon + global $conf; + + // FIXME this duplicates Doku_Indexer::getIndex() + if ($type == self::TYPE_PAGES) { + $fn = $conf['indexdir'] . '/relation_references_w.idx'; + } else { + $fn = $conf['indexdir'] . '/relation_media_w.idx'; + } + if (!@file_exists($fn)){ + $referenceidx = array(); + } else { + $referenceidx = file($fn, FILE_IGNORE_NEW_LINES); } $len = strlen($src); - foreach($this->referenceidx as $idx => $page) { + foreach($referenceidx as $idx => $page) { if(substr($page, 0, $len+1) != "$src:") continue; // remember missing pages if(!page_exists($page)) { $newpage = $dst . substr($page, $len+1); - $this->tmpstore['miss'][$page] = $newpage; + if ($type == self::TYPE_PAGES) { + $this->tmpstore['miss'][$page] = $newpage; + } else { + $this->tmpstore['miss_media'][$page] = $newpage; + } } - // we never need to look at this page again - unset($this->referenceidx[$idx]); } } @@ -779,7 +801,8 @@ protected function storeDocumentLists() { 'media' => $this->files['medialist'], 'ns' => $this->files['namespaces'], 'affpg' => $this->files['affected'], - 'miss' => $this->files['missing'] + 'miss' => $this->files['missing'], + 'miss_media' => $this->files['missing_media'], ); foreach($lists as $store => $file) { From be42951744c2cdab6f517036573185e9b714db29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 20 Apr 2015 15:12:14 +0200 Subject: [PATCH 169/338] Test move of pages&media, Fix steps and teardown --- _test/namespace_move.test.php | 83 +++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index a8cb1c3..2e4f3b7 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -23,6 +23,10 @@ public function tearDown() { /** @var helper_plugin_move_plan $plan */ $plan = plugin_load('helper', 'move_plan'); $plan->abort(); + + io_rmdir(DOKU_TMP_DATA."pages/newns",true); + io_rmdir(DOKU_TMP_DATA."media/newns",true); + parent::tearDown(); } @@ -50,12 +54,13 @@ public function test_move_wiki_namespace() { $plan->commit(); - $this->assertSame(1, $plan->nextStep()); // pages - $this->assertSame(1, $plan->nextStep()); // media - $this->assertSame(1, $plan->nextStep()); // missing - $this->assertSame(1, $plan->nextStep()); // links - $this->assertSame(1, $plan->nextStep()); // namepaces - $this->assertSame(0, $plan->nextStep()); // done + $this->assertSame(1, $plan->nextStep(),'pages'); + $this->assertSame(1, $plan->nextStep(),'media'); + $this->assertSame(1, $plan->nextStep(),'missing'); + $this->assertSame(1, $plan->nextStep(),'missing_media'); + $this->assertSame(1, $plan->nextStep(),'namespace'); + $this->assertSame(1, $plan->nextStep(),'autorewrite'); + $this->assertSame(0, $plan->nextStep(),'done'); $this->assertFileExists(wikiFN('foo:dokuwiki')); $this->assertFileNotExists(wikiFN('wiki:syntax')); @@ -81,11 +86,11 @@ public function test_move_missing() { $plan->commit(); - $this->assertSame(1, $plan->nextStep()); // pages - $this->assertSame(1, $plan->nextStep()); // missing - $this->assertSame(1, $plan->nextStep()); // links - $this->assertSame(1, $plan->nextStep()); // namepaces - $this->assertSame(0, $plan->nextStep()); // done + $this->assertSame(1, $plan->nextStep(),'page'); + $this->assertSame(1, $plan->nextStep(),'missing'); + $this->assertSame(1, $plan->nextStep(),'namespace'); + $this->assertSame(1, $plan->nextStep(),'autorewrite'); + $this->assertSame(0, $plan->nextStep(),'done'); $this->assertFileExists(wikiFN('newspace:page')); $this->assertFileNotExists(wikiFN('oldspace:page')); @@ -285,19 +290,61 @@ public function test_move_small_namespace_media() { $plan->commit(); - $this->assertSame(1, $plan->nextStep(), 'pages'); // pages - $this->assertSame(1, $plan->nextStep(), 'media'); // media -// $this->assertSame(1, $plan->nextStep(), 'missing'); // missing -// $this->assertSame(1, $plan->nextStep(), 'links'); // links -// $this->assertSame(1, $plan->nextStep(), 'autorewrite'); // autorewrite - $this->assertSame(0, $plan->nextStep(), 'done'); // done + $this->assertSame(1, $plan->nextStep(), 'media'); + $this->assertSame(1, $plan->nextStep(), 'missing_media'); + $this->assertSame(1, $plan->nextStep(), 'autorewrite'); + $this->assertSame(0, $plan->nextStep(), 'done'); $this->assertFileExists(mediaFN('newns:oldnsimage.png')); $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); $this->assertSame('{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}',rawWiki('start')); + } + + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + * + * @group slow + */ + public function test_move_small_namespace_combi() { + global $AUTH_ACL; + + $AUTH_ACL[] = "oldns:*\t@ALL\t16"; + $AUTH_ACL[] = "newns:*\t@ALL\t16"; + + $filepath = DOKU_TMP_DATA.'media/oldns/oldnsimage.png'; + io_makeFileDir($filepath); + io_saveFile($filepath,''); + saveWikiText('start', "[[oldns:start]] [[oldns:page]] [[oldns:missing]]\n{{oldns:oldnsimage.png}} {{oldns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}", 'setup'); + idx_addPage('start'); + saveWikiText('oldns:start', '[[oldns:start]] [[oldns:page]] [[oldns:missing]] [[missing]] [[page]]', 'setup'); + idx_addPage('oldns:start'); + saveWikiText('oldns:page', '[[oldns:start]] [[oldns:page]] [[oldns:missing]] [[missing]] [[start]]', 'setup'); + idx_addPage('oldns:page'); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addMediaNamespaceMove('oldns', 'newns'); + $plan->addPageNamespaceMove('oldns', 'newns'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep(), 'pages'); + $this->assertSame(1, $plan->nextStep(), 'media'); + $this->assertSame(1, $plan->nextStep(), 'missing'); + $this->assertSame(1, $plan->nextStep(), 'missing_media'); + $this->assertSame(1, $plan->nextStep(), 'namespaces'); + $this->assertSame(1, $plan->nextStep(), 'autorewrite'); + $this->assertSame(0, $plan->nextStep(), 'done'); + + $this->assertFileExists(mediaFN('newns:oldnsimage.png')); + $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); - $this->markTestIncomplete('It is not yet clear, which nextSteps should actually be taken and hence be tested for.'); + $this->assertSame("[[newns:start]] [[newns:page]] [[newns:missing]]\n{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}",rawWiki('start')); } } From e7b1fd244b7ef46de346f7003d332588461580ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 20 Apr 2015 15:14:25 +0200 Subject: [PATCH 170/338] Group tests which take longer than 1 sec as slow --- _test/mediamove.test.php | 6 ++++++ _test/pagemove.test.php | 23 +++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index 17efa86..c885308 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -16,6 +16,9 @@ public function setUp() { parent::setUp(); } + /** + * @group slow + */ public function test_movePageWithRelativeMedia() { $src = 'mediareltest:foo'; saveWikiText($src, @@ -35,6 +38,9 @@ public function test_movePageWithRelativeMedia() { [[doku>wiki:foo|{{mediareltest:foo.gif?200x3000}}]]', rawWiki('foo')); } + /** + * @group slow + */ public function test_moveSingleMedia() { global $AUTH_ACL; $AUTH_ACL[] = "wiki:*\t@ALL\t16"; diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 39d95fa..62a663b 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -175,8 +175,10 @@ function setUp() { $conf['useslash'] = 1; } - - function test_move_page_in_same_ns() { + /** + * @group slow + */ + function test_move_page_in_same_ns() { global $ID; $newId = getNS($ID).':new_page'; $this->movedToId = $newId; @@ -289,8 +291,10 @@ function test_move_page_in_same_ns() { $this->assertEquals($expectedContent, $newContent); } - - function test_move_page_to_parallel_ns() { + /** + * @group slow + */ + function test_move_page_to_parallel_ns() { global $ID; $newId = 'parent_ns:parallel_ns:new_page'; $this->movedToId = $newId; @@ -403,8 +407,10 @@ function test_move_page_to_parallel_ns() { $this->assertEquals($expectedContent, $newContent); } - - function test_move_page_to_parent_ns() { + /** + * @group slow + */ + function test_move_page_to_parent_ns() { global $ID; $newId = 'parent_ns:new_page'; @@ -521,6 +527,8 @@ function test_move_page_to_parent_ns() { /** * Ensure that absolute links stay absolute. See https://github.com/michitux/dokuwiki-plugin-move/pull/6#discussion_r15698440 + * + * @group slow */ function test_move_startpage_of_ns() { saveWikiText('wiki:bar:test', @@ -540,6 +548,8 @@ function test_move_startpage_of_ns() { /** * If the relative part would be too large, create an absolute link instead. * If the original link ended with a colon and the new link also points to a namespace's startpage: keep the colon. + * + * @group slow */ function test_move_no_long_rel_links_keep_colon() { saveWikiText('wiki:foo:start', '[[..:..:one_ns_up:]]', 'Test setup'); @@ -555,6 +565,7 @@ function test_move_no_long_rel_links_keep_colon() { /** * @covers helper_plugin_move_handler::_nsStartCheck + * @group slow */ function test_move_to_thisns_start(){ saveWikiText('wiki:foo:test_page', '[[..:..:bar:]]', 'Test setup'); From 1430f9f82af81bcfb053d455925b233fb0122e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 20 Apr 2015 15:17:14 +0200 Subject: [PATCH 171/338] Add unittests for findMissingDocuments --- _test/findMissingDocuments.test.php | 100 ++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 _test/findMissingDocuments.test.php diff --git a/_test/findMissingDocuments.test.php b/_test/findMissingDocuments.test.php new file mode 100644 index 0000000..7820a4e --- /dev/null +++ b/_test/findMissingDocuments.test.php @@ -0,0 +1,100 @@ +tmpstore; + } + +} + + +/** + * Test cases for helper_plugin_move_plan::stepThroughDocuments function of the move plugin + * + * @group plugin_move + * @group plugin_move_unittests + * @group plugins + * @group unittests + * @covers helper_plugin_move_plan::findMissingDocuments + */ +class plugin_move_findMissingPages_test extends DokuWikiTest { + + protected $pluginsEnabled = array('move',); + /** @var helper_plugin_move_plan_findMissingDocuments_mock $plan */ + protected $plan; + + /** + * @coversNothing + */ + public function setUp() { + parent::setUp(); + $this->plan = new helper_plugin_move_plan_findMissingDocuments_mock(); + } + + + /** + * @coversNothing + */ + public function tearDown() { + global $conf; + $indexfn = $conf['indexdir'].'/relation_references_w.idx'; + if(file_exists($indexfn)) { + unlink($indexfn); + } + $this->plan->abort(); + parent::tearDown(); + } + + + function test_findMissingPages_empty () { + $this->plan->findMissingDocuments('oldns','newns:'); + $tmpstore = $this->plan->getTmpstore(); + $this->assertSame(array(),$tmpstore['miss']); + } + + function test_findMissingPages_missingPage_default () { + saveWikiText('start','[[oldns:missing]]','test edit'); + idx_addPage('start'); + $this->plan->findMissingDocuments('oldns','newns:'); + $tmpstore = $this->plan->getTmpstore(); + $this->assertSame(array('oldns:missing' => 'newns:missing',),$tmpstore['miss']); + } + + function test_findMissingPages_missingPage_explicit () { + saveWikiText('start','[[oldns:missing]]','test edit'); + idx_addPage('start'); + $this->plan->findMissingDocuments('oldns','newns:',helper_plugin_move_plan::TYPE_PAGES); + $tmpstore = $this->plan->getTmpstore(); + $this->assertSame(array('oldns:missing' => 'newns:missing',),$tmpstore['miss']); + } + + function test_findMissingPages_missingPage_integrated () { + saveWikiText('oldns:start','[[oldns:missing]] {{oldns:missing.png}}','test edit'); + idx_addPage('oldns:start'); + $this->plan->addPageNamespaceMove('oldns', 'newns'); + $this->plan->addMediaNamespaceMove('oldns', 'newns'); + + $this->plan->commit(); + + $missing_file = file(TMP_DIR . '/data/meta/__move_missing'); + $this->assertSame(array("oldns:missing\tnewns:missing\n",),$missing_file,'new configuration fails'); + + $missing_media_file = file(TMP_DIR . '/data/meta/__move_missing_media'); + $this->assertSame(array("oldns:missing.png\tnewns:missing.png\n",),$missing_media_file,'new configuration fails'); + + } + + function test_findMissingPages_missingMedia () { + saveWikiText('start','{{oldns:missing.png}}','test edit'); + idx_addPage('start'); + $this->plan->findMissingDocuments('oldns','newns:',helper_plugin_move_plan::TYPE_MEDIA); + $tmpstore = $this->plan->getTmpstore(); + $this->assertSame(array('oldns:missing.png' => 'newns:missing.png',),$tmpstore['miss_media']); + } +} From 2c2cf4007b222346da1cc4ab37ff86979a97142c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 20 Apr 2015 15:28:00 +0200 Subject: [PATCH 172/338] Test affectedPages with media files --- _test/affectedPagesNs.test.php | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 _test/affectedPagesNs.test.php diff --git a/_test/affectedPagesNs.test.php b/_test/affectedPagesNs.test.php new file mode 100644 index 0000000..87b33bc --- /dev/null +++ b/_test/affectedPagesNs.test.php @@ -0,0 +1,58 @@ +abort(); + parent::tearDown(); + } + + /** + * @covers helper_plugin_move_plan::findAffectedPages + * @uses Doku_Indexer + */ + public function test_affectedPagesNS_Media() { + + saveWikiText('oldns:start', '{{oldnsimage_missing.png}}', 'setup'); + idx_addPage('oldns:start'); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper','move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addMediaNamespaceMove('oldns', 'newns'); + + $plan->commit(); + + $affected_file = file(TMP_DIR . '/data/meta/__move_affected'); + + $this->assertSame('newns:start',trim($affected_file[0])); + + } + +} From ed3b1bec29a85f53157cd2a6bbeae251dd22f50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 20 Apr 2015 15:29:49 +0200 Subject: [PATCH 173/338] Fix bug in stepThroughNamespaces.This needs more work --- helper/plan.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index f21f95e..f3a5c29 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -611,6 +611,7 @@ protected function stepThroughMissingDocuments($type = self::TYPE_PAGES) { * * @return int always 0 * @todo maybe add an event so plugins can move more stuff? + * @todo fixed that $src and $dst are seperated by tab, not newline. This method has no tests? */ protected function stepThroughNamespaces() { /** @var helper_plugin_move_file $FileMover */ @@ -620,7 +621,7 @@ protected function stepThroughNamespaces() { $lines = explode("\n", $lines); foreach($lines as $line) { - list($src, $dst) = explode("\n", trim($line)); + list($src, $dst) = explode("\t", trim($line)); $FileMover->moveNamespaceSubscription($src, $dst); } From dfd45b0781987ddd9bdb9e349980a7f5b2e083cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 21 Apr 2015 17:53:03 +0200 Subject: [PATCH 174/338] Also delete meta directory on teardown --- _test/namespace_move.test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 2e4f3b7..1bfb0a1 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -26,6 +26,7 @@ public function tearDown() { io_rmdir(DOKU_TMP_DATA."pages/newns",true); io_rmdir(DOKU_TMP_DATA."media/newns",true); + io_rmdir(DOKU_TMP_DATA."meta/newns",true); parent::tearDown(); } From 591872533a2112f44b378418f32a4f35bfc6f915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 21 Apr 2015 17:54:13 +0200 Subject: [PATCH 175/338] Add tests for moving the subscriptions to namespace and pages --- _test/namespace_move.test.php | 86 +++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 1bfb0a1..b369921 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -348,4 +348,90 @@ public function test_move_small_namespace_combi() { $this->assertSame("[[newns:start]] [[newns:page]] [[newns:missing]]\n{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}",rawWiki('start')); } + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + * + * @group slow + */ + public function test_move_small_namespace_subscription_ns() { + global $AUTH_ACL; + + $AUTH_ACL[] = "subns:*\t@ALL\t16"; + $AUTH_ACL[] = "newns:*\t@ALL\t16"; + + saveWikiText('subns:start', 'Lorem Ipsum', 'setup'); + idx_addPage('subns:start'); + + $oldfilepath = DOKU_TMP_DATA.'meta/subns/.mlist'; + $subscription = 'doe every 1427984341'; + io_makeFileDir($oldfilepath); + io_saveFile($oldfilepath,$subscription); + $newfilepath = DOKU_TMP_DATA.'meta/newns/.mlist'; + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('subns', 'newns'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep(), 'pages'); + $this->assertSame(1, $plan->nextStep(), 'namespace'); + $this->assertSame(0, $plan->nextStep(), 'done'); + + $this->assertFileExists(wikiFN('newns:start')); + $this->assertFileExists($newfilepath); + $this->assertFileNotExists(wikiFN('subns:start')); + $this->assertFileNotExists($oldfilepath); + + $this->assertSame($subscription,file_get_contents($newfilepath)); + + } + + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + * + * @group slow + */ + public function test_move_small_namespace_subscription_page() { + global $AUTH_ACL; + + $AUTH_ACL[] = "subns:*\t@ALL\t16"; + $AUTH_ACL[] = "newns:*\t@ALL\t16"; + + saveWikiText('subns:start', 'Lorem Ipsum', 'setup'); + idx_addPage('subns:start'); + + $oldfilepath = DOKU_TMP_DATA.'meta/subns/start.mlist'; + $subscription = 'doe every 1427984341'; + io_makeFileDir($oldfilepath); + io_saveFile($oldfilepath,$subscription); + $newfilepath = DOKU_TMP_DATA.'meta/newns/start.mlist'; + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addPageNamespaceMove('subns', 'newns'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep(), 'pages'); + $this->assertSame(1, $plan->nextStep(), 'namespace'); + $this->assertSame(0, $plan->nextStep(), 'done'); + + $this->assertFileExists(wikiFN('newns:start')); + $this->assertFileExists($newfilepath); + $this->assertFileNotExists(wikiFN('subns:start')); + $this->assertFileNotExists($oldfilepath); + + $this->assertSame($subscription,file_get_contents($newfilepath)); + + } + } From 52f67fd4d0012042d9c424de5ab300e77d7bf6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Tue, 21 Apr 2015 17:56:24 +0200 Subject: [PATCH 176/338] Remove obsolete comments --- _test/namespace_move.test.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index b369921..1687e3b 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -247,11 +247,11 @@ public function test_move_small_namespace_pages() { $plan->commit(); - $this->assertSame(1, $plan->nextStep(), 'pages'); // pages - $this->assertSame(1, $plan->nextStep(), 'missing'); // missing - $this->assertSame(1, $plan->nextStep(), 'links'); // links - $this->assertSame(1, $plan->nextStep(), 'autorewrite'); // autorewrite - $this->assertSame(0, $plan->nextStep(), 'done'); // done + $this->assertSame(1, $plan->nextStep(), 'pages'); + $this->assertSame(1, $plan->nextStep(), 'missing'); + $this->assertSame(1, $plan->nextStep(), 'namespace'); + $this->assertSame(1, $plan->nextStep(), 'autorewrite'); + $this->assertSame(0, $plan->nextStep(), 'done'); $this->assertFileExists(wikiFN('newns:start')); $this->assertFileExists(wikiFN('newns:page')); @@ -287,7 +287,6 @@ public function test_move_small_namespace_media() { $this->assertFalse($plan->inProgress()); $plan->addMediaNamespaceMove('oldns', 'newns'); - //todo: it apears that only existing mediafiles are checked, but there is no checking for links to missing media files in that namespace $plan->commit(); From e655db0792592010ecae14facd1231880c9493f0 Mon Sep 17 00:00:00 2001 From: Yadav Gowda Date: Wed, 22 Apr 2015 16:05:33 -0500 Subject: [PATCH 177/338] adding ability to let managers view tree-based move manager --- admin/tree.php | 10 ++++++++++ conf/default.php | 3 ++- conf/metadata.php | 3 ++- lang/en/settings.php | 3 ++- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/admin/tree.php b/admin/tree.php index a218c0b..3604757 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -13,6 +13,16 @@ public function getMenuText($language) { return false; // do not show in Admin menu } + + /** + * If this admin plugin is for admins only + * + * @return bool false + */ + function forAdminOnly() { + return !($this->getConf('allowmanagerstree')); + } + /** * no-op */ diff --git a/conf/default.php b/conf/default.php index d5cccd3..a4d4baa 100644 --- a/conf/default.php +++ b/conf/default.php @@ -3,4 +3,5 @@ $conf['allowrename'] = '@user'; $conf['minor'] = 1; $conf['autoskip'] = 0; -$conf['autorewrite'] = 1; \ No newline at end of file +$conf['autorewrite'] = 1; +$conf['allowmanagerstree'] = 0; \ No newline at end of file diff --git a/conf/metadata.php b/conf/metadata.php index 4010be6..fa9d44c 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -3,4 +3,5 @@ $meta['allowrename'] = array('string'); $meta['minor'] = array('onoff'); $meta['autoskip'] = array('onoff'); -$meta['autorewrite'] = array('onoff'); \ No newline at end of file +$meta['autorewrite'] = array('onoff'); +$meta['allowmanagerstree'] = array('onoff'); \ No newline at end of file diff --git a/lang/en/settings.php b/lang/en/settings.php index b4b5328..e8a8c55 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -3,4 +3,5 @@ $lang['allowrename'] = 'Allow renaming of pages to these groups and users (comma separated).'; $lang['minor'] = 'Mark link adjustments as minor? Minor changes will not be listed in RSS feeds and subscription mails.'; $lang['autoskip'] = 'Enable automatic skipping of errors in namespace moves by default.'; -$lang['autorewrite'] = 'Enable automatic link rewriting after namespace moves by default.'; \ No newline at end of file +$lang['autorewrite'] = 'Enable automatic link rewriting after namespace moves by default.'; +$lang['allowmanagerstree'] = 'Allow managers to access tree-based move manager'; \ No newline at end of file From a8528bb9f08f28ac8e187927e927de85f5080599 Mon Sep 17 00:00:00 2001 From: SPP Date: Mon, 27 Apr 2015 12:59:27 +0200 Subject: [PATCH 178/338] Create lang.php Italian translation --- lang/it/lang.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lang/it/lang.php diff --git a/lang/it/lang.php b/lang/it/lang.php new file mode 100644 index 0000000..6f022ef --- /dev/null +++ b/lang/it/lang.php @@ -0,0 +1,62 @@ + + */ + +// settings must be present and set appropriately for the language +$lang['encoding'] = 'utf-8'; +$lang['direction'] = 'ltr'; + +// for admin plugins, the menu prompt to be displayed in the admin menu +// if set here, the plugin doesn't need to override the getMenuText() method +$lang['menu'] = 'Pagina/Namespace Sposta/Rinomina...'; +$lang['desc'] = 'Page/Namespace Sposta/Rinomina Plugin'; + +$lang['notexist'] = 'La pagina %s non esiste'; +$lang['medianotexist'] = 'Il file media %s non esiste'; +$lang['notwrite'] = 'Non hai permessi sufficienti per modificare questa pagina'; +$lang['badns'] = 'Carattere invalido nel namespace.'; +$lang['badname'] = 'Carattere invalido nel nome della pagina'; +$lang['nochange'] = 'Il nome della pagina ed il namespace non sono stati modificati.'; +$lang['nomediachange'] = 'Il nome del file media e il namespace non sono stati modificati.'; +$lang['existing'] = 'Una pagina chiamata %s esiste già in %s'; +$lang['mediaexisting'] = 'Un file media chiamato %s esiste già in %s'; +$lang['root'] = '[Namespace radice]'; +$lang['current'] = '(Corrente)'; +$lang['renamed'] = 'Il nome della pagina è stato cambiato da %s a %s'; +$lang['moved'] = 'Pagina spostata da %s a %s'; +$lang['move_rename'] = 'Pagina spostata e rinominata da %s a %s'; +$lang['delete'] = 'Cancellato da move (sposta) plugin'; +$lang['norights'] = 'Non hai permessi sufficienti per modificare %s.'; +$lang['nomediarights'] = 'Non hai permessi sufficienti per cancellare %s.'; +$lang['notargetperms'] = 'Non hai permessi sufficienti per creare la pagina %s.'; +$lang['nomediatargetperms'] = 'Non hai i permessi per creare il file media %s.'; +$lang['filelocked'] = 'La pagina %s è bloccata. Riprova più tardi.'; +$lang['linkchange'] = 'Collegamento modificati a causa di un\'operazione di spostamento'; + +$lang['ns_move_in_progress'] = 'E\' in corso un\'operazione di spostamento di %s pagine e %s file media dal namespace %s al namespace %s.'; +$lang['ns_move_continue'] = 'Continua lo spostamento del namespace'; +$lang['ns_move_abort'] = 'Interrompi lo spostamento del namespace'; +$lang['ns_move_continued'] = 'Lo spostamento del namespace dal namespace %s al namespace %s è ripresa, rimangono ancora %s elementi.'; +$lang['ns_move_started'] = 'Lo spostamento di un namespace dal namespace %s al namespace %s è iniziata, %s pagine e %s file media saranno mossi.'; +$lang['ns_move_error'] = 'E\' successo un errore mentre era stava continuando lo spostamento del namespace da %s a %s.'; +$lang['ns_move_tryagain'] = 'Riprova'; +$lang['ns_move_skip'] = 'Salta l\'elemento corrente'; +// Form labels +$lang['newname'] = 'Nome della nuova pagina:'; +$lang['newnsname'] = 'Nome del nuovo namespace:'; +$lang['targetns'] = 'Seleziona il nuovo namespace:'; +$lang['newtargetns'] = 'Crea un nuovo namespace:'; +$lang['movepage'] = 'Sposta la pagina'; +$lang['movens'] = 'Sposta il namespace'; +$lang['submit'] = 'Invia'; +$lang['content_to_move'] = 'Contenuto da spostare'; +$lang['move_pages'] = 'Pagine'; +$lang['move_media'] = 'File media'; +$lang['move_media_and_pages'] = 'Pagine e file media'; +// JavaScript preview +$lang['js']['previewpage'] = 'OLDPAGE saranno spostate nelle NEWPAGE'; +$lang['js']['previewns'] = 'Tutte le pagine ed i namespace nel namespace OLDNS saranno mossi verso il namespace NEWNS'; From 911aae43f642f09704fefeb96bec8c990ee24bea Mon Sep 17 00:00:00 2001 From: SPP Date: Mon, 27 Apr 2015 13:00:57 +0200 Subject: [PATCH 179/338] Create move.txt Italian translation --- lang/it/move.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 lang/it/move.txt diff --git a/lang/it/move.txt b/lang/it/move.txt new file mode 100644 index 0000000..fa67e5f --- /dev/null +++ b/lang/it/move.txt @@ -0,0 +1,10 @@ +====== Move ====== + +Questo plugin ti permette di spostare e/o rinominare la pagina corrente o muovere e/o rinominare il namespace corrente, con le seguenti restrizioni: + + * Devi avere i permessi di modificare la pagina corrente/tutte le pagine nel namespace corrente. + * Le pagine che verranno mosse non devono essere bloccate per un richiesta di modifica. + * Per muovere un pagina hai anche bisogno di creare i permessi nel namespace di destinazione. + * Non puoi muovere una pagina verso un namespace dove una pagina con lo stesso nome già esiste. + +Tutti i collegamenti verso e dalle pagine che verranno mosse saranno aggiornate in coerenza con la nuova posizione e/o nome. From 7deed88ffcb8f1d5e9caed726b5436c231953167 Mon Sep 17 00:00:00 2001 From: Yadav Gowda Date: Mon, 4 May 2015 14:34:40 -0500 Subject: [PATCH 180/338] no need for conf setting --- admin/tree.php | 4 ++-- conf/default.php | 1 - conf/metadata.php | 1 - lang/en/settings.php | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/admin/tree.php b/admin/tree.php index 3604757..99aa9d4 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -20,7 +20,7 @@ public function getMenuText($language) { * @return bool false */ function forAdminOnly() { - return !($this->getConf('allowmanagerstree')); + return false; } /** @@ -180,4 +180,4 @@ function html_li($item) { return "
  • "; } -} \ No newline at end of file +} diff --git a/conf/default.php b/conf/default.php index a4d4baa..e3f5a8a 100644 --- a/conf/default.php +++ b/conf/default.php @@ -4,4 +4,3 @@ $conf['minor'] = 1; $conf['autoskip'] = 0; $conf['autorewrite'] = 1; -$conf['allowmanagerstree'] = 0; \ No newline at end of file diff --git a/conf/metadata.php b/conf/metadata.php index fa9d44c..5a0832f 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -4,4 +4,3 @@ $meta['minor'] = array('onoff'); $meta['autoskip'] = array('onoff'); $meta['autorewrite'] = array('onoff'); -$meta['allowmanagerstree'] = array('onoff'); \ No newline at end of file diff --git a/lang/en/settings.php b/lang/en/settings.php index e8a8c55..3a7a18f 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -4,4 +4,3 @@ $lang['minor'] = 'Mark link adjustments as minor? Minor changes will not be listed in RSS feeds and subscription mails.'; $lang['autoskip'] = 'Enable automatic skipping of errors in namespace moves by default.'; $lang['autorewrite'] = 'Enable automatic link rewriting after namespace moves by default.'; -$lang['allowmanagerstree'] = 'Allow managers to access tree-based move manager'; \ No newline at end of file From ca74e8f54c8630b8dc014d5fe1c498b298ba8d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 11 May 2015 18:47:50 +0200 Subject: [PATCH 181/338] Fix occasionally undefined variable --- helper/plan.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helper/plan.php b/helper/plan.php index f3a5c29..7822614 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -725,6 +725,8 @@ protected function findAffectedPages($src, $dst, $class, $type) { if($class == self::CLASS_NS) { $src_ = "$src:*"; // use wildcard lookup for namespaces + } else { + $src_ = $src; } $pages = array(); From 98390e8fd85d38f234d5976d540b5fcf29f00766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 11 May 2015 18:48:27 +0200 Subject: [PATCH 182/338] Fix rewriting of links to moved mediafiles starting with : --- _test/mediamove.test.php | 27 +++++++++++++++++++++++++++ helper/handler.php | 26 ++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index c885308..3bbcea6 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -60,4 +60,31 @@ public function test_moveSingleMedia() { $this->assertEquals('{{foobar:logo.png?200}}', rawWiki('wiki:movetest')); } + + /** + * @group slow + */ + public function test_moveSingleMedia_colonstart() { + global $AUTH_ACL; + $AUTH_ACL[] = "wiki:*\t@ALL\t16"; + $AUTH_ACL[] = "foobar:*\t@ALL\t8"; + + $filepath = DOKU_TMP_DATA.'media/wiki/testimage.png'; + io_makeFileDir($filepath); + io_saveFile($filepath,''); + + saveWikiText('wiki:movetest', '{{:wiki:testimage.png?200}}', 'Test initialized'); + idx_addPage('wiki:movetest'); + + $src = 'wiki:testimage.png'; + $dst = 'foobar:logo_2.png'; + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + $this->assertTrue($move->moveMedia($src, $dst)); + + $this->assertTrue(@file_exists(mediaFn('foobar:logo_2.png'))); + + $this->assertEquals('{{:foobar:logo_2.png?200}}', rawWiki('wiki:movetest')); + } } diff --git a/helper/handler.php b/helper/handler.php index 764270d..c63cd3f 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -57,7 +57,13 @@ public function resolveMoves($old, $type) { if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); - if($conf['useslash']) $old = str_replace('/', ':', $old); + if($conf['useslash']) { + $old = str_replace('/', ':', $old); + $delimiter = '/'; + } else { + $delimiter = ':'; + } + $old = resolve_id($this->origNS, $old, false); if($type == 'page') { @@ -72,8 +78,24 @@ public function resolveMoves($old, $type) { $moves = $this->media_moves; } + if (substr($old,0,1) !== $delimiter) { + $tempColon = true; + $old = $delimiter . $old; + } + foreach($moves as $move) { - if($move[0] == $old) $old = $move[1]; + if (substr($move[0],0,1) !== $delimiter) { + $move[0] = $delimiter . $move[0]; + } + if($move[0] == $old) { + $old = $move[1]; + if (substr($old,0,1) !== $delimiter) { + $old = $delimiter . $old; + } + } + } + if ($tempColon) { + $old = substr($old,1); } return $old; // this is now new } From cdbedf5006d4691396f03cdb56cb3ad9706e37a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Wed, 13 May 2015 19:40:55 +0200 Subject: [PATCH 183/338] Save wip --- _test/namespace_move.test.php | 42 ++++++++++++++++++++++++++++-- _test/tpl.test.php | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 _test/tpl.test.php diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 1687e3b..a2f4764 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -278,7 +278,7 @@ public function test_move_small_namespace_media() { $filepath = DOKU_TMP_DATA.'media/oldns/oldnsimage.png'; io_makeFileDir($filepath); io_saveFile($filepath,''); - saveWikiText('start', '{{oldns:oldnsimage.png}} {{oldns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}', 'setup'); + saveWikiText('start', '{{oldns:oldnsimage.png}} {{oldns:oldnsimage_missing.png}} {{image_missing.png}}', 'setup'); idx_addPage('start'); /** @var helper_plugin_move_plan $plan */ @@ -298,7 +298,45 @@ public function test_move_small_namespace_media() { $this->assertFileExists(mediaFN('newns:oldnsimage.png')); $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); - $this->assertSame('{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}}',rawWiki('start')); + $this->assertSame('{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{image_missing.png}}',rawWiki('start')); + } + + /** + * This is an integration test, which checks the correct working of an entire namespace move. + * Hence it is not an unittest, hence it @coversNothing + * + * @group slow + */ + public function test_move_small_namespace_media_affected() { + global $AUTH_ACL; + + $AUTH_ACL[] = "oldns:*\t@ALL\t16"; + $AUTH_ACL[] = "newns:*\t@ALL\t16"; + + $filepath = DOKU_TMP_DATA.'media/oldns/oldnsimage.png'; + io_makeFileDir($filepath); + io_saveFile($filepath,''); + saveWikiText('oldns:start', '{{:oldns:oldnsimage.png}} {{oldns:oldnsimage_missing.png}} {{oldnsimage_missing.png}} {{oldnsimage.png}}', 'setup'); + idx_addPage('oldns:start'); + + /** @var helper_plugin_move_plan $plan */ + $plan = plugin_load('helper', 'move_plan'); + + $this->assertFalse($plan->inProgress()); + + $plan->addMediaNamespaceMove('oldns', 'newns'); + + $plan->commit(); + + $this->assertSame(1, $plan->nextStep(), 'media'); + $this->assertSame(1, $plan->nextStep(), 'missing_media'); + $this->assertSame(1, $plan->nextStep(), 'autorewrite'); + $this->assertSame(0, $plan->nextStep(), 'done'); + + $this->assertFileExists(mediaFN('newns:oldnsimage.png')); + $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); + + $this->assertSame('{{:newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}} {{newns:oldnsimage.png}}',rawWiki('oldns:start')); } /** diff --git a/_test/tpl.test.php b/_test/tpl.test.php new file mode 100644 index 0000000..be91f74 --- /dev/null +++ b/_test/tpl.test.php @@ -0,0 +1,49 @@ + + * @group plugin_move + * @group plugins + */ +class move_tpl_test extends DokuWikiTest { + + public function setUp() { + parent::setUp(); + } + + protected $pluginsEnabled = array('move'); + + /** + * @coversNothing + * Integration-ish kind of test testing action_plugin_move_rename::handle_pagetools + *//* + function test_tpl () { + saveWikiText('wiki:foo:start', '[[..:..:one_ns_up:]]', 'Test setup'); + idx_addPage('wiki:foo:start'); + + $request = new TestRequest(); + $response = $request->get(array(),'/doku.php?id=wiki:foo:start'); + + $this->assertTrue(strstr($response->getContent(),'class="plugin_move_page"') !== false); + }*/ + + /** + * @covers action_plugin_move_rename::renameOkay + */ + function test_renameOkay() { + global $conf; + global $USERINFO; + $conf['superuser'] = 'john'; + $_SERVER['REMOTE_USER'] = 'john'; + $USERINFO['grps'] = array('admin','user'); + + saveWikiText('wiki:foo:start', '[[..:..:one_ns_up:]]', 'Test setup'); + idx_addPage('wiki:foo:start'); + + $move_rename = new action_plugin_move_rename(); + $this->assertTrue($move_rename->renameOkay('wiki:foo:start')); + + } +} From 1c0789b1d43c7a7bb78b0780bfb8e9d6f6fb65d3 Mon Sep 17 00:00:00 2001 From: Dalibo Date: Fri, 15 May 2015 17:31:06 +0200 Subject: [PATCH 184/338] Fix test to not depend on linkbase detection --- _test/namespace_move.test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index a2f4764..347253a 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -195,13 +195,13 @@ function test_move_large_ns(){ $actual_response = $response->getContent(); //clean away clutter $actual_response = substr($actual_response,strpos($actual_response,"") + 23); + $actual_response = substr($actual_response,strpos($actual_response, 'doku.php')); $actual_response = substr($actual_response,0,strpos($actual_response,"")); $actual_response = trim($actual_response); - $actual_response = ltrim($actual_response,"

    "); $actual_response = rtrim($actual_response,"

    "); $actual_response = trim($actual_response); - $expected_response = 'testns test_page17'; + $expected_response = 'doku.php?id=foo:testns:start" class="wikilink1" title="foo:testns:start">testns test_page17'; $this->assertSame($expected_response,$actual_response); // todo: this assert fails occaisionally, but not reproduciably. It then has the following oputput: testns test_page17 $expected_file_contents = '[[testns:start]] [[testns:test_page17]]'; From 00c9a895d4a717df3d251a6c882e1ad9a3a117b3 Mon Sep 17 00:00:00 2001 From: Dalibo Date: Fri, 15 May 2015 17:40:59 +0200 Subject: [PATCH 185/338] Fix wrong affected pages by media move --- _test/affectedPagesNs.test.php | 2 +- _test/namespace_move.test.php | 2 +- helper/plan.php | 8 -------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/_test/affectedPagesNs.test.php b/_test/affectedPagesNs.test.php index 87b33bc..6b6f31d 100644 --- a/_test/affectedPagesNs.test.php +++ b/_test/affectedPagesNs.test.php @@ -51,7 +51,7 @@ public function test_affectedPagesNS_Media() { $affected_file = file(TMP_DIR . '/data/meta/__move_affected'); - $this->assertSame('newns:start',trim($affected_file[0])); + $this->assertSame('oldns:start',trim($affected_file[0])); } diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 347253a..e8159eb 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -336,7 +336,7 @@ public function test_move_small_namespace_media_affected() { $this->assertFileExists(mediaFN('newns:oldnsimage.png')); $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); - $this->assertSame('{{:newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{oldnsimage_missing.png}} {{newns:oldnsimage.png}}',rawWiki('oldns:start')); + $this->assertSame('{{:newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage.png}}',rawWiki('oldns:start')); } /** diff --git a/helper/plan.php b/helper/plan.php index 7822614..0533904 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -741,14 +741,6 @@ protected function findAffectedPages($src, $dst, $class, $type) { unset($page); } else if($type == self::TYPE_MEDIA) { $pages = $idx->lookupKey('relation_media', $src_); - $len = strlen($src); - foreach($pages as &$page) { - if (substr($page, 0, $len + 1) === "$src:") { - $page = $dst . substr($page, $len + 1); - } - } - unset($page); - //todo: we may have to rewrite src -> dst here as well. tests needed } $this->addToAffectedPagesList($pages); From 31c7c89e40d736b62d8687ff084b13decd75fb75 Mon Sep 17 00:00:00 2001 From: Dalibo Date: Fri, 15 May 2015 18:46:32 +0200 Subject: [PATCH 186/338] Fix findMissingDocuments. page_exists doesn't work for media --- _test/findMissingDocuments.test.php | 19 +++++++++++++++---- _test/namespace_move.test.php | 1 - helper/plan.php | 12 +++++++----- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/_test/findMissingDocuments.test.php b/_test/findMissingDocuments.test.php index 7820a4e..1467fee 100644 --- a/_test/findMissingDocuments.test.php +++ b/_test/findMissingDocuments.test.php @@ -43,10 +43,10 @@ public function setUp() { */ public function tearDown() { global $conf; - $indexfn = $conf['indexdir'].'/relation_references_w.idx'; - if(file_exists($indexfn)) { - unlink($indexfn); - } + + io_rmdir($conf['indexdir'],true); + mkdir($conf['indexdir']); + $this->plan->abort(); parent::tearDown(); } @@ -97,4 +97,15 @@ function test_findMissingPages_missingMedia () { $tmpstore = $this->plan->getTmpstore(); $this->assertSame(array('oldns:missing.png' => 'newns:missing.png',),$tmpstore['miss_media']); } + + function test_findMissingDocuments_nonMissingMedia () { + $filepath = DOKU_TMP_DATA.'media/oldns/oldnsimage.png'; + io_makeFileDir($filepath); + io_saveFile($filepath,''); + saveWikiText('start','{{oldns:oldnsimage.png}}','test edit'); + idx_addPage('start'); + $this->plan->findMissingDocuments('oldns','newns:',helper_plugin_move_plan::TYPE_MEDIA); + $tmpstore = $this->plan->getTmpstore(); + $this->assertSame(array(),$tmpstore['miss_media']); + } } diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index e8159eb..26c1197 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -58,7 +58,6 @@ public function test_move_wiki_namespace() { $this->assertSame(1, $plan->nextStep(),'pages'); $this->assertSame(1, $plan->nextStep(),'media'); $this->assertSame(1, $plan->nextStep(),'missing'); - $this->assertSame(1, $plan->nextStep(),'missing_media'); $this->assertSame(1, $plan->nextStep(),'namespace'); $this->assertSame(1, $plan->nextStep(),'autorewrite'); $this->assertSame(0, $plan->nextStep(),'done'); diff --git a/helper/plan.php b/helper/plan.php index 0533904..300e22e 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -773,15 +773,17 @@ protected function findMissingDocuments($src, $dst, $type = self::TYPE_PAGES) { if(substr($page, 0, $len+1) != "$src:") continue; // remember missing pages - if(!page_exists($page)) { - $newpage = $dst . substr($page, $len+1); - if ($type == self::TYPE_PAGES) { + if ($type == self::TYPE_PAGES) { + if(!page_exists($page)) { + $newpage = $dst . substr($page, $len+1); $this->tmpstore['miss'][$page] = $newpage; - } else { + } + } else { + if(!file_exists(mediaFN($page))){ + $newpage = $dst . substr($page, $len+1); $this->tmpstore['miss_media'][$page] = $newpage; } } - } } From 7aa8a5bc7edc6a852ba9b1f1d82d55674062a9e5 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Fri, 15 May 2015 19:15:05 +0200 Subject: [PATCH 187/338] Delete all data to fix random fails --- _test/findMissingDocuments.test.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_test/findMissingDocuments.test.php b/_test/findMissingDocuments.test.php index 1467fee..e3a7153 100644 --- a/_test/findMissingDocuments.test.php +++ b/_test/findMissingDocuments.test.php @@ -44,9 +44,11 @@ public function setUp() { public function tearDown() { global $conf; - io_rmdir($conf['indexdir'],true); - mkdir($conf['indexdir']); - + $dirs = array('indexdir','datadir','metadir', 'mediadir'); + foreach ($dirs as $dir) { + io_rmdir($conf[$dir],true); + mkdir($conf[$dir]); + } $this->plan->abort(); parent::tearDown(); } From 3ad67da38d5d22141aaf439170bae784bd759325 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Sat, 16 May 2015 11:43:25 +0200 Subject: [PATCH 188/338] Skip broken test --- _test/namespace_move.test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 26c1197..2f80110 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -125,6 +125,11 @@ public function test_move_affected() { * @group slow */ function test_move_large_ns(){ + + $this->markTestSkipped( + 'This test randomly fails with the page "testns:start" being moved, but "start" not being rewritten in the request.' + ); + global $conf; $test = '[[testns:start]] [[testns:test_page17]]'; From f5e3efd270ee24ebc11ec10fe81622c939b9f94c Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Sat, 16 May 2015 12:08:51 +0200 Subject: [PATCH 189/338] Remove fixed todo comment --- admin/main.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/main.php b/admin/main.php index 364e4b2..87a1b0d 100644 --- a/admin/main.php +++ b/admin/main.php @@ -253,7 +253,7 @@ protected function btn($control, $show = true) { if($control == 'start') $control = 'continue'; if($control == 'retry') { $control = 'continue'; - $skip = 0; //todo: this should be 0 for retry and 1 for skip + $skip = 0; } $class = 'move__control ctlfrm-' . $id; From 4a0d3169dba859d27716f6460127b8dbac9b2875 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Sat, 16 May 2015 12:33:49 +0200 Subject: [PATCH 190/338] findMissingDocuments expects both src and dst to end with colon --- _test/findMissingDocuments.test.php | 8 ++++---- helper/plan.php | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/_test/findMissingDocuments.test.php b/_test/findMissingDocuments.test.php index e3a7153..fdeb0cd 100644 --- a/_test/findMissingDocuments.test.php +++ b/_test/findMissingDocuments.test.php @@ -63,7 +63,7 @@ function test_findMissingPages_empty () { function test_findMissingPages_missingPage_default () { saveWikiText('start','[[oldns:missing]]','test edit'); idx_addPage('start'); - $this->plan->findMissingDocuments('oldns','newns:'); + $this->plan->findMissingDocuments('oldns:','newns:'); $tmpstore = $this->plan->getTmpstore(); $this->assertSame(array('oldns:missing' => 'newns:missing',),$tmpstore['miss']); } @@ -71,7 +71,7 @@ function test_findMissingPages_missingPage_default () { function test_findMissingPages_missingPage_explicit () { saveWikiText('start','[[oldns:missing]]','test edit'); idx_addPage('start'); - $this->plan->findMissingDocuments('oldns','newns:',helper_plugin_move_plan::TYPE_PAGES); + $this->plan->findMissingDocuments('oldns:','newns:',helper_plugin_move_plan::TYPE_PAGES); $tmpstore = $this->plan->getTmpstore(); $this->assertSame(array('oldns:missing' => 'newns:missing',),$tmpstore['miss']); } @@ -95,7 +95,7 @@ function test_findMissingPages_missingPage_integrated () { function test_findMissingPages_missingMedia () { saveWikiText('start','{{oldns:missing.png}}','test edit'); idx_addPage('start'); - $this->plan->findMissingDocuments('oldns','newns:',helper_plugin_move_plan::TYPE_MEDIA); + $this->plan->findMissingDocuments('oldns:','newns:',helper_plugin_move_plan::TYPE_MEDIA); $tmpstore = $this->plan->getTmpstore(); $this->assertSame(array('oldns:missing.png' => 'newns:missing.png',),$tmpstore['miss_media']); } @@ -106,7 +106,7 @@ function test_findMissingDocuments_nonMissingMedia () { io_saveFile($filepath,''); saveWikiText('start','{{oldns:oldnsimage.png}}','test edit'); idx_addPage('start'); - $this->plan->findMissingDocuments('oldns','newns:',helper_plugin_move_plan::TYPE_MEDIA); + $this->plan->findMissingDocuments('oldns:','newns:',helper_plugin_move_plan::TYPE_MEDIA); $tmpstore = $this->plan->getTmpstore(); $this->assertSame(array(),$tmpstore['miss_media']); } diff --git a/helper/plan.php b/helper/plan.php index 300e22e..425d250 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -332,7 +332,7 @@ public function commit() { // them is moved? Should it be copied then? Complicated. This is good enough for now $this->addToDocumentList($move['src'], $move['dst'], self::CLASS_NS); } - $this->findMissingDocuments($move['src'], $move['dst'],$move['type']); + $this->findMissingDocuments($move['src'] . ':', $move['dst'],$move['type']); } // store what pages are affected by this move $this->findAffectedPages($move['src'], $move['dst'], $move['class'], $move['type']); @@ -753,7 +753,7 @@ protected function findAffectedPages($src, $dst, $class, $type) { * @param string $dst destination namespace * @param int $type either self::TYPE_PAGES or self::TYPE_MEDIA */ - protected function findMissingDocuments($src, $dst, $type = self::TYPE_PAGES) { //FIXME: expects $src without colon, but $dst with colon + protected function findMissingDocuments($src, $dst, $type = self::TYPE_PAGES) { global $conf; // FIXME this duplicates Doku_Indexer::getIndex() @@ -770,17 +770,17 @@ protected function findMissingDocuments($src, $dst, $type = self::TYPE_PAGES) { $len = strlen($src); foreach($referenceidx as $idx => $page) { - if(substr($page, 0, $len+1) != "$src:") continue; + if(substr($page, 0, $len) != "$src") continue; // remember missing pages if ($type == self::TYPE_PAGES) { if(!page_exists($page)) { - $newpage = $dst . substr($page, $len+1); + $newpage = $dst . substr($page, $len); $this->tmpstore['miss'][$page] = $newpage; } } else { if(!file_exists(mediaFN($page))){ - $newpage = $dst . substr($page, $len+1); + $newpage = $dst . substr($page, $len); $this->tmpstore['miss_media'][$page] = $newpage; } } From 1f18d223a623ec4aee3b9c6dd307eb4ec8ea85bb Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Sat, 16 May 2015 12:41:22 +0200 Subject: [PATCH 191/338] Save to file after every move This impacts performance but should improve recovery when a move is interrupted --- helper/plan.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index 425d250..cb24f6b 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -478,8 +478,9 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) } $doclist = fopen($file, 'a+'); - $log = ""; + for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) { + $log = ""; $line = $this->getLastLine($doclist); if($line === false) { break; @@ -514,9 +515,9 @@ protected function stepThroughDocuments($type = self::TYPE_PAGES, $skip = false) ftruncate($doclist, ftell($doclist)); $this->options[$items_run_counter]--; $return_items_run = $this->options[$items_run_counter]; + $this->write_log($log); + $this->saveOptions(); } - $this->write_log($log); - $this->saveOptions(); if ($return_items_run !== false) { fclose($doclist); From 65bf5a82f0e09ca95be7506b4a8fa9afde570f20 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Sat, 16 May 2015 13:04:53 +0200 Subject: [PATCH 192/338] Better filename for lockfile and saver writing --- helper/rewrite.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index 8bb0241..8ec970c 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -25,6 +25,11 @@ class helper_plugin_move_rewrite extends DokuWiki_Plugin { */ const METAKEY = 'plugin_move'; + /** + * What is they filename of the lockfile + */ + const LOCKFILENAME = '_plugin_move.lock'; + /** * @var string symbol to make move operations easily recognizable in change log */ @@ -137,7 +142,7 @@ public function setSelfMoveMeta($id) { public static function isLocked() { global $PLUGIN_MOVE_WORKING; global $conf; - $lockfile = $conf['lockdir'] . 'move.lock'; + $lockfile = $conf['lockdir'] . self::LOCKFILENAME; return ((isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0) || file_exists($lockfile)); } @@ -148,13 +153,13 @@ public static function addLock() { global $PLUGIN_MOVE_WORKING; global $conf; $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING + 1 : 1; - $lockfile = $conf['lockdir'] . 'move.lock'; + $lockfile = $conf['lockdir'] . self::LOCKFILENAME; if (!file_exists($lockfile)) { - file_put_contents($lockfile, "1\n"); + io_savefile($lockfile, "1\n"); } else { $stack = intval(file_get_contents($lockfile)); ++$stack; - file_put_contents($lockfile, strval($stack)); + io_savefile($lockfile, strval($stack)); } } @@ -165,7 +170,7 @@ public static function removeLock() { global $PLUGIN_MOVE_WORKING; global $conf; $PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING - 1 : 0; - $lockfile = $conf['lockdir'] . 'move.lock'; + $lockfile = $conf['lockdir'] . self::LOCKFILENAME; if (!file_exists($lockfile)) { throw new Exception("removeLock failed: lockfile missing"); } else { @@ -174,7 +179,7 @@ public static function removeLock() { unlink($lockfile); } else { --$stack; - file_put_contents($lockfile, strval($stack)); + io_savefile($lockfile, strval($stack)); } } } @@ -186,7 +191,7 @@ public static function removeLock() { */ public static function removeAllLocks() { global $conf; - $lockfile = $conf['lockdir'] . 'move.lock'; + $lockfile = $conf['lockdir'] . self::LOCKFILENAME; if (file_exists($lockfile)) { unlink($lockfile); } From e046a92611f1c93b5052eea6eb9c8c22c1af4b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Sat, 16 May 2015 13:23:11 +0200 Subject: [PATCH 193/338] Update plugin.info.txt upped version --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index 6db5c16..8108451 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2014-07-02 +date 2015-05-16 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 0d8a95f37a650784bcc2fbc7c26f5dd27c6c72ff Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 16 May 2015 16:15:15 +0200 Subject: [PATCH 194/338] Added swedish translation, closes #10 --- lang/sv/lang.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ lang/sv/move.txt | 10 ++++++++ 2 files changed, 72 insertions(+) create mode 100644 lang/sv/lang.php create mode 100644 lang/sv/move.txt diff --git a/lang/sv/lang.php b/lang/sv/lang.php new file mode 100644 index 0000000..787d5fe --- /dev/null +++ b/lang/sv/lang.php @@ -0,0 +1,62 @@ + + */ + +// settings must be present and set appropriately for the language +$lang['encoding'] = 'utf-8'; +$lang['direction'] = 'ltr'; + +// for admin plugins, the menu prompt to be displayed in the admin menu +// if set here, the plugin doesn't need to override the getMenuText() method +$lang['menu'] = 'Flytt/Namnbyte på Sida/Namnrymd...'; +$lang['desc'] = 'Plugin för Flytt/Namnbyte på Sida/Namnrymd...'; + +$lang['notexist'] = 'Sidan %s finns inte'; +$lang['medianotexist'] = 'Media filen %s finns inte'; +$lang['notwrite'] = 'Du har inte tillräcklig behörighet att ändar på den här sidan'; +$lang['badns'] = 'Otillåtet tecken i namnrymd.'; +$lang['badname'] = 'Otillåtet tecken i sidnamn.'; +$lang['nochange'] = 'Sid- och namnrymdsnamn är inte ändrade'; +$lang['nomediachange'] = 'Mediafil- och namnrymdsnamn är inte ändrade'; +$lang['existing'] = 'En sida som heter %s finns redan i %s'; +$lang['mediaexisting'] = 'En mediafil som heter %s finns redan i %s'; +$lang['root'] = '[Rotnamnrymd]'; +$lang['current'] = '[Nuvarande]'; +$lang['renamed'] = 'Sidnamn ändrat från %s till %s'; +$lang['moved'] = 'Sida flyttad från %s till %s'; +$lang['move_rename'] = 'Sida flyttad och namnändrad från %s till %s'; +$lang['delete'] = 'Borttagen av pluginen'; +$lang['norights'] = 'Du har inte tillräcklig behörighet för att ändra %s.'; +$lang['nomediarights'] = 'Du har inte tillräcklig behörighet att ta bort %s.'; +$lang['notargetperms'] = 'Du har inte tillräcklig behörighet för att skapa sidan %s.'; +$lang['nomediatargetperms'] = 'Du har inte tillräcklig behörighet för att skapa mediafilen %s.'; +$lang['filelocked'] = 'Sidan %s är låst. Försök senare.'; +$lang['linkchange'] = 'Länkar som ändrats på grund av flytt/namnändring'; + +$lang['ns_move_in_progress'] = 'En namnrymdsflytt eller namnändring av %s sidor och %s mediafiler pågår.'; +$lang['ns_move_continue'] = 'Fortsätt flytt av namnrymd'; +$lang['ns_move_abort'] = 'Avbryt flytt av namnrymd'; +$lang['ns_move_continued'] = 'Namnrymdsflytt från %s till %s pågår, %s åtgärder återstår.'; +$lang['ns_move_started'] = 'En namnrymdsflytt från %s till %s har startat, %s sidor och %s mediafiler kommer att flyttas.'; +$lang['ns_move_error'] = 'Ett fel uppstod under namnrymdsflytt från %s till %s.'; +$lang['ns_move_tryagain'] = 'Försök igen'; +$lang['ns_move_skip'] = 'Hoppa över nuvarande åtgärd'; +// Form labels +$lang['newname'] = 'Nytt sidnamn:'; +$lang['newnsname'] = 'Nytt namn för namnrymden:'; +$lang['targetns'] = 'Välj ny namnrymd:'; +$lang['newtargetns'] = 'Skapa ny namnrymd:'; +$lang['movepage'] = 'Flytta sida'; +$lang['movens'] = 'Flytta namnrymd'; +$lang['submit'] = 'Genomför'; +$lang['content_to_move'] = 'Innehåll att flytta'; +$lang['move_pages'] = 'Sidor'; +$lang['move_media'] = 'Mediafiler'; +$lang['move_media_and_pages'] = 'Sidor och mediafiler'; +// JavaScript preview +$lang['js']['previewpage'] = 'OLDPAGE kommer att flyttas till NEWPAGE'; +$lang['js']['previewns'] = 'Alla sidor och namnrymder i namnrymden OLDNS kommer att flyttas till namnrymden NEWNS'; diff --git a/lang/sv/move.txt b/lang/sv/move.txt new file mode 100644 index 0000000..01c6edf --- /dev/null +++ b/lang/sv/move.txt @@ -0,0 +1,10 @@ +====== Flytta och byt namn ====== + +Den här pluginen gör det möjligt att flytta och/eller byta namn på den aktuella sidan och/eller namnrymden. Följande begränsningar gäller: + + * Du måste ha behörighet att redigera nuvarande/alla sidor i aktuell namnrymd. + * Sidan/sidorna som flyttas får inte vara låsta. + * Om du vill flytta en sida måste du också ha behörighet att skapa dokument in den nya namnrymden. + * Det går inte att flytta en sida till en namnrymd där det redan finns en sida med det namn du vill ge sidan. + +Alla länkar från alla sidor till sidor som flyttas uppdateras så att de pekar på det nya namnet eller den nya platsen. From 1970c5fbce225600911e6c876625e4793a3dea42 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Sat, 16 May 2015 16:54:01 +0200 Subject: [PATCH 195/338] Move lang string from source to lang.php --- helper/op.php | 14 +++++++------- lang/en/lang.php | 8 ++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/helper/op.php b/helper/op.php index c962267..e8a5acd 100644 --- a/helper/op.php +++ b/helper/op.php @@ -167,11 +167,11 @@ public function movePage($src, $dst) { if(($idx_msg = $Indexer->renamePage($src, $dst)) !== true || ($idx_msg = $Indexer->renameMetaValue('relation_references', $src, $dst)) !== true ) { - msg('Error while updating the search index ' . $idx_msg, -1); + msg(sprintf($this->getLang('indexerror'), $idx_msg), -1); return false; } if(!$FileMover->movePageMeta($src_ns, $src_name, $dst_ns, $dst_name)) { - msg('The meta files of page ' . $src . ' couldn\'t be moved', -1); + msg(sprintf($this->getLang('metamoveerror'), $src), -1); return false; } @@ -201,7 +201,7 @@ public function movePage($src, $dst) { // Move the old revisions if(!$FileMover->movePageAttic($src_ns, $src_name, $dst_ns, $dst_name)) { // it's too late to stop the move, so just display a message. - msg('The attic files of page ' . $src . ' couldn\'t be moved. Please move them manually.', -1); + msg(sprintf($this->getLang('atticmoveerror'), $src ), -1); } // Add meta data to all affected pages, so links get updated later @@ -267,11 +267,11 @@ public function moveMedia($src, $dst) { // Move the Subscriptions & Indexes (new feature since Spring 2013 release) $Indexer = idx_get_indexer(); if(($idx_msg = $Indexer->renameMetaValue('relation_media', $src, $dst)) !== true) { - msg('Error while updating the search index ' . $idx_msg, -1); + msg(sprintf($this->getLang('indexerror'), $idx_msg), -1); return false; } if(!$FileMover->moveMediaMeta($src_ns, $src_name, $dst_ns, $dst_name)) { - msg('The meta files of the media file ' . $src . ' couldn\'t be moved', -1); + msg(sprintf($this->getLang('mediametamoveerror'), $src), -1); return false; } @@ -280,7 +280,7 @@ public function moveMedia($src, $dst) { // move it FIXME this does not create a changelog entry! if(!io_rename(mediaFN($src), mediaFN($dst))) { - msg('Moving the media file ' . $src . ' failed', -1); + msg(sprintf($this->getLang('mediamoveerror'), $src), -1); return false; } @@ -290,7 +290,7 @@ public function moveMedia($src, $dst) { // Move the old revisions if(!$FileMover->moveMediaAttic($src_ns, $src_name, $dst_ns, $dst_name)) { // it's too late to stop the move, so just display a message. - msg('The attic files of media file ' . $src . ' couldn\'t be moved. Please move them manually.', -1); + msg(sprintf($this->getLang('mediaatticmoveerror'), $src), -1); } // Add meta data to all affected pages, so links get updated later diff --git a/lang/en/lang.php b/lang/en/lang.php index 042cfa4..ccb1c59 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -25,6 +25,14 @@ $lang['mediaexists'] = 'Media %s can\'t be moved to %s, the target already exists.'; $lang['nomediatargetperms'] = 'You don\'t have the permission to create the media file %s.'; +// system errors +$lang['indexerror'] = 'Error while updating the search index %s'; +$lang['metamoveerror'] = 'The meta files of page %s couldn\'t be moved'; +$lang['atticmoveerror'] = 'The attic files of page %s couldn\'t be moved. Please move them manually.'; +$lang['mediametamoveerror'] = 'The meta files of the media file %s couldn\'t be moved'; +$lang['mediamoveerror'] = 'Moving the media file %s failed'; +$lang['mediaatticmoveerror'] = 'The attic files of media file %s couldn\'t be moved. Please move them manually.'; + // changelog summaries $lang['renamed'] = 'Page name changed from %s to %s'; $lang['moved'] = 'Page moved from %s to %s'; From d505cd8b21d25c8e579a628bb072992e35c4cab0 Mon Sep 17 00:00:00 2001 From: Hanjia Zhuang Date: Fri, 22 May 2015 05:40:08 +0200 Subject: [PATCH 196/338] translation update --- lang/zh/lang.php | 83 ++++++++++++++++++++++++++++++-------------- lang/zh/move.txt | 8 +++++ lang/zh/progress.txt | 3 ++ lang/zh/settings.php | 11 ++++++ lang/zh/tree.txt | 3 ++ 5 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 lang/zh/move.txt create mode 100644 lang/zh/progress.txt create mode 100644 lang/zh/settings.php create mode 100644 lang/zh/tree.txt diff --git a/lang/zh/lang.php b/lang/zh/lang.php index 08ca0f8..5594e3f 100644 --- a/lang/zh/lang.php +++ b/lang/zh/lang.php @@ -1,31 +1,60 @@ - * @author TombCrow + * + * @author Gary Owen + * @author TombCrow + * @author Hanjia Zhuang */ - -// 此处设置用户语言 -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// 若在此处设置,插件不必要求 getMenuText() 模式 -$lang['menu'] = '页面移动/重命名……'; -$lang['desc'] = '页面移动/重命名插件'; - -//$lang['notexist'] = '这个主题还不存在'; -$lang['notwrite'] = '您无权修改这个页面'; -$lang['badns'] = '分类名中存在无效字符'; -$lang['badname'] = '页面名中存在无效字符'; -$lang['nochange'] = '不能更改文件名和分类名'; -$lang['existing1'] = '文件 %s 已经存在于 %s'; -$lang['root'] = '[跟目录]'; -$lang['current'] = '(当前)'; -//$lang['norights'] = '您无权编辑此文件的 backlinks'; -$lang['filelocked'] = '此文件被锁定 - 请稍后重试'; -$lang['linkchange1'] = '链接到 %s 更改到 %s'; -$lang['newname'] = '新的文件名 :'; -$lang['targetns'] = '选择目标分类 :'; -$lang['submit'] = '提交'; +$lang['menu'] = '页面移动/重命名……'; +$lang['inprogress'] = '(待移动)'; +$lang['treelink'] = '您还可以通过树形移动.来为您的wiki条目结构做复杂调整'; +$lang['notexist'] = '页面 %s不存在'; +$lang['norights'] = '您没有权限编辑%s.'; +$lang['filelocked'] = '此文件被锁定 - 请稍后重试'; +$lang['notchanged'] = '未为页面%s指定新地址(位置未变)'; +$lang['exists'] = '页面%s无法被移动至%s ,该目标已存在 '; +$lang['notargetperms'] = '您没有权限创建页面%s.'; +$lang['medianotexist'] = '媒体文件%s不存在'; +$lang['nomediarights'] = '您没有权限删除%s.'; +$lang['medianotchanged'] = '未为页面%s指定新地址(位置未变)'; +$lang['mediaexists'] = '媒体文件%s无法被移动至%s,目标已存在。'; +$lang['nomediatargetperms'] = '您没有权限创建媒体文件%s。'; +$lang['renamed'] = '页面名由%s改为%s'; +$lang['moved'] = '页面%s被移动至%s'; +$lang['move_rename'] = '页面%s被移动并更名为%s'; +$lang['delete'] = '被Move插件删除'; +$lang['linkchange'] = '链接因页面移动而自动修正'; +$lang['intro'] = '移动操作尚未开始!'; +$lang['preview'] = '预览即将执行的变动'; +$lang['inexecution'] = '上一个移动尚未完成-点击下方按钮继续或放弃执行'; +$lang['btn_start'] = '开始'; +$lang['btn_continue'] = '继续'; +$lang['btn_retry'] = '重试'; +$lang['btn_skip'] = '跳过'; +$lang['btn_abort'] = '放弃'; +$lang['legend'] = '移动当前页面或目录'; +$lang['movepage'] = '移动页面'; +$lang['movens'] = '移动目录'; +$lang['dst'] = '新名字:'; +$lang['content_to_move'] = '移动内容:'; +$lang['autoskip'] = '忽略错误并跳过无法被移动的页面或文件'; +$lang['autorewrite'] = '待移动完成后立即重写链接'; +$lang['move_pages'] = '页面'; +$lang['move_media'] = '媒体文件'; +$lang['move_media_and_pages'] = '页面和媒体文件'; +$lang['nodst'] = '未指定新名字'; +$lang['noaction'] = '未定义任何移动'; +$lang['renamepage'] = '页面重命名'; +$lang['cantrename'] = '页面现在无法重命名,请稍后再试。'; +$lang['js']['rename'] = '重命名'; +$lang['js']['cancel'] = '取消'; +$lang['js']['newname'] = '新名字:'; +$lang['js']['inprogress'] = '重命名页面并修正有关链接:'; +$lang['js']['complete'] = '移动操作完毕。'; +$lang['js']['renameitem'] = '重命名该项'; +$lang['js']['duplicate'] = '抱歉,"%s"在该目录已存在'; +$lang['root'] = '[跟目录]'; +$lang['noscript'] = '该功能需要JavaScript'; +$lang['moveinprogress'] = '另一个移动操作正在进行,您现在无法使用该工具'; diff --git a/lang/zh/move.txt b/lang/zh/move.txt new file mode 100644 index 0000000..12c7dc3 --- /dev/null +++ b/lang/zh/move.txt @@ -0,0 +1,8 @@ +====== Move ====== +该插件允许您移动并/或重命名当前页面,或移动并/或重命名当前目录。您必须满足以下条件: +*您必须拥有编辑当前页面/该目录中所有页面的权限; +*页面未因编辑而处于锁定状态; +*为移动页面,您必须拥有目的地目录的写权限; +*您无法将页面移动至一个已有同名页面的目录中。 + +所有来自和指向被移动页面的链接,都将被自动更新以反映新地址和/或新名字。 \ No newline at end of file diff --git a/lang/zh/progress.txt b/lang/zh/progress.txt new file mode 100644 index 0000000..194f65e --- /dev/null +++ b/lang/zh/progress.txt @@ -0,0 +1,3 @@ +====== 正在移动... ====== + +移动正在进行中,请勿关闭本页面。 \ No newline at end of file diff --git a/lang/zh/settings.php b/lang/zh/settings.php new file mode 100644 index 0000000..29adc7e --- /dev/null +++ b/lang/zh/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = '允许这些用户/用户组重命名页面(用逗号分隔)'; +$lang['minor'] = '将链接修正标记为”细微变动“,这样就不会被列入RSS订阅或订阅邮件中。'; +$lang['autoskip'] = '在目录移动中,启用默认自动跳过错误'; +$lang['autorewrite'] = '在目录移动中,启用默认自动修正链接'; diff --git a/lang/zh/tree.txt b/lang/zh/tree.txt new file mode 100644 index 0000000..420cb21 --- /dev/null +++ b/lang/zh/tree.txt @@ -0,0 +1,3 @@ +====== 移动控制台 ===== + +本页面允许您通过鼠标拖放,重新安排您wiki的目录、页面与媒体文件 \ No newline at end of file From dedaba361748cef09a76f8a8497c94040a6cfbce Mon Sep 17 00:00:00 2001 From: e-dschungel Date: Sun, 24 May 2015 21:50:36 +0200 Subject: [PATCH 197/338] translation update --- lang/de/lang.php | 94 +++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/lang/de/lang.php b/lang/de/lang.php index 9805bc9..7736101 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -1,58 +1,44 @@ + * + * @author picsar + * @author e-dschungel */ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; -$lang['desc'] = 'Seite/Namespace verschieben/umbenennen... Plugin'; - -$lang['notexist'] = 'Die Seite %s existiert nicht.'; -$lang['medianotexist'] = 'Die Mediendatei %s existiert nicht'; -$lang['notwrite'] = 'Sie haben unzureichende Rechte um diese Seite zu ändern'; -$lang['badns'] = 'Ungültige Zeichen in der Namensraum-Bezeichnung.'; -$lang['badname'] = 'Ungültiges Zeichen im Seitennamen.'; -$lang['nochange'] = 'Name und Namensraum der Seite sind unverändert.'; -$lang['nomediachange'] = 'Name und Namensraum der Mediendatei sind unverändert.'; -$lang['existing'] = 'Eine Seite mit der Bezeichnung %s existiert bereits in %s'; -$lang['mediaexisting'] = 'Eine Mediendatei mit der Bezeichnung %s existiert bereits in %s'; -$lang['root'] = '[Wurzel des Namensraumes / Root namespace]'; -$lang['current'] = '(Aktueller)'; -$lang['renamed'] = 'Seitename wurde von %s auf %s geändert'; -$lang['moved'] = 'Seite von %s nach %s verschoben'; -$lang['move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; -$lang['delete'] = 'Gelöscht durch das move Plugin'; -$lang['norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; -$lang['nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; -$lang['notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; -$lang['nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; -$lang['filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; -$lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; - -$lang['ns_move_in_progress'] = 'Das Verschieben von %s Seiten und %s Mediendateien vom Namensraum %s nach %s ist derzeit im Gange.'; -$lang['ns_move_continue'] = 'Das Verschieben des Namensraumes fortsetzen'; -$lang['ns_move_abort'] = 'Das Verschieben des Namensraumes abbrechen'; -$lang['ns_move_continued'] = 'Das Verschieben des Namensraumes %s nach %s wurde fortgesetzt, %s Einträge müssen noch verschoben werden.'; -$lang['ns_move_started'] = 'Das Verschieben des Namensraumes %s nach %s wurde begonnen, %s Seiten und %s Mediendateien werden verschoben werden.'; -$lang['ns_move_error'] = 'Ein Fehler ist beim Verschieben des Namensraumes %s nach %s aufgetreten.'; -$lang['ns_move_tryagain'] = 'Nochmal versuchen'; -$lang['ns_move_skip'] = 'Den aktuellen Eintrag überspringen'; -// Form labels -$lang['newname'] = 'Neuer Seitenname:'; -$lang['newnsname'] = 'Neuer Name für Namensraum:'; -$lang['targetns'] = 'Wählen Sie einen neuen Namensraum: '; -$lang['newtargetns'] = 'Erstellen Sie einen neuen Namensraum'; -$lang['movepage'] = 'Seite verschieben'; -$lang['movens'] = 'Namensraum verschieben'; -$lang['submit'] = 'Übernehmen'; -// JavaScript preview -$lang['js']['previewpage'] = 'OLDPAGE wird in NEWPAGE umbenannt'; -$lang['js']['previewns'] = 'Alle Seiten und Namensräume im Namensraum OLDNS werden in den Namensraum NEWNS verschoben'; +$lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; +$lang['inprogress'] = '(Verschiebung läuft gerade)'; +$lang['notexist'] = 'Die Seite %s existiert nicht.'; +$lang['norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; +$lang['filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; +$lang['notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; +$lang['medianotexist'] = 'Die Mediendatei %s existiert nicht'; +$lang['nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; +$lang['nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; +$lang['renamed'] = 'Seitename wurde von %s auf %s geändert'; +$lang['moved'] = 'Seite von %s nach %s verschoben'; +$lang['move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; +$lang['delete'] = 'Gelöscht durch das move Plugin'; +$lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; +$lang['intro'] = 'Die Verschiebung wurde noch nicht gestartet!'; +$lang['preview'] = 'Vorschau der Änderungen, die ausgeführt werden sollen '; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Fortsetzen'; +$lang['btn_abort'] = 'Abbrechen'; +$lang['legend'] = 'Aktuelle Seite oder aktueller Namesraum'; +$lang['movepage'] = 'Seite verschieben'; +$lang['movens'] = 'Namensraum verschieben'; +$lang['dst'] = 'Neuer Name:'; +$lang['content_to_move'] = 'Zu verschiebender Inhalt:'; +$lang['move_pages'] = 'Seiten'; +$lang['nodst'] = 'Kein neuer Name angegeben'; +$lang['noaction'] = 'Es wurden keine Verschiebungen angegeben'; +$lang['renamepage'] = 'Seite umbennen'; +$lang['cantrename'] = 'Auf die Seite kann zur Zeit nicht zugegriffen werden - versuchen Sie es später noch einmal.'; +$lang['js']['rename'] = 'Umbenennen'; +$lang['js']['cancel'] = 'Abbrechen'; +$lang['js']['newname'] = 'Neuer Name:'; +$lang['js']['complete'] = 'Verschieben abgeschlossen.'; +$lang['js']['duplicate'] = 'Entschuldigung, "%s" existiert in diesem Namensraum bereits. '; +$lang['root'] = '[Wurzel des Namensraumes / Root namespace]'; +$lang['noscript'] = 'Dieses Feature benötigt JavaScript.'; From 6ee2d4f415ad84e9ae1e1b575d1911f507ad99b8 Mon Sep 17 00:00:00 2001 From: Nicolas Friedli Date: Mon, 25 May 2015 12:40:07 +0200 Subject: [PATCH 198/338] translation update --- lang/fr/lang.php | 70 +++++++++++++++++++++++++++++------------------- lang/fr/tree.txt | 3 +++ 2 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 lang/fr/tree.txt diff --git a/lang/fr/lang.php b/lang/fr/lang.php index fa36bf9..ea8d6b5 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -1,31 +1,47 @@ - * @translator Clement Hermann (nodens) + * + * @author Gary Owen + * @author Nicolas Friedli */ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Déplacer/Renommer la page...'; -$lang['desc'] = 'Plugin de Déplacement/Renommage'; - -$lang['notexist'] = 'Le sujet %s n\'existe pas encore'; -$lang['notwrite'] = 'Vous ne disposez pas des droits suffisants pour modifier cette page'; -$lang['badns'] = "Caractères invalides dans l'espace de nommage."; -$lang['badname'] = 'Caractères invalides dans le nom de la page.'; -$lang['nochange'] = "Le nom du document et l'espace de nomage sont inchangés."; -$lang['existing'] = 'Un document appelé %s existe déjà dans %s'; -$lang['root'] = '[Espace de nom racine]'; -$lang['current'] = '(Courant)'; -$lang['norights'] = 'Vos permissions sont insufisante pour éditer %s.'; -$lang['filelocked'] = 'Ce fichier est verrouillé - réessayez plus tard.'; -$lang['linkchange'] = 'Les liens vers %s ont été changés vers %s'; -$lang['newname'] = 'Nouveau nom du document :'; -$lang['targetns'] = 'Sélectionnez le nouvel espace de nommage :'; +$lang['menu'] = 'Déplacer/Renommer la page...'; +$lang['inprogress'] = '(déplacement en attente)'; +$lang['notexist'] = 'Le sujet %s n\'existe pas encore'; +$lang['norights'] = 'Vos permissions sont insufisante pour éditer %s.'; +$lang['filelocked'] = 'Ce fichier est verrouillé - réessayez plus tard.'; +$lang['notchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; +$lang['exists'] = 'La page %s ne peut être déplacée vers %s, la cible existe déjà.'; +$lang['notargetperms'] = 'Pous n\'avez pas la permission de créer la page %s.'; +$lang['medianotexist'] = 'Le fichier média %s n\'existe pas.'; +$lang['nomediarights'] = 'Vous ne disposez pas des permissions suffisantes pour effacer %s.'; +$lang['medianotchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; +$lang['renamed'] = 'Nom de la page changé de %s à %s'; +$lang['moved'] = 'Page déplacée de %s à %s'; +$lang['move_rename'] = 'Page déplacée et renommée de %s à %s'; +$lang['delete'] = 'Effacé par le plugin de déplacement'; +$lang['linkchange'] = 'Les liens vers %s ont été changés vers %s'; +$lang['btn_start'] = 'Départ'; +$lang['btn_continue'] = 'Continuer'; +$lang['btn_retry'] = 'Réessayer cette étape'; +$lang['btn_skip'] = 'Passer cette étape'; +$lang['btn_abort'] = 'Abandonner'; +$lang['legend'] = 'Déplacer la page ou l\'espace de nom courant'; +$lang['movepage'] = 'Déplacer la page'; +$lang['movens'] = 'Déplacer l\'espace de nom'; +$lang['dst'] = 'Nouveau nom:'; +$lang['content_to_move'] = 'Contenu à déplacer:'; +$lang['move_pages'] = 'Pages'; +$lang['move_media'] = 'Fichiers média'; +$lang['move_media_and_pages'] = 'Pages et fichiers média'; +$lang['nodst'] = 'Pas de nouveau nom donné'; +$lang['noaction'] = 'Pas de déplacement demandé'; +$lang['renamepage'] = 'Renommer la page'; +$lang['js']['rename'] = 'Renommer'; +$lang['js']['cancel'] = 'Annuler'; +$lang['js']['newname'] = 'Nouveau nom:'; +$lang['js']['complete'] = 'Déplacement effectué.'; +$lang['js']['renameitem'] = 'Renommer cet élément'; +$lang['root'] = '[Espace de nom racine]'; +$lang['noscript'] = 'Cette fonction requiert JavaScript'; diff --git a/lang/fr/tree.txt b/lang/fr/tree.txt new file mode 100644 index 0000000..c511686 --- /dev/null +++ b/lang/fr/tree.txt @@ -0,0 +1,3 @@ +====== Gestionnaire déplacement ===== + +Cette interface vous permet de réorganiser vos espaces de noms, pages et médias par glisser-déposer. \ No newline at end of file From 8efe60cfce8abac02716de790894f51526ce1af4 Mon Sep 17 00:00:00 2001 From: e-dschungel Date: Tue, 26 May 2015 23:15:08 +0200 Subject: [PATCH 199/338] translation update --- lang/de/lang.php | 17 ++++++++++++++++- lang/de/progress.txt | 3 +++ lang/de/settings.php | 11 +++++++++++ lang/de/tree.txt | 3 +++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 lang/de/progress.txt create mode 100644 lang/de/settings.php create mode 100644 lang/de/tree.txt diff --git a/lang/de/lang.php b/lang/de/lang.php index 7736101..9d8e6cb 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -8,12 +8,17 @@ */ $lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; $lang['inprogress'] = '(Verschiebung läuft gerade)'; +$lang['treelink'] = 'Alternativ zu dieser einfachen Form können komplexere Umstrukturierungen des Wikis mit dem baumbasierten Move-Manager durchgeführt werden.'; $lang['notexist'] = 'Die Seite %s existiert nicht.'; $lang['norights'] = 'Sie haben unzureichende Rechte um %s zu bearbeiten.'; $lang['filelocked'] = 'Die Seite %s ist gesperrt - versuchen Sie es später noch einmal.'; +$lang['notchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; +$lang['exists'] = 'Seite %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; $lang['notargetperms'] = 'Sie haben nicht die Berechtigung, die Seite %s anzulegen.'; $lang['medianotexist'] = 'Die Mediendatei %s existiert nicht'; $lang['nomediarights'] = 'Sie haben unzureichende Rechte, um die Mediendatei %s zu löschen.'; +$lang['medianotchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; +$lang['mediaexists'] = 'Mediendatei %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; $lang['nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; $lang['renamed'] = 'Seitename wurde von %s auf %s geändert'; $lang['moved'] = 'Seite von %s nach %s verschoben'; @@ -22,23 +27,33 @@ $lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; $lang['intro'] = 'Die Verschiebung wurde noch nicht gestartet!'; $lang['preview'] = 'Vorschau der Änderungen, die ausgeführt werden sollen '; +$lang['inexecution'] = 'Eine vorherige Verschiebung wurde nicht beendet - benutzen sie die Knöpfe unten um die Verschiebung fortzusetzen oder abzubrechen. '; $lang['btn_start'] = 'Start'; $lang['btn_continue'] = 'Fortsetzen'; +$lang['btn_retry'] = 'Element wiederholen'; +$lang['btn_skip'] = 'Element überspringen'; $lang['btn_abort'] = 'Abbrechen'; $lang['legend'] = 'Aktuelle Seite oder aktueller Namesraum'; $lang['movepage'] = 'Seite verschieben'; $lang['movens'] = 'Namensraum verschieben'; $lang['dst'] = 'Neuer Name:'; $lang['content_to_move'] = 'Zu verschiebender Inhalt:'; +$lang['autoskip'] = 'Fehler ignorieren und Seiten oder Dateien, die nicht verschoben werden können, überspringen'; +$lang['autorewrite'] = 'Links anpassen, nachdem die Verschiebung abgeschlossen wurde'; $lang['move_pages'] = 'Seiten'; +$lang['move_media'] = 'Mediendateien'; +$lang['move_media_and_pages'] = 'Seiten und Mediendateien'; $lang['nodst'] = 'Kein neuer Name angegeben'; $lang['noaction'] = 'Es wurden keine Verschiebungen angegeben'; -$lang['renamepage'] = 'Seite umbennen'; +$lang['renamepage'] = 'Seite umbenennen'; $lang['cantrename'] = 'Auf die Seite kann zur Zeit nicht zugegriffen werden - versuchen Sie es später noch einmal.'; $lang['js']['rename'] = 'Umbenennen'; $lang['js']['cancel'] = 'Abbrechen'; $lang['js']['newname'] = 'Neuer Name:'; +$lang['js']['inprogress'] = 'Benenne Seite um und passe Links an...'; $lang['js']['complete'] = 'Verschieben abgeschlossen.'; +$lang['js']['renameitem'] = 'Dieses Element umbenennen'; $lang['js']['duplicate'] = 'Entschuldigung, "%s" existiert in diesem Namensraum bereits. '; $lang['root'] = '[Wurzel des Namensraumes / Root namespace]'; $lang['noscript'] = 'Dieses Feature benötigt JavaScript.'; +$lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft gerade, Sie können dieses Tool gerade nicht benutzen.'; diff --git a/lang/de/progress.txt b/lang/de/progress.txt new file mode 100644 index 0000000..f9b39e1 --- /dev/null +++ b/lang/de/progress.txt @@ -0,0 +1,3 @@ +====== Verschiebung läuft... ====== + +Bitte lassen Sie diese Seite geöffnet, während die Verschiebung läuft. \ No newline at end of file diff --git a/lang/de/settings.php b/lang/de/settings.php new file mode 100644 index 0000000..1e8061e --- /dev/null +++ b/lang/de/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = 'Umbennenung von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt) '; +$lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderung werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; +$lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; +$lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; diff --git a/lang/de/tree.txt b/lang/de/tree.txt new file mode 100644 index 0000000..a5c31d1 --- /dev/null +++ b/lang/de/tree.txt @@ -0,0 +1,3 @@ +====== Move-Manager ===== + +Diese Ansicht ermöglicht die Restrukturierung von Namensräumen, Seiten und Mediendateien des Wikis per Drag'n'Drop. From dcfe7d3250b9e66a8861e2dcf95b6031e3d9f547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schplurtz=20le=20D=C3=A9boulonn=C3=A9?= Date: Mon, 1 Jun 2015 19:35:20 +0200 Subject: [PATCH 200/338] translation update --- lang/fr/lang.php | 23 ++++++++++++++++++----- lang/fr/move.txt | 10 +++++----- lang/fr/progress.txt | 3 +++ lang/fr/settings.php | 11 +++++++++++ lang/fr/tree.txt | 2 +- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 lang/fr/progress.txt create mode 100644 lang/fr/settings.php diff --git a/lang/fr/lang.php b/lang/fr/lang.php index ea8d6b5..2e488de 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -5,24 +5,31 @@ * * @author Gary Owen * @author Nicolas Friedli + * @author Schplurtz le Déboulonné */ -$lang['menu'] = 'Déplacer/Renommer la page...'; +$lang['menu'] = 'Déplacer/Renommer pages et catégories...'; $lang['inprogress'] = '(déplacement en attente)'; +$lang['treelink'] = 'Au lieu de ce simple formulaire, vous pouvez effectuer des restructurations complexes de votre wiki en utilisant le gestionnaire déplacements par arborescence'; $lang['notexist'] = 'Le sujet %s n\'existe pas encore'; $lang['norights'] = 'Vos permissions sont insufisante pour éditer %s.'; -$lang['filelocked'] = 'Ce fichier est verrouillé - réessayez plus tard.'; +$lang['filelocked'] = 'La page %s est verrouillée - réessayez plus tard.'; $lang['notchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; $lang['exists'] = 'La page %s ne peut être déplacée vers %s, la cible existe déjà.'; $lang['notargetperms'] = 'Pous n\'avez pas la permission de créer la page %s.'; $lang['medianotexist'] = 'Le fichier média %s n\'existe pas.'; $lang['nomediarights'] = 'Vous ne disposez pas des permissions suffisantes pour effacer %s.'; $lang['medianotchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; +$lang['mediaexists'] = 'Impossible de déplacer le média %s. la cible %s existe déjà.'; +$lang['nomediatargetperms'] = 'Vous n\'avez pas les permissions de créer le média %s'; $lang['renamed'] = 'Nom de la page changé de %s à %s'; $lang['moved'] = 'Page déplacée de %s à %s'; $lang['move_rename'] = 'Page déplacée et renommée de %s à %s'; $lang['delete'] = 'Effacé par le plugin de déplacement'; -$lang['linkchange'] = 'Les liens vers %s ont été changés vers %s'; -$lang['btn_start'] = 'Départ'; +$lang['linkchange'] = 'Liens modifié en raison d\'un déplacement.'; +$lang['intro'] = 'L\'opération de déplacement n\'a pas encore commencé.'; +$lang['preview'] = 'Visualiser les changements à effectuer.'; +$lang['inexecution'] = 'Un déplacement n\'est pas arrivé à son terme - utilisez les boutons ci-dessous pour continuer ou abandonner son exécution.'; +$lang['btn_start'] = 'Commencer'; $lang['btn_continue'] = 'Continuer'; $lang['btn_retry'] = 'Réessayer cette étape'; $lang['btn_skip'] = 'Passer cette étape'; @@ -32,16 +39,22 @@ $lang['movens'] = 'Déplacer l\'espace de nom'; $lang['dst'] = 'Nouveau nom:'; $lang['content_to_move'] = 'Contenu à déplacer:'; +$lang['autoskip'] = 'Ignorer les erreurs et passer les pages ou fichiers qui ne peuvent être déplacés.'; +$lang['autorewrite'] = 'Récrire les liens à l\'issue du déplacement.'; $lang['move_pages'] = 'Pages'; $lang['move_media'] = 'Fichiers média'; $lang['move_media_and_pages'] = 'Pages et fichiers média'; $lang['nodst'] = 'Pas de nouveau nom donné'; $lang['noaction'] = 'Pas de déplacement demandé'; $lang['renamepage'] = 'Renommer la page'; +$lang['cantrename'] = 'Impossible de renommer la page maintenant. Veuillez essayer plus tard.'; $lang['js']['rename'] = 'Renommer'; $lang['js']['cancel'] = 'Annuler'; $lang['js']['newname'] = 'Nouveau nom:'; +$lang['js']['inprogress'] = 'Renommage des pages et ajustement des pages en cours...'; $lang['js']['complete'] = 'Déplacement effectué.'; $lang['js']['renameitem'] = 'Renommer cet élément'; -$lang['root'] = '[Espace de nom racine]'; +$lang['js']['duplicate'] = 'Désolé, "%s" existe dans cette catégorie.'; +$lang['root'] = '[Catégorie racine]'; $lang['noscript'] = 'Cette fonction requiert JavaScript'; +$lang['moveinprogress'] = 'Une opération de déplacement est en cours en ce moment. Vous ne pouvez pas utiliser cet outil maintenant.'; diff --git a/lang/fr/move.txt b/lang/fr/move.txt index 6fb801a..b4c4a85 100644 --- a/lang/fr/move.txt +++ b/lang/fr/move.txt @@ -1,10 +1,10 @@ ====== Move ====== -Ce plugin permet de déplacer et/ou renommer le document courant, avec les limitations suivantes : +Cette extension permet de déplacer et/ou renommer le document courant ou la catégorie courante, avec les limitations suivantes : - * Il faut avoir les droits d'édition sur le document - * Le document ne peut être verrouillés pour l'édition - * Pour déplacer une page il faut également disposer du droit de création dans le répertoire de destination - * Il est impossible de déplacer le document vers un espace de nommage où un document du même nom existe déjà. + * Il faut avoir les droits d'édition sur le document/tous les documents de la catégorie + * Les documents ne doivent pas être verrouillés pour l'édition + * Pour déplacer une page il faut également disposer du droit de création dans la catégorie de destination + * Il est impossible de déplacer le document vers une catégorie où un document du même nom existe déjà. Tous les liens depuis et vers la page seront mis à jour pour refléter le nouvel emplacement et/ou le nouveau nom. diff --git a/lang/fr/progress.txt b/lang/fr/progress.txt new file mode 100644 index 0000000..51b56a8 --- /dev/null +++ b/lang/fr/progress.txt @@ -0,0 +1,3 @@ +====== Déplacements en cours... ====== + +Veuillez garder cette page ouverte pendant toute la durée du déplacement. \ No newline at end of file diff --git a/lang/fr/settings.php b/lang/fr/settings.php new file mode 100644 index 0000000..fea26aa --- /dev/null +++ b/lang/fr/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = 'Autoriser le renommage de page à ces utilisaetrus et groupes (utiliser des virgules)'; +$lang['minor'] = 'Noter les ajustements de liens comme des modification mineures. Les modifications mineures ne sont indiquées ni dans les flux RSS, ni dans les courriels de s\'abonnement.'; +$lang['autoskip'] = 'Par défaut, ignorer les erreurs de déplacement de catégories.'; +$lang['autorewrite'] = 'Activer par défaut la réécriture automatique des liens après déplacement de catégories.'; diff --git a/lang/fr/tree.txt b/lang/fr/tree.txt index c511686..0f537ee 100644 --- a/lang/fr/tree.txt +++ b/lang/fr/tree.txt @@ -1,3 +1,3 @@ ====== Gestionnaire déplacement ===== -Cette interface vous permet de réorganiser vos espaces de noms, pages et médias par glisser-déposer. \ No newline at end of file +Cette interface vous permet de réorganiser catégories, pages et médias de votre wiki par glisser-déposer. \ No newline at end of file From ad294df658cc56fcaac6323740e0db12377a7a7a Mon Sep 17 00:00:00 2001 From: Andre Dierick Date: Wed, 10 Jun 2015 16:20:37 +0200 Subject: [PATCH 201/338] translation update --- lang/nl/lang.php | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/lang/nl/lang.php b/lang/nl/lang.php index 8f0f373..fa955de 100644 --- a/lang/nl/lang.php +++ b/lang/nl/lang.php @@ -1,30 +1,22 @@ + * + * @author Gary Owen + * @author Andre Dierick */ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Pagina Verplaatsen/Hernoemen...'; -$lang['desc'] = 'Pagina Verplaatsen/Hernoemen Plugin'; - -//$lang['notexist'] = 'Dit onderwerp bestaat nog niet'; -$lang['notwrite'] = 'U heeft niet voldoende rechten om deze pagina te wijzigen'; -$lang['badns'] = 'De namespace bevat een niet-toegestaan teken.'; -$lang['badname'] = 'De paginanaam bevat een niet-toegestaan teken.'; -$lang['nochange'] = 'De paginanaam en -namespace zijn ongewijzigd.'; -$lang['existing1'] = 'Het document met naam %s bestaat al in %s'; -$lang['root'] = '[Hoofdnamespace]'; -$lang['current'] = '(Huidig)'; -//$lang['norights'] = 'U heeft niet voldoende rechten om een of meerdere referenties aan te passen.'; -$lang['filelocked'] = 'Deze file is geblokkeerd - probeer later opnieuw.'; -$lang['linkchange1'] = 'Gelinkt aan %s gewijzigd naar %s'; -$lang['newname'] = 'Nieuwe naam document:'; -$lang['targetns'] = 'Selecteer namespace van het doel:'; +$lang['menu'] = 'Pagina Verplaatsen/Hernoemen...'; +$lang['inprogress'] = '(verplaatsen verwacht)'; +$lang['notexist'] = 'De pagina %s bestaat niet'; +$lang['norights'] = 'U hebt onvoldoende permissies om %s aan te passen'; +$lang['filelocked'] = 'Deze file is geblokkeerd - probeer later opnieuw.'; +$lang['exists'] = 'Pagina %s kan niet worden verplaatst naar %s, het doel bestaat al'; +$lang['notargetperms'] = 'U heeft niet voldoende permissies om pagina %s aan te maken'; +$lang['medianotexist'] = 'Het media bestand %s bestaat niet'; +$lang['nomediarights'] = 'U heeft niet voldoende permissies om pagina %s te verwijderen'; +$lang['nomediatargetperms'] = 'U heeft niet voldoende permissies om het media bestand %s aan te maken '; +$lang['renamed'] = 'Pagina naam van %s gewijzigd in %s'; +$lang['moved'] = 'Pagina verplaatst van %s naar %s'; +$lang['move_rename'] = 'pagina verplaatst en hernoemd van %s naar %s'; +$lang['root'] = '[Hoofdnamespace]'; From 108e7c5b50c594ddd36a2d5d4c51dfbfa464eb35 Mon Sep 17 00:00:00 2001 From: e-dschungel Date: Thu, 11 Jun 2015 22:15:08 +0200 Subject: [PATCH 202/338] translation update --- lang/de/lang.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lang/de/lang.php b/lang/de/lang.php index 9d8e6cb..e36d4a8 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -20,6 +20,12 @@ $lang['medianotchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; $lang['mediaexists'] = 'Mediendatei %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; $lang['nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; +$lang['indexerror'] = 'Fehler während der Aktualisierung des Suchindexes %s'; +$lang['metamoveerror'] = 'Die Metadateien der Seite %s konnten nicht verschoben werden'; +$lang['atticmoveerror'] = 'Die Attic-Dateien der Seite %s konnten nicht verschoben werden. Bitte verschieben Sie sie manuell.'; +$lang['mediametamoveerror'] = 'Die Metadateien der Mediendatei %s konnten nicht verschoben werden'; +$lang['mediamoveerror'] = 'Verschieben der Mediendatei %s fehlgeschlagen'; +$lang['mediaatticmoveerror'] = 'Die Attic-Dateien der Mediendatei %s konnten nicht verschoben werden. Bitte verschieben Sie sie manuell.'; $lang['renamed'] = 'Seitename wurde von %s auf %s geändert'; $lang['moved'] = 'Seite von %s nach %s verschoben'; $lang['move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; From 367f300c0bfcd3a7b4b77b5623e731ea2acd1349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schplurtz=20le=20D=C3=A9boulonn=C3=A9?= Date: Tue, 23 Jun 2015 18:25:36 +0200 Subject: [PATCH 203/338] translation update --- lang/fr/lang.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lang/fr/lang.php b/lang/fr/lang.php index 2e488de..9de99f4 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -9,8 +9,8 @@ */ $lang['menu'] = 'Déplacer/Renommer pages et catégories...'; $lang['inprogress'] = '(déplacement en attente)'; -$lang['treelink'] = 'Au lieu de ce simple formulaire, vous pouvez effectuer des restructurations complexes de votre wiki en utilisant le gestionnaire déplacements par arborescence'; -$lang['notexist'] = 'Le sujet %s n\'existe pas encore'; +$lang['treelink'] = 'Au lieu de ce simple formulaire, vous pouvez effectuer des restructurations complexes de votre wiki en utilisant le gestionnaire de déplacements par arborescence'; +$lang['notexist'] = 'La page %s n\'existe pas encore'; $lang['norights'] = 'Vos permissions sont insufisante pour éditer %s.'; $lang['filelocked'] = 'La page %s est verrouillée - réessayez plus tard.'; $lang['notchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; @@ -21,11 +21,17 @@ $lang['medianotchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; $lang['mediaexists'] = 'Impossible de déplacer le média %s. la cible %s existe déjà.'; $lang['nomediatargetperms'] = 'Vous n\'avez pas les permissions de créer le média %s'; +$lang['indexerror'] = 'Erreur lors de la mise à jour de l\'index de recherche %s.'; +$lang['metamoveerror'] = 'Impossible de déplacer les métafichiers de la page %s.'; +$lang['atticmoveerror'] = 'L\'historique (attic) de la page %s ne peut être déplacé. Veuillez déplacer les fichiers manuellement.'; +$lang['mediametamoveerror'] = 'Impossible de déplacer les métafichiers du media %s.'; +$lang['mediamoveerror'] = 'Échec du déplacement du média %s.'; +$lang['mediaatticmoveerror'] = 'L\'historique (attic) du média %s ne peut être déplacé. Veuillez déplacer les fichiers manuellement.'; $lang['renamed'] = 'Nom de la page changé de %s à %s'; $lang['moved'] = 'Page déplacée de %s à %s'; $lang['move_rename'] = 'Page déplacée et renommée de %s à %s'; $lang['delete'] = 'Effacé par le plugin de déplacement'; -$lang['linkchange'] = 'Liens modifié en raison d\'un déplacement.'; +$lang['linkchange'] = 'Liens modifiés en raison d\'un déplacement.'; $lang['intro'] = 'L\'opération de déplacement n\'a pas encore commencé.'; $lang['preview'] = 'Visualiser les changements à effectuer.'; $lang['inexecution'] = 'Un déplacement n\'est pas arrivé à son terme - utilisez les boutons ci-dessous pour continuer ou abandonner son exécution.'; From 1d4f7a9c7b0109015167e5d81942ea766651c74c Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 26 Jun 2015 09:40:05 +0200 Subject: [PATCH 204/338] translation update --- lang/no/lang.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lang/no/lang.php diff --git a/lang/no/lang.php b/lang/no/lang.php new file mode 100644 index 0000000..186f67c --- /dev/null +++ b/lang/no/lang.php @@ -0,0 +1,13 @@ + + */ +$lang['menu'] = 'Flytt sider og navnerom'; +$lang['inprogress'] = '(flytting avventer)'; +$lang['treelink'] = 'I tillegg til dette enkle skjemaet kan du også utføre kompleks omstrukturering av din wiki ved å bruke tree-based move manager.'; +$lang['notexist'] = 'Siden %s eksisterer ikke'; +$lang['norights'] = 'Du har ikke nok rettigheter til å endre %s.'; +$lang['filelocked'] = 'Side %s er låst. Prøv igjen senere.'; From f2f492f352b726dd9cb4912d3e742957d1e7c11e Mon Sep 17 00:00:00 2001 From: Daniel Raknes Date: Mon, 29 Jun 2015 15:15:04 +0200 Subject: [PATCH 205/338] translation update --- lang/no/lang.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lang/no/lang.php b/lang/no/lang.php index 186f67c..6a56c2f 100644 --- a/lang/no/lang.php +++ b/lang/no/lang.php @@ -4,6 +4,7 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * * @author Daniel + * @author Daniel Raknes */ $lang['menu'] = 'Flytt sider og navnerom'; $lang['inprogress'] = '(flytting avventer)'; @@ -11,3 +12,19 @@ $lang['notexist'] = 'Siden %s eksisterer ikke'; $lang['norights'] = 'Du har ikke nok rettigheter til å endre %s.'; $lang['filelocked'] = 'Side %s er låst. Prøv igjen senere.'; +$lang['notchanged'] = 'Det er ikke lagt inn nytt lagringssted for %s (lagringsstedet er uendret).'; +$lang['exists'] = 'Siden %s kan ikke flyttes til %s, mål finnes allerede.'; +$lang['notargetperms'] = 'Du har ikke rettigheter til å lage siden %s.'; +$lang['medianotexist'] = 'Media-filen %s eksisterer ikke'; +$lang['nomediarights'] = 'Du har ikke rettigheter til å slette %s.'; +$lang['metamoveerror'] = 'Metafilene for siden %s kunne ikke flyttes.'; +$lang['mediamoveerror'] = 'Flytting av mediafilen %s feilet'; +$lang['moved'] = 'Siden ble flyttet fra %s til %s'; +$lang['delete'] = 'Slettet av move plugin'; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Fortsett'; +$lang['btn_retry'] = 'Prøv på nytt'; +$lang['btn_skip'] = 'Hopp over'; +$lang['btn_abort'] = 'Avbryt'; +$lang['movepage'] = 'Flytt side'; +$lang['movens'] = 'Flytt navnerom'; From dde9f03252a77c0e056f200c98621a3a57a1cb83 Mon Sep 17 00:00:00 2001 From: Peter van Diest Date: Thu, 9 Jul 2015 09:45:08 +0200 Subject: [PATCH 206/338] translation update --- lang/nl/lang.php | 48 ++++++++++++++++++++++++++++++++++++++++++-- lang/nl/move.txt | 10 ++++----- lang/nl/progress.txt | 3 +++ lang/nl/settings.php | 11 ++++++++++ lang/nl/tree.txt | 3 +++ 5 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 lang/nl/progress.txt create mode 100644 lang/nl/settings.php create mode 100644 lang/nl/tree.txt diff --git a/lang/nl/lang.php b/lang/nl/lang.php index fa955de..9b37782 100644 --- a/lang/nl/lang.php +++ b/lang/nl/lang.php @@ -5,18 +5,62 @@ * * @author Gary Owen * @author Andre Dierick + * @author Peter van Diest */ $lang['menu'] = 'Pagina Verplaatsen/Hernoemen...'; $lang['inprogress'] = '(verplaatsen verwacht)'; +$lang['treelink'] = 'Als alternatief voor dit eenvoudig formulier kun je complexere herstructurering aan met de tree-based move manager.'; $lang['notexist'] = 'De pagina %s bestaat niet'; $lang['norights'] = 'U hebt onvoldoende permissies om %s aan te passen'; -$lang['filelocked'] = 'Deze file is geblokkeerd - probeer later opnieuw.'; +$lang['filelocked'] = 'Pagina %s is geblokkeerd. Probeer het later nog eens.'; +$lang['notchanged'] = 'Geen nieuwe bestemming gegeven voor pagina %s (locatie onveranderd).'; $lang['exists'] = 'Pagina %s kan niet worden verplaatst naar %s, het doel bestaat al'; $lang['notargetperms'] = 'U heeft niet voldoende permissies om pagina %s aan te maken'; $lang['medianotexist'] = 'Het media bestand %s bestaat niet'; $lang['nomediarights'] = 'U heeft niet voldoende permissies om pagina %s te verwijderen'; +$lang['medianotchanged'] = 'Geen nieuwe bestemming gegeven voor pagina %s (locatie onveranderd).'; +$lang['mediaexists'] = 'Media %s kan niet worden verplaatst naar %s, het doel bestaat al.'; $lang['nomediatargetperms'] = 'U heeft niet voldoende permissies om het media bestand %s aan te maken '; +$lang['indexerror'] = 'Fout bij updaten van zoekindex %s'; +$lang['metamoveerror'] = 'De metabestanden van pagina %s konden niet worden verplaatst'; +$lang['atticmoveerror'] = 'De atticbestanden van pagina %s konden niet worden verplaatst. Verplaats ze handmatig.'; +$lang['mediametamoveerror'] = 'De metabestanden van mediabestand %s konden niet worden verplaatst'; +$lang['mediamoveerror'] = 'Verplaatsen van het mediabestand %s is mislukt'; +$lang['mediaatticmoveerror'] = 'De atticbestanden van mediabestand %s konden niet worden verplaatst. Verplaats ze handmatig.'; $lang['renamed'] = 'Pagina naam van %s gewijzigd in %s'; $lang['moved'] = 'Pagina verplaatst van %s naar %s'; -$lang['move_rename'] = 'pagina verplaatst en hernoemd van %s naar %s'; +$lang['move_rename'] = 'Pagina verplaatst en hernoemd van %s naar %s'; +$lang['delete'] = 'Verwijderd door move plugin'; +$lang['linkchange'] = 'Links aangepast vanwege een verplaatsing'; +$lang['intro'] = 'De verplaatsing is nog niet begonnen!'; +$lang['preview'] = 'Bekijk de wijzigingen die worden uitgevoerd.'; +$lang['inexecution'] = 'Een vorige verplaatsing was niet gereed - gebruik onderstaande knoppen om door te gaan of te stoppen.'; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Ga door'; +$lang['btn_retry'] = 'Probeer opnieuw voor dit item'; +$lang['btn_skip'] = 'Sla item over'; +$lang['btn_abort'] = 'Breek af'; +$lang['legend'] = 'Verplaats huidige pagina of namespace'; +$lang['movepage'] = 'Verplaats pagina'; +$lang['movens'] = 'Verplaats namespace'; +$lang['dst'] = 'Nieuwe naam:'; +$lang['content_to_move'] = 'Te verplaatsen inhoud:'; +$lang['autoskip'] = 'Negeer fouten en sla pagina\'s of bestanden die niet kunnen worden verplaatst over.'; +$lang['autorewrite'] = 'Herschrijf links meteen nadat de verplaatsing gereed is'; +$lang['move_pages'] = 'Pagina\'s'; +$lang['move_media'] = 'Mediabestanden'; +$lang['move_media_and_pages'] = 'Pagina\'s en mediabestanden'; +$lang['nodst'] = 'Geen nieuwe naam opgegeven'; +$lang['noaction'] = 'Er zijn geen verplaatsingen gedefinieerd'; +$lang['renamepage'] = 'Hernoem Pagina'; +$lang['cantrename'] = 'De pagina kan momenteel niet worden hernoemd. Probeer het later nog eens.'; +$lang['js']['rename'] = 'Hernoem'; +$lang['js']['cancel'] = 'Annuleren'; +$lang['js']['newname'] = 'Nieuwe naam:'; +$lang['js']['inprogress'] = 'pagina hernoemen en links aanpassen...'; +$lang['js']['complete'] = 'Verplaatsing compleet.'; +$lang['js']['renameitem'] = 'Hernoem dit item'; +$lang['js']['duplicate'] = 'Sorry, "%s" bestaat al in deze namespace.'; $lang['root'] = '[Hoofdnamespace]'; +$lang['noscript'] = 'Deze mogelijkheid vereist Javascript'; +$lang['moveinprogress'] = 'Er is een andere verplaatsingsactie gaande, gebruik van deze tool is momenteel niet mogelijk.'; diff --git a/lang/nl/move.txt b/lang/nl/move.txt index 5705529..0528d81 100644 --- a/lang/nl/move.txt +++ b/lang/nl/move.txt @@ -2,9 +2,9 @@ Deze plugin stelt je in staat pagina's te verplaatsen en/of te hernoemen binnen volgende beperkingen: - * You must have edit permission for the current page/all pages in the current namespace - * De pagina en zijn referenties kunnen niet geblokkeerd worden tijdens het verplaatsen - * Om pagina's te verplaatsen heb je ook schrijfrechten nodig in de folder van bestemming - * Je kan een pagina niet plaatsen in een namespace waar al een pagina bestaat met dezelfde naam + * Je moet edit-permissie hebben voor de huidige pagina/alle pagina's in de huidige namespace. + * De te verplaatsen pagina's mogen niet geblokkeerd zijn vanwege aanpassing. + * Om pagina's te verplaatsen heb je ook schrijfrechten nodig in de doelfolder. + * Je kunt een pagina niet plaatsen naar een namespace waar al een pagina bestaat met dezelfde naam -Al de links van en naar de pagina zullen geupdated worden naar de nieuwe naam/locatie. +Alle links van en naar de pagina zullen geupdated worden naar de nieuwe naam/locatie. diff --git a/lang/nl/progress.txt b/lang/nl/progress.txt new file mode 100644 index 0000000..73f404d --- /dev/null +++ b/lang/nl/progress.txt @@ -0,0 +1,3 @@ +====== Bezig met verplaatsing... ====== + +Houd deze pagina open zolang de verplaatsing bezig is. \ No newline at end of file diff --git a/lang/nl/settings.php b/lang/nl/settings.php new file mode 100644 index 0000000..a6ccf6b --- /dev/null +++ b/lang/nl/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = 'Hernoemen van pagina\'s toestaan voor deze groepen en gebruikers (komma-gescheiden).'; +$lang['minor'] = 'Link-aanpassingen als kleine aanpassingen markeren? Kleine aanpassingen worden niet genoemd in RRS feeds en nieuwsbrieven.'; +$lang['autoskip'] = 'Automatisch overslaan van fouten bij verplaatsingen van namespaces standaard inschakelen.'; +$lang['autorewrite'] = 'Automatisch herschrijven van links na verplaatsingen van namespaces standaard inschakelen.'; diff --git a/lang/nl/tree.txt b/lang/nl/tree.txt new file mode 100644 index 0000000..a8bc657 --- /dev/null +++ b/lang/nl/tree.txt @@ -0,0 +1,3 @@ +====== Move Manager ===== + +Met dit interface kun je de namespaces, pagina's en mediabestanden verplaatsen door te slepen. \ No newline at end of file From 41faeb1190860005757bfc1bd6e11e3f2ebbddd8 Mon Sep 17 00:00:00 2001 From: Giuseppe Di Terlizzi Date: Sat, 18 Jul 2015 16:48:10 +0200 Subject: [PATCH 207/338] Added support to Bootstrap3 Template --- action/rename.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/action/rename.php b/action/rename.php index c609d07..f443c7e 100644 --- a/action/rename.php +++ b/action/rename.php @@ -45,6 +45,7 @@ public function handle_pagetools(Doku_Event $event) { switch($conf['template']) { case 'dokuwiki': case 'arago': + case 'bootstrap3': $newitem = '
  • ' . $this->getLang('renamepage') . '
  • '; $offset = count($event->data['items']) - 1; @@ -121,4 +122,4 @@ public function tpl() { echo ''; } -} \ No newline at end of file +} From 0e14fb088e494024af176d5ef2b0df518547887e Mon Sep 17 00:00:00 2001 From: trebmuh Date: Wed, 22 Jul 2015 21:20:45 +0200 Subject: [PATCH 208/338] Update settings.php typos --- lang/fr/settings.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lang/fr/settings.php b/lang/fr/settings.php index fea26aa..5e447dc 100644 --- a/lang/fr/settings.php +++ b/lang/fr/settings.php @@ -5,7 +5,7 @@ * * @author Schplurtz le Déboulonné */ -$lang['allowrename'] = 'Autoriser le renommage de page à ces utilisaetrus et groupes (utiliser des virgules)'; -$lang['minor'] = 'Noter les ajustements de liens comme des modification mineures. Les modifications mineures ne sont indiquées ni dans les flux RSS, ni dans les courriels de s\'abonnement.'; +$lang['allowrename'] = 'Autoriser le renommage de page à ces utilisateus et groupes (utiliser des virgules)'; +$lang['minor'] = 'Noter les ajustements de liens comme des modifications mineures. Les modifications mineures ne sont indiquées ni dans les flux RSS, ni dans les courriels des abonnements.'; $lang['autoskip'] = 'Par défaut, ignorer les erreurs de déplacement de catégories.'; -$lang['autorewrite'] = 'Activer par défaut la réécriture automatique des liens après déplacement de catégories.'; +$lang['autorewrite'] = 'Activer par défaut la ré-écriture automatique des liens après déplacement de catégories.'; From e3f15331569d88dab53e292cc5d3c71f077f5fad Mon Sep 17 00:00:00 2001 From: Hideaki SAWADA Date: Fri, 31 Jul 2015 08:20:06 +0200 Subject: [PATCH 209/338] translation update --- lang/ja/move.txt | 10 ++++++++++ lang/ja/progress.txt | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 lang/ja/move.txt create mode 100644 lang/ja/progress.txt diff --git a/lang/ja/move.txt b/lang/ja/move.txt new file mode 100644 index 0000000..8004a86 --- /dev/null +++ b/lang/ja/move.txt @@ -0,0 +1,10 @@ +====== 移動 ====== + +このプラグインは、以下の制約の範囲内で、今いるページの移動・名称変更、今いる名前空間の移動・名称変更が可能です: + + * 今いるページ/今いる名前空間内の全ページに対する編集権限があること + * 移動するページが編集ロックされていないこと + * ページ移動のために、移動先の名前空間に対する作成権限があること + * 移動先の名前空間内に同じ名前のページが存在しないこと + +移動したページとの間の全てのリンクは、新しい場所・新しい名前を反映して更新されます。 \ No newline at end of file diff --git a/lang/ja/progress.txt b/lang/ja/progress.txt new file mode 100644 index 0000000..aeca181 --- /dev/null +++ b/lang/ja/progress.txt @@ -0,0 +1,3 @@ +====== 移動処理中・・・ ====== + +移動処理中は、このページを閉じないで下さい。 From 3c692d0a0917f3ed5b2525ffb26f636964c1f209 Mon Sep 17 00:00:00 2001 From: Hideaki SAWADA Date: Sat, 1 Aug 2015 16:45:32 +0200 Subject: [PATCH 210/338] translation update --- lang/ja/lang.php | 64 ++++++++++++++++++++++++++++++++++++++++++++ lang/ja/settings.php | 11 ++++++++ lang/ja/tree.txt | 3 +++ 3 files changed, 78 insertions(+) create mode 100644 lang/ja/lang.php create mode 100644 lang/ja/settings.php create mode 100644 lang/ja/tree.txt diff --git a/lang/ja/lang.php b/lang/ja/lang.php new file mode 100644 index 0000000..1b3f6d0 --- /dev/null +++ b/lang/ja/lang.php @@ -0,0 +1,64 @@ + + */ +$lang['menu'] = 'ページ・名前空間の移動'; +$lang['inprogress'] = '(移動保留中)'; +$lang['treelink'] = 'この簡単なフォームの代わりに、ツリー型の移動管理を利用して Wiki の複雑な再構築を管理できます。'; +$lang['notexist'] = '%s ページは存在しません。'; +$lang['norights'] = '%s の編集権限がありません。'; +$lang['filelocked'] = '%s ページはロックされています。後で再実行して下さい。'; +$lang['notchanged'] = '%s ページの移動先が指定されていません(変更なし)。'; +$lang['exists'] = '%s ページは %s に移動できません。既に存在します。'; +$lang['notargetperms'] = '%s ページの作成権限がありません。'; +$lang['medianotexist'] = '%s メディアファイルは存在しません。'; +$lang['nomediarights'] = '%s の削除権限がありません。'; +$lang['medianotchanged'] = '%s メディアファイルの移動先が指定されていません(変更なし)。'; +$lang['mediaexists'] = '%s メディアファイルは %s に移動できません。既に存在します。'; +$lang['nomediatargetperms'] = '%s メディアファイルの作成権限がありません。'; +$lang['indexerror'] = '%s 検索インデックス更新中にエラーが発生しました。'; +$lang['metamoveerror'] = '%s ページの meta ファイルが移動できませんでした。'; +$lang['atticmoveerror'] = '%s ページの attic ファイルが移動できませんでした。手動で移動して下さい'; +$lang['mediametamoveerror'] = '%s メディアファイルの meta ファイルが移動できませんでした。'; +$lang['mediamoveerror'] = '%s メディアファイルが移動できませんでした。'; +$lang['mediaatticmoveerror'] = '%s メディアファイルの attic ファイルが移動できませんでした。手動で移動して下さい。'; +$lang['renamed'] = '%s から %s へページを名称変更しました。'; +$lang['moved'] = '%s から %s へページを移動しました。'; +$lang['move_rename'] = '%s から %s へページの移動と名称変更しました。'; +$lang['delete'] = '移動プラグインが削除しました。'; +$lang['linkchange'] = '移動操作に合わせてリンクを書き換えました。'; +$lang['intro'] = '移動操作はまだ開始していません!'; +$lang['preview'] = '実行する変更を事前確認して下さい。'; +$lang['inexecution'] = '前の移動が完了していません。処理の続行・中止を下のボタンで指定して下さい。'; +$lang['btn_start'] = '開始'; +$lang['btn_continue'] = '続行'; +$lang['btn_retry'] = '再実行'; +$lang['btn_skip'] = 'スキップ'; +$lang['btn_abort'] = '中止'; +$lang['legend'] = '現在のページ・名前空間の移動'; +$lang['movepage'] = 'ページの移動'; +$lang['movens'] = '名前空間の移動'; +$lang['dst'] = '移動先: '; +$lang['content_to_move'] = '移動する内容: '; +$lang['autoskip'] = 'エラーを無視し、移動できないページ・ファイルをスキップします。'; +$lang['autorewrite'] = '移動完了後にリンクを書き換えます。'; +$lang['move_pages'] = 'ページ'; +$lang['move_media'] = 'メディアファイル'; +$lang['move_media_and_pages'] = 'ページとメディアファイル'; +$lang['nodst'] = '移動先が指定されていません。'; +$lang['noaction'] = '移動操作が指定されていません。'; +$lang['renamepage'] = 'ページの名称変更'; +$lang['cantrename'] = 'ページを名称変更できません。後で再実行して下さい。'; +$lang['js']['rename'] = '名称変更'; +$lang['js']['cancel'] = '中止'; +$lang['js']['newname'] = '新ページ名: '; +$lang['js']['inprogress'] = 'ページの名称変更・リンクの書き換え中…'; +$lang['js']['complete'] = '名称変更操作が完了しました。'; +$lang['js']['renameitem'] = 'この項目を名称変更します。'; +$lang['js']['duplicate'] = '"%s" はこの名前空間内に既に存在します。'; +$lang['root'] = '[ルート名前空間]'; +$lang['noscript'] = 'この機能には JavaScriptが必要です。'; +$lang['moveinprogress'] = '別の移動操作を処理中なので、今はこのツールを使用できません。'; diff --git a/lang/ja/settings.php b/lang/ja/settings.php new file mode 100644 index 0000000..bdac41b --- /dev/null +++ b/lang/ja/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = 'ページ名変更を許可するグループ・ユーザー(カンマ区切り)'; +$lang['minor'] = 'リンクの書き換えを小変更扱いにする。小変更にすると RSS 配信・メール更新通知には表示されない。'; +$lang['autoskip'] = '名前空間移動時のエラーの自動スキップ。デフォルトは有効。'; +$lang['autorewrite'] = '名前空間移動後のリンクの自動書き換え。デフォルトは有効。'; diff --git a/lang/ja/tree.txt b/lang/ja/tree.txt new file mode 100644 index 0000000..7bf9059 --- /dev/null +++ b/lang/ja/tree.txt @@ -0,0 +1,3 @@ +====== 移動管理 ===== + +この画面では、Wiki 内の名前空間・ページ・メディアファイルをドラッグ&ドロップで再配置することができます。 \ No newline at end of file From e086c93b3f0f108c93c90997a7f58d1287d00483 Mon Sep 17 00:00:00 2001 From: Myeongjin Date: Sun, 16 Aug 2015 15:10:39 +0200 Subject: [PATCH 211/338] translation update --- lang/ko/lang.php | 120 ++++++++++++++++++++++--------------------- lang/ko/move.txt | 2 +- lang/ko/progress.txt | 3 ++ lang/ko/settings.php | 11 ++++ lang/ko/tree.txt | 3 ++ 5 files changed, 79 insertions(+), 60 deletions(-) create mode 100644 lang/ko/progress.txt create mode 100644 lang/ko/settings.php create mode 100644 lang/ko/tree.txt diff --git a/lang/ko/lang.php b/lang/ko/lang.php index 9e167aa..83ec84e 100644 --- a/lang/ko/lang.php +++ b/lang/ko/lang.php @@ -1,63 +1,65 @@ - * @author Myeongjin + * + * @author Gary Owen + * @author Myeongjin */ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = '문서/이름공간 옮기기/이름 바꾸기...'; -$lang['desc'] = '문서/이름공간 옮기기/이름 바꾸기 플러그인'; - -$lang['notexist'] = '%s 문서가 존재하지 않습니다'; -$lang['medianotexist'] = '%s 미디어 파일이 존재하지 않습니다'; -$lang['notwrite'] = '이 문서를 수정할 충분한 권한이 없습니다'; -$lang['badns'] = '이름공간에 잘못된 글자가 있습니다.'; -$lang['badname'] = '문서 이름에 잘못된 글자가 있습니다.'; -$lang['nochange'] = '문서 이름과 이름공간이 바뀌지 않습니다.'; -$lang['nomediachange'] = '미디어 파일 이름과 이름공간이 바뀌지 않습니다.'; -$lang['existing'] = '%s인 문서는 이미 %s에 존재합니다'; -$lang['mediaexisting'] = '%s인 미디어 파일은 이미 %s에 존재합니다'; -$lang['root'] = '[루트 이름공간]'; -$lang['current'] = '(현재)'; -$lang['renamed'] = '문서 이름이 %s에서 %s(으)로 바뀌었습니다'; -$lang['moved'] = '문서가 %s에서 %s(으)로 옮겨졌습니다'; -$lang['move_rename'] = '문서가 %s에서 %s(으)로 옮겨지고 이름이 바뀌었습니다'; -$lang['delete'] = '옮기기 플러그인에 의해 삭제됨'; -$lang['norights'] = '%s(을)를 편집할 충분하지 않은 권한이 있습니다.'; -$lang['nomediarights'] = '%s(을)를 삭제할 충분하지 않은 권한이 있습니다.'; -$lang['notargetperms'] = '%s 문서를 만들 권한이 없습니다.'; -$lang['nomediatargetperms'] = '%s 미디어 파일을 만들 권한이 없습니다.'; -$lang['filelocked'] = '%s 문서가 잠겨 있습니다. 나중에 다시 시도하세요.'; -$lang['linkchange'] = '링크가 옮기기 작업 때문에 적응했습니다'; - -$lang['ns_move_in_progress'] = '여기에 현재 문서 %s개와 미디어 파일 %s개가 %s 이름공간에서 %s 이름공간으로 옮겨지고 있습니다.'; -$lang['ns_move_continue'] = '이름공간 옮기기 계속'; -$lang['ns_move_abort'] = '이름공간 옮기기 중단'; -$lang['ns_move_continued'] = '이름공간 옮기기가 %s 이름공간에서 %s 이름공간으로 계속되었으며, 항목 %s개가 여전히 남아 있습니다.'; -$lang['ns_move_started'] = '이름공간 옮기기가 %s 이름공간에서 %s 이름공간으로 시작되었으며, 문서 %s개와 미디어 파일 %s개가 옮겨집니다.'; -$lang['ns_move_error'] = '이름공간 옮기기를 %s에서 %s(으)로 계속하는 동안 오류가 발생했습니다.'; -$lang['ns_move_tryagain'] = '다시 시도'; -$lang['ns_move_skip'] = '현재 항목을 건너뛰기'; -// Form labels -$lang['newname'] = '새 문서 이름:'; -$lang['newnsname'] = '새 이름공간 이름:'; -$lang['targetns'] = '새 이름공간 선택:'; -$lang['newtargetns'] = '새 이름공간 만들기:'; -$lang['movepage'] = '문서 옮기기'; -$lang['movens'] = '이름공간 옮기기'; -$lang['submit'] = '제출'; -$lang['content_to_move'] = '옮길 내용'; -$lang['move_pages'] = '문서'; -$lang['move_media'] = '미디어 파일'; -$lang['move_media_and_pages'] = '문서와 미디어 파일'; -// JavaScript preview -$lang['js']['previewpage'] = 'OLDPAGE(은)는 NEWPAGE(으)로 옮겨집니다'; -$lang['js']['previewns'] = 'OLDNS 이름공간 안에 모든 문서와 이름공간은 NEWNS 이름공간 안으로 옮겨집니다'; +$lang['menu'] = '문서와 이름공간 옮기기'; +$lang['inprogress'] = '(옮기기 보류 중)'; +$lang['treelink'] = '다른 방법으로 이 간단한 양식은 트리 기반의 옮기기 관리자를 사용하여 위키의 복잡한 구조 조정을 관리할 수 있습니다.'; +$lang['notexist'] = '%s 문서가 존재하지 않습니다'; +$lang['norights'] = '%s(을)를 편집할 충분하지 않은 권한이 있습니다.'; +$lang['filelocked'] = '%s 문서가 잠겨 있습니다. 나중에 다시 시도하세요.'; +$lang['notchanged'] = '%s 문서에 주어진 새 대상이 없습니다. (위치가 바뀌지 않음)'; +$lang['exists'] = '%s 문서는 %s(으)로 옮길 수 없으며, 대상이 이미 존재합니다.'; +$lang['notargetperms'] = '%s 문서를 만들 권한이 없습니다.'; +$lang['medianotexist'] = '%s 미디어 파일이 존재하지 않습니다'; +$lang['nomediarights'] = '%s(을)를 삭제할 충분하지 않은 권한이 있습니다.'; +$lang['medianotchanged'] = '%s 문서에 주어진 새 대상이 없습니다. (위치가 바뀌지 않음)'; +$lang['mediaexists'] = '%s 미디어는 %s(으)로 옮길 수 없으며, 대상이 이미 존재합니다.'; +$lang['nomediatargetperms'] = '%s 미디어 파일을 만들 권한이 없습니다.'; +$lang['indexerror'] = '%s 검색 색인을 업데이트하는 동안 오류'; +$lang['metamoveerror'] = '%s 문서의 메타 파일을 옮길 수 없습니다'; +$lang['atticmoveerror'] = '%s 문서의 첨부 파일을 옮길 수 없습니다. 직접 옮겨주세요.'; +$lang['mediametamoveerror'] = '%s 미디어 파일의 메타 파일을 옮길 수 없습니다'; +$lang['mediamoveerror'] = '%s 미디어 파일을 옮기는 데 실패했습니다'; +$lang['mediaatticmoveerror'] = '%s 문서의 첨부 파일을 옮길 수 없습니다. 직접 옮겨주세요.'; +$lang['renamed'] = '문서 이름이 %s에서 %s(으)로 바뀌었습니다'; +$lang['moved'] = '문서가 %s에서 %s(으)로 옮겨졌습니다'; +$lang['move_rename'] = '문서가 %s에서 %s(으)로 옮겨지고 이름이 바뀌었습니다'; +$lang['delete'] = '옮기기 플러그인에 의해 삭제됨'; +$lang['linkchange'] = '링크가 옮기기 작업으로 인해 적응했습니다'; +$lang['intro'] = '옮기기 작업은 아직 시작되지 않았습니다!'; +$lang['preview'] = '실행할 바뀜을 미리 봅니다.'; +$lang['inexecution'] = '이전 옮기기가 완료되지 않았습니다 - 실행을 계속하거나 중단하려면 아래 버튼을 사용하세요.'; +$lang['btn_start'] = '시작'; +$lang['btn_continue'] = '계속'; +$lang['btn_retry'] = '항목 다시 시도'; +$lang['btn_skip'] = '항목 건너뛰기'; +$lang['btn_abort'] = '중단'; +$lang['legend'] = '현재 문서 또는 이름공간 옮기기'; +$lang['movepage'] = '문서 옮기기'; +$lang['movens'] = '이름공간 옮기기'; +$lang['dst'] = '새 이름:'; +$lang['content_to_move'] = '옮길 내용:'; +$lang['autoskip'] = '오류를 무시하고 옮길 수 없는 문서나 파일을 건너뛰기'; +$lang['autorewrite'] = '옮기기를 완료하고 나서 링크를 올바르게 다시 쓰기'; +$lang['move_pages'] = '문서'; +$lang['move_media'] = '미디어 파일'; +$lang['move_media_and_pages'] = '문서와 미디어 파일'; +$lang['nodst'] = '주어진 새 이름이 없습니다'; +$lang['noaction'] = '정의한 옮기기가 없습니다'; +$lang['renamepage'] = '문서 이름 바꾸기'; +$lang['cantrename'] = '문서는 지금 바로 이름을 바꿀 수 없습니다. 나중에 시도해주세요.'; +$lang['js']['rename'] = '이름 바꾸기'; +$lang['js']['cancel'] = '취소'; +$lang['js']['newname'] = '새 이름:'; +$lang['js']['inprogress'] = '문서의 이름을 바꾸고 링크를 조절하는 중...'; +$lang['js']['complete'] = '옮기기 작업이 완료되었습니다.'; +$lang['js']['renameitem'] = '이 항목 이름 바꾸기'; +$lang['js']['duplicate'] = '죄송하지만, "%s"은(는) 이미 이 이름공간에 존재합니다.'; +$lang['root'] = '[루트 이름공간]'; +$lang['noscript'] = '이 기능은 자바스크립트가 필요합니다'; +$lang['moveinprogress'] = '현재 진행 중인 다른 옮기기 작업이 있습니다, 지금 바로 이 도구를 사용할 수 없습니다.'; diff --git a/lang/ko/move.txt b/lang/ko/move.txt index eae25c2..d4e161b 100644 --- a/lang/ko/move.txt +++ b/lang/ko/move.txt @@ -7,4 +7,4 @@ * 문서 옮기기를 위해서는 대상 이름공간에서 만들기 권한도 필요합니다. * 같은 이름으로 된 문서가 이미 존재하는 이름공간으로 문서를 옮길 수 없습니다. -기존에서 새로 옮겨지는 문서의 모든 링크는 새 위치와/나 이름을 반영하도록 바뀝니다. +기존에서 새로 옮겨지는 문서의 모든 링크는 새 위치와/나 이름을 반영하도록 바뀝니다. \ No newline at end of file diff --git a/lang/ko/progress.txt b/lang/ko/progress.txt new file mode 100644 index 0000000..2be01ce --- /dev/null +++ b/lang/ko/progress.txt @@ -0,0 +1,3 @@ +====== 진행 중인 옮기기... ====== + +옮기기를 진행하는 동안 이 문서를 열어두세요. \ No newline at end of file diff --git a/lang/ko/settings.php b/lang/ko/settings.php new file mode 100644 index 0000000..50a22f7 --- /dev/null +++ b/lang/ko/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = '문서의 이름을 바꿀 수 있는 그룹 및 사용자 (쉼표로 구분).'; +$lang['minor'] = '링크 조절을 사소한 바뀜으로 표시하겠습니까? 사소한 바뀜은 RSS 피드와 구독 메일에 나열하지 않을 것입니다.'; +$lang['autoskip'] = '기본적으로 이름공간 옮기기에서 오류를 자동으로 건너뛰도록 활성화합니다.'; +$lang['autorewrite'] = '기본적으로 이름공간을 옮기고 나서 자동으로 링크 다시 쓰기를 활성화합니다.'; diff --git a/lang/ko/tree.txt b/lang/ko/tree.txt new file mode 100644 index 0000000..957153a --- /dev/null +++ b/lang/ko/tree.txt @@ -0,0 +1,3 @@ +====== 옮기기 관리자 ===== + +이 인터페이스는 드래그 앤 드롭을 통해 위키의 이름공간, 문서와 미디어 파일을 재배열할 수 있습니다. \ No newline at end of file From df61a5077d8e51c69a7705f0888eb138c297a1f9 Mon Sep 17 00:00:00 2001 From: Pavel Kochman Date: Wed, 19 Aug 2015 14:31:47 +0200 Subject: [PATCH 212/338] Typo in comment. --- action/progress.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action/progress.php b/action/progress.php index 5120a15..6b00782 100644 --- a/action/progress.php +++ b/action/progress.php @@ -9,7 +9,7 @@ if(!defined('DOKU_INC')) die(); /** - * Class action_plugin_move_rename + * Class action_plugin_move_progress */ class action_plugin_move_progress extends DokuWiki_Action_Plugin { From 4aec28994cb0f4481483e9302273d1ce366a9bd9 Mon Sep 17 00:00:00 2001 From: Pavel Kochman Date: Wed, 19 Aug 2015 21:18:44 +0200 Subject: [PATCH 213/338] update czech language files --- lang/cs/lang.php | 95 +++++++++++++++++++++++++++++++++++--------- lang/cs/move.txt | 2 +- lang/cs/progress.txt | 3 ++ lang/cs/settings.php | 11 +++++ lang/cs/tree.txt | 3 ++ 5 files changed, 94 insertions(+), 20 deletions(-) create mode 100644 lang/cs/progress.txt create mode 100644 lang/cs/settings.php create mode 100644 lang/cs/tree.txt diff --git a/lang/cs/lang.php b/lang/cs/lang.php index 19d79ea..efa045f 100644 --- a/lang/cs/lang.php +++ b/lang/cs/lang.php @@ -4,28 +4,85 @@ * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Tomáš Borland Valenta + * @author Pavel Kochman */ // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Přesun/přejmenování stránky'; -$lang['desc'] = 'Plugin pro přesun/přejmenování stránku'; - -//$lang['notexist'] = 'Toto téma ještě neexistuje'; -$lang['notwrite'] = 'Nemáte dostatečná oprávnění pro úpravu stránky'; -$lang['badns'] = 'Neplatný název jmenného prostoru'; -$lang['badname'] = 'Neplatný název stránky'; -$lang['nochange'] = 'Jméno stránky a jmenného prostoru se nezměnilo'; -$lang['existing1'] = 'Stránka %s již existuje v %s'; -$lang['root'] = '[Kořen]'; -$lang['current'] = '(Současný)'; -//$lang['norights'] = 'Nemáte právo editovat jednu nebo více odkazujících stránek'; -$lang['filelocked'] = 'Tento soubor je uzamčen - zkuste prosím znovu později'; -$lang['linkchange1'] = 'Odkazy na %s změněny na %s'; -$lang['newname'] = 'Nový název stránky :'; -$lang['targetns'] = 'Cílový jmenný prostor :'; -$lang['submit'] = 'Potvrdit'; +$lang['menu'] = 'Přesun/přejmenování stránky'; +$lang['inprogress'] = '(probíhá přesun)'; +$lang['treelink'] = 'Alternativou k tomuto jednoduchému formuláři můžete použít komplexní přeskupení vaší wiki pomocí stromového manažeru přesunu.'; + +// page errors +$lang['notexist'] = 'Stránka \'%s\' neexistuje.'; +$lang['norights'] = 'Nedostatečné oprávnění editovat \'%s\'.'; +$lang['filelocked'] = 'Stránka \'%s\' je uzamčna - zkuste prosím znovu později.'; +$lang['notchanged'] = 'Žádný cíl pro stránku \'%s\' (umístění nezměněno).'; +$lang['exists'] = 'Stránku \'%s\' nelze přesunout do \'%s\', cíl již existuje.'; +$lang['notargetperms'] = 'Nemáte oprávnění vytvořit stránku \'%s\'.'; + +// media errors +$lang['medianotexist'] = 'Médium \'%s\' neexistuje.'; +$lang['nomediarights'] = 'Nedostatečné oprávnění ke smazání \'%s\'.'; +$lang['medianotchanged'] = 'Žádný cíl pro médium \'%s\' (umístění nezměněno).'; +$lang['mediaexists'] = 'Médium \'%s\' nelze přesunout do \'%s\', cíl již existuje.'; +$lang['nomediatargetperms'] = 'Nemáte oprávnění vytvořit médium \'%s\'.'; + +// system errors +$lang['indexerror'] = 'Chyba při aktualizaci search index \'%s\'.'; +$lang['metamoveerror'] = 'Meta soubory stránky \'%s\' nemohou být přesunut.'; +$lang['atticmoveerror'] = 'Staré verze stránky \'%s\' nemohou být přesunuty. Prosím, přsuňte je ručně.'; +$lang['mediametamoveerror'] = 'Meta soubory média \'%s\' nemohou být přesunuty.'; +$lang['mediamoveerror'] = 'Přesunutí média \'%s\' selhalo.'; +$lang['mediaatticmoveerror'] = 'Staré verze média \'%s\' nemohou být přesunuty. Prosím, přsuňte je ručně.'; + +// changelog summaries +$lang['renamed'] = 'Stránka přejmenována z \'%s\' na \'%s\''; +$lang['moved'] = 'Stránka přesunuta z \'%s\' do \'%s\''; +$lang['move_rename'] = 'Stránka přesunuta a přejmenována z \'%s\' do \'%s\''; +$lang['delete'] = 'Smazáno pluginem move'; +$lang['linkchange'] = 'Odkaz upraven z důvodu přesunutí'; + +// progress view +$lang['intro'] = 'Přesun dosud nebyl zahájen!'; +$lang['preview'] = 'Náhled změn, které budou provedeny.'; +$lang['inexecution'] = 'Předchozí přesun nebyl dokončen - použijte tlačítko dole k pokračování či přerušení přesunu.'; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Pokračovat'; +$lang['btn_retry'] = 'Znovu'; +$lang['btn_skip'] = 'Přeskočit položku'; +$lang['btn_abort'] = 'Přerušit'; + +// Form labels +$lang['legend'] = 'Přesunout aktuální stránku nebo jmenný prostor'; +$lang['movepage'] = 'Přesunout stránku'; +$lang['movens'] = 'Přesunout aktuální jmenný prostor'; +$lang['dst'] = 'Nové jméno:'; +$lang['content_to_move'] = 'Obsah k přesunutí:'; +$lang['autoskip'] = 'Ignorovat chyby a přeskočit stránky a média, které nemohou být přesunuty'; +$lang['autorewrite'] = 'Přepsat odkazy po úspěšmén přesunu'; +$lang['move_pages'] = 'Stránky'; +$lang['move_media'] = 'Média'; +$lang['move_media_and_pages'] = 'Stránky a média'; +$lang['nodst'] = 'Žádné nové jméno'; +$lang['noaction'] = 'Nebyl definován přesun'; + +// Rename feature +$lang['renamepage'] = 'Přejmenovat stránku'; +$lang['cantrename'] = 'Stránka nemůže být právě přejmenována. Zkuste to později.'; +$lang['js']['rename'] = 'Přejmenovat'; +$lang['js']['cancel'] = 'Zrušit'; +$lang['js']['newname'] = 'Nový název stránky:'; +$lang['js']['inprogress'] = 'Přesouvám stránky a upravuji odkazy...'; +$lang['js']['complete'] = 'Přesun byl dokončen.'; + +// Tree Manager +$lang['root'] = '[Kořen]'; +$lang['noscript'] = 'Tato vlastost vyžaduje JavaScript'; +$lang['moveinprogress'] = 'Právě probíhá jiný přsun, proto nyní nemůžete použít tento nástroj.'; +$lang['js']['renameitem'] = 'Přejmenovat tuto položku'; +$lang['js']['duplicate'] = 'Lituji, ale \'%s\' již existuje ve jmenném prosoru.'; + + diff --git a/lang/cs/move.txt b/lang/cs/move.txt index 29d1c4d..c2a832b 100644 --- a/lang/cs/move.txt +++ b/lang/cs/move.txt @@ -3,7 +3,7 @@ Pomocí tohoto pluginu lze přesunout nebo přejmenovat aktuální stránku. Platí však jistá omezení: * Musíte mít práva na danou stránku. - * The pages that are moved must not be locked for editing. + * Stránky které se přesouvají nesmí být zamčeny pro úpravu. * Pro přesun stránky potřebujete práva pro zápis v cílovém místě. * Nelze přesunout stránku někam, kde již existuje stránka stejného jména. diff --git a/lang/cs/progress.txt b/lang/cs/progress.txt new file mode 100644 index 0000000..209f27a --- /dev/null +++ b/lang/cs/progress.txt @@ -0,0 +1,3 @@ +====== Probíhá přesun... ====== + +Prosím nazavírejte tuto stránku, dokud přesun neskončí. \ No newline at end of file diff --git a/lang/cs/settings.php b/lang/cs/settings.php new file mode 100644 index 0000000..acd5926 --- /dev/null +++ b/lang/cs/settings.php @@ -0,0 +1,11 @@ + Date: Wed, 19 Aug 2015 21:59:33 +0200 Subject: [PATCH 214/338] Shows error message for duplicite filename. --- script/rename.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/rename.js b/script/rename.js index f5708eb..9fd4536 100644 --- a/script/rename.js +++ b/script/rename.js @@ -32,7 +32,7 @@ if(JSINFO.move_renameokay) // redirect or display error function (result) { if(result.error){ - $dialog.html(result.error); + $dialog.html(result.error.msg); } else { window.location.href = result.redirect_url; } From f89655c41610d031ee6cf526cfc443725526c311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 25 Aug 2015 10:05:00 +0300 Subject: [PATCH 215/338] exclude github related files from export --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6b97151 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/.gitignore export-ignore +/.gitattributes export-ignore +/.travis.yml export-ignore From 228db22d1a62e523ebc56f933665d43d232672d9 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 17 Oct 2015 14:05:15 +0200 Subject: [PATCH 216/338] Add test case for cache handling --- _test/plugin_move_cache_handling.test.php | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 _test/plugin_move_cache_handling.test.php diff --git a/_test/plugin_move_cache_handling.test.php b/_test/plugin_move_cache_handling.test.php new file mode 100644 index 0000000..a982c89 --- /dev/null +++ b/_test/plugin_move_cache_handling.test.php @@ -0,0 +1,47 @@ +pluginsEnabled[] = 'move'; + parent::setUp(); + } + + /** + * @group slow + */ + function test_cache_handling() { + $testid = 'wiki:bar:test'; + saveWikiText($testid, + '[[wiki:foo:]]', 'Test setup'); + idx_addPage($testid); + saveWikiText('wiki:foo:start', + 'bar', 'Test setup'); + idx_addPage('wiki:foo:start'); + + sleep(1); // wait in order to make sure that conditions with < give the right result. + p_wiki_xhtml($testid); // populate cache + + $cache = new cache_renderer($testid, wikiFN($testid), 'xhtml'); + $this->assertTrue($cache->useCache()); + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + $this->assertTrue($move->movePage('wiki:foo:start', 'wiki:foo2:start')); + + $cache = new cache_renderer($testid, wikiFN($testid), 'xhtml'); + $this->assertFalse($cache->useCache()); + + } + +} From bce6806cbb4a92cb8764936c5c36437e2ff7d564 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 17 Oct 2015 14:05:29 +0200 Subject: [PATCH 217/338] Fix cache handling, the cache was not expired on moves. --- action/rewrite.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/action/rewrite.php b/action/rewrite.php index 3d65aa8..1097950 100644 --- a/action/rewrite.php +++ b/action/rewrite.php @@ -95,13 +95,17 @@ function handle_cache(Doku_Event $event, $param) { } } if($id) { - $meta = p_get_metadata($id, 'plugin_move', METADATA_DONT_RENDER); - if($meta && (isset($meta['moves']) || isset($meta['media_moves']))) { - $file = wikiFN($id, '', false); - if(is_writable($file)) - $cache->depends['purge'] = true; - else // FIXME: print error here or fail silently? - msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); + /** @var helper_plugin_move_rewrite $helper */ + $helper = $this->loadHelper('move_rewrite'); + if(!is_null($helper)) { + $meta = $helper->getMoveMeta($id); + if($meta && ($meta['pages'] || $meta['media'])) { + $file = wikiFN($id, '', false); + if(is_writable($file)) + $cache->depends['purge'] = true; + else // FIXME: print error here or fail silently? + msg('Error: Page ' . hsc($id) . ' needs to be rewritten because of page renames but is not writable.', -1); + } } } } From a904da265ef570d29bf4f16ca12b1d731043d19a Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 17 Oct 2015 14:38:10 +0200 Subject: [PATCH 218/338] Add missing isset() before variable access --- helper/handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/handler.php b/helper/handler.php index c63cd3f..2df752b 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -94,7 +94,7 @@ public function resolveMoves($old, $type) { } } } - if ($tempColon) { + if (isset($tempColon) && $tempColon) { $old = substr($old,1); } return $old; // this is now new From 54f18c5a522f1b6c4b06bc3d0e2b7e8fd966c9f1 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 17 Oct 2015 14:38:52 +0200 Subject: [PATCH 219/338] Fix #54 adding ':' to absolute ids in the root namespace --- _test/pagemove.test.php | 16 ++++++++++++++++ helper/handler.php | 1 + 2 files changed, 17 insertions(+) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 62a663b..3ba2c25 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -596,5 +596,21 @@ function test_move_ns_in_same_ns() { } + function test_move_start_ns_into_ns_page() { + saveWikiText('bugs:start', 'Bug page', 'created'); + idx_addPage('bugs:start'); + saveWikiText('foo:bugs:test', '[[bugs:start]]', 'created'); + idx_addPage('foo:bugs:test'); + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + + $this->assertTrue($move->movePage('bugs:start', 'bugs')); + $this->assertEquals('[[:bugs]]', rawWiki('foo:bugs:test')); + + $this->assertTrue($move->movePage('bugs', 'start')); + $this->assertEquals('[[:start]]', rawWiki('foo:bugs:test')); + } + } diff --git a/helper/handler.php b/helper/handler.php index 2df752b..b469635 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -160,6 +160,7 @@ public function relativeLink($relold, $new, $type) { // if it wasn't relative then, leave it absolute now, too if(!$wasrel) { + if($this->ns && !getNS($new)) $new = ':' . $new; $new = $this->_nsStartCheck($relold, $new, $type); return $new; } From 50e7b1c52a00d2f752f2902ffdfa329a062f2d73 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 17 Oct 2015 14:44:31 +0200 Subject: [PATCH 220/338] New version 2015-10-17 released. Bug fixes and translation updates. --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index 8108451..826ad6d 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2015-05-16 +date 2015-10-17 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 1388aff976eeba1c4c6f409716939b3b2740a03a Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 18 Oct 2015 15:42:11 +0200 Subject: [PATCH 221/338] Renamed test file --- ...lugin_move_cache_handling.test.php => cache_handling.test.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename _test/{plugin_move_cache_handling.test.php => cache_handling.test.php} (100%) diff --git a/_test/plugin_move_cache_handling.test.php b/_test/cache_handling.test.php similarity index 100% rename from _test/plugin_move_cache_handling.test.php rename to _test/cache_handling.test.php From 52037678f9a9fad352df94f10d5edaaa5c8540e7 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 18 Oct 2015 16:24:28 +0200 Subject: [PATCH 222/338] Clean media ids, too. Might help with #52 In DokuWiki, media ids are cleaned, too (e.g. in mediaFN()). Therefore the move plugin now also rewrites ids like "foo bar.jpg". This also removes leading colons in new absolute media ids. --- _test/mediamove.test.php | 38 +++++++++++++++++++++++++++++++++-- _test/namespace_move.test.php | 2 +- _test/pagemove.test.php | 12 +++++++++++ helper/handler.php | 16 ++------------- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index 3bbcea6..ec734bb 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -67,7 +67,8 @@ public function test_moveSingleMedia() { public function test_moveSingleMedia_colonstart() { global $AUTH_ACL; $AUTH_ACL[] = "wiki:*\t@ALL\t16"; - $AUTH_ACL[] = "foobar:*\t@ALL\t8"; + $AUTH_ACL[] = "foobar:*\t@ALL\t16"; + $AUTH_ACL[] = "*\t@ALL\t8"; $filepath = DOKU_TMP_DATA.'media/wiki/testimage.png'; io_makeFileDir($filepath); @@ -85,6 +86,39 @@ public function test_moveSingleMedia_colonstart() { $this->assertTrue(@file_exists(mediaFn('foobar:logo_2.png'))); - $this->assertEquals('{{:foobar:logo_2.png?200}}', rawWiki('wiki:movetest')); + $this->assertEquals('{{foobar:logo_2.png?200}}', rawWiki('wiki:movetest')); + + $this->assertTrue($move->moveMedia($dst, 'logo_2.png')); + + $this->assertTrue(@file_exists(mediaFn('logo_2.png'))); + + $this->assertEquals('{{:logo_2.png?200}}', rawWiki('wiki:movetest')); + } + + /** + * @group slow + */ + public function test_moveSingleMedia_space() { + global $AUTH_ACL; + $AUTH_ACL[] = "wiki:*\t@ALL\t16"; + $AUTH_ACL[] = "foobar:*\t@ALL\t8"; + + $filepath = DOKU_TMP_DATA.'media/wiki/foo/test_image.png'; + io_makeFileDir($filepath); + io_saveFile($filepath,''); + + saveWikiText('wiki:movetest', '{{:wiki:foo:test image.png?200|test image}}', 'Test initialized'); + idx_addPage('wiki:movetest'); + + $src = 'wiki:foo:test_image.png'; + $dst = 'wiki:foobar:test_image.png'; + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + $this->assertTrue($move->moveMedia($src, $dst)); + + $this->assertTrue(@file_exists(mediaFn('wiki:foobar:test_image.png'))); + + $this->assertEquals('{{wiki:foobar:test_image.png?200|test image}}', rawWiki('wiki:movetest')); } } diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 2f80110..70f9a22 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -340,7 +340,7 @@ public function test_move_small_namespace_media_affected() { $this->assertFileExists(mediaFN('newns:oldnsimage.png')); $this->assertFileNotExists(mediaFN('oldns:oldnsimage.png')); - $this->assertSame('{{:newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage.png}}',rawWiki('oldns:start')); + $this->assertSame('{{newns:oldnsimage.png}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage.png}}',rawWiki('oldns:start')); } /** diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 3ba2c25..9ad5816 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -612,5 +612,17 @@ function test_move_start_ns_into_ns_page() { $this->assertEquals('[[:start]]', rawWiki('foo:bugs:test')); } + function test_clean_id_move() { + saveWikiText('some_space:start', 'Space page', 'created'); + idx_addPage('some_space:start'); + saveWikiText('foo:bar:test', '[[some space:start]]', 'created'); + idx_addPage('foo:bar:test'); + + /** @var helper_plugin_move_op $move */ + $move = plugin_load('helper', 'move_op'); + + $this->assertTrue($move->movePage('some_space:start', 'spaceless:start')); + $this->assertEquals('[[spaceless:start]]', rawWiki('foo:bar:test')); + } } diff --git a/helper/handler.php b/helper/handler.php index b469635..f9daf67 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -71,32 +71,20 @@ public function resolveMoves($old, $type) { // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been // deleted already if(substr($old, -1) === ':') $old .= $conf['start']; - $old = cleanID($old); $moves = $this->page_moves; } else { $moves = $this->media_moves; } - if (substr($old,0,1) !== $delimiter) { - $tempColon = true; - $old = $delimiter . $old; - } + $old = cleanID($old); foreach($moves as $move) { - if (substr($move[0],0,1) !== $delimiter) { - $move[0] = $delimiter . $move[0]; - } if($move[0] == $old) { $old = $move[1]; - if (substr($old,0,1) !== $delimiter) { - $old = $delimiter . $old; - } } } - if (isset($tempColon) && $tempColon) { - $old = substr($old,1); - } + return $old; // this is now new } From 98b910b834ee126b128f3416dcf85ef8667ffc3a Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 18 Oct 2015 16:27:22 +0200 Subject: [PATCH 223/338] Minor documentation fix --- helper/handler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper/handler.php b/helper/handler.php index f9daf67..d45774a 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -91,8 +91,8 @@ public function resolveMoves($old, $type) { /** * if the old link ended with a colon and the new one is a start page, adjust * - * @param $relold the old, possibly relative ID - * @param $new the new, full qualified ID + * @param $relold string the old, possibly relative ID + * @param $new string the new, full qualified ID * @param $type 'media' or 'page' * @return string */ From 5ade0f87ddd3d56202fdd2143d9077a6b7f35fcf Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 18 Oct 2015 16:49:09 +0200 Subject: [PATCH 224/338] Remove redundant code (the same is already in resolve_id) --- helper/handler.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/helper/handler.php b/helper/handler.php index d45774a..37b4476 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -57,13 +57,6 @@ public function resolveMoves($old, $type) { if($type != 'media' && $type != 'page') throw new Exception('Not a valid type'); - if($conf['useslash']) { - $old = str_replace('/', ':', $old); - $delimiter = '/'; - } else { - $delimiter = ':'; - } - $old = resolve_id($this->origNS, $old, false); if($type == 'page') { From 46c2a448136621d16ab5a7e5bc647ded9f2121ea Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 18 Oct 2015 17:05:52 +0200 Subject: [PATCH 225/338] Restore PHP 5.2 compatibility, fixes #35 We still support DokuWiki version 2015-08-10 "Hrun" which only requires PHP 5.2, so supporting PHP 5.2 makes sense. --- helper/rewrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index 8ec970c..29eac27 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -11,7 +11,7 @@ if(!defined('DOKU_INC')) die(); // load required handler class -require_once(__DIR__ . '/handler.php'); +require_once(dirname(__FILE__) . '/handler.php'); /** * Class helper_plugin_move_rewrite From 0bdc6d1efc2c9e4a0a912fcfe40a9a66b555c7fd Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 18 Oct 2015 17:28:47 +0200 Subject: [PATCH 226/338] New version 2015-10-18 released (bug fixes for media moves and PHP 5.2) --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index 826ad6d..c72b682 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2015-10-17 +date 2015-10-18 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 12ea564ff1049f50b4edc19904bed70a9a4f13a3 Mon Sep 17 00:00:00 2001 From: EDB Date: Thu, 22 Oct 2015 10:53:06 +0630 Subject: [PATCH 227/338] Create lang.php --- lang/zh-tw/lang.php | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lang/zh-tw/lang.php diff --git a/lang/zh-tw/lang.php b/lang/zh-tw/lang.php new file mode 100644 index 0000000..d590f81 --- /dev/null +++ b/lang/zh-tw/lang.php @@ -0,0 +1,58 @@ + + */ +$lang['menu'] = '頁面移動/重新命名……'; +$lang['inprogress'] = '(待移動)'; +$lang['treelink'] = '您還可以通過樹形移動.來為您的wiki條目結構做複雜調整'; +$lang['notexist'] = '頁面 %s 不存在'; +$lang['norights'] = '您沒有權限編輯%s.'; +$lang['filelocked'] = '此文件被鎖定 - 請稍後重試'; +$lang['notchanged'] = '未為頁面%s指定新地址(位置未變)'; +$lang['exists'] = '頁面%s無法被移動至%s ,該目標已存在 '; +$lang['notargetperms'] = '您沒有權限建立頁面%s.'; +$lang['medianotexist'] = '媒體文件%s不存在'; +$lang['nomediarights'] = '您沒有權限刪除%s.'; +$lang['medianotchanged'] = '未為頁面%s指定新地址(位置未變)'; +$lang['mediaexists'] = '媒體文件%s無法被移動至%s,目標已存在。'; +$lang['nomediatargetperms'] = '您沒有權限建立媒體文件%s。'; +$lang['renamed'] = '頁面名由%s改為%s'; +$lang['moved'] = '頁面%s被移動至%s'; +$lang['move_rename'] = '頁面%s被移動並更名為%s'; +$lang['delete'] = '被Move插件刪除'; +$lang['linkchange'] = '鏈結因頁面移動而自動修正'; +$lang['intro'] = '移動操作尚未開始!'; +$lang['preview'] = '預覽即將執行的變更'; +$lang['inexecution'] = '上一個移動尚未完成;請點擊下方按鈕繼續或放棄執行'; +$lang['btn_start'] = '開始'; +$lang['btn_continue'] = '繼續'; +$lang['btn_retry'] = '重試'; +$lang['btn_skip'] = '跳過'; +$lang['btn_abort'] = '放棄'; +$lang['legend'] = '移動當前頁面或目錄'; +$lang['movepage'] = '移動頁面'; +$lang['movens'] = '移動目錄'; +$lang['dst'] = '新名字:'; +$lang['content_to_move'] = '移動內容:'; +$lang['autoskip'] = '忽略錯誤並跳過無法被移動的頁面或文件'; +$lang['autorewrite'] = '待移動完成後立即重寫鏈接'; +$lang['move_pages'] = '頁面'; +$lang['move_media'] = '媒體文件'; +$lang['move_media_and_pages'] = '頁面與媒體文件'; +$lang['nodst'] = '未指定新名字'; +$lang['noaction'] = '未定義任何移動'; +$lang['renamepage'] = '重新命名頁面'; +$lang['cantrename'] = '頁面現在無法重新命名,請稍後再試。'; +$lang['js']['rename'] = '重新命名'; +$lang['js']['cancel'] = '取消'; +$lang['js']['newname'] = '新名字:'; +$lang['js']['inprogress'] = '重新命名頁面並修正有關鏈結:'; +$lang['js']['complete'] = '移動操作完畢。'; +$lang['js']['renameitem'] = '重新命名該項'; +$lang['js']['duplicate'] = '抱歉,"%s"在該目錄已存在'; +$lang['root'] = '[根目錄]'; +$lang['noscript'] = '此功能需要JavaScript'; +$lang['moveinprogress'] = '另一個移動操作正在進行,您現在無法使用該工具'; From 4c94cb94be065b8d6d0102fb26b519feb72632ea Mon Sep 17 00:00:00 2001 From: EDB Date: Thu, 22 Oct 2015 10:55:13 +0630 Subject: [PATCH 228/338] Create move.txt --- lang/zh-tw/move.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 lang/zh-tw/move.txt diff --git a/lang/zh-tw/move.txt b/lang/zh-tw/move.txt new file mode 100644 index 0000000..b27a498 --- /dev/null +++ b/lang/zh-tw/move.txt @@ -0,0 +1,11 @@ +====== Move ====== +此插件允許您移動並/或重新命名目前頁面,或移動並/或重新命名目前目錄。但是必須符合以下條件: + + *您必須擁有編輯當前頁面/該目錄中所有頁面的權限; + *頁面未因編輯而處於鎖定狀態; + *為了移動頁面,您必須擁有目的地目錄的寫入權限; + *您無法將頁面移動至另一個已有同名頁面的目錄中。 + +所有來自和指向被移動頁面的鏈接,都將被自動更新以反映新地址和/或新名字。 + +正體中文化: Aaron Wang From c24dd4245210c22505cc2acebf99060f47d88760 Mon Sep 17 00:00:00 2001 From: EDB Date: Thu, 22 Oct 2015 10:56:15 +0630 Subject: [PATCH 229/338] Create progress.txt --- lang/zh-tw/progress.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lang/zh-tw/progress.txt diff --git a/lang/zh-tw/progress.txt b/lang/zh-tw/progress.txt new file mode 100644 index 0000000..5ae1ebc --- /dev/null +++ b/lang/zh-tw/progress.txt @@ -0,0 +1,3 @@ +====== 正在移動... ====== + +移動正在進行中,請勿關閉本頁面。 From e48711baf0eb37c91ed7390810ff6db8f21762e0 Mon Sep 17 00:00:00 2001 From: EDB Date: Thu, 22 Oct 2015 10:57:28 +0630 Subject: [PATCH 230/338] Create settings.php --- lang/zh-tw/settings.php | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 lang/zh-tw/settings.php diff --git a/lang/zh-tw/settings.php b/lang/zh-tw/settings.php new file mode 100644 index 0000000..bdfc838 --- /dev/null +++ b/lang/zh-tw/settings.php @@ -0,0 +1,11 @@ + */ + +$lang['allowrename'] = '允許這些用戶/用戶群組重命名頁面(用逗號分隔)'; +$lang['minor'] = '將鏈接修正標記為『細微變動』,這樣就不會被列入RSS訂閱或訂閱郵件中。'; +$lang['autoskip'] = '目錄移動時,啟用預設自動跳過錯誤'; +$lang['autorewrite'] = '目錄移動時,啟用預設自動修正鏈接'; From 5fc4f957b8d30f76664018282d4960dceb1b843c Mon Sep 17 00:00:00 2001 From: EDB Date: Thu, 22 Oct 2015 10:59:44 +0630 Subject: [PATCH 231/338] Create tree.txt --- lang/zh-tw/tree.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lang/zh-tw/tree.txt diff --git a/lang/zh-tw/tree.txt b/lang/zh-tw/tree.txt new file mode 100644 index 0000000..c2f634e --- /dev/null +++ b/lang/zh-tw/tree.txt @@ -0,0 +1,3 @@ +====== 移動主控台 ===== + +本頁面允許您透過鼠標拖放,重新安排您wiki的目錄、頁面與媒體文件 From c47c1ae2896c352d2e108cea9580328617309dd9 Mon Sep 17 00:00:00 2001 From: Chang Zhao Date: Thu, 29 Oct 2015 17:56:07 +0300 Subject: [PATCH 232/338] Update lang.php --- lang/ru/lang.php | 94 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 19 deletions(-) diff --git a/lang/ru/lang.php b/lang/ru/lang.php index 47c8869..f94a7d5 100644 --- a/lang/ru/lang.php +++ b/lang/ru/lang.php @@ -4,28 +4,84 @@ * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author S'Adm*n + * @author Chang Zhao */ +$lang['menu'] = 'Перемещение/переименование страниц и папок'; +$lang['desc'] = 'Плагин для перемещения (переименования) страниц'; +$lang['inprogress'] = '(...идёт перемещение...)'; +$lang['treelink'] = 'Кроме этой простой формы, для сложной реструктуризации страниц вы можете использовать древовидную настройку.'; + // settings must be present and set appropriately for the language $lang['encoding'] = 'utf-8'; $lang['direction'] = 'ltr'; -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Перемещение/переименование страницы...'; -$lang['desc'] = 'Page Move/Rename Plugin'; - -//$lang['notexist'] = 'Эта страница еще не существует'; -$lang['notwrite'] = 'Ваши права доступа не позволяют Вам изменять эту страницу'; -$lang['badns'] = 'В названии пространства имён присутствуют недопустимые символы.'; -$lang['badname'] = 'Недопустимые символы в названии страниц.'; -$lang['nochange'] = 'Параметры страницы не изменены.'; -$lang['existing1'] = 'Страница с именем %s уже существует в %s'; -$lang['root'] = '[Корневой каталог]'; -$lang['current'] = '(Текущий)'; -//$lang['norights'] = 'У Вас нет прав на редактирование одной из страниц, ссылающихся на данный документ.'; -$lang['filelocked'] = 'Изменение данного файла запрещено - попробуйте позже.'; -$lang['linkchange1'] = 'Ссылки на страницу %s изменены на %s'; -$lang['newname'] = 'Новое название документа :'; -$lang['targetns'] = 'Переместить в пространство :'; -$lang['submit'] = 'Применить'; +// page errors +$lang['notexist'] = 'Страница %s не существует.'; +$lang['norights'] = 'У Вас нет прав редактировать %s.'; +$lang['filelocked'] = 'Изменение страницы %s сейчас заблокировано - попробуйте позже.'; +$lang['notchanged'] = 'Не задано нового названия %s (адрес не изменён).'; +$lang['exists'] = 'Невозможно переместить %s - уже существует страница %s.'; +$lang['notargetperms'] = 'У вас недостаточно прав для создания страницы %s.'; + +// media errors +$lang['medianotexist'] = 'Медиафайла %s не существует'; +$lang['nomediarights'] = 'У вас недостаточно прав для удаления %s.'; +$lang['medianotchanged'] = 'Не задано нового названия %s (адрес не изменён).'; +$lang['mediaexists'] = 'Невозможно переместить %s - уже существует страница %s.'; +$lang['nomediatargetperms'] = 'У вас недостаточно прав для создания медиафайла %s.'; + +// system errors +$lang['indexerror'] = 'Ошибка при обновлении индексирования поиска %s'; +$lang['metamoveerror'] = 'Не удалось переместить медиафайлы страницы %s'; +$lang['atticmoveerror'] = 'Не удалось переместить архивы (attic) страницы %s. Переместите их вручную.'; +$lang['mediametamoveerror'] = 'Не удалось переместить мета-файлы страницы %s.'; +$lang['mediamoveerror'] = 'Не удалось переместить медиафайл %s.'; +$lang['mediaatticmoveerror'] = 'Не удалось переместить архивы (attic) медиафайла %s. Переместите их вручную.'; + +// changelog summaries +$lang['renamed'] = 'Имя страницы %s изменено на %s'; +$lang['moved'] = 'Страница перемещена из %s в %s'; +$lang['move_rename'] = 'Страница перемещена и переименована из %s в %s'; +$lang['delete'] = 'Удалено плагином Move (перемещения страниц)'; +$lang['linkchange'] = 'Операцией перемещения обновлены ссылки'; + +// progress view +$lang['intro'] = 'Операция перемещения ещё не начата!'; +$lang['preview'] = 'Просмотреть ожидаемые изменения.'; +$lang['inexecution'] = 'Предыдущее перемещение не завершилось - кнопками внизу выберите завершение или отмену.'; +$lang['btn_start'] = 'Начать'; +$lang['btn_continue'] = 'Продолжить'; +$lang['btn_retry'] = 'Попытаться ещё'; +$lang['btn_skip'] = 'Пропустить'; +$lang['btn_abort'] = 'Отменить'; + +// Form labels +$lang['legend'] = 'Переместить текущую страницу или папку'; +$lang['movepage'] = 'Переместить страницу'; +$lang['movens'] = 'Переместить папку'; +$lang['dst'] = 'Новое название:'; +$lang['content_to_move'] = 'Переместить содержимое:'; +$lang['autoskip'] = 'Игнорировать ошибки; пропускать страницы и файлы, которые не удаётся переместить.'; +$lang['autorewrite'] = 'По окончании перемещения обновить ссылки.'; +$lang['move_pages'] = 'Страницы'; +$lang['move_media'] = 'Медиафайлы'; +$lang['move_media_and_pages'] = 'Страницы и медиафайлы'; +$lang['nodst'] = 'Не задано новое имя'; +$lang['noaction'] = 'Не было задано перемещений'; + +// Rename feature +$lang['renamepage'] = 'Переименовать страницу'; +$lang['cantrename'] = 'Сейчас не удаётся переименовать страницу - попробуйте позже.'; +$lang['js']['rename'] = 'Переименовать'; +$lang['js']['cancel'] = 'Отменить'; +$lang['js']['newname'] = 'Новое название:'; +$lang['js']['inprogress'] = '...переименование страницы и обновление ссылок...'; +$lang['js']['complete'] = 'Перемещение завершено.'; + +// Tree Manager +$lang['root'] = '[Корневой каталог]'; +$lang['noscript'] = 'Для этого требуется включить JavaScript'; +$lang['moveinprogress'] = 'Сейчас происходит другая операция перемещения; пока она не закончена, данный инструмент не работает.'; +$lang['js']['renameitem'] = 'Переименовать'; +$lang['js']['duplicate'] = 'Не получается: "%s" уже существует в данной папке.'; From 75825cf4aa1debdcc0e9a35393cae204b314bfb1 Mon Sep 17 00:00:00 2001 From: Chang Zhao Date: Thu, 29 Oct 2015 17:58:48 +0300 Subject: [PATCH 233/338] Update move.txt --- lang/ru/move.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lang/ru/move.txt b/lang/ru/move.txt index 1417219..7945a27 100644 --- a/lang/ru/move.txt +++ b/lang/ru/move.txt @@ -1,10 +1,10 @@ -====== Перемещение страницы ====== +====== Перемещение ====== -Этот плагин позволяет перемещать и/или переименовывать текущую страницу со следующими ограничениями: +Этот плагин позволяет перемещать или переименовывать текущую страницу или текущую папку со следующими ограничениями: - * You must have edit permission for the current page/all pages in the current namespace. - * The pages that are moved must not be locked for editing. - * Вы должны обладать соответствующими правами доступа в директории, куда Вы планируете переместить файл. - * Вы не можете переместить страницу в пространство имён, уже содержащее страницу с таким же названием. + * У вас должны быть права для редактирования данной страницы или в данной папке для всех страниц. + * Перемещаемые страницы не должны быть заблокированы (напр., когда их редактируют другие пользователи). + * Для перемещения страницы в другую папку вам нужны права создания в этой папке. + * Вы не можете переместить страницу в папку, уже содержащую страницу с таким же названием. -Все ссылки, ведущие с этой страницы и на неё, будут обновлены в соответствии с внесёнными изменениями. +Все ссылки, ведущие с перемещаемых (переименуемых) страниц или на них - будут обновлены в соответствии со внесёнными изменениями. From 1a8bbcf59a99f19ec91d424f91778be514d47ff7 Mon Sep 17 00:00:00 2001 From: Chang Zhao Date: Thu, 29 Oct 2015 18:00:06 +0300 Subject: [PATCH 234/338] Create progress.txt --- lang/ru/progress.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lang/ru/progress.txt diff --git a/lang/ru/progress.txt b/lang/ru/progress.txt new file mode 100644 index 0000000..218b387 --- /dev/null +++ b/lang/ru/progress.txt @@ -0,0 +1,3 @@ +====== Идёт перемещение... ====== + +Пожалуйста, не закрывайте эту страницу, пока идёт перемещение. From cadbe91462963f302c19f2d9ca0a46d637e3dfdb Mon Sep 17 00:00:00 2001 From: Chang Zhao Date: Thu, 29 Oct 2015 18:02:26 +0300 Subject: [PATCH 235/338] Create settings.php --- lang/ru/settings.php | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 lang/ru/settings.php diff --git a/lang/ru/settings.php b/lang/ru/settings.php new file mode 100644 index 0000000..ec57fb2 --- /dev/null +++ b/lang/ru/settings.php @@ -0,0 +1,6 @@ + Date: Thu, 29 Oct 2015 18:02:53 +0300 Subject: [PATCH 236/338] Create tree.txt --- lang/ru/tree.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lang/ru/tree.txt diff --git a/lang/ru/tree.txt b/lang/ru/tree.txt new file mode 100644 index 0000000..e652528 --- /dev/null +++ b/lang/ru/tree.txt @@ -0,0 +1,3 @@ +====== Древовидный инструмент перемещения ===== + +Здесь вы можете перемещать папки, страницы и медиафайлы вашей ДокуВики, просто передвигая их на новое место. From acaf0fe35905671beca92fd9f6f6df40b264b058 Mon Sep 17 00:00:00 2001 From: Christopher Schive Date: Sat, 28 Nov 2015 23:55:05 +0100 Subject: [PATCH 237/338] translation update --- lang/no/lang.php | 31 +++++++++++++++++++++++++++++++ lang/no/tree.txt | 3 +++ 2 files changed, 34 insertions(+) create mode 100644 lang/no/tree.txt diff --git a/lang/no/lang.php b/lang/no/lang.php index 6a56c2f..6c87531 100644 --- a/lang/no/lang.php +++ b/lang/no/lang.php @@ -5,6 +5,7 @@ * * @author Daniel * @author Daniel Raknes + * @author Christopher Schive */ $lang['menu'] = 'Flytt sider og navnerom'; $lang['inprogress'] = '(flytting avventer)'; @@ -17,14 +18,44 @@ $lang['notargetperms'] = 'Du har ikke rettigheter til å lage siden %s.'; $lang['medianotexist'] = 'Media-filen %s eksisterer ikke'; $lang['nomediarights'] = 'Du har ikke rettigheter til å slette %s.'; +$lang['medianotchanged'] = 'Ingen ny plassering er gitt for siden %s (uendret plassering).'; +$lang['mediaexists'] = 'Media %s kan ikke flyttes til %s da den allerede eksisterer.'; +$lang['nomediatargetperms'] = 'Du har ikke tillatelse til å opprette mediafilen %s.'; +$lang['indexerror'] = 'Feil ved oppdatering av søkeindeks %s'; $lang['metamoveerror'] = 'Metafilene for siden %s kunne ikke flyttes.'; +$lang['atticmoveerror'] = 'Revisjonsfiler til siden %s kunne ikke flyttes. Vennligst flytt dem manuelt.'; +$lang['mediametamoveerror'] = 'Metafiler for mediafilen %s kunne ikke flyttes'; $lang['mediamoveerror'] = 'Flytting av mediafilen %s feilet'; +$lang['mediaatticmoveerror'] = 'Revisjonsfiler til mediafilen %s kunne ikke flyttes. Vennligst flytt dem manuelt.'; +$lang['renamed'] = 'Sidenavn endret fra %s til %s'; $lang['moved'] = 'Siden ble flyttet fra %s til %s'; +$lang['move_rename'] = 'Side flyttet og endret navn fra %s til %s'; $lang['delete'] = 'Slettet av move plugin'; +$lang['linkchange'] = 'Lenke endret på grunn av flyttingen'; +$lang['intro'] = 'Flyttingen har ikke startet ennå!'; +$lang['preview'] = 'Forhåndsvis endringer som skal utføres.'; +$lang['inexecution'] = 'En tidligere flytting var ikke avsluttet - bruk knappene under for å fortsette eller avbryt flyttingen.'; $lang['btn_start'] = 'Start'; $lang['btn_continue'] = 'Fortsett'; $lang['btn_retry'] = 'Prøv på nytt'; $lang['btn_skip'] = 'Hopp over'; $lang['btn_abort'] = 'Avbryt'; +$lang['legend'] = 'Flytt gjeldende side eller navnerom'; $lang['movepage'] = 'Flytt side'; $lang['movens'] = 'Flytt navnerom'; +$lang['dst'] = 'Nytt navn:'; +$lang['content_to_move'] = 'Innhold som skal flyttes:'; +$lang['autoskip'] = 'Ignorer feil og utelat sider eller filer som ikke kan flyttes'; +$lang['autorewrite'] = 'Oppdater lenker etter at flyttingen er avsluttet'; +$lang['move_pages'] = 'Sider'; +$lang['move_media'] = 'Mediafiler'; +$lang['move_media_and_pages'] = 'Sider og mediafiler'; +$lang['nodst'] = 'Intet nytt navn er gitt'; +$lang['noaction'] = 'Det var ikke angitt noen flyttinger'; +$lang['renamepage'] = 'Gi side nytt navn'; +$lang['cantrename'] = 'Siden kan ikke endre navn akkurat nå. Prøv igjen senere.'; +$lang['js']['rename'] = 'Gi nytt navn'; +$lang['js']['cancel'] = 'Avbryt'; +$lang['js']['newname'] = 'Nytt navn:'; +$lang['js']['inprogress'] = 'endrer navn på side og justerer lenker...'; +$lang['js']['complete'] = 'Flytting avsluttet'; diff --git a/lang/no/tree.txt b/lang/no/tree.txt new file mode 100644 index 0000000..f8eb6c0 --- /dev/null +++ b/lang/no/tree.txt @@ -0,0 +1,3 @@ +====== Move Manager ===== + +Denne dialogen tillater deg å flytte din wikis navnerom, sider og mediafiler via "dra og slipp". \ No newline at end of file From bbd8e8f6cd51a6ad0fd3b673f90d9761e6cea8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Nogueira?= Date: Wed, 23 Dec 2015 20:30:15 +0100 Subject: [PATCH 238/338] translation update --- lang/pt-br/lang.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 lang/pt-br/lang.php diff --git a/lang/pt-br/lang.php b/lang/pt-br/lang.php new file mode 100644 index 0000000..5bb84e9 --- /dev/null +++ b/lang/pt-br/lang.php @@ -0,0 +1,12 @@ + + */ +$lang['notexist'] = 'A página %s não existe'; +$lang['norights'] = 'Você tem permissões insuficientes para editar %s'; +$lang['medianotexist'] = 'O arquivo de mídia %s não existe'; +$lang['btn_start'] = 'Iniciar'; +$lang['btn_continue'] = 'Continuar'; From dec4666137c7ed29e83cf8ae0511458c8de12694 Mon Sep 17 00:00:00 2001 From: Daniel Raknes Date: Wed, 20 Jan 2016 12:10:16 +0100 Subject: [PATCH 239/338] translation update --- lang/no/lang.php | 8 +++++++- lang/no/move.txt | 7 +++++++ lang/no/progress.txt | 3 +++ lang/no/settings.php | 11 +++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 lang/no/move.txt create mode 100644 lang/no/progress.txt create mode 100644 lang/no/settings.php diff --git a/lang/no/lang.php b/lang/no/lang.php index 6c87531..ebc177c 100644 --- a/lang/no/lang.php +++ b/lang/no/lang.php @@ -6,6 +6,7 @@ * @author Daniel * @author Daniel Raknes * @author Christopher Schive + * @author Daniel Raknes */ $lang['menu'] = 'Flytt sider og navnerom'; $lang['inprogress'] = '(flytting avventer)'; @@ -25,7 +26,7 @@ $lang['metamoveerror'] = 'Metafilene for siden %s kunne ikke flyttes.'; $lang['atticmoveerror'] = 'Revisjonsfiler til siden %s kunne ikke flyttes. Vennligst flytt dem manuelt.'; $lang['mediametamoveerror'] = 'Metafiler for mediafilen %s kunne ikke flyttes'; -$lang['mediamoveerror'] = 'Flytting av mediafilen %s feilet'; +$lang['mediamoveerror'] = 'Flytting av mediafilAktive automatisk link en %s feilet'; $lang['mediaatticmoveerror'] = 'Revisjonsfiler til mediafilen %s kunne ikke flyttes. Vennligst flytt dem manuelt.'; $lang['renamed'] = 'Sidenavn endret fra %s til %s'; $lang['moved'] = 'Siden ble flyttet fra %s til %s'; @@ -59,3 +60,8 @@ $lang['js']['newname'] = 'Nytt navn:'; $lang['js']['inprogress'] = 'endrer navn på side og justerer lenker...'; $lang['js']['complete'] = 'Flytting avsluttet'; +$lang['js']['renameitem'] = 'Endre navn '; +$lang['js']['duplicate'] = 'Beklager, "%s" finnes allerede i dette navnerommet.'; +$lang['root'] = '[Rot navnerom]'; +$lang['noscript'] = 'Denne funksjonen krever Javascript'; +$lang['moveinprogress'] = 'En annen flyttingsjobb pågår for øyeblikket så denne funksjonen kan ikke brukes akkurat nå. '; diff --git a/lang/no/move.txt b/lang/no/move.txt new file mode 100644 index 0000000..5448485 --- /dev/null +++ b/lang/no/move.txt @@ -0,0 +1,7 @@ +====== Flytt ====== + +Denne plugin lar deg flytte og/eller endre navn på siden og/eller endre navn må navnerom med følgende restriksjoner: + * Du må ha redigeringsrettigheter til siden/sidene i navnerommet. + * Sidene som flyttes må ikke være låst for redigering. + * Du må også ha redigeringsrettigheter til navnerommet siden/sidene flyttes til. + * Du kan ikke flytte en side til et navnerom som inneholder en side med samme navn. Alle lenker til og fra siden vil bli oppdatert ved flytting. \ No newline at end of file diff --git a/lang/no/progress.txt b/lang/no/progress.txt new file mode 100644 index 0000000..62cf791 --- /dev/null +++ b/lang/no/progress.txt @@ -0,0 +1,3 @@ +====== Flytting pågår... ====== + +Vennligst hold denne siden åpen mens flyttingen pågår. \ No newline at end of file diff --git a/lang/no/settings.php b/lang/no/settings.php new file mode 100644 index 0000000..818e4bb --- /dev/null +++ b/lang/no/settings.php @@ -0,0 +1,11 @@ + + */ +$lang['allowrename'] = 'Tillatt navenendring på disse sidene for disse gruppene og brukerne (separert med komma)'; +$lang['minor'] = 'Merk lenkejusteringer som liten endring? Små endringer vil ikke bli listet i RSS eller varslet til de som abonnerer på endringseposter. '; +$lang['autoskip'] = 'Tillatt automatisk ignorering av feil i navnerom som standard.'; +$lang['autorewrite'] = 'Tillatt automatisk lenkeoppdatering etter flytting av navnerom som standard.'; From 7cdbeda25db834fb976419db8664f7786597da2a Mon Sep 17 00:00:00 2001 From: Damien Regad Date: Tue, 22 Mar 2016 15:32:35 +0100 Subject: [PATCH 240/338] Fix typo in French settings --- lang/fr/settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/fr/settings.php b/lang/fr/settings.php index 5e447dc..ec63d0f 100644 --- a/lang/fr/settings.php +++ b/lang/fr/settings.php @@ -5,7 +5,7 @@ * * @author Schplurtz le Déboulonné */ -$lang['allowrename'] = 'Autoriser le renommage de page à ces utilisateus et groupes (utiliser des virgules)'; +$lang['allowrename'] = 'Autoriser le renommage de page à ces utilisateurs et groupes (utiliser des virgules)'; $lang['minor'] = 'Noter les ajustements de liens comme des modifications mineures. Les modifications mineures ne sont indiquées ni dans les flux RSS, ni dans les courriels des abonnements.'; $lang['autoskip'] = 'Par défaut, ignorer les erreurs de déplacement de catégories.'; $lang['autorewrite'] = 'Activer par défaut la ré-écriture automatique des liens après déplacement de catégories.'; From b19b2e37b0344164352e0eba694087011e5d713a Mon Sep 17 00:00:00 2001 From: Davor Turkalj Date: Sat, 4 Jun 2016 00:40:09 +0200 Subject: [PATCH 241/338] translation update --- lang/hr/lang.php | 64 ++++++++++++++++++++++++++++++++++++++++++++ lang/hr/move.txt | 10 +++++++ lang/hr/progress.txt | 3 +++ lang/hr/settings.php | 12 +++++++++ lang/hr/tree.txt | 4 +++ 5 files changed, 93 insertions(+) create mode 100644 lang/hr/lang.php create mode 100644 lang/hr/move.txt create mode 100644 lang/hr/progress.txt create mode 100644 lang/hr/settings.php create mode 100644 lang/hr/tree.txt diff --git a/lang/hr/lang.php b/lang/hr/lang.php new file mode 100644 index 0000000..0deb1e6 --- /dev/null +++ b/lang/hr/lang.php @@ -0,0 +1,64 @@ + + */ +$lang['menu'] = 'Premještanje stranica i imenskih prostora'; +$lang['inprogress'] = '(čekam premještanje)'; +$lang['treelink'] = 'Umjesto ovog jednostavnog oblika možete raditi kompleksnu reorganizaciju vašeg wiki-a korištenjem vizualnog upravitelja pomicanja'; +$lang['notexist'] = 'Stranica %s ne postoji'; +$lang['norights'] = 'Nemate dovoljne ovlasti za uređivanje %s.'; +$lang['filelocked'] = 'Stranica %s je zaključana. Pokušajte kasnije.'; +$lang['notchanged'] = 'Za stranicu %s nije dana nova lokacija (lokacija nije promijenjena)'; +$lang['exists'] = 'Stranica %s ne može biti pomaknuta na %s, odredište već postoji.'; +$lang['notargetperms'] = 'Nemate ovlaštenja da kreirate stranicu %s.'; +$lang['medianotexist'] = 'Medijska datoteka %s ne postoji'; +$lang['nomediarights'] = 'Nemate dovoljna prava da obrišete %s.'; +$lang['medianotchanged'] = 'Za stranicu %s nije dana nova lokacija (lokacija nije promijenjena)'; +$lang['mediaexists'] = 'Medijska datoteka %s ne može biti pomaknuta na %s, odredište već postoji.'; +$lang['nomediatargetperms'] = 'Nemate ovlaštenja da kreirate medijsku datoteku %s.'; +$lang['indexerror'] = 'Greška pri izmjeni indeksa pretrage %s'; +$lang['metamoveerror'] = 'Meta datoteke stranice %s ne mogu biti premještene'; +$lang['atticmoveerror'] = 'Arhiva stranice (attic datoteke) %s ne može biti premještena. Molimo premjestite ju ručno.'; +$lang['mediametamoveerror'] = 'Meta podaci medijske datoteke %s ne mogu biti premještene'; +$lang['mediamoveerror'] = 'Neuspješno premještanje medijske datoteke %s'; +$lang['mediaatticmoveerror'] = 'Arhiva (attic) medijske datoteke %s ne može biti premještena. Molimo premjestite ju ručno.'; +$lang['renamed'] = 'Ime stranice promijenjeno iz %s u %s'; +$lang['moved'] = 'Stranica premještena iz %s u %s'; +$lang['move_rename'] = 'Stranica premještena i preimenovana iz %s u %s'; +$lang['delete'] = 'Obrisano od strane dodatka za premještanje'; +$lang['linkchange'] = 'Poveznice prilagođene zbog operacije premještanja'; +$lang['intro'] = 'Operacija premještanja još nije počela!'; +$lang['preview'] = 'Pregled izmjena koje će biti izvršene.'; +$lang['inexecution'] = 'Prethodno premještanje nije završeno - upotrijebite tipke ispod za nastavak ili prekid izvršavanja.'; +$lang['btn_start'] = 'Kreni'; +$lang['btn_continue'] = 'Nastavi'; +$lang['btn_retry'] = 'Ponovi stavku'; +$lang['btn_skip'] = 'Preskoči stavku'; +$lang['btn_abort'] = 'Prekini'; +$lang['legend'] = 'Premjesti trenutnu stranicu ili imenski prostor'; +$lang['movepage'] = 'Premjesti stranicu'; +$lang['movens'] = 'Premjesti imenski prostor'; +$lang['dst'] = 'Novo ime:'; +$lang['content_to_move'] = 'Sadržaj za premjestiti:'; +$lang['autoskip'] = 'Zanemari greške i preskoči stranice ili datoteke koje ne mogu biti premještene'; +$lang['autorewrite'] = 'Izmijeniti poveznice odmah nakon završetka premještanja'; +$lang['move_pages'] = 'Stranice'; +$lang['move_media'] = 'Medijske datoteke'; +$lang['move_media_and_pages'] = 'Stranice i medijske datoteke'; +$lang['nodst'] = 'Nije uneseno novo ime'; +$lang['noaction'] = 'Nema definiranih premještanja'; +$lang['renamepage'] = 'Preimenuj stranicu'; +$lang['cantrename'] = 'Stranica trenutno ne može biti preimenovana. Molimo pokušajte kasnije.'; +$lang['js']['rename'] = 'Preimenuj'; +$lang['js']['cancel'] = 'Prekini'; +$lang['js']['newname'] = 'Novo ime:'; +$lang['js']['inprogress'] = 'preimenovanje stranice i prilagodba poveznica...'; +$lang['js']['complete'] = 'Operacija premještanja završila.'; +$lang['js']['renameitem'] = 'Preimenuj ovu stavku'; +$lang['js']['duplicate'] = 'Isprika ali "%s" već postoji u ovom imenskom prostoru'; +$lang['root'] = '[Korijen imenskog prostora]'; +$lang['noscript'] = 'Ova osobina zahtijeva JavaScript'; +$lang['moveinprogress'] = 'Trenutno je druga operacija premještanja u tijeku, zasada ne možete koristiti ovaj alat.'; diff --git a/lang/hr/move.txt b/lang/hr/move.txt new file mode 100644 index 0000000..a939a69 --- /dev/null +++ b/lang/hr/move.txt @@ -0,0 +1,10 @@ +====== Premjesti ====== + +Ovaj dodatak omogućava premještanje i/ili preimenovanje trenutne stranice ili imenskog prostora unutar slijedećih ograničenja: + + * Morate imate dopuštenje za izmjenu trenutne ili svih stranicau trenutnom imenskom prostoru. + * Stranice koje se premještaju ne smiju biti zaključane. + * Za premještanje stranice također morate imati ovlaštenje za kreiranje u odredišnom imenskom prostoru. + * Na možete premjestiti stranicu u imenski prostor gdje stranica s istim imenom već postoji. + +Sve poveznice na ili sa stranice koja se premješta biti će preusmjerene da pokazuju na novu lokaciju i/ili ime. diff --git a/lang/hr/progress.txt b/lang/hr/progress.txt new file mode 100644 index 0000000..e585c72 --- /dev/null +++ b/lang/hr/progress.txt @@ -0,0 +1,3 @@ +====== Premještanje u tijeku... ====== + +Molimo držite ovu stranicu otvorenom dok traje premještanje. \ No newline at end of file diff --git a/lang/hr/settings.php b/lang/hr/settings.php new file mode 100644 index 0000000..2c854ae --- /dev/null +++ b/lang/hr/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Omogući preimenovanje stranica ovim grupama i korisnicima (zarezom odvojena lista).'; +$lang['minor'] = 'Označiti prilagodbe poveznica kao manje značajne? Takve promjene neće biti prikazane u RSS obavijestima i obavijesnim porukama.'; +$lang['autoskip'] = 'Omogući kao podrazumijevano automatsko preskakanje grešaka pri premještanju imenskog prostora.'; +$lang['autorewrite'] = 'Omogući kao podrazumijevano automatsku prilagodbu poveznica. +'; diff --git a/lang/hr/tree.txt b/lang/hr/tree.txt new file mode 100644 index 0000000..36b6db5 --- /dev/null +++ b/lang/hr/tree.txt @@ -0,0 +1,4 @@ +====== Upravitelj premještanja ===== + +Ovo sučelje omogućava reorganizaciju wiki imenskih prostora, stranica i medijskih datoteka korištenjem Povuci-i-Spusti radnje. + From b28d375c17f1f1aad8dc8e583546d112231acbac Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Thu, 30 Jun 2016 12:20:45 +0200 Subject: [PATCH 242/338] Remove old files on update These files became an issue with the new DokuWiki release as pointed out in issue #72 --- deleted.files | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 deleted.files diff --git a/deleted.files b/deleted.files new file mode 100644 index 0000000..d0cd2c6 --- /dev/null +++ b/deleted.files @@ -0,0 +1,6 @@ +# This is a list of files that were present in previous plugin releases +# but were removed later. An up to date plugin should not have any of +# the files installed +action.php +admin.php +helper.php From b8e4b541ac24fbd610572218bbdf62819f5facd4 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Thu, 30 Jun 2016 12:49:58 +0200 Subject: [PATCH 243/338] Remove all old files on update This list hast been generated by the command: git log --no-renames --diff-filter=D --summary | grep delete (with git 2.9) --- deleted.files | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/deleted.files b/deleted.files index d0cd2c6..9492d25 100644 --- a/deleted.files +++ b/deleted.files @@ -1,6 +1,33 @@ # This is a list of files that were present in previous plugin releases # but were removed later. An up to date plugin should not have any of # the files installed +_action.php action.php admin.php helper.php +rename.png +sprite.png + +_test/plugin_move_cache_handling.test.php +_test/mediaindex.test.php +helper/general.php +admin/simple.php +script/move.js + +lang/cs/pagemove.txt +lang/de/pagemove.txt +lang/en/pagemove.txt +lang/es/pagemove.txt +lang/fr/pagemove.txt +lang/lv/pagemove.txt +lang/nl/pagemove.txt +lang/pl/pagemove.txt +lang/ru/pagemove.txt +lang/sl/pagemove.txt +lang/cs/lang.php.txt +lang/cs/pagemove.txt.txt +lang/es/lang.php.txt +lang/es/pagemove.txt.txt +lang/pl/lang.php.txt +lang/pl/pagemove.txt.txt +lang/zh/pagemove.txt From 2f4149082cb9d0534023ea2b66a7ece0a6bedfea Mon Sep 17 00:00:00 2001 From: Myeongjin Date: Wed, 27 Jul 2016 15:30:38 +0200 Subject: [PATCH 244/338] translation update --- lang/ko/lang.php | 62 ++++++++++++++++++++++---------------------- lang/ko/move.txt | 12 ++++----- lang/ko/progress.txt | 4 +-- lang/ko/settings.php | 10 +++---- lang/ko/tree.txt | 2 +- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/lang/ko/lang.php b/lang/ko/lang.php index 83ec84e..f080d62 100644 --- a/lang/ko/lang.php +++ b/lang/ko/lang.php @@ -2,64 +2,64 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Gary Owen * @author Myeongjin */ -$lang['menu'] = '문서와 이름공간 옮기기'; -$lang['inprogress'] = '(옮기기 보류 중)'; -$lang['treelink'] = '다른 방법으로 이 간단한 양식은 트리 기반의 옮기기 관리자를 사용하여 위키의 복잡한 구조 조정을 관리할 수 있습니다.'; +$lang['menu'] = '문서와 이름공간 이동'; +$lang['inprogress'] = '(이동 보류 중)'; +$lang['treelink'] = '다른 방법으로 이 간단한 양식은 트리 기반의 이동 관리자를 사용하여 위키의 복잡한 구조 조정을 관리할 수 있습니다.'; $lang['notexist'] = '%s 문서가 존재하지 않습니다'; -$lang['norights'] = '%s(을)를 편집할 충분하지 않은 권한이 있습니다.'; -$lang['filelocked'] = '%s 문서가 잠겨 있습니다. 나중에 다시 시도하세요.'; +$lang['norights'] = '%s 문서를 편집할 충분하지 않은 권한이 있습니다.'; +$lang['filelocked'] = '%s 문서가 잠겨 있습니다. 나중에 다시 시도해주세요.'; $lang['notchanged'] = '%s 문서에 주어진 새 대상이 없습니다. (위치가 바뀌지 않음)'; -$lang['exists'] = '%s 문서는 %s(으)로 옮길 수 없으며, 대상이 이미 존재합니다.'; +$lang['exists'] = '%s 문서는 %s 문서로 이동할 수 없으며, 대상이 이미 존재합니다.'; $lang['notargetperms'] = '%s 문서를 만들 권한이 없습니다.'; $lang['medianotexist'] = '%s 미디어 파일이 존재하지 않습니다'; -$lang['nomediarights'] = '%s(을)를 삭제할 충분하지 않은 권한이 있습니다.'; +$lang['nomediarights'] = '%s 문서를 삭제할 충분하지 않은 권한이 있습니다.'; $lang['medianotchanged'] = '%s 문서에 주어진 새 대상이 없습니다. (위치가 바뀌지 않음)'; -$lang['mediaexists'] = '%s 미디어는 %s(으)로 옮길 수 없으며, 대상이 이미 존재합니다.'; +$lang['mediaexists'] = '%s 미디어는 %s 미디어로 이동할 수 없으며, 대상이 이미 존재합니다.'; $lang['nomediatargetperms'] = '%s 미디어 파일을 만들 권한이 없습니다.'; $lang['indexerror'] = '%s 검색 색인을 업데이트하는 동안 오류'; -$lang['metamoveerror'] = '%s 문서의 메타 파일을 옮길 수 없습니다'; -$lang['atticmoveerror'] = '%s 문서의 첨부 파일을 옮길 수 없습니다. 직접 옮겨주세요.'; -$lang['mediametamoveerror'] = '%s 미디어 파일의 메타 파일을 옮길 수 없습니다'; -$lang['mediamoveerror'] = '%s 미디어 파일을 옮기는 데 실패했습니다'; -$lang['mediaatticmoveerror'] = '%s 문서의 첨부 파일을 옮길 수 없습니다. 직접 옮겨주세요.'; +$lang['metamoveerror'] = '%s 문서의 메타 파일을 이동할 수 없습니다'; +$lang['atticmoveerror'] = '%s 문서의 첨부 파일을 이동할 수 없습니다. 수동으로 이동해주시기 바랍니다.'; +$lang['mediametamoveerror'] = '%s 미디어 파일의 메타 파일을 이동할 수 없습니다'; +$lang['mediamoveerror'] = '%s 미디어 파일을 이동하는 데 실패했습니다'; +$lang['mediaatticmoveerror'] = '%s 문서의 첨부 파일을 이동할 수 없습니다. 수동으로 이동해주시기 바랍니다.'; $lang['renamed'] = '문서 이름이 %s에서 %s(으)로 바뀌었습니다'; -$lang['moved'] = '문서가 %s에서 %s(으)로 옮겨졌습니다'; -$lang['move_rename'] = '문서가 %s에서 %s(으)로 옮겨지고 이름이 바뀌었습니다'; -$lang['delete'] = '옮기기 플러그인에 의해 삭제됨'; -$lang['linkchange'] = '링크가 옮기기 작업으로 인해 적응했습니다'; -$lang['intro'] = '옮기기 작업은 아직 시작되지 않았습니다!'; +$lang['moved'] = '문서가 %s에서 %s(으)로 이동되었습니다'; +$lang['move_rename'] = '문서가 %s에서 %s(으)로 이동되고 이름이 바뀌었습니다'; +$lang['delete'] = 'move 플러그인에 의해 삭제됨'; +$lang['linkchange'] = '링크가 이동 작업으로 인해 적응했습니다'; +$lang['intro'] = '이동 작업은 아직 시작되지 않았습니다!'; $lang['preview'] = '실행할 바뀜을 미리 봅니다.'; -$lang['inexecution'] = '이전 옮기기가 완료되지 않았습니다 - 실행을 계속하거나 중단하려면 아래 버튼을 사용하세요.'; +$lang['inexecution'] = '이전 이동이 완료되지 않았습니다 - 실행을 계속하거나 중단하려면 아래 버튼을 사용하세요.'; $lang['btn_start'] = '시작'; $lang['btn_continue'] = '계속'; $lang['btn_retry'] = '항목 다시 시도'; $lang['btn_skip'] = '항목 건너뛰기'; $lang['btn_abort'] = '중단'; -$lang['legend'] = '현재 문서 또는 이름공간 옮기기'; -$lang['movepage'] = '문서 옮기기'; -$lang['movens'] = '이름공간 옮기기'; +$lang['legend'] = '현재 문서 또는 이름공간 이동'; +$lang['movepage'] = '문서 이동'; +$lang['movens'] = '이름공간 이동'; $lang['dst'] = '새 이름:'; -$lang['content_to_move'] = '옮길 내용:'; -$lang['autoskip'] = '오류를 무시하고 옮길 수 없는 문서나 파일을 건너뛰기'; -$lang['autorewrite'] = '옮기기를 완료하고 나서 링크를 올바르게 다시 쓰기'; +$lang['content_to_move'] = '이동할 내용:'; +$lang['autoskip'] = '오류를 무시하고 이동할 수 없는 문서나 파일을 건너뛰기'; +$lang['autorewrite'] = '이동을 완료하고 나서 링크를 올바르게 다시 쓰기'; $lang['move_pages'] = '문서'; $lang['move_media'] = '미디어 파일'; $lang['move_media_and_pages'] = '문서와 미디어 파일'; $lang['nodst'] = '주어진 새 이름이 없습니다'; -$lang['noaction'] = '정의한 옮기기가 없습니다'; +$lang['noaction'] = '정의한 이동이 없습니다'; $lang['renamepage'] = '문서 이름 바꾸기'; -$lang['cantrename'] = '문서는 지금 바로 이름을 바꿀 수 없습니다. 나중에 시도해주세요.'; +$lang['cantrename'] = '문서는 지금 바로 이름을 바꿀 수 없습니다. 나중에 시도해주시기 바랍니다.'; $lang['js']['rename'] = '이름 바꾸기'; $lang['js']['cancel'] = '취소'; $lang['js']['newname'] = '새 이름:'; $lang['js']['inprogress'] = '문서의 이름을 바꾸고 링크를 조절하는 중...'; -$lang['js']['complete'] = '옮기기 작업이 완료되었습니다.'; +$lang['js']['complete'] = '이동 작업이 완료되었습니다.'; $lang['js']['renameitem'] = '이 항목 이름 바꾸기'; -$lang['js']['duplicate'] = '죄송하지만, "%s"은(는) 이미 이 이름공간에 존재합니다.'; +$lang['js']['duplicate'] = '죄송하지만, "%s" 문서는 이미 이 이름공간에 존재합니다.'; $lang['root'] = '[루트 이름공간]'; $lang['noscript'] = '이 기능은 자바스크립트가 필요합니다'; -$lang['moveinprogress'] = '현재 진행 중인 다른 옮기기 작업이 있습니다, 지금 바로 이 도구를 사용할 수 없습니다.'; +$lang['moveinprogress'] = '현재 진행 중인 다른 이동 작업이 있으므로, 지금 바로 이 도구를 사용할 수 없습니다.'; diff --git a/lang/ko/move.txt b/lang/ko/move.txt index d4e161b..17b1885 100644 --- a/lang/ko/move.txt +++ b/lang/ko/move.txt @@ -1,10 +1,10 @@ -====== 옮기기 ====== +====== 이동 ====== -이 플러그인은 다음 제한 안에서 현재 문서를 옮기고/거나 이름을 바꾸거나 현재 이름공간을 옮기고/거나 이름을 바꿀 수 있습니다: +이 플러그인은 다음 제한 안에서 현재 문서를 이동하고/거나 이름을 바꾸거나 현재 이름공간을 이동하고/거나 이름을 바꿀 수 있습니다: * 현재 이름공간에서 현재 문서/모든 문서에 대한 편집 권한이 있어야 합니다. - * 옮겨지는 문서는 편집을 위해 잠겨 있지 않아야 합니다. - * 문서 옮기기를 위해서는 대상 이름공간에서 만들기 권한도 필요합니다. - * 같은 이름으로 된 문서가 이미 존재하는 이름공간으로 문서를 옮길 수 없습니다. + * 이동되는 문서는 편집을 위해 잠겨 있지 않아야 합니다. + * 문서 이동을 위해서는 대상 이름공간에서 만들기 권한도 필요합니다. + * 같은 이름으로 된 문서가 이미 존재하는 이름공간으로 문서를 이동할 수 없습니다. -기존에서 새로 옮겨지는 문서의 모든 링크는 새 위치와/나 이름을 반영하도록 바뀝니다. \ No newline at end of file +기존에서 새로 이동하는 문서의 모든 링크는 새 위치와/나 이름을 반영하도록 바뀝니다. \ No newline at end of file diff --git a/lang/ko/progress.txt b/lang/ko/progress.txt index 2be01ce..e2f3705 100644 --- a/lang/ko/progress.txt +++ b/lang/ko/progress.txt @@ -1,3 +1,3 @@ -====== 진행 중인 옮기기... ====== +====== 진행 중인 이동... ====== -옮기기를 진행하는 동안 이 문서를 열어두세요. \ No newline at end of file +이동을 진행하는 동안 이 문서를 열어두시기 바랍니다. \ No newline at end of file diff --git a/lang/ko/settings.php b/lang/ko/settings.php index 50a22f7..e5dbc42 100644 --- a/lang/ko/settings.php +++ b/lang/ko/settings.php @@ -2,10 +2,10 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Myeongjin */ -$lang['allowrename'] = '문서의 이름을 바꿀 수 있는 그룹 및 사용자 (쉼표로 구분).'; -$lang['minor'] = '링크 조절을 사소한 바뀜으로 표시하겠습니까? 사소한 바뀜은 RSS 피드와 구독 메일에 나열하지 않을 것입니다.'; -$lang['autoskip'] = '기본적으로 이름공간 옮기기에서 오류를 자동으로 건너뛰도록 활성화합니다.'; -$lang['autorewrite'] = '기본적으로 이름공간을 옮기고 나서 자동으로 링크 다시 쓰기를 활성화합니다.'; +$lang['allowrename'] = '문서의 이름을 바꿀 수 있는 그룹 및 사용자. (쉼표로 구분)'; +$lang['minor'] = '링크 조절을 사소한 바뀜으로 표시하겠습니까? 사소한 바뀜은 RSS 피드와 구독 메일에 나열되지 않을 것입니다.'; +$lang['autoskip'] = '기본적으로 이름공간 이동에서 오류를 자동으로 건너뛰도록 활성화합니다.'; +$lang['autorewrite'] = '기본적으로 이름공간을 이동하고 나서 자동으로 링크 다시 쓰기를 활성화합니다.'; diff --git a/lang/ko/tree.txt b/lang/ko/tree.txt index 957153a..51b8780 100644 --- a/lang/ko/tree.txt +++ b/lang/ko/tree.txt @@ -1,3 +1,3 @@ -====== 옮기기 관리자 ===== +====== 이동 관리자 ===== 이 인터페이스는 드래그 앤 드롭을 통해 위키의 이름공간, 문서와 미디어 파일을 재배열할 수 있습니다. \ No newline at end of file From ebffba718660d679afde1aaeda4d8aada1287701 Mon Sep 17 00:00:00 2001 From: Michael Grosse Date: Mon, 5 Dec 2016 14:44:22 +0100 Subject: [PATCH 245/338] feat: Add config to toggle pagetools integration Having a hard-coded list of templates where the integration happens is cumbersome, because it requires a pull-request for every new template and it is somehow the wrong order because the templates should have the option to create special handling for specific plugins, however plugins should not have special handling for specific templates. --- action/rename.php | 23 +++++++++-------------- conf/default.php | 1 + conf/metadata.php | 1 + lang/en/settings.php | 1 + 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/action/rename.php b/action/rename.php index f443c7e..35019b9 100644 --- a/action/rename.php +++ b/action/rename.php @@ -39,22 +39,17 @@ public function handle_init() { * @param Doku_Event $event */ public function handle_pagetools(Doku_Event $event) { - global $conf; if($event->data['view'] != 'main') return; - - switch($conf['template']) { - case 'dokuwiki': - case 'arago': - case 'bootstrap3': - - $newitem = '
  • ' . $this->getLang('renamepage') . '
  • '; - $offset = count($event->data['items']) - 1; - $event->data['items'] = - array_slice($event->data['items'], 0, $offset, true) + - array('plugin_move' => $newitem) + - array_slice($event->data['items'], $offset, null, true); - break; + if (!$this->getConf('pagetools integration')) { + return; } + + $newitem = '
  • ' . $this->getLang('renamepage') . '
  • '; + $offset = count($event->data['items']) - 1; + $event->data['items'] = + array_slice($event->data['items'], 0, $offset, true) + + array('plugin_move' => $newitem) + + array_slice($event->data['items'], $offset, null, true); } /** diff --git a/conf/default.php b/conf/default.php index e3f5a8a..251edb8 100644 --- a/conf/default.php +++ b/conf/default.php @@ -4,3 +4,4 @@ $conf['minor'] = 1; $conf['autoskip'] = 0; $conf['autorewrite'] = 1; +$conf['pagetools integration'] = 1; diff --git a/conf/metadata.php b/conf/metadata.php index 5a0832f..16e22c4 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -4,3 +4,4 @@ $meta['minor'] = array('onoff'); $meta['autoskip'] = array('onoff'); $meta['autorewrite'] = array('onoff'); +$meta['pagetools integration'] = array('onoff'); diff --git a/lang/en/settings.php b/lang/en/settings.php index 3a7a18f..1a3ca6c 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -4,3 +4,4 @@ $lang['minor'] = 'Mark link adjustments as minor? Minor changes will not be listed in RSS feeds and subscription mails.'; $lang['autoskip'] = 'Enable automatic skipping of errors in namespace moves by default.'; $lang['autorewrite'] = 'Enable automatic link rewriting after namespace moves by default.'; +$lang['pagetools integration'] = 'Add renaming button to pagetools'; From fb13e13a9a998f51ee082e609dcbff797ea07583 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 2 Jan 2017 12:45:18 +0100 Subject: [PATCH 246/338] Remove space character from configuration key --- action/rename.php | 2 +- conf/default.php | 2 +- conf/metadata.php | 2 +- lang/en/settings.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/action/rename.php b/action/rename.php index 35019b9..ad4208b 100644 --- a/action/rename.php +++ b/action/rename.php @@ -40,7 +40,7 @@ public function handle_init() { */ public function handle_pagetools(Doku_Event $event) { if($event->data['view'] != 'main') return; - if (!$this->getConf('pagetools integration')) { + if (!$this->getConf('pagetools_integration')) { return; } diff --git a/conf/default.php b/conf/default.php index 251edb8..cc1cbe7 100644 --- a/conf/default.php +++ b/conf/default.php @@ -4,4 +4,4 @@ $conf['minor'] = 1; $conf['autoskip'] = 0; $conf['autorewrite'] = 1; -$conf['pagetools integration'] = 1; +$conf['pagetools_integration'] = 1; diff --git a/conf/metadata.php b/conf/metadata.php index 16e22c4..35e1476 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -4,4 +4,4 @@ $meta['minor'] = array('onoff'); $meta['autoskip'] = array('onoff'); $meta['autorewrite'] = array('onoff'); -$meta['pagetools integration'] = array('onoff'); +$meta['pagetools_integration'] = array('onoff'); diff --git a/lang/en/settings.php b/lang/en/settings.php index 1a3ca6c..a662c27 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -4,4 +4,4 @@ $lang['minor'] = 'Mark link adjustments as minor? Minor changes will not be listed in RSS feeds and subscription mails.'; $lang['autoskip'] = 'Enable automatic skipping of errors in namespace moves by default.'; $lang['autorewrite'] = 'Enable automatic link rewriting after namespace moves by default.'; -$lang['pagetools integration'] = 'Add renaming button to pagetools'; +$lang['pagetools_integration'] = 'Add renaming button to pagetools'; From 11fe6b493e047eefc13d05b14f9357c916095826 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 2 Jan 2017 15:25:09 +0100 Subject: [PATCH 247/338] Show hidden pages in tree move --- admin/tree.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/admin/tree.php b/admin/tree.php index 99aa9d4..8187870 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -108,12 +108,13 @@ public function tree($type = self::TYPE_PAGES, $open = '', $base = '') { $basedir = utf8_encodeFN(str_replace(':', '/', $base)); $opts = array( - 'pagesonly' => ($type == self::TYPE_PAGES), - 'listdirs' => true, - 'listfiles' => true, - 'sneakyacl' => $conf['sneaky_index'], - 'showmsg' => false, - 'depth' => 1 + 'pagesonly' => ($type == self::TYPE_PAGES), + 'listdirs' => true, + 'listfiles' => true, + 'sneakyacl' => $conf['sneaky_index'], + 'showmsg' => false, + 'depth' => 1, + 'showhidden' => true ); $data = array(); From a428ba587d763df5f6b1d0ef47bd5ead9e062757 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 2 Jan 2017 21:40:16 +0100 Subject: [PATCH 248/338] Make the handler helper a proper helper plugin, fixes #84, fixes #33 --- _test/handler.test.php | 13 +++++++++++-- helper/handler.php | 15 ++++++++++++--- helper/rewrite.php | 4 +++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/_test/handler.test.php b/_test/handler.test.php index 4a2318b..1c968b6 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -12,8 +12,15 @@ */ class plugin_move_handler_test extends DokuWikiTest { + public function setUp() { + $this->pluginsEnabled[] = 'move'; + parent::setUp(); + } + public function test_relativeLink() { - $handler = new helper_plugin_move_handler('deep:namespace:page', 'used:to:be:here', array(), array(), array()); + /** @var $handler helper_plugin_move_handler */ + $handler = plugin_load('helper', 'move_handler'); + $handler->init('deep:namespace:page', 'used:to:be:here', array(), array(), array()); $tests = array( 'deep:namespace:new1' => 'new1', @@ -33,7 +40,9 @@ public function test_relativeLink() { } public function test_resolveMoves() { - $handler = new helper_plugin_move_handler( + /** @var $handler helper_plugin_move_handler */ + $handler = plugin_load('helper', 'move_handler'); + $handler->init( 'deep:namespace:page', 'used:to:be:here', array( diff --git a/helper/handler.php b/helper/handler.php index 37b4476..fdfdb55 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -14,7 +14,7 @@ * * Note: This is not actually a valid DokuWiki Helper plugin and can not be loaded via plugin_load() */ -class helper_plugin_move_handler { +class helper_plugin_move_handler extends DokuWiki_Plugin { public $calls = ''; protected $id; @@ -26,7 +26,16 @@ class helper_plugin_move_handler { protected $handlers; /** - * Construct the move handler. + * Do not allow re-using instances. + * + * @return bool false - the handler must not be re-used. + */ + public function isSingleton() { + return false; + } + + /** + * Initialize the move handler. * * @param string $id The id of the text that is passed to the handler * @param string $original The name of the original ID of this page. Same as $id if this page wasn't moved @@ -34,7 +43,7 @@ class helper_plugin_move_handler { * @param array $media_moves Moves of media files that shall be considered in the form $old => $new * @param array $handlers Handlers for plugin content in the form $plugin_name => $callback */ - public function __construct($id, $original, $page_moves, $media_moves, $handlers) { + public function init($id, $original, $page_moves, $media_moves, $handlers) { $this->id = $id; $this->ns = getNS($id); $this->origID = $original; diff --git a/helper/rewrite.php b/helper/rewrite.php index 29eac27..9e55b2b 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -241,7 +241,9 @@ public function rewrite($id, $text) { $Parser = new Doku_Parser(); // Add the Handler - $Parser->Handler = new helper_plugin_move_handler($id, $origin, $pages, $media, $handlers); + /** @var $Parser->Handler helper_plugin_move_handler */ + $Parser->Handler = $this->loadHelper('move_handler'); + $Parser->Handler->init($id, $origin, $pages, $media, $handlers); //add modes to parser foreach($modes as $mode) { From 99d285fc8ec37c23fa50b915fa11c1930e63dbb8 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 2 Jan 2017 23:25:27 +0100 Subject: [PATCH 249/338] New version 2017-01-02 released. Apart from translation updates this includes the following changes: * The integration in the page tools can now be set in the configuration and is independent of the template. * Hidden pages are shown in the tree-based move manager so they can be renamed, too. They were already included when moving namespaces before (and then shown in the list of changes). Note that this is for managers only. * Problems with the plugin list provided by the info plugin were fixed (e.g. used in the syntax page) * Old plugin files are automatically removed with this update. --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index c72b682..33e3bc6 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2015-10-18 +date 2017-01-02 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From fe7b1a115e86059f3e590414d2969e7fc036377d Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 3 Jan 2017 20:34:46 +0100 Subject: [PATCH 250/338] Tree move ui: add new drag & drop logic, fixes #17 (move into empty folders) --- script/tree.js | 66 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/script/tree.js b/script/tree.js index 4532bb8..02cb093 100644 --- a/script/tree.js +++ b/script/tree.js @@ -36,12 +36,11 @@ var checkForMovement = function ($li) { * Check if the given name is allowed in the given parent * * @param {jQuery} $li the edited or moved LI + * @param {jQuery} $parent the (new) parent of the edited or moved LI * @param {string} name the (new) name to check * @returns {boolean} */ -var checkNameAllowed = function ($li, name) { - var $parent = $li.parent(); - +var checkNameAllowed = function ($li, $parent, name) { var ok = true; $parent.children('li').each(function () { if (this === $li[0]) return; @@ -89,6 +88,48 @@ var cleanID = function (id) { return id; }; +/** + * Initialize the drag & drop-tree starting at the given ul (must be this). + */ +var initTree = function () { + var my_root = jQuery(this).closest('.tree_root')[0]; + jQuery(this).find('li').draggable({ + revert: true, + revertDuration: 0, + opacity: 0.5 + }).droppable({ + tolerance: 'pointer', + greedy: true, + accept : function(draggable) { + return my_root == draggable.closest('.tree_root')[0]; + }, + drop : function (event, ui) { + var $dropped = ui.draggable; + var $me = jQuery(this); + $dropped.css({height: "auto", width: "auto"}); + + if ($me == $dropped) { + return; + } + + if ($me.hasClass("type-f") || $me.hasClass("closed")) { + if (checkNameAllowed($dropped, $me.parent(), ui.draggable.data('name'))) { + $dropped.insertAfter($me); + } + } else { + var $new_parent = $me.children('ul'); + if (checkNameAllowed($dropped, $new_parent, $dropped.data('name'))) { + $dropped.prependTo($new_parent); + } + } + + checkForMovement($dropped); + } + }) + // add title to rename icon + .find('img').attr('title', LANG.plugins.move.renameitem); +}; + /** * Attach event listeners to the tree */ @@ -121,6 +162,7 @@ $GUI.find('ul.tree_list') }, function (data) { $li.append(data); + $li.children('ul').each(initTree); } ); } @@ -132,7 +174,7 @@ $GUI.find('ul.tree_list') var newname = window.prompt(LANG.plugins.move.renameitem, $li.data('name')); newname = cleanID(newname); if (newname) { - if (checkNameAllowed($li, newname)) { + if (checkNameAllowed($li, $li.parent(), newname)) { $li.data('name', newname); $a.text(newname); checkForMovement($li); @@ -142,21 +184,7 @@ $GUI.find('ul.tree_list') } } e.preventDefault(); - }) - // initialize sortable - .find('ul').sortable({ - items: 'li', - stop: function (e, ui) { - if (!checkNameAllowed(ui.item, ui.item.data('name'))) { - jQuery(this).sortable('cancel'); - alert(LANG.plugins.move.duplicate.replace('%s', ui.item.data('name'))); - } - - checkForMovement(ui.item); - } - }) - // add title to rename icon - .find('img').attr('title', LANG.plugins.move.renameitem); + }).each(initTree); /** * Gather all moves from the trees and put them as JSON into the form before submit From 2e9872c401c49b1ac332182cb584e8d76dee663e Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 3 Jan 2017 22:24:00 +0100 Subject: [PATCH 251/338] Tree move: Add checkboxes to allow moving many pages resolve #66 --- admin/tree.php | 4 ++++ script/tree.js | 32 +++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/admin/tree.php b/admin/tree.php index 8187870..161fdf1 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -146,6 +146,10 @@ function html_list($item) { if($item['id'] == '*') $item['id'] = ''; + if ($item['id']) { + $ret .= ' '; + } + // namespace or page? if($item['type'] == 'd') { $ret .= ''; diff --git a/script/tree.js b/script/tree.js index 02cb093..3cd1f9f 100644 --- a/script/tree.js +++ b/script/tree.js @@ -108,17 +108,38 @@ var initTree = function () { var $me = jQuery(this); $dropped.css({height: "auto", width: "auto"}); - if ($me == $dropped) { + if ($dropped.children('div.li').children('input').prop('checked')) { + $dropped = $dropped.add( + jQuery(my_root) + .find('input') + .filter(function() { + return jQuery(this).prop('checked'); + }).parent().parent() + ); + } + + if ($me.parents().addBack().is($dropped)) { return; } + var allowed = true; if ($me.hasClass("type-f") || $me.hasClass("closed")) { - if (checkNameAllowed($dropped, $me.parent(), ui.draggable.data('name'))) { + $dropped.each(function () { + var $this = jQuery(this); + allowed &= checkNameAllowed($this, $me.parent(), $this.data('name')); + }); + if (allowed) { $dropped.insertAfter($me); } } else { var $new_parent = $me.children('ul'); - if (checkNameAllowed($dropped, $new_parent, $dropped.data('name'))) { + + $dropped.each(function () { + var $this = jQuery(this); + allowed &= checkNameAllowed($this, $new_parent, $this.data('name')); + }); + + if (allowed) { $dropped.prependTo($new_parent); } } @@ -133,7 +154,7 @@ var initTree = function () { /** * Attach event listeners to the tree */ -$GUI.find('ul.tree_list') +$GUI.find('div.tree_root > ul.tree_list') .click(function (e) { var $clicky = jQuery(e.target); var $li = $clicky.parent().parent(); @@ -167,6 +188,7 @@ $GUI.find('ul.tree_list') ); } } + e.preventDefault(); } else if ($clicky[0].tagName == 'IMG') { // Click on IMG - do rename e.stopPropagation(); var $a = $clicky.parent().find('a'); @@ -182,8 +204,8 @@ $GUI.find('ul.tree_list') alert(LANG.plugins.move.duplicate.replace('%s', newname)); } } + e.preventDefault(); } - e.preventDefault(); }).each(initTree); /** From a6dfdd27ef82a0075f130fd726e29a71e267250c Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 3 Jan 2017 22:46:38 +0100 Subject: [PATCH 252/338] Fixes for tree move: root can be closed, reset heights correctly --- script/tree.js | 8 +++++--- style.less | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/script/tree.js b/script/tree.js index 3cd1f9f..0df8ce7 100644 --- a/script/tree.js +++ b/script/tree.js @@ -96,7 +96,10 @@ var initTree = function () { jQuery(this).find('li').draggable({ revert: true, revertDuration: 0, - opacity: 0.5 + opacity: 0.5, + stop : function(event, ui) { + ui.helper.css({height: "auto", width: "auto"}); + } }).droppable({ tolerance: 'pointer', greedy: true, @@ -106,7 +109,6 @@ var initTree = function () { drop : function (event, ui) { var $dropped = ui.draggable; var $me = jQuery(this); - $dropped.css({height: "auto", width: "auto"}); if ($dropped.children('div.li').children('input').prop('checked')) { $dropped = $dropped.add( @@ -159,7 +161,7 @@ $GUI.find('div.tree_root > ul.tree_list') var $clicky = jQuery(e.target); var $li = $clicky.parent().parent(); - if ($clicky.attr('href')) { // Click on folder - open and close via AJAX + if ($clicky[0].tagName == 'A' && $li.hasClass('type-d')) { // Click on folder - open and close via AJAX e.stopPropagation(); if ($li.hasClass('open')) { $li diff --git a/style.less b/style.less index bbcfa5b..32764a7 100644 --- a/style.less +++ b/style.less @@ -18,7 +18,7 @@ display: block; } - ul.tree_list ul { + ul.tree_list { .moved > div { border: 1px dashed lighten(@ini_text, 30%); border-radius: 3px; From ed105af57ed1d71992d4a83b6206d4b90670936e Mon Sep 17 00:00:00 2001 From: e-dschungel Date: Thu, 5 Jan 2017 21:40:08 +0100 Subject: [PATCH 253/338] translation update --- lang/de/lang.php | 2 +- lang/de/settings.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lang/de/lang.php b/lang/de/lang.php index e36d4a8..dae9b89 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -2,7 +2,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author picsar * @author e-dschungel */ diff --git a/lang/de/settings.php b/lang/de/settings.php index 1e8061e..ade23fc 100644 --- a/lang/de/settings.php +++ b/lang/de/settings.php @@ -2,10 +2,11 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author e-dschungel */ $lang['allowrename'] = 'Umbennenung von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt) '; $lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderung werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; $lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; $lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; +$lang['pagetools_integration'] = 'Umbenennen-Button zu Pagetools hinzufügen'; From 7f0935c19a5ef899ba4aeab6301ad6ba03c48217 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 6 Jan 2017 20:39:28 +0100 Subject: [PATCH 254/338] Remove some duplicate JS code --- script/tree.js | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/script/tree.js b/script/tree.js index 0df8ce7..72adcdf 100644 --- a/script/tree.js +++ b/script/tree.js @@ -124,25 +124,20 @@ var initTree = function () { return; } + var insert_child = !($me.hasClass("type-f") || $me.hasClass("closed")); + var $new_parent = insert_child ? $me.children('ul') : $me.parent(); var allowed = true; - if ($me.hasClass("type-f") || $me.hasClass("closed")) { - $dropped.each(function () { - var $this = jQuery(this); - allowed &= checkNameAllowed($this, $me.parent(), $this.data('name')); - }); - if (allowed) { - $dropped.insertAfter($me); - } - } else { - var $new_parent = $me.children('ul'); - $dropped.each(function () { - var $this = jQuery(this); - allowed &= checkNameAllowed($this, $new_parent, $this.data('name')); - }); + $dropped.each(function () { + var $this = jQuery(this); + allowed &= checkNameAllowed($this, $new_parent, $this.data('name')); + }); - if (allowed) { + if (allowed) { + if (insert_child) { $dropped.prependTo($new_parent); + } else { + $dropped.insertAfter($me); } } From f8254d41aefa8de13bd5bcd00f000e4544d791fe Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Fri, 6 Jan 2017 22:47:39 +0100 Subject: [PATCH 255/338] Add create namespace feature in tree move ui #77 --- admin/tree.php | 3 ++- images/folder_add.png | Bin 0 -> 668 bytes lang/en/lang.php | 1 + script/tree.js | 52 +++++++++++++++++++++++++++++------------- style.less | 2 +- 5 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 images/folder_add.png diff --git a/admin/tree.php b/admin/tree.php index 161fdf1..a3482dc 100644 --- a/admin/tree.php +++ b/admin/tree.php @@ -161,7 +161,8 @@ function html_list($item) { $ret .= ''; } - if($item['id']) $ret .= ''; + if($item['id']) $ret .= ''; + else $ret .= ''; return $ret; } diff --git a/images/folder_add.png b/images/folder_add.png new file mode 100644 index 0000000000000000000000000000000000000000..529fe8fe04c5b750ce3b4d48118465d73c74c970 GIT binary patch literal 668 zcmV;N0%QG&P)g@#5J*h%>dq^uaFBvVQ$3&c*y#>&P@VnG_z zkezqQ&je1b~~$O}L9 zo^;|X_f#3CS5n-cFHBf|3c+u^PpWoka6G0Rsr|AOXUJ zbHD{5nUGu>5YB96PUmjGgM{$-j5TbT8bBGbz2R zHjvpHkWu0*cCs9&;{|Ugi`d3|T+)Vj%kXX`qqQ>4W)|B!_mMlW`2x#YyU0W#8Pyvn z-<;pE4zUG8k-yYxmFW4%eIAbtF|hR_$8YW;YMMc&ZY1$9z5S(QZA)e!-q6)Y`+^>Z zzdYprlOaC7jZYg%{Ey!L(s5u9Pz1(+vk%UU4EzNDb1nO~@as(g0000 ' + newid); } else { @@ -89,11 +89,12 @@ var cleanID = function (id) { }; /** - * Initialize the drag & drop-tree starting at the given ul (must be this). + * Initialize the drag & drop-tree at the given li (must be this). */ var initTree = function () { - var my_root = jQuery(this).closest('.tree_root')[0]; - jQuery(this).find('li').draggable({ + var $li = jQuery(this); + var my_root = $li.closest('.tree_root')[0]; + $li.draggable({ revert: true, revertDuration: 0, opacity: 0.5, @@ -145,9 +146,13 @@ var initTree = function () { } }) // add title to rename icon - .find('img').attr('title', LANG.plugins.move.renameitem); + .find('img.rename').attr('title', LANG.plugins.move.renameitem) + .end() + .find('img.add').attr('title', LANG.plugins.move.add); }; +var add_template = '
    • '; + /** * Attach event listeners to the tree */ @@ -180,7 +185,7 @@ $GUI.find('div.tree_root > ul.tree_list') }, function (data) { $li.append(data); - $li.children('ul').each(initTree); + $li.find('li').each(initTree); } ); } @@ -190,20 +195,35 @@ $GUI.find('div.tree_root > ul.tree_list') e.stopPropagation(); var $a = $clicky.parent().find('a'); - var newname = window.prompt(LANG.plugins.move.renameitem, $li.data('name')); - newname = cleanID(newname); - if (newname) { - if (checkNameAllowed($li, $li.parent(), newname)) { - $li.data('name', newname); - $a.text(newname); - checkForMovement($li); - } else { - alert(LANG.plugins.move.duplicate.replace('%s', newname)); + if ($clicky.hasClass('rename')) { + var newname = window.prompt(LANG.plugins.move.renameitem, $li.data('name')); + newname = cleanID(newname); + if (newname) { + if (checkNameAllowed($li, $li.parent(), newname)) { + $li.data('name', newname); + $a.text(newname); + checkForMovement($li); + } else { + alert(LANG.plugins.move.duplicate.replace('%s', newname)); + } + } + } else { + var newname = window.prompt(LANG.plugins.move.add); + newname = cleanID(newname); + if (newname) { + if (checkNameAllowed($li, $li.children('ul'), newname)) { + var $new_li = jQuery(add_template.replace(/%s/g, newname)); + $li.children('ul').prepend($new_li); + + $new_li.each(initTree); + } else { + alert(LANG.plugins.move.duplicate.replace('%s', newname)); + } } } e.preventDefault(); } - }).each(initTree); + }).find('li').each(initTree); /** * Gather all moves from the trees and put them as JSON into the form before submit diff --git a/style.less b/style.less index 32764a7..5a7dfbb 100644 --- a/style.less +++ b/style.less @@ -19,7 +19,7 @@ } ul.tree_list { - .moved > div { + .moved > div, .created > div { border: 1px dashed lighten(@ini_text, 30%); border-radius: 3px; margin-left: -3px; From d638c458484aeafec74be4f99525ad7ac3e64ee8 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 7 Jan 2017 17:48:38 +0100 Subject: [PATCH 256/338] Add icon sources/license --- README | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README b/README index 8028d59..112c7e9 100644 --- a/README +++ b/README @@ -26,4 +26,28 @@ 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. -See the COPYING file in your DokuWiki folder for details \ No newline at end of file +See the COPYING file in your DokuWiki folder for details + +Sources of the icons contained in images/: + +disk.png +folder_add.png +page.png +page_link.png + +Silk icon set 1.3 + +_________________________________________ +Mark James +http://www.famfamfam.com/lab/icons/silk/ +_________________________________________ + +Licensed under a +Creative Commons Attribution 2.5 License. +[ http://creativecommons.org/licenses/by/2.5/ ] + + +rename.png + +SEMLabs Free Web Design Icon Set, +http://semlabs.co.uk/blog/free-web-design-icon-set/ \ No newline at end of file From 06b7ca40382938ebdd466c283d150452d1e7014e Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sat, 7 Jan 2017 17:29:56 +0100 Subject: [PATCH 257/338] New version 2017-01-07 released This version contains an improved tree move ui: * Multiple items can be selected and moved together. * New namespaces can be created (currently only in the root namespace, but they can be moved and renamed later). --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index 33e3bc6..ffbbaa8 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2017-01-02 +date 2017-01-07 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 2f859ee90d28e8f6f8fcaf54e73f7a6aece4be97 Mon Sep 17 00:00:00 2001 From: Hideaki SAWADA Date: Wed, 11 Jan 2017 18:15:32 +0100 Subject: [PATCH 258/338] translation update --- lang/ja/lang.php | 3 ++- lang/ja/settings.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lang/ja/lang.php b/lang/ja/lang.php index 1b3f6d0..8b3adf8 100644 --- a/lang/ja/lang.php +++ b/lang/ja/lang.php @@ -2,7 +2,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Hideaki SAWADA */ $lang['menu'] = 'ページ・名前空間の移動'; @@ -58,6 +58,7 @@ $lang['js']['inprogress'] = 'ページの名称変更・リンクの書き換え中…'; $lang['js']['complete'] = '名称変更操作が完了しました。'; $lang['js']['renameitem'] = 'この項目を名称変更します。'; +$lang['js']['add'] = '新しい名前空間の作成'; $lang['js']['duplicate'] = '"%s" はこの名前空間内に既に存在します。'; $lang['root'] = '[ルート名前空間]'; $lang['noscript'] = 'この機能には JavaScriptが必要です。'; diff --git a/lang/ja/settings.php b/lang/ja/settings.php index bdac41b..7a31427 100644 --- a/lang/ja/settings.php +++ b/lang/ja/settings.php @@ -2,10 +2,11 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Hideaki SAWADA */ $lang['allowrename'] = 'ページ名変更を許可するグループ・ユーザー(カンマ区切り)'; $lang['minor'] = 'リンクの書き換えを小変更扱いにする。小変更にすると RSS 配信・メール更新通知には表示されない。'; $lang['autoskip'] = '名前空間移動時のエラーの自動スキップ。デフォルトは有効。'; $lang['autorewrite'] = '名前空間移動後のリンクの自動書き換え。デフォルトは有効。'; +$lang['pagetools_integration'] = '名称変更ボタンのページツールへの追加'; From bb3346cace45f00f0101943d465d7b044a46e213 Mon Sep 17 00:00:00 2001 From: Arne Hanssen Date: Sun, 29 Jan 2017 11:40:31 +0100 Subject: [PATCH 259/338] translation update --- lang/no/lang.php | 4 +++- lang/no/move.txt | 7 +++++-- lang/no/settings.php | 6 ++++-- lang/no/tree.txt | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lang/no/lang.php b/lang/no/lang.php index ebc177c..4fd7235 100644 --- a/lang/no/lang.php +++ b/lang/no/lang.php @@ -2,11 +2,12 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Daniel * @author Daniel Raknes * @author Christopher Schive * @author Daniel Raknes + * @author Arne Hanssen */ $lang['menu'] = 'Flytt sider og navnerom'; $lang['inprogress'] = '(flytting avventer)'; @@ -61,6 +62,7 @@ $lang['js']['inprogress'] = 'endrer navn på side og justerer lenker...'; $lang['js']['complete'] = 'Flytting avsluttet'; $lang['js']['renameitem'] = 'Endre navn '; +$lang['js']['add'] = 'Lag et nytt navnerom'; $lang['js']['duplicate'] = 'Beklager, "%s" finnes allerede i dette navnerommet.'; $lang['root'] = '[Rot navnerom]'; $lang['noscript'] = 'Denne funksjonen krever Javascript'; diff --git a/lang/no/move.txt b/lang/no/move.txt index 5448485..b056d99 100644 --- a/lang/no/move.txt +++ b/lang/no/move.txt @@ -1,7 +1,10 @@ ====== Flytt ====== -Denne plugin lar deg flytte og/eller endre navn på siden og/eller endre navn må navnerom med følgende restriksjoner: +Denne programutvidelse lar deg flytte og/eller endre navn på siden og/eller endre navn må navnerom med følgende restriksjoner: + * Du må ha redigeringsrettigheter til siden/sidene i navnerommet. * Sidene som flyttes må ikke være låst for redigering. * Du må også ha redigeringsrettigheter til navnerommet siden/sidene flyttes til. - * Du kan ikke flytte en side til et navnerom som inneholder en side med samme navn. Alle lenker til og fra siden vil bli oppdatert ved flytting. \ No newline at end of file + * Du kan ikke flytte en side til et navnerom som inneholder en side med samme navn. + +Alle lenker til og fra siden vil bli oppdatert ved flytting. diff --git a/lang/no/settings.php b/lang/no/settings.php index 818e4bb..2a36cee 100644 --- a/lang/no/settings.php +++ b/lang/no/settings.php @@ -2,10 +2,12 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Daniel Raknes + * @author Arne Hanssen */ -$lang['allowrename'] = 'Tillatt navenendring på disse sidene for disse gruppene og brukerne (separert med komma)'; +$lang['allowrename'] = 'Tillatt navenendring på disse sidene for disse gruppene og brukerne (separert med komma).'; $lang['minor'] = 'Merk lenkejusteringer som liten endring? Små endringer vil ikke bli listet i RSS eller varslet til de som abonnerer på endringseposter. '; $lang['autoskip'] = 'Tillatt automatisk ignorering av feil i navnerom som standard.'; $lang['autorewrite'] = 'Tillatt automatisk lenkeoppdatering etter flytting av navnerom som standard.'; +$lang['pagetools_integration'] = 'Legg til knapp for å endre navn i sideverktøyet'; diff --git a/lang/no/tree.txt b/lang/no/tree.txt index f8eb6c0..c2e9f21 100644 --- a/lang/no/tree.txt +++ b/lang/no/tree.txt @@ -1,3 +1,3 @@ ====== Move Manager ===== -Denne dialogen tillater deg å flytte din wikis navnerom, sider og mediafiler via "dra og slipp". \ No newline at end of file +Denne dialogen tillater deg å flytte din wikis navnerom, sider og mediafiler ved hjelp av «dra og slipp». \ No newline at end of file From 9d8722f0d3076c7d7f2192afb7a4e7308319b071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schplurtz=20le=20D=C3=A9boulonn=C3=A9?= Date: Tue, 14 Feb 2017 06:50:42 +0100 Subject: [PATCH 260/338] translation update --- lang/fr/lang.php | 3 ++- lang/fr/settings.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lang/fr/lang.php b/lang/fr/lang.php index 9de99f4..5b5c59e 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -2,7 +2,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Gary Owen * @author Nicolas Friedli * @author Schplurtz le Déboulonné @@ -60,6 +60,7 @@ $lang['js']['inprogress'] = 'Renommage des pages et ajustement des pages en cours...'; $lang['js']['complete'] = 'Déplacement effectué.'; $lang['js']['renameitem'] = 'Renommer cet élément'; +$lang['js']['add'] = 'Créer une nouvelle catégorie'; $lang['js']['duplicate'] = 'Désolé, "%s" existe dans cette catégorie.'; $lang['root'] = '[Catégorie racine]'; $lang['noscript'] = 'Cette fonction requiert JavaScript'; diff --git a/lang/fr/settings.php b/lang/fr/settings.php index ec63d0f..19918ff 100644 --- a/lang/fr/settings.php +++ b/lang/fr/settings.php @@ -2,10 +2,11 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Schplurtz le Déboulonné */ $lang['allowrename'] = 'Autoriser le renommage de page à ces utilisateurs et groupes (utiliser des virgules)'; $lang['minor'] = 'Noter les ajustements de liens comme des modifications mineures. Les modifications mineures ne sont indiquées ni dans les flux RSS, ni dans les courriels des abonnements.'; $lang['autoskip'] = 'Par défaut, ignorer les erreurs de déplacement de catégories.'; $lang['autorewrite'] = 'Activer par défaut la ré-écriture automatique des liens après déplacement de catégories.'; +$lang['pagetools_integration'] = 'Ajouter un bouton "renommage" aux outils de page'; From 5e5dd9d24ef3bfc24425051407e43322b28c4a28 Mon Sep 17 00:00:00 2001 From: kuma Date: Sat, 25 Feb 2017 13:40:41 +0100 Subject: [PATCH 261/338] translation update --- lang/zh/lang.php | 10 +++++++++- lang/zh/settings.php | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lang/zh/lang.php b/lang/zh/lang.php index 5594e3f..c2ee93e 100644 --- a/lang/zh/lang.php +++ b/lang/zh/lang.php @@ -2,10 +2,11 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Gary Owen * @author TombCrow * @author Hanjia Zhuang + * @author kuma */ $lang['menu'] = '页面移动/重命名……'; $lang['inprogress'] = '(待移动)'; @@ -21,6 +22,12 @@ $lang['medianotchanged'] = '未为页面%s指定新地址(位置未变)'; $lang['mediaexists'] = '媒体文件%s无法被移动至%s,目标已存在。'; $lang['nomediatargetperms'] = '您没有权限创建媒体文件%s。'; +$lang['indexerror'] = '当更新搜索索引 %s 时发生错误'; +$lang['metamoveerror'] = 'meta文件的页面 %s 无法移动'; +$lang['atticmoveerror'] = '页面文件 %s 的attic文件无法移动。请手动移动它们。'; +$lang['mediametamoveerror'] = '媒体文件 %s 的meta文件无法移动'; +$lang['mediamoveerror'] = '移动媒体文件 %s 失败'; +$lang['mediaatticmoveerror'] = '媒体文件 %s 的attic文件无法移动。请手动移动它们。'; $lang['renamed'] = '页面名由%s改为%s'; $lang['moved'] = '页面%s被移动至%s'; $lang['move_rename'] = '页面%s被移动并更名为%s'; @@ -54,6 +61,7 @@ $lang['js']['inprogress'] = '重命名页面并修正有关链接:'; $lang['js']['complete'] = '移动操作完毕。'; $lang['js']['renameitem'] = '重命名该项'; +$lang['js']['add'] = '创建一个新的名称空间'; $lang['js']['duplicate'] = '抱歉,"%s"在该目录已存在'; $lang['root'] = '[跟目录]'; $lang['noscript'] = '该功能需要JavaScript'; diff --git a/lang/zh/settings.php b/lang/zh/settings.php index 29adc7e..6c8609b 100644 --- a/lang/zh/settings.php +++ b/lang/zh/settings.php @@ -2,10 +2,12 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * * @author Hanjia Zhuang + * @author kuma */ $lang['allowrename'] = '允许这些用户/用户组重命名页面(用逗号分隔)'; $lang['minor'] = '将链接修正标记为”细微变动“,这样就不会被列入RSS订阅或订阅邮件中。'; $lang['autoskip'] = '在目录移动中,启用默认自动跳过错误'; $lang['autorewrite'] = '在目录移动中,启用默认自动修正链接'; +$lang['pagetools_integration'] = '重命名按钮添加到页面工具'; From dcf6d3e7684cfe1f08d42e58aa397061f7c807d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20R=C5=AF=C5=BEi=C4=8Dka?= Date: Thu, 16 Mar 2017 14:55:41 +0100 Subject: [PATCH 262/338] translation update --- lang/cs/lang.php | 145 ++++++++++++++++++------------------------- lang/cs/progress.txt | 2 +- lang/cs/settings.php | 10 +-- 3 files changed, 67 insertions(+), 90 deletions(-) diff --git a/lang/cs/lang.php b/lang/cs/lang.php index efa045f..0b6520e 100644 --- a/lang/cs/lang.php +++ b/lang/cs/lang.php @@ -1,88 +1,65 @@ stromového manažeru přesunu.'; - -// page errors -$lang['notexist'] = 'Stránka \'%s\' neexistuje.'; -$lang['norights'] = 'Nedostatečné oprávnění editovat \'%s\'.'; -$lang['filelocked'] = 'Stránka \'%s\' je uzamčna - zkuste prosím znovu později.'; -$lang['notchanged'] = 'Žádný cíl pro stránku \'%s\' (umístění nezměněno).'; -$lang['exists'] = 'Stránku \'%s\' nelze přesunout do \'%s\', cíl již existuje.'; -$lang['notargetperms'] = 'Nemáte oprávnění vytvořit stránku \'%s\'.'; - -// media errors -$lang['medianotexist'] = 'Médium \'%s\' neexistuje.'; -$lang['nomediarights'] = 'Nedostatečné oprávnění ke smazání \'%s\'.'; -$lang['medianotchanged'] = 'Žádný cíl pro médium \'%s\' (umístění nezměněno).'; -$lang['mediaexists'] = 'Médium \'%s\' nelze přesunout do \'%s\', cíl již existuje.'; -$lang['nomediatargetperms'] = 'Nemáte oprávnění vytvořit médium \'%s\'.'; - -// system errors -$lang['indexerror'] = 'Chyba při aktualizaci search index \'%s\'.'; -$lang['metamoveerror'] = 'Meta soubory stránky \'%s\' nemohou být přesunut.'; -$lang['atticmoveerror'] = 'Staré verze stránky \'%s\' nemohou být přesunuty. Prosím, přsuňte je ručně.'; -$lang['mediametamoveerror'] = 'Meta soubory média \'%s\' nemohou být přesunuty.'; -$lang['mediamoveerror'] = 'Přesunutí média \'%s\' selhalo.'; -$lang['mediaatticmoveerror'] = 'Staré verze média \'%s\' nemohou být přesunuty. Prosím, přsuňte je ručně.'; - -// changelog summaries -$lang['renamed'] = 'Stránka přejmenována z \'%s\' na \'%s\''; -$lang['moved'] = 'Stránka přesunuta z \'%s\' do \'%s\''; -$lang['move_rename'] = 'Stránka přesunuta a přejmenována z \'%s\' do \'%s\''; -$lang['delete'] = 'Smazáno pluginem move'; -$lang['linkchange'] = 'Odkaz upraven z důvodu přesunutí'; - -// progress view -$lang['intro'] = 'Přesun dosud nebyl zahájen!'; -$lang['preview'] = 'Náhled změn, které budou provedeny.'; -$lang['inexecution'] = 'Předchozí přesun nebyl dokončen - použijte tlačítko dole k pokračování či přerušení přesunu.'; -$lang['btn_start'] = 'Start'; -$lang['btn_continue'] = 'Pokračovat'; -$lang['btn_retry'] = 'Znovu'; -$lang['btn_skip'] = 'Přeskočit položku'; -$lang['btn_abort'] = 'Přerušit'; - -// Form labels -$lang['legend'] = 'Přesunout aktuální stránku nebo jmenný prostor'; -$lang['movepage'] = 'Přesunout stránku'; -$lang['movens'] = 'Přesunout aktuální jmenný prostor'; -$lang['dst'] = 'Nové jméno:'; -$lang['content_to_move'] = 'Obsah k přesunutí:'; -$lang['autoskip'] = 'Ignorovat chyby a přeskočit stránky a média, které nemohou být přesunuty'; -$lang['autorewrite'] = 'Přepsat odkazy po úspěšmén přesunu'; -$lang['move_pages'] = 'Stránky'; -$lang['move_media'] = 'Média'; -$lang['move_media_and_pages'] = 'Stránky a média'; -$lang['nodst'] = 'Žádné nové jméno'; -$lang['noaction'] = 'Nebyl definován přesun'; - -// Rename feature -$lang['renamepage'] = 'Přejmenovat stránku'; -$lang['cantrename'] = 'Stránka nemůže být právě přejmenována. Zkuste to později.'; -$lang['js']['rename'] = 'Přejmenovat'; -$lang['js']['cancel'] = 'Zrušit'; -$lang['js']['newname'] = 'Nový název stránky:'; -$lang['js']['inprogress'] = 'Přesouvám stránky a upravuji odkazy...'; -$lang['js']['complete'] = 'Přesun byl dokončen.'; - -// Tree Manager -$lang['root'] = '[Kořen]'; -$lang['noscript'] = 'Tato vlastost vyžaduje JavaScript'; -$lang['moveinprogress'] = 'Právě probíhá jiný přsun, proto nyní nemůžete použít tento nástroj.'; -$lang['js']['renameitem'] = 'Přejmenovat tuto položku'; -$lang['js']['duplicate'] = 'Lituji, ale \'%s\' již existuje ve jmenném prosoru.'; - - +$lang['menu'] = 'Přesun/přejmenování stránky'; +$lang['inprogress'] = '(probíhá přesun)'; +$lang['treelink'] = 'Alternativou k tomuto jednoduchému formuláři můžete použít komplexní přeskupení vaší wiki pomocí stromového manažeru přesunu.'; +$lang['notexist'] = 'Stránka \'%s\' neexistuje.'; +$lang['norights'] = 'Nedostatečné oprávnění editovat \'%s\'.'; +$lang['filelocked'] = 'Stránka \'%s\' je uzamčna - zkuste prosím znovu později.'; +$lang['notchanged'] = 'Žádný cíl pro stránku \'%s\' (umístění nezměněno).'; +$lang['exists'] = 'Stránku \'%s\' nelze přesunout do \'%s\', cíl již existuje.'; +$lang['notargetperms'] = 'Nemáte oprávnění vytvořit stránku \'%s\'.'; +$lang['medianotexist'] = 'Médium \'%s\' neexistuje.'; +$lang['nomediarights'] = 'Nedostatečné oprávnění ke smazání \'%s\'.'; +$lang['medianotchanged'] = 'Žádný cíl pro médium \'%s\' (umístění nezměněno).'; +$lang['mediaexists'] = 'Médium \'%s\' nelze přesunout do \'%s\', cíl již existuje.'; +$lang['nomediatargetperms'] = 'Nemáte oprávnění vytvořit médium \'%s\'.'; +$lang['indexerror'] = 'Chyba při aktualizaci search index \'%s\'.'; +$lang['metamoveerror'] = 'Meta soubory stránky \'%s\' nemohou být přesunut.'; +$lang['atticmoveerror'] = 'Staré verze stránky \'%s\' nemohou být přesunuty. Prosím, přsuňte je ručně.'; +$lang['mediametamoveerror'] = 'Meta soubory média \'%s\' nemohou být přesunuty.'; +$lang['mediamoveerror'] = 'Přesunutí média \'%s\' selhalo.'; +$lang['mediaatticmoveerror'] = 'Staré verze média \'%s\' nemohou být přesunuty. Prosím, přsuňte je ručně.'; +$lang['renamed'] = 'Stránka přejmenována z \'%s\' na \'%s\''; +$lang['moved'] = 'Stránka přesunuta z \'%s\' do \'%s\''; +$lang['move_rename'] = 'Stránka přesunuta a přejmenována z \'%s\' do \'%s\''; +$lang['delete'] = 'Smazáno pluginem move'; +$lang['linkchange'] = 'Odkaz upraven z důvodu přesunutí'; +$lang['intro'] = 'Přesun dosud nebyl zahájen!'; +$lang['preview'] = 'Náhled změn, které budou provedeny.'; +$lang['inexecution'] = 'Předchozí přesun nebyl dokončen - použijte tlačítko dole k pokračování či přerušení přesunu.'; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Pokračovat'; +$lang['btn_retry'] = 'Znovu'; +$lang['btn_skip'] = 'Přeskočit položku'; +$lang['btn_abort'] = 'Přerušit'; +$lang['legend'] = 'Přesunout aktuální stránku nebo jmenný prostor'; +$lang['movepage'] = 'Přesunout stránku'; +$lang['movens'] = 'Přesunout aktuální jmenný prostor'; +$lang['dst'] = 'Nové jméno:'; +$lang['content_to_move'] = 'Obsah k přesunutí:'; +$lang['autoskip'] = 'Ignorovat chyby a přeskočit stránky a média, které nemohou být přesunuty'; +$lang['autorewrite'] = 'Přepsat odkazy po úspěšmén přesunu'; +$lang['move_pages'] = 'Stránky'; +$lang['move_media'] = 'Média'; +$lang['move_media_and_pages'] = 'Stránky a média'; +$lang['nodst'] = 'Žádné nové jméno'; +$lang['noaction'] = 'Nebyl definován přesun'; +$lang['renamepage'] = 'Přejmenovat stránku'; +$lang['cantrename'] = 'Stránka nemůže být právě přejmenována. Zkuste to později.'; +$lang['js']['rename'] = 'Přejmenovat'; +$lang['js']['cancel'] = 'Zrušit'; +$lang['js']['newname'] = 'Nový název stránky:'; +$lang['js']['inprogress'] = 'Přesouvám stránky a upravuji odkazy...'; +$lang['js']['complete'] = 'Přesun byl dokončen.'; +$lang['js']['renameitem'] = 'Přejmenovat tuto položku'; +$lang['js']['duplicate'] = 'Lituji, ale \'%s\' již existuje ve jmenném prosoru.'; +$lang['root'] = '[Kořen]'; +$lang['noscript'] = 'Tato vlastost vyžaduje JavaScript'; +$lang['moveinprogress'] = 'Právě probíhá jiný přsun, proto nyní nemůžete použít tento nástroj.'; diff --git a/lang/cs/progress.txt b/lang/cs/progress.txt index 209f27a..3ac1e43 100644 --- a/lang/cs/progress.txt +++ b/lang/cs/progress.txt @@ -1,3 +1,3 @@ ====== Probíhá přesun... ====== -Prosím nazavírejte tuto stránku, dokud přesun neskončí. \ No newline at end of file +Prosím nezavírejte tuto stránku, dokud přesun neskončí. \ No newline at end of file diff --git a/lang/cs/settings.php b/lang/cs/settings.php index acd5926..0a6d83e 100644 --- a/lang/cs/settings.php +++ b/lang/cs/settings.php @@ -1,11 +1,11 @@ Date: Tue, 23 May 2017 15:35:23 +0200 Subject: [PATCH 263/338] translation update --- lang/hr/lang.php | 1 + lang/hr/settings.php | 1 + 2 files changed, 2 insertions(+) diff --git a/lang/hr/lang.php b/lang/hr/lang.php index 0deb1e6..ad9f222 100644 --- a/lang/hr/lang.php +++ b/lang/hr/lang.php @@ -58,6 +58,7 @@ $lang['js']['inprogress'] = 'preimenovanje stranice i prilagodba poveznica...'; $lang['js']['complete'] = 'Operacija premještanja završila.'; $lang['js']['renameitem'] = 'Preimenuj ovu stavku'; +$lang['js']['add'] = 'Kreiraj novi imenski prostor'; $lang['js']['duplicate'] = 'Isprika ali "%s" već postoji u ovom imenskom prostoru'; $lang['root'] = '[Korijen imenskog prostora]'; $lang['noscript'] = 'Ova osobina zahtijeva JavaScript'; diff --git a/lang/hr/settings.php b/lang/hr/settings.php index 2c854ae..fac20b6 100644 --- a/lang/hr/settings.php +++ b/lang/hr/settings.php @@ -10,3 +10,4 @@ $lang['autoskip'] = 'Omogući kao podrazumijevano automatsko preskakanje grešaka pri premještanju imenskog prostora.'; $lang['autorewrite'] = 'Omogući kao podrazumijevano automatsku prilagodbu poveznica. '; +$lang['pagetools_integration'] = 'Dodaj tipku za preimenovanje na alate stranice'; From 98a0e35f50d078f8360577e38baad67302eafeea Mon Sep 17 00:00:00 2001 From: Jaemin Kim Date: Thu, 25 May 2017 12:05:29 +0200 Subject: [PATCH 264/338] translation update --- lang/ko/lang.php | 2 ++ lang/ko/settings.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lang/ko/lang.php b/lang/ko/lang.php index f080d62..3396dcd 100644 --- a/lang/ko/lang.php +++ b/lang/ko/lang.php @@ -5,6 +5,7 @@ * * @author Gary Owen * @author Myeongjin + * @author Jaemin Kim */ $lang['menu'] = '문서와 이름공간 이동'; $lang['inprogress'] = '(이동 보류 중)'; @@ -59,6 +60,7 @@ $lang['js']['inprogress'] = '문서의 이름을 바꾸고 링크를 조절하는 중...'; $lang['js']['complete'] = '이동 작업이 완료되었습니다.'; $lang['js']['renameitem'] = '이 항목 이름 바꾸기'; +$lang['js']['add'] = '새 이름공간 만들기'; $lang['js']['duplicate'] = '죄송하지만, "%s" 문서는 이미 이 이름공간에 존재합니다.'; $lang['root'] = '[루트 이름공간]'; $lang['noscript'] = '이 기능은 자바스크립트가 필요합니다'; diff --git a/lang/ko/settings.php b/lang/ko/settings.php index e5dbc42..6c88357 100644 --- a/lang/ko/settings.php +++ b/lang/ko/settings.php @@ -4,8 +4,10 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * * @author Myeongjin + * @author Jaemin Kim */ $lang['allowrename'] = '문서의 이름을 바꿀 수 있는 그룹 및 사용자. (쉼표로 구분)'; $lang['minor'] = '링크 조절을 사소한 바뀜으로 표시하겠습니까? 사소한 바뀜은 RSS 피드와 구독 메일에 나열되지 않을 것입니다.'; $lang['autoskip'] = '기본적으로 이름공간 이동에서 오류를 자동으로 건너뛰도록 활성화합니다.'; $lang['autorewrite'] = '기본적으로 이름공간을 이동하고 나서 자동으로 링크 다시 쓰기를 활성화합니다.'; +$lang['pagetools_integration'] = '페이지도구에 이름 새로짓기 버튼 추가하기'; From 21fd566c648083ded025bc1fa764c63b2838f69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=BCller?= Date: Tue, 13 Jun 2017 09:50:02 +0200 Subject: [PATCH 265/338] enlarge newname input field #117 --- script/rename.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script/rename.js b/script/rename.js index 9fd4536..e616301 100644 --- a/script/rename.js +++ b/script/rename.js @@ -46,8 +46,8 @@ if(JSINFO.move_renameokay) var $dialog = jQuery( '
      ' + '
      ' + - '
      ' @@ -58,7 +58,7 @@ if(JSINFO.move_renameokay) // set up the dialog $dialog.dialog({ title: LANG.plugins.move.rename+' '+JSINFO.id, - width: 340, + width: 800, height: 180, dialogClass: 'plugin_move_dialog', modal: true, From b5e7779cedb6916037cdcacb304b867e2a4db699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20H=C3=A4rnqvist?= Date: Mon, 17 Jul 2017 21:45:31 +0200 Subject: [PATCH 266/338] translation update --- lang/sv/lang.php | 105 +++++++++++++++++++------------------------ lang/sv/progress.txt | 3 ++ lang/sv/settings.php | 9 ++++ 3 files changed, 59 insertions(+), 58 deletions(-) create mode 100644 lang/sv/progress.txt create mode 100644 lang/sv/settings.php diff --git a/lang/sv/lang.php b/lang/sv/lang.php index 787d5fe..281223f 100644 --- a/lang/sv/lang.php +++ b/lang/sv/lang.php @@ -1,62 +1,51 @@ + * + * @author Gary Owen + * @author Tor Härnqvist */ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Flytt/Namnbyte på Sida/Namnrymd...'; -$lang['desc'] = 'Plugin för Flytt/Namnbyte på Sida/Namnrymd...'; - -$lang['notexist'] = 'Sidan %s finns inte'; -$lang['medianotexist'] = 'Media filen %s finns inte'; -$lang['notwrite'] = 'Du har inte tillräcklig behörighet att ändar på den här sidan'; -$lang['badns'] = 'Otillåtet tecken i namnrymd.'; -$lang['badname'] = 'Otillåtet tecken i sidnamn.'; -$lang['nochange'] = 'Sid- och namnrymdsnamn är inte ändrade'; -$lang['nomediachange'] = 'Mediafil- och namnrymdsnamn är inte ändrade'; -$lang['existing'] = 'En sida som heter %s finns redan i %s'; -$lang['mediaexisting'] = 'En mediafil som heter %s finns redan i %s'; -$lang['root'] = '[Rotnamnrymd]'; -$lang['current'] = '[Nuvarande]'; -$lang['renamed'] = 'Sidnamn ändrat från %s till %s'; -$lang['moved'] = 'Sida flyttad från %s till %s'; -$lang['move_rename'] = 'Sida flyttad och namnändrad från %s till %s'; -$lang['delete'] = 'Borttagen av pluginen'; -$lang['norights'] = 'Du har inte tillräcklig behörighet för att ändra %s.'; -$lang['nomediarights'] = 'Du har inte tillräcklig behörighet att ta bort %s.'; -$lang['notargetperms'] = 'Du har inte tillräcklig behörighet för att skapa sidan %s.'; -$lang['nomediatargetperms'] = 'Du har inte tillräcklig behörighet för att skapa mediafilen %s.'; -$lang['filelocked'] = 'Sidan %s är låst. Försök senare.'; -$lang['linkchange'] = 'Länkar som ändrats på grund av flytt/namnändring'; - -$lang['ns_move_in_progress'] = 'En namnrymdsflytt eller namnändring av %s sidor och %s mediafiler pågår.'; -$lang['ns_move_continue'] = 'Fortsätt flytt av namnrymd'; -$lang['ns_move_abort'] = 'Avbryt flytt av namnrymd'; -$lang['ns_move_continued'] = 'Namnrymdsflytt från %s till %s pågår, %s åtgärder återstår.'; -$lang['ns_move_started'] = 'En namnrymdsflytt från %s till %s har startat, %s sidor och %s mediafiler kommer att flyttas.'; -$lang['ns_move_error'] = 'Ett fel uppstod under namnrymdsflytt från %s till %s.'; -$lang['ns_move_tryagain'] = 'Försök igen'; -$lang['ns_move_skip'] = 'Hoppa över nuvarande åtgärd'; -// Form labels -$lang['newname'] = 'Nytt sidnamn:'; -$lang['newnsname'] = 'Nytt namn för namnrymden:'; -$lang['targetns'] = 'Välj ny namnrymd:'; -$lang['newtargetns'] = 'Skapa ny namnrymd:'; -$lang['movepage'] = 'Flytta sida'; -$lang['movens'] = 'Flytta namnrymd'; -$lang['submit'] = 'Genomför'; -$lang['content_to_move'] = 'Innehåll att flytta'; -$lang['move_pages'] = 'Sidor'; -$lang['move_media'] = 'Mediafiler'; -$lang['move_media_and_pages'] = 'Sidor och mediafiler'; -// JavaScript preview -$lang['js']['previewpage'] = 'OLDPAGE kommer att flyttas till NEWPAGE'; -$lang['js']['previewns'] = 'Alla sidor och namnrymder i namnrymden OLDNS kommer att flyttas till namnrymden NEWNS'; +$lang['menu'] = 'Flytt/Namnbyte på Sida/Namnrymd...'; +$lang['notexist'] = 'Sidan %s finns inte'; +$lang['norights'] = 'Du har inte tillräcklig behörighet för att ändra %s.'; +$lang['filelocked'] = 'Sidan %s är låst. Försök senare.'; +$lang['notargetperms'] = 'Du har inte tillräcklig behörighet för att skapa sidan %s.'; +$lang['medianotexist'] = 'Media filen %s finns inte'; +$lang['nomediarights'] = 'Du har inte tillräcklig behörighet att ta bort %s.'; +$lang['nomediatargetperms'] = 'Du har inte tillräcklig behörighet för att skapa mediafilen %s.'; +$lang['indexerror'] = 'Fel när sökindex %s uppdaterades'; +$lang['metamoveerror'] = 'Metafilerna för sidorna %s kunde inte flyttas'; +$lang['renamed'] = 'Sidnamn ändrat från %s till %s'; +$lang['moved'] = 'Sida flyttad från %s till %s'; +$lang['move_rename'] = 'Sida flyttad och namnändrad från %s till %s'; +$lang['delete'] = 'Borttagen av pluginen'; +$lang['linkchange'] = 'Länkar som ändrats på grund av flytt/namnändring'; +$lang['preview'] = 'Förhandsvisa ändringar att utföra '; +$lang['btn_start'] = 'Starta'; +$lang['btn_continue'] = 'Fortsätt'; +$lang['btn_skip'] = 'Hoppa över post'; +$lang['btn_abort'] = 'Avbryt'; +$lang['legend'] = 'Flytta nuvarande sida eller namnrymd'; +$lang['movepage'] = 'Flytta sida'; +$lang['movens'] = 'Flytta namnrymd'; +$lang['dst'] = 'Nytt namn:'; +$lang['content_to_move'] = 'Innehåll att flytta'; +$lang['autoskip'] = 'Ignorera fel och hoppa över sidor eller filer som inte kunde flyttas'; +$lang['autorewrite'] = 'Skriv om länkar efter att flytt/namnbyte genomförts'; +$lang['move_pages'] = 'Sidor'; +$lang['move_media'] = 'Mediafiler'; +$lang['move_media_and_pages'] = 'Sidor och mediafiler'; +$lang['nodst'] = 'Inget nytt namn är angett'; +$lang['renamepage'] = 'Byt namn på sida'; +$lang['cantrename'] = 'Kan inte byta namn på sidan just nu. Var god försök senare.'; +$lang['js']['rename'] = 'Byt namn'; +$lang['js']['cancel'] = 'Avbryt'; +$lang['js']['newname'] = 'Nytt namn:'; +$lang['js']['inprogress'] = 'ändra namn och justera länkar...'; +$lang['js']['complete'] = 'Flytt/Namnbyte avklarat.'; +$lang['js']['renameitem'] = 'Ändra namn på denna post'; +$lang['js']['add'] = 'Skapa en ny namnrymd'; +$lang['js']['duplicate'] = 'Tyvärr, "%s" existerar redan i denna namnrymd.'; +$lang['root'] = '[Rotnamnrymd]'; +$lang['noscript'] = 'Denna funktion kräver JavaScript.'; diff --git a/lang/sv/progress.txt b/lang/sv/progress.txt new file mode 100644 index 0000000..fd00db7 --- /dev/null +++ b/lang/sv/progress.txt @@ -0,0 +1,3 @@ +====== Flytt/namnbyte pågår... ====== + +Var god håll den här sidan öppen medan flytten/namnbytet pågår. \ No newline at end of file diff --git a/lang/sv/settings.php b/lang/sv/settings.php new file mode 100644 index 0000000..edb281d --- /dev/null +++ b/lang/sv/settings.php @@ -0,0 +1,9 @@ + + */ +$lang['allowrename'] = 'Tillåt namnbyte på sidor i dessa grupper och från användare (kommaseparerat).'; +$lang['pagetools_integration'] = 'Lägg till namnändringsknapp till sidverktygen'; From 8953fad3c5be558ca4684856eaca3fd0a5f92038 Mon Sep 17 00:00:00 2001 From: Domingo Redal Date: Tue, 26 Sep 2017 18:20:27 +0200 Subject: [PATCH 267/338] translation update --- lang/es/lang.php | 92 ++++++++++++++++++++++++++++++-------------- lang/es/move.txt | 10 ++--- lang/es/progress.txt | 3 ++ lang/es/settings.php | 12 ++++++ lang/es/tree.txt | 3 ++ 5 files changed, 86 insertions(+), 34 deletions(-) create mode 100644 lang/es/progress.txt create mode 100644 lang/es/settings.php create mode 100644 lang/es/tree.txt diff --git a/lang/es/lang.php b/lang/es/lang.php index 8d50c71..0c09498 100644 --- a/lang/es/lang.php +++ b/lang/es/lang.php @@ -1,32 +1,66 @@ - * @translation Ruben Squartini <> -*/ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Mover/Renombrar página...'; -$lang['desc'] = 'Extensión para Mover/Renombrar páginas'; - -//$lang['notexist'] = 'Este tema no existe aún'; -$lang['notwrite'] = 'No tiene suficientes derechos para modificar esta página'; -$lang['badns'] = 'Caractéres inválidos en el Espacio de Nombres.'; -$lang['badname'] = 'Caractéres inválidos en el nombre de la página.'; -$lang['nochange'] = 'Los cambios en el nombre de la página y del espacio no fueron cambiados.'; -$lang['existing'] = 'Un documento llamado %s ya existe en %s'; -$lang['root'] = '[Espacio de Nombres Raiz]'; -$lang['current'] = '(Actual)'; -//$lang['norights'] = 'No tiene suficientes permisos para editar uno o mas de los punteros a este documento.'; -$lang['filelocked'] = 'Este documento está bloqueado - trate de nuevo en unos minutos.'; -$lang['linkchange1'] = 'Enlaces a %s cambiados a %s'; -$lang['newname'] = 'Nombre del nuevo documento :'; -$lang['targetns'] = 'Seleccione el Espacio de Nombres de Destino :'; -$lang['submit'] = 'Enviar'; + * @author Gary Owen + * @author Domingo Redal + */ +$lang['menu'] = 'Mover/Renombrar página...'; +$lang['inprogress'] = '(pendientes de mover)'; +$lang['treelink'] = 'Como alternativa a este sencillo formulario, puede gestionar una reestructuración compleja de su wiki utilizando el administrador para mover páginas basado en listas desplegables.'; +$lang['notexist'] = 'La página %s aún no existe'; +$lang['norights'] = 'No tiene permisos suficientes para editar %s.'; +$lang['filelocked'] = 'La página %s está bloqueada. Inténtalo de nuevo más tarde.'; +$lang['notchanged'] = 'No se ha indicado un destino nuevo para la página %s (ubicación sin cambios).'; +$lang['exists'] = 'La página %s no se puede mover a %s, ya existe el destino.'; +$lang['notargetperms'] = 'No tienes permisos para crear la página %s.'; +$lang['medianotexist'] = 'El fichero multimedia %s no existe'; +$lang['nomediarights'] = 'No tiene permisos suficientes para borrar %s.'; +$lang['medianotchanged'] = 'No se ha indicado un destino nuevo para la página %s (ubicación sin cambios).'; +$lang['mediaexists'] = 'El fichero multimedia %s no se puede mover a %s, ya existe el destino.'; +$lang['nomediatargetperms'] = 'No tienes permisos para crear el fichero multimedia %s.'; +$lang['indexerror'] = 'Error al actualizar el índice de búsqueda %s'; +$lang['metamoveerror'] = 'Los ficheros meta de la página %s no se pudieron mover'; +$lang['atticmoveerror'] = 'Los ficheros attic de la página %s no se pudieron mover. Por favor, muévalos manualmente.'; +$lang['mediametamoveerror'] = 'Los ficheros meta del fichero multimedia %s no se pudieron mover'; +$lang['mediamoveerror'] = 'Se ha producido un error al mover el fichero multimedia %s'; +$lang['mediaatticmoveerror'] = 'Los ficheros attic del fichero multimedia %s no se pudieron mover. Por favor, muévalos manualmente.'; +$lang['renamed'] = 'El nombre de la página cambió de %s a %s'; +$lang['moved'] = 'Página movida de %s a %s'; +$lang['move_rename'] = 'Página movida y renombrada de %s a %s'; +$lang['delete'] = 'Borrado por la extensión move'; +$lang['linkchange'] = 'Enlaces adaptados debido a una operación de mover'; +$lang['intro'] = '¡La operación de mover aún no se ha iniciado!'; +$lang['preview'] = 'Previsualizar los cambios a ejecutar.'; +$lang['inexecution'] = 'Una operación de mover anterior no se completó - utilice los botones de abajo para continuar o anular la ejecución.'; +$lang['btn_start'] = 'Empezar'; +$lang['btn_continue'] = 'Continuar'; +$lang['btn_retry'] = 'Reintentar elemento'; +$lang['btn_skip'] = 'Saltar elemento'; +$lang['btn_abort'] = 'Anular'; +$lang['legend'] = 'Mover la página actual o el espacio de nombres'; +$lang['movepage'] = 'Mover la página'; +$lang['movens'] = 'Mover el espacio de nombres'; +$lang['dst'] = 'Nuevo nombre:'; +$lang['content_to_move'] = 'Contenido para mover:'; +$lang['autoskip'] = 'Ignorar errores y omitir páginas o ficheros que no se pueden mover'; +$lang['autorewrite'] = 'Reescribir los enlaces justo después de completar la operación de mover'; +$lang['move_pages'] = 'Páginas'; +$lang['move_media'] = 'Ficheros multimedia'; +$lang['move_media_and_pages'] = 'Páginas y ficheros multimedia'; +$lang['nodst'] = 'No se ha dado ningún nombre nuevo'; +$lang['noaction'] = 'No hubo operaciones de mover definidas'; +$lang['renamepage'] = 'Cambiar nombre de página'; +$lang['cantrename'] = 'No se puede cambiar el nombre de la página en este momento. Inténtalo de nuevo más tarde.'; +$lang['js']['rename'] = 'Renombrar'; +$lang['js']['cancel'] = 'Cancelar'; +$lang['js']['newname'] = 'Nuevo nombre:'; +$lang['js']['inprogress'] = 'cambiar el nombre de la página y ajustar los enlaces...'; +$lang['js']['complete'] = 'La operación de mover ha finalizado.'; +$lang['js']['renameitem'] = 'Renombrar este elemento'; +$lang['js']['add'] = 'Crear un nuevo espacio de nombres'; +$lang['js']['duplicate'] = 'Lo sentimos, "%s" ya existe en este espacio de nombres.'; +$lang['root'] = '[Espacio de nombres raíz]'; +$lang['noscript'] = 'Esta función requiere JavaScript'; +$lang['moveinprogress'] = 'Hay otra operación de mover actualmente en curso, no se puede usar esta herramienta ahora mismo.'; diff --git a/lang/es/move.txt b/lang/es/move.txt index d1f364f..68cdcec 100644 --- a/lang/es/move.txt +++ b/lang/es/move.txt @@ -1,10 +1,10 @@ -====== Move ====== +====== Mover ====== Esta extensión le permite mover y/o renombrar el documento actual respetando las siguientes restricciones. - * Debe tener permisos de edición sobre el documento actual. - * El documento actual no puede ser bloqueados para la edición. - * Para mover un documento también necesita permiso de creación sobre el directorio de destino. - * No puede mover el documento a un Espacio de Nombres donde ya existe un documento con el mismo nombre. + * Debe tener permisos de edición sobre la página actual. + * La página actual no puede ser bloqueada para la edición. + * Para mover una página también necesita permiso de creación sobre el directorio de destino. + * No puede mover la página a un espacio de nombres donde ya existe una página con el mismo nombre. Todos los enlaces desde y hacia esta página serán actualizados para reflejar la nueva ubicación y/o nombre. diff --git a/lang/es/progress.txt b/lang/es/progress.txt new file mode 100644 index 0000000..ae6caef --- /dev/null +++ b/lang/es/progress.txt @@ -0,0 +1,3 @@ +====== Mover en progreso... ====== + +Por favor, mantenga esta página abierta mientras progresa la operación de mover. \ No newline at end of file diff --git a/lang/es/settings.php b/lang/es/settings.php new file mode 100644 index 0000000..332caa6 --- /dev/null +++ b/lang/es/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Permitir el cambio de nombre de páginas a estos grupos y usuarios (separados por comas).'; +$lang['minor'] = '¿Marcar los ajustes de enlace como cambios menores? Los cambios menores no se incluirán en los feeds RSS ni en los correos de suscripción.'; +$lang['autoskip'] = 'Habilitar de forma predeterminada el salto automático de errores en las operaciones de mover el espacio de nombres.'; +$lang['autorewrite'] = 'Habilitar de forma predeterminada la reescritura automática de enlaces después de mover el espacio de nombres.'; +$lang['pagetools_integration'] = 'Añadir botón de cambio de nombre a las herramientas de página'; diff --git a/lang/es/tree.txt b/lang/es/tree.txt new file mode 100644 index 0000000..6c30939 --- /dev/null +++ b/lang/es/tree.txt @@ -0,0 +1,3 @@ +====== Administrador de mover ===== + +Esta interfaz le permite reorganizar los espacios de nombres, páginas y ficheros multimedia de su wiki a través de arrastrar y soltar (Drag'n'Drop). \ No newline at end of file From 3fc280d9ac5b40ba452705c4710d059db7838c92 Mon Sep 17 00:00:00 2001 From: "F. Mueller-Donath" Date: Wed, 4 Oct 2017 15:10:33 +0200 Subject: [PATCH 268/338] translation update --- lang/de/lang.php | 12 +++++++----- lang/de/move.txt | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lang/de/lang.php b/lang/de/lang.php index dae9b89..234110b 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -5,8 +5,9 @@ * * @author picsar * @author e-dschungel + * @author F. Mueller-Donath */ -$lang['menu'] = 'Seite/Namespace verschieben/umbenennen...'; +$lang['menu'] = 'Seite/Namensraum verschieben/umbenennen...'; $lang['inprogress'] = '(Verschiebung läuft gerade)'; $lang['treelink'] = 'Alternativ zu dieser einfachen Form können komplexere Umstrukturierungen des Wikis mit dem baumbasierten Move-Manager durchgeführt werden.'; $lang['notexist'] = 'Die Seite %s existiert nicht.'; @@ -33,13 +34,13 @@ $lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; $lang['intro'] = 'Die Verschiebung wurde noch nicht gestartet!'; $lang['preview'] = 'Vorschau der Änderungen, die ausgeführt werden sollen '; -$lang['inexecution'] = 'Eine vorherige Verschiebung wurde nicht beendet - benutzen sie die Knöpfe unten um die Verschiebung fortzusetzen oder abzubrechen. '; +$lang['inexecution'] = 'Eine vorherige Verschiebung wurde nicht beendet - benutzen Sie die Knöpfe unten um die Verschiebung fortzusetzen oder abzubrechen. '; $lang['btn_start'] = 'Start'; $lang['btn_continue'] = 'Fortsetzen'; $lang['btn_retry'] = 'Element wiederholen'; $lang['btn_skip'] = 'Element überspringen'; $lang['btn_abort'] = 'Abbrechen'; -$lang['legend'] = 'Aktuelle Seite oder aktueller Namesraum'; +$lang['legend'] = 'Aktuelle Seite oder aktueller Namensraum'; $lang['movepage'] = 'Seite verschieben'; $lang['movens'] = 'Namensraum verschieben'; $lang['dst'] = 'Neuer Name:'; @@ -59,7 +60,8 @@ $lang['js']['inprogress'] = 'Benenne Seite um und passe Links an...'; $lang['js']['complete'] = 'Verschieben abgeschlossen.'; $lang['js']['renameitem'] = 'Dieses Element umbenennen'; +$lang['js']['add'] = 'Neuen Namensraum erstellen'; $lang['js']['duplicate'] = 'Entschuldigung, "%s" existiert in diesem Namensraum bereits. '; -$lang['root'] = '[Wurzel des Namensraumes / Root namespace]'; +$lang['root'] = '[Oberster Namensraum]'; $lang['noscript'] = 'Dieses Feature benötigt JavaScript.'; -$lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft gerade, Sie können dieses Tool gerade nicht benutzen.'; +$lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft momentan, Sie können dieses Tool gerade nicht benutzen.'; diff --git a/lang/de/move.txt b/lang/de/move.txt index 8d4da83..daf9f1e 100644 --- a/lang/de/move.txt +++ b/lang/de/move.txt @@ -1,6 +1,6 @@ -====== Seite/Namespace verschieben/umbenennen ====== +====== Seite/Namensraum verschieben/umbenennen ====== -Mit diesem Plugin kann die aktuelle Seite verschoben/umbenannt oder ein gesamter Namensraum verschoben/umbenannt werden. +Mit diesem Plugin kann die aktuelle Seite oder ein gesamter Namensraum verschoben oder umbenannt werden. Folgende Einschränkungen/Bedingungen gelten: * Sie müssen die Bearbeiten-Rechte für die Seite/alle Seiten im aktuellen Namensraum haben. From 04f3a106ce6f15a2e2354a3846753982cab1b92e Mon Sep 17 00:00:00 2001 From: "F. Mueller-Donath" Date: Wed, 4 Oct 2017 15:10:48 +0200 Subject: [PATCH 269/338] translation update --- lang/de-informal/lang.php | 65 +++++++++++++++++++++++++++++++++++ lang/de-informal/move.txt | 11 ++++++ lang/de-informal/progress.txt | 3 ++ lang/de-informal/settings.php | 12 +++++++ lang/de-informal/tree.txt | 3 ++ 5 files changed, 94 insertions(+) create mode 100644 lang/de-informal/lang.php create mode 100644 lang/de-informal/move.txt create mode 100644 lang/de-informal/progress.txt create mode 100644 lang/de-informal/settings.php create mode 100644 lang/de-informal/tree.txt diff --git a/lang/de-informal/lang.php b/lang/de-informal/lang.php new file mode 100644 index 0000000..b525d8f --- /dev/null +++ b/lang/de-informal/lang.php @@ -0,0 +1,65 @@ + + */ +$lang['menu'] = 'Seite/Namensraum verschieben/umbenennen...'; +$lang['inprogress'] = '(Verschiebung läuft gerade)'; +$lang['treelink'] = 'Alternativ zu dieser einfachen Form können komplexere Umstrukturierungen des Wikis mit dem baumbasierten Move-Manager durchgeführt werden.'; +$lang['notexist'] = 'Die Seite %s existiert nicht.'; +$lang['norights'] = 'Du hast unzureichende Rechte um %s zu bearbeiten.'; +$lang['filelocked'] = 'Die Seite %s ist gesperrt - bitte versuche es später noch einmal.'; +$lang['notchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; +$lang['exists'] = 'Seite %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; +$lang['notargetperms'] = 'Du hast nicht die Berechtigung, die Seite %s anzulegen.'; +$lang['medianotexist'] = 'Die Mediendatei %s existiert nicht'; +$lang['nomediarights'] = 'Du hast unzureichende Rechte, um die Mediendatei %s zu löschen.'; +$lang['medianotchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; +$lang['mediaexists'] = 'Mediendatei %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; +$lang['nomediatargetperms'] = 'Du hast keine Berechtigung, die Mediendatei %s anzulegen.'; +$lang['indexerror'] = 'Fehler während der Aktualisierung des Suchindexes %s'; +$lang['metamoveerror'] = 'Die Metadateien der Seite %s konnten nicht verschoben werden'; +$lang['atticmoveerror'] = 'Die Attic-Dateien der Seite %s konnten nicht verschoben werden. Bitte verschiebe Sie sie manuell.'; +$lang['mediametamoveerror'] = 'Die Metadateien der Mediendatei %s konnten nicht verschoben werden'; +$lang['mediamoveerror'] = 'Verschieben der Mediendatei %s fehlgeschlagen'; +$lang['mediaatticmoveerror'] = 'Die Attic-Dateien der Mediendatei %s konnten nicht verschoben werden. Bitte verschiebe sie manuell.'; +$lang['renamed'] = 'Seitename wurde von %s auf %s geändert'; +$lang['moved'] = 'Seite von %s nach %s verschoben'; +$lang['move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; +$lang['delete'] = 'Gelöscht durch das move Plugin'; +$lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; +$lang['intro'] = 'Die Verschiebung wurde noch nicht gestartet!'; +$lang['preview'] = 'Vorschau der Änderungen, die ausgeführt werden sollen '; +$lang['inexecution'] = 'Eine vorherige Verschiebung wurde nicht beendet - benutze die Knöpfe unten um die Verschiebung fortzusetzen oder abzubrechen. '; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Fortsetzen'; +$lang['btn_retry'] = 'Element wiederholen'; +$lang['btn_skip'] = 'Element überspringen'; +$lang['btn_abort'] = 'Abbrechen'; +$lang['legend'] = 'Aktuelle Seite oder Namensraum verschieben'; +$lang['movepage'] = 'Seite verschieben'; +$lang['movens'] = 'Namensraum verschieben'; +$lang['dst'] = 'Neuer Name:'; +$lang['content_to_move'] = 'Zu verschiebender Inhalt:'; +$lang['autoskip'] = 'Zu verschiebender Inhalt:'; +$lang['autorewrite'] = 'Links anpassen, nachdem die Verschiebung abgeschlossen wurde'; +$lang['move_pages'] = 'Seiten'; +$lang['move_media'] = 'Mediandateien'; +$lang['move_media_and_pages'] = 'Seiten und Mediendateien'; +$lang['nodst'] = 'Kein neuer Name angegeben'; +$lang['noaction'] = 'Es wurden keine Verschiebungen angegeben'; +$lang['renamepage'] = 'Seite umbenennen'; +$lang['cantrename'] = 'Auf die Seite kann zur Zeit nicht zugegriffen werden - bitte versuche es später noch einmal.'; +$lang['js']['rename'] = 'Umbenennen'; +$lang['js']['cancel'] = 'Abbrechen'; +$lang['js']['newname'] = 'Neuer Name:'; +$lang['js']['inprogress'] = 'Benenne Seite um und passe Links an...'; +$lang['js']['complete'] = 'Verschieben abgeschlossen.'; +$lang['js']['renameitem'] = 'Dieses Element umbenennen'; +$lang['js']['add'] = 'Neuen Namensraum erstellen'; +$lang['js']['duplicate'] = 'Entschuldigung, "%s" existiert in diesem Namensraum bereits. '; +$lang['root'] = '[Oberster Namensraum]'; +$lang['noscript'] = 'Dieses Feature benötigt JavaScript.'; +$lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft momentan, du kannst dieses Tool gerade nicht benutzen.'; diff --git a/lang/de-informal/move.txt b/lang/de-informal/move.txt new file mode 100644 index 0000000..daf9f1e --- /dev/null +++ b/lang/de-informal/move.txt @@ -0,0 +1,11 @@ +====== Seite/Namensraum verschieben/umbenennen ====== + +Mit diesem Plugin kann die aktuelle Seite oder ein gesamter Namensraum verschoben oder umbenannt werden. +Folgende Einschränkungen/Bedingungen gelten: + + * Sie müssen die Bearbeiten-Rechte für die Seite/alle Seiten im aktuellen Namensraum haben. + * Die Seiten, die verschoben werden, dürfen nicht gesperrt sein, d.h. sich im Bearbeitungsmodus befinden. + * Um eine Seite zu verschieben, benötigt man das Erstellen-Recht im Ziel-Namensraum. + * Eine Seite kann nicht in einen Namensraum verschoben werden, in der bereits eine Seite gleichen Namens existiert. + +Alle Links von und auf die Seite werden aktualisiert, um dem neuen Namen bzw. dem neuen Namensraum zu entsprechen. diff --git a/lang/de-informal/progress.txt b/lang/de-informal/progress.txt new file mode 100644 index 0000000..f9b39e1 --- /dev/null +++ b/lang/de-informal/progress.txt @@ -0,0 +1,3 @@ +====== Verschiebung läuft... ====== + +Bitte lassen Sie diese Seite geöffnet, während die Verschiebung läuft. \ No newline at end of file diff --git a/lang/de-informal/settings.php b/lang/de-informal/settings.php new file mode 100644 index 0000000..206940d --- /dev/null +++ b/lang/de-informal/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Umbennenung von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt) '; +$lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderung werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; +$lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; +$lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; +$lang['pagetools_integration'] = 'Umbenennen-Button zu Pagetools hinzufügen'; diff --git a/lang/de-informal/tree.txt b/lang/de-informal/tree.txt new file mode 100644 index 0000000..a5c31d1 --- /dev/null +++ b/lang/de-informal/tree.txt @@ -0,0 +1,3 @@ +====== Move-Manager ===== + +Diese Ansicht ermöglicht die Restrukturierung von Namensräumen, Seiten und Mediendateien des Wikis per Drag'n'Drop. From 25b5a942d6d4e9419675e75c5daa583c9f3d50b8 Mon Sep 17 00:00:00 2001 From: "F. Mueller-Donath" Date: Thu, 19 Oct 2017 09:55:17 +0200 Subject: [PATCH 270/338] translation update --- lang/de-informal/settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/de-informal/settings.php b/lang/de-informal/settings.php index 206940d..8ef0f2f 100644 --- a/lang/de-informal/settings.php +++ b/lang/de-informal/settings.php @@ -5,8 +5,8 @@ * * @author F. Mueller-Donath */ -$lang['allowrename'] = 'Umbennenung von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt) '; -$lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderung werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; +$lang['allowrename'] = 'Umbenennen von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt).'; +$lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderungen werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; $lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; $lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; $lang['pagetools_integration'] = 'Umbenennen-Button zu Pagetools hinzufügen'; From 24b76f72e6d5340cea780e1c2e226550faffd3dd Mon Sep 17 00:00:00 2001 From: "F. Mueller-Donath" Date: Thu, 19 Oct 2017 09:55:34 +0200 Subject: [PATCH 271/338] translation update --- lang/de/settings.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lang/de/settings.php b/lang/de/settings.php index ade23fc..23b567a 100644 --- a/lang/de/settings.php +++ b/lang/de/settings.php @@ -3,9 +3,10 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author F. Mueller-Donath * @author e-dschungel */ -$lang['allowrename'] = 'Umbennenung von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt) '; +$lang['allowrename'] = 'Umbenennen von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt).'; $lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderung werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; $lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; $lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; From beffdc9068ecf9337b1439a3989a615ff01cfe6a Mon Sep 17 00:00:00 2001 From: Aleksandr Selivanov Date: Fri, 3 Nov 2017 21:10:58 +0100 Subject: [PATCH 272/338] translation update --- lang/ru/lang.php | 144 +++++++++++++++++++------------------------ lang/ru/settings.php | 14 +++-- 2 files changed, 73 insertions(+), 85 deletions(-) diff --git a/lang/ru/lang.php b/lang/ru/lang.php index f94a7d5..01f0c49 100644 --- a/lang/ru/lang.php +++ b/lang/ru/lang.php @@ -1,87 +1,69 @@ - * @author Chang Zhao + * + * @author Aleksandr Selivanov + * @author S'Adm*n + * @author Chang Zhao */ - -$lang['menu'] = 'Перемещение/переименование страниц и папок'; -$lang['desc'] = 'Плагин для перемещения (переименования) страниц'; -$lang['inprogress'] = '(...идёт перемещение...)'; -$lang['treelink'] = 'Кроме этой простой формы, для сложной реструктуризации страниц вы можете использовать древовидную настройку.'; - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// page errors -$lang['notexist'] = 'Страница %s не существует.'; -$lang['norights'] = 'У Вас нет прав редактировать %s.'; -$lang['filelocked'] = 'Изменение страницы %s сейчас заблокировано - попробуйте позже.'; -$lang['notchanged'] = 'Не задано нового названия %s (адрес не изменён).'; -$lang['exists'] = 'Невозможно переместить %s - уже существует страница %s.'; -$lang['notargetperms'] = 'У вас недостаточно прав для создания страницы %s.'; - -// media errors -$lang['medianotexist'] = 'Медиафайла %s не существует'; -$lang['nomediarights'] = 'У вас недостаточно прав для удаления %s.'; -$lang['medianotchanged'] = 'Не задано нового названия %s (адрес не изменён).'; -$lang['mediaexists'] = 'Невозможно переместить %s - уже существует страница %s.'; -$lang['nomediatargetperms'] = 'У вас недостаточно прав для создания медиафайла %s.'; - -// system errors -$lang['indexerror'] = 'Ошибка при обновлении индексирования поиска %s'; -$lang['metamoveerror'] = 'Не удалось переместить медиафайлы страницы %s'; -$lang['atticmoveerror'] = 'Не удалось переместить архивы (attic) страницы %s. Переместите их вручную.'; -$lang['mediametamoveerror'] = 'Не удалось переместить мета-файлы страницы %s.'; -$lang['mediamoveerror'] = 'Не удалось переместить медиафайл %s.'; -$lang['mediaatticmoveerror'] = 'Не удалось переместить архивы (attic) медиафайла %s. Переместите их вручную.'; - -// changelog summaries -$lang['renamed'] = 'Имя страницы %s изменено на %s'; -$lang['moved'] = 'Страница перемещена из %s в %s'; -$lang['move_rename'] = 'Страница перемещена и переименована из %s в %s'; -$lang['delete'] = 'Удалено плагином Move (перемещения страниц)'; -$lang['linkchange'] = 'Операцией перемещения обновлены ссылки'; - -// progress view -$lang['intro'] = 'Операция перемещения ещё не начата!'; -$lang['preview'] = 'Просмотреть ожидаемые изменения.'; -$lang['inexecution'] = 'Предыдущее перемещение не завершилось - кнопками внизу выберите завершение или отмену.'; -$lang['btn_start'] = 'Начать'; -$lang['btn_continue'] = 'Продолжить'; -$lang['btn_retry'] = 'Попытаться ещё'; -$lang['btn_skip'] = 'Пропустить'; -$lang['btn_abort'] = 'Отменить'; - -// Form labels -$lang['legend'] = 'Переместить текущую страницу или папку'; -$lang['movepage'] = 'Переместить страницу'; -$lang['movens'] = 'Переместить папку'; -$lang['dst'] = 'Новое название:'; -$lang['content_to_move'] = 'Переместить содержимое:'; -$lang['autoskip'] = 'Игнорировать ошибки; пропускать страницы и файлы, которые не удаётся переместить.'; -$lang['autorewrite'] = 'По окончании перемещения обновить ссылки.'; -$lang['move_pages'] = 'Страницы'; -$lang['move_media'] = 'Медиафайлы'; -$lang['move_media_and_pages'] = 'Страницы и медиафайлы'; -$lang['nodst'] = 'Не задано новое имя'; -$lang['noaction'] = 'Не было задано перемещений'; - -// Rename feature -$lang['renamepage'] = 'Переименовать страницу'; -$lang['cantrename'] = 'Сейчас не удаётся переименовать страницу - попробуйте позже.'; -$lang['js']['rename'] = 'Переименовать'; -$lang['js']['cancel'] = 'Отменить'; -$lang['js']['newname'] = 'Новое название:'; -$lang['js']['inprogress'] = '...переименование страницы и обновление ссылок...'; -$lang['js']['complete'] = 'Перемещение завершено.'; - -// Tree Manager -$lang['root'] = '[Корневой каталог]'; -$lang['noscript'] = 'Для этого требуется включить JavaScript'; -$lang['moveinprogress'] = 'Сейчас происходит другая операция перемещения; пока она не закончена, данный инструмент не работает.'; -$lang['js']['renameitem'] = 'Переименовать'; -$lang['js']['duplicate'] = 'Не получается: "%s" уже существует в данной папке.'; +$lang['menu'] = 'Перемещение/переименование страниц и папок'; +$lang['inprogress'] = '(...идёт перемещение...)'; +$lang['treelink'] = 'Кроме этой простой формы, для сложной реструктуризации страниц вы можете использовать древовидную настройку.'; +$lang['notexist'] = 'Страница %s не существует.'; +$lang['norights'] = 'У Вас нет прав редактировать %s.'; +$lang['filelocked'] = 'Изменение страницы %s сейчас заблокировано - попробуйте позже.'; +$lang['notchanged'] = 'Не задано нового названия %s (адрес не изменён).'; +$lang['exists'] = 'Невозможно переместить %s - уже существует страница %s.'; +$lang['notargetperms'] = 'У вас недостаточно прав для создания страницы %s.'; +$lang['medianotexist'] = 'Медиафайла %s не существует'; +$lang['nomediarights'] = 'У вас недостаточно прав для удаления %s.'; +$lang['medianotchanged'] = 'Не задано нового названия %s (адрес не изменён).'; +$lang['mediaexists'] = 'Невозможно переместить %s - уже существует страница %s.'; +$lang['nomediatargetperms'] = 'У вас недостаточно прав для создания медиафайла %s.'; +$lang['indexerror'] = 'Ошибка при обновлении индексирования поиска %s'; +$lang['metamoveerror'] = 'Не удалось переместить медиафайлы страницы %s'; +$lang['atticmoveerror'] = 'Не удалось переместить архивы (attic) страницы %s. Переместите их вручную.'; +$lang['mediametamoveerror'] = 'Не удалось переместить мета-файлы страницы %s.'; +$lang['mediamoveerror'] = 'Не удалось переместить медиафайл %s.'; +$lang['mediaatticmoveerror'] = 'Не удалось переместить архивы (attic) медиафайла %s. Переместите их вручную.'; +$lang['renamed'] = 'Имя страницы %s изменено на %s'; +$lang['moved'] = 'Страница перемещена из %s в %s'; +$lang['move_rename'] = 'Страница перемещена и переименована из %s в %s'; +$lang['delete'] = 'Удалено плагином Move (перемещения страниц)'; +$lang['linkchange'] = 'Операцией перемещения обновлены ссылки'; +$lang['intro'] = 'Операция перемещения ещё не начата!'; +$lang['preview'] = 'Просмотреть ожидаемые изменения.'; +$lang['inexecution'] = 'Предыдущее перемещение не завершилось - кнопками внизу выберите завершение или отмену.'; +$lang['btn_start'] = 'Начать'; +$lang['btn_continue'] = 'Продолжить'; +$lang['btn_retry'] = 'Попытаться ещё'; +$lang['btn_skip'] = 'Пропустить'; +$lang['btn_abort'] = 'Отменить'; +$lang['legend'] = 'Переместить текущую страницу или папку'; +$lang['movepage'] = 'Переместить страницу'; +$lang['movens'] = 'Переместить папку'; +$lang['dst'] = 'Новое название:'; +$lang['content_to_move'] = 'Переместить содержимое:'; +$lang['autoskip'] = 'Игнорировать ошибки; пропускать страницы и файлы, которые не удаётся переместить.'; +$lang['autorewrite'] = 'По окончании перемещения обновить ссылки.'; +$lang['move_pages'] = 'Страницы'; +$lang['move_media'] = 'Медиафайлы'; +$lang['move_media_and_pages'] = 'Страницы и медиафайлы'; +$lang['nodst'] = 'Не задано новое имя'; +$lang['noaction'] = 'Не было задано перемещений'; +$lang['renamepage'] = 'Переименовать страницу'; +$lang['cantrename'] = 'Сейчас не удаётся переименовать страницу - попробуйте позже.'; +$lang['js']['rename'] = 'Переименовать'; +$lang['js']['cancel'] = 'Отменить'; +$lang['js']['newname'] = 'Новое название:'; +$lang['js']['inprogress'] = '...переименование страницы и обновление ссылок...'; +$lang['js']['complete'] = 'Перемещение завершено.'; +$lang['js']['renameitem'] = 'Переименовать'; +$lang['js']['add'] = 'Создать новое пространство имён'; +$lang['js']['duplicate'] = 'Не получается: "%s" уже существует в данной папке.'; +$lang['root'] = '[Корневой каталог]'; +$lang['noscript'] = 'Для этого требуется включить JavaScript'; +$lang['moveinprogress'] = 'Сейчас происходит другая операция перемещения; пока она не закончена, данный инструмент не работает.'; diff --git a/lang/ru/settings.php b/lang/ru/settings.php index ec57fb2..f85ba2d 100644 --- a/lang/ru/settings.php +++ b/lang/ru/settings.php @@ -1,6 +1,12 @@ + */ +$lang['allowrename'] = 'Разрешить переименование страниц следующим группам и пользователям (разделяйте запятыми)'; +$lang['minor'] = 'Помечать обновление ссылок как небольшие изменения? Они не будут появляться в письмах подписчикам и RSS.'; +$lang['autoskip'] = 'Включить автоматический пропуск ошибок при перемещении пространств имён по умолчанию'; +$lang['autorewrite'] = 'Включить автоматическое обновление ссылок после перемещения пространств имён по умолчанию'; +$lang['pagetools_integration'] = 'Добавить кнопку переименования на панель инструментов страницы'; From 50cf7afea2e003bf9683fd7de47527a617d69cf8 Mon Sep 17 00:00:00 2001 From: Aleksandr Selivanov Date: Sun, 5 Nov 2017 16:20:17 +0100 Subject: [PATCH 273/338] translation update --- lang/ru/lang.php | 26 +++++++++++++------------- lang/ru/move.txt | 12 ++++++------ lang/ru/progress.txt | 2 +- lang/ru/tree.txt | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lang/ru/lang.php b/lang/ru/lang.php index 01f0c49..508ca58 100644 --- a/lang/ru/lang.php +++ b/lang/ru/lang.php @@ -9,14 +9,14 @@ * @author S'Adm*n * @author Chang Zhao */ -$lang['menu'] = 'Перемещение/переименование страниц и папок'; -$lang['inprogress'] = '(...идёт перемещение...)'; -$lang['treelink'] = 'Кроме этой простой формы, для сложной реструктуризации страниц вы можете использовать древовидную настройку.'; -$lang['notexist'] = 'Страница %s не существует.'; -$lang['norights'] = 'У Вас нет прав редактировать %s.'; -$lang['filelocked'] = 'Изменение страницы %s сейчас заблокировано - попробуйте позже.'; -$lang['notchanged'] = 'Не задано нового названия %s (адрес не изменён).'; -$lang['exists'] = 'Невозможно переместить %s - уже существует страница %s.'; +$lang['menu'] = 'Перемещение страниц и пространств имён'; +$lang['inprogress'] = '(идёт перемещение)'; +$lang['treelink'] = 'Для сложной реструктуризации страниц вы можете использовать древовидное управление перемещением.'; +$lang['notexist'] = 'Страница %s не существует'; +$lang['norights'] = 'У вас нет прав редактировать %s.'; +$lang['filelocked'] = 'Изменение страницы %s сейчас заблокировано. Попробуйте позже.'; +$lang['notchanged'] = 'Не задано нового названия %s (адрес не изменён).'; +$lang['exists'] = 'Невозможно переместить %s, уже существует страница %s.'; $lang['notargetperms'] = 'У вас недостаточно прав для создания страницы %s.'; $lang['medianotexist'] = 'Медиафайла %s не существует'; $lang['nomediarights'] = 'У вас недостаточно прав для удаления %s.'; @@ -47,23 +47,23 @@ $lang['movens'] = 'Переместить папку'; $lang['dst'] = 'Новое название:'; $lang['content_to_move'] = 'Переместить содержимое:'; -$lang['autoskip'] = 'Игнорировать ошибки; пропускать страницы и файлы, которые не удаётся переместить.'; +$lang['autoskip'] = 'Игнорировать ошибки, пропускать страницы и медиафайлы, которые не удаётся переместить'; $lang['autorewrite'] = 'По окончании перемещения обновить ссылки.'; $lang['move_pages'] = 'Страницы'; $lang['move_media'] = 'Медиафайлы'; -$lang['move_media_and_pages'] = 'Страницы и медиафайлы'; +$lang['move_media_and_pages'] = 'Страницы и медиафайлы'; $lang['nodst'] = 'Не задано новое имя'; $lang['noaction'] = 'Не было задано перемещений'; $lang['renamepage'] = 'Переименовать страницу'; -$lang['cantrename'] = 'Сейчас не удаётся переименовать страницу - попробуйте позже.'; +$lang['cantrename'] = 'Сейчас не удаётся переименовать страницу. Попробуйте позже.'; $lang['js']['rename'] = 'Переименовать'; $lang['js']['cancel'] = 'Отменить'; $lang['js']['newname'] = 'Новое название:'; -$lang['js']['inprogress'] = '...переименование страницы и обновление ссылок...'; +$lang['js']['inprogress'] = 'переименование страницы и обновление ссылок...'; $lang['js']['complete'] = 'Перемещение завершено.'; $lang['js']['renameitem'] = 'Переименовать'; $lang['js']['add'] = 'Создать новое пространство имён'; -$lang['js']['duplicate'] = 'Не получается: "%s" уже существует в данной папке.'; +$lang['js']['duplicate'] = 'Не получается: „%s“ уже существует в данной папке.'; $lang['root'] = '[Корневой каталог]'; $lang['noscript'] = 'Для этого требуется включить JavaScript'; $lang['moveinprogress'] = 'Сейчас происходит другая операция перемещения; пока она не закончена, данный инструмент не работает.'; diff --git a/lang/ru/move.txt b/lang/ru/move.txt index 7945a27..bf3f576 100644 --- a/lang/ru/move.txt +++ b/lang/ru/move.txt @@ -1,10 +1,10 @@ ====== Перемещение ====== -Этот плагин позволяет перемещать или переименовывать текущую страницу или текущую папку со следующими ограничениями: +Плагин позволяет перемещать и переименовывать текущую страницу или текущее пространство имён со следующими ограничениями: - * У вас должны быть права для редактирования данной страницы или в данной папке для всех страниц. - * Перемещаемые страницы не должны быть заблокированы (напр., когда их редактируют другие пользователи). - * Для перемещения страницы в другую папку вам нужны права создания в этой папке. - * Вы не можете переместить страницу в папку, уже содержащую страницу с таким же названием. + * у вас должны быть права для редактирования текущей страницы или страниц в текущем пространстве имён; + * перемещаемые страницы не должны быть заблокированы (например, когда их редактируют другие пользователи); + * для перемещения страницы в другое пространство имён вам нужны права создания в этом пространство имён; + * вы не можете переместить страницу в пространство имён, уже содержащее страницу с таким же названием. -Все ссылки, ведущие с перемещаемых (переименуемых) страниц или на них - будут обновлены в соответствии со внесёнными изменениями. +Все ссылки, ведущие с перемещаемых и переименовываемых страниц или на них, будут обновлены в соответствии с внесёнными изменениями. diff --git a/lang/ru/progress.txt b/lang/ru/progress.txt index 218b387..3855281 100644 --- a/lang/ru/progress.txt +++ b/lang/ru/progress.txt @@ -1,3 +1,3 @@ ====== Идёт перемещение... ====== -Пожалуйста, не закрывайте эту страницу, пока идёт перемещение. +Пожалуйста, не закрывайте эту страницу. diff --git a/lang/ru/tree.txt b/lang/ru/tree.txt index e652528..4d71570 100644 --- a/lang/ru/tree.txt +++ b/lang/ru/tree.txt @@ -1,3 +1,3 @@ -====== Древовидный инструмент перемещения ===== +====== Управление перемещением ===== -Здесь вы можете перемещать папки, страницы и медиафайлы вашей ДокуВики, просто передвигая их на новое место. +Здесь вы можете перемещать пространства имён, страницы и медиафайлы вашей вики перетаскиванием (drag-and-drop). \ No newline at end of file From 71c876310004ed1015fca79e139c91f6074416ce Mon Sep 17 00:00:00 2001 From: Tormec Date: Tue, 14 Nov 2017 09:45:32 +0100 Subject: [PATCH 274/338] added description for checkboxes --- lang/en/tree.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lang/en/tree.txt b/lang/en/tree.txt index 16a4427..e7fc00b 100644 --- a/lang/en/tree.txt +++ b/lang/en/tree.txt @@ -1,3 +1,7 @@ ====== Move Manager ===== -This interface allows you to rearrange your wiki's namespaces, pages and media files via Drag'n'Drop. \ No newline at end of file +This interface allows you to rearrange your wiki's namespaces, pages and media files via Drag'n'Drop. + +In case you have to move many files to the same destination you can use the checkboxes as follows: + * check the namespaces, pages or media files you have to reorganize; + * move only one of the checked files to the desired destination. \ No newline at end of file From d1cf09b70b87dea4f9dc5c66456c908bfc3e2174 Mon Sep 17 00:00:00 2001 From: Tormec Date: Tue, 14 Nov 2017 09:52:53 +0100 Subject: [PATCH 275/338] changed "have to" in "want to" --- lang/en/tree.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/en/tree.txt b/lang/en/tree.txt index e7fc00b..f599e1b 100644 --- a/lang/en/tree.txt +++ b/lang/en/tree.txt @@ -3,5 +3,5 @@ This interface allows you to rearrange your wiki's namespaces, pages and media files via Drag'n'Drop. In case you have to move many files to the same destination you can use the checkboxes as follows: - * check the namespaces, pages or media files you have to reorganize; + * check the namespaces, pages or media files you want to reorganize; * move only one of the checked files to the desired destination. \ No newline at end of file From 5173034c5e92ce69ccfe0b2aedc45fa3d6df661a Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Wed, 3 Jan 2018 15:00:25 +0100 Subject: [PATCH 276/338] translation update --- lang/nl/lang.php | 4 +++- lang/nl/settings.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lang/nl/lang.php b/lang/nl/lang.php index 9b37782..8a11125 100644 --- a/lang/nl/lang.php +++ b/lang/nl/lang.php @@ -2,7 +2,8 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * + * @author Gerrit Uitslag * @author Gary Owen * @author Andre Dierick * @author Peter van Diest @@ -60,6 +61,7 @@ $lang['js']['inprogress'] = 'pagina hernoemen en links aanpassen...'; $lang['js']['complete'] = 'Verplaatsing compleet.'; $lang['js']['renameitem'] = 'Hernoem dit item'; +$lang['js']['add'] = 'Maak een nieuwe namespace'; $lang['js']['duplicate'] = 'Sorry, "%s" bestaat al in deze namespace.'; $lang['root'] = '[Hoofdnamespace]'; $lang['noscript'] = 'Deze mogelijkheid vereist Javascript'; diff --git a/lang/nl/settings.php b/lang/nl/settings.php index a6ccf6b..e5b49be 100644 --- a/lang/nl/settings.php +++ b/lang/nl/settings.php @@ -2,10 +2,12 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * + * @author Gerrit Uitslag * @author Peter van Diest */ $lang['allowrename'] = 'Hernoemen van pagina\'s toestaan voor deze groepen en gebruikers (komma-gescheiden).'; $lang['minor'] = 'Link-aanpassingen als kleine aanpassingen markeren? Kleine aanpassingen worden niet genoemd in RRS feeds en nieuwsbrieven.'; $lang['autoskip'] = 'Automatisch overslaan van fouten bij verplaatsingen van namespaces standaard inschakelen.'; $lang['autorewrite'] = 'Automatisch herschrijven van links na verplaatsingen van namespaces standaard inschakelen.'; +$lang['pagetools_integration'] = 'Voeg een \'Hernoem Pagina\' knop toe aan het paginamenu'; From 0f9dde9f48df7c5bd18fb0a936f32e6eb219fcea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Fri, 19 Jan 2018 19:34:21 +0100 Subject: [PATCH 277/338] feat: add pagetools button with new svg mechanism --- MenuItem.php | 33 +++++++++++++++++++++++++++++++++ action/rename.php | 26 ++++++++++++++++++++++++++ images/rename.svg | 1 + 3 files changed, 60 insertions(+) create mode 100644 MenuItem.php create mode 100644 images/rename.svg diff --git a/MenuItem.php b/MenuItem.php new file mode 100644 index 0000000..de6769c --- /dev/null +++ b/MenuItem.php @@ -0,0 +1,33 @@ +getLang('renamepage'); + } +} diff --git a/action/rename.php b/action/rename.php index ad4208b..6e78da9 100644 --- a/action/rename.php +++ b/action/rename.php @@ -20,7 +20,11 @@ class action_plugin_move_rename extends DokuWiki_Action_Plugin { */ public function register(Doku_Event_Handler $controller) { $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'handle_init'); + + // TODO: DEPRECATED JAN 2018 $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'handle_pagetools'); + + $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addsvgbutton', array()); $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); } @@ -36,6 +40,8 @@ public function handle_init() { /** * Adds a button to the default template * + * TODO: DEPRECATED JAN 2018 + * * @param Doku_Event $event */ public function handle_pagetools(Doku_Event $event) { @@ -52,6 +58,26 @@ public function handle_pagetools(Doku_Event $event) { array_slice($event->data['items'], $offset, null, true); } + /** + * Add 'rename' button to page tools, new SVG based mechanism + * + * @param Doku_Event $event + */ + public function addsvgbutton(Doku_Event $event) { + global $INFO, $JSINFO; + if( + $event->data['view'] !== 'page' || + !$this->getConf('pagetools_integration') || + !$JSINFO['move_renameokay'] + ) { + return; + } + if(!$INFO['exists']) { + return; + } + array_splice($event->data['items'], -1, 0, [new \dokuwiki\plugin\move\MenuItem()]); + } + /** * Rename a single page */ diff --git a/images/rename.svg b/images/rename.svg new file mode 100644 index 0000000..1f03921 --- /dev/null +++ b/images/rename.svg @@ -0,0 +1 @@ + From c27d0fa28cf66dc96bd386d72a454ae0d764f367 Mon Sep 17 00:00:00 2001 From: Oleksii Date: Thu, 15 Feb 2018 15:20:34 +0100 Subject: [PATCH 278/338] translation update --- lang/uk/lang.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lang/uk/lang.php diff --git a/lang/uk/lang.php b/lang/uk/lang.php new file mode 100644 index 0000000..4a45999 --- /dev/null +++ b/lang/uk/lang.php @@ -0,0 +1,30 @@ + + */ +$lang['menu'] = 'Переміщення сторінок і просторів назв'; +$lang['inprogress'] = '(очікування переміщення)'; +$lang['treelink'] = 'Також можливо виконувати реструктурізацію за допомогою дерево подібного менеджера'; +$lang['notexist'] = 'Сторінка %s не існує.'; +$lang['norights'] = 'Ви не маєте прав на редагування сторінки %s.'; +$lang['filelocked'] = 'Сторінка %s заблоковано. Спробуйте пізніше.'; +$lang['notchanged'] = 'Не вказано куди переміщати сторінку %s (положення не змінено).'; +$lang['exists'] = 'Сторінка %s не може бути перенесена в %s тому, що така сторінка вже існує.'; +$lang['notargetperms'] = 'Ви не маєте прав на створення сторінки %s.'; +$lang['medianotexist'] = 'Файл %s не існує'; +$lang['nomediarights'] = 'Ви не маєте прав на знищення %s'; +$lang['mediametamoveerror'] = 'Метафайли мультимедійного файла %s не можуть бути переміщені'; +$lang['mediamoveerror'] = 'Файл %s не вдалось перемістити'; +$lang['renamed'] = 'Назва сторінки змінено з %s на %s'; +$lang['moved'] = 'Сторінка посунуто з %s на %s'; +$lang['move_rename'] = 'Сторінка змінена з %s на %s'; +$lang['delete'] = 'Плагін move видалено'; +$lang['linkchange'] = 'Посилання оновлені через операцію переміщення'; +$lang['intro'] = 'Переміщення ще не почато!'; +$lang['preview'] = 'Попередній перегляд майбутніх змін.'; +$lang['inexecution'] = 'Попереднє перейменування не завершено -- нажміть кнопки нижче щоб продовжити або зупинити процес.'; +$lang['btn_start'] = 'Почати'; +$lang['btn_continue'] = 'Продовжити'; From 4cb1aea5a29279cccc2ba819b664a0c09a7ca318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Fri, 16 Feb 2018 18:42:57 +0100 Subject: [PATCH 279/338] fix: use legacy array creation syntax Apparently, there is some ambiguity about which PHP versions are supported by DokuWiki release Frusterick Manners. So to be on the save side, we should choose the syntax that is still compatible with PHP 5.3. --- action/rename.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action/rename.php b/action/rename.php index 6e78da9..6bd495d 100644 --- a/action/rename.php +++ b/action/rename.php @@ -75,7 +75,7 @@ public function addsvgbutton(Doku_Event $event) { if(!$INFO['exists']) { return; } - array_splice($event->data['items'], -1, 0, [new \dokuwiki\plugin\move\MenuItem()]); + array_splice($event->data['items'], -1, 0, array(new \dokuwiki\plugin\move\MenuItem())); } /** From 9aafe3bd975c319f245b8b04cab2e0fb477d52c9 Mon Sep 17 00:00:00 2001 From: Olelsii Date: Tue, 20 Feb 2018 16:25:05 +0100 Subject: [PATCH 280/338] translation update --- lang/uk/lang.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lang/uk/lang.php b/lang/uk/lang.php index 4a45999..a2d0c27 100644 --- a/lang/uk/lang.php +++ b/lang/uk/lang.php @@ -3,7 +3,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * - * @author Oleksii + * @author Olelsii */ $lang['menu'] = 'Переміщення сторінок і просторів назв'; $lang['inprogress'] = '(очікування переміщення)'; @@ -28,3 +28,19 @@ $lang['inexecution'] = 'Попереднє перейменування не завершено -- нажміть кнопки нижче щоб продовжити або зупинити процес.'; $lang['btn_start'] = 'Почати'; $lang['btn_continue'] = 'Продовжити'; +$lang['btn_retry'] = 'Повторити'; +$lang['btn_skip'] = 'Пропустити'; +$lang['btn_abort'] = 'Зупинити'; +$lang['movepage'] = 'Перенести сторінку'; +$lang['movens'] = 'Перенести простір назв'; +$lang['dst'] = 'Нова назва:'; +$lang['content_to_move'] = 'Перенести зміст:'; +$lang['move_pages'] = 'Сторінок'; +$lang['move_media'] = 'Медіа файли'; +$lang['move_media_and_pages'] = 'Сторінки та медіа файли'; +$lang['renamepage'] = 'Перейменована сторінка'; +$lang['js']['rename'] = 'Перейменувати'; +$lang['js']['cancel'] = 'Відмінити'; +$lang['js']['newname'] = 'Нова назва:'; +$lang['js']['complete'] = 'Операцію перенесення закінчено.'; +$lang['js']['renameitem'] = 'Перейменувати це '; From 51e6c3402aea4034b9723a3455767dd88fff4e6a Mon Sep 17 00:00:00 2001 From: damiano Date: Mon, 23 Apr 2018 16:35:37 +0200 Subject: [PATCH 281/338] translation update --- lang/it/lang.php | 88 ++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/lang/it/lang.php b/lang/it/lang.php index 6f022ef..fa96a3a 100644 --- a/lang/it/lang.php +++ b/lang/it/lang.php @@ -1,62 +1,38 @@ + * + * @author damiano + * @author Dario Sguassero */ - -// settings must be present and set appropriately for the language -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; - -// for admin plugins, the menu prompt to be displayed in the admin menu -// if set here, the plugin doesn't need to override the getMenuText() method -$lang['menu'] = 'Pagina/Namespace Sposta/Rinomina...'; -$lang['desc'] = 'Page/Namespace Sposta/Rinomina Plugin'; - -$lang['notexist'] = 'La pagina %s non esiste'; -$lang['medianotexist'] = 'Il file media %s non esiste'; -$lang['notwrite'] = 'Non hai permessi sufficienti per modificare questa pagina'; -$lang['badns'] = 'Carattere invalido nel namespace.'; -$lang['badname'] = 'Carattere invalido nel nome della pagina'; -$lang['nochange'] = 'Il nome della pagina ed il namespace non sono stati modificati.'; -$lang['nomediachange'] = 'Il nome del file media e il namespace non sono stati modificati.'; -$lang['existing'] = 'Una pagina chiamata %s esiste già in %s'; -$lang['mediaexisting'] = 'Un file media chiamato %s esiste già in %s'; -$lang['root'] = '[Namespace radice]'; -$lang['current'] = '(Corrente)'; -$lang['renamed'] = 'Il nome della pagina è stato cambiato da %s a %s'; -$lang['moved'] = 'Pagina spostata da %s a %s'; -$lang['move_rename'] = 'Pagina spostata e rinominata da %s a %s'; -$lang['delete'] = 'Cancellato da move (sposta) plugin'; -$lang['norights'] = 'Non hai permessi sufficienti per modificare %s.'; -$lang['nomediarights'] = 'Non hai permessi sufficienti per cancellare %s.'; -$lang['notargetperms'] = 'Non hai permessi sufficienti per creare la pagina %s.'; -$lang['nomediatargetperms'] = 'Non hai i permessi per creare il file media %s.'; -$lang['filelocked'] = 'La pagina %s è bloccata. Riprova più tardi.'; -$lang['linkchange'] = 'Collegamento modificati a causa di un\'operazione di spostamento'; - -$lang['ns_move_in_progress'] = 'E\' in corso un\'operazione di spostamento di %s pagine e %s file media dal namespace %s al namespace %s.'; -$lang['ns_move_continue'] = 'Continua lo spostamento del namespace'; -$lang['ns_move_abort'] = 'Interrompi lo spostamento del namespace'; -$lang['ns_move_continued'] = 'Lo spostamento del namespace dal namespace %s al namespace %s è ripresa, rimangono ancora %s elementi.'; -$lang['ns_move_started'] = 'Lo spostamento di un namespace dal namespace %s al namespace %s è iniziata, %s pagine e %s file media saranno mossi.'; -$lang['ns_move_error'] = 'E\' successo un errore mentre era stava continuando lo spostamento del namespace da %s a %s.'; -$lang['ns_move_tryagain'] = 'Riprova'; -$lang['ns_move_skip'] = 'Salta l\'elemento corrente'; -// Form labels -$lang['newname'] = 'Nome della nuova pagina:'; -$lang['newnsname'] = 'Nome del nuovo namespace:'; -$lang['targetns'] = 'Seleziona il nuovo namespace:'; -$lang['newtargetns'] = 'Crea un nuovo namespace:'; -$lang['movepage'] = 'Sposta la pagina'; -$lang['movens'] = 'Sposta il namespace'; -$lang['submit'] = 'Invia'; -$lang['content_to_move'] = 'Contenuto da spostare'; -$lang['move_pages'] = 'Pagine'; -$lang['move_media'] = 'File media'; -$lang['move_media_and_pages'] = 'Pagine e file media'; -// JavaScript preview -$lang['js']['previewpage'] = 'OLDPAGE saranno spostate nelle NEWPAGE'; -$lang['js']['previewns'] = 'Tutte le pagine ed i namespace nel namespace OLDNS saranno mossi verso il namespace NEWNS'; +$lang['menu'] = 'Pagina/Namespace Sposta/Rinomina...'; +$lang['inprogress'] = '(in sospeso)'; +$lang['treelink'] = 'In alternativa a questo semplice modulo puoi gestire la ristrutturazione complessa della tua wiki usando il tree-based gestore di movimento basato su albero .'; +$lang['notexist'] = 'La pagina %s non esiste'; +$lang['norights'] = 'Non hai permessi sufficienti per modificare %s.'; +$lang['filelocked'] = 'La pagina %s è bloccata. Riprova più tardi.'; +$lang['notchanged'] = 'Nessuna nuova destinazione indicata per la pagina %s (posizione invariata).'; +$lang['exists'] = 'La pagina% s non può essere spostata su %s, la destinazione esiste già.'; +$lang['notargetperms'] = 'Non hai permessi sufficienti per creare la pagina %s.'; +$lang['medianotexist'] = 'Il file media %s non esiste'; +$lang['nomediarights'] = 'Non hai permessi sufficienti per cancellare %s.'; +$lang['medianotchanged'] = 'Nessuna nuova destinazione indicata per la pagina %s (posizione invariata).'; +$lang['mediaexists'] = 'Il supporto%s non può essere spostato su %s, la destinazione esiste già.'; +$lang['nomediatargetperms'] = 'Non hai i permessi per creare il file media %s.'; +$lang['indexerror'] = 'Errore durante l\'aggiornamento dell\'indice di ricerca %s'; +$lang['metamoveerror'] = 'I meta file della pagina %s non possono essere spostati'; +$lang['renamed'] = 'Il nome della pagina è stato cambiato da %s a %s'; +$lang['moved'] = 'Pagina spostata da %s a %s'; +$lang['move_rename'] = 'Pagina spostata e rinominata da %s a %s'; +$lang['delete'] = 'Cancellato da move (sposta) plugin'; +$lang['linkchange'] = 'Collegamento modificati a causa di un\'operazione di spostamento'; +$lang['movepage'] = 'Sposta la pagina'; +$lang['movens'] = 'Sposta il namespace'; +$lang['content_to_move'] = 'Contenuto da spostare'; +$lang['move_pages'] = 'Pagine'; +$lang['move_media'] = 'File media'; +$lang['move_media_and_pages'] = 'Pagine e file media'; +$lang['root'] = '[Namespace radice]'; From 6e4616c1b8e86da2b46e2dc3e28f06d8102f47a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Apr 2018 10:54:53 +0200 Subject: [PATCH 282/338] Version upped for Greebo --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index ffbbaa8..cfb8c1c 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2017-01-07 +date 2018-04-30 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 57fff8775561ce04b4c5c4b969d9cb40370a8ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= Date: Mon, 30 Apr 2018 11:03:03 +0200 Subject: [PATCH 283/338] chore: test only on supported PHP versions --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6540e22..3141dba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: php php: - - "5.5" - - "5.4" - - "5.3" + - "7.2" + - "7.1" + - "7.0" + - "5.6" env: - DOKUWIKI=master - DOKUWIKI=stable From ab15946e441e15a32adb0127cba46e59101270d3 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 1 Oct 2018 21:00:23 +0200 Subject: [PATCH 284/338] Rewrite helper: discard empty metadata At least during tests, the metadata of the move plugin is initialised with an empty string which leads to errors in PHP >= 7.1. --- helper/rewrite.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helper/rewrite.php b/helper/rewrite.php index 9e55b2b..73ae471 100644 --- a/helper/rewrite.php +++ b/helper/rewrite.php @@ -56,7 +56,8 @@ public function getMoveMeta($id) { } */ - $meta = isset($all_meta[self::METAKEY]) ? $all_meta[self::METAKEY] : array(); + // discard missing or empty array or string + $meta = !empty($all_meta[self::METAKEY]) ? $all_meta[self::METAKEY] : array(); if(!isset($meta['origin'])) { $meta['origin'] = ''; } From ee07a9d177bc41fccc9d9967bf405d5b2353046e Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 1 Oct 2018 21:02:41 +0200 Subject: [PATCH 285/338] Plan helper: initialize all arrays This avoids errors when using count() on that array later. --- helper/plan.php | 1 + 1 file changed, 1 insertion(+) diff --git a/helper/plan.php b/helper/plan.php index cb24f6b..fd78216 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -56,6 +56,7 @@ class helper_plugin_move_plan extends DokuWiki_Plugin { 'pages' => array(), 'media' => array(), 'ns' => array(), + 'affpg' => array(), 'miss' => array(), 'miss_media' => array(), ); From fc4412ff0c05b659497e515d0daa58e943af79d6 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Mon, 1 Oct 2018 21:04:14 +0200 Subject: [PATCH 286/338] Plan tests: store error on mocked failure This avoids errors later as the code assumes that on failure an error message has been triggered. --- _test/stepThroughDocuments.test.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_test/stepThroughDocuments.test.php b/_test/stepThroughDocuments.test.php index 928c387..dadc41c 100644 --- a/_test/stepThroughDocuments.test.php +++ b/_test/stepThroughDocuments.test.php @@ -42,6 +42,8 @@ class helper_plugin_move_op_mock extends helper_plugin_move_op { public function movePage($src, $dst) { if ($this->fail !== false && count($this->movedPages) == $this->fail) { $this->fail=false; + // Store a msg as it is expected by the plugin + msg("Intentional failure in test case.", -1); return false; } $moveOperation = array($src => $dst); From c3e93b511a239fb826f182c61c4a930f01d85d27 Mon Sep 17 00:00:00 2001 From: Hakan Date: Wed, 14 Nov 2018 14:25:12 +0100 Subject: [PATCH 287/338] translation update --- lang/tr/lang.php | 36 ++++++++++++++++++++++++++++++++++++ lang/tr/progress.txt | 3 +++ 2 files changed, 39 insertions(+) create mode 100644 lang/tr/lang.php create mode 100644 lang/tr/progress.txt diff --git a/lang/tr/lang.php b/lang/tr/lang.php new file mode 100644 index 0000000..26ea42f --- /dev/null +++ b/lang/tr/lang.php @@ -0,0 +1,36 @@ + + */ +$lang['menu'] = 'Sayfaları ve ad alanlarını taşıma'; +$lang['inprogress'] = '(devam et)'; +$lang['intro'] = 'Hareket işlemi henüz başlatılmamış!'; +$lang['preview'] = 'Yürütülecek değişiklikleri önizleyin.'; +$lang['inexecution'] = 'Önceki bir hareket tamamlanmadı. Yürütmeye devam etmek veya iptal etmek için aşağıdaki düğmeleri kullanın.'; +$lang['btn_start'] = 'Başla'; +$lang['btn_continue'] = 'Devam et'; +$lang['btn_skip'] = 'Öğeyi atla'; +$lang['btn_abort'] = 'İptal et'; +$lang['legend'] = 'Geçerli sayfayı veya ad alanını taşı'; +$lang['movepage'] = 'Sayfayı taşı'; +$lang['movens'] = 'Ad alanını taşı'; +$lang['dst'] = 'Yeni isim:'; +$lang['content_to_move'] = 'Taşınacak içerik:'; +$lang['autoskip'] = 'Hataları yoksay ve taşınamayan sayfaları veya dosyaları atla'; +$lang['autorewrite'] = 'Hareket tamamlandıktan hemen sonra bağlantıları yeniden yaz'; +$lang['move_pages'] = 'Sayfalar'; +$lang['move_media'] = 'Medya dosyaları'; +$lang['move_media_and_pages'] = 'Sayfalar ve medya dosyaları'; +$lang['nodst'] = 'Yeni ad yok'; +$lang['noaction'] = 'Tanımlanan hareket yok'; +$lang['renamepage'] = 'Sayfayı Yeniden Adlandır'; +$lang['cantrename'] = 'Sayfa şu anda yeniden adlandırılamaz. Lütfen daha sonra tekrar deneyin.'; +$lang['js']['cancel'] = 'İptal et'; +$lang['js']['newname'] = 'Yeni isim:'; +$lang['js']['complete'] = 'Taşıma işlemi bitti.'; +$lang['root'] = '[Kök ad alanı]'; +$lang['noscript'] = 'Bu özellik JavaScript gerektirir'; +$lang['moveinprogress'] = 'Şu anda devam eden başka bir hareket işlemi var, şu anda bu aracı kullanamazsınız.'; diff --git a/lang/tr/progress.txt b/lang/tr/progress.txt new file mode 100644 index 0000000..127d1af --- /dev/null +++ b/lang/tr/progress.txt @@ -0,0 +1,3 @@ +====== Devam Ediyor... ====== + +Hareket ilerledikçe lütfen bu sayfayı açık tutunuz. \ No newline at end of file From 205cf38c78340dd3b10ecd47a938b3f331f1660b Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Fri, 30 Nov 2018 11:35:04 +0100 Subject: [PATCH 288/338] translation update --- lang/el/lang.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lang/el/lang.php diff --git a/lang/el/lang.php b/lang/el/lang.php new file mode 100644 index 0000000..a0e6e0c --- /dev/null +++ b/lang/el/lang.php @@ -0,0 +1,26 @@ + + */ +$lang['menu'] = 'Μετακινείστε σελίδες και κενά ονομάτων'; +$lang['inprogress'] = '(μετακίνηση εκκρεμοτήτων)'; +$lang['treelink'] = 'Κατ\'εναλλαγή προς αυτή την απλή φόρμα μπορείτε να ανοικοδομήστε το σύμπλεγμα wiki σας χρησιμοποιώντας tree-based move manager '; +$lang['notexist'] = 'Η σελίδα %s δεν υπάρχει'; +$lang['norights'] = 'Δεν έχετε επαρκείς άδειες να εκδώσετε %s. '; +$lang['filelocked'] = 'Η σελίδα %s είναι κλειδωμένη. Παρακαλώ προσπαθήστε ξανά. '; +$lang['notchanged'] = 'Ο νέος προορισμός που δόθηκε για την σελίδα %s (η τοποθεσία δεν άλλαξε).'; +$lang['exists'] = 'Η σελίδα δεν μπορεί να μετακινηθεί στο %s, ο προορισμός υπάρχει ήδη.'; +$lang['notargetperms'] = 'Δεν έχετε την άδεια να δημιουργήσετε την σελίδα %s.'; +$lang['medianotexist'] = 'Το αρχείο μέσων ενημέρωσης %s δεν υπάρχει'; +$lang['nomediarights'] = 'Δεν έχετε άδεια να καταργήσετε το %s.'; +$lang['medianotchanged'] = 'Ο νέος προορισμός που δόθηκε για την σελίδα %s (η θέση δεν άλλαξε)'; +$lang['mediaexists'] = 'Τα μέσα %s δεν μπορούν να μετακινηθούν στο %s, ο προορισμός υπάρχει ήδη.'; +$lang['nomediatargetperms'] = 'Δεν έχετε άδεια να δημιουργήσετε τον φάκελλο μέσων ενημέρωσης %s'; +$lang['indexerror'] = 'Υπήρξε σφάλμα κατά την ενημέρωση του δείκτη %s.'; +$lang['metamoveerror'] = '5Οι φάκελλοι meta της σελίδας %s δεν μπόρεσαν να μετακινηθούν'; +$lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; +$lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; +$lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; From 4cab1d53f244a2c6bd1e73e09cd1671ee77567f1 Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Sun, 2 Dec 2018 19:45:05 +0100 Subject: [PATCH 289/338] translation update --- lang/el/lang.php | 39 +++++++++++++++++++++++++++++++++++++++ lang/el/move.txt | 8 ++++++++ 2 files changed, 47 insertions(+) create mode 100644 lang/el/move.txt diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..98448ec 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -24,3 +24,42 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['mediaatticmoveerror'] = 'Οι αττικοί φάκελλοι του μεσαίου φακέλλου %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους χειροκίνητα.'; +$lang['renamed'] = 'Το όνομα της σελίδας άλλαξε από %s σε% s '; +$lang['moved'] = 'Η σελίδα μετακινήθηκε από το %s στο% s '; +$lang['move_rename'] = 'Η σελίδα μετακινήθηκε και μετονομάστηκε από% s σε %s '; +$lang['delete'] = 'Διαγράφηκε μετακινώντας το επιπρόσθετο'; +$lang['linkchange'] = 'Οι ιστοσελίδες προσαρμόστηκαν λόγω προσπάθειας μετακίνησης'; +$lang['intro'] = 'Η διαδικασία μετακίνησης δεν έχει αρχίσει, ακόμη!'; +$lang['preview'] = 'Ελέγξετε εκ των προτέρων τις αλλαγές που πρέπει να γίνουν.'; +$lang['inexecution'] = 'Δεν έγινε προηγούμενη μετακίνηση-χρησιμοποιείστε τα πλήκτρα πιο κάτω για να συνεχίσετε ή σταματήστε την εκτέλεση.'; +$lang['btn_start'] = 'Έναρξη '; +$lang['btn_continue'] = 'Συνέχεια'; +$lang['btn_retry'] = 'Ξαναπροσπαθήστε το θέμα'; +$lang['btn_skip'] = 'Παραλείψετε το θέμα'; +$lang['btn_abort'] = 'Αφαίρεση'; +$lang['legend'] = 'Μετακινήστε την τρέχουσα σελίδα ή το διάστημα με όνομα'; +$lang['movepage'] = 'Μετακινείστε την σελίδα'; +$lang['movens'] = 'Μετακινήστε το κενό ονόματος'; +$lang['dst'] = 'Νέο όνομα:'; +$lang['content_to_move'] = 'Περιεχόμενο προς μετακίνηση:'; +$lang['autoskip'] = 'Αγνοήστε τα λάθη και παραλείψετε σελίδες ή αρχεία που δεν μπορούν να μετακινηθούν'; +$lang['autorewrite'] = 'Ξαναγράψετε τους συνδέσμους μετά την ολοκλήρωση της μετακίνησης'; +$lang['move_pages'] = 'Σελίδες'; +$lang['move_media'] = 'Αρχεία μέσων ενημέρωσης'; +$lang['move_media_and_pages'] = 'Σελίδες και φάκελλοι μέσων ενημέρωσης'; +$lang['nodst'] = 'Δεν δόθηκε νέο όνομα'; +$lang['noaction'] = 'Δεν έγιναν προκαθορισμένες μετακινήσεις'; +$lang['renamepage'] = 'Μετονομάστε την Σελίδα'; +$lang['cantrename'] = 'Η σελίδα δεν μπορεί να μετονομαστεί αμέσως τώρα. Παρακαλώ προσπαθήστε αργότερα.'; +$lang['js']['rename'] = 'Μετονομάστε'; +$lang['js']['cancel'] = 'Ακυρώστε'; +$lang['js']['newname'] = ' Νέο όνομα :'; +$lang['js']['inprogress'] = 'μετονομασία σελίδων και προσαρμογή συνδέσμων'; +$lang['js']['complete'] = 'Η διαδικασία της μετακίνησης ολοκληρώθηκε'; +$lang['js']['renameitem'] = 'Μετονομάστε αυτό το θέμα'; +$lang['js']['add'] = 'Δημιουργήστε ένα νέο χώρο ονόματος'; +$lang['js']['duplicate'] = 'Λυπάμαι, το \'\'%s\'\' υπάρχει ήδη σε αυτό το χώρο ονόματος'; +$lang['root'] = '{Βασικός χώρος ονόματος}'; +$lang['noscript'] = 'Αυτό το χαρακτηριστικό χρειάζεται JavaScript'; +$lang['moveinprogress'] = 'Υπάρχει μια άλλη διαδικασία μετακίνησης σε εξέλιξη τώρα, δεν μπορείτε να χρησιμοποιήστε αυτό το εργαλείο.'; diff --git a/lang/el/move.txt b/lang/el/move.txt new file mode 100644 index 0000000..98f9a78 --- /dev/null +++ b/lang/el/move.txt @@ -0,0 +1,8 @@ +-------Μετακίνηση--------- +Αυτό το επιπρόσθετο σας επιτρέπει να μετακινήσετε και/ή μετονομάστε την παρούσα σελίδα ή μετακινήστε και/ή μετονομάστε τον τρέχοντα χώρο ονόματος στα πλαίσια των ακόλουθων περιορισμών: + +* Πρέπει να έχετε άδεια έκδοσης για αυτήν την σελίδα/όλες τις σελίδες στο παρόντα κενό χώρο. +* Οι σελίδες που μετακινούνται δεν πρέπει να είναι κλειδωμένες για έκδοση. +-Για να μετακινήσετε μια σελίδα πρέπει επίσης να δημιουργήσετε 'άδεια' στον κενό χώρο ονομασίας. +-Δεν μπορείτε να μετακινήσετε μια σελίδα σε χώρο ονόματος όπου υπάρχει μια σελίδα με το ίδιο όνομα. +Όλες οι ιστοσελίδες από και προς τις σελίδες που μετακινούνται θα ενημερωθούν για να απεικονίσουν το νέο μέρος και/ή όνομα. \ No newline at end of file From ce8e173de91615142692c271c138631b04a3469b Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Tue, 4 Dec 2018 18:10:40 +0100 Subject: [PATCH 290/338] translation update --- lang/el/lang.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..aefd423 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -24,3 +24,33 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['mediaatticmoveerror'] = 'Οι αρχικοί φάκελλοι του φακέλλου μέσων ενημέρωσης δεν μπόρεσαν να %s μετακινηθούν. Παρακαλώ μετακινήστε τους χειροκίνητα.. '; +$lang['renamed'] = 'Το όνομα της σελίδας άλλαξε από %s στο %s '; +$lang['moved'] = 'Η σελίδα μετακινήθηκε από %s στο %s '; +$lang['move_rename'] = 'Η σελίδα μετακινήθηκε και μετονομάστηκε από %s στο %s '; +$lang['delete'] = 'Διαγράφηκε με μετακίνηση του επιπρόσθετου'; +$lang['linkchange'] = 'Οι συνδέσεις ιστοσελίδων έγιναν λόγω μετακίνησης '; +$lang['intro'] = 'Η λειτουργία μετακίνησης δεν έχει αρχίσει ακόμα!'; +$lang['preview'] = 'Ελέγξτε τις αλλαγές που πρέπει να γίνουν'; +$lang['inexecution'] = 'Μια προηγούμενη μετακίνηση δεν ολοκληρώθηκε - χρησιμοποιήστε τα κουμπιά κάτω για να συνεχίσετε την εξαγωγή. '; +$lang['btn_start'] = 'Έναρξη '; +$lang['btn_continue'] = 'Συνεχίστε'; +$lang['btn_retry'] = 'Ξαναπροσπαθήστε'; +$lang['btn_skip'] = 'Παραλείψετε '; +$lang['btn_abort'] = 'Εξάγετε'; +$lang['legend'] = 'Μετακινήστε την παρούσα σελίδα ή χώρο ονόματος'; +$lang['movepage'] = 'Μετακινήστε την σελίδα'; +$lang['movens'] = 'Μετακινήστε τον χώρο ονόματος'; +$lang['dst'] = 'Νέο όνομα :'; +$lang['content_to_move'] = 'Περιεχόμενο προς μετακίνηση:'; +$lang['autoskip'] = 'Αγνοήστε τα λάθη και παραλείψετε σελίδες ή φακέλλους που δεν μπορούν να μετακινηθούν'; +$lang['autorewrite'] = 'Ξαναγράψετε ιστοσελίδες μετά την ολοκλήρωση της μετακίνησης'; +$lang['move_pages'] = 'Σελίδες'; +$lang['move_media'] = 'Αρχεία μέσων ενημέρωσης'; +$lang['move_media_and_pages'] = 'Σελίδες και αρχεία μέσων ενημέρωσης'; +$lang['nodst'] = 'Δεν δόθηκε νέο όνομα'; +$lang['noaction'] = 'Δεν βρέθηκαν μετακινήσεις'; +$lang['renamepage'] = 'Μετονομάστε την σελίδα'; +$lang['cantrename'] = 'Η σελίδα δεν μπορεί να αλλάξει όνομα τώρα. Παρακαλώ προσπαθήσετ αργότερα'; +$lang['js']['rename'] = 'Μετονομάστε'; +$lang['js']['cancel'] = 'Ακυρώστε'; From 475755158abfb07312c8cd385702286d5d84ac6e Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Tue, 4 Dec 2018 18:25:39 +0100 Subject: [PATCH 291/338] translation update --- lang/el/lang.php | 8 ++++++++ lang/el/settings.php | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 lang/el/settings.php diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..01e8207 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -24,3 +24,11 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['js']['newname'] = 'Νέο όνομα'; +$lang['js']['inprogress'] = 'μετονομασία σελίδας και προσαρμογή συνδέσμων'; +$lang['js']['complete'] = 'Η λειτουργία μετακίνησης ολοκληρώθηκε'; +$lang['js']['renameitem'] = 'Μετονομάστε αυτό το θέμα'; +$lang['js']['add'] = 'Δημιουργήστε νέο χώρο για όνομα'; +$lang['js']['duplicate'] = 'Λυπάμαι, "%s" υπάρχει ήδη στο χώρο ονόματος αρχείου. '; +$lang['noscript'] = 'Για μετονομασία χρειάζεταιJavaScript '; +$lang['moveinprogress'] = 'Υπάρχει μια άλλη προσπάθεια μετακίνησης σε εξέλιξη , δεν μπορείτε να χρησιμοποιήσετε αυτό το εργαλείο τώρα. '; diff --git a/lang/el/settings.php b/lang/el/settings.php new file mode 100644 index 0000000..c7124af --- /dev/null +++ b/lang/el/settings.php @@ -0,0 +1,9 @@ + + */ +$lang['autoskip'] = 'Ενεργοποιήστε το αυτόματο σύστημα παράλειψης λαθών στις μετακινήσεις ονόματος αρχείου κατ\'επιλογή'; +$lang['autorewrite'] = 'Ενεργοποιήστε τον αυτόματο σύνδεσμο γραφής μετά την μετακίνηση θέσης ονόματος αρχείου κατ\'επιλογήν'; From 4862ebfe6ebcd2388ab051d50f4935d3dd03b4f9 Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Tue, 4 Dec 2018 18:30:46 +0100 Subject: [PATCH 292/338] translation update --- lang/el/lang.php | 8 ++++++++ lang/el/settings.php | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 lang/el/settings.php diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..01e8207 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -24,3 +24,11 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['js']['newname'] = 'Νέο όνομα'; +$lang['js']['inprogress'] = 'μετονομασία σελίδας και προσαρμογή συνδέσμων'; +$lang['js']['complete'] = 'Η λειτουργία μετακίνησης ολοκληρώθηκε'; +$lang['js']['renameitem'] = 'Μετονομάστε αυτό το θέμα'; +$lang['js']['add'] = 'Δημιουργήστε νέο χώρο για όνομα'; +$lang['js']['duplicate'] = 'Λυπάμαι, "%s" υπάρχει ήδη στο χώρο ονόματος αρχείου. '; +$lang['noscript'] = 'Για μετονομασία χρειάζεταιJavaScript '; +$lang['moveinprogress'] = 'Υπάρχει μια άλλη προσπάθεια μετακίνησης σε εξέλιξη , δεν μπορείτε να χρησιμοποιήσετε αυτό το εργαλείο τώρα. '; diff --git a/lang/el/settings.php b/lang/el/settings.php new file mode 100644 index 0000000..c7124af --- /dev/null +++ b/lang/el/settings.php @@ -0,0 +1,9 @@ + + */ +$lang['autoskip'] = 'Ενεργοποιήστε το αυτόματο σύστημα παράλειψης λαθών στις μετακινήσεις ονόματος αρχείου κατ\'επιλογή'; +$lang['autorewrite'] = 'Ενεργοποιήστε τον αυτόματο σύνδεσμο γραφής μετά την μετακίνηση θέσης ονόματος αρχείου κατ\'επιλογήν'; From ab0d9e66508773af9b75039560e87e817e26d8df Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Tue, 11 Dec 2018 10:55:37 +0100 Subject: [PATCH 293/338] translation update --- lang/el/lang.php | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..77a6ff9 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -3,7 +3,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * - * @author Katerina Katapodi + * @author Katerina Katapodi */ $lang['menu'] = 'Μετακινείστε σελίδες και κενά ονομάτων'; $lang['inprogress'] = '(μετακίνηση εκκρεμοτήτων)'; @@ -24,3 +24,33 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['mediaatticmoveerror'] = 'Οι συνημμένοι φάκελλοι του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσε να μετακινηθεί. Παρακαλώ μετακινείστε τους χειροκίνητα.'; +$lang['renamed'] = 'Το όνομα της σελίδας άλλαξε από %s σε %s '; +$lang['moved'] = 'Η σελίδα μετακινήθηκε από %s σε %s '; +$lang['move_rename'] = 'Η σελίδα μετακινήθηκε και μετονομάστηκε από %s σε %s '; +$lang['delete'] = 'Διαγράφηκε μετακινώντας το plugin '; +$lang['linkchange'] = 'Οι σύνδεσμοι άλλαξαν λόγω μια διαδικασίας μετακίνησης'; +$lang['intro'] = 'Η διαδικασία μετακίνησης δεν άρχισε ακόμη!'; +$lang['preview'] = 'Ελέγξετε τις αλλαγές που θα γίνουν.'; +$lang['inexecution'] = 'Μια προηγούμενη κίνηση δεν ολοκληρώθηκε-χρησιμοποιείστε τα κουμπιά κάτω για να συνεχίσετε ή αφαιρέστε την διαδικασία.'; +$lang['btn_start'] = 'Έναρξη '; +$lang['btn_continue'] = 'Συνέχεια '; +$lang['btn_retry'] = 'Ξαναπροσπαθήσετε '; +$lang['btn_skip'] = 'Παρακάμψετε θέμα'; +$lang['btn_abort'] = 'Αφαίρεση'; +$lang['legend'] = 'Μετακινείστε την παρούσα σελίδα ή τον χώρο ονόματος '; +$lang['movepage'] = 'Μετακινείστε την σελίδα'; +$lang['movens'] = 'Μετακινείστε τον χώρο ονόματος '; +$lang['dst'] = 'Νέο όνομα:'; +$lang['content_to_move'] = 'Περιεχόμενο προς μετακίνηση:'; +$lang['autoskip'] = 'Αγνοήστε τα λάθη και αφήσετε τις σελίδες ή φακέλλους που δεν μπορούν να μετακινηθούν'; +$lang['autorewrite'] = 'Ξαναγράψετε τις ιστοσελίδες ακριβώς όταν έχει ολοκληρωθεί η μετακίνηση'; +$lang['move_pages'] = 'Σελίδες'; +$lang['move_media'] = 'Αρχεία μέσων ενημέρωσης'; +$lang['move_media_and_pages'] = 'Σελίδες και φάκελλοι μέσων ενημέρωσης'; +$lang['nodst'] = 'Δεν δόθηκε νέο όνομα'; +$lang['noaction'] = 'Δεν υπάρχουν συγκεκριμένες κινήσεις'; +$lang['renamepage'] = 'Μετονομάστε την Σελίδα '; +$lang['cantrename'] = 'Η σελίδα δεν μπορεί να αλλάξει όνομα τώρα αμέσως. Παρακαλώ προσπαθήστε αργότερα'; +$lang['js']['rename'] = 'Μετονομάστε'; +$lang['js']['cancel'] = 'Ακυρώστε'; From 77929fc1ce538512b2c84ebf651080b631abe7c8 Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Fri, 14 Dec 2018 18:10:42 +0100 Subject: [PATCH 294/338] translation update --- lang/el/lang.php | 11 ++++++++++- lang/el/move.txt | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 lang/el/move.txt diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..431097a 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -3,7 +3,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * - * @author Katerina Katapodi + * @author Katerina Katapodi */ $lang['menu'] = 'Μετακινείστε σελίδες και κενά ονομάτων'; $lang['inprogress'] = '(μετακίνηση εκκρεμοτήτων)'; @@ -24,3 +24,12 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['js']['newname'] = 'Νέο όνομα :'; +$lang['js']['inprogress'] = 'μετονομασία της σελίδας και ρύθμιση συνδεόμενων ιστοσελίδων..'; +$lang['js']['complete'] = 'Η διαδικασία της μετακίνησης τελείωσε.'; +$lang['js']['renameitem'] = 'Μετονομάστε αυτό το τεμάχιο'; +$lang['js']['add'] = 'Δημιουργείστε ένα νέο όνομα αρχείου'; +$lang['js']['duplicate'] = 'Συγγνώμη, "%s" ήδη υπάρχει σε αυτό το όνομα.. '; +$lang['root'] = '{Αρχικό όνομα}'; +$lang['noscript'] = 'Αυτό το χαρακτηριστικό απαιτεί JavaScript'; +$lang['moveinprogress'] = 'Υπάρχει μια άλλη διαδικασία μετακίνησης σε εξέλιξη τώρα, δεν μπορείτε να δείτε αυτό το εργαλείο μόλις τώρα.'; diff --git a/lang/el/move.txt b/lang/el/move.txt new file mode 100644 index 0000000..4176b92 --- /dev/null +++ b/lang/el/move.txt @@ -0,0 +1,10 @@ +====== Μετακίνηση ====== + +Αυτό η εισαγωγή σας επιτρέπει να μετακινήσετε και/'η να μετονομάσετε την τρέχουσα σελίδα ή να μετακινήσετε και/ή μετονομάσετε το παρόν όνομα σύμφωνα με τους ακόλουθους κανόνες: +* Πρέπει να έχετε άδεια για έκδοση της παρούσας/παρόντων όλων των σελίδων στα τρέχουσα αρχεία. +* Οι σελίδες που μετακινούνται δεν πρέπει να είναι κλειδωμένες για έκδοση. +* Για να μετακινήσετε μια σελίδα πρέπει επίσης να δημιουργήσετε δυνατότητα έκδοσης στο αρχείο που θα στείλετε. +* Δεν μπορείτε να μετακινήσετε μια σελίδα σε ένα αρχείο όπου υπάρχει μια σελίδα με το ίδιο όνομα. +Όλες οι ιστοσελίδες προς και από τις σελίδες μετακίνησης θα ενημερωθούν για να προβάλλουν την νέα τοποθεσία και/'η όνομα. + + From 66df258d5551ded847595bc757d31cbc357be1c9 Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Fri, 14 Dec 2018 18:55:23 +0100 Subject: [PATCH 295/338] translation update --- lang/el/progress.txt | 2 ++ lang/el/settings.php | 12 ++++++++++++ lang/el/tree.txt | 2 ++ 3 files changed, 16 insertions(+) create mode 100644 lang/el/progress.txt create mode 100644 lang/el/settings.php create mode 100644 lang/el/tree.txt diff --git a/lang/el/progress.txt b/lang/el/progress.txt new file mode 100644 index 0000000..4fbed7d --- /dev/null +++ b/lang/el/progress.txt @@ -0,0 +1,2 @@ +====== Μετακίνηση σε Εξέλιξη... ====== +Παρακαλώ κρατήστε αυτήν την σελίδα ανοικτή κατά την διάρκεια της διαδικασίας εξέλιξης. diff --git a/lang/el/settings.php b/lang/el/settings.php new file mode 100644 index 0000000..28d38b8 --- /dev/null +++ b/lang/el/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Συμβάλλετε στην μετονομασία σελίδων σε αυτές τις ομάδες και χρήστες (χωρισμός με κόμμα).'; +$lang['minor'] = 'Θέλετε να σημειώσετε τις ρυθμίσεις των ιστοσελίδων ως ελάσσονες? Οι ελάσσονες αλλαγές δεν θα συμπεριληφθούν στην λίστα των τροφοδοτήσεων RSS και στις εγγραφές με email.'; +$lang['autoskip'] = 'Ενεργοποιείστε την αυτόματη παράλειψη λαθών σε αρχεία που μετακινείτε κατ\'επιλογήν.'; +$lang['autorewrite'] = 'Ενεργοποιείστε το σύνδεσμο αυτόματης επανεγγραφής μετά τις μετακινήσεις αρχείων κατ\'επιλογήν.'; +$lang['pagetools_integration'] = 'Προσθέσετε το πλήκτρο μετονομασίας στα εργαλεία σελίδων.'; diff --git a/lang/el/tree.txt b/lang/el/tree.txt new file mode 100644 index 0000000..ce0deca --- /dev/null +++ b/lang/el/tree.txt @@ -0,0 +1,2 @@ +====== Βασική Μετακίνηση ===== +Αυτή η προβολή σας επιτρέπει να ρυθμίσετε εκ νέου τις ονομασίες αρχείων Wiki, φακέλλους σελίδων και μέσων ενημέρωσης μέσω του Drag'n Drop. From 897ec31fda532e1a8cdd561348bddbc9d72986b6 Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Tue, 29 Jan 2019 18:10:42 +0100 Subject: [PATCH 296/338] translation update --- lang/el/lang.php | 29 +++++++++++++++++++++++++++++ lang/el/move.txt | 8 ++++++++ 2 files changed, 37 insertions(+) create mode 100644 lang/el/move.txt diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..5017e73 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -24,3 +24,32 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['btn_start'] = 'Έναρξη '; +$lang['btn_continue'] = 'Συνέχεια'; +$lang['btn_retry'] = 'Ξαναπροσπαθήστε το ίδιο θέμα'; +$lang['btn_skip'] = 'Παραλείψετε το θέα'; +$lang['btn_abort'] = 'Εξαγωγή'; +$lang['legend'] = 'Τροποποιήστε την τρέχουσα σελίδα ή τίτλο αρχείου'; +$lang['movepage'] = 'Αλλαγή σελίδας'; +$lang['movens'] = 'Αλλαγή ονόματος αρχείου'; +$lang['dst'] = 'Νέο όνομα'; +$lang['content_to_move'] = 'Περιεχόμενο τροποποίησης'; +$lang['autoskip'] = 'Αγνοήστε τα λάθη και παραλείψετε σελίδες ή φακέλλους που δεν επιδέχονται αλλαγή'; +$lang['autorewrite'] = 'Αντιγράψετε πάλι συνδέσμους αμέσως αφού ολοκληρωθεί η αλλαγή'; +$lang['move_pages'] = 'Σελίδες'; +$lang['move_media'] = 'Αρχεία μέσων επικοινωνίας'; +$lang['move_media_and_pages'] = 'Σελίδες και αρχεία μέσων επικοινωνίας'; +$lang['nodst'] = 'Δεν δόθηκε καινούργιο όνομα'; +$lang['noaction'] = 'Δεν βρέθηκαν αλλαγές'; +$lang['renamepage'] = 'Μετονομάστε την Σελίδα'; +$lang['cantrename'] = 'Αυτή η σελίδα δεν μπορεί να μετονομαστεί τώρα. Παρακαλώ προσπαθήστε αργότερα'; +$lang['js']['rename'] = 'Μετονομασία '; +$lang['js']['cancel'] = 'Ακυρώστε'; +$lang['js']['newname'] = 'Καινούργιο όνομα'; +$lang['js']['inprogress'] = 'νέος τίτλος σελίδας και ρύθμιση συνδέσμων'; +$lang['js']['complete'] = 'Η διαδικασία αλλαγής έχει τελειώσει'; +$lang['js']['renameitem'] = 'Δώστε νέο τίτλο θέματος'; +$lang['js']['add'] = 'Δώσετε νέο όνομα στο αρχείο'; +$lang['js']['duplicate'] = 'Λυπάμαι, το\'\' %\'\'s υπάρχει ήδη ως όνομα αρχείο'; +$lang['noscript'] = 'Αυτή η ρύθμιση χρειάζεται JavaScript'; +$lang['moveinprogress'] = 'Υπάρχει ήδη μια νέα ρύθμιση αλλαγής σε εξέλιξη, δεν μπορείτε να χρησιμοποιήσετε αυτό το εργαλείο τώρα.'; diff --git a/lang/el/move.txt b/lang/el/move.txt new file mode 100644 index 0000000..1a7a8e1 --- /dev/null +++ b/lang/el/move.txt @@ -0,0 +1,8 @@ +====== Μετακίνηση ====== +Αυτό το plugin σας επιτρέπει να αλλάξετε και/ή να μετονομάσετε αυτήν την σελίδα ή/και να αλλάξετε αυτόν το όνομα αρχείου με περιορισμούς ως ακολούθως: + +* Πρέπει να έχετε άδεια έκδοσης της παρούσας σελίδας/όλων των σελίδων για αυτόν τον τίτλο αρχείου +*Οι σελίδες που άλλαξαν δεν πρέπει να είναι κλειδωμένες για έκδοση. +*Για αλλαγή σελίδας πρέπει επίσης να δώσετε άδεια στον τίτλο αρχείου προορισμού +*Δεν μπορείτε να δώσετε το ίδιο όνομα στο αρχείο εκεί όπου υπάρχει η σελίδα ήδη με το ίδιο όνομα. +Όλοι οι σύνδεσμοι προς ή από τις σελίδες που άλλαξαν θα ενημερωθούν για να προβάλλουν τον ίδιο τόπο και/ή όνομα. \ No newline at end of file From f6b51660ae8fbaea671970cc65b9a3598d5d881c Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sun, 28 Apr 2019 11:26:59 +0200 Subject: [PATCH 297/338] Cosmetics: Correct copy&paste error in documemtation comments --- MenuItem.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MenuItem.php b/MenuItem.php index de6769c..eec70f1 100644 --- a/MenuItem.php +++ b/MenuItem.php @@ -4,9 +4,9 @@ /** * Class MenuItem * - * Implements the PDF export button for DokuWiki's menu system + * Implements the Rename button for DokuWiki's menu system * - * @package dokuwiki\plugin\dw2pdf + * @package dokuwiki\plugin\move */ class MenuItem extends AbstractItem { From ffbd915d3cc5898c41a14933d79cd03e95561a6b Mon Sep 17 00:00:00 2001 From: Katerina Katapodi Date: Wed, 1 May 2019 10:45:35 +0200 Subject: [PATCH 298/338] translation update --- lang/el/lang.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lang/el/lang.php b/lang/el/lang.php index a0e6e0c..d97e782 100644 --- a/lang/el/lang.php +++ b/lang/el/lang.php @@ -24,3 +24,29 @@ $lang['atticmoveerror'] = 'Οι φάκελλοι attic της σελίδας %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους με το χέρι.'; $lang['mediametamoveerror'] = 'Οι φάκελλοι meta του φακέλλου μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν'; $lang['mediamoveerror'] = 'Η μετακίνηση του φακέλλου μέσων ενημέρωσης %s απέτυχε'; +$lang['mediaatticmoveerror'] = 'Οι αττικοί φάκελλοι μέσων ενημέρωσης %s δεν μπόρεσαν να μετακινηθούν. Παρακαλώ μετακινήστε τους χειροκίνητα. '; +$lang['renamed'] = 'Ο τίτλος της σελίδας άλλαξε από % s σε %s'; +$lang['moved'] = 'Η σελίδα μετακινήθηκε από %s σε %s'; +$lang['move_rename'] = 'H σελίδα μετακινήθηκε και μετονομάστηκε από %s σε %s'; +$lang['delete'] = 'Σβήστηκε μετακινώντας το plugin '; +$lang['linkchange'] = 'Οι σύνδεσμοι προσαρμόστηκαν μέσω διαδικασίας μετακίνησης '; +$lang['intro'] = 'Η διαδικασία μετακίνησης δεν άρχισε ακόμη!'; +$lang['preview'] = 'Δέστε τις αλλαγές που πρέπει να γίνουν.'; +$lang['inexecution'] = 'Μια προηγούμενη αλλαγή δεν ολοκληρώθηκε-χρησιμοποιείστε τα κουμπιά κάτω για να συνεχίσετε την εκτέλεση ή την εξαγωγή.'; +$lang['btn_start'] = 'Έναρξη '; +$lang['btn_continue'] = 'Συνεχίστε'; +$lang['btn_retry'] = 'Προσπαθήστε πάλι'; +$lang['btn_skip'] = 'Παραλείψετε το θέμα '; +$lang['btn_abort'] = 'Εξάγετε '; +$lang['legend'] = 'Μετακινήστε την τρέχουσα σελίδα ή τον χώρο ονομασίας '; +$lang['movepage'] = 'Μετακίνηση σελίδας '; +$lang['movens'] = 'Μετακίνηση χώρου ονομασίας '; +$lang['dst'] = 'Νέο όνομα :'; +$lang['content_to_move'] = 'Περιεχόμενο προς μετακίνηση:'; +$lang['autoskip'] = 'Αγνοήστε τα λάθη και παραλείψετε σελίδες ή φακέλλους που δεν μπορούν να μετακινηθούν'; +$lang['autorewrite'] = 'Ξαναγράψετε συνδέσμους αφού ολοκληρωθεί η μετακίνηση'; +$lang['move_pages'] = 'Σελίδες '; +$lang['renamepage'] = 'Δώστε νέο τίτλο στη σελίδα '; +$lang['cantrename'] = 'Δεν μπορείτε να μετονομάσετε την σελίδα τώρα. Παρακαλώ προσπαθήστε αργότερα.'; +$lang['js']['rename'] = 'Μετονομάστε'; +$lang['js']['cancel'] = 'Ακυρώστε'; From b9f518716648018e73cb847a8ff7c8d530b26279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sur=C3=BD?= Date: Sat, 3 Aug 2019 11:20:26 +0200 Subject: [PATCH 299/338] translation update --- lang/cs/lang.php | 2 ++ lang/cs/settings.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lang/cs/lang.php b/lang/cs/lang.php index 0b6520e..265820a 100644 --- a/lang/cs/lang.php +++ b/lang/cs/lang.php @@ -3,6 +3,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author Robert Surý * @author Tomáš Borland Valenta * @author Pavel Kochman */ @@ -59,6 +60,7 @@ $lang['js']['inprogress'] = 'Přesouvám stránky a upravuji odkazy...'; $lang['js']['complete'] = 'Přesun byl dokončen.'; $lang['js']['renameitem'] = 'Přejmenovat tuto položku'; +$lang['js']['add'] = 'Vytvořit nový jmenný prostor'; $lang['js']['duplicate'] = 'Lituji, ale \'%s\' již existuje ve jmenném prosoru.'; $lang['root'] = '[Kořen]'; $lang['noscript'] = 'Tato vlastost vyžaduje JavaScript'; diff --git a/lang/cs/settings.php b/lang/cs/settings.php index 0a6d83e..282b473 100644 --- a/lang/cs/settings.php +++ b/lang/cs/settings.php @@ -3,9 +3,11 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author Robert Surý * @author Pavel Kochman */ $lang['allowrename'] = 'Povolit přeijmenovat stránky témto skupinám a uživatelům (oddělených čárkou).'; $lang['minor'] = 'Označit úpravu odkaů jako drobná změna? Drobné změny nebudou viditelné v RSS feeds a v odebíraných mailech změn.'; $lang['autoskip'] = 'Zapnout automatické přeskakování chyb při přesouvání namespace.'; $lang['autorewrite'] = 'Zapnout automatické přepisování odkazů po přesunutí namespace.'; +$lang['pagetools_integration'] = 'Přidat tlačítko pro přejmenování do nástrojů stránky'; From bb4102b4120dfcd0433ab8c5be9534fef41c4524 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 4 Aug 2019 18:29:51 +0200 Subject: [PATCH 300/338] Check if JSINFO is defined, closes #31 The other changes proposed in #31 are not necessary as jQuery() already behaves like $(document).read(), see https://api.jquery.com/jQuery/#jQuery3 --- script/rename.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script/rename.js b/script/rename.js index e616301..4eb0071 100644 --- a/script/rename.js +++ b/script/rename.js @@ -3,7 +3,7 @@ * * @author Andreas Gohr */ -if(JSINFO.move_renameokay) +if(JSINFO && JSINFO.move_renameokay) { jQuery('.plugin_move_page') .show() .click(function(e) { @@ -80,3 +80,4 @@ if(JSINFO.move_renameokay) } }) }); +} From 334946ad24138f56126b5fc18a4aab0b2ccea2de Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 4 Aug 2019 18:45:26 +0200 Subject: [PATCH 301/338] Slight rewording of the tree move help --- lang/en/tree.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lang/en/tree.txt b/lang/en/tree.txt index f599e1b..621abf8 100644 --- a/lang/en/tree.txt +++ b/lang/en/tree.txt @@ -2,6 +2,6 @@ This interface allows you to rearrange your wiki's namespaces, pages and media files via Drag'n'Drop. -In case you have to move many files to the same destination you can use the checkboxes as follows: - * check the namespaces, pages or media files you want to reorganize; - * move only one of the checked files to the desired destination. \ No newline at end of file +In order to move many namespaces, pages or media files to the same destination, you can use the checkboxes as follows: + * check the namespaces, pages or media files you want to move; + * move one of the checked items to the desired destination, all selected items will be moved to this destination. From f884dc6da086d3ca76af3952f0b01d3566430f9d Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 4 Aug 2019 18:50:01 +0200 Subject: [PATCH 302/338] Add admin.svg, copy of images/rename.svg closes #168 This icon is displayed in the admin menu. --- admin.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 admin.svg diff --git a/admin.svg b/admin.svg new file mode 100644 index 0000000..1f03921 --- /dev/null +++ b/admin.svg @@ -0,0 +1 @@ + From 5538001d5f14ef1001bf3412d2426f62e07ddf7f Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 6 Aug 2019 14:10:56 +0200 Subject: [PATCH 303/338] Travis: test PHP 7.3 and DokuWiki old-stable, use local phpunit This hopefully fixes builds failing on PHP 7. --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3141dba..fc1d5cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: php php: + - "7.3" - "7.2" - "7.1" - "7.0" @@ -7,6 +8,10 @@ php: env: - DOKUWIKI=master - DOKUWIKI=stable +matrix: + include: + - php: "5.6" + env: DOKUWIKI=old-stable before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh && rm .gitignore install: sh travis.sh -script: cd _test && phpunit --stderr --group plugin_move +script: cd _test && ./phpunit.phar --stderr --group plugin_move From b53c6e1b5fc9c3b66f1ee0ef52e2b406dbd0e66c Mon Sep 17 00:00:00 2001 From: Good Gu Date: Thu, 27 Feb 2020 03:40:30 +0100 Subject: [PATCH 304/338] translation update --- lang/zh-tw/lang.php | 12 ++++++++++-- lang/zh-tw/settings.php | 8 +++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lang/zh-tw/lang.php b/lang/zh-tw/lang.php index d590f81..ce4a660 100644 --- a/lang/zh-tw/lang.php +++ b/lang/zh-tw/lang.php @@ -2,7 +2,8 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * + * @author Good Gu * @author Aaron Wang */ $lang['menu'] = '頁面移動/重新命名……'; @@ -10,7 +11,7 @@ $lang['treelink'] = '您還可以通過樹形移動.來為您的wiki條目結構做複雜調整'; $lang['notexist'] = '頁面 %s 不存在'; $lang['norights'] = '您沒有權限編輯%s.'; -$lang['filelocked'] = '此文件被鎖定 - 請稍後重試'; +$lang['filelocked'] = '文件 %s 被鎖定 - 請稍後重試'; $lang['notchanged'] = '未為頁面%s指定新地址(位置未變)'; $lang['exists'] = '頁面%s無法被移動至%s ,該目標已存在 '; $lang['notargetperms'] = '您沒有權限建立頁面%s.'; @@ -19,6 +20,12 @@ $lang['medianotchanged'] = '未為頁面%s指定新地址(位置未變)'; $lang['mediaexists'] = '媒體文件%s無法被移動至%s,目標已存在。'; $lang['nomediatargetperms'] = '您沒有權限建立媒體文件%s。'; +$lang['indexerror'] = '更新索引 %s 時發生錯誤'; +$lang['metamoveerror'] = '頁面 %s 的 meta 無法移動'; +$lang['atticmoveerror'] = '頁面 %s 的 attic 無法移動,請手動搬移'; +$lang['mediametamoveerror'] = '媒體 %s 的 meta 無法移動'; +$lang['mediamoveerror'] = '移動媒體 %s 的 attic 失敗'; +$lang['mediaatticmoveerror'] = '媒體 %s 的 attic 無法移動,請手動搬移'; $lang['renamed'] = '頁面名由%s改為%s'; $lang['moved'] = '頁面%s被移動至%s'; $lang['move_rename'] = '頁面%s被移動並更名為%s'; @@ -52,6 +59,7 @@ $lang['js']['inprogress'] = '重新命名頁面並修正有關鏈結:'; $lang['js']['complete'] = '移動操作完畢。'; $lang['js']['renameitem'] = '重新命名該項'; +$lang['js']['add'] = '產生新的目錄'; $lang['js']['duplicate'] = '抱歉,"%s"在該目錄已存在'; $lang['root'] = '[根目錄]'; $lang['noscript'] = '此功能需要JavaScript'; diff --git a/lang/zh-tw/settings.php b/lang/zh-tw/settings.php index bdfc838..45b5f1d 100644 --- a/lang/zh-tw/settings.php +++ b/lang/zh-tw/settings.php @@ -2,10 +2,12 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * - * @author Aaron Wang */ - + * + * @author Good Gu + * @author Aaron Wang + */ $lang['allowrename'] = '允許這些用戶/用戶群組重命名頁面(用逗號分隔)'; $lang['minor'] = '將鏈接修正標記為『細微變動』,這樣就不會被列入RSS訂閱或訂閱郵件中。'; $lang['autoskip'] = '目錄移動時,啟用預設自動跳過錯誤'; $lang['autorewrite'] = '目錄移動時,啟用預設自動修正鏈接'; +$lang['pagetools_integration'] = '在頁面工具欄中加入重新命名'; From 3f59277feda75c2dfa86443720bb3810fcb6b871 Mon Sep 17 00:00:00 2001 From: Thien Hau Date: Fri, 8 May 2020 06:05:08 +0200 Subject: [PATCH 305/338] translation update --- lang/vi/lang.php | 65 ++++++++++++++++++++++++++++++++++++++++++++ lang/vi/move.txt | 10 +++++++ lang/vi/progress.txt | 3 ++ lang/vi/settings.php | 12 ++++++++ lang/vi/tree.txt | 7 +++++ 5 files changed, 97 insertions(+) create mode 100644 lang/vi/lang.php create mode 100644 lang/vi/move.txt create mode 100644 lang/vi/progress.txt create mode 100644 lang/vi/settings.php create mode 100644 lang/vi/tree.txt diff --git a/lang/vi/lang.php b/lang/vi/lang.php new file mode 100644 index 0000000..ad97f75 --- /dev/null +++ b/lang/vi/lang.php @@ -0,0 +1,65 @@ + + */ +$lang['menu'] = 'Di chuyển trang và không gian tên'; +$lang['inprogress'] = '(di chuyển đang chờ xử lý)'; +$lang['treelink'] = 'Ngoài ra, với hình thức đơn giản này, bạn có thể quản lý việc tái cấu trúc phức tạp wiki của mình bằng cách sử dụng quản lý di chuyển dựa trên cây.'; +$lang['notexist'] = 'Trang %s không tồn tại'; +$lang['norights'] = 'Bạn không có đủ quyền để sửa đổi %s.'; +$lang['filelocked'] = 'Trang %s đã bị khóa. Thử lại sau.'; +$lang['notchanged'] = 'Không có đích đến mới cho trang %s (vị trí không thay đổi).'; +$lang['exists'] = 'Không thể di chuyển trang %s đến %s, đích đến đã tồn tại.'; +$lang['notargetperms'] = 'Bạn không có quyền tạo trang %s.'; +$lang['medianotexist'] = 'Không tồn tại tập tin phương tiện %s'; +$lang['nomediarights'] = 'Bạn không có đủ quyền để xóa %s.'; +$lang['medianotchanged'] = 'Không có đích đến mới cho trang %s (vị trí không thay đổi).'; +$lang['mediaexists'] = 'Không thể di chuyển phương tiện %s đến %s, đích đến đã tồn tại.'; +$lang['nomediatargetperms'] = 'Bạn không có quyền tạo tập tin phương tiện %s.'; +$lang['indexerror'] = 'Lỗi trong khi cập nhật chỉ mục tìm kiếm %s'; +$lang['metamoveerror'] = 'Không thể di chuyển các tập tin meta của trang %s'; +$lang['atticmoveerror'] = 'Không thể di chuyển các tập tin tum của trang %s. Vui lòng di chuyển chúng thủ công.'; +$lang['mediametamoveerror'] = 'Không thể di chuyển các tập tin meta của tập tin phương tiện %s'; +$lang['mediamoveerror'] = 'Di chuyển tập tin phương tiện %s không thành công.'; +$lang['mediaatticmoveerror'] = 'Không thể di chuyển các tập tin tum của tập tin phương tiện %s. Vui lòng di chuyển chúng thủ công.'; +$lang['renamed'] = 'Đã thay đổi tên trang từ %s thành %s'; +$lang['moved'] = 'Đã di chuyển trang từ %s thành %s'; +$lang['move_rename'] = 'Đã di chuyển và đổi tên trang từ %s thành %s'; +$lang['delete'] = 'Đã xóa bằng cách di chuyển plugin'; +$lang['linkchange'] = 'Đã thích nghi liên kết vì một hoạt động di chuyển'; +$lang['intro'] = 'Hoạt động di chuyển chưa được bắt đầu!'; +$lang['preview'] = 'Xem trước các thay đổi sẽ được thực hiện.'; +$lang['inexecution'] = 'Một di chuyển trước đó đã không được hoàn thành - sử dụng các nút bên dưới để tiếp tục hoặc hủy bỏ việc thực hiện.'; +$lang['btn_start'] = 'Bắt đầu'; +$lang['btn_continue'] = 'Tiếp tục'; +$lang['btn_retry'] = 'Thử lại mục'; +$lang['btn_skip'] = 'Bỏ qua mục'; +$lang['btn_abort'] = 'Hủy bỏ'; +$lang['legend'] = 'Di chuyển trang hiện tại hoặc không gian tên'; +$lang['movepage'] = 'Di chuyển trang'; +$lang['movens'] = 'Di chuyển không gian tên'; +$lang['dst'] = 'Tên mới:'; +$lang['content_to_move'] = 'Nội dung cần di chuyển:'; +$lang['autoskip'] = 'Bỏ qua lỗi và bỏ qua các trang hoặc tập tin không thể di chuyển'; +$lang['autorewrite'] = 'Viết lại liên kết ngay sau khi hoàn thành di chuyển'; +$lang['move_pages'] = 'Trang'; +$lang['move_media'] = 'Tập tin phương tiện'; +$lang['move_media_and_pages'] = 'Trang và tập tin phương tiện'; +$lang['nodst'] = 'Không có tên mới nào được chỉ định'; +$lang['noaction'] = 'Không có động thái nào được xác định'; +$lang['renamepage'] = 'Đổi tên trang'; +$lang['cantrename'] = 'Không thể đổi tên trang này ngay bây giờ. Vui lòng thử lại sau.'; +$lang['js']['rename'] = 'Đổi tên'; +$lang['js']['cancel'] = 'Hủy bỏ'; +$lang['js']['newname'] = 'Tên mới'; +$lang['js']['inprogress'] = 'đang đổi tên trang và điều chỉnh liên kết ...'; +$lang['js']['complete'] = 'Đã hoàn thành hoạt động di chuyển.'; +$lang['js']['renameitem'] = 'Đổi tên mục này'; +$lang['js']['add'] = 'Tạo không gian tên mới'; +$lang['js']['duplicate'] = 'Xin lỗi, đã tồn tại "%s" trong không gian tên này.'; +$lang['root'] = '[Không gian tên Gốc]'; +$lang['noscript'] = 'Tính năng này yêu cầu JavaScript'; +$lang['moveinprogress'] = 'Hiện tại đang diễn ra một hoạt động di chuyển khác, bạn không thể sử dụng công cụ này ngay bây giờ.'; diff --git a/lang/vi/move.txt b/lang/vi/move.txt new file mode 100644 index 0000000..dd33d2f --- /dev/null +++ b/lang/vi/move.txt @@ -0,0 +1,10 @@ +====== Di chuyển ====== + +Plugin này cho phép bạn di chuyển và/hoặc đổi tên trang hiện tại hoặc di chuyển và/hoặc đổi tên không gian tên hiện tại với các hạn chế sau: + + * Bạn phải có quyền sửa đổi trang hiện tại/tất cả các trang trong không gian tên hiện tại. + * Không được khóa sửa đổi trang được di chuyển. + * Để di chuyển một trang, bạn cũng cần tạo quyền trong không gian tên đích. + * Bạn không thể di chuyển trang đến không gian tên mà nơi đó đã tồn tại một trang có cùng tên với trang bạn di chuyển. + +Tất cả các liên kết đến và từ các trang được di chuyển sẽ được cập nhật để phản ánh vị trí và/hoặc tên mới. \ No newline at end of file diff --git a/lang/vi/progress.txt b/lang/vi/progress.txt new file mode 100644 index 0000000..7e17c5e --- /dev/null +++ b/lang/vi/progress.txt @@ -0,0 +1,3 @@ +====== Đang thực hiện di chuyển... ====== + +Vui lòng giữ trang này mở trong khi đang thực hiện di chuyển. \ No newline at end of file diff --git a/lang/vi/settings.php b/lang/vi/settings.php new file mode 100644 index 0000000..2788fae --- /dev/null +++ b/lang/vi/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Cho phép đổi tên các trang thành các nhóm và thành viên này (được phân tách bằng dấu phẩy).'; +$lang['minor'] = 'Đánh dấu việc điều chỉnh liên kết là nhỏ? Những thay đổi nhỏ sẽ không được liệt kê trong nguồn cấp dữ liệu RSS và thư đăng ký.'; +$lang['autoskip'] = 'Cho phép tự động bỏ qua các lỗi trong di chuyển không gian tên theo mặc định.'; +$lang['autorewrite'] = 'Cho phép tự động viết lại liên kết sau khi di chuyển không gian tên theo mặc định.'; +$lang['pagetools_integration'] = 'Thêm nút đổi tên vào Công cụ trang'; diff --git a/lang/vi/tree.txt b/lang/vi/tree.txt new file mode 100644 index 0000000..c69bc04 --- /dev/null +++ b/lang/vi/tree.txt @@ -0,0 +1,7 @@ +====== Quản lý di chuyển ===== + +Giao diện này cho phép bạn sắp xếp lại các không gian tên, trang và tập tin phương tiện wiki của bạn thông qua Kéo và Thả. + +Để di chuyển nhiều không gian tên, trang hoặc tập tin phương tiện đến cùng một đích đến, bạn có thể sử dụng các hộp kiểm như sau: + * kiểm tra các không gian tên, trang hoặc tập tin phương tiện bạn muốn di chuyển; + * di chuyển một trong các mục đã chọn đến đích đến mong muốn, tất cả các mục đã chọn sẽ được di chuyển đến đích đến này. \ No newline at end of file From df8cae884365b1776337ae8d5bf43b4dc2ecb6e0 Mon Sep 17 00:00:00 2001 From: Jacob Palm Date: Fri, 22 May 2020 23:55:39 +0200 Subject: [PATCH 306/338] translation update --- lang/da/lang.php | 65 ++++++++++++++++++++++++++++++++++++++++++++ lang/da/move.txt | 10 +++++++ lang/da/progress.txt | 3 ++ lang/da/settings.php | 12 ++++++++ lang/da/tree.txt | 7 +++++ 5 files changed, 97 insertions(+) create mode 100644 lang/da/lang.php create mode 100644 lang/da/move.txt create mode 100644 lang/da/progress.txt create mode 100644 lang/da/settings.php create mode 100644 lang/da/tree.txt diff --git a/lang/da/lang.php b/lang/da/lang.php new file mode 100644 index 0000000..73cf293 --- /dev/null +++ b/lang/da/lang.php @@ -0,0 +1,65 @@ + + */ +$lang['menu'] = 'Flyt sider og navnerum'; +$lang['inprogress'] = '(flytning afventer)'; +$lang['treelink'] = 'Som alternativ til denne simple formular, kan du omstrukturere din wiki ved hjælp af trævisningen i flytningshåndtering.'; +$lang['notexist'] = 'Siden %s findes ikke'; +$lang['norights'] = 'Du har ikke rettigheder til at redigere %s.'; +$lang['filelocked'] = 'Siden %s er låst. Prøv igen senere.'; +$lang['notchanged'] = 'Ingen ny lokation til siden %s angivet (lokation uændret).'; +$lang['exists'] = 'Siden %s kan ikke flyttes til %s, da destinationssiden allerede findes.'; +$lang['notargetperms'] = 'Du har ikke rettigheder til at oprette siden %s.'; +$lang['medianotexist'] = 'Mediefilen %s findes ikke'; +$lang['nomediarights'] = 'Du har ikke rettigheder til at slette %s.'; +$lang['medianotchanged'] = 'Ingen ny lokation til siden %s angivet (lokation uændret).'; +$lang['mediaexists'] = 'Mediet %s kan ikke flyttes til %s, der findes allerede et medie der.'; +$lang['nomediatargetperms'] = 'Du har ikke rettigheder til at oprette mediefilen %s.'; +$lang['indexerror'] = 'Fejl under opdatering af søgeindeks %s'; +$lang['metamoveerror'] = 'Meta filerne til siden %s kunne ikke flyttes'; +$lang['atticmoveerror'] = 'Attic-filerne til siden %s kunne ikke flyttes. Disse skal flyttes manuelt.'; +$lang['mediametamoveerror'] = 'Meta filerne til mediefilen %s kunne ikke flyttes'; +$lang['mediamoveerror'] = 'Flytning af mediefilen %s fejlede'; +$lang['mediaatticmoveerror'] = 'Attic-filerne til mediefilen %s kunne ikke flyttes. Disse skal flyttes manuelt.'; +$lang['renamed'] = 'Sidenavn ændret fra %s til %s'; +$lang['moved'] = 'Side flyttet fra %s til %s'; +$lang['move_rename'] = 'Side flyttet og omdøbt fra %s til %s'; +$lang['delete'] = 'Slettet af flytningsudvidelse'; +$lang['linkchange'] = 'Links tilrettede pga. en flytningsoperation'; +$lang['intro'] = 'Flytningsoperation er ikke startet endnu!'; +$lang['preview'] = 'Forhåndsvisning af ændringer der bliver udført.'; +$lang['inexecution'] = 'En tidligere flytningsoperation blev ikke fuldført - brug knapperne herunder til at fortsætte eller afbryde flytningen.'; +$lang['btn_start'] = 'Start'; +$lang['btn_continue'] = 'Fortsæt'; +$lang['btn_retry'] = 'Forsøg igen'; +$lang['btn_skip'] = 'Spring over'; +$lang['btn_abort'] = 'Afbryd'; +$lang['legend'] = 'Flyt aktuelle side eller navnerum'; +$lang['movepage'] = 'Flyt side'; +$lang['movens'] = 'Flyt navnerum'; +$lang['dst'] = 'Nyt navn:'; +$lang['content_to_move'] = 'Indhold der skal flyttes:'; +$lang['autoskip'] = 'Ignorer fejl, og spring over sider/filer der ikke kan flyttes'; +$lang['autorewrite'] = 'Tilret links når flytning er fuldført'; +$lang['move_pages'] = 'Sider'; +$lang['move_media'] = 'Mediefiler'; +$lang['move_media_and_pages'] = 'Sider og mediefiler'; +$lang['nodst'] = 'Intet nyt navn angivet'; +$lang['noaction'] = 'Der blev ikke defineret nogen flytninger'; +$lang['renamepage'] = 'Omdøb side'; +$lang['cantrename'] = 'Siden kan ikke omdøbes i øjeblikket. Prøv igen senere.'; +$lang['js']['rename'] = 'Omdøb'; +$lang['js']['cancel'] = 'Annuller'; +$lang['js']['newname'] = 'Nyt navn:'; +$lang['js']['inprogress'] = 'omdøber side og tilretter links...'; +$lang['js']['complete'] = 'Flytningsoperation færdig.'; +$lang['js']['renameitem'] = 'Omdøb denne'; +$lang['js']['add'] = 'Opret et nyt navnerum'; +$lang['js']['duplicate'] = 'Beklager, "%s" findes allerede i dette navnerum.'; +$lang['root'] = '[Rod navnerum]'; +$lang['noscript'] = 'Denne handling kræver JavaScript'; +$lang['moveinprogress'] = 'Der er i øjeblikket en anden flytningsoperation i gang, du kan ikke anvende dette værktøj på dette tidspunkt.'; diff --git a/lang/da/move.txt b/lang/da/move.txt new file mode 100644 index 0000000..21a7540 --- /dev/null +++ b/lang/da/move.txt @@ -0,0 +1,10 @@ +====== Flyt ====== + +Denne udvidelse gør dig i stand til at flytte og/eller omdøbe den aktuelle side, eller det aktuelle navnerum, med følgende restriktioner: + + * Du skal have rettigheder til at redigere den aktuelle side/alle sider i det aktuelle navnerum + * Siderne der flyttes må ikke være låst pga. redigering + * For at flytte en side, skal du også have rettigheder til at oprette sider i det navnerum der flyttes til + * Du kan ikke flytte en side til et navnerum, hvor der allerede findes en side med samme navn. + +Alle links til og fra sider der flyttes, vil blive tilrettet så de passer til den nye lokation og/eller det nye navn. \ No newline at end of file diff --git a/lang/da/progress.txt b/lang/da/progress.txt new file mode 100644 index 0000000..9e83c1b --- /dev/null +++ b/lang/da/progress.txt @@ -0,0 +1,3 @@ +===== Flytning i gang... ===== + +Hold venligst denne side åben mens flytningen behandles. \ No newline at end of file diff --git a/lang/da/settings.php b/lang/da/settings.php new file mode 100644 index 0000000..dfdb432 --- /dev/null +++ b/lang/da/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Tillad disse grupper og brugere at omdøbe sider (adskil med komma).'; +$lang['minor'] = 'Markér tilretning af links som mindre rettelser? Mindre rettelser optræder ikke i RSS-feeds elller mails.'; +$lang['autoskip'] = 'Slå overspring af fejl under flytning af navnerum til som standard'; +$lang['autorewrite'] = 'Slå automatisk tilrettelse af links efter flytning af navnerum til som standard'; +$lang['pagetools_integration'] = 'Tilføj omdøbningsknap til sideværktøjer'; diff --git a/lang/da/tree.txt b/lang/da/tree.txt new file mode 100644 index 0000000..dad74fc --- /dev/null +++ b/lang/da/tree.txt @@ -0,0 +1,7 @@ +===== Flytningshåndtering ===== + +Denne side gør dig i stand til at omarrangere din wikis navnerum, sider og mediefiler via træk og slip. + +For at flytte mange navnerum, sider eller mediefiler til det samme navnerum, kan du benytte afkrydsningsfelter som følger: + * Marker de navnerum, sider og/eller mediefiler som du ønsker at flytte + * Træk et af de markerede elementer til den ønskede lokation, og alle øvrige markerede elementer flyttes automatisk med. \ No newline at end of file From 7c5a89d62b67dff85949126719edbeb2d08b9fe0 Mon Sep 17 00:00:00 2001 From: Anna Dabrowska Date: Mon, 17 Aug 2020 18:20:46 +0200 Subject: [PATCH 307/338] Fix deprecated array syntax --- helper/handler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper/handler.php b/helper/handler.php index fdfdb55..0bf17f4 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -142,7 +142,7 @@ public function relativeLink($relold, $new, $type) { if($conf['useslash']) $relold = str_replace('/', ':', $relold); // check if the link was relative - if(strpos($relold, ':') === false ||$relold{0} == '.') { + if(strpos($relold, ':') === false ||$relold[0] == '.') { $wasrel = true; } else { $wasrel = false; @@ -173,7 +173,7 @@ public function relativeLink($relold, $new, $type) { if($remainder) $newrel .= join(':', $remainder) . ':'; $newrel .= noNS($new); $newrel = str_replace('::', ':', trim($newrel, ':')); - if($newrel{0} != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; + if($newrel[0] != '.' && $this->ns && getNS($newrel)) $newrel = '.' . $newrel; // if the old link ended with a colon and the new one is a start page, adjust $newrel = $this->_nsStartCheck($relold,$newrel,$type); From 493b5c2372a3fa85dbc98391eb5fa6577fe18856 Mon Sep 17 00:00:00 2001 From: Brad Bulger Date: Mon, 28 Dec 2020 12:10:14 -0800 Subject: [PATCH 308/338] Fix spellings of "committed" key to avoid undefined array key errors. https://github.com/michitux/dokuwiki-plugin-move/issues/194 --- helper/plan.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/helper/plan.php b/helper/plan.php index fd78216..a1e8289 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -193,12 +193,12 @@ public function inProgress() { } /** - * Check if this plan has been commited, yet + * Check if this plan has been committed, yet * * @return bool */ public function isCommited() { - return $this->options['commited']; + return $this->options['committed']; } /** @@ -251,7 +251,7 @@ public function addMediaNamespaceMove($src, $dst) { * @throws Exception */ protected function addMove($src, $dst, $class = self::CLASS_NS, $type = self::TYPE_PAGES) { - if($this->options['commited']) throw new Exception('plan is commited already, can not be added to'); + if($this->options['committed']) throw new Exception('plan is committed already, can not be added to'); $src = cleanID($src); $dst = cleanID($dst); @@ -283,12 +283,12 @@ public function abort() { * list files * * @throws Exception if you try to commit a plan twice - * @return bool true if the plan was commited + * @return bool true if the plan was committed */ public function commit() { global $conf; - if($this->options['commited']) throw new Exception('plan is commited already, can not be commited again'); + if($this->options['committed']) throw new Exception('plan is committed already, can not be committed again'); helper_plugin_move_rewrite::addLock(); @@ -346,7 +346,7 @@ public function commit() { return false; } - $this->options['commited'] = true; + $this->options['committed'] = true; $this->saveOptions(); return true; @@ -360,7 +360,7 @@ public function commit() { * @throws Exception */ public function nextStep($skip = false) { - if(!$this->options['commited']) throw new Exception('plan is not committed yet!'); + if(!$this->options['committed']) throw new Exception('plan is not committed yet!'); // execution has started if(!$this->options['started']) $this->options['started'] = time(); From 91cfbff164362b3e11feffdf2ec21df26092ef36 Mon Sep 17 00:00:00 2001 From: Damien Regad Date: Sat, 6 Feb 2021 02:07:24 +0100 Subject: [PATCH 309/338] PHPUnit tests: fix function signatures Added return type void to setUp() and tearDown() methods. --- _test/affectedPagesNs.test.php | 4 ++-- _test/cache_handling.test.php | 2 +- _test/findMissingDocuments.test.php | 4 ++-- _test/handler.test.php | 2 +- _test/mediamove.test.php | 2 +- _test/namespace_move.test.php | 4 ++-- _test/pagemove.test.php | 2 +- _test/plan.test.php | 2 +- _test/stepThroughDocuments.test.php | 2 +- _test/tpl.test.php | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/_test/affectedPagesNs.test.php b/_test/affectedPagesNs.test.php index 6b6f31d..3c55dc5 100644 --- a/_test/affectedPagesNs.test.php +++ b/_test/affectedPagesNs.test.php @@ -11,7 +11,7 @@ class plugin_move_affectedPagesNS_test extends DokuWikiTest { protected $pluginsEnabled = array('move',); - public function setUp() { + public function setUp(): void { parent::setUp(); global $USERINFO; global $conf; @@ -24,7 +24,7 @@ public function setUp() { /** * @coversNothing */ - public function tearDown() { + public function tearDown(): void { /** @var helper_plugin_move_plan $plan */ $plan = plugin_load('helper', 'move_plan'); $plan->abort(); diff --git a/_test/cache_handling.test.php b/_test/cache_handling.test.php index a982c89..0dd521c 100644 --- a/_test/cache_handling.test.php +++ b/_test/cache_handling.test.php @@ -11,7 +11,7 @@ */ class plugin_move_cache_handling_test extends DokuWikiTest { - function setUp() { + function setUp(): void { parent::setUpBeforeClass(); $this->pluginsEnabled[] = 'move'; parent::setUp(); diff --git a/_test/findMissingDocuments.test.php b/_test/findMissingDocuments.test.php index fdeb0cd..b231cd6 100644 --- a/_test/findMissingDocuments.test.php +++ b/_test/findMissingDocuments.test.php @@ -32,7 +32,7 @@ class plugin_move_findMissingPages_test extends DokuWikiTest { /** * @coversNothing */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->plan = new helper_plugin_move_plan_findMissingDocuments_mock(); } @@ -41,7 +41,7 @@ public function setUp() { /** * @coversNothing */ - public function tearDown() { + public function tearDown(): void { global $conf; $dirs = array('indexdir','datadir','metadir', 'mediadir'); diff --git a/_test/handler.test.php b/_test/handler.test.php index 1c968b6..cc05be4 100644 --- a/_test/handler.test.php +++ b/_test/handler.test.php @@ -12,7 +12,7 @@ */ class plugin_move_handler_test extends DokuWikiTest { - public function setUp() { + public function setUp(): void { $this->pluginsEnabled[] = 'move'; parent::setUp(); } diff --git a/_test/mediamove.test.php b/_test/mediamove.test.php index ec734bb..da532ac 100644 --- a/_test/mediamove.test.php +++ b/_test/mediamove.test.php @@ -11,7 +11,7 @@ */ class plugin_move_mediamove_test extends DokuWikiTest { - public function setUp() { + public function setUp(): void { $this->pluginsEnabled[] = 'move'; parent::setUp(); } diff --git a/_test/namespace_move.test.php b/_test/namespace_move.test.php index 70f9a22..500a775 100644 --- a/_test/namespace_move.test.php +++ b/_test/namespace_move.test.php @@ -11,7 +11,7 @@ */ class plugin_move_namespace_move_test extends DokuWikiTest { - public function setUp() { + public function setUp(): void { $this->pluginsEnabled[] = 'move'; parent::setUp(); } @@ -19,7 +19,7 @@ public function setUp() { /** * @coversNothing */ - public function tearDown() { + public function tearDown(): void { /** @var helper_plugin_move_plan $plan */ $plan = plugin_load('helper', 'move_plan'); $plan->abort(); diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 9ad5816..991209e 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -21,7 +21,7 @@ class plugin_move_pagemove_test extends DokuWikiTest { // @todo Move page to an ID which already exists // @todo Check backlinks of a sub-namespace page (moving same, up, down, different) - function setUp() { + function setUp(): void { parent::setUpBeforeClass(); $this->pluginsEnabled[] = 'move'; global $ID; diff --git a/_test/plan.test.php b/_test/plan.test.php index 542cd54..37e294a 100644 --- a/_test/plan.test.php +++ b/_test/plan.test.php @@ -15,7 +15,7 @@ class plugin_move_plan_test extends DokuWikiTest { /** * Create some page namespace structure */ - function setUp() { + function setUp():void { $pages = array( 'animals:mammals:bear:brownbear', 'animals:mammals:bear:blackbear', diff --git a/_test/stepThroughDocuments.test.php b/_test/stepThroughDocuments.test.php index dadc41c..313b074 100644 --- a/_test/stepThroughDocuments.test.php +++ b/_test/stepThroughDocuments.test.php @@ -65,7 +65,7 @@ public function movePage($src, $dst) { */ class plugin_move_stepThroughDocuments_test extends DokuWikiTest { - public function setUp() { + public function setUp(): void { parent::setUp(); $opts_file = dirname(DOKU_CONF) . '/data/meta/__move_opts'; if(file_exists($opts_file)){ diff --git a/_test/tpl.test.php b/_test/tpl.test.php index be91f74..256503e 100644 --- a/_test/tpl.test.php +++ b/_test/tpl.test.php @@ -9,7 +9,7 @@ */ class move_tpl_test extends DokuWikiTest { - public function setUp() { + public function setUp(): void { parent::setUp(); } From 79f824ccff21315ee8b99c86ea5b95ce91914ad5 Mon Sep 17 00:00:00 2001 From: Damien Regad Date: Sat, 6 Feb 2021 02:24:02 +0100 Subject: [PATCH 310/338] PHPUnit tests: fix "Undefined array key 1" error --- helper/plan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/plan.php b/helper/plan.php index a1e8289..7cbef21 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -623,7 +623,7 @@ protected function stepThroughNamespaces() { $lines = explode("\n", $lines); foreach($lines as $line) { - list($src, $dst) = explode("\t", trim($line)); + list($src, $dst) = explode("\t", trim($line) . "\t"); $FileMover->moveNamespaceSubscription($src, $dst); } From 6a0dbb3d1e11107077ca487fb4f9a8ec8bb82332 Mon Sep 17 00:00:00 2001 From: bleistivt Date: Sat, 23 Oct 2021 01:42:13 +0200 Subject: [PATCH 311/338] German translation: added comma --- lang/de/lang.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/de/lang.php b/lang/de/lang.php index 234110b..ee997f1 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -31,7 +31,7 @@ $lang['moved'] = 'Seite von %s nach %s verschoben'; $lang['move_rename'] = 'Seite von %s nach %s verschoben und umbenannt'; $lang['delete'] = 'Gelöscht durch das move Plugin'; -$lang['linkchange'] = 'Links angepasst weil Seiten im Wiki verschoben wurden'; +$lang['linkchange'] = 'Links angepasst, weil Seiten im Wiki verschoben wurden'; $lang['intro'] = 'Die Verschiebung wurde noch nicht gestartet!'; $lang['preview'] = 'Vorschau der Änderungen, die ausgeführt werden sollen '; $lang['inexecution'] = 'Eine vorherige Verschiebung wurde nicht beendet - benutzen Sie die Knöpfe unten um die Verschiebung fortzusetzen oder abzubrechen. '; From 8ad5b489d08f976e696c59731b3f44f6d8b4f133 Mon Sep 17 00:00:00 2001 From: Viktor Kristian Date: Thu, 13 Jan 2022 20:17:01 +0100 Subject: [PATCH 312/338] added translation to sk language --- lang/sk/lang.php | 72 ++++++++++++++++++++++++++++++++++++++++++++ lang/sk/move.txt | 11 +++++++ lang/sk/progress.txt | 3 ++ lang/sk/settings.php | 11 +++++++ lang/sk/tree.txt | 8 +++++ 5 files changed, 105 insertions(+) create mode 100644 lang/sk/lang.php create mode 100644 lang/sk/move.txt create mode 100644 lang/sk/progress.txt create mode 100644 lang/sk/settings.php create mode 100644 lang/sk/tree.txt diff --git a/lang/sk/lang.php b/lang/sk/lang.php new file mode 100644 index 0000000..309f654 --- /dev/null +++ b/lang/sk/lang.php @@ -0,0 +1,72 @@ + + */ + +$lang['menu'] = 'Presun/premenovanie stránky'; +$lang['inprogress'] = '(prebieha presun)'; +$lang['treelink'] = 'Ako alternatívu k tomuto jednoduchému formuláru môžte použiť stromový manažér presuov na komplexné preskupovanie vašej wiki.'; + +$lang['notexist'] = 'Stránka \'%s\' neexistuje.'; +$lang['norights'] = 'Nedostatočné oprávnenie editovať \'%s\'.'; +$lang['filelocked'] = 'Stránka \'%s\' je uzamknutá - skúste prosím neskôr.'; +$lang['notchanged'] = 'Žiaden nový cieľ pre stránku \'%s\' nezadaný (umiestnenie nezmenené).'; +$lang['exists'] = 'Stránku \'%s\' nie je možné do \'%s\', cieľ už existuje.'; +$lang['notargetperms'] = 'Nemáte dostatočné oprávnenie vytvoriť stránku \'%s\'.'; + +$lang['medianotexist'] = 'Médium \'%s\' neexistuje.'; +$lang['nomediarights'] = 'Nemáte dostatočné oprávnenie na zmazanie \'%s\'.'; +$lang['medianotchanged'] = 'Žiaden nový cieľ pre stránku \'%s\' nezadaný (umiestnenie nezmenené).'; +$lang['mediaexists'] = 'Médium \'%s\' nie je možné do \'%s\', cieľ už existuje.'; +$lang['nomediatargetperms'] = 'Nemáte dostatočné oprávnnenie vytvoriť médium \'%s\'.'; + +$lang['indexerror'] = 'Chyba pri aktualizácii indexu vyhľadávania \'%s\'.'; +$lang['metamoveerror'] = 'Meta súbory stránky \'%s\' nemôžu byť presunuté.'; +$lang['atticmoveerror'] = 'Staré verzie stránky \'%s\' nemôžu byť presunuté. Prosím, presuňte ich ručne.'; +$lang['mediametamoveerror'] = 'Meta súbory média \'%s\' nemôžu byť presunuté.'; +$lang['mediamoveerror'] = 'Presunutie média \'%s\' zlyhalo.'; +$lang['mediaatticmoveerror'] = 'Staré verzie média \'%s\' nemôžu byť presunuté. Prosím, presuňte ich ručne.'; + +$lang['renamed'] = 'Stránka premenovaná z \'%s\' na \'%s\''; +$lang['moved'] = 'Stránka presunutá z \'%s\' do \'%s\''; +$lang['move_rename'] = 'Stránka presunutá a premenovaná z \'%s\' na \'%s\''; +$lang['delete'] = 'Zmazané pluginem move'; +$lang['linkchange'] = 'Odkazy upravené z dôvodu presunu'; + +$lang['intro'] = 'Operácia presunu zatiaľ nezačala!'; +$lang['preview'] = 'Náhled zmien, ktoré budou vykonané.'; +$lang['inexecution'] = 'Predchádzajúci presun nebol dokončený - použite tlačidlá dole k pokračovaniu alebo zrušeniu presunu.'; +$lang['btn_start'] = 'Štart'; +$lang['btn_continue'] = 'Pokračovať'; +$lang['btn_retry'] = 'Znova'; +$lang['btn_skip'] = 'Preskočiť položku'; +$lang['btn_abort'] = 'Prerušiť'; + +$lang['legend'] = 'Presunúť aktuálnu stránku nebo menný priestor'; +$lang['movepage'] = 'Presunúť stránku'; +$lang['movens'] = 'Presunúť aktuálny menný prostor'; +$lang['dst'] = 'Nové meno:'; +$lang['content_to_move'] = 'Obsah k presunu:'; +$lang['autoskip'] = 'Ignorovať chyby a preskočiť stránky a médiá, ktoré nemôžu byť presunuté'; +$lang['autorewrite'] = 'Prepísať odkazy hneď po ukončení presunu'; +$lang['move_pages'] = 'Stránky'; +$lang['move_media'] = 'Médiá'; +$lang['move_media_and_pages'] = 'Stránky a médiá'; +$lang['nodst'] = 'Nebolo zadané nové meno'; +$lang['noaction'] = 'Neboli definované žiadne presuny'; + +$lang['renamepage'] = 'Premenovať stránku'; +$lang['cantrename'] = 'Stránka nemôže byť momentálne premenovaná. Prosím skúste neskôr.'; +$lang['js']['rename'] = 'Premenovať'; +$lang['js']['cancel'] = 'Zrušit'; +$lang['js']['newname'] = 'Nový názov:'; +$lang['js']['inprogress'] = 'Presúvam stránky a upravujem odkazy...'; +$lang['js']['complete'] = 'Presun bol dokončený.'; + +$lang['root'] = '[Koreňový menný priestor]'; +$lang['noscript'] = 'Táto vlastosť vyžaduje JavaScript'; +$lang['moveinprogress'] = 'Práve prebieha iná operácia presunu, tento nástroj momentálne nemôžete použiť.'; +$lang['js']['renameitem'] = 'Premenovať túto položku'; +$lang['js']['add'] = 'Vytvoriť nový menný priestor'; +$lang['js']['duplicate'] = 'Ľutujeme, \'%s\' už v tomto mennom priestore existuje.'; diff --git a/lang/sk/move.txt b/lang/sk/move.txt new file mode 100644 index 0000000..42f9911 --- /dev/null +++ b/lang/sk/move.txt @@ -0,0 +1,11 @@ +====== Move ====== + +Tento plugin vám umožňuje presunúť alebo premenovať aktuálnu stránku alebo namespace, v rámci istých obmedzení: + + * Musíte mať právo editovať aktuálnu stránku / všetky stránky v aktuálnom mennom priestore. + * Stránky ktoré majú byť presunuté nesmú byť zamknuté pre úpravu. + * Na presun stránky potrebujete právo zápisu do cieľového menného priestoru. + * Nemôžte presunúť stránku do menného priestoru, v ktorom už stránka s rovnakým menom existuje. + +Všetky odkazy z a na presúvané stránky budú upravené podľa ich nového umiestnenia. + diff --git a/lang/sk/progress.txt b/lang/sk/progress.txt new file mode 100644 index 0000000..3a61d2a --- /dev/null +++ b/lang/sk/progress.txt @@ -0,0 +1,3 @@ +====== Prebieha presun... ====== + +Prosím, nezatvárajte túto stránku kým presun neskončí. diff --git a/lang/sk/settings.php b/lang/sk/settings.php new file mode 100644 index 0000000..c0e2324 --- /dev/null +++ b/lang/sk/settings.php @@ -0,0 +1,11 @@ + + */ + +$lang['allowrename'] = 'Povoliť premenovávanie stránok týmto používateľom a skupinám (oddelených čiarkou).'; +$lang['minor'] = 'Označiť úpravu odkazov ako drobnú zmenu? Drobné zmeny nebudú viditelné v RSS feedoch a v e-mailoch informujcich o zmenách.'; +$lang['autoskip'] = 'Zapnúť východzie automatické preskakovanie chýb pri presune menného priestoru.'; +$lang['autorewrite'] = 'Zapnúť východzie automatické prepisovanie odkazov po presune menného priestoru.'; +$lang['pagetools_integration'] = 'Pridať tlačidlo na premenovanie do nástrojov stránky'; diff --git a/lang/sk/tree.txt b/lang/sk/tree.txt new file mode 100644 index 0000000..b37e71a --- /dev/null +++ b/lang/sk/tree.txt @@ -0,0 +1,8 @@ +====== Manažér presunov ===== + +Tento interface vám umožňuje preskupiť menné priestory, stránky a médiá vo vašej wiki použitím metódy Drag'n'Drop. + +Na presun viacerých menných priestorov, stránok a médií do rovnakého cieľa môžete použiť zaškrtávacie políčka nasledujúcim spôsobom: + * zaškrtnite menné priestory, stránky alebo médiá, ktoré chcete presunúť; + * presuňte jeden zo zaškrtnutých objektov do žiadanej cieľovej lokality, presunuté budú všetky zaškrtnuté objekty. + From 83e018aaaca05e049378b502539d454ff9f8087c Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 23 Jan 2022 22:38:17 +0100 Subject: [PATCH 313/338] Replace Travis by GitHub Actions --- .github/workflows/phpTestLinux.yml | 52 ++++++++++++++++++++++++++++++ .travis.yml | 17 ---------- deleted.files | 1 + 3 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/phpTestLinux.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/phpTestLinux.yml b/.github/workflows/phpTestLinux.yml new file mode 100644 index 0000000..cb3361e --- /dev/null +++ b/.github/workflows/phpTestLinux.yml @@ -0,0 +1,52 @@ +name: PHP Tests on Linux + +on: [push, pull_request] + +jobs: + testLinux: + name: PHP ${{ matrix.php-versions }} DokuWiki ${{ matrix.dokuwiki-branch }} + runs-on: ubuntu-latest + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + strategy: + matrix: + php-versions: ['7.2', '7.3', '7.4', '8.0'] + dokuwiki-branch: [ 'master', 'stable'] + exclude: + - dokuwiki-branch: 'stable' + php-versions: '8.0' + fail-fast: false + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl, PDO, pdo_sqlite, bz2 + + - name: Setup problem matchers + run: | + echo ::add-matcher::${{ runner.tool_cache }}/php.json + echo ::add-matcher::${{ runner.tool_cache }}/phpunit.json + + - name: Download DokuWiki Test-setup + run: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh + + - name: Run DokuWiki Test-setup + env: + CI_SERVER: 1 + DOKUWIKI: ${{ matrix.dokuwiki-branch }} + run: sh travis.sh + + - name: Setup PHPUnit + run: | + php _test/fetchphpunit.php + cd _test + + - name: Run PHPUnit + run: | + cd _test + php phpunit.phar --verbose --stderr --group plugin_move diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fc1d5cb..0000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: php -php: - - "7.3" - - "7.2" - - "7.1" - - "7.0" - - "5.6" -env: - - DOKUWIKI=master - - DOKUWIKI=stable -matrix: - include: - - php: "5.6" - env: DOKUWIKI=old-stable -before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh && rm .gitignore -install: sh travis.sh -script: cd _test && ./phpunit.phar --stderr --group plugin_move diff --git a/deleted.files b/deleted.files index 9492d25..7d54c63 100644 --- a/deleted.files +++ b/deleted.files @@ -31,3 +31,4 @@ lang/es/pagemove.txt.txt lang/pl/lang.php.txt lang/pl/pagemove.txt.txt lang/zh/pagemove.txt +.travis.yml From e2441e18f9612faa5832defb2233e6efb7aaf80b Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 23 Jan 2022 22:47:59 +0100 Subject: [PATCH 314/338] Fix handling of empty line in the plan --- helper/plan.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/helper/plan.php b/helper/plan.php index a1e8289..6d632d3 100644 --- a/helper/plan.php +++ b/helper/plan.php @@ -623,6 +623,9 @@ protected function stepThroughNamespaces() { $lines = explode("\n", $lines); foreach($lines as $line) { + // There is an empty line at the end of the list. + if ($line === '') continue; + list($src, $dst) = explode("\t", trim($line)); $FileMover->moveNamespaceSubscription($src, $dst); } From 6e56e1e81df72e6d8fe5a7092ae3dfe7d52fecbe Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Sun, 23 Jan 2022 23:04:54 +0100 Subject: [PATCH 315/338] Version upped --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index cfb8c1c..809b80d 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2018-04-30 +date 2022-01-23 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url http://www.dokuwiki.org/plugin:move From 195d39c43448e958240e2f1ac05566d4b3577f4a Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 24 Jan 2022 13:11:03 +0100 Subject: [PATCH 316/338] Attach JS rename handler to mobile menu items. When the MobileMenu is used the required handler to show the rename dialog wasn't attached to the select resulting in an unkown action call. This attaches the handler and uses a jQuery specific trick to be the first handler to be evaluated (allowing to cancel the default handler used on the quickselect behaviour). fixes #150 fixes #169 --- MenuItem.php | 2 + script/rename.js | 182 +++++++++++++++++++++++++++++------------------ 2 files changed, 115 insertions(+), 69 deletions(-) diff --git a/MenuItem.php b/MenuItem.php index eec70f1..f1e0250 100644 --- a/MenuItem.php +++ b/MenuItem.php @@ -13,6 +13,8 @@ class MenuItem extends AbstractItem { /** @var string icon file */ protected $svg = __DIR__ . '/images/rename.svg'; + protected $type = "plugin_move_page"; + public function getLinkAttributes($classprefix = 'menuitem ') { $attr = parent::getLinkAttributes($classprefix); if (empty($attr['class'])) { diff --git a/script/rename.js b/script/rename.js index 4eb0071..1749d00 100644 --- a/script/rename.js +++ b/script/rename.js @@ -3,81 +3,125 @@ * * @author Andreas Gohr */ -if(JSINFO && JSINFO.move_renameokay) { - jQuery('.plugin_move_page') - .show() - .click(function(e) { - e.preventDefault(); +(function () { + if (!JSINFO || !JSINFO.move_renameokay) return; - var renameFN = function () { - var self = this; - var newid = $dialog.find('input[name=id]').val(); - if (!newid) return false; - // remove buttons and show throbber - $dialog.html( - ' '+ - LANG.plugins.move.inprogress - ); - $dialog.dialog('option', 'buttons', []); + // basic dialog template + const $dialog = jQuery( + '
      ' + + '
      ' + + '' + + '
      ' + + '
      ' + ); - // post the data - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - { - call: 'plugin_move_rename', - id: JSINFO.id, - newid: newid - }, - // redirect or display error - function (result) { - if(result.error){ - $dialog.html(result.error.msg); - } else { - window.location.href = result.redirect_url; - } - } - ); + /** + * Executes the renaming based on the form contents + * @return {boolean} + */ + const renameFN = function () { + const newid = $dialog.find('input[name=id]').val(); + if (!newid) return false; + + // remove buttons and show throbber + $dialog.html( + ' ' + + LANG.plugins.move.inprogress + ); + $dialog.dialog('option', 'buttons', []); - return false; - }; + // post the data + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_rename', + id: JSINFO.id, + newid: newid + }, + // redirect or display error + function (result) { + if (result.error) { + $dialog.html(result.error.msg); + } else { + window.location.href = result.redirect_url; + } + } + ); - // basic dialog template - var $dialog = jQuery( - '
      ' + - '
      ' + - '' + - '
      ' + - '
      ' - ); - $dialog.find('input[name=id]').val(JSINFO.id); - $dialog.find('form').submit(renameFN); + return false; + }; - // set up the dialog - $dialog.dialog({ - title: LANG.plugins.move.rename+' '+JSINFO.id, - width: 800, - height: 180, - dialogClass: 'plugin_move_dialog', - modal: true, - buttons: [ - { - text: LANG.plugins.move.cancel, - click: function () { - $dialog.dialog("close"); - } - }, - { - text: LANG.plugins.move.rename, - click: renameFN + /** + * Create the actual dialog modal and show it + */ + const showDialog = function () { + $dialog.dialog({ + title: LANG.plugins.move.rename + ' ' + JSINFO.id, + width: 800, + height: 200, + dialogClass: 'plugin_move_dialog', + modal: true, + buttons: [ + { + text: LANG.plugins.move.cancel, + click: function () { + $dialog.dialog("close"); } - ], - // remove HTML from DOM again - close: function () { - jQuery(this).remove(); + }, + { + text: LANG.plugins.move.rename, + click: renameFN } - }) + ], + // remove HTML from DOM again + close: function () { + jQuery(this).remove(); + } }); -} + $dialog.find('input[name=id]').val(JSINFO.id); + $dialog.find('form').submit(renameFN); + }; + + /** + * Bind an event handler as the first handler + * + * @param {jQuery} $owner + * @param {string} event + * @param {function} handler + * @link https://stackoverflow.com/a/4700103 + */ + const bindFirst = function ($owner, event, handler) { + $owner.unbind(event, handler); + $owner.bind(event, handler); + + const events = jQuery._data($owner[0])['events'][event]; + events.unshift(events.pop()); + + jQuery._data($owner[0])['events'][event] = events; + }; + + + // attach handler to menu item + jQuery('.plugin_move_page') + .show() + .click(function (e) { + e.preventDefault(); + showDialog(); + }); + + // attach handler to mobile menu entry + $mobileMenuOption = jQuery('form select[name=do] option[value=plugin_move_page]'); + if ($mobileMenuOption.length === 1) { + bindFirst($mobileMenuOption.form().find('select[name=do]'), 'change', function (e) { + if (jQuery(this).val() !== 'plugin_move_page') return; + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + showDialog(); + }); + } + +})(); From d42179ec8b8671e1b26f9965d20b9e2b42b1be45 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Tue, 25 Jan 2022 09:16:13 +0100 Subject: [PATCH 317/338] avoid clash with old pagetool CSS, unset mobile dropdown --- MenuItem.php | 2 +- script/rename.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/MenuItem.php b/MenuItem.php index f1e0250..9bad087 100644 --- a/MenuItem.php +++ b/MenuItem.php @@ -13,7 +13,7 @@ class MenuItem extends AbstractItem { /** @var string icon file */ protected $svg = __DIR__ . '/images/rename.svg'; - protected $type = "plugin_move_page"; + protected $type = "plugin_move"; public function getLinkAttributes($classprefix = 'menuitem ') { $attr = parent::getLinkAttributes($classprefix); diff --git a/script/rename.js b/script/rename.js index 1749d00..db32ff3 100644 --- a/script/rename.js +++ b/script/rename.js @@ -113,13 +113,15 @@ }); // attach handler to mobile menu entry - $mobileMenuOption = jQuery('form select[name=do] option[value=plugin_move_page]'); + const $mobileMenuOption = jQuery('form select[name=do] option[value=plugin_move]'); if ($mobileMenuOption.length === 1) { bindFirst($mobileMenuOption.form().find('select[name=do]'), 'change', function (e) { - if (jQuery(this).val() !== 'plugin_move_page') return; + const $select = jQuery(this); + if ($select.val() !== 'plugin_move') return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); + $select.val(''); showDialog(); }); } From cefbae5298a98047b19ce08398aa60a3681e27fa Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Wed, 26 Jan 2022 21:55:09 +0100 Subject: [PATCH 318/338] Fix rewriting of links to the root start page Previously, we had a bug that the "start"-name was not appended to the id in this case, and we thus didn't detect that the old relative link was still valid. Further, this could have caused issues if the root start page is renamed where certain links wouldn't have been adapted. --- _test/pagemove.test.php | 3 ++- helper/handler.php | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/_test/pagemove.test.php b/_test/pagemove.test.php index 991209e..97cffdb 100644 --- a/_test/pagemove.test.php +++ b/_test/pagemove.test.php @@ -431,12 +431,13 @@ function test_move_page_to_parent_ns() { [[.current_ns:|..:current_ns:]] [[.parallel_ns:|..parallel_ns:]] [[.parallel_ns:|..:parallel_ns:]] -[[:|..:..:]] +[[..:..:|..:..:]] [[..:..:parent_ns:|..:..:parent_ns:]] [[parent_ns:new_page|parent_ns:new_page]] [[parent_ns/new_page|parent_ns/new_page]] [[/start|/start]] EOT; + // Note: ..:..: is not a great link for a page in a namespace 'parent_ns', but it is correctly resolved. $this->assertEquals($expectedContent, $newContent); // page is moved to same NS as backlinking page (parent_ns) diff --git a/helper/handler.php b/helper/handler.php index 0bf17f4..fff2254 100644 --- a/helper/handler.php +++ b/helper/handler.php @@ -72,7 +72,7 @@ public function resolveMoves($old, $type) { // FIXME this simply assumes that the link pointed to :$conf['start'], but it could also point to another page // resolve_pageid does a lot more here, but we can't really assume this as the original pages might have been // deleted already - if(substr($old, -1) === ':') $old .= $conf['start']; + if(substr($old, -1) === ':' || $old === '') $old .= $conf['start']; $moves = $this->page_moves; } else { @@ -132,6 +132,11 @@ public function relativeLink($relold, $new, $type) { $old = $relold; if($type == 'page') { resolve_pageid($this->ns, $old, $exists); + // Work around bug in DokuWiki 2020-07-29 where resolve_pageid doesn't append the start page to a link to + // the root. + if ($old === '') { + $old = $conf['start']; + } } else { resolve_mediaid($this->ns, $old, $exists); } From f74b36ad689fd29ef8be80697842e96720762660 Mon Sep 17 00:00:00 2001 From: NawanP Date: Fri, 4 Mar 2022 13:55:35 +0100 Subject: [PATCH 319/338] translation update --- lang/id/lang.php | 62 ++++++++++++++++++++++++++++++++++++++++++++ lang/id/progress.txt | 3 +++ lang/id/settings.php | 12 +++++++++ lang/id/tree.txt | 7 +++++ 4 files changed, 84 insertions(+) create mode 100644 lang/id/lang.php create mode 100644 lang/id/progress.txt create mode 100644 lang/id/settings.php create mode 100644 lang/id/tree.txt diff --git a/lang/id/lang.php b/lang/id/lang.php new file mode 100644 index 0000000..55a9df3 --- /dev/null +++ b/lang/id/lang.php @@ -0,0 +1,62 @@ + + */ +$lang['menu'] = 'pindahkan halaman dan ruangnama'; +$lang['notexist'] = 'Halaman %s tidak ada'; +$lang['norights'] = 'Anda tidak memiliki izin untuk menyunting %s.'; +$lang['filelocked'] = 'Halaman %s telah dikunci. Coba lagi nanti.'; +$lang['notchanged'] = 'Tujuan baru tidak diberikan untuk halaman %s (lokasi halaman tidak berubah)'; +$lang['exists'] = 'Halaman %s tidak dapat dipindahkan ke %s, target telah ada.'; +$lang['notargetperms'] = 'Anda tidak memiliki izin untuk membuat halaman %s.'; +$lang['medianotexist'] = 'Berkas %s tidak ada'; +$lang['nomediarights'] = 'Anda tidak memiliki izin untuk menghapus %s.'; +$lang['medianotchanged'] = 'Tidak ada tujuan yang dipilih untuk halaman %s (lokasi halaman tidak berubah).'; +$lang['mediaexists'] = 'Media %s tidak dapat dipindahkan ke %s, target telah ada.'; +$lang['nomediatargetperms'] = 'Anda tidak memiliki izin untuk mengunggah berkas %s.'; +$lang['indexerror'] = 'Galat ketika memperbaharui indeks pencarian %s'; +$lang['metamoveerror'] = 'Berkas meta halaman %s tidak dapat dipindahkan'; +$lang['atticmoveerror'] = 'File attic halaman %s tidak dapat dipindahkan. Mohon pindahkan secara manual.'; +$lang['mediametamoveerror'] = 'Berkas meta dari berkas media tidak dapat dipindahkan'; +$lang['mediamoveerror'] = 'Gagal memindahkan berkas media %s'; +$lang['mediaatticmoveerror'] = 'File attic dari berkas media %s tidak dapat dipindahkan. Mohon pindahkan secara manual.'; +$lang['renamed'] = 'Nama halaman diubah dari %s menjadi %s'; +$lang['moved'] = 'Halaman dipindahkan dari %s ke %s'; +$lang['move_rename'] = 'Halaman dipindahkan dan diubah dari %s menjadi %s'; +$lang['delete'] = 'Dihapus oleh move plugin'; +$lang['linkchange'] = 'Pranala diubah karena operasi pemindahan'; +$lang['intro'] = 'Operasi pemindahan belum dimulai!'; +$lang['preview'] = 'Sedang mengeksekusi pratinjau perubahan.'; +$lang['inexecution'] = 'Pemindahan sebelumnya belum selesai - gunakan tombol dibawah untuk melanjutkan atau membatalkan pemindahan.'; +$lang['btn_start'] = 'Mulai'; +$lang['btn_continue'] = 'Lanjutkan'; +$lang['btn_retry'] = 'Coba butir'; +$lang['btn_skip'] = 'Lewati butir'; +$lang['btn_abort'] = 'Batalkan'; +$lang['legend'] = 'Pindahkan halaman atau ruangnama terkini'; +$lang['movepage'] = 'Pindahkan halaman'; +$lang['movens'] = 'Pindahkan ruangnama'; +$lang['dst'] = 'Nama baru:'; +$lang['content_to_move'] = 'Konten untuk dipindahkan:'; +$lang['autoskip'] = 'Abaikan galat dan lewati halaman atau berkas yang tidak dapat dipindahkan'; +$lang['autorewrite'] = 'Ubah pranala setelah pemindahan selesai'; +$lang['move_pages'] = 'Halaman'; +$lang['move_media'] = 'Berkas media'; +$lang['move_media_and_pages'] = 'Halaman dan berkas'; +$lang['nodst'] = 'Tidak ada nama baru diberikan'; +$lang['renamepage'] = 'Ubah nama halaman'; +$lang['cantrename'] = 'Nama halaman tidak dapat diubah saat ini. Coba lagi nanti.'; +$lang['js']['rename'] = 'Ubah nama'; +$lang['js']['cancel'] = 'Batal'; +$lang['js']['newname'] = 'Nama baru:'; +$lang['js']['inprogress'] = 'mengubah nama halaman dan menyesuaikan pranala...'; +$lang['js']['complete'] = 'Pemindahan selesai.'; +$lang['js']['renameitem'] = 'Ubah nama item ini'; +$lang['js']['add'] = 'Buat ruangnama baru'; +$lang['js']['duplicate'] = 'Maaf, %s telah ada di ruangnama ini.'; +$lang['root'] = '[Ruang nama root]'; +$lang['noscript'] = 'Fitur ini membutuhkan JavaScript'; +$lang['moveinprogress'] = 'Ada operasi pemindahan lain yang belum selesai, Anda tidak dapat menggunakan alat ini sekarang.'; diff --git a/lang/id/progress.txt b/lang/id/progress.txt new file mode 100644 index 0000000..fdf7613 --- /dev/null +++ b/lang/id/progress.txt @@ -0,0 +1,3 @@ +====== Pemindahan dalam proses... ====== + +Mohon tetap di halaman ini saat pemindahan sedang diproses. \ No newline at end of file diff --git a/lang/id/settings.php b/lang/id/settings.php new file mode 100644 index 0000000..d277e4b --- /dev/null +++ b/lang/id/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Izinkan pengguna dan grup ini untuk mengubah nama halaman (pisahkan dengan koma).'; +$lang['minor'] = 'Tandai penyesuaian pranala sebagai perubahan kecil? Perubahan kecil tidak akan terlihat di feed RSS dan milis.'; +$lang['autoskip'] = 'Aktifkan lewati otomatis galat saat memindahkan ruangnama secara default.'; +$lang['autorewrite'] = 'Aktifkan pengubahan pranala secara default saat memindahkan ruangnama.'; +$lang['pagetools_integration'] = 'Tambahkan tombol ubah nama ke pagetools'; diff --git a/lang/id/tree.txt b/lang/id/tree.txt new file mode 100644 index 0000000..3a9cc4c --- /dev/null +++ b/lang/id/tree.txt @@ -0,0 +1,7 @@ +====== Move Manager ===== + +Antarmuka ini mengizinkan Anda untuk mengurutkan ulang ruangnama, halaman, dan berkas media dengan geser dan lepas. + +Untuk memindahkan ruangnama, halaman, atau berkas sekaligus ke tujuan yang sama, Anda dapat menggunakan kotak centang sebagaimana dibawah ini: + * klik kotak centang pada ruangnama, halaman, atau berkas yang ingin Anda pindahkan; + * pindahkan satu dari butir yang telah dipilih ke tujuan yang diinginkan, semua butir yang dipilih secara otomatis akan dipindahkan ke tujuan tersebut. \ No newline at end of file From 785507433c32618b7bdd49b9eb3a66f9294f7d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Mon, 24 Apr 2023 22:15:58 +0300 Subject: [PATCH 320/338] Allow move to work if acl is disabled --- action/rename.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/action/rename.php b/action/rename.php index 6bd495d..fdad35c 100644 --- a/action/rename.php +++ b/action/rename.php @@ -119,12 +119,14 @@ public function handle_ajax(Doku_Event $event) { * @return bool */ public function renameOkay($id) { + global $conf; global $ACT; global $USERINFO; if(!($ACT == 'show' || empty($ACT))) return false; if(!page_exists($id)) return false; if(auth_quickaclcheck($id) < AUTH_EDIT) return false; if(checklock($id) !== false || @file_exists(wikiLockFN($id))) return false; + if(!$conf['useacl']) return true; if(!isset($_SERVER['REMOTE_USER'])) return false; if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], (array) $USERINFO['grps'])) return false; From 6a6cdb7bbfa9e969db2de6c893b1cde564871f6b Mon Sep 17 00:00:00 2001 From: aljailane Date: Tue, 9 May 2023 09:40:13 +0200 Subject: [PATCH 321/338] translation update --- lang/ar/lang.php | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 lang/ar/lang.php diff --git a/lang/ar/lang.php b/lang/ar/lang.php new file mode 100644 index 0000000..c7567a6 --- /dev/null +++ b/lang/ar/lang.php @@ -0,0 +1,10 @@ + + */ +$lang['menu'] = 'نقل الصفحات ومساحات الأسماء'; +$lang['inprogress'] = '(التحرك معلق)'; +$lang['treelink'] = 'بدلاً من هذا النموذج البسيط ، يمكنك إدارة إعادة الهيكلة المعقدة لموقع wiki الخاص بك باستخدام مدير النقل المستند إلى الشجرة . '; From 52a9cbe1294eb8ec6615291b97c225c2af44f5a2 Mon Sep 17 00:00:00 2001 From: Daniel Dias Rodrigues Date: Mon, 29 May 2023 20:20:29 +0200 Subject: [PATCH 322/338] translation update --- lang/pt-br/lang.php | 56 ++++++++++++++++++++++++++++++++++++++++- lang/pt-br/move.txt | 9 +++++++ lang/pt-br/progress.txt | 2 ++ lang/pt-br/settings.php | 12 +++++++++ lang/pt-br/tree.txt | 6 +++++ 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 lang/pt-br/move.txt create mode 100644 lang/pt-br/progress.txt create mode 100644 lang/pt-br/settings.php create mode 100644 lang/pt-br/tree.txt diff --git a/lang/pt-br/lang.php b/lang/pt-br/lang.php index 5bb84e9..f68c2dd 100644 --- a/lang/pt-br/lang.php +++ b/lang/pt-br/lang.php @@ -2,11 +2,65 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * + * + * @author Daniel Dias Rodrigues * @author Fábio Nogueira */ +$lang['menu'] = 'Mover páginas e domínios'; +$lang['inprogress'] = '(movimentação pendente)'; +$lang['treelink'] = 'Como alternativa a este formulário simples, você pode gerenciar reestruturações complexas da sua wiki usando o gerenciador de movimentação baseado em árvore.'; $lang['notexist'] = 'A página %s não existe'; $lang['norights'] = 'Você tem permissões insuficientes para editar %s'; +$lang['filelocked'] = 'A página %s está bloqueada. Tente mais tarde.'; +$lang['notchanged'] = 'Não foi fornecido um novo destino para a página %s (localização inalterada).'; +$lang['exists'] = 'A página %s não pode ser movida para %s, o destino já existe.'; +$lang['notargetperms'] = 'Você não tem permissão para criar a página %s.'; $lang['medianotexist'] = 'O arquivo de mídia %s não existe'; +$lang['nomediarights'] = 'Você não tem permissões suficientes para excluir %s.'; +$lang['medianotchanged'] = 'Não foi fornecido um novo destino para a página %s (localização inalterada).'; +$lang['mediaexists'] = 'A mídia %s não pode ser movida para %s, o destino já existe.'; +$lang['nomediatargetperms'] = 'Você não tem permissão para criar o arquivo de mídia %s.'; +$lang['indexerror'] = 'Erro ao atualizar o índice de pesquisa %s'; +$lang['metamoveerror'] = 'Os meta-arquivos da página %s não puderam ser movidos'; +$lang['atticmoveerror'] = 'Os arquivos do diretório superior ao da página %s não puderam ser movidos. Por favor mova-os manualmente.'; +$lang['mediametamoveerror'] = 'Os meta-arquivos do arquivo de mídia %s não puderam ser movidos'; +$lang['mediamoveerror'] = 'A movimentação do arquivo de mídia %s falhou'; +$lang['mediaatticmoveerror'] = 'Os arquivos do diretório superior ao do arquivo de mídia %s não puderam ser movidos. Por favor mova-os manualmente.'; +$lang['renamed'] = 'Nome da página alterado de %s para %s'; +$lang['moved'] = 'Página movida de %s para %s'; +$lang['move_rename'] = 'Página movida e renomeada de %s para %s'; +$lang['delete'] = 'Excluído pelo plugin de movimentação'; +$lang['linkchange'] = 'Links adaptados devido a uma operação de movimentação'; +$lang['intro'] = 'A operação de movimentação ainda não foi iniciada!'; +$lang['preview'] = 'Visualize as alterações a serem executadas.'; +$lang['inexecution'] = 'Um movimento anterior não foi concluído - use os botões abaixo para continuar ou abortar a execução.'; $lang['btn_start'] = 'Iniciar'; $lang['btn_continue'] = 'Continuar'; +$lang['btn_retry'] = 'Repetir item'; +$lang['btn_skip'] = 'Ignorar item'; +$lang['btn_abort'] = 'Abortar'; +$lang['legend'] = 'Mover página atual ou domínio'; +$lang['movepage'] = 'Mover página'; +$lang['movens'] = 'Mover domínio'; +$lang['dst'] = 'Novo nome:'; +$lang['content_to_move'] = 'Conteúdo a mover:'; +$lang['autoskip'] = 'Ignore erros e pule páginas ou arquivos que não podem ser movidos'; +$lang['autorewrite'] = 'Reescrever links logo após a conclusão da mudança'; +$lang['move_pages'] = 'Páginas'; +$lang['move_media'] = 'Arquivos de mídia'; +$lang['move_media_and_pages'] = 'Páginas e arquivos de mídia'; +$lang['nodst'] = 'Não foi fornecido um nome novo'; +$lang['noaction'] = 'Não houve movimentos definidos'; +$lang['renamepage'] = 'Renomear Página'; +$lang['cantrename'] = 'A página não pode ser renomeada agora. Por favor tente mais tarde.'; +$lang['js']['rename'] = 'Renomear'; +$lang['js']['cancel'] = 'Cancelar'; +$lang['js']['newname'] = 'Novo nome:'; +$lang['js']['inprogress'] = 'renomeando página e ajustando links...'; +$lang['js']['complete'] = 'Operação de movimentação concluída.'; +$lang['js']['renameitem'] = 'Renomear este item'; +$lang['js']['add'] = 'Criar um novo domínio'; +$lang['js']['duplicate'] = 'Desculpe, "%s" já existe neste domínio.'; +$lang['root'] = '[Domínio raiz]'; +$lang['noscript'] = 'Este recurso requer JavaScript'; +$lang['moveinprogress'] = 'Há outra operação de movimentação em andamento no momento, você não pode usar esta ferramenta agora.'; diff --git a/lang/pt-br/move.txt b/lang/pt-br/move.txt new file mode 100644 index 0000000..19a6c43 --- /dev/null +++ b/lang/pt-br/move.txt @@ -0,0 +1,9 @@ +====== Movimentação ====== +Este plugin permite mover e/ou renomear a página atual ou mover e/ou renomear o domínio atual dentro das seguintes restrições: + + * Você deve ter permissão de edição para a página atual ou para todas as páginas no domínio atual. + * As páginas que a serem movidas não devem estar bloqueadas para edição. + * Para mover uma página, você também precisa criar permissão no domínio de destino. + * Você não pode mover uma página para um domínio onde já existe uma página com o mesmo nome. + +Todos os links de e para as páginas movidas serão atualizados para refletir o novo local e/ou nome. \ No newline at end of file diff --git a/lang/pt-br/progress.txt b/lang/pt-br/progress.txt new file mode 100644 index 0000000..a65c3ad --- /dev/null +++ b/lang/pt-br/progress.txt @@ -0,0 +1,2 @@ +====== Movimentação em andamento... ====== +Por favor, mantenha esta página aberta enquanto a mudança está sendo realizada. \ No newline at end of file diff --git a/lang/pt-br/settings.php b/lang/pt-br/settings.php new file mode 100644 index 0000000..2926b9a --- /dev/null +++ b/lang/pt-br/settings.php @@ -0,0 +1,12 @@ + + */ +$lang['allowrename'] = 'Permitir renomeação de páginas para esses grupos e usuários (separados por vírgula).'; +$lang['minor'] = 'Marcar ajustes de link como menores? Alterações menores não serão listadas em feeds RSS e listas de e-mails.'; +$lang['autoskip'] = 'Ativa o salto automático de erros em movimentações de domínio por padrão.'; +$lang['autorewrite'] = 'Habilita a regravação automática do link após a movimentação do domínio por padrão.'; +$lang['pagetools_integration'] = 'Adicionar botão de renomeação às ferramentas de página'; diff --git a/lang/pt-br/tree.txt b/lang/pt-br/tree.txt new file mode 100644 index 0000000..031ed58 --- /dev/null +++ b/lang/pt-br/tree.txt @@ -0,0 +1,6 @@ +====== Gerenciador de Movimentação ====== +Esta interface permite que você reorganize os domínios, páginas e arquivos de mídia da sua wiki via Arraste e Solte. + +Para mover vários domínios, páginas ou arquivos de mídia para o mesmo destino, você pode usar as caixas de seleção da seguinte forma: + * verifique os domínios, páginas ou arquivos de mídia que deseja mover; + * mova um dos itens marcados para o destino desejado, todos os itens selecionados serão movidos para este destino. \ No newline at end of file From 32c4849b6a60946189dc085a3a53a5bd912435c3 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 1 Jun 2023 16:40:10 +0200 Subject: [PATCH 323/338] replace invalid call to jQuery.form() fixes #244 using optimization suggested by @michitux in https://github.com/michitux/dokuwiki-plugin-move/pull/245#discussion_r1213577313 --- script/rename.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/rename.js b/script/rename.js index db32ff3..03a8e5f 100644 --- a/script/rename.js +++ b/script/rename.js @@ -115,7 +115,7 @@ // attach handler to mobile menu entry const $mobileMenuOption = jQuery('form select[name=do] option[value=plugin_move]'); if ($mobileMenuOption.length === 1) { - bindFirst($mobileMenuOption.form().find('select[name=do]'), 'change', function (e) { + bindFirst($mobileMenuOption.closest('select[name=do]'), 'change', function (e) { const $select = jQuery(this); if ($select.val() !== 'plugin_move') return; e.preventDefault(); From 673900a51c21c4e0b96aacf94b3d02d2919d4aaa Mon Sep 17 00:00:00 2001 From: Anna Dabrowska Date: Wed, 7 Jun 2023 13:42:20 +0200 Subject: [PATCH 324/338] Integrate into media manager Implements #209 --- action/rename.php | 43 ++++++++++ lang/de-informal/lang.php | 6 ++ lang/de/lang.php | 6 ++ lang/en/lang.php | 6 ++ lang/pl/lang.php | 6 ++ script.js | 4 +- script/MoveMediaManager.js | 165 +++++++++++++++++++++++++++++++++++++ 7 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 script/MoveMediaManager.js diff --git a/action/rename.php b/action/rename.php index fdad35c..5602feb 100644 --- a/action/rename.php +++ b/action/rename.php @@ -26,6 +26,7 @@ public function register(Doku_Event_Handler $controller) { $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addsvgbutton', array()); $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); + $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxMediaManager'); } /** @@ -112,6 +113,48 @@ public function handle_ajax(Doku_Event $event) { } } + /** + * Handle media renames in media manager + * + * @param Doku_Event $event + * @return void + */ + public function handleAjaxMediaManager(Doku_Event $event) + { + if ($event->data !== 'plugin_move_rename_mediamanager') return; + + $event->preventDefault(); + $event->stopPropagation(); + + global $INPUT; + + $src = cleanID($INPUT->str('src')); + $dst = cleanID($INPUT->str('dst')); + + /** @var helper_plugin_move_op $MoveOperator */ + $MoveOperator = plugin_load('helper', 'move_op'); + + if ($src && $dst) { + $response = []; + header('Content-Type: application/json'); + + if (file_exists(mediaFN($dst))) { + $response['error'][] = $this->getLang('errorOverwrite'); + } + if (auth_quickaclcheck($dst) < AUTH_CREATE) { + $response['error'][] = $this->getLang('errorPermissions'); + } + + if (empty($response['error'])) { + $response['success'] = $MoveOperator->moveMedia($src, $dst); + $ns = getNS($dst); + $response['redirect_url'] = wl($dst, ['do' => 'media', 'ns' => $ns], true, '&'); + } + + echo json_encode($response); + } + } + /** * Determines if it would be okay to show a rename page button for the given page and current user * diff --git a/lang/de-informal/lang.php b/lang/de-informal/lang.php index b525d8f..18700f7 100644 --- a/lang/de-informal/lang.php +++ b/lang/de-informal/lang.php @@ -63,3 +63,9 @@ $lang['root'] = '[Oberster Namensraum]'; $lang['noscript'] = 'Dieses Feature benötigt JavaScript.'; $lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft momentan, du kannst dieses Tool gerade nicht benutzen.'; + +// Media Manager +$lang['errorOverwrite'] = 'Die Datei existiert bereits!'; +$lang['errorPermissions'] = 'Du hast unzureichende Rechte, um die Datei in den Zielnamensraum zu verschieben!'; +$lang['js']['moveButton'] = 'Datei verschieben / umbenennen'; +$lang['js']['dialogIntro'] = 'Neuer Dateiname. Du kannst den Namensraum ändern, aber nicht die Dateierweiterung.'; diff --git a/lang/de/lang.php b/lang/de/lang.php index ee997f1..04140d1 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -65,3 +65,9 @@ $lang['root'] = '[Oberster Namensraum]'; $lang['noscript'] = 'Dieses Feature benötigt JavaScript.'; $lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft momentan, Sie können dieses Tool gerade nicht benutzen.'; + +// Media Manager +$lang['errorOverwrite'] = 'Die Datei existiert bereits!'; +$lang['errorPermissions'] = 'Sie haben unzureichende Rechte, um die Datei in den Zielnamensraum zu verschieben!'; +$lang['js']['moveButton'] = 'Datei verschieben / umbenennen'; +$lang['js']['dialogIntro'] = 'Neuer Dateiname. Sie können den Namensraum ändern, aber nicht die Dateierweiterung.'; diff --git a/lang/en/lang.php b/lang/en/lang.php index 4146dca..65c3b7c 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -80,3 +80,9 @@ $lang['js']['renameitem'] = 'Rename this item'; $lang['js']['add'] = 'Create a new namespace'; $lang['js']['duplicate'] = 'Sorry, "%s" already exists in this namespace.'; + +// Media Manager +$lang['errorOverwrite'] = 'File already exists!'; +$lang['errorPermissions'] = 'You have no permissions to create files in the target namespace!'; +$lang['js']['moveButton'] = 'Move file'; +$lang['js']['dialogIntro'] = 'Enter new file destination. You may change the namespace but not the file extension.'; diff --git a/lang/pl/lang.php b/lang/pl/lang.php index 6c0e162..f6d627f 100644 --- a/lang/pl/lang.php +++ b/lang/pl/lang.php @@ -30,3 +30,9 @@ $lang['newname'] = 'Nowa nazwa dokumentu:'; $lang['targetns'] = 'Nazwa docelowego katalogu:'; $lang['submit'] = 'Zmień'; + +// Media Manager +$lang['errorOverwrite'] = 'Plik już istnieje!'; +$lang['errorPermissions'] = 'Niewystarczające uprawnienia by wykonać operację!'; +$lang['js']['moveButton'] = 'Przenieś/Zmień nazwę'; +$lang['js']['dialogIntro'] = 'Nowa nazwa pliku. Możesz zmienić katalog, ale nie rozszerzenie pliku.'; diff --git a/script.js b/script.js index 98913b5..9fba837 100644 --- a/script.js +++ b/script.js @@ -5,9 +5,11 @@ */ /* DOKUWIKI:include_once script/json2.js */ +/* DOKUWIKI:include script/MoveMediaManager.js */ + jQuery(function() { /* DOKUWIKI:include script/form.js */ /* DOKUWIKI:include script/progress.js */ /* DOKUWIKI:include script/tree.js */ /* DOKUWIKI:include script/rename.js */ -}); \ No newline at end of file +}); diff --git a/script/MoveMediaManager.js b/script/MoveMediaManager.js new file mode 100644 index 0000000..32c1553 --- /dev/null +++ b/script/MoveMediaManager.js @@ -0,0 +1,165 @@ +/** + * Integrates move capability into the media manager + * Based on the implementation in diagrams plugin + */ +class MoveMediaManager { + + constructor() { + const filePanel = document.querySelector('#mediamanager__page .panel.file'); + if (filePanel) { + const observer = new MutationObserver(this.#addEditButton.bind(this)); + observer.observe(filePanel, {childList: true, subtree: true}); + } + } + + /** + * Observer callback to add the edit button in the detail panel of the media manager + * + * @param mutationsList + * @param observer + */ + async #addEditButton(mutationsList, observer) { + for (let mutation of mutationsList) { + // div.file has been filled with new content? + if (mutation.type !== 'childList') continue; + + // check that the file panel contains a link to a file + if (mutation.target.classList.contains('file') === false) continue; + const link = mutation.target.querySelector('a.select.mediafile'); + if (!link) continue; + + const uri = link.getAttribute('href'); + + const [ , paramString ] = uri.split( '?' ); + const searchParams = new URLSearchParams(paramString); + const src = searchParams.get('media'); + + const actionList = mutation.target.querySelector('ul.actions'); + if (actionList.querySelector('button.move-btn')) continue; // already added + + + const moveButton = document.createElement('button'); + moveButton.classList.add('move-btn'); + moveButton.innerText = LANG.plugins.move.moveButton; + + moveButton.addEventListener('click', this.#showDialog.bind(this, src)); + actionList.appendChild(moveButton); + } + } + + /** + * Show the move dialog + * + * Uses JQuery UI + * + * @param {string} src + * @param {Event} event + * @returns {Promise} + */ + async #showDialog(src, event) { + event.preventDefault(); + event.stopPropagation(); + + const $form = jQuery(this.#buildForm(src)); + $form.dialog({ + title: LANG.plugins.move.moveButton, + width: 600, + appendTo: '.dokuwiki', + modal: true, + close: function () { + // do not reuse the dialog + // https://stackoverflow.com/a/2864783 + jQuery(this).dialog('destroy').remove(); + } + }); + } + + /** + * Create the form for the old and new file names + * + * @param {string} src + * @returns {HTMLDivElement} + */ + #buildForm(src) { + const wrapper = document.createElement('div'); + const form = document.createElement('form'); + wrapper.appendChild(form); + + const intro = document.createElement('p'); + intro.innerText = LANG.plugins.move.dialogIntro; + form.appendChild(intro); + + const original = document.createElement('input'); + original.type = 'hidden'; + original.name = 'move-old-filename'; + original.value = src; + form.appendChild(original); + + // strip file extension and put it in a readonly field so it may not be modified + const fileExt = document.createElement('input'); + fileExt.type = 'text'; + fileExt.readOnly = true; + fileExt.size = 5; + fileExt.name = 'move-file-ext'; + fileExt.value = src.split('.').pop(); + + const destination = document.createElement('input'); + destination.type = 'text'; + destination.className = 'edit'; + destination.name = 'move-new-filename'; + destination.value = src.substring(0, src.length - (fileExt.value.length + 1)); + destination.size = 50; + form.appendChild(destination); + form.appendChild(fileExt); + + const button = document.createElement('button'); + button.innerText = LANG.plugins.move.moveButton; + form.appendChild(button); + + form.addEventListener('submit', this.#requestMove.bind(this, form)); + + return wrapper; + } + + /** + * Send move request to backend + * + * @param {HTMLFormElement} form + * @param {Event} event + * @returns {Promise} + */ + async #requestMove(form, event) { + + event.preventDefault(); + event.stopPropagation(); + + const src = form.querySelector('input[name="move-old-filename"]').value; + const dst = form.querySelector('input[name="move-new-filename"]').value; + const ext = form.querySelector('input[name="move-file-ext"]').value; + + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'plugin_move_rename_mediamanager', + src: src, + dst: dst + '.' + ext + }, + // redirect or display error + function (result) { + if (result.error) { + const errorText = document.createElement('strong'); + errorText.innerText = result.error.join(); + errorText.style = 'color: red;'; + form.prepend(errorText); + } else { + window.location.href = result.redirect_url; + } + } + ); + } +} + +// initialize +document.addEventListener('DOMContentLoaded', () => { + new MoveMediaManager(); +}); From 779fa0ed9deace35b2315085766e23e367461717 Mon Sep 17 00:00:00 2001 From: Anna Dabrowska Date: Thu, 8 Jun 2023 15:29:57 +0200 Subject: [PATCH 325/338] Improve error handling and messages --- action/rename.php | 27 ++++++++++++++++----------- lang/de-informal/lang.php | 2 -- lang/de/lang.php | 2 -- lang/en/lang.php | 2 -- script/MoveMediaManager.js | 31 +++++++++++++++++++++---------- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/action/rename.php b/action/rename.php index 5602feb..9126730 100644 --- a/action/rename.php +++ b/action/rename.php @@ -123,32 +123,37 @@ public function handleAjaxMediaManager(Doku_Event $event) { if ($event->data !== 'plugin_move_rename_mediamanager') return; + if (!checkSecurityToken()) return; + $event->preventDefault(); $event->stopPropagation(); global $INPUT; + global $MSG; $src = cleanID($INPUT->str('src')); $dst = cleanID($INPUT->str('dst')); - /** @var helper_plugin_move_op $MoveOperator */ - $MoveOperator = plugin_load('helper', 'move_op'); + /** @var helper_plugin_move_op $moveOperator */ + $moveOperator = plugin_load('helper', 'move_op'); if ($src && $dst) { - $response = []; header('Content-Type: application/json'); - if (file_exists(mediaFN($dst))) { - $response['error'][] = $this->getLang('errorOverwrite'); - } - if (auth_quickaclcheck($dst) < AUTH_CREATE) { - $response['error'][] = $this->getLang('errorPermissions'); - } + $response = []; - if (empty($response['error'])) { - $response['success'] = $MoveOperator->moveMedia($src, $dst); + $response['success'] = $moveOperator->moveMedia($src, $dst); + + if ($response['success']) { $ns = getNS($dst); $response['redirect_url'] = wl($dst, ['do' => 'media', 'ns' => $ns], true, '&'); + } else { + $response['error'] = sprintf($this->getLang('mediamoveerror'), $src); + if (isset($MSG)) { + foreach ($MSG as $msg) { + $response['error'] .= ' ' . $msg['msg']; + } + } } echo json_encode($response); diff --git a/lang/de-informal/lang.php b/lang/de-informal/lang.php index 18700f7..9ba0cf2 100644 --- a/lang/de-informal/lang.php +++ b/lang/de-informal/lang.php @@ -65,7 +65,5 @@ $lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft momentan, du kannst dieses Tool gerade nicht benutzen.'; // Media Manager -$lang['errorOverwrite'] = 'Die Datei existiert bereits!'; -$lang['errorPermissions'] = 'Du hast unzureichende Rechte, um die Datei in den Zielnamensraum zu verschieben!'; $lang['js']['moveButton'] = 'Datei verschieben / umbenennen'; $lang['js']['dialogIntro'] = 'Neuer Dateiname. Du kannst den Namensraum ändern, aber nicht die Dateierweiterung.'; diff --git a/lang/de/lang.php b/lang/de/lang.php index 04140d1..60bb75d 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -67,7 +67,5 @@ $lang['moveinprogress'] = 'Eine andere Verschiebeoperation läuft momentan, Sie können dieses Tool gerade nicht benutzen.'; // Media Manager -$lang['errorOverwrite'] = 'Die Datei existiert bereits!'; -$lang['errorPermissions'] = 'Sie haben unzureichende Rechte, um die Datei in den Zielnamensraum zu verschieben!'; $lang['js']['moveButton'] = 'Datei verschieben / umbenennen'; $lang['js']['dialogIntro'] = 'Neuer Dateiname. Sie können den Namensraum ändern, aber nicht die Dateierweiterung.'; diff --git a/lang/en/lang.php b/lang/en/lang.php index 65c3b7c..b5df07d 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -82,7 +82,5 @@ $lang['js']['duplicate'] = 'Sorry, "%s" already exists in this namespace.'; // Media Manager -$lang['errorOverwrite'] = 'File already exists!'; -$lang['errorPermissions'] = 'You have no permissions to create files in the target namespace!'; $lang['js']['moveButton'] = 'Move file'; $lang['js']['dialogIntro'] = 'Enter new file destination. You may change the namespace but not the file extension.'; diff --git a/script/MoveMediaManager.js b/script/MoveMediaManager.js index 32c1553..f825572 100644 --- a/script/MoveMediaManager.js +++ b/script/MoveMediaManager.js @@ -28,15 +28,18 @@ class MoveMediaManager { const link = mutation.target.querySelector('a.select.mediafile'); if (!link) continue; + const actionList = mutation.target.querySelector('ul.actions'); + if (actionList.querySelector('button.move-btn')) continue; // already added + + const deleteButton = actionList.querySelector('form#mediamanager__btn_delete'); + if (deleteButton === null) continue; // no delete permissions + const uri = link.getAttribute('href'); const [ , paramString ] = uri.split( '?' ); const searchParams = new URLSearchParams(paramString); const src = searchParams.get('media'); - const actionList = mutation.target.querySelector('ul.actions'); - if (actionList.querySelector('button.move-btn')) continue; // already added - const moveButton = document.createElement('button'); moveButton.classList.add('move-btn'); @@ -89,12 +92,19 @@ class MoveMediaManager { intro.innerText = LANG.plugins.move.dialogIntro; form.appendChild(intro); + const errorContainer = document.createElement('div'); + errorContainer.className = 'move-error'; + form.appendChild(errorContainer); + const original = document.createElement('input'); original.type = 'hidden'; original.name = 'move-old-filename'; original.value = src; form.appendChild(original); + const sectok = document.querySelector('form#mediamanager__btn_delete input[name=sectok]').cloneNode(); + form.appendChild(sectok); + // strip file extension and put it in a readonly field so it may not be modified const fileExt = document.createElement('input'); fileExt.type = 'text'; @@ -136,23 +146,24 @@ class MoveMediaManager { const src = form.querySelector('input[name="move-old-filename"]').value; const dst = form.querySelector('input[name="move-new-filename"]').value; const ext = form.querySelector('input[name="move-file-ext"]').value; + const sectok = form.querySelector('input[name="sectok"]').value; + const err = form.querySelector('div.move-error'); jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_move_rename_mediamanager', src: src, - dst: dst + '.' + ext + dst: dst + '.' + ext, + sectok: sectok }, // redirect or display error function (result) { - if (result.error) { - const errorText = document.createElement('strong'); - errorText.innerText = result.error.join(); - errorText.style = 'color: red;'; - form.prepend(errorText); - } else { + if (result.success) { window.location.href = result.redirect_url; + } else { + err.classList.add('error'); + err.innerText = result.error; } } ); From 302c75cb0ff657c8761ac55aef69a31fef2e7d07 Mon Sep 17 00:00:00 2001 From: Anna Dabrowska Date: Thu, 8 Jun 2023 15:32:32 +0200 Subject: [PATCH 326/338] Additional check on media file extensions Media move is prevented if source and destination media files do not have identical extensions (strict comparison). UTF-8 names should be handled correctly if UTF-8 locale is set. --- helper/op.php | 8 +++++++- lang/de-informal/lang.php | 1 + lang/de/lang.php | 1 + lang/en/lang.php | 1 + lang/pl/lang.php | 4 ++-- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/helper/op.php b/helper/op.php index e8a5acd..48c4175 100644 --- a/helper/op.php +++ b/helper/op.php @@ -106,6 +106,12 @@ public function checkMedia($src, $dst) { return false; } + // check if the file extension is unchanged + if (pathinfo(mediaFN($src), PATHINFO_EXTENSION) !== pathinfo(mediaFN($dst), PATHINFO_EXTENSION)) { + msg($this->getLang('extensionchange'), -1); + return false; + } + return true; } @@ -314,4 +320,4 @@ public function moveMedia($src, $dst) { public function getAffectedPages() { return $this->affectedPages; } -} \ No newline at end of file +} diff --git a/lang/de-informal/lang.php b/lang/de-informal/lang.php index 9ba0cf2..d3d985b 100644 --- a/lang/de-informal/lang.php +++ b/lang/de-informal/lang.php @@ -19,6 +19,7 @@ $lang['medianotchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; $lang['mediaexists'] = 'Mediendatei %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; $lang['nomediatargetperms'] = 'Du hast keine Berechtigung, die Mediendatei %s anzulegen.'; +$lang['extensionchange'] = 'Die Dateierweiterungen der alten und der neuen Datei sind unterschiedlich.'; $lang['indexerror'] = 'Fehler während der Aktualisierung des Suchindexes %s'; $lang['metamoveerror'] = 'Die Metadateien der Seite %s konnten nicht verschoben werden'; $lang['atticmoveerror'] = 'Die Attic-Dateien der Seite %s konnten nicht verschoben werden. Bitte verschiebe Sie sie manuell.'; diff --git a/lang/de/lang.php b/lang/de/lang.php index 60bb75d..4293406 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -21,6 +21,7 @@ $lang['medianotchanged'] = 'Kein Ziel für Seite %s angegeben (Ort bleibt unverändert).'; $lang['mediaexists'] = 'Mediendatei %s kann nicht nach %s verschoben werden, da das Ziel bereits existiert.'; $lang['nomediatargetperms'] = 'Sie haben nicht die Berechtigung, die Mediendatei %s anzulegen.'; +$lang['extensionchange'] = 'Die Dateierweiterungen der alten und der neuen Datei sind unterschiedlich.'; $lang['indexerror'] = 'Fehler während der Aktualisierung des Suchindexes %s'; $lang['metamoveerror'] = 'Die Metadateien der Seite %s konnten nicht verschoben werden'; $lang['atticmoveerror'] = 'Die Attic-Dateien der Seite %s konnten nicht verschoben werden. Bitte verschieben Sie sie manuell.'; diff --git a/lang/en/lang.php b/lang/en/lang.php index b5df07d..a614280 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -24,6 +24,7 @@ $lang['medianotchanged'] = 'No new destination given for page %s (location unchanged).'; $lang['mediaexists'] = 'Media %s can\'t be moved to %s, the target already exists.'; $lang['nomediatargetperms'] = 'You don\'t have the permission to create the media file %s.'; +$lang['extensionchange'] = 'Extension of the new file is not the same as the original.'; // system errors $lang['indexerror'] = 'Error while updating the search index %s'; diff --git a/lang/pl/lang.php b/lang/pl/lang.php index f6d627f..a4a5f62 100644 --- a/lang/pl/lang.php +++ b/lang/pl/lang.php @@ -31,8 +31,8 @@ $lang['targetns'] = 'Nazwa docelowego katalogu:'; $lang['submit'] = 'Zmień'; +$lang['extensionchange'] = 'Rozszerzenia plików nie są identyczne.'; + // Media Manager -$lang['errorOverwrite'] = 'Plik już istnieje!'; -$lang['errorPermissions'] = 'Niewystarczające uprawnienia by wykonać operację!'; $lang['js']['moveButton'] = 'Przenieś/Zmień nazwę'; $lang['js']['dialogIntro'] = 'Nowa nazwa pliku. Możesz zmienić katalog, ale nie rozszerzenie pliku.'; From 27a1b6d680f8088573cad08a9945ea0ed3dfca15 Mon Sep 17 00:00:00 2001 From: Anna Dabrowska Date: Wed, 21 Jun 2023 16:42:12 +0200 Subject: [PATCH 327/338] Check renaming restrictions when moving media --- action/rename.php | 14 +++++++++++++- lang/de-informal/lang.php | 1 + lang/de-informal/settings.php | 2 +- lang/de/lang.php | 1 + lang/de/settings.php | 2 +- lang/en/lang.php | 1 + lang/en/settings.php | 2 +- lang/pl/lang.php | 1 + 8 files changed, 20 insertions(+), 4 deletions(-) diff --git a/action/rename.php b/action/rename.php index 9126730..48cf667 100644 --- a/action/rename.php +++ b/action/rename.php @@ -123,13 +123,16 @@ public function handleAjaxMediaManager(Doku_Event $event) { if ($event->data !== 'plugin_move_rename_mediamanager') return; - if (!checkSecurityToken()) return; + if (!checkSecurityToken()) { + throw new \Exception('Security token did not match'); + } $event->preventDefault(); $event->stopPropagation(); global $INPUT; global $MSG; + global $USERINFO; $src = cleanID($INPUT->str('src')); $dst = cleanID($INPUT->str('dst')); @@ -142,6 +145,15 @@ public function handleAjaxMediaManager(Doku_Event $event) $response = []; + // check user/group restrictions + if ( + !auth_isMember($this->getConf('allowrename'), $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']) + ) { + $response['error'] = $this->getLang('notallowed'); + echo json_encode($response); + return; + } + $response['success'] = $moveOperator->moveMedia($src, $dst); if ($response['success']) { diff --git a/lang/de-informal/lang.php b/lang/de-informal/lang.php index d3d985b..2fb0ef3 100644 --- a/lang/de-informal/lang.php +++ b/lang/de-informal/lang.php @@ -52,6 +52,7 @@ $lang['nodst'] = 'Kein neuer Name angegeben'; $lang['noaction'] = 'Es wurden keine Verschiebungen angegeben'; $lang['renamepage'] = 'Seite umbenennen'; +$lang['notallowed'] = 'Du hast unzureichende Rechte, um Seiten oder Medien umzubenennen.'; $lang['cantrename'] = 'Auf die Seite kann zur Zeit nicht zugegriffen werden - bitte versuche es später noch einmal.'; $lang['js']['rename'] = 'Umbenennen'; $lang['js']['cancel'] = 'Abbrechen'; diff --git a/lang/de-informal/settings.php b/lang/de-informal/settings.php index 8ef0f2f..71ba293 100644 --- a/lang/de-informal/settings.php +++ b/lang/de-informal/settings.php @@ -5,7 +5,7 @@ * * @author F. Mueller-Donath */ -$lang['allowrename'] = 'Umbenennen von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt).'; +$lang['allowrename'] = 'Umbenennen von Seiten und Mediendateien diesen Gruppen und Benutzern erlauben (durch Kommas getrennt).'; $lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderungen werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; $lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; $lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; diff --git a/lang/de/lang.php b/lang/de/lang.php index 4293406..e6f6479 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -54,6 +54,7 @@ $lang['nodst'] = 'Kein neuer Name angegeben'; $lang['noaction'] = 'Es wurden keine Verschiebungen angegeben'; $lang['renamepage'] = 'Seite umbenennen'; +$lang['notallowed'] = 'Sie haben unzureichende Rechte, um Seiten oder Medien umzubenennen.'; $lang['cantrename'] = 'Auf die Seite kann zur Zeit nicht zugegriffen werden - versuchen Sie es später noch einmal.'; $lang['js']['rename'] = 'Umbenennen'; $lang['js']['cancel'] = 'Abbrechen'; diff --git a/lang/de/settings.php b/lang/de/settings.php index 23b567a..9e9a4a5 100644 --- a/lang/de/settings.php +++ b/lang/de/settings.php @@ -6,7 +6,7 @@ * @author F. Mueller-Donath * @author e-dschungel */ -$lang['allowrename'] = 'Umbenennen von Seiten diesen Gruppen und Benutzern erlauben (durch Kommas getrennt).'; +$lang['allowrename'] = 'Umbenennen von Seiten und Mediendateien diesen Gruppen und Benutzern erlauben (durch Kommas getrennt).'; $lang['minor'] = 'Linkanpassung als kleine Änderung markieren? Kleine Änderung werden in RSS Feeds und Benachrichtigungsmails nicht aufgeführt.'; $lang['autoskip'] = 'Automatisches Überspringen von Fehlern beim Verschieben von Namensräumen standardmäßig aktivieren. '; $lang['autorewrite'] = 'Automatische Linkanpassung standardmäßig aktivieren.'; diff --git a/lang/en/lang.php b/lang/en/lang.php index a614280..48a81d6 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -68,6 +68,7 @@ // Rename feature $lang['renamepage'] = 'Rename Page'; $lang['cantrename'] = 'The page can\'t be renamed right now. Please try later.'; +$lang['notallowed'] = 'You are not allowed to rename pages or media.'; $lang['js']['rename'] = 'Rename'; $lang['js']['cancel'] = 'Cancel'; $lang['js']['newname'] = 'New name:'; diff --git a/lang/en/settings.php b/lang/en/settings.php index a662c27..659f2e1 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -1,6 +1,6 @@ Date: Tue, 27 Jun 2023 10:28:28 +0200 Subject: [PATCH 328/338] Media manager: early check if user is allowed to rename files Checks if user matches the 'allowrename' setting --- action/rename.php | 4 ++++ script/MoveMediaManager.js | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/action/rename.php b/action/rename.php index 48cf667..6e53083 100644 --- a/action/rename.php +++ b/action/rename.php @@ -35,7 +35,11 @@ public function register(Doku_Event_Handler $controller) { public function handle_init() { global $JSINFO; global $INFO; + global $INPUT; + global $USERINFO; + $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']); + $JSINFO['move_allowrename'] = auth_isMember($this->getConf('allowrename'), $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']); } /** diff --git a/script/MoveMediaManager.js b/script/MoveMediaManager.js index f825572..fe2d7e7 100644 --- a/script/MoveMediaManager.js +++ b/script/MoveMediaManager.js @@ -5,20 +5,23 @@ class MoveMediaManager { constructor() { + // user is not allowed to move anything + if (!JSINFO.move_allowrename) return; + const filePanel = document.querySelector('#mediamanager__page .panel.file'); if (filePanel) { - const observer = new MutationObserver(this.#addEditButton.bind(this)); + const observer = new MutationObserver(this.#addMoveButton.bind(this)); observer.observe(filePanel, {childList: true, subtree: true}); } } /** - * Observer callback to add the edit button in the detail panel of the media manager + * Observer callback to add the move button in the detail panel of the media manager * * @param mutationsList * @param observer */ - async #addEditButton(mutationsList, observer) { + async #addMoveButton(mutationsList, observer) { for (let mutation of mutationsList) { // div.file has been filled with new content? if (mutation.type !== 'childList') continue; From 42c7121ac83e2fd3b28ce31881b818300f16ffe0 Mon Sep 17 00:00:00 2001 From: Anna Dabrowska Date: Wed, 28 Jun 2023 12:23:25 +0200 Subject: [PATCH 329/338] Fix media renaming with URL rewriting --- script/MoveMediaManager.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/script/MoveMediaManager.js b/script/MoveMediaManager.js index fe2d7e7..cca7cdf 100644 --- a/script/MoveMediaManager.js +++ b/script/MoveMediaManager.js @@ -37,12 +37,7 @@ class MoveMediaManager { const deleteButton = actionList.querySelector('form#mediamanager__btn_delete'); if (deleteButton === null) continue; // no delete permissions - const uri = link.getAttribute('href'); - - const [ , paramString ] = uri.split( '?' ); - const searchParams = new URLSearchParams(paramString); - const src = searchParams.get('media'); - + const src = link.textContent; const moveButton = document.createElement('button'); moveButton.classList.add('move-btn'); From f1684ff5153a8c41b0da552bdbff1e1bcc6a1ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schplurtz=20le=20D=C3=A9boulonn=C3=A9?= Date: Tue, 15 Aug 2023 04:00:25 +0200 Subject: [PATCH 330/338] translation update --- lang/fr/lang.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lang/fr/lang.php b/lang/fr/lang.php index 5b5c59e..8e9242a 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -3,9 +3,9 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author Schplurtz le Déboulonné * @author Gary Owen * @author Nicolas Friedli - * @author Schplurtz le Déboulonné */ $lang['menu'] = 'Déplacer/Renommer pages et catégories...'; $lang['inprogress'] = '(déplacement en attente)'; @@ -21,6 +21,7 @@ $lang['medianotchanged'] = 'Pas de nouvelle destination pour la page %s (emplacement inchangé).'; $lang['mediaexists'] = 'Impossible de déplacer le média %s. la cible %s existe déjà.'; $lang['nomediatargetperms'] = 'Vous n\'avez pas les permissions de créer le média %s'; +$lang['extensionchange'] = 'L\'extension du nouveau fichier diffère de celle de l\'original.'; $lang['indexerror'] = 'Erreur lors de la mise à jour de l\'index de recherche %s.'; $lang['metamoveerror'] = 'Impossible de déplacer les métafichiers de la page %s.'; $lang['atticmoveerror'] = 'L\'historique (attic) de la page %s ne peut être déplacé. Veuillez déplacer les fichiers manuellement.'; @@ -54,6 +55,7 @@ $lang['noaction'] = 'Pas de déplacement demandé'; $lang['renamepage'] = 'Renommer la page'; $lang['cantrename'] = 'Impossible de renommer la page maintenant. Veuillez essayer plus tard.'; +$lang['notallowed'] = 'Vous n\'êtes pas autorisé à renommer les pages ou les médias.'; $lang['js']['rename'] = 'Renommer'; $lang['js']['cancel'] = 'Annuler'; $lang['js']['newname'] = 'Nouveau nom:'; @@ -62,6 +64,8 @@ $lang['js']['renameitem'] = 'Renommer cet élément'; $lang['js']['add'] = 'Créer une nouvelle catégorie'; $lang['js']['duplicate'] = 'Désolé, "%s" existe dans cette catégorie.'; +$lang['js']['moveButton'] = 'Déplacer le fichier.'; +$lang['js']['dialogIntro'] = 'Entrez le nouvel emplacement du fichier. Vous pouvez changer la catégorie, mais pas l\'extension.'; $lang['root'] = '[Catégorie racine]'; $lang['noscript'] = 'Cette fonction requiert JavaScript'; $lang['moveinprogress'] = 'Une opération de déplacement est en cours en ce moment. Vous ne pouvez pas utiliser cet outil maintenant.'; From f175a7aa86dc33121afa73b5abc9bb516d367136 Mon Sep 17 00:00:00 2001 From: Damien Regad Date: Fri, 26 Apr 2024 10:31:08 +0200 Subject: [PATCH 331/338] Fix PHP warning when user not logged in Warning: Trying to access array offset on value of type null in ./dokuwiki/move/action/rename.php on line 42 $USERINFO is null when user is not logged in. Regression introduced by 0af31bb63abd3731e904efc2ed90dd3ce33f4e52 (#246). Fixes #256, #255 --- action/rename.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/action/rename.php b/action/rename.php index 6e53083..d58bca2 100644 --- a/action/rename.php +++ b/action/rename.php @@ -39,7 +39,11 @@ public function handle_init() { global $USERINFO; $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']); - $JSINFO['move_allowrename'] = auth_isMember($this->getConf('allowrename'), $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']); + $JSINFO['move_allowrename'] = auth_isMember( + $this->getConf('allowrename'), + $INPUT->server->str('REMOTE_USER'), + $USERINFO['grps'] ?? [] + ); } /** From c67a68dc87a0b66b8dfbf312d97d4767a9df849b Mon Sep 17 00:00:00 2001 From: Damien Regad Date: Fri, 26 Apr 2024 10:32:26 +0200 Subject: [PATCH 332/338] Bump version --- plugin.info.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.info.txt b/plugin.info.txt index 809b80d..dcc72a5 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2022-01-23 +date 2024-04-26 name Move plugin desc Move and rename pages and media files whilst maintaining the links. -url http://www.dokuwiki.org/plugin:move +url https://www.dokuwiki.org/plugin:move From db707aeb49a33f8ebaffc92847fe6449278847db Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 30 Apr 2024 22:55:50 +0200 Subject: [PATCH 333/338] Add modern plugin skeleton * Add license file * Migrate to DokuWiki workflow * Add general test --- .github/workflows/dokuwiki.yml | 11 + .github/workflows/phpTestLinux.yml | 52 ----- LICENSE | 339 +++++++++++++++++++++++++++++ _test/GeneralTest.php | 84 +++++++ 4 files changed, 434 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/dokuwiki.yml delete mode 100644 .github/workflows/phpTestLinux.yml create mode 100644 LICENSE create mode 100644 _test/GeneralTest.php diff --git a/.github/workflows/dokuwiki.yml b/.github/workflows/dokuwiki.yml new file mode 100644 index 0000000..608ef34 --- /dev/null +++ b/.github/workflows/dokuwiki.yml @@ -0,0 +1,11 @@ +name: DokuWiki Default Tasks +on: + push: + pull_request: + schedule: + - cron: '1 18 5 * *' + + +jobs: + all: + uses: dokuwiki/github-action/.github/workflows/all.yml@main diff --git a/.github/workflows/phpTestLinux.yml b/.github/workflows/phpTestLinux.yml deleted file mode 100644 index cb3361e..0000000 --- a/.github/workflows/phpTestLinux.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: PHP Tests on Linux - -on: [push, pull_request] - -jobs: - testLinux: - name: PHP ${{ matrix.php-versions }} DokuWiki ${{ matrix.dokuwiki-branch }} - runs-on: ubuntu-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - - strategy: - matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0'] - dokuwiki-branch: [ 'master', 'stable'] - exclude: - - dokuwiki-branch: 'stable' - php-versions: '8.0' - fail-fast: false - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, intl, PDO, pdo_sqlite, bz2 - - - name: Setup problem matchers - run: | - echo ::add-matcher::${{ runner.tool_cache }}/php.json - echo ::add-matcher::${{ runner.tool_cache }}/phpunit.json - - - name: Download DokuWiki Test-setup - run: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh - - - name: Run DokuWiki Test-setup - env: - CI_SERVER: 1 - DOKUWIKI: ${{ matrix.dokuwiki-branch }} - run: sh travis.sh - - - name: Setup PHPUnit - run: | - php _test/fetchphpunit.php - cd _test - - - name: Run PHPUnit - run: | - cd _test - php phpunit.phar --verbose --stderr --group plugin_move diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/_test/GeneralTest.php b/_test/GeneralTest.php new file mode 100644 index 0000000..918656b --- /dev/null +++ b/_test/GeneralTest.php @@ -0,0 +1,84 @@ +assertFileExists($file); + + $info = confToHash($file); + + $this->assertArrayHasKey('base', $info); + $this->assertArrayHasKey('author', $info); + $this->assertArrayHasKey('email', $info); + $this->assertArrayHasKey('date', $info); + $this->assertArrayHasKey('name', $info); + $this->assertArrayHasKey('desc', $info); + $this->assertArrayHasKey('url', $info); + + $this->assertEquals('move', $info['base']); + $this->assertRegExp('/^https?:\/\//', $info['url']); + $this->assertTrue(mail_isvalid($info['email'])); + $this->assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']); + $this->assertTrue(false !== strtotime($info['date'])); + } + + /** + * Test to ensure that every conf['...'] entry in conf/default.php has a corresponding meta['...'] entry in + * conf/metadata.php. + */ + public function testPluginConf(): void + { + $conf_file = __DIR__ . '/../conf/default.php'; + $meta_file = __DIR__ . '/../conf/metadata.php'; + + if (!file_exists($conf_file) && !file_exists($meta_file)) { + self::markTestSkipped('No config files exist -> skipping test'); + } + + if (file_exists($conf_file)) { + include($conf_file); + } + if (file_exists($meta_file)) { + include($meta_file); + } + + $this->assertEquals( + gettype($conf), + gettype($meta), + 'Both ' . DOKU_PLUGIN . 'move/conf/default.php and ' . DOKU_PLUGIN . 'move/conf/metadata.php have to exist and contain the same keys.' + ); + + if ($conf !== null && $meta !== null) { + foreach ($conf as $key => $value) { + $this->assertArrayHasKey( + $key, + $meta, + 'Key $meta[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'move/conf/metadata.php' + ); + } + + foreach ($meta as $key => $value) { + $this->assertArrayHasKey( + $key, + $conf, + 'Key $conf[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'move/conf/default.php' + ); + } + } + } +} From 577a39e7617b7e6fa7525845e7c7bfe2998233bf Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 7 May 2024 22:31:46 +0200 Subject: [PATCH 334/338] Version upped --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index dcc72a5..cbca9c7 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2024-04-26 +date 2024-04-30 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url https://www.dokuwiki.org/plugin:move From 8c44e302a524f29a85e8f59d3f58b76815890ce0 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 7 May 2024 22:42:07 +0200 Subject: [PATCH 335/338] Add release workflow --- .github/workflows/release.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..54f680b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +# Create release on change to plugin.info.txt version line +# https://github.com/dokuwiki/dokuwiki/issues/3951 +# +# Requires DOKUWIKI_USER and DOKUWIKI_PASS secrets be set in GitHub Actions + +name: Release + +on: + push: + branches: + - master + paths: + - "*.info.txt" + +jobs: + release: + name: Release + # https://github.com/dokuwiki/dokuwiki/pull/3966 + uses: glensc/dokuwiki/.github/workflows/plugin-release.yml@39431875f734bddc35cc6b4a899bbfdec97e8aba + secrets: + DOKUWIKI_USER: ${{ secrets.DOKUWIKI_USER }} + DOKUWIKI_PASS: ${{ secrets.DOKUWIKI_PASS }} + +# vim:ts=2:sw=2:et From 941af2bce06825a5c29404f2d3693a810b3dc262 Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 7 May 2024 23:10:35 +0200 Subject: [PATCH 336/338] Fix #251 undefined array keys --- action/rename.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/action/rename.php b/action/rename.php index d58bca2..ca7cb0d 100644 --- a/action/rename.php +++ b/action/rename.php @@ -38,7 +38,12 @@ public function handle_init() { global $INPUT; global $USERINFO; - $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']); + if (isset($INFO['id'])) { + $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']); + } else { + $JSINFO['move_renameokay'] = false; + } + $JSINFO['move_allowrename'] = auth_isMember( $this->getConf('allowrename'), $INPUT->server->str('REMOTE_USER'), @@ -77,7 +82,7 @@ public function addsvgbutton(Doku_Event $event) { if( $event->data['view'] !== 'page' || !$this->getConf('pagetools_integration') || - !$JSINFO['move_renameokay'] + empty($JSINFO['move_renameokay']) ) { return; } From 25f355432c1991e69ca609ad550dfd3ff41a254a Mon Sep 17 00:00:00 2001 From: Michael Hamann Date: Tue, 7 May 2024 23:16:49 +0200 Subject: [PATCH 337/338] New version, fixed undefined array key warnings --- plugin.info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.info.txt b/plugin.info.txt index cbca9c7..675c418 100644 --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base move author Michael Hamann, Gary Owen, Arno Puschmann, Christoph Jähnigen email michael@content-space.de -date 2024-04-30 +date 2024-05-07 name Move plugin desc Move and rename pages and media files whilst maintaining the links. url https://www.dokuwiki.org/plugin:move From 788b8f5d47a8ca79c475e6e972d1d7e06764bde7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=91=BDLeaflet?= <2532846822@qq.com> Date: Thu, 31 Oct 2024 15:55:48 +0100 Subject: [PATCH 338/338] translation update --- lang/zh/lang.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lang/zh/lang.php b/lang/zh/lang.php index c2ee93e..2752eb1 100644 --- a/lang/zh/lang.php +++ b/lang/zh/lang.php @@ -3,6 +3,7 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author 小命Leaflet <2532846822@qq.com> * @author Gary Owen * @author TombCrow * @author Hanjia Zhuang @@ -13,7 +14,7 @@ $lang['treelink'] = '您还可以通过树形移动.来为您的wiki条目结构做复杂调整'; $lang['notexist'] = '页面 %s不存在'; $lang['norights'] = '您没有权限编辑%s.'; -$lang['filelocked'] = '此文件被锁定 - 请稍后重试'; +$lang['filelocked'] = '此页面%s被锁定 - 请稍后重试'; $lang['notchanged'] = '未为页面%s指定新地址(位置未变)'; $lang['exists'] = '页面%s无法被移动至%s ,该目标已存在 '; $lang['notargetperms'] = '您没有权限创建页面%s.'; @@ -22,6 +23,7 @@ $lang['medianotchanged'] = '未为页面%s指定新地址(位置未变)'; $lang['mediaexists'] = '媒体文件%s无法被移动至%s,目标已存在。'; $lang['nomediatargetperms'] = '您没有权限创建媒体文件%s。'; +$lang['extensionchange'] = '新文件的扩展名与原始文件不相同'; $lang['indexerror'] = '当更新搜索索引 %s 时发生错误'; $lang['metamoveerror'] = 'meta文件的页面 %s 无法移动'; $lang['atticmoveerror'] = '页面文件 %s 的attic文件无法移动。请手动移动它们。'; @@ -55,6 +57,7 @@ $lang['noaction'] = '未定义任何移动'; $lang['renamepage'] = '页面重命名'; $lang['cantrename'] = '页面现在无法重命名,请稍后再试。'; +$lang['notallowed'] = '您没有权限重命名页面或媒体文件'; $lang['js']['rename'] = '重命名'; $lang['js']['cancel'] = '取消'; $lang['js']['newname'] = '新名字:'; @@ -63,6 +66,8 @@ $lang['js']['renameitem'] = '重命名该项'; $lang['js']['add'] = '创建一个新的名称空间'; $lang['js']['duplicate'] = '抱歉,"%s"在该目录已存在'; +$lang['js']['moveButton'] = '文件移动'; +$lang['js']['dialogIntro'] = '输入新文件的目标位置。您可以更改命名空间,但无法更改文件扩展名'; $lang['root'] = '[跟目录]'; $lang['noscript'] = '该功能需要JavaScript'; $lang['moveinprogress'] = '另一个移动操作正在进行,您现在无法使用该工具';