Service za ether API, izboljsave nastavitev, validacija, manjsi popravek obrazca za dodajanje
parent
905b8e8b04
commit
8621c8f6f3
|
@ -18,6 +18,7 @@
|
|||
"composer/installers": "^2.0",
|
||||
"cweagans/composer-patches": "^1.7",
|
||||
"drupal/cer": "^5.0@beta",
|
||||
"drupal/config_ignore": "^3.1",
|
||||
"drupal/content_as_config": "^1.0",
|
||||
"drupal/core-composer-scaffold": "^10.0",
|
||||
"drupal/core-project-message": "^10.0",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
_core:
|
||||
default_config_hash: IgOVnECx6lbVt6JVFnadoEEugneDf3UblPZnOzov43Q
|
||||
mode: simple
|
||||
ignored_config_entities:
|
||||
- etherpad_api.settings
|
|
@ -6,7 +6,6 @@ dependencies:
|
|||
- field.field.node.concept.body
|
||||
- field.field.node.concept.field_media
|
||||
- field.field.node.concept.field_related_concept
|
||||
- field.field.node.concept.field_tags
|
||||
- node.type.concept
|
||||
- workflows.workflow.concept_workflow
|
||||
module:
|
||||
|
@ -52,16 +51,6 @@ content:
|
|||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
field_tags:
|
||||
type: entity_reference_autocomplete
|
||||
weight: 4
|
||||
region: content
|
||||
settings:
|
||||
match_operator: CONTAINS
|
||||
match_limit: 10
|
||||
size: 60
|
||||
placeholder: ''
|
||||
third_party_settings: { }
|
||||
langcode:
|
||||
type: language_select
|
||||
weight: 3
|
||||
|
|
|
@ -6,7 +6,6 @@ dependencies:
|
|||
- field.field.node.concept.body
|
||||
- field.field.node.concept.field_media
|
||||
- field.field.node.concept.field_related_concept
|
||||
- field.field.node.concept.field_tags
|
||||
- node.type.concept
|
||||
module:
|
||||
- text
|
||||
|
@ -40,14 +39,6 @@ content:
|
|||
third_party_settings: { }
|
||||
weight: 103
|
||||
region: content
|
||||
field_tags:
|
||||
type: entity_reference_label
|
||||
label: above
|
||||
settings:
|
||||
link: true
|
||||
third_party_settings: { }
|
||||
weight: 104
|
||||
region: content
|
||||
links:
|
||||
settings: { }
|
||||
third_party_settings: { }
|
||||
|
|
|
@ -7,7 +7,6 @@ dependencies:
|
|||
- field.field.node.concept.body
|
||||
- field.field.node.concept.field_media
|
||||
- field.field.node.concept.field_related_concept
|
||||
- field.field.node.concept.field_tags
|
||||
- node.type.concept
|
||||
module:
|
||||
- text
|
||||
|
@ -33,5 +32,4 @@ content:
|
|||
hidden:
|
||||
field_media: true
|
||||
field_related_concept: true
|
||||
field_tags: true
|
||||
langcode: true
|
||||
|
|
|
@ -10,6 +10,7 @@ module:
|
|||
ckeditor5: 0
|
||||
comment: 0
|
||||
config: 0
|
||||
config_ignore: 0
|
||||
config_translation: 0
|
||||
content_as_config: 0
|
||||
content_moderation: 0
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
uuid: f5fade64-73dc-420b-8c1f-ab4fe3355a52
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_tags
|
||||
- node.type.concept
|
||||
- taxonomy.vocabulary.tags
|
||||
id: node.concept.field_tags
|
||||
field_name: field_tags
|
||||
entity_type: node
|
||||
bundle: concept
|
||||
label: Tags
|
||||
description: ''
|
||||
required: false
|
||||
translatable: true
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:taxonomy_term'
|
||||
handler_settings:
|
||||
target_bundles:
|
||||
tags: tags
|
||||
sort:
|
||||
field: name
|
||||
direction: asc
|
||||
auto_create: true
|
||||
auto_create_bundle: ''
|
||||
field_type: entity_reference
|
|
@ -1,3 +1,3 @@
|
|||
_core:
|
||||
default_config_hash: 2OMXCScXUOLSYID9-phjO4q36nnnaMWNUlDxEqZzG1U
|
||||
use_admin_theme: true
|
||||
use_admin_theme: false
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
<script setup="setup">
|
||||
|
||||
const prikazi = ref(false)
|
||||
const revisionId = ref(null)
|
||||
|
||||
const dodajPojem = () => {
|
||||
revisionId.value = crypto.randomUUID()
|
||||
prikazi.value = true
|
||||
console.log('NOV POJEM!', revisionId.value)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<details>
|
||||
<summary class="gumb">
|
||||
<div>
|
||||
<div class="gumb" @click="dodajPojem()">
|
||||
Dodaj pojem
|
||||
</summary>
|
||||
<PojemForm />
|
||||
</details>
|
||||
</div>
|
||||
<PojemForm v-if="prikazi" :revisionId="revisionId" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -5,20 +5,21 @@ import { ref } from 'vue'
|
|||
const { etherpadUrl, etherpadPrefix } = useRuntimeConfig().public
|
||||
|
||||
const props = defineProps({
|
||||
revisionId: String
|
||||
revisionId: String,
|
||||
onLoad: Function
|
||||
})
|
||||
|
||||
const embed = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
// Ce ni revisionId propertyja, se random generira.
|
||||
const uuid = props.revisionId ? props.revisionId : crypto.randomUUID()
|
||||
const padUrl = `${etherpadUrl}p/${etherpadPrefix}${uuid}?showChat=false&showLineNumbers=false&toc=false`
|
||||
embed.value.src = padUrl
|
||||
window.location.hash = uuid
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<iframe ref="embed" class="etherpad-textarea" />
|
||||
<iframe ref="embed" class="etherpad-textarea" @load="props.onLoad" />
|
||||
</template>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<script setup="setup">
|
||||
|
||||
const { etherpadUrl, etherpadPrefix } = useRuntimeConfig().public
|
||||
|
||||
const store = usePojmiStore()
|
||||
|
||||
const props = defineProps({
|
||||
naslov: String
|
||||
naslov: String,
|
||||
revisionId: String
|
||||
})
|
||||
|
||||
//const pojem = computed(() => store.pojmi[props.naslov])
|
||||
|
@ -21,6 +25,14 @@ const oddajPredlog = data => {
|
|||
store.ustvariPojem(data)
|
||||
}
|
||||
|
||||
const etherNalozen = ev => {
|
||||
// @TODO DRY
|
||||
const padUrl = `${etherpadUrl}p/${etherpadPrefix}${props.revisionId}?showChat=false&showLineNumbers=false&toc=false`
|
||||
// Izprazni pad!
|
||||
console.log('etherpad nalozen!')
|
||||
window.location.hash = props.revisionId
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -31,7 +43,7 @@ const oddajPredlog = data => {
|
|||
<input name="naslov" type="text" v-model="naslov">
|
||||
|
||||
<label for="tekst">Besedilo</label>
|
||||
<EtherpadTextarea />
|
||||
<EtherpadTextarea :onLoad="etherNalozen" :revisionId="props.revisionId" />
|
||||
|
||||
<label for="email">E-poštni naslov</label>
|
||||
<input name="email" type="email" v-model="email">
|
||||
|
|
|
@ -1,95 +1,36 @@
|
|||
<?php
|
||||
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the Etherpad API module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function etherpad_api_install() {
|
||||
\Drupal::messenger()->addStatus(__FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function etherpad_api_uninstall() {
|
||||
\Drupal::messenger()->addStatus(__FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function etherpad_api_schema() {
|
||||
$schema['etherpad_api_example'] = [
|
||||
'description' => 'Table description.',
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary Key: Unique record ID.',
|
||||
],
|
||||
'uid' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'The {users}.uid of the user who created the record.',
|
||||
],
|
||||
'status' => [
|
||||
'description' => 'Boolean indicating whether this record is active.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 64,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Type of the record.',
|
||||
],
|
||||
'created' => [
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Timestamp when the record was created.',
|
||||
],
|
||||
'data' => [
|
||||
'type' => 'blob',
|
||||
'not null' => TRUE,
|
||||
'size' => 'big',
|
||||
'description' => 'The arbitrary data for the item.',
|
||||
],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
'indexes' => [
|
||||
'type' => ['type'],
|
||||
'uid' => ['uid'],
|
||||
'status' => ['status'],
|
||||
],
|
||||
];
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function etherpad_api_requirements($phase) {
|
||||
$requirements = [];
|
||||
|
||||
// Preveri ali api deluje
|
||||
if ($phase == 'runtime') {
|
||||
$value = mt_rand(0, 100);
|
||||
$requirements['etherpad_api_status'] = [
|
||||
'title' => t('Etherpad API status'),
|
||||
'value' => t('Etherpad API value: @value', ['@value' => $value]),
|
||||
'severity' => $value > 50 ? REQUIREMENT_INFO : REQUIREMENT_WARNING,
|
||||
];
|
||||
$client = Drupal::service('etherpad_api.client');
|
||||
|
||||
try {
|
||||
$client->checkToken();
|
||||
} catch (ClientException $exception) {
|
||||
$value = $exception->getCode();
|
||||
$msg = $exception->getMessage();
|
||||
$requirements['etherpad_api_status'] = [
|
||||
'title' => t('Etherpad API status'),
|
||||
'value' => t('Etherpad API not accessible (@code: @msg)', [
|
||||
'@code' => $exception->getCode(),
|
||||
'@msg' => $exception->getMessage()
|
||||
]),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
|
|
|
@ -3,3 +3,10 @@ services:
|
|||
class: Drupal\etherpad_api\PathProcessor\EtherpadAPIPathProcessor
|
||||
tags:
|
||||
- { name: path_processor_inbound, priority: 1000 }
|
||||
etherpad_api.settings:
|
||||
class: Drupal\Core\Config\ImmutableConfig
|
||||
factory: config.factory:get
|
||||
arguments: ['etherpad_api.settings']
|
||||
etherpad_api.client:
|
||||
class: Drupal\etherpad_api\Client
|
||||
arguments: ['@http_client', '@etherpad_api.settings']
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\etherpad_api;
|
||||
|
||||
use Drupal\Core\Config\ImmutableConfig;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
|
||||
/**
|
||||
* Service description.
|
||||
*/
|
||||
class Client {
|
||||
|
||||
/**
|
||||
* The HTTP client.
|
||||
*
|
||||
* @var \GuzzleHttp\ClientInterface
|
||||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* The config.
|
||||
*
|
||||
* @var \Drupal\Core\Config\ImmutableConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
protected $apiKey = null;
|
||||
protected $baseUrl = null;
|
||||
|
||||
// (Minimal) Etherpad version
|
||||
const API_VERSION = '1.2';
|
||||
|
||||
/**
|
||||
* Constructs a Client object.
|
||||
*
|
||||
* @param \GuzzleHttp\ClientInterface $httpClient
|
||||
* The HTTP client.
|
||||
* @param \Drupal\Core\Config\ImmutableConfig $config
|
||||
* The config.
|
||||
*/
|
||||
public function __construct(ClientInterface $httpClient, ImmutableConfig $config) {
|
||||
$this->httpClient = $httpClient;
|
||||
$this->config = $config;
|
||||
$this->baseUrl = rtrim($config->get('url'), '/');
|
||||
$this->apiKey = $config->get('key');
|
||||
}
|
||||
|
||||
public function checkToken() {
|
||||
return $this->request('get', '/checkToken');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description.
|
||||
*/
|
||||
public function request($method, $url) {
|
||||
$uri = "{$this->baseUrl}/" . self::API_VERSION . $url;
|
||||
|
||||
if (str_contains($uri, '?')) {
|
||||
$uri .= "&apikey={$this->apiKey}";
|
||||
} else {
|
||||
$uri .= "?apikey={$this->apiKey}";
|
||||
}
|
||||
|
||||
return $this->httpClient->request($method, $uri);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\etherpad_api\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
use Drupal\etherpad_api\Client;
|
||||
|
||||
/**
|
||||
* Returns responses for Etherpad API routes.
|
||||
*/
|
||||
class EtherpadApiController extends ControllerBase {
|
||||
protected $client;
|
||||
|
||||
public function __construct(Client $client) {
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('etherpad_api.client'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the response.
|
||||
*/
|
||||
public function build($components, Request $request) {
|
||||
$uri = str_replace(':', '/', $components);
|
||||
if ($params = $request->getQueryString()) {
|
||||
$uri .= "?$params";
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->client->request($request->getMethod(), $uri);
|
||||
} catch (ClientException $exception) {
|
||||
return new Response($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,47 +3,38 @@
|
|||
namespace Drupal\etherpad_api\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
use Drupal\etherpad_api\Client;
|
||||
|
||||
/**
|
||||
* Returns responses for Etherpad API routes.
|
||||
*/
|
||||
class EtherpadApiController extends ControllerBase {
|
||||
protected $httpClient;
|
||||
protected $config;
|
||||
protected $client;
|
||||
|
||||
public function __construct(ClientInterface $http_client, ConfigFactoryInterface $config_factory) {
|
||||
$this->httpClient = $http_client;
|
||||
$this->configFactory = $config_factory;
|
||||
public function __construct(Client $client) {
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('http_client'), $container->get('config.factory'));
|
||||
return new static($container->get('etherpad_api.client'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the response.
|
||||
*/
|
||||
public function build($components, Request $request) {
|
||||
$baseUrl = $this->config('etherpad_api.settings')->get('url');
|
||||
$apiKey = $this->config('etherpad_api.settings')->get('key');
|
||||
|
||||
$params = $request->getQueryString();
|
||||
if ($params) {
|
||||
$params .= "&apikey=$apiKey";
|
||||
} else {
|
||||
$params = "apikey=$apiKey";
|
||||
$uri = str_replace(':', '/', $components);
|
||||
if ($params = $request->getQueryString()) {
|
||||
$uri .= "?$params";
|
||||
}
|
||||
$uri = $baseUrl . str_replace(':', '/', $components) . "?$params";
|
||||
|
||||
$method = $request->getMethod();
|
||||
try {
|
||||
return $this->httpClient->request($method, $uri);
|
||||
return $this->client->request($request->getMethod(), $uri);
|
||||
} catch (ClientException $exception) {
|
||||
return new Response($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
|
|
|
@ -2,13 +2,29 @@
|
|||
|
||||
namespace Drupal\etherpad_api\Form;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
use Drupal\etherpad_api\Client;
|
||||
|
||||
/**
|
||||
* Configure Etherpad API settings for this site.
|
||||
*/
|
||||
class SettingsForm extends ConfigFormBase {
|
||||
protected $httpClient;
|
||||
protected $settings;
|
||||
|
||||
public function __construct(ClientInterface $httpClient) {
|
||||
$this->httpClient = $httpClient;
|
||||
$this->settings = $this->config('etherpad_api.settings');
|
||||
}
|
||||
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('http_client'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -31,12 +47,13 @@ class SettingsForm extends ConfigFormBase {
|
|||
$form['url'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Etherpad API URL'),
|
||||
'#default_value' => $this->config('etherpad_api.settings')->get('url'),
|
||||
'#required' => true,
|
||||
'#default_value' => $this->settings->get('url'),
|
||||
];
|
||||
$form['key'] = [
|
||||
'#type' => 'textfield',
|
||||
'#type' => 'password',
|
||||
'#title' => $this->t('Etherpad API key (found in instance root folder)'),
|
||||
'#default_value' => $this->config('etherpad_api.settings')->get('key'),
|
||||
'#default_value' => $this->settings->get('key'),
|
||||
];
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
@ -45,11 +62,22 @@ class SettingsForm extends ConfigFormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
if (!$form_state->getValue('url')) {
|
||||
$form_state->setErrorByName('url', $this->t('The value is required.'));
|
||||
// Check API accessibility
|
||||
$apiKey = $form_state->getValue('key');
|
||||
|
||||
if (!$apiKey) {
|
||||
$apiKey = $this->settings->get('key');
|
||||
}
|
||||
if (!$form_state->getValue('key')) {
|
||||
$form_state->setErrorByName('key', $this->t('The value is required.'));
|
||||
$baseUrl = $form_state->getValue('url');
|
||||
|
||||
$url = rtrim($baseUrl, '/') . "/1.2/checkToken?apikey=$apiKey";
|
||||
try {
|
||||
$this->httpClient->request('get', $url);
|
||||
} catch (ClientException $e) {
|
||||
$form_state->setErrorByName('url', $this->t('Etherpad API not accessible (@code: @msg). The URL or the API key is wrong', [
|
||||
'@value' => $e->getCode(),
|
||||
'@msg' => $e->getMessage()
|
||||
]));
|
||||
}
|
||||
parent::validateForm($form, $form_state);
|
||||
}
|
||||
|
@ -58,10 +86,12 @@ class SettingsForm extends ConfigFormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->config('etherpad_api.settings')
|
||||
->set('url', $form_state->getValue('url'))
|
||||
->set('key', $form_state->getValue('key'))
|
||||
->save();
|
||||
$this->settings->set('url', $form_state->getValue('url'));
|
||||
if ($form_state->getValue('key')) {
|
||||
$this->settings->set('key', $form_state->getValue('key'));
|
||||
}
|
||||
|
||||
$this->settings->save();
|
||||
parent::submitForm($form, $form_state);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue