diff --git a/src/Backend.php b/src/Backend.php index 67e4980..9c4f57d 100644 --- a/src/Backend.php +++ b/src/Backend.php @@ -48,7 +48,7 @@ class Backend extends dcNsProcess return false; } - # Admin menu + // backend sidebar menu icon dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem( My::name(), dcCore::app()->adminurl?->get('admin.plugin.' . My::id()), @@ -58,7 +58,7 @@ class Backend extends dcNsProcess ); dcCore::app()->addBehaviors([ - # Dashboard favorites + // backend user dashboard favorites icon 'adminDashboardFavoritesV2' => function (dcFavorites $favs): void { $favs->register(My::id(), [ 'title' => My::name(), @@ -68,11 +68,11 @@ class Backend extends dcNsProcess 'permissions' => dcCore::app()->auth?->makePermissions([dcCore::app()->auth::PERMISSION_CONTENT_ADMIN]), ]); }, - # Preference form + // backend user preference form 'adminBlogPreferencesFormV2' => function (dcSettings $blog_settings): void { $active = (bool) $blog_settings->get(My::id())->get('active'); - $allowedtplvalues = Epc::blogAllowedTplValues(); - $allowedpubpages = Epc::blogAllowedPubPages(); + $allowedtplvalues = Epc::blogAllowedTemplateValue(); + $allowedpubpages = Epc::blogAllowedTemplatePage(); echo '

' . My::name() . '

' . @@ -95,13 +95,13 @@ class Backend extends dcNsProcess // allowedtplvalues (new Para())->items([ (new Label(__('Allowed DC template values:'), Label::OUTSIDE_LABEL_BEFORE))->for('epc_allowedtplvalues'), - (new Input('epc_allowedtplvalues'))->size(100)->maxlenght(0)->value(Epc::implode($allowedtplvalues)), + (new Input('epc_allowedtplvalues'))->size(100)->maxlenght(0)->value(Epc::encodeMulti($allowedtplvalues)), ])->render() . '

' . __('Use "readable_name1:template_value1;readable_name2:template_value2;" like "entry content:EntryContent;entry excerpt:EntryExcerpt;".') . '

' . // allowedpubpages (new Para())->items([ (new Label(__('Allowed public pages:'), Label::OUTSIDE_LABEL_BEFORE))->for('epc_allowedpubpages'), - (new Input('epc_allowedpubpages'))->size(100)->maxlenght(0)->value(Epc::implode($allowedpubpages)), + (new Input('epc_allowedpubpages'))->size(100)->maxlenght(0)->value(Epc::encodeMulti($allowedpubpages)), ])->render() . '

' . __('Use "readable_name1:template_page1;readable_name2:template_page2;" like "post page:post.html;home page:home.html;".') . '

' . '
' . @@ -109,17 +109,17 @@ class Backend extends dcNsProcess '
' . ''; }, - # Save preference + // backend user preference save 'adminBeforeBlogSettingsUpdate' => function (dcSettings $blog_settings): void { $active = !empty($_POST['epc_active']); - $allowedtplvalues = Epc::explode($_POST['epc_allowedtplvalues']); - $allowedpubpages = Epc::explode($_POST['epc_allowedpubpages']); + $allowedtplvalues = Epc::decodeMulti($_POST['epc_allowedtplvalues']); + $allowedpubpages = Epc::decodeMulti($_POST['epc_allowedpubpages']); $blog_settings->get(My::id())->put('active', $active); $blog_settings->get(My::id())->put('allowedtplvalues', json_encode($allowedtplvalues)); $blog_settings->get(My::id())->put('allowedpubpages', json_encode($allowedpubpages)); }, - # List filter + // backend epc list filter 'adminFiltersListsV2' => function (ArrayObject $sorts): void { $sorts['epc'] = [ My::name(), @@ -134,7 +134,7 @@ class Backend extends dcNsProcess [__('records per page'), 20], ]; }, - # Widgets + // widgets registration 'initWidgets' => [Widgets::class, 'initWidgets'], ]); diff --git a/src/BackendList.php b/src/BackendList.php index 918851c..588be4d 100644 --- a/src/BackendList.php +++ b/src/BackendList.php @@ -22,57 +22,65 @@ use Dotclear\Helper\Html\Form\Checkbox; use Dotclear\Helper\Html\Html; /** - * @ingroup DC_PLUGIN_PERIODICAL - * @brief Periodical - admin pager methods. - * @since 2.6 + * Backend filters values list. */ class BackendList extends adminGenericListV2 { - public function display(adminGenericFilterV2 $filter, string $pager_url, string $enclose_block): void + /** + * Display list. + * + * @param adminGenericFilterV2 $filter The filter + * @param string $url The pager URL + * @param string $block The enclose bloc + */ + public function display(adminGenericFilterV2 $filter, string $url, string $block): void { if ($this->rs->isEmpty()) { echo '

' . ($filter->show() ? __('No record matches the filter') : __('No record')) . '

