Implemented Telegram Chat Peers
This commit is contained in:
parent
1728d607d7
commit
8c5237ff7f
10 changed files with 703 additions and 79 deletions
72
.idea/inspectionProfiles/Project_Default.xml
generated
72
.idea/inspectionProfiles/Project_Default.xml
generated
|
@ -1,6 +1,78 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<Languages>
|
||||
<language minSize="111" name="PHP" />
|
||||
</Languages>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ForgottenDebugOutputInspection" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="configuration">
|
||||
<list>
|
||||
<option value="\Codeception\Util\Debug::debug" />
|
||||
<option value="\Codeception\Util\Debug::pause" />
|
||||
<option value="\Doctrine\Common\Util\Debug::dump" />
|
||||
<option value="\Doctrine\Common\Util\Debug::export" />
|
||||
<option value="\Illuminate\Support\Debug\Dumper::dump" />
|
||||
<option value="\Symfony\Component\Debug\Debug::enable" />
|
||||
<option value="\Symfony\Component\Debug\DebugClassLoader::enable" />
|
||||
<option value="\Symfony\Component\Debug\ErrorHandler::register" />
|
||||
<option value="\Symfony\Component\Debug\ExceptionHandler::register" />
|
||||
<option value="\TYPO3\CMS\Core\Utility\DebugUtility::debug" />
|
||||
<option value="\Zend\Debug\Debug::dump" />
|
||||
<option value="\Zend\Di\Display\Console::export" />
|
||||
<option value="dd" />
|
||||
<option value="debug_print_backtrace" />
|
||||
<option value="debug_zval_dump" />
|
||||
<option value="dpm" />
|
||||
<option value="dpq" />
|
||||
<option value="dsm" />
|
||||
<option value="dump" />
|
||||
<option value="dvm" />
|
||||
<option value="error_log" />
|
||||
<option value="kpr" />
|
||||
<option value="phpinfo" />
|
||||
<option value="print_r" />
|
||||
<option value="var_dump" />
|
||||
<option value="var_export" />
|
||||
<option value="wp_die" />
|
||||
<option value="xdebug_break" />
|
||||
<option value="xdebug_call_class" />
|
||||
<option value="xdebug_call_file" />
|
||||
<option value="xdebug_call_function" />
|
||||
<option value="xdebug_call_line" />
|
||||
<option value="xdebug_code_coverage_started" />
|
||||
<option value="xdebug_debug_zval" />
|
||||
<option value="xdebug_debug_zval_stdout" />
|
||||
<option value="xdebug_dump_superglobals" />
|
||||
<option value="xdebug_enable" />
|
||||
<option value="xdebug_get_code_coverage" />
|
||||
<option value="xdebug_get_collected_errors" />
|
||||
<option value="xdebug_get_declared_vars" />
|
||||
<option value="xdebug_get_function_stack" />
|
||||
<option value="xdebug_get_headers" />
|
||||
<option value="xdebug_get_monitored_functions" />
|
||||
<option value="xdebug_get_profiler_filename" />
|
||||
<option value="xdebug_get_stack_depth" />
|
||||
<option value="xdebug_get_tracefile_name" />
|
||||
<option value="xdebug_is_enabled" />
|
||||
<option value="xdebug_memory_usage" />
|
||||
<option value="xdebug_peak_memory_usage" />
|
||||
<option value="xdebug_print_function_stack" />
|
||||
<option value="xdebug_start_code_coverage" />
|
||||
<option value="xdebug_start_error_collection" />
|
||||
<option value="xdebug_start_function_monitor" />
|
||||
<option value="xdebug_start_trace" />
|
||||
<option value="xdebug_stop_code_coverage" />
|
||||
<option value="xdebug_stop_error_collection" />
|
||||
<option value="xdebug_stop_function_monitor" />
|
||||
<option value="xdebug_stop_trace" />
|
||||
<option value="xdebug_time_index" />
|
||||
<option value="xdebug_var_dump" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="migratedIntoUserSpace" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="IncorrectHttpHeaderInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="customHeaders">
|
||||
<set>
|
||||
|
|
|
@ -320,6 +320,11 @@
|
|||
*/
|
||||
public static function getObjectCacheEnabled(string $name): bool
|
||||
{
|
||||
if(self::isCacheSystemEnabled() === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)self::getConfiguration()['cache_system']['cache'][sprintf('%s_enabled', $name)];
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace FederationLib\Interfaces;
|
||||
|
||||
use FederationLib\Exceptions\Standard\InvalidPeerMetadataException;
|
||||
use FederationLib\Objects\ParsedFederatedAddress;
|
||||
|
||||
interface PeerMetadataInterface extends SerializableObjectInterface
|
||||
{
|
||||
|
@ -34,9 +35,9 @@
|
|||
/**
|
||||
* Returns the calculated standard federated address of the peer
|
||||
*
|
||||
* @return string
|
||||
* @return ParsedFederatedAddress
|
||||
*/
|
||||
public function getFederatedAddress(): string;
|
||||
public function getFederatedAddress(): ParsedFederatedAddress;
|
||||
|
||||
/**
|
||||
* Sets the timestamp of when the peer record was last updated (this is usually used internally)
|
||||
|
@ -56,10 +57,10 @@
|
|||
/**
|
||||
* Sets the Client's UUID that last updated the peer record (this is usually used internally)
|
||||
*
|
||||
* @param string|null $client
|
||||
* @param string|null $client_uuid
|
||||
* @return void
|
||||
*/
|
||||
public function setUpdatedClient(?string $client): void;
|
||||
public function setUpdatedClient(?string $client_uuid): void;
|
||||
|
||||
/**
|
||||
* Returns the Client's UUID that last updated the peer record
|
||||
|
|
|
@ -13,26 +13,26 @@
|
|||
* data from the given $client_uuid
|
||||
*
|
||||
* @param ClientRecord|string $client_uuid
|
||||
* @param TelegramUserMetadata $telegram_user_metadata
|
||||
* @param PeerMetadataInterface $peer_metadata
|
||||
* @return string
|
||||
*/
|
||||
public function syncMetadata(ClientRecord|string $client_uuid, TelegramUserMetadata $telegram_user_metadata): string;
|
||||
public function syncMetadata(ClientRecord|string $client_uuid, PeerMetadataInterface $peer_metadata): string;
|
||||
|
||||
/**
|
||||
* Registers the metadata of the given federated address, this will ignore raw metadata & use data from the
|
||||
* given $client_uuid
|
||||
*
|
||||
* @param ClientRecord|string $client_uuid
|
||||
* @param TelegramUserMetadata $telegram_user_metadata
|
||||
* @param PeerMetadataInterface $peer_metadata
|
||||
* @return string
|
||||
*/
|
||||
public function registerMetadata(ClientRecord|string $client_uuid, TelegramUserMetadata $telegram_user_metadata): string;
|
||||
public function registerMetadata(ClientRecord|string $client_uuid, PeerMetadataInterface $peer_metadata): string;
|
||||
|
||||
/**
|
||||
* Returns the metadata of the given federated address, this returns the full raw metadata
|
||||
*
|
||||
* @param ParsedFederatedAddress|string $federated_address
|
||||
* @return TelegramUserMetadata
|
||||
* @return PeerMetadataInterface
|
||||
*/
|
||||
public function getMetadata(ParsedFederatedAddress|string $federated_address): TelegramUserMetadata;
|
||||
public function getMetadata(ParsedFederatedAddress|string $federated_address): PeerMetadataInterface;
|
||||
}
|
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
|
||||
namespace FederationLib\Managers\MetadataManagers;
|
||||
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Exception;
|
||||
use FederationLib\Classes\Configuration;
|
||||
use FederationLib\Classes\Database;
|
||||
use FederationLib\Classes\Utilities;
|
||||
use FederationLib\Enums\DatabaseTables;
|
||||
use FederationLib\Enums\Misc;
|
||||
use FederationLib\Exceptions\DatabaseException;
|
||||
use FederationLib\Exceptions\Standard\InvalidPeerMetadataException;
|
||||
use FederationLib\Exceptions\Standard\PeerMetadataNotFoundException;
|
||||
use FederationLib\Interfaces\PeerMetadataInterface;
|
||||
use FederationLib\Interfaces\PeerMetadataManagerInterface;
|
||||
use FederationLib\Managers\RedisConnectionManager;
|
||||
use FederationLib\Objects\ClientRecord;
|
||||
use FederationLib\Objects\ParsedFederatedAddress;
|
||||
use FederationLib\Objects\Standard\PeerMetadata\TelegramChatMetadata;
|
||||
use LogLib\Log;
|
||||
|
||||
class TelegramChatManager implements PeerMetadataManagerInterface
|
||||
{
|
||||
/**
|
||||
* Syncs the metadata into the database
|
||||
*
|
||||
* @param ClientRecord|string $client_uuid
|
||||
* @param PeerMetadataInterface $peer_metadata
|
||||
* @return string
|
||||
* @throws DatabaseException
|
||||
* @throws InvalidPeerMetadataException
|
||||
*/
|
||||
public function syncMetadata(ClientRecord|string $client_uuid, PeerMetadataInterface $peer_metadata): string
|
||||
{
|
||||
if($client_uuid instanceof ClientRecord)
|
||||
{
|
||||
$client_uuid = $client_uuid->getUuid();
|
||||
}
|
||||
|
||||
$peer_metadata->validate();
|
||||
$cache_key = sprintf('telegram_chat_metadata:%s', $peer_metadata->getFederatedAddress());
|
||||
$redis_client = null;
|
||||
|
||||
if(Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
{
|
||||
try
|
||||
{
|
||||
$redis_client = RedisConnectionManager::getConnectionFromConfig('peer_objects');
|
||||
|
||||
if($redis_client->exists($cache_key))
|
||||
{
|
||||
$redis_client->del($cache_key);
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Log::warning(Misc::FEDERATIONLIB, sprintf('There was an error with the cache system while tyring to sync peer metadata with the Redis server: %s', $e->getMessage()), $e);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$old_metadata = $this->getMetadata($peer_metadata->getFederatedAddress());
|
||||
}
|
||||
catch(PeerMetadataNotFoundException $e)
|
||||
{
|
||||
unset($e);
|
||||
|
||||
// If it doesn't exist, we create it instead of updating it
|
||||
return $this->registerMetadata($client_uuid, $peer_metadata);
|
||||
}
|
||||
|
||||
// Take the old metadata and get the differences
|
||||
$differences = Utilities::metadataDifferences($old_metadata, $peer_metadata);
|
||||
|
||||
try
|
||||
{
|
||||
// If there are no differences, then we don't need to update the database
|
||||
if(count($differences) === 0)
|
||||
{
|
||||
if($redis_client !== null && Configuration::getObjectCacheTtl('peer_objects') > 0)
|
||||
{
|
||||
// Reset the TTL since we just accessed it
|
||||
$redis_client->expire($cache_key, Configuration::getObjectCacheTtl('peer_objects'));
|
||||
}
|
||||
|
||||
return $peer_metadata->getFederatedAddress();
|
||||
}
|
||||
|
||||
$qb = Database::getConnection()->createQueryBuilder();
|
||||
$qb->update(DatabaseTables::PEERS_TELEGRAM_CHAT);
|
||||
$qb->where('federated_address = :federated_address');
|
||||
$qb->setParameter('federated_address', $peer_metadata->getFederatedAddress());
|
||||
$qb->set('updated_timestamp', $qb->createNamedParameter(time(), ParameterType::INTEGER));
|
||||
$qb->set('updated_client', $qb->createNamedParameter($client_uuid));
|
||||
$qb->setMaxResults(1);
|
||||
|
||||
foreach($differences as $key => $value)
|
||||
{
|
||||
$qb->set($key, $qb->createNamedParameter($value));
|
||||
}
|
||||
|
||||
$qb->executeQuery();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new DatabaseException(sprintf('There was a database error while trying to sync peer metadata: %s', $e->getMessage()), $e);
|
||||
}
|
||||
|
||||
if($redis_client !== null && count($differences) > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach($differences as $key => $value)
|
||||
{
|
||||
$redis_client->hSet($cache_key, $key, $value);
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Log::warning(Misc::FEDERATIONLIB, sprintf('There was an error with the cache system while tyring to sync peer metadata with the Redis server: %s', $e->getMessage()), $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $peer_metadata->getFederatedAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the metadata into the database
|
||||
*
|
||||
* @param ClientRecord|string $client_uuid
|
||||
* @param PeerMetadataInterface $peer_metadata
|
||||
* @return string
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function registerMetadata(ClientRecord|string $client_uuid, PeerMetadataInterface $peer_metadata): string
|
||||
{
|
||||
if($client_uuid instanceof ClientRecord)
|
||||
{
|
||||
$client_uuid = $client_uuid->getUuid();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$peer_metadata->validate();
|
||||
$qb = Database::getConnection()->createQueryBuilder();
|
||||
$qb->insert(DatabaseTables::PEERS_TELEGRAM_CHAT);
|
||||
|
||||
$qb->setValue('federated_address', $qb->createNamedParameter($peer_metadata->getFederatedAddress()));
|
||||
$qb->setValue('updated_timestamp', $qb->createNamedParameter(time(), ParameterType::INTEGER));
|
||||
$qb->setValue('updated_client', $qb->createNamedParameter($client_uuid));
|
||||
|
||||
foreach($peer_metadata->toArray() as $key => $value)
|
||||
{
|
||||
switch(gettype($value))
|
||||
{
|
||||
case 'array':
|
||||
$qb->setValue($key, $qb->createNamedParameter(implode(',', $value)));
|
||||
break;
|
||||
case 'NULL':
|
||||
$qb->setValue($key, $qb->createNamedParameter(null, ParameterType::NULL));
|
||||
break;
|
||||
case 'boolean':
|
||||
$qb->setValue($key, $qb->createNamedParameter((int)$value, ParameterType::INTEGER));
|
||||
break;
|
||||
case 'integer':
|
||||
$qb->setValue($key, $qb->createNamedParameter($value, ParameterType::INTEGER));
|
||||
break;
|
||||
|
||||
default:
|
||||
$qb->setValue($key, $qb->createNamedParameter($value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$qb->executeQuery();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new DatabaseException(sprintf('There was a database error while trying to register peer metadata: %s', $e->getMessage()), $e);
|
||||
}
|
||||
|
||||
return $peer_metadata->getFederatedAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|ParsedFederatedAddress $federated_address
|
||||
* @return PeerMetadataInterface
|
||||
* @throws DatabaseException
|
||||
* @throws PeerMetadataNotFoundException
|
||||
*/
|
||||
public function getMetadata(string|ParsedFederatedAddress $federated_address): PeerMetadataInterface
|
||||
{
|
||||
if(Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
{
|
||||
try
|
||||
{
|
||||
$redis = RedisConnectionManager::getConnectionFromConfig('peer_objects');
|
||||
$key = sprintf('telegram_chat_metadata:%s', $federated_address->getAddress());
|
||||
|
||||
if($redis->exists($key))
|
||||
{
|
||||
$telegram_chat_metadata = TelegramChatMetadata::fromArray($redis->hGetAll($key), true);
|
||||
|
||||
if(Configuration::getObjectCacheTTL('peer_objects') > 0)
|
||||
{
|
||||
$redis->expire($key, Configuration::getObjectCacheTTL('peer_objects'));
|
||||
}
|
||||
|
||||
Log::debug(Misc::FEDERATIONLIB, sprintf('Loaded peer metadata object %s from cache', $federated_address->getAddress()));
|
||||
return $telegram_chat_metadata;
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Log::warning(Misc::FEDERATIONLIB, sprintf('Failed to load peer metadata object %s from cache: %s', $federated_address->getAddress(), $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
$qb = Database::getConnection()->createQueryBuilder();
|
||||
$qb->select(
|
||||
'id',
|
||||
'type',
|
||||
'title',
|
||||
'username',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'is_forum',
|
||||
'updated_timestamp',
|
||||
'updated_client'
|
||||
);
|
||||
$qb->from(DatabaseTables::PEERS_TELEGRAM_CHAT);
|
||||
$qb->where('federated_address = :federated_address');
|
||||
$qb->setParameter('federated_address', $federated_address->getAddress());
|
||||
$qb->setMaxResults(1);
|
||||
|
||||
try
|
||||
{
|
||||
$result = $qb->executeQuery();
|
||||
|
||||
if($result->rowCount() === 0)
|
||||
{
|
||||
throw new PeerMetadataNotFoundException(sprintf('PeerRecord metadata not found for federated address %s', $federated_address->getAddress()));
|
||||
}
|
||||
|
||||
$telegram_chat_metadata = TelegramChatMetadata::fromArray($result->fetchAssociative(), true);
|
||||
}
|
||||
catch(PeerMetadataNotFoundException $e)
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new DatabaseException(sprintf('Failed to get peer metadata for federated address %s', $federated_address->getAddress()), $e);
|
||||
}
|
||||
|
||||
if(Configuration::isCacheSystemEnabled() && Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
{
|
||||
try
|
||||
{
|
||||
$redis = RedisConnectionManager::getConnectionFromConfig('peer_objects');
|
||||
|
||||
$key = sprintf('telegram_chat_metadata:%s', $federated_address);
|
||||
$redis->hMSet($key, $telegram_chat_metadata->toArray());
|
||||
|
||||
if(Configuration::getObjectCacheTTL('peer_objects') > 0)
|
||||
{
|
||||
$redis->expire($key, Configuration::getObjectCacheTTL('peer_objects'));
|
||||
}
|
||||
|
||||
Log::debug(Misc::FEDERATIONLIB, sprintf('Cached peer metadata object %s', $federated_address->getAddress()));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Log::warning(Misc::FEDERATIONLIB, sprintf('Failed to cache peer metadata object %s: %s', $federated_address->getAddress(), $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
return $telegram_chat_metadata;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
use FederationLib\Exceptions\DatabaseException;
|
||||
use FederationLib\Exceptions\Standard\InvalidPeerMetadataException;
|
||||
use FederationLib\Exceptions\Standard\PeerMetadataNotFoundException;
|
||||
use FederationLib\Interfaces\PeerMetadataInterface;
|
||||
use FederationLib\Interfaces\PeerMetadataManagerInterface;
|
||||
use FederationLib\Managers\RedisConnectionManager;
|
||||
use FederationLib\Objects\ClientRecord;
|
||||
|
@ -23,23 +24,23 @@
|
|||
{
|
||||
/**
|
||||
* @param ClientRecord|string $client_uuid
|
||||
* @param TelegramUserMetadata $telegram_user_metadata
|
||||
* @param TelegramUserMetadata $peer_metadata
|
||||
* @return string
|
||||
* @throws DatabaseException
|
||||
* @throws InvalidPeerMetadataException
|
||||
*/
|
||||
public function syncMetadata(ClientRecord|string $client_uuid, TelegramUserMetadata $telegram_user_metadata): string
|
||||
public function syncMetadata(ClientRecord|string $client_uuid, PeerMetadataInterface $peer_metadata): string
|
||||
{
|
||||
if($client_uuid instanceof ClientRecord)
|
||||
{
|
||||
$client_uuid = $client_uuid->getUuid();
|
||||
}
|
||||
|
||||
$telegram_user_metadata->validate();
|
||||
$cache_key = sprintf('telegram_user_metadata:%s', $telegram_user_metadata->getFederatedAddress());
|
||||
$peer_metadata->validate();
|
||||
$cache_key = sprintf('telegram_user_metadata:%s', $peer_metadata->getFederatedAddress());
|
||||
$redis_client = null;
|
||||
|
||||
if(Configuration::isCacheSystemEnabled() && Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
if(Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -58,18 +59,18 @@
|
|||
|
||||
try
|
||||
{
|
||||
$old_metadata = $this->getMetadata($telegram_user_metadata->getFederatedAddress());
|
||||
$old_metadata = $this->getMetadata($peer_metadata->getFederatedAddress());
|
||||
}
|
||||
catch(PeerMetadataNotFoundException $e)
|
||||
{
|
||||
unset($e);
|
||||
|
||||
// If it doesn't exist, we create it instead of updating it
|
||||
return $this->registerMetadata($client_uuid, $telegram_user_metadata);
|
||||
return $this->registerMetadata($client_uuid, $peer_metadata);
|
||||
}
|
||||
|
||||
// Take the old metadata and get the differences
|
||||
$differences = Utilities::metadataDifferences($old_metadata, $telegram_user_metadata);
|
||||
$differences = Utilities::metadataDifferences($old_metadata, $peer_metadata);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -82,13 +83,13 @@
|
|||
$redis_client->expire($cache_key, Configuration::getObjectCacheTtl('peer_objects'));
|
||||
}
|
||||
|
||||
return $telegram_user_metadata->getFederatedAddress();
|
||||
return $peer_metadata->getFederatedAddress();
|
||||
}
|
||||
|
||||
$qb = Database::getConnection()->createQueryBuilder();
|
||||
$qb->update(DatabaseTables::PEERS_TELEGRAM_USER);
|
||||
$qb->where('federated_address = :federated_address');
|
||||
$qb->setParameter('federated_address', $telegram_user_metadata->getFederatedAddress());
|
||||
$qb->setParameter('federated_address', $peer_metadata->getFederatedAddress());
|
||||
$qb->set('updated_timestamp', $qb->createNamedParameter(time(), ParameterType::INTEGER));
|
||||
$qb->set('updated_client', $qb->createNamedParameter($client_uuid));
|
||||
$qb->setMaxResults(1);
|
||||
|
@ -120,18 +121,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
return $telegram_user_metadata->getFederatedAddress();
|
||||
return $peer_metadata->getFederatedAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the client's metadata with the database
|
||||
*
|
||||
* @param ClientRecord|string $client_uuid
|
||||
* @param TelegramUserMetadata $telegram_user_metadata
|
||||
* @param TelegramUserMetadata $peer_metadata
|
||||
* @return string
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function registerMetadata(ClientRecord|string $client_uuid, TelegramUserMetadata $telegram_user_metadata): string
|
||||
public function registerMetadata(ClientRecord|string $client_uuid, PeerMetadataInterface $peer_metadata): string
|
||||
{
|
||||
if($client_uuid instanceof ClientRecord)
|
||||
{
|
||||
|
@ -140,15 +141,15 @@
|
|||
|
||||
try
|
||||
{
|
||||
$telegram_user_metadata->validate();
|
||||
$peer_metadata->validate();
|
||||
$qb = Database::getConnection()->createQueryBuilder();
|
||||
$qb->insert(DatabaseTables::PEERS_TELEGRAM_USER);
|
||||
|
||||
$qb->setValue('federated_address', $qb->createNamedParameter($telegram_user_metadata->getFederatedAddress()));
|
||||
$qb->setValue('federated_address', $qb->createNamedParameter($peer_metadata->getFederatedAddress()));
|
||||
$qb->setValue('updated_timestamp', $qb->createNamedParameter(time(), ParameterType::INTEGER));
|
||||
$qb->setValue('updated_client', $qb->createNamedParameter($client_uuid));
|
||||
|
||||
foreach($telegram_user_metadata->toArray() as $key => $value)
|
||||
foreach($peer_metadata->toArray() as $key => $value)
|
||||
{
|
||||
switch(gettype($value))
|
||||
{
|
||||
|
@ -178,7 +179,7 @@
|
|||
throw new DatabaseException(sprintf('There was a database error while trying to register peer metadata: %s', $e->getMessage()), $e);
|
||||
}
|
||||
|
||||
return $telegram_user_metadata->getFederatedAddress();
|
||||
return $peer_metadata->getFederatedAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,7 +190,7 @@
|
|||
*/
|
||||
public function getMetadata(ParsedFederatedAddress|string $federated_address): TelegramUserMetadata
|
||||
{
|
||||
if(Configuration::isCacheSystemEnabled() && Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
if(Configuration::getObjectCacheEnabled('peer_objects'))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -70,11 +70,9 @@
|
|||
* @param ParsedFederatedAddress|string $federated_address
|
||||
* @param array $peer_metadata
|
||||
* @return void
|
||||
* @throws CacheConnectionException
|
||||
* @throws DatabaseException
|
||||
* @throws InvalidFederatedAddressException
|
||||
* @throws InvalidPeerMetadataException
|
||||
* @throws RedisException
|
||||
* @throws UnsupportedPeerType
|
||||
*/
|
||||
public function syncPeer(ClientRecord|string $client_uuid, ParsedFederatedAddress|string $federated_address, array $peer_metadata): void
|
||||
|
|
|
@ -0,0 +1,293 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace FederationLib\Objects\Standard\PeerMetadata;
|
||||
|
||||
use FederationLib\Classes\Validate;
|
||||
use FederationLib\Enums\Standard\InternetPeerType;
|
||||
use FederationLib\Exceptions\Standard\InvalidPeerMetadataException;
|
||||
use FederationLib\Interfaces\PeerMetadataInterface;
|
||||
use FederationLib\Objects\ParsedFederatedAddress;
|
||||
|
||||
class TelegramChatMetadata implements PeerMetadataInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $username;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $first_name;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $last_name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $is_forum;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $updated_timestamp;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $updated_client;
|
||||
|
||||
/**
|
||||
* Validates the metadata, throws an exception if the metadata is invalid.
|
||||
*
|
||||
* @return void
|
||||
* @throws InvalidPeerMetadataException
|
||||
*/
|
||||
public function validate(): void
|
||||
{
|
||||
$required_properties = [
|
||||
'id' => 'integer',
|
||||
'type' => 'string'
|
||||
];
|
||||
|
||||
$optional_properties = [
|
||||
'title' => 'string',
|
||||
'username' => 'string',
|
||||
'first_name' => 'string',
|
||||
'last_name' => 'string',
|
||||
'is_forum' => 'boolean'
|
||||
];
|
||||
|
||||
Validate::validateMetadata($this->toArray(), $required_properties, $optional_properties);
|
||||
|
||||
if(!in_array(strtolower($this->type), ['private', 'group', 'supergroup', 'channel']))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The metadata contains an invalid value for the property "type": got %s"', $this->type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this peer is automated
|
||||
* (in this case it's never because it's an internet peer)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutomated(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the platform-specific ID for this peer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPlatformId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full federated address for this peer
|
||||
*
|
||||
* @return ParsedFederatedAddress
|
||||
*/
|
||||
public function getFederatedAddress(): ParsedFederatedAddress
|
||||
{
|
||||
return new ParsedFederatedAddress(sprintf('%s:%s', InternetPeerType::TELEGRAM_CHAT, $this->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Client UUID that last updated this metadata
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUpdatedClient(): ?string
|
||||
{
|
||||
return $this->updated_client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client UUID that last updated this metadata
|
||||
*
|
||||
* @param string|null $client_uuid
|
||||
* @return void
|
||||
*/
|
||||
public function setUpdatedClient(?string $client_uuid): void
|
||||
{
|
||||
$this->updated_client = $client_uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Unix Timestamp for when this metadata was last updated
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getLastUpdatedTimestamp(): ?int
|
||||
{
|
||||
return $this->updated_timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last updated timestamp
|
||||
*
|
||||
* @param int|null $timestamp
|
||||
* @return void
|
||||
*/
|
||||
public function setLastUpdatedTimestamp(?int $timestamp): void
|
||||
{
|
||||
$this->updated_timestamp = $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this chat. This number may have more than 32 significant bits and some programming
|
||||
* languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so
|
||||
* a signed 64-bit integer or double-precision float type are safe for storing this identifier.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of chat, can be either “private”, “group”, “supergroup” or “channel”
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Title, for supergroups, channels and group chats
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Username, for private chats, supergroups and channels if available
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUsername(): ?string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. First name of the other party in a private chat
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFirstName(): ?string
|
||||
{
|
||||
return $this->first_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Last name of the other party in a private chat
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLastName(): ?string
|
||||
{
|
||||
return $this->last_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. True, if the supergroup chat is a forum (has topics enabled)
|
||||
*
|
||||
* @link https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
|
||||
* @return bool
|
||||
*/
|
||||
public function isForum(): bool
|
||||
{
|
||||
return $this->is_forum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of this object
|
||||
*
|
||||
* @param bool $raw
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(bool $raw=false): array
|
||||
{
|
||||
$return = [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'title' => $this->title,
|
||||
'username' => $this->username,
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'is_forum' => $this->is_forum
|
||||
];
|
||||
|
||||
if (!$raw)
|
||||
{
|
||||
return $return;
|
||||
}
|
||||
|
||||
return array_merge($return, [
|
||||
'updated_timestamp' => $this->updated_timestamp,
|
||||
'updated_client' => $this->updated_client
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $array
|
||||
* @param bool $raw
|
||||
* @return TelegramChatMetadata
|
||||
*/
|
||||
public static function fromArray(array $array, bool $raw=false): TelegramChatMetadata
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
$object->id = $array['id'];
|
||||
$object->type = $array['type'];
|
||||
$object->title = $array['title'];
|
||||
$object->username = $array['username'];
|
||||
$object->first_name = $array['first_name'];
|
||||
$object->last_name = $array['last_name'];
|
||||
$object->is_forum = $array['is_forum'];
|
||||
|
||||
if(!$raw)
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
|
||||
$object->updated_timestamp = $array['updated_timestamp'];
|
||||
$object->updated_client = $array['updated_client'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
namespace FederationLib\Objects\Standard\PeerMetadata;
|
||||
|
||||
use FederationLib\Classes\Validate;
|
||||
use FederationLib\Enums\Standard\UserPeerType;
|
||||
use FederationLib\Exceptions\Standard\InvalidPeerMetadataException;
|
||||
use FederationLib\Interfaces\PeerMetadataInterface;
|
||||
use FederationLib\Objects\ParsedFederatedAddress;
|
||||
|
||||
class TelegramUserMetadata implements PeerMetadataInterface
|
||||
{
|
||||
|
@ -63,50 +65,20 @@
|
|||
*/
|
||||
public function validate(): void
|
||||
{
|
||||
if($this->id === null)
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "id" is required in the metadata for peer type %s', UserPeerType::TELEGRAM_USER));
|
||||
}
|
||||
$required_properties = [
|
||||
'id' => 'integer',
|
||||
'is_bot' => 'boolean',
|
||||
'first_name' => 'string',
|
||||
'is_premium' => 'boolean',
|
||||
];
|
||||
|
||||
if(!is_int($this->id))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "id" must be an integer in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->id)));
|
||||
}
|
||||
$optional_properties = [
|
||||
'last_name' => 'string',
|
||||
'username' => 'string',
|
||||
'language_code' => 'string',
|
||||
];
|
||||
|
||||
if(!is_bool($this->is_bot))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "is_bot" must be a boolean in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->is_bot)));
|
||||
}
|
||||
|
||||
if($this->first_name === null)
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "first_name" is required in the metadata for peer type %s', UserPeerType::TELEGRAM_USER));
|
||||
}
|
||||
|
||||
if(!is_string($this->first_name))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "first_name" must be a string in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->first_name)));
|
||||
}
|
||||
|
||||
if($this->last_name !== null && !is_string($this->last_name))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "last_name" must be a string in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->last_name)));
|
||||
}
|
||||
|
||||
if($this->username !== null && !is_string($this->username))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "username" must be a string in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->username)));
|
||||
}
|
||||
|
||||
if($this->language_code !== null && !is_string($this->language_code))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "language_code" must be a string in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->language_code)));
|
||||
}
|
||||
|
||||
if(!is_bool($this->is_premium))
|
||||
{
|
||||
throw new InvalidPeerMetadataException(sprintf('The property "is_premium" must be a boolean in metadata for peer type %s, got %s', UserPeerType::TELEGRAM_USER, gettype($this->is_premium)));
|
||||
}
|
||||
Validate::validateMetadata($this->toArray(), $required_properties, $optional_properties);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,11 +105,11 @@
|
|||
* Returns the standard federated address of the peer
|
||||
* Format: telegram.user:<id>
|
||||
*
|
||||
* @return string
|
||||
* @return ParsedFederatedAddress
|
||||
*/
|
||||
public function getFederatedAddress(): string
|
||||
public function getFederatedAddress(): ParsedFederatedAddress
|
||||
{
|
||||
return sprintf('%s:%s', UserPeerType::TELEGRAM_USER, $this->id);
|
||||
return new ParsedFederatedAddress(sprintf('%s:%s', UserPeerType::TELEGRAM_USER, $this->id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,12 +125,12 @@
|
|||
/**
|
||||
* Sets the client UUID that last updated the record
|
||||
*
|
||||
* @param string|null $client
|
||||
* @param string|null $client_uuid
|
||||
* @return void
|
||||
*/
|
||||
public function setUpdatedClient(?string $client): void
|
||||
public function setUpdatedClient(?string $client_uuid): void
|
||||
{
|
||||
$this->updated_client = $client;
|
||||
$this->updated_client = $client_uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue