use abtsract plugin id, settings ns, short settings id

This commit is contained in:
Jean-Christian Denis 2022-12-23 14:09:26 +01:00
parent 9bd94e05c1
commit 293432f04c
Signed by: JcDenis
GPG key ID: 1B5B8C5B90B6C951
8 changed files with 105 additions and 84 deletions

View file

@ -17,20 +17,20 @@ if (!defined('DC_CONTEXT_ADMIN')) {
require __DIR__ . '/_widgets.php'; require __DIR__ . '/_widgets.php';
# Admin menu # Admin menu
if (dcCore::app()->blog->settings->postwidgettext->postwidgettext_active) { if (dcCore::app()->blog->settings->get(basename(__DIR__))->get('active')) {
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem( dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
__('Post widget text'), __('Post widget text'),
dcCore::app()->adminurl->get('admin.plugin.postWidgetText'), dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
dcPage::getPF('postWidgetText/icon.svg'), dcPage::getPF(basename(__DIR__) . '/icon.svg'),
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.postWidgetText')) . '(&.*)?$/', $_SERVER['REQUEST_URI']), 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()->auth->check(dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_CONTENT_ADMIN]), dcCore::app()->blog->id)
); );
dcCore::app()->addBehavior('adminDashboardFavoritesV2', ['adminPostWidgetText', 'adminDashboardFavorites']); dcCore::app()->addBehavior('adminDashboardFavoritesV2', ['adminPostWidgetText', 'adminDashboardFavorites']);
} }
# Pref # Pref
dcCore::app()->addBehavior('adminFiltersListsV2', ['adminPostWidgetText', 'adminFiltersLists']); dcCore::app()->addBehavior('adminFiltersListsV2', ['adminPostWidgetText', 'adminFiltersListsV2']);
dcCore::app()->addBehavior('adminBlogPreferencesFormV2', ['adminPostWidgetText', 'adminBlogPreferencesForm']); dcCore::app()->addBehavior('adminBlogPreferencesFormV2', ['adminPostWidgetText', 'adminBlogPreferencesFormV2']);
dcCore::app()->addBehavior('adminBeforeBlogSettingsUpdate', ['adminPostWidgetText', 'adminBeforeBlogSettingsUpdate']); dcCore::app()->addBehavior('adminBeforeBlogSettingsUpdate', ['adminPostWidgetText', 'adminBeforeBlogSettingsUpdate']);
# Post # Post
@ -48,10 +48,10 @@ dcCore::app()->addBehavior('adminAfterPageCreate', ['adminPostWidgetText', 'admi
dcCore::app()->addBehavior('adminBeforePageDelete', ['adminPostWidgetText', 'adminBeforePostDelete']); dcCore::app()->addBehavior('adminBeforePageDelete', ['adminPostWidgetText', 'adminBeforePostDelete']);
# Plugin "importExport" # Plugin "importExport"
if (dcCore::app()->blog->settings->postwidgettext->postwidgettext_importexport_active) { if (dcCore::app()->blog->settings->get(basename(__DIR__))->get('importexport_active')) {
dcCore::app()->addBehavior('exportFull', ['adminPostWidgetText', 'exportFull']); dcCore::app()->addBehavior('exportFullV2', ['adminPostWidgetText', 'exportFullV2']);
dcCore::app()->addBehavior('exportSingle', ['adminPostWidgetText', 'exportSingle']); dcCore::app()->addBehavior('exportSingleV2', ['adminPostWidgetText', 'exportSingleV2']);
dcCore::app()->addBehavior('importInit', ['adminPostWidgetText', 'importInit']); dcCore::app()->addBehavior('importInitV2', ['adminPostWidgetText', 'importInitV2']);
dcCore::app()->addBehavior('importSingle', ['adminPostWidgetText', 'importSingle']); dcCore::app()->addBehavior('importSingleV2', ['adminPostWidgetText', 'importSingleV2']);
dcCore::app()->addBehavior('importFull', ['adminPostWidgetText', 'importFull']); dcCore::app()->addBehavior('importFullV2', ['adminPostWidgetText', 'importFullV2']);
} }

View file

@ -18,7 +18,7 @@ $this->registerModule(
'Post widget text', 'Post widget text',
'Add a widget with a text related to an entry', 'Add a widget with a text related to an entry',
'Jean-Christian Denis and Contributors', 'Jean-Christian Denis and Contributors',
'2022.11.20', '2022.12.23',
[ [
'requires' => [['core', '2.24']], 'requires' => [['core', '2.24']],
'permissions' => dcCore::app()->auth->makePermissions([ 'permissions' => dcCore::app()->auth->makePermissions([
@ -26,9 +26,9 @@ $this->registerModule(
dcAuth::PERMISSION_CONTENT_ADMIN, dcAuth::PERMISSION_CONTENT_ADMIN,
]), ]),
'type' => 'plugin', 'type' => 'plugin',
'support' => 'https://github.com/JcDenis/postWidgetText', 'support' => 'https://github.com/JcDenis/' . basename(__DIR__),
'details' => 'https://plugins.dotaddict.org/dc2/details/postWidgetText', 'details' => 'https://plugins.dotaddict.org/dc2/details/' . basename(__DIR__),
'repository' => 'https://raw.githubusercontent.com/JcDenis/postWidgetText/master/dcstore.xml', 'repository' => 'https://raw.githubusercontent.com/JcDenis/' . basename(__DIR__) . '/master/dcstore.xml',
'settings' => [ 'settings' => [
'blog' => '#params.pwt_params', 'blog' => '#params.pwt_params',
], ],

View file

@ -15,7 +15,7 @@ if (!defined('DC_CONTEXT_ADMIN')) {
} }
try { try {
# check installed version // check installed version
if (!dcCore::app()->newVersion( if (!dcCore::app()->newVersion(
basename(__DIR__), basename(__DIR__),
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version') dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
@ -23,8 +23,7 @@ try {
return null; return null;
} }
# Table is the same for plugins // Table is the same for plugins pollsFactory, postTask, postWidgetText
# pollsFactory, postTask, postWidgetText
$s = new dbStruct(dcCore::app()->con, dcCore::app()->prefix); $s = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
$s->{initPostWidgetText::PWT_TABLE_NAME} $s->{initPostWidgetText::PWT_TABLE_NAME}
->option_id('bigint', 0, false) ->option_id('bigint', 0, false)
@ -45,24 +44,45 @@ try {
$si = new dbStruct(dcCore::app()->con, dcCore::app()->prefix); $si = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
$changes = $si->synchronize($s); $changes = $si->synchronize($s);
# Settings $current = dcCore::app()->getVersion(basename(__DIR__));
dcCore::app()->blog->settings->addNamespace('postwidgettext');
dcCore::app()->blog->settings->postwidgettext->put( // Update settings id, ns
'postwidgettext_active', if ($current && version_compare($current, '2022.12.23', '<=')) {
true, $record = dcCore::app()->con->select(
'boolean', 'SELECT * FROM ' . dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME . ' ' .
'post widget text plugin enabled', "WHERE setting_ns = 'postwidgettext' "
false, );
true
); while ($record->fetch()) {
dcCore::app()->blog->settings->postwidgettext->put( if (preg_match('/^postwidgettext_(.*?)$/', $record->setting_id, $match)) {
'postwidgettext_importexport_active', $cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
true, $cur->setting_id = $match[1];
'boolean', $cur->setting_ns = basename(__DIR__);
'activate import/export behaviors', $cur->update(
false, "WHERE setting_id = '" . $record->setting_id . "' and setting_ns = 'postwidgettext' " .
true 'AND blog_id ' . (null === $record->blog_id ? 'IS NULL ' : ("= '" . dcCore::app()->con->escape($record->blog_id) . "' "))
); );
}
}
} else {
// Settings
dcCore::app()->blog->settings->get(basename(__DIR__))->put(
'active',
true,
'boolean',
'post widget text plugin enabled',
false,
true
);
dcCore::app()->blog->settings->get(basename(__DIR__))->put(
'importexport_active',
true,
'boolean',
'activate import/export behaviors',
false,
true
);
}
# Transfert records from old table to the new one # Transfert records from old table to the new one
if (dcCore::app()->getVersion(basename(__DIR__)) !== null if (dcCore::app()->getVersion(basename(__DIR__)) !== null

View file

@ -14,4 +14,4 @@ if (!defined('DC_RC_PATH')) {
return null; return null;
} }
require dirname(__FILE__) . '/_widgets.php'; require __DIR__ . '/_widgets.php';

View file

@ -14,8 +14,6 @@ if (!defined('DC_RC_PATH')) {
return null; return null;
} }
dcCore::app()->blog->settings->addNamespace('postwidgettext');
dcCore::app()->addBehavior('initWidgets', ['postWidgetTextWidget', 'init']); dcCore::app()->addBehavior('initWidgets', ['postWidgetTextWidget', 'init']);
/** /**
@ -29,7 +27,7 @@ class postWidgetTextWidget
{ {
$w $w
->create( ->create(
'postwidgettext', basename(__DIR__),
__('Post widget text'), __('Post widget text'),
['postWidgetTextWidget', 'display'], ['postWidgetTextWidget', 'display'],
null, null,
@ -59,7 +57,7 @@ class postWidgetTextWidget
return null; return null;
} }
if (!dcCore::app()->blog->settings->postwidgettext->postwidgettext_active if (!dcCore::app()->blog->settings->get(basename(__DIR__))->get('active')
|| !dcCore::app()->ctx->exists('posts') || !dcCore::app()->ctx->exists('posts')
|| !dcCore::app()->ctx->posts->post_id || !dcCore::app()->ctx->posts->post_id
) { ) {
@ -88,7 +86,7 @@ class postWidgetTextWidget
return $w->renderDiv( return $w->renderDiv(
$w->content_only, $w->content_only,
'postwidgettext ' . $w->class, basename(__DIR__) . ' ' . $w->class,
'', '',
($title ? $w->renderTitle(html::escapeHTML($title)) : '') . $content ($title ? $w->renderTitle(html::escapeHTML($title)) : '') . $content
); );

View file

@ -83,7 +83,7 @@ class postWidgetText
if (isset($params['option_type'])) { if (isset($params['option_type'])) {
$params['sql'] .= "AND W.option_type = '" . $this->con->escape($params['option_type']) . "' "; $params['sql'] .= "AND W.option_type = '" . $this->con->escape($params['option_type']) . "' ";
} else { } else {
$params['sql'] .= "AND W.option_type = 'postwidgettext' "; $params['sql'] .= "AND W.option_type = '" . $this->con->escape(basename(__DIR__)) . "' ";
} }
unset($params['option_type']); unset($params['option_type']);
if (!isset($params['post_type'])) { if (!isset($params['post_type'])) {
@ -170,7 +170,7 @@ class postWidgetText
$this->triggerBlog(); $this->triggerBlog();
} }
public function delWidget($id, $type = 'postwidgettext') public function delWidget($id, $type = '')
{ {
if (!dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([ if (!dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
dcAuth::PERMISSION_DELETE, dcAuth::PERMISSION_DELETE,
@ -179,7 +179,8 @@ class postWidgetText
throw new Exception(__('You are not allowed to delete entries text widget')); throw new Exception(__('You are not allowed to delete entries text widget'));
} }
$id = (int) $id; $id = (int) $id;
$type = $type ?? basename(__DIR__);
if (empty($id)) { if (empty($id)) {
throw new Exception(__('No such ID')); throw new Exception(__('No such ID'));

View file

@ -17,6 +17,11 @@
*/ */
class adminPostWidgetText class adminPostWidgetText
{ {
private static function id()
{
return basename(dirname(__DIR__));
}
public static function sortbyCombo() public static function sortbyCombo()
{ {
return [ return [
@ -27,7 +32,7 @@ class adminPostWidgetText
]; ];
} }
public static function adminFiltersLists($sorts) public static function adminFiltersListsV2($sorts)
{ {
$sorts['pwt'] = [ $sorts['pwt'] = [
__('Post widget text'), __('Post widget text'),
@ -38,7 +43,7 @@ class adminPostWidgetText
]; ];
} }
public static function adminBlogPreferencesForm(dcSettings $blog_settings) public static function adminBlogPreferencesFormV2(dcSettings $blog_settings)
{ {
echo ' echo '
<div class="fieldset"> <div class="fieldset">
@ -46,12 +51,12 @@ class adminPostWidgetText
<div class="two-cols"> <div class="two-cols">
<div class="col"> <div class="col">
<p><label for="active">' . <p><label for="active">' .
form::checkbox('active', 1, (bool) $blog_settings->postwidgettext->postwidgettext_active) . form::checkbox('active', 1, (bool) $blog_settings->get(self::id())->get('active')) .
__('Enable post widget text on this blog') . '</label></p> __('Enable post widget text on this blog') . '</label></p>
</div> </div>
<div class="col"> <div class="col">
<p><label for="importexport_active">' . <p><label for="importexport_active">' .
form::checkbox('importexport_active', 1, (bool) $blog_settings->postwidgettext->postwidgettext_importexport_active) . form::checkbox('importexport_active', 1, (bool) $blog_settings->get(self::id())->get('importexport_active')) .
__('Enable import/export behaviors') . '</label></p> __('Enable import/export behaviors') . '</label></p>
</div> </div>
</div> </div>
@ -61,17 +66,17 @@ class adminPostWidgetText
public static function adminBeforeBlogSettingsUpdate(dcSettings $blog_settings) public static function adminBeforeBlogSettingsUpdate(dcSettings $blog_settings)
{ {
$blog_settings->postwidgettext->put('postwidgettext_active', !empty($_POST['active'])); $blog_settings->get(self::id())->put('active', !empty($_POST['active']));
$blog_settings->postwidgettext->put('postwidgettext_importexport_active', !empty($_POST['importexport_active'])); $blog_settings->get(self::id())->put('importexport_active', !empty($_POST['importexport_active']));
} }
public static function adminDashboardFavorites(dcFavorites $favs) public static function adminDashboardFavoritesV2(dcFavorites $favs)
{ {
$favs->register('postWidgetText', [ $favs->register(self::id(), [
'title' => __('Post widget text'), 'title' => __('Post widget text'),
'url' => dcCore::app()->adminurl->get('admin.plugin.postWidgetText'), 'url' => dcCore::app()->adminurl->get('admin.plugin.' . self::id()),
'small-icon' => dcPage::getPF('postWidgetText/icon.svg'), 'small-icon' => dcPage::getPF(self::id() . '/icon.svg'),
'large-icon' => dcPage::getPF('postWidgetText/icon.svg'), 'large-icon' => dcPage::getPF(self::id() . '/icon.svg'),
'permissions' => dcCore::app()->auth->makePermissions([ 'permissions' => dcCore::app()->auth->makePermissions([
dcAuth::PERMISSION_USAGE, dcAuth::PERMISSION_USAGE,
dcAuth::PERMISSION_CONTENT_ADMIN, dcAuth::PERMISSION_CONTENT_ADMIN,
@ -85,7 +90,7 @@ class adminPostWidgetText
return return
dcCore::app()->callBehavior('adminPostEditor', $editor['xhtml'], 'pwt', ['#post_wtext'], 'xhtml') . dcCore::app()->callBehavior('adminPostEditor', $editor['xhtml'], 'pwt', ['#post_wtext'], 'xhtml') .
dcPage::jsLoad(dcPage::getPF('postWidgetText/js/post.js')); dcPage::jsModuleLoad(self::id() . '/js/post.js');
} }
public static function adminPostFormItems($main, $sidebar, $post) public static function adminPostFormItems($main, $sidebar, $post)
@ -147,7 +152,7 @@ class adminPostWidgetText
if (!empty($title) || !empty($content)) { if (!empty($title) || !empty($content)) {
$wcur = $pwt->openCursor(); $wcur = $pwt->openCursor();
$wcur->post_id = $post_id; $wcur->post_id = $post_id;
$wcur->option_type = 'postwidgettext'; $wcur->option_type = self::id();
$wcur->option_lang = $cur->post_lang; $wcur->option_lang = $cur->post_lang;
$wcur->option_format = $cur->post_format; $wcur->option_format = $cur->post_format;
$wcur->option_title = $title; $wcur->option_title = $title;
@ -180,49 +185,49 @@ class adminPostWidgetText
} }
} }
public static function exportSingle(dcCore $core, $exp, $blog_id) public static function exportSingleV2($exp, $blog_id)
{ {
$exp->export( $exp->export(
'postwidgettext', self::id(),
'SELECT option_type, option_content, ' . 'SELECT option_type, option_content, ' .
'option_content_xhtml, W.post_id ' . 'option_content_xhtml, W.post_id ' .
'FROM ' . dcCore::app()->prefix . initPostWidgetText::PWT_TABLE_NAME . ' W ' . 'FROM ' . dcCore::app()->prefix . initPostWidgetText::PWT_TABLE_NAME . ' W ' .
'LEFT JOIN ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ' . 'LEFT JOIN ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ' .
'ON P.post_id = W.post_id ' . 'ON P.post_id = W.post_id ' .
"WHERE P.blog_id = '" . $blog_id . "' " . "WHERE P.blog_id = '" . $blog_id . "' " .
"AND W.option_type = 'postwidgettext' " "AND W.option_type = '" . dcCore::app()->con->escape(self::id()) . "' "
); );
} }
public static function exportFull(dcCore $core, $exp) public static function exportFullV2($exp)
{ {
$exp->export( $exp->export(
'postwidgettext', self::id(),
'SELECT option_type, option_content, ' . 'SELECT option_type, option_content, ' .
'option_content_xhtml, W.post_id ' . 'option_content_xhtml, W.post_id ' .
'FROM ' . dcCore::app()->prefix . initPostWidgetText::PWT_TABLE_NAME . ' W ' . 'FROM ' . dcCore::app()->prefix . initPostWidgetText::PWT_TABLE_NAME . ' W ' .
'LEFT JOIN ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ' . 'LEFT JOIN ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ' .
'ON P.post_id = W.post_id ' . 'ON P.post_id = W.post_id ' .
"WHERE W.option_type = 'postwidgettext' " "WHERE W.option_type = '" . dcCore::app()->con->escape(self::id()) . "' "
); );
} }
public static function importInit($bk, dcCore $core) public static function importInitV2($bk)
{ {
$bk->cur_postwidgettext = dcCore::app()->con->openCursor( $bk->cur_postwidgettext = dcCore::app()->con->openCursor(
dcCore::app()->prefix . initPostWidgetText::PWT_TABLE_NAME dcCore::app()->prefix . initPostWidgetText::PWT_TABLE_NAME
); );
$bk->postwidgettext = new postWidgetText(); $bk->{self::id()} = new postWidgetText();
} }
public static function importSingle($line, $bk, dcCore $core) public static function importSingleV2($line, $bk)
{ {
if ($line->__name == 'postwidgettext' if ($line->__name == self::id()
&& isset($bk->old_ids['post'][(int) $line->post_id]) && isset($bk->old_ids['post'][(int) $line->post_id])
) { ) {
$line->post_id = $bk->old_ids['post'][(int) $line->post_id]; $line->post_id = $bk->old_ids['post'][(int) $line->post_id];
$exists = $bk->postwidgettext->getWidgets([ $exists = $bk->{self::id()}->getWidgets([
'post_id' => $line->post_id, 'post_id' => $line->post_id,
]); ]);
@ -236,17 +241,17 @@ class adminPostWidgetText
$bk->cur_postwidgettext->option_content = (string) $line->option_content; $bk->cur_postwidgettext->option_content = (string) $line->option_content;
$bk->cur_postwidgettext->option_content_xhtml = (string) $line->option_content_xhtml; $bk->cur_postwidgettext->option_content_xhtml = (string) $line->option_content_xhtml;
$bk->postwidgettext->addWidget( $bk->{self::id()}->addWidget(
$bk->cur_postwidgettext $bk->cur_postwidgettext
); );
} }
} }
} }
public static function importFull($line, $bk, dcCore $core) public static function importFullV2($line, $bk)
{ {
if ($line->__name == 'postwidgettext') { if ($line->__name == self::id()) {
$exists = $bk->postwidgettext->getWidgets([ $exists = $bk->{self::id()}->getWidgets([
'post_id' => $line->post_id, 'post_id' => $line->post_id,
]); ]);
@ -260,7 +265,7 @@ class adminPostWidgetText
$bk->cur_postwidgettext->option_content = (string) $line->option_content; $bk->cur_postwidgettext->option_content = (string) $line->option_content;
$bk->cur_postwidgettext->option_content_xhtml = (string) $line->option_content_xhtml; $bk->cur_postwidgettext->option_content_xhtml = (string) $line->option_content_xhtml;
$bk->postwidgettext->addWidget( $bk->{self::id()}->addWidget(
$bk->cur_postwidgettext $bk->cur_postwidgettext
); );
} }

View file

@ -35,7 +35,7 @@ if (!empty($_POST['save']) && !empty($_POST['widgets'])) {
if (!empty($_POST['redir'])) { if (!empty($_POST['redir'])) {
http::redirect($_POST['redir']); http::redirect($_POST['redir']);
} else { } else {
dcCore::app()->adminurl->redirect('admin.plugin.postWidgetText'); dcCore::app()->adminurl->redirect('admin.plugin.' . basename(__DIR__));
} }
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->error->add($e->getMessage()); dcCore::app()->error->add($e->getMessage());
@ -59,8 +59,8 @@ try {
# Display # Display
echo ' echo '
<html><head><title>' . __('Post widget text') . '</title>' . <html><head><title>' . __('Post widget text') . '</title>' .
dcPage::jsLoad(dcPage::getPF('postWidgetText/js/index.js')) . dcPage::jsModuleLoad(basename(__DIR__) . '/js/index.js') .
$filter->js(dcCore::app()->adminurl->get('admin.plugin.postWidgetText')) . ' $filter->js(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '
</head> </head>
<body>' . <body>' .
@ -70,24 +70,21 @@ dcPage::breadcrumb([
]) . ]) .
dcPage::notices(); dcPage::notices();
$filter->display('admin.plugin.postWidgetText', form::hidden('p', 'postWidgetText')); $filter->display('admin.plugin.' . basename(__DIR__), form::hidden('p', basename(__DIR__)));
$posts_list->display( $posts_list->display(
$filter->page, $filter->page,
$filter->nb, $filter->nb,
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.postWidgetText') . '" method="post" id="form-entries">' . '<form action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)) . '" method="post" id="form-entries">' .
'%s' . '%s' .
'<div class="two-cols">' . '<div class="two-cols">' .
'<p class="col checkboxes-helpers"></p>' . '<p class="col checkboxes-helpers"></p>' .
'<p class="col right">' . '<p class="col right">' .
'<input id="do-action" type="submit" name="save" value="' . __('Delete selected widgets') . '" /></p>' . '<input id="do-action" type="submit" name="save" value="' . __('Delete selected widgets') . '" /></p>' .
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.postWidgetText', array_merge(['p' => 'postWidgetText'], $filter->values(true))) . dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . basename(__DIR__), array_merge(['p' => basename(__DIR__)], $filter->values(true))) .
dcCore::app()->formNonce() . dcCore::app()->formNonce() .
'</div>' . '</div>' .
'</form>' '</form>'
); );
# Footer
dcPage::helpBlock('postWidgetText');
echo '</body></html>'; echo '</body></html>';