'; - } else { - $pager = new dcPager($filter->value('page'), $this->rs_count, $filter->value('nb'), 10); - $pager->base_url = $pager_url; - $epc_id = []; - if (isset($_REQUEST['epc_id'])) { - foreach ($_REQUEST['epc_id'] as $v) { - $epc_id[(int) $v] = true; - } - } - - $cols = [ - 'key' => '' . __('Key') . '', - 'value' => '' . __('Value') . '', - 'date' => '' . __('Date') . '', - ]; - - $html_block = '
' . - '' . implode($cols) . '%s
' . - ( - $filter->show() ? - sprintf(__('List of %s records matching the filter.'), $this->rs_count) : - sprintf(__('List of %s records.'), $this->rs_count) - ) . '
%s
'; - - if ($enclose_block) { - $html_block = sprintf($enclose_block, $html_block); - } - $blocks = explode('%s', $html_block); - - echo $pager->getLinks() . $blocks[0]; - - while ($this->rs->fetch()) { - echo $this->line(isset($epc_id[$this->rs->epc_id])); - } - - echo $blocks[1] . $blocks[2] . $pager->getLinks(); + return; } + + $pager = new dcPager($filter->value('page'), $this->rs_count, $filter->value('nb'), 10); + $pager->base_url = $url; + + $epc_id = []; + if (isset($_REQUEST['epc_id'])) { + foreach ($_REQUEST['epc_id'] as $v) { + $epc_id[(int) $v] = true; + } + } + + $cols = [ + 'key' => '' . __('Key') . '', + 'value' => '' . __('Value') . '', + 'date' => '' . __('Date') . '', + ]; + + $content = '
' . + '' . implode($cols) . '%s
' . ( + $filter->show() ? + sprintf(__('List of %s records matching the filter.'), $this->rs_count) : + sprintf(__('List of %s records.'), $this->rs_count) + ) . '
%s
'; + + $blocks = explode('%s', sprintf($block, $content)); + + echo $pager->getLinks() . $blocks[0]; + + while ($this->rs->fetch()) { + $this->line(isset($epc_id[$this->rs->epc_id])); + } + + echo $blocks[1] . $blocks[2] . $pager->getLinks(); } - private function line(bool $checked): string + /** + * Dispay a list line. + * + * @param bool $checked Checkbox checked + */ + private function line(bool $checked): void { $cols = [ 'check' => '' . (new Checkbox(['epc_id[]'], $checked))->value($this->rs->epc_id)->render() . '', @@ -81,9 +89,9 @@ class BackendList extends adminGenericListV2 'date' => '' . Date::dt2str(__('%Y-%m-%d %H:%M'), $this->rs->epc_upddt) . '', ]; - return - '' . - implode($cols) . - ''; + echo + '' . + implode($cols) . + ''; } } diff --git a/src/Epc.php b/src/Epc.php index 039726c..ea79d79 100644 --- a/src/Epc.php +++ b/src/Epc.php @@ -33,39 +33,54 @@ __('RSS feeds'); class Epc { + /** @var string The temporary pattern to tag words to replace */ public const FLAGGER = 'ççççç%sççççç'; + /** @var EpcFilters $filters THe filters stack */ private static EpcFilters $filters; - public static array $epcFilterLimit = []; - # - # Default definition - # + /** @var array $limits The replacment limit per filtre */ + private static array $limits = []; - public static function defaultAllowedTplValues(): array + /** + * Get list of default allowed templates name->tag. + * + * @return array The templates name->tag pairs + */ + public static function defaultAllowedTemplateValue(): array { - $rs = new ArrayObject([ + $list = new ArrayObject([ 'entry excerpt' => 'EntryExcerpt', 'entry content' => 'EntryContent', 'comment content' => 'CommentContent', ]); # --BEHAVIOR-- enhancePostContentAllowedTplValues : ArrayObject - dcCore::app()->callBehavior('enhancePostContentAllowedTplValues', $rs); + dcCore::app()->callBehavior('enhancePostContentAllowedTplValues', $list); - return iterator_to_array($rs, true); + return iterator_to_array($list, true); } - public static function blogAllowedTplValues(): array + /** + * Get list of allowed templates name->tag set on current blog. + * + * @return array The templates name->tag pairs + */ + public static function blogAllowedTemplateValue(): array { - $rs = json_decode((string) dcCore::app()->blog?->settings->get(My::id())->get('allowedtplvalues'), true); + $list = json_decode((string) dcCore::app()->blog?->settings->get(My::id())->get('allowedtplvalues'), true); - return is_array($rs) ? $rs : self::defaultAllowedTplValues(); + return is_array($list) ? $list : self::defaultAllowedTemplateValue(); } - public static function defaultAllowedWidgetValues(): array + /** + * Get list of allowed templates name->[tag,callback] to list on epc widgets. + * + * @return array The templates name->[id,cb] values + */ + public static function widgetAllowedTemplateValue(): array { - $rs = new ArrayObject([ + $list = new ArrayObject([ 'entry excerpt' => [ 'id' => 'entryexcerpt', 'cb' => [self::class, 'widgetContentEntryExcerpt'], @@ -81,14 +96,19 @@ class Epc ]); # --BEHAVIOR-- enhancePostContentAllowedWidgetValues : ArrayObject - dcCore::app()->callBehavior('enhancePostContentAllowedWidgetValues', $rs); + dcCore::app()->callBehavior('enhancePostContentAllowedWidgetValues', $list); - return iterator_to_array($rs, true); + return iterator_to_array($list, true); } - public static function defaultAllowedPubPages(): array + /** + * Get list of default allowed templates name->page to list on epc widgets. + * + * @return array The templates name->page pairs + */ + public static function defaultAllowedTemplatePage(): array { - $rs = new ArrayObject([ + $list = new ArrayObject([ 'home page' => 'home.html', 'post page' => 'post.html', 'category page' => 'category.html', @@ -98,16 +118,21 @@ class Epc ]); # --BEHAVIOR-- enhancePostContentAllowedPubPages : ArrayObject - dcCore::app()->callBehavior('enhancePostContentAllowedPubPages', $rs); + dcCore::app()->callBehavior('enhancePostContentAllowedPubPages', $list); - return iterator_to_array($rs, true); + return iterator_to_array($list, true); } - public static function blogAllowedPubPages(): array + /** + * Get list of allowed templates name->page set on blog to list on epc widgets. + * + * @return array The templates name->page pairs + */ + public static function blogAllowedTemplatePage(): array { - $rs = json_decode((string) dcCore::app()->blog?->settings->get(My::id())->get('allowedpubpages'), true); + $list = json_decode((string) dcCore::app()->blog?->settings->get(My::id())->get('allowedpubpages'), true); - return is_array($rs) ? $rs : self::defaultAllowedPubPages(); + return is_array($list) ? $list : self::defaultAllowedTemplatePage(); } /** @@ -135,153 +160,193 @@ class Epc return self::$filters; } - public static function testContext(string $tag, array $args, EpcFilter $filter): bool - { - return in_array((string) dcCore::app()->ctx?->__get('current_tpl'), $filter->pubPages) - && in_array($tag, $filter->tplValues) - && $args[0] != '' //content - && empty($args['encode_xml']) - && empty($args['encode_html']) - && empty($args['remove_html']) - && empty($args['strip_tags']) - ; - } - - public static function replaceString(string $p, string $r, string $s, EpcFilter $filter, string $before = '\b', string $after = '\b'): string - { - # Limit + /** + * Apply filter to content. + * + * @param string $search The search + * @param string $replacement The replacement + * @param string $content The content + * @param EpcFilter $filter The filter + * @param string $before The start limit pattern + * @param string $after The end limit pattern + */ + public static function replaceString( + string $search, + string $replacement, + string $content, + EpcFilter $filter, + string $before = '\b', + string $after = '\b' + ): string { + // Limit if ($filter->limit > 0) { - $limit = array_key_exists($filter->id() . '_' . $p, self::$epcFilterLimit) ? self::$epcFilterLimit[$filter->id() . '_' . $p] : $filter->limit; + // memorize limit between two template values + $limit = array_key_exists($filter->id() . '_' . $search, self::$limits) ? self::$limits[$filter->id() . '_' . $search] : $filter->limit; if ($limit < 1) { - return $s; + return $content; } } else { $limit = -1; } - # Case sensitive - $i = $filter->nocase ? 'i' : ''; + + // Case sensitive + $caseless = $filter->nocase ? 'i' : ''; + # Plural - $x = $filter->plural ? $p . 's|' . $p : $p; + $plural = $filter->plural ? 's?' : ''; - # Mark words - $ret = preg_replace('#(' . $before . ')(' . $x . ')(' . $after . ')#su' . $i, '$1' . sprintf(self::FLAGGER, '$2') . '$3', $s, -1, $count); + // Mark words + $ret = preg_replace('#(' . $before . ')(' . $search . $plural . ')(' . $after . ')#su' . $caseless, '$1' . sprintf(self::FLAGGER, '$2') . '$3', $content, -1, $count); if (is_string($ret)) { - $s = $ret; + $content = $ret; } - # Nothing to parse + + // Nothing to parse if (!$count) { - return $s; + return $content; } - # Remove words that are into unwanted html tags - $ignore_tags = array_merge(self::decodeTags($filter->htmltag), self::decodeTags($filter->notag)); - if (!empty($ignore_tags)) { - $tags = implode('|', array_unique($ignore_tags)); - - $ret = preg_replace_callback('#(<(' . $tags . ')[^>]*?>)(.*?)()#s', [self::class, 'removeTags'], $s); + // Remove words that are into unwanted html tags + $ignore = array_merge(self::decodeSingle($filter->ignore), self::decodeSingle($filter->notag)); + if (!empty($ignore)) { + $ret = preg_replace_callback('#(<(' . implode('|', array_unique($ignore)) . ')[^>]*?>)(.*?)()#s', function (array $m): string { + return $m[1] . preg_replace('#' . sprintf(self::FLAGGER, '(?!') . ')#s', '$1', $m[3]) . $m[4]; + }, $content); if (is_string($ret)) { - $s = $ret; + $content = $ret; } } - # Remove words inside html tag (class, title, alt, href, ...) - $ret = preg_replace('#(' . sprintf(self::FLAGGER, '(' . $x . '(s|))') . ')(?=[^<]*>)#s' . $i, '$2$4', $s); + // Remove words inside html tag (class, title, alt, href, ...) + $ret = preg_replace('#(' . sprintf(self::FLAGGER, '(' . $search . '(' . $plural . '))') . ')(?=[^<]*>)#s' . $caseless, '$2$4', $content); if (is_string($ret)) { - $s = $ret; + $content = $ret; } - # Replace words by what you want (with limit) - $ret = preg_replace('#' . sprintf(self::FLAGGER, '(' . $p . '(s|))') . '#s' . $i, $r, $s, $limit, $count); + // Replace words by what you want (with limit) + $ret = preg_replace('#' . sprintf(self::FLAGGER, '(' . $search . '(' . $plural . '))') . '#s' . $caseless, $replacement, $content, $limit, $count); if (is_string($ret)) { - $s = $ret; + $content = $ret; } - # update limit - self::$epcFilterLimit[$filter->id() . '_' . $p] = $limit - $count; + // update limit + self::$limits[$filter->id() . '_' . $search] = $limit - $count; - # Clean rest - $ret = preg_replace('#' . sprintf(self::FLAGGER, '(.*?)') . '#s', '$1', $s); + // Clean rest + $ret = preg_replace('#' . sprintf(self::FLAGGER, '(.*?)') . '#s', '$1', $content); if (is_string($ret)) { - $s = $ret; + $content = $ret; } - return $s; + return $content; } - public static function matchString(string $p, string $r, string $s, EpcFilter $filter, string $before = '\b', string $after = '\b'): array - { - # Case sensitive - $i = $filter->nocase ? 'i' : ''; - # Plural - $x = $filter->plural ? $p . 's|' . $p : $p; - # Mark words - $t = preg_match_all('#' . $before . '(' . $x . ')' . $after . '#su' . $i, $s, $matches); - # Nothing to parse - if (!$t) { - return ['total' => 0, 'matches' => []]; - } - - # Build array - $m = []; - $loop = 0; - foreach ($matches[1] as $match) { - $m[$loop]['key'] = $match; - $m[$loop]['match'] = preg_replace('#(' . $p . '(s|))#s' . $i, $r, $match, -1, $count); - $m[$loop]['num'] = $count; - $loop++; - } - - return ['total' => $t, 'matches' => $m]; + /** + * Find filter on content. + * + * @param string $search The search + * @param string $replacement The replacement + * @param string $content The content + * @param EpcFilter $filter The filter + * @param string $before The start limit pattern + * @param string $after The end limit pattern + */ + public static function matchString( + string $search, + string $replacement, + string $content, + EpcFilter $filter, + string $before = '\b', + string $after = '\b' + ): array { + return [ + 'total' => (int) preg_match_all('#' . $before . '(' . $search . ($filter->plural ? 's?' : '') . ')' . $after . '#su' . ($filter->nocase ? 'i' : ''), $content), + 'search' => $search, + 'replacement' => preg_replace('#(' . $search . ')#', $replacement, $search), + ]; } - public static function quote(string $s): string + /** + * Quote regular expression according to epc parser. + * + * @param string $string The string + * + * @return string The quoted string + */ + public static function quote(string $string): string { - return preg_quote($s, '#'); + return preg_quote($string, '#'); } - public static function removeTags(array $m): string + /** + * Implode simple array into string a,b,c. + * + * @param array|string $values The values + * + * @return string The value + */ + public static function encodeSingle(array|string $values): string { - return $m[1] . preg_replace('#' . sprintf(self::FLAGGER, '(?!') . ')#s', '$1', $m[3]) . $m[4]; + return implode(',', self::decodeSingle($values)); } - public static function decodeTags(string $t): array + /** + * Explode string into simple array [a,b,c]. + * + * @param array|string $value The value + * + * @return array The values + */ + public static function decodeSingle(array|string $value): array { - return preg_match_all('#([A-Za-z0-9]+)#', (string) $t, $m) ? $m[1] : []; + if (is_array($value)) { + $value = implode(',', $value); + } + + return preg_match_all('#([A-Za-z0-9]+)#', (string) $value, $matches) ? $matches[1] : []; } - public static function implode(array|string $a): string + /** + * Implode complexe array into string a:aa:b:bb;c:cc. + * + * @param array|string $values The values + * + * @return string The value + */ + public static function encodeMulti(array|string $values): string { - if (is_string($a)) { - return $a; - } - if (!is_array($a)) { - return ''; + if (is_string($values)) { + return $values; } - $r = ''; - foreach ($a as $k => $v) { - $r .= $k . ':' . $v . ';'; + $string = ''; + foreach ($values as $key => $value) { + $string .= $key . ':' . $value . ';'; } - return $r; + return $string; } - public static function explode(array|string $s): array + /** + * Explode string into complexe array [a=>aa,b=>aa,c=>cc]. + * + * @param array|string $value The value + * + * @return array The values + */ + public static function decodeMulti(array|string $value): array { - if (is_array($s)) { - return $s; + if (is_array($value)) { + return $value; } - if (!is_string($s)) { + + $values = []; + $exp = explode(';', (string) $value); + if (!is_array($exp)) { return []; } - $r = []; - $s = explode(';', (string) $s); - if (!is_array($s)) { - return []; - } - - foreach ($s as $cpl) { + foreach ($exp as $cpl) { $cur = explode(':', $cpl); if (!is_array($cur) || !isset($cur[1])) { @@ -295,59 +360,75 @@ class Epc continue; } - $r[$key] = $val; + $values[$key] = $val; } - return $r; + return $values; } - # - # Widgets - # - - public static function widgetContentEntryExcerpt(?WidgetsElement $w = null): string + /** + * Send entries excerpts to widget. + * + * @param WidgetsElement|null $widget The widgets + * + * @return string The entries exceprts + */ + public static function widgetContentEntryExcerpt(?WidgetsElement $widget = null): string { if (is_null(dcCore::app()->ctx) || !dcCore::app()->ctx->exists('posts')) { return ''; } - $res = ''; + $content = ''; while (dcCore::app()->ctx->__get('posts')?->fetch()) { - $res .= dcCore::app()->ctx->__get('posts')->f('post_excerpt'); + $content .= dcCore::app()->ctx->__get('posts')->f('post_excerpt'); } - return $res; + return $content; } - public static function widgetContentEntryContent(): string + /** + * Send entries contents to widget. + * + * @param WidgetsElement|null $widget The widgets + * + * @return string The entries contents + */ + public static function widgetContentEntryContent(?WidgetsElement $widget = null): string { if (is_null(dcCore::app()->ctx) || !dcCore::app()->ctx->exists('posts')) { return ''; } - $res = ''; + $content = ''; while (dcCore::app()->ctx->__get('posts')?->fetch()) { - $res .= dcCore::app()->ctx->__get('posts')->f('post_content'); + $content .= dcCore::app()->ctx->__get('posts')->f('post_content'); } - return $res; + return $content; } - public static function widgetContentCommentContent(): string + /** + * Send entries comments to widget. + * + * @param WidgetsElement|null $widget The widgets + * + * @return string The entries comments + */ + public static function widgetContentCommentContent(?WidgetsElement $widget = null): string { if (is_null(dcCore::app()->ctx) || !dcCore::app()->ctx->exists('posts')) { return ''; } - $res = ''; - $post_ids = []; + $content = ''; while (dcCore::app()->ctx->__get('posts')?->fetch()) { $comments = dcCore::app()->blog?->getComments(['post_id' => dcCore::app()->ctx->__get('posts')->f('post_id')]); while ($comments?->fetch()) { - $res .= $comments->getContent(); + $content .= $comments->getContent(); } } - return $res; + return $content; } } diff --git a/src/EpcFilter.php b/src/EpcFilter.php index a36e83a..64ab3fd 100644 --- a/src/EpcFilter.php +++ b/src/EpcFilter.php @@ -20,31 +20,67 @@ use dcRecord; use Dotclear\Plugin\widgets\WidgetsElement; use Exception; +/** + * Filter abstract class. + * + * All filter must extends this class. + */ abstract class EpcFilter { + /** @var string $id The filter id */ protected string $id = 'undefined'; + /** @var dcRecord $records The filter record if any */ private ?dcRecord $records = null; - // properties + /** @var int $priority The filter priority (property) */ public readonly int $priority; + + /** @var string $name The filter name (property) */ public readonly string $name; - public readonly string $help; + + /** @var string $description The filter description (property) */ + public readonly string $description; + + /** @var bool $has_list Filter has list of records (property) */ public readonly bool $has_list; - public readonly string $htmltag; + + /** @var array $ignore The filter disabled html tags (property) */ + public readonly array $ignore; + + /** @var array $class The css class that apply to filter (property) */ public readonly array $class; + + /** @var string $replace The filter replacement bloc in content (property) */ public readonly string $replace; + + /** @var string $widget The filter replacement bloc in widget (property) */ public readonly string $widget; - // settings + /** @var bool $nocase The filter caseless match (settings) */ public readonly bool $nocase; - public readonly bool $plural; - public readonly int $limit; - public readonly array $style; - public readonly string $notag; - public readonly array $tplValues; - public readonly array $pubPages; + /** @var bool $plural The filter caseless match (settings) */ + public readonly bool $plural; + + /** @var bool $plural The replacement limit per filter (settings) */ + public readonly int $limit; + + /** @var array $style The style applied to filter class (settings) */ + public readonly array $style; + + /** @var array $notag The filter disabled html tags (settings) */ + public readonly array $notag; + + /** @var array $template The extra template value to scan (settings) */ + public readonly array $template; + + /** @var array $page The extra frontend pages to scan (settings) */ + public readonly array $page; + + /** + * Constructor sets filter properties and settings. + */ final public function __construct() { if ($this->id == 'undefined') { @@ -61,55 +97,66 @@ abstract class EpcFilter $settings = $this->initSettings(); // from filter defautl properties - $this->priority = isset($properties['priority']) ? abs((int) $properties['priority']) : 500; - $this->name = isset($properties['name']) ? (string) $properties['name'] : 'undefined'; - $this->help = isset($properties['help']) ? (string) $properties['help'] : 'undefined'; - $this->has_list = isset($properties['has_list']) ? (bool) $properties['has_list'] : false; - $this->htmltag = isset($properties['htmltag']) ? (string) $properties['htmltag'] : ''; - $this->class = isset($properties['class']) && is_array($properties['class']) ? $properties['class'] : []; - $this->replace = isset($properties['replace']) ? (string) $properties['replace'] : ''; - $this->widget = isset($properties['widget']) ? (string) $properties['widget'] : ''; + $this->priority = isset($properties['priority']) ? abs((int) $properties['priority']) : 500; + $this->name = isset($properties['name']) ? (string) $properties['name'] : 'undefined'; + $this->description = isset($properties['description']) ? (string) $properties['description'] : 'undefined'; + $this->has_list = isset($properties['has_list']) ? (bool) $properties['has_list'] : false; + $this->ignore = isset($properties['ignore']) && is_array($properties['ignore']) ? $properties['ignore'] : []; + $this->class = isset($properties['class']) && is_array($properties['class']) ? $properties['class'] : []; + $this->replace = isset($properties['replace']) ? (string) $properties['replace'] : ''; + $this->widget = isset($properties['widget']) ? (string) $properties['widget'] : ''; // from filter defautl settings - $nocase = isset($settings['nocase']) ? (bool) $settings['nocase'] : false; - $plural = isset($settings['plural']) ? (bool) $settings['plural'] : false; - $limit = isset($settings['limit']) ? abs((int) $settings['limit']) : 0; - $style = isset($settings['style']) && is_array($settings['style']) ? $settings['style'] : []; - $notag = isset($settings['notag']) ? (string) $settings['notag'] : ''; - $tplValues = isset($settings['tplValues']) && is_array($settings['tplValues']) ? $settings['tplValues'] : []; - $pubPages = isset($settings['pubPages']) && is_array($settings['pubPages']) ? $settings['pubPages'] : []; + $nocase = isset($settings['nocase']) ? (bool) $settings['nocase'] : false; + $plural = isset($settings['plural']) ? (bool) $settings['plural'] : false; + $limit = isset($settings['limit']) ? abs((int) $settings['limit']) : 0; + $style = isset($settings['style']) && is_array($settings['style']) ? $settings['style'] : []; + $notag = isset($settings['notag']) && is_array($settings['notag']) ? $settings['notag'] : []; + $template = isset($settings['template']) && is_array($settings['template']) ? $settings['template'] : []; + $page = isset($settings['page']) && is_array($settings['page']) ? $settings['page'] : []; // from blog settings - $this->nocase = isset($s['nocase']) ? (bool) $s['nocase'] : $nocase; - $this->plural = isset($s['plural']) ? (bool) $s['plural'] : $plural; - $this->limit = isset($s['limit']) ? abs((int) $s['limit']) : $limit; - $this->style = isset($s['style']) && is_array($s['style']) ? $s['style'] : $style; - $this->notag = isset($s['notag']) ? (string) $s['notag'] : $notag; - $this->tplValues = isset($s['tplValues']) && is_array($s['tplValues']) ? $s['tplValues'] : $tplValues; - $this->pubPages = isset($s['pubPages']) && is_array($s['pubPages']) ? $s['pubPages'] : $pubPages; + $this->nocase = isset($s['nocase']) ? (bool) $s['nocase'] : $nocase; + $this->plural = isset($s['plural']) ? (bool) $s['plural'] : $plural; + $this->limit = isset($s['limit']) ? abs((int) $s['limit']) : $limit; + $this->style = isset($s['style']) && is_array($s['style']) ? $s['style'] : $style; + $this->notag = isset($s['notag']) && is_array($s['notag']) ? $s['notag'] : $notag; + $this->template = isset($s['template']) && is_array($s['template']) ? $s['template'] : $template; + $this->page = isset($s['page']) && is_array($s['page']) ? $s['page'] : $page; } - protected function initProperties(): array - { - return []; - } + /** + * Return filter default properties. + * + * @return array The properties + */ + abstract protected function initProperties(): array; - protected function initSettings(): array - { - return []; - } - - public static function create(ArrayObject $o): void - { - $c = static::class; - $o->append(new $c()); - } + /** + * Return filter default settings. + * + * @return array The settings + */ + abstract protected function initSettings(): array; + /** + * Get fitler ID. + * + * @return string The filter ID + */ final public function id(): string { return $this->id; } + /** + * Get fitler record. + * + * Fitler records are usefull to store and retrieve + * list of keyword / replacement etc... + * + * @return dcRecord The filter record instance + */ final public function records(): dcRecord { if ($this->records === null && $this->has_list) { @@ -119,11 +166,27 @@ abstract class EpcFilter return $this->records ?? dcRecord::newFromArray([]); } + /** + * Filter frontend contents in situ. + * + * @param string $tag The tempale block tag + * @param array $args The template block arguments + */ public function publicContent(string $tag, array $args): void { } - public function widgetList(string $content, WidgetsElement $w, ArrayObject $list): void + /** + * Filter frontend contents for widgets. + * + * Filter the contents and return matching results infos + * into the list of current widget. + * + * @param string $content The contents + * @param WidgetsElement $widget The widget + * @param ArrayObject $list The list + */ + public function widgetList(string $content, WidgetsElement $widget, ArrayObject $list): void { } } diff --git a/src/EpcFilters.php b/src/EpcFilters.php index 8fb91a1..69fdfca 100644 --- a/src/EpcFilters.php +++ b/src/EpcFilters.php @@ -67,7 +67,7 @@ class EpcFilters { $nid = []; foreach ($this->stack as $filter) { - if ($filter->widget != '') { + if (!$exclude_widget || $filter->widget != '') { $nid[$filter->name] = $filter->id(); } } @@ -76,13 +76,17 @@ class EpcFilters } /** - * Sort filters stack by filter name. + * Sort filters stack by filter name or priority. * * @return EpcFilters The filters instance */ - public function sort(): EpcFilters + public function sort(bool $by_name = false): EpcFilters { - uasort($this->stack, fn ($a, $b) => $a->name <=> $b->name); + if ($by_name) { + uasort($this->stack, fn ($a, $b) => $a->name <=> $b->name); + } else { + uasort($this->stack, fn ($a, $b) => $a->priority <=> $b->priority); + } return $this; } diff --git a/src/EpcRecord.php b/src/EpcRecord.php index 2b35234..cf50647 100644 --- a/src/EpcRecord.php +++ b/src/EpcRecord.php @@ -19,8 +19,19 @@ use dcCore; use dcRecord; use Exception; +/** + * Filter records. + */ class EpcRecord { + /** + * Get records. + * + * @param array $params The query params + * @param bool $count_only Count only + * + * @return dcRecord The records instance + */ public static function getRecords(array $params, bool $count_only = false): dcRecord { if ($count_only) { @@ -99,6 +110,13 @@ class EpcRecord return new dcRecord(dcCore::app()->con->select($strReq)); } + /** + * Add record. + * + * @param cursor $cur The cursor + * + * @return int The record ID + */ public static function addRecord(cursor $cur): int { dcCore::app()->con->writeLock(dcCore::app()->prefix . My::TABLE_NAME); @@ -117,7 +135,7 @@ class EpcRecord throw $e; } - self::trigger(); + dcCore::app()->blog?->triggerBlog(); # --BEHAVIOR-- enhancePostContentAfterAddRecord : cursor dcCore::app()->callBehavior('enhancePostContentAfterAddRecord', $cur); @@ -125,6 +143,12 @@ class EpcRecord return (int) $cur->getField('epc_id'); } + /** + * Update a record. + * + * @param int $id The record ID + * @param cursor $cur The cursor + */ public static function updRecord(int $id, cursor $cur): void { if (empty($id)) { @@ -134,12 +158,21 @@ class EpcRecord $cur->setField('epc_upddt', date('Y-m-d H:i:s')); $cur->update('WHERE epc_id = ' . $id . " AND blog_id = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id) . "' "); - self::trigger(); + dcCore::app()->blog?->triggerBlog(); # --BEHAVIOR-- enhancePostContentAfterUpdRecord : cursor, int dcCore::app()->callBehavior('enhancePostContentAfterUpdRecord', $cur, $id); } + /** + * Check if a record exists. + * + * @param null|string $filter The filter ID + * @param null|string $key The record key + * @param null|int $not_id Exclude an id + * + * @return bool True if it exists + */ public static function isRecord(?string $filter, ?string $key, ?int $not_id = null): bool { return 0 < self::getRecords([ @@ -149,6 +182,11 @@ class EpcRecord ], true)->f(0); } + /** + * Delete a record. + * + * @param int $id The record ID + */ public static function delRecord(int $id): void { if (empty($id)) { @@ -164,9 +202,14 @@ class EpcRecord "AND blog_id = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id) . "' " ); - self::trigger(); + dcCore::app()->blog?->triggerBlog(); } + /** + * Get next record ID. + * + * @return int The next record ID + */ private static function getNextId(): int { return (int) dcCore::app()->con->select( @@ -174,11 +217,21 @@ class EpcRecord )->f(0) + 1; } + /** + * Open filter cursor. + * + * @return cursor The cursor + */ public static function openCursor(): cursor { return dcCore::app()->con->openCursor(dcCore::app()->prefix . My::TABLE_NAME); } + /** + * Clean up a cursor. + * + * @param cursor $cur The cursor + */ private static function getCursor(cursor $cur): void { if ($cur->getField('epc_key') == '') { @@ -191,9 +244,4 @@ class EpcRecord throw new Exception(__('No record filter')); } } - - private static function trigger(): void - { - dcCore::app()->blog?->triggerBlog(); - } } diff --git a/src/Filter/EpcFilterAbbreviation.php b/src/Filter/EpcFilterAbbreviation.php index 65dc0b7..e336d2a 100644 --- a/src/Filter/EpcFilterAbbreviation.php +++ b/src/Filter/EpcFilterAbbreviation.php @@ -26,24 +26,24 @@ class EpcFilterAbbreviation extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 400, - 'name' => __('Abbreviation'), - 'help' => __('Explain some abbreviation. First term of the list is the abbreviation and second term the explanation.'), - 'has_list' => true, - 'htmltag' => 'pre,code,a', - 'class' => ['abbr.epc-abbr'], - 'replace' => '%s', - 'widget' => '%s', + 'priority' => 400, + 'name' => __('Abbreviation'), + 'description' => __('Explain some abbreviation. First term of the list is the abbreviation and second term the explanation.'), + 'has_list' => true, + 'ignore' => ['pre','code','a'], + 'class' => ['abbr.epc-abbr'], + 'replace' => '%s', + 'widget' => '%s', ]; } protected function initSettings(): array { return [ - 'style' => ['font-weight: bold;'], - 'notag' => 'a,acronym,abbr,dfn,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'style' => ['font-weight: bold;'], + 'notag' => ['acronym','abbr','dfn','h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterAcronym.php b/src/Filter/EpcFilterAcronym.php index 91ca1eb..11f52b1 100644 --- a/src/Filter/EpcFilterAcronym.php +++ b/src/Filter/EpcFilterAcronym.php @@ -26,24 +26,24 @@ class EpcFilterAcronym extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 700, - 'name' => __('Acronym'), - 'help' => __('Explain some acronyms. First term of the list is the acornym and second term the explanation.'), - 'has_list' => true, - 'htmltag' => 'pre,code,acronym', - 'class' => ['acronym.epc-acronym'], - 'replace' => '%s', - 'widget' => '%s', + 'priority' => 700, + 'name' => __('Acronym'), + 'description' => __('Explain some acronyms. First term of the list is the acornym and second term the explanation.'), + 'has_list' => true, + 'ignore' => ['pre','code','acronym'], + 'class' => ['acronym.epc-acronym'], + 'replace' => '%s', + 'widget' => '%s', ]; } protected function initSettings(): array { return [ - 'style' => ['font-weight: bold;'], - 'notag' => 'a,acronym,abbr,dfn,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'style' => ['font-weight: bold;'], + 'notag' => ['a','acronym','abbr','dfn','h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterCitation.php b/src/Filter/EpcFilterCitation.php index bc8b275..ffba217 100644 --- a/src/Filter/EpcFilterCitation.php +++ b/src/Filter/EpcFilterCitation.php @@ -26,25 +26,25 @@ class EpcFilterCitation extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 600, - 'name' => __('Citation'), - 'help' => __('Highlight citation of people. First term of the list is the citation and second term the author.'), - 'has_list' => true, - 'htmltag' => 'pre,code,cite', - 'class' => ['cite.epc-cite'], - 'replace' => '%s', - 'widget' => '%s', + 'priority' => 600, + 'name' => __('Citation'), + 'description' => __('Highlight citation of people. First term of the list is the citation and second term the author.'), + 'has_list' => true, + 'ignore' => ['pre','code','cite'], + 'class' => ['cite.epc-cite'], + 'replace' => '%s', + 'widget' => '%s', ]; } protected function initSettings(): array { return [ - 'nocase' => true, - 'style' => ['font-style: italic;'], - 'notag' => 'a,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'nocase' => true, + 'style' => ['font-style: italic;'], + 'notag' => ['a','h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterDefinition.php b/src/Filter/EpcFilterDefinition.php index 8c273d3..bf97430 100644 --- a/src/Filter/EpcFilterDefinition.php +++ b/src/Filter/EpcFilterDefinition.php @@ -26,24 +26,24 @@ class EpcFilterDefinition extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 800, - 'name' => __('Definition'), - 'help' => __('Explain some definition. First term of the list is the sample to define and second term the explanation.'), - 'has_list' => true, - 'htmltag' => 'pre,code,dfn', - 'class' => ['dfn.epc-dfn'], - 'replace' => '%s', - 'widget' => '%s', + 'priority' => 800, + 'name' => __('Definition'), + 'description' => __('Explain some definition. First term of the list is the sample to define and second term the explanation.'), + 'has_list' => true, + 'ignore' => ['pre','code','dfn'], + 'class' => ['dfn.epc-dfn'], + 'replace' => '%s', + 'widget' => '%s', ]; } protected function initSettings(): array { return [ - 'style' => ['font-weight: bold;'], - 'notag' => 'a,acronym,abbr,dfn,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'style' => ['font-weight: bold;'], + 'notag' => ['a','acronym','abbr','dfn','h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterLink.php b/src/Filter/EpcFilterLink.php index cabe8f2..3965605 100644 --- a/src/Filter/EpcFilterLink.php +++ b/src/Filter/EpcFilterLink.php @@ -26,24 +26,24 @@ class EpcFilterLink extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 500, - 'name' => __('Link'), - 'help' => __('Link some words. First term of the list is the term to link and second term the link.'), - 'has_list' => true, - 'htmltag' => 'pre,code,a', - 'class' => ['a.epc-link'], - 'replace' => '%s', - 'widget' => '%s', + 'priority' => 500, + 'name' => __('Link'), + 'description' => __('Link some words. First term of the list is the term to link and second term the link.'), + 'has_list' => true, + 'ignore' => ['pre','code','a'], + 'class' => ['a.epc-link'], + 'replace' => '%s', + 'widget' => '%s', ]; } protected function initSettings(): array { return [ - 'style' => ['text-decoration: none; font-style: italic; color: #0000FF;'], - 'notag' => 'a,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'style' => ['text-decoration: none; font-style: italic; color: #0000FF;'], + 'notag' => ['h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterReplace.php b/src/Filter/EpcFilterReplace.php index ed88e50..9722dc2 100644 --- a/src/Filter/EpcFilterReplace.php +++ b/src/Filter/EpcFilterReplace.php @@ -24,25 +24,25 @@ class EpcFilterReplace extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 200, - 'name' => __('Replace'), - 'help' => __('Replace some text. First term of the list is the text to replace and second term the replacement.'), - 'has_list' => true, - 'htmltag' => 'pre,code', - 'class' => ['span.epc-replace'], - 'replace' => '%s', + 'priority' => 200, + 'name' => __('Replace'), + 'description' => __('Replace some text. First term of the list is the text to replace and second term the replacement.'), + 'has_list' => true, + 'ignore' => ['pre','code'], + 'class' => ['span.epc-replace'], + 'replace' => '%s', ]; } protected function initSettings(): array { return [ - 'nocase' => true, - 'plural' => true, - 'style' => ['font-style: italic;'], - 'notag' => 'h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'nocase' => true, + 'plural' => true, + 'style' => ['font-style: italic;'], + 'notag' => ['h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterSearch.php b/src/Filter/EpcFilterSearch.php index 3d629ea..b499e53 100644 --- a/src/Filter/EpcFilterSearch.php +++ b/src/Filter/EpcFilterSearch.php @@ -25,12 +25,12 @@ class EpcFilterSearch extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 100, - 'name' => __('Search'), - 'help' => __('Highlight searched words.'), - 'htmltag' => '', - 'class' => ['span.epc-search'], - 'replace' => '%s', + 'priority' => 100, + 'name' => __('Search'), + 'description' => __('Highlight searched words.'), + 'ignore' => [], + 'class' => ['span.epc-search'], + 'replace' => '%s', ]; } @@ -40,9 +40,9 @@ class EpcFilterSearch extends EpcFilter 'nocase' => true, 'plural' => true, 'style' => ['color: #FFCC66;'], - 'notag' => 'h1,h2,h3', + 'notag' => ['h1','h2','h3'], 'tplValues' => ['EntryContent'], - 'pubPages' => ['search.html'], + 'page' => ['search.html'], ]; } diff --git a/src/Filter/EpcFilterTag.php b/src/Filter/EpcFilterTag.php index f5b091f..fecd735 100644 --- a/src/Filter/EpcFilterTag.php +++ b/src/Filter/EpcFilterTag.php @@ -27,23 +27,23 @@ class EpcFilterTag extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 900, - 'name' => __('Tag'), - 'help' => __('Highlight tags of your blog.'), - 'htmltag' => 'pre,code,a', - 'class' => ['a.epc-tag'], - 'replace' => '%s', - 'widget' => '%s', + 'priority' => 900, + 'name' => __('Tag'), + 'description' => __('Highlight tags of your blog.'), + 'ignore' => ['pre','code','a'], + 'class' => ['a.epc-tag'], + 'replace' => '%s', + 'widget' => '%s', ]; } protected function initSettings(): array { return [ - 'style' => ['text-decoration: none; border-bottom: 3px double #CCCCCC;'], - 'notag' => 'pre,code,a,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'style' => ['text-decoration: none; border-bottom: 3px double #CCCCCC;'], + 'notag' => ['h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterTwitter.php b/src/Filter/EpcFilterTwitter.php index b571c15..4c9f4f0 100644 --- a/src/Filter/EpcFilterTwitter.php +++ b/src/Filter/EpcFilterTwitter.php @@ -24,22 +24,22 @@ class EpcFilterTwitter extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 1000, - 'name' => __('Twitter'), - 'help' => __('Add link to twitter user page. Every word started with "@" will be considered as twitter user.'), - 'htmltag' => 'pre,code,a', - 'class' => ['a.epc-twitter'], - 'replace' => '', + 'priority' => 1000, + 'name' => __('Twitter'), + 'description' => __('Add link to twitter user page. Every word started with "@" will be considered as twitter user.'), + 'ingore' => ['pre','code','a'], + 'class' => ['a.epc-twitter'], + 'replace' => '', ]; } protected function initSettings(): array { return [ - 'style' => ['text-decoration: none; font-weight: bold; font-style: italic; color: #0000FF;'], - 'notag' => 'a,h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'style' => ['text-decoration: none; font-weight: bold; font-style: italic; color: #0000FF;'], + 'notag' => ['h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Filter/EpcFilterUpdate.php b/src/Filter/EpcFilterUpdate.php index 391ad55..432f787 100644 --- a/src/Filter/EpcFilterUpdate.php +++ b/src/Filter/EpcFilterUpdate.php @@ -24,25 +24,25 @@ class EpcFilterUpdate extends EpcFilter protected function initProperties(): array { return [ - 'priority' => 300, - 'name' => __('Update'), - 'help' => __('Update and show terms. First term of the list is the term to update and second term the new term.'), - 'has_list' => true, - 'htmltag' => 'pre,code,del,ins', - 'class' => ['del.epc-update', 'ins.epc-update'], - 'replace' => '%s %s', + 'priority' => 300, + 'name' => __('Update'), + 'description' => __('Update and show terms. First term of the list is the term to update and second term the new term.'), + 'has_list' => true, + 'ignore' => ['pre','code','del','ins'], + 'class' => ['del.epc-update', 'ins.epc-update'], + 'replace' => '%s %s', ]; } protected function initSettings(): array { return [ - 'nocase' => true, - 'plural' => true, - 'style' => ['text-decoration: line-through;', 'font-style: italic;'], - 'notag' => 'h1,h2,h3', - 'tplValues' => ['EntryContent'], - 'pubPages' => ['post.html'], + 'nocase' => true, + 'plural' => true, + 'style' => ['text-decoration: line-through;', 'font-style: italic;'], + 'notag' => ['h1','h2','h3'], + 'template' => ['EntryContent'], + 'page' => ['post.html'], ]; } diff --git a/src/Frontend.php b/src/Frontend.php index c19cb62..6099393 100644 --- a/src/Frontend.php +++ b/src/Frontend.php @@ -38,17 +38,24 @@ class Frontend extends dcNsProcess } dcCore::app()->addBehaviors([ - // add CSS URL to header + // Add CSS URL to frontend header 'publicHeadContent' => function (): void { echo dcUtils::cssLoad(dcCore::app()->blog?->url . dcCore::app()->url->getURLFor('epccss')); }, // Filter template blocks content 'publicBeforeContentFilterV2' => function (string $tag, array $args): void { foreach (Epc::getFilters()->dump() as $filter) { - if (!Epc::testContext($tag, $args, $filter)) { - continue; + // test context + if (in_array((string) dcCore::app()->ctx?->__get('current_tpl'), $filter->page) + && in_array($tag, $filter->template) + && $args[0] != '' //content + && empty($args['encode_xml']) + && empty($args['encode_html']) + && empty($args['remove_html']) + && empty($args['strip_tags']) + ) { + $filter->publicContent($tag, $args); } - $filter->publicContent($tag, $args); } }, // Widgets diff --git a/src/Install.php b/src/Install.php index 14c214f..1a4a680 100644 --- a/src/Install.php +++ b/src/Install.php @@ -71,19 +71,19 @@ class Install extends dcNsProcess $s->put('list_sortby', 'epc_key', 'string', 'Admin records list field order', false, true); $s->put('list_order', 'desc', 'string', 'Admin records list order', false, true); $s->put('list_nb', 20, 'integer', 'Admin records list nb per page', false, true); - $s->put('allowedtplvalues', json_encode(Epc::defaultAllowedTplValues()), 'string', 'List of allowed template values', false, true); - $s->put('allowedpubpages', json_encode(Epc::defaultAllowedPubPages()), 'string', 'List of allowed template pages', false, true); + $s->put('allowedtplvalues', json_encode(Epc::defaultAllowedTemplateValue()), 'string', 'List of allowed template values', false, true); + $s->put('allowedpubpages', json_encode(Epc::defaultAllowedTemplatePage()), 'string', 'List of allowed template pages', false, true); // Filters settings foreach (Epc::getFilters()->dump() as $filter) { // Only editable options $opt = [ - 'nocase' => $filter->nocase, - 'plural' => $filter->plural, - 'style' => $filter->style, - 'notag' => $filter->notag, - 'tplValues' => $filter->tplValues, - 'pubPages' => $filter->pubPages, + 'nocase' => $filter->nocase, + 'plural' => $filter->plural, + 'style' => $filter->style, + 'notag' => $filter->notag, + 'template' => $filter->template, + 'page' => $filter->page, ]; $s->put($filter->id(), json_encode($opt), 'string', 'Settings for ' . $filter->id(), false, true); } @@ -114,10 +114,12 @@ class Install extends dcNsProcess if ($current && version_compare($current, '2022.11.20', '<=')) { self::upTo20221120(); } + + // 2023.04.22: not replaced: tplValues->template and pubPages->page } /** - * 0.6.6 + * Upgrade from 0.6.6 * * - filters move from settings to dedicated table */ @@ -150,7 +152,7 @@ class Install extends dcNsProcess } /** - * 2021.10.06 + * Upgrade from 2021.10.06 * * - filters change name to id */ @@ -169,7 +171,7 @@ class Install extends dcNsProcess } /** - * 2022.11.20 + * Upgrade from 2022.11.20 * * - setting id changes to shorter one, * - setting ns changes to abstract one (no real changes), diff --git a/src/Manage.php b/src/Manage.php index 58126ee..387fe04 100644 --- a/src/Manage.php +++ b/src/Manage.php @@ -57,37 +57,41 @@ class Manage extends dcNsProcess return false; } + // nullsafe check if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) { return false; } + // get filter and post values $action = $_POST['action'] ?? ''; $filter = Epc::getFilters()->get($_REQUEST['part'] ?? ''); if (is_null($filter)) { return true; } + // check errors if (dcCore::app()->error->flag()) { return true; } + // open save to other plugins if (!empty($action)) { # --BEHAVIOR-- enhancePostContentAdminSave dcCore::app()->callBehavior('enhancePostContentAdminSave'); } try { - # Update filter settings + // Update filter settings if ($action == 'savefiltersetting') { # Parse filters options $f = [ - 'nocase' => !empty($_POST['filter_nocase']), - 'plural' => !empty($_POST['filter_plural']), - 'limit' => abs((int) $_POST['filter_limit']), - 'style' => (array) $_POST['filter_style'], - 'notag' => (string) $_POST['filter_notag'], - 'tplValues' => (array) $_POST['filter_tplValues'], - 'pubPages' => (array) $_POST['filter_pubPages'], + 'nocase' => !empty($_POST['filter_nocase']), + 'plural' => !empty($_POST['filter_plural']), + 'limit' => abs((int) $_POST['filter_limit']), + 'style' => (array) $_POST['filter_style'], + 'notag' => Epc::decodeSingle($_POST['filter_notag']), + 'template' => (array) $_POST['filter_template'], + 'page' => (array) $_POST['filter_page'], ]; dcCore::app()->blog->settings->get(My::id())->put($filter->id(), json_encode($f)); @@ -105,7 +109,7 @@ class Manage extends dcNsProcess ); } - # Add new filter record + // Add new filter record if ($action == 'savenewrecord' && !empty($_POST['new_key']) && !empty($_POST['new_value']) @@ -133,7 +137,7 @@ class Manage extends dcNsProcess ); } - # Update filter records + // Update filter records if ($action == 'deleterecords' && $filter->has_list && !empty($_POST['epc_id']) @@ -172,17 +176,22 @@ class Manage extends dcNsProcess return; } + // nullsafe check if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) { return; } + // get filters $filters = Epc::getFilters(); $filter = $filters->get($_REQUEST['part'] ?? 'link'); if (is_null($filter)) { return; } - # -- Prepare page -- + // sort filters by name on backend + Epc::getFilters()->sort(true); + + // Prepare tabs and lists $header = ''; if ($filter->has_list) { $sorts = new adminGenericFilterV2('epc'); @@ -203,7 +212,7 @@ class Manage extends dcNsProcess $header = $sorts->js(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => $filter->id()], '&') . '#record'); } - # Page headers + // display dcPage::openModule( My::name(), dcPage::jsPageTabs() . @@ -214,7 +223,6 @@ class Manage extends dcNsProcess dcCore::app()->callBehavior('enhancePostContentAdminHeader') ); - # Page title echo dcPage::breadcrumb([ __('Plugins') => '', @@ -223,7 +231,7 @@ class Manage extends dcNsProcess ]) . dcPage::notices(); - # Filters select menu list + // filters select menu echo (new Form('filters_menu'))->method('get')->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->fields([ (new Para())->class('anchor-nav')->items([ @@ -233,25 +241,25 @@ class Manage extends dcNsProcess ]), ])->render(); - # Filter title and description + // selected filter echo '

