Alpha update
This commit is contained in:
parent
3a568602da
commit
a06cdba30e
28 changed files with 615 additions and 589 deletions
0
README.md
Normal file → Executable file
0
README.md
Normal file → Executable file
|
|
@ -4,18 +4,18 @@ namespace pedodev\tagging\acp;
|
|||
|
||||
class main_info
|
||||
{
|
||||
public function module()
|
||||
{
|
||||
return [
|
||||
'filename' => '\pedodev\tagging\acp\main_module',
|
||||
'title' => 'ACP_TAGGING_TITLE',
|
||||
'modes' => [
|
||||
'settings' => [
|
||||
'title' => 'ACP_TAGGING_SETTINGS',
|
||||
'auth' => 'ext_pedodev/tagging && acl_a_board',
|
||||
'cat' => ['ACP_TAGGING_TITLE'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
public function module()
|
||||
{
|
||||
return [
|
||||
'filename' => '\pedodev\tagging\acp\main_module',
|
||||
'title' => 'ACP_TAGGING_TITLE',
|
||||
'modes' => [
|
||||
'settings' => [
|
||||
'title' => 'ACP_TAGGING_SETTINGS',
|
||||
'auth' => 'ext_pedodev/tagging && acl_a_board',
|
||||
'cat' => ['ACP_TAGGING_TITLE'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ use phpbb\request\request_interface;
|
|||
|
||||
class main_module
|
||||
{
|
||||
public $u_action, $tpl_name, $page_title;
|
||||
private $config, $request, $template, $user, $language, $tag_helper;
|
||||
private array $tag_list;
|
||||
private string $tag_list_filepath;
|
||||
public $u_action, $tpl_name, $page_title;
|
||||
private $config, $request, $template, $user, $language, $tag_helper;
|
||||
private array $tag_list;
|
||||
private string $tag_list_filepath;
|
||||
private bool $tag_search_available;
|
||||
|
||||
public function main(string $id, string $mode): void
|
||||
{
|
||||
public function main(string $id, string $mode): void
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
$this->config = $phpbb_container->get('config');
|
||||
|
|
@ -23,8 +24,9 @@ class main_module
|
|||
$this->tag_helper = $phpbb_container->get('pedodev.tagging.tag_helper');
|
||||
|
||||
$this->page_title = $this->language->lang('ACP_TAGGING_TITLE');
|
||||
$this->tpl_name = 'acp_tagging_body';
|
||||
$this->tag_list = $this->tag_helper->get_tag_list();
|
||||
$this->tpl_name = 'acp_tagging_body';
|
||||
$this->tag_list = $this->tag_helper->get_tag_list();
|
||||
$this->tag_search_available = ($this->config['search_type'] == '\phpbb\search\fulltext_native' or $this->config['search_type'] == '\phpbb\search\fulltext_mysql');
|
||||
|
||||
$action = $this->request->variable('action', '', $super_global = request_interface::GET);
|
||||
|
||||
|
|
@ -43,12 +45,21 @@ class main_module
|
|||
$this->load_main_page();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function load_edit_page()
|
||||
{
|
||||
$form_key = 'pedodev_tagging_edit_tag';
|
||||
}
|
||||
|
||||
private function get_tag_data(): array
|
||||
{
|
||||
return array(
|
||||
'title' => $this->request->variable('tagging_tagtitle', ''),
|
||||
'color' => ltrim($this->request->variable('tagging_tagcolor', ''), '#'),
|
||||
'active' => $this->request->variable('tagging_tagactive', false),
|
||||
'searchable' => $this->request->variable('tagging_tagsearchable', false),
|
||||
);
|
||||
}
|
||||
|
||||
private function load_edit_page(): void
|
||||
{
|
||||
$form_key = 'pedodev_tagging_edit_tag';
|
||||
add_form_key($form_key);
|
||||
|
||||
$tag_id = $this->request->variable('tag', -1, request_interface::GET);
|
||||
|
|
@ -59,43 +70,70 @@ class main_module
|
|||
}
|
||||
|
||||
if ($this->request->is_set_post('submit'))
|
||||
{
|
||||
$this->check_form_key($form_key);
|
||||
{
|
||||
$this->check_form_key($form_key);
|
||||
|
||||
$tag_data = array(
|
||||
'title' => $this->request->variable('tagging_tagtitle', ''),
|
||||
'color' => $this->request->variable('tagging_tagcolor', ''),
|
||||
'active' => $this->request->variable('tagging_tagactive', false),
|
||||
'searchable' => $this->request->variable('tagging_tagsearchable', false),
|
||||
);
|
||||
|
||||
if (empty($tag_data['title']) || empty($tag_data['color']))
|
||||
{
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_EMPTY') . adm_back_link($this->u_action));
|
||||
}
|
||||
$tag_data = $this->get_tag_data();
|
||||
|
||||
$this->tag_list[$tag_id] = $tag_data;
|
||||
if (!$this->tag_helper->validate_tag($tag_data))
|
||||
{
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_INVALID') . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$this->tag_list[$tag_id] = $tag_data;
|
||||
$this->tag_helper->update_tag_list($this->tag_list);
|
||||
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_EDITED', $tag_data['title']) . adm_back_link($this->u_action));
|
||||
}
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_EDITED', $tag_data['title']) . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$tag = $this->tag_list[$tag_id];
|
||||
$tag = $this->tag_list[$tag_id];
|
||||
|
||||
$this->template->assign_vars([
|
||||
'EDIT' => 1,
|
||||
'EDIT' => 1,
|
||||
'TAGGING_PAGE_TITLE' => $this->language->lang('ACP_TAGGING_SETTINGS_EDIT'),
|
||||
'EDIT_TAG_NAME' => $tag['title'],
|
||||
'TAG_COLOR' => $tag['color'],
|
||||
'TAG_ACTIVE' => $tag['active'],
|
||||
'TAG_SEARCHABLE' => $tag['searchable'],
|
||||
'EDIT_TAG_NAME' => $tag['title'],
|
||||
'TAG_COLOR' => $tag['color'],
|
||||
'TAG_ACTIVE' => $tag['active'],
|
||||
'TAG_SEARCHABLE' => $tag['searchable'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function load_delete_page()
|
||||
{
|
||||
$form_key = 'pedodev_tagging_delete_tag';
|
||||
private function load_add_page(): void
|
||||
{
|
||||
$form_key = 'pedodev_tagging_add_tag';
|
||||
add_form_key($form_key);
|
||||
|
||||
if ($this->request->is_set_post('submit'))
|
||||
{
|
||||
$this->check_form_key($form_key);
|
||||
|
||||
$tag_data = $this->get_tag_data();
|
||||
|
||||
if (!$this->tag_helper->validate_tag($tag_data))
|
||||
{
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_INVALID') . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$this->tag_list[] = $tag_data;
|
||||
$this->tag_helper->update_tag_list($this->tag_list);
|
||||
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_ADDED', $tag_data['title']) . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$random_color = substr(md5(rand()), 0, 6);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'EDIT' => 1,
|
||||
'TAGGING_PAGE_TITLE' => $this->language->lang('ACP_TAGGING_SETTINGS_ADD'),
|
||||
'TAG_COLOR' => $random_color,
|
||||
'TAG_ACTIVE' => true,
|
||||
'TAG_SEARCHABLE' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
private function load_delete_page(): void
|
||||
{
|
||||
$form_key = 'pedodev_tagging_delete_tag';
|
||||
add_form_key($form_key);
|
||||
|
||||
$tag_id = $this->request->variable('tag', -1, request_interface::GET);
|
||||
|
|
@ -108,14 +146,14 @@ class main_module
|
|||
$tag = $this->tag_list[$tag_id];
|
||||
|
||||
if ($this->request->is_set_post('submit'))
|
||||
{
|
||||
$this->check_form_key($form_key);
|
||||
{
|
||||
$this->check_form_key($form_key);
|
||||
|
||||
unset($this->tag_list[$tag_id]);
|
||||
unset($this->tag_list[$tag_id]);
|
||||
$this->tag_helper->update_tag_list($this->tag_list);
|
||||
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_DELETED', $tag['title']) . adm_back_link($this->u_action));
|
||||
}
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_DELETED', $tag['title']) . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$this->template->assign_vars([
|
||||
'DELETE' => 1,
|
||||
|
|
@ -123,53 +161,13 @@ class main_module
|
|||
'DELETE_CONFIRMATION' => $this->language->lang('ACP_TAGGING_DELETE_CONFIRMATION', $tag['title']),
|
||||
]);
|
||||
}
|
||||
|
||||
private function load_add_page()
|
||||
{
|
||||
$form_key = 'pedodev_tagging_add_tag';
|
||||
|
||||
add_form_key($form_key);
|
||||
|
||||
if ($this->request->is_set_post('submit'))
|
||||
{
|
||||
$this->check_form_key($form_key);
|
||||
|
||||
$new_tag = $this->request->variable('tagging_tagtitle', '');
|
||||
|
||||
if (empty($new_tag))
|
||||
{
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_EMPTY') . adm_back_link($this->u_action));
|
||||
}
|
||||
|
||||
$this->tag_list[] = array(
|
||||
'title' => $new_tag,
|
||||
'color' => $this->request->variable('tagging_tagcolor', ''),
|
||||
'active' => $this->request->variable('tagging_tagactive', false),
|
||||
'searchable' => $this->request->variable('tagging_tagsearchable', false),
|
||||
);
|
||||
|
||||
$this->tag_helper->update_tag_list($this->tag_list);
|
||||
|
||||
trigger_error($this->language->lang('ACP_TAGGING_TAG_ADDED', $new_tag) . adm_back_link($this->u_action));
|
||||
}
|
||||
private function load_main_page(): void
|
||||
{
|
||||
$form_key = 'pedodev_tagging_main';
|
||||
add_form_key($form_key);
|
||||
|
||||
$random_color = '#' . substr(md5(rand()), 0, 6);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'EDIT' => 1,
|
||||
'TAGGING_PAGE_TITLE' => $this->language->lang('ACP_TAGGING_SETTINGS_ADD',),
|
||||
'TAG_COLOR' => $random_color,
|
||||
'TAG_ACTIVE' => true,
|
||||
'TAG_SEARCHABLE' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
private function load_main_page()
|
||||
{
|
||||
$form_key = 'pedodev_tagging_main';
|
||||
add_form_key($form_key);
|
||||
|
||||
$id = 0;
|
||||
$id = 0;
|
||||
|
||||
if ($this->request->is_set_post('submit'))
|
||||
{
|
||||
|
|
@ -177,7 +175,7 @@ class main_module
|
|||
$this->config->set('pedodev_tagging_tagthreads', $this->request->variable('tagging_tagthreads', false));
|
||||
$this->config->set('pedodev_tagging_tagposts', $this->request->variable('tagging_tagposts', false));
|
||||
$this->config->set('pedodev_tagging_maxtags', $this->request->variable('tagging_maxtags', 0));
|
||||
$this->config->set('pedodev_tagging_tagsearch', $this->request->variable('tagging_tagsearch', false));
|
||||
$this->config->set('pedodev_tagging_tagsearch', ($this->request->variable('tagging_tagsearch', false) and $this->tag_search_available));
|
||||
$this->config->set('pedodev_tagging_viewtopic', $this->request->variable('tagging_viewtopic', false));
|
||||
$this->config->set('pedodev_tagging_viewforum', $this->request->variable('tagging_viewforum', false));
|
||||
$this->config->set('pedodev_tagging_results', $this->request->variable('tagging_results', false));
|
||||
|
|
@ -187,37 +185,38 @@ class main_module
|
|||
|
||||
foreach ($this->tag_list as $id => $tag)
|
||||
{
|
||||
$id = (int)$id;
|
||||
|
||||
$this->template->assign_block_vars('tag_list', [
|
||||
'TITLE' => $tag['title'],
|
||||
'COLOR' => $tag['color'],
|
||||
'ACTIVE' => $tag['active'],
|
||||
'TITLE' => $tag['title'],
|
||||
'COLOR' => $tag['color'],
|
||||
'ACTIVE' => $tag['active'],
|
||||
'SEARCHABLE' => $tag['searchable'],
|
||||
'EDIT_LINK' => $this->u_action . "&tag={$id}&action=edit",
|
||||
'EDIT_LINK' => $this->u_action . "&tag={$id}&action=edit",
|
||||
'DELETE_LINK' => $this->u_action . "&tag={$id}&action=delete",
|
||||
]);
|
||||
}
|
||||
|
||||
$id++;
|
||||
|
||||
|
||||
$this->template->assign_vars([
|
||||
'TAGGING_PAGE_TITLE' => $this->language->lang('ACP_TAGGING_SETTINGS'),
|
||||
'U_ACTION' => $this->u_action,
|
||||
'TAGGING_ADD_TAG' => $this->u_action . "&tag={$id}&action=add",
|
||||
'TAG_THREADS' => $this->config['pedodev_tagging_tagthreads'],
|
||||
'TAG_POSTS' => $this->config['pedodev_tagging_tagposts'],
|
||||
'MAX_TAGS' => (int)$this->config['pedodev_tagging_maxtags'],
|
||||
'TAG_SEARCH' => $this->config['pedodev_tagging_tagsearch'],
|
||||
'TAG_VIEWTOPIC' => $this->config['pedodev_tagging_viewtopic'],
|
||||
'TAG_VIEWFORUM' => $this->config['pedodev_tagging_viewforum'],
|
||||
'TAG_RESULTS' => $this->config['pedodev_tagging_results'],
|
||||
]);
|
||||
}
|
||||
'U_ACTION' => $this->u_action,
|
||||
'TAGGING_ADD_TAG' => $this->u_action . "&action=add",
|
||||
'TAG_THREADS' => $this->config['pedodev_tagging_tagthreads'],
|
||||
'TAG_POSTS' => $this->config['pedodev_tagging_tagposts'],
|
||||
'MAX_TAGS' => (int)$this->config['pedodev_tagging_maxtags'],
|
||||
'TAG_SEARCH' => $this->config['pedodev_tagging_tagsearch'],
|
||||
'TAG_VIEWTOPIC' => $this->config['pedodev_tagging_viewtopic'],
|
||||
'TAG_VIEWFORUM' => $this->config['pedodev_tagging_viewforum'],
|
||||
'TAG_RESULTS' => $this->config['pedodev_tagging_results'],
|
||||
'TAG_SEARCH_UNAVAILABLE' => !$this->tag_search_available,
|
||||
]);
|
||||
}
|
||||
|
||||
private function check_form_key($form_key)
|
||||
{
|
||||
private function check_form_key($form_key): void
|
||||
{
|
||||
if (!check_form_key($form_key))
|
||||
{
|
||||
trigger_error('FORM_INVALID');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<label for="tagging_tagcolor">{{ lang('ACP_TAGGING_TAGCOLOR') ~ lang('COLON') }}</label><br /><span>{{ lang('ACP_TAGGING_TAGCOLOR_EXPLANATION') }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
<input type="color" id="tagging_tagcolor" name="tagging_tagcolor" value="{{ TAG_COLOR }}" style="width:5%;">
|
||||
<input type="color" id="tagging_tagcolor" name="tagging_tagcolor" value="#{{ TAG_COLOR }}" style="width:5%;">
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
|
@ -47,4 +47,4 @@
|
|||
{{ S_FORM_TOKEN }}
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
{% for TAG in loops.tag_list %}
|
||||
<tr>
|
||||
<td>{{ TAG.TITLE }}</td>
|
||||
<td style="background: {{ TAG.COLOR }}"></td>
|
||||
<td style="background: #{{ TAG.COLOR }}"></td>
|
||||
<td>{% if TAG.ACTIVE %}{{ lang('YES') }}{% else %}{{ lang('NO') }}{% endif %}</td>
|
||||
<td>{% if TAG.SEARCHABLE %}{{ lang('YES') }}{% else %}{{ lang('NO') }}{% endif %}</td>
|
||||
<td><a href="{{ TAG.EDIT_LINK }}">{{ lang('ACP_TAGGING_EDIT') }}</a></td>
|
||||
|
|
@ -73,15 +73,19 @@
|
|||
|
||||
<fieldset>
|
||||
<legend>{{ lang('ACP_TAGGING_SEARCH') }}</legend>
|
||||
{% if TAG_SEARCH_UNAVAILABLE %}
|
||||
<b><font color="red">{{ lang('ACP_TAGGING_TAGSEARCH_UNAVAILABLE') }}</font></b>
|
||||
{% else %}
|
||||
<dl>
|
||||
<dt>
|
||||
<label for="tagging_tagsearch">{{ lang('ACP_TAGGING_TAGSEARCH') ~ lang('COLON') }}</label><br /><span>{{ lang('ACP_TAGGING_TAGSEARCH_EXPLANATION') }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
<label><input type="radio" class="radio" name="tagging_tagsearch" value="1" id="tagging_tagsearch" {% if TAG_SEARCH %}checked="checked"{% endif %} /> {{ lang('YES') }}</label>
|
||||
<label><input type="radio" class="radio" name="tagging_tagsearch" value="0" {% if not TAG_SEARCH %}checked="checked"{% endif %} /> {{ lang('NO') }}</label>
|
||||
<label><input type="radio" class="radio" name="tagging_tagsearch" value="1" id="tagging_tagsearch" {% if TAG_SEARCH %}checked="checked"{% endif %}/> {{ lang('YES') }}</label>
|
||||
<label><input type="radio" class="radio" name="tagging_tagsearch" value="0" {% if not TAG_SEARCH %}checked="checked"{% endif %}/> {{ lang('NO') }}</label>
|
||||
</dd>
|
||||
</dl>
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
|
|
@ -125,4 +129,4 @@
|
|||
|
||||
{{ S_FORM_TOKEN }}
|
||||
</fieldset>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -3,11 +3,15 @@ services:
|
|||
class: pedodev\tagging\core\tag_helper
|
||||
arguments:
|
||||
- '@dbal.conn'
|
||||
- '@config'
|
||||
- '%core.root_path%'
|
||||
- '%core.table_prefix%'
|
||||
|
||||
pedodev.tagging.search_helper:
|
||||
class: pedodev\tagging\core\search_helper
|
||||
arguments:
|
||||
- '@dbal.conn'
|
||||
- '@config'
|
||||
- '@pedodev.tagging.tag_helper'
|
||||
|
||||
pedodev.tagging.request_helper:
|
||||
|
|
@ -35,14 +39,15 @@ services:
|
|||
- '@pedodev.tagging.search_helper'
|
||||
- '@pedodev.tagging.request_helper'
|
||||
|
||||
pedodev.tagging.search_tag_listener:
|
||||
class: pedodev\tagging\event\search_tag_listener
|
||||
pedodev.tagging.search_listener:
|
||||
class: pedodev\tagging\event\search_listener
|
||||
tags:
|
||||
- { name: event.listener }
|
||||
arguments:
|
||||
- '@config'
|
||||
- '@template'
|
||||
- '@language'
|
||||
- '@auth'
|
||||
- '@pedodev.tagging.tag_helper'
|
||||
- '@pedodev.tagging.search_helper'
|
||||
- '@pedodev.tagging.request_helper'
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class request_helper
|
|||
|
||||
private function tag_is_selected(int $tag_id): bool
|
||||
{
|
||||
return $this->request->variable('tag_' . $tag_id, '', request_interface::GET);
|
||||
return (bool)$this->request->variable('tag_' . $tag_id, '', request_interface::GET);
|
||||
}
|
||||
|
||||
public function get_selected_tags(): array
|
||||
|
|
@ -32,9 +32,12 @@ class request_helper
|
|||
{
|
||||
return $this->request->variable('tag_filter', '', request_interface::GET);
|
||||
}
|
||||
|
||||
public function is_keyword_search(): bool
|
||||
|
||||
public function keywords_or_author(): bool
|
||||
{
|
||||
return (bool)$this->request->variable('keywords', '', request_interface::GET);
|
||||
$keywords = $this->request->variable('keywords', '', request_interface::GET);
|
||||
$author = $this->request->variable('author', '', request_interface::GET);
|
||||
|
||||
return !(empty($keywords) and empty($author));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,27 +3,36 @@
|
|||
namespace pedodev\tagging\core;
|
||||
|
||||
use phpbb\db\driver\factory;
|
||||
use phpbb\config\config;
|
||||
|
||||
use pedodev\tagging\core\tag_helper;
|
||||
|
||||
class search_helper
|
||||
{
|
||||
public function __construct(
|
||||
private factory $db,
|
||||
private factory $db,
|
||||
private config $config,
|
||||
|
||||
private tag_helper $tag_helper,
|
||||
) {}
|
||||
|
||||
public function search_post_tags(array $post_list): array
|
||||
public function search_post_tags(array $post_list, string $mode): array
|
||||
{
|
||||
if (empty($post_list))
|
||||
if (empty($post_list)) return array();
|
||||
|
||||
if ($mode == 'posts')
|
||||
{
|
||||
return array();
|
||||
$sql = 'SELECT t.post_id, t.tag_id
|
||||
FROM ' . $this->tag_helper->tag_table . ' t
|
||||
WHERE t.' . $this->db->sql_in_set('post_id', $post_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'SELECT t.topic_id as post_id, c.tag_id
|
||||
FROM ' . $this->tag_helper->tag_table . ' c, ' . TOPICS_TABLE . ' t
|
||||
WHERE t.topic_first_post_id = c.post_id AND t.' . $this->db->sql_in_set('topic_id', $post_list);
|
||||
}
|
||||
|
||||
$sql = 'SELECT t.post_id, t.tag_id
|
||||
FROM ' . $this->tag_helper->get_tag_table() . ' t
|
||||
WHERE t.' . $this->db->sql_in_set('post_id', $post_list);
|
||||
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$post_tags = array();
|
||||
|
|
@ -33,67 +42,29 @@ class search_helper
|
|||
$post_tags[$row['post_id']][] = $row['tag_id'];
|
||||
}
|
||||
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $post_tags;
|
||||
}
|
||||
|
||||
public function search_topic_tags(array $topic_list): array
|
||||
{
|
||||
if (empty($topic_list))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$sql = 'SELECT t.topic_id, c.tag_id
|
||||
FROM ' . $this->tag_helper->get_tag_table() . ' c, ' . TOPICS_TABLE . ' t
|
||||
WHERE t.topic_first_post_id = c.post_id AND t.' . $this->db->sql_in_set('topic_id', $topic_list);
|
||||
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$topic_tags = array();
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$topic_tags[$row['topic_id']][] = $row['tag_id'];
|
||||
}
|
||||
|
||||
return $topic_tags;
|
||||
}
|
||||
|
||||
public function search_posts_by_tag(array $tag_list, string $filter_mode, string $mode): array
|
||||
{
|
||||
if (empty($tag_list))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
public function generate_tag_subquery(array $search_tags, string $tag_filter): ?string
|
||||
{
|
||||
// Explicitly cast search tags to integers for security
|
||||
$search_tags = array_map('intval', $search_tags);
|
||||
$tag_count = count($search_tags);
|
||||
|
||||
if ($mode === 'posts')
|
||||
{
|
||||
$sql = 'SELECT post_id, count(*)
|
||||
FROM ' . $this->tag_helper->get_tag_table() . '
|
||||
WHERE ' . $this->db->sql_in_set('tag_id', $tag_list) . '
|
||||
GROUP BY post_id';
|
||||
}
|
||||
else if ($mode === 'topics')
|
||||
{
|
||||
$sql = 'SELECT t.topic_id, count(*)
|
||||
FROM ' . $this->tag_helper->get_tag_table() . ' c, ' . TOPICS_TABLE . ' t
|
||||
WHERE t.topic_first_post_id = c.post_id AND c.' . $this->db->sql_in_set('tag_id', $tag_list) . '
|
||||
GROUP BY t.topic_id';
|
||||
}
|
||||
if ($tag_count == 0) return null;
|
||||
|
||||
$result = $this->db->sql_query($sql);
|
||||
$tag_string = implode(',', $search_tags);
|
||||
$subquery_where = $this->db->sql_in_set('ct.tag_id', $search_tags);
|
||||
|
||||
$count = count($tag_list);
|
||||
$post_list = array();
|
||||
$tag_subquery = "SELECT ct.post_id from {$this->tag_helper->tag_table} ct WHERE {$subquery_where}";
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
if ($filter_mode === 'union' || ($filter_mode === 'intersect' && $row['count(*)'] == $count))
|
||||
{
|
||||
$post_list[] = (isset($row['post_id'])) ? (int)$row['post_id'] : (int)$row['topic_id'];
|
||||
}
|
||||
}
|
||||
if ($tag_filter == "intersect" && $tag_count > 1) {
|
||||
$tag_subquery .= ' GROUP BY ct.post_id HAVING COUNT(ct.post_id) = ' . (int)$tag_count;
|
||||
}
|
||||
|
||||
return $tag_subquery;
|
||||
}
|
||||
}
|
||||
|
||||
return $post_list;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace pedodev\tagging\core;
|
||||
|
||||
use phpbb\db\driver\factory;
|
||||
use phpbb\config\config;
|
||||
|
||||
class tag_helper
|
||||
{
|
||||
|
|
@ -10,20 +11,29 @@ class tag_helper
|
|||
private array $active_tag_list;
|
||||
private array $searchable_tag_list;
|
||||
|
||||
private string $tag_table;
|
||||
public readonly string $tag_table;
|
||||
private string $tag_list_filepath;
|
||||
|
||||
public function __construct(
|
||||
private factory $db,
|
||||
private factory $db,
|
||||
private config $config,
|
||||
string $phpbb_root_path,
|
||||
string $table_prefix,
|
||||
)
|
||||
{
|
||||
global $table_prefix;
|
||||
|
||||
$this->tag_list_filepath = __DIR__ . '/../taglist.json';
|
||||
$this->tag_list_filepath = "{$phpbb_root_path}files/{$this->config['pedodev_tagging_taglist_prefix']}_taglist.json";
|
||||
$this->tag_table = $this->db->sql_escape($table_prefix . 'content_tags');
|
||||
$this->load_tag_list();
|
||||
}
|
||||
|
||||
|
||||
public function validate_tag(array $tag): bool
|
||||
{
|
||||
return (bool)preg_match("/^[\w ]{1,20}$/", $tag['title'])
|
||||
and (bool)preg_match('/^[0-9a-f]{6}$/', $tag['color'])
|
||||
and is_bool($tag['active'])
|
||||
and is_bool($tag['searchable']);
|
||||
}
|
||||
|
||||
private function load_tag_list(): void
|
||||
{
|
||||
$tag_list_json = '';
|
||||
|
|
@ -33,22 +43,36 @@ class tag_helper
|
|||
$tag_list_json = file_get_contents($this->tag_list_filepath);
|
||||
}
|
||||
|
||||
$tag_list = json_decode($tag_list_json, $associative = true);
|
||||
$this->tag_list = isset($tag_list) ? $tag_list : array();
|
||||
|
||||
$this->active_tag_list = array_filter($this->tag_list, function($v) {
|
||||
return (bool)$v['active'];
|
||||
});
|
||||
$tag_list = json_decode($tag_list_json, $associative = true);
|
||||
|
||||
$this->searchable_tag_list = array_filter($this->tag_list, function($v) {
|
||||
return (bool)$v['searchable'];
|
||||
});
|
||||
// Remove invalid tags
|
||||
$tag_list = array_filter($tag_list, [$this, 'validate_tag']);
|
||||
|
||||
// Remove tags with non-numeric IDs
|
||||
$tag_list = array_filter($tag_list, function ($id) {
|
||||
return is_int($id);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
$this->tag_list = $tag_list ?? array();
|
||||
|
||||
$this->active_tag_list = array_filter($this->tag_list, function($tag) {
|
||||
return (bool)$tag['active'];
|
||||
});
|
||||
|
||||
$this->searchable_tag_list = array_filter($this->tag_list, function($tag) {
|
||||
return (bool)$tag['searchable'];
|
||||
});
|
||||
}
|
||||
|
||||
public function update_tag_list(array $tag_list): bool
|
||||
public function update_tag_list(array $tag_list): void
|
||||
{
|
||||
$tag_list = array_filter($tag_list, [$this, 'validate_tag']);
|
||||
$tag_list_json = json_encode($tag_list);
|
||||
return (bool)file_put_contents($this->tag_list_filepath, $tag_list_json);
|
||||
|
||||
if (!chmod($this->tag_list_filepath, 0600) or !file_put_contents($this->tag_list_filepath, $tag_list_json) or !chmod($this->tag_list_filepath, 0400))
|
||||
{
|
||||
trigger_error('Unable to update taglist. Check your file and ownership permissions', E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_tag_list(): array
|
||||
|
|
@ -65,20 +89,15 @@ class tag_helper
|
|||
{
|
||||
return $this->searchable_tag_list;
|
||||
}
|
||||
|
||||
public function get_tag_table(): string
|
||||
{
|
||||
return $this->tag_table;
|
||||
}
|
||||
|
||||
|
||||
public function get_colored_title(int $tag_id): string
|
||||
{
|
||||
if (!array_key_exists($tag_id, $this->tag_list))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
if (!array_key_exists($tag_id, $this->tag_list)) return '';
|
||||
|
||||
$tag = $this->tag_list[$tag_id];
|
||||
return '<span class="content_tag" style="background: ' . $tag['color'] . '">' . $tag['title'] . '</span>';
|
||||
$tag['title'] = htmlspecialchars($tag['title']);
|
||||
$tag['color'] = htmlspecialchars($tag['color']);
|
||||
|
||||
return "<span class=\"content_tag\" style=\"background: #{$tag['color']}\">{$tag['title']}</span>";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Adds permissions to the Permissions page in the Admin CP
|
||||
*/
|
||||
|
||||
namespace pedodev\tagging\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
|
@ -20,5 +16,6 @@ class permissions implements EventSubscriberInterface
|
|||
public function load_permissions(object $event): void
|
||||
{
|
||||
$event->update_subarray('permissions', 'u_pedodev_tagging_cantagposts', ['lang' => 'ACL_U_PEDODEV_TAGGING_CANTAGPOSTS', 'cat' => 'post']);
|
||||
$event->update_subarray('permissions', 'u_pedodev_tagging_cantagsearch', ['lang' => 'ACL_U_PEDODEV_TAGGING_CANTAGSEARCH', 'cat' => 'misc']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,10 +91,7 @@ class posting_listener implements EventSubscriberInterface
|
|||
$allowed = $this->config['pedodev_tagging_tagposts'];
|
||||
}
|
||||
|
||||
if (!$allowed || !$this->auth->acl_get('u_pedodev_tagging_cantagposts'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!$allowed || !$this->auth->acl_get('u_pedodev_tagging_cantagposts')) return;
|
||||
|
||||
$post_id = (int)$event['post_id'];
|
||||
|
||||
|
|
@ -104,7 +101,7 @@ class posting_listener implements EventSubscriberInterface
|
|||
}
|
||||
else if ($post_id != 0)
|
||||
{
|
||||
$post_tags = $this->search_helper->search_post_tags(array($post_id));
|
||||
$post_tags = $this->search_helper->search_post_tags(array($post_id), 'posts');
|
||||
$post_tags = empty($post_tags) ? array() : current($post_tags);
|
||||
}
|
||||
else
|
||||
|
|
@ -153,10 +150,7 @@ class posting_listener implements EventSubscriberInterface
|
|||
|
||||
private function insert_post_tags(int $post_id): void
|
||||
{
|
||||
if ($post_id <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ($post_id <= 0) return;
|
||||
|
||||
$sql_ary = array();
|
||||
$active_tag_list = $this->tag_helper->get_active_tag_list();
|
||||
|
|
@ -172,17 +166,14 @@ class posting_listener implements EventSubscriberInterface
|
|||
}
|
||||
}
|
||||
|
||||
$this->db->sql_multi_insert($this->tag_helper->get_tag_table(), $sql_ary);
|
||||
$this->db->sql_multi_insert($this->tag_helper->tag_table, $sql_ary);
|
||||
}
|
||||
|
||||
private function delete_post_tags(int $post_id): void
|
||||
{
|
||||
if ($post_id <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ($post_id <= 0) return;
|
||||
|
||||
$sql = 'DELETE FROM ' . $this->tag_helper->get_tag_table() . '
|
||||
$sql = 'DELETE FROM ' . $this->tag_helper->tag_table . '
|
||||
WHERE post_id = ' . (int)$post_id;
|
||||
|
||||
$this->db->sql_query($sql);
|
||||
|
|
|
|||
223
event/search_listener.php
Executable file
223
event/search_listener.php
Executable file
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
use phpbb\config\config;
|
||||
use phpbb\template\template;
|
||||
use phpbb\language\language;
|
||||
use phpbb\auth\auth;
|
||||
|
||||
use pedodev\tagging\core\tag_helper;
|
||||
use pedodev\tagging\core\search_helper;
|
||||
use pedodev\tagging\core\request_helper;
|
||||
|
||||
class search_listener implements EventSubscriberInterface
|
||||
{
|
||||
private array $post_tags;
|
||||
private string $mode;
|
||||
|
||||
public function __construct(
|
||||
private config $config,
|
||||
private template $template,
|
||||
private language $language,
|
||||
private auth $auth,
|
||||
|
||||
private tag_helper $tag_helper,
|
||||
private search_helper $search_helper,
|
||||
private request_helper $request_helper,
|
||||
) {}
|
||||
|
||||
static public function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'core.search_modify_forum_select_list' => 'assign_presearch_tags',
|
||||
'core.search_backend_search_after' => [['tag_search', 1],['fetch_results_tags', 0]],
|
||||
'core.search_modify_url_parameters' => 'add_tags_url',
|
||||
'core.search_modify_tpl_ary' => 'assign_results_tags',
|
||||
'core.search_modify_submit_parameters' => 'load_language',
|
||||
|
||||
'core.search_native_by_keyword_modify_search_key' => 'pre_cache_assign_tags',
|
||||
'core.search_native_keywords_count_query_before' => 'native_keyword_search_with_tags',
|
||||
'core.search_native_by_author_modify_search_key' => 'pre_cache_assign_tags',
|
||||
'core.search_native_author_count_query_before' => [['authorless_tag_search', 1], ['author_search_with_tags', 0]],
|
||||
|
||||
'core.search_mysql_by_keyword_modify_search_key' => 'pre_cache_assign_tags',
|
||||
'core.search_mysql_keywords_main_query_before' => 'mysql_keyword_search_with_tags',
|
||||
'core.search_mysql_by_author_modify_search_key' => 'pre_cache_assign_tags',
|
||||
'core.search_mysql_author_query_before' => [['authorless_tag_search', 1], ['author_search_with_tags', 0]],
|
||||
];
|
||||
}
|
||||
|
||||
private function can_tag_search(): bool
|
||||
{
|
||||
return ($this->config['pedodev_tagging_tagsearch'] and $this->auth->acl_get('u_pedodev_tagging_cantagsearch'));
|
||||
}
|
||||
|
||||
public function load_language(object $event): void
|
||||
{
|
||||
$this->language->add_lang('tagging_search', 'pedodev/tagging');
|
||||
}
|
||||
|
||||
public function assign_presearch_tags(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search()) return;
|
||||
|
||||
$active_tag_list = $this->tag_helper->get_searchable_tag_list();
|
||||
|
||||
$this->template->assign_var('TAGGING_ALLOWED', 1);
|
||||
|
||||
foreach ($active_tag_list as $id => $tag)
|
||||
{
|
||||
$this->template->assign_block_vars('tags', [
|
||||
'ID' => $id,
|
||||
'TITLE' => $tag['title'],
|
||||
'COLOR' => $tag['color'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function fetch_results_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_results']) return;
|
||||
|
||||
$this->post_tags = $this->search_helper->search_post_tags($event['id_ary'], $event['show_results']);
|
||||
}
|
||||
|
||||
public function add_tags_url(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search()) return;
|
||||
|
||||
$tag_ids = $this->request_helper->get_selected_tags();
|
||||
if (empty($tag_ids)) return;
|
||||
|
||||
$u_search = $event['u_search'];
|
||||
|
||||
$u_search .= '&submit=Search';
|
||||
$u_search .= '&tag_' . implode('=1&tag_', $tag_ids) . '=1';
|
||||
$u_search .= '&tag_filter=' . $this->request_helper->get_tag_filter();
|
||||
|
||||
$event['u_search'] = $u_search;
|
||||
}
|
||||
|
||||
public function assign_results_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_results']) return;
|
||||
|
||||
$post_row = $event['tpl_ary'];
|
||||
$post_id = $post_row['POST_ID'] ? (int)$post_row['POST_ID'] : (int)$post_row['TOPIC_ID'];
|
||||
|
||||
if (array_key_exists($post_id, $this->post_tags))
|
||||
{
|
||||
$post_tags = $this->post_tags[$post_id];
|
||||
$tags = implode(' ', array_map([$this->tag_helper, 'get_colored_title'], $post_tags));
|
||||
$post_row['POST_TAGS'] = $tags;
|
||||
}
|
||||
|
||||
$event['tpl_ary'] = $post_row;
|
||||
}
|
||||
|
||||
private function get_tag_string(): string
|
||||
{
|
||||
$search_tags = $this->request_helper->get_selected_tags();
|
||||
$tag_filter = $this->request_helper->get_tag_filter();
|
||||
|
||||
$search_tags_string = implode(',', $search_tags);
|
||||
$tag_string = "tags({$search_tags_string})";
|
||||
|
||||
$tag_string .= (count($search_tags) > 1) ? $tag_filter : '';
|
||||
|
||||
return $tag_string;
|
||||
|
||||
}
|
||||
|
||||
public function pre_cache_assign_tags(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search()) return;
|
||||
|
||||
$search_key_array = $event['search_key_array'];
|
||||
$search_key_array[] = $this->get_tag_string();
|
||||
$event['search_key_array'] = $search_key_array;
|
||||
}
|
||||
|
||||
// thread search not working?
|
||||
public function native_keyword_search_with_tags(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search()) return;
|
||||
|
||||
$search_tags = $this->request_helper->get_selected_tags();
|
||||
$tag_filter = $this->request_helper->get_tag_filter();
|
||||
|
||||
$tag_subquery = $this->search_helper->generate_tag_subquery($search_tags, $tag_filter);
|
||||
|
||||
if (is_null($tag_subquery)) return;
|
||||
|
||||
$sql_where = $event['sql_where'];
|
||||
$sql_where[] = "p.post_id IN ({$tag_subquery})";
|
||||
$event['sql_where'] = $sql_where;
|
||||
}
|
||||
|
||||
public function author_search_with_tags(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search()) return;
|
||||
|
||||
$search_tags = $this->request_helper->get_selected_tags();
|
||||
$tag_filter = $this->request_helper->get_tag_filter();
|
||||
|
||||
$tag_subquery = $this->search_helper->generate_tag_subquery($search_tags, $tag_filter);
|
||||
|
||||
if (is_null($tag_subquery)) return;
|
||||
|
||||
$sql_author = $event['sql_author'];
|
||||
$sql_author .= " AND p.post_id IN ({$tag_subquery})";
|
||||
$event['sql_author'] = $sql_author;
|
||||
}
|
||||
|
||||
public function mysql_keyword_search_with_tags(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search()) return;
|
||||
|
||||
$search_tags = $this->request_helper->get_selected_tags();
|
||||
$tag_filter = $this->request_helper->get_tag_filter();
|
||||
|
||||
$tag_subquery = $this->search_helper->generate_tag_subquery($search_tags, $tag_filter);
|
||||
|
||||
if (is_null($tag_subquery)) return;
|
||||
|
||||
$sql_match_where = $event['sql_match_where'];
|
||||
$sql_match_where = " AND p.post_id IN ({$tag_subquery})";
|
||||
$event['sql_match_where'] = $sql_match_where;
|
||||
}
|
||||
|
||||
public function tag_search(object $event): void
|
||||
{
|
||||
global $search;
|
||||
|
||||
if (!$this->can_tag_search() or $this->request_helper->keywords_or_author()) return;
|
||||
|
||||
$search_tags = $this->request_helper->get_selected_tags();
|
||||
if (empty($search_tags)) return;
|
||||
|
||||
$id_ary = array();
|
||||
$start = $event['start'];
|
||||
|
||||
$total_results = $search->author_search($event['show_results'], true, $event['sort_by_sql'], $event['sort_key'],
|
||||
$event['sort_dir'], $event['sort_days'], $event['ex_fid_ary'], $event['m_approve_posts_fid_sql'],
|
||||
$event['topic_id'], array(0), '', $id_ary, $start, $event['per_page']
|
||||
);
|
||||
|
||||
$event['id_ary'] = $id_ary;
|
||||
$event['total_match_count'] = $total_results;
|
||||
$event['start'] = $start;
|
||||
}
|
||||
|
||||
public function authorless_tag_search(object $event): void
|
||||
{
|
||||
if (!$this->can_tag_search() or $event['sql_author'] != 'p.poster_id = 0') return;
|
||||
|
||||
$event['sql_author'] = '1 = 1';
|
||||
$event['firstpost_only'] = false;
|
||||
$event['sql_firstpost'] = '';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
use phpbb\config\config;
|
||||
use phpbb\template\template;
|
||||
use phpbb\language\language;
|
||||
|
||||
use pedodev\tagging\core\tag_helper;
|
||||
use pedodev\tagging\core\search_helper;
|
||||
use pedodev\tagging\core\request_helper;
|
||||
|
||||
class search_tag_listener implements EventSubscriberInterface
|
||||
{
|
||||
private array $post_tags;
|
||||
private string $mode;
|
||||
|
||||
public function __construct(
|
||||
private config $config,
|
||||
private template $template,
|
||||
private language $language,
|
||||
|
||||
private tag_helper $tag_helper,
|
||||
private search_helper $search_helper,
|
||||
private request_helper $request_helper,
|
||||
) {}
|
||||
|
||||
static public function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'core.search_modify_forum_select_list' => 'assign_presearch_tags',
|
||||
// 'core.search_backend_search_after' => [['fetch_results_tags', 0], ['search_by_tag', 1]],
|
||||
'core.search_modify_url_parameters' => 'add_tags_url',
|
||||
// 'core.search_modify_tpl_ary' => 'assign_results_tags',
|
||||
'core.search_modify_submit_parameters' => 'load_language',
|
||||
'core.search_native_keywords_count_query_before' => 'test_func',
|
||||
];
|
||||
}
|
||||
|
||||
public function load_language(object $event): void
|
||||
{
|
||||
$this->language->add_lang('tagging_search', 'pedodev/tagging');
|
||||
}
|
||||
|
||||
public function assign_presearch_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_tagsearch'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$active_tag_list = $this->tag_helper->get_searchable_tag_list();
|
||||
|
||||
$this->template->assign_var('TAGGING_ALLOWED', 1);
|
||||
|
||||
foreach ($active_tag_list as $id => $tag)
|
||||
{
|
||||
$this->template->assign_block_vars('tags', [
|
||||
'ID' => $id,
|
||||
'TITLE' => $tag['title'],
|
||||
'COLOR' => $tag['color'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function fetch_results_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_results'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->mode = $event['show_results'];
|
||||
|
||||
if ($this->mode === 'posts')
|
||||
{
|
||||
$this->post_tags = $this->search_helper->search_post_tags($event['id_ary']);
|
||||
}
|
||||
else if ($this->mode === 'topics')
|
||||
{
|
||||
$this->post_tags = $this->search_helper->search_topic_tags($event['id_ary']);
|
||||
}
|
||||
}
|
||||
|
||||
public function add_tags_url(object $event): void
|
||||
{
|
||||
$tag_ids = $this->request_helper->get_selected_tags();
|
||||
|
||||
if (empty($tag_ids))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$u_search = $event['u_search'];
|
||||
$u_search .= '&tag_' . implode('=1&tag_', $tag_ids) . '=1';
|
||||
$u_search .= '&tag_filter=' . $this->request_helper->get_tag_filter();
|
||||
$event['u_search'] = $u_search;
|
||||
}
|
||||
|
||||
public function assign_results_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_results'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$post_row = $event['tpl_ary'];
|
||||
$post_id = $post_row['POST_ID'] ? (int)$post_row['POST_ID'] : (int)$post_row['TOPIC_ID'];
|
||||
|
||||
if (array_key_exists($post_id, $this->post_tags))
|
||||
{
|
||||
$post_tags = $this->post_tags[$post_id];
|
||||
$tags = implode(' ', array_map([$this->tag_helper, 'get_colored_title'], $post_tags));
|
||||
$post_row['POST_TAGS'] = $tags;
|
||||
}
|
||||
|
||||
$event['tpl_ary'] = $post_row;
|
||||
}
|
||||
|
||||
public function search_by_tag(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_tagsearch'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$id_ary = $event['id_ary'];
|
||||
|
||||
if (empty($id_ary) && $this->request_helper->is_keyword_search())
|
||||
{
|
||||
var_dump("Empty search");
|
||||
return;
|
||||
}
|
||||
|
||||
$tag_ids = $this->request_helper->get_selected_tags();
|
||||
|
||||
if (empty($tag_ids))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$mode = $event['show_results'];
|
||||
$tag_filter = $this->request_helper->get_tag_filter();
|
||||
|
||||
$post_ary = $this->search_helper->search_posts_by_tag($tag_ids, $tag_filter, $mode);
|
||||
|
||||
if (empty($id_ary))
|
||||
{
|
||||
$id_ary = $post_ary;
|
||||
}
|
||||
else
|
||||
{
|
||||
$id_ary = array_intersect($id_ary, $post_ary);
|
||||
}
|
||||
|
||||
$event['id_ary'] = $id_ary;
|
||||
$event['total_match_count'] = count($id_ary);
|
||||
}
|
||||
|
||||
public function test_func(object $event): void
|
||||
{
|
||||
// var_dump($event);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ class viewforum_listener implements EventSubscriberInterface
|
|||
|
||||
public function __construct(
|
||||
private config $config,
|
||||
|
||||
private tag_helper $tag_helper,
|
||||
private search_helper $search_helper,
|
||||
) {}
|
||||
|
|
@ -29,20 +30,14 @@ class viewforum_listener implements EventSubscriberInterface
|
|||
|
||||
public function fetch_topic_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_viewforum'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!$this->config['pedodev_tagging_viewforum']) return;
|
||||
|
||||
$this->topic_tags = $this->search_helper->search_topic_tags($event['topic_list']);
|
||||
$this->topic_tags = $this->search_helper->search_post_tags($event['topic_list'], 'topics');
|
||||
}
|
||||
|
||||
public function assign_topic_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_viewforum'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!$this->config['pedodev_tagging_viewforum']) return;
|
||||
|
||||
$topic_row = $event['topic_row'];
|
||||
$topic_id = (int)$topic_row['TOPIC_ID'];
|
||||
|
|
|
|||
|
|
@ -29,20 +29,14 @@ class viewtopic_listener implements EventSubscriberInterface
|
|||
|
||||
public function fetch_post_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_viewtopic'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!$this->config['pedodev_tagging_viewtopic']) return;
|
||||
|
||||
$this->post_tags = $this->search_helper->search_post_tags($event['post_list']);
|
||||
$this->post_tags = $this->search_helper->search_post_tags($event['post_list'], 'posts');
|
||||
}
|
||||
|
||||
public function assign_post_tags(object $event): void
|
||||
{
|
||||
if (!$this->config['pedodev_tagging_viewtopic'])
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!$this->config['pedodev_tagging_viewtopic']) return;
|
||||
|
||||
$post_row = $event['post_row'];
|
||||
$post_id = (int)$post_row['POST_ID'];
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ $lang = array_merge($lang, array(
|
|||
'ACP_TAGGING_TAG_ADDED' => 'New tag \'%s\' added successfully',
|
||||
'ACP_TAGGING_TAG_EDITED' => 'Tag \'%s\' successfully edited',
|
||||
'ACP_TAGGING_TAG_DELETED' => 'Tag \'%s\' has been deleted',
|
||||
'ACP_TAGGING_TAG_INVALID' => 'Invalid tag input',
|
||||
'ACP_TAGGING_INVALID_TAG' => 'Invalid tag id',
|
||||
'ACP_TAGGING_TAG_EMPTY' => 'Tag cannot be empty',
|
||||
'ACP_TAGGING_DELETE_CONFIRMATION' => 'Confirm Deletion of Tag \'%s\'',
|
||||
|
|
@ -39,6 +40,7 @@ $lang = array_merge($lang, array(
|
|||
'ACP_TAGGING_TAGPOSTS' => 'Allow Tagging Posts',
|
||||
'ACP_TAGGING_TAGLIST' => 'Tag List',
|
||||
'ACP_TAGGING_TAGSEARCH' => 'Allow Searching by Tag',
|
||||
'ACP_TAGGING_TAGSEARCH_UNAVAILABLE' => 'Warning: tag search requires the Native Fulltext or MySQL Fulltext search engine',
|
||||
'ACP_TAGGING_VIEWFORUM' => 'Show Tags in Forum View',
|
||||
'ACP_TAGGING_VIEWTOPIC' => 'Show Tags in Topic View',
|
||||
'ACP_TAGGING_RESULTS' => 'Show Tags in Search Results',
|
||||
|
|
|
|||
|
|
@ -12,4 +12,5 @@ if (empty($lang) || !is_array($lang))
|
|||
|
||||
$lang = array_merge($lang, array(
|
||||
'ACL_U_PEDODEV_TAGGING_CANTAGPOSTS' => 'Can tag posts',
|
||||
'ACL_U_PEDODEV_TAGGING_CANTAGSEARCH' => 'Can search by tag',
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\migrations;
|
||||
|
||||
class dev_1 extends \phpbb\db\migration\migration
|
||||
{
|
||||
public function effectively_installed()
|
||||
{
|
||||
return isset($this->config['pedodev_tagging']);
|
||||
}
|
||||
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v330\v330'];
|
||||
}
|
||||
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
|
||||
['config.add', ['pedodev_tagging', 1]],
|
||||
|
||||
['module.add', [
|
||||
'acp',
|
||||
'ACP_CAT_DOT_MODS',
|
||||
'ACP_TAGGING_TITLE'
|
||||
]],
|
||||
|
||||
['module.add', [
|
||||
'acp',
|
||||
'ACP_TAGGING_TITLE',
|
||||
[
|
||||
'module_basename' => '\pedodev\tagging\acp\main_module',
|
||||
'modes' => ['settings'],
|
||||
],
|
||||
]],
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\migrations;
|
||||
|
||||
class dev_2 extends \phpbb\db\migration\migration
|
||||
{
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v330\v330'];
|
||||
}
|
||||
|
||||
public function update_data()
|
||||
{
|
||||
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : '../';
|
||||
$tag_directory_filepath = "{$phpbb_root_path}/ext/pedodev/tagging/taglist";
|
||||
|
||||
if (!file_exists($tag_directory_filepath)) {
|
||||
mkdir($tag_directory_filepath, 0644);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\migrations;
|
||||
|
||||
class dev_3 extends \phpbb\db\migration\migration
|
||||
{
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v330\v330'];
|
||||
}
|
||||
|
||||
public function update_data()
|
||||
{
|
||||
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : '../';
|
||||
$tag_list_filepath = "{$phpbb_root_path}/ext/pedodev/tagging/taglist.json";
|
||||
|
||||
if (!file_exists($tag_list_filepath)) {
|
||||
touch($tag_list_filepath);
|
||||
chmod($tag_list_filepath, 0644);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\migrations;
|
||||
|
||||
class dev_4 extends \phpbb\db\migration\migration
|
||||
{
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v330\v330'];
|
||||
}
|
||||
|
||||
public function update_schema()
|
||||
{
|
||||
return [
|
||||
|
||||
'add_tables' => [
|
||||
$this->table_prefix . 'content_tags' => [
|
||||
'COLUMNS' => [
|
||||
'id' => ['ULINT', NULL, 'auto_increment'],
|
||||
'post_id' => ['ULINT', 0, 'NON-NULL'],
|
||||
'tag_id' => ['USINT', 0, 'NON-NULL'],
|
||||
],
|
||||
'PRIMARY_KEY' => 'id',
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
public function revert_schema()
|
||||
{
|
||||
return [
|
||||
'drop_tables' => [
|
||||
$this->table_prefix . 'content_tags',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\migrations;
|
||||
|
||||
class dev_5 extends \phpbb\db\migration\migration
|
||||
{
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v330\v330'];
|
||||
}
|
||||
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
|
||||
['permission.add', ['u_pedodev_tagging_cantagposts']],
|
||||
['permission.permission_set', ['ROLE_USER_LIMITED', 'u_pedodev_tagging_cantagposts']],
|
||||
['permission.permission_set', ['ROLE_USER_STANDARD', 'u_pedodev_tagging_cantagposts']],
|
||||
['permission.permission_set', ['ROLE_USER_FULL', 'u_pedodev_tagging_cantagposts']],
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
113
migrations/release_1_0_0.php
Executable file
113
migrations/release_1_0_0.php
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
namespace pedodev\tagging\migrations;
|
||||
|
||||
class release_1_0_0 extends \phpbb\db\migration\migration
|
||||
{
|
||||
public function effectively_installed()
|
||||
{
|
||||
return isset($this->config['pedodev_tagging']);
|
||||
}
|
||||
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v330\v330'];
|
||||
}
|
||||
|
||||
public function update_schema()
|
||||
{
|
||||
return [
|
||||
'add_tables' => [
|
||||
$this->table_prefix . 'content_tags' => [
|
||||
'COLUMNS' => [
|
||||
'id' => ['ULINT', NULL, 'auto_increment'],
|
||||
'post_id' => ['ULINT', 0, 'NON-NULL'],
|
||||
'tag_id' => ['USINT', 0, 'NON-NULL'],
|
||||
],
|
||||
'PRIMARY_KEY' => 'id',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function revert_schema()
|
||||
{
|
||||
return [
|
||||
'drop_tables' => [
|
||||
$this->table_prefix . 'content_tags',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function update_data()
|
||||
{
|
||||
$random_string = bin2hex(random_bytes(8));
|
||||
$taglist_prefix = isset($this->config['pedodev_tagging_taglist_prefix']) ? $this->config['pedodev_tagging_taglist_prefix'] : $random_string;
|
||||
$taglist_filepath = "{$this->phpbb_root_path}files/{$taglist_prefix}_taglist.json";
|
||||
|
||||
if (!touch($taglist_filepath) or !chmod($taglist_filepath, 0400))
|
||||
{
|
||||
trigger_error('Unable to access taglist.json file. Check your file and ownership permissions', E_USER_ERROR);
|
||||
}
|
||||
|
||||
return [
|
||||
|
||||
['config.add', ['pedodev_tagging', 1]],
|
||||
|
||||
['module.add', [
|
||||
'acp',
|
||||
'ACP_CAT_DOT_MODS',
|
||||
'ACP_TAGGING_TITLE'
|
||||
]],
|
||||
|
||||
['module.add', [
|
||||
'acp',
|
||||
'ACP_TAGGING_TITLE',
|
||||
[
|
||||
'module_basename' => '\pedodev\tagging\acp\main_module',
|
||||
'modes' => ['settings'],
|
||||
],
|
||||
]],
|
||||
|
||||
['config.add', ['pedodev_tagging_tagthreads', true]],
|
||||
['config.add', ['pedodev_tagging_tagposts', true]],
|
||||
['config.add', ['pedodev_tagging_maxtags', 5]],
|
||||
['config.add', ['pedodev_tagging_viewtopic', true]],
|
||||
['config.add', ['pedodev_tagging_viewforum', true]],
|
||||
['config.add', ['pedodev_tagging_results', true]],
|
||||
|
||||
['if', [
|
||||
($this->config['search_type'] == '\phpbb\search\fulltext_native' or $this->config['search_type'] == '\phpbb\search\fulltext_mysql'),
|
||||
['config.add', ['pedodev_tagging_tagsearch', true]],
|
||||
]],
|
||||
|
||||
['permission.add', ['u_pedodev_tagging_cantagposts']],
|
||||
['permission.permission_set', ['ROLE_USER_LIMITED', 'u_pedodev_tagging_cantagposts']],
|
||||
['permission.permission_set', ['ROLE_USER_STANDARD', 'u_pedodev_tagging_cantagposts']],
|
||||
['permission.permission_set', ['ROLE_USER_FULL', 'u_pedodev_tagging_cantagposts']],
|
||||
|
||||
['permission.add', ['u_pedodev_tagging_cantagsearch']],
|
||||
['permission.permission_set', ['ROLE_USER_LIMITED', 'u_pedodev_tagging_cantagsearch']],
|
||||
['permission.permission_set', ['ROLE_USER_STANDARD', 'u_pedodev_tagging_cantagsearch']],
|
||||
['permission.permission_set', ['ROLE_USER_FULL', 'u_pedodev_tagging_cantagsearch']],
|
||||
|
||||
|
||||
['if', [
|
||||
!isset($this->config['pedodev_tagging_taglist_prefix']),
|
||||
['config.add', ['pedodev_tagging_taglist_prefix', $random_string]],
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
public function revert_data()
|
||||
{
|
||||
$taglist_filepath = "{$this->phpbb_root_path}files/{$this->config['pedodev_tagging_taglist_prefix']}_taglist.json";
|
||||
|
||||
if (file_exists($taglist_filepath) and !unlink($taglist_filepath))
|
||||
{
|
||||
trigger_error('Unable to delete taglist.json file. Check your file and ownership permissions', E_USER_ERROR);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
30
release.txt
Executable file
30
release.txt
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
Introducing this revolutionary new extension, designed and written specially for the pedo community. Often requested but never seen until now, this extension allows users to tag their threads with a variety of pre-selected tags chosen by the admin. A thread's tags will be visible when browsing the forums, giving users an easy way to find threads they are interested in. Most importantly, tags are fully integrated with the search system, allowing you to search for any combination of tags, keywords and authors.
|
||||
|
||||
This is a beta release in preparation for an upcoming official release. You can help by downloading the plugin, testing it out and reviewing the code, then reporting on any bugs or vulnerabilites and suggesting new features. Please do not use this beta version on a live site.
|
||||
|
||||
[b]Tagging threads[/b]
|
||||
When creating a thread, users will have the option to select a variety of tags. These tags are defined in the Admin CP, where admins can easily add/edit/remove tags as they wish. Users can select multiple tags up to a maximum limit configured in the Admin CP. Tags can be added/removed by editing a thread, allowing moderators to fix incorrectly tagged threads. Tags are color coded for easy recognition.
|
||||
|
||||
Individual posts within a thread can also be tagged. This is useful for megathreads where each post can contain a different video. The ability to tag posts can be enabled/disabled by the admin.
|
||||
|
||||
[b]Search[/b]
|
||||
Searching by tags is perhaps the best feature of this extension. Tags can be added to any existing keyword/author search, or you can search with only tags. When multiple tags are selected, the tag filter can be applied in two ways: 'intersect' will search for posts containing ALL matching tags, while 'union' will search for posts containing ANY matching tags.
|
||||
|
||||
Tag search is fully integrated with the cache to prevent excessive server load.
|
||||
|
||||
[b]Configuration[/b]
|
||||
Comes with a configuration page in the Admin CP. This page is easy to use, allowing any admin to easily add, edit or remove tags. You can also set the color for each individual tag.
|
||||
|
||||
[b]Permissions[/b]
|
||||
Full integration with the phpBB permissions system. The following permissions can be applied to individual users or to groups:
|
||||
[list]
|
||||
[*] - Whether the user can tag threads/posts
|
||||
[*] - Whether the user can search by tag
|
||||
[/list]
|
||||
|
||||
[b]Download[/b]
|
||||
Download from any of the links below:
|
||||
|
||||
[code]
|
||||
[/code]
|
||||
Installation instructions are included within the archive. See the README.txt file.
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<dd class="content_tag_list">
|
||||
{% if loops.tags|length %}
|
||||
{% for TAG in loops.tags %}
|
||||
<label class="content_tag" style="background: {{ TAG.COLOR }}">
|
||||
<label class="content_tag" style="background: #{{ TAG.COLOR }}">
|
||||
<input type="checkbox" id="tag_{{ TAG.ID }}" name="tag_{{ TAG.ID }}" value="{{ TAG.TITLE }}" {% if TAG.SELECTED %} checked="checked"{% endif %}>
|
||||
{{ TAG.TITLE }}
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<dd>
|
||||
{% if loops.tags|length %}
|
||||
{% for TAG in loops.tags %}
|
||||
<label class="content_tag" style="background: {{ TAG.COLOR }}">
|
||||
<label class="content_tag" style="background: #{{ TAG.COLOR }}">
|
||||
<input type="checkbox" id="tag_{{ TAG.ID }}" name="tag_{{ TAG.ID }}" value="{{ TAG.TITLE }}">
|
||||
{{ TAG.TITLE }}
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -6,9 +6,3 @@
|
|||
font-weight: bold;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.content_tag_checkbox {
|
||||
}
|
||||
|
||||
.content_tag_list {
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
[{"title":"Lesbian","color":"#dc8add","active":true,"searchable":true},{"title":"Hardcore","color":"#cfd11c","active":true,"searchable":true},{"title":"Softcore","color":"#ffbe6f","active":true,"searchable":true},{"title":"White","color":"#deddda","active":true,"searchable":true},{"title":"Ebony","color":"#77767b","active":true,"searchable":true},{"title":"Hispanic","color":"#cdab8f","active":true,"searchable":true},{"title":"Indian","color":"#986a44","active":true,"searchable":true},{"title":"Studio","color":"#4a87da","active":true,"searchable":true},{"title":"Non-nude","color":"#bcc28f","active":true,"searchable":true},{"title":"Gay","color":"#61c4c7","active":true,"searchable":true},{"title":"Pedomom","color":"#e73e61","active":true,"searchable":true},{"title":"Pedowoman","color":"#a9559b","active":true,"searchable":true},{"title":"Pedofamily","color":"#b02cd4","active":true,"searchable":true}]
|
||||
Loading…
Add table
Add a link
Reference in a new issue