Skip to content

Commit

Permalink
refactor: migrated tags page to controller (#3257)
Browse files Browse the repository at this point in the history
  • Loading branch information
thorsten committed Dec 1, 2024
1 parent a939f4d commit a4f06c8
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 147 deletions.
2 changes: 1 addition & 1 deletion nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ server {
rewrite admin/api/(.*) /admin/api/index.php last;

# Administration pages
rewrite admin/(attachments|backup|configuration|elasticsearch|export|group|import|instance|instances|password|session-keep-alive|statistics|stopwords|system|update|user) /admin/front.php last;
rewrite admin/(attachments|backup|configuration|elasticsearch|export|group|import|instance|instances|password|session-keep-alive|statistics|stopwords|system|tags|update|user) /admin/front.php last;

# REST API v3.0 and v3.1
rewrite ^api/v3\.[01]/(.*) /api/index.php last;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"type": "module",
"scripts": {
"build": "vite build",
"build:watch": "vite build --watch",
"build:watch": "vite build --watch -d",
"build:prod": "vite build",
"lint": "prettier --check .",
"lint:fix": "prettier --write .",
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/.htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Header set Access-Control-Allow-Headers "Content-Type, Authorization"
# Administration API
RewriteRule ^admin/api/(.*) admin/api/index.php [L,QSA]
# Administration pages
RewriteRule ^admin/(attachments|backup|configuration|elasticsearch|export|group|import|instance|instances|password|session-keep-alive|statistics|stopwords|system|update|user) admin/front.php [L,QSA]
RewriteRule ^admin/(attachments|backup|configuration|elasticsearch|export|group|import|instance|instances|password|session-keep-alive|statistics|stopwords|system|tags|update|user) admin/front.php [L,QSA]
# Private APIs
RewriteRule ^api/(autocomplete|bookmark/delete|bookmark/create|user/data/update|user/password/update|user/request-removal|user/remove-twofactor|contact|voting|register|captcha|share|comment/create|faq/create|question/create|webauthn/prepare|webauthn/register|webauthn/prepare-login|webauthn/login) api/index.php [L,QSA]
# Setup APIs
Expand Down
27 changes: 27 additions & 0 deletions phpmyfaq/admin/assets/src/api/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,30 @@ export const fetchTags = async (searchString) => {
throw error;
}
};

export const deleteTag = async (tagId) => {
try {
const response = await fetch(`./api/content/tags/${tagId}`, {
method: 'DELETE',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
});

if (response.ok) {
return await response.json();
} else {
throw new Error('Network response was not ok: ', { cause: { response } });
}
} catch (error) {
console.error('Error deleting tag:', error);
if (error.cause && error.cause.response) {
const errorMessage = await error.cause.response.json();
console.error(errorMessage);
}
throw error;
}
};
21 changes: 20 additions & 1 deletion phpmyfaq/admin/assets/src/content/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@

import autocomplete from 'autocompleter';
import { addElement } from '../../../../assets/src/utils';
import { fetchTags } from '../api';
import { deleteTag, fetchTags } from '../api';
import { pushNotification } from '../utils/index.js';

export const handleTags = () => {
const editTagButtons = document.querySelectorAll('.btn-edit');
const deleteButtons = document.querySelectorAll('.btn-delete');
const tagForm = document.getElementById('tag-form');
const tagsAutocomplete = document.querySelector('.pmf-tags-autocomplete');

Expand Down Expand Up @@ -51,6 +53,23 @@ export const handleTags = () => {
});
}

if (deleteButtons) {
deleteButtons.forEach((element) => {
element.addEventListener('click', async (event) => {
const tagId = event.target.getAttribute('data-pmf-id');

const response = await deleteTag(tagId);
if (response.success) {
pushNotification(response.success);
const row = document.getElementById(`pmf-row-tag-id-${tagId}`);
row.remove();
} else {
throw new Error('Network response was not ok: ' + JSON.stringify(response.error));
}
});
});
}

if (tagForm) {
tagForm.addEventListener('submit', (event) => {
event.preventDefault();
Expand Down
5 changes: 2 additions & 3 deletions phpmyfaq/admin/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@
$secLevelEntries['content'] .= $adminHelper->addMenuEntry(
PermissionType::FAQ_EDIT->value,
'tags',
'ad_entry_tags'
'ad_entry_tags',
'tags'
);
$secLevelEntries['content'] .= $adminHelper->addMenuEntry(
'addglossary+editglossary+delglossary',
Expand Down Expand Up @@ -201,8 +202,6 @@
case 'takequestion':
case 'comments':
case 'attachments':
case 'tags':
case 'delete-tag':
case 'stickyfaqs':
$contentPage = true;
break;
Expand Down
5 changes: 0 additions & 5 deletions phpmyfaq/admin/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,6 @@
case 'stickyfaqs':
require 'stickyfaqs.php';
break;
// functions for tags
case 'tags':
case 'delete-tag':
require 'tags.php';
break;
// news administration
case 'news':
case 'add-news':
Expand Down
72 changes: 0 additions & 72 deletions phpmyfaq/admin/tags.php

This file was deleted.

113 changes: 58 additions & 55 deletions phpmyfaq/assets/templates/admin/content/tags.twig
Original file line number Diff line number Diff line change
@@ -1,58 +1,61 @@
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i aria-hidden="true" class="bi bi-tags"></i>
{{ adminHeaderTags }}
</h1>
</div>


<div class="row">
<div class="col-lg-12">
<form action="" method="post" id="tag-form">
{{ csrfToken | raw }}

{% if isDelete %}
{% if isDeleteSuccess %}
<div class="alert alert-success" role="alert">
{{ msgDeleteSuccess }}
</div>
{% else %}
<div class="alert alert-danger" role="alert">
{{ msgDeleteError }}
{% extends '@admin/index.twig' %}

{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i aria-hidden="true" class="bi bi-tags"></i>
{{ adminHeaderTags }}
</h1>
</div>


<div class="row">
<div class="col-lg-12">
<form action="" method="post" id="tag-form">
{{ csrfToken | raw }}

{% if isDelete %}
{% if isDeleteSuccess %}
<div class="alert alert-success" role="alert">
{{ msgDeleteSuccess }}
</div>
{% else %}
<div class="alert alert-danger" role="alert">
{{ msgDeleteError }}
</div>
{% endif %}
{% endif %}

{% if tags|length == 0 %}
<div class="alert alert-info" role="alert">
{{ noTags }}
</div>
{% endif %}
{% endif %}

{% if tags|length == 0 %}
<div class="alert alert-info" role="alert">
{{ noTags }}
</div>
{% endif %}

<table class="table table-hover align-middle border shadow">
<tbody>

{% for key, tag in tags %}
<tr>
<td>
<span id="tag-id-{{ key }}">{{ tag }}</span>
</td>
<td>
<a class="btn btn-primary btn-edit" data-btn-id="{{ key }}" title="{{ buttonEdit }}">
<i aria-hidden="true" class="bi bi-pencil" data-btn-id="{{ key }}"></i>
</a>
</td>
<td>
<a class="btn btn-danger" onclick="return confirm('{{ msgConfirm }}');"
href="?action=delete-tag&amp;id={{ key }}">
<span title="{{ buttonDelete }}"><i aria-hidden="true" class="bi bi-trash"></i></span>
</a>
</td>
</tr>
{% endfor %}

</tbody>
</table>
</form>

<table class="table table-hover align-middle border shadow">
<tbody>

{% for key, tag in tags %}
<tr id="pmf-row-tag-id-{{ key }}">
<td>
<span id="tag-id-{{ key }}">{{ tag }}</span>
</td>
<td>
<a class="btn btn-primary btn-edit" data-btn-id="{{ key }}" title="{{ buttonEdit }}">
<i aria-hidden="true" class="bi bi-pencil" data-btn-id="{{ key }}"></i>
</a>
</td>
<td>
<button class="btn btn-danger btn-delete" type="button" data-pmf-id="{{ key }}">
<i aria-hidden="true" class="bi bi-trash"></i> {{ buttonDelete }}
</button>
</td>
</tr>
{% endfor %}

</tbody>
</table>
</form>
</div>
</div>
</div>
{% endblock %}
5 changes: 5 additions & 0 deletions phpmyfaq/src/admin-api-routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@
'controller' => [TagController::class, 'search'],
'methods' => 'GET'
],
'admin.api.content.tags.id' => [
'path' => '/content/tags/{tagId}',
'controller' => [TagController::class, 'delete'],
'methods' => 'GET'
],
// Update API
'admin.api.health-check' => [
'path' => '/health-check',
Expand Down
6 changes: 6 additions & 0 deletions phpmyfaq/src/admin-routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use phpMyFAQ\Controller\Administration\StatisticsSessionsController;
use phpMyFAQ\Controller\Administration\StopWordsController;
use phpMyFAQ\Controller\Administration\SystemInformationController;
use phpMyFAQ\Controller\Administration\TagController;
use phpMyFAQ\Controller\Administration\UpdateController;
use phpMyFAQ\Controller\Administration\UserController;
use Symfony\Component\Routing\Route;
Expand Down Expand Up @@ -195,6 +196,11 @@
'controller' => [SystemInformationController::class, 'index'],
'methods' => 'GET'
],
'admin.tags' => [
'path' => '/tags',
'controller' => [TagController::class, 'index'],
'methods' => 'GET'
],
'admin.update' => [
'path' => '/update',
'controller' => [UpdateController::class, 'index'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ protected function getHeader(Request $request): array
$userPage = true;
break;
case 'admin.attachments':
case 'admin.tags':
$contentPage = true;
break;
case 'admin.statistics.admin-log':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ public function update(Request $request): JsonResponse

$data = json_decode($request->getContent())->data;

if (!Token::getInstance()->verifyToken('edit-faq', $data->{'pmf-csrf-token'})) {
if (!Token::getInstance($this->container->get('session'))->verifyToken('edit-faq', $data->{'pmf-csrf-token'})) {
return $this->json(['error' => Translation::get('msgNoPermission')], Response::HTTP_UNAUTHORIZED);
}

Expand Down
Loading

0 comments on commit a4f06c8

Please sign in to comment.