Add Install Mode
- merged `friendica/develop` to `nupplaPhil/install_mode` - content merged `mod/install.php` to `src/Class/`
This commit is contained in:
commit
1ab965c944
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,6 +9,7 @@ include/jquery-1.4.2.min.js
|
|||
favicon.*
|
||||
home.html
|
||||
addon
|
||||
*.orig
|
||||
*~
|
||||
robots.txt
|
||||
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
---
|
||||
language: php
|
||||
php: 5.6
|
||||
## Friendica supports PHP version >= 5.6
|
||||
php:
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
|
||||
install: composer install
|
||||
|
|
3
boot.php
3
boot.php
|
@ -232,6 +232,7 @@ define('ACCOUNT_TYPE_RELAY', 4);
|
|||
* Type of the community page
|
||||
* @{
|
||||
*/
|
||||
define('CP_NO_INTERNAL_COMMUNITY', -2);
|
||||
define('CP_NO_COMMUNITY_PAGE', -1);
|
||||
define('CP_USERS_ON_SERVER', 0);
|
||||
define('CP_GLOBAL_COMMUNITY', 1);
|
||||
|
@ -1291,7 +1292,7 @@ function get_server()
|
|||
$server = Config::get("system", "directory");
|
||||
|
||||
if ($server == "") {
|
||||
$server = "http://dir.friendica.social";
|
||||
$server = "https://dir.friendica.social";
|
||||
}
|
||||
|
||||
return($server);
|
||||
|
|
376
doc/Addons.md
376
doc/Addons.md
|
@ -321,184 +321,300 @@ Complete list of hook callbacks
|
|||
|
||||
Here is a complete list of all hook callbacks with file locations (as of 01-Apr-2018). Please see the source for details of any hooks not documented above.
|
||||
|
||||
index.php: Addon::callHooks('init_1');
|
||||
index.php: Addon::callHooks('app_menu', $arr);
|
||||
index.php: Addon::callHooks('page_content_top', $a->page['content']);
|
||||
index.php: Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
index.php: Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
index.php: Addon::callHooks($a->module.'_mod_post', $_POST);
|
||||
index.php: Addon::callHooks($a->module.'_mod_afterpost', $placeholder);
|
||||
index.php: Addon::callHooks($a->module.'_mod_content', $arr);
|
||||
index.php: Addon::callHooks($a->module.'_mod_aftercontent', $arr);
|
||||
index.php: Addon::callHooks('page_end', $a->page['content']);
|
||||
### index.php
|
||||
|
||||
include/api.php: Addon::callHooks('logged_in', $a->user);
|
||||
include/api.php: Addon::callHooks('authenticate', $addon_auth);
|
||||
include/api.php: Addon::callHooks('logged_in', $a->user);
|
||||
Addon::callHooks('init_1');
|
||||
Addon::callHooks('app_menu', $arr);
|
||||
Addon::callHooks('page_content_top', $a->page['content']);
|
||||
Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
Addon::callHooks($a->module.'_mod_post', $_POST);
|
||||
Addon::callHooks($a->module.'_mod_afterpost', $placeholder);
|
||||
Addon::callHooks($a->module.'_mod_content', $arr);
|
||||
Addon::callHooks($a->module.'_mod_aftercontent', $arr);
|
||||
Addon::callHooks('page_end', $a->page['content']);
|
||||
|
||||
include/enotify.php: Addon::callHooks('enotify', $h);
|
||||
include/enotify.php: Addon::callHooks('enotify_store', $datarray);
|
||||
include/enotify.php: Addon::callHooks('enotify_mail', $datarray);
|
||||
include/enotify.php: Addon::callHooks('check_item_notification', $notification_data);
|
||||
### include/api.php
|
||||
|
||||
include/conversation.php: Addon::callHooks('conversation_start', $cb);
|
||||
include/conversation.php: Addon::callHooks('render_location', $locate);
|
||||
include/conversation.php: Addon::callHooks('display_item', $arr);
|
||||
include/conversation.php: Addon::callHooks('display_item', $arr);
|
||||
include/conversation.php: Addon::callHooks('item_photo_menu', $args);
|
||||
include/conversation.php: Addon::callHooks('jot_tool', $jotplugins);
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
Addon::callHooks('authenticate', $addon_auth);
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
|
||||
include/security.php: Addon::callHooks('logged_in', $a->user);
|
||||
### include/enotify.php
|
||||
|
||||
include/text.php: Addon::callHooks('contact_block_end', $arr);
|
||||
include/text.php: Addon::callHooks('poke_verbs', $arr);
|
||||
include/text.php: Addon::callHooks('prepare_body_init', $item);
|
||||
include/text.php: Addon::callHooks('prepare_body_content_filter', $hook_data);
|
||||
include/text.php: Addon::callHooks('prepare_body', $hook_data);
|
||||
include/text.php: Addon::callHooks('prepare_body_final', $hook_data);
|
||||
Addon::callHooks('enotify', $h);
|
||||
Addon::callHooks('enotify_store', $datarray);
|
||||
Addon::callHooks('enotify_mail', $datarray);
|
||||
Addon::callHooks('check_item_notification', $notification_data);
|
||||
|
||||
include/items.php: Addon::callHooks('page_info_data', $data);
|
||||
### include/conversation.php
|
||||
|
||||
mod/directory.php: Addon::callHooks('directory_item', $arr);
|
||||
Addon::callHooks('conversation_start', $cb);
|
||||
Addon::callHooks('render_location', $locate);
|
||||
Addon::callHooks('display_item', $arr);
|
||||
Addon::callHooks('display_item', $arr);
|
||||
Addon::callHooks('item_photo_menu', $args);
|
||||
Addon::callHooks('jot_tool', $jotplugins);
|
||||
|
||||
mod/xrd.php: Addon::callHooks('personal_xrd', $arr);
|
||||
### include/security.php
|
||||
|
||||
mod/ping.php: Addon::callHooks('network_ping', $arr);
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
|
||||
mod/parse_url.php: Addon::callHooks("parse_link", $arr);
|
||||
### include/text.php
|
||||
|
||||
mod/manage.php: Addon::callHooks('home_init', $ret);
|
||||
Addon::callHooks('contact_block_end', $arr);
|
||||
Addon::callHooks('poke_verbs', $arr);
|
||||
Addon::callHooks('prepare_body_init', $item);
|
||||
Addon::callHooks('prepare_body_content_filter', $hook_data);
|
||||
Addon::callHooks('prepare_body', $hook_data);
|
||||
Addon::callHooks('prepare_body_final', $hook_data);
|
||||
|
||||
mod/acl.php: Addon::callHooks('acl_lookup_end', $results);
|
||||
### include/items.php
|
||||
|
||||
mod/network.php: Addon::callHooks('network_content_init', $arr);
|
||||
mod/network.php: Addon::callHooks('network_tabs', $arr);
|
||||
Addon::callHooks('page_info_data', $data);
|
||||
|
||||
mod/friendica.php: Addon::callHooks('about_hook', $o);
|
||||
mod/subthread.php: Addon::callHooks('post_local_end', $arr);
|
||||
### mod/directory.php
|
||||
|
||||
mod/profiles.php: Addon::callHooks('profile_post', $_POST);
|
||||
mod/profiles.php: Addon::callHooks('profile_edit', $arr);
|
||||
Addon::callHooks('directory_item', $arr);
|
||||
|
||||
mod/settings.php: Addon::callHooks('addon_settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('connector_settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('display_settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('addon_settings', $settings_addons);
|
||||
mod/settings.php: Addon::callHooks('connector_settings', $settings_connectors);
|
||||
mod/settings.php: Addon::callHooks('display_settings', $o);
|
||||
mod/settings.php: Addon::callHooks('settings_form', $o);
|
||||
### mod/xrd.php
|
||||
|
||||
mod/photos.php: Addon::callHooks('photo_post_init', $_POST);
|
||||
mod/photos.php: Addon::callHooks('photo_post_file', $ret);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', intval($item_id));
|
||||
mod/photos.php: Addon::callHooks('photo_upload_form', $ret);
|
||||
Addon::callHooks('personal_xrd', $arr);
|
||||
|
||||
mod/profile.php: Addon::callHooks('profile_advanced', $o);
|
||||
### mod/ping.php
|
||||
|
||||
mod/home.php: Addon::callHooks('home_init', $ret);
|
||||
mod/home.php: Addon::callHooks("home_content", $content);
|
||||
Addon::callHooks('network_ping', $arr);
|
||||
|
||||
mod/poke.php: Addon::callHooks('post_local_end', $arr);
|
||||
### mod/parse_url.php
|
||||
|
||||
mod/contacts.php: Addon::callHooks('contact_edit_post', $_POST);
|
||||
mod/contacts.php: Addon::callHooks('contact_edit', $arr);
|
||||
Addon::callHooks("parse_link", $arr);
|
||||
|
||||
mod/tagger.php: Addon::callHooks('post_local_end', $arr);
|
||||
### mod/manage.php
|
||||
|
||||
mod/lockview.php: Addon::callHooks('lockview_content', $item);
|
||||
Addon::callHooks('home_init', $ret);
|
||||
|
||||
mod/uexport.php: Addon::callHooks('uexport_options', $options);
|
||||
### mod/acl.php
|
||||
|
||||
mod/register.php: Addon::callHooks('register_post', $arr);
|
||||
mod/register.php: Addon::callHooks('register_form', $arr);
|
||||
Addon::callHooks('acl_lookup_end', $results);
|
||||
|
||||
mod/item.php: Addon::callHooks('post_local_start', $_REQUEST);
|
||||
mod/item.php: Addon::callHooks('post_local', $datarray);
|
||||
mod/item.php: Addon::callHooks('post_local_end', $datarray);
|
||||
### mod/network.php
|
||||
|
||||
mod/editpost.php: Addon::callHooks('jot_tool', $jotplugins);
|
||||
Addon::callHooks('network_content_init', $arr);
|
||||
Addon::callHooks('network_tabs', $arr);
|
||||
|
||||
src/Network/FKOAuth1.php: Addon::callHooks('logged_in', $a->user);
|
||||
### mod/friendica.php
|
||||
|
||||
src/Render/FriendicaSmartyEngine.php: Addon::callHooks("template_vars", $arr);
|
||||
Addon::callHooks('about_hook', $o);
|
||||
|
||||
src/Model/Item.php: Addon::callHooks('post_local', $item);
|
||||
src/Model/Item.php: Addon::callHooks('post_remote', $item);
|
||||
src/Model/Item.php: Addon::callHooks('post_local_end', $posted_item);
|
||||
src/Model/Item.php: Addon::callHooks('post_remote_end', $posted_item);
|
||||
src/Model/Item.php: Addon::callHooks('tagged', $arr);
|
||||
src/Model/Item.php: Addon::callHooks('post_local_end', $new_item);
|
||||
### mod/subthread.php
|
||||
|
||||
src/Model/Contact.php: Addon::callHooks('contact_photo_menu', $args);
|
||||
src/Model/Contact.php: Addon::callHooks('follow', $arr);
|
||||
Addon::callHooks('post_local_end', $arr);
|
||||
|
||||
src/Model/Profile.php: Addon::callHooks('profile_sidebar_enter', $profile);
|
||||
src/Model/Profile.php: Addon::callHooks('profile_sidebar', $arr);
|
||||
src/Model/Profile.php: Addon::callHooks('profile_tabs', $arr);
|
||||
src/Model/Profile.php: Addon::callHooks('zrl_init', $arr);
|
||||
### mod/profiles.php
|
||||
|
||||
src/Model/Event.php: Addon::callHooks('event_updated', $event['id']);
|
||||
src/Model/Event.php: Addon::callHooks("event_created", $event['id']);
|
||||
Addon::callHooks('profile_post', $_POST);
|
||||
Addon::callHooks('profile_edit', $arr);
|
||||
|
||||
src/Model/User.php: Addon::callHooks('register_account', $uid);
|
||||
src/Model/User.php: Addon::callHooks('remove_user', $user);
|
||||
### mod/settings.php
|
||||
|
||||
src/Content/Text/BBCode.php: Addon::callHooks('bbcode', $text);
|
||||
src/Content/Text/BBCode.php: Addon::callHooks('bb2diaspora', $text);
|
||||
Addon::callHooks('addon_settings_post', $_POST);
|
||||
Addon::callHooks('connector_settings_post', $_POST);
|
||||
Addon::callHooks('display_settings_post', $_POST);
|
||||
Addon::callHooks('settings_post', $_POST);
|
||||
Addon::callHooks('addon_settings', $settings_addons);
|
||||
Addon::callHooks('connector_settings', $settings_connectors);
|
||||
Addon::callHooks('display_settings', $o);
|
||||
Addon::callHooks('settings_form', $o);
|
||||
|
||||
src/Content/Text/HTML.php: Addon::callHooks('html2bbcode', $message);
|
||||
### mod/photos.php
|
||||
|
||||
src/Content/Smilies.php: Addon::callHooks('smilie', $params);
|
||||
Addon::callHooks('photo_post_init', $_POST);
|
||||
Addon::callHooks('photo_post_file', $ret);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', intval($item_id));
|
||||
Addon::callHooks('photo_upload_form', $ret);
|
||||
|
||||
src/Content/Feature.php: Addon::callHooks('isEnabled', $arr);
|
||||
src/Content/Feature.php: Addon::callHooks('get', $arr);
|
||||
### mod/profile.php
|
||||
|
||||
src/Content/ContactSelector.php: Addon::callHooks('network_to_name', $nets);
|
||||
src/Content/ContactSelector.php: Addon::callHooks('gender_selector', $select);
|
||||
src/Content/ContactSelector.php: Addon::callHooks('sexpref_selector', $select);
|
||||
src/Content/ContactSelector.php: Addon::callHooks('marital_selector', $select);
|
||||
Addon::callHooks('profile_advanced', $o);
|
||||
|
||||
src/Content/OEmbed.php: Addon::callHooks('oembed_fetch_url', $embedurl, $j);
|
||||
### mod/home.php
|
||||
|
||||
src/Content/Nav.php: Addon::callHooks('page_header', $a->page['nav']);
|
||||
src/Content/Nav.php: Addon::callHooks('nav_info', $nav);
|
||||
Addon::callHooks('home_init', $ret);
|
||||
Addon::callHooks("home_content", $content);
|
||||
|
||||
src/Worker/Directory.php: Addon::callHooks('globaldir_update', $arr);
|
||||
src/Worker/Notifier.php: Addon::callHooks('notifier_end', $target_item);
|
||||
src/Worker/Queue.php: Addon::callHooks('queue_predeliver', $r);
|
||||
src/Worker/Queue.php: Addon::callHooks('queue_deliver', $params);
|
||||
### mod/poke.php
|
||||
|
||||
src/Module/Login.php: Addon::callHooks('authenticate', $addon_auth);
|
||||
src/Module/Login.php: Addon::callHooks('login_hook', $o);
|
||||
src/Module/Logout.php: Addon::callHooks("logging_out");
|
||||
Addon::callHooks('post_local_end', $arr);
|
||||
|
||||
src/Object/Post.php: Addon::callHooks('render_location', $locate);
|
||||
src/Object/Post.php: Addon::callHooks('display_item', $arr);
|
||||
### mod/contacts.php
|
||||
|
||||
src/Core/ACL.php: Addon::callHooks('contact_select_options', $x);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
src/Core/ACL.php: Addon::callHooks('jot_networks', $jotnets);
|
||||
Addon::callHooks('contact_edit_post', $_POST);
|
||||
Addon::callHooks('contact_edit', $arr);
|
||||
|
||||
src/Core/Worker.php: Addon::callHooks("proc_run", $arr);
|
||||
### mod/tagger.php
|
||||
|
||||
src/Util/Emailer.php: Addon::callHooks('emailer_send_prepare', $params);
|
||||
src/Util/Emailer.php: Addon::callHooks("emailer_send", $hookdata);
|
||||
Addon::callHooks('post_local_end', $arr);
|
||||
|
||||
src/Util/Map.php: Addon::callHooks('generate_map', $arr);
|
||||
src/Util/Map.php: Addon::callHooks('generate_named_map', $arr);
|
||||
src/Util/Map.php: Addon::callHooks('Map::getCoordinates', $arr);
|
||||
### mod/lockview.php
|
||||
|
||||
src/Util/Network.php: Addon::callHooks('avatar_lookup', $avatar);
|
||||
Addon::callHooks('lockview_content', $item);
|
||||
|
||||
src/Util/ParseUrl.php: Addon::callHooks("getsiteinfo", $siteinfo);
|
||||
### mod/uexport.php
|
||||
|
||||
src/Protocol/DFRN.php: Addon::callHooks('atom_feed_end', $atom);
|
||||
src/Protocol/DFRN.php: Addon::callHooks('atom_feed_end', $atom);
|
||||
Addon::callHooks('uexport_options', $options);
|
||||
|
||||
### mod/register.php
|
||||
|
||||
Addon::callHooks('register_post', $arr);
|
||||
Addon::callHooks('register_form', $arr);
|
||||
|
||||
### mod/item.php
|
||||
|
||||
Addon::callHooks('post_local_start', $_REQUEST);
|
||||
Addon::callHooks('post_local', $datarray);
|
||||
Addon::callHooks('post_local_end', $datarray);
|
||||
|
||||
### mod/editpost.php
|
||||
|
||||
Addon::callHooks('jot_tool', $jotplugins);
|
||||
|
||||
### src/Network/FKOAuth1.php
|
||||
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
|
||||
### src/Render/FriendicaSmartyEngine.php
|
||||
|
||||
Addon::callHooks("template_vars", $arr);
|
||||
|
||||
### src/Model/Item.php
|
||||
|
||||
Addon::callHooks('post_local', $item);
|
||||
Addon::callHooks('post_remote', $item);
|
||||
Addon::callHooks('post_local_end', $posted_item);
|
||||
Addon::callHooks('post_remote_end', $posted_item);
|
||||
Addon::callHooks('tagged', $arr);
|
||||
Addon::callHooks('post_local_end', $new_item);
|
||||
|
||||
### src/Model/Contact.php
|
||||
|
||||
Addon::callHooks('contact_photo_menu', $args);
|
||||
Addon::callHooks('follow', $arr);
|
||||
|
||||
### src/Model/Profile.php
|
||||
|
||||
Addon::callHooks('profile_sidebar_enter', $profile);
|
||||
Addon::callHooks('profile_sidebar', $arr);
|
||||
Addon::callHooks('profile_tabs', $arr);
|
||||
Addon::callHooks('zrl_init', $arr);
|
||||
|
||||
### src/Model/Event.php
|
||||
|
||||
Addon::callHooks('event_updated', $event['id']);
|
||||
Addon::callHooks("event_created", $event['id']);
|
||||
|
||||
### src/Model/User.php
|
||||
|
||||
Addon::callHooks('register_account', $uid);
|
||||
Addon::callHooks('remove_user', $user);
|
||||
|
||||
### src/Content/Text/BBCode.php
|
||||
|
||||
Addon::callHooks('bbcode', $text);
|
||||
Addon::callHooks('bb2diaspora', $text);
|
||||
|
||||
### src/Content/Text/HTML.php
|
||||
|
||||
Addon::callHooks('html2bbcode', $message);
|
||||
|
||||
### src/Content/Smilies.php
|
||||
|
||||
Addon::callHooks('smilie', $params);
|
||||
|
||||
### src/Content/Feature.php
|
||||
|
||||
Addon::callHooks('isEnabled', $arr);
|
||||
Addon::callHooks('get', $arr);
|
||||
|
||||
### src/Content/ContactSelector.php
|
||||
|
||||
Addon::callHooks('network_to_name', $nets);
|
||||
Addon::callHooks('gender_selector', $select);
|
||||
Addon::callHooks('sexpref_selector', $select);
|
||||
Addon::callHooks('marital_selector', $select);
|
||||
|
||||
### src/Content/OEmbed.php
|
||||
|
||||
Addon::callHooks('oembed_fetch_url', $embedurl, $j);
|
||||
|
||||
### src/Content/Nav.php
|
||||
|
||||
Addon::callHooks('page_header', $a->page['nav']);
|
||||
Addon::callHooks('nav_info', $nav);
|
||||
|
||||
### src/Worker/Directory.php
|
||||
|
||||
Addon::callHooks('globaldir_update', $arr);
|
||||
|
||||
### src/Worker/Notifier.php
|
||||
|
||||
Addon::callHooks('notifier_end', $target_item);
|
||||
|
||||
### src/Worker/Queue.php
|
||||
|
||||
Addon::callHooks('queue_predeliver', $r);
|
||||
Addon::callHooks('queue_deliver', $params);
|
||||
|
||||
### src/Module/Login.php
|
||||
|
||||
Addon::callHooks('authenticate', $addon_auth);
|
||||
Addon::callHooks('login_hook', $o);
|
||||
|
||||
### src/Module/Logout.php
|
||||
|
||||
Addon::callHooks("logging_out");
|
||||
|
||||
### src/Object/Post.php
|
||||
|
||||
Addon::callHooks('render_location', $locate);
|
||||
Addon::callHooks('display_item', $arr);
|
||||
|
||||
### src/Core/ACL.php
|
||||
|
||||
Addon::callHooks('contact_select_options', $x);
|
||||
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
Addon::callHooks('jot_networks', $jotnets);
|
||||
|
||||
### src/Core/Worker.php
|
||||
|
||||
Addon::callHooks("proc_run", $arr);
|
||||
|
||||
### src/Util/Emailer.php
|
||||
|
||||
Addon::callHooks('emailer_send_prepare', $params);
|
||||
Addon::callHooks("emailer_send", $hookdata);
|
||||
|
||||
### src/Util/Map.php
|
||||
|
||||
Addon::callHooks('generate_map', $arr);
|
||||
Addon::callHooks('generate_named_map', $arr);
|
||||
Addon::callHooks('Map::getCoordinates', $arr);
|
||||
|
||||
### src/Util/Network.php
|
||||
|
||||
Addon::callHooks('avatar_lookup', $avatar);
|
||||
|
||||
### src/Util/ParseUrl.php
|
||||
|
||||
Addon::callHooks("getsiteinfo", $siteinfo);
|
||||
|
||||
### src/Protocol/DFRN.php
|
||||
|
||||
Addon::callHooks('atom_feed_end', $atom);
|
||||
Addon::callHooks('atom_feed_end', $atom);
|
||||
|
|
|
@ -2,6 +2,7 @@ Friendica Installation
|
|||
===============
|
||||
|
||||
We've tried very hard to ensure that Friendica will run on commodity hosting platforms - such as those used to host Wordpress blogs and Drupal websites.
|
||||
We offer a manual and an automatic installation.
|
||||
But be aware that Friendica is more than a simple web application.
|
||||
It is a complex communications system which more closely resembles an email server than a web server.
|
||||
For reliability and performance, messages are delivered in the background and are queued for later delivery when sites are down.
|
||||
|
@ -79,24 +80,49 @@ In this case find the [mysqld] section in your my.cnf file and add the line :
|
|||
|
||||
Restart mysql and you should be fine.
|
||||
|
||||
|
||||
### Run the installer
|
||||
### Option A: Run the manual installer
|
||||
|
||||
Point your web browser to the new site and follow the instructions.
|
||||
Please note any error messages and correct these before continuing.
|
||||
|
||||
If you need to specify a port for the connection to the database, you can do so in the host name setting for the database.
|
||||
|
||||
*If* the automated installation fails for any reason, check the following:
|
||||
*If* the manual installation fails for any reason, check the following:
|
||||
|
||||
* Does ".htconfig.php" exist? If not, edit htconfig.php and change the system settings. Rename to .htconfig.php
|
||||
* Is the database is populated? If not, import the contents of "database.sql" with phpmyadmin or mysql command line.
|
||||
* Is the database is populated? If not, import the contents of "database.sql" with phpmyadmin or the mysql command line.
|
||||
|
||||
At this point visit your website again, and register your personal account.
|
||||
Registration errors should all be recoverable automatically.
|
||||
If you get any *critical* failure at this point, it generally indicates the database was not installed correctly.
|
||||
You might wish to move/rename .htconfig.php to another name and empty (called 'dropping') the database tables, so that you can start fresh.
|
||||
|
||||
### Option B: Run the automatic install script
|
||||
|
||||
Open the file htconfig.php in the main Friendica directory with a text editor.
|
||||
Remove the `die('...');` line and edit the lines to suit your installation (MySQL, language, theme etc.).
|
||||
Then save the file (do not rename it).
|
||||
|
||||
Navigate to the main Friendica directory and execute the following command:
|
||||
|
||||
bin/console autoinstall
|
||||
|
||||
Or if you wish to include all optional checks, execute this statement instead:
|
||||
|
||||
bin/console autoinstall -a
|
||||
|
||||
At this point visit your website again, and register your personal account.
|
||||
|
||||
*If* the automatic installation fails for any reason, check the following:
|
||||
|
||||
* Does ".htconfig.php" already exist? If yes, the automatic installation won't start
|
||||
* Are the settings inside "htconfig.php" correct? If not, edit the file again.
|
||||
* Is the empty MySQL-database created? If not, create it.
|
||||
|
||||
For more information during the installation, you can use this command line option
|
||||
|
||||
bin/console autoinstall -v
|
||||
|
||||
### Set up the worker
|
||||
|
||||
Set up a cron job or scheduled task to run the worker once every 5-10 minutes in order to perform background processing.
|
||||
|
|
|
@ -4,35 +4,32 @@ Profiles
|
|||
* [Home](help)
|
||||
|
||||
Friendica has unlimited profiles.
|
||||
You may use different profiles to show different "sides of yourself" to different audiences.
|
||||
You may use different profiles to present different aspects of yourself to different audiences.
|
||||
|
||||
Default / public profile
|
||||
---
|
||||
You always have a profile known as your "default" or "public" profile.
|
||||
This profile is always available to the general public and cannot be hidden (there may be rare exceptions on privately run or disconnected sites).
|
||||
You may, and probably should restrict the information you make available on your public profile.
|
||||
This profile is always available to the general public and usually cannot be hidden.
|
||||
You may, and probably should restrict the personal information you make available on your public profile.
|
||||
|
||||
That said, if you want other friends to be able to find you, it helps to have the following information in your public profile:
|
||||
|
||||
* Your real name
|
||||
* A photo of **you**
|
||||
* Your location on the planet, at least to a country level.
|
||||
* Your location, preferably at least the country.
|
||||
|
||||
Without this basic information, you could get very lonely here.
|
||||
Most people (even your best friends) will not try and connect with somebody that has a fake name or doesn't contain a real photo.
|
||||
|
||||
In addition, if you'd like to meet people that share some general interests with you, please take a moment and add some "Public Keywords" to your profile.
|
||||
In addition, if you'd like to meet people that share some general interests with you, add some "Public Keywords" to your profile.
|
||||
Such as "music, linux, photography" or whatever.
|
||||
You can add as many keywords as you like.
|
||||
|
||||
Your default or public profile is also shown to contacts on other networks, since they do not have the ability to view your private profiles.
|
||||
Only members of the Friendica network can see alternate/ private profiles.
|
||||
|
||||
Alternate profiles
|
||||
Alternate/ private profiles
|
||||
---
|
||||
To create an alternate profile, select "Profiles" from the menu of your Friendica site.
|
||||
You may edit an existing profile, change the profile photo, or create a new profile.
|
||||
You may also create a "clone" of an existing profile if you only wish to change a few items but don't wish to enter all the information again.
|
||||
You may also "clone" your existing profile if you only wish to change a few items but don't wish to enter all the information again.
|
||||
|
||||
To assign a profile to specific persons, select the person from your "Contacts" page and click the pencil "Edit" icon.
|
||||
You will find a dropdown box listing the various profiles available.
|
||||
|
@ -51,17 +48,13 @@ You may also be able to comment directly on posts from while visiting the other
|
|||
There are two settings which allow you to publish your profile to a directory and ensure that it can be found by others.
|
||||
You can change these through settings on the "Settings" page.
|
||||
One setting allows you to publish your profile in the site directory of this Friendica server.
|
||||
Another option (this may have been disabled by the site creator) allows you to publish your profile in the "Global Directory".
|
||||
This is a mega directory which contains people from many other Friendica installations world-wide.
|
||||
Another option (this may have been disabled by the site admin) allows you to publish your profile in a [Global Directory](Making-Friends.md#the-directories).
|
||||
|
||||
If you do not wish to be visible to any of these sites, you may leave your profile unpublished.
|
||||
If you do not wish to be visible to any of these directories, do not published your profile.
|
||||
|
||||
Although you may have multiple profiles, you only have one profile photo.
|
||||
This is intentional.
|
||||
In early tests we experimented with different photos for each profile and found it was very confusing for people.
|
||||
They might see a different picture depending on what website they visited or what conversation they were in, and often alerted them to the fact that other people might be able to see different profiles of you than they could see.
|
||||
|
||||
(But you can use the rich-text information boxes within a profile such as "Tell us about yourself" and link other photos onto the page.)
|
||||
This is intentional; it avoids confusion by potentially seeing different profile pictures of a contact depending on what website you visit or conversation you participate in.
|
||||
You can always can use the free text information boxes within a profile such as "Tell us about yourself" and link other photos for yourself.
|
||||
|
||||
Keywords and Directory Search
|
||||
---
|
||||
|
@ -70,8 +63,7 @@ The search is typically for your nickname or part of your full name.
|
|||
However this search will also match against other profile fields - such as gender, location, "about", work, and education.
|
||||
You may also include "Keywords" in your default profile - which may be used to search for common interests with other members.
|
||||
You have two sets of keywords available - public and private.
|
||||
Private keywords are *not* visible to anybody.
|
||||
You could use these keywords to locate people who share membership in secret societies, or that share a love of fishing (for example) - without making this information visible on your public profile.
|
||||
Private keywords are *not* visible on your profile, but will bring up your profile when matched in a search of the site directory.
|
||||
Public keywords are used in the friend suggestion tool and although they aren't readily visible, they may be seen by viewing the HTML of your profile page.
|
||||
|
||||
Directory searches are also able to use "boolean" logic so that you can search for "+lesbian +Florida" and find those who's sexual preference (or keywords) contain the world "lesbian" and that live in Florida.
|
||||
|
@ -79,7 +71,7 @@ See the section on "Topical Tags" on the [Tags-and-Mentions](help/Tags-and-Menti
|
|||
|
||||
On your Contacts page is a link to "Find People with Shared Interests" (unless your site administrator has disabled the global directory).
|
||||
This will combine both your public and private keywords, and find people in the global directory who have matching and/or similar keywords.
|
||||
(Your private keywords are not identified or stored on the global directory).
|
||||
Private keywords are not identified or stored on the global directory.
|
||||
The more keywords you provide, the more relevant the search results that are returned.
|
||||
These are sorted by relevance.
|
||||
You may discover that you are the first person on the list - because you are very likely the most relevant match for your keywords in the directory.
|
||||
|
|
376
doc/de/Addons.md
376
doc/de/Addons.md
|
@ -191,184 +191,300 @@ Komplette Liste der Hook-Callbacks
|
|||
|
||||
Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Apr-2018 generiert): Bitte schau in die Quellcodes für Details zu Hooks, die oben nicht dokumentiert sind.
|
||||
|
||||
index.php: Addon::callHooks('init_1');
|
||||
index.php: Addon::callHooks('app_menu', $arr);
|
||||
index.php: Addon::callHooks('page_content_top', $a->page['content']);
|
||||
index.php: Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
index.php: Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
index.php: Addon::callHooks($a->module.'_mod_post', $_POST);
|
||||
index.php: Addon::callHooks($a->module.'_mod_afterpost', $placeholder);
|
||||
index.php: Addon::callHooks($a->module.'_mod_content', $arr);
|
||||
index.php: Addon::callHooks($a->module.'_mod_aftercontent', $arr);
|
||||
index.php: Addon::callHooks('page_end', $a->page['content']);
|
||||
### index.php
|
||||
|
||||
include/api.php: Addon::callHooks('logged_in', $a->user);
|
||||
include/api.php: Addon::callHooks('authenticate', $addon_auth);
|
||||
include/api.php: Addon::callHooks('logged_in', $a->user);
|
||||
Addon::callHooks('init_1');
|
||||
Addon::callHooks('app_menu', $arr);
|
||||
Addon::callHooks('page_content_top', $a->page['content']);
|
||||
Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
Addon::callHooks($a->module.'_mod_init', $placeholder);
|
||||
Addon::callHooks($a->module.'_mod_post', $_POST);
|
||||
Addon::callHooks($a->module.'_mod_afterpost', $placeholder);
|
||||
Addon::callHooks($a->module.'_mod_content', $arr);
|
||||
Addon::callHooks($a->module.'_mod_aftercontent', $arr);
|
||||
Addon::callHooks('page_end', $a->page['content']);
|
||||
|
||||
include/enotify.php: Addon::callHooks('enotify', $h);
|
||||
include/enotify.php: Addon::callHooks('enotify_store', $datarray);
|
||||
include/enotify.php: Addon::callHooks('enotify_mail', $datarray);
|
||||
include/enotify.php: Addon::callHooks('check_item_notification', $notification_data);
|
||||
### include/api.php
|
||||
|
||||
include/conversation.php: Addon::callHooks('conversation_start', $cb);
|
||||
include/conversation.php: Addon::callHooks('render_location', $locate);
|
||||
include/conversation.php: Addon::callHooks('display_item', $arr);
|
||||
include/conversation.php: Addon::callHooks('display_item', $arr);
|
||||
include/conversation.php: Addon::callHooks('item_photo_menu', $args);
|
||||
include/conversation.php: Addon::callHooks('jot_tool', $jotplugins);
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
Addon::callHooks('authenticate', $addon_auth);
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
|
||||
include/security.php: Addon::callHooks('logged_in', $a->user);
|
||||
### include/enotify.php
|
||||
|
||||
include/text.php: Addon::callHooks('contact_block_end', $arr);
|
||||
include/text.php: Addon::callHooks('poke_verbs', $arr);
|
||||
include/text.php: Addon::callHooks('prepare_body_init', $item);
|
||||
include/text.php: Addon::callHooks('prepare_body_content_filter', $hook_data);
|
||||
include/text.php: Addon::callHooks('prepare_body', $hook_data);
|
||||
include/text.php: Addon::callHooks('prepare_body_final', $hook_data);
|
||||
Addon::callHooks('enotify', $h);
|
||||
Addon::callHooks('enotify_store', $datarray);
|
||||
Addon::callHooks('enotify_mail', $datarray);
|
||||
Addon::callHooks('check_item_notification', $notification_data);
|
||||
|
||||
include/items.php: Addon::callHooks('page_info_data', $data);
|
||||
### include/conversation.php
|
||||
|
||||
mod/directory.php: Addon::callHooks('directory_item', $arr);
|
||||
Addon::callHooks('conversation_start', $cb);
|
||||
Addon::callHooks('render_location', $locate);
|
||||
Addon::callHooks('display_item', $arr);
|
||||
Addon::callHooks('display_item', $arr);
|
||||
Addon::callHooks('item_photo_menu', $args);
|
||||
Addon::callHooks('jot_tool', $jotplugins);
|
||||
|
||||
mod/xrd.php: Addon::callHooks('personal_xrd', $arr);
|
||||
### include/security.php
|
||||
|
||||
mod/ping.php: Addon::callHooks('network_ping', $arr);
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
|
||||
mod/parse_url.php: Addon::callHooks("parse_link", $arr);
|
||||
### include/text.php
|
||||
|
||||
mod/manage.php: Addon::callHooks('home_init', $ret);
|
||||
Addon::callHooks('contact_block_end', $arr);
|
||||
Addon::callHooks('poke_verbs', $arr);
|
||||
Addon::callHooks('prepare_body_init', $item);
|
||||
Addon::callHooks('prepare_body_content_filter', $hook_data);
|
||||
Addon::callHooks('prepare_body', $hook_data);
|
||||
Addon::callHooks('prepare_body_final', $hook_data);
|
||||
|
||||
mod/acl.php: Addon::callHooks('acl_lookup_end', $results);
|
||||
### include/items.php
|
||||
|
||||
mod/network.php: Addon::callHooks('network_content_init', $arr);
|
||||
mod/network.php: Addon::callHooks('network_tabs', $arr);
|
||||
Addon::callHooks('page_info_data', $data);
|
||||
|
||||
mod/friendica.php: Addon::callHooks('about_hook', $o);
|
||||
mod/subthread.php: Addon::callHooks('post_local_end', $arr);
|
||||
### mod/directory.php
|
||||
|
||||
mod/profiles.php: Addon::callHooks('profile_post', $_POST);
|
||||
mod/profiles.php: Addon::callHooks('profile_edit', $arr);
|
||||
Addon::callHooks('directory_item', $arr);
|
||||
|
||||
mod/settings.php: Addon::callHooks('addon_settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('connector_settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('display_settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('settings_post', $_POST);
|
||||
mod/settings.php: Addon::callHooks('addon_settings', $settings_addons);
|
||||
mod/settings.php: Addon::callHooks('connector_settings', $settings_connectors);
|
||||
mod/settings.php: Addon::callHooks('display_settings', $o);
|
||||
mod/settings.php: Addon::callHooks('settings_form', $o);
|
||||
### mod/xrd.php
|
||||
|
||||
mod/photos.php: Addon::callHooks('photo_post_init', $_POST);
|
||||
mod/photos.php: Addon::callHooks('photo_post_file', $ret);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', $foo);
|
||||
mod/photos.php: Addon::callHooks('photo_post_end', intval($item_id));
|
||||
mod/photos.php: Addon::callHooks('photo_upload_form', $ret);
|
||||
Addon::callHooks('personal_xrd', $arr);
|
||||
|
||||
mod/profile.php: Addon::callHooks('profile_advanced', $o);
|
||||
### mod/ping.php
|
||||
|
||||
mod/home.php: Addon::callHooks('home_init', $ret);
|
||||
mod/home.php: Addon::callHooks("home_content", $content);
|
||||
Addon::callHooks('network_ping', $arr);
|
||||
|
||||
mod/poke.php: Addon::callHooks('post_local_end', $arr);
|
||||
### mod/parse_url.php
|
||||
|
||||
mod/contacts.php: Addon::callHooks('contact_edit_post', $_POST);
|
||||
mod/contacts.php: Addon::callHooks('contact_edit', $arr);
|
||||
Addon::callHooks("parse_link", $arr);
|
||||
|
||||
mod/tagger.php: Addon::callHooks('post_local_end', $arr);
|
||||
### mod/manage.php
|
||||
|
||||
mod/lockview.php: Addon::callHooks('lockview_content', $item);
|
||||
Addon::callHooks('home_init', $ret);
|
||||
|
||||
mod/uexport.php: Addon::callHooks('uexport_options', $options);
|
||||
### mod/acl.php
|
||||
|
||||
mod/register.php: Addon::callHooks('register_post', $arr);
|
||||
mod/register.php: Addon::callHooks('register_form', $arr);
|
||||
Addon::callHooks('acl_lookup_end', $results);
|
||||
|
||||
mod/item.php: Addon::callHooks('post_local_start', $_REQUEST);
|
||||
mod/item.php: Addon::callHooks('post_local', $datarray);
|
||||
mod/item.php: Addon::callHooks('post_local_end', $datarray);
|
||||
### mod/network.php
|
||||
|
||||
mod/editpost.php: Addon::callHooks('jot_tool', $jotplugins);
|
||||
Addon::callHooks('network_content_init', $arr);
|
||||
Addon::callHooks('network_tabs', $arr);
|
||||
|
||||
src/Network/FKOAuth1.php: Addon::callHooks('logged_in', $a->user);
|
||||
### mod/friendica.php
|
||||
|
||||
src/Render/FriendicaSmartyEngine.php: Addon::callHooks("template_vars", $arr);
|
||||
Addon::callHooks('about_hook', $o);
|
||||
|
||||
src/Model/Item.php: Addon::callHooks('post_local', $item);
|
||||
src/Model/Item.php: Addon::callHooks('post_remote', $item);
|
||||
src/Model/Item.php: Addon::callHooks('post_local_end', $posted_item);
|
||||
src/Model/Item.php: Addon::callHooks('post_remote_end', $posted_item);
|
||||
src/Model/Item.php: Addon::callHooks('tagged', $arr);
|
||||
src/Model/Item.php: Addon::callHooks('post_local_end', $new_item);
|
||||
### mod/subthread.php
|
||||
|
||||
src/Model/Contact.php: Addon::callHooks('contact_photo_menu', $args);
|
||||
src/Model/Contact.php: Addon::callHooks('follow', $arr);
|
||||
Addon::callHooks('post_local_end', $arr);
|
||||
|
||||
src/Model/Profile.php: Addon::callHooks('profile_sidebar_enter', $profile);
|
||||
src/Model/Profile.php: Addon::callHooks('profile_sidebar', $arr);
|
||||
src/Model/Profile.php: Addon::callHooks('profile_tabs', $arr);
|
||||
src/Model/Profile.php: Addon::callHooks('zrl_init', $arr);
|
||||
### mod/profiles.php
|
||||
|
||||
src/Model/Event.php: Addon::callHooks('event_updated', $event['id']);
|
||||
src/Model/Event.php: Addon::callHooks("event_created", $event['id']);
|
||||
Addon::callHooks('profile_post', $_POST);
|
||||
Addon::callHooks('profile_edit', $arr);
|
||||
|
||||
src/Model/User.php: Addon::callHooks('register_account', $uid);
|
||||
src/Model/User.php: Addon::callHooks('remove_user', $user);
|
||||
### mod/settings.php
|
||||
|
||||
src/Content/Text/BBCode.php: Addon::callHooks('bbcode', $text);
|
||||
src/Content/Text/BBCode.php: Addon::callHooks('bb2diaspora', $text);
|
||||
Addon::callHooks('addon_settings_post', $_POST);
|
||||
Addon::callHooks('connector_settings_post', $_POST);
|
||||
Addon::callHooks('display_settings_post', $_POST);
|
||||
Addon::callHooks('settings_post', $_POST);
|
||||
Addon::callHooks('addon_settings', $settings_addons);
|
||||
Addon::callHooks('connector_settings', $settings_connectors);
|
||||
Addon::callHooks('display_settings', $o);
|
||||
Addon::callHooks('settings_form', $o);
|
||||
|
||||
src/Content/Text/HTML.php: Addon::callHooks('html2bbcode', $message);
|
||||
### mod/photos.php
|
||||
|
||||
src/Content/Smilies.php: Addon::callHooks('smilie', $params);
|
||||
Addon::callHooks('photo_post_init', $_POST);
|
||||
Addon::callHooks('photo_post_file', $ret);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', $foo);
|
||||
Addon::callHooks('photo_post_end', intval($item_id));
|
||||
Addon::callHooks('photo_upload_form', $ret);
|
||||
|
||||
src/Content/Feature.php: Addon::callHooks('isEnabled', $arr);
|
||||
src/Content/Feature.php: Addon::callHooks('get', $arr);
|
||||
### mod/profile.php
|
||||
|
||||
src/Content/ContactSelector.php: Addon::callHooks('network_to_name', $nets);
|
||||
src/Content/ContactSelector.php: Addon::callHooks('gender_selector', $select);
|
||||
src/Content/ContactSelector.php: Addon::callHooks('sexpref_selector', $select);
|
||||
src/Content/ContactSelector.php: Addon::callHooks('marital_selector', $select);
|
||||
Addon::callHooks('profile_advanced', $o);
|
||||
|
||||
src/Content/OEmbed.php: Addon::callHooks('oembed_fetch_url', $embedurl, $j);
|
||||
### mod/home.php
|
||||
|
||||
src/Content/Nav.php: Addon::callHooks('page_header', $a->page['nav']);
|
||||
src/Content/Nav.php: Addon::callHooks('nav_info', $nav);
|
||||
Addon::callHooks('home_init', $ret);
|
||||
Addon::callHooks("home_content", $content);
|
||||
|
||||
src/Worker/Directory.php: Addon::callHooks('globaldir_update', $arr);
|
||||
src/Worker/Notifier.php: Addon::callHooks('notifier_end', $target_item);
|
||||
src/Worker/Queue.php: Addon::callHooks('queue_predeliver', $r);
|
||||
src/Worker/Queue.php: Addon::callHooks('queue_deliver', $params);
|
||||
### mod/poke.php
|
||||
|
||||
src/Module/Login.php: Addon::callHooks('authenticate', $addon_auth);
|
||||
src/Module/Login.php: Addon::callHooks('login_hook', $o);
|
||||
src/Module/Logout.php: Addon::callHooks("logging_out");
|
||||
Addon::callHooks('post_local_end', $arr);
|
||||
|
||||
src/Object/Post.php: Addon::callHooks('render_location', $locate);
|
||||
src/Object/Post.php: Addon::callHooks('display_item', $arr);
|
||||
### mod/contacts.php
|
||||
|
||||
src/Core/ACL.php: Addon::callHooks('contact_select_options', $x);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
src/Core/ACL.php: Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
src/Core/ACL.php: Addon::callHooks('jot_networks', $jotnets);
|
||||
Addon::callHooks('contact_edit_post', $_POST);
|
||||
Addon::callHooks('contact_edit', $arr);
|
||||
|
||||
src/Core/Worker.php: Addon::callHooks("proc_run", $arr);
|
||||
### mod/tagger.php
|
||||
|
||||
src/Util/Emailer.php: Addon::callHooks('emailer_send_prepare', $params);
|
||||
src/Util/Emailer.php: Addon::callHooks("emailer_send", $hookdata);
|
||||
Addon::callHooks('post_local_end', $arr);
|
||||
|
||||
src/Util/Map.php: Addon::callHooks('generate_map', $arr);
|
||||
src/Util/Map.php: Addon::callHooks('generate_named_map', $arr);
|
||||
src/Util/Map.php: Addon::callHooks('Map::getCoordinates', $arr);
|
||||
### mod/lockview.php
|
||||
|
||||
src/Util/Network.php: Addon::callHooks('avatar_lookup', $avatar);
|
||||
Addon::callHooks('lockview_content', $item);
|
||||
|
||||
src/Util/ParseUrl.php: Addon::callHooks("getsiteinfo", $siteinfo);
|
||||
### mod/uexport.php
|
||||
|
||||
src/Protocol/DFRN.php: Addon::callHooks('atom_feed_end', $atom);
|
||||
src/Protocol/DFRN.php: Addon::callHooks('atom_feed_end', $atom);
|
||||
Addon::callHooks('uexport_options', $options);
|
||||
|
||||
### mod/register.php
|
||||
|
||||
Addon::callHooks('register_post', $arr);
|
||||
Addon::callHooks('register_form', $arr);
|
||||
|
||||
### mod/item.php
|
||||
|
||||
Addon::callHooks('post_local_start', $_REQUEST);
|
||||
Addon::callHooks('post_local', $datarray);
|
||||
Addon::callHooks('post_local_end', $datarray);
|
||||
|
||||
### mod/editpost.php
|
||||
|
||||
Addon::callHooks('jot_tool', $jotplugins);
|
||||
|
||||
### src/Network/FKOAuth1.php
|
||||
|
||||
Addon::callHooks('logged_in', $a->user);
|
||||
|
||||
### src/Render/FriendicaSmartyEngine.php
|
||||
|
||||
Addon::callHooks("template_vars", $arr);
|
||||
|
||||
### src/Model/Item.php
|
||||
|
||||
Addon::callHooks('post_local', $item);
|
||||
Addon::callHooks('post_remote', $item);
|
||||
Addon::callHooks('post_local_end', $posted_item);
|
||||
Addon::callHooks('post_remote_end', $posted_item);
|
||||
Addon::callHooks('tagged', $arr);
|
||||
Addon::callHooks('post_local_end', $new_item);
|
||||
|
||||
### src/Model/Contact.php
|
||||
|
||||
Addon::callHooks('contact_photo_menu', $args);
|
||||
Addon::callHooks('follow', $arr);
|
||||
|
||||
### src/Model/Profile.php
|
||||
|
||||
Addon::callHooks('profile_sidebar_enter', $profile);
|
||||
Addon::callHooks('profile_sidebar', $arr);
|
||||
Addon::callHooks('profile_tabs', $arr);
|
||||
Addon::callHooks('zrl_init', $arr);
|
||||
|
||||
### src/Model/Event.php
|
||||
|
||||
Addon::callHooks('event_updated', $event['id']);
|
||||
Addon::callHooks("event_created", $event['id']);
|
||||
|
||||
### src/Model/User.php
|
||||
|
||||
Addon::callHooks('register_account', $uid);
|
||||
Addon::callHooks('remove_user', $user);
|
||||
|
||||
### src/Content/Text/BBCode.php
|
||||
|
||||
Addon::callHooks('bbcode', $text);
|
||||
Addon::callHooks('bb2diaspora', $text);
|
||||
|
||||
### src/Content/Text/HTML.php
|
||||
|
||||
Addon::callHooks('html2bbcode', $message);
|
||||
|
||||
### src/Content/Smilies.php
|
||||
|
||||
Addon::callHooks('smilie', $params);
|
||||
|
||||
### src/Content/Feature.php
|
||||
|
||||
Addon::callHooks('isEnabled', $arr);
|
||||
Addon::callHooks('get', $arr);
|
||||
|
||||
### src/Content/ContactSelector.php
|
||||
|
||||
Addon::callHooks('network_to_name', $nets);
|
||||
Addon::callHooks('gender_selector', $select);
|
||||
Addon::callHooks('sexpref_selector', $select);
|
||||
Addon::callHooks('marital_selector', $select);
|
||||
|
||||
### src/Content/OEmbed.php
|
||||
|
||||
Addon::callHooks('oembed_fetch_url', $embedurl, $j);
|
||||
|
||||
### src/Content/Nav.php
|
||||
|
||||
Addon::callHooks('page_header', $a->page['nav']);
|
||||
Addon::callHooks('nav_info', $nav);
|
||||
|
||||
### src/Worker/Directory.php
|
||||
|
||||
Addon::callHooks('globaldir_update', $arr);
|
||||
|
||||
### src/Worker/Notifier.php
|
||||
|
||||
Addon::callHooks('notifier_end', $target_item);
|
||||
|
||||
### src/Worker/Queue.php
|
||||
|
||||
Addon::callHooks('queue_predeliver', $r);
|
||||
Addon::callHooks('queue_deliver', $params);
|
||||
|
||||
### src/Module/Login.php
|
||||
|
||||
Addon::callHooks('authenticate', $addon_auth);
|
||||
Addon::callHooks('login_hook', $o);
|
||||
|
||||
### src/Module/Logout.php
|
||||
|
||||
Addon::callHooks("logging_out");
|
||||
|
||||
### src/Object/Post.php
|
||||
|
||||
Addon::callHooks('render_location', $locate);
|
||||
Addon::callHooks('display_item', $arr);
|
||||
|
||||
### src/Core/ACL.php
|
||||
|
||||
Addon::callHooks('contact_select_options', $x);
|
||||
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
Addon::callHooks($a->module.'_pre_'.$selname, $arr);
|
||||
Addon::callHooks($a->module.'_post_'.$selname, $o);
|
||||
Addon::callHooks('jot_networks', $jotnets);
|
||||
|
||||
### src/Core/Worker.php
|
||||
|
||||
Addon::callHooks("proc_run", $arr);
|
||||
|
||||
### src/Util/Emailer.php
|
||||
|
||||
Addon::callHooks('emailer_send_prepare', $params);
|
||||
Addon::callHooks("emailer_send", $hookdata);
|
||||
|
||||
### src/Util/Map.php
|
||||
|
||||
Addon::callHooks('generate_map', $arr);
|
||||
Addon::callHooks('generate_named_map', $arr);
|
||||
Addon::callHooks('Map::getCoordinates', $arr);
|
||||
|
||||
### src/Util/Network.php
|
||||
|
||||
Addon::callHooks('avatar_lookup', $avatar);
|
||||
|
||||
### src/Util/ParseUrl.php
|
||||
|
||||
Addon::callHooks("getsiteinfo", $siteinfo);
|
||||
|
||||
### src/Protocol/DFRN.php
|
||||
|
||||
Addon::callHooks('atom_feed_end', $atom);
|
||||
Addon::callHooks('atom_feed_end', $atom);
|
||||
|
|
|
@ -4,6 +4,7 @@ Friendica Installation
|
|||
* [Zur Startseite der Hilfe](help)
|
||||
|
||||
Wir haben hart daran gearbeitet, um Friendica auf vorgefertigten Hosting-Plattformen zum Laufen zu bringen - solche, auf denen auch Wordpress Blogs und Drupal-Installationen laufen.
|
||||
Wir bieten eine manuelle und eine automatische Installation an.
|
||||
Aber bedenke, dass Friendica mehr als eine einfache Webanwendung ist.
|
||||
Es handelt sich um ein komplexes Kommunikationssystem, das eher an einen Email-Server erinnert als an einen Webserver.
|
||||
Um die Verfügbarkeit und Performance zu gewährleisten, werden Nachrichten im Hintergrund verschickt und gespeichert, um sie später zu verschicken, wenn eine Webseite gerade nicht erreichbar ist.
|
||||
|
@ -11,83 +12,124 @@ Diese Funktionalität benötigt ein wenig mehr als die normalen Blogs.
|
|||
Nicht jeder PHP/MySQL-Hosting-Anbieter kann Friendica unterstützen.
|
||||
Viele hingegen können es. Aber **bitte** prüfe die Voraussetzungen deines Servers vor der Installation.
|
||||
|
||||
Wenn dir Fehler während der Installation auffallen, sag uns bitte über [github](https://github.com/friendica/issues) Bescheid.
|
||||
Wenn dir Fehler während der Installation auffallen, sag uns bitte über [Helper](http://forum.friendi.ca/profile/helpers) oder das [Entwickler Forum](https://forum.friendi.ca/profile/developers) Bescheid oder [erstelle ein Issue](https://github.com/friendica/friendica/issues).
|
||||
Gib uns bitte so viele Infos zu deinem System, wie du kannst, und beschreibe den Fehler mit allen Details und Fehlermeldungen, so dass wir den Fehler zukünftig verhindern können.
|
||||
Aufgrund der großen Anzahl an verschiedenen Betriebssystemen und PHP-Plattformen haben wir nur geringe Kapazitäten, um deine PHP-Installation zu debuggen oder fehlende Module zu ersetzen, aber wir tun unser Bestes, um allgemeine Code-Fehler zu beheben.
|
||||
Falls du noch keinen Friendica-Account hast, kannst du dir einen temporären Account hier erstellen: [tryfriendica.de](https://tryfriendica.de).
|
||||
Darüber kannst du den genannten Forum beitreten.
|
||||
Der Account wird nach 7 Tagen ablaufen, aber du kannst einen Server-Admin fragen, diesen Account länger zu erhalten, sollte das Problem nicht innerhalb dieser Zeit gelöst sein.
|
||||
|
||||
Bevor du anfängst: suche dir einen Domain- oder Subdomainnamen für deinen Server.
|
||||
Dinge verändern sich und einige deiner Freunde haben möglicherweise Probleme, mit dir zu kommunizieren.
|
||||
Wir planen, diese Einschränkung in einer zukünftigen Version zu beheben.
|
||||
|
||||
|
||||
1. Voraussetzungen
|
||||
- Apache mit einer aktiverten mod-rewrite-Funktion und dem Eintrag "Options All", so dass du die lokale .htaccess-Datei nutzen kannst
|
||||
- PHP 5.6+. Je neuer, desto besser.
|
||||
- PHP *Kommandozeilen*-Zugang mit register_argc_argv auf "true" gesetzt in der php.ini-Datei
|
||||
- Curl, GD, PDO, MySQLi, xml, zip und OpenSSL-Erweiterung
|
||||
- etwas in der Art eines Email-Servers oder eines Gateways wie PHP mail()
|
||||
- Das POSIX Modul muss aktiviert sein ([CentOS, RHEL](http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7) haben dies z.B. deaktiviert)
|
||||
- Mysql 5.5.3+
|
||||
- die Möglichkeit, wiederkehrende Aufgaben mit cron (Linux/Mac) oder "Scheduled Tasks" einzustellen (Windows) [Beachte: andere Optionen sind in Abschnitt 7 dieser Dokumentation zu finden]
|
||||
- Installation in einer Top-Level-Domain oder Subdomain (ohne eine Verzeichnis/Pfad-Komponente in der URL) wird bevorzugt. Verzeichnispfade sind für diesen Zweck nicht so günstig und wurden auch nicht ausführlich getestet.
|
||||
Requirements
|
||||
---
|
||||
|
||||
* Apache mit einer aktiverten mod-rewrite-Funktion und dem Eintrag "Options All", so dass du die lokale .htaccess-Datei nutzen kannst
|
||||
* PHP 5.6+ (PHP 7 ist aufgrund der Performance empfohlen)
|
||||
* PHP *Kommandozeilen*-Zugang mit register_argc_argv auf "true" gesetzt in der php.ini-Datei
|
||||
* Curl, GD, PDO, MySQLi, xml, zip und OpenSSL-Erweiterung
|
||||
* Das POSIX Modul muss aktiviert sein ([CentOS, RHEL](http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7) haben dies z.B. deaktiviert)
|
||||
* etwas in der Art eines Email-Servers oder eines Gateways wie PHP mail()
|
||||
* Mysql 5.5.3+ (oder eine äquivalente Alternative: MariaDB, Percona Server etc.)
|
||||
* die Möglichkeit, wiederkehrende Aufgaben mit cron (Linux/Mac) oder "Scheduled Tasks" einzustellen (Windows) [Beachte: andere Optionen sind in Abschnitt 7 dieser Dokumentation zu finden]
|
||||
* Installation in einer Top-Level-Domain oder Subdomain (ohne eine Verzeichnis/Pfad-Komponente in der URL) wird bevorzugt. Verzeichnispfade sind für diesen Zweck nicht so günstig und wurden auch nicht ausführlich getestet.
|
||||
|
||||
[Dreamhost.com bietet ein ausreichendes Hosting-Paket mit den nötigen Features zu einem annehmbaren Preis. Wenn dein Hosting-Anbieter keinen Unix-Zugriff erlaubt, kannst du Schwierigkeiten mit der Einrichtung der Webseite haben.
|
||||
Installation
|
||||
---
|
||||
|
||||
1.1. APT-Pakete
|
||||
- Apache: sudo apt-get install apache2
|
||||
- PHP5: sudo apt-get install php5
|
||||
- PHP5-Zusätzliche Pakete: sudo apt-get install php5-curl php5-gd php5-mysql
|
||||
- MySQL: sudo apt-get install mysql-server
|
||||
### Friendica
|
||||
|
||||
2. Entpacke die Friendica-Daten in das Quellverzeichnis (root) des Dokumentenbereichs deines Webservers.
|
||||
Entpacke die Friendica-Daten in das Quellverzeichnis (root) des Dokumentenbereichs deines Webservers.
|
||||
Wenn du die Möglichkeit hierzu hast, empfehlen wir dir "git" zu nutzen, um die Daten direkt von der Quelle zu klonen, statt die gepackte .tar- oder .zip-Datei zu nutzen.
|
||||
Das macht die Aktualisierung wesentlich einfacher.
|
||||
Der Linux-Code, mit dem man die Dateien direkt in ein Verzeichnis wie "meinewebseite" kopiert, ist
|
||||
|
||||
- Wenn du die Möglichkeit hierzu hast, empfehlen wir dir "git" zu nutzen, um die Daten direkt von der Quelle zu klonen, statt die gepackte .tar- oder .zip-Datei zu nutzen. Das macht die Aktualisierung wesentlich einfacher. Der Linux-Code, mit dem man die Dateien direkt in ein Verzeichnis wie "meinewebseite" kopiert, ist
|
||||
git clone https://github.com/friendica/friendica.git mywebsite
|
||||
cd mywebsite
|
||||
bin/composer.phar install
|
||||
|
||||
`git clone https://github.com/friendica/friendica.git meinewebseite`
|
||||
Stelle sicher, dass der Ordner *view/smarty3* existiert and von dem Webserver-Benutzer beschreibbar ist
|
||||
|
||||
- und dann kannst du die letzten Änderungen immer mit dem folgenden Code holen
|
||||
mkdir view/smarty3
|
||||
chmod 777 view/smarty3
|
||||
|
||||
`cd meinewebseite`
|
||||
`git pull`
|
||||
`bin/composer.phar install`
|
||||
Falls Addons installiert werden sollen: Gehe in den Friendica-Ordner
|
||||
|
||||
- Addons installieren
|
||||
- zunächst solltest du **in** deinem Webseitenordner sein
|
||||
cd mywebsite
|
||||
|
||||
`cd meinewebseite`
|
||||
Und die Addon Repository klonst:
|
||||
|
||||
- dann kannst du das Addon-Verzeichnis seperat kopieren
|
||||
git clone https://github.com/friendica/friendica-addons.git addon
|
||||
|
||||
`git clone https://github.com/friendica/friendica-addons.git addon`
|
||||
Um das Addon-Verzeichnis aktuell zu halten, solltest du in diesem Pfad ein "git pull"-Befehl eintragen
|
||||
|
||||
- Um das Addon-Verzeichnis aktuell zu halten, solltest du in diesem Pfad ein "git pull"-Befehl eintragen
|
||||
cd meinewebseite/addon
|
||||
git pull
|
||||
|
||||
`cd meinewebseite/addon`
|
||||
Wenn du den Verzeichnispfad auf deinen Webserver kopierst, dann stelle sicher, dass du auch die .htaccess kopierst, da "Punkt"-Dateien oft versteckt sind und normalerweise nicht direkt kopiert werden.
|
||||
|
||||
`git pull`
|
||||
### Erselle eine Datenbank
|
||||
|
||||
- Wenn du den Verzeichnispfad auf deinen Webserver kopierst, dann stelle sicher, dass du auch die .htaccess kopierst, da "Punkt"-Dateien oft versteckt sind und normalerweise nicht direkt kopiert werden.
|
||||
|
||||
|
||||
3. Erstelle eine leere Datenbank und notiere alle Zugangsdaten (Adresse der Datenbank, Nutzername, Passwort, Datenbankname).
|
||||
Erstelle eine leere Datenbank und notiere alle Zugangsdaten (Adresse der Datenbank, Nutzername, Passwort, Datenbankname).
|
||||
|
||||
Friendica benötigt die Berechtigungen um neue Felder in dieser Datenbank zu ertellen (create) und zu löschen (delete).
|
||||
|
||||
4. Besuche deine Webseite mit deinem Browser und befolge die Anleitung. Bitte beachte jeden Fehler und korrigiere diese, bevor du fortfährst.
|
||||
Mit neueren Versionen von MySQL (5.7.17+) musst du den `sql_mode` zu `''` (blank) setzen.
|
||||
Benutze diese Einstellung, wenn der Installer nicht in der Lage ist, die Tabellen aufgrund eines Timestamp-Format Problems zu erstellen.
|
||||
Falls dem so ist, finde den `[mysqld]` Bereich in deiner `my.conf` Datei und füge diese Zeile hinzu:
|
||||
|
||||
5. *Wenn* die automatisierte Installation aus irgendeinem Grund fehlschlägt, dann prüfe das Folgende:
|
||||
sql_mode = ''
|
||||
|
||||
- ".htconfig.php" existiert ... wenn nicht, bearbeite die „htconfig.php“ und ändere die Systemeinstellungen. Benenne sie um in „.htconfig.php"
|
||||
“
|
||||
- die Datenbank beinhaltet Daten. ... wenn nicht, importiere den Inhalt der Datei "database.sql" mit phpmyadmin oder per mysql-Kommandozeile.
|
||||
Starte MySQL dann neu und es sollte klappen.
|
||||
|
||||
6. Besuche deine Seite an diesem Punkt wieder und registriere deinen persönlichen Account. Alle Registrierungsprobleme sollten automatisch behebbar sein.
|
||||
Wenn du irgendwelche **kritischen** Fehler zu diesen Zeitpunkt erhalten solltest, deutet das darauf hin, dass die Datenbank nicht korrekt installiert wurde. Du kannst bei Bedarf die Datei .htconfig.php verschieben/umbenennen und die Datenbank leeren (als „Dropping“ bezeichnet), so dass du mit einem sauberen System neu starten kannst.
|
||||
### Option A: Der manuelle Installer
|
||||
|
||||
7. Erstelle einen Cron job oder einen regelmäßigen Task, um den Poller alle 5-10 Minuten im Hintergrund ablaufen zu lassen. Beispiel:
|
||||
Besuche deine Webseite mit deinem Browser und befolge die Anleitung.
|
||||
Bitte beachte jeden Fehler und korrigiere diese, bevor du fortfährst.
|
||||
|
||||
`cd /base/directory; /path/to/php bin/worker.php`
|
||||
Falls du einen Port für die Datenbankverbindung angeben musst, kannst du diesen in der Host-Eingabe Zeile angeben.
|
||||
|
||||
*Wenn* die manuelle Installation aus irgendeinem Grund fehlschlägt, dann prüfe das Folgende:
|
||||
* ".htconfig.php" existiert ... wenn nicht, bearbeite die „htconfig.php“ und ändere die Systemeinstellungen. Benenne sie um in „.htconfig.php".
|
||||
* die Datenbank beinhaltet Daten. ... wenn nicht, importiere den Inhalt der Datei "database.sql" mit phpmyadmin oder per mysql-Kommandozeile.
|
||||
|
||||
Besuche deine Seite an diesem Punkt wieder und registriere deinen persönlichen Account.
|
||||
Alle Registrierungsprobleme sollten automatisch behebbar sein.
|
||||
Wenn du irgendwelche **kritischen** Fehler zu diesen Zeitpunkt erhalten solltest, deutet das darauf hin, dass die Datenbank nicht korrekt installiert wurde.
|
||||
Du kannst bei Bedarf die Datei .htconfig.php verschieben/umbenennen und die Datenbank leeren (als „Dropping“ bezeichnet), so dass du mit einem sauberen System neu starten kannst.
|
||||
|
||||
### Option B: Starte das manuelle Installationsscript
|
||||
|
||||
Öffne die Datei htconfig.php im Friendica-Hauptordner mit einem Text-Editor.
|
||||
Entferne die `die('...');` Zeile und bearbeite die Einstellungen so, das sie zu deinem System passen (MySQL, Sprache, Theme etc.).
|
||||
Dann speichere die Datei (jedoch nicht umbenennen).
|
||||
|
||||
Gehe in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus:
|
||||
|
||||
bin/console autoinstall
|
||||
|
||||
Oder falls du alle optionalen Checks ausfürehn lassen möchtest, benutze diese Option:
|
||||
|
||||
bin/console autoinstall -a
|
||||
|
||||
*Wenn* die automatisierte Installation aus irgendeinem Grund fehlschlägt, dann prüfe das Folgende:
|
||||
* Existiert die `.htconfig.php`? Falls ja, wird die automatisierte Installation nicht gestartet.
|
||||
* Sind Einstellungen in der `.htconfig.php` korrekt? Falls nicht, bitte bearbeite diese Datei erneut.
|
||||
* Ist die leere MySQL-Datenbank erstellt? Falls nicht, erstelle diese.
|
||||
|
||||
Für mehr Informationen kannst du diese Option verwenden:
|
||||
|
||||
bin/console autoinstall -v
|
||||
|
||||
### Einen Worker einrichten
|
||||
|
||||
Erstelle einen Cron job oder einen regelmäßigen Task, um den Poller alle 5-10 Minuten im Hintergrund ablaufen zu lassen.
|
||||
Beispiel:
|
||||
|
||||
cd /base/directory; /path/to/php bin/worker.php
|
||||
|
||||
Ändere "/base/directory" und "/path/to/php" auf deine Systemvorgaben.
|
||||
|
||||
|
@ -102,9 +144,10 @@ Friendica wird nicht korrekt laufen, wenn dieser Schritt nicht erfolgreich abges
|
|||
Falls das Einrichten des cron nicht möglich ist, kannst Du alternativ den "frontend worker" vom Administrationsinterface aus aktivieren.
|
||||
|
||||
### Erstelle einen Backup Plan
|
||||
|
||||
Es werden schlimme Dinge geschehen.
|
||||
Sei es nun ein Hardwareversage oder eine korrumpierte Datenbank.
|
||||
Deshalb solltest du dir nachdem die Installation deines Friendica Knotens abgeschlossen ist einen Backup Plan erstellen.
|
||||
Sei es nun ein Hardwareversagen oder eine kaputte Datenbank.
|
||||
Deshalb solltest du dir, nachdem die Installation deines Friendica Knotens abgeschlossen ist, einen Backup Plan erstellen.
|
||||
|
||||
Die wichtigste Datei ist die `.htconfig.php` im Stammverzeichnis deiner Friendica Installation.
|
||||
Und da alle Daten in der Datenbank gespeichert werden, solltest du einen nicht all zu alten Dump der Friendica Datenbank zur Hand haben, solltest du deinen Knoten wieder herstellen müssen.
|
||||
|
|
|
@ -860,12 +860,15 @@ class dba {
|
|||
*
|
||||
* @param string $table Table name
|
||||
* @param array $conditions Field condition(s)
|
||||
* @param array $options
|
||||
* - cascade: If true we delete records in other tables that depend on the one we're deleting through
|
||||
* relations (default: true)
|
||||
* @param boolean $in_process Internal use: Only do a commit after the last delete
|
||||
* @param array $callstack Internal use: prevent endless loops
|
||||
*
|
||||
* @return boolean|array was the delete successful? When $in_process is set: deletion data
|
||||
*/
|
||||
public static function delete($table, array $conditions, $in_process = false, array &$callstack = [])
|
||||
public static function delete($table, array $conditions, array $options = [], $in_process = false, array &$callstack = [])
|
||||
{
|
||||
if (empty($table) || empty($conditions)) {
|
||||
logger('Table and conditions have to be set');
|
||||
|
@ -888,13 +891,15 @@ class dba {
|
|||
|
||||
$commands[$key] = ['table' => $table, 'conditions' => $conditions];
|
||||
|
||||
$cascade = defaults($options, 'cascade', true);
|
||||
|
||||
// To speed up the whole process we cache the table relations
|
||||
if (count(self::$relation) == 0) {
|
||||
if ($cascade && count(self::$relation) == 0) {
|
||||
self::buildRelationData();
|
||||
}
|
||||
|
||||
// Is there a relation entry for the table?
|
||||
if (isset(self::$relation[$table])) {
|
||||
if ($cascade && isset(self::$relation[$table])) {
|
||||
// We only allow a simple "one field" relation.
|
||||
$field = array_keys(self::$relation[$table])[0];
|
||||
$rel_def = array_values(self::$relation[$table])[0];
|
||||
|
@ -907,7 +912,7 @@ class dba {
|
|||
if ((count($conditions) == 1) && ($field == array_keys($conditions)[0])) {
|
||||
foreach ($rel_def AS $rel_table => $rel_fields) {
|
||||
foreach ($rel_fields AS $rel_field) {
|
||||
$retval = self::delete($rel_table, [$rel_field => array_values($conditions)[0]], true, $callstack);
|
||||
$retval = self::delete($rel_table, [$rel_field => array_values($conditions)[0]], $options, true, $callstack);
|
||||
$commands = array_merge($commands, $retval);
|
||||
}
|
||||
}
|
||||
|
@ -921,7 +926,7 @@ class dba {
|
|||
|
||||
while ($row = self::fetch($data)) {
|
||||
// Now we accumulate the delete commands
|
||||
$retval = self::delete($table, [$field => $row[$field]], true, $callstack);
|
||||
$retval = self::delete($table, [$field => $row[$field]], $options, true, $callstack);
|
||||
$commands = array_merge($commands, $retval);
|
||||
}
|
||||
|
||||
|
@ -968,7 +973,7 @@ class dba {
|
|||
// Split the SQL queries in chunks of 100 values
|
||||
// We do the $i stuff here to make the code better readable
|
||||
$i = $counter[$key_table][$key_condition];
|
||||
if (count($compacted[$key_table][$key_condition][$i]) > 100) {
|
||||
if (isset($compacted[$key_table][$key_condition][$i]) && count($compacted[$key_table][$key_condition][$i]) > 100) {
|
||||
++$i;
|
||||
}
|
||||
|
||||
|
|
|
@ -1411,18 +1411,13 @@ function prepare_body(array &$item, $attach = false, $is_preview = false)
|
|||
function apply_content_filter($html, array $reasons)
|
||||
{
|
||||
if (count($reasons)) {
|
||||
$rnd = random_string(8);
|
||||
$content_filter_html = '<ul class="content-filter-reasons">';
|
||||
foreach ($reasons as $reason) {
|
||||
$content_filter_html .= '<li>' . htmlspecialchars($reason) . '</li>' . PHP_EOL;
|
||||
}
|
||||
$content_filter_html .= '</ul>
|
||||
<p><span id="content-filter-wrap-' . $rnd . '" class="fakelink content-filter-button" onclick=openClose(\'content-filter-' . $rnd . '\'); >' .
|
||||
L10n::t('Click to open/close') .
|
||||
'</span></p>
|
||||
<div id="content-filter-' . $rnd . '" class="content-filter-content" style="display: none;">';
|
||||
|
||||
$html = $content_filter_html . $html . '</div>';
|
||||
$tpl = get_markup_template('wall/content_filter.tpl');
|
||||
$html = replace_macros($tpl, [
|
||||
'$reasons' => $reasons,
|
||||
'$rnd' => random_string(8),
|
||||
'$openclose' => L10n::t('Click to open/close'),
|
||||
'$html' => $html
|
||||
]);
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
|
|
@ -1120,6 +1120,7 @@ function admin_page_site_post(App $a)
|
|||
}
|
||||
Config::set('system', 'language', $language);
|
||||
Config::set('system', 'theme', $theme);
|
||||
Theme::install($theme);
|
||||
|
||||
if ($theme_mobile == '---') {
|
||||
Config::delete('system', 'mobile-theme');
|
||||
|
@ -1262,6 +1263,7 @@ function admin_page_site(App $a)
|
|||
|
||||
/* Community page style */
|
||||
$community_page_style_choices = [
|
||||
CP_NO_INTERNAL_COMMUNITY => L10n::t("No community page for local users"),
|
||||
CP_NO_COMMUNITY_PAGE => L10n::t("No community page"),
|
||||
CP_USERS_ON_SERVER => L10n::t("Public postings from users of this site"),
|
||||
CP_GLOBAL_COMMUNITY => L10n::t("Public postings from the federated network"),
|
||||
|
|
|
@ -23,6 +23,12 @@ function babel_content()
|
|||
'content' => visible_lf($bbcode)
|
||||
];
|
||||
|
||||
$plain = Text\BBCode::toPlaintext($bbcode, false);
|
||||
$results[] = [
|
||||
'title' => L10n::t('BBCode::toPlaintext'),
|
||||
'content' => visible_lf($plain)
|
||||
];
|
||||
|
||||
$html = Text\BBCode::convert($bbcode);
|
||||
$results[] = [
|
||||
'title' => L10n::t("BBCode::convert \x28raw HTML\x29"),
|
||||
|
|
|
@ -30,6 +30,11 @@ function community_content(App $a, $update = 0)
|
|||
|
||||
$page_style = Config::get('system', 'community_page_style');
|
||||
|
||||
if ($page_style == CP_NO_INTERNAL_COMMUNITY) {
|
||||
notice(L10n::t('Access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($a->argc > 1) {
|
||||
$content = $a->argv[1];
|
||||
} else {
|
||||
|
|
|
@ -25,42 +25,13 @@ function dfrn_notify_post(App $a) {
|
|||
$data = json_decode($postdata);
|
||||
if (is_object($data)) {
|
||||
$nick = defaults($a->argv, 1, '');
|
||||
|
||||
$user = dba::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
|
||||
if (!DBM::is_result($user)) {
|
||||
System::httpExit(500);
|
||||
}
|
||||
$msg = Diaspora::decodeRaw($user, $postdata);
|
||||
|
||||
// Check if the user has got this contact
|
||||
$cid = Contact::getIdForURL($msg['author'], $user['uid']);
|
||||
if (!$cid) {
|
||||
// Otherwise there should be a public contact
|
||||
$cid = Contact::getIdForURL($msg['author']);
|
||||
if (!$cid) {
|
||||
logger('Contact not found for address ' . $msg['author']);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
}
|
||||
}
|
||||
|
||||
// We now have some contact, so we fetch it
|
||||
$importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
||||
FROM `contact`
|
||||
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
||||
$cid);
|
||||
|
||||
// This should never fail
|
||||
if (!DBM::is_result($importer)) {
|
||||
logger('Contact not found for address ' . $msg['author']);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
}
|
||||
|
||||
// Set the user id. This is important if this is a public contact
|
||||
$importer['importer_uid'] = $user['uid'];
|
||||
|
||||
// Now we should be able to import it
|
||||
$ret = DFRN::import($msg['message'], $importer);
|
||||
System::xmlExit($ret, 'Done');
|
||||
} else {
|
||||
dfrn_dispatch_private($user, $postdata);
|
||||
} elseif (!dfrn_dispatch_public($postdata)) {
|
||||
require_once 'mod/salmon.php';
|
||||
salmon_post($a, $postdata);
|
||||
}
|
||||
|
@ -91,19 +62,12 @@ function dfrn_notify_post(App $a) {
|
|||
$dfrn_id = substr($dfrn_id, 2);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
|
||||
dbesc($dfrn_id),
|
||||
dbesc($challenge)
|
||||
);
|
||||
if (! DBM::is_result($r)) {
|
||||
logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
|
||||
if (!dba::exists('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge])) {
|
||||
logger('could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
|
||||
System::xmlExit(3, 'Could not match challenge');
|
||||
}
|
||||
|
||||
$r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s'",
|
||||
dbesc($dfrn_id),
|
||||
dbesc($challenge)
|
||||
);
|
||||
dba::delete('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge]);
|
||||
|
||||
// find the local user who owns this relationship.
|
||||
|
||||
|
@ -144,7 +108,7 @@ function dfrn_notify_post(App $a) {
|
|||
);
|
||||
|
||||
if (!DBM::is_result($r)) {
|
||||
logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id);
|
||||
logger('contact not found for dfrn_id ' . $dfrn_id);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
//NOTREACHED
|
||||
}
|
||||
|
@ -153,15 +117,11 @@ function dfrn_notify_post(App $a) {
|
|||
|
||||
$importer = $r[0];
|
||||
|
||||
logger("Remote rino version: ".$rino_remote." for ".$importer["url"], LOGGER_DEBUG);
|
||||
|
||||
if ((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $forum) || ($importer['prv'] != $prv)) {
|
||||
q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d",
|
||||
intval(($writable == (-1)) ? $importer['writable'] : $writable),
|
||||
intval($forum),
|
||||
intval($prv),
|
||||
intval($importer['id'])
|
||||
);
|
||||
$fields = ['writable' => ($writable == (-1)) ? $importer['writable'] : $writable,
|
||||
'forum' => $forum, 'prv' => $prv];
|
||||
dba::update('contact', $fields, ['id' => $importer['id']]);
|
||||
|
||||
if ($writable != (-1)) {
|
||||
$importer['writable'] = $writable;
|
||||
}
|
||||
|
@ -173,8 +133,7 @@ function dfrn_notify_post(App $a) {
|
|||
|
||||
$importer = Contact::updateSslPolicy($importer, $ssl_policy);
|
||||
|
||||
logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']);
|
||||
logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
|
||||
logger('data: ' . $data, LOGGER_DATA);
|
||||
|
||||
if ($dissolve == 1) {
|
||||
// Relationship is dissolved permanently
|
||||
|
@ -186,8 +145,6 @@ function dfrn_notify_post(App $a) {
|
|||
$rino = Config::get('system', 'rino_encrypt');
|
||||
$rino = intval($rino);
|
||||
|
||||
logger("Local rino version: " . $rino, LOGGER_DEBUG);
|
||||
|
||||
if (strlen($key)) {
|
||||
|
||||
// if local rino is lower than remote rino, abort: should not happen!
|
||||
|
@ -198,17 +155,18 @@ function dfrn_notify_post(App $a) {
|
|||
}
|
||||
|
||||
$rawkey = hex2bin(trim($key));
|
||||
logger('rino: md5 raw key: ' . md5($rawkey));
|
||||
logger('rino: md5 raw key: ' . md5($rawkey), LOGGER_DATA);
|
||||
|
||||
$final_key = '';
|
||||
|
||||
if ($dfrn_version >= 2.1) {
|
||||
if ((($importer['duplex']) && strlen($importer['cprvkey'])) || (! strlen($importer['cpubkey']))) {
|
||||
if (($importer['duplex'] && strlen($importer['cprvkey'])) || !strlen($importer['cpubkey'])) {
|
||||
openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
|
||||
} else {
|
||||
openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
|
||||
}
|
||||
} else {
|
||||
if ((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
|
||||
if (($importer['duplex'] && strlen($importer['cpubkey'])) || !strlen($importer['cprvkey'])) {
|
||||
openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
|
||||
} else {
|
||||
openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
|
||||
|
@ -230,12 +188,89 @@ function dfrn_notify_post(App $a) {
|
|||
logger('rino: decrypted data: ' . $data, LOGGER_DATA);
|
||||
}
|
||||
|
||||
logger('Importing post from ' . $importer['addr'] . ' to ' . $importer['nickname'] . ' with the RINO ' . $rino_remote . ' encryption.', LOGGER_DEBUG);
|
||||
|
||||
$ret = DFRN::import($data, $importer);
|
||||
System::xmlExit($ret, 'Processed');
|
||||
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
function dfrn_dispatch_public($postdata)
|
||||
{
|
||||
$msg = Diaspora::decodeRaw([], $postdata);
|
||||
if (!$msg) {
|
||||
// We have to fail silently to be able to hand it over to the salmon parser
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fetch the corresponding public contact
|
||||
$contact = Contact::getDetailsByAddr($msg['author'], 0);
|
||||
if (!$contact) {
|
||||
logger('Contact not found for address ' . $msg['author']);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
}
|
||||
|
||||
// We now have some contact, so we fetch it
|
||||
$importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
||||
FROM `contact`
|
||||
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
||||
$contact['id']);
|
||||
|
||||
$importer['importer_uid'] = 0;
|
||||
|
||||
// This should never fail
|
||||
if (!DBM::is_result($importer)) {
|
||||
logger('Contact not found for address ' . $msg['author']);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
}
|
||||
|
||||
logger('Importing post from ' . $msg['author'] . ' with the public envelope.', LOGGER_DEBUG);
|
||||
|
||||
// Now we should be able to import it
|
||||
$ret = DFRN::import($msg['message'], $importer);
|
||||
System::xmlExit($ret, 'Done');
|
||||
}
|
||||
|
||||
function dfrn_dispatch_private($user, $postdata)
|
||||
{
|
||||
$msg = Diaspora::decodeRaw($user, $postdata);
|
||||
if (!$msg) {
|
||||
System::xmlExit(4, 'Unable to parse message');
|
||||
}
|
||||
|
||||
// Check if the user has got this contact
|
||||
$cid = Contact::getIdForURL($msg['author'], $user['uid']);
|
||||
if (!$cid) {
|
||||
// Otherwise there should be a public contact
|
||||
$cid = Contact::getIdForURL($msg['author']);
|
||||
if (!$cid) {
|
||||
logger('Contact not found for address ' . $msg['author']);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
}
|
||||
}
|
||||
|
||||
// We now have some contact, so we fetch it
|
||||
$importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
||||
FROM `contact`
|
||||
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
||||
$cid);
|
||||
|
||||
// This should never fail
|
||||
if (!DBM::is_result($importer)) {
|
||||
logger('Contact not found for address ' . $msg['author']);
|
||||
System::xmlExit(3, 'Contact not found');
|
||||
}
|
||||
|
||||
// Set the user id. This is important if this is a public contact
|
||||
$importer['importer_uid'] = $user['uid'];
|
||||
|
||||
logger('Importing post from ' . $msg['author'] . ' to ' . $user['nickname'] . ' with the private envelope.', LOGGER_DEBUG);
|
||||
|
||||
// Now we should be able to import it
|
||||
$ret = DFRN::import($msg['message'], $importer);
|
||||
System::xmlExit($ret, 'Done');
|
||||
}
|
||||
|
||||
function dfrn_notify_content(App $a) {
|
||||
|
||||
|
@ -252,7 +287,7 @@ function dfrn_notify_content(App $a) {
|
|||
$type = "";
|
||||
$last_update = "";
|
||||
|
||||
logger('dfrn_notify: new notification dfrn_id=' . $dfrn_id);
|
||||
logger('new notification dfrn_id=' . $dfrn_id);
|
||||
|
||||
$direction = (-1);
|
||||
if (strpos($dfrn_id,':') == 1) {
|
||||
|
@ -264,18 +299,13 @@ function dfrn_notify_content(App $a) {
|
|||
|
||||
$status = 0;
|
||||
|
||||
$r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
|
||||
dba::delete('challenge', ["`expire` < ?", time()]);
|
||||
|
||||
$r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` )
|
||||
VALUES( '%s', '%s', %d, '%s', '%s' ) ",
|
||||
dbesc($hash),
|
||||
dbesc($dfrn_id),
|
||||
intval(time() + 90 ),
|
||||
dbesc($type),
|
||||
dbesc($last_update)
|
||||
);
|
||||
$fields = ['challenge' => $hash, 'dfrn-id' => $dfrn_id, 'expire' => time() + 90,
|
||||
'type' => $type, 'last_update' => $last_update];
|
||||
dba::insert('challenge', $fields);
|
||||
|
||||
logger('dfrn_notify: challenge=' . $hash, LOGGER_DEBUG);
|
||||
logger('challenge=' . $hash, LOGGER_DATA);
|
||||
|
||||
$sql_extra = '';
|
||||
switch($direction) {
|
||||
|
@ -306,7 +336,7 @@ function dfrn_notify_content(App $a) {
|
|||
$status = 1;
|
||||
}
|
||||
|
||||
logger("Remote rino version: ".$rino_remote." for ".$r[0]["url"], LOGGER_DEBUG);
|
||||
logger("Remote rino version: ".$rino_remote." for ".$r[0]["url"], LOGGER_DATA);
|
||||
|
||||
$challenge = '';
|
||||
$encrypted_id = '';
|
||||
|
@ -316,7 +346,7 @@ function dfrn_notify_content(App $a) {
|
|||
$pub_key = trim($r[0]['pubkey']);
|
||||
$dplx = intval($r[0]['duplex']);
|
||||
|
||||
if ((($dplx) && (strlen($prv_key))) || ((strlen($prv_key)) && (!(strlen($pub_key))))) {
|
||||
if (($dplx && strlen($prv_key)) || (strlen($prv_key) && !strlen($pub_key))) {
|
||||
openssl_private_encrypt($hash, $challenge, $prv_key);
|
||||
openssl_private_encrypt($id_str, $encrypted_id, $prv_key);
|
||||
} elseif (strlen($pub_key)) {
|
||||
|
@ -334,7 +364,7 @@ function dfrn_notify_content(App $a) {
|
|||
$rino = Config::get('system', 'rino_encrypt');
|
||||
$rino = intval($rino);
|
||||
|
||||
logger("Local rino version: ". $rino, LOGGER_DEBUG);
|
||||
logger("Local rino version: ". $rino, LOGGER_DATA);
|
||||
|
||||
// if requested rino is lower than enabled local rino, lower local rino version
|
||||
// if requested rino is higher than enabled local rino, reply with local rino
|
||||
|
@ -342,7 +372,7 @@ function dfrn_notify_content(App $a) {
|
|||
$rino = $rino_remote;
|
||||
}
|
||||
|
||||
if((($r[0]['rel']) && ($r[0]['rel'] != CONTACT_IS_SHARING)) || ($r[0]['page-flags'] == PAGE_COMMUNITY)) {
|
||||
if (($r[0]['rel'] && ($r[0]['rel'] != CONTACT_IS_SHARING)) || ($r[0]['page-flags'] == PAGE_COMMUNITY)) {
|
||||
$perm = 'rw';
|
||||
} else {
|
||||
$perm = 'r';
|
||||
|
@ -362,5 +392,4 @@ function dfrn_notify_content(App $a) {
|
|||
|
||||
killme();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -122,8 +122,8 @@ function friendica_content(App $a)
|
|||
$o .= '<p>'.L10n::t('Read about the <a href="%1$s/tos">Terms of Service</a> of this node.', System::baseurl()).'</p>';
|
||||
}
|
||||
|
||||
$blocklist = Config::get('system', 'blocklist');
|
||||
if (count($blocklist)) {
|
||||
$blocklist = Config::get('system', 'blocklist', []);
|
||||
if (!empty($blocklist)) {
|
||||
$o .= '<div id="about_blocklist"><p>' . L10n::t('On this server the following remote servers are blocked.') . '</p>' . PHP_EOL;
|
||||
$o .= '<table class="table"><thead><tr><th>' . L10n::t('Blocked domain') . '</th><th>' . L10n::t('Reason for the block') . '</th></thead><tbody>' . PHP_EOL;
|
||||
foreach ($blocklist as $b) {
|
||||
|
|
|
@ -51,7 +51,7 @@ function install_post(App $a) {
|
|||
$phpath = notags(trim($_POST['phpath']));
|
||||
|
||||
require_once("include/dba.php");
|
||||
if (!dba::connect($dbhost, $dbuser, $dbpass, $dbdata)) {
|
||||
if (!dba::connect($dbhost, $dbuser, $dbpass, $dbdata, true)) {
|
||||
$a->data['db_conn_failed'] = true;
|
||||
}
|
||||
|
||||
|
@ -140,11 +140,37 @@ function install_content(App $a) {
|
|||
switch ($install_wizard_pass) {
|
||||
case 1: { // System check
|
||||
|
||||
|
||||
$checks = [];
|
||||
|
||||
check_funcs($checks);
|
||||
|
||||
check_imagik($checks);
|
||||
|
||||
check_htconfig($checks);
|
||||
|
||||
check_smarty3($checks);
|
||||
|
||||
check_keys($checks);
|
||||
|
||||
if (x($_POST, 'phpath')) {
|
||||
$phpath = notags(trim($_POST['phpath']));
|
||||
}
|
||||
|
||||
list($checks, $checkspassed) = Install::check($phpath);
|
||||
check_php($phpath, $checks);
|
||||
|
||||
check_htaccess($checks);
|
||||
|
||||
/// @TODO Maybe move this out?
|
||||
function check_passed($v, $c) {
|
||||
if ($c['required']) {
|
||||
$v = $v && $c['status'];
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
$checkspassed = array_reduce($checks, "check_passed", true);
|
||||
|
||||
|
||||
|
||||
$tpl = get_markup_template('install_checks.tpl');
|
||||
$o .= replace_macros($tpl, [
|
||||
|
|
|
@ -144,14 +144,13 @@ function invite_content(App $a) {
|
|||
|
||||
$o = replace_macros($tpl, [
|
||||
'$form_security_token' => get_form_security_token("send_invite"),
|
||||
'$invite' => L10n::t('Send invitations'),
|
||||
'$addr_text' => L10n::t('Enter email addresses, one per line:'),
|
||||
'$msg_text' => L10n::t('Your message:'),
|
||||
'$default_message' => L10n::t('You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web.') . "\r\n" . "\r\n"
|
||||
'$title' => L10n::t('Send invitations'),
|
||||
'$recipients' => ['recipients', L10n::t('Enter email addresses, one per line:')],
|
||||
'$message' => ['message', L10n::t('Your message:'),L10n::t('You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web.') . "\r\n" . "\r\n"
|
||||
. $linktxt
|
||||
. "\r\n" . "\r\n" . (($invonly) ? L10n::t('You will need to supply this invitation code: $invite_code') . "\r\n" . "\r\n" : '') .L10n::t('Once you have registered, please connect with me via my profile page at:')
|
||||
. "\r\n" . "\r\n" . System::baseUrl() . '/profile/' . $a->user['nickname']
|
||||
. "\r\n" . "\r\n" . L10n::t('For more information about the Friendica project and why we feel it is important, please visit http://friendi.ca') . "\r\n" . "\r\n" ,
|
||||
. "\r\n" . "\r\n" . L10n::t('For more information about the Friendica project and why we feel it is important, please visit http://friendi.ca') . "\r\n" . "\r\n"],
|
||||
'$submit' => L10n::t('Submit')
|
||||
]);
|
||||
|
||||
|
|
|
@ -23,9 +23,18 @@ function noscrape_init(App $a)
|
|||
|
||||
Profile::load($a, $which, $profile);
|
||||
|
||||
$json_info = [
|
||||
'addr' => $a->profile['addr'],
|
||||
'nick' => $which,
|
||||
'guid' => $a->profile['guid'],
|
||||
'key' => $a->profile['pubkey'],
|
||||
'homepage' => System::baseUrl()."/profile/{$which}",
|
||||
'comm' => ($a->profile['account-type'] == ACCOUNT_TYPE_COMMUNITY),
|
||||
];
|
||||
|
||||
if (!$a->profile['net-publish'] || $a->profile['hidewall']) {
|
||||
header('Content-type: application/json; charset=utf-8');
|
||||
$json_info = ["hide" => true];
|
||||
$json_info["hide"] = true;
|
||||
echo json_encode($json_info);
|
||||
exit;
|
||||
}
|
||||
|
@ -36,17 +45,9 @@ function noscrape_init(App $a)
|
|||
|
||||
$contactPhoto = dba::selectFirst('contact', ['photo'], ['self' => true, 'uid' => $a->profile['uid']]);
|
||||
|
||||
$json_info = [
|
||||
'fn' => $a->profile['name'],
|
||||
'addr' => $a->profile['addr'],
|
||||
'nick' => $which,
|
||||
'guid' => $a->profile['guid'],
|
||||
'key' => $a->profile['pubkey'],
|
||||
'homepage' => System::baseUrl()."/profile/{$which}",
|
||||
'comm' => (x($a->profile, 'page-flags')) && ($a->profile['page-flags'] == PAGE_COMMUNITY),
|
||||
'photo' => $contactPhoto["photo"],
|
||||
'tags' => $keywords
|
||||
];
|
||||
$json_info['fn'] = $a->profile['name'];
|
||||
$json_info['photo'] = $contactPhoto["photo"];
|
||||
$json_info['tags'] = $keywords;
|
||||
|
||||
if (is_array($a->profile) && !$a->profile['hide-friends']) {
|
||||
/// @todo What should this value tell us?
|
||||
|
|
|
@ -191,7 +191,7 @@ function profile_content(App $a, $update = 0)
|
|||
$o .= Widget::commonFriendsVisitor($a->profile['profile_uid']);
|
||||
|
||||
if (x($_SESSION, 'new_member') && $is_owner) {
|
||||
$o .= '<a href="newmember" id="newmember-tips" style="font-size: 1.2em;"><b>' . L10n::t('Tips for New Members') . '</b></a>' . EOL;
|
||||
$o .= '<div id="newmember-tips"><a href="newmember"><b>' . L10n::t('Tips for New Members') . '</b></a></div>';
|
||||
}
|
||||
|
||||
$commpage = $a->profile['page-flags'] == PAGE_COMMUNITY;
|
||||
|
|
|
@ -12,6 +12,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\PConfig;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Core\Theme;
|
||||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBM;
|
||||
use Friendica\Model\Contact;
|
||||
|
@ -354,6 +355,7 @@ function settings_post(App $a)
|
|||
theme_post($a);
|
||||
}
|
||||
}
|
||||
Theme::install($theme);
|
||||
|
||||
$r = q("UPDATE `user` SET `theme` = '%s' WHERE `uid` = %d",
|
||||
dbesc($theme),
|
||||
|
|
|
@ -49,7 +49,7 @@ class ForumManager
|
|||
"SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro`, `contact`.`thumb`
|
||||
FROM `contact`
|
||||
WHERE `network`= 'dfrn' AND $select AND `uid` = ?
|
||||
AND NOT `blocked` AND NOT `hidden` AND NOT `pending` AND NOT `archive`
|
||||
AND NOT `blocked` AND NOT `pending` AND NOT `archive`
|
||||
AND `success_update` > `failure_update`
|
||||
$order ",
|
||||
$uid
|
||||
|
|
|
@ -161,7 +161,8 @@ class Nav
|
|||
}
|
||||
}
|
||||
|
||||
if (local_user() || Config::get('system', 'community_page_style') != CP_NO_COMMUNITY_PAGE) {
|
||||
if ((local_user() || Config::get('system', 'community_page_style') != CP_NO_COMMUNITY_PAGE) &&
|
||||
!(Config::get('system', 'community_page_style') == CP_NO_INTERNAL_COMMUNITY)) {
|
||||
$nav['community'] = ['community', L10n::t('Community'), '', L10n::t('Conversations on this and other servers')];
|
||||
}
|
||||
|
||||
|
@ -180,17 +181,13 @@ class Nav
|
|||
|
||||
$nav['home'] = ['profile/' . $a->user['nickname'], L10n::t('Home'), '', L10n::t('Your posts and conversations')];
|
||||
|
||||
if (in_array($_SESSION['page_flags'], [PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE, PAGE_PRVGROUP])) {
|
||||
// only show friend requests for normal pages. Other page types have automatic friendship.
|
||||
if (in_array($_SESSION['page_flags'], [PAGE_NORMAL, PAGE_SOAPBOX, PAGE_PRVGROUP])) {
|
||||
// Don't show notifications for public communities
|
||||
if ($_SESSION['page_flags'] != PAGE_COMMUNITY) {
|
||||
$nav['introductions'] = ['notifications/intros', L10n::t('Introductions'), '', L10n::t('Friend Requests')];
|
||||
}
|
||||
if (in_array($_SESSION['page_flags'], [PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE])) {
|
||||
$nav['notifications'] = ['notifications', L10n::t('Notifications'), '', L10n::t('Notifications')];
|
||||
$nav['notifications']['all'] = ['notifications/system', L10n::t('See all notifications'), '', ''];
|
||||
$nav['notifications']['mark'] = ['', L10n::t('Mark as seen'), '', L10n::t('Mark all system notifications seen')];
|
||||
}
|
||||
}
|
||||
|
||||
$nav['messages'] = ['message', L10n::t('Messages'), '', L10n::t('Private mail')];
|
||||
$nav['messages']['inbox'] = ['message', L10n::t('Inbox'), '', L10n::t('Inbox')];
|
||||
|
|
|
@ -343,159 +343,20 @@ class BBCode extends BaseObject
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a message into plaintext for connectors to other networks
|
||||
* @brief Converts a BBCode text into plaintext
|
||||
*
|
||||
* @param array $b The message array that is about to be posted
|
||||
* @param int $limit The maximum number of characters when posting to that network
|
||||
* @param bool $includedlinks Has an attached link to be included into the message?
|
||||
* @param int $htmlmode This triggers the behaviour of the bbcode conversion
|
||||
* @param string $target_network Name of the network where the post should go to.
|
||||
* @param bool $keep_urls Whether to keep URLs in the resulting plaintext
|
||||
*
|
||||
* @return string The converted message
|
||||
* @return string
|
||||
*/
|
||||
public static function toPlaintext($b, $limit = 0, $includedlinks = false, $htmlmode = 2, $target_network = "")
|
||||
public static function toPlaintext($text, $keep_urls = true)
|
||||
{
|
||||
// Remove the hash tags
|
||||
$URLSearchString = "^\[\]";
|
||||
$body = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $b["body"]);
|
||||
|
||||
// Add an URL element if the text contains a raw link
|
||||
$body = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url]$2[/url]', $body);
|
||||
|
||||
// Remove the abstract
|
||||
$body = self::stripAbstract($body);
|
||||
|
||||
// At first look at data that is attached via "type-..." stuff
|
||||
// This will hopefully replaced with a dedicated bbcode later
|
||||
//$post = self::getAttachedData($b["body"]);
|
||||
$post = self::getAttachedData($body, $b);
|
||||
|
||||
if (($b["title"] != "") && ($post["text"] != "")) {
|
||||
$post["text"] = trim($b["title"]."\n\n".$post["text"]);
|
||||
} elseif ($b["title"] != "") {
|
||||
$post["text"] = trim($b["title"]);
|
||||
$naked_text = preg_replace('/\[(.+?)\]/','', $text);
|
||||
if (!$keep_urls) {
|
||||
$naked_text = preg_replace('#https?\://[^\s<]+[^\s\.\)]#i', '', $naked_text);
|
||||
}
|
||||
|
||||
$abstract = "";
|
||||
|
||||
// Fetch the abstract from the given target network
|
||||
if ($target_network != "") {
|
||||
$default_abstract = self::getAbstract($b["body"]);
|
||||
$abstract = self::getAbstract($b["body"], $target_network);
|
||||
|
||||
// If we post to a network with no limit we only fetch
|
||||
// an abstract exactly for this network
|
||||
if (($limit == 0) && ($abstract == $default_abstract)) {
|
||||
$abstract = "";
|
||||
}
|
||||
} else {// Try to guess the correct target network
|
||||
switch ($htmlmode) {
|
||||
case 8:
|
||||
$abstract = self::getAbstract($b["body"], NETWORK_TWITTER);
|
||||
break;
|
||||
case 7:
|
||||
$abstract = self::getAbstract($b["body"], NETWORK_STATUSNET);
|
||||
break;
|
||||
case 6:
|
||||
$abstract = self::getAbstract($b["body"], NETWORK_APPNET);
|
||||
break;
|
||||
default: // We don't know the exact target.
|
||||
// We fetch an abstract since there is a posting limit.
|
||||
if ($limit > 0) {
|
||||
$abstract = self::getAbstract($b["body"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($abstract != "") {
|
||||
$post["text"] = $abstract;
|
||||
|
||||
if ($post["type"] == "text") {
|
||||
$post["type"] = "link";
|
||||
$post["url"] = $b["plink"];
|
||||
}
|
||||
}
|
||||
|
||||
$html = self::convert($post["text"].$post["after"], false, $htmlmode);
|
||||
$msg = HTML::toPlaintext($html, 0, true);
|
||||
$msg = trim(html_entity_decode($msg, ENT_QUOTES, 'UTF-8'));
|
||||
|
||||
$link = "";
|
||||
if ($includedlinks) {
|
||||
if ($post["type"] == "link") {
|
||||
$link = $post["url"];
|
||||
} elseif ($post["type"] == "text") {
|
||||
$link = $post["url"];
|
||||
} elseif ($post["type"] == "video") {
|
||||
$link = $post["url"];
|
||||
} elseif ($post["type"] == "photo") {
|
||||
$link = $post["image"];
|
||||
}
|
||||
|
||||
if (($msg == "") && isset($post["title"])) {
|
||||
$msg = trim($post["title"]);
|
||||
}
|
||||
|
||||
if (($msg == "") && isset($post["description"])) {
|
||||
$msg = trim($post["description"]);
|
||||
}
|
||||
|
||||
// If the link is already contained in the post, then it neeedn't to be added again
|
||||
// But: if the link is beyond the limit, then it has to be added.
|
||||
if (($link != "") && strstr($msg, $link)) {
|
||||
$pos = strpos($msg, $link);
|
||||
|
||||
// Will the text be shortened in the link?
|
||||
// Or is the link the last item in the post?
|
||||
if (($limit > 0) && ($pos < $limit) && (($pos + 23 > $limit) || ($pos + strlen($link) == strlen($msg)))) {
|
||||
$msg = trim(str_replace($link, "", $msg));
|
||||
} elseif (($limit == 0) || ($pos < $limit)) {
|
||||
// The limit has to be increased since it will be shortened - but not now
|
||||
// Only do it with Twitter (htmlmode = 8)
|
||||
if (($limit > 0) && (strlen($link) > 23) && ($htmlmode == 8)) {
|
||||
$limit = $limit - 23 + strlen($link);
|
||||
}
|
||||
|
||||
$link = "";
|
||||
|
||||
if ($post["type"] == "text") {
|
||||
unset($post["url"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($limit > 0) {
|
||||
// Reduce multiple spaces
|
||||
// When posted to a network with limited space, we try to gain space where possible
|
||||
while (strpos($msg, " ") !== false) {
|
||||
$msg = str_replace(" ", " ", $msg);
|
||||
}
|
||||
|
||||
// Twitter is using its own limiter, so we always assume that shortened links will have this length
|
||||
if (iconv_strlen($link, "UTF-8") > 0) {
|
||||
$limit = $limit - 23;
|
||||
}
|
||||
|
||||
if (iconv_strlen($msg, "UTF-8") > $limit) {
|
||||
if (($post["type"] == "text") && isset($post["url"])) {
|
||||
$post["url"] = $b["plink"];
|
||||
} elseif (!isset($post["url"])) {
|
||||
$limit = $limit - 23;
|
||||
$post["url"] = $b["plink"];
|
||||
// Which purpose has this line? It is now uncommented, but left as a reminder
|
||||
//} elseif (strpos($b["body"], "[share") !== false) {
|
||||
// $post["url"] = $b["plink"];
|
||||
} elseif (PConfig::get($b["uid"], "system", "no_intelligent_shortening")) {
|
||||
$post["url"] = $b["plink"];
|
||||
}
|
||||
$msg = Plaintext::shorten($msg, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
$post["text"] = trim($msg);
|
||||
|
||||
return($post);
|
||||
return $naked_text;
|
||||
}
|
||||
|
||||
public static function scaleExternalImages($srctext, $include_link = true, $scale_replace = false)
|
||||
|
@ -1947,7 +1808,7 @@ class BBCode extends BaseObject
|
|||
* @param string $addon The addon for which the abstract is meant for
|
||||
* @return string The abstract
|
||||
*/
|
||||
private static function getAbstract($text, $addon = "")
|
||||
public static function getAbstract($text, $addon = "")
|
||||
{
|
||||
$abstract = "";
|
||||
$abstracts = [];
|
||||
|
|
|
@ -55,19 +55,24 @@ class Widget
|
|||
}
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('peoplefind.tpl'), array(
|
||||
'$findpeople' => L10n::t('Find People'),
|
||||
'$desc' => L10n::t('Enter name or interest'),
|
||||
'$label' => L10n::t('Connect/Follow'),
|
||||
'$hint' => L10n::t('Examples: Robert Morgenstein, Fishing'),
|
||||
'$findthem' => L10n::t('Find'),
|
||||
'$suggest' => L10n::t('Friend Suggestions'),
|
||||
'$similar' => L10n::t('Similar Interests'),
|
||||
'$random' => L10n::t('Random Profile'),
|
||||
'$inv' => L10n::t('Invite Friends'),
|
||||
'$directory' => L10n::t('View Global Directory'),
|
||||
'$global_dir' => $global_dir
|
||||
));
|
||||
$nv = [];
|
||||
$nv['findpeople'] = L10n::t('Find People');
|
||||
$nv['desc'] = L10n::t('Enter name or interest');
|
||||
$nv['label'] = L10n::t('Connect/Follow');
|
||||
$nv['hint'] = L10n::t('Examples: Robert Morgenstein, Fishing');
|
||||
$nv['findthem'] = L10n::t('Find');
|
||||
$nv['suggest'] = L10n::t('Friend Suggestions');
|
||||
$nv['similar'] = L10n::t('Similar Interests');
|
||||
$nv['random'] = L10n::t('Random Profile');
|
||||
$nv['inv'] = L10n::t('Invite Friends');
|
||||
$nv['directory'] = L10n::t('Global Directory');
|
||||
$nv['global_dir'] = $global_dir;
|
||||
$nv['local_directory'] = L10n::t('Local Directory');
|
||||
|
||||
$aside = [];
|
||||
$aside['$nv'] = $nv;
|
||||
|
||||
return replace_macros(get_markup_template('peoplefind.tpl'), $aside);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -246,7 +246,7 @@ class Addon
|
|||
} else {
|
||||
// remove orphan hooks
|
||||
$condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]];
|
||||
dba::delete('hook', $condition);
|
||||
dba::delete('hook', $condition, ['cascade' => false]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ class Console extends \Asika\SimpleConsole\Console
|
|||
'extract' => __NAMESPACE__ . '\Console\Extract',
|
||||
'globalcommunityblock' => __NAMESPACE__ . '\Console\GlobalCommunityBlock',
|
||||
'globalcommunitysilence' => __NAMESPACE__ . '\Console\GlobalCommunitySilence',
|
||||
'archivecontact' => __NAMESPACE__ . '\Console\ArchiveContact',
|
||||
'autoinstall' => __NAMESPACE__ . '\Console\AutomaticInstallation',
|
||||
'maintenance' => __NAMESPACE__ . '\Console\Maintenance',
|
||||
'newpassword' => __NAMESPACE__ . '\Console\NewPassword',
|
||||
|
@ -42,6 +43,7 @@ Commands:
|
|||
extract Generate translation string file for the Friendica project (deprecated)
|
||||
globalcommunityblock Block remote profile from interacting with this node
|
||||
globalcommunitysilence Silence remote profile from global community page
|
||||
archivecontact Archive a contact when you know that it isn't existing anymore
|
||||
help Show help about a command, e.g (bin/console help config)
|
||||
autoinstall Starts automatic installation of friendica based on values from htconfig.php
|
||||
maintenance Set maintenance mode for this node
|
||||
|
|
79
src/Core/Console/ArchiveContact.php
Normal file
79
src/Core/Console/ArchiveContact.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Console;
|
||||
|
||||
use Friendica\Core\L10n;
|
||||
use dba;
|
||||
|
||||
/**
|
||||
* @brief tool to archive a contact on the server
|
||||
*
|
||||
* With this tool you can archive a contact when you know that it isn't existing anymore.
|
||||
* Normally this does happen automatically after a few days.
|
||||
*
|
||||
* License: AGPLv3 or later, same as Friendica
|
||||
*
|
||||
*/
|
||||
class ArchiveContact extends \Asika\SimpleConsole\Console
|
||||
{
|
||||
protected $helpOptions = ['h', 'help', '?'];
|
||||
|
||||
protected function getHelp()
|
||||
{
|
||||
$help = <<<HELP
|
||||
console archivecontact - archive a contact
|
||||
Usage
|
||||
bin/console archivecontact <profile_url> [-h|--help|-?] [-v]
|
||||
|
||||
Description
|
||||
Archive a contact when you know that it isn't existing anymore. Normally this does happen automatically after a few days.
|
||||
|
||||
Options
|
||||
-h|--help|-? Show help information
|
||||
-v Show more debug information.
|
||||
HELP;
|
||||
return $help;
|
||||
}
|
||||
|
||||
protected function doExecute()
|
||||
{
|
||||
$a = get_app();
|
||||
|
||||
if ($this->getOption('v')) {
|
||||
$this->out('Class: ' . __CLASS__);
|
||||
$this->out('Arguments: ' . var_export($this->args, true));
|
||||
$this->out('Options: ' . var_export($this->options, true));
|
||||
}
|
||||
|
||||
if (count($this->args) == 0) {
|
||||
$this->out($this->getHelp());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (count($this->args) > 1) {
|
||||
throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
|
||||
}
|
||||
|
||||
require_once '.htconfig.php';
|
||||
$result = \dba::connect($db_host, $db_user, $db_pass, $db_data);
|
||||
unset($db_host, $db_user, $db_pass, $db_data);
|
||||
|
||||
if (!$result) {
|
||||
throw new \RuntimeException('Unable to connect to database');
|
||||
}
|
||||
|
||||
$nurl = normalise_link($this->getArgument(0));
|
||||
if (!dba::exists('contact', ['nurl' => $nurl, 'archive' => false])) {
|
||||
throw new \RuntimeException(L10n::t('Could not find any unarchived contact entry for this URL (%s)', $nurl));
|
||||
}
|
||||
if (dba::update('contact', ['archive' => true], ['nurl' => $nurl])) {
|
||||
$condition = ["`cid` IN (SELECT `id` FROM `contact` WHERE `archive`)"];
|
||||
dba::delete('queue', $condition);
|
||||
$this->out(L10n::t('The contact entries have been archived'));
|
||||
} else {
|
||||
throw new \RuntimeException('The contact archival failed.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -423,7 +423,7 @@ class Contact extends BaseObject
|
|||
// Fetch the data from the gcontact table
|
||||
if (!DBM::is_result($r)) {
|
||||
$s = dba::p("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
|
||||
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
|
||||
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, 0 AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
|
||||
FROM `gcontact` WHERE `nurl` = ?", normalise_link($url));
|
||||
$r = dba::inArray($s);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
namespace Friendica\Model;
|
||||
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\Content\Text;
|
||||
use Friendica\Core\Addon;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\L10n;
|
||||
|
@ -838,6 +839,101 @@ class Item extends BaseObject
|
|||
return $current_post;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Distributes public items to the receivers
|
||||
*
|
||||
* @param integer $itemid Item ID that should be added
|
||||
*/
|
||||
public static function distribute($itemid)
|
||||
{
|
||||
$condition = ["`id` IN (SELECT `parent` FROM `item` WHERE `id` = ?)", $itemid];
|
||||
$parent = dba::selectFirst('item', ['owner-id'], $condition);
|
||||
if (!DBM::is_result($parent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only distribute public items from native networks
|
||||
$condition = ['id' => $itemid, 'uid' => 0,
|
||||
'network' => [NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""],
|
||||
'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
|
||||
$item = dba::selectFirst('item', [], ['id' => $itemid]);
|
||||
if (!DBM::is_result($item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset($item['id']);
|
||||
unset($item['parent']);
|
||||
unset($item['mention']);
|
||||
unset($item['wall']);
|
||||
unset($item['origin']);
|
||||
unset($item['starred']);
|
||||
unset($item['rendered-hash']);
|
||||
unset($item['rendered-html']);
|
||||
|
||||
$users = [];
|
||||
|
||||
$condition = ["`nurl` IN (SELECT `nurl` FROM `contact` WHERE `id` = ?) AND `uid` != 0 AND NOT `blocked` AND NOT `readonly` AND `rel` IN (?, ?)",
|
||||
$parent['owner-id'], CONTACT_IS_SHARING, CONTACT_IS_FRIEND];
|
||||
$contacts = dba::select('contact', ['uid'], $condition);
|
||||
while ($contact = dba::fetch($contacts)) {
|
||||
$users[$contact['uid']] = $contact['uid'];
|
||||
}
|
||||
|
||||
if ($item['uri'] != $item['parent-uri']) {
|
||||
$parents = dba::select('item', ['uid'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
|
||||
while ($parent = dba::fetch($parents)) {
|
||||
$users[$parent['uid']] = $parent['uid'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($users as $uid) {
|
||||
self::storeForUser($itemid, $item, $uid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store public items for the receivers
|
||||
*
|
||||
* @param integer $itemid Item ID that should be added
|
||||
* @param array $item The item entry that will be stored
|
||||
* @param integer $uid The user that will receive the item entry
|
||||
*/
|
||||
private static function storeForUser($itemid, $item, $uid)
|
||||
{
|
||||
$item['uid'] = $uid;
|
||||
$item['origin'] = 0;
|
||||
$item['wall'] = 0;
|
||||
if ($item['uri'] == $item['parent-uri']) {
|
||||
$item['contact-id'] = Contact::getIdForURL($item['owner-link'], $uid);
|
||||
} else {
|
||||
$item['contact-id'] = Contact::getIdForURL($item['author-link'], $uid);
|
||||
}
|
||||
|
||||
if (empty($item['contact-id'])) {
|
||||
$self = dba::selectFirst('contact', ['id'], ['self' => true, 'uid' => $uid]);
|
||||
if (!DBM::is_result($self)) {
|
||||
return;
|
||||
}
|
||||
$item['contact-id'] = $self['id'];
|
||||
}
|
||||
|
||||
if (in_array($item['type'], ["net-comment", "wall-comment"])) {
|
||||
$item['type'] = 'remote-comment';
|
||||
} elseif ($item['type'] == 'wall') {
|
||||
$item['type'] = 'remote';
|
||||
}
|
||||
|
||||
/// @todo Handling of "event-id"
|
||||
|
||||
$distributed = self::insert($item, false, false, true);
|
||||
|
||||
if (!$distributed) {
|
||||
logger("Distributed public item " . $itemid . " for user " . $uid . " wasn't stored", LOGGER_DEBUG);
|
||||
} else {
|
||||
logger("Distributed public item " . $itemid . " for user " . $uid . " with id " . $distributed, LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a shadow entry for a given item id that is a thread starter
|
||||
*
|
||||
|
@ -849,8 +945,8 @@ class Item extends BaseObject
|
|||
*/
|
||||
public static function addShadow($itemid)
|
||||
{
|
||||
$fields = ['uid', 'wall', 'private', 'moderated', 'visible', 'contact-id', 'deleted', 'network', 'author-id', 'owner-id'];
|
||||
$condition = ["`id` = ? AND (`parent` = ? OR `parent` = 0)", $itemid, $itemid];
|
||||
$fields = ['uid', 'private', 'moderated', 'visible', 'deleted', 'network'];
|
||||
$condition = ['id' => $itemid, 'parent' => [0, $itemid]];
|
||||
$item = dba::selectFirst('item', $fields, $condition);
|
||||
|
||||
if (!DBM::is_result($item)) {
|
||||
|
@ -872,24 +968,6 @@ class Item extends BaseObject
|
|||
return;
|
||||
}
|
||||
|
||||
// Only do these checks if the post isn't a wall post
|
||||
if (!$item["wall"]) {
|
||||
// Check, if hide-friends is activated - then don't do a shadow entry
|
||||
if (dba::exists('profile', ['is-default' => true, 'uid' => $item['uid'], 'hide-friends' => true])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the contact is hidden or blocked
|
||||
if (!dba::exists('contact', ['hidden' => false, 'blocked' => false, 'id' => $item['contact-id']])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Only add a shadow, if the profile isn't hidden
|
||||
if (dba::exists('user', ['uid' => $item['uid'], 'hidewall' => true])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = dba::selectFirst('item', [], ['id' => $itemid]);
|
||||
|
||||
if (DBM::is_result($item) && ($item["allow_cid"] == '') && ($item["allow_gid"] == '') &&
|
||||
|
@ -897,10 +975,15 @@ class Item extends BaseObject
|
|||
|
||||
if (!dba::exists('item', ['uri' => $item['uri'], 'uid' => 0])) {
|
||||
// Preparing public shadow (removing user specific data)
|
||||
unset($item['id']);
|
||||
$item['uid'] = 0;
|
||||
$item['origin'] = 0;
|
||||
$item['wall'] = 0;
|
||||
unset($item['id']);
|
||||
unset($item['parent']);
|
||||
unset($item['wall']);
|
||||
unset($item['mention']);
|
||||
unset($item['origin']);
|
||||
unset($item['starred']);
|
||||
unset($item['rendered-hash']);
|
||||
unset($item['rendered-html']);
|
||||
if ($item['uri'] == $item['parent-uri']) {
|
||||
$item['contact-id'] = Contact::getIdForURL($item['owner-link']);
|
||||
} else {
|
||||
|
@ -954,11 +1037,20 @@ class Item extends BaseObject
|
|||
return;
|
||||
}
|
||||
|
||||
// Save "origin" and "parent" state
|
||||
$origin = $item['origin'];
|
||||
$parent = $item['parent'];
|
||||
|
||||
// Preparing public shadow (removing user specific data)
|
||||
unset($item['id']);
|
||||
$item['uid'] = 0;
|
||||
$item['origin'] = 0;
|
||||
$item['wall'] = 0;
|
||||
unset($item['id']);
|
||||
unset($item['parent']);
|
||||
unset($item['wall']);
|
||||
unset($item['mention']);
|
||||
unset($item['origin']);
|
||||
unset($item['starred']);
|
||||
unset($item['rendered-hash']);
|
||||
unset($item['rendered-html']);
|
||||
$item['contact-id'] = Contact::getIdForURL($item['author-link']);
|
||||
|
||||
if (in_array($item['type'], ["net-comment", "wall-comment"])) {
|
||||
|
@ -970,6 +1062,14 @@ class Item extends BaseObject
|
|||
$public_shadow = self::insert($item, false, false, true);
|
||||
|
||||
logger("Stored public shadow for comment ".$item['uri']." under id ".$public_shadow, LOGGER_DEBUG);
|
||||
|
||||
// If this was a comment to a Diaspora post we don't get our comment back.
|
||||
// This means that we have to distribute the comment by ourselves.
|
||||
if ($origin) {
|
||||
if (dba::exists('item', ['id' => $parent, 'network' => NETWORK_DIASPORA])) {
|
||||
self::distribute($public_shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -977,35 +1077,35 @@ class Item extends BaseObject
|
|||
* if possible and not already present.
|
||||
* Expects "body" element to exist in $arr.
|
||||
*/
|
||||
private static function addLanguageInPostopts(&$arr)
|
||||
private static function addLanguageInPostopts(&$item)
|
||||
{
|
||||
if (x($arr, 'postopts')) {
|
||||
if (strstr($arr['postopts'], 'lang=')) {
|
||||
if (!empty($item['postopts'])) {
|
||||
if (strstr($item['postopts'], 'lang=')) {
|
||||
// do not override
|
||||
return;
|
||||
}
|
||||
$postopts = $arr['postopts'];
|
||||
$postopts = $item['postopts'];
|
||||
} else {
|
||||
$postopts = "";
|
||||
}
|
||||
|
||||
$naked_body = preg_replace('/\[(.+?)\]/','', $arr['body']);
|
||||
$l = new Text_LanguageDetect();
|
||||
$lng = $l->detect($naked_body, 3);
|
||||
$naked_body = Text\BBCode::toPlaintext($item['body'], false);
|
||||
|
||||
if (sizeof($lng) > 0) {
|
||||
if ($postopts != "") {
|
||||
$languages = (new Text_LanguageDetect())->detect($naked_body, 3);
|
||||
|
||||
if (sizeof($languages) > 0) {
|
||||
if ($postopts != '') {
|
||||
$postopts .= '&'; // arbitrary separator, to be reviewed
|
||||
}
|
||||
|
||||
$postopts .= 'lang=';
|
||||
$sep = "";
|
||||
|
||||
foreach ($lng as $language => $score) {
|
||||
foreach ($languages as $language => $score) {
|
||||
$postopts .= $sep . $language . ";" . $score;
|
||||
$sep = ':';
|
||||
}
|
||||
$arr['postopts'] = $postopts;
|
||||
$item['postopts'] = $postopts;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
176
src/Model/ItemContent.php
Normal file
176
src/Model/ItemContent.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file src/Model/ItemContent.php
|
||||
*/
|
||||
|
||||
namespace Friendica\Model;
|
||||
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\Content\Text;
|
||||
use Friendica\Core\PConfig;
|
||||
|
||||
require_once 'boot.php';
|
||||
require_once 'include/items.php';
|
||||
require_once 'include/text.php';
|
||||
|
||||
class ItemContent extends BaseObject
|
||||
{
|
||||
/**
|
||||
* @brief Convert a message into plaintext for connectors to other networks
|
||||
*
|
||||
* @param array $item The message array that is about to be posted
|
||||
* @param int $limit The maximum number of characters when posting to that network
|
||||
* @param bool $includedlinks Has an attached link to be included into the message?
|
||||
* @param int $htmlmode This controls the behavior of the BBCode conversion
|
||||
* @param string $target_network Name of the network where the post should go to.
|
||||
*
|
||||
* @see \Friendica\Content\Text\BBCode::getAttachedData
|
||||
*
|
||||
* @return array Same array structure than \Friendica\Content\Text\BBCode::getAttachedData
|
||||
*/
|
||||
public static function getPlaintextPost($item, $limit = 0, $includedlinks = false, $htmlmode = 2, $target_network = '')
|
||||
{
|
||||
// Remove hashtags
|
||||
$URLSearchString = '^\[\]';
|
||||
$body = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $item['body']);
|
||||
|
||||
// Add an URL element if the text contains a raw link
|
||||
$body = preg_replace('/([^\]\=\'"]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism',
|
||||
'$1[url]$2[/url]', $body);
|
||||
|
||||
// Remove the abstract
|
||||
$body = Text\BBCode::stripAbstract($body);
|
||||
|
||||
// At first look at data that is attached via "type-..." stuff
|
||||
// This will hopefully replaced with a dedicated bbcode later
|
||||
//$post = self::getAttachedData($b['body']);
|
||||
$post = Text\BBCode::getAttachedData($body, $item);
|
||||
|
||||
if (($item['title'] != '') && ($post['text'] != '')) {
|
||||
$post['text'] = trim($item['title'] . "\n\n" . $post['text']);
|
||||
} elseif ($item['title'] != '') {
|
||||
$post['text'] = trim($item['title']);
|
||||
}
|
||||
|
||||
$abstract = '';
|
||||
|
||||
// Fetch the abstract from the given target network
|
||||
if ($target_network != '') {
|
||||
$default_abstract = Text\BBCode::getAbstract($item['body']);
|
||||
$abstract = Text\BBCode::getAbstract($item['body'], $target_network);
|
||||
|
||||
// If we post to a network with no limit we only fetch
|
||||
// an abstract exactly for this network
|
||||
if (($limit == 0) && ($abstract == $default_abstract)) {
|
||||
$abstract = '';
|
||||
}
|
||||
} else {// Try to guess the correct target network
|
||||
switch ($htmlmode) {
|
||||
case 8:
|
||||
$abstract = Text\BBCode::getAbstract($item['body'], NETWORK_TWITTER);
|
||||
break;
|
||||
case 7:
|
||||
$abstract = Text\BBCode::getAbstract($item['body'], NETWORK_STATUSNET);
|
||||
break;
|
||||
case 6:
|
||||
$abstract = Text\BBCode::getAbstract($item['body'], NETWORK_APPNET);
|
||||
break;
|
||||
default: // We don't know the exact target.
|
||||
// We fetch an abstract since there is a posting limit.
|
||||
if ($limit > 0) {
|
||||
$abstract = Text\BBCode::getAbstract($item['body']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($abstract != '') {
|
||||
$post['text'] = $abstract;
|
||||
|
||||
if ($post['type'] == 'text') {
|
||||
$post['type'] = 'link';
|
||||
$post['url'] = $item['plink'];
|
||||
}
|
||||
}
|
||||
|
||||
$html = Text\BBCode::convert($post['text'] . $post['after'], false, $htmlmode);
|
||||
$msg = Text\HTML::toPlaintext($html, 0, true);
|
||||
$msg = trim(html_entity_decode($msg, ENT_QUOTES, 'UTF-8'));
|
||||
|
||||
$link = '';
|
||||
if ($includedlinks) {
|
||||
if ($post['type'] == 'link') {
|
||||
$link = $post['url'];
|
||||
} elseif ($post['type'] == 'text') {
|
||||
$link = $post['url'];
|
||||
} elseif ($post['type'] == 'video') {
|
||||
$link = $post['url'];
|
||||
} elseif ($post['type'] == 'photo') {
|
||||
$link = $post['image'];
|
||||
}
|
||||
|
||||
if (($msg == '') && isset($post['title'])) {
|
||||
$msg = trim($post['title']);
|
||||
}
|
||||
|
||||
if (($msg == '') && isset($post['description'])) {
|
||||
$msg = trim($post['description']);
|
||||
}
|
||||
|
||||
// If the link is already contained in the post, then it neeedn't to be added again
|
||||
// But: if the link is beyond the limit, then it has to be added.
|
||||
if (($link != '') && strstr($msg, $link)) {
|
||||
$pos = strpos($msg, $link);
|
||||
|
||||
// Will the text be shortened in the link?
|
||||
// Or is the link the last item in the post?
|
||||
if (($limit > 0) && ($pos < $limit) && (($pos + 23 > $limit) || ($pos + strlen($link) == strlen($msg)))) {
|
||||
$msg = trim(str_replace($link, '', $msg));
|
||||
} elseif (($limit == 0) || ($pos < $limit)) {
|
||||
// The limit has to be increased since it will be shortened - but not now
|
||||
// Only do it with Twitter (htmlmode = 8)
|
||||
if (($limit > 0) && (strlen($link) > 23) && ($htmlmode == 8)) {
|
||||
$limit = $limit - 23 + strlen($link);
|
||||
}
|
||||
|
||||
$link = '';
|
||||
|
||||
if ($post['type'] == 'text') {
|
||||
unset($post['url']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($limit > 0) {
|
||||
// Reduce multiple spaces
|
||||
// When posted to a network with limited space, we try to gain space where possible
|
||||
while (strpos($msg, ' ') !== false) {
|
||||
$msg = str_replace(' ', ' ', $msg);
|
||||
}
|
||||
|
||||
// Twitter is using its own limiter, so we always assume that shortened links will have this length
|
||||
if (iconv_strlen($link, 'UTF-8') > 0) {
|
||||
$limit = $limit - 23;
|
||||
}
|
||||
|
||||
if (iconv_strlen($msg, 'UTF-8') > $limit) {
|
||||
if (($post['type'] == 'text') && isset($post['url'])) {
|
||||
$post['url'] = $item['plink'];
|
||||
} elseif (!isset($post['url'])) {
|
||||
$limit = $limit - 23;
|
||||
$post['url'] = $item['plink'];
|
||||
} elseif (strpos($item['body'], '[share') !== false) {
|
||||
$post['url'] = $item['plink'];
|
||||
} elseif (PConfig::get($item['uid'], 'system', 'no_intelligent_shortening')) {
|
||||
$post['url'] = $item['plink'];
|
||||
}
|
||||
$msg = Text\Plaintext::shorten($msg, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
$post['text'] = trim($msg);
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
|
@ -92,14 +92,14 @@ class Profile
|
|||
{
|
||||
$user = dba::selectFirst('user', ['uid'], ['nickname' => $nickname]);
|
||||
|
||||
if (!$user && !count($user) && !count($profiledata)) {
|
||||
if (!DBM::is_result($user) && empty($profiledata)) {
|
||||
logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
|
||||
notice(L10n::t('Requested account is not available.') . EOL);
|
||||
$a->error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!x($a->page, 'aside')) {
|
||||
if (empty($a->page['aside'])) {
|
||||
$a->page['aside'] = '';
|
||||
}
|
||||
|
||||
|
@ -157,10 +157,6 @@ class Profile
|
|||
require_once $theme_info_file;
|
||||
}
|
||||
|
||||
if (!x($a->page, 'aside')) {
|
||||
$a->page['aside'] = '';
|
||||
}
|
||||
|
||||
if (local_user() && local_user() == $a->profile['uid'] && $profiledata) {
|
||||
$a->page['aside'] .= replace_macros(
|
||||
get_markup_template('profile_edlink.tpl'),
|
||||
|
@ -644,26 +640,26 @@ class Profile
|
|||
$classtoday = '';
|
||||
|
||||
$s = dba::p(
|
||||
"SELECT *
|
||||
"SELECT `event`.*
|
||||
FROM `event`
|
||||
INNER JOIN `item`
|
||||
ON `item`.`uid` = `event`.`uid`
|
||||
AND `item`.`parent-uri` = `event`.`uri`
|
||||
WHERE `event`.`uid` = ?
|
||||
AND `event`.`type` != 'birthday'
|
||||
AND `event`.`start` < ?
|
||||
AND `event`.`start` >= ?
|
||||
AND NOT EXISTS (
|
||||
SELECT `id`
|
||||
FROM `item`
|
||||
WHERE `item`.`uid` = `event`.`uid`
|
||||
AND `item`.`parent-uri` = `event`.`uri`
|
||||
AND `item`.`verb` = ?
|
||||
AND `item`.`author-id` = ?
|
||||
AND (`item`.`verb` = ? OR `item`.`verb` = ?)
|
||||
AND `item`.`visible`
|
||||
AND NOT `item`.`deleted`
|
||||
)
|
||||
ORDER BY `event`.`start` ASC",
|
||||
local_user(),
|
||||
DateTimeFormat::utc('now + 7 days'),
|
||||
DateTimeFormat::utc('now - 1 days'),
|
||||
ACTIVITY_ATTENDNO
|
||||
public_contact(),
|
||||
ACTIVITY_ATTEND,
|
||||
ACTIVITY_ATTENDMAYBE
|
||||
);
|
||||
|
||||
$r = [];
|
||||
|
@ -954,7 +950,7 @@ class Profile
|
|||
];
|
||||
}
|
||||
|
||||
if ((!$is_owner) && ((count($a->profile)) || (!$a->profile['hide-friends']))) {
|
||||
if (!$is_owner && empty($a->profile['hide-friends'])) {
|
||||
$tabs[] = [
|
||||
'label' => L10n::t('Contacts'),
|
||||
'url' => System::baseUrl() . '/viewcontacts/' . $nickname,
|
||||
|
|
|
@ -78,7 +78,7 @@ class Post extends BaseObject
|
|||
}
|
||||
|
||||
// Prepare the children
|
||||
if (count($data['children'])) {
|
||||
if (!empty($data['children'])) {
|
||||
foreach ($data['children'] as $item) {
|
||||
// Only add will be displayed
|
||||
if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
|
||||
|
|
|
@ -1197,6 +1197,7 @@ class DFRN
|
|||
$ret = Network::curl($url);
|
||||
|
||||
if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) {
|
||||
Contact::markForArchival($contact);
|
||||
return -2; // timed out
|
||||
}
|
||||
|
||||
|
@ -1204,24 +1205,28 @@ class DFRN
|
|||
|
||||
$curl_stat = $a->get_curl_code();
|
||||
if (empty($curl_stat)) {
|
||||
Contact::markForArchival($contact);
|
||||
return -3; // timed out
|
||||
}
|
||||
|
||||
logger('dfrn_deliver: ' . $xml, LOGGER_DATA);
|
||||
|
||||
if (empty($xml)) {
|
||||
Contact::markForArchival($contact);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (strpos($xml, '<?xml') === false) {
|
||||
logger('dfrn_deliver: no valid XML returned');
|
||||
logger('dfrn_deliver: returned XML: ' . $xml, LOGGER_DATA);
|
||||
Contact::markForArchival($contact);
|
||||
return 3;
|
||||
}
|
||||
|
||||
$res = XML::parseString($xml);
|
||||
|
||||
if ((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) {
|
||||
if ((intval($res->status) != 0) || !strlen($res->challenge) || !strlen($res->dfrn_id)) {
|
||||
Contact::markForArchival($contact);
|
||||
return ($res->status ? $res->status : 3);
|
||||
}
|
||||
|
||||
|
@ -1274,6 +1279,7 @@ class DFRN
|
|||
if ($final_dfrn_id != $orig_id) {
|
||||
logger('dfrn_deliver: wrong dfrn_id.');
|
||||
// did not decode properly - cannot trust this site
|
||||
Contact::markForArchival($contact);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -1309,6 +1315,7 @@ class DFRN
|
|||
break;
|
||||
default:
|
||||
logger("rino: invalid requested version '$rino_remote_version'");
|
||||
Contact::markForArchival($contact);
|
||||
return -8;
|
||||
}
|
||||
|
||||
|
@ -1346,22 +1353,26 @@ class DFRN
|
|||
|
||||
$curl_stat = $a->get_curl_code();
|
||||
if (empty($curl_stat) || empty($xml)) {
|
||||
Contact::markForArchival($contact);
|
||||
return -9; // timed out
|
||||
}
|
||||
|
||||
if (($curl_stat == 503) && stristr($a->get_curl_headers(), 'retry-after')) {
|
||||
Contact::markForArchival($contact);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (strpos($xml, '<?xml') === false) {
|
||||
logger('dfrn_deliver: phase 2: no valid XML returned');
|
||||
logger('dfrn_deliver: phase 2: returned XML: ' . $xml, LOGGER_DATA);
|
||||
Contact::markForArchival($contact);
|
||||
return 3;
|
||||
}
|
||||
|
||||
$res = XML::parseString($xml);
|
||||
|
||||
if (!isset($res->status)) {
|
||||
Contact::markForArchival($contact);
|
||||
return -11;
|
||||
}
|
||||
|
||||
|
@ -1374,7 +1385,7 @@ class DFRN
|
|||
logger('Delivery returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
if ($res->status == 200) {
|
||||
if (($res->status >= 200) && ($res->status <= 299)) {
|
||||
Contact::unmarkForArchival($contact);
|
||||
}
|
||||
|
||||
|
@ -1394,6 +1405,7 @@ class DFRN
|
|||
{
|
||||
$a = get_app();
|
||||
|
||||
if (!$public_batch) {
|
||||
if (empty($contact['addr'])) {
|
||||
logger('Empty contact handle for ' . $contact['id'] . ' - ' . $contact['url'] . ' - trying to update it.');
|
||||
if (Contact::updateFromProbe($contact['id'])) {
|
||||
|
@ -1403,6 +1415,7 @@ class DFRN
|
|||
|
||||
if (empty($contact['addr'])) {
|
||||
logger('Unable to find contact handle for ' . $contact['id'] . ' - ' . $contact['url']);
|
||||
Contact::markForArchival($contact);
|
||||
return -21;
|
||||
}
|
||||
}
|
||||
|
@ -1410,12 +1423,23 @@ class DFRN
|
|||
$fcontact = Diaspora::personByHandle($contact['addr']);
|
||||
if (empty($fcontact)) {
|
||||
logger('Unable to find contact details for ' . $contact['id'] . ' - ' . $contact['addr']);
|
||||
Contact::markForArchival($contact);
|
||||
return -22;
|
||||
}
|
||||
}
|
||||
|
||||
$envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $fcontact['pubkey'], $public_batch);
|
||||
|
||||
$dest_url = ($public_batch ? $fcontact["batch"] : $contact["notify"]);
|
||||
// Create the endpoint for public posts. This is some WIP and should later be added to the probing
|
||||
if ($public_batch && empty($contact["batch"])) {
|
||||
$parts = parse_url($contact["notify"]);
|
||||
$path_parts = explode('/', $parts['path']);
|
||||
array_pop($path_parts);
|
||||
$parts['path'] = implode('/', $path_parts);
|
||||
$contact["batch"] = Network::unparseURL($parts);
|
||||
}
|
||||
|
||||
$dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]);
|
||||
|
||||
$content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json");
|
||||
|
||||
|
@ -1424,22 +1448,26 @@ class DFRN
|
|||
$curl_stat = $a->get_curl_code();
|
||||
if (empty($curl_stat) || empty($xml)) {
|
||||
logger('Empty answer from ' . $contact['id'] . ' - ' . $dest_url);
|
||||
Contact::markForArchival($contact);
|
||||
return -9; // timed out
|
||||
}
|
||||
|
||||
if (($curl_stat == 503) && (stristr($a->get_curl_headers(), 'retry-after'))) {
|
||||
Contact::markForArchival($contact);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (strpos($xml, '<?xml') === false) {
|
||||
logger('No valid XML returned from ' . $contact['id'] . ' - ' . $dest_url);
|
||||
logger('Returned XML: ' . $xml, LOGGER_DATA);
|
||||
Contact::markForArchival($contact);
|
||||
return 3;
|
||||
}
|
||||
|
||||
$res = XML::parseString($xml);
|
||||
|
||||
if (empty($res->status)) {
|
||||
Contact::markForArchival($contact);
|
||||
return -23;
|
||||
}
|
||||
|
||||
|
@ -1447,7 +1475,7 @@ class DFRN
|
|||
logger('Transmit to ' . $dest_url . ' returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
if ($res->status == 200) {
|
||||
if (($res->status >= 200) && ($res->status <= 299)) {
|
||||
Contact::unmarkForArchival($contact);
|
||||
}
|
||||
|
||||
|
@ -1467,33 +1495,33 @@ class DFRN
|
|||
// Check for duplicates
|
||||
$r = q(
|
||||
"SELECT `id` FROM `event` WHERE `uid` = %d AND `cid` = %d AND `start` = '%s' AND `type` = '%s' LIMIT 1",
|
||||
intval($contact["uid"]),
|
||||
intval($contact["id"]),
|
||||
intval($contact['uid']),
|
||||
intval($contact['id']),
|
||||
dbesc(DateTimeFormat::utc($birthday)),
|
||||
dbesc("birthday")
|
||||
dbesc('birthday')
|
||||
);
|
||||
|
||||
if (DBM::is_result($r)) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger("updating birthday: ".$birthday." for contact ".$contact["id"]);
|
||||
logger('updating birthday: ' . $birthday . ' for contact ' . $contact['id']);
|
||||
|
||||
$bdtext = L10n::t("%s\'s birthday", $contact["name"]);
|
||||
$bdtext2 = L10n::t("Happy Birthday %s", " [url=".$contact["url"]."]".$contact["name"]."[/url]");
|
||||
$bdtext = L10n::t('%s\'s birthday', $contact['name']);
|
||||
$bdtext2 = L10n::t('Happy Birthday %s', ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]');
|
||||
|
||||
$r = q(
|
||||
"INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`)
|
||||
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
|
||||
intval($contact["uid"]),
|
||||
intval($contact["id"]),
|
||||
intval($contact['uid']),
|
||||
intval($contact['id']),
|
||||
dbesc(DateTimeFormat::utcNow()),
|
||||
dbesc(DateTimeFormat::utcNow()),
|
||||
dbesc(DateTimeFormat::utc($birthday)),
|
||||
dbesc(DateTimeFormat::utc($birthday . " + 1 day ")),
|
||||
dbesc(DateTimeFormat::utc($birthday . ' + 1 day ')),
|
||||
dbesc($bdtext),
|
||||
dbesc($bdtext2),
|
||||
dbesc("birthday")
|
||||
dbesc('birthday')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2747,6 +2775,10 @@ class DFRN
|
|||
if ($posted_id) {
|
||||
logger("Reply from contact ".$item["contact-id"]." was stored with id ".$posted_id, LOGGER_DEBUG);
|
||||
|
||||
if ($item['uid'] == 0) {
|
||||
Item::distribute($posted_id);
|
||||
}
|
||||
|
||||
$item["id"] = $posted_id;
|
||||
|
||||
$r = q(
|
||||
|
@ -2771,7 +2803,7 @@ class DFRN
|
|||
logger('ignoring read-only contact '.$importer["id"]);
|
||||
return;
|
||||
}
|
||||
if ($importer["uid"] == 0) {
|
||||
if (($importer["uid"] == 0) && ($importer["importer_uid"] != 0)) {
|
||||
logger("Contact ".$importer["id"]." isn't known to user ".$importer["importer_uid"].". The post will be ignored.", LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
@ -2801,6 +2833,10 @@ class DFRN
|
|||
|
||||
logger("Item was stored with id ".$posted_id, LOGGER_DEBUG);
|
||||
|
||||
if ($item['uid'] == 0) {
|
||||
Item::distribute($posted_id);
|
||||
}
|
||||
|
||||
if (stristr($item["verb"], ACTIVITY_POKE)) {
|
||||
self::doPoke($item, $importer, $posted_id);
|
||||
}
|
||||
|
@ -2923,6 +2959,9 @@ class DFRN
|
|||
|
||||
logger("Import DFRN message for user " . $importer["importer_uid"] . " from contact " . $importer["id"], LOGGER_DEBUG);
|
||||
|
||||
// is it a public forum? Private forums aren't exposed with this method
|
||||
$forum = intval($xpath->evaluate("/atom:feed/dfrn:community/text()")->item(0)->nodeValue);
|
||||
|
||||
// The account type is new since 3.5.1
|
||||
if ($xpath->query("/atom:feed/dfrn:account_type")->length > 0) {
|
||||
$accounttype = intval($xpath->evaluate("/atom:feed/dfrn:account_type/text()")->item(0)->nodeValue);
|
||||
|
@ -2930,17 +2969,17 @@ class DFRN
|
|||
if ($accounttype != $importer["contact-type"]) {
|
||||
dba::update('contact', ['contact-type' => $accounttype], ['id' => $importer["id"]]);
|
||||
}
|
||||
// A forum contact can either have set "forum" or "prv" - but not both
|
||||
if (($accounttype == ACCOUNT_TYPE_COMMUNITY) && (($forum != $importer["forum"]) || ($forum == $importer["prv"]))) {
|
||||
$condition = ['(`forum` != ? OR `prv` != ?) AND `id` = ?', $forum, !$forum, $importer["id"]];
|
||||
dba::update('contact', ['forum' => $forum, 'prv' => !$forum], $condition);
|
||||
}
|
||||
|
||||
// is it a public forum? Private forums aren't supported with this method
|
||||
// This is deprecated since 3.5.1
|
||||
$forum = intval($xpath->evaluate("/atom:feed/dfrn:community/text()")->item(0)->nodeValue);
|
||||
|
||||
if ($forum != $importer["forum"]) {
|
||||
} elseif ($forum != $importer["forum"]) { // Deprecated since 3.5.1
|
||||
$condition = ['`forum` != ? AND `id` = ?', $forum, $importer["id"]];
|
||||
dba::update('contact', ['forum' => $forum], $condition);
|
||||
}
|
||||
|
||||
|
||||
// We are processing relocations even if we are ignoring a contact
|
||||
$relocations = $xpath->query("/atom:feed/dfrn:relocate");
|
||||
foreach ($relocations as $relocation) {
|
||||
|
|
|
@ -590,59 +590,15 @@ class Diaspora
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!($postdata = self::validPosting($msg))) {
|
||||
if (!($fields = self::validPosting($msg))) {
|
||||
logger("Invalid posting");
|
||||
return false;
|
||||
}
|
||||
|
||||
$fields = $postdata['fields'];
|
||||
|
||||
// Is it a an action (comment, like, ...) for our own post?
|
||||
if (isset($fields->parent_guid) && !$postdata["relayed"]) {
|
||||
$guid = notags(unxmlify($fields->parent_guid));
|
||||
$importer = self::importerForGuid($guid);
|
||||
if (is_array($importer)) {
|
||||
logger("delivering to origin: ".$importer["name"]);
|
||||
$message_id = self::dispatch($importer, $msg, $fields);
|
||||
return $message_id;
|
||||
}
|
||||
}
|
||||
|
||||
// Process item retractions. This has to be done separated from the other stuff,
|
||||
// since retractions for comments could come even from non followers.
|
||||
if (!empty($fields) && in_array($fields->getName(), ['retraction'])) {
|
||||
$target = notags(unxmlify($fields->target_type));
|
||||
if (in_array($target, ["Comment", "Like", "Post", "Reshare", "StatusMessage"])) {
|
||||
logger('processing retraction for '.$target, LOGGER_DEBUG);
|
||||
$importer = ["uid" => 0, "page-flags" => PAGE_FREELOVE];
|
||||
$message_id = self::dispatch($importer, $msg, $fields);
|
||||
return $message_id;
|
||||
}
|
||||
}
|
||||
$success = self::dispatch($importer, $msg, $fields);
|
||||
|
||||
// Now distribute it to the followers
|
||||
$r = q(
|
||||
"SELECT `user`.* FROM `user` WHERE `user`.`uid` IN
|
||||
(SELECT `contact`.`uid` FROM `contact` WHERE `contact`.`network` = '%s' AND `contact`.`addr` = '%s')
|
||||
AND NOT `account_expired` AND NOT `account_removed`",
|
||||
dbesc(NETWORK_DIASPORA),
|
||||
dbesc($msg["author"])
|
||||
);
|
||||
|
||||
if (DBM::is_result($r)) {
|
||||
foreach ($r as $rr) {
|
||||
logger("delivering to: ".$rr["username"]);
|
||||
self::dispatch($rr, $msg, $fields);
|
||||
}
|
||||
} elseif (!Config::get('system', 'relay_subscribe', false)) {
|
||||
logger("Unwanted message from ".$msg["author"]." send by ".$_SERVER["REMOTE_ADDR"]." with ".$_SERVER["HTTP_USER_AGENT"].": ".print_r($msg, true), LOGGER_DEBUG);
|
||||
} else {
|
||||
// Use a dummy importer to import the data for the public copy
|
||||
$importer = ["uid" => 0, "page-flags" => PAGE_FREELOVE];
|
||||
$message_id = self::dispatch($importer, $msg, $fields);
|
||||
}
|
||||
|
||||
return $message_id;
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -662,11 +618,13 @@ class Diaspora
|
|||
|
||||
// This is only needed for private postings since this is already done for public ones before
|
||||
if (is_null($fields)) {
|
||||
if (!($postdata = self::validPosting($msg))) {
|
||||
$private = true;
|
||||
if (!($fields = self::validPosting($msg))) {
|
||||
logger("Invalid posting");
|
||||
return false;
|
||||
}
|
||||
$fields = $postdata['fields'];
|
||||
} else {
|
||||
$private = false;
|
||||
}
|
||||
|
||||
$type = $fields->getName();
|
||||
|
@ -675,27 +633,47 @@ class Diaspora
|
|||
|
||||
switch ($type) {
|
||||
case "account_migration":
|
||||
if (!$private) {
|
||||
logger('Message with type ' . $type . ' is not private, quitting.');
|
||||
return false;
|
||||
}
|
||||
return self::receiveAccountMigration($importer, $fields);
|
||||
|
||||
case "account_deletion":
|
||||
return self::receiveAccountDeletion($importer, $fields);
|
||||
return self::receiveAccountDeletion($fields);
|
||||
|
||||
case "comment":
|
||||
return self::receiveComment($importer, $sender, $fields, $msg["message"]);
|
||||
|
||||
case "contact":
|
||||
if (!$private) {
|
||||
logger('Message with type ' . $type . ' is not private, quitting.');
|
||||
return false;
|
||||
}
|
||||
return self::receiveContactRequest($importer, $fields);
|
||||
|
||||
case "conversation":
|
||||
if (!$private) {
|
||||
logger('Message with type ' . $type . ' is not private, quitting.');
|
||||
return false;
|
||||
}
|
||||
return self::receiveConversation($importer, $msg, $fields);
|
||||
|
||||
case "like":
|
||||
return self::receiveLike($importer, $sender, $fields);
|
||||
|
||||
case "message":
|
||||
if (!$private) {
|
||||
logger('Message with type ' . $type . ' is not private, quitting.');
|
||||
return false;
|
||||
}
|
||||
return self::receiveMessage($importer, $fields);
|
||||
|
||||
case "participation":
|
||||
if (!$private) {
|
||||
logger('Message with type ' . $type . ' is not private, quitting.');
|
||||
return false;
|
||||
}
|
||||
return self::receiveParticipation($importer, $fields);
|
||||
|
||||
case "photo": // Not implemented
|
||||
|
@ -705,6 +683,10 @@ class Diaspora
|
|||
return self::receivePollParticipation($importer, $fields);
|
||||
|
||||
case "profile":
|
||||
if (!$private) {
|
||||
logger('Message with type ' . $type . ' is not private, quitting.');
|
||||
return false;
|
||||
}
|
||||
return self::receiveProfile($importer, $fields);
|
||||
|
||||
case "reshare":
|
||||
|
@ -840,7 +822,7 @@ class Diaspora
|
|||
|
||||
// Only some message types have signatures. So we quit here for the other types.
|
||||
if (!in_array($type, ["comment", "like"])) {
|
||||
return ["fields" => $fields, "relayed" => false];
|
||||
return $fields;
|
||||
}
|
||||
// No author_signature? This is a must, so we quit.
|
||||
if (!isset($author_signature)) {
|
||||
|
@ -849,25 +831,29 @@ class Diaspora
|
|||
}
|
||||
|
||||
if (isset($parent_author_signature)) {
|
||||
$relayed = true;
|
||||
|
||||
$key = self::key($msg["author"]);
|
||||
if (empty($key)) {
|
||||
logger("No key found for parent author ".$msg["author"], LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) {
|
||||
logger("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$relayed = false;
|
||||
}
|
||||
|
||||
$key = self::key($fields->author);
|
||||
if (empty($key)) {
|
||||
logger("No key found for author ".$fields->author, LOGGER_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) {
|
||||
logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG);
|
||||
return false;
|
||||
} else {
|
||||
return ["fields" => $fields, "relayed" => $relayed];
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1650,25 +1636,23 @@ class Diaspora
|
|||
/**
|
||||
* @brief Processes an account deletion
|
||||
*
|
||||
* @param array $importer Array of the importer user
|
||||
* @param object $data The message object
|
||||
*
|
||||
* @return bool Success
|
||||
*/
|
||||
private static function receiveAccountDeletion($importer, $data)
|
||||
private static function receiveAccountDeletion($data)
|
||||
{
|
||||
/// @todo Account deletion should remove the contact from the global contacts as well
|
||||
|
||||
$author = notags(unxmlify($data->author));
|
||||
|
||||
$contact = self::contactByHandle($importer["uid"], $author);
|
||||
if (!$contact) {
|
||||
logger("cannot find contact for author: ".$author);
|
||||
return false;
|
||||
$contacts = dba::select('contact', ['id'], ['addr' => $author]);
|
||||
while ($contact = dba::fetch($contacts)) {
|
||||
Contact::remove($contact["id"]);
|
||||
}
|
||||
|
||||
// We now remove the contact
|
||||
Contact::remove($contact["id"]);
|
||||
dba::delete('gcontact', ['addr' => $author]);
|
||||
|
||||
logger('Removed contacts for ' . $author);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1836,6 +1820,9 @@ class Diaspora
|
|||
|
||||
if ($message_id) {
|
||||
logger("Stored comment ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
|
||||
if ($datarray['uid'] == 0) {
|
||||
Item::distribute($message_id);
|
||||
}
|
||||
}
|
||||
|
||||
// If we are the origin of the parent we store the original data and notify our followers
|
||||
|
@ -2157,6 +2144,9 @@ class Diaspora
|
|||
|
||||
if ($message_id) {
|
||||
logger("Stored like ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
|
||||
if ($datarray['uid'] == 0) {
|
||||
Item::distribute($message_id);
|
||||
}
|
||||
}
|
||||
|
||||
// like on comments have the comment as parent. So we need to fetch the toplevel parent
|
||||
|
@ -2739,10 +2729,15 @@ class Diaspora
|
|||
*/
|
||||
public static function originalItem($guid, $orig_author)
|
||||
{
|
||||
if (empty($guid)) {
|
||||
logger('Empty guid. Quitting.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do we already have this item?
|
||||
$fields = ['body', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
||||
'author-name', 'author-link', 'author-avatar'];
|
||||
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false];
|
||||
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false];
|
||||
$item = dba::selectfirst('item', $fields, $condition);
|
||||
|
||||
if (DBM::is_result($item)) {
|
||||
|
@ -2752,7 +2747,7 @@ class Diaspora
|
|||
// Then refetch the content, if it is a reshare from a reshare.
|
||||
// If it is a reshared post from another network then reformat to avoid display problems with two share elements
|
||||
if (self::isReshare($item["body"], true)) {
|
||||
$r = [];
|
||||
$item = [];
|
||||
} elseif (self::isReshare($item["body"], false) || strstr($item["body"], "[share")) {
|
||||
$item["body"] = Markdown::toBBCode(BBCode::toMarkdown($item["body"]));
|
||||
|
||||
|
@ -2767,21 +2762,26 @@ class Diaspora
|
|||
}
|
||||
}
|
||||
|
||||
if (!DBM::is_result($r)) {
|
||||
$server = "https://".substr($orig_author, strpos($orig_author, "@") + 1);
|
||||
logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server);
|
||||
$item_id = self::storeByGuid($guid, $server);
|
||||
|
||||
if (!$item_id) {
|
||||
$server = "http://".substr($orig_author, strpos($orig_author, "@") + 1);
|
||||
logger("2nd try: reshared message ".$guid." will be fetched without SLL from the server ".$server);
|
||||
$item_id = self::storeByGuid($guid, $server);
|
||||
if (!DBM::is_result($item)) {
|
||||
if (empty($orig_author)) {
|
||||
logger('Empty author for guid ' . $guid . '. Quitting.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($item_id) {
|
||||
$server = "https://".substr($orig_author, strpos($orig_author, "@") + 1);
|
||||
logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server);
|
||||
$stored = self::storeByGuid($guid, $server);
|
||||
|
||||
if (!$stored) {
|
||||
$server = "http://".substr($orig_author, strpos($orig_author, "@") + 1);
|
||||
logger("2nd try: reshared message ".$guid." will be fetched without SSL from the server ".$server);
|
||||
$stored = self::storeByGuid($guid, $server);
|
||||
}
|
||||
|
||||
if ($stored) {
|
||||
$fields = ['body', 'tag', 'app', 'created', 'object-type', 'uri', 'guid',
|
||||
'author-name', 'author-link', 'author-avatar'];
|
||||
$condition = ['id' => $item_id, 'visible' => true, 'deleted' => false];
|
||||
$condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false];
|
||||
$item = dba::selectfirst('item', $fields, $condition);
|
||||
|
||||
if (DBM::is_result($item)) {
|
||||
|
@ -2883,6 +2883,9 @@ class Diaspora
|
|||
|
||||
if ($message_id) {
|
||||
logger("Stored reshare ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
|
||||
if ($datarray['uid'] == 0) {
|
||||
Item::distribute($message_id);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -3107,6 +3110,9 @@ class Diaspora
|
|||
|
||||
if ($message_id) {
|
||||
logger("Stored item ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
|
||||
if ($datarray['uid'] == 0) {
|
||||
Item::distribute($message_id);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -36,7 +36,30 @@ class Network
|
|||
*/
|
||||
public static function fetchUrl($url, $binary = false, &$redirects = 0, $timeout = 0, $accept_content = null, $cookiejar = 0)
|
||||
{
|
||||
$ret = self::curl(
|
||||
$ret = self::fetchUrlFull($url, $binary, $redirects, $timeout, $accept_content, $cookiejar);
|
||||
|
||||
return $ret['body'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Curl wrapper with array of return values.
|
||||
*
|
||||
* Inner workings and parameters are the same as @ref fetchUrl but returns an array with
|
||||
* all the information collected during the fetch.
|
||||
*
|
||||
* @param string $url URL to fetch
|
||||
* @param boolean $binary default false
|
||||
* TRUE if asked to return binary results (file download)
|
||||
* @param integer $redirects The recursion counter for internal use - default 0
|
||||
* @param integer $timeout Timeout in seconds, default system config value or 60 seconds
|
||||
* @param string $accept_content supply Accept: header with 'accept_content' as the value
|
||||
* @param string $cookiejar Path to cookie jar file
|
||||
*
|
||||
* @return array With all relevant information, 'body' contains the actual fetched content.
|
||||
*/
|
||||
public static function fetchUrlFull($url, $binary = false, &$redirects = 0, $timeout = 0, $accept_content = null, $cookiejar = 0)
|
||||
{
|
||||
return self::curl(
|
||||
$url,
|
||||
$binary,
|
||||
$redirects,
|
||||
|
@ -45,8 +68,6 @@ class Network
|
|||
'cookiejar'=>$cookiejar
|
||||
]
|
||||
);
|
||||
|
||||
return($ret['body']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,7 +59,7 @@ class Temporal
|
|||
|
||||
$o = '<select id="timezone_select" name="timezone">';
|
||||
|
||||
usort($timezone_identifiers, [self, 'timezoneCompareCallback']);
|
||||
usort($timezone_identifiers, [__CLASS__, 'timezoneCompareCallback']);
|
||||
$continent = '';
|
||||
foreach ($timezone_identifiers as $value) {
|
||||
$ex = explode("/", $value);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
namespace Friendica\Worker;
|
||||
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\System;
|
||||
|
@ -19,98 +20,67 @@ use dba;
|
|||
|
||||
require_once 'include/items.php';
|
||||
|
||||
/// @todo This is some ugly code that needs to be split into several methods
|
||||
class Delivery extends BaseObject
|
||||
{
|
||||
const MAIL = 'mail';
|
||||
const SUGGESTION = 'suggest';
|
||||
const RELOCATION = 'relocate';
|
||||
const DELETION = 'drop';
|
||||
const POST = 'wall-new';
|
||||
const COMMENT = 'comment-new';
|
||||
|
||||
class Delivery {
|
||||
public static function execute($cmd, $item_id, $contact_id) {
|
||||
global $a;
|
||||
public static function execute($cmd, $item_id, $contact_id)
|
||||
{
|
||||
logger('Invoked: ' . $cmd . ': ' . $item_id . ' to ' . $contact_id, LOGGER_DEBUG);
|
||||
|
||||
logger('delivery: invoked: '.$cmd.': '.$item_id.' to '.$contact_id, LOGGER_DEBUG);
|
||||
|
||||
$mail = false;
|
||||
$fsuggest = false;
|
||||
$relocate = false;
|
||||
$top_level = false;
|
||||
$recipients = [];
|
||||
$followup = false;
|
||||
$public_message = false;
|
||||
|
||||
$normal_mode = true;
|
||||
|
||||
$item = null;
|
||||
|
||||
$recipients[] = $contact_id;
|
||||
|
||||
if ($cmd === 'mail') {
|
||||
$normal_mode = false;
|
||||
$mail = true;
|
||||
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if (!count($message)) {
|
||||
if ($cmd == self::MAIL) {
|
||||
$target_item = dba::selectFirst('mail', [], ['id' => $item_id]);
|
||||
if (!DBM::is_result($message)) {
|
||||
return;
|
||||
}
|
||||
$uid = $message[0]['uid'];
|
||||
$recipients[] = $message[0]['contact-id'];
|
||||
$item = $message[0];
|
||||
} elseif ($cmd === 'suggest') {
|
||||
$normal_mode = false;
|
||||
$fsuggest = true;
|
||||
|
||||
$suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if (!count($suggest)) {
|
||||
$uid = $target_item['uid'];
|
||||
} elseif ($cmd == self::SUGGESTION) {
|
||||
$target_item = dba::selectFirst('fsuggest', [], ['id' => $item_id]);
|
||||
if (!DBM::is_result($message)) {
|
||||
return;
|
||||
}
|
||||
$uid = $suggest[0]['uid'];
|
||||
$recipients[] = $suggest[0]['cid'];
|
||||
$item = $suggest[0];
|
||||
} elseif ($cmd === 'relocate') {
|
||||
$normal_mode = false;
|
||||
$relocate = true;
|
||||
$uid = $target_item['uid'];
|
||||
} elseif ($cmd == self::RELOCATION) {
|
||||
$uid = $item_id;
|
||||
} else {
|
||||
// find ancestors
|
||||
$target_item = dba::fetch_first("SELECT `item`.*, `contact`.`uid` AS `cuid` FROM `item`
|
||||
$item = dba::selectFirst('item', ['parent'], ['id' => $item_id]);
|
||||
if (!DBM::is_result($item) || empty($item['parent'])) {
|
||||
return;
|
||||
}
|
||||
$parent_id = intval($item['parent']);
|
||||
|
||||
$itemdata = dba::p("SELECT `item`.*, `contact`.`uid` AS `cuid`,
|
||||
`sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
|
||||
FROM `item`
|
||||
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
|
||||
WHERE `item`.`id` = ? AND `visible` AND NOT `moderated`", $item_id);
|
||||
|
||||
if (!DBM::is_result($target_item) || !intval($target_item['parent'])) {
|
||||
return;
|
||||
LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`
|
||||
WHERE `item`.`id` IN (?, ?) AND `visible` AND NOT `moderated`
|
||||
ORDER BY `item`.`id`",
|
||||
$item_id, $parent_id);
|
||||
$items = [];
|
||||
while ($item = dba::fetch($itemdata)) {
|
||||
if ($item['id'] == $parent_id) {
|
||||
$parent = $item;
|
||||
}
|
||||
if ($item['id'] == $item_id) {
|
||||
$target_item = $item;
|
||||
}
|
||||
$items[] = $item;
|
||||
}
|
||||
dba::close($itemdata);
|
||||
|
||||
$parent_id = intval($target_item['parent']);
|
||||
$uid = $target_item['cuid'];
|
||||
$updated = $target_item['edited'];
|
||||
|
||||
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
|
||||
FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d AND visible = 1 AND moderated = 0 ORDER BY `id` ASC",
|
||||
intval($parent_id)
|
||||
);
|
||||
|
||||
if (!count($items)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$icontacts = null;
|
||||
$contacts_arr = [];
|
||||
foreach ($items as $item) {
|
||||
if (!in_array($item['contact-id'],$contacts_arr)) {
|
||||
$contacts_arr[] = intval($item['contact-id']);
|
||||
}
|
||||
}
|
||||
if (count($contacts_arr)) {
|
||||
$str_contacts = implode(',',$contacts_arr);
|
||||
$icontacts = q("SELECT * FROM `contact`
|
||||
WHERE `id` IN ( $str_contacts ) "
|
||||
);
|
||||
}
|
||||
if ( !($icontacts && count($icontacts))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid race condition with deleting entries
|
||||
|
||||
if ($items[0]['deleted']) {
|
||||
foreach ($items as $item) {
|
||||
$item['deleted'] = 1;
|
||||
|
@ -120,24 +90,10 @@ class Delivery {
|
|||
// When commenting too fast after delivery, a post wasn't recognized as top level post.
|
||||
// The count then showed more than one entry. The additional check should help.
|
||||
// The check for the "count" should be superfluous, but I'm not totally sure by now, so we keep it.
|
||||
if ((($items[0]['id'] == $item_id) || (count($items) == 1)) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
|
||||
logger('delivery: top level post');
|
||||
if ((($parent['id'] == $item_id) || (count($items) == 1)) && ($parent['uri'] === $parent['parent-uri'])) {
|
||||
logger('Top level post');
|
||||
$top_level = true;
|
||||
}
|
||||
}
|
||||
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
if (!$owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't treat Forum posts as "wall-to-wall" to be able to post them via Diaspora
|
||||
$walltowall = $top_level && ($owner['id'] != $items[0]['contact-id']) & ($owner['account-type'] != ACCOUNT_TYPE_COMMUNITY);
|
||||
|
||||
$public_message = true;
|
||||
|
||||
if (!$mail && !$fsuggest && !$relocate) {
|
||||
$parent = $items[0];
|
||||
|
||||
// This is IMPORTANT!!!!
|
||||
|
||||
|
@ -147,7 +103,7 @@ class Delivery {
|
|||
// if $parent['wall'] == 1 we will already have the parent message in our array
|
||||
// and we will relay the whole lot.
|
||||
|
||||
$localhost = $a->get_hostname();
|
||||
$localhost = self::getApp()->get_hostname();
|
||||
if (strpos($localhost, ':')) {
|
||||
$localhost = substr($localhost, 0, strpos($localhost, ':'));
|
||||
}
|
||||
|
@ -159,26 +115,24 @@ class Delivery {
|
|||
*
|
||||
*/
|
||||
|
||||
$relay_to_owner = false;
|
||||
|
||||
if (!$top_level && ($parent['wall'] == 0) && stristr($target_item['uri'], $localhost)) {
|
||||
$relay_to_owner = true;
|
||||
}
|
||||
|
||||
if ($relay_to_owner) {
|
||||
logger('followup '.$target_item["guid"], LOGGER_DEBUG);
|
||||
logger('Followup ' . $target_item["guid"], LOGGER_DEBUG);
|
||||
// local followup to remote post
|
||||
$followup = true;
|
||||
}
|
||||
|
||||
if (strlen($parent['allow_cid'])
|
||||
|| strlen($parent['allow_gid'])
|
||||
|| strlen($parent['deny_cid'])
|
||||
|| strlen($parent['deny_gid'])
|
||||
|| $parent["private"]) {
|
||||
$public_message = false; // private recipients, not public
|
||||
if (empty($parent['allow_cid'])
|
||||
&& empty($parent['allow_gid'])
|
||||
&& empty($parent['deny_cid'])
|
||||
&& empty($parent['deny_gid'])
|
||||
&& !$parent["private"]) {
|
||||
$public_message = true;
|
||||
}
|
||||
}
|
||||
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
if (!DBM::is_result($owner)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't deliver our items to blocked or pending contacts, and not to ourselves either
|
||||
|
@ -189,146 +143,22 @@ class Delivery {
|
|||
return;
|
||||
}
|
||||
|
||||
$deliver_status = 0;
|
||||
|
||||
// Transmit via Diaspora if not possible via Friendica
|
||||
if (($item['uid'] == 0) && ($contact['network'] == NETWORK_DFRN)) {
|
||||
// Transmit via Diaspora if the thread had started as Diaspora post
|
||||
// This is done since the uri wouldn't match (Diaspora doesn't transmit it)
|
||||
if (isset($parent) && ($parent['network'] == NETWORK_DIASPORA) && ($contact['network'] == NETWORK_DFRN)) {
|
||||
$contact['network'] = NETWORK_DIASPORA;
|
||||
}
|
||||
|
||||
logger("main delivery by delivery: followup=$followup mail=$mail fsuggest=$fsuggest relocate=$relocate - network ".$contact['network']);
|
||||
logger("Delivering " . $cmd . " followup=$followup - via network " . $contact['network']);
|
||||
|
||||
switch ($contact['network']) {
|
||||
|
||||
case NETWORK_DFRN:
|
||||
logger('notifier: '.$target_item["guid"].' dfrndelivery: '.$contact['name']);
|
||||
|
||||
if ($mail) {
|
||||
$item['body'] = Item::fixPrivatePhotos($item['body'], $owner['uid'], null, $item['contact-id']);
|
||||
$atom = DFRN::mail($item, $owner);
|
||||
} elseif ($fsuggest) {
|
||||
$atom = DFRN::fsuggest($item, $owner);
|
||||
dba::delete('fsuggest', ['id' => $item['id']]);
|
||||
} elseif ($relocate) {
|
||||
$atom = DFRN::relocate($owner, $uid);
|
||||
} elseif ($followup) {
|
||||
$msgitems = [];
|
||||
foreach ($items as $item) { // there is only one item
|
||||
if (!$item['parent']) {
|
||||
return;
|
||||
}
|
||||
if ($item['id'] == $item_id) {
|
||||
logger('followup: item: '. print_r($item,true), LOGGER_DATA);
|
||||
$msgitems[] = $item;
|
||||
}
|
||||
}
|
||||
$atom = DFRN::entries($msgitems,$owner);
|
||||
} else {
|
||||
$msgitems = [];
|
||||
foreach ($items as $item) {
|
||||
if (!$item['parent']) {
|
||||
return;
|
||||
}
|
||||
|
||||
// private emails may be in included in public conversations. Filter them.
|
||||
if ($public_message && $item['private']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item_contact = self::getItemContact($item,$icontacts);
|
||||
if (!$item_contact) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($normal_mode) {
|
||||
// Only add the parent when we don't delete other items.
|
||||
if ($item_id == $item['id'] || (($item['id'] == $item['parent']) && ($cmd != 'drop'))) {
|
||||
$item["entry:comment-allow"] = true;
|
||||
$item["entry:cid"] = (($top_level) ? $contact['id'] : 0);
|
||||
$msgitems[] = $item;
|
||||
}
|
||||
} else {
|
||||
$item["entry:comment-allow"] = true;
|
||||
$msgitems[] = $item;
|
||||
}
|
||||
}
|
||||
$atom = DFRN::entries($msgitems,$owner);
|
||||
}
|
||||
|
||||
logger('notifier entry: '.$contact["url"].' '.$target_item["guid"].' entry: '.$atom, LOGGER_DEBUG);
|
||||
|
||||
logger('notifier: '.$atom, LOGGER_DATA);
|
||||
$basepath = implode('/', array_slice(explode('/',$contact['url']),0,3));
|
||||
|
||||
// perform local delivery if we are on the same site
|
||||
|
||||
if (link_compare($basepath,System::baseUrl())) {
|
||||
$nickname = basename($contact['url']);
|
||||
if ($contact['issued-id']) {
|
||||
$sql_extra = sprintf(" AND `dfrn-id` = '%s' ", dbesc($contact['issued-id']));
|
||||
} else {
|
||||
$sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($contact['dfrn-id']));
|
||||
}
|
||||
|
||||
$x = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
|
||||
`contact`.`pubkey` AS `cpubkey`,
|
||||
`contact`.`prvkey` AS `cprvkey`,
|
||||
`contact`.`thumb` AS `thumb`,
|
||||
`contact`.`url` as `url`,
|
||||
`contact`.`name` as `senderName`,
|
||||
`user`.*
|
||||
FROM `contact`
|
||||
INNER JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
|
||||
$sql_extra
|
||||
AND `user`.`account_expired` = 0 AND `user`.`account_removed` = 0 LIMIT 1",
|
||||
dbesc(NETWORK_DFRN),
|
||||
dbesc($nickname)
|
||||
);
|
||||
|
||||
if ($x && count($x)) {
|
||||
$write_flag = ((($x[0]['rel']) && ($x[0]['rel'] != CONTACT_IS_SHARING)) ? true : false);
|
||||
if ((($owner['page-flags'] == PAGE_COMMUNITY) || $write_flag) && !$x[0]['writable']) {
|
||||
dba::update('contact', ['writable' => true], ['id' => $x[0]['id']]);
|
||||
$x[0]['writable'] = 1;
|
||||
}
|
||||
|
||||
$ssl_policy = Config::get('system','ssl_policy');
|
||||
$x[0] = Contact::updateSslPolicy($x[0], $ssl_policy);
|
||||
|
||||
// If we are setup as a soapbox we aren't accepting top level posts from this person
|
||||
|
||||
if (($x[0]['page-flags'] == PAGE_SOAPBOX) && $top_level) {
|
||||
self::deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
|
||||
break;
|
||||
}
|
||||
logger('mod-delivery: local delivery');
|
||||
DFRN::import($atom, $x[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Queue::wasDelayed($contact['id'])) {
|
||||
$deliver_status = DFRN::deliver($owner, $contact, $atom);
|
||||
} else {
|
||||
$deliver_status = -1;
|
||||
}
|
||||
|
||||
logger('notifier: dfrn_delivery to '.$contact["url"].' with guid '.$target_item["guid"].' returns '.$deliver_status);
|
||||
|
||||
if ($deliver_status < 0) {
|
||||
logger('notifier: delivery failed: queuing message');
|
||||
Queue::add($contact['id'], NETWORK_DFRN, $atom, false, $target_item['guid']);
|
||||
}
|
||||
|
||||
if (($deliver_status >= 200) && ($deliver_status <= 299)) {
|
||||
// We successfully delivered a message, the contact is alive
|
||||
Contact::unmarkForArchival($contact);
|
||||
} else {
|
||||
// The message could not be delivered. We mark the contact as "dead"
|
||||
Contact::markForArchival($contact);
|
||||
}
|
||||
|
||||
case NETWORK_DIASPORA:
|
||||
self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
|
||||
break;
|
||||
|
||||
case NETWORK_OSTATUS:
|
||||
|
@ -345,156 +175,7 @@ class Delivery {
|
|||
break;
|
||||
|
||||
case NETWORK_MAIL:
|
||||
|
||||
if (Config::get('system','dfrn_only')) {
|
||||
break;
|
||||
}
|
||||
// WARNING: does not currently convert to RFC2047 header encodings, etc.
|
||||
|
||||
$addr = $contact['addr'];
|
||||
if (!strlen($addr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($cmd === 'wall-new' || $cmd === 'comment-new') {
|
||||
$it = null;
|
||||
if ($cmd === 'wall-new') {
|
||||
$it = $items[0];
|
||||
} else {
|
||||
$r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
if (DBM::is_result($r)) {
|
||||
$it = $r[0];
|
||||
}
|
||||
}
|
||||
if (!$it) {
|
||||
break;
|
||||
}
|
||||
|
||||
$local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if (!count($local_user)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$reply_to = '';
|
||||
$r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if ($r1 && $r1[0]['reply_to']) {
|
||||
$reply_to = $r1[0]['reply_to'];
|
||||
}
|
||||
|
||||
$subject = (($it['title']) ? Email::encodeHeader($it['title'],'UTF-8') : L10n::t("\x28no subject\x29")) ;
|
||||
|
||||
// only expose our real email address to true friends
|
||||
|
||||
if (($contact['rel'] == CONTACT_IS_FRIEND) && !$contact['blocked']) {
|
||||
if ($reply_to) {
|
||||
$headers = 'From: '.Email::encodeHeader($local_user[0]['username'],'UTF-8').' <'.$reply_to.'>'."\n";
|
||||
$headers .= 'Sender: '.$local_user[0]['email']."\n";
|
||||
} else {
|
||||
$headers = 'From: '.Email::encodeHeader($local_user[0]['username'],'UTF-8').' <'.$local_user[0]['email'].'>'."\n";
|
||||
}
|
||||
} else {
|
||||
$headers = 'From: '. Email::encodeHeader($local_user[0]['username'], 'UTF-8') . ' <noreply@' . $a->get_hostname() . '>' . "\n";
|
||||
}
|
||||
|
||||
//if ($reply_to)
|
||||
// $headers .= 'Reply-to: '.$reply_to . "\n";
|
||||
|
||||
$headers .= 'Message-Id: <'. Email::iri2msgid($it['uri']).'>'. "\n";
|
||||
|
||||
//logger("Mail: uri: ".$it['uri']." parent-uri ".$it['parent-uri'], LOGGER_DEBUG);
|
||||
//logger("Mail: Data: ".print_r($it, true), LOGGER_DEBUG);
|
||||
//logger("Mail: Data: ".print_r($it, true), LOGGER_DATA);
|
||||
|
||||
if ($it['uri'] !== $it['parent-uri']) {
|
||||
$headers .= "References: <".Email::iri2msgid($it["parent-uri"]).">";
|
||||
|
||||
// If Threading is enabled, write down the correct parent
|
||||
if (($it["thr-parent"] != "") && ($it["thr-parent"] != $it["parent-uri"])) {
|
||||
$headers .= " <".Email::iri2msgid($it["thr-parent"]).">";
|
||||
}
|
||||
$headers .= "\n";
|
||||
|
||||
if (!$it['title']) {
|
||||
$r = q("SELECT `title` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($it['parent-uri']),
|
||||
intval($uid));
|
||||
|
||||
if (DBM::is_result($r) && ($r[0]['title'] != '')) {
|
||||
$subject = $r[0]['title'];
|
||||
} else {
|
||||
$r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($it['parent-uri']),
|
||||
intval($uid));
|
||||
|
||||
if (DBM::is_result($r) && ($r[0]['title'] != '')) {
|
||||
$subject = $r[0]['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strncasecmp($subject,'RE:',3)) {
|
||||
$subject = 'Re: '.$subject;
|
||||
}
|
||||
}
|
||||
Email::send($addr, $subject, $headers, $it);
|
||||
}
|
||||
break;
|
||||
|
||||
case NETWORK_DIASPORA:
|
||||
if ($public_message) {
|
||||
$loc = 'public batch '.$contact['batch'];
|
||||
} else {
|
||||
$loc = $contact['name'];
|
||||
}
|
||||
|
||||
logger('delivery: diaspora batch deliver: '.$loc);
|
||||
|
||||
if (Config::get('system','dfrn_only') || !Config::get('system','diaspora_enabled')) {
|
||||
break;
|
||||
}
|
||||
if ($mail) {
|
||||
Diaspora::sendMail($item,$owner,$contact);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$normal_mode) {
|
||||
break;
|
||||
}
|
||||
if (!$contact['pubkey'] && !$public_message) {
|
||||
break;
|
||||
}
|
||||
if (($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) {
|
||||
// top-level retraction
|
||||
logger('diaspora retract: '.$loc);
|
||||
Diaspora::sendRetraction($target_item,$owner,$contact,$public_message);
|
||||
break;
|
||||
} elseif ($relocate) {
|
||||
Diaspora::sendAccountMigration($owner, $contact, $uid);
|
||||
break;
|
||||
} elseif ($followup) {
|
||||
// send comments and likes to owner to relay
|
||||
logger('diaspora followup: '.$loc);
|
||||
Diaspora::sendFollowup($target_item,$owner,$contact,$public_message);
|
||||
break;
|
||||
} elseif ($target_item['uri'] !== $target_item['parent-uri']) {
|
||||
// we are the relay - send comments, likes and relayable_retractions to our conversants
|
||||
logger('diaspora relay: '.$loc);
|
||||
Diaspora::sendRelay($target_item,$owner,$contact,$public_message);
|
||||
break;
|
||||
} elseif ($top_level && !$walltowall) {
|
||||
// currently no workable solution for sending walltowall
|
||||
logger('diaspora status: '.$loc);
|
||||
Diaspora::sendStatus($target_item,$owner,$contact,$public_message);
|
||||
break;
|
||||
}
|
||||
|
||||
logger('delivery: diaspora unknown mode: '.$contact['name']);
|
||||
|
||||
self::deliverMail($cmd, $contact, $owner, $target_item);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -504,16 +185,268 @@ class Delivery {
|
|||
return;
|
||||
}
|
||||
|
||||
private static function getItemContact($item, $contacts)
|
||||
/**
|
||||
* @brief Deliver content via DFRN
|
||||
*
|
||||
* @param string $cmd Command
|
||||
* @param array $contact Contact record of the receiver
|
||||
* @param array $owner Owner record of the sender
|
||||
* @param array $items Item record of the content and the parent
|
||||
* @param array $target_item Item record of the content
|
||||
* @param boolean $public_message Is the content public?
|
||||
* @param boolean $top_level Is it a thread starter?
|
||||
* @param boolean $followup Is it an answer to a remote post?
|
||||
*/
|
||||
private static function deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup)
|
||||
{
|
||||
if (!count($contacts) || !is_array($item)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($contacts as $contact) {
|
||||
if ($contact['id'] == $item['contact-id']) {
|
||||
return $contact;
|
||||
logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . $contact['addr']);
|
||||
|
||||
if ($cmd == self::MAIL) {
|
||||
$item = $target_item;
|
||||
$item['body'] = Item::fixPrivatePhotos($item['body'], $owner['uid'], null, $item['contact-id']);
|
||||
$atom = DFRN::mail($item, $owner);
|
||||
} elseif ($cmd == self::SUGGESTION) {
|
||||
$item = $target_item;
|
||||
$atom = DFRN::fsuggest($item, $owner);
|
||||
dba::delete('fsuggest', ['id' => $item['id']]);
|
||||
} elseif ($cmd == self::RELOCATION) {
|
||||
$atom = DFRN::relocate($owner, $owner['uid']);
|
||||
} elseif ($followup) {
|
||||
$msgitems = [$target_item];
|
||||
$atom = DFRN::entries($msgitems, $owner);
|
||||
} else {
|
||||
$msgitems = [];
|
||||
foreach ($items as $item) {
|
||||
// Only add the parent when we don't delete other items.
|
||||
if (($target_item['id'] == $item['id']) || ($cmd != self::DELETION)) {
|
||||
$item["entry:comment-allow"] = true;
|
||||
$item["entry:cid"] = ($top_level ? $contact['id'] : 0);
|
||||
$msgitems[] = $item;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
$atom = DFRN::entries($msgitems, $owner);
|
||||
}
|
||||
|
||||
logger('Notifier entry: ' . $contact["url"] . ' ' . $target_item["guid"] . ' entry: ' . $atom, LOGGER_DATA);
|
||||
|
||||
$basepath = implode('/', array_slice(explode('/', $contact['url']), 0, 3));
|
||||
|
||||
// perform local delivery if we are on the same site
|
||||
|
||||
if (link_compare($basepath, System::baseUrl())) {
|
||||
$condition = ['nurl' => normalise_link($contact['url']), 'self' => true];
|
||||
$target_self = dba::selectFirst('contact', ['uid'], $condition);
|
||||
if (!DBM::is_result($target_self)) {
|
||||
return;
|
||||
}
|
||||
$target_uid = $target_self['uid'];
|
||||
|
||||
// Check if the user has got this contact
|
||||
$cid = Contact::getIdForURL($owner['url'], $target_uid);
|
||||
if (!$cid) {
|
||||
// Otherwise there should be a public contact
|
||||
$cid = Contact::getIdForURL($owner['url']);
|
||||
if (!$cid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We now have some contact, so we fetch it
|
||||
$target_importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
||||
FROM `contact`
|
||||
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
||||
$cid);
|
||||
|
||||
// This should never fail
|
||||
if (!DBM::is_result($target_importer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the user id. This is important if this is a public contact
|
||||
$target_importer['importer_uid'] = $target_uid;
|
||||
DFRN::import($atom, $target_importer);
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't have a relationship with contacts on a public post.
|
||||
// Se we transmit with the new method and via Diaspora as a fallback
|
||||
if ($items[0]['uid'] == 0) {
|
||||
// Transmit in public if it's a relay post
|
||||
$public_dfrn = ($contact['contact-type'] == ACCOUNT_TYPE_RELAY);
|
||||
|
||||
$deliver_status = DFRN::transmit($owner, $contact, $atom, $public_dfrn);
|
||||
if (($deliver_status < 200) || ($deliver_status > 299)) {
|
||||
// Transmit via Diaspora if not possible via Friendica
|
||||
self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$deliver_status = DFRN::deliver($owner, $contact, $atom);
|
||||
}
|
||||
|
||||
logger('Delivery to ' . $contact["url"] . ' with guid ' . $target_item["guid"] . ' returns ' . $deliver_status);
|
||||
|
||||
if ($deliver_status < 0) {
|
||||
logger('Delivery failed: queuing message ' . $target_item["guid"] );
|
||||
Queue::add($contact['id'], NETWORK_DFRN, $atom, false, $target_item['guid']);
|
||||
}
|
||||
|
||||
if (($deliver_status >= 200) && ($deliver_status <= 299)) {
|
||||
// We successfully delivered a message, the contact is alive
|
||||
Contact::unmarkForArchival($contact);
|
||||
} else {
|
||||
// The message could not be delivered. We mark the contact as "dead"
|
||||
Contact::markForArchival($contact);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deliver content via Diaspora
|
||||
*
|
||||
* @param string $cmd Command
|
||||
* @param array $contact Contact record of the receiver
|
||||
* @param array $owner Owner record of the sender
|
||||
* @param array $items Item record of the content and the parent
|
||||
* @param array $target_item Item record of the content
|
||||
* @param boolean $public_message Is the content public?
|
||||
* @param boolean $top_level Is it a thread starter?
|
||||
* @param boolean $followup Is it an answer to a remote post?
|
||||
*/
|
||||
private static function deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup)
|
||||
{
|
||||
// We don't treat Forum posts as "wall-to-wall" to be able to post them via Diaspora
|
||||
$walltowall = $top_level && ($owner['id'] != $items[0]['contact-id']) & ($owner['account-type'] != ACCOUNT_TYPE_COMMUNITY);
|
||||
|
||||
if ($public_message) {
|
||||
$loc = 'public batch ' . $contact['batch'];
|
||||
} else {
|
||||
$loc = $contact['addr'];
|
||||
}
|
||||
|
||||
logger('Deliver ' . $target_item["guid"] . ' via Diaspora to ' . $loc);
|
||||
|
||||
if (Config::get('system', 'dfrn_only') || !Config::get('system', 'diaspora_enabled')) {
|
||||
return;
|
||||
}
|
||||
if ($cmd == self::MAIL) {
|
||||
Diaspora::sendMail($target_item, $owner, $contact);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($cmd == self::SUGGESTION) {
|
||||
return;
|
||||
}
|
||||
if (!$contact['pubkey'] && !$public_message) {
|
||||
return;
|
||||
}
|
||||
if (($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) {
|
||||
// top-level retraction
|
||||
logger('diaspora retract: ' . $loc);
|
||||
Diaspora::sendRetraction($target_item, $owner, $contact, $public_message);
|
||||
return;
|
||||
} elseif ($cmd == self::RELOCATION) {
|
||||
Diaspora::sendAccountMigration($owner, $contact, $owner['uid']);
|
||||
return;
|
||||
} elseif ($followup) {
|
||||
// send comments and likes to owner to relay
|
||||
logger('diaspora followup: ' . $loc);
|
||||
Diaspora::sendFollowup($target_item, $owner, $contact, $public_message);
|
||||
return;
|
||||
} elseif ($target_item['uri'] !== $target_item['parent-uri']) {
|
||||
// we are the relay - send comments, likes and relayable_retractions to our conversants
|
||||
logger('diaspora relay: ' . $loc);
|
||||
Diaspora::sendRelay($target_item, $owner, $contact, $public_message);
|
||||
return;
|
||||
} elseif ($top_level && !$walltowall) {
|
||||
// currently no workable solution for sending walltowall
|
||||
logger('diaspora status: ' . $loc);
|
||||
Diaspora::sendStatus($target_item, $owner, $contact, $public_message);
|
||||
return;
|
||||
}
|
||||
|
||||
logger('Unknown mode ' . $cmd . ' for ' . $loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deliver content via mail
|
||||
*
|
||||
* @param string $cmd Command
|
||||
* @param array $contact Contact record of the receiver
|
||||
* @param array $owner Owner record of the sender
|
||||
* @param array $target_item Item record of the content
|
||||
*/
|
||||
private static function deliverMail($cmd, $contact, $owner, $target_item)
|
||||
{
|
||||
if (Config::get('system','dfrn_only')) {
|
||||
return;
|
||||
}
|
||||
// WARNING: does not currently convert to RFC2047 header encodings, etc.
|
||||
|
||||
$addr = $contact['addr'];
|
||||
if (!strlen($addr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($cmd, [self::POST, self::COMMENT])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$local_user = dba::selectFirst('user', [], ['uid' => $owner['uid']]);
|
||||
if (!DBM::is_result($local_user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger('Deliver ' . $target_item["guid"] . ' via mail to ' . $contact['addr']);
|
||||
|
||||
$reply_to = '';
|
||||
$mailacct = dba::selectFirst('mailacct', ['reply_to'], ['uid' => $owner['uid']]);
|
||||
if (DBM::is_result($mailacct) && !empty($mailacct['reply_to'])) {
|
||||
$reply_to = $mailacct['reply_to'];
|
||||
}
|
||||
|
||||
$subject = ($target_item['title'] ? Email::encodeHeader($target_item['title'], 'UTF-8') : L10n::t("\x28no subject\x29"));
|
||||
|
||||
// only expose our real email address to true friends
|
||||
|
||||
if (($contact['rel'] == CONTACT_IS_FRIEND) && !$contact['blocked']) {
|
||||
if ($reply_to) {
|
||||
$headers = 'From: ' . Email::encodeHeader($local_user['username'],'UTF-8') . ' <' . $reply_to.'>' . "\n";
|
||||
$headers .= 'Sender: ' . $local_user['email'] . "\n";
|
||||
} else {
|
||||
$headers = 'From: ' . Email::encodeHeader($local_user['username'],'UTF-8').' <' . $local_user['email'] . '>' . "\n";
|
||||
}
|
||||
} else {
|
||||
$headers = 'From: '. Email::encodeHeader($local_user['username'], 'UTF-8') . ' <noreply@' . self::getApp()->get_hostname() . '>' . "\n";
|
||||
}
|
||||
|
||||
$headers .= 'Message-Id: <' . Email::iri2msgid($target_item['uri']) . '>' . "\n";
|
||||
|
||||
if ($target_item['uri'] !== $target_item['parent-uri']) {
|
||||
$headers .= "References: <" . Email::iri2msgid($target_item["parent-uri"]) . ">";
|
||||
|
||||
// If Threading is enabled, write down the correct parent
|
||||
if (($target_item["thr-parent"] != "") && ($target_item["thr-parent"] != $target_item["parent-uri"])) {
|
||||
$headers .= " <".Email::iri2msgid($target_item["thr-parent"]).">";
|
||||
}
|
||||
$headers .= "\n";
|
||||
|
||||
if (empty($target_item['title'])) {
|
||||
$condition = ['uri' => $target_item['parent-uri'], 'uid' => $owner['uid']];
|
||||
$title = dba::selectFirst('item', ['title'], $condition);
|
||||
if (DBM::is_result($title) && ($title['title'] != '')) {
|
||||
$subject = $title['title'];
|
||||
} else {
|
||||
$condition = ['parent-uri' => $target_item['parent-uri'], 'uid' => $owner['uid']];
|
||||
$title = dba::selectFirst('item', ['title'], $condition);
|
||||
if (DBM::is_result($title) && ($title['title'] != '')) {
|
||||
$subject = $title['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strncasecmp($subject, 'RE:', 3)) {
|
||||
$subject = 'Re: ' . $subject;
|
||||
}
|
||||
}
|
||||
Email::send($addr, $subject, $headers, $target_item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class PubSubPublish {
|
|||
$rr['topic']),
|
||||
"X-Hub-Signature: sha1=".$hmac_sig];
|
||||
|
||||
logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DEBUG);
|
||||
logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DATA);
|
||||
|
||||
Network::post($rr['callback_url'], $params, $headers);
|
||||
$ret = $a->get_curl_code();
|
||||
|
|
|
@ -63,7 +63,7 @@ class Queue
|
|||
return;
|
||||
}
|
||||
|
||||
if (empty($contact['notify'])) {
|
||||
if (empty($contact['notify']) || $contact['archive']) {
|
||||
QueueModel::removeItem($q_item['id']);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@ namespace Friendica\Test;
|
|||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseObject;
|
||||
use PHPUnit_Framework_TestCase;
|
||||
|
||||
// backward compatibility
|
||||
if (!class_exists('\PHPUnit\Framework\TestCase')) {
|
||||
class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
|
||||
}
|
||||
/**
|
||||
* Tests for the BaseObject class.
|
||||
*/
|
||||
class BaseObjectTest extends PHPUnit_Framework_TestCase
|
||||
class BaseObjectTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
|
||||
namespace Friendica\Test;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
// backward compatibility
|
||||
if (!class_exists('\PHPUnit\Framework\TestCase')) {
|
||||
class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for text functions.
|
||||
*/
|
||||
class TextTest extends PHPUnit_Framework_TestCase
|
||||
class TextTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -61,10 +64,10 @@ class TextTest extends PHPUnit_Framework_TestCase
|
|||
public function testAutonameLength1()
|
||||
{
|
||||
$autoname1=autoname(1);
|
||||
$this->assertEquals(1, count($autoname1));
|
||||
$this->assertEquals(1, strlen($autoname1));
|
||||
|
||||
$autoname2=autoname(1);
|
||||
$this->assertEquals(1, count($autoname2));
|
||||
$this->assertEquals(1, strlen($autoname2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,6 +12,7 @@ Alexandre Alapetite
|
|||
AlfredSK
|
||||
Andi Stadler
|
||||
Andreas H.
|
||||
Andreas Neustifter
|
||||
Andrej Stieben
|
||||
André Alves
|
||||
André Lohan
|
||||
|
|
|
@ -65,7 +65,7 @@ $a->config['system']['no_regfullname'] = true;
|
|||
//$a->config['system']['block_local_dir'] = false;
|
||||
|
||||
// Location of the global directory
|
||||
$a->config['system']['directory'] = 'http://dir.friendica.social';
|
||||
$a->config['system']['directory'] = 'https://dir.friendica.social';
|
||||
|
||||
// turn on friendica's log
|
||||
$a->config['system']['debugging'] = true;
|
||||
|
|
12587
util/messages.po
12587
util/messages.po
File diff suppressed because it is too large
Load diff
|
@ -202,9 +202,17 @@ blockquote.shared_content {
|
|||
}
|
||||
|
||||
#profile-photo-wrapper {
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#newmember-tips {
|
||||
font-size: 1.2em;
|
||||
float: right;
|
||||
margin-top: -32px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* headers */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 5px 0px 5px 0px;
|
||||
|
|
|
@ -32,6 +32,9 @@ td.help {
|
|||
td.help blockquote {
|
||||
margin-left: 60px;
|
||||
}
|
||||
.error_header {
|
||||
margin-left: 60px;
|
||||
}
|
||||
input[type="submit"] {
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
|
12970
view/lang/de/messages.po
12970
view/lang/de/messages.po
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
13056
view/lang/pl/messages.po
13056
view/lang/pl/messages.po
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,8 @@
|
|||
<div class="field checkbox" id="div_id_{{$field.0}}">
|
||||
<label for="id_{{$field.0}}">{{$field.1}}</label>
|
||||
<label id="id_{{$field.0}}_label" for="id_{{$field.0}}">{{$field.1}}</label>
|
||||
<input type="hidden" name="{{$field.0}}" value="0">
|
||||
<input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" aria-describedby="{{$field.0}}_tip" value="1" {{if $field.2}}checked="checked"{{/if}} {{if $field.4}}{{$field.4}}{{/if}}>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
{{foreach $field.4 as $opt=>$val}}<option value="{{$val|escape:'html'}}">{{$val}}</option>{{/foreach}}
|
||||
</select>
|
||||
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,5 +3,7 @@
|
|||
<div class='field custom'>
|
||||
<label for='{{$field.0}}'>{{$field.1}}</label>
|
||||
{{$field.2}}
|
||||
<span class='field_help'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -2,5 +2,7 @@
|
|||
<div class='field input' id='wrapper_{{$field.0}}'>
|
||||
<label for='id_{{$field.0}}'>{{$field.1}}</label>
|
||||
<input{{if $field.6 eq 'email'}} type='email'{{elseif $field.6 eq 'url'}} type='url'{{else}} type="text"{{/if}} name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.2|escape:'html'}}"{{if $field.4 eq 'required'}} required{{/if}}{{if $field.5 eq "autofocus"}} autofocus{{elseif $field.5}} {{$field.5}}{{/if}} aria-describedby='{{$field.0}}_tip'>
|
||||
{{if $field.3}}
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -3,5 +3,7 @@
|
|||
<div class='field checkbox'>
|
||||
<label for='id_{{$field.0}}'>{{$field.1}}</label>
|
||||
<input type="checkbox" name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.3|escape:'html'}}" {{if $field.2}}checked="true"{{/if}} aria-describedby='{{$field.0}}_tip'>
|
||||
{{if $field.4}}
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.4}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -2,5 +2,7 @@
|
|||
<div class='field input openid' id='wrapper_{{$field.0}}'>
|
||||
<label for='id_{{$field.0}}'>{{$field.1}}</label>
|
||||
<input name='{{$field.0}}' id='id_{{$field.0}}' type="text" value="{{$field.2|escape:'html'}}" aria-describedby='{{$field.0}}_tip'>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -2,5 +2,7 @@
|
|||
<div class='field password' id='wrapper_{{$field.0}}'>
|
||||
<label for='id_{{$field.0}}'>{{$field.1}}</label>
|
||||
<input type='password' name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.2|escape:'html'}}"{{if $field.4 eq 'required'}} required{{/if}}{{if $field.5 eq 'autofocus'}} autofocus{{/if}} aria-describedby='{{$field.0}}_tip'>
|
||||
{{if $field.3}}
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<div class='field radio'>
|
||||
<label for='id_{{$field.0}}_{{$field.2}}'>{{$field.1}}</label>
|
||||
<input type="radio" name='{{$field.0}}' id='id_{{$field.0}}_{{$field.2}}' value="{{$field.2|escape:'html'}}" {{if $field.4}}checked{{/if}} aria-describedby={{$field.0}}_{{$field.2}}_tip'>
|
||||
{{if $field.3}}
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_{{$field.2}}_tip'>{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -3,5 +3,7 @@
|
|||
<div class='field richtext'>
|
||||
<label for='id_{{$field.0}}'>{{$field.1}}</label>
|
||||
<textarea name='{{$field.0}}' id='id_{{$field.0}}' class="fieldRichtext" aria-describedby='{{$field.0}}_tip'>{{$field.2}}</textarea>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<select name='{{$field.0}}' id='id_{{$field.0}}' aria-describedby='{{$field.0}}_tip'>
|
||||
{{foreach $field.4 as $opt=>$val}}<option value="{{$opt|escape:'html'}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option>{{/foreach}}
|
||||
</select>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<select name='{{$field.0}}' id='id_{{$field.0}}' aria-describedby='{{$field.0}}_tip'>
|
||||
{{$field.4}}
|
||||
</select>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -3,5 +3,7 @@
|
|||
<div class='field textarea'>
|
||||
<label for='id_{{$field.0}}'>{{$field.1}}</label>
|
||||
<textarea name='{{$field.0}}' id='id_{{$field.0}}' aria-describedby='{{$field.0}}_tip'>{{$field.2}}</textarea>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
<select name='{{$field.0}}' id='id_{{$field.0}}' {{if $field.5}}onchange="previewTheme(this);"{{/if}} aria-describedby='{{$field.0}}_tip'>
|
||||
{{foreach $field.4 as $opt=>$val}}<option value="{{$opt|escape:'html'}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option>{{/foreach}}
|
||||
</select>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
{{if $field.5}}<div id="theme-preview"></div>{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -10,5 +10,7 @@
|
|||
{{if $field.4}}{{$field.4.1}}{{else}}ON{{/if}}
|
||||
</a>
|
||||
</div>
|
||||
<span class='field_help' role='tooltip' id='{{$field.0}}_tip'>{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="field_help" role="tooltip" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -107,7 +107,7 @@ $a->config['system']['no_regfullname'] = true;
|
|||
//$a->config['system']['block_local_dir'] = false;
|
||||
|
||||
// Location of the global directory
|
||||
$a->config['system']['directory'] = 'http://dir.friendica.social';
|
||||
$a->config['system']['directory'] = 'https://dir.friendica.social';
|
||||
|
||||
// Authentication cookie lifetime, in days
|
||||
$a->config['system']['auth_cookie_lifetime'] = 7;
|
||||
|
|
|
@ -16,7 +16,13 @@
|
|||
{{/if}}
|
||||
</td><td>{{if $check.required}}(required){{/if}}</td></tr>
|
||||
{{if $check.help}}
|
||||
<tr><td class="help" colspan="3"><blockquote>{{$check.help}}</blockquote></td></tr>
|
||||
<tr><td class="help" colspan="3">
|
||||
<blockquote>{{$check.help}}</blockquote>
|
||||
{{if $check.error_msg}}
|
||||
<div class="error_header"><b>{{$check.error_msg.head}}</br><a href="{{$check.error_msg.url}}">{{$check.error_msg.url}}</a></b></div>
|
||||
<blockquote>{{$check.error_msg.msg}}</blockquote>
|
||||
{{/if}}
|
||||
</td></tr>
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
</table>
|
||||
|
|
|
@ -5,23 +5,10 @@
|
|||
|
||||
<div id="invite-wrapper">
|
||||
|
||||
<h3>{{$invite}}</h3>
|
||||
<h3>{{$title}}</h3>
|
||||
|
||||
<div id="invite-recipient-text">
|
||||
{{$addr_text}}
|
||||
</div>
|
||||
|
||||
<div id="invite-recipient-textarea">
|
||||
<textarea id="invite-recipients" name="recipients" rows="8" cols="32" ></textarea>
|
||||
</div>
|
||||
|
||||
<div id="invite-message-text">
|
||||
{{$msg_text}}
|
||||
</div>
|
||||
|
||||
<div id="invite-message-textarea">
|
||||
<textarea id="invite-message" name="message" rows="10" cols="72" >{{$default_message}}</textarea>
|
||||
</div>
|
||||
{{include file="field_textarea.tpl" field=$recipients}}
|
||||
{{include file="field_textarea.tpl" field=$message}}
|
||||
|
||||
<div id="invite-submit-wrapper">
|
||||
<input type="submit" name="submit" value="{{$submit|escape:'html'}}" />
|
||||
|
|
|
@ -4,11 +4,14 @@
|
|||
<div id="login-group" role="group" aria-labelledby="login-head">
|
||||
<input type="hidden" name="auth-params" value="login" />
|
||||
|
||||
<div id="login-head" class="sr-only">{{$login}}</div>
|
||||
<h3 id="login-head" class="sr-only">{{$login}}</h3>
|
||||
|
||||
<div id="login_standard">
|
||||
{{include file="field_input.tpl" field=$lname}}
|
||||
{{include file="field_password.tpl" field=$lpassword}}
|
||||
<div id="login-lost-password-link">
|
||||
<a href="lostpass" title="{{$lostpass|escape:'html'}}" id="lost-password-link" >{{$lostlink}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if $openid}}
|
||||
|
@ -17,17 +20,12 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{include file="field_checkbox.tpl" field=$lremember}}
|
||||
|
||||
<div id="login-extra-links">
|
||||
{{if $register}}<a href="register" title="{{$register.title|escape:'html'}}" id="register-link">{{$register.desc}}</a>{{/if}}
|
||||
<a href="lostpass" title="{{$lostpass|escape:'html'}}" id="lost-password-link" >{{$lostlink}}</a>
|
||||
</div>
|
||||
|
||||
<div id="login-submit-wrapper" >
|
||||
<input type="submit" name="submit" id="login-submit-button" value="{{$login|escape:'html'}}" />
|
||||
</div>
|
||||
|
||||
{{include file="field_checkbox.tpl" field=$lremember}}
|
||||
|
||||
{{foreach $hiddens as $k=>$v}}
|
||||
<input type="hidden" name="{{$k}}" value="{{$v|escape:'html'}}" />
|
||||
{{/foreach}}
|
||||
|
@ -35,5 +33,11 @@
|
|||
</div>
|
||||
</form>
|
||||
|
||||
{{if $register}}
|
||||
<div id="login-extra-links">
|
||||
<h3 id="login-head" class="sr-only">{{$register.title|escape:'html'}}</h3>
|
||||
<a href="register" title="{{$register.title|escape:'html'}}" id="register-link">{{$register.desc}}</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<script type="text/javascript"> $(document).ready(function() { $("#id_{{$lname.0}}").focus();} );</script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{{if $pager && ($pager.prev || $pager.next)}}
|
||||
<div class="pager">
|
||||
{{if $pager}}
|
||||
{{if $pager.prev}}<span class="pager_prev {{$pager.prev.class}}"><a href="{{$pager.prev.url}}">{{$pager.prev.text}}</a></span>{{/if}}
|
||||
|
||||
{{if $pager.first}}<span class="pager_first {{$pager.first.class}}"><a href="{{$pager.first.url}}">{{$pager.first.text}}</a></span>{{/if}}
|
||||
|
@ -9,5 +9,5 @@
|
|||
{{if $pager.last}} <span class="pager_last {{$pager.last.class}}"><a href="{{$pager.last.url}}">{{$pager.last.text}}</a></span>{{/if}}
|
||||
|
||||
{{if $pager.next}}<span class="pager_next {{$pager.next.class}}"><a href="{{$pager.next.url}}">{{$pager.next.text}}</a></span>{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
|
||||
<div id="peoplefind-sidebar" class="widget">
|
||||
<h3>{{$findpeople}}</h3>
|
||||
<div id="peoplefind-desc">{{$desc}}</div>
|
||||
<h3>{{$nv.findpeople}}</h3>
|
||||
<div id="peoplefind-desc">{{$nv.desc}}</div>
|
||||
<form action="dirfind" method="get" />
|
||||
<input id="side-peoplefind-url" type="text" name="search" size="24" title="{{$hint|escape:'html'}}" /><input id="side-peoplefind-submit" type="submit" name="submit" value="{{$findthem|escape:'html'}}" />
|
||||
<input id="side-peoplefind-url" type="text" name="search" size="24" title="{{$nv.hint|escape:'html'}}" /><input id="side-peoplefind-submit" type="submit" name="submit" value="{{$nv.findthem|escape:'html'}}" />
|
||||
</form>
|
||||
<div class="side-link" id="side-match-link"><a href="match" >{{$similar}}</a></div>
|
||||
<div class="side-link" id="side-suggest-link"><a href="suggest" >{{$suggest}}</a></div>
|
||||
<div class="side-link" id="side-directory-link"><a href="{{$global_dir}}" target="extlink" >{{$directory}}</a></div>
|
||||
<div class="side-link" id="side-random-profile-link" ><a href="randprof" target="extlink" >{{$random}}</a></div>
|
||||
{{if $inv}}
|
||||
<div class="side-link" id="side-invite-link" ><a href="invite" >{{$inv}}</a></div>
|
||||
<div class="side-link" id="side-match-link"><a href="match" >{{$nv.similar}}</a></div>
|
||||
<div class="side-link" id="side-suggest-link"><a href="suggest" >{{$nv.suggest}}</a></div>
|
||||
<div class="side-link" id="side-directory-link"><a href="directory" >{{$nv.local_directory}}</a></div>
|
||||
<div class="side-link" id="side-directory-link"><a href="{{$nv.global_dir}}" target="extlink" >{{$nv.directory}}</a></div>
|
||||
<div class="side-link" id="side-random-profile-link" ><a href="randprof" target="extlink" >{{$nv.random}}</a></div>
|
||||
{{if $nv.inv}}
|
||||
<div class="side-link" id="side-invite-link" ><a href="invite" >{{$nv.inv}}</a></div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
|
22
view/templates/wall/content_filter.tpl
Normal file
22
view/templates/wall/content_filter.tpl
Normal file
|
@ -0,0 +1,22 @@
|
|||
{{if count($reasons) > 1}}
|
||||
<ul class="content-filter-reasons">
|
||||
{{foreach $reasons as $reason}}
|
||||
<li>{{$reason|escape:html}}</li>
|
||||
{{/foreach}}
|
||||
</ul>
|
||||
<p>
|
||||
<button type="button" id="content-filter-wrap-{{$rnd}}" class="btn btn-default btn-small content-filter-button" onclick="openClose('content-filter-{{$rnd}}');">
|
||||
<i class="glyphicon glyphicon-eye-open"></i> {{$openclose}}
|
||||
</button>
|
||||
</p>
|
||||
{{else}}
|
||||
<p>
|
||||
{{$reasons.0|escape:html}}
|
||||
<button type="button" id="content-filter-wrap-{{$rnd}}" class="btn btn-default btn-xs content-filter-button" onclick="openClose('content-filter-{{$rnd}}');">
|
||||
<i class="glyphicon glyphicon-eye-open"></i> {{$openclose}}
|
||||
</button>
|
||||
</p>
|
||||
{{/if}}
|
||||
<div id="content-filter-{{$rnd}}" class="content-filter-content" style="display: none;">
|
||||
{{$html}}
|
||||
</div>
|
|
@ -37,11 +37,11 @@ Don't blame me too much for ugly code and hacks. Fix it ;-)
|
|||
**Theme - Settings**
|
||||
![Theme - Settings](https://github.com/rabuzarus/frio/blob/master/img/screenshots/screenshot-settings.png)
|
||||
|
||||
**Red schema**
|
||||
![Red schema](https://github.com/rabuzarus/frio/blob/master/img/screenshots/screenshot-schema-red.png)
|
||||
**Red scheme**
|
||||
![Red scheme](https://github.com/rabuzarus/frio/blob/master/img/screenshots/screenshot-scheme-red.png)
|
||||
|
||||
**Love Music schema**
|
||||
![Love Music schema](https://github.com/rabuzarus/frio/blob/master/img/screenshots/screenshot-schema-love-music.png)
|
||||
**Love Music scheme**
|
||||
![Love Music scheme](https://github.com/rabuzarus/frio/blob/master/img/screenshots/screenshot-scheme-love-music.png)
|
||||
|
||||
**frio on mobile**
|
||||
|
||||
|
|
|
@ -8,129 +8,135 @@ use Friendica\Core\System;
|
|||
|
||||
require_once 'view/theme/frio/php/Image.php';
|
||||
|
||||
function theme_post(App $a) {
|
||||
function theme_post(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($_POST['frio-settings-submit'])) {
|
||||
PConfig::set(local_user(), 'frio', 'schema', $_POST["frio_schema"]);
|
||||
PConfig::set(local_user(), 'frio', 'nav_bg', $_POST["frio_nav_bg"]);
|
||||
PConfig::set(local_user(), 'frio', 'nav_icon_color', $_POST["frio_nav_icon_color"]);
|
||||
PConfig::set(local_user(), 'frio', 'link_color', $_POST["frio_link_color"]);
|
||||
PConfig::set(local_user(), 'frio', 'background_color', $_POST["frio_background_color"]);
|
||||
PConfig::set(local_user(), 'frio', 'contentbg_transp', $_POST["frio_contentbg_transp"]);
|
||||
PConfig::set(local_user(), 'frio', 'background_image', $_POST["frio_background_image"]);
|
||||
PConfig::set(local_user(), 'frio', 'bg_image_option', $_POST["frio_bg_image_option"]);
|
||||
PConfig::set(local_user(), 'frio', 'scheme', $_POST['frio_scheme']);
|
||||
PConfig::set(local_user(), 'frio', 'nav_bg', $_POST['frio_nav_bg']);
|
||||
PConfig::set(local_user(), 'frio', 'nav_icon_color', $_POST['frio_nav_icon_color']);
|
||||
PConfig::set(local_user(), 'frio', 'link_color', $_POST['frio_link_color']);
|
||||
PConfig::set(local_user(), 'frio', 'background_color', $_POST['frio_background_color']);
|
||||
PConfig::set(local_user(), 'frio', 'contentbg_transp', $_POST['frio_contentbg_transp']);
|
||||
PConfig::set(local_user(), 'frio', 'background_image', $_POST['frio_background_image']);
|
||||
PConfig::set(local_user(), 'frio', 'bg_image_option', $_POST['frio_bg_image_option']);
|
||||
PConfig::set(local_user(), 'frio', 'css_modified', time());
|
||||
}
|
||||
}
|
||||
|
||||
function theme_admin_post(App $a) {
|
||||
function theme_admin_post(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($_POST['frio-settings-submit'])) {
|
||||
Config::set('frio', 'schema', $_POST["frio_schema"]);
|
||||
Config::set('frio', 'nav_bg', $_POST["frio_nav_bg"]);
|
||||
Config::set('frio', 'nav_icon_color', $_POST["frio_nav_icon_color"]);
|
||||
Config::set('frio', 'link_color', $_POST["frio_link_color"]);
|
||||
Config::set('frio', 'background_color', $_POST["frio_background_color"]);
|
||||
Config::set('frio', 'contentbg_transp', $_POST["frio_contentbg_transp"]);
|
||||
Config::set('frio', 'background_image', $_POST["frio_background_image"]);
|
||||
Config::set('frio', 'bg_image_option', $_POST["frio_bg_image_option"]);
|
||||
Config::set('frio', 'login_bg_image', $_POST["frio_login_bg_image"]);
|
||||
Config::set('frio', 'login_bg_color', $_POST["frio_login_bg_color"]);
|
||||
Config::set('frio', 'scheme', $_POST['frio_scheme']);
|
||||
Config::set('frio', 'nav_bg', $_POST['frio_nav_bg']);
|
||||
Config::set('frio', 'nav_icon_color', $_POST['frio_nav_icon_color']);
|
||||
Config::set('frio', 'link_color', $_POST['frio_link_color']);
|
||||
Config::set('frio', 'background_color', $_POST['frio_background_color']);
|
||||
Config::set('frio', 'contentbg_transp', $_POST['frio_contentbg_transp']);
|
||||
Config::set('frio', 'background_image', $_POST['frio_background_image']);
|
||||
Config::set('frio', 'bg_image_option', $_POST['frio_bg_image_option']);
|
||||
Config::set('frio', 'login_bg_image', $_POST['frio_login_bg_image']);
|
||||
Config::set('frio', 'login_bg_color', $_POST['frio_login_bg_color']);
|
||||
Config::set('frio', 'css_modified', time());
|
||||
}
|
||||
}
|
||||
|
||||
function theme_content(App $a) {
|
||||
function theme_content(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return;
|
||||
}
|
||||
$arr = [];
|
||||
|
||||
$arr["schema"] = PConfig::get(local_user(), 'frio', 'schema');
|
||||
$arr["nav_bg"] = PConfig::get(local_user(), 'frio', 'nav_bg');
|
||||
$arr["nav_icon_color"] = PConfig::get(local_user(), 'frio', 'nav_icon_color');
|
||||
$arr["link_color"] = PConfig::get(local_user(), 'frio', 'link_color');
|
||||
$arr["bgcolor"] = PConfig::get(local_user(), 'frio', 'background_color');
|
||||
$arr["contentbg_transp"] = PConfig::get(local_user(), 'frio', 'contentbg_transp');
|
||||
$arr["background_image"] = PConfig::get(local_user(), 'frio', 'background_image');
|
||||
$arr["bg_image_option"] = PConfig::get(local_user(), 'frio', 'bg_image_option');
|
||||
$arr['scheme'] = PConfig::get(local_user(), 'frio', 'scheme', PConfig::get(local_user(), 'frio', 'schema'));
|
||||
$arr['nav_bg'] = PConfig::get(local_user(), 'frio', 'nav_bg');
|
||||
$arr['nav_icon_color'] = PConfig::get(local_user(), 'frio', 'nav_icon_color');
|
||||
$arr['link_color'] = PConfig::get(local_user(), 'frio', 'link_color');
|
||||
$arr['background_color'] = PConfig::get(local_user(), 'frio', 'background_color');
|
||||
$arr['contentbg_transp'] = PConfig::get(local_user(), 'frio', 'contentbg_transp');
|
||||
$arr['background_image'] = PConfig::get(local_user(), 'frio', 'background_image');
|
||||
$arr['bg_image_option'] = PConfig::get(local_user(), 'frio', 'bg_image_option');
|
||||
|
||||
return frio_form($arr);
|
||||
}
|
||||
|
||||
function theme_admin(App $a) {
|
||||
function theme_admin(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
return;
|
||||
}
|
||||
$arr = [];
|
||||
|
||||
$arr["schema"] = Config::get('frio', 'schema');
|
||||
$arr["nav_bg"] = Config::get('frio', 'nav_bg');
|
||||
$arr["nav_icon_color"] = Config::get('frio', 'nav_icon_color');
|
||||
$arr["link_color"] = Config::get('frio', 'link_color');
|
||||
$arr["bgcolor"] = Config::get('frio', 'background_color');
|
||||
$arr["contentbg_transp"] = Config::get('frio', 'contentbg_transp');
|
||||
$arr["background_image"] = Config::get('frio', 'background_image');
|
||||
$arr["bg_image_option"] = Config::get('frio', 'bg_image_option');
|
||||
$arr["login_bg_image"] = Config::get('frio', 'login_bg_image');
|
||||
$arr["login_bg_color"] = Config::get('frio', 'login_bg_color');
|
||||
$arr['scheme'] = Config::get('frio', 'scheme', Config::get('frio', 'scheme'));
|
||||
$arr['nav_bg'] = Config::get('frio', 'nav_bg');
|
||||
$arr['nav_icon_color'] = Config::get('frio', 'nav_icon_color');
|
||||
$arr['link_color'] = Config::get('frio', 'link_color');
|
||||
$arr['background_color'] = Config::get('frio', 'background_color');
|
||||
$arr['contentbg_transp'] = Config::get('frio', 'contentbg_transp');
|
||||
$arr['background_image'] = Config::get('frio', 'background_image');
|
||||
$arr['bg_image_option'] = Config::get('frio', 'bg_image_option');
|
||||
$arr['login_bg_image'] = Config::get('frio', 'login_bg_image');
|
||||
$arr['login_bg_color'] = Config::get('frio', 'login_bg_color');
|
||||
|
||||
return frio_form($arr);
|
||||
}
|
||||
|
||||
function frio_form($arr) {
|
||||
require_once("view/theme/frio/php/schema.php");
|
||||
function frio_form($arr)
|
||||
{
|
||||
require_once 'view/theme/frio/php/scheme.php';
|
||||
|
||||
$scheme_info = get_schema_info($arr["schema"]);
|
||||
$disable = $scheme_info["overwrites"];
|
||||
$scheme_info = get_scheme_info($arr['scheme']);
|
||||
$disable = $scheme_info['overwrites'];
|
||||
if (!is_array($disable)) {
|
||||
$disable = [];
|
||||
}
|
||||
|
||||
$scheme_choices = [];
|
||||
$scheme_choices["---"] = L10n::t("Default");
|
||||
$files = glob('view/theme/frio/schema/*.php');
|
||||
$scheme_choices['---'] = L10n::t('Custom');
|
||||
$files = glob('view/theme/frio/scheme/*.php');
|
||||
if ($files) {
|
||||
foreach ($files as $file) {
|
||||
$f = basename($file, ".php");
|
||||
$f = basename($file, '.php');
|
||||
if ($f != 'default') {
|
||||
$scheme_name = $f;
|
||||
$scheme_name = ucfirst($f);
|
||||
$scheme_choices[$f] = $scheme_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$background_image_help = "<strong>" . L10n::t("Note"). ": </strong>".L10n::t("Check image permissions if all users are allowed to visit the image");
|
||||
$background_image_help = '<strong>' . L10n::t('Note') . ': </strong>' . L10n::t('Check image permissions if all users are allowed to see the image');
|
||||
|
||||
$t = get_markup_template('theme_settings.tpl');
|
||||
$ctx = [
|
||||
'$submit' => L10n::t('Submit'),
|
||||
'$baseurl' => System::baseUrl(),
|
||||
'$title' => L10n::t("Theme settings"),
|
||||
'$schema' => ['frio_schema', L10n::t("Select scheme"), $arr["schema"], '', $scheme_choices],
|
||||
'$nav_bg' => array_key_exists("nav_bg", $disable) ? "" : ['frio_nav_bg', L10n::t('Navigation bar background color'), $arr['nav_bg'], '', false],
|
||||
'$nav_icon_color' => array_key_exists("nav_icon_color", $disable) ? "" : ['frio_nav_icon_color', L10n::t('Navigation bar icon color '), $arr['nav_icon_color'], '', false],
|
||||
'$link_color' => array_key_exists("link_color", $disable) ? "" : ['frio_link_color', L10n::t('Link color'), $arr['link_color'], '', false],
|
||||
'$bgcolor' => array_key_exists("bgcolor", $disable) ? "" : ['frio_background_color', L10n::t('Set the background color'), $arr['bgcolor'], '', false],
|
||||
'$contentbg_transp' => array_key_exists("contentbg_transp", $disable) ? "" : ['frio_contentbg_transp', L10n::t("Content background opacity"), ((isset($arr["contentbg_transp"]) && $arr["contentbg_transp"] != "") ? $arr["contentbg_transp"] : 100), ''],
|
||||
'$background_image' => array_key_exists("background_image", $disable) ? "" : ['frio_background_image', L10n::t('Set the background image'), $arr['background_image'], $background_image_help, false],
|
||||
'$title' => L10n::t('Theme settings'),
|
||||
'$scheme' => ['frio_scheme', L10n::t('Select color scheme'), $arr['scheme'], '', $scheme_choices],
|
||||
'$nav_bg' => array_key_exists('nav_bg', $disable) ? '' : ['frio_nav_bg', L10n::t('Navigation bar background color'), $arr['nav_bg'], '', false],
|
||||
'$nav_icon_color' => array_key_exists('nav_icon_color', $disable) ? '' : ['frio_nav_icon_color', L10n::t('Navigation bar icon color '), $arr['nav_icon_color'], '', false],
|
||||
'$link_color' => array_key_exists('link_color', $disable) ? '' : ['frio_link_color', L10n::t('Link color'), $arr['link_color'], '', false],
|
||||
'$background_color' => array_key_exists('background_color', $disable) ? '' : ['frio_background_color', L10n::t('Set the background color'), $arr['background_color'], '', false],
|
||||
'$contentbg_transp' => array_key_exists('contentbg_transp', $disable) ? '' : ['frio_contentbg_transp', L10n::t('Content background opacity'), defaults($arr, 'contentbg_transp', 100), ''],
|
||||
'$background_image' => array_key_exists('background_image', $disable) ? '' : ['frio_background_image', L10n::t('Set the background image'), $arr['background_image'], $background_image_help, false],
|
||||
'$bg_image_options_title' => L10n::t('Background image style'),
|
||||
'$bg_image_options' => Image::get_options($arr),
|
||||
];
|
||||
|
||||
if (array_key_exists("login_bg_image", $arr) && !array_key_exists("login_bg_image", $disable)) {
|
||||
if (array_key_exists('login_bg_image', $arr) && !array_key_exists('login_bg_image', $disable)) {
|
||||
$ctx['$login_bg_image'] = ['frio_login_bg_image', L10n::t('Login page background image'), $arr['login_bg_image'], $background_image_help, false];
|
||||
}
|
||||
if (array_key_exists("login_bg_color", $arr) && !array_key_exists("login_bg_color", $disable)) {
|
||||
|
||||
if (array_key_exists('login_bg_color', $arr) && !array_key_exists('login_bg_color', $disable)) {
|
||||
$ctx['$login_bg_color'] = ['frio_login_bg_color', L10n::t('Login page background color'), $arr['login_bg_color'], L10n::t('Leave background image and color empty for theme defaults'), false];
|
||||
}
|
||||
|
||||
|
||||
$o = replace_macros($t, $ctx);
|
||||
|
||||
return $o;
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
|
||||
#admin-users.adminpage { padding-left:0; padding-right: 0;}
|
||||
#admin-users.adminpage > h1 { padding: 0 15px; }
|
||||
|
||||
#admin-users td { word-break: break-all; }
|
||||
#admin-users.adminpage .panel-collapse { margin-left: -15px; margin-right: -15px; }
|
||||
|
||||
#admin-users #users th:first-of-type { width: 1em; }
|
||||
#admin-users #users th:nth-of-type(2) { width: 40px; }
|
||||
#admin-users #users th:last-of-type { width: 1em; }
|
||||
#admin-users .admin-settings-footer-elements { padding-left: 8px; padding-right: 8px; }
|
||||
|
||||
#admin-users #deleted th:first-of-type { width: 40px; }
|
||||
|
||||
#admin-users #users img.avatar-nano, #deleted img.avatar-nano { height: 24px; width: 24px; }
|
||||
.opened .caret { transform: rotate(180deg); }
|
||||
tr.details td,
|
||||
tr.details th
|
||||
{ border-top: 0!important; }
|
||||
tr.details th {
|
||||
border-top: 0!important;
|
||||
}
|
||||
|
||||
.adminpage td > .checkbox { margin: 0; }
|
||||
.adminpage td { word-break: break-all; }
|
|
@ -24,9 +24,10 @@ and open the template in the editor.
|
|||
|
||||
body {
|
||||
padding-top: 110px;
|
||||
background-color: $bgcolor;
|
||||
background-color: $background_color;
|
||||
background-image: url("$background_image");
|
||||
background-size: $background_size_img;
|
||||
background-repeat: $background_repeat;
|
||||
background-attachment: fixed;
|
||||
color: #777;
|
||||
/*color: #555;*/
|
||||
|
@ -2115,9 +2116,10 @@ ul.dropdown-menu li:hover {
|
|||
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
|
||||
.directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper,
|
||||
.message-content-wrapper, .apps-content-wrapper, .photos-content-wrapper,
|
||||
#adminpage, .viewcontacts-content-wrapper, .dfrn_request-content-wrapper,
|
||||
#adminpage, .delegate-content-wrapper, .uexport-content-wrapper,
|
||||
.viewcontacts-content-wrapper, .dfrn_request-content-wrapper,
|
||||
.friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper,
|
||||
.profperm-content-wrapper {
|
||||
.profperm-content-wrapper, .invite-content-wrapper {
|
||||
min-height: calc(100vh - 150px);
|
||||
padding: 15px;
|
||||
padding-bottom: 20px;
|
||||
|
@ -2409,10 +2411,13 @@ ul li:hover .contact-wrapper .contact-action-link:hover {
|
|||
height: 48px;
|
||||
width: 48px;
|
||||
}
|
||||
|
||||
#prvmail-end {
|
||||
clear:both;
|
||||
}
|
||||
#modal #prvmail-text-edit-bb .bb-img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* photos */
|
||||
.photo-album-actions {
|
||||
margin-bottom: 10px;
|
||||
|
@ -2650,7 +2655,8 @@ ul li:hover .contact-wrapper .contact-action-link:hover {
|
|||
margin-left: -15px;
|
||||
margin-right: -15px;
|
||||
}
|
||||
.panel-group-settings > .panel {
|
||||
.panel-group-settings > .panel,
|
||||
.panel-group-settings > form > .panel {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
@ -2935,6 +2941,22 @@ section.help-content-wrapper li {
|
|||
#adminpage .plugin .desc {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.adminpage .admin-settings-action-link,
|
||||
.adminpage .admin-settings-action-link:hover {
|
||||
color: #555;
|
||||
}
|
||||
.adminpage .admin-settings-action-link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.adminpage .admin-settings-action-link {
|
||||
opacity: 0.8;
|
||||
}
|
||||
#admin-users tr.blocked {
|
||||
background-color: #f8efc0;
|
||||
}
|
||||
.adminpage .table-hover > tbody > tr:hover + tr.details {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Register Page*/
|
||||
#register-openid-wrapper, #register-name-wrapper, #register-invite-wrapper, #profile-publish-wrapper {
|
||||
|
@ -3115,12 +3137,30 @@ section .profile-match-wrapper {
|
|||
* Login page
|
||||
*/
|
||||
#login-submit-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
float: right;
|
||||
}
|
||||
#lost-password-link { flex-grow: 2; }
|
||||
#login-lost-password-link {
|
||||
margin-bottom: 10px;
|
||||
float: right;
|
||||
}
|
||||
#div_id_remember {
|
||||
float: left;
|
||||
}
|
||||
#id_password_wrapper {
|
||||
margin-bottom: unset;
|
||||
}
|
||||
#login_openid {
|
||||
clear: both;
|
||||
}
|
||||
#register-link {
|
||||
color: white;
|
||||
background: #8ad0a1;
|
||||
width: 100%;
|
||||
}
|
||||
#login-end {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.mod-home.is-not-singleuser,
|
||||
.mod-login {
|
||||
|
@ -3145,12 +3185,15 @@ section .profile-match-wrapper {
|
|||
margin-top: 2.5%;
|
||||
}
|
||||
|
||||
.mod-home.is-not-singleuser .login-form > #login-extra-links {
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
.mod-home.is-not-singleuser .login-form > #login-form label,
|
||||
.mod-login #content #login-form label {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
|
||||
.mod-home.is-not-singleuser .login-panel-content,
|
||||
.mod-login .login-panel-content {
|
||||
background-color: rgba(255,255,255,.85);
|
||||
|
@ -3164,11 +3207,15 @@ section .profile-match-wrapper {
|
|||
}
|
||||
|
||||
.mod-home.is-not-singleuser .login-form > #login-form,
|
||||
.mod-home.is-not-singleuser .login-form > #login-extra-links,
|
||||
.mod-login #content #login-form {
|
||||
background-color: #fff;
|
||||
padding: 1em;
|
||||
position: relative;
|
||||
margin-top: 4em;
|
||||
}
|
||||
.mod-home.is-not-singleuser .login-form > #login-extra-links {
|
||||
margin-top: unset;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.mod-home.is-not-singleuser .login-form > #login-form label,
|
||||
|
@ -3176,7 +3223,7 @@ section .profile-match-wrapper {
|
|||
color: #444;
|
||||
}
|
||||
|
||||
.mod-home.is-not-singleuser .login-form > #login-form::before,
|
||||
.mod-home.is-not-singleuser .login-form::before,
|
||||
.mod-login #content #login-form::before {
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
@ -3189,7 +3236,7 @@ section .profile-match-wrapper {
|
|||
z-index: -1;
|
||||
}
|
||||
|
||||
.mod-home.is-not-singleuser .login-form > #login-form::after,
|
||||
.mod-home.is-not-singleuser .login-form::after,
|
||||
.mod-login #content #login-form::after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
|
Before Width: | Height: | Size: 239 KiB After Width: | Height: | Size: 239 KiB |
Before Width: | Height: | Size: 750 KiB After Width: | Height: | Size: 750 KiB |
|
@ -231,7 +231,6 @@ var FileBrowser = {
|
|||
$(".fbrowser .fbswitcher [data-mode=" + FileBrowser.type + "]").addClass("active");
|
||||
// We need to add the AjaxUpload to the button
|
||||
FileBrowser.uploadButtons();
|
||||
|
||||
},
|
||||
|
||||
// Load new content (e.g. change photo album)
|
||||
|
|
|
@ -9,7 +9,9 @@ $(function() {
|
|||
selectnone($(this).data('selectNone'));
|
||||
});
|
||||
|
||||
$('body').on('change', 'input[type=checkbox].select', function() {
|
||||
// Toggle checkbox status to all or none for all checkboxes of a specific
|
||||
// css class.
|
||||
$('body').on('change', 'input[type=checkbox].selecttoggle', function() {
|
||||
$this = $(this);
|
||||
if ($this.prop('checked')) {
|
||||
selectall($this.data('selectClass'));
|
||||
|
@ -20,6 +22,26 @@ $(function() {
|
|||
}
|
||||
});
|
||||
|
||||
// Use AJAX calls to reorder the table (so we don't need to reload the page).
|
||||
$('body').on('click', '.table-order', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Get the parent table element.
|
||||
var table = $(this).parents('table');
|
||||
var orderUrl = this.getAttribute("data-order-url");
|
||||
table.fadeTo("fast", 0.33);
|
||||
|
||||
$("body").css("cursor", "wait");
|
||||
|
||||
$.get(orderUrl, function(data) {
|
||||
// Find the table element in the html we got.
|
||||
var result = $(data).find('#' + table[0].id);
|
||||
// And add the new table html to the parent.
|
||||
$(table).parent().html(result);
|
||||
|
||||
$("body").css("cursor", "auto");
|
||||
});
|
||||
});
|
||||
|
||||
function selectall(cls) {
|
||||
$('.' + cls).prop('checked', true);
|
||||
|
|
|
@ -152,6 +152,7 @@ Dialog._load = function(url) {
|
|||
var jsbrowser = function() {
|
||||
FileBrowser.init(nickname, type, hash);
|
||||
};
|
||||
loadScript("view/js/ajaxupload.js");
|
||||
loadScript("view/theme/frio/js/filebrowser.js", jsbrowser);
|
||||
};
|
||||
|
||||
|
@ -206,6 +207,10 @@ function addToModal(url) {
|
|||
//Get first element with the class "heading"
|
||||
//and use it as title.
|
||||
loadModalTitle();
|
||||
|
||||
// We need to initialize autosize again for new
|
||||
// modal conent.
|
||||
autosize($('.modal .text-autosize'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -446,8 +446,16 @@ function justifyPhotosAjax() {
|
|||
$('#photo-album-contents').justifiedGallery('norewind').on('jg.complete', function(e){ justifiedGalleryActive = false; });
|
||||
}
|
||||
|
||||
// Load a js script to the html head.
|
||||
function loadScript(url, callback) {
|
||||
// Adding the script tag to the head as suggested before
|
||||
// Check if the script is already in the html head.
|
||||
var oscript = $('head script[src="' + url + '"]');
|
||||
|
||||
// Delete the old script from head.
|
||||
if (oscript.length > 0) {
|
||||
oscript.remove();
|
||||
}
|
||||
// Adding the script tag to the head as suggested before.
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
|
@ -458,7 +466,7 @@ function loadScript(url, callback) {
|
|||
script.onreadystatechange = callback;
|
||||
script.onload = callback;
|
||||
|
||||
// Fire the loading
|
||||
// Fire the loading.
|
||||
head.appendChild(script);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,14 +21,10 @@ class Image
|
|||
public static function get_options($arr)
|
||||
{
|
||||
$bg_image_options = [
|
||||
'repeat' => [
|
||||
'frio_bg_image_option', L10n::t("Repeat the image"), "repeat", L10n::t("Will repeat your image to fill the background."), ($arr["bg_image_option"] == "repeat")],
|
||||
'stretch' => [
|
||||
'frio_bg_image_option', L10n::t("Stretch"), "stretch", L10n::t("Will stretch to width/height of the image."), ($arr["bg_image_option"] == "stretch")],
|
||||
'cover' => [
|
||||
'frio_bg_image_option', L10n::t("Resize fill and-clip"), "cover", L10n::t("Resize to fill and retain aspect ratio."), ($arr["bg_image_option"] == "cover")],
|
||||
'contain' => [
|
||||
'frio_bg_image_option', L10n::t("Resize best fit"), "contain", L10n::t("Resize to best fit and retain aspect ratio."), ($arr["bg_image_option"] == "contain")],
|
||||
'stretch' => ['frio_bg_image_option', L10n::t('Top Banner'), 'stretch', L10n::t('Resize image to the width of the screen and show background color below on long pages.'), ($arr['bg_image_option'] == 'stretch')],
|
||||
'cover' => ['frio_bg_image_option', L10n::t('Full screen'), 'cover', L10n::t('Resize image to fill entire screen, clipping either the right or the bottom.'), ($arr['bg_image_option'] == 'cover')],
|
||||
'contain' => ['frio_bg_image_option', L10n::t('Single row mosaic'), 'contain', L10n::t('Resize image to repeat it on a single row, either vertical or horizontal.'), ($arr['bg_image_option'] == 'contain')],
|
||||
'repeat' => ['frio_bg_image_option', L10n::t('Mosaic'), 'repeat', L10n::t('Repeat image to fill the screen.'), ($arr['bg_image_option'] == 'repeat')],
|
||||
];
|
||||
|
||||
return $bg_image_options;
|
||||
|
|
|
@ -26,8 +26,9 @@ if (!isset($minimal)) {
|
|||
<script type="text/javascript">var baseurl = "<?php echo System::baseUrl(); ?>";</script>
|
||||
<script type="text/javascript">var frio = "<?php echo 'view/theme/frio'; ?>";</script>
|
||||
<?php
|
||||
$baseurl = System::baseUrl();
|
||||
$basepath = $a->path ? "/" . $a->path . "/" : "/";
|
||||
$frio = "view/theme/frio";
|
||||
|
||||
// Because we use minimal for modals the header and the included js stuff should be only loaded
|
||||
// if the page is an standard page (so we don't have it twice for modals)
|
||||
//
|
||||
|
@ -35,16 +36,17 @@ if (!isset($minimal)) {
|
|||
if (!$minimal && x($page, 'htmlhead')) {
|
||||
echo $page['htmlhead'];
|
||||
}
|
||||
|
||||
// Add the theme color meta
|
||||
// It makes mobile Chrome UI match Frio's top bar color.
|
||||
$uid = $a->profile_uid;
|
||||
if (is_null($uid)) {
|
||||
$uid = Profile::getThemeUid();
|
||||
}
|
||||
$schema = PConfig::get($uid, 'frio', 'schema');
|
||||
if (($schema) && ($schema != '---')) {
|
||||
if (file_exists('view/theme/frio/schema/' . $schema . '.php')) {
|
||||
$schemefile = 'view/theme/frio/schema/' . $schema . '.php';
|
||||
$scheme = PConfig::get($uid, 'frio', 'scheme', PConfig::get($uid, 'frio', 'schema'));
|
||||
if (($scheme) && ($scheme != '---')) {
|
||||
if (file_exists('view/theme/frio/scheme/' . $scheme . '.php')) {
|
||||
$schemefile = 'view/theme/frio/scheme/' . $scheme . '.php';
|
||||
require_once $schemefile;
|
||||
}
|
||||
} else {
|
||||
|
@ -60,6 +62,7 @@ if (!isset($minimal)) {
|
|||
$is_singleuser_class = $is_singleuser ? "is-singleuser" : "is-not-singleuser";
|
||||
?>
|
||||
</head>
|
||||
|
||||
<body id="top" class="mod-<?php echo $a->module." ".$is_singleuser_class;?>">
|
||||
<a href="#content" class="sr-only sr-only-focusable">Skip to main content</a>
|
||||
<?php
|
||||
|
@ -90,7 +93,7 @@ if (!isset($minimal)) {
|
|||
<div class="container">
|
||||
<div class="row">
|
||||
<?php
|
||||
if ((!x($_REQUEST, 'pagename') || $_REQUEST['pagename'] != "lostpass") && ($_SERVER['REQUEST_URI'] != "/")) {
|
||||
if ((!x($_REQUEST, 'pagename') || $_REQUEST['pagename'] != "lostpass") && ($_SERVER['REQUEST_URI'] != $basepath)) {
|
||||
echo '
|
||||
<aside class="col-lg-3 col-md-3 offcanvas-sm offcanvas-xs">';
|
||||
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* @brief: Get info header of the shema
|
||||
*
|
||||
* This function parses the header of the shemename.php file for inormations like
|
||||
* Author, Description and Overwrites. Most of the code comes from the Addon::getInfo()
|
||||
* function. We use this to get the variables which get overwritten through the shema.
|
||||
* All color variables which get overwritten through the theme have to be
|
||||
* listed (comma seperated) in the shema header under Overwrites:
|
||||
* This seemst not to be the best solution. We need to investigate further.
|
||||
*
|
||||
* @param string $schema Name of the shema
|
||||
* @return array With theme information
|
||||
* 'author' => Author Name
|
||||
* 'description' => Schema description
|
||||
* 'version' => Schema version
|
||||
* 'overwrites' => Variables which overwriting custom settings
|
||||
*/
|
||||
|
||||
use Friendica\Core\PConfig;
|
||||
|
||||
function get_schema_info($schema){
|
||||
|
||||
$theme = current_theme();
|
||||
$themepath = "view/theme/" . $theme . "/";
|
||||
$schema = PConfig::get(local_user(),'frio', 'schema');
|
||||
|
||||
$info=[
|
||||
'name' => $schema,
|
||||
'description' => "",
|
||||
'author' => [],
|
||||
'version' => "",
|
||||
'overwrites' => []
|
||||
];
|
||||
|
||||
if (!is_file($themepath . "schema/" . $schema . ".php")) return $info;
|
||||
|
||||
$f = file_get_contents($themepath . "schema/" . $schema . ".php");
|
||||
|
||||
$r = preg_match("|/\*.*\*/|msU", $f, $m);
|
||||
|
||||
if ($r){
|
||||
$ll = explode("\n", $m[0]);
|
||||
foreach( $ll as $l ) {
|
||||
$l = trim($l,"\t\n\r */");
|
||||
if ($l!=""){
|
||||
list($k,$v) = array_map("trim", explode(":",$l,2));
|
||||
$k= strtolower($k);
|
||||
if ($k=="author"){
|
||||
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
|
||||
if ($r) {
|
||||
$info['author'][] = ['name'=>$m[1], 'link'=>$m[2]];
|
||||
} else {
|
||||
$info['author'][] = ['name'=>$v];
|
||||
}
|
||||
} elseif ($k == "overwrites") {
|
||||
$theme_settings = explode(',',str_replace(' ','', $v));
|
||||
foreach ($theme_settings as $key => $value) {
|
||||
$info["overwrites"][$value] = true;
|
||||
}
|
||||
} else {
|
||||
if (array_key_exists($k,$info)){
|
||||
$info[$k]=$v;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $info;
|
||||
}
|
71
view/theme/frio/php/scheme.php
Normal file
71
view/theme/frio/php/scheme.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @brief: Get info header of the scheme
|
||||
*
|
||||
* This function parses the header of the schemename.php file for informations like
|
||||
* Author, Description and Overwrites. Most of the code comes from the Addon::getInfo()
|
||||
* function. We use this to get the variables which get overwritten through the scheme.
|
||||
* All color variables which get overwritten through the theme have to be
|
||||
* listed (comma separated) in the scheme header under Overwrites:
|
||||
* This seems not to be the best solution. We need to investigate further.
|
||||
*
|
||||
* @param string $scheme Name of the scheme
|
||||
* @return array With theme information
|
||||
* 'author' => Author Name
|
||||
* 'description' => Scheme description
|
||||
* 'version' => Scheme version
|
||||
* 'overwrites' => Variables which overwriting custom settings
|
||||
*/
|
||||
use Friendica\Core\PConfig;
|
||||
|
||||
function get_scheme_info($scheme)
|
||||
{
|
||||
$theme = current_theme();
|
||||
$themepath = 'view/theme/' . $theme . '/';
|
||||
$scheme = PConfig::get(local_user(), 'frio', 'scheme', PConfig::get(local_user(), 'frio', 'scheme'));
|
||||
|
||||
$info = [
|
||||
'name' => $scheme,
|
||||
'description' => '',
|
||||
'author' => [],
|
||||
'version' => '',
|
||||
'overwrites' => []
|
||||
];
|
||||
|
||||
if (!is_file($themepath . 'scheme/' . $scheme . '.php')) return $info;
|
||||
|
||||
$f = file_get_contents($themepath . 'scheme/' . $scheme . '.php');
|
||||
|
||||
$r = preg_match('|/\*.*\*/|msU', $f, $m);
|
||||
|
||||
if ($r) {
|
||||
$ll = explode("\n", $m[0]);
|
||||
foreach ($ll as $l) {
|
||||
$l = trim($l, "\t\n\r */");
|
||||
if ($l != '') {
|
||||
list($k, $v) = array_map('trim', explode(':', $l, 2));
|
||||
$k = strtolower($k);
|
||||
if ($k == 'author') {
|
||||
$r = preg_match('|([^<]+)<([^>]+)>|', $v, $m);
|
||||
if ($r) {
|
||||
$info['author'][] = ['name' => $m[1], 'link' => $m[2]];
|
||||
} else {
|
||||
$info['author'][] = ['name' => $v];
|
||||
}
|
||||
} elseif ($k == 'overwrites') {
|
||||
$theme_settings = explode(',', str_replace(' ', '', $v));
|
||||
foreach ($theme_settings as $key => $value) {
|
||||
$info['overwrites'][$value] = true;
|
||||
}
|
||||
} else {
|
||||
if (array_key_exists($k, $info)) {
|
||||
$info[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
<?php $frio = "view/theme/frio"; ?>
|
||||
<?php if(x($page,'htmlhead')) echo $page['htmlhead']; ?>
|
||||
</head>
|
||||
<body id=\"top\">";
|
||||
<body id="top">
|
||||
<?php if($_SERVER['REQUEST_URI'] == "/"){header('Location: /login');} ?>
|
||||
<a href="#content" class="sr-only sr-only-focusable">Skip to main content</a>
|
||||
<?php
|
||||
|
|
16
view/theme/frio/scheme/blue.php
Normal file
16
view/theme/frio/scheme/blue.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/*
|
||||
* Name: Blue
|
||||
* Author: Rabuzarus
|
||||
*
|
||||
* List here all variables which will get overwritten through this scheme
|
||||
* Overwrites: nav_bg, nav_icon_color, link_color, background_color, login_bg_color, contentbg_transp
|
||||
*/
|
||||
|
||||
$nav_bg = "#708fa0";
|
||||
$nav_icon_color = "#fff";
|
||||
$link_color = "#6fdbe8";
|
||||
$background_color = "#ededed";
|
||||
$login_bg_color = "#ededed";
|
||||
$contentbg_transp = 100;
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
/* Licence: AGP
|
||||
* Author: rabuzarus
|
||||
* Overwrites: nav_bg, nav_icon_color, link_color, bgcolor, contentbg_transp, background_image, bg_image_option, link_hover_color
|
||||
* Overwrites: nav_bg, nav_icon_color, link_color, background_color, contentbg_transp, background_image, bg_image_option, link_hover_color
|
||||
*/
|
||||
|
||||
$nav_bg = "#000";
|
||||
$nav_icon_color = "#e355e0";
|
||||
$link_color = "#e355e0";
|
||||
$bgcolor = "#fff";
|
||||
$background_color = "#fff";
|
||||
$contentbg_transp = 100;
|
||||
$background_image = "img/bg_circle.png";
|
||||
$bg_image_option = "repeat";
|
|
@ -3,13 +3,13 @@
|
|||
* Name: Red
|
||||
* Author: Rabuzarus
|
||||
*
|
||||
* List here all variables which will get overwritten through this schema
|
||||
* Overwrites: nav_bg, nav_icon_color, link_color, bgcolor, contentbg_transp
|
||||
* List here all variables which will get overwritten through this scheme
|
||||
* Overwrites: nav_bg, nav_icon_color, link_color, background_color, contentbg_transp
|
||||
*/
|
||||
|
||||
$nav_bg = "#870000";
|
||||
$nav_icon_color = "#f5f5f5";
|
||||
$link_color = "#b50404";
|
||||
$bgcolor = "#ededed";
|
||||
$background_color = "#ededed";
|
||||
$contentbg_transp = 95;
|
||||
|
|
@ -8,7 +8,7 @@ use Friendica\Model\Profile;
|
|||
|
||||
require_once 'view/theme/frio/php/PHPColors/Color.php';
|
||||
|
||||
$schemecss = "";
|
||||
$schemecss = '';
|
||||
$schemecssfile = false;
|
||||
$scheme_modified = 0;
|
||||
|
||||
|
@ -19,15 +19,15 @@ if ($a->module !== 'install') {
|
|||
PConfig::load($uid, 'frio');
|
||||
|
||||
// Load the profile owners pconfig.
|
||||
$schema = PConfig::get($uid, "frio", "schema");
|
||||
$nav_bg = PConfig::get($uid, "frio", "nav_bg");
|
||||
$nav_icon_color = PConfig::get($uid, "frio", "nav_icon_color");
|
||||
$link_color = PConfig::get($uid, "frio", "link_color");
|
||||
$bgcolor = PConfig::get($uid, "frio", "background_color");
|
||||
$contentbg_transp = PConfig::get($uid, "frio", "contentbg_transp");
|
||||
$background_image = PConfig::get($uid, "frio", "background_image");
|
||||
$bg_image_option = PConfig::get($uid, "frio", "bg_image_option");
|
||||
$modified = PConfig::get($uid, "frio", "css_modified");
|
||||
$scheme = PConfig::get($uid, 'frio', 'scheme', PConfig::get($uid, 'frio', 'schema'));
|
||||
$nav_bg = PConfig::get($uid, 'frio', 'nav_bg');
|
||||
$nav_icon_color = PConfig::get($uid, 'frio', 'nav_icon_color');
|
||||
$link_color = PConfig::get($uid, 'frio', 'link_color');
|
||||
$background_color = PConfig::get($uid, 'frio', 'background_color');
|
||||
$contentbg_transp = PConfig::get($uid, 'frio', 'contentbg_transp');
|
||||
$background_image = PConfig::get($uid, 'frio', 'background_image');
|
||||
$bg_image_option = PConfig::get($uid, 'frio', 'bg_image_option');
|
||||
$modified = PConfig::get($uid, 'frio', 'css_modified');
|
||||
|
||||
// There is maybe the case that the user did never modify the theme settings.
|
||||
// In this case we store the present time.
|
||||
|
@ -38,17 +38,17 @@ if ($a->module !== 'install') {
|
|||
Config::load('frio');
|
||||
|
||||
// Load frios system config.
|
||||
$schema = Config::get("frio", "schema");
|
||||
$nav_bg = Config::get("frio", "nav_bg");
|
||||
$nav_icon_color = Config::get("frio", "nav_icon_color");
|
||||
$link_color = Config::get("frio", "link_color");
|
||||
$bgcolor = Config::get("frio", "background_color");
|
||||
$contentbg_transp = Config::get("frio", "contentbg_transp");
|
||||
$background_image = Config::get("frio", "background_image");
|
||||
$bg_image_option = Config::get("frio", "bg_image_option");
|
||||
$login_bg_image = Config::get("frio", "login_bg_image");
|
||||
$login_bg_color = Config::get("frio", "login_bg_color");
|
||||
$modified = Config::get("frio", "css_modified");
|
||||
$scheme = Config::get('frio', 'scheme', Config::get('frio', 'schema'));
|
||||
$nav_bg = Config::get('frio', 'nav_bg');
|
||||
$nav_icon_color = Config::get('frio', 'nav_icon_color');
|
||||
$link_color = Config::get('frio', 'link_color');
|
||||
$background_color = Config::get('frio', 'background_color');
|
||||
$contentbg_transp = Config::get('frio', 'contentbg_transp');
|
||||
$background_image = Config::get('frio', 'background_image');
|
||||
$bg_image_option = Config::get('frio', 'bg_image_option');
|
||||
$login_bg_image = Config::get('frio', 'login_bg_image');
|
||||
$login_bg_color = Config::get('frio', 'login_bg_color');
|
||||
$modified = Config::get('frio', 'css_modified');
|
||||
|
||||
// There is maybe the case that the user did never modify the theme settings.
|
||||
// In this case we store the present time.
|
||||
|
@ -59,47 +59,47 @@ if ($a->module !== 'install') {
|
|||
}
|
||||
|
||||
// Now load the scheme. If a value is changed above, we'll keep the settings
|
||||
// If not, we'll keep those defined by the schema
|
||||
// Setting $schema to '' wasn't working for some reason, so we'll check it's
|
||||
// If not, we'll keep those defined by the scheme
|
||||
// Setting $scheme to '' wasn't working for some reason, so we'll check it's
|
||||
// not --- like the mobile theme does instead.
|
||||
// Allow layouts to over-ride the schema.
|
||||
if (x($_REQUEST, 'schema')) {
|
||||
$schema = $_REQUEST['schema'];
|
||||
// Allow layouts to over-ride the scheme.
|
||||
if (x($_REQUEST, 'scheme')) {
|
||||
$scheme = $_REQUEST['scheme'];
|
||||
}
|
||||
|
||||
// Sanitize the data.
|
||||
$schema = !empty($schema) ? basename($schema) : "";
|
||||
$scheme = !empty($scheme) ? basename($scheme) : '';
|
||||
|
||||
|
||||
if (($schema) && ($schema != '---')) {
|
||||
if (file_exists('view/theme/frio/schema/' . $schema . '.php')) {
|
||||
$schemefile = 'view/theme/frio/schema/' . $schema . '.php';
|
||||
if (($scheme) && ($scheme != '---')) {
|
||||
if (file_exists('view/theme/frio/scheme/' . $scheme . '.php')) {
|
||||
$schemefile = 'view/theme/frio/scheme/' . $scheme . '.php';
|
||||
require_once $schemefile;
|
||||
}
|
||||
if (file_exists('view/theme/frio/schema/' . $schema . '.css')) {
|
||||
$schemecssfile = 'view/theme/frio/schema/' . $schema . '.css';
|
||||
if (file_exists('view/theme/frio/scheme/' . $scheme . '.css')) {
|
||||
$schemecssfile = 'view/theme/frio/scheme/' . $scheme . '.css';
|
||||
}
|
||||
}
|
||||
|
||||
// If we haven't got a schema, load the default. We shouldn't touch this - we
|
||||
// If we haven't got a scheme, load the default. We shouldn't touch this - we
|
||||
// should leave it for admins to define for themselves.
|
||||
// default.php and default.css MUST be symlinks to existing schema files.
|
||||
if (! $schema) {
|
||||
if (file_exists('view/theme/frio/schema/default.php')) {
|
||||
$schemefile = 'view/theme/frio/schema/default.php';
|
||||
// default.php and default.css MUST be symlinks to existing scheme files.
|
||||
if (!$scheme) {
|
||||
if (file_exists('view/theme/frio/scheme/default.php')) {
|
||||
$schemefile = 'view/theme/frio/scheme/default.php';
|
||||
require_once $schemefile;
|
||||
}
|
||||
if (file_exists('view/theme/frio/schema/default.css')) {
|
||||
$schemecssfile = 'view/theme/frio/schema/default.css';
|
||||
if (file_exists('view/theme/frio/scheme/default.css')) {
|
||||
$schemecssfile = 'view/theme/frio/scheme/default.css';
|
||||
}
|
||||
}
|
||||
|
||||
//Set some defaults - we have to do this after pulling owner settings, and we have to check for each setting
|
||||
//individually. If we don't, we'll have problems if a user has set one, but not all options.
|
||||
$nav_bg = (empty($nav_bg) ? "#708fa0" : $nav_bg);
|
||||
$nav_icon_color = (empty($nav_icon_color) ? "#fff" : $nav_icon_color);
|
||||
$link_color = (empty($link_color) ? "#6fdbe8" : $link_color);
|
||||
$bgcolor = (empty($bgcolor) ? "#ededed" : $bgcolor);
|
||||
$nav_bg = (empty($nav_bg) ? '#708fa0' : $nav_bg);
|
||||
$nav_icon_color = (empty($nav_icon_color) ? '#fff' : $nav_icon_color);
|
||||
$link_color = (empty($link_color) ? '#6fdbe8' : $link_color);
|
||||
$background_color = (empty($background_color) ? '#ededed' : $background_color);
|
||||
// The background image can not be empty. So we use a dummy jpg if no image was set.
|
||||
$background_image = (empty($background_image) ? 'img/none.jpg' : $background_image);
|
||||
$modified = (empty($modified) ? time() : $modified);
|
||||
|
@ -107,12 +107,11 @@ $modified = (empty($modified) ? time() :$modified);
|
|||
|
||||
// set a default login bg image if no custom image and no custom bg color are set.
|
||||
if (empty($login_bg_image) && empty($login_bg_color)) {
|
||||
$login_bg_image = (empty($login_bg_image) ? 'img/login_bg.jpg' : $login_bg_image);
|
||||
$login_bg_image = 'img/login_bg.jpg';
|
||||
}
|
||||
$login_bg_color = (empty($login_bg_color) ? "#ededed" : $login_bg_color);
|
||||
$login_bg_color = (empty($login_bg_color) ? '#ededed' : $login_bg_color);
|
||||
|
||||
|
||||
$contentbg_transp = ((isset($contentbg_transp) && $contentbg_transp != "") ? $contentbg_transp : 100);
|
||||
$contentbg_transp = ((isset($contentbg_transp) && $contentbg_transp != '') ? $contentbg_transp : 100);
|
||||
|
||||
// Calculate some colors in dependance of existing colors.
|
||||
// Some colors are calculated to don't have too many selection
|
||||
|
@ -153,22 +152,28 @@ if (!isset($link_hover_color)) {
|
|||
if (!isset($bg_image_option)) {
|
||||
$bg_image_option = null;
|
||||
}
|
||||
|
||||
switch ($bg_image_option) {
|
||||
case "stretch":
|
||||
$background_size_img = "100%";
|
||||
case 'stretch':
|
||||
$background_size_img = '100%';
|
||||
$background_repeat = 'no-repeat';
|
||||
break;
|
||||
case "cover":
|
||||
$background_size_img ="cover";
|
||||
case 'cover':
|
||||
$background_size_img = 'cover';
|
||||
$background_repeat = 'no-repeat';
|
||||
break;
|
||||
case "repeat":
|
||||
$background_size_img = "auto";
|
||||
case 'repeat':
|
||||
$background_size_img = 'auto';
|
||||
$background_repeat = 'repeat';
|
||||
break;
|
||||
case "contain":
|
||||
$background_size_img = "contain";
|
||||
case 'contain':
|
||||
$background_size_img = 'contain';
|
||||
$background_repeat = 'repeat';
|
||||
break;
|
||||
|
||||
default:
|
||||
$background_size_img = "auto";
|
||||
$background_size_img = 'auto';
|
||||
$background_repeat = 'no-repeat';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -184,10 +189,11 @@ $options = [
|
|||
'$menu_background_hover_color' => $menu_background_hover_color,
|
||||
'$btn_primary_color' => $nav_icon_color,
|
||||
'$btn_primary_hover_color' => $menu_background_hover_color,
|
||||
'$bgcolor' => $bgcolor,
|
||||
'$background_color' => $background_color,
|
||||
'$contentbg_transp' => $contentbg_transp,
|
||||
'$background_image' => $background_image,
|
||||
'$background_size_img' => $background_size_img,
|
||||
'$background_repeat' => $background_repeat,
|
||||
'$login_bg_image' => $login_bg_image,
|
||||
'$login_bg_color' => $login_bg_color
|
||||
];
|
||||
|
@ -220,7 +226,7 @@ header('Last-Modified: '.$modified);
|
|||
// Only send the CSS file if it was changed.
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
$cached_modified = gmdate('r', strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']));
|
||||
$cached_etag = str_replace(['"', "-gzip"], ['', ''],
|
||||
$cached_etag = str_replace(['"', '-gzip'], ['', ''],
|
||||
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
|
||||
|
||||
if (($cached_modified == $modified) && ($cached_etag == $etag)) {
|
||||
|
|
|
@ -1,16 +1,55 @@
|
|||
<script type="text/javascript" src="view/theme/frio/js/mod_admin.js"></script>
|
||||
<div id="adminpage">
|
||||
<link rel="stylesheet" href="view/theme/frio/css/mod_admin.css" type="text/css" media="screen"/>
|
||||
|
||||
<div id="admin-contactblock" class="adminpage generic-page-wrapper">
|
||||
<h1>{{$title}} - {{$page}}</h1>
|
||||
<p>{{$description}}</p>
|
||||
|
||||
{{* We organize the settings in collapsable panel-groups *}}
|
||||
<div class="panel-group panel-group-settings" id="admin-settings" role="tablist" aria-multiselectable="true">
|
||||
{{* The form for entering user profile which should be blocked *}}
|
||||
<div class="panel">
|
||||
<div class="section-subtitle-wrapper" role="tab" id="admin-settings-contactblock-block">
|
||||
<h4>
|
||||
<a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#admin-settings" href="#admin-settings-contactblock-block-collapse" aria-expanded="false" aria-controls="admin-settings-contactblock-block-collapse">
|
||||
{{$h_newblock}}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="admin-settings-contactblock-block-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-contactblock-block">
|
||||
<form action="{{$baseurl}}/admin/contactblock" method="post">
|
||||
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
|
||||
|
||||
{{include file="field_input.tpl" field=$contacturl}}
|
||||
|
||||
<div class="admin-settings-submit-wrapper form-group pull-right">
|
||||
<button type="submit" class="btn btn-primary" name="page_contactblock_block" value="1">{{$submit|escape:'html'}}</button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{* The list of blocked user profiles with the possibility to unblock them *}}
|
||||
<div class="panel">
|
||||
<div class="section-subtitle-wrapper" role="tab" id="admin-settings-contactblock-blocked">
|
||||
<h4>
|
||||
<a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#admin-settings" href="#admin-settings-contactblock-blocked-collapse" aria-expanded="{{if count($contacts) > 0}}true{{else}}false{{/if}}" aria-controls="admin-settings-contactblock-blocked-collapse">
|
||||
{{$h_contacts}} ({{count($contacts)}})
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="admin-settings-contactblock-blocked-collapse" class="panel-collapse collapse {{if count($contacts) > 0}}in{{/if}}" role="tabpanel" aria-labelledby="admin-settings-contactblock-blocked">
|
||||
<form action="{{$baseurl}}/admin/contactblock" method="post">
|
||||
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
|
||||
|
||||
<h3>{{$h_contacts}}</h3>
|
||||
{{if $contacts}}
|
||||
<table id="contactblock" class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" class="select contacts_ckbx" data-select-class="contacts_ckbx" data-select-all="{{$select_all}}" data-select-none="{{$select_none}}" title="{{$select_all}}"/></th>
|
||||
<th></th>
|
||||
{{foreach $th_contacts as $th}}
|
||||
<th>
|
||||
{{$th}}
|
||||
|
@ -22,39 +61,45 @@
|
|||
<tbody>
|
||||
{{foreach $contacts as $contact}}
|
||||
<tr>
|
||||
<td><input type="checkbox" class="contacts_ckbx" id="id_contact_{{$contact.id}}" name="contacts[]" value="{{$contact.id}}"/></td>
|
||||
<td>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" class="contacts_ckbx" id="id_contact_{{$contact.id}}" name="contacts[]" value="{{$contact.id}}"/>
|
||||
<label for="id_contact_{{$contact.id}}"></label>
|
||||
</div>
|
||||
</td>
|
||||
<td><img class="icon" src="{{$contact.micro}}" alt="{{$contact.nickname}}" title="{{$contact.addr}}"></td>
|
||||
<td class="name">{{$contact.name}}</td>
|
||||
<td class="addr" colspan="2"><a href="{{$contact.url}}" title="{{$contact.addr}}" >{{$contact.url}}</a></td>
|
||||
<td class="addr" colspan="3"><a href="{{$contact.url}}" title="{{$contact.addr}}" >{{$contact.url}}</a></td>
|
||||
</tr>
|
||||
{{/foreach}}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td><input type="checkbox" class="select contacts_ckbx" data-select-class="contacts_ckbx" data-select-all="{{$select_all}}" data-select-none="{{$select_none}}" title="{{$select_all}}"/></td>
|
||||
<td colspan="3">
|
||||
<td>
|
||||
{{* Checkbox to select all blocked contacts *}}
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="contactblock-select" class="selecttoggle contacts_ckbx" data-select-class="contacts_ckbx" data-select-all="{{$select_all}}" data-select-none="{{$select_none}}" title="{{$select_all}}"/>
|
||||
<label for="contactblock-select"></label>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="5">
|
||||
{{$total_contacts}}
|
||||
<div class="admin-settings-submit-wrapper form-group pull-right">
|
||||
<button type="submit" class="btn btn-small btn-default pull-right" name="page_contactblock_unblock" value="1">{{$unblock|escape:'html'}}</button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="submit"><button type="submit" class="btn btn-small btn-default" name="page_contactblock_unblock" value="1">{{$unblock|escape:'html'}}</button></div>
|
||||
|
||||
{{$paginate}}
|
||||
|
||||
{{else}}
|
||||
<p>{{$no_data|escape:'html'}}</p>
|
||||
{{/if}}
|
||||
</form>
|
||||
|
||||
<h3>{{$h_newblock}}</h3>
|
||||
<form action="{{$baseurl}}/admin/contactblock" method="post">
|
||||
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
|
||||
<table id="contactblock">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{include file="field_input.tpl" field=$contacturl}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="submit"><button type="submit" class="btn btn-primary" name="page_contactblock_block" value="1">{{$submit|escape:'html'}}</button></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<form action="{{$baseurl}}/admin/users" method="post">
|
||||
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
|
||||
|
||||
{{* We organize the settings in collapsable panel-groups *}}
|
||||
<div class="panel-group panel-group-settings" id="admin-settings" role="tablist" aria-multiselectable="true">
|
||||
|
||||
<!--
|
||||
**
|
||||
|
@ -15,9 +17,16 @@
|
|||
*
|
||||
**
|
||||
-->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">{{$h_pending}}</h3></div>
|
||||
<div class="panel">
|
||||
<div class="section-subtitle-wrapper" role="tab" id="admin-settings-pending">
|
||||
<h4>
|
||||
<a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#admin-settings" href="#admin-settings-pending-collapse" aria-expanded="{{if count($pending) > 0}}true{{else}}false{{/if}}" aria-controls="admin-settings-pending-collapse">
|
||||
{{$h_pending}} ({{count($pending)}})
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="admin-settings-pending-collapse" class="panel-collapse collapse {{if count($pending) > 0}}in{{/if}}" role="tabpanel" aria-labelledby="admin-settings-pending">
|
||||
{{if $pending}}
|
||||
<table id="pending" class="table table-hover">
|
||||
<thead>
|
||||
|
@ -30,34 +39,45 @@
|
|||
<tbody>
|
||||
{{foreach $pending as $u}}
|
||||
<tr>
|
||||
<td><input type="checkbox" class="pending_ckbx" id="id_pending_{{$u.hash}}" name="pending[]" value="{{$u.hash}}" /></td>
|
||||
<td>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" class="pending_ckbx" id="id_pending_{{$u.hash}}" name="pending[]" value="{{$u.hash}}" />
|
||||
<label for="id_pending_{{$u.hash}}"></label>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{$u.created}}</td>
|
||||
<td>{{$u.name}}</td>
|
||||
<td>{{$u.email}}</td>
|
||||
<td>
|
||||
<a href="{{$baseurl}}/regmod/allow/{{$u.hash}}" title="{{$approve}}"><i class="fa fa-thumbs-up" aria-hidden="true"></i></a>
|
||||
<a href="{{$baseurl}}/regmod/deny/{{$u.hash}}" title="{{$deny}}"><i class="fa fa-thumbs-down" aria-hidden="true"></i></a>
|
||||
<a href="{{$baseurl}}/regmod/allow/{{$u.hash}}" class="admin-settings-action-link" title="{{$approve}}"><i class="fa fa-check" aria-hidden="true"></i></a>
|
||||
<a href="{{$baseurl}}/regmod/deny/{{$u.hash}}" class="admin-settings-action-link" title="{{$deny}}"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{{if $u.note}}
|
||||
<tr class="details">
|
||||
<td></td>
|
||||
<th>{{$pendingnotetext}}</th>
|
||||
<td colspan="4">{{$u.note}}</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="panel-footer">
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default selectall" data-select-all="pending_ckbx"><i class="fa fa-check-square-o" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-default selectnone" data-select-none="pending_ckbx"><i class="fa fa-square-o" aria-hidden="true"></i></button>
|
||||
<div class="col-xs-3 admin-settings-footer-elements">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="admin-settings-pending-select" class="selecttoggle" data-select-class="pending_ckbx"/>
|
||||
<label for="admin-settings-pending-select"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-9 text-right">
|
||||
<button type="submit" name="page_users_deny" class="btn btn-primary"><i class="fa fa-thumbs-down" aria-hidden="true"></i> {{$deny}}</button>
|
||||
<button type="submit" name="page_users_approve" class="btn btn-warinig"><i class="fa fa-thumbs-up" aria-hidden="true"></i> {{$approve}}</button>
|
||||
<div class="col-xs-9 admin-settings-footer-elements text-right">
|
||||
<button type="submit" name="page_users_deny" value="1" class="btn btn-primary">
|
||||
<i class="fa fa-trash-o" aria-hidden="true"></i> {{$deny}}
|
||||
</button>
|
||||
<button type="submit" name="page_users_approve" value="1" class="btn btn-warinig">
|
||||
<i class="fa fa-check" aria-hidden="true"></i> {{$approve}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -65,6 +85,7 @@
|
|||
<div class="panel-body text-center text-muted">{{$no_pending}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
**
|
||||
|
@ -73,10 +94,18 @@
|
|||
*
|
||||
**
|
||||
-->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">{{$h_users}}</h3></div>
|
||||
{{if $users}}
|
||||
<div class="panel">
|
||||
<div class="section-subtitle-wrapper" role="tab" id="admin-settings-user">
|
||||
<h4>
|
||||
<a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#admin-settings" href="#admin-settings-user-collapse" aria-expanded="false" aria-controls="admin-settings-user-collapse">
|
||||
{{$h_users}} ({{count($users)}})
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="admin-settings-user-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-user">
|
||||
|
||||
{{if $users}}
|
||||
<table id="users" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -85,7 +114,7 @@
|
|||
{{foreach $th_users as $k=>$th}}
|
||||
{{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }}
|
||||
<th class="th-{{$k}}">
|
||||
<a href="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th.1}}">
|
||||
<button type="button" data-order-url="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th.1}}" class="btn-link table-order">
|
||||
{{if $order_users == $th.1}}
|
||||
{{if $order_direction_users == "+"}}
|
||||
↓
|
||||
|
@ -95,7 +124,8 @@
|
|||
{{else}}
|
||||
↕
|
||||
{{/if}}
|
||||
{{$th.0}}</a>
|
||||
{{$th.0}}
|
||||
</button>
|
||||
</th>
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
|
@ -104,10 +134,13 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
{{foreach $users as $u}}
|
||||
<tr id="user-{{$u.uid}}">
|
||||
<tr id="user-{{$u.uid}}" class="{{if $u.blocked != 0}}blocked{{/if}}">
|
||||
<td>
|
||||
{{if $u.is_deletable}}
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" class="users_ckbx" id="id_user_{{$u.uid}}" name="user[]" value="{{$u.uid}}"/>
|
||||
<label for="id_user_{{$u.uid}}"></label>
|
||||
</div>
|
||||
{{else}}
|
||||
|
||||
{{/if}}
|
||||
|
@ -128,7 +161,6 @@
|
|||
{{/if}}
|
||||
|
||||
{{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }}
|
||||
|
||||
<td>
|
||||
<i class="fa
|
||||
{{if $u.page_flags_raw==0}}fa-user{{/if}} {{* PAGE_NORMAL *}}
|
||||
|
@ -137,56 +169,69 @@
|
|||
{{if $u.page_flags_raw==3}}fa-heart{{/if}} {{* PAGE_FREELOVE *}}
|
||||
{{if $u.page_flags_raw==4}}fa-rss{{/if}} {{* PAGE_BLOG *}}
|
||||
{{if $u.page_flags_raw==5}}fa-user-secret{{/if}} {{* PAGE_PRVGROUP *}}
|
||||
" title="{{$u.page_flags}}"></i>
|
||||
" title="{{$u.page_flags}}">
|
||||
</i>
|
||||
{{if $u.page_flags_raw==0 && $u.account_type_raw > 0}}
|
||||
<i class="fa
|
||||
{{if $u.account_type_raw==1}}fa-sitemap{{/if}} {{* ACCOUNT_TYPE_ORGANISATION *}}
|
||||
{{if $u.account_type_raw==2}}fa-newspaper-o{{/if}} {{* ACCOUNT_TYPE_NEWS *}}
|
||||
{{if $u.account_type_raw==3}}fa-comments{{/if}} {{* ACCOUNT_TYPE_COMMUNITY *}}
|
||||
" title="{{$u.account_type}}"></i>
|
||||
" title="{{$u.account_type}}">
|
||||
</i>
|
||||
{{/if}}
|
||||
{{if $u.is_admin}}<i class="fa fa-user-md text-primary" title="{{$siteadmin}}"></i>{{/if}}
|
||||
{{if $u.account_expired}}<i class="fa fa-clock-o text-warning" title="{{$accountexpired}}"></i>{{/if}}
|
||||
</td>
|
||||
{{/if}}
|
||||
|
||||
<td class="text-right">
|
||||
<button type="button" class="btn-link" onclick="return details({{$u.uid}})"><span class="caret"></span></button>
|
||||
<button type="button" class="btn-link admin-settings-action-link" onclick="return details({{$u.uid}})"><span class="caret"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="user-{{$u.uid}}-detail" class="hidden details">
|
||||
<tr id="user-{{$u.uid}}-detail" class=" details hidden {{if $u.blocked != 0}}blocked{{/if}}">
|
||||
<td> </td>
|
||||
<td colspan="4">
|
||||
{{if $order_users != $th_users.2.1}}
|
||||
<p><a href="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.2.1}}">
|
||||
↕ {{$th_users.2.0}}</a> : {{$u.register_date}}</p>
|
||||
<p>
|
||||
<button type="button" data-order-url="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.2.1}}" class="btn-link table-order">
|
||||
↕ {{$th_users.2.0}}</button> : {{$u.register_date}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{if $order_users != $th_users.3.1}}
|
||||
<p><a href="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.3.1}}">
|
||||
↕ {{$th_users.3.0}}</a> : {{$u.login_date}}</p>
|
||||
<p>
|
||||
<button type="button" data-order-url="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.3.1}}" class="btn-link table-order">
|
||||
↕ {{$th_users.3.0}}</button> : {{$u.login_date}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{if $order_users != $th_users.4.1}}
|
||||
<p><a href="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.4.1}}">
|
||||
↕ {{$th_users.4.0}}</a> : {{$u.lastitem_date}}</p>
|
||||
<p>
|
||||
<button type="button" data-order-url="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.4.1}}" class="btn-link table-order">
|
||||
↕ {{$th_users.4.0}}</button> : {{$u.lastitem_date}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{if in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }}
|
||||
<p><a href="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.5.1}}">
|
||||
↕ {{$th_users.5.0}}</a> : {{$u.page_flags}}{{if $u.page_flags_raw==0 && $u.account_type_raw > 0}}, {{$u.account_type}}{{/if}} {{if $u.is_admin}}({{$siteadmin}}){{/if}} {{if $u.account_expired}}({{$accountexpired}}){{/if}}</p>
|
||||
<p>
|
||||
<button type="button" data-order-url="{{$baseurl}}/admin/users/?o={{if $order_direction_users == "+"}}-{{/if}}{{$th_users.5.1}}" class="btn-link table-order">
|
||||
↕ {{$th_users.5.0}}</button> : {{$u.page_flags}}{{if $u.page_flags_raw==0 && $u.account_type_raw > 0}}, {{$u.account_type}}{{/if}} {{if $u.is_admin}}({{$siteadmin}}){{/if}} {{if $u.account_expired}}({{$accountexpired}}){{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{if $u.is_deletable}}
|
||||
<a href="{{$baseurl}}/admin/users/block/{{$u.uid}}?t={{$form_security_token}}" title="{{if $u.blocked}}{{$unblock}}{{else}}{{$block}}{{/if}}">
|
||||
<a href="{{$baseurl}}/admin/users/block/{{$u.uid}}?t={{$form_security_token}}" class="admin-settings-action-link"title="{{if $u.blocked}}{{$unblock}}{{else}}{{$block}}{{/if}}">
|
||||
{{if $u.blocked == 0}}
|
||||
<i class="fa fa-ban" aria-hidden="true"></i>
|
||||
{{else}}
|
||||
<i class="fa fa-circle-o" aria-hidden="true"></i>
|
||||
{{/if}}
|
||||
</a>
|
||||
<a href="{{$baseurl}}/admin/users/delete/{{$u.uid}}?t={{$form_security_token}}" title="{{$delete}}" onclick="return confirm_delete('{{$confirm_delete}}','{{$u.name}}')"><i class="fa fa-trash" aria-hidden="true"></i></a>
|
||||
<a href="{{$baseurl}}/admin/users/delete/{{$u.uid}}?t={{$form_security_token}}" class="admin-settings-action-link" title="{{$delete}}" onclick="return confirm_delete('{{$confirm_delete}}','{{$u.name}}')">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</a>
|
||||
{{else}}
|
||||
|
||||
{{/if}}
|
||||
|
@ -197,15 +242,19 @@
|
|||
</table>
|
||||
<div class="panel-footer">
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default selectall" data-select-all="users_ckbx"><i class="fa fa-check-square-o" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-default selectnone" data-select-none="users_ckbx"><i class="fa fa-square-o" aria-hidden="true"></i></button>
|
||||
<div class="col-xs-3 admin-settings-footer-elements">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="admin-settings-users-select" class="selecttoggle" data-select-class="users_ckbx"/>
|
||||
<label for="admin-settings-users-select"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-9 text-right">
|
||||
<button type="submit" name="page_users_block" class="btn btn-warning"> <i class="fa fa-ban" aria-hidden="true"></i> {{$block}} / <i class="fa fa-circle-o" aria-hidden="true"></i> {{$unblock}}</button>
|
||||
<button type="submit" name="page_users_delete" class="btn btn-danger" onclick="return confirm_delete('{{$confirm_delete_multi}}')"><i class="fa fa-trash" aria-hidden="true"></i> {{$delete}}</button>
|
||||
<div class="col-xs-9 admin-settings-footer-elements text-right">
|
||||
<button type="submit" name="page_users_block" value="1" class="btn btn-warning">
|
||||
<i class="fa fa-ban" aria-hidden="true"></i> {{$block}} / <i class="fa fa-circle-o" aria-hidden="true"></i> {{$unblock}}
|
||||
</button>
|
||||
<button type="submit" name="page_users_delete" value="1" class="btn btn-danger" onclick="return confirm_delete('{{$confirm_delete_multi}}')">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> {{$delete}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -213,13 +262,7 @@
|
|||
<div class="panel-body text-center bg-danger">NO USERS?!?</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!--
|
||||
|
@ -230,8 +273,16 @@
|
|||
**
|
||||
-->
|
||||
{{if $deleted}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">{{$h_deleted}}</h3></div>
|
||||
<div class="panel">
|
||||
<div class="section-subtitle-wrapper" role="tab" id="admin-settings-deleted">
|
||||
<h4>
|
||||
<a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#admin-settings" href="#admin-settings-deleted-collapse" aria-expanded="false" aria-controls="admin-settings-deleted-collapse">
|
||||
{{$h_deleted}} ({{count($deleted)}})
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="admin-settings-deleted-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-deleted">
|
||||
<table id="deleted" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -255,6 +306,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
@ -266,11 +318,16 @@
|
|||
*
|
||||
**
|
||||
-->
|
||||
<form action="{{$baseurl}}/admin/users" method="post">
|
||||
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
|
||||
<div class="panel">
|
||||
<div class="section-subtitle-wrapper" role="tab" id="admin-settings-new-user">
|
||||
<h4>
|
||||
<a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#admin-settings" href="#admin-settings-new-user-collapse" aria-expanded="false" aria-controls="admin-settings-new-user-collapse">
|
||||
{{$h_newuser}}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h3 class="panel-title">{{$h_newuser}}</h3></div>
|
||||
<div id="admin-settings-new-user-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-new-user">
|
||||
<div class="panel-body">
|
||||
{{include file="field_input.tpl" field=$newusername}}
|
||||
{{include file="field_input.tpl" field=$newusernickname}}
|
||||
|
@ -278,8 +335,11 @@
|
|||
</div>
|
||||
<div class="panel-footer text-right">
|
||||
<button type="submit" class="btn btn-primary">{{$submit}}</button>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
{{/if}}
|
||||
<ul class="comment-edit-bb-{{$id}} comment-icon-list nav nav-pills pull-right">
|
||||
<li>
|
||||
<button type="button" class="btn-link icon" style="cursor: pointer;" aria-label="{{$edimg}}" title="{{$edimg}}" data-role="insert-formatting" data-bbcode="img" data-id="{{$id}}">
|
||||
<button type="button" class="btn-link icon bb-img" style="cursor: pointer;" aria-label="{{$edimg}}" title="{{$edimg}}" data-role="insert-formatting" data-bbcode="img" data-id="{{$id}}">
|
||||
<i class="fa fa-picture-o"></i>
|
||||
</button>
|
||||
</li>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<ul id="event-desc-text-edit-bb" class="comment-edit-bb comment-icon-list nav nav-pills hidden-xs pull-left">
|
||||
{{* commented out because it isn't implemented yet
|
||||
<li>
|
||||
<button type="button" class="btn-link icon" style="cursor: pointer;" title="{{$edimg|escape:'html'}}" data-role="insert-formatting" data-comment=" " data-bbcode="img" data-id="desc">
|
||||
<button type="button" class="btn-link icon bb-img" style="cursor: pointer;" title="{{$edimg|escape:'html'}}" data-role="insert-formatting" data-comment=" " data-bbcode="img" data-id="desc">
|
||||
<i class="fa fa-picture-o"></i>
|
||||
</button>
|
||||
</li>
|
||||
|
@ -126,7 +126,7 @@
|
|||
<ul id="comment-tools-loc" class="comment-edit-bb comment-icon-list nav nav-pills hidden-xs pull-left">
|
||||
{{* commented out because it isn't implemented yet
|
||||
<li>
|
||||
<button type="button" class="btn-link icon" style="cursor: pointer;" title="{{$edimg|escape:'html'}}" data-role="insert-formatting" data-comment=" " data-bbcode="img" data-id="loc">
|
||||
<button type="button" class="btn-link icon bb-img" style="cursor: pointer;" title="{{$edimg|escape:'html'}}" data-role="insert-formatting" data-comment=" " data-bbcode="img" data-id="loc">
|
||||
<i class="fa fa-picture-o"></i>
|
||||
</button>
|
||||
</li>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<input type="checkbox" name="{{$field.0}}" id="id_{{$field.0}}" value="1" {{if $field.2}}checked="checked"{{/if}} aria-checked="{{if $field.2}}true{{else}}false{{/if}}" aria-describedby="{{$field.0}}_tip" {{if $field.4}}{{$field.4}}{{/if}}>
|
||||
<label for="id_{{$field.0}}">
|
||||
{{$field.1}}
|
||||
{{if $field.3}}
|
||||
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</label>
|
||||
</div>
|
|
@ -6,6 +6,8 @@
|
|||
{{if $field.4}}<span class="required">{{$field.4}}</span>{{/if}}
|
||||
<span class="input-group-addon"><i></i></span>
|
||||
</div>
|
||||
<span id="{{$field.0}}_tip" class="help-block" role="tooltip">{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
<div id="end_{{$field.0}}" class="field_end"></div>
|
||||
</div>
|
||||
|
|
|
@ -2,5 +2,7 @@
|
|||
<div class="form-group field custom">
|
||||
<label for="{{$field.0}}">{{$field.1}}</label>
|
||||
{{$field.2}}
|
||||
<span class="help-block" id="{{$field.0}}_tip">{{$field.3}}</span>
|
||||
{{if $field.3}}
|
||||
<span class="help-block" id="{{$field.0}}_tip" role="tooltip">{{$field.3}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue