Merge pull request #10401 from annando/no-diaspora-relay

Diaspora relay functionality is removed
This commit is contained in:
Hypolite Petovan 2021-06-13 21:50:08 -04:00 committed by GitHub
commit 40a1841e22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 333 additions and 345 deletions

View file

@ -32,6 +32,7 @@ use Friendica\Model\Contact;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\BaseAdmin; use Friendica\Module\BaseAdmin;
use Friendica\Module\Register; use Friendica\Module\Register;
use Friendica\Protocol\Relay;
use Friendica\Util\BasePath; use Friendica\Util\BasePath;
use Friendica\Util\EMailer\MailBuilder; use Friendica\Util\EMailer\MailBuilder;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -208,8 +209,6 @@ class Site extends BaseAdmin
$worker_fastlane = !empty($_POST['worker_fastlane']); $worker_fastlane = !empty($_POST['worker_fastlane']);
$relay_directly = !empty($_POST['relay_directly']); $relay_directly = !empty($_POST['relay_directly']);
$relay_server = (!empty($_POST['relay_server']) ? Strings::escapeTags(trim($_POST['relay_server'])) : '');
$relay_subscribe = !empty($_POST['relay_subscribe']);
$relay_scope = (!empty($_POST['relay_scope']) ? Strings::escapeTags(trim($_POST['relay_scope'])) : ''); $relay_scope = (!empty($_POST['relay_scope']) ? Strings::escapeTags(trim($_POST['relay_scope'])) : '');
$relay_server_tags = (!empty($_POST['relay_server_tags']) ? Strings::escapeTags(trim($_POST['relay_server_tags'])) : ''); $relay_server_tags = (!empty($_POST['relay_server_tags']) ? Strings::escapeTags(trim($_POST['relay_server_tags'])) : '');
$relay_deny_tags = (!empty($_POST['relay_deny_tags']) ? Strings::escapeTags(trim($_POST['relay_deny_tags'])) : ''); $relay_deny_tags = (!empty($_POST['relay_deny_tags']) ? Strings::escapeTags(trim($_POST['relay_deny_tags'])) : '');
@ -418,8 +417,6 @@ class Site extends BaseAdmin
DI::config()->set('system', 'worker_fastlane' , $worker_fastlane); DI::config()->set('system', 'worker_fastlane' , $worker_fastlane);
DI::config()->set('system', 'relay_directly' , $relay_directly); DI::config()->set('system', 'relay_directly' , $relay_directly);
DI::config()->set('system', 'relay_server' , $relay_server);
DI::config()->set('system', 'relay_subscribe' , $relay_subscribe);
DI::config()->set('system', 'relay_scope' , $relay_scope); DI::config()->set('system', 'relay_scope' , $relay_scope);
DI::config()->set('system', 'relay_server_tags', $relay_server_tags); DI::config()->set('system', 'relay_server_tags', $relay_server_tags);
DI::config()->set('system', 'relay_deny_tags' , $relay_deny_tags); DI::config()->set('system', 'relay_deny_tags' , $relay_deny_tags);
@ -589,6 +586,10 @@ class Site extends BaseAdmin
'$performance' => DI::l10n()->t('Performance'), '$performance' => DI::l10n()->t('Performance'),
'$worker_title' => DI::l10n()->t('Worker'), '$worker_title' => DI::l10n()->t('Worker'),
'$relay_title' => DI::l10n()->t('Message Relay'), '$relay_title' => DI::l10n()->t('Message Relay'),
'$relay_description' => DI::l10n()->t('Use the command "console relay" in the command line to add or remove relays.'),
'$no_relay_list' => DI::l10n()->t('The system is not subscribed to any relays at the moment.'),
'$relay_list_title' => DI::l10n()->t('The system is currently subscribed to the following relays:'),
'$relay_list' => Relay::getList(['url']),
'$relocate' => DI::l10n()->t('Relocate Instance'), '$relocate' => DI::l10n()->t('Relocate Instance'),
'$relocate_warning' => DI::l10n()->t('<strong>Warning!</strong> Advanced function. Could make this server unreachable.'), '$relocate_warning' => DI::l10n()->t('<strong>Warning!</strong> Advanced function. Could make this server unreachable.'),
'$baseurl' => DI::baseUrl()->get(true), '$baseurl' => DI::baseUrl()->get(true),
@ -688,10 +689,8 @@ class Site extends BaseAdmin
'$worker_queues' => ['worker_queues', DI::l10n()->t('Maximum number of parallel workers'), DI::config()->get('system', 'worker_queues'), DI::l10n()->t('On shared hosters set this to %d. On larger systems, values of %d are great. Default value is %d.', 5, 20, 10)], '$worker_queues' => ['worker_queues', DI::l10n()->t('Maximum number of parallel workers'), DI::config()->get('system', 'worker_queues'), DI::l10n()->t('On shared hosters set this to %d. On larger systems, values of %d are great. Default value is %d.', 5, 20, 10)],
'$worker_fastlane' => ['worker_fastlane', DI::l10n()->t('Enable fastlane'), DI::config()->get('system', 'worker_fastlane'), DI::l10n()->t('When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.')], '$worker_fastlane' => ['worker_fastlane', DI::l10n()->t('Enable fastlane'), DI::config()->get('system', 'worker_fastlane'), DI::l10n()->t('When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.')],
'$relay_subscribe' => ['relay_subscribe', DI::l10n()->t('Use relay servers'), DI::config()->get('system', 'relay_subscribe'), DI::l10n()->t('Enables the receiving of public posts from relay servers. They will be included in the search, subscribed tags and on the global community page.')],
'$relay_server' => ['relay_server', DI::l10n()->t('"Social Relay" server'), DI::config()->get('system', 'relay_server'), DI::l10n()->t('Address of the "Social Relay" server where public posts should be send to. For example %s. ActivityRelay servers are administrated via the "console relay" command line command.', 'https://social-relay.isurf.ca')],
'$relay_directly' => ['relay_directly', DI::l10n()->t('Direct relay transfer'), DI::config()->get('system', 'relay_directly'), DI::l10n()->t('Enables the direct transfer to other servers without using the relay servers')], '$relay_directly' => ['relay_directly', DI::l10n()->t('Direct relay transfer'), DI::config()->get('system', 'relay_directly'), DI::l10n()->t('Enables the direct transfer to other servers without using the relay servers')],
'$relay_scope' => ['relay_scope', DI::l10n()->t('Relay scope'), DI::config()->get('system', 'relay_scope'), DI::l10n()->t('Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts with selected tags should be received.'), ['' => DI::l10n()->t('Disabled'), 'all' => DI::l10n()->t('all'), 'tags' => DI::l10n()->t('tags')]], '$relay_scope' => ['relay_scope', DI::l10n()->t('Relay scope'), DI::config()->get('system', 'relay_scope'), DI::l10n()->t('Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts with selected tags should be received.'), [SR_SCOPE_NONE => DI::l10n()->t('Disabled'), SR_SCOPE_ALL => DI::l10n()->t('all'), SR_SCOPE_TAGS => DI::l10n()->t('tags')]],
'$relay_server_tags' => ['relay_server_tags', DI::l10n()->t('Server tags'), DI::config()->get('system', 'relay_server_tags'), DI::l10n()->t('Comma separated list of tags for the "tags" subscription.')], '$relay_server_tags' => ['relay_server_tags', DI::l10n()->t('Server tags'), DI::config()->get('system', 'relay_server_tags'), DI::l10n()->t('Comma separated list of tags for the "tags" subscription.')],
'$relay_deny_tags' => ['relay_deny_tags', DI::l10n()->t('Deny Server tags'), DI::config()->get('system', 'relay_deny_tags'), DI::l10n()->t('Comma separated list of tags that are rejected.')], '$relay_deny_tags' => ['relay_deny_tags', DI::l10n()->t('Deny Server tags'), DI::config()->get('system', 'relay_deny_tags'), DI::l10n()->t('Comma separated list of tags that are rejected.')],
'$relay_user_tags' => ['relay_user_tags', DI::l10n()->t('Allow user tags'), DI::config()->get('system', 'relay_user_tags'), DI::l10n()->t('If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags".')], '$relay_user_tags' => ['relay_user_tags', DI::l10n()->t('Allow user tags'), DI::config()->get('system', 'relay_user_tags'), DI::l10n()->t('If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags".')],

