diff --git a/.github/php-syntax.json b/.github/php-syntax.json new file mode 100644 index 0000000..a8b970d --- /dev/null +++ b/.github/php-syntax.json @@ -0,0 +1,15 @@ +{ + "problemMatcher": [ + { + "owner": "php -l", + "pattern": [ + { + "regexp": "^\\s*(PHP\\s+)?([a-zA-Z\\s]+):\\s+(.*)\\s+in\\s+(\\S+)\\s+on\\s+line\\s+(\\d+)$", + "file": 4, + "line": 5, + "message": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml new file mode 100644 index 0000000..5c19af7 --- /dev/null +++ b/.github/workflows/codestyle.yml @@ -0,0 +1,22 @@ +name: Code Style + +on: + push: + pull_request: + +jobs: + php: + name: PHP + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup PHP with tools + uses: shivammathur/setup-php@v2 + with: + php-version: '8.0' + extensions: ctype, dom, exif, gd, gmp, hash, intl, json, libxml, mbstring, opcache, pcre, pdo, pdo_mysql, zlib + tools: cs2pr, phpcs, php-cs-fixer + - name: phpcs + run: phpcs -n -q --report=checkstyle | cs2pr + - name: php-cs-fixer + run: php-cs-fixer fix --dry-run --diff diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..cab57e2 --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,25 @@ +name: PHP + +on: + push: + pull_request: + +jobs: + syntax: + name: "Check Syntax (${{ matrix.php }})" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: + - '8.1' + - '8.2' + steps: + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + - uses: actions/checkout@v4 + - run: echo "::add-matcher::.github/php-syntax.json" + - run: | + ! find . -type f -name '*.php' -exec php -l '{}' \; 2>&1 |grep -v '^No syntax errors detected' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..555ec1e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +name: Release + +on: + push: + tags: ['*'] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Create package + run: | + rm -rf *.tar.gz + npx --yes wspackager@latest + + - name: Check file existence + id: check_files + uses: andstor/file-existence-action@v2.0.0 + with: + files: "*.tar.gz" + + - name: On Build Failure + if: steps.check_files.outputs.files_exists == 'false' + run: | + echo "Packaging FAILED" && exit 1 + + - name: Release + uses: softprops/action-gh-release@v0.1.15 + if: startsWith(github.ref, 'refs/tags/') && steps.check_files.outputs.files_exists == 'true' + with: + files: "*.tar.gz" diff --git a/.gitignore b/.gitignore index 72079da..830f6ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.tar -option.xml \ No newline at end of file +.phpcs-cache +*.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..87458e8 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,129 @@ +in(__DIR__.'/files/') + ->notPath('lib/system/api'); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PSR1' => true, + '@PSR2' => true, + + 'array_push' => true, + 'backtick_to_shell_exec' => true, + 'no_alias_language_construct_call' => true, + 'no_mixed_echo_print' => true, + 'pow_to_exponentiation' => true, + 'random_api_migration' => true, + + 'array_syntax' => ['syntax' => 'short'], + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_whitespace_before_comma_in_array' => true, + 'normalize_index_brace' => true, + 'whitespace_after_comma_in_array' => true, + + 'non_printable_character' => ['use_escape_sequences_in_strings' => true], + + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'native_function_casing' => true, + 'native_function_type_declaration_casing' => true, + + 'cast_spaces' => ['space' => 'none'], + 'lowercase_cast' => true, + 'no_unset_cast' => true, + 'short_scalar_cast' => true, + + 'class_attributes_separation' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_null_property_initialization' => true, + 'self_accessor' => true, + 'single_class_element_per_statement' => true, + 'single_trait_insert_per_statement' => true, + + 'no_empty_comment' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + + 'native_constant_invocation' => ['strict' => false], + + 'no_alternative_syntax' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_unneeded_control_parentheses' => ['statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield', 'yield_from']], + 'no_unneeded_curly_braces' => ['namespaces' => true], + 'switch_continue_to_break' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + + 'function_typehint_space' => true, + 'lambda_not_used_import' => true, + 'native_function_invocation' => ['include' => ['@internal']], + 'no_unreachable_default_argument_value' => true, + 'nullable_type_declaration_for_default_null_value' => true, + 'return_type_declaration' => true, + 'static_lambda' => true, + + 'fully_qualified_strict_types' => true, + 'no_leading_import_slash' => true, + 'no_unused_imports' => true, + 'ordered_imports' => true, + + 'declare_equal_normalize' => true, + 'dir_constant' => true, + 'explicit_indirect_variable' => true, + 'function_to_constant' => true, + 'is_null' => true, + 'no_unset_on_property' => true, + + 'list_syntax' => ['syntax' => 'short'], + + 'clean_namespace' => true, + 'no_leading_namespace_whitespace' => true, + 'single_blank_line_before_namespace' => true, + + 'no_homoglyph_names' => true, + + 'binary_operator_spaces' => true, + 'concat_space' => ['spacing' => 'one'], + 'increment_style' => ['style' => 'post'], + 'logical_operators' => true, + 'object_operator_without_whitespace' => true, + 'operator_linebreak' => true, + 'standardize_increment' => true, + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'ternary_to_elvis_operator' => true, + 'ternary_to_null_coalescing' => true, + 'unary_operator_spaces' => true, + + 'no_useless_return' => true, + 'return_assignment' => true, + + 'multiline_whitespace_before_semicolons' => true, + 'no_empty_statement' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'space_after_semicolon' => ['remove_in_empty_for_expressions' => true], + + 'escape_implicit_backslashes' => true, + 'explicit_string_variable' => true, + 'heredoc_to_nowdoc' => true, + 'no_binary_string' => true, + 'simple_to_complex_string_variable' => true, + + 'array_indentation' => true, + 'blank_line_before_statement' => ['statements' => ['return', 'exit']], + 'compact_nullable_typehint' => true, + 'method_chaining_indentation' => true, + 'no_extra_blank_lines' => ['tokens' => ['case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'square_brace_block', 'switch', 'throw', 'use']], + 'no_spaces_around_offset' => true, + + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => false, + 'import_functions' => false, + ], + 'ordered_imports' => [ + 'imports_order' => ['class', 'function', 'const'], + ], + ]) + ->setFinder($finder); diff --git a/.phpcs.xml b/.phpcs.xml new file mode 100644 index 0000000..903c00b --- /dev/null +++ b/.phpcs.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + files + lib/system/api/* + + + + diff --git a/acpMenu.xml b/acpMenu.xml index 867ead2..ded8531 100644 --- a/acpMenu.xml +++ b/acpMenu.xml @@ -1,10 +1,9 @@ - + wcf.acp.menu.link.application - packages\acp\page\RepositoryListPage packages.acp.menu.link.package @@ -15,7 +14,7 @@ packages\acp\form\RepositoryAddForm packages.acp.menu.link.package.repository.list admin.packages.canManageRepository - fa-plus + plus diff --git a/acptemplates/__haFilebaseCategoryAddPackageServer.tpl b/acptemplates/__haFilebaseCategoryAddPackageServer.tpl index 0247fa6..279e398 100644 --- a/acptemplates/__haFilebaseCategoryAddPackageServer.tpl +++ b/acptemplates/__haFilebaseCategoryAddPackageServer.tpl @@ -8,11 +8,11 @@
  1. - +
  2. - +
{lang}packages.page.filebaseCategoryAdd.packageServer.description{/lang} @@ -41,4 +41,4 @@ -{/if} \ No newline at end of file +{/if} diff --git a/acptemplates/repositoryAdd.tpl b/acptemplates/repositoryAdd.tpl index 6b1cded..3aa55c5 100644 --- a/acptemplates/repositoryAdd.tpl +++ b/acptemplates/repositoryAdd.tpl @@ -4,46 +4,15 @@

{lang}packages.page.repositoryAdd.title{/lang}

- - -{include file='formError'} -{if $success|isset} -

- {lang}packages.page.repositoryAdd.scuccess{/lang} -

-{/if} + + -
-
- -
-
- - {if $errorField == 'name'} - - {if $errorType == 'tooShort'} - {lang}packages.page.repositoryAdd.name.error.tooShort{/lang} - {else if $errorType == 'noNumberOnStart'} - {lang}packages.page.repositoryAdd.name.error.noNumberOnStart{/lang} - {else if $errorType == 'wrongFormat'} - {lang}packages.page.repositoryAdd.name.error.wrongFormat{/lang} - {else if $errorType == 'nameTooLong'} - {lang}packages.page.repositoryAdd.name.error.nameTooLong{/lang} - {else if $errorType == 'alreadyUsed'} - {lang}packages.page.repositoryAdd.name.error.alreadyUsed{/lang} - {/if} - - {/if} - {lang}packages.page.repositoryAdd.name.description{/lang} -
- -
- -
- - {@SECURITY_TOKEN_INPUT_TAG} -
-
+{@$form->getHtml()} {include file='footer'} \ No newline at end of file diff --git a/acptemplates/repositoryList.tpl b/acptemplates/repositoryList.tpl index a747fc0..c283108 100644 --- a/acptemplates/repositoryList.tpl +++ b/acptemplates/repositoryList.tpl @@ -1,11 +1,5 @@ {include file='header' pageTitle='packages.page.repositoryList.title'} - -

{lang}packages.page.repositoryList.title{/lang}

@@ -13,7 +7,7 @@ @@ -29,7 +23,7 @@ {if $objects|count}
- +
@@ -42,9 +36,9 @@ {foreach from=$objects item=object} - + @@ -63,4 +57,4 @@

{lang}wcf.global.noItems{/lang}

{/if} -{include file='footer'} \ No newline at end of file +{include file='footer'} diff --git a/cronjob.xml b/cronjob.xml index 71ef685..cc77365 100644 --- a/cronjob.xml +++ b/cronjob.xml @@ -1,18 +1,15 @@ - + - + packages\system\cronjob\PackageServerUpdateCronjob - - + Refreshs cache of package server. + Aktualisiert den Cache des Paket-Servers. */5 * * * * - 1 - 1 - 1 - \ No newline at end of file + diff --git a/eventListener.xml b/eventListener.xml index 815dfd6..337724f 100644 --- a/eventListener.xml +++ b/eventListener.xml @@ -1,12 +1,12 @@ - - - + + + filebase\acp\form\CategoryEditForm readFormParameters,validate,save,assignVariables + packages\system\event\listener\FilebaseCategoryEditFormListener admin 1 - packages\system\event\listener\FilebaseCategoryEditFormListener filebase\acp\form\CategoryAddForm @@ -15,5 +15,5 @@ 1 packages\system\event\listener\FilebaseCategoryEditFormListener - - \ No newline at end of file + + diff --git a/files/acp/database/install_dev.hanashi.packages.php b/files/acp/database/install_dev.hanashi.packages.php new file mode 100644 index 0000000..d3b82e1 --- /dev/null +++ b/files/acp/database/install_dev.hanashi.packages.php @@ -0,0 +1,61 @@ +columns([ + ObjectIdDatabaseTableColumn::create('repositoryID'), + VarcharDatabaseTableColumn::create('name') + ->length(20) + ->notNull(), + NotNullInt10DatabaseTableColumn::create('packesCount') + ->defaultValue(0), + IntDatabaseTableColumn::create('lastUpdateTime') + ->length(10), + ]) + ->indices([ + DatabaseTablePrimaryIndex::create() + ->columns(['repositoryID']), + ]), + PartialDatabaseTable::create('wcf1_category') + ->columns([ + TinyintDatabaseTableColumn::create('isPackageServer') + ->length(1) + ->notNull() + ->defaultValue(0), + IntDatabaseTableColumn::create('repositoryID') + ->length(10), + ]) + ->foreignKeys([ + DatabaseTableForeignKey::create() + ->columns(['repositoryID']) + ->referencedTable('packages1_repository') + ->referencedColumns(['repositoryID']) + ->onDelete('SET NULL'), + ]), + PartialDatabaseTable::create('filebase1_file_version') + ->columns([ + VarcharDatabaseTableColumn::create('packageName') + ->length(100), + VarcharDatabaseTableColumn::create('packageVersion') + ->length(80), + IntDatabaseTableColumn::create('repositoryID') + ->length(10), + ]) + ->foreignKeys([ + DatabaseTableForeignKey::create() + ->columns(['repositoryID']) + ->referencedTable('packages1_repository') + ->referencedColumns(['repositoryID']) + ->onDelete('SET NULL'), + ]), +]; diff --git a/files/acp/global.php b/files/acp/global.php index 6a1b0ec..4968693 100644 --- a/files/acp/global.php +++ b/files/acp/global.php @@ -1,6 +1,11 @@ handle('packages', true); diff --git a/files/global.php b/files/global.php index e130b52..316c820 100644 --- a/files/global.php +++ b/files/global.php @@ -1,3 +1,9 @@ handle('packages'); diff --git a/files/lib/acp/form/RepositoryAddForm.class.php b/files/lib/acp/form/RepositoryAddForm.class.php index 6369151..60f629c 100644 --- a/files/lib/acp/form/RepositoryAddForm.class.php +++ b/files/lib/acp/form/RepositoryAddForm.class.php @@ -1,64 +1,80 @@ form->appendChildren([ + FormContainer::create('data') + ->appendChildren([ + TextFormField::create('name') + ->label('packages.page.repositoryAdd.name') + ->description('packages.page.repositoryAdd.name.description') + ->required() + ->maximumLength(20) + ->minimumLength(2) + ->addValidator( + new FormFieldValidator('formatCheck', static function (TextFormField $formField) { + if (\preg_match('/^[0-9]+$/', \substr($formField->getValue(), 0, 1))) { + $formField->addValidationError( + new FormFieldValidationError( + 'noNumberOnStart', + 'packages.page.repositoryAdd.name.error.noNumberOnStart' + ) + ); + + return; + } + if (!\preg_match('/^[a-z0-9]+$/', $formField->getValue())) { + $formField->addValidationError( + new FormFieldValidationError( + 'wrongFormat', + 'packages.page.repositoryAdd.name.error.wrongFormat' + ) + ); + + return; + } -class RepositoryAddForm extends AbstractForm { - public $activeMenuItem = 'packages.acp.menu.link.package.repository.add'; - - protected $name; - - public function readFormParameters() { - parent::readFormParameters(); - - if (isset($_POST['name'])) - $this->name = $_POST['name']; - } - - public function validate() { - parent::validate(); - - if (strlen($this->name) < 2) - throw new UserInputException('name', 'tooShort'); - if (preg_match('/^[0-9]+$/', substr($this->name, 0, 1))) - throw new UserInputException('name', 'noNumberOnStart'); - if (!preg_match('/^[a-z0-9]+$/', $this->name)) - throw new UserInputException('name', 'wrongFormat'); - if (strlen($this->name) > 20) - throw new UserInputException('name', 'nameTooLong'); - - $repositoryList = new RepositoryList(); - $repositoryList->getConditionBuilder()->add('name = ?', [$this->name]); - $repositoryList->readObjects(); - if (count($repositoryList) > 0) - throw new UserInputException('name', 'alreadyUsed'); - } - - public function save() { - parent::save(); - - $this->objectAction = new RepositoryAction([], 'create', ['data' => [ - 'name' => $this->name - ]]); - $this->objectAction->executeAction(); - - $this->saved(); - } - - public function saved() { - parent::saved(); - - WCF::getTPL()->assign('success', true); - } - - public function assignVariables() { - parent::assignVariables(); - - WCF::getTPL()->assign(array( - 'name' => $this->name - )); - } -} \ No newline at end of file + $repositoryList = new RepositoryList(); + $repositoryList->getConditionBuilder()->add('name = ?', [$formField->getValue()]); + $repositoryList->readObjects(); + if (\count($repositoryList) > 0) { + $formField->addValidationError( + new FormFieldValidationError( + 'alreadyUsed', + 'packages.page.repositoryAdd.name.error.alreadyUsed' + ) + ); + } + }) + ), + ]), + ]); + } +} diff --git a/files/lib/acp/page/RepositoryListPage.class.php b/files/lib/acp/page/RepositoryListPage.class.php index a1c5374..5478380 100644 --- a/files/lib/acp/page/RepositoryListPage.class.php +++ b/files/lib/acp/page/RepositoryListPage.class.php @@ -1,14 +1,17 @@ changeUser(new User(null, ['username' => 'System', 'userID' => 0]), true); - $this->downloadFile($_REQUEST['packageName'], $_REQUEST['packageVersion']); - return; - } - - $repository = new Repository($this->repositoryID); - if ($repository->repositoryID != $this->repositoryID) { - echo 'Repository does not exist.'; - return; - } - - $cacheFile = $repository->getCacheFile(); - if (!file_exists($cacheFile)) { - echo 'Cache file does not exist.'; - return; - } - header('Content-type: application/xml'); - echo file_get_contents($repository->getCacheFile()); - } - - protected function downloadFile($packageName, $packageVersion) { - $fileVersionList = new FileVersionList(); - $fileVersionList->getConditionBuilder()->add('packageName = ? AND packageVersion = ?', [$packageName, $packageVersion]); - $fileVersionList->readObjects(); - - foreach ($fileVersionList as $fileVersion) { - if ($fileVersion->repositoryID != $this->repositoryID) { - echo 'File not found'; - return; - } - - $this->getFile($fileVersion); - return; - } - echo 'File not found'; - } - - protected function getFile($fileVersion) { - $this->authenticate($fileVersion); - - $location = $fileVersion->getLocation(); - if (!file_exists($location)) { - echo 'File not found'; - return; - } - header('Content-type: '.$fileVersion->fileType); - header('Content-disposition: attachment; filename="'.$fileVersion->filename.'"'); - echo file_get_contents($location); - - $editor = new FileEditor($fileVersion->getFile()); - $editor->updateCounters([ - 'downloads' => 1 - ]); - $editor = new FileVersionEditor($fileVersion); - $editor->updateCounters([ - 'downloads' => 1 - ]); - } - - protected function authenticate($fileVersion) { - if (!$fileVersion->canDownload() && !(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER["PHP_AUTH_PW"]))) { - $this->authHeader(); - } else if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER["PHP_AUTH_PW"])) { - try { - $user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($_SERVER['PHP_AUTH_USER'], $_SERVER["PHP_AUTH_PW"]); - } catch (UserInputException $e) { - if ($e->getField() == 'username') { - try { - $user = EmailUserAuthentication::getInstance()->loginManually($_SERVER['PHP_AUTH_USER'], $_SERVER["PHP_AUTH_PW"]); - } catch (UserInputException $e2) { - $this->authHeader(); - } - } else { - $this->authHeader(); - } - } - WCF::getSession()->changeUser($user); - if (!$fileVersion->canDownload()) { - $this->authHeader(); - } - } - } - - protected function authHeader() { - header('WWW-Authenticate: Basic realm="PackageServer"'); - header('HTTP/1.0 401 Unauthorized'); - echo 'Not authenticated.'; - exit; - } -} \ No newline at end of file +abstract class AbstractPackageAction extends AbstractAction +{ + public $repositoryID; + + public $repositoryName; + + public function readParameters() + { + parent::readParameters(); + } + + public function execute() + { + if (isset($_REQUEST['packageName']) && isset($_REQUEST['packageVersion'])) { + WCF::getSession()->changeUser(new User(null, ['username' => 'System', 'userID' => 0]), true); + $this->downloadFile($_REQUEST['packageName'], $_REQUEST['packageVersion']); + + return; + } + + $repository = new Repository($this->repositoryID); + if ($repository->repositoryID != $this->repositoryID) { + echo 'Repository does not exist.'; + + return; + } + + $cacheFile = $repository->getCacheFile(); + if (!\file_exists($cacheFile)) { + echo 'Cache file does not exist.'; + + return; + } + \header('Content-type: application/xml'); + echo \file_get_contents($repository->getCacheFile()); + } + + protected function downloadFile($packageName, $packageVersion) + { + $fileVersionList = new FileVersionList(); + $fileVersionList->getConditionBuilder()->add('packageName = ?', [$packageName]); + $fileVersionList->getConditionBuilder()->add('packageVersion = ?', [$packageVersion]); + $fileVersionList->readObjects(); + + foreach ($fileVersionList as $fileVersion) { + if ($fileVersion->repositoryID != $this->repositoryID) { + echo 'File not found'; + + return; + } + + $this->getFile($fileVersion); + + return; + } + echo 'File not found'; + } + + protected function getFile($fileVersion) + { + $this->authenticate($fileVersion); + + $location = $fileVersion->getLocation(); + if (!\file_exists($location)) { + echo 'File not found'; + + return; + } + \header('Content-type: ' . $fileVersion->fileType); + \header('Content-disposition: attachment; filename="' . $fileVersion->filename . '"'); + echo \file_get_contents($location); + + $editor = new FileEditor($fileVersion->getFile()); + $editor->updateCounters([ + 'downloads' => 1, + ]); + $editor = new FileVersionEditor($fileVersion); + $editor->updateCounters([ + 'downloads' => 1, + ]); + } + + protected function authenticate($fileVersion) + { + if (!$fileVersion->canDownload() && !(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER["PHP_AUTH_PW"]))) { + $this->authHeader(); + } elseif (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER["PHP_AUTH_PW"])) { + try { + $user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually( + $_SERVER['PHP_AUTH_USER'], + $_SERVER["PHP_AUTH_PW"] + ); + } catch (UserInputException $e) { + if ($e->getField() == 'username') { + try { + $user = EmailUserAuthentication::getInstance()->loginManually( + $_SERVER['PHP_AUTH_USER'], + $_SERVER["PHP_AUTH_PW"] + ); + } catch (UserInputException $e2) { + $this->authHeader(); + } + } else { + $this->authHeader(); + } + } + WCF::getSession()->changeUser($user); + if (!$fileVersion->canDownload()) { + $this->authHeader(); + } + } + } + + protected function authHeader() + { + \header('WWW-Authenticate: Basic realm="PackageServer"'); + \header('HTTP/1.0 401 Unauthorized'); + echo 'Not authenticated.'; + + exit; + } +} diff --git a/files/lib/data/repository/Repository.class.php b/files/lib/data/repository/Repository.class.php index b6d6d0f..6a8374f 100644 --- a/files/lib/data/repository/Repository.class.php +++ b/files/lib/data/repository/Repository.class.php @@ -1,29 +1,38 @@ name; - } - - public function canManage() { - return true; - } - - public function getLink() { - return LinkHandler::getInstance()->getLink(StringUtil::firstCharToUpperCase($this->name), ['forceFrontend' => true, 'application' => 'packages']); - } - - public function getCacheFile() { - return WCF_DIR.'cache/cache.packages_'.$this->name.'.xml'; - } -} \ No newline at end of file +class Repository extends DatabaseObject implements IRouteController +{ + protected static $databaseTableName = 'repository'; + + protected static $databaseTableIndexName = 'repositoryID'; + + public function getTitle(): string + { + return $this->name; + } + + public function canManage() + { + return true; + } + + public function getLink(): string + { + return LinkHandler::getInstance()->getLink( + StringUtil::firstCharToUpperCase($this->name), + ['forceFrontend' => true, 'application' => 'packages'] + ); + } + + public function getCacheFile() + { + return WCF_DIR . 'cache/cache.packages_' . $this->name . '.xml'; + } +} diff --git a/files/lib/data/repository/RepositoryAction.class.php b/files/lib/data/repository/RepositoryAction.class.php index c187b64..39a39f2 100644 --- a/files/lib/data/repository/RepositoryAction.class.php +++ b/files/lib/data/repository/RepositoryAction.class.php @@ -1,40 +1,45 @@ objects as $object) { - if(!$object->canManage()) { - throw new PermissionDeniedException(); - } - } - } - - public function create() { - $repository = parent::create(); - - $repositoryActionHandler = new RepositoryActionHandler($repository); - $repositoryActionHandler->create(); - return $repository; - } - - public function delete() { - parent::delete(); - - foreach ($this->objects as $object) { - $repositoryActionHandler = new RepositoryActionHandler($object->getDecoratedObject()); - $repositoryActionHandler->delete(); - } - } -} \ No newline at end of file + +class RepositoryAction extends AbstractDatabaseObjectAction +{ + protected $permissionsCreate = ['admin.packages.canManageRepository']; + + protected $permissionsDelete = ['admin.packages.canManageRepository']; + + public function validateDelete() + { + parent::validateDelete(); + + foreach ($this->objects as $object) { + if (!$object->canManage()) { + throw new PermissionDeniedException(); + } + } + } + + public function create() + { + $repository = parent::create(); + + $repositoryActionHandler = new RepositoryActionHandler($repository); + $repositoryActionHandler->create(); + + return $repository; + } + + public function delete() + { + parent::delete(); + + foreach ($this->objects as $object) { + $repositoryActionHandler = new RepositoryActionHandler($object->getDecoratedObject()); + $repositoryActionHandler->delete(); + } + } +} diff --git a/files/lib/data/repository/RepositoryEditor.class.php b/files/lib/data/repository/RepositoryEditor.class.php index 031c1f2..dda41d8 100644 --- a/files/lib/data/repository/RepositoryEditor.class.php +++ b/files/lib/data/repository/RepositoryEditor.class.php @@ -1,8 +1,10 @@ readObjects(); + + foreach ($repositoryList as $repository) { + $this->createRepositoryCache($repository); + } + } + + protected function createRepositoryCache(Repository $repository) + { + $categoryList = new CategoryList(); + $categoryList->getConditionBuilder()->add('repositoryID = ?', [$repository->repositoryID]); + $categoryList->getConditionBuilder()->add('isPackageServer = 1'); + $categoryList->readObjectIDs(); + + $xml = new RepositoryWriter($repository->getCacheFile()); + $xml->createSection(); + + $fileList = new ViewableFileList(); + $fileList->getConditionBuilder()->add('categoryID IN (?)', [\implode(',', $categoryList->objectIDs)]); + $fileList->readObjects(); + + $packageCounter = 0; + foreach ($fileList as $file) { + if ($file->getLastVersion()->filesize == 0) { + continue; + } + + $fileVersion = new FileVersion($file->lastVersionID); + $fileVersion->getFile(); + + $archive = new PackageArchive($fileVersion->getLocation()); + try { + $archive->openArchive(); + } catch (PackageValidationException $e) { + continue; + } + + $packageNameArr = $archive->getPackageInfo('packageName'); + $packageDescriptionArr = $archive->getPackageInfo('packageDescription'); + + $name = $archive->getPackageInfo('name'); + $packageName = $packageNameArr['default']; + $packageDescription = ''; + if (isset($packageDescriptionArr['default'])) { + $packageDescription = $packageDescriptionArr['default']; + } + $author = $archive->getAuthorInfo('author'); + $authorUrl = $archive->getAuthorInfo('authorURL'); + $isApplication = $archive->getPackageInfo('isApplication'); + $license = ($file->isCommercial == 1) ? 'commercial' : 'free'; + + $fileVersionList = new FileVersionList(); + $fileVersionList->getConditionBuilder()->add('fileID = ?', [$file->fileID]); + $fileVersionList->readObjects(); + + $versions = []; + foreach ($fileVersionList as $fileVersion) { + $archive = new PackageArchive($fileVersion->getLocation()); + try { + $archive->openArchive(); + } catch (PackageValidationException $e) { + continue; + } + + $versions[] = [ + 'version' => $archive->getPackageInfo('version'), + 'timestamp' => $fileVersion->uploadTime, + 'updateType' => ($archive->getInstructions('update') == null) ? 'install' : 'update', + 'requiredPackages' => $archive->getRequirements(), + 'excludedPackages' => $archive->getExcludedPackages(), + 'instructions' => $archive->getInstructions('update'), + 'requireAuth' => ($fileVersion->canDownload()) ? 'false' : 'true', + ]; + + $objectAction = new FileVersionAction([$fileVersion], 'update', ['data' => [ + 'packageName' => $archive->getPackageInfo('name'), + 'packageVersion' => $archive->getPackageInfo('version'), + 'repositoryID' => $repository->repositoryID, + ]]); + $objectAction->executeAction(); + } + + $xml->createPackage( + $name, + $packageName, + $packageDescription, + $author, + $authorUrl, + $versions, + $isApplication, + $license + ); + + $packageCounter++; + } + $objectAction = new RepositoryAction([$repository], 'update', ['data' => [ + 'packesCount' => $packageCounter, + 'lastUpdateTime' => \time(), + ]]); + $objectAction->executeAction(); -class PackageServerUpdateCronjob extends AbstractCronjob { - public function execute(Cronjob $cronjob) { - parent::execute($cronjob); - - $repositoryList = new RepositoryList(); - $repositoryList->readObjects(); - - foreach ($repositoryList as $repository) { - $this->createRepositoryCache($repository); - } - } - - protected function createRepositoryCache(Repository $repository) { - $categoryList = new CategoryList(); - $categoryList->getConditionBuilder()->add('repositoryID = ? AND isPackageServer = 1', [$repository->repositoryID]); - $categoryList->readObjectIDs(); - - $xml = new RepositoryWriter($repository->getCacheFile()); - $xml->createSection(); - - $fileList = new ViewableFileList(); - $fileList->getConditionBuilder()->add('categoryID IN (?)', [implode(',', $categoryList->objectIDs)]); - $fileList->readObjects(); - - $packageCounter = 0; - foreach ($fileList as $file) { - if ($file->getLastVersion()->filesize == 0) { - continue; - } - - $fileVersion = new FileVersion($file->lastVersionID); - $fileVersion->getFile(); - - $archive = new PackageArchive($fileVersion->getLocation()); - try { - $archive->openArchive(); - } catch (PackageValidationException $e) { - continue; - } - - $packageNameArr = $archive->getPackageInfo('packageName'); - $packageDescriptionArr = $archive->getPackageInfo('packageDescription'); - - $name = $archive->getPackageInfo('name'); - $packageName = $packageNameArr['default']; - $packageDescription = ''; - if (isset($packageDescriptionArr['default'])) - $packageDescription = $packageDescriptionArr['default']; - $author = $archive->getAuthorInfo('author'); - $authorUrl = $archive->getAuthorInfo('authorURL'); - $isApplication = $archive->getPackageInfo('isApplication'); - $license = ($file->isCommercial == 1) ? 'commercial' : 'free'; - - $fileVersionList = new FileVersionList(); - $fileVersionList->getConditionBuilder()->add('fileID = ?', [$file->fileID]); - $fileVersionList->readObjects(); - - $versions = []; - foreach ($fileVersionList as $fileVersion) { - $archive = new PackageArchive($fileVersion->getLocation()); - try { - $archive->openArchive(); - } catch (PackageValidationException $e) { - continue; - } - - $versions[] = [ - 'version' => $archive->getPackageInfo('version'), - 'timestamp' => $fileVersion->uploadTime, - 'updateType' => ($archive->getInstructions('update') == null) ? 'install' : 'update', - 'requiredPackages' => $archive->getRequirements(), - 'excludedPackages' => $archive->getExcludedPackages(), - 'instructions' => $archive->getInstructions('update'), - 'requireAuth' => ($fileVersion->canDownload()) ? 'false' : 'true' - ]; - - $objectAction = new FileVersionAction([$fileVersion], 'update', ['data' => [ - 'packageName' => $archive->getPackageInfo('name'), - 'packageVersion' => $archive->getPackageInfo('version'), - 'repositoryID' => $repository->repositoryID - ]]); - $objectAction->executeAction(); - } - - $xml->createPackage( - $name, - $packageName, - $packageDescription, - $author, - $authorUrl, - $versions, - $isApplication, - $license - ); - - $packageCounter++; - } - $objectAction = new RepositoryAction([$repository], 'update', ['data' => [ - 'packesCount' => $packageCounter, - 'lastUpdateTime' => time() - ]]); - $objectAction->executeAction(); - - $xml->save(); - } + $xml->save(); + } } diff --git a/files/lib/system/event/listener/FilebaseCategoryEditFormListener.class.php b/files/lib/system/event/listener/FilebaseCategoryEditFormListener.class.php index 33b6265..7e8a508 100644 --- a/files/lib/system/event/listener/FilebaseCategoryEditFormListener.class.php +++ b/files/lib/system/event/listener/FilebaseCategoryEditFormListener.class.php @@ -1,63 +1,69 @@ packageServer = $_POST['values']['packageServer']; - if (isset($_POST['repository'])) - $this->repository = $_POST['repository']; - } else if ($eventName == 'validate') { - if ($this->packageServer == 1) { - if (empty($this->repository)) { - throw new UserInputException('repository', 'empty'); - } - - $repositoryList = new RepositoryList(); - $repositoryList->getConditionBuilder()->add('repositoryID = ?', [$this->repository]); - $repositoryList->readObjects(); - - if (count($repositoryList) == 0) { - throw new UserInputException('repository', 'notExist'); - } - } - } else if ($eventName == 'save') { - if ($this->packageServer == 1) { - $eventObj->additionalFields = array_merge($eventObj->additionalFields, [ - 'isPackageServer' => $this->packageServer, - 'repositoryID' => $this->repository - ]); - } else if ($this->packageServer == 0) { - $eventObj->additionalFields = array_merge($eventObj->additionalFields, [ - 'isPackageServer' => $this->packageServer, - 'repositoryID' => null - ]); - } - } else if ($eventName == 'assignVariables') { - if (empty($_POST) && $eventObj instanceof CategoryEditForm) { - $this->packageServer = $eventObj->category->isPackageServer; - $this->repository = $eventObj->category->repositoryID; - } - - $repositoryList = new RepositoryList(); - $repositoryList->readObjects(); - - WCF::getTPL()->assign([ - 'packagesFilebaseAdd' => true, - 'repositoryList' => $repositoryList, - 'packageServer' => $this->packageServer, - 'repositoryID' => $this->repository - ]); - } - } +class FilebaseCategoryEditFormListener implements IParameterizedEventListener +{ + protected $packageServer; + + protected $repository; + + public function execute($eventObj, $className, $eventName, array &$parameters) + { + if ($eventName == 'readFormParameters') { + if (isset($_POST['values']['packageServer'])) { + $this->packageServer = $_POST['values']['packageServer']; + } + if (isset($_POST['repository'])) { + $this->repository = $_POST['repository']; + } + } elseif ($eventName == 'validate') { + if ($this->packageServer == 1) { + if (empty($this->repository)) { + throw new UserInputException('repository', 'empty'); + } + + $repositoryList = new RepositoryList(); + $repositoryList->getConditionBuilder()->add('repositoryID = ?', [$this->repository]); + $repositoryList->readObjects(); + + if (\count($repositoryList) == 0) { + throw new UserInputException('repository', 'notExist'); + } + } + } elseif ($eventName == 'save') { + if ($this->packageServer == 1) { + $eventObj->additionalFields = \array_merge($eventObj->additionalFields, [ + 'isPackageServer' => $this->packageServer, + 'repositoryID' => $this->repository, + ]); + } elseif ($this->packageServer == 0) { + $eventObj->additionalFields = \array_merge($eventObj->additionalFields, [ + 'isPackageServer' => $this->packageServer, + 'repositoryID' => null, + ]); + } + } elseif ($eventName == 'assignVariables') { + if (empty($_POST) && $eventObj instanceof CategoryEditForm) { + $this->packageServer = $eventObj->category->isPackageServer; + $this->repository = $eventObj->category->repositoryID; + } + + $repositoryList = new RepositoryList(); + $repositoryList->readObjects(); + + WCF::getTPL()->assign([ + 'packagesFilebaseAdd' => true, + 'repositoryList' => $repositoryList, + 'packageServer' => $this->packageServer, + 'repositoryID' => $this->repository, + ]); + } + } } diff --git a/files/lib/system/repository/RepositoryActionHandler.class.php b/files/lib/system/repository/RepositoryActionHandler.class.php index 365bb79..e3c3ff7 100644 --- a/files/lib/system/repository/RepositoryActionHandler.class.php +++ b/files/lib/system/repository/RepositoryActionHandler.class.php @@ -1,34 +1,41 @@ repository = $repository; - } - - public function create() { - $templatePath = PACKAGES_DIR.'lib/action/PackageAction.class.template'; - $template = file_get_contents($templatePath); - - $className = StringUtil::firstCharToUpperCase($this->repository->name); - $template = str_replace('{className}', $className, $template); - $template = str_replace('{repositoryID}', $this->repository->repositoryID, $template); - $template = str_replace('{repositoryName}', $this->repository->name, $template); - - $classPathName = PACKAGES_DIR.'lib/action/'.$className.'Action.class.php'; - - file_put_contents($classPathName, $template); - } - - public function delete() { - $className = StringUtil::firstCharToUpperCase($this->repository->name); - $classPathName = PACKAGES_DIR.'lib/action/'.$className.'Action.class.php'; - - if (file_exists($classPathName)) - unlink($classPathName); - } +class RepositoryActionHandler +{ + protected $repository; + + public function __construct(Repository $repository) + { + $this->repository = $repository; + } + + public function create() + { + $templatePath = PACKAGES_DIR . 'lib/action/PackageAction.class.template'; + $template = \file_get_contents($templatePath); + + $className = StringUtil::firstCharToUpperCase($this->repository->name); + $template = \str_replace('{className}', $className, $template); + $template = \str_replace('{repositoryID}', $this->repository->repositoryID, $template); + $template = \str_replace('{repositoryName}', $this->repository->name, $template); + + $classPathName = PACKAGES_DIR . 'lib/action/' . $className . 'Action.class.php'; + + \file_put_contents($classPathName, $template); + } + + public function delete() + { + $className = StringUtil::firstCharToUpperCase($this->repository->name); + $classPathName = PACKAGES_DIR . 'lib/action/' . $className . 'Action.class.php'; + + if (\file_exists($classPathName)) { + \unlink($classPathName); + } + } } diff --git a/files/lib/system/repository/RepositoryWriter.class.php b/files/lib/system/repository/RepositoryWriter.class.php index a62ffd7..701d0c7 100644 --- a/files/lib/system/repository/RepositoryWriter.class.php +++ b/files/lib/system/repository/RepositoryWriter.class.php @@ -1,154 +1,199 @@ outputFile = $outputFile; - } - - public function createSection() { - $this->section = $this->document->createElement('section'); - $this->section->appendChild($this->createSimpleAttribute('xmlns', 'http://www.woltlab.com')); - $this->section->appendChild($this->createSimpleAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')); - $this->section->appendChild($this->createSimpleAttribute('name', 'packages')); - $this->section->appendChild($this->createSimpleAttribute('xsi:schemaLocation', 'http://www.woltlab.com https://www.woltlab.com/XSD/tornado/packageUpdateServer.xsd')); - } - - public function createPackage($name, $packageName, $packageDescription, $authorName, $authorURL, $versions, $isApplication, $license) { - $package = $this->document->createElement('package'); - $package->appendChild($this->createSimpleAttribute('name', $name)); - - $package->appendChild($this->createPackageInformation($packageName, $packageDescription, $isApplication)); - $package->appendChild($this->createAuthorInformation($authorName, $authorURL)); - $package->appendChild($this->createVersions($versions, $license)); - - $this->packages[] = $package; - } - - protected function createPackageInformation($packageName, $packageDescription, $isApplication) { - $packageinformation = $this->document->createElement('packageinformation'); - - $packageinformation->appendChild($this->createCDATAElement('packagename', $packageName)); - $packageinformation->appendChild($this->createCDATAElement('packagedescription', $packageDescription)); - if ($isApplication == 1) - $packageinformation->appendChild($this->document->createElement('isapplication', 1)); - - return $packageinformation; - } - - protected function createAuthorInformation($authorName, $authorURL) { - $authorinformation = $this->document->createElement('authorinformation'); - - $authorinformation->appendChild($this->createCDATAElement('author', $authorName)); - $authorinformation->appendChild($this->createCDATAElement('authorurl', $authorURL)); - - return $authorinformation; - } - - protected function createVersions($versions, $license) { - $versionsNode = $this->document->createElement('versions'); - - foreach ($versions as $version) { - $versionsNode->appendChild($this->createVersion($version['version'], $version['timestamp'], $version['updateType'], $version['requiredPackages'], $version['excludedPackages'], $version['instructions'], $license, $version['requireAuth'])); - } - - return $versionsNode; - } - - protected function createVersion($versionNr, $versionTime, $updateType, $requiredPackages, $excludedPackages, $updateInstructions, $license, $requireAuth) { - $version = $this->document->createElement('version'); - - $version->appendChild($this->createSimpleAttribute('name', $versionNr)); - $version->appendChild($this->createSimpleAttribute('accessible', 'true')); - $version->appendChild($this->createSimpleAttribute('requireAuth', $requireAuth)); - if ($updateInstructions != null) - { - $version->appendChild($this->createFromVersions($updateInstructions)); - } - if (count($requiredPackages) > 0) - { - $version->appendChild($this->createRequiredPackages($requiredPackages)); - } - if (count($excludedPackages) > 0) - { - $version->appendChild($this->createExcludedPackages($excludedPackages)); - } - $version->appendChild($this->createCDATAElement('updatetype', $updateType)); - $version->appendChild($this->createCDATAElement('timestamp', $versionTime)); - $version->appendChild($this->createCDATAElement('license', $license)); - - return $version; - } - - protected function createFromVersions($updateInstructions) { - $fromversions = $this->document->createElement('fromversions'); - - foreach($updateInstructions as $version => $updateInstruction) - { - $fromversion = $this->createCDATAElement('fromversion', $version); - - $fromversions->appendChild($fromversion); - } - - return $fromversions; - } - - protected function createRequiredPackages($requiredPackages) { - $requiredpackages = $this->document->createElement('requiredpackages'); - - foreach($requiredPackages as $name => $requiredPackage) - { - $requiredpackage = $this->createCDATAElement('requiredpackage', $requiredPackage['name']); - $requiredpackage->appendChild($this->createSimpleAttribute('minversion', $requiredPackage['minversion'])); - $requiredpackages->appendChild($requiredpackage); - } - - return $requiredpackages; - } - - protected function createExcludedPackages($excludedPackages) { - $excludedpackages = $this->document->createElement('excludedpackages'); - - foreach($excludedPackages as $excludedPackage) - { - $excludedpackage = $this->createCDATAElement('excludedpackage', $excludedPackage['name']); - $excludedpackage->appendChild($this->createSimpleAttribute('version', $excludedPackage['version'])); - $excludedpackages->appendChild($excludedpackage); - } - - return $excludedpackages; - } - - public function save() { - foreach ($this->packages as $package) { - $this->section->appendChild($package); - } - - $this->document->appendChild($this->section); - $this->document->formatOutput = true; - $this->document->save($this->outputFile); - } - - protected function createSimpleAttribute($name, $value) - { - $attr = $this->document->createAttribute($name); - $attr->value = $value; - return $attr; - } - - protected function createCDATAElement($name, $value) - { - $element = $this->document->createElement($name); - $element->appendChild($this->document->createCDATASection($value)); - return $element; - } +class RepositoryWriter extends XML +{ + protected $outputFile; + + protected $section; + + protected $packages = []; + + public function __construct($outputFile) + { + parent::__construct(); + + $this->outputFile = $outputFile; + } + + public function createSection() + { + $this->section = $this->document->createElement('section'); + $this->section->appendChild($this->createSimpleAttribute('xmlns', 'http://www.woltlab.com')); + $this->section->appendChild( + $this->createSimpleAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance') + ); + $this->section->appendChild($this->createSimpleAttribute('name', 'packages')); + $this->section->appendChild( + $this->createSimpleAttribute( + 'xsi:schemaLocation', + 'http://www.woltlab.com http://www.woltlab.com/XSD/6.0/packageUpdateServer.xsd' + ) + ); + } + + public function createPackage( + $name, + $packageName, + $packageDescription, + $authorName, + $authorURL, + $versions, + $isApplication, + $license + ) { + $package = $this->document->createElement('package'); + $package->appendChild($this->createSimpleAttribute('name', $name)); + + $package->appendChild($this->createPackageInformation($packageName, $packageDescription, $isApplication)); + $package->appendChild($this->createAuthorInformation($authorName, $authorURL)); + $package->appendChild($this->createVersions($versions, $license)); + + $this->packages[] = $package; + } + + protected function createPackageInformation($packageName, $packageDescription, $isApplication) + { + $packageinformation = $this->document->createElement('packageinformation'); + + $packageinformation->appendChild($this->createCDATAElement('packagename', $packageName)); + $packageinformation->appendChild($this->createCDATAElement('packagedescription', $packageDescription)); + if ($isApplication == 1) { + $packageinformation->appendChild($this->document->createElement('isapplication', 1)); + } + + return $packageinformation; + } + + protected function createAuthorInformation($authorName, $authorURL) + { + $authorinformation = $this->document->createElement('authorinformation'); + + $authorinformation->appendChild($this->createCDATAElement('author', $authorName)); + $authorinformation->appendChild($this->createCDATAElement('authorurl', $authorURL)); + + return $authorinformation; + } + + protected function createVersions($versions, $license) + { + $versionsNode = $this->document->createElement('versions'); + + foreach ($versions as $version) { + $versionsNode->appendChild( + $this->createVersion( + $version['version'], + $version['timestamp'], + $version['updateType'], + $version['requiredPackages'], + $version['excludedPackages'], + $version['instructions'], + $license, + $version['requireAuth'] + ) + ); + } + + return $versionsNode; + } + + protected function createVersion( + $versionNr, + $versionTime, + $updateType, + $requiredPackages, + $excludedPackages, + $updateInstructions, + $license, + $requireAuth + ) { + $version = $this->document->createElement('version'); + + $version->appendChild($this->createSimpleAttribute('name', $versionNr)); + $version->appendChild($this->createSimpleAttribute('accessible', 'true')); + $version->appendChild($this->createSimpleAttribute('requireAuth', $requireAuth)); + if ($updateInstructions != null) { + $version->appendChild($this->createFromVersions($updateInstructions)); + } + if (\count($requiredPackages) > 0) { + $version->appendChild($this->createRequiredPackages($requiredPackages)); + } + if (\count($excludedPackages) > 0) { + $version->appendChild($this->createExcludedPackages($excludedPackages)); + } + $version->appendChild($this->createCDATAElement('updatetype', $updateType)); + $version->appendChild($this->createCDATAElement('timestamp', $versionTime)); + $version->appendChild($this->createCDATAElement('license', $license)); + + return $version; + } + + protected function createFromVersions($updateInstructions) + { + $fromversions = $this->document->createElement('fromversions'); + + foreach ($updateInstructions as $version => $updateInstruction) { + $fromversion = $this->createCDATAElement('fromversion', $version); + + $fromversions->appendChild($fromversion); + } + + return $fromversions; + } + + protected function createRequiredPackages($requiredPackages) + { + $requiredpackages = $this->document->createElement('requiredpackages'); + + foreach ($requiredPackages as $name => $requiredPackage) { + $requiredpackage = $this->createCDATAElement('requiredpackage', $requiredPackage['name']); + $requiredpackage->appendChild($this->createSimpleAttribute('minversion', $requiredPackage['minversion'])); + $requiredpackages->appendChild($requiredpackage); + } + + return $requiredpackages; + } + + protected function createExcludedPackages($excludedPackages) + { + $excludedpackages = $this->document->createElement('excludedpackages'); + + foreach ($excludedPackages as $excludedPackage) { + $excludedpackage = $this->createCDATAElement('excludedpackage', $excludedPackage['name']); + $excludedpackage->appendChild($this->createSimpleAttribute('version', $excludedPackage['version'])); + $excludedpackages->appendChild($excludedpackage); + } + + return $excludedpackages; + } + + public function save() + { + foreach ($this->packages as $package) { + $this->section->appendChild($package); + } + + $this->document->appendChild($this->section); + $this->document->formatOutput = true; + $this->document->save($this->outputFile); + } + + protected function createSimpleAttribute($name, $value) + { + $attr = $this->document->createAttribute($name); + $attr->value = $value; + + return $attr; + } + + protected function createCDATAElement($name, $value) + { + $element = $this->document->createElement($name); + $element->appendChild($this->document->createCDATASection($value)); + + return $element; + } } diff --git a/install.sql b/install.sql deleted file mode 100644 index fa322a6..0000000 --- a/install.sql +++ /dev/null @@ -1,15 +0,0 @@ -ALTER TABLE wcf1_category ADD isPackageServer TINYINT(1) NOT NULL DEFAULT 0; -ALTER TABLE wcf1_category ADD repositoryID INT(10); -ALTER TABLE filebase1_file_version ADD packageName VARCHAR(100); -ALTER TABLE filebase1_file_version ADD packageVersion VARCHAR(80); -ALTER TABLE filebase1_file_version ADD repositoryID INT(10); - -DROP TABLE IF EXISTS packages1_repository; -CREATE TABLE packages1_repository ( - repositoryID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(20) NOT NULL, - packesCount INT(10) NOT NULL DEFAULT 0, - lastUpdateTime INT(10) -); -ALTER TABLE wcf1_category ADD FOREIGN KEY (repositoryID) REFERENCES packages1_repository (repositoryID) ON DELETE SET NULL; -ALTER TABLE filebase1_file_version ADD FOREIGN KEY (repositoryID) REFERENCES packages1_repository (repositoryID) ON DELETE SET NULL; diff --git a/language/de.xml b/language/de.xml index e4fcd0e..f157c95 100644 --- a/language/de.xml +++ b/language/de.xml @@ -1,45 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/make.bat b/make.bat deleted file mode 100644 index f0e2ef4..0000000 --- a/make.bat +++ /dev/null @@ -1,9 +0,0 @@ -@ECHO OFF -del acptemplates.tar -7z a -ttar -mx=9 acptemplates.tar .\acptemplates\* -del files.tar -7z a -ttar -mx=9 files.tar .\files\* -del templates.tar -7z a -ttar -mx=9 templates.tar .\templates\* -del eu.hanashi.packages.tar -7z a -ttar -mx=9 eu.hanashi.packages.tar .\* -x!acptemplates -x!files -x!templates -x!eu.hanashi.packages.tar -x!.git -x!.gitignore -x!make.bat -x!make.sh \ No newline at end of file diff --git a/make.sh b/make.sh deleted file mode 100755 index 205d578..0000000 --- a/make.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -rm -rf acptemplates.tar -7z a -ttar -mx=9 acptemplates.tar ./acptemplates/* -rm -rf files.tar -7z a -ttar -mx=9 files.tar ./files/* -# rm -rf templates.tar -# 7z a -ttar -mx=9 templates.tar ./templates/* -rm -rf eu.hanashi.packages.tar -7z a -ttar -mx=9 eu.hanashi.packages.tar ./* -x!acptemplates -x!files -x!templates -x!eu.hanashi.packages.tar -x!.git -x!.gitignore -x!make.bat -x!make.sh \ No newline at end of file diff --git a/package.xml b/package.xml index f44f471..51f5f5b 100644 --- a/package.xml +++ b/package.xml @@ -1,50 +1,34 @@ - - - - + + + + Package server + Ein kleiner Paketserver der auf die Filebase von WoltLab aufbaut. 1 - 1.0.0 Alpha 6 - 2019-12-10 - - - - - - - - - - - - - - com.woltlab.wcf - com.woltlab.filebase - - - - - - - - - - - - - - - - - - - - - - - - - + 1.1.0 + 2023-10-21 + + + Hanashi Development + https://hanashi.dev/ + + + com.woltlab.wcf + com.woltlab.filebase + + + com.woltlab.wcf + com.woltlab.filebase + + + + + + + + + + + acp/database/install_dev.hanashi.packages.php diff --git a/templateListener.xml b/templateListener.xml index bde0f2e..eb0d306 100644 --- a/templateListener.xml +++ b/templateListener.xml @@ -1,5 +1,5 @@ - + @@ -10,4 +10,4 @@ - \ No newline at end of file + diff --git a/userGroupOption.xml b/userGroupOption.xml index 66bbda6..35f09b6 100644 --- a/userGroupOption.xml +++ b/userGroupOption.xml @@ -1,5 +1,5 @@ - + @@ -7,7 +7,7 @@ - - \ No newline at end of file +
- + {objectAction action="delete" objectTitle=$object->name} {event name='rowButtons'} {#$object->repositoryID}