' . $filter->name . '

' . - '

' . $filter->help . '

'; + '

' . $filter->description . '

'; - # Filter settings + // Filter settings $form_pages = [(new Text('h4', __('Pages to be filtered')))]; - foreach (Epc::blogAllowedPubPages() as $k => $v) { + foreach (Epc::blogAllowedTemplatePage() as $k => $v) { $form_pages[] = (new Para())->items([ - (new Checkbox(['filter_pubPages[]', 'filter_pubPages' . $v], in_array($v, $filter->pubPages)))->value($v), - (new Label(__($k), Label::OUTSIDE_LABEL_AFTER))->for('filter_pubPages' . $v)->class('classic'), + (new Checkbox(['filter_page[]', 'filter_page' . $v], in_array($v, $filter->page)))->value($v), + (new Label(__($k), Label::OUTSIDE_LABEL_AFTER))->for('filter_page' . $v)->class('classic'), ]); } $form_values = [(new Text('h4', __('Contents to be filtered')))]; - foreach (Epc::blogAllowedTplValues() as $k => $v) { + foreach (Epc::blogAllowedTemplateValue() as $k => $v) { $form_values[] = (new Para())->items([ - (new Checkbox(['filter_tplValues[]', 'filter_tplValues' . $v], in_array($v, $filter->tplValues)))->value($v), - (new Label(__($k), Label::OUTSIDE_LABEL_AFTER))->for('filter_tplValues' . $v)->class('classic'), + (new Checkbox(['filter_template[]', 'filter_template' . $v], in_array($v, $filter->template)))->value($v), + (new Label(__($k), Label::OUTSIDE_LABEL_AFTER))->for('filter_template' . $v)->class('classic'), ]); } @@ -288,9 +296,9 @@ class Manage extends dcNsProcess (new Note())->class('form-note')->text(sprintf(__('The inserted HTML tag looks like: %s'), Html::escapeHTML(str_replace('%s', '...', $filter->replace)))), (new Para())->items([ (new Label(__('Ignore HTML tags:'), Label::OUTSIDE_LABEL_BEFORE))->for('filter_notag'), - (new Input('filter_notag'))->size(60)->maxlenght(255)->value(Html::escapeHTML($filter->notag)), + (new Input('filter_notag'))->size(60)->maxlenght(255)->value(Epc::encodeSingle($filter->notag)), ]), - (new Note())->class('form-note')->text(__('This is the list of HTML tags where content will be ignored.') . ' ' . ('' != $filter->htmltag ? '' : sprintf(__('Tag "%s" always be ignored.'), $filter->htmltag))), + (new Note())->class('form-note')->text(__('This is the list of HTML tags where content will be ignored.') . '
' . (empty($filter->ignore) ? '' : sprintf(__('Tags "%s" will allways be ignored.'), Epc::encodeSingle($filter->ignore)))), ])), (new Div())->class('clear')->items([ @@ -302,7 +310,7 @@ class Manage extends dcNsProcess ]), ])->render(); - # Filter records list + // Filter records list (if any) if ($filter->has_list && isset($pager)) { $pager_url = dcCore::app()->adminurl->get('admin.plugin.' . My::id(), array_diff_key($sorts->values(true), ['page' => ''])) . '&page=%s#record'; @@ -335,7 +343,7 @@ class Manage extends dcNsProcess echo ''; - # New record + // New record echo (new Div('newrecord'))->class('multi-part')->title(__('New record'))->items([ (new Form('form-create'))->method('post')->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()) . '#record')->fields([ diff --git a/src/Widgets.php b/src/Widgets.php index f19cd76..b36f28f 100644 --- a/src/Widgets.php +++ b/src/Widgets.php @@ -59,10 +59,10 @@ class Widgets Epc::getFilters()->nid(true) ); # Content - foreach (Epc::defaultAllowedWidgetValues() as $k => $v) { + foreach (Epc::widgetAllowedTemplateValue() as $name => $info) { $w->epclist->setting( - 'content' . $v['id'], - sprintf(__('Enable filter on %s'), __($k)), + 'content' . $info['id'], + sprintf(__('Enable filter on %s'), __($name)), 1, 'check' ); @@ -101,11 +101,11 @@ class Widgets # Content $content = ''; - foreach (Epc::defaultAllowedWidgetValues() as $k => $v) { - $ns = 'content' . $v['id']; - if ($w->$ns && is_callable($v['cb'])) { + foreach (Epc::widgetAllowedTemplateValue() as $info) { + $ns = 'content' . $info['id']; + if ($w->$ns && is_callable($info['cb'])) { $content .= call_user_func( - $v['cb'], + $info['cb'], $w ); } @@ -130,11 +130,11 @@ class Widgets # Parse result $res = ''; foreach ($list as $line) { - if (empty($line['matches'][0]['match'])) { + if ((int) $line['total'] == 0) { continue; } - $res .= '
  • ' . $line['matches'][0]['match'] . + $res .= '
  • ' . $line['replacement'] . ($w->show_total ? ' (' . $line['total'] . ')' : '') . '
  • '; }