diff options
380 files changed, 12452 insertions, 10973 deletions
diff --git a/.github/workflows/autoFix.yml b/.github/workflows/autoFix.yml new file mode 100644 index 000000000..a16ee8a98 --- /dev/null +++ b/.github/workflows/autoFix.yml @@ -0,0 +1,50 @@ +name: "Auto-Fix code" +on: + push: + branches: + - master + +jobs: + autofix: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + tools: phpcbf, rector + + - name: Setup Cache + uses: actions/cache@v3 + with: + path: _test/.rector-cache + key: ${{ runner.os }}-rector-${{ hashFiles('_test/rector.php') }} + + - name: Run Rector + run: rector process --config _test/rector.php --no-diffs + + - name: Run PHP CodeSniffer autofixing + run: phpcbf --standard=_test/phpcs_MigrationAdjustments.xml + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4 + with: + commit-message: "🤖 Rector and PHPCS fixes" + title: "🤖 Automatic code style fixes" + body: | + These changes were made automatically by running rector and phpcbf. + + Please carefully check the changes before merging. Please note that + unit tests are not run for automated pull requests - so if in doubt, + manually test the branch before merging. + + If you disagree with the changes, simply clean the code yourself and + create a new pull request. This PR automatically closes when no more + changes are suggested by rector and phpcbf. + delete-branch: true + branch: "bot/autofix" diff --git a/.github/workflows/deletedFiles.yml b/.github/workflows/deletedFiles.yml index 885c98190..d26fa0f7c 100644 --- a/.github/workflows/deletedFiles.yml +++ b/.github/workflows/deletedFiles.yml @@ -33,7 +33,8 @@ jobs: - name: Create Pull Request uses: peter-evans/create-pull-request@v4 with: - commit-message: "Update deleted files" - title: "Update deleted files" + commit-message: "🤖 Update deleted files" + title: "🤖 Update deleted files" body: "This updates the list of deleted files based on the recent changes." delete-branch: true + branch: "bot/deletedFiles" diff --git a/.github/workflows/phpCS.yml b/.github/workflows/phpCS.yml index 214a8ea78..5dad99ef8 100644 --- a/.github/workflows/phpCS.yml +++ b/.github/workflows/phpCS.yml @@ -16,13 +16,15 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.2' tools: cs2pr, phpcs - name: run PHP codesniffer - run: phpcs -q --standard=_test/phpcs_MigrationAdjustments.xml --report=checkstyle | cs2pr + run: phpcs -q --standard=_test/phpcs_MigrationAdjustments.xml diff --git a/.gitignore b/.gitignore index 57cf99312..6c49271d7 100644 --- a/.gitignore +++ b/.gitignore @@ -98,3 +98,4 @@ _test/vendor/*/*/tests/* phpunit.phar *.phpunit.result.cache _test/data/ +_test/.rector-cache/ diff --git a/_test/phpcs.xml b/_test/phpcs.xml index 8f0d4dd24..feecafc03 100644 --- a/_test/phpcs.xml +++ b/_test/phpcs.xml @@ -25,14 +25,11 @@ <!-- 3rd party libs, these should be moved to composer some day --> <exclude-pattern>*/inc/DifferenceEngine.php</exclude-pattern> - <exclude-pattern>*/inc/IXR_Library.php</exclude-pattern> - <exclude-pattern>*/inc/JSON.php</exclude-pattern> <exclude-pattern>*/inc/JpegMeta.php</exclude-pattern> <exclude-pattern>*/lib/plugins/authad/adLDAP</exclude-pattern> <!-- deprecated files to be removed soon --> - <exclude-pattern>*/inc/cli.php</exclude-pattern> - <exclude-pattern>*/inc/parser/*</exclude-pattern> + <exclude-pattern>*/inc/parser/parser.php</exclude-pattern> <!-- rules on top of PSR-12 --> <rule ref="PSR12"> @@ -64,6 +61,8 @@ <exclude-pattern>*/lib/plugins/*/remote/*.php</exclude-pattern> <exclude-pattern>*/lib/plugins/*/syntax.php</exclude-pattern> <exclude-pattern>*/lib/plugins/*/syntax/*.php</exclude-pattern> + + <exclude-pattern>*/inc/parser/*</exclude-pattern> </rule> <!-- underscore skips exposing public methods to remote api --> @@ -71,10 +70,18 @@ <exclude-pattern>*/inc/Extension/RemotePlugin.php</exclude-pattern> <exclude-pattern>*/lib/plugins/*/remote.php</exclude-pattern> <exclude-pattern>*/lib/plugins/*/remote/*.php</exclude-pattern> + + <exclude-pattern>*/inc/parser/*</exclude-pattern> + </rule> + + <rule ref="PSR2.Classes.PropertyDeclaration.Underscore"> + <exclude-pattern>*/inc/parser/*</exclude-pattern> </rule> <rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"> <exclude-pattern>*/inc/Extension/PluginInterface.php</exclude-pattern> <exclude-pattern>*/inc/Extension/PluginTrait.php</exclude-pattern> + + <exclude-pattern>*/inc/parser/*</exclude-pattern> </rule> </ruleset> diff --git a/_test/phpcs_MigrationAdjustments.xml b/_test/phpcs_MigrationAdjustments.xml index b56ffc12b..ce571b7fd 100644 --- a/_test/phpcs_MigrationAdjustments.xml +++ b/_test/phpcs_MigrationAdjustments.xml @@ -2,82 +2,8 @@ <ruleset name="Migration Adjustments for the DokuWiki Coding Standard Standard" namespace="DokuWiki\CS\Standard"> <description>These are exceptions to the Coding Standard used for DokuWiki that are intended to be removed over time.</description> - <!-- rules on top of PSR-12 --> + <!-- extend the standard configuration --> <rule ref="./phpcs.xml"> - <!-- Rules with automatic fixes that we want to adhere to, but currently don't --> - <exclude name="Generic.Formatting.DisallowMultipleStatements.SameLine"/> - <exclude name="Generic.Functions.FunctionCallArgumentSpacing.NoSpaceAfterComma"/> - <exclude name="Generic.Functions.FunctionCallArgumentSpacing.SpaceBeforeComma"/> - <exclude name="Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma"/> - <exclude name="Generic.PHP.LowerCaseKeyword.Found"/> - <exclude name="Generic.PHP.LowerCaseConstant.Found"/> - <exclude name="Generic.WhiteSpace.ScopeIndent.IncorrectExact"/> - <exclude name="Generic.WhiteSpace.ScopeIndent.Incorrect"/> - <exclude name="Generic.WhiteSpace.IncrementDecrementSpacing.SpaceAfterDecrement"/> - <exclude name="Generic.WhiteSpace.IncrementDecrementSpacing.SpaceAfterIncrement"/> - - <exclude name="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseParenthesis"/> - <exclude name="Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword"/> - <exclude name="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseBrace"/> - <exclude name="Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace"/> - <exclude name="Squiz.ControlStructures.ForEachLoopDeclaration.NoSpaceBeforeArrow"/> - <exclude name="Squiz.ControlStructures.ForEachLoopDeclaration.NoSpaceAfterArrow"/> - <exclude name="Squiz.ControlStructures.ForEachLoopDeclaration.SpacingBeforeAs"/> - <exclude name="Squiz.ControlStructures.ForLoopDeclaration.SpacingAfterSecond"/> - <exclude name="Squiz.ControlStructures.ForLoopDeclaration.NoSpaceAfterSecond"/> - <exclude name="Squiz.ControlStructures.ForLoopDeclaration.NoSpaceAfterFirst"/> - <exclude name="Squiz.Functions.FunctionDeclarationArgumentSpacing.NoSpaceBeforeArg"/> - <exclude name="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpaceAfterEquals"/> - <exclude name="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterReference"/> - <exclude name="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingBeforeClose"/> - <exclude name="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpaceBeforeEquals"/> - <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine"/> - <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.NewlineBeforeOpenBrace"/> - <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.CloseBracketLine"/> - <exclude name="Squiz.WhiteSpace.ControlStructureSpacing.SpacingAfterOpen"/> - <exclude name="Squiz.WhiteSpace.ControlStructureSpacing.SpacingBeforeClose"/> - <exclude name="Squiz.WhiteSpace.ScopeClosingBrace.ContentBefore"/> - <exclude name="Squiz.WhiteSpace.ScopeClosingBrace.Indent"/> - <exclude name="Squiz.WhiteSpace.SuperfluousWhitespace.EndLine"/> - - <exclude name="PSR2.Classes.ClassDeclaration.CloseBraceAfterBody"/> - <exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/> - <exclude name="PSR2.Classes.PropertyDeclaration.StaticBeforeVisibility"/> - <exclude name="PSR2.ControlStructures.ControlStructureSpacing.SpacingAfterOpenBrace"/> - <exclude name="PSR2.ControlStructures.ControlStructureSpacing.SpaceBeforeCloseBrace"/> - <exclude name="PSR2.ControlStructures.ElseIfDeclaration.NotAllowed"/> - <exclude name="PSR2.ControlStructures.SwitchDeclaration.BreakIndent"/> - <exclude name="PSR2.ControlStructures.SwitchDeclaration.BreakNotNewLine"/> - <exclude name="PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLineCASE"/> - <exclude name="PSR2.ControlStructures.SwitchDeclaration.SpaceBeforeColonDEFAULT"/> - <exclude name="PSR2.ControlStructures.SwitchDeclaration.SpaceBeforeColonCASE"/> - <exclude name="PSR2.Files.EndFileNewline.TooMany"/> - <exclude name="PSR2.Files.EndFileNewline.NoneFound"/> - <exclude name="PSR2.Methods.FunctionCallSignature.Indent"/> - <exclude name="PSR2.Methods.FunctionCallSignature.EmptyLine"/> - <exclude name="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"/> - <exclude name="PSR2.Methods.FunctionCallSignature.SpaceBeforeOpenBracket"/> - <exclude name="PSR2.Methods.FunctionCallSignature.CloseBracketLine"/> - <exclude name="PSR2.Methods.FunctionCallSignature.SpaceBeforeCloseBracket"/> - <exclude name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket"/> - <exclude name="PSR2.Methods.FunctionCallSignature.MultipleArguments"/> - <exclude name="PSR2.Methods.FunctionClosingBrace.SpacingBeforeClose"/> - <exclude name="PSR2.Methods.MethodDeclaration.StaticBeforeVisibility"/> - <exclude name="PSR2.Namespaces.NamespaceDeclaration.BlankLineAfter"/> - <exclude name="PSR2.Namespaces.UseDeclaration.SpaceAfterLastUse"/> - - <exclude name="PSR12.Classes.ClassInstantiation.MissingParentheses"/> - <exclude name="PSR12.Classes.OpeningBraceSpace.Found"/> - <exclude name="PSR12.ControlStructures.BooleanOperatorPlacement.FoundMixed"/> - <exclude name="PSR12.ControlStructures.ControlStructureSpacing.FirstExpressionLine"/> - <exclude name="PSR12.ControlStructures.ControlStructureSpacing.CloseParenthesisLine"/> - <exclude name="PSR12.ControlStructures.ControlStructureSpacing.LineIndent"/> - <exclude name="PSR12.ControlStructures.ControlStructureSpacing.SpacingAfterOpenBrace"/> - <exclude name="PSR12.ControlStructures.ControlStructureSpacing.SpaceBeforeCloseBrace"/> - <exclude name="PSR12.Files.FileHeader.SpacingAfterBlock"/> - <exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/> - <exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/> - <exclude name="PSR12.Properties.ConstantVisibility.NotFound"/> </rule> <!-- for now we mix declarations and execution here (mostly for defines) --> diff --git a/_test/rector.php b/_test/rector.php new file mode 100644 index 000000000..81f5c57ed --- /dev/null +++ b/_test/rector.php @@ -0,0 +1,205 @@ +<?php + +declare(strict_types=1); + +use dokuwiki\test\rector\DokuWikiPtlnRector; +use dokuwiki\test\rector\DokuWikiRenamePrintToEcho; +use Rector\Caching\ValueObject\Storage\FileCacheStorage; +use Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector; +use Rector\CodeQuality\Rector\Concat\JoinStringConcatRector; +use Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector; +use Rector\CodeQuality\Rector\If_\CombineIfRector; +use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector; +use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector; +use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector; +use Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector; +use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector; +use Rector\CodingStyle\Rector\Class_\AddArrayDefaultToArrayPropertyRector; +use Rector\CodingStyle\Rector\Closure\StaticClosureRector; +use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector; +use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector; +use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector; +use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector; +use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector; +use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector; +use Rector\Config\RectorConfig; +use Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector; +use Rector\DeadCode\Rector\If_\RemoveAlwaysTrueIfConditionRector; +use Rector\DeadCode\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector; +use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector; +use Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector; +use Rector\DeadCode\Rector\Stmt\RemoveUnreachableStatementRector; +use Rector\Php71\Rector\FuncCall\CountOnNullRector; +use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector; +use Rector\Php80\Rector\Identical\StrEndsWithRector; +use Rector\Php80\Rector\Identical\StrStartsWithRector; +use Rector\Php80\Rector\NotIdentical\StrContainsRector; +use Rector\Renaming\Rector\FuncCall\RenameFunctionRector; +use Rector\Renaming\Rector\Name\RenameClassRector; +use Rector\Set\ValueObject\LevelSetList; +use Rector\Set\ValueObject\SetList; +use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector; +use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector; + +return static function (RectorConfig $rectorConfig): void { + // FIXME we may want to autoload these later + require_once __DIR__ . '/rector/DokuWikiPtlnRector.php'; + require_once __DIR__ . '/rector/DokuWikiRenamePrintToEcho.php'; + + $rectorConfig->paths([ + __DIR__ . '/../inc/', + __DIR__ . '/../lib/', + __DIR__ . '/../bin/', + __DIR__ . '/../*.php', + ]); + + $rectorConfig->bootstrapFiles([ + __DIR__ . '/../inc/init.php', + ]); + + $rectorConfig->importNames(); + $rectorConfig->importShortClasses(false); + $rectorConfig->cacheClass(FileCacheStorage::class); + $rectorConfig->cacheDirectory(__DIR__ . '/.rector-cache'); + + // define sets of rules + $rectorConfig->sets([ + LevelSetList::UP_TO_PHP_74, + SetList::CODE_QUALITY, + SetList::DEAD_CODE, + SetList::CODING_STYLE, + ]); + + // future rules for which we have polyfills + $rectorConfig->rule(StrContainsRector::class); + $rectorConfig->rule(StrEndsWithRector::class); + $rectorConfig->rule(StrStartsWithRector::class); + + $rectorConfig->skip([ + // skip paths + __DIR__ . '/../inc/lang/*', + __DIR__ . '/../lib/plugins/*/_test/*', + __DIR__ . '/../lib/tpl/*/_test/*', + __DIR__ . '/../lib/plugins/*/lang/*', + __DIR__ . '/../lib/tpl/*/lang/*', + __DIR__ . '/../lib/plugins/*/conf/*', // maybe later + __DIR__ . '/../lib/tpl/*/conf/*', // maybe later + __DIR__ . '/../lib/plugins/*/vendor/*', + __DIR__ . '/../lib/tpl/*/vendor/*', + __DIR__ . '/../lib/plugins/*/skel/*', // dev plugin + __DIR__ . '/../inc/deprecated.php', + __DIR__ . '/../inc/form.php', + + // third party libs, not yet moved to composer + __DIR__ . '/../inc/DifferenceEngine.php', + __DIR__ . '/../inc/JpegMeta.php', + __DIR__ . '/../lib/plugins/authad/adLDAP', + + // skip rules + SimplifyIfElseToTernaryRector::class, + NewlineAfterStatementRector::class, + CombineIfRector::class, + ExplicitBoolCompareRector::class, + IssetOnPropertyObjectToPropertyExistsRector::class, // maybe? + SymplifyQuoteEscapeRector::class, + CatchExceptionNameMatchingTypeRector::class, + EncapsedStringsToSprintfRector::class, + CallableThisArrayToAnonymousFunctionRector::class, + StaticClosureRector::class, + SimplifyUselessVariableRector::class, // seems to strip constructor property initializations + PostIncDecToPreIncDecRector::class, + RemoveUselessParamTagRector::class, + DisallowedEmptyRuleFixerRector::class, + CountOnNullRector::class, // adds unwanted is_countable checks? + RemoveParentCallWithoutParentRector::class, + WrapEncapsedVariableInCurlyBracesRector::class, + SimplifyIfReturnBoolRector::class, + StrictArraySearchRector::class, // we cannot assume strict search is always wanted + AddArrayDefaultToArrayPropertyRector::class, // may break code differentiating between null and empty array + RemoveUselessVarTagRector::class, + TypedPropertyFromAssignsRector::class, // maybe? + JoinStringConcatRector::class, // this does not count variables, so it creates overlong lines + RemoveExtraParametersRector::class, // this actually broke code + RemoveUnusedNonEmptyArrayBeforeForeachRector::class, // seems unreliable when checking on array keys + RemoveAlwaysTrueIfConditionRector::class, // fails with if(defined(...)) constructs + RemoveUnreachableStatementRector::class, // fails GOTO in authpdo -> should be rewritten with exceptions + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + // see inc/deprecated.php + 'RemoteAccessDeniedException' => 'dokuwiki\Remote\AccessDeniedException', + 'RemoteException' => 'dokuwiki\Remote\RemoteException', + 'setting' => 'dokuwiki\plugin\config\core\Setting\Setting', + 'setting_authtype' => 'dokuwiki\plugin\config\core\Setting\SettingAuthtype', + 'setting_string' => 'dokuwiki\plugin\config\core\Setting\SettingString', + 'PageChangelog' => 'dokuwiki\ChangeLog\PageChangeLog', + 'MediaChangelog' => 'dokuwiki\ChangeLog\MediaChangeLog', + 'Input' => 'dokuwiki\Input\Input', + 'PostInput' => 'dokuwiki\Input\Post', + 'GetInput' => 'dokuwiki\Input\Get', + 'ServerInput' => 'dokuwiki\Input\Server', + 'PassHash' => 'dokuwiki\PassHash', + 'HTTPClientException' => 'dokuwiki\HTTP\HTTPClientException', + 'HTTPClient' => 'dokuwiki\HTTP\HTTPClient', + 'DokuHTTPClient' => 'dokuwiki\HTTP\DokuHTTPClient', + 'Doku_Plugin_Controller' => 'dokuwiki\Extension\PluginController', + 'Doku_Indexer' => 'dokuwiki\Search\Indexer', + 'IXR_Client' => 'dokuwiki\Remote\IXR\Client', + 'IXR_ClientMulticall' => 'IXR\Client\ClientMulticall', + 'IXR_Server' => 'IXR\Server\Server', + 'IXR_IntrospectionServer' => 'IXR\Server\IntrospectionServer', + 'IXR_Request' => 'IXR\Request\Request', + 'IXR_Message' => 'R\Message\Message', + 'IXR_Error' => 'XR\Message\Error', + 'IXR_Date' => 'IXR\DataType\Date', + 'IXR_Base64' => 'IXR\DataType\Base64', + 'IXR_Value' => 'IXR\DataType\Value', + + // see inc/legacy.php + 'Doku_Event_Handler' => 'dokuwiki\Extension\EventHandler', + 'Doku_Event' => 'dokuwiki\Extension\Event', + 'DokuWiki_Action_Plugin' => 'dokuwiki\Extension\ActionPlugin', + 'DokuWiki_Admin_Plugin' => 'dokuwiki\Extension\AdminPlugin', + 'DokuWiki_Auth_Plugin' => 'dokuwiki\Extension\AuthPlugin', + 'DokuWiki_CLI_Plugin' => 'dokuwiki\Extension\CLIPlugin', + 'DokuWiki_Plugin' => 'dokuwiki\Extension\Plugin', + 'DokuWiki_Remote_Plugin' => 'dokuwiki\Extension\RemotePlugin', + 'DokuWiki_Syntax_Plugin' => 'dokuwiki\Extension\SyntaxPlugin', + ]); + + $rectorConfig->ruleWithConfiguration(RenameFunctionRector::class, [ + // see inc/deprecated.php + 'Doku_Lexer_Escape' => 'dokuwiki\Parsing\Lexer\Lexer::escape', + + // see inc/utf8.php + 'utf8_isASCII' => 'dokuwiki\Utf8\Clean::isASCII', + 'utf8_strip' => 'dokuwiki\Utf8\Clean::strip', + 'utf8_check' => 'dokuwiki\Utf8\Clean::isUtf8', + 'utf8_basename' => 'dokuwiki\Utf8\PhpString::basename', + 'utf8_strlen' => 'dokuwiki\Utf8\PhpString::strlen', + 'utf8_substr' => 'dokuwiki\Utf8\PhpString::substr', + 'utf8_substr_replace' => 'dokuwiki\Utf8\PhpString::substr_replace', + 'utf8_ltrim' => 'dokuwiki\Utf8\PhpString::ltrim', + 'utf8_rtrim' => 'dokuwiki\Utf8\PhpString::rtrim', + 'utf8_trim' => 'dokuwiki\Utf8\PhpString::trim', + 'utf8_strtolower' => 'dokuwiki\Utf8\PhpString::strtolower', + 'utf8_strtoupper' => 'dokuwiki\Utf8\PhpString::strtoupper', + 'utf8_ucfirst' => 'dokuwiki\Utf8\PhpString::ucfirst', + 'utf8_ucwords' => 'dokuwiki\Utf8\PhpString::ucwords', + 'utf8_deaccent' => 'dokuwiki\Utf8\Clean::deaccent', + 'utf8_romanize' => 'dokuwiki\Utf8\Clean::romanize', + 'utf8_stripspecials' => 'dokuwiki\Utf8\Clean::stripspecials', + 'utf8_strpos' => 'dokuwiki\Utf8\PhpString::strpos', + 'utf8_tohtml' => 'dokuwiki\Utf8\Conversion::toHtml', + 'utf8_unhtml' => 'dokuwiki\Utf8\Conversion::fromHtml', + 'utf8_to_unicode' => 'dokuwiki\Utf8\Conversion::fromUtf8', + 'unicode_to_utf8' => 'dokuwiki\Utf8\Conversion::toUtf8', + 'utf8_to_utf16be' => 'dokuwiki\Utf8\Conversion::toUtf16be', + 'utf16be_to_utf8' => 'dokuwiki\Utf8\Conversion::fromUtf16be', + 'utf8_bad_replace' => 'dokuwiki\Utf8\Clean::replaceBadBytes', + 'utf8_correctIdx' => 'dokuwiki\Utf8\Clean::correctIdx', + ]); + + $rectorConfig->rule(DokuWikiPtlnRector::class); + $rectorConfig->rule(DokuWikiRenamePrintToEcho::class); +}; diff --git a/_test/rector/DokuWikiPtlnRector.php b/_test/rector/DokuWikiPtlnRector.php new file mode 100644 index 000000000..fa432a366 --- /dev/null +++ b/_test/rector/DokuWikiPtlnRector.php @@ -0,0 +1,55 @@ +<?php + +namespace dokuwiki\test\rector; + +use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Stmt\Echo_; +use PhpParser\Node\Stmt\Expression; +use Rector\Core\Rector\AbstractRector; +use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; +use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; + +/** + * Replace ptln() calls with echo + */ +class DokuWikiPtlnRector extends AbstractRector +{ + + /** @inheritdoc */ + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Replace ptln() calls with echo', [ + new CodeSample( + <<<'CODE_SAMPLE' +ptln('Hello World', 7); +CODE_SAMPLE, + <<<'CODE_SAMPLE' +echo 'Hello World'; +CODE_SAMPLE + ), + ]); + } + + /** @inheritdoc */ + public function getNodeTypes(): array + { + return [Expression::class]; + } + + /** @inheritdoc */ + public function refactor(Node $node) + { + if (!$node->expr instanceof FuncCall) { + return null; + } + + if (!$this->nodeNameResolver->isName($node->expr, 'ptln')) { + return null; + } + + return new Echo_([ + $node->expr->args[0]->value + ]); + } +} diff --git a/_test/rector/DokuWikiRenamePrintToEcho.php b/_test/rector/DokuWikiRenamePrintToEcho.php new file mode 100644 index 000000000..2545e17a5 --- /dev/null +++ b/_test/rector/DokuWikiRenamePrintToEcho.php @@ -0,0 +1,49 @@ +<?php + +namespace dokuwiki\test\rector; + +use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Expr\Print_; +use PhpParser\Node\Stmt\Echo_; +use PhpParser\Node\Stmt\Expression; +use Rector\Core\Rector\AbstractRector; +use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; +use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; + +/** + * Replace print calls with echo + */ +class DokuWikiRenamePrintToEcho extends AbstractRector +{ + + /** @inheritdoc */ + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Replace print calls with echo', [ + new CodeSample( + <<<'CODE_SAMPLE' +print 'Hello World'; +CODE_SAMPLE, + <<<'CODE_SAMPLE' +echo 'Hello World'; +CODE_SAMPLE + ), + ]); + } + + /** @inheritdoc */ + public function getNodeTypes(): array + { + return [Expression::class]; + } + + /** @inheritdoc */ + public function refactor(Node $node) + { + if (!$node->expr instanceof Print_) { + return null; + } + return new Echo_([$node->expr->expr], $node->getAttributes()); + } +} diff --git a/bin/dwpage.php b/bin/dwpage.php index a640fa783..a343cb0ed 100755 --- a/bin/dwpage.php +++ b/bin/dwpage.php @@ -3,16 +3,17 @@ use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; +use dokuwiki\Utf8\PhpString; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); /** * Checkout and commit pages from the command line while maintaining the history */ -class PageCLI extends CLI { - +class PageCLI extends CLI +{ protected $force = false; protected $username = ''; @@ -22,7 +23,8 @@ class PageCLI extends CLI { * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { /* global */ $options->registerOption( 'force', @@ -133,7 +135,7 @@ class PageCLI extends CLI { $options->registerArgument( 'key', 'The name of the metadata item to be retrieved.' . "\n" . - 'If empty, an array of all the metadata items is returned.' ."\n" . + 'If empty, an array of all the metadata items is returned.' . "\n" . 'For retrieving items that are stored in sub-arrays, separate the ' . 'keys of the different levels by spaces, in quotes, eg "date modified".', false, @@ -149,13 +151,14 @@ class PageCLI extends CLI { * @param Options $options * @return void */ - protected function main(Options $options) { + protected function main(Options $options) + { $this->force = $options->getOpt('force', false); $this->username = $options->getOpt('user', $this->getUser()); $command = $options->getCmd(); $args = $options->getArgs(); - switch($command) { + switch ($command) { case 'checkout': $wiki_id = array_shift($args); $localfile = array_shift($args); @@ -199,31 +202,32 @@ class PageCLI extends CLI { * @param string $wiki_id * @param string $localfile */ - protected function commandCheckout($wiki_id, $localfile) { + protected function commandCheckout($wiki_id, $localfile) + { global $conf; $wiki_id = cleanID($wiki_id); $wiki_fn = wikiFN($wiki_id); - if(!file_exists($wiki_fn)) { + if (!file_exists($wiki_fn)) { $this->fatal("$wiki_id does not yet exist"); } - if(empty($localfile)) { - $localfile = getcwd() . '/' . \dokuwiki\Utf8\PhpString::basename($wiki_fn); + if (empty($localfile)) { + $localfile = getcwd() . '/' . PhpString::basename($wiki_fn); } - if(!file_exists(dirname($localfile))) { + if (!file_exists(dirname($localfile))) { $this->fatal("Directory " . dirname($localfile) . " does not exist"); } - if(stristr(realpath(dirname($localfile)), realpath($conf['datadir'])) !== false) { + if (stristr(realpath(dirname($localfile)), (string) realpath($conf['datadir'])) !== false) { $this->fatal("Attempt to check out file into data directory - not allowed"); } $this->obtainLock($wiki_id); - if(!copy($wiki_fn, $localfile)) { + if (!copy($wiki_fn, $localfile)) { $this->clearLock($wiki_id); $this->fatal("Unable to copy $wiki_fn to $localfile"); } @@ -239,19 +243,20 @@ class PageCLI extends CLI { * @param string $message * @param bool $minor */ - protected function commandCommit($localfile, $wiki_id, $message, $minor) { + protected function commandCommit($localfile, $wiki_id, $message, $minor) + { $wiki_id = cleanID($wiki_id); $message = trim($message); - if(!file_exists($localfile)) { + if (!file_exists($localfile)) { $this->fatal("$localfile does not exist"); } - if(!is_readable($localfile)) { + if (!is_readable($localfile)) { $this->fatal("Cannot read from $localfile"); } - if(!$message) { + if (!$message) { $this->fatal("Summary message required"); } @@ -269,19 +274,20 @@ class PageCLI extends CLI { * * @param string $wiki_id */ - protected function obtainLock($wiki_id) { - if($this->force) $this->deleteLock($wiki_id); + protected function obtainLock($wiki_id) + { + if ($this->force) $this->deleteLock($wiki_id); $_SERVER['REMOTE_USER'] = $this->username; - if(checklock($wiki_id)) { + if (checklock($wiki_id)) { $this->error("Page $wiki_id is already locked by another user"); exit(1); } lock($wiki_id); - if(checklock($wiki_id)) { + if (checklock($wiki_id)) { $this->error("Unable to obtain lock for $wiki_id "); var_dump(checklock($wiki_id)); exit(1); @@ -293,18 +299,19 @@ class PageCLI extends CLI { * * @param string $wiki_id */ - protected function clearLock($wiki_id) { - if($this->force) $this->deleteLock($wiki_id); + protected function clearLock($wiki_id) + { + if ($this->force) $this->deleteLock($wiki_id); $_SERVER['REMOTE_USER'] = $this->username; - if(checklock($wiki_id)) { + if (checklock($wiki_id)) { $this->error("Page $wiki_id is locked by another user"); exit(1); } unlock($wiki_id); - if(file_exists(wikiLockFN($wiki_id))) { + if (file_exists(wikiLockFN($wiki_id))) { $this->error("Unable to clear lock for $wiki_id"); exit(1); } @@ -315,11 +322,12 @@ class PageCLI extends CLI { * * @param string $wiki_id */ - protected function deleteLock($wiki_id) { + protected function deleteLock($wiki_id) + { $wikiLockFN = wikiLockFN($wiki_id); - if(file_exists($wikiLockFN)) { - if(!unlink($wikiLockFN)) { + if (file_exists($wikiLockFN)) { + if (!unlink($wikiLockFN)) { $this->error("Unable to delete $wikiLockFN"); exit(1); } @@ -331,14 +339,15 @@ class PageCLI extends CLI { * * @return string */ - protected function getUser() { + protected function getUser() + { $user = getenv('USER'); - if(empty ($user)) { + if (empty($user)) { $user = getenv('USERNAME'); } else { return $user; } - if(empty ($user)) { + if (empty($user)) { $user = 'admin'; } return $user; diff --git a/bin/gittool.php b/bin/gittool.php index 5ebd0c584..26480a460 100755 --- a/bin/gittool.php +++ b/bin/gittool.php @@ -4,7 +4,7 @@ use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); @@ -13,15 +13,16 @@ require_once(DOKU_INC . 'inc/init.php'); * * @author Andreas Gohr <andi@splitbrain.org> */ -class GitToolCLI extends CLI { - +class GitToolCLI extends CLI +{ /** * Register options and arguments on the given $options object * * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { $options->setHelp( "Manage git repositories for DokuWiki and its plugins and templates.\n\n" . "$> ./bin/gittool.php clone gallery template:ach\n" . @@ -79,12 +80,13 @@ class GitToolCLI extends CLI { * @param Options $options * @return void */ - protected function main(Options $options) { + protected function main(Options $options) + { $command = $options->getCmd(); $args = $options->getArgs(); - if(!$command) $command = array_shift($args); + if (!$command) $command = array_shift($args); - switch($command) { + switch ($command) { case '': echo $options->help(); break; @@ -108,28 +110,27 @@ class GitToolCLI extends CLI { * * @param array $extensions */ - public function cmdClone($extensions) { - $errors = array(); - $succeeded = array(); + public function cmdClone($extensions) + { + $errors = []; + $succeeded = []; - foreach($extensions as $ext) { + foreach ($extensions as $ext) { $repo = $this->getSourceRepo($ext); - if(!$repo) { + if (!$repo) { $this->error("could not find a repository for $ext"); $errors[] = $ext; + } elseif ($this->cloneExtension($ext, $repo)) { + $succeeded[] = $ext; } else { - if($this->cloneExtension($ext, $repo)) { - $succeeded[] = $ext; - } else { - $errors[] = $ext; - } + $errors[] = $ext; } } echo "\n"; - if($succeeded) $this->success('successfully cloned the following extensions: ' . join(', ', $succeeded)); - if($errors) $this->error('failed to clone the following extensions: ' . join(', ', $errors)); + if ($succeeded) $this->success('successfully cloned the following extensions: ' . implode(', ', $succeeded)); + if ($errors) $this->error('failed to clone the following extensions: ' . implode(', ', $errors)); } /** @@ -137,32 +138,31 @@ class GitToolCLI extends CLI { * * @param array $extensions */ - public function cmdInstall($extensions) { - $errors = array(); - $succeeded = array(); + public function cmdInstall($extensions) + { + $errors = []; + $succeeded = []; - foreach($extensions as $ext) { + foreach ($extensions as $ext) { $repo = $this->getSourceRepo($ext); - if(!$repo) { + if (!$repo) { $this->info("could not find a repository for $ext"); - if($this->downloadExtension($ext)) { + if ($this->downloadExtension($ext)) { $succeeded[] = $ext; } else { $errors[] = $ext; } + } elseif ($this->cloneExtension($ext, $repo)) { + $succeeded[] = $ext; } else { - if($this->cloneExtension($ext, $repo)) { - $succeeded[] = $ext; - } else { - $errors[] = $ext; - } + $errors[] = $ext; } } echo "\n"; - if($succeeded) $this->success('successfully installed the following extensions: ' . join(', ', $succeeded)); - if($errors) $this->error('failed to install the following extensions: ' . join(', ', $errors)); + if ($succeeded) $this->success('successfully installed the following extensions: ' . implode(', ', $succeeded)); + if ($errors) $this->error('failed to install the following extensions: ' . implode(', ', $errors)); } /** @@ -171,15 +171,16 @@ class GitToolCLI extends CLI { * @param $cmd * @param $arg */ - public function cmdGit($cmd, $arg) { + public function cmdGit($cmd, $arg) + { $repos = $this->findRepos(); - $shell = array_merge(array('git', $cmd), $arg); + $shell = array_merge(['git', $cmd], $arg); $shell = array_map('escapeshellarg', $shell); - $shell = join(' ', $shell); + $shell = implode(' ', $shell); - foreach($repos as $repo) { - if(!@chdir($repo)) { + foreach ($repos as $repo) { + if (!@chdir($repo)) { $this->error("Could not change into $repo"); continue; } @@ -188,7 +189,7 @@ class GitToolCLI extends CLI { $ret = 0; system($shell, $ret); - if($ret == 0) { + if ($ret == 0) { $this->success("git succeeded in $repo"); } else { $this->error("git failed in $repo"); @@ -199,9 +200,10 @@ class GitToolCLI extends CLI { /** * Simply lists the repositories */ - public function cmdRepos() { + public function cmdRepos() + { $repos = $this->findRepos(); - foreach($repos as $repo) { + foreach ($repos as $repo) { echo "$repo\n"; } } @@ -212,15 +214,16 @@ class GitToolCLI extends CLI { * @param string $ext * @return bool|null */ - private function downloadExtension($ext) { + private function downloadExtension($ext) + { /** @var helper_plugin_extension_extension $plugin */ $plugin = plugin_load('helper', 'extension_extension'); - if(!$ext) die("extension plugin not available, can't continue"); + if (!$ext) die("extension plugin not available, can't continue"); $plugin->setExtension($ext); $url = $plugin->getDownloadURL(); - if(!$url) { + if (!$url) { $this->error("no download URL for $ext"); return false; } @@ -229,11 +232,11 @@ class GitToolCLI extends CLI { try { $this->info("installing $ext via download from $url"); $ok = $plugin->installFromURL($url); - } catch(Exception $e) { + } catch (Exception $e) { $this->error($e->getMessage()); } - if($ok) { + if ($ok) { $this->success("installed $ext via download"); return true; } else { @@ -249,8 +252,9 @@ class GitToolCLI extends CLI { * @param string $repo * @return bool */ - private function cloneExtension($ext, $repo) { - if(substr($ext, 0, 9) == 'template:') { + private function cloneExtension($ext, $repo) + { + if (substr($ext, 0, 9) == 'template:') { $target = fullpath(tpl_incdir() . '../' . substr($ext, 9)); } else { $target = DOKU_PLUGIN . $ext; @@ -259,7 +263,7 @@ class GitToolCLI extends CLI { $this->info("cloning $ext from $repo to $target"); $ret = 0; system("git clone $repo $target", $ret); - if($ret === 0) { + if ($ret === 0) { $this->success("cloning of $ext succeeded"); return true; } else { @@ -275,7 +279,8 @@ class GitToolCLI extends CLI { * * @return array */ - private function findRepos() { + private function findRepos() + { $this->info('Looking for .git directories'); $data = array_merge( glob(DOKU_INC . '.git', GLOB_ONLYDIR), @@ -283,7 +288,7 @@ class GitToolCLI extends CLI { glob(fullpath(tpl_incdir() . '../') . '/*/.git', GLOB_ONLYDIR) ); - if(!$data) { + if (!$data) { $this->error('Found no .git directories'); } else { $this->success('Found ' . count($data) . ' .git directories'); @@ -298,34 +303,35 @@ class GitToolCLI extends CLI { * @param $extension * @return false|string */ - private function getSourceRepo($extension) { + private function getSourceRepo($extension) + { /** @var helper_plugin_extension_extension $ext */ $ext = plugin_load('helper', 'extension_extension'); - if(!$ext) die("extension plugin not available, can't continue"); + if (!$ext) die("extension plugin not available, can't continue"); $ext->setExtension($extension); $repourl = $ext->getSourcerepoURL(); - if(!$repourl) return false; + if (!$repourl) return false; // match github repos - if(preg_match('/github\.com\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) { + if (preg_match('/github\.com\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) { $user = $m[1]; $repo = $m[2]; return 'https://github.com/' . $user . '/' . $repo . '.git'; } // match gitorious repos - if(preg_match('/gitorious.org\/([^\/]+)\/([^\/]+)?/i', $repourl, $m)) { + if (preg_match('/gitorious.org\/([^\/]+)\/([^\/]+)?/i', $repourl, $m)) { $user = $m[1]; $repo = $m[2]; - if(!$repo) $repo = $user; + if (!$repo) $repo = $user; return 'https://git.gitorious.org/' . $user . '/' . $repo . '.git'; } // match bitbucket repos - most people seem to use mercurial there though - if(preg_match('/bitbucket\.org\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) { + if (preg_match('/bitbucket\.org\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) { $user = $m[1]; $repo = $m[2]; return 'https://bitbucket.org/' . $user . '/' . $repo . '.git'; diff --git a/bin/indexer.php b/bin/indexer.php index c8c83610d..cda740d0b 100755 --- a/bin/indexer.php +++ b/bin/indexer.php @@ -4,15 +4,15 @@ use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); /** * Update the Search Index from command line */ -class IndexerCLI extends CLI { - +class IndexerCLI extends CLI +{ private $quiet = false; private $clear = false; @@ -22,7 +22,8 @@ class IndexerCLI extends CLI { * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { $options->setHelp( 'Updates the searchindex by indexing all new or changed pages. When the -c option is ' . 'given the index is cleared first.' @@ -48,11 +49,12 @@ class IndexerCLI extends CLI { * @param Options $options * @return void */ - protected function main(Options $options) { + protected function main(Options $options) + { $this->clear = $options->getOpt('clear'); $this->quiet = $options->getOpt('quiet'); - if($this->clear) $this->clearindex(); + if ($this->clear) $this->clearindex(); $this->update(); } @@ -60,14 +62,15 @@ class IndexerCLI extends CLI { /** * Update the index */ - protected function update() { + protected function update() + { global $conf; - $data = array(); + $data = []; $this->quietecho("Searching pages... "); - search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true)); + search($data, $conf['datadir'], 'search_allpages', ['skipacl' => true]); $this->quietecho(count($data) . " pages found.\n"); - foreach($data as $val) { + foreach ($data as $val) { $this->index($val['id']); } } @@ -77,7 +80,8 @@ class IndexerCLI extends CLI { * * @param string $id */ - protected function index($id) { + protected function index($id) + { $this->quietecho("$id... "); idx_addPage($id, !$this->quiet, $this->clear); $this->quietecho("done.\n"); @@ -86,7 +90,8 @@ class IndexerCLI extends CLI { /** * Clear all index files */ - protected function clearindex() { + protected function clearindex() + { $this->quietecho("Clearing index... "); idx_get_indexer()->clear(); $this->quietecho("done.\n"); @@ -97,8 +102,9 @@ class IndexerCLI extends CLI { * * @param string $msg */ - protected function quietecho($msg) { - if(!$this->quiet) echo $msg; + protected function quietecho($msg) + { + if (!$this->quiet) echo $msg; } } diff --git a/bin/plugin.php b/bin/plugin.php index 62c2f55ee..99c496bf7 100755 --- a/bin/plugin.php +++ b/bin/plugin.php @@ -5,20 +5,23 @@ use dokuwiki\Extension\PluginController; use splitbrain\phpcli\CLI; use splitbrain\phpcli\Colors; use splitbrain\phpcli\Options; +use dokuwiki\Extension\CLIPlugin; +use splitbrain\phpcli\TableFormatter; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); -class PluginCLI extends CLI { - +class PluginCLI extends CLI +{ /** * Register options and arguments on the given $options object * * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { $options->setHelp('Excecutes Plugin command line tools'); $options->registerArgument('plugin', 'The plugin CLI you want to run. Leave off to see list', false); } @@ -31,13 +34,14 @@ class PluginCLI extends CLI { * @param Options $options * @return void */ - protected function main(Options $options) { + protected function main(Options $options) + { global $argv; $argv = $options->getArgs(); - if($argv) { + if ($argv) { $plugin = $this->loadPlugin($argv[0]); - if($plugin !== null) { + if ($plugin instanceof CLIPlugin) { $plugin->run(); } else { $this->fatal('Command {cmd} not found.', ['cmd' => $argv[0]]); @@ -51,7 +55,8 @@ class PluginCLI extends CLI { /** * List available plugins */ - protected function listPlugins() { + protected function listPlugins() + { /** @var PluginController $plugin_controller */ global $plugin_controller; @@ -62,21 +67,20 @@ class PluginCLI extends CLI { $list = $plugin_controller->getList('cli'); sort($list); - if(!count($list)) { + if ($list === []) { echo $this->colors->wrap(" No plugins providing CLI components available\n", Colors::C_RED); } else { - $tf = new \splitbrain\phpcli\TableFormatter($this->colors); + $tf = new TableFormatter($this->colors); - foreach($list as $name) { + foreach ($list as $name) { $plugin = $this->loadPlugin($name); - if($plugin === null) continue; + if (!$plugin instanceof CLIPlugin) continue; $info = $plugin->getInfo(); echo $tf->format( [2, '30%', '*'], ['', $name, $info['desc']], ['', Colors::C_CYAN, ''] - ); } } @@ -86,14 +90,15 @@ class PluginCLI extends CLI { * Instantiate a CLI plugin * * @param string $name - * @return \dokuwiki\Extension\CLIPlugin|null + * @return CLIPlugin|null */ - protected function loadPlugin($name) { - if(plugin_isdisabled($name)) return null; + protected function loadPlugin($name) + { + if (plugin_isdisabled($name)) return null; // execute the plugin CLI $class = "cli_plugin_$name"; - if(class_exists($class)) { + if (class_exists($class)) { return new $class(); } return null; diff --git a/bin/render.php b/bin/render.php index 607695191..6f5b5bb68 100755 --- a/bin/render.php +++ b/bin/render.php @@ -4,7 +4,7 @@ use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); @@ -19,15 +19,16 @@ require_once(DOKU_INC . 'inc/init.php'); * @license GPL2 * @author Andreas Gohr <andi@splitbrain.org> */ -class RenderCLI extends CLI { - +class RenderCLI extends CLI +{ /** * Register options and arguments on the given $options object * * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { $options->setHelp( 'A simple commandline tool to render some DokuWiki syntax with a given renderer.' . "\n\n" . @@ -47,14 +48,15 @@ class RenderCLI extends CLI { * @throws DokuCLI_Exception * @return void */ - protected function main(Options $options) { + protected function main(Options $options) + { $renderer = $options->getOpt('renderer', 'xhtml'); // do the action $source = stream_get_contents(STDIN); - $info = array(); + $info = []; $result = p_render($renderer, p_get_instructions($source), $info); - if(is_null($result)) throw new DokuCLI_Exception("No such renderer $renderer"); + if (is_null($result)) throw new DokuCLI_Exception("No such renderer $renderer"); echo $result; } } diff --git a/bin/striplangs.php b/bin/striplangs.php index 91805d59e..b7895b56f 100755 --- a/bin/striplangs.php +++ b/bin/striplangs.php @@ -4,22 +4,23 @@ use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); /** * Remove unwanted languages from a DokuWiki install */ -class StripLangsCLI extends CLI { - +class StripLangsCLI extends CLI +{ /** * Register options and arguments on the given $options object * * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { $options->setHelp( 'Remove all languages from the installation, besides the ones specified. English language ' . @@ -47,21 +48,22 @@ class StripLangsCLI extends CLI { * @param Options $options * @return void */ - protected function main(Options $options) { - if($options->getOpt('keep')) { + protected function main(Options $options) + { + if ($options->getOpt('keep')) { $keep = explode(',', $options->getOpt('keep')); - if(!in_array('en', $keep)) $keep[] = 'en'; - } elseif($options->getOpt('english-only')) { - $keep = array('en'); + if (!in_array('en', $keep)) $keep[] = 'en'; + } elseif ($options->getOpt('english-only')) { + $keep = ['en']; } else { echo $options->help(); exit(0); } // Kill all language directories in /inc/lang and /lib/plugins besides those in $langs array - $this->stripDirLangs(realpath(dirname(__FILE__) . '/../inc/lang'), $keep); - $this->processExtensions(realpath(dirname(__FILE__) . '/../lib/plugins'), $keep); - $this->processExtensions(realpath(dirname(__FILE__) . '/../lib/tpl'), $keep); + $this->stripDirLangs(realpath(__DIR__ . '/../inc/lang'), $keep); + $this->processExtensions(realpath(__DIR__ . '/../lib/plugins'), $keep); + $this->processExtensions(realpath(__DIR__ . '/../lib/tpl'), $keep); } /** @@ -70,17 +72,17 @@ class StripLangsCLI extends CLI { * @param string $path path to plugin or template dir * @param array $keep_langs languages to keep */ - protected function processExtensions($path, $keep_langs) { - if(is_dir($path)) { + protected function processExtensions($path, $keep_langs) + { + if (is_dir($path)) { $entries = scandir($path); - foreach($entries as $entry) { - if($entry != "." && $entry != "..") { - if(is_dir($path . '/' . $entry)) { - + foreach ($entries as $entry) { + if ($entry != "." && $entry != "..") { + if (is_dir($path . '/' . $entry)) { $plugin_langs = $path . '/' . $entry . '/lang'; - if(is_dir($plugin_langs)) { + if (is_dir($plugin_langs)) { $this->stripDirLangs($plugin_langs, $keep_langs); } } @@ -95,13 +97,13 @@ class StripLangsCLI extends CLI { * @param string $path path to lang dir * @param array $keep_langs languages to keep */ - protected function stripDirLangs($path, $keep_langs) { + protected function stripDirLangs($path, $keep_langs) + { $dir = dir($path); - while(($cur_dir = $dir->read()) !== false) { - if($cur_dir != '.' and $cur_dir != '..' and is_dir($path . '/' . $cur_dir)) { - - if(!in_array($cur_dir, $keep_langs, true)) { + while (($cur_dir = $dir->read()) !== false) { + if ($cur_dir != '.' && $cur_dir != '..' && is_dir($path . '/' . $cur_dir)) { + if (!in_array($cur_dir, $keep_langs, true)) { io_rmdir($path . '/' . $cur_dir, true); } } diff --git a/bin/wantedpages.php b/bin/wantedpages.php index 3eb03349a..00ed28a9c 100755 --- a/bin/wantedpages.php +++ b/bin/wantedpages.php @@ -6,23 +6,23 @@ use dokuwiki\File\PageResolver; use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; -if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/'); define('NOSESSION', 1); require_once(DOKU_INC . 'inc/init.php'); /** * Find wanted pages */ -class WantedPagesCLI extends CLI { - - const DIR_CONTINUE = 1; - const DIR_NS = 2; - const DIR_PAGE = 3; +class WantedPagesCLI extends CLI +{ + protected const DIR_CONTINUE = 1; + protected const DIR_NS = 2; + protected const DIR_PAGE = 3; private $skip = false; private $sort = 'wanted'; - private $result = array(); + private $result = []; /** * Register options and arguments on the given $options object @@ -30,7 +30,8 @@ class WantedPagesCLI extends CLI { * @param Options $options * @return void */ - protected function setup(Options $options) { + protected function setup(Options $options) + { $options->setHelp( 'Outputs a list of wanted pages (pages that do not exist yet) and their origin pages ' . ' (the pages that are linkin to these missing pages).' @@ -63,9 +64,10 @@ class WantedPagesCLI extends CLI { * @param Options $options * @return void */ - protected function main(Options $options) { + protected function main(Options $options) + { $args = $options->getArgs(); - if($args) { + if ($args) { $startdir = dirname(wikiFN($args[0] . ':xxx')); } else { $startdir = dirname(wikiFN('xxx')); @@ -76,17 +78,17 @@ class WantedPagesCLI extends CLI { $this->info("searching $startdir"); - foreach($this->getPages($startdir) as $page) { + foreach ($this->getPages($startdir) as $page) { $this->internalLinks($page); } Sort::ksort($this->result); - foreach($this->result as $main => $subs) { - if($this->skip) { - print "$main\n"; + foreach ($this->result as $main => $subs) { + if ($this->skip) { + echo "$main\n"; } else { $subs = array_unique($subs); Sort::sort($subs); - foreach($subs as $sub) { + foreach ($subs as $sub) { printf("%-40s %s\n", $main, $sub); } } @@ -100,17 +102,18 @@ class WantedPagesCLI extends CLI { * @param string $basepath * @return int */ - protected function dirFilter($entry, $basepath) { - if($entry == '.' || $entry == '..') { + protected function dirFilter($entry, $basepath) + { + if ($entry == '.' || $entry == '..') { return WantedPagesCLI::DIR_CONTINUE; } - if(is_dir($basepath . '/' . $entry)) { - if(strpos($entry, '_') === 0) { + if (is_dir($basepath . '/' . $entry)) { + if (strpos($entry, '_') === 0) { return WantedPagesCLI::DIR_CONTINUE; } return WantedPagesCLI::DIR_NS; } - if(preg_match('/\.txt$/', $entry)) { + if (preg_match('/\.txt$/', $entry)) { return WantedPagesCLI::DIR_PAGE; } return WantedPagesCLI::DIR_CONTINUE; @@ -123,30 +126,28 @@ class WantedPagesCLI extends CLI { * @return array * @throws DokuCLI_Exception */ - protected function getPages($dir) { + protected function getPages($dir) + { static $trunclen = null; - if(!$trunclen) { + if (!$trunclen) { global $conf; $trunclen = strlen($conf['datadir'] . ':'); } - if(!is_dir($dir)) { + if (!is_dir($dir)) { throw new DokuCLI_Exception("Unable to read directory $dir"); } - $pages = array(); + $pages = []; $dh = opendir($dir); - while(false !== ($entry = readdir($dh))) { + while (false !== ($entry = readdir($dh))) { $status = $this->dirFilter($entry, $dir); - if($status == WantedPagesCLI::DIR_CONTINUE) { + if ($status == WantedPagesCLI::DIR_CONTINUE) { continue; - } else if($status == WantedPagesCLI::DIR_NS) { + } elseif ($status == WantedPagesCLI::DIR_NS) { $pages = array_merge($pages, $this->getPages($dir . '/' . $entry)); } else { - $page = array( - 'id' => pathID(substr($dir . '/' . $entry, $trunclen)), - 'file' => $dir . '/' . $entry, - ); + $page = ['id' => pathID(substr($dir . '/' . $entry, $trunclen)), 'file' => $dir . '/' . $entry]; $pages[] = $page; } } @@ -159,18 +160,19 @@ class WantedPagesCLI extends CLI { * * @param array $page array with page id and file path */ - protected function internalLinks($page) { + protected function internalLinks($page) + { global $conf; $instructions = p_get_instructions(file_get_contents($page['file'])); $resolver = new PageResolver($page['id']); $pid = $page['id']; - foreach($instructions as $ins) { - if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) { + foreach ($instructions as $ins) { + if ($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) { $mid = $resolver->resolveId($ins[1][0]); - if(!page_exists($mid)) { - list($mid) = explode('#', $mid); //record pages without hashes + if (!page_exists($mid)) { + [$mid] = explode('#', $mid); //record pages without hashes - if($this->sort == 'origin') { + if ($this->sort == 'origin') { $this->result[$pid][] = $mid; } else { $this->result[$mid][] = $pid; @@ -1,4 +1,5 @@ <?php + /** * DokuWiki mainscript * @@ -8,47 +9,48 @@ * @global Input $INPUT */ -// update message version - always use a string to avoid localized floats! +use dokuwiki\ChangeLog\PageChangeLog; use dokuwiki\Extension\Event; +// update message version - always use a string to avoid localized floats! $updateVersion = "55"; // xdebug_start_profiling(); -if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/'); // define all DokuWiki globals here (needed within test requests but also helps to keep track) -global $ACT, $INPUT, $QUERY, $ID, $REV, $DATE_AT, $IDX, - $DATE, $RANGE, $HIGH, $TEXT, $PRE, $SUF, $SUM, $INFO, $JSINFO; +global $ACT, $INPUT, $QUERY, $ID, $REV, $DATE_AT, $IDX, + $DATE, $RANGE, $HIGH, $TEXT, $PRE, $SUF, $SUM, $INFO, $JSINFO; -if(isset($_SERVER['HTTP_X_DOKUWIKI_DO'])) { +if (isset($_SERVER['HTTP_X_DOKUWIKI_DO'])) { $ACT = trim(strtolower($_SERVER['HTTP_X_DOKUWIKI_DO'])); -} elseif(!empty($_REQUEST['idx'])) { +} elseif (!empty($_REQUEST['idx'])) { $ACT = 'index'; -} elseif(isset($_REQUEST['do'])) { +} elseif (isset($_REQUEST['do'])) { $ACT = $_REQUEST['do']; } else { $ACT = 'show'; } // load and initialize the core system -require_once(DOKU_INC.'inc/init.php'); +require_once(DOKU_INC . 'inc/init.php'); //import variables $INPUT->set('id', str_replace("\xC2\xAD", '', $INPUT->str('id'))); //soft-hyphen -$QUERY = trim($INPUT->str('q')); -$ID = getID(); +$QUERY = trim($INPUT->str('q')); +$ID = getID(); -$REV = $INPUT->int('rev'); +$REV = $INPUT->int('rev'); $DATE_AT = $INPUT->str('at'); -$IDX = $INPUT->str('idx'); -$DATE = $INPUT->int('date'); +$IDX = $INPUT->str('idx'); +$DATE = $INPUT->int('date'); $RANGE = $INPUT->str('range'); -$HIGH = $INPUT->param('s'); -if(empty($HIGH)) $HIGH = getGoogleQuery(); +$HIGH = $INPUT->param('s'); +if (empty($HIGH)) $HIGH = getGoogleQuery(); -if($INPUT->post->has('wikitext')) { +if ($INPUT->post->has('wikitext')) { $TEXT = cleanText($INPUT->post->str('wikitext')); } $PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); @@ -57,13 +59,13 @@ $SUM = $INPUT->post->str('summary'); //parse DATE_AT -if($DATE_AT) { +if ($DATE_AT) { $date_parse = strtotime($DATE_AT); - if($date_parse) { + if ($date_parse) { $DATE_AT = $date_parse; } else { // check for UNIX Timestamp - $date_parse = @date('Ymd',$DATE_AT); - if(!$date_parse || $date_parse === '19700101') { + $date_parse = @date('Ymd', $DATE_AT); + if (!$date_parse || $date_parse === '19700101') { msg(sprintf($lang['unable_to_parse_date'], hsc($DATE_AT))); $DATE_AT = null; } @@ -71,19 +73,21 @@ if($DATE_AT) { } //check for existing $REV related to $DATE_AT -if($DATE_AT) { - $pagelog = new \dokuwiki\ChangeLog\PageChangeLog($ID); +if ($DATE_AT) { + $pagelog = new PageChangeLog($ID); $rev_t = $pagelog->getLastRevisionAt($DATE_AT); - if($rev_t === '') { //current revision + if ($rev_t === '') { + //current revision $REV = null; $DATE_AT = null; - } else if ($rev_t === false) { //page did not exist - $rev_n = $pagelog->getRelativeRevision($DATE_AT,+1); + } elseif ($rev_t === false) { + //page did not exist + $rev_n = $pagelog->getRelativeRevision($DATE_AT, +1); msg( sprintf( $lang['page_nonexist_rev'], dformat($DATE_AT), - wl($ID, array('rev' => $rev_n)), + wl($ID, ['rev' => $rev_n]), dformat($rev_n) ) ); @@ -97,13 +101,14 @@ if($DATE_AT) { $INFO = pageinfo(); // handle debugging -if($conf['allowdebug'] && $ACT == 'debug') { +if ($conf['allowdebug'] && $ACT == 'debug') { html_debug(); exit; } //send 404 for missing pages if configured or ID has special meaning to bots -if(!$INFO['exists'] && +if ( + !$INFO['exists'] && ($conf['send404'] || preg_match('/^(robots\.txt|sitemap\.xml(\.gz)?|favicon\.ico|crossdomain\.xml)$/', $ID)) && ($ACT == 'show' || (!is_array($ACT) && substr($ACT, 0, 7) == 'export_')) ) { @@ -111,12 +116,12 @@ if(!$INFO['exists'] && } //prepare breadcrumbs (initialize a static var) -if($conf['breadcrumbs']) breadcrumbs(); +if ($conf['breadcrumbs']) breadcrumbs(); // check upstream checkUpdateMessages(); -$tmp = array(); // No event data +$tmp = []; // No event data Event::createAndTrigger('DOKUWIKI_STARTED', $tmp); //close session @@ -125,7 +130,7 @@ session_write_close(); //do the work (picks up what to do from global env) act_dispatch(); -$tmp = array(); // No event data +$tmp = []; // No event data Event::createAndTrigger('DOKUWIKI_DONE', $tmp); // xdebug_dump_function_profile(1); @@ -16,7 +16,7 @@ use dokuwiki\ChangeLog\PageChangeLog; use dokuwiki\Extension\AuthPlugin; use dokuwiki\Extension\Event; -if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/'); require_once(DOKU_INC . 'inc/init.php'); //close session @@ -34,13 +34,13 @@ $opt = rss_parseOptions(); // the feed is dynamic - we need a cache for each combo // (but most people just use the default feed so it's still effective) -$key = join('', array_values($opt)) . '$' . $INPUT->server->str('REMOTE_USER') +$key = implode('', array_values($opt)) . '$' . $INPUT->server->str('REMOTE_USER') . '$' . $INPUT->server->str('HTTP_HOST') . $INPUT->server->str('SERVER_PORT'); $cache = new Cache($key, '.feed'); // prepare cache depends $depends['files'] = getConfigFiles('main'); -$depends['age'] = $conf['rss_update']; +$depends['age'] = $conf['rss_update']; $depends['purge'] = $INPUT->bool('purge'); // check cacheage and deliver if nothing has changed since last @@ -52,28 +52,28 @@ header('X-Robots-Tag: noindex'); if ($cache->useCache($depends)) { http_conditionalRequest($cache->getTime()); if ($conf['allowdebug']) header("X-CacheUsed: $cache->cache"); - print $cache->retrieveCache(); + echo $cache->retrieveCache(); exit; } else { http_conditionalRequest(time()); } // create new feed -$rss = new UniversalFeedCreator(); -$rss->title = $conf['title'] . (($opt['namespace']) ? ' ' . $opt['namespace'] : ''); -$rss->link = DOKU_URL; +$rss = new UniversalFeedCreator(); +$rss->title = $conf['title'] . (($opt['namespace']) ? ' ' . $opt['namespace'] : ''); +$rss->link = DOKU_URL; $rss->syndicationURL = DOKU_URL . 'feed.php'; -$rss->cssStyleSheet = DOKU_URL . 'lib/exe/css.php?s=feed'; +$rss->cssStyleSheet = DOKU_URL . 'lib/exe/css.php?s=feed'; -$image = new FeedImage(); +$image = new FeedImage(); $image->title = $conf['title']; -$image->url = tpl_getMediaFile([':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico'], true); -$image->link = DOKU_URL; -$rss->image = $image; +$image->url = tpl_getMediaFile([':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico'], true); +$image->link = DOKU_URL; +$rss->image = $image; -$data = null; +$data = null; $modes = [ - 'list' => 'rssListNamespace', + 'list' => 'rssListNamespace', 'search' => 'rssSearch', 'recent' => 'rssRecentChanges' ]; @@ -82,10 +82,10 @@ if (isset($modes[$opt['feed_mode']])) { $data = $modes[$opt['feed_mode']]($opt); } else { $eventData = [ - 'opt' => &$opt, + 'opt' => &$opt, 'data' => &$data, ]; - $event = new Event('FEED_MODE_UNKNOWN', $eventData); + $event = new Event('FEED_MODE_UNKNOWN', $eventData); if ($event->advise_before(true)) { echo sprintf('<error>Unknown feed mode %s</error>', hsc($opt['feed_mode'])); exit; @@ -100,7 +100,7 @@ $feed = $rss->createFeed($opt['feed_type']); $cache->storeCache($feed); // finally deliver -print $feed; +echo $feed; // ---------------------------------------------------------------- // @@ -123,9 +123,9 @@ function rss_parseOptions() // properties for implementing own feeds // One of: list, search, recent - 'feed_mode' => ['str', 'mode', 'recent'], + 'feed_mode' => ['str', 'mode', 'recent'], // One of: diff, page, rev, current - 'link_to' => ['str', 'linkto', $conf['rss_linkto']], + 'link_to' => ['str', 'linkto', $conf['rss_linkto']], // One of: abstract, diff, htmldiff, html 'item_content' => ['str', 'content', $conf['rss_content']], @@ -133,15 +133,15 @@ function rss_parseOptions() // These are only used by certain feed_modes // String, used for feed title, in list and rc mode - 'namespace' => ['str', 'ns', null], + 'namespace' => ['str', 'ns', null], // Positive integer, only used in rc mode - 'items' => ['int', 'num', $conf['recent']], + 'items' => ['int', 'num', $conf['recent']], // Boolean, only used in rc mode - 'show_minor' => ['bool', 'minor', false], + 'show_minor' => ['bool', 'minor', false], // Boolean, only used in rc mode - 'only_new' => ['bool', 'onlynewpages', false], + 'only_new' => ['bool', 'onlynewpages', false], // String, only used in list mode - 'sort' => ['str', 'sort', 'natural'], + 'sort' => ['str', 'sort', 'natural'], // String, only used in search mode 'search_query' => ['str', 'q', null], // One of: pages, media, both @@ -152,10 +152,10 @@ function rss_parseOptions() $opt[$name] = $INPUT->{$val[0]}($val[1], $val[2], true); } - $opt['items'] = max(0, (int) $opt['items']); - $opt['show_minor'] = (bool) $opt['show_minor']; - $opt['only_new'] = (bool) $opt['only_new']; - $opt['sort'] = valid_input_set('sort', ['default' => 'natural', 'date'], $opt); + $opt['items'] = max(0, (int)$opt['items']); + $opt['show_minor'] = (bool)$opt['show_minor']; + $opt['only_new'] = (bool)$opt['only_new']; + $opt['sort'] = valid_input_set('sort', ['default' => 'natural', 'date'], $opt); $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none'); @@ -196,9 +196,9 @@ function rss_parseOptions() /** * Add recent changed pages to a feed object * - * @param FeedCreator $rss the FeedCreator Object - * @param array $data the items to add - * @param array $opt the feed options + * @param FeedCreator $rss the FeedCreator Object + * @param array $data the items to add + * @param array $opt the feed options * @author Andreas Gohr <andi@splitbrain.org> */ function rss_buildItems(&$rss, &$data, $opt) @@ -209,11 +209,11 @@ function rss_buildItems(&$rss, &$data, $opt) global $auth; $eventData = [ - 'rss' => &$rss, + 'rss' => &$rss, 'data' => &$data, - 'opt' => &$opt, + 'opt' => &$opt, ]; - $event = new Event('FEED_DATA_PROCESS', $eventData); + $event = new Event('FEED_DATA_PROCESS', $eventData); if ($event->advise_before(false)) { foreach ($data as $ditem) { if (!is_array($ditem)) { @@ -222,7 +222,7 @@ function rss_buildItems(&$rss, &$data, $opt) } $item = new FeedItem(); - $id = $ditem['id']; + $id = $ditem['id']; if (empty($ditem['media'])) { $meta = p_get_metadata($id); } else { @@ -260,8 +260,8 @@ function rss_buildItems(&$rss, &$data, $opt) $item->link = media_managerURL( [ 'image' => $id, - 'ns' => getNS($id), - 'rev' => $date + 'ns' => getNS($id), + 'rev' => $date ], '&', true @@ -274,9 +274,9 @@ function rss_buildItems(&$rss, &$data, $opt) if ($ditem['media']) { $item->link = media_managerURL( [ - 'image' => $id, - 'ns' => getNS($id), - 'rev' => $date, + 'image' => $id, + 'ns' => getNS($id), + 'rev' => $date, 'tab_details' => 'history' ], '&', @@ -291,7 +291,7 @@ function rss_buildItems(&$rss, &$data, $opt) $item->link = media_managerURL( [ 'image' => $id, - 'ns' => getNS($id) + 'ns' => getNS($id) ], '&', true @@ -305,11 +305,11 @@ function rss_buildItems(&$rss, &$data, $opt) if ($ditem['media']) { $item->link = media_managerURL( [ - 'image' => $id, - 'ns' => getNS($id), - 'rev' => $date, + 'image' => $id, + 'ns' => getNS($id), + 'rev' => $date, 'tab_details' => 'history', - 'mediado' => 'diff' + 'mediado' => 'diff' ], '&', true @@ -325,17 +325,23 @@ function rss_buildItems(&$rss, &$data, $opt) case 'htmldiff': if ($ditem['media']) { $medialog = new MediaChangeLog($id); - $revs = $medialog->getRevisions(0, 1); - $rev = $revs[0]; - $src_r = ''; - $src_l = ''; + $revs = $medialog->getRevisions(0, 1); + $rev = $revs[0]; + $src_r = ''; + $src_l = ''; if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)), 300)) { - $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id)); + $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id)); $src_r = ml($id, $more, true, '&', true); } - if ($rev && $size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), - 300)) { + if ( + $rev && $size = media_image_preview_size( + $id, + $rev, + new JpegMeta(mediaFN($id, $rev)), + 300 + ) + ) { $more = 'rev=' . $rev . '&w=' . $size[0] . '&h=' . $size[1]; $src_l = ml($id, $more, true, '&', true); } @@ -351,8 +357,8 @@ function rss_buildItems(&$rss, &$data, $opt) } else { require_once(DOKU_INC . 'inc/DifferenceEngine.php'); $pagelog = new PageChangeLog($id); - $revs = $pagelog->getRevisions(0, 1); - $rev = $revs[0]; + $revs = $pagelog->getRevisions(0, 1); + $rev = $revs[0]; if ($rev) { $df = new Diff( @@ -368,7 +374,7 @@ function rss_buildItems(&$rss, &$data, $opt) if ($opt['item_content'] == 'htmldiff') { // note: no need to escape diff output, TableDiffFormatter provides 'safe' html - $tdf = new TableDiffFormatter(); + $tdf = new TableDiffFormatter(); $content = '<table>'; $content .= '<tr><th colspan="2" width="50%">' . $rev . '</th>'; $content .= '<th colspan="2" width="50%">' . $lang['current'] . '</th></tr>'; @@ -376,7 +382,7 @@ function rss_buildItems(&$rss, &$data, $opt) $content .= '</table>'; } else { // note: diff output must be escaped, UnifiedDiffFormatter provides plain text - $udf = new UnifiedDiffFormatter(); + $udf = new UnifiedDiffFormatter(); $content = "<pre>\n" . hsc($udf->format($df)) . "\n</pre>"; } } @@ -384,8 +390,8 @@ function rss_buildItems(&$rss, &$data, $opt) case 'html': if ($ditem['media']) { if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) { - $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id)); - $src = ml($id, $more, true, '&', true); + $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id)); + $src = ml($id, $more, true, '&', true); $content = '<img src="' . $src . '" alt="' . $id . '" />'; } else { $content = ''; @@ -405,9 +411,10 @@ function rss_buildItems(&$rss, &$data, $opt) // make URLs work when canonical is not set, regexp instead of rerendering! if (!$conf['canonical']) { - $base = preg_quote(DOKU_REL, '/'); + $base = preg_quote(DOKU_REL, '/'); $content = preg_replace( - '/(<a href|<img src)="(' . $base . ')/s', '$1="' . DOKU_URL, + '/(<a href|<img src)="(' . $base . ')/s', + '$1="' . DOKU_URL, $content ); } @@ -418,8 +425,8 @@ function rss_buildItems(&$rss, &$data, $opt) default: if (isset($ditem['media'])) { if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) { - $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id)); - $src = ml($id, $more, true, '&', true); + $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id)); + $src = ml($id, $more, true, '&', true); $content = '<img src="' . $src . '" alt="' . $id . '" />'; } else { $content = ''; @@ -434,14 +441,14 @@ function rss_buildItems(&$rss, &$data, $opt) # FIXME should the user be pulled from metadata as well? $user = @$ditem['user']; // the @ spares time repeating lookup if (blank($user)) { - $item->author = 'Anonymous'; + $item->author = 'Anonymous'; $item->authorEmail = 'anonymous@undisclosed.example.com'; } else { - $item->author = $user; + $item->author = $user; $item->authorEmail = $user . '@undisclosed.example.com'; // get real user name if configured - if ($conf['useacl'] && $auth) { + if ($conf['useacl'] && $auth instanceof AuthPlugin) { $userInfo = $auth->getUserData($user); if ($userInfo) { switch ($conf['showuseras']) { @@ -469,12 +476,12 @@ function rss_buildItems(&$rss, &$data, $opt) // finally add the item to the feed object, after handing it to registered plugins $evdata = [ - 'item' => &$item, - 'opt' => &$opt, + 'item' => &$item, + 'opt' => &$opt, 'ditem' => &$ditem, - 'rss' => &$rss + 'rss' => &$rss ]; - $evt = new Event('FEED_ITEM_ADD', $evdata); + $evt = new Event('FEED_ITEM_ADD', $evdata); if ($evt->advise_before()) { $rss->addItem($item); } @@ -516,9 +523,9 @@ function rssListNamespace($opt) $ns = ':' . cleanID($opt['namespace']); $ns = utf8_encodeFN(str_replace(':', '/', $ns)); - $data = []; + $data = []; $search_opts = [ - 'depth' => 1, + 'depth' => 1, 'pagesonly' => true, 'listfiles' => true ]; diff --git a/inc/Action/AbstractAclAction.php b/inc/Action/AbstractAclAction.php index 871edb0ae..27b514d52 100644 --- a/inc/Action/AbstractAclAction.php +++ b/inc/Action/AbstractAclAction.php @@ -3,6 +3,7 @@ namespace dokuwiki\Action; use dokuwiki\Action\Exception\ActionAclRequiredException; +use dokuwiki\Extension\AuthPlugin; /** * Class AbstractAclAction @@ -11,15 +12,15 @@ use dokuwiki\Action\Exception\ActionAclRequiredException; * * @package dokuwiki\Action */ -abstract class AbstractAclAction extends AbstractAction { - +abstract class AbstractAclAction extends AbstractAction +{ /** @inheritdoc */ - public function checkPreconditions() { + public function checkPreconditions() + { parent::checkPreconditions(); global $conf; global $auth; - if(!$conf['useacl']) throw new ActionAclRequiredException(); - if(!$auth) throw new ActionAclRequiredException(); + if (!$conf['useacl']) throw new ActionAclRequiredException(); + if (!$auth instanceof AuthPlugin) throw new ActionAclRequiredException(); } - } diff --git a/inc/Action/AbstractAction.php b/inc/Action/AbstractAction.php index 37eab3a8e..54dd459c2 100644 --- a/inc/Action/AbstractAction.php +++ b/inc/Action/AbstractAction.php @@ -12,8 +12,8 @@ use dokuwiki\Action\Exception\FatalException; * * @package dokuwiki\Action */ -abstract class AbstractAction { - +abstract class AbstractAction +{ /** @var string holds the name of the action (lowercase class name, no namespace) */ protected $actionname; @@ -22,8 +22,9 @@ abstract class AbstractAction { * * @param string $actionname the name of this action (see getActionName() for caveats) */ - public function __construct($actionname = '') { - if($actionname !== '') { + public function __construct($actionname = '') + { + if ($actionname !== '') { $this->actionname = $actionname; } else { // http://stackoverflow.com/a/27457689/172068 @@ -48,7 +49,8 @@ abstract class AbstractAction { * @throws ActionException * @return void */ - public function checkPreconditions() { + public function checkPreconditions() + { } /** @@ -61,7 +63,8 @@ abstract class AbstractAction { * @throws ActionException * @return void */ - public function preProcess() { + public function preProcess() + { } /** @@ -70,7 +73,8 @@ abstract class AbstractAction { * @fixme we may want to return a Ui class here * @throws FatalException */ - public function tplContent() { + public function tplContent() + { throw new FatalException('No content for Action ' . $this->actionname); } @@ -82,7 +86,8 @@ abstract class AbstractAction { * * @return string */ - public function getActionName() { + public function getActionName() + { return $this->actionname; } } diff --git a/inc/Action/AbstractAliasAction.php b/inc/Action/AbstractAliasAction.php index 771664a37..605e1c136 100644 --- a/inc/Action/AbstractAliasAction.php +++ b/inc/Action/AbstractAliasAction.php @@ -14,18 +14,19 @@ use dokuwiki\Action\Exception\FatalException; * * @package dokuwiki\Action */ -abstract class AbstractAliasAction extends AbstractAction { - +abstract class AbstractAliasAction extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_NONE; } /** * @throws FatalException */ - public function preProcess() { + public function preProcess() + { throw new FatalException('Alias Actions need to implement preProcess to load the aliased action'); } - } diff --git a/inc/Action/AbstractUserAction.php b/inc/Action/AbstractUserAction.php index 233f52edb..623860d67 100644 --- a/inc/Action/AbstractUserAction.php +++ b/inc/Action/AbstractUserAction.php @@ -11,15 +11,15 @@ use dokuwiki\Action\Exception\ActionUserRequiredException; * * @package dokuwiki\Action */ -abstract class AbstractUserAction extends AbstractAclAction { - +abstract class AbstractUserAction extends AbstractAclAction +{ /** @inheritdoc */ - public function checkPreconditions() { + public function checkPreconditions() + { parent::checkPreconditions(); global $INPUT; - if($INPUT->server->str('REMOTE_USER') === '') { + if ($INPUT->server->str('REMOTE_USER') === '') { throw new ActionUserRequiredException(); } } - } diff --git a/inc/Action/Admin.php b/inc/Action/Admin.php index 7a884b5b5..d292dee22 100644 --- a/inc/Action/Admin.php +++ b/inc/Action/Admin.php @@ -12,22 +12,24 @@ use dokuwiki\Extension\AdminPlugin; * * @package dokuwiki\Action */ -class Admin extends AbstractUserAction { - +class Admin extends AbstractUserAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_READ; // let in check later } /** @inheritDoc */ - public function preProcess() { + public function preProcess() + { global $INPUT; // retrieve admin plugin name from $_REQUEST['page'] - if($INPUT->str('page', '', true) != '') { + if ($INPUT->str('page', '', true) != '') { /** @var AdminPlugin $plugin */ - if($plugin = plugin_getRequestAdminPlugin()) { // FIXME this method does also permission checking - if(!$plugin->isAccessibleByCurrentUser()) { + if ($plugin = plugin_getRequestAdminPlugin()) { // FIXME this method does also permission checking + if (!$plugin->isAccessibleByCurrentUser()) { throw new ActionException('denied'); } $plugin->handle(); @@ -36,7 +38,8 @@ class Admin extends AbstractUserAction { } /** @inheritDoc */ - public function tplContent() { + public function tplContent() + { tpl_admin(); } } diff --git a/inc/Action/Backlink.php b/inc/Action/Backlink.php index 5c51014b5..6e1735f60 100644 --- a/inc/Action/Backlink.php +++ b/inc/Action/Backlink.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\Backlinks; use dokuwiki\Ui; /** @@ -22,7 +23,6 @@ class Backlink extends AbstractAction /** @inheritdoc */ public function tplContent() { - (new Ui\Backlinks)->show(); + (new Backlinks())->show(); } - } diff --git a/inc/Action/Cancel.php b/inc/Action/Cancel.php index d7505e4cc..31b481e99 100644 --- a/inc/Action/Cancel.php +++ b/inc/Action/Cancel.php @@ -11,18 +11,18 @@ use dokuwiki\Action\Exception\ActionAbort; * * @package dokuwiki\Action */ -class Cancel extends AbstractAliasAction { - +class Cancel extends AbstractAliasAction +{ /** * @inheritdoc * @throws ActionAbort */ - public function preProcess() { + public function preProcess() + { global $ID; unlock($ID); // continue with draftdel -> redirect -> show throw new ActionAbort('draftdel'); } - } diff --git a/inc/Action/Check.php b/inc/Action/Check.php index 36ae8e8bd..88d3a3e27 100644 --- a/inc/Action/Check.php +++ b/inc/Action/Check.php @@ -11,16 +11,17 @@ use dokuwiki\Action\Exception\ActionAbort; * * @package dokuwiki\Action */ -class Check extends AbstractAction { - +class Check extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_READ; } - public function preProcess() { + public function preProcess() + { check(); throw new ActionAbort(); } - } diff --git a/inc/Action/Conflict.php b/inc/Action/Conflict.php index f3b9521b9..020d60532 100644 --- a/inc/Action/Conflict.php +++ b/inc/Action/Conflict.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\PageConflict; use dokuwiki\Ui; /** @@ -33,7 +34,6 @@ class Conflict extends AbstractAction global $SUM; $text = con($PRE, $TEXT, $SUF); - (new Ui\PageConflict($text, $SUM))->show(); + (new PageConflict($text, $SUM))->show(); } - } diff --git a/inc/Action/Denied.php b/inc/Action/Denied.php index ab2f0d8f4..14cbd8953 100644 --- a/inc/Action/Denied.php +++ b/inc/Action/Denied.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\Login; use dokuwiki\Extension\Event; use dokuwiki\Ui; @@ -30,7 +31,7 @@ class Denied extends AbstractAction if ($event->advise_before()) { global $INPUT; if (empty($INPUT->server->str('REMOTE_USER')) && actionOK('login')) { - (new Ui\Login)->show(); + (new Login())->show(); } } $event->advise_after(); @@ -46,7 +47,6 @@ class Denied extends AbstractAction public function showBanner() { // print intro - print p_locale_xhtml('denied'); + echo p_locale_xhtml('denied'); } - } diff --git a/inc/Action/Diff.php b/inc/Action/Diff.php index 31024b6cd..c12de9cab 100644 --- a/inc/Action/Diff.php +++ b/inc/Action/Diff.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\PageDiff; use dokuwiki\Ui; /** @@ -35,7 +36,6 @@ class Diff extends AbstractAction public function tplContent() { global $INFO; - (new Ui\PageDiff($INFO['id']))->preference('showIntro', true)->show(); + (new PageDiff($INFO['id']))->preference('showIntro', true)->show(); } - } diff --git a/inc/Action/Draft.php b/inc/Action/Draft.php index 0c33dab54..1abb56d69 100644 --- a/inc/Action/Draft.php +++ b/inc/Action/Draft.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\PageDraft; use dokuwiki\Action\Exception\ActionException; use dokuwiki\Ui; @@ -37,7 +38,6 @@ class Draft extends AbstractAction /** @inheritdoc */ public function tplContent() { - (new Ui\PageDraft)->show(); + (new PageDraft())->show(); } - } diff --git a/inc/Action/Draftdel.php b/inc/Action/Draftdel.php index 1fb796601..770a8c7d7 100644 --- a/inc/Action/Draftdel.php +++ b/inc/Action/Draftdel.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Draft; use dokuwiki\Action\Exception\ActionAbort; /** @@ -11,10 +12,11 @@ use dokuwiki\Action\Exception\ActionAbort; * * @package dokuwiki\Action */ -class Draftdel extends AbstractAction { - +class Draftdel extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_EDIT; } @@ -25,14 +27,14 @@ class Draftdel extends AbstractAction { * * @throws ActionAbort */ - public function preProcess() { + public function preProcess() + { global $INFO, $ID; - $draft = new \dokuwiki\Draft($ID, $INFO['client']); + $draft = new Draft($ID, $INFO['client']); if ($draft->isDraftAvailable() && checkSecurityToken()) { $draft->deleteDraft(); } throw new ActionAbort('redirect'); } - } diff --git a/inc/Action/Edit.php b/inc/Action/Edit.php index 417fdb075..e8ac347b2 100644 --- a/inc/Action/Edit.php +++ b/inc/Action/Edit.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\Editor; use dokuwiki\Action\Exception\ActionAbort; use dokuwiki\Ui; @@ -57,7 +58,7 @@ class Edit extends AbstractAction if (!isset($TEXT)) { if ($INFO['exists']) { if ($RANGE) { - list($PRE, $TEXT, $SUF) = rawWikiSlices($RANGE, $ID, $REV); + [$PRE, $TEXT, $SUF] = rawWikiSlices($RANGE, $ID, $REV); } else { $TEXT = rawWiki($ID, $REV); } @@ -90,7 +91,6 @@ class Edit extends AbstractAction /** @inheritdoc */ public function tplContent() { - (new Ui\Editor)->show(); + (new Editor())->show(); } - } diff --git a/inc/Action/Exception/ActionAbort.php b/inc/Action/Exception/ActionAbort.php index 9c188bb4b..4f9006be5 100644 --- a/inc/Action/Exception/ActionAbort.php +++ b/inc/Action/Exception/ActionAbort.php @@ -15,6 +15,6 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class ActionAbort extends ActionException { - +class ActionAbort extends ActionException +{ } diff --git a/inc/Action/Exception/ActionAclRequiredException.php b/inc/Action/Exception/ActionAclRequiredException.php index 64a2c61e3..083fe2a17 100644 --- a/inc/Action/Exception/ActionAclRequiredException.php +++ b/inc/Action/Exception/ActionAclRequiredException.php @@ -12,6 +12,6 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class ActionAclRequiredException extends ActionException { - +class ActionAclRequiredException extends ActionException +{ } diff --git a/inc/Action/Exception/ActionDisabledException.php b/inc/Action/Exception/ActionDisabledException.php index 40a0c7dd7..cf3c07781 100644 --- a/inc/Action/Exception/ActionDisabledException.php +++ b/inc/Action/Exception/ActionDisabledException.php @@ -12,6 +12,6 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class ActionDisabledException extends ActionException { - +class ActionDisabledException extends ActionException +{ } diff --git a/inc/Action/Exception/ActionException.php b/inc/Action/Exception/ActionException.php index 381584c15..57318fb04 100644 --- a/inc/Action/Exception/ActionException.php +++ b/inc/Action/Exception/ActionException.php @@ -13,8 +13,8 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class ActionException extends \Exception { - +class ActionException extends \Exception +{ /** @var string the new action */ protected $newaction; @@ -30,11 +30,12 @@ class ActionException extends \Exception { * @param string|null $newaction the action that should be used next * @param string $message optional message, will not be shown except for some dub classes */ - public function __construct($newaction = null, $message = '') { + public function __construct($newaction = null, $message = '') + { global $INPUT; parent::__construct($message); - if(is_null($newaction)) { - if(strtolower($INPUT->server->str('REQUEST_METHOD')) == 'post') { + if (is_null($newaction)) { + if (strtolower($INPUT->server->str('REQUEST_METHOD')) == 'post') { $newaction = 'redirect'; } else { $newaction = 'show'; @@ -49,7 +50,8 @@ class ActionException extends \Exception { * * @return string */ - public function getNewAction() { + public function getNewAction() + { return $this->newaction; } @@ -59,8 +61,9 @@ class ActionException extends \Exception { * @param null|bool $set when null is given, the current setting is not changed * @return bool */ - public function displayToUser($set = null) { - if(!is_null($set)) $this->displayToUser = $set; + public function displayToUser($set = null) + { + if (!is_null($set)) $this->displayToUser = $set; return $set; } } diff --git a/inc/Action/Exception/ActionUserRequiredException.php b/inc/Action/Exception/ActionUserRequiredException.php index aab06cca1..33ff328a1 100644 --- a/inc/Action/Exception/ActionUserRequiredException.php +++ b/inc/Action/Exception/ActionUserRequiredException.php @@ -12,6 +12,6 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class ActionUserRequiredException extends ActionException { - +class ActionUserRequiredException extends ActionException +{ } diff --git a/inc/Action/Exception/FatalException.php b/inc/Action/Exception/FatalException.php index 42e30ccae..74f45cccb 100644 --- a/inc/Action/Exception/FatalException.php +++ b/inc/Action/Exception/FatalException.php @@ -12,7 +12,8 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class FatalException extends \Exception { +class FatalException extends \Exception +{ /** * FatalException constructor. * @@ -20,7 +21,8 @@ class FatalException extends \Exception { * @param int $status the HTTP status to send * @param null|\Exception $previous previous exception */ - public function __construct($message = 'A fatal error occured', $status = 500, $previous = null) { + public function __construct($message = 'A fatal error occured', $status = 500, $previous = null) + { parent::__construct($message, $status, $previous); } } diff --git a/inc/Action/Exception/NoActionException.php b/inc/Action/Exception/NoActionException.php index 1c4e4d094..23838972f 100644 --- a/inc/Action/Exception/NoActionException.php +++ b/inc/Action/Exception/NoActionException.php @@ -10,6 +10,6 @@ namespace dokuwiki\Action\Exception; * * @package dokuwiki\Action\Exception */ -class NoActionException extends \Exception { - +class NoActionException extends \Exception +{ } diff --git a/inc/Action/Export.php b/inc/Action/Export.php index 6b46b276e..61458e298 100644 --- a/inc/Action/Export.php +++ b/inc/Action/Export.php @@ -12,10 +12,11 @@ use dokuwiki\Extension\Event; * * @package dokuwiki\Action */ -class Export extends AbstractAction { - +class Export extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_READ; } @@ -34,7 +35,8 @@ class Export extends AbstractAction { * @author Michael Klier <chi@chimeric.de> * @inheritdoc */ - public function preProcess() { + public function preProcess() + { global $ID; global $REV; global $conf; @@ -42,13 +44,13 @@ class Export extends AbstractAction { $pre = ''; $post = ''; - $headers = array(); + $headers = []; // search engines: never cache exported docs! (Google only currently) $headers['X-Robots-Tag'] = 'noindex'; $mode = substr($this->actionname, 7); - switch($mode) { + switch ($mode) { case 'raw': $headers['Content-Type'] = 'text/plain; charset=utf-8'; $headers['Content-Disposition'] = 'attachment; filename=' . noNS($ID) . '.txt'; @@ -91,7 +93,7 @@ class Export extends AbstractAction { } // prepare event data - $data = array(); + $data = []; $data['id'] = $ID; $data['mode'] = $mode; $data['headers'] = $headers; @@ -99,15 +101,14 @@ class Export extends AbstractAction { Event::createAndTrigger('ACTION_EXPORT_POSTPROCESS', $data); - if(!empty($data['output'])) { - if(is_array($data['headers'])) foreach($data['headers'] as $key => $val) { + if (!empty($data['output'])) { + if (is_array($data['headers'])) foreach ($data['headers'] as $key => $val) { header("$key: $val"); } - print $pre . $data['output'] . $post; + echo $pre . $data['output'] . $post; exit; } throw new ActionAbort(); } - } diff --git a/inc/Action/Index.php b/inc/Action/Index.php index 17ef6b7fd..5a2120d76 100644 --- a/inc/Action/Index.php +++ b/inc/Action/Index.php @@ -25,5 +25,4 @@ class Index extends AbstractAction global $IDX; (new Ui\Index($IDX))->show(); } - } diff --git a/inc/Action/Locked.php b/inc/Action/Locked.php index bb8437370..6849777bd 100644 --- a/inc/Action/Locked.php +++ b/inc/Action/Locked.php @@ -2,7 +2,7 @@ namespace dokuwiki\Action; -use dokuwiki\Ui; +use dokuwiki\Ui\Editor; /** * Class Locked @@ -23,15 +23,15 @@ class Locked extends AbstractAction public function tplContent() { $this->showBanner(); - (new Ui\Editor)->show(); + (new Editor())->show(); } /** * Display error on locked pages * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function showBanner() { @@ -42,15 +42,16 @@ class Locked extends AbstractAction $locktime = filemtime(wikiLockFN($ID)); $expire = dformat($locktime + $conf['locktime']); - $min = round(($conf['locktime'] - (time() - $locktime) )/60); + $min = round(($conf['locktime'] - (time() - $locktime)) / 60); // print intro - print p_locale_xhtml('locked'); - - print '<ul>'; - print '<li><div class="li"><strong>'.$lang['lockedby'].'</strong> '.editorinfo($INFO['locked']).'</div></li>'; - print '<li><div class="li"><strong>'.$lang['lockexpire'].'</strong> '.$expire.' ('.$min.' min)</div></li>'; - print '</ul>'.DOKU_LF; + echo p_locale_xhtml('locked'); + + echo '<ul>'; + echo '<li><div class="li"><strong>' . $lang['lockedby'] . '</strong> ' . + editorinfo($INFO['locked']) . '</div></li>'; + echo '<li><div class="li"><strong>' . $lang['lockexpire'] . '</strong> ' . + $expire . ' (' . $min . ' min)</div></li>'; + echo '</ul>' . DOKU_LF; } - } diff --git a/inc/Action/Login.php b/inc/Action/Login.php index 6b553f384..6d3d12407 100644 --- a/inc/Action/Login.php +++ b/inc/Action/Login.php @@ -34,7 +34,6 @@ class Login extends AbstractAclAction /** @inheritdoc */ public function tplContent() { - (new Ui\Login)->show(); + (new Ui\Login())->show(); } - } diff --git a/inc/Action/Logout.php b/inc/Action/Logout.php index d9aead529..a4cbfcca5 100644 --- a/inc/Action/Logout.php +++ b/inc/Action/Logout.php @@ -13,24 +13,27 @@ use dokuwiki\Extension\AuthPlugin; * * @package dokuwiki\Action */ -class Logout extends AbstractUserAction { - +class Logout extends AbstractUserAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_NONE; } /** @inheritdoc */ - public function checkPreconditions() { + public function checkPreconditions() + { parent::checkPreconditions(); /** @var AuthPlugin $auth */ global $auth; - if(!$auth->canDo('logout')) throw new ActionDisabledException(); + if (!$auth->canDo('logout')) throw new ActionDisabledException(); } /** @inheritdoc */ - public function preProcess() { + public function preProcess() + { global $ID; global $INPUT; @@ -38,16 +41,15 @@ class Logout extends AbstractUserAction { // when logging out during an edit session, unlock the page $lockedby = checklock($ID); - if($lockedby == $INPUT->server->str('REMOTE_USER')) { + if ($lockedby == $INPUT->server->str('REMOTE_USER')) { unlock($ID); } // do the logout stuff and redirect to login auth_logoff(); - send_redirect(wl($ID, array('do' => 'login'), true, '&')); + send_redirect(wl($ID, ['do' => 'login'], true, '&')); // should never be reached throw new ActionException('login'); } - } diff --git a/inc/Action/Media.php b/inc/Action/Media.php index 77a2a6f0d..0571af855 100644 --- a/inc/Action/Media.php +++ b/inc/Action/Media.php @@ -9,16 +9,17 @@ namespace dokuwiki\Action; * * @package dokuwiki\Action */ -class Media extends AbstractAction { - +class Media extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_READ; } /** @inheritdoc */ - public function tplContent() { + public function tplContent() + { tpl_media(); } - } diff --git a/inc/Action/Plugin.php b/inc/Action/Plugin.php index cbc407839..a38697186 100644 --- a/inc/Action/Plugin.php +++ b/inc/Action/Plugin.php @@ -11,10 +11,11 @@ use dokuwiki\Extension\Event; * * @package dokuwiki\Action */ -class Plugin extends AbstractAction { - +class Plugin extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_NONE; } @@ -24,9 +25,10 @@ class Plugin extends AbstractAction { * @inheritdoc * @triggers TPL_ACT_UNKNOWN */ - public function tplContent() { + public function tplContent() + { $evt = new Event('TPL_ACT_UNKNOWN', $this->actionname); - if($evt->advise_before()) { + if ($evt->advise_before()) { msg('Failed to handle action: ' . hsc($this->actionname), -1); } $evt->advise_after(); diff --git a/inc/Action/Preview.php b/inc/Action/Preview.php index dfe5afaa5..7ab6941df 100644 --- a/inc/Action/Preview.php +++ b/inc/Action/Preview.php @@ -2,6 +2,9 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\Editor; +use dokuwiki\Ui\PageView; +use dokuwiki\Draft; use dokuwiki\Ui; /** @@ -25,8 +28,8 @@ class Preview extends Edit public function tplContent() { global $TEXT; - (new Ui\Editor)->show(); - (new Ui\PageView($TEXT))->show(); + (new Editor())->show(); + (new PageView($TEXT))->show(); } /** @@ -35,7 +38,7 @@ class Preview extends Edit protected function savedraft() { global $ID, $INFO; - $draft = new \dokuwiki\Draft($ID, $INFO['client']); + $draft = new Draft($ID, $INFO['client']); if (!$draft->saveDraft()) { $errors = $draft->getErrors(); foreach ($errors as $error) { @@ -43,5 +46,4 @@ class Preview extends Edit } } } - } diff --git a/inc/Action/Profile.php b/inc/Action/Profile.php index 0ffcb260b..41615af07 100644 --- a/inc/Action/Profile.php +++ b/inc/Action/Profile.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\UserProfile; use dokuwiki\Action\Exception\ActionAbort; use dokuwiki\Action\Exception\ActionDisabledException; use dokuwiki\Extension\AuthPlugin; @@ -29,7 +30,7 @@ class Profile extends AbstractUserAction /** @var AuthPlugin $auth */ global $auth; - if(!$auth->canDo('Profile')) throw new ActionDisabledException(); + if (!$auth->canDo('Profile')) throw new ActionDisabledException(); } /** @inheritdoc */ @@ -45,7 +46,6 @@ class Profile extends AbstractUserAction /** @inheritdoc */ public function tplContent() { - (new Ui\UserProfile)->show(); + (new UserProfile())->show(); } - } diff --git a/inc/Action/ProfileDelete.php b/inc/Action/ProfileDelete.php index d8e434011..5c190cd69 100644 --- a/inc/Action/ProfileDelete.php +++ b/inc/Action/ProfileDelete.php @@ -13,31 +13,33 @@ use dokuwiki\Extension\AuthPlugin; * * @package dokuwiki\Action */ -class ProfileDelete extends AbstractUserAction { - +class ProfileDelete extends AbstractUserAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_NONE; } /** @inheritdoc */ - public function checkPreconditions() { + public function checkPreconditions() + { parent::checkPreconditions(); /** @var AuthPlugin $auth */ global $auth; - if(!$auth->canDo('delUser')) throw new ActionDisabledException(); + if (!$auth->canDo('delUser')) throw new ActionDisabledException(); } /** @inheritdoc */ - public function preProcess() { + public function preProcess() + { global $lang; - if(auth_deleteprofile()) { + if (auth_deleteprofile()) { msg($lang['profdeleted'], 1); throw new ActionAbort('show'); } else { throw new ActionAbort('profile'); } } - } diff --git a/inc/Action/Recent.php b/inc/Action/Recent.php index 203c91d81..f5b45a1ac 100644 --- a/inc/Action/Recent.php +++ b/inc/Action/Recent.php @@ -41,5 +41,4 @@ class Recent extends AbstractAction global $INPUT; (new Ui\Recent($INPUT->extract('first')->int('first'), $this->showType))->show(); } - } diff --git a/inc/Action/Recover.php b/inc/Action/Recover.php index c0e744663..5e5c95dd2 100644 --- a/inc/Action/Recover.php +++ b/inc/Action/Recover.php @@ -11,14 +11,14 @@ use dokuwiki\Action\Exception\ActionAbort; * * @package dokuwiki\Action */ -class Recover extends AbstractAliasAction { - +class Recover extends AbstractAliasAction +{ /** * @inheritdoc * @throws ActionAbort */ - public function preProcess() { + public function preProcess() + { throw new ActionAbort('edit'); } - } diff --git a/inc/Action/Redirect.php b/inc/Action/Redirect.php index dca911a22..5a8309f44 100644 --- a/inc/Action/Redirect.php +++ b/inc/Action/Redirect.php @@ -12,37 +12,35 @@ use dokuwiki\Extension\Event; * * @package dokuwiki\Action */ -class Redirect extends AbstractAliasAction { - +class Redirect extends AbstractAliasAction +{ /** * Redirect to the show action, trying to jump to the previously edited section * * @triggers ACTION_SHOW_REDIRECT * @throws ActionAbort */ - public function preProcess() { + public function preProcess() + { global $PRE; global $TEXT; global $INPUT; global $ID; global $ACT; - $opts = array( - 'id' => $ID, - 'preact' => $ACT - ); + $opts = ['id' => $ID, 'preact' => $ACT]; //get section name when coming from section edit - if($INPUT->has('hid')) { + if ($INPUT->has('hid')) { // Use explicitly transmitted header id $opts['fragment'] = $INPUT->str('hid'); - } else if($PRE && preg_match('/^\s*==+([^=\n]+)/', $TEXT, $match)) { + } elseif ($PRE && preg_match('/^\s*==+([^=\n]+)/', $TEXT, $match)) { // Fallback to old mechanism $check = false; //Byref $opts['fragment'] = sectionID($match[0], $check); } // execute the redirect - Event::createAndTrigger('ACTION_SHOW_REDIRECT', $opts, array($this, 'redirect')); + Event::createAndTrigger('ACTION_SHOW_REDIRECT', $opts, [$this, 'redirect']); // should never be reached throw new ActionAbort('show'); @@ -55,9 +53,10 @@ class Redirect extends AbstractAliasAction { * * @param array $opts id and fragment for the redirect and the preact */ - public function redirect($opts) { + public function redirect($opts) + { $go = wl($opts['id'], '', true, '&'); - if(isset($opts['fragment'])) $go .= '#' . $opts['fragment']; + if (isset($opts['fragment'])) $go .= '#' . $opts['fragment']; //show it send_redirect($go); diff --git a/inc/Action/Register.php b/inc/Action/Register.php index 4c3da19bb..232d21a01 100644 --- a/inc/Action/Register.php +++ b/inc/Action/Register.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\UserRegister; use dokuwiki\Action\Exception\ActionAbort; use dokuwiki\Action\Exception\ActionDisabledException; use dokuwiki\Extension\AuthPlugin; @@ -45,7 +46,6 @@ class Register extends AbstractAclAction /** @inheritdoc */ public function tplContent() { - (new Ui\UserRegister)->show(); + (new UserRegister())->show(); } - } diff --git a/inc/Action/Resendpwd.php b/inc/Action/Resendpwd.php index 0e442346a..2813bfcac 100644 --- a/inc/Action/Resendpwd.php +++ b/inc/Action/Resendpwd.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\UserResendPwd; use dokuwiki\Action\Exception\ActionAbort; use dokuwiki\Action\Exception\ActionDisabledException; use dokuwiki\Extension\AuthPlugin; @@ -46,7 +47,7 @@ class Resendpwd extends AbstractAclAction /** @inheritdoc */ public function tplContent() { - (new Ui\UserResendPwd)->show(); + (new UserResendPwd())->show(); } /** @@ -81,7 +82,7 @@ class Resendpwd extends AbstractAclAction if ($token) { // we're in token phase - get user info from token - $tfile = $conf['cachedir'] .'/'. $token[0] .'/'. $token . '.pwauth'; + $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); @@ -113,15 +114,13 @@ class Resendpwd extends AbstractAclAction } // change it - if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { + if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) { msg($lang['proffail'], -1); return false; } - } else { // autogenerate the password and send by mail - $pass = auth_pwgen($user); - if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { + if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) { msg($lang['proffail'], -1); return false; } @@ -135,7 +134,6 @@ class Resendpwd extends AbstractAclAction @unlink($tfile); return true; - } else { // we're in request phase @@ -156,20 +154,20 @@ class Resendpwd extends AbstractAclAction // generate auth token $token = md5(auth_randombytes(16)); // random secret - $tfile = $conf['cachedir'] .'/'. $token[0] .'/'. $token .'.pwauth'; - $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); + $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; + $url = wl('', ['do' => 'resendpwd', 'pwauth' => $token], true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); - $trep = array( + $trep = [ 'FULLNAME' => $userinfo['name'], 'LOGIN' => $user, 'CONFIRM' => $url - ); + ]; $mail = new \Mailer(); - $mail->to($userinfo['name'] .' <'. $userinfo['mail'] .'>'); + $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>'); $mail->subject($lang['regpwmail']); $mail->setBody($text, $trep); if ($mail->send()) { @@ -181,5 +179,4 @@ class Resendpwd extends AbstractAclAction } // never reached } - } diff --git a/inc/Action/Revert.php b/inc/Action/Revert.php index b7ee75313..4a42fe019 100644 --- a/inc/Action/Revert.php +++ b/inc/Action/Revert.php @@ -14,7 +14,6 @@ use dokuwiki\Action\Exception\ActionException; */ class Revert extends AbstractUserAction { - /** @inheritdoc */ public function minimumPermission() { @@ -59,5 +58,4 @@ class Revert extends AbstractUserAction // continue with draftdel -> redirect -> show throw new ActionAbort('draftdel'); } - } diff --git a/inc/Action/Revisions.php b/inc/Action/Revisions.php index 511a0dc7c..9d8e6047c 100644 --- a/inc/Action/Revisions.php +++ b/inc/Action/Revisions.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\PageRevisions; use dokuwiki\Ui; /** @@ -23,6 +24,6 @@ class Revisions extends AbstractAction public function tplContent() { global $INFO, $INPUT; - (new Ui\PageRevisions($INFO['id']))->show($INPUT->int('first', -1)); + (new PageRevisions($INFO['id']))->show($INPUT->int('first', -1)); } } diff --git a/inc/Action/Save.php b/inc/Action/Save.php index a577e379f..3df208b05 100644 --- a/inc/Action/Save.php +++ b/inc/Action/Save.php @@ -12,12 +12,13 @@ use dokuwiki\Action\Exception\ActionException; * * @package dokuwiki\Action */ -class Save extends AbstractAction { - +class Save extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { global $INFO; - if($INFO['exists']) { + if ($INFO['exists']) { return AUTH_EDIT; } else { return AUTH_CREATE; @@ -25,8 +26,9 @@ class Save extends AbstractAction { } /** @inheritdoc */ - public function preProcess() { - if(!checkSecurityToken()) throw new ActionException('preview'); + public function preProcess() + { + if (!checkSecurityToken()) throw new ActionException('preview'); global $ID; global $DATE; @@ -39,12 +41,13 @@ class Save extends AbstractAction { global $INPUT; //spam check - if(checkwordblock()) { + if (checkwordblock()) { msg($lang['wordblock'], -1); throw new ActionException('edit'); } //conflict check - if($DATE != 0 + if ( + $DATE != 0 && isset($INFO['meta']['date']['modified']) && $INFO['meta']['date']['modified'] > $DATE ) { @@ -59,5 +62,4 @@ class Save extends AbstractAction { // continue with draftdel -> redirect -> show throw new ActionAbort('draftdel'); } - } diff --git a/inc/Action/Search.php b/inc/Action/Search.php index 88bd0baa3..10433d373 100644 --- a/inc/Action/Search.php +++ b/inc/Action/Search.php @@ -11,14 +11,15 @@ use dokuwiki\Action\Exception\ActionAbort; * * @package dokuwiki\Action */ -class Search extends AbstractAction { - - protected $pageLookupResults = array(); - protected $fullTextResults = array(); - protected $highlight = array(); +class Search extends AbstractAction +{ + protected $pageLookupResults = []; + protected $fullTextResults = []; + protected $highlight = []; /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_NONE; } @@ -27,7 +28,8 @@ class Search extends AbstractAction { * * @inheritdoc */ - public function checkPreconditions() { + public function checkPreconditions() + { parent::checkPreconditions(); } @@ -125,7 +127,6 @@ class Search extends AbstractAction { } return '*' . $part . '*'; - }, $queryParts); $QUERY = implode(' ', $queryParts); } diff --git a/inc/Action/Show.php b/inc/Action/Show.php index 14da7fd16..c274e06e6 100644 --- a/inc/Action/Show.php +++ b/inc/Action/Show.php @@ -1,4 +1,5 @@ <?php + /** * Created by IntelliJ IDEA. * User: andi @@ -8,6 +9,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\PageView; use dokuwiki\Ui; /** @@ -20,7 +22,8 @@ use dokuwiki\Ui; class Show extends AbstractAction { /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_READ; } @@ -34,7 +37,6 @@ class Show extends AbstractAction /** @inheritdoc */ public function tplContent() { - (new Ui\PageView())->show(); + (new PageView())->show(); } - } diff --git a/inc/Action/Sitemap.php b/inc/Action/Sitemap.php index eba9c2813..f1f22ab2e 100644 --- a/inc/Action/Sitemap.php +++ b/inc/Action/Sitemap.php @@ -13,10 +13,11 @@ use dokuwiki\Utf8\PhpString; * * @package dokuwiki\Action */ -class Sitemap extends AbstractAction { - +class Sitemap extends AbstractAction +{ /** @inheritdoc */ - public function minimumPermission() { + public function minimumPermission() + { return AUTH_NONE; } @@ -27,26 +28,27 @@ class Sitemap extends AbstractAction { * @throws FatalException * @inheritdoc */ - public function preProcess() { + public function preProcess() + { global $conf; - if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) { + if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) { throw new FatalException('Sitemap generation is disabled', 404); } $sitemap = Mapper::getFilePath(); - if(Mapper::sitemapIsCompressed()) { + if (Mapper::sitemapIsCompressed()) { $mime = 'application/x-gzip'; } else { $mime = 'application/xml; charset=utf-8'; } // Check if sitemap file exists, otherwise create it - if(!is_readable($sitemap)) { + if (!is_readable($sitemap)) { Mapper::generate(); } - if(is_readable($sitemap)) { + if (is_readable($sitemap)) { // Send headers header('Content-Type: ' . $mime); header('Content-Disposition: attachment; filename=' . PhpString::basename($sitemap)); @@ -63,5 +65,4 @@ class Sitemap extends AbstractAction { throw new FatalException('Could not read the sitemap file - bad permissions?'); } - } diff --git a/inc/Action/Source.php b/inc/Action/Source.php index 92b38552b..0d2f822e4 100644 --- a/inc/Action/Source.php +++ b/inc/Action/Source.php @@ -2,6 +2,7 @@ namespace dokuwiki\Action; +use dokuwiki\Ui\Editor; use dokuwiki\Ui; /** @@ -35,7 +36,6 @@ class Source extends AbstractAction /** @inheritdoc */ public function tplContent() { - (new Ui\Editor)->show(); + (new Editor())->show(); } - } diff --git a/inc/Action/Subscribe.php b/inc/Action/Subscribe.php index 5aa3cf1fc..974feb6fd 100644 --- a/inc/Action/Subscribe.php +++ b/inc/Action/Subscribe.php @@ -30,7 +30,7 @@ class Subscribe extends AbstractUserAction parent::checkPreconditions(); global $conf; - if(isset($conf['subscribers']) && !$conf['subscribers']) throw new ActionDisabledException(); + if (isset($conf['subscribers']) && !$conf['subscribers']) throw new ActionDisabledException(); } /** @inheritdoc */ @@ -48,7 +48,7 @@ class Subscribe extends AbstractUserAction /** @inheritdoc */ public function tplContent() { - (new Ui\Subscribe)->show(); + (new Ui\Subscribe())->show(); } /** @@ -65,8 +65,8 @@ class Subscribe extends AbstractUserAction global $INPUT; // get and preprocess data. - $params = array(); - foreach (array('target', 'style', 'action') as $param) { + $params = []; + foreach (['target', 'style', 'action'] as $param) { if ($INPUT->has("sub_$param")) { $params[$param] = $INPUT->str("sub_$param"); } @@ -76,7 +76,7 @@ class Subscribe extends AbstractUserAction if (empty($params['action']) || !checkSecurityToken()) return; // Handle POST data, may throw exception. - Event::createAndTrigger('ACTION_HANDLE_SUBSCRIBE', $params, array($this, 'handlePostData')); + Event::createAndTrigger('ACTION_HANDLE_SUBSCRIBE', $params, [$this, 'handlePostData']); $target = $params['target']; $style = $params['style']; @@ -93,9 +93,11 @@ class Subscribe extends AbstractUserAction if ($ok) { msg( sprintf( - $lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']), + $lang["subscr_{$action}_success"], + hsc($INFO['userinfo']['name']), prettyprint_id($target) - ), 1 + ), + 1 ); throw new ActionAbort('redirect'); } @@ -131,18 +133,22 @@ class Subscribe extends AbstractUserAction throw new Exception('no subscription target given'); } $target = $params['target']; - $valid_styles = array('every', 'digest'); + $valid_styles = ['every', 'digest']; if (substr($target, -1, 1) === ':') { // Allow “list” subscribe style since the target is a namespace. $valid_styles[] = 'list'; } $style = valid_input_set( - 'style', $valid_styles, $params, + 'style', + $valid_styles, + $params, 'invalid subscription style given' ); $action = valid_input_set( - 'action', array('subscribe', 'unsubscribe'), - $params, 'invalid subscription action given' + 'action', + ['subscribe', 'unsubscribe'], + $params, + 'invalid subscription action given' ); // Check other conditions. @@ -170,7 +176,6 @@ class Subscribe extends AbstractUserAction $style = null; } - $params = compact('target', 'style', 'action'); + $params = ['target' => $target, 'style' => $style, 'action' => $action]; } - } diff --git a/inc/ActionRouter.php b/inc/ActionRouter.php index 300a56cd0..daed634d0 100644 --- a/inc/ActionRouter.php +++ b/inc/ActionRouter.php @@ -2,6 +2,7 @@ namespace dokuwiki; +use dokuwiki\Extension\Event; use dokuwiki\Action\AbstractAction; use dokuwiki\Action\Exception\ActionDisabledException; use dokuwiki\Action\Exception\ActionException; @@ -13,19 +14,19 @@ use dokuwiki\Action\Plugin; * Class ActionRouter * @package dokuwiki */ -class ActionRouter { - +class ActionRouter +{ /** @var AbstractAction */ protected $action; /** @var ActionRouter */ - protected static $instance = null; + protected static $instance; /** @var int transition counter */ protected $transitions = 0; /** maximum loop */ - const MAX_TRANSITIONS = 5; + protected const MAX_TRANSITIONS = 5; /** @var string[] the actions disabled in the configuration */ protected $disabled; @@ -36,13 +37,13 @@ class ActionRouter { * Sets up the correct action based on the $ACT global. Writes back * the selected action to $ACT */ - protected function __construct() { + protected function __construct() + { global $ACT; global $conf; $this->disabled = explode(',', $conf['disableactions']); $this->disabled = array_map('trim', $this->disabled); - $this->transitions = 0; $ACT = act_clean($ACT); $this->setupAction($ACT); @@ -55,8 +56,9 @@ class ActionRouter { * @param bool $reinit * @return ActionRouter */ - public static function getInstance($reinit = false) { - if((self::$instance === null) || $reinit) { + public static function getInstance($reinit = false) + { + if ((!self::$instance instanceof \dokuwiki\ActionRouter) || $reinit) { self::$instance = new ActionRouter(); } return self::$instance; @@ -71,12 +73,13 @@ class ActionRouter { * @param string $actionname this is passed as a reference to $ACT, for plugin backward compatibility * @triggers ACTION_ACT_PREPROCESS */ - protected function setupAction(&$actionname) { + protected function setupAction(&$actionname) + { $presetup = $actionname; try { // give plugins an opportunity to process the actionname - $evt = new Extension\Event('ACTION_ACT_PREPROCESS', $actionname); + $evt = new Event('ACTION_ACT_PREPROCESS', $actionname); if ($evt->advise_before()) { $this->action = $this->loadAction($actionname); $this->checkAction($this->action); @@ -86,29 +89,27 @@ class ActionRouter { $this->action = new Plugin($actionname); } $evt->advise_after(); - - } catch(ActionException $e) { + } catch (ActionException $e) { // we should have gotten a new action $actionname = $e->getNewAction(); // this one should trigger a user message - if(is_a($e, ActionDisabledException::class)) { + if ($e instanceof ActionDisabledException) { msg('Action disabled: ' . hsc($presetup), -1); } // some actions may request the display of a message - if($e->displayToUser()) { + if ($e->displayToUser()) { msg(hsc($e->getMessage()), -1); } // do setup for new action $this->transitionAction($presetup, $actionname); - - } catch(NoActionException $e) { + } catch (NoActionException $e) { msg('Action unknown: ' . hsc($actionname), -1); $actionname = 'show'; $this->transitionAction($presetup, $actionname); - } catch(\Exception $e) { + } catch (\Exception $e) { $this->handleFatalException($e); } } @@ -122,16 +123,17 @@ class ActionRouter { * @param string $to new action name * @param null|ActionException $e any previous exception that caused the transition */ - protected function transitionAction($from, $to, $e = null) { + protected function transitionAction($from, $to, $e = null) + { $this->transitions++; // no infinite recursion - if($from == $to) { + if ($from == $to) { $this->handleFatalException(new FatalException('Infinite loop in actions', 500, $e)); } // larger loops will be caught here - if($this->transitions >= self::MAX_TRANSITIONS) { + if ($this->transitions >= self::MAX_TRANSITIONS) { $this->handleFatalException(new FatalException('Maximum action transitions reached', 500, $e)); } @@ -147,13 +149,14 @@ class ActionRouter { * @param \Exception|FatalException $e * @throws FatalException during unit testing */ - protected function handleFatalException(\Exception $e) { - if(is_a($e, FatalException::class)) { + protected function handleFatalException(\Throwable $e) + { + if ($e instanceof FatalException) { http_status($e->getCode()); } else { http_status(500); } - if(defined('DOKU_UNITTEST')) { + if (defined('DOKU_UNITTEST')) { throw $e; } ErrorHandler::logException($e); @@ -175,13 +178,14 @@ class ActionRouter { * @return AbstractAction * @throws NoActionException */ - public function loadAction($actionname) { + public function loadAction($actionname) + { $actionname = strtolower($actionname); // FIXME is this needed here? should we run a cleanup somewhere else? $parts = explode('_', $actionname); - while(!empty($parts)) { - $load = join('_', $parts); + while ($parts !== []) { + $load = implode('_', $parts); $class = 'dokuwiki\\Action\\' . str_replace('_', '', ucwords($load, '_')); - if(class_exists($class)) { + if (class_exists($class)) { return new $class($actionname); } array_pop($parts); @@ -197,23 +201,24 @@ class ActionRouter { * @throws ActionDisabledException * @throws ActionException */ - public function checkAction(AbstractAction $action) { + public function checkAction(AbstractAction $action) + { global $INFO; global $ID; - if(in_array($action->getActionName(), $this->disabled)) { + if (in_array($action->getActionName(), $this->disabled)) { throw new ActionDisabledException(); } $action->checkPreconditions(); - if(isset($INFO)) { + if (isset($INFO)) { $perm = $INFO['perm']; } else { $perm = auth_quickaclcheck($ID); } - if($perm < $action->minimumPermission()) { + if ($perm < $action->minimumPermission()) { throw new ActionException('denied'); } } @@ -223,7 +228,8 @@ class ActionRouter { * * @return AbstractAction */ - public function getAction() { + public function getAction() + { return $this->action; } } diff --git a/inc/Ajax.php b/inc/Ajax.php index fd6abb5e4..2a7de0747 100644 --- a/inc/Ajax.php +++ b/inc/Ajax.php @@ -2,6 +2,9 @@ namespace dokuwiki; +use dokuwiki\Extension\Event; +use dokuwiki\Ui\MediaDiff; +use dokuwiki\Ui\Index; use dokuwiki\Ui; use dokuwiki\Utf8\Sort; @@ -11,21 +14,22 @@ use dokuwiki\Utf8\Sort; * @todo The calls should be refactored out to their own proper classes * @package dokuwiki */ -class Ajax { - +class Ajax +{ /** * Execute the given call * * @param string $call name of the ajax call */ - public function __construct($call) { + public function __construct($call) + { $callfn = 'call' . ucfirst($call); - if(method_exists($this, $callfn)) { + if (method_exists($this, $callfn)) { $this->$callfn(); } else { - $evt = new Extension\Event('AJAX_CALL_UNKNOWN', $call); - if($evt->advise_before()) { - print "AJAX call '" . hsc($call) . "' unknown!\n"; + $evt = new Event('AJAX_CALL_UNKNOWN', $call); + if ($evt->advise_before()) { + echo "AJAX call '" . hsc($call) . "' unknown!\n"; } else { $evt->advise_after(); unset($evt); @@ -38,31 +42,32 @@ class Ajax { * * @author Andreas Gohr <andi@splitbrain.org> */ - protected function callQsearch() { + protected function callQsearch() + { global $lang; global $INPUT; $maxnumbersuggestions = 50; $query = $INPUT->post->str('q'); - if(empty($query)) $query = $INPUT->get->str('q'); - if(empty($query)) return; + if (empty($query)) $query = $INPUT->get->str('q'); + if (empty($query)) return; $query = urldecode($query); $data = ft_pageLookup($query, true, useHeading('navigation')); - if(!count($data)) return; + if ($data === []) return; - print '<strong>' . $lang['quickhits'] . '</strong>'; - print '<ul>'; + echo '<strong>' . $lang['quickhits'] . '</strong>'; + echo '<ul>'; $counter = 0; - foreach($data as $id => $title) { - if(useHeading('navigation')) { + foreach ($data as $id => $title) { + if (useHeading('navigation')) { $name = $title; } else { $ns = getNS($id); - if($ns) { + if ($ns) { $name = noNS($id) . ' (' . $ns . ')'; } else { $name = $id; @@ -71,12 +76,12 @@ class Ajax { echo '<li>' . html_wikilink(':' . $id, $name) . '</li>'; $counter++; - if($counter > $maxnumbersuggestions) { + if ($counter > $maxnumbersuggestions) { echo '<li>...</li>'; break; } } - print '</ul>'; + echo '</ul>'; } /** @@ -85,15 +90,16 @@ class Ajax { * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0 * @author Mike Frysinger <vapier@gentoo.org> */ - protected function callSuggestions() { + protected function callSuggestions() + { global $INPUT; $query = cleanID($INPUT->post->str('q')); - if(empty($query)) $query = cleanID($INPUT->get->str('q')); - if(empty($query)) return; + if (empty($query)) $query = cleanID($INPUT->get->str('q')); + if (empty($query)) return; $data = ft_pageLookup($query); - if(!count($data)) return; + if ($data === []) return; $data = array_keys($data); // limit results to 15 hits @@ -104,15 +110,15 @@ class Ajax { Sort::sort($data); /* now construct a json */ - $suggestions = array( - $query, // the original query - $data, // some suggestions - array(), // no description - array() // no urls - ); + $suggestions = [ + $query, // the original query + $data, // some suggestions + [], // no description + [], // no urls + ]; header('Content-Type: application/x-suggestions+json'); - print json_encode($suggestions); + echo json_encode($suggestions, JSON_THROW_ON_ERROR); } /** @@ -120,13 +126,14 @@ class Ajax { * * Andreas Gohr <andi@splitbrain.org> */ - protected function callLock() { + protected function callLock() + { global $ID; global $INFO; global $INPUT; $ID = cleanID($INPUT->post->str('id')); - if(empty($ID)) return; + if (empty($ID)) return; $INFO = pageinfo(); @@ -135,13 +142,13 @@ class Ajax { 'lock' => '0', 'draft' => '', ]; - if(!$INFO['writable']) { + if (!$INFO['writable']) { $response['errors'][] = 'Permission to write this page has been denied.'; echo json_encode($response); return; } - if(!checklock($ID)) { + if (!checklock($ID)) { lock($ID); $response['lock'] = '1'; } @@ -152,7 +159,7 @@ class Ajax { } else { $response['errors'] = array_merge($response['errors'], $draft->getErrors()); } - echo json_encode($response); + echo json_encode($response, JSON_THROW_ON_ERROR); } /** @@ -160,13 +167,14 @@ class Ajax { * * @author Andreas Gohr <andi@splitbrain.org> */ - protected function callDraftdel() { + protected function callDraftdel() + { global $INPUT; $id = cleanID($INPUT->str('id')); - if(empty($id)) return; + if (empty($id)) return; $client = $INPUT->server->str('REMOTE_USER'); - if(!$client) $client = clientIP(true); + if (!$client) $client = clientIP(true); $draft = new Draft($id, $client); if ($draft->isDraftAvailable() && checkSecurityToken()) { @@ -179,7 +187,8 @@ class Ajax { * * @author Andreas Gohr <andi@splitbrain.org> */ - protected function callMedians() { + protected function callMedians() + { global $conf; global $INPUT; @@ -189,9 +198,9 @@ class Ajax { $lvl = count(explode(':', $ns)); - $data = array(); - search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir); - foreach(array_keys($data) as $item) { + $data = []; + search($data, $conf['mediadir'], 'search_index', ['nofiles' => true], $dir); + foreach (array_keys($data) as $item) { $data[$item]['level'] = $lvl + 1; } echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); @@ -202,13 +211,14 @@ class Ajax { * * @author Andreas Gohr <andi@splitbrain.org> */ - protected function callMedialist() { + protected function callMedialist() + { global $NS; global $INPUT; $NS = cleanID($INPUT->post->str('ns')); $sort = $INPUT->post->bool('recent') ? 'date' : 'natural'; - if($INPUT->post->str('do') == 'media') { + if ($INPUT->post->str('do') == 'media') { tpl_mediaFileList(); } else { tpl_mediaContent(true, $sort); @@ -221,17 +231,18 @@ class Ajax { * * @author Kate Arzamastseva <pshns@ukr.net> */ - protected function callMediadetails() { + protected function callMediadetails() + { global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT; $fullscreen = true; require_once(DOKU_INC . 'lib/exe/mediamanager.php'); $image = ''; - if($INPUT->has('image')) $image = cleanID($INPUT->str('image')); - if(isset($IMG)) $image = $IMG; - if(isset($JUMPTO)) $image = $JUMPTO; + if ($INPUT->has('image')) $image = cleanID($INPUT->str('image')); + if (isset($IMG)) $image = $IMG; + if (isset($JUMPTO)) $image = $JUMPTO; $rev = false; - if(isset($REV) && !$JUMPTO) $rev = $REV; + if (isset($REV) && !$JUMPTO) $rev = $REV; html_msgarea(); tpl_mediaFileDetails($image, $rev); @@ -242,12 +253,13 @@ class Ajax { * * @author Kate Arzamastseva <pshns@ukr.net> */ - protected function callMediadiff() { + protected function callMediadiff() + { global $INPUT; $image = ''; - if($INPUT->has('image')) $image = cleanID($INPUT->str('image')); - (new Ui\MediaDiff($image))->preference('fromAjax', true)->show(); + if ($INPUT->has('image')) $image = cleanID($INPUT->str('image')); + (new MediaDiff($image))->preference('fromAjax', true)->show(); } /** @@ -255,13 +267,14 @@ class Ajax { * * @author Kate Arzamastseva <pshns@ukr.net> */ - protected function callMediaupload() { + protected function callMediaupload() + { global $NS, $MSG, $INPUT; $id = ''; - if(isset($_FILES['qqfile']['tmp_name'])) { + if (isset($_FILES['qqfile']['tmp_name'])) { $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']); - } elseif($INPUT->get->has('qqfile')) { + } elseif ($INPUT->get->has('qqfile')) { $id = $INPUT->get->str('qqfile'); } @@ -271,38 +284,35 @@ class Ajax { $ns = $NS . ':' . getNS($id); $AUTH = auth_quickaclcheck("$ns:*"); - if($AUTH >= AUTH_UPLOAD) { + if ($AUTH >= AUTH_UPLOAD) { io_createNamespace("$ns:xxx", 'media'); } - if(isset($_FILES['qqfile']['error']) && $_FILES['qqfile']['error']) unset($_FILES['qqfile']); + if (isset($_FILES['qqfile']['error']) && $_FILES['qqfile']['error']) unset($_FILES['qqfile']); $res = false; - if(isset($_FILES['qqfile']['tmp_name'])) $res = media_upload($NS, $AUTH, $_FILES['qqfile']); - if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH); + if (isset($_FILES['qqfile']['tmp_name'])) $res = media_upload($NS, $AUTH, $_FILES['qqfile']); + if ($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH); - if($res) { - $result = array( + if ($res) { + $result = [ 'success' => true, - 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'), + 'link' => media_managerURL(['ns' => $ns, 'image' => $NS . ':' . $id], '&'), 'id' => $NS . ':' . $id, 'ns' => $NS - ); + ]; } else { $error = ''; - if(isset($MSG)) { - foreach($MSG as $msg) { + if (isset($MSG)) { + foreach ($MSG as $msg) { $error .= $msg['msg']; } } - $result = array( - 'error' => $error, - 'ns' => $NS - ); + $result = ['error' => $error, 'ns' => $NS]; } header('Content-Type: application/json'); - echo json_encode($result); + echo json_encode($result, JSON_THROW_ON_ERROR); } /** @@ -310,7 +320,8 @@ class Ajax { * * @author Andreas Gohr <andi@splitbrain.org> */ - protected function callIndex() { + protected function callIndex() + { global $conf; global $INPUT; @@ -320,12 +331,12 @@ class Ajax { $lvl = count(explode(':', $ns)); - $data = array(); - search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir); + $data = []; + search($data, $conf['datadir'], 'search_index', ['ns' => $ns], $dir); foreach (array_keys($data) as $item) { $data[$item]['level'] = $lvl + 1; } - $idx = new Ui\Index; + $idx = new Index(); echo html_buildlist($data, 'idx', [$idx,'formatListItem'], [$idx,'tagListItem']); } @@ -334,7 +345,8 @@ class Ajax { * * @author Andreas Gohr <gohr@cosmocode.de> */ - protected function callLinkwiz() { + protected function callLinkwiz() + { global $conf; global $lang; global $INPUT; @@ -344,92 +356,81 @@ class Ajax { $ns = getNS($q); $ns = cleanID($ns); + $id = cleanID($id); $nsd = utf8_encodeFN(str_replace(':', '/', $ns)); - $data = array(); - if($q !== '' && $ns === '') { - + $data = []; + if ($q !== '' && $ns === '') { // use index to lookup matching pages $pages = ft_pageLookup($id, true); // If 'useheading' option is 'always' or 'content', // search page titles with original query as well. - if ($conf['useheading'] == '1' || $conf['useheading'] == 'content') { + if ($conf['useheading'] == '1' || $conf['useheading'] == 'content') { $pages = array_merge($pages, ft_pageLookup($q, true, true)); asort($pages, SORT_STRING); } - + // result contains matches in pages and namespaces // we now extract the matching namespaces to show // them seperately - $dirs = array(); + $dirs = []; - foreach($pages as $pid => $title) { - if(strpos(getNS($pid), $id) !== false) { + foreach ($pages as $pid => $title) { + if (strpos(getNS($pid), $id) !== false) { // match was in the namespace $dirs[getNS($pid)] = 1; // assoc array avoids dupes } else { // it is a matching page, add it to the result - $data[] = array( - 'id' => $pid, - 'title' => $title, - 'type' => 'f', - ); + $data[] = ['id' => $pid, 'title' => $title, 'type' => 'f']; } unset($pages[$pid]); } - foreach($dirs as $dir => $junk) { - $data[] = array( - 'id' => $dir, - 'type' => 'd', - ); + foreach (array_keys($dirs) as $dir) { + $data[] = ['id' => $dir, 'type' => 'd']; } - } else { - - $opts = array( + $opts = [ 'depth' => 1, 'listfiles' => true, 'listdirs' => true, 'pagesonly' => true, 'firsthead' => true, - 'sneakyacl' => $conf['sneaky_index'], - ); - if($id) $opts['filematch'] = '^.*\/' . $id; - if($id) $opts['dirmatch'] = '^.*\/' . $id; + 'sneakyacl' => $conf['sneaky_index'] + ]; + if ($id) $opts['filematch'] = '^.*\/' . $id; + if ($id) $opts['dirmatch'] = '^.*\/' . $id; search($data, $conf['datadir'], 'search_universal', $opts, $nsd); // add back to upper - if($ns) { + if ($ns) { array_unshift( - $data, array( - 'id' => getNS($ns), - 'type' => 'u', - ) + $data, + ['id' => getNS($ns), 'type' => 'u'] ); } } // fixme sort results in a useful way ? - if(!count($data)) { + if (!count($data)) { echo $lang['nothingfound']; exit; } // output the found data $even = 1; - foreach($data as $item) { + foreach ($data as $item) { $even *= -1; //zebra - if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':'; + if (($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':'; $link = wl($item['id']); echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">'; - if($item['type'] == 'u') { + if ($item['type'] == 'u') { $name = $lang['upperns']; } else { $name = hsc($item['id']); @@ -437,12 +438,10 @@ class Ajax { echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>'; - if(!blank($item['title'])) { + if (!blank($item['title'])) { echo '<span>' . hsc($item['title']) . '</span>'; } echo '</div>'; } - } - } diff --git a/inc/Cache/Cache.php b/inc/Cache/Cache.php index af82e6bf6..e304943eb 100644 --- a/inc/Cache/Cache.php +++ b/inc/Cache/Cache.php @@ -15,7 +15,7 @@ class Cache public $key = ''; // primary identifier for this item public $ext = ''; // file ext for cache data, secondary identifier for this item public $cache = ''; // cache file name - public $depends = array(); // array containing cache dependency information, + public $depends = []; // array containing cache dependency information, // used by makeDefaultCacheDecision to determine cache validity // phpcs:disable @@ -73,7 +73,7 @@ class Cache * * @return bool true if cache can be used, false otherwise */ - public function useCache($depends = array()) + public function useCache($depends = []) { $this->depends = $depends; $this->addDependencies(); @@ -83,7 +83,7 @@ class Cache Event::createAndTrigger( $this->getEvent(), $this, - array($this, 'makeDefaultCacheDecision') + [$this, 'makeDefaultCacheDecision'] ) ); } @@ -212,7 +212,7 @@ class Cache } if (isset($stats[$this->ext])) { - list($ext, $count, $hits) = explode(',', $stats[$this->ext]); + [$ext, $count, $hits] = explode(',', $stats[$this->ext]); } else { $ext = $this->ext; $count = 0; @@ -225,7 +225,7 @@ class Cache } $stats[$this->ext] = "$ext,$count,$hits"; - io_saveFile($file, join("\n", $stats)); + io_saveFile($file, implode("\n", $stats)); return $success; } diff --git a/inc/Cache/CacheImageMod.php b/inc/Cache/CacheImageMod.php index 5883f7842..bec3ef455 100644 --- a/inc/Cache/CacheImageMod.php +++ b/inc/Cache/CacheImageMod.php @@ -7,7 +7,6 @@ namespace dokuwiki\Cache; */ class CacheImageMod extends Cache { - /** @var string source file */ protected $file; @@ -52,5 +51,4 @@ class CacheImageMod extends Cache getConfigFiles('main') ); } - } diff --git a/inc/Cache/CacheInstructions.php b/inc/Cache/CacheInstructions.php index acd02abae..8bc72d976 100644 --- a/inc/Cache/CacheInstructions.php +++ b/inc/Cache/CacheInstructions.php @@ -5,9 +5,8 @@ namespace dokuwiki\Cache; /** * Caching of parser instructions */ -class CacheInstructions extends \dokuwiki\Cache\CacheParser +class CacheInstructions extends CacheParser { - /** * @param string $id page id * @param string $file source file for cache @@ -26,7 +25,7 @@ class CacheInstructions extends \dokuwiki\Cache\CacheParser public function retrieveCache($clean = true) { $contents = io_readFile($this->cache, false); - return !empty($contents) ? unserialize($contents) : array(); + return empty($contents) ? [] : unserialize($contents); } /** diff --git a/inc/Cache/CacheParser.php b/inc/Cache/CacheParser.php index 4d8550dbe..d885d256b 100644 --- a/inc/Cache/CacheParser.php +++ b/inc/Cache/CacheParser.php @@ -7,7 +7,6 @@ namespace dokuwiki\Cache; */ class CacheParser extends Cache { - public $file = ''; // source file for cache public $mode = ''; // input mode (represents the processing the input file will undergo) public $page = ''; @@ -35,32 +34,30 @@ class CacheParser extends Cache /** * method contains cache use decision logic * - * @return bool see useCache() + * @return bool see useCache() */ public function makeDefaultCacheDecision() { - if (!file_exists($this->file)) { + // source doesn't exist return false; - } // source exists? + } return parent::makeDefaultCacheDecision(); } protected function addDependencies() { - // parser cache file dependencies ... - $files = array( - $this->file, // ... source - DOKU_INC . 'inc/Parsing/Parser.php', // ... parser - DOKU_INC . 'inc/parser/handler.php', // ... handler - ); - $files = array_merge($files, getConfigFiles('main')); // ... wiki settings - - $this->depends['files'] = !empty($this->depends['files']) ? - array_merge($files, $this->depends['files']) : - $files; + $files = [ + $this->file, // source + DOKU_INC . 'inc/Parsing/Parser.php', // parser + DOKU_INC . 'inc/parser/handler.php', // handler + ]; + $files = array_merge($files, getConfigFiles('main')); // wiki settings + + $this->depends['files'] = empty($this->depends['files']) ? + $files : + array_merge($files, $this->depends['files']); parent::addDependencies(); } - } diff --git a/inc/Cache/CacheRenderer.php b/inc/Cache/CacheRenderer.php index e8a28c309..95b330d5a 100644 --- a/inc/Cache/CacheRenderer.php +++ b/inc/Cache/CacheRenderer.php @@ -7,7 +7,6 @@ namespace dokuwiki\Cache; */ class CacheRenderer extends CacheParser { - /** * method contains cache use decision logic * @@ -40,8 +39,10 @@ class CacheRenderer extends CacheParser // for wiki pages, check metadata dependencies $metadata = p_get_metadata($this->page); - if (!isset($metadata['relation']['references']) || - empty($metadata['relation']['references'])) { + if ( + !isset($metadata['relation']['references']) || + empty($metadata['relation']['references']) + ) { return true; } @@ -70,13 +71,10 @@ class CacheRenderer extends CacheParser } // renderer cache file dependencies ... - $files = array( - DOKU_INC . 'inc/parser/' . $this->mode . '.php', // ... the renderer - ); + $files = [DOKU_INC . 'inc/parser/' . $this->mode . '.php']; // page implies metadata and possibly some other dependencies if (isset($this->page)) { - // for xhtml this will render the metadata if needed $valid = p_get_metadata($this->page, 'date valid'); if (!empty($valid['age'])) { @@ -85,9 +83,9 @@ class CacheRenderer extends CacheParser } } - $this->depends['files'] = !empty($this->depends['files']) ? - array_merge($files, $this->depends['files']) : - $files; + $this->depends['files'] = empty($this->depends['files']) ? + $files : + array_merge($files, $this->depends['files']); parent::addDependencies(); } diff --git a/inc/ChangeLog/ChangeLog.php b/inc/ChangeLog/ChangeLog.php index b64c24e83..2d5812a5f 100644 --- a/inc/ChangeLog/ChangeLog.php +++ b/inc/ChangeLog/ChangeLog.php @@ -16,7 +16,7 @@ abstract class ChangeLog /** @var false|int */ protected $currentRevision; /** @var array */ - protected $cache; + protected $cache = []; /** * Constructor @@ -30,7 +30,7 @@ abstract class ChangeLog $this->cache =& $cache_revinfo; if (!isset($this->cache[$id])) { - $this->cache[$id] = array(); + $this->cache[$id] = []; } $this->id = $id; @@ -40,9 +40,10 @@ abstract class ChangeLog /** * Returns path to current page/media * + * @param string|int $rev empty string or revision timestamp * @return string path to file */ - abstract protected function getFilename(); + abstract protected function getFilename($rev = ''); /** * Check whether given revision is the current page @@ -107,7 +108,7 @@ abstract class ChangeLog { if (!is_array($info)) return false; //$this->cache[$this->id][$info['date']] ??= $info; // since php 7.4 - $this->cache[$this->id][$info['date']] = $this->cache[$this->id][$info['date']] ?? $info; + $this->cache[$this->id][$info['date']] ??= $info; return true; } @@ -150,7 +151,7 @@ abstract class ChangeLog } //read lines from changelog - list($fp, $lines) = $this->readloglines($rev); + [$fp, $lines] = $this->readloglines($rev); if ($fp) { fclose($fp); } @@ -158,7 +159,7 @@ abstract class ChangeLog // parse and cache changelog lines foreach ($lines as $value) { - $info = $this->parseLogLine($value); + $info = static::parseLogLine($value); $this->cacheRevisionInfo($info); } if (!isset($this->cache[$this->id][$rev])) { @@ -192,8 +193,8 @@ abstract class ChangeLog */ public function getRevisions($first, $num) { - $revs = array(); - $lines = array(); + $revs = []; + $lines = []; $count = 0; $logfile = $this->getChangelogFilename(); @@ -259,7 +260,7 @@ abstract class ChangeLog // combine with previous chunk $count += count($tmp); - $lines = array_merge($tmp, $lines); + $lines = [...$tmp, ...$lines]; // next chunk if ($finger == 0) { @@ -284,7 +285,7 @@ abstract class ChangeLog // handle lines in reverse order for ($i = count($lines) - 1; $i >= 0; $i--) { - $info = $this->parseLogLine($lines[$i]); + $info = static::parseLogLine($lines[$i]); if ($this->cacheRevisionInfo($info)) { $revs[] = $info['date']; } @@ -321,7 +322,7 @@ abstract class ChangeLog } //get lines from changelog - list($fp, $lines, $head, $tail, $eof) = $this->readloglines($rev); + [$fp, $lines, $head, $tail, $eof] = $this->readloglines($rev); if (empty($lines)) return false; // look for revisions later/earlier than $rev, when founded count till the wanted revision is reached @@ -330,7 +331,7 @@ abstract class ChangeLog $relativeRev = false; $checkOtherChunk = true; //always runs once while (!$relativeRev && $checkOtherChunk) { - $info = array(); + $info = []; //parse in normal or reverse order $count = count($lines); if ($direction > 0) { @@ -340,8 +341,8 @@ abstract class ChangeLog $start = $count - 1; $step = -1; } - for ($i = $start; $i >= 0 && $i < $count; $i = $i + $step) { - $info = $this->parseLogLine($lines[$i]); + for ($i = $start; $i >= 0 && $i < $count; $i += $step) { + $info = static::parseLogLine($lines[$i]); if ($this->cacheRevisionInfo($info)) { //look for revs older/earlier then reference $rev and select $direction-th one if (($direction > 0 && $info['date'] > $rev) || ($direction < 0 && $info['date'] < $rev)) { @@ -356,10 +357,10 @@ abstract class ChangeLog //true when $rev is found, but not the wanted follow-up. $checkOtherChunk = $fp && ($info['date'] == $rev || ($revCounter > 0 && !$relativeRev)) - && !(($tail == $eof && $direction > 0) || ($head == 0 && $direction < 0)); + && (!($tail == $eof && $direction > 0) && !($head == 0 && $direction < 0)); if ($checkOtherChunk) { - list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, $direction); + [$lines, $head, $tail] = $this->readAdjacentChunk($fp, $head, $tail, $direction); if (empty($lines)) break; } @@ -382,7 +383,7 @@ abstract class ChangeLog */ public function getRevisionsAround($rev1, $rev2, $max = 50) { - $max = intval(abs($max) / 2) * 2 + 1; + $max = (int) (abs($max) / 2) * 2 + 1; $rev1 = max($rev1, 0); $rev2 = max($rev2, 0); @@ -397,41 +398,41 @@ abstract class ChangeLog $rev2 = $this->currentRevision(); } //collect revisions around rev2 - list($revs2, $allRevs, $fp, $lines, $head, $tail) = $this->retrieveRevisionsAround($rev2, $max); + [$revs2, $allRevs, $fp, $lines, $head, $tail] = $this->retrieveRevisionsAround($rev2, $max); - if (empty($revs2)) return array(array(), array()); + if (empty($revs2)) return [[], []]; //collect revisions around rev1 $index = array_search($rev1, $allRevs); if ($index === false) { //no overlapping revisions - list($revs1, , , , ,) = $this->retrieveRevisionsAround($rev1, $max); - if (empty($revs1)) $revs1 = array(); + [$revs1, , , , , ] = $this->retrieveRevisionsAround($rev1, $max); + if (empty($revs1)) $revs1 = []; } else { //revisions overlaps, reuse revisions around rev2 $lastRev = array_pop($allRevs); //keep last entry that could be external edit $revs1 = $allRevs; while ($head > 0) { for ($i = count($lines) - 1; $i >= 0; $i--) { - $info = $this->parseLogLine($lines[$i]); + $info = static::parseLogLine($lines[$i]); if ($this->cacheRevisionInfo($info)) { $revs1[] = $info['date']; $index++; - if ($index > intval($max / 2)) break 2; + if ($index > (int) ($max / 2)) break 2; } } - list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1); + [$lines, $head, $tail] = $this->readAdjacentChunk($fp, $head, $tail, -1); } sort($revs1); $revs1[] = $lastRev; //push back last entry //return wanted selection - $revs1 = array_slice($revs1, max($index - intval($max / 2), 0), $max); + $revs1 = array_slice($revs1, max($index - (int) ($max / 2), 0), $max); } - return array(array_reverse($revs1), array_reverse($revs2)); + return [array_reverse($revs1), array_reverse($revs2)]; } /** @@ -447,12 +448,11 @@ abstract class ChangeLog //requested date_at(timestamp) younger or equal then modified_time($this->id) => load current if (file_exists($fileLastMod) && $date_at >= @filemtime($fileLastMod)) { return ''; + } elseif ($rev = $this->getRelativeRevision($date_at + 1, -1)) { + //+1 to get also the requested date revision + return $rev; } else { - if ($rev = $this->getRelativeRevision($date_at + 1, -1)) { //+1 to get also the requested date revision - return $rev; - } else { - return false; - } + return false; } } @@ -477,11 +477,12 @@ abstract class ChangeLog */ protected function retrieveRevisionsAround($rev, $max) { - $revs = array(); - $afterCount = $beforeCount = 0; + $revs = []; + $afterCount = 0; + $beforeCount = 0; //get lines from changelog - list($fp, $lines, $startHead, $startTail, $eof) = $this->readloglines($rev); + [$fp, $lines, $startHead, $startTail, $eof] = $this->readloglines($rev); if (empty($lines)) return false; //parse changelog lines in chunk, and read forward more chunks until $max/2 is reached @@ -489,7 +490,7 @@ abstract class ChangeLog $tail = $startTail; while (count($lines) > 0) { foreach ($lines as $line) { - $info = $this->parseLogLine($line); + $info = static::parseLogLine($line); if ($this->cacheRevisionInfo($info)) { $revs[] = $info['date']; if ($info['date'] >= $rev) { @@ -498,17 +499,18 @@ abstract class ChangeLog if ($afterCount == 1) $beforeCount = count($revs); } //enough revs after reference $rev? - if ($afterCount > intval($max / 2)) break 2; + if ($afterCount > (int) ($max / 2)) break 2; } } //retrieve next chunk - list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, 1); + [$lines, $head, $tail] = $this->readAdjacentChunk($fp, $head, $tail, 1); } $lastTail = $tail; // add a possible revision of external edit, create or deletion - if ($lastTail == $eof && $afterCount <= intval($max / 2) && - count($revs) && !$this->isCurrentRevision($revs[count($revs)-1]) + if ( + $lastTail == $eof && $afterCount <= (int) ($max / 2) && + count($revs) && !$this->isCurrentRevision($revs[count($revs) - 1]) ) { $revs[] = $this->currentRevision; $afterCount++; @@ -520,22 +522,20 @@ abstract class ChangeLog } //read more chunks backward until $max/2 is reached and total number of revs is equal to $max - $lines = array(); + $lines = []; $i = 0; - if ($afterCount > 0) { - $head = $startHead; - $tail = $startTail; - while ($head > 0) { - list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1); + $head = $startHead; + $tail = $startTail; + while ($head > 0) { + [$lines, $head, $tail] = $this->readAdjacentChunk($fp, $head, $tail, -1); - for ($i = count($lines) - 1; $i >= 0; $i--) { - $info = $this->parseLogLine($lines[$i]); - if ($this->cacheRevisionInfo($info)) { - $revs[] = $info['date']; - $beforeCount++; - //enough revs before reference $rev? - if ($beforeCount > max(intval($max / 2), $max - $afterCount)) break 2; - } + for ($i = count($lines) - 1; $i >= 0; $i--) { + $info = static::parseLogLine($lines[$i]); + if ($this->cacheRevisionInfo($info)) { + $revs[] = $info['date']; + $beforeCount++; + //enough revs before reference $rev? + if ($beforeCount > max((int) ($max / 2), $max - $afterCount)) break 2; } } } @@ -547,7 +547,7 @@ abstract class ChangeLog //trunk desired selection $requestedRevs = array_slice($revs, -$max, $max); - return array($requestedRevs, $revs, $fp, $lines, $head, $lastTail); + return [$requestedRevs, $revs, $fp, $lines, $head, $lastTail]; } /** @@ -607,17 +607,16 @@ abstract class ChangeLog // externally deleted, set revision date as late as possible $revInfo = [ - 'date' => max($lastRev +1, time() -1), // 1 sec before now or new page save + 'date' => max($lastRev + 1, time() - 1), // 1 sec before now or new page save 'ip' => '127.0.0.1', 'type' => DOKU_CHANGE_TYPE_DELETE, 'id' => $this->id, 'user' => '', - 'sum' => $lang['deleted'].' - '.$lang['external_edit'].' ('.$lang['unknowndate'].')', + 'sum' => $lang['deleted'] . ' - ' . $lang['external_edit'] . ' (' . $lang['unknowndate'] . ')', 'extra' => '', 'sizechange' => -io_getSizeFile($this->getFilename($lastRev)), 'timestamp' => false, ]; - } else { // item file exists, with timestamp $fileRev // here, file timestamp $fileRev is different with last revision timestamp $lastRev in changelog $isJustCreated = $lastRev === false || ( @@ -630,23 +629,23 @@ abstract class ChangeLog if ($isJustCreated) { $timestamp = $fileRev; - $sum = $lang['created'].' - '.$lang['external_edit']; + $sum = $lang['created'] . ' - ' . $lang['external_edit']; } elseif ($fileRev > $lastRev) { $timestamp = $fileRev; $sum = $lang['external_edit']; } else { // $fileRev is older than $lastRev, that is erroneous/incorrect occurrence. $msg = "Warning: current file modification time is older than last revision date"; - $details = 'File revision: '.$fileRev.' '.dformat($fileRev, "%Y-%m-%d %H:%M:%S")."\n" - .'Last revision: '.$lastRev.' '.dformat($lastRev, "%Y-%m-%d %H:%M:%S"); + $details = 'File revision: ' . $fileRev . ' ' . dformat($fileRev, "%Y-%m-%d %H:%M:%S") . "\n" + . 'Last revision: ' . $lastRev . ' ' . dformat($lastRev, "%Y-%m-%d %H:%M:%S"); Logger::error($msg, $details, $this->getFilename()); $timestamp = false; - $sum = $lang['external_edit'].' ('.$lang['unknowndate'].')'; + $sum = $lang['external_edit'] . ' (' . $lang['unknowndate'] . ')'; } // externally created or edited $revInfo = [ - 'date' => $timestamp ?: $lastRev +1, + 'date' => $timestamp ?: $lastRev + 1, 'ip' => '127.0.0.1', 'type' => $isJustCreated ? DOKU_CHANGE_TYPE_CREATE : DOKU_CHANGE_TYPE_EDIT, 'id' => $this->id, diff --git a/inc/ChangeLog/ChangeLogTrait.php b/inc/ChangeLog/ChangeLogTrait.php index a9609f3aa..f10c53d8b 100644 --- a/inc/ChangeLog/ChangeLogTrait.php +++ b/inc/ChangeLog/ChangeLogTrait.php @@ -19,22 +19,22 @@ trait ChangeLogTrait /** * Parses a changelog line into its components * - * @author Ben Coburn <btcoburn@silicodon.net> - * * @param string $line changelog line * @return array|bool parsed line or false + * @author Ben Coburn <btcoburn@silicodon.net> + * */ public static function parseLogLine($line) { $info = sexplode("\t", rtrim($line, "\n"), 8); if ($info[3]) { // we need at least the page id to consider it a valid line return [ - 'date' => (int)$info[0], // unix timestamp - 'ip' => $info[1], // IP address (127.0.0.1) - 'type' => $info[2], // log line type - 'id' => $info[3], // page id - 'user' => $info[4], // user name - 'sum' => $info[5], // edit summary (or action reason) + 'date' => (int)$info[0], // unix timestamp + 'ip' => $info[1], // IP address (127.0.0.1) + 'type' => $info[2], // log line type + 'id' => $info[3], // page id + 'user' => $info[4], // user name + 'sum' => $info[5], // edit summary (or action reason) 'extra' => $info[6], // extra data (varies by line type) 'sizechange' => ($info[7] != '') ? (int)$info[7] : null, // size difference in bytes ]; @@ -53,18 +53,18 @@ trait ChangeLogTrait public static function buildLogLine(array &$info, $timestamp = null) { $strip = ["\t", "\n"]; - $entry = array( - 'date' => $timestamp ?? $info['date'], - 'ip' => $info['ip'], - 'type' => str_replace($strip, '', $info['type']), - 'id' => $info['id'], - 'user' => $info['user'], - 'sum' => PhpString::substr(str_replace($strip, '', $info['sum'] ?? ''), 0, 255), + $entry = [ + 'date' => $timestamp ?? $info['date'], + 'ip' => $info['ip'], + 'type' => str_replace($strip, '', $info['type']), + 'id' => $info['id'], + 'user' => $info['user'], + 'sum' => PhpString::substr(str_replace($strip, '', $info['sum'] ?? ''), 0, 255), 'extra' => str_replace($strip, '', $info['extra']), - 'sizechange' => $info['sizechange'], - ); + 'sizechange' => $info['sizechange'] + ]; $info = $entry; - return implode("\t", $entry) ."\n"; + return implode("\t", $entry) . "\n"; } /** @@ -98,7 +98,7 @@ trait ChangeLogTrait { if (!is_numeric($chunk_size)) $chunk_size = 0; - $this->chunk_size = (int)max($chunk_size, 0); + $this->chunk_size = max($chunk_size, 0); } /** @@ -145,7 +145,7 @@ trait ChangeLogTrait // find chunk while ($tail - $head > $this->chunk_size) { - $finger = $head + intval(($tail - $head) / 2); + $finger = $head + (int)(($tail - $head) / 2); $finger = $this->getNewlinepointer($fp, $finger); $tmp = fgets($fp); if ($finger == $head || $finger == $tail) { @@ -169,13 +169,7 @@ trait ChangeLogTrait $lines = $this->readChunk($fp, $head, $tail); } - return array( - $fp, - $lines, - $head, - $tail, - $eof, - ); + return [$fp, $lines, $head, $tail, $eof]; } /** @@ -238,12 +232,12 @@ trait ChangeLogTrait */ protected function readAdjacentChunk($fp, $head, $tail, $direction) { - if (!$fp) return array(array(), $head, $tail); + if (!$fp) return [[], $head, $tail]; if ($direction > 0) { //read forward $head = $tail; - $tail = $head + intval($this->chunk_size * (2 / 3)); + $tail = $head + (int)($this->chunk_size * (2 / 3)); $tail = $this->getNewlinepointer($fp, $tail); } else { //read backward @@ -263,7 +257,6 @@ trait ChangeLogTrait //load next chunk $lines = $this->readChunk($fp, $head, $tail); - return array($lines, $head, $tail); + return [$lines, $head, $tail]; } - } diff --git a/inc/ChangeLog/MediaChangeLog.php b/inc/ChangeLog/MediaChangeLog.php index 81279dc45..fd6e3f89f 100644 --- a/inc/ChangeLog/MediaChangeLog.php +++ b/inc/ChangeLog/MediaChangeLog.php @@ -7,7 +7,6 @@ namespace dokuwiki\ChangeLog; */ class MediaChangeLog extends ChangeLog { - /** * Returns path to changelog * @@ -47,8 +46,8 @@ class MediaChangeLog extends ChangeLog if (isset($timestamp)) unset($this->cache[$this->id][$info['date']]); // add changelog lines - $logline = $this->buildLogLine($info, $timestamp); - io_saveFile(mediaMetaFN($this->id,'.changes'), $logline, $append = true); + $logline = static::buildLogLine($info, $timestamp); + io_saveFile(mediaMetaFN($this->id, '.changes'), $logline, $append = true); io_saveFile($conf['media_changelog'], $logline, $append = true); //global changelog cache // update cache @@ -56,5 +55,4 @@ class MediaChangeLog extends ChangeLog $this->cache[$this->id][$this->currentRevision] = $info; return $info; } - } diff --git a/inc/ChangeLog/PageChangeLog.php b/inc/ChangeLog/PageChangeLog.php index 6399d6a56..38fc1ca30 100644 --- a/inc/ChangeLog/PageChangeLog.php +++ b/inc/ChangeLog/PageChangeLog.php @@ -7,7 +7,6 @@ namespace dokuwiki\ChangeLog; */ class PageChangeLog extends ChangeLog { - /** * Returns path to changelog * @@ -47,8 +46,8 @@ class PageChangeLog extends ChangeLog if (isset($timestamp)) unset($this->cache[$this->id][$info['date']]); // add changelog lines - $logline = $this->buildLogLine($info, $timestamp); - io_saveFile(metaFN($this->id,'.changes'), $logline, true); + $logline = static::buildLogLine($info, $timestamp); + io_saveFile(metaFN($this->id, '.changes'), $logline, true); io_saveFile($conf['changelog'], $logline, true); //global changelog cache // update cache @@ -56,5 +55,4 @@ class PageChangeLog extends ChangeLog $this->cache[$this->id][$this->currentRevision] = $info; return $info; } - } diff --git a/inc/ChangeLog/RevisionInfo.php b/inc/ChangeLog/RevisionInfo.php index 40e265177..43bc8c66f 100644 --- a/inc/ChangeLog/RevisionInfo.php +++ b/inc/ChangeLog/RevisionInfo.php @@ -106,11 +106,12 @@ class RevisionInfo public function showFileIcon() { $id = $this->val('id'); - switch ($this->val('mode')) { - case 'media': // media file revision - return media_printicon($id); - case 'page': // page revision - return '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />'; + if ($this->val('mode') == 'media') { + // media file revision + return media_printicon($id); + } elseif ($this->val('mode') == 'page') { + // page revision + return '<img class="icon" src="' . DOKU_BASE . 'lib/images/fileicons/file.png" alt="' . $id . '" />'; } } @@ -127,9 +128,9 @@ class RevisionInfo if ($checkTimestamp && $this->val('timestamp') === false) { // exact date is unknown for externally deleted file // when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__" - $formatted = preg_replace('/[0-9a-zA-Z]/','_', $formatted); + $formatted = preg_replace('/[0-9a-zA-Z]/', '_', $formatted); } - return '<span class="date">'. $formatted .'</span>'; + return '<span class="date">' . $formatted . '</span>'; } /** @@ -140,7 +141,7 @@ class RevisionInfo */ public function showEditSummary() { - return '<span class="sum">'.' – '. hsc($this->val('sum')).'</span>'; + return '<span class="sum">' . ' – ' . hsc($this->val('sum')) . '</span>'; } /** @@ -152,12 +153,12 @@ class RevisionInfo public function showEditor() { if ($this->val('user')) { - $html = '<bdi>'. editorinfo($this->val('user')) .'</bdi>'; - if (auth_ismanager()) $html .= ' <bdo dir="ltr">('. $this->val('ip') .')</bdo>'; + $html = '<bdi>' . editorinfo($this->val('user')) . '</bdi>'; + if (auth_ismanager()) $html .= ' <bdo dir="ltr">(' . $this->val('ip') . ')</bdo>'; } else { - $html = '<bdo dir="ltr">'. $this->val('ip') .'</bdo>'; + $html = '<bdo dir="ltr">' . $this->val('ip') . '</bdo>'; } - return '<span class="user">'. $html. '</span>'; + return '<span class="user">' . $html . '</span>'; } /** @@ -171,37 +172,35 @@ class RevisionInfo $id = $this->val('id'); $rev = $this->isCurrent() ? '' : $this->val('date'); - switch ($this->val('mode')) { - case 'media': // media file revision - $params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id]; - if ($rev) $params += ['rev'=> $rev]; - $href = media_managerURL($params, '&'); - $display_name = $id; - $exists = file_exists(mediaFN($id, $rev)); - break; - case 'page': // page revision - $params = $rev ? ['rev'=> $rev] : []; - $href = wl($id, $params, false, '&'); - $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; - if (!$display_name) $display_name = $id; - $exists = page_exists($id, $rev); + if ($this->val('mode') == 'media') { + // media file revision + $params = ['tab_details' => 'view', 'ns' => getNS($id), 'image' => $id]; + if ($rev) $params += ['rev' => $rev]; + $href = media_managerURL($params, '&'); + $display_name = $id; + $exists = file_exists(mediaFN($id, $rev)); + } elseif ($this->val('mode') == 'page') { + // page revision + $params = $rev ? ['rev' => $rev] : []; + $href = wl($id, $params, false, '&'); + $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id; + if (!$display_name) $display_name = $id; + $exists = page_exists($id, $rev); } - if($exists) { + if ($exists) { $class = 'wikilink1'; + } elseif ($this->isCurrent()) { + //show only not-existing link for current page, which allows for directly create a new page/upload + $class = 'wikilink2'; } else { - if($this->isCurrent()) { - //show only not-existing link for current page, which allows for directly create a new page/upload - $class = 'wikilink2'; - } else { - //revision is not in attic - return $display_name; - } + //revision is not in attic + return $display_name; } if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) { $class = 'wikilink2'; } - return '<a href="'.$href.'" class="'.$class.'">'.$display_name.'</a>'; + return '<a href="' . $href . '" class="' . $class . '">' . $display_name . '</a>'; } /** @@ -217,7 +216,7 @@ class RevisionInfo $id = $this->val('id'); $rev = $this->isCurrent() ? '' : $this->val('date'); - $params = ($rev) ? ['rev'=> $rev] : []; + $params = ($rev) ? ['rev' => $rev] : []; // revision info may have timestamp key when external edits occurred $date = ($this->val('timestamp') === false) @@ -225,30 +224,28 @@ class RevisionInfo : dformat($this->val('date')); - switch ($this->val('mode')) { - case 'media': // media file revision - $href = ml($id, $params, false, '&'); - $exists = file_exists(mediaFN($id, $rev)); - break; - case 'page': // page revision - $href = wl($id, $params, false, '&'); - $exists = page_exists($id, $rev); + if ($this->val('mode') == 'media') { + // media file revision + $href = ml($id, $params, false, '&'); + $exists = file_exists(mediaFN($id, $rev)); + } elseif ($this->val('mode') == 'page') { + // page revision + $href = wl($id, $params, false, '&'); + $exists = page_exists($id, $rev); } - if($exists) { + if ($exists) { $class = 'wikilink1'; + } elseif ($this->isCurrent()) { + //show only not-existing link for current page, which allows for directly create a new page/upload + $class = 'wikilink2'; } else { - if($this->isCurrent()) { - //show only not-existing link for current page, which allows for directly create a new page/upload - $class = 'wikilink2'; - } else { - //revision is not in attic - return $id.' ['.$date.']'; - } + //revision is not in attic + return $id . ' [' . $date . ']'; } if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) { $class = 'wikilink2'; } - return '<bdi><a class="'.$class.'" href="'.$href.'">'.$id.' ['.$date.']'.'</a></bdi>'; + return '<bdi><a class="' . $class . '" href="' . $href . '">' . $id . ' [' . $date . ']' . '</a></bdi>'; } /** @@ -263,33 +260,33 @@ class RevisionInfo $id = $this->val('id'); $href = ''; - switch ($this->val('mode')) { - case 'media': // media file revision - // unlike page, media file does not copied to media_attic when uploaded. - // diff icon will not be shown when external edit occurred - // because no attic file to be compared with current. - $revs = (new MediaChangeLog($id))->getRevisions(0, 1); - $showLink = (count($revs) && file_exists(mediaFN($id,$revs[0])) && file_exists(mediaFN($id))); - if ($showLink) { - $param = ['tab_details'=>'history', 'mediado'=>'diff', 'ns'=> getNS($id), 'image'=> $id]; - $href = media_managerURL($param, '&'); - } - break; - case 'page': // page revision - // when a page just created anyway, it is natural to expect no older revisions - // even if it had once existed but deleted before. Simply ignore to check changelog. - if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE) { - $href = wl($id, ['do'=>'diff'], false, '&'); - } + if ($this->val('mode') == 'media') { + // media file revision + // unlike page, media file does not copied to media_attic when uploaded. + // diff icon will not be shown when external edit occurred + // because no attic file to be compared with current. + $revs = (new MediaChangeLog($id))->getRevisions(0, 1); + $showLink = (count($revs) && file_exists(mediaFN($id, $revs[0])) && file_exists(mediaFN($id))); + if ($showLink) { + $param = ['tab_details' => 'history', 'mediado' => 'diff', 'ns' => getNS($id), 'image' => $id]; + $href = media_managerURL($param, '&'); + } + } elseif ($this->val('mode') == 'page') { + // page revision + // when a page just created anyway, it is natural to expect no older revisions + // even if it had once existed but deleted before. Simply ignore to check changelog. + if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE) { + $href = wl($id, ['do' => 'diff'], false, '&'); + } } if ($href) { - return '<a href="'.$href.'" class="diff_link">' - .'<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' - .' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' - .'</a>'; + return '<a href="' . $href . '" class="diff_link">' + . '<img src="' . DOKU_BASE . 'lib/images/diff.png" width="15" height="11"' + . ' title="' . $lang['diff'] . '" alt="' . $lang['diff'] . '" />' + . '</a>'; } else { - return '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; + return '<img src="' . DOKU_BASE . 'lib/images/blank.gif" width="15" height="11" alt="" />'; } } @@ -306,26 +303,26 @@ class RevisionInfo $rev = $this->isCurrent() ? '' : $this->val('date'); $href = ''; - switch ($this->val('mode')) { - case 'media': // media file revision - if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) { - $param = ['mediado'=>'diff', 'image'=> $id, 'rev'=> $rev]; - $href = media_managerURL($param, '&'); - } - break; - case 'page': // page revision - if (!$this->isCurrent()) { - $href = wl($id, ['rev'=> $rev, 'do'=>'diff'], false, '&'); - } + if ($this->val('mode') == 'media') { + // media file revision + if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) { + $param = ['mediado' => 'diff', 'image' => $id, 'rev' => $rev]; + $href = media_managerURL($param, '&'); + } + } elseif ($this->val('mode') == 'page') { + // page revision + if (!$this->isCurrent()) { + $href = wl($id, ['rev' => $rev, 'do' => 'diff'], false, '&'); + } } if ($href) { - return '<a href="'.$href.'" class="diff_link">' - .'<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"' - .' title="'. $lang['diff'] .'" alt="'.$lang['diff'] .'" />' - .'</a>'; + return '<a href="' . $href . '" class="diff_link">' + . '<img src="' . DOKU_BASE . 'lib/images/diff.png" width="15" height="11"' + . ' title="' . $lang['diff'] . '" alt="' . $lang['diff'] . '" />' + . '</a>'; } else { - return '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />'; + return '<img src="' . DOKU_BASE . 'lib/images/blank.gif" width="15" height="11" alt="" />'; } } @@ -344,17 +341,17 @@ class RevisionInfo } $id = $this->val('id'); - switch ($this->val('mode')) { - case 'media': // media file revision - $param = ['tab_details'=>'history', 'ns'=> getNS($id), 'image'=> $id]; - $href = media_managerURL($param, '&'); - break; - case 'page': // page revision - $href = wl($id, ['do'=>'revisions'], false, '&'); + if ($this->val('mode') == 'media') { + // media file revision + $param = ['tab_details' => 'history', 'ns' => getNS($id), 'image' => $id]; + $href = media_managerURL($param, '&'); + } elseif ($this->val('mode') == 'page') { + // page revision + $href = wl($id, ['do' => 'revisions'], false, '&'); } - return '<a href="'.$href.'" class="revisions_link">' - . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"' - . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />' + return '<a href="' . $href . '" class="revisions_link">' + . '<img src="' . DOKU_BASE . 'lib/images/history.png" width="12" height="14"' + . ' title="' . $lang['btn_revs'] . '" alt="' . $lang['btn_revs'] . '" />' . '</a>'; } @@ -377,7 +374,7 @@ class RevisionInfo } else { $value = '±' . $value; } - return '<span class="'.$class.'">'.$value.'</span>'; + return '<span class="' . $class . '">' . $value . '</span>'; } /** @@ -389,8 +386,6 @@ class RevisionInfo public function showCurrentIndicator() { global $lang; - return $this->isCurrent() ? '('.$lang['current'].')' : ''; + return $this->isCurrent() ? '(' . $lang['current'] . ')' : ''; } - - } diff --git a/inc/Debug/DebugHelper.php b/inc/Debug/DebugHelper.php index f78b88193..4fc8bf9da 100644 --- a/inc/Debug/DebugHelper.php +++ b/inc/Debug/DebugHelper.php @@ -1,15 +1,14 @@ <?php - namespace dokuwiki\Debug; -use Doku_Event; +use dokuwiki\Extension\Event; use dokuwiki\Extension\EventHandler; use dokuwiki\Logger; class DebugHelper { - const INFO_DEPRECATION_LOG_EVENT = 'INFO_DEPRECATION_LOG'; + protected const INFO_DEPRECATION_LOG_EVENT = 'INFO_DEPRECATION_LOG'; /** * Check if deprecation messages shall be handled @@ -24,7 +23,7 @@ class DebugHelper global $EVENT_HANDLER; if ( !Logger::getInstance(Logger::LOG_DEPRECATED)->isLogging() && - ($EVENT_HANDLER === null || !$EVENT_HANDLER->hasHandlerForEvent('INFO_DEPRECATION_LOG')) + (!$EVENT_HANDLER instanceof EventHandler || !$EVENT_HANDLER->hasHandlerForEvent('INFO_DEPRECATION_LOG')) ) { // avoid any work if no one cares return false; @@ -45,31 +44,38 @@ class DebugHelper if (!self::isEnabled()) return; $backtrace = debug_backtrace(); - for ($i = 0; $i < $callerOffset; $i += 1) { - if(count($backtrace) > 1) array_shift($backtrace); + for ($i = 0; $i < $callerOffset; ++$i) { + if (count($backtrace) > 1) array_shift($backtrace); } - list($self, $call) = $backtrace; - - if (!$thing) { - $thing = trim( - (!empty($self['class']) ? ($self['class'] . '::') : '') . - $self['function'] . '()', ':'); - } + [$self, $call] = $backtrace; self::triggerDeprecationEvent( $backtrace, $alternative, - $thing, - trim( - (!empty($call['class']) ? ($call['class'] . '::') : '') . - $call['function'] . '()', ':'), + self::formatCall($self), + self::formatCall($call), $self['file'] ?? $call['file'] ?? '', $self['line'] ?? $call['line'] ?? 0 ); } /** + * Format the given backtrace info into a proper function/method call string + * @param array $call + * @return string + */ + protected static function formatCall($call) + { + $thing = ''; + if (!empty($call['class'])) { + $thing .= $call['class'] . '::'; + } + $thing .= $call['function'] . '()'; + return trim($thing, ':'); + } + + /** * This marks logs a deprecation warning for a property that should no longer be used * * This is usually called withing a magic getter or setter. @@ -119,8 +125,7 @@ class DebugHelper $file, $line, $callerOffset = 1 - ) - { + ) { if (!self::isEnabled()) return; $backtrace = array_slice(debug_backtrace(), $callerOffset); @@ -133,7 +138,6 @@ class DebugHelper $file, $line ); - } /** @@ -151,8 +155,7 @@ class DebugHelper $caller, $file, $line - ) - { + ) { $data = [ 'trace' => $backtrace, 'alternative' => $alternative, @@ -161,7 +164,7 @@ class DebugHelper 'file' => $file, 'line' => $line, ]; - $event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data); + $event = new Event(self::INFO_DEPRECATION_LOG_EVENT, $data); if ($event->advise_before()) { $msg = $event->data['called'] . ' is deprecated. It was called from '; $msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line']; diff --git a/inc/Debug/PropertyDeprecationHelper.php b/inc/Debug/PropertyDeprecationHelper.php index 6289d5ba8..ed6a2dcba 100644 --- a/inc/Debug/PropertyDeprecationHelper.php +++ b/inc/Debug/PropertyDeprecationHelper.php @@ -1,4 +1,5 @@ <?php + /** * Trait for issuing warnings on deprecated access. * @@ -6,7 +7,6 @@ * */ - namespace dokuwiki\Debug; /** @@ -32,7 +32,6 @@ namespace dokuwiki\Debug; */ trait PropertyDeprecationHelper { - /** * List of deprecated properties, in <property name> => <class> format * where <class> is the the name of the class defining the property @@ -108,7 +107,7 @@ trait PropertyDeprecationHelper // The class name is not necessarily correct here but getting the correct class // name would be expensive, this will work most of the time and getting it // wrong is not a big deal. - return __CLASS__; + return self::class; } // property_exists() returns false when the property does exist but is private (and not // defined by the current class, for some value of "current" that differs slightly @@ -124,7 +123,7 @@ trait PropertyDeprecationHelper $classname = substr($obfuscatedProp, 1, -strlen($obfuscatedPropTail)); if ($classname === '*') { // sanity; this shouldn't be possible as protected properties were handled earlier - $classname = __CLASS__; + $classname = self::class; } return $classname; } diff --git a/inc/Draft.php b/inc/Draft.php index ea9431069..4f108f60e 100644 --- a/inc/Draft.php +++ b/inc/Draft.php @@ -2,6 +2,8 @@ namespace dokuwiki; +use dokuwiki\Extension\Event; + /** * Class Draft * @@ -9,7 +11,6 @@ namespace dokuwiki; */ class Draft { - protected $errors = []; protected $cname; protected $id; @@ -26,7 +27,7 @@ class Draft $this->id = $ID; $this->client = $client; $this->cname = getCacheName("$client\n$ID", '.draft'); - if(file_exists($this->cname) && file_exists(wikiFN($ID))) { + if (file_exists($this->cname) && file_exists(wikiFN($ID))) { if (filemtime($this->cname) < filemtime(wikiFN($ID))) { // remove stale draft $this->deleteDraft(); @@ -72,8 +73,10 @@ class Draft if (!$conf['usedraft']) { return false; } - if (!$INPUT->post->has('wikitext') && - !$EVENT_HANDLER->hasHandlerForEvent('DRAFT_SAVE')) { + if ( + !$INPUT->post->has('wikitext') && + !$EVENT_HANDLER->hasHandlerForEvent('DRAFT_SAVE') + ) { return false; } $draft = [ @@ -86,7 +89,7 @@ class Draft 'cname' => $this->cname, 'errors' => [], ]; - $event = new Extension\Event('DRAFT_SAVE', $draft); + $event = new Event('DRAFT_SAVE', $draft); if ($event->advise_before()) { $draft['hasBeenSaved'] = io_saveFile($draft['cname'], serialize($draft)); if ($draft['hasBeenSaved']) { @@ -116,8 +119,8 @@ class Draft "Draft for page $this->id and user $this->client doesn't exist at $this->cname." ); } - $draft = unserialize(io_readFile($this->cname,false)); - return cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true)); + $draft = unserialize(io_readFile($this->cname, false)); + return cleanText(con($draft['prefix'], $draft['text'], $draft['suffix'], true)); } /** diff --git a/inc/ErrorHandler.php b/inc/ErrorHandler.php index a14cbc4df..bd21196b6 100644 --- a/inc/ErrorHandler.php +++ b/inc/ErrorHandler.php @@ -15,7 +15,7 @@ class ErrorHandler * Standard error codes used in PHP errors * @see https://www.php.net/manual/en/errorfunc.constants.php */ - const ERRORCODES = [ + protected const ERRORCODES = [ 1 => 'E_ERROR', 2 => 'E_WARNING', 4 => 'E_PARSE', @@ -43,7 +43,7 @@ class ErrorHandler register_shutdown_function([ErrorHandler::class, 'fatalShutdown']); set_error_handler( [ErrorHandler::class, 'errorHandler'], - E_WARNING|E_USER_ERROR|E_USER_WARNING|E_RECOVERABLE_ERROR + E_WARNING | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR ); } } @@ -126,7 +126,7 @@ EOT; */ public static function logException($e) { - if (is_a($e, \ErrorException::class)) { + if ($e instanceof \ErrorException) { $prefix = self::ERRORCODES[$e->getSeverity()]; } else { $prefix = get_class($e); @@ -165,7 +165,7 @@ EOT; ); self::logException($ex); - if($ex->getSeverity() === E_WARNING && $conf['hidewarnings']) { + if ($ex->getSeverity() === E_WARNING && $conf['hidewarnings']) { return true; } diff --git a/inc/Exception/FatalException.php b/inc/Exception/FatalException.php index f52cc6647..c3035112f 100644 --- a/inc/Exception/FatalException.php +++ b/inc/Exception/FatalException.php @@ -7,5 +7,4 @@ namespace dokuwiki\Exception; */ class FatalException extends \ErrorException { - } diff --git a/inc/Extension/ActionPlugin.php b/inc/Extension/ActionPlugin.php index ed6d82038..7fbd6f7f2 100644 --- a/inc/Extension/ActionPlugin.php +++ b/inc/Extension/ActionPlugin.php @@ -12,11 +12,10 @@ namespace dokuwiki\Extension; */ abstract class ActionPlugin extends Plugin { - /** * Registers a callback function for a given event * - * @param \Doku_Event_Handler $controller + * @param EventHandler $controller */ - abstract public function register(\Doku_Event_Handler $controller); + abstract public function register(EventHandler $controller); } diff --git a/inc/Extension/AdminPlugin.php b/inc/Extension/AdminPlugin.php index 7900a1ec4..099a83623 100644 --- a/inc/Extension/AdminPlugin.php +++ b/inc/Extension/AdminPlugin.php @@ -12,7 +12,6 @@ namespace dokuwiki\Extension; */ abstract class AdminPlugin extends Plugin { - /** * Return the text that is displayed at the main admin menu * (Default localized language string 'menu' is returned, override this function for setting another name) @@ -78,13 +77,14 @@ abstract class AdminPlugin extends Plugin * * @return bool true if the current user may access this admin plugin */ - public function isAccessibleByCurrentUser() { + public function isAccessibleByCurrentUser() + { $data = []; $data['instance'] = $this; $data['hasAccess'] = false; $event = new Event('ADMINPLUGIN_ACCESS_CHECK', $data); - if($event->advise_before()) { + if ($event->advise_before()) { if ($this->forAdminOnly()) { $data['hasAccess'] = auth_isadmin(); } else { @@ -116,8 +116,6 @@ abstract class AdminPlugin extends Plugin */ public function getTOC() { - return array(); + return []; } - } - diff --git a/inc/Extension/AuthPlugin.php b/inc/Extension/AuthPlugin.php index 4b75fba95..4e889f90c 100644 --- a/inc/Extension/AuthPlugin.php +++ b/inc/Extension/AuthPlugin.php @@ -20,7 +20,7 @@ abstract class AuthPlugin extends Plugin * do. The things a backend can do need to be set to true * in the constructor. */ - protected $cando = array( + protected $cando = [ 'addUser' => false, // can Users be created? 'delUser' => false, // can Users be deleted? 'modLogin' => false, // can login names be changed? @@ -33,7 +33,7 @@ abstract class AuthPlugin extends Plugin 'getGroups' => false, // can a list of available groups be retrieved? 'external' => false, // does the module do external auth checking? 'logout' => true, // can the user logout again? (eg. not possible with HTTP auth) - ); + ]; /** * Constructor. @@ -90,7 +90,6 @@ abstract class AuthPlugin extends Plugin return ($this->cando['modPass'] || $this->cando['modName'] || $this->cando['modMail']); - break; case 'UserMod': // can at least anything be changed? return ($this->cando['modPass'] || @@ -99,7 +98,6 @@ abstract class AuthPlugin extends Plugin $this->cando['modLogin'] || $this->cando['modGroups'] || $this->cando['modMail']); - break; default: // print a helping message for developers if (!isset($this->cando[$cap])) { @@ -124,20 +122,20 @@ abstract class AuthPlugin extends Plugin */ public function triggerUserMod($type, $params) { - $validTypes = array( + $validTypes = [ 'create' => 'createUser', 'modify' => 'modifyUser', - 'delete' => 'deleteUsers', - ); + 'delete' => 'deleteUsers' + ]; if (empty($validTypes[$type])) { return false; } $result = false; - $eventdata = array('type' => $type, 'params' => $params, 'modification_result' => null); + $eventdata = ['type' => $type, 'params' => $params, 'modification_result' => null]; $evt = new Event('AUTH_USER_CHANGE', $eventdata); if ($evt->advise_before(true)) { - $result = call_user_func_array(array($this, $validTypes[$type]), $evt->data['params']); + $result = call_user_func_array([$this, $validTypes[$type]], $evt->data['params']); $evt->data['modification_result'] = $result; } $evt->advise_after(); @@ -323,7 +321,7 @@ abstract class AuthPlugin extends Plugin * @param array $filter array of field/pattern pairs, empty array for no filter * @return int */ - public function getUserCount($filter = array()) + public function getUserCount($filter = []) { msg("authorisation method does not provide user counts", -1); return 0; @@ -343,7 +341,7 @@ abstract class AuthPlugin extends Plugin public function retrieveUsers($start = 0, $limit = 0, $filter = null) { msg("authorisation method does not support mass retrieval of user data", -1); - return array(); + return []; } /** @@ -374,7 +372,7 @@ abstract class AuthPlugin extends Plugin public function retrieveGroups($start = 0, $limit = 0) { msg("authorisation method does not support group list retrieval", -1); - return array(); + return []; } /** diff --git a/inc/Extension/CLIPlugin.php b/inc/Extension/CLIPlugin.php index 8637ccf8c..e06e87d2c 100644 --- a/inc/Extension/CLIPlugin.php +++ b/inc/Extension/CLIPlugin.php @@ -2,12 +2,14 @@ namespace dokuwiki\Extension; +use splitbrain\phpcli\CLI; + /** * CLI plugin prototype * * Provides DokuWiki plugin functionality on top of php-cli */ -abstract class CLIPlugin extends \splitbrain\phpcli\CLI implements PluginInterface +abstract class CLIPlugin extends CLI implements PluginInterface { use PluginTrait; } diff --git a/inc/Extension/Event.php b/inc/Extension/Event.php index cc38f0f36..12c9753b8 100644 --- a/inc/Extension/Event.php +++ b/inc/Extension/Event.php @@ -1,4 +1,5 @@ <?php + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps namespace dokuwiki\Extension; @@ -13,13 +14,13 @@ class Event /** @var string READONLY event name, objects must register against this name to see the event */ public $name = ''; /** @var mixed|null READWRITE data relevant to the event, no standardised format, refer to event docs */ - public $data = null; + public $data; /** * @var mixed|null READWRITE the results of the event action, only relevant in "_AFTER" advise * event handlers may modify this if they are preventing the default action * to provide the after event handlers with event results */ - public $result = null; + public $result; /** @var bool READONLY if true, event handlers can prevent the events default action */ public $canPreventDefault = true; @@ -193,7 +194,7 @@ class Event * by default this is the return value of the default action however * it can be set or modified by event handler hooks */ - static public function createAndTrigger($name, &$data, $action = null, $canPreventDefault = true) + public static function createAndTrigger($name, &$data, $action = null, $canPreventDefault = true) { $evt = new Event($name, $data); return $evt->trigger($action, $canPreventDefault); diff --git a/inc/Extension/EventHandler.php b/inc/Extension/EventHandler.php index 33ae5e123..cc537d3c3 100644 --- a/inc/Extension/EventHandler.php +++ b/inc/Extension/EventHandler.php @@ -1,4 +1,5 @@ <?php + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps namespace dokuwiki\Extension; @@ -8,11 +9,10 @@ namespace dokuwiki\Extension; */ class EventHandler { - // public properties: none // private properties - protected $hooks = array(); // array of events and their registered handlers + protected $hooks = []; // array of events and their registered handlers /** * event_handler @@ -31,7 +31,7 @@ class EventHandler foreach ($pluginlist as $plugin_name) { $plugin = plugin_load('action', $plugin_name); - if ($plugin !== null) $plugin->register($this); + if ($plugin instanceof PluginInterface) $plugin->register($this); } } @@ -51,7 +51,7 @@ class EventHandler { $seq = (int)$seq; $doSort = !isset($this->hooks[$event . '_' . $advise][$seq]); - $this->hooks[$event . '_' . $advise][$seq][] = array($obj, $method, $param); + $this->hooks[$event . '_' . $advise][$seq][] = [$obj, $method, $param]; if ($doSort) { ksort($this->hooks[$event . '_' . $advise]); @@ -72,7 +72,7 @@ class EventHandler if (!empty($this->hooks[$evt_name])) { foreach ($this->hooks[$evt_name] as $sequenced_hooks) { foreach ($sequenced_hooks as $hook) { - list($obj, $method, $param) = $hook; + [$obj, $method, $param] = $hook; if ($obj === null) { $method($event, $param); diff --git a/inc/Extension/PluginController.php b/inc/Extension/PluginController.php index d53ea853e..dcdf29cd2 100644 --- a/inc/Extension/PluginController.php +++ b/inc/Extension/PluginController.php @@ -13,7 +13,7 @@ use dokuwiki\ErrorHandler; class PluginController { /** @var array the types of plugins DokuWiki supports */ - const PLUGIN_TYPES = ['auth', 'admin', 'syntax', 'action', 'renderer', 'helper', 'remote', 'cli']; + public const PLUGIN_TYPES = ['auth', 'admin', 'syntax', 'action', 'renderer', 'helper', 'remote', 'cli']; protected $listByType = []; /** @var array all installed plugins and their enabled state [plugin=>enabled] */ @@ -83,7 +83,7 @@ class PluginController //we keep all loaded plugins available in global scope for reuse global $DOKU_PLUGINS; - list($plugin, /* $component */) = $this->splitName($name); + [$plugin, /* component */ ] = $this->splitName($name); // check if disabled if (!$disabled && !$this->isEnabled($plugin)) { @@ -96,8 +96,7 @@ class PluginController //plugin already loaded? if (!empty($DOKU_PLUGINS[$type][$name])) { if ($new || !$DOKU_PLUGINS[$type][$name]->isSingleton()) { - - return class_exists($class, true) ? new $class : null; + return class_exists($class, true) ? new $class() : null; } return $DOKU_PLUGINS[$type][$name]; @@ -115,21 +114,19 @@ class PluginController hsc( $inf['base'] ) - ), -1 + ), + -1 ); } elseif (preg_match('/^' . DOKU_PLUGIN_NAME_REGEX . '$/', $plugin) !== 1) { - msg( - sprintf( - "Plugin name '%s' is not a valid plugin name, only the characters a-z ". - "and 0-9 are allowed. " . - 'Maybe the plugin has been installed in the wrong directory?', hsc($plugin) - ), -1 - ); + msg(sprintf( + 'Plugin name \'%s\' is not a valid plugin name, only the characters a-z and 0-9 are allowed. ' . + 'Maybe the plugin has been installed in the wrong directory?', + hsc($plugin) + ), -1); } return null; } - $DOKU_PLUGINS[$type][$name] = new $class; - + $DOKU_PLUGINS[$type][$name] = new $class(); } catch (\Throwable $e) { ErrorHandler::showExceptionMsg($e, sprintf('Failed to load plugin %s', $plugin)); return null; @@ -204,14 +201,13 @@ class PluginController protected function populateMasterList() { if ($dh = @opendir(DOKU_PLUGIN)) { - $all_plugins = array(); + $all_plugins = []; while (false !== ($plugin = readdir($dh))) { if ($plugin[0] === '.') continue; // skip hidden entries if (is_file(DOKU_PLUGIN . $plugin)) continue; // skip files, we're only interested in directories if (array_key_exists($plugin, $this->masterList) && $this->masterList[$plugin] == 0) { $all_plugins[$plugin] = 0; - } elseif (array_key_exists($plugin, $this->masterList) && $this->masterList[$plugin] == 1) { $all_plugins[$plugin] = 1; } else { @@ -234,7 +230,7 @@ class PluginController */ protected function checkRequire($files) { - $plugins = array(); + $plugins = []; foreach ($files as $file) { if (file_exists($file)) { include_once($file); @@ -297,7 +293,7 @@ class PluginController //gives us the ones we need to check and save $diffed_ones = array_diff_key($local_default, $this->pluginCascade['default']); //The ones which we are sure of (list of 0s not in default) - $sure_plugins = array_filter($diffed_ones, array($this, 'negate')); + $sure_plugins = array_filter($diffed_ones, [$this, 'negate']); //the ones in need of diff $conflicts = array_diff_key($local_default, $diffed_ones); //The final list @@ -311,20 +307,18 @@ class PluginController protected function loadConfig() { global $config_cascade; - foreach (array('default', 'protected') as $type) { + foreach (['default', 'protected'] as $type) { if (array_key_exists($type, $config_cascade['plugins'])) { $this->pluginCascade[$type] = $this->checkRequire($config_cascade['plugins'][$type]); } } $local = $config_cascade['plugins']['local']; $this->lastLocalConfigFile = array_pop($local); - $this->pluginCascade['local'] = $this->checkRequire(array($this->lastLocalConfigFile)); - if (is_array($local)) { - $this->pluginCascade['default'] = array_merge( - $this->pluginCascade['default'], - $this->checkRequire($local) - ); - } + $this->pluginCascade['local'] = $this->checkRequire([$this->lastLocalConfigFile]); + $this->pluginCascade['default'] = array_merge( + $this->pluginCascade['default'], + $this->checkRequire($local) + ); $this->masterList = array_merge( $this->pluginCascade['default'], $this->pluginCascade['local'], @@ -344,11 +338,10 @@ class PluginController { $master_list = $enabled ? array_keys(array_filter($this->masterList)) - : array_keys(array_filter($this->masterList, array($this, 'negate'))); - $plugins = array(); + : array_keys(array_filter($this->masterList, [$this, 'negate'])); + $plugins = []; foreach ($master_list as $plugin) { - if (file_exists(DOKU_PLUGIN . "$plugin/$type.php")) { $plugins[] = $plugin; continue; @@ -366,7 +359,6 @@ class PluginController closedir($dp); } } - }//foreach return $plugins; @@ -386,7 +378,7 @@ class PluginController return sexplode('_', $name, 2, ''); } - return array($name, ''); + return [$name, '']; } /** diff --git a/inc/Extension/PluginInterface.php b/inc/Extension/PluginInterface.php index f2dbe8626..b5ded25ee 100644 --- a/inc/Extension/PluginInterface.php +++ b/inc/Extension/PluginInterface.php @@ -157,6 +157,3 @@ interface PluginInterface */ public function isSingleton(); } - - - diff --git a/inc/Extension/PluginTrait.php b/inc/Extension/PluginTrait.php index 7f399df1a..96c25aeb7 100644 --- a/inc/Extension/PluginTrait.php +++ b/inc/Extension/PluginTrait.php @@ -7,11 +7,10 @@ namespace dokuwiki\Extension; */ trait PluginTrait { - protected $localised = false; // set to true by setupLocale() after loading language dependent strings - protected $lang = array(); // array to hold language dependent strings, best accessed via ->getLang() + protected $lang = []; // array to hold language dependent strings, best accessed via ->getLang() protected $configloaded = false; // set to true by loadConfig() after loading plugin configuration variables - protected $conf = array(); // array to hold plugin settings, best accessed via ->getConf() + protected $conf = []; // array to hold plugin settings, best accessed via ->getConf() /** * @see PluginInterface::getInfo() @@ -25,12 +24,13 @@ trait PluginTrait msg( 'getInfo() not implemented in ' . get_class($this) . ' and ' . $info . ' not found.<br />' . 'Verify you\'re running the latest version of the plugin. If the problem persists, send a ' . - 'bug report to the author of the ' . $parts[2] . ' plugin.', -1 + 'bug report to the author of the ' . $parts[2] . ' plugin.', + -1 ); - return array( + return [ 'date' => '0000-00-00', - 'name' => $parts[2] . ' plugin', - ); + 'name' => $parts[2] . ' plugin' + ]; } /** @@ -58,7 +58,7 @@ trait PluginTrait */ public function getPluginType() { - list($t) = explode('_', get_class($this), 2); + [$t] = explode('_', get_class($this), 2); return $t; } @@ -67,7 +67,7 @@ trait PluginTrait */ public function getPluginName() { - list(/* $t */, /* $p */, $n) = sexplode('_', get_class($this), 4, ''); + [/* t */, /* p */, $n] = sexplode('_', get_class($this), 4, ''); return $n; } @@ -76,7 +76,7 @@ trait PluginTrait */ public function getPluginComponent() { - list(/* $t */, /* $p */, /* $n */, $c) = sexplode('_', get_class($this), 4, ''); + [/* t */, /* p */, /* n */, $c] = sexplode('_', get_class($this), 4, ''); return $c; } @@ -90,7 +90,7 @@ trait PluginTrait { if (!$this->localised) $this->setupLocale(); - return (isset($this->lang[$id]) ? $this->lang[$id] : ''); + return ($this->lang[$id] ?? ''); } /** @@ -129,7 +129,7 @@ trait PluginTrait global $conf, $config_cascade; // definitely don't invoke "global $lang" $path = DOKU_PLUGIN . $this->getPluginName() . '/lang/'; - $lang = array(); + $lang = []; // don't include once, in case several plugin components require the same language file @include($path . 'en/lang.php'); @@ -201,7 +201,7 @@ trait PluginTrait { $path = DOKU_PLUGIN . $this->getPluginName() . '/conf/'; - $conf = array(); + $conf = []; if (file_exists($path . 'default.php')) { include($path . 'default.php'); @@ -221,7 +221,7 @@ trait PluginTrait if (!$email) return $name; $email = obfuscate($email); if (!$name) $name = $email; - $class = "class='" . ($class ? $class : 'mail') . "'"; + $class = "class='" . ($class ?: 'mail') . "'"; return "<a href='mailto:$email' $class title='$email' $more>$name</a>"; } diff --git a/inc/Extension/RemotePlugin.php b/inc/Extension/RemotePlugin.php index 33bca980a..985aa91c9 100644 --- a/inc/Extension/RemotePlugin.php +++ b/inc/Extension/RemotePlugin.php @@ -13,8 +13,7 @@ use ReflectionMethod; */ abstract class RemotePlugin extends Plugin { - - private $api; + private Api $api; /** * Constructor @@ -35,7 +34,7 @@ abstract class RemotePlugin extends Plugin */ public function _getMethods() { - $result = array(); + $result = []; $reflection = new \ReflectionClass($this); foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { @@ -52,17 +51,17 @@ abstract class RemotePlugin extends Plugin // strip asterisks $doc = $method->getDocComment(); $doc = preg_replace( - array('/^[ \t]*\/\*+[ \t]*/m', '/[ \t]*\*+[ \t]*/m', '/\*+\/\s*$/m', '/\s*\/\s*$/m'), - array('', '', '', ''), + ['/^[ \t]*\/\*+[ \t]*/m', '/[ \t]*\*+[ \t]*/m', '/\*+\/\s*$/m', '/\s*\/\s*$/m'], + ['', '', '', ''], $doc ); // prepare data - $data = array(); + $data = []; $data['name'] = $method_name; $data['public'] = 0; $data['doc'] = $doc; - $data['args'] = array(); + $data['args'] = []; // get parameter type from doc block type hint foreach ($method->getParameters() as $parameter) { @@ -104,7 +103,7 @@ abstract class RemotePlugin extends Plugin if ($t === 'boolean') { return 'bool'; } - if (in_array($t, array('array', 'string', 'int', 'double', 'bool', 'null', 'date', 'file'))) { + if (in_array($t, ['array', 'string', 'int', 'double', 'bool', 'null', 'date', 'file'])) { return $t; } } @@ -118,5 +117,4 @@ abstract class RemotePlugin extends Plugin { return $this->api; } - } diff --git a/inc/Extension/SyntaxPlugin.php b/inc/Extension/SyntaxPlugin.php index ea8f51b4d..d590b04e4 100644 --- a/inc/Extension/SyntaxPlugin.php +++ b/inc/Extension/SyntaxPlugin.php @@ -2,6 +2,7 @@ namespace dokuwiki\Extension; +use dokuwiki\Parsing\ParserMode\Plugin; use Doku_Handler; use Doku_Renderer; @@ -14,7 +15,7 @@ use Doku_Renderer; * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */ -abstract class SyntaxPlugin extends \dokuwiki\Parsing\ParserMode\Plugin +abstract class SyntaxPlugin extends Plugin { use PluginTrait; @@ -40,7 +41,7 @@ abstract class SyntaxPlugin extends \dokuwiki\Parsing\ParserMode\Plugin */ public function getAllowedTypes() { - return array(); + return []; } /** @@ -120,7 +121,7 @@ abstract class SyntaxPlugin extends \dokuwiki\Parsing\ParserMode\Plugin $this->allowedModes = array_merge($this->allowedModes, $PARSER_MODES[$mt]); } - $idx = array_search(substr(get_class($this), 7), (array)$this->allowedModes); + $idx = array_search(substr(get_class($this), 7), (array)$this->allowedModes, true); if ($idx !== false) { unset($this->allowedModes[$idx]); } diff --git a/inc/FeedParser.php b/inc/FeedParser.php index 028f1136f..b93ba2937 100644 --- a/inc/FeedParser.php +++ b/inc/FeedParser.php @@ -1,17 +1,19 @@ <?php +use SimplePie\SimplePie; use dokuwiki\FeedParserFile; use SimplePie\File; /** * We override some methods of the original SimplePie class here */ -class FeedParser extends \SimplePie\SimplePie { - +class FeedParser extends SimplePie +{ /** * Constructor. Set some defaults */ - public function __construct(){ + public function __construct() + { parent::__construct(); $this->enable_cache(false); $this->registry->register(File::class, FeedParserFile::class); @@ -23,9 +25,8 @@ class FeedParser extends \SimplePie\SimplePie { * phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps * @param string $url */ - public function feed_url($url){ + public function feed_url($url) + { $this->set_feed_url($url); } } - - diff --git a/inc/FeedParserFile.php b/inc/FeedParserFile.php index b056530dd..3297a0d20 100644 --- a/inc/FeedParserFile.php +++ b/inc/FeedParserFile.php @@ -2,6 +2,8 @@ namespace dokuwiki; +use SimplePie\File; +use SimplePie\SimplePie; use dokuwiki\HTTP\DokuHTTPClient; /** @@ -9,7 +11,7 @@ use dokuwiki\HTTP\DokuHTTPClient; * * Replaces SimplePie's own class */ -class FeedParserFile extends \SimplePie\File +class FeedParserFile extends File { protected $http; /** @noinspection PhpMissingParentConstructorInspection */ @@ -22,13 +24,7 @@ class FeedParserFile extends \SimplePie\File * @inheritdoc */ public function __construct( - $url, - $timeout = 10, - $redirects = 5, - $headers = null, - $useragent = null, - $force_fsockopen = false, - $curl_options = array() + $url ) { $this->http = new DokuHTTPClient(); $this->success = $this->http->sendRequest($url); @@ -37,7 +33,7 @@ class FeedParserFile extends \SimplePie\File $this->body = $this->http->resp_body; $this->error = $this->http->error; - $this->method = \SimplePie\SimplePie::FILE_SOURCE_REMOTE | \SimplePie\SimplePie::FILE_SOURCE_FSOCKOPEN; + $this->method = SimplePie::FILE_SOURCE_REMOTE | SimplePie::FILE_SOURCE_FSOCKOPEN; return $this->success; } diff --git a/inc/File/MediaFile.php b/inc/File/MediaFile.php index d45822ad7..fcb10c250 100644 --- a/inc/File/MediaFile.php +++ b/inc/File/MediaFile.php @@ -27,7 +27,7 @@ class MediaFile $this->id = $id; //FIXME should it be cleaned? $this->path = mediaFN($id, $rev); - list($this->ext, $this->mime, $this->downloadable) = mimetype($this->path, false); + [$this->ext, $this->mime, $this->downloadable] = mimetype($this->path, false); } /** @return string */ @@ -121,7 +121,7 @@ class MediaFile if (!$this->isImage()) return; $info = getimagesize($this->path); if ($info === false) return; - list($this->width, $this->height) = $info; + [$this->width, $this->height] = $info; } /** @@ -154,13 +154,13 @@ class MediaFile */ public function userPermission() { - return auth_quickaclcheck(getNS($this->id).':*'); + return auth_quickaclcheck(getNS($this->id) . ':*'); } /** @return JpegMeta */ public function getMeta() { - if($this->meta === null) $this->meta = new JpegMeta($this->path); + if ($this->meta === null) $this->meta = new JpegMeta($this->path); return $this->meta; } } diff --git a/inc/File/MediaResolver.php b/inc/File/MediaResolver.php index 098584e72..cc65978d0 100644 --- a/inc/File/MediaResolver.php +++ b/inc/File/MediaResolver.php @@ -5,8 +5,8 @@ namespace dokuwiki\File; /** * Creates an absolute media ID from a relative one */ -class MediaResolver extends Resolver { - +class MediaResolver extends Resolver +{ /** @inheritDoc */ public function resolveId($id, $rev = '', $isDateAt = false) { diff --git a/inc/File/PageFile.php b/inc/File/PageFile.php index 965426185..f561c4e12 100644 --- a/inc/File/PageFile.php +++ b/inc/File/PageFile.php @@ -99,20 +99,20 @@ class PageFile $currentSize = file_exists($pagefile) ? filesize($pagefile) : 0; // prepare data for event COMMON_WIKIPAGE_SAVE - $data = array( - 'id' => $this->id, // should not be altered by any handlers - 'file' => $pagefile, // same above - 'changeType' => null, // set prior to event, and confirm later + $data = [ + 'id' => $this->id,// should not be altered by any handlers + 'file' => $pagefile,// same above + 'changeType' => null,// set prior to event, and confirm later 'revertFrom' => $REV, 'oldRevision' => $currentRevision, 'oldContent' => $currentContent, - 'newRevision' => 0, // only available in the after hook + 'newRevision' => 0,// only available in the after hook 'newContent' => $text, 'summary' => $summary, - 'contentChanged' => ($text != $currentContent), // confirm later - 'changeInfo' => '', // automatically determined by revertFrom - 'sizechange' => strlen($text) - strlen($currentContent), // TBD - ); + 'contentChanged' => ($text != $currentContent),// confirm later + 'changeInfo' => '',// automatically determined by revertFrom + 'sizechange' => strlen($text) - strlen($currentContent), + ]; // determine tentatively change type and relevant elements of event data if ($data['revertFrom']) { @@ -166,7 +166,7 @@ class PageFile $data['summary'] = $lang['deleted']; } // send "update" event with empty data, so plugins can react to page deletion - $ioData = array([$pagefile, '', false], getNS($this->id), noNS($this->id), false); + $ioData = [[$pagefile, '', false], getNS($this->id), noNS($this->id), false]; Event::createAndTrigger('IO_WIKIPAGE_WRITE', $ioData); // pre-save deleted revision @touch($pagefile); @@ -210,7 +210,7 @@ class PageFile $this->updateMetadata($logEntry); // update the purgefile (timestamp of the last time anything within the wiki was changed) - io_saveFile($conf['cachedir'].'/purgefile', time()); + io_saveFile($conf['cachedir'] . '/purgefile', time()); return $data; } @@ -238,12 +238,12 @@ class PageFile if (touch($fileLastMod, $revInfo['date'])) { clearstatcache(); $msg = "PageFile($this->id)::detectExternalEdit(): timestamp successfully modified"; - $details = '('.$wrong_timestamp.' -> '.$revInfo['date'].')'; + $details = '(' . $wrong_timestamp . ' -> ' . $revInfo['date'] . ')'; Logger::error($msg, $details, $fileLastMod); } else { // runtime error $msg = "PageFile($this->id)::detectExternalEdit(): page file should be newer than last revision " - .'('.filemtime($fileLastMod).' < '. $this->changelog->lastRevision() .')'; + . '(' . filemtime($fileLastMod) . ' < ' . $this->changelog->lastRevision() . ')'; throw new RuntimeException($msg); } } @@ -286,11 +286,7 @@ class PageFile { global $INFO; - list( - 'date' => $date, - 'type' => $changeType, - 'user' => $user, - ) = $logEntry; + ['date' => $date, 'type' => $changeType, 'user' => $user, ] = $logEntry; $wasRemoved = ($changeType === DOKU_CHANGE_TYPE_DELETE); $wasCreated = ($changeType === DOKU_CHANGE_TYPE_CREATE); @@ -302,9 +298,10 @@ class PageFile if ($wasRemoved) return; $oldmeta = p_read_metadata($this->id)['persistent']; - $meta = array(); + $meta = []; - if ($wasCreated && + if ( + $wasCreated && (empty($oldmeta['date']['created']) || $oldmeta['date']['created'] === $createdDate) ) { // newly created @@ -330,5 +327,4 @@ class PageFile $meta['last_change'] = $logEntry; p_set_metadata($this->id, $meta); } - } diff --git a/inc/File/PageResolver.php b/inc/File/PageResolver.php index 1c10ea674..03edd612a 100644 --- a/inc/File/PageResolver.php +++ b/inc/File/PageResolver.php @@ -7,7 +7,6 @@ namespace dokuwiki\File; */ class PageResolver extends Resolver { - /** * Resolves a given ID to be absolute * @@ -21,7 +20,7 @@ class PageResolver extends Resolver // pages may have a hash attached, we separate it on resolving if (strpos($id, '#') !== false) { - list($id, $hash) = sexplode('#', $id, 2); + [$id, $hash] = sexplode('#', $id, 2); $hash = cleanID($hash); } else { $hash = ''; @@ -95,5 +94,4 @@ class PageResolver extends Resolver } return $id; } - } diff --git a/inc/File/Resolver.php b/inc/File/Resolver.php index e3734cf69..4fe849b63 100644 --- a/inc/File/Resolver.php +++ b/inc/File/Resolver.php @@ -7,7 +7,6 @@ namespace dokuwiki\File; */ abstract class Resolver { - /** @var string context page ID */ protected $contextID; /** @var string namespace of context page ID */ @@ -51,7 +50,7 @@ abstract class Resolver */ protected function resolvePrefix($id) { - if($id === '') return $id; + if ($id === '') return $id; // relative to current page (makes the current page a start page) if ($id[0] === '~') { @@ -94,7 +93,7 @@ abstract class Resolver array_pop($result); continue; } - array_push($result, $dir); + $result[] = $dir; } $id = implode(':', $result); @@ -102,5 +101,4 @@ abstract class Resolver return $id; } - } diff --git a/inc/Form/ButtonElement.php b/inc/Form/ButtonElement.php index 3e110c62d..b68554a8c 100644 --- a/inc/Form/ButtonElement.php +++ b/inc/Form/ButtonElement.php @@ -20,7 +20,7 @@ class ButtonElement extends Element */ public function __construct($name, $content = '') { - parent::__construct('button', array('name' => $name, 'value' => 1)); + parent::__construct('button', ['name' => $name, 'value' => 1]); $this->content = $content; } @@ -31,7 +31,6 @@ class ButtonElement extends Element */ public function toHTML() { - return '<button ' . buildAttributes($this->attrs(), true) . '>'.$this->content.'</button>'; + return '<button ' . buildAttributes($this->attrs(), true) . '>' . $this->content . '</button>'; } - } diff --git a/inc/Form/CheckableElement.php b/inc/Form/CheckableElement.php index d70672bc7..29a3b0d3b 100644 --- a/inc/Form/CheckableElement.php +++ b/inc/Form/CheckableElement.php @@ -29,7 +29,7 @@ class CheckableElement extends InputElement protected function prefillInput() { global $INPUT; - list($name, $key) = $this->getInputName(); + [$name, $key] = $this->getInputName(); $myvalue = $this->val(); if (!$INPUT->has($name)) return; @@ -71,13 +71,12 @@ class CheckableElement extends InputElement public function toHTML() { if ($this->label) { - return '<label '. buildAttributes($this->label->attrs()) .'>'.DOKU_LF - . $this->mainElementHTML() .DOKU_LF - .'<span>'. $this->label->val() .'</span>'.DOKU_LF - .'</label>'; + return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF + . $this->mainElementHTML() . DOKU_LF + . '<span>' . $this->label->val() . '</span>' . DOKU_LF + . '</label>'; } else { return $this->mainElementHTML(); } } - } diff --git a/inc/Form/DropdownElement.php b/inc/Form/DropdownElement.php index e5628cf1d..4e892734c 100644 --- a/inc/Form/DropdownElement.php +++ b/inc/Form/DropdownElement.php @@ -65,7 +65,7 @@ class DropdownElement extends InputElement if (!is_array($optGroups)) { throw new \InvalidArgumentException(hsc('Argument must be an associative array of label => [options]!')); } - $this->optGroups = array(); + $this->optGroups = []; foreach ($optGroups as $label => $options) { $this->addOptGroup($label, $options); } @@ -119,7 +119,7 @@ class DropdownElement extends InputElement // setter $this->values = $this->setValuesInOptGroups((array) $value); - if(!$this->values) { + if (!$this->values) { // unknown value set, select first option instead $this->values = $this->setValuesInOptGroups((array) $this->getFirstOptionKey()); } @@ -189,14 +189,11 @@ class DropdownElement extends InputElement $html = '<select ' . buildAttributes($attr) . '>'; $html = array_reduce( $this->optGroups, - function ($html, OptGroup $optGroup) { - return $html . $optGroup->toHTML(); - }, + static fn($html, OptGroup $optGroup) => $html . $optGroup->toHTML(), $html ); $html .= '</select>'; return $html; } - } diff --git a/inc/Form/Element.php b/inc/Form/Element.php index e1c6147d4..c56c7580a 100644 --- a/inc/Form/Element.php +++ b/inc/Form/Element.php @@ -14,7 +14,7 @@ abstract class Element /** * @var array the attributes of this element */ - protected $attributes = array(); + protected $attributes = []; /** * @var string The type of this element @@ -25,7 +25,7 @@ abstract class Element * @param string $type The type of this element * @param array $attributes */ - public function __construct($type, $attributes = array()) + public function __construct($type, $attributes = []) { $this->type = $type; $this->attributes = $attributes; @@ -117,7 +117,7 @@ abstract class Element $classes[] = $class; $classes = array_unique($classes); $classes = array_filter($classes); - $this->attr('class', join(' ', $classes)); + $this->attr('class', implode(' ', $classes)); return $this; } diff --git a/inc/Form/FieldsetCloseElement.php b/inc/Form/FieldsetCloseElement.php index 5d724a25d..afcc55200 100644 --- a/inc/Form/FieldsetCloseElement.php +++ b/inc/Form/FieldsetCloseElement.php @@ -14,7 +14,7 @@ class FieldsetCloseElement extends TagCloseElement /** * @param array $attributes */ - public function __construct($attributes = array()) + public function __construct($attributes = []) { parent::__construct('', $attributes); $this->type = 'fieldsetclose'; diff --git a/inc/Form/FieldsetOpenElement.php b/inc/Form/FieldsetOpenElement.php index d89771b67..2d9925541 100644 --- a/inc/Form/FieldsetOpenElement.php +++ b/inc/Form/FieldsetOpenElement.php @@ -11,12 +11,11 @@ namespace dokuwiki\Form; */ class FieldsetOpenElement extends TagOpenElement { - /** * @param string $legend * @param array $attributes */ - public function __construct($legend='', $attributes = array()) + public function __construct($legend = '', $attributes = []) { // this is a bit messy and we just do it for the nicer class hierarchy // the parent would expect the tag in $value but we're storing the @@ -32,9 +31,9 @@ class FieldsetOpenElement extends TagOpenElement */ public function toHTML() { - $html = '<fieldset '.buildAttributes($this->attrs()).'>'; + $html = '<fieldset ' . buildAttributes($this->attrs()) . '>'; $legend = $this->val(); - if ($legend) $html .= DOKU_LF.'<legend>'.hsc($legend).'</legend>'; + if ($legend) $html .= DOKU_LF . '<legend>' . hsc($legend) . '</legend>'; return $html; } } diff --git a/inc/Form/Form.php b/inc/Form/Form.php index b84df03b2..ae3145f65 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -16,12 +16,12 @@ class Form extends Element /** * @var array name value pairs for hidden values */ - protected $hidden = array(); + protected $hidden = []; /** * @var Element[] the elements of the form */ - protected $elements = array(); + protected $elements = []; /** * Creates a new, empty form with some default attributes @@ -29,7 +29,7 @@ class Form extends Element * @param array $attributes * @param bool $unsafe if true, then the security token is ommited */ - public function __construct($attributes = array(), $unsafe = false) + public function __construct($attributes = [], $unsafe = false) { global $ID; @@ -175,7 +175,7 @@ class Form extends Element if ($pos < 0) { $this->elements[] = $element; } else { - array_splice($this->elements, $pos, 0, array($element)); + array_splice($this->elements, $pos, 0, [$element]); } return $element; } @@ -191,7 +191,7 @@ class Form extends Element if (is_a($element, '\dokuwiki\Form\Form')) throw new \InvalidArgumentException( 'You can\'t add a form to a form' ); - array_splice($this->elements, $pos, 1, array($element)); + array_splice($this->elements, $pos, 1, [$element]); } /** @@ -321,7 +321,7 @@ class Form extends Element * @param int $pos * @return Element */ - public function addLabel($label, $for='', $pos = -1) + public function addLabel($label, $for = '', $pos = -1) { return $this->addLabelHTML(hsc($label), $for, $pos); } @@ -334,7 +334,7 @@ class Form extends Element * @param int $pos * @return Element */ - public function addLabelHTML($content, $for='', $pos = -1) + public function addLabelHTML($content, $for = '', $pos = -1) { $element = new LabelElement($content); @@ -478,14 +478,14 @@ class Form extends Element // trigger event to provide an opportunity to modify this form if (isset($eventName)) { - $eventName = 'FORM_'.strtoupper($eventName).'_OUTPUT'; + $eventName = 'FORM_' . strtoupper($eventName) . '_OUTPUT'; Event::createAndTrigger($eventName, $this, null, false); } - $html = '<form '. buildAttributes($this->attrs()) .'>'; + $html = '<form ' . buildAttributes($this->attrs()) . '>'; foreach ($this->hidden as $name => $value) { - $html .= '<input type="hidden" name="'. $name .'" value="'. formText($value) .'" />'; + $html .= '<input type="hidden" name="' . $name . '" value="' . formText($value) . '" />'; } foreach ($this->elements as $element) { diff --git a/inc/Form/InputElement.php b/inc/Form/InputElement.php index b7ace8a90..ab6784597 100644 --- a/inc/Form/InputElement.php +++ b/inc/Form/InputElement.php @@ -16,7 +16,7 @@ class InputElement extends Element /** * @var LabelElement */ - protected $label = null; + protected $label; /** * @var bool if the element should reflect posted values @@ -30,7 +30,7 @@ class InputElement extends Element */ public function __construct($type, $name, $label = '') { - parent::__construct($type, array('name' => $name)); + parent::__construct($type, ['name' => $name]); $this->attr('name', $name); $this->attr('type', $type); if ($label) $this->label = new LabelElement($label); @@ -114,7 +114,7 @@ class InputElement extends Element $key = null; } - return array($name, $key); + return [$name, $key]; } /** @@ -124,7 +124,7 @@ class InputElement extends Element { global $INPUT; - list($name, $key) = $this->getInputName(); + [$name, $key] = $this->getInputName(); if (!$INPUT->has($name)) return; if ($key === null) { @@ -148,7 +148,7 @@ class InputElement extends Element protected function mainElementHTML() { if ($this->useInput) $this->prefillInput(); - return '<input '. buildAttributes($this->attrs()) .' />'; + return '<input ' . buildAttributes($this->attrs()) . ' />'; } /** @@ -159,10 +159,10 @@ class InputElement extends Element public function toHTML() { if ($this->label) { - return '<label '. buildAttributes($this->label->attrs()) .'>'.DOKU_LF - .'<span>'. hsc($this->label->val()) .'</span>'.DOKU_LF - . $this->mainElementHTML() .DOKU_LF - .'</label>'; + return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF + . '<span>' . hsc($this->label->val()) . '</span>' . DOKU_LF + . $this->mainElementHTML() . DOKU_LF + . '</label>'; } else { return $this->mainElementHTML(); } diff --git a/inc/Form/LegacyForm.php b/inc/Form/LegacyForm.php index 8232cc713..f5b6e9253 100644 --- a/inc/Form/LegacyForm.php +++ b/inc/Form/LegacyForm.php @@ -26,7 +26,7 @@ class LegacyForm extends Form $this->hidden = $oldform->_hidden; foreach ($oldform->_content as $element) { - list($ctl, $attr) = $this->parseLegacyAttr($element); + [$ctl, $attr] = $this->parseLegacyAttr($element); if (is_array($element)) { switch ($ctl['elem']) { @@ -95,16 +95,13 @@ class LegacyForm extends Form case 'menufield': case 'listboxfield': throw new \UnexpectedValueException('Unsupported legacy field ' . $ctl['elem']); - break; default: throw new \UnexpectedValueException('Unknown legacy field ' . $ctl['elem']); - } } else { $this->addHTML($element); } } - } /** @@ -115,22 +112,22 @@ class LegacyForm extends Form */ protected function parseLegacyAttr($legacy) { - $attributes = array(); - $control = array(); + $attributes = []; + $control = []; foreach ($legacy as $key => $val) { if ($key[0] == '_') { $control[substr($key, 1)] = $val; - } elseif($key == 'name') { + } elseif ($key == 'name') { $control[$key] = $val; - } elseif($key == 'id') { + } elseif ($key == 'id') { $control[$key] = $val; } else { $attributes[$key] = $val; } } - return array($control, $attributes); + return [$control, $attributes]; } /** @@ -141,7 +138,7 @@ class LegacyForm extends Form */ protected function legacyType($type) { - static $types = array( + static $types = [ 'text' => 'textfield', 'password' => 'passwordfield', 'checkbox' => 'checkboxfield', @@ -149,10 +146,9 @@ class LegacyForm extends Form 'tagopen' => 'opentag', 'tagclose' => 'closetag', 'fieldsetopen' => 'openfieldset', - 'fieldsetclose' => 'closefieldset', - ); - if (isset($types[$type])) return $types[$type]; - return $type; + 'fieldsetclose' => 'closefieldset' + ]; + return $types[$type] ?? $type; } /** @@ -174,7 +170,7 @@ class LegacyForm extends Form $data = $element->attrs(); $data['_elem'] = $this->legacyType($element->getType()); $label = $element->getLabel(); - if ($label) { + if ($label instanceof LabelElement) { $data['_class'] = $label->attr('class'); } $legacy->_content[] = $data; diff --git a/inc/Form/OptGroup.php b/inc/Form/OptGroup.php index 8fe8a288d..4e7808de5 100644 --- a/inc/Form/OptGroup.php +++ b/inc/Form/OptGroup.php @@ -13,7 +13,7 @@ class OptGroup extends Element */ public function __construct($label, $options) { - parent::__construct('optGroup', array('label' => $label)); + parent::__construct('optGroup', ['label' => $label]); $this->options($options); } @@ -30,7 +30,7 @@ class OptGroup extends Element { $this->values = []; foreach ($values as $value) { - if(isset($this->options[$value])) { + if (isset($this->options[$value])) { $this->values[] = $value; } } @@ -58,24 +58,28 @@ class OptGroup extends Element { if ($options === null) return $this->options; if (!is_array($options)) throw new \InvalidArgumentException('Options have to be an array'); - $this->options = array(); + $this->options = []; foreach ($options as $key => $val) { if (is_array($val)) { - if (!key_exists('label', $val)) { + if (!array_key_exists('label', $val)) { throw new \InvalidArgumentException( 'If option is given as array, it has to have a "label"-key!' ); } - if (key_exists('attrs', $val) && is_array($val['attrs']) && key_exists('selected', $val['attrs'])) { + if ( + array_key_exists('attrs', $val) && + is_array($val['attrs']) && + array_key_exists('selected', $val['attrs']) + ) { throw new \InvalidArgumentException( 'Please use function "DropdownElement::val()" to set the selected option' ); } $this->options[$key] = $val; } elseif (is_int($key)) { - $this->options[$val] = array('label' => (string)$val); + $this->options[$val] = ['label' => (string)$val]; } else { - $this->options[$key] = array('label' => (string)$val); + $this->options[$key] = ['label' => (string)$val]; } } return $this; diff --git a/inc/Form/TagCloseElement.php b/inc/Form/TagCloseElement.php index 538413e64..20579a16d 100644 --- a/inc/Form/TagCloseElement.php +++ b/inc/Form/TagCloseElement.php @@ -16,7 +16,7 @@ class TagCloseElement extends ValueElement * @param string $tag * @param array $attributes */ - public function __construct($tag, $attributes = array()) + public function __construct($tag, $attributes = []) { parent::__construct('tagclose', $tag, $attributes); } @@ -76,7 +76,7 @@ class TagCloseElement extends ValueElement public function attrs($attributes = null) { if ($attributes === null) { - return array(); + return []; } else { throw new \BadMethodCallException('You can\t add attributes to closing tag'); } @@ -89,7 +89,6 @@ class TagCloseElement extends ValueElement */ public function toHTML() { - return '</'.$this->val().'>'; + return '</' . $this->val() . '>'; } - } diff --git a/inc/Form/TagElement.php b/inc/Form/TagElement.php index 9de1f993d..0dbe136e2 100644 --- a/inc/Form/TagElement.php +++ b/inc/Form/TagElement.php @@ -15,7 +15,7 @@ class TagElement extends ValueElement * @param string $tag * @param array $attributes */ - public function __construct($tag, $attributes = array()) + public function __construct($tag, $attributes = []) { parent::__construct('tag', $tag, $attributes); } @@ -27,6 +27,6 @@ class TagElement extends ValueElement */ public function toHTML() { - return '<'.$this->val().' '.buildAttributes($this->attrs()).' />'; + return '<' . $this->val() . ' ' . buildAttributes($this->attrs()) . ' />'; } } diff --git a/inc/Form/TagOpenElement.php b/inc/Form/TagOpenElement.php index 95dc1c083..1dbfd0ace 100644 --- a/inc/Form/TagOpenElement.php +++ b/inc/Form/TagOpenElement.php @@ -16,7 +16,7 @@ class TagOpenElement extends ValueElement * @param string $tag * @param array $attributes */ - public function __construct($tag, $attributes = array()) + public function __construct($tag, $attributes = []) { parent::__construct('tagopen', $tag, $attributes); } @@ -28,6 +28,6 @@ class TagOpenElement extends ValueElement */ public function toHTML() { - return '<'.$this->val().' '.buildAttributes($this->attrs()).'>'; + return '<' . $this->val() . ' ' . buildAttributes($this->attrs()) . '>'; } } diff --git a/inc/Form/TextareaElement.php b/inc/Form/TextareaElement.php index f1d9796ff..7f515bbdb 100644 --- a/inc/Form/TextareaElement.php +++ b/inc/Form/TextareaElement.php @@ -51,5 +51,4 @@ class TextareaElement extends InputElement return '<textarea ' . buildAttributes($this->attrs()) . '>' . formText($this->val()) . '</textarea>'; } - } diff --git a/inc/Form/ValueElement.php b/inc/Form/ValueElement.php index e996eb794..fab0b4091 100644 --- a/inc/Form/ValueElement.php +++ b/inc/Form/ValueElement.php @@ -23,7 +23,7 @@ abstract class ValueElement extends Element * @param string $value * @param array $attributes */ - public function __construct($type, $value, $attributes = array()) + public function __construct($type, $value, $attributes = []) { parent::__construct($type, $attributes); $this->val($value); @@ -43,5 +43,4 @@ abstract class ValueElement extends Element } return $this->value; } - } diff --git a/inc/HTTP/DokuHTTPClient.php b/inc/HTTP/DokuHTTPClient.php index 6f7f3223a..56d70baae 100644 --- a/inc/HTTP/DokuHTTPClient.php +++ b/inc/HTTP/DokuHTTPClient.php @@ -1,9 +1,8 @@ <?php - namespace dokuwiki\HTTP; - +use dokuwiki\Extension\Event; /** * Adds DokuWiki specific configs to the HTTP client @@ -11,30 +10,31 @@ namespace dokuwiki\HTTP; * @author Andreas Goetz <cpuidle@gmx.de> * @link https://www.dokuwiki.org/devel:httpclient */ -class DokuHTTPClient extends HTTPClient { - +class DokuHTTPClient extends HTTPClient +{ /** * Constructor. * * @author Andreas Gohr <andi@splitbrain.org> */ - public function __construct(){ + public function __construct() + { global $conf; // call parent constructor parent::__construct(); // set some values from the config - $this->proxy_host = $conf['proxy']['host']; - $this->proxy_port = $conf['proxy']['port']; - $this->proxy_user = $conf['proxy']['user']; - $this->proxy_pass = conf_decodeString($conf['proxy']['pass']); - $this->proxy_ssl = $conf['proxy']['ssl']; + $this->proxy_host = $conf['proxy']['host']; + $this->proxy_port = $conf['proxy']['port']; + $this->proxy_user = $conf['proxy']['user']; + $this->proxy_pass = conf_decodeString($conf['proxy']['pass']); + $this->proxy_ssl = $conf['proxy']['ssl']; $this->proxy_except = $conf['proxy']['except']; // allow enabling debugging via URL parameter (if debugging allowed) - if($conf['allowdebug']) { - if( + if ($conf['allowdebug']) { + if ( isset($_REQUEST['httpdebug']) || ( isset($_SERVER['HTTP_REFERER']) && @@ -59,19 +59,21 @@ class DokuHTTPClient extends HTTPClient { * @param string $method * @return bool */ - public function sendRequest($url,$data='',$method='GET'){ - $httpdata = array('url' => $url, - 'data' => $data, - 'method' => $method); - $evt = new \Doku_Event('HTTPCLIENT_REQUEST_SEND',$httpdata); - if($evt->advise_before()){ - $url = $httpdata['url']; - $data = $httpdata['data']; + public function sendRequest($url, $data = '', $method = 'GET') + { + $httpdata = [ + 'url' => $url, + 'data' => $data, + 'method' => $method + ]; + $evt = new Event('HTTPCLIENT_REQUEST_SEND', $httpdata); + if ($evt->advise_before()) { + $url = $httpdata['url']; + $data = $httpdata['data']; $method = $httpdata['method']; } $evt->advise_after(); unset($evt); - return parent::sendRequest($url,$data,$method); + return parent::sendRequest($url, $data, $method); } - } diff --git a/inc/HTTP/HTTPClient.php b/inc/HTTP/HTTPClient.php index 05383d33e..e92edda02 100644 --- a/inc/HTTP/HTTPClient.php +++ b/inc/HTTP/HTTPClient.php @@ -2,7 +2,7 @@ namespace dokuwiki\HTTP; -define('HTTP_NL',"\r\n"); +define('HTTP_NL', "\r\n"); /** @@ -17,28 +17,29 @@ define('HTTP_NL',"\r\n"); * @author Andreas Gohr <andi@splitbrain.org> * @author Tobias Sarnowski <sarnowski@new-thoughts.org> */ -class HTTPClient { +class HTTPClient +{ //set these if you like public $agent; // User agent - public $http; // HTTP version defaults to 1.0 - public $timeout; // read timeout (seconds) - public $cookies; - public $referer; - public $max_redirect; - public $max_bodysize; + public $http = '1.0'; // HTTP version defaults to 1.0 + public $timeout = 15; // read timeout (seconds) + public $cookies = []; + public $referer = ''; + public $max_redirect = 3; + public $max_bodysize = 0; public $max_bodysize_abort = true; // if set, abort if the response body is bigger than max_bodysize - public $header_regexp; // if set this RE must match against the headers, else abort - public $headers; - public $debug; + public $header_regexp = ''; // if set this RE must match against the headers, else abort + public $headers = []; + public $debug = false; public $start = 0.0; // for timings public $keep_alive = true; // keep alive rocks // don't set these, read on error public $error; - public $redirect_count; + public $redirect_count = 0; // read these after a successful request - public $status; + public $status = 0; public $resp_body; public $resp_headers; @@ -55,7 +56,7 @@ class HTTPClient { public $proxy_except; // regexp of URLs to exclude from proxy // list of kept alive connections - protected static $connections = array(); + protected static $connections = []; // what we use as boundary on multipart/form-data posts protected $boundary = '---DokuWikiHTTPClient--4523452351'; @@ -65,21 +66,11 @@ class HTTPClient { * * @author Andreas Gohr <andi@splitbrain.org> */ - public function __construct(){ - $this->agent = 'Mozilla/4.0 (compatible; DokuWiki HTTP Client; '.PHP_OS.')'; - $this->timeout = 15; - $this->cookies = array(); - $this->referer = ''; - $this->max_redirect = 3; - $this->redirect_count = 0; - $this->status = 0; - $this->headers = array(); - $this->http = '1.0'; - $this->debug = false; - $this->max_bodysize = 0; - $this->header_regexp= ''; - if(extension_loaded('zlib')) $this->headers['Accept-encoding'] = 'gzip'; - $this->headers['Accept'] = 'text/xml,application/xml,application/xhtml+xml,'. + public function __construct() + { + $this->agent = 'Mozilla/4.0 (compatible; DokuWiki HTTP Client; ' . PHP_OS . ')'; + if (extension_loaded('zlib')) $this->headers['Accept-encoding'] = 'gzip'; + $this->headers['Accept'] = 'text/xml,application/xml,application/xhtml+xml,' . 'text/html,text/plain,image/png,image/jpeg,image/gif,*/*'; $this->headers['Accept-Language'] = 'en-us'; } @@ -90,16 +81,17 @@ class HTTPClient { * * Returns the wanted page or false on an error; * - * @param string $url The URL to fetch - * @param bool $sloppy304 Return body on 304 not modified + * @param string $url The URL to fetch + * @param bool $sloppy304 Return body on 304 not modified * @return false|string response body, false on error * * @author Andreas Gohr <andi@splitbrain.org> */ - public function get($url,$sloppy304=false){ - if(!$this->sendRequest($url)) return false; - if($this->status == 304 && $sloppy304) return $this->resp_body; - if($this->status < 200 || $this->status > 206) return false; + public function get($url, $sloppy304 = false) + { + if (!$this->sendRequest($url)) return false; + if ($this->status == 304 && $sloppy304) return $this->resp_body; + if ($this->status < 200 || $this->status > 206) return false; return $this->resp_body; } @@ -111,21 +103,22 @@ class HTTPClient { * This is a convenience wrapper around get(). The given parameters * will be correctly encoded and added to the given base URL. * - * @param string $url The URL to fetch - * @param array $data Associative array of parameters - * @param bool $sloppy304 Return body on 304 not modified + * @param string $url The URL to fetch + * @param array $data Associative array of parameters + * @param bool $sloppy304 Return body on 304 not modified * @return false|string response body, false on error * * @author Andreas Gohr <andi@splitbrain.org> */ - public function dget($url,$data,$sloppy304=false){ - if(strpos($url,'?')){ + public function dget($url, $data, $sloppy304 = false) + { + if (strpos($url, '?')) { $url .= '&'; - }else{ + } else { $url .= '?'; } $url .= $this->postEncode($data); - return $this->get($url,$sloppy304); + return $this->get($url, $sloppy304); } /** @@ -133,14 +126,15 @@ class HTTPClient { * * Returns the resulting page or false on an error; * - * @param string $url The URL to fetch - * @param array $data Associative array of parameters + * @param string $url The URL to fetch + * @param array $data Associative array of parameters * @return false|string response body, false on error * @author Andreas Gohr <andi@splitbrain.org> */ - public function post($url,$data){ - if(!$this->sendRequest($url,$data,'POST')) return false; - if($this->status < 200 || $this->status > 206) return false; + public function post($url, $data) + { + if (!$this->sendRequest($url, $data, 'POST')) return false; + if ($this->status < 200 || $this->status > 206) return false; return $this->resp_body; } @@ -153,103 +147,104 @@ class HTTPClient { * Post data should be passed as associative array. When passed as string it will be * sent as is. You will need to setup your own Content-Type header then. * - * @param string $url - the complete URL - * @param mixed $data - the post data either as array or raw data - * @param string $method - HTTP Method usually GET or POST. + * @param string $url - the complete URL + * @param mixed $data - the post data either as array or raw data + * @param string $method - HTTP Method usually GET or POST. * @return bool - true on success * * @author Andreas Goetz <cpuidle@gmx.de> * @author Andreas Gohr <andi@splitbrain.org> */ - public function sendRequest($url,$data='',$method='GET'){ - $this->start = microtime(true); - $this->error = ''; + public function sendRequest($url, $data = '', $method = 'GET') + { + $this->start = microtime(true); + $this->error = ''; $this->status = 0; $this->resp_body = ''; - $this->resp_headers = array(); + $this->resp_headers = []; // save unencoded data for recursive call $unencodedData = $data; // don't accept gzip if truncated bodies might occur - if($this->max_bodysize && + if ( + $this->max_bodysize && !$this->max_bodysize_abort && isset($this->headers['Accept-encoding']) && - $this->headers['Accept-encoding'] == 'gzip'){ + $this->headers['Accept-encoding'] == 'gzip' + ) { unset($this->headers['Accept-encoding']); } // parse URL into bits $uri = parse_url($url); $server = $uri['host']; - $path = !empty($uri['path']) ? $uri['path'] : '/'; - $uriPort = !empty($uri['port']) ? $uri['port'] : null; - if(!empty($uri['query'])) $path .= '?'.$uri['query']; - if(isset($uri['user'])) $this->user = $uri['user']; - if(isset($uri['pass'])) $this->pass = $uri['pass']; + $path = empty($uri['path']) ? '/' : $uri['path']; + $uriPort = empty($uri['port']) ? null : $uri['port']; + if (!empty($uri['query'])) $path .= '?' . $uri['query']; + if (isset($uri['user'])) $this->user = $uri['user']; + if (isset($uri['pass'])) $this->pass = $uri['pass']; // proxy setup - if($this->useProxyForUrl($url)){ + if ($this->useProxyForUrl($url)) { $request_url = $url; - $server = $this->proxy_host; - $port = $this->proxy_port; + $server = $this->proxy_host; + $port = $this->proxy_port; if (empty($port)) $port = 8080; - $use_tls = $this->proxy_ssl; - }else{ + $use_tls = $this->proxy_ssl; + } else { $request_url = $path; $port = $uriPort ?: ($uri['scheme'] == 'https' ? 443 : 80); - $use_tls = ($uri['scheme'] == 'https'); + $use_tls = ($uri['scheme'] == 'https'); } // add SSL stream prefix if needed - needs SSL support in PHP - if($use_tls) { - if(!in_array('ssl', stream_get_transports())) { + if ($use_tls) { + if (!in_array('ssl', stream_get_transports())) { $this->status = -200; $this->error = 'This PHP version does not support SSL - cannot connect to server'; } - $server = 'ssl://'.$server; + $server = 'ssl://' . $server; } // prepare headers - $headers = $this->headers; - $headers['Host'] = $uri['host'] + $headers = $this->headers; + $headers['Host'] = $uri['host'] . ($uriPort ? ':' . $uriPort : ''); $headers['User-Agent'] = $this->agent; - $headers['Referer'] = $this->referer; + $headers['Referer'] = $this->referer; - if($method == 'POST'){ - if(is_array($data)){ + if ($method == 'POST') { + if (is_array($data)) { if (empty($headers['Content-Type'])) { $headers['Content-Type'] = null; } - switch ($headers['Content-Type']) { - case 'multipart/form-data': - $headers['Content-Type'] = 'multipart/form-data; boundary=' . $this->boundary; - $data = $this->postMultipartEncode($data); - break; - default: - $headers['Content-Type'] = 'application/x-www-form-urlencoded'; - $data = $this->postEncode($data); + if ($headers['Content-Type'] == 'multipart/form-data') { + $headers['Content-Type'] = 'multipart/form-data; boundary=' . $this->boundary; + $data = $this->postMultipartEncode($data); + } else { + $headers['Content-Type'] = 'application/x-www-form-urlencoded'; + $data = $this->postEncode($data); } } - }elseif($method == 'GET'){ + } elseif ($method == 'GET') { $data = ''; //no data allowed on GET requests } $contentlength = strlen($data); - if($contentlength) { + if ($contentlength) { $headers['Content-Length'] = $contentlength; } - if($this->user) { - $headers['Authorization'] = 'Basic '.base64_encode($this->user.':'.$this->pass); + if ($this->user) { + $headers['Authorization'] = 'Basic ' . base64_encode($this->user . ':' . $this->pass); } - if($this->proxy_user) { - $headers['Proxy-Authorization'] = 'Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass); + if ($this->proxy_user) { + $headers['Proxy-Authorization'] = 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass); } // already connected? - $connectionId = $this->uniqueConnectionId($server,$port); + $connectionId = $this->uniqueConnectionId($server, $port); $this->debug('connection pool', self::$connections); $socket = null; if (isset(self::$connections[$connectionId])) { @@ -259,8 +254,8 @@ class HTTPClient { if (is_null($socket) || feof($socket)) { $this->debug('opening connection', $connectionId); // open socket - $socket = @fsockopen($server,$port,$errno, $errstr, $this->timeout); - if (!$socket){ + $socket = @fsockopen($server, $port, $errno, $errstr, $this->timeout); + if (!$socket) { $this->status = -100; $this->error = "Could not connect to $server:$port\n$errstr ($errno)"; return false; @@ -268,11 +263,11 @@ class HTTPClient { // try to establish a CONNECT tunnel for SSL try { - if($this->ssltunnel($socket, $request_url)){ + if ($this->ssltunnel($socket, $request_url)) { // no keep alive for tunnels $this->keep_alive = false; // tunnel is authed already - if(isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']); + if (isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']); } } catch (HTTPClientException $e) { $this->status = $e->getCode(); @@ -303,66 +298,65 @@ class HTTPClient { stream_set_blocking($socket, 0); // build request - $request = "$method $request_url HTTP/".$this->http.HTTP_NL; + $request = "$method $request_url HTTP/" . $this->http . HTTP_NL; $request .= $this->buildHeaders($headers); $request .= $this->getCookies(); $request .= HTTP_NL; $request .= $data; - $this->debug('request',$request); + $this->debug('request', $request); $this->sendData($socket, $request, 'request'); // read headers from socket $r_headers = ''; - do{ + do { $r_line = $this->readLine($socket, 'headers'); $r_headers .= $r_line; - }while($r_line != "\r\n" && $r_line != "\n"); + } while ($r_line != "\r\n" && $r_line != "\n"); - $this->debug('response headers',$r_headers); + $this->debug('response headers', $r_headers); // check if expected body size exceeds allowance - if($this->max_bodysize && preg_match('/\r?\nContent-Length:\s*(\d+)\r?\n/i',$r_headers,$match)){ - if($match[1] > $this->max_bodysize){ + if ($this->max_bodysize && preg_match('/\r?\nContent-Length:\s*(\d+)\r?\n/i', $r_headers, $match)) { + if ($match[1] > $this->max_bodysize) { if ($this->max_bodysize_abort) throw new HTTPClientException('Reported content length exceeds allowed response size'); - else - $this->error = 'Reported content length exceeds allowed response size'; + else $this->error = 'Reported content length exceeds allowed response size'; } } // get Status if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/s', $r_headers, $m)) - throw new HTTPClientException('Server returned bad answer '.$r_headers); + throw new HTTPClientException('Server returned bad answer ' . $r_headers); $this->status = $m[2]; // handle headers and cookies $this->resp_headers = $this->parseHeaders($r_headers); - if(isset($this->resp_headers['set-cookie'])){ - foreach ((array) $this->resp_headers['set-cookie'] as $cookie){ - list($cookie) = sexplode(';', $cookie, 2, ''); - list($key, $val) = sexplode('=', $cookie, 2, ''); + if (isset($this->resp_headers['set-cookie'])) { + foreach ((array)$this->resp_headers['set-cookie'] as $cookie) { + [$cookie] = sexplode(';', $cookie, 2, ''); + [$key, $val] = sexplode('=', $cookie, 2, ''); $key = trim($key); - if($val == 'deleted'){ - if(isset($this->cookies[$key])){ + if ($val == 'deleted') { + if (isset($this->cookies[$key])) { unset($this->cookies[$key]); } - }elseif($key){ + } elseif ($key) { $this->cookies[$key] = $val; } } } - $this->debug('Object headers',$this->resp_headers); + $this->debug('Object headers', $this->resp_headers); // check server status code to follow redirect - if(in_array($this->status, [301, 302, 303, 307, 308])){ - if (empty($this->resp_headers['location'])){ + if (in_array($this->status, [301, 302, 303, 307, 308])) { + if (empty($this->resp_headers['location'])) { throw new HTTPClientException('Redirect but no Location Header found'); - }elseif($this->redirect_count == $this->max_redirect){ + } elseif ($this->redirect_count == $this->max_redirect) { throw new HTTPClientException('Maximum number of redirects exceeded'); - }else{ + } else { // close the connection because we don't handle content retrieval here // that's the easiest way to clean up the connection fclose($socket); @@ -371,32 +365,32 @@ class HTTPClient { $this->redirect_count++; $this->referer = $url; // handle non-RFC-compliant relative redirects - if (!preg_match('/^http/i', $this->resp_headers['location'])){ - if($this->resp_headers['location'][0] != '/'){ - $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uriPort. - dirname($path).'/'.$this->resp_headers['location']; - }else{ - $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uriPort. + if (!preg_match('/^http/i', $this->resp_headers['location'])) { + if ($this->resp_headers['location'][0] != '/') { + $this->resp_headers['location'] = $uri['scheme'] . '://' . $uri['host'] . ':' . $uriPort . + dirname($path) . '/' . $this->resp_headers['location']; + } else { + $this->resp_headers['location'] = $uri['scheme'] . '://' . $uri['host'] . ':' . $uriPort . $this->resp_headers['location']; } } - if($this->status == 307 || $this->status == 308) { + if ($this->status == 307 || $this->status == 308) { // perform redirected request, same method as before (required by RFC) - return $this->sendRequest($this->resp_headers['location'],$unencodedData,$method); - }else{ + return $this->sendRequest($this->resp_headers['location'], $unencodedData, $method); + } else { // perform redirected request, always via GET (required by RFC) - return $this->sendRequest($this->resp_headers['location'],array(),'GET'); + return $this->sendRequest($this->resp_headers['location'], [], 'GET'); } } } // check if headers are as expected - if($this->header_regexp && !preg_match($this->header_regexp,$r_headers)) + if ($this->header_regexp && !preg_match($this->header_regexp, $r_headers)) throw new HTTPClientException('The received headers did not match the given regexp'); //read body (with chunked encoding if needed) - $r_body = ''; - if( + $r_body = ''; + if ( ( isset($this->resp_headers['transfer-encoding']) && $this->resp_headers['transfer-encoding'] == 'chunked' @@ -408,7 +402,7 @@ class HTTPClient { $abort = false; do { $chunk_size = ''; - while (preg_match('/^[a-zA-Z0-9]?$/',$byte=$this->readData($socket,1,'chunk'))){ + while (preg_match('/^[a-zA-Z0-9]?$/', $byte = $this->readData($socket, 1, 'chunk'))) { // read chunksize until \r $chunk_size .= $byte; if (strlen($chunk_size) > 128) // set an abritrary limit on the size of chunks @@ -417,7 +411,7 @@ class HTTPClient { $this->readLine($socket, 'chunk'); // readtrailing \n $chunk_size = hexdec($chunk_size); - if($this->max_bodysize && $chunk_size+strlen($r_body) > $this->max_bodysize){ + if ($this->max_bodysize && $chunk_size + strlen($r_body) > $this->max_bodysize) { if ($this->max_bodysize_abort) throw new HTTPClientException('Allowed response size exceeded'); $this->error = 'Allowed response size exceeded'; @@ -430,7 +424,10 @@ class HTTPClient { $this->readData($socket, 2, 'chunk'); // read trailing \r\n } } while ($chunk_size && !$abort); - }elseif(isset($this->resp_headers['content-length']) && !isset($this->resp_headers['transfer-encoding'])){ + } elseif ( + isset($this->resp_headers['content-length']) && + !isset($this->resp_headers['transfer-encoding']) + ) { /* RFC 2616 * If a message is received with both a Transfer-Encoding header field and a Content-Length * header field, the latter MUST be ignored. @@ -438,22 +435,22 @@ class HTTPClient { // read up to the content-length or max_bodysize // for keep alive we need to read the whole message to clean up the socket for the next read - if( + if ( !$this->keep_alive && $this->max_bodysize && $this->max_bodysize < $this->resp_headers['content-length'] ) { $length = $this->max_bodysize + 1; - }else{ + } else { $length = $this->resp_headers['content-length']; } $r_body = $this->readData($socket, $length, 'response (content-length limited)', true); - }elseif( !isset($this->resp_headers['transfer-encoding']) && $this->max_bodysize && !$this->keep_alive){ - $r_body = $this->readData($socket, $this->max_bodysize+1, 'response (content-length limited)', true); + } elseif (!isset($this->resp_headers['transfer-encoding']) && $this->max_bodysize && !$this->keep_alive) { + $r_body = $this->readData($socket, $this->max_bodysize + 1, 'response (content-length limited)', true); } elseif ((int)$this->status === 204) { // request has no content - } else{ + } else { // read entire socket while (!feof($socket)) { $r_body .= $this->readData($socket, 4096, 'response (unlimited)', true); @@ -461,8 +458,8 @@ class HTTPClient { } // recheck body size, we might have read max_bodysize+1 or even the whole body, so we abort late here - if($this->max_bodysize){ - if(strlen($r_body) > $this->max_bodysize){ + if ($this->max_bodysize) { + if (strlen($r_body) > $this->max_bodysize) { if ($this->max_bodysize_abort) { throw new HTTPClientException('Allowed response size exceeded'); } else { @@ -470,7 +467,6 @@ class HTTPClient { } } } - } catch (HTTPClientException $err) { $this->error = $err->getMessage(); if ($err->getCode()) @@ -480,27 +476,31 @@ class HTTPClient { return false; } - if (!$this->keep_alive || - (isset($this->resp_headers['connection']) && $this->resp_headers['connection'] == 'Close')) { + if ( + !$this->keep_alive || + (isset($this->resp_headers['connection']) && $this->resp_headers['connection'] == 'Close') + ) { // close socket fclose($socket); unset(self::$connections[$connectionId]); } // decode gzip if needed - if(isset($this->resp_headers['content-encoding']) && + if ( + isset($this->resp_headers['content-encoding']) && $this->resp_headers['content-encoding'] == 'gzip' && - strlen($r_body) > 10 && substr($r_body,0,3)=="\x1f\x8b\x08"){ + strlen($r_body) > 10 && substr($r_body, 0, 3) == "\x1f\x8b\x08" + ) { $this->resp_body = @gzinflate(substr($r_body, 10)); - if($this->resp_body === false){ + if ($this->resp_body === false) { $this->error = 'Failed to decompress gzip encoded content'; $this->resp_body = $r_body; } - }else{ + } else { $this->resp_body = $r_body; } - $this->debug('response body',$this->resp_body); + $this->debug('response body', $this->resp_body); $this->redirect_count = 0; return true; } @@ -512,35 +512,37 @@ class HTTPClient { * * @param resource &$socket * @param string &$requesturl - * @throws HTTPClientException when a tunnel is needed but could not be established * @return bool true if a tunnel was established + * @throws HTTPClientException when a tunnel is needed but could not be established */ - protected function ssltunnel(&$socket, &$requesturl){ - if(!$this->useProxyForUrl($requesturl)) return false; + protected function ssltunnel(&$socket, &$requesturl) + { + if (!$this->useProxyForUrl($requesturl)) return false; $requestinfo = parse_url($requesturl); - if($requestinfo['scheme'] != 'https') return false; - if(empty($requestinfo['port'])) $requestinfo['port'] = 443; + if ($requestinfo['scheme'] != 'https') return false; + if (empty($requestinfo['port'])) $requestinfo['port'] = 443; // build request - $request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL; - $request .= "Host: {$requestinfo['host']}".HTTP_NL; - if($this->proxy_user) { - $request .= 'Proxy-Authorization: Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL; + $request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0" . HTTP_NL; + $request .= "Host: {$requestinfo['host']}" . HTTP_NL; + if ($this->proxy_user) { + $request .= 'Proxy-Authorization: Basic ' . + base64_encode($this->proxy_user . ':' . $this->proxy_pass) . HTTP_NL; } $request .= HTTP_NL; - $this->debug('SSL Tunnel CONNECT',$request); + $this->debug('SSL Tunnel CONNECT', $request); $this->sendData($socket, $request, 'SSL Tunnel CONNECT'); // read headers from socket $r_headers = ''; - do{ + do { $r_line = $this->readLine($socket, 'headers'); $r_headers .= $r_line; - }while($r_line != "\r\n" && $r_line != "\n"); + } while ($r_line != "\r\n" && $r_line != "\n"); - $this->debug('SSL Tunnel Response',$r_headers); - if(preg_match('/^HTTP\/1\.[01] 200/i',$r_headers)){ + $this->debug('SSL Tunnel Response', $r_headers); + if (preg_match('/^HTTP\/1\.[01] 200/i', $r_headers)) { // set correct peer name for verification (enabled since PHP 5.6) stream_context_set_option($socket, 'ssl', 'peer_name', $requestinfo['host']); @@ -554,13 +556,14 @@ class HTTPClient { } if (@stream_socket_enable_crypto($socket, true, $cryptoMethod)) { - $requesturl = ($requestinfo['path'] ?? '/'). - (!empty($requestinfo['query'])?'?'.$requestinfo['query']:''); + $requesturl = ($requestinfo['path'] ?? '/') . + (empty($requestinfo['query']) ? '' : '?' . $requestinfo['query']); return true; } throw new HTTPClientException( - 'Failed to set up crypto for secure connection to '.$requestinfo['host'], -151 + 'Failed to set up crypto for secure connection to ' . $requestinfo['host'], + -151 ); } @@ -570,38 +573,39 @@ class HTTPClient { /** * Safely write data to a socket * - * @param resource $socket An open socket handle - * @param string $data The data to write - * @param string $message Description of what is being read + * @param resource $socket An open socket handle + * @param string $data The data to write + * @param string $message Description of what is being read * @throws HTTPClientException * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function sendData($socket, $data, $message) { + protected function sendData($socket, $data, $message) + { // send request $towrite = strlen($data); $written = 0; - while($written < $towrite){ + while ($written < $towrite) { // check timeout $time_used = microtime(true) - $this->start; - if($time_used > $this->timeout) - throw new HTTPClientException(sprintf('Timeout while sending %s (%.3fs)',$message, $time_used), -100); - if(feof($socket)) + if ($time_used > $this->timeout) + throw new HTTPClientException(sprintf('Timeout while sending %s (%.3fs)', $message, $time_used), -100); + if (feof($socket)) throw new HTTPClientException("Socket disconnected while writing $message"); // select parameters $sel_r = null; - $sel_w = array($socket); + $sel_w = [$socket]; $sel_e = null; // wait for stream ready or timeout (1sec) - if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ + if (@stream_select($sel_r, $sel_w, $sel_e, 1) === false) { usleep(1000); continue; } // write to stream - $nbytes = fwrite($socket, substr($data,$written,4096)); - if($nbytes === false) + $nbytes = fwrite($socket, substr($data, $written, 4096)); + if ($nbytes === false) throw new HTTPClientException("Failed writing to socket while sending $message", -100); $written += $nbytes; } @@ -613,16 +617,17 @@ class HTTPClient { * Reads up to a given number of bytes or throws an exception if the * response times out or ends prematurely. * - * @param resource $socket An open socket handle in non-blocking mode - * @param int $nbytes Number of bytes to read - * @param string $message Description of what is being read - * @param bool $ignore_eof End-of-file is not an error if this is set - * @throws HTTPClientException + * @param resource $socket An open socket handle in non-blocking mode + * @param int $nbytes Number of bytes to read + * @param string $message Description of what is being read + * @param bool $ignore_eof End-of-file is not an error if this is set * @return string * + * @throws HTTPClientException * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function readData($socket, $nbytes, $message, $ignore_eof = false) { + protected function readData($socket, $nbytes, $message, $ignore_eof = false) + { $r_data = ''; // Does not return immediately so timeout and eof can be checked if ($nbytes < 0) $nbytes = 0; @@ -631,27 +636,33 @@ class HTTPClient { $time_used = microtime(true) - $this->start; if ($time_used > $this->timeout) throw new HTTPClientException( - sprintf('Timeout while reading %s after %d bytes (%.3fs)', $message, - strlen($r_data), $time_used), -100); - if(feof($socket)) { - if(!$ignore_eof) + sprintf( + 'Timeout while reading %s after %d bytes (%.3fs)', + $message, + strlen($r_data), + $time_used + ), + -100 + ); + if (feof($socket)) { + if (!$ignore_eof) throw new HTTPClientException("Premature End of File (socket) while reading $message"); break; } if ($to_read > 0) { // select parameters - $sel_r = array($socket); + $sel_r = [$socket]; $sel_w = null; $sel_e = null; // wait for stream ready or timeout (1sec) - if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ + if (@stream_select($sel_r, $sel_w, $sel_e, 1) === false) { usleep(1000); continue; } $bytes = fread($socket, $to_read); - if($bytes === false) + if ($bytes === false) throw new HTTPClientException("Failed reading from socket while reading $message", -100); $r_data .= $bytes; $to_read -= strlen($bytes); @@ -665,36 +676,38 @@ class HTTPClient { * * Always returns a complete line, including the terminating \n. * - * @param resource $socket An open socket handle in non-blocking mode - * @param string $message Description of what is being read - * @throws HTTPClientException + * @param resource $socket An open socket handle in non-blocking mode + * @param string $message Description of what is being read * @return string * + * @throws HTTPClientException * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function readLine($socket, $message) { + protected function readLine($socket, $message) + { $r_data = ''; do { $time_used = microtime(true) - $this->start; if ($time_used > $this->timeout) throw new HTTPClientException( sprintf('Timeout while reading %s (%.3fs) >%s<', $message, $time_used, $r_data), - -100); - if(feof($socket)) + -100 + ); + if (feof($socket)) throw new HTTPClientException("Premature End of File (socket) while reading $message"); // select parameters - $sel_r = array($socket); + $sel_r = [$socket]; $sel_w = null; $sel_e = null; // wait for stream ready or timeout (1sec) - if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ + if (@stream_select($sel_r, $sel_w, $sel_e, 1) === false) { usleep(1000); continue; } $r_data = fgets($socket, 1024); - } while (!preg_match('/\n$/',$r_data)); + } while (!preg_match('/\n$/', $r_data)); return $r_data; } @@ -703,16 +716,17 @@ class HTTPClient { * * Uses _debug_text or _debug_html depending on the SAPI name * + * @param string $info + * @param mixed $var * @author Andreas Gohr <andi@splitbrain.org> * - * @param string $info - * @param mixed $var */ - protected function debug($info,$var=null){ - if(!$this->debug) return; - if(php_sapi_name() == 'cli'){ + protected function debug($info, $var = null) + { + if (!$this->debug) return; + if (PHP_SAPI == 'cli') { $this->debugText($info, $var); - }else{ + } else { $this->debugHtml($info, $var); } } @@ -721,16 +735,17 @@ class HTTPClient { * print debug info as HTML * * @param string $info - * @param mixed $var + * @param mixed $var */ - protected function debugHtml($info, $var=null){ - print '<b>'.$info.'</b> '.(microtime(true) - $this->start).'s<br />'; - if(!is_null($var)){ + protected function debugHtml($info, $var = null) + { + echo '<b>' . $info . '</b> ' . (microtime(true) - $this->start) . 's<br />'; + if (!is_null($var)) { ob_start(); print_r($var); $content = htmlspecialchars(ob_get_contents()); ob_end_clean(); - print '<pre>'.$content.'</pre>'; + echo '<pre>' . $content . '</pre>'; } } @@ -738,12 +753,13 @@ class HTTPClient { * prints debug info as plain text * * @param string $info - * @param mixed $var + * @param mixed $var */ - protected function debugText($info, $var=null){ - print '*'.$info.'* '.(microtime(true) - $this->start)."s\n"; - if(!is_null($var)) print_r($var); - print "\n-----------------------------------------------\n"; + protected function debugText($info, $var = null) + { + echo '*' . $info . '* ' . (microtime(true) - $this->start) . "s\n"; + if (!is_null($var)) print_r($var); + echo "\n-----------------------------------------------\n"; } /** @@ -751,28 +767,29 @@ class HTTPClient { * * All Keys are lowercased. * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $string * @return array + * @author Andreas Gohr <andi@splitbrain.org> + * */ - protected function parseHeaders($string){ - $headers = array(); - $lines = explode("\n",$string); + protected function parseHeaders($string) + { + $headers = []; + $lines = explode("\n", $string); array_shift($lines); //skip first line (status) - foreach($lines as $line){ - list($key, $val) = sexplode(':', $line, 2, ''); + foreach ($lines as $line) { + [$key, $val] = sexplode(':', $line, 2, ''); $key = trim($key); $val = trim($val); $key = strtolower($key); - if(!$key) continue; - if(isset($headers[$key])){ - if(is_array($headers[$key])){ + if (!$key) continue; + if (isset($headers[$key])) { + if (is_array($headers[$key])) { $headers[$key][] = $val; - }else{ - $headers[$key] = array($headers[$key],$val); + } else { + $headers[$key] = [$headers[$key], $val]; } - }else{ + } else { $headers[$key] = $val; } } @@ -782,16 +799,17 @@ class HTTPClient { /** * convert given header array to header string * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $headers * @return string + * @author Andreas Gohr <andi@splitbrain.org> + * */ - protected function buildHeaders($headers){ + protected function buildHeaders($headers) + { $string = ''; - foreach($headers as $key => $value){ - if($value === '') continue; - $string .= $key.': '.$value.HTTP_NL; + foreach ($headers as $key => $value) { + if ($value === '') continue; + $string .= $key . ': ' . $value . HTTP_NL; } return $string; } @@ -799,73 +817,77 @@ class HTTPClient { /** * get cookies as http header string * + * @return string * @author Andreas Goetz <cpuidle@gmx.de> * - * @return string */ - protected function getCookies(){ + protected function getCookies() + { $headers = ''; - foreach ($this->cookies as $key => $val){ + foreach ($this->cookies as $key => $val) { $headers .= "$key=$val; "; } $headers = substr($headers, 0, -2); - if ($headers) $headers = "Cookie: $headers".HTTP_NL; + if ($headers) $headers = "Cookie: $headers" . HTTP_NL; return $headers; } /** * Encode data for posting * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $data * @return string + * @author Andreas Gohr <andi@splitbrain.org> + * */ - protected function postEncode($data){ - return http_build_query($data,'','&'); + protected function postEncode($data) + { + return http_build_query($data, '', '&'); } /** * Encode data for posting using multipart encoding * * @fixme use of urlencode might be wrong here - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $data * @return string + * @author Andreas Gohr <andi@splitbrain.org> + * */ - protected function postMultipartEncode($data){ - $boundary = '--'.$this->boundary; + protected function postMultipartEncode($data) + { + $boundary = '--' . $this->boundary; $out = ''; - foreach($data as $key => $val){ - $out .= $boundary.HTTP_NL; - if(!is_array($val)){ - $out .= 'Content-Disposition: form-data; name="'.urlencode($key).'"'.HTTP_NL; + foreach ($data as $key => $val) { + $out .= $boundary . HTTP_NL; + if (!is_array($val)) { + $out .= 'Content-Disposition: form-data; name="' . urlencode($key) . '"' . HTTP_NL; $out .= HTTP_NL; // end of headers $out .= $val; $out .= HTTP_NL; - }else{ - $out .= 'Content-Disposition: form-data; name="'.urlencode($key).'"'; - if($val['filename']) $out .= '; filename="'.urlencode($val['filename']).'"'; + } else { + $out .= 'Content-Disposition: form-data; name="' . urlencode($key) . '"'; + if ($val['filename']) $out .= '; filename="' . urlencode($val['filename']) . '"'; $out .= HTTP_NL; - if($val['mimetype']) $out .= 'Content-Type: '.$val['mimetype'].HTTP_NL; + if ($val['mimetype']) $out .= 'Content-Type: ' . $val['mimetype'] . HTTP_NL; $out .= HTTP_NL; // end of headers $out .= $val['body']; $out .= HTTP_NL; } } - $out .= "$boundary--".HTTP_NL; + $out .= "$boundary--" . HTTP_NL; return $out; } /** * Generates a unique identifier for a connection. * - * @param string $server - * @param string $port + * @param string $server + * @param string $port * @return string unique identifier */ - protected function uniqueConnectionId($server, $port) { + protected function uniqueConnectionId($server, $port) + { return "$server:$port"; } @@ -877,7 +899,8 @@ class HTTPClient { * @param string $url * @return bool */ - protected function useProxyForUrl($url) { + protected function useProxyForUrl($url) + { return $this->proxy_host && (!$this->proxy_except || !preg_match('/' . $this->proxy_except . '/i', $url)); } } diff --git a/inc/HTTP/HTTPClientException.php b/inc/HTTP/HTTPClientException.php index 5b8f4eeca..17439a9db 100644 --- a/inc/HTTP/HTTPClientException.php +++ b/inc/HTTP/HTTPClientException.php @@ -6,5 +6,4 @@ use Exception; class HTTPClientException extends Exception { - } diff --git a/inc/HTTP/Headers.php b/inc/HTTP/Headers.php index 4d988ea05..254eb1ca8 100644 --- a/inc/HTTP/Headers.php +++ b/inc/HTTP/Headers.php @@ -14,7 +14,7 @@ class Headers * * @param array $policy */ - static public function contentSecurityPolicy($policy) + public static function contentSecurityPolicy($policy) { foreach ($policy as $key => $values) { // if the value is not an array, we also accept newline terminated strings @@ -28,7 +28,7 @@ class Headers $cspheader = 'Content-Security-Policy:'; foreach ($policy as $key => $values) { if ($values) { - $cspheader .= " $key " . join(' ', $values) . ';'; + $cspheader .= " $key " . implode(' ', $values) . ';'; } else { $cspheader .= " $key;"; } diff --git a/inc/Info.php b/inc/Info.php index 9208b2471..1cdccd7a0 100644 --- a/inc/Info.php +++ b/inc/Info.php @@ -9,7 +9,6 @@ namespace dokuwiki; */ class Info { - /** * Parse the given version string into its parts * @@ -17,7 +16,7 @@ class Info * @return array * @throws \Exception */ - static public function parseVersionString($version) + public static function parseVersionString($version) { $return = [ 'type' => '', // stable, rc @@ -50,5 +49,4 @@ class Info return $return; } - } diff --git a/inc/Input/Input.php b/inc/Input/Input.php index 3d2426bcc..d08eec675 100644 --- a/inc/Input/Input.php +++ b/inc/Input/Input.php @@ -13,7 +13,6 @@ namespace dokuwiki\Input; */ class Input { - /** @var Post Access $_POST parameters */ public $post; /** @var Get Access $_GET parameters */ @@ -240,13 +239,13 @@ class Input * @param bool $nonempty Return $default if parameter is set but empty() * @return array */ - public function arr($name, $default = array(), $nonempty = false) + public function arr($name, $default = [], $nonempty = false) { if (!isset($this->access[$name])) return $default; if (!is_array($this->access[$name])) return $default; if ($nonempty && empty($this->access[$name])) return $default; - return (array)$this->access[$name]; + return $this->access[$name]; } /** diff --git a/inc/Input/Post.php b/inc/Input/Post.php index 137cd72f4..88ca2887d 100644 --- a/inc/Input/Post.php +++ b/inc/Input/Post.php @@ -7,7 +7,6 @@ namespace dokuwiki\Input; */ class Post extends Input { - /** @noinspection PhpMissingParentConstructorInspection * Initialize the $access array, remove subclass members */ diff --git a/inc/Input/Server.php b/inc/Input/Server.php index 60964fd8f..b254629b3 100644 --- a/inc/Input/Server.php +++ b/inc/Input/Server.php @@ -7,7 +7,6 @@ namespace dokuwiki\Input; */ class Server extends Input { - /** @noinspection PhpMissingParentConstructorInspection * Initialize the $access array, remove subclass members */ @@ -15,5 +14,4 @@ class Server extends Input { $this->access = &$_SERVER; } - } diff --git a/inc/Logger.php b/inc/Logger.php index 632f37d04..0b8a48a6f 100644 --- a/inc/Logger.php +++ b/inc/Logger.php @@ -9,12 +9,12 @@ use dokuwiki\Extension\Event; */ class Logger { - const LOG_ERROR = 'error'; - const LOG_DEPRECATED = 'deprecated'; - const LOG_DEBUG = 'debug'; + public const LOG_ERROR = 'error'; + public const LOG_DEPRECATED = 'deprecated'; + public const LOG_DEBUG = 'debug'; /** @var Logger[] */ - static protected $instances; + protected static $instances; /** @var string what kind of log is this */ protected $facility; @@ -43,7 +43,7 @@ class Logger * @param string $facility The type of log * @return Logger */ - static public function getInstance($facility = self::LOG_ERROR) + public static function getInstance($facility = self::LOG_ERROR) { if (empty(self::$instances[$facility])) { self::$instances[$facility] = new Logger($facility); @@ -60,10 +60,13 @@ class Logger * @param int $line A line number for the above file * @return bool has a log been written? */ - static public function error($message, $details = null, $file = '', $line = 0) + public static function error($message, $details = null, $file = '', $line = 0) { return self::getInstance(self::LOG_ERROR)->log( - $message, $details, $file, $line + $message, + $details, + $file, + $line ); } @@ -76,10 +79,13 @@ class Logger * @param int $line A line number for the above file * @return bool has a log been written? */ - static public function debug($message, $details = null, $file = '', $line = 0) + public static function debug($message, $details = null, $file = '', $line = 0) { return self::getInstance(self::LOG_DEBUG)->log( - $message, $details, $file, $line + $message, + $details, + $file, + $line ); } @@ -92,10 +98,13 @@ class Logger * @param int $line A line number for the above file * @return bool has a log been written? */ - static public function deprecated($message, $details = null, $file = '', $line = 0) + public static function deprecated($message, $details = null, $file = '', $line = 0) { return self::getInstance(self::LOG_DEPRECATED)->log( - $message, $details, $file, $line + $message, + $details, + $file, + $line ); } @@ -172,9 +181,7 @@ class Logger $details = json_encode($details, JSON_PRETTY_PRINT); } $details = explode("\n", $details); - $loglines = array_map(function ($line) { - return ' ' . $line; - }, $details); + $loglines = array_map(static fn($line) => ' ' . $line, $details); } elseif ($details) { $loglines = [$details]; } else { @@ -221,8 +228,8 @@ class Logger protected function writeLogLines($lines, $logfile) { if (defined('DOKU_UNITTEST')) { - fwrite(STDERR, "\n[" . $this->facility . '] ' . join("\n", $lines) . "\n"); + fwrite(STDERR, "\n[" . $this->facility . '] ' . implode("\n", $lines) . "\n"); } - return io_saveFile($logfile, join("\n", $lines) . "\n", true); + return io_saveFile($logfile, implode("\n", $lines) . "\n", true); } } diff --git a/inc/Mailer.class.php b/inc/Mailer.class.php index f92d80cc6..449c8d42a 100644 --- a/inc/Mailer.class.php +++ b/inc/Mailer.class.php @@ -1,4 +1,5 @@ <?php + /** * A class to build and send multi part mails (with HTML content and embedded * attachments). All mails are assumed to be in UTF-8 encoding. @@ -9,50 +10,54 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Utf8\PhpString; +use dokuwiki\Utf8\Clean; use dokuwiki\Extension\Event; /** * Mail Handling */ -class Mailer { - - protected $headers = array(); - protected $attach = array(); +class Mailer +{ + protected $headers = []; + protected $attach = []; protected $html = ''; protected $text = ''; protected $boundary = ''; protected $partid = ''; - protected $sendparam = null; + protected $sendparam; protected $allowhtml = true; - protected $replacements = array('text'=> array(), 'html' => array()); + protected $replacements = ['text' => [], 'html' => []]; /** * Constructor * * Initializes the boundary strings, part counters and token replacements */ - public function __construct() { + public function __construct() + { global $conf; /* @var Input $INPUT */ global $INPUT; $server = parse_url(DOKU_URL, PHP_URL_HOST); - if(strpos($server,'.') === false) $server .= '.localhost'; + if (strpos($server, '.') === false) $server .= '.localhost'; - $this->partid = substr(md5(uniqid(mt_rand(), true)),0, 8).'@'.$server; - $this->boundary = '__________'.md5(uniqid(mt_rand(), true)); + $this->partid = substr(md5(uniqid(random_int(0, mt_getrandmax()), true)), 0, 8) . '@' . $server; + $this->boundary = '__________' . md5(uniqid(random_int(0, mt_getrandmax()), true)); - $listid = implode('.', array_reverse(explode('/', DOKU_BASE))).$server; + $listid = implode('.', array_reverse(explode('/', DOKU_BASE))) . $server; $listid = strtolower(trim($listid, '.')); - $messageid = uniqid(mt_rand(), true) . "@$server"; + + $messageid = uniqid(random_int(0, mt_getrandmax()), true) . "@$server"; $this->allowhtml = (bool)$conf['htmlmail']; // add some default headers for mailfiltering FS#2247 - if(!empty($conf['mailreturnpath'])) { + if (!empty($conf['mailreturnpath'])) { $this->setHeader('Return-Path', $conf['mailreturnpath']); } $this->setHeader('X-Mailer', 'DokuWiki'); @@ -60,7 +65,7 @@ class Mailer { $this->setHeader('X-DokuWiki-Title', $conf['title']); $this->setHeader('X-DokuWiki-Server', $server); $this->setHeader('X-Auto-Response-Suppress', 'OOF'); - $this->setHeader('List-Id', $conf['title'].' <'.$listid.'>'); + $this->setHeader('List-Id', $conf['title'] . ' <' . $listid . '>'); $this->setHeader('Date', date('r'), false); $this->setHeader('Message-Id', "<$messageid>"); @@ -75,17 +80,18 @@ class Mailer { * @param string $name The filename to use * @param string $embed Unique key to reference this file from the HTML part */ - public function attachFile($path, $mime, $name = '', $embed = '') { - if(!$name) { - $name = \dokuwiki\Utf8\PhpString::basename($path); + public function attachFile($path, $mime, $name = '', $embed = '') + { + if (!$name) { + $name = PhpString::basename($path); } - $this->attach[] = array( + $this->attach[] = [ 'data' => file_get_contents($path), 'mime' => $mime, 'name' => $name, 'embed' => $embed - ); + ]; } /** @@ -96,18 +102,19 @@ class Mailer { * @param string $name The filename to use * @param string $embed Unique key to reference this file from the HTML part */ - public function attachContent($data, $mime, $name = '', $embed = '') { - if(!$name) { - list(, $ext) = explode('/', $mime); - $name = count($this->attach).".$ext"; + public function attachContent($data, $mime, $name = '', $embed = '') + { + if (!$name) { + [, $ext] = explode('/', $mime); + $name = count($this->attach) . ".$ext"; } - $this->attach[] = array( + $this->attach[] = [ 'data' => $data, 'mime' => $mime, 'name' => $name, 'embed' => $embed - ); + ]; } /** @@ -116,19 +123,20 @@ class Mailer { * @param array $matches * @return string placeholder */ - protected function autoEmbedCallBack($matches) { + protected function autoEmbedCallBack($matches) + { static $embeds = 0; $embeds++; // get file and mime type $media = cleanID($matches[1]); - list(, $mime) = mimetype($media); + [, $mime] = mimetype($media); $file = mediaFN($media); - if(!file_exists($file)) return $matches[0]; //bad reference, keep as is + if (!file_exists($file)) return $matches[0]; //bad reference, keep as is // attach it and set placeholder - $this->attachFile($file, $mime, '', 'autoembed'.$embeds); - return '%%autoembed'.$embeds.'%%'; + $this->attachFile($file, $mime, '', 'autoembed' . $embeds); + return '%%autoembed' . $embeds . '%%'; } /** @@ -140,23 +148,24 @@ class Mailer { * @param string|string[] $value the value of the header * @param bool $clean remove all non-ASCII chars and line feeds? */ - public function setHeader($header, $value, $clean = true) { + public function setHeader($header, $value, $clean = true) + { $header = str_replace(' ', '-', ucwords(strtolower(str_replace('-', ' ', $header)))); // streamline casing - if($clean) { + if ($clean) { $header = preg_replace('/[^a-zA-Z0-9_ \-\.\+\@]+/', '', $header); $value = preg_replace('/[^a-zA-Z0-9_ \-\.\+\@<>]+/', '', $value); } // empty value deletes - if(is_array($value)){ + if (is_array($value)) { $value = array_map('trim', $value); $value = array_filter($value); - if(!$value) $value = ''; - }else{ + if (!$value) $value = ''; + } else { $value = trim($value); } - if($value === '') { - if(isset($this->headers[$header])) unset($this->headers[$header]); + if ($value === '') { + if (isset($this->headers[$header])) unset($this->headers[$header]); } else { $this->headers[$header] = $value; } @@ -170,7 +179,8 @@ class Mailer { * * @param string $param */ - public function setParameters($param) { + public function setParameters($param) + { $this->sendparam = $param; } @@ -189,34 +199,35 @@ class Mailer { * @param string $html the HTML body, leave null to create it from $text * @param bool $wrap wrap the HTML in the default header/Footer */ - public function setBody($text, $textrep = null, $htmlrep = null, $html = null, $wrap = true) { + public function setBody($text, $textrep = null, $htmlrep = null, $html = null, $wrap = true) + { $htmlrep = (array)$htmlrep; $textrep = (array)$textrep; // create HTML from text if not given - if($html === null) { + if ($html === null) { $html = $text; $html = hsc($html); $html = preg_replace('/^----+$/m', '<hr >', $html); $html = nl2br($html); } - if($wrap) { + if ($wrap) { $wrapper = rawLocale('mailwrap', 'html'); $html = preg_replace('/\n-- <br \/>.*$/s', '', $html); //strip signature $html = str_replace('@EMAILSIGNATURE@', '', $html); //strip @EMAILSIGNATURE@ $html = str_replace('@HTMLBODY@', $html, $wrapper); } - if(strpos($text, '@EMAILSIGNATURE@') === false) { + if (strpos($text, '@EMAILSIGNATURE@') === false) { $text .= '@EMAILSIGNATURE@'; } // copy over all replacements missing for HTML (autolink URLs) - foreach($textrep as $key => $value) { - if(isset($htmlrep[$key])) continue; - if(media_isexternal($value)) { - $htmlrep[$key] = '<a href="'.hsc($value).'">'.hsc($value).'</a>'; + foreach ($textrep as $key => $value) { + if (isset($htmlrep[$key])) continue; + if (media_isexternal($value)) { + $htmlrep[$key] = '<a href="' . hsc($value) . '">' . hsc($value) . '</a>'; } else { $htmlrep[$key] = hsc($value); } @@ -225,19 +236,20 @@ class Mailer { // embed media from templates $html = preg_replace_callback( '/@MEDIA\(([^\)]+)\)@/', - array($this, 'autoEmbedCallBack'), $html + [$this, 'autoEmbedCallBack'], + $html ); // add default token replacements - $trep = array_merge($this->replacements['text'], (array)$textrep); - $hrep = array_merge($this->replacements['html'], (array)$htmlrep); + $trep = array_merge($this->replacements['text'], $textrep); + $hrep = array_merge($this->replacements['html'], $htmlrep); // Apply replacements - foreach($trep as $key => $substitution) { - $text = str_replace('@'.strtoupper($key).'@', $substitution, $text); + foreach ($trep as $key => $substitution) { + $text = str_replace('@' . strtoupper($key) . '@', $substitution, $text); } - foreach($hrep as $key => $substitution) { - $html = str_replace('@'.strtoupper($key).'@', $substitution, $html); + foreach ($hrep as $key => $substitution) { + $html = str_replace('@' . strtoupper($key) . '@', $substitution, $html); } $this->setHTML($html); @@ -253,7 +265,8 @@ class Mailer { * * @param string $html */ - public function setHTML($html) { + public function setHTML($html) + { $this->html = $html; } @@ -264,7 +277,8 @@ class Mailer { * * @param string $text */ - public function setText($text) { + public function setText($text) + { $this->text = $text; } @@ -274,7 +288,8 @@ class Mailer { * @see cleanAddress * @param string|string[] $address Multiple adresses separated by commas or as array */ - public function to($address) { + public function to($address) + { $this->setHeader('To', $address, false); } @@ -284,7 +299,8 @@ class Mailer { * @see cleanAddress * @param string|string[] $address Multiple adresses separated by commas or as array */ - public function cc($address) { + public function cc($address) + { $this->setHeader('Cc', $address, false); } @@ -294,7 +310,8 @@ class Mailer { * @see cleanAddress * @param string|string[] $address Multiple adresses separated by commas or as array */ - public function bcc($address) { + public function bcc($address) + { $this->setHeader('Bcc', $address, false); } @@ -307,7 +324,8 @@ class Mailer { * @see cleanAddress * @param string $address from address */ - public function from($address) { + public function from($address) + { $this->setHeader('From', $address, false); } @@ -316,7 +334,8 @@ class Mailer { * * @param string $subject the mail subject */ - public function subject($subject) { + public function subject($subject) + { $this->headers['Subject'] = $subject; } @@ -328,11 +347,12 @@ class Mailer { * @param string $name the name to clean-up * @see cleanAddress */ - public function getCleanName($name) { + public function getCleanName($name) + { $name = trim($name, " \t\""); $name = str_replace('"', '\"', $name, $count); if ($count > 0 || strpos($name, ',') !== false) { - $name = '"'.$name.'"'; + $name = '"' . $name . '"'; } return $name; } @@ -355,24 +375,25 @@ class Mailer { * @param string|string[] $addresses Multiple adresses separated by commas or as array * @return false|string the prepared header (can contain multiple lines) */ - public function cleanAddress($addresses) { + public function cleanAddress($addresses) + { $headers = ''; - if(!is_array($addresses)){ + if (!is_array($addresses)) { $count = preg_match_all('/\s*(?:("[^"]*"[^,]+),*)|([^,]+)\s*,*/', $addresses, $matches, PREG_SET_ORDER); - $addresses = array(); + $addresses = []; if ($count !== false && is_array($matches)) { foreach ($matches as $match) { - array_push($addresses, rtrim($match[0], ',')); + $addresses[] = rtrim($match[0], ','); } } } - foreach($addresses as $part) { + foreach ($addresses as $part) { $part = preg_replace('/[\r\n\0]+/', ' ', $part); // remove attack vectors $part = trim($part); // parse address - if(preg_match('#(.*?)<(.*?)>#', $part, $matches)) { + if (preg_match('#(.*?)<(.*?)>#', $part, $matches)) { $text = trim($matches[1]); $addr = $matches[2]; } else { @@ -380,47 +401,47 @@ class Mailer { $addr = $part; } // skip empty ones - if(empty($addr)) { + if (empty($addr)) { continue; } // FIXME: is there a way to encode the localpart of a emailaddress? - if(!\dokuwiki\Utf8\Clean::isASCII($addr)) { + if (!Clean::isASCII($addr)) { msg(hsc("E-Mail address <$addr> is not ASCII"), -1, __LINE__, __FILE__, MSG_ADMINS_ONLY); continue; } - if(!mail_isvalid($addr)) { + if (!mail_isvalid($addr)) { msg(hsc("E-Mail address <$addr> is not valid"), -1, __LINE__, __FILE__, MSG_ADMINS_ONLY); continue; } // text was given - if(!empty($text) && !isWindows()) { // No named recipients for To: in Windows (see FS#652) + if (!empty($text) && !isWindows()) { // No named recipients for To: in Windows (see FS#652) // add address quotes $addr = "<$addr>"; - if(defined('MAILHEADER_ASCIIONLY')) { - $text = \dokuwiki\Utf8\Clean::deaccent($text); - $text = \dokuwiki\Utf8\Clean::strip($text); + if (defined('MAILHEADER_ASCIIONLY')) { + $text = Clean::deaccent($text); + $text = Clean::strip($text); } - if(strpos($text, ',') !== false || !\dokuwiki\Utf8\Clean::isASCII($text)) { - $text = '=?UTF-8?B?'.base64_encode($text).'?='; + if (strpos($text, ',') !== false || !Clean::isASCII($text)) { + $text = '=?UTF-8?B?' . base64_encode($text) . '?='; } } else { $text = ''; } // add to header comma seperated - if($headers != '') { + if ($headers != '') { $headers .= ', '; } - $headers .= $text.' '.$addr; + $headers .= $text . ' ' . $addr; } $headers = trim($headers); - if(empty($headers)) return false; + if (empty($headers)) return false; return $headers; } @@ -433,29 +454,30 @@ class Mailer { * * @return string mime multiparts */ - protected function prepareAttachments() { + protected function prepareAttachments() + { $mime = ''; $part = 1; // embedded attachments - foreach($this->attach as $media) { + foreach ($this->attach as $media) { $media['name'] = str_replace(':', '_', cleanID($media['name'], true)); // create content id - $cid = 'part'.$part.'.'.$this->partid; + $cid = 'part' . $part . '.' . $this->partid; // replace wildcards - if($media['embed']) { - $this->html = str_replace('%%'.$media['embed'].'%%', 'cid:'.$cid, $this->html); + if ($media['embed']) { + $this->html = str_replace('%%' . $media['embed'] . '%%', 'cid:' . $cid, $this->html); } - $mime .= '--'.$this->boundary.MAILHEADER_EOL; - $mime .= $this->wrappedHeaderLine('Content-Type', $media['mime'].'; id="'.$cid.'"'); + $mime .= '--' . $this->boundary . MAILHEADER_EOL; + $mime .= $this->wrappedHeaderLine('Content-Type', $media['mime'] . '; id="' . $cid . '"'); $mime .= $this->wrappedHeaderLine('Content-Transfer-Encoding', 'base64'); - $mime .= $this->wrappedHeaderLine('Content-ID',"<$cid>"); - if($media['embed']) { - $mime .= $this->wrappedHeaderLine('Content-Disposition', 'inline; filename='.$media['name']); + $mime .= $this->wrappedHeaderLine('Content-ID', "<$cid>"); + if ($media['embed']) { + $mime .= $this->wrappedHeaderLine('Content-Disposition', 'inline; filename=' . $media['name']); } else { - $mime .= $this->wrappedHeaderLine('Content-Disposition', 'attachment; filename='.$media['name']); + $mime .= $this->wrappedHeaderLine('Content-Disposition', 'attachment; filename=' . $media['name']); } $mime .= MAILHEADER_EOL; //end of headers $mime .= chunk_split(base64_encode($media['data']), 74, MAILHEADER_EOL); @@ -472,15 +494,16 @@ class Mailer { * * @return string the prepared mail body, false on errors */ - protected function prepareBody() { + protected function prepareBody() + { // no HTML mails allowed? remove HTML body - if(!$this->allowhtml) { + if (!$this->allowhtml) { $this->html = ''; } // check for body - if(!$this->text && !$this->html) { + if (!$this->text && !$this->html) { return false; } @@ -489,44 +512,44 @@ class Mailer { $body = ''; - if(!$this->html && !count($this->attach)) { // we can send a simple single part message + if (!$this->html && !count($this->attach)) { // we can send a simple single part message $this->headers['Content-Type'] = 'text/plain; charset=UTF-8'; $this->headers['Content-Transfer-Encoding'] = 'base64'; $body .= chunk_split(base64_encode($this->text), 72, MAILHEADER_EOL); } else { // multi part it is - $body .= "This is a multi-part message in MIME format.".MAILHEADER_EOL; + $body .= "This is a multi-part message in MIME format." . MAILHEADER_EOL; // prepare the attachments $attachments = $this->prepareAttachments(); // do we have alternative text content? - if($this->text && $this->html) { - $this->headers['Content-Type'] = 'multipart/alternative;'.MAILHEADER_EOL. - ' boundary="'.$this->boundary.'XX"'; - $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL; - $body .= 'Content-Type: text/plain; charset=UTF-8'.MAILHEADER_EOL; - $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; + if ($this->text && $this->html) { + $this->headers['Content-Type'] = 'multipart/alternative;' . MAILHEADER_EOL . + ' boundary="' . $this->boundary . 'XX"'; + $body .= '--' . $this->boundary . 'XX' . MAILHEADER_EOL; + $body .= 'Content-Type: text/plain; charset=UTF-8' . MAILHEADER_EOL; + $body .= 'Content-Transfer-Encoding: base64' . MAILHEADER_EOL; $body .= MAILHEADER_EOL; $body .= chunk_split(base64_encode($this->text), 72, MAILHEADER_EOL); - $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL; - $body .= 'Content-Type: multipart/related;'.MAILHEADER_EOL. - ' boundary="'.$this->boundary.'";'.MAILHEADER_EOL. - ' type="text/html"'.MAILHEADER_EOL; + $body .= '--' . $this->boundary . 'XX' . MAILHEADER_EOL; + $body .= 'Content-Type: multipart/related;' . MAILHEADER_EOL . + ' boundary="' . $this->boundary . '";' . MAILHEADER_EOL . + ' type="text/html"' . MAILHEADER_EOL; $body .= MAILHEADER_EOL; } - $body .= '--'.$this->boundary.MAILHEADER_EOL; - $body .= 'Content-Type: text/html; charset=UTF-8'.MAILHEADER_EOL; - $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; + $body .= '--' . $this->boundary . MAILHEADER_EOL; + $body .= 'Content-Type: text/html; charset=UTF-8' . MAILHEADER_EOL; + $body .= 'Content-Transfer-Encoding: base64' . MAILHEADER_EOL; $body .= MAILHEADER_EOL; $body .= chunk_split(base64_encode($this->html), 72, MAILHEADER_EOL); $body .= MAILHEADER_EOL; $body .= $attachments; - $body .= '--'.$this->boundary.'--'.MAILHEADER_EOL; + $body .= '--' . $this->boundary . '--' . MAILHEADER_EOL; // close open multipart/alternative boundary - if($this->text && $this->html) { - $body .= '--'.$this->boundary.'XX--'.MAILHEADER_EOL; + if ($this->text && $this->html) { + $body .= '--' . $this->boundary . 'XX--' . MAILHEADER_EOL; } } @@ -536,44 +559,44 @@ class Mailer { /** * Cleanup and encode the headers array */ - protected function cleanHeaders() { + protected function cleanHeaders() + { global $conf; // clean up addresses - if(empty($this->headers['From'])) $this->from($conf['mailfrom']); - $addrs = array('To', 'From', 'Cc', 'Bcc', 'Reply-To', 'Sender'); - foreach($addrs as $addr) { - if(isset($this->headers[$addr])) { + if (empty($this->headers['From'])) $this->from($conf['mailfrom']); + $addrs = ['To', 'From', 'Cc', 'Bcc', 'Reply-To', 'Sender']; + foreach ($addrs as $addr) { + if (isset($this->headers[$addr])) { $this->headers[$addr] = $this->cleanAddress($this->headers[$addr]); } } - if(isset($this->headers['Subject'])) { + if (isset($this->headers['Subject'])) { // add prefix to subject - if(empty($conf['mailprefix'])) { - if(\dokuwiki\Utf8\PhpString::strlen($conf['title']) < 20) { - $prefix = '['.$conf['title'].']'; + if (empty($conf['mailprefix'])) { + if (PhpString::strlen($conf['title']) < 20) { + $prefix = '[' . $conf['title'] . ']'; } else { - $prefix = '['.\dokuwiki\Utf8\PhpString::substr($conf['title'], 0, 20).'...]'; + $prefix = '[' . PhpString::substr($conf['title'], 0, 20) . '...]'; } } else { - $prefix = '['.$conf['mailprefix'].']'; + $prefix = '[' . $conf['mailprefix'] . ']'; } $len = strlen($prefix); - if(substr($this->headers['Subject'], 0, $len) != $prefix) { - $this->headers['Subject'] = $prefix.' '.$this->headers['Subject']; + if (substr($this->headers['Subject'], 0, $len) !== $prefix) { + $this->headers['Subject'] = $prefix . ' ' . $this->headers['Subject']; } // encode subject - if(defined('MAILHEADER_ASCIIONLY')) { - $this->headers['Subject'] = \dokuwiki\Utf8\Clean::deaccent($this->headers['Subject']); - $this->headers['Subject'] = \dokuwiki\Utf8\Clean::strip($this->headers['Subject']); + if (defined('MAILHEADER_ASCIIONLY')) { + $this->headers['Subject'] = Clean::deaccent($this->headers['Subject']); + $this->headers['Subject'] = Clean::strip($this->headers['Subject']); } - if(!\dokuwiki\Utf8\Clean::isASCII($this->headers['Subject'])) { - $this->headers['Subject'] = '=?UTF-8?B?'.base64_encode($this->headers['Subject']).'?='; + if (!Clean::isASCII($this->headers['Subject'])) { + $this->headers['Subject'] = '=?UTF-8?B?' . base64_encode($this->headers['Subject']) . '?='; } } - } /** @@ -583,8 +606,9 @@ class Mailer { * @param string $val * @return string line */ - protected function wrappedHeaderLine($key, $val){ - return wordwrap("$key: $val", 78, MAILHEADER_EOL.' ').MAILHEADER_EOL; + protected function wrappedHeaderLine($key, $val) + { + return wordwrap("$key: $val", 78, MAILHEADER_EOL . ' ') . MAILHEADER_EOL; } /** @@ -592,9 +616,10 @@ class Mailer { * * @returns string the headers */ - protected function prepareHeaders() { + protected function prepareHeaders() + { $headers = ''; - foreach($this->headers as $key => $val) { + foreach ($this->headers as $key => $val) { if ($val === '' || $val === null) continue; $headers .= $this->wrappedHeaderLine($key, $val); } @@ -609,13 +634,14 @@ class Mailer { * * @return string the mail, false on errors */ - public function dump() { + public function dump() + { $this->cleanHeaders(); $body = $this->prepareBody(); - if($body === false) return false; + if ($body === false) return false; $headers = $this->prepareHeaders(); - return $headers.MAILHEADER_EOL.$body; + return $headers . MAILHEADER_EOL . $body; } /** @@ -624,7 +650,8 @@ class Mailer { * Populates the '$replacements' property. * Should be called by the class constructor */ - protected function prepareTokenReplacements() { + protected function prepareTokenReplacements() + { global $INFO; global $conf; /* @var Input $INPUT */ @@ -636,7 +663,7 @@ class Mailer { $name = $INFO['userinfo']['name'] ?? ''; $mail = $INFO['userinfo']['mail'] ?? ''; - $this->replacements['text'] = array( + $this->replacements['text'] = [ 'DATE' => dformat(), 'BROWSER' => $INPUT->server->str('HTTP_USER_AGENT'), 'IPADDRESS' => $ip, @@ -646,7 +673,8 @@ class Mailer { 'USER' => $INPUT->server->str('REMOTE_USER'), 'NAME' => $name, 'MAIL' => $mail - ); + ]; + $signature = str_replace( '@DOKUWIKIURL@', $this->replacements['text']['DOKUWIKIURL'], @@ -654,7 +682,7 @@ class Mailer { ); $this->replacements['text']['EMAILSIGNATURE'] = "\n-- \n" . $signature . "\n"; - $this->replacements['html'] = array( + $this->replacements['html'] = [ 'DATE' => '<i>' . hsc(dformat()) . '</i>', 'BROWSER' => hsc($INPUT->server->str('HTTP_USER_AGENT')), 'IPADDRESS' => '<code>' . hsc($ip) . '</code>', @@ -663,22 +691,15 @@ class Mailer { 'DOKUWIKIURL' => '<a href="' . DOKU_URL . '">' . DOKU_URL . '</a>', 'USER' => hsc($INPUT->server->str('REMOTE_USER')), 'NAME' => hsc($name), - 'MAIL' => '<a href="mailto:"' . hsc($mail) . '">' . - hsc($mail) . '</a>' - ); + 'MAIL' => '<a href="mailto:"' . hsc($mail) . '">' . hsc($mail) . '</a>' + ]; $signature = $lang['email_signature_text']; - if(!empty($lang['email_signature_html'])) { + if (!empty($lang['email_signature_html'])) { $signature = $lang['email_signature_html']; } $signature = str_replace( - array( - '@DOKUWIKIURL@', - "\n" - ), - array( - $this->replacements['html']['DOKUWIKIURL'], - '<br />' - ), + ['@DOKUWIKIURL@', "\n"], + [$this->replacements['html']['DOKUWIKIURL'], '<br />'], $signature ); $this->replacements['html']['EMAILSIGNATURE'] = $signature; @@ -692,12 +713,13 @@ class Mailer { * @triggers MAIL_MESSAGE_SEND * @return bool true if the mail was successfully passed to the MTA */ - public function send() { + public function send() + { global $lang; $success = false; // prepare hook data - $data = array( + $data = [ // pass the whole mail class to plugin 'mail' => $this, // pass references for backward compatibility @@ -711,22 +733,23 @@ class Mailer { 'headers' => '', // plugins shouldn't use this // signal if we mailed successfully to AFTER event 'success' => &$success, - ); + ]; // do our thing if BEFORE hook approves $evt = new Event('MAIL_MESSAGE_SEND', $data); - if($evt->advise_before(true)) { + if ($evt->advise_before(true)) { // clean up before using the headers $this->cleanHeaders(); // any recipients? - if(trim($this->headers['To']) === '' && + if ( + trim($this->headers['To']) === '' && trim($this->headers['Cc']) === '' && trim($this->headers['Bcc']) === '' ) return false; // The To: header is special - if(array_key_exists('To', $this->headers)) { + if (array_key_exists('To', $this->headers)) { $to = (string)$this->headers['To']; unset($this->headers['To']); } else { @@ -734,7 +757,7 @@ class Mailer { } // so is the subject - if(array_key_exists('Subject', $this->headers)) { + if (array_key_exists('Subject', $this->headers)) { $subject = (string)$this->headers['Subject']; unset($this->headers['Subject']); } else { @@ -743,16 +766,16 @@ class Mailer { // make the body $body = $this->prepareBody(); - if($body === false) return false; + if ($body === false) return false; // cook the headers $headers = $this->prepareHeaders(); // add any headers set by legacy plugins - if(trim($data['headers'])) { - $headers .= MAILHEADER_EOL.trim($data['headers']); + if (trim($data['headers'])) { + $headers .= MAILHEADER_EOL . trim($data['headers']); } - if(!function_exists('mail')){ + if (!function_exists('mail')) { $emsg = $lang['email_fail'] . $subject; error_log($emsg); msg(hsc($emsg), -1, __LINE__, __FILE__, MSG_MANAGERS_ONLY); @@ -761,8 +784,8 @@ class Mailer { } // send the thing - if($to === '') $to = '(undisclosed-recipients)'; // #1422 - if($this->sendparam === null) { + if ($to === '') $to = '(undisclosed-recipients)'; // #1422 + if ($this->sendparam === null) { $success = @mail($to, $subject, $body, $headers); } else { $success = @mail($to, $subject, $body, $headers, $this->sendparam); diff --git a/inc/Manifest.php b/inc/Manifest.php index 29e7f263f..15d9446fa 100644 --- a/inc/Manifest.php +++ b/inc/Manifest.php @@ -30,7 +30,7 @@ class Manifest $manifest['start_url'] = DOKU_REL; } - $styleUtil = new \dokuwiki\StyleUtils(); + $styleUtil = new StyleUtils(); $styleIni = $styleUtil->cssStyleini(); $replacements = $styleIni['replacements']; @@ -39,9 +39,9 @@ class Manifest } if (empty($manifest['theme_color'])) { - $manifest['theme_color'] = !empty($replacements['__theme_color__']) - ? $replacements['__theme_color__'] - : $replacements['__background_alt__']; + $manifest['theme_color'] = empty($replacements['__theme_color__']) + ? $replacements['__background_alt__'] + : $replacements['__theme_color__']; } if (empty($manifest['icons'])) { @@ -61,7 +61,6 @@ class Manifest ]; foreach ($look as $svgLogo) { - $svgLogoFN = mediaFN($svgLogo); if (file_exists($svgLogoFN)) { @@ -79,6 +78,6 @@ class Manifest Event::createAndTrigger('MANIFEST_SEND', $manifest); header('Content-Type: application/manifest+json'); - echo json_encode($manifest); + echo json_encode($manifest, JSON_THROW_ON_ERROR); } } diff --git a/inc/Menu/AbstractMenu.php b/inc/Menu/AbstractMenu.php index 37e5d2cc3..499500696 100644 --- a/inc/Menu/AbstractMenu.php +++ b/inc/Menu/AbstractMenu.php @@ -12,10 +12,10 @@ use dokuwiki\Menu\Item\AbstractItem; * It contains convenience functions to display the menu in HTML, but template authors can also * just accesst the items via getItems() and create the HTML as however they see fit. */ -abstract class AbstractMenu implements MenuInterface { - +abstract class AbstractMenu implements MenuInterface +{ /** @var string[] list of Item classes to load */ - protected $types = array(); + protected $types = []; /** @var int the context this menu is used in */ protected $context = AbstractItem::CTX_DESKTOP; @@ -28,7 +28,8 @@ abstract class AbstractMenu implements MenuInterface { * * @param int $context the context this menu is used in */ - public function __construct($context = AbstractItem::CTX_DESKTOP) { + public function __construct($context = AbstractItem::CTX_DESKTOP) + { $this->context = $context; } @@ -38,30 +39,29 @@ abstract class AbstractMenu implements MenuInterface { * @return AbstractItem[] * @triggers MENU_ITEMS_ASSEMBLY */ - public function getItems() { - $data = array( - 'view' => $this->view, - 'items' => array(), - ); - Event::createAndTrigger('MENU_ITEMS_ASSEMBLY', $data, array($this, 'loadItems')); + public function getItems() + { + $data = ['view' => $this->view, 'items' => []]; + Event::createAndTrigger('MENU_ITEMS_ASSEMBLY', $data, [$this, 'loadItems']); return $data['items']; } /** * Default action for the MENU_ITEMS_ASSEMBLY event * - * @see getItems() * @param array $data The plugin data + * @see getItems() */ - public function loadItems(&$data) { - foreach($this->types as $class) { + public function loadItems(&$data) + { + foreach ($this->types as $class) { try { $class = "\\dokuwiki\\Menu\\Item\\$class"; /** @var AbstractItem $item */ $item = new $class(); - if(!$item->visibleInContext($this->context)) continue; + if (!$item->visibleInContext($this->context)) continue; $data['items'][] = $item; - } catch(\RuntimeException $ignored) { + } catch (\RuntimeException $ignored) { // item not available } } @@ -77,10 +77,11 @@ abstract class AbstractMenu implements MenuInterface { * @param bool $svg add the SVG link * @return string */ - public function getListItems($classprefix = '', $svg = true) { + public function getListItems($classprefix = '', $svg = true) + { $html = ''; - foreach($this->getItems() as $item) { - if($classprefix !== false) { + foreach ($this->getItems() as $item) { + if ($classprefix !== false) { $class = ' class="' . $classprefix . $item->getType() . '"'; } else { $class = ''; @@ -92,5 +93,4 @@ abstract class AbstractMenu implements MenuInterface { } return $html; } - } diff --git a/inc/Menu/DetailMenu.php b/inc/Menu/DetailMenu.php index 27c0c6fce..2eb5c089e 100644 --- a/inc/Menu/DetailMenu.php +++ b/inc/Menu/DetailMenu.php @@ -8,14 +8,9 @@ namespace dokuwiki\Menu; * This menu offers options on an image detail view. It usually displayed similar to * the PageMenu. */ -class DetailMenu extends AbstractMenu { - +class DetailMenu extends AbstractMenu +{ protected $view = 'detail'; - protected $types = array( - 'MediaManager', - 'ImgBackto', - 'Top', - ); - + protected $types = ['MediaManager', 'ImgBackto', 'Top']; } diff --git a/inc/Menu/Item/AbstractItem.php b/inc/Menu/Item/AbstractItem.php index c6b04bfd3..509ce9747 100644 --- a/inc/Menu/Item/AbstractItem.php +++ b/inc/Menu/Item/AbstractItem.php @@ -17,14 +17,14 @@ namespace dokuwiki\Menu\Item; * Children usually just need to overwrite the different properties, but for complex things * the accessors may be overwritten instead. */ -abstract class AbstractItem { - +abstract class AbstractItem +{ /** menu item is to be shown on desktop screens only */ - const CTX_DESKTOP = 1; + public const CTX_DESKTOP = 1; /** menu item is to be shown on mobile screens only */ - const CTX_MOBILE = 2; + public const CTX_MOBILE = 2; /** menu item is to be shown in all contexts */ - const CTX_ALL = 3; + public const CTX_ALL = 3; /** @var string name of the action, usually the lowercase class name */ protected $type = ''; @@ -35,7 +35,7 @@ abstract class AbstractItem { /** @var string the method to be used when this action is used in a form */ protected $method = 'get'; /** @var array parameters for the action (should contain the do parameter) */ - protected $params = array(); + protected $params = []; /** @var bool when true, a rel=nofollow should be used */ protected $nofollow = true; /** @var string this item's label may contain a placeholder, which is replaced with this */ @@ -58,13 +58,14 @@ abstract class AbstractItem { * * @throws \RuntimeException when the action is disabled */ - public function __construct() { + public function __construct() + { global $ID; $this->id = $ID; $this->type = $this->getType(); $this->params['do'] = $this->type; - if(!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}"); + if (!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}"); } /** @@ -76,16 +77,17 @@ abstract class AbstractItem { * * @return string */ - public function getLabel() { - if($this->label !== '') return $this->label; + public function getLabel() + { + if ($this->label !== '') return $this->label; /** @var array $lang */ global $lang; $label = $lang['btn_' . $this->type]; - if(strpos($label, '%s')) { + if (strpos($label, '%s')) { $label = sprintf($label, $this->replacement); } - if($label === '') $label = '[' . $this->type . ']'; + if ($label === '') $label = '[' . $this->type . ']'; return $label; } @@ -97,8 +99,9 @@ abstract class AbstractItem { * * @return string */ - public function getTitle() { - if($this->title === '') return $this->getLabel(); + public function getTitle() + { + if ($this->title === '') return $this->getLabel(); return $this->title; } @@ -110,11 +113,12 @@ abstract class AbstractItem { * * Please note that the generated URL is *not* XML escaped. * - * @see wl() * @return string + * @see wl() */ - public function getLink() { - if($this->id && $this->id[0] == '#') { + public function getLink() + { + if ($this->id && $this->id[0] == '#') { return $this->id; } else { return wl($this->id, $this->params, false, '&'); @@ -124,21 +128,19 @@ abstract class AbstractItem { /** * Convenience method to get the attributes for constructing an <a> element * - * @see buildAttributes() * @param string|false $classprefix create a class from type with this prefix, false for no class * @return array + * @see buildAttributes() */ - public function getLinkAttributes($classprefix = 'menuitem ') { - $attr = array( - 'href' => $this->getLink(), - 'title' => $this->getTitle(), - ); - if($this->isNofollow()) $attr['rel'] = 'nofollow'; - if($this->getAccesskey()) { + public function getLinkAttributes($classprefix = 'menuitem ') + { + $attr = ['href' => $this->getLink(), 'title' => $this->getTitle()]; + if ($this->isNofollow()) $attr['rel'] = 'nofollow'; + if ($this->getAccesskey()) { $attr['accesskey'] = $this->getAccesskey(); $attr['title'] .= ' [' . $this->getAccesskey() . ']'; } - if($classprefix !== false) $attr['class'] = $classprefix . $this->getType(); + if ($classprefix !== false) $attr['class'] = $classprefix . $this->getType(); return $attr; } @@ -152,10 +154,11 @@ abstract class AbstractItem { * @param bool $svg add SVG icon to the link * @return string */ - public function asHtmlLink($classprefix = 'menuitem ', $svg = true) { + public function asHtmlLink($classprefix = 'menuitem ', $svg = true) + { $attr = buildAttributes($this->getLinkAttributes($classprefix)); $html = "<a $attr>"; - if($svg) { + if ($svg) { $html .= '<span>' . hsc($this->getLabel()) . '</span>'; $html .= inlineSVG($this->getSvg()); } else { @@ -173,7 +176,8 @@ abstract class AbstractItem { * * @return string */ - public function asHtmlButton() { + public function asHtmlButton() + { return html_btn( $this->getType(), $this->id, @@ -192,15 +196,17 @@ abstract class AbstractItem { * @param int $ctx the current context * @return bool */ - public function visibleInContext($ctx) { - return (bool) ($ctx & $this->context); + public function visibleInContext($ctx) + { + return (bool)($ctx & $this->context); } /** * @return string the name of this item */ - public function getType() { - if($this->type === '') { + public function getType() + { + if ($this->type === '') { $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1)); } return $this->type; @@ -209,28 +215,32 @@ abstract class AbstractItem { /** * @return string */ - public function getAccesskey() { + public function getAccesskey() + { return $this->accesskey; } /** * @return array */ - public function getParams() { + public function getParams() + { return $this->params; } /** * @return bool */ - public function isNofollow() { + public function isNofollow() + { return $this->nofollow; } /** * @return string */ - public function getSvg() { + public function getSvg() + { return $this->svg; } @@ -239,8 +249,9 @@ abstract class AbstractItem { * * @return array */ - public function getLegacyData() { - return array( + public function getLegacyData() + { + return [ 'accesskey' => $this->accesskey ?: null, 'type' => $this->type, 'id' => $this->id, @@ -248,6 +259,6 @@ abstract class AbstractItem { 'params' => $this->params, 'nofollow' => $this->nofollow, 'replacement' => $this->replacement - ); + ]; } } diff --git a/inc/Menu/Item/Admin.php b/inc/Menu/Item/Admin.php index e5506c220..d75b8ad6f 100644 --- a/inc/Menu/Item/Admin.php +++ b/inc/Menu/Item/Admin.php @@ -7,10 +7,11 @@ namespace dokuwiki\Menu\Item; * * Opens the Admin screen. Only shown to managers or above */ -class Admin extends AbstractItem { - +class Admin extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { parent::__construct(); $this->svg = DOKU_INC . 'lib/images/menu/settings.svg'; @@ -20,9 +21,8 @@ class Admin extends AbstractItem { public function visibleInContext($ctx) { global $INFO; - if(!$INFO['ismanager']) return false; + if (!$INFO['ismanager']) return false; return parent::visibleInContext($ctx); } - } diff --git a/inc/Menu/Item/Back.php b/inc/Menu/Item/Back.php index a7cc1d976..6c67492c4 100644 --- a/inc/Menu/Item/Back.php +++ b/inc/Menu/Item/Back.php @@ -8,22 +8,22 @@ namespace dokuwiki\Menu\Item; * Navigates back up one namepspace. This is currently not used in any menu. Templates * would need to add this item manually. */ -class Back extends AbstractItem { - +class Back extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $ID; parent::__construct(); $parent = tpl_getparent($ID); - if(!$parent) { + if (!$parent) { throw new \RuntimeException("No parent for back action"); } $this->id = $parent; - $this->params = array('do' => ''); + $this->params = ['do' => '']; $this->accesskey = 'b'; $this->svg = DOKU_INC . 'lib/images/menu/12-back_arrow-left.svg'; } - } diff --git a/inc/Menu/Item/Backlink.php b/inc/Menu/Item/Backlink.php index 6dc242bdd..906d6004a 100644 --- a/inc/Menu/Item/Backlink.php +++ b/inc/Menu/Item/Backlink.php @@ -7,12 +7,12 @@ namespace dokuwiki\Menu\Item; * * Shows the backlinks for the current page */ -class Backlink extends AbstractItem { - +class Backlink extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { parent::__construct(); $this->svg = DOKU_INC . 'lib/images/menu/08-backlink_link-variant.svg'; } - } diff --git a/inc/Menu/Item/Edit.php b/inc/Menu/Item/Edit.php index 579b6885d..c063ca28a 100644 --- a/inc/Menu/Item/Edit.php +++ b/inc/Menu/Item/Edit.php @@ -8,38 +8,39 @@ namespace dokuwiki\Menu\Item; * Most complex item. Shows the edit button but mutates to show, draft and create based on * current state. */ -class Edit extends AbstractItem { - +class Edit extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $ACT; global $INFO; global $REV; parent::__construct(); - if($ACT === 'show') { + if ($ACT === 'show') { $this->method = 'post'; - if($INFO['writable']) { + if ($INFO['writable']) { $this->accesskey = 'e'; - if(!empty($INFO['draft'])) { + if (!empty($INFO['draft'])) { $this->type = 'draft'; $this->params['do'] = 'draft'; } else { $this->params['rev'] = $REV; - if(!$INFO['exists']) { + if (!$INFO['exists']) { $this->type = 'create'; } } } else { - if(!actionOK("source")) throw new \RuntimeException("action disabled: source"); + if (!actionOK("source")) throw new \RuntimeException("action disabled: source"); $params['rev'] = $REV; $this->type = 'source'; $this->accesskey = 'v'; } } else { if (auth_quickaclcheck($INFO['id']) < AUTH_READ) throw new \RuntimeException("no permission to read"); - $this->params = array('do' => ''); + $this->params = ['do' => '']; $this->type = 'show'; $this->accesskey = 'v'; } @@ -50,17 +51,17 @@ class Edit extends AbstractItem { /** * change the icon according to what type the edit button has */ - protected function setIcon() { - $icons = array( + protected function setIcon() + { + $icons = [ 'edit' => '01-edit_pencil.svg', 'create' => '02-create_pencil.svg', 'draft' => '03-draft_android-studio.svg', 'show' => '04-show_file-document.svg', - 'source' => '05-source_file-xml.svg', - ); - if(isset($icons[$this->type])) { + 'source' => '05-source_file-xml.svg' + ]; + if (isset($icons[$this->type])) { $this->svg = DOKU_INC . 'lib/images/menu/' . $icons[$this->type]; } } - } diff --git a/inc/Menu/Item/ImgBackto.php b/inc/Menu/Item/ImgBackto.php index 72820a53a..2d8a2c9b3 100644 --- a/inc/Menu/Item/ImgBackto.php +++ b/inc/Menu/Item/ImgBackto.php @@ -7,18 +7,18 @@ namespace dokuwiki\Menu\Item; * * Links back to the originating page from a detail image view */ -class ImgBackto extends AbstractItem { - +class ImgBackto extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $ID; parent::__construct(); $this->svg = DOKU_INC . 'lib/images/menu/12-back_arrow-left.svg'; $this->type = 'img_backto'; - $this->params = array(); + $this->params = []; $this->accesskey = 'b'; $this->replacement = $ID; } - } diff --git a/inc/Menu/Item/Index.php b/inc/Menu/Item/Index.php index 41326738b..a7459546e 100644 --- a/inc/Menu/Item/Index.php +++ b/inc/Menu/Item/Index.php @@ -7,10 +7,11 @@ namespace dokuwiki\Menu\Item; * * Shows the sitemap */ -class Index extends AbstractItem { - +class Index extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $conf; global $ID; parent::__construct(); @@ -19,9 +20,8 @@ class Index extends AbstractItem { $this->svg = DOKU_INC . 'lib/images/menu/file-tree.svg'; // allow searchbots to get to the sitemap from the homepage (when dokuwiki isn't providing a sitemap.xml) - if($conf['start'] == $ID && !$conf['sitemap']) { + if ($conf['start'] == $ID && !$conf['sitemap']) { $this->nofollow = false; } } - } diff --git a/inc/Menu/Item/Login.php b/inc/Menu/Item/Login.php index 671f6a78a..ca2542b02 100644 --- a/inc/Menu/Item/Login.php +++ b/inc/Menu/Item/Login.php @@ -7,17 +7,18 @@ namespace dokuwiki\Menu\Item; * * Show a login or logout item, based on the current state */ -class Login extends AbstractItem { - +class Login extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $INPUT; parent::__construct(); $this->svg = DOKU_INC . 'lib/images/menu/login.svg'; $this->params['sectok'] = getSecurityToken(); - if($INPUT->server->has('REMOTE_USER')) { - if(!actionOK('logout')) { + if ($INPUT->server->has('REMOTE_USER')) { + if (!actionOK('logout')) { throw new \RuntimeException("logout disabled"); } $this->params['do'] = 'logout'; @@ -25,5 +26,4 @@ class Login extends AbstractItem { $this->svg = DOKU_INC . 'lib/images/menu/logout.svg'; } } - } diff --git a/inc/Menu/Item/Media.php b/inc/Menu/Item/Media.php index 0e5f47bae..3f0cc481e 100644 --- a/inc/Menu/Item/Media.php +++ b/inc/Menu/Item/Media.php @@ -7,15 +7,15 @@ namespace dokuwiki\Menu\Item; * * Opens the media manager */ -class Media extends AbstractItem { - +class Media extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $ID; parent::__construct(); $this->svg = DOKU_INC . 'lib/images/menu/folder-multiple-image.svg'; $this->params['ns'] = getNS($ID); } - } diff --git a/inc/Menu/Item/MediaManager.php b/inc/Menu/Item/MediaManager.php index 8549d2005..2bd5c1a85 100644 --- a/inc/Menu/Item/MediaManager.php +++ b/inc/Menu/Item/MediaManager.php @@ -7,26 +7,22 @@ namespace dokuwiki\Menu\Item; * * Opens the current image in the media manager. Used on image detail view. */ -class MediaManager extends AbstractItem { - +class MediaManager extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $IMG; parent::__construct(); $imgNS = getNS($IMG); $authNS = auth_quickaclcheck("$imgNS:*"); - if($authNS < AUTH_UPLOAD) { + if ($authNS < AUTH_UPLOAD) { throw new \RuntimeException("media manager link only with upload permissions"); } $this->svg = DOKU_INC . 'lib/images/menu/11-mediamanager_folder-image.svg'; $this->type = 'mediaManager'; - $this->params = array( - 'ns' => $imgNS, - 'image' => $IMG, - 'do' => 'media' - ); + $this->params = ['ns' => $imgNS, 'image' => $IMG, 'do' => 'media']; } - } diff --git a/inc/Menu/Item/Profile.php b/inc/Menu/Item/Profile.php index 2b4ceeb77..2e24c2803 100644 --- a/inc/Menu/Item/Profile.php +++ b/inc/Menu/Item/Profile.php @@ -7,18 +7,18 @@ namespace dokuwiki\Menu\Item; * * Open the user's profile */ -class Profile extends AbstractItem { - +class Profile extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $INPUT; parent::__construct(); - if(!$INPUT->server->str('REMOTE_USER')) { + if (!$INPUT->server->str('REMOTE_USER')) { throw new \RuntimeException("profile is only for logged in users"); } $this->svg = DOKU_INC . 'lib/images/menu/account-card-details.svg'; } - } diff --git a/inc/Menu/Item/Recent.php b/inc/Menu/Item/Recent.php index ff90ce605..dabfef123 100644 --- a/inc/Menu/Item/Recent.php +++ b/inc/Menu/Item/Recent.php @@ -7,14 +7,14 @@ namespace dokuwiki\Menu\Item; * * Show the site wide recent changes */ -class Recent extends AbstractItem { - +class Recent extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { parent::__construct(); $this->accesskey = 'r'; $this->svg = DOKU_INC . 'lib/images/menu/calendar-clock.svg'; } - } diff --git a/inc/Menu/Item/Register.php b/inc/Menu/Item/Register.php index 615146ea6..dd2c806cb 100644 --- a/inc/Menu/Item/Register.php +++ b/inc/Menu/Item/Register.php @@ -7,18 +7,18 @@ namespace dokuwiki\Menu\Item; * * Open the view to register a new account */ -class Register extends AbstractItem { - +class Register extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $INPUT; parent::__construct(); - if($INPUT->server->str('REMOTE_USER')) { + if ($INPUT->server->str('REMOTE_USER')) { throw new \RuntimeException("no register when already logged in"); } $this->svg = DOKU_INC . 'lib/images/menu/account-plus.svg'; } - } diff --git a/inc/Menu/Item/Resendpwd.php b/inc/Menu/Item/Resendpwd.php index 7ddc6b02f..6903d0b07 100644 --- a/inc/Menu/Item/Resendpwd.php +++ b/inc/Menu/Item/Resendpwd.php @@ -7,18 +7,18 @@ namespace dokuwiki\Menu\Item; * * Access the "forgot password" dialog */ -class Resendpwd extends AbstractItem { - +class Resendpwd extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $INPUT; parent::__construct(); - if($INPUT->server->str('REMOTE_USER')) { + if ($INPUT->server->str('REMOTE_USER')) { throw new \RuntimeException("no resendpwd when already logged in"); } $this->svg = DOKU_INC . 'lib/images/menu/lock-reset.svg'; } - } diff --git a/inc/Menu/Item/Revert.php b/inc/Menu/Item/Revert.php index f4ae1b36d..c7a3d9fdb 100644 --- a/inc/Menu/Item/Revert.php +++ b/inc/Menu/Item/Revert.php @@ -9,7 +9,6 @@ namespace dokuwiki\Menu\Item; */ class Revert extends AbstractItem { - /** @inheritdoc */ public function __construct() { @@ -25,5 +24,4 @@ class Revert extends AbstractItem $this->params['sectok'] = getSecurityToken(); $this->svg = DOKU_INC . 'lib/images/menu/06-revert_replay.svg'; } - } diff --git a/inc/Menu/Item/Revisions.php b/inc/Menu/Item/Revisions.php index 3009a7924..4b220b801 100644 --- a/inc/Menu/Item/Revisions.php +++ b/inc/Menu/Item/Revisions.php @@ -7,15 +7,15 @@ namespace dokuwiki\Menu\Item; * * Access the old revisions of the current page */ -class Revisions extends AbstractItem { - +class Revisions extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { parent::__construct(); $this->accesskey = 'o'; $this->type = 'revs'; $this->svg = DOKU_INC . 'lib/images/menu/07-revisions_history.svg'; } - } diff --git a/inc/Menu/Item/Subscribe.php b/inc/Menu/Item/Subscribe.php index 1c9d335f8..0545e79eb 100644 --- a/inc/Menu/Item/Subscribe.php +++ b/inc/Menu/Item/Subscribe.php @@ -7,18 +7,18 @@ namespace dokuwiki\Menu\Item; * * Access the subscription management view */ -class Subscribe extends AbstractItem { - +class Subscribe extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { global $INPUT; parent::__construct(); - if(!$INPUT->server->str('REMOTE_USER')) { + if (!$INPUT->server->str('REMOTE_USER')) { throw new \RuntimeException("subscribe is only for logged in users"); } $this->svg = DOKU_INC . 'lib/images/menu/09-subscribe_email-outline.svg'; } - } diff --git a/inc/Menu/Item/Top.php b/inc/Menu/Item/Top.php index a05c4f119..685dcbd17 100644 --- a/inc/Menu/Item/Top.php +++ b/inc/Menu/Item/Top.php @@ -8,15 +8,16 @@ namespace dokuwiki\Menu\Item; * Scroll back to the top. Uses a hash as $id which is handled special in getLink(). * Not shown in mobile context */ -class Top extends AbstractItem { - +class Top extends AbstractItem +{ /** @inheritdoc */ - public function __construct() { + public function __construct() + { parent::__construct(); $this->svg = DOKU_INC . 'lib/images/menu/10-top_arrow-up.svg'; $this->accesskey = 't'; - $this->params = array('do' => ''); + $this->params = ['do' => '']; $this->id = '#dokuwiki__top'; $this->context = self::CTX_DESKTOP; } @@ -26,11 +27,11 @@ class Top extends AbstractItem { * * Uses html_topbtn() * - * @todo this does currently not support the SVG icon * @return string + * @todo this does currently not support the SVG icon */ - public function asHtmlButton() { + public function asHtmlButton() + { return html_topbtn(); } - } diff --git a/inc/Menu/MenuInterface.php b/inc/Menu/MenuInterface.php index 91dde9db6..52e06a256 100644 --- a/inc/Menu/MenuInterface.php +++ b/inc/Menu/MenuInterface.php @@ -9,8 +9,8 @@ use dokuwiki\Menu\Item\AbstractItem; * * Defines what a Menu provides */ -Interface MenuInterface { - +interface MenuInterface +{ /** * Get the list of action items in this menu * diff --git a/inc/Menu/MobileMenu.php b/inc/Menu/MobileMenu.php index 209805646..c9d13932f 100644 --- a/inc/Menu/MobileMenu.php +++ b/inc/Menu/MobileMenu.php @@ -11,23 +11,24 @@ use dokuwiki\Menu\Item\AbstractItem; * menus. This is a meta menu, aggregating the items from the other menus and offering a combined * view. The idea is to use this on mobile devices, thus the context is fixed to CTX_MOBILE */ -class MobileMenu implements MenuInterface { - +class MobileMenu implements MenuInterface +{ /** * Returns all items grouped by view * * @return AbstractItem[][] */ - public function getGroupedItems() { + public function getGroupedItems() + { $pagemenu = new PageMenu(AbstractItem::CTX_MOBILE); $sitemenu = new SiteMenu(AbstractItem::CTX_MOBILE); $usermenu = new UserMenu(AbstractItem::CTX_MOBILE); - return array( + return [ 'page' => $pagemenu->getItems(), 'site' => $sitemenu->getItems(), 'user' => $usermenu->getItems() - ); + ]; } /** @@ -37,9 +38,10 @@ class MobileMenu implements MenuInterface { * * @return AbstractItem[] */ - public function getItems() { + public function getItems() + { $menu = $this->getGroupedItems(); - return call_user_func_array('array_merge', array_values($menu)); + return array_merge(...array_values($menu)); } /** @@ -51,7 +53,8 @@ class MobileMenu implements MenuInterface { * @param string $button submit button label * @return string */ - public function getDropdown($empty = '', $button = '>') { + public function getDropdown($empty = '', $button = '>') + { global $ID; global $REV; /** @var string[] $lang */ @@ -61,18 +64,18 @@ class MobileMenu implements MenuInterface { $html = '<form action="' . script() . '" method="get" accept-charset="utf-8">'; $html .= '<div class="no">'; $html .= '<input type="hidden" name="id" value="' . $ID . '" />'; - if($REV) $html .= '<input type="hidden" name="rev" value="' . $REV . '" />'; - if($INPUT->server->str('REMOTE_USER')) { + if ($REV) $html .= '<input type="hidden" name="rev" value="' . $REV . '" />'; + if ($INPUT->server->str('REMOTE_USER')) { $html .= '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />'; } $html .= '<select name="do" class="edit quickselect" title="' . $lang['tools'] . '">'; $html .= '<option value="">' . $empty . '</option>'; - foreach($this->getGroupedItems() as $tools => $items) { - if (count($items)) { + foreach ($this->getGroupedItems() as $tools => $items) { + if ($items !== []) { $html .= '<optgroup label="' . $lang[$tools . '_tools'] . '">'; - foreach($items as $item) { + foreach ($items as $item) { $params = $item->getParams(); $html .= '<option value="' . $params['do'] . '">'; $html .= hsc($item->getLabel()); @@ -89,5 +92,4 @@ class MobileMenu implements MenuInterface { return $html; } - } diff --git a/inc/Menu/PageMenu.php b/inc/Menu/PageMenu.php index 9c0a55e2d..2ad219614 100644 --- a/inc/Menu/PageMenu.php +++ b/inc/Menu/PageMenu.php @@ -7,17 +7,9 @@ namespace dokuwiki\Menu; * * Actions manipulating the current page. Shown as a floating menu in the dokuwiki template */ -class PageMenu extends AbstractMenu { - +class PageMenu extends AbstractMenu +{ protected $view = 'page'; - protected $types = array( - 'Edit', - 'Revert', - 'Revisions', - 'Backlink', - 'Subscribe', - 'Top', - ); - + protected $types = ['Edit', 'Revert', 'Revisions', 'Backlink', 'Subscribe', 'Top']; } diff --git a/inc/Menu/SiteMenu.php b/inc/Menu/SiteMenu.php index dba6888c7..4edef6c50 100644 --- a/inc/Menu/SiteMenu.php +++ b/inc/Menu/SiteMenu.php @@ -7,14 +7,9 @@ namespace dokuwiki\Menu; * * Actions that are not bound to an individual page but provide toolsfor the whole wiki. */ -class SiteMenu extends AbstractMenu { - +class SiteMenu extends AbstractMenu +{ protected $view = 'site'; - protected $types = array( - 'Recent', - 'Media', - 'Index' - ); - + protected $types = ['Recent', 'Media', 'Index']; } diff --git a/inc/Menu/UserMenu.php b/inc/Menu/UserMenu.php index 01028d3cc..b094b1937 100644 --- a/inc/Menu/UserMenu.php +++ b/inc/Menu/UserMenu.php @@ -7,15 +7,9 @@ namespace dokuwiki\Menu; * * Actions related to the current user */ -class UserMenu extends AbstractMenu { - +class UserMenu extends AbstractMenu +{ protected $view = 'user'; - protected $types = array( - 'Profile', - 'Admin', - 'Register', - 'Login', - ); - + protected $types = ['Profile', 'Admin', 'Register', 'Login']; } diff --git a/inc/Parsing/Handler/AbstractRewriter.php b/inc/Parsing/Handler/AbstractRewriter.php index d9becbf4b..674d8c7ae 100644 --- a/inc/Parsing/Handler/AbstractRewriter.php +++ b/inc/Parsing/Handler/AbstractRewriter.php @@ -11,7 +11,7 @@ abstract class AbstractRewriter implements ReWriterInterface protected $callWriter; /** @var array[] list of calls */ - public $calls = array(); + public $calls = []; /** @inheritdoc */ public function __construct(CallWriterInterface $callWriter) diff --git a/inc/Parsing/Handler/Block.php b/inc/Parsing/Handler/Block.php index 586810438..db0a470cb 100644 --- a/inc/Parsing/Handler/Block.php +++ b/inc/Parsing/Handler/Block.php @@ -9,37 +9,27 @@ namespace dokuwiki\Parsing\Handler; */ class Block { - protected $calls = array(); + protected $calls = []; protected $skipEol = false; protected $inParagraph = false; // Blocks these should not be inside paragraphs - protected $blockOpen = array( - 'header', - 'listu_open','listo_open','listitem_open','listcontent_open', - 'table_open','tablerow_open','tablecell_open','tableheader_open','tablethead_open', - 'quote_open', - 'code','file','hr','preformatted','rss', - 'footnote_open', - ); + protected $blockOpen = [ + 'header', 'listu_open', 'listo_open', 'listitem_open', 'listcontent_open', 'table_open', 'tablerow_open', + 'tablecell_open', 'tableheader_open', 'tablethead_open', 'quote_open', 'code', 'file', 'hr', 'preformatted', + 'rss', 'footnote_open' + ]; - protected $blockClose = array( - 'header', - 'listu_close','listo_close','listitem_close','listcontent_close', - 'table_close','tablerow_close','tablecell_close','tableheader_close','tablethead_close', - 'quote_close', - 'code','file','hr','preformatted','rss', - 'footnote_close', - ); + protected $blockClose = [ + 'header', 'listu_close', 'listo_close', 'listitem_close', 'listcontent_close', 'table_close', + 'tablerow_close', 'tablecell_close', 'tableheader_close', 'tablethead_close', 'quote_close', 'code', 'file', + 'hr', 'preformatted', 'rss', 'footnote_close' + ]; // Stacks can contain paragraphs - protected $stackOpen = array( - 'section_open', - ); + protected $stackOpen = ['section_open']; - protected $stackClose = array( - 'section_close', - ); + protected $stackClose = ['section_close']; /** @@ -56,11 +46,11 @@ class Block foreach ($DOKU_PLUGINS['syntax'] as $n => $p) { $ptype = $p->getPType(); if ($ptype == 'block') { - $this->blockOpen[] = 'plugin_'.$n; - $this->blockClose[] = 'plugin_'.$n; + $this->blockOpen[] = 'plugin_' . $n; + $this->blockClose[] = 'plugin_' . $n; } elseif ($ptype == 'stack') { - $this->stackOpen[] = 'plugin_'.$n; - $this->stackClose[] = 'plugin_'.$n; + $this->stackOpen[] = 'plugin_' . $n; + $this->stackClose[] = 'plugin_' . $n; } } } @@ -68,7 +58,7 @@ class Block protected function openParagraph($pos) { if ($this->inParagraph) return; - $this->calls[] = array('p_open',array(), $pos); + $this->calls[] = ['p_open', [], $pos]; $this->inParagraph = true; $this->skipEol = true; } @@ -88,7 +78,7 @@ class Block // look back if there was any content - we don't want empty paragraphs $content = ''; $ccount = count($this->calls); - for ($i=$ccount-1; $i>=0; $i--) { + for ($i = $ccount - 1; $i >= 0; $i--) { if ($this->calls[$i][0] == 'p_open') { break; } elseif ($this->calls[$i][0] == 'cdata') { @@ -99,16 +89,18 @@ class Block } } - if (trim($content)=='') { + if (trim($content) == '') { //remove the whole paragraph //array_splice($this->calls,$i); // <- this is much slower than the loop below - for ($x=$ccount; $x>$i; - $x--) array_pop($this->calls); + for ( + $x = $ccount; $x > $i; + $x-- + ) array_pop($this->calls); } else { // remove ending linebreaks in the paragraph - $i=count($this->calls)-1; + $i = count($this->calls) - 1; if ($this->calls[$i][0] == 'cdata') $this->calls[$i][1][0] = rtrim($this->calls[$i][1][0], "\n"); - $this->calls[] = array('p_close',array(), $pos); + $this->calls[] = ['p_close', [], $pos]; } $this->inParagraph = false; @@ -118,8 +110,8 @@ class Block protected function addCall($call) { $key = count($this->calls); - if ($key and ($call[0] == 'cdata') and ($this->calls[$key-1][0] == 'cdata')) { - $this->calls[$key-1][1][0] .= $call[1][0]; + if ($key && $call[0] == 'cdata' && $this->calls[$key - 1][0] == 'cdata') { + $this->calls[$key - 1][1][0] .= $call[1][0]; } else { $this->calls[] = $call; } @@ -148,7 +140,7 @@ class Block foreach ($calls as $key => $call) { $cname = $call[0]; if ($cname == 'plugin') { - $cname='plugin_'.$call[1][0]; + $cname = 'plugin_' . $call[1][0]; $plugin = true; $plugin_open = (($call[1][2] == DOKU_LEXER_ENTER) || ($call[1][2] == DOKU_LEXER_SPECIAL)); $plugin_close = (($call[1][2] == DOKU_LEXER_EXIT) || ($call[1][2] == DOKU_LEXER_SPECIAL)); @@ -187,12 +179,12 @@ class Block // Check this isn't an eol instruction to skip... if (!$this->skipEol) { // Next is EOL => double eol => mark as paragraph - if (isset($calls[$key+1]) && $calls[$key+1][0] == 'eol') { + if (isset($calls[$key + 1]) && $calls[$key + 1][0] == 'eol') { $this->closeParagraph($call[2]); $this->openParagraph($call[2]); } else { //if this is just a single eol make a space from it - $this->addCall(array('cdata',array("\n"), $call[2])); + $this->addCall(['cdata', ["\n"], $call[2]]); } } continue; diff --git a/inc/Parsing/Handler/CallWriter.php b/inc/Parsing/Handler/CallWriter.php index 2457143ed..28b106d10 100644 --- a/inc/Parsing/Handler/CallWriter.php +++ b/inc/Parsing/Handler/CallWriter.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\Handler; class CallWriter implements CallWriterInterface { - /** @var \Doku_Handler $Handler */ protected $Handler; diff --git a/inc/Parsing/Handler/Lists.php b/inc/Parsing/Handler/Lists.php index 282ddfbe8..732e1c0c1 100644 --- a/inc/Parsing/Handler/Lists.php +++ b/inc/Parsing/Handler/Lists.php @@ -4,18 +4,18 @@ namespace dokuwiki\Parsing\Handler; class Lists extends AbstractRewriter { - protected $listCalls = array(); - protected $listStack = array(); + protected $listCalls = []; + protected $listStack = []; protected $initialDepth = 0; - const NODE = 1; + public const NODE = 1; /** @inheritdoc */ public function finalise() { $last_call = end($this->calls); - $this->writeCall(array('list_close',array(), $last_call[2])); + $this->writeCall(['list_close', [], $last_call[2]]); $this->process(); $this->callWriter->finalise(); @@ -53,11 +53,11 @@ class Lists extends AbstractRewriter $this->initialDepth = $depth; // array(list type, current depth, index of current listitem_open) - $this->listStack[] = array($listType, $depth, 1); + $this->listStack[] = [$listType, $depth, 1]; - $this->listCalls[] = array('list'.$listType.'_open',array(),$call[2]); - $this->listCalls[] = array('listitem_open',array(1),$call[2]); - $this->listCalls[] = array('listcontent_open',array(),$call[2]); + $this->listCalls[] = ['list' . $listType . '_open', [], $call[2]]; + $this->listCalls[] = ['listitem_open', [1], $call[2]]; + $this->listCalls[] = ['listcontent_open', [], $call[2]]; } @@ -67,11 +67,11 @@ class Lists extends AbstractRewriter while ($list = array_pop($this->listStack)) { if ($closeContent) { - $this->listCalls[] = array('listcontent_close',array(),$call[2]); + $this->listCalls[] = ['listcontent_close', [], $call[2]]; $closeContent = false; } - $this->listCalls[] = array('listitem_close',array(),$call[2]); - $this->listCalls[] = array('list'.$list[0].'_close', array(), $call[2]); + $this->listCalls[] = ['listitem_close', [], $call[2]]; + $this->listCalls[] = ['list' . $list[0] . '_close', [], $call[2]]; } } @@ -89,40 +89,40 @@ class Lists extends AbstractRewriter if ($depth == $end[1]) { // Just another item in the list... if ($listType == $end[0]) { - $this->listCalls[] = array('listcontent_close',array(),$call[2]); - $this->listCalls[] = array('listitem_close',array(),$call[2]); - $this->listCalls[] = array('listitem_open',array($depth-1),$call[2]); - $this->listCalls[] = array('listcontent_open',array(),$call[2]); + $this->listCalls[] = ['listcontent_close', [], $call[2]]; + $this->listCalls[] = ['listitem_close', [], $call[2]]; + $this->listCalls[] = ['listitem_open', [$depth - 1], $call[2]]; + $this->listCalls[] = ['listcontent_open', [], $call[2]]; // new list item, update list stack's index into current listitem_open $this->listStack[$key][2] = count($this->listCalls) - 2; // Switched list type... } else { - $this->listCalls[] = array('listcontent_close',array(),$call[2]); - $this->listCalls[] = array('listitem_close',array(),$call[2]); - $this->listCalls[] = array('list'.$end[0].'_close', array(), $call[2]); - $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]); - $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]); - $this->listCalls[] = array('listcontent_open',array(),$call[2]); + $this->listCalls[] = ['listcontent_close', [], $call[2]]; + $this->listCalls[] = ['listitem_close', [], $call[2]]; + $this->listCalls[] = ['list' . $end[0] . '_close', [], $call[2]]; + $this->listCalls[] = ['list' . $listType . '_open', [], $call[2]]; + $this->listCalls[] = ['listitem_open', [$depth - 1], $call[2]]; + $this->listCalls[] = ['listcontent_open', [], $call[2]]; array_pop($this->listStack); - $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2); + $this->listStack[] = [$listType, $depth, count($this->listCalls) - 2]; } } elseif ($depth > $end[1]) { // Getting deeper... - $this->listCalls[] = array('listcontent_close',array(),$call[2]); - $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]); - $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]); - $this->listCalls[] = array('listcontent_open',array(),$call[2]); + $this->listCalls[] = ['listcontent_close', [], $call[2]]; + $this->listCalls[] = ['list' . $listType . '_open', [], $call[2]]; + $this->listCalls[] = ['listitem_open', [$depth - 1], $call[2]]; + $this->listCalls[] = ['listcontent_open', [], $call[2]]; // set the node/leaf state of this item's parent listitem_open to NODE $this->listCalls[$this->listStack[$key][2]][1][1] = self::NODE; - $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2); + $this->listStack[] = [$listType, $depth, count($this->listCalls) - 2]; } else { // Getting shallower ( $depth < $end[1] ) - $this->listCalls[] = array('listcontent_close',array(),$call[2]); - $this->listCalls[] = array('listitem_close',array(),$call[2]); - $this->listCalls[] = array('list'.$end[0].'_close',array(),$call[2]); + $this->listCalls[] = ['listcontent_close', [], $call[2]]; + $this->listCalls[] = ['listitem_close', [], $call[2]]; + $this->listCalls[] = ['list' . $end[0] . '_close', [], $call[2]]; // Throw away the end - done array_pop($this->listStack); @@ -135,31 +135,31 @@ class Lists extends AbstractRewriter // Normalize depths $depth = $end[1]; - $this->listCalls[] = array('listitem_close',array(),$call[2]); + $this->listCalls[] = ['listitem_close', [], $call[2]]; if ($end[0] == $listType) { - $this->listCalls[] = array('listitem_open',array($depth-1),$call[2]); - $this->listCalls[] = array('listcontent_open',array(),$call[2]); + $this->listCalls[] = ['listitem_open', [$depth - 1], $call[2]]; + $this->listCalls[] = ['listcontent_open', [], $call[2]]; // new list item, update list stack's index into current listitem_open $this->listStack[$key][2] = count($this->listCalls) - 2; } else { // Switching list type... - $this->listCalls[] = array('list'.$end[0].'_close', array(), $call[2]); - $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]); - $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]); - $this->listCalls[] = array('listcontent_open',array(),$call[2]); + $this->listCalls[] = ['list' . $end[0] . '_close', [], $call[2]]; + $this->listCalls[] = ['list' . $listType . '_open', [], $call[2]]; + $this->listCalls[] = ['listitem_open', [$depth - 1], $call[2]]; + $this->listCalls[] = ['listcontent_open', [], $call[2]]; array_pop($this->listStack); - $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2); + $this->listStack[] = [$listType, $depth, count($this->listCalls) - 2]; } break; // Haven't dropped down far enough yet.... ( $end[1] > $depth ) } else { - $this->listCalls[] = array('listitem_close',array(),$call[2]); - $this->listCalls[] = array('list'.$end[0].'_close',array(),$call[2]); + $this->listCalls[] = ['listitem_close', [], $call[2]]; + $this->listCalls[] = ['list' . $end[0] . '_close', [], $call[2]]; array_pop($this->listStack); } @@ -172,7 +172,7 @@ class Lists extends AbstractRewriter $this->listCalls[] = $call; } - protected function interpretSyntax($match, & $type) + protected function interpretSyntax($match, &$type) { if (substr($match, -1) == '*') { $type = 'u'; diff --git a/inc/Parsing/Handler/Nest.php b/inc/Parsing/Handler/Nest.php index 98d213412..f4e58e408 100644 --- a/inc/Parsing/Handler/Nest.php +++ b/inc/Parsing/Handler/Nest.php @@ -41,7 +41,7 @@ class Nest extends AbstractRewriter public function finalise() { $last_call = end($this->calls); - $this->writeCall(array($this->closingInstruction,array(), $last_call[2])); + $this->writeCall([$this->closingInstruction, [], $last_call[2]]); $this->process(); $this->callWriter->finalise(); @@ -53,12 +53,12 @@ class Nest extends AbstractRewriter { // merge consecutive cdata $unmerged_calls = $this->calls; - $this->calls = array(); + $this->calls = []; foreach ($unmerged_calls as $call) $this->addCall($call); $first_call = reset($this->calls); - $this->callWriter->writeCall(array("nest", array($this->calls), $first_call[2])); + $this->callWriter->writeCall(["nest", [$this->calls], $first_call[2]]); return $this->callWriter; } @@ -69,14 +69,12 @@ class Nest extends AbstractRewriter protected function addCall($call) { $key = count($this->calls); - if ($key and ($call[0] == 'cdata') and ($this->calls[$key-1][0] == 'cdata')) { - $this->calls[$key-1][1][0] .= $call[1][0]; + if ($key && $call[0] == 'cdata' && $this->calls[$key - 1][0] == 'cdata') { + $this->calls[$key - 1][1][0] .= $call[1][0]; } elseif ($call[0] == 'eol') { // do nothing (eol shouldn't be allowed, to counter preformatted fix in #1652 & #1699) } else { $this->calls[] = $call; } } - - } diff --git a/inc/Parsing/Handler/Preformatted.php b/inc/Parsing/Handler/Preformatted.php index 41beb662d..bda7dfa24 100644 --- a/inc/Parsing/Handler/Preformatted.php +++ b/inc/Parsing/Handler/Preformatted.php @@ -4,15 +4,14 @@ namespace dokuwiki\Parsing\Handler; class Preformatted extends AbstractRewriter { - protected $pos; - protected $text =''; + protected $text = ''; /** @inheritdoc */ public function finalise() { $last_call = end($this->calls); - $this->writeCall(array('preformatted_end',array(), $last_call[2])); + $this->writeCall(['preformatted_end', [], $last_call[2]]); $this->process(); $this->callWriter->finalise(); @@ -35,11 +34,11 @@ class Preformatted extends AbstractRewriter break; case 'preformatted_end': if (trim($this->text)) { - $this->callWriter->writeCall(array('preformatted', array($this->text), $this->pos)); + $this->callWriter->writeCall(['preformatted', [$this->text], $this->pos]); } // see FS#1699 & FS#1652, add 'eol' instructions to ensure proper triggering of following p_open - $this->callWriter->writeCall(array('eol', array(), $this->pos)); - $this->callWriter->writeCall(array('eol', array(), $this->pos)); + $this->callWriter->writeCall(['eol', [], $this->pos]); + $this->callWriter->writeCall(['eol', [], $this->pos]); break; } } diff --git a/inc/Parsing/Handler/Quote.php b/inc/Parsing/Handler/Quote.php index 74861b1b2..caa04cc02 100644 --- a/inc/Parsing/Handler/Quote.php +++ b/inc/Parsing/Handler/Quote.php @@ -4,13 +4,13 @@ namespace dokuwiki\Parsing\Handler; class Quote extends AbstractRewriter { - protected $quoteCalls = array(); + protected $quoteCalls = []; /** @inheritdoc */ public function finalise() { $last_call = end($this->calls); - $this->writeCall(array('quote_end',array(), $last_call[2])); + $this->writeCall(['quote_end', [], $last_call[2]]); $this->process(); $this->callWriter->finalise(); @@ -28,7 +28,7 @@ class Quote extends AbstractRewriter /** @noinspection PhpMissingBreakStatementInspection */ case 'quote_start': - $this->quoteCalls[] = array('quote_open',array(),$call[2]); + $this->quoteCalls[] = ['quote_open', [], $call[2]]; // fallthrough case 'quote_newline': $quoteLength = $this->getDepth($call[1][0]); @@ -36,15 +36,15 @@ class Quote extends AbstractRewriter if ($quoteLength > $quoteDepth) { $quoteDiff = $quoteLength - $quoteDepth; for ($i = 1; $i <= $quoteDiff; $i++) { - $this->quoteCalls[] = array('quote_open',array(),$call[2]); + $this->quoteCalls[] = ['quote_open', [], $call[2]]; } } elseif ($quoteLength < $quoteDepth) { $quoteDiff = $quoteDepth - $quoteLength; for ($i = 1; $i <= $quoteDiff; $i++) { - $this->quoteCalls[] = array('quote_close',array(),$call[2]); + $this->quoteCalls[] = ['quote_close', [], $call[2]]; } - } else { - if ($call[0] != 'quote_start') $this->quoteCalls[] = array('linebreak',array(),$call[2]); + } elseif ($call[0] != 'quote_start') { + $this->quoteCalls[] = ['linebreak', [], $call[2]]; } $quoteDepth = $quoteLength; @@ -55,11 +55,11 @@ class Quote extends AbstractRewriter if ($quoteDepth > 1) { $quoteDiff = $quoteDepth - 1; for ($i = 1; $i <= $quoteDiff; $i++) { - $this->quoteCalls[] = array('quote_close',array(),$call[2]); + $this->quoteCalls[] = ['quote_close', [], $call[2]]; } } - $this->quoteCalls[] = array('quote_close',array(),$call[2]); + $this->quoteCalls[] = ['quote_close', [], $call[2]]; $this->callWriter->writeCalls($this->quoteCalls); break; diff --git a/inc/Parsing/Handler/Table.php b/inc/Parsing/Handler/Table.php index 35ff5a832..9305df539 100644 --- a/inc/Parsing/Handler/Table.php +++ b/inc/Parsing/Handler/Table.php @@ -4,22 +4,21 @@ namespace dokuwiki\Parsing\Handler; class Table extends AbstractRewriter { - - protected $tableCalls = array(); + protected $tableCalls = []; protected $maxCols = 0; protected $maxRows = 1; protected $currentCols = 0; protected $firstCell = false; protected $lastCellType = 'tablecell'; protected $inTableHead = true; - protected $currentRow = array('tableheader' => 0, 'tablecell' => 0); + protected $currentRow = ['tableheader' => 0, 'tablecell' => 0]; protected $countTableHeadRows = 0; /** @inheritdoc */ public function finalise() { $last_call = end($this->calls); - $this->writeCall(array('table_end',array(), $last_call[2])); + $this->writeCall(['table_end', [], $last_call[2]]); $this->process(); $this->callWriter->finalise(); @@ -36,7 +35,7 @@ class Table extends AbstractRewriter break; case 'table_row': $this->tableRowClose($call); - $this->tableRowOpen(array('tablerow_open',$call[1],$call[2])); + $this->tableRowOpen(['tablerow_open', $call[1], $call[2]]); break; case 'tableheader': case 'tablecell': @@ -58,14 +57,14 @@ class Table extends AbstractRewriter protected function tableStart($call) { - $this->tableCalls[] = array('table_open',$call[1],$call[2]); - $this->tableCalls[] = array('tablerow_open',array(),$call[2]); + $this->tableCalls[] = ['table_open', $call[1], $call[2]]; + $this->tableCalls[] = ['tablerow_open', [], $call[2]]; $this->firstCell = true; } protected function tableEnd($call) { - $this->tableCalls[] = array('table_close',$call[1],$call[2]); + $this->tableCalls[] = ['table_close', $call[1], $call[2]]; $this->finalizeTable(); } @@ -77,7 +76,7 @@ class Table extends AbstractRewriter $this->lastCellType = 'tablecell'; $this->maxRows++; if ($this->inTableHead) { - $this->currentRow = array('tablecell' => 0, 'tableheader' => 0); + $this->currentRow = ['tablecell' => 0, 'tableheader' => 0]; } } @@ -95,7 +94,7 @@ class Table extends AbstractRewriter $this->currentRow[$discard[0]]--; } } - $this->tableCalls[] = array('tablerow_close', array(), $call[2]); + $this->tableCalls[] = ['tablerow_close', [], $call[2]]; if ($this->currentCols > $this->maxCols) { $this->maxCols = $this->currentCols; @@ -108,7 +107,7 @@ class Table extends AbstractRewriter $th = $this->currentRow['tableheader']; if (!$th || $td > 2) return false; - if (2*$td > $th) return false; + if (2 * $td > $th) return false; return true; } @@ -124,14 +123,14 @@ class Table extends AbstractRewriter // A cell call which follows an open cell means an empty cell so span if ($lastCall[0] == 'tablecell_open' || $lastCall[0] == 'tableheader_open') { - $this->tableCalls[] = array('colspan',array(),$call[2]); + $this->tableCalls[] = ['colspan', [], $call[2]]; } - $this->tableCalls[] = array($this->lastCellType.'_close',array(),$call[2]); - $this->tableCalls[] = array($call[0].'_open',array(1,null,1),$call[2]); + $this->tableCalls[] = [$this->lastCellType . '_close', [], $call[2]]; + $this->tableCalls[] = [$call[0] . '_open', [1, null, 1], $call[2]]; $this->lastCellType = $call[0]; } else { - $this->tableCalls[] = array($call[0].'_open',array(1,null,1),$call[2]); + $this->tableCalls[] = [$call[0] . '_open', [1, null, 1], $call[2]]; $this->lastCellType = $call[0]; $this->firstCell = false; } @@ -159,8 +158,8 @@ class Table extends AbstractRewriter $lastRow = 0; $lastCell = 0; - $cellKey = array(); - $toDelete = array(); + $cellKey = []; + $toDelete = []; // if still in tableheader, then there can be no table header // as all rows can't be within <THEAD> @@ -168,18 +167,21 @@ class Table extends AbstractRewriter $this->inTableHead = false; $this->countTableHeadRows = 0; } + // Look for the colspan elements and increment the colspan on the + // previous non-empty opening cell. Once done, delete all the cells + // that contain colspans + $counter = count($this->tableCalls); // Look for the colspan elements and increment the colspan on the // previous non-empty opening cell. Once done, delete all the cells // that contain colspans - for ($key = 0; $key < count($this->tableCalls); ++$key) { + for ($key = 0; $key < $counter; ++$key) { $call = $this->tableCalls[$key]; switch ($call[0]) { case 'table_open': if ($this->countTableHeadRows) { - array_splice($this->tableCalls, $key+1, 0, array( - array('tablethead_open', array(), $call[2]))); + array_splice($this->tableCalls, $key + 1, 0, [['tablethead_open', [], $call[2]]]); } break; @@ -195,15 +197,15 @@ class Table extends AbstractRewriter break; case 'table_align': - $prev = in_array($this->tableCalls[$key-1][0], array('tablecell_open', 'tableheader_open')); - $next = in_array($this->tableCalls[$key+1][0], array('tablecell_close', 'tableheader_close')); + $prev = in_array($this->tableCalls[$key - 1][0], ['tablecell_open', 'tableheader_open']); + $next = in_array($this->tableCalls[$key + 1][0], ['tablecell_close', 'tableheader_close']); // If the cell is empty, align left if ($prev && $next) { - $this->tableCalls[$key-1][1][1] = 'left'; + $this->tableCalls[$key - 1][1][1] = 'left'; // If the previous element was a cell open, align right } elseif ($prev) { - $this->tableCalls[$key-1][1][1] = 'right'; + $this->tableCalls[$key - 1][1][1] = 'right'; // If the next element is the close of an element, align either center or left } elseif ($next) { @@ -219,10 +221,11 @@ class Table extends AbstractRewriter break; case 'colspan': - $this->tableCalls[$key-1][1][0] = false; + $this->tableCalls[$key - 1][1][0] = false; - for ($i = $key-2; $i >= $cellKey[$lastRow][1]; $i--) { - if ($this->tableCalls[$i][0] == 'tablecell_open' || + for ($i = $key - 2; $i >= $cellKey[$lastRow][1]; $i--) { + if ( + $this->tableCalls[$i][0] == 'tablecell_open' || $this->tableCalls[$i][0] == 'tableheader_open' ) { if (false !== $this->tableCalls[$i][1][0]) { @@ -232,13 +235,13 @@ class Table extends AbstractRewriter } } - $toDelete[] = $key-1; + $toDelete[] = $key - 1; $toDelete[] = $key; - $toDelete[] = $key+1; + $toDelete[] = $key + 1; break; case 'rowspan': - if ($this->tableCalls[$key-1][0] == 'cdata') { + if ($this->tableCalls[$key - 1][0] == 'cdata') { // ignore rowspan if previous call was cdata (text mixed with :::) // we don't have to check next call as that wont match regex $this->tableCalls[$key][0] = 'cdata'; @@ -246,9 +249,10 @@ class Table extends AbstractRewriter $spanning_cell = null; // can't cross thead/tbody boundary - if (!$this->countTableHeadRows || ($lastRow-1 != $this->countTableHeadRows)) { - for ($i = $lastRow-1; $i > 0; $i--) { - if ($this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tablecell_open' || + if (!$this->countTableHeadRows || ($lastRow - 1 != $this->countTableHeadRows)) { + for ($i = $lastRow - 1; $i > 0; $i--) { + if ( + $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tablecell_open' || $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tableheader_open' ) { if ($this->tableCalls[$cellKey[$i][$lastCell]][1][2] >= $lastRow - $i) { @@ -267,21 +271,21 @@ class Table extends AbstractRewriter } $this->tableCalls[$cellKey[$spanning_cell][$lastCell]][1][2]++; - $this->tableCalls[$key-1][1][2] = false; + $this->tableCalls[$key - 1][1][2] = false; - $toDelete[] = $key-1; + $toDelete[] = $key - 1; $toDelete[] = $key; - $toDelete[] = $key+1; + $toDelete[] = $key + 1; } break; case 'tablerow_close': // Fix broken tables by adding missing cells - $moreCalls = array(); + $moreCalls = []; while (++$lastCell < $this->maxCols) { - $moreCalls[] = array('tablecell_open', array(1, null, 1), $call[2]); - $moreCalls[] = array('cdata', array(''), $call[2]); - $moreCalls[] = array('tablecell_close', array(), $call[2]); + $moreCalls[] = ['tablecell_open', [1, null, 1], $call[2]]; + $moreCalls[] = ['cdata', [''], $call[2]]; + $moreCalls[] = ['tablecell_close', [], $call[2]]; } $moreCallsLength = count($moreCalls); if ($moreCallsLength) { @@ -290,8 +294,7 @@ class Table extends AbstractRewriter } if ($this->countTableHeadRows == $lastRow) { - array_splice($this->tableCalls, $key+1, 0, array( - array('tablethead_close', array(), $call[2]))); + array_splice($this->tableCalls, $key + 1, 0, [['tablethead_close', [], $call[2]]]); } break; } diff --git a/inc/Parsing/Lexer/Lexer.php b/inc/Parsing/Lexer/Lexer.php index 20040938e..168127138 100644 --- a/inc/Parsing/Lexer/Lexer.php +++ b/inc/Parsing/Lexer/Lexer.php @@ -1,4 +1,5 @@ <?php + /** * Lexer adapted from Simple Test: http://sourceforge.net/projects/simpletest/ * For an intro to the Lexer see: @@ -18,13 +19,13 @@ namespace dokuwiki\Parsing\Lexer; class Lexer { /** @var ParallelRegex[] */ - protected $regexes; + protected $regexes = []; /** @var \Doku_Handler */ protected $handler; /** @var StateStack */ protected $modeStack; /** @var array mode "rewrites" */ - protected $mode_handlers; + protected $mode_handlers = []; /** @var bool case sensitive? */ protected $case; @@ -38,10 +39,8 @@ class Lexer public function __construct($handler, $start = "accept", $case = false) { $this->case = $case; - $this->regexes = array(); $this->handler = $handler; $this->modeStack = new StateStack($start); - $this->mode_handlers = array(); } /** @@ -141,13 +140,13 @@ class Lexer $length = $initialLength; $pos = 0; while (is_array($parsed = $this->reduce($raw))) { - list($unmatched, $matched, $mode) = $parsed; + [$unmatched, $matched, $mode] = $parsed; $currentLength = strlen($raw); $matchPos = $initialLength - $currentLength - strlen($matched); if (! $this->dispatchTokens($unmatched, $matched, $mode, $pos, $matchPos)) { return false; } - if ($currentLength == $length) { + if ($currentLength === $length) { return false; } $length = $currentLength; @@ -265,8 +264,8 @@ class Lexer // modes starting with plugin_ are all handled by the same // handler but with an additional parameter - if (substr($handler, 0, 7)=='plugin_') { - list($handler,$plugin) = sexplode('_', $handler, 2, ''); + if (substr($handler, 0, 7) == 'plugin_') { + [$handler, $plugin] = sexplode('_', $handler, 2, ''); return $this->handler->$handler($content, $is_match, $pos, $plugin); } @@ -291,8 +290,8 @@ class Lexer return true; } if ($action = $this->regexes[$this->modeStack->getCurrent()]->split($raw, $split)) { - list($unparsed, $match, $raw) = $split; - return array($unparsed, $match, $action); + [$unparsed, $match, $raw] = $split; + return [$unparsed, $match, $action]; } return true; } @@ -305,7 +304,7 @@ class Lexer */ public static function escape($str) { - $chars = array( + $chars = [ '/\\\\/', '/\./', '/\+/', @@ -323,9 +322,9 @@ class Lexer '/\>/', '/\|/', '/\:/' - ); + ]; - $escaped = array( + $escaped = [ '\\\\\\\\', '\.', '\+', @@ -343,7 +342,8 @@ class Lexer '\>', '\|', '\:' - ); + ]; + return preg_replace($chars, $escaped, $str); } } diff --git a/inc/Parsing/Lexer/ParallelRegex.php b/inc/Parsing/Lexer/ParallelRegex.php index bf1979950..d23fb332b 100644 --- a/inc/Parsing/Lexer/ParallelRegex.php +++ b/inc/Parsing/Lexer/ParallelRegex.php @@ -1,4 +1,5 @@ <?php + /** * Lexer adapted from Simple Test: http://sourceforge.net/projects/simpletest/ * For an intro to the Lexer see: @@ -17,9 +18,9 @@ namespace dokuwiki\Parsing\Lexer; class ParallelRegex { /** @var string[] patterns to match */ - protected $patterns; + protected $patterns = []; /** @var string[] labels for above patterns */ - protected $labels; + protected $labels = []; /** @var string the compound regex matching all patterns */ protected $regex; /** @var bool case sensitive matching? */ @@ -34,9 +35,6 @@ class ParallelRegex public function __construct($case) { $this->case = $case; - $this->patterns = array(); - $this->labels = array(); - $this->regex = null; } /** @@ -121,15 +119,15 @@ class ParallelRegex } } - $split = array($subject, "", ""); + $split = [$subject, "", ""]; return false; } - $idx = count($matches)-2; - list($pre, $post) = preg_split($this->patterns[$idx].$this->getPerlMatchingFlags(), $subject, 2); - $split = array($pre, $matches[0], $post); + $idx = count($matches) - 2; + [$pre, $post] = preg_split($this->patterns[$idx] . $this->getPerlMatchingFlags(), $subject, 2); + $split = [$pre, $matches[0], $post]; - return isset($this->labels[$idx]) ? $this->labels[$idx] : true; + return $this->labels[$idx] ?? true; } /** diff --git a/inc/Parsing/Lexer/StateStack.php b/inc/Parsing/Lexer/StateStack.php index 325412bb4..a2d72e487 100644 --- a/inc/Parsing/Lexer/StateStack.php +++ b/inc/Parsing/Lexer/StateStack.php @@ -1,4 +1,5 @@ <?php + /** * Lexer adapted from Simple Test: http://sourceforge.net/projects/simpletest/ * For an intro to the Lexer see: @@ -22,7 +23,7 @@ class StateStack */ public function __construct($start) { - $this->stack = array($start); + $this->stack = [$start]; } /** @@ -41,7 +42,7 @@ class StateStack */ public function enter($state) { - array_push($this->stack, $state); + $this->stack[] = $state; } /** diff --git a/inc/Parsing/Parser.php b/inc/Parsing/Parser.php index 63f014161..018f45eaa 100644 --- a/inc/Parsing/Parser.php +++ b/inc/Parsing/Parser.php @@ -2,6 +2,7 @@ namespace dokuwiki\Parsing; +use dokuwiki\Debug\DebugHelper; use Doku_Handler; use dokuwiki\Parsing\Lexer\Lexer; use dokuwiki\Parsing\ParserMode\Base; @@ -11,8 +12,8 @@ use dokuwiki\Parsing\ParserMode\ModeInterface; * Sets up the Lexer with modes and points it to the Handler * For an intro to the Lexer see: wiki:parser */ -class Parser { - +class Parser +{ /** @var Doku_Handler */ protected $handler; @@ -20,7 +21,7 @@ class Parser { protected $lexer; /** @var ModeInterface[] $modes */ - protected $modes = array(); + protected $modes = []; /** @var bool mode connections may only be set up once */ protected $connected = false; @@ -30,7 +31,8 @@ class Parser { * * @param Doku_Handler $handler */ - public function __construct(Doku_Handler $handler) { + public function __construct(Doku_Handler $handler) + { $this->handler = $handler; } @@ -39,9 +41,10 @@ class Parser { * * @param Base $BaseMode */ - protected function addBaseMode($BaseMode) { + protected function addBaseMode($BaseMode) + { $this->modes['base'] = $BaseMode; - if(!$this->lexer) { + if (!$this->lexer) { $this->lexer = new Lexer($this->handler, 'base', true); } $this->modes['base']->Lexer = $this->lexer; @@ -56,8 +59,9 @@ class Parser { * @param string $name * @param ModeInterface $Mode */ - public function addMode($name, ModeInterface $Mode) { - if(!isset($this->modes['base'])) { + public function addMode($name, ModeInterface $Mode) + { + if (!isset($this->modes['base'])) { $this->addBaseMode(new Base()); } $Mode->Lexer = $this->lexer; // FIXME should be done by setter @@ -69,25 +73,24 @@ class Parser { * * This is the last step before actually parsing. */ - protected function connectModes() { + protected function connectModes() + { - if($this->connected) { + if ($this->connected) { return; } - foreach(array_keys($this->modes) as $mode) { + foreach (array_keys($this->modes) as $mode) { // Base isn't connected to anything - if($mode == 'base') { + if ($mode == 'base') { continue; } $this->modes[$mode]->preConnect(); - foreach(array_keys($this->modes) as $cm) { - - if($this->modes[$cm]->accepts($mode)) { + foreach (array_keys($this->modes) as $cm) { + if ($this->modes[$cm]->accepts($mode)) { $this->modes[$mode]->connectTo($cm); } - } $this->modes[$mode]->postConnect(); @@ -102,7 +105,8 @@ class Parser { * @param string $doc the wiki syntax text * @return array instructions */ - public function parse($doc) { + public function parse($doc) + { $this->connectModes(); // Normalize CRs and pad doc $doc = "\n" . str_replace("\r\n", "\n", $doc) . "\n"; @@ -111,7 +115,7 @@ class Parser { if (!method_exists($this->handler, 'finalize')) { /** @deprecated 2019-10 we have a legacy handler from a plugin, assume legacy _finalize exists */ - \dokuwiki\Debug\DebugHelper::dbgCustomDeprecationEvent( + DebugHelper::dbgCustomDeprecationEvent( 'finalize()', get_class($this->handler) . '::_finalize()', __METHOD__, @@ -124,5 +128,4 @@ class Parser { } return $this->handler->calls; } - } diff --git a/inc/Parsing/ParserMode/AbstractMode.php b/inc/Parsing/ParserMode/AbstractMode.php index 15fc9fe04..44dfe0103 100644 --- a/inc/Parsing/ParserMode/AbstractMode.php +++ b/inc/Parsing/ParserMode/AbstractMode.php @@ -2,6 +2,8 @@ namespace dokuwiki\Parsing\ParserMode; +use dokuwiki\Parsing\Lexer\Lexer; + /** * This class and all the subclasses below are used to reduce the effort required to register * modes with the Lexer. @@ -10,9 +12,9 @@ namespace dokuwiki\Parsing\ParserMode; */ abstract class AbstractMode implements ModeInterface { - /** @var \dokuwiki\Parsing\Lexer\Lexer $Lexer will be injected on loading FIXME this should be done by setter */ + /** @var Lexer $Lexer will be injected on loading FIXME this should be done by setter */ public $Lexer; - protected $allowedModes = array(); + protected $allowedModes = []; /** @inheritdoc */ abstract public function getSort(); diff --git a/inc/Parsing/ParserMode/Acronym.php b/inc/Parsing/ParserMode/Acronym.php index b42a7b573..b80df488c 100644 --- a/inc/Parsing/ParserMode/Acronym.php +++ b/inc/Parsing/ParserMode/Acronym.php @@ -5,7 +5,7 @@ namespace dokuwiki\Parsing\ParserMode; class Acronym extends AbstractMode { // A list - protected $acronyms = array(); + protected $acronyms = []; protected $pattern = ''; /** @@ -15,7 +15,7 @@ class Acronym extends AbstractMode */ public function __construct($acronyms) { - usort($acronyms, array($this,'compare')); + usort($acronyms, [$this, 'compare']); $this->acronyms = $acronyms; } @@ -26,7 +26,7 @@ class Acronym extends AbstractMode $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]'; $acronyms = array_map(['\\dokuwiki\\Parsing\\Lexer\\Lexer', 'escape'], $this->acronyms); - $this->pattern = '(?<=^|'.$bound.')(?:'.join('|', $acronyms).')(?='.$bound.')'; + $this->pattern = '(?<=^|' . $bound . ')(?:' . implode('|', $acronyms) . ')(?=' . $bound . ')'; } /** @inheritdoc */ diff --git a/inc/Parsing/ParserMode/Base.php b/inc/Parsing/ParserMode/Base.php index 562275600..85049cefd 100644 --- a/inc/Parsing/ParserMode/Base.php +++ b/inc/Parsing/ParserMode/Base.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Base extends AbstractMode { - /** * Base constructor. */ diff --git a/inc/Parsing/ParserMode/Camelcaselink.php b/inc/Parsing/ParserMode/Camelcaselink.php index ef0b32531..31fd81230 100644 --- a/inc/Parsing/ParserMode/Camelcaselink.php +++ b/inc/Parsing/ParserMode/Camelcaselink.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Camelcaselink extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Code.php b/inc/Parsing/ParserMode/Code.php index aa494377d..6efba0cb7 100644 --- a/inc/Parsing/ParserMode/Code.php +++ b/inc/Parsing/ParserMode/Code.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Code extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Emaillink.php b/inc/Parsing/ParserMode/Emaillink.php index f9af28c66..c4b7e355a 100644 --- a/inc/Parsing/ParserMode/Emaillink.php +++ b/inc/Parsing/ParserMode/Emaillink.php @@ -4,12 +4,11 @@ namespace dokuwiki\Parsing\ParserMode; class Emaillink extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { // pattern below is defined in inc/mail.php - $this->Lexer->addSpecialPattern('<'.PREG_PATTERN_VALID_EMAIL.'>', $mode, 'emaillink'); + $this->Lexer->addSpecialPattern('<' . PREG_PATTERN_VALID_EMAIL . '>', $mode, 'emaillink'); } /** @inheritdoc */ diff --git a/inc/Parsing/ParserMode/Entity.php b/inc/Parsing/ParserMode/Entity.php index b670124b2..043511144 100644 --- a/inc/Parsing/ParserMode/Entity.php +++ b/inc/Parsing/ParserMode/Entity.php @@ -6,8 +6,7 @@ use dokuwiki\Parsing\Lexer\Lexer; class Entity extends AbstractMode { - - protected $entities = array(); + protected $entities = []; protected $pattern = ''; /** @@ -27,7 +26,7 @@ class Entity extends AbstractMode $sep = ''; foreach ($this->entities as $entity) { - $this->pattern .= $sep. Lexer::escape($entity); + $this->pattern .= $sep . Lexer::escape($entity); $sep = '|'; } } diff --git a/inc/Parsing/ParserMode/Eol.php b/inc/Parsing/ParserMode/Eol.php index a5886b51f..61900653f 100644 --- a/inc/Parsing/ParserMode/Eol.php +++ b/inc/Parsing/ParserMode/Eol.php @@ -4,11 +4,10 @@ namespace dokuwiki\Parsing\ParserMode; class Eol extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { - $badModes = array('listblock','table'); + $badModes = ['listblock', 'table']; if (in_array($mode, $badModes)) { return; } diff --git a/inc/Parsing/ParserMode/Externallink.php b/inc/Parsing/ParserMode/Externallink.php index 530d5dbba..354254b64 100644 --- a/inc/Parsing/ParserMode/Externallink.php +++ b/inc/Parsing/ParserMode/Externallink.php @@ -4,8 +4,8 @@ namespace dokuwiki\Parsing\ParserMode; class Externallink extends AbstractMode { - protected $schemes = array(); - protected $patterns = array(); + protected $schemes = []; + protected $patterns = []; /** @inheritdoc */ public function preConnect() @@ -15,18 +15,18 @@ class Externallink extends AbstractMode $ltrs = '\w'; $gunk = '/\#~:.?+=&%@!\-\[\]'; $punc = '.:?\-;,'; - $host = $ltrs.$punc; - $any = $ltrs.$gunk.$punc; + $host = $ltrs . $punc; + $any = $ltrs . $gunk . $punc; $this->schemes = getSchemes(); foreach ($this->schemes as $scheme) { - $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; + $this->patterns[] = '\b(?i)' . $scheme . '(?-i)://[' . $any . ']+?(?=[' . $punc . ']*[^' . $any . '])'; } - $this->patterns[] = '(?<![/\\\\])\b(?i)www?(?-i)\.['.$host.']+?\.'. - '['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; - $this->patterns[] = '(?<![/\\\\])\b(?i)ftp?(?-i)\.['.$host.']+?\.'. - '['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; + $this->patterns[] = '(?<![/\\\\])\b(?i)www?(?-i)\.[' . $host . ']+?\.' . + '[' . $host . ']+?[' . $any . ']+?(?=[' . $punc . ']*[^' . $any . '])'; + $this->patterns[] = '(?<![/\\\\])\b(?i)ftp?(?-i)\.[' . $host . ']+?\.' . + '[' . $host . ']+?[' . $any . ']+?(?=[' . $punc . ']*[^' . $any . '])'; } /** @inheritdoc */ diff --git a/inc/Parsing/ParserMode/File.php b/inc/Parsing/ParserMode/File.php index 149134135..a49b1c135 100644 --- a/inc/Parsing/ParserMode/File.php +++ b/inc/Parsing/ParserMode/File.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class File extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Filelink.php b/inc/Parsing/ParserMode/Filelink.php index 3cd86cb8b..3e57af32f 100644 --- a/inc/Parsing/ParserMode/Filelink.php +++ b/inc/Parsing/ParserMode/Filelink.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Filelink extends AbstractMode { - protected $pattern; /** @inheritdoc */ @@ -14,11 +13,10 @@ class Filelink extends AbstractMode $ltrs = '\w'; $gunk = '/\#~:.?+=&%@!\-'; $punc = '.:?\-;,'; - $host = $ltrs.$punc; - $any = $ltrs.$gunk.$punc; + $any = $ltrs . $gunk . $punc; - $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['. - $punc.']*[^'.$any.']'; + $this->pattern = '\b(?i)file(?-i)://[' . $any . ']+?[' . + $punc . ']*[^' . $any . ']'; } /** @inheritdoc */ diff --git a/inc/Parsing/ParserMode/Footnote.php b/inc/Parsing/ParserMode/Footnote.php index c399f9849..5bd282740 100644 --- a/inc/Parsing/ParserMode/Footnote.php +++ b/inc/Parsing/ParserMode/Footnote.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Footnote extends AbstractMode { - /** * Footnote constructor. */ diff --git a/inc/Parsing/ParserMode/Formatting.php b/inc/Parsing/ParserMode/Formatting.php index a3c465cc0..7949698b1 100644 --- a/inc/Parsing/ParserMode/Formatting.php +++ b/inc/Parsing/ParserMode/Formatting.php @@ -10,49 +10,44 @@ class Formatting extends AbstractMode { protected $type; - protected $formatting = array( - 'strong' => array( + protected $formatting = [ + 'strong' => [ 'entry' => '\*\*(?=.*\*\*)', 'exit' => '\*\*', 'sort' => 70 - ), - - 'emphasis' => array( - 'entry' => '//(?=[^\x00]*[^:])', //hack for bugs #384 #763 #1468 + ], + 'emphasis' => [ + 'entry' => '//(?=[^\x00]*[^:])', + //hack for bugs #384 #763 #1468 'exit' => '//', - 'sort' => 80 - ), - - 'underline' => array( + 'sort' => 80, + ], + 'underline' => [ 'entry' => '__(?=.*__)', 'exit' => '__', 'sort' => 90 - ), - - 'monospace' => array( + ], + 'monospace' => [ 'entry' => '\x27\x27(?=.*\x27\x27)', 'exit' => '\x27\x27', 'sort' => 100 - ), - - 'subscript' => array( + ], + 'subscript' => [ 'entry' => '<sub>(?=.*</sub>)', 'exit' => '</sub>', 'sort' => 110 - ), - - 'superscript' => array( + ], + 'superscript' => [ 'entry' => '<sup>(?=.*</sup>)', 'exit' => '</sup>', 'sort' => 120 - ), - - 'deleted' => array( + ], + 'deleted' => [ 'entry' => '<del>(?=.*</del>)', 'exit' => '</del>', 'sort' => 130 - ), - ); + ] + ]; /** * @param string $type diff --git a/inc/Parsing/ParserMode/Header.php b/inc/Parsing/ParserMode/Header.php index 854b3178c..8dc8937ec 100644 --- a/inc/Parsing/ParserMode/Header.php +++ b/inc/Parsing/ParserMode/Header.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Header extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Hr.php b/inc/Parsing/ParserMode/Hr.php index e4f0b444b..a64137b18 100644 --- a/inc/Parsing/ParserMode/Hr.php +++ b/inc/Parsing/ParserMode/Hr.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Hr extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Internallink.php b/inc/Parsing/ParserMode/Internallink.php index 6def0d9a3..c3ed4589f 100644 --- a/inc/Parsing/ParserMode/Internallink.php +++ b/inc/Parsing/ParserMode/Internallink.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Internallink extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Linebreak.php b/inc/Parsing/ParserMode/Linebreak.php index dd95cc383..9b5246768 100644 --- a/inc/Parsing/ParserMode/Linebreak.php +++ b/inc/Parsing/ParserMode/Linebreak.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Linebreak extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Listblock.php b/inc/Parsing/ParserMode/Listblock.php index eef762777..a9adbe6b6 100644 --- a/inc/Parsing/ParserMode/Listblock.php +++ b/inc/Parsing/ParserMode/Listblock.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Listblock extends AbstractMode { - /** * Listblock constructor. */ diff --git a/inc/Parsing/ParserMode/Media.php b/inc/Parsing/ParserMode/Media.php index f93f94773..ec6b32217 100644 --- a/inc/Parsing/ParserMode/Media.php +++ b/inc/Parsing/ParserMode/Media.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Media extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Multiplyentity.php b/inc/Parsing/ParserMode/Multiplyentity.php index 89df136df..8ae21134a 100644 --- a/inc/Parsing/ParserMode/Multiplyentity.php +++ b/inc/Parsing/ParserMode/Multiplyentity.php @@ -7,7 +7,6 @@ namespace dokuwiki\Parsing\ParserMode; */ class Multiplyentity extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Nocache.php b/inc/Parsing/ParserMode/Nocache.php index fa6db8305..93ffb3957 100644 --- a/inc/Parsing/ParserMode/Nocache.php +++ b/inc/Parsing/ParserMode/Nocache.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Nocache extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Notoc.php b/inc/Parsing/ParserMode/Notoc.php index 5956207c1..5747050c0 100644 --- a/inc/Parsing/ParserMode/Notoc.php +++ b/inc/Parsing/ParserMode/Notoc.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Notoc extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Plugin.php b/inc/Parsing/ParserMode/Plugin.php index c885c6037..581a854d1 100644 --- a/inc/Parsing/ParserMode/Plugin.php +++ b/inc/Parsing/ParserMode/Plugin.php @@ -5,4 +5,6 @@ namespace dokuwiki\Parsing\ParserMode; /** * @fixme do we need this anymore or could the syntax plugin inherit directly from abstract mode? */ -abstract class Plugin extends AbstractMode {} +abstract class Plugin extends AbstractMode +{ +} diff --git a/inc/Parsing/ParserMode/Preformatted.php b/inc/Parsing/ParserMode/Preformatted.php index 7dfc47489..e7228367a 100644 --- a/inc/Parsing/ParserMode/Preformatted.php +++ b/inc/Parsing/ParserMode/Preformatted.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Preformatted extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Quote.php b/inc/Parsing/ParserMode/Quote.php index 65525b241..c6c2d2807 100644 --- a/inc/Parsing/ParserMode/Quote.php +++ b/inc/Parsing/ParserMode/Quote.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Quote extends AbstractMode { - /** * Quote constructor. */ diff --git a/inc/Parsing/ParserMode/Quotes.php b/inc/Parsing/ParserMode/Quotes.php index 13db2e679..f83964ab0 100644 --- a/inc/Parsing/ParserMode/Quotes.php +++ b/inc/Parsing/ParserMode/Quotes.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Quotes extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Rss.php b/inc/Parsing/ParserMode/Rss.php index a62d9b807..757a5b16f 100644 --- a/inc/Parsing/ParserMode/Rss.php +++ b/inc/Parsing/ParserMode/Rss.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Rss extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Smiley.php b/inc/Parsing/ParserMode/Smiley.php index 084ccc9ed..8523c9f8c 100644 --- a/inc/Parsing/ParserMode/Smiley.php +++ b/inc/Parsing/ParserMode/Smiley.php @@ -6,7 +6,7 @@ use dokuwiki\Parsing\Lexer\Lexer; class Smiley extends AbstractMode { - protected $smileys = array(); + protected $smileys = []; protected $pattern = ''; /** @@ -25,7 +25,7 @@ class Smiley extends AbstractMode $sep = ''; foreach ($this->smileys as $smiley) { - $this->pattern .= $sep.'(?<=\W|^)'. Lexer::escape($smiley).'(?=\W|$)'; + $this->pattern .= $sep . '(?<=\W|^)' . Lexer::escape($smiley) . '(?=\W|$)'; $sep = '|'; } } diff --git a/inc/Parsing/ParserMode/Table.php b/inc/Parsing/ParserMode/Table.php index b4b512380..4fb558560 100644 --- a/inc/Parsing/ParserMode/Table.php +++ b/inc/Parsing/ParserMode/Table.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Table extends AbstractMode { - /** * Table constructor. */ diff --git a/inc/Parsing/ParserMode/Unformatted.php b/inc/Parsing/ParserMode/Unformatted.php index 1bc2826e6..58f1435e1 100644 --- a/inc/Parsing/ParserMode/Unformatted.php +++ b/inc/Parsing/ParserMode/Unformatted.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Unformatted extends AbstractMode { - /** @inheritdoc */ public function connectTo($mode) { diff --git a/inc/Parsing/ParserMode/Windowssharelink.php b/inc/Parsing/ParserMode/Windowssharelink.php index 747d4d8a9..a6517d63f 100644 --- a/inc/Parsing/ParserMode/Windowssharelink.php +++ b/inc/Parsing/ParserMode/Windowssharelink.php @@ -4,7 +4,6 @@ namespace dokuwiki\Parsing\ParserMode; class Windowssharelink extends AbstractMode { - protected $pattern; /** @inheritdoc */ diff --git a/inc/Parsing/ParserMode/Wordblock.php b/inc/Parsing/ParserMode/Wordblock.php index 50b24b2db..64d377fe0 100644 --- a/inc/Parsing/ParserMode/Wordblock.php +++ b/inc/Parsing/ParserMode/Wordblock.php @@ -9,7 +9,7 @@ use dokuwiki\Parsing\Lexer\Lexer; */ class Wordblock extends AbstractMode { - protected $badwords = array(); + protected $badwords = []; protected $pattern = ''; /** @@ -31,7 +31,7 @@ class Wordblock extends AbstractMode $sep = ''; foreach ($this->badwords as $badword) { - $this->pattern .= $sep.'(?<=\b)(?i)'. Lexer::escape($badword).'(?-i)(?=\b)'; + $this->pattern .= $sep . '(?<=\b)(?i)' . Lexer::escape($badword) . '(?-i)(?=\b)'; $sep = '|'; } } diff --git a/inc/PassHash.php b/inc/PassHash.php index 9dfdd72cd..943d64e75 100644 --- a/inc/PassHash.php +++ b/inc/PassHash.php @@ -1,4 +1,5 @@ <?php + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps namespace dokuwiki; @@ -12,7 +13,8 @@ namespace dokuwiki; * @author Schplurtz le Déboulonné <Schplurtz@laposte.net> * @license LGPL2 */ -class PassHash { +class PassHash +{ /** * Verifies a cleartext password against a crypted hash * @@ -27,7 +29,8 @@ class PassHash { * @param string $hash Hash to compare against * @return bool */ - public function verify_hash($clear, $hash) { + public function verify_hash($clear, $hash) + { $method = ''; $salt = ''; $magic = ''; @@ -40,79 +43,70 @@ class PassHash { $clear = md5($clear); } $len = strlen($hash); - if(preg_match('/^\$1\$([^\$]{0,8})\$/', $hash, $m)) { + if (preg_match('/^\$1\$([^\$]{0,8})\$/', $hash, $m)) { $method = 'smd5'; $salt = $m[1]; $magic = '1'; - } elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/', $hash, $m)) { + } elseif (preg_match('/^\$apr1\$([^\$]{0,8})\$/', $hash, $m)) { $method = 'apr1'; $salt = $m[1]; $magic = 'apr1'; - } elseif(preg_match('/^\$S\$(.{52})$/', $hash, $m)) { + } elseif (preg_match('/^\$S\$(.{52})$/', $hash, $m)) { $method = 'drupal_sha512'; $salt = $m[1]; $magic = 'S'; - } elseif(preg_match('/^\$P\$(.{31})$/', $hash, $m)) { + } elseif (preg_match('/^\$P\$(.{31})$/', $hash, $m)) { $method = 'pmd5'; $salt = $m[1]; $magic = 'P'; - } elseif(preg_match('/^\$H\$(.{31})$/', $hash, $m)) { + } elseif (preg_match('/^\$H\$(.{31})$/', $hash, $m)) { $method = 'pmd5'; $salt = $m[1]; $magic = 'H'; - } elseif(preg_match('/^pbkdf2_(\w+?)\$(\d+)\$(.{12})\$/', $hash, $m)) { + } elseif (preg_match('/^pbkdf2_(\w+?)\$(\d+)\$(.{12})\$/', $hash, $m)) { $method = 'djangopbkdf2'; - $magic = array( - 'algo' => $m[1], - 'iter' => $m[2], - ); + $magic = ['algo' => $m[1], 'iter' => $m[2]]; $salt = $m[3]; - } elseif(preg_match('/^PBKDF2(SHA\d+)\$(\d+)\$([[:xdigit:]]+)\$([[:xdigit:]]+)$/', $hash, $m)) { + } elseif (preg_match('/^PBKDF2(SHA\d+)\$(\d+)\$([[:xdigit:]]+)\$([[:xdigit:]]+)$/', $hash, $m)) { $method = 'seafilepbkdf2'; - $magic = array( - 'algo' => $m[1], - 'iter' => $m[2], - ); + $magic = ['algo' => $m[1], 'iter' => $m[2]]; $salt = $m[3]; - } elseif(preg_match('/^sha1\$(.{5})\$/', $hash, $m)) { + } elseif (preg_match('/^sha1\$(.{5})\$/', $hash, $m)) { $method = 'djangosha1'; $salt = $m[1]; - } elseif(preg_match('/^md5\$(.{5})\$/', $hash, $m)) { + } elseif (preg_match('/^md5\$(.{5})\$/', $hash, $m)) { $method = 'djangomd5'; $salt = $m[1]; - } elseif(preg_match('/^\$2(a|y)\$(.{2})\$/', $hash, $m)) { + } elseif (preg_match('/^\$2(a|y)\$(.{2})\$/', $hash, $m)) { $method = 'bcrypt'; $salt = $hash; - } elseif(substr($hash, 0, 6) == '{SSHA}') { + } elseif (substr($hash, 0, 6) == '{SSHA}') { $method = 'ssha'; $salt = substr(base64_decode(substr($hash, 6)), 20); - } elseif(substr($hash, 0, 6) == '{SMD5}') { + } elseif (substr($hash, 0, 6) == '{SMD5}') { $method = 'lsmd5'; $salt = substr(base64_decode(substr($hash, 6)), 16); - } elseif(preg_match('/^:B:(.+?):.{32}$/', $hash, $m)) { + } elseif (preg_match('/^:B:(.+?):.{32}$/', $hash, $m)) { $method = 'mediawiki'; $salt = $m[1]; - } elseif(preg_match('/^\$(5|6)\$(rounds=\d+)?\$?(.+?)\$/', $hash, $m)) { + } elseif (preg_match('/^\$(5|6)\$(rounds=\d+)?\$?(.+?)\$/', $hash, $m)) { $method = 'sha2'; $salt = $m[3]; - $magic = array( - 'prefix' => $m[1], - 'rounds' => $m[2], - ); - } elseif(preg_match('/^\$(argon2id?)/', $hash, $m)) { - if(!defined('PASSWORD_'.strtoupper($m[1]))) { - throw new \Exception('This PHP installation has no '.strtoupper($m[1]).' support'); + $magic = ['prefix' => $m[1], 'rounds' => $m[2]]; + } elseif (preg_match('/^\$(argon2id?)/', $hash, $m)) { + if (!defined('PASSWORD_' . strtoupper($m[1]))) { + throw new \Exception('This PHP installation has no ' . strtoupper($m[1]) . ' support'); } - return password_verify($clear,$hash); - } elseif($len == 32) { + return password_verify($clear, $hash); + } elseif ($len == 32) { $method = 'md5'; - } elseif($len == 40) { + } elseif ($len == 40) { $method = 'sha1'; - } elseif($len == 16) { + } elseif ($len == 16) { $method = 'mysql'; - } elseif($len == 41 && $hash[0] == '*') { + } elseif ($len == 41 && $hash[0] == '*') { $method = 'my411'; - } elseif($len == 34) { + } elseif ($len == 34) { $method = 'kmd5'; $salt = $hash; } else { @@ -121,9 +115,9 @@ class PassHash { } //crypt and compare - $call = 'hash_'.$method; + $call = 'hash_' . $method; $newhash = $this->$call($clear, $salt, $magic); - if(\hash_equals($newhash, $hash)) { + if (\hash_equals($newhash, $hash)) { return true; } return false; @@ -135,10 +129,11 @@ class PassHash { * @param int $len The length of the salt * @return string */ - public function gen_salt($len = 32) { + public function gen_salt($len = 32) + { $salt = ''; $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - for($i = 0; $i < $len; $i++) { + for ($i = 0; $i < $len; $i++) { $salt .= $chars[$this->random(0, 61)]; } return $salt; @@ -154,12 +149,13 @@ class PassHash { * @param int $len The length of the salt * @param bool $cut Apply length restriction to existing salt? */ - public function init_salt(&$salt, $len = 32, $cut = true) { - if(is_null($salt)) { + public function init_salt(&$salt, $len = 32, $cut = true) + { + if (is_null($salt)) { $salt = $this->gen_salt($len); $cut = true; // for new hashes we alway apply length restriction } - if(strlen($salt) > $len && $cut) $salt = substr($salt, 0, $len); + if (strlen($salt) > $len && $cut) $salt = substr($salt, 0, $len); } // Password hashing methods follow below @@ -181,11 +177,12 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_smd5($clear, $salt = null) { + public function hash_smd5($clear, $salt = null) + { $this->init_salt($salt, 8); - if(defined('CRYPT_MD5') && CRYPT_MD5 && $salt !== '') { - return crypt($clear, '$1$'.$salt.'$'); + if (defined('CRYPT_MD5') && CRYPT_MD5 && $salt !== '') { + return crypt($clear, '$1$' . $salt . '$'); } else { // Fall back to PHP-only implementation return $this->hash_apr1($clear, $salt, '1'); @@ -203,9 +200,10 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_lsmd5($clear, $salt = null) { + public function hash_lsmd5($clear, $salt = null) + { $this->init_salt($salt, 8); - return "{SMD5}".base64_encode(md5($clear.$salt, true).$salt); + return "{SMD5}" . base64_encode(md5($clear . $salt, true) . $salt); } /** @@ -223,40 +221,41 @@ class PassHash { * @param string $magic The hash identifier (apr1 or 1) * @return string Hashed password */ - public function hash_apr1($clear, $salt = null, $magic = 'apr1') { + public function hash_apr1($clear, $salt = null, $magic = 'apr1') + { $this->init_salt($salt, 8); $len = strlen($clear); - $text = $clear.'$'.$magic.'$'.$salt; - $bin = pack("H32", md5($clear.$salt.$clear)); - for($i = $len; $i > 0; $i -= 16) { + $text = $clear . '$' . $magic . '$' . $salt; + $bin = pack("H32", md5($clear . $salt . $clear)); + for ($i = $len; $i > 0; $i -= 16) { $text .= substr($bin, 0, min(16, $i)); } - for($i = $len; $i > 0; $i >>= 1) { + for ($i = $len; $i > 0; $i >>= 1) { $text .= ($i & 1) ? chr(0) : $clear[0]; } $bin = pack("H32", md5($text)); - for($i = 0; $i < 1000; $i++) { + for ($i = 0; $i < 1000; $i++) { $new = ($i & 1) ? $clear : $bin; - if($i % 3) $new .= $salt; - if($i % 7) $new .= $clear; + if ($i % 3) $new .= $salt; + if ($i % 7) $new .= $clear; $new .= ($i & 1) ? $bin : $clear; $bin = pack("H32", md5($new)); } $tmp = ''; - for($i = 0; $i < 5; $i++) { + for ($i = 0; $i < 5; $i++) { $k = $i + 6; $j = $i + 12; - if($j == 16) $j = 5; - $tmp = $bin[$i].$bin[$k].$bin[$j].$tmp; + if ($j == 16) $j = 5; + $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp; } - $tmp = chr(0).chr(0).$bin[11].$tmp; + $tmp = chr(0) . chr(0) . $bin[11] . $tmp; $tmp = strtr( strrev(substr(base64_encode($tmp), 2)), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ); - return '$'.$magic.'$'.$salt.'$'.$tmp; + return '$' . $magic . '$' . $salt . '$' . $tmp; } /** @@ -267,7 +266,8 @@ class PassHash { * @param string $clear The clear text to hash * @return string Hashed password */ - public function hash_md5($clear) { + public function hash_md5($clear) + { return md5($clear); } @@ -279,7 +279,8 @@ class PassHash { * @param string $clear The clear text to hash * @return string Hashed password */ - public function hash_sha1($clear) { + public function hash_sha1($clear) + { return sha1($clear); } @@ -292,9 +293,10 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_ssha($clear, $salt = null) { + public function hash_ssha($clear, $salt = null) + { $this->init_salt($salt, 4); - return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt); + return '{SSHA}' . base64_encode(pack("H*", sha1($clear . $salt)) . $salt); } /** @@ -306,7 +308,8 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_crypt($clear, $salt = null) { + public function hash_crypt($clear, $salt = null) + { $this->init_salt($salt, 2); return crypt($clear, $salt); } @@ -321,13 +324,14 @@ class PassHash { * @param string $clear The clear text to hash * @return string Hashed password */ - public function hash_mysql($clear) { + public function hash_mysql($clear) + { $nr = 0x50305735; $nr2 = 0x12345671; $add = 7; $charArr = preg_split("//", $clear); - foreach($charArr as $char) { - if(($char == '') || ($char == ' ') || ($char == '\t')) continue; + foreach ($charArr as $char) { + if (($char == '') || ($char == ' ') || ($char == '\t')) continue; $charVal = ord($char); $nr ^= ((($nr & 63) + $add) * $charVal) + ($nr << 8); $nr2 += ($nr2 << 8) ^ $nr; @@ -344,8 +348,9 @@ class PassHash { * @param string $clear The clear text to hash * @return string Hashed password */ - public function hash_my411($clear) { - return '*'.strtoupper(sha1(pack("H*", sha1($clear)))); + public function hash_my411($clear) + { + return '*' . strtoupper(sha1(pack("H*", sha1($clear)))); } /** @@ -360,12 +365,13 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_kmd5($clear, $salt = null) { + public function hash_kmd5($clear, $salt = null) + { $this->init_salt($salt); $key = substr($salt, 16, 2); - $hash1 = strtolower(md5($key.md5($clear))); - $hash2 = substr($hash1, 0, 16).$key.substr($hash1, 16); + $hash1 = strtolower(md5($key . md5($clear))); + $hash2 = substr($hash1, 0, 16) . $key . substr($hash1, 16); return $hash2; } @@ -395,28 +401,29 @@ class PassHash { * @throws \Exception * @return string Hashed password */ - protected function stretched_hash($algo, $clear, $salt = null, $magic = 'P', $compute = 8) { + protected function stretched_hash($algo, $clear, $salt = null, $magic = 'P', $compute = 8) + { $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - if(is_null($salt)) { + if (is_null($salt)) { $this->init_salt($salt); - $salt = $itoa64[$compute].$salt; // prefix iteration count + $salt = $itoa64[$compute] . $salt; // prefix iteration count } $iterc = $salt[0]; // pos 0 of salt is log2(iteration count) $iter = strpos($itoa64, $iterc); - if($iter > 30) { - throw new \Exception("Too high iteration count ($iter) in ". - __CLASS__.'::'.__FUNCTION__); + if ($iter > 30) { + throw new \Exception("Too high iteration count ($iter) in " . + self::class . '::' . __FUNCTION__); } $iter = 1 << $iter; $salt = substr($salt, 1, 8); // iterate - $hash = hash($algo, $salt . $clear, TRUE); + $hash = hash($algo, $salt . $clear, true); do { - $hash = hash($algo, $hash.$clear, true); - } while(--$iter); + $hash = hash($algo, $hash . $clear, true); + } while (--$iter); // encode $output = ''; @@ -425,20 +432,20 @@ class PassHash { do { $value = ord($hash[$i++]); $output .= $itoa64[$value & 0x3f]; - if($i < $count) + if ($i < $count) $value |= ord($hash[$i]) << 8; $output .= $itoa64[($value >> 6) & 0x3f]; - if($i++ >= $count) + if ($i++ >= $count) break; - if($i < $count) + if ($i < $count) $value |= ord($hash[$i]) << 16; $output .= $itoa64[($value >> 12) & 0x3f]; - if($i++ >= $count) + if ($i++ >= $count) break; $output .= $itoa64[($value >> 18) & 0x3f]; - } while($i < $count); + } while ($i < $count); - return '$'.$magic.'$'.$iterc.$salt.$output; + return '$' . $magic . '$' . $iterc . $salt . $output; } /** @@ -459,7 +466,8 @@ class PassHash { * @throws Exception * @return string Hashed password */ - public function hash_pmd5($clear, $salt = null, $magic = 'P', $compute = 8) { + public function hash_pmd5($clear, $salt = null, $magic = 'P', $compute = 8) + { return $this->stretched_hash('md5', $clear, $salt, $magic, $compute); } @@ -480,8 +488,9 @@ class PassHash { * @throws Exception * @return string Hashed password */ - public function hash_drupal_sha512($clear, $salt = null, $magic = 'S', $compute = 15) { - return substr($this->stretched_hash('sha512', $clear, $salt, $magic, $compute), 0, 55); + public function hash_drupal_sha512($clear, $salt = null, $magic = 'S', $compute = 15) + { + return substr($this->stretched_hash('sha512', $clear, $salt, $magic, $compute), 0, 55); } /** @@ -495,7 +504,8 @@ class PassHash { * @return string * @throws \Exception */ - public function hash_hmd5($clear, $salt = null, $magic = 'H', $compute = 8) { + public function hash_hmd5($clear, $salt = null, $magic = 'H', $compute = 8) + { return $this->hash_pmd5($clear, $salt, $magic, $compute); } @@ -511,9 +521,10 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_djangosha1($clear, $salt = null) { + public function hash_djangosha1($clear, $salt = null) + { $this->init_salt($salt, 5); - return 'sha1$'.$salt.'$'.sha1($salt.$clear); + return 'sha1$' . $salt . '$' . sha1($salt . $clear); } /** @@ -528,9 +539,10 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_djangomd5($clear, $salt = null) { + public function hash_djangomd5($clear, $salt = null) + { $this->init_salt($salt, 5); - return 'md5$'.$salt.'$'.md5($salt.$clear); + return 'md5$' . $salt . '$' . md5($salt . $clear); } /** @@ -550,23 +562,24 @@ class PassHash { * @return string Hashed password * @throws Exception when PHP is missing support for the method/algo */ - public function hash_seafilepbkdf2($clear, $salt=null, $opts=array()) { + public function hash_seafilepbkdf2($clear, $salt = null, $opts = []) + { $this->init_salt($salt, 64); - if(empty($opts['algo'])) { - $prefixalgo='SHA256'; + if (empty($opts['algo'])) { + $prefixalgo = 'SHA256'; } else { - $prefixalgo=$opts['algo']; + $prefixalgo = $opts['algo']; } $algo = strtolower($prefixalgo); - if(empty($opts['iter'])) { + if (empty($opts['iter'])) { $iter = 10000; } else { $iter = (int) $opts['iter']; } - if(!function_exists('hash_pbkdf2')) { + if (!function_exists('hash_pbkdf2')) { throw new Exception('This PHP installation has no PBKDF2 support'); } - if(!in_array($algo, hash_algos())) { + if (!in_array($algo, hash_algos())) { throw new Exception("This PHP installation has no $algo support"); } @@ -586,22 +599,23 @@ class PassHash { * @return string Hashed password * @throws \Exception when PHP is missing support for the method/algo */ - public function hash_djangopbkdf2($clear, $salt=null, $opts=array()) { + public function hash_djangopbkdf2($clear, $salt = null, $opts = []) + { $this->init_salt($salt, 12); - if(empty($opts['algo'])) { + if (empty($opts['algo'])) { $algo = 'sha256'; } else { $algo = $opts['algo']; } - if(empty($opts['iter'])) { + if (empty($opts['iter'])) { $iter = 24000; } else { $iter = (int) $opts['iter']; } - if(!function_exists('hash_pbkdf2')) { + if (!function_exists('hash_pbkdf2')) { throw new \Exception('This PHP installation has no PBKDF2 support'); } - if(!in_array($algo, hash_algos())) { + if (!in_array($algo, hash_algos())) { throw new \Exception("This PHP installation has no $algo support"); } @@ -618,7 +632,8 @@ class PassHash { * @return string Hashed password * @throws \Exception when PHP is missing support for the method/algo */ - public function hash_djangopbkdf2_sha256($clear, $salt=null, $opts=array()) { + public function hash_djangopbkdf2_sha256($clear, $salt = null, $opts = []) + { $opts['algo'] = 'sha256'; return $this->hash_djangopbkdf2($clear, $salt, $opts); } @@ -632,7 +647,8 @@ class PassHash { * @return string Hashed password * @throws \Exception when PHP is missing support for the method/algo */ - public function hash_djangopbkdf2_sha1($clear, $salt=null, $opts=array()) { + public function hash_djangopbkdf2_sha1($clear, $salt = null, $opts = []) + { $opts['algo'] = 'sha1'; return $this->hash_djangopbkdf2($clear, $salt, $opts); } @@ -654,14 +670,15 @@ class PassHash { * @throws \Exception * @return string Hashed password */ - public function hash_bcrypt($clear, $salt = null, $compute = 10) { - if(!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH != 1) { + public function hash_bcrypt($clear, $salt = null, $compute = 10) + { + if (!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH !== 1) { throw new \Exception('This PHP installation has no bcrypt support'); } - if(is_null($salt)) { - if($compute < 4 || $compute > 31) $compute = 8; - $salt = '$2y$'.str_pad($compute, 2, '0', STR_PAD_LEFT).'$'. + if (is_null($salt)) { + if ($compute < 4 || $compute > 31) $compute = 8; + $salt = '$2y$' . str_pad($compute, 2, '0', STR_PAD_LEFT) . '$' . $this->gen_salt(22); } @@ -684,39 +701,42 @@ class PassHash { * @return string Hashed password * @throws \Exception */ - public function hash_sha2($clear, $salt = null, $opts = array()) { - if(empty($opts['prefix'])) { + public function hash_sha2($clear, $salt = null, $opts = []) + { + if (empty($opts['prefix'])) { $prefix = '6'; } else { $prefix = $opts['prefix']; } - if(empty($opts['rounds'])) { + if (empty($opts['rounds'])) { $rounds = null; } else { $rounds = $opts['rounds']; } - if($prefix == '5' && (!defined('CRYPT_SHA256') || CRYPT_SHA256 != 1)) { + if ($prefix == '5' && (!defined('CRYPT_SHA256') || CRYPT_SHA256 !== 1)) { throw new \Exception('This PHP installation has no SHA256 support'); } - if($prefix == '6' && (!defined('CRYPT_SHA512') || CRYPT_SHA512 != 1)) { + if ($prefix == '6' && (!defined('CRYPT_SHA512') || CRYPT_SHA512 !== 1)) { throw new \Exception('This PHP installation has no SHA512 support'); } $this->init_salt($salt, 8, false); - if(empty($rounds)) { - return crypt($clear, '$'.$prefix.'$'.$salt.'$'); - }else{ - return crypt($clear, '$'.$prefix.'$'.$rounds.'$'.$salt.'$'); + if (empty($rounds)) { + return crypt($clear, '$' . $prefix . '$' . $salt . '$'); + } else { + return crypt($clear, '$' . $prefix . '$' . $rounds . '$' . $salt . '$'); } } /** @see sha2 */ - public function hash_sha512($clear, $salt = null, $opts=[]) { + public function hash_sha512($clear, $salt = null, $opts = []) + { $opts['prefix'] = 6; return $this->hash_sha2($clear, $salt, $opts); } /** @see sha2 */ - public function hash_sha256($clear, $salt = null, $opts=[]) { + public function hash_sha256($clear, $salt = null, $opts = []) + { $opts['prefix'] = 5; return $this->hash_sha2($clear, $salt, $opts); } @@ -733,9 +753,10 @@ class PassHash { * @param string $salt The salt to use, null for random * @return string Hashed password */ - public function hash_mediawiki($clear, $salt = null) { + public function hash_mediawiki($clear, $salt = null) + { $this->init_salt($salt, 8, false); - return ':B:'.$salt.':'.md5($salt.'-'.md5($clear)); + return ':B:' . $salt . ':' . md5($salt . '-' . md5($clear)); } @@ -750,11 +771,12 @@ class PassHash { * @param string $clear The clear text to hash * @return string Hashed password */ - public function hash_argon2i($clear) { - if(!defined('PASSWORD_ARGON2I')) { + public function hash_argon2i($clear) + { + if (!defined('PASSWORD_ARGON2I')) { throw new \Exception('This PHP installation has no ARGON2I support'); } - return password_hash($clear,PASSWORD_ARGON2I); + return password_hash($clear, PASSWORD_ARGON2I); } /** @@ -768,11 +790,12 @@ class PassHash { * @param string $clear The clear text to hash * @return string Hashed password */ - public function hash_argon2id($clear) { - if(!defined('PASSWORD_ARGON2ID')) { + public function hash_argon2id($clear) + { + if (!defined('PASSWORD_ARGON2ID')) { throw new \Exception('This PHP installation has no ARGON2ID support'); } - return password_hash($clear,PASSWORD_ARGON2ID); + return password_hash($clear, PASSWORD_ARGON2ID); } /** @@ -793,9 +816,10 @@ class PassHash { * @param bool $raw_output When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits. * @return string */ - public static function hmac($algo, $data, $key, $raw_output = false) { + public static function hmac($algo, $data, $key, $raw_output = false) + { // use native function if available and not in unit test - if(function_exists('hash_hmac') && !defined('SIMPLE_TEST')){ + if (function_exists('hash_hmac') && !defined('SIMPLE_TEST')) { return hash_hmac($algo, $data, $key, $raw_output); } @@ -805,15 +829,17 @@ class PassHash { $opad = str_repeat(chr(0x5C), $size); $ipad = str_repeat(chr(0x36), $size); - if(strlen($key) > $size) { + if (strlen($key) > $size) { $key = str_pad(pack($pack, $algo($key)), $size, chr(0x00)); } else { $key = str_pad($key, $size, chr(0x00)); } - for($i = 0; $i < strlen($key) - 1; $i++) { - $opad[$i] = $opad[$i] ^ $key[$i]; - $ipad[$i] = $ipad[$i] ^ $key[$i]; + for ($i = 0; $i < strlen($key) - 1; $i++) { + $ochar = $opad[$i] ^ $key[$i]; + $ichar = $ipad[$i] ^ $key[$i]; + $opad[$i] = $ochar; + $ipad[$i] = $ichar; } $output = $algo($opad . pack($pack, $algo($ipad . $data))); @@ -828,7 +854,8 @@ class PassHash { * @param int $max * @return int */ - protected function random($min, $max){ + protected function random($min, $max) + { try { return random_int($min, $max); } catch (\Exception $e) { diff --git a/inc/Remote/Api.php b/inc/Remote/Api.php index 8ff38eadb..99dbf2bd4 100644 --- a/inc/Remote/Api.php +++ b/inc/Remote/Api.php @@ -2,6 +2,8 @@ namespace dokuwiki\Remote; +use dokuwiki\Extension\PluginInterface; +use dokuwiki\Input\Input; use dokuwiki\Extension\Event; use dokuwiki\Extension\RemotePlugin; @@ -36,17 +38,16 @@ use dokuwiki\Extension\RemotePlugin; */ class Api { - /** - * @var ApiCore + * @var ApiCore|\RemoteAPICoreTest */ - private $coreMethods = null; + private $coreMethods; /** * @var array remote methods provided by dokuwiki plugins - will be filled lazy via * {@see dokuwiki\Remote\RemoteAPI#getPluginMethods} */ - private $pluginMethods = null; + private $pluginMethods; /** * @var array contains custom calls to the api. Plugins can use the XML_CALL_REGISTER event. @@ -54,7 +55,7 @@ class Api * * The remote method name is the same as in the remote name returned by _getMethods(). */ - private $pluginCustomCalls = null; + private $pluginCustomCalls; private $dateTransformation; private $fileTransformation; @@ -64,8 +65,8 @@ class Api */ public function __construct() { - $this->dateTransformation = array($this, 'dummyTransformation'); - $this->fileTransformation = array($this, 'dummyTransformation'); + $this->dateTransformation = [$this, 'dummyTransformation']; + $this->fileTransformation = [$this, 'dummyTransformation']; } /** @@ -87,13 +88,13 @@ class Api * @return mixed result of method call, must be a primitive type. * @throws RemoteException */ - public function call($method, $args = array()) + public function call($method, $args = []) { if ($args === null) { - $args = array(); + $args = []; } // Ensure we have at least one '.' in $method - list($type, $pluginName, /* $call */) = sexplode('.', $method . '.', 3, ''); + [$type, $pluginName, /* call */] = sexplode('.', $method . '.', 3, ''); if ($type === 'plugin') { return $this->callPlugin($pluginName, $method, $args); } @@ -129,7 +130,7 @@ class Api if (!array_key_exists($method, $customCalls)) { throw new RemoteException('Method does not exist', -32603); } - list($plugin, $method) = $customCalls[$method]; + [$plugin, $method] = $customCalls[$method]; $fullMethod = "plugin.$plugin.$method"; return $this->callPlugin($plugin, $fullMethod, $args); } @@ -143,7 +144,7 @@ class Api private function getCustomCallPlugins() { if ($this->pluginCustomCalls === null) { - $data = array(); + $data = []; Event::createAndTrigger('RPC_CALL_ADD', $data); $this->pluginCustomCalls = $data; } @@ -163,14 +164,14 @@ class Api { $plugin = plugin_load('remote', $pluginName); $methods = $this->getPluginMethods(); - if (!$plugin) { + if (!$plugin instanceof PluginInterface) { throw new RemoteException('Method does not exist', -32603); } $this->checkAccess($methods[$method]); $name = $this->getMethodName($methods, $method); try { - set_error_handler(array($this, "argumentWarningHandler"), E_WARNING); // for PHP <7.1 - return call_user_func_array(array($plugin, $name), $args); + set_error_handler([$this, "argumentWarningHandler"], E_WARNING); // for PHP <7.1 + return call_user_func_array([$plugin, $name], $args); } catch (\ArgumentCountError $th) { throw new RemoteException('Method does not exist - wrong parameter count.', -32603); } finally { @@ -195,8 +196,8 @@ class Api } $this->checkArgumentLength($coreMethods[$method], $args); try { - set_error_handler(array($this, "argumentWarningHandler"), E_WARNING); // for PHP <7.1 - return call_user_func_array(array($this->coreMethods, $this->getMethodName($coreMethods, $method)), $args); + set_error_handler([$this, "argumentWarningHandler"], E_WARNING); // for PHP <7.1 + return call_user_func_array([$this->coreMethods, $this->getMethodName($coreMethods, $method)], $args); } catch (\ArgumentCountError $th) { throw new RemoteException('Method does not exist - wrong parameter count.', -32603); } finally { @@ -214,10 +215,8 @@ class Api { if (!isset($methodMeta['public'])) { $this->forceAccess(); - } else { - if ($methodMeta['public'] == '0') { - $this->forceAccess(); - } + } elseif ($methodMeta['public'] == '0') { + $this->forceAccess(); } } @@ -261,7 +260,7 @@ class Api { global $conf; global $USERINFO; - /** @var \dokuwiki\Input\Input $INPUT */ + /** @var Input $INPUT */ global $INPUT; if (!$conf['remote']) { @@ -302,7 +301,7 @@ class Api public function getPluginMethods() { if ($this->pluginMethods === null) { - $this->pluginMethods = array(); + $this->pluginMethods = []; $plugins = plugin_list('remote'); foreach ($plugins as $pluginName) { @@ -310,7 +309,7 @@ class Api $plugin = plugin_load('remote', $pluginName); if (!is_subclass_of($plugin, 'dokuwiki\Extension\RemotePlugin')) { throw new RemoteException( - "Plugin $pluginName does not implement dokuwiki\Plugin\DokuWiki_Remote_Plugin" + "Plugin $pluginName does not implement dokuwiki\Extension\RemotePlugin" ); } @@ -331,8 +330,8 @@ class Api /** * Collects all the core methods * - * @param ApiCore $apiCore this parameter is used for testing. Here you can pass a non-default RemoteAPICore - * instance. (for mocking) + * @param ApiCore|\RemoteAPICoreTest $apiCore this parameter is used for testing. + * Here you can pass a non-default RemoteAPICore instance. (for mocking) * @return array all core methods. */ public function getCoreMethods($apiCore = null) diff --git a/inc/Remote/ApiCore.php b/inc/Remote/ApiCore.php index 9b9d7c738..aefd0132d 100644 --- a/inc/Remote/ApiCore.php +++ b/inc/Remote/ApiCore.php @@ -5,6 +5,7 @@ namespace dokuwiki\Remote; use Doku_Renderer_xhtml; use dokuwiki\ChangeLog\MediaChangeLog; use dokuwiki\ChangeLog\PageChangeLog; +use dokuwiki\Extension\AuthPlugin; use dokuwiki\Extension\Event; use dokuwiki\Utf8\Sort; @@ -17,7 +18,7 @@ define('DOKU_API_VERSION', 11); class ApiCore { /** @var int Increased whenever the API is changed */ - const API_VERSION = 11; + public const API_VERSION = 11; /** @var Api */ @@ -38,156 +39,183 @@ class ApiCore */ public function getRemoteInfo() { - return array( - 'dokuwiki.getVersion' => array( - 'args' => array(), + return [ + 'dokuwiki.getVersion' => [ + 'args' => [], 'return' => 'string', 'doc' => 'Returns the running DokuWiki version.' - ), 'dokuwiki.login' => array( - 'args' => array('string', 'string'), + ], + 'dokuwiki.login' => [ + 'args' => ['string', 'string'], 'return' => 'int', 'doc' => 'Tries to login with the given credentials and sets auth cookies.', 'public' => '1' - ), 'dokuwiki.logoff' => array( - 'args' => array(), + ], + 'dokuwiki.logoff' => [ + 'args' => [], 'return' => 'int', 'doc' => 'Tries to logoff by expiring auth cookies and the associated PHP session.' - ), 'dokuwiki.getPagelist' => array( - 'args' => array('string', 'array'), + ], + 'dokuwiki.getPagelist' => [ + 'args' => ['string', 'array'], 'return' => 'array', 'doc' => 'List all pages within the given namespace.', 'name' => 'readNamespace' - ), 'dokuwiki.search' => array( - 'args' => array('string'), + ], + 'dokuwiki.search' => [ + 'args' => ['string'], 'return' => 'array', 'doc' => 'Perform a fulltext search and return a list of matching pages' - ), 'dokuwiki.getTime' => array( - 'args' => array(), + ], + 'dokuwiki.getTime' => [ + 'args' => [], 'return' => 'int', - 'doc' => 'Returns the current time at the remote wiki server as Unix timestamp.', - ), 'dokuwiki.setLocks' => array( - 'args' => array('array'), + 'doc' => 'Returns the current time at the remote wiki server as Unix timestamp.' + ], + 'dokuwiki.setLocks' => [ + 'args' => ['array'], 'return' => 'array', 'doc' => 'Lock or unlock pages.' - ), 'dokuwiki.getTitle' => array( - 'args' => array(), + ], + 'dokuwiki.getTitle' => [ + 'args' => [], 'return' => 'string', 'doc' => 'Returns the wiki title.', 'public' => '1' - ), 'dokuwiki.appendPage' => array( - 'args' => array('string', 'string', 'array'), + ], + 'dokuwiki.appendPage' => [ + 'args' => ['string', 'string', 'array'], 'return' => 'bool', 'doc' => 'Append text to a wiki page.' - ), 'dokuwiki.createUser' => array( - 'args' => array('struct'), + ], + 'dokuwiki.createUser' => [ + 'args' => ['struct'], 'return' => 'bool', 'doc' => 'Create a user. The result is boolean' - ),'dokuwiki.deleteUsers' => array( - 'args' => array('array'), + ], + 'dokuwiki.deleteUsers' => [ + 'args' => ['array'], 'return' => 'bool', 'doc' => 'Remove one or more users from the list of registered users.' - ), 'wiki.getPage' => array( - 'args' => array('string'), + ], + 'wiki.getPage' => [ + 'args' => ['string'], 'return' => 'string', 'doc' => 'Get the raw Wiki text of page, latest version.', - 'name' => 'rawPage', - ), 'wiki.getPageVersion' => array( - 'args' => array('string', 'int'), + 'name' => 'rawPage' + ], + 'wiki.getPageVersion' => [ + 'args' => ['string', 'int'], 'name' => 'rawPage', 'return' => 'string', 'doc' => 'Return a raw wiki page' - ), 'wiki.getPageHTML' => array( - 'args' => array('string'), + ], + 'wiki.getPageHTML' => [ + 'args' => ['string'], 'return' => 'string', 'doc' => 'Return page in rendered HTML, latest version.', 'name' => 'htmlPage' - ), 'wiki.getPageHTMLVersion' => array( - 'args' => array('string', 'int'), + ], + 'wiki.getPageHTMLVersion' => [ + 'args' => ['string', 'int'], 'return' => 'string', 'doc' => 'Return page in rendered HTML.', 'name' => 'htmlPage' - ), 'wiki.getAllPages' => array( - 'args' => array(), + ], + 'wiki.getAllPages' => [ + 'args' => [], 'return' => 'array', 'doc' => 'Returns a list of all pages. The result is an array of utf8 pagenames.', 'name' => 'listPages' - ), 'wiki.getAttachments' => array( - 'args' => array('string', 'array'), + ], + 'wiki.getAttachments' => [ + 'args' => ['string', 'array'], 'return' => 'array', 'doc' => 'Returns a list of all media files.', 'name' => 'listAttachments' - ), 'wiki.getBackLinks' => array( - 'args' => array('string'), + ], + 'wiki.getBackLinks' => [ + 'args' => ['string'], 'return' => 'array', 'doc' => 'Returns the pages that link to this page.', 'name' => 'listBackLinks' - ), 'wiki.getPageInfo' => array( - 'args' => array('string'), + ], + 'wiki.getPageInfo' => [ + 'args' => ['string'], 'return' => 'array', 'doc' => 'Returns a struct with info about the page, latest version.', 'name' => 'pageInfo' - ), 'wiki.getPageInfoVersion' => array( - 'args' => array('string', 'int'), + ], + 'wiki.getPageInfoVersion' => [ + 'args' => ['string', 'int'], 'return' => 'array', 'doc' => 'Returns a struct with info about the page.', 'name' => 'pageInfo' - ), 'wiki.getPageVersions' => array( - 'args' => array('string', 'int'), + ], + 'wiki.getPageVersions' => [ + 'args' => ['string', 'int'], 'return' => 'array', 'doc' => 'Returns the available revisions of the page.', 'name' => 'pageVersions' - ), 'wiki.putPage' => array( - 'args' => array('string', 'string', 'array'), + ], + 'wiki.putPage' => [ + 'args' => ['string', 'string', 'array'], 'return' => 'bool', 'doc' => 'Saves a wiki page.' - ), 'wiki.listLinks' => array( - 'args' => array('string'), + ], + 'wiki.listLinks' => [ + 'args' => ['string'], 'return' => 'array', 'doc' => 'Lists all links contained in a wiki page.' - ), 'wiki.getRecentChanges' => array( - 'args' => array('int'), + ], + 'wiki.getRecentChanges' => [ + 'args' => ['int'], 'return' => 'array', 'doc' => 'Returns a struct about all recent changes since given timestamp.' - ), 'wiki.getRecentMediaChanges' => array( - 'args' => array('int'), + ], + 'wiki.getRecentMediaChanges' => [ + 'args' => ['int'], 'return' => 'array', 'doc' => 'Returns a struct about all recent media changes since given timestamp.' - ), 'wiki.aclCheck' => array( - 'args' => array('string', 'string', 'array'), + ], + 'wiki.aclCheck' => ['args' => ['string', 'string', 'array'], 'return' => 'int', 'doc' => 'Returns the permissions of a given wiki page. By default, for current user/groups' - ), 'wiki.putAttachment' => array( - 'args' => array('string', 'file', 'array'), + ], + 'wiki.putAttachment' => ['args' => ['string', 'file', 'array'], 'return' => 'array', 'doc' => 'Upload a file to the wiki.' - ), 'wiki.deleteAttachment' => array( - 'args' => array('string'), + ], + 'wiki.deleteAttachment' => [ + 'args' => ['string'], 'return' => 'int', 'doc' => 'Delete a file from the wiki.' - ), 'wiki.getAttachment' => array( - 'args' => array('string'), + ], + 'wiki.getAttachment' => [ + 'args' => ['string'], 'doc' => 'Return a media file', 'return' => 'file', - 'name' => 'getAttachment', - ), 'wiki.getAttachmentInfo' => array( - 'args' => array('string'), + 'name' => 'getAttachment' + ], + 'wiki.getAttachmentInfo' => [ + 'args' => ['string'], 'return' => 'array', 'doc' => 'Returns a struct with info about the attachment.' - ), 'dokuwiki.getXMLRPCAPIVersion' => array( - 'args' => array(), + ], + 'dokuwiki.getXMLRPCAPIVersion' => [ + 'args' => [], 'name' => 'getAPIVersion', 'return' => 'int', 'doc' => 'Returns the XMLRPC API version.', - 'public' => '1', - ), 'wiki.getRPCVersionSupported' => array( - 'args' => array(), + 'public' => '1' + ], + 'wiki.getRPCVersionSupported' => [ + 'args' => [], 'name' => 'wikiRpcVersion', 'return' => 'int', 'doc' => 'Returns 2 with the supported RPC API version.', - 'public' => '1' - ), - - ); + 'public' => '1'] + ]; } /** @@ -231,12 +259,12 @@ class ApiCore /** * Return a media file * - * @author Gina Haeussge <osd@foosel.net> - * * @param string $id file id * @return mixed media file * @throws AccessDeniedException no permission for media * @throws RemoteException not exist + * @author Gina Haeussge <osd@foosel.net> + * */ public function getAttachment($id) { @@ -257,18 +285,15 @@ class ApiCore /** * Return info about a media file * - * @author Gina Haeussge <osd@foosel.net> - * * @param string $id page id * @return array + * @author Gina Haeussge <osd@foosel.net> + * */ public function getAttachmentInfo($id) { $id = cleanID($id); - $info = array( - 'lastModified' => $this->api->toDate(0), - 'size' => 0, - ); + $info = ['lastModified' => $this->api->toDate(0), 'size' => 0]; $file = mediaFN($id); if (auth_quickaclcheck(getNS($id) . ':*') >= AUTH_READ) { @@ -312,7 +337,7 @@ class ApiCore */ public function listPages() { - $list = array(); + $list = []; $pages = idx_get_indexer()->getPages(); $pages = array_filter(array_filter($pages, 'isVisiblePage'), 'page_exists'); Sort::ksort($pages); @@ -322,7 +347,7 @@ class ApiCore if ($perm < AUTH_READ) { continue; } - $page = array(); + $page = []; $page['id'] = trim($pages[$idx]); $page['perms'] = $perm; $page['size'] = @filesize(wikiFN($pages[$idx])); @@ -342,15 +367,15 @@ class ApiCore * $opts['hash'] do md5 sum of content? * @return array */ - public function readNamespace($ns, $opts = array()) + public function readNamespace($ns, $opts = []) { global $conf; - if (!is_array($opts)) $opts = array(); + if (!is_array($opts)) $opts = []; $ns = cleanID($ns); $dir = utf8_encodeFN(str_replace(':', '/', $ns)); - $data = array(); + $data = []; $opts['skipacl'] = 0; // no ACL skipping for XMLRPC search($data, $conf['datadir'], 'search_allpages', $opts, $dir); return $data; @@ -364,9 +389,9 @@ class ApiCore */ public function search($query) { - $regex = array(); + $regex = []; $data = ft_pageSearch($query, $regex); - $pages = array(); + $pages = []; // prepare additional data $idx = 0; @@ -380,15 +405,15 @@ class ApiCore $snippet = ''; } - $pages[] = array( + $pages[] = [ 'id' => $id, - 'score' => intval($score), + 'score' => (int)$score, 'rev' => filemtime($file), 'mtime' => filemtime($file), 'size' => filesize($file), 'snippet' => $snippet, 'title' => useHeading('navigation') ? p_get_first_heading($id) : $id - ); + ]; } return $pages; } @@ -411,8 +436,6 @@ class ApiCore * in the listing, and 'pattern' for filtering the returned files against * a regular expression matching their name. * - * @author Gina Haeussge <osd@foosel.net> - * * @param string $ns * @param array $options * $options['depth'] recursion level, 0 for all @@ -421,23 +444,25 @@ class ApiCore * $options['hash'] add hashes to result list * @return array * @throws AccessDeniedException no access to the media files + * @author Gina Haeussge <osd@foosel.net> + * */ - public function listAttachments($ns, $options = array()) + public function listAttachments($ns, $options = []) { global $conf; $ns = cleanID($ns); - if (!is_array($options)) $options = array(); + if (!is_array($options)) $options = []; $options['skipacl'] = 0; // no ACL skipping for XMLRPC if (auth_quickaclcheck($ns . ':*') >= AUTH_READ) { $dir = utf8_encodeFN(str_replace(':', '/', $ns)); - $data = array(); + $data = []; search($data, $conf['mediadir'], 'search_media', $options, $dir); $len = count($data); - if (!$len) return array(); + if (!$len) return []; for ($i = 0; $i < $len; $i++) { unset($data[$i]['meta']); @@ -492,12 +517,12 @@ class ApiCore $pagelog = new PageChangeLog($id, 1024); $info = $pagelog->getRevisionInfo($rev); - $data = array( + $data = [ 'name' => $id, 'lastModified' => $this->api->toDate($rev), - 'author' => is_array($info) ? (($info['user']) ? $info['user'] : $info['ip']) : null, + 'author' => is_array($info) ? ($info['user'] ?: $info['ip']) : null, 'version' => $rev - ); + ]; return ($data); } @@ -505,16 +530,16 @@ class ApiCore /** * Save a wiki page * - * @author Michael Klier <chi@chimeric.de> - * * @param string $id page id * @param string $text wiki text * @param array $params parameters: summary, minor edit * @return bool * @throws AccessDeniedException no write access for page * @throws RemoteException no id, empty new page or locked + * @author Michael Klier <chi@chimeric.de> + * */ - public function putPage($id, $text, $params = array()) + public function putPage($id, $text, $params = []) { global $TEXT; global $lang; @@ -577,7 +602,7 @@ class ApiCore * @return bool|string * @throws RemoteException */ - public function appendPage($id, $text, $params = array()) + public function appendPage($id, $text, $params = []) { $currentpage = $this->rawPage($id); if (!is_string($currentpage)) { @@ -602,10 +627,10 @@ class ApiCore throw new AccessDeniedException('Only admins are allowed to create users', 114); } - /** @var \dokuwiki\Extension\AuthPlugin $auth */ + /** @var AuthPlugin $auth */ global $auth; - if(!$auth->canDo('addUser')) { + if (!$auth->canDo('addUser')) { throw new AccessDeniedException( sprintf('Authentication backend %s can\'t do addUser', $auth->getPluginName()), 114 @@ -624,22 +649,22 @@ class ApiCore if ($name === '') throw new RemoteException('empty or invalid user name', 402); if (!mail_isvalid($mail)) throw new RemoteException('empty or invalid mail address', 403); - if(strlen($password) === 0) { + if ((string)$password === '') { $password = auth_pwgen($user); } - if (!is_array($groups) || count($groups) === 0) { + if (!is_array($groups) || $groups === []) { $groups = null; } - $ok = $auth->triggerUserMod('create', array($user, $password, $name, $mail, $groups)); + $ok = $auth->triggerUserMod('create', [$user, $password, $name, $mail, $groups]); if ($ok !== false && $ok !== null) { $ok = true; } - if($ok) { - if($notify) { + if ($ok) { + if ($notify) { auth_sendPassword($user, $password); } } @@ -662,9 +687,9 @@ class ApiCore if (!auth_isadmin()) { throw new AccessDeniedException('Only admins are allowed to delete users', 114); } - /** @var \dokuwiki\Extension\AuthPlugin $auth */ + /** @var AuthPlugin $auth */ global $auth; - return (bool)$auth->triggerUserMod('delete', array($usernames)); + return (bool)$auth->triggerUserMod('delete', [$usernames]); } /** @@ -678,7 +703,7 @@ class ApiCore * @return false|string * @throws RemoteException */ - public function putAttachment($id, $file, $params = array()) + public function putAttachment($id, $file, $params = []) { $id = cleanID($id); $auth = auth_quickaclcheck(getNS($id) . ':*'); @@ -695,7 +720,7 @@ class ApiCore @unlink($ftmp); io_saveFile($ftmp, $file); - $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename'); + $res = media_save(['name' => $ftmp], $id, $params['ow'], $auth, 'rename'); if (is_array($res)) { throw new RemoteException($res[0], -$res[1]); } else { @@ -706,12 +731,12 @@ class ApiCore /** * Deletes a file from the wiki. * - * @author Gina Haeussge <osd@foosel.net> - * * @param string $id page id * @return int * @throws AccessDeniedException no permissions * @throws RemoteException file in use or not deleted + * @author Gina Haeussge <osd@foosel.net> + * */ public function deleteAttachment($id) { @@ -739,7 +764,7 @@ class ApiCore */ public function aclCheck($id, $user = null, $groups = null) { - /** @var \dokuwiki\Extension\AuthPlugin $auth */ + /** @var AuthPlugin $auth */ global $auth; $id = $this->resolvePageId($id); @@ -749,7 +774,7 @@ class ApiCore if ($groups === null) { $userinfo = $auth->getUserData($user); if ($userinfo === false) { - $groups = array(); + $groups = []; } else { $groups = $userinfo['grps']; } @@ -761,11 +786,11 @@ class ApiCore /** * Lists all links contained in a wiki page * - * @author Michael Klier <chi@chimeric.de> - * * @param string $id page id * @return array * @throws AccessDeniedException no read access for page + * @author Michael Klier <chi@chimeric.de> + * */ public function listLinks($id) { @@ -773,7 +798,7 @@ class ApiCore if (auth_quickaclcheck($id) < AUTH_READ) { throw new AccessDeniedException('You are not allowed to read this page', 111); } - $links = array(); + $links = []; // resolve page instructions $ins = p_cached_instructions(wikiFN($id)); @@ -784,26 +809,26 @@ class ApiCore // parse parse instructions foreach ($ins as $in) { - $link = array(); + $link = []; switch ($in[0]) { case 'internallink': $link['type'] = 'local'; $link['page'] = $in[1][0]; $link['href'] = wl($in[1][0]); - array_push($links, $link); + $links[] = $link; break; case 'externallink': $link['type'] = 'extern'; $link['page'] = $in[1][0]; $link['href'] = $in[1][0]; - array_push($links, $link); + $links[] = $link; break; case 'interwikilink': $url = $Renderer->_resolveInterWiki($in[1][2], $in[1][3]); $link['type'] = 'extern'; $link['page'] = $url; $link['href'] = $url; - array_push($links, $link); + $links[] = $link; break; } } @@ -814,12 +839,12 @@ class ApiCore /** * Returns a list of recent changes since give timestamp * - * @author Michael Hamann <michael@content-space.de> - * @author Michael Klier <chi@chimeric.de> - * * @param int $timestamp unix timestamp * @return array * @throws RemoteException no valid timestamp + * @author Michael Klier <chi@chimeric.de> + * + * @author Michael Hamann <michael@content-space.de> */ public function getRecentChanges($timestamp) { @@ -829,20 +854,20 @@ class ApiCore $recents = getRecentsSince($timestamp); - $changes = array(); + $changes = []; foreach ($recents as $recent) { - $change = array(); + $change = []; $change['name'] = $recent['id']; $change['lastModified'] = $this->api->toDate($recent['date']); $change['author'] = $recent['user']; $change['version'] = $recent['date']; $change['perms'] = $recent['perms']; $change['size'] = @filesize(wikiFN($recent['id'])); - array_push($changes, $change); + $changes[] = $change; } - if (!empty($changes)) { + if ($changes !== []) { return $changes; } else { // in case we still have nothing at this point @@ -853,12 +878,12 @@ class ApiCore /** * Returns a list of recent media changes since give timestamp * - * @author Michael Hamann <michael@content-space.de> - * @author Michael Klier <chi@chimeric.de> - * * @param int $timestamp unix timestamp * @return array * @throws RemoteException no valid timestamp + * @author Michael Klier <chi@chimeric.de> + * + * @author Michael Hamann <michael@content-space.de> */ public function getRecentMediaChanges($timestamp) { @@ -867,20 +892,20 @@ class ApiCore $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES); - $changes = array(); + $changes = []; foreach ($recents as $recent) { - $change = array(); + $change = []; $change['name'] = $recent['id']; $change['lastModified'] = $this->api->toDate($recent['date']); $change['author'] = $recent['user']; $change['version'] = $recent['date']; $change['perms'] = $recent['perms']; $change['size'] = @filesize(mediaFN($recent['id'])); - array_push($changes, $change); + $changes[] = $change; } - if (!empty($changes)) { + if ($changes !== []) { return $changes; } else { // in case we still have nothing at this point @@ -893,8 +918,6 @@ class ApiCore * Number of returned pages is set by $conf['recent'] * However not accessible pages are skipped, so less than $conf['recent'] could be returned * - * @author Michael Klier <chi@chimeric.de> - * * @param string $id page id * @param int $first skip the first n changelog lines * 0 = from current(if exists) @@ -903,6 +926,8 @@ class ApiCore * @return array * @throws AccessDeniedException no read access for page * @throws RemoteException empty id + * @author Michael Klier <chi@chimeric.de> + * */ public function pageVersions($id, $first = 0) { @@ -912,15 +937,16 @@ class ApiCore } global $conf; - $versions = array(); + $versions = []; if (empty($id)) { throw new RemoteException('Empty page ID', 131); } - $first = (int) $first; + $first = (int)$first; $first_rev = $first - 1; $first_rev = $first_rev < 0 ? 0 : $first_rev; + $pagelog = new PageChangeLog($id); $revisions = $pagelog->getRevisions($first_rev, $conf['recent']); @@ -940,22 +966,22 @@ class ApiCore // specified via $conf['recent'] if ($time) { $pagelog->setChunkSize(1024); - $info = $pagelog->getRevisionInfo($rev ? $rev : $time); + $info = $pagelog->getRevisionInfo($rev ?: $time); if (!empty($info)) { - $data = array(); + $data = []; $data['user'] = $info['user']; $data['ip'] = $info['ip']; $data['type'] = $info['type']; $data['sum'] = $info['sum']; $data['modified'] = $this->api->toDate($info['date']); $data['version'] = $info['date']; - array_push($versions, $data); + $versions[] = $data; } } } return $versions; } else { - return array(); + return []; } } @@ -981,12 +1007,12 @@ class ApiCore */ public function setLocks($set) { - $locked = array(); - $lockfail = array(); - $unlocked = array(); - $unlockfail = array(); + $locked = []; + $lockfail = []; + $unlocked = []; + $unlockfail = []; - foreach ((array) $set['lock'] as $id) { + foreach ($set['lock'] as $id) { $id = $this->resolvePageId($id); if (auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)) { $lockfail[] = $id; @@ -996,7 +1022,7 @@ class ApiCore } } - foreach ((array) $set['unlock'] as $id) { + foreach ($set['unlock'] as $id) { $id = $this->resolvePageId($id); if (auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)) { $unlockfail[] = $id; @@ -1005,12 +1031,12 @@ class ApiCore } } - return array( + return [ 'locked' => $locked, 'lockfail' => $lockfail, 'unlocked' => $unlocked, - 'unlockfail' => $unlockfail, - ); + 'unlockfail' => $unlockfail + ]; } /** @@ -1033,24 +1059,24 @@ class ApiCore public function login($user, $pass) { global $conf; - /** @var \dokuwiki\Extension\AuthPlugin $auth */ + /** @var AuthPlugin $auth */ global $auth; if (!$conf['useacl']) return 0; - if (!$auth) return 0; + if (!$auth instanceof AuthPlugin) return 0; @session_start(); // reopen session for login $ok = null; if ($auth->canDo('external')) { $ok = $auth->trustExternal($user, $pass, false); } - if ($ok === null){ - $evdata = array( + if ($ok === null) { + $evdata = [ 'user' => $user, 'password' => $pass, 'sticky' => false, - 'silent' => true, - ); + 'silent' => true + ]; $ok = Event::createAndTrigger('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper'); } session_write_close(); // we're done with the session @@ -1068,7 +1094,7 @@ class ApiCore global $conf; global $auth; if (!$conf['useacl']) return 0; - if (!$auth) return 0; + if (!$auth instanceof AuthPlugin) return 0; auth_logoff(); diff --git a/inc/Remote/IXR/Client.php b/inc/Remote/IXR/Client.php index 6c34df5d0..9ca664663 100644 --- a/inc/Remote/IXR/Client.php +++ b/inc/Remote/IXR/Client.php @@ -14,7 +14,6 @@ use IXR\Request\Request; */ class Client extends \IXR\Client\Client { - /** @var HTTPClient */ protected $httpClient; @@ -37,9 +36,8 @@ class Client extends \IXR\Client\Client } /** @inheritdoc */ - public function query() + public function query(...$args) { - $args = func_get_args(); $method = array_shift($args); $request = new Request($method, $args); $length = $request->getLength(); diff --git a/inc/Remote/XmlRpcServer.php b/inc/Remote/XmlRpcServer.php index b213cb9d7..e41b5d791 100644 --- a/inc/Remote/XmlRpcServer.php +++ b/inc/Remote/XmlRpcServer.php @@ -17,11 +17,11 @@ class XmlRpcServer extends Server /** * Constructor. Register methods and run Server */ - public function __construct($wait=false) + public function __construct($wait = false) { $this->remote = new Api(); - $this->remote->setDateTransformation(array($this, 'toDate')); - $this->remote->setFileTransformation(array($this, 'toFile')); + $this->remote->setDateTransformation([$this, 'toDate']); + $this->remote->setFileTransformation([$this, 'toFile']); parent::__construct(false, false, $wait); } @@ -51,7 +51,7 @@ class XmlRpcServer extends Server /** * @inheritdoc */ - public function call($methodname, $args) + protected function call($methodname, $args) { try { $result = $this->remote->call($methodname, $args); diff --git a/inc/SafeFN.class.php b/inc/SafeFN.class.php index c5489b185..a383f6d78 100644 --- a/inc/SafeFN.class.php +++ b/inc/SafeFN.class.php @@ -1,5 +1,7 @@ <?php +use dokuwiki\Utf8\Unicode; + /** * Class to safely store UTF-8 in a Filename * @@ -13,8 +15,8 @@ * @author Christopher Smith <chris@jalakai.co.uk> * @date 2010-04-02 */ -class SafeFN { - +class SafeFN +{ // 'safe' characters are a superset of $plain, $pre_indicator and $post_indicator private static $plain = '-./[_0123456789abcdefghijklmnopqrstuvwxyz'; // these characters aren't converted private static $pre_indicator = '%'; @@ -44,8 +46,9 @@ class SafeFN { * * @author Christopher Smith <chris@jalakai.co.uk> */ - public static function encode($filename) { - return self::unicodeToSafe(\dokuwiki\Utf8\Unicode::fromUtf8($filename)); + public static function encode($filename) + { + return self::unicodeToSafe(Unicode::fromUtf8($filename)); } /** @@ -73,16 +76,19 @@ class SafeFN { * * @author Christopher Smith <chris@jalakai.co.uk> */ - public static function decode($filename) { - return \dokuwiki\Utf8\Unicode::toUtf8(self::safeToUnicode(strtolower($filename))); + public static function decode($filename) + { + return Unicode::toUtf8(self::safeToUnicode(strtolower($filename))); } - public static function validatePrintableUtf8($printable_utf8) { - return !preg_match('#[\x01-\x1f]#',$printable_utf8); + public static function validatePrintableUtf8($printable_utf8) + { + return !preg_match('#[\x01-\x1f]#', $printable_utf8); } - public static function validateSafe($safe) { - return !preg_match('#[^'.self::$plain.self::$post_indicator.self::$pre_indicator.']#',$safe); + public static function validateSafe($safe) + { + return !preg_match('#[^' . self::$plain . self::$post_indicator . self::$pre_indicator . ']#', $safe); } /** @@ -93,28 +99,28 @@ class SafeFN { * * @author Christopher Smith <chris@jalakai.co.uk> */ - private static function unicodeToSafe($unicode) { + private static function unicodeToSafe($unicode) + { $safe = ''; $converted = false; foreach ($unicode as $codepoint) { - if ($codepoint < 127 && (strpos(self::$plain.self::$post_indicator,chr($codepoint))!==false)) { + if ($codepoint < 127 && (strpos(self::$plain . self::$post_indicator, chr($codepoint)) !== false)) { if ($converted) { $safe .= self::$post_indicator; $converted = false; } $safe .= chr($codepoint); - - } else if ($codepoint == ord(self::$pre_indicator)) { + } elseif ($codepoint == ord(self::$pre_indicator)) { $safe .= self::$pre_indicator; $converted = true; } else { - $safe .= self::$pre_indicator.base_convert((string)($codepoint-32),10,36); + $safe .= self::$pre_indicator . base_convert((string)($codepoint - 32), 10, 36); $converted = true; } } - if($converted) $safe .= self::$post_indicator; + if ($converted) $safe .= self::$post_indicator; return $safe; } @@ -126,10 +132,16 @@ class SafeFN { * * @author Christopher Smith <chris@jalakai.co.uk> */ - private static function safeToUnicode($safe) { + private static function safeToUnicode($safe) + { - $unicode = array(); - $split = preg_split('#(?=['.self::$post_indicator.self::$pre_indicator.'])#',$safe,-1,PREG_SPLIT_NO_EMPTY); + $unicode = []; + $split = preg_split( + '#(?=[' . self::$post_indicator . self::$pre_indicator . '])#', + $safe, + -1, + PREG_SPLIT_NO_EMPTY + ); $converted = false; foreach ($split as $sub) { @@ -137,22 +149,21 @@ class SafeFN { if ($sub[0] != self::$pre_indicator) { // plain (unconverted) characters, optionally starting with a post_indicator // set initial value to skip any post_indicator - for ($i=($converted?1:0); $i < $len; $i++) { + for ($i = ($converted ? 1 : 0); $i < $len; $i++) { $unicode[] = ord($sub[$i]); } $converted = false; - } else if ($len==1) { + } elseif ($len == 1) { // a pre_indicator character in the real data $unicode[] = ord($sub); $converted = true; } else { // a single codepoint in base36, adjusted for initial 32 non-printable chars - $unicode[] = 32 + (int)base_convert(substr($sub,1),36,10); + $unicode[] = 32 + (int)base_convert(substr($sub, 1), 36, 10); $converted = true; } } return $unicode; } - } diff --git a/inc/Search/Indexer.php b/inc/Search/Indexer.php index 155a804aa..ea7df0f8c 100644 --- a/inc/Search/Indexer.php +++ b/inc/Search/Indexer.php @@ -2,6 +2,9 @@ namespace dokuwiki\Search; +use dokuwiki\Utf8\Asian; +use dokuwiki\Utf8\Clean; +use dokuwiki\Utf8\PhpString; use dokuwiki\Extension\Event; /** @@ -9,11 +12,12 @@ use dokuwiki\Extension\Event; * * @author Tom N Harris <tnharris@whoopdedo.org> */ -class Indexer { +class Indexer +{ /** * @var array $pidCache Cache for getPID() */ - protected $pidCache = array(); + protected $pidCache = []; /** * Adds the contents of a page to the fulltext index @@ -28,7 +32,8 @@ class Indexer { * @author Tom N Harris <tnharris@whoopdedo.org> * @author Andreas Gohr <andi@splitbrain.org> */ - public function addPageWords($page, $text) { + public function addPageWords($page, $text) + { if (!$this->lock()) return "locked"; @@ -39,7 +44,7 @@ class Indexer { return false; } - $pagewords = array(); + $pagewords = []; // get word usage in page $words = $this->getPageWords($text); if ($words === false) { @@ -51,7 +56,7 @@ class Indexer { foreach (array_keys($words) as $wlen) { $index = $this->getIndex('i', $wlen); foreach ($words[$wlen] as $wid => $freq) { - $idx = ($wid<count($index)) ? $index[$wid] : ''; + $idx = ($wid < count($index)) ? $index[$wid] : ''; $index[$wid] = $this->updateTuple($idx, $pid, $freq); $pagewords[] = "$wlen*$wid"; } @@ -65,12 +70,12 @@ class Indexer { // Remove obsolete index entries $pageword_idx = $this->getIndexKey('pageword', '', $pid); if ($pageword_idx !== '') { - $oldwords = explode(':',$pageword_idx); + $oldwords = explode(':', $pageword_idx); $delwords = array_diff($oldwords, $pagewords); - $upwords = array(); + $upwords = []; foreach ($delwords as $word) { if ($word != '') { - list($wlen, $wid) = explode('*', $word); + [$wlen, $wid] = explode('*', $word); $wid = (int)$wid; $upwords[$wlen][] = $wid; } @@ -84,7 +89,7 @@ class Indexer { } } // Save the reverse index - $pageword_idx = join(':', $pagewords); + $pageword_idx = implode(':', $pagewords); if (!$this->saveIndexKey('pageword', '', $pid, $pageword_idx)) { $this->unlock(); return false; @@ -104,23 +109,24 @@ class Indexer { * @author Christopher Smith <chris@jalakai.co.uk> * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function getPageWords($text) { + protected function getPageWords($text) + { $tokens = $this->tokenizer($text); $tokens = array_count_values($tokens); // count the frequency of each token - $words = array(); - foreach ($tokens as $w=>$c) { + $words = []; + foreach ($tokens as $w => $c) { $l = wordlen($w); - if (isset($words[$l])){ - $words[$l][$w] = $c + (isset($words[$l][$w]) ? $words[$l][$w] : 0); - }else{ - $words[$l] = array($w => $c); + if (isset($words[$l])) { + $words[$l][$w] = $c + ($words[$l][$w] ?? 0); + } else { + $words[$l] = [$w => $c]; } } // arrive here with $words = array(wordlen => array(word => frequency)) - $index = array(); //resulting index + $index = []; //resulting index foreach (array_keys($words) as $wlen) { $word_idx = $this->getIndex('w', $wlen); $word_idx_modified = false; @@ -133,7 +139,7 @@ class Indexer { $word_idx_modified = true; } if (!isset($index[$wlen])) - $index[$wlen] = array(); + $index[$wlen] = []; $index[$wlen][$wid] = $freq; } // save back the word index @@ -160,9 +166,10 @@ class Indexer { * @author Tom N Harris <tnharris@whoopdedo.org> * @author Michael Hamann <michael@content-space.de> */ - public function addMetaKeys($page, $key, $value=null) { + public function addMetaKeys($page, $key, $value = null) + { if (!is_array($key)) { - $key = array($key => $value); + $key = [$key => $value]; } elseif (!is_null($value)) { // $key is array, but $value is not null trigger_error("array passed to addMetaKeys but value is not null", E_USER_WARNING); @@ -191,19 +198,19 @@ class Indexer { foreach ($key as $name => $values) { $metaname = idx_cleanName($name); $this->addIndexKey('metadata', '', $metaname); - $metaidx = $this->getIndex($metaname.'_i', ''); - $metawords = $this->getIndex($metaname.'_w', ''); + $metaidx = $this->getIndex($metaname . '_i', ''); + $metawords = $this->getIndex($metaname . '_w', ''); $addwords = false; - if (!is_array($values)) $values = array($values); + if (!is_array($values)) $values = [$values]; - $val_idx = $this->getIndexKey($metaname.'_p', '', $pid); + $val_idx = $this->getIndexKey($metaname . '_p', '', $pid); if ($val_idx !== '') { $val_idx = explode(':', $val_idx); // -1 means remove, 0 keep, 1 add $val_idx = array_combine($val_idx, array_fill(0, count($val_idx), -1)); } else { - $val_idx = array(); + $val_idx = []; } foreach ($values as $val) { @@ -218,7 +225,7 @@ class Indexer { $addwords = true; } // test if value is already in the index - if (isset($val_idx[$id]) && $val_idx[$id] <= 0){ + if (isset($val_idx[$id]) && $val_idx[$id] <= 0) { $val_idx[$id] = 0; } else { // else add it $val_idx[$id] = 1; @@ -227,7 +234,7 @@ class Indexer { } if ($addwords) { - $this->saveIndex($metaname.'_w', '', $metawords); + $this->saveIndex($metaname . '_w', '', $metawords); } $vals_changed = false; foreach ($val_idx as $id => $action) { @@ -242,9 +249,9 @@ class Indexer { } if ($vals_changed) { - $this->saveIndex($metaname.'_i', '', $metaidx); + $this->saveIndex($metaname . '_i', '', $metaidx); $val_idx = implode(':', array_keys($val_idx)); - $this->saveIndexKey($metaname.'_p', '', $pid, $val_idx); + $this->saveIndexKey($metaname . '_p', '', $pid, $val_idx); } unset($metaidx); @@ -264,7 +271,8 @@ class Indexer { * @param string $newpage The new page name * @return string|bool If the page was successfully renamed, can be a message in the case of an error */ - public function renamePage($oldpage, $newpage) { + public function renamePage($oldpage, $newpage) + { if (!$this->lock()) return 'locked'; $pages = $this->getPages(); @@ -278,11 +286,11 @@ class Indexer { $new_id = array_search($newpage, $pages, true); if ($new_id !== false) { // make sure the page is not in the index anymore - if ($this->deletePageNoLock($newpage) !== true) { + if (!$this->deletePageNoLock($newpage)) { return false; } - $pages[$new_id] = 'deleted:'.time().rand(0, 9999); + $pages[$new_id] = 'deleted:' . time() . random_int(0, 9999); } $pages[$id] = $newpage; @@ -294,7 +302,7 @@ class Indexer { } // reset the pid cache - $this->pidCache = array(); + $this->pidCache = []; $this->unlock(); return true; @@ -309,7 +317,8 @@ class Indexer { * @param string $newvalue The new value to which the old value shall be renamed, if exists values will be merged * @return bool|string If renaming the value has been successful, false or error message on error. */ - public function renameMetaValue($key, $oldvalue, $newvalue) { + public function renameMetaValue($key, $oldvalue, $newvalue) + { if (!$this->lock()) return 'locked'; // change the relation references index @@ -319,35 +328,35 @@ class Indexer { $newid = array_search($newvalue, $metavalues, true); if ($newid !== false) { // free memory - unset ($metavalues); + unset($metavalues); // okay, now we have two entries for the same value. we need to merge them. - $indexline = $this->getIndexKey($key.'_i', '', $oldid); + $indexline = $this->getIndexKey($key . '_i', '', $oldid); if ($indexline != '') { - $newindexline = $this->getIndexKey($key.'_i', '', $newid); - $pagekeys = $this->getIndex($key.'_p', ''); + $newindexline = $this->getIndexKey($key . '_i', '', $newid); + $pagekeys = $this->getIndex($key . '_p', ''); $parts = explode(':', $indexline); foreach ($parts as $part) { - list($id, $count) = explode('*', $part); + [$id, $count] = explode('*', $part); $newindexline = $this->updateTuple($newindexline, $id, $count); $keyline = explode(':', $pagekeys[$id]); // remove old meta value - $keyline = array_diff($keyline, array($oldid)); + $keyline = array_diff($keyline, [$oldid]); // add new meta value when not already present if (!in_array($newid, $keyline)) { - array_push($keyline, $newid); + $keyline[] = $newid; } $pagekeys[$id] = implode(':', $keyline); } - $this->saveIndex($key.'_p', '', $pagekeys); + $this->saveIndex($key . '_p', '', $pagekeys); unset($pagekeys); - $this->saveIndexKey($key.'_i', '', $oldid, ''); - $this->saveIndexKey($key.'_i', '', $newid, $newindexline); + $this->saveIndexKey($key . '_i', '', $oldid, ''); + $this->saveIndexKey($key . '_i', '', $newid, $newindexline); } } else { $metavalues[$oldid] = $newvalue; - if (!$this->saveIndex($key.'_w', '', $metavalues)) { + if (!$this->saveIndex($key . '_w', '', $metavalues)) { $this->unlock(); return false; } @@ -368,7 +377,8 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - public function deletePage($page) { + public function deletePage($page) + { if (!$this->lock()) return "locked"; @@ -389,7 +399,8 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function deletePageNoLock($page) { + protected function deletePageNoLock($page) + { // load known documents $pid = $this->getPIDNoLock($page); if ($pid === false) { @@ -399,11 +410,11 @@ class Indexer { // Remove obsolete index entries $pageword_idx = $this->getIndexKey('pageword', '', $pid); if ($pageword_idx !== '') { - $delwords = explode(':',$pageword_idx); - $upwords = array(); + $delwords = explode(':', $pageword_idx); + $upwords = []; foreach ($delwords as $word) { if ($word != '') { - list($wlen,$wid) = explode('*', $word); + [$wlen, $wid] = explode('*', $word); $wid = (int)$wid; $upwords[$wlen][] = $wid; } @@ -424,14 +435,14 @@ class Indexer { $this->saveIndexKey('title', '', $pid, ""); $keyidx = $this->getIndex('metadata', ''); foreach ($keyidx as $metaname) { - $val_idx = explode(':', $this->getIndexKey($metaname.'_p', '', $pid)); - $meta_idx = $this->getIndex($metaname.'_i', ''); + $val_idx = explode(':', $this->getIndexKey($metaname . '_p', '', $pid)); + $meta_idx = $this->getIndex($metaname . '_i', ''); foreach ($val_idx as $id) { if ($id === '') continue; $meta_idx[$id] = $this->updateTuple($meta_idx[$id], $pid, 0); } - $this->saveIndex($metaname.'_i', '', $meta_idx); - $this->saveIndexKey($metaname.'_p', '', $pid, ''); + $this->saveIndex($metaname . '_i', '', $meta_idx); + $this->saveIndexKey($metaname . '_p', '', $pid, ''); } return true; @@ -442,28 +453,34 @@ class Indexer { * * @return bool If the index has been cleared successfully */ - public function clear() { + public function clear() + { global $conf; if (!$this->lock()) return false; - @unlink($conf['indexdir'].'/page.idx'); - @unlink($conf['indexdir'].'/title.idx'); - @unlink($conf['indexdir'].'/pageword.idx'); - @unlink($conf['indexdir'].'/metadata.idx'); + @unlink($conf['indexdir'] . '/page.idx'); + @unlink($conf['indexdir'] . '/title.idx'); + @unlink($conf['indexdir'] . '/pageword.idx'); + @unlink($conf['indexdir'] . '/metadata.idx'); $dir = @opendir($conf['indexdir']); - if($dir!==false){ - while(($f = readdir($dir)) !== false){ - if(substr($f,-4)=='.idx' && - (substr($f,0,1)=='i' || substr($f,0,1)=='w' - || substr($f,-6)=='_w.idx' || substr($f,-6)=='_i.idx' || substr($f,-6)=='_p.idx')) - @unlink($conf['indexdir']."/$f"); + if ($dir !== false) { + while (($f = readdir($dir)) !== false) { + if ( + substr($f, -4) == '.idx' && + (substr($f, 0, 1) == 'i' || + substr($f, 0, 1) == 'w' || + substr($f, -6) == '_w.idx' || + substr($f, -6) == '_i.idx' || + substr($f, -6) == '_p.idx') + ) + @unlink($conf['indexdir'] . "/$f"); } } - @unlink($conf['indexdir'].'/lengths.idx'); + @unlink($conf['indexdir'] . '/lengths.idx'); // clear the pid cache - $this->pidCache = array(); + $this->pidCache = []; $this->unlock(); return true; @@ -485,7 +502,8 @@ class Indexer { * @author Tom N Harris <tnharris@whoopdedo.org> * @author Andreas Gohr <andi@splitbrain.org> */ - public function tokenizer($text, $wc=false) { + public function tokenizer($text, $wc = false) + { $wc = ($wc) ? '' : '\*'; $stopwords =& idx_get_stopwords(); @@ -493,32 +511,30 @@ class Indexer { $evt = new Event('INDEXER_TEXT_PREPARE', $text); if ($evt->advise_before(true)) { if (preg_match('/[^0-9A-Za-z ]/u', $text)) { - $text = \dokuwiki\Utf8\Asian::separateAsianWords($text); + $text = Asian::separateAsianWords($text); } } $evt->advise_after(); unset($evt); - $text = strtr($text, - array( - "\r" => ' ', - "\n" => ' ', - "\t" => ' ', - "\xC2\xAD" => '', //soft-hyphen - ) + $text = strtr( + $text, + ["\r" => ' ', "\n" => ' ', "\t" => ' ', "\xC2\xAD" => ''] ); if (preg_match('/[^0-9A-Za-z ]/u', $text)) - $text = \dokuwiki\Utf8\Clean::stripspecials($text, ' ', '\._\-:'.$wc); + $text = Clean::stripspecials($text, ' ', '\._\-:' . $wc); $wordlist = explode(' ', $text); foreach ($wordlist as $i => $word) { $wordlist[$i] = (preg_match('/[^0-9A-Za-z]/u', $word)) ? - \dokuwiki\Utf8\PhpString::strtolower($word) : strtolower($word); + PhpString::strtolower($word) : strtolower($word); } foreach ($wordlist as $i => $word) { - if ((!is_numeric($word) && strlen($word) < IDX_MINWORDLENGTH) - || array_search($word, $stopwords, true) !== false) + if ( + (!is_numeric($word) && strlen($word) < IDX_MINWORDLENGTH) + || in_array($word, $stopwords, true) + ) unset($wordlist[$i]); } return array_values($wordlist); @@ -530,7 +546,8 @@ class Indexer { * @param string $page The page to get the PID for * @return bool|int The page id on success, false on error */ - public function getPID($page) { + public function getPID($page) + { // return PID without locking when it is in the cache if (isset($this->pidCache[$page])) return $this->pidCache[$page]; @@ -555,7 +572,8 @@ class Indexer { * @param string $page The page to get the PID for * @return bool|int The page id on success, false on error */ - protected function getPIDNoLock($page) { + protected function getPIDNoLock($page) + { // avoid expensive addIndexKey operation for the most recently requested pages by using a cache if (isset($this->pidCache[$page])) return $this->pidCache[$page]; $pid = $this->addIndexKey('page', '', $page); @@ -572,7 +590,8 @@ class Indexer { * @param int $pid The PID to get the page id for * @return string The page id */ - public function getPageFromPID($pid) { + public function getPageFromPID($pid) + { return $this->getIndexKey('page', '', $pid); } @@ -592,25 +611,26 @@ class Indexer { * @author Tom N Harris <tnharris@whoopdedo.org> * @author Andreas Gohr <andi@splitbrain.org> */ - public function lookup(&$tokens) { - $result = array(); + public function lookup(&$tokens) + { + $result = []; $wids = $this->getIndexWords($tokens, $result); - if (empty($wids)) return array(); + if (empty($wids)) return []; // load known words and documents $page_idx = $this->getIndex('page', ''); - $docs = array(); + $docs = []; foreach (array_keys($wids) as $wlen) { $wids[$wlen] = array_unique($wids[$wlen]); $index = $this->getIndex('i', $wlen); - foreach($wids[$wlen] as $ixid) { + foreach ($wids[$wlen] as $ixid) { if ($ixid < count($index)) $docs["$wlen*$ixid"] = $this->parseTuples($page_idx, $index[$ixid]); } } // merge found pages into final result array - $final = array(); + $final = []; foreach ($result as $word => $res) { - $final[$word] = array(); + $final[$word] = []; foreach ($res as $wid) { // handle the case when ($ixid < count($index)) has been false // and thus $docs[$wid] hasn't been set. @@ -621,8 +641,7 @@ class Indexer { if (!page_exists($hitkey, '', false)) continue; if (!isset($final[$word][$hitkey])) $final[$word][$hitkey] = $hitcnt; - else - $final[$word][$hitkey] += $hitcnt; + else $final[$word][$hitkey] += $hitcnt; } } } @@ -647,14 +666,14 @@ class Indexer { * @author Tom N Harris <tnharris@whoopdedo.org> * @author Michael Hamann <michael@content-space.de> */ - public function lookupKey($key, &$value, $func=null) { + public function lookupKey($key, &$value, $func = null) + { if (!is_array($value)) - $value_array = array($value); - else - $value_array =& $value; + $value_array = [$value]; + else $value_array =& $value; // the matching ids for the provided value(s) - $value_ids = array(); + $value_ids = []; $metaname = idx_cleanName($key); @@ -662,13 +681,13 @@ class Indexer { if ($key == 'title') { $words = $this->getIndex('title', ''); } else { - $words = $this->getIndex($metaname.'_w', ''); + $words = $this->getIndex($metaname . '_w', ''); } if (!is_null($func)) { foreach ($value_array as $val) { foreach ($words as $i => $word) { - if (call_user_func_array($func, array($val, $word))) + if (call_user_func_array($func, [$val, $word])) $value_ids[$i][] = $val; } } @@ -687,12 +706,11 @@ class Indexer { $dollar = ''; } if (!$caret || !$dollar) { - $re = $caret.preg_quote($xval, '/').$dollar; - foreach(array_keys(preg_grep('/'.$re.'/', $words)) as $i) - $value_ids[$i][] = $val; - } else { - if (($i = array_search($val, $words, true)) !== false) + $re = $caret . preg_quote($xval, '/') . $dollar; + foreach (array_keys(preg_grep('/' . $re . '/', $words)) as $i) $value_ids[$i][] = $val; + } elseif (($i = array_search($val, $words, true)) !== false) { + $value_ids[$i][] = $val; } } } @@ -700,9 +718,9 @@ class Indexer { unset($words); // free the used memory // initialize the result so it won't be null - $result = array(); + $result = []; foreach ($value_array as $val) { - $result[$val] = array(); + $result[$val] = []; } $page_idx = $this->getIndex('page', ''); @@ -717,14 +735,14 @@ class Indexer { } } else { // load all lines and pages so the used lines can be taken and matched with the pages - $lines = $this->getIndex($metaname.'_i', ''); + $lines = $this->getIndex($metaname . '_i', ''); foreach ($value_ids as $value_id => $val_list) { // parse the tuples of the form page_id*1:page2_id*1 and so on, return value // is an array with page_id => 1, page2_id => 1 etc. so take the keys only $pages = array_keys($this->parseTuples($page_idx, $lines[$value_id])); foreach ($val_list as $val) { - $result[$val] = array_merge($result[$val], $pages); + $result[$val] = [...$result[$val], ...$pages]; } } } @@ -746,12 +764,13 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function getIndexWords(&$words, &$result) { - $tokens = array(); - $tokenlength = array(); - $tokenwild = array(); + protected function getIndexWords(&$words, &$result) + { + $tokens = []; + $tokenlength = []; + $tokenwild = []; foreach ($words as $word) { - $result[$word] = array(); + $result[$word] = []; $caret = '^'; $dollar = '$'; $xword = $word; @@ -761,35 +780,35 @@ class Indexer { if (substr($xword, 0, 1) == '*') { $xword = substr($xword, 1); $caret = ''; - $wlen -= 1; + --$wlen; } if (substr($xword, -1, 1) == '*') { $xword = substr($xword, 0, -1); $dollar = ''; - $wlen -= 1; + --$wlen; } if ($wlen < IDX_MINWORDLENGTH && $caret && $dollar && !is_numeric($xword)) continue; if (!isset($tokens[$xword])) $tokenlength[$wlen][] = $xword; if (!$caret || !$dollar) { - $re = $caret.preg_quote($xword, '/').$dollar; - $tokens[$xword][] = array($word, '/'.$re.'/'); + $re = $caret . preg_quote($xword, '/') . $dollar; + $tokens[$xword][] = [$word, '/' . $re . '/']; if (!isset($tokenwild[$xword])) $tokenwild[$xword] = $wlen; } else { - $tokens[$xword][] = array($word, null); + $tokens[$xword][] = [$word, null]; } } asort($tokenwild); // $tokens = array( base word => array( [ query term , regexp ] ... ) ... ) // $tokenlength = array( base word length => base word ... ) // $tokenwild = array( base word => base word length ... ) - $length_filter = empty($tokenwild) ? $tokenlength : min(array_keys($tokenlength)); + $length_filter = $tokenwild === [] ? $tokenlength : min(array_keys($tokenlength)); $indexes_known = $this->indexLengths($length_filter); - if (!empty($tokenwild)) sort($indexes_known); + if ($tokenwild !== []) sort($indexes_known); // get word IDs - $wids = array(); + $wids = []; foreach ($indexes_known as $ixlen) { $word_idx = $this->getIndex('w', $ixlen); // handle exact search @@ -808,7 +827,7 @@ class Indexer { if ($wlen >= $ixlen) break; foreach ($tokens[$xword] as $w) { if (is_null($w[1])) continue; - foreach(array_keys(preg_grep($w[1], $word_idx)) as $wid) { + foreach (array_keys(preg_grep($w[1], $word_idx)) as $wid) { $wids[$ixlen][] = $wid; $result[$w[0]][] = "$ixlen*$wid"; } @@ -827,7 +846,8 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - public function getPages($key=null) { + public function getPages($key = null) + { $page_idx = $this->getIndex('page', ''); if (is_null($key)) return $page_idx; @@ -842,8 +862,8 @@ class Indexer { return array_values($page_idx); } - $pages = array(); - $lines = $this->getIndex($metaname.'_i', ''); + $pages = []; + $lines = $this->getIndex($metaname . '_i', ''); foreach ($lines as $line) { $pages = array_merge($pages, $this->parseTuples($page_idx, $line)); } @@ -861,13 +881,14 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - public function histogram($min=1, $max=0, $minlen=3, $key=null) { + public function histogram($min = 1, $max = 0, $minlen = 3, $key = null) + { if ($min < 1) $min = 1; if ($max < $min) $max = 0; - $result = array(); + $result = []; if ($key == 'title') { $index = $this->getIndex('title', ''); @@ -876,25 +897,23 @@ class Indexer { if ($cnt >= $min && (!$max || $cnt <= $max) && strlen($val) >= $minlen) $result[$val] = $cnt; } - } - elseif (!is_null($key)) { + } elseif (!is_null($key)) { $metaname = idx_cleanName($key); - $index = $this->getIndex($metaname.'_i', ''); - $val_idx = array(); + $index = $this->getIndex($metaname . '_i', ''); + $val_idx = []; foreach ($index as $wid => $line) { $freq = $this->countTuples($line); if ($freq >= $min && (!$max || $freq <= $max)) $val_idx[$wid] = $freq; } if (!empty($val_idx)) { - $words = $this->getIndex($metaname.'_w', ''); + $words = $this->getIndex($metaname . '_w', ''); foreach ($val_idx as $wid => $freq) { if (strlen($words[$wid]) >= $minlen) $result[$words[$wid]] = $freq; } } - } - else { + } else { $lengths = idx_listIndexLengths(); foreach ($lengths as $length) { if ($length < $minlen) continue; @@ -922,14 +941,15 @@ class Indexer { * * @return bool|string */ - protected function lock() { + protected function lock() + { global $conf; $status = true; $run = 0; - $lock = $conf['lockdir'].'/_indexer.lock'; + $lock = $conf['lockdir'] . '/_indexer.lock'; while (!@mkdir($lock)) { usleep(50); - if(is_dir($lock) && time()-@filemtime($lock) > 60*5){ + if (is_dir($lock) && time() - @filemtime($lock) > 60 * 5) { // looks like a stale lock - remove it if (!@rmdir($lock)) { $status = "removing the stale lock failed"; @@ -937,7 +957,7 @@ class Indexer { } else { $status = "stale lock removed"; } - }elseif($run++ == 1000){ + } elseif ($run++ == 1000) { // we waited 5 seconds for that lock return false; } @@ -955,9 +975,10 @@ class Indexer { * * @return bool */ - protected function unlock() { + protected function unlock() + { global $conf; - @rmdir($conf['lockdir'].'/_indexer.lock'); + @rmdir($conf['lockdir'] . '/_indexer.lock'); return true; } @@ -974,10 +995,11 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function getIndex($idx, $suffix) { + protected function getIndex($idx, $suffix) + { global $conf; - $fn = $conf['indexdir'].'/'.$idx.$suffix.'.idx'; - if (!file_exists($fn)) return array(); + $fn = $conf['indexdir'] . '/' . $idx . $suffix . '.idx'; + if (!file_exists($fn)) return []; return file($fn, FILE_IGNORE_NEW_LINES); } @@ -991,18 +1013,19 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function saveIndex($idx, $suffix, &$lines) { + protected function saveIndex($idx, $suffix, &$lines) + { global $conf; - $fn = $conf['indexdir'].'/'.$idx.$suffix; - $fh = @fopen($fn.'.tmp', 'w'); + $fn = $conf['indexdir'] . '/' . $idx . $suffix; + $fh = @fopen($fn . '.tmp', 'w'); if (!$fh) return false; - fwrite($fh, join("\n", $lines)); + fwrite($fh, implode("\n", $lines)); if (!empty($lines)) fwrite($fh, "\n"); fclose($fh); if ($conf['fperm']) - chmod($fn.'.tmp', $conf['fperm']); - io_rename($fn.'.tmp', $fn.'.idx'); + chmod($fn . '.tmp', $conf['fperm']); + io_rename($fn . '.tmp', $fn . '.idx'); return true; } @@ -1016,9 +1039,10 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function getIndexKey($idx, $suffix, $id) { + protected function getIndexKey($idx, $suffix, $id) + { global $conf; - $fn = $conf['indexdir'].'/'.$idx.$suffix.'.idx'; + $fn = $conf['indexdir'] . '/' . $idx . $suffix . '.idx'; if (!file_exists($fn)) return ''; $fh = @fopen($fn, 'r'); if (!$fh) return ''; @@ -1041,14 +1065,15 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function saveIndexKey($idx, $suffix, $id, $line) { + protected function saveIndexKey($idx, $suffix, $id, $line) + { global $conf; if (substr($line, -1) != "\n") $line .= "\n"; - $fn = $conf['indexdir'].'/'.$idx.$suffix; - $fh = @fopen($fn.'.tmp', 'w'); + $fn = $conf['indexdir'] . '/' . $idx . $suffix; + $fh = @fopen($fn . '.tmp', 'w'); if (!$fh) return false; - $ih = @fopen($fn.'.idx', 'r'); + $ih = @fopen($fn . '.idx', 'r'); if ($ih) { $ln = -1; while (($curline = fgets($ih)) !== false) { @@ -1068,8 +1093,8 @@ class Indexer { } fclose($fh); if ($conf['fperm']) - chmod($fn.'.tmp', $conf['fperm']); - io_rename($fn.'.tmp', $fn.'.idx'); + chmod($fn . '.tmp', $conf['fperm']); + io_rename($fn . '.tmp', $fn . '.idx'); return true; } @@ -1083,7 +1108,8 @@ class Indexer { * * @author Tom N Harris <tnharris@whoopdedo.org> */ - protected function addIndexKey($idx, $suffix, $value) { + protected function addIndexKey($idx, $suffix, $value) + { $index = $this->getIndex($idx, $suffix); $id = array_search($value, $index, true); if ($id === false) { @@ -1107,7 +1133,8 @@ class Indexer { * * @return array */ - protected function listIndexLengths() { + protected function listIndexLengths() + { return idx_listIndexLengths(); } @@ -1122,19 +1149,20 @@ class Indexer { * @param array|int $filter * @return array */ - protected function indexLengths($filter) { + protected function indexLengths($filter) + { global $conf; - $idx = array(); + $idx = []; if (is_array($filter)) { // testing if index files exist only - $path = $conf['indexdir']."/i"; - foreach ($filter as $key => $value) { - if (file_exists($path.$key.'.idx')) + $path = $conf['indexdir'] . "/i"; + foreach (array_keys($filter) as $key) { + if (file_exists($path . $key . '.idx')) $idx[] = $key; } } else { $lengths = idx_listIndexLengths(); - foreach ($lengths as $key => $length) { + foreach ($lengths as $length) { // keep all the values equal or superior if ((int)$length >= (int)$filter) $idx[] = $length; @@ -1153,14 +1181,15 @@ class Indexer { * @param int $count * @return string */ - protected function updateTuple($line, $id, $count) { - if ($line != ''){ - $line = preg_replace('/(^|:)'.preg_quote($id,'/').'\*\d*/', '', $line); + protected function updateTuple($line, $id, $count) + { + if ($line != '') { + $line = preg_replace('/(^|:)' . preg_quote($id, '/') . '\*\d*/', '', $line); } $line = trim($line, ':'); if ($count) { if ($line) { - return "$id*$count:".$line; + return "$id*$count:" . $line; } else { return "$id*$count"; } @@ -1178,13 +1207,14 @@ class Indexer { * @param string $line * @return array */ - protected function parseTuples(&$keys, $line) { - $result = array(); + protected function parseTuples(&$keys, $line) + { + $result = []; if ($line == '') return $result; $parts = explode(':', $line); foreach ($parts as $tuple) { if ($tuple === '') continue; - list($key, $cnt) = explode('*', $tuple); + [$key, $cnt] = explode('*', $tuple); if (!$cnt) continue; if (isset($keys[$key])) { $key = $keys[$key]; @@ -1203,12 +1233,13 @@ class Indexer { * @param string $line * @return int */ - protected function countTuples($line) { + protected function countTuples($line) + { $freq = 0; $parts = explode(':', $line); foreach ($parts as $tuple) { if ($tuple === '') continue; - list(/* $pid */, $cnt) = explode('*', $tuple); + [/* pid */, $cnt] = explode('*', $tuple); $freq += (int)$cnt; } return $freq; diff --git a/inc/Sitemap/Item.php b/inc/Sitemap/Item.php index d11bfc135..c8e602fbe 100644 --- a/inc/Sitemap/Item.php +++ b/inc/Sitemap/Item.php @@ -7,7 +7,8 @@ namespace dokuwiki\Sitemap; * * @author Michael Hamann */ -class Item { +class Item +{ public $url; public $lastmod; public $changefreq; @@ -23,7 +24,8 @@ class Item { * @param $priority float|string The priority of the item relative to other URLs on your site. * Valid values range from 0.0 to 1.0. */ - public function __construct($url, $lastmod, $changefreq = null, $priority = null) { + public function __construct($url, $lastmod, $changefreq = null, $priority = null) + { $this->url = $url; $this->lastmod = $lastmod; $this->changefreq = $changefreq; @@ -40,10 +42,11 @@ class Item { * Valid values range from 0.0 to 1.0. * @return Item The sitemap item. */ - public static function createFromID($id, $changefreq = null, $priority = null) { + public static function createFromID($id, $changefreq = null, $priority = null) + { $id = trim($id); $date = @filemtime(wikiFN($id)); - if(!$date) return null; + if (!$date) return null; return new Item(wl($id, '', true), $date, $changefreq, $priority); } @@ -52,15 +55,16 @@ class Item { * * @return string The XML representation. */ - public function toXML() { - $result = ' <url>'.NL - .' <loc>'.hsc($this->url).'</loc>'.NL - .' <lastmod>'.date_iso8601($this->lastmod).'</lastmod>'.NL; + public function toXML() + { + $result = ' <url>' . NL + . ' <loc>' . hsc($this->url) . '</loc>' . NL + . ' <lastmod>' . date_iso8601($this->lastmod) . '</lastmod>' . NL; if ($this->changefreq !== null) - $result .= ' <changefreq>'.hsc($this->changefreq).'</changefreq>'.NL; + $result .= ' <changefreq>' . hsc($this->changefreq) . '</changefreq>' . NL; if ($this->priority !== null) - $result .= ' <priority>'.hsc($this->priority).'</priority>'.NL; - $result .= ' </url>'.NL; + $result .= ' <priority>' . hsc($this->priority) . '</priority>' . NL; + $result .= ' </url>' . NL; return $result; } } diff --git a/inc/Sitemap/Mapper.php b/inc/Sitemap/Mapper.php index afa1b2881..917fdd636 100644 --- a/inc/Sitemap/Mapper.php +++ b/inc/Sitemap/Mapper.php @@ -1,4 +1,5 @@ <?php + /** * Sitemap handling functions * @@ -8,6 +9,7 @@ namespace dokuwiki\Sitemap; +use dokuwiki\Extension\Event; use dokuwiki\HTTP\DokuHTTPClient; use dokuwiki\Logger; @@ -16,7 +18,8 @@ use dokuwiki\Logger; * * @author Michael Hamann */ -class Mapper { +class Mapper +{ /** * Builds a Google Sitemap of all public pages known to the indexer * @@ -30,20 +33,23 @@ class Mapper { * * @return bool */ - public static function generate(){ + public static function generate() + { global $conf; - if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) return false; + if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) return false; $sitemap = Mapper::getFilePath(); - if(file_exists($sitemap)){ - if(!is_writable($sitemap)) return false; - }else{ - if(!is_writable(dirname($sitemap))) return false; + if (file_exists($sitemap)) { + if (!is_writable($sitemap)) return false; + } elseif (!is_writable(dirname($sitemap))) { + return false; } - if(@filesize($sitemap) && - @filemtime($sitemap) > (time()-($conf['sitemap']*86400))){ // 60*60*24=86400 + if ( + @filesize($sitemap) && + @filemtime($sitemap) > (time() - ($conf['sitemap'] * 86400)) + ) { // 60*60*24=86400 Logger::debug('Sitemapper::generate(): Sitemap up to date'); return false; } @@ -51,24 +57,24 @@ class Mapper { Logger::debug("Sitemapper::generate(): using $sitemap"); $pages = idx_get_indexer()->getPages(); - Logger::debug('Sitemapper::generate(): creating sitemap using '.count($pages).' pages'); - $items = array(); + Logger::debug('Sitemapper::generate(): creating sitemap using ' . count($pages) . ' pages'); + $items = []; // build the sitemap items - foreach($pages as $id){ + foreach ($pages as $id) { //skip hidden, non existing and restricted files - if(isHiddenPage($id)) continue; - if(auth_aclcheck($id,'',array()) < AUTH_READ) continue; + if (isHiddenPage($id)) continue; + if (auth_aclcheck($id, '', []) < AUTH_READ) continue; $item = Item::createFromID($id); - if ($item !== null) + if ($item instanceof Item) $items[] = $item; } - $eventData = array('items' => &$items, 'sitemap' => &$sitemap); - $event = new \dokuwiki\Extension\Event('SITEMAP_GENERATE', $eventData); + $eventData = ['items' => &$items, 'sitemap' => &$sitemap]; + $event = new Event('SITEMAP_GENERATE', $eventData); if ($event->advise_before(true)) { //save the new sitemap - $event->result = io_saveFile($sitemap, Mapper::getXML($items)); + $event->result = io_saveFile($sitemap, (new Mapper())->getXML($items)); } $event->advise_after(); @@ -83,15 +89,16 @@ class Mapper { * * @author Michael Hamann */ - private static function getXML($items) { + private function getXML($items) + { ob_start(); - echo '<?xml version="1.0" encoding="UTF-8"?>'.NL; - echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'.NL; + echo '<?xml version="1.0" encoding="UTF-8"?>' . NL; + echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . NL; foreach ($items as $item) { /** @var Item $item */ echo $item->toXML(); } - echo '</urlset>'.NL; + echo '</urlset>' . NL; $result = ob_get_contents(); ob_end_clean(); return $result; @@ -104,10 +111,11 @@ class Mapper { * * @author Michael Hamann */ - public static function getFilePath() { + public static function getFilePath() + { global $conf; - $sitemap = $conf['cachedir'].'/sitemap.xml'; + $sitemap = $conf['cachedir'] . '/sitemap.xml'; if (self::sitemapIsCompressed()) { $sitemap .= '.gz'; } @@ -120,7 +128,8 @@ class Mapper { * * @return bool If the sitemap file is compressed */ - public static function sitemapIsCompressed() { + public static function sitemapIsCompressed() + { global $conf; return $conf['compression'] === 'bz2' || $conf['compression'] === 'gz'; } @@ -133,26 +142,28 @@ class Mapper { * * @return bool */ - public static function pingSearchEngines() { + public static function pingSearchEngines() + { //ping search engines... $http = new DokuHTTPClient(); $http->timeout = 8; - $encoded_sitemap_url = urlencode(wl('', array('do' => 'sitemap'), true, '&')); - $ping_urls = array( - 'google' => 'https://www.google.com/ping?sitemap='.$encoded_sitemap_url, - 'yandex' => 'https://webmaster.yandex.com/ping?sitemap='.$encoded_sitemap_url - ); - - $data = array('ping_urls' => $ping_urls, - 'encoded_sitemap_url' => $encoded_sitemap_url - ); - $event = new \dokuwiki\Extension\Event('SITEMAP_PING', $data); + $encoded_sitemap_url = urlencode(wl('', ['do' => 'sitemap'], true, '&')); + $ping_urls = [ + 'google' => 'https://www.google.com/ping?sitemap=' . $encoded_sitemap_url, + 'yandex' => 'https://webmaster.yandex.com/ping?sitemap=' . $encoded_sitemap_url + ]; + + $data = [ + 'ping_urls' => $ping_urls, + 'encoded_sitemap_url' => $encoded_sitemap_url + ]; + $event = new Event('SITEMAP_PING', $data); if ($event->advise_before(true)) { foreach ($data['ping_urls'] as $name => $url) { Logger::debug("Sitemapper::PingSearchEngines(): pinging $name"); $resp = $http->get($url); - if($http->error) { + if ($http->error) { Logger::debug("Sitemapper:pingSearchengines(): $http->error", $resp); } } @@ -162,4 +173,3 @@ class Mapper { return true; } } - diff --git a/inc/StyleUtils.php b/inc/StyleUtils.php index d5a34623a..eb078562a 100644 --- a/inc/StyleUtils.php +++ b/inc/StyleUtils.php @@ -9,7 +9,6 @@ namespace dokuwiki; */ class StyleUtils { - /** @var string current template */ protected $tpl; /** @var bool reinitialize styles config */ @@ -17,7 +16,7 @@ class StyleUtils /** @var bool $preview preview mode */ protected $preview; /** @var array default replacements to be merged with custom style configs */ - protected $defaultReplacements = array( + protected $defaultReplacements = [ '__text__' => "#000", '__background__' => "#fff", '__text_alt__' => "#999", @@ -26,8 +25,8 @@ class StyleUtils '__background_neu__' => "#ddd", '__border__' => "#ccc", '__highlight__' => "#ff9", - '__link__' => "#00f", - ); + '__link__' => "#00f" + ]; /** * StyleUtils constructor. @@ -66,7 +65,7 @@ class StyleUtils global $conf; global $config_cascade; - $stylesheets = array(); // mode, file => base + $stylesheets = []; // mode, file => base // guaranteed placeholder => value $replacements = $this->defaultReplacements; @@ -84,7 +83,7 @@ class StyleUtils $combined['stylesheets'] = []; $combined['replacements'] = []; - foreach (array('default', 'local', 'protected') as $config_group) { + foreach (['default', 'local', 'protected'] as $config_group) { if (empty($config_cascade['styleini'][$config_group])) continue; // set proper server dirs @@ -138,7 +137,7 @@ class StyleUtils { global $conf; if (!file_exists($incbase . $file)) { - list($extension, $basename) = array_map('strrev', sexplode('.', strrev($file), 2, '')); + [$extension, $basename] = array_map('strrev', sexplode('.', strrev($file), 2, '')); $newExtension = $extension === 'css' ? 'less' : 'css'; if (file_exists($incbase . $basename . '.' . $newExtension)) { $stylesheets[$mode][$incbase . $basename . '.' . $newExtension] = $webbase; diff --git a/inc/Subscriptions/BulkSubscriptionSender.php b/inc/Subscriptions/BulkSubscriptionSender.php index d0ae2bf1e..df6141007 100644 --- a/inc/Subscriptions/BulkSubscriptionSender.php +++ b/inc/Subscriptions/BulkSubscriptionSender.php @@ -1,16 +1,14 @@ <?php - namespace dokuwiki\Subscriptions; - use dokuwiki\ChangeLog\PageChangeLog; +use dokuwiki\Extension\AuthPlugin; use dokuwiki\Input\Input; -use DokuWiki_Auth_Plugin; +use Exception; class BulkSubscriptionSender extends SubscriptionSender { - /** * Send digest and list subscriptions * @@ -20,8 +18,8 @@ class BulkSubscriptionSender extends SubscriptionSender * This function is called form lib/exe/indexer.php * * @param string $page - * * @return int number of sent mails + * @throws Exception */ public function sendBulk($page) { @@ -30,7 +28,7 @@ class BulkSubscriptionSender extends SubscriptionSender return 0; } - /** @var DokuWiki_Auth_Plugin $auth */ + /** @var AuthPlugin $auth */ global $auth; global $conf; global $USERINFO; @@ -50,7 +48,7 @@ class BulkSubscriptionSender extends SubscriptionSender } foreach ($users as $user => $info) { - list($style, $lastupdate) = $info; + [$style, $lastupdate] = $info; $lastupdate = (int)$lastupdate; if ($lastupdate + $conf['subscribe_time'] > time()) { @@ -86,12 +84,13 @@ class BulkSubscriptionSender extends SubscriptionSender foreach ($changes as $rev) { $n = 0; $pagelog = new PageChangeLog($rev['id']); - while (!is_null($rev) && $rev['date'] >= $lastupdate && + while ( + !is_null($rev) && $rev['date'] >= $lastupdate && ($INPUT->server->str('REMOTE_USER') === $rev['user'] || $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ) { $revisions = $pagelog->getRevisions($n++, 1); - $rev = (count($revisions) > 0) ? $pagelog->getRevisionInfo($revisions[0]) : null; + $rev = ($revisions !== []) ? $pagelog->getRevisionInfo($revisions[0]) : null; } if (!is_null($rev) && $rev['date'] >= $lastupdate) { @@ -110,11 +109,9 @@ class BulkSubscriptionSender extends SubscriptionSender ); $count++; } - } else { - if ($style === 'list') { - $this->sendList($USERINFO['mail'], $change_ids, $target); - $count++; - } + } elseif ($style === 'list') { + $this->sendList($USERINFO['mail'], $change_ids, $target); + $count++; } // TODO: Handle duplicate subscriptions. @@ -199,7 +196,7 @@ class BulkSubscriptionSender extends SubscriptionSender $n = 0; do { $rev = $pagelog->getRevisions($n++, 1); - $rev = (count($rev) > 0) ? $rev[0] : null; + $rev = ($rev !== []) ? $rev[0] : null; } while (!is_null($rev) && $rev > $lastupdate); // TODO I'm not happy with the following line and passing $this->mailer around. Not sure how to solve it better @@ -227,7 +224,7 @@ class BulkSubscriptionSender extends SubscriptionSender */ protected function sendList($subscriber_mail, $ids, $ns_id) { - if (count($ids) === 0) { + if ($ids === []) { return false; } diff --git a/inc/Subscriptions/MediaSubscriptionSender.php b/inc/Subscriptions/MediaSubscriptionSender.php index 1757c2b1c..84497c071 100644 --- a/inc/Subscriptions/MediaSubscriptionSender.php +++ b/inc/Subscriptions/MediaSubscriptionSender.php @@ -1,12 +1,9 @@ <?php - namespace dokuwiki\Subscriptions; - class MediaSubscriptionSender extends SubscriptionSender { - /** * Send the diff for some media change * @@ -23,11 +20,11 @@ class MediaSubscriptionSender extends SubscriptionSender global $conf; $file = mediaFN($id); - list($mime, /* $ext */) = mimetype($id); + [$mime, /* ext */] = mimetype($id); $trep = [ 'MIME' => $mime, - 'MEDIA' => ml($id, $current_rev?('rev='.$current_rev):'', true, '&', true), + 'MEDIA' => ml($id, $current_rev ? ('rev=' . $current_rev) : '', true, '&', true), 'SIZE' => filesize_h(filesize($file)), ]; diff --git a/inc/Subscriptions/PageSubscriptionSender.php b/inc/Subscriptions/PageSubscriptionSender.php index e5577c1af..dbdc454ac 100644 --- a/inc/Subscriptions/PageSubscriptionSender.php +++ b/inc/Subscriptions/PageSubscriptionSender.php @@ -1,16 +1,13 @@ <?php - namespace dokuwiki\Subscriptions; - use Diff; use InlineDiffFormatter; use UnifiedDiffFormatter; class PageSubscriptionSender extends SubscriptionSender { - /** * Send the diff for some page change * @@ -30,7 +27,7 @@ class PageSubscriptionSender extends SubscriptionSender // prepare replacements (keys not set in hrep will be taken from trep) $trep = [ 'PAGE' => $id, - 'NEWPAGE' => wl($id, $current_rev?('rev='.$current_rev):'', true, '&'), + 'NEWPAGE' => wl($id, $current_rev ? ('rev=' . $current_rev) : '', true, '&'), 'SUMMARY' => $summary, 'SUBSCRIBE' => wl($id, ['do' => 'subscribe'], true, '&'), ]; @@ -84,5 +81,4 @@ class PageSubscriptionSender extends SubscriptionSender $headers ); } - } diff --git a/inc/Subscriptions/RegistrationSubscriptionSender.php b/inc/Subscriptions/RegistrationSubscriptionSender.php index bd4887599..34cfc8907 100644 --- a/inc/Subscriptions/RegistrationSubscriptionSender.php +++ b/inc/Subscriptions/RegistrationSubscriptionSender.php @@ -4,7 +4,6 @@ namespace dokuwiki\Subscriptions; class RegistrationSubscriptionSender extends SubscriptionSender { - /** * Send a notify mail on new registration * diff --git a/inc/Subscriptions/SubscriberManager.php b/inc/Subscriptions/SubscriberManager.php index 44a9b4a26..484daaa51 100644 --- a/inc/Subscriptions/SubscriberManager.php +++ b/inc/Subscriptions/SubscriberManager.php @@ -2,13 +2,12 @@ namespace dokuwiki\Subscriptions; +use dokuwiki\Extension\AuthPlugin; use dokuwiki\Input\Input; -use DokuWiki_Auth_Plugin; use Exception; class SubscriberManager { - /** * Check if subscription system is enabled * @@ -71,12 +70,13 @@ class SubscriberManager * namespace. It will *not* modify any subscriptions that may exist in higher * namespaces. * - * @param string $id The target object’s (namespace or page) id + * @param string $id The target object’s (namespace or page) id * @param string|array $user * @param string|array $style * @param string|array $data * * @return bool + * @throws Exception */ public function remove($id, $user = null, $style = null, $data = null) { @@ -101,12 +101,13 @@ class SubscriberManager * and user is in effect. Else it contains an array of arrays with the fields * “target”, “style”, and optionally “data”. * - * @author Adrian Lang <lang@cosmocode.de> - * - * @param string $id Page ID, defaults to global $ID + * @param string $id Page ID, defaults to global $ID * @param string $user User, defaults to $_SERVER['REMOTE_USER'] * * @return array|false + * @throws Exception + * + * @author Adrian Lang <lang@cosmocode.de> */ public function userSubscription($id = '', $user = '') { @@ -130,7 +131,7 @@ class SubscriberManager } $subs = $this->subscribers($id, $user); - if (!count($subs)) { + if ($subs === []) { return false; } @@ -152,14 +153,16 @@ class SubscriberManager * This function searches all relevant subscription files for a page or * namespace. * - * @author Adrian Lang <lang@cosmocode.de> - * - * @param string $page The target object’s (namespace or page) id + * @param string $page The target object’s (namespace or page) id * @param string|array $user * @param string|array $style * @param string|array $data * * @return array + * @throws Exception + * + * @author Adrian Lang <lang@cosmocode.de> + * */ public function subscribers($page, $user = null, $style = null, $data = null) { @@ -216,17 +219,18 @@ class SubscriberManager * * Aggregates all email addresses of user who have subscribed the given page with 'every' style * - * @author Adrian Lang <lang@cosmocode.de> - * @author Steven Danz <steven-danz@kc.rr.com> - * - * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead, - * use an array for the addresses within it - * * @param array &$data Containing the entries: * - $id (the page id), * - $self (whether the author should be notified, * - $addresslist (current email address list) * - $replacements (array of additional string substitutions, @KEY@ to be replaced by value) + * @throws Exception + * + * @author Adrian Lang <lang@cosmocode.de> + * @author Steven Danz <steven-danz@kc.rr.com> + * + * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead, + * use an array for the addresses within it */ public function notifyAddresses(&$data) { @@ -234,7 +238,7 @@ class SubscriberManager return; } - /** @var DokuWiki_Auth_Plugin $auth */ + /** @var AuthPlugin $auth */ global $auth; global $conf; /** @var \Input $INPUT */ @@ -247,7 +251,7 @@ class SubscriberManager $subscriptions = $this->subscribers($id, null, 'every'); $result = []; - foreach ($subscriptions as $target => $users) { + foreach ($subscriptions as $users) { foreach ($users as $user => $info) { $userinfo = $auth->getUserData($user); if ($userinfo === false) { diff --git a/inc/Subscriptions/SubscriberRegexBuilder.php b/inc/Subscriptions/SubscriberRegexBuilder.php index 959702aac..6c8fd7e6b 100644 --- a/inc/Subscriptions/SubscriberRegexBuilder.php +++ b/inc/Subscriptions/SubscriberRegexBuilder.php @@ -6,7 +6,6 @@ use Exception; class SubscriberRegexBuilder { - /** * Construct a regular expression for parsing a subscription definition line * @@ -36,13 +35,14 @@ class SubscriberRegexBuilder // quote $user = array_map('preg_quote_cb', $user); + $style = array_map('preg_quote_cb', $style); $data = array_map('preg_quote_cb', $data); // join - $user = join('|', $user); - $style = join('|', $style); - $data = join('|', $data); + $user = implode('|', $user); + $style = implode('|', $style); + $data = implode('|', $data); // any data at all? if ($user . $style . $data === '') { diff --git a/inc/Subscriptions/SubscriptionSender.php b/inc/Subscriptions/SubscriptionSender.php index afc05bfc0..4a4e31ea2 100644 --- a/inc/Subscriptions/SubscriptionSender.php +++ b/inc/Subscriptions/SubscriptionSender.php @@ -10,7 +10,7 @@ abstract class SubscriptionSender public function __construct(Mailer $mailer = null) { - if ($mailer === null) { + if (!$mailer instanceof \Mailer) { $mailer = new Mailer(); } $this->mailer = $mailer; @@ -29,7 +29,7 @@ abstract class SubscriptionSender static $listid = null; if (is_null($listid)) { $server = parse_url(DOKU_URL, PHP_URL_HOST); - $listid = join('.', array_reverse(explode('/', DOKU_BASE))) . $server; + $listid = implode('.', array_reverse(explode('/', DOKU_BASE))) . $server; $listid = urlencode($listid); $listid = strtolower(trim($listid, '.')); } diff --git a/inc/TaskRunner.php b/inc/TaskRunner.php index b641fb174..d71bb64d3 100644 --- a/inc/TaskRunner.php +++ b/inc/TaskRunner.php @@ -30,14 +30,14 @@ class TaskRunner // check if user abort worked, if yes send output early $defer = !@ignore_user_abort() || $conf['broken_iua']; $output = $INPUT->has('debug') && $conf['allowdebug']; - if(!$defer && !$output){ + if (!$defer && !$output) { $this->sendGIF(); } $ID = cleanID($INPUT->str('id')); // Catch any possible output (e.g. errors) - if(!$output) { + if (!$output) { ob_start(); } else { header('Content-Type: text/plain'); @@ -47,17 +47,21 @@ class TaskRunner $tmp = []; // No event data $evt = new Event('INDEXER_TASKS_RUN', $tmp); if ($evt->advise_before()) { - $this->runIndexer() or - $this->runSitemapper() or - $this->sendDigest() or - $this->runTrimRecentChanges() or - $this->runTrimRecentChanges(true) or - $evt->advise_after(); + if ( + !( + $this->runIndexer() || + $this->runSitemapper() || + $this->sendDigest() || + $this->runTrimRecentChanges() || + $this->runTrimRecentChanges(true)) + ) { + $evt->advise_after(); + } } - if(!$output) { + if (!$output) { ob_end_clean(); - if($defer) { + if ($defer) { $this->sendGIF(); } } @@ -73,9 +77,9 @@ class TaskRunner { $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); header('Content-Type: image/gif'); - header('Content-Length: '.strlen($img)); + header('Content-Length: ' . strlen($img)); header('Connection: Close'); - print $img; + echo $img; tpl_flush(); // Browser should drop connection after this // Thinks it's got the whole image @@ -103,9 +107,11 @@ class TaskRunner // Trims the recent changes cache to the last $conf['changes_days'] recent // changes or $conf['recent'] items, which ever is larger. // The trimming is only done once a day. - if (file_exists($fn) && + if ( + file_exists($fn) && (@filemtime($fn . '.trimmed') + 86400) < time() && - !file_exists($fn . '_tmp')) { + !file_exists($fn . '_tmp') + ) { @touch($fn . '.trimmed'); io_lock($fn); $lines = file($fn); @@ -120,7 +126,8 @@ class TaskRunner $trim_time = time() - $conf['recent_days'] * 86400; $out_lines = []; $old_lines = []; - for ($i = 0; $i < count($lines); $i++) { + $counter = count($lines); + for ($i = 0; $i < $counter; $i++) { $log = ChangeLog::parseLogLine($lines[$i]); if ($log === false) { continue; // discard junk @@ -189,7 +196,7 @@ class TaskRunner protected function runIndexer() { global $ID; - print 'runIndexer(): started' . NL; + echo 'runIndexer(): started' . NL; if ((string) $ID === '') { return false; @@ -210,9 +217,9 @@ class TaskRunner */ protected function runSitemapper() { - print 'runSitemapper(): started' . NL; + echo 'runSitemapper(): started' . NL; $result = Mapper::generate() && Mapper::pingSearchEngines(); - print 'runSitemapper(): finished' . NL; + echo 'runSitemapper(): finished' . NL; return $result; } diff --git a/inc/Ui/Admin.php b/inc/Ui/Admin.php index 925eb35e8..24d9dc43d 100644 --- a/inc/Ui/Admin.php +++ b/inc/Ui/Admin.php @@ -1,7 +1,9 @@ <?php + namespace dokuwiki\Ui; use dokuwiki\Extension\AdminPlugin; +use dokuwiki\Extension\PluginInterface; use dokuwiki\Utf8\Sort; /** @@ -13,10 +15,10 @@ use dokuwiki\Utf8\Sort; * @author Andreas Gohr <andi@splitbrain.org> * @author Håkan Sandell <hakan.sandell@home.se> */ -class Admin extends Ui { - - protected $forAdmins = array('usermanager', 'acl', 'extension', 'config', 'logviewer', 'styling'); - protected $forManagers = array('revert', 'popularity'); +class Admin extends Ui +{ + protected $forAdmins = ['usermanager', 'acl', 'extension', 'config', 'logviewer', 'styling']; + protected $forManagers = ['revert', 'popularity']; /** @var array[] */ protected $menu; @@ -25,7 +27,8 @@ class Admin extends Ui { * * @return void */ - public function show() { + public function show() + { $this->menu = $this->getPluginList(); echo '<div class="ui-admin">'; echo p_locale_xhtml('admin'); @@ -43,7 +46,8 @@ class Admin extends Ui { * * @param string $type admin|manager|other */ - protected function showMenu($type) { + protected function showMenu($type) + { if (!$this->menu[$type]) return; if ($type === 'other') { @@ -63,7 +67,8 @@ class Admin extends Ui { /** * Display the DokuWiki version */ - protected function showVersion() { + protected function showVersion() + { echo '<div id="admin__version">'; echo getVersion(); echo '</div>'; @@ -80,9 +85,10 @@ class Admin extends Ui { * * The actual check is carried out via JavaScript. See behaviour.js */ - protected function showSecurityCheck() { + protected function showSecurityCheck() + { global $conf; - if(substr($conf['savedir'], 0, 2) !== './') return; + if (substr($conf['savedir'], 0, 2) !== './') return; $img = DOKU_URL . $conf['savedir'] . '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png'; echo '<div id="security__check" data-src="' . $img . '"></div>'; @@ -93,9 +99,10 @@ class Admin extends Ui { * * @param array $item */ - protected function showMenuItem($item) { + protected function showMenuItem($item) + { global $ID; - if(blank($item['prompt'])) return; + if (blank($item['prompt'])) return; echo '<li><div class="li">'; echo '<a href="' . wl($ID, 'do=admin&page=' . $item['plugin']) . '">'; echo '<span class="icon">'; @@ -115,33 +122,34 @@ class Admin extends Ui { * * @return array list of plugins with their properties */ - protected function getPluginList() { + protected function getPluginList() + { global $conf; $pluginlist = plugin_list('admin'); $menu = ['admin' => [], 'manager' => [], 'other' => []]; - foreach($pluginlist as $p) { + foreach ($pluginlist as $p) { /** @var AdminPlugin $obj */ - if(($obj = plugin_load('admin', $p)) === null) continue; + if (!($obj = plugin_load('admin', $p)) instanceof PluginInterface) continue; // check permissions if (!$obj->isAccessibleByCurrentUser()) continue; if (in_array($p, $this->forAdmins, true)) { $type = 'admin'; - } elseif (in_array($p, $this->forManagers, true)){ + } elseif (in_array($p, $this->forManagers, true)) { $type = 'manager'; } else { $type = 'other'; } - $menu[$type][$p] = array( + $menu[$type][$p] = [ 'plugin' => $p, 'prompt' => $obj->getMenuText($conf['lang']), 'icon' => $obj->getMenuIcon(), - 'sort' => $obj->getMenuSort(), - ); + 'sort' => $obj->getMenuSort() + ]; } // sort by name, then sort @@ -161,10 +169,10 @@ class Admin extends Ui { * @param array $b * @return int */ - protected function menuSort($a, $b) { + protected function menuSort($a, $b) + { $strcmp = Sort::strcmp($a['prompt'], $b['prompt']); - if($strcmp != 0) return $strcmp; - if($a['sort'] === $b['sort']) return 0; - return ($a['sort'] < $b['sort']) ? -1 : 1; + if ($strcmp != 0) return $strcmp; + return $a['sort'] <=> $b['sort']; } } diff --git a/inc/Ui/Backlinks.php b/inc/Ui/Backlinks.php index 9ac99b1b0..8eb55820f 100644 --- a/inc/Ui/Backlinks.php +++ b/inc/Ui/Backlinks.php @@ -12,10 +12,10 @@ class Backlinks extends Ui /** * Display backlinks * - * @author Andreas Gohr <andi@splitbrain.org> + * @return void * @author Michael Klier <chi@chimeric.de> * - * @return void + * @author Andreas Gohr <andi@splitbrain.org> */ public function show() { @@ -23,21 +23,20 @@ class Backlinks extends Ui global $lang; // print intro - print p_locale_xhtml('backlinks'); + echo p_locale_xhtml('backlinks'); $data = ft_backlinks($ID); if (!empty($data)) { - print '<ul class="idx">'; + echo '<ul class="idx">'; foreach ($data as $blink) { - print '<li><div class="li">'; - print html_wikilink(':'.$blink,useHeading('navigation') ? null : $blink); - print '</div></li>'; + echo '<li><div class="li">'; + echo html_wikilink(':' . $blink, useHeading('navigation') ? null : $blink); + echo '</div></li>'; } - print '</ul>'; + echo '</ul>'; } else { - print '<div class="level1"><p>'. $lang['nothingfound'] .'</p></div>'; + echo '<div class="level1"><p>' . $lang['nothingfound'] . '</p></div>'; } } - } diff --git a/inc/Ui/Diff.php b/inc/Ui/Diff.php index 9eb3553b6..70c050d6d 100644 --- a/inc/Ui/Diff.php +++ b/inc/Ui/Diff.php @@ -29,7 +29,7 @@ abstract class Diff extends Ui /** * Diff Ui constructor * - * @param string $id page id or media id + * @param string $id page id or media id */ public function __construct($id) { @@ -65,8 +65,8 @@ abstract class Diff extends Ui /** * Gets or Sets preference of the Ui\Diff object * - * @param string|array $prefs a key name or key-value pair(s) - * @param mixed $value value used when the first args is string + * @param string|array $prefs a key name or key-value pair(s) + * @param mixed $value value used when the first args is string * @return array|$this */ public function preference($prefs = null, $value = null) @@ -100,20 +100,20 @@ abstract class Diff extends Ui $this->rev2 = $this->changelog->currentRevision(); if ($this->rev2 <= $this->rev1) { // fallback to compare previous with current - unset($this->rev1, $this->rev2); + unset($this->rev1, $this->rev2); } } // submit button with two checked boxes, eg. &do=diff&rev2[0]=#&rev2[1]=# $revs = $INPUT->arr('rev2', []); if (count($revs) > 1) { - list($rev1, $rev2) = $revs; + [$rev1, $rev2] = $revs; if ($rev2 < $rev1) [$rev1, $rev2] = [$rev2, $rev1]; $this->rev1 = (int)$rev1; $this->rev2 = (int)$this->changelog->traceCurrentRevision($rev2); } - // no revision was given, compare previous to current + // no revision was given, compare previous to current if (!isset($this->rev1, $this->rev2)) { $rev2 = $this->changelog->currentRevision(); if ($rev2 > $this->changelog->lastRevision()) { diff --git a/inc/Ui/Editor.php b/inc/Ui/Editor.php index 67ad081ff..ba159b78c 100644 --- a/inc/Ui/Editor.php +++ b/inc/Ui/Editor.php @@ -17,10 +17,10 @@ class Editor extends Ui * Display the Edit Window * preprocess edit form data * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * * @triggers EDIT_FORM_ADDTEXTAREA - * @return void */ public function show() { @@ -67,23 +67,23 @@ class Editor extends Ui $form->setHiddenField('id', $ID); $form->setHiddenField('rev', $REV); $form->setHiddenField('date', $DATE); - $form->setHiddenField('prefix', $PRE .'.'); + $form->setHiddenField('prefix', $PRE . '.'); $form->setHiddenField('suffix', $SUF); $form->setHiddenField('changecheck', $check); // prepare data for EDIT_FORM_ALTERNATE event - $data = array( + $data = [ 'form' => $form, - 'wr' => $wr, + 'wr' => $wr, 'media_manager' => true, 'target' => ($INPUT->has('target') && $wr) ? $INPUT->str('target') : 'section', - 'intro_locale' => $intro, - ); + 'intro_locale' => $intro + ]; if ($data['target'] !== 'section') { // Only emit event if page is writable, section edit data is valid and // edit target is not section. - Event::createAndTrigger('EDIT_FORM_ADDTEXTAREA', $data, [$this,'addTextarea'], true); + Event::createAndTrigger('EDIT_FORM_ADDTEXTAREA', $data, [$this, 'addTextarea'], true); } else { $this->addTextarea($data); } @@ -135,23 +135,22 @@ class Editor extends Ui // license note if ($wr && $conf['license']) { - $attr = array( - 'href' => $license[$conf['license']]['url'], - 'rel' => 'license', - 'class' => 'urlextern', - 'target' => $conf['target']['extern'] ?: '', - ); + $attr = [ + 'href' => $license[$conf['license']]['url'], + 'rel' => 'license', + 'class' => 'urlextern', + 'target' => $conf['target']['extern'] ?: '' + ]; $form->addTagOpen('div')->addClass('license'); $form->addHTML($lang['licenseok'] - .' <a '.buildAttributes($attr, true).'>'.$license[$conf['license']]['name'].'</a>' - ); + . ' <a ' . buildAttributes($attr, true) . '>' . $license[$conf['license']]['name'] . '</a>'); $form->addTagClose('div'); } // start editor html output if ($wr) { // sets changed to true when previewed - echo '<script>/*<![CDATA[*/'.'textChanged = '. ($mod ? 'true' : 'false') .'/*!]]>*/</script>'; + echo '<script>/*<![CDATA[*/textChanged = ' . ($mod ? 'true' : 'false') . '/*!]]>*/</script>'; } // print intro locale text (edit, rditrev, or read.txt) @@ -164,7 +163,7 @@ class Editor extends Ui echo '<div class="toolbar group">'; echo '<div id="tool__bar" class="tool__bar">'; if ($wr && $data['media_manager']) { - echo '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.$INFO['namespace'].'" target="_blank">'; + echo '<a href="' . DOKU_BASE . 'lib/exe/mediamanager.php?ns=' . $INFO['namespace'] . '" target="_blank">'; echo $lang['mediaselect']; echo '</a>'; } @@ -195,18 +194,17 @@ class Editor extends Ui global $TEXT; if ($data['target'] !== 'section') { - msg('No editor for edit target '. hsc($data['target']) .' found.', -1); + msg('No editor for edit target ' . hsc($data['target']) . ' found.', -1); } // set textarea attributes - $attr = array('tabindex' => '1'); + $attr = ['tabindex' => '1']; if (!$data['wr']) $attr['readonly'] = 'readonly'; - $attr['dir'] = 'auto'; + $attr['dir'] = 'auto'; $attr['cols'] = '80'; $attr['rows'] = '10'; - $data['form']->addTextarea('wikitext','')->attrs($attr)->val($TEXT) - ->id('wiki__text')->addClass('edit'); + $data['form']->addTextarea('wikitext', '')->attrs($attr)->val($TEXT) + ->id('wiki__text')->addClass('edit'); } - } diff --git a/inc/Ui/Index.php b/inc/Ui/Index.php index f7920f1ff..22132c92c 100644 --- a/inc/Ui/Index.php +++ b/inc/Ui/Index.php @@ -14,8 +14,8 @@ class Index extends Ui /** * Index Ui constructor * - * @param string $ns namespace - */ + * @param string $ns namespace + */ public function __construct($ns = '') { $this->ns = $ns; @@ -25,16 +25,16 @@ class Index extends Ui /** * Display page index * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { // print intro - print p_locale_xhtml('index'); + echo p_locale_xhtml('index'); - print $this->sitemap(); + echo $this->sitemap(); } /** @@ -48,17 +48,17 @@ class Index extends Ui global $ID; $ns = cleanID($this->ns); - if (empty($ns)){ + if (empty($ns)) { $ns = getNS($ID); if ($ns === false) $ns = ''; } $ns = utf8_encodeFN(str_replace(':', '/', $ns)); - $data = array(); - search($data, $conf['datadir'], 'search_index', array('ns' => $ns)); + $data = []; + search($data, $conf['datadir'], 'search_index', ['ns' => $ns]); return '<div id="index__tree" class="index__tree">' - . html_buildlist($data, 'idx', [$this,'formatListItem'], [$this,'tagListItem']) - . '</div>'; + . html_buildlist($data, 'idx', [$this, 'formatListItem'], [$this, 'tagListItem']) + . '</div>'; } /** @@ -66,10 +66,10 @@ class Index extends Ui * * User function for html_buildlist() * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $item * @return string + * @author Andreas Gohr <andi@splitbrain.org> + * */ public function formatListItem($item) // RENAMED from html_list_index() { @@ -79,17 +79,17 @@ class Index extends Ui $nofollow = ($ID != $conf['start'] || $conf['sitemap']) ? 'rel="nofollow"' : ''; $html = ''; - $base = ':'.$item['id']; - $base = substr($base, strrpos($base,':') +1); + $base = ':' . $item['id']; + $base = substr($base, strrpos($base, ':') + 1); if ($item['type'] == 'd') { // FS#2766, no need for search bots to follow namespace links in the index - $link = wl($ID, 'idx='. rawurlencode($item['id'])); - $html .= '<a href="'. $link .'" title="'. $item['id'] .'" class="idx_dir"' . $nofollow .'><strong>'; + $link = wl($ID, 'idx=' . rawurlencode($item['id'])); + $html .= '<a href="' . $link . '" title="' . $item['id'] . '" class="idx_dir"' . $nofollow . '><strong>'; $html .= $base; $html .= '</strong></a>'; } else { // default is noNSorNS($id), but we want noNS($id) when useheading is off FS#2605 - $html .= html_wikilink(':'.$item['id'], useHeading('navigation') ? null : noNS($item['id'])); + $html .= html_wikilink(':' . $item['id'], useHeading('navigation') ? null : noNS($item['id'])); } return $html; } @@ -101,10 +101,10 @@ class Index extends Ui * <li> tags for namespaces when displaying the page index * it gives different classes to opened or closed "folders" * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $item * @return string html + * @author Andreas Gohr <andi@splitbrain.org> + * */ public function tagListItem($item) // RENAMED from html_li_index() { @@ -120,12 +120,11 @@ class Index extends Ui $id = ' id="scroll__here"'; $class = ' bounce'; } - return '<li class="level'.$item['level'].$class.'" '.$id.'>'; + return '<li class="level' . $item['level'] . $class . '" ' . $id . '>'; } elseif ($item['open']) { return '<li class="open">'; } else { return '<li class="closed">'; } } - } diff --git a/inc/Ui/Login.php b/inc/Ui/Login.php index 0980130a4..09fc5386b 100644 --- a/inc/Ui/Login.php +++ b/inc/Ui/Login.php @@ -3,6 +3,8 @@ namespace dokuwiki\Ui; use dokuwiki\Form\Form; +use dokuwiki\Menu\Item\Register; +use dokuwiki\Menu\Item\Resendpwd; /** * DokuWiki User Login Interface (Login Form) @@ -13,10 +15,10 @@ class Login extends Ui { protected $showIcon = false; - /** + /** * Login Ui constructor * - * @param bool $showIcon Whether to show svg icons in the register and resendpwd links or not + * @param bool $showIcon Whether to show svg icons in the register and resendpwd links or not */ public function __construct($showIcon = false) { @@ -26,9 +28,9 @@ class Login extends Ui /** * Display the Login Form Panel * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { @@ -38,8 +40,8 @@ class Login extends Ui global $INPUT; // print intro - print p_locale_xhtml('login'); - print '<div class="centeralign">'.NL; + echo p_locale_xhtml('login'); + echo '<div class="centeralign">' . NL; // create the login form $form = new Form(['id' => 'dw__login', 'action' => wl($ID)]); @@ -49,7 +51,7 @@ class Login extends Ui $form->setHiddenField('do', 'login'); $input = $form->addTextInput('u', $lang['user'])->id('focus__this')->addClass('edit') - ->val((!$INPUT->bool('http_credentials')) ? $INPUT->str('u') : ''); + ->val(($INPUT->bool('http_credentials')) ? '' : $INPUT->str('u')); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); @@ -64,19 +66,18 @@ class Login extends Ui $form->addFieldsetClose(); $form->addTagClose('div'); - if(actionOK('register')){ - $registerLink = (new \dokuwiki\Menu\Item\Register())->asHtmlLink('', $this->showIcon); - $form->addHTML('<p>'.$lang['reghere'].': '. $registerLink .'</p>'); + if (actionOK('register')) { + $registerLink = (new Register())->asHtmlLink('', $this->showIcon); + $form->addHTML('<p>' . $lang['reghere'] . ': ' . $registerLink . '</p>'); } if (actionOK('resendpwd')) { - $resendPwLink = (new \dokuwiki\Menu\Item\Resendpwd())->asHtmlLink('', $this->showIcon); - $form->addHTML('<p>'.$lang['pwdforget'].': '. $resendPwLink .'</p>'); + $resendPwLink = (new Resendpwd())->asHtmlLink('', $this->showIcon); + $form->addHTML('<p>' . $lang['pwdforget'] . ': ' . $resendPwLink . '</p>'); } - print $form->toHTML('Login'); + echo $form->toHTML('Login'); - print '</div>'; + echo '</div>'; } - } diff --git a/inc/Ui/Media/Display.php b/inc/Ui/Media/Display.php index 0d2266be2..ff81b1f1e 100644 --- a/inc/Ui/Media/Display.php +++ b/inc/Ui/Media/Display.php @@ -10,7 +10,7 @@ class Display protected $mediaFile; /** @var string should IDs be shown relative to this namespace? Used in search results */ - protected $relativeDisplay = null; + protected $relativeDisplay; /** @var bool scroll to this file on display? */ protected $scrollIntoView = false; @@ -115,7 +115,7 @@ class Display { if ($this->relativeDisplay !== null) { $id = $this->mediaFile->getId(); - if (substr($id, 0, strlen($this->relativeDisplay)) == $this->relativeDisplay) { + if (substr($id, 0, strlen($this->relativeDisplay)) === $this->relativeDisplay) { $id = substr($id, strlen($this->relativeDisplay)); } return ltrim($id, ':'); diff --git a/inc/Ui/Media/DisplayRow.php b/inc/Ui/Media/DisplayRow.php index 32209824f..03bb60ff3 100644 --- a/inc/Ui/Media/DisplayRow.php +++ b/inc/Ui/Media/DisplayRow.php @@ -32,7 +32,7 @@ class DisplayRow extends DisplayTile 'alt="' . $lang['mediaview'] . '" title="' . $lang['mediaview'] . '" class="btn" /></a>'; // mediamanager button - $link = wl('', array('do' => 'media', 'image' => $id, 'ns' => getNS($id))); + $link = wl('', ['do' => 'media', 'image' => $id, 'ns' => getNS($id)]); echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/mediamanager.png" ' . 'alt="' . $lang['btn_media'] . '" title="' . $lang['btn_media'] . '" class="btn" /></a>'; @@ -51,7 +51,6 @@ class DisplayRow extends DisplayTile if ($this->mediaFile->isImage()) $this->showDetails(); echo '<div class="clearer"></div>' . NL; echo '</div>' . NL; - } /** @@ -69,15 +68,15 @@ class DisplayRow extends DisplayTile echo '</div>'; // read EXIF/IPTC data - $t = $this->mediaFile->getMeta()->getField(array('IPTC.Headline', 'xmp.dc:title')); - $d = $this->mediaFile->getMeta()->getField(array( + $t = $this->mediaFile->getMeta()->getField(['IPTC.Headline', 'xmp.dc:title']); + $d = $this->mediaFile->getMeta()->getField([ 'IPTC.Caption', 'EXIF.UserComment', 'EXIF.TIFFImageDescription', - 'EXIF.TIFFUserComment', - )); + 'EXIF.TIFFUserComment' + ]); if (PhpString::strlen($d) > 250) $d = PhpString::substr($d, 0, 250) . '...'; - $k = $this->mediaFile->getMeta()->getField(array('IPTC.Keywords', 'IPTC.Category', 'xmp.dc:subject')); + $k = $this->mediaFile->getMeta()->getField(['IPTC.Keywords', 'IPTC.Category', 'xmp.dc:subject']); // print EXIF/IPTC data if ($t || $d || $k) { @@ -89,5 +88,4 @@ class DisplayRow extends DisplayTile } echo '</div>'; } - } diff --git a/inc/Ui/MediaDiff.php b/inc/Ui/MediaDiff.php index ec3d4c8bb..6a60e2e1e 100644 --- a/inc/Ui/MediaDiff.php +++ b/inc/Ui/MediaDiff.php @@ -29,7 +29,7 @@ class MediaDiff extends Diff /** * MediaDiff Ui constructor * - * @param string $id media id + * @param string $id media id */ public function __construct($id) { @@ -79,7 +79,7 @@ class MediaDiff extends Diff // create revision info object for older and newer sides // RevInfo1 : older, left side // RevInfo2 : newer, right side - + $changelogRev1 = $changelog->getRevisionInfo($this->rev1); $changelogRev2 = $changelog->getRevisionInfo($this->rev2); $changelogRev1['media'] = $changelogRev2['media'] = true; @@ -214,15 +214,15 @@ class MediaDiff extends Diff $rev2Src = ml($this->id, ['rev' => $rev2, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); // slider - echo '<div class="slider" style="max-width: '.($rev1Size[0]-20).'px;" ></div>'; + echo '<div class="slider" style="max-width: ' . ($rev1Size[0] - 20) . 'px;" ></div>'; // two images in divs - echo '<div class="imageDiff '.$type.'">'; - echo '<div class="image1" style="max-width: '.$rev1Size[0].'px;">'; - echo '<img src="'.$rev1Src.'" alt="" />'; + echo '<div class="imageDiff ' . $type . '">'; + echo '<div class="image1" style="max-width: ' . $rev1Size[0] . 'px;">'; + echo '<img src="' . $rev1Src . '" alt="" />'; echo '</div>'; - echo '<div class="image2" style="max-width: '.$rev1Size[0].'px;">'; - echo '<img src="'.$rev2Src.'" alt="" />'; + echo '<div class="image2" style="max-width: ' . $rev1Size[0] . 'px;">'; + echo '<img src="' . $rev2Src . '" alt="" />'; echo '</div>'; echo '</div>'; } @@ -243,13 +243,13 @@ class MediaDiff extends Diff $rev2 = $this->RevInfo2->isCurrent() ? '' : (int)$this->RevInfo2->val('date'); // revision title - $rev1Title = trim($this->RevInfo1->showRevisionTitle() .' '. $this->RevInfo1->showCurrentIndicator()); + $rev1Title = trim($this->RevInfo1->showRevisionTitle() . ' ' . $this->RevInfo1->showCurrentIndicator()); $rev1Summary = ($this->RevInfo1->val('date')) - ? $this->RevInfo1->showEditSummary() .' '. $this->RevInfo1->showEditor() + ? $this->RevInfo1->showEditSummary() . ' ' . $this->RevInfo1->showEditor() : ''; - $rev2Title = trim($this->RevInfo2->showRevisionTitle() .' '. $this->RevInfo2->showCurrentIndicator()); + $rev2Title = trim($this->RevInfo2->showRevisionTitle() . ' ' . $this->RevInfo2->showCurrentIndicator()); $rev2Summary = ($this->RevInfo2->val('date')) - ? $this->RevInfo2->showEditSummary() .' '. $this->RevInfo2->showEditor() + ? $this->RevInfo2->showEditSummary() . ' ' . $this->RevInfo2->showEditor() : ''; $rev1Meta = new JpegMeta(mediaFN($this->id, $rev1)); @@ -259,8 +259,8 @@ class MediaDiff extends Diff echo '<div class="table">'; echo '<table>'; echo '<tr>'; - echo '<th>'. $rev1Title .' '. $rev1Summary .'</th>'; - echo '<th>'. $rev2Title .' '. $rev2Summary .'</th>'; + echo '<th>' . $rev1Title . ' ' . $rev1Summary . '</th>'; + echo '<th>' . $rev2Title . ' ' . $rev2Summary . '</th>'; echo '</tr>'; echo '<tr class="image">'; @@ -304,7 +304,7 @@ class MediaDiff extends Diff foreach ($tags as $tag) { $value = cleanText($tag['value']); if (!$value) $value = '-'; - echo '<dt>'.$lang[$tag['tag'][1]].'</dt>'; + echo '<dt>' . $lang[$tag['tag'][1]] . '</dt>'; echo '<dd>'; if (!empty($tag['highlighted'])) echo '<strong>'; if ($tag['tag'][2] == 'date') { @@ -324,5 +324,4 @@ class MediaDiff extends Diff echo '</table>'; echo '</div>'; } - } diff --git a/inc/Ui/MediaRevisions.php b/inc/Ui/MediaRevisions.php index e774de776..05d4a2d18 100644 --- a/inc/Ui/MediaRevisions.php +++ b/inc/Ui/MediaRevisions.php @@ -20,7 +20,7 @@ class MediaRevisions extends Revisions /** * MediaRevisions Ui constructor * - * @param string $id id of media + * @param string $id id of media */ public function __construct($id) { @@ -39,13 +39,13 @@ class MediaRevisions extends Revisions /** * Display a list of Media Revisions in the MediaManager * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Ben Coburn <btcoburn@silicodon.net> + * @param int $first skip the first n changelog lines + * @return void * @author Kate Arzamastseva <pshns@ukr.net> * @author Satoshi Sahara <sahara.satoshi@gmail.com> * - * @param int $first skip the first n changelog lines - * @return void + * @author Andreas Gohr <andi@splitbrain.org> + * @author Ben Coburn <btcoburn@silicodon.net> */ public function show($first = -1) { @@ -59,9 +59,9 @@ class MediaRevisions extends Revisions // create the form $form = new Form([ - 'id' => 'page__revisions', // must not be "media__revisions" - 'action' => media_managerURL(['image' => $this->id], '&'), - 'class' => 'changes', + 'id' => 'page__revisions', // must not be "media__revisions" + 'action' => media_managerURL(['image' => $this->id], '&'), + 'class' => 'changes', ]); $form->setHiddenField('mediado', 'diff'); // required for media revisions $form->addTagOpen('div')->addClass('no'); @@ -83,7 +83,7 @@ class MediaRevisions extends Revisions } elseif (file_exists(mediaFN($this->id, $rev))) { $form->addCheckbox('rev2[]')->val($rev); } else { - $form->addCheckbox('')->val($rev)->attr('disabled','disabled'); + $form->addCheckbox('')->val($rev)->attr('disabled', 'disabled'); } $form->addHTML(' '); @@ -110,12 +110,13 @@ class MediaRevisions extends Revisions $form->addTagClose('div'); // close div class=no - print $form->toHTML('Revisions'); + echo $form->toHTML('Revisions'); // provide navigation for paginated revision list (of pages and/or media files) - print $this->navigation($first, $hasNext, function ($n) { - return media_managerURL(['first' => $n], '&', false, true); - }); + echo $this->navigation( + $first, + $hasNext, + static fn($n) => media_managerURL(['first' => $n], '&', false, true) + ); } - } diff --git a/inc/Ui/PageConflict.php b/inc/Ui/PageConflict.php index 584860100..fd28170a4 100644 --- a/inc/Ui/PageConflict.php +++ b/inc/Ui/PageConflict.php @@ -14,24 +14,24 @@ class PageConflict extends Ui protected $text; protected $summary; - /** + /** * PageConflict Ui constructor * - * @param string $text wiki text - * @param string $summary edit summary - */ + * @param string $text wiki text + * @param string $summary edit summary + */ public function __construct($text = '', $summary = '') { - $this->text = $text; + $this->text = $text; $this->summary = $summary; } /** * Show conflict form to ask whether save anyway or cancel the page edits * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { @@ -39,7 +39,7 @@ class PageConflict extends Ui global $lang; // print intro - print p_locale_xhtml('conflict'); + echo p_locale_xhtml('conflict'); // create the form $form = new Form(['id' => 'dw__editform']); @@ -48,16 +48,15 @@ class PageConflict extends Ui $form->setHiddenField('wikitext', $this->text); $form->setHiddenField('summary', $this->summary); - $form->addButton('do[save]', $lang['btn_save'] )->attrs(['type' => 'submit', 'accesskey' => 's']); - $form->addButton('do[cancel]', $lang['btn_cancel'] )->attrs(['type' => 'submit']); + $form->addButton('do[save]', $lang['btn_save'])->attrs(['type' => 'submit', 'accesskey' => 's']); + $form->addButton('do[cancel]', $lang['btn_cancel'])->attrs(['type' => 'submit']); $form->addTagClose('div'); - print $form->toHTML('Conflict'); + echo $form->toHTML('Conflict'); - print '<br /><br /><br /><br />'; + echo '<br /><br /><br /><br />'; // print difference (new PageDiff($INFO['id']))->compareWith($this->text)->preference('showIntro', false)->show(); } - } diff --git a/inc/Ui/PageDiff.php b/inc/Ui/PageDiff.php index 92aacb76a..5089a108f 100644 --- a/inc/Ui/PageDiff.php +++ b/inc/Ui/PageDiff.php @@ -31,7 +31,7 @@ class PageDiff extends Diff /** * PageDiff Ui constructor * - * @param string $id page id + * @param string $id page id */ public function __construct($id = null) { @@ -76,13 +76,13 @@ class PageDiff extends Diff $this->RevInfo2 = new RevisionInfo(); $this->RevInfo2->append([ 'date' => false, - //'ip' => '127.0.0.1', - //'type' => DOKU_CHANGE_TYPE_CREATE, - 'id' => $this->id, - //'user' => '', - //'sum' => '', + //'ip' => '127.0.0.1', + //'type' => DOKU_CHANGE_TYPE_CREATE, + 'id' => $this->id, + //'user' => '', + //'sum' => '', 'extra' => 'compareWith', - //'sizechange' => strlen($this->text) - io_getSizeFile(wikiFN($this->id)), + //'sizechange' => strlen($this->text) - io_getSizeFile(wikiFN($this->id)), 'current' => false, 'text' => cleanText($this->text), ]); @@ -112,7 +112,7 @@ class PageDiff extends Diff // read preference from DokuWiki cookie. PageDiff only $mode = get_doku_pref('difftype', null); } - if(in_array($mode, ['inline','sidebyside'])) $this->preference['difftype'] = $mode; + if (in_array($mode, ['inline', 'sidebyside'])) $this->preference['difftype'] = $mode; if (!$INPUT->has('rev') && !$INPUT->has('rev2')) { global $INFO, $REV; @@ -133,14 +133,14 @@ class PageDiff extends Diff // create revision info object for older and newer sides // RevInfo1 : older, left side // RevInfo2 : newer, right side - + $changelogRev1 = $changelog->getRevisionInfo($this->rev1); $changelogRev2 = $changelog->getRevisionInfo($this->rev2); $changelogRev1['media'] = $changelogRev2['media'] = false; $this->RevInfo1 = new RevisionInfo($changelogRev1); $this->RevInfo2 = new RevisionInfo($changelogRev2); - + foreach ([$this->RevInfo1, $this->RevInfo2] as $RevInfo) { $isCurrent = $changelog->isCurrentRevision($RevInfo->val('date')); $RevInfo->isCurrent($isCurrent); @@ -156,10 +156,12 @@ class PageDiff extends Diff // msg could displayed only when wrong url typed in browser address bar if ($this->rev2 === false) { - msg(sprintf($lang['page_nonexist_rev'], + msg(sprintf( + $lang['page_nonexist_rev'], $this->id, - wl($this->id, ['do'=>'edit']), - $this->id), -1); + wl($this->id, ['do' => 'edit']), + $this->id + ), -1); } elseif (!$this->rev1 || $this->rev1 == $this->rev2) { msg('no way to compare when less than two revisions', -1); } @@ -170,9 +172,9 @@ class PageDiff extends Diff * between current page version and provided $text * or between the revisions provided via GET or POST * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { @@ -186,25 +188,25 @@ class PageDiff extends Diff } // revision title - $rev1Title = trim($this->RevInfo1->showRevisionTitle() .' '. $this->RevInfo1->showCurrentIndicator()); + $rev1Title = trim($this->RevInfo1->showRevisionTitle() . ' ' . $this->RevInfo1->showCurrentIndicator()); $rev1Summary = ($this->RevInfo1->val('date')) - ? $this->RevInfo1->showEditSummary() .' '. $this->RevInfo1->showEditor() + ? $this->RevInfo1->showEditSummary() . ' ' . $this->RevInfo1->showEditor() : ''; if ($this->RevInfo2->val('extra') == 'compareWith') { $rev2Title = $lang['yours']; $rev2Summary = ''; } else { - $rev2Title = trim($this->RevInfo2->showRevisionTitle() .' '. $this->RevInfo2->showCurrentIndicator()); + $rev2Title = trim($this->RevInfo2->showRevisionTitle() . ' ' . $this->RevInfo2->showCurrentIndicator()); $rev2Summary = ($this->RevInfo2->val('date')) - ? $this->RevInfo2->showEditSummary() .' '. $this->RevInfo2->showEditor() + ? $this->RevInfo2->showEditSummary() . ' ' . $this->RevInfo2->showEditor() : ''; } // create difference engine object $Difference = new \Diff( - explode("\n", $this->RevInfo1->val('text')), - explode("\n", $this->RevInfo2->val('text')) + explode("\n", $this->RevInfo1->val('text')), + explode("\n", $this->RevInfo2->val('text')) ); // build paired navigation @@ -217,57 +219,57 @@ class PageDiff extends Diff $this->showDiffViewSelector(); // assign minor edit checker to the variable - $classEditType = function ($changeType) { - return ($changeType === DOKU_CHANGE_TYPE_MINOR_EDIT) ? ' class="minor"' : ''; - }; + $classEditType = static fn($changeType) => ($changeType === DOKU_CHANGE_TYPE_MINOR_EDIT) + ? ' class="minor"' + : ''; // display diff view table echo '<div class="table">'; - echo '<table class="diff diff_'.hsc($this->preference['difftype']) .'">'; + echo '<table class="diff diff_' . hsc($this->preference['difftype']) . '">'; //navigation and header switch ($this->preference['difftype']) { case 'inline': - $title1 = $rev1Title . ($rev1Summary ? '<br />'.$rev1Summary : ''); - $title2 = $rev2Title . ($rev2Summary ? '<br />'.$rev2Summary : ''); + $title1 = $rev1Title . ($rev1Summary ? '<br />' . $rev1Summary : ''); + $title2 = $rev2Title . ($rev2Summary ? '<br />' . $rev2Summary : ''); // no navigation for PageConflict or PageDraft if ($this->RevInfo2->val('extra') !== 'compareWith') { echo '<tr>' - .'<td class="diff-lineheader">-</td>' - .'<td class="diffnav">'. $rev1Navi .'</td>' - .'</tr>'; + . '<td class="diff-lineheader">-</td>' + . '<td class="diffnav">' . $rev1Navi . '</td>' + . '</tr>'; echo '<tr>' - .'<th class="diff-lineheader">-</th>' - .'<th'.$classEditType($this->RevInfo1->val('type')).'>'. $title1 .'</th>' - .'</tr>'; + . '<th class="diff-lineheader">-</th>' + . '<th' . $classEditType($this->RevInfo1->val('type')) . '>' . $title1 . '</th>' + . '</tr>'; } echo '<tr>' - .'<td class="diff-lineheader">+</td>' - .'<td class="diffnav">'. $rev2Navi .'</td>' - .'</tr>'; + . '<td class="diff-lineheader">+</td>' + . '<td class="diffnav">' . $rev2Navi . '</td>' + . '</tr>'; echo '<tr>' - .'<th class="diff-lineheader">+</th>' - .'<th'.$classEditType($this->RevInfo2->val('type')).'>'. $title2 .'</th>' - .'</tr>'; + . '<th class="diff-lineheader">+</th>' + . '<th' . $classEditType($this->RevInfo2->val('type')) . '>' . $title2 . '</th>' + . '</tr>'; // create formatter object $DiffFormatter = new InlineDiffFormatter(); break; case 'sidebyside': default: - $title1 = $rev1Title . ($rev1Summary ? ' '.$rev1Summary : ''); - $title2 = $rev2Title . ($rev2Summary ? ' '.$rev2Summary : ''); + $title1 = $rev1Title . ($rev1Summary ? ' ' . $rev1Summary : ''); + $title2 = $rev2Title . ($rev2Summary ? ' ' . $rev2Summary : ''); // no navigation for PageConflict or PageDraft if ($this->RevInfo2->val('extra') !== 'compareWith') { echo '<tr>' - .'<td colspan="2" class="diffnav">'. $rev1Navi .'</td>' - .'<td colspan="2" class="diffnav">'. $rev2Navi .'</td>' - .'</tr>'; + . '<td colspan="2" class="diffnav">' . $rev1Navi . '</td>' + . '<td colspan="2" class="diffnav">' . $rev2Navi . '</td>' + . '</tr>'; } echo '<tr>' - .'<th colspan="2"'.$classEditType($this->RevInfo1->val('type')).'>'.$title1.'</th>' - .'<th colspan="2"'.$classEditType($this->RevInfo2->val('type')).'>'.$title2.'</th>' - .'</tr>'; + . '<th colspan="2"' . $classEditType($this->RevInfo1->val('type')) . '>' . $title1 . '</th>' + . '<th colspan="2"' . $classEditType($this->RevInfo2->val('type')) . '>' . $title2 . '</th>' + . '</tr>'; // create formatter object $DiffFormatter = new TableDiffFormatter(); break; @@ -301,15 +303,13 @@ class PageDiff extends Diff $form->setHiddenField('rev2[0]', $rev1); $form->setHiddenField('rev2[1]', $rev2); $form->setHiddenField('do', 'diff'); - $options = array( - 'sidebyside' => $lang['diff_side'], - 'inline' => $lang['diff_inline'], - ); + + $options = ['sidebyside' => $lang['diff_side'], 'inline' => $lang['diff_inline']]; $input = $form->addDropdown('difftype', $options, $lang['diff_type']) ->val($this->preference['difftype']) ->addClass('quickselect'); $input->useInput(false); // inhibit prefillInput() during toHTML() process - $form->addButton('do[diff]', 'Go')->attr('type','submit'); + $form->addButton('do[diff]', 'Go')->attr('type', 'submit'); echo $form->toHTML(); // show exact url reference to the view when it is meaningful @@ -338,7 +338,7 @@ class PageDiff extends Diff if ($this->RevInfo2->val('extra') == 'compareWith') { // no revisions selector for PageConflict or PageDraft - return array('', ''); + return ['', '']; } // use timestamp for current revision, date may be false when revisions < 2 @@ -353,18 +353,19 @@ class PageDiff extends Diff // build options for dropdown selector $rev1Options = $this->buildRevisionOptions('older', $revs1); $rev2Options = $this->buildRevisionOptions('newer', $revs2); - // determine previous/next revisions (older/left side) - $rev1Prev = $rev1Next = false; + $rev1Prev = false; + $rev1Next = false; if (($index = array_search($rev1, $revs1)) !== false) { - $rev1Prev = ($index +1 < count($revs1)) ? $revs1[$index +1] : false; - $rev1Next = ($index > 0) ? $revs1[$index -1] : false; + $rev1Prev = ($index + 1 < count($revs1)) ? $revs1[$index + 1] : false; + $rev1Next = ($index > 0) ? $revs1[$index - 1] : false; } // determine previous/next revisions (newer/right side) - $rev2Prev = $rev2Next = false; + $rev2Prev = false; + $rev2Next = false; if (($index = array_search($rev2, $revs2)) !== false) { - $rev2Prev = ($index +1 < count($revs2)) ? $revs2[$index +1] : false; - $rev2Next = ($index > 0) ? $revs2[$index -1] : false; + $rev2Prev = ($index + 1 < count($revs2)) ? $revs2[$index + 1] : false; + $rev2Next = ($index > 0) ? $revs2[$index - 1] : false; } /* @@ -404,7 +405,7 @@ class PageDiff extends Diff if ($rev1Next && $rev2Next) $rev2Navi .= $this->diffViewlink('diffbothnextrev', $rev1Next, $rev2Next); - return array($rev1Navi, $rev2Navi); + return [$rev1Navi, $rev2Navi]; } /** @@ -425,22 +426,23 @@ class PageDiff extends Diff foreach ($revs as $rev) { $info = $changelog->getRevisionInfo($rev); // revision info may have timestamp key when external edits occurred - $info['timestamp'] = $info['timestamp'] ?? true; + $info['timestamp'] ??= true; $date = dformat($info['date']); if ($info['timestamp'] === false) { // exteranlly deleted or older file restored - $date = preg_replace('/[0-9a-zA-Z]/','_', $date); + $date = preg_replace('/[0-9a-zA-Z]/', '_', $date); } - $options[$rev] = array( + $options[$rev] = [ 'label' => implode(' ', [ - $date, - editorinfo($info['user'], true), - $info['sum'], - ]), - 'attrs' => ['title' => $rev], - ); - if (($side == 'older' && ($rev2 && $rev >= $rev2)) - ||($side == 'newer' && ($rev <= $rev1)) + $date, + editorinfo($info['user'], true), + $info['sum'], + ]), + 'attrs' => ['title' => $rev] + ]; + if ( + ($side == 'older' && ($rev2 && $rev >= $rev2)) + || ($side == 'newer' && ($rev <= $rev1)) ) { $options[$rev]['attrs']['disabled'] = 'disabled'; } @@ -465,21 +467,20 @@ class PageDiff extends Diff $form->setHiddenField('do', 'diff'); $form->setHiddenField('difftype', $this->preference['difftype']); - switch ($side) { - case 'older': // left side - $form->setHiddenField('rev2[1]', $rev2); - $input = $form->addDropdown('rev2[0]', $options) - ->val($rev1)->addClass('quickselect'); - $input->useInput(false); // inhibit prefillInput() during toHTML() process - break; - case 'newer': // right side - $form->setHiddenField('rev2[0]', $rev1); - $input = $form->addDropdown('rev2[1]', $options) - ->val($rev2)->addClass('quickselect'); - $input->useInput(false); // inhibit prefillInput() during toHTML() process - break; + if ($side == 'older') { + // left side + $form->setHiddenField('rev2[1]', $rev2); + $input = $form->addDropdown('rev2[0]', $options) + ->val($rev1)->addClass('quickselect'); + $input->useInput(false); + } elseif ($side == 'newer') { + // right side + $form->setHiddenField('rev2[0]', $rev1); + $input = $form->addDropdown('rev2[1]', $options) + ->val($rev2)->addClass('quickselect'); + $input->useInput(false); } - $form->addButton('do[diff]', 'Go')->attr('type','submit'); + $form->addButton('do[diff]', 'Go')->attr('type', 'submit'); return $form->toHTML(); } @@ -497,25 +498,25 @@ class PageDiff extends Diff if ($rev1 === false) return ''; if ($rev2 === null) { - $urlparam = array( + $urlparam = [ 'do' => 'diff', 'rev' => $rev1, - 'difftype' => $this->preference['difftype'], - ); + 'difftype' => $this->preference['difftype'] + ]; } else { - $urlparam = array( + $urlparam = [ 'do' => 'diff', 'rev2[0]' => $rev1, 'rev2[1]' => $rev2, - 'difftype' => $this->preference['difftype'], - ); + 'difftype' => $this->preference['difftype'] + ]; } - $attr = array( + $attr = [ 'class' => $linktype, - 'href' => wl($this->id, $urlparam, true, '&'), - 'title' => $lang[$linktype], - ); - return '<a '. buildAttributes($attr) .'><span>'. $lang[$linktype] .'</span></a>'; + 'href' => wl($this->id, $urlparam, true, '&'), + 'title' => $lang[$linktype] + ]; + return '<a ' . buildAttributes($attr) . '><span>' . $lang[$linktype] . '</span></a>'; } @@ -544,8 +545,7 @@ class PageDiff extends Diff [?/,&\#;:] # no pattern - any other group of 'special' characters to insert a breaking character after )+ # end conditional expression REGEX; - return preg_replace('<'.$regex.'>xu', '\0<wbr>', $match[0]); + return preg_replace('<' . $regex . '>xu', '\0<wbr>', $match[0]); }, $diffhtml); } - } diff --git a/inc/Ui/PageDraft.php b/inc/Ui/PageDraft.php index c4c4f5261..967c30b53 100644 --- a/inc/Ui/PageDraft.php +++ b/inc/Ui/PageDraft.php @@ -16,9 +16,9 @@ class PageDraft extends Ui * Display the Page Draft Form * ask the user about how to handle an exisiting draft * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { @@ -26,10 +26,10 @@ class PageDraft extends Ui global $lang; $draft = new Draft($INFO['id'], $INFO['client']); - $text = $draft->getDraftText(); + $text = $draft->getDraftText(); // print intro - print p_locale_xhtml('draft'); + echo p_locale_xhtml('draft'); // print difference (new PageDiff($INFO['id']))->compareWith($text)->preference('showIntro', false)->show(); @@ -44,12 +44,11 @@ class PageDraft extends Ui $form->addTagOpen('div')->id('draft__status'); $form->addHTML($draft->getDraftMessage()); $form->addTagClose('div'); - $form->addButton('do[recover]', $lang['btn_recover'] )->attrs(['type' => 'submit', 'tabindex' => '1']); + $form->addButton('do[recover]', $lang['btn_recover'])->attrs(['type' => 'submit', 'tabindex' => '1']); $form->addButton('do[draftdel]', $lang['btn_draftdel'])->attrs(['type' => 'submit', 'tabindex' => '2']); - $form->addButton('do[show]', $lang['btn_cancel'] )->attrs(['type' => 'submit', 'tabindex' => '3']); + $form->addButton('do[show]', $lang['btn_cancel'])->attrs(['type' => 'submit', 'tabindex' => '3']); $form->addTagClose('div'); - print $form->toHTML('Draft'); + echo $form->toHTML('Draft'); } - } diff --git a/inc/Ui/PageRevisions.php b/inc/Ui/PageRevisions.php index 9ef80e8bc..6f62cfef7 100644 --- a/inc/Ui/PageRevisions.php +++ b/inc/Ui/PageRevisions.php @@ -19,7 +19,7 @@ class PageRevisions extends Revisions /** * PageRevisions Ui constructor * - * @param string $id id of page + * @param string $id id of page */ public function __construct($id = null) { @@ -37,13 +37,13 @@ class PageRevisions extends Revisions /** * Display list of old revisions of the page * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Ben Coburn <btcoburn@silicodon.net> + * @param int $first skip the first n changelog lines + * @return void * @author Kate Arzamastseva <pshns@ukr.net> * @author Satoshi Sahara <sahara.satoshi@gmail.com> * - * @param int $first skip the first n changelog lines - * @return void + * @author Andreas Gohr <andi@splitbrain.org> + * @author Ben Coburn <btcoburn@silicodon.net> */ public function show($first = -1) { @@ -56,12 +56,12 @@ class PageRevisions extends Revisions $revisions = $this->getRevisions($first, $hasNext); // print intro - print p_locale_xhtml('revisions'); + echo p_locale_xhtml('revisions'); // create the form $form = new Form([ - 'id' => 'page__revisions', - 'class' => 'changes', + 'id' => 'page__revisions', + 'class' => 'changes', ]); $form->addTagOpen('div')->addClass('no'); @@ -80,11 +80,11 @@ class PageRevisions extends Revisions if ($RevInfo->isCurrent()) { $form->addCheckbox('rev2[]')->val($rev); } elseif ($rev == $REV) { - $form->addCheckbox('rev2[]')->val($rev)->attr('checked','checked'); + $form->addCheckbox('rev2[]')->val($rev)->attr('checked', 'checked'); } elseif (page_exists($this->id, $rev)) { $form->addCheckbox('rev2[]')->val($rev); } else { - $form->addCheckbox('')->val($rev)->attr('disabled','disabled'); + $form->addCheckbox('')->val($rev)->attr('disabled', 'disabled'); } $form->addHTML(' '); @@ -108,11 +108,9 @@ class PageRevisions extends Revisions $form->addTagClose('div'); // close div class=no - print $form->toHTML('Revisions'); + echo $form->toHTML('Revisions'); // provide navigation for paginated revision list (of pages and/or media files) - print $this->navigation($first, $hasNext, function ($n) { - return array('do' => 'revisions', 'first' => $n); - }); + echo $this->navigation($first, $hasNext, static fn($n) => ['do' => 'revisions', 'first' => $n]); } } diff --git a/inc/Ui/PageView.php b/inc/Ui/PageView.php index a85c2d076..504fad068 100644 --- a/inc/Ui/PageView.php +++ b/inc/Ui/PageView.php @@ -13,10 +13,10 @@ class PageView extends Ui { protected $text; - /** + /** * PageView Ui constructor * - * @param null|string $text wiki text or null for showing $ID + * @param null|string $text wiki text or null for showing $ID */ public function __construct($text = null) { @@ -26,10 +26,10 @@ class PageView extends Ui /** * Show a wiki page * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * * @triggers HTML_SHOWREV_OUTPUT - * @return void */ public function show() { @@ -58,11 +58,10 @@ class PageView extends Ui echo $html; echo '<div class="clearer"></div>'; echo '</div></div>'; - } else { if ($REV || $DATE_AT) { // print intro for old revisions - $data = array('rev' => &$REV, 'date_at' => &$DATE_AT); + $data = ['rev' => &$REV, 'date_at' => &$DATE_AT]; Event::createAndTrigger('HTML_SHOWREV_OUTPUT', $data, [$this, 'showrev']); } $html = p_wiki_xhtml($ID, $REV, true, $DATE_AT); @@ -80,8 +79,6 @@ class PageView extends Ui */ public function showrev() { - print p_locale_xhtml('showrev'); + echo p_locale_xhtml('showrev'); } - - } diff --git a/inc/Ui/Recent.php b/inc/Ui/Recent.php index 7a6cc86b2..810e20cee 100644 --- a/inc/Ui/Recent.php +++ b/inc/Ui/Recent.php @@ -2,8 +2,8 @@ namespace dokuwiki\Ui; -use dokuwiki\ChangeLog\PageChangeLog; use dokuwiki\ChangeLog\MediaChangeLog; +use dokuwiki\ChangeLog\PageChangeLog; use dokuwiki\ChangeLog\RevisionInfo; use dokuwiki\Form\Form; @@ -20,25 +20,25 @@ class Recent extends Ui /** * Recent Ui constructor * - * @param int $first skip the first n changelog lines - * @param string $show_changes type of changes to show; 'pages', 'mediafiles', or 'both' + * @param int $first skip the first n changelog lines + * @param string $show_changes type of changes to show; 'pages', 'mediafiles', or 'both' */ public function __construct($first = 0, $show_changes = 'both') { - $this->first = $first; + $this->first = $first; $this->show_changes = $show_changes; } /** * Display recent changes * - * @author Andreas Gohr <andi@splitbrain.org> + * @return void * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> * @author Ben Coburn <btcoburn@silicodon.net> * @author Kate Arzamastseva <pshns@ukr.net> * @author Satoshi Sahara <sahara.satoshi@gmail.com> * - * @return void + * @author Andreas Gohr <andi@splitbrain.org> */ public function show() { @@ -51,16 +51,16 @@ class Recent extends Ui $recents = $this->getRecents($first, $hasNext); // print intro - print p_locale_xhtml('recent'); + echo p_locale_xhtml('recent'); if (getNS($ID) != '') { - print '<div class="level1"><p>' + echo '<div class="level1"><p>' . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent')) - .'</p></div>'; + . '</p></div>'; } // create the form - $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']); + $form = new Form(['id' => 'dw__recent', 'method' => 'GET', 'action' => wl($ID), 'class' => 'changes']); $form->addTagOpen('div')->addClass('no'); $form->setHiddenField('sectok', null); $form->setHiddenField('do', 'recent'); @@ -79,7 +79,7 @@ class Recent extends Ui $RevInfo = new RevisionInfo($recent); $RevInfo->isCurrent(true); - $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': ''; + $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : ''; $form->addTagOpen('li')->addClass($class); $form->addTagOpen('div')->addClass('li'); $html = implode(' ', [ @@ -103,13 +103,13 @@ class Recent extends Ui // provide navigation for paginated recent list (of pages and/or media files) $form->addHTML($this->htmlNavigation($first, $hasNext)); - print $form->toHTML('Recent'); + echo $form->toHTML('Recent'); } /** * Get recent items, and set correct pagination parameters (first, hasNext) * - * @param int $first + * @param int $first * @param bool $hasNext * @return array recent items to be shown in a paginated list * @@ -175,7 +175,7 @@ class Recent extends Ui /** * Navigation buttons for Pagination (prev/next) * - * @param int $first + * @param int $first * @param bool $hasNext * @return string html */ @@ -187,22 +187,22 @@ class Recent extends Ui $html = '<div class="pagenav">'; if ($first > 0) { $first = max($first - $conf['recent'], 0); - $html.= '<div class="pagenav-prev">'; - $html.= '<button type="submit" name="first['.$first.']" accesskey="n"' - . ' title="'.$lang['btn_newer'].' [N]" class="button show">' - . $lang['btn_newer'] - . '</button>'; - $html.= '</div>'; + $html .= '<div class="pagenav-prev">'; + $html .= '<button type="submit" name="first[' . $first . ']" accesskey="n"' + . ' title="' . $lang['btn_newer'] . ' [N]" class="button show">' + . $lang['btn_newer'] + . '</button>'; + $html .= '</div>'; } if ($hasNext) { - $html.= '<div class="pagenav-next">'; - $html.= '<button type="submit" name="first['.$last.']" accesskey="p"' - . ' title="'.$lang['btn_older'].' [P]" class="button show">' - . $lang['btn_older'] - . '</button>'; - $html.= '</div>'; + $html .= '<div class="pagenav-next">'; + $html .= '<button type="submit" name="first[' . $last . ']" accesskey="p"' + . ' title="' . $lang['btn_older'] . ' [P]" class="button show">' + . $lang['btn_older'] + . '</button>'; + $html .= '</div>'; } - $html.= '</div>'; + $html .= '</div>'; return $html; } @@ -217,15 +217,14 @@ class Recent extends Ui global $lang; $form->addTagOpen('div')->addClass('changeType'); - $options = array( - 'pages' => $lang['pages_changes'], - 'mediafiles' => $lang['media_changes'], - 'both' => $lang['both_changes'], - ); + $options = [ + 'pages' => $lang['pages_changes'], + 'mediafiles' => $lang['media_changes'], + 'both' => $lang['both_changes'] + ]; $form->addDropdown('show_changes', $options, $lang['changes_type']) - ->val($this->show_changes)->addClass('quickselect'); - $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit'); + ->val($this->show_changes)->addClass('quickselect'); + $form->addButton('do[recent]', $lang['btn_apply'])->attr('type', 'submit'); $form->addTagClose('div'); } - } diff --git a/inc/Ui/Revisions.php b/inc/Ui/Revisions.php index e47a609b9..d231be207 100644 --- a/inc/Ui/Revisions.php +++ b/inc/Ui/Revisions.php @@ -110,5 +110,4 @@ abstract class Revisions extends Ui $html .= '</div>'; return $html; } - } diff --git a/inc/Ui/Search.php b/inc/Ui/Search.php index e32101fb5..62a254046 100644 --- a/inc/Ui/Search.php +++ b/inc/Ui/Search.php @@ -12,16 +12,16 @@ class Search extends Ui protected $query; protected $parsedQuery; protected $searchState; - protected $pageLookupResults = array(); - protected $fullTextResults = array(); - protected $highlight = array(); + protected $pageLookupResults = []; + protected $fullTextResults = []; + protected $highlight = []; /** * Search constructor. * * @param array $pageLookupResults pagename lookup results in the form [pagename => pagetitle] * @param array $fullTextResults fulltext search results in the form [pagename => #hits] - * @param array $highlight array of strings to be highlighted + * @param array $highlight array of strings to be highlighted */ public function __construct(array $pageLookupResults, array $fullTextResults, $highlight) { @@ -142,7 +142,6 @@ class Search extends Ui $searchForm->addTagClose('ul'); $searchForm->addTagClose('div'); - } /** @@ -152,7 +151,8 @@ class Search extends Ui * * @return bool */ - protected function isNamespaceAssistanceAvailable(array $parsedQuery) { + protected function isNamespaceAssistanceAvailable(array $parsedQuery) + { if (preg_match('/[\(\)\|]/', $parsedQuery['query']) === 1) { return false; } @@ -167,7 +167,8 @@ class Search extends Ui * * @return bool */ - protected function isFragmentAssistanceAvailable(array $parsedQuery) { + protected function isFragmentAssistanceAvailable(array $parsedQuery) + { if (preg_match('/[\(\)\|]/', $parsedQuery['query']) === 1) { return false; } @@ -214,39 +215,23 @@ class Search extends Ui $options = [ 'exact' => [ 'label' => $lang['search_exact_match'], - 'and' => array_map(function ($term) { - return trim($term, '*'); - }, $this->parsedQuery['and']), - 'not' => array_map(function ($term) { - return trim($term, '*'); - }, $this->parsedQuery['not']), + 'and' => array_map(static fn($term) => trim($term, '*'), $this->parsedQuery['and']), + 'not' => array_map(static fn($term) => trim($term, '*'), $this->parsedQuery['not']), ], 'starts' => [ 'label' => $lang['search_starts_with'], - 'and' => array_map(function ($term) { - return trim($term, '*') . '*'; - }, $this->parsedQuery['and']), - 'not' => array_map(function ($term) { - return trim($term, '*') . '*'; - }, $this->parsedQuery['not']), + 'and' => array_map(static fn($term) => trim($term, '*') . '*', $this->parsedQuery['and']), + 'not' => array_map(static fn($term) => trim($term, '*') . '*', $this->parsedQuery['not']), ], 'ends' => [ 'label' => $lang['search_ends_with'], - 'and' => array_map(function ($term) { - return '*' . trim($term, '*'); - }, $this->parsedQuery['and']), - 'not' => array_map(function ($term) { - return '*' . trim($term, '*'); - }, $this->parsedQuery['not']), + 'and' => array_map(static fn($term) => '*' . trim($term, '*'), $this->parsedQuery['and']), + 'not' => array_map(static fn($term) => '*' . trim($term, '*'), $this->parsedQuery['not']), ], 'contains' => [ 'label' => $lang['search_contains'], - 'and' => array_map(function ($term) { - return '*' . trim($term, '*') . '*'; - }, $this->parsedQuery['and']), - 'not' => array_map(function ($term) { - return '*' . trim($term, '*') . '*'; - }, $this->parsedQuery['not']), + 'and' => array_map(static fn($term) => '*' . trim($term, '*') . '*', $this->parsedQuery['and']), + 'not' => array_map(static fn($term) => '*' . trim($term, '*') . '*', $this->parsedQuery['not']), ] ]; @@ -284,8 +269,7 @@ class Search extends Ui } else { $link = $this->searchState ->withFragments($option['and'], $option['not']) - ->getSearchLink($option['label']) - ; + ->getSearchLink($option['label']); $searchForm->addHTML($link); } $searchForm->addTagClose('li'); @@ -353,7 +337,6 @@ class Search extends Ui $searchForm->addTagClose('ul'); $searchForm->addTagClose('div'); - } /** @@ -380,7 +363,7 @@ class Search extends Ui if (empty($namespaces[$subtopNS])) { $namespaces[$subtopNS] = 0; } - $namespaces[$subtopNS] += 1; + ++$namespaces[$subtopNS]; } Sort::ksort($namespaces); arsort($namespaces); @@ -447,8 +430,7 @@ class Search extends Ui } else { $link = $this->searchState ->withTimeLimitations($option['after'], $option['before']) - ->getSearchLink($option['label']) - ; + ->getSearchLink($option['label']); $searchForm->addHTML($link); } $searchForm->addTagClose('li'); @@ -480,8 +462,8 @@ class Search extends Ui $pagecreateinfo = sprintf($lang['searchcreatepage'], $createQueryPageLink); } return str_replace( - array('@QUERY@', '@SEARCH@', '@CREATEPAGEINFO@'), - array(hsc(rawurlencode($query)), hsc($query), $pagecreateinfo), + ['@QUERY@', '@SEARCH@', '@CREATEPAGEINFO@'], + [hsc(rawurlencode($query)), hsc($query), $pagecreateinfo], $intro ); } @@ -503,7 +485,7 @@ class Search extends Ui if (!empty($parsedQuery['ns'])) { $pagename .= ':' . cleanID($parsedQuery['ns'][0]); } - $pagename .= ':' . cleanID(implode(' ' , $parsedQuery['highlight'])); + $pagename .= ':' . cleanID(implode(' ', $parsedQuery['highlight'])); return $pagename; } @@ -525,7 +507,7 @@ class Search extends Ui $html = '<div class="search_quickresult">'; $html .= '<h2>' . $lang['quickhits'] . ':</h2>'; $html .= '<ul class="search_quickhits">'; - foreach ($data as $id => $title) { + foreach (array_keys($data) as $id) { $name = null; if (!useHeading('navigation') && $ns = getNS($id)) { $name = shorten(noNS($id), ' (' . $ns . ')', 30); @@ -549,7 +531,7 @@ class Search extends Ui /** * Build HTML for fulltext search results or "no results" message * - * @param array $data the results of the fulltext search + * @param array $data the results of the fulltext search * @param array $highlight the terms to be highlighted in the results * * @return string @@ -570,7 +552,7 @@ class Search extends Ui $position = 0; foreach ($data as $id => $cnt) { - $position += 1; + ++$position; $resultLink = html_wikilink(':' . $id, null, $highlight); $resultHeader = [$resultLink]; diff --git a/inc/Ui/SearchState.php b/inc/Ui/SearchState.php index eb3f7faeb..7b28ae373 100644 --- a/inc/Ui/SearchState.php +++ b/inc/Ui/SearchState.php @@ -34,7 +34,7 @@ class SearchState * Get a search state for the current search limited to a new namespace * * @param string $ns the namespace to which to limit the search, falsy to remove the limitation - * @param array $notns + * @param array $notns * * @return SearchState */ diff --git a/inc/Ui/Subscribe.php b/inc/Ui/Subscribe.php index 80352d7fd..949593706 100644 --- a/inc/Ui/Subscribe.php +++ b/inc/Ui/Subscribe.php @@ -14,9 +14,9 @@ class Subscribe extends Ui /** * Display the subscribe form * + * @return void * @author Adrian Lang <lang@cosmocode.de> * - * @return void */ public function show() { @@ -31,34 +31,34 @@ class Subscribe extends Ui echo p_locale_xhtml('subscr_form'); // list up current subscriptions - echo '<h2>'.$lang['subscr_m_current_header'].'</h2>'; + echo '<h2>' . $lang['subscr_m_current_header'] . '</h2>'; echo '<div class="level2">'; if ($INFO['subscribed'] === false) { - echo '<p>'.$lang['subscr_m_not_subscribed'].'</p>'; + echo '<p>' . $lang['subscr_m_not_subscribed'] . '</p>'; } else { echo '<ul>'; foreach ($INFO['subscribed'] as $sub) { echo '<li><div class="li">'; if ($sub['target'] !== $ID) { - echo '<code class="ns">'.hsc(prettyprint_id($sub['target'])).'</code>'; + echo '<code class="ns">' . hsc(prettyprint_id($sub['target'])) . '</code>'; } else { - echo '<code class="page">'.hsc(prettyprint_id($sub['target'])).'</code>'; + echo '<code class="page">' . hsc(prettyprint_id($sub['target'])) . '</code>'; } - $sstl = sprintf($lang['subscr_style_'.$sub['style']], $stime_days); + $sstl = sprintf($lang['subscr_style_' . $sub['style']], $stime_days); if (!$sstl) $sstl = hsc($sub['style']); - echo ' ('.$sstl.') '; + echo ' (' . $sstl . ') '; - echo '<a href="'.wl( + echo '<a href="' . wl( $ID, - array( - 'do' => 'subscribe', - 'sub_target'=> $sub['target'], - 'sub_style' => $sub['style'], - 'sub_action'=> 'unsubscribe', - 'sectok' => getSecurityToken() - ) - ). - '" class="unsubscribe">'.$lang['subscr_m_unsubscribe']. + [ + 'do' => 'subscribe', + 'sub_target' => $sub['target'], + 'sub_style' => $sub['style'], + 'sub_action' => 'unsubscribe', + 'sectok' => getSecurityToken() + ] + ) . + '" class="unsubscribe">' . $lang['subscr_m_unsubscribe'] . '</a></div></li>'; } echo '</ul>'; @@ -66,17 +66,17 @@ class Subscribe extends Ui echo '</div>'; // Add new subscription form - echo '<h2>'.$lang['subscr_m_new_header'].'</h2>'; + echo '<h2>' . $lang['subscr_m_new_header'] . '</h2>'; echo '<div class="level2">'; - $ns = getNS($ID).':'; + $ns = getNS($ID) . ':'; $targets = [ - $ID => '<code class="page">'.prettyprint_id($ID).'</code>', - $ns => '<code class="ns">'.prettyprint_id($ns).'</code>', + $ID => '<code class="page">' . prettyprint_id($ID) . '</code>', + $ns => '<code class="ns">' . prettyprint_id($ns) . '</code>', ]; $styles = [ - 'every' => $lang['subscr_style_every'], + 'every' => $lang['subscr_style_every'], 'digest' => sprintf($lang['subscr_style_digest'], $stime_days), - 'list' => sprintf($lang['subscr_style_list'], $stime_days), + 'list' => sprintf($lang['subscr_style_list'], $stime_days), ]; // create the form @@ -87,8 +87,9 @@ class Subscribe extends Ui $form->setHiddenField('sub_action', 'subscribe'); $form->addFieldsetOpen($lang['subscr_m_subscribe']); + $value = (array_key_exists($INPUT->post->str('sub_target'), $targets)) ? - $INPUT->str('sub_target') : key($targets); + $INPUT->str('sub_target') : key($targets); foreach ($targets as $val => $label) { $data = ($value === $val) ? ['checked' => 'checked'] : []; $form->addRadioButton('sub_target', $label)->val($val)->attrs($data); @@ -96,8 +97,9 @@ class Subscribe extends Ui $form->addFieldsetClose(); $form->addFieldsetOpen($lang['subscr_m_receive']); + $value = (array_key_exists($INPUT->post->str('sub_style'), $styles)) ? - $INPUT->str('sub_style') : key($styles); + $INPUT->str('sub_style') : key($styles); foreach ($styles as $val => $label) { $data = ($value === $val) ? ['checked' => 'checked'] : []; $form->addRadioButton('sub_style', $label)->val($val)->attrs($data); @@ -107,9 +109,8 @@ class Subscribe extends Ui $form->addButton('do[subscribe]', $lang['subscr_m_subscribe'])->attr('type', 'submit'); $form->addTagClose('div'); - print $form->toHTML('Subscribe'); + echo $form->toHTML('Subscribe'); echo '</div>'; } - } diff --git a/inc/Ui/Ui.php b/inc/Ui/Ui.php index 57d0c2998..703e8e88d 100644 --- a/inc/Ui/Ui.php +++ b/inc/Ui/Ui.php @@ -17,5 +17,4 @@ abstract class Ui * @return void */ abstract public function show(); - } diff --git a/inc/Ui/UserProfile.php b/inc/Ui/UserProfile.php index c1d20c281..90e3d4571 100644 --- a/inc/Ui/UserProfile.php +++ b/inc/Ui/UserProfile.php @@ -15,9 +15,9 @@ class UserProfile extends Ui /** * Display the User Profile Form Panel * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { @@ -29,8 +29,8 @@ class UserProfile extends Ui global $auth; // print intro - print p_locale_xhtml('updateprofile'); - print '<div class="centeralign">'; + echo p_locale_xhtml('updateprofile'); + echo '<div class="centeralign">'; $fullname = $INPUT->post->str('fullname', $INFO['userinfo']['name'], true); $email = $INPUT->post->str('email', $INFO['userinfo']['mail'], true); @@ -42,20 +42,20 @@ class UserProfile extends Ui $form->setHiddenField('do', 'profile'); $form->setHiddenField('save', '1'); - $attr = array('size' => '50', 'disabled' => 'disabled'); + $attr = ['size' => '50', 'disabled' => 'disabled']; $input = $form->addTextInput('login', $lang['user'])->attrs($attr)->addClass('edit') ->val($INPUT->server->str('REMOTE_USER')); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); - $attr = array('size' => '50'); + $attr = ['size' => '50']; if (!$auth->canDo('modName')) $attr['disabled'] = 'disabled'; $input = $form->addTextInput('fullname', $lang['fullname'])->attrs($attr)->addClass('edit') ->val($fullname); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); - $attr = array('type' => 'email', 'size' => '50'); + $attr = ['type' => 'email', 'size' => '50']; if (!$auth->canDo('modMail')) $attr['disabled'] = 'disabled'; $input = $form->addTextInput('email', $lang['email'])->attrs($attr)->addClass('edit') ->val($email); @@ -63,7 +63,7 @@ class UserProfile extends Ui $form->addHTML("<br>\n"); if ($auth->canDo('modPass')) { - $attr = array('size'=>'50'); + $attr = ['size' => '50']; $input = $form->addPasswordInput('newpass', $lang['newpass'])->attrs($attr)->addClass('edit'); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); @@ -75,7 +75,7 @@ class UserProfile extends Ui if ($conf['profileconfirm']) { $form->addHTML("<br>\n"); - $attr = array('size' => '50', 'required' => 'required'); + $attr = ['size' => '50', 'required' => 'required']; $input = $form->addPasswordInput('oldpass', $lang['oldpass'])->attrs($attr)->addClass('edit'); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); @@ -87,11 +87,10 @@ class UserProfile extends Ui $form->addFieldsetClose(); $form->addTagClose('div'); - print $form->toHTML('UpdateProfile'); + echo $form->toHTML('UpdateProfile'); if ($auth->canDo('delUser') && actionOK('profile_delete')) { - // create the profiledelete form $form = new Form(['id' => 'dw__profiledelete']); $form->addTagOpen('div')->addClass('no'); @@ -106,7 +105,7 @@ class UserProfile extends Ui if ($conf['profileconfirm']) { $form->addHTML("<br>\n"); - $attr = array('size' => '50', 'required' => 'required'); + $attr = ['size' => '50', 'required' => 'required']; $input = $form->addPasswordInput('oldpass', $lang['oldpass'])->attrs($attr) ->addClass('edit'); $input->getLabel()->attr('class', 'block'); @@ -117,10 +116,9 @@ class UserProfile extends Ui $form->addFieldsetClose(); $form->addTagClose('div'); - print $form->toHTML('ProfileDelete'); + echo $form->toHTML('ProfileDelete'); } - print '</div>'; + echo '</div>'; } - } diff --git a/inc/Ui/UserRegister.php b/inc/Ui/UserRegister.php index 26da3933e..7f719b331 100644 --- a/inc/Ui/UserRegister.php +++ b/inc/Ui/UserRegister.php @@ -14,9 +14,9 @@ class UserRegister extends Ui /** * Display the User Registration Form Panel * + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void */ public function show() { @@ -24,12 +24,12 @@ class UserRegister extends Ui global $conf; global $INPUT; - $base_attrs = array('size' => '50', 'required' => 'required'); - $email_attrs = $base_attrs + array('type' => 'email'); + $base_attrs = ['size' => '50', 'required' => 'required']; + $email_attrs = $base_attrs + ['type' => 'email']; // print intro - print p_locale_xhtml('register'); - print '<div class="centeralign">'; + echo p_locale_xhtml('register'); + echo '<div class="centeralign">'; // create the login form $form = new Form(['id' => 'dw__register']); @@ -66,9 +66,8 @@ class UserRegister extends Ui $form->addFieldsetClose(); $form->addTagClose('div'); - print $form->toHTML('Register'); + echo $form->toHTML('Register'); - print '</div>'; + echo '</div>'; } - } diff --git a/inc/Ui/UserResendPwd.php b/inc/Ui/UserResendPwd.php index 65cd2151e..62f9afe22 100644 --- a/inc/Ui/UserResendPwd.php +++ b/inc/Ui/UserResendPwd.php @@ -14,10 +14,10 @@ class UserResendPwd extends Ui /** * Display the form to request a new password for an existing account * - * @author Benoit Chesneau <benoit@bchesneau.info> + * @return void * @author Andreas Gohr <andi@splitbrain.org> * - * @return void + * @author Benoit Chesneau <benoit@bchesneau.info> */ public function show() { @@ -27,8 +27,8 @@ class UserResendPwd extends Ui $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); // print intro - print p_locale_xhtml('resetpwd'); - print '<div class="centeralign">'; + echo p_locale_xhtml('resetpwd'); + echo '<div class="centeralign">'; if (!$conf['autopasswd'] && $token) { $form = $this->formSetNewPassword($token); @@ -36,9 +36,9 @@ class UserResendPwd extends Ui $form = $this->formResendPassword(); } - print $form->toHTML('ResendPwd'); + echo $form->toHTML('ResendPwd'); - print '</div>'; + echo '</div>'; } /** @@ -57,6 +57,7 @@ class UserResendPwd extends Ui $form->addFieldsetOpen($lang['btn_resendpwd']); $form->setHiddenField('token', $token); $form->setHiddenField('do', 'resendpwd'); + $input = $form->addPasswordInput('pass', $lang['pass'])->attr('size', '50')->addClass('edit'); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); @@ -85,6 +86,7 @@ class UserResendPwd extends Ui $form->setHiddenField('do', 'resendpwd'); $form->setHiddenField('save', '1'); $form->addHTML("<br>\n"); + $input = $form->addTextInput('login', $lang['user'])->addClass('edit'); $input->getLabel()->attr('class', 'block'); $form->addHTML("<br>\n"); @@ -94,5 +96,4 @@ class UserResendPwd extends Ui $form->addTagClose('div'); return $form; } - } diff --git a/inc/Utf8/Asian.php b/inc/Utf8/Asian.php index c7baa3029..75406594a 100644 --- a/inc/Utf8/Asian.php +++ b/inc/Utf8/Asian.php @@ -11,13 +11,12 @@ namespace dokuwiki\Utf8; */ class Asian { - /** * This defines a non-capturing group for the use in regular expressions to match any asian character that * needs to be treated as a word. Uses the Unicode-Ranges for Asian characters taken from * http://en.wikipedia.org/wiki/Unicode_block */ - const REGEXP = + public const REGEXP = '(?:' . '[\x{0E00}-\x{0E7F}]' . // Thai diff --git a/inc/Utf8/Clean.php b/inc/Utf8/Clean.php index 0975ff559..434da7043 100644 --- a/inc/Utf8/Clean.php +++ b/inc/Utf8/Clean.php @@ -200,5 +200,4 @@ class Clean return $i; } - } diff --git a/inc/Utf8/Conversion.php b/inc/Utf8/Conversion.php index fad9cd0b1..acde3fb2f 100644 --- a/inc/Utf8/Conversion.php +++ b/inc/Utf8/Conversion.php @@ -7,7 +7,6 @@ namespace dokuwiki\Utf8; */ class Conversion { - /** * Encodes UTF-8 characters to HTML entities * @@ -58,14 +57,14 @@ class Conversion if (!$entities) { return preg_replace_callback( '/(&#([Xx])?([0-9A-Za-z]+);)/m', - [__CLASS__, 'decodeNumericEntity'], + [self::class, 'decodeNumericEntity'], $str ); } return preg_replace_callback( '/&(#)?([Xx])?([0-9A-Za-z]+);/m', - [__CLASS__, 'decodeAnyEntity'], + [self::class, 'decodeAnyEntity'], $str ); } @@ -84,9 +83,7 @@ class Conversion $table = get_html_translation_table(HTML_ENTITIES); $table = array_flip($table); $table = array_map( - static function ($c) { - return Unicode::toUtf8(array(ord($c))); - }, + static fn($c) => Unicode::toUtf8([ord($c)]), $table ); } @@ -116,10 +113,10 @@ class Conversion $cp = hexdec($ent[3]); break; default: - $cp = intval($ent[3]); + $cp = (int) $ent[3]; break; } - return Unicode::toUtf8(array($cp)); + return Unicode::toUtf8([$cp]); } /** @@ -158,5 +155,4 @@ class Conversion $uni = unpack('n*', $str); return Unicode::toUtf8($uni); } - } diff --git a/inc/Utf8/PhpString.php b/inc/Utf8/PhpString.php index d382f14aa..6d9a8d547 100644 --- a/inc/Utf8/PhpString.php +++ b/inc/Utf8/PhpString.php @@ -7,7 +7,6 @@ namespace dokuwiki\Utf8; */ class PhpString { - /** * A locale independent basename() implementation * @@ -138,29 +137,21 @@ class PhpString if ($length === null) { $length_pattern = '(.*)$'; // the rest of the string } else { - if (!isset($strlen)) $strlen = self::strlen($str); // see notes if ($offset > $strlen) return ''; // another trivial case if ($length > 0) { - // reduce any length that would go past the end of the string $length = min($strlen - $offset, $length); - $Lx = (int)($length / 65535); $Ly = $length % 65535; - // +ve length requires ... a captured group of length characters if ($Lx) $length_pattern = '(?:.{65535}){' . $Lx . '}'; $length_pattern = '(' . $length_pattern . '.{' . $Ly . '})'; - - } else if ($length < 0) { - + } elseif ($length < 0) { if ($length < ($offset - $strlen)) return ''; - $Lx = (int)((-$length) / 65535); $Ly = (-$length) % 65535; - // -ve length requires ... capture everything except a group of -length characters // anchored at the tail-end of the string if ($Lx) $length_pattern = '(?:.{65535}){' . $Lx . '}'; @@ -268,7 +259,7 @@ class PhpString */ public static function strtolower($string) { - if($string === null) return ''; // pre-8.1 behaviour + if ($string === null) return ''; // pre-8.1 behaviour if (UTF8_MBSTRING) { if (class_exists('Normalizer', $autoload = false)) { return \Normalizer::normalize(mb_strtolower($string, 'utf-8')); @@ -379,6 +370,4 @@ class PhpString return $length; } - - } diff --git a/inc/Utf8/Sort.php b/inc/Utf8/Sort.php index decb058a7..9f066b050 100644 --- a/inc/Utf8/Sort.php +++ b/inc/Utf8/Sort.php @@ -55,7 +55,9 @@ class Sort 'Collator created with locale "' . $lc . '": numeric collation on, ' . 'valid locale "' . $collator->getLocale(\Locale::VALID_LOCALE) . '", ' . 'actual locale "' . $collator->getLocale(\Locale::ACTUAL_LOCALE) . '"', - null, __FILE__, __LINE__ + null, + __FILE__, + __LINE__ ); self::$collators[$lc] = $collator; } @@ -128,7 +130,7 @@ class Sort { $collator = self::getCollator(); if (isset($collator)) { - return uksort($array, array($collator, 'compare')); + return uksort($array, [$collator, 'compare']); } else { return ksort($array, SORT_NATURAL | SORT_FLAG_CASE); } diff --git a/inc/Utf8/Table.php b/inc/Utf8/Table.php index 8683c9238..f618c69ea 100644 --- a/inc/Utf8/Table.php +++ b/inc/Utf8/Table.php @@ -9,7 +9,6 @@ namespace dokuwiki\Utf8; */ class Table { - /** * Get the upper to lower case conversion table * diff --git a/inc/Utf8/Unicode.php b/inc/Utf8/Unicode.php index 4b6426533..31faf95d7 100644 --- a/inc/Utf8/Unicode.php +++ b/inc/Utf8/Unicode.php @@ -7,7 +7,6 @@ namespace dokuwiki\Utf8; */ class Unicode { - /** * Takes an UTF-8 string and returns an array of ints representing the * Unicode characters. Astral planes are supported ie. the ints in the @@ -40,45 +39,39 @@ class Unicode $mUcs4 = 0; // cached Unicode character $mBytes = 1; // cached expected number of octets in the current sequence - $out = array(); + $out = []; $len = strlen($str); for ($i = 0; $i < $len; $i++) { - $in = ord($str[$i]); if ($mState === 0) { - // When mState is zero we expect either a US-ASCII character or a // multi-octet sequence. if (0 === (0x80 & $in)) { // US-ASCII, pass straight through. $out[] = $in; $mBytes = 1; - - } else if (0xC0 === (0xE0 & $in)) { + } elseif (0xC0 === (0xE0 & $in)) { // First octet of 2 octet sequence $mUcs4 = $in; $mUcs4 = ($mUcs4 & 0x1F) << 6; $mState = 1; $mBytes = 2; - - } else if (0xE0 === (0xF0 & $in)) { + } elseif (0xE0 === (0xF0 & $in)) { // First octet of 3 octet sequence $mUcs4 = $in; $mUcs4 = ($mUcs4 & 0x0F) << 12; $mState = 2; $mBytes = 3; - - } else if (0xF0 === (0xF8 & $in)) { + } elseif (0xF0 === (0xF8 & $in)) { // First octet of 4 octet sequence $mUcs4 = $in; $mUcs4 = ($mUcs4 & 0x07) << 18; $mState = 3; $mBytes = 4; - - } else if (0xF8 === (0xFC & $in)) { + } elseif (0xF8 === (0xFC & $in)) { /* First octet of 5 octet sequence. * * This is illegal because the encoded codepoint must be either @@ -91,14 +84,12 @@ class Unicode $mUcs4 = ($mUcs4 & 0x03) << 24; $mState = 4; $mBytes = 5; - - } else if (0xFC === (0xFE & $in)) { + } elseif (0xFC === (0xFE & $in)) { // First octet of 6 octet sequence, see comments for 5 octet sequence. $mUcs4 = $in; $mUcs4 = ($mUcs4 & 1) << 30; $mState = 5; $mBytes = 6; - } elseif ($strict) { /* Current octet is neither in the US-ASCII range nor a legal first * octet of a multi-octet sequence. @@ -109,76 +100,67 @@ class Unicode E_USER_WARNING ); return false; - } - - } else { - + } elseif (0x80 === (0xC0 & $in)) { // When mState is non-zero, we expect a continuation of the multi-octet // sequence - if (0x80 === (0xC0 & $in)) { - - // Legal continuation. - $shift = ($mState - 1) * 6; - $tmp = $in; - $tmp = ($tmp & 0x0000003F) << $shift; - $mUcs4 |= $tmp; - - /** - * End of the multi-octet sequence. mUcs4 now contains the final - * Unicode codepoint to be output + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + /** + * End of the multi-octet sequence. mUcs4 now contains the final + * Unicode codepoint to be output + */ + if (0 === --$mState) { + /* + * Check for illegal sequences and codepoints. */ - if (0 === --$mState) { - - /* - * Check for illegal sequences and codepoints. - */ - // From Unicode 3.1, non-shortest form is illegal - if (((2 === $mBytes) && ($mUcs4 < 0x0080)) || - ((3 === $mBytes) && ($mUcs4 < 0x0800)) || - ((4 === $mBytes) && ($mUcs4 < 0x10000)) || - (4 < $mBytes) || - // From Unicode 3.2, surrogate characters are illegal - (($mUcs4 & 0xFFFFF800) === 0xD800) || - // Codepoints outside the Unicode range are illegal - ($mUcs4 > 0x10FFFF)) { - - if ($strict) { - trigger_error( - 'utf8_to_unicode: Illegal sequence or codepoint ' . - 'in UTF-8 at byte ' . $i, - E_USER_WARNING - ); - - return false; - } - + // From Unicode 3.1, non-shortest form is illegal + if ( + ((2 === $mBytes) && ($mUcs4 < 0x0080)) || + ((3 === $mBytes) && ($mUcs4 < 0x0800)) || + ((4 === $mBytes) && ($mUcs4 < 0x10000)) || + (4 < $mBytes) || + // From Unicode 3.2, surrogate characters are illegal + (($mUcs4 & 0xFFFFF800) === 0xD800) || + // Codepoints outside the Unicode range are illegal + ($mUcs4 > 0x10FFFF) + ) { + if ($strict) { + trigger_error( + 'utf8_to_unicode: Illegal sequence or codepoint ' . + 'in UTF-8 at byte ' . $i, + E_USER_WARNING + ); + + return false; } - - if (0xFEFF !== $mUcs4) { - // BOM is legal but we don't want to output it - $out[] = $mUcs4; - } - - //initialize UTF8 cache - $mState = 0; - $mUcs4 = 0; - $mBytes = 1; } - } elseif ($strict) { - /** - *((0xC0 & (*in) != 0x80) && (mState != 0)) - * Incomplete multi-octet sequence. - */ - trigger_error( - 'utf8_to_unicode: Incomplete multi-octet ' . - ' sequence in UTF-8 at byte ' . $i, - E_USER_WARNING - ); + if (0xFEFF !== $mUcs4) { + // BOM is legal but we don't want to output it + $out[] = $mUcs4; + } - return false; + //initialize UTF8 cache + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; } + } elseif ($strict) { + /** + *((0xC0 & (*in) != 0x80) && (mState != 0)) + * Incomplete multi-octet sequence. + */ + trigger_error( + 'utf8_to_unicode: Incomplete multi-octet ' . + ' sequence in UTF-8 at byte ' . $i, + E_USER_WARNING + ); + + return false; } } return $out; @@ -215,25 +197,18 @@ class Unicode ob_start(); foreach (array_keys($arr) as $k) { - if (($arr[$k] >= 0) && ($arr[$k] <= 0x007f)) { # ASCII range (including control chars) - echo chr($arr[$k]); - - } else if ($arr[$k] <= 0x07ff) { + } elseif ($arr[$k] <= 0x07ff) { # 2 byte sequence - echo chr(0xc0 | ($arr[$k] >> 6)); echo chr(0x80 | ($arr[$k] & 0x003f)); - - } else if ($arr[$k] == 0xFEFF) { + } elseif ($arr[$k] == 0xFEFF) { # Byte order mark (skip) // nop -- zap the BOM - - } else if ($arr[$k] >= 0xD800 && $arr[$k] <= 0xDFFF) { + } elseif ($arr[$k] >= 0xD800 && $arr[$k] <= 0xDFFF) { # Test for illegal surrogates - // found a surrogate if ($strict) { trigger_error( @@ -243,24 +218,18 @@ class Unicode ); return false; } - - } else if ($arr[$k] <= 0xffff) { + } elseif ($arr[$k] <= 0xffff) { # 3 byte sequence - echo chr(0xe0 | ($arr[$k] >> 12)); echo chr(0x80 | (($arr[$k] >> 6) & 0x003f)); echo chr(0x80 | ($arr[$k] & 0x003f)); - - } else if ($arr[$k] <= 0x10ffff) { + } elseif ($arr[$k] <= 0x10ffff) { # 4 byte sequence - echo chr(0xf0 | ($arr[$k] >> 18)); echo chr(0x80 | (($arr[$k] >> 12) & 0x3f)); echo chr(0x80 | (($arr[$k] >> 6) & 0x3f)); echo chr(0x80 | ($arr[$k] & 0x3f)); - } elseif ($strict) { - trigger_error( 'unicode_to_utf8: Codepoint out of Unicode range ' . 'at index: ' . $k . ', value: ' . $arr[$k], diff --git a/inc/Utf8/tables/case.php b/inc/Utf8/tables/case.php index 6c41b5808..ca5b48078 100644 --- a/inc/Utf8/tables/case.php +++ b/inc/Utf8/tables/case.php @@ -1,4 +1,5 @@ <?php + /** * UTF-8 Case lookup table * @@ -7,6 +8,7 @@ * * @author Andreas Gohr <andi@splitbrain.org> */ + return [ 'A' => 'a', 'B' => 'b', diff --git a/inc/Utf8/tables/loweraccents.php b/inc/Utf8/tables/loweraccents.php index 789379b64..74cbff321 100644 --- a/inc/Utf8/tables/loweraccents.php +++ b/inc/Utf8/tables/loweraccents.php @@ -1,4 +1,5 @@ <?php + /** * UTF-8 lookup table for lower case accented letters * @@ -8,6 +9,7 @@ * @author Andreas Gohr <andi@splitbrain.org> * @see \dokuwiki\Utf8\Clean::deaccent() */ + return [ 'á' => 'a', 'à' => 'a', diff --git a/inc/Utf8/tables/romanization.php b/inc/Utf8/tables/romanization.php index b15a9baa9..006a70598 100644 --- a/inc/Utf8/tables/romanization.php +++ b/inc/Utf8/tables/romanization.php @@ -1,4 +1,5 @@ <?php + /** * Romanization lookup table * @@ -24,6 +25,7 @@ * @link http://en.wikipedia.org/wiki/Royal_Thai_General_System_of_Transcription * @link http://www.btranslations.com/resources/romanization/korean.asp */ + return [ // scandinavian - differs from what we do in deaccent 'å' => 'a', @@ -298,9 +300,6 @@ return [ // 3 character syllables, っ doubles the consonant after 'っちゃ' => 'ccha', - 'っちぇ' => 'cche', - 'っちょ' => 'ccho', - 'っちゅ' => 'cchu', 'っびゃ' => 'bbya', 'っびぇ' => 'bbye', 'っびぃ' => 'bbyi', @@ -313,7 +312,6 @@ return [ 'っぴゅ' => 'ppyu', 'っちゃ' => 'ccha', 'っちぇ' => 'cche', - 'っち' => 'cchi', 'っちょ' => 'ccho', 'っちゅ' => 'cchu', // 'っひゃ'=>'hya', @@ -348,7 +346,6 @@ return [ 'っりゅ' => 'rryu', 'っしゃ' => 'ssha', 'っしぇ' => 'sshe', - 'っし' => 'sshi', 'っしょ' => 'ssho', 'っしゅ' => 'sshu', @@ -370,7 +367,6 @@ return [ 'ふぉ' => 'fo', 'ちゃ' => 'cha', 'ちぇ' => 'che', - 'ち' => 'chi', 'ちょ' => 'cho', 'ちゅ' => 'chu', 'ひゃ' => 'hya', @@ -415,7 +411,6 @@ return [ 'りゅ' => 'ryu', 'しゃ' => 'sha', 'しぇ' => 'she', - 'し' => 'shi', 'しょ' => 'sho', 'しゅ' => 'shu', 'じゃ' => 'ja', @@ -633,12 +628,10 @@ return [ 'ッリュー' => 'rryuu', 'ッシャー' => 'sshaa', 'ッシェー' => 'sshee', - 'ッシー' => 'sshii', 'ッショー' => 'sshoo', 'ッシュー' => 'sshuu', 'ッチャー' => 'cchaa', 'ッチェー' => 'cchee', - 'ッチー' => 'cchii', 'ッチョー' => 'cchoo', 'ッチュー' => 'cchuu', 'ッティー' => 'ttii', @@ -646,8 +639,6 @@ return [ // 3 character syllables - doubled vowels 'ファー' => 'faa', - 'フェー' => 'fee', - 'フィー' => 'fii', 'フォー' => 'foo', 'フャー' => 'fyaa', 'フェー' => 'fyee', @@ -696,12 +687,10 @@ return [ 'リュー' => 'ryuu', 'シャー' => 'shaa', 'シェー' => 'shee', - 'シー' => 'shii', 'ショー' => 'shoo', 'シュー' => 'shuu', 'ジャー' => 'jaa', 'ジェー' => 'jee', - 'ジー' => 'jii', 'ジョー' => 'joo', 'ジュー' => 'juu', 'スァー' => 'swaa', @@ -716,19 +705,16 @@ return [ 'デゥー' => 'duu', 'チャー' => 'chaa', 'チェー' => 'chee', - 'チー' => 'chii', 'チョー' => 'choo', 'チュー' => 'chuu', 'ヂャー' => 'dyaa', 'ヂェー' => 'dyee', - 'ヂィー' => 'dyii', 'ヂョー' => 'dyoo', 'ヂュー' => 'dyuu', 'ツャー' => 'tsaa', 'ツェー' => 'tsee', 'ツィー' => 'tsii', 'ツョー' => 'tsoo', - 'ツー' => 'tsuu', 'トァー' => 'twaa', 'トェー' => 'twee', 'トィー' => 'twii', @@ -740,13 +726,9 @@ return [ 'ドォー' => 'dwoo', 'ドゥー' => 'dwuu', 'ウァー' => 'whaa', - 'ウェー' => 'whee', - 'ウィー' => 'whii', 'ウォー' => 'whoo', 'ウゥー' => 'whuu', 'ヴャー' => 'vyaa', - 'ヴェー' => 'vyee', - 'ヴィー' => 'vyii', 'ヴョー' => 'vyoo', 'ヴュー' => 'vyuu', 'ヴァー' => 'vaa', @@ -798,12 +780,10 @@ return [ 'ッリュ' => 'rryu', 'ッシャ' => 'ssha', 'ッシェ' => 'sshe', - 'ッシ' => 'sshi', 'ッショ' => 'ssho', 'ッシュ' => 'sshu', 'ッチャ' => 'ccha', 'ッチェ' => 'cche', - 'ッチ' => 'cchi', 'ッチョ' => 'ccho', 'ッチュ' => 'cchu', 'ッティ' => 'tti', @@ -868,8 +848,6 @@ return [ // 2 character syllables - normal 'ファ' => 'fa', - 'フェ' => 'fe', - 'フィ' => 'fi', 'フォ' => 'fo', 'フゥ' => 'fu', // 'フャ'=>'fya', @@ -942,7 +920,6 @@ return [ 'デゥ' => 'du', 'チャ' => 'cha', 'チェ' => 'che', - 'チ' => 'chi', 'チョ' => 'cho', 'チュ' => 'chu', // 'ヂャ'=>'dya', @@ -954,7 +931,6 @@ return [ 'ツェ' => 'tse', 'ツィ' => 'tsi', 'ツョ' => 'tso', - 'ツ' => 'tsu', 'トァ' => 'twa', 'トェ' => 'twe', 'トィ' => 'twi', @@ -966,13 +942,9 @@ return [ 'ドォ' => 'dwo', 'ドゥ' => 'dwu', 'ウァ' => 'wha', - 'ウェ' => 'whe', - 'ウィ' => 'whi', 'ウォ' => 'who', 'ウゥ' => 'whu', 'ヴャ' => 'vya', - 'ヴェ' => 'vye', - 'ヴィ' => 'vyi', 'ヴョ' => 'vyo', 'ヴュ' => 'vyu', 'ヴァ' => 'va', @@ -1414,7 +1386,6 @@ return [ 'ำ' => 'am', 'ํา' => 'am', 'ิ' => 'i', - 'ี' => 'i', 'ึ' => 'ue', 'ี' => 'ue', 'ุ' => 'u', diff --git a/inc/Utf8/tables/specials.php b/inc/Utf8/tables/specials.php index f6243bccd..2f9c14619 100644 --- a/inc/Utf8/tables/specials.php +++ b/inc/Utf8/tables/specials.php @@ -1,4 +1,5 @@ <?php + /** * UTF-8 array of common special characters * @@ -13,6 +14,7 @@ * @author Andreas Gohr <andi@splitbrain.org> * @see \dokuwiki\Utf8\Clean::stripspecials() */ + return [ 0x1a, // 0x1b, // diff --git a/inc/Utf8/tables/upperaccents.php b/inc/Utf8/tables/upperaccents.php index e6e48de2c..facda0c30 100644 --- a/inc/Utf8/tables/upperaccents.php +++ b/inc/Utf8/tables/upperaccents.php @@ -1,4 +1,5 @@ <?php + /** * UTF-8 lookup table for upper case accented letters * @@ -8,6 +9,7 @@ * @author Andreas Gohr <andi@splitbrain.org> * @see \dokuwiki\Utf8\Clean::deaccent() */ + return [ 'Á' => 'A', 'À' => 'A', diff --git a/inc/actions.php b/inc/actions.php index 8c993ef98..03a874fbf 100644 --- a/inc/actions.php +++ b/inc/actions.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki Actions * @@ -6,17 +7,19 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\ActionRouter; use dokuwiki\Extension\Event; /** * All action processing starts here */ -function act_dispatch(){ +function act_dispatch() +{ // always initialize on first dispatch (test request may dispatch mutliple times on one request) - $router = \dokuwiki\ActionRouter::getInstance(true); + $router = ActionRouter::getInstance(true); - $headers = array('Content-Type: text/html; charset=utf-8'); - Event::createAndTrigger('ACTION_HEADERS_SEND',$headers,'act_sendheaders'); + $headers = ['Content-Type: text/html; charset=utf-8']; + Event::createAndTrigger('ACTION_HEADERS_SEND', $headers, 'act_sendheaders'); // clear internal variables unset($router); @@ -34,7 +37,8 @@ function act_dispatch(){ * * @param array $headers The headers that shall be sent */ -function act_sendheaders($headers) { +function act_sendheaders($headers) +{ foreach ($headers as $hdr) header($hdr); } @@ -46,22 +50,23 @@ function act_sendheaders($headers) { * @param array|string $act * @return string */ -function act_clean($act){ +function act_clean($act) +{ // check if the action was given as array key - if(is_array($act)){ - list($act) = array_keys($act); + if (is_array($act)) { + [$act] = array_keys($act); } // no action given - if($act === null) return 'show'; + if ($act === null) return 'show'; //remove all bad chars $act = strtolower($act); - $act = preg_replace('/[^1-9a-z_]+/','',$act); + $act = preg_replace('/[^1-9a-z_]+/', '', $act); - if($act == 'export_html') $act = 'export_xhtml'; - if($act == 'export_htmlbody') $act = 'export_xhtmlbody'; + if ($act == 'export_html') $act = 'export_xhtml'; + if ($act == 'export_htmlbody') $act = 'export_xhtmlbody'; - if($act === '') $act = 'show'; + if ($act === '') $act = 'show'; return $act; } diff --git a/inc/auth.php b/inc/auth.php index 1dd2b2bdd..a18eab1e3 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -1,4 +1,5 @@ <?php + /** * Authentication library * @@ -9,6 +10,8 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use phpseclib\Crypt\AES; +use dokuwiki\Utf8\PhpString; use dokuwiki\Extension\AuthPlugin; use dokuwiki\Extension\Event; use dokuwiki\Extension\PluginController; @@ -27,7 +30,8 @@ use dokuwiki\Subscriptions\RegistrationSubscriptionSender; * @triggers AUTH_LOGIN_CHECK * @return bool */ -function auth_setup() { +function auth_setup() +{ global $conf; /* @var AuthPlugin $auth */ global $auth; @@ -37,9 +41,9 @@ function auth_setup() { global $lang; /* @var PluginController $plugin_controller */ global $plugin_controller; - $AUTH_ACL = array(); + $AUTH_ACL = []; - if(!$conf['useacl']) return false; + if (!$conf['useacl']) return false; // try to load auth backend from plugins foreach ($plugin_controller->getList('auth') as $plugin) { @@ -49,7 +53,7 @@ function auth_setup() { } } - if(!isset($auth) || !$auth){ + if (!$auth instanceof AuthPlugin) { msg($lang['authtempfail'], -1); return false; } @@ -64,14 +68,14 @@ function auth_setup() { // do the login either by cookie or provided credentials XXX $INPUT->set('http_credentials', false); - if(!$conf['rememberme']) $INPUT->set('r', false); + if (!$conf['rememberme']) $INPUT->set('r', false); // Populate Basic Auth user/password from Authorization header // Note: with FastCGI, data is in REDIRECT_HTTP_AUTHORIZATION instead of HTTP_AUTHORIZATION $header = $INPUT->server->str('HTTP_AUTHORIZATION') ?: $INPUT->server->str('REDIRECT_HTTP_AUTHORIZATION'); - if(preg_match( '~^Basic ([a-z\d/+]*={0,2})$~i', $header, $matches )) { + if (preg_match('~^Basic ([a-z\d/+]*={0,2})$~i', $header, $matches)) { $userpass = explode(':', base64_decode($matches[1])); - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = $userpass; + [$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']] = $userpass; } // if no credentials were given try to use HTTP auth (for SSO) @@ -88,19 +92,19 @@ function auth_setup() { } $ok = null; - if (!is_null($auth) && $auth->canDo('external')) { + if ($auth instanceof AuthPlugin && $auth->canDo('external')) { $ok = $auth->trustExternal($INPUT->str('u'), $INPUT->str('p'), $INPUT->bool('r')); } if ($ok === null) { // external trust mechanism not in place, or returns no result, // then attempt auth_login - $evdata = array( + $evdata = [ 'user' => $INPUT->str('u'), 'password' => $INPUT->str('p'), 'sticky' => $INPUT->bool('r'), 'silent' => $INPUT->bool('http_credentials') - ); + ]; Event::createAndTrigger('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper'); } @@ -117,38 +121,39 @@ function auth_setup() { * * @return array */ -function auth_loadACL() { +function auth_loadACL() +{ global $config_cascade; global $USERINFO; /* @var Input $INPUT */ global $INPUT; - if(!is_readable($config_cascade['acl']['default'])) return array(); + if (!is_readable($config_cascade['acl']['default'])) return []; $acl = file($config_cascade['acl']['default']); - $out = array(); - foreach($acl as $line) { + $out = []; + foreach ($acl as $line) { $line = trim($line); - if(empty($line) || ($line[0] == '#')) continue; // skip blank lines & comments - list($id,$rest) = preg_split('/[ \t]+/',$line,2); + if (empty($line) || ($line[0] == '#')) continue; // skip blank lines & comments + [$id, $rest] = preg_split('/[ \t]+/', $line, 2); // substitute user wildcard first (its 1:1) - if(strstr($line, '%USER%')){ + if (strstr($line, '%USER%')) { // if user is not logged in, this ACL line is meaningless - skip it if (!$INPUT->server->has('REMOTE_USER')) continue; - $id = str_replace('%USER%',cleanID($INPUT->server->str('REMOTE_USER')),$id); - $rest = str_replace('%USER%',auth_nameencode($INPUT->server->str('REMOTE_USER')),$rest); + $id = str_replace('%USER%', cleanID($INPUT->server->str('REMOTE_USER')), $id); + $rest = str_replace('%USER%', auth_nameencode($INPUT->server->str('REMOTE_USER')), $rest); } // substitute group wildcard (its 1:m) - if(strstr($line, '%GROUP%')){ + if (strstr($line, '%GROUP%')) { // if user is not logged in, grps is empty, no output will be added (i.e. skipped) - if(isset($USERINFO['grps'])){ - foreach((array) $USERINFO['grps'] as $grp){ - $nid = str_replace('%GROUP%',cleanID($grp),$id); - $nrest = str_replace('%GROUP%','@'.auth_nameencode($grp),$rest); + if (isset($USERINFO['grps'])) { + foreach ((array) $USERINFO['grps'] as $grp) { + $nid = str_replace('%GROUP%', cleanID($grp), $id); + $nrest = str_replace('%GROUP%', '@' . auth_nameencode($grp), $rest); $out[] = "$nid\t$nrest"; } } @@ -165,8 +170,10 @@ function auth_loadACL() { * * @param array $evdata * @return bool + * @throws Exception */ -function auth_login_wrapper($evdata) { +function auth_login_wrapper($evdata) +{ return auth_login( $evdata['user'], $evdata['password'], @@ -196,15 +203,17 @@ function auth_login_wrapper($evdata) { * On a successful login $_SERVER[REMOTE_USER] and $USERINFO * are set. * - * @author Andreas Gohr <andi@splitbrain.org> + * @param string $user Username + * @param string $pass Cleartext Password + * @param bool $sticky Cookie should not expire + * @param bool $silent Don't show error on bad auth + * @return bool true on successful auth + * @throws Exception * - * @param string $user Username - * @param string $pass Cleartext Password - * @param bool $sticky Cookie should not expire - * @param bool $silent Don't show error on bad auth - * @return bool true on successful auth + * @author Andreas Gohr <andi@splitbrain.org> */ -function auth_login($user, $pass, $sticky = false, $silent = false) { +function auth_login($user, $pass, $sticky = false, $silent = false) +{ global $USERINFO; global $conf; global $lang; @@ -213,13 +222,11 @@ function auth_login($user, $pass, $sticky = false, $silent = false) { /* @var Input $INPUT */ global $INPUT; - $sticky ? $sticky = true : $sticky = false; //sanity check - - if(!$auth) return false; + if (!$auth instanceof AuthPlugin) return false; - if(!empty($user)) { + if (!empty($user)) { //usual login - if(!empty($pass) && $auth->checkPass($user, $pass)) { + if (!empty($pass) && $auth->checkPass($user, $pass)) { // make logininfo globally available $INPUT->server->set('REMOTE_USER', $user); $secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session @@ -227,7 +234,7 @@ function auth_login($user, $pass, $sticky = false, $silent = false) { return true; } else { //invalid credentials - log off - if(!$silent) { + if (!$silent) { http_status(403, 'Login failed'); msg($lang['badlogin'], -1); } @@ -236,21 +243,21 @@ function auth_login($user, $pass, $sticky = false, $silent = false) { } } else { // read cookie information - list($user, $sticky, $pass) = auth_getCookie(); - if($user && $pass) { + [$user, $sticky, $pass] = auth_getCookie(); + if ($user && $pass) { // we got a cookie - see if we can trust it // get session info if (isset($_SESSION[DOKU_COOKIE])) { $session = $_SESSION[DOKU_COOKIE]['auth']; - if (isset($session) && + if ( + isset($session) && $auth->useSessionCache($user) && ($session['time'] >= time() - $conf['auth_security_timeout']) && ($session['user'] == $user) && ($session['pass'] == sha1($pass)) && //still crypted ($session['buid'] == auth_browseruid()) ) { - // he has session, cookie and browser right - let him in $INPUT->server->set('REMOTE_USER', $user); $USERINFO = $session['info']; //FIXME move all references to session @@ -279,7 +286,8 @@ function auth_login($user, $pass, $sticky = false, $silent = false) { * * @return string a SHA256 sum of various browser headers */ -function auth_browseruid() { +function auth_browseruid() +{ /* @var Input $INPUT */ global $INPUT; @@ -303,27 +311,29 @@ function auth_browseruid() { * if no such file is found a random key is created and * and stored in this file. * - * @author Andreas Gohr <andi@splitbrain.org> - * - * @param bool $addsession if true, the sessionid is added to the salt - * @param bool $secure if security is more important than keeping the old value + * @param bool $addsession if true, the sessionid is added to the salt + * @param bool $secure if security is more important than keeping the old value * @return string + * @throws Exception + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function auth_cookiesalt($addsession = false, $secure = false) { +function auth_cookiesalt($addsession = false, $secure = false) +{ if (defined('SIMPLE_TEST')) { return 'test'; } global $conf; - $file = $conf['metadir'].'/_htcookiesalt'; + $file = $conf['metadir'] . '/_htcookiesalt'; if ($secure || !file_exists($file)) { - $file = $conf['metadir'].'/_htcookiesalt2'; + $file = $conf['metadir'] . '/_htcookiesalt2'; } $salt = io_readFile($file); - if(empty($salt)) { + if (empty($salt)) { $salt = bin2hex(auth_randombytes(64)); io_saveFile($file, $salt); } - if($addsession) { + if ($addsession) { $salt .= session_id(); } return $salt; @@ -332,25 +342,29 @@ function auth_cookiesalt($addsession = false, $secure = false) { /** * Return cryptographically secure random bytes. * - * @author Niklas Keller <me@kelunik.com> - * * @param int $length number of bytes * @return string cryptographically secure random bytes + * @throws Exception + * + * @author Niklas Keller <me@kelunik.com> */ -function auth_randombytes($length) { +function auth_randombytes($length) +{ return random_bytes($length); } /** * Cryptographically secure random number generator. * - * @author Niklas Keller <me@kelunik.com> - * * @param int $min * @param int $max * @return int + * @throws Exception + * + * @author Niklas Keller <me@kelunik.com> */ -function auth_random($min, $max) { +function auth_random($min, $max) +{ return random_int($min, $max); } @@ -360,13 +374,15 @@ function auth_random($min, $max) { * The mode is CBC with a random initialization vector, the key is derived * using pbkdf2. * - * @param string $data The data that shall be encrypted + * @param string $data The data that shall be encrypted * @param string $secret The secret/password that shall be used * @return string The ciphertext + * @throws Exception */ -function auth_encrypt($data, $secret) { +function auth_encrypt($data, $secret) +{ $iv = auth_randombytes(16); - $cipher = new \phpseclib\Crypt\AES(); + $cipher = new AES(); $cipher->setPassword($secret); /* @@ -375,7 +391,7 @@ function auth_encrypt($data, $secret) { for unique but necessarily random IVs. The resulting ciphertext is compatible to ciphertext that was created using a "normal" IV. */ - return $cipher->encrypt($iv.$data); + return $cipher->encrypt($iv . $data); } /** @@ -387,9 +403,10 @@ function auth_encrypt($data, $secret) { * @param string $secret The secret/password that shall be used * @return string The decrypted data */ -function auth_decrypt($ciphertext, $secret) { +function auth_decrypt($ciphertext, $secret) +{ $iv = substr($ciphertext, 0, 16); - $cipher = new \phpseclib\Crypt\AES(); + $cipher = new AES(); $cipher->setPassword($secret); $cipher->setIV($iv); @@ -406,7 +423,8 @@ function auth_decrypt($ciphertext, $secret) { * * @param bool $keepbc - when true, the breadcrumb data is not cleared */ -function auth_logoff($keepbc = false) { +function auth_logoff($keepbc = false) +{ global $conf; global $USERINFO; /* @var AuthPlugin $auth */ @@ -417,13 +435,13 @@ function auth_logoff($keepbc = false) { // make sure the session is writable (it usually is) @session_start(); - if(isset($_SESSION[DOKU_COOKIE]['auth']['user'])) + if (isset($_SESSION[DOKU_COOKIE]['auth']['user'])) unset($_SESSION[DOKU_COOKIE]['auth']['user']); - if(isset($_SESSION[DOKU_COOKIE]['auth']['pass'])) + if (isset($_SESSION[DOKU_COOKIE]['auth']['pass'])) unset($_SESSION[DOKU_COOKIE]['auth']['pass']); - if(isset($_SESSION[DOKU_COOKIE]['auth']['info'])) + if (isset($_SESSION[DOKU_COOKIE]['auth']['info'])) unset($_SESSION[DOKU_COOKIE]['auth']['info']); - if(!$keepbc && isset($_SESSION[DOKU_COOKIE]['bc'])) + if (!$keepbc && isset($_SESSION[DOKU_COOKIE]['bc'])) unset($_SESSION[DOKU_COOKIE]['bc']); $INPUT->server->remove('REMOTE_USER'); $USERINFO = null; //FIXME @@ -437,7 +455,9 @@ function auth_logoff($keepbc = false) { 'samesite' => $conf['samesitecookie'] ?: null, // null means browser default ]); - if($auth) $auth->logOff(); + if ($auth instanceof AuthPlugin) { + $auth->logOff(); + } } /** @@ -457,7 +477,8 @@ function auth_logoff($keepbc = false) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function auth_ismanager($user = null, $groups = null, $adminonly = false, $recache=false) { +function auth_ismanager($user = null, $groups = null, $adminonly = false, $recache = false) +{ global $conf; global $USERINFO; /* @var AuthPlugin $auth */ @@ -466,9 +487,9 @@ function auth_ismanager($user = null, $groups = null, $adminonly = false, $recac global $INPUT; - if(!$auth) return false; - if(is_null($user)) { - if(!$INPUT->server->has('REMOTE_USER')) { + if (!$auth instanceof AuthPlugin) return false; + if (is_null($user)) { + if (!$INPUT->server->has('REMOTE_USER')) { return false; } else { $user = $INPUT->server->str('REMOTE_USER'); @@ -517,7 +538,8 @@ function auth_ismanager($user = null, $groups = null, $adminonly = false, $recac * @see auth_ismanager() * */ -function auth_isadmin($user = null, $groups = null, $recache=false) { +function auth_isadmin($user = null, $groups = null, $recache = false) +{ return auth_ismanager($user, $groups, true, $recache); } @@ -532,18 +554,19 @@ function auth_isadmin($user = null, $groups = null, $recache=false) { * @param array $groups groups the user is member of * @return bool true for membership acknowledged */ -function auth_isMember($memberlist, $user, array $groups) { +function auth_isMember($memberlist, $user, array $groups) +{ /* @var AuthPlugin $auth */ global $auth; - if(!$auth) return false; + if (!$auth instanceof AuthPlugin) return false; // clean user and groups - if(!$auth->isCaseSensitive()) { - $user = \dokuwiki\Utf8\PhpString::strtolower($user); - $groups = array_map([\dokuwiki\Utf8\PhpString::class, 'strtolower'], $groups); + if (!$auth->isCaseSensitive()) { + $user = PhpString::strtolower($user); + $groups = array_map([PhpString::class, 'strtolower'], $groups); } $user = $auth->cleanUser($user); - $groups = array_map(array($auth, 'cleanGroup'), $groups); + $groups = array_map([$auth, 'cleanGroup'], $groups); // extract the memberlist $members = explode(',', $memberlist); @@ -552,15 +575,15 @@ function auth_isMember($memberlist, $user, array $groups) { $members = array_filter($members); // compare cleaned values - foreach($members as $member) { - if($member == '@ALL' ) return true; - if(!$auth->isCaseSensitive()) $member = \dokuwiki\Utf8\PhpString::strtolower($member); - if($member[0] == '@') { + foreach ($members as $member) { + if ($member == '@ALL') return true; + if (!$auth->isCaseSensitive()) $member = PhpString::strtolower($member); + if ($member[0] == '@') { $member = $auth->cleanGroup(substr($member, 1)); - if(in_array($member, $groups)) return true; + if (in_array($member, $groups)) return true; } else { $member = $auth->cleanUser($member); - if($member == $user) return true; + if ($member == $user) return true; } } @@ -578,14 +601,15 @@ function auth_isMember($memberlist, $user, array $groups) { * @param string $id page ID (needs to be resolved and cleaned) * @return int permission level */ -function auth_quickaclcheck($id) { +function auth_quickaclcheck($id) +{ global $conf; global $USERINFO; /* @var Input $INPUT */ global $INPUT; # if no ACL is used always return upload rights - if(!$conf['useacl']) return AUTH_UPLOAD; - return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), is_array($USERINFO) ? $USERINFO['grps'] : array()); + if (!$conf['useacl']) return AUTH_UPLOAD; + return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), is_array($USERINFO) ? $USERINFO['grps'] : []); } /** @@ -599,12 +623,13 @@ function auth_quickaclcheck($id) { * @param array|null $groups Array of groups the user is in * @return int permission level */ -function auth_aclcheck($id, $user, $groups) { - $data = array( +function auth_aclcheck($id, $user, $groups) +{ + $data = [ 'id' => $id ?? '', 'user' => $user, 'groups' => $groups - ); + ]; return Event::createAndTrigger('AUTH_ACL_CHECK', $data, 'auth_aclcheck_cb'); } @@ -619,7 +644,8 @@ function auth_aclcheck($id, $user, $groups) { * @param array $data event data * @return int permission level */ -function auth_aclcheck_cb($data) { +function auth_aclcheck_cb($data) +{ $id =& $data['id']; $user =& $data['user']; $groups =& $data['groups']; @@ -630,28 +656,28 @@ function auth_aclcheck_cb($data) { global $auth; // if no ACL is used always return upload rights - if(!$conf['useacl']) return AUTH_UPLOAD; - if(!$auth) return AUTH_NONE; - if(!is_array($AUTH_ACL)) return AUTH_NONE; + if (!$conf['useacl']) return AUTH_UPLOAD; + if (!$auth instanceof AuthPlugin) return AUTH_NONE; + if (!is_array($AUTH_ACL)) return AUTH_NONE; //make sure groups is an array - if(!is_array($groups)) $groups = array(); + if (!is_array($groups)) $groups = []; //if user is superuser or in superusergroup return 255 (acl_admin) - if(auth_isadmin($user, $groups)) { + if (auth_isadmin($user, $groups)) { return AUTH_ADMIN; } - if(!$auth->isCaseSensitive()) { - $user = \dokuwiki\Utf8\PhpString::strtolower($user); - $groups = array_map([\dokuwiki\Utf8\PhpString::class, 'strtolower'], $groups); + if (!$auth->isCaseSensitive()) { + $user = PhpString::strtolower($user); + $groups = array_map([PhpString::class, 'strtolower'], $groups); } $user = auth_nameencode($auth->cleanUser($user)); - $groups = array_map(array($auth, 'cleanGroup'), (array) $groups); + $groups = array_map([$auth, 'cleanGroup'], $groups); //prepend groups with @ and nameencode - foreach($groups as &$group) { - $group = '@'.auth_nameencode($group); + foreach ($groups as &$group) { + $group = '@' . auth_nameencode($group); } $ns = getNS($id); @@ -661,66 +687,66 @@ function auth_aclcheck_cb($data) { $groups[] = '@ALL'; //add User - if($user) $groups[] = $user; + if ($user) $groups[] = $user; //check exact match first - $matches = preg_grep('/^'.preg_quote($id, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL); - if(count($matches)) { - foreach($matches as $match) { + $matches = preg_grep('/^' . preg_quote($id, '/') . '[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL); + if (count($matches)) { + foreach ($matches as $match) { $match = preg_replace('/#.*$/', '', $match); //ignore comments $acl = preg_split('/[ \t]+/', $match); - if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') { - $acl[1] = \dokuwiki\Utf8\PhpString::strtolower($acl[1]); + if (!$auth->isCaseSensitive() && $acl[1] !== '@ALL') { + $acl[1] = PhpString::strtolower($acl[1]); } - if(!in_array($acl[1], $groups)) { + if (!in_array($acl[1], $groups)) { continue; } - if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! - if($acl[2] > $perm) { + if ($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! + if ($acl[2] > $perm) { $perm = $acl[2]; } } - if($perm > -1) { + if ($perm > -1) { //we had a match - return it return (int) $perm; } } //still here? do the namespace checks - if($ns) { - $path = $ns.':*'; + if ($ns) { + $path = $ns . ':*'; } else { $path = '*'; //root document } do { - $matches = preg_grep('/^'.preg_quote($path, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL); - if(count($matches)) { - foreach($matches as $match) { + $matches = preg_grep('/^' . preg_quote($path, '/') . '[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL); + if (count($matches)) { + foreach ($matches as $match) { $match = preg_replace('/#.*$/', '', $match); //ignore comments $acl = preg_split('/[ \t]+/', $match); - if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') { - $acl[1] = \dokuwiki\Utf8\PhpString::strtolower($acl[1]); + if (!$auth->isCaseSensitive() && $acl[1] !== '@ALL') { + $acl[1] = PhpString::strtolower($acl[1]); } - if(!in_array($acl[1], $groups)) { + if (!in_array($acl[1], $groups)) { continue; } - if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! - if($acl[2] > $perm) { + if ($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! + if ($acl[2] > $perm) { $perm = $acl[2]; } } //we had a match - return it - if($perm != -1) { + if ($perm != -1) { return (int) $perm; } } //get next higher namespace $ns = getNS($ns); - if($path != '*') { - $path = $ns.':*'; - if($path == ':*') $path = '*'; + if ($path != '*') { + $path = $ns . ':*'; + if ($path == ':*') $path = '*'; } else { //we did this already //looks like there is something wrong with the ACL @@ -728,7 +754,7 @@ function auth_aclcheck_cb($data) { msg('No ACL setup yet! Denying access to everyone.'); return AUTH_NONE; } - } while(1); //this should never loop endless + } while (1); //this should never loop endless return AUTH_NONE; } @@ -749,25 +775,28 @@ function auth_aclcheck_cb($data) { * @param bool $skip_group * @return string */ -function auth_nameencode($name, $skip_group = false) { +function auth_nameencode($name, $skip_group = false) +{ global $cache_authname; $cache =& $cache_authname; $name = (string) $name; // never encode wildcard FS#1955 - if($name == '%USER%') return $name; - if($name == '%GROUP%') return $name; + if ($name == '%USER%') return $name; + if ($name == '%GROUP%') return $name; - if(!isset($cache[$name][$skip_group])) { - if($skip_group && $name[0] == '@') { - $cache[$name][$skip_group] = '@'.preg_replace_callback( + if (!isset($cache[$name][$skip_group])) { + if ($skip_group && $name[0] == '@') { + $cache[$name][$skip_group] = '@' . preg_replace_callback( '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/', - 'auth_nameencode_callback', substr($name, 1) + 'auth_nameencode_callback', + substr($name, 1) ); } else { $cache[$name][$skip_group] = preg_replace_callback( '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/', - 'auth_nameencode_callback', $name + 'auth_nameencode_callback', + $name ); } } @@ -781,8 +810,9 @@ function auth_nameencode($name, $skip_group = false) { * @param array $matches first complete match, next matching subpatterms * @return string */ -function auth_nameencode_callback($matches) { - return '%'.dechex(ord(substr($matches[1],-1))); +function auth_nameencode_callback($matches) +{ + return '%' . dechex(ord(substr($matches[1], -1))); } /** @@ -791,34 +821,37 @@ function auth_nameencode_callback($matches) { * The $foruser variable might be used by plugins to run additional password * policy checks, but is not used by the default implementation * - * @author Andreas Gohr <andi@splitbrain.org> + * @param string $foruser username for which the password is generated + * @return string pronouncable password + * @throws Exception + * * @link http://www.phpbuilder.com/annotate/message.php3?id=1014451 * @triggers AUTH_PASSWORD_GENERATE * - * @param string $foruser username for which the password is generated - * @return string pronouncable password + * @author Andreas Gohr <andi@splitbrain.org> */ -function auth_pwgen($foruser = '') { - $data = array( +function auth_pwgen($foruser = '') +{ + $data = [ 'password' => '', 'foruser' => $foruser - ); + ]; $evt = new Event('AUTH_PASSWORD_GENERATE', $data); - if($evt->advise_before(true)) { + if ($evt->advise_before(true)) { $c = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones $v = 'aeiou'; //vowels - $a = $c.$v; //both + $a = $c . $v; //both $s = '!$%&?+*~#-_:.;,'; // specials //use thre syllables... - for($i = 0; $i < 3; $i++) { + for ($i = 0; $i < 3; $i++) { $data['password'] .= $c[auth_random(0, strlen($c) - 1)]; $data['password'] .= $v[auth_random(0, strlen($v) - 1)]; $data['password'] .= $a[auth_random(0, strlen($a) - 1)]; } //... and add a nice number and special - $data['password'] .= $s[auth_random(0, strlen($s) - 1)].auth_random(10, 99); + $data['password'] .= $s[auth_random(0, strlen($s) - 1)] . auth_random(10, 99); } $evt->advise_after(); @@ -834,26 +867,27 @@ function auth_pwgen($foruser = '') { * @param string $password The new password in clear text * @return bool true on success */ -function auth_sendPassword($user, $password) { +function auth_sendPassword($user, $password) +{ global $lang; /* @var AuthPlugin $auth */ global $auth; - if(!$auth) return false; + if (!$auth instanceof AuthPlugin) return false; $user = $auth->cleanUser($user); - $userinfo = $auth->getUserData($user, $requireGroups = false); + $userinfo = $auth->getUserData($user, false); - if(!$userinfo['mail']) return false; + if (!$userinfo['mail']) return false; $text = rawLocale('password'); - $trep = array( + $trep = [ 'FULLNAME' => $userinfo['name'], 'LOGIN' => $user, 'PASSWORD' => $password - ); + ]; $mail = new Mailer(); - $mail->to($mail->getCleanName($userinfo['name']).' <'.$userinfo['mail'].'>'); + $mail->to($mail->getCleanName($userinfo['name']) . ' <' . $userinfo['mail'] . '>'); $mail->subject($lang['regpwmail']); $mail->setBody($text, $trep); return $mail->send(); @@ -864,19 +898,21 @@ function auth_sendPassword($user, $password) { * * This registers a new user - Data is read directly from $_POST * - * @author Andreas Gohr <andi@splitbrain.org> - * * @return bool true on success, false on any error + * @throws Exception + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function register() { +function register() +{ global $lang; global $conf; - /* @var \dokuwiki\Extension\AuthPlugin $auth */ + /* @var AuthPlugin $auth */ global $auth; global $INPUT; - if(!$INPUT->post->bool('save')) return false; - if(!actionOK('register')) return false; + if (!$INPUT->post->bool('save')) return false; + if (!actionOK('register')) return false; // gather input $login = trim($auth->cleanUser($INPUT->post->str('login'))); @@ -885,29 +921,29 @@ function register() { $pass = $INPUT->post->str('pass'); $passchk = $INPUT->post->str('passchk'); - if(empty($login) || empty($fullname) || empty($email)) { + if (empty($login) || empty($fullname) || empty($email)) { msg($lang['regmissing'], -1); return false; } - if($conf['autopasswd']) { + if ($conf['autopasswd']) { $pass = auth_pwgen($login); // automatically generate password - } elseif(empty($pass) || empty($passchk)) { + } elseif (empty($pass) || empty($passchk)) { msg($lang['regmissing'], -1); // complain about missing passwords return false; - } elseif($pass != $passchk) { + } elseif ($pass != $passchk) { msg($lang['regbadpass'], -1); // complain about misspelled passwords return false; } //check mail - if(!mail_isvalid($email)) { + if (!mail_isvalid($email)) { msg($lang['regbadmail'], -1); return false; } //okay try to create the user - if(!$auth->triggerUserMod('create', array($login, $pass, $fullname, $email))) { + if (!$auth->triggerUserMod('create', [$login, $pass, $fullname, $email])) { msg($lang['regfail'], -1); return false; } @@ -917,13 +953,13 @@ function register() { $subscription->sendRegister($login, $fullname, $email); // are we done? - if(!$conf['autopasswd']) { + if (!$conf['autopasswd']) { msg($lang['regsuccess2'], 1); return true; } // autogenerated password? then send password to user - if(auth_sendPassword($login, $pass)) { + if (auth_sendPassword($login, $pass)) { msg($lang['regsuccess'], 1); return true; } else { @@ -935,9 +971,12 @@ function register() { /** * Update user profile * + * @throws Exception + * * @author Christopher Smith <chris@jalakai.co.uk> */ -function updateprofile() { +function updateprofile() +{ global $conf; global $lang; /* @var AuthPlugin $auth */ @@ -945,21 +984,21 @@ function updateprofile() { /* @var Input $INPUT */ global $INPUT; - if(!$INPUT->post->bool('save')) return false; - if(!checkSecurityToken()) return false; + if (!$INPUT->post->bool('save')) return false; + if (!checkSecurityToken()) return false; - if(!actionOK('profile')) { + if (!actionOK('profile')) { msg($lang['profna'], -1); return false; } - $changes = array(); + $changes = []; $changes['pass'] = $INPUT->post->str('newpass'); $changes['name'] = $INPUT->post->str('fullname'); $changes['mail'] = $INPUT->post->str('email'); // check misspelled passwords - if($changes['pass'] != $INPUT->post->str('passchk')) { + if ($changes['pass'] != $INPUT->post->str('passchk')) { msg($lang['regbadpass'], -1); return false; } @@ -969,13 +1008,14 @@ function updateprofile() { $changes['mail'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $changes['mail'])); // no empty name and email (except the backend doesn't support them) - if((empty($changes['name']) && $auth->canDo('modName')) || + if ( + (empty($changes['name']) && $auth->canDo('modName')) || (empty($changes['mail']) && $auth->canDo('modMail')) ) { msg($lang['profnoempty'], -1); return false; } - if(!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) { + if (!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) { msg($lang['regbadmail'], -1); return false; } @@ -983,31 +1023,31 @@ function updateprofile() { $changes = array_filter($changes); // check for unavailable capabilities - if(!$auth->canDo('modName')) unset($changes['name']); - if(!$auth->canDo('modMail')) unset($changes['mail']); - if(!$auth->canDo('modPass')) unset($changes['pass']); + if (!$auth->canDo('modName')) unset($changes['name']); + if (!$auth->canDo('modMail')) unset($changes['mail']); + if (!$auth->canDo('modPass')) unset($changes['pass']); // anything to do? - if(!count($changes)) { + if ($changes === []) { msg($lang['profnochange'], -1); return false; } - if($conf['profileconfirm']) { - if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) { + if ($conf['profileconfirm']) { + if (!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) { msg($lang['badpassconfirm'], -1); return false; } } - if(!$auth->triggerUserMod('modify', array($INPUT->server->str('REMOTE_USER'), &$changes))) { + if (!$auth->triggerUserMod('modify', [$INPUT->server->str('REMOTE_USER'), &$changes])) { msg($lang['proffail'], -1); return false; } - if($changes['pass']) { + if ($changes['pass']) { // update cookie and session with the changed data - list( /*user*/, $sticky, /*pass*/) = auth_getCookie(); + [/* user */, $sticky, /* pass */] = auth_getCookie(); $pass = auth_encrypt($changes['pass'], auth_cookiesalt(!$sticky, true)); auth_setCookie($INPUT->server->str('REMOTE_USER'), $pass, (bool) $sticky); } else { @@ -1026,38 +1066,39 @@ function updateprofile() { * * @return bool true on success, false on any error */ -function auth_deleteprofile(){ +function auth_deleteprofile() +{ global $conf; global $lang; - /* @var \dokuwiki\Extension\AuthPlugin $auth */ + /* @var AuthPlugin $auth */ global $auth; /* @var Input $INPUT */ global $INPUT; - if(!$INPUT->post->bool('delete')) return false; - if(!checkSecurityToken()) return false; + if (!$INPUT->post->bool('delete')) return false; + if (!checkSecurityToken()) return false; // action prevented or auth module disallows - if(!actionOK('profile_delete') || !$auth->canDo('delUser')) { + if (!actionOK('profile_delete') || !$auth->canDo('delUser')) { msg($lang['profnodelete'], -1); return false; } - if(!$INPUT->post->bool('confirm_delete')){ + if (!$INPUT->post->bool('confirm_delete')) { msg($lang['profconfdeletemissing'], -1); return false; } - if($conf['profileconfirm']) { - if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) { + if ($conf['profileconfirm']) { + if (!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) { msg($lang['badpassconfirm'], -1); return false; } } - $deleted = array(); + $deleted = []; $deleted[] = $INPUT->server->str('REMOTE_USER'); - if($auth->triggerUserMod('delete', array($deleted))) { + if ($auth->triggerUserMod('delete', [$deleted])) { // force and immediate logout including removing the sticky cookie auth_logoff(); return true; @@ -1074,13 +1115,15 @@ function auth_deleteprofile(){ * - handling the first request of password reset * - validating the password reset auth token * + * @return bool true on success, false on any error + * @throws Exception + * + * @author Andreas Gohr <andi@splitbrain.org> * @author Benoit Chesneau <benoit@bchesneau.info> * @author Chris Smith <chris@jalakai.co.uk> - * @author Andreas Gohr <andi@splitbrain.org> - * - * @return bool true on success, false on any error */ -function act_resendpwd() { +function act_resendpwd() +{ global $lang; global $conf; /* @var AuthPlugin $auth */ @@ -1088,24 +1131,24 @@ function act_resendpwd() { /* @var Input $INPUT */ global $INPUT; - if(!actionOK('resendpwd')) { + if (!actionOK('resendpwd')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); - if($token) { + if ($token) { // we're in token phase - get user info from token - $tfile = $conf['cachedir'].'/'.$token[0].'/'.$token.'.pwauth'; - if(!file_exists($tfile)) { + $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; + if (!file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); return false; } // token is only valid for 3 days - if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) { + if ((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); @unlink($tfile); @@ -1113,37 +1156,35 @@ function act_resendpwd() { } $user = io_readfile($tfile); - $userinfo = $auth->getUserData($user, $requireGroups = false); - if(!$userinfo['mail']) { + $userinfo = $auth->getUserData($user, false); + if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } - if(!$conf['autopasswd']) { // we let the user choose a password + if (!$conf['autopasswd']) { // we let the user choose a password $pass = $INPUT->str('pass'); // password given correctly? - if(!$pass) return false; - if($pass != $INPUT->str('passchk')) { + if (!$pass) return false; + if ($pass != $INPUT->str('passchk')) { msg($lang['regbadpass'], -1); return false; } // change it - if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { + if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) { msg($lang['proffail'], -1); return false; } - } else { // autogenerate the password and send by mail - $pass = auth_pwgen($user); - if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { + if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) { msg($lang['proffail'], -1); return false; } - if(auth_sendPassword($user, $pass)) { + if (auth_sendPassword($user, $pass)) { msg($lang['resendpwdsuccess'], 1); } else { msg($lang['regmailfail'], -1); @@ -1152,44 +1193,39 @@ function act_resendpwd() { @unlink($tfile); return true; - } else { // we're in request phase - if(!$INPUT->post->bool('save')) return false; + if (!$INPUT->post->bool('save')) return false; - if(!$INPUT->post->str('login')) { + if (!$INPUT->post->str('login')) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($INPUT->post->str('login'))); } - $userinfo = $auth->getUserData($user, $requireGroups = false); - if(!$userinfo['mail']) { + $userinfo = $auth->getUserData($user, false); + if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_randombytes(16)); // random secret - $tfile = $conf['cachedir'].'/'.$token[0].'/'.$token.'.pwauth'; - $url = wl('', array('do'=> 'resendpwd', 'pwauth'=> $token), true, '&'); + $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; + $url = wl('', ['do' => 'resendpwd', 'pwauth' => $token], true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); - $trep = array( - 'FULLNAME' => $userinfo['name'], - 'LOGIN' => $user, - 'CONFIRM' => $url - ); + $trep = ['FULLNAME' => $userinfo['name'], 'LOGIN' => $user, 'CONFIRM' => $url]; $mail = new Mailer(); - $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>'); + $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>'); $mail->subject($lang['regpwmail']); $mail->setBody($text, $trep); - if($mail->send()) { + if ($mail->send()) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); @@ -1212,14 +1248,15 @@ function act_resendpwd() { * @param string $salt A salt, null for random * @return string The crypted password */ -function auth_cryptPassword($clear, $method = '', $salt = null) { +function auth_cryptPassword($clear, $method = '', $salt = null) +{ global $conf; - if(empty($method)) $method = $conf['passcrypt']; + if (empty($method)) $method = $conf['passcrypt']; $pass = new PassHash(); - $call = 'hash_'.$method; + $call = 'hash_' . $method; - if(!method_exists($pass, $call)) { + if (!method_exists($pass, $call)) { msg("Unsupported crypt method $method", -1); return false; } @@ -1230,13 +1267,15 @@ function auth_cryptPassword($clear, $method = '', $salt = null) { /** * Verifies a cleartext password against a crypted hash * - * @author Andreas Gohr <andi@splitbrain.org> - * - * @param string $clear The clear text password - * @param string $crypt The hash to compare with + * @param string $clear The clear text password + * @param string $crypt The hash to compare with * @return bool true if both match + * @throws Exception + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function auth_verifyPassword($clear, $crypt) { +function auth_verifyPassword($clear, $crypt) +{ $pass = new PassHash(); return $pass->verify_hash($clear, $crypt); } @@ -1249,17 +1288,18 @@ function auth_verifyPassword($clear, $crypt) { * @param bool $sticky whether or not the cookie will last beyond the session * @return bool */ -function auth_setCookie($user, $pass, $sticky) { +function auth_setCookie($user, $pass, $sticky) +{ global $conf; /* @var AuthPlugin $auth */ global $auth; global $USERINFO; - if(!$auth) return false; + if (!$auth instanceof AuthPlugin) return false; $USERINFO = $auth->getUserData($user); // set cookie - $cookie = base64_encode($user).'|'.((int) $sticky).'|'.base64_encode($pass); + $cookie = base64_encode($user) . '|' . ((int) $sticky) . '|' . base64_encode($pass); $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; $time = $sticky ? (time() + 60 * 60 * 24 * 365) : 0; //one year setcookie(DOKU_COOKIE, $cookie, [ @@ -1285,15 +1325,16 @@ function auth_setCookie($user, $pass, $sticky) { * * @returns array */ -function auth_getCookie() { - if(!isset($_COOKIE[DOKU_COOKIE])) { - return array(null, null, null); +function auth_getCookie() +{ + if (!isset($_COOKIE[DOKU_COOKIE])) { + return [null, null, null]; } - list($user, $sticky, $pass) = sexplode('|', $_COOKIE[DOKU_COOKIE], 3, ''); + [$user, $sticky, $pass] = sexplode('|', $_COOKIE[DOKU_COOKIE], 3, ''); $sticky = (bool) $sticky; $pass = base64_decode($pass); $user = base64_decode($user); - return array($user, $sticky, $pass); + return [$user, $sticky, $pass]; } //Setup VIM: ex: et ts=2 : diff --git a/inc/cache.php b/inc/cache.php index b5793c263..832e45e1a 100644 --- a/inc/cache.php +++ b/inc/cache.php @@ -1,5 +1,6 @@ <?php // phpcs:ignoreFile +use dokuwiki\Cache\Cache; use dokuwiki\Cache\CacheParser; use dokuwiki\Cache\CacheInstructions; use dokuwiki\Cache\CacheRenderer; @@ -8,11 +9,11 @@ use dokuwiki\Debug\DebugHelper; /** * @deprecated since 2019-02-02 use \dokuwiki\Cache\Cache instead! */ -class cache extends \dokuwiki\Cache\Cache +class cache extends Cache { public function __construct($key, $ext) { - DebugHelper::dbgDeprecatedFunction(dokuwiki\Cache\Cache::class); + DebugHelper::dbgDeprecatedFunction(Cache::class); parent::__construct($key, $ext); } } @@ -20,7 +21,7 @@ class cache extends \dokuwiki\Cache\Cache /** * @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheParser instead! */ -class cache_parser extends \dokuwiki\Cache\CacheParser +class cache_parser extends CacheParser { public function __construct($id, $file, $mode) @@ -34,7 +35,7 @@ class cache_parser extends \dokuwiki\Cache\CacheParser /** * @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheRenderer instead! */ -class cache_renderer extends \dokuwiki\Cache\CacheRenderer +class cache_renderer extends CacheRenderer { public function __construct($id, $file, $mode) @@ -47,7 +48,7 @@ class cache_renderer extends \dokuwiki\Cache\CacheRenderer /** * @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheInstructions instead! */ -class cache_instructions extends \dokuwiki\Cache\CacheInstructions +class cache_instructions extends CacheInstructions { public function __construct($id, $file) { diff --git a/inc/changelog.php b/inc/changelog.php index fb1184777..af147b7e0 100644 --- a/inc/changelog.php +++ b/inc/changelog.php @@ -1,4 +1,5 @@ <?php + /** * Changelog handling functions * @@ -6,6 +7,7 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\ChangeLog\MediaChangeLog; use dokuwiki\ChangeLog\ChangeLog; use dokuwiki\File\PageFile; @@ -17,7 +19,8 @@ use dokuwiki\File\PageFile; * @param string $line changelog line * @return array|bool parsed line or false */ -function parseChangelogLine($line) { +function parseChangelogLine($line) +{ return ChangeLog::parseLogLine($line); } @@ -49,23 +52,23 @@ function addLogEntry( $summary = '', $extra = '', $flags = null, - $sizechange = null) -{ + $sizechange = null +) { // no more used in DokuWiki core, but left for third-party plugins - dbg_deprecated('see '. PageFile::class .'::saveWikiText()'); + dbg_deprecated('see ' . PageFile::class . '::saveWikiText()'); /** @var Input $INPUT */ global $INPUT; // check for special flags as keys - if (!is_array($flags)) $flags = array(); + if (!is_array($flags)) $flags = []; $flagExternalEdit = isset($flags['ExternalEdit']); $id = cleanid($id); if (!$date) $date = time(); //use current time if none supplied - $remote = (!$flagExternalEdit) ? clientIP(true) : '127.0.0.1'; - $user = (!$flagExternalEdit) ? $INPUT->server->str('REMOTE_USER') : ''; + $remote = ($flagExternalEdit) ? '127.0.0.1' : clientIP(true); + $user = ($flagExternalEdit) ? '' : $INPUT->server->str('REMOTE_USER'); $sizechange = ($sizechange === null) ? '' : (int)$sizechange; // update changelog file and get the added entry that is also to be stored in metadata @@ -110,24 +113,24 @@ function addMediaLogEntry( $summary = '', $extra = '', $flags = null, - $sizechange = null) -{ + $sizechange = null +) { /** @var Input $INPUT */ global $INPUT; // check for special flags as keys - if (!is_array($flags)) $flags = array(); + if (!is_array($flags)) $flags = []; $flagExternalEdit = isset($flags['ExternalEdit']); $id = cleanid($id); if (!$date) $date = time(); //use current time if none supplied - $remote = (!$flagExternalEdit) ? clientIP(true) : '127.0.0.1'; - $user = (!$flagExternalEdit) ? $INPUT->server->str('REMOTE_USER') : ''; + $remote = ($flagExternalEdit) ? '127.0.0.1' : clientIP(true); + $user = ($flagExternalEdit) ? '' : $INPUT->server->str('REMOTE_USER'); $sizechange = ($sizechange === null) ? '' : (int)$sizechange; // update changelog file and get the added entry - (new \dokuwiki\ChangeLog\MediaChangeLog($id, 1024))->addLogEntry([ + (new MediaChangeLog($id, 1024))->addLogEntry([ 'date' => $date, 'ip' => $remote, 'type' => $type, @@ -161,9 +164,10 @@ function addMediaLogEntry( * @author Ben Coburn <btcoburn@silicodon.net> * @author Kate Arzamastseva <pshns@ukr.net> */ -function getRecents($first, $num, $ns = '', $flags = 0) { +function getRecents($first, $num, $ns = '', $flags = 0) +{ global $conf; - $recent = array(); + $recent = []; $count = 0; if (!$num) @@ -176,28 +180,28 @@ function getRecents($first, $num, $ns = '', $flags = 0) { $lines = @file($conf['changelog']) ?: []; } if (!is_array($lines)) { - $lines = array(); + $lines = []; } $lines_position = count($lines) - 1; $media_lines_position = 0; - $media_lines = array(); + $media_lines = []; if ($flags & RECENTS_MEDIA_PAGES_MIXED) { $media_lines = @file($conf['media_changelog']) ?: []; if (!is_array($media_lines)) { - $media_lines = array(); + $media_lines = []; } $media_lines_position = count($media_lines) - 1; } - $seen = array(); // caches seen lines, _handleRecent() skips them + $seen = []; // caches seen lines, _handleRecent() skips them // handle lines while ($lines_position >= 0 || (($flags & RECENTS_MEDIA_PAGES_MIXED) && $media_lines_position >= 0)) { if (empty($rec) && $lines_position >= 0) { $rec = _handleRecent(@$lines[$lines_position], $ns, $flags, $seen); if (!$rec) { - $lines_position --; + $lines_position--; continue; } } @@ -209,7 +213,7 @@ function getRecents($first, $num, $ns = '', $flags = 0) { $seen ); if (!$media_rec) { - $media_lines_position --; + $media_lines_position--; continue; } } @@ -221,7 +225,7 @@ function getRecents($first, $num, $ns = '', $flags = 0) { } else { $lines_position--; $x = $rec; - if ($flags & RECENTS_MEDIA_CHANGES){ + if ($flags & RECENTS_MEDIA_CHANGES) { $x['media'] = true; } else { $x['media'] = false; @@ -232,7 +236,9 @@ function getRecents($first, $num, $ns = '', $flags = 0) { $recent[] = $x; $count++; // break when we have enough entries - if ($count >= $num) { break; } + if ($count >= $num) { + break; + } } return $recent; } @@ -259,9 +265,10 @@ function getRecents($first, $num, $ns = '', $flags = 0) { * @author Michael Hamann <michael@content-space.de> * @author Ben Coburn <btcoburn@silicodon.net> */ -function getRecentsSince($from, $to = null, $ns = '', $flags = 0) { +function getRecentsSince($from, $to = null, $ns = '', $flags = 0) +{ global $conf; - $recent = array(); + $recent = []; if ($to && $to < $from) return $recent; @@ -278,7 +285,7 @@ function getRecentsSince($from, $to = null, $ns = '', $flags = 0) { $lines = array_reverse($lines); // handle lines - $seen = array(); // caches seen lines, _handleRecent() skips them + $seen = []; // caches seen lines, _handleRecent() skips them foreach ($lines as $line) { $rec = _handleRecent($line, $ns, $flags, $seen); @@ -311,7 +318,8 @@ function getRecentsSince($from, $to = null, $ns = '', $flags = 0) { * @param array $seen listing of seen pages * @return array|bool false or array with info about a change */ -function _handleRecent($line, $ns, $flags, &$seen) { +function _handleRecent($line, $ns, $flags, &$seen) +{ if (empty($line)) return false; //skip empty lines // split the line into parts @@ -334,14 +342,14 @@ function _handleRecent($line, $ns, $flags, &$seen) { if (isHiddenPage($recent['id'])) return false; // filter namespace - if (($ns) && (strpos($recent['id'], $ns.':') !== 0)) return false; + if (($ns) && (strpos($recent['id'], $ns . ':') !== 0)) return false; // exclude subnamespaces if (($flags & RECENTS_SKIP_SUBSPACES) && (getNS($recent['id']) != $ns)) return false; // check ACL if ($flags & RECENTS_MEDIA_CHANGES) { - $recent['perms'] = auth_quickaclcheck(getNS($recent['id']).':*'); + $recent['perms'] = auth_quickaclcheck(getNS($recent['id']) . ':*'); } else { $recent['perms'] = auth_quickaclcheck($recent['id']); } diff --git a/inc/common.php b/inc/common.php index dacd0849e..0b5d71ceb 100644 --- a/inc/common.php +++ b/inc/common.php @@ -1,4 +1,5 @@ <?php + /** * Common DokuWiki functions * @@ -6,11 +7,14 @@ * @author Andreas Gohr <andi@splitbrain.org> */ -use dokuwiki\Cache\CacheInstructions; +use dokuwiki\PassHash; +use dokuwiki\Draft; +use dokuwiki\Utf8\Clean; +use dokuwiki\Utf8\PhpString; +use dokuwiki\Utf8\Conversion; use dokuwiki\Cache\CacheRenderer; use dokuwiki\ChangeLog\PageChangeLog; use dokuwiki\File\PageFile; -use dokuwiki\Logger; use dokuwiki\Subscriptions\PageSubscriptionSender; use dokuwiki\Subscriptions\SubscriberManager; use dokuwiki\Extension\AuthPlugin; @@ -25,7 +29,8 @@ use dokuwiki\Extension\Event; * @param string $string the string being converted * @return string converted string */ -function hsc($string) { +function hsc($string) +{ return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8'); } @@ -66,30 +71,17 @@ function sexplode($separator, $string, $limit, $default = null) * @param bool $trim Consider a string of whitespace to be blank * @return bool */ -function blank(&$in, $trim = false) { - if(is_null($in)) return true; - if(is_array($in)) return empty($in); - if($in === "\0") return true; - if($trim && trim($in) === '') return true; - if(strlen($in) > 0) return false; +function blank(&$in, $trim = false) +{ + if (is_null($in)) return true; + if (is_array($in)) return $in === []; + if ($in === "\0") return true; + if ($trim && trim($in) === '') return true; + if (strlen($in) > 0) return false; return empty($in); } /** - * print a newline terminated string - * - * You can give an indention as optional parameter - * - * @author Andreas Gohr <andi@splitbrain.org> - * - * @param string $string line of text - * @param int $indent number of spaces indention - */ -function ptln($string, $indent = 0) { - echo str_repeat(' ', $indent)."$string\n"; -} - -/** * strips control characters (<32) from the given string * * @author Andreas Gohr <andi@splitbrain.org> @@ -97,7 +89,8 @@ function ptln($string, $indent = 0) { * @param string $string being stripped * @return string */ -function stripctl($string) { +function stripctl($string) +{ return preg_replace('/[\x00-\x1F]+/s', '', $string); } @@ -110,7 +103,8 @@ function stripctl($string) { * * @return string */ -function getSecurityToken() { +function getSecurityToken() +{ /** @var Input $INPUT */ global $INPUT; @@ -118,8 +112,8 @@ function getSecurityToken() { $session = session_id(); // CSRF checks are only for logged in users - do not generate for anonymous - if(trim($user) == '' || trim($session) == '') return ''; - return \dokuwiki\PassHash::hmac('md5', $session.$user, auth_cookiesalt()); + if (trim($user) == '' || trim($session) == '') return ''; + return PassHash::hmac('md5', $session . $user, auth_cookiesalt()); } /** @@ -128,13 +122,14 @@ function getSecurityToken() { * @param null|string $token security token or null to read it from request variable * @return bool success if the token matched */ -function checkSecurityToken($token = null) { +function checkSecurityToken($token = null) +{ /** @var Input $INPUT */ global $INPUT; - if(!$INPUT->server->str('REMOTE_USER')) return true; // no logged in user, no need for a check + if (!$INPUT->server->str('REMOTE_USER')) return true; // no logged in user, no need for a check - if(is_null($token)) $token = $INPUT->str('sectok'); - if(getSecurityToken() != $token) { + if (is_null($token)) $token = $INPUT->str('sectok'); + if (getSecurityToken() != $token) { msg('Security Token did not match. Possible CSRF attack.', -1); return false; } @@ -149,9 +144,10 @@ function checkSecurityToken($token = null) { * @param bool $print if true print the field, otherwise html of the field is returned * @return string html of hidden form field */ -function formSecurityToken($print = true) { - $ret = '<div class="no"><input type="hidden" name="sectok" value="'.getSecurityToken().'" /></div>'."\n"; - if($print) echo $ret; +function formSecurityToken($print = true) +{ + $ret = '<div class="no"><input type="hidden" name="sectok" value="' . getSecurityToken() . '" /></div>' . "\n"; + if ($print) echo $ret; return $ret; } @@ -166,32 +162,32 @@ function formSecurityToken($print = true) { * @return array with info for a request of $id * */ -function basicinfo($id, $htmlClient=true){ +function basicinfo($id, $htmlClient = true) +{ global $USERINFO; /* @var Input $INPUT */ global $INPUT; // set info about manager/admin status. - $info = array(); + $info = []; $info['isadmin'] = false; $info['ismanager'] = false; - if($INPUT->server->has('REMOTE_USER')) { + if ($INPUT->server->has('REMOTE_USER')) { $info['userinfo'] = $USERINFO; $info['perm'] = auth_quickaclcheck($id); $info['client'] = $INPUT->server->str('REMOTE_USER'); - if($info['perm'] == AUTH_ADMIN) { + if ($info['perm'] == AUTH_ADMIN) { $info['isadmin'] = true; $info['ismanager'] = true; - } elseif(auth_ismanager()) { + } elseif (auth_ismanager()) { $info['ismanager'] = true; } // if some outside auth were used only REMOTE_USER is set - if(empty($info['userinfo']['name'])) { + if (empty($info['userinfo']['name'])) { $info['userinfo']['name'] = $INPUT->server->str('REMOTE_USER'); } - } else { $info['perm'] = auth_aclcheck($id, '', null); $info['client'] = clientIP(true); @@ -205,23 +201,23 @@ function basicinfo($id, $htmlClient=true){ } return $info; - } +} /** * Return info about the current document as associative * array. * - * @author Andreas Gohr <andi@splitbrain.org> - * * @return array with info about current document + * @throws Exception + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function pageinfo() { +function pageinfo() +{ global $ID; global $REV; global $RANGE; global $lang; - /* @var Input $INPUT */ - global $INPUT; $info = basicinfo($ID); @@ -269,16 +265,14 @@ function pageinfo() { $pagelog = new PageChangeLog($ID, 1024); if ($REV) { $revinfo = $pagelog->getRevisionInfo($REV); + } elseif (!empty($info['meta']['last_change']) && is_array($info['meta']['last_change'])) { + $revinfo = $info['meta']['last_change']; } else { - if (!empty($info['meta']['last_change']) && is_array($info['meta']['last_change'])) { - $revinfo = $info['meta']['last_change']; - } else { - $revinfo = $pagelog->getRevisionInfo($info['lastmod']); - // cache most recent changelog line in metadata if missing and still valid - if ($revinfo !== false) { - $info['meta']['last_change'] = $revinfo; - p_set_metadata($ID, array('last_change' => $revinfo)); - } + $revinfo = $pagelog->getRevisionInfo($info['lastmod']); + // cache most recent changelog line in metadata if missing and still valid + if ($revinfo !== false) { + $info['meta']['last_change'] = $revinfo; + p_set_metadata($ID, ['last_change' => $revinfo]); } } //and check for an external edit @@ -286,7 +280,7 @@ function pageinfo() { // cached changelog line no longer valid $revinfo = false; $info['meta']['last_change'] = $revinfo; - p_set_metadata($ID, array('last_change' => $revinfo)); + p_set_metadata($ID, ['last_change' => $revinfo]); } if ($revinfo !== false) { @@ -305,7 +299,7 @@ function pageinfo() { } // draft - $draft = new \dokuwiki\Draft($ID, $info['client']); + $draft = new Draft($ID, $info['client']); if ($draft->isDraftAvailable()) { $info['draft'] = $draft->getDraftFilename(); } @@ -316,7 +310,8 @@ function pageinfo() { /** * Initialize and/or fill global $JSINFO with some basic info to be given to javascript */ -function jsinfo() { +function jsinfo() +{ global $JSINFO, $ID, $INFO, $ACT; if (!is_array($JSINFO)) { @@ -335,7 +330,8 @@ function jsinfo() { * * @return array with info about current media item */ -function mediainfo() { +function mediainfo() +{ global $NS; global $IMG; @@ -354,13 +350,14 @@ function mediainfo() { * @param string $sep series of pairs are separated by this character * @return string query string */ -function buildURLparams($params, $sep = '&') { +function buildURLparams($params, $sep = '&') +{ $url = ''; $amp = false; - foreach($params as $key => $val) { - if($amp) $url .= $sep; + foreach ($params as $key => $val) { + if ($amp) $url .= $sep; - $url .= rawurlencode($key).'='; + $url .= rawurlencode($key) . '='; $url .= rawurlencode((string) $val); $amp = true; } @@ -378,15 +375,16 @@ function buildURLparams($params, $sep = '&') { * @param bool $skipEmptyStrings skip empty string values? * @return string */ -function buildAttributes($params, $skipEmptyStrings = false) { +function buildAttributes($params, $skipEmptyStrings = false) +{ $url = ''; $white = false; - foreach($params as $key => $val) { - if($key[0] == '_') continue; - if($val === '' && $skipEmptyStrings) continue; - if($white) $url .= ' '; + foreach ($params as $key => $val) { + if ($key[0] == '_') continue; + if ($val === '' && $skipEmptyStrings) continue; + if ($white) $url .= ' '; - $url .= $key.'="'; + $url .= $key . '="'; $url .= hsc($val); $url .= '"'; $white = true; @@ -401,10 +399,11 @@ function buildAttributes($params, $skipEmptyStrings = false) { * * @return string[] with the data: array(pageid=>name, ... ) */ -function breadcrumbs() { +function breadcrumbs() +{ // we prepare the breadcrumbs early for quick session closing static $crumbs = null; - if($crumbs != null) return $crumbs; + if ($crumbs != null) return $crumbs; global $ID; global $ACT; @@ -412,33 +411,33 @@ function breadcrumbs() { global $INFO; //first visit? - $crumbs = isset($_SESSION[DOKU_COOKIE]['bc']) ? $_SESSION[DOKU_COOKIE]['bc'] : array(); + $crumbs = $_SESSION[DOKU_COOKIE]['bc'] ?? []; //we only save on show and existing visible readable wiki documents $file = wikiFN($ID); - if($ACT != 'show' || $INFO['perm'] < AUTH_READ || isHiddenPage($ID) || !file_exists($file)) { + if ($ACT != 'show' || $INFO['perm'] < AUTH_READ || isHiddenPage($ID) || !file_exists($file)) { $_SESSION[DOKU_COOKIE]['bc'] = $crumbs; return $crumbs; } // page names $name = noNSorNS($ID); - if(useHeading('navigation')) { + if (useHeading('navigation')) { // get page title $title = p_get_first_heading($ID, METADATA_RENDER_USING_SIMPLE_CACHE); - if($title) { + if ($title) { $name = $title; } } //remove ID from array - if(isset($crumbs[$ID])) { + if (isset($crumbs[$ID])) { unset($crumbs[$ID]); } //add to array $crumbs[$ID] = $name; //reduce size - while(count($crumbs) > $conf['breadcrumbs']) { + while (count($crumbs) > $conf['breadcrumbs']) { array_shift($crumbs); } //save to session @@ -465,22 +464,24 @@ function breadcrumbs() { * @param bool $ue apply urlencoding? * @return string */ -function idfilter($id, $ue = true) { +function idfilter($id, $ue = true) +{ global $conf; /* @var Input $INPUT */ global $INPUT; $id = (string) $id; - if($conf['useslash'] && $conf['userewrite']) { + if ($conf['useslash'] && $conf['userewrite']) { $id = strtr($id, ':', '/'); - } elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && + } elseif ( + strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && $conf['userewrite'] && strpos($INPUT->server->str('SERVER_SOFTWARE'), 'Microsoft-IIS') === false ) { $id = strtr($id, ':', ';'); } - if($ue) { + if ($ue) { $id = rawurlencode($id); $id = str_replace('%3A', ':', $id); //keep as colon $id = str_replace('%3B', ';', $id); //keep as semicolon @@ -502,39 +503,40 @@ function idfilter($id, $ue = true) { * @param string $separator parameter separator * @return string */ -function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&') { +function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&') +{ global $conf; - if(is_array($urlParameters)) { - if(isset($urlParameters['rev']) && !$urlParameters['rev']) unset($urlParameters['rev']); - if(isset($urlParameters['at']) && $conf['date_at_format']) { + if (is_array($urlParameters)) { + if (isset($urlParameters['rev']) && !$urlParameters['rev']) unset($urlParameters['rev']); + if (isset($urlParameters['at']) && $conf['date_at_format']) { $urlParameters['at'] = date($conf['date_at_format'], $urlParameters['at']); } $urlParameters = buildURLparams($urlParameters, $separator); } else { $urlParameters = str_replace(',', $separator, $urlParameters); } - if($id === '') { + if ($id === '') { $id = $conf['start']; } $id = idfilter($id); - if($absolute) { + if ($absolute) { $xlink = DOKU_URL; } else { $xlink = DOKU_BASE; } - if($conf['userewrite'] == 2) { - $xlink .= DOKU_SCRIPT.'/'.$id; - if($urlParameters) $xlink .= '?'.$urlParameters; - } elseif($conf['userewrite']) { + if ($conf['userewrite'] == 2) { + $xlink .= DOKU_SCRIPT . '/' . $id; + if ($urlParameters) $xlink .= '?' . $urlParameters; + } elseif ($conf['userewrite']) { $xlink .= $id; - if($urlParameters) $xlink .= '?'.$urlParameters; - } elseif($id !== '') { - $xlink .= DOKU_SCRIPT.'?id='.$id; - if($urlParameters) $xlink .= $separator.$urlParameters; + if ($urlParameters) $xlink .= '?' . $urlParameters; + } elseif ($id !== '') { + $xlink .= DOKU_SCRIPT . '?id=' . $id; + if ($urlParameters) $xlink .= $separator . $urlParameters; } else { $xlink .= DOKU_SCRIPT; - if($urlParameters) $xlink .= '?'.$urlParameters; + if ($urlParameters) $xlink .= '?' . $urlParameters; } return $xlink; @@ -553,9 +555,10 @@ function wl($id = '', $urlParameters = '', $absolute = false, $separator = '& * @param string $sep parameter separator * @return string */ -function exportlink($id = '', $format = 'raw', $urlParameters = '', $abs = false, $sep = '&') { +function exportlink($id = '', $format = 'raw', $urlParameters = '', $abs = false, $sep = '&') +{ global $conf; - if(is_array($urlParameters)) { + if (is_array($urlParameters)) { $urlParameters = buildURLparams($urlParameters, $sep); } else { $urlParameters = str_replace(',', $sep, $urlParameters); @@ -563,21 +566,21 @@ function exportlink($id = '', $format = 'raw', $urlParameters = '', $abs = false $format = rawurlencode($format); $id = idfilter($id); - if($abs) { + if ($abs) { $xlink = DOKU_URL; } else { $xlink = DOKU_BASE; } - if($conf['userewrite'] == 2) { - $xlink .= DOKU_SCRIPT.'/'.$id.'?do=export_'.$format; - if($urlParameters) $xlink .= $sep.$urlParameters; - } elseif($conf['userewrite'] == 1) { - $xlink .= '_export/'.$format.'/'.$id; - if($urlParameters) $xlink .= '?'.$urlParameters; + if ($conf['userewrite'] == 2) { + $xlink .= DOKU_SCRIPT . '/' . $id . '?do=export_' . $format; + if ($urlParameters) $xlink .= $sep . $urlParameters; + } elseif ($conf['userewrite'] == 1) { + $xlink .= '_export/' . $format . '/' . $id; + if ($urlParameters) $xlink .= '?' . $urlParameters; } else { - $xlink .= DOKU_SCRIPT.'?do=export_'.$format.$sep.'id='.$id; - if($urlParameters) $xlink .= $sep.$urlParameters; + $xlink .= DOKU_SCRIPT . '?do=export_' . $format . $sep . 'id=' . $id; + if ($urlParameters) $xlink .= $sep . $urlParameters; } return $xlink; @@ -598,84 +601,81 @@ function exportlink($id = '', $format = 'raw', $urlParameters = '', $abs = false * @param bool $abs Create an absolute URL * @return string */ -function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false) { +function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false) +{ global $conf; $isexternalimage = media_isexternal($id); - if(!$isexternalimage) { + if (!$isexternalimage) { $id = cleanID($id); } - if(is_array($more)) { + if (is_array($more)) { // add token for resized images - $w = isset($more['w']) ? $more['w'] : null; - $h = isset($more['h']) ? $more['h'] : null; - if($w || $h || $isexternalimage){ + $w = $more['w'] ?? null; + $h = $more['h'] ?? null; + if ($w || $h || $isexternalimage) { $more['tok'] = media_get_token($id, $w, $h); } // strip defaults for shorter URLs - if(isset($more['cache']) && $more['cache'] == 'cache') unset($more['cache']); - if(empty($more['w'])) unset($more['w']); - if(empty($more['h'])) unset($more['h']); - if(isset($more['id']) && $direct) unset($more['id']); - if(isset($more['rev']) && !$more['rev']) unset($more['rev']); + if (isset($more['cache']) && $more['cache'] == 'cache') unset($more['cache']); + if (empty($more['w'])) unset($more['w']); + if (empty($more['h'])) unset($more['h']); + if (isset($more['id']) && $direct) unset($more['id']); + if (isset($more['rev']) && !$more['rev']) unset($more['rev']); $more = buildURLparams($more, $sep); } else { - $matches = array(); - if (preg_match_all('/\b(w|h)=(\d*)\b/',$more,$matches,PREG_SET_ORDER) || $isexternalimage){ - $resize = array('w'=>0, 'h'=>0); - foreach ($matches as $match){ + $matches = []; + if (preg_match_all('/\b(w|h)=(\d*)\b/', $more, $matches, PREG_SET_ORDER) || $isexternalimage) { + $resize = ['w' => 0, 'h' => 0]; + foreach ($matches as $match) { $resize[$match[1]] = $match[2]; } $more .= $more === '' ? '' : $sep; - $more .= 'tok='.media_get_token($id,$resize['w'],$resize['h']); + $more .= 'tok=' . media_get_token($id, $resize['w'], $resize['h']); } $more = str_replace('cache=cache', '', $more); //skip default $more = str_replace(',,', ',', $more); $more = str_replace(',', $sep, $more); } - if($abs) { + if ($abs) { $xlink = DOKU_URL; } else { $xlink = DOKU_BASE; } // external URLs are always direct without rewriting - if($isexternalimage) { + if ($isexternalimage) { $xlink .= 'lib/exe/fetch.php'; - $xlink .= '?'.$more; - $xlink .= $sep.'media='.rawurlencode($id); + $xlink .= '?' . $more; + $xlink .= $sep . 'media=' . rawurlencode($id); return $xlink; } $id = idfilter($id); // decide on scriptname - if($direct) { - if($conf['userewrite'] == 1) { + if ($direct) { + if ($conf['userewrite'] == 1) { $script = '_media'; } else { $script = 'lib/exe/fetch.php'; } + } elseif ($conf['userewrite'] == 1) { + $script = '_detail'; } else { - if($conf['userewrite'] == 1) { - $script = '_detail'; - } else { - $script = 'lib/exe/detail.php'; - } + $script = 'lib/exe/detail.php'; } // build URL based on rewrite mode - if($conf['userewrite']) { - $xlink .= $script.'/'.$id; - if($more) $xlink .= '?'.$more; + if ($conf['userewrite']) { + $xlink .= $script . '/' . $id; + if ($more) $xlink .= '?' . $more; + } elseif ($more) { + $xlink .= $script . '?' . $more; + $xlink .= $sep . 'media=' . $id; } else { - if($more) { - $xlink .= $script.'?'.$more; - $xlink .= $sep.'media='.$id; - } else { - $xlink .= $script.'?media='.$id; - } + $xlink .= $script . '?media=' . $id; } return $xlink; @@ -690,8 +690,9 @@ function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false) * * @return string */ -function script() { - return DOKU_BASE.DOKU_SCRIPT; +function script() +{ + return DOKU_BASE . DOKU_SCRIPT; } /** @@ -719,7 +720,8 @@ function script() { * @param string $text - optional text to check, if not given the globals are used * @return bool - true if a spam word was found */ -function checkwordblock($text = '') { +function checkwordblock($text = '') +{ global $TEXT; global $PRE; global $SUF; @@ -729,9 +731,9 @@ function checkwordblock($text = '') { /* @var Input $INPUT */ global $INPUT; - if(!$conf['usewordblock']) return false; + if (!$conf['usewordblock']) return false; - if(!$text) $text = "$PRE $TEXT $SUF $SUM"; + if (!$text) $text = "$PRE $TEXT $SUF $SUM"; // we prepare the text a tiny bit to prevent spammers circumventing URL checks // phpcs:disable Generic.Files.LineLength.TooLong @@ -747,28 +749,26 @@ function checkwordblock($text = '') { // MAX_PATTERN_SIZE in modern PCRE $chunksize = 200; - while($blocks = array_splice($wordblocks, 0, $chunksize)) { - $re = array(); + while ($blocks = array_splice($wordblocks, 0, $chunksize)) { + $re = []; // build regexp from blocks - foreach($blocks as $block) { + foreach ($blocks as $block) { $block = preg_replace('/#.*$/', '', $block); $block = trim($block); - if(empty($block)) continue; + if (empty($block)) continue; $re[] = $block; } - if(count($re) && preg_match('#('.join('|', $re).')#si', $text, $matches)) { + if (count($re) && preg_match('#(' . implode('|', $re) . ')#si', $text, $matches)) { // prepare event data - $data = array(); + $data = []; $data['matches'] = $matches; $data['userinfo']['ip'] = $INPUT->server->str('REMOTE_ADDR'); - if($INPUT->server->str('REMOTE_USER')) { + if ($INPUT->server->str('REMOTE_USER')) { $data['userinfo']['user'] = $INPUT->server->str('REMOTE_USER'); $data['userinfo']['name'] = $INFO['userinfo']['name']; $data['userinfo']['mail'] = $INFO['userinfo']['mail']; } - $callback = function () { - return true; - }; + $callback = static fn() => true; return Event::createAndTrigger('COMMON_WORDBLOCK_BLOCKED', $data, $callback, true); } } @@ -790,34 +790,35 @@ function checkwordblock($text = '') { * @param boolean $single If set only a single IP is returned * @return string */ -function clientIP($single = false) { +function clientIP($single = false) +{ /* @var Input $INPUT */ global $INPUT, $conf; - $ip = array(); + $ip = []; $ip[] = $INPUT->server->str('REMOTE_ADDR'); - if($INPUT->server->str('HTTP_X_FORWARDED_FOR')) { + if ($INPUT->server->str('HTTP_X_FORWARDED_FOR')) { $ip = array_merge($ip, explode(',', str_replace(' ', '', $INPUT->server->str('HTTP_X_FORWARDED_FOR')))); } - if($INPUT->server->str('HTTP_X_REAL_IP')) { + if ($INPUT->server->str('HTTP_X_REAL_IP')) { $ip = array_merge($ip, explode(',', str_replace(' ', '', $INPUT->server->str('HTTP_X_REAL_IP')))); } // remove any non-IP stuff $cnt = count($ip); - for($i = 0; $i < $cnt; $i++) { - if(filter_var($ip[$i], FILTER_VALIDATE_IP) === false) { + for ($i = 0; $i < $cnt; $i++) { + if (filter_var($ip[$i], FILTER_VALIDATE_IP) === false) { unset($ip[$i]); } } $ip = array_values(array_unique($ip)); - if(empty($ip) || !$ip[0]) $ip[0] = '0.0.0.0'; // for some strange reason we don't have a IP + if ($ip === [] || !$ip[0]) $ip[0] = '0.0.0.0'; // for some strange reason we don't have a IP - if(!$single) return join(',', $ip); + if (!$single) return implode(',', $ip); // skip trusted local addresses - foreach($ip as $i) { - if(!empty($conf['trustedproxy']) && preg_match('/'.$conf['trustedproxy'].'/', $i)) { + foreach ($ip as $i) { + if (!empty($conf['trustedproxy']) && preg_match('/' . $conf['trustedproxy'] . '/', $i)) { continue; } else { return $i; @@ -826,7 +827,7 @@ function clientIP($single = false) { // still here? just use the last address // this case all ips in the list are trusted - return $ip[count($ip)-1]; + return $ip[count($ip) - 1]; } /** @@ -839,17 +840,18 @@ function clientIP($single = false) { * @deprecated 2018-04-27 you probably want media queries instead anyway * @return bool if true, client is mobile browser; otherwise false */ -function clientismobile() { +function clientismobile() +{ /* @var Input $INPUT */ global $INPUT; - if($INPUT->server->has('HTTP_X_WAP_PROFILE')) return true; + if ($INPUT->server->has('HTTP_X_WAP_PROFILE')) return true; - if(preg_match('/wap\.|\.wap/i', $INPUT->server->str('HTTP_ACCEPT'))) return true; + if (preg_match('/wap\.|\.wap/i', $INPUT->server->str('HTTP_ACCEPT'))) return true; - if(!$INPUT->server->has('HTTP_USER_AGENT')) return false; + if (!$INPUT->server->has('HTTP_USER_AGENT')) return false; - $uamatches = join( + $uamatches = implode( '|', [ 'midp', 'j2me', 'avantg', 'docomo', 'novarra', 'palmos', 'palmsource', '240x320', 'opwv', @@ -862,7 +864,7 @@ function clientismobile() { ] ); - if(preg_match("/$uamatches/i", $INPUT->server->str('HTTP_USER_AGENT'))) return true; + if (preg_match("/$uamatches/i", $INPUT->server->str('HTTP_USER_AGENT'))) return true; return false; } @@ -873,8 +875,9 @@ function clientismobile() { * @param string $link the link, e.g. "wiki>page" * @return bool */ -function link_isinterwiki($link){ - if (preg_match('/^[a-zA-Z0-9\.]+>/u',$link)) return true; +function link_isinterwiki($link) +{ + if (preg_match('/^[a-zA-Z0-9\.]+>/u', $link)) return true; return false; } @@ -888,18 +891,19 @@ function link_isinterwiki($link){ * @param string $ips comma separated list of IP addresses * @return string a comma separated list of hostnames */ -function gethostsbyaddrs($ips) { +function gethostsbyaddrs($ips) +{ global $conf; - if(!$conf['dnslookups']) return $ips; + if (!$conf['dnslookups']) return $ips; - $hosts = array(); + $hosts = []; $ips = explode(',', $ips); - if(is_array($ips)) { - foreach($ips as $ip) { + if (is_array($ips)) { + foreach ($ips as $ip) { $hosts[] = gethostbyaddr(trim($ip)); } - return join(',', $hosts); + return implode(',', $hosts); } else { return gethostbyaddr(trim($ips)); } @@ -915,7 +919,8 @@ function gethostsbyaddrs($ips) { * @param string $id page id * @return bool page is locked? */ -function checklock($id) { +function checklock($id) +{ global $conf; /* @var Input $INPUT */ global $INPUT; @@ -923,17 +928,17 @@ function checklock($id) { $lock = wikiLockFN($id); //no lockfile - if(!file_exists($lock)) return false; + if (!file_exists($lock)) return false; //lockfile expired - if((time() - filemtime($lock)) > $conf['locktime']) { + if ((time() - filemtime($lock)) > $conf['locktime']) { @unlink($lock); return false; } //my own lock - @list($ip, $session) = explode("\n", io_readFile($lock)); - if($ip == $INPUT->server->str('REMOTE_USER') || (session_id() && $session == session_id())) { + @[$ip, $session] = explode("\n", io_readFile($lock)); + if ($ip == $INPUT->server->str('REMOTE_USER') || (session_id() && $session === session_id())) { return false; } @@ -947,20 +952,21 @@ function checklock($id) { * * @param string $id page id to lock */ -function lock($id) { +function lock($id) +{ global $conf; /* @var Input $INPUT */ global $INPUT; - if($conf['locktime'] == 0) { + if ($conf['locktime'] == 0) { return; } $lock = wikiLockFN($id); - if($INPUT->server->str('REMOTE_USER')) { + if ($INPUT->server->str('REMOTE_USER')) { io_saveFile($lock, $INPUT->server->str('REMOTE_USER')); } else { - io_saveFile($lock, clientIP()."\n".session_id()); + io_saveFile($lock, clientIP() . "\n" . session_id()); } } @@ -972,14 +978,15 @@ function lock($id) { * @param string $id page id to unlock * @return bool true if a lock was removed */ -function unlock($id) { +function unlock($id) +{ /* @var Input $INPUT */ global $INPUT; $lock = wikiLockFN($id); - if(file_exists($lock)) { - @list($ip, $session) = explode("\n", io_readFile($lock)); - if($ip == $INPUT->server->str('REMOTE_USER') || $session == session_id()) { + if (file_exists($lock)) { + @[$ip, $session] = explode("\n", io_readFile($lock)); + if ($ip == $INPUT->server->str('REMOTE_USER') || $session == session_id()) { @unlink($lock); return true; } @@ -998,13 +1005,14 @@ function unlock($id) { * @param string $text * @return string */ -function cleanText($text) { +function cleanText($text) +{ $text = preg_replace("/(\015\012)|(\015)/", "\012", $text); // if the text is not valid UTF-8 we simply assume latin1 // this won't break any worse than it breaks with the wrong encoding // but might actually fix the problem in many cases - if(!\dokuwiki\Utf8\Clean::isUtf8($text)) $text = utf8_encode($text); + if (!Clean::isUtf8($text)) $text = utf8_encode($text); return $text; } @@ -1020,7 +1028,8 @@ function cleanText($text) { * @param string $text * @return string */ -function formText($text) { +function formText($text) +{ $text = str_replace("\012", "\015\012", $text ?? ''); return htmlspecialchars($text); } @@ -1034,7 +1043,8 @@ function formText($text) { * @param string $ext extension of file being read, default 'txt' * @return string */ -function rawLocale($id, $ext = 'txt') { +function rawLocale($id, $ext = 'txt') +{ return io_readFile(localeFN($id, $ext)); } @@ -1047,7 +1057,8 @@ function rawLocale($id, $ext = 'txt') { * @param string|int $rev timestamp when a revision of wikitext is desired * @return string */ -function rawWiki($id, $rev = '') { +function rawWiki($id, $rev = '') +{ return io_readWikiPage(wikiFN($id, $rev), $id, $rev); } @@ -1060,34 +1071,35 @@ function rawWiki($id, $rev = '') { * @param string $id the id of the page to be created * @return string parsed pagetemplate content */ -function pageTemplate($id) { +function pageTemplate($id) +{ global $conf; - if(is_array($id)) $id = $id[0]; + if (is_array($id)) $id = $id[0]; // prepare initial event data - $data = array( + $data = [ 'id' => $id, // the id of the page to be created 'tpl' => '', // the text used as template 'tplfile' => '', // the file above text was/should be loaded from - 'doreplace' => true // should wildcard replacements be done on the text? - ); + 'doreplace' => true, + ]; $evt = new Event('COMMON_PAGETPL_LOAD', $data); - if($evt->advise_before(true)) { + if ($evt->advise_before(true)) { // the before event might have loaded the content already - if(empty($data['tpl'])) { + if (empty($data['tpl'])) { // if the before event did not set a template file, try to find one - if(empty($data['tplfile'])) { + if (empty($data['tplfile'])) { $path = dirname(wikiFN($id)); - if(file_exists($path.'/_template.txt')) { - $data['tplfile'] = $path.'/_template.txt'; + if (file_exists($path . '/_template.txt')) { + $data['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')) { - $data['tplfile'] = $path.'/__template.txt'; + while (strlen($path) >= $len) { + if (file_exists($path . '/__template.txt')) { + $data['tplfile'] = $path . '/__template.txt'; break; } $path = substr($path, 0, strrpos($path, '/')); @@ -1097,7 +1109,7 @@ function pageTemplate($id) { // load the content $data['tpl'] = io_readFile($data['tplfile']); } - if($data['doreplace']) parsePageTemplate($data); + if ($data['doreplace']) parsePageTemplate($data); } $evt->advise_after(); unset($evt); @@ -1114,7 +1126,8 @@ function pageTemplate($id) { * @param array $data array with event data * @return string */ -function parsePageTemplate(&$data) { +function parsePageTemplate(&$data) +{ /** * @var string $id the id of the page to be created * @var string $tpl the text used as template @@ -1133,52 +1146,51 @@ function parsePageTemplate(&$data) { $page = strtr($file, $conf['sepchar'], ' '); $tpl = str_replace( - array( - '@ID@', - '@NS@', - '@CURNS@', - '@!CURNS@', - '@!!CURNS@', - '@!CURNS!@', - '@FILE@', - '@!FILE@', - '@!FILE!@', - '@PAGE@', - '@!PAGE@', - '@!!PAGE@', - '@!PAGE!@', - '@USER@', - '@NAME@', - '@MAIL@', - '@DATE@', - ), - array( - $id, - getNS($id), - curNS($id), - \dokuwiki\Utf8\PhpString::ucfirst(curNS($id)), - \dokuwiki\Utf8\PhpString::ucwords(curNS($id)), - \dokuwiki\Utf8\PhpString::strtoupper(curNS($id)), - $file, - \dokuwiki\Utf8\PhpString::ucfirst($file), - \dokuwiki\Utf8\PhpString::strtoupper($file), - $page, - \dokuwiki\Utf8\PhpString::ucfirst($page), - \dokuwiki\Utf8\PhpString::ucwords($page), - \dokuwiki\Utf8\PhpString::strtoupper($page), - $INPUT->server->str('REMOTE_USER'), - $USERINFO ? $USERINFO['name'] : '', - $USERINFO ? $USERINFO['mail'] : '', - $conf['dformat'], - ), $tpl + [ + '@ID@', + '@NS@', + '@CURNS@', + '@!CURNS@', + '@!!CURNS@', + '@!CURNS!@', + '@FILE@', + '@!FILE@', + '@!FILE!@', + '@PAGE@', + '@!PAGE@', + '@!!PAGE@', + '@!PAGE!@', + '@USER@', + '@NAME@', + '@MAIL@', + '@DATE@' + ], + [ + $id, + getNS($id), + curNS($id), + PhpString::ucfirst(curNS($id)), + PhpString::ucwords(curNS($id)), + PhpString::strtoupper(curNS($id)), + $file, + PhpString::ucfirst($file), + PhpString::strtoupper($file), + $page, + PhpString::ucfirst($page), + PhpString::ucwords($page), + PhpString::strtoupper($page), + $INPUT->server->str('REMOTE_USER'), + $USERINFO ? $USERINFO['name'] : '', + $USERINFO ? $USERINFO['mail'] : '', + $conf['dformat'] + ], + $tpl ); // we need the callback to work around strftime's char limit $tpl = preg_replace_callback( '/%./', - function ($m) { - return dformat(null, $m[0]); - }, + static fn($m) => dformat(null, $m[0]), $tpl ); $data['tpl'] = $tpl; @@ -1200,16 +1212,17 @@ function parsePageTemplate(&$data) { * @param string $rev optional, the revision timestamp * @return string[] with three slices */ -function rawWikiSlices($range, $id, $rev = '') { +function rawWikiSlices($range, $id, $rev = '') +{ $text = io_readWikiPage(wikiFN($id, $rev), $id, $rev); // Parse range - list($from, $to) = sexplode('-', $range, 2); + [$from, $to] = sexplode('-', $range, 2); // Make range zero-based, use defaults if marker is missing - $from = !$from ? 0 : ($from - 1); - $to = !$to ? strlen($text) : ($to - 1); + $from = $from ? $from - 1 : (0); + $to = $to ? $to - 1 : (strlen($text)); - $slices = array(); + $slices = []; $slices[0] = substr($text, 0, $from); $slices[1] = substr($text, $from, $to - $from); $slices[2] = substr($text, $to); @@ -1231,21 +1244,24 @@ function rawWikiSlices($range, $id, $rev = '') { * @param bool $pretty add additional empty lines between sections * @return string */ -function con($pre, $text, $suf, $pretty = false) { - if($pretty) { - if($pre !== '' && substr($pre, -1) !== "\n" && +function con($pre, $text, $suf, $pretty = false) +{ + if ($pretty) { + if ( + $pre !== '' && substr($pre, -1) !== "\n" && substr($text, 0, 1) !== "\n" ) { $pre .= "\n"; } - if($suf !== '' && substr($text, -1) !== "\n" && + if ( + $suf !== '' && substr($text, -1) !== "\n" && substr($suf, 0, 1) !== "\n" ) { $text .= "\n"; } } - return $pre.$text.$suf; + return $pre . $text . $suf; } /** @@ -1259,8 +1275,9 @@ function con($pre, $text, $suf, $pretty = false) { * @param string $id the page ID * @deprecated 2021-11-28 */ -function detectExternalEdit($id) { - dbg_deprecated(PageFile::class .'::detectExternalEdit()'); +function detectExternalEdit($id) +{ + dbg_deprecated(PageFile::class . '::detectExternalEdit()'); (new PageFile($id))->detectExternalEdit(); } @@ -1276,14 +1293,15 @@ function detectExternalEdit($id) { * @param string $summary summary of text update * @param bool $minor mark this saved version as minor update */ -function saveWikiText($id, $text, $summary, $minor = false) { +function saveWikiText($id, $text, $summary, $minor = false) +{ // get COMMON_WIKIPAGE_SAVE event data $data = (new PageFile($id))->saveWikiText($text, $summary, $minor); - if(!$data) return; // save was cancelled (for no changes or by a plugin) + if (!$data) return; // save was cancelled (for no changes or by a plugin) // send notify mails - list('oldRevision' => $rev, 'newRevision' => $new_rev, 'summary' => $summary) = $data; + ['oldRevision' => $rev, 'newRevision' => $new_rev, 'summary' => $summary] = $data; notify($id, 'admin', $rev, $summary, $minor, $new_rev); notify($id, 'subscribers', $rev, $summary, $minor, $new_rev); @@ -1306,8 +1324,9 @@ function saveWikiText($id, $text, $summary, $minor = false) { * @return int|string revision timestamp * @deprecated 2021-11-28 */ -function saveOldRevision($id) { - dbg_deprecated(PageFile::class .'::saveOldRevision()'); +function saveOldRevision($id) +{ + dbg_deprecated(PageFile::class . '::saveOldRevision()'); return (new PageFile($id))->saveOldRevision(); } @@ -1325,7 +1344,8 @@ function saveOldRevision($id) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array(), $current_rev = false) { +function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = [], $current_rev = false) +{ global $conf; /* @var Input $INPUT */ global $INPUT; @@ -1338,10 +1358,11 @@ function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = } elseif ($who == 'subscribers') { if (!actionOK('subscribe')) return false; //subscribers enabled? if ($conf['useacl'] && $INPUT->server->str('REMOTE_USER') && $minor) return false; //skip minors - $data = array('id' => $id, 'addresslist' => '', 'self' => false, 'replacements' => $replace); + $data = ['id' => $id, 'addresslist' => '', 'self' => false, 'replacements' => $replace]; Event::createAndTrigger( - 'COMMON_NOTIFY_ADDRESSLIST', $data, - array(new SubscriberManager(), 'notifyAddresses') + 'COMMON_NOTIFY_ADDRESSLIST', + $data, + [new SubscriberManager(), 'notifyAddresses'] ); $to = $data['addresslist']; if (empty($to)) return false; @@ -1363,36 +1384,37 @@ function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = * * @return array|string */ -function getGoogleQuery() { +function getGoogleQuery() +{ /* @var Input $INPUT */ global $INPUT; - if(!$INPUT->server->has('HTTP_REFERER')) { + if (!$INPUT->server->has('HTTP_REFERER')) { return ''; } $url = parse_url($INPUT->server->str('HTTP_REFERER')); // only handle common SEs - if(!array_key_exists('host', $url)) return ''; - if(!preg_match('/(google|bing|yahoo|ask|duckduckgo|babylon|aol|yandex)/',$url['host'])) return ''; + if (!array_key_exists('host', $url)) return ''; + if (!preg_match('/(google|bing|yahoo|ask|duckduckgo|babylon|aol|yandex)/', $url['host'])) return ''; - $query = array(); - if(!array_key_exists('query', $url)) return ''; + $query = []; + if (!array_key_exists('query', $url)) return ''; parse_str($url['query'], $query); $q = ''; - if(isset($query['q'])){ + if (isset($query['q'])) { $q = $query['q']; - }elseif(isset($query['p'])){ + } elseif (isset($query['p'])) { $q = $query['p']; - }elseif(isset($query['query'])){ + } elseif (isset($query['query'])) { $q = $query['query']; } $q = trim($q); - if(!$q) return ''; + if (!$q) return ''; // ignore if query includes a full URL - if(strpos($q, '//') !== false) return ''; + if (strpos($q, '//') !== false) return ''; $q = preg_split('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/', $q, -1, PREG_SPLIT_NO_EMPTY); return $q; } @@ -1408,17 +1430,18 @@ function getGoogleQuery() { * @author Aidan Lister <aidan@php.net> * @version 1.0.0 */ -function filesize_h($size, $dec = 1) { - $sizes = array('B', 'KB', 'MB', 'GB'); +function filesize_h($size, $dec = 1) +{ + $sizes = ['B', 'KB', 'MB', 'GB']; $count = count($sizes); $i = 0; - while($size >= 1024 && ($i < $count - 1)) { + while ($size >= 1024 && ($i < $count - 1)) { $size /= 1024; $i++; } - return round($size, $dec)."\xC2\xA0".$sizes[$i]; //non-breaking space + return round($size, $dec) . "\xC2\xA0" . $sizes[$i]; //non-breaking space } /** @@ -1429,26 +1452,27 @@ function filesize_h($size, $dec = 1) { * @param int $dt timestamp * @return string */ -function datetime_h($dt) { +function datetime_h($dt) +{ global $lang; $ago = time() - $dt; - if($ago > 24 * 60 * 60 * 30 * 12 * 2) { + if ($ago > 24 * 60 * 60 * 30 * 12 * 2) { return sprintf($lang['years'], round($ago / (24 * 60 * 60 * 30 * 12))); } - if($ago > 24 * 60 * 60 * 30 * 2) { + if ($ago > 24 * 60 * 60 * 30 * 2) { return sprintf($lang['months'], round($ago / (24 * 60 * 60 * 30))); } - if($ago > 24 * 60 * 60 * 7 * 2) { + if ($ago > 24 * 60 * 60 * 7 * 2) { return sprintf($lang['weeks'], round($ago / (24 * 60 * 60 * 7))); } - if($ago > 24 * 60 * 60 * 2) { + if ($ago > 24 * 60 * 60 * 2) { return sprintf($lang['days'], round($ago / (24 * 60 * 60))); } - if($ago > 60 * 60 * 2) { + if ($ago > 60 * 60 * 2) { return sprintf($lang['hours'], round($ago / (60 * 60))); } - if($ago > 60 * 2) { + if ($ago > 60 * 2) { return sprintf($lang['minutes'], round($ago / (60))); } return sprintf($lang['seconds'], $ago); @@ -1467,12 +1491,13 @@ function datetime_h($dt) { * @param string $format empty default to $conf['dformat'], or provide format as recognized by strftime() * @return string */ -function dformat($dt = null, $format = '') { +function dformat($dt = null, $format = '') +{ global $conf; - if(is_null($dt)) $dt = time(); + if (is_null($dt)) $dt = time(); $dt = (int) $dt; - if(!$format) $format = $conf['dformat']; + if (!$format) $format = $conf['dformat']; $format = str_replace('%f', datetime_h($dt), $format); return strftime($format, $dt); @@ -1487,10 +1512,11 @@ function dformat($dt = null, $format = '') { * @param int $int_date current date in UNIX timestamp * @return string */ -function date_iso8601($int_date) { +function date_iso8601($int_date) +{ $date_mod = date('Y-m-d\TH:i:s', $int_date); $pre_timezone = date('O', $int_date); - $time_zone = substr($pre_timezone, 0, 3).":".substr($pre_timezone, 3, 2); + $time_zone = substr($pre_timezone, 0, 3) . ":" . substr($pre_timezone, 3, 2); $date_mod .= $time_zone; return $date_mod; } @@ -1504,19 +1530,20 @@ function date_iso8601($int_date) { * @param string $email email address * @return string */ -function obfuscate($email) { +function obfuscate($email) +{ global $conf; - switch($conf['mailguard']) { - case 'visible' : - $obfuscate = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] '); + switch ($conf['mailguard']) { + case 'visible': + $obfuscate = ['@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] ']; return strtr($email, $obfuscate); - case 'hex' : - return \dokuwiki\Utf8\Conversion::toHtml($email, true); + case 'hex': + return Conversion::toHtml($email, true); - case 'none' : - default : + case 'none': + default: return $email; } } @@ -1530,8 +1557,9 @@ function obfuscate($email) { * @param string $char backslashed character * @return string */ -function unslash($string, $char = "'") { - return str_replace('\\'.$char, $char, $string); +function unslash($string, $char = "'") +{ + return str_replace('\\' . $char, $char, $string); } /** @@ -1545,19 +1573,20 @@ function unslash($string, $char = "'") { * @param string $value PHP size shorthand * @return int */ -function php_to_byte($value) { - switch (strtoupper(substr($value,-1))) { +function php_to_byte($value) +{ + switch (strtoupper(substr($value, -1))) { case 'G': - $ret = intval(substr($value, 0, -1)) * 1024 * 1024 * 1024; + $ret = (int) substr($value, 0, -1) * 1024 * 1024 * 1024; break; case 'M': - $ret = intval(substr($value, 0, -1)) * 1024 * 1024; + $ret = (int) substr($value, 0, -1) * 1024 * 1024; break; case 'K': - $ret = intval(substr($value, 0, -1)) * 1024; + $ret = (int) substr($value, 0, -1) * 1024; break; default: - $ret = intval($value); + $ret = (int) $value; break; } return $ret; @@ -1569,7 +1598,8 @@ function php_to_byte($value) { * @param string $string * @return string */ -function preg_quote_cb($string) { +function preg_quote_cb($string) +{ return preg_quote($string, '/'); } @@ -1588,16 +1618,17 @@ function preg_quote_cb($string) { * @param string $char the shortening character to use * @return string */ -function shorten($keep, $short, $max, $min = 9, $char = '…') { - $max = $max - \dokuwiki\Utf8\PhpString::strlen($keep); - if($max < $min) return $keep; - $len = \dokuwiki\Utf8\PhpString::strlen($short); - if($len <= $max) return $keep.$short; +function shorten($keep, $short, $max, $min = 9, $char = '…') +{ + $max -= PhpString::strlen($keep); + if ($max < $min) return $keep; + $len = PhpString::strlen($short); + if ($len <= $max) return $keep . $short; $half = floor($max / 2); return $keep . - \dokuwiki\Utf8\PhpString::substr($short, 0, $half - 1) . + PhpString::substr($short, 0, $half - 1) . $char . - \dokuwiki\Utf8\PhpString::substr($short, $len - $half); + PhpString::substr($short, $len - $half); } /** @@ -1610,7 +1641,8 @@ function shorten($keep, $short, $max, $min = 9, $char = '…') { * * @author Andy Webber <dokuwiki AT andywebber DOT com> */ -function editorinfo($username, $textonly = false) { +function editorinfo($username, $textonly = false) +{ return userlink($username, $textonly); } @@ -1623,7 +1655,8 @@ function editorinfo($username, $textonly = false) { * * @triggers COMMON_USER_LINK */ -function userlink($username = null, $textonly = false) { +function userlink($username = null, $textonly = false) +{ global $conf, $INFO; /** @var AuthPlugin $auth */ global $auth; @@ -1631,38 +1664,41 @@ function userlink($username = null, $textonly = false) { global $INPUT; // prepare initial event data - $data = array( + $data = [ 'username' => $username, // the unique user name 'name' => '', - 'link' => array( //setting 'link' to false disables linking - 'target' => '', - 'pre' => '', - 'suf' => '', - 'style' => '', - 'more' => '', - 'url' => '', - 'title' => '', - 'class' => '' - ), + 'link' => [ + //setting 'link' to false disables linking + 'target' => '', + 'pre' => '', + 'suf' => '', + 'style' => '', + 'more' => '', + 'url' => '', + 'title' => '', + 'class' => '', + ], 'userlink' => '', // formatted user name as will be returned - 'textonly' => $textonly - ); - if($username === null) { + 'textonly' => $textonly, + ]; + if ($username === null) { $data['username'] = $username = $INPUT->server->str('REMOTE_USER'); - if($textonly){ - $data['name'] = $INFO['userinfo']['name']. ' (' . $INPUT->server->str('REMOTE_USER') . ')'; - }else { - $data['name'] = '<bdi>' . hsc($INFO['userinfo']['name']) . '</bdi> '. + if ($textonly) { + $data['name'] = $INFO['userinfo']['name'] . ' (' . $INPUT->server->str('REMOTE_USER') . ')'; + } else { + $data['name'] = '<bdi>' . hsc($INFO['userinfo']['name']) . '</bdi> ' . '(<bdi>' . hsc($INPUT->server->str('REMOTE_USER')) . '</bdi>)'; } } $evt = new Event('COMMON_USER_LINK', $data); - if($evt->advise_before(true)) { - if(empty($data['name'])) { - if($auth) $info = $auth->getUserData($username); - if($conf['showuseras'] != 'loginname' && isset($info) && $info) { - switch($conf['showuseras']) { + if ($evt->advise_before(true)) { + if (empty($data['name'])) { + if ($auth instanceof AuthPlugin) { + $info = $auth->getUserData($username); + } + if ($conf['showuseras'] != 'loginname' && isset($info) && $info) { + switch ($conf['showuseras']) { case 'username': case 'username_link': $data['name'] = $textonly ? $info['name'] : hsc($info['name']); @@ -1680,28 +1716,27 @@ function userlink($username = null, $textonly = false) { /** @var Doku_Renderer_xhtml $xhtml_renderer */ static $xhtml_renderer = null; - if(!$data['textonly'] && empty($data['link']['url'])) { - - if(in_array($conf['showuseras'], array('email_link', 'username_link'))) { - if(!isset($info)) { - if($auth) $info = $auth->getUserData($username); + if (!$data['textonly'] && empty($data['link']['url'])) { + if (in_array($conf['showuseras'], ['email_link', 'username_link'])) { + if (!isset($info) && $auth instanceof AuthPlugin) { + $info = $auth->getUserData($username); } - if(isset($info) && $info) { - if($conf['showuseras'] == 'email_link') { + if (isset($info) && $info) { + if ($conf['showuseras'] == 'email_link') { $data['link']['url'] = 'mailto:' . obfuscate($info['mail']); } else { - if(is_null($xhtml_renderer)) { + if (is_null($xhtml_renderer)) { $xhtml_renderer = p_get_renderer('xhtml'); } - if(empty($xhtml_renderer->interwiki)) { + if (empty($xhtml_renderer->interwiki)) { $xhtml_renderer->interwiki = getInterwiki(); } $shortcut = 'user'; $exists = null; $data['link']['url'] = $xhtml_renderer->_resolveInterWiki($shortcut, $username, $exists); $data['link']['class'] .= ' interwiki iw_user'; - if($exists !== null) { - if($exists) { + if ($exists !== null) { + if ($exists) { $data['link']['class'] .= ' wikilink1'; } else { $data['link']['class'] .= ' wikilink2'; @@ -1712,17 +1747,16 @@ function userlink($username = null, $textonly = false) { } else { $data['textonly'] = true; } - } else { $data['textonly'] = true; } } - if($data['textonly']) { + if ($data['textonly']) { $data['userlink'] = $data['name']; } else { $data['link']['name'] = $data['name']; - if(is_null($xhtml_renderer)) { + if (is_null($xhtml_renderer)) { $xhtml_renderer = p_get_renderer('xhtml'); } $data['userlink'] = $xhtml_renderer->_formatLink($data['link']); @@ -1743,19 +1777,20 @@ function userlink($username = null, $textonly = false) { * @param string $type - type of image 'badge' or 'button' * @return string */ -function license_img($type) { +function license_img($type) +{ global $license; global $conf; - if(!$conf['license']) return ''; - if(!is_array($license[$conf['license']])) return ''; - $try = array(); - $try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.png'; - $try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.gif'; - if(substr($conf['license'], 0, 3) == 'cc-') { - $try[] = 'lib/images/license/'.$type.'/cc.png'; + if (!$conf['license']) return ''; + if (!is_array($license[$conf['license']])) return ''; + $try = []; + $try[] = 'lib/images/license/' . $type . '/' . $conf['license'] . '.png'; + $try[] = 'lib/images/license/' . $type . '/' . $conf['license'] . '.gif'; + if (substr($conf['license'], 0, 3) == 'cc-') { + $try[] = 'lib/images/license/' . $type . '/cc.png'; } - foreach($try as $src) { - if(file_exists(DOKU_INC.$src)) return $src; + foreach ($try as $src) { + if (file_exists(DOKU_INC . $src)) return $src; } return ''; } @@ -1773,22 +1808,23 @@ function license_img($type) { * @param int $bytes already allocated memory (see above) * @return bool */ -function is_mem_available($mem, $bytes = 1048576) { +function is_mem_available($mem, $bytes = 1_048_576) +{ $limit = trim(ini_get('memory_limit')); - if(empty($limit)) return true; // no limit set! - if($limit == -1) return true; // unlimited + if (empty($limit)) return true; // no limit set! + if ($limit == -1) return true; // unlimited // parse limit to bytes $limit = php_to_byte($limit); // get used memory if possible - if(function_exists('memory_get_usage')) { + if (function_exists('memory_get_usage')) { $used = memory_get_usage(); } else { $used = $bytes; } - if($used + $mem > $limit) { + if ($used + $mem > $limit) { return false; } @@ -1805,7 +1841,8 @@ function is_mem_available($mem, $bytes = 1048576) { * * @param string $url url being directed to */ -function send_redirect($url) { +function send_redirect($url) +{ $url = stripctl($url); // defend against HTTP Response Splitting /* @var Input $INPUT */ @@ -1813,7 +1850,7 @@ function send_redirect($url) { //are there any undisplayed messages? keep them in session for display global $MSG; - if(isset($MSG) && count($MSG) && !defined('NOSESSION')) { + if (isset($MSG) && count($MSG) && !defined('NOSESSION')) { //reopen session, store data and close session again @session_start(); $_SESSION[DOKU_COOKIE]['msg'] = $MSG; @@ -1823,21 +1860,22 @@ function send_redirect($url) { session_write_close(); // check if running on IIS < 6 with CGI-PHP - if($INPUT->server->has('SERVER_SOFTWARE') && $INPUT->server->has('GATEWAY_INTERFACE') && + if ( + $INPUT->server->has('SERVER_SOFTWARE') && $INPUT->server->has('GATEWAY_INTERFACE') && (strpos($INPUT->server->str('GATEWAY_INTERFACE'), 'CGI') !== false) && (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($INPUT->server->str('SERVER_SOFTWARE')), $matches)) && $matches[1] < 6 ) { - header('Refresh: 0;url='.$url); + header('Refresh: 0;url=' . $url); } else { - header('Location: '.$url); + header('Location: ' . $url); } // no exits during unit tests - if(defined('DOKU_UNITTEST')) { + if (defined('DOKU_UNITTEST')) { // pass info about the redirect back to the test suite $testRequest = TestRequest::getRunning(); - if($testRequest !== null) { + if ($testRequest !== null) { $testRequest->addData('send_redirect', $url); } return; @@ -1864,10 +1902,11 @@ function send_redirect($url) { * @return mixed * @author Adrian Lang <lang@cosmocode.de> */ -function valid_input_set($param, $valid_values, $array, $exc = '') { - if(isset($array[$param]) && in_array($array[$param], $valid_values)) { +function valid_input_set($param, $valid_values, $array, $exc = '') +{ + if (isset($array[$param]) && in_array($array[$param], $valid_values)) { return $array[$param]; - } elseif(isset($valid_values['default'])) { + } elseif (isset($valid_values['default'])) { return $valid_values['default']; } else { throw new Exception($exc); @@ -1882,16 +1921,17 @@ function valid_input_set($param, $valid_values, $array, $exc = '') { * @param mixed $default value returned when preference not found * @return string preference value */ -function get_doku_pref($pref, $default) { +function get_doku_pref($pref, $default) +{ $enc_pref = urlencode($pref); - if(isset($_COOKIE['DOKU_PREFS']) && strpos($_COOKIE['DOKU_PREFS'], $enc_pref) !== false) { + if (isset($_COOKIE['DOKU_PREFS']) && strpos($_COOKIE['DOKU_PREFS'], $enc_pref) !== false) { $parts = explode('#', $_COOKIE['DOKU_PREFS']); $cnt = count($parts); // due to #2721 there might be duplicate entries, // so we read from the end - for($i = $cnt-2; $i >= 0; $i -= 2) { - if($parts[$i] == $enc_pref) { + for ($i = $cnt - 2; $i >= 0; $i -= 2) { + if ($parts[$i] === $enc_pref) { return urldecode($parts[$i + 1]); } } @@ -1907,20 +1947,21 @@ function get_doku_pref($pref, $default) { * @param string $pref preference key * @param string $val preference value */ -function set_doku_pref($pref, $val) { +function set_doku_pref($pref, $val) +{ global $conf; $orig = get_doku_pref($pref, false); $cookieVal = ''; - if($orig !== false && ($orig !== $val)) { + if ($orig !== false && ($orig !== $val)) { $parts = explode('#', $_COOKIE['DOKU_PREFS']); $cnt = count($parts); // urlencode $pref for the comparison $enc_pref = rawurlencode($pref); $seen = false; for ($i = 0; $i < $cnt; $i += 2) { - if ($parts[$i] == $enc_pref) { - if (!$seen){ + if ($parts[$i] === $enc_pref) { + if (!$seen) { if ($val !== false) { $parts[$i + 1] = rawurlencode($val ?? ''); } else { @@ -1936,15 +1977,15 @@ function set_doku_pref($pref, $val) { } } $cookieVal = implode('#', $parts); - } else if ($orig === false && $val !== false) { + } elseif ($orig === false && $val !== false) { $cookieVal = (isset($_COOKIE['DOKU_PREFS']) ? $_COOKIE['DOKU_PREFS'] . '#' : '') . rawurlencode($pref) . '#' . rawurlencode($val); } $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; - if(defined('DOKU_UNITTEST')) { + if (defined('DOKU_UNITTEST')) { $_COOKIE['DOKU_PREFS'] = $cookieVal; - }else{ + } else { setcookie('DOKU_PREFS', $cookieVal, [ 'expires' => time() + 365 * 24 * 3600, 'path' => $cookieDir, @@ -1959,7 +2000,8 @@ function set_doku_pref($pref, $val) { * * @param string &$text reference to the CSS or JavaScript code to clean */ -function stripsourcemaps(&$text){ +function stripsourcemaps(&$text) +{ $text = preg_replace('/^(\/\/|\/\*)[@#]\s+sourceMappingURL=.*?(\*\/)?$/im', '\\1\\2', $text); } @@ -1976,19 +2018,20 @@ function stripsourcemaps(&$text){ * @param int $maxsize maximum allowed size for the SVG to be embedded * @return string|false the SVG content, false if the file couldn't be loaded */ -function inlineSVG($file, $maxsize = 2048) { +function inlineSVG($file, $maxsize = 2048) +{ $file = trim($file); - if($file === '') return false; - if(!file_exists($file)) return false; - if(filesize($file) > $maxsize) return false; - if(!is_readable($file)) return false; + if ($file === '') return false; + if (!file_exists($file)) return false; + if (filesize($file) > $maxsize) return false; + if (!is_readable($file)) return false; $content = file_get_contents($file); - $content = preg_replace('/<!--.*?(-->)/s','', $content); // comments + $content = preg_replace('/<!--.*?(-->)/s', '', $content); // comments $content = preg_replace('/<\?xml .*?\?>/i', '', $content); // xml header $content = preg_replace('/<!DOCTYPE .*?>/i', '', $content); // doc type $content = preg_replace('/>\s+</s', '><', $content); // newlines between tags $content = trim($content); - if(substr($content, 0, 5) !== '<svg ') return false; + if (substr($content, 0, 5) !== '<svg ') return false; return $content; } diff --git a/inc/compatibility.php b/inc/compatibility.php index 445f2456b..cb28ab46a 100644 --- a/inc/compatibility.php +++ b/inc/compatibility.php @@ -1,41 +1,44 @@ <?php + /** * compatibility functions * * This file contains a few functions that might be missing from the PHP build */ -if(!function_exists('ctype_space')) { +if (!function_exists('ctype_space')) { /** * Check for whitespace character(s) * - * @see ctype_space * @param string $text * @return bool + * @see ctype_space */ - function ctype_space($text) { - if(!is_string($text)) return false; #FIXME original treats between -128 and 255 inclusive as ASCII chars - if(trim($text) === '') return true; + function ctype_space($text) + { + if (!is_string($text)) return false; #FIXME original treats between -128 and 255 inclusive as ASCII chars + if (trim($text) === '') return true; return false; } } -if(!function_exists('ctype_digit')) { +if (!function_exists('ctype_digit')) { /** * Check for numeric character(s) * - * @see ctype_digit * @param string $text * @return bool + * @see ctype_digit */ - function ctype_digit($text) { - if(!is_string($text)) return false; #FIXME original treats between -128 and 255 inclusive as ASCII chars - if(preg_match('/^\d+$/', $text)) return true; + function ctype_digit($text) + { + if (!is_string($text)) return false; #FIXME original treats between -128 and 255 inclusive as ASCII chars + if (preg_match('/^\d+$/', $text)) return true; return false; } } -if(!function_exists('gzopen') && function_exists('gzopen64')) { +if (!function_exists('gzopen') && function_exists('gzopen64')) { /** * work around for PHP compiled against certain zlib versions #865 * @@ -43,31 +46,33 @@ if(!function_exists('gzopen') && function_exists('gzopen64')) { * * @param string $filename * @param string $mode - * @param int $use_include_path + * @param int $use_include_path * @return mixed */ - function gzopen($filename, $mode, $use_include_path = 0) { + function gzopen($filename, $mode, $use_include_path = 0) + { return gzopen64($filename, $mode, $use_include_path); } } -if(!function_exists('gzseek') && function_exists('gzseek64')) { +if (!function_exists('gzseek') && function_exists('gzseek64')) { /** * work around for PHP compiled against certain zlib versions #865 * * @link http://stackoverflow.com/questions/23417519/php-zlib-gzopen-not-exists * * @param resource $zp - * @param int $offset - * @param int $whence + * @param int $offset + * @param int $whence * @return int */ - function gzseek($zp, $offset, $whence = SEEK_SET) { + function gzseek($zp, $offset, $whence = SEEK_SET) + { return gzseek64($zp, $offset, $whence); } } -if(!function_exists('gztell') && function_exists('gztell64')) { +if (!function_exists('gztell') && function_exists('gztell64')) { /** * work around for PHP compiled against certain zlib versions #865 * @@ -76,8 +81,41 @@ if(!function_exists('gztell') && function_exists('gztell64')) { * @param resource $zp * @return int */ - function gztell($zp) { + function gztell($zp) + { return gztell64($zp); } } +/** + * polyfill for PHP < 8 + * @see https://www.php.net/manual/en/function.str-starts-with + */ +if (!function_exists('str_starts_with')) { + function str_starts_with(string $haystack, string $needle) + { + return empty($needle) || strpos($haystack, $needle) === 0; + } +} + +/** + * polyfill for PHP < 8 + * @see https://www.php.net/manual/en/function.str-contains + */ +if (!function_exists('str_contains')) { + function str_contains(string $haystack, string $needle) + { + return empty($needle) || strpos($haystack, $needle) !== false; + } +} + +/** + * polyfill for PHP < 8 + * @see https://www.php.net/manual/en/function.str-ends-with + */ +if (!function_exists('str_ends_with')) { + function str_ends_with(string $haystack, string $needle) + { + return empty($needle) || substr($haystack, -strlen($needle)) === $needle; + } +} diff --git a/inc/config_cascade.php b/inc/config_cascade.php index 61d099c6e..f723adabe 100644 --- a/inc/config_cascade.php +++ b/inc/config_cascade.php @@ -1,91 +1,89 @@ <?php + /** * The default config cascade * * This array configures the default locations of various files in the * DokuWiki directory hierarchy. It can be overriden in inc/preload.php */ + $config_cascade = array_merge( - array( - 'main' => array( - 'default' => array(DOKU_CONF . 'dokuwiki.php'), - 'local' => array(DOKU_CONF . 'local.php'), - 'protected' => array(DOKU_CONF . 'local.protected.php'), - ), - 'acronyms' => array( - 'default' => array(DOKU_CONF . 'acronyms.conf'), - 'local' => array(DOKU_CONF . 'acronyms.local.conf'), - ), - 'entities' => array( - 'default' => array(DOKU_CONF . 'entities.conf'), - 'local' => array(DOKU_CONF . 'entities.local.conf'), - ), - 'interwiki' => array( - 'default' => array(DOKU_CONF . 'interwiki.conf'), - 'local' => array(DOKU_CONF . 'interwiki.local.conf'), - ), - 'license' => array( - 'default' => array(DOKU_CONF . 'license.php'), - 'local' => array(DOKU_CONF . 'license.local.php'), - ), - 'manifest' => array( - 'default' => array(DOKU_CONF . 'manifest.json'), - 'local' => array(DOKU_CONF . 'manifest.local.json'), - ), - 'mediameta' => array( - 'default' => array(DOKU_CONF . 'mediameta.php'), - 'local' => array(DOKU_CONF . 'mediameta.local.php'), - ), - 'mime' => array( - 'default' => array(DOKU_CONF . 'mime.conf'), - 'local' => array(DOKU_CONF . 'mime.local.conf'), - ), - 'scheme' => array( - 'default' => array(DOKU_CONF . 'scheme.conf'), - 'local' => array(DOKU_CONF . 'scheme.local.conf'), - ), - 'smileys' => array( - 'default' => array(DOKU_CONF . 'smileys.conf'), - 'local' => array(DOKU_CONF . 'smileys.local.conf'), - ), - 'wordblock' => array( - 'default' => array(DOKU_CONF . 'wordblock.conf'), - 'local' => array(DOKU_CONF . 'wordblock.local.conf'), - ), - 'userstyle' => array( - 'screen' => array(DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less'), - 'print' => array(DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less'), - 'feed' => array(DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less'), - 'all' => array(DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less') - ), - 'userscript' => array( - 'default' => array(DOKU_CONF . 'userscript.js') - ), - 'styleini' => array( - 'default' => array(DOKU_INC . 'lib/tpl/%TEMPLATE%/' . 'style.ini'), - 'local' => array(DOKU_CONF . 'tpl/%TEMPLATE%/' . 'style.ini') - ), - 'acl' => array( - 'default' => DOKU_CONF . 'acl.auth.php', - ), - 'plainauth.users' => array( - 'default' => DOKU_CONF . 'users.auth.php', - 'protected' => '' // not used by default - ), - 'plugins' => array( - 'default' => array(DOKU_CONF . 'plugins.php'), - 'local' => array(DOKU_CONF . 'plugins.local.php'), - 'protected' => array( - DOKU_CONF . 'plugins.required.php', - DOKU_CONF . 'plugins.protected.php', - ), - ), - 'lang' => array( - 'core' => array(DOKU_CONF . 'lang/'), - 'plugin' => array(DOKU_CONF . 'plugin_lang/'), - 'template' => array(DOKU_CONF . 'template_lang/') - ) - ), + [ + 'main' => [ + 'default' => [DOKU_CONF . 'dokuwiki.php'], + 'local' => [DOKU_CONF . 'local.php'], + 'protected' => [DOKU_CONF . 'local.protected.php'] + ], + 'acronyms' => [ + 'default' => [DOKU_CONF . 'acronyms.conf'], + 'local' => [DOKU_CONF . 'acronyms.local.conf'] + ], + 'entities' => [ + 'default' => [DOKU_CONF . 'entities.conf'], + 'local' => [DOKU_CONF . 'entities.local.conf'] + ], + 'interwiki' => [ + 'default' => [DOKU_CONF . 'interwiki.conf'], + 'local' => [DOKU_CONF . 'interwiki.local.conf'] + ], + 'license' => [ + 'default' => [DOKU_CONF . 'license.php'], + 'local' => [DOKU_CONF . 'license.local.php'] + ], + 'manifest' => [ + 'default' => [DOKU_CONF . 'manifest.json'], + 'local' => [DOKU_CONF . 'manifest.local.json'] + ], + 'mediameta' => [ + 'default' => [DOKU_CONF . 'mediameta.php'], + 'local' => [DOKU_CONF . 'mediameta.local.php'] + ], + 'mime' => [ + 'default' => [DOKU_CONF . 'mime.conf'], + 'local' => [DOKU_CONF . 'mime.local.conf'] + ], + 'scheme' => [ + 'default' => [DOKU_CONF . 'scheme.conf'], + 'local' => [DOKU_CONF . 'scheme.local.conf'] + ], + 'smileys' => [ + 'default' => [DOKU_CONF . 'smileys.conf'], + 'local' => [DOKU_CONF . 'smileys.local.conf'] + ], + 'wordblock' => [ + 'default' => [DOKU_CONF . 'wordblock.conf'], + 'local' => [DOKU_CONF . 'wordblock.local.conf'] + ], + 'userstyle' => [ + 'screen' => [DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less'], + 'print' => [DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less'], + 'feed' => [DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less'], + 'all' => [DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less'] + ], + 'userscript' => [ + 'default' => [DOKU_CONF . 'userscript.js'] + ], + 'styleini' => [ + 'default' => [DOKU_INC . 'lib/tpl/%TEMPLATE%/' . 'style.ini'], + 'local' => [DOKU_CONF . 'tpl/%TEMPLATE%/' . 'style.ini'] + ], + 'acl' => [ + 'default' => DOKU_CONF . 'acl.auth.php' + ], + 'plainauth.users' => [ + 'default' => DOKU_CONF . 'users.auth.php', + 'protected' => '' + ], + 'plugins' => [ + 'default' => [DOKU_CONF . 'plugins.php'], + 'local' => [DOKU_CONF . 'plugins.local.php'], + 'protected' => [DOKU_CONF . 'plugins.required.php', DOKU_CONF . 'plugins.protected.php'] + ], + 'lang' => [ + 'core' => [DOKU_CONF . 'lang/'], + 'plugin' => [DOKU_CONF . 'plugin_lang/'], + 'template' => [DOKU_CONF . 'template_lang/'] + ] + ], $config_cascade ); - diff --git a/inc/confutils.php b/inc/confutils.php index c754a1aec..54909f02e 100644 --- a/inc/confutils.php +++ b/inc/confutils.php @@ -1,4 +1,5 @@ <?php + /** * Utilities for collecting data from config files * @@ -14,6 +15,7 @@ use dokuwiki\Extension\AuthPlugin; use dokuwiki\Extension\Event; + const DOKU_CONF_NEGATION = '!'; /** @@ -28,24 +30,25 @@ const DOKU_CONF_NEGATION = '!'; * @param bool $knownonly * @return array with extension, mimetype and if it should be downloaded */ -function mimetype($file, $knownonly=true){ +function mimetype($file, $knownonly = true) +{ $mtypes = getMimeTypes(); // known mimetypes $ext = strrpos($file, '.'); if ($ext === false) { - return array(false, false, false); + return [false, false, false]; } $ext = strtolower(substr($file, $ext + 1)); - if (!isset($mtypes[$ext])){ + if (!isset($mtypes[$ext])) { if ($knownonly) { - return array(false, false, false); + return [false, false, false]; } else { - return array($ext, 'application/octet-stream', true); + return [$ext, 'application/octet-stream', true]; } } - if($mtypes[$ext][0] == '!'){ - return array($ext, substr($mtypes[$ext],1), true); - }else{ - return array($ext, $mtypes[$ext], false); + if ($mtypes[$ext][0] == '!') { + return [$ext, substr($mtypes[$ext], 1), true]; + } else { + return [$ext, $mtypes[$ext], false]; } } @@ -54,10 +57,11 @@ function mimetype($file, $knownonly=true){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function getMimeTypes() { +function getMimeTypes() +{ static $mime = null; - if ( !$mime ) { - $mime = retrieveConfig('mime','confToHash'); + if (!$mime) { + $mime = retrieveConfig('mime', 'confToHash'); $mime = array_filter($mime); } return $mime; @@ -68,10 +72,11 @@ function getMimeTypes() { * * @author Harry Fuecks <hfuecks@gmail.com> */ -function getAcronyms() { +function getAcronyms() +{ static $acronyms = null; - if ( !$acronyms ) { - $acronyms = retrieveConfig('acronyms','confToHash'); + if (!$acronyms) { + $acronyms = retrieveConfig('acronyms', 'confToHash'); $acronyms = array_filter($acronyms, 'strlen'); } return $acronyms; @@ -82,10 +87,11 @@ function getAcronyms() { * * @author Harry Fuecks <hfuecks@gmail.com> */ -function getSmileys() { +function getSmileys() +{ static $smileys = null; - if ( !$smileys ) { - $smileys = retrieveConfig('smileys','confToHash'); + if (!$smileys) { + $smileys = retrieveConfig('smileys', 'confToHash'); $smileys = array_filter($smileys, 'strlen'); } return $smileys; @@ -96,10 +102,11 @@ function getSmileys() { * * @author Harry Fuecks <hfuecks@gmail.com> */ -function getEntities() { +function getEntities() +{ static $entities = null; - if ( !$entities ) { - $entities = retrieveConfig('entities','confToHash'); + if (!$entities) { + $entities = retrieveConfig('entities', 'confToHash'); $entities = array_filter($entities, 'strlen'); } return $entities; @@ -110,14 +117,15 @@ function getEntities() { * * @author Harry Fuecks <hfuecks@gmail.com> */ -function getInterwiki() { +function getInterwiki() +{ static $wikis = null; - if ( !$wikis ) { - $wikis = retrieveConfig('interwiki','confToHash',array(true)); + if (!$wikis) { + $wikis = retrieveConfig('interwiki', 'confToHash', [true]); $wikis = array_filter($wikis, 'strlen'); //add sepecial case 'this' - $wikis['this'] = DOKU_URL.'{NAME}'; + $wikis['this'] = DOKU_URL . '{NAME}'; } return $wikis; } @@ -128,35 +136,33 @@ function getInterwiki() { * @trigger CONFUTIL_CDN_SELECT * @return array */ -function getCdnUrls() { +function getCdnUrls() +{ global $conf; // load version info - $versions = array(); + $versions = []; $lines = file(DOKU_INC . 'lib/scripts/jquery/versions'); - foreach($lines as $line) { + foreach ($lines as $line) { $line = trim(preg_replace('/#.*$/', '', $line)); - if($line === '') continue; - list($key, $val) = sexplode('=', $line, 2, ''); + if ($line === '') continue; + [$key, $val] = sexplode('=', $line, 2, ''); $key = trim($key); $val = trim($val); $versions[$key] = $val; } - $src = array(); - $data = array( - 'versions' => $versions, - 'src' => &$src - ); + $src = []; + $data = ['versions' => $versions, 'src' => &$src]; $event = new Event('CONFUTIL_CDN_SELECT', $data); - if($event->advise_before()) { - if(!$conf['jquerycdn']) { - $jqmod = md5(join('-', $versions)); + if ($event->advise_before()) { + if (!$conf['jquerycdn']) { + $jqmod = md5(implode('-', $versions)); $src[] = DOKU_BASE . 'lib/exe/jquery.php' . '?tseed=' . $jqmod; - } elseif($conf['jquerycdn'] == 'jquery') { + } elseif ($conf['jquerycdn'] == 'jquery') { $src[] = sprintf('https://code.jquery.com/jquery-%s.min.js', $versions['JQ_VERSION']); $src[] = sprintf('https://code.jquery.com/ui/%s/jquery-ui.min.js', $versions['JQUI_VERSION']); - } elseif($conf['jquerycdn'] == 'cdnjs') { + } elseif ($conf['jquerycdn'] == 'cdnjs') { $src[] = sprintf( 'https://cdnjs.cloudflare.com/ajax/libs/jquery/%s/jquery.min.js', $versions['JQ_VERSION'] @@ -176,10 +182,11 @@ function getCdnUrls() { * returns array of wordblock patterns * */ -function getWordblocks() { +function getWordblocks() +{ static $wordblocks = null; - if ( !$wordblocks ) { - $wordblocks = retrieveConfig('wordblock','file',null,'array_merge_with_removal'); + if (!$wordblocks) { + $wordblocks = retrieveConfig('wordblock', 'file', null, 'array_merge_with_removal'); } return $wordblocks; } @@ -189,10 +196,11 @@ function getWordblocks() { * * @return array the schemes */ -function getSchemes() { +function getSchemes() +{ static $schemes = null; - if ( !$schemes ) { - $schemes = retrieveConfig('scheme','file',null,'array_merge_with_removal'); + if (!$schemes) { + $schemes = retrieveConfig('scheme', 'file', null, 'array_merge_with_removal'); $schemes = array_map('trim', $schemes); $schemes = preg_replace('/^#.*/', '', $schemes); $schemes = array_filter($schemes); @@ -215,21 +223,22 @@ function getSchemes() { * * @return array */ -function linesToHash($lines, $lower = false) { - $conf = array(); +function linesToHash($lines, $lower = false) +{ + $conf = []; // remove BOM - if(isset($lines[0]) && substr($lines[0], 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf)) + if (isset($lines[0]) && substr($lines[0], 0, 3) === pack('CCC', 0xef, 0xbb, 0xbf)) $lines[0] = substr($lines[0], 3); - foreach($lines as $line) { + foreach ($lines as $line) { //ignore comments (except escaped ones) $line = preg_replace('/(?<![&\\\\])#.*$/', '', $line); $line = str_replace('\\#', '#', $line); $line = trim($line); - if($line === '') continue; + if ($line === '') continue; $line = preg_split('/\s+/', $line, 2); $line = array_pad($line, 2, ''); // Build the associative array - if($lower) { + if ($lower) { $conf[strtolower($line[0])] = $line[1]; } else { $conf[$line[0]] = $line[1]; @@ -254,10 +263,11 @@ function linesToHash($lines, $lower = false) { * * @return array */ -function confToHash($file,$lower=false) { - $conf = array(); - $lines = @file( $file ); - if ( !$lines ) return $conf; +function confToHash($file, $lower = false) +{ + $conf = []; + $lines = @file($file); + if (!$lines) return $conf; return linesToHash($lines, $lower); } @@ -267,12 +277,13 @@ function confToHash($file,$lower=false) { * * @param string $file * @return array + * @throws JsonException */ function jsonToArray($file) { $json = file_get_contents($file); - $conf = json_decode($json, true); + $conf = json_decode($json, true, 512, JSON_THROW_ON_ERROR); if ($conf === null) { return []; @@ -296,18 +307,19 @@ function jsonToArray($file) * and returns an array of the merged configuration values. * @return array configuration values */ -function retrieveConfig($type,$fn,$params=null,$combine='array_merge') { +function retrieveConfig($type, $fn, $params = null, $combine = 'array_merge') +{ global $config_cascade; - if(!is_array($params)) $params = array(); + if (!is_array($params)) $params = []; - $combined = array(); - if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING); - foreach (array('default','local','protected') as $config_group) { + $combined = []; + if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "' . $type . '"', E_USER_WARNING); + foreach (['default', 'local', 'protected'] as $config_group) { if (empty($config_cascade[$type][$config_group])) continue; foreach ($config_cascade[$type][$config_group] as $file) { if (file_exists($file)) { - $config = call_user_func_array($fn,array_merge(array($file),$params)); + $config = call_user_func_array($fn, array_merge([$file], $params)); $combined = $combine($combined, $config); } } @@ -324,12 +336,13 @@ function retrieveConfig($type,$fn,$params=null,$combine='array_merge') { * @param string $type the configuration settings to be read, must correspond to a key/array in $config_cascade * @return array list of files, default before local before protected */ -function getConfigFiles($type) { +function getConfigFiles($type) +{ global $config_cascade; - $files = array(); + $files = []; - if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING); - foreach (array('default','local','protected') as $config_group) { + if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "' . $type . '"', E_USER_WARNING); + foreach (['default', 'local', 'protected'] as $config_group) { if (empty($config_cascade[$type][$config_group])) continue; $files = array_merge($files, $config_cascade[$type][$config_group]); } @@ -344,41 +357,48 @@ function getConfigFiles($type) { * @param string $action * @returns boolean true if enabled, false if disabled */ -function actionOK($action){ +function actionOK($action) +{ static $disabled = null; - if(is_null($disabled) || defined('SIMPLE_TEST')){ + if (is_null($disabled) || defined('SIMPLE_TEST')) { global $conf; /** @var AuthPlugin $auth */ global $auth; // prepare disabled actions array and handle legacy options - $disabled = explode(',',$conf['disableactions']); - $disabled = array_map('trim',$disabled); - if((isset($conf['openregister']) && !$conf['openregister']) || is_null($auth) || !$auth->canDo('addUser')) { + $disabled = explode(',', $conf['disableactions']); + $disabled = array_map('trim', $disabled); + if ( + (isset($conf['openregister']) && !$conf['openregister']) || !$auth instanceof AuthPlugin + || !$auth->canDo('addUser') + ) { $disabled[] = 'register'; } - if((isset($conf['resendpasswd']) && !$conf['resendpasswd']) || is_null($auth) || !$auth->canDo('modPass')) { + if ( + (isset($conf['resendpasswd']) && !$conf['resendpasswd']) || !$auth instanceof AuthPlugin + || !$auth->canDo('modPass') + ) { $disabled[] = 'resendpwd'; } - if((isset($conf['subscribers']) && !$conf['subscribers']) || is_null($auth)) { + if ((isset($conf['subscribers']) && !$conf['subscribers']) || !$auth instanceof AuthPlugin) { $disabled[] = 'subscribe'; } - if (is_null($auth) || !$auth->canDo('Profile')) { + if (!$auth instanceof AuthPlugin || !$auth->canDo('Profile')) { $disabled[] = 'profile'; } - if (is_null($auth) || !$auth->canDo('delUser')) { + if (!$auth instanceof AuthPlugin || !$auth->canDo('delUser')) { $disabled[] = 'profile_delete'; } - if (is_null($auth)) { + if (!$auth instanceof AuthPlugin) { $disabled[] = 'login'; } - if (is_null($auth) || !$auth->canDo('logout')) { + if (!$auth instanceof AuthPlugin || !$auth->canDo('logout')) { $disabled[] = 'logout'; } $disabled = array_unique($disabled); } - return !in_array($action,$disabled); + return !in_array($action, $disabled); } /** @@ -390,9 +410,10 @@ function actionOK($action){ * navigation applies to all other links * @return boolean true if headings should be used for $linktype, false otherwise */ -function useHeading($linktype) { +function useHeading($linktype) +{ static $useHeading = null; - if(defined('DOKU_UNITTEST')) $useHeading = null; // don't cache during unit tests + if (defined('DOKU_UNITTEST')) $useHeading = null; // don't cache during unit tests if (is_null($useHeading)) { global $conf; @@ -411,7 +432,7 @@ function useHeading($linktype) { $useHeading['navigation'] = true; } } else { - $useHeading = array(); + $useHeading = []; } } @@ -425,13 +446,16 @@ function useHeading($linktype) { * @param string $code encoding method, values: plain, base64, uuencode. * @return string the encoded value */ -function conf_encodeString($str,$code) { +function conf_encodeString($str, $code) +{ switch ($code) { - case 'base64' : return '<b>'.base64_encode($str); - case 'uuencode' : return '<u>'.convert_uuencode($str); + case 'base64': + return '<b>' . base64_encode($str); + case 'uuencode': + return '<u>' . convert_uuencode($str); case 'plain': default: - return $str; + return $str; } } /** @@ -440,12 +464,15 @@ function conf_encodeString($str,$code) { * @param string $str encoded data * @return string plain text */ -function conf_decodeString($str) { - switch (substr($str,0,3)) { - case '<b>' : return base64_decode(substr($str,3)); - case '<u>' : return convert_uudecode(substr($str,3)); +function conf_decodeString($str) +{ + switch (substr($str, 0, 3)) { + case '<b>': + return base64_decode(substr($str, 3)); + case '<u>': + return convert_uudecode(substr($str, 3)); default: // not encoded (or unknown) - return $str; + return $str; } } @@ -457,10 +484,11 @@ function conf_decodeString($str) { * * @return array the combined array, numeric keys reset */ -function array_merge_with_removal($current, $new) { +function array_merge_with_removal($current, $new) +{ foreach ($new as $val) { - if (substr($val,0,1) == DOKU_CONF_NEGATION) { - $idx = array_search(trim(substr($val,1)),$current); + if (substr($val, 0, 1) == DOKU_CONF_NEGATION) { + $idx = array_search(trim(substr($val, 1)), $current); if ($idx !== false) { unset($current[$idx]); } @@ -469,6 +497,6 @@ function array_merge_with_removal($current, $new) { } } - return array_slice($current,0); + return array_slice($current, 0); } //Setup VIM: ex: et ts=4 : diff --git a/inc/deprecated.php b/inc/deprecated.php index 31a023293..9d49392ed 100644 --- a/inc/deprecated.php +++ b/inc/deprecated.php @@ -2,6 +2,8 @@ // phpcs:ignoreFile -- this file violates PSR2 by definition /** * These classes and functions are deprecated and will be removed in future releases + * + * Note: when adding to this file, please also add appropriate actions to _test/rector.php */ use dokuwiki\Debug\DebugHelper; @@ -720,3 +722,19 @@ class IXR_Value extends \IXR\DataType\Value } } +/** + * print a newline terminated string + * + * You can give an indention as optional parameter + * + * @author Andreas Gohr <andi@splitbrain.org> + * + * @param string $string line of text + * @param int $indent number of spaces indention + * @deprecated 2023-08-31 use echo instead + */ +function ptln($string, $indent = 0) +{ + DebugHelper::dbgDeprecatedFunction('echo'); + echo str_repeat(' ', $indent) . "$string\n"; +} diff --git a/inc/farm.php b/inc/farm.php index 08f6fdc29..fd1e2e123 100644 --- a/inc/farm.php +++ b/inc/farm.php @@ -1,4 +1,5 @@ <?php + /** * This overwrites DOKU_CONF. Each animal gets its own configuration and data directory. * This can be used together with preload.php. See preload.php.dist for an example setup. @@ -23,10 +24,9 @@ */ // DOKU_FARMDIR needs to be set in preload.php, the fallback is the same as DOKU_INC would be (if it was set already) -if(!defined('DOKU_FARMDIR')) define('DOKU_FARMDIR', fullpath(dirname(__FILE__).'/../').'/'); -if(!defined('DOKU_CONF')) define('DOKU_CONF', farm_confpath(DOKU_FARMDIR)); -if(!defined('DOKU_FARM')) define('DOKU_FARM', false); - +if (!defined('DOKU_FARMDIR')) define('DOKU_FARMDIR', fullpath(__DIR__ . '/../') . '/'); +if (!defined('DOKU_CONF')) define('DOKU_CONF', farm_confpath(DOKU_FARMDIR)); +if (!defined('DOKU_FARM')) define('DOKU_FARM', false); /** * Find the appropriate configuration directory. @@ -43,14 +43,15 @@ if(!defined('DOKU_FARM')) define('DOKU_FARM', false); * * @return string */ -function farm_confpath($farm) { +function farm_confpath($farm) +{ // htaccess based or cli // cli usage example: animal=your_animal bin/indexer.php - if(isset($_GET['animal']) || ('cli' == php_sapi_name() && isset($_SERVER['animal']))) { + if (isset($_GET['animal']) || ('cli' == PHP_SAPI && isset($_SERVER['animal']))) { $mode = isset($_GET['animal']) ? 'htaccess' : 'cli'; $animal = $mode == 'htaccess' ? $_GET['animal'] : $_SERVER['animal']; - if(isset($_GET['animal'])) { + if (isset($_GET['animal'])) { // now unset the parameter to not leak into new queries // code by @splitbrain from farmer plugin unset($_GET['animal']); @@ -62,98 +63,96 @@ function farm_confpath($farm) { // check that $animal is a string and just a directory name and not a path if (!is_string($animal) || strpbrk($animal, '\\/') !== false) nice_die('Sorry! Invalid animal name!'); - if(!is_dir($farm.'/'.$animal)) + if (!is_dir($farm . '/' . $animal)) nice_die("Sorry! This Wiki doesn't exist!"); - if(!defined('DOKU_FARM')) define('DOKU_FARM', $mode); - return $farm.'/'.$animal.'/conf/'; + if (!defined('DOKU_FARM')) define('DOKU_FARM', $mode); + return $farm . '/' . $animal . '/conf/'; } // virtual host based - $uri = explode('/', $_SERVER['SCRIPT_NAME'] ? $_SERVER['SCRIPT_NAME'] : $_SERVER['SCRIPT_FILENAME']); + $uri = explode('/', $_SERVER['SCRIPT_NAME'] ?: $_SERVER['SCRIPT_FILENAME']); $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.'))))); for ($i = count($uri) - 1; $i > 0; $i--) { for ($j = count($server); $j > 0; $j--) { $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i)); - if(is_dir("$farm/$dir/conf/")) { - if(!defined('DOKU_FARM')) define('DOKU_FARM', 'virtual'); + if (is_dir("$farm/$dir/conf/")) { + if (!defined('DOKU_FARM')) define('DOKU_FARM', 'virtual'); return "$farm/$dir/conf/"; } } } // default conf directory in farm - if(is_dir("$farm/default/conf/")) { - if(!defined('DOKU_FARM')) define('DOKU_FARM', 'default'); + if (is_dir("$farm/default/conf/")) { + if (!defined('DOKU_FARM')) define('DOKU_FARM', 'default'); return "$farm/default/conf/"; } // farmer - return DOKU_INC.'conf/'; + return DOKU_INC . 'conf/'; } /* Use default config files and local animal config files */ -$config_cascade = array( - 'main' => array( - 'default' => array(DOKU_INC.'conf/dokuwiki.php'), - 'local' => array(DOKU_CONF.'local.php'), - 'protected' => array(DOKU_CONF.'local.protected.php'), - ), - 'acronyms' => array( - 'default' => array(DOKU_INC.'conf/acronyms.conf'), - 'local' => array(DOKU_CONF.'acronyms.local.conf'), - ), - 'entities' => array( - 'default' => array(DOKU_INC.'conf/entities.conf'), - 'local' => array(DOKU_CONF.'entities.local.conf'), - ), - 'interwiki' => array( - 'default' => array(DOKU_INC.'conf/interwiki.conf'), - 'local' => array(DOKU_CONF.'interwiki.local.conf'), - ), - 'license' => array( - 'default' => array(DOKU_INC.'conf/license.php'), - 'local' => array(DOKU_CONF.'license.local.php'), - ), - 'mediameta' => array( - 'default' => array(DOKU_INC.'conf/mediameta.php'), - 'local' => array(DOKU_CONF.'mediameta.local.php'), - ), - 'mime' => array( - 'default' => array(DOKU_INC.'conf/mime.conf'), - 'local' => array(DOKU_CONF.'mime.local.conf'), - ), - 'scheme' => array( - 'default' => array(DOKU_INC.'conf/scheme.conf'), - 'local' => array(DOKU_CONF.'scheme.local.conf'), - ), - 'smileys' => array( - 'default' => array(DOKU_INC.'conf/smileys.conf'), - 'local' => array(DOKU_CONF.'smileys.local.conf'), - ), - 'wordblock' => array( - 'default' => array(DOKU_INC.'conf/wordblock.conf'), - 'local' => array(DOKU_CONF.'wordblock.local.conf'), - ), - 'acl' => array( - 'default' => DOKU_CONF.'acl.auth.php', - ), - 'plainauth.users' => array( - 'default' => DOKU_CONF.'users.auth.php', - ), - 'plugins' => array( // needed since Angua - 'default' => array(DOKU_INC.'conf/plugins.php'), - 'local' => array(DOKU_CONF.'plugins.local.php'), - 'protected' => array( - DOKU_INC.'conf/plugins.required.php', - DOKU_CONF.'plugins.protected.php', - ), - ), - 'userstyle' => array( - 'screen' => array(DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less'), - 'print' => array(DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less'), - 'feed' => array(DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less'), - 'all' => array(DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less') - ), - 'userscript' => array( - 'default' => array(DOKU_CONF . 'userscript.js') - ), -); +$config_cascade = [ + 'main' => [ + 'default' => [DOKU_INC . 'conf/dokuwiki.php'], + 'local' => [DOKU_CONF . 'local.php'], + 'protected' => [DOKU_CONF . 'local.protected.php'] + ], + 'acronyms' => [ + 'default' => [DOKU_INC . 'conf/acronyms.conf'], + 'local' => [DOKU_CONF . 'acronyms.local.conf'] + ], + 'entities' => [ + 'default' => [DOKU_INC . 'conf/entities.conf'], + 'local' => [DOKU_CONF . 'entities.local.conf'] + ], + 'interwiki' => [ + 'default' => [DOKU_INC . 'conf/interwiki.conf'], + 'local' => [DOKU_CONF . 'interwiki.local.conf'] + ], + 'license' => [ + 'default' => [DOKU_INC . 'conf/license.php'], + 'local' => [DOKU_CONF . 'license.local.php'] + ], + 'mediameta' => [ + 'default' => [DOKU_INC . 'conf/mediameta.php'], + 'local' => [DOKU_CONF . 'mediameta.local.php'] + ], + 'mime' => [ + 'default' => [DOKU_INC . 'conf/mime.conf'], + 'local' => [DOKU_CONF . 'mime.local.conf'] + ], + 'scheme' => [ + 'default' => [DOKU_INC . 'conf/scheme.conf'], + 'local' => [DOKU_CONF . 'scheme.local.conf'] + ], + 'smileys' => [ + 'default' => [DOKU_INC . 'conf/smileys.conf'], + 'local' => [DOKU_CONF . 'smileys.local.conf'] + ], + 'wordblock' => [ + 'default' => [DOKU_INC . 'conf/wordblock.conf'], + 'local' => [DOKU_CONF . 'wordblock.local.conf'] + ], + 'acl' => [ + 'default' => DOKU_CONF . 'acl.auth.php' + ], + 'plainauth.users' => [ + 'default' => DOKU_CONF . 'users.auth.php' + ], + 'plugins' => [ + // needed since Angua + 'default' => [DOKU_INC . 'conf/plugins.php'], + 'local' => [DOKU_CONF . 'plugins.local.php'], + 'protected' => [DOKU_INC . 'conf/plugins.required.php', DOKU_CONF . 'plugins.protected.php'], + ], + 'userstyle' => [ + 'screen' => [DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less'], + 'print' => [DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less'], + 'feed' => [DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less'], + 'all' => [DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less'] + ], + 'userscript' => [ + 'default' => [DOKU_CONF . 'userscript.js'] + ] +]; diff --git a/inc/fetch.functions.php b/inc/fetch.functions.php index d1b15633b..a911bb944 100644 --- a/inc/fetch.functions.php +++ b/inc/fetch.functions.php @@ -1,4 +1,8 @@ <?php + +use dokuwiki\HTTP\Headers; +use dokuwiki\Utf8\PhpString; + /** * Functions used by lib/exe/fetch.php * (not included by other parts of dokuwiki) @@ -25,19 +29,20 @@ * @author Gerry Weissbach <dokuwiki@gammaproduction.de> * */ -function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null, $csp=[]) { +function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null, $csp = []) +{ global $conf; // send mime headers header("Content-Type: $mime"); // send security policy if given - if (!empty($csp)) dokuwiki\HTTP\Headers::contentSecurityPolicy($csp); + if (!empty($csp)) Headers::contentSecurityPolicy($csp); // calculate cache times - if($cache == -1) { + if ($cache == -1) { $maxage = max($conf['cachetime'], 3600); // cachetime or one hour $expires = time() + $maxage; - } else if($cache > 0) { + } elseif ($cache > 0) { $maxage = $cache; // given time $expires = time() + $maxage; } else { // $cache == 0 @@ -46,15 +51,15 @@ function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null, $csp } // smart http caching headers - if($maxage) { - if($public) { + if ($maxage) { + if ($public) { // cache publically - header('Expires: '.gmdate("D, d M Y H:i:s", $expires).' GMT'); - header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.$maxage); + header('Expires: ' . gmdate("D, d M Y H:i:s", $expires) . ' GMT'); + header('Cache-Control: public, proxy-revalidate, no-transform, max-age=' . $maxage); } else { // cache in browser - header('Expires: '.gmdate("D, d M Y H:i:s", $expires).' GMT'); - header('Cache-Control: private, no-transform, max-age='.$maxage); + header('Expires: ' . gmdate("D, d M Y H:i:s", $expires) . ' GMT'); + header('Cache-Control: private, no-transform, max-age=' . $maxage); } } else { // no cache at all @@ -67,19 +72,21 @@ function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null, $csp http_conditionalRequest($fmtime); // Use the current $file if is $orig is not set. - if ( $orig == null ) { + if ($orig == null) { $orig = $file; } //download or display? if ($dl) { header('Content-Disposition: attachment;' . rfc2231_encode( - 'filename', \dokuwiki\Utf8\PhpString::basename($orig)) . ';' - ); + 'filename', + PhpString::basename($orig) + ) . ';'); } else { header('Content-Disposition: inline;' . rfc2231_encode( - 'filename', \dokuwiki\Utf8\PhpString::basename($orig)) . ';' - ); + 'filename', + PhpString::basename($orig) + ) . ';'); } //use x-sendfile header to pass the delivery to compatible webservers @@ -87,11 +94,11 @@ function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null, $csp // send file contents $fp = @fopen($file, "rb"); - if($fp) { + if ($fp) { http_rangeRequest($fp, filesize($file), $mime); } else { http_status(500); - print "Could not read $file - bad permissions?"; + echo "Could not read $file - bad permissions?"; } } @@ -111,18 +118,17 @@ function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null, $csp * @return string in the format " name=value" for values WITHOUT special characters * @return string in the format " name*=charset'lang'value" for values WITH special characters */ -function rfc2231_encode($name, $value, $charset='utf-8', $lang='en') { +function rfc2231_encode($name, $value, $charset = 'utf-8', $lang = 'en') +{ $internal = preg_replace_callback( '/[\x00-\x20*\'%()<>@,;:\\\\"\/[\]?=\x80-\xFF]/', - function ($match) { - return rawurlencode($match[0]); - }, + static fn($match) => rawurlencode($match[0]), $value ); - if ( $value != $internal ) { - return ' '.$name.'*='.$charset."'".$lang."'".$internal; + if ($value != $internal) { + return ' ' . $name . '*=' . $charset . "'" . $lang . "'" . $internal; } else { - return ' '.$name.'="'.$value.'"'; + return ' ' . $name . '="' . $value . '"'; } } @@ -141,44 +147,45 @@ function rfc2231_encode($name, $value, $charset='utf-8', $lang='en') { * @param int $height * @return array as array(STATUS, STATUSMESSAGE) */ -function checkFileStatus(&$media, &$file, $rev = '', $width=0, $height=0) { +function checkFileStatus(&$media, &$file, $rev = '', $width = 0, $height = 0) +{ global $MIME, $EXT, $CACHE, $INPUT; //media to local file - if(media_isexternal($media)) { + if (media_isexternal($media)) { //check token for external image and additional for resized and cached images - if(media_get_token($media, $width, $height) !== $INPUT->str('tok')) { - return array(412, 'Precondition Failed'); + if (media_get_token($media, $width, $height) !== $INPUT->str('tok')) { + return [412, 'Precondition Failed']; } //handle external images - if(strncmp($MIME, 'image/', 6) == 0) $file = media_get_from_URL($media, $EXT, $CACHE); - if(!$file) { + if (strncmp($MIME, 'image/', 6) == 0) $file = media_get_from_URL($media, $EXT, $CACHE); + if (!$file) { //download failed - redirect to original URL - return array(302, $media); + return [302, $media]; } } else { $media = cleanID($media); - if(empty($media)) { - return array(400, 'Bad request'); + if (empty($media)) { + return [400, 'Bad request']; } // check token for resized images if (($width || $height) && media_get_token($media, $width, $height) !== $INPUT->str('tok')) { - return array(412, 'Precondition Failed'); + return [412, 'Precondition Failed']; } //check permissions (namespace only) - if(auth_quickaclcheck(getNS($media).':X') < AUTH_READ) { - return array(403, 'Forbidden'); + if (auth_quickaclcheck(getNS($media) . ':X') < AUTH_READ) { + return [403, 'Forbidden']; } $file = mediaFN($media, $rev); } //check file existance - if(!file_exists($file)) { - return array(404, 'Not Found'); + if (!file_exists($file)) { + return [404, 'Not Found']; } - return array(200, null); + return [200, null]; } /** @@ -191,10 +198,11 @@ function checkFileStatus(&$media, &$file, $rev = '', $width=0, $height=0) { * @param string $cache * @return int cachetime in seconds */ -function calc_cache($cache) { +function calc_cache($cache) +{ global $conf; - if(strtolower($cache) == 'nocache') return 0; //never cache - if(strtolower($cache) == 'recache') return $conf['cachetime']; //use standard cache + if (strtolower($cache) == 'nocache') return 0; //never cache + if (strtolower($cache) == 'recache') return $conf['cachetime']; //use standard cache return -1; //cache endless } diff --git a/inc/form.php b/inc/form.php index e93be0f27..670d20470 100644 --- a/inc/form.php +++ b/inc/form.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki XHTML Form * @@ -62,7 +63,7 @@ class Doku_Form * * @author Tom N Harris <tnharris@whoopdedo.org> */ - public function __construct($params, $action=false, $method=false, $enctype=false) + public function __construct($params, $action = false, $method = false, $enctype = false) { if (!is_array($params)) { $this->params = array('id' => $params); @@ -99,9 +100,9 @@ class Doku_Form public function startFieldset($legend) { if ($this->_infieldset) { - $this->addElement(array('_elem'=>'closefieldset')); + $this->addElement(array('_elem' => 'closefieldset')); } - $this->addElement(array('_elem'=>'openfieldset', '_legend'=>$legend)); + $this->addElement(array('_elem' => 'openfieldset', '_legend' => $legend)); $this->_infieldset = true; } @@ -113,7 +114,7 @@ class Doku_Form public function endFieldset() { if ($this->_infieldset) { - $this->addElement(array('_elem'=>'closefieldset')); + $this->addElement(array('_elem' => 'closefieldset')); } $this->_infieldset = false; } @@ -134,8 +135,7 @@ class Doku_Form { if (is_null($value)) unset($this->_hidden[$name]); - else - $this->_hidden[$name] = $value; + else $this->_hidden[$name] = $value; } /** @@ -279,23 +279,23 @@ class Doku_Form global $lang; $form = ''; $this->params['accept-charset'] = $lang['encoding']; - $form .= '<form '. buildAttributes($this->params,false) .'><div class="no">'. DOKU_LF; + $form .= '<form ' . buildAttributes($this->params, false) . '><div class="no">' . DOKU_LF; if (!empty($this->_hidden)) { foreach ($this->_hidden as $name => $value) - $form .= form_hidden(array('name'=>$name, 'value'=>$value)); + $form .= form_hidden(array('name' => $name, 'value' => $value)); } foreach ($this->_content as $element) { if (is_array($element)) { $elem_type = $element['_elem']; - if (function_exists('form_'.$elem_type)) { - $form .= call_user_func('form_'.$elem_type, $element).DOKU_LF; + if (function_exists('form_' . $elem_type)) { + $form .= call_user_func('form_' . $elem_type, $element) . DOKU_LF; } } else { $form .= $element; } } - if ($this->_infieldset) $form .= form_closefieldset().DOKU_LF; - $form .= '</div></form>'.DOKU_LF; + if ($this->_infieldset) $form .= form_closefieldset() . DOKU_LF; + $form .= '</div></form>' . DOKU_LF; return $form; } @@ -327,12 +327,11 @@ class Doku_Form global $INPUT; $value = (array_key_exists($INPUT->post->str($name), $entries)) ? $INPUT->str($name) : key($entries); - foreach($entries as $val => $cap) { + foreach ($entries as $val => $cap) { $data = ($value === $val) ? array('checked' => 'checked') : array(); $this->addElement(form_makeRadioField($name, $val, $cap, '', '', $data)); } } - } /** @@ -346,8 +345,9 @@ class Doku_Form * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function form_makeTag($tag, $attrs=array()) { - $elem = array('_elem'=>'tag', '_tag'=>$tag); +function form_makeTag($tag, $attrs = array()) +{ + $elem = array('_elem' => 'tag', '_tag' => $tag); return array_merge($elem, $attrs); } @@ -363,8 +363,9 @@ function form_makeTag($tag, $attrs=array()) { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function form_makeOpenTag($tag, $attrs=array()) { - $elem = array('_elem'=>'opentag', '_tag'=>$tag); +function form_makeOpenTag($tag, $attrs = array()) +{ + $elem = array('_elem' => 'opentag', '_tag' => $tag); return array_merge($elem, $attrs); } @@ -379,8 +380,9 @@ function form_makeOpenTag($tag, $attrs=array()) { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function form_makeCloseTag($tag) { - return array('_elem'=>'closetag', '_tag'=>$tag); +function form_makeCloseTag($tag) +{ + return array('_elem' => 'closetag', '_tag' => $tag); } /** @@ -397,9 +399,10 @@ function form_makeCloseTag($tag) { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function form_makeWikiText($text, $attrs=array()) { - $elem = array('_elem'=>'wikitext', '_text'=>$text, - 'class'=>'edit', 'cols'=>'80', 'rows'=>'10'); +function form_makeWikiText($text, $attrs = array()) +{ + $elem = array('_elem' => 'wikitext', '_text' => $text, + 'class' => 'edit', 'cols' => '80', 'rows' => '10'); return array_merge($elem, $attrs); } @@ -418,12 +421,13 @@ function form_makeWikiText($text, $attrs=array()) { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function form_makeButton($type, $act, $value='', $attrs=array()) { +function form_makeButton($type, $act, $value = '', $attrs = array()) +{ if ($value == '') $value = $act; - $elem = array('_elem'=>'button', 'type'=>$type, '_action'=>$act, - 'value'=>$value); + $elem = array('_elem' => 'button', 'type' => $type, '_action' => $act, + 'value' => $value); if (!empty($attrs['accesskey']) && empty($attrs['title'])) { - $attrs['title'] = $value .' ['. strtoupper($attrs['accesskey']) .']'; + $attrs['title'] = $value . ' [' . strtoupper($attrs['accesskey']) . ']'; } return array_merge($elem, $attrs); } @@ -447,10 +451,11 @@ function form_makeButton($type, $act, $value='', $attrs=array()) { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function form_makeField($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) { +function form_makeField($type, $name, $value = '', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - $elem = array('_elem'=>'field', '_text'=>$label, '_class'=>$class, - 'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value); + $elem = array('_elem' => 'field', '_text' => $label, '_class' => $class, + 'type' => $type, 'id' => $id, 'name' => $name, 'value' => $value); return array_merge($elem, $attrs); } @@ -473,10 +478,11 @@ function form_makeField($type, $name, $value='', $label=null, $id='', $class='', * * @return array */ -function form_makeFieldRight($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) { +function form_makeFieldRight($type, $name, $value = '', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - $elem = array('_elem'=>'fieldright', '_text'=>$label, '_class'=>$class, - 'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value); + $elem = array('_elem' => 'fieldright', '_text' => $label, '_class' => $class, + 'type' => $type, 'id' => $id, 'name' => $name, 'value' => $value); return array_merge($elem, $attrs); } @@ -497,10 +503,11 @@ function form_makeFieldRight($type, $name, $value='', $label=null, $id='', $clas * * @return array */ -function form_makeTextField($name, $value='', $label=null, $id='', $class='', $attrs=array()) { +function form_makeTextField($name, $value = '', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - $elem = array('_elem'=>'textfield', '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name, 'value'=>$value, 'class'=>'edit'); + $elem = array('_elem' => 'textfield', '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name, 'value' => $value, 'class' => 'edit'); return array_merge($elem, $attrs); } @@ -521,10 +528,11 @@ function form_makeTextField($name, $value='', $label=null, $id='', $class='', $a * * @return array */ -function form_makePasswordField($name, $label=null, $id='', $class='', $attrs=array()) { +function form_makePasswordField($name, $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - $elem = array('_elem'=>'passwordfield', '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name, 'class'=>'edit'); + $elem = array('_elem' => 'passwordfield', '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name, 'class' => 'edit'); return array_merge($elem, $attrs); } @@ -544,10 +552,11 @@ function form_makePasswordField($name, $label=null, $id='', $class='', $attrs=ar * * @return array */ -function form_makeFileField($name, $label=null, $id='', $class='', $attrs=array()) { +function form_makeFileField($name, $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - $elem = array('_elem'=>'filefield', '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name, 'class'=>'edit'); + $elem = array('_elem' => 'filefield', '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name, 'class' => 'edit'); return array_merge($elem, $attrs); } @@ -570,11 +579,12 @@ function form_makeFileField($name, $label=null, $id='', $class='', $attrs=array( * * @return array */ -function form_makeCheckboxField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) { +function form_makeCheckboxField($name, $value = '1', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - if (is_null($value) || $value=='') $value='0'; - $elem = array('_elem'=>'checkboxfield', '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name, 'value'=>$value); + if (is_null($value) || $value == '') $value = '0'; + $elem = array('_elem' => 'checkboxfield', '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name, 'value' => $value); return array_merge($elem, $attrs); } @@ -595,11 +605,12 @@ function form_makeCheckboxField($name, $value='1', $label=null, $id='', $class=' * * @return array */ -function form_makeRadioField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) { +function form_makeRadioField($name, $value = '1', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; - if (is_null($value) || $value=='') $value='0'; - $elem = array('_elem'=>'radiofield', '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name, 'value'=>$value); + if (is_null($value) || $value == '') $value = '0'; + $elem = array('_elem' => 'radiofield', '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name, 'value' => $value); return array_merge($elem, $attrs); } @@ -627,27 +638,27 @@ function form_makeRadioField($name, $value='1', $label=null, $id='', $class='', * @param array $attrs Optional attributes. * @return array pseudo-tag */ -function form_makeMenuField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) { +function form_makeMenuField($name, $values, $selected = '', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; $options = array(); reset($values); // FIXME: php doesn't know the difference between a string and an integer if (is_string(key($values))) { foreach ($values as $val => $text) { - $options[] = array($val, $text, (!is_null($selected) && $val==$selected)); + $options[] = array($val, $text, (!is_null($selected) && $val == $selected)); } } else { if (is_integer($selected)) $selected = $values[$selected]; foreach ($values as $val) { if (is_array($val)) @list($val, $text) = $val; - else - $text = null; - $options[] = array($val, $text, $val===$selected); + else $text = null; + $options[] = array($val, $text, $val === $selected); } } - $elem = array('_elem'=>'menufield', '_options'=>$options, '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name); + $elem = array('_elem' => 'menufield', '_options' => $options, '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name); return array_merge($elem, $attrs); } @@ -673,7 +684,8 @@ function form_makeMenuField($name, $values, $selected='', $label=null, $id='', $ * @param array $attrs Optional attributes. * @return array pseudo-tag */ -function form_makeListboxField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) { +function form_makeListboxField($name, $values, $selected = '', $label = null, $id = '', $class = '', $attrs = array()) +{ if (is_null($label)) $label = $name; $options = array(); reset($values); @@ -685,7 +697,7 @@ function form_makeListboxField($name, $values, $selected='', $label=null, $id='' // FIXME: php doesn't know the difference between a string and an integer if (is_string(key($values))) { foreach ($values as $val => $text) { - $options[] = array($val, $text, in_array($val,$selected)); + $options[] = array($val, $text, in_array($val, $selected)); } } else { foreach ($values as $val) { @@ -698,8 +710,8 @@ function form_makeListboxField($name, $values, $selected='', $label=null, $id='' $options[] = array($val, $text, in_array($val, $selected), $disabled); } } - $elem = array('_elem'=>'listboxfield', '_options'=>$options, '_text'=>$label, '_class'=>$class, - 'id'=>$id, 'name'=>$name); + $elem = array('_elem' => 'listboxfield', '_options' => $options, '_text' => $label, '_class' => $class, + 'id' => $id, 'name' => $name); return array_merge($elem, $attrs); } @@ -715,8 +727,9 @@ function form_makeListboxField($name, $values, $selected='', $label=null, $id='' * @param array $attrs attributes * @return string html of tag */ -function form_tag($attrs) { - return '<'.$attrs['_tag'].' '. buildAttributes($attrs,true) .'/>'; +function form_tag($attrs) +{ + return '<' . $attrs['_tag'] . ' ' . buildAttributes($attrs, true) . '/>'; } /** @@ -731,8 +744,9 @@ function form_tag($attrs) { * @param array $attrs attributes * @return string html of tag */ -function form_opentag($attrs) { - return '<'.$attrs['_tag'].' '. buildAttributes($attrs,true) .'>'; +function form_opentag($attrs) +{ + return '<' . $attrs['_tag'] . ' ' . buildAttributes($attrs, true) . '>'; } /** @@ -747,8 +761,9 @@ function form_opentag($attrs) { * @param array $attrs attributes * @return string html of tag */ -function form_closetag($attrs) { - return '</'.$attrs['_tag'].'>'; +function form_closetag($attrs) +{ + return '</' . $attrs['_tag'] . '>'; } /** @@ -763,9 +778,10 @@ function form_closetag($attrs) { * @param array $attrs attributes * @return string html */ -function form_openfieldset($attrs) { - $s = '<fieldset '. buildAttributes($attrs,true) .'>'; - if (!is_null($attrs['_legend'])) $s .= '<legend>'.$attrs['_legend'].'</legend>'; +function form_openfieldset($attrs) +{ + $s = '<fieldset ' . buildAttributes($attrs, true) . '>'; + if (!is_null($attrs['_legend'])) $s .= '<legend>' . $attrs['_legend'] . '</legend>'; return $s; } @@ -779,7 +795,8 @@ function form_openfieldset($attrs) { * * @return string html */ -function form_closefieldset() { +function form_closefieldset() +{ return '</fieldset>'; } @@ -795,8 +812,9 @@ function form_closefieldset() { * @param array $attrs attributes * @return string html */ -function form_hidden($attrs) { - return '<input type="hidden" name="'.$attrs['name'].'" value="'. formText($attrs['value']) .'" />'; +function form_hidden($attrs) +{ + return '<input type="hidden" name="' . $attrs['name'] . '" value="' . formText($attrs['value']) . '" />'; } /** @@ -811,14 +829,15 @@ function form_hidden($attrs) { * @param array $attrs attributes * @return string html */ -function form_wikitext($attrs) { +function form_wikitext($attrs) +{ // mandatory attributes unset($attrs['name']); unset($attrs['id']); return '<textarea name="wikitext" id="wiki__text" dir="auto" ' - . buildAttributes($attrs,true).'>'.DOKU_LF + . buildAttributes($attrs, true) . '>' . DOKU_LF . formText($attrs['_text']) - .'</textarea>'; + . '</textarea>'; } /** @@ -833,11 +852,12 @@ function form_wikitext($attrs) { * @param array $attrs attributes * @return string html */ -function form_button($attrs) { - $p = (!empty($attrs['_action'])) ? 'name="do['.$attrs['_action'].']" ' : ''; +function form_button($attrs) +{ + $p = (!empty($attrs['_action'])) ? 'name="do[' . $attrs['_action'] . ']" ' : ''; $value = $attrs['value']; unset($attrs['value']); - return '<button '.$p. buildAttributes($attrs,true) .'>'.$value.'</button>'; + return '<button ' . $p . buildAttributes($attrs, true) . '>' . $value . '</button>'; } /** @@ -853,12 +873,13 @@ function form_button($attrs) { * @param array $attrs attributes * @return string html */ -function form_field($attrs) { +function form_field($attrs) +{ $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><span>'.$attrs['_text'].'</span>'; - $s .= ' <input '. buildAttributes($attrs,true) .' /></label>'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><span>' . $attrs['_text'] . '</span>'; + $s .= ' <input ' . buildAttributes($attrs, true) . ' /></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -877,12 +898,13 @@ function form_field($attrs) { * @param array $attrs attributes * @return string html */ -function form_fieldright($attrs) { +function form_fieldright($attrs) +{ $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><input '. buildAttributes($attrs,true) .' />'; - $s .= ' <span>'.$attrs['_text'].'</span></label>'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><input ' . buildAttributes($attrs, true) . ' />'; + $s .= ' <span>' . $attrs['_text'] . '</span></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -901,14 +923,15 @@ function form_fieldright($attrs) { * @param array $attrs attributes * @return string html */ -function form_textfield($attrs) { +function form_textfield($attrs) +{ // mandatory attributes unset($attrs['type']); $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><span>'.$attrs['_text'].'</span> '; - $s .= '<input type="text" '. buildAttributes($attrs,true) .' /></label>'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><span>' . $attrs['_text'] . '</span> '; + $s .= '<input type="text" ' . buildAttributes($attrs, true) . ' /></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -927,14 +950,15 @@ function form_textfield($attrs) { * @param array $attrs attributes * @return string html */ -function form_passwordfield($attrs) { +function form_passwordfield($attrs) +{ // mandatory attributes unset($attrs['type']); $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><span>'.$attrs['_text'].'</span> '; - $s .= '<input type="password" '. buildAttributes($attrs,true) .' /></label>'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><span>' . $attrs['_text'] . '</span> '; + $s .= '<input type="password" ' . buildAttributes($attrs, true) . ' /></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -955,14 +979,15 @@ function form_passwordfield($attrs) { * @param array $attrs attributes * @return string html */ -function form_filefield($attrs) { +function form_filefield($attrs) +{ $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><span>'.$attrs['_text'].'</span> '; - $s .= '<input type="file" '. buildAttributes($attrs,true); - if (!empty($attrs['_maxlength'])) $s .= ' maxlength="'.$attrs['_maxlength'].'"'; - if (!empty($attrs['_accept'])) $s .= ' accept="'.$attrs['_accept'].'"'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><span>' . $attrs['_text'] . '</span> '; + $s .= '<input type="file" ' . buildAttributes($attrs, true); + if (!empty($attrs['_maxlength'])) $s .= ' maxlength="' . $attrs['_maxlength'] . '"'; + if (!empty($attrs['_accept'])) $s .= ' accept="' . $attrs['_accept'] . '"'; $s .= ' /></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; @@ -984,20 +1009,21 @@ function form_filefield($attrs) { * @param array $attrs attributes * @return string html */ -function form_checkboxfield($attrs) { +function form_checkboxfield($attrs) +{ // mandatory attributes unset($attrs['type']); $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; $s .= '>'; if (is_array($attrs['value'])) { - echo '<input type="hidden" name="'. hsc($attrs['name']) .'"' - .' value="'. hsc($attrs['value'][1]) .'" />'; + echo '<input type="hidden" name="' . hsc($attrs['name']) . '"' + . ' value="' . hsc($attrs['value'][1]) . '" />'; $attrs['value'] = $attrs['value'][0]; } - $s .= '<input type="checkbox" '. buildAttributes($attrs,true) .' />'; - $s .= ' <span>'.$attrs['_text'].'</span></label>'; + $s .= '<input type="checkbox" ' . buildAttributes($attrs, true) . ' />'; + $s .= ' <span>' . $attrs['_text'] . '</span></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -1016,14 +1042,15 @@ function form_checkboxfield($attrs) { * @param array $attrs attributes * @return string html */ -function form_radiofield($attrs) { +function form_radiofield($attrs) +{ // mandatory attributes unset($attrs['type']); $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><input type="radio" '. buildAttributes($attrs,true) .' />'; - $s .= ' <span>'.$attrs['_text'].'</span></label>'; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><input type="radio" ' . buildAttributes($attrs, true) . ' />'; + $s .= ' <span>' . $attrs['_text'] . '</span></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -1045,34 +1072,34 @@ function form_radiofield($attrs) { * @param array $attrs attributes * @return string html */ -function form_menufield($attrs) { +function form_menufield($attrs) +{ $attrs['size'] = '1'; $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><span>'.$attrs['_text'].'</span>'; - $s .= ' <select '. buildAttributes($attrs,true) .'>'.DOKU_LF; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><span>' . $attrs['_text'] . '</span>'; + $s .= ' <select ' . buildAttributes($attrs, true) . '>' . DOKU_LF; if (!empty($attrs['_options'])) { $selected = false; $cnt = count($attrs['_options']); - for($n=0; $n < $cnt; $n++){ + for ($n = 0; $n < $cnt; $n++) { @list($value,$text,$select) = $attrs['_options'][$n]; $p = ''; if (!is_null($text)) - $p .= ' value="'. formText($value) .'"'; - else - $text = $value; + $p .= ' value="' . formText($value) . '"'; + else $text = $value; if (!empty($select) && !$selected) { $p .= ' selected="selected"'; $selected = true; } - $s .= '<option'.$p.'>'. formText($text) .'</option>'; + $s .= '<option' . $p . '>' . formText($text) . '</option>'; } } else { $s .= '<option></option>'; } - $s .= DOKU_LF.'</select></label>'; + $s .= DOKU_LF . '</select></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; @@ -1093,26 +1120,27 @@ function form_menufield($attrs) { * @param array $attrs attributes * @return string html */ -function form_listboxfield($attrs) { +function form_listboxfield($attrs) +{ $s = '<label'; - if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"'; - if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"'; - $s .= '><span>'.$attrs['_text'].'</span> '; - $s .= '<select '. buildAttributes($attrs,true) .'>'.DOKU_LF; + if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"'; + if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"'; + $s .= '><span>' . $attrs['_text'] . '</span> '; + $s .= '<select ' . buildAttributes($attrs, true) . '>' . DOKU_LF; if (!empty($attrs['_options'])) { foreach ($attrs['_options'] as $opt) { @list($value, $text, $select, $disabled) = $opt; $p = ''; if (is_null($text)) $text = $value; - $p .= ' value="'. formText($value) .'"'; + $p .= ' value="' . formText($value) . '"'; if (!empty($select)) $p .= ' selected="selected"'; if ($disabled) $p .= ' disabled="disabled"'; - $s .= '<option'.$p.'>'. formText($text) .'</option>'; + $s .= '<option' . $p . '>' . formText($text) . '</option>'; } } else { $s .= '<option></option>'; } - $s .= DOKU_LF.'</select></label>'; + $s .= DOKU_LF . '</select></label>'; if (preg_match('/(^| )block($| )/', $attrs['_class'])) $s .= '<br />'; return $s; diff --git a/inc/fulltext.php b/inc/fulltext.php index fda2b0e5b..eb886e6e9 100644 --- a/inc/fulltext.php +++ b/inc/fulltext.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki fulltextsearch functions using the index * @@ -6,6 +7,8 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Utf8\Asian; +use dokuwiki\Search\Indexer; use dokuwiki\Extension\Event; use dokuwiki\Utf8\Clean; use dokuwiki\Utf8\PhpString; @@ -14,7 +17,7 @@ use dokuwiki\Utf8\Sort; /** * create snippets for the first few results only */ -if(!defined('FT_SNIPPET_NUMBER')) define('FT_SNIPPET_NUMBER',15); +if (!defined('FT_SNIPPET_NUMBER')) define('FT_SNIPPET_NUMBER', 15); /** * The fulltext search @@ -31,7 +34,8 @@ if(!defined('FT_SNIPPET_NUMBER')) define('FT_SNIPPET_NUMBER',15); * * @return array */ -function ft_pageSearch($query,&$highlight, $sort = null, $after = null, $before = null){ +function ft_pageSearch($query, &$highlight, $sort = null, $after = null, $before = null) +{ if ($sort === null) { $sort = 'hits'; @@ -56,33 +60,34 @@ function ft_pageSearch($query,&$highlight, $sort = null, $after = null, $before * @param array $data event data * @return array matching documents */ -function _ft_pageSearch(&$data) { +function _ft_pageSearch(&$data) +{ $Indexer = idx_get_indexer(); // parse the given query $q = ft_queryParser($Indexer, $data['query']); $data['highlight'] = $q['highlight']; - if (empty($q['parsed_ary'])) return array(); + if (empty($q['parsed_ary'])) return []; // lookup all words found in the query $lookup = $Indexer->lookup($q['words']); // get all pages in this dokuwiki site (!: includes nonexistent pages) - $pages_all = array(); + $pages_all = []; foreach ($Indexer->getPages() as $id) { $pages_all[$id] = 0; // base: 0 hit } // process the query - $stack = array(); + $stack = []; foreach ($q['parsed_ary'] as $token) { switch (substr($token, 0, 3)) { case 'W+:': case 'W-:': case 'W_:': // word $word = substr($token, 3); - if(isset($lookup[$word])) { + if (isset($lookup[$word])) { $stack[] = (array)$lookup[$word]; } break; @@ -93,14 +98,14 @@ function _ft_pageSearch(&$data) { // the end($stack) always points the pages that contain // all words in this phrase $pages = end($stack); - $pages_matched = array(); - foreach(array_keys($pages) as $id){ - $evdata = array( + $pages_matched = []; + foreach (array_keys($pages) as $id) { + $evdata = [ 'id' => $id, 'phrase' => $phrase, 'text' => rawWiki($id) - ); - $evt = new Event('FULLTEXT_PHRASE_MATCH',$evdata); + ]; + $evt = new Event('FULLTEXT_PHRASE_MATCH', $evdata); if ($evt->advise_before() && $evt->result !== true) { $text = PhpString::strtolower($evdata['text']); if (strpos($text, $phrase) !== false) { @@ -117,7 +122,7 @@ function _ft_pageSearch(&$data) { case 'N+:': case 'N-:': // namespace $ns = cleanID(substr($token, 3)) . ':'; - $pages_matched = array(); + $pages_matched = []; foreach (array_keys($pages_all) as $id) { if (strpos($id, $ns) === 0) { $pages_matched[$id] = 0; // namespace: always 0 hit @@ -126,22 +131,22 @@ function _ft_pageSearch(&$data) { $stack[] = $pages_matched; break; case 'AND': // and operation - list($pages1, $pages2) = array_splice($stack, -2); - $stack[] = ft_resultCombine(array($pages1, $pages2)); + [$pages1, $pages2] = array_splice($stack, -2); + $stack[] = ft_resultCombine([$pages1, $pages2]); break; case 'OR': // or operation - list($pages1, $pages2) = array_splice($stack, -2); - $stack[] = ft_resultUnite(array($pages1, $pages2)); + [$pages1, $pages2] = array_splice($stack, -2); + $stack[] = ft_resultUnite([$pages1, $pages2]); break; case 'NOT': // not operation (unary) $pages = array_pop($stack); - $stack[] = ft_resultComplement(array($pages_all, $pages)); + $stack[] = ft_resultComplement([$pages_all, $pages]); break; } } $docs = array_pop($stack); - if (empty($docs)) return array(); + if (empty($docs)) return []; // check: settings, acls, existence foreach (array_keys($docs) as $id) { @@ -172,16 +177,19 @@ function _ft_pageSearch(&$data) { * @param bool $ignore_perms Ignore the fact that pages are hidden or read-protected * @return array The pages that contain links to the given page */ -function ft_backlinks($id, $ignore_perms = false){ +function ft_backlinks($id, $ignore_perms = false) +{ $result = idx_get_indexer()->lookupKey('relation_references', $id); - if(!count($result)) return $result; + if ($result === []) return $result; // check ACL permissions - foreach(array_keys($result) as $idx){ - if(($ignore_perms !== true && ( + foreach (array_keys($result) as $idx) { + if ( + (!$ignore_perms && ( isHiddenPage($result[$idx]) || auth_quickaclcheck($result[$idx]) < AUTH_READ - )) || !page_exists($result[$idx], '', false)){ + )) || !page_exists($result[$idx], '', false) + ) { unset($result[$idx]); } } @@ -203,16 +211,19 @@ function ft_backlinks($id, $ignore_perms = false){ * @param bool $ignore_perms Ignore hidden pages and acls (optional, default: false) * @return array A list of pages that use the given media file */ -function ft_mediause($id, $ignore_perms = false){ +function ft_mediause($id, $ignore_perms = false) +{ $result = idx_get_indexer()->lookupKey('relation_media', $id); - if(!count($result)) return $result; + if ($result === []) return $result; // check ACL permissions - foreach(array_keys($result) as $idx){ - if(($ignore_perms !== true && ( + foreach (array_keys($result) as $idx) { + if ( + (!$ignore_perms && ( isHiddenPage($result[$idx]) || auth_quickaclcheck($result[$idx]) < AUTH_READ - )) || !page_exists($result[$idx], '', false)){ + )) || !page_exists($result[$idx], '', false) + ) { unset($result[$idx]); } } @@ -243,7 +254,8 @@ function ft_mediause($id, $ignore_perms = false){ * * @return string[] */ -function ft_pageLookup($id, $in_ns=false, $in_title=false, $after = null, $before = null){ +function ft_pageLookup($id, $in_ns = false, $in_title = false, $after = null, $before = null) +{ $data = [ 'id' => $id, 'in_ns' => $in_ns, @@ -261,7 +273,8 @@ function ft_pageLookup($id, $in_ns=false, $in_title=false, $after = null, $befor * @param array &$data event data * @return string[] */ -function _ft_pageLookup(&$data){ +function _ft_pageLookup(&$data) +{ // split out original parameters $id = $data['id']; $Indexer = idx_get_indexer(); @@ -282,7 +295,7 @@ function _ft_pageLookup(&$data){ $Indexer = idx_get_indexer(); $page_idx = $Indexer->getPages(); - $pages = array(); + $pages = []; if ($id !== '' && $cleaned !== '') { foreach ($page_idx as $p_id) { if ((strpos($in_ns ? $p_id : noNSorNS($p_id), $cleaned) !== false)) { @@ -316,16 +329,18 @@ function _ft_pageLookup(&$data){ // discard hidden pages // discard nonexistent pages // check ACL permissions - foreach(array_keys($pages) as $idx){ - if(!isVisiblePage($idx) || !page_exists($idx) || - auth_quickaclcheck($idx) < AUTH_READ) { + foreach (array_keys($pages) as $idx) { + if ( + !isVisiblePage($idx) || !page_exists($idx) || + auth_quickaclcheck($idx) < AUTH_READ + ) { unset($pages[$idx]); } } $pages = _ft_filterResultsByTime($pages, $data['after'], $data['before']); - uksort($pages,'ft_pagesorter'); + uksort($pages, 'ft_pagesorter'); return $pages; } @@ -337,12 +352,13 @@ function _ft_pageLookup(&$data){ * * @return array */ -function _ft_filterResultsByTime(array $results, $after, $before) { +function _ft_filterResultsByTime(array $results, $after, $before) +{ if ($after || $before) { $after = is_int($after) ? $after : strtotime($after); $before = is_int($before) ? $before : strtotime($before); - foreach ($results as $id => $value) { + foreach (array_keys($results) as $id) { $mTime = filemtime(wikiFN($id)); if ($after && $after > $mTime) { unset($results[$id]); @@ -366,7 +382,8 @@ function _ft_filterResultsByTime(array $results, $after, $before) { * @param string $title title from index * @return bool */ -function _ft_pageLookupTitleCompare($search, $title) { +function _ft_pageLookupTitleCompare($search, $title) +{ if (Clean::isASCII($search)) { $pos = stripos($title, $search); } else { @@ -388,15 +405,16 @@ function _ft_pageLookupTitleCompare($search, $title) { * @param string $b * @return int Returns < 0 if $a is less than $b; > 0 if $a is greater than $b, and 0 if they are equal. */ -function ft_pagesorter($a, $b){ - $ac = count(explode(':',$a)); - $bc = count(explode(':',$b)); - if($ac < $bc){ +function ft_pagesorter($a, $b) +{ + $ac = count(explode(':', $a)); + $bc = count(explode(':', $b)); + if ($ac < $bc) { return -1; - }elseif($ac > $bc){ + } elseif ($ac > $bc) { return 1; } - return Sort::strcmp($a,$b); + return Sort::strcmp($a, $b); } /** @@ -407,7 +425,8 @@ function ft_pagesorter($a, $b){ * * @return int Returns < 0 if $a is newer than $b, > 0 if $b is newer than $a and 0 if they are of the same age */ -function ft_pagemtimesorter($a, $b) { +function ft_pagemtimesorter($a, $b) +{ $mtimeA = filemtime(wikiFN($a)); $mtimeB = filemtime(wikiFN($b)); return $mtimeB - $mtimeA; @@ -423,26 +442,30 @@ function ft_pagemtimesorter($a, $b) { * @param array $highlight * @return mixed */ -function ft_snippet($id,$highlight){ +function ft_snippet($id, $highlight) +{ $text = rawWiki($id); - $text = str_replace("\xC2\xAD",'',$text); // remove soft-hyphens - $evdata = array( - 'id' => $id, - 'text' => &$text, - 'highlight' => &$highlight, - 'snippet' => '', - ); - - $evt = new Event('FULLTEXT_SNIPPET_CREATE',$evdata); + $text = str_replace("\xC2\xAD", '', $text); + // remove soft-hyphens + $evdata = [ + 'id' => $id, + 'text' => &$text, + 'highlight' => &$highlight, + 'snippet' => '' + ]; + + $evt = new Event('FULLTEXT_SNIPPET_CREATE', $evdata); if ($evt->advise_before()) { - $match = array(); - $snippets = array(); - $utf8_offset = $offset = $end = 0; + $match = []; + $snippets = []; + $utf8_offset = 0; + $offset = 0; + $end = 0; $len = PhpString::strlen($text); // build a regexp from the phrases to highlight $re1 = '(' . - join( + implode( '|', array_map( 'ft_snippet_re_preprocess', @@ -456,38 +479,39 @@ function ft_snippet($id,$highlight){ $re2 = "$re1.{0,75}(?!\\1)$re1"; $re3 = "$re1.{0,45}(?!\\1)$re1.{0,45}(?!\\1)(?!\\2)$re1"; - for ($cnt=4; $cnt--;) { + for ($cnt = 4; $cnt--;) { if (0) { - } else if (preg_match('/'.$re3.'/iu',$text,$match,PREG_OFFSET_CAPTURE,$offset)) { - } else if (preg_match('/'.$re2.'/iu',$text,$match,PREG_OFFSET_CAPTURE,$offset)) { - } else if (preg_match('/'.$re1.'/iu',$text,$match,PREG_OFFSET_CAPTURE,$offset)) { + } elseif (preg_match('/' . $re3 . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $offset)) { + } elseif (preg_match('/' . $re2 . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $offset)) { + } elseif (preg_match('/' . $re1 . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $offset)) { } else { break; } - list($str,$idx) = $match[0]; + [$str, $idx] = $match[0]; // convert $idx (a byte offset) into a utf8 character offset - $utf8_idx = PhpString::strlen(substr($text,0,$idx)); + $utf8_idx = PhpString::strlen(substr($text, 0, $idx)); $utf8_len = PhpString::strlen($str); // establish context, 100 bytes surrounding the match string // first look to see if we can go 100 either side, // then drop to 50 adding any excess if the other side can't go to 50, - $pre = min($utf8_idx-$utf8_offset,100); - $post = min($len-$utf8_idx-$utf8_len,100); - - if ($pre>50 && $post>50) { - $pre = $post = 50; - } else if ($pre>50) { - $pre = min($pre,100-$post); - } else if ($post>50) { - $post = min($post, 100-$pre); - } else if ($offset == 0) { + $pre = min($utf8_idx - $utf8_offset, 100); + $post = min($len - $utf8_idx - $utf8_len, 100); + + if ($pre > 50 && $post > 50) { + $pre = 50; + $post = 50; + } elseif ($pre > 50) { + $pre = min($pre, 100 - $post); + } elseif ($post > 50) { + $post = min($post, 100 - $pre); + } elseif ($offset == 0) { // both are less than 50, means the context is the whole string // make it so and break out of this loop - there is no need for the // complex snippet calculations - $snippets = array($text); + $snippets = [$text]; break; } @@ -498,9 +522,9 @@ function ft_snippet($id,$highlight){ $end = $utf8_idx + $utf8_len + $post; // now set it to the end of this context if ($append) { - $snippets[count($snippets)-1] .= PhpString::substr($text,$append,$end-$append); + $snippets[count($snippets) - 1] .= PhpString::substr($text, $append, $end - $append); } else { - $snippets[] = PhpString::substr($text,$start,$end-$start); + $snippets[] = PhpString::substr($text, $start, $end - $start); } // set $offset for next match attempt @@ -509,16 +533,16 @@ function ft_snippet($id,$highlight){ // this prevents further matching of this snippet but for possible matches of length // smaller than match length + context (at least 50 characters) this match is part of the context $utf8_offset = $utf8_idx + $utf8_len; - $offset = $idx + strlen(PhpString::substr($text,$utf8_idx,$utf8_len)); - $offset = Clean::correctIdx($text,$offset); + $offset = $idx + strlen(PhpString::substr($text, $utf8_idx, $utf8_len)); + $offset = Clean::correctIdx($text, $offset); } $m = "\1"; - $snippets = preg_replace('/'.$re1.'/iu',$m.'$1'.$m,$snippets); + $snippets = preg_replace('/' . $re1 . '/iu', $m . '$1' . $m, $snippets); $snippet = preg_replace( '/' . $m . '([^' . $m . ']*?)' . $m . '/iu', '<strong class="search_hit">$1</strong>', - hsc(join('... ', $snippets)) + hsc(implode('... ', $snippets)) ); $evdata['snippet'] = $snippet; @@ -535,9 +559,10 @@ function ft_snippet($id,$highlight){ * @param string $term * @return string */ -function ft_snippet_re_preprocess($term) { +function ft_snippet_re_preprocess($term) +{ // do not process asian terms where word boundaries are not explicit - if(\dokuwiki\Utf8\Asian::isAsianWords($term)) return $term; + if (Asian::isAsianWords($term)) return $term; if (UTF8_PROPERTYSUPPORT) { // unicode word boundaries @@ -550,19 +575,19 @@ function ft_snippet_re_preprocess($term) { $BR = '\b'; } - if(substr($term,0,2) == '\\*'){ - $term = substr($term,2); - }else{ - $term = $BL.$term; + if (substr($term, 0, 2) == '\\*') { + $term = substr($term, 2); + } else { + $term = $BL . $term; } - if(substr($term,-2,2) == '\\*'){ - $term = substr($term,0,-2); - }else{ - $term = $term.$BR; + if (substr($term, -2, 2) == '\\*') { + $term = substr($term, 0, -2); + } else { + $term .= $BR; } - if($term == $BL || $term == $BR || $term == $BL.$BR) $term = ''; + if ($term == $BL || $term == $BR || $term == $BL . $BR) $term = ''; return $term; } @@ -577,13 +602,14 @@ function ft_snippet_re_preprocess($term) { * @param array $args An array of page arrays * @return array */ -function ft_resultCombine($args){ +function ft_resultCombine($args) +{ $array_count = count($args); - if($array_count == 1){ + if ($array_count == 1) { return $args[0]; } - $result = array(); + $result = []; if ($array_count > 1) { foreach ($args[0] as $key => $value) { $result[$key] = $value; @@ -609,7 +635,8 @@ function ft_resultCombine($args){ * * @author Kazutaka Miyasaka <kazmiya@gmail.com> */ -function ft_resultUnite($args) { +function ft_resultUnite($args) +{ $array_count = count($args); if ($array_count === 1) { return $args[0]; @@ -634,7 +661,8 @@ function ft_resultUnite($args) { * * @author Kazutaka Miyasaka <kazmiya@gmail.com> */ -function ft_resultComplement($args) { +function ft_resultComplement($args) +{ $array_count = count($args); if ($array_count === 1) { return $args[0]; @@ -655,11 +683,12 @@ function ft_resultComplement($args) { * @author Andreas Gohr <andi@splitbrain.org> * @author Kazutaka Miyasaka <kazmiya@gmail.com> * - * @param dokuwiki\Search\Indexer $Indexer + * @param Indexer $Indexer * @param string $query search query * @return array of search formulas */ -function ft_queryParser($Indexer, $query){ +function ft_queryParser($Indexer, $query) +{ /** * parse a search query and transform it into intermediate representation * @@ -698,22 +727,26 @@ function ft_queryParser($Indexer, $query){ */ $parsed_query = ''; $parens_level = 0; - $terms = preg_split('/(-?".*?")/u', PhpString::strtolower($query), - -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + $terms = preg_split( + '/(-?".*?")/u', + PhpString::strtolower($query), + -1, + PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY + ); foreach ($terms as $term) { $parsed = ''; if (preg_match('/^(-?)"(.+)"$/u', $term, $matches)) { // phrase-include and phrase-exclude $not = $matches[1] ? 'NOT' : ''; - $parsed = $not.ft_termParser($Indexer, $matches[2], false, true); + $parsed = $not . ft_termParser($Indexer, $matches[2], false, true); } else { // fix incomplete phrase $term = str_replace('"', ' ', $term); // fix parentheses - $term = str_replace(')' , ' ) ', $term); - $term = str_replace('(' , ' ( ', $term); + $term = str_replace(')', ' ) ', $term); + $term = str_replace('(', ' ( ', $term); $term = str_replace('- (', ' -(', $term); // treat pipe symbols as 'OR' operators @@ -721,7 +754,7 @@ function ft_queryParser($Indexer, $query){ // treat ideographic spaces (U+3000) as search term separators // FIXME: some more separators? - $term = preg_replace('/[ \x{3000}]+/u', ' ', $term); + $term = preg_replace('/[ \x{3000}]+/u', ' ', $term); $term = trim($term); if ($term === '') continue; @@ -747,13 +780,13 @@ function ft_queryParser($Indexer, $query){ $parsed .= 'OR'; } elseif (preg_match('/^(?:\^|-ns:)(.+)$/u', $token, $matches)) { // namespace-exclude - $parsed .= 'NOT(N+:'.$matches[1].')'; + $parsed .= 'NOT(N+:' . $matches[1] . ')'; } elseif (preg_match('/^(?:@|ns:)(.+)$/u', $token, $matches)) { // namespace-include - $parsed .= '(N+:'.$matches[1].')'; + $parsed .= '(N+:' . $matches[1] . ')'; } elseif (preg_match('/^-(.+)$/', $token, $matches)) { // word-exclude - $parsed .= 'NOT('.ft_termParser($Indexer, $matches[1]).')'; + $parsed .= 'NOT(' . ft_termParser($Indexer, $matches[1]) . ')'; } else { // word-include $parsed .= ft_termParser($Indexer, $token); @@ -769,15 +802,15 @@ function ft_queryParser($Indexer, $query){ $parsed_query_old = $parsed_query; $parsed_query = preg_replace('/(NOT)?\(\)/u', '', $parsed_query); } while ($parsed_query !== $parsed_query_old); - $parsed_query = preg_replace('/(NOT|OR)+\)/u', ')' , $parsed_query); - $parsed_query = preg_replace('/(OR)+/u' , 'OR' , $parsed_query); - $parsed_query = preg_replace('/\(OR/u' , '(' , $parsed_query); - $parsed_query = preg_replace('/^OR|OR$/u' , '' , $parsed_query); - $parsed_query = preg_replace('/\)(NOT)?\(/u' , ')AND$1(', $parsed_query); + $parsed_query = preg_replace('/(NOT|OR)+\)/u', ')', $parsed_query); + $parsed_query = preg_replace('/(OR)+/u', 'OR', $parsed_query); + $parsed_query = preg_replace('/\(OR/u', '(', $parsed_query); + $parsed_query = preg_replace('/^OR|OR$/u', '', $parsed_query); + $parsed_query = preg_replace('/\)(NOT)?\(/u', ')AND$1(', $parsed_query); // adjustment: make highlightings right $parens_level = 0; - $notgrp_levels = array(); + $notgrp_levels = []; $parsed_query_new = ''; $tokens = preg_split('/(NOT\(|[()])/u', $parsed_query, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); foreach ($tokens as $token) { @@ -802,9 +835,9 @@ function ft_queryParser($Indexer, $query){ * see: http://en.wikipedia.org/wiki/Reverse_Polish_notation * see: http://en.wikipedia.org/wiki/Shunting-yard_algorithm */ - $parsed_ary = array(); - $ope_stack = array(); - $ope_precedence = array(')' => 1, 'OR' => 2, 'AND' => 3, 'NOT' => 4, '(' => 5); + $parsed_ary = []; + $ope_stack = []; + $ope_precedence = [')' => 1, 'OR' => 2, 'AND' => 3, 'NOT' => 4, '(' => 5]; $ope_regex = '/([()]|OR|AND|NOT)/u'; $tokens = preg_split($ope_regex, $parsed_query, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); @@ -823,11 +856,11 @@ function ft_queryParser($Indexer, $query){ } } else { // operand - $token_decoded = str_replace(array('OP', 'CP'), array('(', ')'), $token); + $token_decoded = str_replace(['OP', 'CP'], ['(', ')'], $token); $parsed_ary[] = $token_decoded; } } - $parsed_ary = array_values(array_merge($parsed_ary, array_reverse($ope_stack))); + $parsed_ary = array_values([...$parsed_ary, ...array_reverse($ope_stack)]); // cleanup: each double "NOT" in RPN array actually does nothing $parsed_ary_count = count($parsed_ary); @@ -839,7 +872,7 @@ function ft_queryParser($Indexer, $query){ $parsed_ary = array_values($parsed_ary); // build return value - $q = array(); + $q = []; $q['query'] = $query; $q['parsed_str'] = $parsed_query; $q['parsed_ary'] = $parsed_ary; @@ -851,33 +884,33 @@ function ft_queryParser($Indexer, $query){ switch (substr($token, 0, 3)) { case 'N+:': $q['ns'][] = $body; // for backward compatibility - break; + break; case 'N-:': $q['notns'][] = $body; // for backward compatibility - break; + break; case 'W_:': $q['words'][] = $body; - break; + break; case 'W-:': $q['words'][] = $body; $q['not'][] = $body; // for backward compatibility - break; + break; case 'W+:': $q['words'][] = $body; $q['highlight'][] = $body; $q['and'][] = $body; // for backward compatibility - break; + break; case 'P-:': $q['phrases'][] = $body; - break; + break; case 'P+:': $q['phrases'][] = $body; $q['highlight'][] = $body; - break; + break; } } - foreach (array('words', 'phrases', 'highlight', 'ns', 'notns', 'and', 'not') as $key) { - $q[$key] = empty($q[$key]) ? array() : array_values(array_unique($q[$key])); + foreach (['words', 'phrases', 'highlight', 'ns', 'notns', 'and', 'not'] as $key) { + $q[$key] = empty($q[$key]) ? [] : array_values(array_unique($q[$key])); } return $q; @@ -890,35 +923,36 @@ function ft_queryParser($Indexer, $query){ * * @author Kazutaka Miyasaka <kazmiya@gmail.com> * - * @param dokuwiki\Search\Indexer $Indexer + * @param Indexer $Indexer * @param string $term * @param bool $consider_asian * @param bool $phrase_mode * @return string */ -function ft_termParser($Indexer, $term, $consider_asian = true, $phrase_mode = false) { +function ft_termParser($Indexer, $term, $consider_asian = true, $phrase_mode = false) +{ $parsed = ''; if ($consider_asian) { // successive asian characters need to be searched as a phrase - $words = \dokuwiki\Utf8\Asian::splitAsianWords($term); + $words = Asian::splitAsianWords($term); foreach ($words as $word) { - $phrase_mode = $phrase_mode ? true : \dokuwiki\Utf8\Asian::isAsianWords($word); + $phrase_mode = $phrase_mode ? true : Asian::isAsianWords($word); $parsed .= ft_termParser($Indexer, $word, false, $phrase_mode); } } else { - $term_noparen = str_replace(array('(', ')'), ' ', $term); + $term_noparen = str_replace(['(', ')'], ' ', $term); $words = $Indexer->tokenizer($term_noparen, true); // W_: no need to highlight if (empty($words)) { $parsed = '()'; // important: do not remove } elseif ($words[0] === $term) { - $parsed = '(W+:'.$words[0].')'; + $parsed = '(W+:' . $words[0] . ')'; } elseif ($phrase_mode) { - $term_encoded = str_replace(array('(', ')'), array('OP', 'CP'), $term); - $parsed = '((W_:'.implode(')(W_:', $words).')(P+:'.$term_encoded.'))'; + $term_encoded = str_replace(['(', ')'], ['OP', 'CP'], $term); + $parsed = '((W_:' . implode(')(W_:', $words) . ')(P+:' . $term_encoded . '))'; } else { - $parsed = '((W+:'.implode(')(W+:', $words).'))'; + $parsed = '((W+:' . implode(')(W+:', $words) . '))'; } } return $parsed; @@ -935,21 +969,22 @@ function ft_termParser($Indexer, $term, $consider_asian = true, $phrase_mode = f * * @return string */ -function ft_queryUnparser_simple(array $and, array $not, array $phrases, array $ns, array $notns) { +function ft_queryUnparser_simple(array $and, array $not, array $phrases, array $ns, array $notns) +{ $query = implode(' ', $and); - if (!empty($not)) { + if ($not !== []) { $query .= ' -' . implode(' -', $not); } - if (!empty($phrases)) { + if ($phrases !== []) { $query .= ' "' . implode('" "', $phrases) . '"'; } - if (!empty($ns)) { + if ($ns !== []) { $query .= ' @' . implode(' @', $ns); } - if (!empty($notns)) { + if ($notns !== []) { $query .= ' ^' . implode(' ^', $notns); } diff --git a/inc/html.php b/inc/html.php index a7e225383..9b7664370 100644 --- a/inc/html.php +++ b/inc/html.php @@ -1,4 +1,5 @@ <?php + /** * HTML output functions * @@ -6,6 +7,8 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Ui\MediaRevisions; +use dokuwiki\Form\Form; use dokuwiki\Action\Denied; use dokuwiki\Action\Locked; use dokuwiki\ChangeLog\PageChangeLog; @@ -40,14 +43,15 @@ if (!defined('SEC_EDIT_PATTERN')) { * @param string|array $search search string(s) that shall be highlighted in the target page * @return string the HTML code of the link */ -function html_wikilink($id, $name = null, $search = '') { +function html_wikilink($id, $name = null, $search = '') +{ /** @var Doku_Renderer_xhtml $xhtml_renderer */ static $xhtml_renderer = null; if (is_null($xhtml_renderer)) { $xhtml_renderer = p_get_renderer('xhtml'); } - return $xhtml_renderer->internallink($id,$name,$search,true,'navigation'); + return $xhtml_renderer->internallink($id, $name, $search, true, 'navigation'); } /** @@ -58,9 +62,10 @@ function html_wikilink($id, $name = null, $search = '') { * @param bool $svg Whether to show svg icons in the register and resendpwd links or not * @deprecated 2020-07-18 */ -function html_login($svg = false) { - dbg_deprecated(Login::class .'::show()'); - (new dokuwiki\Ui\Login($svg))->show(); +function html_login($svg = false) +{ + dbg_deprecated(Login::class . '::show()'); + (new Login($svg))->show(); } @@ -69,9 +74,10 @@ function html_login($svg = false) { * * @deprecated 2020-07-18 not called anymore, see inc/Action/Denied::tplContent() */ -function html_denied() { - dbg_deprecated(Denied::class .'::showBanner()'); - (new dokuwiki\Action\Denied())->showBanner(); +function html_denied() +{ + dbg_deprecated(Denied::class . '::showBanner()'); + (new Denied())->showBanner(); } /** @@ -83,15 +89,19 @@ function html_denied() { * @param bool $show show section edit buttons? * @return string */ -function html_secedit($text, $show = true) { +function html_secedit($text, $show = true) +{ global $INFO; if ((isset($INFO) && !$INFO['writable']) || !$show || (isset($INFO) && $INFO['rev'])) { - return preg_replace(SEC_EDIT_PATTERN,'',$text); + return preg_replace(SEC_EDIT_PATTERN, '', $text); } - return preg_replace_callback(SEC_EDIT_PATTERN, - 'html_secedit_button', $text); + return preg_replace_callback( + SEC_EDIT_PATTERN, + 'html_secedit_button', + $text + ); } /** @@ -104,10 +114,13 @@ function html_secedit($text, $show = true) { * @return string * @triggers HTML_SECEDIT_BUTTON */ -function html_secedit_button($matches){ +function html_secedit_button($matches) +{ $json = htmlspecialchars_decode($matches[1], ENT_QUOTES); - $data = json_decode($json, true); - if ($data === null) { + + try { + $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { return ''; } $data['target'] = strtolower($data['target']); @@ -129,7 +142,8 @@ function html_secedit_button($matches){ * @param array $data name, section id and target * @return string html */ -function html_secedit_get_button($data) { +function html_secedit_get_button($data) +{ global $ID; global $INFO; @@ -142,13 +156,13 @@ function html_secedit_get_button($data) { unset($data['secid']); $params = array_merge( - array('do' => 'edit', 'rev' => $INFO['lastmod'], 'summary' => '['.$name.'] '), - $data + ['do' => 'edit', 'rev' => $INFO['lastmod'], 'summary' => '[' . $name . '] '], + $data ); - $html = '<div class="secedit editbutton_'.$data['target'] .' editbutton_'.$secid .'">'; - $html.= html_btn('secedit', $ID, '', $params, 'post', $name); - $html.= '</div>'; + $html = '<div class="secedit editbutton_' . $data['target'] . ' editbutton_' . $secid . '">'; + $html .= html_btn('secedit', $ID, '', $params, 'post', $name); + $html .= '</div>'; return $html; } @@ -159,13 +173,14 @@ function html_secedit_get_button($data) { * * @return string html */ -function html_topbtn() { +function html_topbtn() +{ global $lang; return '<a class="nolink" href="#dokuwiki__top">' - .'<button class="button" onclick="window.scrollTo(0, 0)" title="'. $lang['btn_top'] .'">' + . '<button class="button" onclick="window.scrollTo(0, 0)" title="' . $lang['btn_top'] . '">' . $lang['btn_top'] - .'</button></a>'; + . '</button></a>'; } /** @@ -184,31 +199,32 @@ function html_topbtn() { * @param string $svg (optional) svg code, inserted into the button * @return string */ -function html_btn($name, $id, $akey, $params, $method = 'get', $tooltip = '', $label = false, $svg = null) { +function html_btn($name, $id, $akey, $params, $method = 'get', $tooltip = '', $label = false, $svg = null) +{ global $conf; global $lang; if (!$label) - $label = $lang['btn_'.$name]; + $label = $lang['btn_' . $name]; //filter id (without urlencoding) - $id = idfilter($id,false); + $id = idfilter($id, false); //make nice URLs even for buttons if ($conf['userewrite'] == 2) { - $script = DOKU_BASE.DOKU_SCRIPT.'/'.$id; + $script = DOKU_BASE . DOKU_SCRIPT . '/' . $id; } elseif ($conf['userewrite']) { - $script = DOKU_BASE.$id; + $script = DOKU_BASE . $id; } else { - $script = DOKU_BASE.DOKU_SCRIPT; + $script = DOKU_BASE . DOKU_SCRIPT; $params['id'] = $id; } - $html = '<form class="button btn_'.$name.'" method="'.$method.'" action="'.$script.'"><div class="no">'; + $html = '<form class="button btn_' . $name . '" method="' . $method . '" action="' . $script . '"><div class="no">'; if (is_array($params)) { foreach ($params as $key => $val) { - $html .= '<input type="hidden" name="'.$key.'" value="'.hsc($val).'" />'; + $html .= '<input type="hidden" name="' . $key . '" value="' . hsc($val) . '" />'; } } @@ -216,12 +232,12 @@ function html_btn($name, $id, $akey, $params, $method = 'get', $tooltip = '', $l $html .= '<button type="submit" '; if ($akey) { - $tip .= ' ['.strtoupper($akey).']'; - $html .= 'accesskey="'.$akey.'" '; + $tip .= ' [' . strtoupper($akey) . ']'; + $html .= 'accesskey="' . $akey . '" '; } - $html .= 'title="'.$tip.'">'; + $html .= 'title="' . $tip . '">'; if ($svg) { - $html .= '<span>'. hsc($label) .'</span>'. inlineSVG($svg); + $html .= '<span>' . hsc($label) . '</span>' . inlineSVG($svg); } else { $html .= hsc($label); } @@ -236,8 +252,9 @@ function html_btn($name, $id, $akey, $params, $method = 'get', $tooltip = '', $l * @author Szymon Olewniczak <dokuwiki@imz.re> * @deprecated 2020-07-18 */ -function html_showrev() { - dbg_deprecated(PageView::class .'::showrev()'); +function html_showrev() +{ + dbg_deprecated(PageView::class . '::showrev()'); } /** @@ -248,9 +265,10 @@ function html_showrev() { * @param null|string $txt wiki text or null for showing $ID * @deprecated 2020-07-18 */ -function html_show($txt=null) { - dbg_deprecated(PageView::class .'::show()'); - (new dokuwiki\Ui\PageView($txt))->show(); +function html_show($txt = null) +{ + dbg_deprecated(PageView::class . '::show()'); + (new PageView($txt))->show(); } /** @@ -259,9 +277,10 @@ function html_show($txt=null) { * @author Andreas Gohr <andi@splitbrain.org> * @deprecated 2020-07-18 */ -function html_draft() { - dbg_deprecated(PageDraft::class .'::show()'); - (new dokuwiki\Ui\PageDraft)->show(); +function html_draft() +{ + dbg_deprecated(PageDraft::class . '::show()'); + (new PageDraft())->show(); } /** @@ -274,12 +293,14 @@ function html_draft() { * @param array|string $phrases * @return string html */ -function html_hilight($html, $phrases) { +function html_hilight($html, $phrases) +{ $phrases = (array) $phrases; $phrases = array_map('preg_quote_cb', $phrases); $phrases = array_map('ft_snippet_re_preprocess', $phrases); $phrases = array_filter($phrases); - $regex = join('|',$phrases); + + $regex = implode('|', $phrases); if ($regex === '') return $html; if (!Clean::isUtf8($regex)) return $html; @@ -287,7 +308,7 @@ function html_hilight($html, $phrases) { return @preg_replace_callback("/((<[^>]*)|$regex)/ui", function ($match) { $hlight = unslash($match[0]); if (!isset($match[2])) { - $hlight = '<span class="search_hit">'.$hlight.'</span>'; + $hlight = '<span class="search_hit">' . $hlight . '</span>'; } return $hlight; }, $html); @@ -299,9 +320,10 @@ function html_hilight($html, $phrases) { * @author Andreas Gohr <andi@splitbrain.org> * @deprecated 2020-07-18 not called anymore, see inc/Action/Locked::tplContent() */ -function html_locked() { - dbg_deprecated(Locked::class .'::showBanner()'); - (new dokuwiki\Action\Locked())->showBanner(); +function html_locked() +{ + dbg_deprecated(Locked::class . '::showBanner()'); + (new Locked())->showBanner(); } /** @@ -315,13 +337,14 @@ function html_locked() { * @param string $media_id id of media, or empty for current page * @deprecated 2020-07-18 */ -function html_revisions($first = -1, $media_id = '') { - dbg_deprecated(PageRevisions::class .'::show()'); +function html_revisions($first = -1, $media_id = '') +{ + dbg_deprecated(PageRevisions::class . '::show()'); if ($media_id) { - (new dokuwiki\Ui\MediaRevisions($media_id))->show($first); + (new MediaRevisions($media_id))->show($first); } else { global $INFO; - (new dokuwiki\Ui\PageRevisions($INFO['id']))->show($first); + (new PageRevisions($INFO['id']))->show($first); } } @@ -337,9 +360,10 @@ function html_revisions($first = -1, $media_id = '') { * @param string $show_changes * @deprecated 2020-07-18 */ -function html_recent($first = 0, $show_changes = 'both') { - dbg_deprecated(Recent::class .'::show()'); - (new dokuwiki\Ui\Recent($first, $show_changes))->show(); +function html_recent($first = 0, $show_changes = 'both') +{ + dbg_deprecated(Recent::class . '::show()'); + (new Recent($first, $show_changes))->show(); } /** @@ -350,9 +374,10 @@ function html_recent($first = 0, $show_changes = 'both') { * @param string $ns * @deprecated 2020-07-18 */ -function html_index($ns) { - dbg_deprecated(Index::class .'::show()'); - (new dokuwiki\Ui\Index($ns))->show(); +function html_index($ns) +{ + dbg_deprecated(Index::class . '::show()'); + (new Index($ns))->show(); } /** @@ -366,9 +391,10 @@ function html_index($ns) { * @return string * @deprecated 2020-07-18 */ -function html_list_index($item) { - dbg_deprecated(Index::class .'::formatListItem()'); - return (new dokuwiki\Ui\Index)->formatListItem($item); +function html_list_index($item) +{ + dbg_deprecated(Index::class . '::formatListItem()'); + return (new Index())->formatListItem($item); } /** @@ -384,9 +410,10 @@ function html_list_index($item) { * @return string html * @deprecated 2020-07-18 */ -function html_li_index($item) { - dbg_deprecated(Index::class .'::tagListItem()'); - return (new dokuwiki\Ui\Index)->tagListItem($item); +function html_li_index($item) +{ + dbg_deprecated(Index::class . '::tagListItem()'); + return (new Index())->tagListItem($item); } /** @@ -398,8 +425,9 @@ function html_li_index($item) { * @return string html * @deprecated 2020-07-18 */ -function html_li_default($item){ - return '<li class="level'.$item['level'].'">'; +function html_li_default($item) +{ + return '<li class="level' . $item['level'] . '">'; } /** @@ -425,8 +453,9 @@ function html_li_default($item){ * 0 (we have a root object) or 1 (just the root content) * @return string html of an unordered list */ -function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = false) { - if (count($data) === 0) { +function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = false) +{ + if ($data === []) { return ''; } @@ -438,9 +467,7 @@ function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = fa // set callback function to build the <li> tag, formerly defined as html_li_default() if (!is_callable($lifunc)) { - $lifunc = function ($item) { - return '<li class="level'.$item['level'].'">'; - }; + $lifunc = static fn($item) => '<li class="level' . $item['level'] . '">'; } foreach ($data as $item) { @@ -448,23 +475,22 @@ function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = fa //open new list for ($i = 0; $i < ($item['level'] - $level); $i++) { if ($i) $html .= '<li class="clear">'; - $html .= "\n".'<ul class="'.$class.'">'."\n"; + $html .= "\n" . '<ul class="' . $class . '">' . "\n"; $open++; } $level = $item['level']; - } elseif ($item['level'] < $level) { //close last item - $html .= '</li>'."\n"; - while ($level > $item['level'] && $open > 0 ) { + $html .= '</li>' . "\n"; + while ($level > $item['level'] && $open > 0) { //close higher lists - $html .= '</ul>'."\n".'</li>'."\n"; + $html .= '</ul>' . "\n" . '</li>' . "\n"; $level--; $open--; } } elseif ($html !== '') { //close previous item - $html .= '</li>'."\n"; + $html .= '</li>' . "\n"; } //print item @@ -476,15 +502,15 @@ function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = fa } //close remaining items and lists - $html .= '</li>'."\n"; + $html .= '</li>' . "\n"; while ($open-- > 0) { - $html .= '</ul></li>'."\n"; + $html .= '</ul></li>' . "\n"; } if ($forcewrapper || $start_level < 2) { // Trigger building a wrapper ul if the first level is // 0 (we have a root object) or 1 (just the root content) - $html = "\n".'<ul class="'.$class.'">'."\n".$html.'</ul>'."\n"; + $html = "\n" . '<ul class="' . $class . '">' . "\n" . $html . '</ul>' . "\n"; } return $html; @@ -497,9 +523,10 @@ function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = fa * @author Michael Klier <chi@chimeric.de> * @deprecated 2020-07-18 */ -function html_backlinks() { - dbg_deprecated(Backlinks::class .'::show()'); - (new dokuwiki\Ui\Backlinks)->show(); +function html_backlinks() +{ + dbg_deprecated(Backlinks::class . '::show()'); + (new Backlinks())->show(); } /** @@ -513,8 +540,9 @@ function html_backlinks() { * @return string[] HTML snippets for diff header * @deprecated 2020-07-18 */ -function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false) { - dbg_deprecated('see '. PageDiff::class .'::buildDiffHead()'); +function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false) +{ + dbg_deprecated('see ' . PageDiff::class . '::buildDiffHead()'); return ['', '', '', '']; } @@ -529,10 +557,11 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = fa * @param string $type type of the diff (inline or sidebyside) * @deprecated 2020-07-18 */ -function html_diff($text = '', $intro = true, $type = null) { - dbg_deprecated(PageDiff::class .'::show()'); +function html_diff($text = '', $intro = true, $type = null) +{ + dbg_deprecated(PageDiff::class . '::show()'); global $INFO; - (new dokuwiki\Ui\PageDiff($INFO['id']))->compareWith($text)->preference([ + (new PageDiff($INFO['id']))->compareWith($text)->preference([ 'showIntro' => $intro, 'difftype' => $type, ])->show(); @@ -548,8 +577,9 @@ function html_diff($text = '', $intro = true, $type = null) { * @return string[] html of left and right navigation elements * @deprecated 2020-07-18 */ -function html_diff_navigation($pagelog, $type, $l_rev, $r_rev) { - dbg_deprecated('see '. PageDiff::class .'::buildRevisionsNavigation()'); +function html_diff_navigation($pagelog, $type, $l_rev, $r_rev) +{ + dbg_deprecated('see ' . PageDiff::class . '::buildRevisionsNavigation()'); return ['', '']; } @@ -563,8 +593,9 @@ function html_diff_navigation($pagelog, $type, $l_rev, $r_rev) { * @return string html of link to a diff * @deprecated 2020-07-18 */ -function html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null) { - dbg_deprecated('see '. PageDiff::class .'::diffViewlink()'); +function html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null) +{ + dbg_deprecated('see ' . PageDiff::class . '::diffViewlink()'); return ''; } @@ -575,9 +606,10 @@ function html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null) { * @return string * @deprecated 2020-07-18 */ -function html_insert_softbreaks($diffhtml) { - dbg_deprecated(PageDiff::class .'::insertSoftbreaks()'); - return (new dokuwiki\Ui\PageDiff)->insertSoftbreaks($diffhtml); +function html_insert_softbreaks($diffhtml) +{ + dbg_deprecated(PageDiff::class . '::insertSoftbreaks()'); + return (new PageDiff())->insertSoftbreaks($diffhtml); } /** @@ -589,9 +621,10 @@ function html_insert_softbreaks($diffhtml) { * @param string $summary * @deprecated 2020-07-18 */ -function html_conflict($text, $summary) { - dbg_deprecated(PageConflict::class .'::show()'); - (new dokuwiki\Ui\PageConflict($text, $summary))->show(); +function html_conflict($text, $summary) +{ + dbg_deprecated(PageConflict::class . '::show()'); + (new PageConflict($text, $summary))->show(); } /** @@ -599,7 +632,8 @@ function html_conflict($text, $summary) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function html_msgarea() { +function html_msgarea() +{ global $MSG, $MSG_shown; /** @var array $MSG */ // store if the global $MSG has already been shown and thus HTML output has been started @@ -607,14 +641,14 @@ function html_msgarea() { if (!isset($MSG)) return; - $shown = array(); + $shown = []; foreach ($MSG as $msg) { $hash = md5($msg['msg']); if (isset($shown[$hash])) continue; // skip double messages if (info_msg_allowed($msg)) { - print '<div class="'.$msg['lvl'].'">'; - print $msg['msg']; - print '</div>'; + echo '<div class="' . $msg['lvl'] . '">'; + echo $msg['msg']; + echo '</div>'; } $shown[$hash] = 1; } @@ -628,9 +662,10 @@ function html_msgarea() { * @author Andreas Gohr <andi@splitbrain.org> * @deprecated 2020-07-18 */ -function html_register() { - dbg_deprecated(UserRegister::class .'::show()'); - (new dokuwiki\Ui\UserRegister)->show(); +function html_register() +{ + dbg_deprecated(UserRegister::class . '::show()'); + (new UserRegister())->show(); } /** @@ -640,9 +675,10 @@ function html_register() { * @author Andreas Gohr <andi@splitbrain.org> * @deprecated 2020-07-18 */ -function html_updateprofile() { - dbg_deprecated(UserProfile::class .'::show()'); - (new dokuwiki\Ui\UserProfile)->show(); +function html_updateprofile() +{ + dbg_deprecated(UserProfile::class . '::show()'); + (new UserProfile())->show(); } /** @@ -652,9 +688,10 @@ function html_updateprofile() { * * @deprecated 2020-07-18 */ -function html_edit() { - dbg_deprecated(Editor::class .'::show()'); - (new dokuwiki\Ui\Editor)->show(); +function html_edit() +{ + dbg_deprecated(Editor::class . '::show()'); + (new Editor())->show(); } /** @@ -665,9 +702,10 @@ function html_edit() { * @param array $param * @deprecated 2020-07-18 */ -function html_edit_form($param) { - dbg_deprecated(Editor::class .'::addTextarea()'); - (new dokuwiki\Ui\Editor)->addTextarea($param); +function html_edit_form($param) +{ + dbg_deprecated(Editor::class . '::addTextarea()'); + (new Editor())->addTextarea($param); } /** @@ -675,7 +713,8 @@ function html_edit_form($param) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function html_debug() { +function html_debug() +{ global $conf; global $lang; /** @var AuthPlugin $auth */ @@ -690,82 +729,82 @@ function html_debug() { $ses = $_SESSION; debug_guard($ses); - print '<html><body>'; + echo '<html><body>'; - print '<p>When reporting bugs please send all the following '; - print 'output as a mail to andi@splitbrain.org '; - print 'The best way to do this is to save this page in your browser</p>'; + echo '<p>When reporting bugs please send all the following '; + echo 'output as a mail to andi@splitbrain.org '; + echo 'The best way to do this is to save this page in your browser</p>'; - print '<b>$INFO:</b><pre>'; + echo '<b>$INFO:</b><pre>'; print_r($nfo); - print '</pre>'; + echo '</pre>'; - print '<b>$_SERVER:</b><pre>'; + echo '<b>$_SERVER:</b><pre>'; print_r($_SERVER); - print '</pre>'; + echo '</pre>'; - print '<b>$conf:</b><pre>'; + echo '<b>$conf:</b><pre>'; print_r($cnf); - print '</pre>'; + echo '</pre>'; - print '<b>DOKU_BASE:</b><pre>'; - print DOKU_BASE; - print '</pre>'; + echo '<b>DOKU_BASE:</b><pre>'; + echo DOKU_BASE; + echo '</pre>'; - print '<b>abs DOKU_BASE:</b><pre>'; - print DOKU_URL; - print '</pre>'; + echo '<b>abs DOKU_BASE:</b><pre>'; + echo DOKU_URL; + echo '</pre>'; - print '<b>rel DOKU_BASE:</b><pre>'; - print dirname($_SERVER['PHP_SELF']).'/'; - print '</pre>'; + echo '<b>rel DOKU_BASE:</b><pre>'; + echo dirname($_SERVER['PHP_SELF']) . '/'; + echo '</pre>'; - print '<b>PHP Version:</b><pre>'; - print phpversion(); - print '</pre>'; + echo '<b>PHP Version:</b><pre>'; + echo phpversion(); + echo '</pre>'; - print '<b>locale:</b><pre>'; - print setlocale(LC_ALL,0); - print '</pre>'; + echo '<b>locale:</b><pre>'; + echo setlocale(LC_ALL, 0); + echo '</pre>'; - print '<b>encoding:</b><pre>'; - print $lang['encoding']; - print '</pre>'; + echo '<b>encoding:</b><pre>'; + echo $lang['encoding']; + echo '</pre>'; - if ($auth) { - print '<b>Auth backend capabilities:</b><pre>'; + if ($auth instanceof AuthPlugin) { + echo '<b>Auth backend capabilities:</b><pre>'; foreach ($auth->getCapabilities() as $cando) { - print ' '.str_pad($cando,16) .' => '. (int)$auth->canDo($cando) . DOKU_LF; + echo ' ' . str_pad($cando, 16) . ' => ' . (int)$auth->canDo($cando) . DOKU_LF; } - print '</pre>'; + echo '</pre>'; } - print '<b>$_SESSION:</b><pre>'; + echo '<b>$_SESSION:</b><pre>'; print_r($ses); - print '</pre>'; + echo '</pre>'; - print '<b>Environment:</b><pre>'; + echo '<b>Environment:</b><pre>'; print_r($_ENV); - print '</pre>'; + echo '</pre>'; - print '<b>PHP settings:</b><pre>'; + echo '<b>PHP settings:</b><pre>'; $inis = ini_get_all(); print_r($inis); - print '</pre>'; + echo '</pre>'; if (function_exists('apache_get_version')) { - $apache = array(); + $apache = []; $apache['version'] = apache_get_version(); if (function_exists('apache_get_modules')) { $apache['modules'] = apache_get_modules(); } - print '<b>Apache</b><pre>'; + echo '<b>Apache</b><pre>'; print_r($apache); - print '</pre>'; + echo '</pre>'; } - print '</body></html>'; + echo '</body></html>'; } /** @@ -775,9 +814,10 @@ function html_debug() { * @author Andreas Gohr <gohr@cosmocode.de> * @deprecated 2020-07-18 */ -function html_resendpwd() { - dbg_deprecated(UserResendPwd::class .'::show()'); - (new dokuwiki\Ui\UserResendPwd)->show(); +function html_resendpwd() +{ + dbg_deprecated(UserResendPwd::class . '::show()'); + (new UserResendPwd())->show(); } /** @@ -788,18 +828,19 @@ function html_resendpwd() { * @param array $toc * @return string html */ -function html_TOC($toc) { - if (!count($toc)) return ''; +function html_TOC($toc) +{ + if ($toc === []) return ''; global $lang; - $out = '<!-- TOC START -->'.DOKU_LF; - $out .= '<div id="dw__toc" class="dw__toc">'.DOKU_LF; + $out = '<!-- TOC START -->' . DOKU_LF; + $out .= '<div id="dw__toc" class="dw__toc">' . DOKU_LF; $out .= '<h3 class="toggle">'; $out .= $lang['toc']; - $out .= '</h3>'.DOKU_LF; - $out .= '<div>'.DOKU_LF; + $out .= '</h3>' . DOKU_LF; + $out .= '<div>' . DOKU_LF; $out .= html_buildlist($toc, 'toc', 'html_list_toc', null, true); - $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF; - $out .= '<!-- TOC END -->'.DOKU_LF; + $out .= '</div>' . DOKU_LF . '</div>' . DOKU_LF; + $out .= '<!-- TOC END -->' . DOKU_LF; return $out; } @@ -809,14 +850,15 @@ function html_TOC($toc) { * @param array $item * @return string html */ -function html_list_toc($item) { - if (isset($item['hid'])){ - $link = '#'.$item['hid']; +function html_list_toc($item) +{ + if (isset($item['hid'])) { + $link = '#' . $item['hid']; } else { $link = $item['link']; } - return '<a href="'.$link.'">'.hsc($item['title']).'</a>'; + return '<a href="' . $link . '">' . hsc($item['title']) . '</a>'; } /** @@ -830,13 +872,14 @@ function html_list_toc($item) { * @param string $hash - is prepended to the given $link, set blank if you want full links * @return array the toc item */ -function html_mktocitem($link, $text, $level, $hash='#') { - return array( - 'link' => $hash.$link, - 'title' => $text, - 'type' => 'ul', - 'level' => $level - ); +function html_mktocitem($link, $text, $level, $hash = '#') +{ + return [ + 'link' => $hash . $link, + 'title' => $text, + 'type' => 'ul', + 'level' => $level + ]; } /** @@ -850,11 +893,12 @@ function html_mktocitem($link, $text, $level, $hash='#') { * @return void * @deprecated 2020-07-18 */ -function html_form($name, $form) { +function html_form($name, $form) +{ dbg_deprecated('use dokuwiki\Form\Form instead of Doku_Form'); // Safety check in case the caller forgets. $form->endFieldset(); - Event::createAndTrigger('HTML_'.strtoupper($name).'FORM_OUTPUT', $form, 'html_form_output', false); + Event::createAndTrigger('HTML_' . strtoupper($name) . 'FORM_OUTPUT', $form, 'html_form_output', false); } /** @@ -865,8 +909,9 @@ function html_form($name, $form) { * @return void * @deprecated 2020-07-18 */ -function html_form_output($form) { - dbg_deprecated('use dokuwiki\Form\Form::toHTML()'); +function html_form_output($form) +{ + dbg_deprecated('use ' . Form::class . '::toHTML()'); $form->printForm(); } @@ -893,17 +938,18 @@ function html_form_output($form) { * @param string $alt - alternative content (is NOT automatically escaped!) * @return string - the XHTML markup */ -function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts=null,$alt=''){ +function html_flashobject($swf, $width, $height, $params = null, $flashvars = null, $atts = null, $alt = '') +{ global $lang; $out = ''; // prepare the object attributes - if(is_null($atts)) $atts = array(); + if (is_null($atts)) $atts = []; $atts['width'] = (int) $width; $atts['height'] = (int) $height; - if(!$atts['width']) $atts['width'] = 425; - if(!$atts['height']) $atts['height'] = 350; + if (!$atts['width']) $atts['width'] = 425; + if (!$atts['height']) $atts['height'] = 350; // add object attributes for standard compliant browsers $std = $atts; @@ -915,34 +961,34 @@ function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts $ie['classid'] = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; // open object (with conditional comments) - $out .= '<!--[if !IE]> -->'.NL; - $out .= '<object '.buildAttributes($std).'>'.NL; - $out .= '<!-- <![endif]-->'.NL; - $out .= '<!--[if IE]>'.NL; - $out .= '<object '.buildAttributes($ie).'>'.NL; - $out .= ' <param name="movie" value="'.hsc($swf).'" />'.NL; - $out .= '<!--><!-- -->'.NL; + $out .= '<!--[if !IE]> -->' . NL; + $out .= '<object ' . buildAttributes($std) . '>' . NL; + $out .= '<!-- <![endif]-->' . NL; + $out .= '<!--[if IE]>' . NL; + $out .= '<object ' . buildAttributes($ie) . '>' . NL; + $out .= ' <param name="movie" value="' . hsc($swf) . '" />' . NL; + $out .= '<!--><!-- -->' . NL; // print params - if(is_array($params)) foreach($params as $key => $val){ - $out .= ' <param name="'.hsc($key).'" value="'.hsc($val).'" />'.NL; + if (is_array($params)) foreach ($params as $key => $val) { + $out .= ' <param name="' . hsc($key) . '" value="' . hsc($val) . '" />' . NL; } // add flashvars - if(is_array($flashvars)){ - $out .= ' <param name="FlashVars" value="'.buildURLparams($flashvars).'" />'.NL; + if (is_array($flashvars)) { + $out .= ' <param name="FlashVars" value="' . buildURLparams($flashvars) . '" />' . NL; } // alternative content - if($alt){ - $out .= $alt.NL; - }else{ - $out .= $lang['noflash'].NL; + if ($alt) { + $out .= $alt . NL; + } else { + $out .= $lang['noflash'] . NL; } // finish - $out .= '</object>'.NL; - $out .= '<!-- <![endif]-->'.NL; + $out .= '</object>' . NL; + $out .= '<!-- <![endif]-->' . NL; return $out; } @@ -954,14 +1000,15 @@ function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts * @param string $current_tab the current tab id * @return void */ -function html_tabs($tabs, $current_tab = null) { - echo '<ul class="tabs">'.NL; +function html_tabs($tabs, $current_tab = null) +{ + echo '<ul class="tabs">' . NL; foreach ($tabs as $id => $tab) { html_tab($tab['href'], $tab['caption'], $id === $current_tab); } - echo '</ul>'.NL; + echo '</ul>' . NL; } /** @@ -976,7 +1023,8 @@ function html_tabs($tabs, $current_tab = null) { * @return void */ -function html_tab($href, $caption, $selected = false) { +function html_tab($href, $caption, $selected = false) +{ $tab = '<li>'; if ($selected) { $tab .= '<strong>'; @@ -985,7 +1033,7 @@ function html_tab($href, $caption, $selected = false) { } $tab .= hsc($caption) . '</' . ($selected ? 'strong' : 'a') . '>' - . '</li>'.NL; + . '</li>' . NL; echo $tab; } @@ -996,7 +1044,8 @@ function html_tab($href, $caption, $selected = false) { * @param Doku_Form $form - (optional) form to add elements to * @return void|string */ -function html_sizechange($sizechange, $form = null) { +function html_sizechange($sizechange, $form = null) +{ if (isset($sizechange)) { $class = 'sizechange'; $value = filesize_h(abs($sizechange)); @@ -1010,9 +1059,9 @@ function html_sizechange($sizechange, $form = null) { $value = '±' . $value; } if (!isset($form)) { - return '<span class="'.$class.'">'.$value.'</span>'; + return '<span class="' . $class . '">' . $value . '</span>'; } else { // Doku_Form - $form->addElement(form_makeOpenTag('span', array('class' => $class))); + $form->addElement(form_makeOpenTag('span', ['class' => $class])); $form->addElement($value); $form->addElement(form_makeCloseTag('span')); } diff --git a/inc/httputils.php b/inc/httputils.php index 00d001f81..d0cf510c8 100644 --- a/inc/httputils.php +++ b/inc/httputils.php @@ -1,4 +1,5 @@ <?php + /** * Utilities for handling HTTP related tasks * @@ -6,26 +7,27 @@ * @author Andreas Gohr <andi@splitbrain.org> */ -define('HTTP_MULTIPART_BOUNDARY','D0KuW1K1B0uNDARY'); -define('HTTP_HEADER_LF',"\r\n"); -define('HTTP_CHUNK_SIZE',16*1024); +define('HTTP_MULTIPART_BOUNDARY', 'D0KuW1K1B0uNDARY'); +define('HTTP_HEADER_LF', "\r\n"); +define('HTTP_CHUNK_SIZE', 16 * 1024); /** * Checks and sets HTTP headers for conditional HTTP requests * - * @author Simon Willison <swillison@gmail.com> + * @param int $timestamp lastmodified time of the cache file + * @returns void or exits with previously header() commands executed * @link http://simonwillison.net/2003/Apr/23/conditionalGet/ * - * @param int $timestamp lastmodified time of the cache file - * @returns void or exits with previously header() commands executed + * @author Simon Willison <swillison@gmail.com> */ -function http_conditionalRequest($timestamp){ +function http_conditionalRequest($timestamp) +{ global $INPUT; // A PHP implementation of conditional get, see // http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers/ - $last_modified = substr(gmdate('r', $timestamp), 0, -5).'GMT'; - $etag = '"'.md5($last_modified).'"'; + $last_modified = substr(gmdate('r', $timestamp), 0, -5) . 'GMT'; + $etag = '"' . md5($last_modified) . '"'; // Send the headers header("Last-Modified: $last_modified"); header("ETag: $etag"); @@ -33,7 +35,7 @@ function http_conditionalRequest($timestamp){ $if_modified_since = $INPUT->server->filter('stripslashes')->str('HTTP_IF_MODIFIED_SINCE', false); $if_none_match = $INPUT->server->filter('stripslashes')->str('HTTP_IF_NONE_MATCH', false); - if (!$if_modified_since && !$if_none_match){ + if (!$if_modified_since && !$if_none_match) { return; } @@ -57,26 +59,27 @@ function http_conditionalRequest($timestamp){ /** * Let the webserver send the given file via x-sendfile method * - * @author Chris Smith <chris@jalakai.co.uk> - * * @param string $file absolute path of file to send * @returns void or exits with previous header() commands executed + * @author Chris Smith <chris@jalakai.co.uk> + * */ -function http_sendfile($file) { +function http_sendfile($file) +{ global $conf; //use x-sendfile header to pass the delivery to compatible web servers - if($conf['xsendfile'] == 1){ + if ($conf['xsendfile'] == 1) { header("X-LIGHTTPD-send-file: $file"); ob_end_clean(); exit; - }elseif($conf['xsendfile'] == 2){ + } elseif ($conf['xsendfile'] == 2) { header("X-Sendfile: $file"); ob_end_clean(); exit; - }elseif($conf['xsendfile'] == 3){ + } elseif ($conf['xsendfile'] == 3) { // FS#2388 nginx just needs the relative path. - $file = DOKU_REL.substr($file, strlen(fullpath(DOKU_INC)) + 1); + $file = DOKU_REL . substr($file, strlen(fullpath(DOKU_INC)) + 1); header("X-Accel-Redirect: $file"); ob_end_clean(); exit; @@ -89,90 +92,91 @@ function http_sendfile($file) { * This function exits the running script * * @param resource $fh - file handle for an already open file - * @param int $size - size of the whole file - * @param int $mime - MIME type of the file + * @param int $size - size of the whole file + * @param int $mime - MIME type of the file * * @author Andreas Gohr <andi@splitbrain.org> */ -function http_rangeRequest($fh,$size,$mime){ +function http_rangeRequest($fh, $size, $mime) +{ global $INPUT; - $ranges = array(); + $ranges = []; $isrange = false; header('Accept-Ranges: bytes'); - if(!$INPUT->server->has('HTTP_RANGE')){ + if (!$INPUT->server->has('HTTP_RANGE')) { // no range requested - send the whole file - $ranges[] = array(0,$size,$size); - }else{ + $ranges[] = [0, $size, $size]; + } else { $t = explode('=', $INPUT->server->str('HTTP_RANGE')); - if (!$t[0]=='bytes') { + if (!$t[0] == 'bytes') { // we only understand byte ranges - send the whole file - $ranges[] = array(0,$size,$size); - }else{ + $ranges[] = [0, $size, $size]; + } else { $isrange = true; // handle multiple ranges - $r = explode(',',$t[1]); - foreach($r as $x){ + $r = explode(',', $t[1]); + foreach ($r as $x) { $p = explode('-', $x); $start = (int)$p[0]; - $end = (int)$p[1]; + $end = (int)$p[1]; if (!$end) $end = $size - 1; - if ($start > $end || $start > $size || $end > $size){ + if ($start > $end || $start > $size || $end > $size) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); - print 'Bad Range Request!'; + echo 'Bad Range Request!'; exit; } $len = $end - $start + 1; - $ranges[] = array($start,$end,$len); + $ranges[] = [$start, $end, $len]; } } } $parts = count($ranges); // now send the type and length headers - if(!$isrange){ - header("Content-Type: $mime",true); - }else{ + if (!$isrange) { + header("Content-Type: $mime", true); + } else { header('HTTP/1.1 206 Partial Content'); - if($parts == 1){ - header("Content-Type: $mime",true); - }else{ - header('Content-Type: multipart/byteranges; boundary='.HTTP_MULTIPART_BOUNDARY,true); + if ($parts == 1) { + header("Content-Type: $mime", true); + } else { + header('Content-Type: multipart/byteranges; boundary=' . HTTP_MULTIPART_BOUNDARY, true); } } // send all ranges - for($i=0; $i<$parts; $i++){ - list($start,$end,$len) = $ranges[$i]; + for ($i = 0; $i < $parts; $i++) { + [$start, $end, $len] = $ranges[$i]; // multipart or normal headers - if($parts > 1){ - echo HTTP_HEADER_LF.'--'.HTTP_MULTIPART_BOUNDARY.HTTP_HEADER_LF; - echo "Content-Type: $mime".HTTP_HEADER_LF; - echo "Content-Range: bytes $start-$end/$size".HTTP_HEADER_LF; + if ($parts > 1) { + echo HTTP_HEADER_LF . '--' . HTTP_MULTIPART_BOUNDARY . HTTP_HEADER_LF; + echo "Content-Type: $mime" . HTTP_HEADER_LF; + echo "Content-Range: bytes $start-$end/$size" . HTTP_HEADER_LF; echo HTTP_HEADER_LF; - }else{ + } else { header("Content-Length: $len"); - if($isrange){ + if ($isrange) { header("Content-Range: bytes $start-$end/$size"); } } // send file content - fseek($fh,$start); //seek to start of range + fseek($fh, $start); //seek to start of range $chunk = ($len > HTTP_CHUNK_SIZE) ? HTTP_CHUNK_SIZE : $len; while (!feof($fh) && $chunk > 0) { @set_time_limit(30); // large files can take a lot of time - print fread($fh, $chunk); + echo fread($fh, $chunk); flush(); $len -= $chunk; $chunk = ($len > HTTP_CHUNK_SIZE) ? HTTP_CHUNK_SIZE : $len; } } - if($parts > 1){ - echo HTTP_HEADER_LF.'--'.HTTP_MULTIPART_BOUNDARY.'--'.HTTP_HEADER_LF; + if ($parts > 1) { + echo HTTP_HEADER_LF . '--' . HTTP_MULTIPART_BOUNDARY . '--' . HTTP_HEADER_LF; } // everything should be done here, exit (or return if testing) @@ -186,17 +190,18 @@ function http_rangeRequest($fh,$size,$mime){ * return true if there exists a gzip version of the uncompressed file * (samepath/samefilename.sameext.gz) created after the uncompressed file * - * @author Chris Smith <chris.eureka@jalakai.co.uk> - * * @param string $uncompressed_file * @return bool + * @author Chris Smith <chris.eureka@jalakai.co.uk> + * */ -function http_gzip_valid($uncompressed_file) { - if(!DOKU_HAS_GZIP) return false; +function http_gzip_valid($uncompressed_file) +{ + if (!DOKU_HAS_GZIP) return false; - $gzip = $uncompressed_file.'.gz'; + $gzip = $uncompressed_file . '.gz'; if (filemtime($gzip) < filemtime($uncompressed_file)) { // filemtime returns false (0) if file doesn't exist - return copy($uncompressed_file, 'compress.zlib://'.$gzip); + return copy($uncompressed_file, 'compress.zlib://' . $gzip); } return true; @@ -210,24 +215,25 @@ function http_gzip_valid($uncompressed_file) { * and the script is terminated. * * @param string $cache cache file name - * @param bool $cache_ok if cache can be used + * @param bool $cache_ok if cache can be used */ -function http_cached($cache, $cache_ok) { +function http_cached($cache, $cache_ok) +{ global $conf; // check cache age & handle conditional request // since the resource files are timestamped, we can use a long max age: 1 year header('Cache-Control: public, max-age=31536000'); header('Pragma: public'); - if($cache_ok){ + if ($cache_ok) { http_conditionalRequest(filemtime($cache)); - if($conf['allowdebug']) header("X-CacheUsed: $cache"); + if ($conf['allowdebug']) header("X-CacheUsed: $cache"); // finally send output if ($conf['gzip_output'] && http_gzip_valid($cache)) { header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); - readfile($cache.".gz"); + readfile($cache . ".gz"); } else { http_sendfile($cache); readfile($cache); @@ -244,20 +250,21 @@ function http_cached($cache, $cache_ok) { * @param string $file file name * @param string $content */ -function http_cached_finish($file, $content) { +function http_cached_finish($file, $content) +{ global $conf; // save cache file io_saveFile($file, $content); - if(DOKU_HAS_GZIP) io_saveFile("$file.gz",$content); + if (DOKU_HAS_GZIP) io_saveFile("$file.gz", $content); // finally send output if ($conf['gzip_output'] && DOKU_HAS_GZIP) { header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); - print gzencode($content,9,FORCE_GZIP); + echo gzencode($content, 9, FORCE_GZIP); } else { - print $content; + echo $content; } } @@ -266,7 +273,8 @@ function http_cached_finish($file, $content) { * * @return string */ -function http_get_raw_post_data() { +function http_get_raw_post_data() +{ static $postData = null; if ($postData === null) { $postData = file_get_contents('php://input'); @@ -279,13 +287,14 @@ function http_get_raw_post_data() { * * Inspired by CodeIgniter's set_status_header function * - * @param int $code + * @param int $code * @param string $text */ -function http_status($code = 200, $text = '') { +function http_status($code = 200, $text = '') +{ global $INPUT; - static $stati = array( + static $stati = [ 200 => 'OK', 201 => 'Created', 202 => 'Accepted', @@ -293,14 +302,12 @@ function http_status($code = 200, $text = '') { 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', - 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', - 400 => 'Bad Request', 401 => 'Unauthorized', 403 => 'Forbidden', @@ -318,25 +325,24 @@ function http_status($code = 200, $text = '') { 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', - 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported' - ); + ]; - if($text == '' && isset($stati[$code])) { + if ($text == '' && isset($stati[$code])) { $text = $stati[$code]; } $server_protocol = $INPUT->server->str('SERVER_PROTOCOL', false); - if(substr(php_sapi_name(), 0, 3) == 'cgi' || defined('SIMPLE_TEST')) { + if (substr(PHP_SAPI, 0, 3) == 'cgi' || defined('SIMPLE_TEST')) { header("Status: {$code} {$text}", true); - } elseif($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') { - header($server_protocol." {$code} {$text}", true, $code); + } elseif ($server_protocol == 'HTTP/1.1' || $server_protocol == 'HTTP/1.0') { + header($server_protocol . " {$code} {$text}", true, $code); } else { header("HTTP/1.1 {$code} {$text}", true, $code); } diff --git a/inc/indexer.php b/inc/indexer.php index ab02b8ea2..31b092e67 100644 --- a/inc/indexer.php +++ b/inc/indexer.php @@ -1,4 +1,5 @@ <?php + /** * Functions to create the fulltext search index * @@ -7,6 +8,7 @@ * @author Tom N Harris <tnharris@whoopdedo.org> */ +use dokuwiki\Utf8\Clean; use dokuwiki\Extension\Event; use dokuwiki\Search\Indexer; @@ -14,7 +16,7 @@ use dokuwiki\Search\Indexer; define('INDEXER_VERSION', 8); // set the minimum token length to use in the index (note, this doesn't apply to numeric tokens) -if (!defined('IDX_MINWORDLENGTH')) define('IDX_MINWORDLENGTH',2); +if (!defined('IDX_MINWORDLENGTH')) define('IDX_MINWORDLENGTH', 2); /** * Version of the indexer taking into consideration the external tokenizer. @@ -30,18 +32,19 @@ if (!defined('IDX_MINWORDLENGTH')) define('IDX_MINWORDLENGTH',2); * * @return int|string */ -function idx_get_version(){ +function idx_get_version() +{ static $indexer_version = null; if ($indexer_version == null) { $version = INDEXER_VERSION; // DokuWiki version is included for the convenience of plugins - $data = array('dokuwiki'=>$version); + $data = ['dokuwiki' => $version]; Event::createAndTrigger('INDEXER_VERSION_GET', $data, null, false); unset($data['dokuwiki']); // this needs to be first ksort($data); - foreach ($data as $plugin=>$vers) - $version .= '+'.$plugin.'='.$vers; + foreach ($data as $plugin => $vers) + $version .= '+' . $plugin . '=' . $vers; $indexer_version = $version; } return $indexer_version; @@ -56,12 +59,13 @@ function idx_get_version(){ * @param string $w * @return int */ -function wordlen($w){ +function wordlen($w) +{ $l = strlen($w); // If left alone, all chinese "words" will get put into w3.idx // So the "length" of a "word" is faked - if(preg_match_all('/[\xE2-\xEF]/',$w,$leadbytes)) { - foreach($leadbytes[0] as $b) + if (preg_match_all('/[\xE2-\xEF]/', $w, $leadbytes)) { + foreach ($leadbytes[0] as $b) $l += ord($b) - 0xE1; } return $l; @@ -74,7 +78,8 @@ function wordlen($w){ * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function idx_get_indexer() { +function idx_get_indexer() +{ static $Indexer; if (!isset($Indexer)) { $Indexer = new Indexer(); @@ -89,15 +94,16 @@ function idx_get_indexer() { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function & idx_get_stopwords() { +function & idx_get_stopwords() +{ static $stopwords = null; if (is_null($stopwords)) { global $conf; - $swfile = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt'; - if(file_exists($swfile)){ + $swfile = DOKU_INC . 'inc/lang/' . $conf['lang'] . '/stopwords.txt'; + if (file_exists($swfile)) { $stopwords = file($swfile, FILE_IGNORE_NEW_LINES); - }else{ - $stopwords = array(); + } else { + $stopwords = []; } } return $stopwords; @@ -115,18 +121,19 @@ function & idx_get_stopwords() { * * @author Tom N Harris <tnharris@whoopdedo.org> */ -function idx_addPage($page, $verbose=false, $force=false) { - $idxtag = metaFN($page,'.indexed'); +function idx_addPage($page, $verbose = false, $force = false) +{ + $idxtag = metaFN($page, '.indexed'); // check if page was deleted but is still in the index if (!page_exists($page)) { if (!file_exists($idxtag)) { - if ($verbose) print("Indexer: $page does not exist, ignoring".DOKU_LF); + if ($verbose) echo "Indexer: $page does not exist, ignoring" . DOKU_LF; return false; } $Indexer = idx_get_indexer(); $result = $Indexer->deletePage($page); if ($result === "locked") { - if ($verbose) print("Indexer: locked".DOKU_LF); + if ($verbose) echo "Indexer: locked" . DOKU_LF; return false; } @unlink($idxtag); @@ -134,11 +141,11 @@ function idx_addPage($page, $verbose=false, $force=false) { } // check if indexing needed - if(!$force && file_exists($idxtag)){ - if(trim(io_readFile($idxtag)) == idx_get_version()){ + if (!$force && file_exists($idxtag)) { + if (trim(io_readFile($idxtag)) == idx_get_version()) { $last = @filemtime($idxtag); - if($last > @filemtime(wikiFN($page))){ - if ($verbose) print("Indexer: index for $page up to date".DOKU_LF); + if ($last > @filemtime(wikiFN($page))) { + if ($verbose) echo "Indexer: index for $page up to date" . DOKU_LF; return false; } } @@ -151,35 +158,33 @@ function idx_addPage($page, $verbose=false, $force=false) { $Indexer = idx_get_indexer(); $result = $Indexer->deletePage($page); if ($result === "locked") { - if ($verbose) print("Indexer: locked".DOKU_LF); + if ($verbose) echo "Indexer: locked" . DOKU_LF; return false; } @unlink($idxtag); } - if ($verbose) print("Indexer: index disabled for $page".DOKU_LF); + if ($verbose) echo "Indexer: index disabled for $page" . DOKU_LF; return $result; } $Indexer = idx_get_indexer(); $pid = $Indexer->getPID($page); if ($pid === false) { - if ($verbose) print("Indexer: getting the PID failed for $page".DOKU_LF); + if ($verbose) echo "Indexer: getting the PID failed for $page" . DOKU_LF; return false; } $body = ''; - $metadata = array(); + $metadata = []; $metadata['title'] = p_get_metadata($page, 'title', METADATA_RENDER_UNLIMITED); if (($references = p_get_metadata($page, 'relation references', METADATA_RENDER_UNLIMITED)) !== null) $metadata['relation_references'] = array_keys($references); - else - $metadata['relation_references'] = array(); + else $metadata['relation_references'] = []; if (($media = p_get_metadata($page, 'relation media', METADATA_RENDER_UNLIMITED)) !== null) $metadata['relation_media'] = array_keys($media); - else - $metadata['relation_media'] = array(); + else $metadata['relation_media'] = []; - $data = compact('page', 'body', 'metadata', 'pid'); + $data = ['page' => $page, 'body' => $body, 'metadata' => $metadata, 'pid' => $pid]; $evt = new Event('INDEXER_PAGE_ADD', $data); if ($evt->advise_before()) $data['body'] = $data['body'] . " " . rawWiki($page); $evt->advise_after(); @@ -188,22 +193,22 @@ function idx_addPage($page, $verbose=false, $force=false) { $result = $Indexer->addPageWords($page, $body); if ($result === "locked") { - if ($verbose) print("Indexer: locked".DOKU_LF); + if ($verbose) echo "Indexer: locked" . DOKU_LF; return false; } if ($result) { $result = $Indexer->addMetaKeys($page, $metadata); if ($result === "locked") { - if ($verbose) print("Indexer: locked".DOKU_LF); + if ($verbose) echo "Indexer: locked" . DOKU_LF; return false; } } if ($result) - io_saveFile(metaFN($page,'.indexed'), idx_get_version()); + io_saveFile(metaFN($page, '.indexed'), idx_get_version()); if ($verbose) { - print("Indexer: finished".DOKU_LF); + echo "Indexer: finished" . DOKU_LF; return true; } return $result; @@ -221,7 +226,8 @@ function idx_addPage($page, $verbose=false, $force=false) { * @param array $words list of words to search for * @return array list of pages found, associated with the search terms */ -function idx_lookup(&$words) { +function idx_lookup(&$words) +{ $Indexer = idx_get_indexer(); return $Indexer->lookup($words); } @@ -234,7 +240,8 @@ function idx_lookup(&$words) { * * @return array */ -function idx_tokenizer($string, $wc=false) { +function idx_tokenizer($string, $wc = false) +{ $Indexer = idx_get_indexer(); return $Indexer->tokenizer($string, $wc); } @@ -250,10 +257,11 @@ function idx_tokenizer($string, $wc=false) { * @param string $suffix * @return array */ -function idx_getIndex($idx, $suffix) { +function idx_getIndex($idx, $suffix) +{ global $conf; - $fn = $conf['indexdir'].'/'.$idx.$suffix.'.idx'; - if (!file_exists($fn)) return array(); + $fn = $conf['indexdir'] . '/' . $idx . $suffix . '.idx'; + if (!file_exists($fn)) return []; return file($fn); } @@ -267,20 +275,23 @@ function idx_getIndex($idx, $suffix) { * * @return array */ -function idx_listIndexLengths() { +function idx_listIndexLengths() +{ global $conf; // testing what we have to do, create a cache file or not. if ($conf['readdircache'] == 0) { $docache = false; } else { clearstatcache(); - if (file_exists($conf['indexdir'].'/lengths.idx') - && (time() < @filemtime($conf['indexdir'].'/lengths.idx') + $conf['readdircache'])) { + if ( + file_exists($conf['indexdir'] . '/lengths.idx') + && (time() < @filemtime($conf['indexdir'] . '/lengths.idx') + $conf['readdircache']) + ) { if ( - ($lengths = @file($conf['indexdir'].'/lengths.idx', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)) + ($lengths = @file($conf['indexdir'] . '/lengths.idx', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)) !== false ) { - $idx = array(); + $idx = []; foreach ($lengths as $length) { $idx[] = (int)$length; } @@ -293,8 +304,8 @@ function idx_listIndexLengths() { if ($conf['readdircache'] == 0 || $docache) { $dir = @opendir($conf['indexdir']); if ($dir === false) - return array(); - $idx = array(); + return []; + $idx = []; while (($f = readdir($dir)) !== false) { if (substr($f, 0, 1) == 'i' && substr($f, -4) == '.idx') { $i = substr($f, 1, -4); @@ -306,14 +317,14 @@ function idx_listIndexLengths() { sort($idx); // save this in a file if ($docache) { - $handle = @fopen($conf['indexdir'].'/lengths.idx', 'w'); + $handle = @fopen($conf['indexdir'] . '/lengths.idx', 'w'); @fwrite($handle, implode("\n", $idx)); @fclose($handle); } return $idx; } - return array(); + return []; } /** @@ -327,19 +338,20 @@ function idx_listIndexLengths() { * @param array|int $filter * @return array */ -function idx_indexLengths($filter) { +function idx_indexLengths($filter) +{ global $conf; - $idx = array(); + $idx = []; if (is_array($filter)) { // testing if index files exist only - $path = $conf['indexdir']."/i"; - foreach ($filter as $key => $value) { - if (file_exists($path.$key.'.idx')) + $path = $conf['indexdir'] . "/i"; + foreach (array_keys($filter) as $key) { + if (file_exists($path . $key . '.idx')) $idx[] = $key; } } else { $lengths = idx_listIndexLengths(); - foreach ($lengths as $key => $length) { + foreach ($lengths as $length) { // keep all the values equal or superior if ((int)$length >= (int)$filter) $idx[] = $length; @@ -359,8 +371,9 @@ function idx_indexLengths($filter) { * @param string $name * @return string */ -function idx_cleanName($name) { - $name = \dokuwiki\Utf8\Clean::romanize(trim((string)$name)); +function idx_cleanName($name) +{ + $name = Clean::romanize(trim((string)$name)); $name = preg_replace('#[ \./\\:-]+#', '_', $name); $name = preg_replace('/[^A-Za-z0-9_]/', '', $name); return strtolower($name); diff --git a/inc/infoutils.php b/inc/infoutils.php index 0044f00b4..6acfeef37 100644 --- a/inc/infoutils.php +++ b/inc/infoutils.php @@ -1,4 +1,5 @@ <?php + /** * Information and debugging functions * @@ -6,14 +7,18 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Extension\AuthPlugin; +use dokuwiki\Extension\Event; +use dokuwiki\Utf8\PhpString; +use dokuwiki\Debug\DebugHelper; use dokuwiki\HTTP\DokuHTTPClient; use dokuwiki\Logger; -if(!defined('DOKU_MESSAGEURL')){ - if(in_array('ssl', stream_get_transports())) { - define('DOKU_MESSAGEURL','https://update.dokuwiki.org/check/'); - }else{ - define('DOKU_MESSAGEURL','http://update.dokuwiki.org/check/'); +if (!defined('DOKU_MESSAGEURL')) { + if (in_array('ssl', stream_get_transports())) { + define('DOKU_MESSAGEURL', 'https://update.dokuwiki.org/check/'); + } else { + define('DOKU_MESSAGEURL', 'http://update.dokuwiki.org/check/'); } } @@ -22,40 +27,47 @@ if(!defined('DOKU_MESSAGEURL')){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function checkUpdateMessages(){ +function checkUpdateMessages() +{ global $conf; global $INFO; global $updateVersion; - if(!$conf['updatecheck']) return; - if($conf['useacl'] && !$INFO['ismanager']) return; + if (!$conf['updatecheck']) return; + if ($conf['useacl'] && !$INFO['ismanager']) return; $cf = getCacheName($updateVersion, '.updmsg'); $lm = @filemtime($cf); $is_http = substr(DOKU_MESSAGEURL, 0, 5) != 'https'; // check if new messages needs to be fetched - if($lm < time()-(60*60*24) || $lm < @filemtime(DOKU_INC.DOKU_SCRIPT)){ + if ($lm < time() - (60 * 60 * 24) || $lm < @filemtime(DOKU_INC . DOKU_SCRIPT)) { @touch($cf); - Logger::debug("checkUpdateMessages(): downloading messages to ".$cf.($is_http?' (without SSL)':' (with SSL)')); + Logger::debug( + sprintf( + 'checkUpdateMessages(): downloading messages to %s%s', + $cf, + $is_http ? ' (without SSL)' : ' (with SSL)' + ) + ); $http = new DokuHTTPClient(); $http->timeout = 12; - $resp = $http->get(DOKU_MESSAGEURL.$updateVersion); - if(is_string($resp) && ($resp == "" || substr(trim($resp), -1) == '%')) { + $resp = $http->get(DOKU_MESSAGEURL . $updateVersion); + if (is_string($resp) && ($resp == "" || substr(trim($resp), -1) == '%')) { // basic sanity check that this is either an empty string response (ie "no messages") // or it looks like one of our messages, not WiFi login or other interposed response - io_saveFile($cf,$resp); + io_saveFile($cf, $resp); } else { Logger::debug("checkUpdateMessages(): unexpected HTTP response received", $http->error); } - }else{ + } else { Logger::debug("checkUpdateMessages(): messages up to date"); } $data = io_readFile($cf); // show messages through the usual message mechanism - $msgs = explode("\n%\n",$data); - foreach($msgs as $msg){ - if($msg) msg($msg,2); + $msgs = explode("\n%\n", $data); + foreach ($msgs as $msg) { + if ($msg) msg($msg, 2); } } @@ -65,14 +77,15 @@ function checkUpdateMessages(){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function getVersionData(){ - $version = array(); +function getVersionData() +{ + $version = []; //import version string - if(file_exists(DOKU_INC.'VERSION')){ + if (file_exists(DOKU_INC . 'VERSION')) { //official release - $version['date'] = trim(io_readFile(DOKU_INC.'VERSION')); + $version['date'] = trim(io_readFile(DOKU_INC . 'VERSION')); $version['type'] = 'Release'; - }elseif(is_dir(DOKU_INC.'.git')){ + } elseif (is_dir(DOKU_INC . '.git')) { $version['type'] = 'Git'; $version['date'] = 'unknown'; @@ -80,7 +93,7 @@ function getVersionData(){ if (function_exists('shell_exec')) { $commitInfo = shell_exec("git log -1 --pretty=format:'%h %cd' --date=short"); if ($commitInfo) { - list($version['sha'], $date) = explode(' ', $commitInfo); + [$version['sha'], $date] = explode(' ', $commitInfo); $version['date'] = hsc($date); return $version; } @@ -122,9 +135,9 @@ function getVersionData(){ } } } - }else{ + } else { global $updateVersion; - $version['date'] = 'update version '.$updateVersion; + $version['date'] = 'update version ' . $updateVersion; $version['type'] = 'snapshot?'; } return $version; @@ -135,9 +148,10 @@ function getVersionData(){ * * @author Anika Henke <anika@selfthinker.org> */ -function getVersion(){ +function getVersion() +{ $version = getVersionData(); - $sha = !empty($version['sha']) ? ' (' . $version['sha'] . ')' : ''; + $sha = empty($version['sha']) ? '' : ' (' . $version['sha'] . ')'; return $version['type'] . ' ' . $version['date'] . $sha; } @@ -146,37 +160,35 @@ function getVersion(){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function check(){ +function check() +{ global $conf; global $INFO; /* @var Input $INPUT */ global $INPUT; - if ($INFO['isadmin'] || $INFO['ismanager']){ - msg('DokuWiki version: '.getVersion(),1); - - if(version_compare(phpversion(),'7.4.0','<')){ - msg('Your PHP version is too old ('.phpversion().' vs. 7.4+ needed)',-1); - }else{ - msg('PHP version '.phpversion(),1); - } - } else { - if(version_compare(phpversion(),'7.4.0','<')){ - msg('Your PHP version is too old',-1); + if ($INFO['isadmin'] || $INFO['ismanager']) { + msg('DokuWiki version: ' . getVersion(), 1); + if (version_compare(phpversion(), '7.4.0', '<')) { + msg('Your PHP version is too old (' . phpversion() . ' vs. 7.4+ needed)', -1); + } else { + msg('PHP version ' . phpversion(), 1); } + } elseif (version_compare(phpversion(), '7.4.0', '<')) { + msg('Your PHP version is too old', -1); } - $mem = (int) php_to_byte(ini_get('memory_limit')); - if($mem){ + $mem = php_to_byte(ini_get('memory_limit')); + if ($mem) { if ($mem === -1) { msg('PHP memory is unlimited', 1); - } else if ($mem < 16777216) { + } elseif ($mem < 16_777_216) { msg('PHP is limited to less than 16MB RAM (' . filesize_h($mem) . '). Increase memory_limit in php.ini', -1); - } else if ($mem < 20971520) { + } elseif ($mem < 20_971_520) { msg('PHP is limited to less than 20MB RAM (' . filesize_h($mem) . '), you might encounter problems with bigger pages. Increase memory_limit in php.ini', -1); - } else if ($mem < 33554432) { + } elseif ($mem < 33_554_432) { msg('PHP is limited to less than 32MB RAM (' . filesize_h($mem) . '), but that should be enough in most cases. If not, increase memory_limit in php.ini', 0); } else { @@ -184,55 +196,53 @@ function check(){ } } - if(is_writable($conf['changelog'])){ - msg('Changelog is writable',1); - }else{ - if (file_exists($conf['changelog'])) { - msg('Changelog is not writable',-1); - } + if (is_writable($conf['changelog'])) { + msg('Changelog is writable', 1); + } elseif (file_exists($conf['changelog'])) { + msg('Changelog is not writable', -1); } if (isset($conf['changelog_old']) && file_exists($conf['changelog_old'])) { msg('Old changelog exists', 0); } - if (file_exists($conf['changelog'].'_failed')) { + if (file_exists($conf['changelog'] . '_failed')) { msg('Importing old changelog failed', -1); - } else if (file_exists($conf['changelog'].'_importing')) { + } elseif (file_exists($conf['changelog'] . '_importing')) { msg('Importing old changelog now.', 0); - } else if (file_exists($conf['changelog'].'_import_ok')) { + } elseif (file_exists($conf['changelog'] . '_import_ok')) { msg('Old changelog imported', 1); if (!plugin_isdisabled('importoldchangelog')) { msg('Importoldchangelog plugin not disabled after import', -1); } } - if(is_writable(DOKU_CONF)){ - msg('conf directory is writable',1); - }else{ - msg('conf directory is not writable',-1); + if (is_writable(DOKU_CONF)) { + msg('conf directory is writable', 1); + } else { + msg('conf directory is not writable', -1); } - if($conf['authtype'] == 'plain'){ + if ($conf['authtype'] == 'plain') { global $config_cascade; - if(is_writable($config_cascade['plainauth.users']['default'])){ - msg('conf/users.auth.php is writable',1); - }else{ - msg('conf/users.auth.php is not writable',0); + if (is_writable($config_cascade['plainauth.users']['default'])) { + msg('conf/users.auth.php is writable', 1); + } else { + msg('conf/users.auth.php is not writable', 0); } } - if(function_exists('mb_strpos')){ - if(defined('UTF8_NOMBSTRING')){ - msg('mb_string extension is available but will not be used',0); - }else{ - msg('mb_string extension is available and will be used',1); - if(ini_get('mbstring.func_overload') != 0){ - msg('mb_string function overloading is enabled, this will cause problems and should be disabled',-1); + if (function_exists('mb_strpos')) { + if (defined('UTF8_NOMBSTRING')) { + msg('mb_string extension is available but will not be used', 0); + } else { + msg('mb_string extension is available and will be used', 1); + if (ini_get('mbstring.func_overload') != 0) { + msg('mb_string function overloading is enabled, this will cause problems and should be disabled', -1); } } - }else{ - msg('mb_string extension not available - PHP only replacements will be used',0); + } else { + msg('mb_string extension not available - PHP only replacements will be used', 0); } if (!UTF8_PREGSUPPORT) { @@ -243,29 +253,33 @@ function check(){ } $loc = setlocale(LC_ALL, 0); - if(!$loc){ - msg('No valid locale is set for your PHP setup. You should fix this',-1); - }elseif(stripos($loc,'utf') === false){ - msg('Your locale <code>'.hsc($loc).'</code> seems not to be a UTF-8 locale, - you should fix this if you encounter problems.',0); - }else{ - msg('Valid locale '.hsc($loc).' found.', 1); + if (!$loc) { + msg('No valid locale is set for your PHP setup. You should fix this', -1); + } elseif (stripos($loc, 'utf') === false) { + msg('Your locale <code>' . hsc($loc) . '</code> seems not to be a UTF-8 locale, + you should fix this if you encounter problems.', 0); + } else { + msg('Valid locale ' . hsc($loc) . ' found.', 1); } - if($conf['allowdebug']){ - msg('Debugging support is enabled. If you don\'t need it you should set $conf[\'allowdebug\'] = 0',-1); - }else{ - msg('Debugging support is disabled',1); + if ($conf['allowdebug']) { + msg('Debugging support is enabled. If you don\'t need it you should set $conf[\'allowdebug\'] = 0', -1); + } else { + msg('Debugging support is disabled', 1); } - if(!empty($INFO['userinfo']['name'])){ - msg('You are currently logged in as '.$INPUT->server->str('REMOTE_USER').' ('.$INFO['userinfo']['name'].')',0); - msg('You are part of the groups '.implode(', ', $INFO['userinfo']['grps']),0); - }else{ - msg('You are currently not logged in',0); + if (!empty($INFO['userinfo']['name'])) { + msg(sprintf( + "You are currently logged in as %s (%s)", + $INPUT->server->str('REMOTE_USER'), + $INFO['userinfo']['name'] + ), 0); + msg('You are part of the groups ' . implode(', ', $INFO['userinfo']['grps']), 0); + } else { + msg('You are currently not logged in', 0); } - msg('Your current permission for this page is '.$INFO['perm'],0); + msg('Your current permission for this page is ' . $INFO['perm'], 0); if (file_exists($INFO['filepath']) && is_writable($INFO['filepath'])) { msg('The current page is writable by the webserver', 1); @@ -285,32 +299,33 @@ function check(){ $lengths = idx_listIndexLengths(); $index_corrupted = false; foreach ($lengths as $length) { - if (count(idx_getIndex('w', $length)) != count(idx_getIndex('i', $length))) { + if (count(idx_getIndex('w', $length)) !== count(idx_getIndex('i', $length))) { $index_corrupted = true; break; } } foreach (idx_getIndex('metadata', '') as $index) { - if (count(idx_getIndex($index.'_w', '')) != count(idx_getIndex($index.'_i', ''))) { + if (count(idx_getIndex($index . '_w', '')) !== count(idx_getIndex($index . '_i', ''))) { $index_corrupted = true; break; } } - if($index_corrupted) { + if ($index_corrupted) { msg( 'The search index is corrupted. It might produce wrong results and most probably needs to be rebuilt. See - <a href="http://www.dokuwiki.org/faq:searchindex">faq:searchindex</a> - for ways to rebuild the search index.', -1 + <a href="https://www.dokuwiki.org/faq:searchindex">faq:searchindex</a> + for ways to rebuild the search index.', + -1 ); - } elseif(!empty($lengths)) { + } elseif (!empty($lengths)) { msg('The search index seems to be working', 1); } else { msg( 'The search index is empty. See - <a href="http://www.dokuwiki.org/faq:searchindex">faq:searchindex</a> + <a href="https://www.dokuwiki.org/faq:searchindex">faq:searchindex</a> for help on how to fix the search index. If the default indexer isn\'t used or the wiki is actually empty this is normal.' ); @@ -320,20 +335,19 @@ function check(){ $http = new DokuHTTPClient(); $http->max_redirect = 0; $http->timeout = 3; - $http->sendRequest('http://www.dokuwiki.org', '', 'HEAD'); + $http->sendRequest('https://www.dokuwiki.org', '', 'HEAD'); $now = time(); - if(isset($http->resp_headers['date'])) { + if (isset($http->resp_headers['date'])) { $time = strtotime($http->resp_headers['date']); $diff = $time - $now; - if(abs($diff) < 4) { + if (abs($diff) < 4) { msg("Server time seems to be okay. Diff: {$diff}s", 1); } else { msg("Your server's clock seems to be out of sync! Consider configuring a sync with a NTP server. Diff: {$diff}s"); } } - } /** @@ -345,14 +359,15 @@ function check(){ * * Triggers INFOUTIL_MSG_SHOW * - * @see html_msgarea() * @param string $message - * @param int $lvl -1 = error, 0 = info, 1 = success, 2 = notify - * @param string $line line number - * @param string $file file number - * @param int $allow who's allowed to see the message, see MSG_* constants + * @param int $lvl -1 = error, 0 = info, 1 = success, 2 = notify + * @param string $line line number + * @param string $file file number + * @param int $allow who's allowed to see the message, see MSG_* constants + * @see html_msgarea() */ -function msg($message,$lvl=0,$line='',$file='',$allow=MSG_PUBLIC){ +function msg($message, $lvl = 0, $line = '', $file = '', $allow = MSG_PUBLIC) +{ global $MSG, $MSG_shown; static $errors = [ -1 => 'error', @@ -369,21 +384,21 @@ function msg($message,$lvl=0,$line='',$file='',$allow=MSG_PUBLIC){ 'file' => $file, ]; - $evt = new \dokuwiki\Extension\Event('INFOUTIL_MSG_SHOW', $msgdata); + $evt = new Event('INFOUTIL_MSG_SHOW', $msgdata); if ($evt->advise_before()) { /* Show msg normally - event could suppress message show */ - if($msgdata['line'] || $msgdata['file']) { - $basename = \dokuwiki\Utf8\PhpString::basename($msgdata['file']); - $msgdata['msg'] .=' ['.$basename.':'.$msgdata['line'].']'; + if ($msgdata['line'] || $msgdata['file']) { + $basename = PhpString::basename($msgdata['file']); + $msgdata['msg'] .= ' [' . $basename . ':' . $msgdata['line'] . ']'; } - if(!isset($MSG)) $MSG = array(); + if (!isset($MSG)) $MSG = []; $MSG[] = $msgdata; - if(isset($MSG_shown) || headers_sent()){ - if(function_exists('html_msgarea')){ + if (isset($MSG_shown) || headers_sent()) { + if (function_exists('html_msgarea')) { html_msgarea(); - }else{ - print "ERROR(".$msgdata['lvl'].") ".$msgdata['msg']."\n"; + } else { + echo "ERROR(" . $msgdata['lvl'] . ") " . $msgdata['msg'] . "\n"; } unset($GLOBALS['MSG']); } @@ -391,27 +406,28 @@ function msg($message,$lvl=0,$line='',$file='',$allow=MSG_PUBLIC){ $evt->advise_after(); unset($evt); } + /** * Determine whether the current user is allowed to view the message * in the $msg data structure * - * @param $msg array dokuwiki msg structure - * msg => string, the message - * lvl => int, level of the message (see msg() function) - * allow => int, flag used to determine who is allowed to see the message - * see MSG_* constants + * @param array $msg dokuwiki msg structure: + * msg => string, the message; + * lvl => int, level of the message (see msg() function); + * allow => int, flag used to determine who is allowed to see the message, see MSG_* constants * @return bool */ -function info_msg_allowed($msg){ +function info_msg_allowed($msg) +{ global $INFO, $auth; // is the message public? - everyone and anyone can see it if (empty($msg['allow']) || ($msg['allow'] == MSG_PUBLIC)) return true; // restricted msg, but no authentication - if (empty($auth)) return false; + if (!$auth instanceof AuthPlugin) return false; - switch ($msg['allow']){ + switch ($msg['allow']) { case MSG_USERS_ONLY: return !empty($INFO['userinfo']); @@ -422,12 +438,12 @@ function info_msg_allowed($msg){ return $INFO['isadmin']; default: - trigger_error('invalid msg allow restriction. msg="'.$msg['msg'].'" allow='.$msg['allow'].'"', - E_USER_WARNING); + trigger_error( + 'invalid msg allow restriction. msg="' . $msg['msg'] . '" allow=' . $msg['allow'] . '"', + E_USER_WARNING + ); return $INFO['isadmin']; } - - return false; } /** @@ -435,19 +451,20 @@ function info_msg_allowed($msg){ * * little function to print the content of a var * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $msg * @param bool $hidden + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function dbg($msg,$hidden=false){ - if($hidden){ +function dbg($msg, $hidden = false) +{ + if ($hidden) { echo "<!--\n"; print_r($msg); echo "\n-->"; - }else{ + } else { echo '<pre class="dbg">'; - echo hsc(print_r($msg,true)); + echo hsc(print_r($msg, true)); echo '</pre>'; } } @@ -455,22 +472,25 @@ function dbg($msg,$hidden=false){ /** * Print info to debug log file * - * @author Andreas Gohr <andi@splitbrain.org> - * @deprecated 2020-08-13 * @param string $msg * @param string $header + * + * @author Andreas Gohr <andi@splitbrain.org> + * @deprecated 2020-08-13 */ -function dbglog($msg,$header=''){ +function dbglog($msg, $header = '') +{ dbg_deprecated('\\dokuwiki\\Logger'); // was the msg as single line string? use it as header - if($header === '' && is_string($msg) && strpos($msg, "\n") === false) { + if ($header === '' && is_string($msg) && strpos($msg, "\n") === false) { $header = $msg; $msg = ''; } Logger::getInstance(Logger::LOG_DEBUG)->log( - $header, $msg + $header, + $msg ); } @@ -480,8 +500,9 @@ function dbglog($msg,$header=''){ * @param string $alternative The function or method that should be used instead * @triggers INFO_DEPRECATION_LOG */ -function dbg_deprecated($alternative = '') { - \dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction($alternative, 2); +function dbg_deprecated($alternative = '') +{ + DebugHelper::dbgDeprecatedFunction($alternative, 2); } /** @@ -489,7 +510,8 @@ function dbg_deprecated($alternative = '') { * * @author Gary Owen <gary_owen@bigfoot.com> */ -function dbg_backtrace(){ +function dbg_backtrace() +{ // Get backtrace $backtrace = debug_backtrace(); @@ -497,33 +519,35 @@ function dbg_backtrace(){ array_shift($backtrace); // Iterate backtrace - $calls = array(); + $calls = []; $depth = count($backtrace) - 1; foreach ($backtrace as $i => $call) { $location = $call['file'] . ':' . $call['line']; $function = (isset($call['class'])) ? $call['class'] . $call['type'] . $call['function'] : $call['function']; - $params = array(); - if (isset($call['args'])){ - foreach($call['args'] as $arg){ - if(is_object($arg)){ - $params[] = '[Object '.get_class($arg).']'; - }elseif(is_array($arg)){ + $params = []; + if (isset($call['args'])) { + foreach ($call['args'] as $arg) { + if (is_object($arg)) { + $params[] = '[Object ' . get_class($arg) . ']'; + } elseif (is_array($arg)) { $params[] = '[Array]'; - }elseif(is_null($arg)){ + } elseif (is_null($arg)) { $params[] = '[NULL]'; - }else{ - $params[] = (string) '"'.$arg.'"'; + } else { + $params[] = '"' . $arg . '"'; } } } - $params = implode(', ',$params); + $params = implode(', ', $params); - $calls[$depth - $i] = sprintf('%s(%s) called at %s', - $function, - str_replace("\n", '\n', $params), - $location); + $calls[$depth - $i] = sprintf( + '%s(%s) called at %s', + $function, + str_replace("\n", '\n', $params), + $location + ); } ksort($calls); @@ -536,16 +560,17 @@ function dbg_backtrace(){ * This is used to remove passwords, mail addresses and similar data from the * debug output * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $data + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function debug_guard(&$data){ - foreach($data as $key => $value){ - if(preg_match('/(notify|pass|auth|secret|ftp|userinfo|token|buid|mail|proxy)/i',$key)){ +function debug_guard(&$data) +{ + foreach ($data as $key => $value) { + if (preg_match('/(notify|pass|auth|secret|ftp|userinfo|token|buid|mail|proxy)/i', $key)) { $data[$key] = '***'; continue; } - if(is_array($value)) debug_guard($data[$key]); + if (is_array($value)) debug_guard($data[$key]); } } diff --git a/inc/init.php b/inc/init.php index 06791e03c..467d4eb7f 100644 --- a/inc/init.php +++ b/inc/init.php @@ -1,8 +1,12 @@ <?php + /** * Initialize some defaults needed for DokuWiki */ +use dokuwiki\Extension\PluginController; +use dokuwiki\ErrorHandler; +use dokuwiki\Input\Input; use dokuwiki\Extension\Event; use dokuwiki\Extension\EventHandler; @@ -13,29 +17,30 @@ use dokuwiki\Extension\EventHandler; * * @return mixed */ -function delta_time($start=0) { - return microtime(true)-((float)$start); +function delta_time($start = 0) +{ + return microtime(true) - ((float)$start); } define('DOKU_START_TIME', delta_time()); global $config_cascade; -$config_cascade = array(); +$config_cascade = []; // if available load a preload config file -$preload = fullpath(dirname(__FILE__)).'/preload.php'; +$preload = fullpath(__DIR__) . '/preload.php'; if (file_exists($preload)) include($preload); // define the include path -if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/'); +if (!defined('DOKU_INC')) define('DOKU_INC', fullpath(__DIR__ . '/../') . '/'); // define Plugin dir -if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); +if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); // define config path (packagers may want to change this to /etc/dokuwiki/) -if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/'); +if (!defined('DOKU_CONF')) define('DOKU_CONF', DOKU_INC . 'conf/'); // check for error reporting override or set error reporting to sane values -if (!defined('DOKU_E_LEVEL') && file_exists(DOKU_CONF.'report_e_all')) { +if (!defined('DOKU_E_LEVEL') && file_exists(DOKU_CONF . 'report_e_all')) { define('DOKU_E_LEVEL', E_ALL); } if (!defined('DOKU_E_LEVEL')) { @@ -49,26 +54,26 @@ header('Vary: Cookie'); // init memory caches global $cache_revinfo; - $cache_revinfo = array(); + $cache_revinfo = []; global $cache_wikifn; - $cache_wikifn = array(); + $cache_wikifn = []; global $cache_cleanid; - $cache_cleanid = array(); + $cache_cleanid = []; global $cache_authname; - $cache_authname = array(); + $cache_authname = []; global $cache_metadata; - $cache_metadata = array(); + $cache_metadata = []; // always include 'inc/config_cascade.php' // previously in preload.php set fields of $config_cascade will be merged with the defaults -include(DOKU_INC.'inc/config_cascade.php'); +include(DOKU_INC . 'inc/config_cascade.php'); //prepare config array() global $conf; -$conf = array(); +$conf = []; // load the global config file(s) -foreach (array('default','local','protected') as $config_group) { +foreach (['default', 'local', 'protected'] as $config_group) { if (empty($config_cascade['main'][$config_group])) continue; foreach ($config_cascade['main'][$config_group] as $config_file) { if (file_exists($config_file)) { @@ -79,13 +84,13 @@ foreach (array('default','local','protected') as $config_group) { //prepare license array() global $license; -$license = array(); +$license = []; // load the license file(s) -foreach (array('default','local') as $config_group) { +foreach (['default', 'local'] as $config_group) { if (empty($config_cascade['license'][$config_group])) continue; foreach ($config_cascade['license'][$config_group] as $config_file) { - if(file_exists($config_file)){ + if (file_exists($config_file)) { include($config_file); } } @@ -95,45 +100,45 @@ foreach (array('default','local') as $config_group) { date_default_timezone_set(@date_default_timezone_get()); // define baseURL -if(!defined('DOKU_REL')) define('DOKU_REL',getBaseURL(false)); -if(!defined('DOKU_URL')) define('DOKU_URL',getBaseURL(true)); -if(!defined('DOKU_BASE')){ - if($conf['canonical']){ - define('DOKU_BASE',DOKU_URL); - }else{ - define('DOKU_BASE',DOKU_REL); +if (!defined('DOKU_REL')) define('DOKU_REL', getBaseURL(false)); +if (!defined('DOKU_URL')) define('DOKU_URL', getBaseURL(true)); +if (!defined('DOKU_BASE')) { + if ($conf['canonical']) { + define('DOKU_BASE', DOKU_URL); + } else { + define('DOKU_BASE', DOKU_REL); } } // define whitespace -if(!defined('NL')) define ('NL',"\n"); -if(!defined('DOKU_LF')) define ('DOKU_LF',"\n"); -if(!defined('DOKU_TAB')) define ('DOKU_TAB',"\t"); +if (!defined('NL')) define('NL', "\n"); +if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); +if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); // define cookie and session id, append server port when securecookie is configured FS#1664 if (!defined('DOKU_COOKIE')) { - $serverPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : ''; + $serverPort = $_SERVER['SERVER_PORT'] ?? ''; define('DOKU_COOKIE', 'DW' . md5(DOKU_REL . (($conf['securecookie']) ? $serverPort : ''))); unset($serverPort); } // define main script -if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php'); +if (!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT', 'doku.php'); -if(!defined('DOKU_TPL')) { +if (!defined('DOKU_TPL')) { /** * @deprecated 2012-10-13 replaced by more dynamic method * @see tpl_basedir() */ - define('DOKU_TPL', DOKU_BASE.'lib/tpl/'.$conf['template'].'/'); + define('DOKU_TPL', DOKU_BASE . 'lib/tpl/' . $conf['template'] . '/'); } -if(!defined('DOKU_TPLINC')) { +if (!defined('DOKU_TPLINC')) { /** * @deprecated 2012-10-13 replaced by more dynamic method * @see tpl_incdir() */ - define('DOKU_TPLINC', DOKU_INC.'lib/tpl/'.$conf['template'].'/'); + define('DOKU_TPLINC', DOKU_INC . 'lib/tpl/' . $conf['template'] . '/'); } // make session rewrites XHTML compliant @@ -146,43 +151,45 @@ if(!defined('DOKU_TPLINC')) { @ini_set('pcre.backtrack_limit', '20971520'); // enable gzip compression if supported -$httpAcceptEncoding = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : ''; +$httpAcceptEncoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? ''; $conf['gzip_output'] &= (strpos($httpAcceptEncoding, 'gzip') !== false); global $ACT; -if ($conf['gzip_output'] && +if ( + $conf['gzip_output'] && !defined('DOKU_DISABLE_GZIP_OUTPUT') && function_exists('ob_gzhandler') && // Disable compression when a (compressed) sitemap might be delivered // See https://bugs.dokuwiki.org/index.php?do=details&task_id=2576 - $ACT != 'sitemap') { + $ACT != 'sitemap' +) { ob_start('ob_gzhandler'); } // init session -if(!headers_sent() && !defined('NOSESSION')) { - if(!defined('DOKU_SESSION_NAME')) define ('DOKU_SESSION_NAME', "DokuWiki"); - if(!defined('DOKU_SESSION_LIFETIME')) define ('DOKU_SESSION_LIFETIME', 0); - if(!defined('DOKU_SESSION_PATH')) { +if (!headers_sent() && !defined('NOSESSION')) { + if (!defined('DOKU_SESSION_NAME')) define('DOKU_SESSION_NAME', "DokuWiki"); + if (!defined('DOKU_SESSION_LIFETIME')) define('DOKU_SESSION_LIFETIME', 0); + if (!defined('DOKU_SESSION_PATH')) { $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; - define ('DOKU_SESSION_PATH', $cookieDir); + define('DOKU_SESSION_PATH', $cookieDir); } - if(!defined('DOKU_SESSION_DOMAIN')) define ('DOKU_SESSION_DOMAIN', ''); + if (!defined('DOKU_SESSION_DOMAIN')) define('DOKU_SESSION_DOMAIN', ''); // start the session init_session(); // load left over messages - if(isset($_SESSION[DOKU_COOKIE]['msg'])) { + if (isset($_SESSION[DOKU_COOKIE]['msg'])) { $MSG = $_SESSION[DOKU_COOKIE]['msg']; unset($_SESSION[DOKU_COOKIE]['msg']); } } // don't let cookies ever interfere with request vars -$_REQUEST = array_merge($_GET,$_POST); +$_REQUEST = array_merge($_GET, $_POST); // we don't want a purge URL to be digged -if(isset($_REQUEST['purge']) && !empty($_SERVER['HTTP_REFERER'])) unset($_REQUEST['purge']); +if (isset($_REQUEST['purge']) && !empty($_SERVER['HTTP_REFERER'])) unset($_REQUEST['purge']); // precalculate file creation modes init_creationmodes(); @@ -193,28 +200,28 @@ init_files(); // setup plugin controller class (can be overwritten in preload.php) global $plugin_controller_class, $plugin_controller; -if (empty($plugin_controller_class)) $plugin_controller_class = dokuwiki\Extension\PluginController::class; +if (empty($plugin_controller_class)) $plugin_controller_class = PluginController::class; // load libraries -require_once(DOKU_INC.'vendor/autoload.php'); -require_once(DOKU_INC.'inc/load.php'); +require_once(DOKU_INC . 'vendor/autoload.php'); +require_once(DOKU_INC . 'inc/load.php'); // from now on everything is an exception -\dokuwiki\ErrorHandler::register(); +ErrorHandler::register(); // disable gzip if not available define('DOKU_HAS_BZIP', function_exists('bzopen')); define('DOKU_HAS_GZIP', function_exists('gzopen')); -if($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) { +if ($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) { $conf['compression'] = 'gz'; } -if($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) { +if ($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) { $conf['compression'] = 0; } // input handle class global $INPUT; -$INPUT = new \dokuwiki\Input\Input(); +$INPUT = new Input(); // initialize plugin controller $plugin_controller = new $plugin_controller_class(); @@ -246,7 +253,8 @@ Event::createAndTrigger('DOKUWIKI_INIT_DONE', $nil, null, false); * @link http://stackoverflow.com/a/33024310/172068 * @link http://php.net/manual/en/session.configuration.php#ini.session.sid-length */ -function init_session() { +function init_session() +{ global $conf; session_name(DOKU_SESSION_NAME); session_set_cookie_params([ @@ -259,7 +267,7 @@ function init_session() { ]); // make sure the session cookie contains a valid session ID - if(isset($_COOKIE[DOKU_SESSION_NAME]) && !preg_match('/^[-,a-zA-Z0-9]{22,256}$/', $_COOKIE[DOKU_SESSION_NAME])) { + if (isset($_COOKIE[DOKU_SESSION_NAME]) && !preg_match('/^[-,a-zA-Z0-9]{22,256}$/', $_COOKIE[DOKU_SESSION_NAME])) { unset($_COOKIE[DOKU_SESSION_NAME]); } @@ -270,7 +278,8 @@ function init_session() { /** * Checks paths from config file */ -function init_paths(){ +function init_paths() +{ global $conf; $paths = [ @@ -287,10 +296,10 @@ function init_paths(){ 'logdir' => 'log', ]; - foreach($paths as $c => $p) { - $path = empty($conf[$c]) ? $conf['savedir'].'/'.$p : $conf[$c]; + foreach ($paths as $c => $p) { + $path = empty($conf[$c]) ? $conf['savedir'] . '/' . $p : $conf[$c]; $conf[$c] = init_path($path); - if(empty($conf[$c])) { + if (empty($conf[$c])) { $path = fullpath($path); nice_die("The $c ('$p') at $path is not found, isn't accessible or writable. You should check your config and permission settings. @@ -301,12 +310,14 @@ function init_paths(){ // path to old changelog only needed for upgrading $conf['changelog_old'] = init_path( - (isset($conf['changelog'])) ? ($conf['changelog']) : ($conf['savedir'] . '/changes.log') + $conf['changelog'] ?? $conf['savedir'] . '/changes.log' ); - if ($conf['changelog_old']=='') { unset($conf['changelog_old']); } + if ($conf['changelog_old'] == '') { + unset($conf['changelog_old']); + } // hardcoded changelog because it is now a cache that lives in meta - $conf['changelog'] = $conf['metadir'].'/_dokuwiki.changes'; - $conf['media_changelog'] = $conf['metadir'].'/_media.changes'; + $conf['changelog'] = $conf['metadir'] . '/_dokuwiki.changes'; + $conf['media_changelog'] = $conf['metadir'] . '/_media.changes'; } /** @@ -314,13 +325,14 @@ function init_paths(){ * * @param string $langCode language code, as passed by event handler */ -function init_lang($langCode) { +function init_lang($langCode) +{ //prepare language array global $lang, $config_cascade; - $lang = array(); + $lang = []; //load the language files - require(DOKU_INC.'inc/lang/en/lang.php'); + require(DOKU_INC . 'inc/lang/en/lang.php'); foreach ($config_cascade['lang']['core'] as $config_file) { if (file_exists($config_file . 'en/lang.php')) { include($config_file . 'en/lang.php'); @@ -328,8 +340,8 @@ function init_lang($langCode) { } if ($langCode && $langCode != 'en') { - if (file_exists(DOKU_INC."inc/lang/$langCode/lang.php")) { - require(DOKU_INC."inc/lang/$langCode/lang.php"); + if (file_exists(DOKU_INC . "inc/lang/$langCode/lang.php")) { + require(DOKU_INC . "inc/lang/$langCode/lang.php"); } foreach ($config_cascade['lang']['core'] as $config_file) { if (file_exists($config_file . "$langCode/lang.php")) { @@ -342,18 +354,19 @@ function init_lang($langCode) { /** * Checks the existence of certain files and creates them if missing. */ -function init_files(){ +function init_files() +{ global $conf; - $files = array($conf['indexdir'].'/page.idx'); + $files = [$conf['indexdir'] . '/page.idx']; - foreach($files as $file){ - if(!file_exists($file)){ - $fh = @fopen($file,'a'); - if($fh){ + foreach ($files as $file) { + if (!file_exists($file)) { + $fh = @fopen($file, 'a'); + if ($fh) { fclose($fh); - if($conf['fperm']) chmod($file, $conf['fperm']); - }else{ + if ($conf['fperm']) chmod($file, $conf['fperm']); + } else { nice_die("$file is not writable. Check your permissions settings!"); } } @@ -372,23 +385,24 @@ function init_files(){ * * @return bool|string */ -function init_path($path){ +function init_path($path) +{ // check existence $p = fullpath($path); - if(!file_exists($p)){ - $p = fullpath(DOKU_INC.$path); - if(!file_exists($p)){ + if (!file_exists($p)) { + $p = fullpath(DOKU_INC . $path); + if (!file_exists($p)) { return ''; } } // check writability - if(!@is_writable($p)){ + if (!@is_writable($p)) { return ''; } // check accessability (execute bit) for directories - if(@is_dir($p) && !file_exists("$p/.")){ + if (@is_dir($p) && !file_exists("$p/.")) { return ''; } @@ -401,7 +415,8 @@ function init_path($path){ * file with chmod. Considers the influence of the system's umask * setting the values only if needed. */ -function init_creationmodes(){ +function init_creationmodes() +{ global $conf; // Legacy support for old umask/dmask scheme @@ -414,17 +429,17 @@ function init_creationmodes(){ // get system umask, fallback to 0 if none available $umask = @umask(); - if(!$umask) $umask = 0000; + if (!$umask) $umask = 0000; // check what is set automatically by the system on file creation // and set the fperm param if it's not what we want $auto_fmode = 0666 & ~$umask; - if($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode']; + if ($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode']; // check what is set automatically by the system on directory creation // and set the dperm param if it's not what we want. $auto_dmode = 0777 & ~$umask; - if($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode']; + if ($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode']; } /** @@ -437,77 +452,77 @@ function init_creationmodes(){ * * @author Andreas Gohr <andi@splitbrain.org> * - * @param null|string $abs + * @param null|bool $abs Return an absolute URL? (null defaults to $conf['canonical']) * * @return string */ -function getBaseURL($abs=null){ +function getBaseURL($abs = null) +{ global $conf; - //if canonical url enabled always return absolute - if(is_null($abs)) $abs = $conf['canonical']; - if(!empty($conf['basedir'])){ + $abs ??= $conf['canonical']; + + if (!empty($conf['basedir'])) { $dir = $conf['basedir']; - }elseif(substr($_SERVER['SCRIPT_NAME'],-4) == '.php'){ + } elseif (substr($_SERVER['SCRIPT_NAME'], -4) == '.php') { $dir = dirname($_SERVER['SCRIPT_NAME']); - }elseif(substr($_SERVER['PHP_SELF'],-4) == '.php'){ + } elseif (substr($_SERVER['PHP_SELF'], -4) == '.php') { $dir = dirname($_SERVER['PHP_SELF']); - }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){ - $dir = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','', - $_SERVER['SCRIPT_FILENAME']); - $dir = dirname('/'.$dir); - }else{ + } elseif ($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']) { + $dir = preg_replace( + '/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', + '', + $_SERVER['SCRIPT_FILENAME'] + ); + $dir = dirname('/' . $dir); + } else { $dir = '.'; //probably wrong } - $dir = str_replace('\\','/',$dir); // bugfix for weird WIN behaviour - $dir = preg_replace('#//+#','/',"/$dir/"); // ensure leading and trailing slashes + $dir = str_replace('\\', '/', $dir); // bugfix for weird WIN behaviour + $dir = preg_replace('#//+#', '/', "/$dir/"); // ensure leading and trailing slashes //handle script in lib/exe dir - $dir = preg_replace('!lib/exe/$!','',$dir); + $dir = preg_replace('!lib/exe/$!', '', $dir); //handle script in lib/plugins dir - $dir = preg_replace('!lib/plugins/.*$!','',$dir); + $dir = preg_replace('!lib/plugins/.*$!', '', $dir); //finish here for relative URLs - if(!$abs) return $dir; + if (!$abs) return $dir; //use config if available, trim any slash from end of baseurl to avoid multiple consecutive slashes in the path - if(!empty($conf['baseurl'])) return rtrim($conf['baseurl'],'/').$dir; + if (!empty($conf['baseurl'])) return rtrim($conf['baseurl'], '/') . $dir; //split hostheader into host and port - if(isset($_SERVER['HTTP_HOST'])){ - $parsed_host = parse_url('http://'.$_SERVER['HTTP_HOST']); - $host = isset($parsed_host['host']) ? $parsed_host['host'] : null; - $port = isset($parsed_host['port']) ? $parsed_host['port'] : null; - }elseif(isset($_SERVER['SERVER_NAME'])){ - $parsed_host = parse_url('http://'.$_SERVER['SERVER_NAME']); - $host = isset($parsed_host['host']) ? $parsed_host['host'] : null; - $port = isset($parsed_host['port']) ? $parsed_host['port'] : null; - }else{ + if (isset($_SERVER['HTTP_HOST'])) { + $parsed_host = parse_url('http://' . $_SERVER['HTTP_HOST']); + $host = $parsed_host['host'] ?? ''; + $port = $parsed_host['port'] ?? ''; + } elseif (isset($_SERVER['SERVER_NAME'])) { + $parsed_host = parse_url('http://' . $_SERVER['SERVER_NAME']); + $host = $parsed_host['host'] ?? ''; + $port = $parsed_host['port'] ?? ''; + } else { $host = php_uname('n'); $port = ''; } - if(is_null($port)){ - $port = ''; - } - - if(!is_ssl()){ + if (!is_ssl()) { $proto = 'http://'; if ($port == '80') { $port = ''; } - }else{ + } else { $proto = 'https://'; if ($port == '443') { $port = ''; } } - if($port !== '') $port = ':'.$port; + if ($port !== '') $port = ':' . $port; - return $proto.$host.$port.$dir; + return $proto . $host . $port . $dir; } /** @@ -518,29 +533,27 @@ function getBaseURL($abs=null){ * * @returns bool true when SSL is active */ -function is_ssl() { +function is_ssl() +{ // check if we are behind a reverse proxy - if(isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { - if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { - return true; - } else { - return false; - } + if (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') == 'https') { + return true; } - if(!isset($_SERVER['HTTPS']) || - preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS'])) { + + if (preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS'] ?? 'off')) { return false; - } else { - return true; } + + return true; } /** * checks it is windows OS * @return bool */ -function isWindows() { - return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false; +function isWindows() +{ + return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; } /** @@ -548,7 +561,8 @@ function isWindows() { * * @param integer|string $msg */ -function nice_die($msg){ +function nice_die($msg) +{ echo<<<EOT <!DOCTYPE html> <html> @@ -562,8 +576,8 @@ function nice_die($msg){ </body> </html> EOT; - if(defined('DOKU_UNITTEST')) { - throw new RuntimeException('nice_die: '.$msg); + if (defined('DOKU_UNITTEST')) { + throw new RuntimeException('nice_die: ' . $msg); } exit(1); } @@ -583,54 +597,54 @@ EOT; * * @return bool|string */ -function fullpath($path,$exists=false){ +function fullpath($path, $exists = false) +{ static $run = 0; $root = ''; $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || !empty($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'])); // find the (indestructable) root of the path - keeps windows stuff intact - if($path[0] == '/'){ + if ($path[0] == '/') { $root = '/'; - }elseif($iswin){ + } elseif ($iswin) { // match drive letter and UNC paths - if(preg_match('!^([a-zA-z]:)(.*)!',$path,$match)){ - $root = $match[1].'/'; + if (preg_match('!^([a-zA-z]:)(.*)!', $path, $match)) { + $root = $match[1] . '/'; $path = $match[2]; - }else if(preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!',$path,$match)){ + } elseif (preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!', $path, $match)) { $root = $match[1]; $path = $match[2]; } } - $path = str_replace('\\','/',$path); + $path = str_replace('\\', '/', $path); // if the given path wasn't absolute already, prepend the script path and retry - if(!$root){ + if (!$root) { $base = dirname($_SERVER['SCRIPT_FILENAME']); - $path = $base.'/'.$path; - if($run == 0){ // avoid endless recursion when base isn't absolute for some reason + $path = $base . '/' . $path; + if ($run == 0) { // avoid endless recursion when base isn't absolute for some reason $run++; - return fullpath($path,$exists); + return fullpath($path, $exists); } } $run = 0; // canonicalize - $path=explode('/', $path); - $newpath=array(); - foreach($path as $p) { + $path = explode('/', $path); + $newpath = []; + foreach ($path as $p) { if ($p === '' || $p === '.') continue; - if ($p==='..') { + if ($p === '..') { array_pop($newpath); continue; } - array_push($newpath, $p); + $newpath[] = $p; } - $finalpath = $root.implode('/', $newpath); + $finalpath = $root . implode('/', $newpath); // check for existence when needed (except when unit testing) - if($exists && !defined('DOKU_UNITTEST') && !file_exists($finalpath)) { + if ($exists && !defined('DOKU_UNITTEST') && !file_exists($finalpath)) { return false; } return $finalpath; } - diff --git a/inc/io.php b/inc/io.php index 72831a2da..e691a5dbe 100644 --- a/inc/io.php +++ b/inc/io.php @@ -1,4 +1,5 @@ <?php + /** * File IO functions * @@ -6,6 +7,7 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Utf8\PhpString; use dokuwiki\HTTP\DokuHTTPClient; use dokuwiki\Extension\Event; @@ -17,32 +19,35 @@ use dokuwiki\Extension\Event; * $data[0] ns: The colon separated namespace path minus the trailing page name. * $data[1] ns_type: 'pages' or 'media' namespace tree. * - * @param string $id - a pageid, the namespace of that id will be tried to deleted + * @param string $id - a pageid, the namespace of that id will be tried to deleted * @param string $basedir - the config name of the type to delete (datadir or mediadir usally) * @return bool - true if at least one namespace was deleted * * @author Andreas Gohr <andi@splitbrain.org> * @author Ben Coburn <btcoburn@silicodon.net> */ -function io_sweepNS($id,$basedir='datadir'){ +function io_sweepNS($id, $basedir = 'datadir') +{ global $conf; - $types = array ('datadir'=>'pages', 'mediadir'=>'media'); - $ns_type = (isset($types[$basedir])?$types[$basedir]:false); + $types = ['datadir' => 'pages', 'mediadir' => 'media']; + $ns_type = ($types[$basedir] ?? false); $delone = false; //scan all namespaces - while(($id = getNS($id)) !== false){ - $dir = $conf[$basedir].'/'.utf8_encodeFN(str_replace(':','/',$id)); + while (($id = getNS($id)) !== false) { + $dir = $conf[$basedir] . '/' . utf8_encodeFN(str_replace(':', '/', $id)); //try to delete dir else return - if(@rmdir($dir)) { - if ($ns_type!==false) { - $data = array($id, $ns_type); + if (@rmdir($dir)) { + if ($ns_type !== false) { + $data = [$id, $ns_type]; $delone = true; // we deleted at least one dir Event::createAndTrigger('IO_NAMESPACE_DELETED', $data); } - } else { return $delone; } + } else { + return $delone; + } } return $delone; } @@ -60,30 +65,34 @@ function io_sweepNS($id,$basedir='datadir'){ * $data[2] page_name: The wiki page name. * $data[3] rev: The page revision, false for current wiki pages. * - * @author Ben Coburn <btcoburn@silicodon.net> - * - * @param string $file filename - * @param string $id page id - * @param bool|int $rev revision timestamp + * @param string $file filename + * @param string $id page id + * @param bool|int|string $rev revision timestamp * @return string + * + * @author Ben Coburn <btcoburn@silicodon.net> */ -function io_readWikiPage($file, $id, $rev=false) { - if (empty($rev)) { $rev = false; } - $data = array(array($file, true), getNS($id), noNS($id), $rev); +function io_readWikiPage($file, $id, $rev = false) +{ + if (empty($rev)) { + $rev = false; + } + $data = [[$file, true], getNS($id), noNS($id), $rev]; return Event::createAndTrigger('IO_WIKIPAGE_READ', $data, '_io_readWikiPage_action', false); } /** * Callback adapter for io_readFile(). * - * @author Ben Coburn <btcoburn@silicodon.net> - * * @param array $data event data * @return string + * + * @author Ben Coburn <btcoburn@silicodon.net> */ -function _io_readWikiPage_action($data) { - if (is_array($data) && is_array($data[0]) && count($data[0])===2) { - return call_user_func_array('io_readFile', $data[0]); +function _io_readWikiPage_action($data) +{ + if (is_array($data) && is_array($data[0]) && count($data[0]) === 2) { + return io_readFile(...$data[0]); } else { return ''; //callback error } @@ -97,68 +106,78 @@ function _io_readWikiPage_action($data) { * If you want to use the returned value in unserialize * be sure to set $clean to false! * - * @author Andreas Gohr <andi@splitbrain.org> * - * @param string $file filename - * @param bool $clean + * @param string $file filename + * @param bool $clean * @return string|bool the file contents or false on error + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_readFile($file,$clean=true){ +function io_readFile($file, $clean = true) +{ $ret = ''; - if(file_exists($file)){ - if(substr($file,-3) == '.gz'){ - if(!DOKU_HAS_GZIP) return false; + if (file_exists($file)) { + if (substr($file, -3) == '.gz') { + if (!DOKU_HAS_GZIP) return false; $ret = gzfile($file); - if(is_array($ret)) $ret = join('', $ret); - }else if(substr($file,-4) == '.bz2'){ - if(!DOKU_HAS_BZIP) return false; + if (is_array($ret)) { + $ret = implode('', $ret); + } + } elseif (substr($file, -4) == '.bz2') { + if (!DOKU_HAS_BZIP) return false; $ret = bzfile($file); - }else{ + } else { $ret = file_get_contents($file); } } - if($ret === null) return false; - if($ret !== false && $clean){ + if ($ret === null) return false; + if ($ret !== false && $clean) { return cleanText($ret); - }else{ + } else { return $ret; } } + /** * Returns the content of a .bz2 compressed file as string * - * @author marcel senf <marcel@rucksackreinigung.de> - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file filename - * @param bool $array return array of lines + * @param bool $array return array of lines * @return string|array|bool content or false on error + * + * @author marcel senf <marcel@rucksackreinigung.de> + * @author Andreas Gohr <andi@splitbrain.org> */ -function bzfile($file, $array=false) { - $bz = bzopen($file,"r"); - if($bz === false) return false; +function bzfile($file, $array = false) +{ + $bz = bzopen($file, "r"); + if ($bz === false) return false; - if($array) $lines = array(); + if ($array) { + $lines = []; + } $str = ''; while (!feof($bz)) { //8192 seems to be the maximum buffersize? - $buffer = bzread($bz,8192); - if(($buffer === false) || (bzerrno($bz) !== 0)) { + $buffer = bzread($bz, 8192); + if (($buffer === false) || (bzerrno($bz) !== 0)) { return false; } - $str = $str . $buffer; - if($array) { + $str .= $buffer; + if ($array) { $pos = strpos($str, "\n"); - while($pos !== false) { - $lines[] = substr($str, 0, $pos+1); - $str = substr($str, $pos+1); + while ($pos !== false) { + $lines[] = substr($str, 0, $pos + 1); + $str = substr($str, $pos + 1); $pos = strpos($str, "\n"); } } } bzclose($bz); - if($array) { - if($str !== '') $lines[] = $str; + if ($array) { + if ($str !== '') { + $lines[] = $str; + } return $lines; } return $str; @@ -178,33 +197,40 @@ function bzfile($file, $array=false) { * $data[2] page_name: The wiki page name. * $data[3] rev: The page revision, false for current wiki pages. * - * @author Ben Coburn <btcoburn@silicodon.net> - * - * @param string $file filename + * @param string $file filename * @param string $content - * @param string $id page id - * @param int|bool $rev timestamp of revision + * @param string $id page id + * @param int|bool|string $rev timestamp of revision * @return bool + * + * @author Ben Coburn <btcoburn@silicodon.net> */ -function io_writeWikiPage($file, $content, $id, $rev=false) { - if (empty($rev)) { $rev = false; } - if ($rev===false) { io_createNamespace($id); } // create namespaces as needed - $data = array(array($file, $content, false), getNS($id), noNS($id), $rev); +function io_writeWikiPage($file, $content, $id, $rev = false) +{ + if (empty($rev)) { + $rev = false; + } + if ($rev === false) { + io_createNamespace($id); // create namespaces as needed + } + $data = [[$file, $content, false], getNS($id), noNS($id), $rev]; return Event::createAndTrigger('IO_WIKIPAGE_WRITE', $data, '_io_writeWikiPage_action', false); } /** * Callback adapter for io_saveFile(). - * @author Ben Coburn <btcoburn@silicodon.net> * * @param array $data event data * @return bool + * + * @author Ben Coburn <btcoburn@silicodon.net> */ -function _io_writeWikiPage_action($data) { - if (is_array($data) && is_array($data[0]) && count($data[0])===3) { - $ok = call_user_func_array('io_saveFile', $data[0]); +function _io_writeWikiPage_action($data) +{ + if (is_array($data) && is_array($data[0]) && count($data[0]) === 3) { + $ok = io_saveFile(...$data[0]); // for attic files make sure the file has the mtime of the revision - if($ok && is_int($data[3]) && $data[3] > 0) { + if ($ok && is_int($data[3]) && $data[3] > 0) { @touch($data[0][0], $data[3]); } return $ok; @@ -216,43 +242,46 @@ function _io_writeWikiPage_action($data) { /** * Internal function to save contents to a file. * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file filename path to file * @param string $content - * @param bool $append + * @param bool $append * @return bool true on success, otherwise false + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function _io_saveFile($file, $content, $append) { +function _io_saveFile($file, $content, $append) +{ global $conf; $mode = ($append) ? 'ab' : 'wb'; $fileexists = file_exists($file); - if(substr($file,-3) == '.gz'){ - if(!DOKU_HAS_GZIP) return false; - $fh = @gzopen($file,$mode.'9'); - if(!$fh) return false; + if (substr($file, -3) == '.gz') { + if (!DOKU_HAS_GZIP) return false; + $fh = @gzopen($file, $mode . '9'); + if (!$fh) return false; gzwrite($fh, $content); gzclose($fh); - }else if(substr($file,-4) == '.bz2'){ - if(!DOKU_HAS_BZIP) return false; - if($append) { + } elseif (substr($file, -4) == '.bz2') { + if (!DOKU_HAS_BZIP) return false; + if ($append) { $bzcontent = bzfile($file); - if($bzcontent === false) return false; - $content = $bzcontent.$content; + if ($bzcontent === false) return false; + $content = $bzcontent . $content; } - $fh = @bzopen($file,'w'); - if(!$fh) return false; + $fh = @bzopen($file, 'w'); + if (!$fh) return false; bzwrite($fh, $content); bzclose($fh); - }else{ - $fh = @fopen($file,$mode); - if(!$fh) return false; + } else { + $fh = @fopen($file, $mode); + if (!$fh) return false; fwrite($fh, $content); fclose($fh); } - if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); + if (!$fileexists && $conf['fperm']) { + chmod($file, $conf['fperm']); + } return true; } @@ -265,18 +294,19 @@ function _io_saveFile($file, $content, $append) { * Uses gzip if extension is .gz * and bz2 if extension is .bz2 * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file filename path to file * @param string $content - * @param bool $append + * @param bool $append * @return bool true on success, otherwise false + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_saveFile($file, $content, $append=false) { +function io_saveFile($file, $content, $append = false) +{ io_makeFileDir($file); io_lock($file); - if(!_io_saveFile($file, $content, $append)) { - msg("Writing $file failed",-1); + if (!_io_saveFile($file, $content, $append)) { + msg("Writing $file failed", -1); io_unlock($file); return false; } @@ -299,18 +329,19 @@ function io_saveFile($file, $content, $append=false) { * Uses gzip if extension is .gz * and bz2 if extension is .bz2 * + * @param string $file filename + * @param string $oldline exact linematch to remove + * @param string $newline new line to insert + * @param bool $regex use regexp? + * @param int $maxlines number of occurrences of the line to replace + * @return bool true on success + * * @author Steven Danz <steven-danz@kc.rr.com> * @author Christopher Smith <chris@jalakai.co.uk> * @author Patrick Brown <ptbrown@whoopdedo.org> - * - * @param string $file filename - * @param string $oldline exact linematch to remove - * @param string $newline new line to insert - * @param bool $regex use regexp? - * @param int $maxlines number of occurrences of the line to replace - * @return bool true on success */ -function io_replaceInFile($file, $oldline, $newline, $regex=false, $maxlines=0) { +function io_replaceInFile($file, $oldline, $newline, $regex = false, $maxlines = 0) +{ if ((string)$oldline === '') { trigger_error('$oldline parameter cannot be empty in io_replaceInFile()', E_USER_WARNING); return false; @@ -321,47 +352,48 @@ function io_replaceInFile($file, $oldline, $newline, $regex=false, $maxlines=0) io_lock($file); // load into array - if(substr($file,-3) == '.gz'){ - if(!DOKU_HAS_GZIP) return false; + if (substr($file, -3) == '.gz') { + if (!DOKU_HAS_GZIP) return false; $lines = gzfile($file); - }else if(substr($file,-4) == '.bz2'){ - if(!DOKU_HAS_BZIP) return false; + } elseif (substr($file, -4) == '.bz2') { + if (!DOKU_HAS_BZIP) return false; $lines = bzfile($file, true); - }else{ + } else { $lines = file($file); } // make non-regexes into regexes - $pattern = $regex ? $oldline : '/^'.preg_quote($oldline,'/').'$/'; + $pattern = $regex ? $oldline : '/^' . preg_quote($oldline, '/') . '$/'; $replace = $regex ? $newline : addcslashes($newline, '\$'); // remove matching lines if ($maxlines > 0) { $count = 0; $matched = 0; - foreach($lines as $i => $line) { - if($count >= $maxlines) break; + foreach ($lines as $i => $line) { + if ($count >= $maxlines) break; // $matched will be set to 0|1 depending on whether pattern is matched and line replaced $lines[$i] = preg_replace($pattern, $replace, $line, -1, $matched); - if ($matched) $count++; + if ($matched) { + $count++; + } } - } else if ($maxlines == 0) { + } elseif ($maxlines == 0) { $lines = preg_grep($pattern, $lines, PREG_GREP_INVERT); - - if ((string)$newline !== ''){ + if ((string)$newline !== '') { $lines[] = $newline; } } else { $lines = preg_replace($pattern, $replace, $lines); } - if(count($lines)){ - if(!_io_saveFile($file, join('',$lines), false)) { - msg("Removing content from $file failed",-1); + if (count($lines)) { + if (!_io_saveFile($file, implode('', $lines), false)) { + msg("Removing content from $file failed", -1); io_unlock($file); return false; } - }else{ + } else { @unlink($file); } @@ -374,15 +406,16 @@ function io_replaceInFile($file, $oldline, $newline, $regex=false, $maxlines=0) * * Be sure to include the trailing newline in $badline * - * @author Patrick Brown <ptbrown@whoopdedo.org> - * - * @param string $file filename + * @param string $file filename * @param string $badline exact linematch to remove - * @param bool $regex use regexp? + * @param bool $regex use regexp? * @return bool true on success + * + * @author Patrick Brown <ptbrown@whoopdedo.org> */ -function io_deleteFromFile($file,$badline,$regex=false){ - return io_replaceInFile($file,$badline,null,$regex,0); +function io_deleteFromFile($file, $badline, $regex = false) +{ + return io_replaceInFile($file, $badline, null, $regex, 0); } /** @@ -394,14 +427,15 @@ function io_deleteFromFile($file,$badline,$regex=false){ * It waits maximal 3 seconds for the lock, after this time * the lock is assumed to be stale and the function goes on * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file filename + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_lock($file){ +function io_lock($file) +{ global $conf; - $lockDir = $conf['lockdir'].'/'.md5($file); + $lockDir = $conf['lockdir'] . '/' . md5($file); @ignore_user_abort(1); $timeStart = time(); @@ -409,8 +443,10 @@ function io_lock($file){ //waited longer than 3 seconds? -> stale lock if ((time() - $timeStart) > 3) break; $locked = @mkdir($lockDir); - if($locked){ - if($conf['dperm']) chmod($lockDir, $conf['dperm']); + if ($locked) { + if ($conf['dperm']) { + chmod($lockDir, $conf['dperm']); + } break; } usleep(50); @@ -420,14 +456,15 @@ function io_lock($file){ /** * Unlocks a file * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file filename + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_unlock($file){ +function io_unlock($file) +{ global $conf; - $lockDir = $conf['lockdir'].'/'.md5($file); + $lockDir = $conf['lockdir'] . '/' . md5($file); @rmdir($lockDir); @ignore_user_abort(0); } @@ -440,27 +477,30 @@ function io_unlock($file){ * $data[0] ns: The colon separated namespace path minus the trailing page name. * $data[1] ns_type: 'pages' or 'media' namespace tree. * - * @author Ben Coburn <btcoburn@silicodon.net> - * * @param string $id page id * @param string $ns_type 'pages' or 'media' + * + * @author Ben Coburn <btcoburn@silicodon.net> */ -function io_createNamespace($id, $ns_type='pages') { +function io_createNamespace($id, $ns_type = 'pages') +{ // verify ns_type - $types = array('pages'=>'wikiFN', 'media'=>'mediaFN'); + $types = ['pages' => 'wikiFN', 'media' => 'mediaFN']; if (!isset($types[$ns_type])) { trigger_error('Bad $ns_type parameter for io_createNamespace().'); return; } // make event list - $missing = array(); + $missing = []; $ns_stack = explode(':', $id); $ns = $id; - $tmp = dirname( $file = call_user_func($types[$ns_type], $ns) ); + $tmp = dirname($file = call_user_func($types[$ns_type], $ns)); while (!@is_dir($tmp) && !(file_exists($tmp) && !is_dir($tmp))) { array_pop($ns_stack); $ns = implode(':', $ns_stack); - if (strlen($ns)==0) { break; } + if (strlen($ns) == 0) { + break; + } $missing[] = $ns; $tmp = dirname(call_user_func($types[$ns_type], $ns)); } @@ -469,7 +509,7 @@ function io_createNamespace($id, $ns_type='pages') { // send the events $missing = array_reverse($missing); // inside out foreach ($missing as $ns) { - $data = array($ns, $ns_type); + $data = [$ns, $ns_type]; Event::createAndTrigger('IO_NAMESPACE_CREATED', $data); } } @@ -477,85 +517,86 @@ function io_createNamespace($id, $ns_type='pages') { /** * Create the directory needed for the given file * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file file name + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_makeFileDir($file){ +function io_makeFileDir($file) +{ $dir = dirname($file); - if(!@is_dir($dir)){ - io_mkdir_p($dir) || msg("Creating directory $dir failed",-1); + if (!@is_dir($dir)) { + io_mkdir_p($dir) || msg("Creating directory $dir failed", -1); } } /** * Creates a directory hierachy. * + * @param string $target filename + * @return bool + * * @link http://php.net/manual/en/function.mkdir.php * @author <saint@corenova.com> * @author Andreas Gohr <andi@splitbrain.org> - * - * @param string $target filename - * @return bool|int|string */ -function io_mkdir_p($target){ +function io_mkdir_p($target) +{ global $conf; - if (@is_dir($target)||empty($target)) return 1; // best case check first - if (file_exists($target) && !is_dir($target)) return 0; + if (@is_dir($target) || empty($target)) return true; // best case check first + if (file_exists($target) && !is_dir($target)) return false; //recursion - if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){ + if (io_mkdir_p(substr($target, 0, strrpos($target, '/')))) { $ret = @mkdir($target); // crawl back up & create dir tree - if($ret && !empty($conf['dperm'])) chmod($target, $conf['dperm']); + if ($ret && !empty($conf['dperm'])) { + chmod($target, $conf['dperm']); + } return $ret; } - return 0; + return false; } /** * Recursively delete a directory * - * @author Andreas Gohr <andi@splitbrain.org> * @param string $path - * @param bool $removefiles defaults to false which will delete empty directories only + * @param bool $removefiles defaults to false which will delete empty directories only * @return bool + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_rmdir($path, $removefiles = false) { - if(!is_string($path) || $path == "") return false; - if(!file_exists($path)) return true; // it's already gone or was never there, count as success - - if(is_dir($path) && !is_link($path)) { - $dirs = array(); - $files = array(); - - if(!$dh = @opendir($path)) return false; - while(false !== ($f = readdir($dh))) { - if($f == '..' || $f == '.') continue; +function io_rmdir($path, $removefiles = false) +{ + if (!is_string($path) || $path == "") return false; + if (!file_exists($path)) return true; // it's already gone or was never there, count as success + + if (is_dir($path) && !is_link($path)) { + $dirs = []; + $files = []; + if (!$dh = @opendir($path)) return false; + while (false !== ($f = readdir($dh))) { + if ($f == '..' || $f == '.') continue; // collect dirs and files first - if(is_dir("$path/$f") && !is_link("$path/$f")) { + if (is_dir("$path/$f") && !is_link("$path/$f")) { $dirs[] = "$path/$f"; - } else if($removefiles) { + } elseif ($removefiles) { $files[] = "$path/$f"; } else { return false; // abort when non empty } - } closedir($dh); - // now traverse into directories first - foreach($dirs as $dir) { - if(!io_rmdir($dir, $removefiles)) return false; // abort on any error + foreach ($dirs as $dir) { + if (!io_rmdir($dir, $removefiles)) return false; // abort on any error } - // now delete files - foreach($files as $file) { - if(!@unlink($file)) return false; //abort on any error + foreach ($files as $file) { + if (!@unlink($file)) return false; //abort on any error } - // remove self return @rmdir($path); - } else if($removefiles) { + } elseif ($removefiles) { return @unlink($path); } return false; @@ -565,19 +606,21 @@ function io_rmdir($path, $removefiles = false) { * Creates a unique temporary directory and returns * its path. * - * @author Michael Klier <chi@chimeric.de> - * * @return false|string path to new directory or false + * @throws Exception + * + * @author Michael Klier <chi@chimeric.de> */ -function io_mktmpdir() { +function io_mktmpdir() +{ global $conf; $base = $conf['tmpdir']; - $dir = md5(uniqid(mt_rand(), true)); - $tmpdir = $base.'/'.$dir; + $dir = md5(uniqid(random_int(0, mt_getrandmax()), true)); + $tmpdir = $base . '/' . $dir; - if(io_mkdir_p($tmpdir)) { - return($tmpdir); + if (io_mkdir_p($tmpdir)) { + return $tmpdir; } else { return false; } @@ -594,18 +637,19 @@ function io_mktmpdir() { * - $file is the directory where the file should be saved * - if successful will return the name used for the saved file, false otherwise * + * @param string $url url to download + * @param string $file path to file or directory where to save + * @param bool $useAttachment true: try to use name of download, uses otherwise $defaultName + * false: uses $file as path to file + * @param string $defaultName fallback for if using $useAttachment + * @param int $maxSize maximum file size + * @return bool|string if failed false, otherwise true or the name of the file in the given dir + * * @author Andreas Gohr <andi@splitbrain.org> * @author Chris Smith <chris@jalakai.co.uk> - * - * @param string $url url to download - * @param string $file path to file or directory where to save - * @param bool $useAttachment true: try to use name of download, uses otherwise $defaultName - * false: uses $file as path to file - * @param string $defaultName fallback for if using $useAttachment - * @param int $maxSize maximum file size - * @return bool|string if failed false, otherwise true or the name of the file in the given dir */ -function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=2097152){ +function io_download($url, $file, $useAttachment = false, $defaultName = '', $maxSize = 2_097_152) +{ global $conf; $http = new DokuHTTPClient(); $http->max_bodysize = $maxSize; @@ -613,19 +657,19 @@ function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=20 $http->keep_alive = false; // we do single ops here, no need for keep-alive $data = $http->get($url); - if(!$data) return false; + if (!$data) return false; $name = ''; if ($useAttachment) { if (isset($http->resp_headers['content-disposition'])) { $content_disposition = $http->resp_headers['content-disposition']; - $match=array(); - if (is_string($content_disposition) && - preg_match('/attachment;\s*filename\s*=\s*"([^"]*)"/i', $content_disposition, $match)) { - - $name = \dokuwiki\Utf8\PhpString::basename($match[1]); + $match = []; + if ( + is_string($content_disposition) && + preg_match('/attachment;\s*filename\s*=\s*"([^"]*)"/i', $content_disposition, $match) + ) { + $name = PhpString::basename($match[1]); } - } if (!$name) { @@ -633,15 +677,17 @@ function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=20 $name = $defaultName; } - $file = $file.$name; + $file .= $name; } $fileexists = file_exists($file); - $fp = @fopen($file,"w"); - if(!$fp) return false; - fwrite($fp,$data); + $fp = @fopen($file, "w"); + if (!$fp) return false; + fwrite($fp, $data); fclose($fp); - if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); + if (!$fileexists && $conf['fperm']) { + chmod($file, $conf['fperm']); + } if ($useAttachment) return $name; return true; } @@ -656,11 +702,14 @@ function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=20 * @param string $to * @return bool succes or fail */ -function io_rename($from,$to){ +function io_rename($from, $to) +{ global $conf; - if(!@rename($from,$to)){ - if(@copy($from,$to)){ - if($conf['fperm']) chmod($to, $conf['fperm']); + if (!@rename($from, $to)) { + if (@copy($from, $to)) { + if ($conf['fperm']) { + chmod($to, $conf['fperm']); + } @unlink($from); return true; } @@ -673,20 +722,22 @@ function io_rename($from,$to){ * Runs an external command with input and output pipes. * Returns the exit code from the process. * - * @author Tom N Harris <tnharris@whoopdedo.org> - * * @param string $cmd - * @param string $input input pipe + * @param string $input input pipe * @param string $output output pipe * @return int exit code from process + * + * @author Tom N Harris <tnharris@whoopdedo.org> */ -function io_exec($cmd, $input, &$output){ - $descspec = array( - 0=>array("pipe","r"), - 1=>array("pipe","w"), - 2=>array("pipe","w")); +function io_exec($cmd, $input, &$output) +{ + $descspec = [ + 0 => ["pipe", "r"], + 1 => ["pipe", "w"], + 2 => ["pipe", "w"] + ]; $ph = proc_open($cmd, $descspec, $pipes); - if(!$ph) return -1; + if (!$ph) return -1; fclose($pipes[2]); // ignore stderr fwrite($pipes[0], $input); fclose($pipes[0]); @@ -702,34 +753,36 @@ function io_exec($cmd, $input, &$output){ * memory intensive because not the whole file needs to be loaded * at once. * - * @author Andreas Gohr <andi@splitbrain.org> - * @param string $file The file to search - * @param string $pattern PCRE pattern - * @param int $max How many lines to return (0 for all) - * @param bool $backref When true returns array with backreferences instead of lines + * @param string $file The file to search + * @param string $pattern PCRE pattern + * @param int $max How many lines to return (0 for all) + * @param bool $backref When true returns array with backreferences instead of lines * @return array matching lines or backref, false on error + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function io_grep($file,$pattern,$max=0,$backref=false){ - $fh = @fopen($file,'r'); - if(!$fh) return false; - $matches = array(); +function io_grep($file, $pattern, $max = 0, $backref = false) +{ + $fh = @fopen($file, 'r'); + if (!$fh) return false; + $matches = []; - $cnt = 0; + $cnt = 0; $line = ''; while (!feof($fh)) { $line .= fgets($fh, 4096); // read full line - if(substr($line,-1) != "\n") continue; + if (substr($line, -1) != "\n") continue; // check if line matches - if(preg_match($pattern,$line,$match)){ - if($backref){ + if (preg_match($pattern, $line, $match)) { + if ($backref) { $matches[] = $match; - }else{ + } else { $matches[] = $line; } $cnt++; } - if($max && $max == $cnt) break; + if ($max && $max == $cnt) break; $line = ''; } fclose($fh); @@ -741,41 +794,39 @@ function io_grep($file,$pattern,$max=0,$backref=false){ * Get size of contents of a file, for a compressed file the uncompressed size * Warning: reading uncompressed size of content of bz-files requires uncompressing * - * @author Gerrit Uitslag <klapinklapin@gmail.com> - * * @param string $file filename path to file * @return int size of file + * + * @author Gerrit Uitslag <klapinklapin@gmail.com> */ -function io_getSizeFile($file) { +function io_getSizeFile($file) +{ if (!file_exists($file)) return 0; - if(substr($file,-3) == '.gz'){ + if (substr($file, -3) == '.gz') { $fp = @fopen($file, "rb"); - if($fp === false) return 0; - + if ($fp === false) return 0; fseek($fp, -4, SEEK_END); $buffer = fread($fp, 4); fclose($fp); $array = unpack("V", $buffer); $uncompressedsize = end($array); - }else if(substr($file,-4) == '.bz2'){ - if(!DOKU_HAS_BZIP) return 0; - - $bz = bzopen($file,"r"); - if($bz === false) return 0; - + } elseif (substr($file, -4) == '.bz2') { + if (!DOKU_HAS_BZIP) return 0; + $bz = bzopen($file, "r"); + if ($bz === false) return 0; $uncompressedsize = 0; while (!feof($bz)) { //8192 seems to be the maximum buffersize? - $buffer = bzread($bz,8192); - if(($buffer === false) || (bzerrno($bz) !== 0)) { + $buffer = bzread($bz, 8192); + if (($buffer === false) || (bzerrno($bz) !== 0)) { return 0; } $uncompressedsize += strlen($buffer); } - }else{ + } else { $uncompressedsize = filesize($file); } return $uncompressedsize; - } +} diff --git a/inc/legacy.php b/inc/legacy.php index fa72649b7..eb32e5cda 100644 --- a/inc/legacy.php +++ b/inc/legacy.php @@ -1,9 +1,12 @@ <?php + /** * We map legacy class names to the new namespaced versions here * * These are names that we will probably never change because they have been part of DokuWiki's * public interface for years and renaming would break just too many plugins + * + * Note: when adding to this file, please also add appropriate actions to _test/rector.php */ class_alias('\dokuwiki\Extension\EventHandler', 'Doku_Event_Handler'); diff --git a/inc/load.php b/inc/load.php index 961c56958..31d9bc9f3 100644 --- a/inc/load.php +++ b/inc/load.php @@ -1,10 +1,12 @@ <?php + /** * Load all internal libraries and setup class autoloader * * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\ErrorHandler; use dokuwiki\Extension\PluginController; // setup class autoloader @@ -12,31 +14,31 @@ spl_autoload_register('load_autoload'); // require all the common libraries // for a few of these order does matter -require_once(DOKU_INC.'inc/defines.php'); -require_once(DOKU_INC.'inc/actions.php'); -require_once(DOKU_INC.'inc/changelog.php'); -require_once(DOKU_INC.'inc/common.php'); -require_once(DOKU_INC.'inc/confutils.php'); -require_once(DOKU_INC.'inc/pluginutils.php'); -require_once(DOKU_INC.'inc/form.php'); -require_once(DOKU_INC.'inc/fulltext.php'); -require_once(DOKU_INC.'inc/html.php'); -require_once(DOKU_INC.'inc/httputils.php'); -require_once(DOKU_INC.'inc/indexer.php'); -require_once(DOKU_INC.'inc/infoutils.php'); -require_once(DOKU_INC.'inc/io.php'); -require_once(DOKU_INC.'inc/mail.php'); -require_once(DOKU_INC.'inc/media.php'); -require_once(DOKU_INC.'inc/pageutils.php'); -require_once(DOKU_INC.'inc/parserutils.php'); -require_once(DOKU_INC.'inc/search.php'); -require_once(DOKU_INC.'inc/template.php'); -require_once(DOKU_INC.'inc/toolbar.php'); -require_once(DOKU_INC.'inc/utf8.php'); -require_once(DOKU_INC.'inc/auth.php'); -require_once(DOKU_INC.'inc/compatibility.php'); -require_once(DOKU_INC.'inc/deprecated.php'); -require_once(DOKU_INC.'inc/legacy.php'); +require_once(DOKU_INC . 'inc/defines.php'); +require_once(DOKU_INC . 'inc/actions.php'); +require_once(DOKU_INC . 'inc/changelog.php'); +require_once(DOKU_INC . 'inc/common.php'); +require_once(DOKU_INC . 'inc/confutils.php'); +require_once(DOKU_INC . 'inc/pluginutils.php'); +require_once(DOKU_INC . 'inc/form.php'); +require_once(DOKU_INC . 'inc/fulltext.php'); +require_once(DOKU_INC . 'inc/html.php'); +require_once(DOKU_INC . 'inc/httputils.php'); +require_once(DOKU_INC . 'inc/indexer.php'); +require_once(DOKU_INC . 'inc/infoutils.php'); +require_once(DOKU_INC . 'inc/io.php'); +require_once(DOKU_INC . 'inc/mail.php'); +require_once(DOKU_INC . 'inc/media.php'); +require_once(DOKU_INC . 'inc/pageutils.php'); +require_once(DOKU_INC . 'inc/parserutils.php'); +require_once(DOKU_INC . 'inc/search.php'); +require_once(DOKU_INC . 'inc/template.php'); +require_once(DOKU_INC . 'inc/toolbar.php'); +require_once(DOKU_INC . 'inc/utf8.php'); +require_once(DOKU_INC . 'inc/auth.php'); +require_once(DOKU_INC . 'inc/compatibility.php'); +require_once(DOKU_INC . 'inc/deprecated.php'); +require_once(DOKU_INC . 'inc/legacy.php'); /** * spl_autoload_register callback @@ -51,34 +53,33 @@ require_once(DOKU_INC.'inc/legacy.php'); * * @return bool */ -function load_autoload($name){ +function load_autoload($name) +{ static $classes = null; - if($classes === null) $classes = array( - 'Diff' => DOKU_INC.'inc/DifferenceEngine.php', - 'UnifiedDiffFormatter' => DOKU_INC.'inc/DifferenceEngine.php', - 'TableDiffFormatter' => DOKU_INC.'inc/DifferenceEngine.php', - 'cache' => DOKU_INC.'inc/cache.php', - 'cache_parser' => DOKU_INC.'inc/cache.php', - 'cache_instructions' => DOKU_INC.'inc/cache.php', - 'cache_renderer' => DOKU_INC.'inc/cache.php', - 'Input' => DOKU_INC.'inc/Input.class.php', - 'JpegMeta' => DOKU_INC.'inc/JpegMeta.php', - 'SimplePie' => DOKU_INC.'inc/SimplePie.php', - 'FeedParser' => DOKU_INC.'inc/FeedParser.php', - 'SafeFN' => DOKU_INC.'inc/SafeFN.class.php', - 'Sitemapper' => DOKU_INC.'inc/Sitemapper.php', - 'Mailer' => DOKU_INC.'inc/Mailer.class.php', - - 'Doku_Handler' => DOKU_INC.'inc/parser/handler.php', - 'Doku_Renderer' => DOKU_INC.'inc/parser/renderer.php', - 'Doku_Renderer_xhtml' => DOKU_INC.'inc/parser/xhtml.php', - 'Doku_Renderer_code' => DOKU_INC.'inc/parser/code.php', - 'Doku_Renderer_xhtmlsummary' => DOKU_INC.'inc/parser/xhtmlsummary.php', - 'Doku_Renderer_metadata' => DOKU_INC.'inc/parser/metadata.php', - ); + if ($classes === null) $classes = [ + 'Diff' => DOKU_INC . 'inc/DifferenceEngine.php', + 'UnifiedDiffFormatter' => DOKU_INC . 'inc/DifferenceEngine.php', + 'TableDiffFormatter' => DOKU_INC . 'inc/DifferenceEngine.php', + 'cache' => DOKU_INC . 'inc/cache.php', + 'cache_parser' => DOKU_INC . 'inc/cache.php', + 'cache_instructions' => DOKU_INC . 'inc/cache.php', + 'cache_renderer' => DOKU_INC . 'inc/cache.php', + 'Input' => DOKU_INC . 'inc/Input.class.php', + 'JpegMeta' => DOKU_INC . 'inc/JpegMeta.php', + 'SimplePie' => DOKU_INC . 'inc/SimplePie.php', + 'FeedParser' => DOKU_INC . 'inc/FeedParser.php', + 'SafeFN' => DOKU_INC . 'inc/SafeFN.class.php', + 'Mailer' => DOKU_INC . 'inc/Mailer.class.php', + 'Doku_Handler' => DOKU_INC . 'inc/parser/handler.php', + 'Doku_Renderer' => DOKU_INC . 'inc/parser/renderer.php', + 'Doku_Renderer_xhtml' => DOKU_INC . 'inc/parser/xhtml.php', + 'Doku_Renderer_code' => DOKU_INC . 'inc/parser/code.php', + 'Doku_Renderer_xhtmlsummary' => DOKU_INC . 'inc/parser/xhtmlsummary.php', + 'Doku_Renderer_metadata' => DOKU_INC . 'inc/parser/metadata.php' + ]; - if(isset($classes[$name])){ - require ($classes[$name]); + if (isset($classes[$name])) { + require($classes[$name]); return true; } @@ -104,62 +105,63 @@ function load_autoload($name){ } // plugin namespace - if(substr($name, 0, 16) === 'dokuwiki/plugin/') { + if (substr($name, 0, 16) === 'dokuwiki/plugin/') { $name = str_replace('/test/', '/_test/', $name); // no underscore in test namespace $file = DOKU_PLUGIN . substr($name, 16) . '.php'; - if(file_exists($file)) { + if (file_exists($file)) { try { require $file; } catch (\Throwable $e) { - \dokuwiki\ErrorHandler::showExceptionMsg($e, "Error loading plugin $name"); + ErrorHandler::showExceptionMsg($e, "Error loading plugin $name"); } return true; } } // template namespace - if(substr($name, 0, 18) === 'dokuwiki/template/') { + if (substr($name, 0, 18) === 'dokuwiki/template/') { $name = str_replace('/test/', '/_test/', $name); // no underscore in test namespace - $file = DOKU_INC.'lib/tpl/' . substr($name, 18) . '.php'; - if(file_exists($file)) { + $file = DOKU_INC . 'lib/tpl/' . substr($name, 18) . '.php'; + if (file_exists($file)) { try { require $file; } catch (\Throwable $e) { - \dokuwiki\ErrorHandler::showExceptionMsg($e, "Error loading template $name"); + ErrorHandler::showExceptionMsg($e, "Error loading template $name"); } return true; } } // our own namespace - if(substr($name, 0, 9) === 'dokuwiki/') { + if (substr($name, 0, 9) === 'dokuwiki/') { $file = DOKU_INC . 'inc/' . substr($name, 9) . '.php'; - if(file_exists($file)) { + if (file_exists($file)) { require $file; return true; } } // Plugin loading - if(preg_match( - '/^(' . implode('|', PluginController::PLUGIN_TYPES) . ')_plugin_(' . - DOKU_PLUGIN_NAME_REGEX . - ')(?:_([^_]+))?$/', - $name, - $m - )) { + if ( + preg_match( + '/^(' . implode('|', PluginController::PLUGIN_TYPES) . ')_plugin_(' . + DOKU_PLUGIN_NAME_REGEX . + ')(?:_([^_]+))?$/', + $name, + $m + ) + ) { // try to load the wanted plugin file $c = ((count($m) === 4) ? "/{$m[3]}" : ''); $plg = DOKU_PLUGIN . "{$m[2]}/{$m[1]}$c.php"; - if(file_exists($plg)){ + if (file_exists($plg)) { try { require $plg; } catch (\Throwable $e) { - \dokuwiki\ErrorHandler::showExceptionMsg($e, "Error loading plugin {$m[2]}"); + ErrorHandler::showExceptionMsg($e, "Error loading plugin {$m[2]}"); } } return true; } return false; } - diff --git a/inc/mail.php b/inc/mail.php index 4f5d1b337..77869e0ad 100644 --- a/inc/mail.php +++ b/inc/mail.php @@ -1,4 +1,5 @@ <?php + /** * Mail functions * @@ -6,7 +7,6 @@ * @author Andreas Gohr <andi@splitbrain.org> */ - /** * Patterns for use in email detection and validation * @@ -20,10 +20,10 @@ * @author Chris Smith <chris@jalakai.co.uk> * Check if a given mail address is valid */ -if (!defined('RFC2822_ATEXT')) define('RFC2822_ATEXT',"0-9a-zA-Z!#$%&'*+/=?^_`{|}~-"); +if (!defined('RFC2822_ATEXT')) define('RFC2822_ATEXT', "0-9a-zA-Z!#$%&'*+/=?^_`{|}~-"); if (!defined('PREG_PATTERN_VALID_EMAIL')) define( 'PREG_PATTERN_VALID_EMAIL', - '['.RFC2822_ATEXT.']+(?:\.['.RFC2822_ATEXT.']+)*@(?i:[0-9a-z][0-9a-z-]*\.)+(?i:[a-z]{2,63})' + '[' . RFC2822_ATEXT . ']+(?:\.[' . RFC2822_ATEXT . ']+)*@(?i:[0-9a-z][0-9a-z-]*\.)+(?i:[a-z]{2,63})' ); /** @@ -34,42 +34,45 @@ if (!defined('PREG_PATTERN_VALID_EMAIL')) define( * * @author Andreas Gohr <andi@splitbrain.org> */ -function mail_setup(){ +function mail_setup() +{ global $conf; global $USERINFO; /** @var Input $INPUT */ global $INPUT; // auto constructed address - $host = @parse_url(DOKU_URL,PHP_URL_HOST); - if(!$host) $host = 'example.com'; - $noreply = 'noreply@'.$host; + $host = @parse_url(DOKU_URL, PHP_URL_HOST); + if (!$host) $host = 'example.com'; + $noreply = 'noreply@' . $host; - $replace = array(); - if(!empty($USERINFO['mail'])){ + $replace = []; + if (!empty($USERINFO['mail'])) { $replace['@MAIL@'] = $USERINFO['mail']; - }else{ + } else { $replace['@MAIL@'] = $noreply; } // use 'noreply' if no user $replace['@USER@'] = $INPUT->server->str('REMOTE_USER', 'noreply', true); - if(!empty($USERINFO['name'])){ + if (!empty($USERINFO['name'])) { $replace['@NAME@'] = $USERINFO['name']; - }else{ + } else { $replace['@NAME@'] = ''; } // apply replacements - $from = str_replace(array_keys($replace), - array_values($replace), - $conf['mailfrom']); + $from = str_replace( + array_keys($replace), + array_values($replace), + $conf['mailfrom'] + ); // any replacements done? set different mailfromnone - if($from != $conf['mailfrom']){ + if ($from != $conf['mailfrom']) { $conf['mailfromnobody'] = $noreply; - }else{ + } else { $conf['mailfromnobody'] = $from; } $conf['mailfrom'] = $from; @@ -81,7 +84,8 @@ function mail_setup(){ * @param string $email the address to check * @return bool true if address is valid */ -function mail_isvalid($email) { +function mail_isvalid($email) +{ return EmailAddressValidator::checkEmailAddress($email, true); } @@ -97,14 +101,15 @@ function mail_isvalid($email) { * * @return string */ -function mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) { +function mail_quotedprintable_encode($sText, $maxlen = 74, $bEmulate_imap_8bit = true) +{ // split text into lines - $aLines= preg_split("/(?:\r\n|\r|\n)/", $sText); + $aLines = preg_split("/(?:\r\n|\r|\n)/", $sText); $cnt = count($aLines); - for ($i=0;$i<$cnt;$i++) { + for ($i = 0; $i < $cnt; $i++) { $sLine =& $aLines[$i]; - if (strlen($sLine)===0) continue; // do nothing, if empty + if ($sLine === '') continue; // do nothing, if empty $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e'; @@ -114,29 +119,29 @@ function mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) if ($bEmulate_imap_8bit) $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/'; - $sLine = preg_replace_callback( $sRegExp, 'mail_quotedprintable_encode_callback', $sLine ); + $sLine = preg_replace_callback($sRegExp, 'mail_quotedprintable_encode_callback', $sLine); // encode x09,x20 at lineends { $iLength = strlen($sLine); - $iLastChar = ord($sLine[$iLength-1]); + $iLastChar = ord($sLine[$iLength - 1]); // !!!!!!!! // imap_8_bit does not encode x20 at the very end of a text, // here is, where I don't agree with imap_8_bit, // please correct me, if I'm wrong, // or comment next line for RFC2045 conformance, if you like - if (!($bEmulate_imap_8bit && ($i==count($aLines)-1))){ - if (($iLastChar==0x09)||($iLastChar==0x20)) { - $sLine[$iLength-1]='='; - $sLine .= ($iLastChar==0x09)?'09':'20'; - } + if (!($bEmulate_imap_8bit && ($i == count($aLines) - 1))) { + if (($iLastChar == 0x09) || ($iLastChar == 0x20)) { + $sLine[$iLength - 1] = '='; + $sLine .= ($iLastChar == 0x09) ? '09' : '20'; } + } } // imap_8bit encodes x20 before chr(13), too // although IMHO not requested by RFC2045, why not do it safer :) // and why not encode any x20 around chr(10) or chr(13) if ($bEmulate_imap_8bit) { - $sLine=str_replace(' =0D','=20=0D',$sLine); + $sLine = str_replace(' =0D', '=20=0D', $sLine); //$sLine=str_replace(' =0A','=20=0A',$sLine); //$sLine=str_replace('=0D ','=0D=20',$sLine); //$sLine=str_replace('=0A ','=0A=20',$sLine); @@ -147,16 +152,17 @@ function mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) // at the very first character of the line // and after soft linebreaks, as well, // but this wouldn't be caught by such an easy RegExp - if($maxlen){ - preg_match_all( '/.{1,'.($maxlen - 2).'}([^=]{0,2})?/', $sLine, $aMatch ); - $sLine = implode( '=' . MAILHEADER_EOL, $aMatch[0] ); // add soft crlf's + if ($maxlen) { + preg_match_all('/.{1,' . ($maxlen - 2) . '}([^=]{0,2})?/', $sLine, $aMatch); + $sLine = implode('=' . MAILHEADER_EOL, $aMatch[0]); // add soft crlf's } } // join lines into text - return implode(MAILHEADER_EOL,$aLines); + return implode(MAILHEADER_EOL, $aLines); } -function mail_quotedprintable_encode_callback($matches){ - return sprintf( "=%02X", ord ( $matches[0] ) ) ; +function mail_quotedprintable_encode_callback($matches) +{ + return sprintf("=%02X", ord($matches[0])) ; } diff --git a/inc/media.php b/inc/media.php index 2ec52497f..ed3270096 100644 --- a/inc/media.php +++ b/inc/media.php @@ -1,4 +1,5 @@ <?php + /** * All output and handler function needed for the media management popup * @@ -6,6 +7,10 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Ui\MediaRevisions; +use dokuwiki\Cache\CacheImageMod; +use splitbrain\slika\Exception; +use dokuwiki\PassHash; use dokuwiki\ChangeLog\MediaChangeLog; use dokuwiki\Extension\Event; use dokuwiki\Form\Form; @@ -30,22 +35,22 @@ use splitbrain\slika\Slika; * @param array $data * @param string $id */ -function media_filesinuse($data,$id){ +function media_filesinuse($data, $id) +{ global $lang; - echo '<h1>'.$lang['reference'].' <code>'.hsc(noNS($id)).'</code></h1>'; - echo '<p>'.hsc($lang['ref_inuse']).'</p>'; + echo '<h1>' . $lang['reference'] . ' <code>' . hsc(noNS($id)) . '</code></h1>'; + echo '<p>' . hsc($lang['ref_inuse']) . '</p>'; - $hidden=0; //count of hits without read permission - foreach($data as $row){ - if(auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)){ + $hidden = 0; //count of hits without read permission + foreach ($data as $row) { + if (auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)) { echo '<div class="search_result">'; - echo '<span class="mediaref_ref">'.hsc($row).'</span>'; + echo '<span class="mediaref_ref">' . hsc($row) . '</span>'; echo '</div>'; - }else - $hidden++; + } else $hidden++; } - if ($hidden){ - print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>'; + if ($hidden) { + echo '<div class="mediaref_hidden">' . $lang['ref_hidden'] . '</div>'; } } @@ -60,9 +65,10 @@ function media_filesinuse($data,$id){ * @param array $data * @return false|string */ -function media_metasave($id,$auth,$data){ - if($auth < AUTH_UPLOAD) return false; - if(!checkSecurityToken()) return false; +function media_metasave($id, $auth, $data) +{ + if ($auth < AUTH_UPLOAD) return false; + if (!checkSecurityToken()) return false; global $lang; global $conf; $src = mediaFN($id); @@ -70,23 +76,23 @@ function media_metasave($id,$auth,$data){ $meta = new JpegMeta($src); $meta->_parseAll(); - foreach($data as $key => $val){ - $val=trim($val); - if(empty($val)){ + foreach ($data as $key => $val) { + $val = trim($val); + if (empty($val)) { $meta->deleteField($key); - }else{ - $meta->setField($key,$val); + } else { + $meta->setField($key, $val); } } $old = @filemtime($src); - if(!file_exists(mediaFN($id, $old)) && file_exists($src)) { + if (!file_exists(mediaFN($id, $old)) && file_exists($src)) { // add old revision to the attic media_saveOldRevision($id); } $filesize_old = filesize($src); - if($meta->save()){ - if($conf['fperm']) chmod($src, $conf['fperm']); + if ($meta->save()) { + if ($conf['fperm']) chmod($src, $conf['fperm']); @clearstatcache(true, $src); $new = @filemtime($src); $filesize_new = filesize($src); @@ -95,10 +101,10 @@ function media_metasave($id,$auth,$data){ // add a log entry to the media changelog addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited'], '', null, $sizechange); - msg($lang['metasaveok'],1); + msg($lang['metasaveok'], 1); return $id; - }else{ - msg($lang['metasaveerr'],-1); + } else { + msg($lang['metasaveerr'], -1); return false; } } @@ -111,7 +117,8 @@ function media_metasave($id,$auth,$data){ * @param string $id the media ID or URL * @return bool */ -function media_isexternal($id){ +function media_isexternal($id) +{ if (preg_match('#^(?:https?|ftp)://#i', $id)) return true; return false; } @@ -124,10 +131,11 @@ function media_isexternal($id){ * @param string $id the media ID or URL * @return bool */ -function media_ispublic($id){ - if(media_isexternal($id)) return true; +function media_ispublic($id) +{ + if (media_isexternal($id)) return true; $id = cleanID($id); - if(auth_aclcheck(getNS($id).':*', '', array()) >= AUTH_READ) return true; + if (auth_aclcheck(getNS($id) . ':*', '', []) >= AUTH_READ) return true; return false; } @@ -141,11 +149,12 @@ function media_ispublic($id){ * @param int $auth permission level * @return bool */ -function media_metaform($id, $auth) { +function media_metaform($id, $auth) +{ global $lang; if ($auth < AUTH_UPLOAD) { - echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.DOKU_LF; + echo '<div class="nothing">' . $lang['media_perm_upload'] . '</div>' . DOKU_LF; return false; } @@ -171,17 +180,17 @@ function media_metaform($id, $auth) { foreach ($fields as $key => $field) { // get current value if (empty($field[0])) continue; - $tags = array($field[0]); + $tags = [$field[0]]; if (is_array($field[3])) $tags = array_merge($tags, $field[3]); $value = tpl_img_getTag($tags, '', $src); $value = cleanText($value); // prepare attributes - $p = array( + $p = [ 'class' => 'edit', - 'id' => 'meta__'.$key, - 'name' => 'meta['.$field[0].']', - ); + 'id' => 'meta__' . $key, + 'name' => 'meta[' . $field[0] . ']' + ]; $form->addTagOpen('div')->addClass('row'); if ($field[2] == 'text') { @@ -215,12 +224,13 @@ function media_metaform($id, $auth) { * @param string $id media id * @return array|bool */ -function media_inuse($id) { +function media_inuse($id) +{ global $conf; - if($conf['refcheck']){ - $mediareferences = ft_mediause($id,true); - if(!count($mediareferences)) { + if ($conf['refcheck']) { + $mediareferences = ft_mediause($id, true); + if ($mediareferences === []) { return false; } else { return $mediareferences; @@ -245,16 +255,17 @@ function media_inuse($id) { * DOKU_MEDIA_NOT_AUTH, * DOKU_MEDIA_INUSE */ -function media_delete($id,$auth){ +function media_delete($id, $auth) +{ global $lang; - $auth = auth_quickaclcheck(ltrim(getNS($id).':*', ':')); - if($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; - if(media_inuse($id)) return DOKU_MEDIA_INUSE; + $auth = auth_quickaclcheck(ltrim(getNS($id) . ':*', ':')); + if ($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; + if (media_inuse($id)) return DOKU_MEDIA_INUSE; $file = mediaFN($id); // trigger an event - MEDIA_DELETE_FILE - $data = array(); + $data = []; $data['id'] = $id; $data['name'] = PhpString::basename($file); $data['path'] = $file; @@ -262,16 +273,16 @@ function media_delete($id,$auth){ $data['unl'] = false; $data['del'] = false; - $evt = new Event('MEDIA_DELETE_FILE',$data); + $evt = new Event('MEDIA_DELETE_FILE', $data); if ($evt->advise_before()) { $old = @filemtime($file); - if(!file_exists(mediaFN($id, $old)) && file_exists($file)) { + if (!file_exists(mediaFN($id, $old)) && file_exists($file)) { // add old revision to the attic media_saveOldRevision($id); } $data['unl'] = @unlink($file); - if($data['unl']) { + if ($data['unl']) { $sizechange = 0 - $data['size']; addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted'], '', null, $sizechange); @@ -281,7 +292,7 @@ function media_delete($id,$auth){ $evt->advise_after(); unset($evt); - if($data['unl'] && $data['del']){ + if ($data['unl'] && $data['del']) { return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS; } @@ -295,15 +306,16 @@ function media_delete($id,$auth){ * @param int $auth current auth check result * @return false|string false on error, id of the new file on success */ -function media_upload_xhr($ns,$auth){ - if(!checkSecurityToken()) return false; +function media_upload_xhr($ns, $auth) +{ + if (!checkSecurityToken()) return false; global $INPUT; $id = $INPUT->get->str('qqfile'); - list($ext,$mime) = mimetype($id); + [$ext, $mime] = mimetype($id); $input = fopen("php://input", "r"); if (!($tmp = io_mktmpdir())) return false; - $path = $tmp.'/'.md5($id); + $path = $tmp . '/' . md5($id); $target = fopen($path, "w"); $realSize = stream_copy_to_stream($input, $target); fclose($target); @@ -314,10 +326,8 @@ function media_upload_xhr($ns,$auth){ } $res = media_save( - array('name' => $path, - 'mime' => $mime, - 'ext' => $ext), - $ns.':'.$id, + ['name' => $path, 'mime' => $mime, 'ext' => $ext], + $ns . ':' . $id, ($INPUT->get->str('ow') == 'true'), $auth, 'copy' @@ -342,35 +352,43 @@ function media_upload_xhr($ns,$auth){ * @param bool|array $file $_FILES member, $_FILES['upload'] if false * @return false|string false on error, id of the new file on success */ -function media_upload($ns,$auth,$file=false){ - if(!checkSecurityToken()) return false; +function media_upload($ns, $auth, $file = false) +{ + if (!checkSecurityToken()) return false; global $lang; global $INPUT; // get file and id $id = $INPUT->post->str('mediaid'); if (!$file) $file = $_FILES['upload']; - if(empty($id)) $id = $file['name']; + if (empty($id)) $id = $file['name']; // check for errors (messages are done in lib/exe/mediamanager.php) - if($file['error']) return false; + if ($file['error']) return false; // check extensions - list($fext,$fmime) = mimetype($file['name']); - list($iext,$imime) = mimetype($id); - if($fext && !$iext){ + [$fext, $fmime] = mimetype($file['name']); + [$iext, $imime] = mimetype($id); + if ($fext && !$iext) { // no extension specified in id - read original one - $id .= '.'.$fext; + $id .= '.' . $fext; $imime = $fmime; - }elseif($fext && $fext != $iext){ + } elseif ($fext && $fext != $iext) { // extension was changed, print warning - msg(sprintf($lang['mediaextchange'],$fext,$iext)); + msg(sprintf($lang['mediaextchange'], $fext, $iext)); } - $res = media_save(array('name' => $file['tmp_name'], - 'mime' => $imime, - 'ext' => $iext), $ns.':'.$id, - $INPUT->post->bool('ow'), $auth, 'copy_uploaded_file'); + $res = media_save( + [ + 'name' => $file['tmp_name'], + 'mime' => $imime, + 'ext' => $iext + ], + $ns . ':' . $id, + $INPUT->post->bool('ow'), + $auth, + 'copy_uploaded_file' + ); if (is_array($res)) { msg($res[0], $res[1]); return false; @@ -389,8 +407,9 @@ function media_upload($ns,$auth,$file=false){ * @param string $to * @return bool */ -function copy_uploaded_file($from, $to){ - if(!is_uploaded_file($from)) return false; +function copy_uploaded_file($from, $to) +{ + if (!is_uploaded_file($from)) return false; $ok = copy($from, $to); @unlink($from); return $ok; @@ -418,13 +437,14 @@ function copy_uploaded_file($from, $to){ * @param string $move name of functions that performs move/copy/.. * @return false|array|string */ -function media_save($file, $id, $ow, $auth, $move) { - if($auth < AUTH_UPLOAD) { - return array("You don't have permissions to upload files.", -1); +function media_save($file, $id, $ow, $auth, $move) +{ + if ($auth < AUTH_UPLOAD) { + return ["You don't have permissions to upload files.", -1]; } if (!isset($file['mime']) || !isset($file['ext'])) { - list($ext, $mime) = mimetype($id); + [$ext, $mime] = mimetype($id); if (!isset($file['mime'])) { $file['mime'] = $mime; } @@ -442,36 +462,34 @@ function media_save($file, $id, $ow, $auth, $move) { // get filetype regexp $types = array_keys(getMimeTypes()); $types = array_map( - function ($q) { - return preg_quote($q, "/"); - }, + static fn($q) => preg_quote($q, "/"), $types ); - $regex = join('|',$types); + $regex = implode('|', $types); // because a temp file was created already - if(!preg_match('/\.('.$regex.')$/i',$fn)) { - return array($lang['uploadwrong'],-1); + if (!preg_match('/\.(' . $regex . ')$/i', $fn)) { + return [$lang['uploadwrong'], -1]; } //check for overwrite $overwrite = file_exists($fn); $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); - if($overwrite && (!$ow || $auth < $auth_ow)) { - return array($lang['uploadexist'], 0); + if ($overwrite && (!$ow || $auth < $auth_ow)) { + return [$lang['uploadexist'], 0]; } // check for valid content $ok = media_contentcheck($file['name'], $file['mime']); - if($ok == -1){ - return array(sprintf($lang['uploadbadcontent'],'.' . $file['ext']),-1); - }elseif($ok == -2){ - return array($lang['uploadspam'],-1); - }elseif($ok == -3){ - return array($lang['uploadxss'],-1); + if ($ok == -1) { + return [sprintf($lang['uploadbadcontent'], '.' . $file['ext']), -1]; + } elseif ($ok == -2) { + return [$lang['uploadspam'], -1]; + } elseif ($ok == -3) { + return [$lang['uploadxss'], -1]; } // prepare event data - $data = array(); + $data = []; $data[0] = $file['name']; $data[1] = $fn; $data[2] = $id; @@ -491,9 +509,10 @@ function media_save($file, $id, $ow, $auth, $move) { * @param array $data event data * @return false|array|string */ -function _media_upload_action($data) { +function _media_upload_action($data) +{ // fixme do further sanity tests of given data? - if(is_array($data) && count($data)===6) { + if (is_array($data) && count($data) === 6) { return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); } else { return false; //callback error @@ -515,13 +534,14 @@ function _media_upload_action($data) { * @param string $move function name * @return array|string */ -function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') { +function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') +{ global $conf; global $lang; global $REV; $old = @filemtime($fn); - if(!file_exists(mediaFN($id, $old)) && file_exists($fn)) { + if (!file_exists(mediaFN($id, $old)) && file_exists($fn)) { // add old revision to the attic if missing media_saveOldRevision($id); } @@ -531,19 +551,19 @@ function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'mov $filesize_old = file_exists($fn) ? filesize($fn) : 0; - if($move($fn_tmp, $fn)) { - @clearstatcache(true,$fn); + if ($move($fn_tmp, $fn)) { + @clearstatcache(true, $fn); $new = @filemtime($fn); // Set the correct permission here. // Always chmod media because they may be saved with different permissions than expected from the php umask. // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) chmod($fn, $conf['fmode']); - msg($lang['uploadsucc'],1); - media_notify($id,$fn,$imime,$old,$new); + msg($lang['uploadsucc'], 1); + media_notify($id, $fn, $imime, $old, $new); // add a log entry to the media changelog $filesize_new = filesize($fn); $sizechange = $filesize_new - $filesize_old; - if($REV) { + if ($REV) { addMediaLogEntry( $new, $id, @@ -553,14 +573,14 @@ function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'mov null, $sizechange ); - } elseif($overwrite) { + } elseif ($overwrite) { addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); } else { addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); } return $id; - }else{ - return array($lang['uploadfail'],-1); + } else { + return [$lang['uploadfail'], -1]; } } @@ -573,7 +593,8 @@ function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'mov * @param string $id * @return int - revision date */ -function media_saveOldRevision($id) { +function media_saveOldRevision($id) +{ global $conf, $lang; $oldf = mediaFN($id); @@ -586,13 +607,13 @@ function media_saveOldRevision($id) { // there was an external edit, // there is no log entry for current version of file $sizechange = filesize($oldf); - if(!file_exists(mediaMetaFN($id, '.changes'))) { + if (!file_exists(mediaMetaFN($id, '.changes'))) { addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); } else { $oldRev = $medialog->getRevisions(-1, 1); // from changelog $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]); $filesize_old = filesize(mediaFN($id, $oldRev)); - $sizechange = $sizechange - $filesize_old; + $sizechange -= $filesize_old; addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); } @@ -624,32 +645,33 @@ function media_saveOldRevision($id) { * @param string $mime mimetype * @return int */ -function media_contentcheck($file,$mime){ +function media_contentcheck($file, $mime) +{ global $conf; - if($conf['iexssprotect']){ + if ($conf['iexssprotect']) { $fh = @fopen($file, 'rb'); - if($fh){ + if ($fh) { $bytes = fread($fh, 256); fclose($fh); - if(preg_match('/<(script|a|img|html|body|iframe)[\s>]/i',$bytes)){ + if (preg_match('/<(script|a|img|html|body|iframe)[\s>]/i', $bytes)) { return -3; //XSS: possibly malicious content } } } - if(substr($mime,0,6) == 'image/'){ + if (substr($mime, 0, 6) == 'image/') { $info = @getimagesize($file); - if($mime == 'image/gif' && $info[2] != 1){ + if ($mime == 'image/gif' && $info[2] != 1) { return -1; // uploaded content did not match the file extension - }elseif($mime == 'image/jpeg' && $info[2] != 2){ + } elseif ($mime == 'image/jpeg' && $info[2] != 2) { return -1; - }elseif($mime == 'image/png' && $info[2] != 3){ + } elseif ($mime == 'image/png' && $info[2] != 3) { return -1; } # fixme maybe check other images types as well - }elseif(substr($mime,0,5) == 'text/'){ + } elseif (substr($mime, 0, 5) == 'text/') { global $TEXT; $TEXT = io_readFile($file); - if(checkwordblock()){ + if (checkwordblock()) { return -2; //blocked by the spam blacklist } } @@ -666,9 +688,10 @@ function media_contentcheck($file,$mime){ * @param string $mime mime type * @param bool|int $old_rev revision timestamp or false */ -function media_notify($id,$file,$mime,$old_rev=false,$current_rev=false){ +function media_notify($id, $file, $mime, $old_rev = false, $current_rev = false) +{ global $conf; - if(empty($conf['notify'])) return; //notify enabled? + if (empty($conf['notify'])) return; //notify enabled? $subscription = new MediaSubscriptionSender(); $subscription->sendMediaDiff($conf['notify'], 'uploadmail', $id, $old_rev, $current_rev); @@ -683,37 +706,45 @@ function media_notify($id,$file,$mime,$old_rev=false,$current_rev=false){ * @param bool $fullscreenview * @param bool|string $sort sorting order, false skips sorting */ -function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=false){ +function media_filelist($ns, $auth = null, $jump = '', $fullscreenview = false, $sort = false) +{ global $conf; global $lang; $ns = cleanID($ns); // check auth our self if not given (needed for ajax calls) - if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); + if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); - if (!$fullscreenview) echo '<h1 id="media__ns">:'.hsc($ns).'</h1>'.NL; + if (!$fullscreenview) echo '<h1 id="media__ns">:' . hsc($ns) . '</h1>' . NL; - if($auth < AUTH_READ){ + if ($auth < AUTH_READ) { // FIXME: print permission warning here instead? - echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; - }else{ + echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; + } else { if (!$fullscreenview) { media_uploadform($ns, $auth); media_searchform($ns); } - $dir = utf8_encodeFN(str_replace(':','/',$ns)); - $data = array(); - search($data,$conf['mediadir'],'search_mediafiles', - array('showmsg'=>true,'depth'=>1),$dir,1,$sort); + $dir = utf8_encodeFN(str_replace(':', '/', $ns)); + $data = []; + search( + $data, + $conf['mediadir'], + 'search_mediafiles', + ['showmsg' => true, 'depth' => 1], + $dir, + 1, + $sort + ); - if(!count($data)){ - echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; - }else { + if (!count($data)) { + echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; + } else { if ($fullscreenview) { echo '<ul class="' . _media_get_list_type() . '">'; } - foreach($data as $item){ + foreach ($data as $item) { if (!$fullscreenview) { //FIXME old call: media_printfile($item,$auth,$jump); $display = new DisplayRow($item); @@ -728,7 +759,7 @@ function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=fals echo '</li>'; } } - if ($fullscreenview) echo '</ul>'.NL; + if ($fullscreenview) echo '</ul>' . NL; } } } @@ -742,14 +773,21 @@ function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=fals * @param string $selected_tab - opened tab */ -function media_tabs_files($selected_tab = ''){ +function media_tabs_files($selected_tab = '') +{ global $lang; - $tabs = array(); - foreach(array('files' => 'mediaselect', - 'upload' => 'media_uploadtab', - 'search' => 'media_searchtab') as $tab => $caption) { - $tabs[$tab] = array('href' => media_managerURL(['tab_files' => $tab], '&'), - 'caption' => $lang[$caption]); + $tabs = []; + foreach ( + [ + 'files' => 'mediaselect', + 'upload' => 'media_uploadtab', + 'search' => 'media_searchtab' + ] as $tab => $caption + ) { + $tabs[$tab] = [ + 'href' => media_managerURL(['tab_files' => $tab], '&'), + 'caption' => $lang[$caption] + ]; } html_tabs($tabs, $selected_tab); @@ -762,21 +800,28 @@ function media_tabs_files($selected_tab = ''){ * @param string $image filename of the current image * @param string $selected_tab opened tab */ -function media_tabs_details($image, $selected_tab = '') { +function media_tabs_details($image, $selected_tab = '') +{ global $lang, $conf; - $tabs = array(); - $tabs['view'] = array('href' => media_managerURL(['tab_details' => 'view'], '&'), - 'caption' => $lang['media_viewtab']); + $tabs = []; + $tabs['view'] = [ + 'href' => media_managerURL(['tab_details' => 'view'], '&'), + 'caption' => $lang['media_viewtab'] + ]; - list(, $mime) = mimetype($image); + [, $mime] = mimetype($image); if ($mime == 'image/jpeg' && file_exists(mediaFN($image))) { - $tabs['edit'] = array('href' => media_managerURL(['tab_details' => 'edit'], '&'), - 'caption' => $lang['media_edittab']); + $tabs['edit'] = [ + 'href' => media_managerURL(['tab_details' => 'edit'], '&'), + 'caption' => $lang['media_edittab'] + ]; } if ($conf['mediarevisions']) { - $tabs['history'] = array('href' => media_managerURL(['tab_details' => 'history'], '&'), - 'caption' => $lang['media_historytab']); + $tabs['history'] = [ + 'href' => media_managerURL(['tab_details' => 'history'], '&'), + 'caption' => $lang['media_historytab'] + ]; } html_tabs($tabs, $selected_tab); @@ -787,7 +832,8 @@ function media_tabs_details($image, $selected_tab = '') { * * @author Kate Arzamastseva <pshns@ukr.net> */ -function media_tab_files_options() { +function media_tab_files_options() +{ global $lang; global $INPUT; global $ID; @@ -806,33 +852,36 @@ function media_tab_files_options() { if ($INPUT->has('q')) { $form->setHiddenField('q', $INPUT->str('q')); } - $form->addHTML('<ul>'.NL); - foreach (array('list' => array('listType', array('thumbs', 'rows')), - 'sort' => array('sortBy', array('name', 'date'))) - as $group => $content) { + $form->addHTML('<ul>' . NL); + foreach ( + [ + 'list' => ['listType', ['thumbs', 'rows']], + 'sort' => ['sortBy', ['name', 'date']] + ] as $group => $content + ) { $checked = "_media_get_{$group}_type"; $checked = $checked(); - $form->addHTML('<li class="'. $content[0] .'">'); + $form->addHTML('<li class="' . $content[0] . '">'); foreach ($content[1] as $option) { - $attrs = array(); + $attrs = []; if ($checked == $option) { $attrs['checked'] = 'checked'; } $radio = $form->addRadioButton( - $group.'_dwmedia', - $lang['media_'.$group.'_'.$option] - )->val($option)->id($content[0].'__'.$option)->addClass($option); + $group . '_dwmedia', + $lang['media_' . $group . '_' . $option] + )->val($option)->id($content[0] . '__' . $option)->addClass($option); $radio->attrs($attrs); } - $form->addHTML('</li>'.NL); + $form->addHTML('</li>' . NL); } $form->addHTML('<li>'); $form->addButton('', $lang['btn_apply'])->attr('type', 'submit'); - $form->addHTML('</li>'.NL); - $form->addHTML('</ul>'.NL); + $form->addHTML('</li>' . NL); + $form->addHTML('</ul>' . NL); $form->addTagClose('div'); - print $form->toHTML(); + echo $form->toHTML(); } /** @@ -842,8 +891,9 @@ function media_tab_files_options() { * * @return string - sort type */ -function _media_get_sort_type() { - return _media_get_display_param('sort', array('default' => 'name', 'date')); +function _media_get_sort_type() +{ + return _media_get_display_param('sort', ['default' => 'name', 'date']); } /** @@ -853,8 +903,9 @@ function _media_get_sort_type() { * * @return string - list type */ -function _media_get_list_type() { - return _media_get_display_param('list', array('default' => 'thumbs', 'rows')); +function _media_get_list_type() +{ + return _media_get_display_param('list', ['default' => 'thumbs', 'rows']); } /** @@ -864,7 +915,8 @@ function _media_get_list_type() { * @param array $values allowed values, where default value has index key 'default' * @return string the parameter value */ -function _media_get_display_param($param, $values) { +function _media_get_display_param($param, $values) +{ global $INPUT; if (in_array($INPUT->str($param), $values)) { // FIXME: Set cookie @@ -887,14 +939,15 @@ function _media_get_display_param($param, $values) { * @param null|int $auth permission level * @param string $jump item id */ -function media_tab_files($ns,$auth=null,$jump='') { +function media_tab_files($ns, $auth = null, $jump = '') +{ global $lang; - if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); + if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); - if($auth < AUTH_READ){ - echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; - }else{ - media_filelist($ns,$auth,$jump,true,_media_get_sort_type()); + if ($auth < AUTH_READ) { + echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; + } else { + media_filelist($ns, $auth, $jump, true, _media_get_sort_type()); } } @@ -907,16 +960,17 @@ function media_tab_files($ns,$auth=null,$jump='') { * @param null|int $auth permission level * @param string $jump item id */ -function media_tab_upload($ns,$auth=null,$jump='') { +function media_tab_upload($ns, $auth = null, $jump = '') +{ global $lang; - if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); + if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); - echo '<div class="upload">'.NL; + echo '<div class="upload">' . NL; if ($auth >= AUTH_UPLOAD) { echo '<p>' . $lang['mediaupload'] . '</p>'; } media_uploadform($ns, $auth, true); - echo '</div>'.NL; + echo '</div>' . NL; } /** @@ -927,18 +981,19 @@ function media_tab_upload($ns,$auth=null,$jump='') { * @param string $ns * @param null|int $auth permission level */ -function media_tab_search($ns,$auth=null) { +function media_tab_search($ns, $auth = null) +{ global $INPUT; $do = $INPUT->str('mediado'); $query = $INPUT->str('q'); - echo '<div class="search">'.NL; + echo '<div class="search">' . NL; media_searchform($ns, $query, true); if ($do == 'searchlist' || $query) { - media_searchlist($query,$ns,$auth,true,_media_get_sort_type()); + media_searchlist($query, $ns, $auth, true, _media_get_sort_type()); } - echo '</div>'.NL; + echo '</div>' . NL; } /** @@ -951,18 +1006,18 @@ function media_tab_search($ns,$auth=null) { * @param null|int $auth permission level * @param string|int $rev revision timestamp or empty string */ -function media_tab_view($image, $ns, $auth=null, $rev='') { +function media_tab_view($image, $ns, $auth = null, $rev = '') +{ global $lang; - if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); + if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); if ($image && $auth >= AUTH_READ) { $meta = new JpegMeta(mediaFN($image, $rev)); media_preview($image, $auth, $rev, $meta); media_preview_buttons($image, $auth, $rev); media_details($image, $auth, $rev, $meta); - } else { - echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; + echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; } } @@ -975,12 +1030,13 @@ function media_tab_view($image, $ns, $auth=null, $rev='') { * @param string $ns * @param null|int $auth permission level */ -function media_tab_edit($image, $ns, $auth=null) { - if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); +function media_tab_edit($image, $ns, $auth = null) +{ + if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); if ($image) { - list(, $mime) = mimetype($image); - if ($mime == 'image/jpeg') media_metaform($image,$auth); + [, $mime] = mimetype($image); + if ($mime == 'image/jpeg') media_metaform($image, $auth); } } @@ -993,22 +1049,23 @@ function media_tab_edit($image, $ns, $auth=null) { * @param string $ns * @param null|int $auth permission level */ -function media_tab_history($image, $ns, $auth=null) { +function media_tab_history($image, $ns, $auth = null) +{ global $lang; global $INPUT; - if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); + if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); $do = $INPUT->str('mediado'); if ($auth >= AUTH_READ && $image) { - if ($do == 'diff'){ - (new dokuwiki\Ui\MediaDiff($image))->show(); //media_diff($image, $ns, $auth); + if ($do == 'diff') { + (new MediaDiff($image))->show(); //media_diff($image, $ns, $auth); } else { - $first = $INPUT->int('first',-1); - (new dokuwiki\Ui\MediaRevisions($image))->show($first); + $first = $INPUT->int('first', -1); + (new MediaRevisions($image))->show($first); } } else { - echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; + echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; } } @@ -1022,7 +1079,8 @@ function media_tab_history($image, $ns, $auth=null) { * * @author Kate Arzamastseva <pshns@ukr.net> */ -function media_preview($image, $auth, $rev = '', $meta = false) { +function media_preview($image, $auth, $rev = '', $meta = false) +{ $size = media_image_preview_size($image, $rev, $meta); @@ -1030,7 +1088,7 @@ function media_preview($image, $auth, $rev = '', $meta = false) { global $lang; echo '<div class="image">'; - $more = array(); + $more = []; if ($rev) { $more['rev'] = $rev; } else { @@ -1042,8 +1100,8 @@ function media_preview($image, $auth, $rev = '', $meta = false) { $more['h'] = $size[1]; $src = ml($image, $more); - echo '<a href="'.$src.'" target="_blank" title="'.$lang['mediaview'].'">'; - echo '<img src="'.$src.'" alt="" style="max-width: '.$size[0].'px;" />'; + echo '<a href="' . $src . '" target="_blank" title="' . $lang['mediaview'] . '">'; + echo '<img src="' . $src . '" alt="" style="max-width: ' . $size[0] . 'px;" />'; echo '</a>'; echo '</div>'; @@ -1059,13 +1117,13 @@ function media_preview($image, $auth, $rev = '', $meta = false) { * @param int $auth permission level * @param int|string $rev revision timestamp, or empty string */ -function media_preview_buttons($image, $auth, $rev = '') { +function media_preview_buttons($image, $auth, $rev = '') +{ global $lang, $conf; echo '<ul class="actions">'; if ($auth >= AUTH_DELETE && !$rev && file_exists(mediaFN($image))) { - // delete button $form = new Form([ 'id' => 'mediamanager__btn_delete', @@ -1081,7 +1139,6 @@ function media_preview_buttons($image, $auth, $rev = '') { $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); if ($auth >= $auth_ow && !$rev) { - // upload new version button $form = new Form([ 'id' => 'mediamanager__btn_update', @@ -1096,11 +1153,10 @@ function media_preview_buttons($image, $auth, $rev = '') { } if ($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && file_exists(mediaFN($image, $rev))) { - // restore button $form = new Form([ 'id' => 'mediamanager__btn_restore', - 'action'=>media_managerURL(['image' => $image], '&'), + 'action' => media_managerURL(['image' => $image], '&'), ]); $form->addTagOpen('div')->addClass('no'); $form->setHiddenField('mediado', 'restore'); @@ -1125,21 +1181,23 @@ function media_preview_buttons($image, $auth, $rev = '') { * @param int $size * @return array */ -function media_image_preview_size($image, $rev, $meta = false, $size = 500) { - if (!preg_match("/\.(jpe?g|gif|png)$/", $image) - || !file_exists($filename = mediaFN($image, $rev)) - ) return array(); +function media_image_preview_size($image, $rev, $meta = false, $size = 500) +{ + if ( + !preg_match("/\.(jpe?g|gif|png)$/", $image) + || !file_exists($filename = mediaFN($image, $rev)) + ) return []; $info = getimagesize($filename); - $w = (int) $info[0]; - $h = (int) $info[1]; + $w = $info[0]; + $h = $info[1]; if ($meta && ($w > $size || $h > $size)) { $ratio = $meta->getResizeRatio($size, $size); $w = floor($w * $ratio); $h = floor($h * $ratio); } - return array($w, $h); + return [$w, $h]; } /** @@ -1152,7 +1210,8 @@ function media_image_preview_size($image, $rev, $meta = false, $size = 500) { * @param string $alt alternative value * @return string */ -function media_getTag($tags, $meta = false, $alt = '') { +function media_getTag($tags, $meta = false, $alt = '') +{ if (!$meta) return $alt; $info = $meta->getField($tags); if (!$info) return $alt; @@ -1167,7 +1226,8 @@ function media_getTag($tags, $meta = false, $alt = '') { * @param JpegMeta $meta * @return array list of tags of the mediafile */ -function media_file_tags($meta) { +function media_file_tags($meta) +{ // load the field descriptions static $fields = null; if (is_null($fields)) { @@ -1177,14 +1237,14 @@ function media_file_tags($meta) { } } - $tags = array(); + $tags = []; - foreach ($fields as $key => $tag) { - $t = array(); - if (!empty($tag[0])) $t = array($tag[0]); - if (isset($tag[3]) && is_array($tag[3])) $t = array_merge($t,$tag[3]); + foreach ($fields as $tag) { + $t = []; + if (!empty($tag[0])) $t = [$tag[0]]; + if (isset($tag[3]) && is_array($tag[3])) $t = array_merge($t, $tag[3]); $value = media_getTag($t, $meta); - $tags[] = array('tag' => $tag, 'value' => $value); + $tags[] = ['tag' => $tag, 'value' => $value]; } return $tags; @@ -1200,35 +1260,35 @@ function media_file_tags($meta) { * @param string|int $rev revision timestamp, or empty string * @param bool|JpegMeta $meta image object, or create one if false */ -function media_details($image, $auth, $rev='', $meta=false) { +function media_details($image, $auth, $rev = '', $meta = false) +{ global $lang; if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev)); $tags = media_file_tags($meta); - echo '<dl>'.NL; - foreach($tags as $tag){ + echo '<dl>' . NL; + foreach ($tags as $tag) { if ($tag['value']) { $value = cleanText($tag['value']); - echo '<dt>'.$lang[$tag['tag'][1]].'</dt><dd>'; + echo '<dt>' . $lang[$tag['tag'][1]] . '</dt><dd>'; if ($tag['tag'][2] == 'date') echo dformat($value); else echo hsc($value); - echo '</dd>'.NL; + echo '</dd>' . NL; } } - echo '</dl>'.NL; - echo '<dl>'.NL; - echo '<dt>'.$lang['reference'].':</dt>'; - $media_usage = ft_mediause($image,true); - if(count($media_usage) > 0){ - foreach($media_usage as $path){ - echo '<dd>'.html_wikilink($path).'</dd>'; + echo '</dl>' . NL; + echo '<dl>' . NL; + echo '<dt>' . $lang['reference'] . ':</dt>'; + $media_usage = ft_mediause($image, true); + if ($media_usage !== []) { + foreach ($media_usage as $path) { + echo '<dd>' . html_wikilink($path) . '</dd>'; } - }else{ - echo '<dd>'.$lang['nothingfound'].'</dd>'; + } else { + echo '<dd>' . $lang['nothingfound'] . '</dd>'; } - echo '</dl>'.NL; - + echo '</dl>' . NL; } /** @@ -1243,8 +1303,9 @@ function media_details($image, $auth, $rev='', $meta=false) { * * @deprecated 2020-12-31 */ -function media_diff($image, $ns, $auth, $fromajax = false) { - dbg_deprecated('see '. MediaDiff::class .'::show()'); +function media_diff($image, $ns, $auth, $fromajax = false) +{ + dbg_deprecated('see ' . MediaDiff::class . '::show()'); } /** @@ -1254,8 +1315,9 @@ function media_diff($image, $ns, $auth, $fromajax = false) { * * @deprecated 2020-12-31 */ -function _media_file_diff($data) { - dbg_deprecated('see '. MediaDiff::class .'::show()'); +function _media_file_diff($data) +{ + dbg_deprecated('see ' . MediaDiff::class . '::show()'); } /** @@ -1271,8 +1333,9 @@ function _media_file_diff($data) { * @param bool $fromajax * @deprecated 2020-12-31 */ -function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) { - dbg_deprecated('see '. MediaDiff::class .'::showFileDiff()'); +function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) +{ + dbg_deprecated('see ' . MediaDiff::class . '::showFileDiff()'); } /** @@ -1289,8 +1352,9 @@ function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) { * @param string $type * @deprecated 2020-12-31 */ -function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) { - dbg_deprecated('see '. MediaDiff::class .'::showImageDiff()'); +function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) +{ + dbg_deprecated('see ' . MediaDiff::class . '::showImageDiff()'); } /** @@ -1303,19 +1367,22 @@ function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) { * * @author Kate Arzamastseva <pshns@ukr.net> */ -function media_restore($image, $rev, $auth){ +function media_restore($image, $rev, $auth) +{ global $conf; if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false; $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes'))); if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false; if (!$rev || !file_exists(mediaFN($image, $rev))) return false; - list(,$imime,) = mimetype($image); - $res = media_upload_finish(mediaFN($image, $rev), + [, $imime, ] = mimetype($image); + $res = media_upload_finish( + mediaFN($image, $rev), mediaFN($image), $image, $imime, true, - 'copy'); + 'copy' + ); if (is_array($res)) { msg($res[0], $res[1]); return false; @@ -1337,52 +1404,55 @@ function media_restore($image, $rev, $auth){ * @param bool $fullscreen * @param string $sort */ -function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural'){ +function media_searchlist($query, $ns, $auth = null, $fullscreen = false, $sort = 'natural') +{ global $conf; global $lang; $ns = cleanID($ns); - $evdata = array( + $evdata = [ 'ns' => $ns, - 'data' => array(), + 'data' => [], 'query' => $query - ); + ]; if (!blank($query)) { $evt = new Event('MEDIA_SEARCH', $evdata); if ($evt->advise_before()) { - $dir = utf8_encodeFN(str_replace(':','/',$evdata['ns'])); - $quoted = preg_quote($evdata['query'],'/'); + $dir = utf8_encodeFN(str_replace(':', '/', $evdata['ns'])); + $quoted = preg_quote($evdata['query'], '/'); //apply globbing - $quoted = str_replace(array('\*', '\?'), array('.*', '.'), $quoted, $count); + $quoted = str_replace(['\*', '\?'], ['.*', '.'], $quoted, $count); //if we use globbing file name must match entirely but may be preceded by arbitrary namespace - if ($count > 0) $quoted = '^([^:]*:)*'.$quoted.'$'; - - $pattern = '/'.$quoted.'/i'; - search($evdata['data'], - $conf['mediadir'], - 'search_mediafiles', - array('showmsg'=>false,'pattern'=>$pattern), - $dir, - 1, - $sort); + if ($count > 0) $quoted = '^([^:]*:)*' . $quoted . '$'; + + $pattern = '/' . $quoted . '/i'; + search( + $evdata['data'], + $conf['mediadir'], + 'search_mediafiles', + ['showmsg' => false, 'pattern' => $pattern], + $dir, + 1, + $sort + ); } $evt->advise_after(); unset($evt); } if (!$fullscreen) { - echo '<h1 id="media__ns">'.sprintf($lang['searchmedia_in'],hsc($ns).':*').'</h1>'.NL; - media_searchform($ns,$query); + echo '<h1 id="media__ns">' . sprintf($lang['searchmedia_in'], hsc($ns) . ':*') . '</h1>' . NL; + media_searchform($ns, $query); } - if(!count($evdata['data'])){ - echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; - }else { + if (!count($evdata['data'])) { + echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; + } else { if ($fullscreen) { echo '<ul class="' . _media_get_list_type() . '">'; } - foreach($evdata['data'] as $item){ + foreach ($evdata['data'] as $item) { if (!$fullscreen) { // FIXME old call: media_printfile($item,$item['perm'],'',true); $display = new DisplayRow($item); @@ -1397,7 +1467,7 @@ function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural echo '</li>'; } } - if ($fullscreen) echo '</ul>'.NL; + if ($fullscreen) echo '</ul>' . NL; } } @@ -1408,16 +1478,17 @@ function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural * @param string $size the size subfolder, if not specified 16x16 is used * @return string html */ -function media_printicon($filename, $size=''){ - list($ext) = mimetype(mediaFN($filename),false); +function media_printicon($filename, $size = '') +{ + [$ext] = mimetype(mediaFN($filename), false); - if (file_exists(DOKU_INC.'lib/images/fileicons/'.$size.'/'.$ext.'.png')) { - $icon = DOKU_BASE.'lib/images/fileicons/'.$size.'/'.$ext.'.png'; + if (file_exists(DOKU_INC . 'lib/images/fileicons/' . $size . '/' . $ext . '.png')) { + $icon = DOKU_BASE . 'lib/images/fileicons/' . $size . '/' . $ext . '.png'; } else { - $icon = DOKU_BASE.'lib/images/fileicons/'.$size.'/file.png'; + $icon = DOKU_BASE . 'lib/images/fileicons/' . $size . '/file.png'; } - return '<img src="'.$icon.'" alt="'.$filename.'" class="icon" />'; + return '<img src="' . $icon . '" alt="' . $filename . '" class="icon" />'; } /** @@ -1431,12 +1502,13 @@ function media_printicon($filename, $size=''){ * @param bool $params_array return the parmeters array? * @return string|array - link or link parameters */ -function media_managerURL($params = false, $amp = '&', $abs = false, $params_array = false) { +function media_managerURL($params = false, $amp = '&', $abs = false, $params_array = false) +{ global $ID; global $INPUT; - $gets = array('do' => 'media'); - $media_manager_params = array('tab_files', 'tab_details', 'image', 'ns', 'list', 'sort'); + $gets = ['do' => 'media']; + $media_manager_params = ['tab_files', 'tab_details', 'image', 'ns', 'list', 'sort']; foreach ($media_manager_params as $x) { if ($INPUT->has($x)) $gets[$x] = $INPUT->str($x); } @@ -1452,7 +1524,7 @@ function media_managerURL($params = false, $amp = '&', $abs = false, $params if ($params_array) return $gets; - return wl($ID,$gets,$abs,$amp); + return wl($ID, $gets, $abs, $amp); } /** @@ -1465,13 +1537,14 @@ function media_managerURL($params = false, $amp = '&', $abs = false, $params * @param int $auth permission level * @param bool $fullscreen */ -function media_uploadform($ns, $auth, $fullscreen = false) { +function media_uploadform($ns, $auth, $fullscreen = false) +{ global $lang; global $conf; global $INPUT; if ($auth < AUTH_UPLOAD) { - echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL; + echo '<div class="nothing">' . $lang['media_perm_upload'] . '</div>' . NL; return; } $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); @@ -1489,7 +1562,7 @@ function media_uploadform($ns, $auth, $fullscreen = false) { 'enctype' => 'multipart/form-data', 'action' => ($fullscreen) ? media_managerURL(['tab_files' => 'files', 'tab_details' => 'view'], '&') - : DOKU_BASE.'lib/exe/mediamanager.php', + : DOKU_BASE . 'lib/exe/mediamanager.php', ]); $form->addTagOpen('div')->addClass('no'); $form->setHiddenField('ns', hsc($ns)); // FIXME hsc required? @@ -1502,9 +1575,9 @@ function media_uploadform($ns, $auth, $fullscreen = false) { ->val(noNS($id)); $form->addButton('', $lang['btn_upload'])->attr('type', 'submit'); $form->addTagClose('p'); - if ($auth >= $auth_ow){ + if ($auth >= $auth_ow) { $form->addTagOpen('p'); - $attrs = array(); + $attrs = []; if ($update) $attrs['checked'] = 'checked'; $form->addCheckbox('ow', $lang['txt_overwrt'])->id('dw__ow')->val('1') ->addClass('check')->attrs($attrs); @@ -1513,20 +1586,20 @@ function media_uploadform($ns, $auth, $fullscreen = false) { $form->addTagClose('div'); if (!$fullscreen) { - echo '<div class="upload">'. $lang['mediaupload'] .'</div>'.DOKU_LF; + echo '<div class="upload">' . $lang['mediaupload'] . '</div>' . DOKU_LF; } else { echo DOKU_LF; } - echo '<div id="mediamanager__uploader">'.DOKU_LF; + echo '<div id="mediamanager__uploader">' . DOKU_LF; echo $form->toHTML('Upload'); - echo '</div>'.DOKU_LF; + echo '</div>' . DOKU_LF; echo '<p class="maxsize">'; printf($lang['maxuploadsize'], filesize_h(media_getuploadsize())); - echo ' <a class="allowedmime" href="#">'. $lang['allowedmime'] .'</a>'; - echo ' <span>'. implode(', ', array_keys(getMimeTypes())) .'</span>'; - echo '</p>'.DOKU_LF; + echo ' <a class="allowedmime" href="#">' . $lang['allowedmime'] . '</a>'; + echo ' <span>' . implode(', ', array_keys(getMimeTypes())) . '</span>'; + echo '</p>' . DOKU_LF; } /** @@ -1537,16 +1610,17 @@ function media_uploadform($ns, $auth, $fullscreen = false) { * * @returns int size in bytes */ -function media_getuploadsize(){ +function media_getuploadsize() +{ $okay = 0; - $post = (int) php_to_byte(@ini_get('post_max_size')); - $suho = (int) php_to_byte(@ini_get('suhosin.post.max_value_length')); - $upld = (int) php_to_byte(@ini_get('upload_max_filesize')); + $post = php_to_byte(@ini_get('post_max_size')); + $suho = php_to_byte(@ini_get('suhosin.post.max_value_length')); + $upld = php_to_byte(@ini_get('upload_max_filesize')); - if($post && ($post < $okay || $okay == 0)) $okay = $post; - if($suho && ($suho < $okay || $okay == 0)) $okay = $suho; - if($upld && ($upld < $okay || $okay == 0)) $okay = $upld; + if ($post && ($post < $okay || $okay === 0)) $okay = $post; + if ($suho && ($suho < $okay || $okay == 0)) $okay = $suho; + if ($upld && ($upld < $okay || $okay == 0)) $okay = $upld; return $okay; } @@ -1561,7 +1635,8 @@ function media_getuploadsize(){ * @param string $query * @param bool $fullscreen */ -function media_searchform($ns, $query = '', $fullscreen = false) { +function media_searchform($ns, $query = '', $fullscreen = false) +{ global $lang; // The default HTML search form @@ -1569,7 +1644,7 @@ function media_searchform($ns, $query = '', $fullscreen = false) { 'id' => 'dw__mediasearch', 'action' => ($fullscreen) ? media_managerURL([], '&') - : DOKU_BASE.'lib/exe/mediamanager.php', + : DOKU_BASE . 'lib/exe/mediamanager.php', ]); $form->addTagOpen('div')->addClass('no'); $form->setHiddenField('ns', $ns); @@ -1577,13 +1652,13 @@ function media_searchform($ns, $query = '', $fullscreen = false) { $form->addTagOpen('p'); $form->addTextInput('q', $lang['searchmedia']) - ->attr('title', sprintf($lang['searchmedia_in'], hsc($ns) .':*')) + ->attr('title', sprintf($lang['searchmedia_in'], hsc($ns) . ':*')) ->val($query); $form->addHTML(' '); $form->addButton('', $lang['btn_search'])->attr('type', 'submit'); $form->addTagClose('p'); $form->addTagClose('div'); - print $form->toHTML('SearchMedia'); + echo $form->toHTML('SearchMedia'); } /** @@ -1593,48 +1668,48 @@ function media_searchform($ns, $query = '', $fullscreen = false) { * * @param string $ns */ -function media_nstree($ns){ +function media_nstree($ns) +{ global $conf; global $lang; // currently selected namespace $ns = cleanID($ns); - if(empty($ns)){ + if (empty($ns)) { global $ID; $ns = (string)getNS($ID); } - $ns_dir = utf8_encodeFN(str_replace(':','/',$ns)); + $ns_dir = utf8_encodeFN(str_replace(':', '/', $ns)); - $data = array(); - search($data,$conf['mediadir'],'search_index',array('ns' => $ns_dir, 'nofiles' => true)); + $data = []; + search($data, $conf['mediadir'], 'search_index', ['ns' => $ns_dir, 'nofiles' => true]); // wrap a list with the root level around the other namespaces - array_unshift($data, array('level' => 0, 'id' => '', 'open' =>'true', - 'label' => '['.$lang['mediaroot'].']')); + array_unshift($data, ['level' => 0, 'id' => '', 'open' => 'true', 'label' => '[' . $lang['mediaroot'] . ']']); // insert the current ns into the hierarchy if it isn't already part of it $ns_parts = explode(':', $ns); $tmp_ns = ''; $pos = 0; foreach ($ns_parts as $level => $part) { - if ($tmp_ns) $tmp_ns .= ':'.$part; + if ($tmp_ns) $tmp_ns .= ':' . $part; else $tmp_ns = $part; // find the namespace parts or insert them while ($data[$pos]['id'] != $tmp_ns) { if ( $pos >= count($data) || - ($data[$pos]['level'] <= $level+1 && Sort::strcmp($data[$pos]['id'], $tmp_ns) > 0) + ($data[$pos]['level'] <= $level + 1 && Sort::strcmp($data[$pos]['id'], $tmp_ns) > 0) ) { - array_splice($data, $pos, 0, array(array('level' => $level+1, 'id' => $tmp_ns, 'open' => 'true'))); + array_splice($data, $pos, 0, [['level' => $level + 1, 'id' => $tmp_ns, 'open' => 'true']]); break; } ++$pos; } } - echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li'); + echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); } /** @@ -1647,17 +1722,18 @@ function media_nstree($ns){ * @param array $item * @return string html */ -function media_nstree_item($item){ +function media_nstree_item($item) +{ global $INPUT; $pos = strrpos($item['id'], ':'); $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); - if(empty($item['label'])) $item['label'] = $label; + if (empty($item['label'])) $item['label'] = $label; $ret = ''; - if (!($INPUT->str('do') == 'media')) - $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">'; - else $ret .= '<a href="'.media_managerURL(['ns' => idfilter($item['id'], false), 'tab_files' => 'files']) - .'" class="idx_dir">'; + if ($INPUT->str('do') != 'media') + $ret .= '<a href="' . DOKU_BASE . 'lib/exe/mediamanager.php?ns=' . idfilter($item['id']) . '" class="idx_dir">'; + else $ret .= '<a href="' . media_managerURL(['ns' => idfilter($item['id'], false), 'tab_files' => 'files']) + . '" class="idx_dir">'; $ret .= $item['label']; $ret .= '</a>'; return $ret; @@ -1673,20 +1749,21 @@ function media_nstree_item($item){ * @param array $item * @return string html */ -function media_nstree_li($item){ - $class='media level'.$item['level']; - if($item['open']){ +function media_nstree_li($item) +{ + $class = 'media level' . $item['level']; + if ($item['open']) { $class .= ' open'; - $img = DOKU_BASE.'lib/images/minus.gif'; + $img = DOKU_BASE . 'lib/images/minus.gif'; $alt = '−'; - }else{ + } else { $class .= ' closed'; - $img = DOKU_BASE.'lib/images/plus.gif'; + $img = DOKU_BASE . 'lib/images/plus.gif'; $alt = '+'; } // TODO: only deliver an image if it actually has a subtree... - return '<li class="'.$class.'">'. - '<img src="'.$img.'" alt="'.$alt.'" />'; + return '<li class="' . $class . '">' . + '<img src="' . $img . '" alt="' . $alt . '" />'; } /** @@ -1701,12 +1778,12 @@ function media_nstree_li($item){ * @param bool $crop should a center crop be used? * @return string path to resized or original size if failed */ -function media_mod_image($file, $ext, $w, $h=0, $crop=false) +function media_mod_image($file, $ext, $w, $h = 0, $crop = false) { global $conf; - if(!$h) $h = 0; + if (!$h) $h = 0; // we wont scale up to infinity - if($w > 2000 || $h > 2000) return $file; + if ($w > 2000 || $h > 2000) return $file; $operation = $crop ? 'crop' : 'resize'; @@ -1715,15 +1792,15 @@ function media_mod_image($file, $ext, $w, $h=0, $crop=false) 'imconvert' => $conf['im_convert'], ]; - $cache = new \dokuwiki\Cache\CacheImageMod($file, $w, $h, $ext, $crop); - if(!$cache->useCache()) { + $cache = new CacheImageMod($file, $w, $h, $ext, $crop); + if (!$cache->useCache()) { try { Slika::run($file, $options) ->autorotate() ->$operation($w, $h) ->save($cache->cache, $ext); - if($conf['fperm']) @chmod($cache->cache, $conf['fperm']); - } catch (\splitbrain\slika\Exception $e) { + if ($conf['fperm']) @chmod($cache->cache, $conf['fperm']); + } catch (Exception $e) { Logger::debug($e->getMessage()); return $file; } @@ -1776,14 +1853,15 @@ function media_crop_image($file, $ext, $w, $h = 0) * @param int $h resize/crop height * @return string token or empty string if no token required */ -function media_get_token($id,$w,$h){ +function media_get_token($id, $w, $h) +{ // token is only required for modified images if ($w || $h || media_isexternal($id)) { $token = $id; - if ($w) $token .= '.'.$w; - if ($h) $token .= '.'.$h; + if ($w) $token .= '.' . $w; + if ($h) $token .= '.' . $h; - return substr(\dokuwiki\PassHash::hmac('md5', $token, auth_cookiesalt()),0,6); + return substr(PassHash::hmac('md5', $token, auth_cookiesalt()), 0, 6); } return ''; @@ -1803,21 +1881,23 @@ function media_get_token($id,$w,$h){ * @param int $cache cachetime in seconds * @return false|string path to cached file */ -function media_get_from_URL($url,$ext,$cache){ +function media_get_from_URL($url, $ext, $cache) +{ global $conf; // if no cache or fetchsize just redirect - if ($cache==0) return false; + if ($cache == 0) return false; if (!$conf['fetchsize']) return false; - $local = getCacheName(strtolower($url),".media.$ext"); + $local = getCacheName(strtolower($url), ".media.$ext"); $mtime = @filemtime($local); // 0 if not exists //decide if download needed: - if(($mtime == 0) || // cache does not exist + if ( + ($mtime == 0) || // cache does not exist ($cache != -1 && $mtime < time() - $cache) // 'recache' and cache has expired ) { - if(media_image_download($url, $local)) { + if (media_image_download($url, $local)) { return $local; } else { return false; @@ -1825,7 +1905,7 @@ function media_get_from_URL($url,$ext,$cache){ } //if cache exists use it else - if($mtime) return $local; + if ($mtime) return $local; //else return false return false; @@ -1840,7 +1920,8 @@ function media_get_from_URL($url,$ext,$cache){ * @param string $file path to file in which to put the downloaded content * @return bool */ -function media_image_download($url,$file){ +function media_image_download($url, $file) +{ global $conf; $http = new DokuHTTPClient(); $http->keep_alive = false; // we do single ops here, no need for keep-alive @@ -1850,18 +1931,18 @@ function media_image_download($url,$file){ $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; $data = $http->get($url); - if(!$data) return false; + if (!$data) return false; $fileexists = file_exists($file); - $fp = @fopen($file,"w"); - if(!$fp) return false; - fwrite($fp,$data); + $fp = @fopen($file, "w"); + if (!$fp) return false; + fwrite($fp, $data); fclose($fp); - if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); + if (!$fileexists && $conf['fperm']) chmod($file, $conf['fperm']); // check if it is really an image $info = @getimagesize($file); - if(!$info){ + if (!$info) { @unlink($file); return false; } @@ -1884,21 +1965,22 @@ function media_image_download($url,$file){ * @param int $to_h desired height * @return bool */ -function media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ +function media_resize_imageIM($ext, $from, $from_w, $from_h, $to, $to_w, $to_h) +{ global $conf; // check if convert is configured - if(!$conf['im_convert']) return false; + if (!$conf['im_convert']) return false; // prepare command $cmd = $conf['im_convert']; - $cmd .= ' -resize '.$to_w.'x'.$to_h.'!'; + $cmd .= ' -resize ' . $to_w . 'x' . $to_h . '!'; if ($ext == 'jpg' || $ext == 'jpeg') { - $cmd .= ' -quality '.$conf['jpg_quality']; + $cmd .= ' -quality ' . $conf['jpg_quality']; } $cmd .= " $from $to"; - @exec($cmd,$out,$retval); + @exec($cmd, $out, $retval); if ($retval == 0) return true; return false; } @@ -1920,22 +2002,23 @@ function media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ * @return bool * @deprecated 2020-09-01 */ -function media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){ +function media_crop_imageIM($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x, $ofs_y) +{ global $conf; dbg_deprecated('splitbrain\\Slika'); // check if convert is configured - if(!$conf['im_convert']) return false; + if (!$conf['im_convert']) return false; // prepare command $cmd = $conf['im_convert']; - $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y; + $cmd .= ' -crop ' . $to_w . 'x' . $to_h . '+' . $ofs_x . '+' . $ofs_y; if ($ext == 'jpg' || $ext == 'jpeg') { - $cmd .= ' -quality '.$conf['jpg_quality']; + $cmd .= ' -quality ' . $conf['jpg_quality']; } $cmd .= " $from $to"; - @exec($cmd,$out,$retval); + @exec($cmd, $out, $retval); if ($retval == 0) return true; return false; } @@ -1958,53 +2041,53 @@ function media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$o * @return bool * @deprecated 2020-09-01 */ -function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){ +function media_resize_imageGD($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x = 0, $ofs_y = 0) +{ global $conf; dbg_deprecated('splitbrain\\Slika'); - if($conf['gdlib'] < 1) return false; //no GDlib available or wanted + if ($conf['gdlib'] < 1) return false; //no GDlib available or wanted // check available memory - if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){ + if (!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))) { return false; } // create an image of the given filetype $image = false; - if ($ext == 'jpg' || $ext == 'jpeg'){ - if(!function_exists("imagecreatefromjpeg")) return false; + if ($ext == 'jpg' || $ext == 'jpeg') { + if (!function_exists("imagecreatefromjpeg")) return false; $image = @imagecreatefromjpeg($from); - }elseif($ext == 'png') { - if(!function_exists("imagecreatefrompng")) return false; + } elseif ($ext == 'png') { + if (!function_exists("imagecreatefrompng")) return false; $image = @imagecreatefrompng($from); - - }elseif($ext == 'gif') { - if(!function_exists("imagecreatefromgif")) return false; + } elseif ($ext == 'gif') { + if (!function_exists("imagecreatefromgif")) return false; $image = @imagecreatefromgif($from); } - if(!$image) return false; + if (!$image) return false; $newimg = false; - if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){ - $newimg = @imagecreatetruecolor ($to_w, $to_h); + if (($conf['gdlib'] > 1) && function_exists("imagecreatetruecolor") && $ext != 'gif') { + $newimg = @imagecreatetruecolor($to_w, $to_h); } - if(!$newimg) $newimg = @imagecreate($to_w, $to_h); - if(!$newimg){ + if (!$newimg) $newimg = @imagecreate($to_w, $to_h); + if (!$newimg) { imagedestroy($image); return false; } //keep png alpha channel if possible - if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ + if ($ext == 'png' && $conf['gdlib'] > 1 && function_exists('imagesavealpha')) { imagealphablending($newimg, false); - imagesavealpha($newimg,true); + imagesavealpha($newimg, true); } //keep gif transparent color if possible - if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { - if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { + if ($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { + if (function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { $transcolorindex = @imagecolortransparent($image); - if($transcolorindex >= 0 ) { //transparent color exists + if ($transcolorindex >= 0) { //transparent color exists $transcolor = @imagecolorsforindex($image, $transcolorindex); $transcolorindex = @imagecolorallocate( $newimg, @@ -2014,42 +2097,42 @@ function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x= ); @imagefill($newimg, 0, 0, $transcolorindex); @imagecolortransparent($newimg, $transcolorindex); - }else{ //filling with white + } else { //filling with white $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); @imagefill($newimg, 0, 0, $whitecolorindex); } - }else{ //filling with white + } else { //filling with white $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); @imagefill($newimg, 0, 0, $whitecolorindex); } } //try resampling first - if(function_exists("imagecopyresampled")){ - if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { + if (function_exists("imagecopyresampled")) { + if (!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); } - }else{ + } else { imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); } $okay = false; - if ($ext == 'jpg' || $ext == 'jpeg'){ - if(!function_exists('imagejpeg')){ + if ($ext == 'jpg' || $ext == 'jpeg') { + if (!function_exists('imagejpeg')) { $okay = false; - }else{ + } else { $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); } - }elseif($ext == 'png') { - if(!function_exists('imagepng')){ + } elseif ($ext == 'png') { + if (!function_exists('imagepng')) { $okay = false; - }else{ + } else { $okay = imagepng($newimg, $to); } - }elseif($ext == 'gif') { - if(!function_exists('imagegif')){ + } elseif ($ext == 'gif') { + if (!function_exists('imagegif')) { $okay = false; - }else{ + } else { $okay = imagegif($newimg, $to); } } @@ -2071,17 +2154,18 @@ function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x= * * @author Anika Henke <anika@selfthinker.org> */ -function media_alternativefiles($src, $exts){ +function media_alternativefiles($src, $exts) +{ - $files = array(); - list($srcExt, /* $srcMime */) = mimetype($src); - $filebase = substr($src, 0, -1 * (strlen($srcExt)+1)); + $files = []; + [$srcExt, /* srcMime */] = mimetype($src); + $filebase = substr($src, 0, -1 * (strlen($srcExt) + 1)); - foreach($exts as $ext) { - $fileid = $filebase.'.'.$ext; + foreach ($exts as $ext) { + $fileid = $filebase . '.' . $ext; $file = mediaFN($fileid); - if(file_exists($file)) { - list(/* $fileExt */, $fileMime) = mimetype($file); + if (file_exists($file)) { + [/* fileExt */, $fileMime] = mimetype($file); $files[$fileMime] = $fileid; } } @@ -2097,17 +2181,18 @@ function media_alternativefiles($src, $exts){ * * @author Anika Henke <anika@selfthinker.org> */ -function media_supportedav($mime, $type=NULL){ - $supportedAudio = array( +function media_supportedav($mime, $type = null) +{ + $supportedAudio = [ 'ogg' => 'audio/ogg', 'mp3' => 'audio/mpeg', - 'wav' => 'audio/wav', - ); - $supportedVideo = array( + 'wav' => 'audio/wav' + ]; + $supportedVideo = [ 'webm' => 'video/webm', 'ogv' => 'video/ogg', - 'mp4' => 'video/mp4', - ); + 'mp4' => 'video/mp4' + ]; if ($type == 'audio') { $supportedAv = $supportedAudio; } elseif ($type == 'video') { @@ -2128,26 +2213,24 @@ function media_supportedav($mime, $type=NULL){ * * @author Schplurtz le Déboulonné <Schplurtz@laposte.net> */ -function media_trackfiles($src){ - $kinds=array( +function media_trackfiles($src) +{ + $kinds = [ 'sub' => 'subtitles', 'cap' => 'captions', 'des' => 'descriptions', 'cha' => 'chapters', 'met' => 'metadata' - ); + ]; - $files = array(); - $re='/\\.(sub|cap|des|cha|met)\\.([^.]+)\\.vtt$/'; - $baseid=pathinfo($src, PATHINFO_FILENAME); - $pattern=mediaFN($baseid).'.*.*.vtt'; - $list=glob($pattern); - foreach($list as $track) { - if(preg_match($re, $track, $matches)){ - $files[$baseid.'.'.$matches[1].'.'.$matches[2].'.vtt']=array( - $kinds[$matches[1]], - $matches[2], - ); + $files = []; + $re = '/\\.(sub|cap|des|cha|met)\\.([^.]+)\\.vtt$/'; + $baseid = pathinfo($src, PATHINFO_FILENAME); + $pattern = mediaFN($baseid) . '.*.*.vtt'; + $list = glob($pattern); + foreach ($list as $track) { + if (preg_match($re, $track, $matches)) { + $files[$baseid . '.' . $matches[1] . '.' . $matches[2] . '.vtt'] = [$kinds[$matches[1]], $matches[2]]; } } return $files; diff --git a/inc/pageutils.php b/inc/pageutils.php index 6af58ed82..0907a049e 100644 --- a/inc/pageutils.php +++ b/inc/pageutils.php @@ -8,6 +8,10 @@ * @todo Combine similar functions like {wiki,media,meta}FN() */ +use dokuwiki\Utf8\PhpString; +use dokuwiki\Utf8\Clean; +use dokuwiki\File\Resolver; +use dokuwiki\Extension\Event; use dokuwiki\ChangeLog\MediaChangeLog; use dokuwiki\ChangeLog\PageChangeLog; use dokuwiki\File\MediaResolver; @@ -49,7 +53,7 @@ function getID($param = 'id', $clean = true) $relpath = 'lib/exe/'; } $script = $conf['basedir'] . $relpath . - \dokuwiki\Utf8\PhpString::basename($INPUT->server->str('SCRIPT_FILENAME')); + PhpString::basename($INPUT->server->str('SCRIPT_FILENAME')); } elseif ($INPUT->server->str('PATH_INFO')) { $request = $INPUT->server->str('PATH_INFO'); } elseif ($INPUT->server->str('SCRIPT_NAME')) { @@ -80,16 +84,16 @@ function getID($param = 'id', $clean = true) if (substr($id, -1) == ':' || ($conf['useslash'] && substr($id, -1) == '/')) { if (page_exists($id . $conf['start'])) { // start page inside namespace - $id = $id . $conf['start']; + $id .= $conf['start']; } elseif (page_exists($id . noNS(cleanID($id)))) { // page named like the NS inside the NS - $id = $id . noNS(cleanID($id)); + $id .= noNS(cleanID($id)); } elseif (page_exists($id)) { // page like namespace exists $id = substr($id, 0, -1); } else { // fall back to default - $id = $id . $conf['start']; + $id .= $conf['start']; } if (isset($ACT) && $ACT === 'show') { $urlParameters = $_GET; @@ -135,7 +139,7 @@ function cleanID($raw_id, $ascii = false) $sepcharpat = '#\\' . $sepchar . '+#'; $id = trim((string)$raw_id); - $id = \dokuwiki\Utf8\PhpString::strtolower($id); + $id = PhpString::strtolower($id); //alternative namespace seperator if ($conf['useslash']) { @@ -144,13 +148,13 @@ function cleanID($raw_id, $ascii = false) $id = strtr($id, ';/', ':' . $sepchar); } - if ($conf['deaccent'] == 2 || $ascii) $id = \dokuwiki\Utf8\Clean::romanize($id); - if ($conf['deaccent'] || $ascii) $id = \dokuwiki\Utf8\Clean::deaccent($id, -1); + if ($conf['deaccent'] == 2 || $ascii) $id = Clean::romanize($id); + if ($conf['deaccent'] || $ascii) $id = Clean::deaccent($id, -1); //remove specials - $id = \dokuwiki\Utf8\Clean::stripspecials($id, $sepchar, '\*'); + $id = Clean::stripspecials($id, $sepchar, '\*'); - if ($ascii) $id = \dokuwiki\Utf8\Clean::strip($id); + if ($ascii) $id = Clean::strip($id); //clean up $id = preg_replace($sepcharpat, $sepchar, $id); @@ -244,7 +248,7 @@ function noNSorNS($id) */ function sectionID($title, &$check) { - $title = str_replace(array(':','.'), '', cleanID($title)); + $title = str_replace([':', '.'], '', cleanID($title)); $new = ltrim($title, '0123456789_-'); if (empty($new)) { $title = 'section' . preg_replace('/[^0-9]+/', '', $title); //keep numbers from headline @@ -359,7 +363,7 @@ function wikiFN($raw_id, $rev = '', $clean = true) } if (!isset($cache[$id])) { - $cache[$id] = array(); + $cache[$id] = []; } $cache[$id][$rev] = $fn; return $fn; @@ -394,6 +398,7 @@ function metaFN($id, $ext) global $conf; $id = cleanID($id); $id = str_replace(':', '/', $id); + $fn = $conf['metadir'] . '/' . utf8_encodeFN($id) . $ext; return $fn; } @@ -412,6 +417,7 @@ function mediaMetaFN($id, $ext) global $conf; $id = cleanID($id); $id = str_replace(':', '/', $id); + $fn = $conf['mediametadir'] . '/' . utf8_encodeFN($id) . $ext; return $fn; } @@ -430,7 +436,7 @@ function metaFiles($id) $basename = metaFN($id, ''); $files = glob($basename . '.*', GLOB_MARK); // filter files like foo.bar.meta when $id == 'foo' - return $files ? preg_grep('/^' . preg_quote($basename, '/') . '\.[^.\/]*$/u', $files) : array(); + return $files ? preg_grep('/^' . preg_quote($basename, '/') . '\.[^.\/]*$/u', $files) : []; } /** @@ -504,7 +510,7 @@ function localeFN($id, $ext = 'txt') function resolve_id($ns, $id, $clean = true) { global $conf; - dbg_deprecated(\dokuwiki\File\Resolver::class . ' and its children'); + dbg_deprecated(Resolver::class . ' and its children'); // some pre cleaning for useslash: if ($conf['useslash']) $id = str_replace('/', ':', $id); @@ -518,10 +524,10 @@ function resolve_id($ns, $id, $clean = true) $id = $ns . ':' . $id; // cleanup relatives - $result = array(); + $result = []; $pathA = explode(':', $id); if (!$pathA[0]) $result[] = ''; - foreach ($pathA as $key => $dir) { + foreach ($pathA as $dir) { if ($dir == '..') { if (end($result) == '..') { $result[] = '..'; @@ -617,11 +623,8 @@ function getCacheName($data, $ext = '') */ function isHiddenPage($id) { - $data = array( - 'id' => $id, - 'hidden' => false - ); - \dokuwiki\Extension\Event::createAndTrigger('PAGEUTILS_ID_HIDEPAGE', $data, '_isHiddenPage'); + $data = ['id' => $id, 'hidden' => false]; + Event::createAndTrigger('PAGEUTILS_ID_HIDEPAGE', $data, '_isHiddenPage'); return $data['hidden']; } diff --git a/inc/parser/code.php b/inc/parser/code.php index cded87d6d..ac2e136dd 100644 --- a/inc/parser/code.php +++ b/inc/parser/code.php @@ -1,10 +1,15 @@ <?php + +use dokuwiki\Utf8\Clean; +use dokuwiki\Utf8\PhpString; + /** * A simple renderer that allows downloading of code and file snippets * * @author Andreas Gohr <andi@splitbrain.org> */ -class Doku_Renderer_code extends Doku_Renderer { +class Doku_Renderer_code extends Doku_Renderer +{ protected $_codeblock = 0; /** @@ -16,20 +21,21 @@ class Doku_Renderer_code extends Doku_Renderer { * @param string $language * @param string $filename */ - public function code($text, $language = null, $filename = '') { + public function code($text, $language = null, $filename = '') + { global $INPUT; - if(!$language) $language = 'txt'; + if (!$language) $language = 'txt'; $language = preg_replace(PREG_PATTERN_VALID_LANGUAGE, '', $language); - if(!$filename) $filename = 'snippet.'.$language; - $filename = \dokuwiki\Utf8\PhpString::basename($filename); - $filename = \dokuwiki\Utf8\Clean::stripspecials($filename, '_'); + if (!$filename) $filename = 'snippet.' . $language; + $filename = PhpString::basename($filename); + $filename = Clean::stripspecials($filename, '_'); // send CRLF to Windows clients - if(strpos($INPUT->server->str('HTTP_USER_AGENT'), 'Windows') !== false) { + if (strpos($INPUT->server->str('HTTP_USER_AGENT'), 'Windows') !== false) { $text = str_replace("\n", "\r\n", $text); } - if($this->_codeblock == $INPUT->str('codeblock')) { + if ($this->_codeblock == $INPUT->str('codeblock')) { header("Content-Type: text/plain; charset=utf-8"); header("Content-Disposition: attachment; filename=$filename"); header("X-Robots-Tag: noindex"); @@ -47,14 +53,16 @@ class Doku_Renderer_code extends Doku_Renderer { * @param string $language * @param string $filename */ - public function file($text, $language = null, $filename = '') { + public function file($text, $language = null, $filename = '') + { $this->code($text, $language, $filename); } /** * This should never be reached, if it is send a 404 */ - public function document_end() { + public function document_end() + { http_status(404); echo '404 - Not found'; exit; @@ -65,7 +73,8 @@ class Doku_Renderer_code extends Doku_Renderer { * * @returns string 'code' */ - public function getFormat() { + public function getFormat() + { return 'code'; } } diff --git a/inc/parser/handler.php b/inc/parser/handler.php index 1ef9ffdd5..c68190442 100644 --- a/inc/parser/handler.php +++ b/inc/parser/handler.php @@ -14,18 +14,19 @@ use dokuwiki\Parsing\Handler\Table; /** * Class Doku_Handler */ -class Doku_Handler { +class Doku_Handler +{ /** @var CallWriterInterface */ - protected $callWriter = null; + protected $callWriter; /** @var array The current CallWriter will write directly to this list of calls, Parser reads it */ - public $calls = array(); + public $calls = []; /** @var array internal status holders for some modes */ - protected $status = array( + protected $status = [ 'section' => false, - 'doublequote' => 0, - ); + 'doublequote' => 0 + ]; /** @var bool should blocks be rewritten? FIXME seems to always be true */ protected $rewriteBlocks = true; @@ -38,7 +39,8 @@ class Doku_Handler { /** * Doku_Handler constructor. */ - public function __construct() { + public function __construct() + { $this->callWriter = new CallWriter($this); } @@ -47,10 +49,11 @@ class Doku_Handler { * * @param string $handler handler method name (see mode handlers below) * @param mixed $args arguments for this call - * @param int $pos byte position in the original source file + * @param int $pos byte position in the original source file */ - public function addCall($handler, $args, $pos) { - $call = array($handler,$args, $pos); + public function addCall($handler, $args, $pos) + { + $call = [$handler, $args, $pos]; $this->callWriter->writeCall($call); } @@ -59,7 +62,8 @@ class Doku_Handler { * * @return CallWriterInterface */ - public function getCallWriter() { + public function getCallWriter() + { return $this->callWriter; } @@ -68,7 +72,8 @@ class Doku_Handler { * * @param CallWriterInterface $callWriter */ - public function setCallWriter($callWriter) { + public function setCallWriter($callWriter) + { $this->callWriter = $callWriter; } @@ -78,7 +83,8 @@ class Doku_Handler { * @param string $status * @return mixed|null */ - public function getStatus($status) { + public function getStatus($status) + { if (!isset($this->status[$status])) return null; return $this->status[$status]; } @@ -89,12 +95,14 @@ class Doku_Handler { * @param string $status * @param mixed $value */ - public function setStatus($status, $value) { + public function setStatus($status, $value) + { $this->status[$status] = $value; } /** @deprecated 2019-10-31 use addCall() instead */ - public function _addCall($handler, $args, $pos) { + public function _addCall($handler, $args, $pos) + { dbg_deprecated('addCall'); $this->addCall($handler, $args, $pos); } @@ -108,8 +116,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @param string $match matched syntax */ - public function addPluginCall($plugin, $args, $state, $pos, $match) { - $call = array('plugin',array($plugin, $args, $state, $match), $pos); + public function addPluginCall($plugin, $args, $state, $pos, $match) + { + $call = ['plugin', [$plugin, $args, $state, $match], $pos]; $this->callWriter->writeCall($call); } @@ -121,24 +130,25 @@ class Doku_Handler { * * @triggers PARSER_HANDLER_DONE */ - public function finalize(){ + public function finalize() + { $this->callWriter->finalise(); - if ( $this->status['section'] ) { + if ($this->status['section']) { $last_call = end($this->calls); - array_push($this->calls,array('section_close',array(), $last_call[2])); + $this->calls[] = ['section_close', [], $last_call[2]]; } - if ( $this->rewriteBlocks ) { + if ($this->rewriteBlocks) { $B = new Block(); $this->calls = $B->process($this->calls); } - Event::createAndTrigger('PARSER_HANDLER_DONE',$this); + Event::createAndTrigger('PARSER_HANDLER_DONE', $this); - array_unshift($this->calls,array('document_start',array(),0)); + array_unshift($this->calls, ['document_start', [], 0]); $last_call = end($this->calls); - array_push($this->calls,array('document_end',array(),$last_call[2])); + $this->calls[] = ['document_end', [], $last_call[2]]; } /** @@ -147,9 +157,10 @@ class Doku_Handler { * @fixme seems to be unused? * @return bool|mixed */ - public function fetch() { + public function fetch() + { $call = current($this->calls); - if($call !== false) { + if ($call !== false) { next($this->calls); //advance the pointer return $call; } @@ -169,8 +180,9 @@ class Doku_Handler { * @return array|null Array of key-value pairs $array['key'] = 'value'; * or null if no entries found */ - protected function parse_highlight_options($options) { - $result = array(); + protected function parse_highlight_options($options) + { + $result = []; preg_match_all('/(\w+(?:="[^"]*"))|(\w+(?:=[^\s]*))|(\w+[^=\s\]])(?:\s*)/', $options, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $equal_sign = strpos($match [0], '='); @@ -179,7 +191,7 @@ class Doku_Handler { $result [$key] = 1; } else { $key = substr($match[0], 0, $equal_sign); - $value = substr($match[0], $equal_sign+1); + $value = substr($match[0], $equal_sign + 1); $value = trim($value, '"'); if (strlen($value) > 0) { $result [$key] = $value; @@ -192,34 +204,34 @@ class Doku_Handler { // Check for supported options $result = array_intersect_key( $result, - array_flip(array( - 'enable_line_numbers', - 'start_line_numbers_at', - 'highlight_lines_extra', - 'enable_keyword_links') - ) + array_flip([ + 'enable_line_numbers', + 'start_line_numbers_at', + 'highlight_lines_extra', + 'enable_keyword_links' + ]) ); // Sanitize values - if(isset($result['enable_line_numbers'])) { - if($result['enable_line_numbers'] === 'false') { + if (isset($result['enable_line_numbers'])) { + if ($result['enable_line_numbers'] === 'false') { $result['enable_line_numbers'] = false; } - $result['enable_line_numbers'] = (bool) $result['enable_line_numbers']; + $result['enable_line_numbers'] = (bool)$result['enable_line_numbers']; } - if(isset($result['highlight_lines_extra'])) { + if (isset($result['highlight_lines_extra'])) { $result['highlight_lines_extra'] = array_map('intval', explode(',', $result['highlight_lines_extra'])); $result['highlight_lines_extra'] = array_filter($result['highlight_lines_extra']); $result['highlight_lines_extra'] = array_unique($result['highlight_lines_extra']); } - if(isset($result['start_line_numbers_at'])) { - $result['start_line_numbers_at'] = (int) $result['start_line_numbers_at']; + if (isset($result['start_line_numbers_at'])) { + $result['start_line_numbers_at'] = (int)$result['start_line_numbers_at']; } - if(isset($result['enable_keyword_links'])) { - if($result['enable_keyword_links'] === 'false') { + if (isset($result['enable_keyword_links'])) { + if ($result['enable_keyword_links'] === 'false') { $result['enable_keyword_links'] = false; } - $result['enable_keyword_links'] = (bool) $result['enable_keyword_links']; + $result['enable_keyword_links'] = (bool)$result['enable_keyword_links']; } if (count($result) == 0) { return null; @@ -236,16 +248,17 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @param string $name actual mode name */ - protected function nestingTag($match, $state, $pos, $name) { - switch ( $state ) { + protected function nestingTag($match, $state, $pos, $name) + { + switch ($state) { case DOKU_LEXER_ENTER: - $this->addCall($name.'_open', array(), $pos); + $this->addCall($name . '_open', [], $pos); break; case DOKU_LEXER_EXIT: - $this->addCall($name.'_close', array(), $pos); + $this->addCall($name . '_close', [], $pos); break; case DOKU_LEXER_UNMATCHED: - $this->addCall('cdata', array($match), $pos); + $this->addCall('cdata', [$match], $pos); break; } } @@ -268,23 +281,24 @@ class Doku_Handler { * An additional parameter with the plugin name is passed. The plugin's handle() * method is called here * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $match matched syntax * @param int $state a LEXER_STATE_* constant * @param int $pos byte position in the original source file * @param string $pluginname name of the plugin * @return bool mode handled? + * @author Andreas Gohr <andi@splitbrain.org> + * */ - public function plugin($match, $state, $pos, $pluginname){ - $data = array($match); + public function plugin($match, $state, $pos, $pluginname) + { + $data = [$match]; /** @var SyntaxPlugin $plugin */ - $plugin = plugin_load('syntax',$pluginname); - if($plugin != null){ + $plugin = plugin_load('syntax', $pluginname); + if ($plugin != null) { $data = $plugin->handle($match, $state, $pos, $this); } if ($data !== false) { - $this->addPluginCall($pluginname,$data,$state,$pos,$match); + $this->addPluginCall($pluginname, $data, $state, $pos, $match); } return true; } @@ -295,12 +309,11 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function base($match, $state, $pos) { - switch ( $state ) { - case DOKU_LEXER_UNMATCHED: - $this->addCall('cdata', array($match), $pos); - return true; - break; + public function base($match, $state, $pos) + { + if ($state === DOKU_LEXER_UNMATCHED) { + $this->addCall('cdata', [$match], $pos); + return true; } return false; } @@ -311,19 +324,20 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function header($match, $state, $pos) { + public function header($match, $state, $pos) + { // get level and title $title = trim($match); - $level = 7 - strspn($title,'='); - if($level < 1) $level = 1; - $title = trim($title,'='); + $level = 7 - strspn($title, '='); + if ($level < 1) $level = 1; + $title = trim($title, '='); $title = trim($title); - if ($this->status['section']) $this->addCall('section_close', array(), $pos); + if ($this->status['section']) $this->addCall('section_close', [], $pos); - $this->addCall('header', array($title, $level, $pos), $pos); + $this->addCall('header', [$title, $level, $pos], $pos); - $this->addCall('section_open', array($level), $pos); + $this->addCall('section_open', [$level], $pos); $this->status['section'] = true; return true; } @@ -334,8 +348,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function notoc($match, $state, $pos) { - $this->addCall('notoc', array(), $pos); + public function notoc($match, $state, $pos) + { + $this->addCall('notoc', [], $pos); return true; } @@ -345,8 +360,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function nocache($match, $state, $pos) { - $this->addCall('nocache', array(), $pos); + public function nocache($match, $state, $pos) + { + $this->addCall('nocache', [], $pos); return true; } @@ -356,8 +372,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function linebreak($match, $state, $pos) { - $this->addCall('linebreak', array(), $pos); + public function linebreak($match, $state, $pos) + { + $this->addCall('linebreak', [], $pos); return true; } @@ -367,8 +384,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function eol($match, $state, $pos) { - $this->addCall('eol', array(), $pos); + public function eol($match, $state, $pos) + { + $this->addCall('eol', [], $pos); return true; } @@ -378,8 +396,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function hr($match, $state, $pos) { - $this->addCall('hr', array(), $pos); + public function hr($match, $state, $pos) + { + $this->addCall('hr', [], $pos); return true; } @@ -389,7 +408,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function strong($match, $state, $pos) { + public function strong($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'strong'); return true; } @@ -400,7 +420,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function emphasis($match, $state, $pos) { + public function emphasis($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'emphasis'); return true; } @@ -411,7 +432,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function underline($match, $state, $pos) { + public function underline($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'underline'); return true; } @@ -422,7 +444,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function monospace($match, $state, $pos) { + public function monospace($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'monospace'); return true; } @@ -433,7 +456,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function subscript($match, $state, $pos) { + public function subscript($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'subscript'); return true; } @@ -444,7 +468,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function superscript($match, $state, $pos) { + public function superscript($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'superscript'); return true; } @@ -455,7 +480,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function deleted($match, $state, $pos) { + public function deleted($match, $state, $pos) + { $this->nestingTag($match, $state, $pos, 'deleted'); return true; } @@ -466,39 +492,40 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function footnote($match, $state, $pos) { + public function footnote($match, $state, $pos) + { if (!isset($this->footnote)) $this->footnote = false; - switch ( $state ) { + switch ($state) { case DOKU_LEXER_ENTER: // footnotes can not be nested - however due to limitations in lexer it can't be prevented // we will still enter a new footnote mode, we just do nothing if ($this->footnote) { - $this->addCall('cdata', array($match), $pos); + $this->addCall('cdata', [$match], $pos); break; } $this->footnote = true; $this->callWriter = new Nest($this->callWriter, 'footnote_close'); - $this->addCall('footnote_open', array(), $pos); - break; + $this->addCall('footnote_open', [], $pos); + break; case DOKU_LEXER_EXIT: // check whether we have already exitted the footnote mode, can happen if the modes were nested if (!$this->footnote) { - $this->addCall('cdata', array($match), $pos); + $this->addCall('cdata', [$match], $pos); break; } $this->footnote = false; - $this->addCall('footnote_close', array(), $pos); + $this->addCall('footnote_close', [], $pos); /** @var Nest $reWriter */ $reWriter = $this->callWriter; $this->callWriter = $reWriter->process(); - break; + break; case DOKU_LEXER_UNMATCHED: - $this->addCall('cdata', array($match), $pos); - break; + $this->addCall('cdata', [$match], $pos); + break; } return true; } @@ -509,24 +536,25 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function listblock($match, $state, $pos) { - switch ( $state ) { + public function listblock($match, $state, $pos) + { + switch ($state) { case DOKU_LEXER_ENTER: $this->callWriter = new Lists($this->callWriter); - $this->addCall('list_open', array($match), $pos); - break; + $this->addCall('list_open', [$match], $pos); + break; case DOKU_LEXER_EXIT: - $this->addCall('list_close', array(), $pos); + $this->addCall('list_close', [], $pos); /** @var Lists $reWriter */ $reWriter = $this->callWriter; $this->callWriter = $reWriter->process(); - break; + break; case DOKU_LEXER_MATCHED: - $this->addCall('list_item', array($match), $pos); - break; + $this->addCall('list_item', [$match], $pos); + break; case DOKU_LEXER_UNMATCHED: - $this->addCall('cdata', array($match), $pos); - break; + $this->addCall('cdata', [$match], $pos); + break; } return true; } @@ -537,9 +565,10 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function unformatted($match, $state, $pos) { - if ( $state == DOKU_LEXER_UNMATCHED ) { - $this->addCall('unformatted', array($match), $pos); + public function unformatted($match, $state, $pos) + { + if ($state == DOKU_LEXER_UNMATCHED) { + $this->addCall('unformatted', [$match], $pos); } return true; } @@ -550,24 +579,25 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function preformatted($match, $state, $pos) { - switch ( $state ) { + public function preformatted($match, $state, $pos) + { + switch ($state) { case DOKU_LEXER_ENTER: $this->callWriter = new Preformatted($this->callWriter); - $this->addCall('preformatted_start', array(), $pos); - break; + $this->addCall('preformatted_start', [], $pos); + break; case DOKU_LEXER_EXIT: - $this->addCall('preformatted_end', array(), $pos); + $this->addCall('preformatted_end', [], $pos); /** @var Preformatted $reWriter */ $reWriter = $this->callWriter; $this->callWriter = $reWriter->process(); - break; + break; case DOKU_LEXER_MATCHED: - $this->addCall('preformatted_newline', array(), $pos); - break; + $this->addCall('preformatted_newline', [], $pos); + break; case DOKU_LEXER_UNMATCHED: - $this->addCall('preformatted_content', array($match), $pos); - break; + $this->addCall('preformatted_content', [$match], $pos); + break; } return true; @@ -579,30 +609,29 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function quote($match, $state, $pos) { - - switch ( $state ) { + public function quote($match, $state, $pos) + { + switch ($state) { case DOKU_LEXER_ENTER: $this->callWriter = new Quote($this->callWriter); - $this->addCall('quote_start', array($match), $pos); - break; + $this->addCall('quote_start', [$match], $pos); + break; case DOKU_LEXER_EXIT: - $this->addCall('quote_end', array(), $pos); + $this->addCall('quote_end', [], $pos); /** @var Lists $reWriter */ $reWriter = $this->callWriter; $this->callWriter = $reWriter->process(); - break; + break; case DOKU_LEXER_MATCHED: - $this->addCall('quote_newline', array($match), $pos); - break; + $this->addCall('quote_newline', [$match], $pos); + break; case DOKU_LEXER_UNMATCHED: - $this->addCall('cdata', array($match), $pos); - break; - + $this->addCall('cdata', [$match], $pos); + break; } return true; @@ -614,7 +643,8 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function file($match, $state, $pos) { + public function file($match, $state, $pos) + { return $this->code($match, $state, $pos, 'file'); } @@ -625,22 +655,23 @@ class Doku_Handler { * @param string $type either 'code' or 'file' * @return bool mode handled? */ - public function code($match, $state, $pos, $type='code') { - if ( $state == DOKU_LEXER_UNMATCHED ) { - $matches = sexplode('>',$match,2,''); + public function code($match, $state, $pos, $type = 'code') + { + if ($state == DOKU_LEXER_UNMATCHED) { + $matches = sexplode('>', $match, 2, ''); // Cut out variable options enclosed in [] preg_match('/\[.*\]/', $matches[0], $options); if (!empty($options[0])) { $matches[0] = str_replace($options[0], '', $matches[0]); } $param = preg_split('/\s+/', $matches[0], 2, PREG_SPLIT_NO_EMPTY); - while(count($param) < 2) array_push($param, null); + while (count($param) < 2) $param[] = null; // We shortcut html here. if ($param[0] == 'html') $param[0] = 'html4strict'; if ($param[0] == '-') $param[0] = null; array_unshift($param, $matches[1]); if (!empty($options[0])) { - $param [] = $this->parse_highlight_options ($options[0]); + $param [] = $this->parse_highlight_options($options[0]); } $this->addCall($type, $param, $pos); } @@ -653,8 +684,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function acronym($match, $state, $pos) { - $this->addCall('acronym', array($match), $pos); + public function acronym($match, $state, $pos) + { + $this->addCall('acronym', [$match], $pos); return true; } @@ -664,8 +696,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function smiley($match, $state, $pos) { - $this->addCall('smiley', array($match), $pos); + public function smiley($match, $state, $pos) + { + $this->addCall('smiley', [$match], $pos); return true; } @@ -675,8 +708,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function wordblock($match, $state, $pos) { - $this->addCall('wordblock', array($match), $pos); + public function wordblock($match, $state, $pos) + { + $this->addCall('wordblock', [$match], $pos); return true; } @@ -686,8 +720,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function entity($match, $state, $pos) { - $this->addCall('entity', array($match), $pos); + public function entity($match, $state, $pos) + { + $this->addCall('entity', [$match], $pos); return true; } @@ -697,9 +732,10 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function multiplyentity($match, $state, $pos) { - preg_match_all('/\d+/',$match,$matches); - $this->addCall('multiplyentity', array($matches[0][0], $matches[0][1]), $pos); + public function multiplyentity($match, $state, $pos) + { + preg_match_all('/\d+/', $match, $matches); + $this->addCall('multiplyentity', [$matches[0][0], $matches[0][1]], $pos); return true; } @@ -709,8 +745,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function singlequoteopening($match, $state, $pos) { - $this->addCall('singlequoteopening', array(), $pos); + public function singlequoteopening($match, $state, $pos) + { + $this->addCall('singlequoteopening', [], $pos); return true; } @@ -720,8 +757,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function singlequoteclosing($match, $state, $pos) { - $this->addCall('singlequoteclosing', array(), $pos); + public function singlequoteclosing($match, $state, $pos) + { + $this->addCall('singlequoteclosing', [], $pos); return true; } @@ -731,8 +769,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function apostrophe($match, $state, $pos) { - $this->addCall('apostrophe', array(), $pos); + public function apostrophe($match, $state, $pos) + { + $this->addCall('apostrophe', [], $pos); return true; } @@ -742,8 +781,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function doublequoteopening($match, $state, $pos) { - $this->addCall('doublequoteopening', array(), $pos); + public function doublequoteopening($match, $state, $pos) + { + $this->addCall('doublequoteopening', [], $pos); $this->status['doublequote']++; return true; } @@ -754,11 +794,12 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function doublequoteclosing($match, $state, $pos) { + public function doublequoteclosing($match, $state, $pos) + { if ($this->status['doublequote'] <= 0) { $this->doublequoteopening($match, $state, $pos); } else { - $this->addCall('doublequoteclosing', array(), $pos); + $this->addCall('doublequoteclosing', [], $pos); $this->status['doublequote'] = max(0, --$this->status['doublequote']); } return true; @@ -770,8 +811,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function camelcaselink($match, $state, $pos) { - $this->addCall('camelcaselink', array($match), $pos); + public function camelcaselink($match, $state, $pos) + { + $this->addCall('camelcaselink', [$match], $pos); return true; } @@ -781,15 +823,16 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function internallink($match, $state, $pos) { + public function internallink($match, $state, $pos) + { // Strip the opening and closing markup - $link = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match); + $link = preg_replace(['/^\[\[/', '/\]\]$/u'], '', $match); // Split title from URL - $link = sexplode('|',$link,2); - if ( $link[1] === null ) { + $link = sexplode('|', $link, 2); + if ($link[1] === null) { $link[1] = null; - } else if ( preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) { + } elseif (preg_match('/^\{\{[^\}]+\}\}$/', $link[1])) { // If the title is an image, convert it to an array containing the image details $link[1] = Doku_Handler_Parse_Media($link[1]); } @@ -797,49 +840,49 @@ class Doku_Handler { //decide which kind of link it is - if ( link_isinterwiki($link[0]) ) { + if (link_isinterwiki($link[0])) { // Interwiki - $interwiki = sexplode('>',$link[0],2,''); + $interwiki = sexplode('>', $link[0], 2, ''); $this->addCall( 'interwikilink', - array($link[0],$link[1],strtolower($interwiki[0]),$interwiki[1]), + [$link[0], $link[1], strtolower($interwiki[0]), $interwiki[1]], $pos - ); - }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) { + ); + } elseif (preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u', $link[0])) { // Windows Share $this->addCall( 'windowssharelink', - array($link[0],$link[1]), + [$link[0], $link[1]], $pos - ); - }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) { + ); + } elseif (preg_match('#^([a-z0-9\-\.+]+?)://#i', $link[0])) { // external link (accepts all protocols) $this->addCall( - 'externallink', - array($link[0],$link[1]), - $pos - ); - }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) { + 'externallink', + [$link[0], $link[1]], + $pos + ); + } elseif (preg_match('<' . PREG_PATTERN_VALID_EMAIL . '>', $link[0])) { // E-Mail (pattern above is defined in inc/mail.php) $this->addCall( 'emaillink', - array($link[0],$link[1]), + [$link[0], $link[1]], $pos - ); - }elseif ( preg_match('!^#.+!',$link[0]) ){ + ); + } elseif (preg_match('!^#.+!', $link[0])) { // local link $this->addCall( 'locallink', - array(substr($link[0],1),$link[1]), + [substr($link[0], 1), $link[1]], $pos - ); - }else{ + ); + } else { // internal link $this->addCall( 'internallink', - array($link[0],$link[1]), + [$link[0], $link[1]], $pos - ); + ); } return true; @@ -851,8 +894,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function filelink($match, $state, $pos) { - $this->addCall('filelink', array($match, null), $pos); + public function filelink($match, $state, $pos) + { + $this->addCall('filelink', [$match, null], $pos); return true; } @@ -862,8 +906,9 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function windowssharelink($match, $state, $pos) { - $this->addCall('windowssharelink', array($match, null), $pos); + public function windowssharelink($match, $state, $pos) + { + $this->addCall('windowssharelink', [$match, null], $pos); return true; } @@ -873,15 +918,15 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function media($match, $state, $pos) { + public function media($match, $state, $pos) + { $p = Doku_Handler_Parse_Media($match); $this->addCall( - $p['type'], - array($p['src'], $p['title'], $p['align'], $p['width'], - $p['height'], $p['cache'], $p['linking']), - $pos - ); + $p['type'], + [$p['src'], $p['title'], $p['align'], $p['width'], $p['height'], $p['cache'], $p['linking']], + $pos + ); return true; } @@ -891,32 +936,33 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function rss($match, $state, $pos) { - $link = preg_replace(array('/^\{\{rss>/','/\}\}$/'),'',$match); + public function rss($match, $state, $pos) + { + $link = preg_replace(['/^\{\{rss>/', '/\}\}$/'], '', $match); // get params - list($link, $params) = sexplode(' ', $link, 2, ''); + [$link, $params] = sexplode(' ', $link, 2, ''); - $p = array(); - if(preg_match('/\b(\d+)\b/',$params,$match)){ + $p = []; + if (preg_match('/\b(\d+)\b/', $params, $match)) { $p['max'] = $match[1]; - }else{ + } else { $p['max'] = 8; } - $p['reverse'] = (preg_match('/rev/',$params)); - $p['author'] = (preg_match('/\b(by|author)/',$params)); - $p['date'] = (preg_match('/\b(date)/',$params)); - $p['details'] = (preg_match('/\b(desc|detail)/',$params)); - $p['nosort'] = (preg_match('/\b(nosort)\b/',$params)); - - if (preg_match('/\b(\d+)([dhm])\b/',$params,$match)) { - $period = array('d' => 86400, 'h' => 3600, 'm' => 60); - $p['refresh'] = max(600,$match[1]*$period[$match[2]]); // n * period in seconds, minimum 10 minutes + $p['reverse'] = (preg_match('/rev/', $params)); + $p['author'] = (preg_match('/\b(by|author)/', $params)); + $p['date'] = (preg_match('/\b(date)/', $params)); + $p['details'] = (preg_match('/\b(desc|detail)/', $params)); + $p['nosort'] = (preg_match('/\b(nosort)\b/', $params)); + + if (preg_match('/\b(\d+)([dhm])\b/', $params, $match)) { + $period = ['d' => 86400, 'h' => 3600, 'm' => 60]; + $p['refresh'] = max(600, $match[1] * $period[$match[2]]); // n * period in seconds, minimum 10 minutes } else { $p['refresh'] = 14400; // default to 4 hours } - $this->addCall('rss', array($link, $p), $pos); + $this->addCall('rss', [$link, $p], $pos); return true; } @@ -926,21 +972,22 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function externallink($match, $state, $pos) { - $url = $match; + public function externallink($match, $state, $pos) + { + $url = $match; $title = null; // add protocol on simple short URLs - if(substr($url,0,3) == 'ftp' && (substr($url,0,6) != 'ftp://')){ + if (str_starts_with($url, 'ftp') && !str_starts_with($url, 'ftp://')) { $title = $url; - $url = 'ftp://'.$url; + $url = 'ftp://' . $url; } - if(substr($url,0,3) == 'www' && (substr($url,0,7) != 'http://')){ + if (str_starts_with($url, 'www')) { $title = $url; - $url = 'http://'.$url; + $url = 'http://' . $url; } - $this->addCall('externallink', array($url, $title), $pos); + $this->addCall('externallink', [$url, $title], $pos); return true; } @@ -950,9 +997,10 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function emaillink($match, $state, $pos) { - $email = preg_replace(array('/^</','/>$/'),'',$match); - $this->addCall('emaillink', array($email, null), $pos); + public function emaillink($match, $state, $pos) + { + $email = preg_replace(['/^</', '/>$/'], '', $match); + $this->addCall('emaillink', [$email, null], $pos); return true; } @@ -962,55 +1010,54 @@ class Doku_Handler { * @param int $pos byte position in the original source file * @return bool mode handled? */ - public function table($match, $state, $pos) { - switch ( $state ) { - + public function table($match, $state, $pos) + { + switch ($state) { case DOKU_LEXER_ENTER: - $this->callWriter = new Table($this->callWriter); - $this->addCall('table_start', array($pos + 1), $pos); - if ( trim($match) == '^' ) { - $this->addCall('tableheader', array(), $pos); + $this->addCall('table_start', [$pos + 1], $pos); + if (trim($match) == '^') { + $this->addCall('tableheader', [], $pos); } else { - $this->addCall('tablecell', array(), $pos); + $this->addCall('tablecell', [], $pos); } - break; + break; case DOKU_LEXER_EXIT: - $this->addCall('table_end', array($pos), $pos); + $this->addCall('table_end', [$pos], $pos); /** @var Table $reWriter */ $reWriter = $this->callWriter; $this->callWriter = $reWriter->process(); - break; + break; case DOKU_LEXER_UNMATCHED: - if ( trim($match) != '' ) { - $this->addCall('cdata', array($match), $pos); + if (trim($match) != '') { + $this->addCall('cdata', [$match], $pos); } - break; + break; case DOKU_LEXER_MATCHED: - if ( $match == ' ' ){ - $this->addCall('cdata', array($match), $pos); - } else if ( preg_match('/:::/',$match) ) { - $this->addCall('rowspan', array($match), $pos); - } else if ( preg_match('/\t+/',$match) ) { - $this->addCall('table_align', array($match), $pos); - } else if ( preg_match('/ {2,}/',$match) ) { - $this->addCall('table_align', array($match), $pos); - } else if ( $match == "\n|" ) { - $this->addCall('table_row', array(), $pos); - $this->addCall('tablecell', array(), $pos); - } else if ( $match == "\n^" ) { - $this->addCall('table_row', array(), $pos); - $this->addCall('tableheader', array(), $pos); - } else if ( $match == '|' ) { - $this->addCall('tablecell', array(), $pos); - } else if ( $match == '^' ) { - $this->addCall('tableheader', array(), $pos); + if ($match == ' ') { + $this->addCall('cdata', [$match], $pos); + } elseif (preg_match('/:::/', $match)) { + $this->addCall('rowspan', [$match], $pos); + } elseif (preg_match('/\t+/', $match)) { + $this->addCall('table_align', [$match], $pos); + } elseif (preg_match('/ {2,}/', $match)) { + $this->addCall('table_align', [$match], $pos); + } elseif ($match == "\n|") { + $this->addCall('table_row', [], $pos); + $this->addCall('tablecell', [], $pos); + } elseif ($match == "\n^") { + $this->addCall('table_row', [], $pos); + $this->addCall('tableheader', [], $pos); + } elseif ($match == '|') { + $this->addCall('tablecell', [], $pos); + } elseif ($match == '^') { + $this->addCall('tableheader', [], $pos); } - break; + break; } return true; } @@ -1019,31 +1066,32 @@ class Doku_Handler { } //------------------------------------------------------------------------ -function Doku_Handler_Parse_Media($match) { +function Doku_Handler_Parse_Media($match) +{ // Strip the opening and closing markup - $link = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match); + $link = preg_replace(['/^\{\{/', '/\}\}$/u'], '', $match); // Split title from URL $link = sexplode('|', $link, 2); // Check alignment - $ralign = (bool)preg_match('/^ /',$link[0]); - $lalign = (bool)preg_match('/ $/',$link[0]); + $ralign = (bool)preg_match('/^ /', $link[0]); + $lalign = (bool)preg_match('/ $/', $link[0]); // Logic = what's that ;)... - if ( $lalign & $ralign ) { + if ($lalign & $ralign) { $align = 'center'; - } else if ( $ralign ) { + } elseif ($ralign) { $align = 'right'; - } else if ( $lalign ) { + } elseif ($lalign) { $align = 'left'; } else { $align = null; } // The title... - if ( !isset($link[1]) ) { + if (!isset($link[1])) { $link[1] = null; } @@ -1052,59 +1100,58 @@ function Doku_Handler_Parse_Media($match) { //split into src and parameters (using the very last questionmark) $pos = strrpos($link[0], '?'); - if($pos !== false){ - $src = substr($link[0],0,$pos); - $param = substr($link[0],$pos+1); - }else{ - $src = $link[0]; + if ($pos !== false) { + $src = substr($link[0], 0, $pos); + $param = substr($link[0], $pos + 1); + } else { + $src = $link[0]; $param = ''; } //parse width and height - if(preg_match('#(\d+)(x(\d+))?#i',$param,$size)){ - !empty($size[1]) ? $w = $size[1] : $w = null; - !empty($size[3]) ? $h = $size[3] : $h = null; + if (preg_match('#(\d+)(x(\d+))?#i', $param, $size)) { + $w = empty($size[1]) ? null : $size[1]; + $h = empty($size[3]) ? null : $size[3]; } else { $w = null; $h = null; } //get linking command - if(preg_match('/nolink/i',$param)){ + if (preg_match('/nolink/i', $param)) { $linking = 'nolink'; - }else if(preg_match('/direct/i',$param)){ + } elseif (preg_match('/direct/i', $param)) { $linking = 'direct'; - }else if(preg_match('/linkonly/i',$param)){ + } elseif (preg_match('/linkonly/i', $param)) { $linking = 'linkonly'; - }else{ + } else { $linking = 'details'; } //get caching command - if (preg_match('/(nocache|recache)/i',$param,$cachemode)){ + if (preg_match('/(nocache|recache)/i', $param, $cachemode)) { $cache = $cachemode[1]; - }else{ + } else { $cache = 'cache'; } // Check whether this is a local or remote image or interwiki - if (media_isexternal($src) || link_isinterwiki($src)){ + if (media_isexternal($src) || link_isinterwiki($src)) { $call = 'externalmedia'; } else { $call = 'internalmedia'; } - $params = array( - 'type'=>$call, - 'src'=>$src, - 'title'=>$link[1], - 'align'=>$align, - 'width'=>$w, - 'height'=>$h, - 'cache'=>$cache, - 'linking'=>$linking, - ); + $params = [ + 'type' => $call, + 'src' => $src, + 'title' => $link[1], + 'align' => $align, + 'width' => $w, + 'height' => $h, + 'cache' => $cache, + 'linking' => $linking + ]; return $params; } - diff --git a/inc/parser/metadata.php b/inc/parser/metadata.php index 222b3d065..2d84f5060 100644 --- a/inc/parser/metadata.php +++ b/inc/parser/metadata.php @@ -1,4 +1,9 @@ <?php + +use dokuwiki\File\MediaResolver; +use dokuwiki\File\PageResolver; +use dokuwiki\Utf8\PhpString; + /** * The MetaData Renderer * @@ -13,19 +18,19 @@ class Doku_Renderer_metadata extends Doku_Renderer { /** the approximate byte lenght to capture for the abstract */ - const ABSTRACT_LEN = 250; + public const ABSTRACT_LEN = 250; /** the maximum UTF8 character length for the abstract */ - const ABSTRACT_MAX = 500; + public const ABSTRACT_MAX = 500; /** @var array transient meta data, will be reset on each rendering */ - public $meta = array(); + public $meta = []; /** @var array persistent meta data, will be kept until explicitly deleted */ - public $persistent = array(); + public $persistent = []; /** @var array the list of headers used to create unique link ids */ - protected $headers = array(); + protected $headers = []; /** @var string temporary $doc store */ protected $store = ''; @@ -61,7 +66,7 @@ class Doku_Renderer_metadata extends Doku_Renderer { global $ID; - $this->headers = array(); + $this->headers = []; // external pages are missing create date if (!isset($this->persistent['date']['created']) || !$this->persistent['date']['created']) { @@ -93,7 +98,7 @@ class Doku_Renderer_metadata extends Doku_Renderer // cut off too long abstracts $this->doc = trim($this->doc); if (strlen($this->doc) > self::ABSTRACT_MAX) { - $this->doc = \dokuwiki\Utf8\PhpString::substr($this->doc, 0, self::ABSTRACT_MAX).'…'; + $this->doc = PhpString::substr($this->doc, 0, self::ABSTRACT_MAX) . '…'; } $this->meta['description']['abstract'] = $this->doc; } @@ -130,9 +135,9 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Add an item to the TOC * - * @param string $id the hash link - * @param string $text the text to display - * @param int $level the nesting level + * @param string $id the hash link + * @param string $text the text to display + * @param int $level the nesting level */ public function toc_additem($id, $text, $level) { @@ -141,21 +146,21 @@ class Doku_Renderer_metadata extends Doku_Renderer //only add items within configured levels if ($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']) { // the TOC is one of our standard ul list arrays ;-) - $this->meta['description']['tableofcontents'][] = array( - 'hid' => $id, + $this->meta['description']['tableofcontents'][] = [ + 'hid' => $id, 'title' => $text, - 'type' => 'ul', + 'type' => 'ul', 'level' => $level - $conf['toptoclevel'] + 1 - ); + ]; } } /** * Render a heading * - * @param string $text the text to display - * @param int $level header level - * @param int $pos byte position in the original source + * @param string $text the text to display + * @param int $level header level + * @param int $pos byte position in the original source */ public function header($text, $level, $pos) { @@ -168,7 +173,7 @@ class Doku_Renderer_metadata extends Doku_Renderer $this->toc_additem($hid, $text, $level); // add to summary - $this->cdata(DOKU_LF.$text.DOKU_LF); + $this->cdata(DOKU_LF . $text . DOKU_LF); } /** @@ -200,7 +205,7 @@ class Doku_Renderer_metadata extends Doku_Renderer */ public function hr() { - $this->cdata(DOKU_LF.'----------'.DOKU_LF); + $this->cdata(DOKU_LF . '----------' . DOKU_LF); } /** @@ -218,7 +223,7 @@ class Doku_Renderer_metadata extends Doku_Renderer // move current content to store // this is required to ensure safe behaviour of plugins accessed within footnotes $this->store = $this->doc; - $this->doc = ''; + $this->doc = ''; // disable capturing $this->capturing = false; @@ -239,7 +244,7 @@ class Doku_Renderer_metadata extends Doku_Renderer // re-enable capturing $this->capturing = true; // restore previously rendered content - $this->doc = $this->store; + $this->doc = $this->store; $this->store = ''; } } @@ -266,9 +271,9 @@ class Doku_Renderer_metadata extends Doku_Renderer * @param int $level the nesting level * @param bool $node true when a node; false when a leaf */ - public function listitem_open($level, $node=false) + public function listitem_open($level, $node = false) { - $this->cdata(str_repeat(DOKU_TAB, $level).'* '); + $this->cdata(str_repeat(DOKU_TAB, $level) . '* '); } /** @@ -294,7 +299,7 @@ class Doku_Renderer_metadata extends Doku_Renderer */ public function quote_open() { - $this->cdata(DOKU_LF.DOKU_TAB.'"'); + $this->cdata(DOKU_LF . DOKU_TAB . '"'); } /** @@ -302,7 +307,7 @@ class Doku_Renderer_metadata extends Doku_Renderer */ public function quote_close() { - $this->cdata('"'.DOKU_LF); + $this->cdata('"' . DOKU_LF); } /** @@ -314,19 +319,19 @@ class Doku_Renderer_metadata extends Doku_Renderer */ public function file($text, $lang = null, $file = null) { - $this->cdata(DOKU_LF.$text.DOKU_LF); + $this->cdata(DOKU_LF . $text . DOKU_LF); } /** * Display text as code content, optionally syntax highlighted * - * @param string $text text to show + * @param string $text text to show * @param string $language programming language to use for syntax highlighting - * @param string $file file path label + * @param string $file file path label */ public function code($text, $language = null, $file = null) { - $this->cdata(DOKU_LF.$text.DOKU_LF); + $this->cdata(DOKU_LF . $text . DOKU_LF); } /** @@ -377,7 +382,7 @@ class Doku_Renderer_metadata extends Doku_Renderer */ public function multiplyentity($x, $y) { - $this->cdata($x.'×'.$y); + $this->cdata($x . '×' . $y); } /** @@ -455,7 +460,7 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * keep track of internal links in $this->meta['relation']['references'] * - * @param string $id page ID to link to. eg. 'wiki:syntax' + * @param string $id page ID to link to. eg. 'wiki:syntax' * @param string|array|null $name name for the link, array for media file */ public function internallink($id, $name = null) @@ -477,9 +482,9 @@ class Doku_Renderer_metadata extends Doku_Renderer $default = $this->_simpleTitle($id); // first resolve and clean up the $id - $resolver = new \dokuwiki\File\PageResolver($ID); + $resolver = new PageResolver($ID); $id = $resolver->resolveId($id); - list($page) = sexplode('#', $id, 2); + [$page] = sexplode('#', $id, 2); // set metadata $this->meta['relation']['references'][$page] = page_exists($page); @@ -496,7 +501,7 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Render an external link * - * @param string $url full URL with scheme + * @param string $url full URL with scheme * @param string|array|null $name name for the link, array for media file */ public function externallink($url, $name = null) @@ -509,7 +514,7 @@ class Doku_Renderer_metadata extends Doku_Renderer } if ($this->capture) { - $this->doc .= $this->_getLinkTitle($name, '<'.$url.'>'); + $this->doc .= $this->_getLinkTitle($name, '<' . $url . '>'); } } @@ -518,10 +523,10 @@ class Doku_Renderer_metadata extends Doku_Renderer * * You may want to use $this->_resolveInterWiki() here * - * @param string $match original link - probably not much use - * @param string|array $name name for the link, array for media file - * @param string $wikiName indentifier (shortcut) for the remote wiki - * @param string $wikiUri the fragment parsed from the original link + * @param string $match original link - probably not much use + * @param string|array $name name for the link, array for media file + * @param string $wikiName indentifier (shortcut) for the remote wiki + * @param string $wikiUri the fragment parsed from the original link */ public function interwikilink($match, $name, $wikiName, $wikiUri) { @@ -533,7 +538,7 @@ class Doku_Renderer_metadata extends Doku_Renderer } if ($this->capture) { - list($wikiUri) = explode('#', $wikiUri, 2); + [$wikiUri] = explode('#', $wikiUri, 2); $name = $this->_getLinkTitle($name, $wikiUri); $this->doc .= $name; } @@ -542,7 +547,7 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Link to windows share * - * @param string $url the link + * @param string $url the link * @param string|array $name name for the link, array for media file */ public function windowssharelink($url, $name = null) @@ -558,7 +563,7 @@ class Doku_Renderer_metadata extends Doku_Renderer if ($name) { $this->doc .= $name; } else { - $this->doc .= '<'.$url.'>'; + $this->doc .= '<' . $url . '>'; } } } @@ -568,8 +573,8 @@ class Doku_Renderer_metadata extends Doku_Renderer * * Should honor $conf['mailguard'] setting * - * @param string $address Email-Address - * @param string|array $name name for the link, array for media file + * @param string $address Email-Address + * @param string|array $name name for the link, array for media file */ public function emaillink($address, $name = null) { @@ -584,7 +589,7 @@ class Doku_Renderer_metadata extends Doku_Renderer if ($name) { $this->doc .= $name; } else { - $this->doc .= '<'.$address.'>'; + $this->doc .= '<' . $address . '>'; } } } @@ -592,19 +597,25 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Render an internal media file * - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache * @param string $linking linkonly|detail|nolink */ - public function internalmedia($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $linking = null) - { + public function internalmedia( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $linking = null + ) { if ($this->capture && $title) { - $this->doc .= '['.$title.']'; + $this->doc .= '[' . $title . ']'; } $this->_firstimage($src); $this->_recordMediaUsage($src); @@ -613,19 +624,25 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Render an external media file * - * @param string $src full media URL - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src full media URL + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache * @param string $linking linkonly|detail|nolink */ - public function externalmedia($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $linking = null) - { + public function externalmedia( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $linking = null + ) { if ($this->capture && $title) { - $this->doc .= '['.$title.']'; + $this->doc .= '[' . $title . ']'; } $this->_firstimage($src); } @@ -633,8 +650,8 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Render the output of an RSS feed * - * @param string $url URL of the feed - * @param array $params Finetuning of the output + * @param string $url URL of the feed + * @param array $params Finetuning of the output */ public function rss($url, $params) { @@ -652,11 +669,11 @@ class Doku_Renderer_metadata extends Doku_Renderer * Removes any Namespace from the given name but keeps * casing and special chars * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $name * * @return mixed|string + * @author Andreas Gohr <andi@splitbrain.org> + * */ public function _simpleTitle($name) { @@ -671,7 +688,7 @@ class Doku_Renderer_metadata extends Doku_Renderer } else { $nssep = '[:;]'; } - $name = preg_replace('!.*'.$nssep.'!', '', $name); + $name = preg_replace('!.*' . $nssep . '!', '', $name); //if there is a hash we use the anchor name only $name = preg_replace('!.*#!', '', $name); return $name; @@ -680,17 +697,17 @@ class Doku_Renderer_metadata extends Doku_Renderer /** * Construct a title and handle images in titles * - * @author Harry Fuecks <hfuecks@gmail.com> - * @param string|array|null $title either string title or media array - * @param string $default default title if nothing else is found - * @param null|string $id linked page id (used to extract title from first heading) + * @param string|array|null $title either string title or media array + * @param string $default default title if nothing else is found + * @param null|string $id linked page id (used to extract title from first heading) * @return string title text + * @author Harry Fuecks <hfuecks@gmail.com> */ public function _getLinkTitle($title, $default, $id = null) { if (is_array($title)) { if ($title['title']) { - return '['.$title['title'].']'; + return '[' . $title['title'] . ']'; } else { return $default; } @@ -720,9 +737,9 @@ class Doku_Renderer_metadata extends Doku_Renderer return; } - list($src) = explode('#', $src, 2); + [$src] = explode('#', $src, 2); if (!media_isexternal($src)) { - $src = (new \dokuwiki\File\MediaResolver($ID))->resolveId($src); + $src = (new MediaResolver($ID))->resolveId($src); } if (preg_match('/.(jpe?g|gif|png|webp|svg)$/i', $src)) { $this->firstimage = $src; @@ -738,11 +755,11 @@ class Doku_Renderer_metadata extends Doku_Renderer { global $ID; - list ($src) = explode('#', $src, 2); + [$src] = explode('#', $src, 2); if (media_isexternal($src)) { return; } - $src = (new \dokuwiki\File\MediaResolver($ID))->resolveId($src); + $src = (new MediaResolver($ID))->resolveId($src); $file = mediaFN($src); $this->meta['relation']['media'][$src] = file_exists($file); } diff --git a/inc/parser/parser.php b/inc/parser/parser.php index 77f47e3ac..225dee35b 100644 --- a/inc/parser/parser.php +++ b/inc/parser/parser.php @@ -1,67 +1,60 @@ <?php use dokuwiki\Debug\PropertyDeprecationHelper; +use dokuwiki\Parsing\Parser; /** * Define various types of modes used by the parser - they are used to * populate the list of modes another mode accepts */ global $PARSER_MODES; -$PARSER_MODES = array( +$PARSER_MODES = [ // containers are complex modes that can contain many other modes // hr breaks the principle but they shouldn't be used in tables / lists // so they are put here - 'container' => array('listblock', 'table', 'quote', 'hr'), - + 'container' => ['listblock', 'table', 'quote', 'hr'], // some mode are allowed inside the base mode only - 'baseonly' => array('header'), - + 'baseonly' => ['header'], // modes for styling text -- footnote behaves similar to styling - 'formatting' => array( - 'strong', 'emphasis', 'underline', 'monospace', - 'subscript', 'superscript', 'deleted', 'footnote' - ), - + 'formatting' => [ + 'strong', 'emphasis', 'underline', 'monospace', 'subscript', 'superscript', 'deleted', 'footnote' + ], // modes where the token is simply replaced - they can not contain any // other modes - 'substition' => array( - 'acronym', 'smiley', 'wordblock', 'entity', - 'camelcaselink', 'internallink', 'media', - 'externallink', 'linebreak', 'emaillink', - 'windowssharelink', 'filelink', 'notoc', - 'nocache', 'multiplyentity', 'quotes', 'rss' - ), - + 'substition' => [ + 'acronym', 'smiley', 'wordblock', 'entity', 'camelcaselink', 'internallink', 'media', 'externallink', + 'linebreak', 'emaillink', 'windowssharelink', 'filelink', 'notoc', 'nocache', 'multiplyentity', 'quotes', 'rss' + ], // modes which have a start and end token but inside which // no other modes should be applied - 'protected' => array('preformatted', 'code', 'file'), - + 'protected' => ['preformatted', 'code', 'file'], // inside this mode no wiki markup should be applied but lineendings // and whitespace isn't preserved - 'disabled' => array('unformatted'), - + 'disabled' => ['unformatted'], // used to mark paragraph boundaries - 'paragraphs' => array('eol') -); + 'paragraphs' => ['eol'], +]; /** * Class Doku_Parser * * @deprecated 2018-05-04 */ -class Doku_Parser extends \dokuwiki\Parsing\Parser { +class Doku_Parser extends Parser +{ use PropertyDeprecationHelper { __set as protected deprecationHelperMagicSet; __get as protected deprecationHelperMagicGet; } /** @inheritdoc */ - public function __construct(Doku_Handler $handler = null) { - dbg_deprecated(\dokuwiki\Parsing\Parser::class); - $this->deprecatePublicProperty('modes', __CLASS__); - $this->deprecatePublicProperty('connected', __CLASS__); + public function __construct(Doku_Handler $handler = null) + { + dbg_deprecated(Parser::class); + $this->deprecatePublicProperty('modes', self::class); + $this->deprecatePublicProperty('connected', self::class); - if ($handler === null) { + if (!$handler instanceof \Doku_Handler) { $handler = new Doku_Handler(); } diff --git a/inc/parser/renderer.php b/inc/parser/renderer.php index 14ad5d949..cd43997ef 100644 --- a/inc/parser/renderer.php +++ b/inc/parser/renderer.php @@ -1,4 +1,5 @@ <?php + /** * Renderer output base class * @@ -18,7 +19,7 @@ define('PREG_PATTERN_VALID_LANGUAGE', '#[^a-zA-Z0-9\-_]#'); /** * An empty renderer, produces no output * - * Inherits from dokuwiki\Plugin\DokuWiki_Plugin for giving additional functions to render plugins + * Inherits from dokuwiki\Extension\Plugin for giving additional functions to render plugins * * The renderer transforms the syntax instructions created by the parser and handler into the * desired output format. For each instruction a corresponding method defined in this class will @@ -26,26 +27,27 @@ define('PREG_PATTERN_VALID_LANGUAGE', '#[^a-zA-Z0-9\-_]#'); * $doc field. When all instructions are processed, the $doc field contents will be cached by * DokuWiki and sent to the user. */ -abstract class Doku_Renderer extends Plugin { +abstract class Doku_Renderer extends Plugin +{ /** @var array Settings, control the behavior of the renderer */ - public $info = array( + public $info = [ 'cache' => true, // may the rendered result cached? - 'toc' => true, // render the TOC? - ); + 'toc' => true, // render the TOC? + ]; /** @var array contains the smiley configuration, set in p_render() */ - public $smileys = array(); + public $smileys = []; /** @var array contains the entity configuration, set in p_render() */ - public $entities = array(); + public $entities = []; /** @var array contains the acronym configuration, set in p_render() */ - public $acronyms = array(); + public $acronyms = []; /** @var array contains the interwiki configuration, set in p_render() */ - public $interwiki = array(); + public $interwiki = []; /** @var string|int link pages and media against this revision */ public $date_at = ''; /** @var array the list of headers used to create unique link ids */ - protected $headers = array(); + protected $headers = []; /** * @var string the rendered document, this will be cached after the renderer ran through @@ -58,11 +60,12 @@ abstract class Doku_Renderer extends Plugin { * This is called before each use of the renderer object and should be used to * completely reset the state of the renderer to be reused for a new document */ - public function reset(){ - $this->headers = array(); - $this->doc = ''; + public function reset() + { + $this->headers = []; + $this->doc = ''; $this->info['cache'] = true; - $this->info['toc'] = true; + $this->info['toc'] = true; } /** @@ -73,7 +76,8 @@ abstract class Doku_Renderer extends Plugin { * * @return bool false if the plugin has to be instantiated */ - public function isSingleton() { + public function isSingleton() + { return false; } @@ -89,7 +93,8 @@ abstract class Doku_Renderer extends Plugin { /** * Disable caching of this renderer's output */ - public function nocache() { + public function nocache() + { $this->info['cache'] = false; } @@ -98,7 +103,8 @@ abstract class Doku_Renderer extends Plugin { * * This might not be used for certain sub renderer */ - public function notoc() { + public function notoc() + { $this->info['toc'] = false; } @@ -107,15 +113,16 @@ abstract class Doku_Renderer extends Plugin { * * Most likely this needs NOT to be overwritten by sub classes * - * @param string $name Plugin name - * @param mixed $data custom data set by handler + * @param string $name Plugin name + * @param mixed $data custom data set by handler * @param string $state matched state if any * @param string $match raw matched syntax */ - public function plugin($name, $data, $state = '', $match = '') { + public function plugin($name, $data, $state = '', $match = '') + { /** @var SyntaxPlugin $plugin */ $plugin = plugin_load('syntax', $name); - if($plugin != null) { + if ($plugin != null) { $plugin->render($this->getFormat(), $this, $data); } } @@ -126,11 +133,12 @@ abstract class Doku_Renderer extends Plugin { * * @param array $instructions */ - public function nest($instructions) { - foreach($instructions as $instruction) { + public function nest($instructions) + { + foreach ($instructions as $instruction) { // execute the callback against ourself - if(method_exists($this, $instruction[0])) { - call_user_func_array(array($this, $instruction[0]), $instruction[1] ? $instruction[1] : array()); + if (method_exists($this, $instruction[0])) { + call_user_func_array([$this, $instruction[0]], $instruction[1] ?: []); } } } @@ -141,7 +149,8 @@ abstract class Doku_Renderer extends Plugin { * normally the syntax mode should override this instruction when instantiating Doku_Handler_Nest - * however plugins will not be able to - as their instructions require data. */ - public function nest_close() { + public function nest_close() + { } #region Syntax modes - sub classes will need to implement them to fill $doc @@ -149,13 +158,15 @@ abstract class Doku_Renderer extends Plugin { /** * Initialize the document */ - public function document_start() { + public function document_start() + { } /** * Finalize the document */ - public function document_end() { + public function document_end() + { } /** @@ -163,28 +174,31 @@ abstract class Doku_Renderer extends Plugin { * * @return string */ - public function render_TOC() { + public function render_TOC() + { return ''; } /** * Add an item to the TOC * - * @param string $id the hash link - * @param string $text the text to display - * @param int $level the nesting level + * @param string $id the hash link + * @param string $text the text to display + * @param int $level the nesting level */ - public function toc_additem($id, $text, $level) { + public function toc_additem($id, $text, $level) + { } /** * Render a heading * - * @param string $text the text to display - * @param int $level header level - * @param int $pos byte position in the original source + * @param string $text the text to display + * @param int $level header level + * @param int $pos byte position in the original source */ - public function header($text, $level, $pos) { + public function header($text, $level, $pos) + { } /** @@ -192,13 +206,15 @@ abstract class Doku_Renderer extends Plugin { * * @param int $level section level (as determined by the previous header) */ - public function section_open($level) { + public function section_open($level) + { } /** * Close the current section */ - public function section_close() { + public function section_close() + { } /** @@ -206,151 +222,176 @@ abstract class Doku_Renderer extends Plugin { * * @param string $text */ - public function cdata($text) { + public function cdata($text) + { } /** * Open a paragraph */ - public function p_open() { + public function p_open() + { } /** * Close a paragraph */ - public function p_close() { + public function p_close() + { } /** * Create a line break */ - public function linebreak() { + public function linebreak() + { } /** * Create a horizontal line */ - public function hr() { + public function hr() + { } /** * Start strong (bold) formatting */ - public function strong_open() { + public function strong_open() + { } /** * Stop strong (bold) formatting */ - public function strong_close() { + public function strong_close() + { } /** * Start emphasis (italics) formatting */ - public function emphasis_open() { + public function emphasis_open() + { } /** * Stop emphasis (italics) formatting */ - public function emphasis_close() { + public function emphasis_close() + { } /** * Start underline formatting */ - public function underline_open() { + public function underline_open() + { } /** * Stop underline formatting */ - public function underline_close() { + public function underline_close() + { } /** * Start monospace formatting */ - public function monospace_open() { + public function monospace_open() + { } /** * Stop monospace formatting */ - public function monospace_close() { + public function monospace_close() + { } /** * Start a subscript */ - public function subscript_open() { + public function subscript_open() + { } /** * Stop a subscript */ - public function subscript_close() { + public function subscript_close() + { } /** * Start a superscript */ - public function superscript_open() { + public function superscript_open() + { } /** * Stop a superscript */ - public function superscript_close() { + public function superscript_close() + { } /** * Start deleted (strike-through) formatting */ - public function deleted_open() { + public function deleted_open() + { } /** * Stop deleted (strike-through) formatting */ - public function deleted_close() { + public function deleted_close() + { } /** * Start a footnote */ - public function footnote_open() { + public function footnote_open() + { } /** * Stop a footnote */ - public function footnote_close() { + public function footnote_close() + { } /** * Open an unordered list */ - public function listu_open() { + public function listu_open() + { } /** * Close an unordered list */ - public function listu_close() { + public function listu_close() + { } /** * Open an ordered list */ - public function listo_open() { + public function listo_open() + { } /** * Close an ordered list */ - public function listo_close() { + public function listo_close() + { } /** @@ -359,25 +400,29 @@ abstract class Doku_Renderer extends Plugin { * @param int $level the nesting level * @param bool $node true when a node; false when a leaf */ - public function listitem_open($level,$node=false) { + public function listitem_open($level, $node = false) + { } /** * Close a list item */ - public function listitem_close() { + public function listitem_close() + { } /** * Start the content of a list item */ - public function listcontent_open() { + public function listcontent_open() + { } /** * Stop the content of a list item */ - public function listcontent_close() { + public function listcontent_close() + { } /** @@ -387,7 +432,8 @@ abstract class Doku_Renderer extends Plugin { * * @param string $text */ - public function unformatted($text) { + public function unformatted($text) + { $this->cdata($text); } @@ -396,19 +442,22 @@ abstract class Doku_Renderer extends Plugin { * * @param string $text */ - public function preformatted($text) { + public function preformatted($text) + { } /** * Start a block quote */ - public function quote_open() { + public function quote_open() + { } /** * Stop a block quote */ - public function quote_close() { + public function quote_close() + { } /** @@ -418,7 +467,8 @@ abstract class Doku_Renderer extends Plugin { * @param string $lang programming language to use for syntax highlighting * @param string $file file path label */ - public function file($text, $lang = null, $file = null) { + public function file($text, $lang = null, $file = null) + { } /** @@ -428,7 +478,8 @@ abstract class Doku_Renderer extends Plugin { * @param string $lang programming language to use for syntax highlighting * @param string $file file path label */ - public function code($text, $lang = null, $file = null) { + public function code($text, $lang = null, $file = null) + { } /** @@ -438,7 +489,8 @@ abstract class Doku_Renderer extends Plugin { * * @param string $acronym */ - public function acronym($acronym) { + public function acronym($acronym) + { } /** @@ -448,7 +500,8 @@ abstract class Doku_Renderer extends Plugin { * * @param string $smiley */ - public function smiley($smiley) { + public function smiley($smiley) + { } /** @@ -460,7 +513,8 @@ abstract class Doku_Renderer extends Plugin { * * @param string $entity */ - public function entity($entity) { + public function entity($entity) + { } /** @@ -471,37 +525,43 @@ abstract class Doku_Renderer extends Plugin { * @param string|int $x first value * @param string|int $y second value */ - public function multiplyentity($x, $y) { + public function multiplyentity($x, $y) + { } /** * Render an opening single quote char (language specific) */ - public function singlequoteopening() { + public function singlequoteopening() + { } /** * Render a closing single quote char (language specific) */ - public function singlequoteclosing() { + public function singlequoteclosing() + { } /** * Render an apostrophe char (language specific) */ - public function apostrophe() { + public function apostrophe() + { } /** * Render an opening double quote char (language specific) */ - public function doublequoteopening() { + public function doublequoteopening() + { } /** * Render an closinging double quote char (language specific) */ - public function doublequoteclosing() { + public function doublequoteclosing() + { } /** @@ -510,7 +570,8 @@ abstract class Doku_Renderer extends Plugin { * @param string $link The link name * @see http://en.wikipedia.org/wiki/CamelCase */ - public function camelcaselink($link) { + public function camelcaselink($link) + { } /** @@ -519,34 +580,38 @@ abstract class Doku_Renderer extends Plugin { * @param string $hash hash link identifier * @param string $name name for the link */ - public function locallink($hash, $name = null) { + public function locallink($hash, $name = null) + { } /** * Render a wiki internal link * - * @param string $link page ID to link to. eg. 'wiki:syntax' + * @param string $link page ID to link to. eg. 'wiki:syntax' * @param string|array $title name for the link, array for media file */ - public function internallink($link, $title = null) { + public function internallink($link, $title = null) + { } /** * Render an external link * - * @param string $link full URL with scheme + * @param string $link full URL with scheme * @param string|array $title name for the link, array for media file */ - public function externallink($link, $title = null) { + public function externallink($link, $title = null) + { } /** * Render the output of an RSS feed * - * @param string $url URL of the feed - * @param array $params Finetuning of the output + * @param string $url URL of the feed + * @param array $params Finetuning of the output */ - public function rss($url, $params) { + public function rss($url, $params) + { } /** @@ -554,30 +619,33 @@ abstract class Doku_Renderer extends Plugin { * * You may want to use $this->_resolveInterWiki() here * - * @param string $link original link - probably not much use - * @param string|array $title name for the link, array for media file - * @param string $wikiName indentifier (shortcut) for the remote wiki - * @param string $wikiUri the fragment parsed from the original link + * @param string $link original link - probably not much use + * @param string|array $title name for the link, array for media file + * @param string $wikiName indentifier (shortcut) for the remote wiki + * @param string $wikiUri the fragment parsed from the original link */ - public function interwikilink($link, $title, $wikiName, $wikiUri) { + public function interwikilink($link, $title, $wikiName, $wikiUri) + { } /** * Link to file on users OS * - * @param string $link the link + * @param string $link the link * @param string|array $title name for the link, array for media file */ - public function filelink($link, $title = null) { + public function filelink($link, $title = null) + { } /** * Link to windows share * - * @param string $link the link + * @param string $link the link * @param string|array $title name for the link, array for media file */ - public function windowssharelink($link, $title = null) { + public function windowssharelink($link, $title = null) + { } /** @@ -588,65 +656,92 @@ abstract class Doku_Renderer extends Plugin { * @param string $address Email-Address * @param string|array $name name for the link, array for media file */ - public function emaillink($address, $name = null) { + public function emaillink($address, $name = null) + { } /** * Render an internal media file * - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache * @param string $linking linkonly|detail|nolink */ - public function internalmedia($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $linking = null) { + public function internalmedia( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $linking = null + ) { } /** * Render an external media file * - * @param string $src full media URL - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src full media URL + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache * @param string $linking linkonly|detail|nolink */ - public function externalmedia($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $linking = null) { + public function externalmedia( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $linking = null + ) { } /** * Render a link to an internal media file * - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache */ - public function internalmedialink($src, $title = null, $align = null, - $width = null, $height = null, $cache = null) { + public function internalmedialink( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null + ) { } /** * Render a link to an external media file * - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache */ - public function externalmedialink($src, $title = null, $align = null, - $width = null, $height = null, $cache = null) { + public function externalmedialink( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null + ) { } /** @@ -654,9 +749,10 @@ abstract class Doku_Renderer extends Plugin { * * @param int $maxcols maximum number of columns * @param int $numrows NOT IMPLEMENTED - * @param int $pos byte position in the original source + * @param int $pos byte position in the original source */ - public function table_open($maxcols = null, $numrows = null, $pos = null) { + public function table_open($maxcols = null, $numrows = null, $pos = null) + { } /** @@ -664,87 +760,100 @@ abstract class Doku_Renderer extends Plugin { * * @param int $pos byte position in the original source */ - public function table_close($pos = null) { + public function table_close($pos = null) + { } /** * Open a table header */ - public function tablethead_open() { + public function tablethead_open() + { } /** * Close a table header */ - public function tablethead_close() { + public function tablethead_close() + { } /** * Open a table body */ - public function tabletbody_open() { + public function tabletbody_open() + { } /** * Close a table body */ - public function tabletbody_close() { + public function tabletbody_close() + { } /** * Open a table footer */ - public function tabletfoot_open() { + public function tabletfoot_open() + { } /** * Close a table footer */ - public function tabletfoot_close() { + public function tabletfoot_close() + { } /** * Open a table row */ - public function tablerow_open() { + public function tablerow_open() + { } /** * Close a table row */ - public function tablerow_close() { + public function tablerow_close() + { } /** * Open a table header cell * - * @param int $colspan + * @param int $colspan * @param string $align left|center|right - * @param int $rowspan + * @param int $rowspan */ - public function tableheader_open($colspan = 1, $align = null, $rowspan = 1) { + public function tableheader_open($colspan = 1, $align = null, $rowspan = 1) + { } /** * Close a table header cell */ - public function tableheader_close() { + public function tableheader_close() + { } /** * Open a table cell * - * @param int $colspan + * @param int $colspan * @param string $align left|center|right - * @param int $rowspan + * @param int $rowspan */ - public function tablecell_open($colspan = 1, $align = null, $rowspan = 1) { + public function tablecell_open($colspan = 1, $align = null, $rowspan = 1) + { } /** * Close a table cell */ - public function tablecell_close() { + public function tablecell_close() + { } #endregion @@ -754,13 +863,14 @@ abstract class Doku_Renderer extends Plugin { /** * Creates a linkid from a headline * - * @author Andreas Gohr <andi@splitbrain.org> - * @param string $title The headline title - * @param boolean $create Create a new unique ID? + * @param string $title The headline title + * @param boolean $create Create a new unique ID? * @return string + * @author Andreas Gohr <andi@splitbrain.org> */ - public function _headerToLink($title, $create = false) { - if($create) { + public function _headerToLink($title, $create = false) + { + if ($create) { return sectionID($title, $this->headers); } else { $check = false; @@ -772,19 +882,20 @@ abstract class Doku_Renderer extends Plugin { * Removes any Namespace from the given name but keeps * casing and special chars * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $name * @return string + * @author Andreas Gohr <andi@splitbrain.org> + * */ - public function _simpleTitle($name) { + public function _simpleTitle($name) + { global $conf; //if there is a hash we use the ancor name only - list($name, $hash) = sexplode('#', $name, 2); - if($hash) return $hash; + [$name, $hash] = sexplode('#', $name, 2); + if ($hash) return $hash; - if($conf['useslash']) { + if ($conf['useslash']) { $name = strtr($name, ';/', ';:'); } else { $name = strtr($name, ';', ':'); @@ -796,69 +907,75 @@ abstract class Doku_Renderer extends Plugin { /** * Resolve an interwikilink * - * @param string $shortcut identifier for the interwiki link - * @param string $reference fragment that refers the content - * @param null|bool $exists reference which returns if an internal page exists + * @param string $shortcut identifier for the interwiki link + * @param string $reference fragment that refers the content + * @param null|bool $exists reference which returns if an internal page exists * @return string interwikilink */ - public function _resolveInterWiki(&$shortcut, $reference, &$exists = null) { + public function _resolveInterWiki(&$shortcut, $reference, &$exists = null) + { //get interwiki URL - if(isset($this->interwiki[$shortcut])) { + if (isset($this->interwiki[$shortcut])) { $url = $this->interwiki[$shortcut]; - }elseif(isset($this->interwiki['default'])) { + } elseif (isset($this->interwiki['default'])) { $shortcut = 'default'; $url = $this->interwiki[$shortcut]; - }else{ + } else { // not parsable interwiki outputs '' to make sure string manipluation works $shortcut = ''; - $url = ''; + $url = ''; } //split into hash and url part $hash = strrchr($reference, '#'); - if($hash) { + if ($hash) { $reference = substr($reference, 0, -strlen($hash)); $hash = substr($hash, 1); } //replace placeholder - if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) { + if (preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) { //use placeholders - $url = str_replace('{URL}', rawurlencode($reference), $url); + $url = str_replace('{URL}', rawurlencode($reference), $url); //wiki names will be cleaned next, otherwise urlencode unsafe chars - $url = str_replace('{NAME}', ($url[0] === ':') ? $reference : - preg_replace_callback('/[[\\\\\]^`{|}#%]/', function($match) { - return rawurlencode($match[0]); - }, $reference), $url); + $url = str_replace( + '{NAME}', + ($url[0] === ':') ? $reference : preg_replace_callback( + '/[[\\\\\]^`{|}#%]/', + static fn($match) => rawurlencode($match[0]), + $reference + ), + $url + ); $parsed = parse_url($reference); if (empty($parsed['scheme'])) $parsed['scheme'] = ''; if (empty($parsed['host'])) $parsed['host'] = ''; if (empty($parsed['port'])) $parsed['port'] = 80; if (empty($parsed['path'])) $parsed['path'] = ''; if (empty($parsed['query'])) $parsed['query'] = ''; - $url = strtr($url,[ + $url = strtr($url, [ '{SCHEME}' => $parsed['scheme'], '{HOST}' => $parsed['host'], '{PORT}' => $parsed['port'], '{PATH}' => $parsed['path'], - '{QUERY}' => $parsed['query'] , + '{QUERY}' => $parsed['query'], ]); - } else if($url != '') { + } elseif ($url != '') { // make sure when no url is defined, we keep it null // default - $url = $url.rawurlencode($reference); + $url .= rawurlencode($reference); } //handle as wiki links - if($url && $url[0] === ':') { + if ($url && $url[0] === ':') { $urlparam = ''; $id = $url; if (strpos($url, '?') !== false) { - list($id, $urlparam) = sexplode('?', $url, 2, ''); + [$id, $urlparam] = sexplode('?', $url, 2, ''); } - $url = wl(cleanID($id), $urlparam); + $url = wl(cleanID($id), $urlparam); $exists = page_exists($id); } - if($hash) $url .= '#'.rawurlencode($hash); + if ($hash) $url .= '#' . rawurlencode($hash); return $url; } diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index ba7ec51a9..fb8c658e4 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -3,6 +3,8 @@ use dokuwiki\ChangeLog\MediaChangeLog; use dokuwiki\File\MediaResolver; use dokuwiki\File\PageResolver; +use dokuwiki\Utf8\PhpString; +use SimplePie\Author; /** * Renderer for XHTML output @@ -13,41 +15,42 @@ use dokuwiki\File\PageResolver; * @author Andreas Gohr <andi@splitbrain.org> * */ -class Doku_Renderer_xhtml extends Doku_Renderer { +class Doku_Renderer_xhtml extends Doku_Renderer +{ /** @var array store the table of contents */ - public $toc = array(); + public $toc = []; /** @var array A stack of section edit data */ - protected $sectionedits = array(); + protected $sectionedits = []; /** @var int last section edit id, used by startSectionEdit */ protected $lastsecid = 0; /** @var array a list of footnotes, list starts at 1! */ - protected $footnotes = array(); + protected $footnotes = []; /** @var int current section level */ protected $lastlevel = 0; /** @var array section node tracker */ - protected $node = array(0, 0, 0, 0, 0); + protected $node = [0, 0, 0, 0, 0]; /** @var string temporary $doc store */ protected $store = ''; /** @var array global counter, for table classes etc. */ - protected $_counter = array(); // + protected $_counter = []; // /** @var int counts the code and file blocks, used to provide download links */ protected $_codeblock = 0; /** @var array list of allowed URL schemes */ - protected $schemes = null; + protected $schemes; /** * Register a new edit section range * - * @param int $start The byte position for the edit start - * @param array $data Associative array with section data: + * @param int $start The byte position for the edit start + * @param array $data Associative array with section data: * Key 'name': the section name/title * Key 'target': the target for the section edit, * e.g. 'section' or 'table' @@ -62,49 +65,52 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @author Adrian Lang <lang@cosmocode.de> */ - public function startSectionEdit($start, $data) { + public function startSectionEdit($start, $data) + { if (!is_array($data)) { msg( sprintf( 'startSectionEdit: $data "%s" is NOT an array! One of your plugins needs an update.', - hsc((string) $data) - ), -1 + hsc((string)$data) + ), + -1 ); // @deprecated 2018-04-14, backward compatibility $args = func_get_args(); - $data = array(); - if(isset($args[1])) $data['target'] = $args[1]; - if(isset($args[2])) $data['name'] = $args[2]; - if(isset($args[3])) $data['hid'] = $args[3]; + $data = []; + if (isset($args[1])) $data['target'] = $args[1]; + if (isset($args[2])) $data['name'] = $args[2]; + if (isset($args[3])) $data['hid'] = $args[3]; } $data['secid'] = ++$this->lastsecid; $data['start'] = $start; $this->sectionedits[] = $data; - return 'sectionedit'.$data['secid']; + return 'sectionedit' . $data['secid']; } /** * Finish an edit section range * - * @param int $end The byte position for the edit end; null for the rest of the page + * @param int $end The byte position for the edit end; null for the rest of the page * * @author Adrian Lang <lang@cosmocode.de> */ - public function finishSectionEdit($end = null, $hid = null) { - if(count($this->sectionedits) == 0) { + public function finishSectionEdit($end = null, $hid = null) + { + if (count($this->sectionedits) == 0) { return; } $data = array_pop($this->sectionedits); - if(!is_null($end) && $end <= $data['start']) { + if (!is_null($end) && $end <= $data['start']) { return; } - if(!is_null($hid)) { + if (!is_null($hid)) { $data['hid'] .= $hid; } - $data['range'] = $data['start'].'-'.(is_null($end) ? '' : $end); + $data['range'] = $data['start'] . '-' . (is_null($end) ? '' : $end); unset($data['start']); - $this->doc .= '<!-- EDIT'.hsc(json_encode ($data)).' -->'; + $this->doc .= '<!-- EDIT' . hsc(json_encode($data, JSON_THROW_ON_ERROR)) . ' -->'; } /** @@ -112,25 +118,28 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @return string always 'xhtml' */ - public function getFormat() { + public function getFormat() + { return 'xhtml'; } /** * Initialize the document */ - public function document_start() { + public function document_start() + { //reset some internals - $this->toc = array(); + $this->toc = []; } /** * Finalize the document */ - public function document_end() { + public function document_end() + { // Finish open section edits. - while(count($this->sectionedits) > 0) { - if($this->sectionedits[count($this->sectionedits) - 1]['start'] <= 1) { + while ($this->sectionedits !== []) { + if ($this->sectionedits[count($this->sectionedits) - 1]['start'] <= 1) { // If there is only one section, do not write a section edit // marker. array_pop($this->sectionedits); @@ -139,40 +148,37 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } } - if(count($this->footnotes) > 0) { - $this->doc .= '<div class="footnotes">'.DOKU_LF; + if ($this->footnotes !== []) { + $this->doc .= '<div class="footnotes">' . DOKU_LF; - foreach($this->footnotes as $id => $footnote) { + foreach ($this->footnotes as $id => $footnote) { // check its not a placeholder that indicates actual footnote text is elsewhere - if(substr($footnote, 0, 5) != "@@FNT") { - + if (substr($footnote, 0, 5) != "@@FNT") { // open the footnote and set the anchor and backlink $this->doc .= '<div class="fn">'; - $this->doc .= '<sup><a href="#fnt__'.$id.'" id="fn__'.$id.'" class="fn_bot">'; - $this->doc .= $id.')</a></sup> '.DOKU_LF; + $this->doc .= '<sup><a href="#fnt__' . $id . '" id="fn__' . $id . '" class="fn_bot">'; + $this->doc .= $id . ')</a></sup> ' . DOKU_LF; // get any other footnotes that use the same markup $alt = array_keys($this->footnotes, "@@FNT$id"); - if(count($alt)) { - foreach($alt as $ref) { - // set anchor and backlink for the other footnotes - $this->doc .= ', <sup><a href="#fnt__'.($ref).'" id="fn__'.($ref).'" class="fn_bot">'; - $this->doc .= ($ref).')</a></sup> '.DOKU_LF; - } + foreach ($alt as $ref) { + // set anchor and backlink for the other footnotes + $this->doc .= ', <sup><a href="#fnt__' . ($ref) . '" id="fn__' . ($ref) . '" class="fn_bot">'; + $this->doc .= ($ref) . ')</a></sup> ' . DOKU_LF; } // add footnote markup and close this footnote - $this->doc .= '<div class="content">'.$footnote.'</div>'; - $this->doc .= '</div>'.DOKU_LF; + $this->doc .= '<div class="content">' . $footnote . '</div>'; + $this->doc .= '</div>' . DOKU_LF; } } - $this->doc .= '</div>'.DOKU_LF; + $this->doc .= '</div>' . DOKU_LF; } // Prepare the TOC global $conf; - if( + if ( $this->info['toc'] && is_array($this->toc) && $conf['tocminheads'] && count($this->toc) >= $conf['tocminheads'] @@ -188,15 +194,16 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Add an item to the TOC * - * @param string $id the hash link - * @param string $text the text to display - * @param int $level the nesting level + * @param string $id the hash link + * @param string $text the text to display + * @param int $level the nesting level */ - public function toc_additem($id, $text, $level) { + public function toc_additem($id, $text, $level) + { global $conf; //handle TOC - if($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']) { + if ($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']) { $this->toc[] = html_mktocitem($id, $text, $level - $conf['toptoclevel'] + 1); } } @@ -204,16 +211,17 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render a heading * - * @param string $text the text to display - * @param int $level header level - * @param int $pos byte position in the original source - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $text the text to display + * @param int $level header level + * @param int $pos byte position in the original source + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly */ - public function header($text, $level, $pos, $returnonly = false) { + public function header($text, $level, $pos, $returnonly = false) + { global $conf; - if(blank($text)) return; //skip empty headlines + if (blank($text)) return; //skip empty headlines $hid = $this->_headerToLink($text, true); @@ -222,33 +230,34 @@ class Doku_Renderer_xhtml extends Doku_Renderer { // adjust $node to reflect hierarchy of levels $this->node[$level - 1]++; - if($level < $this->lastlevel) { - for($i = 0; $i < $this->lastlevel - $level; $i++) { + if ($level < $this->lastlevel) { + for ($i = 0; $i < $this->lastlevel - $level; $i++) { $this->node[$this->lastlevel - $i - 1] = 0; } } $this->lastlevel = $level; - if($level <= $conf['maxseclevel'] && - count($this->sectionedits) > 0 && + if ( + $level <= $conf['maxseclevel'] && + $this->sectionedits !== [] && $this->sectionedits[count($this->sectionedits) - 1]['target'] === 'section' ) { $this->finishSectionEdit($pos - 1); } // build the header - $header = DOKU_LF.'<h'.$level; - if($level <= $conf['maxseclevel']) { - $data = array(); + $header = DOKU_LF . '<h' . $level; + if ($level <= $conf['maxseclevel']) { + $data = []; $data['target'] = 'section'; $data['name'] = $text; $data['hid'] = $hid; $data['codeblockOffset'] = $this->_codeblock; - $header .= ' class="'.$this->startSectionEdit($pos, $data).'"'; + $header .= ' class="' . $this->startSectionEdit($pos, $data) . '"'; } - $header .= ' id="'.$hid.'">'; + $header .= ' id="' . $hid . '">'; $header .= $this->_xmlEntities($text); - $header .= "</h$level>".DOKU_LF; + $header .= "</h$level>" . DOKU_LF; if ($returnonly) { return $header; @@ -262,15 +271,17 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param int $level section level (as determined by the previous header) */ - public function section_open($level) { - $this->doc .= '<div class="level'.$level.'">'.DOKU_LF; + public function section_open($level) + { + $this->doc .= '<div class="level' . $level . '">' . DOKU_LF; } /** * Close the current section */ - public function section_close() { - $this->doc .= DOKU_LF.'</div>'.DOKU_LF; + public function section_close() + { + $this->doc .= DOKU_LF . '</div>' . DOKU_LF; } /** @@ -278,133 +289,152 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param $text */ - public function cdata($text) { + public function cdata($text) + { $this->doc .= $this->_xmlEntities($text); } /** * Open a paragraph */ - public function p_open() { - $this->doc .= DOKU_LF.'<p>'.DOKU_LF; + public function p_open() + { + $this->doc .= DOKU_LF . '<p>' . DOKU_LF; } /** * Close a paragraph */ - public function p_close() { - $this->doc .= DOKU_LF.'</p>'.DOKU_LF; + public function p_close() + { + $this->doc .= DOKU_LF . '</p>' . DOKU_LF; } /** * Create a line break */ - public function linebreak() { - $this->doc .= '<br/>'.DOKU_LF; + public function linebreak() + { + $this->doc .= '<br/>' . DOKU_LF; } /** * Create a horizontal line */ - public function hr() { - $this->doc .= '<hr />'.DOKU_LF; + public function hr() + { + $this->doc .= '<hr />' . DOKU_LF; } /** * Start strong (bold) formatting */ - public function strong_open() { + public function strong_open() + { $this->doc .= '<strong>'; } /** * Stop strong (bold) formatting */ - public function strong_close() { + public function strong_close() + { $this->doc .= '</strong>'; } /** * Start emphasis (italics) formatting */ - public function emphasis_open() { + public function emphasis_open() + { $this->doc .= '<em>'; } /** * Stop emphasis (italics) formatting */ - public function emphasis_close() { + public function emphasis_close() + { $this->doc .= '</em>'; } /** * Start underline formatting */ - public function underline_open() { + public function underline_open() + { $this->doc .= '<em class="u">'; } /** * Stop underline formatting */ - public function underline_close() { + public function underline_close() + { $this->doc .= '</em>'; } /** * Start monospace formatting */ - public function monospace_open() { + public function monospace_open() + { $this->doc .= '<code>'; } /** * Stop monospace formatting */ - public function monospace_close() { + public function monospace_close() + { $this->doc .= '</code>'; } /** * Start a subscript */ - public function subscript_open() { + public function subscript_open() + { $this->doc .= '<sub>'; } /** * Stop a subscript */ - public function subscript_close() { + public function subscript_close() + { $this->doc .= '</sub>'; } /** * Start a superscript */ - public function superscript_open() { + public function superscript_open() + { $this->doc .= '<sup>'; } /** * Stop a superscript */ - public function superscript_close() { + public function superscript_close() + { $this->doc .= '</sup>'; } /** * Start deleted (strike-through) formatting */ - public function deleted_open() { + public function deleted_open() + { $this->doc .= '<del>'; } /** * Stop deleted (strike-through) formatting */ - public function deleted_close() { + public function deleted_close() + { $this->doc .= '</del>'; } @@ -417,11 +447,12 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @author Andreas Gohr <andi@splitbrain.org> */ - public function footnote_open() { + public function footnote_open() + { // move current content to store and record footnote $this->store = $this->doc; - $this->doc = ''; + $this->doc = ''; } /** @@ -432,30 +463,36 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @author Andreas Gohr */ - public function footnote_close() { + public function footnote_close() + { /** @var $fnid int takes track of seen footnotes, assures they are unique even across multiple docs FS#2841 */ static $fnid = 0; // assign new footnote id (we start at 1) $fnid++; // recover footnote into the stack and restore old content - $footnote = $this->doc; - $this->doc = $this->store; + $footnote = $this->doc; + $this->doc = $this->store; $this->store = ''; // check to see if this footnote has been seen before $i = array_search($footnote, $this->footnotes); - if($i === false) { + if ($i === false) { // its a new footnote, add it to the $footnotes array $this->footnotes[$fnid] = $footnote; } else { // seen this one before, save a placeholder - $this->footnotes[$fnid] = "@@FNT".($i); + $this->footnotes[$fnid] = "@@FNT" . ($i); } // output the footnote reference and link - $this->doc .= '<sup><a href="#fn__'.$fnid.'" id="fnt__'.$fnid.'" class="fn_top">'.$fnid.')</a></sup>'; + $this->doc .= sprintf( + '<sup><a href="#fn__%d" id="fnt__%d" class="fn_top">%d)</a></sup>', + $fnid, + $fnid, + $fnid + ); } /** @@ -463,20 +500,22 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input */ - public function listu_open($classes = null) { + public function listu_open($classes = null) + { $class = ''; - if($classes !== null) { - if(is_array($classes)) $classes = join(' ', $classes); + if ($classes !== null) { + if (is_array($classes)) $classes = implode(' ', $classes); $class = " class=\"$classes\""; } - $this->doc .= "<ul$class>".DOKU_LF; + $this->doc .= "<ul$class>" . DOKU_LF; } /** * Close an unordered list */ - public function listu_close() { - $this->doc .= '</ul>'.DOKU_LF; + public function listu_close() + { + $this->doc .= '</ul>' . DOKU_LF; } /** @@ -484,20 +523,22 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input */ - public function listo_open($classes = null) { + public function listo_open($classes = null) + { $class = ''; - if($classes !== null) { - if(is_array($classes)) $classes = join(' ', $classes); + if ($classes !== null) { + if (is_array($classes)) $classes = implode(' ', $classes); $class = " class=\"$classes\""; } - $this->doc .= "<ol$class>".DOKU_LF; + $this->doc .= "<ol$class>" . DOKU_LF; } /** * Close an ordered list */ - public function listo_close() { - $this->doc .= '</ol>'.DOKU_LF; + public function listo_close() + { + $this->doc .= '</ol>' . DOKU_LF; } /** @@ -506,30 +547,34 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * @param int $level the nesting level * @param bool $node true when a node; false when a leaf */ - public function listitem_open($level, $node=false) { + public function listitem_open($level, $node = false) + { $branching = $node ? ' node' : ''; - $this->doc .= '<li class="level'.$level.$branching.'">'; + $this->doc .= '<li class="level' . $level . $branching . '">'; } /** * Close a list item */ - public function listitem_close() { - $this->doc .= '</li>'.DOKU_LF; + public function listitem_close() + { + $this->doc .= '</li>' . DOKU_LF; } /** * Start the content of a list item */ - public function listcontent_open() { + public function listcontent_open() + { $this->doc .= '<div class="li">'; } /** * Stop the content of a list item */ - public function listcontent_close() { - $this->doc .= '</div>'.DOKU_LF; + public function listcontent_close() + { + $this->doc .= '</div>' . DOKU_LF; } /** @@ -539,22 +584,25 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string $text */ - public function unformatted($text) { + public function unformatted($text) + { $this->doc .= $this->_xmlEntities($text); } /** * Start a block quote */ - public function quote_open() { - $this->doc .= '<blockquote><div class="no">'.DOKU_LF; + public function quote_open() + { + $this->doc .= '<blockquote><div class="no">' . DOKU_LF; } /** * Stop a block quote */ - public function quote_close() { - $this->doc .= '</div></blockquote>'.DOKU_LF; + public function quote_close() + { + $this->doc .= '</div></blockquote>' . DOKU_LF; } /** @@ -562,92 +610,96 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string $text */ - public function preformatted($text) { - $this->doc .= '<pre class="code">'.trim($this->_xmlEntities($text), "\n\r").'</pre>'.DOKU_LF; + public function preformatted($text) + { + $this->doc .= '<pre class="code">' . trim($this->_xmlEntities($text), "\n\r") . '</pre>' . DOKU_LF; } /** * Display text as file content, optionally syntax highlighted * - * @param string $text text to show + * @param string $text text to show * @param string $language programming language to use for syntax highlighting * @param string $filename file path label - * @param array $options assoziative array with additional geshi options + * @param array $options assoziative array with additional geshi options */ - public function file($text, $language = null, $filename = null, $options=null) { + public function file($text, $language = null, $filename = null, $options = null) + { $this->_highlight('file', $text, $language, $filename, $options); } /** * Display text as code content, optionally syntax highlighted * - * @param string $text text to show + * @param string $text text to show * @param string $language programming language to use for syntax highlighting * @param string $filename file path label - * @param array $options assoziative array with additional geshi options + * @param array $options assoziative array with additional geshi options */ - public function code($text, $language = null, $filename = null, $options=null) { + public function code($text, $language = null, $filename = null, $options = null) + { $this->_highlight('code', $text, $language, $filename, $options); } /** * Use GeSHi to highlight language syntax in code and file blocks * - * @author Andreas Gohr <andi@splitbrain.org> - * @param string $type code|file - * @param string $text text to show + * @param string $type code|file + * @param string $text text to show * @param string $language programming language to use for syntax highlighting * @param string $filename file path label - * @param array $options assoziative array with additional geshi options + * @param array $options assoziative array with additional geshi options + * @author Andreas Gohr <andi@splitbrain.org> */ - public function _highlight($type, $text, $language = null, $filename = null, $options = null) { + public function _highlight($type, $text, $language = null, $filename = null, $options = null) + { global $ID; global $lang; global $INPUT; $language = preg_replace(PREG_PATTERN_VALID_LANGUAGE, '', $language ?? ''); - if($filename) { + if ($filename) { // add icon - list($ext) = mimetype($filename, false); + [$ext] = mimetype($filename, false); $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); - $class = 'mediafile mf_'.$class; + $class = 'mediafile mf_' . $class; $offset = 0; if ($INPUT->has('codeblockOffset')) { $offset = $INPUT->str('codeblockOffset'); } - $this->doc .= '<dl class="'.$type.'">'.DOKU_LF; + $this->doc .= '<dl class="' . $type . '">' . DOKU_LF; $this->doc .= '<dt><a href="' . exportlink( $ID, 'code', - array('codeblock' => $offset + $this->_codeblock) + ['codeblock' => $offset + $this->_codeblock] ) . '" title="' . $lang['download'] . '" class="' . $class . '">'; $this->doc .= hsc($filename); - $this->doc .= '</a></dt>'.DOKU_LF.'<dd>'; + $this->doc .= '</a></dt>' . DOKU_LF . '<dd>'; } - if($text[0] == "\n") { + if ($text[0] == "\n") { $text = substr($text, 1); } - if(substr($text, -1) == "\n") { + if (substr($text, -1) == "\n") { $text = substr($text, 0, -1); } - if(empty($language)) { // empty is faster than is_null and can prevent '' string - $this->doc .= '<pre class="'.$type.'">'.$this->_xmlEntities($text).'</pre>'.DOKU_LF; + if (empty($language)) { // empty is faster than is_null and can prevent '' string + $this->doc .= '<pre class="' . $type . '">' . $this->_xmlEntities($text) . '</pre>' . DOKU_LF; } else { $class = 'code'; //we always need the code class to make the syntax highlighting apply - if($type != 'code') $class .= ' '.$type; + if ($type != 'code') $class .= ' ' . $type; $this->doc .= "<pre class=\"$class $language\">" . p_xhtml_cached_geshi($text, $language, '', $options) . '</pre>' . DOKU_LF; } - if($filename) { - $this->doc .= '</dd></dl>'.DOKU_LF; + if ($filename) { + $this->doc .= '</dd></dl>' . DOKU_LF; } $this->_codeblock++; @@ -660,15 +712,14 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string $acronym */ - public function acronym($acronym) { - - if(array_key_exists($acronym, $this->acronyms)) { + public function acronym($acronym) + { + if (array_key_exists($acronym, $this->acronyms)) { $title = $this->_xmlEntities($this->acronyms[$acronym]); - $this->doc .= '<abbr title="'.$title - .'">'.$this->_xmlEntities($acronym).'</abbr>'; - + $this->doc .= '<abbr title="' . $title + . '">' . $this->_xmlEntities($acronym) . '</abbr>'; } else { $this->doc .= $this->_xmlEntities($acronym); } @@ -681,7 +732,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string $smiley */ - public function smiley($smiley) { + public function smiley($smiley) + { if (isset($this->smileys[$smiley])) { $this->doc .= '<img src="' . DOKU_BASE . 'lib/images/smileys/' . $this->smileys[$smiley] . '" class="icon smiley" alt="' . $this->_xmlEntities($smiley) . '" />'; @@ -699,8 +751,9 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string $entity */ - public function entity($entity) { - if(array_key_exists($entity, $this->entities)) { + public function entity($entity) + { + if (array_key_exists($entity, $this->entities)) { $this->doc .= $this->entities[$entity]; } else { $this->doc .= $this->_xmlEntities($entity); @@ -715,14 +768,16 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * @param string|int $x first value * @param string|int $y second value */ - public function multiplyentity($x, $y) { + public function multiplyentity($x, $y) + { $this->doc .= "$x×$y"; } /** * Render an opening single quote char (language specific) */ - public function singlequoteopening() { + public function singlequoteopening() + { global $lang; $this->doc .= $lang['singlequoteopening']; } @@ -730,7 +785,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render a closing single quote char (language specific) */ - public function singlequoteclosing() { + public function singlequoteclosing() + { global $lang; $this->doc .= $lang['singlequoteclosing']; } @@ -738,7 +794,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render an apostrophe char (language specific) */ - public function apostrophe() { + public function apostrophe() + { global $lang; $this->doc .= $lang['apostrophe']; } @@ -746,7 +803,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render an opening double quote char (language specific) */ - public function doublequoteopening() { + public function doublequoteopening() + { global $lang; $this->doc .= $lang['doublequoteopening']; } @@ -754,7 +812,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render an closinging double quote char (language specific) */ - public function doublequoteclosing() { + public function doublequoteclosing() + { global $lang; $this->doc .= $lang['doublequoteclosing']; } @@ -762,42 +821,44 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render a CamelCase link * - * @param string $link The link name - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $link The link name + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly * * @see http://en.wikipedia.org/wiki/CamelCase */ - public function camelcaselink($link, $returnonly = false) { - if($returnonly) { - return $this->internallink($link, $link, null, true); + public function camelcaselink($link, $returnonly = false) + { + if ($returnonly) { + return $this->internallink($link, $link, null, true); } else { - $this->internallink($link, $link); + $this->internallink($link, $link); } } /** * Render a page local link * - * @param string $hash hash link identifier - * @param string $name name for the link - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $hash hash link identifier + * @param string $name name for the link + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly */ - public function locallink($hash, $name = null, $returnonly = false) { + public function locallink($hash, $name = null, $returnonly = false) + { global $ID; - $name = $this->_getLinkTitle($name, $hash, $isImage); - $hash = $this->_headerToLink($hash); - $title = $ID.' ↵'; + $name = $this->_getLinkTitle($name, $hash, $isImage); + $hash = $this->_headerToLink($hash); + $title = $ID . ' ↵'; - $doc = '<a href="#'.$hash.'" title="'.$title.'" class="wikilink1">'; + $doc = '<a href="#' . $hash . '" title="' . $title . '" class="wikilink1">'; $doc .= $name; $doc .= '</a>'; - if($returnonly) { - return $doc; + if ($returnonly) { + return $doc; } else { - $this->doc .= $doc; + $this->doc .= $doc; } } @@ -807,23 +868,24 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * $search,$returnonly & $linktype are not for the renderer but are used * elsewhere - no need to implement them in other renderers * - * @author Andreas Gohr <andi@splitbrain.org> - * @param string $id pageid - * @param string|null $name link name - * @param string|null $search adds search url param - * @param bool $returnonly whether to return html or write to doc attribute - * @param string $linktype type to set use of headings + * @param string $id pageid + * @param string|null $name link name + * @param string|null $search adds search url param + * @param bool $returnonly whether to return html or write to doc attribute + * @param string $linktype type to set use of headings * @return void|string writes to doc attribute or returns html depends on $returnonly + * @author Andreas Gohr <andi@splitbrain.org> */ - public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') { + public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') + { global $conf; global $ID; global $INFO; $params = ''; - $parts = explode('?', $id, 2); - if(count($parts) === 2) { - $id = $parts[0]; + $parts = explode('?', $id, 2); + if (count($parts) === 2) { + $id = $parts[0]; $params = $parts[1]; } @@ -831,7 +893,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { // We need this check because _simpleTitle needs // correct $id and resolve_pageid() use cleanID($id) // (some things could be lost) - if($id === '') { + if ($id === '') { $id = $ID; } @@ -842,13 +904,13 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $id = (new PageResolver($ID))->resolveId($id, $this->date_at, true); $exists = page_exists($id, $this->date_at, false, true); - $link = array(); + $link = []; $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype); - if(!$isImage) { - if($exists) { + if (!$isImage) { + if ($exists) { $class = 'wikilink1'; } else { - $class = 'wikilink2'; + $class = 'wikilink2'; $link['rel'] = 'nofollow'; } } else { @@ -856,38 +918,38 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } //keep hash anchor - list($id, $hash) = sexplode('#', $id, 2); - if(!empty($hash)) $hash = $this->_headerToLink($hash); + [$id, $hash] = sexplode('#', $id, 2); + if (!empty($hash)) $hash = $this->_headerToLink($hash); //prepare for formating $link['target'] = $conf['target']['wiki']; - $link['style'] = ''; - $link['pre'] = ''; - $link['suf'] = ''; - $link['more'] = 'data-wiki-id="'.$id.'"'; // id is already cleaned - $link['class'] = $class; - if($this->date_at) { - $params = $params.'&at='.rawurlencode($this->date_at); - } - $link['url'] = wl($id, $params); - $link['name'] = $name; - $link['title'] = $id; + $link['style'] = ''; + $link['pre'] = ''; + $link['suf'] = ''; + $link['more'] = 'data-wiki-id="' . $id . '"'; // id is already cleaned + $link['class'] = $class; + if ($this->date_at) { + $params = $params . '&at=' . rawurlencode($this->date_at); + } + $link['url'] = wl($id, $params); + $link['name'] = $name; + $link['title'] = $id; //add search string - if($search) { + if ($search) { ($conf['userewrite']) ? $link['url'] .= '?' : $link['url'] .= '&'; - if(is_array($search)) { + if (is_array($search)) { $search = array_map('rawurlencode', $search); - $link['url'] .= 's[]='.join('&s[]=', $search); + $link['url'] .= 's[]=' . implode('&s[]=', $search); } else { - $link['url'] .= 's='.rawurlencode($search); + $link['url'] .= 's=' . rawurlencode($search); } } //keep hash - if($hash) $link['url'] .= '#'.$hash; + if ($hash) $link['url'] .= '#' . $hash; //output formatted - if($returnonly) { + if ($returnonly) { return $this->_formatLink($link); } else { $this->doc .= $this->_formatLink($link); @@ -897,25 +959,26 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render an external link * - * @param string $url full URL with scheme - * @param string|array $name name for the link, array for media file - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $url full URL with scheme + * @param string|array $name name for the link, array for media file + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly */ - public function externallink($url, $name = null, $returnonly = false) { + public function externallink($url, $name = null, $returnonly = false) + { global $conf; $name = $this->_getLinkTitle($name, $url, $isImage); // url might be an attack vector, only allow registered protocols - if(is_null($this->schemes)) $this->schemes = getSchemes(); - list($scheme) = explode('://', $url); + if (is_null($this->schemes)) $this->schemes = getSchemes(); + [$scheme] = explode('://', $url); $scheme = strtolower($scheme); - if(!in_array($scheme, $this->schemes)) $url = ''; + if (!in_array($scheme, $this->schemes)) $url = ''; // is there still an URL? - if(!$url) { - if($returnonly) { + if (!$url) { + if ($returnonly) { return $name; } else { $this->doc .= $name; @@ -924,30 +987,30 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } // set class - if(!$isImage) { + if (!$isImage) { $class = 'urlextern'; } else { $class = 'media'; } //prepare for formating - $link = array(); + $link = []; $link['target'] = $conf['target']['extern']; - $link['style'] = ''; - $link['pre'] = ''; - $link['suf'] = ''; - $link['more'] = ''; - $link['class'] = $class; - $link['url'] = $url; - $link['rel'] = ''; - - $link['name'] = $name; + $link['style'] = ''; + $link['pre'] = ''; + $link['suf'] = ''; + $link['more'] = ''; + $link['class'] = $class; + $link['url'] = $url; + $link['rel'] = ''; + + $link['name'] = $name; $link['title'] = $this->_xmlEntities($url); - if($conf['relnofollow']) $link['rel'] .= ' ugc nofollow'; - if($conf['target']['extern']) $link['rel'] .= ' noopener'; + if ($conf['relnofollow']) $link['rel'] .= ' ugc nofollow'; + if ($conf['target']['extern']) $link['rel'] .= ' noopener'; //output formatted - if($returnonly) { + if ($returnonly) { return $this->_formatLink($link); } else { $this->doc .= $this->_formatLink($link); @@ -959,94 +1022,95 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * You may want to use $this->_resolveInterWiki() here * - * @param string $match original link - probably not much use - * @param string|array $name name for the link, array for media file - * @param string $wikiName indentifier (shortcut) for the remote wiki - * @param string $wikiUri the fragment parsed from the original link - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $match original link - probably not much use + * @param string|array $name name for the link, array for media file + * @param string $wikiName indentifier (shortcut) for the remote wiki + * @param string $wikiUri the fragment parsed from the original link + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly */ - public function interwikilink($match, $name, $wikiName, $wikiUri, $returnonly = false) { + public function interwikilink($match, $name, $wikiName, $wikiUri, $returnonly = false) + { global $conf; - $link = array(); + $link = []; $link['target'] = $conf['target']['interwiki']; - $link['pre'] = ''; - $link['suf'] = ''; - $link['more'] = ''; - $link['name'] = $this->_getLinkTitle($name, $wikiUri, $isImage); - $link['rel'] = ''; + $link['pre'] = ''; + $link['suf'] = ''; + $link['more'] = ''; + $link['name'] = $this->_getLinkTitle($name, $wikiUri, $isImage); + $link['rel'] = ''; //get interwiki URL $exists = null; - $url = $this->_resolveInterWiki($wikiName, $wikiUri, $exists); + $url = $this->_resolveInterWiki($wikiName, $wikiUri, $exists); - if(!$isImage) { - $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $wikiName); + if (!$isImage) { + $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $wikiName); $link['class'] = "interwiki iw_$class"; } else { $link['class'] = 'media'; } //do we stay at the same server? Use local target - if(strpos($url, DOKU_URL) === 0 OR strpos($url, DOKU_BASE) === 0) { + if (strpos($url, DOKU_URL) === 0 || strpos($url, DOKU_BASE) === 0) { $link['target'] = $conf['target']['wiki']; } - if($exists !== null && !$isImage) { - if($exists) { + if ($exists !== null && !$isImage) { + if ($exists) { $link['class'] .= ' wikilink1'; } else { $link['class'] .= ' wikilink2'; $link['rel'] .= ' nofollow'; } } - if($conf['target']['interwiki']) $link['rel'] .= ' noopener'; + if ($conf['target']['interwiki']) $link['rel'] .= ' noopener'; - $link['url'] = $url; + $link['url'] = $url; $link['title'] = $this->_xmlEntities($link['url']); // output formatted - if($returnonly) { - if($url == '') return $link['name']; + if ($returnonly) { + if ($url == '') return $link['name']; return $this->_formatLink($link); - } else { - if($url == '') $this->doc .= $link['name']; - else $this->doc .= $this->_formatLink($link); - } + } elseif ($url == '') { + $this->doc .= $link['name']; + } else $this->doc .= $this->_formatLink($link); } /** * Link to windows share * - * @param string $url the link - * @param string|array $name name for the link, array for media file - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $url the link + * @param string|array $name name for the link, array for media file + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly */ - public function windowssharelink($url, $name = null, $returnonly = false) { + public function windowssharelink($url, $name = null, $returnonly = false) + { global $conf; //simple setup - $link = array(); + $link = []; $link['target'] = $conf['target']['windows']; - $link['pre'] = ''; - $link['suf'] = ''; - $link['style'] = ''; + $link['pre'] = ''; + $link['suf'] = ''; + $link['style'] = ''; $link['name'] = $this->_getLinkTitle($name, $url, $isImage); - if(!$isImage) { + if (!$isImage) { $link['class'] = 'windows'; } else { $link['class'] = 'media'; } $link['title'] = $this->_xmlEntities($url); - $url = str_replace('\\', '/', $url); - $url = 'file:///'.$url; - $link['url'] = $url; + $url = str_replace('\\', '/', $url); + $url = 'file:///' . $url; + $link['url'] = $url; //output formatted - if($returnonly) { + if ($returnonly) { return $this->_formatLink($link); } else { $this->doc .= $this->_formatLink($link); @@ -1058,23 +1122,24 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * Honors $conf['mailguard'] setting * - * @param string $address Email-Address - * @param string|array $name name for the link, array for media file - * @param bool $returnonly whether to return html or write to doc attribute + * @param string $address Email-Address + * @param string|array $name name for the link, array for media file + * @param bool $returnonly whether to return html or write to doc attribute * @return void|string writes to doc attribute or returns html depends on $returnonly */ - public function emaillink($address, $name = null, $returnonly = false) { + public function emaillink($address, $name = null, $returnonly = false) + { global $conf; //simple setup - $link = array(); + $link = []; $link['target'] = ''; - $link['pre'] = ''; - $link['suf'] = ''; - $link['style'] = ''; - $link['more'] = ''; + $link['pre'] = ''; + $link['suf'] = ''; + $link['style'] = ''; + $link['more'] = ''; $name = $this->_getLinkTitle($name, '', $isImage); - if(!$isImage) { + if (!$isImage) { $link['class'] = 'mail'; } else { $link['class'] = 'media'; @@ -1082,20 +1147,21 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $address = $this->_xmlEntities($address); $address = obfuscate($address); - $title = $address; - if(empty($name)) { + $title = $address; + + if (empty($name)) { $name = $address; } - if($conf['mailguard'] == 'visible') $address = rawurlencode($address); + if ($conf['mailguard'] == 'visible') $address = rawurlencode($address); - $link['url'] = 'mailto:'.$address; - $link['name'] = $name; + $link['url'] = 'mailto:' . $address; + $link['name'] = $name; $link['title'] = $title; //output formatted - if($returnonly) { + if ($returnonly) { return $this->_formatLink($link); } else { $this->doc .= $this->_formatLink($link); @@ -1105,179 +1171,199 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Render an internal media file * - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache - * @param string $linking linkonly|detail|nolink - * @param bool $return return HTML instead of adding to $doc + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache + * @param string $linking linkonly|detail|nolink + * @param bool $return return HTML instead of adding to $doc * @return void|string writes to doc attribute or returns html depends on $return */ - public function internalmedia($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $linking = null, $return = false) { + public function internalmedia( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $linking = null, + $return = false + ) { global $ID; if (strpos($src, '#') !== false) { - list($src, $hash) = sexplode('#', $src, 2); + [$src, $hash] = sexplode('#', $src, 2); } - $src = (new MediaResolver($ID))->resolveId($src,$this->date_at,true); + $src = (new MediaResolver($ID))->resolveId($src, $this->date_at, true); $exists = media_exists($src); $noLink = false; - $render = ($linking == 'linkonly') ? false : true; - $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render); + $render = $linking != 'linkonly'; + $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render); - list($ext, $mime) = mimetype($src, false); - if(substr($mime, 0, 5) == 'image' && $render) { + [$ext, $mime] = mimetype($src, false); + if (substr($mime, 0, 5) == 'image' && $render) { $link['url'] = ml( $src, - array( + [ 'id' => $ID, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src) - ), + ], ($linking == 'direct') ); - } elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render) { + } elseif (($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render) { // don't link movies $noLink = true; } else { // add file icons $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); - $link['class'] .= ' mediafile mf_'.$class; + $link['class'] .= ' mediafile mf_' . $class; $link['url'] = ml( $src, - array( + [ 'id' => $ID, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src) - ), + ], true ); - if($exists) $link['title'] .= ' ('.filesize_h(filesize(mediaFN($src))).')'; + if ($exists) $link['title'] .= ' (' . filesize_h(filesize(mediaFN($src))) . ')'; } - if (!empty($hash)) $link['url'] .= '#'.$hash; + if (!empty($hash)) $link['url'] .= '#' . $hash; //markup non existing files - if(!$exists) { + if (!$exists) { $link['class'] .= ' wikilink2'; } //output formatted - if($return) { - if($linking == 'nolink' || $noLink) return $link['name']; - else return $this->_formatLink($link); + if ($return) { + if ($linking == 'nolink' || $noLink) { + return $link['name']; + } else { + return $this->_formatLink($link); + } + } elseif ($linking == 'nolink' || $noLink) { + $this->doc .= $link['name']; } else { - if($linking == 'nolink' || $noLink) $this->doc .= $link['name']; - else $this->doc .= $this->_formatLink($link); + $this->doc .= $this->_formatLink($link); } } /** * Render an external media file * - * @param string $src full media URL - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache + * @param string $src full media URL + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache * @param string $linking linkonly|detail|nolink - * @param bool $return return HTML instead of adding to $doc + * @param bool $return return HTML instead of adding to $doc * @return void|string writes to doc attribute or returns html depends on $return */ - public function externalmedia($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $linking = null, $return = false) { - if(link_isinterwiki($src)){ - list($shortcut, $reference) = sexplode('>', $src, 2, ''); + public function externalmedia( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $linking = null, + $return = false + ) { + if (link_isinterwiki($src)) { + [$shortcut, $reference] = sexplode('>', $src, 2, ''); $exists = null; $src = $this->_resolveInterWiki($shortcut, $reference, $exists); - if($src == '' && empty($title)){ + if ($src == '' && empty($title)) { // make sure at least something will be shown in this case $title = $reference; } } - list($src, $hash) = sexplode('#', $src, 2); + [$src, $hash] = sexplode('#', $src, 2); $noLink = false; - if($src == '') { + if ($src == '') { // only output plaintext without link if there is no src $noLink = true; } - $render = ($linking == 'linkonly') ? false : true; - $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render); + $render = $linking != 'linkonly'; + $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render); - $link['url'] = ml($src, array('cache' => $cache)); + $link['url'] = ml($src, ['cache' => $cache]); - list($ext, $mime) = mimetype($src, false); - if(substr($mime, 0, 5) == 'image' && $render) { + [$ext, $mime] = mimetype($src, false); + if (substr($mime, 0, 5) == 'image' && $render) { // link only jpeg images // if ($ext != 'jpg' && $ext != 'jpeg') $noLink = true; - } elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render) { + } elseif (($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render) { // don't link movies $noLink = true; } else { // add file icons $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); - $link['class'] .= ' mediafile mf_'.$class; + $link['class'] .= ' mediafile mf_' . $class; } - if($hash) $link['url'] .= '#'.$hash; + if ($hash) $link['url'] .= '#' . $hash; //output formatted - if($return) { - if($linking == 'nolink' || $noLink) return $link['name']; + if ($return) { + if ($linking == 'nolink' || $noLink) return $link['name']; else return $this->_formatLink($link); - } else { - if($linking == 'nolink' || $noLink) $this->doc .= $link['name']; - else $this->doc .= $this->_formatLink($link); - } + } elseif ($linking == 'nolink' || $noLink) { + $this->doc .= $link['name']; + } else $this->doc .= $this->_formatLink($link); } /** * Renders an RSS feed * - * @param string $url URL of the feed - * @param array $params Finetuning of the output + * @param string $url URL of the feed + * @param array $params Finetuning of the output * * @author Andreas Gohr <andi@splitbrain.org> */ - public function rss($url, $params) { + public function rss($url, $params) + { global $lang; global $conf; - require_once(DOKU_INC.'inc/FeedParser.php'); + require_once(DOKU_INC . 'inc/FeedParser.php'); $feed = new FeedParser(); $feed->set_feed_url($url); //disable warning while fetching - if(!defined('DOKU_E_LEVEL')) { + if (!defined('DOKU_E_LEVEL')) { $elvl = error_reporting(E_ERROR); } $rc = $feed->init(); - if(isset($elvl)) { + if (isset($elvl)) { error_reporting($elvl); } - if($params['nosort']) $feed->enable_order_by_date(false); + if ($params['nosort']) $feed->enable_order_by_date(false); //decide on start and end - if($params['reverse']) { - $mod = -1; + if ($params['reverse']) { + $mod = -1; $start = $feed->get_item_quantity() - 1; - $end = $start - ($params['max']); - $end = ($end < -1) ? -1 : $end; + $end = $start - ($params['max']); + $end = ($end < -1) ? -1 : $end; } else { - $mod = 1; + $mod = 1; $start = 0; - $end = $feed->get_item_quantity(); - $end = ($end > $params['max']) ? $params['max'] : $end; + $end = $feed->get_item_quantity(); + $end = ($end > $params['max']) ? $params['max'] : $end; } $this->doc .= '<ul class="rss">'; - if($rc) { - for($x = $start; $x != $end; $x += $mod) { + if ($rc) { + for ($x = $start; $x != $end; $x += $mod) { $item = $feed->get_item($x); $this->doc .= '<li><div class="li">'; @@ -1285,23 +1371,23 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $title = html_entity_decode($item->get_title(), ENT_QUOTES, 'UTF-8'); // support feeds without links - if($lnkurl) { + if ($lnkurl) { $this->externallink($item->get_permalink(), $title); } else { - $this->doc .= ' '.hsc($item->get_title()); + $this->doc .= ' ' . hsc($item->get_title()); } - if($params['author']) { + if ($params['author']) { $author = $item->get_author(0); - if($author) { + if ($author instanceof Author) { $name = $author->get_name(); - if(!$name) $name = $author->get_email(); - if($name) $this->doc .= ' '.$lang['by'].' '.hsc($name); + if (!$name) $name = $author->get_email(); + if ($name) $this->doc .= ' ' . $lang['by'] . ' ' . hsc($name); } } - if($params['date']) { - $this->doc .= ' ('.$item->get_local_date($conf['dformat']).')'; + if ($params['date']) { + $this->doc .= ' (' . $item->get_local_date($conf['dformat']) . ')'; } - if($params['details']) { + if ($params['details']) { $desc = $item->get_description(); $desc = strip_tags($desc); $desc = html_entity_decode($desc, ENT_QUOTES, 'UTF-8'); @@ -1314,10 +1400,10 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } } else { $this->doc .= '<li><div class="li">'; - $this->doc .= '<em>'.$lang['rssfailed'].'</em>'; + $this->doc .= '<em>' . $lang['rssfailed'] . '</em>'; $this->externallink($url); - if($conf['allowdebug']) { - $this->doc .= '<!--'.hsc($feed->error).'-->'; + if ($conf['allowdebug']) { + $this->doc .= '<!--' . hsc($feed->error) . '-->'; } $this->doc .= '</div></li>'; } @@ -1332,23 +1418,24 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * @param int $pos byte position in the original source * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input */ - public function table_open($maxcols = null, $numrows = null, $pos = null, $classes = null) { + public function table_open($maxcols = null, $numrows = null, $pos = null, $classes = null) + { // initialize the row counter used for classes $this->_counter['row_counter'] = 0; - $class = 'table'; - if($classes !== null) { - if(is_array($classes)) $classes = join(' ', $classes); + $class = 'table'; + if ($classes !== null) { + if (is_array($classes)) $classes = implode(' ', $classes); $class .= ' ' . $classes; } - if($pos !== null) { + if ($pos !== null) { $hid = $this->_headerToLink($class, true); - $data = array(); + $data = []; $data['target'] = 'table'; $data['name'] = ''; $data['hid'] = $hid; - $class .= ' '.$this->startSectionEdit($pos, $data); + $class .= ' ' . $this->startSectionEdit($pos, $data); } - $this->doc .= '<div class="'.$class.'"><table class="inline">'. + $this->doc .= '<div class="' . $class . '"><table class="inline">' . DOKU_LF; } @@ -1357,9 +1444,10 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param int $pos byte position in the original source */ - public function table_close($pos = null) { - $this->doc .= '</table></div>'.DOKU_LF; - if($pos !== null) { + public function table_close($pos = null) + { + $this->doc .= '</table></div>' . DOKU_LF; + if ($pos !== null) { $this->finishSectionEdit($pos); } } @@ -1367,43 +1455,49 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Open a table header */ - public function tablethead_open() { - $this->doc .= DOKU_TAB.'<thead>'.DOKU_LF; + public function tablethead_open() + { + $this->doc .= DOKU_TAB . '<thead>' . DOKU_LF; } /** * Close a table header */ - public function tablethead_close() { - $this->doc .= DOKU_TAB.'</thead>'.DOKU_LF; + public function tablethead_close() + { + $this->doc .= DOKU_TAB . '</thead>' . DOKU_LF; } /** * Open a table body */ - public function tabletbody_open() { - $this->doc .= DOKU_TAB.'<tbody>'.DOKU_LF; + public function tabletbody_open() + { + $this->doc .= DOKU_TAB . '<tbody>' . DOKU_LF; } /** * Close a table body */ - public function tabletbody_close() { - $this->doc .= DOKU_TAB.'</tbody>'.DOKU_LF; + public function tabletbody_close() + { + $this->doc .= DOKU_TAB . '</tbody>' . DOKU_LF; } /** * Open a table footer */ - public function tabletfoot_open() { - $this->doc .= DOKU_TAB.'<tfoot>'.DOKU_LF; + public function tabletfoot_open() + { + $this->doc .= DOKU_TAB . '<tfoot>' . DOKU_LF; } /** * Close a table footer */ - public function tabletfoot_close() { - $this->doc .= DOKU_TAB.'</tfoot>'.DOKU_LF; + public function tabletfoot_close() + { + $this->doc .= DOKU_TAB . '</tfoot>' . DOKU_LF; } /** @@ -1411,49 +1505,52 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input */ - public function tablerow_open($classes = null) { + public function tablerow_open($classes = null) + { // initialize the cell counter used for classes $this->_counter['cell_counter'] = 0; - $class = 'row'.$this->_counter['row_counter']++; - if($classes !== null) { - if(is_array($classes)) $classes = join(' ', $classes); + $class = 'row' . $this->_counter['row_counter']++; + if ($classes !== null) { + if (is_array($classes)) $classes = implode(' ', $classes); $class .= ' ' . $classes; } - $this->doc .= DOKU_TAB.'<tr class="'.$class.'">'.DOKU_LF.DOKU_TAB.DOKU_TAB; + $this->doc .= DOKU_TAB . '<tr class="' . $class . '">' . DOKU_LF . DOKU_TAB . DOKU_TAB; } /** * Close a table row */ - public function tablerow_close() { - $this->doc .= DOKU_LF.DOKU_TAB.'</tr>'.DOKU_LF; + public function tablerow_close() + { + $this->doc .= DOKU_LF . DOKU_TAB . '</tr>' . DOKU_LF; } /** * Open a table header cell * - * @param int $colspan + * @param int $colspan * @param string $align left|center|right - * @param int $rowspan + * @param int $rowspan * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input */ - public function tableheader_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) { - $class = 'class="col'.$this->_counter['cell_counter']++; - if(!is_null($align)) { - $class .= ' '.$align.'align'; + public function tableheader_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) + { + $class = 'class="col' . $this->_counter['cell_counter']++; + if (!is_null($align)) { + $class .= ' ' . $align . 'align'; } - if($classes !== null) { - if(is_array($classes)) $classes = join(' ', $classes); + if ($classes !== null) { + if (is_array($classes)) $classes = implode(' ', $classes); $class .= ' ' . $classes; } $class .= '"'; - $this->doc .= '<th '.$class; - if($colspan > 1) { + $this->doc .= '<th ' . $class; + if ($colspan > 1) { $this->_counter['cell_counter'] += $colspan - 1; - $this->doc .= ' colspan="'.$colspan.'"'; + $this->doc .= ' colspan="' . $colspan . '"'; } - if($rowspan > 1) { - $this->doc .= ' rowspan="'.$rowspan.'"'; + if ($rowspan > 1) { + $this->doc .= ' rowspan="' . $rowspan . '"'; } $this->doc .= '>'; } @@ -1461,35 +1558,37 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Close a table header cell */ - public function tableheader_close() { + public function tableheader_close() + { $this->doc .= '</th>'; } /** * Open a table cell * - * @param int $colspan - * @param string $align left|center|right - * @param int $rowspan - * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input + * @param int $colspan + * @param string $align left|center|right + * @param int $rowspan + * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input */ - public function tablecell_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) { - $class = 'class="col'.$this->_counter['cell_counter']++; - if(!is_null($align)) { - $class .= ' '.$align.'align'; + public function tablecell_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) + { + $class = 'class="col' . $this->_counter['cell_counter']++; + if (!is_null($align)) { + $class .= ' ' . $align . 'align'; } - if($classes !== null) { - if(is_array($classes)) $classes = join(' ', $classes); + if ($classes !== null) { + if (is_array($classes)) $classes = implode(' ', $classes); $class .= ' ' . $classes; } $class .= '"'; - $this->doc .= '<td '.$class; - if($colspan > 1) { + $this->doc .= '<td ' . $class; + if ($colspan > 1) { $this->_counter['cell_counter'] += $colspan - 1; - $this->doc .= ' colspan="'.$colspan.'"'; + $this->doc .= ' colspan="' . $colspan . '"'; } - if($rowspan > 1) { - $this->doc .= ' rowspan="'.$rowspan.'"'; + if ($rowspan > 1) { + $this->doc .= ' rowspan="' . $rowspan . '"'; } $this->doc .= '>'; } @@ -1497,7 +1596,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Close a table cell */ - public function tablecell_close() { + public function tablecell_close() + { $this->doc .= '</td>'; } @@ -1507,7 +1607,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @return int The current header level */ - public function getLastlevel() { + public function getLastlevel() + { return $this->lastlevel; } @@ -1523,9 +1624,10 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * @author Andreas Gohr <andi@splitbrain.org> */ - public function _formatLink($link) { + public function _formatLink($link) + { //make sure the url is XHTML compliant (skip mailto) - if(substr($link['url'], 0, 7) != 'mailto:') { + if (substr($link['url'], 0, 7) != 'mailto:') { $link['url'] = str_replace('&', '&', $link['url']); $link['url'] = str_replace('&amp;', '&', $link['url']); } @@ -1534,18 +1636,18 @@ class Doku_Renderer_xhtml extends Doku_Renderer { // be sure there are no bad chars in url or title // (we can't do this for name because it can contain an img tag) - $link['url'] = strtr($link['url'], array('>' => '%3E', '<' => '%3C', '"' => '%22')); - $link['title'] = strtr($link['title'], array('>' => '>', '<' => '<', '"' => '"')); + $link['url'] = strtr($link['url'], ['>' => '%3E', '<' => '%3C', '"' => '%22']); + $link['title'] = strtr($link['title'], ['>' => '>', '<' => '<', '"' => '"']); $ret = ''; $ret .= $link['pre']; - $ret .= '<a href="'.$link['url'].'"'; - if(!empty($link['class'])) $ret .= ' class="'.$link['class'].'"'; - if(!empty($link['target'])) $ret .= ' target="'.$link['target'].'"'; - if(!empty($link['title'])) $ret .= ' title="'.$link['title'].'"'; - if(!empty($link['style'])) $ret .= ' style="'.$link['style'].'"'; - if(!empty($link['rel'])) $ret .= ' rel="'.trim($link['rel']).'"'; - if(!empty($link['more'])) $ret .= ' '.$link['more']; + $ret .= '<a href="' . $link['url'] . '"'; + if (!empty($link['class'])) $ret .= ' class="' . $link['class'] . '"'; + if (!empty($link['target'])) $ret .= ' target="' . $link['target'] . '"'; + if (!empty($link['title'])) $ret .= ' title="' . $link['title'] . '"'; + if (!empty($link['style'])) $ret .= ' style="' . $link['style'] . '"'; + if (!empty($link['rel'])) $ret .= ' rel="' . trim($link['rel']) . '"'; + if (!empty($link['more'])) $ret .= ' ' . $link['more']; $ret .= '>'; $ret .= $link['name']; $ret .= '</a>'; @@ -1556,123 +1658,133 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Renders internal and external media * - * @author Andreas Gohr <andi@splitbrain.org> - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache - * @param bool $render should the media be embedded inline or just linked + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache + * @param bool $render should the media be embedded inline or just linked * @return string + * @author Andreas Gohr <andi@splitbrain.org> */ - public function _media($src, $title = null, $align = null, $width = null, - $height = null, $cache = null, $render = true) { + public function _media( + $src, + $title = null, + $align = null, + $width = null, + $height = null, + $cache = null, + $render = true + ) { $ret = ''; - list($ext, $mime) = mimetype($src); - if(substr($mime, 0, 5) == 'image') { + [$ext, $mime] = mimetype($src); + if (substr($mime, 0, 5) == 'image') { // first get the $title - if(!is_null($title)) { + if (!is_null($title)) { $title = $this->_xmlEntities($title); - } elseif($ext == 'jpg' || $ext == 'jpeg') { + } elseif ($ext == 'jpg' || $ext == 'jpeg') { //try to use the caption from IPTC/EXIF - require_once(DOKU_INC.'inc/JpegMeta.php'); + require_once(DOKU_INC . 'inc/JpegMeta.php'); $jpeg = new JpegMeta(mediaFN($src)); - if($jpeg !== false) $cap = $jpeg->getTitle(); - if(!empty($cap)) { + $cap = $jpeg->getTitle(); + if (!empty($cap)) { $title = $this->_xmlEntities($cap); } } - if(!$render) { + if (!$render) { // if the picture is not supposed to be rendered // return the title of the picture - if($title === null || $title === "") { + if ($title === null || $title === "") { // just show the sourcename - $title = $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($src))); + $title = $this->_xmlEntities(PhpString::basename(noNS($src))); } return $title; } //add image tag $ret .= '<img src="' . ml( - $src, - array( - 'w' => $width, 'h' => $height, + $src, + [ + 'w' => $width, + 'h' => $height, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src) - ) - ) . '"'; - $ret .= ' class="media'.$align.'"'; + ] + ) . '"'; + $ret .= ' class="media' . $align . '"'; $ret .= ' loading="lazy"'; - if($title) { - $ret .= ' title="'.$title.'"'; - $ret .= ' alt="'.$title.'"'; + if ($title) { + $ret .= ' title="' . $title . '"'; + $ret .= ' alt="' . $title . '"'; } else { $ret .= ' alt=""'; } - if(!is_null($width)) - $ret .= ' width="'.$this->_xmlEntities($width).'"'; + if (!is_null($width)) { + $ret .= ' width="' . $this->_xmlEntities($width) . '"'; + } - if(!is_null($height)) - $ret .= ' height="'.$this->_xmlEntities($height).'"'; + if (!is_null($height)) { + $ret .= ' height="' . $this->_xmlEntities($height) . '"'; + } $ret .= ' />'; - - } elseif(media_supportedav($mime, 'video') || media_supportedav($mime, 'audio')) { + } elseif (media_supportedav($mime, 'video') || media_supportedav($mime, 'audio')) { // first get the $title - $title = !is_null($title) ? $title : false; - if(!$render) { + $title ??= false; + if (!$render) { // if the file is not supposed to be rendered // return the title of the file (just the sourcename if there is no title) - return $this->_xmlEntities($title ? $title : \dokuwiki\Utf8\PhpString::basename(noNS($src))); + return $this->_xmlEntities($title ?: PhpString::basename(noNS($src))); } - $att = array(); + $att = []; $att['class'] = "media$align"; - if($title) { + if ($title) { $att['title'] = $title; } - if(media_supportedav($mime, 'video')) { + if (media_supportedav($mime, 'video')) { //add video $ret .= $this->_video($src, $width, $height, $att); } - if(media_supportedav($mime, 'audio')) { + if (media_supportedav($mime, 'audio')) { //add audio $ret .= $this->_audio($src, $att); } - - } elseif($mime == 'application/x-shockwave-flash') { - if(!$render) { + } elseif ($mime == 'application/x-shockwave-flash') { + if (!$render) { // if the flash is not supposed to be rendered // return the title of the flash - if(!$title) { + if (!$title) { // just show the sourcename - $title = \dokuwiki\Utf8\PhpString::basename(noNS($src)); + $title = PhpString::basename(noNS($src)); } return $this->_xmlEntities($title); } - $att = array(); + $att = []; $att['class'] = "media$align"; - if($align == 'right') $att['align'] = 'right'; - if($align == 'left') $att['align'] = 'left'; + if ($align == 'right') $att['align'] = 'right'; + if ($align == 'left') $att['align'] = 'left'; $ret .= html_flashobject( - ml($src, array('cache' => $cache), true, '&'), $width, $height, - array('quality' => 'high'), + ml($src, ['cache' => $cache], true, '&'), + $width, + $height, + ['quality' => 'high'], null, $att, $this->_xmlEntities($title) ); - } elseif($title) { + } elseif ($title) { // well at least we have a title to display $ret .= $this->_xmlEntities($title); } else { // just show the sourcename - $ret .= $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($src))); + $ret .= $this->_xmlEntities(PhpString::basename(noNS($src))); } return $ret; @@ -1684,32 +1796,33 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * @param $string * @return string */ - public function _xmlEntities($string) { + public function _xmlEntities($string) + { return hsc($string); } - /** * Construct a title and handle images in titles * - * @author Harry Fuecks <hfuecks@gmail.com> - * @param string|array $title either string title or media array - * @param string $default default title if nothing else is found - * @param bool $isImage will be set to true if it's a media file - * @param null|string $id linked page id (used to extract title from first heading) - * @param string $linktype content|navigation + * @param string|array $title either string title or media array + * @param string $default default title if nothing else is found + * @param bool $isImage will be set to true if it's a media file + * @param null|string $id linked page id (used to extract title from first heading) + * @param string $linktype content|navigation * @return string HTML of the title, might be full image tag or just escaped text + * @author Harry Fuecks <hfuecks@gmail.com> */ - public function _getLinkTitle($title, $default, &$isImage, $id = null, $linktype = 'content') { + public function _getLinkTitle($title, $default, &$isImage, $id = null, $linktype = 'content') + { $isImage = false; - if(is_array($title)) { + if (is_array($title)) { $isImage = true; return $this->_imageTitle($title); - } elseif(is_null($title) || trim($title) == '') { - if(useHeading($linktype) && $id) { + } elseif (is_null($title) || trim($title) == '') { + if (useHeading($linktype) && $id) { $heading = p_get_first_heading($id); - if(!blank($heading)) { + if (!blank($heading)) { return $this->_xmlEntities($heading); } } @@ -1722,17 +1835,18 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Returns HTML code for images used in link titles * - * @author Andreas Gohr <andi@splitbrain.org> * @param array $img * @return string HTML img tag or similar + * @author Andreas Gohr <andi@splitbrain.org> */ - public function _imageTitle($img) { + public function _imageTitle($img) + { global $ID; // some fixes on $img['src'] // see internalmedia() and externalmedia() - list($img['src']) = explode('#', $img['src'], 2); - if($img['type'] == 'internalmedia') { + [$img['src']] = explode('#', $img['src'], 2); + if ($img['type'] == 'internalmedia') { $img['src'] = (new MediaResolver($ID))->resolveId($img['src'], $this->date_at, true); } @@ -1751,29 +1865,30 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * * used in internalmedia() and externalmedia() * - * @author Pierre Spring <pierre.spring@liip.ch> - * @param string $src media ID - * @param string $title descriptive text - * @param string $align left|center|right - * @param int $width width of media in pixel - * @param int $height height of media in pixel - * @param string $cache cache|recache|nocache - * @param bool $render should the media be embedded inline or just linked + * @param string $src media ID + * @param string $title descriptive text + * @param string $align left|center|right + * @param int $width width of media in pixel + * @param int $height height of media in pixel + * @param string $cache cache|recache|nocache + * @param bool $render should the media be embedded inline or just linked * @return array associative array with link config + * @author Pierre Spring <pierre.spring@liip.ch> */ - public function _getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render) { + public function _getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render) + { global $conf; - $link = array(); - $link['class'] = 'media'; - $link['style'] = ''; - $link['pre'] = ''; - $link['suf'] = ''; - $link['more'] = ''; + $link = []; + $link['class'] = 'media'; + $link['style'] = ''; + $link['pre'] = ''; + $link['suf'] = ''; + $link['more'] = ''; $link['target'] = $conf['target']['media']; - if($conf['target']['media']) $link['rel'] = 'noopener'; - $link['title'] = $this->_xmlEntities($src); - $link['name'] = $this->_media($src, $title, $align, $width, $height, $cache, $render); + if ($conf['target']['media']) $link['rel'] = 'noopener'; + $link['title'] = $this->_xmlEntities($src); + $link['name'] = $this->_media($src, $title, $align, $width, $height, $cache, $render); return $link; } @@ -1781,52 +1896,53 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Embed video(s) in HTML * - * @author Anika Henke <anika@selfthinker.org> + * @param string $src - ID of video to embed + * @param int $width - width of the video in pixels + * @param int $height - height of the video in pixels + * @param array $atts - additional attributes for the <video> tag + * @return string * @author Schplurtz le Déboulonné <Schplurtz@laposte.net> * - * @param string $src - ID of video to embed - * @param int $width - width of the video in pixels - * @param int $height - height of the video in pixels - * @param array $atts - additional attributes for the <video> tag - * @return string + * @author Anika Henke <anika@selfthinker.org> */ - public function _video($src, $width, $height, $atts = null) { + public function _video($src, $width, $height, $atts = null) + { // prepare width and height - if(is_null($atts)) $atts = array(); - $atts['width'] = (int) $width; - $atts['height'] = (int) $height; - if(!$atts['width']) $atts['width'] = 320; - if(!$atts['height']) $atts['height'] = 240; + if (is_null($atts)) $atts = []; + $atts['width'] = (int)$width; + $atts['height'] = (int)$height; + if (!$atts['width']) $atts['width'] = 320; + if (!$atts['height']) $atts['height'] = 240; $posterUrl = ''; - $files = array(); - $tracks = array(); + $files = []; + $tracks = []; $isExternal = media_isexternal($src); if ($isExternal) { // take direct source for external files - list(/*ext*/, $srcMime) = mimetype($src); + [/* ext */, $srcMime] = mimetype($src); $files[$srcMime] = $src; } else { // prepare alternative formats - $extensions = array('webm', 'ogv', 'mp4'); - $files = media_alternativefiles($src, $extensions); - $poster = media_alternativefiles($src, array('jpg', 'png')); - $tracks = media_trackfiles($src); - if(!empty($poster)) { + $extensions = ['webm', 'ogv', 'mp4']; + $files = media_alternativefiles($src, $extensions); + $poster = media_alternativefiles($src, ['jpg', 'png']); + $tracks = media_trackfiles($src); + if (!empty($poster)) { $posterUrl = ml(reset($poster), '', true, '&'); } } $out = ''; // open video tag - $out .= '<video '.buildAttributes($atts).' controls="controls"'; - if($posterUrl) $out .= ' poster="'.hsc($posterUrl).'"'; - $out .= '>'.NL; + $out .= '<video ' . buildAttributes($atts) . ' controls="controls"'; + if ($posterUrl) $out .= ' poster="' . hsc($posterUrl) . '"'; + $out .= '>' . NL; $fallback = ''; // output source for each alternative video format - foreach($files as $mime => $file) { + foreach ($files as $mime => $file) { if ($isExternal) { $url = $file; $linkType = 'externalmedia'; @@ -1834,11 +1950,11 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $url = ml($file, '', true, '&'); $linkType = 'internalmedia'; } - $title = !empty($atts['title']) - ? $atts['title'] - : $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($file))); + $title = empty($atts['title']) + ? $this->_xmlEntities(PhpString::basename(noNS($file))) + : $atts['title']; - $out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL; + $out .= '<source src="' . hsc($url) . '" type="' . $mime . '" />' . NL; // alternative content (just a link to the file) $fallback .= $this->$linkType( $file, @@ -1853,49 +1969,50 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } // output each track if any - foreach( $tracks as $trackid => $info ) { - list( $kind, $srclang ) = array_map( 'hsc', $info ); + foreach ($tracks as $trackid => $info) { + [$kind, $srclang] = array_map('hsc', $info); $out .= "<track kind=\"$kind\" srclang=\"$srclang\" "; $out .= "label=\"$srclang\" "; - $out .= 'src="'.ml($trackid, '', true).'">'.NL; + $out .= 'src="' . ml($trackid, '', true) . '">' . NL; } // finish $out .= $fallback; - $out .= '</video>'.NL; + $out .= '</video>' . NL; return $out; } /** * Embed audio in HTML * + * @param string $src - ID of audio to embed + * @param array $atts - additional attributes for the <audio> tag + * @return string * @author Anika Henke <anika@selfthinker.org> * - * @param string $src - ID of audio to embed - * @param array $atts - additional attributes for the <audio> tag - * @return string */ - public function _audio($src, $atts = array()) { - $files = array(); + public function _audio($src, $atts = []) + { + $files = []; $isExternal = media_isexternal($src); if ($isExternal) { // take direct source for external files - list(/*ext*/, $srcMime) = mimetype($src); + [/* ext */, $srcMime] = mimetype($src); $files[$srcMime] = $src; } else { // prepare alternative formats - $extensions = array('ogg', 'mp3', 'wav'); - $files = media_alternativefiles($src, $extensions); + $extensions = ['ogg', 'mp3', 'wav']; + $files = media_alternativefiles($src, $extensions); } $out = ''; // open audio tag - $out .= '<audio '.buildAttributes($atts).' controls="controls">'.NL; + $out .= '<audio ' . buildAttributes($atts) . ' controls="controls">' . NL; $fallback = ''; // output source for each alternative audio format - foreach($files as $mime => $file) { + foreach ($files as $mime => $file) { if ($isExternal) { $url = $file; $linkType = 'externalmedia'; @@ -1903,9 +2020,9 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $url = ml($file, '', true, '&'); $linkType = 'internalmedia'; } - $title = $atts['title'] ? $atts['title'] : $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($file))); + $title = $atts['title'] ?: $this->_xmlEntities(PhpString::basename(noNS($file))); - $out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL; + $out .= '<source src="' . hsc($url) . '" type="' . $mime . '" />' . NL; // alternative content (just a link to the file) $fallback .= $this->$linkType( $file, @@ -1921,7 +2038,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { // finish $out .= $fallback; - $out .= '</audio>'.NL; + $out .= '</audio>' . NL; return $out; } @@ -1929,12 +2046,13 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * _getLastMediaRevisionAt is a helperfunction to internalmedia() and _media() * which returns an existing media revision less or equal to rev or date_at * - * @author lisps * @param string $media_id * @access protected * @return string revision ('' for current) + * @author lisps */ - protected function _getLastMediaRevisionAt($media_id) { + protected function _getLastMediaRevisionAt($media_id) + { if (!$this->date_at || media_isexternal($media_id)) return ''; $changelog = new MediaChangeLog($media_id); return $changelog->getLastRevisionAt($this->date_at); diff --git a/inc/parser/xhtmlsummary.php b/inc/parser/xhtmlsummary.php index 4641bf836..1b73d1368 100644 --- a/inc/parser/xhtmlsummary.php +++ b/inc/parser/xhtmlsummary.php @@ -1,4 +1,5 @@ <?php + /** * The summary XHTML form selects either up to the first two paragraphs * it find in a page or the first section (whichever comes first) @@ -14,8 +15,8 @@ * @author Harry Fuecks <hfuecks@gmail.com> * @todo Is this currently used anywhere? Should it? */ -class Doku_Renderer_xhtmlsummary extends Doku_Renderer_xhtml { - +class Doku_Renderer_xhtmlsummary extends Doku_Renderer_xhtml +{ // Namespace these variables to // avoid clashes with parent classes protected $sum_paragraphs = 0; @@ -25,59 +26,70 @@ class Doku_Renderer_xhtmlsummary extends Doku_Renderer_xhtml { protected $sum_pageTitle = false; /** @inheritdoc */ - public function document_start() { - $this->doc .= DOKU_LF.'<div>'.DOKU_LF; + public function document_start() + { + $this->doc .= DOKU_LF . '<div>' . DOKU_LF; } /** @inheritdoc */ - public function document_end() { + public function document_end() + { $this->doc = $this->sum_summary; - $this->doc .= DOKU_LF.'</div>'.DOKU_LF; + $this->doc .= DOKU_LF . '</div>' . DOKU_LF; } - /** @inheritdoc */ - public function header($text, $level, $pos) { - if ( !$this->sum_pageTitle ) { + /** @inheritdoc + * @param string $text + * @param int $level + * @param int $pos + * @param false $returnonly + */ + public function header($text, $level, $pos, $returnonly = false) + { + if (!$this->sum_pageTitle) { $this->info['sum_pagetitle'] = $text; $this->sum_pageTitle = true; } - $this->doc .= DOKU_LF.'<h'.$level.'>'; + $this->doc .= DOKU_LF . '<h' . $level . '>'; $this->doc .= $this->_xmlEntities($text); - $this->doc .= "</h$level>".DOKU_LF; + $this->doc .= "</h$level>" . DOKU_LF; } /** @inheritdoc */ - public function section_open($level) { - if ( $this->sum_capture ) { + public function section_open($level) + { + if ($this->sum_capture) { $this->sum_inSection = true; } } /** @inheritdoc */ - public function section_close() { - if ( $this->sum_capture && $this->sum_inSection ) { + public function section_close() + { + if ($this->sum_capture && $this->sum_inSection) { $this->sum_summary .= $this->doc; $this->sum_capture = false; } } /** @inheritdoc */ - public function p_open() { - if ( $this->sum_capture && $this->sum_paragraphs < 2 ) { + public function p_open() + { + if ($this->sum_capture && $this->sum_paragraphs < 2) { $this->sum_paragraphs++; } - parent :: p_open(); + parent::p_open(); } /** @inheritdoc */ - public function p_close() { - parent :: p_close(); - if ( $this->sum_capture && $this->sum_paragraphs >= 2 ) { + public function p_close() + { + parent::p_close(); + if ($this->sum_capture && $this->sum_paragraphs >= 2) { $this->sum_summary .= $this->doc; $this->sum_capture = false; } } - } diff --git a/inc/parserutils.php b/inc/parserutils.php index 0f309cc3d..9beaeef24 100644 --- a/inc/parserutils.php +++ b/inc/parserutils.php @@ -1,4 +1,5 @@ <?php + /** * Utilities for accessing the parser * @@ -7,6 +8,7 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Extension\PluginInterface; use dokuwiki\Cache\CacheInstructions; use dokuwiki\Cache\CacheRenderer; use dokuwiki\ChangeLog\PageChangeLog; @@ -91,17 +93,15 @@ function p_wiki_xhtml($id, $rev = '', $excuse = true, $date_at = '') } elseif ($excuse) { $ret = p_locale_xhtml('norev'); } - } else { - if (file_exists($file)) { - $ret = p_cached_output($file, 'xhtml', $id); - } elseif ($excuse) { - //check if the page once existed - $changelog = new PageChangeLog($id); - if ($changelog->hasRevisions()) { - $ret = p_locale_xhtml('onceexisted'); - } else { - $ret = p_locale_xhtml('newpage'); - } + } elseif (file_exists($file)) { + $ret = p_cached_output($file, 'xhtml', $id); + } elseif ($excuse) { + //check if the page once existed + $changelog = new PageChangeLog($id); + if ($changelog->hasRevisions()) { + $ret = p_locale_xhtml('onceexisted'); + } else { + $ret = p_locale_xhtml('newpage'); } } @@ -193,7 +193,7 @@ function p_cached_instructions($file, $cacheonly = false, $id = '') if ($cacheonly || $cache->useCache() || (isset($run[$file]) && !defined('DOKU_UNITTEST'))) { return $cache->retrieveCache(); - } else if (file_exists($file)) { + } elseif (file_exists($file)) { // no cache - do some work $ins = p_get_instructions(io_readWikiPage($file, $id)); if ($cache->storeCache($ins)) { @@ -359,10 +359,8 @@ function p_set_metadata($id, $data, $render = false, $persistent = true) // now add the passed metadata $protected = ['description', 'date', 'contributor']; foreach ($data as $key => $value) { - // be careful with sub-arrays of $meta['relation'] if ($key == 'relation') { - foreach ($value as $subkey => $subvalue) { if (isset($meta['current'][$key][$subkey]) && is_array($meta['current'][$key][$subkey])) { $meta['current'][$key][$subkey] = array_replace($meta['current'][$key][$subkey], (array)$subvalue); @@ -383,17 +381,16 @@ function p_set_metadata($id, $data, $render = false, $persistent = true) // be careful with some senisitive arrays of $meta } elseif (in_array($key, $protected)) { - // these keys, must have subkeys - a legitimate value must be an array if (is_array($value)) { - $meta['current'][$key] = !empty($meta['current'][$key]) ? - array_replace((array)$meta['current'][$key], $value) : - $value; + $meta['current'][$key] = empty($meta['current'][$key]) ? + $value : + array_replace((array)$meta['current'][$key], $value); if ($persistent) { - $meta['persistent'][$key] = !empty($meta['persistent'][$key]) ? - array_replace((array)$meta['persistent'][$key], $value) : - $value; + $meta['persistent'][$key] = empty($meta['persistent'][$key]) ? + $value : + array_replace((array)$meta['persistent'][$key], $value); } } @@ -435,7 +432,6 @@ function p_purge_metadata($id) } else { $meta['current'][$key] = ''; } - } return p_save_metadata($id, $meta); } @@ -520,7 +516,6 @@ function p_render_metadata($id, $orig) $orig['page'] = $id; $evt = new Event('PARSER_METADATA_RENDER', $orig); if ($evt->advise_before()) { - // get instructions $instructions = p_cached_instructions(wikiFN($id), false, $id); if (is_null($instructions)) { @@ -576,11 +571,11 @@ function p_get_parsermodes() // add syntax plugins $pluginlist = plugin_list('syntax'); - if (count($pluginlist)) { + if ($pluginlist !== []) { global $PARSER_MODES; foreach ($pluginlist as $p) { /** @var SyntaxPlugin $obj */ - if (!$obj = plugin_load('syntax', $p)) continue; //attempt to load plugin into $obj + if (!($obj = plugin_load('syntax', $p)) instanceof PluginInterface) continue; $PARSER_MODES[$obj->getType()][] = "plugin_$p"; //register mode type //add to modes $modes[] = [ @@ -605,11 +600,7 @@ function p_get_parsermodes() foreach ($std_modes as $m) { $class = 'dokuwiki\\Parsing\\ParserMode\\' . ucfirst($m); $obj = new $class(); - $modes[] = array( - 'sort' => $obj->getSort(), - 'mode' => $m, - 'obj' => $obj - ); + $modes[] = ['sort' => $obj->getSort(), 'mode' => $m, 'obj' => $obj]; } // add formatting modes @@ -618,11 +609,11 @@ function p_get_parsermodes() ]; foreach ($fmt_modes as $m) { $obj = new Formatting($m); - $modes[] = array( + $modes[] = [ 'sort' => $obj->getSort(), 'mode' => $m, 'obj' => $obj - ); + ]; } // add modes which need files @@ -656,8 +647,7 @@ function p_get_parsermodes() */ function p_sort_modes($a, $b) { - if ($a['sort'] == $b['sort']) return 0; - return ($a['sort'] < $b['sort']) ? -1 : 1; + return $a['sort'] <=> $b['sort']; } /** @@ -724,7 +714,7 @@ function p_get_renderer($mode) /** @var PluginController $plugin_controller */ global $conf, $plugin_controller; - $rname = !empty($conf['renderer_' . $mode]) ? $conf['renderer_' . $mode] : $mode; + $rname = empty($conf['renderer_' . $mode]) ? $mode : $conf['renderer_' . $mode]; $rclass = "Doku_Renderer_$rname"; // if requested earlier or a bundled renderer @@ -751,7 +741,7 @@ function p_get_renderer($mode) $msg .= ".<br/>Attempting to fallback to the bundled renderer."; msg($msg, -1, '', '', MSG_ADMINS_ONLY); - $Renderer = new $rclass; + $Renderer = new $rclass(); $Renderer->nocache(); // fallback only (and may include admin alerts), don't cache return $Renderer; } @@ -803,12 +793,13 @@ function p_xhtml_cached_geshi($code, $language, $wrapper = 'pre', array $options $optionsmd5 = md5(serialize($options)); $cache = getCacheName($language . $code . $optionsmd5, ".code"); $ctime = @filemtime($cache); - if ($ctime && !$INPUT->bool('purge') && + if ( + $ctime && !$INPUT->bool('purge') && $ctime > filemtime(DOKU_INC . 'vendor/composer/installed.json') && // libraries changed - $ctime > filemtime(reset($config_cascade['main']['default']))) { // dokuwiki changed + $ctime > filemtime(reset($config_cascade['main']['default'])) + ) { // dokuwiki changed $highlighted_code = io_readFile($cache, false); } else { - $geshi = new GeSHi($code, $language); $geshi->set_encoding('utf-8'); $geshi->enable_classes(); @@ -835,4 +826,3 @@ function p_xhtml_cached_geshi($code, $language, $wrapper = 'pre', array $options return $highlighted_code; } } - diff --git a/inc/pluginutils.php b/inc/pluginutils.php index a93cd4f60..cd26d7e86 100644 --- a/inc/pluginutils.php +++ b/inc/pluginutils.php @@ -1,4 +1,5 @@ <?php + /** * Utilities for handling plugins * @@ -11,10 +12,10 @@ use dokuwiki\Extension\AdminPlugin; use dokuwiki\Extension\PluginController; use dokuwiki\Extension\PluginInterface; -if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); +if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); // note that only [a-z0-9]+ is officially supported, // this is only to support plugins that don't follow these conventions, too -if(!defined('DOKU_PLUGIN_NAME_REGEX')) define('DOKU_PLUGIN_NAME_REGEX', '[a-zA-Z0-9\x7f-\xff]+'); +if (!defined('DOKU_PLUGIN_NAME_REGEX')) define('DOKU_PLUGIN_NAME_REGEX', '[a-zA-Z0-9\x7f-\xff]+'); /** * Original plugin functions, remain for backwards compatibility @@ -27,12 +28,12 @@ if(!defined('DOKU_PLUGIN_NAME_REGEX')) define('DOKU_PLUGIN_NAME_REGEX', '[a-zA-Z * @param bool $all; true to retrieve all, false to retrieve only enabled plugins * @return array with plugin names or plugin component names */ -function plugin_list($type='',$all=false) +function plugin_list($type = '', $all = false) { /** @var $plugin_controller PluginController */ global $plugin_controller; - $plugins = $plugin_controller->getList($type,$all); - sort($plugins, SORT_NATURAL|SORT_FLAG_CASE); + $plugins = $plugin_controller->getList($type, $all); + sort($plugins, SORT_NATURAL | SORT_FLAG_CASE); return $plugins; } @@ -47,11 +48,11 @@ function plugin_list($type='',$all=false) * @param $disabled bool true to load even disabled plugins * @return PluginInterface|null the plugin object or null on failure */ -function plugin_load($type,$name,$new=false,$disabled=false) +function plugin_load($type, $name, $new = false, $disabled = false) { /** @var $plugin_controller PluginController */ global $plugin_controller; - return $plugin_controller->load($type,$name,$new,$disabled); + return $plugin_controller->load($type, $name, $new, $disabled); } /** @@ -141,7 +142,7 @@ function plugin_getRequestAdminPlugin() if ($admin_plugin && !$admin_plugin->isAccessibleByCurrentUser()) { $admin_plugin = null; $INPUT->remove('page'); - msg('For admins only',-1); + msg('For admins only', -1); } } } diff --git a/inc/search.php b/inc/search.php index 27ca453c7..04e5c48f6 100644 --- a/inc/search.php +++ b/inc/search.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki search functions * @@ -6,6 +7,8 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Utf8\PhpString; +use dokuwiki\File\MediaFile; use dokuwiki\Utf8\Sort; /** @@ -24,27 +27,28 @@ use dokuwiki\Utf8\Sort; * 'date' to sort by filemtime; leave empty to skip sorting. * @author Andreas Gohr <andi@splitbrain.org> */ -function search(&$data,$base,$func,$opts,$dir='',$lvl=1,$sort='natural'){ - $dirs = array(); - $files = array(); - $filepaths = array(); +function search(&$data, $base, $func, $opts, $dir = '', $lvl = 1, $sort = 'natural') +{ + $dirs = []; + $files = []; + $filepaths = []; // safeguard against runaways #1452 - if($base == '' || $base == '/') { + if ($base == '' || $base == '/') { throw new RuntimeException('No valid $base passed to search() - possible misconfiguration or bug'); } //read in directories and files - $dh = @opendir($base.'/'.$dir); - if(!$dh) return; - while(($file = readdir($dh)) !== false){ - if(preg_match('/^[\._]/',$file)) continue; //skip hidden files and upper dirs - if(is_dir($base.'/'.$dir.'/'.$file)){ - $dirs[] = $dir.'/'.$file; + $dh = @opendir($base . '/' . $dir); + if (!$dh) return; + while (($file = readdir($dh)) !== false) { + if (preg_match('/^[\._]/', $file)) continue; //skip hidden files and upper dirs + if (is_dir($base . '/' . $dir . '/' . $file)) { + $dirs[] = $dir . '/' . $file; continue; } - $files[] = $dir.'/'.$file; - $filepaths[] = $base.'/'.$dir.'/'.$file; + $files[] = $dir . '/' . $file; + $filepaths[] = $base . '/' . $dir . '/' . $file; } closedir($dh); if (!empty($sort)) { @@ -57,14 +61,14 @@ function search(&$data,$base,$func,$opts,$dir='',$lvl=1,$sort='natural'){ } //give directories to userfunction then recurse - foreach($dirs as $dir){ - if (call_user_func_array($func, array(&$data,$base,$dir,'d',$lvl,$opts))){ - search($data,$base,$func,$opts,$dir,$lvl+1,$sort); + foreach ($dirs as $dir) { + if (call_user_func_array($func, [&$data, $base, $dir, 'd', $lvl, $opts])) { + search($data, $base, $func, $opts, $dir, $lvl + 1, $sort); } } //now handle the files - foreach($files as $file){ - call_user_func_array($func, array(&$data,$base,$file,'f',$lvl,$opts)); + foreach ($files as $file) { + call_user_func_array($func, [&$data, $base, $file, 'f', $lvl, $opts]); } } @@ -105,13 +109,14 @@ function search(&$data,$base,$func,$opts,$dir='',$lvl=1,$sort='natural'){ * * @return bool */ -function search_qsearch(&$data,$base,$file,$type,$lvl,$opts){ - $opts = array( - 'idmatch' => '(^|:)'.preg_quote($opts['query'],'/').'/', - 'listfiles' => true, - 'pagesonly' => true, - ); - return search_universal($data,$base,$file,$type,$lvl,$opts); +function search_qsearch(&$data, $base, $file, $type, $lvl, $opts) +{ + $opts = [ + 'idmatch' => '(^|:)' . preg_quote($opts['query'], '/') . '/', + 'listfiles' => true, + 'pagesonly' => true + ]; + return search_universal($data, $base, $file, $type, $lvl, $opts); } /** @@ -130,17 +135,18 @@ function search_qsearch(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_index(&$data,$base,$file,$type,$lvl,$opts){ +function search_index(&$data, $base, $file, $type, $lvl, $opts) +{ global $conf; - $ns = isset($opts['ns']) ? $opts['ns'] : ''; - $opts = array( + $ns = $opts['ns'] ?? ''; + $opts = [ 'pagesonly' => true, 'listdirs' => true, 'listfiles' => empty($opts['nofiles']), 'sneakyacl' => $conf['sneaky_index'], // Hacky, should rather use recmatch - 'depth' => preg_match('#^'.preg_quote($file, '#').'(/|$)#','/'.$ns) ? 0 : -1 - ); + 'depth' => preg_match('#^' . preg_quote($file, '#') . '(/|$)#', '/' . $ns) ? 0 : -1, + ]; return search_universal($data, $base, $file, $type, $lvl, $opts); } @@ -159,11 +165,10 @@ function search_index(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_namespaces(&$data,$base,$file,$type,$lvl,$opts){ - $opts = array( - 'listdirs' => true, - ); - return search_universal($data,$base,$file,$type,$lvl,$opts); +function search_namespaces(&$data, $base, $file, $type, $lvl, $opts) +{ + $opts = ['listdirs' => true]; + return search_universal($data, $base, $file, $type, $lvl, $opts); } /** @@ -185,47 +190,48 @@ function search_namespaces(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_media(&$data,$base,$file,$type,$lvl,$opts){ +function search_media(&$data, $base, $file, $type, $lvl, $opts) +{ //we do nothing with directories - if($type == 'd') { - if(empty($opts['depth'])) return true; // recurse forever - $depth = substr_count($file,'/'); - if($depth >= $opts['depth']) return false; // depth reached + if ($type == 'd') { + if (empty($opts['depth'])) return true; // recurse forever + $depth = substr_count($file, '/'); + if ($depth >= $opts['depth']) return false; // depth reached return true; } - $info = array(); - $info['id'] = pathID($file,true); - if($info['id'] != cleanID($info['id'])){ - if(!empty($opts['showmsg'])) - msg(hsc($info['id']).' is not a valid file name for DokuWiki - skipped',-1); + $info = []; + $info['id'] = pathID($file, true); + if ($info['id'] != cleanID($info['id'])) { + if (!empty($opts['showmsg'])) + msg(hsc($info['id']) . ' is not a valid file name for DokuWiki - skipped', -1); return false; // skip non-valid files } //check ACL for namespace (we have no ACL for mediafiles) - $info['perm'] = auth_quickaclcheck(getNS($info['id']).':*'); - if(empty($opts['skipacl']) && $info['perm'] < AUTH_READ){ + $info['perm'] = auth_quickaclcheck(getNS($info['id']) . ':*'); + if (empty($opts['skipacl']) && $info['perm'] < AUTH_READ) { return false; } //check pattern filter - if(!empty($opts['pattern']) && !@preg_match($opts['pattern'], $info['id'])){ + if (!empty($opts['pattern']) && !@preg_match($opts['pattern'], $info['id'])) { return false; } - $info['file'] = \dokuwiki\Utf8\PhpString::basename($file); - $info['size'] = filesize($base.'/'.$file); - $info['mtime'] = filemtime($base.'/'.$file); - $info['writable'] = is_writable($base.'/'.$file); - if(preg_match("/\.(jpe?g|gif|png)$/",$file)){ + $info['file'] = PhpString::basename($file); + $info['size'] = filesize($base . '/' . $file); + $info['mtime'] = filemtime($base . '/' . $file); + $info['writable'] = is_writable($base . '/' . $file); + if (preg_match("/\.(jpe?g|gif|png)$/", $file)) { $info['isimg'] = true; - $info['meta'] = new JpegMeta($base.'/'.$file); - }else{ + $info['meta'] = new JpegMeta($base . '/' . $file); + } else { $info['isimg'] = false; } - if(!empty($opts['hash'])){ - $info['hash'] = md5(io_readFile(mediaFN($info['id']),false)); + if (!empty($opts['hash'])) { + $info['hash'] = md5(io_readFile(mediaFN($info['id']), false)); } $data[] = $info; @@ -252,35 +258,36 @@ function search_media(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_mediafiles(&$data,$base,$file,$type,$lvl,$opts){ +function search_mediafiles(&$data, $base, $file, $type, $lvl, $opts) +{ //we do nothing with directories - if($type == 'd') { - if(empty($opts['depth'])) return true; // recurse forever - $depth = substr_count($file,'/'); - if($depth >= $opts['depth']) return false; // depth reached + if ($type == 'd') { + if (empty($opts['depth'])) return true; // recurse forever + $depth = substr_count($file, '/'); + if ($depth >= $opts['depth']) return false; // depth reached return true; } - $id = pathID($file,true); - if($id != cleanID($id)){ - if($opts['showmsg']) - msg(hsc($id).' is not a valid file name for DokuWiki - skipped',-1); + $id = pathID($file, true); + if ($id != cleanID($id)) { + if ($opts['showmsg']) + msg(hsc($id) . ' is not a valid file name for DokuWiki - skipped', -1); return false; // skip non-valid files } //check ACL for namespace (we have no ACL for mediafiles) - $info['perm'] = auth_quickaclcheck(getNS($id).':*'); - if(empty($opts['skipacl']) && $info['perm'] < AUTH_READ){ + $info['perm'] = auth_quickaclcheck(getNS($id) . ':*'); + if (empty($opts['skipacl']) && $info['perm'] < AUTH_READ) { return false; } //check pattern filter - if(!empty($opts['pattern']) && !@preg_match($opts['pattern'], $id)){ + if (!empty($opts['pattern']) && !@preg_match($opts['pattern'], $id)) { return false; } - $data[] = new \dokuwiki\File\MediaFile($id); + $data[] = new MediaFile($id); return false; } @@ -299,14 +306,15 @@ function search_mediafiles(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_list(&$data,$base,$file,$type,$lvl,$opts){ +function search_list(&$data, $base, $file, $type, $lvl, $opts) +{ //we do nothing with directories - if($type == 'd') return false; + if ($type == 'd') return false; //only search txt files - if(substr($file,-4) == '.txt'){ + if (substr($file, -4) == '.txt') { //check ACL $id = pathID($file); - if(auth_quickaclcheck($id) < AUTH_READ){ + if (auth_quickaclcheck($id) < AUTH_READ) { return false; } $data[]['id'] = $id; @@ -330,18 +338,19 @@ function search_list(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_pagename(&$data,$base,$file,$type,$lvl,$opts){ +function search_pagename(&$data, $base, $file, $type, $lvl, $opts) +{ //we do nothing with directories - if($type == 'd') return true; + if ($type == 'd') return true; //only search txt files - if(substr($file,-4) != '.txt') return true; + if (substr($file, -4) != '.txt') return true; //simple stringmatching - if (!empty($opts['query'])){ - if(strpos($file,$opts['query']) !== false){ + if (!empty($opts['query'])) { + if (strpos($file, (string) $opts['query']) !== false) { //check ACL $id = pathID($file); - if(auth_quickaclcheck($id) < AUTH_READ){ + if (auth_quickaclcheck($id) < AUTH_READ) { return false; } $data[]['id'] = $id; @@ -368,33 +377,36 @@ function search_pagename(&$data,$base,$file,$type,$lvl,$opts){ * * @return bool */ -function search_allpages(&$data,$base,$file,$type,$lvl,$opts){ - if(isset($opts['depth']) && $opts['depth']){ - $parts = explode('/',ltrim($file,'/')); - if(($type == 'd' && count($parts) >= $opts['depth']) - || ($type != 'd' && count($parts) > $opts['depth'])){ +function search_allpages(&$data, $base, $file, $type, $lvl, $opts) +{ + if (($opts['depth'] ?? 0) > 0) { + $parts = explode('/', ltrim($file, '/')); + if ( + ($type == 'd' && count($parts) >= $opts['depth']) + || ($type != 'd' && count($parts) > $opts['depth']) + ) { return false; // depth reached } } //we do nothing with directories - if($type == 'd'){ + if ($type == 'd') { return true; } //only search txt files - if(substr($file,-4) != '.txt') return true; + if (substr($file, -4) != '.txt') return true; - $item = array(); + $item = []; $item['id'] = pathID($file); - if(empty($opts['skipacl']) && auth_quickaclcheck($item['id']) < AUTH_READ){ + if (empty($opts['skipacl']) && auth_quickaclcheck($item['id']) < AUTH_READ) { return false; } - $item['rev'] = filemtime($base.'/'.$file); + $item['rev'] = filemtime($base . '/' . $file); $item['mtime'] = $item['rev']; - $item['size'] = filesize($base.'/'.$file); - if(!empty($opts['hash'])){ + $item['size'] = filesize($base . '/' . $file); + if (!empty($opts['hash'])) { $item['hash'] = md5(trim(rawWiki($item['id']))); } @@ -417,13 +429,14 @@ function search_allpages(&$data,$base,$file,$type,$lvl,$opts){ * * @return int */ -function sort_search_fulltext($a,$b){ - if($a['count'] > $b['count']){ +function sort_search_fulltext($a, $b) +{ + if ($a['count'] > $b['count']) { return -1; - }elseif($a['count'] < $b['count']){ + } elseif ($a['count'] < $b['count']) { return 1; - }else{ - return Sort::strcmp($a['id'],$b['id']); + } else { + return Sort::strcmp($a['id'], $b['id']); } } @@ -436,12 +449,13 @@ function sort_search_fulltext($a,$b){ * @param string $path * @param bool $keeptxt * - * @return mixed|string + * @return string */ -function pathID($path,$keeptxt=false){ +function pathID($path, $keeptxt = false) +{ $id = utf8_decodeFN($path); - $id = str_replace('/',':',$id); - if(!$keeptxt) $id = preg_replace('#\.txt$#','',$id); + $id = str_replace('/', ':', $id); + if (!$keeptxt) $id = preg_replace('#\.txt$#', '', $id); $id = trim($id, ':'); return $id; } @@ -484,35 +498,36 @@ function pathID($path,$keeptxt=false){ * * @author Andreas Gohr <gohr@cosmocode.de> */ -function search_universal(&$data,$base,$file,$type,$lvl,$opts){ - $item = array(); +function search_universal(&$data, $base, $file, $type, $lvl, $opts) +{ + $item = []; $return = true; // get ID and check if it is a valid one - $item['id'] = pathID($file,($type == 'd' || !empty($opts['keeptxt']))); - if($item['id'] != cleanID($item['id'])){ - if(!empty($opts['showmsg'])){ - msg(hsc($item['id']).' is not a valid file name for DokuWiki - skipped',-1); + $item['id'] = pathID($file, ($type == 'd' || !empty($opts['keeptxt']))); + if ($item['id'] != cleanID($item['id'])) { + if (!empty($opts['showmsg'])) { + msg(hsc($item['id']) . ' is not a valid file name for DokuWiki - skipped', -1); } return false; // skip non-valid files } $item['ns'] = getNS($item['id']); - if($type == 'd') { + if ($type == 'd') { // decide if to recursion into this directory is wanted - if(empty($opts['depth'])){ + if (empty($opts['depth'])) { $return = true; // recurse forever - }else{ - $depth = substr_count($file,'/'); - if($depth >= $opts['depth']){ + } else { + $depth = substr_count($file, '/'); + if ($depth >= $opts['depth']) { $return = false; // depth reached - }else{ + } else { $return = true; } } if ($return) { - $match = empty($opts['recmatch']) || preg_match('/'.$opts['recmatch'].'/',$file); + $match = empty($opts['recmatch']) || preg_match('/' . $opts['recmatch'] . '/', $file); if (!$match) { return false; // doesn't match } @@ -520,30 +535,30 @@ function search_universal(&$data,$base,$file,$type,$lvl,$opts){ } // check ACL - if(empty($opts['skipacl'])){ - if($type == 'd'){ - $item['perm'] = auth_quickaclcheck($item['id'].':*'); - }else{ + if (empty($opts['skipacl'])) { + if ($type == 'd') { + $item['perm'] = auth_quickaclcheck($item['id'] . ':*'); + } else { $item['perm'] = auth_quickaclcheck($item['id']); //FIXME check namespace for media files } - }else{ + } else { $item['perm'] = AUTH_DELETE; } // are we done here maybe? - if($type == 'd'){ - if(empty($opts['listdirs'])) return $return; + if ($type == 'd') { + if (empty($opts['listdirs'])) return $return; //neither list nor recurse forbidden items: - if(empty($opts['skipacl']) && !empty($opts['sneakyacl']) && $item['perm'] < AUTH_READ) return false; - if(!empty($opts['dirmatch']) && !preg_match('/'.$opts['dirmatch'].'/',$file)) return $return; - if(!empty($opts['nsmatch']) && !preg_match('/'.$opts['nsmatch'].'/',$item['ns'])) return $return; - }else{ - if(empty($opts['listfiles'])) return $return; - if(empty($opts['skipacl']) && $item['perm'] < AUTH_READ) return $return; - if(!empty($opts['pagesonly']) && (substr($file,-4) != '.txt')) return $return; - if(empty($opts['showhidden']) && isHiddenPage($item['id'])) return $return; - if(!empty($opts['filematch']) && !preg_match('/'.$opts['filematch'].'/',$file)) return $return; - if(!empty($opts['idmatch']) && !preg_match('/'.$opts['idmatch'].'/',$item['id'])) return $return; + if (empty($opts['skipacl']) && !empty($opts['sneakyacl']) && $item['perm'] < AUTH_READ) return false; + if (!empty($opts['dirmatch']) && !preg_match('/' . $opts['dirmatch'] . '/', $file)) return $return; + if (!empty($opts['nsmatch']) && !preg_match('/' . $opts['nsmatch'] . '/', $item['ns'])) return $return; + } else { + if (empty($opts['listfiles'])) return $return; + if (empty($opts['skipacl']) && $item['perm'] < AUTH_READ) return $return; + if (!empty($opts['pagesonly']) && (substr($file, -4) != '.txt')) return $return; + if (empty($opts['showhidden']) && isHiddenPage($item['id'])) return $return; + if (!empty($opts['filematch']) && !preg_match('/' . $opts['filematch'] . '/', $file)) return $return; + if (!empty($opts['idmatch']) && !preg_match('/' . $opts['idmatch'] . '/', $item['id'])) return $return; } // still here? prepare the item @@ -551,18 +566,18 @@ function search_universal(&$data,$base,$file,$type,$lvl,$opts){ $item['level'] = $lvl; $item['open'] = $return; - if(!empty($opts['meta'])){ - $item['file'] = \dokuwiki\Utf8\PhpString::basename($file); - $item['size'] = filesize($base.'/'.$file); - $item['mtime'] = filemtime($base.'/'.$file); + if (!empty($opts['meta'])) { + $item['file'] = PhpString::basename($file); + $item['size'] = filesize($base . '/' . $file); + $item['mtime'] = filemtime($base . '/' . $file); $item['rev'] = $item['mtime']; - $item['writable'] = is_writable($base.'/'.$file); - $item['executable'] = is_executable($base.'/'.$file); + $item['writable'] = is_writable($base . '/' . $file); + $item['executable'] = is_executable($base . '/' . $file); } - if($type == 'f'){ - if(!empty($opts['hash'])) $item['hash'] = md5(io_readFile($base.'/'.$file,false)); - if(!empty($opts['firsthead'])) $item['title'] = p_get_first_heading($item['id'],METADATA_DONT_RENDER); + if ($type == 'f') { + if (!empty($opts['hash'])) $item['hash'] = md5(io_readFile($base . '/' . $file, false)); + if (!empty($opts['firsthead'])) $item['title'] = p_get_first_heading($item['id'], METADATA_DONT_RENDER); } // finally add the item diff --git a/inc/template.php b/inc/template.php index 0e4e3e0c5..31b0af0a7 100644 --- a/inc/template.php +++ b/inc/template.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki template functions * @@ -6,6 +7,15 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\ActionRouter; +use dokuwiki\Action\Exception\FatalException; +use dokuwiki\Extension\PluginInterface; +use dokuwiki\Ui\Admin; +use dokuwiki\StyleUtils; +use dokuwiki\Menu\Item\AbstractItem; +use dokuwiki\Form\Form; +use dokuwiki\Menu\MobileMenu; +use dokuwiki\Ui\Subscribe; use dokuwiki\Extension\AdminPlugin; use dokuwiki\Extension\Event; use dokuwiki\File\PageResolver; @@ -16,17 +26,19 @@ use dokuwiki\File\PageResolver; * Returns the path to the given file inside the current template, uses * default template if the custom version doesn't exist. * - * @author Andreas Gohr <andi@splitbrain.org> * @param string $file * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function template($file) { +function template($file) +{ global $conf; - if(@is_readable(DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$file)) - return DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$file; + if (@is_readable(DOKU_INC . 'lib/tpl/' . $conf['template'] . '/' . $file)) + return DOKU_INC . 'lib/tpl/' . $conf['template'] . '/' . $file; - return DOKU_INC.'lib/tpl/dokuwiki/'.$file; + return DOKU_INC . 'lib/tpl/dokuwiki/' . $file; } /** @@ -34,14 +46,16 @@ function template($file) { * * This replaces the deprecated DOKU_TPLINC constant * - * @author Andreas Gohr <andi@splitbrain.org> * @param string $tpl The template to use, default to current one * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_incdir($tpl='') { +function tpl_incdir($tpl = '') +{ global $conf; - if(!$tpl) $tpl = $conf['template']; - return DOKU_INC.'lib/tpl/'.$tpl.'/'; + if (!$tpl) $tpl = $conf['template']; + return DOKU_INC . 'lib/tpl/' . $tpl . '/'; } /** @@ -49,14 +63,16 @@ function tpl_incdir($tpl='') { * * This replaces the deprecated DOKU_TPL constant * - * @author Andreas Gohr <andi@splitbrain.org> * @param string $tpl The template to use, default to current one * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_basedir($tpl='') { +function tpl_basedir($tpl = '') +{ global $conf; - if(!$tpl) $tpl = $conf['template']; - return DOKU_BASE.'lib/tpl/'.$tpl.'/'; + if (!$tpl) $tpl = $conf['template']; + return DOKU_BASE . 'lib/tpl/' . $tpl . '/'; } /** @@ -69,14 +85,15 @@ function tpl_basedir($tpl='') { * Everything that doesn't use the main template file isn't * handled by this function. ACL stuff is not done here either. * - * @author Andreas Gohr <andi@splitbrain.org> + * @param bool $prependTOC should the TOC be displayed here? + * @return bool true if any output * * @triggers TPL_ACT_RENDER * @triggers TPL_CONTENT_DISPLAY - * @param bool $prependTOC should the TOC be displayed here? - * @return bool true if any output + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_content($prependTOC = true) { +function tpl_content($prependTOC = true) +{ global $ACT; global $INFO; $INFO['prependTOC'] = $prependTOC; @@ -94,11 +111,12 @@ function tpl_content($prependTOC = true) { * * @return bool */ -function tpl_content_core() { - $router = \dokuwiki\ActionRouter::getInstance(); +function tpl_content_core() +{ + $router = ActionRouter::getInstance(); try { $router->getAction()->tplContent(); - } catch(\dokuwiki\Action\Exception\FatalException $e) { + } catch (FatalException $e) { // there was no content for the action msg(hsc($e->getMessage()), -1); return false; @@ -112,39 +130,35 @@ function tpl_content_core() { * If you use this you most probably want to call tpl_content with * a false argument * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param bool $return Should the TOC be returned instead to be printed? * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_toc($return = false) { +function tpl_toc($return = false) +{ global $TOC; global $ACT; global $ID; global $REV; global $INFO; global $conf; - global $INPUT; - $toc = array(); + $toc = []; - if(is_array($TOC)) { + if (is_array($TOC)) { // if a TOC was prepared in global scope, always use it $toc = $TOC; - } elseif(($ACT == 'show' || substr($ACT, 0, 6) == 'export') && !$REV && $INFO['exists']) { + } elseif (($ACT == 'show' || substr($ACT, 0, 6) == 'export') && !$REV && $INFO['exists']) { // get TOC from metadata, render if neccessary $meta = p_get_metadata($ID, '', METADATA_RENDER_USING_CACHE); - if(isset($meta['internal']['toc'])) { - $tocok = $meta['internal']['toc']; - } else { - $tocok = true; + $tocok = $meta['internal']['toc'] ?? true; + $toc = $meta['description']['tableofcontents'] ?? null; + if (!$tocok || !is_array($toc) || !$conf['tocminheads'] || count($toc) < $conf['tocminheads']) { + $toc = []; } - $toc = isset($meta['description']['tableofcontents']) ? $meta['description']['tableofcontents'] : null; - if(!$tocok || !is_array($toc) || !$conf['tocminheads'] || count($toc) < $conf['tocminheads']) { - $toc = array(); - } - } elseif($ACT == 'admin') { + } elseif ($ACT == 'admin') { // try to load admin plugin TOC - /** @var $plugin AdminPlugin */ + /** @var AdminPlugin $plugin */ if ($plugin = plugin_getRequestAdminPlugin()) { $toc = $plugin->getTOC(); $TOC = $toc; // avoid later rebuild @@ -153,7 +167,7 @@ function tpl_toc($return = false) { Event::createAndTrigger('TPL_TOC_RENDER', $toc, null, false); $html = html_TOC($toc); - if($return) return $html; + if ($return) return $html; echo $html; return ''; } @@ -161,33 +175,34 @@ function tpl_toc($return = false) { /** * Handle the admin page contents * - * @author Andreas Gohr <andi@splitbrain.org> - * * @return bool + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_admin() { +function tpl_admin() +{ global $INFO; global $TOC; global $INPUT; $plugin = null; - $class = $INPUT->str('page'); - if(!empty($class)) { + $class = $INPUT->str('page'); + if (!empty($class)) { $pluginlist = plugin_list('admin'); - if(in_array($class, $pluginlist)) { + if (in_array($class, $pluginlist)) { // attempt to load the plugin - /** @var $plugin AdminPlugin */ + /** @var AdminPlugin $plugin */ $plugin = plugin_load('admin', $class); } } - if($plugin !== null) { - if(!is_array($TOC)) $TOC = $plugin->getTOC(); //if TOC wasn't requested yet - if($INFO['prependTOC']) tpl_toc(); + if ($plugin instanceof PluginInterface) { + if (!is_array($TOC)) $TOC = $plugin->getTOC(); //if TOC wasn't requested yet + if ($INFO['prependTOC']) tpl_toc(); $plugin->html(); } else { - $admin = new dokuwiki\Ui\Admin(); + $admin = new Admin(); $admin->show(); } return true; @@ -198,13 +213,15 @@ function tpl_admin() { * * This has to go into the head section of your template. * - * @author Andreas Gohr <andi@splitbrain.org> + * @param bool $alt Should feeds and alternative format links be added? + * @return bool + * @throws JsonException * + * @author Andreas Gohr <andi@splitbrain.org> * @triggers TPL_METAHEADER_OUTPUT - * @param bool $alt Should feeds and alternative format links be added? - * @return bool */ -function tpl_metaheaders($alt = true) { +function tpl_metaheaders($alt = true) +{ global $ID; global $REV; global $INFO; @@ -218,147 +235,164 @@ function tpl_metaheaders($alt = true) { global $INPUT; // prepare the head array - $head = array(); + $head = []; // prepare seed for js and css - $tseed = $updateVersion; + $tseed = $updateVersion; $depends = getConfigFiles('main'); - $depends[] = DOKU_CONF."tpl/".$conf['template']."/style.ini"; - foreach($depends as $f) $tseed .= @filemtime($f); - $tseed = md5($tseed); + $depends[] = DOKU_CONF . "tpl/" . $conf['template'] . "/style.ini"; + foreach ($depends as $f) $tseed .= @filemtime($f); + $tseed = md5($tseed); // the usual stuff - $head['meta'][] = array('name'=> 'generator', 'content'=> 'DokuWiki'); - if(actionOK('search')) { - $head['link'][] = array( - 'rel' => 'search', 'type'=> 'application/opensearchdescription+xml', - 'href'=> DOKU_BASE.'lib/exe/opensearch.php', 'title'=> $conf['title'] - ); + $head['meta'][] = ['name' => 'generator', 'content' => 'DokuWiki']; + if (actionOK('search')) { + $head['link'][] = [ + 'rel' => 'search', + 'type' => 'application/opensearchdescription+xml', + 'href' => DOKU_BASE . 'lib/exe/opensearch.php', + 'title' => $conf['title'] + ]; } - $head['link'][] = array('rel'=> 'start', 'href'=> DOKU_BASE); - if(actionOK('index')) { - $head['link'][] = array( - 'rel' => 'contents', 'href'=> wl($ID, 'do=index', false, '&'), - 'title'=> $lang['btn_index'] - ); + $head['link'][] = ['rel' => 'start', 'href' => DOKU_BASE]; + if (actionOK('index')) { + $head['link'][] = [ + 'rel' => 'contents', + 'href' => wl($ID, 'do=index', false, '&'), + 'title' => $lang['btn_index'] + ]; } if (actionOK('manifest')) { - $head['link'][] = array('rel'=> 'manifest', 'href'=> DOKU_BASE.'lib/exe/manifest.php'); + $head['link'][] = [ + 'rel' => 'manifest', + 'href' => DOKU_BASE . 'lib/exe/manifest.php' + ]; } - $styleUtil = new \dokuwiki\StyleUtils(); + $styleUtil = new StyleUtils(); $styleIni = $styleUtil->cssStyleini(); $replacements = $styleIni['replacements']; if (!empty($replacements['__theme_color__'])) { - $head['meta'][] = array('name' => 'theme-color', 'content' => $replacements['__theme_color__']); + $head['meta'][] = [ + 'name' => 'theme-color', + 'content' => $replacements['__theme_color__'] + ]; } - if($alt) { - if(actionOK('rss')) { - $head['link'][] = array( - 'rel' => 'alternate', 'type'=> 'application/rss+xml', - 'title'=> $lang['btn_recent'], 'href'=> DOKU_BASE.'feed.php' - ); - $head['link'][] = array( - 'rel' => 'alternate', 'type'=> 'application/rss+xml', - 'title'=> $lang['currentns'], - 'href' => DOKU_BASE.'feed.php?mode=list&ns='.(isset($INFO) ? $INFO['namespace'] : '') - ); + if ($alt) { + if (actionOK('rss')) { + $head['link'][] = [ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => $lang['btn_recent'], + 'href' => DOKU_BASE . 'feed.php' + ]; + $head['link'][] = [ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => $lang['currentns'], + 'href' => DOKU_BASE . 'feed.php?mode=list&ns=' . (isset($INFO) ? $INFO['namespace'] : '') + ]; } - if(($ACT == 'show' || $ACT == 'search') && $INFO['writable']) { - $head['link'][] = array( - 'rel' => 'edit', - 'title'=> $lang['btn_edit'], + if (($ACT == 'show' || $ACT == 'search') && $INFO['writable']) { + $head['link'][] = [ + 'rel' => 'edit', + 'title' => $lang['btn_edit'], 'href' => wl($ID, 'do=edit', false, '&') - ); + ]; } - if(actionOK('rss') && $ACT == 'search') { - $head['link'][] = array( - 'rel' => 'alternate', 'type'=> 'application/rss+xml', - 'title'=> $lang['searchresult'], - 'href' => DOKU_BASE.'feed.php?mode=search&q='.$QUERY - ); + if (actionOK('rss') && $ACT == 'search') { + $head['link'][] = [ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => $lang['searchresult'], + 'href' => DOKU_BASE . 'feed.php?mode=search&q=' . $QUERY + ]; } - if(actionOK('export_xhtml')) { - $head['link'][] = array( - 'rel' => 'alternate', 'type'=> 'text/html', 'title'=> $lang['plainhtml'], - 'href'=> exportlink($ID, 'xhtml', '', false, '&') - ); + if (actionOK('export_xhtml')) { + $head['link'][] = [ + 'rel' => 'alternate', + 'type' => 'text/html', + 'title' => $lang['plainhtml'], + 'href' => exportlink($ID, 'xhtml', '', false, '&') + ]; } - if(actionOK('export_raw')) { - $head['link'][] = array( - 'rel' => 'alternate', 'type'=> 'text/plain', 'title'=> $lang['wikimarkup'], - 'href'=> exportlink($ID, 'raw', '', false, '&') - ); + if (actionOK('export_raw')) { + $head['link'][] = [ + 'rel' => 'alternate', + 'type' => 'text/plain', + 'title' => $lang['wikimarkup'], + 'href' => exportlink($ID, 'raw', '', false, '&') + ]; } } // setup robot tags appropriate for different modes - if(($ACT == 'show' || $ACT == 'export_xhtml') && !$REV) { - if($INFO['exists']) { + if (($ACT == 'show' || $ACT == 'export_xhtml') && !$REV) { + if ($INFO['exists']) { //delay indexing: - if((time() - $INFO['lastmod']) >= $conf['indexdelay'] && !isHiddenPage($ID) ) { - $head['meta'][] = array('name'=> 'robots', 'content'=> 'index,follow'); + if ((time() - $INFO['lastmod']) >= $conf['indexdelay'] && !isHiddenPage($ID)) { + $head['meta'][] = ['name' => 'robots', 'content' => 'index,follow']; } else { - $head['meta'][] = array('name'=> 'robots', 'content'=> 'noindex,nofollow'); + $head['meta'][] = ['name' => 'robots', 'content' => 'noindex,nofollow']; } $canonicalUrl = wl($ID, '', true, '&'); if ($ID == $conf['start']) { $canonicalUrl = DOKU_URL; } - $head['link'][] = array('rel'=> 'canonical', 'href'=> $canonicalUrl); + $head['link'][] = ['rel' => 'canonical', 'href' => $canonicalUrl]; } else { - $head['meta'][] = array('name'=> 'robots', 'content'=> 'noindex,follow'); + $head['meta'][] = ['name' => 'robots', 'content' => 'noindex,follow']; } - } elseif(defined('DOKU_MEDIADETAIL')) { - $head['meta'][] = array('name'=> 'robots', 'content'=> 'index,follow'); + } elseif (defined('DOKU_MEDIADETAIL')) { + $head['meta'][] = ['name' => 'robots', 'content' => 'index,follow']; } else { - $head['meta'][] = array('name'=> 'robots', 'content'=> 'noindex,nofollow'); + $head['meta'][] = ['name' => 'robots', 'content' => 'noindex,nofollow']; } // set metadata - if($ACT == 'show' || $ACT == 'export_xhtml') { + if ($ACT == 'show' || $ACT == 'export_xhtml') { // keywords (explicit or implicit) - if(!empty($INFO['meta']['subject'])) { - $head['meta'][] = array('name'=> 'keywords', 'content'=> join(',', $INFO['meta']['subject'])); + if (!empty($INFO['meta']['subject'])) { + $head['meta'][] = ['name' => 'keywords', 'content' => implode(',', $INFO['meta']['subject'])]; } else { - $head['meta'][] = array('name'=> 'keywords', 'content'=> str_replace(':', ',', $ID)); + $head['meta'][] = ['name' => 'keywords', 'content' => str_replace(':', ',', $ID)]; } } // load stylesheets - $head['link'][] = array( + $head['link'][] = [ 'rel' => 'stylesheet', - 'href'=> DOKU_BASE.'lib/exe/css.php?t='.rawurlencode($conf['template']).'&tseed='.$tseed - ); + 'href' => DOKU_BASE . 'lib/exe/css.php?t=' . rawurlencode($conf['template']) . '&tseed=' . $tseed + ]; - $script = "var NS='".(isset($INFO)?$INFO['namespace']:'')."';"; - if($conf['useacl'] && $INPUT->server->str('REMOTE_USER')) { - $script .= "var SIG=".toolbar_signature().";"; + $script = "var NS='" . (isset($INFO) ? $INFO['namespace'] : '') . "';"; + if ($conf['useacl'] && $INPUT->server->str('REMOTE_USER')) { + $script .= "var SIG=" . toolbar_signature() . ";"; } jsinfo(); - $script .= 'var JSINFO = ' . json_encode($JSINFO).';'; - $head['script'][] = array('_data'=> $script); + $script .= 'var JSINFO = ' . json_encode($JSINFO, JSON_THROW_ON_ERROR) . ';'; + $head['script'][] = ['_data' => $script]; // load jquery $jquery = getCdnUrls(); - foreach($jquery as $src) { - $head['script'][] = array( - '_data' => '', - 'src' => $src, - ) + ($conf['defer_js'] ? [ 'defer' => 'defer'] : []); + foreach ($jquery as $src) { + $head['script'][] = [ + '_data' => '', + 'src' => $src + ] + ($conf['defer_js'] ? ['defer' => 'defer'] : []); } // load our javascript dispatcher - $head['script'][] = array( - '_data'=> '', - 'src' => DOKU_BASE.'lib/exe/js.php'.'?t='.rawurlencode($conf['template']).'&tseed='.$tseed, - ) + ($conf['defer_js'] ? [ 'defer' => 'defer'] : []); + $head['script'][] = [ + '_data' => '', + 'src' => DOKU_BASE . 'lib/exe/js.php' . '?t=' . rawurlencode($conf['template']) . '&tseed=' . $tseed + ] + ($conf['defer_js'] ? ['defer' => 'defer'] : []); // trigger event here Event::createAndTrigger('TPL_METAHEADER_OUTPUT', $head, '_tpl_metaheaders_action', true); @@ -375,31 +409,34 @@ function tpl_metaheaders($alt = true) { * For tags having a body attribute specify the body data in the special * attribute '_data'. This field will NOT BE ESCAPED automatically. * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $data + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function _tpl_metaheaders_action($data) { - foreach($data as $tag => $inst) { - if($tag == 'script') { +function _tpl_metaheaders_action($data) +{ + foreach ($data as $tag => $inst) { + if ($tag == 'script') { echo "<!--[if gte IE 9]><!-->\n"; // no scripts for old IE } - foreach($inst as $attr) { - if ( empty($attr) ) { continue; } + foreach ($inst as $attr) { + if (empty($attr)) { + continue; + } echo '<', $tag, ' ', buildAttributes($attr); - if(isset($attr['_data']) || $tag == 'script') { - if($tag == 'script' && isset($attr['_data'])) - $attr['_data'] = "/*<![CDATA[*/". - $attr['_data']. + if (isset($attr['_data']) || $tag == 'script') { + if ($tag == 'script' && isset($attr['_data'])) + $attr['_data'] = "/*<![CDATA[*/" . + $attr['_data'] . "\n/*!]]>*/"; - echo '>', isset($attr['_data']) ? $attr['_data'] : '', '</', $tag, '>'; + echo '>', $attr['_data'] ?? '', '</', $tag, '>'; } else { echo '/>'; } echo "\n"; } - if($tag == 'script') { + if ($tag == 'script') { echo "<!--<![endif]-->\n"; } } @@ -410,20 +447,21 @@ function _tpl_metaheaders_action($data) { * * Just builds a link. * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $url * @param string $name * @param string $more * @param bool $return if true return the link html, otherwise print * @return bool|string html of the link, or true if printed + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_link($url, $name, $more = '', $return = false) { - $out = '<a href="'.$url.'" '; - if($more) $out .= ' '.$more; +function tpl_link($url, $name, $more = '', $return = false) +{ + $out = '<a href="' . $url . '" '; + if ($more) $out .= ' ' . $more; $out .= ">$name</a>"; - if($return) return $out; - print $out; + if ($return) return $out; + echo $out; return true; } @@ -432,17 +470,18 @@ function tpl_link($url, $name, $more = '', $return = false) { * * Wrapper around html_wikilink * - * @author Andreas Gohr <andi@splitbrain.org> - * - * @param string $id page id + * @param string $id page id * @param string|null $name the name of the link - * @param bool $return + * @param bool $return * @return true|string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_pagelink($id, $name = null, $return = false) { - $out = '<bdi>'.html_wikilink($id, $name).'</bdi>'; - if($return) return $out; - print $out; +function tpl_pagelink($id, $name = null, $return = false) +{ + $out = '<bdi>' . html_wikilink($id, $name) . '</bdi>'; + if ($return) return $out; + echo $out; return true; } @@ -452,21 +491,22 @@ function tpl_pagelink($id, $name = null, $return = false) { * Tries to find out which page is parent. * returns false if none is available * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $id page id * @return false|string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_getparent($id) { +function tpl_getparent($id) +{ $resolver = new PageResolver('root'); - $parent = getNS($id).':'; + $parent = getNS($id) . ':'; $parent = $resolver->resolveId($parent); - if($parent == $id) { - $pos = strrpos(getNS($id), ':'); - $parent = substr($parent, 0, $pos).':'; + if ($parent == $id) { + $pos = strrpos(getNS($id), ':'); + $parent = substr($parent, 0, $pos) . ':'; $parent = $resolver->resolveId($parent); - if($parent == $id) return false; + if ($parent == $id) return false; } return $parent; } @@ -474,36 +514,37 @@ function tpl_getparent($id) { /** * Print one of the buttons * - * @author Adrian Lang <mail@adrianlang.de> - * @see tpl_get_action - * * @param string $type * @param bool $return * @return bool|string html, or false if no data, true if printed + * @see tpl_get_action + * + * @author Adrian Lang <mail@adrianlang.de> * @deprecated 2017-09-01 see devel:menus */ -function tpl_button($type, $return = false) { +function tpl_button($type, $return = false) +{ dbg_deprecated('see devel:menus'); $data = tpl_get_action($type); - if($data === false) { + if ($data === false) { return false; - } elseif(!is_array($data)) { + } elseif (!is_array($data)) { $out = sprintf($data, 'button'); } else { /** * @var string $accesskey * @var string $id * @var string $method - * @var array $params + * @var array $params */ extract($data); - if($id === '#dokuwiki__top') { + if ($id === '#dokuwiki__top') { $out = html_topbtn(); } else { $out = html_btn($type, $id, $accesskey, $params, $method); } } - if($return) return $out; + if ($return) return $out; echo $out; return true; } @@ -511,58 +552,62 @@ function tpl_button($type, $return = false) { /** * Like the action buttons but links * - * @author Adrian Lang <mail@adrianlang.de> - * @see tpl_get_action - * - * @param string $type action command - * @param string $pre prefix of link - * @param string $suf suffix of link - * @param string $inner innerHML of link - * @param bool $return if true it returns html, otherwise prints + * @param string $type action command + * @param string $pre prefix of link + * @param string $suf suffix of link + * @param string $inner innerHML of link + * @param bool $return if true it returns html, otherwise prints * @return bool|string html or false if no data, true if printed + * + * @see tpl_get_action + * @author Adrian Lang <mail@adrianlang.de> * @deprecated 2017-09-01 see devel:menus */ -function tpl_actionlink($type, $pre = '', $suf = '', $inner = '', $return = false) { +function tpl_actionlink($type, $pre = '', $suf = '', $inner = '', $return = false) +{ dbg_deprecated('see devel:menus'); global $lang; $data = tpl_get_action($type); - if($data === false) { + if ($data === false) { return false; - } elseif(!is_array($data)) { + } elseif (!is_array($data)) { $out = sprintf($data, 'link'); } else { /** * @var string $accesskey * @var string $id * @var string $method - * @var bool $nofollow - * @var array $params + * @var bool $nofollow + * @var array $params * @var string $replacement */ extract($data); - if(strpos($id, '#') === 0) { + if (strpos($id, '#') === 0) { $linktarget = $id; } else { $linktarget = wl($id, $params); } - $caption = $lang['btn_'.$type]; - if(strpos($caption, '%s')){ + $caption = $lang['btn_' . $type]; + if (strpos($caption, '%s')) { $caption = sprintf($caption, $replacement); } - $akey = $addTitle = ''; - if($accesskey) { - $akey = 'accesskey="'.$accesskey.'" '; - $addTitle = ' ['.strtoupper($accesskey).']'; + $akey = ''; + $addTitle = ''; + if ($accesskey) { + $akey = 'accesskey="' . $accesskey . '" '; + $addTitle = ' [' . strtoupper($accesskey) . ']'; } $rel = $nofollow ? 'rel="nofollow" ' : ''; $out = tpl_link( - $linktarget, $pre.(($inner) ? $inner : $caption).$suf, - 'class="action '.$type.'" '. - $akey.$rel. - 'title="'.hsc($caption).$addTitle.'"', true + $linktarget, + $pre . ($inner ?: $caption) . $suf, + 'class="action ' . $type . '" ' . + $akey . $rel . + 'title="' . hsc($caption) . $addTitle . '"', + true ); } - if($return) return $out; + if ($return) return $out; echo $out; return true; } @@ -570,48 +615,49 @@ function tpl_actionlink($type, $pre = '', $suf = '', $inner = '', $return = fals /** * Check the actions and get data for buttons and links * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> - * @author Adrian Lang <mail@adrianlang.de> - * * @param string $type * @return array|bool|string + * + * @author Adrian Lang <mail@adrianlang.de> + * @author Andreas Gohr <andi@splitbrain.org> + * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> * @deprecated 2017-09-01 see devel:menus */ -function tpl_get_action($type) { +function tpl_get_action($type) +{ dbg_deprecated('see devel:menus'); - if($type == 'history') $type = 'revisions'; - if($type == 'subscription') $type = 'subscribe'; - if($type == 'img_backto') $type = 'imgBackto'; + if ($type == 'history') $type = 'revisions'; + if ($type == 'subscription') $type = 'subscribe'; + if ($type == 'img_backto') $type = 'imgBackto'; $class = '\\dokuwiki\\Menu\\Item\\' . ucfirst($type); - if(class_exists($class)) { + if (class_exists($class)) { try { - /** @var \dokuwiki\Menu\Item\AbstractItem $item */ - $item = new $class; + /** @var AbstractItem $item */ + $item = new $class(); $data = $item->getLegacyData(); $unknown = false; - } catch(\RuntimeException $ignored) { + } catch (RuntimeException $ignored) { return false; } } else { global $ID; - $data = array( + $data = [ 'accesskey' => null, 'type' => $type, 'id' => $ID, 'method' => 'get', - 'params' => array('do' => $type), + 'params' => ['do' => $type], 'nofollow' => true, - 'replacement' => '', - ); + 'replacement' => '' + ]; $unknown = true; } $evt = new Event('TPL_ACTION_GET', $data); - if($evt->advise_before()) { + if ($evt->advise_before()) { //handle unknown types - if($unknown) { + if ($unknown) { $data = '[unknown %s type]'; } } @@ -624,31 +670,32 @@ function tpl_get_action($type) { /** * Wrapper around tpl_button() and tpl_actionlink() * - * @author Anika Henke <anika@selfthinker.org> - * - * @param string $type action command - * @param bool $link link or form button? - * @param string|bool $wrapper HTML element wrapper - * @param bool $return return or print - * @param string $pre prefix for links - * @param string $suf suffix for links - * @param string $inner inner HTML for links + * @param string $type action command + * @param bool $link link or form button? + * @param string|bool $wrapper HTML element wrapper + * @param bool $return return or print + * @param string $pre prefix for links + * @param string $suf suffix for links + * @param string $inner inner HTML for links * @return bool|string + * + * @author Anika Henke <anika@selfthinker.org> * @deprecated 2017-09-01 see devel:menus */ -function tpl_action($type, $link = false, $wrapper = false, $return = false, $pre = '', $suf = '', $inner = '') { +function tpl_action($type, $link = false, $wrapper = false, $return = false, $pre = '', $suf = '', $inner = '') +{ dbg_deprecated('see devel:menus'); $out = ''; - if($link) { + if ($link) { $out .= tpl_actionlink($type, $pre, $suf, $inner, true); } else { $out .= tpl_button($type, true); } - if($out && $wrapper) $out = "<$wrapper>$out</$wrapper>"; + if ($out && $wrapper) $out = "<$wrapper>$out</$wrapper>"; - if($return) return $out; - print $out; - return $out ? true : false; + if ($return) return $out; + echo $out; + return (bool)$out; } /** @@ -661,22 +708,23 @@ function tpl_action($type, $link = false, $wrapper = false, $return = false, $pr * value of "off" to instruct the browser to disable it's own built in * autocompletion feature (MSIE and Firefox) * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param bool $ajax * @param bool $autocomplete * @return bool + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_searchform($ajax = true, $autocomplete = true) { +function tpl_searchform($ajax = true, $autocomplete = true) +{ global $lang; global $ACT; global $QUERY; global $ID; // don't print the search form if search action has been disabled - if(!actionOK('search')) return false; + if (!actionOK('search')) return false; - $searchForm = new dokuwiki\Form\Form([ + $searchForm = new Form([ 'action' => wl(), 'method' => 'get', 'role' => 'search', @@ -696,8 +744,7 @@ function tpl_searchform($ajax = true, $autocomplete = true) { ]) ->id('qsearch__in') ->val($ACT === 'search' ? $QUERY : '') - ->useInput(false) - ; + ->useInput(false); $searchForm->addButton('', $lang['btn_search'])->attrs([ 'type' => 'submit', 'title' => $lang['btn_search'], @@ -716,42 +763,43 @@ function tpl_searchform($ajax = true, $autocomplete = true) { /** * Print the breadcrumbs trace * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $sep Separator between entries - * @param bool $return return or print + * @param bool $return return or print * @return bool|string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_breadcrumbs($sep = null, $return = false) { +function tpl_breadcrumbs($sep = null, $return = false) +{ global $lang; global $conf; //check if enabled - if(!$conf['breadcrumbs']) return false; + if (!$conf['breadcrumbs']) return false; //set default - if(is_null($sep)) $sep = '•'; + if (is_null($sep)) $sep = '•'; - $out=''; + $out = ''; $crumbs = breadcrumbs(); //setup crumb trace - $crumbs_sep = ' <span class="bcsep">'.$sep.'</span> '; + $crumbs_sep = ' <span class="bcsep">' . $sep . '</span> '; //render crumbs, highlight the last one - $out .= '<span class="bchead">'.$lang['breadcrumb'].'</span>'; + $out .= '<span class="bchead">' . $lang['breadcrumb'] . '</span>'; $last = count($crumbs); - $i = 0; - foreach($crumbs as $id => $name) { + $i = 0; + foreach ($crumbs as $id => $name) { $i++; $out .= $crumbs_sep; - if($i == $last) $out .= '<span class="curid">'; - $out .= '<bdi>' . tpl_link(wl($id), hsc($name), 'class="breadcrumbs" title="'.$id.'"', true) . '</bdi>'; - if($i == $last) $out .= '</span>'; + if ($i == $last) $out .= '<span class="curid">'; + $out .= '<bdi>' . tpl_link(wl($id), hsc($name), 'class="breadcrumbs" title="' . $id . '"', true) . '</bdi>'; + if ($i == $last) $out .= '</span>'; } - if($return) return $out; - print $out; - return $out ? true : false; + if ($return) return $out; + echo $out; + return (bool)$out; } /** @@ -760,43 +808,44 @@ function tpl_breadcrumbs($sep = null, $return = false) { * This code was suggested as replacement for the usual breadcrumbs. * It only makes sense with a deep site structure. * + * @param string $sep Separator between entries + * @param bool $return return or print + * @return bool|string + * + * @todo May behave strangely in RTL languages + * @author <fredrik@averpil.com> * @author Andreas Gohr <andi@splitbrain.org> * @author Nigel McNie <oracle.shinoda@gmail.com> * @author Sean Coates <sean@caedmon.net> - * @author <fredrik@averpil.com> - * @todo May behave strangely in RTL languages - * - * @param string $sep Separator between entries - * @param bool $return return or print - * @return bool|string */ -function tpl_youarehere($sep = null, $return = false) { +function tpl_youarehere($sep = null, $return = false) +{ global $conf; global $ID; global $lang; // check if enabled - if(!$conf['youarehere']) return false; + if (!$conf['youarehere']) return false; //set default - if(is_null($sep)) $sep = ' » '; + if (is_null($sep)) $sep = ' » '; $out = ''; $parts = explode(':', $ID); $count = count($parts); - $out .= '<span class="bchead">'.$lang['youarehere'].' </span>'; + $out .= '<span class="bchead">' . $lang['youarehere'] . ' </span>'; // always print the startpage - $out .= '<span class="home">' . tpl_pagelink(':'.$conf['start'], null, true) . '</span>'; + $out .= '<span class="home">' . tpl_pagelink(':' . $conf['start'], null, true) . '</span>'; // print intermediate namespace links $part = ''; - for($i = 0; $i < $count - 1; $i++) { - $part .= $parts[$i].':'; + for ($i = 0; $i < $count - 1; $i++) { + $part .= $parts[$i] . ':'; $page = $part; - if($page == $conf['start']) continue; // Skip startpage + if ($page == $conf['start']) continue; // Skip startpage // output $out .= $sep . tpl_pagelink($page, null, true); @@ -807,21 +856,21 @@ function tpl_youarehere($sep = null, $return = false) { $page = (new PageResolver('root'))->resolveId($page); if ($page == $part . $parts[$i]) { if ($return) return $out; - print $out; + echo $out; return true; } } - $page = $part.$parts[$i]; - if($page == $conf['start']) { - if($return) return $out; - print $out; + $page = $part . $parts[$i]; + if ($page == $conf['start']) { + if ($return) return $out; + echo $out; return true; } $out .= $sep; $out .= tpl_pagelink($page, null, true); - if($return) return $out; - print $out; - return $out ? true : false; + if ($return) return $out; + echo $out; + return (bool)$out; } /** @@ -830,17 +879,18 @@ function tpl_youarehere($sep = null, $return = false) { * * Could be enhanced with a profile link in future? * - * @author Andreas Gohr <andi@splitbrain.org> - * * @return bool + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_userinfo() { +function tpl_userinfo() +{ global $lang; /** @var Input $INPUT */ global $INPUT; - if($INPUT->server->str('REMOTE_USER')) { - print $lang['loggedinas'].' '.userlink(); + if ($INPUT->server->str('REMOTE_USER')) { + echo $lang['loggedinas'] . ' ' . userlink(); return true; } return false; @@ -849,55 +899,55 @@ function tpl_userinfo() { /** * Print some info about the current page * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param bool $ret return content instead of printing it * @return bool|string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_pageinfo($ret = false) { +function tpl_pageinfo($ret = false) +{ global $conf; global $lang; global $INFO; global $ID; // return if we are not allowed to view the page - if(!auth_quickaclcheck($ID)) { + if (!auth_quickaclcheck($ID)) { return false; } // prepare date and path $fn = $INFO['filepath']; - if(!$conf['fullpath']) { - if($INFO['rev']) { - $fn = str_replace($conf['olddir'].'/', '', $fn); + if (!$conf['fullpath']) { + if ($INFO['rev']) { + $fn = str_replace($conf['olddir'] . '/', '', $fn); } else { - $fn = str_replace($conf['datadir'].'/', '', $fn); + $fn = str_replace($conf['datadir'] . '/', '', $fn); } } - $fn = utf8_decodeFN($fn); + $fn = utf8_decodeFN($fn); $date = dformat($INFO['lastmod']); // print it - if($INFO['exists']) { - $out = ''; - $out .= '<bdi>'.$fn.'</bdi>'; + if ($INFO['exists']) { + $out = '<bdi>' . $fn . '</bdi>'; $out .= ' · '; $out .= $lang['lastmod']; $out .= ' '; $out .= $date; - if($INFO['editor']) { - $out .= ' '.$lang['by'].' '; - $out .= '<bdi>'.editorinfo($INFO['editor']).'</bdi>'; + if ($INFO['editor']) { + $out .= ' ' . $lang['by'] . ' '; + $out .= '<bdi>' . editorinfo($INFO['editor']) . '</bdi>'; } else { - $out .= ' ('.$lang['external_edit'].')'; + $out .= ' (' . $lang['external_edit'] . ')'; } - if($INFO['locked']) { + if ($INFO['locked']) { $out .= ' · '; $out .= $lang['lockedby']; $out .= ' '; - $out .= '<bdi>'.editorinfo($INFO['locked']).'</bdi>'; + $out .= '<bdi>' . editorinfo($INFO['locked']) . '</bdi>'; } - if($ret) { + if ($ret) { return $out; } else { echo $out; @@ -913,77 +963,78 @@ function tpl_pageinfo($ret = false) { * If useheading is enabled this will use the first headline else * the given ID is used. * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $id page id - * @param bool $ret return content instead of printing + * @param bool $ret return content instead of printing * @return bool|string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_pagetitle($id = null, $ret = false) { - global $ACT, $INPUT, $conf, $lang; +function tpl_pagetitle($id = null, $ret = false) +{ + global $ACT, $conf, $lang; - if(is_null($id)) { + if (is_null($id)) { global $ID; $id = $ID; } $name = $id; - if(useHeading('navigation')) { + if (useHeading('navigation')) { $first_heading = p_get_first_heading($id); - if($first_heading) $name = $first_heading; + if ($first_heading) $name = $first_heading; } // default page title is the page name, modify with the current action switch ($ACT) { // admin functions - case 'admin' : + case 'admin': $page_title = $lang['btn_admin']; // try to get the plugin name - /** @var $plugin AdminPlugin */ - if ($plugin = plugin_getRequestAdminPlugin()){ + /** @var AdminPlugin $plugin */ + if ($plugin = plugin_getRequestAdminPlugin()) { $plugin_title = $plugin->getMenuText($conf['lang']); - $page_title = $plugin_title ? $plugin_title : $plugin->getPluginName(); + $page_title = $plugin_title ?: $plugin->getPluginName(); } break; // user functions - case 'login' : - case 'profile' : - case 'register' : - case 'resendpwd' : - $page_title = $lang['btn_'.$ACT]; + case 'login': + case 'profile': + case 'register': + case 'resendpwd': + $page_title = $lang['btn_' . $ACT]; break; - // wiki functions - case 'search' : - case 'index' : - $page_title = $lang['btn_'.$ACT]; + // wiki functions + case 'search': + case 'index': + $page_title = $lang['btn_' . $ACT]; break; // page functions - case 'edit' : - case 'preview' : - $page_title = "✎ ".$name; + case 'edit': + case 'preview': + $page_title = "✎ " . $name; break; - case 'revisions' : + case 'revisions': $page_title = $name . ' - ' . $lang['btn_revs']; break; - case 'backlink' : - case 'recent' : - case 'subscribe' : - $page_title = $name . ' - ' . $lang['btn_'.$ACT]; + case 'backlink': + case 'recent': + case 'subscribe': + $page_title = $name . ' - ' . $lang['btn_' . $ACT]; break; - default : // SHOW and anything else not included + default: // SHOW and anything else not included $page_title = $name; } - if($ret) { + if ($ret) { return hsc($page_title); } else { - print hsc($page_title); + echo hsc($page_title); return true; } } @@ -1000,24 +1051,27 @@ function tpl_pagetitle($id = null, $ret = false) { * * Only allowed in: detail.php * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array|string $tags tag or array of tags to try - * @param string $alt alternative output if no data was found - * @param null|string $src the image src, uses global $SRC if not given + * @param string $alt alternative output if no data was found + * @param null|string $src the image src, uses global $SRC if not given * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_img_getTag($tags, $alt = '', $src = null) { +function tpl_img_getTag($tags, $alt = '', $src = null) +{ // Init Exif Reader global $SRC, $imgMeta; - if(is_null($src)) $src = $SRC; - if(is_null($src)) return $alt; + if (is_null($src)) $src = $SRC; + if (is_null($src)) return $alt; - if(!isset($imgMeta) || $imgMeta === null) $imgMeta = new JpegMeta($src); - if($imgMeta === false) return $alt; + if (!isset($imgMeta)) { + $imgMeta = new JpegMeta($src); + } + if ($imgMeta === false) return $alt; $info = cleanText($imgMeta->getField($tags)); - if($info == false) return $alt; + if (!$info) return $alt; return $info; } @@ -1025,27 +1079,27 @@ function tpl_img_getTag($tags, $alt = '', $src = null) { /** * Garbage collects up the open JpegMeta object. */ -function tpl_img_close(){ +function tpl_img_close() +{ global $imgMeta; $imgMeta = null; } /** - * Returns a description list of the metatags of the current image - * - * @return string html of description list + * Prints a html description list of the metatags of the current image */ -function tpl_img_meta() { +function tpl_img_meta() +{ global $lang; $tags = tpl_get_img_meta(); echo '<dl>'; - foreach($tags as $tag) { + foreach ($tags as $tag) { $label = $lang[$tag['langkey']]; - if(!$label) $label = $tag['langkey'] . ':'; + if (!$label) $label = $tag['langkey'] . ':'; - echo '<dt>'.$label.'</dt><dd>'; + echo '<dt>' . $label . '</dt><dd>'; if ($tag['type'] == 'date') { echo dformat($tag['value']); } else { @@ -1064,28 +1118,27 @@ function tpl_img_meta() { * - string type type of value * - string value tag value (unescaped) */ -function tpl_get_img_meta() { +function tpl_get_img_meta() +{ $config_files = getConfigFiles('mediameta'); foreach ($config_files as $config_file) { - if(file_exists($config_file)) { + if (file_exists($config_file)) { include($config_file); } } - /** @var array $fields the included array with metadata */ - - $tags = array(); - foreach($fields as $tag){ - $t = array(); + $tags = []; + foreach ($fields as $tag) { + $t = []; if (!empty($tag[0])) { - $t = array($tag[0]); + $t = [$tag[0]]; } - if(isset($tag[3]) && is_array($tag[3])) { - $t = array_merge($t,$tag[3]); + if (isset($tag[3]) && is_array($tag[3])) { + $t = array_merge($t, $tag[3]); } $value = tpl_img_getTag($t); if ($value) { - $tags[] = array('langkey' => $tag[1], 'type' => $tag[2], 'value' => $value); + $tags[] = ['langkey' => $tag[1], 'type' => $tag[2], 'value' => $value]; } } return $tags; @@ -1097,63 +1150,62 @@ function tpl_get_img_meta() { * Only allowed in: detail.php * * @triggers TPL_IMG_DISPLAY - * @param $maxwidth int - maximal width of the image - * @param $maxheight int - maximal height of the image - * @param $link bool - link to the orginal size? - * @param $params array - additional image attributes + * @param int $maxwidth - maximal width of the image + * @param int $maxheight - maximal height of the image + * @param bool $link - link to the orginal size? + * @param array $params - additional image attributes * @return bool Result of TPL_IMG_DISPLAY */ -function tpl_img($maxwidth = 0, $maxheight = 0, $link = true, $params = null) { +function tpl_img($maxwidth = 0, $maxheight = 0, $link = true, $params = null) +{ global $IMG; /** @var Input $INPUT */ global $INPUT; global $REV; - $w = (int) tpl_img_getTag('File.Width'); - $h = (int) tpl_img_getTag('File.Height'); + $w = (int)tpl_img_getTag('File.Width'); + $h = (int)tpl_img_getTag('File.Height'); //resize to given max values $ratio = 1; - if($w >= $h) { - if($maxwidth && $w >= $maxwidth) { + if ($w >= $h) { + if ($maxwidth && $w >= $maxwidth) { $ratio = $maxwidth / $w; - } elseif($maxheight && $h > $maxheight) { + } elseif ($maxheight && $h > $maxheight) { $ratio = $maxheight / $h; } - } else { - if($maxheight && $h >= $maxheight) { - $ratio = $maxheight / $h; - } elseif($maxwidth && $w > $maxwidth) { - $ratio = $maxwidth / $w; - } + } elseif ($maxheight && $h >= $maxheight) { + $ratio = $maxheight / $h; + } elseif ($maxwidth && $w > $maxwidth) { + $ratio = $maxwidth / $w; } - if($ratio) { + if ($ratio) { $w = floor($ratio * $w); $h = floor($ratio * $h); } //prepare URLs - $url = ml($IMG, array('cache'=> $INPUT->str('cache'),'rev'=>$REV), true, '&'); - $src = ml($IMG, array('cache'=> $INPUT->str('cache'),'rev'=>$REV, 'w'=> $w, 'h'=> $h), true, '&'); + $url = ml($IMG, ['cache' => $INPUT->str('cache'), 'rev' => $REV], true, '&'); + $src = ml($IMG, ['cache' => $INPUT->str('cache'), 'rev' => $REV, 'w' => $w, 'h' => $h], true, '&'); //prepare attributes $alt = tpl_img_getTag('Simple.Title'); - if(is_null($params)) { - $p = array(); + if (is_null($params)) { + $p = []; } else { $p = $params; } - if($w) $p['width'] = $w; - if($h) $p['height'] = $h; + if ($w) $p['width'] = $w; + if ($h) $p['height'] = $h; $p['class'] = 'img_detail'; - if($alt) { - $p['alt'] = $alt; + if ($alt) { + $p['alt'] = $alt; $p['title'] = $alt; } else { $p['alt'] = ''; } $p['src'] = $src; - $data = array('url'=> ($link ? $url : null), 'params'=> $p); + $data = ['url' => ($link ? $url : null), 'params' => $p]; return Event::createAndTrigger('TPL_IMG_DISPLAY', $data, '_tpl_img_action', true); } @@ -1163,35 +1215,36 @@ function tpl_img($maxwidth = 0, $maxheight = 0, $link = true, $params = null) { * @param array $data * @return bool */ -function _tpl_img_action($data) { +function _tpl_img_action($data) +{ global $lang; $p = buildAttributes($data['params']); - if($data['url']) print '<a href="'.hsc($data['url']).'" title="'.$lang['mediaview'].'">'; - print '<img '.$p.'/>'; - if($data['url']) print '</a>'; + if ($data['url']) echo '<a href="' . hsc($data['url']) . '" title="' . $lang['mediaview'] . '">'; + echo '<img ' . $p . '/>'; + if ($data['url']) echo '</a>'; return true; } /** * This function inserts a small gif which in reality is the indexer function. * - * Should be called somewhere at the very end of the main.php - * template + * Should be called somewhere at the very end of the main.php template * * @return bool */ -function tpl_indexerWebBug() { +function tpl_indexerWebBug() +{ global $ID; - $p = array(); - $p['src'] = DOKU_BASE.'lib/exe/taskrunner.php?id='.rawurlencode($ID). - '&'.time(); - $p['width'] = 2; //no more 1x1 px image because we live in times of ad blockers... + $p = []; + $p['src'] = DOKU_BASE . 'lib/exe/taskrunner.php?id=' . rawurlencode($ID) . + '&' . time(); + $p['width'] = 2; //no more 1x1 px image because we live in times of ad blockers... $p['height'] = 1; - $p['alt'] = ''; - $att = buildAttributes($p); - print "<img $att />"; + $p['alt'] = ''; + $att = buildAttributes($p); + echo "<img $att />"; return true; } @@ -1200,32 +1253,29 @@ function tpl_indexerWebBug() { * * use this function to access template configuration variables * - * @param string $id name of the value to access - * @param mixed $notset what to return if the setting is not available + * @param string $id name of the value to access + * @param mixed $notset what to return if the setting is not available * @return mixed */ -function tpl_getConf($id, $notset=false) { +function tpl_getConf($id, $notset = false) +{ global $conf; static $tpl_configloaded = false; $tpl = $conf['template']; - if(!$tpl_configloaded) { + if (!$tpl_configloaded) { $tconf = tpl_loadConfig(); - if($tconf !== false) { - foreach($tconf as $key => $value) { - if(isset($conf['tpl'][$tpl][$key])) continue; + if ($tconf !== false) { + foreach ($tconf as $key => $value) { + if (isset($conf['tpl'][$tpl][$key])) continue; $conf['tpl'][$tpl][$key] = $value; } $tpl_configloaded = true; } } - if(isset($conf['tpl'][$tpl][$id])){ - return $conf['tpl'][$tpl][$id]; - } - - return $notset; + return $conf['tpl'][$tpl][$id] ?? $notset; } /** @@ -1234,14 +1284,15 @@ function tpl_getConf($id, $notset=false) { * reads all template configuration variables * this function is automatically called by tpl_getConf() * - * @return array + * @return false|array */ -function tpl_loadConfig() { +function tpl_loadConfig() +{ - $file = tpl_incdir().'/conf/default.php'; - $conf = array(); + $file = tpl_incdir() . '/conf/default.php'; + $conf = []; - if(!file_exists($file)) return false; + if (!file_exists($file)) return false; // load default config file include($file); @@ -1250,6 +1301,7 @@ function tpl_loadConfig() { } // language methods + /** * tpl_getLang($id) * @@ -1258,44 +1310,46 @@ function tpl_loadConfig() { * @param string $id key of language string * @return string */ -function tpl_getLang($id) { - static $lang = array(); +function tpl_getLang($id) +{ + static $lang = []; - if(count($lang) === 0) { + if (count($lang) === 0) { global $conf, $config_cascade; // definitely don't invoke "global $lang" $path = tpl_incdir() . 'lang/'; - $lang = array(); + $lang = []; // don't include once @include($path . 'en/lang.php'); - foreach($config_cascade['lang']['template'] as $config_file) { - if(file_exists($config_file . $conf['template'] . '/en/lang.php')) { + foreach ($config_cascade['lang']['template'] as $config_file) { + if (file_exists($config_file . $conf['template'] . '/en/lang.php')) { include($config_file . $conf['template'] . '/en/lang.php'); } } - if($conf['lang'] != 'en') { + if ($conf['lang'] != 'en') { @include($path . $conf['lang'] . '/lang.php'); - foreach($config_cascade['lang']['template'] as $config_file) { - if(file_exists($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php')) { + foreach ($config_cascade['lang']['template'] as $config_file) { + if (file_exists($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php')) { include($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php'); } } } } - return isset($lang[$id]) ? $lang[$id] : ''; + return $lang[$id] ?? ''; } /** * Retrieve a language dependent file and pass to xhtml renderer for display * template equivalent of p_locale_xhtml() * - * @param string $id id of language dependent wiki page + * @param string $id id of language dependent wiki page * @return string parsed contents of the wiki page in xhtml format */ -function tpl_locale_xhtml($id) { +function tpl_locale_xhtml($id) +{ return p_cached_output(tpl_localeFN($id)); } @@ -1305,15 +1359,16 @@ function tpl_locale_xhtml($id) { * @param string $id id of localized text * @return string wiki text */ -function tpl_localeFN($id) { - $path = tpl_incdir().'lang/'; +function tpl_localeFN($id) +{ + $path = tpl_incdir() . 'lang/'; global $conf; - $file = DOKU_CONF.'template_lang/'.$conf['template'].'/'.$conf['lang'].'/'.$id.'.txt'; - if (!file_exists($file)){ - $file = $path.$conf['lang'].'/'.$id.'.txt'; - if(!file_exists($file)){ + $file = DOKU_CONF . 'template_lang/' . $conf['template'] . '/' . $conf['lang'] . '/' . $id . '.txt'; + if (!file_exists($file)) { + $file = $path . $conf['lang'] . '/' . $id . '.txt'; + if (!file_exists($file)) { //fall back to english - $file = $path.'en/'.$id.'.txt'; + $file = $path . 'en/' . $id . '.txt'; } } return $file; @@ -1334,7 +1389,8 @@ function tpl_localeFN($id) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_mediaContent($fromajax = false, $sort='natural') { +function tpl_mediaContent($fromajax = false, $sort = 'natural') +{ global $IMG; global $AUTH; global $INUSE; @@ -1344,12 +1400,12 @@ function tpl_mediaContent($fromajax = false, $sort='natural') { global $INPUT; $do = $INPUT->extract('do')->str('do'); - if(in_array($do, array('save', 'cancel'))) $do = ''; + if (in_array($do, ['save', 'cancel'])) $do = ''; - if(!$do) { - if($INPUT->bool('edit')) { + if (!$do) { + if ($INPUT->bool('edit')) { $do = 'metaform'; - } elseif(is_array($INUSE)) { + } elseif (is_array($INUSE)) { $do = 'filesinuse'; } else { $do = 'filelist'; @@ -1357,25 +1413,24 @@ function tpl_mediaContent($fromajax = false, $sort='natural') { } // output the content pane, wrapped in an event. - if(!$fromajax) ptln('<div id="media__content">'); - $data = array('do' => $do); - $evt = new Event('MEDIAMANAGER_CONTENT_OUTPUT', $data); - if($evt->advise_before()) { + if (!$fromajax) echo '<div id="media__content">'; + $data = ['do' => $do]; + $evt = new Event('MEDIAMANAGER_CONTENT_OUTPUT', $data); + if ($evt->advise_before()) { $do = $data['do']; - if($do == 'filesinuse') { + if ($do == 'filesinuse') { media_filesinuse($INUSE, $IMG); - } elseif($do == 'filelist') { - media_filelist($NS, $AUTH, $JUMPTO,false,$sort); - } elseif($do == 'searchlist') { + } elseif ($do == 'filelist') { + media_filelist($NS, $AUTH, $JUMPTO, false, $sort); + } elseif ($do == 'searchlist') { media_searchlist($INPUT->str('q'), $NS, $AUTH); } else { - msg('Unknown action '.hsc($do), -1); + msg('Unknown action ' . hsc($do), -1); } } $evt->advise_after(); unset($evt); - if(!$fromajax) ptln('</div>'); - + if (!$fromajax) echo '</div>'; } /** @@ -1385,7 +1440,8 @@ function tpl_mediaContent($fromajax = false, $sort='natural') { * * @author Kate Arzamastseva <pshns@ukr.net> */ -function tpl_mediaFileList() { +function tpl_mediaFileList() +{ global $AUTH; global $NS; global $JUMPTO; @@ -1394,32 +1450,32 @@ function tpl_mediaFileList() { global $INPUT; $opened_tab = $INPUT->str('tab_files'); - if(!$opened_tab || !in_array($opened_tab, array('files', 'upload', 'search'))) $opened_tab = 'files'; - if($INPUT->str('mediado') == 'update') $opened_tab = 'upload'; + if (!$opened_tab || !in_array($opened_tab, ['files', 'upload', 'search'])) $opened_tab = 'files'; + if ($INPUT->str('mediado') == 'update') $opened_tab = 'upload'; - echo '<h2 class="a11y">'.$lang['mediaselect'].'</h2>'.NL; + echo '<h2 class="a11y">' . $lang['mediaselect'] . '</h2>' . NL; media_tabs_files($opened_tab); - echo '<div class="panelHeader">'.NL; + echo '<div class="panelHeader">' . NL; echo '<h3>'; - $tabTitle = ($NS) ? $NS : '['.$lang['mediaroot'].']'; - printf($lang['media_'.$opened_tab], '<strong>'.hsc($tabTitle).'</strong>'); - echo '</h3>'.NL; - if($opened_tab === 'search' || $opened_tab === 'files') { + $tabTitle = $NS ?: '[' . $lang['mediaroot'] . ']'; + printf($lang['media_' . $opened_tab], '<strong>' . hsc($tabTitle) . '</strong>'); + echo '</h3>' . NL; + if ($opened_tab === 'search' || $opened_tab === 'files') { media_tab_files_options(); } - echo '</div>'.NL; + echo '</div>' . NL; - echo '<div class="panelContent">'.NL; - if($opened_tab == 'files') { + echo '<div class="panelContent">' . NL; + if ($opened_tab == 'files') { media_tab_files($NS, $AUTH, $JUMPTO); - } elseif($opened_tab == 'upload') { + } elseif ($opened_tab == 'upload') { media_tab_upload($NS, $AUTH, $JUMPTO); - } elseif($opened_tab == 'search') { + } elseif ($opened_tab == 'search') { media_tab_search($NS, $AUTH); } - echo '</div>'.NL; + echo '</div>' . NL; } /** @@ -1428,12 +1484,13 @@ function tpl_mediaFileList() { * selected file, the meta editing dialog or * list of file revisions * - * @author Kate Arzamastseva <pshns@ukr.net> - * * @param string $image * @param boolean $rev + * + * @author Kate Arzamastseva <pshns@ukr.net> */ -function tpl_mediaFileDetails($image, $rev) { +function tpl_mediaFileDetails($image, $rev) +{ global $conf, $DEL, $lang; /** @var Input $INPUT */ global $INPUT; @@ -1443,56 +1500,60 @@ function tpl_mediaFileDetails($image, $rev) { file_exists(mediaMetaFN($image, '.changes')) && $conf['mediarevisions'] ); - if(!$image || (!file_exists(mediaFN($image)) && !$removed) || $DEL) return; - if($rev && !file_exists(mediaFN($image, $rev))) $rev = false; + if (!$image || (!file_exists(mediaFN($image)) && !$removed) || $DEL) return; + if ($rev && !file_exists(mediaFN($image, $rev))) $rev = false; $ns = getNS($image); $do = $INPUT->str('mediado'); $opened_tab = $INPUT->str('tab_details'); - $tab_array = array('view'); - list(, $mime) = mimetype($image); - if($mime == 'image/jpeg') { + $tab_array = ['view']; + [, $mime] = mimetype($image); + if ($mime == 'image/jpeg') { $tab_array[] = 'edit'; } - if($conf['mediarevisions']) { + if ($conf['mediarevisions']) { $tab_array[] = 'history'; } - if(!$opened_tab || !in_array($opened_tab, $tab_array)) $opened_tab = 'view'; - if($INPUT->bool('edit')) $opened_tab = 'edit'; - if($do == 'restore') $opened_tab = 'view'; + if (!$opened_tab || !in_array($opened_tab, $tab_array)) $opened_tab = 'view'; + if ($INPUT->bool('edit')) $opened_tab = 'edit'; + if ($do == 'restore') $opened_tab = 'view'; media_tabs_details($image, $opened_tab); echo '<div class="panelHeader"><h3>'; - list($ext) = mimetype($image, false); - $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); - $class = 'select mediafile mf_'.$class; + [$ext] = mimetype($image, false); + $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); + $class = 'select mediafile mf_' . $class; + $attributes = $rev ? ['rev' => $rev] : []; - $tabTitle = '<strong><a href="'.ml($image, $attributes).'" class="'.$class.'" title="'.$lang['mediaview'].'">'. - $image.'</a>'.'</strong>'; - if($opened_tab === 'view' && $rev) { + $tabTitle = sprintf( + '<strong><a href="%s" class="%s" title="%s">%s</a></strong>', + ml($image, $attributes), + $class, + $lang['mediaview'], + $image + ); + if ($opened_tab === 'view' && $rev) { printf($lang['media_viewold'], $tabTitle, dformat($rev)); } else { - printf($lang['media_'.$opened_tab], $tabTitle); + printf($lang['media_' . $opened_tab], $tabTitle); } - echo '</h3></div>'.NL; + echo '</h3></div>' . NL; - echo '<div class="panelContent">'.NL; + echo '<div class="panelContent">' . NL; - if($opened_tab == 'view') { + if ($opened_tab == 'view') { media_tab_view($image, $ns, null, $rev); - - } elseif($opened_tab == 'edit' && !$removed) { + } elseif ($opened_tab == 'edit' && !$removed) { media_tab_edit($image, $ns); - - } elseif($opened_tab == 'history' && $conf['mediarevisions']) { + } elseif ($opened_tab == 'history' && $conf['mediarevisions']) { media_tab_history($image, $ns); } - echo '</div>'.NL; + echo '</div>' . NL; } /** @@ -1502,11 +1563,12 @@ function tpl_mediaFileDetails($image, $rev) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_mediaTree() { +function tpl_mediaTree() +{ global $NS; - ptln('<div id="media__tree">'); + echo '<div id="media__tree">'; media_nstree($NS); - ptln('</div>'); + echo '</div>'; } /** @@ -1514,55 +1576,58 @@ function tpl_mediaTree() { * * Note: this will not use any pretty URLs * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $empty empty option label * @param string $button submit button label + * + * @author Andreas Gohr <andi@splitbrain.org> * @deprecated 2017-09-01 see devel:menus */ -function tpl_actiondropdown($empty = '', $button = '>') { +function tpl_actiondropdown($empty = '', $button = '>') +{ dbg_deprecated('see devel:menus'); - $menu = new \dokuwiki\Menu\MobileMenu(); + $menu = new MobileMenu(); echo $menu->getDropdown($empty, $button); } /** * Print a informational line about the used license * - * @author Andreas Gohr <andi@splitbrain.org> - * @param string $img print image? (|button|badge) - * @param bool $imgonly skip the textual description? - * @param bool $return when true don't print, but return HTML - * @param bool $wrap wrap in div with class="license"? + * @param string $img print image? (|button|badge) + * @param bool $imgonly skip the textual description? + * @param bool $return when true don't print, but return HTML + * @param bool $wrap wrap in div with class="license"? * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_license($img = 'badge', $imgonly = false, $return = false, $wrap = true) { +function tpl_license($img = 'badge', $imgonly = false, $return = false, $wrap = true) +{ global $license; global $conf; global $lang; - if(!$conf['license']) return ''; - if(!is_array($license[$conf['license']])) return ''; - $lic = $license[$conf['license']]; - $target = ($conf['target']['extern']) ? ' target="'.$conf['target']['extern'].'"' : ''; + if (!$conf['license']) return ''; + if (!is_array($license[$conf['license']])) return ''; + $lic = $license[$conf['license']]; + $target = ($conf['target']['extern']) ? ' target="' . $conf['target']['extern'] . '"' : ''; $out = ''; - if($wrap) $out .= '<div class="license">'; - if($img) { + if ($wrap) $out .= '<div class="license">'; + if ($img) { $src = license_img($img); - if($src) { - $out .= '<a href="'.$lic['url'].'" rel="license"'.$target; - $out .= '><img src="'.DOKU_BASE.$src.'" alt="'.$lic['name'].'" /></a>'; - if(!$imgonly) $out .= ' '; + if ($src) { + $out .= '<a href="' . $lic['url'] . '" rel="license"' . $target; + $out .= '><img src="' . DOKU_BASE . $src . '" alt="' . $lic['name'] . '" /></a>'; + if (!$imgonly) $out .= ' '; } } - if(!$imgonly) { - $out .= $lang['license'].' '; - $out .= '<bdi><a href="'.$lic['url'].'" rel="license" class="urlextern"'.$target; - $out .= '>'.$lic['name'].'</a></bdi>'; + if (!$imgonly) { + $out .= $lang['license'] . ' '; + $out .= '<bdi><a href="' . $lic['url'] . '" rel="license" class="urlextern"' . $target; + $out .= '>' . $lic['name'] . '</a></bdi>'; } - if($wrap) $out .= '</div>'; + if ($wrap) $out .= '</div>'; - if($return) return $out; + if ($return) return $out; echo $out; return ''; } @@ -1579,20 +1644,21 @@ function tpl_license($img = 'badge', $imgonly = false, $return = false, $wrap = * @param bool $useacl Include the page only if the ACLs check out? * @return bool|null|string */ -function tpl_include_page($pageid, $print = true, $propagate = false, $useacl = true) { - if($propagate) { +function tpl_include_page($pageid, $print = true, $propagate = false, $useacl = true) +{ + if ($propagate) { $pageid = page_findnearest($pageid, $useacl); - } elseif($useacl && auth_quickaclcheck($pageid) == AUTH_NONE) { + } elseif ($useacl && auth_quickaclcheck($pageid) == AUTH_NONE) { return false; } - if(!$pageid) return false; + if (!$pageid) return false; global $TOC; $oldtoc = $TOC; - $html = p_wiki_xhtml($pageid, '', false); - $TOC = $oldtoc; + $html = p_wiki_xhtml($pageid, '', false); + $TOC = $oldtoc; - if($print) echo $html; + if ($print) echo $html; return $html; } @@ -1602,9 +1668,10 @@ function tpl_include_page($pageid, $print = true, $propagate = false, $useacl = * @author Adrian Lang <lang@cosmocode.de> * @deprecated 2020-07-23 */ -function tpl_subscribe() { - dbg_deprecated(\dokuwiki\Ui\Subscribe::class .'::show()'); - (new \dokuwiki\Ui\Subscribe)->show(); +function tpl_subscribe() +{ + dbg_deprecated(Subscribe::class . '::show()'); + (new Subscribe())->show(); } /** @@ -1614,8 +1681,9 @@ function tpl_subscribe() { * * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_flush() { - if( ob_get_level() > 0 ) ob_flush(); +function tpl_flush() +{ + if (ob_get_level() > 0) ob_flush(); flush(); } @@ -1625,36 +1693,37 @@ function tpl_flush() { * If a given location starts with a colon it is assumed to be a media * file, otherwise it is assumed to be relative to the current template * - * @param string[] $search locations to look at - * @param bool $abs if to use absolute URL - * @param array &$imginfo filled with getimagesize() - * @param bool $fallback use fallback image if target isn't found or return 'false' if potential + * @param string[] $search locations to look at + * @param bool $abs if to use absolute URL + * @param array &$imginfo filled with getimagesize() + * @param bool $fallback use fallback image if target isn't found or return 'false' if potential * false result is required * @return string * * @author Andreas Gohr <andi@splitbrain.org> */ -function tpl_getMediaFile($search, $abs = false, &$imginfo = null, $fallback = true) { - $img = ''; - $file = ''; +function tpl_getMediaFile($search, $abs = false, &$imginfo = null, $fallback = true) +{ + $img = ''; + $file = ''; $ismedia = false; // loop through candidates until a match was found: - foreach($search as $img) { - if(substr($img, 0, 1) == ':') { - $file = mediaFN($img); + foreach ($search as $img) { + if (substr($img, 0, 1) == ':') { + $file = mediaFN($img); $ismedia = true; } else { - $file = tpl_incdir().$img; + $file = tpl_incdir() . $img; $ismedia = false; } - if(file_exists($file)) break; + if (file_exists($file)) break; } // manage non existing target if (!file_exists($file)) { // give result for fallback image - if ($fallback === true) { + if ($fallback) { $file = DOKU_INC . 'lib/images/blank.gif'; // stop process if false result is required (if $fallback is false) } else { @@ -1663,16 +1732,16 @@ function tpl_getMediaFile($search, $abs = false, &$imginfo = null, $fallback = t } // fetch image data if requested - if(!is_null($imginfo)) { + if (!is_null($imginfo)) { $imginfo = getimagesize($file); } // build URL - if($ismedia) { + if ($ismedia) { $url = ml($img, '', true, '', $abs); } else { - $url = tpl_basedir().$img; - if($abs) $url = DOKU_URL.substr($url, strlen(DOKU_REL)); + $url = tpl_basedir() . $img; + if ($abs) $url = DOKU_URL . substr($url, strlen(DOKU_REL)); } return $url; @@ -1691,18 +1760,19 @@ function tpl_getMediaFile($search, $abs = false, &$imginfo = null, $fallback = t * Note: no escaping or sanity checking is done here. Never pass user input * to this function! * - * @author Anika Henke <anika@selfthinker.org> - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file + * + * @author Andreas Gohr <andi@splitbrain.org> + * @author Anika Henke <anika@selfthinker.org> */ -function tpl_includeFile($file) { +function tpl_includeFile($file) +{ global $config_cascade; - foreach(array('protected', 'local', 'default') as $config_group) { - if(empty($config_cascade['main'][$config_group])) continue; - foreach($config_cascade['main'][$config_group] as $conf_file) { + foreach (['protected', 'local', 'default'] as $config_group) { + if (empty($config_cascade['main'][$config_group])) continue; + foreach ($config_cascade['main'][$config_group] as $conf_file) { $dir = dirname($conf_file); - if(file_exists("$dir/$file")) { + if (file_exists("$dir/$file")) { include("$dir/$file"); return; } @@ -1710,8 +1780,8 @@ function tpl_includeFile($file) { } // still here? try the template dir - $file = tpl_incdir().$file; - if(file_exists($file)) { + $file = tpl_incdir() . $file; + if (file_exists($file)) { include($file); } } @@ -1719,29 +1789,30 @@ function tpl_includeFile($file) { /** * Returns <link> tag for various icon types (favicon|mobile|generic) * - * @author Anika Henke <anika@selfthinker.org> - * - * @param array $types - list of icon types to display (favicon|mobile|generic) + * @param array $types - list of icon types to display (favicon|mobile|generic) * @return string + * + * @author Anika Henke <anika@selfthinker.org> */ -function tpl_favicon($types = array('favicon')) { +function tpl_favicon($types = ['favicon']) +{ $return = ''; - foreach($types as $type) { - switch($type) { + foreach ($types as $type) { + switch ($type) { case 'favicon': - $look = array(':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico'); - $return .= '<link rel="shortcut icon" href="'.tpl_getMediaFile($look).'" />'.NL; + $look = [':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico']; + $return .= '<link rel="shortcut icon" href="' . tpl_getMediaFile($look) . '" />' . NL; break; case 'mobile': - $look = array(':wiki:apple-touch-icon.png', ':apple-touch-icon.png', 'images/apple-touch-icon.png'); - $return .= '<link rel="apple-touch-icon" href="'.tpl_getMediaFile($look).'" />'.NL; + $look = [':wiki:apple-touch-icon.png', ':apple-touch-icon.png', 'images/apple-touch-icon.png']; + $return .= '<link rel="apple-touch-icon" href="' . tpl_getMediaFile($look) . '" />' . NL; break; case 'generic': // ideal world solution, which doesn't work in any browser yet - $look = array(':wiki:favicon.svg', ':favicon.svg', 'images/favicon.svg'); - $return .= '<link rel="icon" href="'.tpl_getMediaFile($look).'" type="image/svg+xml" />'.NL; + $look = [':wiki:favicon.svg', ':favicon.svg', 'images/favicon.svg']; + $return .= '<link rel="icon" href="' . tpl_getMediaFile($look) . '" type="image/svg+xml" />' . NL; break; } } @@ -1754,90 +1825,88 @@ function tpl_favicon($types = array('favicon')) { * * @author Kate Arzamastseva <pshns@ukr.net> */ -function tpl_media() { +function tpl_media() +{ global $NS, $IMG, $JUMPTO, $REV, $lang, $fullscreen, $INPUT; $fullscreen = true; - require_once DOKU_INC.'lib/exe/mediamanager.php'; + require_once DOKU_INC . 'lib/exe/mediamanager.php'; - $rev = ''; + $rev = ''; $image = cleanID($INPUT->str('image')); - if(isset($IMG)) $image = $IMG; - if(isset($JUMPTO)) $image = $JUMPTO; - if(isset($REV) && !$JUMPTO) $rev = $REV; + if (isset($IMG)) $image = $IMG; + if (isset($JUMPTO)) $image = $JUMPTO; + if (isset($REV) && !$JUMPTO) $rev = $REV; - echo '<div id="mediamanager__page">'.NL; - echo '<h1>'.$lang['btn_media'].'</h1>'.NL; + echo '<div id="mediamanager__page">' . NL; + echo '<h1>' . $lang['btn_media'] . '</h1>' . NL; html_msgarea(); - echo '<div class="panel namespaces">'.NL; - echo '<h2>'.$lang['namespaces'].'</h2>'.NL; + echo '<div class="panel namespaces">' . NL; + echo '<h2>' . $lang['namespaces'] . '</h2>' . NL; echo '<div class="panelHeader">'; echo $lang['media_namespaces']; - echo '</div>'.NL; + echo '</div>' . NL; - echo '<div class="panelContent" id="media__tree">'.NL; + echo '<div class="panelContent" id="media__tree">' . NL; media_nstree($NS); - echo '</div>'.NL; - echo '</div>'.NL; + echo '</div>' . NL; + echo '</div>' . NL; - echo '<div class="panel filelist">'.NL; + echo '<div class="panel filelist">' . NL; tpl_mediaFileList(); - echo '</div>'.NL; + echo '</div>' . NL; - echo '<div class="panel file">'.NL; - echo '<h2 class="a11y">'.$lang['media_file'].'</h2>'.NL; + echo '<div class="panel file">' . NL; + echo '<h2 class="a11y">' . $lang['media_file'] . '</h2>' . NL; tpl_mediaFileDetails($image, $rev); - echo '</div>'.NL; + echo '</div>' . NL; - echo '</div>'.NL; + echo '</div>' . NL; } /** * Return useful layout classes * - * @author Anika Henke <anika@selfthinker.org> - * * @return string + * + * @author Anika Henke <anika@selfthinker.org> */ -function tpl_classes() { +function tpl_classes() +{ global $ACT, $conf, $ID, $INFO; /** @var Input $INPUT */ global $INPUT; - $classes = array( + $classes = [ 'dokuwiki', - 'mode_'.$ACT, - 'tpl_'.$conf['template'], + 'mode_' . $ACT, + 'tpl_' . $conf['template'], $INPUT->server->bool('REMOTE_USER') ? 'loggedIn' : '', (isset($INFO['exists']) && $INFO['exists']) ? '' : 'notFound', - ($ID == $conf['start']) ? 'home' : '', - ); - return join(' ', $classes); + ($ID == $conf['start']) ? 'home' : '' + ]; + return implode(' ', $classes); } /** * Create event for tools menues * - * @author Anika Henke <anika@selfthinker.org> * @param string $toolsname name of menu * @param array $items * @param string $view e.g. 'main', 'detail', ... + * + * @author Anika Henke <anika@selfthinker.org> * @deprecated 2017-09-01 see devel:menus */ -function tpl_toolsevent($toolsname, $items, $view = 'main') { +function tpl_toolsevent($toolsname, $items, $view = 'main') +{ dbg_deprecated('see devel:menus'); - $data = array( - 'view' => $view, - 'items' => $items - ); + $data = ['view' => $view, 'items' => $items]; $hook = 'TEMPLATE_' . strtoupper($toolsname) . '_DISPLAY'; $evt = new Event($hook, $data); - if($evt->advise_before()) { - foreach($evt->data['items'] as $k => $html) echo $html; + if ($evt->advise_before()) { + foreach ($evt->data['items'] as $html) echo $html; } $evt->advise_after(); } - -//Setup VIM: ex: et ts=4 : - diff --git a/inc/toolbar.php b/inc/toolbar.php index d49a96ddc..16ba3f715 100644 --- a/inc/toolbar.php +++ b/inc/toolbar.php @@ -1,10 +1,13 @@ <?php + /** * Editing toolbar functions * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> - */use dokuwiki\Extension\Event; + */ + +use dokuwiki\Extension\Event; /** * Prepares and prints an JavaScript array with all toolbar buttons @@ -13,17 +16,17 @@ * @param string $varname Name of the JS variable to fill * @author Andreas Gohr <andi@splitbrain.org> */ -function toolbar_JSdefines($varname){ +function toolbar_JSdefines($varname) +{ global $lang; - $menu = array(); + $menu = []; $evt = new Event('TOOLBAR_DEFINE', $menu); - if ($evt->advise_before()){ - + if ($evt->advise_before()) { // build button array - $menu = array_merge($menu, array( - array( + $menu = array_merge($menu, [ + [ 'type' => 'format', 'title' => $lang['qb_bold'], 'icon' => 'bold.png', @@ -31,8 +34,8 @@ function toolbar_JSdefines($varname){ 'open' => '**', 'close' => '**', 'block' => false - ), - array( + ], + [ 'type' => 'format', 'title' => $lang['qb_italic'], 'icon' => 'italic.png', @@ -40,8 +43,8 @@ function toolbar_JSdefines($varname){ 'open' => '//', 'close' => '//', 'block' => false - ), - array( + ], + [ 'type' => 'format', 'title' => $lang['qb_underl'], 'icon' => 'underline.png', @@ -49,8 +52,8 @@ function toolbar_JSdefines($varname){ 'open' => '__', 'close' => '__', 'block' => false - ), - array( + ], + [ 'type' => 'format', 'title' => $lang['qb_code'], 'icon' => 'mono.png', @@ -58,8 +61,8 @@ function toolbar_JSdefines($varname){ 'open' => "''", 'close' => "''", 'block' => false - ), - array( + ], + [ 'type' => 'format', 'title' => $lang['qb_strike'], 'icon' => 'strike.png', @@ -67,9 +70,8 @@ function toolbar_JSdefines($varname){ 'open' => '<del>', 'close' => '</del>', 'block' => false - ), - - array( + ], + [ 'type' => 'autohead', 'title' => $lang['qb_hequal'], 'icon' => 'hequal.png', @@ -77,8 +79,8 @@ function toolbar_JSdefines($varname){ 'text' => $lang['qb_h'], 'mod' => 0, 'block' => true - ), - array( + ], + [ 'type' => 'autohead', 'title' => $lang['qb_hminus'], 'icon' => 'hminus.png', @@ -86,8 +88,8 @@ function toolbar_JSdefines($varname){ 'text' => $lang['qb_h'], 'mod' => 1, 'block' => true - ), - array( + ], + [ 'type' => 'autohead', 'title' => $lang['qb_hplus'], 'icon' => 'hplus.png', @@ -95,59 +97,57 @@ function toolbar_JSdefines($varname){ 'text' => $lang['qb_h'], 'mod' => -1, 'block' => true - ), - - array( + ], + [ 'type' => 'picker', 'title' => $lang['qb_hs'], 'icon' => 'h.png', 'class' => 'pk_hl', - 'list' => array( - array( - 'type' => 'format', - 'title' => $lang['qb_h1'], - 'icon' => 'h1.png', - 'key' => '1', - 'open' => '====== ', - 'close' => ' ======\n', - ), - array( - 'type' => 'format', - 'title' => $lang['qb_h2'], - 'icon' => 'h2.png', - 'key' => '2', - 'open' => '===== ', - 'close' => ' =====\n', - ), - array( - 'type' => 'format', - 'title' => $lang['qb_h3'], - 'icon' => 'h3.png', - 'key' => '3', - 'open' => '==== ', - 'close' => ' ====\n', - ), - array( - 'type' => 'format', - 'title' => $lang['qb_h4'], - 'icon' => 'h4.png', - 'key' => '4', - 'open' => '=== ', - 'close' => ' ===\n', - ), - array( - 'type' => 'format', - 'title' => $lang['qb_h5'], - 'icon' => 'h5.png', - 'key' => '5', - 'open' => '== ', - 'close' => ' ==\n', - ), - ), + 'list' => [ + [ + 'type' => 'format', + 'title' => $lang['qb_h1'], + 'icon' => 'h1.png', + 'key' => '1', + 'open' => '====== ', + 'close' => ' ======\n' + ], + [ + 'type' => 'format', + 'title' => $lang['qb_h2'], + 'icon' => 'h2.png', + 'key' => '2', + 'open' => '===== ', + 'close' => ' =====\n' + ], + [ + 'type' => 'format', + 'title' => $lang['qb_h3'], + 'icon' => 'h3.png', + 'key' => '3', + 'open' => '==== ', + 'close' => ' ====\n' + ], + [ + 'type' => 'format', + 'title' => $lang['qb_h4'], + 'icon' => 'h4.png', + 'key' => '4', + 'open' => '=== ', + 'close' => ' ===\n' + ], + [ + 'type' => 'format', + 'title' => $lang['qb_h5'], + 'icon' => 'h5.png', + 'key' => '5', + 'open' => '== ', + 'close' => ' ==\n' + ] + ], 'block' => true - ), - - array( + ], + [ 'type' => 'linkwiz', 'title' => $lang['qb_link'], 'icon' => 'link.png', @@ -155,17 +155,17 @@ function toolbar_JSdefines($varname){ 'open' => '[[', 'close' => ']]', 'block' => false - ), - array( + ], + [ 'type' => 'format', 'title' => $lang['qb_extlink'], 'icon' => 'linkextern.png', 'open' => '[[', 'close' => ']]', - 'sample' => 'http://example.com|'.$lang['qb_extlink'], + 'sample' => 'http://example.com|' . $lang['qb_extlink'], 'block' => false - ), - array( + ], + [ 'type' => 'formatln', 'title' => $lang['qb_ol'], 'icon' => 'ol.png', @@ -173,8 +173,8 @@ function toolbar_JSdefines($varname){ 'close' => '', 'key' => '-', 'block' => true - ), - array( + ], + [ 'type' => 'formatln', 'title' => $lang['qb_ul'], 'icon' => 'ul.png', @@ -182,32 +182,32 @@ function toolbar_JSdefines($varname){ 'close' => '', 'key' => '.', 'block' => true - ), - array( + ], + [ 'type' => 'insert', 'title' => $lang['qb_hr'], 'icon' => 'hr.png', 'insert' => '\n----\n', 'block' => true - ), - array( + ], + [ 'type' => 'mediapopup', 'title' => $lang['qb_media'], 'icon' => 'image.png', 'url' => 'lib/exe/mediamanager.php?ns=', 'name' => 'mediaselect', - 'options'=> 'width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes', + 'options' => 'width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes', 'block' => false - ), - array( + ], + [ 'type' => 'picker', 'title' => $lang['qb_smileys'], 'icon' => 'smiley.png', 'list' => getSmileys(), - 'icobase'=> 'smileys', + 'icobase' => 'smileys', 'block' => false - ), - array( + ], + [ 'type' => 'picker', 'title' => $lang['qb_chars'], 'icon' => 'chars.png', @@ -236,21 +236,21 @@ function toolbar_JSdefines($varname){ '″', '[', ']', '{', '}', '~', '(', ')', '%', '§', '$', '#', '|', '@' ], 'block' => false - ), - array( + ], + [ 'type' => 'signature', 'title' => $lang['qb_sig'], 'icon' => 'sig.png', 'key' => 'y', 'block' => false - ), - )); + ] + ]); } // end event TOOLBAR_DEFINE default action $evt->advise_after(); unset($evt); // use JSON to build the JavaScript array - print "var $varname = ".json_encode($menu).";\n"; + echo "var $varname = " . json_encode($menu, JSON_THROW_ON_ERROR) . ";\n"; } /** @@ -258,24 +258,25 @@ function toolbar_JSdefines($varname){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function toolbar_signature(){ +function toolbar_signature() +{ global $conf; global $INFO; /** @var Input $INPUT */ global $INPUT; $sig = $conf['signature']; - $sig = dformat(null,$sig); - $sig = str_replace('@USER@',$INPUT->server->str('REMOTE_USER'),$sig); + $sig = dformat(null, $sig); + $sig = str_replace('@USER@', $INPUT->server->str('REMOTE_USER'), $sig); if (is_null($INFO)) { $sig = str_replace(['@NAME@', '@MAIL@'], '', $sig); } else { $sig = str_replace('@NAME@', $INFO['userinfo']['name'] ?? "", $sig); $sig = str_replace('@MAIL@', $INFO['userinfo']['mail'] ?? "", $sig); } - $sig = str_replace('@DATE@',dformat(),$sig); - $sig = str_replace('\\\\n','\\n',$sig); - return json_encode($sig); + $sig = str_replace('@DATE@', dformat(), $sig); + $sig = str_replace('\\\\n', '\\n', $sig); + return json_encode($sig, JSON_THROW_ON_ERROR); } //Setup VIM: ex: et ts=4 : diff --git a/inc/utf8.php b/inc/utf8.php index 1227407bf..5ac3cd6a1 100644 --- a/inc/utf8.php +++ b/inc/utf8.php @@ -1,4 +1,5 @@ <?php + /** * UTF8 helper functions * @@ -1,4 +1,5 @@ <?php + /** * Forwarder/Router to doku.php * @@ -13,8 +14,9 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */ -if (php_sapi_name() != 'cli-server') { - if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/'); + +if (PHP_SAPI != 'cli-server') { + if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/'); require_once(DOKU_INC . 'inc/init.php'); send_redirect(wl($conf['start'])); @@ -30,18 +32,15 @@ if (preg_match('/^\/_media\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) { // media dispatcher $_GET['media'] = $m[1]; require $_SERVER['DOCUMENT_ROOT'] . '/lib/exe/fetch.php'; - } elseif (preg_match('/^\/_detail\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) { // image detail view $_GET['media'] = $m[1]; require $_SERVER['DOCUMENT_ROOT'] . '/lib/exe/detail.php'; - } elseif (preg_match('/^\/_export\/([^\/]+)\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) { // exports $_GET['do'] = 'export_' . $m[1]; $_GET['id'] = $m[2]; require $_SERVER['DOCUMENT_ROOT'] . '/doku.php'; - } elseif ( $_SERVER['SCRIPT_NAME'] !== '/index.php' && file_exists($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME']) @@ -49,7 +48,8 @@ if (preg_match('/^\/_media\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) { // existing files // access limitiations - if (preg_match('/\/([._]ht|README$|VERSION$|COPYING$)/', $_SERVER['SCRIPT_NAME']) or + if ( + preg_match('/\/([._]ht|README$|VERSION$|COPYING$)/', $_SERVER['SCRIPT_NAME']) || preg_match('/^\/(data|conf|bin|inc)\//', $_SERVER['SCRIPT_NAME']) ) { header('HTTP/1.1 403 Forbidden'); diff --git a/install.php b/install.php index bede24cc8..22f3769b1 100644 --- a/install.php +++ b/install.php @@ -9,13 +9,10 @@ provider if you're unsure what this means. </div>*/ -/** - * Dokuwiki installation assistance - * - * @author Chris Smith <chris@jalakai.co.uk> - */ -if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/'); +use dokuwiki\PassHash; + +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/'); if (!defined('DOKU_CONF')) define('DOKU_CONF', DOKU_INC . 'conf/'); if (!defined('DOKU_LOCAL')) define('DOKU_LOCAL', DOKU_INC . 'conf/'); @@ -41,63 +38,92 @@ if ($LC && $LC != 'en') { } // initialise variables ... -$error = array(); +$error = []; // begin output header('Content-Type: text/html; charset=utf-8'); ?> -<!DOCTYPE html> -<html lang="<?php echo $LC?>" dir="<?php echo $lang['direction']?>"> -<head> - <meta charset="utf-8" /> - <title><?php echo $lang['i_installer']?></title> - <style> - body { width: 90%; margin: 0 auto; font: 84% Verdana, Helvetica, Arial, sans-serif; } - img { border: none } - br.cl { clear:both; } - code { font-size: 110%; color: #800000; } - fieldset { border: none } - label { display: block; margin-top: 0.5em; } - select.text, input.text { width: 30em; margin: 0 0.5em; } - a {text-decoration: none} - </style> - <script> - function acltoggle(){ - var cb = document.getElementById('acl'); - var fs = document.getElementById('acldep'); - if(!cb || !fs) return; - if(cb.checked){ - fs.style.display = ''; - }else{ - fs.style.display = 'none'; + <!DOCTYPE html> + <html lang="<?php echo $LC ?>" dir="<?php echo $lang['direction'] ?>"> + <head> + <meta charset="utf-8"/> + <title><?php echo $lang['i_installer'] ?></title> + <style> + body { + width: 90%; + margin: 0 auto; + font: 84% Verdana, Helvetica, Arial, sans-serif; } - } - window.onload = function(){ - acltoggle(); - var cb = document.getElementById('acl'); - if(cb) cb.onchange = acltoggle; - }; - </script> -</head> -<body style=""> + + img { + border: none + } + + br.cl { + clear: both; + } + + code { + font-size: 110%; + color: #800000; + } + + fieldset { + border: none + } + + label { + display: block; + margin-top: 0.5em; + } + + select.text, input.text { + width: 30em; + margin: 0 0.5em; + } + + a { + text-decoration: none + } + </style> + <script> + function acltoggle() { + var cb = document.getElementById('acl'); + var fs = document.getElementById('acldep'); + if (!cb || !fs) return; + if (cb.checked) { + fs.style.display = ''; + } else { + fs.style.display = 'none'; + } + } + + window.onload = function () { + acltoggle(); + var cb = document.getElementById('acl'); + if (cb) cb.onchange = acltoggle; + }; + </script> + </head> + <body style=""> <h1 style="float:left"> <img src="lib/exe/fetch.php?media=wiki:dokuwiki-128.png" - style="vertical-align: middle;" alt="" height="64" width="64" /> - <?php echo $lang['i_installer']?> + style="vertical-align: middle;" alt="" height="64" width="64"/> + <?php echo $lang['i_installer'] ?> </h1> <div style="float:right; margin: 1em;"> - <?php langsel()?> + <?php langsel() ?> </div> - <br class="cl" /> + <br class="cl"/> <div style="float: right; width: 34%;"> <?php if (file_exists(DOKU_INC . 'inc/lang/' . $LC . '/install.html')) { include(DOKU_INC . 'inc/lang/' . $LC . '/install.html'); } else { - print "<div lang=\"en\" dir=\"ltr\">\n"; + echo "<div lang=\"en\" dir=\"ltr\">\n"; include(DOKU_INC . 'inc/lang/en/install.html'); - print "</div>\n"; + echo "</div>\n"; } ?> <a style=" @@ -106,13 +132,13 @@ header('Content-Type: text/html; charset=utf-8'); left top no-repeat; display: block; width:380px; height:73px; border:none; clear:both;" target="_blank" - href="http://www.dokuwiki.org/security#web_access_security"></a> + href="https://www.dokuwiki.org/security#web_access_security"></a> </div> <div style="float: left; width: 58%;"> <?php try { - if (! (check_functions() && check_permissions())) { + if (!(check_functions() && check_permissions())) { echo '<p>' . $lang['i_problems'] . '</p>'; print_errors(); print_retry(); @@ -132,18 +158,18 @@ header('Content-Type: text/html; charset=utf-8'); print_form($_REQUEST['d']); } } catch (Exception $e) { - echo 'Caught exception: ', $e->getMessage(), "\n"; + echo 'Caught exception: ', $e->getMessage(), "\n"; } ?> </div> -<div style="clear: both"> - <a href="http://dokuwiki.org/"><img src="lib/tpl/dokuwiki/images/button-dw.png" alt="driven by DokuWiki" /></a> - <a href="http://php.net"><img src="lib/tpl/dokuwiki/images/button-php.gif" alt="powered by PHP" /></a> -</div> -</body> -</html> + <div style="clear: both"> + <a href="https://dokuwiki.org/"><img src="lib/tpl/dokuwiki/images/button-dw.png" alt="driven by DokuWiki"/></a> + <a href="https://php.net"><img src="lib/tpl/dokuwiki/images/button-php.gif" alt="powered by PHP"/></a> + </div> + </body> + </html> <?php /** @@ -158,7 +184,7 @@ function print_form($d) include(DOKU_CONF . 'license.php'); - if (!is_array($d)) $d = array(); + if (!is_array($d)) $d = []; $d = array_map('hsc', $d); if (!isset($d['acl'])) $d['acl'] = 1; @@ -166,83 +192,84 @@ function print_form($d) ?> <form action="" method="post"> - <input type="hidden" name="l" value="<?php echo $LC ?>" /> - <fieldset> - <label for="title"><?php echo $lang['i_wikiname']?> - <input type="text" name="d[title]" id="title" value="<?php echo $d['title'] ?>" style="width: 20em;" /> - </label> - - <fieldset style="margin-top: 1em;"> - <label for="acl"> - <input type="checkbox" name="d[acl]" id="acl" <?php echo(($d['acl'] ? ' checked="checked"' : ''));?> /> - <?php echo $lang['i_enableacl']?></label> - - <fieldset id="acldep"> - <label for="superuser"><?php echo $lang['i_superuser']?></label> - <input class="text" type="text" name="d[superuser]" id="superuser" - value="<?php echo $d['superuser'] ?>" /> - - <label for="fullname"><?php echo $lang['fullname']?></label> - <input class="text" type="text" name="d[fullname]" id="fullname" - value="<?php echo $d['fullname'] ?>" /> - - <label for="email"><?php echo $lang['email']?></label> - <input class="text" type="text" name="d[email]" id="email" value="<?php echo $d['email'] ?>" /> - - <label for="password"><?php echo $lang['pass']?></label> - <input class="text" type="password" name="d[password]" id="password" /> - - <label for="confirm"><?php echo $lang['passchk']?></label> - <input class="text" type="password" name="d[confirm]" id="confirm" /> - - <label for="policy"><?php echo $lang['i_policy']?></label> - <select class="text" name="d[policy]" id="policy"> - <option value="0" <?php echo ($d['policy'] == 0) ? 'selected="selected"' : '' ?>><?php - echo $lang['i_pol0']?></option> - <option value="1" <?php echo ($d['policy'] == 1) ? 'selected="selected"' : '' ?>><?php - echo $lang['i_pol1']?></option> - <option value="2" <?php echo ($d['policy'] == 2) ? 'selected="selected"' : '' ?>><?php - echo $lang['i_pol2']?></option> - </select> - - <label for="allowreg"> - <input type="checkbox" name="d[allowreg]" id="allowreg" <?php - echo(($d['allowreg'] ? ' checked="checked"' : ''));?> /> - <?php echo $lang['i_allowreg']?> + <input type="hidden" name="l" value="<?php echo $LC ?>"/> + <fieldset> + <label for="title"><?php echo $lang['i_wikiname'] ?> + <input type="text" name="d[title]" id="title" value="<?php echo $d['title'] ?>" style="width: 20em;"/> + </label> + + <fieldset style="margin-top: 1em;"> + <label for="acl"> + <input type="checkbox" name="d[acl]" + id="acl" <?php echo(($d['acl'] ? ' checked="checked"' : '')); ?> /> + <?php echo $lang['i_enableacl'] ?></label> + + <fieldset id="acldep"> + <label for="superuser"><?php echo $lang['i_superuser'] ?></label> + <input class="text" type="text" name="d[superuser]" id="superuser" + value="<?php echo $d['superuser'] ?>"/> + + <label for="fullname"><?php echo $lang['fullname'] ?></label> + <input class="text" type="text" name="d[fullname]" id="fullname" + value="<?php echo $d['fullname'] ?>"/> + + <label for="email"><?php echo $lang['email'] ?></label> + <input class="text" type="text" name="d[email]" id="email" value="<?php echo $d['email'] ?>"/> + + <label for="password"><?php echo $lang['pass'] ?></label> + <input class="text" type="password" name="d[password]" id="password"/> + + <label for="confirm"><?php echo $lang['passchk'] ?></label> + <input class="text" type="password" name="d[confirm]" id="confirm"/> + + <label for="policy"><?php echo $lang['i_policy'] ?></label> + <select class="text" name="d[policy]" id="policy"> + <option value="0" <?php echo ($d['policy'] == 0) ? 'selected="selected"' : '' ?>><?php + echo $lang['i_pol0'] ?></option> + <option value="1" <?php echo ($d['policy'] == 1) ? 'selected="selected"' : '' ?>><?php + echo $lang['i_pol1'] ?></option> + <option value="2" <?php echo ($d['policy'] == 2) ? 'selected="selected"' : '' ?>><?php + echo $lang['i_pol2'] ?></option> + </select> + + <label for="allowreg"> + <input type="checkbox" name="d[allowreg]" id="allowreg" <?php + echo(($d['allowreg'] ? ' checked="checked"' : '')); ?> /> + <?php echo $lang['i_allowreg'] ?> + </label> + </fieldset> + </fieldset> + + <fieldset> + <p><?php echo $lang['i_license'] ?></p> + <?php + $license[] = ['name' => $lang['i_license_none'], 'url' => '']; + if (empty($d['license'])) $d['license'] = 'cc-by-sa'; + foreach ($license as $key => $lic) { + echo '<label for="lic_' . $key . '">'; + echo '<input type="radio" name="d[license]" value="' . hsc($key) . '" id="lic_' . $key . '"' . + (($d['license'] === $key) ? ' checked="checked"' : '') . '>'; + echo hsc($lic['name']); + if ($lic['url']) echo ' <a href="' . $lic['url'] . '" target="_blank"><sup>[?]</sup></a>'; + echo '</label>'; + } + ?> + </fieldset> + + <fieldset> + <p><?php echo $lang['i_pop_field'] ?></p> + <label for="pop"> + <input type="checkbox" name="d[pop]" id="pop" <?php + echo(($d['pop'] ? ' checked="checked"' : '')); ?> /> + <?php echo $lang['i_pop_label'] ?> + <a href="https://www.dokuwiki.org/popularity" target="_blank"><sup>[?]</sup></a> </label> </fieldset> - </fieldset> - <fieldset> - <p><?php echo $lang['i_license']?></p> - <?php - array_push($license, array('name' => $lang['i_license_none'], 'url' => '')); - if (empty($d['license'])) $d['license'] = 'cc-by-sa'; - foreach ($license as $key => $lic) { - echo '<label for="lic_' . $key . '">'; - echo '<input type="radio" name="d[license]" value="' . hsc($key) . '" id="lic_' . $key . '"' . - (($d['license'] === $key) ? ' checked="checked"' : '') . '>'; - echo hsc($lic['name']); - if ($lic['url']) echo ' <a href="' . $lic['url'] . '" target="_blank"><sup>[?]</sup></a>'; - echo '</label>'; - } - ?> </fieldset> - - <fieldset> - <p><?php echo $lang['i_pop_field']?></p> - <label for="pop"> - <input type="checkbox" name="d[pop]" id="pop" <?php - echo(($d['pop'] ? ' checked="checked"' : ''));?> /> - <?php echo $lang['i_pop_label']?> - <a href="http://www.dokuwiki.org/popularity" target="_blank"><sup>[?]</sup></a> - </label> + <fieldset id="process"> + <button type="submit" name="submit"><?php echo $lang['btn_save'] ?></button> </fieldset> - - </fieldset> - <fieldset id="process"> - <button type="submit" name="submit"><?php echo $lang['btn_save']?></button> - </fieldset> </form> <?php } @@ -253,10 +280,10 @@ function print_retry() global $LC; ?> <form action="" method="get"> - <fieldset> - <input type="hidden" name="l" value="<?php echo $LC ?>" /> - <button type="submit"><?php echo $lang['i_retry'];?></button> - </fieldset> + <fieldset> + <input type="hidden" name="l" value="<?php echo $LC ?>"/> + <button type="submit"><?php echo $lang['i_retry']; ?></button> + </fieldset> </form> <?php } @@ -264,29 +291,29 @@ function print_retry() /** * Check validity of data * - * @author Andreas Gohr - * * @param array $d * @return bool ok? + * @author Andreas Gohr + * */ function check_data(&$d) { - static $form_default = array( - 'title' => '', - 'acl' => '1', + static $form_default = [ + 'title' => '', + 'acl' => '1', 'superuser' => '', - 'fullname' => '', - 'email' => '', - 'password' => '', - 'confirm' => '', - 'policy' => '0', - 'allowreg' => '0', - 'license' => 'cc-by-sa' - ); + 'fullname' => '', + 'email' => '', + 'password' => '', + 'confirm' => '', + 'policy' => '0', + 'allowreg' => '0', + 'license' => 'cc-by-sa' + ]; global $lang; global $error; - if (!is_array($d)) $d = array(); + if (!is_array($d)) $d = []; foreach ($d as $k => $v) { if (is_array($v)) unset($d[$k]); @@ -304,27 +331,27 @@ function check_data(&$d) // check input if (empty($d['title'])) { $error[] = sprintf($lang['i_badval'], $lang['i_wikiname']); - $ok = false; + $ok = false; } if (isset($d['acl'])) { if (empty($d['superuser']) || ($d['superuser'] !== cleanID($d['superuser']))) { $error[] = sprintf($lang['i_badval'], $lang['i_superuser']); - $ok = false; + $ok = false; } if (empty($d['password'])) { $error[] = sprintf($lang['i_badval'], $lang['pass']); - $ok = false; + $ok = false; } elseif (!isset($d['confirm']) || $d['confirm'] != $d['password']) { $error[] = sprintf($lang['i_badval'], $lang['passchk']); - $ok = false; + $ok = false; } if (empty($d['fullname']) || strstr($d['fullname'], ':')) { $error[] = sprintf($lang['i_badval'], $lang['fullname']); - $ok = false; + $ok = false; } if (empty($d['email']) || strstr($d['email'], ':') || !strstr($d['email'], '@')) { $error[] = sprintf($lang['i_badval'], $lang['email']); - $ok = false; + $ok = false; } } else { // Since default = 1, browser won't send acl=0 when user untick acl @@ -338,19 +365,20 @@ function check_data(&$d) /** * Writes the data to the config files * - * @author Chris Smith <chris@jalakai.co.uk> - * * @param array $d * @return bool + * @throws Exception + * + * @author Chris Smith <chris@jalakai.co.uk> */ function store_data($d) { global $LC; $ok = true; - $d['policy'] = (int) $d['policy']; + $d['policy'] = (int)$d['policy']; // create local.php - $now = gmdate('r'); + $now = gmdate('r'); $output = <<<EOT <?php /** @@ -384,7 +412,7 @@ EOT; if ($d['acl']) { // hash the password - $phash = new \dokuwiki\PassHash(); + $phash = new PassHash(); $pass = $phash->hash_bcrypt($d['password']); // create users.auth.php @@ -403,7 +431,7 @@ EOT; EOT; // --- user:bcryptpasswordhash:Real Name:email:groups,comma,seperated - $output = $output . "\n" . join(':', [ + $output = $output . "\n" . implode(':', [ $d['superuser'], $pass, $d['fullname'], @@ -425,13 +453,13 @@ EOT; EOT; if ($d['policy'] == 2) { - $output .= "* @ALL 0\n"; - $output .= "* @user 8\n"; + $output .= "* @ALL 0\n"; + $output .= "* @user 8\n"; } elseif ($d['policy'] == 1) { - $output .= "* @ALL 1\n"; - $output .= "* @user 8\n"; + $output .= "* @ALL 1\n"; + $output .= "* @user 8\n"; } else { - $output .= "* @ALL 8\n"; + $output .= "* @ALL 8\n"; } $ok = $ok && fileWrite(DOKU_LOCAL . 'acl.auth.php', $output); } @@ -465,11 +493,11 @@ EOT; /** * Write the given content to a file * - * @author Chris Smith <chris@jalakai.co.uk> - * * @param string $filename * @param string $data * @return bool + * + * @author Chris Smith <chris@jalakai.co.uk> */ function fileWrite($filename, $data) { @@ -478,7 +506,7 @@ function fileWrite($filename, $data) if (($fp = @fopen($filename, 'wb')) === false) { $filename = str_replace($_SERVER['DOCUMENT_ROOT'], '{DOCUMENT_ROOT}/', $filename); - $error[] = sprintf($lang['i_writeerr'], $filename); + $error[] = sprintf($lang['i_writeerr'], $filename); return false; } @@ -494,9 +522,9 @@ function fileWrite($filename, $data) * check installation dependent local config files and tests for a known * unmodified main config file * - * @author Chris Smith <chris@jalakai.co.uk> - * * @return bool + * + * @author Chris Smith <chris@jalakai.co.uk> */ function check_configs() { @@ -505,18 +533,18 @@ function check_configs() $ok = true; - $config_files = array( + $config_files = [ 'local' => DOKU_LOCAL . 'local.php', 'users' => DOKU_LOCAL . 'users.auth.php', - 'auth' => DOKU_LOCAL . 'acl.auth.php' - ); + 'auth' => DOKU_LOCAL . 'acl.auth.php' + ]; // configs shouldn't exist foreach ($config_files as $file) { if (file_exists($file) && filesize($file)) { - $file = str_replace($_SERVER['DOCUMENT_ROOT'], '{DOCUMENT_ROOT}/', $file); + $file = str_replace($_SERVER['DOCUMENT_ROOT'], '{DOCUMENT_ROOT}/', $file); $error[] = sprintf($lang['i_confexists'], $file); - $ok = false; + $ok = false; } } return $ok; @@ -526,36 +554,36 @@ function check_configs() /** * Check other installation dir/file permission requirements * - * @author Chris Smith <chris@jalakai.co.uk> - * * @return bool + * + * @author Chris Smith <chris@jalakai.co.uk> */ function check_permissions() { global $error; global $lang; - $dirs = array( - 'conf' => DOKU_LOCAL, - 'data' => DOKU_INC . 'data', - 'pages' => DOKU_INC . 'data/pages', - 'attic' => DOKU_INC . 'data/attic', - 'media' => DOKU_INC . 'data/media', + $dirs = [ + 'conf' => DOKU_LOCAL, + 'data' => DOKU_INC . 'data', + 'pages' => DOKU_INC . 'data/pages', + 'attic' => DOKU_INC . 'data/attic', + 'media' => DOKU_INC . 'data/media', 'media_attic' => DOKU_INC . 'data/media_attic', - 'media_meta' => DOKU_INC . 'data/media_meta', - 'meta' => DOKU_INC . 'data/meta', - 'cache' => DOKU_INC . 'data/cache', - 'locks' => DOKU_INC . 'data/locks', - 'index' => DOKU_INC . 'data/index', - 'tmp' => DOKU_INC . 'data/tmp' - ); + 'media_meta' => DOKU_INC . 'data/media_meta', + 'meta' => DOKU_INC . 'data/meta', + 'cache' => DOKU_INC . 'data/cache', + 'locks' => DOKU_INC . 'data/locks', + 'index' => DOKU_INC . 'data/index', + 'tmp' => DOKU_INC . 'data/tmp' + ]; $ok = true; foreach ($dirs as $dir) { if (!file_exists("$dir/.") || !is_writable($dir)) { - $dir = str_replace($_SERVER['DOCUMENT_ROOT'], '{DOCUMENT_ROOT}', $dir); + $dir = str_replace($_SERVER['DOCUMENT_ROOT'], '{DOCUMENT_ROOT}', $dir); $error[] = sprintf($lang['i_permfail'], $dir); - $ok = false; + $ok = false; } } return $ok; @@ -564,9 +592,9 @@ function check_permissions() /** * Check the availability of functions used in DokuWiki and the PHP version * - * @author Andreas Gohr <andi@splitbrain.org> - * * @return bool + * + * @author Andreas Gohr <andi@splitbrain.org> */ function check_functions() { @@ -586,7 +614,7 @@ function check_functions() try { random_bytes(1); - } catch (\Exception $th) { + } catch (Exception $th) { // If an appropriate source of randomness cannot be found, an Exception will be thrown by PHP 7+ $error[] = $lang['i_urandom']; $ok = false; @@ -598,12 +626,12 @@ function check_functions() } $funcs = explode(' ', 'addslashes call_user_func chmod copy fgets ' . - 'file file_exists fseek flush filesize ftell fopen ' . - 'glob header ignore_user_abort ini_get mkdir ' . - 'ob_start opendir parse_ini_file readfile realpath ' . - 'rename rmdir serialize session_start unlink usleep ' . - 'preg_replace file_get_contents htmlspecialchars_decode ' . - 'spl_autoload_register stream_select fsockopen pack xml_parser_create'); + 'file file_exists fseek flush filesize ftell fopen ' . + 'glob header ignore_user_abort ini_get mkdir ' . + 'ob_start opendir parse_ini_file readfile realpath ' . + 'rename rmdir serialize session_start unlink usleep ' . + 'preg_replace file_get_contents htmlspecialchars_decode ' . + 'spl_autoload_register stream_select fsockopen pack xml_parser_create'); if (!function_exists('mb_substr')) { $funcs[] = 'utf8_encode'; @@ -639,12 +667,12 @@ function langsel() global $LC; $dir = DOKU_INC . 'inc/lang'; - $dh = opendir($dir); + $dh = opendir($dir); if (!$dh) return; - $langs = array(); + $langs = []; while (($file = readdir($dh)) !== false) { - if (preg_match('/^[\._]/', $file)) continue; + if (preg_match('/^[._]/', $file)) continue; if (is_dir($dir . '/' . $file) && file_exists($dir . '/' . $file . '/lang.php')) { $langs[] = $file; } diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php index 5f49e5135..719064175 100644 --- a/lib/exe/ajax.php +++ b/lib/exe/ajax.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki AJAX call handler * @@ -6,7 +7,10 @@ * @author Andreas Gohr <andi@splitbrain.org> */ -if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../'); +use dokuwiki\Utf8\Clean; +use dokuwiki\Ajax; + +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); require_once(DOKU_INC . 'inc/init.php'); //close session @@ -18,8 +22,8 @@ header('Content-Type: text/html; charset=utf-8'); //call the requested function global $INPUT; if ($INPUT->has('call')) { - $call = $INPUT->filter([\dokuwiki\Utf8\Clean::class, 'stripspecials'])->str('call'); - new \dokuwiki\Ajax($call); + $call = $INPUT->filter([Clean::class, 'stripspecials'])->str('call'); + new Ajax($call); } else { http_status(404); } diff --git a/lib/exe/css.php b/lib/exe/css.php index 05e55bb56..2df3e6286 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki StyleSheet creator * @@ -6,17 +7,18 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\StyleUtils; use dokuwiki\Cache\Cache; use dokuwiki\Extension\Event; -if(!defined('DOKU_INC')) define('DOKU_INC', __DIR__ .'/../../'); -if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) -if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here -if(!defined('NL')) define('NL',"\n"); -require_once(DOKU_INC.'inc/init.php'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +if (!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching) +if (!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); // we gzip ourself here +if (!defined('NL')) define('NL', "\n"); +require_once(DOKU_INC . 'inc/init.php'); // Main (don't run when UNIT test) -if(!defined('SIMPLE_TEST')){ +if (!defined('SIMPLE_TEST')) { header('Content-Type: text/css; charset=utf-8'); css_out(); } @@ -29,49 +31,54 @@ if(!defined('SIMPLE_TEST')){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function css_out(){ +function css_out() +{ global $conf; global $lang; global $config_cascade; global $INPUT; if ($INPUT->str('s') == 'feed') { - $mediatypes = array('feed'); + $mediatypes = ['feed']; $type = 'feed'; } else { - $mediatypes = array('screen', 'all', 'print', 'speech'); + $mediatypes = ['screen', 'all', 'print', 'speech']; $type = ''; } // decide from where to get the template - $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t'))); - if(!$tpl) $tpl = $conf['template']; + $tpl = trim(preg_replace('/[^\w-]+/', '', $INPUT->str('t'))); + if (!$tpl) { + $tpl = $conf['template']; + } // load style.ini - $styleUtil = new \dokuwiki\StyleUtils($tpl, $INPUT->bool('preview')); + $styleUtil = new StyleUtils($tpl, $INPUT->bool('preview')); $styleini = $styleUtil->cssStyleini(); // cache influencers $tplinc = tpl_incdir($tpl); $cache_files = getConfigFiles('main'); - $cache_files[] = $tplinc.'style.ini'; - $cache_files[] = DOKU_CONF."tpl/$tpl/style.ini"; + $cache_files[] = $tplinc . 'style.ini'; + $cache_files[] = DOKU_CONF . "tpl/$tpl/style.ini"; $cache_files[] = __FILE__; - if($INPUT->bool('preview')) $cache_files[] = $conf['cachedir'].'/preview.ini'; + if ($INPUT->bool('preview')) { + $cache_files[] = $conf['cachedir'] . '/preview.ini'; + } // Array of needed files and their web locations, the latter ones // are needed to fix relative paths in the stylesheets - $media_files = array(); - foreach($mediatypes as $mediatype) { - $files = array(); + $media_files = []; + foreach ($mediatypes as $mediatype) { + $files = []; // load core styles - $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/'; + $files[DOKU_INC . 'lib/styles/' . $mediatype . '.css'] = DOKU_BASE . 'lib/styles/'; // load jQuery-UI theme if ($mediatype == 'screen') { - $files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = - DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/'; + $files[DOKU_INC . 'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = + DOKU_BASE . 'lib/scripts/jquery/jquery-ui-theme/'; } // load plugin styles $files = array_merge($files, css_pluginstyles($mediatype)); @@ -80,8 +87,8 @@ function css_out(){ $files = array_merge($files, $styleini['stylesheets'][$mediatype]); } // load user styles - if(isset($config_cascade['userstyle'][$mediatype]) and is_array($config_cascade['userstyle'][$mediatype])) { - foreach($config_cascade['userstyle'][$mediatype] as $userstyle) { + if (isset($config_cascade['userstyle'][$mediatype]) && is_array($config_cascade['userstyle'][$mediatype])) { + foreach ($config_cascade['userstyle'][$mediatype] as $userstyle) { $files[$userstyle] = DOKU_BASE; } } @@ -91,7 +98,7 @@ function css_out(){ $CSSEvt = new Event('CSS_STYLES_INCLUDED', $media_files[$mediatype]); // Make it preventable. - if ( $CSSEvt->advise_before() ) { + if ($CSSEvt->advise_before()) { $cache_files = array_merge($cache_files, array_keys($media_files[$mediatype]['files'])); } else { // unset if prevented. Nothing will be printed for this mediatype. @@ -117,7 +124,7 @@ function css_out(){ // check cache age & handle conditional request // This may exit if a cache can be used - $cache_ok = $cache->useCache(array('files' => $cache_files)); + $cache_ok = $cache->useCache(['files' => $cache_files]); http_cached($cache->cache, $cache_ok); // start output buffering @@ -131,30 +138,34 @@ function css_out(){ // build the stylesheet foreach ($mediatypes as $mediatype) { - // Check if there is a wrapper set for this type. - if ( !isset($media_files[$mediatype]) ) { + if (!isset($media_files[$mediatype])) { continue; } $cssData = $media_files[$mediatype]; // Print the styles. - print NL; - if ( $cssData['encapsulate'] === true ) print $cssData['encapsulationPrefix'] . ' {'; - print '/* START '.$cssData['mediatype'].' styles */'.NL; + echo NL; + if ($cssData['encapsulate'] === true) { + echo $cssData['encapsulationPrefix'] . ' {'; + } + echo '/* START ' . $cssData['mediatype'] . ' styles */' . NL; // load files - foreach($cssData['files'] as $file => $location){ + foreach ($cssData['files'] as $file => $location) { $display = str_replace(fullpath(DOKU_INC), '', fullpath($file)); - print "\n/* XXXXXXXXX $display XXXXXXXXX */\n"; - print css_loadfile($file, $location); + echo "\n/* XXXXXXXXX $display XXXXXXXXX */\n"; + echo css_loadfile($file, $location); } - print NL; - if ( $cssData['encapsulate'] === true ) print '} /* /@media '; - else print '/*'; - print ' END '.$cssData['mediatype'].' styles */'.NL; + echo NL; + if ($cssData['encapsulate'] === true) { + echo '} /* /@media '; + } else { + echo '/*'; + } + echo ' END ' . $cssData['mediatype'] . ' styles */' . NL; } // end output buffering and get contents @@ -171,14 +182,14 @@ function css_out(){ $css = css_parseless($css); // compress whitespace and comments - if($conf['compress']){ + if ($conf['compress']) { $css = css_compress($css); } // embed small images right into the stylesheet - if($conf['cssdatauri']){ - $base = preg_quote(DOKU_BASE,'#'); - $css = preg_replace_callback('#(url\([ \'"]*)('.$base.')(.*?(?:\.(png|gif)))#i','css_datauri',$css); + if ($conf['cssdatauri']) { + $base = preg_quote(DOKU_BASE, '#'); + $css = preg_replace_callback('#(url\([ \'"]*)(' . $base . ')(.*?(?:\.(png|gif)))#i', 'css_datauri', $css); } http_cached_finish($cache->cache, $css); @@ -193,43 +204,44 @@ function css_out(){ * @param string $css * @return string */ -function css_parseless($css) { +function css_parseless($css) +{ global $conf; $less = new lessc(); - $less->importDir = array(DOKU_INC); + $less->importDir = [DOKU_INC]; $less->setPreserveComments(!$conf['compress']); - if (defined('DOKU_UNITTEST')){ + if (defined('DOKU_UNITTEST')) { $less->importDir[] = TMP_DIR; } try { return $less->compile($css); - } catch(Exception $e) { + } catch (Exception $e) { // get exception message - $msg = str_replace(array("\n", "\r", "'"), array(), $e->getMessage()); + $msg = str_replace(["\n", "\r", "'"], [], $e->getMessage()); // try to use line number to find affected file - if(preg_match('/line: (\d+)$/', $msg, $m)){ - $msg = substr($msg, 0, -1* strlen($m[0])); //remove useless linenumber + if (preg_match('/line: (\d+)$/', $msg, $m)) { + $msg = substr($msg, 0, -1 * strlen($m[0])); //remove useless linenumber $lno = $m[1]; // walk upwards to last include $lines = explode("\n", $css); - for($i=$lno-1; $i>=0; $i--){ - if(preg_match('/\/(\* XXXXXXXXX )(.*?)( XXXXXXXXX \*)\//', $lines[$i], $m)){ + for ($i = $lno - 1; $i >= 0; $i--) { + if (preg_match('/\/(\* XXXXXXXXX )(.*?)( XXXXXXXXX \*)\//', $lines[$i], $m)) { // we found it, add info to message - $msg .= ' in '.$m[2].' at line '.($lno-$i); + $msg .= ' in ' . $m[2] . ' at line ' . ($lno - $i); break; } } } // something went wrong - $error = 'A fatal error occured during compilation of the CSS files. '. - 'If you recently installed a new plugin or template it '. - 'might be broken and you should try disabling it again. ['.$msg.']'; + $error = 'A fatal error occured during compilation of the CSS files. ' . + 'If you recently installed a new plugin or template it ' . + 'might be broken and you should try disabling it again. [' . $msg . ']'; echo ".dokuwiki:before { content: '$error'; @@ -252,19 +264,20 @@ function css_parseless($css) { * This also adds the ini defined placeholders as less variables * (sans the surrounding __ and with a ini_ prefix) * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $css - * @param array $replacements array(placeholder => value) + * @param array $replacements array(placeholder => value) * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function css_applystyle($css, $replacements) { +function css_applystyle($css, $replacements) +{ // we convert ini replacements to LESS variable names // and build a list of variable: value; pairs $less = ''; - foreach((array) $replacements as $key => $value) { + foreach ((array)$replacements as $key => $value) { $lkey = trim($key, '_'); - $lkey = '@ini_'.$lkey; + $lkey = '@ini_' . $lkey; $less .= "$lkey: $value;\n"; $replacements[$key] = $lkey; @@ -274,43 +287,45 @@ function css_applystyle($css, $replacements) { $css = strtr($css, $replacements); // now prepend the list of LESS variables as the very first thing - $css = $less.$css; + $css = $less . $css; return $css; } /** * Wrapper for the files, content and mediatype for the event CSS_STYLES_INCLUDED * - * @author Gerry Weißbach <gerry.w@gammaproduction.de> - * * @param string $mediatype type ofthe current media files/content set * @param array $files set of files that define the current mediatype * @return array + * + * @author Gerry Weißbach <gerry.w@gammaproduction.de> */ -function css_filewrapper($mediatype, $files=array()){ - return array( - 'files' => $files, - 'mediatype' => $mediatype, - 'encapsulate' => $mediatype != 'all', - 'encapsulationPrefix' => '@media '.$mediatype - ); +function css_filewrapper($mediatype, $files = []) +{ + return [ + 'files' => $files, + 'mediatype' => $mediatype, + 'encapsulate' => $mediatype != 'all', + 'encapsulationPrefix' => '@media ' . $mediatype + ]; } /** * Prints the @media encapsulated default styles of DokuWiki * - * @author Gerry Weißbach <gerry.w@gammaproduction.de> - * * This function is being called by a CSS_STYLES_INCLUDED event * The event can be distinguished by the mediatype which is: * DW_DEFAULT + * + * @author Gerry Weißbach <gerry.w@gammaproduction.de> */ -function css_defaultstyles(){ +function css_defaultstyles() +{ // print the default classes for interwiki links and file downloads - print '@media screen {'; + echo '@media screen {'; css_interwiki(); css_filetypes(); - print '}'; + echo '}'; } /** @@ -324,11 +339,12 @@ function css_defaultstyles(){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function css_interwiki(){ +function css_interwiki() +{ // default style echo 'a.interwiki {'; - echo ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.svg) 0 0 no-repeat;'; + echo ' background: transparent url(' . DOKU_BASE . 'lib/images/interwiki.svg) 0 0 no-repeat;'; echo ' background-size: 1.2em;'; echo ' padding: 0 0 0 1.4em;'; echo '}'; @@ -355,30 +371,31 @@ function css_interwiki(){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function css_filetypes(){ +function css_filetypes() +{ // default style echo '.mediafile {'; - echo ' background: transparent url('.DOKU_BASE.'lib/images/fileicons/svg/file.svg) 0px 1px no-repeat;'; + echo ' background: transparent url(' . DOKU_BASE . 'lib/images/fileicons/svg/file.svg) 0px 1px no-repeat;'; echo ' background-size: 1.2em;'; echo ' padding-left: 1.5em;'; echo '}'; // additional styles when icon available // scan directory for all icons - $exts = array(); - if($dh = opendir(DOKU_INC.'lib/images/fileicons/svg')){ - while(false !== ($file = readdir($dh))){ - if(preg_match('/(.*?)\.svg$/i',$file, $match)){ + $exts = []; + if ($dh = opendir(DOKU_INC . 'lib/images/fileicons/svg')) { + while (false !== ($file = readdir($dh))) { + if (preg_match('/(.*?)\.svg$/i', $file, $match)) { $exts[] = strtolower($match[1]); } } closedir($dh); } - foreach($exts as $ext){ - $class = preg_replace('/[^_\-a-z0-9]+/','_',$ext); + foreach ($exts as $ext) { + $class = preg_replace('/[^_\-a-z0-9]+/', '_', $ext); echo ".mf_$class {"; - echo ' background-image: url('.DOKU_BASE.'lib/images/fileicons/svg/'.$ext.'.svg)'; + echo ' background-image: url(' . DOKU_BASE . 'lib/images/fileicons/svg/' . $ext . '.svg)'; echo '}'; } } @@ -391,23 +408,25 @@ function css_filetypes(){ * @param string $location * @return string */ -function css_loadfile($file,$location=''){ +function css_loadfile($file, $location = '') +{ $css_file = new DokuCssFile($file); return $css_file->load($location); } /** - * Helper class to abstract loading of css/less files + * Helper class to abstract loading of css/less files * - * @author Chris Smith <chris@jalakai.co.uk> + * @author Chris Smith <chris@jalakai.co.uk> */ -class DokuCssFile { - +class DokuCssFile +{ protected $filepath; // file system path to the CSS/Less file protected $location; // base url location of the CSS/Less file - protected $relative_path = null; + protected $relative_path; - public function __construct($file) { + public function __construct($file) + { $this->filepath = $file; } @@ -416,10 +435,11 @@ class DokuCssFile { * relative to the dokuwiki root: the web root (DOKU_BASE) for most files; the file system root (DOKU_INC) * for less files. * - * @param string $location base url for this file - * @return string the CSS/Less contents of the file + * @param string $location base url for this file + * @return string the CSS/Less contents of the file */ - public function load($location='') { + public function load($location = '') + { if (!file_exists($this->filepath)) return ''; $css = io_readFile($this->filepath); @@ -427,8 +447,8 @@ class DokuCssFile { $this->location = $location; - $css = preg_replace_callback('#(url\( *)([\'"]?)(.*?)(\2)( *\))#',array($this,'replacements'),$css); - $css = preg_replace_callback('#(@import\s+)([\'"])(.*?)(\2)#',array($this,'replacements'),$css); + $css = preg_replace_callback('#(url\( *)([\'"]?)(.*?)(\2)( *\))#', [$this, 'replacements'], $css); + $css = preg_replace_callback('#(@import\s+)([\'"])(.*?)(\2)#', [$this, 'replacements'], $css); return $css; } @@ -438,10 +458,11 @@ class DokuCssFile { * * @return string relative file system path */ - protected function getRelativePath(){ + protected function getRelativePath() + { if (is_null($this->relative_path)) { - $basedir = array(DOKU_INC); + $basedir = [DOKU_INC]; // during testing, files may be found relative to a second base dir, TMP_DIR if (defined('DOKU_UNITTEST')) { @@ -449,7 +470,7 @@ class DokuCssFile { } $basedir = array_map('preg_quote_cb', $basedir); - $regex = '/^('.join('|',$basedir).')/'; + $regex = '/^(' . implode('|', $basedir) . ')/'; $this->relative_path = preg_replace($regex, '', dirname($this->filepath)); } @@ -460,10 +481,11 @@ class DokuCssFile { * preg_replace callback to adjust relative urls from relative to this file to relative * to the appropriate dokuwiki root location as described in the code * - * @param array see http://php.net/preg_replace_callback + * @param array $match see http://php.net/preg_replace_callback * @return string see http://php.net/preg_replace_callback */ - public function replacements($match) { + public function replacements($match) + { if (preg_match('#^(/|data:|https?://)#', $match[3])) { // not a relative url? - no adjustment required return $match[0]; @@ -475,7 +497,7 @@ class DokuCssFile { $match[3] = $this->location . $match[3]; } - return join('',array_slice($match,1)); + return implode('', array_slice($match, 1)); } } @@ -487,46 +509,48 @@ class DokuCssFile { * @param array $match * @return string */ -function css_datauri($match){ +function css_datauri($match) +{ global $conf; - $pre = unslash($match[1]); - $base = unslash($match[2]); - $url = unslash($match[3]); - $ext = unslash($match[4]); + $pre = unslash($match[1]); + $base = unslash($match[2]); + $url = unslash($match[3]); + $ext = unslash($match[4]); - $local = DOKU_INC.$url; - $size = @filesize($local); - if($size && $size < $conf['cssdatauri']){ + $local = DOKU_INC . $url; + $size = @filesize($local); + if ($size && $size < $conf['cssdatauri']) { $data = base64_encode(file_get_contents($local)); } - if (!empty($data)){ - $url = 'data:image/'.$ext.';base64,'.$data; - }else{ - $url = $base.$url; + if (!empty($data)) { + $url = 'data:image/' . $ext . ';base64,' . $data; + } else { + $url = $base . $url; } - return $pre.$url; + return $pre . $url; } /** * Returns a list of possible Plugin Styles (no existance check here) * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $mediatype * @return array + * @author Andreas Gohr <andi@splitbrain.org> + * */ -function css_pluginstyles($mediatype='screen'){ - $list = array(); +function css_pluginstyles($mediatype = 'screen') +{ + $list = []; $plugins = plugin_list(); - foreach ($plugins as $p){ - $list[DOKU_PLUGIN."$p/$mediatype.css"] = DOKU_BASE."lib/plugins/$p/"; - $list[DOKU_PLUGIN."$p/$mediatype.less"] = DOKU_BASE."lib/plugins/$p/"; + foreach ($plugins as $p) { + $list[DOKU_PLUGIN . "$p/$mediatype.css"] = DOKU_BASE . "lib/plugins/$p/"; + $list[DOKU_PLUGIN . "$p/$mediatype.less"] = DOKU_BASE . "lib/plugins/$p/"; // alternative for screen.css - if ($mediatype=='screen') { - $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/"; - $list[DOKU_PLUGIN."$p/style.less"] = DOKU_BASE."lib/plugins/$p/"; + if ($mediatype == 'screen') { + $list[DOKU_PLUGIN . "$p/style.css"] = DOKU_BASE . "lib/plugins/$p/"; + $list[DOKU_PLUGIN . "$p/style.less"] = DOKU_BASE . "lib/plugins/$p/"; } } return $list; @@ -535,32 +559,33 @@ function css_pluginstyles($mediatype='screen'){ /** * Very simple CSS optimizer * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $css * @return string + * @author Andreas Gohr <andi@splitbrain.org> + * */ -function css_compress($css){ +function css_compress($css) +{ // replace quoted strings with placeholder $quote_storage = []; $quote_cb = function ($match) use (&$quote_storage) { $quote_storage[] = $match[0]; - return '"STR'.(count($quote_storage)-1).'"'; + return '"STR' . (count($quote_storage) - 1) . '"'; }; $css = preg_replace_callback('/(([\'"]).*?(?<!\\\\)\2)/', $quote_cb, $css); // strip comments through a callback - $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s','css_comment_cb',$css); + $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s', 'css_comment_cb', $css); // strip (incorrect but common) one line comments - $css = preg_replace_callback('/^.*\/\/.*$/m','css_onelinecomment_cb',$css); + $css = preg_replace_callback('/^.*\/\/.*$/m', 'css_onelinecomment_cb', $css); // strip whitespaces - $css = preg_replace('![\r\n\t ]+!',' ',$css); - $css = preg_replace('/ ?([;,{}\/]) ?/','\\1',$css); - $css = preg_replace('/ ?: /',':',$css); + $css = preg_replace('![\r\n\t ]+!', ' ', $css); + $css = preg_replace('/ ?([;,{}\/]) ?/', '\\1', $css); + $css = preg_replace('/ ?: /', ':', $css); // number compression $css = preg_replace( @@ -624,13 +649,15 @@ function css_compress($css){ * * Keeps short comments (< 5 chars) to maintain typical browser hacks * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param array $matches * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> + * */ -function css_comment_cb($matches){ - if(strlen($matches[2]) > 4) return ''; +function css_comment_cb($matches) +{ + if (strlen($matches[2]) > 4) return ''; return $matches[0]; } @@ -642,23 +669,24 @@ function css_comment_cb($matches){ * @param array $matches * @return string */ -function css_onelinecomment_cb($matches) { +function css_onelinecomment_cb($matches) +{ $line = $matches[0]; $i = 0; $len = strlen($line); - while ($i< $len){ + while ($i < $len) { $nextcom = strpos($line, '//', $i); $nexturl = stripos($line, 'url(', $i); - if($nextcom === false) { + if ($nextcom === false) { // no more comments, we're done $i = $len; break; } - if($nexturl === false || $nextcom < $nexturl) { + if ($nexturl === false || $nextcom < $nexturl) { // no url anymore, strip comment and be done $i = $nextcom; break; diff --git a/lib/exe/detail.php b/lib/exe/detail.php index 4df11fed6..96dcf9323 100644 --- a/lib/exe/detail.php +++ b/lib/exe/detail.php @@ -2,23 +2,23 @@ use dokuwiki\Extension\Event; -if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); -if(!defined('DOKU_MEDIADETAIL')) define('DOKU_MEDIADETAIL',1); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +if (!defined('DOKU_MEDIADETAIL')) define('DOKU_MEDIADETAIL', 1); // define all DokuWiki globals here (needed within test requests but also helps to keep track) global $INPUT, $IMG, $ID, $REV, $SRC, $ERROR, $AUTH; -require_once(DOKU_INC.'inc/init.php'); +require_once(DOKU_INC . 'inc/init.php'); -$IMG = getID('media'); -$ID = cleanID($INPUT->str('id')); -$REV = $INPUT->int('rev'); +$IMG = getID('media'); +$ID = cleanID($INPUT->str('id')); +$REV = $INPUT->int('rev'); // this makes some general info available as well as the info about the // "parent" page -$INFO = array_merge(pageinfo(),mediainfo()); +$INFO = array_merge(pageinfo(), mediainfo()); -$tmp = array(); +$tmp = []; Event::createAndTrigger('DETAIL_STARTED', $tmp); //close session @@ -27,15 +27,15 @@ session_write_close(); $ERROR = false; // check image permissions $AUTH = auth_quickaclcheck($IMG); -if($AUTH >= AUTH_READ){ +if ($AUTH >= AUTH_READ) { // check if image exists - $SRC = mediaFN($IMG,$REV); - if(!file_exists($SRC)){ + $SRC = mediaFN($IMG, $REV); + if (!file_exists($SRC)) { //doesn't exist! http_status(404); $ERROR = 'File not found'; } -}else{ +} else { // no auth $ERROR = p_locale_xhtml('denied'); } @@ -44,4 +44,3 @@ if($AUTH >= AUTH_READ){ header('Content-Type: text/html; charset=utf-8'); include(template('detail.php')); tpl_img_close(); - diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php index 1b987ec10..845edc69e 100644 --- a/lib/exe/fetch.php +++ b/lib/exe/fetch.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki media passthrough file * @@ -6,122 +7,121 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Input\Input; use dokuwiki\Extension\Event; -if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/../../'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); if (!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); -require_once(DOKU_INC.'inc/init.php'); +require_once(DOKU_INC . 'inc/init.php'); session_write_close(); //close session -require_once(DOKU_INC.'inc/fetch.functions.php'); +require_once(DOKU_INC . 'inc/fetch.functions.php'); if (defined('SIMPLE_TEST')) { - $INPUT = new \dokuwiki\Input\Input(); + $INPUT = new Input(); } // BEGIN main - $mimetypes = getMimeTypes(); +$mimetypes = getMimeTypes(); - //get input - $MEDIA = stripctl(getID('media', false)); // no cleaning except control chars - maybe external - $CACHE = calc_cache($INPUT->str('cache')); - $WIDTH = $INPUT->int('w'); - $HEIGHT = $INPUT->int('h'); - $REV = & $INPUT->ref('rev'); - //sanitize revision - $REV = preg_replace('/[^0-9]/', '', $REV); +//get input +$MEDIA = stripctl(getID('media', false)); // no cleaning except control chars - maybe external +$CACHE = calc_cache($INPUT->str('cache')); +$WIDTH = $INPUT->int('w'); +$HEIGHT = $INPUT->int('h'); +$REV = &$INPUT->ref('rev'); +//sanitize revision +$REV = preg_replace('/[^0-9]/', '', $REV); - list($EXT, $MIME, $DL) = mimetype($MEDIA, false); - if($EXT === false) { - $EXT = 'unknown'; - $MIME = 'application/octet-stream'; - $DL = true; - } +[$EXT, $MIME, $DL] = mimetype($MEDIA, false); +if ($EXT === false) { + $EXT = 'unknown'; + $MIME = 'application/octet-stream'; + $DL = true; +} - // check for permissions, preconditions and cache external files - list($STATUS, $STATUSMESSAGE) = checkFileStatus($MEDIA, $FILE, $REV, $WIDTH, $HEIGHT); +// check for permissions, preconditions and cache external files +[$STATUS, $STATUSMESSAGE] = checkFileStatus($MEDIA, $FILE, $REV, $WIDTH, $HEIGHT); - // prepare data for plugin events - $data = array( - 'media' => $MEDIA, - 'file' => $FILE, - 'orig' => $FILE, - 'mime' => $MIME, - 'download' => $DL, - 'cache' => $CACHE, - 'ext' => $EXT, - 'width' => $WIDTH, - 'height' => $HEIGHT, - 'status' => $STATUS, - 'statusmessage' => $STATUSMESSAGE, - 'ispublic' => media_ispublic($MEDIA), - 'csp' => [ - 'default-src' => "'none'", - 'style-src' => "'unsafe-inline'", - 'media-src' => "'self'", - 'object-src' => "'self'", - 'font-src' => "'self' data:", - 'form-action' => "'none'", - 'frame-ancestors' => "'self'", - ], - ); +// prepare data for plugin events +$data = [ + 'media' => $MEDIA, + 'file' => $FILE, + 'orig' => $FILE, + 'mime' => $MIME, + 'download' => $DL, + 'cache' => $CACHE, + 'ext' => $EXT, + 'width' => $WIDTH, + 'height' => $HEIGHT, + 'status' => $STATUS, + 'statusmessage' => $STATUSMESSAGE, + 'ispublic' => media_ispublic($MEDIA), + 'csp' => [ + 'default-src' => "'none'", + 'style-src' => "'unsafe-inline'", + 'media-src' => "'self'", + 'object-src' => "'self'", + 'font-src' => "'self' data:", + 'form-action' => "'none'", + 'frame-ancestors' => "'self'", + ] +]; - // handle the file status - $evt = new Event('FETCH_MEDIA_STATUS', $data); - if($evt->advise_before()) { - // redirects - if($data['status'] > 300 && $data['status'] <= 304) { - if (defined('SIMPLE_TEST')) return; //TestResponse doesn't recognize redirects - send_redirect($data['statusmessage']); - } - // send any non 200 status - if($data['status'] != 200) { - http_status($data['status'], $data['statusmessage']); - } - // die on errors - if($data['status'] > 203) { - print $data['statusmessage']; - if (defined('SIMPLE_TEST')) return; - exit; - } +// handle the file status +$evt = new Event('FETCH_MEDIA_STATUS', $data); +if ($evt->advise_before()) { + // redirects + if ($data['status'] > 300 && $data['status'] <= 304) { + if (defined('SIMPLE_TEST')) return; //TestResponse doesn't recognize redirects + send_redirect($data['statusmessage']); + } + // send any non 200 status + if ($data['status'] != 200) { + http_status($data['status'], $data['statusmessage']); } - $evt->advise_after(); - unset($evt); + // die on errors + if ($data['status'] > 203) { + echo $data['statusmessage']; + if (defined('SIMPLE_TEST')) return; + exit; + } +} +$evt->advise_after(); +unset($evt); - //handle image resizing/cropping - $evt = new Event('MEDIA_RESIZE', $data); - if($evt->advise_before()) { - if( - $MIME != 'image/svg+xml' && - (substr($MIME, 0, 5) == 'image') && - ($WIDTH || $HEIGHT) - ) { - if($HEIGHT && $WIDTH) { - $data['file'] = $FILE = media_crop_image($data['file'], $EXT, $WIDTH, $HEIGHT); - } else { - $data['file'] = $FILE = media_resize_image($data['file'], $EXT, $WIDTH, $HEIGHT); - } +//handle image resizing/cropping +$evt = new Event('MEDIA_RESIZE', $data); +if ($evt->advise_before()) { + if ( + $MIME != 'image/svg+xml' && + (substr($MIME, 0, 5) == 'image') && + ($WIDTH || $HEIGHT) + ) { + if ($HEIGHT && $WIDTH) { + $data['file'] = $FILE = media_crop_image($data['file'], $EXT, $WIDTH, $HEIGHT); + } else { + $data['file'] = $FILE = media_resize_image($data['file'], $EXT, $WIDTH, $HEIGHT); } } - $evt->advise_after(); - unset($evt); +} +$evt->advise_after(); +unset($evt); - // finally send the file to the client - $evt = new Event('MEDIA_SENDFILE', $data); - if($evt->advise_before()) { - sendFile( - $data['file'], - $data['mime'], - $data['download'], - $data['cache'], - $data['ispublic'], - $data['orig'], - $data['csp'] - ); - } - // Do something after the download finished. - $evt->advise_after(); // will not be emitted on 304 or x-sendfile +// finally send the file to the client +$evt = new Event('MEDIA_SENDFILE', $data); +if ($evt->advise_before()) { + sendFile( + $data['file'], + $data['mime'], + $data['download'], + $data['cache'], + $data['ispublic'], + $data['orig'], + $data['csp'] + ); +} +// Do something after the download finished. +$evt->advise_after(); // will not be emitted on 304 or x-sendfile // END DO main - -//Setup VIM: ex: et ts=2 : diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php index c5f6e4081..944c31dcf 100644 --- a/lib/exe/indexer.php +++ b/lib/exe/indexer.php @@ -1,5 +1,7 @@ <?php + /** * @deprecated 2020-06-04 use taskrunner instead */ + include __DIR__ . '/taskrunner.php'; diff --git a/lib/exe/jquery.php b/lib/exe/jquery.php index b8638ecc0..7b0fceb72 100644 --- a/lib/exe/jquery.php +++ b/lib/exe/jquery.php @@ -2,10 +2,10 @@ use dokuwiki\Cache\Cache; -if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../'); -if(!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching) -if(!defined('NL')) define('NL', "\n"); -if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); // we gzip ourself here +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +if (!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching) +if (!defined('NL')) define('NL', "\n"); +if (!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); // we gzip ourself here require_once(DOKU_INC . 'inc/init.php'); // MAIN @@ -20,23 +20,24 @@ jquery_out(); * * uses cache or fills it */ -function jquery_out() { +function jquery_out() +{ $cache = new Cache('jquery', '.js'); - $files = array( + $files = [ DOKU_INC . 'lib/scripts/jquery/jquery.min.js', - DOKU_INC . 'lib/scripts/jquery/jquery-ui.min.js', - ); + DOKU_INC . 'lib/scripts/jquery/jquery-ui.min.js' + ]; $cache_files = $files; $cache_files[] = __FILE__; // check cache age & handle conditional request // This may exit if a cache can be used - $cache_ok = $cache->useCache(array('files' => $cache_files)); + $cache_ok = $cache->useCache(['files' => $cache_files]); http_cached($cache->cache, $cache_ok); $js = ''; - foreach($files as $file) { - $js .= file_get_contents($file)."\n"; + foreach ($files as $file) { + $js .= file_get_contents($file) . "\n"; } stripsourcemaps($js); diff --git a/lib/exe/js.php b/lib/exe/js.php index 1d87fb6e5..36e1814f6 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki JavaScript creator * @@ -6,19 +7,20 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Utf8\PhpString; use dokuwiki\Cache\Cache; use dokuwiki\Extension\Event; use splitbrain\JSStrip\Exception as JSStripException; use splitbrain\JSStrip\JSStrip; -if(!defined('DOKU_INC')) define('DOKU_INC', __DIR__ .'/../../'); -if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) -if(!defined('NL')) define('NL',"\n"); -if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here -require_once(DOKU_INC.'inc/init.php'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +if (!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching) +if (!defined('NL')) define('NL', "\n"); +if (!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); // we gzip ourself here +require_once(DOKU_INC . 'inc/init.php'); // Main (don't run when UNIT test) -if(!defined('SIMPLE_TEST')){ +if (!defined('SIMPLE_TEST')) { header('Content-Type: application/javascript; charset=utf-8'); js_out(); } @@ -31,48 +33,49 @@ if(!defined('SIMPLE_TEST')){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function js_out(){ +function js_out() +{ global $conf; global $lang; global $config_cascade; global $INPUT; // decide from where to get the template - $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t'))); - if(!$tpl) $tpl = $conf['template']; + $tpl = trim(preg_replace('/[^\w-]+/', '', $INPUT->str('t'))); + if (!$tpl) $tpl = $conf['template']; // array of core files - $files = array( - DOKU_INC.'lib/scripts/jquery/jquery.cookie.js', - DOKU_INC.'inc/lang/'.$conf['lang'].'/jquery.ui.datepicker.js', - DOKU_INC."lib/scripts/fileuploader.js", - DOKU_INC."lib/scripts/fileuploaderextended.js", - DOKU_INC.'lib/scripts/helpers.js', - DOKU_INC.'lib/scripts/delay.js', - DOKU_INC.'lib/scripts/cookie.js', - DOKU_INC.'lib/scripts/script.js', - DOKU_INC.'lib/scripts/qsearch.js', - DOKU_INC.'lib/scripts/search.js', - DOKU_INC.'lib/scripts/tree.js', - DOKU_INC.'lib/scripts/index.js', - DOKU_INC.'lib/scripts/textselection.js', - DOKU_INC.'lib/scripts/toolbar.js', - DOKU_INC.'lib/scripts/edit.js', - DOKU_INC.'lib/scripts/editor.js', - DOKU_INC.'lib/scripts/locktimer.js', - DOKU_INC.'lib/scripts/linkwiz.js', - DOKU_INC.'lib/scripts/media.js', - DOKU_INC.'lib/scripts/compatibility.js', -# disabled for FS#1958 DOKU_INC.'lib/scripts/hotkeys.js', - DOKU_INC.'lib/scripts/behaviour.js', - DOKU_INC.'lib/scripts/page.js', - tpl_incdir($tpl).'script.js', - ); + $files = [ + DOKU_INC . 'lib/scripts/jquery/jquery.cookie.js', + DOKU_INC . 'inc/lang/' . $conf['lang'] . '/jquery.ui.datepicker.js', + DOKU_INC . "lib/scripts/fileuploader.js", + DOKU_INC . "lib/scripts/fileuploaderextended.js", + DOKU_INC . 'lib/scripts/helpers.js', + DOKU_INC . 'lib/scripts/delay.js', + DOKU_INC . 'lib/scripts/cookie.js', + DOKU_INC . 'lib/scripts/script.js', + DOKU_INC . 'lib/scripts/qsearch.js', + DOKU_INC . 'lib/scripts/search.js', + DOKU_INC . 'lib/scripts/tree.js', + DOKU_INC . 'lib/scripts/index.js', + DOKU_INC . 'lib/scripts/textselection.js', + DOKU_INC . 'lib/scripts/toolbar.js', + DOKU_INC . 'lib/scripts/edit.js', + DOKU_INC . 'lib/scripts/editor.js', + DOKU_INC . 'lib/scripts/locktimer.js', + DOKU_INC . 'lib/scripts/linkwiz.js', + DOKU_INC . 'lib/scripts/media.js', + DOKU_INC . 'lib/scripts/compatibility.js', + # disabled for FS#1958 DOKU_INC.'lib/scripts/hotkeys.js', + DOKU_INC . 'lib/scripts/behaviour.js', + DOKU_INC . 'lib/scripts/page.js', + tpl_incdir($tpl) . 'script.js', + ]; // add possible plugin scripts and userscript - $files = array_merge($files,js_pluginscripts()); - if(is_array($config_cascade['userscript']['default'])) { - foreach($config_cascade['userscript']['default'] as $userscript) { + $files = array_merge($files, js_pluginscripts()); + if (is_array($config_cascade['userscript']['default'])) { + foreach ($config_cascade['userscript']['default'] as $userscript) { $files[] = $userscript; } } @@ -81,7 +84,7 @@ function js_out(){ Event::createAndTrigger('JS_SCRIPT_LIST', $files); // The generated script depends on some dynamic options - $cache = new Cache('scripts'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].md5(serialize($files)),'.js'); + $cache = new Cache('scripts' . $_SERVER['HTTP_HOST'] . $_SERVER['SERVER_PORT'] . md5(serialize($files)), '.js'); $cache->setEvent('JS_CACHE_USE'); $cache_files = array_merge($files, getConfigFiles('main')); @@ -89,60 +92,59 @@ function js_out(){ // check cache age & handle conditional request // This may exit if a cache can be used - $cache_ok = $cache->useCache(array('files' => $cache_files)); + $cache_ok = $cache->useCache(['files' => $cache_files]); http_cached($cache->cache, $cache_ok); // start output buffering and build the script ob_start(); // add some global variables - print "var DOKU_BASE = '".DOKU_BASE."';"; - print "var DOKU_TPL = '".tpl_basedir($tpl)."';"; - print "var DOKU_COOKIE_PARAM = " . json_encode( - array( - 'path' => empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'], - 'secure' => $conf['securecookie'] && is_ssl() - )).";"; + echo "var DOKU_BASE = '" . DOKU_BASE . "';"; + echo "var DOKU_TPL = '" . tpl_basedir($tpl) . "';"; + echo "var DOKU_COOKIE_PARAM = " . json_encode([ + 'path' => empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'], + 'secure' => $conf['securecookie'] && is_ssl() + ], JSON_THROW_ON_ERROR) . ";"; // FIXME: Move those to JSINFO - print "Object.defineProperty(window, 'DOKU_UHN', { get: function() {". - "console.warn('Using DOKU_UHN is deprecated. Please use JSINFO.useHeadingNavigation instead');". - "return JSINFO.useHeadingNavigation; } });"; - print "Object.defineProperty(window, 'DOKU_UHC', { get: function() {". - "console.warn('Using DOKU_UHC is deprecated. Please use JSINFO.useHeadingContent instead');". - "return JSINFO.useHeadingContent; } });"; + echo "Object.defineProperty(window, 'DOKU_UHN', { get: function() {" . + "console.warn('Using DOKU_UHN is deprecated. Please use JSINFO.useHeadingNavigation instead');" . + "return JSINFO.useHeadingNavigation; } });"; + echo "Object.defineProperty(window, 'DOKU_UHC', { get: function() {" . + "console.warn('Using DOKU_UHC is deprecated. Please use JSINFO.useHeadingContent instead');" . + "return JSINFO.useHeadingContent; } });"; // load JS specific translations $lang['js']['plugins'] = js_pluginstrings(); $templatestrings = js_templatestrings($tpl); - if(!empty($templatestrings)) { + if (!empty($templatestrings)) { $lang['js']['template'] = $templatestrings; } - echo 'LANG = '.json_encode($lang['js']).";\n"; + echo 'LANG = ' . json_encode($lang['js'], JSON_THROW_ON_ERROR) . ";\n"; // load toolbar toolbar_JSdefines('toolbar'); // load files - foreach($files as $file){ - if(!file_exists($file)) continue; - $ismin = (substr($file,-7) == '.min.js'); - $debugjs = ($conf['allowdebug'] && strpos($file, DOKU_INC.'lib/scripts/') !== 0); + foreach ($files as $file) { + if (!file_exists($file)) continue; + $ismin = (substr($file, -7) == '.min.js'); + $debugjs = ($conf['allowdebug'] && strpos($file, DOKU_INC . 'lib/scripts/') !== 0); - echo "\n\n/* XXXXXXXXXX begin of ".str_replace(DOKU_INC, '', $file) ." XXXXXXXXXX */\n\n"; - if($ismin) echo "\n/* BEGIN NOCOMPRESS */\n"; + echo "\n\n/* XXXXXXXXXX begin of " . str_replace(DOKU_INC, '', $file) . " XXXXXXXXXX */\n\n"; + if ($ismin) echo "\n/* BEGIN NOCOMPRESS */\n"; if ($debugjs) echo "\ntry {\n"; js_load($file); - if ($debugjs) echo "\n} catch (e) {\n logError(e, '".str_replace(DOKU_INC, '', $file)."');\n}\n"; - if($ismin) echo "\n/* END NOCOMPRESS */\n"; + if ($debugjs) echo "\n} catch (e) {\n logError(e, '" . str_replace(DOKU_INC, '', $file) . "');\n}\n"; + if ($ismin) echo "\n/* END NOCOMPRESS */\n"; echo "\n\n/* XXXXXXXXXX end of " . str_replace(DOKU_INC, '', $file) . " XXXXXXXXXX */\n\n"; } // init stuff - if($conf['locktime'] != 0){ - js_runonstart("dw_locktimer.init(".($conf['locktime'] - 60).",".$conf['usedraft'].")"); + if ($conf['locktime'] != 0) { + js_runonstart("dw_locktimer.init(" . ($conf['locktime'] - 60) . "," . $conf['usedraft'] . ")"); } // init hotkeys - must have been done after init of toolbar -# disabled for FS#1958 js_runonstart('initializeHotkeys()'); + # disabled for FS#1958 js_runonstart('initializeHotkeys()'); // end output buffering and get contents $js = ob_get_contents(); @@ -152,11 +154,11 @@ function js_out(){ stripsourcemaps($js); // compress whitespace and comments - if($conf['compress']){ + if ($conf['compress']) { try { $js = (new JSStrip())->compress($js); } catch (JSStripException $e) { - $js .= "\nconsole.error(".json_encode($e->getMessage()).");\n"; + $js .= "\nconsole.error(" . json_encode($e->getMessage(), JSON_THROW_ON_ERROR) . ");\n"; } } @@ -168,38 +170,39 @@ function js_out(){ /** * Load the given file, handle include calls and print it * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $file filename path to file + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function js_load($file){ - if(!file_exists($file)) return; - static $loaded = array(); +function js_load($file) +{ + if (!file_exists($file)) return; + static $loaded = []; $data = io_readFile($file); - while(preg_match('#/\*\s*DOKUWIKI:include(_once)?\s+([\w\.\-_/]+)\s*\*/#',$data,$match)){ + while (preg_match('#/\*\s*DOKUWIKI:include(_once)?\s+([\w\.\-_/]+)\s*\*/#', $data, $match)) { $ifile = $match[2]; // is it a include_once? - if($match[1]){ - $base = \dokuwiki\Utf8\PhpString::basename($ifile); - if(array_key_exists($base, $loaded) && $loaded[$base] === true){ - $data = str_replace($match[0], '' ,$data); + if ($match[1]) { + $base = PhpString::basename($ifile); + if (array_key_exists($base, $loaded) && $loaded[$base] === true) { + $data = str_replace($match[0], '', $data); continue; } $loaded[$base] = true; } - if($ifile[0] != '/') $ifile = dirname($file).'/'.$ifile; + if ($ifile[0] != '/') $ifile = dirname($file) . '/' . $ifile; $idata = ''; if (file_exists($ifile)) { - $ismin = (substr($ifile, -7) == '.min.js');; + $ismin = (substr($ifile, -7) == '.min.js'); if ($ismin) $idata .= "\n/* BEGIN NOCOMPRESS */\n"; $idata .= io_readFile($ifile); if ($ismin) $idata .= "\n/* END NOCOMPRESS */\n"; } - $data = str_replace($match[0],$idata,$data); + $data = str_replace($match[0], $idata, $data); } echo "$data\n"; } @@ -207,15 +210,16 @@ function js_load($file){ /** * Returns a list of possible Plugin Scripts (no existance check here) * - * @author Andreas Gohr <andi@splitbrain.org> - * * @return array + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function js_pluginscripts(){ - $list = array(); +function js_pluginscripts() +{ + $list = []; $plugins = plugin_list(); - foreach ($plugins as $p){ - $list[] = DOKU_PLUGIN."$p/script.js"; + foreach ($plugins as $p) { + $list[] = DOKU_PLUGIN . "$p/script.js"; } return $list; } @@ -226,38 +230,39 @@ function js_pluginscripts(){ * - $lang['js'] must be an array. * - Nothing is returned for plugins without an entry for $lang['js'] * + * @return array * @author Gabriel Birke <birke@d-scribe.de> * - * @return array */ -function js_pluginstrings() { +function js_pluginstrings() +{ global $conf, $config_cascade; - $pluginstrings = array(); + $pluginstrings = []; $plugins = plugin_list(); - foreach($plugins as $p) { + foreach ($plugins as $p) { $path = DOKU_PLUGIN . $p . '/lang/'; - if(isset($lang)) unset($lang); - if(file_exists($path . "en/lang.php")) { + if (isset($lang)) unset($lang); + if (file_exists($path . "en/lang.php")) { include $path . "en/lang.php"; } - foreach($config_cascade['lang']['plugin'] as $config_file) { - if(file_exists($config_file . $p . '/en/lang.php')) { + foreach ($config_cascade['lang']['plugin'] as $config_file) { + if (file_exists($config_file . $p . '/en/lang.php')) { include($config_file . $p . '/en/lang.php'); } } - if(isset($conf['lang']) && $conf['lang'] != 'en') { - if(file_exists($path . $conf['lang'] . "/lang.php")) { + if (isset($conf['lang']) && $conf['lang'] != 'en') { + if (file_exists($path . $conf['lang'] . "/lang.php")) { include($path . $conf['lang'] . '/lang.php'); } - foreach($config_cascade['lang']['plugin'] as $config_file) { - if(file_exists($config_file . $p . '/' . $conf['lang'] . '/lang.php')) { + foreach ($config_cascade['lang']['plugin'] as $config_file) { + if (file_exists($config_file . $p . '/' . $conf['lang'] . '/lang.php')) { include($config_file . $p . '/' . $conf['lang'] . '/lang.php'); } } } - if(isset($lang['js'])) { + if (isset($lang['js'])) { $pluginstrings[$p] = $lang['js']; } } @@ -273,35 +278,36 @@ function js_pluginstrings() { * @param string $tpl * @return array */ -function js_templatestrings($tpl) { +function js_templatestrings($tpl) +{ global $conf, $config_cascade; $path = tpl_incdir() . 'lang/'; - $templatestrings = array(); - if(file_exists($path . "en/lang.php")) { + $templatestrings = []; + if (file_exists($path . "en/lang.php")) { include $path . "en/lang.php"; } - foreach($config_cascade['lang']['template'] as $config_file) { - if(file_exists($config_file . $conf['template'] . '/en/lang.php')) { + foreach ($config_cascade['lang']['template'] as $config_file) { + if (file_exists($config_file . $conf['template'] . '/en/lang.php')) { include($config_file . $conf['template'] . '/en/lang.php'); } } - if(isset($conf['lang']) && $conf['lang'] != 'en' && file_exists($path . $conf['lang'] . "/lang.php")) { + if (isset($conf['lang']) && $conf['lang'] != 'en' && file_exists($path . $conf['lang'] . "/lang.php")) { include $path . $conf['lang'] . "/lang.php"; } - if(isset($conf['lang']) && $conf['lang'] != 'en') { - if(file_exists($path . $conf['lang'] . "/lang.php")) { + if (isset($conf['lang']) && $conf['lang'] != 'en') { + if (file_exists($path . $conf['lang'] . "/lang.php")) { include $path . $conf['lang'] . "/lang.php"; } - foreach($config_cascade['lang']['template'] as $config_file) { - if(file_exists($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php')) { + foreach ($config_cascade['lang']['template'] as $config_file) { + if (file_exists($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php')) { include($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php'); } } } - if(isset($lang['js'])) { + if (isset($lang['js'])) { $templatestrings[$tpl] = $lang['js']; } return $templatestrings; @@ -311,22 +317,24 @@ function js_templatestrings($tpl) { * Escapes a String to be embedded in a JavaScript call, keeps \n * as newline * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $string * @return string + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function js_escape($string){ - return str_replace('\\\\n','\\n',addslashes($string)); +function js_escape($string) +{ + return str_replace('\\\\n', '\\n', addslashes($string)); } /** * Adds the given JavaScript code to the window.onload() event * - * @author Andreas Gohr <andi@splitbrain.org> - * * @param string $func + * + * @author Andreas Gohr <andi@splitbrain.org> */ -function js_runonstart($func){ - echo "jQuery(function(){ $func; });".NL; +function js_runonstart($func) +{ + echo "jQuery(function(){ $func; });" . NL; } diff --git a/lib/exe/manifest.php b/lib/exe/manifest.php index 687c1937c..b3ccfb7e8 100644 --- a/lib/exe/manifest.php +++ b/lib/exe/manifest.php @@ -1,9 +1,11 @@ <?php +use dokuwiki\Manifest; + if (!defined('DOKU_INC')) { define('DOKU_INC', __DIR__ . '/../../'); } -if(!defined('NOSESSION')) define('NOSESSION',true); // no session or auth required here +if (!defined('NOSESSION')) define('NOSESSION', true); // no session or auth required here require_once(DOKU_INC . 'inc/init.php'); if (!actionOK('manifest')) { @@ -11,5 +13,5 @@ if (!actionOK('manifest')) { exit(); } -$manifest = new \dokuwiki\Manifest(); +$manifest = new Manifest(); $manifest->sendManifest(); diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php index 3d8f865b0..54c6b81c1 100644 --- a/lib/exe/mediamanager.php +++ b/lib/exe/mediamanager.php @@ -2,130 +2,130 @@ use dokuwiki\Extension\Event; - if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); - define('DOKU_MEDIAMANAGER',1); - - // for multi uploader: - @ini_set('session.use_only_cookies',0); - - require_once(DOKU_INC.'inc/init.php'); - - global $INPUT; - global $lang; - global $conf; - // handle passed message - if($INPUT->str('msg1')) msg(hsc($INPUT->str('msg1')),1); - if($INPUT->str('err')) msg(hsc($INPUT->str('err')),-1); - - global $DEL; - // get namespace to display (either direct or from deletion order) - if($INPUT->str('delete')){ - $DEL = cleanID($INPUT->str('delete')); - $IMG = $DEL; - $NS = getNS($DEL); - }elseif($INPUT->str('edit')){ - $IMG = cleanID($INPUT->str('edit')); - $NS = getNS($IMG); - }elseif($INPUT->str('img')){ - $IMG = cleanID($INPUT->str('img')); - $NS = getNS($IMG); - }else{ - $NS = cleanID($INPUT->str('ns')); - $IMG = null; +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +define('DOKU_MEDIAMANAGER', 1); + +// for multi uploader: +@ini_set('session.use_only_cookies', 0); + +require_once(DOKU_INC . 'inc/init.php'); + +global $INPUT; +global $lang; +global $conf; +// handle passed message +if ($INPUT->str('msg1')) msg(hsc($INPUT->str('msg1')), 1); +if ($INPUT->str('err')) msg(hsc($INPUT->str('err')), -1); + +global $DEL; +// get namespace to display (either direct or from deletion order) +if ($INPUT->str('delete')) { + $DEL = cleanID($INPUT->str('delete')); + $IMG = $DEL; + $NS = getNS($DEL); +} elseif ($INPUT->str('edit')) { + $IMG = cleanID($INPUT->str('edit')); + $NS = getNS($IMG); +} elseif ($INPUT->str('img')) { + $IMG = cleanID($INPUT->str('img')); + $NS = getNS($IMG); +} else { + $NS = cleanID($INPUT->str('ns')); + $IMG = null; +} + +global $INFO, $JSINFO; +$INFO = empty($INFO) ? mediainfo() : array_merge($INFO, mediainfo()); +$JSINFO['id'] = ''; +$JSINFO['namespace'] = ''; +$AUTH = $INFO['perm']; // shortcut for historical reasons + +// If this page is directly opened it means we are in popup mode not fullscreen +// $fullscreen isn't defined by default it might lead to some PHP warnings +$fullscreen ??= false; + +$tmp = []; +Event::createAndTrigger('MEDIAMANAGER_STARTED', $tmp); +session_write_close(); //close session + +// do not display the manager if user does not have read access +if ($AUTH < AUTH_READ && !$fullscreen) { + http_status(403); + die($lang['accessdenied']); +} + +// handle flash upload +if (isset($_FILES['Filedata'])) { + $_FILES['upload'] =& $_FILES['Filedata']; + $JUMPTO = media_upload($NS, $AUTH); + if ($JUMPTO == false) { + http_status(400); + echo 'Upload failed'; } - - global $INFO, $JSINFO; - $INFO = !empty($INFO) ? array_merge($INFO, mediainfo()) : mediainfo(); - $JSINFO['id'] = ''; - $JSINFO['namespace'] = ''; - $AUTH = $INFO['perm']; // shortcut for historical reasons - - // If this page is directly opened it means we are in popup mode not fullscreen - // $fullscreen isn't defined by default it might lead to some PHP warnings - $fullscreen = isset($fullscreen) ? $fullscreen : false; - - $tmp = array(); - Event::createAndTrigger('MEDIAMANAGER_STARTED', $tmp); - session_write_close(); //close session - - // do not display the manager if user does not have read access - if($AUTH < AUTH_READ && !$fullscreen) { - http_status(403); - die($lang['accessdenied']); - } - - // handle flash upload - if(isset($_FILES['Filedata'])){ - $_FILES['upload'] =& $_FILES['Filedata']; - $JUMPTO = media_upload($NS,$AUTH); - if($JUMPTO == false){ - http_status(400); - echo 'Upload failed'; - } - echo 'ok'; - exit; - } - - // give info on PHP caught upload errors - if(!empty($_FILES['upload']['error'])){ - switch($_FILES['upload']['error']){ - case 1: - case 2: - msg(sprintf($lang['uploadsize'], - filesize_h(php_to_byte(ini_get('upload_max_filesize')))),-1); - break; - default: - msg($lang['uploadfail'].' ('.$_FILES['upload']['error'].')',-1); - } - unset($_FILES['upload']); - } - - // handle upload - if(!empty($_FILES['upload']['tmp_name'])){ - $JUMPTO = media_upload($NS,$AUTH); - if($JUMPTO) $NS = getNS($JUMPTO); - } - - // handle meta saving - if($IMG && @array_key_exists('save', $INPUT->arr('do'))){ - $JUMPTO = media_metasave($IMG,$AUTH,$INPUT->arr('meta')); + echo 'ok'; + exit; +} + +// give info on PHP caught upload errors +if (!empty($_FILES['upload']['error'])) { + switch ($_FILES['upload']['error']) { + case 1: + case 2: + msg(sprintf( + $lang['uploadsize'], + filesize_h(php_to_byte(ini_get('upload_max_filesize'))) + ), -1); + break; + default: + msg($lang['uploadfail'] . ' (' . $_FILES['upload']['error'] . ')', -1); } - - if($IMG && ($INPUT->str('mediado') == 'save' || @array_key_exists('save', $INPUT->arr('mediado')))) { - $JUMPTO = media_metasave($IMG,$AUTH,$INPUT->arr('meta')); + unset($_FILES['upload']); +} + +// handle upload +if (!empty($_FILES['upload']['tmp_name'])) { + $JUMPTO = media_upload($NS, $AUTH); + if ($JUMPTO) $NS = getNS($JUMPTO); +} + +// handle meta saving +if ($IMG && @array_key_exists('save', $INPUT->arr('do'))) { + $JUMPTO = media_metasave($IMG, $AUTH, $INPUT->arr('meta')); +} + +if ($IMG && ($INPUT->str('mediado') == 'save' || @array_key_exists('save', $INPUT->arr('mediado')))) { + $JUMPTO = media_metasave($IMG, $AUTH, $INPUT->arr('meta')); +} + +if ($INPUT->int('rev') && $conf['mediarevisions']) $REV = $INPUT->int('rev'); + +if ($INPUT->str('mediado') == 'restore' && $conf['mediarevisions']) { + $JUMPTO = media_restore($INPUT->str('image'), $REV, $AUTH); +} + +// handle deletion +if ($DEL) { + $res = 0; + if (checkSecurityToken()) { + $res = media_delete($DEL, $AUTH); } - - if ($INPUT->int('rev') && $conf['mediarevisions']) $REV = $INPUT->int('rev'); - - if($INPUT->str('mediado') == 'restore' && $conf['mediarevisions']){ - $JUMPTO = media_restore($INPUT->str('image'), $REV, $AUTH); - } - - // handle deletion - if($DEL) { - $res = 0; - if(checkSecurityToken()) { - $res = media_delete($DEL,$AUTH); - } - if ($res & DOKU_MEDIA_DELETED) { - $msg = sprintf($lang['deletesucc'], noNS($DEL)); - if ($res & DOKU_MEDIA_EMPTY_NS && !$fullscreen) { - // current namespace was removed. redirecting to root ns passing msg along - send_redirect(DOKU_URL.'lib/exe/mediamanager.php?msg1='. - rawurlencode($msg).'&edid='.$INPUT->str('edid')); - } - msg($msg,1); - } elseif ($res & DOKU_MEDIA_INUSE) { - msg(sprintf($lang['mediainuse'],noNS($DEL)),0); - } else { - msg(sprintf($lang['deletefail'],noNS($DEL)),-1); + if ($res & DOKU_MEDIA_DELETED) { + $msg = sprintf($lang['deletesucc'], noNS($DEL)); + if ($res & DOKU_MEDIA_EMPTY_NS && !$fullscreen) { + // current namespace was removed. redirecting to root ns passing msg along + send_redirect(DOKU_URL . 'lib/exe/mediamanager.php?msg1=' . + rawurlencode($msg) . '&edid=' . $INPUT->str('edid')); } + msg($msg, 1); + } elseif ($res & DOKU_MEDIA_INUSE) { + msg(sprintf($lang['mediainuse'], noNS($DEL)), 0); + } else { + msg(sprintf($lang['deletefail'], noNS($DEL)), -1); } - // finished - start output - - if (!$fullscreen) { - header('Content-Type: text/html; charset=utf-8'); - include(template('mediamanager.php')); - } +} +// finished - start output -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ +if (!$fullscreen) { + header('Content-Type: text/html; charset=utf-8'); + include(template('mediamanager.php')); +} diff --git a/lib/exe/opensearch.php b/lib/exe/opensearch.php index b00b2b771..766bdb2e6 100644 --- a/lib/exe/opensearch.php +++ b/lib/exe/opensearch.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki OpenSearch creator * @@ -8,31 +9,29 @@ * @author Andreas Gohr <andi@splitbrain.org> */ -if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); -if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) -if(!defined('NL')) define('NL',"\n"); -require_once(DOKU_INC.'inc/init.php'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +if (!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching) +if (!defined('NL')) define('NL', "\n"); +require_once(DOKU_INC . 'inc/init.php'); // try to be clever about the favicon location -if(file_exists(DOKU_INC.'favicon.ico')){ - $ico = DOKU_URL.'favicon.ico'; -}elseif(file_exists(tpl_incdir().'images/favicon.ico')){ - $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/images/favicon.ico'; -}elseif(file_exists(tpl_incdir().'favicon.ico')){ - $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/favicon.ico'; -}else{ - $ico = DOKU_URL.'lib/tpl/dokuwiki/images/favicon.ico'; +if (file_exists(DOKU_INC . 'favicon.ico')) { + $ico = DOKU_URL . 'favicon.ico'; +} elseif (file_exists(tpl_incdir() . 'images/favicon.ico')) { + $ico = DOKU_URL . 'lib/tpl/' . $conf['template'] . '/images/favicon.ico'; +} elseif (file_exists(tpl_incdir() . 'favicon.ico')) { + $ico = DOKU_URL . 'lib/tpl/' . $conf['template'] . '/favicon.ico'; +} else { + $ico = DOKU_URL . 'lib/tpl/dokuwiki/images/favicon.ico'; } // output header('Content-Type: application/opensearchdescription+xml; charset=utf-8'); -echo '<?xml version="1.0"?>'.NL; -echo '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">'.NL; -echo ' <ShortName>'.hsc($conf['title']).'</ShortName>'.NL; -echo ' <Image width="16" height="16" type="image/x-icon">'.$ico.'</Image>'.NL; -echo ' <Url type="text/html" template="'.DOKU_URL.DOKU_SCRIPT.'?do=search&id={searchTerms}" />'.NL; -echo ' <Url type="application/x-suggestions+json" template="'. - DOKU_URL.'lib/exe/ajax.php?call=suggestions&q={searchTerms}" />'.NL; -echo '</OpenSearchDescription>'.NL; - -//Setup VIM: ex: et ts=4 : +echo '<?xml version="1.0"?>' . NL; +echo '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">' . NL; +echo ' <ShortName>' . hsc($conf['title']) . '</ShortName>' . NL; +echo ' <Image width="16" height="16" type="image/x-icon">' . $ico . '</Image>' . NL; +echo ' <Url type="text/html" template="' . DOKU_URL . DOKU_SCRIPT . '?do=search&id={searchTerms}" />' . NL; +echo ' <Url type="application/x-suggestions+json" template="' . + DOKU_URL . 'lib/exe/ajax.php?call=suggestions&q={searchTerms}" />' . NL; +echo '</OpenSearchDescription>' . NL; diff --git a/lib/exe/taskrunner.php b/lib/exe/taskrunner.php index 69ab4451a..0a62bf623 100644 --- a/lib/exe/taskrunner.php +++ b/lib/exe/taskrunner.php @@ -1,16 +1,20 @@ <?php + /** * DokuWiki indexer * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */ + +use dokuwiki\TaskRunner; + if (!defined('DOKU_INC')) { define('DOKU_INC', __DIR__ . '/../../'); } -define('DOKU_DISABLE_GZIP_OUTPUT',1); -require_once DOKU_INC.'inc/init.php'; +define('DOKU_DISABLE_GZIP_OUTPUT', 1); +require_once DOKU_INC . 'inc/init.php'; session_write_close(); //close session -$taskRunner = new \dokuwiki\TaskRunner(); +$taskRunner = new TaskRunner(); $taskRunner->run(); diff --git a/lib/exe/xmlrpc.php b/lib/exe/xmlrpc.php index e90fb9eba..9fad90136 100644 --- a/lib/exe/xmlrpc.php +++ b/lib/exe/xmlrpc.php @@ -1,4 +1,5 @@ <?php + /** * XMLRPC API backend */ diff --git a/lib/images/fileicons/index.php b/lib/images/fileicons/index.php index d1f233e48..8729e515c 100644 --- a/lib/images/fileicons/index.php +++ b/lib/images/fileicons/index.php @@ -29,29 +29,30 @@ <body> <?php -$fi_list = ''; $fi_list32 = ''; +$fi_list = ''; +$fi_list32 = ''; foreach (glob('*.png') as $img) { - $fi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> '; + $fi_list .= '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" /> '; } foreach (glob('32x32/*.png') as $img) { - $fi_list32 .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> '; + $fi_list32 .= '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" /> '; } echo '<div class="white box"> -'.$fi_list.' +' . $fi_list . ' </div> <div class="black box"> -'.$fi_list.' +' . $fi_list . ' </div> <br style="clear: left" /> <div class="white box"> -'.$fi_list32.' +' . $fi_list32 . ' </div> <div class="black box"> -'.$fi_list32; +' . $fi_list32; ?> </div> diff --git a/lib/images/fileicons/svg/index.php b/lib/images/fileicons/svg/index.php index 66c4835af..2df7699ae 100644 --- a/lib/images/fileicons/svg/index.php +++ b/lib/images/fileicons/svg/index.php @@ -15,7 +15,7 @@ <body> <?php foreach (glob('*.svg') as $img) { - echo '<img src="'.$img.'" alt="'.$img.'" width="32" height="32" title="'.$img.'" /> '; + echo '<img src="' . $img . '" alt="' . $img . '" width="32" height="32" title="' . $img . '" /> '; } ?> </body> diff --git a/lib/images/smileys/index.php b/lib/images/smileys/index.php index 9441c1f9f..31440fda0 100644 --- a/lib/images/smileys/index.php +++ b/lib/images/smileys/index.php @@ -31,21 +31,21 @@ <?php $smi_list = ''; foreach (glob('*.svg') as $img) { - $smi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> '; + $smi_list .= '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" /> '; } -if(is_dir('local')) { +if (is_dir('local')) { $smi_list .= '<hr />'; foreach (glob('local/*.svg') as $img) { - $smi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> '; + $smi_list .= '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" /> '; } } echo '<div class="white box"> -'.$smi_list.' +' . $smi_list . ' </div> <div class="black box"> -'.$smi_list; +' . $smi_list; ?> </div> diff --git a/lib/index.html b/lib/index.html index 885c954a4..36286bffc 100644 --- a/lib/index.html +++ b/lib/index.html @@ -1,9 +1,9 @@ <!DOCTYPE html> <html> <head> -<meta http-equiv="refresh" content="0; URL=../" /> -<meta name="robots" content="noindex" /> -<title>nothing here...</title> + <meta http-equiv="refresh" content="0; URL=../"/> + <meta name="robots" content="noindex"/> + <title>nothing here...</title> </head> <body> <!-- this is just here to prevent directory browsing --> diff --git a/lib/plugins/acl/action.php b/lib/plugins/acl/action.php index 86e587093..bb84ff16c 100644 --- a/lib/plugins/acl/action.php +++ b/lib/plugins/acl/action.php @@ -1,24 +1,27 @@ <?php + +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; +use dokuwiki\Extension\Event; + /** * AJAX call handler for ACL plugin * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */ - /** * Register handler */ -class action_plugin_acl extends DokuWiki_Action_Plugin +class action_plugin_acl extends ActionPlugin { - /** * Registers a callback function for a given event * - * @param Doku_Event_Handler $controller DokuWiki's event controller object + * @param EventHandler $controller DokuWiki's event controller object * @return void */ - public function register(Doku_Event_Handler $controller) + public function register(EventHandler $controller) { $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxCallAcl'); @@ -27,11 +30,11 @@ class action_plugin_acl extends DokuWiki_Action_Plugin /** * AJAX call handler for ACL plugin * - * @param Doku_Event $event event object by reference + * @param Event $event event object by reference * @param mixed $param empty * @return void */ - public function handleAjaxCallAcl(Doku_Event $event, $param) + public function handleAjaxCallAcl(Event $event, $param) { if ($event->data !== 'plugin_acl') { return; @@ -78,8 +81,8 @@ class action_plugin_acl extends DokuWiki_Action_Plugin echo html_buildlist( $data, 'acl', - array($acl, 'makeTreeItem'), - array($acl, 'makeListItem') + [$acl, 'makeTreeItem'], + [$acl, 'makeListItem'] ); } } diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php index a295692f2..3a2857f62 100644 --- a/lib/plugins/acl/admin.php +++ b/lib/plugins/acl/admin.php @@ -1,4 +1,6 @@ <?php + +use dokuwiki\Extension\AdminPlugin; use dokuwiki\Utf8\Sort; /** @@ -14,10 +16,10 @@ use dokuwiki\Utf8\Sort; * All DokuWiki plugins to extend the admin function * need to inherit from this class */ -class admin_plugin_acl extends DokuWiki_Admin_Plugin +class admin_plugin_acl extends AdminPlugin { - public $acl = null; - protected $ns = null; + public $acl; + protected $ns; /** * The currently selected item, associative array with id and type. * Populated from (in this order): @@ -26,10 +28,10 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin * $ns * $ID */ - protected $current_item = null; + protected $current_item; protected $who = ''; - protected $usersgroups = array(); - protected $specials = array(); + protected $usersgroups = []; + protected $specials = []; /** * return prompt for admin menu @@ -73,27 +75,29 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin } if ($INPUT->str('current_ns')) { - $this->current_item = array('id' => cleanID($INPUT->str('current_ns')), 'type' => 'd'); + $this->current_item = ['id' => cleanID($INPUT->str('current_ns')), 'type' => 'd']; } elseif ($INPUT->str('current_id')) { - $this->current_item = array('id' => cleanID($INPUT->str('current_id')), 'type' => 'f'); + $this->current_item = ['id' => cleanID($INPUT->str('current_id')), 'type' => 'f']; } elseif ($this->ns) { - $this->current_item = array('id' => $this->ns, 'type' => 'd'); + $this->current_item = ['id' => $this->ns, 'type' => 'd']; } else { - $this->current_item = array('id' => $ID, 'type' => 'f'); + $this->current_item = ['id' => $ID, 'type' => 'f']; } // user or group choosen? $who = trim($INPUT->str('acl_w')); if ($INPUT->str('acl_t') == '__g__' && $who) { - $this->who = '@'.ltrim($auth->cleanGroup($who), '@'); + $this->who = '@' . ltrim($auth->cleanGroup($who), '@'); } elseif ($INPUT->str('acl_t') == '__u__' && $who) { $this->who = ltrim($who, '@'); if ($this->who != '%USER%' && $this->who != '%GROUP%') { #keep wildcard as is $this->who = $auth->cleanUser($this->who); } - } elseif ($INPUT->str('acl_t') && - $INPUT->str('acl_t') != '__u__' && - $INPUT->str('acl_t') != '__g__') { + } elseif ( + $INPUT->str('acl_t') && + $INPUT->str('acl_t') != '__u__' && + $INPUT->str('acl_t') != '__g__' + ) { $this->who = $INPUT->str('acl_t'); } elseif ($who) { $this->who = $who; @@ -108,7 +112,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin if ($this->ns == '*') { $scope = '*'; } else { - $scope = $this->ns.':*'; + $scope = $this->ns . ':*'; } } else { $scope = $ID; @@ -131,7 +135,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin unset($acl[$where][$who]); } // prepare lines - $lines = array(); + $lines = []; // keep header foreach ($AUTH_ACL as $line) { if ($line[0] == '#') { @@ -143,9 +147,9 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin // re-add all rules foreach ($acl as $where => $opt) { foreach ($opt as $who => $perm) { - if ($who[0]=='@') { - if ($who!='@ALL') { - $who = '@'.ltrim($auth->cleanGroup($who), '@'); + if ($who[0] == '@') { + if ($who != '@ALL') { + $who = '@' . ltrim($auth->cleanGroup($who), '@'); } } elseif ($who != '%USER%' && $who != '%GROUP%') { #keep wildcard as is $who = $auth->cleanUser($who); @@ -155,7 +159,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin } } // save it - io_saveFile($config_cascade['acl']['default'], join('', $lines)); + io_saveFile($config_cascade['acl']['default'], implode('', $lines)); } // reload ACL config @@ -177,31 +181,31 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin */ public function html() { - echo '<div id="acl_manager">'.NL; - echo '<h1>'.$this->getLang('admin_acl').'</h1>'.NL; - echo '<div class="level1">'.NL; + echo '<div id="acl_manager">'; + echo '<h1>' . $this->getLang('admin_acl') . '</h1>'; + echo '<div class="level1">'; - echo '<div id="acl__tree">'.NL; + echo '<div id="acl__tree">'; $this->makeExplorer(); - echo '</div>'.NL; + echo '</div>'; - echo '<div id="acl__detail">'.NL; + echo '<div id="acl__detail">'; $this->printDetail(); - echo '</div>'.NL; - echo '</div>'.NL; + echo '</div>'; + echo '</div>'; echo '<div class="clearer"></div>'; - echo '<h2>'.$this->getLang('current').'</h2>'.NL; - echo '<div class="level2">'.NL; + echo '<h2>' . $this->getLang('current') . '</h2>'; + echo '<div class="level2">'; $this->printAclTable(); - echo '</div>'.NL; + echo '</div>'; - echo '<div class="footnotes"><div class="fn">'.NL; - echo '<sup><a id="fn__1" class="fn_bot" href="#fnt__1">1)</a></sup>'.NL; - echo '<div class="content">'.$this->getLang('p_include').'</div>'; + echo '<div class="footnotes"><div class="fn">'; + echo '<sup><a id="fn__1" class="fn_bot" href="#fnt__1">1)</a></sup>'; + echo '<div class="content">' . $this->getLang('p_include') . '</div>'; echo '</div></div>'; - echo '</div>'.NL; + echo '</div>'; } /** @@ -211,10 +215,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin */ protected function getLinkOptions($addopts = null) { - $opts = array( - 'do'=>'admin', - 'page'=>'acl', - ); + $opts = ['do' => 'admin', 'page' => 'acl']; if ($this->ns) $opts['ns'] = $this->ns; if ($this->who) $opts['acl_w'] = $this->who; @@ -233,26 +234,31 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin global $ID; global $lang; - $ns = $this->ns; + $ns = $this->ns; if (empty($ns)) { $ns = dirname(str_replace(':', '/', $ID)); - if ($ns == '.') $ns =''; + if ($ns == '.') $ns = ''; } elseif ($ns == '*') { - $ns =''; + $ns = ''; } - $ns = utf8_encodeFN(str_replace(':', '/', $ns)); + $ns = utf8_encodeFN(str_replace(':', '/', $ns)); $data = $this->makeTree($ns); // wrap a list with the root level around the other namespaces - array_unshift($data, array( 'level' => 0, 'id' => '*', 'type' => 'd', - 'open' =>'true', 'label' => '['.$lang['mediaroot'].']')); + array_unshift($data, [ + 'level' => 0, + 'id' => '*', + 'type' => 'd', + 'open' => 'true', + 'label' => '[' . $lang['mediaroot'] . ']' + ]); echo html_buildlist( $data, 'acl', - array($this, 'makeTreeItem'), - array($this, 'makeListItem') + [$this, 'makeTreeItem'], + [$this, 'makeListItem'] ); } @@ -270,18 +276,18 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin global $conf; // read tree structure from pages and media - $data = array(); - search($data, $conf['datadir'], 'search_index', array('ns' => $folder), $limit); - $media = array(); - search($media, $conf['mediadir'], 'search_index', array('ns' => $folder, 'nofiles' => true), $limit); + $data = []; + search($data, $conf['datadir'], 'search_index', ['ns' => $folder], $limit); + $media = []; + search($media, $conf['mediadir'], 'search_index', ['ns' => $folder, 'nofiles' => true], $limit); $data = array_merge($data, $media); unset($media); // combine by sorting and removing duplicates - usort($data, array($this, 'treeSort')); + usort($data, [$this, 'treeSort']); $count = count($data); - if ($count>0) for ($i=1; $i<$count; $i++) { - if ($data[$i-1]['id'] == $data[$i]['id'] && $data[$i-1]['type'] == $data[$i]['type']) { + if ($count > 0) for ($i = 1; $i < $count; $i++) { + if ($data[$i - 1]['id'] == $data[$i]['id'] && $data[$i - 1]['type'] == $data[$i]['type']) { unset($data[$i]); $i++; // duplicate found, next $i can't be a duplicate, so skip forward one } @@ -311,14 +317,14 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin // if one of the components is the last component and is a file // and the other one is either of a deeper level or a directory, // the file has to come after the deeper level or directory - if (empty($a_ids) && $a['type'] == 'f' && (count($b_ids) || $b['type'] == 'd')) return 1; - if (empty($b_ids) && $b['type'] == 'f' && (count($a_ids) || $a['type'] == 'd')) return -1; + if ($a_ids === [] && $a['type'] == 'f' && (count($b_ids) || $b['type'] == 'd')) return 1; + if ($b_ids === [] && $b['type'] == 'f' && (count($a_ids) || $a['type'] == 'd')) return -1; return $cur_result; } } // The two ids seem to be equal. One of them might however refer // to a page, one to a namespace, the namespace needs to be first. - if (empty($a_ids) && empty($b_ids)) { + if ($a_ids === [] && $b_ids === []) { if ($a['type'] == $b['type']) return 0; if ($a['type'] == 'f') return 1; return -1; @@ -327,8 +333,8 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin // that obviously needs to be after the namespace // Or it is the namespace that contains the other part and should be // before that other part. - if (empty($a_ids)) return ($a['type'] == 'd') ? -1 : 1; - if (empty($b_ids)) return ($b['type'] == 'd') ? 1 : -1; + if ($a_ids === []) return ($a['type'] == 'd') ? -1 : 1; + if ($b_ids === []) return ($b['type'] == 'd') ? 1 : -1; return 0; //shouldn't happen } @@ -342,25 +348,28 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin { global $ID; - echo '<form action="'.wl().'" method="post" accept-charset="utf-8"><div class="no">'.NL; + echo '<form action="' . wl() . '" method="post" accept-charset="utf-8"><div class="no">'; echo '<div id="acl__user">'; - echo $this->getLang('acl_perms').' '; - $inl = $this->makeSelect(); - echo '<input type="text" name="acl_w" class="edit" value="'.(($inl)?'':hsc(ltrim($this->who, '@'))).'" />'.NL; - echo '<button type="submit">'.$this->getLang('btn_select').'</button>'.NL; - echo '</div>'.NL; + echo $this->getLang('acl_perms') . ' '; + $inl = $this->makeSelect(); + echo sprintf( + '<input type="text" name="acl_w" class="edit" value="%s" />', + ($inl) ? '' : hsc(ltrim($this->who, '@')) + ); + echo '<button type="submit">' . $this->getLang('btn_select') . '</button>'; + echo '</div>'; echo '<div id="acl__info">'; $this->printInfo(); echo '</div>'; - echo '<input type="hidden" name="ns" value="'.hsc($this->ns).'" />'.NL; - echo '<input type="hidden" name="id" value="'.hsc($ID).'" />'.NL; - echo '<input type="hidden" name="do" value="admin" />'.NL; - echo '<input type="hidden" name="page" value="acl" />'.NL; - echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL; - echo '</div></form>'.NL; + echo '<input type="hidden" name="ns" value="' . hsc($this->ns) . '" />'; + echo '<input type="hidden" name="id" value="' . hsc($ID) . '" />'; + echo '<input type="hidden" name="do" value="admin" />'; + echo '<input type="hidden" name="page" value="acl" />'; + echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />'; + echo '</div></form>'; } /** @@ -403,18 +412,18 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin echo '<fieldset>'; if (is_null($current)) { - echo '<legend>'.$this->getLang('acl_new').'</legend>'; + echo '<legend>' . $this->getLang('acl_new') . '</legend>'; } else { - echo '<legend>'.$this->getLang('acl_mod').'</legend>'; + echo '<legend>' . $this->getLang('acl_mod') . '</legend>'; } echo $this->makeCheckboxes($current, empty($this->ns), 'acl'); if (is_null($current)) { - echo '<button type="submit" name="cmd[save]">'.$lang['btn_save'].'</button>'.NL; + echo '<button type="submit" name="cmd[save]">' . $lang['btn_save'] . '</button>'; } else { - echo '<button type="submit" name="cmd[save]">'.$lang['btn_update'].'</button>'.NL; - echo '<button type="submit" name="cmd[del]">'.$lang['btn_delete'].'</button>'.NL; + echo '<button type="submit" name="cmd[save]">' . $lang['btn_update'] . '</button>'; + echo '<button type="submit" name="cmd[del]">' . $lang['btn_delete'] . '</button>'; } echo '</fieldset>'; @@ -431,14 +440,14 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin global $auth; $who = $this->who; - $ns = $this->ns; + $ns = $this->ns; // prepare where to check if ($ns) { if ($ns == '*') { - $check='*'; + $check = '*'; } else { - $check=$ns.':*'; + $check = $ns . ':*'; } } else { $check = $ID; @@ -446,13 +455,13 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin // prepare who to check if ($who[0] == '@') { - $user = ''; - $groups = array(ltrim($who, '@')); + $user = ''; + $groups = [ltrim($who, '@')]; } else { $user = $who; $info = $auth->getUserData($user); if ($info === false) { - $groups = array(); + $groups = []; } else { $groups = $info['grps']; } @@ -462,7 +471,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin $perm = auth_aclcheck($check, $user, $groups); // build array of named permissions - $names = array(); + $names = []; if ($perm) { if ($ns) { if ($perm >= AUTH_DELETE) $names[] = $this->getLang('acl_perm16'); @@ -480,24 +489,22 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin echo '<p>'; if ($user) { if ($ns) { - printf($this->getLang('p_user_ns'), hsc($who), hsc($ns), join(', ', $names)); + printf($this->getLang('p_user_ns'), hsc($who), hsc($ns), implode(', ', $names)); } else { - printf($this->getLang('p_user_id'), hsc($who), hsc($ID), join(', ', $names)); + printf($this->getLang('p_user_id'), hsc($who), hsc($ID), implode(', ', $names)); } + } elseif ($ns) { + printf($this->getLang('p_group_ns'), hsc(ltrim($who, '@')), hsc($ns), implode(', ', $names)); } else { - if ($ns) { - printf($this->getLang('p_group_ns'), hsc(ltrim($who, '@')), hsc($ns), join(', ', $names)); - } else { - printf($this->getLang('p_group_id'), hsc(ltrim($who, '@')), hsc($ID), join(', ', $names)); - } + printf($this->getLang('p_group_id'), hsc(ltrim($who, '@')), hsc($ID), implode(', ', $names)); } echo '</p>'; // add note if admin if ($perm == AUTH_ADMIN) { - echo '<p>'.$this->getLang('p_isadmin').'</p>'; + echo '<p>' . $this->getLang('p_isadmin') . '</p>'; } elseif (is_null($current)) { - echo '<p>'.$this->getLang('p_inherited').'</p>'; + echo '<p>' . $this->getLang('p_inherited') . '</p>'; } } @@ -516,36 +523,36 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin if (!empty($item['label'])) { $base = $item['label']; } else { - $base = ':'.$item['id']; - $base = substr($base, strrpos($base, ':')+1); + $base = ':' . $item['id']; + $base = substr($base, strrpos($base, ':') + 1); } // highlight? - if (($item['type']== $this->current_item['type'] && $item['id'] == $this->current_item['id'])) { + if (($item['type'] == $this->current_item['type'] && $item['id'] == $this->current_item['id'])) { $cl = ' cur'; } else { $cl = ''; } // namespace or page? - if ($item['type']=='d') { + if ($item['type'] == 'd') { if ($item['open']) { - $img = DOKU_BASE.'lib/images/minus.gif'; - $alt = '−'; + $img = DOKU_BASE . 'lib/images/minus.gif'; + $alt = '−'; } else { - $img = DOKU_BASE.'lib/images/plus.gif'; - $alt = '+'; + $img = DOKU_BASE . 'lib/images/plus.gif'; + $alt = '+'; } - $ret .= '<img src="'.$img.'" alt="'.$alt.'" />'; - $ret .= '<a href="'. - wl('', $this->getLinkOptions(array('ns'=> $item['id'], 'sectok'=>getSecurityToken()))). - '" class="idx_dir'.$cl.'">'; + $ret .= '<img src="' . $img . '" alt="' . $alt . '" />'; + $ret .= '<a href="' . + wl('', $this->getLinkOptions(['ns' => $item['id'], 'sectok' => getSecurityToken()])) . + '" class="idx_dir' . $cl . '">'; $ret .= $base; $ret .= '</a>'; } else { - $ret .= '<a href="'. - wl('', $this->getLinkOptions(array('id'=> $item['id'], 'ns'=>'', 'sectok'=>getSecurityToken()))). - '" class="wikilink1'.$cl.'">'; + $ret .= '<a href="' . + wl('', $this->getLinkOptions(['id' => $item['id'], 'ns' => '', 'sectok' => getSecurityToken()])) . + '" class="wikilink1' . $cl . '">'; $ret .= noNS($item['id']); $ret .= '</a>'; } @@ -561,7 +568,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin public function makeListItem($item) { return '<li class="level' . $item['level'] . ' ' . - ($item['open'] ? 'open' : 'closed') . '">'; + ($item['open'] ? 'open' : 'closed') . '">'; } @@ -574,12 +581,12 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin { global $AUTH_ACL; global $conf; - $acl_config=array(); - $usersgroups = array(); + $acl_config = []; + $usersgroups = []; // get special users and groups $this->specials[] = '@ALL'; - $this->specials[] = '@'.$conf['defaultgroup']; + $this->specials[] = '@' . $conf['defaultgroup']; if ($conf['manager'] != '!!not set!!') { $this->specials = array_merge( $this->specials, @@ -630,51 +637,51 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin global $lang; global $ID; - echo '<form action="'.wl().'" method="post" accept-charset="utf-8"><div class="no">'.NL; + echo '<form action="' . wl() . '" method="post" accept-charset="utf-8"><div class="no">'; if ($this->ns) { - echo '<input type="hidden" name="ns" value="'.hsc($this->ns).'" />'.NL; + echo '<input type="hidden" name="ns" value="' . hsc($this->ns) . '" />'; } else { - echo '<input type="hidden" name="id" value="'.hsc($ID).'" />'.NL; + echo '<input type="hidden" name="id" value="' . hsc($ID) . '" />'; } - echo '<input type="hidden" name="acl_w" value="'.hsc($this->who).'" />'.NL; - echo '<input type="hidden" name="do" value="admin" />'.NL; - echo '<input type="hidden" name="page" value="acl" />'.NL; - echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL; + echo '<input type="hidden" name="acl_w" value="' . hsc($this->who) . '" />'; + echo '<input type="hidden" name="do" value="admin" />'; + echo '<input type="hidden" name="page" value="acl" />'; + echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />'; echo '<div class="table">'; echo '<table class="inline">'; echo '<tr>'; - echo '<th>'.$this->getLang('where').'</th>'; - echo '<th>'.$this->getLang('who').'</th>'; - echo '<th>'.$this->getLang('perm').'<sup><a id="fnt__1" class="fn_top" href="#fn__1">1)</a></sup></th>'; - echo '<th>'.$lang['btn_delete'].'</th>'; + echo '<th>' . $this->getLang('where') . '</th>'; + echo '<th>' . $this->getLang('who') . '</th>'; + echo '<th>' . $this->getLang('perm') . '<sup><a id="fnt__1" class="fn_top" href="#fn__1">1)</a></sup></th>'; + echo '<th>' . $lang['btn_delete'] . '</th>'; echo '</tr>'; foreach ($this->acl as $where => $set) { foreach ($set as $who => $perm) { echo '<tr>'; echo '<td>'; if (substr($where, -1) == '*') { - echo '<span class="aclns">'.hsc($where).'</span>'; + echo '<span class="aclns">' . hsc($where) . '</span>'; $ispage = false; } else { - echo '<span class="aclpage">'.hsc($where).'</span>'; + echo '<span class="aclpage">' . hsc($where) . '</span>'; $ispage = true; } echo '</td>'; echo '<td>'; if ($who[0] == '@') { - echo '<span class="aclgroup">'.hsc($who).'</span>'; + echo '<span class="aclgroup">' . hsc($who) . '</span>'; } else { - echo '<span class="acluser">'.hsc($who).'</span>'; + echo '<span class="acluser">' . hsc($who) . '</span>'; } echo '</td>'; echo '<td>'; - echo $this->makeCheckboxes($perm, $ispage, 'acl['.$where.']['.$who.']'); + echo $this->makeCheckboxes($perm, $ispage, 'acl[' . $where . '][' . $who . ']'); echo '</td>'; echo '<td class="check">'; - echo '<input type="checkbox" name="del['.hsc($where).'][]" value="'.hsc($who).'" />'; + echo '<input type="checkbox" name="del[' . hsc($where) . '][]" value="' . hsc($who) . '" />'; echo '</td>'; echo '</tr>'; } @@ -682,12 +689,12 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin echo '<tr>'; echo '<th class="action" colspan="4">'; - echo '<button type="submit" name="cmd[update]">'.$lang['btn_update'].'</button>'; + echo '<button type="submit" name="cmd[update]">' . $lang['btn_update'] . '</button>'; echo '</th>'; echo '</tr>'; echo '</table>'; echo '</div>'; - echo '</div></form>'.NL; + echo '</div></form>'; } /** @@ -703,7 +710,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin if ($this->ns == '*') { $check = '*'; } else { - $check = $this->ns.':*'; + $check = $this->ns . ':*'; } } else { $check = $ID; @@ -749,7 +756,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin global $config_cascade; $acl_user = auth_nameencode($acl_user, true); - $acl_pattern = '^'.preg_quote($acl_scope, '/').'[ \t]+'.$acl_user.'[ \t]+[0-8].*$'; + $acl_pattern = '^' . preg_quote($acl_scope, '/') . '[ \t]+' . $acl_user . '[ \t]+[0-8].*$'; return io_deleteFromFile($config_cascade['acl']['default'], "/$acl_pattern/", true); } @@ -769,16 +776,18 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin if ($ispage && $setperm > AUTH_EDIT) $setperm = AUTH_EDIT; - foreach (array(AUTH_NONE,AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD,AUTH_DELETE) as $perm) { - $label += 1; + foreach ([AUTH_NONE, AUTH_READ, AUTH_EDIT, AUTH_CREATE, AUTH_UPLOAD, AUTH_DELETE] as $perm) { + ++$label; //general checkbox attributes - $atts = array( 'type' => 'radio', - 'id' => 'pbox'.$label, - 'name' => $name, - 'value' => $perm ); + $atts = [ + 'type' => 'radio', + 'id' => 'pbox' . $label, + 'name' => $name, + 'value' => $perm + ]; //dynamic attributes - if (!is_null($setperm) && $setperm == $perm) $atts['checked'] = 'checked'; + if (!is_null($setperm) && $setperm == $perm) $atts['checked'] = 'checked'; if ($ispage && $perm > AUTH_EDIT) { $atts['disabled'] = 'disabled'; $class = ' class="disabled"'; @@ -787,10 +796,10 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin } //build code - $ret .= '<label for="pbox'.$label.'"'.$class.'>'; - $ret .= '<input '.buildAttributes($atts).' /> '; - $ret .= $this->getLang('acl_perm'.$perm); - $ret .= '</label>'.NL; + $ret .= '<label for="pbox' . $label . '"' . $class . '>'; + $ret .= '<input ' . buildAttributes($atts) . ' /> '; + $ret .= $this->getLang('acl_perm' . $perm); + $ret .= '</label>'; } return $ret; } @@ -806,9 +815,11 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin $usel = ''; $gsel = ''; - if ($this->who && - !in_array($this->who, $this->usersgroups) && - !in_array($this->who, $this->specials)) { + if ( + $this->who && + !in_array($this->who, $this->usersgroups) && + !in_array($this->who, $this->specials) + ) { if ($this->who[0] == '@') { $gsel = ' selected="selected"'; } else { @@ -818,46 +829,46 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin $inlist = true; } - echo '<select name="acl_t" class="edit">'.NL; - echo ' <option value="__g__" class="aclgroup"'.$gsel.'>'.$this->getLang('acl_group').'</option>'.NL; - echo ' <option value="__u__" class="acluser"'.$usel.'>'.$this->getLang('acl_user').'</option>'.NL; + echo '<select name="acl_t" class="edit">'; + echo ' <option value="__g__" class="aclgroup"' . $gsel . '>' . $this->getLang('acl_group') . '</option>'; + echo ' <option value="__u__" class="acluser"' . $usel . '>' . $this->getLang('acl_user') . '</option>'; if (!empty($this->specials)) { - echo ' <optgroup label=" ">'.NL; + echo ' <optgroup label=" ">'; foreach ($this->specials as $ug) { if ($ug == $this->who) { - $sel = ' selected="selected"'; + $sel = ' selected="selected"'; $inlist = true; } else { $sel = ''; } if ($ug[0] == '@') { - echo ' <option value="'.hsc($ug).'" class="aclgroup"'.$sel.'>'.hsc($ug).'</option>'.NL; + echo ' <option value="' . hsc($ug) . '" class="aclgroup"' . $sel . '>' . hsc($ug) . '</option>'; } else { - echo ' <option value="'.hsc($ug).'" class="acluser"'.$sel.'>'.hsc($ug).'</option>'.NL; + echo ' <option value="' . hsc($ug) . '" class="acluser"' . $sel . '>' . hsc($ug) . '</option>'; } } - echo ' </optgroup>'.NL; + echo ' </optgroup>'; } if (!empty($this->usersgroups)) { - echo ' <optgroup label=" ">'.NL; + echo ' <optgroup label=" ">'; foreach ($this->usersgroups as $ug) { if ($ug == $this->who) { - $sel = ' selected="selected"'; + $sel = ' selected="selected"'; $inlist = true; } else { $sel = ''; } if ($ug[0] == '@') { - echo ' <option value="'.hsc($ug).'" class="aclgroup"'.$sel.'>'.hsc($ug).'</option>'.NL; + echo ' <option value="' . hsc($ug) . '" class="aclgroup"' . $sel . '>' . hsc($ug) . '</option>'; } else { - echo ' <option value="'.hsc($ug).'" class="acluser"'.$sel.'>'.hsc($ug).'</option>'.NL; + echo ' <option value="' . hsc($ug) . '" class="acluser"' . $sel . '>' . hsc($ug) . '</option>'; } } - echo ' </optgroup>'.NL; + echo ' </optgroup>'; } - echo '</select>'.NL; + echo '</select>'; return $inlist; } } diff --git a/lib/plugins/acl/remote.php b/lib/plugins/acl/remote.php index 8d19add72..692e219c5 100644 --- a/lib/plugins/acl/remote.php +++ b/lib/plugins/acl/remote.php @@ -1,13 +1,13 @@ <?php +use dokuwiki\Extension\RemotePlugin; use dokuwiki\Remote\AccessDeniedException; /** * Class remote_plugin_acl */ -class remote_plugin_acl extends DokuWiki_Remote_Plugin +class remote_plugin_acl extends RemotePlugin { - /** * Returns details about the remote plugin methods * @@ -15,24 +15,26 @@ class remote_plugin_acl extends DokuWiki_Remote_Plugin */ public function _getMethods() { - return array( - 'listAcls' => array( - 'args' => array(), + return [ + 'listAcls' => [ + 'args' => [], 'return' => 'Array of ACLs {scope, user, permission}', 'name' => 'listAcls', - 'doc' => 'Get the list of all ACLs', - ),'addAcl' => array( - 'args' => array('string','string','int'), + 'doc' => 'Get the list of all ACLs' + ], + 'addAcl' => [ + 'args' => ['string', 'string', 'int'], 'return' => 'int', 'name' => 'addAcl', 'doc' => 'Adds a new ACL rule.' - ), 'delAcl' => array( - 'args' => array('string','string'), + ], + 'delAcl' => [ + 'args' => ['string', 'string'], 'return' => 'int', 'name' => 'delAcl', 'doc' => 'Delete an existing ACL rule.' - ), - ); + ] + ]; } /** diff --git a/lib/plugins/action.php b/lib/plugins/action.php index 5bf8da91e..e75f700a0 100644 --- a/lib/plugins/action.php +++ b/lib/plugins/action.php @@ -1,4 +1,9 @@ <?php -\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction( - 'Autoloading', 1, 'require(' . basename(__FILE__) . ')' + +use dokuwiki\Debug\DebugHelper; + +DebugHelper::dbgDeprecatedFunction( + 'Autoloading', + 1, + 'require(' . basename(__FILE__) . ')' ); diff --git a/lib/plugins/admin.php b/lib/plugins/admin.php index 5bf8da91e..e75f700a0 100644 --- a/lib/plugins/admin.php +++ b/lib/plugins/admin.php @@ -1,4 +1,9 @@ <?php -\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction( - 'Autoloading', 1, 'require(' . basename(__FILE__) . ')' + +use dokuwiki\Debug\DebugHelper; + +DebugHelper::dbgDeprecatedFunction( + 'Autoloading', + 1, + 'require(' . basename(__FILE__) . ')' ); diff --git a/lib/plugins/auth.php b/lib/plugins/auth.php index 5bf8da91e..e75f700a0 100644 --- a/lib/plugins/auth.php +++ b/lib/plugins/auth.php @@ -1,4 +1,9 @@ <?php -\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction( - 'Autoloading', 1, 'require(' . basename(__FILE__) . ')' + +use dokuwiki\Debug\DebugHelper; + +DebugHelper::dbgDeprecatedFunction( + 'Autoloading', + 1, + 'require(' . basename(__FILE__) . ')' ); diff --git a/lib/plugins/authad/action.php b/lib/plugins/authad/action.php index 671138a98..904767f8d 100644 --- a/lib/plugins/authad/action.php +++ b/lib/plugins/authad/action.php @@ -1,4 +1,9 @@ <?php + +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; +use dokuwiki\Extension\Event; + /** * DokuWiki Plugin addomain (Action Component) * @@ -9,13 +14,12 @@ /** * Class action_plugin_addomain */ -class action_plugin_authad extends DokuWiki_Action_Plugin +class action_plugin_authad extends ActionPlugin { - /** * Registers a callback function for a given event */ - public function register(Doku_Event_Handler $controller) + public function register(EventHandler $controller) { $controller->register_hook('AUTH_LOGIN_CHECK', 'BEFORE', $this, 'handleAuthLoginCheck'); $controller->register_hook('FORM_LOGIN_OUTPUT', 'BEFORE', $this, 'handleFormLoginOutput'); @@ -24,10 +28,10 @@ class action_plugin_authad extends DokuWiki_Action_Plugin /** * Adds the selected domain as user postfix when attempting a login * - * @param Doku_Event $event + * @param Event $event * @param array $param */ - public function handleAuthLoginCheck(Doku_Event $event, $param) + public function handleAuthLoginCheck(Event $event, $param) { global $INPUT; @@ -39,7 +43,7 @@ class action_plugin_authad extends DokuWiki_Action_Plugin $usr = $auth->cleanUser($event->data['user']); $dom = $auth->getUserDomain($usr); if (!$dom) { - $usr = "$usr@".$INPUT->str('dom'); + $usr = "$usr@" . $INPUT->str('dom'); } $INPUT->post->set('u', $usr); $event->data['user'] = $usr; @@ -49,10 +53,10 @@ class action_plugin_authad extends DokuWiki_Action_Plugin /** * Shows a domain selection in the login form when more than one domain is configured * - * @param Doku_Event $event + * @param Event $event * @param array $param */ - public function handleFormLoginOutput(Doku_Event $event, $param) + public function handleFormLoginOutput(Event $event, $param) { global $INPUT; /** @var auth_plugin_authad $auth */ @@ -82,7 +86,7 @@ class action_plugin_authad extends DokuWiki_Action_Plugin } // add locate domain selector just after the username input box - $element = $form->addDropdown('dom', $domains, $this->getLang('domain'), $pos +1); + $element = $form->addDropdown('dom', $domains, $this->getLang('domain'), $pos + 1); $element->addClass('block'); } } diff --git a/lib/plugins/authad/auth.php b/lib/plugins/authad/auth.php index 0c3690f0a..47665c31f 100644 --- a/lib/plugins/authad/auth.php +++ b/lib/plugins/authad/auth.php @@ -1,4 +1,8 @@ <?php + +use dokuwiki\Extension\AuthPlugin; +use dokuwiki\Utf8\Clean; +use dokuwiki\Utf8\PhpString; use dokuwiki\Utf8\Sort; use dokuwiki\Logger; @@ -38,18 +42,17 @@ use dokuwiki\Logger; * @author Andreas Gohr <andi@splitbrain.org> * @author Jan Schumann <js@schumann-it.com> */ -class auth_plugin_authad extends DokuWiki_Auth_Plugin +class auth_plugin_authad extends AuthPlugin { - /** * @var array hold connection data for a specific AD domain */ - protected $opts = array(); + protected $opts = []; /** * @var array open connections for each AD domain, as adLDAP objects */ - protected $adldap = array(); + protected $adldap = []; /** * @var bool message state @@ -59,14 +62,14 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin /** * @var array user listing cache */ - protected $users = array(); + protected $users = []; /** * @var array filter patterns for listing users */ - protected $pattern = array(); + protected $pattern = []; - protected $grpsusers = array(); + protected $grpsusers = []; /** * Constructor @@ -76,8 +79,8 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin global $INPUT; parent::__construct(); - require_once(DOKU_PLUGIN.'authad/adLDAP/adLDAP.php'); - require_once(DOKU_PLUGIN.'authad/adLDAP/classes/adLDAPUtils.php'); + require_once(DOKU_PLUGIN . 'authad/adLDAP/adLDAP.php'); + require_once(DOKU_PLUGIN . 'authad/adLDAP/classes/adLDAPUtils.php'); // we load the config early to modify it a bit here $this->loadConfig(); @@ -86,7 +89,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin if (isset($this->conf['additional'])) { $this->conf['additional'] = str_replace(' ', '', $this->conf['additional']); $this->conf['additional'] = explode(',', $this->conf['additional']); - } else $this->conf['additional'] = array(); + } else $this->conf['additional'] = []; // ldap extension is needed if (!function_exists('ldap_connect')) { @@ -100,9 +103,11 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin if (!empty($INPUT->server->str('REMOTE_USER'))) { // make sure the right encoding is used if ($this->getConf('sso_charset')) { - $INPUT->server->set('REMOTE_USER', - iconv($this->getConf('sso_charset'), 'UTF-8', $INPUT->server->str('REMOTE_USER'))); - } elseif (!\dokuwiki\Utf8\Clean::isUtf8($INPUT->server->str('REMOTE_USER'))) { + $INPUT->server->set( + 'REMOTE_USER', + iconv($this->getConf('sso_charset'), 'UTF-8', $INPUT->server->str('REMOTE_USER')) + ); + } elseif (!Clean::isUtf8($INPUT->server->str('REMOTE_USER'))) { $INPUT->server->set('REMOTE_USER', utf8_encode($INPUT->server->str('REMOTE_USER'))); } @@ -154,7 +159,8 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin public function checkPass($user, $pass) { global $INPUT; - if ($INPUT->server->str('REMOTE_USER') == $user && + if ( + $INPUT->server->str('REMOTE_USER') == $user && $this->conf['sso'] ) return true; @@ -201,11 +207,11 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin global $ID; global $INPUT; $adldap = $this->initAdLdap($this->getUserDomain($user)); - if (!$adldap) return array(); + if (!$adldap) return []; - if ($user == '') return array(); + if ($user == '') return []; - $fields = array('mail', 'displayname', 'samaccountname', 'lastpwd', 'pwdlastset', 'useraccountcontrol'); + $fields = ['mail', 'displayname', 'samaccountname', 'lastpwd', 'pwdlastset', 'useraccountcontrol']; // add additional fields to read $fields = array_merge($fields, $this->conf['additional']); @@ -215,17 +221,17 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin //get info for given user $result = $adldap->user()->info($this->getUserName($user), $fields); if ($result == false) { - return array(); + return []; } //general user info - $info = array(); + $info = []; $info['name'] = $result[0]['displayname'][0]; $info['mail'] = $result[0]['mail'][0]; $info['uid'] = $result[0]['samaccountname'][0]; $info['dn'] = $result[0]['dn']; //last password set (Windows counts from January 1st 1601) - $info['lastpwd'] = $result[0]['pwdlastset'][0] / 10000000 - 11644473600; + $info['lastpwd'] = $result[0]['pwdlastset'][0] / 10_000_000 - 11_644_473_600; //will it expire? $info['expires'] = !($result[0]['useraccountcontrol'][0] & 0x10000); //ADS_UF_DONT_EXPIRE_PASSWD @@ -252,7 +258,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin // add the user's domain to the groups $domain = $this->getUserDomain($user); - if ($domain && !in_array("domain-$domain", (array) $info['grps'])) { + if ($domain && !in_array("domain-$domain", $info['grps'])) { $info['grps'][] = $this->cleanGroup("domain-$domain"); } @@ -262,17 +268,18 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin $expiry = $adldap->user()->passwordExpiry($user); if (is_array($expiry)) { $info['expiresat'] = $expiry['expiryts']; - $info['expiresin'] = round(($info['expiresat'] - time())/(24*60*60)); + $info['expiresin'] = round(($info['expiresat'] - time()) / (24 * 60 * 60)); // if this is the current user, warn him (once per request only) - if (($INPUT->server->str('REMOTE_USER') == $user) && + if ( + ($INPUT->server->str('REMOTE_USER') == $user) && ($info['expiresin'] <= $this->conf['expirywarn']) && !$this->msgshown ) { $msg = sprintf($this->getLang('authpwdexpire'), $info['expiresin']); if ($this->canDo('modPass')) { - $url = wl($ID, array('do'=> 'profile')); - $msg .= ' <a href="'.$url.'">'.$lang['btn_profile'].'</a>'; + $url = wl($ID, ['do' => 'profile']); + $msg .= ' <a href="' . $url . '">' . $lang['btn_profile'] . '</a>'; } msg($msg); $this->msgshown = true; @@ -300,7 +307,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin $group = str_replace('\\', '', $group); $group = str_replace('#', '', $group); $group = preg_replace('[\s]', '_', $group); - $group = \dokuwiki\Utf8\PhpString::strtolower(trim($group)); + $group = PhpString::strtolower(trim($group)); return $group; } @@ -318,19 +325,21 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin $domain = ''; // get NTLM or Kerberos domain part - list($dom, $user) = sexplode('\\', $user, 2, ''); + [$dom, $user] = sexplode('\\', $user, 2, ''); if (!$user) $user = $dom; if ($dom) $domain = $dom; - list($user, $dom) = sexplode('@', $user, 2, ''); + [$user, $dom] = sexplode('@', $user, 2, ''); if ($dom) $domain = $dom; // clean up both - $domain = \dokuwiki\Utf8\PhpString::strtolower(trim($domain)); - $user = \dokuwiki\Utf8\PhpString::strtolower(trim($user)); + $domain = PhpString::strtolower(trim($domain)); + $user = PhpString::strtolower(trim($user)); // is this a known, valid domain or do we work without account suffix? if not discard - if ((!isset($this->conf[$domain]) || !is_array($this->conf[$domain])) && - $this->conf['account_suffix'] !== '') { + if ( + (!isset($this->conf[$domain]) || !is_array($this->conf[$domain])) && + $this->conf['account_suffix'] !== '' + ) { $domain = ''; } @@ -385,14 +394,14 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin * @param array $filter $filter array of field/pattern pairs, empty array for no filter * @return int number of users */ - public function getUserCount($filter = array()) + public function getUserCount($filter = []) { $adldap = $this->initAdLdap(null); if (!$adldap) { Logger::debug("authad/auth.php getUserCount(): _adldap not set."); return -1; } - if ($filter == array()) { + if ($filter == []) { $result = $adldap->user()->all(); } else { $searchString = $this->constructSearchString($filter); @@ -403,14 +412,15 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin $usermanager = plugin_load("admin", "usermanager", false); $usermanager->setLastdisabled(true); if (!isset($this->grpsusers[$this->filterToString($filter)])) { - $this->fillGroupUserArray($filter, $usermanager->getStart() + 3*$usermanager->getPagesize()); - } elseif (count($this->grpsusers[$this->filterToString($filter)]) < - $usermanager->getStart() + 3*$usermanager->getPagesize() + $this->fillGroupUserArray($filter, $usermanager->getStart() + 3 * $usermanager->getPagesize()); + } elseif ( + count($this->grpsusers[$this->filterToString($filter)]) < + $usermanager->getStart() + 3 * $usermanager->getPagesize() ) { $this->fillGroupUserArray( $filter, $usermanager->getStart() + - 3*$usermanager->getPagesize() - + 3 * $usermanager->getPagesize() - count($this->grpsusers[$this->filterToString($filter)]) ); } @@ -471,7 +481,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin $actualstart = 0; } - $i=0; + $i = 0; $count = 0; $this->constructPattern($filter); foreach ($this->users as $user => &$info) { @@ -499,21 +509,21 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin * @param array $filter array of field/pattern pairs, null for no filter * @return array userinfo (refer getUserData for internal userinfo details) */ - public function retrieveUsers($start = 0, $limit = 0, $filter = array()) + public function retrieveUsers($start = 0, $limit = 0, $filter = []) { $adldap = $this->initAdLdap(null); - if (!$adldap) return array(); + if (!$adldap) return []; //if (!$this->users) { //get info for given user $result = $adldap->user()->all(false, $this->constructSearchString($filter)); - if (!$result) return array(); + if (!$result) return []; $this->users = array_fill_keys($result, false); //} $i = 0; $count = 0; - $result = array(); + $result = []; if (!isset($filter['grps'])) { /** @var admin_plugin_usermanager $usermanager */ @@ -534,19 +544,20 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin /** @var admin_plugin_usermanager $usermanager */ $usermanager = plugin_load("admin", "usermanager", false); $usermanager->setLastdisabled(true); - if (!isset($this->grpsusers[$this->filterToString($filter)]) || - count($this->grpsusers[$this->filterToString($filter)]) < ($start+$limit) + if ( + !isset($this->grpsusers[$this->filterToString($filter)]) || + count($this->grpsusers[$this->filterToString($filter)]) < ($start + $limit) ) { - if(!isset($this->grpsusers[$this->filterToString($filter)])) { + if (!isset($this->grpsusers[$this->filterToString($filter)])) { $this->grpsusers[$this->filterToString($filter)] = []; } $this->fillGroupUserArray( $filter, - $start+$limit - count($this->grpsusers[$this->filterToString($filter)]) +1 + $start + $limit - count($this->grpsusers[$this->filterToString($filter)]) + 1 ); } - if (!$this->grpsusers[$this->filterToString($filter)]) return array(); + if (!$this->grpsusers[$this->filterToString($filter)]) return []; foreach ($this->grpsusers[$this->filterToString($filter)] as $user => &$info) { if ($i++ < $start) { continue; @@ -579,29 +590,29 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin try { $return = $adldap->user()->password($this->getUserName($user), $changes['pass']); } catch (adLDAPException $e) { - if ($this->conf['debug']) msg('AD Auth: '.$e->getMessage(), -1); + if ($this->conf['debug']) msg('AD Auth: ' . $e->getMessage(), -1); $return = false; } if (!$return) msg($this->getLang('passchangefail'), -1); } // changing user data - $adchanges = array(); + $adchanges = []; if (isset($changes['name'])) { // get first and last name $parts = explode(' ', $changes['name']); $adchanges['surname'] = array_pop($parts); - $adchanges['firstname'] = join(' ', $parts); + $adchanges['firstname'] = implode(' ', $parts); $adchanges['display_name'] = $changes['name']; } if (isset($changes['mail'])) { $adchanges['email'] = $changes['mail']; } - if (count($adchanges)) { + if ($adchanges !== []) { try { - $return = $return & $adldap->user()->modify($this->getUserName($user), $adchanges); + $return &= $adldap->user()->modify($this->getUserName($user), $adchanges); } catch (adLDAPException $e) { - if ($this->conf['debug']) msg('AD Auth: '.$e->getMessage(), -1); + if ($this->conf['debug']) msg('AD Auth: ' . $e->getMessage(), -1); $return = false; } if (!$return) msg($this->getLang('userchangefail'), -1); @@ -635,7 +646,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin return $this->adldap[$domain]; } catch (Exception $e) { if ($this->conf['debug']) { - msg('AD Auth: '.$e->getMessage(), -1); + msg('AD Auth: ' . $e->getMessage(), -1); } $this->success = false; $this->adldap[$domain] = null; @@ -651,7 +662,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin */ public function getUserDomain($user) { - list(, $domain) = sexplode('@', $user, 2, ''); + [, $domain] = sexplode('@', $user, 2, ''); return $domain; } @@ -666,7 +677,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin public function getUserName($user) { if ($this->conf['account_suffix'] !== '') { - list($user) = explode('@', $user, 2); + [$user] = explode('@', $user, 2); } return $user; } @@ -733,7 +744,7 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin */ public function getConfiguredDomains() { - $domains = array(); + $domains = []; if (empty($this->conf['account_suffix'])) return $domains; // not configured yet // add default domain, using the name from account suffix @@ -768,8 +779,8 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin if (!preg_match($pattern, $user)) return false; } elseif ($item == 'grps') { if (!count(preg_grep($pattern, $info['grps']))) return false; - } else { - if (!preg_match($pattern, $info[$item])) return false; + } elseif (!preg_match($pattern, $info[$item])) { + return false; } } return true; @@ -784,9 +795,9 @@ class auth_plugin_authad extends DokuWiki_Auth_Plugin */ protected function constructPattern($filter) { - $this->pattern = array(); + $this->pattern = []; foreach ($filter as $item => $pattern) { - $this->pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters + $this->pattern[$item] = '/' . str_replace('/', '\/', $pattern) . '/i'; // allow regex characters } } } diff --git a/lib/plugins/authad/conf/metadata.php b/lib/plugins/authad/conf/metadata.php index 96d8937ae..aa5d92e5c 100644 --- a/lib/plugins/authad/conf/metadata.php +++ b/lib/plugins/authad/conf/metadata.php @@ -11,7 +11,7 @@ $meta['real_primarygroup'] = array('onoff','_caution' => 'danger'); $meta['use_ssl'] = array('onoff','_caution' => 'danger'); $meta['use_tls'] = array('onoff','_caution' => 'danger'); $meta['debug'] = array('onoff','_caution' => 'security'); -$meta['expirywarn'] = array('numeric', '_min'=>0,'_caution' => 'danger'); +$meta['expirywarn'] = array('numeric', '_min' => 0,'_caution' => 'danger'); $meta['additional'] = array('string','_caution' => 'danger'); $meta['update_name'] = array('onoff','_caution' => 'danger'); $meta['update_mail'] = array('onoff','_caution' => 'danger'); diff --git a/lib/plugins/authldap/auth.php b/lib/plugins/authldap/auth.php index 71b2584cb..213e43f29 100644 --- a/lib/plugins/authldap/auth.php +++ b/lib/plugins/authldap/auth.php @@ -1,4 +1,7 @@ <?php + +use dokuwiki\Extension\AuthPlugin; +use dokuwiki\PassHash; use dokuwiki\Utf8\Sort; /** @@ -9,19 +12,19 @@ use dokuwiki\Utf8\Sort; * @author Chris Smith <chris@jalakaic.co.uk> * @author Jan Schumann <js@schumann-it.com> */ -class auth_plugin_authldap extends DokuWiki_Auth_Plugin +class auth_plugin_authldap extends AuthPlugin { /* @var resource $con holds the LDAP connection */ - protected $con = null; + protected $con; /* @var int $bound What type of connection does already exist? */ protected $bound = 0; // 0: anonymous, 1: user, 2: superuser /* @var array $users User data cache */ - protected $users = null; + protected $users; /* @var array $pattern User filter pattern */ - protected $pattern = null; + protected $pattern; /** * Constructor @@ -67,28 +70,27 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin return false; } $this->bound = 2; - } elseif ($this->getConf('binddn') && + } elseif ( + $this->getConf('binddn') && $this->getConf('usertree') && $this->getConf('userfilter') ) { // special bind string $dn = $this->makeFilter( $this->getConf('binddn'), - array('user' => $user, 'server' => $this->getConf('server')) + ['user' => $user, 'server' => $this->getConf('server')] ); } elseif (strpos($this->getConf('usertree'), '%{user}')) { // direct user bind $dn = $this->makeFilter( $this->getConf('usertree'), - array('user' => $user, 'server' => $this->getConf('server')) + ['user' => $user, 'server' => $this->getConf('server')] ); - } else { + } elseif (!@ldap_bind($this->con)) { // Anonymous bind - if (!@ldap_bind($this->con)) { - msg("LDAP: can not bind anonymously", -1); - $this->debug('LDAP anonymous bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__); - return false; - } + msg("LDAP: can not bind anonymously", -1); + $this->debug('LDAP anonymous bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__); + return false; } // Try to bind to with the dn if we have one. @@ -162,28 +164,28 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin protected function fetchUserData($user, $inbind = false) { global $conf; - if (!$this->openLDAP()) return array(); + if (!$this->openLDAP()) return []; // force superuser bind if wanted and not bound as superuser yet if ($this->getConf('binddn') && $this->getConf('bindpw') && $this->bound < 2) { // use superuser credentials if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) { $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__); - return array(); + return []; } $this->bound = 2; } elseif ($this->bound == 0 && !$inbind) { // in some cases getUserData is called outside the authentication workflow // eg. for sending email notification on subscribed pages. This data might not // be accessible anonymously, so we try to rebind the current user here - list($loginuser, $loginsticky, $loginpass) = auth_getCookie(); + [$loginuser, $loginsticky, $loginpass] = auth_getCookie(); if ($loginuser && $loginpass) { $loginpass = auth_decrypt($loginpass, auth_cookiesalt(!$loginsticky, true)); $this->checkPass($loginuser, $loginpass); } } - $info = array(); + $info = []; $info['user'] = $user; $this->debug('LDAP user to find: ' . hsc($info['user']), 0, __LINE__, __FILE__); @@ -204,8 +206,8 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin $this->debug('LDAP search at: ' . hsc($base . ' ' . $filter), 0, __LINE__, __FILE__); $sr = $this->ldapSearch($this->con, $base, $filter, $this->getConf('userscope'), $this->getConf('attributes')); if ($sr === false) { - $this->debug('User ldap_search failed. Check configuration.', 0, __LINE__, __FILE__); - return false; + $this->debug('User ldap_search failed. Check configuration.', 0, __LINE__, __FILE__); + return false; } $result = @ldap_get_entries($this->con, $sr); @@ -214,7 +216,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin if (!is_array($result)) { // no objects found $this->debug('LDAP search returned non-array result: ' . hsc(print($result)), -1, __LINE__, __FILE__); - return array(); + return []; } // Don't accept more or less than one response @@ -228,7 +230,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin //for($i = 0; $i < $result["count"]; $i++) { //$this->_debug('result: '.hsc(print_r($result[$i])), 0, __LINE__, __FILE__); //} - return array(); + return []; } $this->debug('LDAP search found single result !', 0, __LINE__, __FILE__); @@ -241,7 +243,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin $info['gid'] = $user_result['gidnumber'][0] ?? null; $info['mail'] = $user_result['mail'][0]; $info['name'] = $user_result['cn'][0]; - $info['grps'] = array(); + $info['grps'] = []; // overwrite if other attribs are specified. if (is_array($this->getConf('mapping'))) { @@ -276,14 +278,14 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin $base, $filter, $this->getConf('groupscope'), - array($this->getConf('groupkey')) + [$this->getConf('groupkey')] ); $this->debug('LDAP group search: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__); $this->debug('LDAP search at: ' . hsc($base . ' ' . $filter), 0, __LINE__, __FILE__); if (!$sr) { msg("LDAP: Reading group memberships failed", -1); - return array(); + return []; } $result = ldap_get_entries($this->con, $sr); ldap_free_result($sr); @@ -305,7 +307,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin } // always add the default group to the list of groups - if (!$info['grps'] or !in_array($conf['defaultgroup'], $info['grps'])) { + if (!$info['grps'] || !in_array($conf['defaultgroup'], $info['grps'])) { $info['grps'][] = $conf['defaultgroup']; } return $info; @@ -336,7 +338,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin $dn = $info['dn']; // find the old password of the user - list($loginuser, $loginsticky, $loginpass) = auth_getCookie(); + [$loginuser, $loginsticky, $loginpass] = auth_getCookie(); if ($loginuser !== null) { // the user is currently logged in $secret = auth_cookiesalt(!$loginsticky, true); $pass = auth_decrypt($loginpass, $secret); @@ -363,11 +365,11 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin } // Generate the salted hashed password for LDAP - $phash = new \dokuwiki\PassHash(); + $phash = new PassHash(); $hash = $phash->hash_ssha($changes['pass']); // change the password - if (!@ldap_mod_replace($this->con, $dn, array('userpassword' => $hash))) { + if (!@ldap_mod_replace($this->con, $dn, ['userpassword' => $hash])) { $this->debug( 'LDAP mod replace failed: ' . hsc($dn) . ': ' . hsc(ldap_error($this->con)), 0, @@ -399,9 +401,9 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin * @return array of userinfo (refer getUserData for internal userinfo details) * @author Dominik Eckelmann <dokuwiki@cosmocode.de> */ - public function retrieveUsers($start = 0, $limit = 0, $filter = array()) + public function retrieveUsers($start = 0, $limit = 0, $filter = []) { - if (!$this->openLDAP()) return array(); + if (!$this->openLDAP()) return []; if (is_null($this->users)) { // Perform the search and grab all their details @@ -412,20 +414,20 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin } $sr = ldap_search($this->con, $this->getConf('usertree'), $all_filter); $entries = ldap_get_entries($this->con, $sr); - $users_array = array(); + $users_array = []; $userkey = $this->getConf('userkey'); for ($i = 0; $i < $entries["count"]; $i++) { - array_push($users_array, $entries[$i][$userkey][0]); + $users_array[] = $entries[$i][$userkey][0]; } Sort::asort($users_array); $result = $users_array; - if (!$result) return array(); + if (!$result) return []; $this->users = array_fill_keys($result, false); } $i = 0; $count = 0; $this->constructPattern($filter); - $result = array(); + $result = []; foreach ($this->users as $user => &$info) { if ($i++ < $start) { @@ -486,8 +488,8 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin if (!preg_match($pattern, $user)) return false; } elseif ($item == 'grps') { if (!count(preg_grep($pattern, $info['grps']))) return false; - } else { - if (!preg_match($pattern, $info[$item])) return false; + } elseif (!preg_match($pattern, $info[$item])) { + return false; } } return true; @@ -503,7 +505,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin */ protected function constructPattern($filter) { - $this->pattern = array(); + $this->pattern = []; foreach ($filter as $item => $pattern) { $this->pattern[$item] = '/' . str_replace('/', '\/', $pattern) . '/i'; // allow regex characters } @@ -523,9 +525,7 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin // see https://github.com/adldap/adLDAP/issues/22 return preg_replace_callback( '/([\x00-\x1F\*\(\)\\\\])/', - function ($matches) { - return "\\" . join("", unpack("H2", $matches[1])); - }, + static fn($matches) => "\\" . implode("", unpack("H2", $matches[1])), $string ); } @@ -566,11 +566,12 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin //set protocol version and dependend options if ($this->getConf('version')) { - if (!@ldap_set_option( - $this->con, - LDAP_OPT_PROTOCOL_VERSION, - $this->getConf('version') - ) + if ( + !@ldap_set_option( + $this->con, + LDAP_OPT_PROTOCOL_VERSION, + $this->getConf('version') + ) ) { msg('Setting LDAP Protocol version ' . $this->getConf('version') . ' failed', -1); $this->debug('LDAP version set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__); @@ -584,11 +585,12 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin } // needs version 3 if ($this->getConf('referrals') > -1) { - if (!@ldap_set_option( - $this->con, - LDAP_OPT_REFERRALS, - $this->getConf('referrals') - ) + if ( + !@ldap_set_option( + $this->con, + LDAP_OPT_REFERRALS, + $this->getConf('referrals') + ) ) { msg('Setting LDAP referrals failed', -1); $this->debug('LDAP referal set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__); @@ -651,9 +653,8 @@ class auth_plugin_authldap extends DokuWiki_Auth_Plugin $attributes = null, $attrsonly = 0, $sizelimit = 0 - ) - { - if (is_null($attributes)) $attributes = array(); + ) { + if (is_null($attributes)) $attributes = []; if ($scope == 'base') { return @ldap_read( diff --git a/lib/plugins/authldap/conf/metadata.php b/lib/plugins/authldap/conf/metadata.php index 3a58590a8..db33d8b51 100644 --- a/lib/plugins/authldap/conf/metadata.php +++ b/lib/plugins/authldap/conf/metadata.php @@ -1,4 +1,5 @@ <?php + $meta['server'] = array('string','_caution' => 'danger'); $meta['port'] = array('numeric','_caution' => 'danger'); $meta['usertree'] = array('string','_caution' => 'danger'); @@ -10,7 +11,7 @@ $meta['starttls'] = array('onoff','_caution' => 'danger'); $meta['referrals'] = array('multichoice','_choices' => array(-1,0,1),'_caution' => 'danger'); $meta['deref'] = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'danger'); $meta['binddn'] = array('string','_caution' => 'danger'); -$meta['bindpw'] = array('password','_caution' => 'danger','_code'=>'base64'); +$meta['bindpw'] = array('password','_caution' => 'danger','_code' => 'base64'); $meta['attributes'] = array('array'); //$meta['mapping']['name'] unsupported in config manager //$meta['mapping']['grps'] unsupported in config manager diff --git a/lib/plugins/authpdo/auth.php b/lib/plugins/authpdo/auth.php index f58ad0247..47fe9cfc6 100644 --- a/lib/plugins/authpdo/auth.php +++ b/lib/plugins/authpdo/auth.php @@ -1,4 +1,7 @@ <?php + +use dokuwiki\Extension\AuthPlugin; +use dokuwiki\PassHash; use dokuwiki\Utf8\Sort; /** @@ -11,14 +14,13 @@ use dokuwiki\Utf8\Sort; /** * Class auth_plugin_authpdo */ -class auth_plugin_authpdo extends DokuWiki_Auth_Plugin +class auth_plugin_authpdo extends AuthPlugin { - /** @var PDO */ protected $pdo; /** @var null|array The list of all groups */ - protected $groupcache = null; + protected $groupcache; /** * Constructor. @@ -44,11 +46,11 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $this->getConf('dsn'), $this->getConf('user'), conf_decodeString($this->getConf('pass')), - array( + [ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // always fetch as array PDO::ATTR_EMULATE_PREPARES => true, // emulating prepares allows us to reuse param names PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes - ) + ] ); } catch (PDOException $e) { $this->debugMsg($e); @@ -59,94 +61,52 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin // can Users be created? $this->cando['addUser'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'select-groups', - 'insert-user', - 'insert-group', - 'join-group' - ) + ['select-user', 'select-user-groups', 'select-groups', 'insert-user', 'insert-group', 'join-group'] ); // can Users be deleted? $this->cando['delUser'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'select-groups', - 'leave-group', - 'delete-user' - ) + ['select-user', 'select-user-groups', 'select-groups', 'leave-group', 'delete-user'] ); // can login names be changed? $this->cando['modLogin'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'update-user-login' - ) + ['select-user', 'select-user-groups', 'update-user-login'] ); // can passwords be changed? $this->cando['modPass'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'update-user-pass' - ) + ['select-user', 'select-user-groups', 'update-user-pass'] ); // can real names be changed? $this->cando['modName'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'update-user-info:name' - ) + ['select-user', 'select-user-groups', 'update-user-info:name'] ); // can real email be changed? $this->cando['modMail'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'update-user-info:mail' - ) + ['select-user', 'select-user-groups', 'update-user-info:mail'] ); // can groups be changed? $this->cando['modGroups'] = $this->checkConfig( - array( - 'select-user', - 'select-user-groups', - 'select-groups', - 'leave-group', - 'join-group', - 'insert-group' - ) + ['select-user', 'select-user-groups', 'select-groups', 'leave-group', 'join-group', 'insert-group'] ); // can a filtered list of users be retrieved? $this->cando['getUsers'] = $this->checkConfig( - array( - 'list-users' - ) + ['list-users'] ); // can the number of users be retrieved? $this->cando['getUserCount'] = $this->checkConfig( - array( - 'count-users' - ) + ['count-users'] ); // can a list of available groups be retrieved? $this->cando['getGroups'] = $this->checkConfig( - array( - 'select-groups' - ) + ['select-groups'] ); $this->success = true; @@ -166,7 +126,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin if ($userdata == false) return false; // password checking done in SQL? - if ($this->checkConfig(array('check-pass'))) { + if ($this->checkConfig(['check-pass'])) { $userdata['clear'] = $pass; $userdata['hash'] = auth_cryptPassword($pass); $result = $this->query($this->getConf('check-pass'), $userdata); @@ -177,7 +137,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin // we do password checking on our own if (isset($userdata['hash'])) { // hashed password - $passhash = new \dokuwiki\PassHash(); + $passhash = new PassHash(); return $passhash->verify_hash($pass, $userdata['hash']); } else { // clear text password in the database O_o @@ -243,11 +203,11 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin } // prepare data - if ($grps == null) $grps = array(); + if ($grps == null) $grps = []; array_unshift($grps, $conf['defaultgroup']); $grps = array_unique($grps); $hash = auth_cryptPassword($clear); - $userdata = compact('user', 'clear', 'hash', 'name', 'mail'); + $userdata = ['user' => $user, 'clear' => $clear, 'hash' => $hash, 'name' => $name, 'mail' => $mail]; // action protected by transaction $this->pdo->beginTransaction(); @@ -260,19 +220,19 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin // create all groups that do not exist, the refetch the groups $allgroups = $this->selectGroups(); - foreach ($grps as $group) { - if (!isset($allgroups[$group])) { - $ok = $this->addGroup($group); - if ($ok === false) goto FAIL; - } + foreach ($grps as $group) { + if (!isset($allgroups[$group])) { + $ok = $this->addGroup($group); + if ($ok === false) goto FAIL; } + } $allgroups = $this->selectGroups(); // add user to the groups - foreach ($grps as $group) { - $ok = $this->joinGroup($userdata, $allgroups[$group]); - if ($ok === false) goto FAIL; - } + foreach ($grps as $group) { + $ok = $this->joinGroup($userdata, $allgroups[$group]); + if ($ok === false) goto FAIL; + } } $this->pdo->commit(); return true; @@ -302,67 +262,67 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin unset($olddata['grps']); // changing the user name? - if (isset($changes['user'])) { - if ($this->getUserData($changes['user'], false)) goto FAIL; - $params = $olddata; - $params['newlogin'] = $changes['user']; + if (isset($changes['user'])) { + if ($this->getUserData($changes['user'], false)) goto FAIL; + $params = $olddata; + $params['newlogin'] = $changes['user']; - $ok = $this->query($this->getConf('update-user-login'), $params); - if ($ok === false) goto FAIL; - } + $ok = $this->query($this->getConf('update-user-login'), $params); + if ($ok === false) goto FAIL; + } // changing the password? - if (isset($changes['pass'])) { - $params = $olddata; - $params['clear'] = $changes['pass']; - $params['hash'] = auth_cryptPassword($changes['pass']); + if (isset($changes['pass'])) { + $params = $olddata; + $params['clear'] = $changes['pass']; + $params['hash'] = auth_cryptPassword($changes['pass']); - $ok = $this->query($this->getConf('update-user-pass'), $params); - if ($ok === false) goto FAIL; - } + $ok = $this->query($this->getConf('update-user-pass'), $params); + if ($ok === false) goto FAIL; + } // changing info? - if (isset($changes['mail']) || isset($changes['name'])) { - $params = $olddata; - if (isset($changes['mail'])) $params['mail'] = $changes['mail']; - if (isset($changes['name'])) $params['name'] = $changes['name']; + if (isset($changes['mail']) || isset($changes['name'])) { + $params = $olddata; + if (isset($changes['mail'])) $params['mail'] = $changes['mail']; + if (isset($changes['name'])) $params['name'] = $changes['name']; - $ok = $this->query($this->getConf('update-user-info'), $params); - if ($ok === false) goto FAIL; - } + $ok = $this->query($this->getConf('update-user-info'), $params); + if ($ok === false) goto FAIL; + } // changing groups? - if (isset($changes['grps'])) { - $allgroups = $this->selectGroups(); - - // remove membership for previous groups - foreach ($oldgroups as $group) { - if (!in_array($group, $changes['grps']) && isset($allgroups[$group])) { - $ok = $this->leaveGroup($olddata, $allgroups[$group]); - if ($ok === false) goto FAIL; - } + if (isset($changes['grps'])) { + $allgroups = $this->selectGroups(); + + // remove membership for previous groups + foreach ($oldgroups as $group) { + if (!in_array($group, $changes['grps']) && isset($allgroups[$group])) { + $ok = $this->leaveGroup($olddata, $allgroups[$group]); + if ($ok === false) goto FAIL; } + } - // create all new groups that are missing - $added = 0; - foreach ($changes['grps'] as $group) { - if (!isset($allgroups[$group])) { - $ok = $this->addGroup($group); - if ($ok === false) goto FAIL; - $added++; - } + // create all new groups that are missing + $added = 0; + foreach ($changes['grps'] as $group) { + if (!isset($allgroups[$group])) { + $ok = $this->addGroup($group); + if ($ok === false) goto FAIL; + $added++; } - // reload group info - if ($added > 0) $allgroups = $this->selectGroups(); - - // add membership for new groups - foreach ($changes['grps'] as $group) { - if (!in_array($group, $oldgroups)) { - $ok = $this->joinGroup($olddata, $allgroups[$group]); - if ($ok === false) goto FAIL; - } + } + // reload group info + if ($added > 0) $allgroups = $this->selectGroups(); + + // add membership for new groups + foreach ($changes['grps'] as $group) { + if (!in_array($group, $oldgroups)) { + $ok = $this->joinGroup($olddata, $allgroups[$group]); + if ($ok === false) goto FAIL; } } + } } $this->pdo->commit(); @@ -406,10 +366,10 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin public function retrieveUsers($start = 0, $limit = -1, $filter = null) { if ($limit < 0) $limit = 10000; // we don't support no limit - if (is_null($filter)) $filter = array(); + if (is_null($filter)) $filter = []; if (isset($filter['grps'])) $filter['group'] = $filter['grps']; - foreach (array('user', 'name', 'mail', 'group') as $key) { + foreach (['user', 'name', 'mail', 'group'] as $key) { if (!isset($filter[$key])) { $filter[$key] = '%'; } else { @@ -421,13 +381,13 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $filter['limit'] = (int)$limit; $result = $this->query($this->getConf('list-users'), $filter); - if (!$result) return array(); - $users = array(); + if (!$result) return []; + $users = []; if (is_array($result)) { foreach ($result as $row) { if (!isset($row['user'])) { $this->debugMsg("list-users statement did not return 'user' attribute", -1, __LINE__); - return array(); + return []; } $users[] = $this->getUserData($row['user']); } @@ -443,12 +403,12 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin * @param array $filter array of field/pattern pairs, empty array for no filter * @return int */ - public function getUserCount($filter = array()) + public function getUserCount($filter = []) { - if (is_null($filter)) $filter = array(); + if (is_null($filter)) $filter = []; if (isset($filter['grps'])) $filter['group'] = $filter['grps']; - foreach (array('user', 'name', 'mail', 'group') as $key) { + foreach (['user', 'name', 'mail', 'group'] as $key) { if (!isset($filter[$key])) { $filter[$key] = '%'; } else { @@ -473,7 +433,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { $sql = $this->getConf('insert-group'); - $result = $this->query($sql, array(':group' => $group)); + $result = $this->query($sql, [':group' => $group]); $this->clearGroupCache(); if ($result === false) return false; return true; @@ -491,7 +451,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin public function retrieveGroups($start = 0, $limit = 0) { $groups = array_keys($this->selectGroups()); - if ($groups === false) return array(); + if ($groups === false) return []; if (!$limit) { return array_splice($groups, $start); @@ -510,7 +470,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { $sql = $this->getConf('select-user'); - $result = $this->query($sql, array(':user' => $user)); + $result = $this->query($sql, [':user' => $user]); if (!$result) return false; if (count($result) > 1) { @@ -525,7 +485,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $this->debugMsg("Statement did not return 'user' attribute", -1, __LINE__); $dataok = false; } - if (!isset($data['hash']) && !isset($data['clear']) && !$this->checkConfig(array('check-pass'))) { + if (!isset($data['hash']) && !isset($data['clear']) && !$this->checkConfig(['check-pass'])) { $this->debugMsg("Statement did not return 'clear' or 'hash' attribute", -1, __LINE__); $dataok = false; } @@ -557,11 +517,11 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $allgroups = $this->selectGroups(); // remove group memberships (ignore errors) - foreach ($userdata['grps'] as $group) { - if (isset($allgroups[$group])) { - $this->leaveGroup($userdata, $allgroups[$group]); - } + foreach ($userdata['grps'] as $group) { + if (isset($allgroups[$group])) { + $this->leaveGroup($userdata, $allgroups[$group]); } + } $ok = $this->query($this->getConf('delete-user'), $userdata); if ($ok === false) goto FAIL; @@ -587,7 +547,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $result = $this->query($sql, $userdata); if ($result === false) return false; - $groups = array($conf['defaultgroup']); // always add default config + $groups = [$conf['defaultgroup']]; // always add default config if (is_array($result)) { foreach ($result as $row) { if (!isset($row['group'])) { @@ -618,7 +578,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $result = $this->query($sql); if ($result === false) return false; - $groups = array(); + $groups = []; if (is_array($result)) { foreach ($result as $row) { if (!isset($row['group'])) { @@ -685,7 +645,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin * @param array $arguments Named parameters to be used in the statement * @return array|int|bool The result as associative array for SELECTs, affected rows for others, false on error */ - protected function query($sql, $arguments = array()) + protected function query($sql, $arguments = []) { $sql = trim($sql); if (empty($sql)) { @@ -694,7 +654,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin } // execute - $params = array(); + $params = []; $sth = $this->pdo->prepare($sql); $result = false; try { @@ -703,7 +663,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin if (is_array($value)) continue; if (is_object($value)) continue; if ($key[0] != ':') $key = ":$key"; // prefix with colon if needed - if (strpos($sql, $key) === false) continue; // skip if parameter is missing + if (strpos($sql, (string) $key) === false) continue; // skip if parameter is missing if (is_int($value)) { $sth->bindValue($key, $value, PDO::PARAM_INT); @@ -742,7 +702,6 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin $this->debugMsg("SQL: <pre>$dsql</pre>", -1, $line); } $sth->closeCursor(); - $sth = null; return $result; } diff --git a/lib/plugins/authpdo/conf/default.php b/lib/plugins/authpdo/conf/default.php index 138ca2f10..de15979b3 100644 --- a/lib/plugins/authpdo/conf/default.php +++ b/lib/plugins/authpdo/conf/default.php @@ -1,4 +1,5 @@ <?php + /** * Default settings for the authpdo plugin * diff --git a/lib/plugins/authpdo/conf/metadata.php b/lib/plugins/authpdo/conf/metadata.php index 34e60a40e..bf427e5ba 100644 --- a/lib/plugins/authpdo/conf/metadata.php +++ b/lib/plugins/authpdo/conf/metadata.php @@ -1,4 +1,5 @@ <?php + /** * Options for the authpdo plugin * diff --git a/lib/plugins/authplain/auth.php b/lib/plugins/authplain/auth.php index e0c1b9291..370e6cfa0 100644 --- a/lib/plugins/authplain/auth.php +++ b/lib/plugins/authplain/auth.php @@ -1,5 +1,6 @@ <?php +use dokuwiki\Extension\AuthPlugin; use dokuwiki\Logger; use dokuwiki\Utf8\Sort; @@ -11,13 +12,13 @@ use dokuwiki\Utf8\Sort; * @author Chris Smith <chris@jalakai.co.uk> * @author Jan Schumann <js@schumann-it.com> */ -class auth_plugin_authplain extends DokuWiki_Auth_Plugin +class auth_plugin_authplain extends AuthPlugin { /** @var array user cache */ - protected $users = null; + protected $users; /** @var array filter pattern */ - protected $pattern = array(); + protected $pattern = []; /** @var bool safe version of preg_split */ protected $pregsplit_safe = false; @@ -90,7 +91,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin public function getUserData($user, $requireGroups = true) { if ($this->users === null) $this->loadUserData(); - return isset($this->users[$user]) ? $this->users[$user] : false; + return $this->users[$user] ?? false; } /** @@ -107,11 +108,11 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin */ protected function createUserLine($user, $pass, $name, $mail, $grps) { - $groups = join(',', $grps); - $userline = array($user, $pass, $name, $mail, $groups); + $groups = implode(',', $grps); + $userline = [$user, $pass, $name, $mail, $groups]; $userline = str_replace('\\', '\\\\', $userline); // escape \ as \\ $userline = str_replace(':', '\\:', $userline); // escape : as \: - $userline = join(':', $userline)."\n"; + $userline = implode(':', $userline) . "\n"; return $userline; } @@ -148,7 +149,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin $pass = auth_cryptPassword($pwd); // set default group if no groups specified - if (!is_array($grps)) $grps = array($conf['defaultgroup']); + if (!is_array($grps)) $grps = [$conf['defaultgroup']]; // prepare user line $userline = $this->createUserLine($user, $pass, $name, $mail, $grps); @@ -158,7 +159,12 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin return null; } - $this->users[$user] = compact('pass', 'name', 'mail', 'grps'); + $this->users[$user] = [ + 'pass' => $pass, + 'name' => $name, + 'mail' => $mail, + 'grps' => $grps + ]; return $pwd; } @@ -187,7 +193,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin return false; } - if (!is_array($changes) || !count($changes)) return true; + if (!is_array($changes) || $changes === []) return true; // update userinfo with new data, remembering to encrypt any password $newuser = $user; @@ -208,14 +214,14 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin $userinfo['grps'] ); - if (!io_replaceInFile($config_cascade['plainauth.users']['default'], '/^'.$user.':/', $userline, true)) { + if (!io_replaceInFile($config_cascade['plainauth.users']['default'], '/^' . $user . ':/', $userline, true)) { msg('There was an error modifying your user data. You may need to register again.', -1); // FIXME, io functions should be fail-safe so existing data isn't lost $ACT = 'register'; return false; } - if(isset($this->users[$user])) unset($this->users[$user]); + if (isset($this->users[$user])) unset($this->users[$user]); $this->users[$newuser] = $userinfo; return true; } @@ -231,11 +237,11 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { global $config_cascade; - if (!is_array($users) || empty($users)) return 0; + if (!is_array($users) || $users === []) return 0; if ($this->users === null) $this->loadUserData(); - $deleted = array(); + $deleted = []; foreach ($users as $user) { // don't delete protected users if (!empty($this->users[$user]['protected'])) { @@ -245,9 +251,9 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin if (isset($this->users[$user])) $deleted[] = preg_quote($user, '/'); } - if (empty($deleted)) return 0; + if ($deleted === []) return 0; - $pattern = '/^('.join('|', $deleted).'):/'; + $pattern = '/^(' . implode('|', $deleted) . '):/'; if (!io_deleteFromFile($config_cascade['plainauth.users']['default'], $pattern, true)) { msg($this->getLang('writefail'), -1); return 0; @@ -268,12 +274,12 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin * @param array $filter * @return int */ - public function getUserCount($filter = array()) + public function getUserCount($filter = []) { if ($this->users === null) $this->loadUserData(); - if (!count($filter)) return count($this->users); + if ($filter === []) return count($this->users); $count = 0; $this->constructPattern($filter); @@ -295,7 +301,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin * @param array $filter array of field/pattern pairs * @return array userinfo (refer getUserData for internal userinfo details) */ - public function retrieveUsers($start = 0, $limit = 0, $filter = array()) + public function retrieveUsers($start = 0, $limit = 0, $filter = []) { if ($this->users === null) $this->loadUserData(); @@ -304,7 +310,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin $i = 0; $count = 0; - $out = array(); + $out = []; $this->constructPattern($filter); foreach ($this->users as $user => $info) { @@ -334,12 +340,12 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin $groups = []; if ($this->users === null) $this->loadUserData(); - foreach($this->users as $user => $info) { + foreach ($this->users as $info) { $groups = array_merge($groups, array_diff($info['grps'], $groups)); } Sort::ksort($groups); - if($limit > 0) { + if ($limit > 0) { return array_splice($groups, $start, $limit); } return array_splice($groups, $start); @@ -404,7 +410,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin */ protected function readUserFile($file) { - $users = array(); + $users = []; if (!file_exists($file)) return $users; $lines = file($file); @@ -436,7 +442,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin protected function splitUserData($line) { $data = preg_split('/(?<![^\\\\]\\\\)\:/', $line, 5); // allow for : escaped as \: - if(count($data) < 5) { + if (count($data) < 5) { $data = array_pad($data, 5, ''); Logger::error('User line with less than 5 fields. Possibly corruption in your user file', $data); } @@ -459,8 +465,8 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin if (!preg_match($pattern, $user)) return false; } elseif ($item == 'grps') { if (!count(preg_grep($pattern, $info['grps']))) return false; - } else { - if (!preg_match($pattern, $info[$item])) return false; + } elseif (!preg_match($pattern, $info[$item])) { + return false; } } return true; @@ -473,9 +479,9 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin */ protected function constructPattern($filter) { - $this->pattern = array(); + $this->pattern = []; foreach ($filter as $item => $pattern) { - $this->pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters + $this->pattern[$item] = '/' . str_replace('/', '\/', $pattern) . '/i'; // allow regex characters } } } diff --git a/lib/plugins/cli.php b/lib/plugins/cli.php index 5bf8da91e..e75f700a0 100644 --- a/lib/plugins/cli.php +++ b/lib/plugins/cli.php @@ -1,4 +1,9 @@ <?php -\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction( - 'Autoloading', 1, 'require(' . basename(__FILE__) . ')' + +use dokuwiki\Debug\DebugHelper; + +DebugHelper::dbgDeprecatedFunction( + 'Autoloading', + 1, + 'require(' . basename(__FILE__) . ')' ); diff --git a/lib/plugins/config/admin.php b/lib/plugins/config/admin.php index 568fc1846..a77c787f5 100644 --- a/lib/plugins/config/admin.php +++ b/lib/plugins/config/admin.php @@ -1,4 +1,5 @@ <?php + /** * Configuration Manager admin plugin * @@ -7,6 +8,7 @@ * @author Ben Coburn <btcoburn@silicodon.net> */ +use dokuwiki\Extension\AdminPlugin; use dokuwiki\plugin\config\core\Configuration; use dokuwiki\plugin\config\core\Setting\Setting; use dokuwiki\plugin\config\core\Setting\SettingFieldset; @@ -16,9 +18,9 @@ use dokuwiki\plugin\config\core\Setting\SettingHidden; * All DokuWiki plugins to extend the admin function * need to inherit from this class */ -class admin_plugin_config extends DokuWiki_Admin_Plugin { - - const IMGDIR = DOKU_BASE . 'lib/plugins/config/images/'; +class admin_plugin_config extends AdminPlugin +{ + protected const IMGDIR = DOKU_BASE . 'lib/plugins/config/images/'; /** @var Configuration */ protected $configuration; @@ -33,33 +35,34 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { /** * handle user request */ - public function handle() { + public function handle() + { global $ID, $INPUT; // always initialize the configuration $this->configuration = new Configuration(); - if(!$INPUT->bool('save') || !checkSecurityToken()) { + if (!$INPUT->bool('save') || !checkSecurityToken()) { return; } // don't go any further if the configuration is locked - if($this->configuration->isLocked()) return; + if ($this->configuration->isLocked()) return; // update settings and redirect of successful $ok = $this->configuration->updateSettings($INPUT->arr('config')); - if($ok) { // no errors + if ($ok) { // no errors try { - if($this->configuration->hasChanged()) { + if ($this->configuration->hasChanged()) { $this->configuration->save(); } else { $this->configuration->touch(); } msg($this->getLang('updated'), 1); - } catch(Exception $e) { + } catch (Exception $e) { msg($this->getLang('error'), -1); } - send_redirect(wl($ID, array('do' => 'admin', 'page' => 'config'), true, '&')); + send_redirect(wl($ID, ['do' => 'admin', 'page' => 'config'], true, '&')); } else { $this->hasErrors = true; msg($this->getLang('error'), -1); @@ -69,7 +72,8 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { /** * output appropriate html */ - public function html() { + public function html() + { $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here. global $lang; global $ID; @@ -80,7 +84,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { echo '<div id="config__manager">'; - if($this->configuration->isLocked()) { + if ($this->configuration->isLocked()) { echo '<div class="info">' . $this->getLang('locked') . '</div>'; } @@ -95,22 +99,22 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { $in_fieldset = false; $first_plugin_fieldset = true; $first_template_fieldset = true; - foreach($this->configuration->getSettings() as $setting) { - if(is_a($setting, SettingHidden::class)) { + foreach ($this->configuration->getSettings() as $setting) { + if ($setting instanceof SettingHidden) { continue; - } else if(is_a($setting, settingFieldset::class)) { + } elseif ($setting instanceof SettingFieldset) { // config setting group - if($in_fieldset) { + if ($in_fieldset) { echo '</table>'; echo '</div>'; echo '</fieldset>'; } else { $in_fieldset = true; } - if($first_plugin_fieldset && $setting->getType() == 'plugin') { + if ($first_plugin_fieldset && $setting->getType() == 'plugin') { $this->printH1('plugin_settings', $this->getLang('_header_plugin')); $first_plugin_fieldset = false; - } else if($first_template_fieldset && $setting->getType() == 'template') { + } elseif ($first_template_fieldset && $setting->getType() == 'template') { $this->printH1('template_settings', $this->getLang('_header_template')); $first_template_fieldset = false; } @@ -120,7 +124,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { echo '<table class="inline">'; } else { // config settings - list($label, $input) = $setting->html($this, $this->hasErrors); + [$label, $input] = $setting->html($this, $this->hasErrors); $class = $setting->isDefault() ? ' class="default"' @@ -145,13 +149,13 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { echo '</table>'; echo '</div>'; - if($in_fieldset) { + if ($in_fieldset) { echo '</fieldset>'; } // show undefined settings list $undefined_settings = $this->configuration->getUndefined(); - if($allow_debug && !empty($undefined_settings)) { + if ($allow_debug && !empty($undefined_settings)) { /** * Callback for sorting settings * @@ -159,7 +163,8 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { * @param Setting $b * @return int if $a is lower/equal/higher than $b */ - function settingNaturalComparison($a, $b) { + function settingNaturalComparison($a, $b) + { return strnatcmp($a->getKey(), $b->getKey()); } @@ -168,8 +173,8 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { echo '<fieldset>'; echo '<div class="table">'; echo '<table class="inline">'; - foreach($undefined_settings as $setting) { - list($label, $input) = $setting->html($this); + foreach ($undefined_settings as $setting) { + [$label, $input] = $setting->html($this); echo '<tr>'; echo '<td class="label">' . $label . '</td>'; echo '<td>' . $input . '</td>'; @@ -185,7 +190,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { echo '<input type="hidden" name="do" value="admin" />'; echo '<input type="hidden" name="page" value="config" />'; - if(!$this->configuration->isLocked()) { + if (!$this->configuration->isLocked()) { echo '<input type="hidden" name="save" value="1" />'; echo '<button type="submit" name="submit" accesskey="s">' . $lang['btn_save'] . '</button>'; echo '<button type="reset">' . $lang['btn_reset'] . '</button>'; @@ -200,9 +205,10 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { /** * @param bool $prompts */ - public function setupLocale($prompts = false) { + public function setupLocale($prompts = false) + { parent::setupLocale(); - if(!$prompts || $this->promptsLocalized) return; + if (!$prompts || $this->promptsLocalized) return; $this->lang = array_merge($this->lang, $this->configuration->getLangs()); $this->promptsLocalized = true; } @@ -214,17 +220,18 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { * * @return array */ - public function getTOC() { + public function getTOC() + { $this->setupLocale(true); $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here. - $toc = array(); + $toc = []; $check = false; // gather settings data into three sub arrays $labels = ['dokuwiki' => [], 'plugin' => [], 'template' => []]; - foreach($this->configuration->getSettings() as $setting) { - if(is_a($setting, SettingFieldset::class)) { + foreach ($this->configuration->getSettings() as $setting) { + if ($setting instanceof SettingFieldset) { $labels[$setting->getType()][] = $setting; } } @@ -234,8 +241,8 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { $toc[] = html_mktocitem(sectionID($title, $check), $title, 1); // main entries - foreach(['dokuwiki', 'plugin', 'template'] as $section) { - if(empty($labels[$section])) continue; // no entries, skip + foreach (['dokuwiki', 'plugin', 'template'] as $section) { + if (empty($labels[$section])) continue; // no entries, skip // create main header $toc[] = html_mktocitem( @@ -245,7 +252,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { ); // create sub headers - foreach($labels[$section] as $setting) { + foreach ($labels[$section] as $setting) { /** @var SettingFieldset $setting */ $name = $setting->prompt($this); $toc[] = html_mktocitem($setting->getKey(), $name, 2); @@ -253,7 +260,7 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { } // undefined settings if allowed - if(count($this->configuration->getUndefined()) && $allow_debug) { + if (count($this->configuration->getUndefined()) && $allow_debug) { $toc[] = html_mktocitem('undefined_settings', $this->getLang('_header_undefined'), 1); } @@ -264,7 +271,8 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { * @param string $id * @param string $text */ - protected function printH1($id, $text) { + protected function printH1($id, $text) + { echo '<h1 id="' . $id . '">' . $text . '</h1>'; } @@ -276,8 +284,9 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin { * @param string $key * @param string $value */ - public function addLang($key, $value) { - if(!$this->localised) $this->setupLocale(); + public function addLang($key, $value) + { + if (!$this->localised) $this->setupLocale(); $this->lang[$key] = $value; } } diff --git a/lib/plugins/config/core/ConfigParser.php b/lib/plugins/config/core/ConfigParser.php index fd9ff2ec6..aae44d983 100644 --- a/lib/plugins/config/core/ConfigParser.php +++ b/lib/plugins/config/core/ConfigParser.php @@ -10,7 +10,8 @@ namespace dokuwiki\plugin\config\core; * * @author Chris Smith <chris@jalakai.co.uk> */ -class ConfigParser { +class ConfigParser +{ /** @var string variable to parse from the file */ protected $varname = 'conf'; /** @var string the key to mark sub arrays */ @@ -24,36 +25,38 @@ class ConfigParser { * @param string $file * @return array */ - public function parse($file) { - if(!file_exists($file)) return array(); + public function parse($file) + { + if (!file_exists($file)) return []; - $config = array(); + $config = []; $contents = @php_strip_whitespace($file); // fallback to simply including the file #3271 - if($contents === null) { + if ($contents === null) { $conf = []; include $file; return $conf; } $pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s'; - $matches = array(); + $matches = []; preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER); + $counter = count($matches); - for($i = 0; $i < count($matches); $i++) { + for ($i = 0; $i < $counter; $i++) { $value = $matches[$i][2]; // merge multi-dimensional array indices using the keymarker $key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]); // handle arrays - if(preg_match('/^array ?\((.*)\)/', $value, $match)) { + if (preg_match('/^array ?\((.*)\)/', $value, $match)) { $arr = explode(',', $match[1]); // remove quotes from quoted strings & unescape escaped data $len = count($arr); - for($j = 0; $j < $len; $j++) { + for ($j = 0; $j < $len; $j++) { $arr[$j] = trim($arr[$j]); $arr[$j] = $this->readValue($arr[$j]); } @@ -75,17 +78,18 @@ class ConfigParser { * @param string $value * @return bool|string */ - protected function readValue($value) { + protected function readValue($value) + { $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s'; - $unescape_pairs = array( + $unescape_pairs = [ '\\\\' => '\\', '\\\'' => '\'', '\\"' => '"' - ); + ]; - if($value == 'true') { + if ($value == 'true') { $value = true; - } elseif($value == 'false') { + } elseif ($value == 'false') { $value = false; } else { // remove quotes from quoted strings & unescape escaped data @@ -94,5 +98,4 @@ class ConfigParser { } return $value; } - } diff --git a/lib/plugins/config/core/Configuration.php b/lib/plugins/config/core/Configuration.php index c58645c5b..d2c63e3d4 100644 --- a/lib/plugins/config/core/Configuration.php +++ b/lib/plugins/config/core/Configuration.php @@ -15,14 +15,14 @@ use dokuwiki\plugin\config\core\Setting\SettingUndefined; * @author Ben Coburn <btcoburn@silicodon.net> * @author Andreas Gohr <andi@splitbrain.org> */ -class Configuration { - - const KEYMARKER = '____'; +class Configuration +{ + public const KEYMARKER = '____'; /** @var Setting[] metadata as array of Settings objects */ - protected $settings = array(); + protected $settings = []; /** @var Setting[] undefined and problematic settings */ - protected $undefined = array(); + protected $undefined = []; /** @var array all metadata */ protected $metadata; @@ -44,7 +44,8 @@ class Configuration { /** * ConfigSettings constructor. */ - public function __construct() { + public function __construct() + { $this->loader = new Loader(new ConfigParser()); $this->writer = new Writer(); @@ -61,7 +62,8 @@ class Configuration { * * @return Setting[] */ - public function getSettings() { + public function getSettings() + { return $this->settings; } @@ -70,7 +72,8 @@ class Configuration { * * @return Setting[] */ - public function getUndefined() { + public function getUndefined() + { return $this->undefined; } @@ -79,7 +82,8 @@ class Configuration { * * @return bool */ - public function hasChanged() { + public function hasChanged() + { return $this->changed; } @@ -88,7 +92,8 @@ class Configuration { * * @return bool */ - public function isLocked() { + public function isLocked() + { return $this->writer->isLocked(); } @@ -98,15 +103,16 @@ class Configuration { * @param array $input as posted * @return bool true if all updates went through, false on errors */ - public function updateSettings($input) { + public function updateSettings($input) + { $ok = true; - foreach($this->settings as $key => $obj) { - $value = isset($input[$key]) ? $input[$key] : null; - if($obj->update($value)) { + foreach ($this->settings as $key => $obj) { + $value = $input[$key] ?? null; + if ($obj->update($value)) { $this->changed = true; } - if($obj->hasError()) $ok = false; + if ($obj->hasError()) $ok = false; } return $ok; @@ -120,7 +126,8 @@ class Configuration { * * @throws \Exception */ - public function save() { + public function save() + { // only save the undefined settings that have not been handled in settings $undefined = array_diff_key($this->undefined, $this->settings); $this->writer->save(array_merge($this->settings, $undefined)); @@ -131,7 +138,8 @@ class Configuration { * * @throws \Exception */ - public function touch() { + public function touch() + { $this->writer->touch(); } @@ -140,32 +148,34 @@ class Configuration { * * @return array */ - public function getLangs() { + public function getLangs() + { return $this->loader->loadLangs(); } /** * Initalizes the $settings and $undefined properties */ - protected function initSettings() { - $keys = array_merge( - array_keys($this->metadata), - array_keys($this->default), - array_keys($this->local), - array_keys($this->protected) - ); + protected function initSettings() + { + $keys = [ + ...array_keys($this->metadata), + ...array_keys($this->default), + ...array_keys($this->local), + ...array_keys($this->protected) + ]; $keys = array_unique($keys); - foreach($keys as $key) { + foreach ($keys as $key) { $obj = $this->instantiateClass($key); - if($obj->shouldHaveDefault() && !isset($this->default[$key])) { + if ($obj->shouldHaveDefault() && !isset($this->default[$key])) { $this->undefined[$key] = new SettingNoDefault($key); } - $d = isset($this->default[$key]) ? $this->default[$key] : null; - $l = isset($this->local[$key]) ? $this->local[$key] : null; - $p = isset($this->protected[$key]) ? $this->protected[$key] : null; + $d = $this->default[$key] ?? null; + $l = $this->local[$key] ?? null; + $p = $this->protected[$key] ?? null; $obj->initialize($d, $l, $p); } @@ -179,8 +189,9 @@ class Configuration { * @param string $key * @return Setting */ - protected function instantiateClass($key) { - if(isset($this->metadata[$key])) { + protected function instantiateClass($key) + { + if (isset($this->metadata[$key])) { $param = $this->metadata[$key]; $class = $this->determineClassName(array_shift($param), $key); // first param is class $obj = new $class($key, $param); @@ -199,14 +210,15 @@ class Configuration { * @param string $key the settings key * @return string */ - protected function determineClassName($class, $key) { + protected function determineClassName($class, $key) + { // try namespaced class first - if(is_string($class)) { + if (is_string($class)) { $modern = str_replace('_', '', ucwords($class, '_')); $modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern; - if($modern && class_exists($modern)) return $modern; + if ($modern && class_exists($modern)) return $modern; // try class as given - if(class_exists($class)) return $class; + if (class_exists($class)) return $class; // class wasn't found add to errors $this->undefined[$key] = new SettingNoKnownClass($key); } else { @@ -215,5 +227,4 @@ class Configuration { } return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting'; } - } diff --git a/lib/plugins/config/core/Loader.php b/lib/plugins/config/core/Loader.php index e4d7b50af..c9dbec95d 100644 --- a/lib/plugins/config/core/Loader.php +++ b/lib/plugins/config/core/Loader.php @@ -10,7 +10,8 @@ use dokuwiki\Extension\Event; * Loads configuration meta data and settings from the various files. Honors the * configuration cascade and installed plugins. */ -class Loader { +class Loader +{ /** @var ConfigParser */ protected $parser; @@ -24,7 +25,8 @@ class Loader { * @param ConfigParser $parser * @triggers PLUGIN_CONFIG_PLUGINLIST */ - public function __construct(ConfigParser $parser) { + public function __construct(ConfigParser $parser) + { global $conf; $this->parser = $parser; $this->plugins = plugin_list(); @@ -40,13 +42,14 @@ class Loader { * * @return array */ - public function loadMeta() { + public function loadMeta() + { // load main file - $meta = array(); + $meta = []; include DOKU_PLUGIN . 'config/settings/config.metadata.php'; // plugins - foreach($this->plugins as $plugin) { + foreach ($this->plugins as $plugin) { $meta = array_merge( $meta, $this->loadExtensionMeta( @@ -81,7 +84,7 @@ class Loader { { // initialize array - $conf = array(); + $conf = []; // plugins foreach ($this->plugins as $plugin) { @@ -120,11 +123,12 @@ class Loader { * * @return array */ - public function loadLangs() { - $lang = array(); + public function loadLangs() + { + $lang = []; // plugins - foreach($this->plugins as $plugin) { + foreach ($this->plugins as $plugin) { $lang = array_merge( $lang, $this->loadExtensionLang( @@ -153,7 +157,8 @@ class Loader { * * @return array */ - public function loadLocal() { + public function loadLocal() + { global $config_cascade; return $this->loadConfigs($config_cascade['main']['local']); } @@ -163,7 +168,8 @@ class Loader { * * @return array */ - public function loadProtected() { + public function loadProtected() + { global $config_cascade; return $this->loadConfigs($config_cascade['main']['protected']); } @@ -174,9 +180,10 @@ class Loader { * @param string[] $files paths to config php's * @return array */ - protected function loadConfigs($files) { - $conf = array(); - foreach($files as $file) { + protected function loadConfigs($files) + { + $conf = []; + foreach ($files as $file) { $conf = array_merge($conf, $this->parser->parse($file)); } return $conf; @@ -192,20 +199,21 @@ class Loader { * @param string $extname name of the extension * @return array */ - protected function loadExtensionMeta($file, $type, $extname) { - if(!file_exists($file)) return array(); + protected function loadExtensionMeta($file, $type, $extname) + { + if (!file_exists($file)) return []; $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER; // include file - $meta = array(); + $meta = []; include $file; - if(empty($meta)) return array(); + if ($meta === []) return []; // read data - $data = array(); + $data = []; $data[$prefix . $type . '_settings_name'] = ['fieldset']; - foreach($meta as $key => $value) { - if($value[0] == 'fieldset') continue; //plugins only get one fieldset + foreach ($meta as $key => $value) { + if ($value[0] == 'fieldset') continue; //plugins only get one fieldset $data[$prefix . $key] = $value; } @@ -222,17 +230,18 @@ class Loader { * @param string $extname name of the extension * @return array */ - protected function loadExtensionConf($file, $type, $extname) { - if(!file_exists($file)) return array(); + protected function loadExtensionConf($file, $type, $extname) + { + if (!file_exists($file)) return []; $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER; // parse file $conf = $this->parser->parse($file); - if(empty($conf)) return array(); + if (empty($conf)) return []; // read data - $data = array(); - foreach($conf as $key => $value) { + $data = []; + foreach ($conf as $key => $value) { $data[$prefix . $key] = $value; } @@ -247,23 +256,24 @@ class Loader { * @param string $extname name of the extension * @return array */ - protected function loadExtensionLang($dir, $type, $extname) { + protected function loadExtensionLang($dir, $type, $extname) + { global $conf; $ll = $conf['lang']; $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER; // include files - $lang = array(); - if(file_exists($dir . 'lang/en/settings.php')) { + $lang = []; + if (file_exists($dir . 'lang/en/settings.php')) { include $dir . 'lang/en/settings.php'; } - if($ll != 'en' && file_exists($dir . 'lang/' . $ll . '/settings.php')) { + if ($ll != 'en' && file_exists($dir . 'lang/' . $ll . '/settings.php')) { include $dir . 'lang/' . $ll . '/settings.php'; } // set up correct keys - $strings = array(); - foreach($lang as $key => $val) { + $strings = []; + foreach ($lang as $key => $val) { $strings[$prefix . $key] = $val; } diff --git a/lib/plugins/config/core/Setting/Setting.php b/lib/plugins/config/core/Setting/Setting.php index bbf048a85..cc22cf91a 100644 --- a/lib/plugins/config/core/Setting/Setting.php +++ b/lib/plugins/config/core/Setting/Setting.php @@ -7,24 +7,25 @@ use dokuwiki\plugin\config\core\Configuration; /** * Class Setting */ -class Setting { +class Setting +{ /** @var string unique identifier of this setting */ protected $key = ''; /** @var mixed the default value of this setting */ - protected $default = null; + protected $default; /** @var mixed the local value of this setting */ - protected $local = null; + protected $local; /** @var mixed the protected value of this setting */ - protected $protected = null; + protected $protected; /** @var array valid alerts, images matching the alerts are in the plugin's images directory */ - static protected $validCautions = array('warning', 'danger', 'security'); + protected static $validCautions = ['warning', 'danger', 'security']; protected $pattern = ''; protected $error = false; // only used by those classes which error check - protected $input = null; // only used by those classes which error check - protected $caution = null; // used by any setting to provide an alert along with the setting + protected $input; // only used by those classes which error check + protected $caution; // used by any setting to provide an alert along with the setting /** * Constructor. @@ -36,11 +37,12 @@ class Setting { * @param string $key * @param array|null $params array with metadata of setting */ - public function __construct($key, $params = null) { + public function __construct($key, $params = null) + { $this->key = $key; - if(is_array($params)) { - foreach($params as $property => $value) { + if (is_array($params)) { + foreach ($params as $property => $value) { $property = trim($property, '_'); // we don't use underscores anymore $this->$property = $value; } @@ -57,7 +59,8 @@ class Setting { * @param mixed $local local setting value * @param mixed $protected protected setting value */ - public function initialize($default = null, $local = null, $protected = null) { + public function initialize($default = null, $local = null, $protected = null) + { $this->default = $this->cleanValue($default); $this->local = $this->cleanValue($local); $this->protected = $this->cleanValue($protected); @@ -71,16 +74,17 @@ class Setting { * @param mixed $input the new value * @return boolean true if changed, false otherwise */ - public function update($input) { - if(is_null($input)) return false; - if($this->isProtected()) return false; + public function update($input) + { + if (is_null($input)) return false; + if ($this->isProtected()) return false; $input = $this->cleanValue($input); $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; // validate new value - if($this->pattern && !preg_match($this->pattern, $input)) { + if ($this->pattern && !preg_match($this->pattern, $input)) { $this->error = true; $this->input = $input; return false; @@ -104,7 +108,8 @@ class Setting { * @param mixed $value * @return mixed */ - protected function cleanValue($value) { + protected function cleanValue($value) + { return $value; } @@ -113,7 +118,8 @@ class Setting { * * @return bool */ - public function shouldHaveDefault() { + public function shouldHaveDefault() + { return true; } @@ -122,7 +128,8 @@ class Setting { * * @return string */ - public function getKey() { + public function getKey() + { return $this->key; } @@ -132,10 +139,11 @@ class Setting { * @param bool $url link to dokuwiki.org manual? * @return string */ - public function getPrettyKey($url = true) { + public function getPrettyKey($url = true) + { $out = str_replace(Configuration::KEYMARKER, "»", $this->key); - if($url && !strstr($out, '»')) {//provide no urls for plugins, etc. - if($out == 'start') { + if ($url && !strstr($out, '»')) {//provide no urls for plugins, etc. + if ($out == 'start') { // exception, because this config name is clashing with our actual start page return '<a href="https://www.dokuwiki.org/config:startpage">' . $out . '</a>'; } else { @@ -152,7 +160,8 @@ class Setting { * * @return string key */ - public function getArrayKey() { + public function getArrayKey() + { return str_replace(Configuration::KEYMARKER, "']['", $this->key); } @@ -167,10 +176,11 @@ class Setting { * * @return string */ - public function getType() { - if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) { + public function getType() + { + if (substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) { return 'plugin'; - } else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) { + } elseif (substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) { return 'template'; } else { return 'dokuwiki'; @@ -184,18 +194,17 @@ class Setting { * @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting * @return string[] with content array(string $label_html, string $input_html) */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = ''; - if($this->isProtected()) { + if ($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; + } elseif ($echo && $this->error) { + $value = $this->input; } else { - if($echo && $this->error) { - $value = $this->input; - } else { - $value = is_null($this->local) ? $this->default : $this->local; - } + $value = is_null($this->local) ? $this->default : $this->local; } $key = htmlspecialchars($this->key); @@ -204,7 +213,7 @@ class Setting { $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>'; $input = '<textarea rows="3" cols="40" id="config___' . $key . '" name="config[' . $key . ']" class="edit" ' . $disable . '>' . $value . '</textarea>'; - return array($label, $input); + return [$label, $input]; } /** @@ -213,10 +222,11 @@ class Setting { * @see out() to run when this returns true * @return bool */ - public function shouldBeSaved() { - if($this->isProtected()) return false; - if($this->local === null) return false; - if($this->default == $this->local) return false; + public function shouldBeSaved() + { + if ($this->isProtected()) return false; + if ($this->local === null) return false; + if ($this->default == $this->local) return false; return true; } @@ -226,8 +236,9 @@ class Setting { * @param string $string * @return string */ - protected function escape($string) { - $tr = array("\\" => '\\\\', "'" => '\\\''); + protected function escape($string) + { + $tr = ["\\" => '\\\\', "'" => '\\\'']; return "'" . strtr(cleanText($string), $tr) . "'"; } @@ -239,11 +250,12 @@ class Setting { * @param string $fmt save format * @return string */ - public function out($var, $fmt = 'php') { + public function out($var, $fmt = 'php') + { if ($fmt != 'php') return ''; if (is_array($this->local)) { - $value = 'array(' . join(', ', array_map([$this, 'escape'], $this->local)) . ')'; + $value = 'array(' . implode(', ', array_map([$this, 'escape'], $this->local)) . ')'; } else { $value = $this->escape($this->local); } @@ -259,9 +271,10 @@ class Setting { * @param \admin_plugin_config $plugin object of config plugin * @return string text */ - public function prompt(\admin_plugin_config $plugin) { + public function prompt(\admin_plugin_config $plugin) + { $prompt = $plugin->getLang($this->key); - if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key)); + if (!$prompt) $prompt = htmlspecialchars(str_replace(['____', '_'], ' ', $this->key)); return $prompt; } @@ -270,7 +283,8 @@ class Setting { * * @return bool */ - public function isProtected() { + public function isProtected() + { return !is_null($this->protected); } @@ -279,7 +293,8 @@ class Setting { * * @return bool */ - public function isDefault() { + public function isDefault() + { return !$this->isProtected() && is_null($this->local); } @@ -288,7 +303,8 @@ class Setting { * * @return bool */ - public function hasError() { + public function hasError() + { return $this->error; } @@ -297,14 +313,14 @@ class Setting { * * @return false|string caution string, otherwise false for invalid caution */ - public function caution() { - if(empty($this->caution)) return false; - if(!in_array($this->caution, Setting::$validCautions)) { + public function caution() + { + if (empty($this->caution)) return false; + if (!in_array($this->caution, Setting::$validCautions)) { throw new \RuntimeException( 'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"' ); } return $this->caution; } - } diff --git a/lib/plugins/config/core/Setting/SettingArray.php b/lib/plugins/config/core/Setting/SettingArray.php index 8dfda0dd6..bae9e87df 100644 --- a/lib/plugins/config/core/Setting/SettingArray.php +++ b/lib/plugins/config/core/Setting/SettingArray.php @@ -5,15 +5,16 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_array */ -class SettingArray extends Setting { - +class SettingArray extends Setting +{ /** * Create an array from a string * * @param string $string * @return array */ - protected function fromString($string) { + protected function fromString($string) + { $array = explode(',', $string); $array = array_map('trim', $array); $array = array_filter($array); @@ -27,8 +28,9 @@ class SettingArray extends Setting { * @param array $array * @return string */ - protected function fromArray($array) { - return join(', ', (array) $array); + protected function fromArray($array) + { + return implode(', ', (array) $array); } /** @@ -38,17 +40,18 @@ class SettingArray extends Setting { * @param string $input * @return bool true if changed, false otherwise (incl. on error) */ - public function update($input) { - if(is_null($input)) return false; - if($this->isProtected()) return false; + public function update($input) + { + if (is_null($input)) return false; + if ($this->isProtected()) return false; $input = $this->fromString($input); $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; - foreach($input as $item) { - if($this->pattern && !preg_match($this->pattern, $item)) { + foreach ($input as $item) { + if ($this->pattern && !preg_match($this->pattern, $item)) { $this->error = true; $this->input = $input; return false; @@ -60,18 +63,17 @@ class SettingArray extends Setting { } /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = ''; - if($this->isProtected()) { + if ($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; + } elseif ($echo && $this->error) { + $value = $this->input; } else { - if($echo && $this->error) { - $value = $this->input; - } else { - $value = is_null($this->local) ? $this->default : $this->local; - } + $value = is_null($this->local) ? $this->default : $this->local; } $key = htmlspecialchars($this->key); @@ -80,6 +82,6 @@ class SettingArray extends Setting { $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>'; $input = '<input id="config___' . $key . '" name="config[' . $key . ']" type="text" class="edit" value="' . $value . '" ' . $disable . '/>'; - return array($label, $input); + return [$label, $input]; } } diff --git a/lib/plugins/config/core/Setting/SettingAuthtype.php b/lib/plugins/config/core/Setting/SettingAuthtype.php index 3a6df6fe5..1874db0a7 100644 --- a/lib/plugins/config/core/Setting/SettingAuthtype.php +++ b/lib/plugins/config/core/Setting/SettingAuthtype.php @@ -5,15 +5,16 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_authtype */ -class SettingAuthtype extends SettingMultichoice { - +class SettingAuthtype extends SettingMultichoice +{ /** @inheritdoc */ - public function initialize($default = null, $local = null, $protected = null) { + public function initialize($default = null, $local = null, $protected = null) + { /** @var $plugin_controller \dokuwiki\Extension\PluginController */ global $plugin_controller; // retrieve auth types provided by plugins - foreach($plugin_controller->getList('auth') as $plugin) { + foreach ($plugin_controller->getList('auth') as $plugin) { $this->choices[] = $plugin; } @@ -21,27 +22,28 @@ class SettingAuthtype extends SettingMultichoice { } /** @inheritdoc */ - public function update($input) { + public function update($input) + { /** @var $plugin_controller \dokuwiki\Extension\PluginController */ global $plugin_controller; // is an update possible/requested? $local = $this->local; // save this, parent::update() may change it - if(!parent::update($input)) return false; // nothing changed or an error caught by parent + if (!parent::update($input)) return false; // nothing changed or an error caught by parent $this->local = $local; // restore original, more error checking to come // attempt to load the plugin $auth_plugin = $plugin_controller->load('auth', $input); // @TODO: throw an error in plugin controller instead of returning null - if(is_null($auth_plugin)) { + if (is_null($auth_plugin)) { $this->error = true; msg('Cannot load Auth Plugin "' . $input . '"', -1); return false; } // verify proper instantiation (is this really a plugin?) @TODO use instanceof? implement interface? - if(is_object($auth_plugin) && !method_exists($auth_plugin, 'getPluginName')) { + if (is_object($auth_plugin) && !method_exists($auth_plugin, 'getPluginName')) { $this->error = true; msg('Cannot create Auth Plugin "' . $input . '"', -1); return false; @@ -49,7 +51,7 @@ class SettingAuthtype extends SettingMultichoice { // did we change the auth type? logout global $conf; - if($conf['authtype'] != $input) { + if ($conf['authtype'] != $input) { msg('Authentication system changed. Please re-login.'); auth_logoff(); } diff --git a/lib/plugins/config/core/Setting/SettingCompression.php b/lib/plugins/config/core/Setting/SettingCompression.php index f97d82801..f52405989 100644 --- a/lib/plugins/config/core/Setting/SettingCompression.php +++ b/lib/plugins/config/core/Setting/SettingCompression.php @@ -5,16 +5,17 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_compression */ -class SettingCompression extends SettingMultichoice { - - protected $choices = array('0'); // 0 = no compression, always supported +class SettingCompression extends SettingMultichoice +{ + protected $choices = ['0']; // 0 = no compression, always supported /** @inheritdoc */ - public function initialize($default = null, $local = null, $protected = null) { + public function initialize($default = null, $local = null, $protected = null) + { // populate _choices with the compression methods supported by this php installation - if(function_exists('gzopen')) $this->choices[] = 'gz'; - if(function_exists('bzopen')) $this->choices[] = 'bz2'; + if (function_exists('gzopen')) $this->choices[] = 'gz'; + if (function_exists('bzopen')) $this->choices[] = 'bz2'; parent::initialize($default, $local, $protected); } diff --git a/lib/plugins/config/core/Setting/SettingDirchoice.php b/lib/plugins/config/core/Setting/SettingDirchoice.php index dfb27f5f4..a571149f0 100644 --- a/lib/plugins/config/core/Setting/SettingDirchoice.php +++ b/lib/plugins/config/core/Setting/SettingDirchoice.php @@ -5,23 +5,24 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_dirchoice */ -class SettingDirchoice extends SettingMultichoice { - +class SettingDirchoice extends SettingMultichoice +{ protected $dir = ''; /** @inheritdoc */ - public function initialize($default = null, $local = null, $protected = null) { + public function initialize($default = null, $local = null, $protected = null) + { // populate $this->_choices with a list of directories - $list = array(); + $list = []; - if($dh = @opendir($this->dir)) { - while(false !== ($entry = readdir($dh))) { - if($entry == '.' || $entry == '..') continue; - if($this->pattern && !preg_match($this->pattern, $entry)) continue; + if ($dh = @opendir($this->dir)) { + while (false !== ($entry = readdir($dh))) { + if ($entry == '.' || $entry == '..') continue; + if ($this->pattern && !preg_match($this->pattern, $entry)) continue; $file = (is_link($this->dir . $entry)) ? readlink($this->dir . $entry) : $this->dir . $entry; - if(is_dir($file)) $list[] = $entry; + if (is_dir($file)) $list[] = $entry; } closedir($dh); } diff --git a/lib/plugins/config/core/Setting/SettingDisableactions.php b/lib/plugins/config/core/Setting/SettingDisableactions.php index 2553175bd..46427c457 100644 --- a/lib/plugins/config/core/Setting/SettingDisableactions.php +++ b/lib/plugins/config/core/Setting/SettingDisableactions.php @@ -5,17 +5,18 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_disableactions */ -class SettingDisableactions extends SettingMulticheckbox { - +class SettingDisableactions extends SettingMulticheckbox +{ /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { global $lang; // make some language adjustments (there must be a better way) // transfer some DokuWiki language strings to the plugin $plugin->addLang($this->key . '_revisions', $lang['btn_revs']); - foreach($this->choices as $choice) { - if(isset($lang['btn_' . $choice])) $plugin->addLang($this->key . '_' . $choice, $lang['btn_' . $choice]); + foreach ($this->choices as $choice) { + if (isset($lang['btn_' . $choice])) $plugin->addLang($this->key . '_' . $choice, $lang['btn_' . $choice]); } return parent::html($plugin, $echo); diff --git a/lib/plugins/config/core/Setting/SettingEmail.php b/lib/plugins/config/core/Setting/SettingEmail.php index 25a0c0e75..a1a2ab028 100644 --- a/lib/plugins/config/core/Setting/SettingEmail.php +++ b/lib/plugins/config/core/Setting/SettingEmail.php @@ -5,24 +5,26 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_email */ -class SettingEmail extends SettingString { +class SettingEmail extends SettingString +{ protected $multiple = false; protected $placeholders = false; /** @inheritdoc */ - public function update($input) { - if(is_null($input)) return false; - if($this->isProtected()) return false; + public function update($input) + { + if (is_null($input)) return false; + if ($this->isProtected()) return false; $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; - if($input === '') { + if ($value == $input) return false; + if ($input === '') { $this->local = $input; return true; } $mail = $input; - if($this->placeholders) { + if ($this->placeholders) { // replace variables with pseudo values $mail = str_replace('@USER@', 'joe', $mail); $mail = str_replace('@NAME@', 'Joe Schmoe', $mail); @@ -30,22 +32,22 @@ class SettingEmail extends SettingString { } // multiple mail addresses? - if($this->multiple) { + if ($this->multiple) { $mails = array_filter(array_map('trim', explode(',', $mail))); } else { - $mails = array($mail); + $mails = [$mail]; } // check them all - foreach($mails as $mail) { + foreach ($mails as $mail) { // only check the address part - if(preg_match('#(.*?)<(.*?)>#', $mail, $matches)) { + if (preg_match('#(.*?)<(.*?)>#', $mail, $matches)) { $addr = $matches[2]; } else { $addr = $mail; } - if(!mail_isvalid($addr)) { + if (!mail_isvalid($addr)) { $this->error = true; $this->input = $input; return false; diff --git a/lib/plugins/config/core/Setting/SettingFieldset.php b/lib/plugins/config/core/Setting/SettingFieldset.php index 4e8618967..3db2962cb 100644 --- a/lib/plugins/config/core/Setting/SettingFieldset.php +++ b/lib/plugins/config/core/Setting/SettingFieldset.php @@ -7,11 +7,11 @@ namespace dokuwiki\plugin\config\core\Setting; * * Used to start a new settings "display-group". */ -class SettingFieldset extends Setting { - +class SettingFieldset extends Setting +{ /** @inheritdoc */ - public function shouldHaveDefault() { + public function shouldHaveDefault() + { return false; } - } diff --git a/lib/plugins/config/core/Setting/SettingHidden.php b/lib/plugins/config/core/Setting/SettingHidden.php index ca8a03eb9..11b800f84 100644 --- a/lib/plugins/config/core/Setting/SettingHidden.php +++ b/lib/plugins/config/core/Setting/SettingHidden.php @@ -5,6 +5,7 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_hidden */ -class SettingHidden extends Setting { +class SettingHidden extends Setting +{ // Used to explicitly ignore a setting in the configuration manager. } diff --git a/lib/plugins/config/core/Setting/SettingImConvert.php b/lib/plugins/config/core/Setting/SettingImConvert.php index 8740d94c8..985372deb 100644 --- a/lib/plugins/config/core/Setting/SettingImConvert.php +++ b/lib/plugins/config/core/Setting/SettingImConvert.php @@ -5,18 +5,19 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_im_convert */ -class SettingImConvert extends SettingString { - +class SettingImConvert extends SettingString +{ /** @inheritdoc */ - public function update($input) { - if($this->isProtected()) return false; + public function update($input) + { + if ($this->isProtected()) return false; $input = trim($input); $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; - if($input && !file_exists($input)) { + if ($input && !file_exists($input)) { $this->error = true; $this->input = $input; return false; diff --git a/lib/plugins/config/core/Setting/SettingLicense.php b/lib/plugins/config/core/Setting/SettingLicense.php index 8dacf8e25..edd5a09e3 100644 --- a/lib/plugins/config/core/Setting/SettingLicense.php +++ b/lib/plugins/config/core/Setting/SettingLicense.php @@ -5,15 +5,16 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_license */ -class SettingLicense extends SettingMultichoice { - - protected $choices = array(''); // none choosen +class SettingLicense extends SettingMultichoice +{ + protected $choices = ['']; // none choosen /** @inheritdoc */ - public function initialize($default = null, $local = null, $protected = null) { + public function initialize($default = null, $local = null, $protected = null) + { global $license; - foreach($license as $key => $data) { + foreach ($license as $key => $data) { $this->choices[] = $key; $this->lang[$this->key . '_o_' . $key] = $data['name']; // stored in setting } diff --git a/lib/plugins/config/core/Setting/SettingMulticheckbox.php b/lib/plugins/config/core/Setting/SettingMulticheckbox.php index df212cca0..954a51018 100644 --- a/lib/plugins/config/core/Setting/SettingMulticheckbox.php +++ b/lib/plugins/config/core/Setting/SettingMulticheckbox.php @@ -5,24 +5,25 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_multicheckbox */ -class SettingMulticheckbox extends SettingString { - - protected $choices = array(); - protected $combine = array(); +class SettingMulticheckbox extends SettingString +{ + protected $choices = []; + protected $combine = []; protected $other = 'always'; /** @inheritdoc */ - public function update($input) { - if($this->isProtected()) return false; + public function update($input) + { + if ($this->isProtected()) return false; // split any combined values + convert from array to comma separated string - $input = ($input) ? $input : array(); + $input = $input ?: []; $input = $this->array2str($input); $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; - if($this->pattern && !preg_match($this->pattern, $input)) { + if ($this->pattern && !preg_match($this->pattern, $input)) { $this->error = true; $this->input = $input; return false; @@ -33,19 +34,18 @@ class SettingMulticheckbox extends SettingString { } /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = ''; - if($this->isProtected()) { + if ($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; + } elseif ($echo && $this->error) { + $value = $this->input; } else { - if($echo && $this->error) { - $value = $this->input; - } else { - $value = is_null($this->local) ? $this->default : $this->local; - } + $value = is_null($this->local) ? $this->default : $this->local; } $key = htmlspecialchars($this->key); @@ -55,17 +55,16 @@ class SettingMulticheckbox extends SettingString { $default = $this->str2array($this->default); $input = ''; - foreach($this->choices as $choice) { + foreach ($this->choices as $choice) { $idx = array_search($choice, $value); $idx_default = array_search($choice, $default); $checked = ($idx !== false) ? 'checked="checked"' : ''; // @todo ideally this would be handled using a second class of "default" - $class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : ""; + $class = (($idx !== false) === (false !== $idx_default)) ? " selectiondefault" : ""; - $prompt = ($plugin->getLang($this->key . '_' . $choice) ? - $plugin->getLang($this->key . '_' . $choice) : htmlspecialchars($choice)); + $prompt = ($plugin->getLang($this->key . '_' . $choice) ?: htmlspecialchars($choice)); $input .= '<div class="selection' . $class . '">' . "\n"; $input .= '<label for="config___' . $key . '_' . $choice . '">' . $prompt . "</label>\n"; @@ -74,20 +73,19 @@ class SettingMulticheckbox extends SettingString { $input .= "</div>\n"; // remove this action from the disabledactions array - if($idx !== false) unset($value[$idx]); - if($idx_default !== false) unset($default[$idx_default]); + if ($idx !== false) unset($value[$idx]); + if ($idx_default !== false) unset($default[$idx_default]); } // handle any remaining values - if($this->other != 'never') { - $other = join(',', $value); + if ($this->other != 'never') { + $other = implode(',', $value); // test equivalent to ($this->_other == 'always' || ($other && $this->_other == 'exists') // use != 'exists' rather than == 'always' to ensure invalid values default to 'always' - if($this->other != 'exists' || $other) { - + if ($this->other != 'exists' || $other) { $class = ( - (count($default) == count($value)) && - (count($value) == count(array_intersect($value, $default))) + (count($default) === count($value)) && + (count($value) === count(array_intersect($value, $default))) ) ? " selectiondefault" : ""; @@ -102,7 +100,7 @@ class SettingMulticheckbox extends SettingString { } } $label = '<label>' . $this->prompt($plugin) . '</label>'; - return array($label, $input); + return [$label, $input]; } /** @@ -111,18 +109,19 @@ class SettingMulticheckbox extends SettingString { * @param string $str * @return array */ - protected function str2array($str) { + protected function str2array($str) + { $array = explode(',', $str); - if(!empty($this->combine)) { - foreach($this->combine as $key => $combinators) { - $idx = array(); - foreach($combinators as $val) { - if(($idx[] = array_search($val, $array)) === false) break; + if (!empty($this->combine)) { + foreach ($this->combine as $key => $combinators) { + $idx = []; + foreach ($combinators as $val) { + if (($idx[] = array_search($val, $array)) === false) break; } - if(count($idx) && $idx[count($idx) - 1] !== false) { - foreach($idx as $i) unset($array[$i]); + if (count($idx) && $idx[count($idx) - 1] !== false) { + foreach ($idx as $i) unset($array[$i]); $array[] = $key; } } @@ -137,27 +136,27 @@ class SettingMulticheckbox extends SettingString { * @param array $input * @return string */ - protected function array2str($input) { + protected function array2str($input) + { // handle other $other = trim($input['other']); - $other = !empty($other) ? explode(',', str_replace(' ', '', $input['other'])) : array(); + $other = empty($other) ? [] : explode(',', str_replace(' ', '', $input['other'])); unset($input['other']); $array = array_unique(array_merge($input, $other)); // deconstruct any combinations - if(!empty($this->combine)) { - foreach($this->combine as $key => $combinators) { - + if (!empty($this->combine)) { + foreach ($this->combine as $key => $combinators) { $idx = array_search($key, $array); - if($idx !== false) { + if ($idx !== false) { unset($array[$idx]); $array = array_merge($array, $combinators); } } } - return join(',', array_unique($array)); + return implode(',', array_unique($array)); } } diff --git a/lib/plugins/config/core/Setting/SettingMultichoice.php b/lib/plugins/config/core/Setting/SettingMultichoice.php index 3a50857e0..7d29a0e2b 100644 --- a/lib/plugins/config/core/Setting/SettingMultichoice.php +++ b/lib/plugins/config/core/Setting/SettingMultichoice.php @@ -5,16 +5,18 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_multichoice */ -class SettingMultichoice extends SettingString { - protected $choices = array(); +class SettingMultichoice extends SettingString +{ + protected $choices = []; public $lang; //some custom language strings are stored in setting /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = ''; $nochoice = ''; - if($this->isProtected()) { + if ($this->isProtected()) { $value = $this->protected; $disable = ' disabled="disabled"'; } else { @@ -22,11 +24,11 @@ class SettingMultichoice extends SettingString { } // ensure current value is included - if(!in_array($value, $this->choices)) { + if (!in_array($value, $this->choices)) { $this->choices[] = $value; } // disable if no other choices - if(!$this->isProtected() && count($this->choices) <= 1) { + if (!$this->isProtected() && count($this->choices) <= 1) { $disable = ' disabled="disabled"'; $nochoice = $plugin->getLang('nochoice'); } @@ -37,13 +39,13 @@ class SettingMultichoice extends SettingString { $input = "<div class=\"input\">\n"; $input .= '<select class="edit" id="config___' . $key . '" name="config[' . $key . ']"' . $disable . '>' . "\n"; - foreach($this->choices as $choice) { + foreach ($this->choices as $choice) { $selected = ($value == $choice) ? ' selected="selected"' : ''; $option = $plugin->getLang($this->key . '_o_' . $choice); - if(!$option && isset($this->lang[$this->key . '_o_' . $choice])) { + if (!$option && isset($this->lang[$this->key . '_o_' . $choice])) { $option = $this->lang[$this->key . '_o_' . $choice]; } - if(!$option) $option = $choice; + if (!$option) $option = $choice; $choice = htmlspecialchars($choice); $option = htmlspecialchars($option); @@ -52,18 +54,19 @@ class SettingMultichoice extends SettingString { $input .= "</select> $nochoice \n"; $input .= "</div>\n"; - return array($label, $input); + return [$label, $input]; } /** @inheritdoc */ - public function update($input) { - if(is_null($input)) return false; - if($this->isProtected()) return false; + public function update($input) + { + if (is_null($input)) return false; + if ($this->isProtected()) return false; $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; - if(!in_array($input, $this->choices)) return false; + if (!in_array($input, $this->choices)) return false; $this->local = $input; return true; diff --git a/lib/plugins/config/core/Setting/SettingNoClass.php b/lib/plugins/config/core/Setting/SettingNoClass.php index 8efff216a..805ab11c9 100644 --- a/lib/plugins/config/core/Setting/SettingNoClass.php +++ b/lib/plugins/config/core/Setting/SettingNoClass.php @@ -7,6 +7,7 @@ namespace dokuwiki\plugin\config\core\Setting; * A do-nothing class used to detect settings with a missing setting class. * Used internaly to hide undefined settings, and generate the undefined settings list. */ -class SettingNoClass extends SettingUndefined { +class SettingNoClass extends SettingUndefined +{ protected $errorMessage = '_msg_setting_no_class'; } diff --git a/lib/plugins/config/core/Setting/SettingNoDefault.php b/lib/plugins/config/core/Setting/SettingNoDefault.php index 07b8412dd..2780be095 100644 --- a/lib/plugins/config/core/Setting/SettingNoDefault.php +++ b/lib/plugins/config/core/Setting/SettingNoDefault.php @@ -8,6 +8,7 @@ namespace dokuwiki\plugin\config\core\Setting; * A do-nothing class used to detect settings with no default value. * Used internaly to hide undefined settings, and generate the undefined settings list. */ -class SettingNoDefault extends SettingUndefined { +class SettingNoDefault extends SettingUndefined +{ protected $errorMessage = '_msg_setting_no_default'; } diff --git a/lib/plugins/config/core/Setting/SettingNoKnownClass.php b/lib/plugins/config/core/Setting/SettingNoKnownClass.php index 3c527e1ee..0d5c1c734 100644 --- a/lib/plugins/config/core/Setting/SettingNoKnownClass.php +++ b/lib/plugins/config/core/Setting/SettingNoKnownClass.php @@ -6,6 +6,7 @@ namespace dokuwiki\plugin\config\core\Setting; * A do-nothing class used to detect settings with a missing setting class. * Used internaly to hide undefined settings, and generate the undefined settings list. */ -class SettingNoKnownClass extends SettingUndefined { +class SettingNoKnownClass extends SettingUndefined +{ protected $errorMessage = '_msg_setting_no_known_class'; } diff --git a/lib/plugins/config/core/Setting/SettingNumeric.php b/lib/plugins/config/core/Setting/SettingNumeric.php index 8a6b17956..27ca1945c 100644 --- a/lib/plugins/config/core/Setting/SettingNumeric.php +++ b/lib/plugins/config/core/Setting/SettingNumeric.php @@ -5,22 +5,26 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_numeric */ -class SettingNumeric extends SettingString { +class SettingNumeric extends SettingString +{ // This allows for many PHP syntax errors... // var $_pattern = '/^[-+\/*0-9 ]*$/'; // much more restrictive, but should eliminate syntax errors. - protected $pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/'; - protected $min = null; - protected $max = null; + protected $pattern = '/^[-+]? *\d+ *(?:[-+*] *\d+ *)*$/'; + protected $min; + protected $max; /** @inheritdoc */ - public function update($input) { + public function update($input) + { $local = $this->local; $valid = parent::update($input); - if($valid && !(is_null($this->min) && is_null($this->max))) { + if ($valid && !(is_null($this->min) && is_null($this->max))) { $numeric_local = (int) eval('return ' . $this->local . ';'); - if((!is_null($this->min) && $numeric_local < $this->min) || - (!is_null($this->max) && $numeric_local > $this->max)) { + if ( + (!is_null($this->min) && $numeric_local < $this->min) || + (!is_null($this->max) && $numeric_local > $this->max) + ) { $this->error = true; $this->input = $input; $this->local = $local; @@ -31,8 +35,9 @@ class SettingNumeric extends SettingString { } /** @inheritdoc */ - public function out($var, $fmt = 'php') { - if($fmt != 'php') return ''; + public function out($var, $fmt = 'php') + { + if ($fmt != 'php') return ''; $local = $this->local === '' ? "''" : $this->local; $out = '$' . $var . "['" . $this->getArrayKey() . "'] = " . $local . ";\n"; diff --git a/lib/plugins/config/core/Setting/SettingNumericopt.php b/lib/plugins/config/core/Setting/SettingNumericopt.php index a486e187f..117e3920a 100644 --- a/lib/plugins/config/core/Setting/SettingNumericopt.php +++ b/lib/plugins/config/core/Setting/SettingNumericopt.php @@ -5,17 +5,19 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_numericopt */ -class SettingNumericopt extends SettingNumeric { +class SettingNumericopt extends SettingNumeric +{ // just allow an empty config - protected $pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/'; + protected $pattern = '/^(|[-]?\d+(?:[-+*]\d+)*)$/'; /** * @inheritdoc * Empty string is valid for numericopt */ - public function update($input) { - if($input === '') { - if($input == $this->local) return false; + public function update($input) + { + if ($input === '') { + if ($input == $this->local) return false; $this->local = $input; return true; } diff --git a/lib/plugins/config/core/Setting/SettingOnoff.php b/lib/plugins/config/core/Setting/SettingOnoff.php index 780778b48..69a74aa9f 100644 --- a/lib/plugins/config/core/Setting/SettingOnoff.php +++ b/lib/plugins/config/core/Setting/SettingOnoff.php @@ -5,29 +5,31 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_onoff */ -class SettingOnoff extends SettingNumeric { - +class SettingOnoff extends SettingNumeric +{ /** * We treat the strings 'false' and 'off' as false * @inheritdoc */ - protected function cleanValue($value) { - if($value === null) return null; - - if(is_string($value)) { - if(strtolower($value) === 'false') return 0; - if(strtolower($value) === 'off') return 0; - if(trim($value) === '') return 0; + protected function cleanValue($value) + { + if ($value === null) return null; + + if (is_string($value)) { + if (strtolower($value) === 'false') return 0; + if (strtolower($value) === 'off') return 0; + if (trim($value) === '') return 0; } return (int) (bool) $value; } /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = ''; - if($this->isProtected()) { + if ($this->isProtected()) { $value = $this->protected; $disable = ' disabled="disabled"'; } else { @@ -40,16 +42,17 @@ class SettingOnoff extends SettingNumeric { $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>'; $input = '<div class="input"><input id="config___' . $key . '" name="config[' . $key . ']" type="checkbox" class="checkbox" value="1"' . $checked . $disable . '/></div>'; - return array($label, $input); + return [$label, $input]; } /** @inheritdoc */ - public function update($input) { - if($this->isProtected()) return false; + public function update($input) + { + if ($this->isProtected()) return false; $input = ($input) ? 1 : 0; $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; $this->local = $input; return true; diff --git a/lib/plugins/config/core/Setting/SettingPassword.php b/lib/plugins/config/core/Setting/SettingPassword.php index 9d9c53377..e56a1338f 100644 --- a/lib/plugins/config/core/Setting/SettingPassword.php +++ b/lib/plugins/config/core/Setting/SettingPassword.php @@ -5,16 +5,17 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_password */ -class SettingPassword extends SettingString { - +class SettingPassword extends SettingString +{ protected $code = 'plain'; // mechanism to be used to obscure passwords /** @inheritdoc */ - public function update($input) { - if($this->isProtected()) return false; - if(!$input) return false; + public function update($input) + { + if ($this->isProtected()) return false; + if (!$input) return false; - if($this->pattern && !preg_match($this->pattern, $input)) { + if ($this->pattern && !preg_match($this->pattern, $input)) { $this->error = true; $this->input = $input; return false; @@ -25,7 +26,8 @@ class SettingPassword extends SettingString { } /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = $this->isProtected() ? 'disabled="disabled"' : ''; @@ -34,6 +36,6 @@ class SettingPassword extends SettingString { $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>'; $input = '<input id="config___' . $key . '" name="config[' . $key . ']" autocomplete="off" type="password" class="edit" value="" ' . $disable . ' />'; - return array($label, $input); + return [$label, $input]; } } diff --git a/lib/plugins/config/core/Setting/SettingRegex.php b/lib/plugins/config/core/Setting/SettingRegex.php index b38f0a560..7ec3a4d81 100644 --- a/lib/plugins/config/core/Setting/SettingRegex.php +++ b/lib/plugins/config/core/Setting/SettingRegex.php @@ -5,24 +5,25 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_regex */ -class SettingRegex extends SettingString { - +class SettingRegex extends SettingString +{ protected $delimiter = '/'; // regex delimiter to be used in testing input protected $pregflags = 'ui'; // regex pattern modifiers to be used in testing input /** @inheritdoc */ - public function update($input) { + public function update($input) + { // let parent do basic checks, value, not changed, etc. $local = $this->local; - if(!parent::update($input)) return false; + if (!parent::update($input)) return false; $this->local = $local; // see if the regex compiles and runs (we don't check for effectiveness) $regex = $this->delimiter . $input . $this->delimiter . $this->pregflags; $lastError = error_get_last(); @preg_match($regex, 'testdata'); - if(preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) { + if (preg_last_error() != PREG_NO_ERROR || error_get_last() !== $lastError) { $this->input = $input; $this->error = true; return false; diff --git a/lib/plugins/config/core/Setting/SettingRenderer.php b/lib/plugins/config/core/Setting/SettingRenderer.php index 37ba9c70a..10b3e33f8 100644 --- a/lib/plugins/config/core/Setting/SettingRenderer.php +++ b/lib/plugins/config/core/Setting/SettingRenderer.php @@ -1,4 +1,5 @@ <?php + /** * additional setting classes specific to these settings * @@ -10,17 +11,19 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_renderer */ -class SettingRenderer extends SettingMultichoice { - protected $prompts = array(); - protected $format = null; +class SettingRenderer extends SettingMultichoice +{ + protected $prompts = []; + protected $format; /** @inheritdoc */ - public function initialize($default = null, $local = null, $protected = null) { + public function initialize($default = null, $local = null, $protected = null) + { $format = $this->format; - foreach(plugin_list('renderer') as $plugin) { + foreach (plugin_list('renderer') as $plugin) { $renderer = plugin_load('renderer', $plugin); - if(method_exists($renderer, 'canRender') && $renderer->canRender($format)) { + if (method_exists($renderer, 'canRender') && $renderer->canRender($format)) { $this->choices[] = $plugin; $info = $renderer->getInfo(); @@ -32,13 +35,14 @@ class SettingRenderer extends SettingMultichoice { } /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { // make some language adjustments (there must be a better way) // transfer some plugin names to the config plugin - foreach($this->choices as $choice) { - if(!$plugin->getLang($this->key . '_o_' . $choice)) { - if(!isset($this->prompts[$choice])) { + foreach ($this->choices as $choice) { + if (!$plugin->getLang($this->key . '_o_' . $choice)) { + if (!isset($this->prompts[$choice])) { $plugin->addLang( $this->key . '_o_' . $choice, sprintf($plugin->getLang('renderer__core'), $choice) diff --git a/lib/plugins/config/core/Setting/SettingSavedir.php b/lib/plugins/config/core/Setting/SettingSavedir.php index 43e428dd3..a429b7a38 100644 --- a/lib/plugins/config/core/Setting/SettingSavedir.php +++ b/lib/plugins/config/core/Setting/SettingSavedir.php @@ -5,16 +5,17 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_savedir */ -class SettingSavedir extends SettingString { - +class SettingSavedir extends SettingString +{ /** @inheritdoc */ - public function update($input) { - if($this->isProtected()) return false; + public function update($input) + { + if ($this->isProtected()) return false; $value = is_null($this->local) ? $this->default : $this->local; - if($value == $input) return false; + if ($value == $input) return false; - if(!init_path($input)) { + if (!init_path($input)) { $this->error = true; $this->input = $input; return false; diff --git a/lib/plugins/config/core/Setting/SettingSepchar.php b/lib/plugins/config/core/Setting/SettingSepchar.php index 57cd0ae92..db9e9d694 100644 --- a/lib/plugins/config/core/Setting/SettingSepchar.php +++ b/lib/plugins/config/core/Setting/SettingSepchar.php @@ -5,12 +5,13 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_sepchar */ -class SettingSepchar extends SettingMultichoice { - +class SettingSepchar extends SettingMultichoice +{ /** @inheritdoc */ - public function __construct($key, $param = null) { + public function __construct($key, $param = null) + { $str = '_-.'; - for($i = 0; $i < strlen($str); $i++) $this->choices[] = $str[$i]; + for ($i = 0; $i < strlen($str); $i++) $this->choices[] = $str[$i]; // call foundation class constructor parent::__construct($key, $param); diff --git a/lib/plugins/config/core/Setting/SettingString.php b/lib/plugins/config/core/Setting/SettingString.php index b819407b7..090108501 100644 --- a/lib/plugins/config/core/Setting/SettingString.php +++ b/lib/plugins/config/core/Setting/SettingString.php @@ -5,20 +5,20 @@ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_string */ -class SettingString extends Setting { +class SettingString extends Setting +{ /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { $disable = ''; - if($this->isProtected()) { + if ($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; + } elseif ($echo && $this->error) { + $value = $this->input; } else { - if($echo && $this->error) { - $value = $this->input; - } else { - $value = is_null($this->local) ? $this->default : $this->local; - } + $value = is_null($this->local) ? $this->default : $this->local; } $key = htmlspecialchars($this->key); @@ -27,6 +27,6 @@ class SettingString extends Setting { $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>'; $input = '<input id="config___' . $key . '" name="config[' . $key . ']" type="text" class="edit" value="' . $value . '" ' . $disable . '/>'; - return array($label, $input); + return [$label, $input]; } } diff --git a/lib/plugins/config/core/Setting/SettingUndefined.php b/lib/plugins/config/core/Setting/SettingUndefined.php index fa46a9f1d..e70c90cd7 100644 --- a/lib/plugins/config/core/Setting/SettingUndefined.php +++ b/lib/plugins/config/core/Setting/SettingUndefined.php @@ -8,23 +8,27 @@ use dokuwiki\plugin\config\core\Configuration; * A do-nothing class used to detect settings with no metadata entry. * Used internaly to hide undefined settings, and generate the undefined settings list. */ -class SettingUndefined extends SettingHidden { - +class SettingUndefined extends SettingHidden +{ protected $errorMessage = '_msg_setting_undefined'; /** @inheritdoc */ - public function shouldHaveDefault() { + public function shouldHaveDefault() + { return false; } /** @inheritdoc */ - public function html(\admin_plugin_config $plugin, $echo = false) { + public function html(\admin_plugin_config $plugin, $echo = false) + { // determine the name the meta key would be called - if(preg_match( - '/^(?:plugin|tpl)' . Configuration::KEYMARKER . '.*?' . Configuration::KEYMARKER . '(.*)$/', - $this->getKey(), - $undefined_setting_match - )) { + if ( + preg_match( + '/^(?:plugin|tpl)' . Configuration::KEYMARKER . '.*?' . Configuration::KEYMARKER . '(.*)$/', + $this->getKey(), + $undefined_setting_match + ) + ) { $undefined_setting_key = $undefined_setting_match[1]; } else { $undefined_setting_key = $this->getKey(); @@ -34,7 +38,6 @@ class SettingUndefined extends SettingHidden { 'conf' . '[\'' . $this->getArrayKey() . '\']</span>'; $input = $plugin->getLang($this->errorMessage); - return array($label, $input); + return [$label, $input]; } - } diff --git a/lib/plugins/config/core/Writer.php b/lib/plugins/config/core/Writer.php index 18aa9ee02..6751b88ba 100644 --- a/lib/plugins/config/core/Writer.php +++ b/lib/plugins/config/core/Writer.php @@ -1,13 +1,15 @@ <?php namespace dokuwiki\plugin\config\core; + use dokuwiki\plugin\config\core\Setting\Setting; use dokuwiki\Logger; /** * Writes the settings to the correct local file */ -class Writer { +class Writer +{ /** @var string header info */ protected $header = 'Dokuwiki\'s Main Configuration File - Local Settings'; @@ -17,7 +19,8 @@ class Writer { /** * Writer constructor. */ - public function __construct() { + public function __construct() + { global $config_cascade; $this->savefile = end($config_cascade['main']['local']); } @@ -28,36 +31,37 @@ class Writer { * @param Setting[] $settings * @throws \Exception */ - public function save($settings) { + public function save($settings) + { global $conf; - if($this->isLocked()) throw new \Exception('no save'); + if ($this->isLocked()) throw new \Exception('no save'); // backup current file (remove any existing backup) - if(file_exists($this->savefile)) { - if(file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php'); - if(!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup'); + if (file_exists($this->savefile)) { + if (file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php'); + if (!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup'); } - if(!$fh = @fopen($this->savefile, 'wb')) { + if (!$fh = @fopen($this->savefile, 'wb')) { io_rename($this->savefile . '.bak.php', $this->savefile); // problem opening, restore the backup throw new \Exception('no save'); } $out = ''; - foreach($settings as $setting) { - if($setting->shouldBeSaved()) { + foreach ($settings as $setting) { + if ($setting->shouldBeSaved()) { $out .= $setting->out('conf', 'php'); } } - if($out === '') { + if ($out === '') { throw new \Exception('empty config'); } $out = $this->getHeader() . $out; fwrite($fh, $out); fclose($fh); - if($conf['fperm']) chmod($this->savefile, $conf['fperm']); + if ($conf['fperm']) chmod($this->savefile, $conf['fperm']); $this->opcacheUpdate($this->savefile); } @@ -68,8 +72,9 @@ class Writer { * * @throws \Exception when the config isn't writable */ - public function touch() { - if($this->isLocked()) throw new \Exception('no save'); + public function touch() + { + if ($this->isLocked()) throw new \Exception('no save'); @touch($this->savefile); $this->opcacheUpdate($this->savefile); } @@ -80,11 +85,12 @@ class Writer { * @todo this should probably be moved to core * @param string $file */ - protected function opcacheUpdate($file) { - if(!function_exists('opcache_invalidate')) return; + protected function opcacheUpdate($file) + { + if (!function_exists('opcache_invalidate')) return; set_error_handler(function ($errNo, $errMsg) { - Logger::debug('Unable to invalidate opcache: ' . $errMsg); } - ); + Logger::debug('Unable to invalidate opcache: ' . $errMsg); + }); opcache_invalidate($file); restore_error_handler(); } @@ -95,10 +101,11 @@ class Writer { * * @return bool true: locked, false: writable */ - public function isLocked() { - if(!$this->savefile) return true; - if(!is_writable(dirname($this->savefile))) return true; - if(file_exists($this->savefile) && !is_writable($this->savefile)) return true; + public function isLocked() + { + if (!$this->savefile) return true; + if (!is_writable(dirname($this->savefile))) return true; + if (file_exists($this->savefile) && !is_writable($this->savefile)) return true; return false; } @@ -107,20 +114,21 @@ class Writer { * * @return string */ - protected function getHeader() { - return join( + protected function getHeader() + { + return implode( "\n", - array( + [ '<?php', '/*', ' * ' . $this->header, ' * Auto-generated by config plugin', - ' * Run for user: ' . (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : 'Unknown'), + ' * Run for user: ' . ($_SERVER['REMOTE_USER'] ?? 'Unknown'), ' * Date: ' . date('r'), ' */', '', '' - ) + ] ); } } diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php index 5774f13bb..59c3b8853 100644 --- a/lib/plugins/config/settings/config.metadata.php +++ b/lib/plugins/config/settings/config.metadata.php @@ -1,4 +1,5 @@ <?php + /** * Metadata for configuration manager plugin * @@ -80,62 +81,77 @@ * @author Chris Smith <chris@jalakai.co.uk> */ -$meta['_basic'] = array('fieldset'); -$meta['title'] = array('string'); -$meta['start'] = array('string','_caution' => 'warning','_pattern' => '!^[^:;/]+$!'); // don't accept namespaces -$meta['lang'] = array('dirchoice','_dir' => DOKU_INC.'inc/lang/'); -$meta['template'] = array('dirchoice','_dir' => DOKU_INC.'lib/tpl/','_pattern' => '/^[\w-]+$/'); -$meta['tagline'] = array('string'); -$meta['sidebar'] = array('string'); -$meta['license'] = array('license'); -$meta['savedir'] = array('savedir','_caution' => 'danger'); -$meta['basedir'] = array('string','_caution' => 'danger'); -$meta['baseurl'] = array('string','_caution' => 'danger'); -$meta['cookiedir'] = array('string','_caution' => 'danger'); -$meta['dmode'] = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation -$meta['fmode'] = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation -$meta['allowdebug'] = array('onoff','_caution' => 'security'); +$meta['_basic'] = ['fieldset']; +$meta['title'] = ['string']; +$meta['start'] = ['string', '_caution' => 'warning', '_pattern' => '!^[^:;/]+$!']; // don't accept namespaces +$meta['lang'] = ['dirchoice', '_dir' => DOKU_INC . 'inc/lang/']; +$meta['template'] = ['dirchoice', '_dir' => DOKU_INC . 'lib/tpl/', '_pattern' => '/^[\w-]+$/']; +$meta['tagline'] = ['string']; +$meta['sidebar'] = ['string']; +$meta['license'] = ['license']; +$meta['savedir'] = ['savedir', '_caution' => 'danger']; +$meta['basedir'] = ['string', '_caution' => 'danger']; +$meta['baseurl'] = ['string', '_caution' => 'danger']; +$meta['cookiedir'] = ['string', '_caution' => 'danger']; +$meta['dmode'] = ['numeric', '_pattern' => '/0[0-7]{3,4}/']; // only accept octal representation +$meta['fmode'] = ['numeric', '_pattern' => '/0[0-7]{3,4}/']; // only accept octal representation +$meta['allowdebug'] = ['onoff', '_caution' => 'security']; -$meta['_display'] = array('fieldset'); -$meta['recent'] = array('numeric'); -$meta['recent_days'] = array('numeric'); -$meta['breadcrumbs'] = array('numeric','_min' => 0); -$meta['youarehere'] = array('onoff'); -$meta['fullpath'] = array('onoff','_caution' => 'security'); -$meta['typography'] = array('multichoice','_choices' => array(0,1,2)); -$meta['dformat'] = array('string'); -$meta['signature'] = array('string'); -$meta['showuseras'] = array( - 'multichoice', - '_choices' => array('loginname', 'username', 'username_link', 'email', 'email_link') -); -$meta['toptoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5)); // 5 toc levels -$meta['tocminheads'] = array('multichoice','_choices' => array(0,1,2,3,4,5,10,15,20)); -$meta['maxtoclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5)); -$meta['maxseclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5)); // 0 for no sec edit buttons -$meta['camelcase'] = array('onoff','_caution' => 'warning'); -$meta['deaccent'] = array('multichoice','_choices' => array(0,1,2),'_caution' => 'warning'); -$meta['useheading'] = array('multichoice','_choices' => array(0,'navigation','content',1)); -$meta['sneaky_index'] = array('onoff'); -$meta['hidepages'] = array('regex'); +$meta['_display'] = ['fieldset']; +$meta['recent'] = ['numeric']; +$meta['recent_days'] = ['numeric']; +$meta['breadcrumbs'] = ['numeric', '_min' => 0]; +$meta['youarehere'] = ['onoff']; +$meta['fullpath'] = ['onoff', '_caution' => 'security']; +$meta['typography'] = ['multichoice', '_choices' => [0, 1, 2]]; +$meta['dformat'] = ['string']; +$meta['signature'] = ['string']; +$meta['showuseras'] = ['multichoice', '_choices' => ['loginname', 'username', 'username_link', 'email', 'email_link']]; +$meta['toptoclevel'] = ['multichoice', '_choices' => [1, 2, 3, 4, 5]]; // 5 toc levels +$meta['tocminheads'] = ['multichoice', '_choices' => [0, 1, 2, 3, 4, 5, 10, 15, 20]]; +$meta['maxtoclevel'] = ['multichoice', '_choices' => [0, 1, 2, 3, 4, 5]]; +$meta['maxseclevel'] = ['multichoice', '_choices' => [0, 1, 2, 3, 4, 5]]; // 0 for no sec edit buttons +$meta['camelcase'] = ['onoff', '_caution' => 'warning']; +$meta['deaccent'] = ['multichoice', '_choices' => [0, 1, 2], '_caution' => 'warning']; +$meta['useheading'] = ['multichoice', '_choices' => [0, 'navigation', 'content', 1]]; +$meta['sneaky_index'] = ['onoff']; +$meta['hidepages'] = ['regex']; -$meta['_authentication'] = array('fieldset'); -$meta['useacl'] = array('onoff','_caution' => 'danger'); -$meta['autopasswd'] = array('onoff'); -$meta['authtype'] = array('authtype','_caution' => 'danger'); -$meta['passcrypt'] = array('multichoice','_choices' => array( - 'smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5', - 'mediawiki','bcrypt','djangomd5','djangosha1','djangopbkdf2_sha1','djangopbkdf2_sha256', - 'sha512','argon2i','argon2id' -)); -$meta['defaultgroup']= array('string'); -$meta['superuser'] = array('string','_caution' => 'danger'); -$meta['manager'] = array('string'); -$meta['profileconfirm'] = array('onoff'); -$meta['rememberme'] = array('onoff'); -$meta['disableactions'] = array( - 'disableactions', - '_choices' => array( +$meta['_authentication'] = ['fieldset']; +$meta['useacl'] = ['onoff', '_caution' => 'danger']; +$meta['autopasswd'] = ['onoff']; +$meta['authtype'] = ['authtype', '_caution' => 'danger']; +$meta['passcrypt'] = ['multichoice', + '_choices' => [ + 'smd5', + 'md5', + 'apr1', + 'sha1', + 'ssha', + 'lsmd5', + 'crypt', + 'mysql', + 'my411', + 'kmd5', + 'pmd5', + 'hmd5', + 'mediawiki', + 'bcrypt', + 'djangomd5', + 'djangosha1', + 'djangopbkdf2_sha1', + 'djangopbkdf2_sha256', + 'sha512', + 'argon2i', + 'argon2id'] +]; +$meta['defaultgroup'] = ['string']; +$meta['superuser'] = ['string', '_caution' => 'danger']; +$meta['manager'] = ['string']; +$meta['profileconfirm'] = ['onoff']; +$meta['rememberme'] = ['onoff']; +$meta['disableactions'] = ['disableactions', + '_choices' => [ 'backlink', 'index', 'recent', @@ -150,105 +166,98 @@ $meta['disableactions'] = array( 'wikicode', 'check', 'rss' - ), - '_combine' => array( - 'subscription' => array('subscribe', 'unsubscribe'), - 'wikicode' => array('source', 'export_raw') - ) -); -$meta['auth_security_timeout'] = array('numeric'); -$meta['securecookie'] = array('onoff'); -$meta['samesitecookie'] = array('multichoice','_choices' => array('','Lax','Strict','None')); -$meta['remote'] = array('onoff','_caution' => 'security'); -$meta['remoteuser'] = array('string'); -$meta['remotecors'] = array('string', '_caution' => 'security'); + ], + '_combine' => [ + 'subscription' => ['subscribe', 'unsubscribe'], + 'wikicode' => ['source', 'export_raw'] + ] +]; +$meta['auth_security_timeout'] = ['numeric']; +$meta['securecookie'] = ['onoff']; +$meta['samesitecookie'] = ['multichoice', '_choices' => ['', 'Lax', 'Strict', 'None']]; +$meta['remote'] = ['onoff', '_caution' => 'security']; +$meta['remoteuser'] = ['string']; +$meta['remotecors'] = ['string', '_caution' => 'security']; -$meta['_anti_spam'] = array('fieldset'); -$meta['usewordblock']= array('onoff'); -$meta['relnofollow'] = array('onoff'); -$meta['indexdelay'] = array('numeric'); -$meta['mailguard'] = array('multichoice','_choices' => array('visible','hex','none')); -$meta['iexssprotect']= array('onoff','_caution' => 'security'); +$meta['_anti_spam'] = ['fieldset']; +$meta['usewordblock'] = ['onoff']; +$meta['relnofollow'] = ['onoff']; +$meta['indexdelay'] = ['numeric']; +$meta['mailguard'] = ['multichoice', '_choices' => ['visible', 'hex', 'none']]; +$meta['iexssprotect'] = ['onoff', '_caution' => 'security']; -$meta['_editing'] = array('fieldset'); -$meta['usedraft'] = array('onoff'); -$meta['locktime'] = array('numeric'); -$meta['cachetime'] = array('numeric'); +$meta['_editing'] = ['fieldset']; +$meta['usedraft'] = ['onoff']; +$meta['locktime'] = ['numeric']; +$meta['cachetime'] = ['numeric']; -$meta['_links'] = array('fieldset'); -$meta['target____wiki'] = array('string'); -$meta['target____interwiki'] = array('string'); -$meta['target____extern'] = array('string'); -$meta['target____media'] = array('string'); -$meta['target____windows'] = array('string'); +$meta['_links'] = ['fieldset']; +$meta['target____wiki'] = ['string']; +$meta['target____interwiki'] = ['string']; +$meta['target____extern'] = ['string']; +$meta['target____media'] = ['string']; +$meta['target____windows'] = ['string']; -$meta['_media'] = array('fieldset'); -$meta['mediarevisions'] = array('onoff'); -$meta['gdlib'] = array('multichoice','_choices' => array(0,1,2)); -$meta['im_convert'] = array('im_convert'); -$meta['jpg_quality'] = array('numeric','_pattern' => '/^100$|^[1-9]?[0-9]$/'); //(0-100) -$meta['fetchsize'] = array('numeric'); -$meta['refcheck'] = array('onoff'); +$meta['_media'] = ['fieldset']; +$meta['mediarevisions'] = ['onoff']; +$meta['gdlib'] = ['multichoice', '_choices' => [0, 1, 2]]; +$meta['im_convert'] = ['im_convert']; +$meta['jpg_quality'] = ['numeric', '_pattern' => '/^100$|^[1-9]?\d$/']; //(0-100) +$meta['fetchsize'] = ['numeric']; +$meta['refcheck'] = ['onoff']; -$meta['_notifications'] = array('fieldset'); -$meta['subscribers'] = array('onoff'); -$meta['subscribe_time'] = array('numeric'); -$meta['notify'] = array('email', '_multiple' => true); -$meta['registernotify'] = array('email', '_multiple' => true); -$meta['mailfrom'] = array('email', '_placeholders' => true); -$meta['mailreturnpath'] = array('email', '_placeholders' => true); -$meta['mailprefix'] = array('string'); -$meta['htmlmail'] = array('onoff'); -$meta['dontlog'] = array( - 'disableactions', - '_choices' => array( - 'error', - 'debug', - 'deprecated', - ), -); +$meta['_notifications'] = ['fieldset']; +$meta['subscribers'] = ['onoff']; +$meta['subscribe_time'] = ['numeric']; +$meta['notify'] = ['email', '_multiple' => true]; +$meta['registernotify'] = ['email', '_multiple' => true]; +$meta['mailfrom'] = ['email', '_placeholders' => true]; +$meta['mailreturnpath'] = ['email', '_placeholders' => true]; +$meta['mailprefix'] = ['string']; +$meta['htmlmail'] = ['onoff']; +$meta['dontlog'] = ['disableactions', '_choices' => ['error', 'debug', 'deprecated']]; -$meta['_syndication'] = array('fieldset'); -$meta['sitemap'] = array('numeric'); -$meta['rss_type'] = array('multichoice','_choices' => array('rss','rss1','rss2','atom','atom1')); -$meta['rss_linkto'] = array('multichoice','_choices' => array('diff','page','rev','current')); -$meta['rss_content'] = array('multichoice','_choices' => array('abstract','diff','htmldiff','html')); -$meta['rss_media'] = array('multichoice','_choices' => array('both','pages','media')); -$meta['rss_update'] = array('numeric'); -$meta['rss_show_summary'] = array('onoff'); -$meta['rss_show_deleted'] = array('onoff'); +$meta['_syndication'] = ['fieldset']; +$meta['sitemap'] = ['numeric']; +$meta['rss_type'] = ['multichoice', '_choices' => ['rss', 'rss1', 'rss2', 'atom', 'atom1']]; +$meta['rss_linkto'] = ['multichoice', '_choices' => ['diff', 'page', 'rev', 'current']]; +$meta['rss_content'] = ['multichoice', '_choices' => ['abstract', 'diff', 'htmldiff', 'html']]; +$meta['rss_media'] = ['multichoice', '_choices' => ['both', 'pages', 'media']]; +$meta['rss_update'] = ['numeric']; +$meta['rss_show_summary'] = ['onoff']; +$meta['rss_show_deleted'] = ['onoff']; -$meta['_advanced'] = array('fieldset'); -$meta['updatecheck'] = array('onoff'); -$meta['userewrite'] = array('multichoice','_choices' => array(0,1,2),'_caution' => 'danger'); -$meta['useslash'] = array('onoff'); -$meta['sepchar'] = array('sepchar','_caution' => 'warning'); -$meta['canonical'] = array('onoff'); -$meta['fnencode'] = array('multichoice','_choices' => array('url','safe','utf-8'),'_caution' => 'warning'); -$meta['autoplural'] = array('onoff'); -$meta['compress'] = array('onoff'); -$meta['cssdatauri'] = array('numeric','_pattern' => '/^\d+$/'); -$meta['gzip_output'] = array('onoff'); -$meta['send404'] = array('onoff'); -$meta['compression'] = array('compression','_caution' => 'warning'); -$meta['broken_iua'] = array('onoff'); -$meta['xsendfile'] = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'warning'); -$meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'),'_caution' => 'warning'); -$meta['readdircache'] = array('numeric'); -$meta['search_nslimit'] = array('numeric', '_min' => 0); -$meta['search_fragment'] = array('multichoice','_choices' => array('exact', 'starts_with', 'ends_with', 'contains'),); -$meta['trustedproxy'] = array('regex'); +$meta['_advanced'] = ['fieldset']; +$meta['updatecheck'] = ['onoff']; +$meta['userewrite'] = ['multichoice', '_choices' => [0, 1, 2], '_caution' => 'danger']; +$meta['useslash'] = ['onoff']; +$meta['sepchar'] = ['sepchar', '_caution' => 'warning']; +$meta['canonical'] = ['onoff']; +$meta['fnencode'] = ['multichoice', '_choices' => ['url', 'safe', 'utf-8'], '_caution' => 'warning']; +$meta['autoplural'] = ['onoff']; +$meta['compress'] = ['onoff']; +$meta['cssdatauri'] = ['numeric', '_pattern' => '/^\d+$/']; +$meta['gzip_output'] = ['onoff']; +$meta['send404'] = ['onoff']; +$meta['compression'] = ['compression', '_caution' => 'warning']; +$meta['broken_iua'] = ['onoff']; +$meta['xsendfile'] = ['multichoice', '_choices' => [0, 1, 2, 3], '_caution' => 'warning']; +$meta['renderer_xhtml'] = ['renderer', '_format' => 'xhtml', '_choices' => ['xhtml'], '_caution' => 'warning']; +$meta['readdircache'] = ['numeric']; +$meta['search_nslimit'] = ['numeric', '_min' => 0]; +$meta['search_fragment'] = ['multichoice', '_choices' => ['exact', 'starts_with', 'ends_with', 'contains']]; +$meta['trustedproxy'] = ['regex']; $meta['_feature_flags'] = ['fieldset']; -$meta['defer_js'] = ['onoff']; -$meta['hidewarnings'] = ['onoff']; +$meta['defer_js'] = ['onoff']; +$meta['hidewarnings'] = ['onoff']; -$meta['_network'] = array('fieldset'); -$meta['dnslookups'] = array('onoff'); -$meta['jquerycdn'] = array('multichoice', '_choices' => array(0,'jquery', 'cdnjs')); -$meta['proxy____host'] = array('string','_pattern' => '#^(|[a-z0-9\-\.+]+)$#i'); -$meta['proxy____port'] = array('numericopt'); -$meta['proxy____user'] = array('string'); -$meta['proxy____pass'] = array('password','_code' => 'base64'); -$meta['proxy____ssl'] = array('onoff'); -$meta['proxy____except'] = array('string'); +$meta['_network'] = ['fieldset']; +$meta['dnslookups'] = ['onoff']; +$meta['jquerycdn'] = ['multichoice', '_choices' => [0, 'jquery', 'cdnjs']]; +$meta['proxy____host'] = ['string', '_pattern' => '#^(|[a-z0-9\-\.+]+)$#i']; +$meta['proxy____port'] = ['numericopt']; +$meta['proxy____user'] = ['string']; +$meta['proxy____pass'] = ['password', '_code' => 'base64']; +$meta['proxy____ssl'] = ['onoff']; +$meta['proxy____except'] = ['string']; diff --git a/lib/plugins/extension/action.php b/lib/plugins/extension/action.php index b57fe558e..116208a40 100644 --- a/lib/plugins/extension/action.php +++ b/lib/plugins/extension/action.php @@ -1,20 +1,23 @@ <?php + +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; +use dokuwiki\Extension\Event; + /** DokuWiki Plugin extension (Action Component) * * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html * @author Andreas Gohr <andi@splitbrain.org> */ - -class action_plugin_extension extends DokuWiki_Action_Plugin +class action_plugin_extension extends ActionPlugin { - /** * Registers a callback function for a given event * - * @param Doku_Event_Handler $controller DokuWiki's event controller object + * @param EventHandler $controller DokuWiki's event controller object * @return void */ - public function register(Doku_Event_Handler $controller) + public function register(EventHandler $controller) { $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'info'); } @@ -22,10 +25,10 @@ class action_plugin_extension extends DokuWiki_Action_Plugin /** * Create the detail info for a single plugin * - * @param Doku_Event $event - * @param $param + * @param Event $event + * @param $param */ - public function info(Doku_Event $event, $param) + public function info(Event $event, $param) { global $USERINFO; global $INPUT; @@ -57,7 +60,7 @@ class action_plugin_extension extends DokuWiki_Action_Plugin switch ($act) { case 'enable': case 'disable': - if(getSecurityToken() != $INPUT->str('sectok')) { + if (getSecurityToken() != $INPUT->str('sectok')) { http_status(403); echo 'Security Token did not match. Possible CSRF attack.'; return; @@ -66,14 +69,14 @@ class action_plugin_extension extends DokuWiki_Action_Plugin $extension->$act(); //enables/disables $reverse = ($act == 'disable') ? 'enable' : 'disable'; - $return = array( - 'state' => $act.'d', // isn't English wonderful? :-) + $return = [ + 'state' => $act . 'd', // isn't English wonderful? :-) 'reverse' => $reverse, - 'label' => $extension->getLang('btn_'.$reverse) - ); + 'label' => $extension->getLang('btn_' . $reverse), + ]; header('Content-Type: application/json'); - echo json_encode($return); + echo json_encode($return, JSON_THROW_ON_ERROR); break; case 'info': diff --git a/lib/plugins/extension/admin.php b/lib/plugins/extension/admin.php index 7e7eb60d4..edced2134 100644 --- a/lib/plugins/extension/admin.php +++ b/lib/plugins/extension/admin.php @@ -1,4 +1,7 @@ <?php + +use dokuwiki\Extension\AdminPlugin; + /** * DokuWiki Plugin extension (Admin Component) * @@ -9,9 +12,9 @@ /** * Admin part of the extension manager */ -class admin_plugin_extension extends DokuWiki_Admin_Plugin +class admin_plugin_extension extends AdminPlugin { - protected $infoFor = null; + protected $infoFor; /** @var helper_plugin_extension_gui */ protected $gui; @@ -53,9 +56,8 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin if (!$repository->hasAccess(!$INPUT->bool('purge'))) { $url = $this->gui->tabURL('', ['purge' => 1], '&'); - msg($this->getLang('repo_error'). - ' [<a href="'.$url.'">'.$this->getLang('repo_retry').'</a>]', -1 - ); + msg($this->getLang('repo_error') . + ' [<a href="' . $url . '">' . $this->getLang('repo_retry') . '</a>]', -1); } if (!in_array('ssl', stream_get_transports())) { @@ -76,11 +78,11 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin case 'update': $extension->setExtension($extname); $installed = $extension->installOrUpdate(); - foreach ($installed as $ext => $info) { + foreach ($installed as $info) { msg(sprintf( - $this->getLang('msg_'.$info['type'].'_'.$info['action'].'_success'), - $info['base']), 1 - ); + $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'), + $info['base'] + ), 1); } break; case 'uninstall': @@ -89,13 +91,13 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin if ($status) { msg(sprintf( $this->getLang('msg_delete_success'), - hsc($extension->getDisplayName())), 1 - ); + hsc($extension->getDisplayName()) + ), 1); } else { msg(sprintf( $this->getLang('msg_delete_failed'), - hsc($extension->getDisplayName())), -1 - ); + hsc($extension->getDisplayName()) + ), -1); } break; case 'enable': @@ -106,8 +108,8 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin } else { msg(sprintf( $this->getLang('msg_enabled'), - hsc($extension->getDisplayName())), 1 - ); + hsc($extension->getDisplayName()) + ), 1); } break; case 'disable': @@ -118,8 +120,8 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin } else { msg(sprintf( $this->getLang('msg_disabled'), - hsc($extension->getDisplayName())), 1 - ); + hsc($extension->getDisplayName()) + ), 1); } break; } @@ -129,21 +131,22 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin } elseif ($INPUT->post->str('installurl') && checkSecurityToken()) { $installed = $extension->installFromURL( $INPUT->post->str('installurl'), - $INPUT->post->bool('overwrite')); - foreach ($installed as $ext => $info) { + $INPUT->post->bool('overwrite') + ); + foreach ($installed as $info) { msg(sprintf( - $this->getLang('msg_'.$info['type'].'_'.$info['action'].'_success'), - $info['base']), 1 - ); + $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'), + $info['base'] + ), 1); } send_redirect($this->gui->tabURL('', [], '&', true)); } elseif (isset($_FILES['installfile']) && checkSecurityToken()) { $installed = $extension->installFromUpload('installfile', $INPUT->post->bool('overwrite')); - foreach ($installed as $ext => $info) { + foreach ($installed as $info) { msg(sprintf( - $this->getLang('msg_'.$info['type'].'_'.$info['action'].'_success'), - $info['base']), 1 - ); + $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'), + $info['base'] + ), 1); } send_redirect($this->gui->tabURL('', [], '&', true)); } @@ -158,8 +161,8 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin */ public function html() { - echo '<h1>'.$this->getLang('menu').'</h1>'.DOKU_LF; - echo '<div id="extension__manager">'.DOKU_LF; + echo '<h1>' . $this->getLang('menu') . '</h1>' . DOKU_LF; + echo '<div id="extension__manager">' . DOKU_LF; $this->gui->tabNavigation(); @@ -178,7 +181,7 @@ class admin_plugin_extension extends DokuWiki_Admin_Plugin $this->gui->tabPlugins(); } - echo '</div>'.DOKU_LF; + echo '</div>' . DOKU_LF; } } diff --git a/lib/plugins/extension/cli.php b/lib/plugins/extension/cli.php index 0e1bf83d5..4e6200ba2 100644 --- a/lib/plugins/extension/cli.php +++ b/lib/plugins/extension/cli.php @@ -1,5 +1,8 @@ <?php +use dokuwiki\Extension\CLIPlugin; +use splitbrain\phpcli\Options; +use splitbrain\phpcli\TableFormatter; use splitbrain\phpcli\Colors; /** @@ -10,10 +13,10 @@ use splitbrain\phpcli\Colors; * @license GPL2 * @author Andreas Gohr <andi@splitbrain.org> */ -class cli_plugin_extension extends DokuWiki_CLI_Plugin +class cli_plugin_extension extends CLIPlugin { /** @inheritdoc */ - protected function setup(\splitbrain\phpcli\Options $options) + protected function setup(Options $options) { // general setup $options->setHelp( @@ -42,8 +45,11 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin // install $options->registerCommand('install', 'Install or upgrade extensions'); - $options->registerArgument('extensions...', - 'One or more extensions to install. Either by name or download URL', true, 'install' + $options->registerArgument( + 'extensions...', + 'One or more extensions to install. Either by name or download URL', + true, + 'install' ); // uninstall @@ -57,12 +63,10 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin // disable $options->registerCommand('disable', 'Disable installed extensions'); $options->registerArgument('extensions...', 'One or more extensions to disable', true, 'disable'); - - } /** @inheritdoc */ - protected function main(\splitbrain\phpcli\Options $options) + protected function main(Options $options) { /** @var helper_plugin_extension_repository $repo */ $repo = plugin_load('helper', 'extension_repository'); @@ -145,7 +149,7 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin $ext->setExtension($extname); if (!$ext->isInstalled()) { $this->error(sprintf('Extension %s is not installed', $ext->getID())); - $ok += 1; + ++$ok; continue; } @@ -159,7 +163,7 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin if ($status !== true) { $this->error($status); - $ok += 1; + ++$ok; continue; } else { $this->success(sprintf($this->getLang($msg), $ext->getID())); @@ -185,7 +189,7 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin $ext->setExtension($extname); if (!$ext->isInstalled()) { $this->error(sprintf('Extension %s is not installed', $ext->getID())); - $ok += 1; + ++$ok; continue; } @@ -221,13 +225,13 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin $installed = $ext->installFromURL($extname, true); } catch (Exception $e) { $this->error($e->getMessage()); - $ok += 1; + ++$ok; } } else { $ext->setExtension($extname); if (!$ext->getDownloadURL()) { - $ok += 1; + ++$ok; $this->error( sprintf('Could not find download for %s', $ext->getID()) ); @@ -238,11 +242,11 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin $installed = $ext->installOrUpdate(); } catch (Exception $e) { $this->error($e->getMessage()); - $ok += 1; + ++$ok; } } - foreach ($installed as $name => $info) { + foreach ($installed as $info) { $this->success( sprintf( $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'), @@ -301,9 +305,8 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin global $plugin_controller; $pluginlist = $plugin_controller->getList('', true); $tpllist = glob(DOKU_INC . 'lib/tpl/*', GLOB_ONLYDIR); - $tpllist = array_map(function ($path) { - return 'template:' . basename($path); - }, $tpllist); + $tpllist = array_map(static fn($path) => 'template:' . basename($path), $tpllist); + $list = array_merge($pluginlist, $tpllist); sort($list); return $list; @@ -321,7 +324,7 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin { /** @var helper_plugin_extension_extension $ext */ $ext = $this->loadHelper('extension_extension'); - $tr = new \splitbrain\phpcli\TableFormatter($this->colors); + $tr = new TableFormatter($this->colors); foreach ($list as $name) { @@ -363,10 +366,10 @@ class cli_plugin_extension extends DokuWiki_CLI_Plugin $status, $date, strip_tags(sprintf( - $this->getLang('extensionby'), - $ext->getDisplayName(), - $this->colors->wrap($ext->getAuthor(), Colors::C_PURPLE)) - ) + $this->getLang('extensionby'), + $ext->getDisplayName(), + $this->colors->wrap($ext->getAuthor(), Colors::C_PURPLE) + )) ], [ $ecolor, diff --git a/lib/plugins/extension/helper/extension.php b/lib/plugins/extension/helper/extension.php index 1d06f0482..84c731fcc 100644 --- a/lib/plugins/extension/helper/extension.php +++ b/lib/plugins/extension/helper/extension.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki Plugin extension (Helper Component) * @@ -6,13 +7,19 @@ * @author Michael Hamann <michael@content-space.de> */ +use dokuwiki\Extension\Plugin; +use dokuwiki\Extension\PluginInterface; +use dokuwiki\Utf8\PhpString; +use splitbrain\PHPArchive\Tar; +use splitbrain\PHPArchive\ArchiveIOException; +use splitbrain\PHPArchive\Zip; use dokuwiki\HTTP\DokuHTTPClient; use dokuwiki\Extension\PluginController; /** * Class helper_plugin_extension_extension represents a single extension (plugin or template) */ -class helper_plugin_extension_extension extends DokuWiki_Plugin +class helper_plugin_extension_extension extends Plugin { private $id; private $base; @@ -21,10 +28,10 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin private $remoteInfo; private $managerData; /** @var helper_plugin_extension_repository $repository */ - private $repository = null; + private $repository; /** @var array list of temporary directories */ - private $temporary = array(); + private $temporary = []; /** @var string where templates are installed to */ private $tpllib = ''; @@ -34,7 +41,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin */ public function __construct() { - $this->tpllib = dirname(tpl_incdir()).'/'; + $this->tpllib = dirname(tpl_incdir()) . '/'; } /** @@ -67,6 +74,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { $id = cleanID($id); $this->id = $id; + $this->base = $id; if (substr($id, 0, 9) == 'template:') { @@ -76,9 +84,9 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin $this->is_template = false; } - $this->localInfo = array(); - $this->managerData = array(); - $this->remoteInfo = array(); + $this->localInfo = []; + $this->managerData = []; + $this->remoteInfo = []; if ($this->isInstalled()) { $this->readLocalData(); @@ -112,7 +120,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function isGitControlled() { if (!$this->isInstalled()) return false; - return file_exists($this->getInstallDir().'/.git'); + return file_exists($this->getInstallDir() . '/.git'); } /** @@ -125,12 +133,24 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin if (!empty($this->remoteInfo['bundled'])) return $this->remoteInfo['bundled']; return in_array( $this->id, - array( - 'authad', 'authldap', 'authpdo', 'authplain', - 'acl', 'config', 'extension', 'info', 'popularity', 'revert', - 'safefnrecode', 'styling', 'testing', 'usermanager', 'logviewer', - 'template:dokuwiki', - ) + [ + 'authad', + 'authldap', + 'authpdo', + 'authplain', + 'acl', + 'config', + 'extension', + 'info', + 'popularity', + 'revert', + 'safefnrecode', + 'styling', + 'testing', + 'usermanager', + 'logviewer', + 'template:dokuwiki' + ] ); } @@ -306,8 +326,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getURL() { if (!empty($this->localInfo['url'])) return $this->localInfo['url']; - return 'https://www.dokuwiki.org/'. - ($this->isTemplate() ? 'template' : 'plugin').':'.$this->getBase(); + return 'https://www.dokuwiki.org/' . + ($this->isTemplate() ? 'template' : 'plugin') . ':' . $this->getBase(); } /** @@ -352,7 +372,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getDependencies() { if (!empty($this->remoteInfo['dependencies'])) return $this->remoteInfo['dependencies']; - return array(); + return []; } /** @@ -365,7 +385,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin /* @var PluginController $plugin_controller */ global $plugin_controller; $dependencies = $this->getDependencies(); - $missing_dependencies = array(); + $missing_dependencies = []; foreach ($dependencies as $dependency) { if (!$plugin_controller->isEnabled($dependency)) { $missing_dependencies[] = $dependency; @@ -382,7 +402,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getConflicts() { if (!empty($this->remoteInfo['conflicts'])) return $this->remoteInfo['conflicts']; - return array(); + return []; } /** @@ -393,7 +413,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getSimilarExtensions() { if (!empty($this->remoteInfo['similar'])) return $this->remoteInfo['similar']; - return array(); + return []; } /** @@ -404,7 +424,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getTags() { if (!empty($this->remoteInfo['tags'])) return $this->remoteInfo['tags']; - return array(); + return []; } /** @@ -537,8 +557,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getTypes() { if (!empty($this->remoteInfo['types'])) return $this->remoteInfo['types']; - if ($this->isTemplate()) return array(32 => 'template'); - return array(); + if ($this->isTemplate()) return [32 => 'template']; + return []; } /** @@ -549,7 +569,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getCompatibleVersions() { if (!empty($this->remoteInfo['compatible'])) return $this->remoteInfo['compatible']; - return array(); + return []; } /** @@ -571,9 +591,9 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function getInstallDir() { if ($this->isTemplate()) { - return $this->tpllib.$this->base; + return $this->tpllib . $this->base; } else { - return DOKU_PLUGIN.$this->base; + return DOKU_PLUGIN . $this->base; } } @@ -586,7 +606,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { if (!$this->isInstalled()) return 'none'; if (!empty($this->managerData)) return 'automatic'; - if (is_dir($this->getInstallDir().'/.git')) return 'git'; + if (is_dir($this->getInstallDir() . '/.git')) return 'git'; return 'manual'; } @@ -622,7 +642,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin public function installFromUpload($field, $overwrite = true) { if ($_FILES[$field]['error']) { - throw new Exception($this->getLang('msg_upload_failed').' ('.$_FILES[$field]['error'].')'); + throw new Exception($this->getLang('msg_upload_failed') . ' (' . $_FILES[$field]['error'] . ')'); } $tmp = $this->mkTmpDir(); @@ -636,16 +656,10 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin if (!move_uploaded_file($_FILES[$field]['tmp_name'], "$tmp/upload.archive")) { throw new Exception($this->getLang('msg_upload_failed')); } - - try { - $installed = $this->installArchive("$tmp/upload.archive", $overwrite, $basename); - $this->updateManagerData('', $installed); - $this->removeDeletedfiles($installed); - // purge cache - $this->purgeCache(); - } catch (Exception $e) { - throw $e; - } + $installed = $this->installArchive("$tmp/upload.archive", $overwrite, $basename); + $this->updateManagerData('', $installed); + $this->removeDeletedfiles($installed); + $this->purgeCache(); return $installed; } @@ -659,17 +673,11 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin */ public function installFromURL($url, $overwrite = true) { - try { - $path = $this->download($url); - $installed = $this->installArchive($path, $overwrite); - $this->updateManagerData($url, $installed); - $this->removeDeletedfiles($installed); - - // purge cache - $this->purgeCache(); - } catch (Exception $e) { - throw $e; - } + $path = $this->download($url); + $installed = $this->installArchive($path, $overwrite); + $this->updateManagerData($url, $installed); + $this->removeDeletedfiles($installed); + $this->purgeCache(); return $installed; } @@ -767,37 +775,36 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin protected function readLocalData() { if ($this->isTemplate()) { - $infopath = $this->getInstallDir().'/template.info.txt'; + $infopath = $this->getInstallDir() . '/template.info.txt'; } else { - $infopath = $this->getInstallDir().'/plugin.info.txt'; + $infopath = $this->getInstallDir() . '/plugin.info.txt'; } if (is_readable($infopath)) { $this->localInfo = confToHash($infopath); } elseif (!$this->isTemplate() && $this->isEnabled()) { - $path = $this->getInstallDir().'/'; + $path = $this->getInstallDir() . '/'; $plugin = null; foreach (PluginController::PLUGIN_TYPES as $type) { - if (file_exists($path.$type.'.php')) { + if (file_exists($path . $type . '.php')) { $plugin = plugin_load($type, $this->base); - if ($plugin) break; + if ($plugin instanceof PluginInterface) break; } - if ($dh = @opendir($path.$type.'/')) { + if ($dh = @opendir($path . $type . '/')) { while (false !== ($cp = readdir($dh))) { if ($cp == '.' || $cp == '..' || strtolower(substr($cp, -4)) != '.php') continue; - $plugin = plugin_load($type, $this->base.'_'.substr($cp, 0, -4)); - if ($plugin) break; + $plugin = plugin_load($type, $this->base . '_' . substr($cp, 0, -4)); + if ($plugin instanceof PluginInterface) break; } - if ($plugin) break; + if ($plugin instanceof PluginInterface) break; closedir($dh); } } - if ($plugin) { - /* @var DokuWiki_Plugin $plugin */ + if ($plugin instanceof PluginInterface) { $this->localInfo = $plugin->getInfo(); } } @@ -814,10 +821,10 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin $origID = $this->getID(); if (is_null($installed)) { - $installed = array($origID); + $installed = [$origID]; } - foreach ($installed as $ext => $info) { + foreach (array_keys($installed) as $ext) { if ($this->getID() != $ext) $this->setExtension($ext); if ($url) { $this->managerData['downloadurl'] = $url; @@ -840,12 +847,12 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin */ protected function readManagerData() { - $managerpath = $this->getInstallDir().'/manager.dat'; + $managerpath = $this->getInstallDir() . '/manager.dat'; if (is_readable($managerpath)) { $file = @file($managerpath); if (!empty($file)) { foreach ($file as $line) { - list($key, $value) = sexplode('=', trim($line, DOKU_LF), 2, ''); + [$key, $value] = sexplode('=', trim($line, DOKU_LF), 2, ''); $key = trim($key); $value = trim($value); // backwards compatible with old plugin manager @@ -861,10 +868,10 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin */ protected function writeManagerData() { - $managerpath = $this->getInstallDir().'/manager.dat'; + $managerpath = $this->getInstallDir() . '/manager.dat'; $data = ''; foreach ($this->managerData as $k => $v) { - $data .= $k.'='.$v.DOKU_LF; + $data .= $k . '=' . $v . DOKU_LF; } io_saveFile($managerpath, $data); } @@ -913,13 +920,13 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin $name = ''; if (isset($http->resp_headers['content-disposition'])) { $content_disposition = $http->resp_headers['content-disposition']; - $match = array(); - if (is_string($content_disposition) && + $match = []; + if ( + is_string($content_disposition) && preg_match('/attachment;\s*filename\s*=\s*"([^"]*)"/i', $content_disposition, $match) ) { - $name = \dokuwiki\Utf8\PhpString::basename($match[1]); + $name = PhpString::basename($match[1]); } - } if (!$name) { @@ -927,14 +934,14 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin $name = $defaultName; } - $file = $file.$name; + $file .= $name; $fileexists = file_exists($file); - $fp = @fopen($file,"w"); + $fp = @fopen($file, "w"); if (!$fp) return false; fwrite($fp, $data); fclose($fp); - if (!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); + if (!$fileexists && $conf['fperm']) chmod($file, $conf['fperm']); return $name; } @@ -957,7 +964,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin if (is_null($file)) { $file = md5($url); } else { - $file = \dokuwiki\Utf8\PhpString::basename($file); + $file = PhpString::basename($file); } // create tmp directory for download @@ -966,14 +973,15 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin } // download - if (!$file = $this->downloadToFile($url, $tmp.'/', $file)) { + if (!$file = $this->downloadToFile($url, $tmp . '/', $file)) { io_rmdir($tmp, true); - throw new Exception(sprintf($this->getLang('error_download'), - '<bdi>'.hsc($url).'</bdi>') - ); + throw new Exception(sprintf( + $this->getLang('error_download'), + '<bdi>' . hsc($url) . '</bdi>' + )); } - return $tmp.'/'.$file; + return $tmp . '/' . $file; } /** @@ -985,7 +993,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin */ public function installArchive($file, $overwrite = false, $base = '') { - $installed_extensions = array(); + $installed_extensions = []; // create tmp directory for decompression if (!($tmp = $this->mkTmpDir())) { @@ -993,18 +1001,18 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin } // add default base folder if specified to handle case where zip doesn't contain this - if ($base && !@mkdir($tmp.'/'.$base)) { + if ($base && !@mkdir($tmp . '/' . $base)) { throw new Exception($this->getLang('error_dircreate')); } // decompress - $this->decompress($file, "$tmp/".$base); + $this->decompress($file, "$tmp/" . $base); // search $tmp/$base for the folder(s) that has been created // move the folder(s) to lib/.. - $result = array('old'=>array(), 'new'=>array()); + $result = ['old' => [], 'new' => []]; $default = ($this->isTemplate() ? 'template' : 'plugin'); - if (!$this->findFolders($result, $tmp.'/'.$base, $default)) { + if (!$this->findFolders($result, $tmp . '/' . $base, $default)) { throw new Exception($this->getLang('error_findfolder')); } @@ -1040,7 +1048,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin } // check to make sure we aren't overwriting anything - $target = $target_base_dir.$item['base']; + $target = $target_base_dir . $item['base']; if (!$overwrite && file_exists($target)) { // this info message is not being exposed via exception, // so that it's not interrupting the installation @@ -1055,17 +1063,18 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin // return info $id = $item['base']; if ($item['type'] == 'template') { - $id = 'template:'.$id; + $id = 'template:' . $id; } - $installed_extensions[$id] = array( + $installed_extensions[$id] = [ 'base' => $item['base'], 'type' => $item['type'], 'action' => $action - ); + ]; } else { - throw new Exception(sprintf($this->getLang('error_copy').DOKU_LF, - '<bdi>'.$item['base'].'</bdi>') - ); + throw new Exception(sprintf( + $this->getLang('error_copy') . DOKU_LF, + '<bdi>' . $item['base'] . '</bdi>' + )); } } @@ -1105,7 +1114,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin $dh = @opendir($this_dir); if (!$dh) return false; - $found_dirs = array(); + $found_dirs = []; $found_files = 0; $found_template_parts = 0; while (false !== ($f = readdir($dh))) { @@ -1120,7 +1129,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin case 'plugin.info.txt': case 'template.info.txt': // we have found a clear marker, save and return - $info = array(); + $info = []; $type = explode('.', $f, 2); $info['type'] = $type[0]; $info['tmp'] = $this_dir; @@ -1142,7 +1151,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin // files where found but no info.txt - use old method if ($found_files) { - $info = array(); + $info = []; $info['tmp'] = $this_dir; // does this look like a template or should we use the default type? if ($found_template_parts >= 2) { @@ -1178,23 +1187,23 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin if (substr($target, -1) == "/") $target = substr($target, 0, -1); $ext = $this->guessArchiveType($file); - if (in_array($ext, array('tar', 'bz', 'gz'))) { + if (in_array($ext, ['tar', 'bz', 'gz'])) { try { - $tar = new \splitbrain\PHPArchive\Tar(); + $tar = new Tar(); $tar->open($file); $tar->extract($target); - } catch (\splitbrain\PHPArchive\ArchiveIOException $e) { - throw new Exception($this->getLang('error_decompress').' '.$e->getMessage()); + } catch (ArchiveIOException $e) { + throw new Exception($this->getLang('error_decompress') . ' ' . $e->getMessage(), $e->getCode(), $e); } return true; } elseif ($ext == 'zip') { try { - $zip = new \splitbrain\PHPArchive\Zip(); + $zip = new Zip(); $zip->open($file); $zip->extract($target); - } catch (\splitbrain\PHPArchive\ArchiveIOException $e) { - throw new Exception($this->getLang('error_decompress').' '.$e->getMessage()); + } catch (ArchiveIOException $e) { + throw new Exception($this->getLang('error_decompress') . ' ' . $e->getMessage(), $e->getCode(), $e); } return true; @@ -1202,7 +1211,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin // the only case when we don't get one of the recognized archive types is // when the archive file can't be read - throw new Exception($this->getLang('error_decompress').' Couldn\'t read archive file'); + throw new Exception($this->getLang('error_decompress') . ' Couldn\'t read archive file'); } /** @@ -1269,7 +1278,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin */ private function removeDeletedfiles($installed) { - foreach ($installed as $id => $extension) { + foreach ($installed as $extension) { // only on update if ($extension['action'] == 'install') continue; @@ -1279,7 +1288,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin } else { $extensiondir = DOKU_PLUGIN; } - $extensiondir = $extensiondir . $extension['base'] .'/'; + $extensiondir = $extensiondir . $extension['base'] . '/'; $definitionfile = $extensiondir . 'deleted.files'; if (!file_exists($definitionfile)) continue; diff --git a/lib/plugins/extension/helper/gui.php b/lib/plugins/extension/helper/gui.php index 919eb2c0b..4495af1e5 100644 --- a/lib/plugins/extension/helper/gui.php +++ b/lib/plugins/extension/helper/gui.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki Plugin extension (Helper Component) * @@ -6,14 +7,15 @@ * @author Andreas Gohr <andi@splitbrain.org> */ +use dokuwiki\Extension\Plugin; use dokuwiki\Form\Form; /** * Class helper_plugin_extension_list takes care of the overall GUI */ -class helper_plugin_extension_gui extends DokuWiki_Plugin +class helper_plugin_extension_gui extends Plugin { - protected $tabs = array('plugins', 'templates', 'search', 'install'); + protected $tabs = ['plugins', 'templates', 'search', 'install']; /** @var string the extension that should have an open info window FIXME currently broken */ protected $infoFor = ''; @@ -45,8 +47,8 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin $list = $this->loadHelper('extension_list'); $form = new Form([ - 'action' => $this->tabURL('', [], '&'), - 'id' => 'extension__list', + 'action' => $this->tabURL('', [], '&'), + 'id' => 'extension__list', ]); $list->startForm(); foreach ($pluginlist as $name) { @@ -68,7 +70,7 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin echo '</div>'; // FIXME do we have a real way? - $tpllist = glob(DOKU_INC.'lib/tpl/*', GLOB_ONLYDIR); + $tpllist = glob(DOKU_INC . 'lib/tpl/*', GLOB_ONLYDIR); $tpllist = array_map('basename', $tpllist); sort($tpllist); @@ -78,8 +80,8 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin $list = $this->loadHelper('extension_list'); $form = new Form([ - 'action' => $this->tabURL('', [], '&'), - 'id' => 'extension__list', + 'action' => $this->tabURL('', [], '&'), + 'id' => 'extension__list', ]); $list->startForm(); foreach ($tpllist as $name) { @@ -102,8 +104,8 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin echo '</div>'; $form = new Form([ - 'action' => $this->tabURL('', [], '&'), - 'class' => 'search', + 'action' => $this->tabURL('', [], '&'), + 'class' => 'search', ]); $form->addTagOpen('div')->addClass('no'); $form->addTextInput('q', $this->getLang('search_for')) @@ -118,7 +120,7 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin /* @var helper_plugin_extension_repository $repository FIXME should we use some gloabl instance? */ $repository = $this->loadHelper('extension_repository'); - $result = $repository->search($INPUT->str('q')); + $result = $repository->search($INPUT->str('q')); /* @var helper_plugin_extension_extension $extension */ $extension = $this->loadHelper('extension_extension'); @@ -126,8 +128,8 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin $list = $this->loadHelper('extension_list'); $form = new Form([ - 'action' => $this->tabURL('', [], '&'), - 'id' => 'extension__list', + 'action' => $this->tabURL('', [], '&'), + 'id' => 'extension__list', ]); $list->startForm(); if ($result) { @@ -154,9 +156,9 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin echo '</div>'; $form = new Form([ - 'action' => $this->tabURL('', [], '&'), - 'enctype' => 'multipart/form-data', - 'class' => 'install', + 'action' => $this->tabURL('', [], '&'), + 'enctype' => 'multipart/form-data', + 'class' => 'install', ]); $form->addTagOpen('div')->addClass('no'); $form->addTextInput('installurl', $this->getLang('install_url')) @@ -191,7 +193,8 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin } else { $class = ''; } - echo '<li class="'.$tab.$class.'"><a href="'.$url.'">'.$this->getLang('tab_'.$tab).'</a></li>'; + echo '<li class="' . $tab . $class . '"><a href="' . $url . '">' . + $this->getLang('tab_' . $tab) . '</a></li>'; } echo '</ul>'; } @@ -213,10 +216,10 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin /** * Create an URL inside the extension manager * - * @param string $tab tab to load, empty for current tab - * @param array $params associative array of parameter to set - * @param string $sep seperator to build the URL - * @param bool $absolute create absolute URLs? + * @param string $tab tab to load, empty for current tab + * @param array $params associative array of parameter to set + * @param string $sep seperator to build the URL + * @param bool $absolute create absolute URLs? * @return string */ public function tabURL($tab = '', $params = [], $sep = '&', $absolute = false) @@ -225,11 +228,11 @@ class helper_plugin_extension_gui extends DokuWiki_Plugin global $INPUT; if (!$tab) $tab = $this->currentTab(); - $defaults = array( - 'do' => 'admin', + $defaults = [ + 'do' => 'admin', 'page' => 'extension', - 'tab' => $tab, - ); + 'tab' => $tab + ]; if ($tab == 'search') $defaults['q'] = $INPUT->str('q'); return wl($ID, array_merge($defaults, $params), $absolute, $sep); diff --git a/lib/plugins/extension/helper/list.php b/lib/plugins/extension/helper/list.php index 647575b10..ec5db0e1d 100644 --- a/lib/plugins/extension/helper/list.php +++ b/lib/plugins/extension/helper/list.php @@ -1,15 +1,17 @@ <?php + +use dokuwiki\Extension\Plugin; + /** * DokuWiki Plugin extension (Helper Component) * * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html * @author Michael Hamann <michael@content-space.de> */ - /** * Class helper_plugin_extension_list takes care of creating a HTML list of extensions */ -class helper_plugin_extension_list extends DokuWiki_Plugin +class helper_plugin_extension_list extends Plugin { protected $form = ''; /** @var helper_plugin_extension_gui */ @@ -56,7 +58,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin */ public function addHeader($id, $header, $level = 2) { - $this->form .='<h'.$level.' id="'.$id.'">'.hsc($header).'</h'.$level.'>'.DOKU_LF; + $this->form .= '<h' . $level . ' id="' . $id . '">' . hsc($header) . '</h' . $level . '>' . DOKU_LF; } /** @@ -66,7 +68,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin */ public function addParagraph($data) { - $this->form .= '<p>'.hsc($data).'</p>'.DOKU_LF; + $this->form .= '<p>' . hsc($data) . '</p>' . DOKU_LF; } /** @@ -78,9 +80,9 @@ class helper_plugin_extension_list extends DokuWiki_Plugin { $this->form .= '<div class="no">'; foreach ($data as $key => $value) { - $this->form .= '<input type="hidden" name="'.hsc($key).'" value="'.hsc($value).'" />'; + $this->form .= '<input type="hidden" name="' . hsc($key) . '" value="' . hsc($value) . '" />'; } - $this->form .= '</div>'.DOKU_LF; + $this->form .= '</div>' . DOKU_LF; } /** @@ -97,7 +99,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin public function nothingFound() { global $lang; - $this->form .= '<li class="notfound">'.$lang['nothingfound'].'</li>'; + $this->form .= '<li class="notfound">' . $lang['nothingfound'] . '</li>'; } /** @@ -118,8 +120,8 @@ class helper_plugin_extension_list extends DokuWiki_Plugin */ private function startRow(helper_plugin_extension_extension $extension) { - $this->form .= '<li id="extensionplugin__'.hsc($extension->getID()). - '" class="'.$this->makeClass($extension).'">'; + $this->form .= '<li id="extensionplugin__' . hsc($extension->getID()) . + '" class="' . $this->makeClass($extension) . '">'; } /** @@ -129,7 +131,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin */ private function populateColumn($class, $html) { - $this->form .= '<div class="'.$class.' col">'.$html.'</div>'.DOKU_LF; + $this->form .= '<div class="' . $class . ' col">' . $html . '</div>' . DOKU_LF; } /** @@ -137,7 +139,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin */ private function endRow() { - $this->form .= '</li>'.DOKU_LF; + $this->form .= '</li>' . DOKU_LF; } /** @@ -155,18 +157,18 @@ class helper_plugin_extension_list extends DokuWiki_Plugin } else { $linktype = 'extern'; } - $param = array( + $param = [ 'href' => $url, 'title' => $url, 'class' => ($linktype == 'extern') ? 'urlextern' : 'interwiki iw_doku', 'target' => $conf['target'][$linktype], - 'rel' => ($linktype == 'extern') ? 'noopener' : '', - ); + 'rel' => ($linktype == 'extern') ? 'noopener' : '' + ]; if ($linktype == 'extern' && $conf['relnofollow']) { $param['rel'] = implode(' ', [$param['rel'], 'ugc nofollow']); } - $html = ' <a '. buildAttributes($param, true).'>'. - $this->getLang('homepage_link').'</a>'; + $html = ' <a ' . buildAttributes($param, true) . '>' . + $this->getLang('homepage_link') . '</a>'; return $html; } @@ -180,12 +182,12 @@ class helper_plugin_extension_list extends DokuWiki_Plugin { $class = ($extension->isTemplate()) ? 'template' : 'plugin'; if ($extension->isInstalled()) { - $class.=' installed'; - $class.= ($extension->isEnabled()) ? ' enabled':' disabled'; + $class .= ' installed'; + $class .= ($extension->isEnabled()) ? ' enabled' : ' disabled'; if ($extension->updateAvailable()) $class .= ' updatable'; } - if (!$extension->canModify()) $class.= ' notselect'; - if ($extension->isProtected()) $class.= ' protected'; + if (!$extension->canModify()) $class .= ' notselect'; + if ($extension->isProtected()) $class .= ' protected'; //if($this->showinfo) $class.= ' showinfo'; return $class; } @@ -201,17 +203,17 @@ class helper_plugin_extension_list extends DokuWiki_Plugin if ($extension->getAuthor()) { $mailid = $extension->getEmailID(); if ($mailid) { - $url = $this->gui->tabURL('search', array('q' => 'authorid:'.$mailid)); - $html = '<a href="'.$url.'" class="author" title="'.$this->getLang('author_hint').'" >'. - '<img src="//www.gravatar.com/avatar/'.$mailid. - '?s=20&d=mm" width="20" height="20" alt="" /> '. - hsc($extension->getAuthor()).'</a>'; + $url = $this->gui->tabURL('search', ['q' => 'authorid:' . $mailid]); + $html = '<a href="' . $url . '" class="author" title="' . $this->getLang('author_hint') . '" >' . + '<img src="//www.gravatar.com/avatar/' . $mailid . + '?s=20&d=mm" width="20" height="20" alt="" /> ' . + hsc($extension->getAuthor()) . '</a>'; } else { - $html = '<span class="author">'.hsc($extension->getAuthor()).'</span>'; + $html = '<span class="author">' . hsc($extension->getAuthor()) . '</span>'; } - $html = '<bdi>'.$html.'</bdi>'; + $html = '<bdi>' . $html . '</bdi>'; } else { - $html = '<em class="author">'.$this->getLang('unknown_author').'</em>'.DOKU_LF; + $html = '<em class="author">' . $this->getLang('unknown_author') . '</em>' . DOKU_LF; } return $html; } @@ -233,17 +235,17 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $thumb = str_replace('http://www.dokuwiki.org', '//www.dokuwiki.org', $thumb); $title = sprintf($this->getLang('screenshot'), hsc($extension->getDisplayName())); - $img = '<a href="'.hsc($screen).'" target="_blank" class="extension_screenshot">'. - '<img alt="'.$title.'" width="120" height="70" src="'.hsc($thumb).'" />'. + $img = '<a href="' . hsc($screen) . '" target="_blank" class="extension_screenshot">' . + '<img alt="' . $title . '" width="120" height="70" src="' . hsc($thumb) . '" />' . '</a>'; } elseif ($extension->isTemplate()) { - $img = '<img alt="" width="120" height="70" src="'.DOKU_BASE. + $img = '<img alt="" width="120" height="70" src="' . DOKU_BASE . 'lib/plugins/extension/images/template.png" />'; } else { - $img = '<img alt="" width="120" height="70" src="'.DOKU_BASE. + $img = '<img alt="" width="120" height="70" src="' . DOKU_BASE . 'lib/plugins/extension/images/plugin.png" />'; } - $html = '<div class="screenshot" >'.$img.'<span></span></div>'.DOKU_LF; + $html = '<div class="screenshot" >' . $img . '<span></span></div>' . DOKU_LF; return $html; } @@ -260,26 +262,26 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $html .= '<h2>'; $html .= sprintf( $this->getLang('extensionby'), - '<bdi>'.hsc($extension->getDisplayName()).'</bdi>', + '<bdi>' . hsc($extension->getDisplayName()) . '</bdi>', $this->makeAuthor($extension) ); - $html .= '</h2>'.DOKU_LF; + $html .= '</h2>' . DOKU_LF; $html .= $this->makeScreenshot($extension); $popularity = $extension->getPopularity(); if ($popularity !== false && !$extension->isBundled()) { - $popularityText = sprintf($this->getLang('popularity'), round($popularity*100, 2)); - $html .= '<div class="popularity" title="'.$popularityText.'">'. - '<div style="width: '.($popularity * 100).'%;">'. - '<span class="a11y">'.$popularityText.'</span>'. - '</div></div>'.DOKU_LF; + $popularityText = sprintf($this->getLang('popularity'), round($popularity * 100, 2)); + $html .= '<div class="popularity" title="' . $popularityText . '">' . + '<div style="width: ' . ($popularity * 100) . '%;">' . + '<span class="a11y">' . $popularityText . '</span>' . + '</div></div>' . DOKU_LF; } if ($extension->getDescription()) { $html .= '<p><bdi>'; - $html .= hsc($extension->getDescription()).' '; - $html .= '</bdi></p>'.DOKU_LF; + $html .= hsc($extension->getDescription()) . ' '; + $html .= '</bdi></p>' . DOKU_LF; } $html .= $this->makeLinkbar($extension); @@ -288,18 +290,18 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $url = $this->gui->tabURL(''); $class = 'close'; } else { - $url = $this->gui->tabURL('', array('info' => $extension->getID())); + $url = $this->gui->tabURL('', ['info' => $extension->getID()]); $class = ''; } - $html .= ' <a href="'.$url.'#extensionplugin__'.$extension->getID(). - '" class="info '.$class.'" title="'.$this->getLang('btn_info'). - '" data-extid="'.$extension->getID().'">'.$this->getLang('btn_info').'</a>'; + $html .= ' <a href="' . $url . '#extensionplugin__' . $extension->getID() . + '" class="info ' . $class . '" title="' . $this->getLang('btn_info') . + '" data-extid="' . $extension->getID() . '">' . $this->getLang('btn_info') . '</a>'; if ($showinfo) { $html .= $this->makeInfo($extension); } $html .= $this->makeNoticeArea($extension); - $html .= '</div>'.DOKU_LF; + $html .= '</div>' . DOKU_LF; return $html; } @@ -322,34 +324,34 @@ class helper_plugin_extension_list extends DokuWiki_Plugin } else { $linktype = 'extern'; } - $param = array( + $param = [ 'href' => $bugtrackerURL, 'title' => $bugtrackerURL, 'class' => 'bugs', 'target' => $conf['target'][$linktype], - 'rel' => ($linktype == 'extern') ? 'noopener' : '', - ); + 'rel' => ($linktype == 'extern') ? 'noopener' : '' + ]; if ($conf['relnofollow']) { $param['rel'] = implode(' ', [$param['rel'], 'ugc nofollow']); } - $html .= ' <a '.buildAttributes($param, true).'>'. - $this->getLang('bugs_features').'</a>'; + $html .= ' <a ' . buildAttributes($param, true) . '>' . + $this->getLang('bugs_features') . '</a>'; } if ($extension->getTags()) { $first = true; - $html .= ' <span class="tags">'.$this->getLang('tags').' '; + $html .= ' <span class="tags">' . $this->getLang('tags') . ' '; foreach ($extension->getTags() as $tag) { if (!$first) { $html .= ', '; } else { $first = false; } - $url = $this->gui->tabURL('search', ['q' => 'tag:'.$tag]); - $html .= '<bdi><a href="'.$url.'">'.hsc($tag).'</a></bdi>'; + $url = $this->gui->tabURL('search', ['q' => 'tag:' . $tag]); + $html .= '<bdi><a href="' . $url . '">' . hsc($tag) . '</a></bdi>'; } $html .= '</span>'; } - $html .= '</div>'.DOKU_LF; + $html .= '</div>' . DOKU_LF; return $html; } @@ -381,18 +383,18 @@ class helper_plugin_extension_list extends DokuWiki_Plugin '</div>'; } if (($securityissue = $extension->getSecurityIssue()) !== false) { - $html .= '<div class="msg error">'. - sprintf($this->getLang('security_issue'), '<bdi>'.hsc($securityissue).'</bdi>'). + $html .= '<div class="msg error">' . + sprintf($this->getLang('security_issue'), '<bdi>' . hsc($securityissue) . '</bdi>') . '</div>'; } if (($securitywarning = $extension->getSecurityWarning()) !== false) { - $html .= '<div class="msg notify">'. - sprintf($this->getLang('security_warning'), '<bdi>'.hsc($securitywarning).'</bdi>'). + $html .= '<div class="msg notify">' . + sprintf($this->getLang('security_warning'), '<bdi>' . hsc($securitywarning) . '</bdi>') . '</div>'; } if ($extension->updateAvailable()) { - $html .= '<div class="msg notify">'. - sprintf($this->getLang('update_available'), hsc($extension->getLastUpdate())). + $html .= '<div class="msg notify">' . + sprintf($this->getLang('update_available'), hsc($extension->getLastUpdate())) . '</div>'; } if ($extension->hasDownloadURLChanged()) { @@ -404,7 +406,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin ) . '</div>'; } - return $html.DOKU_LF; + return $html . DOKU_LF; } /** @@ -420,13 +422,13 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $link = parse_url($url); $base = $link['host']; - if (!empty($link['port'])) $base .= $base.':'.$link['port']; + if (!empty($link['port'])) $base .= $base . ':' . $link['port']; $long = $link['path']; if (!empty($link['query'])) $long .= $link['query']; $name = shorten($base, $long, 55); - $html = '<a href="'.hsc($url).'" class="urlextern">'.hsc($name).'</a>'; + $html = '<a href="' . hsc($url) . '" class="urlextern">' . hsc($name) . '</a>'; return $html; } @@ -441,26 +443,26 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $default = $this->getLang('unknown'); $html = '<dl class="details">'; - $html .= '<dt>'.$this->getLang('status').'</dt>'; - $html .= '<dd>'.$this->makeStatus($extension).'</dd>'; + $html .= '<dt>' . $this->getLang('status') . '</dt>'; + $html .= '<dd>' . $this->makeStatus($extension) . '</dd>'; if ($extension->getDonationURL()) { - $html .= '<dt>'.$this->getLang('donate').'</dt>'; + $html .= '<dt>' . $this->getLang('donate') . '</dt>'; $html .= '<dd>'; - $html .= '<a href="'.$extension->getDonationURL().'" class="donate">'. - $this->getLang('donate_action').'</a>'; + $html .= '<a href="' . $extension->getDonationURL() . '" class="donate">' . + $this->getLang('donate_action') . '</a>'; $html .= '</dd>'; } if (!$extension->isBundled()) { - $html .= '<dt>'.$this->getLang('downloadurl').'</dt>'; + $html .= '<dt>' . $this->getLang('downloadurl') . '</dt>'; $html .= '<dd><bdi>'; $html .= ($extension->getDownloadURL() ? $this->shortlink($extension->getDownloadURL()) : $default); $html .= '</bdi></dd>'; - $html .= '<dt>'.$this->getLang('repository').'</dt>'; + $html .= '<dt>' . $this->getLang('repository') . '</dt>'; $html .= '<dd><bdi>'; $html .= ($extension->getSourcerepoURL() ? $this->shortlink($extension->getSourcerepoURL()) @@ -470,13 +472,13 @@ class helper_plugin_extension_list extends DokuWiki_Plugin if ($extension->isInstalled()) { if ($extension->getInstalledVersion()) { - $html .= '<dt>'.$this->getLang('installed_version').'</dt>'; + $html .= '<dt>' . $this->getLang('installed_version') . '</dt>'; $html .= '<dd>'; $html .= hsc($extension->getInstalledVersion()); $html .= '</dd>'; } if (!$extension->isBundled()) { - $html .= '<dt>'.$this->getLang('install_date').'</dt>'; + $html .= '<dt>' . $this->getLang('install_date') . '</dt>'; $html .= '<dd>'; $html .= ($extension->getUpdateDate() ? hsc($extension->getUpdateDate()) @@ -485,7 +487,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin } } if (!$extension->isInstalled() || $extension->updateAvailable()) { - $html .= '<dt>'.$this->getLang('available_version').'</dt>'; + $html .= '<dt>' . $this->getLang('available_version') . '</dt>'; $html .= '<dd>'; $html .= ($extension->getLastUpdate() ? hsc($extension->getLastUpdate()) @@ -493,7 +495,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $html .= '</dd>'; } - $html .= '<dt>'.$this->getLang('provides').'</dt>'; + $html .= '<dt>' . $this->getLang('provides') . '</dt>'; $html .= '<dd><bdi>'; $html .= ($extension->getTypes() ? hsc(implode(', ', $extension->getTypes())) @@ -501,35 +503,35 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $html .= '</bdi></dd>'; if (!$extension->isBundled() && $extension->getCompatibleVersions()) { - $html .= '<dt>'.$this->getLang('compatible').'</dt>'; + $html .= '<dt>' . $this->getLang('compatible') . '</dt>'; $html .= '<dd>'; foreach ($extension->getCompatibleVersions() as $date => $version) { - $html .= '<bdi>'.$version['label'].' ('.$date.')</bdi>, '; + $html .= '<bdi>' . $version['label'] . ' (' . $date . ')</bdi>, '; } $html = rtrim($html, ', '); $html .= '</dd>'; } if ($extension->getDependencies()) { - $html .= '<dt>'.$this->getLang('depends').'</dt>'; + $html .= '<dt>' . $this->getLang('depends') . '</dt>'; $html .= '<dd>'; $html .= $this->makeLinkList($extension->getDependencies()); $html .= '</dd>'; } if ($extension->getSimilarExtensions()) { - $html .= '<dt>'.$this->getLang('similar').'</dt>'; + $html .= '<dt>' . $this->getLang('similar') . '</dt>'; $html .= '<dd>'; $html .= $this->makeLinkList($extension->getSimilarExtensions()); $html .= '</dd>'; } if ($extension->getConflicts()) { - $html .= '<dt>'.$this->getLang('conflicts').'</dt>'; + $html .= '<dt>' . $this->getLang('conflicts') . '</dt>'; $html .= '<dd>'; $html .= $this->makeLinkList($extension->getConflicts()); $html .= '</dd>'; } - $html .= '</dl>'.DOKU_LF; + $html .= '</dl>' . DOKU_LF; return $html; } @@ -543,9 +545,9 @@ class helper_plugin_extension_list extends DokuWiki_Plugin { $html = ''; foreach ($ext as $link) { - $html .= '<bdi><a href="'. - $this->gui->tabURL('search', array('q'=>'ext:'.$link)).'">'. - hsc($link).'</a></bdi>, '; + $html .= '<bdi><a href="' . + $this->gui->tabURL('search', ['q' => 'ext:' . $link]) . '">' . + hsc($link) . '</a></bdi>, '; } return rtrim($html, ', '); } @@ -575,9 +577,8 @@ class helper_plugin_extension_list extends DokuWiki_Plugin } } } else { - $errors .= '<p class="permerror">'.$this->getLang($canmod).'</p>'; + $errors .= '<p class="permerror">' . $this->getLang($canmod) . '</p>'; } - if (!$extension->isProtected() && !$extension->isTemplate()) { // no enable/disable for templates if ($extension->isEnabled()) { $html .= $this->makeAction('disable', $extension); @@ -585,35 +586,32 @@ class helper_plugin_extension_list extends DokuWiki_Plugin $html .= $this->makeAction('enable', $extension); } } - if ($extension->isGitControlled()) { - $errors .= '<p class="permerror">'.$this->getLang('git').'</p>'; + $errors .= '<p class="permerror">' . $this->getLang('git') . '</p>'; } - - if ($extension->isEnabled() && + if ( + $extension->isEnabled() && in_array('Auth', $extension->getTypes()) && $conf['authtype'] != $extension->getID() ) { - $errors .= '<p class="permerror">'.$this->getLang('auth').'</p>'; + $errors .= '<p class="permerror">' . $this->getLang('auth') . '</p>'; } - } else { - if (($canmod = $extension->canModify()) === true) { - if ($extension->getDownloadURL()) { - $html .= $this->makeAction('install', $extension); - } - } else { - $errors .= '<div class="permerror">'.$this->getLang($canmod).'</div>'; + } elseif (($canmod = $extension->canModify()) === true) { + if ($extension->getDownloadURL()) { + $html .= $this->makeAction('install', $extension); } + } else { + $errors .= '<div class="permerror">' . $this->getLang($canmod) . '</div>'; } if (!$extension->isInstalled() && $extension->getDownloadURL()) { - $html .= ' <span class="version">'.$this->getLang('available_version').' '; + $html .= ' <span class="version">' . $this->getLang('available_version') . ' '; $html .= ($extension->getLastUpdate() ? hsc($extension->getLastUpdate()) - : $this->getLang('unknown')).'</span>'; + : $this->getLang('unknown')) . '</span>'; } - return $html.' '.$errors.DOKU_LF; + return $html . ' ' . $errors . DOKU_LF; } /** @@ -627,18 +625,15 @@ class helper_plugin_extension_list extends DokuWiki_Plugin { $title = ''; - switch ($action) { - case 'install': - case 'reinstall': - $title = 'title="'.hsc($extension->getDownloadURL()).'"'; - break; + if ($action == 'install' || $action == 'reinstall') { + $title = 'title="' . hsc($extension->getDownloadURL()) . '"'; } - $classes = 'button '.$action; - $name = 'fn['.$action.']['.hsc($extension->getID()).']'; + $classes = 'button ' . $action; + $name = 'fn[' . $action . '][' . hsc($extension->getID()) . ']'; - $html = '<button class="'.$classes.'" name="'.$name.'" type="submit" '.$title.'>'. - $this->getLang('btn_'.$action).'</button> '; + $html = '<button class="' . $classes . '" name="' . $name . '" type="submit" ' . $title . '>' . + $this->getLang('btn_' . $action) . '</button> '; return $html; } @@ -650,7 +645,7 @@ class helper_plugin_extension_list extends DokuWiki_Plugin */ public function makeStatus(helper_plugin_extension_extension $extension) { - $status = array(); + $status = []; if ($extension->isInstalled()) { $status[] = $this->getLang('status_installed'); diff --git a/lib/plugins/extension/helper/repository.php b/lib/plugins/extension/helper/repository.php index 0bca6c975..9d7f61f3e 100644 --- a/lib/plugins/extension/helper/repository.php +++ b/lib/plugins/extension/helper/repository.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki Plugin extension (Helper Component) * @@ -6,6 +7,7 @@ * @author Michael Hamann <michael@content-space.de> */ +use dokuwiki\Extension\Plugin; use dokuwiki\Cache\Cache; use dokuwiki\HTTP\DokuHTTPClient; use dokuwiki\Extension\PluginController; @@ -13,13 +15,12 @@ use dokuwiki\Extension\PluginController; /** * Class helper_plugin_extension_repository provides access to the extension repository on dokuwiki.org */ -class helper_plugin_extension_repository extends DokuWiki_Plugin +class helper_plugin_extension_repository extends Plugin { + public const EXTENSION_REPOSITORY_API = 'https://www.dokuwiki.org/lib/plugins/pluginrepo/api.php'; - const EXTENSION_REPOSITORY_API = 'https://www.dokuwiki.org/lib/plugins/pluginrepo/api.php'; - - private $loaded_extensions = array(); - private $has_access = null; + private $loaded_extensions = []; + private $has_access; /** * Initialize the repository (cache), fetches data for all installed plugins @@ -30,14 +31,15 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin global $plugin_controller; if ($this->hasAccess()) { $list = $plugin_controller->getList('', true); - $request_data = array('fmt' => 'php'); + $request_data = ['fmt' => 'php']; $request_needed = false; foreach ($list as $name) { - $cache = new Cache('##extension_manager##'.$name, '.repo'); + $cache = new Cache('##extension_manager##' . $name, '.repo'); - if (!isset($this->loaded_extensions[$name]) && + if ( + !isset($this->loaded_extensions[$name]) && $this->hasAccess() && - !$cache->useCache(array('age' => 3600 * 24)) + !$cache->useCache(['age' => 3600 * 24]) ) { $this->loaded_extensions[$name] = true; $request_data['ext'][] = $name; @@ -51,7 +53,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin if ($data !== false) { $extensions = unserialize($data); foreach ($extensions as $extension) { - $cache = new Cache('##extension_manager##'.$extension['plugin'], '.repo'); + $cache = new Cache('##extension_manager##' . $extension['plugin'], '.repo'); $cache->storeCache(serialize($extension)); } } else { @@ -67,14 +69,15 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin * @param bool $usecache use cached result if still valid * @return bool If repository access is available */ - public function hasAccess($usecache = true) { + public function hasAccess($usecache = true) + { if ($this->has_access === null) { $cache = new Cache('##extension_manager###hasAccess', '.repo'); - if (!$cache->useCache(array('age' => 60*10, 'purge' => !$usecache))) { + if (!$cache->useCache(['age' => 60 * 10, 'purge' => !$usecache])) { $httpclient = new DokuHTTPClient(); $httpclient->timeout = 5; - $data = $httpclient->get(self::EXTENSION_REPOSITORY_API.'?cmd=ping'); + $data = $httpclient->get(self::EXTENSION_REPOSITORY_API . '?cmd=ping'); if ($data !== false) { $this->has_access = true; $cache->storeCache(1); @@ -97,22 +100,23 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin */ public function getData($name) { - $cache = new Cache('##extension_manager##'.$name, '.repo'); + $cache = new Cache('##extension_manager##' . $name, '.repo'); - if (!isset($this->loaded_extensions[$name]) && + if ( + !isset($this->loaded_extensions[$name]) && $this->hasAccess() && - !$cache->useCache(array('age' => 3600 * 24)) + !$cache->useCache(['age' => 3600 * 24]) ) { $this->loaded_extensions[$name] = true; $httpclient = new DokuHTTPClient(); - $data = $httpclient->get(self::EXTENSION_REPOSITORY_API.'?fmt=php&ext[]='.urlencode($name)); + $data = $httpclient->get(self::EXTENSION_REPOSITORY_API . '?fmt=php&ext[]=' . urlencode($name)); if ($data !== false) { $result = unserialize($data); - if(count($result)) { + if (count($result)) { $cache->storeCache(serialize($result[0])); return $result[0]; } - return array(); + return []; } else { $this->has_access = false; } @@ -120,7 +124,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin if (file_exists($cache->cache)) { return unserialize($cache->retrieveCache(false)); } - return array(); + return []; } /** @@ -136,15 +140,15 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin $httpclient = new DokuHTTPClient(); $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $query); - if ($data === false) return array(); + if ($data === false) return []; $result = unserialize($data); - $ids = array(); + $ids = []; // store cache info for each extension foreach ($result as $ext) { $name = $ext['plugin']; - $cache = new Cache('##extension_manager##'.$name, '.repo'); + $cache = new Cache('##extension_manager##' . $name, '.repo'); $cache->storeCache(serialize($ext)); $ids[] = $name; } @@ -160,12 +164,7 @@ class helper_plugin_extension_repository extends DokuWiki_Plugin */ protected function parseQuery($q) { - $parameters = array( - 'tag' => array(), - 'mail' => array(), - 'type' => array(), - 'ext' => array() - ); + $parameters = ['tag' => [], 'mail' => [], 'type' => [], 'ext' => []]; // extract tags if (preg_match_all('/(^|\s)(tag:([\S]+))/', $q, $matches, PREG_SET_ORDER)) { diff --git a/lib/plugins/info/syntax.php b/lib/plugins/info/syntax.php index 8d86c220a..9027653b6 100644 --- a/lib/plugins/info/syntax.php +++ b/lib/plugins/info/syntax.php @@ -1,5 +1,8 @@ <?php +use dokuwiki\Extension\SyntaxPlugin; +use dokuwiki\Extension\PluginInterface; + /** * Info Plugin: Displays information about various DokuWiki internals * @@ -7,9 +10,8 @@ * @author Andreas Gohr <andi@splitbrain.org> * @author Esther Brunner <wikidesign@gmail.com> */ -class syntax_plugin_info extends DokuWiki_Syntax_Plugin +class syntax_plugin_info extends SyntaxPlugin { - /** * What kind of syntax are we? */ @@ -54,7 +56,7 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin public function handle($match, $state, $pos, Doku_Handler $handler) { $match = substr($match, 7, -2); //strip ~~INFO: from start and ~~ from end - return array(strtolower($match)); + return [strtolower($match)]; } /** @@ -127,12 +129,13 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin { global $lang; $plugins = plugin_list($type); - $plginfo = array(); + $plginfo = []; // remove subparts foreach ($plugins as $p) { - if (!$po = plugin_load($type, $p)) continue; - list($name,/* $part */) = explode('_', $p, 2); + $po = plugin_load($type, $p); + if (! $po instanceof PluginInterface) continue; + [$name, /* part */] = explode('_', $p, 2); $plginfo[$name] = $po->getInfo(); } @@ -167,7 +170,8 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin { $plugins = plugin_list('helper'); foreach ($plugins as $p) { - if (!$po = plugin_load('helper', $p)) continue; + $po = plugin_load('helper', $p); + if (!$po instanceof PluginInterface) continue; if (!method_exists($po, 'getMethods')) continue; $methods = $po->getMethods(); @@ -176,7 +180,7 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin $hid = $this->addToToc($info['name'], 2, $renderer); $doc = '<h2><a name="' . $hid . '" id="' . $hid . '">' . hsc($info['name']) . '</a></h2>'; $doc .= '<div class="level2">'; - $doc .= '<p>' . strtr(hsc($info['desc']), array("\n" => "<br />")) . '</p>'; + $doc .= '<p>' . strtr(hsc($info['desc']), ["\n" => "<br />"]) . '</p>'; $doc .= '<pre class="code">$' . $p . " = plugin_load('helper', '" . $p . "');</pre>"; $doc .= '</div>'; foreach ($methods as $method) { @@ -190,11 +194,11 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin if ($method['params']) { $c = count($method['params']); $doc .= '<tr><th rowspan="' . $c . '">Parameters</th><td>'; - $params = array(); + $params = []; foreach ($method['params'] as $desc => $type) { $params[] = hsc($desc) . '</td><td>' . hsc($type); } - $doc .= join('</td></tr><tr><td>', $params) . '</td></tr>'; + $doc .= implode('</td></tr><tr><td>', $params) . '</td></tr>'; } if ($method['return']) { $doc .= '<tr><th>Return value</th><td>' . hsc(key($method['return'])) . @@ -226,7 +230,7 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin $doc .= $mode; $doc .= '</td>'; $doc .= '<td class="leftalign">'; - $doc .= join(', ', $modes); + $doc .= implode(', ', $modes); $doc .= '</td>'; $doc .= '</tr>'; } @@ -243,7 +247,7 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin { $modes = p_get_parsermodes(); - $compactmodes = array(); + $compactmodes = []; foreach ($modes as $mode) { $compactmodes[$mode['sort']][] = $mode['mode']; } @@ -325,12 +329,12 @@ class syntax_plugin_info extends DokuWiki_Syntax_Plugin $hid = ''; if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])) { $hid = $renderer->_headerToLink($text, true); - $renderer->toc[] = array( + $renderer->toc[] = [ 'hid' => $hid, 'title' => $text, 'type' => 'ul', - 'level' => $level - $conf['toptoclevel'] + 1, - ); + 'level' => $level - $conf['toptoclevel'] + 1 + ]; } return $hid; } diff --git a/lib/plugins/logviewer/admin.php b/lib/plugins/logviewer/admin.php index 335af4c78..a747686af 100644 --- a/lib/plugins/logviewer/admin.php +++ b/lib/plugins/logviewer/admin.php @@ -1,5 +1,7 @@ <?php +use dokuwiki\Extension\AdminPlugin; +use dokuwiki\Form\Form; use dokuwiki\Logger; /** @@ -8,9 +10,9 @@ use dokuwiki\Logger; * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html * @author Andreas Gohr <andi@splitbrain.org> */ -class admin_plugin_logviewer extends DokuWiki_Admin_Plugin +class admin_plugin_logviewer extends AdminPlugin { - const MAX_READ_SIZE = 1048576; // 1 MB + protected const MAX_READ_SIZE = 1_048_576; // 1 MB protected $facilities; protected $facility; @@ -56,7 +58,7 @@ class admin_plugin_logviewer extends DokuWiki_Admin_Plugin { global $ID; - $form = new dokuwiki\Form\Form(['method' => 'GET']); + $form = new Form(['method' => 'GET']); $form->setHiddenField('do', 'admin'); $form->setHiddenField('page', 'logviewer'); $form->setHiddenField('facility', $this->facility); @@ -71,8 +73,10 @@ class admin_plugin_logviewer extends DokuWiki_Admin_Plugin if ($facility == $this->facility) { echo '<strong>' . hsc($facility) . '</strong>'; } else { - $link = wl($ID, - ['do' => 'admin', 'page' => 'logviewer', 'date' => $this->date, 'facility' => $facility]); + $link = wl( + $ID, + ['do' => 'admin', 'page' => 'logviewer', 'date' => $this->date, 'facility' => $facility] + ); echo '<a href="' . $link . '">' . hsc($facility) . '</a>'; } echo '</li>'; @@ -156,7 +160,7 @@ class admin_plugin_logviewer extends DokuWiki_Admin_Plugin if ($size >= self::MAX_READ_SIZE) { array_shift($lines); // Discard the first line - while (!empty($lines) && (substr($lines[0], 0, 2) === ' ')) { + while ($lines !== [] && (substr($lines[0], 0, 2) === ' ')) { array_shift($lines); // Discard indented lines } @@ -191,10 +195,10 @@ class admin_plugin_logviewer extends DokuWiki_Admin_Plugin $line = $lines[$i] ?? ''; } echo '</dd>'; - $i -= 1; // rewind the counter + --$i; // rewind the counter } else { // other lines are actual log lines in three parts - list($dt, $file, $msg) = sexplode("\t", $line, 3, ''); + [$dt, $file, $msg] = sexplode("\t", $line, 3, ''); echo '<dt>'; echo '<span class="datetime">' . hsc($dt) . '</span>'; echo '<span class="log">'; diff --git a/lib/plugins/popularity/action.php b/lib/plugins/popularity/action.php index fac610735..16b1a21cc 100644 --- a/lib/plugins/popularity/action.php +++ b/lib/plugins/popularity/action.php @@ -1,13 +1,16 @@ <?php + +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; +use dokuwiki\Extension\Event; + /** * Popularity Feedback Plugin * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) */ - -class action_plugin_popularity extends DokuWiki_Action_Plugin +class action_plugin_popularity extends ActionPlugin { - /** * @var helper_plugin_popularity */ @@ -19,18 +22,18 @@ class action_plugin_popularity extends DokuWiki_Action_Plugin } /** @inheritdoc */ - public function register(Doku_Event_Handler $controller) + public function register(EventHandler $controller) { - $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'autosubmit', array()); + $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'autosubmit', []); } /** * Event handler * - * @param Doku_Event $event + * @param Event $event * @param $param */ - public function autosubmit(Doku_Event &$event, $param) + public function autosubmit(Event $event, $param) { //Do we have to send the data now if (!$this->helper->isAutosubmitEnabled() || $this->isTooEarlyToSubmit()) { @@ -61,6 +64,6 @@ class action_plugin_popularity extends DokuWiki_Action_Plugin protected function isTooEarlyToSubmit() { $lastSubmit = $this->helper->lastSentTime(); - return $lastSubmit + 24*60*60*30 > time(); + return $lastSubmit + 24 * 60 * 60 * 30 > time(); } } diff --git a/lib/plugins/popularity/admin.php b/lib/plugins/popularity/admin.php index 61d8cc3bf..f9adcf045 100644 --- a/lib/plugins/popularity/admin.php +++ b/lib/plugins/popularity/admin.php @@ -1,16 +1,18 @@ <?php + +use dokuwiki\Extension\AdminPlugin; + /** * Popularity Feedback Plugin * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr <andi@splitbrain.org> */ -class admin_plugin_popularity extends DokuWiki_Admin_Plugin +class admin_plugin_popularity extends AdminPlugin { - /** @var helper_plugin_popularity */ protected $helper; - protected $sentStatus = null; + protected $sentStatus; /** * admin_plugin_popularity constructor. @@ -88,7 +90,6 @@ class admin_plugin_popularity extends DokuWiki_Admin_Plugin if (! $INPUT->has('data')) { echo $this->locale_xhtml('intro'); - //If there was an error the last time we tried to autosubmit, warn the user if ($this->helper->isAutoSubmitEnabled()) { if (file_exists($this->helper->autosubmitErrorFile)) { @@ -96,26 +97,21 @@ class admin_plugin_popularity extends DokuWiki_Admin_Plugin echo io_readFile($this->helper->autosubmitErrorFile); } } - flush(); echo $this->buildForm('server'); - //Print the last time the data was sent $lastSent = $this->helper->lastSentTime(); if ($lastSent !== 0) { echo $this->getLang('lastSent') . ' ' . datetime_h($lastSent); } + } elseif ($this->sentStatus === '') { + //If we successfully send the data + echo $this->locale_xhtml('submitted'); } else { - //If we just submitted the form - if ($this->sentStatus === '') { - //If we successfully sent the data - echo $this->locale_xhtml('submitted'); - } else { - //If we failed to submit the data, try directly with the browser - echo $this->getLang('submissionFailed') . $this->sentStatus . '<br />'; - echo $this->getLang('submitDirectly'); - echo $this->buildForm('browser', $INPUT->str('data')); - } + //If we failed to submit the data, try directly with the browser + echo $this->getLang('submissionFailed') . $this->sentStatus . '<br />'; + echo $this->getLang('submitDirectly'); + echo $this->buildForm('browser', $INPUT->str('data')); } } @@ -133,25 +129,25 @@ class admin_plugin_popularity extends DokuWiki_Admin_Plugin $data = $this->helper->gatherAsString(); } - $form = '<form method="post" action="'. $url .'" accept-charset="utf-8">' - .'<fieldset style="width: 60%;">' - .'<textarea class="edit" rows="10" cols="80" readonly="readonly" name="data">' - .$data - .'</textarea><br />'; + $form = '<form method="post" action="' . $url . '" accept-charset="utf-8">' + . '<fieldset style="width: 60%;">' + . '<textarea class="edit" rows="10" cols="80" readonly="readonly" name="data">' + . $data + . '</textarea><br />'; //If we submit via the server, we give the opportunity to suscribe to the autosubmission option if ($submissionMode !== 'browser') { $form .= '<label for="autosubmit">' - .'<input type="checkbox" name="autosubmit" id="autosubmit" ' - .($this->helper->isAutosubmitEnabled() ? 'checked' : '' ) - .'/> ' . $this->getLang('autosubmit') .'<br />' - .'</label>' - .'<input type="hidden" name="do" value="admin" />' - .'<input type="hidden" name="page" value="popularity" />'; + . '<input type="checkbox" name="autosubmit" id="autosubmit" ' + . ($this->helper->isAutosubmitEnabled() ? 'checked' : '' ) + . '/> ' . $this->getLang('autosubmit') . '<br />' + . '</label>' + . '<input type="hidden" name="do" value="admin" />' + . '<input type="hidden" name="page" value="popularity" />'; } - $form .= '<button type="submit">'.$this->getLang('submit').'</button>' - .'</fieldset>' - .'</form>'; + $form .= '<button type="submit">' . $this->getLang('submit') . '</button>' + . '</fieldset>' + . '</form>'; return $form; } } diff --git a/lib/plugins/popularity/helper.php b/lib/plugins/popularity/helper.php index 506126a35..b3393d24b 100644 --- a/lib/plugins/popularity/helper.php +++ b/lib/plugins/popularity/helper.php @@ -1,5 +1,6 @@ <?php +use dokuwiki\Extension\AuthPlugin; use dokuwiki\HTTP\DokuHTTPClient; use dokuwiki\Extension\Event; @@ -39,9 +40,9 @@ class helper_plugin_popularity extends Dokuwiki_Plugin public function __construct() { global $conf; - $this->autosubmitFile = $conf['cachedir'].'/autosubmit.txt'; - $this->autosubmitErrorFile = $conf['cachedir'].'/autosubmitError.txt'; - $this->popularityLastSubmitFile = $conf['cachedir'].'/lastSubmitTime.txt'; + $this->autosubmitFile = $conf['cachedir'] . '/autosubmit.txt'; + $this->autosubmitErrorFile = $conf['cachedir'] . '/autosubmitError.txt'; + $this->popularityLastSubmitFile = $conf['cachedir'] . '/lastSubmitTime.txt'; } /** @@ -64,7 +65,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin { $error = ''; $httpClient = new DokuHTTPClient(); - $status = $httpClient->sendRequest($this->submitUrl, array('data' => $data), 'POST'); + $status = $httpClient->sendRequest($this->submitUrl, ['data' => $data], 'POST'); if (! $status) { $error = $httpClient->error; } @@ -95,9 +96,9 @@ class helper_plugin_popularity extends Dokuwiki_Plugin $string = ''; foreach ($data as $key => $val) { if (is_array($val)) foreach ($val as $v) { - $string .= hsc($key)."\t".hsc($v)."\n"; + $string .= hsc($key) . "\t" . hsc($v) . "\n"; } else { - $string .= hsc($key)."\t".hsc($val)."\n"; + $string .= hsc($key) . "\t" . hsc($val) . "\n"; } } return $string; @@ -132,7 +133,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin global $conf; /** @var $auth DokuWiki_Auth_Plugin */ global $auth; - $data = array(); + $data = []; $phptime = ini_get('max_execution_time'); @set_time_limit(0); $pluginInfo = $this->getInfo(); @@ -152,7 +153,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin // number and size of pages $list = $this->initEmptySearchList(); - search($list, $conf['datadir'], array($this, 'searchCountCallback'), array('all'=>false), ''); + search($list, $conf['datadir'], [$this, 'searchCountCallback'], ['all' => false], ''); $data['page_count'] = $list['file_count']; $data['page_size'] = $list['file_size']; $data['page_biggest'] = $list['file_max']; @@ -165,7 +166,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin // number and size of media $list = $this->initEmptySearchList(); - search($list, $conf['mediadir'], array($this, 'searchCountCallback'), array('all'=>true)); + search($list, $conf['mediadir'], [$this, 'searchCountCallback'], ['all' => true]); $data['media_count'] = $list['file_count']; $data['media_size'] = $list['file_size']; $data['media_biggest'] = $list['file_max']; @@ -177,7 +178,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin // number and size of cache $list = $this->initEmptySearchList(); - search($list, $conf['cachedir'], array($this, 'searchCountCallback'), array('all'=>true)); + search($list, $conf['cachedir'], [$this, 'searchCountCallback'], ['all' => true]); $data['cache_count'] = $list['file_count']; $data['cache_size'] = $list['file_size']; $data['cache_biggest'] = $list['file_max']; @@ -187,7 +188,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin // number and size of index $list = $this->initEmptySearchList(); - search($list, $conf['indexdir'], array($this, 'searchCountCallback'), array('all'=>true)); + search($list, $conf['indexdir'], [$this, 'searchCountCallback'], ['all' => true]); $data['index_count'] = $list['file_count']; $data['index_size'] = $list['file_size']; $data['index_biggest'] = $list['file_max']; @@ -197,7 +198,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin // number and size of meta $list = $this->initEmptySearchList(); - search($list, $conf['metadir'], array($this, 'searchCountCallback'), array('all'=>true)); + search($list, $conf['metadir'], [$this, 'searchCountCallback'], ['all' => true]); $data['meta_count'] = $list['file_count']; $data['meta_size'] = $list['file_size']; $data['meta_biggest'] = $list['file_max']; @@ -207,7 +208,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin // number and size of attic $list = $this->initEmptySearchList(); - search($list, $conf['olddir'], array($this, 'searchCountCallback'), array('all'=>true)); + search($list, $conf['olddir'], [$this, 'searchCountCallback'], ['all' => true]); $data['attic_count'] = $list['file_count']; $data['attic_size'] = $list['file_size']; $data['attic_biggest'] = $list['file_max']; @@ -217,18 +218,18 @@ class helper_plugin_popularity extends Dokuwiki_Plugin unset($list); // user count - if ($auth && $auth->canDo('getUserCount')) { + if ($auth instanceof AuthPlugin && $auth->canDo('getUserCount')) { $data['user_count'] = $auth->getUserCount(); } // calculate edits per day - $list = (array) @file($conf['metadir'].'/_dokuwiki.changes'); + $list = (array) @file($conf['metadir'] . '/_dokuwiki.changes'); $count = count($list); if ($count > 2) { $first = (int) substr(array_shift($list), 0, 10); $last = (int) substr(array_pop($list), 0, 10); - $dur = ($last - $first)/(60*60*24); // number of days in the changelog - $data['edits_per_day'] = $count/$dur; + $dur = ($last - $first) / (60 * 60 * 24); // number of days in the changelog + $data['edits_per_day'] = $count / $dur; } unset($list); @@ -244,7 +245,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin $data['os'] = PHP_OS; $data['webserver'] = $_SERVER['SERVER_SOFTWARE']; $data['php_version'] = phpversion(); - $data['php_sapi'] = php_sapi_name(); + $data['php_sapi'] = PHP_SAPI; $data['php_memory'] = php_to_byte(ini_get('memory_limit')); $data['php_exectime'] = $phptime; $data['php_extension'] = get_loaded_extensions(); @@ -262,7 +263,7 @@ class helper_plugin_popularity extends Dokuwiki_Plugin */ protected function addPluginUsageData(&$data) { - $pluginsData = array(); + $pluginsData = []; Event::createAndTrigger('PLUGIN_POPULARITY_DATA_SETUP', $pluginsData); foreach ($pluginsData as $plugin => $d) { if (is_array($d)) { @@ -297,8 +298,8 @@ class helper_plugin_popularity extends Dokuwiki_Plugin //only search txt files if 'all' option not set if ($opts['all'] || substr($file, -4) == '.txt') { - $size = filesize($base.'/'.$file); - $date = filemtime($base.'/'.$file); + $size = filesize($base . '/' . $file); + $date = filemtime($base . '/' . $file); $data['file_count']++; $data['file_size'] += $size; if (!isset($data['file_min']) || $data['file_min'] > $size) $data['file_min'] = $size; diff --git a/lib/plugins/remote.php b/lib/plugins/remote.php index 5bf8da91e..e75f700a0 100644 --- a/lib/plugins/remote.php +++ b/lib/plugins/remote.php @@ -1,4 +1,9 @@ <?php -\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction( - 'Autoloading', 1, 'require(' . basename(__FILE__) . ')' + +use dokuwiki\Debug\DebugHelper; + +DebugHelper::dbgDeprecatedFunction( + 'Autoloading', + 1, + 'require(' . basename(__FILE__) . ')' ); diff --git a/lib/plugins/revert/admin.php b/lib/plugins/revert/admin.php index 2d11dc05a..4b9fe8584 100644 --- a/lib/plugins/revert/admin.php +++ b/lib/plugins/revert/admin.php @@ -1,12 +1,13 @@ <?php +use dokuwiki\Extension\AdminPlugin; use dokuwiki\ChangeLog\PageChangeLog; /** * All DokuWiki plugins to extend the admin function * need to inherit from this class */ -class admin_plugin_revert extends DokuWiki_Admin_Plugin +class admin_plugin_revert extends AdminPlugin { protected $cmd; // some vars which might need tuning later @@ -70,10 +71,10 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin { global $lang, $INPUT; echo '<form action="" method="post"><div class="no">'; - echo '<label>'.$this->getLang('filter').': </label>'; - echo '<input type="text" name="filter" class="edit" value="'.hsc($INPUT->str('filter')).'" /> '; - echo '<button type="submit">'.$lang['btn_search'].'</button> '; - echo '<span>'.$this->getLang('note1').'</span>'; + echo '<label>' . $this->getLang('filter') . ': </label>'; + echo '<input type="text" name="filter" class="edit" value="' . hsc($INPUT->str('filter')) . '" /> '; + echo '<button type="submit">' . $lang['btn_search'] . '</button> '; + echo '<span>' . $this->getLang('note1') . '</span>'; echo '</div></form><br /><br />'; } @@ -83,7 +84,7 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin protected function revertEdits($revert, $filter) { echo '<hr /><br />'; - echo '<p>'.$this->getLang('revstart').'</p>'; + echo '<p>' . $this->getLang('revstart') . '</p>'; echo '<ul>'; foreach ($revert as $id) { @@ -93,26 +94,26 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin $data = ''; $pagelog = new PageChangeLog($id); $old = $pagelog->getRevisions(0, $this->max_revs); - if (count($old)) { + if ($old !== []) { foreach ($old as $REV) { $data = rawWiki($id, $REV); - if (strpos($data, $filter) === false) break; + if (strpos($data, (string) $filter) === false) break; } } if ($data) { saveWikiText($id, $data, 'old revision restored', false); - printf('<li><div class="li">'.$this->getLang('reverted').'</div></li>', $id, $REV); + printf('<li><div class="li">' . $this->getLang('reverted') . '</div></li>', $id, $REV); } else { saveWikiText($id, '', '', false); - printf('<li><div class="li">'.$this->getLang('removed').'</div></li>', $id); + printf('<li><div class="li">' . $this->getLang('removed') . '</div></li>', $id); } @set_time_limit(10); flush(); } echo '</ul>'; - echo '<p>'.$this->getLang('revstop').'</p>'; + echo '<p>' . $this->getLang('revstop') . '</p>'; } /** @@ -124,7 +125,7 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin global $lang; echo '<hr /><br />'; echo '<form action="" method="post"><div class="no">'; - echo '<input type="hidden" name="filter" value="'.hsc($filter).'" />'; + echo '<input type="hidden" name="filter" value="' . hsc($filter) . '" />'; formSecurityToken(); $recents = getRecents(0, $this->max_lines); @@ -133,21 +134,21 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin $cnt = 0; foreach ($recents as $recent) { if ($filter) { - if (strpos(rawWiki($recent['id']), $filter) === false) continue; + if (strpos(rawWiki($recent['id']), (string) $filter) === false) continue; } $cnt++; $date = dformat($recent['date']); - echo ($recent['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) ? '<li class="minor">' : '<li>'; + echo ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? '<li class="minor">' : '<li>'; echo '<div class="li">'; - echo '<input type="checkbox" name="revert[]" value="'.hsc($recent['id']). - '" checked="checked" id="revert__'.$cnt.'" />'; - echo ' <label for="revert__'.$cnt.'">'.$date.'</label> '; + echo '<input type="checkbox" name="revert[]" value="' . hsc($recent['id']) . + '" checked="checked" id="revert__' . $cnt . '" />'; + echo ' <label for="revert__' . $cnt . '">' . $date . '</label> '; - echo '<a href="'.wl($recent['id'], "do=diff").'">'; - $p = array(); - $p['src'] = DOKU_BASE.'lib/images/diff.png'; + echo '<a href="' . wl($recent['id'], "do=diff") . '">'; + $p = []; + $p['src'] = DOKU_BASE . 'lib/images/diff.png'; $p['width'] = 15; $p['height'] = 11; $p['title'] = $lang['diff']; @@ -156,9 +157,9 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin echo "<img $att />"; echo '</a> '; - echo '<a href="'.wl($recent['id'], "do=revisions").'">'; - $p = array(); - $p['src'] = DOKU_BASE.'lib/images/history.png'; + echo '<a href="' . wl($recent['id'], "do=revisions") . '">'; + $p = []; + $p['src'] = DOKU_BASE . 'lib/images/history.png'; $p['width'] = 12; $p['height'] = 14; $p['title'] = $lang['btn_revs']; @@ -167,11 +168,11 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin echo "<img $att />"; echo '</a> '; - echo html_wikilink(':'.$recent['id'], (useHeading('navigation'))?null:$recent['id']); - echo ' – '.htmlspecialchars($recent['sum']); + echo html_wikilink(':' . $recent['id'], (useHeading('navigation')) ? null : $recent['id']); + echo ' – ' . htmlspecialchars($recent['sum']); echo ' <span class="user">'; - echo $recent['user'].' '.$recent['ip']; + echo $recent['user'] . ' ' . $recent['ip']; echo '</span>'; echo '</div>'; @@ -183,7 +184,7 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin echo '</ul>'; echo '<p>'; - echo '<button type="submit">'.$this->getLang('revert').'</button> '; + echo '<button type="submit">' . $this->getLang('revert') . '</button> '; printf($this->getLang('note2'), hsc($filter)); echo '</p>'; diff --git a/lib/plugins/safefnrecode/action.php b/lib/plugins/safefnrecode/action.php index 952d95c90..b3e14fffe 100644 --- a/lib/plugins/safefnrecode/action.php +++ b/lib/plugins/safefnrecode/action.php @@ -1,16 +1,19 @@ <?php + +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; +use dokuwiki\Extension\Event; + /** * DokuWiki Plugin safefnrecode (Action Component) * * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html * @author Andreas Gohr <andi@splitbrain.org> */ - -class action_plugin_safefnrecode extends DokuWiki_Action_Plugin +class action_plugin_safefnrecode extends ActionPlugin { - /** @inheritdoc */ - public function register(Doku_Event_Handler $controller) + public function register(EventHandler $controller) { $controller->register_hook('INDEXER_TASKS_RUN', 'BEFORE', $this, 'handleIndexerTasksRun'); } @@ -18,32 +21,32 @@ class action_plugin_safefnrecode extends DokuWiki_Action_Plugin /** * Handle indexer event * - * @param Doku_Event $event + * @param Event $event * @param $param */ - public function handleIndexerTasksRun(Doku_Event $event, $param) + public function handleIndexerTasksRun(Event $event, $param) { global $conf; if ($conf['fnencode'] != 'safe') return; - if (!file_exists($conf['datadir'].'_safefn.recoded')) { + if (!file_exists($conf['datadir'] . '_safefn.recoded')) { $this->recode($conf['datadir']); - touch($conf['datadir'].'_safefn.recoded'); + touch($conf['datadir'] . '_safefn.recoded'); } - if (!file_exists($conf['olddir'].'_safefn.recoded')) { + if (!file_exists($conf['olddir'] . '_safefn.recoded')) { $this->recode($conf['olddir']); - touch($conf['olddir'].'_safefn.recoded'); + touch($conf['olddir'] . '_safefn.recoded'); } - if (!file_exists($conf['metadir'].'_safefn.recoded')) { + if (!file_exists($conf['metadir'] . '_safefn.recoded')) { $this->recode($conf['metadir']); - touch($conf['metadir'].'_safefn.recoded'); + touch($conf['metadir'] . '_safefn.recoded'); } - if (!file_exists($conf['mediadir'].'_safefn.recoded')) { + if (!file_exists($conf['mediadir'] . '_safefn.recoded')) { $this->recode($conf['mediadir']); - touch($conf['mediadir'].'_safefn.recoded'); + touch($conf['mediadir'] . '_safefn.recoded'); } } diff --git a/lib/plugins/styling/action.php b/lib/plugins/styling/action.php index 46245ca75..39da86028 100644 --- a/lib/plugins/styling/action.php +++ b/lib/plugins/styling/action.php @@ -1,20 +1,24 @@ <?php + +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; +use dokuwiki\Extension\Event; + /** * DokuWiki Plugin styling (Action Component) * * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html * @author Andreas Gohr <andi@splitbrain.org> */ -class action_plugin_styling extends DokuWiki_Action_Plugin +class action_plugin_styling extends ActionPlugin { - /** * Registers a callback functions * - * @param Doku_Event_Handler $controller DokuWiki's event controller object + * @param EventHandler $controller DokuWiki's event controller object * @return void */ - public function register(Doku_Event_Handler $controller) + public function register(EventHandler $controller) { $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleHeader'); } @@ -22,12 +26,12 @@ class action_plugin_styling extends DokuWiki_Action_Plugin /** * Adds the preview parameter to the stylesheet loading in non-js mode * - * @param Doku_Event $event event object by reference - * @param mixed $param [the parameters passed as fifth argument to register_hook() when this - * handler was registered] + * @param Event $event event object by reference + * @param mixed $param [the parameters passed as fifth argument to register_hook() when this + * handler was registered] * @return void */ - public function handleHeader(Doku_Event &$event, $param) + public function handleHeader(Event &$event, $param) { global $ACT; global $INPUT; @@ -39,10 +43,11 @@ class action_plugin_styling extends DokuWiki_Action_Plugin // set preview $len = count($event->data['link']); for ($i = 0; $i < $len; $i++) { - if ($event->data['link'][$i]['rel'] == 'stylesheet' && + if ( + $event->data['link'][$i]['rel'] == 'stylesheet' && strpos($event->data['link'][$i]['href'], 'lib/exe/css.php') !== false ) { - $event->data['link'][$i]['href'] .= '&preview=1&tseed='.time(); + $event->data['link'][$i]['href'] .= '&preview=1&tseed=' . time(); } } } diff --git a/lib/plugins/styling/admin.php b/lib/plugins/styling/admin.php index 08c9afdc2..9fe4ebdba 100644 --- a/lib/plugins/styling/admin.php +++ b/lib/plugins/styling/admin.php @@ -1,13 +1,16 @@ <?php + +use dokuwiki\Extension\AdminPlugin; +use dokuwiki\StyleUtils; + /** * DokuWiki Plugin styling (Admin Component) * * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html * @author Andreas Gohr <andi@splitbrain.org> */ -class admin_plugin_styling extends DokuWiki_Admin_Plugin +class admin_plugin_styling extends AdminPlugin { - public $ispopup = false; /** @@ -34,8 +37,8 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin global $INPUT; $run = $INPUT->extract('run')->str('run'); if (!$run) return; - if(!checkSecurityToken()) return; - $run = 'run'.ucfirst($run); + if (!checkSecurityToken()) return; + $run = 'run' . ucfirst($run); $this->$run(); } @@ -47,8 +50,8 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin $class = 'nopopup'; if ($this->ispopup) $class = 'ispopup page'; - echo '<div id="plugin__styling" class="'.$class.'">'; - ptln('<h1>'.$this->getLang('menu').'</h1>'); + echo '<div id="plugin__styling" class="' . $class . '">'; + echo '<h1>' . $this->getLang('menu') . '</h1>'; $this->form(); echo '</div>'; } @@ -61,22 +64,22 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin global $conf; global $ID; - $styleUtil = new \dokuwiki\StyleUtils($conf['template'], true, true); - $styleini = $styleUtil->cssStyleini(); + $styleUtil = new StyleUtils($conf['template'], true, true); + $styleini = $styleUtil->cssStyleini(); $replacements = $styleini['replacements']; if ($this->ispopup) { - $target = DOKU_BASE.'lib/plugins/styling/popup.php'; + $target = DOKU_BASE . 'lib/plugins/styling/popup.php'; } else { - $target = wl($ID, array('do' => 'admin', 'page' => 'styling')); + $target = wl($ID, ['do' => 'admin', 'page' => 'styling']); } if (empty($replacements)) { - echo '<p class="error">'.$this->getLang('error').'</p>'; + echo '<p class="error">' . $this->getLang('error') . '</p>'; } else { echo $this->locale_xhtml('intro'); - echo '<form class="styling" method="post" action="'.$target.'">'; + echo '<form class="styling" method="post" action="' . $target . '">'; formSecurityToken(); echo '<table><tbody>'; @@ -86,27 +89,28 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin if (empty($name)) $name = $key; echo '<tr>'; - echo '<td><label for="tpl__'.hsc($key).'">'.$name.'</label></td>'; - echo '<td><input type="'.$this->colorType($value).'" name="tpl['.hsc($key).']" id="tpl__'.hsc($key).'" - value="'.hsc($this->colorValue($value)).'" dir="ltr" required="required"/></td>'; + echo '<td><label for="tpl__' . hsc($key) . '">' . $name . '</label></td>'; + echo '<td><input type="' . $this->colorType($value) . '" name="tpl[' . hsc($key) . ']" ' . + 'id="tpl__' . hsc($key) . '" value="' . hsc($this->colorValue($value)) . '" ' . + 'dir="ltr" required="required"/></td>'; echo '</tr>'; } echo '</tbody></table>'; echo '<p>'; - echo '<button type="submit" name="run[preview]" class="btn_preview primary">'. - $this->getLang('btn_preview').'</button> '; + echo '<button type="submit" name="run[preview]" class="btn_preview primary">' . + $this->getLang('btn_preview') . '</button> '; #FIXME only if preview.ini exists: - echo '<button type="submit" name="run[reset]">'.$this->getLang('btn_reset').'</button>'; + echo '<button type="submit" name="run[reset]">' . $this->getLang('btn_reset') . '</button>'; echo '</p>'; echo '<p>'; - echo '<button type="submit" name="run[save]" class="primary">'.$this->getLang('btn_save').'</button>'; + echo '<button type="submit" name="run[save]" class="primary">' . $this->getLang('btn_save') . '</button>'; echo '</p>'; echo '<p>'; #FIXME only if local.ini exists: - echo '<button type="submit" name="run[revert]">'.$this->getLang('btn_revert').'</button>'; + echo '<button type="submit" name="run[revert]">' . $this->getLang('btn_revert') . '</button>'; echo '</p>'; echo '</form>'; @@ -150,7 +154,7 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin public function runPreview() { global $conf; - $ini = $conf['cachedir'].'/preview.ini'; + $ini = $conf['cachedir'] . '/preview.ini'; io_saveFile($ini, $this->makeini()); } @@ -160,7 +164,7 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin protected function runReset() { global $conf; - $ini = $conf['cachedir'].'/preview.ini'; + $ini = $conf['cachedir'] . '/preview.ini'; io_saveFile($ini, ''); } @@ -195,7 +199,7 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin $ini .= ";These overwrites have been generated from the Template styling Admin interface\n"; $ini .= ";Any values in this section will be overwritten by that tool again\n"; foreach ($INPUT->arr('tpl') as $key => $val) { - $ini .= $key.' = "'.addslashes($val).'"'."\n"; + $ini .= $key . ' = "' . addslashes($val) . '"' . "\n"; } return $ini; @@ -209,7 +213,7 @@ class admin_plugin_styling extends DokuWiki_Admin_Plugin protected function replaceIni($new) { global $conf; - $ini = DOKU_CONF."tpl/".$conf['template']."/style.ini"; + $ini = DOKU_CONF . "tpl/" . $conf['template'] . "/style.ini"; if (file_exists($ini)) { $old = io_readFile($ini); $old = preg_replace('/\[replacements\]\n.*?(\n\[.*]|$)/s', '\\1', $old); diff --git a/lib/plugins/styling/popup.php b/lib/plugins/styling/popup.php index 079062e43..0fef79ce3 100644 --- a/lib/plugins/styling/popup.php +++ b/lib/plugins/styling/popup.php @@ -1,6 +1,6 @@ <?php // phpcs:disable PSR1.Files.SideEffects -if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../../'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../../'); require_once(DOKU_INC . 'inc/init.php'); //close session session_write_close(); @@ -23,7 +23,7 @@ $plugin->handle(); <title><?php echo $plugin->getLang('menu') ?></title> <?php tpl_metaheaders(false) ?> <meta name="viewport" content="width=device-width,initial-scale=1" /> - <?php echo tpl_favicon(array('favicon')) ?> + <?php echo tpl_favicon(['favicon']) ?> </head> <body class="dokuwiki"> <?php $plugin->html() ?> diff --git a/lib/plugins/syntax.php b/lib/plugins/syntax.php index 5bf8da91e..e75f700a0 100644 --- a/lib/plugins/syntax.php +++ b/lib/plugins/syntax.php @@ -1,4 +1,9 @@ <?php -\dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction( - 'Autoloading', 1, 'require(' . basename(__FILE__) . ')' + +use dokuwiki\Debug\DebugHelper; + +DebugHelper::dbgDeprecatedFunction( + 'Autoloading', + 1, + 'require(' . basename(__FILE__) . ')' ); diff --git a/lib/plugins/testing/action.php b/lib/plugins/testing/action.php index 09b84262e..48945c337 100644 --- a/lib/plugins/testing/action.php +++ b/lib/plugins/testing/action.php @@ -1,5 +1,7 @@ <?php +use dokuwiki\Extension\ActionPlugin; +use dokuwiki\Extension\EventHandler; use dokuwiki\Extension\Event; /** @@ -9,16 +11,18 @@ use dokuwiki\Extension\Event; * * @author Tobias Sarnowski <tobias@trustedco.de> */ -class action_plugin_testing extends DokuWiki_Action_Plugin { - +class action_plugin_testing extends ActionPlugin +{ /** @inheritdoc */ - public function register(Doku_Event_Handler $controller) { + public function register(EventHandler $controller) + { $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'dokuwikiStarted'); } - public function dokuwikiStarted() { - $param = array(); + public function dokuwikiStarted() + { + $param = []; Event::createAndTrigger('TESTING_PLUGIN_INSTALLED', $param); - msg('The testing plugin is enabled and should be disabled.',-1); + msg('The testing plugin is enabled and should be disabled.', -1); } } diff --git a/lib/plugins/testing/conf/default.php b/lib/plugins/testing/conf/default.php index 28aef9b7e..8ce3ce83b 100644 --- a/lib/plugins/testing/conf/default.php +++ b/lib/plugins/testing/conf/default.php @@ -1,9 +1,10 @@ <?php + /** * Default options * * They don't do anything and are just there for testing config reading */ + $conf['schnibble'] = 0; $conf['second'] = 'Default value'; - diff --git a/lib/plugins/testing/conf/metadata.php b/lib/plugins/testing/conf/metadata.php index 3ea183cfa..09b6f143a 100644 --- a/lib/plugins/testing/conf/metadata.php +++ b/lib/plugins/testing/conf/metadata.php @@ -1,8 +1,10 @@ <?php + /** * Option Metadata * * They don't do anything and are just there for testing config reading */ + $meta['schnibble'] = array('onoff'); $meta['second'] = array('string'); diff --git a/lib/plugins/usermanager/admin.php b/lib/plugins/usermanager/admin.php index 423467133..2314a70a9 100644 --- a/lib/plugins/usermanager/admin.php +++ b/lib/plugins/usermanager/admin.php @@ -1,4 +1,9 @@ <?php + +use dokuwiki\Extension\AdminPlugin; +use dokuwiki\Extension\AuthPlugin; +use dokuwiki\Utf8\Clean; + /* * User Manager * @@ -15,20 +20,20 @@ * All DokuWiki plugins to extend the admin function * need to inherit from this class */ -class admin_plugin_usermanager extends DokuWiki_Admin_Plugin +class admin_plugin_usermanager extends AdminPlugin { - const IMAGE_DIR = DOKU_BASE.'lib/plugins/usermanager/images/'; + protected const IMAGE_DIR = DOKU_BASE . 'lib/plugins/usermanager/images/'; - protected $auth = null; // auth object + protected $auth; // auth object protected $users_total = 0; // number of registered users - protected $filter = array(); // user selection filter(s) + protected $filter = []; // user selection filter(s) protected $start = 0; // index of first user to be displayed protected $last = 0; // index of the last user to be displayed protected $pagesize = 20; // number of users to list on one page protected $edit_user = ''; // set to user selected for editing - protected $edit_userdata = array(); + protected $edit_userdata = []; protected $disabled = ''; // if disabled set to explanatory string - protected $import_failures = array(); + protected $import_failures = []; protected $lastdisabled = false; // set to true if last user is unknown and last button is hence buggy /** @@ -36,18 +41,18 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin */ public function __construct() { - /** @var DokuWiki_Auth_Plugin $auth */ + /** @var AuthPlugin $auth */ global $auth; $this->setupLocale(); - if (!isset($auth)) { + if (!$auth instanceof AuthPlugin) { $this->disabled = $this->lang['noauth']; } elseif (!$auth->canDo('getUsers')) { $this->disabled = $this->lang['nosupport']; } else { // we're good to go - $this->auth = & $auth; + $this->auth = &$auth; } // attempt to retrieve any import failures from the session @@ -66,9 +71,9 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin { if (!is_null($this->auth)) - return parent::getMenuText($language); + return parent::getMenuText($language); - return $this->getLang('menu').' '.$this->disabled; + return $this->getLang('menu') . ' ' . $this->disabled; } /** @@ -117,7 +122,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin // extract the command and any specific parameters // submit button name is of the form - fn[cmd][param(s)] - $fn = $INPUT->param('fn'); + $fn = $INPUT->param('fn'); if (is_array($fn)) { $cmd = key($fn); @@ -147,7 +152,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin break; case "search": $this->setFilter($param); - $this->start = 0; + $this->start = 0; break; case "export": $this->exportCSV(); @@ -185,13 +190,14 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin * Output appropriate html * * @return bool + * @todo split into smaller functions, use Form class */ public function html() { global $ID; if (is_null($this->auth)) { - print $this->lang['badauth']; + echo $this->lang['badauth']; return false; } @@ -203,21 +209,19 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $editable = $this->auth->canDo('UserMod'); $export_label = empty($this->filter) ? $this->lang['export_all'] : $this->lang['export_filtered']; - print $this->locale_xhtml('intro'); - print $this->locale_xhtml('list'); + echo $this->locale_xhtml('intro'); + echo $this->locale_xhtml('list'); - ptln("<div id=\"user__manager\">"); - ptln("<div class=\"level2\">"); + echo '<div id="user__manager">'; + echo '<div class="level2">'; if ($this->users_total > 0) { - ptln( - "<p>" . sprintf( - $this->lang['summary'], - $this->start + 1, - $this->last, - $this->users_total, - $this->auth->getUserCount() - ) . "</p>" + printf( + '<p>' . $this->lang['summary'] . '</p>', + $this->start + 1, + $this->last, + $this->users_total, + $this->auth->getUserCount() ); } else { if ($this->users_total < 0) { @@ -225,126 +229,122 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin } else { $allUserTotal = $this->auth->getUserCount(); } - ptln("<p>".sprintf($this->lang['nonefound'], $allUserTotal)."</p>"); + printf('<p>%s</p>', sprintf($this->lang['nonefound'], $allUserTotal)); } - ptln("<form action=\"".wl($ID)."\" method=\"post\">"); + printf('<form action="%s" method="post">', wl($ID)); formSecurityToken(); - ptln(" <div class=\"table\">"); - ptln(" <table class=\"inline\">"); - ptln(" <thead>"); - ptln(" <tr>"); - ptln(" <th> </th> - <th>".$this->lang["user_id"]."</th> - <th>".$this->lang["user_name"]."</th> - <th>".$this->lang["user_mail"]."</th> - <th>".$this->lang["user_groups"]."</th>"); - ptln(" </tr>"); - - ptln(" <tr>"); - ptln(" <td class=\"rightalign\"><input type=\"image\" src=\"". - self::IMAGE_DIR."search.png\" name=\"fn[search][new]\" title=\"". - $this->lang['search_prompt']."\" alt=\"".$this->lang['search']."\" class=\"button\" /></td>"); - ptln(" <td><input type=\"text\" name=\"userid\" class=\"edit\" value=\"". - $this->htmlFilter('user')."\" /></td>"); - ptln(" <td><input type=\"text\" name=\"username\" class=\"edit\" value=\"". - $this->htmlFilter('name')."\" /></td>"); - ptln(" <td><input type=\"text\" name=\"usermail\" class=\"edit\" value=\"". - $this->htmlFilter('mail')."\" /></td>"); - ptln(" <td><input type=\"text\" name=\"usergroups\" class=\"edit\" value=\"". - $this->htmlFilter('grps')."\" /></td>"); - ptln(" </tr>"); - ptln(" </thead>"); + echo '<div class="table">'; + echo '<table class="inline">'; + echo '<thead>'; + echo '<tr>'; + echo '<th> </th>'; + echo '<th>' . $this->lang["user_id"] . '</th>'; + echo '<th>' . $this->lang["user_name"] . '</th>'; + echo '<th>' . $this->lang["user_mail"] . '</th>'; + echo '<th>' . $this->lang["user_groups"] . '</th>'; + echo '</tr>'; + + echo '<tr>'; + echo '<td class="rightalign"><input type="image" src="' . + self::IMAGE_DIR . 'search.png" name="fn[search][new]" title="' . + $this->lang['search_prompt'] . '" alt="' . $this->lang['search'] . '" class="button" /></td>'; + echo '<td><input type="text" name="userid" class="edit" value="' . $this->htmlFilter('user') . '" /></td>'; + echo '<td><input type="text" name="username" class="edit" value="' . $this->htmlFilter('name') . '" /></td>'; + echo '<td><input type="text" name="usermail" class="edit" value="' . $this->htmlFilter('mail') . '" /></td>'; + echo '<td><input type="text" name="usergroups" class="edit" value="' . $this->htmlFilter('grps') . '" /></td>'; + echo '</tr>'; + echo '</thead>'; if ($this->users_total) { - ptln(" <tbody>"); + echo '<tbody>'; foreach ($user_list as $user => $userinfo) { extract($userinfo); /** * @var string $name * @var string $pass * @var string $mail - * @var array $grps + * @var array $grps */ - $groups = join(', ', $grps); - ptln(" <tr class=\"user_info\">"); - ptln(" <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[".hsc($user). - "]\" ".$delete_disable." /></td>"); + $groups = implode(', ', $grps); + echo '<tr class="user_info">'; + echo '<td class="centeralign"><input type="checkbox" name="delete[' . hsc($user) . + ']" ' . $delete_disable . ' /></td>'; if ($editable) { - ptln(" <td><a href=\"".wl($ID, array('fn[edit]['.$user.']' => 1, - 'do' => 'admin', - 'page' => 'usermanager', - 'sectok' => getSecurityToken())). - "\" title=\"".$this->lang['edit_prompt']."\">".hsc($user)."</a></td>"); + echo '<td><a href="' . wl($ID, ['fn[edit][' . $user . ']' => 1, + 'do' => 'admin', + 'page' => 'usermanager', + 'sectok' => getSecurityToken()]) . + '" title="' . $this->lang['edit_prompt'] . '">' . hsc($user) . '</a></td>'; } else { - ptln(" <td>".hsc($user)."</td>"); + echo '<td>' . hsc($user) . '</td>'; } - ptln(" <td>".hsc($name)."</td><td>".hsc($mail)."</td><td>".hsc($groups)."</td>"); - ptln(" </tr>"); + echo '<td>' . hsc($name) . '</td><td>' . hsc($mail) . '</td><td>' . hsc($groups) . '</td>'; + echo '</tr>'; } - ptln(" </tbody>"); + echo '</tbody>'; } - ptln(" <tbody>"); - ptln(" <tr><td colspan=\"5\" class=\"centeralign\">"); - ptln(" <span class=\"medialeft\">"); - ptln(" <button type=\"submit\" name=\"fn[delete]\" id=\"usrmgr__del\" ".$delete_disable.">". - $this->lang['delete_selected']."</button>"); - ptln(" </span>"); - ptln(" <span class=\"mediaright\">"); - ptln(" <button type=\"submit\" name=\"fn[start]\" ".$page_buttons['start'].">". - $this->lang['start']."</button>"); - ptln(" <button type=\"submit\" name=\"fn[prev]\" ".$page_buttons['prev'].">". - $this->lang['prev']."</button>"); - ptln(" <button type=\"submit\" name=\"fn[next]\" ".$page_buttons['next'].">". - $this->lang['next']."</button>"); - ptln(" <button type=\"submit\" name=\"fn[last]\" ".$page_buttons['last'].">". - $this->lang['last']."</button>"); - ptln(" </span>"); + echo '<tbody>'; + echo '<tr><td colspan="5" class="centeralign">'; + echo '<span class="medialeft">'; + echo '<button type="submit" name="fn[delete]" id="usrmgr__del" ' . $delete_disable . '>' . + $this->lang['delete_selected'] . '</button>'; + echo '</span>'; + echo '<span class="mediaright">'; + echo '<button type="submit" name="fn[start]" ' . $page_buttons['start'] . '>' . + $this->lang['start'] . '</button>'; + echo '<button type="submit" name="fn[prev]" ' . $page_buttons['prev'] . '>' . + $this->lang['prev'] . "</button>"; + echo '<button type="submit" name="fn[next]" ' . $page_buttons['next'] . '>' . + $this->lang['next'] . '</button>'; + echo '<button type="submit" name="fn[last]" ' . $page_buttons['last'] . '>' . + $this->lang['last'] . '</button>'; + echo '</span>'; if (!empty($this->filter)) { - ptln(" <button type=\"submit\" name=\"fn[search][clear]\">".$this->lang['clear']."</button>"); + echo '<button type="submit" name="fn[search][clear]">' . $this->lang['clear'] . '</button>'; } - ptln(" <button type=\"submit\" name=\"fn[export]\">".$export_label."</button>"); - ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />"); - ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />"); + echo '<button type="submit" name="fn[export]">' . $export_label . '</button>'; + echo '<input type="hidden" name="do" value="admin" />'; + echo '<input type="hidden" name="page" value="usermanager" />'; $this->htmlFilterSettings(2); - ptln(" </td></tr>"); - ptln(" </tbody>"); - ptln(" </table>"); - ptln(" </div>"); + echo '</td></tr>'; + echo '</tbody>'; + echo '</table>'; + echo '</div>'; - ptln("</form>"); - ptln("</div>"); + echo '</form>'; + echo '</div>'; - $style = $this->edit_user ? " class=\"edit_user\"" : ""; + $style = $this->edit_user ? ' class="edit_user"' : ''; if ($this->auth->canDo('addUser')) { - ptln("<div".$style.">"); - print $this->locale_xhtml('add'); - ptln(" <div class=\"level2\">"); + echo '<div' . $style . '>'; + echo $this->locale_xhtml('add'); + echo '<div class="level2">'; - $this->htmlUserForm('add', null, array(), 4); + $this->htmlUserForm('add', null, [], 4); - ptln(" </div>"); - ptln("</div>"); + echo '</div>'; + echo '</div>'; } - if ($this->edit_user && $this->auth->canDo('UserMod')) { - ptln("<div".$style." id=\"scroll__here\">"); - print $this->locale_xhtml('edit'); - ptln(" <div class=\"level2\">"); + if ($this->edit_user && $this->auth->canDo('UserMod')) { + echo '<div' . $style . ' id="scroll__here">'; + echo $this->locale_xhtml('edit'); + echo '<div class="level2">'; $this->htmlUserForm('modify', $this->edit_user, $this->edit_userdata, 4); - ptln(" </div>"); - ptln("</div>"); + echo '</div>'; + echo '</div>'; } if ($this->auth->canDo('addUser')) { $this->htmlImportForm(); } - ptln("</div>"); + echo '</div>'; return true; } @@ -356,9 +356,9 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin */ public function isAccessibleByCurrentUser() { - /** @var DokuWiki_Auth_Plugin $auth */ + /** @var AuthPlugin $auth */ global $auth; - if(!$auth || !$auth->canDo('getUsers') ) { + if (!$auth instanceof AuthPlugin || !$auth->canDo('getUsers')) { return false; } @@ -371,33 +371,35 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin * * @param string $cmd 'add' or 'modify' * @param string $user id of user - * @param array $userdata array with name, mail, pass and grps - * @param int $indent + * @param array $userdata array with name, mail, pass and grps + * @param int $indent + * @todo use Form class */ - protected function htmlUserForm($cmd, $user = '', $userdata = array(), $indent = 0) + protected function htmlUserForm($cmd, $user = '', $userdata = [], $indent = 0) { global $conf; global $ID; global $lang; - - $name = $mail = $groups = ''; - $notes = array(); + $name = ''; + $mail = ''; + $groups = ''; + $notes = []; if ($user) { extract($userdata); - if (!empty($grps)) $groups = join(',', $grps); + if (!empty($grps)) $groups = implode(',', $grps); } else { $notes[] = sprintf($this->lang['note_group'], $conf['defaultgroup']); } - ptln("<form action=\"".wl($ID)."\" method=\"post\">", $indent); + printf('<form action="%s" method="post">', wl($ID)); formSecurityToken(); - ptln(" <div class=\"table\">", $indent); - ptln(" <table class=\"inline\">", $indent); - ptln(" <thead>", $indent); - ptln(" <tr><th>".$this->lang["field"]."</th><th>".$this->lang["value"]."</th></tr>", $indent); - ptln(" </thead>", $indent); - ptln(" <tbody>", $indent); + echo '<div class="table">'; + echo '<table class="inline">'; + echo '<thead>'; + echo '<tr><th>' . $this->lang["field"] . "</th><th>" . $this->lang["value"] . "</th></tr>"; + echo '</thead>'; + echo '<tbody>'; $this->htmlInputField( $cmd . "_userid", @@ -462,40 +464,41 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $notes[] = $this->lang['note_notify']; } - ptln("<tr><td><label for=\"".$cmd."_usernotify\" >". - $this->lang["user_notify"].": </label></td> - <td><input type=\"checkbox\" id=\"".$cmd."_usernotify\" name=\"usernotify\" value=\"1\" /> - </td></tr>", $indent); + echo '<tr><td><label for="' . $cmd . "_usernotify\" >" . + $this->lang["user_notify"] . ': </label></td> + <td><input type="checkbox" id="' . $cmd . '_usernotify" name="usernotify" value="1" /> + </td></tr>'; } - ptln(" </tbody>", $indent); - ptln(" <tbody>", $indent); - ptln(" <tr>", $indent); - ptln(" <td colspan=\"2\">", $indent); - ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />", $indent); - ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />", $indent); + echo '</tbody>'; + echo '<tbody>'; + echo '<tr>'; + echo '<td colspan="2">'; + echo '<input type="hidden" name="do" value="admin" />'; + echo '<input type="hidden" name="page" value="usermanager" />'; // save current $user, we need this to access details if the name is changed - if ($user) - ptln(" <input type=\"hidden\" name=\"userid_old\" value=\"".hsc($user)."\" />", $indent); + if ($user) { + echo '<input type="hidden" name="userid_old" value="' . hsc($user) . "\" />"; + } - $this->htmlFilterSettings($indent+10); + $this->htmlFilterSettings($indent + 10); - ptln(" <button type=\"submit\" name=\"fn[".$cmd."]\">".$this->lang[$cmd]."</button>", $indent); - ptln(" </td>", $indent); - ptln(" </tr>", $indent); - ptln(" </tbody>", $indent); - ptln(" </table>", $indent); + echo '<button type="submit" name="fn[' . $cmd . ']">' . $this->lang[$cmd] . '</button>'; + echo '</td>'; + echo '</tr>'; + echo '</tbody>'; + echo '</table>'; if ($notes) { - ptln(" <ul class=\"notes\">"); + echo '<ul class="notes">'; foreach ($notes as $note) { - ptln(" <li><span class=\"li\">".$note."</li>", $indent); + echo '<li><span class="li">' . $note . '</li>'; } - ptln(" </ul>"); + echo '</ul>'; } - ptln(" </div>", $indent); - ptln("</form>", $indent); + echo '</div>'; + echo '</form>'; } /** @@ -505,9 +508,10 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin * @param string $name * @param string $label * @param string $value - * @param bool $cando whether auth backend is capable to do this action - * @param bool $required is this field required? + * @param bool $cando whether auth backend is capable to do this action + * @param bool $required is this field required? * @param int $indent + * @todo obsolete when Form class is used */ protected function htmlInputField($id, $name, $label, $value, $cando, $required, $indent = 0) { @@ -516,19 +520,19 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin if ($name == 'userpass' || $name == 'userpass2') { $fieldtype = 'password'; - $autocomp = 'autocomplete="off"'; + $autocomp = 'autocomplete="off"'; } elseif ($name == 'usermail') { $fieldtype = 'email'; - $autocomp = ''; + $autocomp = ''; } else { $fieldtype = 'text'; - $autocomp = ''; + $autocomp = ''; } $value = hsc($value); echo "<tr $class>"; echo "<td><label for=\"$id\" >$label: </label></td>"; - echo "<td>"; + echo '<td>'; if ($cando) { $req = ''; if ($required) $req = 'required="required"'; @@ -539,8 +543,8 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit disabled\" disabled=\"disabled\" />"; } - echo "</td>"; - echo "</tr>"; + echo '</td>'; + echo '</tr>'; } /** @@ -563,10 +567,10 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin protected function htmlFilterSettings($indent = 0) { - ptln("<input type=\"hidden\" name=\"start\" value=\"".$this->start."\" />", $indent); + echo '<input type="hidden" name="start" value="' . $this->start . '" />'; foreach ($this->filter as $key => $filter) { - ptln("<input type=\"hidden\" name=\"filter[".$key."]\" value=\"".hsc($filter)."\" />", $indent); + echo '<input type="hidden" name="filter[' . $key . ']" value="' . hsc($filter) . '" />'; } } @@ -579,52 +583,52 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin { global $ID; - $failure_download_link = wl($ID, array('do'=>'admin','page'=>'usermanager','fn[importfails]'=>1)); + $failure_download_link = wl($ID, ['do' => 'admin', 'page' => 'usermanager', 'fn[importfails]' => 1]); - ptln('<div class="level2 import_users">', $indent); - print $this->locale_xhtml('import'); - ptln(' <form action="'.wl($ID).'" method="post" enctype="multipart/form-data">', $indent); + echo '<div class="level2 import_users">'; + echo $this->locale_xhtml('import'); + echo '<form action="' . wl($ID) . '" method="post" enctype="multipart/form-data">'; formSecurityToken(); - ptln(' <label>'.$this->lang['import_userlistcsv'].'<input type="file" name="import" /></label>', $indent); - ptln(' <button type="submit" name="fn[import]">'.$this->lang['import'].'</button>', $indent); - ptln(' <input type="hidden" name="do" value="admin" />', $indent); - ptln(' <input type="hidden" name="page" value="usermanager" />', $indent); + echo '<label>' . $this->lang['import_userlistcsv'] . '<input type="file" name="import" /></label>'; + echo '<button type="submit" name="fn[import]">' . $this->lang['import'] . '</button>'; + echo '<input type="hidden" name="do" value="admin" />'; + echo '<input type="hidden" name="page" value="usermanager" />'; - $this->htmlFilterSettings($indent+4); - ptln(' </form>', $indent); - ptln('</div>'); + $this->htmlFilterSettings($indent + 4); + echo '</form>'; + echo '</div>'; // list failures from the previous import if ($this->import_failures) { $digits = strlen(count($this->import_failures)); - ptln('<div class="level3 import_failures">', $indent); - ptln(' <h3>'.$this->lang['import_header'].'</h3>'); - ptln(' <table class="import_failures">', $indent); - ptln(' <thead>', $indent); - ptln(' <tr>', $indent); - ptln(' <th class="line">'.$this->lang['line'].'</th>', $indent); - ptln(' <th class="error">'.$this->lang['error'].'</th>', $indent); - ptln(' <th class="userid">'.$this->lang['user_id'].'</th>', $indent); - ptln(' <th class="username">'.$this->lang['user_name'].'</th>', $indent); - ptln(' <th class="usermail">'.$this->lang['user_mail'].'</th>', $indent); - ptln(' <th class="usergroups">'.$this->lang['user_groups'].'</th>', $indent); - ptln(' </tr>', $indent); - ptln(' </thead>', $indent); - ptln(' <tbody>', $indent); + echo '<div class="level3 import_failures">'; + echo '<h3>' . $this->lang['import_header'] . '</h3>'; + echo '<table class="import_failures">'; + echo '<thead>'; + echo '<tr>'; + echo '<th class="line">' . $this->lang['line'] . '</th>'; + echo '<th class="error">' . $this->lang['error'] . '</th>'; + echo '<th class="userid">' . $this->lang['user_id'] . '</th>'; + echo '<th class="username">' . $this->lang['user_name'] . '</th>'; + echo '<th class="usermail">' . $this->lang['user_mail'] . '</th>'; + echo '<th class="usergroups">' . $this->lang['user_groups'] . '</th>'; + echo '</tr>'; + echo '</thead>'; + echo '<tbody>'; foreach ($this->import_failures as $line => $failure) { - ptln(' <tr>', $indent); - ptln(' <td class="lineno"> '.sprintf('%0'.$digits.'d', $line).' </td>', $indent); - ptln(' <td class="error">' .$failure['error'].' </td>', $indent); - ptln(' <td class="field userid"> '.hsc($failure['user'][0]).' </td>', $indent); - ptln(' <td class="field username"> '.hsc($failure['user'][2]).' </td>', $indent); - ptln(' <td class="field usermail"> '.hsc($failure['user'][3]).' </td>', $indent); - ptln(' <td class="field usergroups"> '.hsc($failure['user'][4]).' </td>', $indent); - ptln(' </tr>', $indent); + echo '<tr>'; + echo '<td class="lineno"> ' . sprintf('%0' . $digits . 'd', $line) . ' </td>'; + echo '<td class="error">' . $failure['error'] . ' </td>'; + echo '<td class="field userid"> ' . hsc($failure['user'][0]) . ' </td>'; + echo '<td class="field username"> ' . hsc($failure['user'][2]) . ' </td>'; + echo '<td class="field usermail"> ' . hsc($failure['user'][3]) . ' </td>'; + echo '<td class="field usergroups"> ' . hsc($failure['user'][4]) . ' </td>'; + echo '</tr>'; } - ptln(' </tbody>', $indent); - ptln(' </table>', $indent); - ptln(' <p><a href="'.$failure_download_link.'">'.$this->lang['import_downloadfailures'].'</a></p>'); - ptln('</div>'); + echo '</tbody>'; + echo '</table>'; + echo '<p><a href="' . $failure_download_link . '">' . $this->lang['import_downloadfailures'] . '</a></p>'; + echo '</div>'; } } @@ -639,7 +643,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin if (!checkSecurityToken()) return false; if (!$this->auth->canDo('addUser')) return false; - list($user,$pass,$name,$mail,$grps,$passconfirm) = $this->retrieveUser(); + [$user, $pass, $name, $mail, $grps, $passconfirm] = $this->retrieveUser(); if (empty($user)) return false; if ($this->auth->canDo('modPass')) { @@ -651,19 +655,15 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin msg($this->lang['addUser_error_missing_pass'], -1); return false; } - } else { - if (!$this->verifyPassword($pass, $passconfirm)) { - msg($this->lang['add_fail'], -1); - msg($this->lang['addUser_error_pass_not_identical'], -1); - return false; - } - } - } else { - if (!empty($pass)) { + } elseif (!$this->verifyPassword($pass, $passconfirm)) { msg($this->lang['add_fail'], -1); - msg($this->lang['addUser_error_modPass_disabled'], -1); + msg($this->lang['addUser_error_pass_not_identical'], -1); return false; } + } elseif (!empty($pass)) { + msg($this->lang['add_fail'], -1); + msg($this->lang['addUser_error_modPass_disabled'], -1); + return false; } if ($this->auth->canDo('modName')) { @@ -672,12 +672,10 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin msg($this->lang['addUser_error_name_missing'], -1); return false; } - } else { - if (!empty($name)) { - msg($this->lang['add_fail'], -1); - msg($this->lang['addUser_error_modName_disabled'], -1); - return false; - } + } elseif (!empty($name)) { + msg($this->lang['add_fail'], -1); + msg($this->lang['addUser_error_modName_disabled'], -1); + return false; } if ($this->auth->canDo('modMail')) { @@ -686,15 +684,13 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin msg($this->lang['addUser_error_mail_missing'], -1); return false; } - } else { - if (!empty($mail)) { - msg($this->lang['add_fail'], -1); - msg($this->lang['addUser_error_modMail_disabled'], -1); - return false; - } + } elseif (!empty($mail)) { + msg($this->lang['add_fail'], -1); + msg($this->lang['addUser_error_modMail_disabled'], -1); + return false; } - if ($ok = $this->auth->triggerUserMod('create', array($user, $pass, $name, $mail, $grps))) { + if ($ok = $this->auth->triggerUserMod('create', [$user, $pass, $name, $mail, $grps])) { msg($this->lang['add_ok'], 1); if ($INPUT->has('usernotify') && $pass) { @@ -729,18 +725,18 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin return false; } - $count = $this->auth->triggerUserMod('delete', array($selected)); + $count = $this->auth->triggerUserMod('delete', [$selected]); if ($count == count($selected)) { $text = str_replace('%d', $count, $this->lang['delete_ok']); msg("$text.", 1); } else { $part1 = str_replace('%d', $count, $this->lang['delete_ok']); - $part2 = str_replace('%d', (count($selected)-$count), $this->lang['delete_fail']); + $part2 = str_replace('%d', (count($selected) - $count), $this->lang['delete_fail']); msg("$part1, $part2", -1); } // invalidate all sessions - io_saveFile($conf['cachedir'].'/sessionpurge', time()); + io_saveFile($conf['cachedir'] . '/sessionpurge', time()); return true; } @@ -787,10 +783,10 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $oldinfo = $this->auth->getUserData($olduser); // get new user data subject to change - list($newuser,$newpass,$newname,$newmail,$newgrps,$passconfirm) = $this->retrieveUser(); + [$newuser, $newpass, $newname, $newmail, $newgrps, $passconfirm] = $this->retrieveUser(); if (empty($newuser)) return false; - $changes = array(); + $changes = []; if ($newuser != $olduser) { if (!$this->auth->canDo('modLogin')) { // sanity check, shouldn't be possible msg($this->lang['update_fail'], -1); @@ -812,11 +808,9 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin } else { return false; } - } else { + } elseif ($INPUT->has('usernotify')) { // no new password supplied, check if we need to generate one (or it stays unchanged) - if ($INPUT->has('usernotify')) { - $changes['pass'] = auth_pwgen($olduser); - } + $changes['pass'] = auth_pwgen($olduser); } } @@ -830,7 +824,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $changes['grps'] = $newgrps; } - if ($ok = $this->auth->triggerUserMod('modify', array($olduser, $changes))) { + if ($ok = $this->auth->triggerUserMod('modify', [$olduser, $changes])) { msg($this->lang['update_ok'], 1); if ($INPUT->has('usernotify') && !empty($changes['pass'])) { @@ -839,7 +833,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin } // invalidate all sessions - io_saveFile($conf['cachedir'].'/sessionpurge', time()); + io_saveFile($conf['cachedir'] . '/sessionpurge', time()); } else { msg($this->lang['update_fail'], -1); } @@ -854,9 +848,9 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin /** * Send password change notification email * - * @param string $user id of user - * @param string $password plain text - * @param bool $status_alert whether status alert should be shown + * @param string $user id of user + * @param string $password plain text + * @param bool $status_alert whether status alert should be shown * @return bool whether succesful */ protected function notifyUser($user, $password, $status_alert = true) @@ -866,10 +860,8 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin if ($status_alert) { msg($this->lang['notify_ok'], 1); } - } else { - if ($status_alert) { - msg($this->lang['notify_fail'], -1); - } + } elseif ($status_alert) { + msg($this->lang['notify_fail'], -1); } return $sent; @@ -879,8 +871,8 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin * Verify password meets minimum requirements * :TODO: extend to support password strength * - * @param string $password candidate string for new password - * @param string $confirm repeated password for confirmation + * @param string $password candidate string for new password + * @param string $confirm repeated password for confirmation * @return bool true if meets requirements, false otherwise */ protected function verifyPassword($password, $confirm) @@ -910,23 +902,27 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin */ protected function retrieveUser($clean = true) { - /** @var DokuWiki_Auth_Plugin $auth */ + /** @var AuthPlugin $auth */ global $auth; global $INPUT; - $user = array(); + $user = []; $user[0] = ($clean) ? $auth->cleanUser($INPUT->str('userid')) : $INPUT->str('userid'); $user[1] = $INPUT->str('userpass'); $user[2] = $INPUT->str('username'); $user[3] = $INPUT->str('usermail'); $user[4] = explode(',', $INPUT->str('usergroups')); - $user[5] = $INPUT->str('userpass2'); // repeated password for confirmation + $user[5] = $INPUT->str('userpass2'); // repeated password for confirmation $user[4] = array_map('trim', $user[4]); - if ($clean) $user[4] = array_map(array($auth,'cleanGroup'), $user[4]); + if ($clean) { + $user[4] = array_map([$auth, 'cleanGroup'], $user[4]); + } $user[4] = array_filter($user[4]); $user[4] = array_unique($user[4]); - if (!count($user[4])) $user[4] = null; + if ($user[4] === []) { + $user[4] = null; + } return $user; } @@ -939,15 +935,15 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin protected function setFilter($op) { - $this->filter = array(); + $this->filter = []; if ($op == 'new') { - list($user,/* $pass */,$name,$mail,$grps) = $this->retrieveUser(false); + [$user, /* pass */, $name, $mail, $grps] = $this->retrieveUser(false); if (!empty($user)) $this->filter['user'] = $user; if (!empty($name)) $this->filter['name'] = $name; if (!empty($mail)) $this->filter['mail'] = $mail; - if (!empty($grps)) $this->filter['grps'] = join('|', $grps); + if (!empty($grps)) $this->filter['grps'] = implode('|', $grps); } } @@ -963,7 +959,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $t_filter = $INPUT->arr('filter'); // messy, but this way we ensure we aren't getting any additional crap from malicious users - $filter = array(); + $filter = []; if (isset($t_filter['user'])) $filter['user'] = $t_filter['user']; if (isset($t_filter['name'])) $filter['name'] = $t_filter['name']; @@ -997,7 +993,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $disabled = 'disabled="disabled"'; - $buttons = array(); + $buttons = []; $buttons['start'] = $buttons['prev'] = ($this->start == 0) ? $disabled : ''; if ($this->users_total == -1) { @@ -1022,12 +1018,12 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin { // list of users for export - based on current filter criteria $user_list = $this->auth->retrieveUsers(0, 0, $this->filter); - $column_headings = array( + $column_headings = [ $this->lang["user_id"], $this->lang["user_name"], $this->lang["user_mail"], $this->lang["user_groups"] - ); + ]; // ============================================================================================== // GENERATE OUTPUT @@ -1041,7 +1037,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $fd = fopen('php://output', 'w'); fputcsv($fd, $column_headings); foreach ($user_list as $user => $info) { - $line = array($user, $info['name'], $info['mail'], join(',', $info['grps'])); + $line = [$user, $info['name'], $info['mail'], implode(',', $info['grps'])]; fputcsv($fd, $line); } fclose($fd); @@ -1066,21 +1062,22 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin if (!$this->auth->canDo('addUser')) return false; // check file uploaded ok. - if (empty($_FILES['import']['size']) || + if ( + empty($_FILES['import']['size']) || !empty($_FILES['import']['error']) && $this->isUploadedFile($_FILES['import']['tmp_name']) ) { msg($this->lang['import_error_upload'], -1); return false; } // retrieve users from the file - $this->import_failures = array(); + $this->import_failures = []; $import_success_count = 0; $import_fail_count = 0; $line = 0; $fd = fopen($_FILES['import']['tmp_name'], 'r'); if ($fd) { while ($csv = fgets($fd)) { - if (!\dokuwiki\Utf8\Clean::isUtf8($csv)) { + if (!Clean::isUtf8($csv)) { $csv = utf8_encode($csv); } $raw = str_getcsv($csv); @@ -1092,7 +1089,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin if (count($raw) < 4) { // need at least four fields $import_fail_count++; $error = sprintf($this->lang['import_error_fields'], count($raw)); - $this->import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv); + $this->import_failures[$line] = ['error' => $error, 'user' => $raw, 'orig' => $csv]; continue; } array_splice($raw, 1, 0, auth_pwgen()); // splice in a generated password @@ -1106,7 +1103,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin } else { $import_fail_count++; array_splice($raw, 1, 1); // remove the spliced in password - $this->import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv); + $this->import_failures[$line] = ['error' => $error, 'user' => $raw, 'orig' => $csv]; } } msg( @@ -1140,7 +1137,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin * @param string $error * @return array|false cleaned data or false */ - protected function cleanImportUser($candidate, & $error) + protected function cleanImportUser($candidate, &$error) { global $INPUT; @@ -1152,7 +1149,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $INPUT->set('usergroups', $candidate[4]); $cleaned = $this->retrieveUser(); - list($user,/* $pass */,$name,$mail,/* $grps */) = $cleaned; + [$user, /* pass */, $name, $mail, /* grps */] = $cleaned; if (empty($user)) { $error = $this->lang['import_error_baduserid']; return false; @@ -1170,11 +1167,9 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin $error = $this->lang['import_error_badmail']; return false; } - } else { - if (!empty($mail)) { - $error = $this->lang['import_error_badmail']; - return false; - } + } elseif (!empty($mail)) { + $error = $this->lang['import_error_badmail']; + return false; } return $cleaned; @@ -1185,7 +1180,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin * * Required a check of canDo('addUser') before * - * @param array $user data of user + * @param array $user data of user * @param string &$error reference catched error message * @return bool whether successful */ @@ -1216,7 +1211,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin // output the csv $fd = fopen('php://output', 'w'); foreach ($this->import_failures as $fail) { - fputs($fd, $fail['orig']); + fwrite($fd, $fail['orig']); } fclose($fd); die; diff --git a/lib/plugins/usermanager/cli.php b/lib/plugins/usermanager/cli.php index 0efd9ec0d..91cf07561 100644 --- a/lib/plugins/usermanager/cli.php +++ b/lib/plugins/usermanager/cli.php @@ -1,5 +1,6 @@ <?php +use dokuwiki\Extension\CLIPlugin; use dokuwiki\Extension\AuthPlugin; use splitbrain\phpcli\Options; use splitbrain\phpcli\TableFormatter; @@ -12,7 +13,7 @@ use splitbrain\phpcli\TableFormatter; * @license GPL2 * @author Karsten Kosmala <karsten.kosmala@gmail.com> */ -class cli_plugin_usermanager extends DokuWiki_CLI_Plugin +class cli_plugin_usermanager extends CLIPlugin { public function __construct() { @@ -62,7 +63,7 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin /** @var AuthPlugin $auth */ global $auth; - if (!isset($auth)) { + if (!$auth instanceof AuthPlugin) { $this->error($this->getLang('noauth')); return 1; } @@ -127,9 +128,9 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin foreach ($list as $username => $user) { $content = [$username]; if ($details) { - array_push($content, $user['name']); - array_push($content, $user['mail']); - array_push($content, implode(", ", $user['grps'])); + $content[] = $user['name']; + $content[] = $user['mail']; + $content[] = implode(", ", $user['grps']); } echo $tr->format( [15, 25, 25, 15], @@ -155,7 +156,7 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin return 1; } - list($login, $mail, $name, $grps, $pass) = $args; + [$login, $mail, $name, $grps, $pass] = $args; $grps = array_filter(array_map('trim', explode(',', $grps))); if ($auth->canDo('modPass')) { @@ -168,15 +169,13 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin return 1; } } - } else { - if (!empty($pass)) { - $this->error($this->getLang('add_fail')); - $this->error($this->getLang('addUser_error_modPass_disabled')); - return 1; - } + } elseif (!empty($pass)) { + $this->error($this->getLang('add_fail')); + $this->error($this->getLang('addUser_error_modPass_disabled')); + return 1; } - if ($auth->triggerUserMod('create', array($login, $pass, $name, $mail, $grps))) { + if ($auth->triggerUserMod('create', [$login, $pass, $name, $mail, $grps])) { $this->success($this->getLang('add_ok')); } else { $this->printErrorMessages(); @@ -204,9 +203,9 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin } $users = explode(',', $args[0]); - $count = $auth->triggerUserMod('delete', array($users)); + $count = $auth->triggerUserMod('delete', [$users]); - if (!($count == count($users))) { + if ($count != count($users)) { $this->printErrorMessages(); $part1 = str_replace('%d', $count, $this->getLang('delete_ok')); $part2 = str_replace('%d', (count($users) - $count), $this->getLang('delete_fail')); @@ -228,22 +227,22 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin /** @var AuthPlugin $auth */ global $auth; - list($name, $newgrps) = $args; + [$name, $newgrps] = $args; $newgrps = array_filter(array_map('trim', explode(',', $newgrps))); $oldinfo = $auth->getUserData($name); - $changes = array(); + $changes = []; - if (!empty($newgrps) && $auth->canDo('modGroups')) { + if ($newgrps !== [] && $auth->canDo('modGroups')) { $changes['grps'] = $oldinfo['grps']; foreach ($newgrps as $group) { if (!in_array($group, $oldinfo['grps'])) { - array_push($changes['grps'], $group); + $changes['grps'][] = $group; } } } if (!empty(array_diff($changes['grps'], $oldinfo['grps']))) { - if ($auth->triggerUserMod('modify', array($name, $changes))) { + if ($auth->triggerUserMod('modify', [$name, $changes])) { $this->success($this->getLang('update_ok')); } else { $this->printErrorMessages(); @@ -266,12 +265,12 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin /** @var AuthPlugin $auth */ global $auth; - list($name, $grps) = $args; + [$name, $grps] = $args; $grps = array_filter(array_map('trim', explode(',', $grps))); $oldinfo = $auth->getUserData($name); - $changes = array(); + $changes = []; - if (!empty($grps) && $auth->canDo('modGroups')) { + if ($grps !== [] && $auth->canDo('modGroups')) { $changes['grps'] = $oldinfo['grps']; foreach ($grps as $group) { if (($pos = array_search($group, $changes['grps'])) == !false) { @@ -281,7 +280,7 @@ class cli_plugin_usermanager extends DokuWiki_CLI_Plugin } if (!empty(array_diff($oldinfo['grps'], $changes['grps']))) { - if ($auth->triggerUserMod('modify', array($name, $changes))) { + if ($auth->triggerUserMod('modify', [$name, $changes])) { $this->success($this->getLang('update_ok')); } else { $this->printErrorMessages(); diff --git a/lib/tpl/dokuwiki/detail.php b/lib/tpl/dokuwiki/detail.php index b5f0a6361..c47a7549e 100644 --- a/lib/tpl/dokuwiki/detail.php +++ b/lib/tpl/dokuwiki/detail.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki Image Detail Page * @@ -15,20 +16,20 @@ if (!defined('DOKU_INC')) die(); <head> <meta charset="utf-8" /> <title> - <?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?> + <?php echo hsc(tpl_img_getTag('IPTC.Headline', $IMG))?> [<?php echo strip_tags($conf['title'])?>] </title> <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script> <?php tpl_metaheaders()?> <meta name="viewport" content="width=device-width,initial-scale=1" /> - <?php echo tpl_favicon(array('favicon', 'mobile')) ?> + <?php echo tpl_favicon(['favicon', 'mobile']) ?> <?php tpl_includeFile('meta.html') ?> </head> <body> <div id="dokuwiki__site"><div id="dokuwiki__top" class="site <?php echo tpl_classes(); ?>"> - <?php include('tpl_header.php') ?> + <?php include(__DIR__ . '/tpl_header.php') ?> <div class="wrapper group" id="dokuwiki__detail"> @@ -36,8 +37,8 @@ if (!defined('DOKU_INC')) die(); <main id="dokuwiki__content"><div class="pad group"> <?php html_msgarea() ?> - <?php if(!$ERROR): ?> - <div class="pageId"><span><?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG)); ?></span></div> + <?php if (!$ERROR) : ?> + <div class="pageId"><span><?php echo hsc(tpl_img_getTag('IPTC.Headline', $IMG)); ?></span></div> <?php endif; ?> <div class="page group"> @@ -45,26 +46,26 @@ if (!defined('DOKU_INC')) die(); <?php tpl_includeFile('pageheader.html') ?> <!-- detail start --> <?php - if($ERROR): - echo '<h1>'.$ERROR.'</h1>'; - else: ?> - <?php if($REV) echo p_locale_xhtml('showrev');?> + if ($ERROR) : + echo '<h1>' . $ERROR . '</h1>'; + else : ?> + <?php if ($REV) echo p_locale_xhtml('showrev');?> <h1><?php echo nl2br(hsc(tpl_img_getTag('simple.title'))); ?></h1> - <?php tpl_img(900,700); /* parameters: maximum width, maximum height (and more) */ ?> + <?php tpl_img(900, 700); /* parameters: maximum width, maximum height (and more) */ ?> <div class="img_detail"> <?php tpl_img_meta(); ?> <dl> <?php - echo '<dt>'.$lang['reference'].':</dt>'; - $media_usage = ft_mediause($IMG,true); - if(count($media_usage) > 0){ - foreach($media_usage as $path){ - echo '<dd>'.html_wikilink($path).'</dd>'; + echo '<dt>' . $lang['reference'] . ':</dt>'; + $media_usage = ft_mediause($IMG, true); + if ($media_usage !== []) { + foreach ($media_usage as $path) { + echo '<dd>' . html_wikilink($path) . '</dd>'; } - }else{ - echo '<dd>'.$lang['nothingfound'].'</dd>'; + } else { + echo '<dd>' . $lang['nothingfound'] . '</dd>'; } ?> </dl> @@ -86,7 +87,7 @@ if (!defined('DOKU_INC')) die(); <hr class="a11y" /> <!-- PAGE ACTIONS --> - <?php if (!$ERROR): ?> + <?php if (!$ERROR) : ?> <nav id="dokuwiki__pagetools" aria-labelledby="dokuwiki__pagetools__heading"> <h3 class="a11y" id="dokuwiki__pagetools__heading"><?php echo $lang['page_tools']; ?></h3> <div class="tools"> @@ -98,7 +99,7 @@ if (!defined('DOKU_INC')) die(); <?php endif; ?> </div><!-- /wrapper --> - <?php include('tpl_footer.php') ?> + <?php include(__DIR__ . '/tpl_footer.php') ?> </div></div><!-- /site --> </body> </html> diff --git a/lib/tpl/dokuwiki/images/pagetools-build.php b/lib/tpl/dokuwiki/images/pagetools-build.php index e19d750c7..42e5bc02c 100644 --- a/lib/tpl/dokuwiki/images/pagetools-build.php +++ b/lib/tpl/dokuwiki/images/pagetools-build.php @@ -17,7 +17,7 @@ $GAMMA = 0.8; $OPTIPNG = '/usr/bin/optipng'; -if('cli' != php_sapi_name()) die('please run from commandline'); +if('cli' != PHP_SAPI) die('please run from commandline'); // load input images $input = glob('pagetools/*.png'); @@ -86,11 +86,7 @@ function hex2rgb($hex) { } // calc rgb - return array( - 'r' => hexdec(substr($hex, 0, 2)), - 'g' => hexdec(substr($hex, 2, 2)), - 'b' => hexdec(substr($hex, 4, 2)) - ); + return ['r' => hexdec(substr($hex, 0, 2)), 'g' => hexdec(substr($hex, 2, 2)), 'b' => hexdec(substr($hex, 4, 2))]; } /** diff --git a/lib/tpl/dokuwiki/main.php b/lib/tpl/dokuwiki/main.php index 014a35c0e..d4b672bd2 100644 --- a/lib/tpl/dokuwiki/main.php +++ b/lib/tpl/dokuwiki/main.php @@ -1,4 +1,5 @@ <?php + /** * DokuWiki Default Template 2012 * @@ -11,7 +12,7 @@ if (!defined('DOKU_INC')) die(); /* must be run from within DokuWiki */ $hasSidebar = page_findnearest($conf['sidebar']); -$showSidebar = $hasSidebar && ($ACT=='show'); +$showSidebar = $hasSidebar && ($ACT == 'show'); ?><!DOCTYPE html> <html lang="<?php echo $conf['lang'] ?>" dir="<?php echo $lang['direction'] ?>" class="no-js"> <head> @@ -20,7 +21,7 @@ $showSidebar = $hasSidebar && ($ACT=='show'); <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script> <?php tpl_metaheaders() ?> <meta name="viewport" content="width=device-width,initial-scale=1" /> - <?php echo tpl_favicon(array('favicon', 'mobile')) ?> + <?php echo tpl_favicon(['favicon', 'mobile']) ?> <?php tpl_includeFile('meta.html') ?> </head> @@ -28,14 +29,14 @@ $showSidebar = $hasSidebar && ($ACT=='show'); <div id="dokuwiki__site"><div id="dokuwiki__top" class="site <?php echo tpl_classes(); ?> <?php echo ($showSidebar) ? 'showSidebar' : ''; ?> <?php echo ($hasSidebar) ? 'hasSidebar' : ''; ?>"> - <?php include('tpl_header.php') ?> + <?php include(__DIR__ . '/tpl_header.php') ?> <div class="wrapper group"> - <?php if($showSidebar): ?> + <?php if ($showSidebar) : ?> <!-- ********** ASIDE ********** --> <nav id="dokuwiki__aside" aria-label="<?php echo $lang['sidebar'] - ?>"><div class="pad aside include group"> + ?>"><div class="pad aside include group"> <h3 class="toggle"><?php echo $lang['sidebar'] ?></h3> <div class="content"><div class="group"> <?php tpl_flush() ?> @@ -79,7 +80,7 @@ $showSidebar = $hasSidebar && ($ACT=='show'); </nav> </div><!-- /wrapper --> - <?php include('tpl_footer.php') ?> + <?php include(__DIR__ . '/tpl_footer.php') ?> </div></div><!-- /site --> <div class="no"><?php tpl_indexerWebBug() /* provide DokuWiki housekeeping, required in all templates */ ?></div> diff --git a/lib/tpl/dokuwiki/mediamanager.php b/lib/tpl/dokuwiki/mediamanager.php index c859ab627..106a439a4 100644 --- a/lib/tpl/dokuwiki/mediamanager.php +++ b/lib/tpl/dokuwiki/mediamanager.php @@ -1,10 +1,12 @@ <?php + /** * DokuWiki Media Manager Popup * * @author Andreas Gohr <andi@splitbrain.org> * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) */ + // must be run from within DokuWiki if (!defined('DOKU_INC')) die(); @@ -19,7 +21,7 @@ if (!defined('DOKU_INC')) die(); <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script> <?php tpl_metaheaders()?> <meta name="viewport" content="width=device-width,initial-scale=1" /> - <?php echo tpl_favicon(array('favicon', 'mobile')) ?> + <?php echo tpl_favicon(['favicon', 'mobile']) ?> <?php tpl_includeFile('meta.html') ?> </head> diff --git a/lib/tpl/dokuwiki/tpl_footer.php b/lib/tpl/dokuwiki/tpl_footer.php index 0750c7b58..b892ba848 100644 --- a/lib/tpl/dokuwiki/tpl_footer.php +++ b/lib/tpl/dokuwiki/tpl_footer.php @@ -1,4 +1,5 @@ <?php + /** * Template footer, included in the main and detail files */ @@ -14,7 +15,7 @@ if (!defined('DOKU_INC')) die(); <div class="buttons"> <?php tpl_license('button', true, false, false); // license button, no wrapper - $target = ($conf['target']['extern']) ? 'target="'.$conf['target']['extern'].'"' : ''; + $target = ($conf['target']['extern']) ? 'target="' . $conf['target']['extern'] . '"' : ''; ?> <a href="https://www.dokuwiki.org/donate" title="Donate" <?php echo $target?>><img src="<?php echo tpl_basedir(); ?>images/button-donate.gif" width="80" height="15" alt="Donate" /></a> diff --git a/lib/tpl/dokuwiki/tpl_header.php b/lib/tpl/dokuwiki/tpl_header.php index 75447bb62..9eb608892 100644 --- a/lib/tpl/dokuwiki/tpl_header.php +++ b/lib/tpl/dokuwiki/tpl_header.php @@ -1,4 +1,5 @@ <?php + /** * Template header, included in the main and detail files */ @@ -33,24 +34,24 @@ if (!defined('DOKU_INC')) die(); '<span>' . $conf['title'] . '</span>', 'accesskey="h" title="' . tpl_getLang('home') . ' [h]"' ); - ?></h1> - <?php if ($conf['tagline']): ?> + ?></h1> + <?php if ($conf['tagline']) : ?> <p class="claim"><?php echo $conf['tagline']; ?></p> <?php endif ?> </div> <div class="tools group"> <!-- USER TOOLS --> - <?php if ($conf['useacl']): ?> + <?php if ($conf['useacl']) : ?> <div id="dokuwiki__usertools"> <h3 class="a11y"><?php echo $lang['user_tools']; ?></h3> <ul> <?php - if (!empty($_SERVER['REMOTE_USER'])) { - echo '<li class="user">'; - tpl_userinfo(); /* 'Logged in as ...' */ - echo '</li>'; - } + if (!empty($_SERVER['REMOTE_USER'])) { + echo '<li class="user">'; + tpl_userinfo(); /* 'Logged in as ...' */ + echo '</li>'; + } echo (new \dokuwiki\Menu\UserMenu())->getListItems('action '); ?> </ul> @@ -72,12 +73,12 @@ if (!defined('DOKU_INC')) die(); </div> <!-- BREADCRUMBS --> - <?php if($conf['breadcrumbs'] || $conf['youarehere']): ?> + <?php if ($conf['breadcrumbs'] || $conf['youarehere']) : ?> <div class="breadcrumbs"> - <?php if($conf['youarehere']): ?> + <?php if ($conf['youarehere']) : ?> <div class="youarehere"><?php tpl_youarehere() ?></div> <?php endif ?> - <?php if($conf['breadcrumbs']): ?> + <?php if ($conf['breadcrumbs']) : ?> <div class="trace"><?php tpl_breadcrumbs() ?></div> <?php endif ?> </div> diff --git a/lib/tpl/index.php b/lib/tpl/index.php index 4d48d5127..22a8a8575 100644 --- a/lib/tpl/index.php +++ b/lib/tpl/index.php @@ -1,4 +1,5 @@ <?php + /** * This file reads the style.ini of the used template and displays the * replacements defined in it. Color replacements will be displayed @@ -8,10 +9,11 @@ * @author Andreas Gohr <andi@splitbrain.org> * @author Anika Henke <anika@selfthinker.org> */ + // phpcs:disable PSR1.Files.SideEffects -if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); -if(!defined('NOSESSION')) define('NOSESSION',1); -require_once(DOKU_INC.'inc/init.php'); +if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); +if (!defined('NOSESSION')) define('NOSESSION', 1); +require_once(DOKU_INC . 'inc/init.php'); ?> <!DOCTYPE html> <html lang="en" dir="ltr"> @@ -50,21 +52,21 @@ $ini = $styleUtils->cssStyleini(); if (!empty($ini)) { echo '<table>'; - echo "<caption>".hsc($conf['template'])."'s style.ini</caption>"; - foreach($ini['replacements'] as $key => $val){ + echo "<caption>" . hsc($conf['template']) . "'s style.ini</caption>"; + foreach ($ini['replacements'] as $key => $val) { echo '<tr>'; - echo '<td>'.hsc($key).'</td>'; - echo '<td>'.hsc($val).'</td>'; + echo '<td>' . hsc($key) . '</td>'; + echo '<td>' . hsc($val) . '</td>'; echo '<td>'; - if(preg_match('/^#[0-f]{3,6}$/i',$val)){ - echo '<div class="color" style="background-color:'.$val.';"> </div>'; + if (preg_match('/^#[0-f]{3,6}$/i', $val)) { + echo '<div class="color" style="background-color:' . $val . ';"> </div>'; } echo '</td>'; echo '</tr>'; } echo '</table>'; } else { - echo "<p>Non-existent or invalid template or style.ini: <strong>".hsc($conf['template'])."</strong></p>"; + echo "<p>Non-existent or invalid template or style.ini: <strong>" . hsc($conf['template']) . "</strong></p>"; } ?> </body> |