2016-03-28 14:29:05 +00:00
< ? php
2018-01-01 20:05:09 +00:00
2016-03-28 14:29:05 +00:00
/*
* Name : frio
2016-06-13 08:57:42 +00: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 >.
2017-05-19 11:11:30 +00:00
* Version : V . 0.8
2016-03-28 14:29:05 +00:00
* Author : Rabuzarus < https :// friendica . kommune4 . de / profile / rabuzarus >
2017-01-09 12:06:08 +00:00
*
2016-03-28 14:29:05 +00:00
*/
2017-04-30 04:07:00 +00:00
use Friendica\App ;
2017-11-07 02:22:52 +00:00
use Friendica\Core\Config ;
use Friendica\Core\PConfig ;
2017-08-26 06:04:21 +00:00
use Friendica\Core\System ;
2017-11-08 03:57:46 +00:00
use Friendica\Database\DBM ;
2017-12-07 13:56:11 +00:00
use Friendica\Object\Image ;
2017-04-30 04:07:00 +00:00
2016-03-28 14:29:05 +00:00
$frio = " view/theme/frio " ;
global $frio ;
2018-01-01 20:05:09 +00:00
function frio_init ( App $a )
{
2016-06-20 11:44:11 +00:00
// disable the events module link in the profile tab
$a -> theme_events_in_profile = false ;
2018-01-09 04:52:54 +00:00
$a -> videowidth = 622 ;
2016-06-20 11:44:11 +00:00
2017-11-11 09:26:23 +00:00
$a -> set_template_engine ( 'smarty3' );
2016-03-28 14:29:05 +00:00
2017-08-26 07:32:10 +00:00
$baseurl = System :: baseUrl ();
2016-03-28 14:29:05 +00:00
2017-11-07 02:22:52 +00:00
$style = PConfig :: get ( local_user (), 'frio' , 'style' );
2016-03-28 14:29:05 +00:00
$frio = " view/theme/frio " ;
global $frio ;
2016-05-28 11:07:24 +00:00
// if the device is a mobile device set js is_mobile
// variable so the js scripts can use this information
2018-01-01 20:05:09 +00:00
if ( $a -> is_mobile || $a -> is_tablet ) {
2016-05-28 11:07:24 +00:00
$a -> page [ " htmlhead " ] .= <<< EOT
2017-10-20 13:21:42 +00:00
< script type = " text/javascript " >
2016-05-28 11:07:24 +00:00
var is_mobile = 1 ;
</ script >
EOT ;
2018-01-01 20:05:09 +00:00
}
2016-03-28 14:29:05 +00:00
2018-01-01 20:05:09 +00:00
if ( $style == " " ) {
2017-11-07 02:22:52 +00:00
$style = Config :: get ( 'frio' , 'style' );
2018-01-01 20:05:09 +00:00
}
2016-03-28 14:29:05 +00:00
}
2018-01-01 20:05:09 +00:00
function frio_install ()
{
2016-04-14 12:07:20 +00:00
register_hook ( 'prepare_body_final' , 'view/theme/frio/theme.php' , 'frio_item_photo_links' );
2016-04-16 22:55:43 +00:00
register_hook ( 'item_photo_menu' , 'view/theme/frio/theme.php' , 'frio_item_photo_menu' );
2016-04-20 17:32:19 +00:00
register_hook ( 'contact_photo_menu' , 'view/theme/frio/theme.php' , 'frio_contact_photo_menu' );
2016-04-19 00:06:02 +00:00
register_hook ( 'nav_info' , 'view/theme/frio/theme.php' , 'frio_remote_nav' );
2016-04-28 19:35:33 +00:00
register_hook ( 'acl_lookup_end' , 'view/theme/frio/theme.php' , 'frio_acl_lookup' );
2017-08-02 13:52:11 +00:00
register_hook ( 'display_item' , 'view/theme/frio/theme.php' , 'frio_display_item' );
2016-03-28 14:29:05 +00:00
logger ( " installed theme frio " );
}
2018-01-01 20:05:09 +00:00
function frio_uninstall ()
{
2016-04-14 12:07:20 +00:00
unregister_hook ( 'prepare_body_final' , 'view/theme/frio/theme.php' , 'frio_item_photo_links' );
2016-04-16 22:55:43 +00:00
unregister_hook ( 'item_photo_menu' , 'view/theme/frio/theme.php' , 'frio_item_photo_menu' );
2016-04-28 19:35:33 +00:00
unregister_hook ( 'contact_photo_menu' , 'view/theme/frio/theme.php' , 'frio_contact_photo_menu' );
2016-04-20 17:32:19 +00:00
unregister_hook ( 'nav_info' , 'view/theme/frio/theme.php' , 'frio_remote_nav' );
2016-04-28 19:35:33 +00:00
unregister_hook ( 'acl_lookup_end' , 'view/theme/frio/theme.php' , 'frio_acl_lookup' );
2017-08-02 13:52:11 +00:00
unregister_hook ( 'display_item' , 'view/theme/frio/theme.php' , 'frio_display_item' );
2016-03-28 14:29:05 +00:00
logger ( " uninstalled theme frio " );
}
2018-01-01 20:05:09 +00:00
2016-04-14 12:07:20 +00:00
/**
2017-01-09 12:06:08 +00:00
* @ brief Replace friendica photo links hook
*
2016-04-14 12:07:20 +00: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 12:06:08 +00:00
*
* @ param App $a Unused but required by hook definition
2016-04-14 12:07:20 +00:00
* @ param array $body_info The item and its html output
*/
2017-11-29 12:52:27 +00:00
function frio_item_photo_links ( App $a , & $body_info )
{
2017-12-07 13:56:11 +00:00
$phototypes = Image :: supportedTypes ();
2016-04-14 12:07:20 +00:00
$occurence = 1 ;
$p = bb_find_open_close ( $body_info [ 'html' ], " <a " , " > " );
2018-01-01 20:05:09 +00:00
while ( $p !== false && ( $occurence ++ < 500 )) {
2016-04-14 12:07:20 +00:00
$link = substr ( $body_info [ 'html' ], $p [ 'start' ], $p [ 'end' ] - $p [ 'start' ]);
$matches = array ();
preg_match ( " / \ /photos \ /[ \ w]+ \ /image \ /([ \ w]+)/ " , $link , $matches );
2018-01-01 20:05:09 +00:00
if ( $matches ) {
2016-04-14 12:07:20 +00: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
$newlink = preg_replace ( " /href= \" ([^ \" ]+) \ /redir \ /([^ \" ]+)&url=([^ \" ]+) \" / " , 'href="$1/redir/$2&quiet=1&url=$3"' , $newlink );
2018-01-01 20:05:09 +00:00
// Having any arguments to the link for Colorbox causes it to fetch base64 code instead of the image
2016-04-14 12:07:20 +00:00
$newlink = preg_replace ( " / \ /[?&]zrl=([^& \" ]+)/ " , '' , $newlink );
$body_info [ 'html' ] = str_replace ( $link , $newlink , $body_info [ 'html' ]);
}
$p = bb_find_open_close ( $body_info [ 'html' ], " <a " , " > " , $occurence );
}
}
2016-04-16 22:55:43 +00:00
/**
2017-01-09 12:06:08 +00:00
* @ brief Replace links of the item_photo_menu hook
*
2016-04-16 22:55:43 +00: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 12:06:08 +00:00
*
* @ param App $a Unused but required by the hook definition
2016-04-16 22:55:43 +00:00
* @ param array $arr Contains item data and the original photo_menu
*/
2018-01-01 20:05:09 +00:00
function frio_item_photo_menu ( App $a , & $arr )
{
foreach ( $arr [ " menu " ] as $k => $v ) {
if ( strpos ( $v , 'poke/?f=&c=' ) === 0 || strpos ( $v , 'message/new/' ) === 0 ) {
2016-04-16 22:55:43 +00:00
$v = " javascript:addToModal(' " . $v . " '); return false; " ;
$arr [ " menu " ][ $k ] = $v ;
}
}
}
2016-04-19 00:06:02 +00:00
2016-04-20 17:32:19 +00:00
/**
* @ brief Replace links of the contact_photo_menu
2017-01-09 12:06:08 +00:00
*
2016-04-20 17:32:19 +00: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 17:59:44 +00: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 12:06:08 +00:00
*
2017-04-30 04:17:49 +00:00
* @ param App $a The app data
2016-04-20 17:32:19 +00:00
* @ param array $args Contains contact data and the original photo_menu
*/
2018-01-01 20:05:09 +00:00
function frio_contact_photo_menu ( App $a , & $args )
{
2016-04-20 17:32:19 +00:00
$cid = $args [ " contact " ][ " id " ];
$pokelink = $args [ " menu " ][ " poke " ][ 1 ];
$pmlink = $args [ " menu " ][ " pm " ][ 1 ];
2016-04-20 17:59:44 +00: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 12:06:08 +00:00
// The value for opening in a new tab is e.g. when
2016-04-20 17:59:44 +00:00
// $args["menu"]["status"][2] is true. If the value of the [2] key is true
// and if it's a friendica contact we set it to false
2018-01-01 20:05:09 +00:00
foreach ( $args [ " menu " ] as $k => $v ) {
if ( $k === " status " || $k === " profile " || $k === " photos " ) {
2016-04-20 17:59:44 +00:00
$v [ 2 ] = (( $args [ " contact " ][ " network " ] === " dfrn " ) ? false : true );
$args [ " menu " ][ $k ][ 2 ] = $v [ 2 ];
}
}
2016-04-20 17:32:19 +00: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)
2018-01-01 20:05:09 +00:00
if ( strpos ( $pokelink , 'poke/?f=&c=' . $cid ) !== false ) {
2016-04-20 17:32:19 +00:00
$args [ " menu " ][ " poke " ][ 3 ] = " modal " ;
2018-01-01 20:05:09 +00:00
}
2016-04-20 17:32:19 +00:00
2018-01-01 20:05:09 +00:00
if ( strpos ( $pmlink , 'message/new/' . $cid ) !== false ) {
2016-04-20 17:32:19 +00:00
$args [ " menu " ][ " pm " ][ 3 ] = " modal " ;
2018-01-01 20:05:09 +00:00
}
2016-04-20 17:32:19 +00:00
}
2016-04-19 00:06:02 +00:00
/**
* @ brief Construct remote nav menu
2017-01-09 12:06:08 +00:00
*
2016-04-19 00:06:02 +00:00
* It creates a remote baseurl form $_SESSION for remote users and friendica
2017-01-09 12:06:08 +00:00
* visitors . This url will be added to some of the nav links . With this behaviour
2016-04-19 00:06:02 +00: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 12:06:08 +00:00
*
2017-04-30 04:17:49 +00:00
* @ param App $a The App class
2016-04-19 00:06:02 +00:00
* @ param array $nav The original nav menu
*/
2018-01-01 20:05:09 +00:00
function frio_remote_nav ( $a , & $nav )
{
2016-04-19 00:06:02 +00:00
// get the homelink from $_XSESSION
$homelink = get_my_url ();
2018-01-01 20:05:09 +00:00
if ( ! $homelink ) {
$homelink = defaults ( $_SESSION , 'visitor_home' , '' );
}
2016-04-19 00:06:02 +00:00
// split up the url in it's parts (protocol,domain/directory, /profile/, nickname
// I'm not familiar with regex, so someone might find a better solutionen
2017-01-09 12:06:08 +00:00
//
2016-04-19 00:06:02 +00:00
// E.g $homelink = 'https://friendica.domain.com/profile/mickey' should result in an array
// with 0 => 'https://friendica.domain.com/profile/mickey' 1 => 'https://',
// 2 => 'friendica.domain.com' 3 => '/profile/' 4 => 'mickey'
2017-01-09 12:06:08 +00:00
//
2016-04-19 00:06:02 +00:00
//$server_url = preg_match('/^(https?:\/\/.*?)\/profile\//2', $homelink);
preg_match ( '/^(https?:\/\/)?(.*?)(\/profile\/)(.*)/' , $homelink , $url_parts );
// Construct the server url of the visitor. So we could link back to his/her own menu.
// And construct a webbie (e.g. mickey@friendica.domain.com for the search in gcontact
// We use the webbie for search in gcontact because we don't know if gcontact table stores
// the right value if its http or https protocol
2018-01-01 20:05:09 +00:00
if ( count ( $url_parts )) {
2016-04-19 00:06:02 +00:00
$server_url = $url_parts [ 1 ] . $url_parts [ 2 ];
$webbie = $url_parts [ 4 ] . '@' . $url_parts [ 2 ];
}
// 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
2017-08-03 05:50:44 +00:00
if ( local_user ()) {
2016-04-19 00:06:02 +00:00
// empty the server url for local user because we won't need it
$server_url = '' ;
// user info
2017-01-09 09:37:37 +00:00
$r = q ( " SELECT `micro` FROM `contact` WHERE `uid` = %d AND `self` " , intval ( $a -> user [ 'uid' ]));
2017-01-09 12:06:08 +00:00
2017-11-08 03:57:46 +00:00
$r [ 0 ][ 'photo' ] = ( DBM :: is_result ( $r ) ? $a -> remove_baseurl ( $r [ 0 ][ 'micro' ]) : " images/person-48.jpg " );
2016-04-19 00:06:02 +00:00
$r [ 0 ][ 'name' ] = $a -> user [ 'username' ];
2017-08-03 05:50:44 +00:00
} elseif ( ! local_user () && remote_user ()) {
2016-04-19 00:06:02 +00:00
$r = q ( " SELECT `name`, `nick`, `micro` AS `photo` FROM `contact` WHERE `id` = %d " , intval ( remote_user ()));
2016-08-09 12:39:18 +00:00
$nav [ 'remote' ] = t ( " Guest " );
2017-08-03 05:50:44 +00:00
} elseif ( get_my_url ()) {
2016-04-19 00:06:02 +00:00
$r = q ( " SELECT `name`, `nick`, `photo` FROM `gcontact`
WHERE `addr` = '%s' AND `network` = 'dfrn' " ,
dbesc ( $webbie ));
2016-04-20 16:03:22 +00:00
$nav [ 'remote' ] = t ( " Visitor " );
2017-08-03 05:50:44 +00:00
} else {
$r = false ;
2016-04-19 00:06:02 +00:00
}
2017-11-08 03:57:46 +00:00
if ( DBM :: is_result ( $r )) {
2018-01-01 20:05:09 +00:00
$nav [ 'userinfo' ] = array (
'icon' => ( DBM :: is_result ( $r ) ? $r [ 0 ][ 'photo' ] : " images/person-48.jpg " ),
'name' => $r [ 0 ][ 'name' ],
);
}
2016-04-19 00:06:02 +00:00
2017-08-03 05:50:44 +00:00
if ( ! local_user () && ! empty ( $server_url )) {
2017-04-08 14:57:24 +00:00
$nav [ 'logout' ] = Array ( $server_url . '/logout' , t ( 'Logout' ), " " , t ( 'End this session' ));
2016-04-19 00:06:02 +00:00
// user menu
$nav [ 'usermenu' ][] = Array ( $server_url . '/profile/' . $a -> user [ 'nickname' ], t ( 'Status' ), " " , t ( 'Your posts and conversations' ));
2018-01-01 20:05:09 +00:00
$nav [ 'usermenu' ][] = Array ( $server_url . '/profile/' . $a -> user [ 'nickname' ] . '?tab=profile' , t ( 'Profile' ), " " , t ( 'Your profile page' ));
2016-04-19 00:06:02 +00:00
$nav [ 'usermenu' ][] = Array ( $server_url . '/photos/' . $a -> user [ 'nickname' ], t ( 'Photos' ), " " , t ( 'Your photos' ));
$nav [ 'usermenu' ][] = Array ( $server_url . '/videos/' . $a -> user [ 'nickname' ], t ( 'Videos' ), " " , t ( 'Your videos' ));
$nav [ 'usermenu' ][] = Array ( $server_url . '/events/' , t ( 'Events' ), " " , t ( 'Your events' ));
// navbar links
$nav [ 'network' ] = array ( $server_url . '/network' , t ( 'Network' ), " " , t ( 'Conversations from your friends' ));
$nav [ 'events' ] = Array ( $server_url . '/events' , t ( 'Events' ), " " , t ( 'Events and Calendar' ));
$nav [ 'messages' ] = array ( $server_url . '/message' , t ( 'Messages' ), " " , t ( 'Private mail' ));
2018-01-01 20:05:09 +00:00
$nav [ 'settings' ] = array ( $server_url . '/settings' , t ( 'Settings' ), " " , t ( 'Account settings' ));
$nav [ 'contacts' ] = array ( $server_url . '/contacts' , t ( 'Contacts' ), " " , t ( 'Manage/edit friends and contacts' ));
2016-04-20 16:03:22 +00:00
$nav [ 'sitename' ] = $a -> config [ 'sitename' ];
2016-04-19 00:06:02 +00:00
}
}
2018-01-01 20:05:09 +00:00
2016-04-28 19:35:33 +00:00
/**
* @ brief : Search for contacts
2017-01-09 12:06:08 +00:00
*
2016-04-28 19:35:33 +00:00
* This function search for a users contacts . The code is copied from contact search
* in / mod / contacts . php . With this function the contacts will permitted to acl_lookup ()
2017-01-09 12:06:08 +00:00
* and can grabbed as json . For this we use the type = " r " . This is usful to to let js
2016-04-28 19:35:33 +00: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 12:06:08 +00:00
*
2016-12-20 20:16:01 +00:00
* @ param App $a The app data @ TODO Unused
2016-04-28 19:35:33 +00:00
* @ param array $results The array with the originals from acl_lookup ()
*/
2018-01-01 20:05:09 +00:00
function frio_acl_lookup ( App $a , & $results )
{
require_once 'mod/contacts.php' ;
2016-04-28 19:35:33 +00:00
2018-01-01 20:05:09 +00:00
$nets = x ( $_GET , " nets " ) ? notags ( trim ( $_GET [ " nets " ])) : " " ;
2016-04-28 19:35:33 +00:00
// we introduce a new search type, r should do the same query like it's
// done in /mod/contacts for connections
2016-12-20 20:16:01 +00:00
if ( $results [ " type " ] == " r " ) {
2016-04-28 19:35:33 +00:00
$searching = false ;
2016-12-20 20:16:01 +00:00
if ( $search ) {
2016-04-28 19:35:33 +00:00
$search_hdr = $search ;
$search_txt = dbesc ( protect_sprintf ( preg_quote ( $search )));
$searching = true ;
}
2018-01-01 20:05:09 +00:00
$sql_extra = '' ;
if ( $searching ) {
$sql_extra .= " AND (`attag` LIKE '%% " . dbesc ( $search_txt ) . " %%' OR `name` LIKE '%% " . dbesc ( $search_txt ) . " %%' OR `nick` LIKE '%% " . dbesc ( $search_txt ) . " %%') " ;
}
2016-04-28 19:35:33 +00:00
2016-12-20 20:16:01 +00:00
if ( $nets ) {
2016-04-28 19:35:33 +00:00
$sql_extra .= sprintf ( " AND network = '%s' " , dbesc ( $nets ));
2016-12-20 20:16:01 +00:00
}
2016-04-28 19:35:33 +00:00
$r = q ( " SELECT COUNT(*) AS `total` FROM `contact`
2018-01-01 20:05:09 +00:00
WHERE `uid` = % d AND NOT `self` AND NOT `pending` $sql_extra " ,
2016-04-28 19:35:33 +00:00
intval ( $_SESSION [ 'uid' ]));
2017-11-08 03:57:46 +00:00
if ( DBM :: is_result ( $r )) {
2016-04-28 19:35:33 +00:00
$total = $r [ 0 ][ " total " ];
}
$sql_extra3 = unavailable_networks ();
2018-01-01 20:05:09 +00:00
$r = q ( " SELECT * FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `pending` $sql_extra $sql_extra3 ORDER BY `name` ASC LIMIT 100 " ,
2016-04-28 19:35:33 +00:00
intval ( $_SESSION [ 'uid' ])
);
$contacts = array ();
2017-11-08 03:57:46 +00:00
if ( DBM :: is_result ( $r )) {
2016-12-20 20:16:01 +00:00
foreach ( $r as $rr ) {
2016-04-28 19:35:33 +00:00
$contacts [] = _contact_detail_for_template ( $rr );
}
}
$results [ " items " ] = $contacts ;
$results [ " tot " ] = $total ;
}
2016-06-25 10:21:13 +00:00
}
2017-08-02 13:52:11 +00:00
/**
* @ brief Manipulate the data of the item
2018-01-01 20:05:09 +00:00
*
2017-08-02 13:52:11 +00:00
* At the moment we use this function to add some own stuff to the item menu
2018-01-01 20:05:09 +00:00
*
2017-08-02 13:52:11 +00: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 20:05:09 +00:00
function frio_display_item ( App $a , & $arr )
{
2017-08-02 13:52:11 +00:00
// Add subthread to the item menu
$subthread = array ();
2018-01-01 20:05:09 +00:00
if ( local_user () == $arr [ 'item' ][ 'uid' ] && $arr [ 'item' ][ 'parent' ] == $arr [ 'item' ][ 'id' ] && ! $arr [ 'item' ][ 'self' ]) {
2017-08-02 13:52:11 +00:00
$subthread = array (
'menu' => 'follow_thread' ,
'title' => t ( 'Follow Thread' ),
'action' => 'dosubthread(' . $arr [ 'item' ][ 'id' ] . '); return false;' ,
'href' => '#'
);
}
$arr [ 'output' ][ 'subthread' ] = $subthread ;
}