View file

@ -35,13 +35,7 @@ class XSocialRelay extends BaseModule
{ {
$config = DI::config(); $config = DI::config();
$subscribe = $config->get('system', 'relay_subscribe', false); $scope = $config->get('system', 'relay_scope');
if ($subscribe) {
$scope = $config->get('system', 'relay_scope', SR_SCOPE_ALL);
} else {
$scope = SR_SCOPE_NONE;
}
$systemTags = []; $systemTags = [];
$userTags = []; $userTags = [];
@ -63,7 +57,7 @@ class XSocialRelay extends BaseModule
$tagList = array_unique(array_merge($systemTags, $userTags)); $tagList = array_unique(array_merge($systemTags, $userTags));
$relay = [ $relay = [
'subscribe' => $subscribe, 'subscribe' => ($scope != SR_SCOPE_NONE),
'scope' => $scope, 'scope' => $scope,
'tags' => $tagList, 'tags' => $tagList,
'protocols' => [ 'protocols' => [

View file

@ -68,13 +68,9 @@ class Transmitter
*/ */
public static function addRelayServerInboxes(array $inboxes = []) public static function addRelayServerInboxes(array $inboxes = [])
{ {
$contacts = DBA::select('apcontact', ['inbox'], foreach (Relay::getList(['inbox']) as $contact) {
["`type` = ? AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` = ?)",
'Application', 0, Contact::FRIEND]);
while ($contact = DBA::fetch($contacts)) {
$inboxes[$contact['inbox']] = $contact['inbox']; $inboxes[$contact['inbox']] = $contact['inbox'];
} }
DBA::close($contacts);
return $inboxes; return $inboxes;
} }
@ -92,7 +88,7 @@ class Transmitter
return $inboxes; return $inboxes;
} }
$relays = Relay::getList($item_id, [], [Protocol::ACTIVITYPUB]); $relays = Relay::getDirectRelayList($item_id);
if (empty($relays)) { if (empty($relays)) {
return $inboxes; return $inboxes;
} }

View file

@ -29,7 +29,6 @@ use Friendica\DI;
use Friendica\Model\APContact; use Friendica\Model\APContact;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\GServer; use Friendica\Model\GServer;
use Friendica\Model\Item;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\Search; use Friendica\Model\Search;
use Friendica\Model\Tag; use Friendica\Model\Tag;
@ -54,12 +53,7 @@ class Relay
{ {
$config = DI::config(); $config = DI::config();
$subscribe = $config->get('system', 'relay_subscribe', false); $scope = $config->get('system', 'relay_scope');
if ($subscribe) {
$scope = $config->get('system', 'relay_scope', SR_SCOPE_ALL);
} else {
$scope = SR_SCOPE_NONE;
}
if ($scope == SR_SCOPE_NONE) { if ($scope == SR_SCOPE_NONE) {
Logger::info('Server does not accept relay posts - rejected', ['network' => $network, 'url' => $url]); Logger::info('Server does not accept relay posts - rejected', ['network' => $network, 'url' => $url]);
@ -168,7 +162,7 @@ class Relay
return; return;
} }
if (DBA::isResult($old)) { if (DBA::isResult($old)) {
$fields['updated'] = DateTimeFormat::utcNow(); $fields['updated'] = DateTimeFormat::utcNow();
Logger::info('Update relay contact', ['server' => $gserver['url'], 'id' => $old['id'], 'fields' => $fields]); Logger::info('Update relay contact', ['server' => $gserver['url'], 'id' => $old['id'], 'fields' => $fields]);
@ -224,76 +218,65 @@ class Relay
} }
/** /**
* Return a list of relay servers * Return a list of servers that we serve via the direct relay
*
* The list contains not only the official relays but also servers that we serve directly
* *
* @param integer $item_id id of the item that is sent * @param integer $item_id id of the item that is sent
* @param array $contacts Previously fetched contacts * @param array $contacts Previously fetched contacts
* @param array $networks Networks of the relay servers * @param array $networks Networks of the relay servers
* *
* @return array of relay servers * @return array of relay servers
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/ */
public static function getList(int $item_id, array $contacts, array $networks) public static function getDirectRelayList(int $item_id)
{ {
$serverlist = []; $serverlist = [];
// Fetching relay servers if (!DI::config()->get("system", "relay_directly", false)) {
$serverdata = DI::config()->get("system", "relay_server"); return [];
if (!empty($serverdata)) {
$servers = explode(",", $serverdata);
foreach ($servers as $server) {
$gserver = DBA::selectFirst('gserver', ['id', 'url', 'network'], ['nurl' => Strings::normaliseLink($server)]);
if (DBA::isResult($gserver)) {
$serverlist[$gserver['id']] = $gserver;
}
}
} }
if (DI::config()->get("system", "relay_directly", false)) { // We distribute our stuff based on the parent to ensure that the thread will be complete
// We distribute our stuff based on the parent to ensure that the thread will be complete $parent = Post::selectFirst(['uri-id'], ['id' => $item_id]);
$parent = Post::selectFirst(['uri-id'], ['id' => $item_id]); if (!DBA::isResult($parent)) {
if (!DBA::isResult($parent)) { return [];
return; }
}
// Servers that want to get all content // Servers that want to get all content
$servers = DBA::select('gserver', ['id', 'url', 'network'], ['relay-subscribe' => true, 'relay-scope' => 'all']); $servers = DBA::select('gserver', ['id', 'url', 'network'], ['relay-subscribe' => true, 'relay-scope' => 'all']);
while ($server = DBA::fetch($servers)) {
$serverlist[$server['id']] = $server;
}
DBA::close($servers);
// All tags of the current post
$tags = DBA::select('tag-view', ['name'], ['uri-id' => $parent['uri-id'], 'type' => Tag::HASHTAG]);
$taglist = [];
while ($tag = DBA::fetch($tags)) {
$taglist[] = $tag['name'];
}
DBA::close($tags);
// All servers who wants content with this tag
$tagserverlist = [];
if (!empty($taglist)) {
$tagserver = DBA::select('gserver-tag', ['gserver-id'], ['tag' => $taglist]);
while ($server = DBA::fetch($tagserver)) {
$tagserverlist[] = $server['gserver-id'];
}
DBA::close($tagserver);
}
// All adresses with the given id
if (!empty($tagserverlist)) {
$servers = DBA::select('gserver', ['id', 'url', 'network'], ['relay-subscribe' => true, 'relay-scope' => 'tags', 'id' => $tagserverlist]);
while ($server = DBA::fetch($servers)) { while ($server = DBA::fetch($servers)) {
$serverlist[$server['id']] = $server; $serverlist[$server['id']] = $server;
} }
DBA::close($servers); DBA::close($servers);
// All tags of the current post
$tags = DBA::select('tag-view', ['name'], ['uri-id' => $parent['uri-id'], 'type' => Tag::HASHTAG]);
$taglist = [];
while ($tag = DBA::fetch($tags)) {
$taglist[] = $tag['name'];
}
DBA::close($tags);
// All servers who wants content with this tag
$tagserverlist = [];
if (!empty($taglist)) {
$tagserver = DBA::select('gserver-tag', ['gserver-id'], ['tag' => $taglist]);
while ($server = DBA::fetch($tagserver)) {
$tagserverlist[] = $server['gserver-id'];
}
DBA::close($tagserver);
}
// All adresses with the given id
if (!empty($tagserverlist)) {
$servers = DBA::select('gserver', ['id', 'url', 'network'], ['relay-subscribe' => true, 'relay-scope' => 'tags', 'id' => $tagserverlist]);
while ($server = DBA::fetch($servers)) {
$serverlist[$server['id']] = $server;
}
DBA::close($servers);
}
} }
$contacts = [];
// Now we are collecting all relay contacts // Now we are collecting all relay contacts
foreach ($serverlist as $gserver) { foreach ($serverlist as $gserver) {
// We don't send messages to ourselves // We don't send messages to ourselves
@ -304,15 +287,24 @@ class Relay
if (empty($contact)) { if (empty($contact)) {
continue; continue;
} }
if (in_array($contact['network'], $networks) && !in_array($contact['batch'], array_column($contacts, 'batch'))) {
$contacts[] = $contact;
}
} }
return $contacts; return $contacts;
} }
/**
* Return a list of relay servers
*
* @param array $fields Field list
* @return array
* @throws Exception
*/
public static function getList($fields = []):array
{
return DBA::selectToArray('apcontact', $fields,
["`type` = ? AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` = ?)", 'Application', 0, Contact::FRIEND]);
}
/** /**
* Return a contact for a given server address or creates a dummy entry * Return a contact for a given server address or creates a dummy entry
* *

View file

@ -39,7 +39,6 @@ use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus; use Friendica\Protocol\OStatus;
use Friendica\Protocol\Relay;
use Friendica\Protocol\Salmon; use Friendica\Protocol\Salmon;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -442,12 +441,12 @@ class Notifier
$batch_delivery = false; $batch_delivery = false;
if ($public_message && !in_array($cmd, [Delivery::MAIL, Delivery::SUGGESTION]) && !$followup) { if ($public_message && !in_array($cmd, [Delivery::MAIL, Delivery::SUGGESTION]) && !$followup) {
$relay_list = []; $participants = [];
if ($diaspora_delivery && !$unlisted) { if ($diaspora_delivery && !$unlisted) {
$batch_delivery = true; $batch_delivery = true;
$relay_list_stmt = DBA::p( $participants_stmt = DBA::p(
"SELECT "SELECT
`batch`, `network`, `protocol`, `batch`, `network`, `protocol`,
ANY_VALUE(`id`) AS `id`, ANY_VALUE(`id`) AS `id`,
@ -466,17 +465,11 @@ class Notifier
$owner['uid'], $owner['uid'],
Contact::SHARING Contact::SHARING
); );
$relay_list = DBA::toArray($relay_list_stmt); $participants = DBA::toArray($participants_stmt);
// Fetch the participation list // Fetch the participation list
// The function will ensure that there are no duplicates // The function will ensure that there are no duplicates
$relay_list = Diaspora::participantsForThread($target_item, $relay_list); $participants = Diaspora::participantsForThread($target_item, $participants);
// Add the relay to the list, avoid duplicates.
// Don't send community posts to the relay. Forum posts via the Diaspora protocol are looking ugly.
if (!$followup && !Item::isForumPost($target_item, $owner) && !self::isForumPost($target_item)) {
$relay_list = Relay::getList($target_id, $relay_list, [Protocol::DFRN, Protocol::DIASPORA]);
}
} }
$condition = ['network' => Protocol::DFRN, 'uid' => $owner['uid'], 'blocked' => false, $condition = ['network' => Protocol::DFRN, 'uid' => $owner['uid'], 'blocked' => false,
@ -484,7 +477,7 @@ class Notifier
$contacts = DBA::toArray(DBA::select('contact', ['id', 'url', 'addr', 'name', 'network', 'protocol'], $condition)); $contacts = DBA::toArray(DBA::select('contact', ['id', 'url', 'addr', 'name', 'network', 'protocol'], $condition));
$conversants = array_merge($contacts, $relay_list); $conversants = array_merge($contacts, $participants);
$delivery_queue_count += self::delivery($cmd, $post_uriid, $sender_uid, $target_item, $thr_parent, $owner, $batch_delivery, true, $conversants, $ap_contacts, []); $delivery_queue_count += self::delivery($cmd, $post_uriid, $sender_uid, $target_item, $thr_parent, $owner, $batch_delivery, true, $conversants, $ap_contacts, []);

View file

@ -164,9 +164,13 @@ return [
// Comma separated list of tags that are rejected. // Comma separated list of tags that are rejected.
'relay_deny_tags' => '', 'relay_deny_tags' => '',
// relay_server (String) // relay_directly (Boolean)
// Address of the relay server where public posts should be send to. // Directly transmit content to relay subscribers without using a relay server
'relay_server' => 'https://social-relay.isurf.ca', 'relay_directly' => false,
// relay_scope (SR_SCOPE_NONE, SR_SCOPE_TAGS or SR_SCOPE_ALL)
// Defines the scope of accepted posts from the relay servers
'relay_scope' => SR_SCOPE_NONE,
// relay_server_tags (String) // relay_server_tags (String)
// Comma separated list of tags for the "tags" subscription. // Comma separated list of tags for the "tags" subscription.

File diff suppressed because it is too large Load diff

View file

@ -127,13 +127,22 @@
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div> <div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div>
<h2>{{$relay_title}}</h2> <h2>{{$relay_title}}</h2>
{{include file="field_checkbox.tpl" field=$relay_subscribe}} {{if $relay_list}}
{{include file="field_input.tpl" field=$relay_server}} <p>{{$relay_list_title}}</p>
{{include file="field_checkbox.tpl" field=$relay_directly}} <ul id="relay-list">
{{foreach $relay_list as $relay}}
<li>{{$relay.url}}</li>
{{/foreach}}
</ul>
{{else}}
<p>{{$no_relay_list}}</p>
{{/if}}
<p>{{$relay_description}}</p>
{{include file="field_select.tpl" field=$relay_scope}} {{include file="field_select.tpl" field=$relay_scope}}
{{include file="field_input.tpl" field=$relay_server_tags}} {{include file="field_input.tpl" field=$relay_server_tags}}
{{include file="field_input.tpl" field=$relay_deny_tags}} {{include file="field_input.tpl" field=$relay_deny_tags}}
{{include file="field_checkbox.tpl" field=$relay_user_tags}} {{include file="field_checkbox.tpl" field=$relay_user_tags}}
{{include file="field_checkbox.tpl" field=$relay_directly}}
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div> <div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div>

View file

@ -297,13 +297,22 @@
</div> </div>
<div id="admin-settings-relay-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-relay"> <div id="admin-settings-relay-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-relay">
<div class="panel-body"> <div class="panel-body">
{{include file="field_checkbox.tpl" field=$relay_subscribe}} {{if $relay_list}}
{{include file="field_input.tpl" field=$relay_server}} <p>{{$relay_list_title}}</p>
{{include file="field_checkbox.tpl" field=$relay_directly}} <ul id="relay-list">
{{foreach $relay_list as $relay}}
<li>{{$relay.url}}</li>
{{/foreach}}
</ul>
{{else}}
<p>{{$no_relay_list}}</p>
{{/if}}
<p>{{$relay_description}}</p>
{{include file="field_select.tpl" field=$relay_scope}} {{include file="field_select.tpl" field=$relay_scope}}
{{include file="field_input.tpl" field=$relay_server_tags}} {{include file="field_input.tpl" field=$relay_server_tags}}
{{include file="field_input.tpl" field=$relay_deny_tags}} {{include file="field_input.tpl" field=$relay_deny_tags}}
{{include file="field_checkbox.tpl" field=$relay_user_tags}} {{include file="field_checkbox.tpl" field=$relay_user_tags}}
{{include file="field_checkbox.tpl" field=$relay_directly}}
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<input type="submit" name="page_site" class="btn btn-primary" value="{{$submit}}"/> <input type="submit" name="page_site" class="btn btn-primary" value="{{$submit}}"/>