2016-03-28 16:29:05 +02:00
< ? php
/*
* Name : frio
2016-06-13 10:57:42 +02:00
* Description : Bootstrap V3 theme . The theme is currently under construction , so it is far from finished . For further information have a look at the < a href = " https://github.com/friendica/friendica/tree/develop/view/theme/frio/README.md " > ReadMe </ a >.
2018-09-05 18:31:09 +02:00
* Version : V . 0.8 . 5
2016-03-28 16:29:05 +02:00
* Author : Rabuzarus < https :// friendica . kommune4 . de / profile / rabuzarus >
2017-01-09 13:06:08 +01:00
*
2016-03-28 16:29:05 +02:00
*/
2018-02-05 01:23:49 +01:00
2017-04-30 06:07:00 +02:00
use Friendica\App ;
2018-02-05 01:23:49 +01:00
use Friendica\Content\Text\Plaintext ;
2018-01-15 15:50:06 +01:00
use Friendica\Content\Widget ;
2018-12-26 16:06:05 +01:00
use Friendica\Core\Hook ;
2018-10-29 22:20:46 +01:00
use Friendica\Core\Logger ;
2018-10-31 18:25:38 +01:00
use Friendica\Core\Renderer ;
2019-05-26 22:15:38 +02:00
use Friendica\Core\Session ;
2018-07-21 14:40:21 +02:00
use Friendica\Database\DBA ;
2019-12-16 00:36:31 +01:00
use Friendica\DI ;
2018-10-13 11:35:51 +02:00
use Friendica\Model ;
2020-08-02 09:54:18 +02:00
use Friendica\Model\Contact ;
2018-10-14 20:03:22 +02:00
use Friendica\Module ;
2018-11-08 16:14:37 +01:00
use Friendica\Util\Strings ;
2017-04-30 06:07:00 +02:00
2020-08-20 04:58:00 +02:00
const FRIO_SCHEME_ACCENT_BLUE = '#1e87c2' ;
2020-08-20 04:58:21 +02:00
const FRIO_SCHEME_ACCENT_RED = '#b50404' ;
const FRIO_SCHEME_ACCENT_PURPLE = '#a54bad' ;
const FRIO_SCHEME_ACCENT_GREEN = '#218f39' ;
const FRIO_SCHEME_ACCENT_PINK = '#d900a9' ;
2018-01-01 21:05:09 +01:00
function frio_init ( App $a )
{
2019-01-20 03:54:10 +01:00
global $frio ;
$frio = 'view/theme/frio' ;
2016-06-20 13:44:11 +02:00
// disable the events module link in the profile tab
$a -> theme_events_in_profile = false ;
2018-01-09 05:52:54 +01:00
$a -> videowidth = 622 ;
2016-06-20 13:44:11 +02:00
2018-10-31 18:25:38 +01:00
Renderer :: setActiveTemplateEngine ( 'smarty3' );
2016-03-28 16:29:05 +02:00
2016-05-28 13:07:24 +02:00
// if the device is a mobile device set js is_mobile
// variable so the js scripts can use this information
2019-12-16 01:12:07 +01:00
if ( DI :: mode () -> isMobile () || DI :: mode () -> isMobile ()) {
2019-12-30 20:02:09 +01:00
DI :: page ()[ 'htmlhead' ] .= <<< EOT
2017-10-20 15:21:42 +02:00
< script type = " text/javascript " >
2016-05-28 13:07:24 +02:00
var is_mobile = 1 ;
</ script >
EOT ;
2018-01-01 21:05:09 +01:00
}
2016-03-28 16:29:05 +02:00
}
2018-01-01 21:05:09 +01:00
function frio_install ()
{
2018-12-26 16:06:05 +01:00
Hook :: register ( 'prepare_body_final' , 'view/theme/frio/theme.php' , 'frio_item_photo_links' );
Hook :: register ( 'item_photo_menu' , 'view/theme/frio/theme.php' , 'frio_item_photo_menu' );
Hook :: register ( 'contact_photo_menu' , 'view/theme/frio/theme.php' , 'frio_contact_photo_menu' );
Hook :: register ( 'nav_info' , 'view/theme/frio/theme.php' , 'frio_remote_nav' );
Hook :: register ( 'acl_lookup_end' , 'view/theme/frio/theme.php' , 'frio_acl_lookup' );
Hook :: register ( 'display_item' , 'view/theme/frio/theme.php' , 'frio_display_item' );
2016-03-28 16:29:05 +02:00
2018-10-29 22:20:46 +01:00
Logger :: log ( 'installed theme frio' );
2016-03-28 16:29:05 +02:00
}
2016-04-14 14:07:20 +02:00
/**
2020-01-19 07:05:23 +01:00
* Replace friendica photo links hook
2017-01-09 13:06:08 +01:00
*
2016-04-14 14:07:20 +02:00
* This function does replace the links to photos
* of other friendica users . Original the photos are
* linked to the photo page . Now they will linked directly
* to the photo file . This function is nessesary to use colorbox
* in the network stream
2017-01-09 13:06:08 +01:00
*
* @ param App $a Unused but required by hook definition
2016-04-14 14:07:20 +02:00
* @ param array $body_info The item and its html output
*/
2017-11-29 13:52:27 +01:00
function frio_item_photo_links ( App $a , & $body_info )
{
2018-02-05 01:23:49 +01:00
$occurence = 0 ;
2018-04-25 02:12:43 +02:00
$p = Plaintext :: getBoundariesPosition ( $body_info [ 'html' ], '<a' , '>' );
2018-01-01 21:05:09 +01:00
while ( $p !== false && ( $occurence ++ < 500 )) {
2016-04-14 14:07:20 +02:00
$link = substr ( $body_info [ 'html' ], $p [ 'start' ], $p [ 'end' ] - $p [ 'start' ]);
2018-01-15 14:05:12 +01:00
$matches = [];
2016-04-14 14:07:20 +02:00
2018-04-25 02:12:43 +02:00
preg_match ( '/\/photos\/[\w]+\/image\/([\w]+)/' , $link , $matches );
2018-01-01 21:05:09 +01:00
if ( $matches ) {
2016-04-14 14:07:20 +02:00
// Replace the link for the photo's page with a direct link to the photo itself
$newlink = str_replace ( $matches [ 0 ], " /photo/ { $matches [ 1 ] } " , $link );
// Add a "quiet" parameter to any redir links to prevent the "XX welcomes YY" info boxes
2018-04-25 02:12:43 +02:00
$newlink = preg_replace ( '/href="([^"]+)\/redir\/([^"]+)&url=([^"]+)"/' , 'href="$1/redir/$2&quiet=1&url=$3"' , $newlink );
2016-04-14 14:07:20 +02:00
2018-01-01 21:05:09 +01:00
// Having any arguments to the link for Colorbox causes it to fetch base64 code instead of the image
2018-04-25 02:12:43 +02:00
$newlink = preg_replace ( '/\/[?&]zrl=([^&"]+)/' , '' , $newlink );
2016-04-14 14:07:20 +02:00
$body_info [ 'html' ] = str_replace ( $link , $newlink , $body_info [ 'html' ]);
}
2018-04-25 02:12:43 +02:00
$p = Plaintext :: getBoundariesPosition ( $body_info [ 'html' ], '<a' , '>' , $occurence );
2016-04-14 14:07:20 +02:00
}
}
2016-04-17 00:55:43 +02:00
/**
2020-01-19 07:05:23 +01:00
* Replace links of the item_photo_menu hook
2017-01-09 13:06:08 +01:00
*
2016-04-17 00:55:43 +02:00
* This function replaces the original poke and the message links
* to call the addToModal javascript function so this pages can
* be loaded in a bootstrap modal
2017-01-09 13:06:08 +01:00
*
* @ param App $a Unused but required by the hook definition
2016-04-17 00:55:43 +02:00
* @ param array $arr Contains item data and the original photo_menu
*/
2018-01-01 21:05:09 +01:00
function frio_item_photo_menu ( App $a , & $arr )
{
2018-04-25 02:12:43 +02:00
foreach ( $arr [ 'menu' ] as $k => $v ) {
2020-04-20 17:42:27 +02:00
if ( strpos ( $v , '/poke' ) === 0 || strpos ( $v , 'message/new/' ) === 0 ) {
2018-04-25 02:12:43 +02:00
$v = 'javascript:addToModal(\'' . $v . '\'); return false;' ;
$arr [ 'menu' ][ $k ] = $v ;
2016-04-17 00:55:43 +02:00
}
}
}
2016-04-19 02:06:02 +02:00
2016-04-20 19:32:19 +02:00
/**
2020-01-19 07:05:23 +01:00
* Replace links of the contact_photo_menu
2017-01-09 13:06:08 +01:00
*
2016-04-20 19:32:19 +02:00
* This function replaces the original poke and the message links
* to call the addToModal javascript function so this pages can
* be loaded in a bootstrap modal
2016-04-20 19:59:44 +02:00
* Additionally the profile , status and photo page links will be changed
* to don ' t open in a new tab if the contact is a friendica contact .
2017-01-09 13:06:08 +01:00
*
2017-04-30 06:17:49 +02:00
* @ param App $a The app data
2016-04-20 19:32:19 +02:00
* @ param array $args Contains contact data and the original photo_menu
*/
2018-01-01 21:05:09 +01:00
function frio_contact_photo_menu ( App $a , & $args )
{
2018-04-25 02:12:43 +02:00
$cid = $args [ 'contact' ][ 'id' ];
2018-08-25 15:48:00 +02:00
if ( ! empty ( $args [ 'menu' ][ 'poke' ])) {
$pokelink = $args [ 'menu' ][ 'poke' ][ 1 ];
} else {
$pokelink = '' ;
}
if ( ! empty ( $args [ 'menu' ][ 'poke' ])) {
$pmlink = $args [ 'menu' ][ 'pm' ][ 1 ];
} else {
$pmlink = '' ;
}
2016-04-20 19:32:19 +02:00
2016-04-20 19:59:44 +02:00
// Set the the indicator for opening the status, profile and photo pages
// in a new tab to false if the contact a dfrn (friendica) contact
// We do this because we can go back on foreign friendica pages throuhg
// friendicas "magic-link" which indicates a friendica user on froreign
// friendica servers as remote user or visitor
//
2017-01-09 13:06:08 +01:00
// The value for opening in a new tab is e.g. when
2018-04-25 02:12:43 +02:00
// $args['menu']['status'][2] is true. If the value of the [2] key is true
2016-04-20 19:59:44 +02:00
// and if it's a friendica contact we set it to false
2018-04-25 02:12:43 +02:00
foreach ( $args [ 'menu' ] as $k => $v ) {
if ( $k === 'status' || $k === 'profile' || $k === 'photos' ) {
$v [ 2 ] = (( $args [ 'contact' ][ 'network' ] === 'dfrn' ) ? false : true );
$args [ 'menu' ][ $k ][ 2 ] = $v [ 2 ];
2016-04-20 19:59:44 +02:00
}
}
2016-04-20 19:32:19 +02:00
// Add to pm and poke links a new key with the value 'modal'.
// Later we can make conditions in the corresponing templates (e.g.
// contact_template.tpl)
2020-04-20 17:42:27 +02:00
if ( strpos ( $pokelink , $cid . '/poke' ) !== false ) {
2018-04-25 02:12:43 +02:00
$args [ 'menu' ][ 'poke' ][ 3 ] = 'modal' ;
2018-01-01 21:05:09 +01:00
}
2016-04-20 19:32:19 +02:00
2018-01-01 21:05:09 +01:00
if ( strpos ( $pmlink , 'message/new/' . $cid ) !== false ) {
2018-04-25 02:12:43 +02:00
$args [ 'menu' ][ 'pm' ][ 3 ] = 'modal' ;
2018-01-01 21:05:09 +01:00
}
2016-04-20 19:32:19 +02:00
}
2016-04-19 02:06:02 +02:00
/**
2020-01-19 07:05:23 +01:00
* Construct remote nav menu
2017-01-09 13:06:08 +01:00
*
2016-04-19 02:06:02 +02:00
* It creates a remote baseurl form $_SESSION for remote users and friendica
2017-01-09 13:06:08 +01:00
* visitors . This url will be added to some of the nav links . With this behaviour
2016-04-19 02:06:02 +02:00
* the user will come back to her / his own pages on his / her friendica server .
* Not all possible links are available ( notifications , administrator , manage ,
* notes aren ' t available because we have no way the check remote permissions ) ..
* Some links will point to the local pages because the user would expect
* local page ( these pages are : search , community , help , apps , directory ) .
2017-01-09 13:06:08 +01:00
*
2017-04-30 06:17:49 +02:00
* @ param App $a The App class
2016-04-19 02:06:02 +02:00
* @ param array $nav The original nav menu
*/
2018-01-01 21:05:09 +01:00
function frio_remote_nav ( $a , & $nav )
{
2016-04-19 02:06:02 +02:00
// get the homelink from $_XSESSION
2018-10-13 11:35:51 +02:00
$homelink = Model\Profile :: getMyURL ();
2018-01-01 21:05:09 +01:00
if ( ! $homelink ) {
2019-05-26 22:15:38 +02:00
$homelink = Session :: get ( 'visitor_home' , '' );
2018-01-01 21:05:09 +01:00
}
2016-04-19 02:06:02 +02:00
// since $userinfo isn't available for the hook we write it to the nav array
// this isn't optimal because the contact query will be done now twice
2020-08-02 17:44:41 +02:00
$fields = [ 'id' , 'url' , 'avatar' , 'micro' , 'name' , 'nick' , 'baseurl' ];
2020-07-09 21:08:09 +02:00
if ( local_user () && ! empty ( $a -> user [ 'uid' ])) {
2020-08-05 05:39:00 +02:00
$remoteUser = Contact :: selectFirst ( $fields , [ 'uid' => $a -> user [ 'uid' ], 'self' => true ]);
2017-08-03 07:50:44 +02:00
} elseif ( ! local_user () && remote_user ()) {
2020-08-02 17:44:41 +02:00
$remoteUser = Contact :: getById ( remote_user (), $fields );
2020-01-18 20:52:34 +01:00
$nav [ 'remote' ] = DI :: l10n () -> t ( 'Guest' );
2018-10-13 11:35:51 +02:00
} elseif ( Model\Profile :: getMyURL ()) {
2020-08-05 14:57:02 +02:00
$remoteUser = Contact :: getByURL ( $homelink , null , $fields );
2020-01-18 20:52:34 +01:00
$nav [ 'remote' ] = DI :: l10n () -> t ( 'Visitor' );
2017-08-03 07:50:44 +02:00
} else {
2020-08-02 09:54:18 +02:00
$remoteUser = null ;
2016-04-19 02:06:02 +02:00
}
2020-08-02 09:54:18 +02:00
if ( DBA :: isResult ( $remoteUser )) {
2018-01-15 14:05:12 +01:00
$nav [ 'userinfo' ] = [
2020-08-02 09:54:18 +02:00
'icon' => Contact :: getMicro ( $remoteUser ),
'name' => $remoteUser [ 'name' ],
2018-01-15 14:05:12 +01:00
];
2020-08-02 09:54:18 +02:00
$server_url = $remoteUser [ 'baseurl' ];
2018-01-01 21:05:09 +01:00
}
2016-04-19 02:06:02 +02:00
2019-01-27 13:21:18 +01:00
if ( ! local_user () && ! empty ( $server_url ) && ! is_null ( $remoteUser )) {
2016-04-19 02:06:02 +02:00
// user menu
2020-01-18 20:52:34 +01:00
$nav [ 'usermenu' ][] = [ $server_url . '/profile/' . $remoteUser [ 'nick' ], DI :: l10n () -> t ( 'Status' ), '' , DI :: l10n () -> t ( 'Your posts and conversations' )];
2020-01-28 01:21:18 +01:00
$nav [ 'usermenu' ][] = [ $server_url . '/profile/' . $remoteUser [ 'nick' ] . '/profile' , DI :: l10n () -> t ( 'Profile' ), '' , DI :: l10n () -> t ( 'Your profile page' )];
2020-01-18 20:52:34 +01:00
$nav [ 'usermenu' ][] = [ $server_url . '/photos/' . $remoteUser [ 'nick' ], DI :: l10n () -> t ( 'Photos' ), '' , DI :: l10n () -> t ( 'Your photos' )];
$nav [ 'usermenu' ][] = [ $server_url . '/videos/' . $remoteUser [ 'nick' ], DI :: l10n () -> t ( 'Videos' ), '' , DI :: l10n () -> t ( 'Your videos' )];
$nav [ 'usermenu' ][] = [ $server_url . '/events/' , DI :: l10n () -> t ( 'Events' ), '' , DI :: l10n () -> t ( 'Your events' )];
2016-04-19 02:06:02 +02:00
// navbar links
2020-01-18 20:52:34 +01:00
$nav [ 'network' ] = [ $server_url . '/network' , DI :: l10n () -> t ( 'Network' ), '' , DI :: l10n () -> t ( 'Conversations from your friends' )];
$nav [ 'events' ] = [ $server_url . '/events' , DI :: l10n () -> t ( 'Events' ), '' , DI :: l10n () -> t ( 'Events and Calendar' )];
$nav [ 'messages' ] = [ $server_url . '/message' , DI :: l10n () -> t ( 'Messages' ), '' , DI :: l10n () -> t ( 'Private mail' )];
$nav [ 'settings' ] = [ $server_url . '/settings' , DI :: l10n () -> t ( 'Settings' ), '' , DI :: l10n () -> t ( 'Account settings' )];
$nav [ 'contacts' ] = [ $server_url . '/contact' , DI :: l10n () -> t ( 'Contacts' ), '' , DI :: l10n () -> t ( 'Manage/edit friends and contacts' )];
2020-01-19 21:21:13 +01:00
$nav [ 'sitename' ] = DI :: config () -> get ( 'config' , 'sitename' );
2016-04-19 02:06:02 +02:00
}
}
2018-01-01 21:05:09 +01:00
2016-04-28 21:35:33 +02:00
/**
2020-01-19 21:44:01 +01:00
* Search for contacts
2017-01-09 13:06:08 +01:00
*
2016-04-28 21:35:33 +02:00
* This function search for a users contacts . The code is copied from contact search
2018-10-13 13:29:56 +02:00
* in / src / Module / Contact . php . With this function the contacts will permitted to acl_lookup ()
2017-01-09 13:06:08 +01:00
* and can grabbed as json . For this we use the type = " r " . This is usful to to let js
2016-04-28 21:35:33 +02:00
* grab the contact data .
* We use this to give the data to textcomplete and have a filter function at the
* contact page .
2017-01-09 13:06:08 +01:00
*
2016-12-20 21:16:01 +01:00
* @ param App $a The app data @ TODO Unused
2016-04-28 21:35:33 +02:00
* @ param array $results The array with the originals from acl_lookup ()
*/
2018-01-01 21:05:09 +01:00
function frio_acl_lookup ( App $a , & $results )
{
2018-11-30 15:06:22 +01:00
$nets = ! empty ( $_GET [ 'nets' ]) ? Strings :: escapeTags ( trim ( $_GET [ 'nets' ])) : '' ;
2016-04-28 21:35:33 +02:00
// we introduce a new search type, r should do the same query like it's
2018-10-13 13:29:56 +02:00
// done in /src/Module/Contact.php for connections
2018-04-25 02:12:43 +02:00
if ( $results [ 'type' ] !== 'r' ) {
2018-01-21 18:39:47 +01:00
return ;
}
2016-04-28 21:35:33 +02:00
2018-02-14 06:07:26 +01:00
$sql_extra = '' ;
2018-04-25 02:12:43 +02:00
if ( $results [ 'search' ]) {
2018-11-08 16:30:45 +01:00
$search_txt = DBA :: escape ( Strings :: protectSprintf ( preg_quote ( $results [ 'search' ])));
2018-07-21 15:10:13 +02:00
$sql_extra .= " AND (`attag` LIKE '%% " . $search_txt . " %%' OR `name` LIKE '%% " . $search_txt . " %%' OR `nick` LIKE '%% " . $search_txt . " %%') " ;
2018-01-21 18:39:47 +01:00
}
2016-04-28 21:35:33 +02:00
2018-01-21 18:39:47 +01:00
if ( $nets ) {
2018-07-21 15:10:13 +02:00
$sql_extra .= sprintf ( " AND network = '%s' " , DBA :: escape ( $nets ));
2018-01-21 18:39:47 +01:00
}
2016-04-28 21:35:33 +02:00
2018-02-14 06:07:26 +01:00
$total = 0 ;
2018-01-21 18:39:47 +01:00
$r = q ( " SELECT COUNT(*) AS `total` FROM `contact`
2019-01-12 14:28:14 +01:00
WHERE `uid` = % d AND NOT `self` AND NOT `deleted` AND NOT `pending` $sql_extra " , intval( $_SESSION['uid'] ));
2018-07-21 14:46:04 +02:00
if ( DBA :: isResult ( $r )) {
2018-04-25 02:12:43 +02:00
$total = $r [ 0 ][ 'total' ];
2018-01-21 18:39:47 +01:00
}
2016-04-28 21:35:33 +02:00
2018-01-21 18:39:47 +01:00
$sql_extra3 = Widget :: unavailableNetworks ();
2016-04-28 21:35:33 +02:00
2019-01-12 14:28:14 +01:00
$r = q ( " SELECT * FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `pending` $sql_extra $sql_extra3 ORDER BY `name` ASC LIMIT %d, %d " ,
2018-01-21 18:39:47 +01:00
intval ( $_SESSION [ 'uid' ]), intval ( $results [ 'start' ]), intval ( $results [ 'count' ])
);
2016-04-28 21:35:33 +02:00
2018-01-21 18:39:47 +01:00
$contacts = [];
2016-04-28 21:35:33 +02:00
2018-07-21 14:46:04 +02:00
if ( DBA :: isResult ( $r )) {
2018-01-21 18:39:47 +01:00
foreach ( $r as $rr ) {
2018-10-14 20:03:22 +02:00
$contacts [] = Module\Contact :: getContactTemplateVars ( $rr );
2018-01-21 18:39:47 +01:00
}
2016-04-28 21:35:33 +02:00
}
2018-01-21 18:39:47 +01:00
2018-04-25 02:12:43 +02:00
$results [ 'items' ] = $contacts ;
$results [ 'tot' ] = $total ;
2016-06-25 12:21:13 +02:00
}
2017-08-02 15:52:11 +02:00
/**
2020-01-19 07:05:23 +01:00
* Manipulate the data of the item
2018-01-01 21:05:09 +01:00
*
2017-08-02 15:52:11 +02:00
* At the moment we use this function to add some own stuff to the item menu
2018-01-01 21:05:09 +01:00
*
2017-08-02 15:52:11 +02:00
* @ param App $a App $a The app data
* @ param array $arr Array with the item and the item actions < br >
* 'item' => Array with item data < br >
* 'output' => Array with item actions < br >
*/
2018-01-01 21:05:09 +01:00
function frio_display_item ( App $a , & $arr )
{
2021-01-30 21:51:27 +01:00
// Add follow to the item menu
$followThread = [];
2018-06-19 18:27:54 +02:00
if (
local_user ()
&& local_user () == $arr [ 'item' ][ 'uid' ]
2020-05-28 18:02:36 +02:00
&& $arr [ 'item' ][ 'gravity' ] == GRAVITY_PARENT
2018-06-19 18:27:54 +02:00
&& ! $arr [ 'item' ][ 'self' ])
{
2021-01-30 21:51:27 +01:00
$followThread = [
2017-08-02 15:52:11 +02:00
'menu' => 'follow_thread' ,
2020-01-18 20:52:34 +01:00
'title' => DI :: l10n () -> t ( 'Follow Thread' ),
2021-01-30 21:51:27 +01:00
'action' => 'doFollowThread(' . $arr [ 'item' ][ 'id' ] . ');' ,
2017-08-02 15:52:11 +02:00
'href' => '#'
2018-01-15 14:05:12 +01:00
];
2017-08-02 15:52:11 +02:00
}
2021-01-30 21:51:27 +01:00
$arr [ 'output' ][ 'follow_thread' ] = $followThread ;
2017-08-02 15:52:11 +02:00
}