Commit 38b39c93 authored by Matthias Larisch's avatar Matthias Larisch

Region twig

parent 3f869951
Pipeline #25055865 failed with stages
in 8 minutes and 23 seconds
......@@ -21,6 +21,7 @@ $finder = PhpCsFixer\Finder::create()
->notPath('tests/_support/_generated')
->notPath('src/Lib/Flourish')
->notPath('cache')
->notPath('client')
->in(__DIR__)
;
......
......@@ -3,6 +3,8 @@
## Features
- updated fpdi plugin to v2.0.2 !351 #168 by @peter.toennies
- update symfony to 4.1.0 as well as other dependencies !351 @NerdyProjects
- remove user list in forums to allow big regions to work !421 @NerdyProjects
- add php intl component for localized internationalization !421 @NerdyProjects
## Bugfixes
- removed XSS-possibility in xhr_out method. !370 @theolampert
......@@ -32,6 +34,7 @@
- reduced size of DataBase classes !409 @peter.toennies
- refactored login and registration !403 @theolampert
- partial refactor of Basket module !426 @nicksellen
- refactored region module into twig/webpack loaded javascript !421 @NerdyProjects
- add constants class database constants in region module !413 @peter.toennies @nicksellen
## Dev/Test/CI stuff
......
......@@ -22,6 +22,7 @@
"leaflet.awesome-markers": "^2.0.4",
"leaflet.markercluster": "0.4.0",
"magnific-popup": "^1.1.0",
"object-path": "^0.11.4",
"raven-js": "^3.23.3",
"socket.io-client": "1.5.0",
"timeago": "^1.4.1",
......@@ -44,6 +45,7 @@
"imports-loader": "^0.8.0",
"jsdom": "^11.11.0",
"jsdom-global": "^3.0.2",
"json-loader": "^0.5.7",
"koa-connect": "^2.0.1",
"loader-utils": "^1.1.0",
"mini-css-extract-plugin": "^0.2.0",
......@@ -60,7 +62,8 @@
"webpack-bundle-analyzer": "^2.11.1",
"webpack-cli": "^2.0.12",
"webpack-merge": "^4.1.3",
"webpack-serve": "^0.2.0"
"webpack-serve": "^0.2.0",
"yaml-loader": "^0.5.0"
},
"babel": {
"presets": [
......
import serverData from '@/server-data'
import trans from '@translations/lang.de.yml'
import objectPath from 'object-path'
const { translations } = serverData
export default function (key, variables = {}) {
const message = translations[key]
let message = objectPath.get(trans, key)
if (!message) message = translations[key]
if (!message) throw new Error(`Missing translation for [${key}]`)
return message.replace(/\{([^}]+)\}/g, (match, name) => {
const value = variables[name]
......
/* eslint-disable eqeqeq,camelcase */
import $ from 'jquery'
import i18n from '@/i18n'
import { expose } from '@/utils'
expose({ u_delPost, mb_finishImage })
export function u_delPost (postId, module, wallId) {
$.ajax({
url: '/xhrapp.php?app=wallpost&m=delpost&table=' + module + '&id=' + wallId + '&post=' + postId,
dataType: 'JSON',
success: function (data) {
if (data.status == 1) {
$('.wallpost-' + postId).remove()
}
}
})
}
export function mb_finishImage (file) {
$('#wallpost-attach').append('<input type="hidden" name="attach[]" value="image-' + file + '" />')
$('#attach-preview div:last').remove()
$('.attach-load').remove()
$('#attach-preview').append('<a rel="wallpost-gallery" class="preview-thumb" href="images/wallpost/' + file + '"><img src="images/wallpost/thumb_' + file + '" height="60" /></a>')
$('#attach-preview').append('<div style="clear:both;"></div>')
$('#attach-preview a').fancybox()
mb_clear()
}
function mb_clear () {
$('#wallpost-loader').html('')
$('a.attach-load').remove()
}
export function init (module, wallId) {
$('#wallpost-text').autosize()
$('#wallpost-text').focus(function () {
$('#wallpost-submit').show()
})
$('#wallpost-attach-trigger').change(function () {
$('#attach-preview div:last').remove()
$('#attach-preview').append('<a rel="wallpost-gallery" class="preview-thumb attach-load" href="#" onclick="return false;">&nbsp;</a>')
$('#attach-preview').append('<div style="clear:both;"></div>')
$('#wallpost-attachimage-form').submit()
})
$('#wallpost-text').blur(function () {
$('#wallpost-submit').show()
})
$('#wallpost-post').submit(function (ev) {
ev.preventDefault()
})
$('#wallpost-attach-image').button().click(function () {
$('#wallpost-attach-trigger').click()
})
$('#wall-submit').button().click(function (ev) {
ev.preventDefault()
if (($('#wallpost-text').val() != '' && $('#wallpost-text').val() != i18n('wall.message_placeholder')) || $('#attach-preview a').length > 0) {
$('.wall-posts table tr:first').before('<tr><td colspan="2" class="load">&nbsp;</td></tr>')
let attach = ''
$('#wallpost-attach input').each(function () {
attach = attach + ':' + $(this).val()
})
if (attach.length > 0) {
attach = attach.substring(1)
}
let text = $('#wallpost-text').val()
if (text == i18n('wall.message_placeholder')) {
text = ''
}
$.ajax({
url: '/xhrapp.php?app=wallpost&m=post&table=' + module + '&id=' + wallId,
type:
'POST',
data:
{
text: text,
attach: attach
},
dataType: 'JSON',
success:
function (data) {
$('#wallpost-attach').html('')
if (data.status == 1) {
$('.wall-posts').html(data.html)
$('.preview-thumb').fancybox()
if (data.script != undefined) {
$.globalEval(data.script)
}
}
}
})
$('#wallpost-text').val('')
$('#attach-preview').html('')
$('#wallpost-attach').html('')
$('#wallpost-text')[0].focus()
$('#wallpost-text').css('height', '33px')
}
})
$('#wallpost-attach-trigger').focus(function () {
$('#wall-submit')[0].focus()
})
$.ajax({
url: '/xhrapp.php?app=wallpost&m=update&table=' + module + '&id=' + wallId + '&last=0',
dataType:
'JSON',
success:
function (data) {
if (data.status == 1) {
$('.wall-posts').html(data.html)
$('.preview-thumb').fancybox()
}
}
})
}
......@@ -64,6 +64,7 @@ module.exports = merge(webpackBase, {
'Basket',
'Dashboard',
'Foodsaver',
'Region',
'StoreUser',
'WorkGroup',
'Login',
......@@ -100,7 +101,8 @@ module.exports = merge(webpackBase, {
'js': resolve('../js'),
'@': resolve('src'),
'@php': resolve('../src'),
'>': resolve('test')
'>': resolve('test'),
'@translations': resolve('../lang')
}
},
module: {
......@@ -109,7 +111,14 @@ module.exports = merge(webpackBase, {
test: /\.css$/,
use: [
dev ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader'
{
loader: 'css-loader',
options: {
alias: {
'./img': ('img')
}
}
}
]
},
{
......@@ -127,6 +136,16 @@ module.exports = merge(webpackBase, {
limit: 10000,
name: dev ? 'fonts/[name].[ext]' : 'fonts/[name].[hash:7].[ext]'
}
},
{
test: /\.yml$/,
exclude: [
/(node_modules)/
],
use: [
'json-loader',
'yaml-loader'
]
}
]
},
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0bf8bb8acbcc46d263755cfb5a91b063",
"content-hash": "113b2b20481a301222ed6b0160ab9e48",
"packages": [
{
"name": "ddeboer/imap",
......@@ -3559,6 +3559,62 @@
"homepage": "https://symfony.com",
"time": "2018-05-30T07:26:09+00:00"
},
{
"name": "twig/extensions",
"version": "v1.5.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig-extensions.git",
"reference": "d188c76168b853481cc75879ea045bf93d718e9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/d188c76168b853481cc75879ea045bf93d718e9c",
"reference": "d188c76168b853481cc75879ea045bf93d718e9c",
"shasum": ""
},
"require": {
"twig/twig": "~1.27|~2.0"
},
"require-dev": {
"symfony/phpunit-bridge": "~3.3@dev",
"symfony/translation": "~2.3|~3.0"
},
"suggest": {
"symfony/translation": "Allow the time_diff output to be translated"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-0": {
"Twig_Extensions_": "lib/"
},
"psr-4": {
"Twig\\Extensions\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Common additional features for Twig that do not directly belong in core",
"homepage": "http://twig.sensiolabs.org/doc/extensions/index.html",
"keywords": [
"i18n",
"text"
],
"time": "2017-06-08T18:19:53+00:00"
},
{
"name": "twig/twig",
"version": "v2.4.8",
......@@ -5194,16 +5250,16 @@
},
{
"name": "phpunit/phpunit",
"version": "6.5.8",
"version": "6.5.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b"
"reference": "093ca5508174cd8ab8efe44fd1dde447adfdec8f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4f21a3c6b97c42952fd5c2837bb354ec0199b97b",
"reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/093ca5508174cd8ab8efe44fd1dde447adfdec8f",
"reference": "093ca5508174cd8ab8efe44fd1dde447adfdec8f",
"shasum": ""
},
"require": {
......@@ -5274,7 +5330,7 @@
"testing",
"xunit"
],
"time": "2018-04-10T11:38:34+00:00"
"time": "2018-07-03T06:40:40+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
......@@ -5341,12 +5397,12 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "0e4ea9f9e1fd3c6a563524f8f399696d98c7c85a"
"reference": "5c802c6300dca269edde06c6ae8c7eb561de3176"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0e4ea9f9e1fd3c6a563524f8f399696d98c7c85a",
"reference": "0e4ea9f9e1fd3c6a563524f8f399696d98c7c85a",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/5c802c6300dca269edde06c6ae8c7eb561de3176",
"reference": "5c802c6300dca269edde06c6ae8c7eb561de3176",
"shasum": ""
},
"conflict": {
......@@ -5397,7 +5453,7 @@
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
"magento/magento1ce": ">=1.5.0.1,<1.9.3.2",
"magento/magento1ee": ">=1.9,<1.14.3.2",
"magento/magento2ce": ">=2,<2.2",
"magento/magento2ce": ">=2,<2.3",
"monolog/monolog": ">=1.8,<1.12",
"namshi/jose": "<2.2",
"onelogin/php-saml": "<2.10.4",
......@@ -5448,7 +5504,7 @@
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
"thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3",
"thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
"titon/framework": ">=0,<9.9.99",
"twig/twig": "<1.20",
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.22|>=8,<8.7.5",
......@@ -5500,7 +5556,7 @@
}
],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
"time": "2018-06-08T09:55:50+00:00"
"time": "2018-07-03T10:42:36+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
......
......@@ -16,6 +16,7 @@ if (!defined('SOCK_URL')) {
}
date_default_timezone_set('Europe/Berlin');
locale_set_default('de-DE');
/*
* Read revision from revision file.
* It is supposed to define SRC_REVISION.
......
......@@ -26,6 +26,7 @@ services:
- [addExtension, ['@Symfony\Bridge\Twig\Extension\TranslationExtension']]
- [addExtension, ['@Symfony\Bridge\Twig\Extension\FormExtension']]
- [addExtension, ['@Twig_Extension_Debug']]
- [addExtension, ['@Twig_Extension_Intl']]
- [addExtension, ['@Foodsharing\Lib\TwigExtensions']]
Twig:
......@@ -36,6 +37,9 @@ services:
Twig_Extension_Debug:
class: Twig_Extension_Debug
Twig_Extension_Intl:
class: Twig_Extensions_Extension_Intl
Symfony\Bridge\Twig\Extension\TranslationExtension:
class: Symfony\Bridge\Twig\Extension\TranslationExtension
arguments:
......@@ -68,6 +72,8 @@ services:
- ['addResource', ['yml', 'lang/lang.de.yml', 'de', 'messages']]
- ['setFallbackLocales', [['de']]]
Symfony\Component\Translation\TranslatorInterface: '@translator'
validator:
class: Symfony\Component\Validator\ValidatorBuilder
factory: [Symfony\Component\Validator\Validation, createValidatorBuilder]
......
FROM registry.gitlab.com/foodsharing-dev/images/php:2.9
FROM registry.gitlab.com/foodsharing-dev/images/php:2.11
WORKDIR /app
......
......@@ -22,7 +22,7 @@ services:
app:
container_name: foodsharing_dev_app
image: registry.gitlab.com/foodsharing-dev/images/php:2.9
image: registry.gitlab.com/foodsharing-dev/images/php:2.11
working_dir: /app
expose:
- 9000
......@@ -59,7 +59,7 @@ services:
mailqueuerunner:
container_name: foodsharing_dev_mailqueuerunner
image: registry.gitlab.com/foodsharing-dev/images/php:2.9
image: registry.gitlab.com/foodsharing-dev/images/php:2.11
command: php run.php Mails queueWorker
restart: always
depends_on:
......
......@@ -24,7 +24,7 @@ services:
app:
container_name: foodsharing_test_app
image: registry.gitlab.com/foodsharing-dev/images/php:2.9
image: registry.gitlab.com/foodsharing-dev/images/php:2.11
working_dir: /app
expose:
- 9000
......@@ -62,7 +62,7 @@ services:
mailqueuerunner:
container_name: foodsharing_test_mailqueuerunner
image: registry.gitlab.com/foodsharing-dev/images/php:2.9
image: registry.gitlab.com/foodsharing-dev/images/php:2.11
command: php run.php Mails queueWorker
working_dir: /app
restart: always
......
......@@ -5,14 +5,20 @@ picture_upload_widget:
button:
change_picture: Bild ändern
attach_image: Bild anhängen
rotate_right: im Uhrzeigersinn drehen
upload: Hochladen
yes_i_am_sure: Ja, ich bin mir sicher
abort: Abbrechen
send: Senden
answer: Antworten
group:
name: Name
description: Beschreibung
photo: Foto
applications: Bewerbungen
applications_for: Bewerbungen für %name%
application_requirements:
requirements: Wer kann sich für diese Gruppe eintragen?
nobody: Niemand (geschlossene Gruppe)
......@@ -42,6 +48,9 @@ group:
join: Dieser Arbeitsgruppe beitreten
safe: Änderungen speichern
no_groups: Hier gibt es noch keine Arbeitsgruppen
quit_name: Team %name% verlassen
quit: Verlassen
really_quit_name: Möchtest Du wirklich den Bezirk bzw. das Team %name% verlassen?
legal:
pp: Datenschutzerklärung
......@@ -112,3 +121,63 @@ register:
pass1: Dein neues gewünschtes Passwort
pass2: Passwortwiederholung
terminology:
forum: Forum
events: Termine
ambassador_forum: BotschafterInnenforum
ambassadors: Botschafter
wall: Pinnwand
fsp: Fair-Teiler
groups: Arbeitsgruppen
group: Arbeitsgruppe
n_foodsaver: 'Ein Foodsaver|%count% Foodsaver'
n_sleeping: 'Eine Schlafmütze|%count% Schlafmützen'
n_ambassadors: 'Ein(e) BotschafterIn|%count% BotschafterInnen'
n_stores: 'Ein Betrieb|%count% Betriebe'
n_cooperating_stores: 'Eine laufende Kooperation|%count% laufende Kooperationen'
statistics:
kg_food_saved: '%count% kg Lebensmittel gerettet'
num_fetches: 'Bei einem Rettungseinsatz|Bei %count% Rettungseinsätzen'
are_you_sure: Bist Du sicher?
really_delete: Wirklich löschen?
yes: Ja
no: Nein
options: Optionen
forum:
from: Von %name%
threads: Themen
new_thread: Neues Thema verfassen
subscribe_thread: Möchtest Du über dieses Thema auf dem Laufenden gehalten werden?
thread_is_inactive: Thema inaktiv!
thread_is_inactive_description: Dieses Thema ist noch nicht aktiv. Hier hast Du die Möglichkeit das Thema zu akzeptieren und alle Foodsaver darüber zu informieren.
placeholder_answer: Antworten...
unfollow: Thema entfolgen
follow: Thema folgen
stick: Thema fixieren
unstick: Fixierung aufheben
delete_post: Beitrag löschen
thread_title: Titel
post_body: Nachricht
activate_thread: Thema aktivieren
delete_thread: Thema löschen
hold_back_for_moderation: Das Thema wurde gespeichert und wird veröffentlicht sobald ein Botschafter es bestätigt.
no_threads: Noch keine Themen gepostet
chat:
open_chat: Nachricht schreiben
wall:
name: Pinnwand
message_placeholder: Nachricht schreiben...
fairteiler:
all_at: Alle Fair-Teiler in %name%
add_new: Neuer Fair-Teiler
events:
name: Termine
add_new_event: Jetzt neuen Termin eintragen
add_event: Neues Event
......@@ -169,7 +169,7 @@ abstract class Control
public function wallposts($table, $id)
{
$this->func->addJsFunc('
function u_delPost(id)
function u_delPost(id, module, wallId)
{
var id = id;
$.ajax({
......
<?php
namespace Foodsharing\Modules\Region;
use Symfony\Component\Validator\Constraints as Assert;
class CreateForumPostData
{
/**
* @Assert\Type("string")
* @Assert\NotBlank()
*/
public $body;
/**
* @Assert\Type("integer")
* @Assert\Range(
* min = 0,
* max = 1
* )
*/
public $subscribe;
public $thread;
public static function create(bool $isFollowing, int $threadId)
{
$data = new self();
$data->subscribe = $isFollowing ? 1 : 0;
$data->thread = $threadId;
return $data;
}
public function toArray(): array
{
$res = [
'body' => $this->body,
'subscribe' => $this->subscribe,
'thread' => $this->thread
];
return $res;
}
}
<?php
namespace Foodsharing\Modules\Region;
use Symfony\Component\Validator\Constraints as Assert;
class CreateForumThreadData
{
/**
* @Assert\Type("string")
* @Assert\NotBlank()
*/
public $title;
/**
* @Assert\Type("string")
* @Assert\NotBlank()
*/
public $body;
public static function create()
{
$data = new self();
return $data;
}
}
<?php
namespace Foodsharing\Modules\Region;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class ForumCreateThreadForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, ['label' => 'forum.thread_title'])
->add('body', TextAreaType::class, ['label' => 'forum.post_body'])
;
}
}
......@@ -2,7 +2,6 @@
namespace Foodsharing\Modules\Region;
use Foodsharing\Lib\Session\S;
use Foodsharing\Modules\Bell\BellGateway;
use Foodsharing\Modules\Core\BaseGateway;
use Foodsharing\Modules\Core\Database;
......@@ -74,11 +73,25 @@ class ForumGateway extends BaseGateway
return $ret;
}
return false;
return [];
}
public function getThread($bezirk_id, $thread_id, $bot_theme = 0)
public function getThreadInfo($threadId)
{
return $this->db->fetch('
SELECT t.name,
bt.bezirk_id as region_id,
bt.bot_theme as ambassador_forum
FROM fs_theme t
LEFT JOIN fs_bezirk_has_theme bt ON bt.theme_id = t.id
WHERE t.id = :thread_id
', ['thread_id' => $threadId]);
}
public function getThread($bezirk_id, $thread_id, $bot_theme = false)
{
$bot_theme_v = $bot_theme ? 1 : 0;
return $this->db->fetch('
SELECT t.id,
t.name,
......@@ -91,7 +104,8 @@ class ForumGateway extends BaseGateway
p.`time` AS post_time,
UNIX_TIMESTAMP(p.`time`) AS post_time_ts,
t.last_post_id,
t.`active`
t.`active`,
t.`sticky`
FROM fs_theme t
INNER JOIN
......@@ -110,11 +124,12 @@ class ForumGateway extends BaseGateway
LIMIT 1
', ['bezirk_id' => $bezirk_id, 'thread_id' => $thread_id, 'bot_theme' => $bot_theme]);
', ['bezirk_id' => $bezirk_id, 'thread_id' => $thread_id, 'bot_theme' => $bot_theme_v]);
}
public function addThread($fs_id, $bezirk_id, $name, $body, $bot_theme = 0, $active)
public function addThread($fs_id, $bezirk_id, $name, $body, $bot_theme = false, $active)