はじまりの大地
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
<signature of Ty Coon>, 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.
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace dokuwiki\plugin\move;
|
||||
use dokuwiki\Menu\Item\AbstractItem;
|
||||
/**
|
||||
* Class MenuItem
|
||||
*
|
||||
* Implements the Rename button for DokuWiki's menu system
|
||||
*
|
||||
* @package dokuwiki\plugin\move
|
||||
*/
|
||||
class MenuItem extends AbstractItem {
|
||||
|
||||
/** @var string icon file */
|
||||
protected $svg = __DIR__ . '/images/rename.svg';
|
||||
|
||||
protected $type = "plugin_move";
|
||||
|
||||
public function getLinkAttributes($classprefix = 'menuitem ') {
|
||||
$attr = parent::getLinkAttributes($classprefix);
|
||||
if (empty($attr['class'])) {
|
||||
$attr['class'] = '';
|
||||
}
|
||||
$attr['class'] .= ' plugin_move_page ';
|
||||
return $attr;
|
||||
}
|
||||
/**
|
||||
* Get label from plugin language file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel() {
|
||||
$hlp = plugin_load('action', 'move_rename');
|
||||
return $hlp->getLang('renamepage');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\move\test;
|
||||
|
||||
use DokuWikiTest;
|
||||
|
||||
/**
|
||||
* General tests for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class GeneralTest extends DokuWikiTest
|
||||
{
|
||||
/**
|
||||
* Simple test to make sure the plugin.info.txt is in correct format
|
||||
*/
|
||||
public function testPluginInfo(): void
|
||||
{
|
||||
$file = __DIR__ . '/../plugin.info.txt';
|
||||
$this->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'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Test cases for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_affectedPagesNS_test extends DokuWikiTest {
|
||||
|
||||
protected $pluginsEnabled = array('move',);
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
global $USERINFO;
|
||||
global $conf;
|
||||
$conf['useacl'] = 1;
|
||||
$conf['superuser'] = 'john';
|
||||
$_SERVER['REMOTE_USER'] = 'john'; //now it's testing as admin
|
||||
$USERINFO['grps'] = array('admin','user');
|
||||
}
|
||||
|
||||
/**
|
||||
* @coversNothing
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
/** @var helper_plugin_move_plan $plan */
|
||||
$plan = plugin_load('helper', 'move_plan');
|
||||
$plan->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('oldns:start',trim($affected_file[0]));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
// must be run within Dokuwiki
|
||||
if (!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* Test cases for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_cache_handling_test extends DokuWikiTest {
|
||||
|
||||
function setUp(): void {
|
||||
parent::setUpBeforeClass();
|
||||
$this->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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
|
||||
class helper_plugin_move_plan_findMissingDocuments_mock extends helper_plugin_move_plan {
|
||||
|
||||
public function findMissingDocuments($src, $dst, $type = self::TYPE_PAGES) {
|
||||
parent::findMissingDocuments($src, $dst, $type);
|
||||
}
|
||||
|
||||
public function getTmpstore() {
|
||||
return $this->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(): void {
|
||||
parent::setUp();
|
||||
$this->plan = new helper_plugin_move_plan_findMissingDocuments_mock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @coversNothing
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
global $conf;
|
||||
|
||||
$dirs = array('indexdir','datadir','metadir', 'mediadir');
|
||||
foreach ($dirs as $dir) {
|
||||
io_rmdir($conf[$dir],true);
|
||||
mkdir($conf[$dir]);
|
||||
}
|
||||
$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']);
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// must be run within Dokuwiki
|
||||
if(!defined('DOKU_INC')) die();
|
||||
|
||||
require_once(__DIR__ . '/../helper/handler.php');
|
||||
|
||||
/**
|
||||
* Test cases for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_handler_test extends DokuWikiTest {
|
||||
|
||||
public function setUp(): void {
|
||||
$this->pluginsEnabled[] = 'move';
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function test_relativeLink() {
|
||||
/** @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',
|
||||
'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) {
|
||||
$this->assertEquals($rel, $handler->relativeLink('foo', $new, 'page'));
|
||||
}
|
||||
|
||||
$this->assertEquals('.deeper:', $handler->relativeLink('.deeper:', 'deep:namespace:deeper:start', 'page'));
|
||||
$this->assertEquals('.:', $handler->relativeLink('.:', 'deep:namespace:start', 'page'));
|
||||
}
|
||||
|
||||
public function test_resolveMoves() {
|
||||
/** @var $handler helper_plugin_move_handler */
|
||||
$handler = plugin_load('helper', 'move_handler');
|
||||
$handler->init(
|
||||
'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'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Test cases log functionality of the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugin_move_unittests
|
||||
* @group plugins
|
||||
* @group unittests
|
||||
*/
|
||||
class plugin_move_log_test extends DokuWikiTest {
|
||||
|
||||
protected $pluginsEnabled = array('move',);
|
||||
|
||||
public function test_log_one_line_success() {
|
||||
/** @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',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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
// must be run within Dokuwiki
|
||||
if (!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* Test cases for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_mediamove_test extends DokuWikiTest {
|
||||
|
||||
public function setUp(): void {
|
||||
$this->pluginsEnabled[] = 'move';
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group slow
|
||||
*/
|
||||
public function test_movePageWithRelativeMedia() {
|
||||
$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($src);
|
||||
|
||||
$dst = 'foo';
|
||||
|
||||
/** @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}}]]
|
||||
[[doku>wiki:foo|{{mediareltest:foo.gif?200x3000}}]]', rawWiki('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group slow
|
||||
*/
|
||||
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');
|
||||
|
||||
$src = 'wiki:dokuwiki-128.png';
|
||||
$dst = 'foobar:logo.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.png')));
|
||||
|
||||
$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\t16";
|
||||
$AUTH_ACL[] = "*\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'));
|
||||
|
||||
$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'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
<?php
|
||||
|
||||
// must be run within Dokuwiki
|
||||
if (!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* Test cases for namespace move functionality of the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_namespace_move_test extends DokuWikiTest {
|
||||
|
||||
public function setUp(): void {
|
||||
$this->pluginsEnabled[] = 'move';
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @coversNothing
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
/** @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);
|
||||
io_rmdir(DOKU_TMP_DATA."meta/newns",true);
|
||||
|
||||
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
|
||||
*
|
||||
* @group slow
|
||||
*/
|
||||
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_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(),'missing');
|
||||
$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'));
|
||||
$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
|
||||
*
|
||||
* @group slow
|
||||
*/
|
||||
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(),'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'));
|
||||
|
||||
$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
|
||||
*
|
||||
* @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]]';
|
||||
$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';
|
||||
|
||||
$this->assertSame(10, $plan->nextStep(),"After processing first chunk of pages, 10 steps should be left");
|
||||
|
||||
$request = new TestRequest();
|
||||
$response = $request->get();
|
||||
$actual_response = $response->getContent();
|
||||
//clean away clutter
|
||||
$actual_response = substr($actual_response,strpos($actual_response,"<!-- wikipage start -->") + 23);
|
||||
$actual_response = substr($actual_response,strpos($actual_response, 'doku.php'));
|
||||
$actual_response = substr($actual_response,0,strpos($actual_response,"<!-- wikipage stop -->"));
|
||||
$actual_response = trim($actual_response);
|
||||
$actual_response = rtrim($actual_response,"</p>");
|
||||
$actual_response = trim($actual_response);
|
||||
|
||||
$expected_response = 'doku.php?id=foo:testns:start" class="wikilink1" title="foo:testns:start">testns</a> <a href="/./doku.php?id=testns:test_page17" class="wikilink1" title="testns:test_page17">test_page17</a>';
|
||||
$this->assertSame($expected_response,$actual_response); // todo: this assert fails occaisionally, but not reproduciably. It then has the following oputput: <a href="/./doku.php?id=testns:start" class="wikilink2" title="testns:start" rel="nofollow">testns</a> <a href="/./doku.php?id=testns:test_page17" class="wikilink1" title="testns:test_page17">test_page17</a>
|
||||
|
||||
$expected_file_contents = '[[testns:start]] [[testns:test_page17]]';
|
||||
$start_file = file(TMP_DIR . '/data/pages/start.txt');
|
||||
$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');
|
||||
$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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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');
|
||||
$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'));
|
||||
$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}} {{image_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');
|
||||
|
||||
$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}} {{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}} {{newns:oldnsimage_missing.png}} {{newns:oldnsimage.png}}',rawWiki('oldns: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->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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,629 @@
|
||||
<?php
|
||||
|
||||
// must be run within Dokuwiki
|
||||
if (!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* Test cases for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_pagemove_test extends DokuWikiTest {
|
||||
|
||||
var $movedToId = '';
|
||||
var $movedId = 'parent_ns:current_ns:test_page';
|
||||
var $parentBacklinkingId = 'parent_ns:some_page';
|
||||
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';
|
||||
|
||||
// @todo Move page to an ID which already exists
|
||||
// @todo Check backlinks of a sub-namespace page (moving same, up, down, different)
|
||||
|
||||
function setUp(): void {
|
||||
parent::setUpBeforeClass();
|
||||
$this->pluginsEnabled[] = 'move';
|
||||
global $ID;
|
||||
global $INFO;
|
||||
global $conf;
|
||||
|
||||
$ID = $this->movedId;
|
||||
|
||||
$text = <<<EOT
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$summary = 'Test';
|
||||
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 = <<<EOT
|
||||
[[$this->movedId|$this->movedId]]
|
||||
[[:$this->movedId|:$this->movedId]]
|
||||
[[.current_ns:test_page|.current_ns:test_page]]
|
||||
[[.:current_ns:test_page|.:current_ns:test_page]]
|
||||
[[..parent_ns:current_ns:test_page|..parent_ns:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
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 = <<<EOT
|
||||
[[$this->movedId|$this->movedId]]
|
||||
[[:$this->movedId|:$this->movedId]]
|
||||
[[..current_ns:test_page|..current_ns:test_page]]
|
||||
[[..:current_ns:test_page|..:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[.test_page|.test_page]]
|
||||
[[.:test_page|.:test_page]]
|
||||
[[..test_page|..test_page]]
|
||||
[[..:test_page|..:test_page]]
|
||||
[[.:..:test_page|.:..:test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
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 = <<<EOT
|
||||
[[$this->movedId|$this->movedId]]
|
||||
[[:$this->movedId|:$this->movedId]]
|
||||
[[.current_ns:test_page|.current_ns:test_page]]
|
||||
[[.:current_ns:test_page|.:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
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 = <<<EOT
|
||||
[[$this->movedId|$this->movedId]]
|
||||
[[:$this->movedId|:$this->movedId]]
|
||||
[[..:..current_ns:test_page|..:..current_ns:test_page]]
|
||||
[[..:..:current_ns:test_page|..:..:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[..:test_page|..:test_page]]
|
||||
[[..:test_page|..:test_page]]
|
||||
[[.:..:test_page|.:..:test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[..:new_page|..:new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
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);
|
||||
|
||||
parent::setUp();
|
||||
|
||||
// we test under useslash conditions
|
||||
$conf['useslash'] = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @group slow
|
||||
*/
|
||||
function test_move_page_in_same_ns() {
|
||||
global $ID;
|
||||
$newId = getNS($ID).':new_page';
|
||||
$this->movedToId = $newId;
|
||||
|
||||
/** @var helper_plugin_move_op $MoveOp */
|
||||
$MoveOp = plugin_load('helper', 'move_op');
|
||||
|
||||
$result = $MoveOp->movePage($ID, $this->movedToId);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$newContent = rawWiki($this->movedToId);
|
||||
$expectedContent = <<<EOT
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->parentBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[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]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->currentNsBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[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]]
|
||||
[[new_page|.test_page]]
|
||||
[[new_page|.:test_page]]
|
||||
[[..test_page|..test_page]]
|
||||
[[..:test_page|..:test_page]]
|
||||
[[.:..:test_page|.:..:test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->otherBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[parent_ns:current_ns:new_page|$this->movedId]]
|
||||
[[$newId|:$this->movedId]]
|
||||
[[.current_ns:test_page|.current_ns:test_page]]
|
||||
[[.:current_ns:test_page|.:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group slow
|
||||
*/
|
||||
function test_move_page_to_parallel_ns() {
|
||||
global $ID;
|
||||
$newId = 'parent_ns:parallel_ns:new_page';
|
||||
$this->movedToId = $newId;
|
||||
|
||||
/** @var helper_plugin_move_op $MoveOp */
|
||||
$MoveOp = plugin_load('helper', 'move_op');
|
||||
|
||||
$result = $MoveOp->movePage($ID, $newId);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$newContent = rawWiki($this->movedToId);
|
||||
$expectedContent = <<<EOT
|
||||
[[..:current_ns:start|start]]
|
||||
[[..:current_ns:parallel_page|parallel_page]]
|
||||
[[..:current_ns:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->parentBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[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]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->currentNsBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[parent_ns:parallel_ns:new_page|$this->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]]
|
||||
[[..test_page|..test_page]]
|
||||
[[..:test_page|..:test_page]]
|
||||
[[.:..:test_page|.:..:test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->otherBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[parent_ns:parallel_ns:new_page|$this->movedId]]
|
||||
[[$newId|:$this->movedId]]
|
||||
[[.current_ns:test_page|.current_ns:test_page]]
|
||||
[[.:current_ns:test_page|.:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group slow
|
||||
*/
|
||||
function test_move_page_to_parent_ns() {
|
||||
global $ID;
|
||||
|
||||
$newId = 'parent_ns:new_page';
|
||||
$this->movedToId = $newId;
|
||||
|
||||
/** @var helper_plugin_move_op $MoveOp */
|
||||
$MoveOp = plugin_load('helper', 'move_op');
|
||||
|
||||
$result = $MoveOp->movePage($ID, $newId); //parent_ns:current_ns:test_page -> parent_ns:new_page
|
||||
$this->assertTrue($result);
|
||||
|
||||
$newContent = rawWiki($this->movedToId);
|
||||
$expectedContent = <<<EOT
|
||||
[[.current_ns:start|start]]
|
||||
[[.current_ns:parallel_page|parallel_page]]
|
||||
[[.current_ns:|.:]]
|
||||
[[.current_ns:|..current_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)
|
||||
$newContent = rawWiki($this->parentBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[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]]
|
||||
[[test_page|test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->currentNsBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[parent_ns:new_page|$this->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]]
|
||||
[[..test_page|..test_page]]
|
||||
[[..:test_page|..:test_page]]
|
||||
[[.:..:test_page|.:..:test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
|
||||
$newContent = rawWiki($this->otherBacklinkingId);
|
||||
$expectedContent = <<<EOT
|
||||
[[parent_ns:new_page|$this->movedId]]
|
||||
[[$newId|:$this->movedId]]
|
||||
[[.current_ns:test_page|.current_ns:test_page]]
|
||||
[[.:current_ns:test_page|.:current_ns:test_page]]
|
||||
[[test_page|test_page]]
|
||||
[[new_page|new_page]]
|
||||
[[ftp://somewhere.com|ftp://somewhere.com]]
|
||||
[[http://somewhere.com|http://somewhere.com]]
|
||||
|
||||
[[start|start]]
|
||||
[[parallel_page|parallel_page]]
|
||||
[[.:|.:]]
|
||||
[[..current_ns:|..current_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;
|
||||
$this->assertEquals($expectedContent, $newContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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',
|
||||
'[[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'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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');
|
||||
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'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers helper_plugin_move_handler::_nsStartCheck
|
||||
* @group slow
|
||||
*/
|
||||
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() {
|
||||
|
||||
$newNamespace = 'new_ns';
|
||||
$newPagename = '';
|
||||
|
||||
$opts = array();
|
||||
$opts['page_ns'] = 'ns';
|
||||
$opts['newns'] = 'parent_ns'.':'.$newNamespace;
|
||||
$opts['newname'] = $newPagename;
|
||||
$this->movedToId = $opts['newns'].':'.$newPagename;
|
||||
|
||||
//$this->move->_pm_move_recursive($opts);
|
||||
$this->markTestIncomplete('Test must yet be implemented.');
|
||||
|
||||
}
|
||||
|
||||
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'));
|
||||
}
|
||||
|
||||
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'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
// must be run within Dokuwiki
|
||||
if(!defined('DOKU_INC')) die();
|
||||
|
||||
require_once(__DIR__ . '/../helper/plan.php');
|
||||
|
||||
/**
|
||||
* Test cases for the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class plugin_move_plan_test extends DokuWikiTest {
|
||||
|
||||
/**
|
||||
* Create some page namespace structure
|
||||
*/
|
||||
function setUp():void {
|
||||
$pages = array(
|
||||
'animals:mammals:bear:brownbear',
|
||||
'animals:mammals:bear:blackbear',
|
||||
'animals:mammals:cute:otter',
|
||||
'animals:mammals:cute:cat',
|
||||
'animals:mammals:cute:dog',
|
||||
'animals:insects:butterfly:fly',
|
||||
'animals:insects:butterfly:moth',
|
||||
'animals:monkey',
|
||||
'humans:programmers:andi',
|
||||
'humans:programmers:joe',
|
||||
'humans:programmers:john',
|
||||
'yeti'
|
||||
);
|
||||
foreach($pages as $page) {
|
||||
saveWikiText($page, $page, 'test setup');
|
||||
}
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the plan is sorted into the right order
|
||||
*/
|
||||
function test_sorting() {
|
||||
$plan = new test_helper_plugin_move_plan();
|
||||
|
||||
$plan->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();
|
||||
|
||||
// the plan is sorted FORWARD (first things first)
|
||||
$this->assertEquals(5, count($sorted));
|
||||
$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[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]));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full saved list specified by name
|
||||
*
|
||||
* @param $name
|
||||
* @return array
|
||||
*/
|
||||
function getList($name) {
|
||||
return file($this->files[$name]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* mock class to access the helper_plugin_move_plan::stepThroughDocuments function in tests
|
||||
*/
|
||||
class helper_plugin_move_plan_mock extends helper_plugin_move_plan {
|
||||
|
||||
public $moveLog = array();
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
// Store a msg as it is expected by the plugin
|
||||
msg("Intentional failure in test case.", -1);
|
||||
return false;
|
||||
}
|
||||
$moveOperation = array($src => $dst);
|
||||
array_push($this->movedPages,$moveOperation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test cases for helper_plugin_move_plan::stepThroughDocuments function of the move plugin
|
||||
*
|
||||
* @group plugin_move
|
||||
* @group plugin_move_unittests
|
||||
* @group plugins
|
||||
* @group unittests
|
||||
*/
|
||||
class plugin_move_stepThroughDocuments_test extends DokuWikiTest {
|
||||
|
||||
public function setUp(): void {
|
||||
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]));
|
||||
|
||||
$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');
|
||||
}
|
||||
|
||||
/**
|
||||
* @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]));
|
||||
|
||||
$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');
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
$fail_at_item = 5;
|
||||
$actual_move_Operator = $mock->getMoveOperator();
|
||||
$actual_move_Operator->fail = $fail_at_item;
|
||||
$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]));
|
||||
|
||||
$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');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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");
|
||||
|
||||
$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');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* tests for the template button of the move plugin
|
||||
*
|
||||
* @author Michael Große <grosse@cosmocode.de>
|
||||
* @group plugin_move
|
||||
* @group plugins
|
||||
*/
|
||||
class move_tpl_test extends DokuWikiTest {
|
||||
|
||||
public function setUp(): void {
|
||||
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'));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin AJAX handler to step through a move plan
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// must be run within Dokuwiki
|
||||
if(!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* Class action_plugin_move_progress
|
||||
*/
|
||||
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;
|
||||
global $USERINFO;
|
||||
|
||||
if(!auth_ismanager($_SERVER['REMOTE_USER'], $USERINFO['grps'])) {
|
||||
http_status(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Page Rename Functionality
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// must be run within Dokuwiki
|
||||
if(!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* Class action_plugin_move_rename
|
||||
*/
|
||||
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');
|
||||
|
||||
// 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');
|
||||
$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxMediaManager');
|
||||
}
|
||||
|
||||
/**
|
||||
* set JavaScript info if renaming of current page is possible
|
||||
*/
|
||||
public function handle_init() {
|
||||
global $JSINFO;
|
||||
global $INFO;
|
||||
global $INPUT;
|
||||
global $USERINFO;
|
||||
|
||||
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'),
|
||||
$USERINFO['grps'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a button to the default template
|
||||
*
|
||||
* TODO: DEPRECATED JAN 2018
|
||||
*
|
||||
* @param Doku_Event $event
|
||||
*/
|
||||
public function handle_pagetools(Doku_Event $event) {
|
||||
if($event->data['view'] != 'main') return;
|
||||
if (!$this->getConf('pagetools_integration')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newitem = '<li class="plugin_move_page"><a href=""><span>' . $this->getLang('renamepage') . '</span></a></li>';
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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') ||
|
||||
empty($JSINFO['move_renameokay'])
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if(!$INFO['exists']) {
|
||||
return;
|
||||
}
|
||||
array_splice($event->data['items'], -1, 0, array(new \dokuwiki\plugin\move\MenuItem()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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($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 = $this->getLang('cantrename');
|
||||
}
|
||||
echo $JSON->encode(array('error' => $error));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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'));
|
||||
|
||||
/** @var helper_plugin_move_op $moveOperator */
|
||||
$moveOperator = plugin_load('helper', 'move_op');
|
||||
|
||||
if ($src && $dst) {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$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']) {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $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;
|
||||
|
||||
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 '<a href="" class="plugin_move_page">';
|
||||
echo $this->getLang('renamepage');
|
||||
echo '</a>';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Page Rewrite Functionality
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// 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;
|
||||
|
||||
// only rewrite if not in move already
|
||||
$save = true;
|
||||
if(helper_plugin_move_rewrite::isLocked()) {
|
||||
$save = false;
|
||||
}
|
||||
|
||||
$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->rewritePage($id, $event->result, $save);
|
||||
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) {
|
||||
/** @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Tree Loading Functionality
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// 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();
|
||||
|
||||
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')) {
|
||||
$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')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18,4V3A1,1 0 0,0 17,2H5A1,1 0 0,0 4,3V7A1,1 0 0,0 5,8H17A1,1 0 0,0 18,7V6H19V10H9V21A1,1 0 0,0 10,22H12A1,1 0 0,0 13,21V12H21V4H18Z" /></svg>
|
||||
|
After Width: | Height: | Size: 235 B |
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin : Move
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Michael Hamann <michael@content-space.de>
|
||||
* @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');
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 1011;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this admin plugin is for admins only
|
||||
*
|
||||
* @return bool false
|
||||
*/
|
||||
function forAdminOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the input
|
||||
*/
|
||||
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()) {
|
||||
helper_plugin_move_rewrite::addLock(); //todo: right place?
|
||||
switch($INPUT->str('ctl')) {
|
||||
case 'continue':
|
||||
$this->plan->nextStep();
|
||||
break;
|
||||
case 'skip':
|
||||
$this->plan->nextStep(true);
|
||||
break;
|
||||
case 'abort':
|
||||
$this->plan->abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the interface
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get input variables and create a move plan from them
|
||||
*
|
||||
* @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')) {
|
||||
$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, $dst);
|
||||
$this->plan->addMediaNamespaceMove($src, $dst);
|
||||
} else if($INPUT->str('type') == 'page') {
|
||||
$this->plan->addPageNamespaceMove($src, $dst);
|
||||
} else if($INPUT->str('type') == 'media') {
|
||||
$this->plan->addMediaNamespaceMove($src, $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
|
||||
$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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the simple move form
|
||||
*/
|
||||
protected function GUI_simpleForm() {
|
||||
global $ID;
|
||||
|
||||
echo $this->locale_xhtml('move');
|
||||
|
||||
$treelink = wl($ID, array('do'=>'admin', 'page'=>'move_tree'));
|
||||
echo '<p id="plugin_move__treelink">';
|
||||
printf($this->getLang('treelink'), $treelink);
|
||||
echo '</p>';
|
||||
|
||||
$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($this->getLang('legend'));
|
||||
|
||||
$form->addElement(form_makeRadioField('class', 'page', $this->getLang('movepage') . ' <code>' . $ID . '</code>', '', 'block radio click-page', array('checked' => 'checked')));
|
||||
$form->addElement(form_makeRadioField('class', 'namespace', $this->getLang('movens') . ' <code>' . getNS($ID) . '</code>', '', '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())));
|
||||
$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('btn_start')));
|
||||
$form->endFieldset();
|
||||
$form->printForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the GUI while the move progresses
|
||||
*/
|
||||
protected function GUI_progress() {
|
||||
echo '<div id="plugin_move__progress">';
|
||||
|
||||
echo $this->locale_xhtml('progress');
|
||||
|
||||
$progress = $this->plan->getProgress();
|
||||
|
||||
if(!$this->plan->inProgress()) {
|
||||
echo '<div id="plugin_move__preview">';
|
||||
echo '<p>';
|
||||
echo '<strong>' . $this->getLang('intro') . '</strong> ';
|
||||
echo '<span>' . $this->getLang('preview') . '</span>';
|
||||
echo '</p>';
|
||||
echo $this->plan->previewHTML();
|
||||
echo '</div>';
|
||||
|
||||
}
|
||||
|
||||
echo '<div class="progress" data-progress="' . $progress . '">' . $progress . '%</div>';
|
||||
|
||||
echo '<div class="output">';
|
||||
if($this->plan->getLastError()) {
|
||||
echo '<p><div class="error">' . $this->plan->getLastError() . '</div></p>';
|
||||
} elseif ($this->plan->inProgress()) {
|
||||
echo '<p><div class="info">' . $this->getLang('inexecution') . '</div></p>';
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
// display all buttons but toggle visibility according to state
|
||||
echo '<p></p>';
|
||||
echo '<div class="controls">';
|
||||
echo '<img src="' . DOKU_BASE . 'lib/images/throbber.gif" class="hide" />';
|
||||
$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 '</div>';
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a move workflow button
|
||||
*
|
||||
* continue, start, retry - continue next steps
|
||||
* abort - abort the whole move
|
||||
* skip - skip error and continue
|
||||
*
|
||||
* @param string $control
|
||||
* @param bool $show should this control be visible?
|
||||
*/
|
||||
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';
|
||||
$skip = 0;
|
||||
}
|
||||
|
||||
$class = 'move__control ctlfrm-' . $id;
|
||||
if(!$show) $class .= ' hide';
|
||||
|
||||
$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->addHidden('skip', $skip);
|
||||
$form->addElement(form_makeButton('submit', 'admin', $label, array('class' => 'btn ctl-' . $control)));
|
||||
$form->printForm();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
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 false; // do not show in Admin menu
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this admin plugin is for admins only
|
||||
*
|
||||
* @return bool false
|
||||
*/
|
||||
function forAdminOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* no-op
|
||||
*/
|
||||
public function handle() {
|
||||
}
|
||||
|
||||
public function html() {
|
||||
global $ID;
|
||||
|
||||
echo $this->locale_xhtml('tree');
|
||||
|
||||
echo '<noscript><div class="error">' . $this->getLang('noscript') . '</div></noscript>';
|
||||
|
||||
echo '<div id="plugin_move__tree">';
|
||||
|
||||
echo '<div class="tree_root tree_pages">';
|
||||
echo '<h3>' . $this->getLang('move_pages') . '</h3>';
|
||||
$this->htmlTree(self::TYPE_PAGES);
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="tree_root tree_media">';
|
||||
echo '<h3>' . $this->getLang('move_media') . '</h3>';
|
||||
$this->htmlTree(self::TYPE_MEDIA);
|
||||
echo '</div>';
|
||||
|
||||
/** @var helper_plugin_move_plan $plan */
|
||||
$plan = plugin_load('helper', 'move_plan');
|
||||
echo '<div class="controls">';
|
||||
if($plan->isCommited()) {
|
||||
echo '<div class="error">' . $this->getLang('moveinprogress') . '</div>';
|
||||
} 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_makeCheckboxField('autoskip', '1', $this->getLang('autoskip'), '', '', ($this->getConf('autoskip') ? array('checked' => 'checked') : array())));
|
||||
$form->addElement('<br />');
|
||||
$form->addElement(form_makeCheckboxField('autorewrite', '1', $this->getLang('autorewrite'), '', '', ($this->getConf('autorewrite') ? array('checked' => 'checked') : array())));
|
||||
$form->addElement('<br />');
|
||||
$form->addElement('<br />');
|
||||
$form->addElement(form_makeButton('submit', 'admin', $this->getLang('btn_start')));
|
||||
$form->printForm();
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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')
|
||||
)
|
||||
);
|
||||
echo html_buildlist(
|
||||
$data, 'tree_list idx',
|
||||
array($this, 'html_list'),
|
||||
array($this, 'html_li')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a tree info structure from media or page directories
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $open The hierarchy to open FIXME not supported yet
|
||||
* @param string $base The namespace to start from
|
||||
* @return array
|
||||
*/
|
||||
public function tree($type = self::TYPE_PAGES, $open = '', $base = '') {
|
||||
global $conf;
|
||||
|
||||
$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,
|
||||
'showhidden' => true
|
||||
);
|
||||
|
||||
$data = array();
|
||||
if($type == self::TYPE_PAGES) {
|
||||
search($data, $conf['datadir'], 'search_universal', $opts, $basedir);
|
||||
} elseif($type == self::TYPE_MEDIA) {
|
||||
search($data, $conf['mediadir'], 'search_universal', $opts, $basedir);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item formatter for the tree view
|
||||
*
|
||||
* User function for html_buildlist()
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
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'] = '';
|
||||
|
||||
if ($item['id']) {
|
||||
$ret .= '<input type="checkbox" /> ';
|
||||
}
|
||||
|
||||
// namespace or page?
|
||||
if($item['type'] == 'd') {
|
||||
$ret .= '<a href="' . $item['id'] . '" class="idx_dir">';
|
||||
$ret .= $base;
|
||||
$ret .= '</a>';
|
||||
} else {
|
||||
$ret .= '<a class="wikilink1">';
|
||||
$ret .= noNS($item['id']);
|
||||
$ret .= '</a>';
|
||||
}
|
||||
|
||||
if($item['id']) $ret .= '<img class="rename" src="'. DOKU_BASE .'lib/plugins/move/images/rename.png" />';
|
||||
else $ret .= '<img class="add" src="' . DOKU_BASE . 'lib/plugins/move/images/folder_add.png" />';
|
||||
|
||||
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'] = ' type-' . $item['type'];
|
||||
if($item['type'] == 'd') $params['class'] .= ' ' . ($item['open'] ? 'open' : 'closed');
|
||||
$params['data-name'] = noNS($item['id']);
|
||||
$params['data-id'] = $item['id'];
|
||||
$attr = buildAttributes($params);
|
||||
|
||||
return "<li $attr>";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
$conf['allowrename'] = '@user';
|
||||
$conf['minor'] = 1;
|
||||
$conf['autoskip'] = 0;
|
||||
$conf['autorewrite'] = 1;
|
||||
$conf['pagetools_integration'] = 1;
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
$meta['allowrename'] = array('string');
|
||||
$meta['minor'] = array('onoff');
|
||||
$meta['autoskip'] = array('onoff');
|
||||
$meta['autorewrite'] = array('onoff');
|
||||
$meta['pagetools_integration'] = array('onoff');
|
||||
@@ -0,0 +1,34 @@
|
||||
# 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
|
||||
.travis.yml
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin File Mover
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Michael Hamann <michael@content-space.de>
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Rewriting Handler
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Michael Hamann <michael@content-space.de>
|
||||
*/
|
||||
|
||||
// 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 extends DokuWiki_Plugin {
|
||||
public $calls = '';
|
||||
|
||||
protected $id;
|
||||
protected $ns;
|
||||
protected $origID;
|
||||
protected $origNS;
|
||||
protected $page_moves;
|
||||
protected $media_moves;
|
||||
protected $handlers;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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 init($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function resolveMoves($old, $type) {
|
||||
global $conf;
|
||||
|
||||
if($type != 'media' && $type != 'page') throw new Exception('Not a valid type');
|
||||
|
||||
$old = resolve_id($this->origNS, $old, false);
|
||||
|
||||
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 === '') $old .= $conf['start'];
|
||||
|
||||
$moves = $this->page_moves;
|
||||
} else {
|
||||
$moves = $this->media_moves;
|
||||
}
|
||||
|
||||
$old = cleanID($old);
|
||||
|
||||
foreach($moves as $move) {
|
||||
if($move[0] == $old) {
|
||||
$old = $move[1];
|
||||
}
|
||||
}
|
||||
|
||||
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 string the old, possibly relative ID
|
||||
* @param $new string 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
|
||||
*
|
||||
* 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 $type 'media' or 'page'
|
||||
* @throws Exception on bad argument
|
||||
* @return string
|
||||
*/
|
||||
public function relativeLink($relold, $new, $type) {
|
||||
global $conf;
|
||||
if($type != 'media' && $type != 'page') throw new Exception('Not a valid type');
|
||||
|
||||
// first check if the old link still resolves
|
||||
$exists = false;
|
||||
$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);
|
||||
}
|
||||
if($old == $new) {
|
||||
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] == '.') {
|
||||
$wasrel = true;
|
||||
} else {
|
||||
$wasrel = false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
$ups = max(count($selfpath) - $common, 0);
|
||||
$remainder = array_slice($goalpath, $common);
|
||||
$upper = $ups ? array_fill(0, $ups, '..:') : array();
|
||||
|
||||
// build the new relative path
|
||||
$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;
|
||||
|
||||
// if the old link ended with a colon and the new one is a start page, adjust
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$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 {
|
||||
// all new, keep CamelCase in title
|
||||
$this->calls .= "[[$newID|$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 hash 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->resolveMoves($id, 'page');
|
||||
$new_id = $this->relativeLink($id, $new_id, 'page');
|
||||
|
||||
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->resolveMoves($p['src'], 'media');
|
||||
$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
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Operation Execution
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Michael Hamann <michael@content-space.de>
|
||||
* @author Gary Owen <gary@isection.co.uk>
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// 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 = '↷';
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @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'), $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'), $src), -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Has the document name and/or namespace changed?
|
||||
if($src == $dst) {
|
||||
msg(sprintf($this->getLang('notchanged'), $src), -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the page does not already exist
|
||||
if(page_exists($dst)) {
|
||||
msg(sprintf($this->getLang('exists'), $src, $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'), $src), -1);
|
||||
return false;
|
||||
}
|
||||
if(auth_quickaclcheck($src) < AUTH_DELETE) {
|
||||
msg(sprintf($this->getLang('nomediarights'), $src), -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Has the document name and/or namespace changed?
|
||||
if($src == $dst) {
|
||||
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('mediaexists'), $src, $dst), -1);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a page move/rename
|
||||
*
|
||||
* @param string $src original ID
|
||||
* @param string $dst new ID
|
||||
* @return bool
|
||||
*/
|
||||
public function movePage($src, $dst) {
|
||||
if(!$this->checkPage($src, $dst)) return false;
|
||||
|
||||
// lock rewrites
|
||||
helper_plugin_move_rewrite::addLock();
|
||||
|
||||
/** @var helper_plugin_move_rewrite $Rewriter */
|
||||
$Rewriter = plugin_load('helper', 'move_rewrite');
|
||||
|
||||
// remember what this page was called before the move in meta data
|
||||
$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);
|
||||
$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);
|
||||
$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_PAGE_RENAME', $eventdata);
|
||||
if($event->advise_before()) {
|
||||
lock($src);
|
||||
|
||||
/** @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->renamePage($src, $dst)) !== true
|
||||
|| ($idx_msg = $Indexer->renameMetaValue('relation_references', $src, $dst)) !== true
|
||||
) {
|
||||
msg(sprintf($this->getLang('indexerror'), $idx_msg), -1);
|
||||
return false;
|
||||
}
|
||||
if(!$FileMover->movePageMeta($src_ns, $src_name, $dst_ns, $dst_name)) {
|
||||
msg(sprintf($this->getLang('metamoveerror'), $src), -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare the summary for the changelog entry
|
||||
if($src_ns == $dst_ns) {
|
||||
$lang_key = 'renamed';
|
||||
} 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);
|
||||
|
||||
// Save the updated document in its new location
|
||||
$text = rawWiki($src);
|
||||
saveWikiText($dst, $text, $summary);
|
||||
|
||||
// Delete the orginal file
|
||||
if(@file_exists(wikiFN($dst))) {
|
||||
saveWikiText($src, '', $summary);
|
||||
}
|
||||
|
||||
// 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(sprintf($this->getLang('atticmoveerror'), $src ), -1);
|
||||
}
|
||||
|
||||
// Add meta data to all affected pages, so links get updated later
|
||||
foreach($affected_pages as $id) {
|
||||
$Rewriter->setMoveMeta($id, $src, $dst, 'pages');
|
||||
}
|
||||
|
||||
unlock($src);
|
||||
}
|
||||
$event->advise_after();
|
||||
|
||||
// store this for later use
|
||||
$this->affectedPages = $affected_pages;
|
||||
|
||||
// unlock rewrites
|
||||
helper_plugin_move_rewrite::removeLock();
|
||||
|
||||
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 moveMedia($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');
|
||||
/** @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();
|
||||
if(($idx_msg = $Indexer->renameMetaValue('relation_media', $src, $dst)) !== true) {
|
||||
msg(sprintf($this->getLang('indexerror'), $idx_msg), -1);
|
||||
return false;
|
||||
}
|
||||
if(!$FileMover->moveMediaMeta($src_ns, $src_name, $dst_ns, $dst_name)) {
|
||||
msg(sprintf($this->getLang('mediametamoveerror'), $src), -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare directory
|
||||
io_createNamespace($dst, 'media');
|
||||
|
||||
// move it FIXME this does not create a changelog entry!
|
||||
if(!io_rename(mediaFN($src), mediaFN($dst))) {
|
||||
msg(sprintf($this->getLang('mediamoveerror'), $src), -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(sprintf($this->getLang('mediaatticmoveerror'), $src), -1);
|
||||
}
|
||||
|
||||
// Add meta data to all affected pages, so links get updated later
|
||||
foreach($affected_pages as $id) {
|
||||
$Rewriter->setMoveMeta($id, $src, $dst, 'media');
|
||||
}
|
||||
}
|
||||
$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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,953 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Operation Planner
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Michael Hamann <michael@content-space.de>
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// must be run within Dokuwiki
|
||||
if(!defined('DOKU_INC')) die();
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* 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;
|
||||
|
||||
const TYPE_PAGES = 1;
|
||||
const TYPE_MEDIA = 2;
|
||||
const CLASS_NS = 4;
|
||||
const CLASS_DOC = 8;
|
||||
|
||||
/**
|
||||
* @var array the options for this move plan
|
||||
*/
|
||||
protected $options = array(); // defaults are set in loadOptions()
|
||||
|
||||
/**
|
||||
* @var array holds the location of the different list and state files
|
||||
*/
|
||||
protected $files = array();
|
||||
|
||||
/**
|
||||
* @var array the planned moves
|
||||
*/
|
||||
protected $plan = array();
|
||||
|
||||
/**
|
||||
* @var array temporary holder of document lists
|
||||
*/
|
||||
protected $tmpstore = array(
|
||||
'pages' => array(),
|
||||
'media' => array(),
|
||||
'ns' => array(),
|
||||
'affpg' => array(),
|
||||
'miss' => array(),
|
||||
'miss_media' => array(),
|
||||
);
|
||||
|
||||
/** @var helper_plugin_move_op $MoveOperator */
|
||||
protected $MoveOperator = null;
|
||||
|
||||
/**
|
||||
* 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',
|
||||
'namespaces' => $conf['metadir'] . '/__move_namespaces',
|
||||
'missing' => $conf['metadir'] . '/__move_missing',
|
||||
'missing_media' => $conf['metadir'] . '/__move_missing_media',
|
||||
);
|
||||
|
||||
$this->MoveOperator = plugin_load('helper', 'move_op');
|
||||
|
||||
$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'),
|
||||
|
||||
// errors
|
||||
'lasterror' => false
|
||||
);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'];
|
||||
|
||||
$remain =
|
||||
$this->options['pages_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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is a move in progress currently
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inProgress() {
|
||||
return (bool) $this->options['started'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this plan has been committed, yet
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCommited() {
|
||||
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, self::CLASS_DOC, self::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, self::CLASS_DOC, self::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, self::CLASS_NS, self::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, self::CLASS_NS, self::TYPE_MEDIA);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (self::CLASS_NS|self::CLASS_DOC)
|
||||
* @param int $type (PLUGIN_MOVE_TYPE_PAGE|self::TYPE_MEDIA)
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function addMove($src, $dst, $class = self::CLASS_NS, $type = self::TYPE_PAGES) {
|
||||
if($this->options['committed']) throw new Exception('plan is committed already, can not be added to');
|
||||
|
||||
$src = cleanID($src);
|
||||
$dst = cleanID($dst);
|
||||
|
||||
$this->plan[] = array(
|
||||
'src' => $src,
|
||||
'dst' => $dst,
|
||||
'class' => $class,
|
||||
'type' => $type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
helper_plugin_move_rewrite::removeAllLocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @throws Exception if you try to commit a plan twice
|
||||
* @return bool true if the plan was committed
|
||||
*/
|
||||
public function commit() {
|
||||
global $conf;
|
||||
|
||||
if($this->options['committed']) throw new Exception('plan is committed already, can not be committed 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
|
||||
foreach($this->plan as $move) {
|
||||
if($move['class'] == self::CLASS_DOC) {
|
||||
// these can just be added
|
||||
$this->addToDocumentList($move['src'], $move['dst'], $move['type']);
|
||||
} 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'] == self::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);
|
||||
$this->addToDocumentList($from, $to, $move['type']);
|
||||
}
|
||||
|
||||
// remember the namespace move itself
|
||||
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
|
||||
$this->addToDocumentList($move['src'], $move['dst'], self::CLASS_NS);
|
||||
}
|
||||
$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']);
|
||||
}
|
||||
|
||||
$this->storeDocumentLists();
|
||||
|
||||
if(!$this->options['pages_all'] && !$this->options['media_all']) {
|
||||
msg($this->getLang('noaction'), -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->options['committed'] = true;
|
||||
$this->saveOptions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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['committed']) throw new Exception('plan is not committed yet!');
|
||||
|
||||
// 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();
|
||||
return max($todo, 1); // force one more call
|
||||
}
|
||||
|
||||
if(@filesize($this->files['medialist']) > 1) {
|
||||
$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) {
|
||||
$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();
|
||||
return max($todo, 1); // force one more call
|
||||
}
|
||||
|
||||
helper_plugin_move_rewrite::removeAllLocks();
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// we're done here, clean up
|
||||
$this->abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of page and media moves and the affected pages as a HTML list
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function previewHTML() {
|
||||
$html = '';
|
||||
|
||||
$html .= '<ul>';
|
||||
if(@file_exists($this->files['pagelist'])) {
|
||||
$pagelist = file($this->files['pagelist']);
|
||||
foreach($pagelist as $line) {
|
||||
list($old, $new) = explode("\t", trim($line));
|
||||
|
||||
$html .= '<li class="page"><div class="li">';
|
||||
$html .= hsc($old);
|
||||
$html .= '→';
|
||||
$html .= hsc($new);
|
||||
$html .= '</div></li>';
|
||||
}
|
||||
}
|
||||
if(@file_exists($this->files['medialist'])) {
|
||||
$medialist = file($this->files['medialist']);
|
||||
foreach($medialist as $line) {
|
||||
list($old, $new) = explode("\t", trim($line));
|
||||
|
||||
$html .= '<li class="media"><div class="li">';
|
||||
$html .= hsc($old);
|
||||
$html .= '→';
|
||||
$html .= hsc($new);
|
||||
$html .= '</div></li>';
|
||||
}
|
||||
}
|
||||
if(@file_exists($this->files['affected'])) {
|
||||
$medialist = file($this->files['affected']);
|
||||
foreach($medialist as $page) {
|
||||
$html .= '<li class="affected"><div class="li">';
|
||||
$html .= '↷';
|
||||
$html .= hsc($page);
|
||||
$html .= '</div></li>';
|
||||
}
|
||||
}
|
||||
$html .= '</ul>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Step through the next bunch of pages or media files
|
||||
*
|
||||
* @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 = self::TYPE_PAGES, $skip = false) {
|
||||
|
||||
if($type == self::TYPE_PAGES) {
|
||||
$file = $this->files['pagelist'];
|
||||
$mark = 'P';
|
||||
$call = 'movePage';
|
||||
$items_run_counter = 'pages_run';
|
||||
} else {
|
||||
$file = $this->files['medialist'];
|
||||
$mark = 'M';
|
||||
$call = 'moveMedia';
|
||||
$items_run_counter = 'media_run';
|
||||
}
|
||||
|
||||
$doclist = fopen($file, 'a+');
|
||||
|
||||
for($i = 0; $i < helper_plugin_move_plan::OPS_PER_RUN; $i++) {
|
||||
$log = "";
|
||||
$line = $this->getLastLine($doclist);
|
||||
if($line === false) {
|
||||
break;
|
||||
}
|
||||
list($src, $dst) = explode("\t", trim($line));
|
||||
|
||||
// should this item be skipped?
|
||||
if($skip === true) {
|
||||
$skip = false;
|
||||
} else {
|
||||
// move the page
|
||||
if(!$this->MoveOperator->$call($src, $dst)) {
|
||||
$log .= $this->build_log_line($mark, $src, $dst, false); // FAILURE!
|
||||
|
||||
// automatically skip this item only if wanted...
|
||||
if(!$this->options['autoskip']) {
|
||||
// ...otherwise abort the operation
|
||||
fclose($doclist);
|
||||
$return_items_run = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$log .= $this->build_log_line($mark, $src, $dst, true); // SUCCESS!
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This adjusts counters and truncates the document list correctly
|
||||
* It is used to finalize a successful or skipped move
|
||||
*/
|
||||
|
||||
ftruncate($doclist, ftell($doclist));
|
||||
$this->options[$items_run_counter]--;
|
||||
$return_items_run = $this->options[$items_run_counter];
|
||||
$this->write_log($log);
|
||||
$this->saveOptions();
|
||||
}
|
||||
|
||||
if ($return_items_run !== false) {
|
||||
fclose($doclist);
|
||||
}
|
||||
return $return_items_run;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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');
|
||||
|
||||
// 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->rewritePage($page);
|
||||
|
||||
// update the list file
|
||||
ftruncate($doclist, ftell($doclist));
|
||||
$this->options['affpg_run']--;
|
||||
$this->saveOptions();
|
||||
}
|
||||
|
||||
fclose($doclist);
|
||||
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.
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return int always 0
|
||||
* @throws Exception
|
||||
*/
|
||||
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();
|
||||
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;
|
||||
list($src, $dst) = explode("\t", $line);
|
||||
$miss[$src] = $dst;
|
||||
}
|
||||
|
||||
$affected = file($this->files['affected']);
|
||||
foreach($affected as $page){
|
||||
$page = trim($page);
|
||||
|
||||
if ($type == self::TYPE_PAGES) {
|
||||
$Rewriter->setMoveMetas($page, $miss, 'pages');
|
||||
} else {
|
||||
$Rewriter->setMoveMetas($page, $miss, 'media');
|
||||
}
|
||||
}
|
||||
|
||||
unlink($missing_fn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Step through all the namespace moves
|
||||
*
|
||||
* 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?
|
||||
* @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 */
|
||||
$FileMover = plugin_load('helper', 'move_file');
|
||||
|
||||
$lines = io_readFile($this->files['namespaces']);
|
||||
$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);
|
||||
}
|
||||
|
||||
@unlink($this->files['namespaces']);
|
||||
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
|
||||
*
|
||||
* 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
|
||||
* @param int $type
|
||||
* @throws Exception
|
||||
*/
|
||||
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(!isset($this->tmpstore[$store][$src])) {
|
||||
$this->tmpstore[$store][$src] = $dst;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 source namespace
|
||||
* @param string $dst destination namespace
|
||||
* @param int $class
|
||||
* @param int $type
|
||||
*/
|
||||
protected function findAffectedPages($src, $dst, $class, $type) {
|
||||
$idx = idx_get_indexer();
|
||||
|
||||
if($class == self::CLASS_NS) {
|
||||
$src_ = "$src:*"; // use wildcard lookup for namespaces
|
||||
} else {
|
||||
$src_ = $src;
|
||||
}
|
||||
|
||||
$pages = array();
|
||||
if($type == self::TYPE_PAGES) {
|
||||
$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_);
|
||||
}
|
||||
|
||||
$this->addToAffectedPagesList($pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find missing pages in the $src namespace
|
||||
*
|
||||
* @param string $src source namespace
|
||||
* @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) {
|
||||
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($referenceidx as $idx => $page) {
|
||||
if(substr($page, 0, $len) != "$src") continue;
|
||||
|
||||
// remember missing pages
|
||||
if ($type == self::TYPE_PAGES) {
|
||||
if(!page_exists($page)) {
|
||||
$newpage = $dst . substr($page, $len);
|
||||
$this->tmpstore['miss'][$page] = $newpage;
|
||||
}
|
||||
} else {
|
||||
if(!file_exists(mediaFN($page))){
|
||||
$newpage = $dst . substr($page, $len);
|
||||
$this->tmpstore['miss_media'][$page] = $newpage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the aggregated document lists in the file system and reset the internal storage
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function storeDocumentLists() {
|
||||
$lists = array(
|
||||
'pages' => $this->files['pagelist'],
|
||||
'media' => $this->files['medialist'],
|
||||
'ns' => $this->files['namespaces'],
|
||||
'affpg' => $this->files['affected'],
|
||||
'miss' => $this->files['missing'],
|
||||
'miss_media' => $this->files['missing_media'],
|
||||
);
|
||||
|
||||
foreach($lists as $store => $file) {
|
||||
// anything to do?
|
||||
$count = count($this->tmpstore[$store]);
|
||||
if(!$count) continue;
|
||||
|
||||
// prepare and save content
|
||||
$data = '';
|
||||
$this->tmpstore[$store] = array_reverse($this->tmpstore[$store]); // store in reverse order
|
||||
foreach($this->tmpstore[$store] as $src => $dst) {
|
||||
if($dst === true) {
|
||||
$data .= "$src\n"; // for affected pages only one ID is saved
|
||||
} else {
|
||||
$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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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") {
|
||||
if($line === '') {
|
||||
continue; // this line was empty, continue
|
||||
} else {
|
||||
break; // we have a line, finish
|
||||
}
|
||||
}
|
||||
|
||||
$line = $c . $line; // prepend char to line
|
||||
}
|
||||
|
||||
if($line === '') return false; // beginning of file reached and no content
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for usort to sort the move plan
|
||||
*
|
||||
* @param $a
|
||||
* @param $b
|
||||
* @return int
|
||||
*/
|
||||
public function planSorter($a, $b) {
|
||||
// do page moves before namespace moves
|
||||
if($a['class'] == self::CLASS_DOC && $b['class'] == self::CLASS_NS) {
|
||||
return -1;
|
||||
}
|
||||
if($a['class'] == self::CLASS_NS && $b['class'] == self::CLASS_DOC) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// do pages before media
|
||||
if($a['type'] == self::TYPE_PAGES && $b['type'] == self::TYPE_MEDIA) {
|
||||
return -1;
|
||||
}
|
||||
if($a['type'] == self::TYPE_MEDIA && $b['type'] == self::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($b['src'], ':');
|
||||
|
||||
if($alen > $blen) {
|
||||
return -1;
|
||||
} elseif($alen < $blen) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 <gohr@cosmocode.de>
|
||||
* @author Michael Große <grosse@cosmocode.de>
|
||||
*/
|
||||
public function build_log_line ($type, $from, $to, $success) {
|
||||
global $MSG;
|
||||
|
||||
$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";
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* Move Plugin Page Rewriter
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Michael Hamann <michael@content-space.de>
|
||||
* @author Gary Owen <gary@isection.co.uk>
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*/
|
||||
// must be run within Dokuwiki
|
||||
if(!defined('DOKU_INC')) die();
|
||||
|
||||
// load required handler class
|
||||
require_once(dirname(__FILE__) . '/handler.php');
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Under what key is move data to be saved in metadata
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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);
|
||||
|
||||
/* 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]);
|
||||
} else {
|
||||
$all_meta[self::METAKEY] = $all_meta['plugin_pagemove'];
|
||||
}
|
||||
p_set_metadata($id, array(self::METAKEY => $all_meta[self::METAKEY], 'plugin_pagemove' => null), false, true);
|
||||
}
|
||||
*/
|
||||
|
||||
// discard missing or empty array or string
|
||||
$meta = !empty($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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$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);
|
||||
foreach($moves as $src => $dst) {
|
||||
$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['origin']) && $meta['origin'] !== '') {
|
||||
return;
|
||||
}
|
||||
$meta['origin'] = $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;
|
||||
global $conf;
|
||||
$lockfile = $conf['lockdir'] . self::LOCKFILENAME;
|
||||
return ((isset($PLUGIN_MOVE_WORKING) && $PLUGIN_MOVE_WORKING > 0) || file_exists($lockfile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not allow any rewrites in this process right now
|
||||
*/
|
||||
public static function addLock() {
|
||||
global $PLUGIN_MOVE_WORKING;
|
||||
global $conf;
|
||||
$PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING + 1 : 1;
|
||||
$lockfile = $conf['lockdir'] . self::LOCKFILENAME;
|
||||
if (!file_exists($lockfile)) {
|
||||
io_savefile($lockfile, "1\n");
|
||||
} else {
|
||||
$stack = intval(file_get_contents($lockfile));
|
||||
++$stack;
|
||||
io_savefile($lockfile, strval($stack));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow rerites in this process again, unless some other lock exists
|
||||
*/
|
||||
public static function removeLock() {
|
||||
global $PLUGIN_MOVE_WORKING;
|
||||
global $conf;
|
||||
$PLUGIN_MOVE_WORKING = $PLUGIN_MOVE_WORKING ? $PLUGIN_MOVE_WORKING - 1 : 0;
|
||||
$lockfile = $conf['lockdir'] . self::LOCKFILENAME;
|
||||
if (!file_exists($lockfile)) {
|
||||
throw new Exception("removeLock failed: lockfile missing");
|
||||
} else {
|
||||
$stack = intval(file_get_contents($lockfile));
|
||||
if($stack === 1) {
|
||||
unlink($lockfile);
|
||||
} else {
|
||||
--$stack;
|
||||
io_savefile($lockfile, strval($stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow rewrites in this process again.
|
||||
*
|
||||
* @author Michael Große <grosse@cosmocode.de>
|
||||
*/
|
||||
public static function removeAllLocks() {
|
||||
global $conf;
|
||||
$lockfile = $conf['lockdir'] . self::LOCKFILENAME;
|
||||
if (file_exists($lockfile)) {
|
||||
unlink($lockfile);
|
||||
}
|
||||
unset($GLOBALS['PLUGIN_MOVE_WORKING']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewrite a text in order to fix the content after the given 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($id, $text) {
|
||||
$meta = $this->getMoveMeta($id);
|
||||
|
||||
$handlers = array();
|
||||
$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:
|
||||
*
|
||||
* 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
|
||||
* which is an instance of helper_plugin_move_handle
|
||||
*/
|
||||
trigger_event('PLUGIN_MOVE_HANDLERS_REGISTER', $data);
|
||||
|
||||
$modes = p_get_parsermodes();
|
||||
|
||||
// Create the parser
|
||||
$Parser = new Doku_Parser();
|
||||
|
||||
// Add the Handler
|
||||
/** @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) {
|
||||
$Parser->addMode($mode['mode'], $mode['obj']);
|
||||
}
|
||||
|
||||
return $Parser->parse($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 rewritePage($id, $text = null, $save = true) {
|
||||
$meta = $this->getMoveMeta($id);
|
||||
if(is_null($text)) {
|
||||
$text = rawWiki($id);
|
||||
}
|
||||
|
||||
if($meta['pages'] || $meta['media']) {
|
||||
$old_text = $text;
|
||||
$text = $this->rewrite($id, $text);
|
||||
|
||||
$changed = ($old_text != $text);
|
||||
$file = wikiFN($id, '', false);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 620 B |
|
After Width: | Height: | Size: 668 B |
|
After Width: | Height: | Size: 635 B |
|
After Width: | Height: | Size: 830 B |
|
After Width: | Height: | Size: 231 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18,4V3A1,1 0 0,0 17,2H5A1,1 0 0,0 4,3V7A1,1 0 0,0 5,8H17A1,1 0 0,0 18,7V6H19V10H9V21A1,1 0 0,0 10,22H12A1,1 0 0,0 13,21V12H21V4H18Z" /></svg>
|
||||
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 343 B |
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author aljailane <shop@souqye.com>
|
||||
*/
|
||||
$lang['menu'] = 'نقل الصفحات ومساحات الأسماء';
|
||||
$lang['inprogress'] = '(التحرك معلق)';
|
||||
$lang['treelink'] = 'بدلاً من هذا النموذج البسيط ، يمكنك إدارة إعادة الهيكلة المعقدة لموقع wiki الخاص بك باستخدام <a href="%s"> مدير النقل المستند إلى الشجرة </a>. ';
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Robert Surý <rsurycz@seznam.cz>
|
||||
* @author Tomáš Borland Valenta
|
||||
* @author Pavel Kochman
|
||||
*/
|
||||
$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í <a href="%s">stromového manažeru přesunu</a>.';
|
||||
$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']['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';
|
||||
$lang['moveinprogress'] = 'Právě probíhá jiný přsun, proto nyní nemůžete použít tento nástroj.';
|
||||
@@ -0,0 +1,10 @@
|
||||
====== Move ======
|
||||
|
||||
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.
|
||||
* 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.
|
||||
|
||||
Všechny odkazy na a ze stránky budou upraveny podle nového umístění stránky.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Probíhá přesun... ======
|
||||
|
||||
Prosím nezavírejte tuto stránku, dokud přesun neskončí.
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Robert Surý <rsurycz@seznam.cz>
|
||||
* @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';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Move Manager =====
|
||||
|
||||
Tento interface umožňuje přeorganizovat vaše wiki namespace, stránky a média pomocí Drag'n'Drop.
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Jacob Palm <jacobpalmdk@icloud.com>
|
||||
*/
|
||||
$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 <a href="%s">flytningshåndtering</a>.';
|
||||
$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.';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,3 @@
|
||||
===== Flytning i gang... =====
|
||||
|
||||
Hold venligst denne side åben mens flytningen behandles.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Jacob Palm <jacobpalmdk@icloud.com>
|
||||
*/
|
||||
$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';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author F. Mueller-Donath <j.felix@mueller-donath.de>
|
||||
*/
|
||||
$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 <a href="%s">baumbasierten Move-Manager</a> 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['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.';
|
||||
$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['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';
|
||||
$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.';
|
||||
|
||||
// Media Manager
|
||||
$lang['js']['moveButton'] = 'Datei verschieben / umbenennen';
|
||||
$lang['js']['dialogIntro'] = 'Neuer Dateiname. Du kannst den Namensraum ändern, aber nicht die Dateierweiterung.';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Verschiebung läuft... ======
|
||||
|
||||
Bitte lassen Sie diese Seite geöffnet, während die Verschiebung läuft.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author F. Mueller-Donath <j.felix@mueller-donath.de>
|
||||
*/
|
||||
$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.';
|
||||
$lang['pagetools_integration'] = 'Umbenennen-Button zu Pagetools hinzufügen';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Move-Manager =====
|
||||
|
||||
Diese Ansicht ermöglicht die Restrukturierung von Namensräumen, Seiten und Mediendateien des Wikis per Drag'n'Drop.
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author picsar
|
||||
* @author e-dschungel <github@e-dschungel.de>
|
||||
* @author F. Mueller-Donath <j.felix@mueller-donath.de>
|
||||
*/
|
||||
$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 <a href="%s">baumbasierten Move-Manager</a> 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['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.';
|
||||
$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';
|
||||
$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 - 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 Namensraum';
|
||||
$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 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';
|
||||
$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, Sie können dieses Tool gerade nicht benutzen.';
|
||||
|
||||
// Media Manager
|
||||
$lang['js']['moveButton'] = 'Datei verschieben / umbenennen';
|
||||
$lang['js']['dialogIntro'] = 'Neuer Dateiname. Sie können den Namensraum ändern, aber nicht die Dateierweiterung.';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Verschiebung läuft... ======
|
||||
|
||||
Bitte lassen Sie diese Seite geöffnet, während die Verschiebung läuft.
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author F. Mueller-Donath <j.felix@mueller-donath.de>
|
||||
* @author e-dschungel <github@e-dschungel.de>
|
||||
*/
|
||||
$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.';
|
||||
$lang['pagetools_integration'] = 'Umbenennen-Button zu Pagetools hinzufügen';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Move-Manager =====
|
||||
|
||||
Diese Ansicht ermöglicht die Restrukturierung von Namensräumen, Seiten und Mediendateien des Wikis per Drag'n'Drop.
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Katerina Katapodi <katerinakatapodi@gmail.com>
|
||||
*/
|
||||
$lang['menu'] = 'Μετακινείστε σελίδες και κενά ονομάτων';
|
||||
$lang['inprogress'] = '(μετακίνηση εκκρεμοτήτων)';
|
||||
$lang['treelink'] = 'Κατ\'εναλλαγή προς αυτή την απλή φόρμα μπορείτε να ανοικοδομήστε το σύμπλεγμα wiki σας χρησιμοποιώντας <href=\'\'%s> tree-based move manager </a>';
|
||||
$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 απέτυχε';
|
||||
$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['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'] = 'Υπάρχει μια άλλη διαδικασία μετακίνησης σε εξέλιξη τώρα, δεν μπορείτε να χρησιμοποιήστε αυτό το εργαλείο.';
|
||||
@@ -0,0 +1,9 @@
|
||||
====== Μετακίνηση ======
|
||||
|
||||
Αυτό το επιπρόσθετο σας επιτρέπει να μετακινήσετε και/ή μετονομάστε την παρούσα σελίδα ή μετακινήστε και/ή μετονομάστε τον τρέχοντα χώρο ονόματος στα πλαίσια των ακόλουθων περιορισμών:
|
||||
|
||||
* Πρέπει να έχετε άδεια έκδοσης για αυτήν την σελίδα/όλες τις σελίδες στο παρόντα κενό χώρο.
|
||||
* Οι σελίδες που μετακινούνται δεν πρέπει να είναι κλειδωμένες για έκδοση.
|
||||
* Για να μετακινήσετε μια σελίδα πρέπει επίσης να δημιουργήσετε 'άδεια' στον κενό χώρο ονομασίας.
|
||||
* Δεν μπορείτε να μετακινήσετε μια σελίδα σε χώρο ονόματος όπου υπάρχει μια σελίδα με το ίδιο όνομα.
|
||||
Όλες οι ιστοσελίδες από και προς τις σελίδες που μετακινούνται θα ενημερωθούν για να απεικονίσουν το νέο μέρος και/ή όνομα.
|
||||
@@ -0,0 +1,2 @@
|
||||
====== Μετακίνηση σε Εξέλιξη... ======
|
||||
Παρακαλώ κρατήστε αυτήν την σελίδα ανοικτή κατά την διάρκεια της διαδικασίας εξέλιξης.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Katerina Katapodi <katerinakatapodi@gmail.com>
|
||||
*/
|
||||
$lang['allowrename'] = 'Συμβάλλετε στην μετονομασία σελίδων σε αυτές τις ομάδες και χρήστες (χωρισμός με κόμμα).';
|
||||
$lang['minor'] = 'Θέλετε να σημειώσετε τις ρυθμίσεις των ιστοσελίδων ως ελάσσονες? Οι ελάσσονες αλλαγές δεν θα συμπεριληφθούν στην λίστα των τροφοδοτήσεων RSS και στις εγγραφές με email.';
|
||||
$lang['autoskip'] = 'Ενεργοποιείστε την αυτόματη παράλειψη λαθών σε αρχεία που μετακινείτε κατ\'επιλογήν.';
|
||||
$lang['autorewrite'] = 'Ενεργοποιείστε το σύνδεσμο αυτόματης επανεγγραφής μετά τις μετακινήσεις αρχείων κατ\'επιλογήν.';
|
||||
$lang['pagetools_integration'] = 'Προσθέσετε το πλήκτρο μετονομασίας στα εργαλεία σελίδων.';
|
||||
@@ -0,0 +1,2 @@
|
||||
====== Βασική Μετακίνηση =====
|
||||
Αυτή η προβολή σας επιτρέπει να ρυθμίσετε εκ νέου τις ονομασίες αρχείων Wiki, φακέλλους σελίδων και μέσων ενημέρωσης μέσω του Drag'n Drop.
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* english language file
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
* @author Gary Owen <>
|
||||
*/
|
||||
|
||||
$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 <a href="%s">tree-based move manager</a>.';
|
||||
|
||||
// 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.';
|
||||
|
||||
// media errors
|
||||
$lang['medianotexist'] = 'The media file %s does not exist';
|
||||
$lang['nomediarights'] = 'You have insufficient permissions to delete %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['extensionchange'] = 'Extension of the new file is not the same as the original.';
|
||||
|
||||
// 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';
|
||||
$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['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';
|
||||
$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 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';
|
||||
$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';
|
||||
$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:';
|
||||
$lang['js']['inprogress'] = 'renaming page and adjusting links...';
|
||||
$lang['js']['complete'] = 'Move operation finished.';
|
||||
|
||||
// Tree Manager
|
||||
$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';
|
||||
$lang['js']['add'] = 'Create a new namespace';
|
||||
$lang['js']['duplicate'] = 'Sorry, "%s" already exists in this namespace.';
|
||||
|
||||
// Media Manager
|
||||
$lang['js']['moveButton'] = 'Move file';
|
||||
$lang['js']['dialogIntro'] = 'Enter new file destination. You may change the namespace but not the file extension.';
|
||||
@@ -0,0 +1,10 @@
|
||||
====== 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:
|
||||
|
||||
* 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 pages that are moved will be updated to reflect the new location and/or name.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Move in Progress... ======
|
||||
|
||||
Please keep this page open while the move progresses.
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
$lang['allowrename'] = 'Allow renaming of pages and media 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.';
|
||||
$lang['pagetools_integration'] = 'Add renaming button to pagetools';
|
||||
@@ -0,0 +1,7 @@
|
||||
====== Move Manager =====
|
||||
|
||||
This interface allows you to rearrange your wiki's namespaces, pages and media files via Drag'n'Drop.
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Gary Owen
|
||||
* @author Domingo Redal <docxml@gmail.com>
|
||||
*/
|
||||
$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 <a href="%s">administrador para mover páginas basado en listas desplegables</a>.';
|
||||
$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.';
|
||||
@@ -0,0 +1,10 @@
|
||||
====== Mover ======
|
||||
|
||||
Esta extensión le permite mover y/o renombrar el documento actual respetando las siguientes restricciones.
|
||||
|
||||
* 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.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Mover en progreso... ======
|
||||
|
||||
Por favor, mantenga esta página abierta mientras progresa la operación de mover.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Domingo Redal <docxml@gmail.com>
|
||||
*/
|
||||
$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';
|
||||
@@ -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).
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Schplurtz le Déboulonné <schplurtz@laposte.net>
|
||||
* @author Gary Owen
|
||||
* @author Nicolas Friedli <nicolas@theologique.ch>
|
||||
*/
|
||||
$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 <a href="%s">gestionnaire de déplacements par arborescence</a>';
|
||||
$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é).';
|
||||
$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['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.';
|
||||
$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é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.';
|
||||
$lang['btn_start'] = 'Commencer';
|
||||
$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['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['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:';
|
||||
$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['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.';
|
||||
@@ -0,0 +1,10 @@
|
||||
====== Move ======
|
||||
|
||||
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/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.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Déplacements en cours... ======
|
||||
|
||||
Veuillez garder cette page ouverte pendant toute la durée du déplacement.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
|
||||
*/
|
||||
$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';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Gestionnaire déplacement =====
|
||||
|
||||
Cette interface vous permet de réorganiser catégories, pages et médias de votre wiki par glisser-déposer.
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Davor Turkalj <turki.bsc@gmail.com>
|
||||
*/
|
||||
$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 <a href="%s">vizualnog upravitelja pomicanja</a>';
|
||||
$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']['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';
|
||||
$lang['moveinprogress'] = 'Trenutno je druga operacija premještanja u tijeku, zasada ne možete koristiti ovaj alat.';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Premještanje u tijeku... ======
|
||||
|
||||
Molimo držite ovu stranicu otvorenom dok traje premještanje.
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Davor Turkalj <turki.bsc@gmail.com>
|
||||
*/
|
||||
$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.
|
||||
';
|
||||
$lang['pagetools_integration'] = 'Dodaj tipku za preimenovanje na alate stranice';
|
||||
@@ -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.
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author NawanP <saya@nawan.my.id>
|
||||
*/
|
||||
$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.';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== Pemindahan dalam proses... ======
|
||||
|
||||
Mohon tetap di halaman ini saat pemindahan sedang diproses.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author NawanP <saya@nawan.my.id>
|
||||
*/
|
||||
$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';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* italian language file
|
||||
*
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author damiano <damiano@spagnuolo.eu>
|
||||
* @author Dario Sguassero
|
||||
*/
|
||||
$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 <a href="%s">tree-based gestore di movimento basato su albero </a>.';
|
||||
$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]';
|
||||
@@ -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.
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Hideaki SAWADA <chuno@live.jp>
|
||||
*/
|
||||
$lang['menu'] = 'ページ・名前空間の移動';
|
||||
$lang['inprogress'] = '(移動保留中)';
|
||||
$lang['treelink'] = 'この簡単なフォームの代わりに、<a href="%s">ツリー型の移動管理</a>を利用して 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']['add'] = '新しい名前空間の作成';
|
||||
$lang['js']['duplicate'] = '"%s" はこの名前空間内に既に存在します。';
|
||||
$lang['root'] = '[ルート名前空間]';
|
||||
$lang['noscript'] = 'この機能には JavaScriptが必要です。';
|
||||
$lang['moveinprogress'] = '別の移動操作を処理中なので、今はこのツールを使用できません。';
|
||||
@@ -0,0 +1,10 @@
|
||||
====== 移動 ======
|
||||
|
||||
このプラグインは、以下の制約の範囲内で、今いるページの移動・名称変更、今いる名前空間の移動・名称変更が可能です:
|
||||
|
||||
* 今いるページ/今いる名前空間内の全ページに対する編集権限があること
|
||||
* 移動するページが編集ロックされていないこと
|
||||
* ページ移動のために、移動先の名前空間に対する作成権限があること
|
||||
* 移動先の名前空間内に同じ名前のページが存在しないこと
|
||||
|
||||
移動したページとの間の全てのリンクは、新しい場所・新しい名前を反映して更新されます。
|
||||
@@ -0,0 +1,3 @@
|
||||
====== 移動処理中・・・ ======
|
||||
|
||||
移動処理中は、このページを閉じないで下さい。
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Hideaki SAWADA <chuno@live.jp>
|
||||
*/
|
||||
$lang['allowrename'] = 'ページ名変更を許可するグループ・ユーザー(カンマ区切り)';
|
||||
$lang['minor'] = 'リンクの書き換えを小変更扱いにする。小変更にすると RSS 配信・メール更新通知には表示されない。';
|
||||
$lang['autoskip'] = '名前空間移動時のエラーの自動スキップ。デフォルトは有効。';
|
||||
$lang['autorewrite'] = '名前空間移動後のリンクの自動書き換え。デフォルトは有効。';
|
||||
$lang['pagetools_integration'] = '名称変更ボタンのページツールへの追加';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== 移動管理 =====
|
||||
|
||||
この画面では、Wiki 内の名前空間・ページ・メディアファイルをドラッグ&ドロップで再配置することができます。
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Gary Owen
|
||||
* @author Myeongjin <aranet100@gmail.com>
|
||||
* @author Jaemin Kim <cooremna@gmail.com>
|
||||
*/
|
||||
$lang['menu'] = '문서와 이름공간 이동';
|
||||
$lang['inprogress'] = '(이동 보류 중)';
|
||||
$lang['treelink'] = '다른 방법으로 이 간단한 양식은 <a href="%s">트리 기반의 이동 관리자</a>를 사용하여 위키의 복잡한 구조 조정을 관리할 수 있습니다.';
|
||||
$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'] = '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'] = '이 기능은 자바스크립트가 필요합니다';
|
||||
$lang['moveinprogress'] = '현재 진행 중인 다른 이동 작업이 있으므로, 지금 바로 이 도구를 사용할 수 없습니다.';
|
||||
@@ -0,0 +1,10 @@
|
||||
====== 이동 ======
|
||||
|
||||
이 플러그인은 다음 제한 안에서 현재 문서를 이동하고/거나 이름을 바꾸거나 현재 이름공간을 이동하고/거나 이름을 바꿀 수 있습니다:
|
||||
|
||||
* 현재 이름공간에서 현재 문서/모든 문서에 대한 편집 권한이 있어야 합니다.
|
||||
* 이동되는 문서는 편집을 위해 잠겨 있지 않아야 합니다.
|
||||
* 문서 이동을 위해서는 대상 이름공간에서 만들기 권한도 필요합니다.
|
||||
* 같은 이름으로 된 문서가 이미 존재하는 이름공간으로 문서를 이동할 수 없습니다.
|
||||
|
||||
기존에서 새로 이동하는 문서의 모든 링크는 새 위치와/나 이름을 반영하도록 바뀝니다.
|
||||
@@ -0,0 +1,3 @@
|
||||
====== 진행 중인 이동... ======
|
||||
|
||||
이동을 진행하는 동안 이 문서를 열어두시기 바랍니다.
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||
*
|
||||
* @author Myeongjin <aranet100@gmail.com>
|
||||
* @author Jaemin Kim <cooremna@gmail.com>
|
||||
*/
|
||||
$lang['allowrename'] = '문서의 이름을 바꿀 수 있는 그룹 및 사용자. (쉼표로 구분)';
|
||||
$lang['minor'] = '링크 조절을 사소한 바뀜으로 표시하겠습니까? 사소한 바뀜은 RSS 피드와 구독 메일에 나열되지 않을 것입니다.';
|
||||
$lang['autoskip'] = '기본적으로 이름공간 이동에서 오류를 자동으로 건너뛰도록 활성화합니다.';
|
||||
$lang['autorewrite'] = '기본적으로 이름공간을 이동하고 나서 자동으로 링크 다시 쓰기를 활성화합니다.';
|
||||
$lang['pagetools_integration'] = '페이지도구에 이름 새로짓기 버튼 추가하기';
|
||||
@@ -0,0 +1,3 @@
|
||||
====== 이동 관리자 =====
|
||||
|
||||
이 인터페이스는 드래그 앤 드롭을 통해 위키의 이름공간, 문서와 미디어 파일을 재배열할 수 있습니다.
|
||||