Compare commits
43
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74aeb90758 | ||
|
|
7c4c9e64d6 | ||
|
|
6695369af7 | ||
|
|
fdafc13e2c | ||
|
|
bd0392698d | ||
|
|
dc58045423 | ||
|
|
a9f3292f8f | ||
|
|
ac723e9fda | ||
|
|
5408f197fd | ||
|
|
c0a9156f0e | ||
|
|
fd0a5a5d4c | ||
|
|
1daf876976 | ||
|
|
7a29151bdd | ||
|
|
623b041a5f | ||
|
|
6242024451 | ||
|
|
0262c31e93 | ||
|
|
5557c54fd6 | ||
|
|
7df897d9d7 | ||
|
|
1a94af6b0b | ||
|
|
fa4125d63b | ||
|
|
ac0048c788 | ||
|
|
f430b7f5ac | ||
|
|
83e739d378 | ||
|
|
a32c201a91 | ||
|
|
cb2b75a3ca | ||
|
|
1f27f9a5f5 | ||
|
|
81e2cdb222 | ||
|
|
5b49171a74 | ||
|
|
869c888947 | ||
|
|
322ca715eb | ||
|
|
ab4e9f001e | ||
|
|
51b70aed0d | ||
|
|
08579804a8 | ||
|
|
64241842f6 | ||
|
|
f5c61ca6eb | ||
|
|
aa32bd1276 | ||
|
|
e6960f0030 | ||
|
|
b02da95c2f | ||
|
|
9994f8c18d | ||
|
|
ce5f359a75 | ||
|
|
57e398e7d4 | ||
|
|
ca5e5c52a1 | ||
|
|
6f5272717f |
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Components\Http\Request;
|
||||
use Xentral\Components\Http\Session\Session;
|
||||
use Xentral\Core\DependencyInjection\ServiceContainer;
|
||||
|
||||
/**
|
||||
* Factory for localization object.
|
||||
*
|
||||
* @see Localization
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
final class Bootstrap
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function registerServices(): array
|
||||
{
|
||||
return [
|
||||
'Localization' => 'onInitLocalization',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Replaces umlauts with their 2 character representation.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return array|string|string[]
|
||||
*/
|
||||
public static function replaceUmlauts(string $string)
|
||||
{
|
||||
$search = ['ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß'];
|
||||
$replace = ['ae', 'oe', 'ue', 'Ae', 'Oe', 'Ue', 'ss'];
|
||||
return str_replace($search, $replace, $string);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find the language information from the given string.
|
||||
*
|
||||
* @param string $lang
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function findLanguage(string $lang): ?array
|
||||
{
|
||||
$subject = strtolower($lang);
|
||||
foreach ((new Iso639()) as $key => $val) {
|
||||
if (array_filter($val, function ($str) use ($subject) {
|
||||
return $str && ((strtolower($str) == $subject) || (self::replaceUmlauts(strtolower($str)) == $subject));
|
||||
})) {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find the region information from the given string.
|
||||
*
|
||||
* @param string $region
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function findRegion(string $region): ?array
|
||||
{
|
||||
$subject = strtolower($region);
|
||||
foreach ((new Iso3166()) as $key => $val) {
|
||||
if (array_filter($val, function ($str) use ($subject) {
|
||||
return $str && ((strtolower($str) == $subject) || (self::replaceUmlauts(strtolower($str)) == $subject));
|
||||
})) {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This is the factory for the Localization object.
|
||||
*
|
||||
* @param ServiceContainer $container
|
||||
*
|
||||
* @return Localization
|
||||
*/
|
||||
public static function onInitLocalization(ServiceContainer $container): Localization
|
||||
{
|
||||
/** @var Request $request */
|
||||
$request = $container->get('Request');
|
||||
/** @var Session $session */
|
||||
$session = $container->get('Session');
|
||||
/** @var \erpooSystem $app */
|
||||
$app = $container->get('LegacyApplication');
|
||||
/** @var Database $db */
|
||||
$db = $container->get('Database');
|
||||
|
||||
$config=[];
|
||||
$firmaLang=null;
|
||||
$firmaRegion=null;
|
||||
// Get language from system settings and normalize to 3-letter-code and 2-letter-code
|
||||
if ($firmaLang = self::findLanguage($app->erp->Firmendaten('preferredLanguage'))) {
|
||||
$config[Localization::LANGUAGE_DEFAULT] = $firmaLang[Iso639\Key::ALPHA_3];
|
||||
}
|
||||
|
||||
// Get region from system settings and normalize to 2-letter-code
|
||||
if ($firmaLang && ($firmaRegion = self::findRegion($app->erp->Firmendaten('land')))) {
|
||||
$config[Localization::LOCALE_DEFAULT] = "{$firmaLang[Iso639\Key::ALPHA_2]}_{$firmaRegion[Iso3166\Key::ALPHA_2]}";
|
||||
}
|
||||
|
||||
|
||||
// Get User
|
||||
$usersettings = [];
|
||||
if ($user = $app->User) {
|
||||
// Get User's address from user
|
||||
$userAddress = $db->fetchRow(
|
||||
$db->select()->cols(['*'])->from('adresse')->where('id=:id'),
|
||||
['id' => $user->GetAdresse()]
|
||||
);
|
||||
|
||||
// Get language from user account and normalize to 3-letter-code and 2-letter-code
|
||||
if ($userLang = self::findLanguage($user->GetSprache())) {
|
||||
$usersettings['language'] = $userLang[Iso639\Key::ALPHA_3];
|
||||
}
|
||||
|
||||
// Get region from user account and normalize to 2-letter-code
|
||||
if ($userLang && ($userRegion = self::findRegion($userAddress['land']))) {
|
||||
$usersettings['locale'] = "{$userLang[Iso639\Key::ALPHA_2]}_{$userRegion[Iso3166\Key::ALPHA_2]}";
|
||||
}
|
||||
}
|
||||
|
||||
// Create Localization object
|
||||
return new Localization($request, $session, $usersettings, $config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
/**
|
||||
* Provides array access functions to the data provider.
|
||||
*
|
||||
* @see \ArrayAccess
|
||||
* @see DataProvider
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
trait ArrayAccessTrait
|
||||
{
|
||||
/**
|
||||
* Whether an offset exists.
|
||||
*
|
||||
* @param string $offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return array_key_exists($offset, $this->DataProvider_DATA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Offset to retrieve.
|
||||
*
|
||||
* @param string $offset
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function offsetGet($offset): array
|
||||
{
|
||||
return $this->DataProvider_DATA[$offset];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assign a value to the specified offset.
|
||||
* No function since data set is read only.
|
||||
*
|
||||
* @param string $offset
|
||||
* @param array $value
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
// $this->DataProvider_DATA[$offset]=$value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Unset an offset.
|
||||
* No function since data set is read only.
|
||||
*
|
||||
* @param string $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
// unset($this->DataProvider_DATA[$offset]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
/**
|
||||
* Provides countable functions to the data provider.
|
||||
*
|
||||
* @see \Countable
|
||||
* @see DataProvider
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
trait CountableTrait
|
||||
{
|
||||
/**
|
||||
* Counts the number of records in the private $data array.
|
||||
*
|
||||
* @return int Number of records
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->DataProvider_DATA);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract filter class.
|
||||
*
|
||||
* @see DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Pointer to next filter in chain.
|
||||
*
|
||||
* @var DataFilterInterface
|
||||
*/
|
||||
private $nextFilter = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::then()
|
||||
*/
|
||||
public function then(DataFilterInterface $filter): DataFilterInterface
|
||||
{
|
||||
if (!$this->nextFilter) {
|
||||
$this->nextFilter = $filter;
|
||||
} else {
|
||||
$this->nextFilter->then($filter);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Applies the filter to the data and executes the next filter
|
||||
* if present.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::__invoke()
|
||||
*/
|
||||
public function __invoke(array $data): array
|
||||
{
|
||||
// echo get_called_class()."::__invoke(\$data)".PHP_EOL;
|
||||
|
||||
$filteredData = [];
|
||||
foreach ($data as $key => $val) {
|
||||
if ($this->selectItem($key, $val)) {
|
||||
$filteredData[$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->nextFilter) {
|
||||
$filteredData = ($this->nextFilter)($filteredData);
|
||||
}
|
||||
return $filteredData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if the current item is to be selected for
|
||||
* the dataset.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function selectItem(&$key, &$val): bool;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
|
||||
/**
|
||||
* Filter Interface.
|
||||
*
|
||||
* @see DataFilter
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
interface DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Add a filter to the end of the filter chain.
|
||||
*
|
||||
* @param DataFilterInterface $filter Filter to add
|
||||
*
|
||||
* @return DataFilterInterface Start of filter chain
|
||||
*/
|
||||
function then(DataFilterInterface $filter): DataFilterInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Applies the filter to the data and executes the next filter
|
||||
* if present.
|
||||
*
|
||||
* @see \Ruga\I18n\Dataaccess\DataFilterInterface::__invoke()
|
||||
*/
|
||||
function __invoke(array $data): array;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a general data provider.
|
||||
*
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class DataProvider implements Countable, Iterator, ArrayAccess, DataProviderInterface
|
||||
{
|
||||
use CountableTrait;
|
||||
use IteratorTrait;
|
||||
use ArrayAccessTrait;
|
||||
|
||||
|
||||
/**
|
||||
* Holds filtered data.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $DataProvider_DATA = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the object and apply data filter.
|
||||
*
|
||||
* @param DataFilterInterface|null $filter
|
||||
*/
|
||||
public function __construct(DataFilterInterface $filter = null)
|
||||
{
|
||||
if ($filter) {
|
||||
$this->DataProvider_DATA = $filter($this->getOriginalData());
|
||||
} else {
|
||||
$this->DataProvider_DATA = $this->getOriginalData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the original data array).
|
||||
* Raw data before any filtering takes place.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getOriginalData(): array;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array suitable for select fields.
|
||||
* The key of the filtered data set is used as key of the
|
||||
* array and $desiredName field is used as value.
|
||||
*
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return array;
|
||||
*/
|
||||
public function getMultiOptions($desiredName = 'NAME_deu'): array
|
||||
{
|
||||
$a = [];
|
||||
foreach ($this as $key => $l) {
|
||||
$a[$key] = $l[$desiredName];
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the field $desiredName from the record $id.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($id, $desiredName): string
|
||||
{
|
||||
if (!isset($this[$id])) {
|
||||
throw new Exception\OutOfRangeException("Index '{$id}' not found");
|
||||
}
|
||||
$d = $this[$id];
|
||||
if ($desiredName) {
|
||||
if ($desiredName == 'POST') {
|
||||
return strtoupper($this->getString($id, 'NAME_eng'));
|
||||
}
|
||||
return $d[$desiredName];
|
||||
}
|
||||
throw new Exception\OutOfRangeException("No '{$desiredName}' data for '{$id}'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the item at position $id.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData($id)
|
||||
{
|
||||
if (empty($id)) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this[$id])) {
|
||||
throw new Exception\OutOfRangeException("Index '{$id}' not found.");
|
||||
}
|
||||
return $this[$id];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
|
||||
/**
|
||||
* Interface to the general data provider class.
|
||||
*
|
||||
* @see DataProvider
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
interface DataProviderInterface
|
||||
{
|
||||
/**
|
||||
* Returns an array suitable for select fields.
|
||||
* The key of the filtered data set is used as key of the
|
||||
* array and $desiredName field is used as value.
|
||||
*
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return array;
|
||||
*/
|
||||
public function getMultiOptions($desiredName): array;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the field $desiredName from the record $id.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $desiredName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($id, $desiredName): string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the item at position $id.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData($id);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess\Exception;
|
||||
|
||||
class OutOfRangeException extends \OutOfRangeException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Dataaccess;
|
||||
|
||||
/**
|
||||
* Provides iterator functions to the data provider.
|
||||
*
|
||||
* @see \Iterator
|
||||
* @see DataProvider
|
||||
* @see DataProviderInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
trait IteratorTrait
|
||||
{
|
||||
/**
|
||||
* Index of the current element's key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $IteratorTrait_index = null;
|
||||
|
||||
/**
|
||||
* Array of keys of the data set.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $IteratorTrait_keys = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the current element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->valid() ? $this->DataProvider_DATA[$this->key()] : null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the key of the current element.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return static::valid() ? $this->IteratorTrait_keys[$this->IteratorTrait_index] : null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Move forward to next element.
|
||||
*
|
||||
* @return bool false if invalid
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->IteratorTrait_index++;
|
||||
if (!$this->valid()) {
|
||||
$this->IteratorTrait_index = null;
|
||||
}
|
||||
return $this->valid();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Rewind the Iterator to the first element.
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->IteratorTrait_keys = array_keys($this->DataProvider_DATA);
|
||||
sort($this->IteratorTrait_keys);
|
||||
$this->IteratorTrait_index = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks if current position is valid.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
return ($this->IteratorTrait_index !== null)
|
||||
&& array_key_exists($this->IteratorTrait_index, $this->IteratorTrait_keys)
|
||||
&& array_key_exists($this->IteratorTrait_keys[$this->IteratorTrait_index], $this->DataProvider_DATA);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Exception;
|
||||
|
||||
class LanguageNotInitializedException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Exception;
|
||||
|
||||
class UnsupportedLocaleStringException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataProvider;
|
||||
|
||||
/**
|
||||
* Country Codes - ISO 3166.
|
||||
* Loads the data and holds the filtered (if desired) list.
|
||||
*
|
||||
* @see https://www.iso.org/iso-3166-country-codes.html
|
||||
* @see DataProvider
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* @license AGPL-3.0-only
|
||||
*/
|
||||
class Iso3166 extends DataProvider
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataProvider::getOriginalData()
|
||||
*/
|
||||
protected function getOriginalData(): array
|
||||
{
|
||||
return include(__DIR__ . '/data/Iso3166data.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
/**
|
||||
* This filter returns all records from the data set (aka dummy filter).
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class All extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
function selectItem(&$key, &$val): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Iso3166\Key;
|
||||
|
||||
|
||||
/**
|
||||
* Applies a filter to only select central european countries.
|
||||
*
|
||||
* @see Custom
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class CentralEurope extends Custom implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Countries in Europe.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const CentralEurope_Countries = ['CHE', 'DEU', 'AUT', 'ITA', 'FRA', 'ESP', 'PRT', 'GBR'];
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set predefined values.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(static::CentralEurope_Countries, Key::ALPHA_3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
|
||||
|
||||
/**
|
||||
* This filter can be used to change the main key
|
||||
* of the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class ChangeKey extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* New key to use for the data set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ChangeKey_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize filter and set the new key.
|
||||
*
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->ChangeKey_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$key = $val[$this->ChangeKey_key];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Apply a custom filter to the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Custom extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Array of wanted values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $Custom_values = null;
|
||||
|
||||
/**
|
||||
* Key to check for the values in $this->Custom_values.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Custom_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set values for filter.
|
||||
*
|
||||
* @param array $values
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct(array $values, $key)
|
||||
{
|
||||
$this->Custom_values = $values;
|
||||
$this->Custom_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$needle = $val[$this->Custom_key];
|
||||
return in_array($needle, $this->Custom_values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Iso3166\Key;
|
||||
|
||||
|
||||
/**
|
||||
* Applies a filter to only select european countries.
|
||||
*
|
||||
* @see Custom
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Europe extends Custom implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Set predefined values.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(['150'], Key::REGION_CODE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166;
|
||||
|
||||
|
||||
/**
|
||||
* Keys for the iso3166 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso3166
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Key/* extends Ruga_Enum*/
|
||||
{
|
||||
/** Key: Alpha-2 code */
|
||||
const ALPHA_2 = 'A2';
|
||||
|
||||
/** Key: Alpha-3 code */
|
||||
const ALPHA_3 = 'A3';
|
||||
|
||||
/** Key: Numeric code */
|
||||
const NUMERIC = 'NUM';
|
||||
|
||||
/** Key: Top Level Domain */
|
||||
const TLD = 'TLD';
|
||||
|
||||
/** Key: Currency Code */
|
||||
const CURRENCY_CODE = 'CURRENCY_CODE';
|
||||
const TELEPHONE_CODE = 'TEL_CODE';
|
||||
const REGION = 'REGION';
|
||||
const REGION_CODE = 'REGION_CODE';
|
||||
const SUBREGION = 'SUBREGION';
|
||||
const SUBREGION_CODE = 'SUBREGION_CODE';
|
||||
const INTERMEDIATEREGION = 'INTERMEDIATEREGION';
|
||||
const INTERMEDIATEREGION_CODE = 'INTERMEDIATEREGION_CODE';
|
||||
const NAME_eng = 'NAME_eng';
|
||||
const NAME_fra = 'NAME_fra';
|
||||
const NAME_deu = 'NAME_deu';
|
||||
|
||||
|
||||
/** Key: Postal country name */
|
||||
const POST = 'POST';
|
||||
|
||||
|
||||
const DEFAULT = self::ALPHA_3;
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ALPHA_2 => 'ISO 3166 Alpha-2',
|
||||
self::ALPHA_3 => 'ISO 3166 Alpha-3',
|
||||
self::NUMERIC => 'ISO 3166 Numerisch',
|
||||
self::TLD => 'Top Level Domain',
|
||||
self::CURRENCY_CODE => 'Währung',
|
||||
self::TELEPHONE_CODE => 'Landesvorwahl',
|
||||
self::REGION => 'Region',
|
||||
self::REGION_CODE => 'Region Code',
|
||||
self::SUBREGION => 'Unter-Region',
|
||||
self::SUBREGION_CODE => 'Unter-Region Code',
|
||||
self::INTERMEDIATEREGION => 'Intermediate-Region',
|
||||
self::INTERMEDIATEREGION_CODE => 'Intermediate-Region Code',
|
||||
self::NAME_eng => 'Englische Bezeichnung',
|
||||
self::NAME_fra => 'Französische Bezeichnung',
|
||||
self::NAME_deu => 'Deutsche Bezeichnung',
|
||||
|
||||
self::POST => 'Landesbezeichung Postadresse',
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso3166;
|
||||
|
||||
/**
|
||||
* Names for the iso3166 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso3166
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Name/* extends Ruga_Enum */
|
||||
{
|
||||
/** Englisch */
|
||||
const ENG = 'NAME_eng';
|
||||
/** Französisch */
|
||||
const FRA = 'NAME_fra';
|
||||
/** Deutsch */
|
||||
const DEU = 'NAME_deu';
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ENG => 'Englische Bezeichnung',
|
||||
self::FRA => 'Französische Bezeichnung',
|
||||
self::DEU => 'Deutsche Bezeichnung',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataProvider;
|
||||
use Xentral\Components\I18n\Dataaccess\Exception\OutOfRangeException;
|
||||
|
||||
/**
|
||||
* Codes for the Representation of Names of Languages - ISO 639.
|
||||
* Loads the data and holds the filtered (if desired) list.
|
||||
*
|
||||
* @see https://www.iso.org/iso-639-language-codes.html
|
||||
* @see DataProvider
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Iso639 extends DataProvider
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataProvider::getOriginalData()
|
||||
*/
|
||||
protected function getOriginalData(): array
|
||||
{
|
||||
return include(__DIR__ . '/data/Iso639data.php');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the field $desiredName from the record $id.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param string $desiredName
|
||||
* @param null $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function find($id, $desiredName, $default = null): string
|
||||
{
|
||||
$id = strtolower($id);
|
||||
try {
|
||||
return $this->getString($id, $desiredName);
|
||||
} catch (OutOfRangeException $e) {
|
||||
try {
|
||||
return (new \Xentral\Components\I18n\Iso639(
|
||||
(new \Xentral\Components\I18n\Iso639\Filter\All())
|
||||
->then(new \Xentral\Components\I18n\Iso639\Filter\ChangeKey(\Xentral\Components\I18n\Iso639\Key::ALPHA_2))
|
||||
))->getString($id, $desiredName);
|
||||
} catch (OutOfRangeException $e) {
|
||||
try {
|
||||
$id = strtoupper($id);
|
||||
return (new \Xentral\Components\I18n\Iso639(
|
||||
(new \Xentral\Components\I18n\Iso639\Filter\All())
|
||||
->then(new \Xentral\Components\I18n\Iso639\Filter\ChangeKey(\Xentral\Components\I18n\Iso639\Key::ONELETTER))
|
||||
))->getString($id, $desiredName);
|
||||
} catch (OutOfRangeException $e) {
|
||||
if ($default === null) {
|
||||
throw $e;
|
||||
} else {
|
||||
return $this->getString($default, $desiredName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
|
||||
/**
|
||||
* This filter returns all records from the data set (aka dummy filter).
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class All extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
function selectItem(&$key, &$val): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Iso639\Key;
|
||||
|
||||
|
||||
/**
|
||||
* Applies a filter to only select central european countries.
|
||||
*
|
||||
* @see Custom
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class CentralEurope extends Custom implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Countries in Europe.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const CentralEurope_Languages = ['deu', 'fra', 'ita', 'roh', 'spa', 'por', 'eng'];
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set predefined values.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(static::CentralEurope_Languages, Key::ALPHA_3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
|
||||
|
||||
/**
|
||||
* This filter can be used to change the main key
|
||||
* of the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class ChangeKey extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* New key to use for the data set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ChangeKey_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize filter and set the new key.
|
||||
*
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->ChangeKey_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$key = $val[$this->ChangeKey_key] ?? null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639\Filter;
|
||||
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilter;
|
||||
use Xentral\Components\I18n\Dataaccess\DataFilterInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Apply a custom filter to the data set.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilter
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
class Custom extends DataFilter implements DataFilterInterface
|
||||
{
|
||||
/**
|
||||
* Array of wanted values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $Custom_values = null;
|
||||
|
||||
/**
|
||||
* Key to check for the values in $this->Custom_values.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Custom_key = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set values for filter.
|
||||
*
|
||||
* @param array $values
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __construct(array $values, $key)
|
||||
{
|
||||
$this->Custom_values = $values;
|
||||
$this->Custom_key = $key;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see \Xentral\Components\I18n\Dataaccess\DataFilterInterface::selectItem()
|
||||
*/
|
||||
protected function selectItem(&$key, &$val): bool
|
||||
{
|
||||
$needle = $val[$this->Custom_key];
|
||||
return in_array($needle, $this->Custom_values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639;
|
||||
|
||||
|
||||
/**
|
||||
* Keys for the iso639 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso639
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Key/* extends Ruga_Enum*/
|
||||
{
|
||||
/** Key: Alpha-2 code */
|
||||
const ALPHA_2 = '639-1';
|
||||
const ISO639_1 = '639-1';
|
||||
|
||||
/** Key: Alpha-3 code */
|
||||
const ALPHA_3 = '639-2';
|
||||
const ISO639_2 = '639-2';
|
||||
|
||||
/** Key: Top Level Domain */
|
||||
const ONELETTER = '1L';
|
||||
|
||||
/** Key: Name */
|
||||
const NAME_eng = 'NAME_eng';
|
||||
const NAME_fra = 'NAME_fra';
|
||||
const NAME_deu = 'NAME_deu';
|
||||
|
||||
|
||||
const DEFAULT = self::ALPHA_3;
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ALPHA_2 => 'ISO 639 Alpha-2',
|
||||
self::ALPHA_3 => 'ISO 639 Alpha-3',
|
||||
self::ONELETTER => 'ISO 639 Alpha-1',
|
||||
self::NAME_eng => 'Englische Bezeichnung',
|
||||
self::NAME_fra => 'Französische Bezeichnung',
|
||||
self::NAME_deu => 'Deutsche Bezeichnung',
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n\Iso639;
|
||||
|
||||
|
||||
/**
|
||||
* Names for the iso639 list.
|
||||
*
|
||||
* @see \Xentral\Components\I18n\Iso639
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
abstract class Name/* extends Ruga_Enum */
|
||||
{
|
||||
/** Englisch */
|
||||
const ENG = 'NAME_eng';
|
||||
/** Französisch */
|
||||
const FRA = 'NAME_fra';
|
||||
/** Deutsch */
|
||||
const DEU = 'NAME_deu';
|
||||
|
||||
|
||||
protected static $fullnameMap = [
|
||||
self::ENG => 'Englische Bezeichnung',
|
||||
self::FRA => 'Französische Bezeichnung',
|
||||
self::DEU => 'Deutsche Bezeichnung',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
use Locale;
|
||||
use Xentral\Components\Http\Request;
|
||||
use Xentral\Components\Http\Session\Session;
|
||||
use Xentral\Components\I18n\Exception\LanguageNotInitializedException;
|
||||
use Xentral\Components\I18n\Exception\UnsupportedLocaleStringException;
|
||||
|
||||
/**
|
||||
* Provides a central service for localization.
|
||||
*
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
final class Localization implements LocalizationInterface
|
||||
{
|
||||
private array $config;
|
||||
|
||||
private ?Request $request;
|
||||
|
||||
private ?Session $session;
|
||||
|
||||
private array $usersettings = [];
|
||||
|
||||
private array $language = [];
|
||||
|
||||
private array $locale = [];
|
||||
|
||||
|
||||
|
||||
public function __construct(?Request $request, ?Session $session, array $usersettings = [], array $config = [])
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->session = $session;
|
||||
$this->usersettings = $usersettings;
|
||||
$this->config = $config;
|
||||
$this->process();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function process()
|
||||
{
|
||||
// Hardcoded defaults if config is not available
|
||||
$localeDefault = $this->config[Localization::LOCALE_DEFAULT] ?? 'de_DE';
|
||||
$localeAttrName = $this->config[Localization::LOCALE_ATTRIBUTE_NAME] ?? 'locale';
|
||||
$langDefault = $this->config[Localization::LANGUAGE_DEFAULT] ?? 'deu';
|
||||
$langAttrName = $this->config[Localization::LANGUAGE_ATTRIBUTE_NAME] ?? 'language';
|
||||
|
||||
$segmentName = 'i18n';
|
||||
|
||||
// Get the locale from the session, if available
|
||||
if ($this->session && ($locale = $this->session->getValue($segmentName, $localeAttrName))) {
|
||||
} else {
|
||||
// Get locale from request, fallback to the user's browser preference
|
||||
if ($this->request) {
|
||||
$locale = $this->request->attributes->get(
|
||||
$localeAttrName,
|
||||
Locale::acceptFromHttp(
|
||||
$this->request->getHeader('Accept-Language', $localeDefault)
|
||||
) ?? $localeDefault
|
||||
);
|
||||
} else {
|
||||
$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? $localeDefault);
|
||||
}
|
||||
}
|
||||
// Get locale from user
|
||||
// This overrides all previous attempts to find a locale
|
||||
if (array_key_exists('locale', $this->usersettings)) {
|
||||
$locale = $this->usersettings['locale'];
|
||||
}
|
||||
// Get locale from query string
|
||||
// This overrides all previous attempts to find a locale
|
||||
if ($this->request) {
|
||||
$locale = $this->request->getParam($localeAttrName, $locale ?? $localeDefault);
|
||||
} else {
|
||||
$locale = $_GET[$localeAttrName] ?? $locale ?? $localeDefault;
|
||||
}
|
||||
|
||||
|
||||
// Get the language from the session, if available
|
||||
if ($this->session && ($language = $this->session->getValue($segmentName, $langAttrName))) {
|
||||
} else {
|
||||
// Get language from request, fallback to the current locale
|
||||
if ($this->request) {
|
||||
$language = $this->request->attributes->get($langAttrName, Locale::getPrimaryLanguage($locale));
|
||||
} else {
|
||||
$language = Locale::getPrimaryLanguage($locale);
|
||||
}
|
||||
}
|
||||
// Get language from user
|
||||
// This overrides all previous attempts to find a language
|
||||
if (array_key_exists('language', $this->usersettings)) {
|
||||
$language = $this->usersettings['language'];
|
||||
}
|
||||
// Get language from query string
|
||||
// This overrides all previous attempts to find a language
|
||||
if ($this->request) {
|
||||
$language = $this->request->getParam($langAttrName, $language ?? $langDefault);
|
||||
} else {
|
||||
$language = $language ?? $langDefault;
|
||||
}
|
||||
|
||||
// Check language against the data from Iso639 (and normalize to 3-letter-code)
|
||||
$language = (new Iso639())->find($language, Iso639\Key::DEFAULT, $langDefault);
|
||||
|
||||
|
||||
// Store the locale and language to the LocalizationInterface
|
||||
$this->setLanguage($language);
|
||||
$this->setLocale($locale);
|
||||
|
||||
// Store the locale and language to the session
|
||||
if ($this->session) {
|
||||
$this->session->setValue($segmentName, $localeAttrName, $locale);
|
||||
$this->session->setValue($segmentName, $langAttrName, $language);
|
||||
}
|
||||
|
||||
// Store the locale and language as a request attribute
|
||||
if ($this->request) {
|
||||
$this->request->attributes->set($localeAttrName, $locale);
|
||||
$this->request->attributes->set($langAttrName, $language);
|
||||
}
|
||||
|
||||
// Set the default locale
|
||||
Locale::setDefault($locale);
|
||||
// error_log(self::class . ": {$locale}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the language.
|
||||
*
|
||||
* @param string $language
|
||||
*/
|
||||
public function setLanguage(string $language)
|
||||
{
|
||||
$this->language[Iso639\Key::DEFAULT] = (new \Xentral\Components\I18n\Iso639())->find(
|
||||
$language,
|
||||
Iso639\Key::DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the language string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso639\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage(string $key = null): string
|
||||
{
|
||||
if (!$key) {
|
||||
$key = Iso639\Key::DEFAULT;
|
||||
}
|
||||
if (!($this->language[$key] ?? null)) {
|
||||
if (!($this->language[Iso639\Key::DEFAULT] ?? null)) {
|
||||
throw new LanguageNotInitializedException("Language is not set for key '" . Iso639\Key::DEFAULT . "'");
|
||||
}
|
||||
$this->language[$key] = (new \Xentral\Components\I18n\Iso639())->find(
|
||||
$this->language[Iso639\Key::DEFAULT],
|
||||
$key
|
||||
);
|
||||
}
|
||||
return $this->language[$key];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
public function setLocale(string $locale)
|
||||
{
|
||||
$parsedLocale = Locale::parseLocale($locale);
|
||||
$locale = Locale::composeLocale([
|
||||
'language' => $parsedLocale['language'],
|
||||
'region' => $parsedLocale['region'],
|
||||
]);
|
||||
|
||||
if(!$locale) throw new UnsupportedLocaleStringException("The given locale string '{$locale}' is not supported");
|
||||
|
||||
$this->locale[Iso3166\Key::DEFAULT] = $locale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the locale string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso3166\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale(string $key = null): string
|
||||
{
|
||||
return $this->locale[Iso3166\Key::DEFAULT];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a new localization object using the given adresse array as source for language and region.
|
||||
*
|
||||
* @param array $adresse
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withAdresse(array $adresse): self
|
||||
{
|
||||
$localization = clone $this;
|
||||
|
||||
// Find language from address array or keep current language
|
||||
if (!$lang = Bootstrap::findLanguage($adresse['sprache'])) {
|
||||
$lang = Bootstrap::findLanguage($this->getLanguage());
|
||||
}
|
||||
if ($lang) {
|
||||
$localization->setLanguage($lang[Iso639\Key::ALPHA_3]);
|
||||
}
|
||||
|
||||
// Find region from address or keep current region
|
||||
if (!$region = Bootstrap::findRegion($adresse['land'])) {
|
||||
$parsedLocale = Locale::parseLocale($this->getLocale());
|
||||
$region = Bootstrap::findRegion($parsedLocale['region']);
|
||||
}
|
||||
if ($lang && $region) {
|
||||
$localization->setLocale("{$lang[Iso639\Key::ALPHA_2]}_{$region[Iso3166\Key::ALPHA_2]}");
|
||||
}
|
||||
|
||||
return $localization;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Components\I18n;
|
||||
|
||||
/**
|
||||
* Interface LocalizationInterface
|
||||
*
|
||||
* @author Roland Rusch, easy-smart solution GmbH <roland.rusch@easy-smart.ch>
|
||||
*/
|
||||
interface LocalizationInterface
|
||||
{
|
||||
const LOCALE_DEFAULT = 'locale_default';
|
||||
const LOCALE_ATTRIBUTE_NAME = 'locale_attr_name';
|
||||
const LANGUAGE_DEFAULT = 'language_default';
|
||||
const LANGUAGE_ATTRIBUTE_NAME = 'language_attr_name';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the language.
|
||||
*
|
||||
* @param string $language
|
||||
*/
|
||||
public function setLanguage(string $language);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the language string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso639\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage(string $key = null): string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
public function setLocale(string $locale);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the locale string as defined by $key.
|
||||
*
|
||||
* @param string|null $key A constant from Iso3166\Key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale(string $key = null): string;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/*
|
||||
* Data extracted from https://www.iso.org/iso-639-language-codes.html
|
||||
*/
|
||||
return [
|
||||
|
||||
'aar' => [
|
||||
'639-2' => 'aar',
|
||||
'639-1' => 'aa',
|
||||
'NAME_eng' => 'Afar',
|
||||
'NAME_fra' => 'afar',
|
||||
'NAME_deu' => 'Danakil-Sprache',
|
||||
],
|
||||
'abk' => [
|
||||
'639-2' => 'abk',
|
||||
'639-1' => 'ab',
|
||||
'NAME_eng' => 'Abkhazian',
|
||||
'NAME_fra' => 'abkhaze',
|
||||
'NAME_deu' => 'Abchasisch',
|
||||
],
|
||||
'ace' => [
|
||||
'639-2' => 'ace',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Achinese',
|
||||
'NAME_fra' => 'aceh',
|
||||
'NAME_deu' => 'Aceh-Sprache',
|
||||
],
|
||||
'ach' => [
|
||||
'639-2' => 'ach',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Acoli',
|
||||
'NAME_fra' => 'acoli',
|
||||
'NAME_deu' => 'Acholi-Sprache',
|
||||
],
|
||||
'ada' => [
|
||||
'639-2' => 'ada',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Adangme',
|
||||
'NAME_fra' => 'adangme',
|
||||
'NAME_deu' => 'Adangme-Sprache',
|
||||
],
|
||||
'ady' => [
|
||||
'639-2' => 'ady',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Adyghe',
|
||||
'NAME_fra' => 'adyghé',
|
||||
'NAME_deu' => 'Adygisch',
|
||||
],
|
||||
'afa' => [
|
||||
'639-2' => 'afa',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Afro-Asiatic languages',
|
||||
'NAME_fra' => 'afro-asiatiques, langues',
|
||||
'NAME_deu' => 'Hamitosemitische Sprachen (Andere)',
|
||||
],
|
||||
'afh' => [
|
||||
'639-2' => 'afh',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Afrihili',
|
||||
'NAME_fra' => 'afrihili',
|
||||
'NAME_deu' => 'Afrihili',
|
||||
],
|
||||
'afr' => [
|
||||
'639-2' => 'afr',
|
||||
'639-1' => 'af',
|
||||
'NAME_eng' => 'Afrikaans',
|
||||
'NAME_fra' => 'afrikaans',
|
||||
'NAME_deu' => 'Afrikaans',
|
||||
],
|
||||
'ain' => [
|
||||
'639-2' => 'ain',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Ainu',
|
||||
'NAME_fra' => 'aïnou',
|
||||
'NAME_deu' => 'Ainu-Sprache',
|
||||
],
|
||||
'aka' => [
|
||||
'639-2' => 'aka',
|
||||
'639-1' => 'ak',
|
||||
'NAME_eng' => 'Akan',
|
||||
'NAME_fra' => 'akan',
|
||||
'NAME_deu' => 'Akan-Sprache',
|
||||
],
|
||||
'akk' => [
|
||||
'639-2' => 'akk',
|
||||
'639-1' => null,
|
||||
'NAME_eng' => 'Akkadian',
|
||||
'NAME_fra' => 'akkadien',
|
||||
'NAME_deu' => 'Akkadisch',
|
||||
],
|
||||
'sqi' => [
|
||||
'639-2' => 'sqi',
|
||||
'639-1' => 'sq',
|
||||
'NAME_eng' => 'Albanian',
|
||||
'NAME_fra' => 'albanais',
|
||||
'NAME_deu' => 'Albanisch',
|
||||
'639-2-B' => 'alb',
|
||||
],
|
||||
|
||||
'deu' => [
|
||||
'639-2' => 'deu',
|
||||
'639-1' => 'de',
|
||||
'NAME_eng' => 'German',
|
||||
'NAME_fra' => 'allemand',
|
||||
'NAME_deu' => 'Deutsch',
|
||||
'639-2-B' => 'ger',
|
||||
'1L' => 'D',
|
||||
],
|
||||
'eng' => [
|
||||
'639-2' => 'eng',
|
||||
'639-1' => 'en',
|
||||
'NAME_eng' => 'English',
|
||||
'NAME_fra' => 'anglais',
|
||||
'NAME_deu' => 'Englisch',
|
||||
'1L' => 'E',
|
||||
],
|
||||
'fra' => [
|
||||
'639-2' => 'fra',
|
||||
'639-1' => 'fr',
|
||||
'NAME_eng' => 'French',
|
||||
'NAME_fra' => 'français',
|
||||
'NAME_deu' => 'Französisch',
|
||||
'639-2-B' => 'fre',
|
||||
'1L' => 'F',
|
||||
],
|
||||
'ita' => [
|
||||
'639-2' => 'ita',
|
||||
'639-1' => 'it',
|
||||
'NAME_eng' => 'Italian',
|
||||
'NAME_fra' => 'italien',
|
||||
'NAME_deu' => 'Italienisch',
|
||||
'1L' => 'I',
|
||||
],
|
||||
'spa' => [
|
||||
'639-2' => 'spa',
|
||||
'639-1' => 'es',
|
||||
'NAME_eng' => 'Spanish',
|
||||
'NAME_fra' => 'espagnol',
|
||||
'NAME_deu' => 'Spanisch',
|
||||
],
|
||||
'por' => [
|
||||
'639-2' => 'por',
|
||||
'639-1' => 'pt',
|
||||
'NAME_eng' => 'Portuguese',
|
||||
'NAME_fra' => 'portugais',
|
||||
'NAME_deu' => 'Portugiesisch',
|
||||
],
|
||||
'roh' => [
|
||||
'639-2' => 'roh',
|
||||
'639-1' => 'rm',
|
||||
'NAME_eng' => 'Romansh',
|
||||
'NAME_fra' => 'romanche',
|
||||
'NAME_deu' => 'Rätoromanisch',
|
||||
],
|
||||
'dut' => ['639-2' => 'dut', '639-1' => 'nl', 'NAME_eng' => 'Dutch', 'NAME_fra' => 'néerlandais', 'NAME_deu' => 'Niederländisch', 'NAME_deu_alt' => 'Holländisch'],
|
||||
'swe' => ['639-2' => 'swe', '639-1' => 'sv', 'NAME_eng' => 'Swedish', 'NAME_fra' => 'suédois', 'NAME_deu' => 'Schwedisch'],
|
||||
'dan' => ['639-2' => 'dan', '639-1' => 'da', 'NAME_eng' => 'Danish', 'NAME_fra' => 'danois', 'NAME_deu' => 'Dänisch'],
|
||||
'nor' => ['639-2' => 'nor', '639-1' => 'no', 'NAME_eng' => 'Norwegian', 'NAME_fra' => 'norvégien', 'NAME_deu' => 'Norwegisch'],
|
||||
];
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Xentral\Components\MailClient\Data;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use JsonSerializable;
|
||||
use Throwable;
|
||||
@@ -307,11 +308,13 @@ final class MailMessageData implements MailMessageInterface, JsonSerializable
|
||||
if ($date === null) {
|
||||
return null;
|
||||
}
|
||||
$dateTime = date_create($date->getValue());
|
||||
/* $dateTime = date_create($date->getValue());
|
||||
if ($dateTime === false) {
|
||||
throw new InvalidArgumentException('Invalid date: '.$date->getValue());
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
|
||||
$dateTime = new DateTimeImmutable($date->getValue());
|
||||
|
||||
return $dateTime;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ final class Psr4ClassNameResolver
|
||||
{
|
||||
// Normalize inputs
|
||||
$prefix = trim($prefix, '\\') . '\\';
|
||||
$baseDir = rtrim($baseDir, '/') . '/';
|
||||
$baseDir = rtrim($baseDir, '/\\') . DIRECTORY_SEPARATOR;
|
||||
|
||||
$this->prefixes[$prefix] = $baseDir;
|
||||
}
|
||||
|
||||
@@ -408,9 +408,6 @@ class TicketImportHelper
|
||||
$this->logger->error('Failed to insert ticket message into db', ['exception' => $e]);
|
||||
}
|
||||
|
||||
|
||||
$this->applyTicketRules($messageId);
|
||||
|
||||
return($result);
|
||||
}
|
||||
|
||||
@@ -440,7 +437,7 @@ class TicketImportHelper
|
||||
|
||||
foreach ($ruleArray as $rule) {
|
||||
|
||||
$this->logger->debug('ticket rule applies',['rule_id' => $rule['id']]);
|
||||
$this->logger->debug('ticket rule applies',['rule_id' => $rule['id'],'rule' => print_r($rule,true)]);
|
||||
|
||||
/*
|
||||
$update = $this->db->update();
|
||||
@@ -461,12 +458,16 @@ class TicketImportHelper
|
||||
$this->db->perform($sql, ['ticket_id' => $ticketId]);
|
||||
*/
|
||||
|
||||
if ($rule['is_spam'] === 1) {
|
||||
$sql = "UPDATE `ticket_nachricht` SET `status` = \'spam\' WHERE `id` = '".$ticketMessageId."'";
|
||||
$this->db->Update($sql);
|
||||
if ($rule['is_spam'] == 1) {
|
||||
$status = 'spam';
|
||||
} else {
|
||||
$status = 'neu';
|
||||
}
|
||||
|
||||
$sql = "UPDATE `ticket` SET `dsgvo` = '".$rule['is_gdpr_relevant']."', `privat` = '".$rule['is_private']."', `prio` = '".$rule['priority']."', `warteschlange` = '".$rule['queue_id']."' WHERE `id` = '".$ticketId."'";
|
||||
$sql = "UPDATE `ticket` SET `dsgvo` = '".$rule['is_gdpr_relevant']."', `privat` = '".$rule['is_private']."', `prio` = '".$rule['priority']."', `warteschlange` = '".$rule['queue_id']."', `status` = '".$status."' WHERE `id` = '".$ticketId."'";
|
||||
|
||||
$this->logger->debug('ticket rule sql',['sql' => $sql]);
|
||||
|
||||
$this->db->Update($sql);
|
||||
}
|
||||
}
|
||||
@@ -699,6 +700,12 @@ class TicketImportHelper
|
||||
$from
|
||||
);
|
||||
|
||||
// Only for new tickets: apply filter rules
|
||||
if (!$ticketexists) {
|
||||
$this->applyTicketRules($ticketnachricht);
|
||||
}
|
||||
|
||||
|
||||
if ($ticketnachricht > 0 && $emailbackup_mails_id > 0) {
|
||||
$this->db->Update(
|
||||
"UPDATE `emailbackup_mails`
|
||||
|
||||
@@ -30,10 +30,10 @@ $factoryServiceMap = @include $serviceCacheFile;
|
||||
|
||||
if (!is_file($serviceCacheFile)) {
|
||||
|
||||
// Installer ausführen wenn ServiceMap nicht vorhanden ist
|
||||
// Installer ausführen, wenn ServiceMap nicht vorhanden ist
|
||||
$resolver = new Psr4ClassNameResolver();
|
||||
$resolver->addNamespace('Xentral\\', __DIR__);
|
||||
$resolver->excludeFile(__DIR__ . '/bootstrap.php');
|
||||
$resolver->excludeFile(__DIR__ . DIRECTORY_SEPARATOR . 'bootstrap.php');
|
||||
|
||||
$generator = new ClassMapGenerator($resolver, __DIR__);
|
||||
$installer = new Installer($generator, $resolver);
|
||||
|
||||
@@ -1252,7 +1252,7 @@ Options -Indexes
|
||||
# Deny access to all *.php
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
<FilesMatch "\.(css|jpg|jpeg|gif|png|svg|js|ico|css.map)$">
|
||||
<FilesMatch "\.(css|jpg|jpeg|gif|png|svg|js|ico|css.map|js.map)$">
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</FilesMatch>
|
||||
|
||||
@@ -1424,7 +1424,7 @@ class DB{
|
||||
if(empty($TableName) || empty($IDFieldName) || empty($IDToDuplicate)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
$sql = "SELECT * FROM $TableName WHERE $IDFieldName = $IDToDuplicate";
|
||||
$result = @mysqli_query($this->connection,$sql);
|
||||
if(empty($result)) {
|
||||
@@ -1442,6 +1442,23 @@ class DB{
|
||||
}
|
||||
$sql .= $RowKeys[$i] . " = '" . $this->real_escape_string($RowValues[$i]) . "'";
|
||||
}
|
||||
|
||||
@mysqli_query($this->connection,$sql);
|
||||
*/
|
||||
|
||||
$sql = "INSERT INTO ".$TableName." SELECT ";
|
||||
$fields = $this->GetColAssocArray($TableName);
|
||||
$comma = "";
|
||||
foreach ($fields as $field => $value) {
|
||||
if ($field != $IDFieldName) {
|
||||
$sql .= $comma."`".$field."`";
|
||||
} else {
|
||||
$sql .= "NULL";
|
||||
}
|
||||
$comma = ", ";
|
||||
}
|
||||
$sql .= " FROM ".$TableName." WHERE id = ".$IDToDuplicate;
|
||||
|
||||
@mysqli_query($this->connection,$sql);
|
||||
|
||||
$id = $this->GetInsertID();
|
||||
|
||||
@@ -1542,7 +1542,7 @@ class YUI {
|
||||
if(!empty($positionsIds)) {
|
||||
$positions = $this->app->DB->SelectArr(
|
||||
sprintf(
|
||||
"SELECT b.id, %s AS `preis`, round(b.menge) as menge
|
||||
"SELECT b.id, %s AS `preis`, trim(b.menge)+0 as menge
|
||||
FROM `%s` AS `b`
|
||||
%s
|
||||
WHERE b.`%s` = %d AND b.id IN (%s)",
|
||||
@@ -2581,7 +2581,7 @@ class YUI {
|
||||
|
||||
|
||||
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum, round(b.menge) as menge, ".$this->FormatPreis($preiscell)." as preis,b.waehrung, ".$this->FormatPreis('b.rabatt')." as rabatt, ";
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum, trim(b.menge)+0 as menge, ".$this->FormatPreis($preiscell)." as preis,b.waehrung, ".$this->FormatPreis('b.rabatt')." as rabatt, ";
|
||||
|
||||
|
||||
$sql .= "b.id as id
|
||||
@@ -2601,7 +2601,7 @@ class YUI {
|
||||
as Artikel,
|
||||
|
||||
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum, round(b.menge) as menge, if(b.geliefert, ".$this->app->erp->FormatMenge('b.geliefert')." ,'-') as geliefert, b.id as id
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum, trim(b.menge)+0 as menge, if(b.geliefert, ".$this->app->erp->FormatMenge('b.geliefert')." ,'-') as geliefert, b.id as id
|
||||
FROM $table b
|
||||
LEFT JOIN artikel a ON a.id=b.artikel LEFT JOIN projekt p ON b.projekt=p.id
|
||||
WHERE b.$module='$id'";
|
||||
@@ -2656,7 +2656,7 @@ class YUI {
|
||||
|
||||
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum,
|
||||
round(b.menge) as menge,
|
||||
trim(b.menge)+0 as menge,
|
||||
if(b.geliefert, ".$this->app->erp->FormatMenge('b.geliefert')." ,'-') as geliefert,
|
||||
if(b.menge_eingang, ".$this->app->erp->FormatMenge('b.menge_eingang')." ,'-') as `Eingang`,
|
||||
if(b.menge_gutschrift, ".$this->app->erp->FormatMenge('b.menge_gutschrift')." ,'-') as `Menge Gutschrift`,
|
||||
@@ -2678,7 +2678,7 @@ class YUI {
|
||||
as Artikel,
|
||||
|
||||
|
||||
p.abkuerzung as projekt, b.nummer as nummer, round(b.menge) as menge,
|
||||
p.abkuerzung as projekt, b.nummer as nummer, trim(b.menge)+0 as menge,
|
||||
".$this->FormatPreis(' b.preis')." as preis,
|
||||
|
||||
b.id as id
|
||||
@@ -2695,7 +2695,7 @@ class YUI {
|
||||
as Artikel,
|
||||
|
||||
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(b.lieferdatum,'%d.%m.%Y') as lieferdatum, round(b.menge) as menge,
|
||||
p.abkuerzung as projekt, b.nummer as nummer, DATE_FORMAT(b.lieferdatum,'%d.%m.%Y') as lieferdatum, trim(b.menge)+0 as menge,
|
||||
|
||||
b.id as id
|
||||
FROM $table b
|
||||
@@ -2717,7 +2717,7 @@ class YUI {
|
||||
if(CHAR_LENGTH(b.bezeichnunglieferant)>" . $this->app->erp->MaxArtikelbezeichnung() . ",CONCAT(SUBSTR(CONCAT(b.bezeichnunglieferant,' *'),1," . $this->app->erp->MaxArtikelbezeichnung() . "),'...'),CONCAT(b.bezeichnunglieferant,' *')),
|
||||
if(CHAR_LENGTH(b.bezeichnunglieferant)>" . $this->app->erp->MaxArtikelbezeichnung() . ",CONCAT(SUBSTR(b.bezeichnunglieferant,1," . $this->app->erp->MaxArtikelbezeichnung() . "),'...'),b.bezeichnunglieferant)))
|
||||
as Artikel,
|
||||
p.abkuerzung as projekt, a.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum, round(b.menge) as menge, ".$this->FormatPreis(' b.preis')." as preis, b.waehrung, b.id as id
|
||||
p.abkuerzung as projekt, a.nummer as nummer, DATE_FORMAT(lieferdatum,'%d.%m.%Y') as lieferdatum, trim(b.menge)+0 as menge, ".$this->FormatPreis(' b.preis')." as preis, b.waehrung, b.id as id
|
||||
FROM $table b
|
||||
LEFT JOIN artikel a ON a.id=b.artikel LEFT JOIN projekt p ON b.projekt=p.id
|
||||
WHERE b.$module='$id'";
|
||||
|
||||
@@ -99553,6 +99553,17 @@
|
||||
"Privileges": "select,insert,update,references",
|
||||
"Comment": ""
|
||||
},
|
||||
{
|
||||
"Field": "getestet",
|
||||
"Type": "int(11)",
|
||||
"Collation": null,
|
||||
"Null": "NO",
|
||||
"Key": "",
|
||||
"Default": "0",
|
||||
"Extra": "",
|
||||
"Privileges": "select,insert,update,references",
|
||||
"Comment": ""
|
||||
},
|
||||
{
|
||||
"Field": "bearbeiter",
|
||||
"Type": "varchar(32)",
|
||||
|
||||
@@ -365,6 +365,9 @@ function upgrade_main(string $directory,bool $verbose, bool $check_git, bool $do
|
||||
foreach ($compare_differences as $compare_difference) {
|
||||
$comma = "";
|
||||
foreach ($compare_difference as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = implode(',',$value);
|
||||
}
|
||||
echo_out($comma."$key => [$value]");
|
||||
$comma = ", ";
|
||||
}
|
||||
|
||||
+21
-15
@@ -67,6 +67,7 @@ $mustal_replacers = [
|
||||
['on update current_timestamp','on update current_timestamp()']
|
||||
];
|
||||
|
||||
|
||||
// Load all db_def from a DB connection into a db_def array
|
||||
function mustal_load_tables_from_db(string $host, string $schema, string $user, string $passwd, array $replacers) : array {
|
||||
|
||||
@@ -358,8 +359,6 @@ function mustal_compare_table_array(array $nominal, string $nominal_name, array
|
||||
$compare_difference['table'] = $database_table['name'];
|
||||
$compare_difference['key'] = $sql_index['Key_name'];
|
||||
$compare_difference['property'] = $key;
|
||||
/* $compare_difference[$nominal_name] = implode(',',$value);
|
||||
$compare_difference[$actual_name] = implode(',',$found_sql_index[$key]);*/
|
||||
$compare_difference[$nominal_name] = $value;
|
||||
$compare_difference[$actual_name] = $found_sql_index[$key];
|
||||
$compare_differences[] = $compare_difference;
|
||||
@@ -585,14 +584,7 @@ function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$
|
||||
if ($key['Key_name'] == 'PRIMARY') {
|
||||
$keystring = "PRIMARY KEY ";
|
||||
} else {
|
||||
|
||||
// if(array_key_exists('Index_type', $key)) {
|
||||
// $index_type = $key['Index_type'];
|
||||
// } else {
|
||||
$index_type = "";
|
||||
// }
|
||||
|
||||
$keystring = $index_type." ".$key['Non_unique']." KEY `".$key['Key_name']."` ";
|
||||
$keystring = mustal_key_type(" ".$key['Non_unique']." KEY `".$key['Key_name']."` ",$key['Index_type']);
|
||||
}
|
||||
$sql .= $comma.$keystring."(`".implode("`,`",$key['columns'])."`) ";
|
||||
}
|
||||
@@ -675,10 +667,7 @@ function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$
|
||||
|
||||
if ($key_key !== false) {
|
||||
$key = $table['keys'][$key_key];
|
||||
|
||||
$sql = "ALTER TABLE `$table_name` ADD ".$key['Non_unique']." KEY `".$key_name."` ";
|
||||
$sql .= "(`".implode("`,`",$key['columns'])."`)";
|
||||
$sql .= ";";
|
||||
$sql = "ALTER TABLE `$table_name` ADD ".mustal_key_type(" ".$key['Non_unique']." KEY `".$key['Key_name']."` "."(`".implode("`,`",$key['columns'])."`)",$key['Index_type']).";";
|
||||
$upgrade_sql[] = $sql;
|
||||
}
|
||||
else {
|
||||
@@ -706,7 +695,7 @@ function mustal_calculate_db_upgrade(array $compare_def, array $db_def, array &$
|
||||
$sql = "ALTER TABLE `$table_name` DROP KEY `".$key_name."`;";
|
||||
$upgrade_sql[] = $sql;
|
||||
|
||||
$sql = "ALTER TABLE `$table_name` ADD ".$key['Non_unique']." KEY `".$key_name."` ";
|
||||
$sql = "ALTER TABLE `$table_name` ADD ".mustal_key_type(" ".$key['Non_unique']." KEY `".$key['Key_name']."` ",$key['Index_type']);
|
||||
$sql .= "(`".implode("`,`",$key['columns'])."`)";
|
||||
$sql .= ";";
|
||||
$upgrade_sql[] = $sql;
|
||||
@@ -781,3 +770,20 @@ function mustal_is_string_type(string $type) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
// create correct index type syntax
|
||||
function mustal_key_type(string $key_definition_string, string $key_type) {
|
||||
|
||||
// Key types with using syntax
|
||||
$mustal_key_types_using_mapping = [
|
||||
'BTREE',
|
||||
'HASH'
|
||||
];
|
||||
|
||||
if (in_array($key_type,$mustal_key_types_using_mapping)) {
|
||||
return ($key_definition_string." USING ".$key_type);
|
||||
} else {
|
||||
return ($key_type." ".$key_definition_string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ Options -Indexes
|
||||
# Deny access to all *.php
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
<FilesMatch "\.(css|jpg|jpeg|gif|png|svg|js|ico|css.map)$">
|
||||
<FilesMatch "\.(css|jpg|jpeg|gif|png|svg|js|ico|css.map|js.map)$">
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</FilesMatch>
|
||||
|
||||
@@ -559,7 +559,7 @@ class Remote
|
||||
$steuersatz_normal = 19;
|
||||
}
|
||||
$crossellingInstalled = $this->app->erp->ModulVorhanden('crossselling');
|
||||
foreach($reta as $k => $ret)
|
||||
foreach($reta as $k => $ret)
|
||||
{
|
||||
if(isset($ret['stueckliste'])){
|
||||
$stuecklistenmechanik = $ret['stueckliste'];
|
||||
@@ -631,8 +631,17 @@ class Remote
|
||||
}
|
||||
$arr['projekt'] = $shopexportArr['projekt'];
|
||||
$arr['name_de'] = $ret['name'];
|
||||
$arr['uebersicht_de'] = isset($ret['uebersicht_de'])?$ret['uebersicht_de']:'';
|
||||
$arr['kurztext_de'] = isset($ret['kurztext_de'])?$ret['kurztext_de']:'';
|
||||
$arr['uebersicht_de'] = $ret['uebersicht_de'] ?? '';
|
||||
$arr['kurztext_de'] = $ret['kurztext_de'] ?? '';
|
||||
$arr['name_en'] = $ret['name_en'];
|
||||
$arr['uebersicht_en'] = $ret['uebersicht_en'] ?? '';
|
||||
$arr['kurztext_en'] = $ret['kurztext_en'] ?? '';
|
||||
$arr['metakeywords_de'] = $ret['metakeywords_de'] ?? '';
|
||||
$arr['metakeywords_en'] = $ret['metakeywords_en'] ?? '';
|
||||
$arr['metatitle_de'] = $ret['metatitle_de'] ?? '';
|
||||
$arr['metatitle_en'] = $ret['metatitle_en'] ?? '';
|
||||
$arr['metadescription_de'] = $ret['metadescription_de'] ?? '';
|
||||
$arr['metadescription_en'] = $ret['metadescription_en'] ?? '';
|
||||
//$arr['anabregs_text'] = isset($ret['uebersicht_de'])?$ret['uebersicht_de']:'';
|
||||
if(isset($ret['ean']) && $ret['ean'] != '')
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2054,7 +2054,7 @@ $table_kontakte = '';
|
||||
$ckontakte = !empty($kontakte)?count($kontakte):0;
|
||||
for($i=0;$i<$ckontakte;$i++)
|
||||
{
|
||||
$tabindex = $tabindex+i;
|
||||
$tabindex = $tabindex+$i;
|
||||
$table_kontakte .= "<tr><td>".$kontakte[$i]['bezeichnung'].":
|
||||
</td><td><input type=text name=\"adresse_kontakte[".$kontakte[$i]['id']."]\" value=\"".$kontakte[$i]['kontakt']."\" size=\"30\" tabindex=\"$tabindex\"> <a href=\"#\" onclick=\"if(!confirm('".$kontakte[$i]['bezeichnung']." wirklich entfernen?')) return false; else window.location.href='index.php?module=adresse&action=delkontakt&id=".$id."&lid=".$kontakte[$i]['id']."';\">x</a></td></tr>";
|
||||
}
|
||||
|
||||
@@ -932,14 +932,14 @@ class Artikel extends GenArtikel {
|
||||
|
||||
$alignright = array(3,5,6);
|
||||
// SQL statement
|
||||
$sql = "SELECT SQL_CALC_FOUND_ROWS
|
||||
$sql = "SELECT SQL_CALC_FOUND_ROWS
|
||||
s.id,
|
||||
CONCAT('<a href=\"index.php?module=artikel&action=edit&id=',a.id,'\" target=\"_blank\">',a.name_de,'</a> ',
|
||||
IF(s.art='it','<br><i style=color:#999>- Informationsteil/Dienstleistung</i>',''),IF(s.art='bt','<br><i style=color:#999>- Beistellung</i>',''), COALESCE((SELECT GROUP_CONCAT('<br><i style=color:#999>- ', art.nummer, ' ', art.name_de, ' (', alt.reason, ')', '</i>' SEPARATOR '') FROM parts_list_alternative AS alt INNER JOIN artikel AS art ON art.id = alt.alternative_article_id WHERE alt.parts_list_id = s.id), '')) as artikel,
|
||||
CONCAT('<a href=\"index.php?module=artikel&action=edit&id=',a.id,'\" target=\"_blank\">',a.nummer,'</a>') as nummer,
|
||||
CONCAT('<a href=\"index.php?module=artikel&action=edit&id=',a.id,'\" target=\"_blank\">',a.nummer,'</a>') as nummer,
|
||||
s.referenz,
|
||||
".$this->app->erp->FormatMenge('s.menge').' as menge, a.einheit,
|
||||
'.$this->app->erp->FormatMenge('ifnull(lag.menge,0)').' as lager,
|
||||
trim(s.menge)+0 as menge, a.einheit,
|
||||
".$this->app->erp->FormatMenge('ifnull(lag.menge,0)').' as lager,
|
||||
CASE WHEN (SELECT SUM(lr.menge) FROM lager_reserviert lr WHERE lr.artikel=a.id) > 0
|
||||
THEN (SELECT '.$this->app->erp->FormatMenge('SUM(lr.menge)')." FROM lager_reserviert lr WHERE lr.artikel=a.id)
|
||||
ELSE 0
|
||||
@@ -6321,7 +6321,7 @@ class Artikel extends GenArtikel {
|
||||
|
||||
$id = (int)$this->app->Secure->GetPOST('id');
|
||||
|
||||
$data = $this->app->DB->SelectRow('SELECT s.id, s.artikel, '.$this->app->erp->FormatMenge("s.menge")." as menge, s.art, s.referenz, s.layer, s.place, s.wert, s.bauform, s.zachse, s.xpos, s.ypos FROM stueckliste s WHERE s.id = '$id' LIMIT 1");
|
||||
$data = $this->app->DB->SelectRow("SELECT s.id, s.artikel, trim(s.menge)+0 as menge, s.art, s.referenz, s.layer, s.place, s.wert, s.bauform, s.zachse, s.xpos, s.ypos FROM stueckliste s WHERE s.id = '$id' LIMIT 1");
|
||||
|
||||
if($data){
|
||||
if($data['artikel'] == 0){
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<legend>{|Aktionen|}</legend>
|
||||
<td><button name="submit" value="speichern" class="ui-button-icon" style="width:100%;">Speichern</button></td></tr>
|
||||
<td><button name="submit" value="neue_email" class="ui-button-icon" style="width:100%;">Neue E-Mail</button></td></tr>
|
||||
<td><button name="submit" formaction="index.php?module=ticketregeln&action=create" value="regel" class="ui-button-icon" style="width:100%;">Ticketregel erstellen</button><input hidden type="text" name="ticketid" value="[ID]"></td></tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
@@ -61,4 +62,3 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -17,50 +17,25 @@
|
||||
<div class="col-xs-12 col-md-12 col-md-height">
|
||||
<div class="inside inside-full-height">
|
||||
<fieldset>
|
||||
<legend>{|Ticketregeln|}</legend><i>Ticketregeln fü die Verarbeitung bei Ticketeingang. Platzhalter werden mit % angegeben.</i>
|
||||
<legend>{|Ticketregeln|}</legend><i>Ticketregeln für die Verarbeitung bei Ticketeingang. Platzhalter werden mit % angegeben.</i>
|
||||
<table width="100%" border="0" class="mkTableFormular">
|
||||
<tr><td>{|E-Mail Empfänger|}:</td><td><input type="text" name="empfaenger_email" value="[EMPFAENGER_EMAIL]" size="40"></td></tr>
|
||||
<tr><td>{|E-Mail Verfasser|}:</td><td><input type="text" name="sender_email" value="[SENDER_EMAIL]" size="40"></td></tr>
|
||||
<tr><td>{|Verfasser Name|}:</td><td><input type="text" name="name" value="[NAME]" size="40"></td></tr>
|
||||
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" value="[BETREFF]" size="40"></td></tr>
|
||||
<tr><td>{|Papierkorb|}:</td><td><input type="text" name="spam" value="[SPAM]" size="40"></td></tr>
|
||||
<tr><td>{|Persönlich|}:</td><td><input type="text" name="persoenlich" value="[PERSOENLICH]" size="40"></td></tr>
|
||||
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="40"></td></tr>
|
||||
<tr><td>{|DSGVO|}:</td><td><input type="text" name="dsgvo" value="[DSGVO]" size="40"></td></tr>
|
||||
<tr><td>{|Papierkorb|}:</td><td><input type="checkbox" name="spam" value="1" [SPAM] size="40"></td></tr>
|
||||
<tr><td>{|Persönlich|}:</td><td><input type="checkbox" name="persoenlich" value="1" [PERSOENLICH] size="40"></td></tr>
|
||||
<tr><td>{|Prio|}:</td><td><input type="checkbox" name="prio" value="1" [PRIO] size="40"></td></tr>
|
||||
<tr><td>{|DSGVO|}:</td><td><input type="checkbox" name="dsgvo" value="1" [DSGVO] size="40"></td></tr>
|
||||
<tr><td>{|Verantwortliche Warteschlange|}:</td><td><input type="text" name="warteschlange" id="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
|
||||
<tr><td>{|Aktiv|}:</td><td><input type="text" name="aktiv" value="[AKTIV]" size="40"></td></tr>
|
||||
<tr><td>{|Aktiv|}:</td><td><input type="checkbox" name="aktiv" value="1" [AKTIV] size="40"></td></tr>
|
||||
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Example for 2nd row
|
||||
<div class="row">
|
||||
<div class="row-height">
|
||||
<div class="col-xs-12 col-md-12 col-md-height">
|
||||
<div class="inside inside-full-height">
|
||||
<fieldset>
|
||||
<legend>{|Another legend|}</legend>
|
||||
<table width="100%" border="0" class="mkTableFormular">
|
||||
<tr><td>{|Empfaenger_email|}:</td><td><input type="text" name="empfaenger_email" value="[EMPFAENGER_EMAIL]" size="40"></td></tr>
|
||||
<tr><td>{|Sender_email|}:</td><td><input type="text" name="sender_email" value="[SENDER_EMAIL]" size="40"></td></tr>
|
||||
<tr><td>{|Name|}:</td><td><input type="text" name="name" value="[NAME]" size="40"></td></tr>
|
||||
<tr><td>{|Betreff|}:</td><td><input type="text" name="betreff" value="[BETREFF]" size="40"></td></tr>
|
||||
<tr><td>{|Spam|}:</td><td><input type="text" name="spam" value="[SPAM]" size="40"></td></tr>
|
||||
<tr><td>{|Persoenlich|}:</td><td><input type="text" name="persoenlich" value="[PERSOENLICH]" size="40"></td></tr>
|
||||
<tr><td>{|Prio|}:</td><td><input type="text" name="prio" value="[PRIO]" size="40"></td></tr>
|
||||
<tr><td>{|Dsgvo|}:</td><td><input type="text" name="dsgvo" value="[DSGVO]" size="40"></td></tr>
|
||||
<tr><td>{|Warteschlange|}:</td><td><input type="text" name="warteschlange" value="[WARTESCHLANGE]" size="40"></td></tr>
|
||||
<tr><td>{|Aktiv|}:</td><td><input type="text" name="aktiv" value="[AKTIV]" size="40"></td></tr>
|
||||
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<input type="submit" name="submit" value="Speichern" style="float:right"/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,11 @@
|
||||
<td>{|Sprache|}:</td>
|
||||
<td><select name="sprachebevorzugen" id="sprachebevorzugen">[SPRACHEBEVORZUGEN]</select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td>{|Sprache und Region|}:</td>
|
||||
<td><input type="text" name="locale" id="locale" value="[LOCALE]" size="40" disabled="disabled"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{|Eigene Kalenderfarbe|}:</td>
|
||||
<td><input type="text" name="defaultcolor" id="defaultcolor" value="[DEFAULTCOLOR]" size="80"></td>
|
||||
<td></td>
|
||||
|
||||
+10
-6
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
/*
|
||||
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
|
||||
*
|
||||
@@ -10,8 +10,8 @@
|
||||
* to obtain the text of the corresponding license version.
|
||||
*
|
||||
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
|
||||
*/
|
||||
?>
|
||||
*/
|
||||
?>
|
||||
<?php
|
||||
class Logfile {
|
||||
/** @var Application $app */
|
||||
@@ -253,9 +253,13 @@ class Logfile {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(is_array($meldung)) {
|
||||
$meldung = $this->app->DB->real_escape_string(print_r($meldung, true));
|
||||
}
|
||||
|
||||
$module = $this->app->DB->real_escape_string(is_scalar($module) ? strval($module) : print_r($module, true));
|
||||
$action = $this->app->DB->real_escape_string(is_scalar($action) ? strval($action) : print_r($action, true));
|
||||
$meldung = $this->app->DB->real_escape_string(is_scalar($meldung) ? strval($meldung) : print_r($meldung, true));
|
||||
$dump = $this->app->DB->real_escape_string(is_scalar($dump) ? strval($dump) : print_r($dump, true));
|
||||
$functionname = $this->app->DB->real_escape_string(is_scalar($functionname) ? strval($functionname) : print_r($functionname, true));
|
||||
|
||||
$this->app->DB->Insert(
|
||||
sprintf(
|
||||
"INSERT INTO logfile (module,action,meldung,dump,datum,bearbeiter,funktionsname)
|
||||
|
||||
@@ -610,7 +610,7 @@ class Shopexport
|
||||
'SELECT `id`
|
||||
FROM `shopexport`
|
||||
WHERE `aktiv` = 1 AND `autosendarticle` = 1 AND `artikelexport` = 1
|
||||
AND (`autosendarticle_last` IS NULL OR DATE_ADD(`autosendarticle_last` INTERVAL %d MINUTE) <= NOW())',
|
||||
AND (`autosendarticle_last` IS NULL OR DATE_ADD(`autosendarticle_last`, INTERVAL %d MINUTE) <= NOW())',
|
||||
$minutes
|
||||
)
|
||||
);
|
||||
|
||||
@@ -333,34 +333,64 @@ class Shopimporter_Presta extends ShopimporterBase
|
||||
if (empty($nummer))
|
||||
return;
|
||||
|
||||
$searchresult = $this->prestaRequest('GET', 'products?filter[reference]='.$nummer);
|
||||
if (empty($searchresult)) {
|
||||
$productsresult = $this->prestaRequest('GET', 'products?filter[reference]='.$nummer);
|
||||
$combinationsresult = $this->prestaRequest('GET', 'combinations?filter[reference]='.$nummer);
|
||||
$numberOfCombinations = count($combinationsresult->combinations->combination);
|
||||
$numberOfProducts = count($productsresult->products->product);
|
||||
$numberOfResults = $numberOfProducts + $numberOfCombinations;
|
||||
if ($numberOfResults > 1) {
|
||||
$this->Log('Got multiple results from Shop', $this->data);
|
||||
return;
|
||||
}
|
||||
elseif ($numberOfResults < 1) {
|
||||
$this->Log('No product found in Shop', $this->data);
|
||||
return;
|
||||
}
|
||||
if (count($searchresult->products->product) > 1) {
|
||||
$this->Log('Got multiple results from Shop', $this->data);
|
||||
}
|
||||
|
||||
$productid = $searchresult->products->product->attributes()->id;
|
||||
$product = $this->prestaRequest('GET', "products/$productid");
|
||||
$isCombination = $numberOfCombinations > 0;
|
||||
if ($isCombination) {
|
||||
$combinationId = intval($combinationsresult->combinations->combination->attributes()->id);
|
||||
$combination = $this->prestaRequest('GET', "combinations/$combinationId");
|
||||
$productId = intval($combination->combination->id_product);
|
||||
} else {
|
||||
$productId = intval($productsresult->products->product->attributes()->id);
|
||||
}
|
||||
$product = $this->prestaRequest('GET', "products/$productId");
|
||||
$res = [];
|
||||
$res['nummer'] = strval($product->product->reference);
|
||||
$res['artikelnummerausshop'] = strval($product->product->reference);
|
||||
if ($isCombination) {
|
||||
$res['nummer'] = strval($combination->combination->reference);
|
||||
$res['artikelnummerausshop'] = strval($combination->combination->reference);
|
||||
$res['ean'] = strval($combination->combination->ean13);
|
||||
$res['preis_netto'] = floatval($product->product->price) + floatval($combination->combination->price);
|
||||
} else {
|
||||
$res['nummer'] = strval($product->product->reference);
|
||||
$res['artikelnummerausshop'] = strval($product->product->reference);
|
||||
$res['ean'] = strval($product->product->ean13);
|
||||
$res['preis_netto'] = floatval($product->product->price);
|
||||
}
|
||||
$names = $this->toMultilangArray($product->product->name->language);
|
||||
$descriptions = $this->toMultilangArray($product->product->description->language);
|
||||
$shortdescriptions = $this->toMultilangArray($product->product->description_short->language);
|
||||
$metadescriptions = $this->toMultilangArray($product->product->meta_description->language);
|
||||
$metakeywords = $this->toMultilangArray($product->product->meta_keywords->language);
|
||||
$metatitles = $this->toMultilangArray($product->product->meta_title->language);
|
||||
$res['name'] = $names['de'];
|
||||
$res['name_en'] = $names['en'];
|
||||
$res['uebersicht_de'] = $descriptions['de'];
|
||||
$res['uebersicht_en'] = $descriptions['en'];
|
||||
$res['preis_netto'] = strval($product->product->price);
|
||||
$res['kurztext_de'] = strip_tags($shortdescriptions['de']);
|
||||
$res['kurztext_en'] = strip_tags($shortdescriptions['en']);
|
||||
$res['hersteller'] = strval($product->product->manufacturer_name);
|
||||
$res['ean'] = strval($product->product->ean13);
|
||||
$res['metakeywords_de'] = $metakeywords['de'];
|
||||
$res['metakeywords_en'] = $metakeywords['en'];
|
||||
$res['metatitle_de'] = $metatitles['de'];
|
||||
$res['metatitle_en'] = $metatitles['en'];
|
||||
$res['metadescription_de'] = $metadescriptions['de'];
|
||||
$res['metadescription_en'] = $metadescriptions['en'];
|
||||
|
||||
$images = [];
|
||||
foreach ($product->product->associations->images->image as $img) {
|
||||
$endpoint = "images/products/$productid/$img->id";
|
||||
$endpoint = "images/products/$productId/$img->id";
|
||||
$imgdata = $this->prestaRequest('GET', $endpoint, '', true);
|
||||
$images[] = [
|
||||
'content' => base64_encode($imgdata),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
/*
|
||||
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
|
||||
*
|
||||
@@ -10,8 +10,8 @@
|
||||
* to obtain the text of the corresponding license version.
|
||||
*
|
||||
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
|
||||
*/
|
||||
?>
|
||||
*/
|
||||
?>
|
||||
<?php
|
||||
use Xentral\Components\Http\JsonResponse;
|
||||
|
||||
@@ -230,10 +230,14 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
if(isset($this->app->User) && $this->app->User && method_exists($this->app->User, 'GetName')){
|
||||
$this->bearbeiter = $this->app->DB->real_escape_string($this->app->User->GetName());
|
||||
}
|
||||
|
||||
$einstellungen = $this->app->DB->Select("SELECT einstellungen_json FROM shopexport WHERE id = '$shopid' LIMIT 1");
|
||||
if($einstellungen){
|
||||
if(!empty($einstellungen)){
|
||||
$einstellungen = json_decode($einstellungen,true);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->ShopifyURL=trim($einstellungen['felder']['ShopifyURL']);
|
||||
if(stripos($this->ShopifyURL,'http') === false){
|
||||
$this->ShopifyURL = 'https://'.$this->ShopifyURL;
|
||||
@@ -396,7 +400,7 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$this->adapter->call("products/".$result['data']['product']['id']."/metafields.json", 'POST', array('metafield' => [
|
||||
'key' => 'sync_status',
|
||||
'value' => 1,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
]));
|
||||
if($result['data']['product']['id'] == $nummer) {
|
||||
@@ -429,7 +433,7 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$this->adapter->call("variants/".$resultv['variant']['id']."/metafields.json", 'POST', array('metafield' => [
|
||||
'key' => 'sync_status',
|
||||
'value' => 1,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
]));
|
||||
$data['nummer'] = $resultv['data']['variant']['sku'];
|
||||
@@ -690,7 +694,7 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$inventoryitemid = $resultv['data']['variant']['inventory_item_id'];
|
||||
$resulti = $this->adapter->call("inventory_levels.json?inventory_item_ids=$inventoryitemid&location_ids=$locationid");
|
||||
$vorhanden = $resulti['data']['inventory_levels'][0]['available'];
|
||||
$adjust = $lageranzahl - $vorhanden;
|
||||
$adjust = floatval($lageranzahl) - floatval($vorhanden);
|
||||
if($adjust != 0){
|
||||
$data = array("location_id" => $locationid,
|
||||
"inventory_item_id"=> $inventoryitemid,
|
||||
@@ -1015,12 +1019,12 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$dataproduct['product']['variants'][0]['metafields'] = array(array(
|
||||
"key" => "harmonized_system_code",
|
||||
"value"=> $zolltarifnummer,
|
||||
"value_type"=> "string",
|
||||
"type"=> "text",
|
||||
"namespace"=> "global"),
|
||||
[
|
||||
'key' => 'sync_status',
|
||||
'value' => 1,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
]);
|
||||
if($pseudopreis != ''){
|
||||
@@ -1185,12 +1189,12 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$veigenschaften[] = array(
|
||||
"key" => "harmonized_system_code",
|
||||
"value"=> $value['zolltarifnummer'],
|
||||
"value_type"=> "string",
|
||||
"type"=> "text",
|
||||
"namespace"=> "global");
|
||||
$veigenschaften[] = [
|
||||
'key' => 'sync_status',
|
||||
'value' => 1,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
];
|
||||
|
||||
@@ -3334,7 +3338,7 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$this->adapter->call('orders/' . $auftrag . '/metafields.json', 'POST', array('metafield' => [
|
||||
'key' => 'sync_status',
|
||||
'value' => 1,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
]));
|
||||
return 'ok';
|
||||
@@ -3367,7 +3371,7 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$this->adapter->call('orders/' . $auftrag . '/metafields.json', 'POST', array('metafield' => [
|
||||
'key' => 'sync_status',
|
||||
'value' => 3,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
]));
|
||||
}
|
||||
@@ -3420,7 +3424,7 @@ class Shopimporter_Shopify extends ShopimporterBase
|
||||
$this->adapter->call('orders/' . $auftrag . '/metafields.json', 'POST', array('metafield' => [
|
||||
'key' => 'sync_status',
|
||||
'value' => 2,
|
||||
'value_type' => 'integer',
|
||||
'type' => 'number_integer',
|
||||
'namespace' => 'xentral',
|
||||
]));
|
||||
}else{
|
||||
|
||||
+97
-43
@@ -98,67 +98,121 @@ class Ticketregeln {
|
||||
if (empty($id)) {
|
||||
// New item
|
||||
$id = 'NULL';
|
||||
|
||||
// Check for ticketid
|
||||
$ticketid = $this->app->Secure->GetPOST('ticketid');
|
||||
if (!empty($ticketid)) {
|
||||
$sql = "
|
||||
SELECT
|
||||
n.id,
|
||||
n.betreff,
|
||||
n.bearbeiter,
|
||||
n.verfasser,
|
||||
n.mail,
|
||||
t.quelle,
|
||||
t.warteschlange,
|
||||
".$this->app->erp->FormatDateTimeShort('n.zeit','zeit').",
|
||||
".$this->app->erp->FormatDateTimeShort('n.zeitausgang','zeitausgang').",
|
||||
n.versendet,
|
||||
n.text,
|
||||
n.textausgang,
|
||||
n.verfasser_replyto,
|
||||
n.mail_replyto,
|
||||
n.mail_cc,
|
||||
(SELECT GROUP_CONCAT(value SEPARATOR ', ') FROM ticket_header th WHERE th.ticket_nachricht = n.id AND th.type = 'cc') as mail_cc_recipients,
|
||||
(SELECT GROUP_CONCAT(value SEPARATOR ', ') FROM ticket_header th WHERE th.ticket_nachricht = n.id AND th.type = 'to') as mail_recipients
|
||||
FROM ticket_nachricht n INNER JOIN ticket t ON t.schluessel = n.ticket
|
||||
WHERE t.id = ".$ticketid." ORDER BY n.zeit DESC LIMIT 1";
|
||||
|
||||
$last_message = $this->app->DB->SelectArr($sql)[0];
|
||||
|
||||
$input['empfaenger_email'] = $last_message['mail_recipients'];
|
||||
$input['sender_email'] = $last_message['mail'];
|
||||
$input['name'] = $last_message['verfasser'];
|
||||
$input['betreff'] = $last_message['betreff'];
|
||||
$input['warteschlange'] = $last_message['warteschlange'];
|
||||
|
||||
$from_ticket = true;
|
||||
|
||||
$result = array(
|
||||
'empfaenger_email' => $last_message['mail_recipients'],
|
||||
'sender_email' => $last_message['mail'],
|
||||
'name' => $last_message['verfasser'],
|
||||
'betreff' => $last_message['betreff'],
|
||||
'warteschlange' => $last_message['warteschlange'],
|
||||
'aktiv' => 1
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($submit != '')
|
||||
{
|
||||
if (!$from_ticket) {
|
||||
|
||||
// Write to database
|
||||
|
||||
// Add checks here
|
||||
$input['warteschlange'] = explode(" ",$input['warteschlange'])[0]; // Just the label
|
||||
if ($submit != '')
|
||||
{
|
||||
|
||||
$columns = "id, ";
|
||||
$values = "$id, ";
|
||||
$update = "";
|
||||
|
||||
$fix = "";
|
||||
// Write to database
|
||||
|
||||
// Add checks here
|
||||
$input['warteschlange'] = explode(" ",$input['warteschlange'])[0]; // Just the label
|
||||
|
||||
foreach ($input as $key => $value) {
|
||||
$columns = $columns.$fix.$key;
|
||||
$values = $values.$fix."'".$value."'";
|
||||
$update = $update.$fix.$key." = '$value'";
|
||||
$columns = "id, ";
|
||||
$values = "$id, ";
|
||||
$update = "";
|
||||
|
||||
$fix = "";
|
||||
|
||||
$fix = ", ";
|
||||
foreach ($input as $key => $value) {
|
||||
$columns = $columns.$fix.$key;
|
||||
$values = $values.$fix."'".$value."'";
|
||||
$update = $update.$fix.$key." = '$value'";
|
||||
|
||||
$fix = ", ";
|
||||
}
|
||||
|
||||
// echo($columns."<br>");
|
||||
// echo($values."<br>");
|
||||
// echo($update."<br>");
|
||||
|
||||
$sql = "INSERT INTO ticket_regeln (".$columns.") VALUES (".$values.") ON DUPLICATE KEY UPDATE ".$update;
|
||||
|
||||
// echo($sql);
|
||||
|
||||
$this->app->DB->Update($sql);
|
||||
|
||||
if ($id == 'NULL') {
|
||||
$msg = $this->app->erp->base64_url_encode("<div class=\"success\">Das Element wurde erfolgreich angelegt.</div>");
|
||||
header("Location: index.php?module=ticketregeln&action=list&msg=$msg");
|
||||
// $this->app->Tpl->Set('MESSAGE', "<div class=\"success\">Das Element wurde erfolgreich angelegt.</div>");
|
||||
// $id = $this->app->DB->GetInsertID();
|
||||
} else {
|
||||
$this->app->Tpl->Set('MESSAGE', "<div class=\"success\">Die Einstellungen wurden erfolgreich übernommen.</div>");
|
||||
}
|
||||
}
|
||||
|
||||
// echo($columns."<br>");
|
||||
// echo($values."<br>");
|
||||
// echo($update."<br>");
|
||||
|
||||
// Load values again from database
|
||||
$result = $this->app->DB->SelectArr("SELECT t.id, t.empfaenger_email, t.sender_email, t.name, t.betreff, t.spam, t.persoenlich, t.prio, t.dsgvo, CONCAT(w.label,' ',w.warteschlange) as warteschlange, t.aktiv, t.id FROM ticket_regeln t LEFT JOIN warteschlangen w on t.warteschlange = w.label WHERE t.id=$id")[0];
|
||||
}
|
||||
|
||||
|
||||
$sql = "INSERT INTO ticket_regeln (".$columns.") VALUES (".$values.") ON DUPLICATE KEY UPDATE ".$update;
|
||||
|
||||
// echo($sql);
|
||||
|
||||
$this->app->DB->Update($sql);
|
||||
|
||||
if ($id == 'NULL') {
|
||||
$msg = $this->app->erp->base64_url_encode("<div class=\"success\">Das Element wurde erfolgreich angelegt.</div>");
|
||||
header("Location: index.php?module=ticketregeln&action=list&msg=$msg");
|
||||
} else {
|
||||
$this->app->Tpl->Set('MESSAGE', "<div class=\"success\">Die Einstellungen wurden erfolgreich übernommen.</div>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load values again from database
|
||||
$result = $this->app->DB->SelectArr("SELECT t.id, t.empfaenger_email, t.sender_email, t.name, t.betreff, t.spam, t.persoenlich, t.prio, t.dsgvo, t.warteschlange, t.aktiv, t.id FROM ticket_regeln t"." WHERE id=$id");
|
||||
|
||||
foreach ($result[0] as $key => $value) {
|
||||
foreach ($result as $key => $value) {
|
||||
$this->app->Tpl->Set(strtoupper($key), $value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add displayed items later
|
||||
*
|
||||
|
||||
$this->app->Tpl->Add('KURZUEBERSCHRIFT2', $email);
|
||||
$this->app->Tpl->Add('EMAIL', $email);
|
||||
$this->app->Tpl->Add('ANGEZEIGTERNAME', $angezeigtername);
|
||||
*/
|
||||
|
||||
$this->app->YUI->AutoComplete("warteschlange","warteschlangename");
|
||||
$this->app->Tpl->Set('PRIO', $result['prio']==1?"checked":"");
|
||||
$this->app->Tpl->Set('SPAM', $result['spam']==1?"checked":"");
|
||||
$this->app->Tpl->Set('PERSOENLICH', $result['persoenlich']==1?"checked":"");
|
||||
$this->app->Tpl->Set('DSGVO', $result['dsgvo']==1?"checked":"");
|
||||
$this->app->Tpl->Set('AKTIV', $result['aktiv']==1?"checked":"");
|
||||
|
||||
$this->app->YUI->AutoComplete("warteschlange","warteschlangename");
|
||||
|
||||
// $this->SetInput($input);
|
||||
$this->app->Tpl->Parse('PAGE', "ticketregeln_edit.tpl");
|
||||
|
||||
@@ -1711,6 +1711,13 @@ $this->app->Tpl->Add('TODOFORUSER',"<tr><td width=\"90%\">".$tmp[$i]['aufgabe'].
|
||||
$this->app->Tpl->Set('STARTSEITE', $settings['startseite']);
|
||||
$this->app->Tpl->Set('DEFAULTCOLOR', $settings['defaultcolor']);
|
||||
$this->app->Tpl->Set('SPRACHEBEVORZUGEN', $this->languageSelectOptions($settings['sprachebevorzugen']));
|
||||
|
||||
/** @var \Xentral\Components\I18n\Localization $localization */
|
||||
if($localization=$this->app->Container->get('Localization')) {
|
||||
$this->app->Tpl->Set('LOCALE', $localization->getLocale());
|
||||
} else {
|
||||
$this->app->Tpl->Set('LOCALE', 'Fehler!');
|
||||
}
|
||||
|
||||
if($settings['chat_popup']){
|
||||
$this->app->Tpl->Set('CHAT_POPUP', ' checked="checked" ');
|
||||
|
||||
@@ -195,7 +195,7 @@ background-color:red;
|
||||
/*
|
||||
function fillArtikel(id,menge)
|
||||
{
|
||||
if(menge < 1)
|
||||
if(menge <= 0)
|
||||
menge=1;
|
||||
strSource = "./index.php";
|
||||
strData = "module=artikel&action=ajaxwerte&id="+id+"&smodule=[MODULE]&sid=[KID]&menge="+menge;
|
||||
@@ -209,7 +209,7 @@ function fillArtikel(id,menge)
|
||||
|
||||
function fillArtikel(id,menge)
|
||||
{
|
||||
if(menge < 1)
|
||||
if(menge <= 0)
|
||||
menge=1;
|
||||
|
||||
var tmp = id.split(' ');
|
||||
@@ -250,7 +250,7 @@ function fillArtikel(id,menge)
|
||||
|
||||
function fillArtikelBestellung(id,menge)
|
||||
{
|
||||
if(menge < 1)
|
||||
if(menge <= 0)
|
||||
menge=1;
|
||||
|
||||
var vpe = 1;
|
||||
@@ -297,7 +297,7 @@ function fillArtikelBestellung(id,menge)
|
||||
|
||||
function fillArtikelProduktion(id,menge)
|
||||
{
|
||||
if(menge < 1)
|
||||
if(menge <= 0)
|
||||
menge=1;
|
||||
|
||||
var tmp = id.split(' ');
|
||||
@@ -325,7 +325,7 @@ function fillArtikelLieferschein(id,menge)
|
||||
id = tmp[0];
|
||||
//wenn ab Menge dabei steht
|
||||
|
||||
if(menge < 1)
|
||||
if(menge <= 0)
|
||||
menge=1;
|
||||
strSource = "./index.php";
|
||||
|
||||
@@ -343,7 +343,7 @@ function fillArtikelLieferschein(id,menge)
|
||||
|
||||
function fillArtikelInventur(id,menge)
|
||||
{
|
||||
if(menge < 1)
|
||||
if(menge <= 0)
|
||||
menge=1;
|
||||
|
||||
var tmp = id.split(' ');
|
||||
|
||||
@@ -149,11 +149,12 @@ $(document).ready(function(){
|
||||
<tr valign="top"><td>{|Liefersperre Grund|}:</td><td>[LIEFERSPERREGRUND][MSGLIEFERSPERREGRUND]</td></tr>
|
||||
<tr><td colspan="2"><br></td></tr>
|
||||
<tr><td>{|Sprache für Belege|}:</td><td>[SPRACHE][MSGSPRACHE]</td></tr>
|
||||
<tr><td>{|Sprache und Region|}:</td><td>[LOCALE][MSGLOCALE]</td></tr>
|
||||
|
||||
<tr><td>{|Kundenfreigabe|}:</td><td>[KUNDENFREIGABE][MSGKUNDENFREIGABE] </td></tr>
|
||||
<tr><td colspan="2"><br></td></tr>
|
||||
<tr><td>{|Folgebestätigungsperre|}:</td><td>[FOLGEBESTAETIGUNGSPERRE][MSGFOLGEBESTAETIGUNGSPERRE]</td></tr>
|
||||
<tr><td>{|Trackingmailsperre|}:</td><td>[TRACKINGSPERRE][MSGTRACKINGSPERRE]</td></tr>
|
||||
<tr><td>{|Folgebestätigungsperre|}:</td><td>[FOLGEBESTAETIGUNGSPERRE][MSGFOLGEBESTAETIGUNGSPERRE]</td></tr>
|
||||
<tr><td>{|Trackingmailsperre|}:</td><td>[TRACKINGSPERRE][MSGTRACKINGSPERRE]</td></tr>
|
||||
<tr><td>{|Marketingsperre|}:</td><td>[MARKETINGSPERRE][MSGMARKETINGSPERRE]</td></tr>
|
||||
<tr><td>{|Lead|}:</td><td>[LEAD][MSGLEAD]</td></tr>
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
|
||||
include ("_gen/widget.gen.adresse.php");
|
||||
|
||||
class WidgetAdresse extends WidgetGenAdresse
|
||||
@@ -284,7 +287,20 @@ class WidgetAdresse extends WidgetGenAdresse
|
||||
$field = new HTMLSelect("sprache",0,"sprache",false,false,"1");
|
||||
$field->AddOptionsSimpleArray($sprachenOptions);
|
||||
$this->form->NewField($field);
|
||||
|
||||
|
||||
/** @var \Xentral\Components\I18n\Localization $localization */
|
||||
$localization=$this->app->Container->get('Localization');
|
||||
/** @var Database $db */
|
||||
$db = $this->app->Container->get('Database');
|
||||
$adresse = $db->fetchRow(
|
||||
$db->select()->cols(['*'])->from('adresse')->where('id=:id'),
|
||||
['id' => $id]
|
||||
);
|
||||
$localization=$localization->withAdresse($adresse);
|
||||
$field = new HTMLInput("locale","text",$localization->getLocale(), size: '10', disabled: 'disabled');
|
||||
$this->form->NewField($field);
|
||||
|
||||
|
||||
$field = new HTMLInput("vorname","hidden","");
|
||||
$this->form->NewField($field);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user