はじまりの大地

This commit is contained in:
miteruzo
2024-07-08 03:32:47 +09:00
commit c616a96f53
7749 changed files with 478270 additions and 0 deletions
+339
View File
@@ -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.
+60
View File
@@ -0,0 +1,60 @@
<?php
/**
* Bureaucracy Plugin: Allows flexible creation of forms
*
* This plugin allows definition of forms in wiki pages. The forms can be
* submitted via email or used to create new pages from templates.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Andreas Gohr <andi@splitbrain.org>
* @author Adrian Lang <dokuwiki@cosmocode.de>
*/
// must be run within Dokuwiki
if (!defined('DOKU_INC')) die();
/**
* Class action_plugin_bureaucracy
*/
class action_plugin_bureaucracy extends DokuWiki_Action_Plugin {
/**
* Registers a callback function for a given event
*/
public function register(Doku_Event_Handler $controller) {
$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'ajax');
}
/**
* @param Doku_Event$event
* @param $param
*/
public function ajax(Doku_Event $event, $param) {
if ($event->data !== 'bureaucracy_user_field') {
return;
}
$event->stopPropagation();
$event->preventDefault();
$search = $_REQUEST['search'];
/** @var DokuWiki_Auth_Plugin $auth */
global $auth;
$users = array();
foreach($auth->retrieveUsers() as $username => $data) {
if ($search === '' || // No search
stripos($username, $search) === 0 || // Username (prefix)
stripos($data['name'], $search) !== false) { // Full name
$users[$username] = $data['name'];
}
if (count($users) === 10) {
break;
}
}
if (count($users) === 1 && key($users) === $search) {
$users = array();
}
echo json_encode($users);
}
}
+4
View File
@@ -0,0 +1,4 @@
<?php
$conf['runas'] = '';
$conf['maxEmailAttachmentSize'] = 3*1024*1024; //3MB
@@ -0,0 +1,5 @@
<?php
$meta['runas'] = array('string');
$meta['maxEmailAttachmentSize'] = array('numeric');
+136
View File
@@ -0,0 +1,136 @@
<?php
/**
* Base class for bureaucracy actions.
*
* All bureaucracy actions have to inherit from this class.
*
* ATM this class is pretty empty but, in the future it could be used to add
* helper functions which can be utilized by the different actions.
*
* @author Michael Klier <chi@chimeric.de>
*/
class helper_plugin_bureaucracy_action extends syntax_plugin_bureaucracy {
/**
* Return false to prevent DokuWiki reusing instances of the plugin
*
* @return bool
*/
public function isSingleton() {
return false;
}
/**
* Handle the user input [required]
*
* This function needs to be implemented to accept the user data collected
* from the form. Data has to be grabbed from $_POST['bureaucracy'] using
* the indicies in the 'idx' members of the $data items.
*
* @param helper_plugin_bureaucracy_field[] $fields the list of fields in the form
* @param string $thanks the thank you message as defined in the form
* or default one. Might be modified by the action
* before returned
* @param array $argv additional arguments passed to the action
* @return bool|string false on error, $thanks on success
*/
public function run($fields, $thanks, $argv){
msg('ERROR: called action %s did not implement a run() function');
return false;
}
/**
* Adds some language related replacement patterns
*/
function prepareLanguagePlaceholder() {
global $ID;
global $conf;
$this->patterns['__lang__'] = '/@LANG@/';
$this->values['__lang__'] = $conf['lang'];
$this->patterns['__trans__'] = '/@TRANS@/';
$this->values['__trans__'] = '';
/** @var helper_plugin_translation $trans */
$trans = plugin_load('helper', 'translation');
if (!$trans) return;
$this->values['__trans__'] = $trans->getLangPart($ID);
$this->values['__lang__'] = $trans->realLC('');
}
/**
* Adds replacement pattern for fieldlabels (e.g @@Label@@)
*
* @param helper_plugin_bureaucracy_field $field
*/
function prepareFieldReplacement($field) {
$label = $field->getParam('label');
if(!is_null($label)) {
$this->patterns[$label] = $field->getReplacementPattern();
$this->values[$label] = $field->getReplacementValue();
}
}
/**
* Adds <noinclude></noinclude> to replacement patterns
*/
function prepareNoincludeReplacement() {
$this->patterns['__noinclude__'] = '/<noinclude>(.*?)<\/noinclude>/is';
$this->values['__noinclude__'] = '';
}
/**
* Generate field replacements
*
* @param helper_plugin_bureaucracy_field[] $fields List of field objects
* @return array
*/
function prepareFieldReplacements($fields) {
foreach ($fields as $field) {
//field replacements
$this->prepareFieldReplacement($field);
}
}
/**
* Returns ACL access level of the user or the (virtual) 'runas' user
*
* @param string $id pageid
* @return int
*/
protected function aclcheck($id) {
$runas = $this->getConf('runas');
if($runas) {
$auth = auth_aclcheck($id, $runas, array());
} else {
$auth = auth_quickaclcheck($id);
}
return $auth;
}
/**
* Available methods
*
* @return array
*/
public function getMethods() {
$result = array();
$result[] = array(
'name' => 'run',
'desc' => 'Handle the user input',
'params' => array(
'fields' => 'helper_plugin_bureaucracy_field[]',
'thanks' => 'string',
'argv' => 'array'
),
'return' => array('false on error, thanks message on success' => 'bool|string')
);
return $result;
}
}
@@ -0,0 +1,212 @@
<?php
/**
* Action sendemail for DokuWiki plugin bureaucracy
*/
class helper_plugin_bureaucracy_actionmail extends helper_plugin_bureaucracy_action {
protected $_mail_html = '';
protected $_mail_text = '';
protected $subject = '';
protected $replyto = array();
protected $mailtemplate = '';
/**
* Build a nice email from the submitted data and send it
*
* @param helper_plugin_bureaucracy_field[] $fields
* @param string $thanks
* @param array $argv
* @return string thanks message
* @throws Exception mailing failed
*/
public function run($fields, $thanks, $argv) {
global $ID;
global $conf;
$mail = new Mailer();
$this->prepareNamespacetemplateReplacements();
$this->prepareDateTimereplacements();
$this->prepareLanguagePlaceholder();
$this->prepareNoincludeReplacement();
$this->prepareFieldReplacements($fields);
$evdata = [
'fields' => $fields,
'values' => &$this->values
];
$event = new Doku_Event('PLUGIN_BUREAUCRACY_EMAIL_SEND', $evdata);
if($event->advise_before()) {
//set default subject
$this->subject = sprintf($this->getLang('mailsubject'), $ID);
//build html&text table, collect replyto and subject
list($table_html, $table_text) = $this->processFieldsBuildTable($fields, $mail);
//Body
if($this->mailtemplate) {
//show template
$this->patterns['__tablehtml__'] = '/@TABLEHTML@/';
$this->patterns['__tabletext__'] = '/@TABLETEXT@/';
$this->values['__tablehtml__'] = $table_html;
$this->values['__tabletext__'] = $table_text;
list($this->_mail_html, $this->_mail_text) = $this->getContent();
} else {
//show simpel listing
$this->_mail_html .= sprintf($this->getLang('mailintro')."<br><br>", dformat());
$this->_mail_html .= $table_html;
$this->_mail_text .= sprintf($this->getLang('mailintro')."\n\n", dformat());
$this->_mail_text .= $table_text;
}
$mail->setBody($this->_mail_text,null,null,$this->_mail_html);
// Reply-to
if(!empty($this->replyto)) {
$replyto = $mail->cleanAddress($this->replyto);
$mail->setHeader('Reply-To', $replyto, false);
}
// To
$to = $this->replace(implode(',',$argv)); // get recipient address(es)
$to = $mail->cleanAddress($to);
$mail->to($to);
// From
$mail->from($conf['mailfrom']);
// Subject
$this->subject = $this->replace($this->subject);
$mail->subject($this->subject);
if(!$mail->send()) {
throw new Exception($this->getLang('e_mail'));
}
}
$event->advise_after();
return '<p>' . $thanks . '</p>';
}
/**
* Create html and plain table of the field
* and collect values for subject and replyto
*
* @param helper_plugin_bureaucracy_field[] $fields
* @param Mailer $mail
* @return array of html and text table
*/
protected function processFieldsBuildTable($fields, $mail) {
global $ID;
$table_html = '<table>';
$table_text = '';
foreach($fields as $field) {
$html = $text = '';
$value = $field->getParam('value');
$label = $field->getParam('label');
switch($field->getFieldType()) {
case 'fieldset':
if(!empty($field->depends_on)) {
//print fieldset only if depend condition is true
foreach($fields as $field_tmp) {
if($field_tmp->getParam('label') === $field->depends_on[0] && $field_tmp->getParam('value') === $field->depends_on[1] ) {
list($html, $text) = $this->mail_buildRow($label);
}
}
} else {
list($html, $text) = $this->mail_buildRow($label);
}
break;
case 'file':
if($value === null || $label === null) break; //print attachment only if field was visible
$file = $field->getParam('file');
if(!$file['size']) {
$message = $this->getLang('attachmentMailEmpty');
} else if($file['size'] > $this->getConf('maxEmailAttachmentSize')) {
$message = $file['name'] . ' ' . $this->getLang('attachmentMailToLarge');
msg(sprintf($this->getLang('attachmentMailToLarge_userinfo'), hsc($file['name']), filesize_h($this->getConf('maxEmailAttachmentSize'))), 2);
} else {
$message = $file['name'];
$mail->attachFile($file['tmp_name'], $file['type'], $file['name']);
}
list($html, $text) = $this->mail_buildRow($label, $message);
break;
case 'subject':
$this->subject = $label;
break;
case 'usemailtemplate':
if (!is_null($field->getParam('template')) ) {
$this->mailtemplate = $this->replace($field->getParam('template'));
resolve_pageid(getNS($ID), $this->mailtemplate, $ignored);
}
break;
default:
if($value === null || $label === null) break;
if(is_array($value)) $value = implode(', ', $value);
list($html, $text) = $this->mail_buildRow($label, $value);
if(!is_null($field->getParam('replyto'))) {
$this->replyto[] = $value;
}
}
$table_html .= $html;
$table_text .= $text;
}
$table_html .= '</table>';
return array($table_html, $table_text);
}
/**
* Build a row
*
* @param $column1
* @param null $column2
* @return array of html and text row
*/
protected function mail_buildRow($column1,$column2=null) {
if($column2 === null) {
$html = '<tr><td colspan="2"><u>'.hsc($column1).'<u></td></tr>';
$text = "\n=====".$column1.'=====';
} else {
$html = '<tr><td><b>'.hsc($column1).'<b></td><td>'.hsc($column2).'</td></tr>';
$text = "\n $column1 \t\t $column2";
}
return array($html, $text);
}
/**
* Parse mail template in html and text, and perform replacements
*
* @return array html and text content
*/
protected function getContent() {
$content = rawWiki($this->mailtemplate);
$html = '';
$text = '';
if(preg_match_all('#<code\b(.*?)>(.*?)</code>#is', $content, $matches)) {
foreach($matches[1] as $index => $codeoptions) {
list($syntax,) = explode(' ', trim($codeoptions), 2);
if($syntax == 'html') {
$html = $matches[2][$index];
}
if($syntax == 'text' || $syntax == '') {
$text = $matches[2][$index];
}
}
}
return array(
$this->replace($html),
$this->replace($text)
);
}
}
// vim:ts=4:sw=4:et:enc=utf-8:
@@ -0,0 +1,62 @@
<?php
class helper_plugin_bureaucracy_actionscript extends helper_plugin_bureaucracy_action {
protected $scriptNamePattern = '/^[_a-zA-Z0-9]+\.php$/';
/**
* @inheritDoc
* @throws \InvalidArgumentException
*/
public function run($fields, $thanks, $argv) {
if (count($argv) < 1) {
throw new InvalidArgumentException('The "script"-action expects exactly 1 argument: the script name.');
}
$scriptName = $argv[0];
if (!$this->validateScriptName($scriptName)) {
$cleanedScriptName = hsc($scriptName);
throw new InvalidArgumentException("The supplied scriptname \"<code>$cleanedScriptName</code>\" is invalid! It must conform to <code>{hsc($this->scriptNamePattern)}</code>!");
}
$path = DOKU_CONF . 'plugin/bureaucracy/' . $scriptName;
if (!file_exists($path)) {
$shortPath = 'conf/plugin/bureaucracy/' . $scriptName;
throw new InvalidArgumentException("Script <code>$shortPath</code> doesn't exist!");
}
require $path;
$classFragment = substr($scriptName, 0, strpos($scriptName, '.'));
$className = 'helper_plugin_bureaucracy_handler_' . $classFragment;
$deprecatedClassName = 'bureaucracy_handler_' . $classFragment;
if (!class_exists($className) && class_exists($deprecatedClassName)) {
msg("Please change this script's class-name to <code>$className</code>.
Your current scheme <code>$deprecatedClassName</code> is deprecated and will stop working in the future.", 2);
$className = $deprecatedClassName;
}
/** @var dokuwiki\plugin\bureaucracy\interfaces\bureaucracy_handler_interface $handler */
$handler = new $className;
if (!is_a($handler, dokuwiki\plugin\bureaucracy\interfaces\bureaucracy_handler_interface::class)) {
throw new InvalidArgumentException('The handler must implement the interface <code>dokuwiki\\plugin\\bureaucracy\\interfaces\\bureaucracy_handler_interface</code> !');
}
return $handler->handleData($fields, $thanks);
}
/**
* @param $scriptName
*
* @return bool
*/
protected function validateScriptName($scriptName) {
$valid = preg_match($this->scriptNamePattern, $scriptName);
return $valid === 1;
}
}
@@ -0,0 +1,464 @@
<?php
use dokuwiki\File\PageResolver;
/**
* Simple template replacement action for the bureaucracy plugin
*
* @author Michael Klier <chi@chimeric.de>
*/
class helper_plugin_bureaucracy_actiontemplate extends helper_plugin_bureaucracy_action {
var $targetpages;
var $pagename;
/**
* Performs template action
*
* @param helper_plugin_bureaucracy_field[] $fields array with form fields
* @param string $thanks thanks message
* @param array $argv array with entries: template, pagename, separator
* @return array|mixed
*
* @throws Exception
*/
public function run($fields, $thanks, $argv) {
global $conf;
[$tpl, $this->pagename] = $argv;
$sep = $argv[2] ?? $conf['sepchar'];
$this->patterns = array();
$this->values = array();
$this->targetpages = array();
$this->prepareNamespacetemplateReplacements();
$this->prepareDateTimereplacements();
$this->prepareLanguagePlaceholder();
$this->prepareNoincludeReplacement();
$this->prepareFieldReplacements($fields);
$evdata = array(
'patterns' => &$this->patterns,
'values' => &$this->values,
'fields' => $fields,
'action' => $this
);
$event = new Doku_Event('PLUGIN_BUREAUCRACY_PAGENAME', $evdata);
if ($event->advise_before()) {
$this->buildTargetPagename($fields, $sep);
}
$event->advise_after();
//target&template(s) from addpage fields
$this->getAdditionalTargetpages($fields);
//target&template(s) from action field
$tpl = $this->getActionTargetpages($tpl);
if(empty($this->targetpages)) {
throw new Exception(sprintf($this->getLang('e_template'), $tpl));
}
$this->checkTargetPageNames();
$this->processUploads($fields);
$this->replaceAndSavePages($fields);
$ret = $this->buildThankYouPage($thanks);
return $ret;
}
/**
* Prepare and resolve target page
*
* @param helper_plugin_bureaucracy_field[] $fields List of field objects
* @param string $sep Separator between fields for page id
* @throws Exception missing pagename
*/
protected function buildTargetPagename($fields, $sep) {
global $ID;
foreach ($fields as $field) {
$pname = $field->getParam('pagename');
if (!is_null($pname)) {
if (is_array($pname)) $pname = implode($sep, $pname);
$this->pagename .= $sep . $pname;
}
}
$resolver = new PageResolver(getNS($ID));
$this->pagename = $resolver->resolveId($this->replace($this->pagename));
if ($this->pagename === '') {
throw new Exception($this->getLang('e_pagename'));
}
}
/**
* Handle templates from addpage field
*
* @param helper_plugin_bureaucracy_field[] $fields List of field objects
* @return array
*/
function getAdditionalTargetpages($fields) {
global $ID;
$ns = getNS($ID);
foreach ($fields as $field) {
if (!is_null($field->getParam('page_tpl')) && !is_null($field->getParam('page_tgt')) ) {
$resolver = new PageResolver($ns);
//template
$templatepage = $this->replace($field->getParam('page_tpl'));
$templatepage = $resolver->resolveId($templatepage);
//target
$relativetargetpage = $resolver->resolveId($field->getParam('page_tgt'));
$targetpage = "$this->pagename:$relativetargetpage";
$auth = $this->aclcheck($templatepage); // runas
if ($auth >= AUTH_READ ) {
$this->addParsedTargetpage($targetpage, $templatepage);
}
}
}
}
/**
* Returns raw pagetemplate contents for the ID's namespace
*
* @param string $id the id of the page to be created
* @return string raw pagetemplate content
*/
protected function rawPageTemplate($id) {
global $conf;
$path = dirname(wikiFN($id));
if(file_exists($path.'/_template.txt')) {
$tplfile = $path.'/_template.txt';
} else {
// search upper namespaces for templates
$len = strlen(rtrim($conf['datadir'], '/'));
while(strlen($path) >= $len) {
if(file_exists($path.'/__template.txt')) {
$tplfile = $path.'/__template.txt';
break;
}
$path = substr($path, 0, strrpos($path, '/'));
}
}
$tpl = io_readFile($tplfile);
return $tpl;
}
/**
* Load template(s) for targetpage as given via action field
*
* @param string $tpl template name as given in form
* @return string parsed templatename
*/
protected function getActionTargetpages($tpl) {
global $USERINFO;
global $conf;
global $ID;
$runas = $this->getConf('runas');
if ($tpl == '_') {
// use namespace template
if (!isset($this->targetpages[$this->pagename])) {
$raw = $this->rawPageTemplate($this->pagename);
$this->noreplace_save($raw);
$this->targetpages[$this->pagename] = pageTemplate(array($this->pagename));
}
} elseif ($tpl !== '!') {
$tpl = $this->replace($tpl);
// resolve templates, but keep references to whole namespaces intact (ending in a colon)
$resolver = new PageResolver(getNS($ID));
if(substr($tpl, -1) == ':') {
$tpl = $tpl.'xxx'; // append a fake page name
$tpl = $resolver->resolveId($tpl);
$tpl = substr($tpl, 0, -3); // cut off fake page name again
} else {
$tpl = $resolver->resolveId($tpl);
}
$backup = array();
if ($runas) {
// Hack user credentials.
$backup = array($_SERVER['REMOTE_USER'], $USERINFO['grps']);
$_SERVER['REMOTE_USER'] = $runas;
$USERINFO['grps'] = array();
}
$template_pages = array();
//search checks acl (as runas)
$opts = array(
'depth' => 0,
'listfiles' => true,
'showhidden' => true
);
search($template_pages, $conf['datadir'], 'search_universal', $opts, str_replace(':', '/', getNS($tpl)));
foreach ($template_pages as $template_page) {
$templatepageid = cleanID($template_page['id']);
// try to replace $tpl path with $this->pagename path in the founded $templatepageid
// - a single-page template will only match on itself and will be replaced,
// other newtargets are pages in same namespace, so aren't changed
// - a namespace as template will match at the namespaces-part of the path of pages in this namespace
// so these newtargets are changed
// if there exist a single-page and a namespace with name $tpl, both are selected
$newTargetpageid = preg_replace('/^' . preg_quote_cb(cleanID($tpl)) . '($|:)/', $this->pagename . '$1', $templatepageid);
if ($newTargetpageid === $templatepageid) {
// only a single-page template or page in the namespace template
// which matches the $tpl path are changed
continue;
}
if (!isset($this->targetpages[$newTargetpageid])) {
$this->addParsedTargetpage($newTargetpageid, $templatepageid);
}
}
if ($runas) {
/* Restore user credentials. */
list($_SERVER['REMOTE_USER'], $USERINFO['grps']) = $backup;
}
}
return $tpl;
}
/**
* Checks for existance and access of target pages
*
* @return mixed
* @throws Exception
*/
protected function checkTargetPageNames() {
foreach (array_keys($this->targetpages) as $pname) {
// prevent overriding already existing pages
if (page_exists($pname)) {
throw new Exception(sprintf($this->getLang('e_pageexists'), html_wikilink($pname)));
}
$auth = $this->aclcheck($pname);
if ($auth < AUTH_CREATE) {
throw new Exception($this->getLang('e_denied'));
}
}
}
/**
* Perform replacements on the collected templates, and save the pages.
*
* Note: wrt runas, for changelog are used:
* - $INFO['userinfo']['name']
* - $INPUT->server->str('REMOTE_USER')
*/
protected function replaceAndSavePages($fields) {
global $ID;
foreach ($this->targetpages as $pageName => $template) {
// set NSBASE var to make certain dataplugin constructs easier
$this->patterns['__nsbase__'] = '/@NSBASE@/';
$this->values['__nsbase__'] = noNS(getNS($pageName));
$evdata = array(
'patterns' => &$this->patterns,
'values' => &$this->values,
'id' => $pageName,
'template' => $template,
'form' => $ID,
'fields' => $fields
);
$event = new Doku_Event('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', $evdata);
if($event->advise_before()) {
// save page
saveWikiText(
$evdata['id'],
cleanText($this->replace($evdata['template'], false)),
sprintf($this->getLang('summary'), $ID)
);
}
$event->advise_after();
}
}
/**
* (Callback) Sorts first by namespace depth, next by page ids
*
* @param string $a
* @param string $b
* @return int positive if $b is in deeper namespace than $a, negative higher.
* further sorted by pageids
*
* return an integer less than, equal to, or
* greater than zero if the first argument is considered to be
* respectively less than, equal to, or greater than the second.
*/
public function _sorttargetpages($a, $b) {
$ns_diff = substr_count($a, ':') - substr_count($b, ':');
return ($ns_diff === 0) ? strcmp($a, $b) : ($ns_diff > 0 ? -1 : 1);
}
/**
* (Callback) Build content of item
*
* @param array $item
* @return string
*/
public function html_list_index($item){
$ret = '';
if($item['type']=='f'){
$ret .= html_wikilink(':'.$item['id']);
} else {
$ret .= '<strong>' . trim(substr($item['id'], strrpos($item['id'], ':', -2)), ':') . '</strong>';
}
return $ret;
}
/**
* Build thanks message, trigger indexing and rendering of new pages.
*
* @param string $thanks
* @return string html of thanks message or when redirect the first page id of created pages
*/
protected function buildThankYouPage($thanks) {
global $ID;
$backupID = $ID;
$html = "<p>$thanks</p>";
// Build result tree
$pages = array_keys($this->targetpages);
usort($pages, array($this, '_sorttargetpages'));
$data = array();
$last_folder = array();
foreach ($pages as $ID) {
$lvl = substr_count($ID, ':');
for ($n = 0; $n < $lvl; ++$n) {
if (!isset($last_folder[$n]) || strpos($ID, $last_folder[$n]['id']) !== 0) {
$last_folder[$n] = array(
'id' => substr($ID, 0, strpos($ID, ':', ($n > 0 ? strlen($last_folder[$n - 1]['id']) : 0) + 1) + 1),
'level' => $n + 1,
'open' => 1,
'type' => null,
);
$data[] = $last_folder[$n];
}
}
$data[] = array('id' => $ID, 'level' => 1 + substr_count($ID, ':'), 'type' => 'f');
}
$index = new dokuwiki\Ui\Index();
$html .= html_buildlist($data, 'idx', array($this, 'html_list_index'), array($index, 'tagListItem'));
// Add indexer bugs for every just-created page
$html .= '<div class="no">';
ob_start();
foreach ($pages as $ID) {
// indexerWebBug uses ID and INFO[exists], but the bureaucracy form
// page always exists, as does the just-saved page, so INFO[exists]
// is correct in any case
tpl_indexerWebBug();
// the iframe will trigger real rendering of the pages to make sure
// any used plugins are initialized (eg. the do plugin)
echo '<iframe src="' . wl($ID, array('do' => 'export_html')) . '" width="1" height="1" style="visibility:hidden"></iframe>';
}
$html .= ob_get_contents();
ob_end_clean();
$html .= '</div>';
$ID = $backupID;
return $html;
}
/**
* move the uploaded files to <pagename>:FILENAME
*
*
* @param helper_plugin_bureaucracy_field[] $fields
* @throws Exception
*/
protected function processUploads($fields) {
foreach($fields as $field) {
if($field->getFieldType() !== 'file') continue;
$label = $field->getParam('label');
$file = $field->getParam('file');
$ns = $field->getParam('namespace');
//skip empty files
if(!$file['size']) {
$this->values[$label] = '';
continue;
}
$id = $ns.':'.$file['name'];
resolve_mediaid($this->pagename, $id, $ignored); // resolve relatives
$auth = $this->aclcheck($id); // runas
$move = 'copy_uploaded_file';
//prevent from is_uploaded_file() check
if(defined('DOKU_UNITTEST')) {
$move = 'copy';
}
$res = media_save(
array('name' => $file['tmp_name']),
$id,
false,
$auth,
$move);
if(is_array($res)) throw new Exception($res[0]);
$this->values[$label] = $res;
}
}
/**
* Load page data and do default pattern replacements like namespace templates do
* and add it to list of targetpages
*
* Note: for runas the values of the real user are used for the placeholders
* @NAME@ => $USERINFO['name']
* @MAIL@ => $USERINFO['mail']
* and the replaced value:
* @USER@ => $INPUT->server->str('REMOTE_USER')
*
* @param string $targetpageid pageid of destination
* @param string $templatepageid pageid of template for this targetpage
*/
protected function addParsedTargetpage($targetpageid, $templatepageid) {
$tpl = rawWiki($templatepageid);
$this->noreplace_save($tpl);
$data = array(
'id' => $targetpageid,
'tpl' => $tpl,
'doreplace' => true,
);
parsePageTemplate($data);
//collect and apply some other replacements
$patterns = array();
$values = array();
$keys = array('__lang__', '__trans__', '__year__', '__month__', '__day__', '__time__');
foreach($keys as $key) {
$patterns[$key] = $this->patterns[$key];
$values[$key] = $this->values[$key];
}
$this->targetpages[$targetpageid] = preg_replace($patterns, $values, $data['tpl']);
}
}
// vim:ts=4:sw=4:et:enc=utf-8:
+508
View File
@@ -0,0 +1,508 @@
<?php
/**
* Base class for form fields
*
* This class provides basic functionality for many form fields. It supports
* labels, basic validation and template-based XHTML output.
*
* @author Adrian Lang <lang@cosmocode.de>
**/
/**
* Class helper_plugin_bureaucracy_field
*
* base class for all the form fields
*/
class helper_plugin_bureaucracy_field extends syntax_plugin_bureaucracy {
protected $mandatory_args = 2;
public $opt = array();
/** @var string|array */
protected $tpl;
protected $checks = array();
public $hidden = false;
protected $error = false;
protected $checktypes = array(
'/' => 'match',
'<' => 'max',
'>' => 'min'
);
/**
* Construct a helper_plugin_bureaucracy_field object
*
* This constructor initializes a helper_plugin_bureaucracy_field object
* based on a given definition.
*
* The first two items represent:
* * the type of the field
* * and the label the field has been given.
* Additional arguments are type-specific mandatory extra arguments and optional arguments.
*
* The optional arguments may add constraints to the field value, provide a
* default value, mark the field as optional or define that the field is
* part of a pagename (when using the template action).
*
* Since the field objects are cached, this constructor may not reference
* request data.
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
$this->init($args);
$this->standardArgs($args);
}
/**
* Return false to prevent DokuWiki reusing instances of the plugin
*
* @return bool
*/
public function isSingleton() {
return false;
}
/**
* Checks number of arguments and store 'cmd', 'label' and 'display' values
*
* @param array $args array with the definition
*/
protected function init(&$args) {
if(count($args) < $this->mandatory_args){
msg(sprintf($this->getLang('e_missingargs'), hsc($args[0]),
hsc($args[1])), -1);
return;
}
// get standard arguments
$this->opt = array();
foreach (array('cmd', 'label') as $key) {
if (count($args) === 0) break;
$this->opt[$key] = array_shift($args);
}
$this->opt['display'] = $this->opt['label']; // allow to modify display value independently
}
/**
* Check for additional arguments and store their values
*
* @param array $args array with remaining definition arguments
*/
protected function standardArgs($args) {
// parse additional arguments
foreach($args as $arg){
if ($arg[0] == '=') {
$this->setVal(substr($arg,1));
} elseif ($arg == '!') {
$this->opt['optional'] = true;
} elseif ($arg == '^') {
//only one field has focus
if (helper_plugin_bureaucracy_field::hasFocus()) {
$this->opt['id'] = 'focus__this';
}
} elseif($arg == '@') {
$this->opt['pagename'] = true;
} elseif($arg == '@@') {
$this->opt['replyto'] = true;
} elseif(preg_match('/x\d/', $arg)) {
$this->opt['rows'] = substr($arg,1);
} elseif($arg[0] == '.') {
$this->opt['class'] = substr($arg, 1);
} elseif(preg_match('/^0{2,}$/', $arg)) {
$this->opt['leadingzeros'] = strlen($arg);
} elseif($arg[0].$arg[1] == '**') {
$this->opt['matchexplanation'] = substr($arg,2);
} else {
$t = $arg[0];
$d = substr($arg,1);
if (in_array($t, array('>', '<')) && !is_numeric($d)) {
break;
}
if ($t == '/') {
if (substr($d, -1) !== '/') {
break;
}
$d = substr($d, 0, -1);
}
if (!isset($this->checktypes[$t]) || !method_exists($this, 'validate_' . $this->checktypes[$t])) {
msg(sprintf($this->getLang('e_unknownconstraint'), hsc($t).' ('.hsc($arg).')'), -1);
return;
}
$this->checks[] = array('t' => $t, 'd' => $d);
}
}
}
/**
* Add parsed element to Form which generates XHTML
*
* Outputs the represented field using the passed Doku_Form object.
* Additional parameters (CSS class & HTML name) are passed in $params.
* HTML output is created by passing the template $this->tpl to the simple
* template engine _parse_tpl.
*
* @param array $params Additional HTML specific parameters
* @param Doku_Form $form The target Doku_Form object
* @param int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
if(!$form->_infieldset){
$form->startFieldset('');
}
if ($this->error) {
$params['class'] = 'bureaucracy_error';
}
$params = array_merge($this->opt, $params);
$form->addElement($this->_parse_tpl($this->tpl, $params));
}
/**
* Only the first use get the focus, next calls not
*
* @return bool
*/
protected static function hasFocus(){
static $focus = true;
if($focus) {
$focus = false;
return true;
} else {
return false;
}
}
/**
* Check for preload value in the request url
*/
protected function _handlePreload() {
$preload_name = '@' . strtr($this->getParam('label'),' .','__') . '@';
if (isset($_GET[$preload_name])) {
$this->setVal($_GET[$preload_name]);
}
}
/**
* Handle a post to the field
*
* Accepts and validates a posted value.
*
* (Overridden by fieldset, which has as argument an array with the form array by reference)
*
* @param string $value The passed value or array or null if none given
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
public function handle_post($value, &$fields, $index, $formid) {
return $this->hidden || $this->setVal($value);
}
/**
* Get the field type
*
* @return string
**/
public function getFieldType() {
return $this->opt['cmd'];
}
/**
* Get the replacement pattern used by action
*
* @return string
*/
public function getReplacementPattern() {
$label = $this->getParam('label');
$value = $this->getParam('value');
if (is_array($value)) {
return '/(@@|##)' . preg_quote($label, '/') .
'(?:\((?P<delimiter>.*?)\))?' .//delimiter
'(?:\|(?P<default>.*?))' . (count($value) == 0 ? '' : '?') .
'\1/si';
}
return '/(@@|##)' . preg_quote($label, '/') .
'(?:\|(.*?))' . (is_null($value) ? '' : '?') .
'\1/si';
}
/**
* Used as an callback for preg_replace_callback
*
* @param $matches
* @return string
*/
public function replacementMultiValueCallback($matches) {
$value = $this->opt['value'];
//default value
if (is_null($value) || $value === false) {
if (isset($matches['default']) && $matches['default'] != '') {
return $matches['default'];
}
return $matches[0];
}
//check if matched string containts a pair of brackets
$delimiter = preg_match('/\(.*\)/s', $matches[0]) ? $matches['delimiter'] : ', ';
return implode($delimiter, $value);
}
/**
* Get the value used by action
* If value is a callback preg_replace_callback is called instead preg_replace
*
* @return mixed|string
*/
public function getReplacementValue() {
$value = $this->getParam('value');
if (is_array($value)) {
return array($this, 'replacementMultiValueCallback');
}
return is_null($value) || $value === false ? '$2' : $value;
}
/**
* Validate value and stores it
*
* @param mixed $value value entered into field
* @return bool whether the passed value is valid
*/
protected function setVal($value) {
if ($value === '') {
$value = null;
}
$this->opt['value'] = $value;
try {
$this->_validate();
$this->error = false;
} catch (Exception $e) {
msg($e->getMessage(), -1);
$this->error = true;
}
return !$this->error;
}
/**
* Whether the field is true (used for depending fieldsets)
*
* @return bool whether field is set
*/
public function isSet_() {
return !is_null($this->getParam('value'));
}
/**
* Validate value of field and throws exceptions for bad values.
*
* @throws Exception when field didn't validate.
*/
protected function _validate() {
$value = $this->getParam('value');
if (is_null($value)) {
if(!isset($this->opt['optional'])) {
throw new Exception(sprintf($this->getLang('e_required'),hsc($this->opt['label'])));
}
return;
}
foreach ($this->checks as $check) {
$checktype = $this->checktypes[$check['t']];
if (!call_user_func(array($this, 'validate_' . $checktype), $check['d'], $value)) {
//replacement is custom explanation or just the regexp or the requested value
if(isset($this->opt['matchexplanation'])) {
$replacement = hsc($this->opt['matchexplanation']);
} elseif($checktype == 'match') {
$replacement = sprintf($this->getLang('checkagainst'), hsc($check['d']));
} else {
$replacement = hsc($check['d']);
}
throw new Exception(sprintf($this->getLang('e_' . $checktype), hsc($this->opt['label']), $replacement));
}
}
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
public function getParam($name) {
if (!isset($this->opt[$name]) || $name === 'value' && $this->hidden) {
return null;
}
if ($name === 'pagename') {
// If $this->opt['pagename'] is set, return the escaped value of the field.
$value = $this->getParam('value');
if (is_null($value)) {
return null;
}
global $conf;
if($conf['useslash']) $value = str_replace('/',' ',$value);
return str_replace(':',' ',$value);
}
return $this->opt[$name];
}
/**
* Parse a template with given parameters
*
* Replaces variables specified like @@VARNAME|default@@ using the passed
* value map.
*
* @param string|array $tpl The template as string or array
* @param array $params A hash mapping parameters to values
*
* @return string|array The parsed template
*/
protected function _parse_tpl($tpl, $params) {
// addElement supports a special array format as well. In this case
// not all elements should be escaped.
$is_simple = !is_array($tpl);
if ($is_simple) $tpl = array($tpl);
foreach ($tpl as &$val) {
// Select box passes options as an array. We do not escape those.
if (is_array($val)) continue;
// find all variables and their defaults or param values
preg_match_all('/@@([A-Z]+)(?:\|((?:[^@]|@$|@[^@])*))?@@/', $val, $pregs);
for ($i = 0 ; $i < count($pregs[2]) ; ++$i) {
if (isset($params[strtolower($pregs[1][$i])])) {
$pregs[2][$i] = $params[strtolower($pregs[1][$i])];
}
}
// we now have placeholders in $pregs[0] and their values in $pregs[2]
$replacements = array(); // check if empty to prevent php 5.3 warning
if (!empty($pregs[0])) {
$replacements = array_combine($pregs[0], $pregs[2]);
}
if($is_simple){
// for simple string templates, we escape all replacements
$replacements = array_map('hsc', $replacements);
}else{
// for the array ones, we escape the label and display only
if(isset($replacements['@@LABEL@@'])) $replacements['@@LABEL@@'] = hsc($replacements['@@LABEL@@']);
if(isset($replacements['@@DISPLAY@@'])) $replacements['@@DISPLAY@@'] = hsc($replacements['@@DISPLAY@@']);
}
// we attach a mandatory marker to the display
if(isset($replacements['@@DISPLAY@@']) && !isset($params['optional'])){
$replacements['@@DISPLAY@@'] .= ' <sup>*</sup>';
}
$val = str_replace(array_keys($replacements), array_values($replacements), $val);
}
return $is_simple ? $tpl[0] : $tpl;
}
/**
* Executed after performing the action hooks
*/
public function after_action() {
}
/**
* Constraint function: value of field should match this regexp
*
* @param string $d regexp
* @param mixed $value
* @return int|bool
*/
protected function validate_match($d, $value) {
return @preg_match('/' . $d . '/i', $value);
}
/**
* Constraint function: value of field should be bigger
*
* @param int|number $d lower bound
* @param mixed $value of field
* @return bool
*/
protected function validate_min($d, $value) {
return $value > $d;
}
/**
* Constraint function: value of field should be smaller
*
* @param int|number $d upper bound
* @param mixed $value of field
* @return bool
*/
protected function validate_max($d, $value) {
return $value < $d;
}
/**
* Available methods
*
* @return array
*/
public function getMethods() {
$result = array();
$result[] = array(
'name' => 'initialize',
'desc' => 'Initiate object, first parameters are at least cmd and label',
'params' => array(
'params' => 'array'
)
);
$result[] = array(
'name' => 'renderfield',
'desc' => 'Add parsed element to Form which generates XHTML',
'params' => array(
'params' => 'array',
'form' => 'Doku_Form',
'formid' => 'integer'
)
);
$result[] = array(
'name' => 'handle_post',
'desc' => 'Handle a post to the field',
'params' => array(
'value' => 'array',
'fields' => 'helper_plugin_bureaucracy_field[]',
'index' => 'Doku_Form',
'formid' => 'integer'
),
'return' => array('isvalid' => 'bool')
);
$result[] = array(
'name' => 'getFieldType',
'desc' => 'Get the field type',
'return' => array('fieldtype' => 'string')
);
$result[] = array(
'name' => 'isSet_',
'desc' => 'Whether the field is true (used for depending fieldsets) ',
'return' => array('isset' => 'bool')
);
$result[] = array(
'name' => 'getParam',
'desc' => 'Get an arbitrary parameter',
'params' => array(
'name' => 'string'
),
'return' => array('Parameter value' => 'mixed|null')
);
$result[] = array(
'name' => 'after_action',
'desc' => 'Executed after performing the action hooks'
);
return $result;
}
}
@@ -0,0 +1,63 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldaddpage
*
* Adds another page page_tgt based on a template page page_tpl only for use with the template action
*/
class helper_plugin_bureaucracy_fieldaddpage extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - page_tpl
* - page_tgt
*
* @param array $args The tokenized definition, only split at spaces
*/
function initialize($args) {
if(count($args) < 3){
msg(sprintf($this->getLang('e_missingargs'), hsc($args[0]),
hsc($args[1])), -1);
return;
}
// get standard arguments
$this->opt = array_combine(array('cmd', 'page_tpl', 'page_tgt'), $args);
}
/**
* Nothing displayed
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
function renderfield($params, Doku_Form $form, $formid) {
}
/**
* Handle a post to the field
*
* @param string $value null
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
function handle_post($value, &$fields, $index, $formid) {
return true;
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
function getParam($name) {
return ($name === 'value' ||
(in_array($name, array('page_tpl', 'page_tgt')) && $this->hidden)) ?
null :
parent::getParam($name);
}
}
@@ -0,0 +1,42 @@
<?php
/**
* Class helper_plugin_bureaucracy_fielddate
*
* A date in the format YYYY-MM-DD, provides a date picker
*/
class helper_plugin_bureaucracy_fielddate extends helper_plugin_bureaucracy_fieldtextbox {
/**
* Arguments:
* - cmd
* - label
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
$attr = array(
'class' => 'datepicker edit',
'maxlength'=>'10'
);
if(!isset($this->opt['optional'])) {
$attr['required'] = 'required';
$attr['class'] .= ' required';
}
$this->tpl = form_makeTextField('@@NAME@@', '@@VALUE@@', '@@DISPLAY@@', '@@ID@@', '@@CLASS@@', $attr);
}
/**
* Validate field input
*
* @throws Exception when empty or wrong date format
*/
protected function _validate() {
parent::_validate();
$value = $this->getParam('value');
if (!is_null($value) && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
throw new Exception(sprintf($this->getLang('e_date'),hsc($this->getParam('display'))));
}
}
}
@@ -0,0 +1,30 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldemail
*
* Creates a single line input field where the input is validated to be a valid email address
*/
class helper_plugin_bureaucracy_fieldemail extends helper_plugin_bureaucracy_fieldtextbox {
/**
* Arguments:
* - cmd
* - label
* - @@ (optional)
* - ^ (optional)
*/
/**
* Validate field value
*
* @throws Exception when empty or not valid email address
*/
function _validate() {
parent::_validate();
$value = $this->getParam('value');
if(!is_null($value) && $value !== '@MAIL@' && !mail_isvalid($value)){
throw new Exception(sprintf($this->getLang('e_email'),hsc($this->getParam('display'))));
}
}
}
@@ -0,0 +1,114 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldfieldset
*
* Creates a new set of fields, which optional can be shown/hidden depending on the value of another field above it.
*/
class helper_plugin_bureaucracy_fieldfieldset extends helper_plugin_bureaucracy_field {
protected $mandatory_args = 1;
/** @var array with zero, one entry (fieldname) or two entries (fieldname and match value) */
public $depends_on = array();
/**
* Arguments:
* - cmd
* - label (optional)
* - field name where switching depends on (optional)
* - match value (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
// get standard arguments
$this->opt = array('cmd' => array_shift($args));
if (count($args) > 0) {
$this->opt['label'] = array_shift($args);
$this->opt['display'] = $this->opt['label'];
$this->depends_on = $args;
}
}
/**
* Render the top of the fieldset as XHTML
*
* @param array $params Additional HTML specific parameters
* @param Doku_Form $form The target Doku_Form object
* @param int $formid unique identifier of the form which contains this field
*/
function renderfield($params, Doku_Form $form, $formid) {
$form->startFieldset(hsc($this->getParam('display')));
if (!empty($this->depends_on)) {
$dependencies = array_map('hsc',(array) $this->depends_on);
if (count($this->depends_on) > 1) {
$msg = 'Only edit this fieldset if ' .
'“<span class="bureaucracy_depends_fname">%s</span>” '.
'is set to “<span class="bureaucracy_depends_fvalue">%s</span>”.';
} else {
$msg = 'Only edit this fieldset if ' .
'“<span class="bureaucracy_depends_fname">%s</span>” is set.';
}
$form->addElement('<p class="bureaucracy_depends">' . vsprintf($msg, $dependencies) . '</p>');
}
}
/**
* Handle a post to the fieldset
*
* When fieldset is closed, set containing fields to hidden
*
* @param null $value field value of fieldset always empty
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
public function handle_post($value, &$fields, $index, $formid) {
if(empty($this->depends_on)) {
return true;
}
// search the field where fieldset depends on in fields before fieldset
$hidden = false;
for ($n = 0 ; $n < $index; ++$n) {
$field = $fields[$n];
if ($field->getParam('label') != $this->depends_on[0]) {
continue;
}
if(count($this->depends_on) > 1) {
$hidden = $field->getParam('value') != $this->depends_on[1];
} else {
$hidden = !$field->isSet_();
}
break;
}
// mark fields after this fieldset as hidden
if ($hidden) {
$this->hidden = true;
for ($n = $index + 1 ; $n < count($fields) ; ++$n) {
$field = $fields[$n];
if ($field->getFieldType() === 'fieldset') {
break;
}
$field->hidden = true;
}
}
return true;
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
function getParam($name) {
if($name === 'value') {
return null;
} else {
return parent::getParam($name);
}
}
}
@@ -0,0 +1,75 @@
<?php
/**
* File upload field
*/
class helper_plugin_bureaucracy_fieldfile extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - label
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
function initialize($args) {
$this->init($args);
//default namespace for file upload (pagepath:file_name)
$this->opt['namespace'] = '.';
//check whenever the first argument is an upload namespace
if (isset($args[0]) && preg_match('/^[a-z.\-_:]+$/', $args[0])) {
$this->opt['namespace'] = array_shift($args);
}
$this->standardArgs($args);
$attr = array();
if(!isset($this->opt['optional'])) {
$attr['required'] = 'required';
}
$this->tpl = form_makeFileField('@@NAME@@', '@@DISPLAY@@', '@@ID@@', '@@CLASS@@', $attr);
if(!isset($this->opt['optional'])){
$this->tpl['class'] .= ' required';
}
}
/**
* Handle a post to the field
*
* Accepts and validates a posted value.
*
* @param array $value The passed value or array or null if none given
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed filename is valid
*/
public function handle_post($value, &$fields, $index, $formid) {
$this->opt['file'] = $value;
return parent::handle_post($value['name'], $fields, $index, $formid);
}
/**
* @throws Exception max size, required or upload error
*/
protected function _validate() {
global $lang;
parent::_validate();
$file = $this->getParam('file');
if($file['error'] == 1 || $file['error'] == 2) {
throw new Exception(sprintf($lang['uploadsize'],filesize_h(php_to_byte(ini_get('upload_max_filesize')))));
} else if($file['error'] == 4) {
if(!isset($this->opt['optional'])) {
throw new Exception(sprintf($this->getLang('e_required'),hsc($this->opt['label'])));
}
} else if( $file['error'] || !is_uploaded_file($file['tmp_name'])) {
throw new Exception(hsc($this->opt['label']) .' '. $lang['uploadfail'] . ' (' .$file['error'] . ')' );
}
}
}
@@ -0,0 +1,47 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldhidden
*
* Creates an invisible field with static data
*/
class helper_plugin_bureaucracy_fieldhidden extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - label
* - =default value
*/
/**
* Render the field as XHTML
*
* Outputs the represented field using the passed Doku_Form object.
*
* @param array $params Additional HTML specific parameters
* @param Doku_Form $form The target Doku_Form object
* @param int $formid unique identifier of the form which contains this field
*/
function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
$form->addHidden($params['name'], $this->getParam('value') . '');
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
function getParam($name) {
if (!isset($this->opt[$name]) || in_array($name, array('pagename', 'value')) && $this->hidden) {
return null;
}
if ($name === 'pagename') {
// If $this->opt['pagename'] is set, return the value of the field,
// UNESCAPED.
$name = 'value';
}
return $this->opt[$name];
}
}
@@ -0,0 +1,35 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldhiddenautoinc
*
* Creates an invisible field with a number that increases by 1 on each form submit
*/
class helper_plugin_bureaucracy_fieldhiddenautoinc extends helper_plugin_bureaucracy_fieldnumber {
/**
* Arguments:
* - cmd
* - label
*
* @param array $args The tokenized definition, only split at spaces
*/
function initialize($args) {
$args[] = '++';
parent::initialize($args);
}
/**
* Render the field as XHTML
*
* Outputs the represented field using the passed Doku_Form object.
*
* @param array $params Additional HTML specific parameters
* @param Doku_Form $form The target Doku_Form object
* @param $formid
*/
function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
$form->addHidden($params['name'], $this->getParam('value') . '');
}
}
@@ -0,0 +1,62 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldmultiselect
*
* Creates a multiselect box
*/
class helper_plugin_bureaucracy_fieldmultiselect extends helper_plugin_bureaucracy_fieldselect {
/**
* Arguments:
* - cmd
* - label
* - option1|option2|etc
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
$this->init($args);
$this->opt['args'] = array_map('trim', explode('|',array_shift($args)));
$this->standardArgs($args);
if (isset($this->opt['value'])) {
$this->opt['value'] = array_map('trim', explode(',', $this->opt['value']));
} else {
$this->opt['value'] = array();
}
}
/**
* Render the field as XHTML
*
* Outputs the represented field using the passed Doku_Form object.
* Additional parameters (CSS class & HTML name) are passed in $params.
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
if(!$form->_infieldset){
$form->startFieldset('');
}
if ($this->error) {
$params['class'] = 'bureaucracy_error';
}
$params = array_merge($this->opt, $params);
$form->addElement(call_user_func_array('form_makeListboxField',
$this->_parse_tpl(
array(
'@@NAME@@[]',
$params['args'],
$this->opt['value'],
'@@DISPLAY@@',
'@@ID@@',
'@@CLASS@@',
array('multiple' => 'multiple')
),
$params
)));
}
}
@@ -0,0 +1,119 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldnumber
*
* Creates a single line input field, where input is validated to be numeric
*/
class helper_plugin_bureaucracy_fieldnumber extends helper_plugin_bureaucracy_fieldtextbox {
private $autoinc = false;
/**
* Arguments:
* - cmd
* - label
* - ++ (optional)
* - 0000 (optional)
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
$pp = array_search('++', $args, true);
if ($pp !== false) {
unset($args[$pp]);
$this->autoinc = true;
}
parent::initialize($args);
if ($this->autoinc) {
global $ID;
$key = $this->get_key();
$c_val = p_get_metadata($ID, 'bureaucracy ' . $key);
if (is_null($c_val)) {
if (!isset($this->opt['value'])) {
$this->opt['value'] = 0;
}
p_set_metadata($ID, array('bureaucracy' => array($key => $this->opt['value'])));
} else {
$this->opt['value'] = $c_val;
}
}
$this->opt['value'] = $this->addLeadingzeros($this->opt['value']);
}
/**
* Validate field value
*
* @throws Exception when not a number
*/
protected function _validate() {
$value = $this->getParam('value');
if (!is_null($value) && !is_numeric($value)){
throw new Exception(sprintf($this->getLang('e_numeric'),hsc($this->getParam('display'))));
}
parent::_validate();
}
/**
* Handle a post to the field
*
* Accepts and validates a posted value.
*
* @param string $value The passed value or array or null if none given
* @param array $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
public function handle_post($value, &$fields, $index, $formid) {
$value = $this->addLeadingzeros($value);
return parent::handle_post($value, $fields, $index, $formid);
}
/**
* Returns the cleaned key for this field required for metadata
*
* @return string key
*/
private function get_key() {
return preg_replace('/\W/', '', $this->opt['label']) . '_autoinc';
}
/**
* Executed after performing the action hooks
*
* Increases counter and purge cache
*/
public function after_action() {
if ($this->autoinc) {
global $ID;
p_set_metadata($ID, array('bureaucracy' => array($this->get_key() => $this->opt['value'] + 1)));
// Force rerendering by removing the instructions cache file
$cache_fn = getCacheName(wikiFN($ID).$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.'.'i');
if (file_exists($cache_fn)) {
unlink($cache_fn);
}
}
}
/**
* Add leading zeros, depending on the corresponding field option
*
* @param int|string $value number
* @return string
*/
protected function addLeadingzeros(&$value) {
if (isset($this->opt['leadingzeros'])) {
$length = strlen($value);
for($i = $length; $i < $this->opt['leadingzeros']; $i++) {
$value = '0' . $value;
}
return $value;
}
return $value;
}
}
@@ -0,0 +1,16 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldonoff
*
* Creates a checkbox
*/
class helper_plugin_bureaucracy_fieldonoff extends helper_plugin_bureaucracy_fieldyesno {
/**
* Arguments:
* - cmd
* - label
* - =yesvalue
* - !falsevalue
* - ^ (optional)
*/
}
@@ -0,0 +1,29 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldpassword
*
* Creates a single line password input field
*/
class helper_plugin_bureaucracy_fieldpassword extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - label
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
function initialize($args) {
parent::initialize($args);
$attr = array();
if(!isset($this->opt['optional'])) {
$attr['required'] = 'required';
}
$this->tpl = form_makePasswordField('@@NAME@@', '@@DISPLAY@@', '@@ID@@', '@@CLASS@@', $attr);
if(!isset($this->opt['optional'])){
$this->tpl['class'] .= ' required';
}
}
}
@@ -0,0 +1,82 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldselect
*
* Creates a dropdown list
*/
class helper_plugin_bureaucracy_fieldradio extends helper_plugin_bureaucracy_field {
protected $mandatory_args = 3;
/**
* Arguments:
* - cmd
* - label
* - option1|option2|etc
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
$this->init($args);
$this->opt['args'] = array_filter(array_map('trim', explode('|',array_shift($args))));
$this->standardArgs($args);
}
/**
* Render the field as XHTML
*
* Outputs the represented field using the passed Doku_Form object.
* Additional parameters (CSS class & HTML name) are passed in $params.
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
if(!$form->_infieldset){
$form->startFieldset('');
}
if ($this->error) {
$params['class'] = 'bureaucracy_error';
}
$params = array_merge($this->opt, $params);
list($name, $entries, $value, $label, $id, $class) = $this->_parse_tpl(
array(
'@@NAME@@',
$params['args'],
'@@VALUE@@',
'@@DISPLAY@@',
'@@ID@@',
'@@CLASS@@'
),
$params
);
$value = (in_array($value, $entries) ? $value : null);
$valueoffieldwithid = ($value !== null ? $value : current($entries));
// label
$s = '<label';
$s .= ' class="radiolabel '.$class.'"';
$s .= '><span>' . $label . '</span>';
$s .= '</label>';
$form->addElement($s);
// radio fields
foreach($entries as $val) {
if($value === $val) {
$attrs = array('checked' => 'checked');
} else {
$attrs = array();
}
if($valueoffieldwithid === $val) {
$_id = $id; //e.g. autofocus with 'focus__this' id
} else {
$_id = '';
}
$form->addElement(form_makeRadioField($name, $val, $val, $_id, $class, $attrs));
}
}
}
@@ -0,0 +1,61 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldselect
*
* Creates a dropdown list
*/
class helper_plugin_bureaucracy_fieldselect extends helper_plugin_bureaucracy_field {
protected $mandatory_args = 3;
/**
* Arguments:
* - cmd
* - label
* - option1|option2|etc
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
$this->init($args);
$this->opt['args'] = array_map('trim', explode('|',array_shift($args)));
$this->standardArgs($args);
if (!isset($this->opt['value']) && isset($this->opt['optional'])) {
array_unshift($this->opt['args'],' ');
}
}
/**
* Render the field as XHTML
*
* Outputs the represented field using the passed Doku_Form object.
* Additional parameters (CSS class & HTML name) are passed in $params.
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
if(!$form->_infieldset){
$form->startFieldset('');
}
if ($this->error) {
$params['class'] = 'bureaucracy_error';
}
$params = array_merge($this->opt, $params);
$form->addElement(call_user_func_array('form_makeListboxField',
$this->_parse_tpl(
array(
'@@NAME@@',
$params['args'],
'@@VALUE|' . $params['args'][0] . '@@',
'@@DISPLAY@@',
'@@ID@@',
'@@CLASS@@'
),
$params
)));
}
}
@@ -0,0 +1,60 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldstatic
*
* Adds some static text to the form
*/
class helper_plugin_bureaucracy_fieldstatic extends helper_plugin_bureaucracy_field {
protected $tpl = '<p>@@DISPLAY@@</p>';
/**
* Arguments:
* - cmd
* - text
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
// make always optional to prevent being marked as required
$this->opt['optional'] = true;
}
/**
* Handle a post to the field
*
* @param string $value The passed value
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
public function handle_post($value, &$fields, $index, $formid) {
return true;
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
public function getParam($name) {
return ($name === 'value') ? null : parent::getParam($name);
}
/**
* Render the field as XHTML
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
if (!isset($this->opt['display'])) {
$this->opt['display'] = $this->opt['label'];
}
parent::renderfield($params, $form, $formid);
}
}
@@ -0,0 +1,37 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldsubject
*
* Defines own subject for mail action from this form
*/
class helper_plugin_bureaucracy_fieldsubject extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - subjecttext
*/
/**
* Render the field as XHTML
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
$this->_handlePreload();
}
/**
* Handle a post to the field
*
* @param string $value null
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
function handle_post($value, &$fields, $index, $formid) {
return true;
}
}
@@ -0,0 +1,89 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldsubmit
*
* Creates a submit button
*/
class helper_plugin_bureaucracy_fieldsubmit extends helper_plugin_bureaucracy_field {
protected $mandatory_args = 1;
static $captcha_displayed = array();
static $captcha_checked = array();
/**
* Arguments:
* - cmd
* - label (optional)
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
// make always optional to prevent being marked as required
$this->opt['optional'] = true;
}
/**
* Render the field as XHTML
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
if(!isset(helper_plugin_bureaucracy_fieldsubmit::$captcha_displayed[$formid])) {
helper_plugin_bureaucracy_fieldsubmit::$captcha_displayed[$formid] = true;
/** @var helper_plugin_captcha $helper */
$helper = null;
if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha');
if(!is_null($helper) && $helper->isEnabled()){
$form->addElement($helper->getHTML());
}
}
$attr = array();
if(isset($this->opt['id'])) {
$attr['id'] = $this->opt['id'];
}
$this->tpl = form_makeButton('submit','', '@@DISPLAY|' . $this->getLang('submit') . '@@', $attr);
parent::renderfield($params, $form, $formid);
}
/**
* Handle a post to the field
*
* Accepts and validates a posted captcha value.
*
* @param string $value The passed value
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the posted form has a valid captcha
*/
public function handle_post($value, &$fields, $index, $formid) {
if ($this->hidden) {
return true;
}
if(!isset(helper_plugin_bureaucracy_fieldsubmit::$captcha_checked[$formid])) {
helper_plugin_bureaucracy_fieldsubmit::$captcha_checked[$formid] = true;
// check CAPTCHA
/** @var helper_plugin_captcha $helper */
$helper = null;
if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha');
if(!is_null($helper) && $helper->isEnabled()){
return $helper->check();
}
}
return true;
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
public function getParam($name) {
return ($name === 'value') ? null : parent::getParam($name);
}
}
@@ -0,0 +1,29 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldtextarea
*
* Creates a multi-line input field
*/
class helper_plugin_bureaucracy_fieldtextarea extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - label
* - x123 (optional) as number of lines
* - ^ (optional)
*/
public function initialize($args) {
parent::initialize($args);
if (!isset($this->opt['class'])) {
$this->opt['class'] = '';
}
$this->opt['class'] .= ' textareafield';
}
protected $tpl =
'<label class="@@CLASS@@">
<span>@@DISPLAY@@</span>
<textarea name="@@NAME@@" id="@@ID@@" rows="@@ROWS|10@@" cols="10" class="edit @@OPTIONAL|required" required="required@@">@@VALUE@@</textarea>
</label>';
}
@@ -0,0 +1,34 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldtextbox
*
* Creates a single line input field
*/
class helper_plugin_bureaucracy_fieldtextbox extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - label
* - =default (optional)
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
function initialize($args) {
parent::initialize($args);
$attr = array();
if(!isset($this->opt['optional'])) {
$attr['required'] = 'required';
}
$this->tpl = form_makeTextField('@@NAME@@', '@@VALUE@@', '@@DISPLAY@@', '@@ID@@', '@@CLASS@@', $attr);
if(isset($this->opt['class'])){
$this->tpl['class'] .= ' '.$this->opt['class'];
}
if(!isset($this->opt['optional'])){
$this->tpl['class'] .= ' required';
}
}
}
@@ -0,0 +1,42 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldtime
*
* A time in the format (h)h:mm(:ss)
*/
class helper_plugin_bureaucracy_fieldtime extends helper_plugin_bureaucracy_fieldtextbox {
/**
* Arguments:
* - cmd
* - label
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
$attr = array(
'class' => 'timefield edit',
'maxlength'=>'8'
);
if(!isset($this->opt['optional'])) {
$attr['required'] = 'required';
$attr['class'] .= ' required';
}
$this->tpl = form_makeTextField('@@NAME@@', '@@VALUE@@', '@@DISPLAY@@', '@@ID@@', '@@CLASS@@', $attr);
}
/**
* Validate field input
*
* @throws Exception when empty or wrong time format
*/
protected function _validate() {
parent::_validate();
$value = $this->getParam('value');
if (!is_null($value) && !preg_match('/^\d{1,2}:\d{2}(?::\d{2})?$/', $value)) {
throw new Exception(sprintf($this->getLang('e_time'),hsc($this->getParam('display'))));
}
}
}
@@ -0,0 +1,62 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldusemailtemplate
*
* Adds a template only for use with the mail action
*/
class helper_plugin_bureaucracy_fieldusemailtemplate extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - template
*
* @param array $args The tokenized definition, only split at spaces
*/
function initialize($args) {
if(count($args) < 2){
msg(sprintf($this->getLang('e_missingargs'), hsc($args[0]),
hsc($args[1])), -1);
return;
}
// get standard arguments
$this->opt = array_combine(array('cmd', 'template'), $args);
}
/**
* Nothing displayed
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
function renderfield($params, Doku_Form $form, $formid) {
}
/**
* Handle a post to the field
*
* @param string $value null
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
function handle_post($value, &$fields, $index, $formid) {
return true;
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
function getParam($name) {
return ($name === 'value' ||
(in_array($name, array('template')) && $this->hidden)) ?
null :
parent::getParam($name);
}
}
@@ -0,0 +1,99 @@
<?php
/**
* Class helper_plugin_bureaucracy_fielduser
*
* Create single user input, with autocompletion
*/
class helper_plugin_bureaucracy_fielduser extends helper_plugin_bureaucracy_fieldtextbox {
/**
* Arguments:
* - cmd
* - label
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
$this->tpl['class'] .= ' userpicker';
}
/**
* Allow receiving user attributes by ".". Ex. user.name
* You can pass an optional argument to user.grps enclosed in brackets, used as an groups delimiter Ex. user.grps(, )
*
* @return string
*/
public function getReplacementPattern() {
$label = $this->opt['label'];
return '/(@@|##)' . preg_quote($label, '/') .
'(?:\.(.*?))?' . //match attribute after "."
'(?:\((.*?)\))?' . //match parameter enclosed in "()". Used for grps separator
'\1/si';
}
/**
* Used as an callback for preg_replace_callback
*
* @param $matches
* @return string
*/
public function replacementValueCallback($matches) {
/** @var DokuWiki_Auth_Plugin $auth */
global $auth;
$value = $this->opt['value'];
//attr doesn't exists
if (!isset($matches[2])) {
return is_null($value) || $value === false ? '' : $value;
}
$attr = $matches[2];
$udata = $auth->getUserData($value);
//no such user
if ($udata === false) {
return $matches[0];
}
switch($attr) {
case 'name':
case 'mail':
return $udata[$attr];
case 'grps':
$delitmiter = ', ';
if (isset($matches[3])) {
$delitmiter = $matches[3];
}
return implode($delitmiter, $udata['grps']);
default:
return $matches[0];
}
}
/**
* Return the callback for user replacement
*
* @return array
*/
public function getReplacementValue() {
return array($this, 'replacementValueCallback');
}
/**
* Validate value of field
*
* @throws Exception when user not exists
*/
protected function _validate() {
parent::_validate();
/** @var DokuWiki_Auth_Plugin $auth */
global $auth;
$value = $this->getParam('value');
if (!is_null($value) && $auth->getUserData($value) === false) {
throw new Exception(sprintf($this->getLang('e_user'),hsc($this->getParam('display'))));
}
}
}
@@ -0,0 +1,96 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldusers
*
* Create multi-user input, with autocompletion
*/
class helper_plugin_bureaucracy_fieldusers extends helper_plugin_bureaucracy_fieldtextbox {
/**
* Arguments:
* - cmd
* - label
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
$this->tpl['class'] .= ' userspicker';
}
/**
* Allow receiving user attributes by ".". Ex. user.name
* You can pass an optional argument to user.grps enclosed in brackets, used as an groups delimiter Ex. user.grps(, )
*
* @return string
*/
public function getReplacementPattern() {
$label = $this->opt['label'];
return '/(@@|##)' . preg_quote($label, '/') .
'(?:\((?P<delimiter>.*?)\))?' .//delimiter
'(?:\.(?P<attribute>.*?))?' . //match attribute after "."
'\1/si';
}
/**
* Used as an callback for preg_replace_callback
*
* @param $matches
* @return string
*/
public function replacementValueCallback($matches) {
/** @var DokuWiki_Auth_Plugin $auth */
global $auth;
$value = $this->opt['value'];
//copy the value by default
if (isset($matches[2]) && is_array($matches[2]) && count($matches[2]) == 2) {
return is_null($value) || $value === false ? $matches[0] : $value;
}
$attribute = isset($matches['attribute']) ? $matches['attribute'] : '';
//check if matched string containts a pair of brackets
$delimiter = preg_match('/\(.*\)/s', $matches[0]) ? $matches['delimiter'] : ', ';
$users = array_map('trim', explode(',', $value));
switch($attribute) {
case '':
return implode($delimiter, $users);
case 'name':
case 'mail':
return implode($delimiter, array_map(function ($user) use ($auth, $attribute) {
return $auth->getUserData($user)[$attribute];
}, $users));
default:
return $matches[0];
}
}
/**
* Return the callback for user replacement
*
* @return array
*/
public function getReplacementValue() {
return array($this, 'replacementValueCallback');
}
/**
* Validate value of field
*
* @throws Exception when user not exists
*/
protected function _validate() {
parent::_validate();
/** @var DokuWiki_Auth_Plugin $auth */
global $auth;
$users = array_filter(preg_split('/\s*,\s*/', $this->getParam('value')));
foreach ($users as $user) {
if ($auth->getUserData($user) === false) {
throw new Exception(sprintf($this->getLang('e_users'), hsc($this->getParam('display'))));
}
}
}
}
@@ -0,0 +1,70 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldwiki
*
* Adds some static text to the form, but parses the input as Wiki syntax (computationally expensive)
*/
class helper_plugin_bureaucracy_fieldwiki extends helper_plugin_bureaucracy_field {
protected $tpl = '<p>@@LABEL@@</p>';
/**
* Arguments:
* - cmd
* - wiki text
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
parent::initialize($args);
// make always optional to prevent being marked as required
$this->opt['optional'] = true;
}
/**
* Handle a post to the field
*
* @param null $value empty
* @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
* @param int $index index number of field in form
* @param int $formid unique identifier of the form which contains this field
* @return bool Whether the passed value is valid
*/
public function handle_post($value, &$fields, $index, $formid) {
return true;
}
/**
* Get an arbitrary parameter
*
* @param string $name
* @return mixed|null
*/
public function getParam($name) {
return ($name === 'value') ? null : parent::getParam($name);
}
/**
* Returns parsed wiki instructions
*
* @param string|array $tpl The template as string
* @param array $params A hash mapping parameters to values
*
* @return string The parsed template
*/
protected function _parse_tpl($tpl, $params) {
$ins = p_get_instructions($params['display']);
// remove document and p instructions (opening and closing)
$start = 2;
$end = 2;
// check if struct instructions have to be removed as well from the beginning or end
if (isset($ins[1][1][0]) && $ins[1][1][0] === 'struct_output') {
$start = 3;
} elseif (isset($ins[count($ins) - 2][1][0]) && $ins[count($ins) - 2][1][0] === 'struct_output') {
$end = 3;
}
$ins = array_slice($ins, $start, -$end);
$tpl = p_render('xhtml', $ins, $byref_ignore);
return '<p>'.$tpl.'</p>';
}
}
@@ -0,0 +1,98 @@
<?php
/**
* Class helper_plugin_bureaucracy_fieldyesno
*
* Creates a checkbox
*/
class helper_plugin_bureaucracy_fieldyesno extends helper_plugin_bureaucracy_field {
/**
* Arguments:
* - cmd
* - label
* - =yesvalue
* - !falsevalue
* - ^ (optional)
*
* @param array $args The tokenized definition, only split at spaces
*/
public function initialize($args) {
$this->init($args);
$newargs = array();
foreach ($args as $arg) {
switch ($arg[0]) {
case '=':
if($arg == '==1') {
$this->opt['value'] = '1';
}elseif($arg == '==0') {
$this->opt['value'] = '0';
}else{
$this->opt['true_value'] = substr($arg, 1);
}
break;
case '!':
$this->opt['false_value'] = substr($arg, 1);
break;
default:
$newargs[] = $arg;
}
}
$this->standardArgs($newargs);
$this->opt['optional'] = true;
}
/**
* Get an arbitrary parameter
*
* @param string $key
* @return mixed|null
*/
public function getParam($key) {
if ($key === 'value') {
if ($this->opt['value'] === '1') {
return isset($this->opt['true_value']) ?
$this->opt['true_value'] :
null;
} elseif ($this->opt['value'] === '0') {
return isset($this->opt['false_value']) ?
$this->opt['false_value'] :
null;
}
}
return parent::getParam($key);
}
/**
* Whether the field is true (used for depending fieldsets)
*
* @return bool whether field is set
*/
public function isSet_() {
return $this->opt['value'] === '1';
}
/**
* Render the field as XHTML
*
* @params array $params Additional HTML specific parameters
* @params Doku_Form $form The target Doku_Form object
* @params int $formid unique identifier of the form which contains this field
*/
public function renderfield($params, Doku_Form $form, $formid) {
$id = 'bureaucracy__'.md5(rand());
if(isset($this->opt['id'])) {
$id = $this->opt['id'];
}
$params = array_merge(
array('value' => false),
$this->opt,
$params
);
$check = $params['value'] ? 'checked="checked"' : '';
$this->tpl = '<label class="@@CLASS@@" for="'.$id.'"><span>@@DISPLAY@@</span>'.
'<input type="hidden" name="@@NAME@@" value="0" />' .
'<input type="checkbox" name="@@NAME@@" value="1" id="'.$id.'" ' . $check . ' />' .
'</label>';
parent::renderfield($params, $form, $formid);
}
}
@@ -0,0 +1,19 @@
<?php
namespace dokuwiki\plugin\bureaucracy\interfaces;
interface bureaucracy_handler_interface {
/**
* Handle the data incoming from the form.
*
* @param \helper_plugin_bureaucracy_field[] $fields the list of fields in the form
* @param string $thanks the thank you message as defined in the form
* or default one. Might be modified by the action
* before returned
*
* @return bool|string false on error, $thanks on success
*
*/
public function handleData($fields, $thanks);
}
+27
View File
@@ -0,0 +1,27 @@
<?php
$lang['e_unknowntype'] = 'Neznámý typ "%s"';
$lang['e_missingargs'] = 'Příliš málo argumentů pro %s %s';
$lang['e_noaction'] = 'Žádná akce nebyla nastavena';
$lang['e_mail'] = 'Nastala chyba při odesílání';
$lang['e_required'] = '"%s" je povinný';
$lang['e_match'] = '"%s" nemá požadovaný formát. %s)';
$lang['checkagainst'] = '(regulární výraz: /%s/i)';
$lang['e_email'] = '"%s" není platná emailová adresa.';
$lang['e_numeric'] = '"%s" není číslo.';
$lang['e_min'] = '"%s" musí být větší než %s.';
$lang['e_max'] = '"%s" musí být menší než %s.';
$lang['e_pagename'] = 'Chybí jméno stránky.';
$lang['e_pageexists'] = 'Stránka "%s" již existuje. Vyberte, prosím, jiné jméno.';
$lang['e_template'] = 'Šablona "%s" nebyla nalezena. Je možné, že nemáte práva pro čtení.';
$lang['e_denied'] = 'Nemáte práva pro vytvoření stránky, možná nejste přihlášen.';
$lang['mailsubject'] = 'Formulář odeslán jako %s';
$lang['mailintro'] = 'Následující data byla odeslánan na %s.';
$lang['mail_thanks'] = 'Data byla odeslána. Děkujeme.';
$lang['template_thanks'] = 'Stránka byla vytvořena, pokračujte na ni následujícím odkazem.';
$lang['summary'] = 'Vytvořeno z formuláře na %s';
@@ -0,0 +1,4 @@
<?php
$lang['runas'] = 'Ovlivňuje "template mode". Použijte práva (virtuálníh)o uživatele pro kontrolu ACL (přístupová práva) při čtení a vytváření stránek.';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Thorsten Niederkrome <dralli@gmx.net>
*/
$lang['e_unknowntype'] = 'Unbekannter Typ "%s"';
$lang['e_unknownaction'] = 'Unbekannte Aktion "%s"';
$lang['e_missingargs'] = 'Nicht genug Argumente für %s %s';
$lang['e_noaction'] = 'Keine Aktion definiert - wohin sollen die Daten gesendet werden?';
$lang['e_mail'] = 'Beim Versenden der Daten ist ein Fehler aufgetreten';
$lang['e_unknownconstraint'] = 'Unbekannter Feld-Parameter %s';
$lang['e_labelpage'] = 'Seite mit Feldnamen %s nicht gefunden';
$lang['e_required'] = '"%s" muss ausgefüllt werden.';
$lang['e_match'] = '"%s" wurde nicht korrekt ausgefüllt. %s';
$lang['checkagainst'] = '(überprüft gegen /%s/)';
$lang['e_email'] = '"%s" muss eine gültige E-Mail Adresse sein.';
$lang['e_numeric'] = '"%s" muss eine Nummer sein.';
$lang['e_date'] = '"%s" muss ein gültiges Datum im Format jjjj-mm-tt sein.';
$lang['e_time'] = '"%s" muss eine gültige Zeit im Format (h)h:mm(:ss) sein.';
$lang['e_user'] = '"%s" muss der Name eines existierenden Benutzers sein.';
$lang['e_users'] = '"%s" muss eine komma-separierte Liste existierender Benutzer sein.';
$lang['e_min'] = '"%s" muss größer sein als %s.';
$lang['e_max'] = '"%s" muss kleiner sein als %s.';
$lang['e_pagename'] = 'Seitenname nicht angegeben.';
$lang['e_pageexists'] = 'Die Seite "%s" exisistiert bereits. Bitte wählen Sie einen anderen Namen.';
$lang['e_template'] = 'Das Template "%s" konnte nicht geladen werden. Möglicherweise existiert es nicht oder Sie verfügen nicht über die benötigten Rechte.';
$lang['e_denied'] = 'Sie sind nicht berechtigt diese Seite anzulegen. Haben Sie vielleicht vergessen sich anzumelden?';
$lang['mailsubject'] = 'Formulardaten übermittelt von %s';
$lang['mailintro'] = 'Die folgenden Daten wurden am %s abgeschickt.';
$lang['mail_thanks'] = 'Ihre Daten wurden erfolgreich versandt. Vielen Dank.';
$lang['template_thanks'] = 'Die Seite wurde angelegt, folgen Sie dem Link um die neue Seite aufzurufen.';
$lang['summary'] = 'Erstellt mit dem Formular %s';
$lang['attachmentMailEmpty'] = '(Datei nicht angegeben)';
$lang['attachmentMailToLarge'] = '(Datei zu groß für Mail-Anhang)';
$lang['attachmentMailToLarge_userinfo'] = 'Die Datei "%s" ist zu groß als Mail-Anhang (>%s) (E-Mail ohne Datei gesendet)';
$lang['submit'] = 'Absenden';
@@ -0,0 +1,8 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
*/
$lang['runas'] = 'Affects the template mode. Use this (virtual) user\'s permissions when checking ACLs for reading templates and creating pages.';
$lang['maxEmailAttachmentSize'] = 'Maximale größe eines Mail-Anhangs in Bytes (pro Datei).';
+40
View File
@@ -0,0 +1,40 @@
<?php
$lang['e_unknowntype'] = 'Unknown type "%s"';
$lang['e_unknownaction'] = 'Unknown action "%s"';
$lang['e_missingargs'] = 'Not enough arguments for %s %s';
$lang['e_noaction'] = 'No action defined - where should the data be sent to?';
$lang['e_mail'] = 'Something went wrong with sending that data';
$lang['e_unknownconstraint'] = 'Unknown field constraint %s';
$lang['e_labelpage'] = 'Labelpage %s not found';
$lang['e_required'] = '"%s" is required';
$lang['e_match'] = '"%s" wasn\'t filled in correctly. %s';
$lang['checkagainst'] = '(Checked against /%s/i)';
$lang['e_email'] = '"%s" needs to be a valid email address.';
$lang['e_numeric'] = '"%s" needs to be a number.';
$lang['e_date'] = '"%s" needs to be a valid date in the format yyyy-mm-dd.';
$lang['e_time'] = '"%s" needs to be a valid time in the format (h)h:mm(:ss).';
$lang['e_user'] = '"%s" needs to be the name of an existing user.';
$lang['e_users'] = '"%s" needs to be a comma-separated list of names of existing users.';
$lang['e_min'] = '"%s" needs to be greater than %s.';
$lang['e_max'] = '"%s" needs to be less than %s.';
$lang['e_pagename'] = 'Missing pagename.';
$lang['e_pageexists'] = 'The page "%s" exists already. Please choose a different pagename.';
$lang['e_template'] = 'Could not read template "%s". Maybe it doesn\'t exist or you have no read permissions?';
$lang['e_denied'] = 'You are not allowed to create this page, maybe you forgot to log in?';
$lang['mailsubject'] = 'Form data submitted at %s';
$lang['mailintro'] = 'The following data was submitted on %s.';
$lang['mail_thanks'] = 'Your data was sent successfully. Thank you.';
$lang['template_thanks'] = 'The page has been created, follow the link to open it.';
$lang['summary'] = 'Created from the form at %s';
$lang['attachmentMailEmpty'] = '(file not submitted)';
$lang['attachmentMailToLarge'] = '(file too large for mail attachment)';
$lang['attachmentMailToLarge_userinfo'] = 'file "%s" too large for mail attachment (>%s) (mail was sent nevertheless)';
$lang['submit'] = 'Submit';
@@ -0,0 +1,5 @@
<?php
$lang['runas'] = 'Affects the template mode. Use this (virtual) user\'s permissions when checking ACLs for reading templates and creating pages.';
$lang['maxEmailAttachmentSize'] = 'Max size of mail attachments in Bytes. (per File)';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Vicente <tirantet@gmail.com>
*/
$lang['e_unknowntype'] = 'Tipo desconocido "%s"';
$lang['e_unknownaction'] = 'Acción desconocida "%s"';
$lang['e_missingargs'] = 'Faltan argumentos para %s %s';
$lang['e_noaction'] = 'Falta definir la acción - ¿Dónde enviamos los datos?';
$lang['e_mail'] = 'Algún problema al enviar los datos';
$lang['e_unknownconstraint'] = 'Faltan los límites del campo %s';
$lang['e_labelpage'] = 'Pagina de LABELS "%s" no encontrada';
$lang['e_required'] = '"%s" es necesario';
$lang['e_match'] = '"%s" no esta completado correctamente. %s';
$lang['checkagainst'] = '(Comprobado con /%s/i)';
$lang['e_email'] = '"%s" tiene que ser un eMail válido.';
$lang['e_numeric'] = '"%s" debe ser numérico.';
$lang['e_date'] = '"%s" debe que ser una fecha válida con formato yyyy-mm-dd';
$lang['e_time'] = '"%s" debe ser una hora válida con formato (h)h:mm(:ss)';
$lang['e_user'] = '"%s" debe ser el nombre de un usuario existente.';
$lang['e_users'] = '"%s" tiene que contener una lista de usuarios existentes separados por comas.';
$lang['e_min'] = '"%s" debe ser mayor de %s.';
$lang['e_max'] = '"%s" debe ser menor de %s.';
$lang['e_pagename'] = 'Falta el nombre de la página.';
$lang['e_pageexists'] = 'La pagina "%s" existe. Escoja un nombre diferente.';
$lang['e_template'] = 'No se puede leer la plantilla "%s". O no existe, o no tenemos permisos de lectura.';
$lang['e_denied'] = 'No tiene permisos para crear la página, ¿Esta logueado?';
$lang['mailsubject'] = 'Formulario enviado en %s';
$lang['mailintro'] = 'Los siguientes datos enviados en %s';
$lang['mail_thanks'] = 'Formulario enviado correctamente. Gracias.';
$lang['template_thanks'] = 'La página esta creada, siga el enlace para abrirla.';
$lang['summary'] = 'Creada desde el formulario en %s';
$lang['attachmentMailEmpty'] = '(fichero no enviado)';
$lang['attachmentMailToLarge'] = '(fichero demasiado largo para incrustarlo en un eMail)';
$lang['attachmentMailToLarge_userinfo'] = 'Fichero "%s" demasiado largo para incrustarlo en un eMail (>%s) (eMail enviado de todas formas)';
$lang['submit'] = 'Enviar';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Vicente <tirantet@gmail.com>
*/
$lang['runas'] = 'Afecta el modo plantilla. Use los permisos de este usuario (virtual) cuando compruebe los ACLs para leer plantillas y crear páginas.';
$lang['maxEmailAttachmentSize'] = 'Maximo tamaño, en Bytes, de los elementos incrustados en un eMail. (por fichero)';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author nima <nima.hamidian@gmail.com>
*/
$lang['e_unknowntype'] = 'نوع ناشناخته "%s"';
$lang['e_unknownaction'] = 'عمل ناشناخته "%s"';
$lang['e_missingargs'] = 'آرگومانهای ناکافی برای %s %s';
$lang['e_noaction'] = 'عملی تعریف نشده است- داده‌ها باید به کجا فرستاده شوند؟';
$lang['e_mail'] = 'در فرستادن داده‌ها اشکالی پیش آمده است';
$lang['e_unknownconstraint'] = 'قید فیلد ناشناخته %s';
$lang['e_labelpage'] = 'صفحه برچسب %s یافته نشد';
$lang['e_required'] = '"%s" ضروری است';
$lang['e_match'] = '"%s" به درستی پر نشد. %s';
$lang['checkagainst'] = '(بررسی شده نسبت به /%s/i)';
$lang['e_email'] = '"%s" باید یک نشانی ایمیل صحیح باشد.';
$lang['e_numeric'] = '"%s" باید یک عدد باشد.';
$lang['e_date'] = '"%s" باید یک تاریخ صحیح با صورت yyyy-mm-dd باشد.';
$lang['e_time'] = '"%s" باید یک زمان صحیح با صورت (h)h:mm(:ss) باشد.';
$lang['e_user'] = '"%s" باید نام یک کاربر موجود باشد.';
$lang['e_users'] = '"%s" باید یک لیست جداشده‌باکاما از نام کاربران موجود باشد.';
$lang['e_min'] = '"%s" باید بزرگتر از %s باشد.';
$lang['e_max'] = '"%s" باید کمتر از %s باشد.';
$lang['e_pagename'] = 'نام صفحه فراموش شده است.';
$lang['e_pageexists'] = 'صفحه "%s" هم‌اکنون موجود است. لطفاً یک نام صفحه متفاوت انتخاب کنید.';
$lang['e_template'] = 'امکان خواندن قالب "%s" نبود. شاید وجود ندارد یا شما اجازه خواندن را ندارید.';
$lang['e_denied'] = 'شما اجازه ایجاد این صفحه را ندارید، نکند فراموش کردید وارد حساب کاربری شوید؟';
$lang['mailsubject'] = 'داده‌های فُرم در %s ارسال شدند. ';
$lang['mailintro'] = 'داده‌های زیر روی %s ارسال شدند. ';
$lang['mail_thanks'] = 'داده‌های شما با موفقیت فرستاده شدند. با تشکر از شما.';
$lang['template_thanks'] = 'این صفحه ایجاد شده است، برای باز کردن آن روی پیوند کلیک کنید. ';
$lang['summary'] = 'ایجاد شده از فُرم در %s';
$lang['attachmentMailEmpty'] = '(فایل ارسال نشد)';
$lang['attachmentMailToLarge'] = '(فایل برای پیوست شدن به ایمیل بیش از حد بزرگ است)';
$lang['attachmentMailToLarge_userinfo'] = 'فایل "%s" برای پیوست شدن به ایمیل بیش‌ازحد بزرگ است (>%s)(با این‌حال ایمیل فرستاده شد)';
$lang['submit'] = 'ارسال';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author nima <nima.hamidian@gmail.com>
*/
$lang['runas'] = 'روی حالت قالب اثر می‌گذارد. از این اجازه‌های کاربر (مجازی) وقتی استفاده کنید که ACL ها برای خواندن قالبها و ایجاد صفحات بررسی می‌شوند. ';
$lang['maxEmailAttachmentSize'] = 'اندازه حداکثر پیوست‌های ایمیل بر حسب بایت. (به ازای هر فایل)';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Schplurtz le Déboulonné <schplurtz@laposte.net>
*/
$lang['e_unknowntype'] = 'Type inconu "%s"';
$lang['e_unknownaction'] = 'Action inconnue "%s"';
$lang['e_missingargs'] = 'Pas assez d\'arguments pour %s %s';
$lang['e_noaction'] = 'Pas d\'action définie - que faire des données ?';
$lang['e_mail'] = 'Erreur lors de l\'envoi des données';
$lang['e_unknownconstraint'] = 'Contrainte de champ inconue %s';
$lang['e_labelpage'] = 'Page de label %s non trouvée.';
$lang['e_required'] = '"%s" est requis';
$lang['e_match'] = '"%s" n\'est pas remplis correctement. %s';
$lang['checkagainst'] = '(vérifié avec /%s/i)';
$lang['e_email'] = '"%s" doit être une adresse de courriel valide.';
$lang['e_numeric'] = '"%s" doit être un nombre.';
$lang['e_date'] = '"%s" doit être une date valide au format yyyy-mm-dd.';
$lang['e_time'] = '"%s" nécessite une heure valide au format (h)h:mm(:ss).';
$lang['e_user'] = '"%s" doit être le nom d\'un utilisateur existant.';
$lang['e_users'] = '"%s" doit être une liste à virgules de noms d\'utilisateurs.';
$lang['e_min'] = '"%s" doit être plus grand que %s.';
$lang['e_max'] = '"%s" doit être plus petit que %s.';
$lang['e_pagename'] = 'Nom de page manquant.';
$lang['e_pageexists'] = 'La page "%s" existe déjà. Veuillez choisir un autre nom.';
$lang['e_template'] = 'Modèle "%s" introuvable. Il n\'existe pas ou vous n\'avez pas l\'autorisation de lecture.';
$lang['e_denied'] = 'Vous n\'avez pas le droit de créer cette page, vous êtes vous connecté ?';
$lang['mailsubject'] = 'Données du formulaire de la page %s';
$lang['mailintro'] = 'Les données suivantes ont été envoyées le %s.';
$lang['mail_thanks'] = 'Données envoyées avec succès. Merci.';
$lang['template_thanks'] = 'La page est créée, suivez le lien pour l\'ouvrir.';
$lang['summary'] = 'Créé depuis le formulaire %s';
$lang['attachmentMailEmpty'] = '(fichier non envoyé)';
$lang['attachmentMailToLarge'] = '(fichier trop grand comme pièce jointe de courriel)';
$lang['attachmentMailToLarge_userinfo'] = 'fichier "%s" trop grand comme pièce jointe (>%s). Le message est tout de même parti.';
$lang['submit'] = 'Envoyer';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Schplurtz le Déboulonné <schplurtz@laposte.net>
*/
$lang['runas'] = 'Mode «template» : teste les ACL avec les permissions de cet utilisateur (virtuel) pour la lecture des modèles et la création de page.';
$lang['maxEmailAttachmentSize'] = 'Taille max en octet des pièces jointes dans les courriels. (par fichier)';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Davor Turkalj <turki.bsc@gmail.com>
*/
$lang['e_unknowntype'] = 'Nepoznat tip "%s"';
$lang['e_unknownaction'] = 'Nepoznata aktivnost "%s"';
$lang['e_missingargs'] = 'Nema dovoljno argumenata za %s %s';
$lang['e_noaction'] = 'Nema definirane akcije - gdje podaci trebaju biti poslani?';
$lang['e_mail'] = 'Nešto je pošlo krivo s slanjem ovih podataka';
$lang['e_unknownconstraint'] = 'Nepoznato ograničenje polja %s';
$lang['e_labelpage'] = 'Stranica s labelama %s nije nađena';
$lang['e_required'] = '"%s" je obvezan';
$lang['e_match'] = '"%s" nije ispravno popunjen. %s';
$lang['checkagainst'] = '(Provjereno prema /%s/i)';
$lang['e_email'] = '"%s" treba biti valjana adresa e-pošte.';
$lang['e_numeric'] = '"%s" treba biti broj.';
$lang['e_date'] = '"%s" treba biti valjani datum u obliku gggg-mm-dd.';
$lang['e_time'] = '"%s" treba biti u valjanom obliku (h)h:mm(:ss).';
$lang['e_user'] = '"%s" treba biti ime postojećeg korisnika.';
$lang['e_users'] = '"%s" treba biti zarezom odvojena lista imena postojećih korisnika.';
$lang['e_min'] = '"%s" treba biti veći od %s.';
$lang['e_max'] = '"%s" treba biti manji od %s.';
$lang['e_pagename'] = 'Nedostaje ime stranice.';
$lang['e_pageexists'] = 'Strnaica "%s" već postoji. Molimo odaberite drugo ime stranice.';
$lang['e_template'] = 'Nemogu pročitati predložak "%s". Možda ne postoji ili nemate pravo čitanja?';
$lang['e_denied'] = 'Nije Vam dopušteno stvaranje ove stranice, možda ste se zaboravili prijaviti?';
$lang['mailsubject'] = 'Podaci proslijeđeni u %s';
$lang['mailintro'] = 'Slijedeći podaci su proslijeđeni u %s.';
$lang['mail_thanks'] = 'Vaši podaci su uspješno poslani. Hvala.';
$lang['template_thanks'] = 'Stranica je kreirana, slijedi vezu za njeno otvaranje.';
$lang['summary'] = 'Kreirano iz forme u %s';
$lang['attachmentMailEmpty'] = '(datoteka nije poslana)';
$lang['attachmentMailToLarge'] = '(datoteka prevelika za prilog pošte)';
$lang['attachmentMailToLarge_userinfo'] = 'datoteka "%s" prevelika za prilog pošte (>%s) (pošta je ipak poslana)';
$lang['submit'] = 'Proslijedi';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Davor Turkalj <turki.bsc@gmail.com>
*/
$lang['runas'] = 'Utječe na mod predloška. Koristi ove (virtualne) ovlasti kada provjeravaš ACL za čitanje predloška i stvaranje stranice.';
$lang['maxEmailAttachmentSize'] = 'Maksimalna veličina priloga pošti u Bajtovima. (po datoteci)';
+19
View File
@@ -0,0 +1,19 @@
<?php
$lang['e_unknowntype'] = 'Tipo sconosciuto "%s"';
$lang['e_missingargs'] = 'Gli argomenti specificati non sono sufficenti per %s %s';
$lang['e_noaction'] = 'Nessuna azione definita - dove devono essere spediti i dati ?';
$lang['e_mail'] = 'Si sono verificati dei problemi sulla spedizione dei dati';
$lang['e_required'] = '"%s" deve essere specificato';
$lang['e_match'] = '"%s" non corretto. %s';
$lang['checkagainst'] = '(Controlla /%s/i)';
$lang['e_email'] = '"%s" deve essere un indirizzo email valido.';
$lang['e_numeric'] = '"%s" deve essere un valore numerico.';
$lang['e_min'] = '"%s" deve essere maggiore di %s.';
$lang['e_max'] = '"%s" deve essere minore di %s.';
$lang['thanks'] = 'Le informazioni sono state inviate. Grazie.';
$lang['mailsubject'] = 'Dati inviati alle %s';
$lang['mailintro'] = 'Le seguenti informazioni sono state inviate alle %s.';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author HokkaidoPerson <dosankomali@yahoo.co.jp>
*/
$lang['e_unknowntype'] = '"%s" という型はありません。';
$lang['e_unknownaction'] = '不明なアクション「%s」';
$lang['e_missingargs'] = '%s %s には引数が十分ではありません。';
$lang['e_noaction'] = 'action が定義されていません - どこにデータを送信するのですか?';
$lang['e_mail'] = 'データの送信について何かがおかしいです。';
$lang['e_unknownconstraint'] = '%s という項目制約がありません。';
$lang['e_labelpage'] = '%s という Labelpage がありません。';
$lang['e_required'] = '"%s" が必要です。';
$lang['e_match'] = '"%s" が正しく記入されていません。%s';
$lang['checkagainst'] = '/%s/i と照合)';
$lang['e_email'] = '"%s" は有効なメールアドレスである必要があります。';
$lang['e_numeric'] = '"%s" は数字である必要があります。';
$lang['e_date'] = '"%s" は yyyy-mm-dd 形式の日付である必要があります。';
$lang['e_time'] = '「%s」は、型 (h)h:mm(:ss) に沿った適切な時刻である必要があります。';
$lang['e_user'] = '"%s" 既存のユーザー名である必要があります。';
$lang['e_users'] = '"%s" 既存のユーザー名のカンマ区切り一覧である必要があります。';
$lang['e_min'] = '"%s" は %s より大きい必要があります。';
$lang['e_max'] = '"%s" は %s より小さい必要があります。';
$lang['e_pagename'] = 'ページ名がありません。';
$lang['e_pageexists'] = '"%s" というページは既に存在します。別のページ名を選んで下さい。';
$lang['e_template'] = '"%s" というテンプレートが読めません。存在しないか読み込み権限がないのではないですか?';
$lang['e_denied'] = 'このページの作成は許可されません。ログインし忘れていませんか?';
$lang['mailsubject'] = 'フォームのデータは %s へ送信されました。';
$lang['mailintro'] = '以下のデータは %s に送信されました。';
$lang['mail_thanks'] = 'データは正常に送信されました。ありがとう。';
$lang['template_thanks'] = 'ページは作成されました。開くためにリンクをたどってください。';
$lang['summary'] = '%s のフォームから作成されました。';
$lang['attachmentMailEmpty'] = '(ファイル未選択)';
$lang['attachmentMailToLarge'] = '(メールに添付するにはファイルが大き過ぎます)';
$lang['attachmentMailToLarge_userinfo'] = 'ファイル「%s」はメールに添付するには大き過ぎます(>%s)(メール自体は送信されました)';
$lang['submit'] = '送信';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author HokkaidoPerson <dosankomali@yahoo.co.jp>
*/
$lang['runas'] = 'テンプレートモードに影響があります。テンプレートを読み込み、ページを作成するために ACL チェックする場合、この(仮想)ユーザーの権限を使用してください。';
$lang['maxEmailAttachmentSize'] = 'メールに添付するファイルの最大サイズ(バイト数/1ファイルごと)';
+30
View File
@@ -0,0 +1,30 @@
<?php
$lang['e_unknowntype'] = 'Nezināma tipa "%s"';
$lang['e_missingargs'] = 'Pietrūkst argumentu %s %s';
$lang['e_noaction'] = 'Nav definēta darbība, kur dati jāsūta vai jāievieto';
$lang['e_mail'] = 'Kļūme nosūtot datus';
$lang['e_required'] = 'Jāaizpilda "%s" ';
$lang['e_match'] = 'Nav pareizi aizpildīts "%s" %s';
$lang['checkagainst'] = '(neatbilst prasībai /%s/i)';
$lang['e_email'] = '"%s" jābūt derīgai epasta adresei.';
$lang['e_numeric'] = '"%s" jābūt skaitlim.';
$lang['e_min'] = '"%s" jābūt lielākam par %s.';
$lang['e_max'] = '"%s" jābūt mazākam par %s.';
$lang['e_pagename'] = 'Nav lapas nosaukuma.';
$lang['e_pageexists'] = 'Lapa "%s" jau eksistē. Lūdzu norādīt citu lapas vārdu.';
$lang['e_template'] = 'Nevar nolasīt šablonu "%s". Varbūt tāda nav vai pietrūkst lasīšanas tiesību?';
$lang['e_denied'] = 'Jums nav tiesību izveidot šo lapu, varbūt aizmirsāt ielogoties?';
$lang['mailsubject'] = 'Veidlapas dati nosūtīti uz %s';
$lang['mailintro'] = 'Norādīties dati nosūtīti uz %s.';
$lang['mail_thanks'] = 'Jūsu dati veiksmīgi nosūtīti. Paldies!';
$lang['template_thanks'] = 'Lapa izveidota, lai to atvērtu lieto šo saiti.';
$lang['summary'] = 'Izveidots no veidlapas %s';
$lang['submit'] = 'Saglabāt';
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Gerrit Uitslag <klapinklapin@gmail.com>
*/
$lang['e_unknowntype'] = 'Onbekend type "%s"';
$lang['e_unknownaction'] = 'Onbekende actie "%s"';
$lang['e_missingargs'] = 'Onvoldoende argumenten voor %s %s';
$lang['e_noaction'] = 'Geen aktie opgegeven - waar moeten de gegevens heen?';
$lang['e_mail'] = 'Het versturen van de gegevens is mislukt';
$lang['e_unknownconstraint'] = 'Onbekende veld voorwaarde %s';
$lang['e_labelpage'] = 'Labelpagina %s is niet gevonden';
$lang['e_required'] = '"%s" is verplicht';
$lang['e_match'] = '"%s" heeft een ongeldige waarde. %s';
$lang['checkagainst'] = '(Moet voldoen aan /%s/i)';
$lang['e_email'] = '"%s" moet een geldig e-mail adres zijn.';
$lang['e_numeric'] = '"%s" moet een nummer zijn.';
$lang['e_date'] = '"%s" moet een geldige datum zijn in het formaat jjjj-mm-dd.';
$lang['e_time'] = '"%s" moet een geldige tijdstip zijn in het formaat (u)u:mm(:ss)';
$lang['e_user'] = '"%s" moet de naam van een bestaande gebruiker zijn.';
$lang['e_users'] = '"%s" moet een komma-gescheiden lijst van bestaande gebruikers zijn.';
$lang['e_min'] = '"%s" moet groter zijn dan %s.';
$lang['e_max'] = '"%s" moet kleiner zijn dan %s.';
$lang['e_pagename'] = 'Pagina naam ontbreekt.';
$lang['e_pageexists'] = 'De pagina "%s" bestaat al. Kies een andere pagina naam.';
$lang['e_template'] = 'Kon de template "%s" niet lezen. wellicht bestaat de pagina niet of zijn de rechten onvoldoende?';
$lang['e_denied'] = 'Onvoldoende rechten om deze pagina te maken, niet ingelogd?';
$lang['mailsubject'] = 'Formulier gegevens verstuurd op %s';
$lang['mailintro'] = 'De volgende gegevens zijn verstuurd op %s.';
$lang['mail_thanks'] = 'De gegevens zijn verstuurt. Bedankt.';
$lang['template_thanks'] = 'De pagina is aangemaakt, volg de link om hem te openen.';
$lang['summary'] = 'Gemaakt door het formulier op %s';
$lang['attachmentMailEmpty'] = '(bestand niet ingediend)';
$lang['attachmentMailToLarge'] = '(bestand te groot voor een e-mailbijlage)';
$lang['attachmentMailToLarge_userinfo'] = 'bestand "%s" te groot voor de e-mailbijlage (>%s) (e-mail is niettemin verstuurd)';
$lang['submit'] = 'Submit';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Gerrit Uitslag <klapinklapin@gmail.com>
*/
$lang['runas'] = 'Gebruikt in de template mode. Gebruik de rechten van deze (virtuele) gebruiker bij het controleren van de ACL gebruiker voor het lezen van templates en het maken van pagina\'s';
$lang['maxEmailAttachmentSize'] = 'Max grootte van e-mailbijlages in Bytes. (per bestand)';
+39
View File
@@ -0,0 +1,39 @@
<?php
$lang['e_unknowntype'] = 'Ukjent type "%s"';
$lang['e_unknownaction'] = 'Ukjent handling "%s"';
$lang['e_missingargs'] = 'Ikke nok verdier for %s %s';
$lang['e_noaction'] = 'Ingen handling valgt - hvor skal dataene sendes til?';
$lang['e_mail'] = 'Det oppsto en feil ved innsending av dataene';
$lang['e_unknownconstraint'] = 'Ukjent feltverdi %s';
$lang['e_labelpage'] = 'Finner ikke siden %s';
$lang['e_required'] = '"%s" er påkrevet';
$lang['e_match'] = '"%s" var ikke riktig utfylt. %s';
$lang['checkagainst'] = '(Sjekk mot /%s/i)';
$lang['e_email'] = '"%s" må være gyldig epostadresse.';
$lang['e_numeric'] = '"%s" må være et nummer.';
$lang['e_date'] = '"%s" må være gyldig dato på formatet åååå-mm-dd.';
$lang['e_time'] = '"%s" må være gyldig tidsformat (t)t:mm(:ss).';
$lang['e_user'] = '"%s" må være navnet til en eksisterende bruker.';
$lang['e_users'] = '"%s" må være en komma-separert liste over eksisterende brukere.';
$lang['e_min'] = '"%s" må være større enn %s.';
$lang['e_max'] = '"%s" må være mindre enn %s.';
$lang['e_pagename'] = 'Sidenavn mangler.';
$lang['e_pageexists'] = 'Siden "%s" eksisterer allerede. Velg en anne side.';
$lang['e_template'] = 'Kan ikke lese malen "%s". Enten finnes den ikke eller så har du ikke leserettigheter?';
$lang['e_denied'] = 'Du har ikke tillatelse til å opprette denne siden, har du glemt å logge inn?';
$lang['mailsubject'] = 'Skjemaet ble sendt ved %s';
$lang['mailintro'] = 'Innholdet ble sendt på %s.';
$lang['mail_thanks'] = 'Skjemaet er sendt, takk skal du ha.';
$lang['template_thanks'] = 'Siden er opprettet, klikk på følgende link for å åpne siden.';
$lang['summary'] = 'Opprettet av skjemaet %s';
$lang['attachmentMailEmpty'] = '(filen er ikke bekreftet)';
$lang['attachmentMailToLarge'] = '(filen er for stor til å legges ved eposten)';
$lang['submit'] = 'Send';
@@ -0,0 +1,5 @@
<?php
$lang['runas'] = 'Påvirker malenes virkemåte. Bruk tillatelse for virituell bruker når du sjekker ACL for lesing av maler og opprettelse av sider.';
$lang['maxEmailAttachmentSize'] = 'Maksimalstørrelse for epostvedlegg i bytes. (pr. fil)';
@@ -0,0 +1,38 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Nilton Röhricht Junior <rohricht@gmail.com>
*/
$lang['e_unknowntype'] = 'Tipo desconhecido "%s".';
$lang['e_unknownaction'] = 'Ação desconhecida "%s"';
$lang['e_missingargs'] = 'Argumentos insuficientes para %s %s.';
$lang['e_noaction'] = 'Nenhuma ação definida - para onde deveriam os dados ser enviados?';
$lang['e_mail'] = 'Ocorreu algum erro com o envio dos dados.';
$lang['e_unknownconstraint'] = 'Restrição %s de campo desconhecida.';
$lang['e_labelpage'] = 'Página de etiquetas "%s" não encontrada';
$lang['e_required'] = '"%s" é requerido.';
$lang['e_match'] = '"%s" não foi corretamente preenchido. %s';
$lang['checkagainst'] = '(Comparado com /%s/i)';
$lang['e_email'] = '"%s" tem de ser um endereço de email válido.';
$lang['e_numeric'] = '"%s" tem de ser um número.';
$lang['e_date'] = '"%s" tem de ser uma data válida no formato dd-mm-yyyy.';
$lang['e_time'] = '"%s" tem de ser um horário válido no formato (h)h:mm(:ss).';
$lang['e_user'] = '"%s" tem de ser o nome de um usuário existente.';
$lang['e_users'] = '"%s" tem de ser uma lista de nomes de usuários existentes separados por vírgulas.';
$lang['e_min'] = '"%s" tem de ser maior que %s.';
$lang['e_max'] = '"%s" tem de ser menor que %s.';
$lang['e_pagename'] = 'Falta o nome da página.';
$lang['e_pageexists'] = 'A página "%s" já existe. Escolha outro nome de página.';
$lang['e_template'] = 'O modelo "%s" não pode ser lido. Talvez não exista ou você não tem permissão de lê-lo?';
$lang['e_denied'] = 'Você não pode criar esta página. Esqueceu-se de Entrar?';
$lang['mailsubject'] = 'Formulário de dados submetido em %s.';
$lang['mailintro'] = 'Os dados seguintes foram submetidos em %s.';
$lang['mail_thanks'] = 'Seus dados foram enviados com sucesso. Obrigado.';
$lang['template_thanks'] = 'A página foi criada, clique no link para abri-la.';
$lang['summary'] = 'Criada a partir do formulário em %s.';
$lang['attachmentMailEmpty'] = '(arquivo não enviado)';
$lang['attachmentMailToLarge'] = '(arquivo muito grande para anexo de e-mail)';
$lang['attachmentMailToLarge_userinfo'] = 'arquivo "%s" muito grande para anexo de e-mail (>%s) (mensagem enviada mesmo assim)';
$lang['submit'] = 'Enviar';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Nilton Röhricht Junior <rohricht@gmail.com>
*/
$lang['runas'] = 'Afeta o modo de template. Use estas permissões de usuário (virtual) quando verificando ACLs para leitura de templates e criação de páginas.';
$lang['maxEmailAttachmentSize'] = 'Tamanho máximo para anexos de e-mail em Bytes. (por arquivo)';
+39
View File
@@ -0,0 +1,39 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Daniel Dias Rodrigues <danieldiasr@gmail.com>
* @author Rafael Grando <r.grando@live.com>
*/
$lang['e_unknowntype'] = 'Tipo desconhecido "%s"';
$lang['e_unknownaction'] = 'Ação desconhecida "%s"';
$lang['e_missingargs'] = 'Argumentos insuficientes para %s %s';
$lang['e_noaction'] = 'Nenhuma ação definida - para onde os dados devem ser enviados?';
$lang['e_mail'] = 'Algo deu errado ao enviar esses dados';
$lang['e_unknownconstraint'] = 'Restrição de campo desconhecida %s';
$lang['e_labelpage'] = 'Labelpage %s não encontrada';
$lang['e_required'] = '"%s" é obrigatório';
$lang['e_match'] = '"%s" não foi preenchido corretamente. %s';
$lang['checkagainst'] = '(Verificado contra /%s/i)';
$lang['e_email'] = '"%s" precisa ser um endereço de email válido.';
$lang['e_numeric'] = '"%s" precisa ser um número.';
$lang['e_date'] = '"%s" precisa ser uma data válida no formato aaaa-mm-dd.';
$lang['e_time'] = '"%s" precisa ser um horário válido no formato (h)h:mm:(:ss).';
$lang['e_user'] = '"%s" precisa ser o nome de um usuário existente.';
$lang['e_users'] = '"%s" precisa ser uma lista separada por vírgulas de nomes de usuários existentes.';
$lang['e_min'] = '"%s" precisa ser maior que %s.';
$lang['e_max'] = '"%s" precisa ser menor que %s.';
$lang['e_pagename'] = 'Nome da página ausente.';
$lang['e_pageexists'] = 'A página "%s" já existe. Por favor, escolha um nome diferente para a página.';
$lang['e_template'] = 'Não foi possível ler o modelo "%s". Talvez ele não exista ou você não tenha permissões de leitura?';
$lang['e_denied'] = 'Você não está autorizado a criar esta página. Talvez tenha esquecido de entrar?';
$lang['mailsubject'] = 'Dados do formulário enviados às %s';
$lang['mailintro'] = 'Os dados a seguir foram enviados em %s.';
$lang['mail_thanks'] = 'Seus dados foram enviados com sucesso. Obrigado.';
$lang['template_thanks'] = 'A página foi criada, siga o link para abri-la.';
$lang['summary'] = 'Criado do formulário às %s.';
$lang['attachmentMailEmpty'] = '(arquivo não enviado)';
$lang['attachmentMailToLarge'] = '(arquivo muito grande para anexar ao email)';
$lang['attachmentMailToLarge_userinfo'] = 'arquivo "%s" é muito grande para anexar ao email (>%s) (email enviado mesmo assim)';
$lang['submit'] = 'Enviar';
@@ -0,0 +1,9 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Rafael Grando <r.grando@live.com>
*/
$lang['runas'] = 'Afeta o modo template. Use essas permissões (virtuais) de usuário quando checar ACLs para ler modelos e criar páginas.';
$lang['maxEmailAttachmentSize'] = 'Tamanho máximo de anexos em bytes. (por arquivo)';
+39
View File
@@ -0,0 +1,39 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Aleksandr Selivanov <alexgearbox@yandex.ru>
* @author Yuriy Skalko <yuriy.skalko@gmail.com>
*/
$lang['e_unknowntype'] = 'Неизвестный тип «%s»';
$lang['e_unknownaction'] = 'Неизвестное действие «%s»';
$lang['e_missingargs'] = 'Недостаточно аргументов для %s %s';
$lang['e_noaction'] = 'Не указано действие (action). Куда следует отправить данные?';
$lang['e_mail'] = 'Что-то пошло не так при отправке данных';
$lang['e_unknownconstraint'] = 'Неизвестный ограничитель поля %s';
$lang['e_labelpage'] = 'Не найдена страница меток: %s';
$lang['e_required'] = 'Поле «%s» обязательно для заполнения';
$lang['e_match'] = 'Поле «%s» заполнено неверно. %s';
$lang['checkagainst'] = '(Проверяется по /%s/i)';
$lang['e_email'] = 'Поле «%s» должно содержать корректный адрес электронной почты.';
$lang['e_numeric'] = 'Поле «%s» должно содержать число.';
$lang['e_date'] = 'Поле «%s» должно содержать корректную дату в формате ГГГГ-ММ-ДД';
$lang['e_time'] = 'Поле «%s» должно быть допустимым временем в формате (ч)ч:мм(:сс)';
$lang['e_user'] = 'Поле «%s» должно содержать имя существующего пользователя.';
$lang['e_users'] = 'Поле «%s» должно содержать разделённый запятыми перечень имён (логинов) зарегистрированных пользователей.';
$lang['e_min'] = 'Поле «%s» должно быть больше %s.';
$lang['e_max'] = 'Поле «%s» должно быть меньше %s.';
$lang['e_pagename'] = 'Отсутствует имя страницы.';
$lang['e_pageexists'] = 'Страница «%s» уже существует. Пожалуйста, выберите другое имя.';
$lang['e_template'] = 'Невозможно прочитать шаблон «%s». Возможно, он не существует, или у вас не хватает прав для чтения.';
$lang['e_denied'] = 'Вам не разрешено создавать эту страницу. Возможно, вы забыли войти?';
$lang['mailsubject'] = 'Данные формы отправлены с %s';
$lang['mailintro'] = 'Следующие данные отправлены %s.';
$lang['mail_thanks'] = 'Ваши данные отправлены успешно. Спасибо.';
$lang['template_thanks'] = 'Страница создана, следуйте по ссылке, чтобы открыть её.';
$lang['summary'] = 'Создано по форме с %s';
$lang['attachmentMailEmpty'] = '(файл не отправлен)';
$lang['attachmentMailToLarge'] = '(файл слишком большой для почтового вложения)';
$lang['attachmentMailToLarge_userinfo'] = 'файл «%s» слишком большой для почтового вложения (>%s) (само сообщение отправлено)';
$lang['submit'] = 'Отправить';
@@ -0,0 +1,10 @@
<?php
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Aleksandr Selivanov <alexgearbox@yandex.ru>
* @author Yuriy Skalko <yuriy.skalko@gmail.com>
*/
$lang['runas'] = '(Влияет на режим шаблона.) Использовать права этого (виртуального) пользователя при проверке доступа для чтения шаблонов и создания страниц.';
$lang['maxEmailAttachmentSize'] = 'Максимальный размер почтовых вложений в байтах. (на файл)';
+39
View File
@@ -0,0 +1,39 @@
<?php
$lang['e_unknowntype'] = '未知类型 "%s"';
$lang['e_unknownaction'] = '未知action "%s"';
$lang['e_missingargs'] = '参数不足: %s %s';
$lang['e_noaction'] = '未定义action - 数据要送到哪里去?';
$lang['e_mail'] = '发送该数据时发生错误';
$lang['e_unknownconstraint'] = '未知的域范围 %s';
$lang['e_labelpage'] = '标签页 %s 未找到';
$lang['e_required'] = '需要"%s"';
$lang['e_match'] = '"%s" 填写错误. %s';
$lang['checkagainst'] = '(请检查 /%s/i)';
$lang['e_email'] = '"%s" 应为有效Email地址。';
$lang['e_numeric'] = '"%s" 必须是数字';
$lang['e_date'] = '"%s" 应为 yyyy-mm-dd 格式的日期';
$lang['e_time'] = '"%s" 应为 (h)h:mm(:ss) 格式的时间';
$lang['e_user'] = '"%s" 应为存在的用户名';
$lang['e_users'] = '"%s" 应为逗号分隔的用户名列表';
$lang['e_min'] = '"%s" 应大于 %s.';
$lang['e_max'] = '"%s" 应小于 %s.';
$lang['e_pagename'] = '未输入文件名';
$lang['e_pageexists'] = '文件名 "%s" 已存在,请换一个名字。';
$lang['e_template'] = '无法读取模板 "%s". 也许它不存在或你没有读取权限?';
$lang['e_denied'] = '你不能创建该页面,也许您忘记登录了?';
$lang['mailsubject'] = '表单数据已向 %s 提交';
$lang['mailintro'] = '以下数据被提交在 %s.';
$lang['mail_thanks'] = '您的数据发送成功。谢谢。';
$lang['template_thanks'] = '页面已创建,点击以下链接查看。';
$lang['summary'] = '创建自 %s 的表单';
$lang['attachmentMailEmpty'] = '文件未提交';
$lang['attachmentMailToLarge'] = '邮件附件过大';
$lang['submit'] = '提交';
@@ -0,0 +1,5 @@
<?php
$lang['runas'] = '在template模式下起效。当读取模板和创建页面需要检查ACLs权限时,使用此(虚拟的)用户权限。';
$lang['maxEmailAttachmentSize'] = '邮件附件大小上限,以Bytes为单位。(每份附件)';
+2
View File
@@ -0,0 +1,2 @@
downloadurl=https://github.com/splitbrain/dokuwiki-plugin-bureaucracy/zipball/master
installed=Mon, 08 Jul 2024 01:01:01 +0900
+8
View File
@@ -0,0 +1,8 @@
base bureaucracy
author Andreas Gohr
email andi@splitbrain.org
date 2023-05-16
name Bureaucracy Plugin
desc Create forms and generate pages or emails from them
url https://www.dokuwiki.org/plugin:bureaucracy
+3
View File
@@ -0,0 +1,3 @@
/* DOKUWIKI:include script/fieldsets.js */
/* DOKUWIKI:include script/user.js */
/* DOKUWIKI:include script/datepicker.js */
@@ -0,0 +1,11 @@
/**
* Init datepicker for all date fields
*/
jQuery(function(){
jQuery('.bureaucracy__plugin .datepicker').datepicker({
dateFormat: "yy-mm-dd",
changeMonth: true,
changeYear: true
});
});
@@ -0,0 +1,84 @@
/**
* Handle display of dependent, i. e. optional fieldsets
*
* Fieldsets may be defined as dependent on the value of a certain input. In
* this case they contain a p element with the CSS class “bureaucracy_depends”.
* This p element holds a span with the class “bureaucracy_depends_fname”
* and optionally another span with “bureaucracy_depends_fvalue”. They
* specify the target input (fname) and the target value for which the fieldset
* is to be shown.
*
* This function adds onchange handlers to the relevant inputs for showing and
* heading the respective fieldsets.
*
* @author Adrian Lang <dokuwiki@cosmocode.de>
**/
jQuery(function () {
jQuery('form.bureaucracy__plugin').each(function () {
//show/hide fieldset and trigger depending children
function updateFieldset(input) {
jQuery.each(jQuery(input).data('dparray'), function (i, dp) {
var showOrHide =
input.parentNode.parentNode.style.display !== 'none' && // input/checkbox is displayed AND
((input.checked === dp.tval) || // ( checkbox is checked
(input.type !== 'checkbox' && (dp.tval === true && input.value !== '')) || // OR no checkbox, but input is set
input.value === dp.tval); // OR input === dp.tval )
dp.fset.toggle(showOrHide);
dp.fset.find('input,select')
.each(function () {
//toggle required attribute
var $inputelem = jQuery(this);
if($inputelem.hasClass('required')) {
if(showOrHide) {
$inputelem.attr('required', 'required');
} else {
$inputelem.removeAttr('required')
}
}
//update dependencies
if ($inputelem.data('dparray')) {
$inputelem.change();
}
});
});
}
//look for p (with info about controller) in depending fieldsets
jQuery('p.bureaucracy_depends', this)
.each(function () {
//get controller info
var fname = jQuery(this).find('span.bureaucracy_depends_fname').html(),
fvalue = jQuery(this).find('span.bureaucracy_depends_fvalue');
fvalue = (fvalue.length ? fvalue.html() : true);
//get controller field and add info and change event to the input that controls depending fieldset
var fieldsetinfo = {
fset: jQuery(this).parent(),
tval: fvalue
};
jQuery("label")
.has(":first-child:contains('" + fname + "')").first()
.find("select,input:last") //yesno field contains first a hidden input
.each(function () {
if (!jQuery(this).data('dparray')) {
jQuery(this).data('dparray', [fieldsetinfo]);
} else {
jQuery(this).data('dparray').push(fieldsetinfo);
}
})
.bind('change keyup', function () {
updateFieldset(this);
})
.change();
})
.hide(); //hide p.bureaucracy_depends in fieldset
});
});
+90
View File
@@ -0,0 +1,90 @@
/**
* Provides a list of matching user names while user inputs into a userpicker
*
* @author Adrian Lang <lang@cosmocode.de>
* @author Gerrit Uitslag <klapinklapin@gmail.com>
*/
jQuery(function () {
/**
* Ajax request for user suggestions
*
* @param {Object} request object, with single 'term' property
* @param {Function} response callback, argument: the data array to suggest to the user.
* @param {Function} getterm callback, argument: the request Object, returns: search term
*/
function ajaxsource(request, response, getterm) {
jQuery.getJSON(
DOKU_BASE + 'lib/exe/ajax.php', {
call: 'bureaucracy_user_field',
search: getterm(request)
}, function (data) {
response(jQuery.map(data, function (name, user) {
return {
label: name + ' (' + user + ')',
value: user
}
}))
}
);
}
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
/**
* pick one user
*/
jQuery(".userpicker").autocomplete({
source: function (request, response) {
ajaxsource(request, response, function (req) {
return req.term
})
}
});
/**
* pick one or more users
*/
jQuery(".userspicker")
// don't navigate away from the field on tab when selecting an item
.bind("keydown", function (event) {
if (event.keyCode === jQuery.ui.keyCode.TAB &&
jQuery(this).data("ui-autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function (request, response) {
ajaxsource(request, response, function (req) {
return extractLast(req.term)
})
},
search: function () {
// custom minLength
var term = extractLast(this.value);
return term.length >= 2;
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
});
+101
View File
@@ -0,0 +1,101 @@
/* Success message */
.dokuwiki div.bureaucracy__plugin {
width: 50%;
font-size: 120%;
padding: 2em;
}
/* Form */
.dokuwiki form.bureaucracy__plugin {
width: 100%;
text-align: center;
margin: 2em 0;
display: block;
}
.dokuwiki form.bureaucracy__plugin p {
font-size: 90%;
margin-top: 0.5em;
}
.dokuwiki form.bureaucracy__plugin fieldset {
width: 80%;
text-align: left;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.dokuwiki form.bureaucracy__plugin label {
display: block;
text-align: right;
line-height: 2em;
}
.dokuwiki form.bureaucracy__plugin label>span {
display: inline-block;
width: 47%;
line-height: normal;
}
.dokuwiki form.bureaucracy__plugin label.textareafield {
text-align: left;
}
.dokuwiki form.bureaucracy__plugin label.textareafield>span {
width: 100%;
}
.dokuwiki form.bureaucracy__plugin label input.edit,
.dokuwiki form.bureaucracy__plugin label select {
width: 50%;
}
.dokuwiki form.bureaucracy__plugin label input.datepicker,
.dokuwiki form.bureaucracy__plugin label input.timefield {
width: 25%;
margin-right: 25%;
}
.dokuwiki form.bureaucracy__plugin label textarea.edit {
width: 100%;
}
.dokuwiki form.bureaucracy__plugin label input[type=checkbox] {
width: 5%;
margin-right: 45%;
}
.dokuwiki form.bureaucracy__plugin input.button {
margin: 3px 0 3px 50%;
display: block;
}
.dokuwiki form.bureaucracy__plugin label.radiolabel span{
width: 100%;
text-align: left;
}
.dokuwiki form.bureaucracy__plugin label input[type=radio]~span {
width: 50%;
display: inline-block;
text-align: left;
line-height: normal;
}
.dokuwiki form.bureaucracy__plugin label.bureaucracy_error span {
color: #F00;
}
.dokuwiki form.bureaucracy__plugin #plugin__captcha_wrapper label {
text-align: left;
}
/*responsive - small screen*/
@media (max-width: 480px) {
.dokuwiki form.bureaucracy__plugin label {
text-align: left;
}
.dokuwiki form.bureaucracy__plugin label>span {
width: 100%;
}
.dokuwiki form.bureaucracy__plugin input.button {
margin-left: 0;
}
.dokuwiki form.bureaucracy__plugin label .edit,
.dokuwiki form.bureaucracy__plugin label select {
width: 100% !important;
}
}
+625
View File
@@ -0,0 +1,625 @@
<?php
/**
* Bureaucracy Plugin: Allows flexible creation of forms
*
* This plugin allows definition of forms in wiki pages. The forms can be
* submitted via email or used to create new pages from templates.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Andreas Gohr <andi@splitbrain.org>
* @author Adrian Lang <dokuwiki@cosmocode.de>
*/
// must be run within Dokuwiki
use dokuwiki\Utf8\PhpString;
if(!defined('DOKU_INC')) die();
/**
* All DokuWiki plugins to extend the parser/rendering mechanism
* need to inherit from this class
*/
class syntax_plugin_bureaucracy extends DokuWiki_Syntax_Plugin {
private $form_id = 0;
var $patterns = array();
var $values = array();
var $noreplace = null;
var $functions = array();
/**
* Prepare some replacements
*/
public function __construct() {
$this->prepareDateTimereplacements();
$this->prepareNamespacetemplateReplacements();
$this->prepareFunctions();
}
/**
* What kind of syntax are we?
*/
public function getType() {
return 'substition';
}
/**
* What about paragraphs?
*/
public function getPType() {
return 'block';
}
/**
* Where to sort in?
*/
public function getSort() {
return 155;
}
/**
* Connect pattern to lexer
*
* @param string $mode
*/
public function connectTo($mode) {
$this->Lexer->addSpecialPattern('<form>.*?</form>', $mode, 'plugin_bureaucracy');
}
/**
* Handler to prepare matched data for the rendering process
*
* @param string $match The text matched by the patterns
* @param int $state The lexer state for the match
* @param int $pos The character position of the matched text
* @param Doku_Handler $handler The Doku_Handler object
* @return bool|array Return an array with all data you want to use in render, false don't add an instruction
*/
public function handle($match, $state, $pos, Doku_Handler $handler) {
$match = substr($match, 6, -7); // remove form wrap
$lines = explode("\n", $match);
$actions = $rawactions = array();
$thanks = '';
$labels = '';
// parse the lines into an command/argument array
$cmds = array();
while(count($lines) > 0) {
$line = trim(array_shift($lines));
if(!$line) continue;
$args = $this->_parse_line($line, $lines);
$args[0] = $this->_sanitizeClassName($args[0]);
if(in_array($args[0], array('action', 'thanks', 'labels'))) {
if(count($args) < 2) {
msg(sprintf($this->getLang('e_missingargs'), hsc($args[0]), hsc($args[1])), -1);
continue;
}
// is action element?
if($args[0] == 'action') {
array_shift($args);
$rawactions[] = array('type' => array_shift($args), 'argv' => $args);
continue;
}
// is thank you text?
if($args[0] == 'thanks') {
$thanks = $args[1];
continue;
}
// is labels?
if($args[0] == 'labels') {
$labels = $args[1];
continue;
}
}
if(strpos($args[0], '_') === false) {
$name = 'bureaucracy_field' . $args[0];
} else {
//name convention: plugin_componentname
$name = $args[0];
}
/** @var helper_plugin_bureaucracy_field $field */
$field = $this->loadHelper($name, false);
if($field && is_a($field, 'helper_plugin_bureaucracy_field')) {
$field->initialize($args);
$cmds[] = $field;
} else {
$evdata = array('fields' => &$cmds, 'args' => $args);
$event = new Doku_Event('PLUGIN_BUREAUCRACY_FIELD_UNKNOWN', $evdata);
if($event->advise_before()) {
msg(sprintf($this->getLang('e_unknowntype'), hsc($name)), -1);
}
}
}
// check if action is available
foreach($rawactions as $action) {
$action['type'] = $this->_sanitizeClassName($action['type']);
if(strpos($action['type'], '_') === false) {
$action['actionname'] = 'bureaucracy_action' . $action['type'];
} else {
//name convention for other plugins: plugin_componentname
$action['actionname'] = $action['type'];
}
list($plugin, $component) = explode('_', $action['actionname']);
$alternativename = $action['type'] . '_'. $action['type'];
// bureaucracy_action<name> or <plugin>_<componentname>
if(!plugin_isdisabled($action['actionname']) || @file_exists(DOKU_PLUGIN . $plugin . '/helper/' . $component . '.php')) {
$actions[] = $action;
// shortcut for other plugins with component name <name>_<name>
} elseif(plugin_isdisabled($alternativename) || !@file_exists(DOKU_PLUGIN . $action['type'] . '/helper/' . $action['type'] . '.php')) {
$action['actionname'] = $alternativename;
$actions[] = $action;
// not found
} else {
$evdata = array('actions' => &$actions, 'action' => $action);
$event = new Doku_Event('PLUGIN_BUREAUCRACY_ACTION_UNKNOWN', $evdata);
if($event->advise_before()) {
msg(sprintf($this->getLang('e_unknownaction'), hsc($action['actionname'])), -1);
}
}
}
// action(s) found?
if(count($actions) < 1) {
msg($this->getLang('e_noaction'), -1);
}
// set thank you message
if(!$thanks) {
$thanks = "";
foreach($actions as $action) {
$thanks .= $this->getLang($action['type'] . '_thanks');
}
} else {
$thanks = hsc($thanks);
}
return array(
'fields' => $cmds,
'actions' => $actions,
'thanks' => $thanks,
'labels' => $labels
);
}
/**
* Handles the actual output creation.
*
* @param string $format output format being rendered
* @param Doku_Renderer $R the current renderer object
* @param array $data data created by handler()
* @return boolean rendered correctly? (however, returned value is not used at the moment)
*/
public function render($format, Doku_Renderer $R, $data) {
if($format != 'xhtml') return false;
$R->info['cache'] = false; // don't cache
/**
* replace some time and name placeholders in the default values
* @var $field helper_plugin_bureaucracy_field
*/
foreach($data['fields'] as &$field) {
if(isset($field->opt['value'])) {
$field->opt['value'] = $this->replace($field->opt['value']);
}
}
if($data['labels']) $this->loadlabels($data);
$this->form_id++;
if(isset($_POST['bureaucracy']) && checkSecurityToken() && $_POST['bureaucracy']['$$id'] == $this->form_id) {
$success = $this->_handlepost($data);
if($success !== false) {
$R->doc .= '<div class="bureaucracy__plugin" id="scroll__here">' . $success . '</div>';
return true;
}
}
$R->doc .= $this->_htmlform($data['fields']);
return true;
}
/**
* Initializes the labels, loaded from a defined labelpage
*
* @param array $data all data passed to render()
*/
protected function loadlabels(&$data) {
global $INFO;
$labelpage = $data['labels'];
$exists = false;
resolve_pageid($INFO['namespace'], $labelpage, $exists);
if(!$exists) {
msg(sprintf($this->getLang('e_labelpage'), html_wikilink($labelpage)), -1);
return;
}
// parse simple list (first level cdata only)
$labels = array();
$instructions = p_cached_instructions(wikiFN($labelpage));
$inli = 0;
$item = '';
foreach($instructions as $instruction) {
if($instruction[0] == 'listitem_open') {
$inli++;
continue;
}
if($inli === 1 && $instruction[0] == 'cdata') {
$item .= $instruction[1][0];
}
if($instruction[0] == 'listitem_close') {
$inli--;
if($inli === 0) {
list($k, $v) = explode('=', $item, 2);
$k = trim($k);
$v = trim($v);
if($k && $v) $labels[$k] = $v;
$item = '';
}
}
}
// apply labels to all fields
$len = count($data['fields']);
for($i = 0; $i < $len; $i++) {
if(isset($data['fields'][$i]->depends_on)) {
// translate dependency on fieldsets
$label = $data['fields'][$i]->depends_on[0];
if(isset($labels[$label])) {
$data['fields'][$i]->depends_on[0] = $labels[$label];
}
} else if(isset($data['fields'][$i]->opt['label'])) {
// translate field labels
$label = $data['fields'][$i]->opt['label'];
if(isset($labels[$label])) {
$data['fields'][$i]->opt['display'] = $labels[$label];
}
}
}
if(isset($data['thanks'])) {
if(isset($labels[$data['thanks']])) {
$data['thanks'] = $labels[$data['thanks']];
}
}
}
/**
* Validate posted data, perform action(s)
*
* @param array $data all data passed to render()
* @return bool|string
* returns thanks message when fields validated and performed the action(s) succesfully;
* otherwise returns false.
*/
private function _handlepost($data) {
$success = true;
foreach($data['fields'] as $index => $field) {
/** @var $field helper_plugin_bureaucracy_field */
$isValid = true;
if($field->getFieldType() === 'file') {
$file = array();
foreach($_FILES['bureaucracy'] as $key => $value) {
$file[$key] = $value[$index];
}
$isValid = $field->handle_post($file, $data['fields'], $index, $this->form_id);
} elseif($field->getFieldType() === 'fieldset' || !$field->hidden) {
$isValid = $field->handle_post($_POST['bureaucracy'][$index] ?? null, $data['fields'], $index, $this->form_id);
}
if(!$isValid) {
// Do not return instantly to allow validation of all fields.
$success = false;
}
}
if(!$success) {
return false;
}
$thanks_array = array();
foreach($data['actions'] as $actionData) {
/** @var helper_plugin_bureaucracy_action $action */
$action = $this->loadHelper($actionData['actionname'], false);
// action helper found?
if(!$action) {
msg(sprintf($this->getLang('e_unknownaction'), hsc($actionData['actionname'])), -1);
return false;
}
try {
$thanks_array[] = $action->run(
$data['fields'],
$data['thanks'],
$actionData['argv']
);
} catch(Exception $e) {
msg($e->getMessage(), -1);
return false;
}
}
// Perform after_action hooks
foreach($data['fields'] as $field) {
$field->after_action();
}
// create thanks string
$thanks = implode('', array_unique($thanks_array));
return $thanks;
}
/**
* Create the form
*
* @param helper_plugin_bureaucracy_field[] $fields array with form fields
* @return string html of the form
*/
private function _htmlform($fields) {
global $INFO;
$form = new Doku_Form(array('class' => 'bureaucracy__plugin',
'id' => 'bureaucracy__plugin' . $this->form_id,
'enctype' => 'multipart/form-data'));
$form->addHidden('id', $INFO['id']);
$form->addHidden('bureaucracy[$$id]', $this->form_id);
foreach($fields as $id => $field) {
$field->renderfield(array('name' => 'bureaucracy[' . $id . ']'), $form, $this->form_id);
}
return $form->getForm();
}
/**
* Parse a line into (quoted) arguments
* Splits line at spaces, except when quoted
*
* @author William Fletcher <wfletcher@applestone.co.za>
*
* @param string $line line to parse
* @param array $lines all remaining lines
* @return array with all the arguments
*/
private function _parse_line($line, &$lines) {
$args = array();
$inQuote = false;
$escapedQuote = false;
$arg = '';
do {
$len = strlen($line);
for($i = 0; $i < $len; $i++) {
if($line[$i] == '"') {
if($inQuote) {
if($escapedQuote) {
$arg .= '"';
$escapedQuote = false;
continue;
}
if($i + 1 < $len && $line[$i + 1] == '"') {
$escapedQuote = true;
continue;
}
array_push($args, $arg);
$inQuote = false;
$arg = '';
continue;
} else {
$inQuote = true;
continue;
}
} else if($line[$i] == ' ') {
if($inQuote) {
$arg .= ' ';
continue;
} else {
if(strlen($arg) < 1) continue;
array_push($args, $arg);
$arg = '';
continue;
}
}
$arg .= $line[$i];
}
if(!$inQuote || count($lines) === 0) break;
$line = array_shift($lines);
$arg .= "\n";
} while(true);
if(strlen($arg) > 0) array_push($args, $arg);
return $args;
}
/**
* Clean class name
*
* @param string $classname
* @return string cleaned name
*/
private function _sanitizeClassName($classname) {
return preg_replace('/[^\w\x7f-\xff]/', '', strtolower($classname));
}
/**
* Save content in <noreplace> tags into $this->noreplace
*
* @param string $input The text to work on
*/
protected function noreplace_save($input) {
$pattern = '/<noreplace>(.*?)<\/noreplace>/is';
//save content of <noreplace> tags
preg_match_all($pattern, $input, $matches);
$this->noreplace = $matches[1];
}
/**
* Apply replacement patterns and values as prepared earlier
* (disable $strftime to prevent double replacements with default strftime() replacements in nstemplate)
*
* @param string $input The text to work on
* @param bool $strftime Apply strftime() replacements
* @return string processed text
*/
function replace($input, $strftime = true) {
//in helper_plugin_struct_field::setVal $input can be an array
//just return $input in that case
if (!is_string($input)) return $input;
if (is_null($this->noreplace)) $this->noreplace_save($input);
foreach ($this->values as $label => $value) {
$pattern = $this->patterns[$label];
if (is_callable($value)) {
$input = preg_replace_callback(
$pattern,
$value,
$input
);
} else {
$input = preg_replace($pattern, $value, $input);
}
}
if($strftime) {
$input = preg_replace_callback(
'/%./',
function($m){return strftime($m[0]);},
$input
);
}
// user syntax: %%.(.*?)
// strftime() is already applied once, so syntax is at this point: %.(.*?)
$input = preg_replace_callback(
'/@DATE\((.*?)(?:,\s*(.*?))?\)@/',
array($this, 'replacedate'),
$input
);
//run functions
foreach ($this->functions as $name => $callback) {
$pattern = '/@' . preg_quote($name) . '\((.*?)\)@/';
if (is_callable($callback)) {
$input = preg_replace_callback($pattern, function ($matches) use ($callback) {
return call_user_func($callback, $matches[1]);
}, $input);
}
}
//replace <noreplace> tags with their original content
$pattern = '/<noreplace>.*?<\/noreplace>/is';
if (is_array($this->noreplace)) foreach ($this->noreplace as $nr) {
$input = preg_replace($pattern, $nr, $input, 1);
}
return $input;
}
/**
* (callback) Replace date by request datestring
* e.g. '%m(30-11-1975)' is replaced by '11'
*
* @param array $match with [0]=>whole match, [1]=> first subpattern, [2] => second subpattern
* @return string
*/
function replacedate($match) {
global $conf;
//no 2nd argument for default date format
$match[2] = $match[2] ?? $conf['dformat'];
return strftime($match[2], strtotime($match[1]));
}
/**
* Same replacements as applied at template namespaces
*
* @see parsePageTemplate()
*/
function prepareNamespacetemplateReplacements() {
/* @var Input $INPUT */
global $INPUT;
global $INFO;
global $USERINFO;
global $conf;
global $ID;
$this->patterns['__formpage_id__'] = '/@FORMPAGE_ID@/';
$this->patterns['__formpage_ns__'] = '/@FORMPAGE_NS@/';
$this->patterns['__formpage_curns__'] = '/@FORMPAGE_CURNS@/';
$this->patterns['__formpage_file__'] = '/@FORMPAGE_FILE@/';
$this->patterns['__formpage_!file__'] = '/@FORMPAGE_!FILE@/';
$this->patterns['__formpage_!file!__'] = '/@FORMPAGE_!FILE!@/';
$this->patterns['__formpage_page__'] = '/@FORMPAGE_PAGE@/';
$this->patterns['__formpage_!page__'] = '/@FORMPAGE_!PAGE@/';
$this->patterns['__formpage_!!page__'] = '/@FORMPAGE_!!PAGE@/';
$this->patterns['__formpage_!page!__'] = '/@FORMPAGE_!PAGE!@/';
$this->patterns['__user__'] = '/@USER@/';
$this->patterns['__name__'] = '/@NAME@/';
$this->patterns['__mail__'] = '/@MAIL@/';
$this->patterns['__date__'] = '/@DATE@/';
// replace placeholders
$localid = isset($INFO['id']) ? $INFO['id'] : $ID;
$file = noNS($localid);
$page = strtr($file, $conf['sepchar'], ' ');
$this->values['__formpage_id__'] = $localid;
$this->values['__formpage_ns__'] = getNS($localid);
$this->values['__formpage_curns__'] = curNS($localid);
$this->values['__formpage_file__'] = $file;
$this->values['__formpage_!file__'] = PhpString::ucfirst($file);
$this->values['__formpage_!file!__'] = PhpString::strtoupper($file);
$this->values['__formpage_page__'] = $page;
$this->values['__formpage_!page__'] = PhpString::ucfirst($page);
$this->values['__formpage_!!page__'] = PhpString::ucwords($page);
$this->values['__formpage_!page!__'] = PhpString::strtoupper($page);
$this->values['__user__'] = $INPUT->server->str('REMOTE_USER');
$this->values['__name__'] = $USERINFO['name'] ?? '';
$this->values['__mail__'] = $USERINFO['mail'] ?? '';
$this->values['__date__'] = strftime($conf['dformat']);
}
/**
* Date time replacements
*/
function prepareDateTimereplacements() {
$this->patterns['__year__'] = '/@YEAR@/';
$this->patterns['__month__'] = '/@MONTH@/';
$this->patterns['__monthname__'] = '/@MONTHNAME@/';
$this->patterns['__day__'] = '/@DAY@/';
$this->patterns['__time__'] = '/@TIME@/';
$this->patterns['__timesec__'] = '/@TIMESEC@/';
$this->values['__year__'] = date('Y');
$this->values['__month__'] = date('m');
$this->values['__monthname__'] = date('B');
$this->values['__day__'] = date('d');
$this->values['__time__'] = date('H:i');
$this->values['__timesec__'] = date('H:i:s');
}
/**
* Functions that can be used after replacements
*/
function prepareFunctions() {
$this->functions['curNS'] = 'curNS';
$this->functions['getNS'] = 'getNS';
$this->functions['noNS'] = 'noNS';
$this->functions['p_get_first_heading'] = 'p_get_first_heading';
}
}