documentation updates
fixed namespaces add doygen generation, unhappy with phpDocumentordevelop
parent
ed84e3be71
commit
6ea9c2728f
|
@ -3,4 +3,5 @@ vendor
|
||||||
php/version.php
|
php/version.php
|
||||||
php-docs
|
php-docs
|
||||||
.phpdoc
|
.phpdoc
|
||||||
phpdoc
|
phpdoc
|
||||||
|
html
|
||||||
|
|
|
@ -49,7 +49,6 @@ return [
|
||||||
//
|
//
|
||||||
// Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist.
|
// Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist.
|
||||||
// (See `backward_compatibility_checks` for additional options)
|
// (See `backward_compatibility_checks` for additional options)
|
||||||
// TODO: Choose a target_php_version for this project, or leave as null and remove this comment
|
|
||||||
'target_php_version' => '8.3',
|
'target_php_version' => '8.3',
|
||||||
|
|
||||||
// If enabled, missing properties will be created when
|
// If enabled, missing properties will be created when
|
||||||
|
|
35
php/api.php
35
php/api.php
|
@ -13,16 +13,32 @@
|
||||||
*/
|
*/
|
||||||
class Api extends Main
|
class Api extends Main
|
||||||
{
|
{
|
||||||
/** @var string called path */
|
/**
|
||||||
|
* called path
|
||||||
|
*
|
||||||
|
* @var string $path
|
||||||
|
*/
|
||||||
private $path;
|
private $path;
|
||||||
|
|
||||||
/** @var array<string> path elements for the API call */
|
/**
|
||||||
|
* path elements for the API call
|
||||||
|
*
|
||||||
|
* @var array<string> $paths
|
||||||
|
* */
|
||||||
private $paths;
|
private $paths;
|
||||||
|
|
||||||
/** @var Data\User current user */
|
/**
|
||||||
|
* current user
|
||||||
|
*
|
||||||
|
* @var Data\User $user
|
||||||
|
* */
|
||||||
private $user;
|
private $user;
|
||||||
|
|
||||||
/** @var int cache time default to 0 */
|
/**
|
||||||
|
* cache time default to 0
|
||||||
|
*
|
||||||
|
* @var int $cacheTime
|
||||||
|
*/
|
||||||
private $cacheTime = 0;
|
private $cacheTime = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +75,6 @@ class Api extends Main
|
||||||
$this->openDatabase();
|
$this->openDatabase();
|
||||||
$this->loadPlugins();
|
$this->loadPlugins();
|
||||||
$retval = "";
|
$retval = "";
|
||||||
/** @var \Api\Api */
|
|
||||||
$handler = null;
|
$handler = null;
|
||||||
if (!array_key_exists('HTTP_X_SESSION', $_SERVER) || !array_key_exists('HTTP_X_PROFILE', $_SERVER)) {
|
if (!array_key_exists('HTTP_X_SESSION', $_SERVER) || !array_key_exists('HTTP_X_PROFILE', $_SERVER)) {
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
|
@ -148,7 +163,7 @@ class Api extends Main
|
||||||
* permission(s) to check for
|
* permission(s) to check for
|
||||||
* @param string $exception Exception Type
|
* @param string $exception Exception Type
|
||||||
* @param string $message optional message
|
* @param string $message optional message
|
||||||
* @throws \Exceptions\PermissionDenied
|
* @throws Exceptions\PermissionDenied
|
||||||
*/
|
*/
|
||||||
public function checkPermission($permission, $exception = "\Exceptions\PermissionDenied", $message = null) : void
|
public function checkPermission($permission, $exception = "\Exceptions\PermissionDenied", $message = null) : void
|
||||||
{
|
{
|
||||||
|
@ -225,14 +240,15 @@ class Api extends Main
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* parameter name
|
* parameter name
|
||||||
* @param array<string,mixed> $data
|
* @param array<string, mixed> $data
|
||||||
* array to update
|
* array to update
|
||||||
* @param bool $int
|
* @param bool $int
|
||||||
* is data an integer
|
* is data an integer
|
||||||
* @param string $altName
|
* @param string $altName
|
||||||
* optional alternative name in POST
|
* optional alternative name in POST
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function updateString(string $name, array &$data, bool $int = false, string $altName = "") : void
|
public function updateString($name, &$data, $int = false, $altName = "")
|
||||||
{
|
{
|
||||||
if ($this->hasPost($altName ?: $name)) {
|
if ($this->hasPost($altName ?: $name)) {
|
||||||
$content = $this->escapePost($altName ?: $name, $int);
|
$content = $this->escapePost($altName ?: $name, $int);
|
||||||
|
@ -244,8 +260,9 @@ class Api extends Main
|
||||||
* set cache time
|
* set cache time
|
||||||
*
|
*
|
||||||
* @param int $time time in seconds
|
* @param int $time time in seconds
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setCacheTime(int $time) : void
|
public function setCacheTime($time)
|
||||||
{
|
{
|
||||||
$this->cacheTime = $time;
|
$this->cacheTime = $time;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,15 @@ interface V1
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* run given url path
|
* run given url path
|
||||||
* @param string[] $paths path array split by /
|
*
|
||||||
|
* @param array<string> $paths path array split by /
|
||||||
* @return bool true on success
|
* @return bool true on success
|
||||||
*/
|
*/
|
||||||
public function exec($paths) : bool;
|
public function exec($paths);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get internal represenation as json string
|
* get internal represenation as json string
|
||||||
* @return string json string or html
|
* @return string json string or html
|
||||||
*/
|
*/
|
||||||
public function toJson() : string;
|
public function toJson();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,23 @@ namespace Federator\Api\V1;
|
||||||
*/
|
*/
|
||||||
class Dummy implements \Federator\Api\V1
|
class Dummy implements \Federator\Api\V1
|
||||||
{
|
{
|
||||||
/** @var \Main $main main instance */
|
/**
|
||||||
|
* \Federator\Main instance
|
||||||
|
*
|
||||||
|
* @var \Federator\Main $main
|
||||||
|
*/
|
||||||
private $main;
|
private $main;
|
||||||
|
|
||||||
/** @var Array<string, string> $message internal message to output */
|
/**
|
||||||
|
* internal message to output
|
||||||
|
*
|
||||||
|
* @var Array<string, mixed> $message
|
||||||
|
*/
|
||||||
private $message = [];
|
private $message = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
|
*
|
||||||
* @param \Main $main main instance
|
* @param \Main $main main instance
|
||||||
*/
|
*/
|
||||||
public function __construct(\Federator\Main $main)
|
public function __construct(\Federator\Main $main)
|
||||||
|
@ -30,7 +39,8 @@ class Dummy implements \Federator\Api\V1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* run given url path
|
* run given url path
|
||||||
* @param string[] $paths path array split by /
|
*
|
||||||
|
* @param array<string> $paths path array split by /
|
||||||
* @return bool true on success
|
* @return bool true on success
|
||||||
*/
|
*/
|
||||||
public function exec($paths) : bool
|
public function exec($paths) : bool
|
||||||
|
@ -60,8 +70,10 @@ class Dummy implements \Federator\Api\V1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get function for "/v1/dummy/moo"
|
* get function for "/v1/dummy/moo"
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getDummy(): bool
|
public function getDummy()
|
||||||
{
|
{
|
||||||
$this->message = [
|
$this->message = [
|
||||||
'r1' => ' (__) ',
|
'r1' => ' (__) ',
|
||||||
|
@ -75,17 +87,20 @@ class Dummy implements \Federator\Api\V1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* post function for /v1/dummy/moo"
|
* post function for /v1/dummy/moo"
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function postDummy() : bool
|
public function postDummy()
|
||||||
{
|
{
|
||||||
return $this->getDummy();
|
return $this->getDummy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get internal represenation as json string
|
* get internal represenation as json string
|
||||||
|
*
|
||||||
* @return string json string
|
* @return string json string
|
||||||
*/
|
*/
|
||||||
public function toJson() : string
|
public function toJson()
|
||||||
{
|
{
|
||||||
return json_encode($this->message, JSON_PRETTY_PRINT) . "\n";
|
return json_encode($this->message, JSON_PRETTY_PRINT) . "\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ interface Cache extends \Federator\Connector\Connector
|
||||||
* save remote user by given session
|
* save remote user by given session
|
||||||
* @param string $_session session id
|
* @param string $_session session id
|
||||||
* @param string $_user user/profile name
|
* @param string $_user user/profile name
|
||||||
* @return \Federator\Data\User | null
|
* @aramm \Federator\Data\User $user user data
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function saveRemoteUserBySession(string $_session, string $_user, \Federator\Data\User $user);
|
public function saveRemoteUserBySession($_session, $_user, $user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ interface Connector
|
||||||
* get remote user by given session
|
* get remote user by given session
|
||||||
* @param string $_session session id
|
* @param string $_session session id
|
||||||
* @param string $_user user/profile name
|
* @param string $_user user/profile name
|
||||||
* @return \Federator\Data\User | null
|
* @return \Federator\Data\User | false
|
||||||
*/
|
*/
|
||||||
public function getRemoteUserBySession(string $_session, string $_user);
|
public function getRemoteUserBySession(string $_session, string $_user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,24 +13,38 @@ namespace Federator\Data;
|
||||||
*/
|
*/
|
||||||
class User
|
class User
|
||||||
{
|
{
|
||||||
/** @var string user id */
|
/**
|
||||||
|
* user id
|
||||||
|
*
|
||||||
|
* @var string $id
|
||||||
|
*/
|
||||||
public $id;
|
public $id;
|
||||||
|
|
||||||
/* @var string user language */
|
/* @var string user language */
|
||||||
//public $lang;
|
//public $lang;
|
||||||
|
|
||||||
/** @var array<string> user permissions */
|
/**
|
||||||
|
* user permissions
|
||||||
|
*
|
||||||
|
* @var array<string> $permissions
|
||||||
|
* @todo convert to enum
|
||||||
|
*/
|
||||||
public $permissions = [];
|
public $permissions = [];
|
||||||
|
|
||||||
/** @var string session id */
|
/**
|
||||||
|
* session id
|
||||||
|
*
|
||||||
|
* @var string $session
|
||||||
|
* */
|
||||||
public $session;
|
public $session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if use has asked permission
|
* check if use has asked permission
|
||||||
* @param string $p @unused-param
|
* @param string $p @unused-param
|
||||||
* permission to check
|
* permission to check
|
||||||
*
|
*
|
||||||
* @return bool true if user has permission, false if not
|
* @return bool true if user has permission, false if not
|
||||||
|
* @todo convert to ENUM
|
||||||
*/
|
*/
|
||||||
public function hasPermission(string $p)
|
public function hasPermission(string $p)
|
||||||
{
|
{
|
||||||
|
|
514
php/language.php
514
php/language.php
|
@ -1,263 +1,279 @@
|
||||||
-<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||||
*/
|
*/
|
||||||
require_once '../vendor/autoload.php';
|
|
||||||
|
namespace Federator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Language abstraction class
|
* Language abstraction class
|
||||||
* @author Sascha Nitsch
|
* @author Sascha Nitsch
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Language {
|
class Language
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* list of valid languages
|
* list of valid languages
|
||||||
* @var array
|
*
|
||||||
*/
|
* @var array $validLanguages
|
||||||
private $validLanguages = array(
|
*/
|
||||||
"de" => true,
|
private $validLanguages = array(
|
||||||
"en" => true,
|
"de" => true,
|
||||||
"xy" => true
|
"en" => true,
|
||||||
);
|
"xy" => true
|
||||||
|
|
||||||
/**
|
|
||||||
* language to use
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $uselang;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* actual language data
|
|
||||||
* @var array<string,array<string,string>>
|
|
||||||
*/
|
|
||||||
private $lang = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* constructor that tries to autodetect language
|
|
||||||
*
|
|
||||||
* @param ?string $uselang
|
|
||||||
* use this language instead of autodetection, set to null if no preference
|
|
||||||
*/
|
|
||||||
function __construct($uselang = null) {
|
|
||||||
$this->lang = Array();
|
|
||||||
if ($uselang !== null) {
|
|
||||||
if (! array_key_exists($uselang, $this->validLanguages)) {
|
|
||||||
$uselang = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($uselang === null && array_key_exists('_lang', $_REQUEST)) {
|
|
||||||
$language = $_REQUEST['_lang'];
|
|
||||||
if (array_key_exists($language, $this->validLanguages)) {
|
|
||||||
$uselang = $language;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($uselang === null && array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
|
|
||||||
$matches = array();
|
|
||||||
if (preg_match("/^(\S\S)\-/",$_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches) == 1) {
|
|
||||||
$language = $matches[1];
|
|
||||||
if (array_key_exists($language, $this->validLanguages)) {
|
|
||||||
$uselang = $language;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($uselang === null) {
|
|
||||||
$uselang = 'de';
|
|
||||||
}
|
|
||||||
$this->uselang = $uselang;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* print translation of given group and id, optionally using variables
|
|
||||||
*
|
|
||||||
* @param string $group
|
|
||||||
* group name
|
|
||||||
* @param string $key
|
|
||||||
* string name
|
|
||||||
* @param array<mixed> $values
|
|
||||||
* optional values to replace
|
|
||||||
* @return string translated string
|
|
||||||
*/
|
|
||||||
function printlang($group, $key, array $values = array()) {
|
|
||||||
if ($this->uselang === 'xy') {
|
|
||||||
return "$group:$key";
|
|
||||||
}
|
|
||||||
if (! isset($this->lang[$group])) {
|
|
||||||
$l = [];
|
|
||||||
$root = $_SERVER['DOCUMENT_ROOT'];
|
|
||||||
if ($root === '') $root = '.';
|
|
||||||
if (@file_exists($root . '/../lang/' . $this->uselang . "/$group.inc")) {
|
|
||||||
require ($root . '/../lang/' . $this->uselang . "/$group.inc");
|
|
||||||
$this->lang[$group] = $l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (array_key_exists($group, $this->lang) && array_key_exists($key, $this->lang[$group])) {
|
|
||||||
$string = $this->lang[$group][$key];
|
|
||||||
for ($i = 0; $i < 9; $i ++) {
|
|
||||||
if (isset($values[$i])) {
|
|
||||||
$string = str_replace("\$$i", $values[$i], $string);
|
|
||||||
} else {
|
|
||||||
$string = str_replace("\$$i", "", $string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
$basedir = $_SERVER['DOCUMENT_ROOT'] . '/../';
|
|
||||||
$fh = @fopen("$basedir/logs/missingtrans.txt", 'a');
|
|
||||||
if ($fh !== false) {
|
|
||||||
fwrite($fh, $this->uselang.":$group:$key\n");
|
|
||||||
fclose($fh);
|
|
||||||
}
|
|
||||||
return ">>$group:$key<<";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get keys (valid ids) of a named group
|
|
||||||
*
|
|
||||||
* @param string $group
|
|
||||||
* group name to fetch keys
|
|
||||||
* @return array<string> list of keys
|
|
||||||
*/
|
|
||||||
function getKeys(string $group) {
|
|
||||||
if (! isset($this->lang[$group])) {
|
|
||||||
$l = [];
|
|
||||||
require_once ($_SERVER['DOCUMENT_ROOT'] . '/../lang/' . $this->uselang . "/$group.inc");
|
|
||||||
$this->lang[$group] = $l;
|
|
||||||
}
|
|
||||||
return array_keys($this->lang[$group]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return current used language
|
|
||||||
*
|
|
||||||
* @return string current language
|
|
||||||
*/
|
|
||||||
function getLang() {
|
|
||||||
return $this->uselang;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* guess langauge of text
|
|
||||||
* @param string $text
|
|
||||||
* @param string $default
|
|
||||||
* @return string detected language
|
|
||||||
*/
|
|
||||||
static function guessLanguage(string $text, string $default, bool $debug = false) {
|
|
||||||
$supported_languages = array(
|
|
||||||
'en',
|
|
||||||
'de',
|
|
||||||
);
|
|
||||||
$wordList = [];
|
|
||||||
// German word list
|
|
||||||
// from http://wortschatz.uni-leipzig.de/Papers/top100de.txt
|
|
||||||
$wordList['de'] = array (
|
|
||||||
'die', 'der', 'und', /*'in',*/ 'zu', 'den', 'das', 'nicht', 'von', 'sie',
|
|
||||||
'ist', 'des', 'sich', 'mit', 'dem', 'dass', 'er', 'es', 'ein', 'ich',
|
|
||||||
'auf', 'so', 'eine', 'auch', 'als', 'an', 'nach', 'wie', 'im', 'für',
|
|
||||||
'man', 'aber', 'aus', 'durch', 'wenn', 'nur', 'war', 'noch', 'werden',
|
|
||||||
'bei', 'hat', 'wir', 'was', 'wird', 'sein', 'einen', 'welche', 'sind',
|
|
||||||
'oder', 'zur', 'um', 'haben', 'einer', 'mir', 'über', 'ihm', 'diese',
|
|
||||||
'einem', 'ihr', 'uns', 'da', 'zum', 'kann', 'doch', 'vor', 'dieser',
|
|
||||||
'mich', 'ihn', 'du', 'hatte', 'seine', 'mehr', 'am', 'denn', 'nun',
|
|
||||||
'unter', 'sehr', 'selbst', 'schon', 'hier', 'bis', 'habe', 'ihre',
|
|
||||||
'dann', 'ihnen', 'seiner', 'alle', 'wieder', 'meine', 'Zeit', 'gegen',
|
|
||||||
'vom', 'ganz', 'einzelnen', 'wo', 'muss', 'ohne', 'eines', 'können',
|
|
||||||
'sei', 'geschrieben', 'instanzen', 'deutsch','aktualisierung', 'registrierung'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// English word list
|
/**
|
||||||
// from http://en.wikipedia.org/wiki/Most_common_words_in_English
|
* language to use
|
||||||
$wordList['en'] = array ('the', 'be', 'to', 'of', 'and', 'a', /*'in',*/
|
*
|
||||||
'that', 'have', 'I', 'it', 'for', 'not', 'on', 'with', 'he',
|
* @var string $uselang
|
||||||
'as', 'you', 'do', 'at', 'this', 'but', 'his', 'by', 'from', 'they',
|
*/
|
||||||
'we', 'say', 'her', 'she', 'or', 'an', 'will', 'my', 'one', 'all',
|
private $uselang;
|
||||||
'would', 'there', 'their', 'what', 'so', 'up', 'out', 'if', 'about'
|
|
||||||
);
|
|
||||||
// French word list
|
|
||||||
// from https://1000mostcommonwords.com/1000-most-common-french-words/
|
|
||||||
/*$wordList['fr'] = array ('comme', 'que', 'tait', 'pour', 'sur', 'sont', 'avec',
|
|
||||||
'tre', 'un', 'ce', 'par', 'mais', 'que', 'est',
|
|
||||||
'il', 'eu', 'la', 'et', 'dans');*/
|
|
||||||
|
|
||||||
// Spanish word list
|
/**
|
||||||
// from https://spanishforyourjob.com/commonwords/
|
* actual language data
|
||||||
/*$wordList['es'] = array ('que', 'no', 'a', 'la', 'el', 'es', 'y',
|
*
|
||||||
'en', 'lo', 'un', 'por', 'qu', 'si', 'una',
|
* @var array<string, array<string, string>> $lang
|
||||||
'los', 'con', 'para', 'est', 'eso', 'las');*/
|
*/
|
||||||
|
private $lang = [];
|
||||||
|
|
||||||
// clean out the input string - note we don't have any non-ASCII
|
/**
|
||||||
// characters in the word lists... change this if it is not the
|
* constructor that tries to autodetect language
|
||||||
// case in your language wordlists!
|
*
|
||||||
$txt = strip_tags($text);
|
* @param ?string $uselang
|
||||||
$txt = preg_replace("/[^A-Za-z:\\/\\.]+/", ' ', $txt);
|
* use this language instead of autodetection, set to null if no preference
|
||||||
if ($debug) echo "text: '$txt'\n";
|
*/
|
||||||
$counter = [];
|
public function __construct($uselang = null)
|
||||||
// count the occurrences of the most frequent words
|
{
|
||||||
foreach ($supported_languages as $language) {
|
$this->lang = [];
|
||||||
$counter[$language]=0;
|
if ($uselang !== null) {
|
||||||
}
|
if (! array_key_exists($uselang, $this->validLanguages)) {
|
||||||
foreach ($supported_languages as $language) {
|
$uselang = null;
|
||||||
for ($i = 0; $i < sizeof($wordList[$language]); ++$i) {
|
}
|
||||||
$count = substr_count($txt, ' ' .$wordList[$language][$i] . ' ');
|
|
||||||
if ($debug && $count > 0) {
|
|
||||||
echo $language . " " . $wordList[$language][$i] . " => $count\n";
|
|
||||||
}
|
}
|
||||||
$counter[$language] += $count;
|
if ($uselang === null && array_key_exists('_lang', $_REQUEST)) {
|
||||||
}
|
$language = $_REQUEST['_lang'];
|
||||||
}
|
if (array_key_exists($language, $this->validLanguages)) {
|
||||||
if ($debug)
|
$uselang = $language;
|
||||||
print_r($counter);
|
}
|
||||||
// get max counter value
|
|
||||||
$max = max($counter);
|
|
||||||
$maxs = array_keys($counter, $max);
|
|
||||||
// if there are two winners - fall back to default!
|
|
||||||
if (count($maxs) == 1) {
|
|
||||||
$winner = $maxs[0];
|
|
||||||
$second = 0;
|
|
||||||
// get runner-up (second place)
|
|
||||||
foreach ($supported_languages as $language) {
|
|
||||||
if ($language !== $winner) {
|
|
||||||
if ($counter[$language]>$second) {
|
|
||||||
$second = $counter[$language];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if ($uselang === null && array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
|
||||||
// apply arbitrary threshold of 50%
|
$matches = array();
|
||||||
if (($second / $max) < 0.5) {
|
if (preg_match("/^(\S\S)\-/", $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches) == 1) {
|
||||||
return $winner;
|
$language = $matches[1];
|
||||||
}
|
if (array_key_exists($language, $this->validLanguages)) {
|
||||||
|
$uselang = $language;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($uselang === null) {
|
||||||
|
$uselang = 'en';
|
||||||
|
}
|
||||||
|
$this->uselang = $uselang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print translation of given group and id, optionally using variables
|
||||||
|
*
|
||||||
|
* @param string $group
|
||||||
|
* group name
|
||||||
|
* @param string $key
|
||||||
|
* string name
|
||||||
|
* @param array<mixed> $values
|
||||||
|
* optional values to replace
|
||||||
|
* @return string translated string
|
||||||
|
*/
|
||||||
|
public function printlang($group, $key, array $values = array())
|
||||||
|
{
|
||||||
|
if ($this->uselang === 'xy') {
|
||||||
|
return "$group:$key";
|
||||||
|
}
|
||||||
|
if (! isset($this->lang[$group])) {
|
||||||
|
$l = [];
|
||||||
|
$root = $_SERVER['DOCUMENT_ROOT'];
|
||||||
|
if ($root === '') {
|
||||||
|
$root = '.';
|
||||||
|
}
|
||||||
|
if (@file_exists($root . '/../lang/' . $this->uselang . "/$group.inc")) {
|
||||||
|
require($root . '/../lang/' . $this->uselang . "/$group.inc");
|
||||||
|
$this->lang[$group] = $l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (array_key_exists($group, $this->lang) && array_key_exists($key, $this->lang[$group])) {
|
||||||
|
$string = $this->lang[$group][$key];
|
||||||
|
for ($i = 0; $i < 9; $i ++) {
|
||||||
|
if (isset($values[$i])) {
|
||||||
|
$string = str_replace("\$$i", $values[$i], $string);
|
||||||
|
} else {
|
||||||
|
$string = str_replace("\$$i", "", $string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
$basedir = $_SERVER['DOCUMENT_ROOT'] . '/../';
|
||||||
|
$fh = @fopen("$basedir/logs/missingtrans.txt", 'a');
|
||||||
|
if ($fh !== false) {
|
||||||
|
fwrite($fh, $this->uselang.":$group:$key\n");
|
||||||
|
fclose($fh);
|
||||||
|
}
|
||||||
|
return ">>$group:$key<<";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get keys (valid ids) of a named group
|
||||||
|
*
|
||||||
|
* @param string $group
|
||||||
|
* group name to fetch keys
|
||||||
|
* @return array<string> list of keys
|
||||||
|
*/
|
||||||
|
public function getKeys(string $group)
|
||||||
|
{
|
||||||
|
if (! isset($this->lang[$group])) {
|
||||||
|
$l = [];
|
||||||
|
require_once($_SERVER['DOCUMENT_ROOT'] . '/../lang/' . $this->uselang . "/$group.inc");
|
||||||
|
$this->lang[$group] = $l;
|
||||||
|
}
|
||||||
|
return array_keys($this->lang[$group]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return current used language
|
||||||
|
*
|
||||||
|
* @return string current language
|
||||||
|
*/
|
||||||
|
public function getLang()
|
||||||
|
{
|
||||||
|
return $this->uselang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* guess langauge of text
|
||||||
|
*
|
||||||
|
* @param string $text input text
|
||||||
|
* @param string $default default language
|
||||||
|
* @param bool $debug debug flag
|
||||||
|
* @return string detected language
|
||||||
|
*/
|
||||||
|
public static function guessLanguage($text, $default, $debug = false)
|
||||||
|
{
|
||||||
|
$supported_languages = array(
|
||||||
|
'en',
|
||||||
|
'de',
|
||||||
|
);
|
||||||
|
$wordList = [];
|
||||||
|
// German word list
|
||||||
|
// from http://wortschatz.uni-leipzig.de/Papers/top100de.txt
|
||||||
|
$wordList['de'] = array (
|
||||||
|
'die', 'der', 'und', /*'in',*/ 'zu', 'den', 'das', 'nicht', 'von', 'sie',
|
||||||
|
'ist', 'des', 'sich', 'mit', 'dem', 'dass', 'er', 'es', 'ein', 'ich',
|
||||||
|
'auf', 'so', 'eine', 'auch', 'als', 'an', 'nach', 'wie', 'im', 'für',
|
||||||
|
'man', 'aber', 'aus', 'durch', 'wenn', 'nur', 'war', 'noch', 'werden',
|
||||||
|
'bei', 'hat', 'wir', 'was', 'wird', 'sein', 'einen', 'welche', 'sind',
|
||||||
|
'oder', 'zur', 'um', 'haben', 'einer', 'mir', 'über', 'ihm', 'diese',
|
||||||
|
'einem', 'ihr', 'uns', 'da', 'zum', 'kann', 'doch', 'vor', 'dieser',
|
||||||
|
'mich', 'ihn', 'du', 'hatte', 'seine', 'mehr', 'am', 'denn', 'nun',
|
||||||
|
'unter', 'sehr', 'selbst', 'schon', 'hier', 'bis', 'habe', 'ihre',
|
||||||
|
'dann', 'ihnen', 'seiner', 'alle', 'wieder', 'meine', 'Zeit', 'gegen',
|
||||||
|
'vom', 'ganz', 'einzelnen', 'wo', 'muss', 'ohne', 'eines', 'können',
|
||||||
|
'sei', 'geschrieben', 'instanzen', 'deutsch','aktualisierung', 'registrierung'
|
||||||
|
);
|
||||||
|
|
||||||
|
// English word list
|
||||||
|
// from http://en.wikipedia.org/wiki/Most_common_words_in_English
|
||||||
|
$wordList['en'] = array ('the', 'be', 'to', 'of', 'and', 'a', /*'in',*/
|
||||||
|
'that', 'have', 'I', 'it', 'for', 'not', 'on', 'with', 'he',
|
||||||
|
'as', 'you', 'do', 'at', 'this', 'but', 'his', 'by', 'from', 'they',
|
||||||
|
'we', 'say', 'her', 'she', 'or', 'an', 'will', 'my', 'one', 'all',
|
||||||
|
'would', 'there', 'their', 'what', 'so', 'up', 'out', 'if', 'about'
|
||||||
|
);
|
||||||
|
|
||||||
|
// French word list
|
||||||
|
// from https://1000mostcommonwords.com/1000-most-common-french-words/
|
||||||
|
/*$wordList['fr'] = array ('comme', 'que', 'tait', 'pour', 'sur', 'sont', 'avec',
|
||||||
|
'tre', 'un', 'ce', 'par', 'mais', 'que', 'est',
|
||||||
|
'il', 'eu', 'la', 'et', 'dans');*/
|
||||||
|
|
||||||
|
// Spanish word list
|
||||||
|
// from https://spanishforyourjob.com/commonwords/
|
||||||
|
/*$wordList['es'] = array ('que', 'no', 'a', 'la', 'el', 'es', 'y',
|
||||||
|
'en', 'lo', 'un', 'por', 'qu', 'si', 'una',
|
||||||
|
'los', 'con', 'para', 'est', 'eso', 'las');*/
|
||||||
|
|
||||||
|
// clean out the input string - note we don't have any non-ASCII
|
||||||
|
// characters in the word lists... change this if it is not the
|
||||||
|
// case in your language wordlists!
|
||||||
|
$txt = strip_tags($text);
|
||||||
|
$txt = preg_replace("/[^A-Za-z:\\/\\.]+/", ' ', $txt);
|
||||||
|
if ($debug) {
|
||||||
|
echo "text: '$txt'\n";
|
||||||
|
}
|
||||||
|
$counter = [];
|
||||||
|
// count the occurrences of the most frequent words
|
||||||
|
foreach ($supported_languages as $language) {
|
||||||
|
$counter[$language] = 0;
|
||||||
|
}
|
||||||
|
foreach ($supported_languages as $language) {
|
||||||
|
for ($i = 0; $i < sizeof($wordList[$language]); ++$i) {
|
||||||
|
$count = substr_count($txt, ' ' .$wordList[$language][$i] . ' ');
|
||||||
|
if ($debug && $count > 0) {
|
||||||
|
echo $language . " " . $wordList[$language][$i] . " => $count\n";
|
||||||
|
}
|
||||||
|
$counter[$language] += $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($debug) {
|
||||||
|
print_r($counter);
|
||||||
|
}
|
||||||
|
// get max counter value
|
||||||
|
$max = max($counter);
|
||||||
|
$maxs = array_keys($counter, $max);
|
||||||
|
// if there are two winners - fall back to default!
|
||||||
|
if (count($maxs) == 1) {
|
||||||
|
$winner = $maxs[0];
|
||||||
|
$second = 0;
|
||||||
|
// get runner-up (second place)
|
||||||
|
foreach ($supported_languages as $language) {
|
||||||
|
if ($language !== $winner) {
|
||||||
|
if ($counter[$language]>$second) {
|
||||||
|
$second = $counter[$language];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// apply arbitrary threshold of 50%
|
||||||
|
if (($second / $max) < 0.5) {
|
||||||
|
return $winner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $default;
|
||||||
}
|
}
|
||||||
return $default;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* function called from smarty templates to print language translation
|
* function called from smarty templates to print language translation
|
||||||
*
|
*
|
||||||
* @param array<string,mixed> $params
|
* @param array<string, mixed> $params
|
||||||
* smarty params, used are 'group', 'txt' and optionally 'var'
|
* smarty params, used are 'group', 'txt' and optionally 'var'
|
||||||
* @param \Smarty\Template $template
|
* @param \Smarty\Template $template
|
||||||
* template instance
|
* template instance
|
||||||
* @return string translated text
|
* @return string translated text
|
||||||
*/
|
*/
|
||||||
function smarty_function_printlang($params, $template) : string {
|
function smarty_function_printlang($params, $template) : string
|
||||||
$lang = $template->getTemplateVars("language");
|
{
|
||||||
<<<'PHAN'
|
$lang = $template->getTemplateVars("language");
|
||||||
@phan-var \Language $lang
|
<<<'PHAN'
|
||||||
PHAN;
|
@phan-var \Language $lang
|
||||||
$forcelang = array_key_exists('lang', $params) ? $params['lang'] : null;
|
PHAN;
|
||||||
if ($forcelang !== null) {
|
$forcelang = array_key_exists('lang', $params) ? $params['lang'] : null;
|
||||||
$lang = new \Language($forcelang);
|
if ($forcelang !== null) {
|
||||||
}
|
$lang = new Language($forcelang);
|
||||||
if (isset($params['var'])) {
|
}
|
||||||
return $lang->printlang($params['group'], $params['key'], $params['var']);
|
if (isset($params['var'])) {
|
||||||
} else {
|
return $lang->printlang($params['group'], $params['key'], $params['var']);
|
||||||
return $lang->printlang($params['group'], $params['key']);
|
} else {
|
||||||
}
|
return $lang->printlang($params['group'], $params['key']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -269,28 +285,14 @@ function smarty_function_printlang($params, $template) : string {
|
||||||
* template instance
|
* template instance
|
||||||
* @return string translated text as JS line
|
* @return string translated text as JS line
|
||||||
*/
|
*/
|
||||||
function smarty_function_printjslang($params, $template) : string {
|
function smarty_function_printjslang($params, $template) : string
|
||||||
$lang = $template->getTemplateVars("language");
|
{
|
||||||
$prefix = 'window.translations.' . $params['group'] . '.' . $params['key'] . ' = \'';
|
$lang = $template->getTemplateVars("language");
|
||||||
$postfix = '\';';
|
$prefix = 'window.translations.' . $params['group'] . '.' . $params['key'] . ' = \'';
|
||||||
if (isset($params['var']))
|
$postfix = '\';';
|
||||||
return $prefix . $lang->printlang($params['group'], $params['key'], $params['var']) . $postfix;
|
if (isset($params['var'])) {
|
||||||
else
|
return $prefix . $lang->printlang($params['group'], $params['key'], $params['var']) . $postfix;
|
||||||
return $prefix . $lang->printlang($params['group'], $params['key']) . $postfix;
|
} else {
|
||||||
}
|
return $prefix . $lang->printlang($params['group'], $params['key']) . $postfix;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* print translation of given group and id, optionally using variables
|
|
||||||
*
|
|
||||||
* @param string $group
|
|
||||||
* group name
|
|
||||||
* @param string $key
|
|
||||||
* string name
|
|
||||||
* @param array<mixed> $values
|
|
||||||
* optional values to replace
|
|
||||||
* @return string translated string
|
|
||||||
*/
|
|
||||||
function printlang(string $group, string $key, array $values=array()) {
|
|
||||||
global $contentnation;
|
|
||||||
return $contentnation->translate(null, $group, $key, $values);
|
|
||||||
}
|
}
|
||||||
|
|
66
php/main.php
66
php/main.php
|
@ -9,30 +9,70 @@
|
||||||
namespace Federator;
|
namespace Federator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for ContentNation and Api
|
* Base class for Api and related classes
|
||||||
* @author Sascha Nitsch
|
* @author Sascha Nitsch
|
||||||
*/
|
*/
|
||||||
class Main
|
class Main
|
||||||
{
|
{
|
||||||
/** @var Cache\Cache cache instance */
|
/**
|
||||||
|
* cache instance
|
||||||
|
*
|
||||||
|
* @var Cache\Cache $cache
|
||||||
|
*/
|
||||||
protected $cache;
|
protected $cache;
|
||||||
/** @var array<string,mixed> current config */
|
/**
|
||||||
|
* current config
|
||||||
|
*
|
||||||
|
* @var array<string,mixed> $config
|
||||||
|
*/
|
||||||
protected $config;
|
protected $config;
|
||||||
/** @var Connector\Connector remote connector */
|
/**
|
||||||
|
* remote connector
|
||||||
|
*
|
||||||
|
* @var Connector\Connector $connector
|
||||||
|
*/
|
||||||
protected $connector = null;
|
protected $connector = null;
|
||||||
/** @var string response content type */
|
/**
|
||||||
|
* response content type
|
||||||
|
*
|
||||||
|
* @var string $contentType
|
||||||
|
*/
|
||||||
protected $contentType = "text/html";
|
protected $contentType = "text/html";
|
||||||
/** @var \Mysqli database instance */
|
/**
|
||||||
|
* database instance
|
||||||
|
*
|
||||||
|
* @var \Mysqli $dbh
|
||||||
|
*/
|
||||||
protected $dbh;
|
protected $dbh;
|
||||||
/** @var array<string,string> extra headers */
|
/**
|
||||||
|
* extra headers
|
||||||
|
*
|
||||||
|
* @var array<string,string> $headers
|
||||||
|
*/
|
||||||
protected $headers = [];
|
protected $headers = [];
|
||||||
/** @var \Language languange instance */
|
/**
|
||||||
|
* languange instance
|
||||||
|
*
|
||||||
|
* @var \Language $lang
|
||||||
|
*/
|
||||||
protected $lang = null;
|
protected $lang = null;
|
||||||
/** @var ?string redirect URL */
|
/**
|
||||||
|
* redirect URL
|
||||||
|
*
|
||||||
|
* @var ?string $redirect
|
||||||
|
*/
|
||||||
protected $redirect = null;
|
protected $redirect = null;
|
||||||
/** @var int response code */
|
/**
|
||||||
|
* response code
|
||||||
|
*
|
||||||
|
* @var int $responseCode
|
||||||
|
*/
|
||||||
protected $responseCode = 200;
|
protected $responseCode = 200;
|
||||||
/** @var \Smarty\Smarty|null smarty instance */
|
/**
|
||||||
|
* smarty instance
|
||||||
|
*
|
||||||
|
* @var \Smarty\Smarty|null $smarty
|
||||||
|
*/
|
||||||
protected $smarty;
|
protected $smarty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +192,7 @@ class Main
|
||||||
}
|
}
|
||||||
if ($this->lang !== null) {
|
if ($this->lang !== null) {
|
||||||
if ($this->lang->getLang() !== $lang) {
|
if ($this->lang->getLang() !== $lang) {
|
||||||
$l = new \Language($lang);
|
$l = new Language($lang);
|
||||||
return $l->printlang($group, $key, $parameters);
|
return $l->printlang($group, $key, $parameters);
|
||||||
}
|
}
|
||||||
return $this->lang->printlang($group, $key, $parameters);
|
return $this->lang->printlang($group, $key, $parameters);
|
||||||
|
@ -168,7 +208,7 @@ class Main
|
||||||
*/
|
*/
|
||||||
public function validLanguage(?string $lang) : bool
|
public function validLanguage(?string $lang) : bool
|
||||||
{
|
{
|
||||||
$language = new \Language($lang);
|
$language = new Language($lang);
|
||||||
if ($language->getLang() === $lang) {
|
if ($language->getLang() === $lang) {
|
||||||
$this->lang = $language;
|
$this->lang = $language;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<paths>
|
<paths>
|
||||||
<output>php-docs</output>
|
<output>php-docs</output>
|
||||||
</paths>
|
</paths>
|
||||||
<version number="develop">
|
<version number="latest">
|
||||||
<api format="php">
|
<api format="php">
|
||||||
<visibility>internal</visibility>
|
<visibility>internal</visibility>
|
||||||
<ignore>
|
<ignore>
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||||
**/
|
**/
|
||||||
|
|
||||||
namespace Federator;
|
namespace Federator\Connector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dummy connector that always return the same permission
|
* dummy connector that always return the same permission
|
||||||
*/
|
*/
|
||||||
class DummyConnector implements Connector\Connector
|
class DummyConnector implements Connector
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
|
@ -28,7 +28,7 @@ class DummyConnector implements Connector\Connector
|
||||||
public function getRemoteUserBySession(string $_session, string $_user)
|
public function getRemoteUserBySession(string $_session, string $_user)
|
||||||
{
|
{
|
||||||
// validate $_session and $user
|
// validate $_session and $user
|
||||||
$user = new Data\User();
|
$user = new \Federator\Data\User();
|
||||||
$user->id = $_user;
|
$user->id = $_user;
|
||||||
$user->permissions = ['PUBLISH'];
|
$user->permissions = ['PUBLISH'];
|
||||||
$user->session = $_session;
|
$user->session = $_session;
|
||||||
|
@ -36,8 +36,16 @@ class DummyConnector implements Connector\Connector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dummy_load(Main $main)
|
namespace Federator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to initialize plugin
|
||||||
|
*
|
||||||
|
* @param \Federator\Main $main main instance
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function dummy_load($main)
|
||||||
{
|
{
|
||||||
$dummy = new DummyConnector();
|
$dummy = new Connector\DummyConnector();
|
||||||
$main->setConnector($dummy);
|
$main->setConnector($dummy);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,30 +13,45 @@ namespace Federator\Cache;
|
||||||
*/
|
*/
|
||||||
class RedisCache implements Cache
|
class RedisCache implements Cache
|
||||||
{
|
{
|
||||||
/** @var \Redis connection handle */
|
/**
|
||||||
|
* connection handle
|
||||||
|
*
|
||||||
|
* @var \Redis $redis
|
||||||
|
*/
|
||||||
private $redis;
|
private $redis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get remote user by given session
|
* {@inheritDoc}
|
||||||
* @param string $_session session id
|
|
||||||
* @param string $_user user/profile name
|
|
||||||
* @return \Data\User | null
|
|
||||||
*/
|
*/
|
||||||
public function getRemoteUserBySession(string $_session, string $_user)
|
public function getRemoteUserBySession($_session, $_user)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveRemoteUserBySession(string $_session, string $_user, \Federator\Data\User $user)
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function saveRemoteUserBySession($_session, $_user, $user)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dummy_rediscache(\Federator\Main $main)
|
namespace Federator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to initialize plugin
|
||||||
|
*
|
||||||
|
* @param \Federator\Main $main main instance
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function rediscache_load($main)
|
||||||
{
|
{
|
||||||
$rc = new RedisCache();
|
$rc = new Cache\RedisCache();
|
||||||
$main->setCache($rc);
|
$main->setCache($rc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
git log | head -n1 | awk '{print "<?php\nglobal $version;\n$version=\"" $2 "\";\n"}' > php/version.php
|
git log | head -n1 | awk '{print "<?php\nglobal $version;\n$version=\"" $2 "\";\n"}' > php/version.php
|
||||||
|
vendor/phan/phan/phan
|
||||||
|
./phpdoc
|
||||||
|
|
Loading…
Reference in New Issue