From 84d2e7448756004614df462942d76c87afe66cab Mon Sep 17 00:00:00 2001 From: Jean-Christian Denis Date: Sun, 26 Mar 2023 15:37:32 +0200 Subject: [PATCH] use namespace --- _init.php | 1 + src/Backend.php | 72 ++++++--- src/Frontend.php | 97 ++++-------- src/FrontendTemplate.php | 29 ++++ src/Install.php | 69 +++++---- src/Manage.php | 325 ++++++++++++++++++++++++--------------- src/My.php | 45 ++++++ src/PallazzoTools.php | 9 +- src/Prepend.php | 48 ++++-- src/UrlHandler.php | 83 ++++++++++ src/Utils.php | 105 ++++++------- 11 files changed, 564 insertions(+), 319 deletions(-) create mode 100644 src/FrontendTemplate.php create mode 100644 src/My.php create mode 100644 src/UrlHandler.php diff --git a/_init.php b/_init.php index f7ee15e..fb705b0 100644 --- a/_init.php +++ b/_init.php @@ -16,5 +16,6 @@ if (!defined('DC_RC_PATH')) { class initFilesAlias { + /** @var string This plugin table name */ public const ALIAS_TABLE_NAME = 'filesalias'; } diff --git a/src/Backend.php b/src/Backend.php index 3ab44c7..22417d2 100644 --- a/src/Backend.php +++ b/src/Backend.php @@ -10,27 +10,53 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; +declare(strict_types=1); + +namespace Dotclear\Plugin\filesAlias; + +use dcAdmin; +use dcAuth; +use dcCore; +use dcFavorites; +use dcNsProcess; +use dcPage; + +class Backend extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN'); + + return static::$init; + } + + public static function process(): bool + { + if (!static::$init) { + return false; + } + + dcCore::app()->menu[dcAdmin::MENU_BLOG]->addItem( + My::name(), + dcCore::app()->adminurl->get('admin.plugin.' . My::id()), + dcPage::getPF(My::id() . '/icon.svg'), + preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/', $_SERVER['REQUEST_URI']), + dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_CONTENT_ADMIN]), dcCore::app()->blog->id) + ); + + dcCore::app()->addBehavior('adminDashboardFavoritesV2', function (dcFavorites $favs): void { + $favs->register(My::id(), [ + 'title' => My::name(), + 'url' => dcCore::app()->adminurl->get('admin.plugin.' . My::id()), + 'small-icon' => dcPage::getPF(My::id() . '/icon.svg'), + 'large-icon' => dcPage::getPF(My::id() . '/icon.svg'), + 'permissions' => dcCore::app()->auth->makePermissions([ + dcAuth::PERMISSION_USAGE, + dcAuth::PERMISSION_CONTENT_ADMIN, + ]), + ]); + }); + + return true; + } } - -dcCore::app()->menu[dcAdmin::MENU_BLOG]->addItem( - __('Media sharing'), - dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)), - urldecode(dcPage::getPF(basename(__DIR__) . '/icon.svg')), - preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/', $_SERVER['REQUEST_URI']), - dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_CONTENT_ADMIN]), dcCore::app()->blog->id) -); - -dcCore::app()->addBehavior('adminDashboardFavoritesV2', function (dcFavorites $favs) { - $favs->register('filesAlias', [ - 'title' => __('Media sharing'), - 'url' => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)), - 'small-icon' => dcPage::getPF(basename(__DIR__) . '/icon.svg'), - 'large-icon' => dcPage::getPF(basename(__DIR__) . '/icon.svg'), - 'permissions' => dcCore::app()->auth->makePermissions([ - dcAuth::PERMISSION_USAGE, - dcAuth::PERMISSION_CONTENT_ADMIN, - ]), - ]); -}); diff --git a/src/Frontend.php b/src/Frontend.php index bd4961a..c577b46 100644 --- a/src/Frontend.php +++ b/src/Frontend.php @@ -10,80 +10,37 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_RC_PATH')) { - return null; -} +declare(strict_types=1); -dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), __DIR__ . '/default-templates'); -dcCore::app()->tpl->addValue('fileAliasURL', ['templateAlias','fileAliasURL']); +namespace Dotclear\Plugin\filesAlias; -class templateAlias +use dcCore; +use dcNsProcess; + +class Frontend extends dcNsProcess { - public static function fileAliasURL($attr) + public static function init(): bool { - $f = dcCore::app()->tpl->getFilters($attr); + static::$init = defined('DC_RC_PATH'); - return 'blog->url.dcCore::app()->url->getBase("filesalias")."/".dcCore::app()->ctx->filealias->filesalias_url') . '; ?>'; - } -} - -class urlFilesAlias extends dcUrlHandlers -{ - public static function alias($args) - { - $delete = false; - - dcCore::app()->ctx->__set('filealias', dcCore::app()->__get('filealias')->getAlias($args)); - - if (dcCore::app()->ctx->__get('filealias')->isEmpty()) { - self::p404(); - } - - if (dcCore::app()->ctx->__get('filealias')->filesalias_disposable) { - $delete = true; - } - - if (dcCore::app()->ctx->__get('filealias')->filesalias_password) { - # Check for match - if (!empty($_POST['filepassword']) && $_POST['filepassword'] == dcCore::app()->ctx->__get('filealias')->filesalias_password) { - self::servefile(dcCore::app()->ctx->__get('filealias')->filesalias_destination, $args, $delete); - } else { - self::serveDocument('file-password-form.html', 'text/html', false); - - return; - } - } else { - self::servefile(dcCore::app()->ctx->__get('filealias')->filesalias_destination, $args, $delete); - } - } - - public static function servefile($target, $alias, $delete = false) - { - $a = new aliasMedia(); - $media = $a->getMediaId($target); - - if (empty($media)) { - self::p404(); - } - - $file = dcCore::app()->media->getFile($media); - - if (empty($file->file)) { - self::p404(); - } - - header('Content-type: ' . $file->type); - header('Content-Length: ' . $file->size); - header('Content-Disposition: attachment; filename="' . $file->basename . '"'); - - if (ob_get_length() > 0) { - ob_end_clean(); - } - flush(); - - readfile($file->file); - if ($delete) { - dcCore::app()->__get('filealias')->deleteAlias($alias); - } + return static::$init; + } + + public static function process(): bool + { + if (!static::$init) { + return false; + } + + dcCore::app()->tpl->setPath( + dcCore::app()->tpl->getPath(), + My::path() . DIRECTORY_SEPARATOR . 'default-templates' + ); + dcCore::app()->tpl->addValue( + 'fileAliasURL', + [FrontendTemplate::class, 'fileAliasURL'] + ); + + return true; } } diff --git a/src/FrontendTemplate.php b/src/FrontendTemplate.php new file mode 100644 index 0000000..4b5afb4 --- /dev/null +++ b/src/FrontendTemplate.php @@ -0,0 +1,29 @@ +tpl->getFilters($attr), + 'dcCore::app()->blog->url.dcCore::app()->url->getBase("filesalias")."/".dcCore::app()->ctx->filealias->filesalias_url' + ) . '; ?>'; + } +} diff --git a/src/Install.php b/src/Install.php index 1edc6a0..c8b6aad 100644 --- a/src/Install.php +++ b/src/Install.php @@ -10,38 +10,53 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -try { - if (!dcCore::app()->newVersion( - basename(__DIR__), - dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version') - )) { - return null; +namespace Dotclear\Plugin\filesAlias; + +use dbStruct; +use dcCore; +use dcNsProcess; +use Exception; + +class Install extends dcNsProcess +{ + public static function init(): bool + { + self::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version')); + + return self::$init; } - $s = new dbStruct(dcCore::app()->con, dcCore::app()->prefix); + public static function process(): bool + { + if (!self::$init) { + return false; + } - $s->{initFilesAlias::ALIAS_TABLE_NAME} - ->blog_id('varchar', 32, false) - ->filesalias_url('varchar', 255, false) - ->filesalias_destination('varchar', 255, false) - ->filesalias_password('varchar', 32, true, null) - ->filesalias_disposable('smallint', 0, false, 0) + try { + $s = new dbStruct(dcCore::app()->con, dcCore::app()->prefix); - ->primary('pk_filesalias', 'blog_id', 'filesalias_url') - ->index('idx_filesalias_blog_id', 'btree', 'blog_id') - ->reference('fk_filesalias_blog', 'blog_id', 'blog', 'blog_id', 'cascade', 'cascade') - ; + $s->{My::ALIAS_TABLE_NAME} + ->blog_id('varchar', 32, false) + ->filesalias_url('varchar', 255, false) + ->filesalias_destination('varchar', 255, false) + ->filesalias_password('varchar', 32, true, null) + ->filesalias_disposable('smallint', 0, false, 0) - $si = new dbStruct(dcCore::app()->con, dcCore::app()->prefix); - $changes = $si->synchronize($s); + ->primary('pk_filesalias', 'blog_id', 'filesalias_url') + ->index('idx_filesalias_blog_id', 'btree', 'blog_id') + ->reference('fk_filesalias_blog', 'blog_id', 'blog', 'blog_id', 'cascade', 'cascade') + ; - return true; -} catch (Exception $e) { - dcCore::app()->error->add($e->getMessage()); + $si = new dbStruct(dcCore::app()->con, dcCore::app()->prefix); + $changes = $si->synchronize($s); + + return true; + } catch (Exception $e) { + dcCore::app()->error->add($e->getMessage()); + } + + return true; + } } - -return false; diff --git a/src/Manage.php b/src/Manage.php index e8b4b63..0f22c48 100644 --- a/src/Manage.php +++ b/src/Manage.php @@ -10,150 +10,231 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -$o = dcCore::app()->__get('filealias'); -$aliases = $o->getAliases(); -$media = new dcMedia(); -$a = new aliasMedia(); -$part = $_REQUEST['part'] ?? 'list'; +namespace Dotclear\Plugin\filesAlias; -# Update aliases -if (isset($_POST['a']) && is_array($_POST['a'])) { - try { - $o->updateAliases($_POST['a']); - dcAdminNotices::addSuccessNotice(__('Aliases successfully updated.')); - dcCore::app()->adminurl->redirect('admin.plugin.' . basename(__DIR__)); - } catch (Exception $e) { - dcCore::app()->error->add($e->getMessage()); +use dcAuth; +use dcCore; +use dcMedia; +use dcNsProcess; +use dcPage; +use Dotclear\Helper\Html\Html; +use Dotclear\Helper\Html\Form\{ + Checkbox, + Form, + Hidden, + Input, + Label, + Note, + Para, + Submit, + Text +}; +use Exception; + +class Manage extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->auth->check( + dcCore::app()->auth->makePermissions([ + dcAuth::PERMISSION_ADMIN, + ]), + dcCore::app()->blog->id + ); + + return static::$init; } -} -# New alias -if (isset($_POST['filesalias_url'])) { - $url = empty($_POST['filesalias_url']) ? PallazzoTools::rand_uniqid() : $_POST['filesalias_url']; + public static function process(): bool + { + if (!static::$init) { + return false; + } - $target = $_POST['filesalias_destination']; - $totrash = isset($_POST['filesalias_disposable']) ? true : false; - $password = empty($_POST['filesalias_password']) ? '' : $_POST['filesalias_password']; + if (!(dcCore::app()->media instanceof dcMedia)) { + dcCore::app()->media = new dcMedia(); + } - if (preg_match('/^' . preg_quote($media->root_url, '/') . '/', $target)) { - $target = preg_replace('/^' . preg_quote($media->root_url, '/') . '/', '', $target); - $found = $a->getMediaId($target); - - if (!empty($found)) { + # Update aliases + if (isset($_POST['a']) && is_array($_POST['a'])) { try { - $o->createAlias($url, $target, $totrash, $password); - dcAdminNotices::addSuccessNotice(__('Alias for this media created.')); - dcCore::app()->adminurl->redirect('admin.plugin.' . basename(__DIR__)); + Utils::updateAliases($_POST['a']); + dcPage::addSuccessNotice(__('Aliases successfully updated.')); + dcCore::app()->adminurl->redirect('admin.plugin.' . My::id()); } catch (Exception $e) { dcCore::app()->error->add($e->getMessage()); } - } else { - dcCore::app()->error->add(__('Target is not in media manager.')); } - } else { - $found = $a->getMediaId($target); - if (!empty($found)) { - try { - $o->createAlias($url, $target, $totrash, $password); - dcAdminNotices::addSuccessNotice(__('Alias for this media modified.')); - dcCore::app()->adminurl->redirect('admin.plugin.' . basename(__DIR__)); - } catch (Exception $e) { - dcCore::app()->error->add($e->getMessage()); + # New alias + if (isset($_POST['filesalias_url'])) { + $url = empty($_POST['filesalias_url']) ? PallazzoTools::rand_uniqid() : $_POST['filesalias_url']; + + $target = $_POST['filesalias_destination']; + $totrash = isset($_POST['filesalias_disposable']) ? true : false; + $password = empty($_POST['filesalias_password']) ? '' : $_POST['filesalias_password']; + + if (preg_match('/^' . preg_quote(dcCore::app()->media->root_url, '/') . '/', $target)) { + $target = preg_replace('/^' . preg_quote(dcCore::app()->media->root_url, '/') . '/', '', $target); + $found = Utils::getMediaId($target); + + if (!empty($found)) { + try { + Utils::createAlias($url, $target, $totrash, $password); + dcPage::addSuccessNotice(__('Alias for this media created.')); + dcCore::app()->adminurl->redirect('admin.plugin.' . My::id()); + } catch (Exception $e) { + dcCore::app()->error->add($e->getMessage()); + } + } else { + dcCore::app()->error->add(__('Target is not in media manager.')); + } + } else { + $found = Utils::getMediaId($target); + + if (!empty($found)) { + try { + Utils::createAlias($url, $target, $totrash, $password); + dcPage::addSuccessNotice(__('Alias for this media modified.')); + dcCore::app()->adminurl->redirect('admin.plugin.' . My::id()); + } catch (Exception $e) { + dcCore::app()->error->add($e->getMessage()); + } + } else { + dcCore::app()->error->add(__('Target is not in media manager.')); + } } - } else { - dcCore::app()->error->add(__('Target is not in media manager.')); } + + return true; } -} -?> - - -<?php echo __('Media sharing'); ?> - - -blog->name) => '', - __('Media sharing') => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)), - __('New alias') => '', - ]) . - dcPage::notices() . - '
' . - '

' . __('New alias') . '

' . - '

' . - form::field('filesalias_destination', 70, 255) . '

' . - '

' . __('Destination file must be in media manager.') . '

' . - '

' . - form::field('filesalias_url', 70, 255) . '

' . - '

' . __('Leave empty to get a randomize alias.') . '

' . - '

' . - form::field('filesalias_password', 70, 255) . '

' . - '

' . form::checkbox('filesalias_disposable', 1) . - '

' . - '

' . - dcCore::app()->formNonce() . - form::hidden('part', 'new') . - '

' . - '

' . sprintf(__('Do not put blog media URL "%s" in fields or it will be removed.'), $media->root_url) . '

' . - '
'; -} else { - echo - dcPage::breadcrumb([ - html::escapeHTML(dcCore::app()->blog->name) => '', - __('Media sharing') => '', - ]) . - dcPage::notices() . - '

' . __('New alias') . '

'; + dcPage::openModule(My::name()); - if (empty($aliases)) { - echo '

' . __('No alias') . '

'; - } else { + if (($_REQUEST['part'] ?? '') == 'new') { + self::displayAliasForm(); + } else { + self::displayAliasList(); + } + + dcPage::helpBlock('filesAlias'); + + dcPage::closeModule(); + } + + private static function displayAliasForm(): void + { echo - '
' . - '
' . - '' . - '' . - '' . - '' . - '' . - '' . - '' . - ''; + dcPage::breadcrumb([ + Html::escapeHTML(dcCore::app()->blog->name) => '', + My::name() => dcCore::app()->adminurl->get('admin.plugin.' . My::id()), + __('New alias') => '', + ]) . + dcPage::notices() . + (new Form('filesalias_new'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->method('post')->fields([ + (new Text('h3', Html::escapeHTML(__('New alias')))), + (new Note())->text(sprintf(__('Do not put blog media URL "%s" in fields or it will be removed.'), dcCore::app()->media->root_url))->class('form-note'), + // destination + (new Para())->items([ + (new Label(__('Destination:')))->for('filesalias_destination')->class('required'), + (new Input('filesalias_destination'))->size(70)->maxlenght(255), + ]), + (new Note())->text(__('Destination file must be in media manager.'))->class('form-note'), + // url + (new Para())->items([ + (new Label(__('URL (alias):')))->for('filesalias_url')->class('required'), + (new Input('filesalias_url'))->size(70)->maxlenght(255), + ]), + (new Note())->text(__('Leave empty to get a randomize alias.'))->class('form-note'), + // password + (new Para())->items([ + (new Label(__('Password:')))->for('filesalias_password')->class('required'), + (new Input('filesalias_password'))->size(70)->maxlenght(255), + ]), + // disposable + (new Para())->items([ + (new Checkbox('filesalias_disposable', false))->value(1), + (new Label(__('Disposable'), Label::OUTSIDE_LABEL_AFTER))->for('filesalias_disposable')->class('classic'), + ]), + // submit + (new Para())->items([ + (new Submit(['save']))->value(__('Save')), + (new Hidden(['part'], 'new')), + (new Text('', dcCore::app()->formNonce())), + ]), + ])->render(); + } - foreach ($aliases as $k => $v) { - $url = dcCore::app()->blog->url . dcCore::app()->url->getBase('filesalias') . '/' . html::escapeHTML($v['filesalias_url']); + private static function displayAliasList(): void + { + $aliases = Utils::getAliases(); + + echo + dcPage::breadcrumb([ + Html::escapeHTML(dcCore::app()->blog->name) => '', + My::name() => '', + ]) . + dcPage::notices() . + '

' . __('New alias') . '

'; + + if ($aliases->isEmpty()) { + echo '

' . __('No alias') . '

'; + } else { + $lines = ''; + $i = 0; + while ($aliases->fetch()) { + $url = dcCore::app()->blog->url . dcCore::app()->url->getBase('filesalias') . '/' . Html::escapeHTML($aliases->f('filesalias_url')); + + $lines .= '' . + '' . + '' . + '' . + '' . + ''; + $i++; + } - $link = '' . __('link') . ''; - $v['filesalias_disposable'] ??= false; echo - '' . - '' . - '' . - '' . - '' . - ''; + (new Form('filesalias_list'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->method('post')->fields([ + (new Text( + '', + '
' . + '
' . __('Aliases list') . '
' . __('Destination') . ' - ' . html::escapeHTML($media->root_url) . '(-?-)' . __('Alias') . ' - ' . dcCore::app()->blog->url . dcCore::app()->url->getBase('filesalias') . '/' . '(-?-)' . __('Disposable') . '' . __('Password') . '
' . + (new Input(['a[' . $i . '][filesalias_destination]']))->size(50)->maxlenght(255)->value(Html::escapeHTML($aliases->f('filesalias_destination')))->render() . + '' . + (new Input(['a[' . $i . '][filesalias_url]']))->size(50)->maxlenght(255)->value(Html::escapeHTML($aliases->f('filesalias_url')))->render() . + '' . __('link') . '' . + (new Input(['a[' . $i . '][filesalias_password]']))->size(50)->maxlenght(255)->value(Html::escapeHTML($aliases->f('filesalias_password')))->render() . + '' . + (new Checkbox(['a[' . $i . '][filesalias_disposable]'], (bool) $aliases->f('filesalias_disposable')))->value(1)->render() . + '
' . form::field(['a[' . $k . '][filesalias_destination]'], 40, 255, html::escapeHTML($v['filesalias_destination'])) . '' . form::field(['a[' . $k . '][filesalias_url]'], 20, 255, html::escapeHTML($v['filesalias_url'])) . '' . __('link') . '' . form::checkbox(['a[' . $k . '][filesalias_disposable]'], 1, $v['filesalias_disposable']) . '' . form::field(['a[' . $k . '][filesalias_password]'], 10, 255, html::escapeHTML($v['filesalias_password'])) . '
' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + $lines . + '
' . __('Aliases list') . '
' . __('Destination') . ' - ' . Html::escapeHTML(dcCore::app()->media->root_url) . '(-?-)' . __('Alias') . ' - ' . dcCore::app()->blog->url . dcCore::app()->url->getBase('filesalias') . '/' . '(-?-)' . __('Password') . '' . __('Disposable') . '
' + )), + (new Para())->items([ + (new Submit(['save']))->value(__('Update')), + (new Hidden(['part'], 'list')), + (new Text('', dcCore::app()->formNonce())), + ]), + (new Note())->text(__('To remove a link, empty its alias or destination.'))->class('form-note'), + ])->render(); } - - echo '' . - '

' . __('To remove a link, empty its alias or destination.') . '

' . - '

' . dcCore::app()->formNonce() . form::hidden('part', 'list') . - '

' . - '
'; } } - -dcPage::helpBlock('filesAlias'); -?> - - \ No newline at end of file diff --git a/src/My.php b/src/My.php new file mode 100644 index 0000000..67e975b --- /dev/null +++ b/src/My.php @@ -0,0 +1,45 @@ +url->register( + 'filesalias', + 'pub', + '^pub/(.+)$', + [UrlHandler::class, 'alias'] + ); + + return true; + } } - -Clearbricks::lib()->autoload([ - 'filesAliases' => __DIR__ . '/inc/class.files.alias.php', - 'aliasMedia' => __DIR__ . '/inc/class.files.alias.php', - 'PallazzoTools' => __DIR__ . '/inc/lib.files.alias.tools.php', -]); - -dcCore::app()->__set('filealias', new filesAliases()); - -dcCore::app()->url->register( - 'filesalias', - 'pub', - '^pub/(.+)$', - ['urlFilesAlias','alias'] -); diff --git a/src/UrlHandler.php b/src/UrlHandler.php new file mode 100644 index 0000000..914335b --- /dev/null +++ b/src/UrlHandler.php @@ -0,0 +1,83 @@ +ctx->__set('filealias', Utils::getAlias($args)); + + if (dcCore::app()->ctx->__get('filealias')->isEmpty()) { + self::p404(); + } + + if (dcCore::app()->ctx->__get('filealias')->f('filesalias_disposable')) { + $delete = true; + } + + if (dcCore::app()->ctx->__get('filealias')->f('filesalias_password')) { + # Check for match + if (!empty($_POST['filepassword']) && $_POST['filepassword'] == dcCore::app()->ctx->__get('filealias')->f('filesalias_password')) { + self::servefile(dcCore::app()->ctx->__get('filealias')->f('filesalias_destination'), $args, $delete); + } else { + self::serveDocument('file-password-form.html', 'text/html', false); + + return; + } + } else { + self::servefile(dcCore::app()->ctx->__get('filealias')->f('filesalias_destination'), $args, $delete); + } + } + + public static function servefile(string $target, string $alias, bool $delete = false): void + { + $media = Utils::getMediaId($target); + + if (empty($media)) { + self::p404(); + } + + if (!(dcCore::app()->media instanceof dcMedia)) { + dcCore::app()->media = new dcMedia(); + } + + $file = dcCore::app()->media->getFile($media); + + if (empty($file->file)) { + self::p404(); + } + + header('Content-type: ' . $file->type); + header('Content-Length: ' . $file->size); + header('Content-Disposition: attachment; filename="' . $file->basename . '"'); + + if (ob_get_length() > 0) { + ob_end_clean(); + } + flush(); + + readfile($file->file); + if ($delete) { + Utils::deleteAlias($alias); + } + } +} diff --git a/src/Utils.php b/src/Utils.php index d2b7749..f68d67f 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -10,53 +10,48 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class filesAliases +declare(strict_types=1); + +namespace Dotclear\Plugin\filesAlias; + +use dcCore; +use dcMedia; +use dcRecord; +use Exception; + +class Utils { - protected $aliases; - - public function __construct() + public static function getAliases(): dcRecord { + return new dcRecord(dcCore::app()->con->select( + 'SELECT filesalias_url, filesalias_destination, filesalias_password, filesalias_disposable ' . + 'FROM ' . dcCore::app()->prefix . My::ALIAS_TABLE_NAME . ' ' . + "WHERE blog_id = '" . dcCore::app()->con->escapeStr(dcCore::app()->blog->id) . "' " . + 'ORDER BY filesalias_url ASC ' + )); } - public function getAliases() + public static function getAlias(string $url): dcRecord { - if (is_array($this->aliases)) { - return $this->aliases; - } - - $this->aliases = []; - $sql = 'SELECT filesalias_url, filesalias_destination, filesalias_password, filesalias_disposable ' . - 'FROM ' . dcCore::app()->prefix . initFilesAlias::ALIAS_TABLE_NAME . ' ' . - "WHERE blog_id = '" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " . - 'ORDER BY filesalias_url ASC '; - $this->aliases = dcCore::app()->con->select($sql)->rows(); - - return $this->aliases; + return new dcRecord(dcCore::app()->con->select( + 'SELECT filesalias_url, filesalias_destination, filesalias_password, filesalias_disposable ' . + 'FROM ' . dcCore::app()->prefix . My::ALIAS_TABLE_NAME . ' ' . + "WHERE blog_id = '" . dcCore::app()->con->escapeStr(dcCore::app()->blog->id) . "' " . + "AND filesalias_url = '" . dcCore::app()->con->escapeStr($url) . "' " . + 'ORDER BY filesalias_url ASC ' + )); } - public function getAlias($url) - { - $strReq = 'SELECT filesalias_url, filesalias_destination, filesalias_password, filesalias_disposable ' . - 'FROM ' . dcCore::app()->prefix . initFilesAlias::ALIAS_TABLE_NAME . ' ' . - "WHERE blog_id = '" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " . - "AND filesalias_url = '" . dcCore::app()->con->escape($url) . "' " . - 'ORDER BY filesalias_url ASC '; - - $rs = dcCore::app()->con->select($strReq); - - return $rs; - } - - public function updateAliases($aliases) + public static function updateAliases(array $aliases): void { dcCore::app()->con->begin(); try { - $this->deleteAliases(); + self::deleteAliases(); foreach ($aliases as $k => $v) { if (!empty($v['filesalias_url']) && !empty($v['filesalias_destination'])) { $v['filesalias_disposable'] = isset($v['filesalias_disposable']) ? true : false; - $this->createAlias($v['filesalias_url'], $v['filesalias_destination'], $v['filesalias_disposable'], $v['filesalias_password']); + self::createAlias($v['filesalias_url'], $v['filesalias_destination'], $v['filesalias_disposable'], $v['filesalias_password']); } } @@ -68,7 +63,7 @@ class filesAliases } } - public function createAlias($url, $destination, $disposable = 0, $password = null) + public static function createAlias(string $url, string $destination, bool $disposable = false, ?string $password = null): void { if (!$url) { throw new Exception(__('File URL is empty.')); @@ -78,49 +73,41 @@ class filesAliases throw new Exception(__('File destination is empty.')); } - $cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . initFilesAlias::ALIAS_TABLE_NAME); - $cur->blog_id = (string) dcCore::app()->blog->id; - $cur->filesalias_url = (string) $url; - $cur->filesalias_destination = (string) $destination; - $cur->filesalias_password = $password; - $cur->filesalias_disposable = abs((int) $disposable); + $cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . My::ALIAS_TABLE_NAME); + $cur->setField('blog_id', (string) dcCore::app()->blog->id); + $cur->setField('filesalias_url', (string) $url); + $cur->setField('filesalias_destination', (string) $destination); + $cur->setField('filesalias_password', $password); + $cur->setField('filesalias_disposable', (int) $disposable); $cur->insert(); } - public function deleteAliases() + public static function deleteAliases(): void { dcCore::app()->con->execute( - 'DELETE FROM ' . dcCore::app()->prefix . initFilesAlias::ALIAS_TABLE_NAME . ' ' . - "WHERE blog_id = '" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " + 'DELETE FROM ' . dcCore::app()->prefix . My::ALIAS_TABLE_NAME . ' ' . + "WHERE blog_id = '" . dcCore::app()->con->escapeStr(dcCore::app()->blog->id) . "' " ); } - public function deleteAlias($url) + public static function deleteAlias(string $url): void { dcCore::app()->con->execute( - 'DELETE FROM ' . dcCore::app()->prefix . initFilesAlias::ALIAS_TABLE_NAME . ' ' . - "WHERE blog_id = '" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " . - "AND filesalias_url = '" . dcCore::app()->con->escape($url) . "' " + 'DELETE FROM ' . dcCore::app()->prefix . My::ALIAS_TABLE_NAME . ' ' . + "WHERE blog_id = '" . dcCore::app()->con->escapeStr(dcCore::app()->blog->id) . "' " . + "AND filesalias_url = '" . dcCore::app()->con->escapeStr($url) . "' " ); } -} -class aliasMedia extends dcMedia -{ - public function __construct() - { - } - - public function getMediaId($target) + public static function getMediaId(string $target): int { $strReq = 'SELECT media_id ' . 'FROM ' . dcCore::app()->prefix . dcMedia::MEDIA_TABLE_NAME . ' ' . - //"WHERE media_path = '" . $this->path . "' " . - "WHERE media_path = '" . dcCore::app()->con->escape(dcCore::app()->blog->settings->system->public_path) . "' " . - "AND media_file = '" . dcCore::app()->con->escape($target) . "' "; + "WHERE media_path = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog->settings->get('system')->get('public_path')) . "' " . + "AND media_file = '" . dcCore::app()->con->escapeStr($target) . "' "; $rs = dcCore::app()->con->select($strReq); - return $rs->count() ? $rs->media_id : null; + return $rs->count() ? (int) $rs->f('media_id') : 0; } }