Commit 24add8fa authored by Karl Hasselbring's avatar Karl Hasselbring
Browse files

Merge branch 'development' into 513-css-dateien-aufraumen

parents a53559e0 621ecc11
......@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\LanguageObject;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
......@@ -87,11 +88,11 @@ class LanguageController extends Controller
$langTexts[$dir] += count($this->getValues([$key => $value]));
}
$filePath[basename($filename)] = preg_replace("/lang\/.*?\//si", "lang/$to/", substr($filename, strpos($filename, "lang")));
}
}
}
$langs = [];
$fn = "";
$t = [];
......@@ -99,10 +100,11 @@ class LanguageController extends Controller
if ($exclude !== "") {
try {
$ex = unserialize(base64_decode($exclude));
} catch (\ErrorException $e) {
} catch (ErrorException $e) {
$ex = ['files' => [], 'new' => 0];
}
}
foreach ($texts as $filename => $text) {
$has = false;
foreach ($ex['files'] as $file) {
......@@ -118,7 +120,6 @@ class LanguageController extends Controller
}
# Hier können wir später die bereits bearbeiteten Dateien ausschließen.
foreach ($text as $textname => $languages) {
if ($languages === "") {
continue;
}
......@@ -136,25 +137,111 @@ class LanguageController extends Controller
if (!isset($languages[$to])) {
$fn = $filePath[$filename];
$t = $text;
break;
break 2;
}
}
}
$t = $this->htmlEscape($t, $to);
$t = $this->createHints($t, $to);
return view('languages.edit')
->with('texts', $t)
->with('filename', $fn)
->with('title', trans('titles.languages.edit'))
->with('langs', $langs)
->with('to', $to)
->with('langTexts', $langTexts)
->with('sum', $sum)
->with('new', $ex["new"])
->with('email', $email);
->with('texts', $t) //Array mit vorhandenen Übersetzungen der Datei $fn in beiden Sprachen
->with('filename', $fn) //Pfad zur angezeigten Datei
->with('title', trans('titles.languages.edit'))
->with('langs', $langs) //Ausgangssprache (1 Element)
->with('to', $to) //zu bearbeitende Sprache
->with('langTexts', $langTexts) //Anzahl der vorhandenen Übersetzungen
->with('sum', $sum) //Alle vorhandenen Texte (in allen Dateien) in beiden Sprachen in einem Array
->with('new', $ex["new"]) //
->with('email', $email); //Email-Adresse des Benutzers
}
public function createSynopticEditPage(Request $request, $exclude = "")
{
$languageFilePath = resource_path() . "/lang/";
$languageFolders = scandir($languageFilePath);
#Enthält zu jeder Sprache ein Objekt mit allen Daten
$languageObjects = [];
$to = [];
#Dekodieren ausgeschlossener Dateien anhand des URL-Parameters
$ex = ['files' => [], 'new' => 0];
if ($exclude !== "") {
try {
$ex = unserialize(base64_decode($exclude));
} catch (\ErrorException $e) {
$ex = ['files' => [], 'new' => 0];
}
}
#Instanziiere LanguageObject
foreach ($languageFolders as $folder) {
if (is_dir($languageFilePath . $folder) && $folder !== "." && $folder !== "..") {
$languageObjects[$folder] = new LanguageObject($folder, $languageFilePath.$folder);
}
}
#Speichere Daten in LanguageObject, überspringe ausgeschlossene Dateien
foreach ($languageObjects as $folder => $languageObject) {
$to[] = $folder;
$di = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($languageObject->filePath));
foreach($di as $filename => $file) {
foreach($ex['files'] as $file) {
if($file === basename($filename)) {
continue 2;
}
}
if(!$this->endsWith($filename, ".")) {
$tmp = include $filename;
foreach ($tmp as $key => $value) {
$languageObject->saveData(basename($filename), $key, $value);
}
}
}
}
$fn = "";
#Wähle die erste, unbearbeitete Datei aus
foreach($languageObjects as $folder => $languageObject) {
foreach($languageObject->stringMap as $languageFileName => $languageFile) {
$fn = $languageFileName;
break 2;
}
}
if($fn === "") {
//Alles bearbeitet -> zeige entsprechende Nachricht
}
$snippets = [];
#Speichere den Inhalt der ausgewählten Datei in allen Sprachen in $snippets ab
foreach($languageObjects as $folder => $languageObject) {
foreach($languageObject->stringMap as $languageFileName => $languageFile) {
if($languageFileName === $fn) {
foreach($languageFile as $key => $value) {
$snippets[$key][$languageObject->language] = $value;
}
continue 2;
}
}
}
#Fülle $snippets auf mit leeren Einträgen für übrige Sprachen
foreach($to as $t) {
foreach($snippets as $key => $langArray) {
if(!isset($langArray[$t])) {
$snippets[$key][$t] = "";
}
}
}
return view('languages.synoptic')
->with('to', $to) #Alle vorhandenen Sprachen
->with('texts', $snippets) #Array mit Sprachsnippets
->with('filename', $fn) #Name der Datei
->with('title', trans('titles.languages.edit'));
}
private function htmlEscape($t, $to)
......
......@@ -9,6 +9,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Response;
use LaravelLocalization;
use Mail;
use ZipArchive;
class MailController extends Controller
{
......@@ -117,14 +118,54 @@ class MailController extends Controller
}
#Ueberprueft ob ein bereits vorhandener Eintrag bearbeitet worden ist
private function isEdited($k, $v, $filename)
{
try {
$temp = include resource_path()."/".$filename;
foreach ($temp as $key => $value) {
if($k === $key && $v !== $value) {
return true;
}
}
} catch (\ErrorException $e) {
#Datei existiert noch nicht
return true;
}
return false;
}
private function extractLanguage($key)
{
#Kürzt bspw. "_new_de_redirect bzw. "de_redirect" zu "de"
preg_match("/^(?:_new_)?([^_]*)/", $key, $matches);
foreach($matches as $dir) {
if(strlen($dir) == 2)
return $dir;
}
}
private function processKey($key)
{
$key = trim($key);
#Kürzt bspw. "_new_de_redirect bzw. "de_redirect" zu "redirect"
preg_match("/^(?:_new_)?(?:[^_]*)_(\w*.?\w*#?.?\w*)/", $key, $matches);
foreach($matches as $processedKey) {
if(strpos($processedKey, "_") === FALSE) {
return $processedKey;
}
}
return $key;
}
public function sendLanguageFile(Request $request, $from, $to, $exclude = "", $email ="")
{
$filename = $request->input('filename');
# Wir erstellen nun zunächst den Inhalt der Datei:
$data = [];
$new = 0;
$emailAddress = "";
$editedKeys = "";
foreach ($request->all() as $key => $value) {
if ($key === "filename" || $value === "") {
......@@ -138,7 +179,13 @@ class MailController extends Controller
if (strpos($key, "_new_") === 0 && $value !== "") {
$new++;
$key = substr($key, strpos($key, "_new_") + 5);
$editedKeys = $editedKeys."\n".$key;
} else if ($this->isEdited($key, $value, $filename)) {
$new++;
$editedKeys = $editedKeys."\n".$key;
}
$key = trim($key);
if (!strpos($key, "#")) {
$data[$key] = $value;
......@@ -151,7 +198,6 @@ class MailController extends Controller
$ref = &$ref[$key];
$ref = $value;
}
}
$output = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
......@@ -161,10 +207,8 @@ class MailController extends Controller
$output = "<?php\n\nreturn $output;\n";
$message = "Moin moin,\n\nein Benutzer hat eine Sprachdatei aktualisiert.\nSollten die Texte so in Ordnung sein, ersetzt, oder erstellt die Datei aus dem Anhang in folgendem Pfad:\n$filename\n\nFolgend zusätzlich der Inhalt der Datei:\n\n$output";
// echo $request->old('email');
//echo $request->input('email','test');
// die("");
$message = "Moin moin,\n\nein Benutzer hat eine Sprachdatei aktualisiert.\nBearbeitet wurden die Einträge: $editedKeys\n\nSollten die Texte so in Ordnung sein, ersetzt, oder erstellt die Datei aus dem Anhang in folgendem Pfad:\n$filename\n\nFolgend zusätzlich der Inhalt der Datei:\n\n$output";
# Wir haben nun eine Mail an uns geschickt, welche die entsprechende Datei beinhaltet.
# Nun müssen wir den Nutzer eigentlich nur noch zurück leiten und die Letzte bearbeitete Datei ausschließen:
$ex = [];
......@@ -189,8 +233,7 @@ class MailController extends Controller
if($emailAddress !== "") {
Mail::to("dev@suma-ev.de")
->send(new Sprachdatei($message, $output, basename($filename), $emailAddress));
}
else {
} else {
Mail::to("dev@suma-ev.de")
->send(new Sprachdatei($message, $output, basename($filename)));
}
......@@ -199,4 +242,124 @@ class MailController extends Controller
return redirect(url('languages/edit', ['from' => $from, 'to' => $to, 'exclude' => $ex, 'email' => $emailAddress]));
}
public function processSynopticPageInput(Request $request, $exclude = "") {
$filename = $request->input('filename');
#Identifizieren des gedrückten Buttons
if(isset($request['nextpage'])) {
#Leite weiter zur nächsten Seite
$ex = [];
if ($exclude !== "") {
try {
$ex = unserialize(base64_decode($exclude));
} catch (\ErrorException $e) {
$ex = [];
}
if (!isset($ex["files"])) {
$ex["files"] = [];
}
}
if (!isset($ex["new"])) {
$ex["new"] = 0;
}
$ex['files'][] = basename($filename);
$ex = base64_encode(serialize($ex));
return redirect(url('synoptic', ['exclude' => $ex]));
}
#Andernfalls auslesen, zippen und herunterladen der veränderten Dateien
$data = [];
$new = 0;
$editedFiles = [];
foreach ($request->all() as $key => $value) {
if ($key === "filename" || $value === "") {
continue;
}
$key = base64_decode($key);
#Pfad zur Datei anhand des Schlüsselnamens rekonstruieren (Schlüssel enthält Sprachkürzel)
$langdir = $this->extractLanguage($key);
$filepath = "lang/".$langdir."/".$filename;
if (strpos($key, "_new_") === 0 && $value !== "" || $this->isEdited($this->processKey($key), $value, $filepath)) {
$new++;
$editedFiles[$langdir] = $filepath;
}
}
#Erneute Iteration über Request, damit Dateien mitsamt vorherigen Einträgen abgespeichert werden
foreach($request->all() as $key => $value) {
if ($key === "filename" || $value === "") {
continue;
}
$key = base64_decode($key);
#Pfad zur Datei anhand des Schlüsselnamens rekonstruieren (Schlüssel enthält Sprachkürzel)
$langdir = $this->extractLanguage($key);
#Überspringe Datei, falls diese nicht bearbeitet worden ist
if(!isset($editedFiles[$langdir])) {
continue;
}
#Key kuerzen, sodass er nur den eigentlichen Keynamen enthält
$key = $this->processKey($key);
if (!strpos($key, "#")) {
$data[$langdir][$key] = $value;
#Aufdröseln von 2D-Arrays
} else {
$ref = &$data;
do {
$ref = &$ref[$langdir][substr($key, 0, strpos($key, "#"))];
$key = substr($key, strpos($key, "#") + 1);
} while (strpos($key, "#"));
$ref = &$ref[$key];
$ref = $value;
}
}
if(empty($data)) {
return redirect(url('synoptic', ['exclude' => $exclude]));
}
$zip = new ZipArchive();
if ($zip->open("langfiles.zip", ZipArchive::OVERWRITE)!==TRUE) {
} else if ($zip->open("langfiles.zip", ZipArchive::CREATE)!==TRUE) {
exit("Cannot open".$filename);
}
#Erstelle Ausgabedateien
foreach($data as $lang => $entries) {
$output = json_encode($entries, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$output = preg_replace("/\{/si", "[", $output);
$output = preg_replace("/\}/si", "]", $output);
$output = preg_replace("/\": ([\"\[])/si", "\"\t=>\t$1", $output);
$output = "<?php\n\nreturn $output;\n";
$zip->addEmptyDir($lang);
$zip->addFromString($lang."/".$filename, $output);
}
$zip->close();
return response()->download("langfiles.zip", $filename.".zip");
}
}
......@@ -169,7 +169,7 @@ class MetaGerSearch extends Controller
}
}
/*
# Wikipedia Quicktip
$url = "https://" . APP::getLocale() . ".wikipedia.org/w/api.php?action=opensearch&search=" . urlencode($q) . "&limit=10&namespace=0&format=json&redirects=resolve";
try{
......@@ -203,7 +203,7 @@ class MetaGerSearch extends Controller
$quicktips[] = $quicktip;
}
$mquicktips = array_merge($mquicktips, $quicktips);
*/
if (APP::getLocale() === "de") {
# Dict.cc Quicktip
if (count(explode(' ', $q)) < 3) {
......
<?php
namespace App\Models;
/*
* Hilfsklasse, welche zu je einer Sprache Angaben zum Pfad der jeweiligen Datei, sowie die vorhandenen Übersetzungen enthält
*/
class LanguageObject
{
public $language = "";
public $filePath = "";
#2D-Array der Form [$filename][$key]
public $stringMap = [];
public function __construct($lang, $path)
{
$this->language = $lang;
$this->filePath = $path;
}
#Speichert Daten in $stringMap, entdimensionalisiert ggbf. $value
public function saveData($filename, $key, $value)
{
if(is_array($value)) {
$this->deMultiDimensionalize($filename, $key, $value);
} else {
$this->stringMap[$filename][$key] = $value;
}
}
private function deMultiDimensionalize($filename, $key, $value)
{
foreach($value as $key2 => $value2) {
$this->saveData($filename, $key."#".$key2, $value2);
}
}
}
\ No newline at end of file
......@@ -24,7 +24,9 @@ elixir(function (mix) {
*/
mix.scripts(['lib/jquery.js', 'lib/jquery-ui.min.js', 'lib/bootstrap.js', 'lib/lightslider.js', 'lib/masonry.js', 'lib/imagesloaded.js', 'lib/openpgp.min.js', 'lib/iframeResizer.min.js', 'lib/md5.js'], 'public/js/lib.js')
mix.scripts(['lib/jquery.js', 'lib/iframeResizer.contentWindow.min.js'], 'public/js/quicktips.js')
mix.version(['css/themes/default.css', 'js/lib.js', 'js/quicktips.js'])
mix.scripts(['scriptStartPage.js', 'results.js'], 'public/js/scriptStartPage.js');
mix.scripts(['scriptResultPage.js', 'results.js'], 'public/js/scriptResultPage.js');
mix.version(['css/themes/default.css', 'js/lib.js', 'js/quicktips.js']);
mix.less('metager/beitritt.less', 'public/css/beitritt.css')
mix.version(['css/beitritt.css'])
mix.version(['js/widgets.js', 'js/editLanguage.js', 'js/kontakt.js', 'js/scriptResultPage.js', 'js/scriptStartPage.js', 'js/settings.js'])
......
This diff is collapsed.
......@@ -5,7 +5,10 @@ $(document).ready(function () {
var custom = $('#foki > li.active').hasClass('custom-focus-tab-selector');
getDocumentReadyForUse(focus, custom);
botProtection();
new Results(); // Adds the saved Results if they are present
new Results().updateResultPageInterface(); // Adds the saved Results if they are present
if(document.location.href.indexOf("focus=container") !== -1){
$($("#foki > li#savedFokiTabSelector").get(0)).find(">a").tab("show");
}
});
function activateJSOnlyContent () {
......@@ -517,15 +520,59 @@ function initialLoadContent (fokus) {
});
}
function resultSaver(index) {
var title = $(".result[data-count=" + index + "] a.title").html();
var link = $(".result[data-count=" + index + "] a.title").attr("href");
var anzeigeLink = $(".result[data-count=" + index + "] div.link-link > a").html();
var gefVon = $(".result[data-count=" + index + "] span.hoster").html();
var hoster = $(".result[data-count=" + index + "] a.title").attr("data-hoster");
var anonym = $(".result[data-count=" + index + "] a.proxy").attr("href");
var description = $(".result[data-count=" + index + "] div.description").html();
var color = $(".result[data-count=" + index + "] div.number").css("color");
var rank = parseFloat($(".result[data-count=" + index + "]").attr("data-rank"));
new Result(title, link, anzeigeLink, gefVon, hoster, anonym, description, color, rank, undefined);
var to = $("#savedFokiTabSelector").length ? $("#savedFokiTabSelector") : $("#foki");
$(".result[data-count=" + index + "]").transfer({to: to, duration: 1000});
new Results().updateResultPageInterface();
}
/*
* This object gathers all stored Result Objects and can Update the Interface to show them.
*/
function Results(){
function Results(sort){
if(!localStorage) return;
this.prefix = "result_";
this.results = [];
this.updateResults();
this.updateInterface();
this.length = this.results.length;
this.sortResults(sort);
}
Results.prototype.sortResults = function(sortType){
if(sortType === undefined) sortType = "chronological";
switch(sortType){
case "chronological":
this.results.sort(function(a,b){
if(a.added > b.added) return -1;
if(a.added < b.added) return 1;
return 0;
});
break;
case "rank":
this.results.sort(function(a,b){
if(a.rank > b.rank) return -1;
if(a.rank < b.rank) return 1;
return 0;
});
break;
case "alphabetical":
this.results.sort(function(a,b){
if(b.hostname > a.hostname) return -1;
if(b.hostname < a.hostname) return 1;
return 0;
});
break;
}
}
Results.prototype.updateResults = function(){
......@@ -534,7 +581,7 @@ Results.prototype.updateResults = function(){
if(localStorage.key(i).indexOf(this.prefix) === 0){
var key = localStorage.key(i);
key = key.substr(this.prefix.length);
var tmpResult = new Result(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, key);
var tmpResult = new Result(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, key);
tmpResult.setIndex(i);
this.results.push(tmpResult);
}
......@@ -554,7 +601,7 @@ Results.prototype.deleteResults = function(){
});
}
Results.prototype.updateInterface = function(){
Results.prototype.updateResultPageInterface = function(sortType){
if(this.results.length === 0){
$("#savedFokiTabSelector, #savedFoki").remove();
$($("#foki > li[data-loaded=1]").get(0)).find(">a").tab("show");
......@@ -584,31 +631,44 @@ Results.prototype.updateInterface = function(){
$("#savedFoki").html("");
var tabPanel = $("#savedFoki");
}
if(this.results.length > 0) this.addToContainer(tabPanel);
this.addToContainer(tabPanel, sortType);
}
Results.prototype.addToContainer = function(container){
Results.prototype.addToContainer = function(container, sortType){
$.each(this.results, function(index, result){
$(container).append(result.toHtml());
});
var options = $('\
<div class="saver-options row">\
<input class="form-control" type="text" placeholder="Filtern">\
<button class="btn btn-danger btn-md"><span class="glyphicon glyphicon-trash"></span> Alle Ergebnisse aus dem Speicher entfernen</button>\
<select class="form-control">\
<option value="chronological">Chronologisch</option>\
<option value="rank">MetaGer-Ranking</option>\
<option value="alphabetical">Alphabetisch (Hostname)</option>\
</select>\
<button class="btn btn-danger btn-md"><span class="glyphicon glyphicon-trash"></span> <span class="hidden-xs">Ergebnisse</span> löschen</button>\
</div>\
');
$(options).find("option[value=" + sortType + "]").prop("selected", true);
$(container).prepend(options);
$(options).find("select").change(function(){
new Results($(this).val()).updateResultPageInterface();