mirror of
https://github.com/kevachat/webapp.git
synced 2025-09-11 05:42:21 +00:00
351 lines
9.6 KiB
PHP
351 lines
9.6 KiB
PHP
<?php
|
|
|
|
namespace App\Twig;
|
|
|
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
use Twig\Extension\AbstractExtension;
|
|
use Twig\TwigFilter;
|
|
|
|
class AppExtension extends AbstractExtension
|
|
{
|
|
protected TranslatorInterface $translator;
|
|
|
|
public function __construct(
|
|
ContainerInterface $container,
|
|
TranslatorInterface $translator
|
|
)
|
|
{
|
|
$this->container = $container;
|
|
$this->translator = $translator;
|
|
}
|
|
|
|
public function getFilters()
|
|
{
|
|
return
|
|
[
|
|
new TwigFilter(
|
|
'format_ago',
|
|
[
|
|
$this,
|
|
'formatAgo'
|
|
]
|
|
),
|
|
new TwigFilter(
|
|
'format_bytes',
|
|
[
|
|
$this,
|
|
'formatBytes'
|
|
]
|
|
),
|
|
new TwigFilter(
|
|
'message_to_markdown',
|
|
[
|
|
$this,
|
|
'messageToMarkdown'
|
|
]
|
|
),
|
|
new TwigFilter(
|
|
'url_to_markdown',
|
|
[
|
|
$this,
|
|
'urlToMarkdown'
|
|
]
|
|
),
|
|
new TwigFilter(
|
|
'mention_to_markdown',
|
|
[
|
|
$this,
|
|
'mentionToMarkdown'
|
|
]
|
|
),
|
|
new TwigFilter(
|
|
'namespace_to_markdown',
|
|
[
|
|
$this,
|
|
'namespaceToMarkdown'
|
|
]
|
|
),
|
|
new TwigFilter(
|
|
'keva_namespace_value',
|
|
[
|
|
$this,
|
|
'kevaNamespaceValue'
|
|
]
|
|
)
|
|
];
|
|
}
|
|
|
|
public function formatAgo(
|
|
int $time,
|
|
): string
|
|
{
|
|
$diff = time() - $time;
|
|
|
|
if ($diff < 1)
|
|
{
|
|
return $this->translator->trans('now');
|
|
}
|
|
|
|
$values =
|
|
[
|
|
365 * 24 * 60 * 60 =>
|
|
[
|
|
$this->translator->trans('year ago'),
|
|
$this->translator->trans('years ago'),
|
|
$this->translator->trans(' years ago')
|
|
],
|
|
30 * 24 * 60 * 60 =>
|
|
[
|
|
$this->translator->trans('month ago'),
|
|
$this->translator->trans('months ago'),
|
|
$this->translator->trans(' months ago')
|
|
],
|
|
24 * 60 * 60 =>
|
|
[
|
|
$this->translator->trans('day ago'),
|
|
$this->translator->trans('days ago'),
|
|
$this->translator->trans(' days ago')
|
|
],
|
|
60 * 60 =>
|
|
[
|
|
$this->translator->trans('hour ago'),
|
|
$this->translator->trans('hours ago'),
|
|
$this->translator->trans(' hours ago')
|
|
],
|
|
60 =>
|
|
[
|
|
$this->translator->trans('minute ago'),
|
|
$this->translator->trans('minutes ago'),
|
|
$this->translator->trans(' minutes ago')
|
|
],
|
|
1 =>
|
|
[
|
|
$this->translator->trans('second ago'),
|
|
$this->translator->trans('seconds ago'),
|
|
$this->translator->trans(' seconds ago')
|
|
]
|
|
];
|
|
|
|
foreach ($values as $key => $value)
|
|
{
|
|
$result = $diff / $key;
|
|
|
|
if ($result >= 1)
|
|
{
|
|
$round = round($result);
|
|
|
|
return sprintf(
|
|
'%s %s',
|
|
$round,
|
|
$this->_plural(
|
|
$round,
|
|
$value
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function formatBytes(
|
|
int $bytes,
|
|
int $precision = 2
|
|
): string
|
|
{
|
|
$size = [
|
|
$this->translator->trans('B'),
|
|
$this->translator->trans('Kb'),
|
|
$this->translator->trans('Mb'),
|
|
$this->translator->trans('Gb'),
|
|
$this->translator->trans('Tb'),
|
|
$this->translator->trans('Pb'),
|
|
$this->translator->trans('Eb'),
|
|
$this->translator->trans('Zb'),
|
|
$this->translator->trans('Yb')
|
|
];
|
|
|
|
$factor = floor((strlen($bytes) - 1) / 3);
|
|
|
|
return sprintf("%.{$precision}f", $bytes / pow(1024, $factor)) . ' ' . @$size[$factor];
|
|
}
|
|
|
|
public function messageToMarkdown(
|
|
string $text
|
|
): string
|
|
{
|
|
$text = $this->urlToMarkdown(
|
|
$text
|
|
);
|
|
|
|
$text = $this->mentionToMarkdown(
|
|
$text
|
|
);
|
|
|
|
$text = $this->namespaceToMarkdown(
|
|
$text
|
|
);
|
|
|
|
return $text;
|
|
}
|
|
|
|
public function urlToMarkdown(
|
|
string $text
|
|
): string
|
|
{
|
|
return preg_replace(
|
|
'/(https?:\/\/(?:www\.)?[^\(\s\)]+)/i',
|
|
'[$1]($1)',
|
|
$text
|
|
);
|
|
}
|
|
|
|
public function mentionToMarkdown(
|
|
string $text
|
|
): string
|
|
{
|
|
return preg_replace(
|
|
'/@([A-f0-9]{64})/i',
|
|
'[@$1](#$1)',
|
|
$text
|
|
);
|
|
}
|
|
|
|
public function namespaceToMarkdown(
|
|
string $text
|
|
): string
|
|
{
|
|
// Search not filtered namespaces
|
|
if (preg_match_all('/(^|\s)(N[A-z0-9]{33})/', $text, $matches))
|
|
{
|
|
if (empty($matches[2]))
|
|
{
|
|
return $text;
|
|
}
|
|
|
|
foreach ($matches[2] as $namespace)
|
|
{
|
|
// Replace with _CLITOR_IS_ value
|
|
if ($meta = $this->_clitor($namespace))
|
|
{
|
|
$text = str_replace(
|
|
$namespace,
|
|
sprintf(
|
|
'[%s](%s) (%s)',
|
|
$meta['file']['name'],
|
|
$this->container->get('router')->generate(
|
|
'view_raw',
|
|
[
|
|
'namespace' => $namespace
|
|
]
|
|
),
|
|
$this->formatBytes(
|
|
$meta['file']['size']
|
|
)
|
|
),
|
|
$text
|
|
);
|
|
}
|
|
|
|
// Replace with _KEVA_NS_ value
|
|
else
|
|
{
|
|
$text = str_replace(
|
|
$namespace,
|
|
sprintf(
|
|
'[%s](%s)',
|
|
$this->kevaNamespaceValue(
|
|
$namespace
|
|
),
|
|
$this->container->get('router')->generate(
|
|
'room_namespace',
|
|
[
|
|
'namespace' => $namespace,
|
|
'_fragment' => 'latest'
|
|
]
|
|
)
|
|
),
|
|
$text
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $text;
|
|
}
|
|
|
|
public function kevaNamespaceValue(
|
|
string $namespace
|
|
): string
|
|
{
|
|
// Validate namespace supported to continue
|
|
if (!preg_match('/^N[A-z0-9]{33}$/', $namespace))
|
|
{
|
|
return $namespace;
|
|
}
|
|
|
|
// Connect kevacoin
|
|
$client = new \Kevachat\Kevacoin\Client(
|
|
$this->container->getParameter('app.kevacoin.protocol'),
|
|
$this->container->getParameter('app.kevacoin.host'),
|
|
$this->container->getParameter('app.kevacoin.port'),
|
|
$this->container->getParameter('app.kevacoin.username'),
|
|
$this->container->getParameter('app.kevacoin.password')
|
|
);
|
|
|
|
// Extract value from wallet
|
|
if ($result = $client->kevaGet($namespace, '_KEVA_NS_'))
|
|
{
|
|
return (string) $result['value'];
|
|
}
|
|
|
|
// Return original hash if no success
|
|
return $namespace;
|
|
}
|
|
|
|
private function _clitor(
|
|
string $namespace
|
|
): ?array
|
|
{
|
|
// Validate namespace supported to continue
|
|
if (preg_match('/^N[A-z0-9]{33}$/', $namespace))
|
|
{
|
|
// Connect kevacoin
|
|
$client = new \Kevachat\Kevacoin\Client(
|
|
$this->container->getParameter('app.kevacoin.protocol'),
|
|
$this->container->getParameter('app.kevacoin.host'),
|
|
$this->container->getParameter('app.kevacoin.port'),
|
|
$this->container->getParameter('app.kevacoin.username'),
|
|
$this->container->getParameter('app.kevacoin.password')
|
|
);
|
|
|
|
// Get meta data by namespace
|
|
if ($meta = $client->kevaGet($namespace, '_CLITOR_IS_'))
|
|
{
|
|
$reader = new \ClitorIsProtocol\Kevacoin\Reader(
|
|
$meta['value']
|
|
);
|
|
|
|
if ($reader->valid())
|
|
{
|
|
return
|
|
[
|
|
'file' =>
|
|
[
|
|
'name' => $reader->fileName() ? $reader->fileName() : $namespace,
|
|
'size' => (int) $reader->fileSize(),
|
|
]
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function _plural(int $number, array $texts)
|
|
{
|
|
$cases = [2, 0, 1, 1, 1, 2];
|
|
|
|
return $texts[(($number % 100) > 4 && ($number % 100) < 20) ? 2 : $cases[min($number % 10, 5)]];
|
|
}
|
|
} |