diff options
-rwxr-xr-x | boot.php | 2 | ||||
-rw-r--r-- | include/RedDAV/RedBrowser.php | 98 | ||||
-rwxr-xr-x | include/diaspora.php | 10 | ||||
-rw-r--r-- | include/enotify.php | 1 | ||||
-rwxr-xr-x | include/items.php | 107 | ||||
-rw-r--r-- | include/onepoll.php | 2 | ||||
-rw-r--r-- | include/poller.php | 2 | ||||
-rw-r--r-- | include/socgraph.php | 223 | ||||
-rw-r--r-- | include/text.php | 71 | ||||
-rw-r--r-- | include/zot.php | 76 | ||||
-rw-r--r-- | install/schema_mysql.sql | 4 | ||||
-rw-r--r-- | install/schema_postgres.sql | 2 | ||||
-rw-r--r-- | install/update.php | 13 | ||||
-rw-r--r-- | mod/acl.php | 10 | ||||
-rw-r--r-- | mod/directory.php | 14 | ||||
-rw-r--r-- | mod/help.php | 20 | ||||
-rw-r--r-- | mod/poco.php | 211 | ||||
-rw-r--r-- | mod/search.php | 17 | ||||
-rw-r--r-- | mod/share.php | 2 | ||||
-rw-r--r-- | mod/sharedwithme.php | 38 | ||||
-rw-r--r-- | mod/xpoco.php | 7 | ||||
-rw-r--r-- | version.inc | 2 | ||||
-rw-r--r-- | view/css/conversation.css | 4 | ||||
-rw-r--r-- | view/css/mod_sharedwithme.css | 24 | ||||
-rw-r--r-- | view/de/lostpass_eml.tpl | 6 | ||||
-rw-r--r-- | view/tpl/cloud_header.tpl | 2 | ||||
-rw-r--r-- | view/tpl/sharedwithme.tpl | 24 |
27 files changed, 604 insertions, 388 deletions
@@ -49,7 +49,7 @@ define ( 'RED_PLATFORM', 'redmatrix' ); define ( 'RED_VERSION', trim(file_get_contents('version.inc')) . 'R'); define ( 'ZOT_REVISION', 1 ); -define ( 'DB_UPDATE_VERSION', 1134 ); +define ( 'DB_UPDATE_VERSION', 1135 ); /** * Constant with a HTML line break. diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php index 5642c3f86..8093aebc9 100644 --- a/include/RedDAV/RedBrowser.php +++ b/include/RedDAV/RedBrowser.php @@ -82,7 +82,7 @@ class RedBrowser extends DAV\Browser\Plugin { date_default_timezone_set($this->auth->getTimezone()); require_once('include/conversation.php'); - + require_once('include/text.php'); if ($this->auth->owner_nick) { $html = profile_tabs(get_app(), (($is_owner) ? true : false), $this->auth->owner_nick); } @@ -208,9 +208,9 @@ class RedBrowser extends DAV\Browser\Plugin { $ft['displayName'] = $displayName; $ft['type'] = $type; $ft['size'] = $size; - $ft['sizeFormatted'] = $this->userReadableSize($size); + $ft['sizeFormatted'] = userReadableSize($size); $ft['lastmodified'] = (($lastmodified) ? datetime_convert('UTC', date_default_timezone_get(), $lastmodified) : ''); - $ft['iconFromType'] = $this->getIconFromType($type); + $ft['iconFromType'] = getIconFromType($type); $f[] = $ft; } @@ -224,13 +224,13 @@ class RedBrowser extends DAV\Browser\Plugin { if ($used) { $quotaDesc = t('%1$s used'); $quotaDesc = sprintf($quotaDesc, - $this->userReadableSize($used)); + userReadableSize($used)); } if ($limit && $used) { $quotaDesc = t('%1$s used of %2$s (%3$s%)'); $quotaDesc = sprintf($quotaDesc, - $this->userReadableSize($used), - $this->userReadableSize($limit), + userReadableSize($used), + userReadableSize($limit), round($used / $limit, 1)); } @@ -252,7 +252,8 @@ class RedBrowser extends DAV\Browser\Plugin { '$actionspanel' => $output, '$shared' => t('Shared'), '$create' => t('Create'), - 'upload' => t('Upload') + '$upload' => t('Upload'), + '$is_owner' => $is_owner )); $html .= replace_macros(get_markup_template('cloud_directory.tpl'), array( @@ -283,29 +284,6 @@ class RedBrowser extends DAV\Browser\Plugin { } /** - * @brief Returns a human readable formatted string for filesizes. - * - * Don't we need such a functionality in other places, too? - * - * @param int $size filesize in bytes - * @return string - */ - function userReadableSize($size) { - $ret = ""; - if (is_numeric($size)) { - $incr = 0; - $k = 1024; - $unit = array('bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); - while (($size / $k) >= 1){ - $incr++; - $size = round($size / $k, 2); - } - $ret = $size . " " . $unit[$incr]; - } - return $ret; - } - - /** * @brief Creates a form to add new folders and upload files. * * @param \Sabre\DAV\INode $node @@ -340,65 +318,6 @@ class RedBrowser extends DAV\Browser\Plugin { } /** - * @brief returns icon name for use with e.g. font-awesome based on mime-type - * - * @param string $type - * @return string - */ - protected function getIconFromType($type) { - $iconMap = array( - //Folder - t('Collection') => 'icon-folder-close', - - //Common file - 'application/octet-stream' => 'icon-file-alt', - - //Text - 'text/plain' => 'icon-file-text-alt', - 'application/msword' => 'icon-file-text-alt', - 'application/pdf' => 'icon-file-text-alt', - 'application/vnd.oasis.opendocument.text' => 'icon-file-text-alt', - 'application/epub+zip' => 'icon-book', - - //Spreadsheet - 'application/vnd.oasis.opendocument.spreadsheet' => 'icon-table', - 'application/vnd.ms-excel' => 'icon-table', - - //Image - 'image/jpeg' => 'icon-picture', - 'image/png' => 'icon-picture', - 'image/gif' => 'icon-picture', - 'image/svg+xml' => 'icon-picture', - - //Archive - 'application/zip' => 'icon-archive', - 'application/x-rar-compressed' => 'icon-archive', - - //Audio - 'audio/mpeg' => 'icon-music', - 'audio/wav' => 'icon-music', - 'application/ogg' => 'icon-music', - 'audio/ogg' => 'icon-music', - 'audio/webm' => 'icon-music', - 'audio/mp4' => 'icon-music', - - //Video - 'video/quicktime' => 'icon-film', - 'video/webm' => 'icon-film', - 'video/mp4' => 'icon-film' - ); - - $iconFromType = 'icon-file-alt'; - - if (array_key_exists($type, $iconMap)) - { - $iconFromType = $iconMap[$type]; - } - - return $iconFromType; - } - - /** * @brief Return the hash of an attachment. * * Given the owner, the parent folder and and attach name get the attachment @@ -412,6 +331,7 @@ class RedBrowser extends DAV\Browser\Plugin { * The name of the attachment * @return string */ + protected function findAttachHash($owner, $parentHash, $attachName) { $r = q("SELECT hash FROM attach WHERE uid = %d AND folder = '%s' AND filename = '%s' ORDER BY edited DESC LIMIT 1", intval($owner), diff --git a/include/diaspora.php b/include/diaspora.php index e494aac0f..767758164 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -15,8 +15,14 @@ function diaspora_dispatch_public($msg) { return; } - // find everybody following or allowing this author + $sys_disabled = true; + + if(! get_config('system','disable_discover_tab')) { + $sys_disabled = get_config('system','disable_diaspora_discover_tab'); + } + $sys = (($sys_disabled) ? null : get_sys_channel()); + // find everybody following or allowing this author $r = q("SELECT * from channel where channel_id in ( SELECT abook_channel from abook left join xchan on abook_xchan = xchan_hash WHERE xchan_network like '%%diaspora%%' and xchan_addr = '%s' )", dbesc($msg['author']) @@ -29,6 +35,8 @@ function diaspora_dispatch_public($msg) { logger('diaspora_public: delivering to: ' . $rr['channel_name'] . ' (' . $rr['channel_address'] . ') '); diaspora_dispatch($rr,$msg); } + if($sys) + diaspora_dispatch($sys,$msg); } else logger('diaspora_public: no subscribers'); diff --git a/include/enotify.php b/include/enotify.php index 6fc771c58..36d457c10 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -333,6 +333,7 @@ function notification($params) { $datarray = array(); $datarray['hash'] = $hash; + $datarray['sender_hash'] = $sender['xchan_hash']; $datarray['name'] = $sender['xchan_name']; $datarray['url'] = $sender['xchan_url']; $datarray['photo'] = $sender['xchan_photo_s']; diff --git a/include/items.php b/include/items.php index fb2f2586a..756625d85 100755 --- a/include/items.php +++ b/include/items.php @@ -2186,6 +2186,20 @@ function item_store($arr,$allow_exec = false) { unset($arr['term']); } + if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid) || strlen($public_policy)) + $private = 1; + else + $private = $arr['item_private']; + + $arr['parent'] = $parent_id; + $arr['allow_cid'] = $allow_cid; + $arr['allow_gid'] = $allow_gid; + $arr['deny_cid'] = $deny_cid; + $arr['deny_gid'] = $deny_gid; + $arr['public_policy'] = $public_policy; + $arr['item_private'] = $private; + $arr['comments_closed'] = $comments_closed; + logger('item_store: ' . print_r($arr,true), LOGGER_DATA); dbesc_array($arr); @@ -2203,7 +2217,6 @@ function item_store($arr,$allow_exec = false) { intval($arr['uid']) ); - if($r && count($r)) { $current_post = $r[0]['id']; $arr = $r[0]; // This will gives us a fresh copy of what's now in the DB and undo the db escaping, which really messes up the notifications @@ -2223,40 +2236,14 @@ function item_store($arr,$allow_exec = false) { ); } - if((! $parent_id) || ($arr['parent_mid'] === $arr['mid'])) - $parent_id = $current_post; + $arr['id'] = $current_post; - if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid) || strlen($public_policy)) - $private = 1; - else - $private = $arr['item_private']; - - // Set parent id - and also make sure to inherit the parent's ACL's. - - $r = q("UPDATE item SET parent = %d, allow_cid = '%s', allow_gid = '%s', - deny_cid = '%s', deny_gid = '%s', public_policy = '%s', item_private = %d, comments_closed = '%s' - WHERE id = %d", - intval($parent_id), - dbesc($allow_cid), - dbesc($allow_gid), - dbesc($deny_cid), - dbesc($deny_gid), - dbesc($public_policy), - intval($private), - dbesc($comments_closed), - intval($current_post) - ); + if(! intval($r[0]['parent'])) { + $x = q("update item set parent = id where id = %d", + intval($r[0]['id']) + ); + } - // These are probably redundant now that we've queried the just stored post - $arr['id'] = $current_post; - $arr['parent'] = $parent_id; - $arr['allow_cid'] = $allow_cid; - $arr['allow_gid'] = $allow_gid; - $arr['deny_cid'] = $deny_cid; - $arr['deny_gid'] = $deny_gid; - $arr['public_policy'] = $public_policy; - $arr['item_private'] = $private; - $arr['comments_closed'] = $comments_closed; // Store taxonomy @@ -2865,12 +2852,27 @@ function tag_deliver($uid,$item_id) { if(preg_match($pattern,$body,$matches)) $tagged = true; - $pattern = '/@\!?\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($term['term'] . '+','/') . '\[\/zrl\]/'; - if(preg_match($pattern,$body,$matches)) - $plustagged = true; + $pattern = '/@\!?\[zrl\=(.*?)\](.*?)\+\[\/zrl\]/'; + + if(preg_match_all($pattern,$body,$matches,PREG_SET_ORDER)) { + $max_forums = get_config('system','max_tagged_forums'); + if(! $max_forums) + $max_forums = 2; + $matched_forums = 0; + foreach($matches as $match) { + $matched_forums ++; + if($term['url'] === $match[1] && $term['term'] === $match[2]) { + if($matched_forums <= $max_forums) { + $plustagged = true; + break; + } + logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); + } + } + } if(! ($tagged || $plustagged)) { - logger('tag_deliver: mention was in a reshare - ignoring'); + logger('tag_deliver: mention was in a reshare or exceeded max_tagged_forums - ignoring'); return; } @@ -2987,6 +2989,7 @@ function tgroup_check($uid,$item) { } } + if($mention) { logger('tgroup_check: mention found for ' . $u[0]['channel_name']); } @@ -2995,6 +2998,7 @@ function tgroup_check($uid,$item) { // At this point we've determined that the person receiving this post was mentioned in it. // Now let's check if this mention was inside a reshare so we don't spam a forum + // note: $term has been set to the matching term $body = $item['body']; @@ -3006,14 +3010,35 @@ function tgroup_check($uid,$item) { $body = preg_replace('/\[share(.*?)\[\/share\]/','',$body); - $pattern = '/@\!?\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($term['term'] . '+','/') . '\[\/zrl\]/'; + +// $pattern = '/@\!?\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($term['term'] . '+','/') . '\[\/zrl\]/'; + + $pattern = '/@\!?\[zrl\=(.*?)\](.*?)\+\[\/zrl\]/'; + + $found = false; + + if(preg_match_all($pattern,$body,$matches,PREG_SET_ORDER)) { + $max_forums = get_config('system','max_tagged_forums'); + if(! $max_forums) + $max_forums = 2; + $matched_forums = 0; + foreach($matches as $match) { + $matched_forums ++; + if($term['url'] === $match[1] && $term['term'] === $match[2]) { + if($matched_forums <= $max_forums) { + $found = true; + break; + } + logger('forum ' . $term['term'] . ' exceeded max_tagged_forums - ignoring'); + } + } + } - if(! preg_match($pattern,$body,$matches)) { - logger('tgroup_check: mention was in a reshare - ignoring'); + if(! $found) { + logger('tgroup_check: mention was in a reshare or exceeded max_tagged_forums - ignoring'); return false; } - return true; } diff --git a/include/onepoll.php b/include/onepoll.php index 095edd095..ee90fbdb1 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -145,7 +145,7 @@ function onepoll_run($argv, $argc){ if($contact['xchan_connurl']) { $r = q("SELECT xlink_id from xlink - where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s limit 1", + where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1", intval($contact['xchan_hash']), db_utcnow(), db_quoteinterval('1 DAY') ); diff --git a/include/poller.php b/include/poller.php index d78355db1..dc310fe16 100644 --- a/include/poller.php +++ b/include/poller.php @@ -160,7 +160,7 @@ function poller_run($argv, $argc){ // get rid of really old poco records - q("delete from xlink where xlink_updated < %s - INTERVAL %s", + q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ", db_utcnow(), db_quoteinterval('14 DAY') ); diff --git a/include/socgraph.php b/include/socgraph.php index 5aa72f0be..542ec7074 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -186,13 +186,13 @@ function poco_load($xchan = '',$url = null) { $total ++; - $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' limit 1", + $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 0 limit 1", dbesc($xchan), dbesc($hash) ); if(! $r) { - q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_updated ) values ( '%s', '%s', %d, '%s', '%s' ) ", + q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', 0 ) ", dbesc($xchan), dbesc($hash), intval($rating), @@ -211,7 +211,7 @@ function poco_load($xchan = '',$url = null) { } logger("poco_load: loaded $total entries",LOGGER_DEBUG); - q("delete from xlink where xlink_xchan = '%s' and xlink_updated < %s - INTERVAL %s", + q("delete from xlink where xlink_xchan = '%s' and xlink_updated < %s - INTERVAL %s and xlink_static = 0", dbesc($xchan), db_utcnow(), db_quoteinterval('2 DAY') ); @@ -222,7 +222,7 @@ function poco_load($xchan = '',$url = null) { function count_common_friends($uid,$xchan) { - $r = q("SELECT count(xlink_id) as total from xlink where xlink_xchan = '%s' and xlink_link in + $r = q("SELECT count(xlink_id) as total from xlink where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_flags = 0 )", dbesc($xchan), dbesc($xchan), @@ -243,7 +243,7 @@ function common_friends($uid,$xchan,$start = 0,$limit=100000000,$shuffle = false else $sql_extra = " order by xchan_name asc "; - $r = q("SELECT * from xchan left join xlink on xlink_link = xchan_hash where xlink_xchan = '%s' and xlink_link in + $r = q("SELECT * from xchan left join xlink on xlink_link = xchan_hash where xlink_xchan = '%s' and xlink_static = 0 and xlink_link in (select abook_xchan from abook where abook_xchan != '%s' and abook_channel = %d and abook_flags = 0 ) $sql_extra limit %d offset %d", dbesc($xchan), dbesc($xchan), @@ -340,6 +340,7 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 80) { and not xlink_link in ( select abook_xchan from abook where abook_channel = %d ) and not xlink_link in ( select xchan from xign where uid = %d ) and xlink_xchan != '' + and xlink_static = 0 and not ( xchan_flags & %d )>0 and not ( xchan_flags & %d )>0 group by xchan_hash order by total desc limit %d offset %d ", @@ -360,6 +361,7 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 80) { where xlink_xchan = '' and not xlink_link in ( select abook_xchan from abook where abook_channel = %d ) and not xlink_link in ( select xchan from xign where uid = %d ) + and xlink_static = 0 and not ( xchan_flags & %d )>0 and not ( xchan_flags & %d )>0 group by xchan_hash order by total desc limit %d offset %d ", @@ -405,7 +407,7 @@ function update_suggestions() { // the targets may have changed their preferences and don't want to be suggested - and they // may have simply gone away. - $r = q("delete from xlink where xlink_xchan = '' and xlink_updated < %s - INTERVAL %s", + $r = q("delete from xlink where xlink_xchan = '' and xlink_updated < %s - INTERVAL %s and xlink_static = 0", db_utcnow(), db_quoteinterval('7 DAY') ); @@ -418,3 +420,212 @@ function update_suggestions() { } } } + + +function poco($a,$extended = false) { + + $system_mode = false; + + if(intval(get_config('system','block_public')) && (! local_user()) && (! remote_user())) { + logger('mod_poco: block_public'); + http_status_exit(401); + } + + $observer = $a->get_observer(); + + if(argc() > 1) { + $user = notags(trim(argv(1))); + } + if(! x($user)) { + $c = q("select * from pconfig where cat = 'system' and k = 'suggestme' and v = '1'"); + if(! $c) { + logger('mod_poco: system mode. No candidates.', LOGGER_DEBUG); + http_status_exit(404); + } + $system_mode = true; + } + + + $format = (($_REQUEST['format']) ? $_REQUEST['format'] : 'json'); + + $justme = false; + + if(argc() > 2 && argv(2) === '@me') + $justme = true; + if(argc() > 3) { + if(argv(3) === '@all') + $justme = false; + elseif(argv(3) === '@self') + $justme = true; + } + if(argc() > 4 && intval(argv(4)) && $justme == false) + $cid = intval(argv(4)); + + if(! $system_mode) { + + $r = q("SELECT channel_id from channel where channel_address = '%s' limit 1", + dbesc($user) + ); + if(! $r) { + logger('mod_poco: user mode. Account not found. ' . $user); + http_status_exit(404); + } + + $channel_id = $r[0]['channel_id']; + $ohash = (($observer) ? $observer['xchan_hash'] : ''); + + if(! perm_is_allowed($channel_id,$ohash,'view_contacts')) { + logger('mod_poco: user mode. Permission denied for ' . $ohash . ' user: ' . $user); + http_status_exit(401); + } + + } + + if($justme) + $sql_extra = " and ( abook_flags & " . ABOOK_FLAG_SELF . " )>0 "; + else + $sql_extra = " and abook_flags = 0 "; + + if($cid) + $sql_extra = sprintf(" and abook_id = %d ",intval($cid)); + + if($system_mode) { + $r = q("SELECT count(*) as `total` from abook where ( abook_flags & " . ABOOK_FLAG_SELF . + " )>0 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') "); + } + else { + $r = q("SELECT count(*) as `total` from abook where abook_channel = %d + $sql_extra ", + intval($channel_id) + ); + $rooms = q("select * from menu_item where ( mitem_flags & " . intval(MENU_ITEM_CHATROOM) . " )>0 and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = '' and mitem_channel_id = %d", + intval($channel_id) + ); + } + if($r) + $totalResults = intval($r[0]['total']); + else + $totalResults = 0; + + $startIndex = intval($_GET['startIndex']); + if(! $startIndex) + $startIndex = 0; + $itemsPerPage = ((x($_GET,'count') && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults); + + + if($system_mode) { + $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where ( abook_flags & " . ABOOK_FLAG_SELF . + " )>0 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') limit %d offset %d ", + intval($itemsPerPage), + intval($startIndex) + ); + } + else { + $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d + $sql_extra LIMIT %d OFFSET %d", + intval($channel_id), + intval($itemsPerPage), + intval($startIndex) + ); + } + + $ret = array(); + if(x($_GET,'sorted')) + $ret['sorted'] = 'false'; + if(x($_GET,'filtered')) + $ret['filtered'] = 'false'; + if(x($_GET,'updatedSince')) + $ret['updateSince'] = 'false'; + + $ret['startIndex'] = (string) $startIndex; + $ret['itemsPerPage'] = (string) $itemsPerPage; + $ret['totalResults'] = (string) $totalResults; + + if($rooms) { + $ret['chatrooms'] = array(); + foreach($rooms as $room) { + $ret['chatrooms'][] = array('url' => $room['mitem_link'], 'desc' => $room['mitem_desc']); + } + } + + $ret['entry'] = array(); + + + $fields_ret = array( + 'id' => false, + 'guid' => false, + 'guid_sig' => false, + 'hash' => false, + 'displayName' => false, + 'urls' => false, + 'preferredUsername' => false, + 'photos' => false, + 'rating' => false + ); + + if((! x($_GET,'fields')) || ($_GET['fields'] === '@all')) + foreach($fields_ret as $k => $v) + $fields_ret[$k] = true; + else { + $fields_req = explode(',',$_GET['fields']); + foreach($fields_req as $f) + $fields_ret[trim($f)] = true; + } + + if(is_array($r)) { + if(count($r)) { + foreach($r as $rr) { + $entry = array(); + if($fields_ret['id']) + $entry['id'] = $rr['abook_id']; + if($fields_ret['guid']) + $entry['guid'] = $rr['xchan_guid']; + if($fields_ret['guid_sig']) + $entry['guid_sig'] = $rr['xchan_guid_sig']; + if($fields_ret['hash']) + $entry['hash'] = $rr['xchan_hash']; + + if($fields_ret['displayName']) + $entry['displayName'] = $rr['xchan_name']; + if($fields_ret['urls']) { + $entry['urls'] = array(array('value' => $rr['xchan_url'], 'type' => 'profile')); + $network = $rr['xchan_network']; + if(strpos($network,'friendica') !== false) + $network = 'friendica'; + if($rr['xchan_addr']) + $entry['urls'][] = array('value' => 'acct:' . $rr['xchan_addr'], 'type' => $network); + } + if($fields_ret['preferredUsername']) + $entry['preferredUsername'] = substr($rr['xchan_addr'],0,strpos($rr['xchan_addr'],'@')); + if($fields_ret['photos']) + $entry['photos'] = array(array('value' => $rr['xchan_photo_l'], 'mimetype' => $rr['xchan_photo_mimetype'], 'type' => 'profile')); + if($fields_ret['rating']) { + $entry['rating'] = ((array_key_exists('abook_rating',$rr)) ? intval($rr['abook_rating']) : 0); + $entry['rating_text'] = ((array_key_exists('abook_rating_text',$rr)) ? $rr['abook_rating_text'] : ''); + // maybe this should be a composite calculated rating in $system_mode + if($system_mode) + $entry['rating'] = 0; + } + $ret['entry'][] = $entry; + } + } + else + $ret['entry'][] = array(); + } + else + http_status_exit(500); + + if($format === 'xml') { + header('Content-type: text/xml'); + echo replace_macros(get_markup_template('poco_xml.tpl'),array_xmlify(array('$response' => $ret))); + http_status_exit(500); + } + if($format === 'json') { + header('Content-type: application/json'); + echo json_encode($ret); + killme(); + } + else + http_status_exit(500); + +}
\ No newline at end of file diff --git a/include/text.php b/include/text.php index 47694a17c..cfe87991c 100644 --- a/include/text.php +++ b/include/text.php @@ -2378,3 +2378,74 @@ function linkify_tags($a, &$body, $uid) { return $results; } +/** + * @brief returns icon name for use with e.g. font-awesome based on mime-type + * + * @param string $type + * @return string + */ +function getIconFromType($type) { + $iconMap = array( + //Folder + t('Collection') => 'icon-folder-close', + //Common file + 'application/octet-stream' => 'icon-file-alt', + //Text + 'text/plain' => 'icon-file-text-alt', + 'application/msword' => 'icon-file-text-alt', + 'application/pdf' => 'icon-file-text-alt', + 'application/vnd.oasis.opendocument.text' => 'icon-file-text-alt', + 'application/epub+zip' => 'icon-book', + //Spreadsheet + 'application/vnd.oasis.opendocument.spreadsheet' => 'icon-table', + 'application/vnd.ms-excel' => 'icon-table', + //Image + 'image/jpeg' => 'icon-picture', + 'image/png' => 'icon-picture', + 'image/gif' => 'icon-picture', + 'image/svg+xml' => 'icon-picture', + //Archive + 'application/zip' => 'icon-archive', + 'application/x-rar-compressed' => 'icon-archive', + //Audio + 'audio/mpeg' => 'icon-music', + 'audio/wav' => 'icon-music', + 'application/ogg' => 'icon-music', + 'audio/ogg' => 'icon-music', + 'audio/webm' => 'icon-music', + 'audio/mp4' => 'icon-music', + //Video + 'video/quicktime' => 'icon-film', + 'video/webm' => 'icon-film', + 'video/mp4' => 'icon-film' + ); + + $iconFromType = 'icon-file-alt'; + + if (array_key_exists($type, $iconMap)) { + $iconFromType = $iconMap[$type]; + } + + return $iconFromType; +} + +/** + * @brief Returns a human readable formatted string for filesizes. + * + * @param int $size filesize in bytes + * @return string + */ +function userReadableSize($size) { + $ret = ""; + if (is_numeric($size)) { + $incr = 0; + $k = 1024; + $unit = array('bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); + while (($size / $k) >= 1){ + $incr++; + $size = round($size / $k, 2); + } + $ret = $size . " " . $unit[$incr]; + } + return $ret; +} diff --git a/include/zot.php b/include/zot.php index 780c6a265..33ac16abf 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1096,6 +1096,12 @@ function zot_import($arr, $sender_url) { $i['notify']['sender']['hash'] = make_xchan_hash($i['notify']['sender']['guid'],$i['notify']['sender']['guid_sig']); $deliveries = null; + if(array_key_exists('message',$i) && array_key_exists('type',$i['message']) && $i['message']['type'] === 'rating') { + // rating messages are processed only by directory servers + logger('Rating received: ' . print_r($arr,true), LOGGER_DATA); + $result = process_rating_delivery($i['notify']['sender'],$arr); + } + if(array_key_exists('recipients',$i['notify']) && count($i['notify']['recipients'])) { logger('specific recipients'); $recip_arr = array(); @@ -1115,7 +1121,8 @@ function zot_import($arr, $sender_url) { // It's a specifically targetted post. If we were sent a public_scope hint (likely), // get rid of it so that it doesn't get stored and cause trouble. - if(($i) && is_array($i) && array_key_exists('message',$i) && is_array($i['message']) && array_key_exists('public_scope',$i['message'])) + if(($i) && is_array($i) && array_key_exists('message',$i) && is_array($i['message']) + && $i['message']['type'] === 'activity' && array_key_exists('public_scope',$i['message'])) unset($i['message']['public_scope']); $deliveries = $r; @@ -1124,7 +1131,7 @@ function zot_import($arr, $sender_url) { } else { - if(($i['message']) && (array_key_exists('flags',$i['message'])) && (in_array('private',$i['message']['flags']))) { + if(($i['message']) && (array_key_exists('flags',$i['message'])) && (in_array('private',$i['message']['flags'])) && $i['message']['type'] === 'activity') { if(array_key_exists('public_scope',$i['message']) && $i['message']['public_scope'] === 'public') { // This should not happen but until we can stop it... logger('private message was delivered with no recipients.'); @@ -1215,6 +1222,7 @@ function zot_import($arr, $sender_url) { $result = process_profile_delivery($i['notify']['sender'],$arr,$deliveries); } + elseif($i['message']['type'] === 'channel_sync') { // $arr = get_channelsync_elements($i['message']); @@ -1477,7 +1485,7 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque // As a side effect we will also do a preliminary check that we have the top-level-post, otherwise // processing it is pointless. - $r = q("select route from item where mid = '%s' and uid = %d limit 1", + $r = q("select route, id from item where mid = '%s' and uid = %d limit 1", dbesc($arr['parent_mid']), intval($channel['channel_id']) ); @@ -1514,14 +1522,37 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque // going downstream check that we have the same upstream provider that // sent it to us originally. Ignore it if it came from another source - // (with potentially different permissions) + // (with potentially different permissions). + // only compare the last hop since it could have arrived at the last location any number of ways. + // Always accept empty routes and firehose items (route contains 'undefined') . + + $existing_route = explode(',', $r[0]['route']); + $routes = count($existing_route); + if($routes) { + $last_hop = array_pop($existing_route); + $last_prior_route = implode(',',$existing_route); + } + else { + $last_hop = ''; + $last_prior_route = ''; + } + + if(in_array('undefined',$existing_route) || $last_hop == 'undefined' || $sender['hash'] == 'undefined') + $last_hop = ''; $current_route = (($arr['route']) ? $arr['route'] . ',' : '') . $sender['hash']; - if($r[0]['route'] != $current_route) { + if($last_hop && $last_hop != $sender['hash']) { + logger('comment route mismatch: parent route = ' . $r[0]['route'] . ' expected = ' . $current_route, LOGGER_DEBUG); + logger('comment route mismatch: parent msg = ' . $r[0]['id'],LOGGER_DEBUG); $result[] = array($d['hash'],'comment route mismatch',$channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>',$arr['mid']); continue; } + + // we'll add sender['hash'] onto this when we deliver it. $last_prior_route now has the previously stored route + // *except* for the sender['hash'] which would've been the last hop before it got to us. + + $arr['route'] = $last_prior_route; } } @@ -1771,6 +1802,41 @@ function process_mail_delivery($sender,$arr,$deliveries) { return $result; } +function process_rating_delivery($sender,$arr) { + + $dirmode = intval(get_config('system','directory_mode')); + if($dirmode == DIRECTORY_MODE_NORMAL) + return; + + if(! $arr['target']) + return; + + $r = q("select * from xlink where xlink_xchan = '%s' and xlink_target = '%s' limit 1", + dbesc($sender['hash']), + dbesc($arr['target']) + ); + if($r) { + $x = q("update xlink set xlink_rating = %d, xlink_rating_text = '%s', xlink_updated = '%s' where xlink_id = %d", + intval($arr['rating']), + intval($arr['rating_text']), + dbesc(datetime_convert()), + intval($r[0]['xlink_id']) + ); + } + else { + $x = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_updated, xlink_static ) + values( '%s', '%s', %d, '%s', '%s', 1 ) ", + dbesc($sender['hash']), + dbesc($arr['target']), + intval($arr['rating']), + intval($arr['rating_text']), + dbesc(datetime_convert()) + ); + } + return; +} + + function process_profile_delivery($sender,$arr,$deliveries) { logger('process_profile_delivery', LOGGER_DEBUG); diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index 226ea2308..ba41073f8 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -1532,11 +1532,13 @@ CREATE TABLE IF NOT EXISTS `xlink` ( `xlink_rating` int(11) NOT NULL DEFAULT '0', `xlink_rating_text` TEXT NOT NULL DEFAULT '', `xlink_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `xlink_static` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`xlink_id`), KEY `xlink_xchan` (`xlink_xchan`), KEY `xlink_link` (`xlink_link`), KEY `xlink_updated` (`xlink_updated`), - KEY `xlink_rating` (`xlink_rating`) + KEY `xlink_rating` (`xlink_rating`), + KEY `xlink_static` (`xlink_static`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index 8539e672d..2fcc7f9ba 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -1145,12 +1145,14 @@ CREATE TABLE "xlink" ( "xlink_rating" bigint NOT NULL DEFAULT '0', "xlink_rating_text" TEXT NOT NULL DEFAULT '', "xlink_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', + "xlink_static" numeric(1) NOT NULL DEFAULT '0', PRIMARY KEY ("xlink_id") ); create index "xlink_xchan" on xlink ("xlink_xchan"); create index "xlink_link" on xlink ("xlink_link"); create index "xlink_updated" on xlink ("xlink_updated"); create index "xlink_rating" on xlink ("xlink_rating"); +create index "xlink_static" on xlink ("xlink_static"); CREATE TABLE "xperm" ( "xp_id" serial NOT NULL, "xp_client" varchar( 20 ) NOT NULL DEFAULT '', diff --git a/install/update.php b/install/update.php index 8cd25f1bf..346b2c25a 100644 --- a/install/update.php +++ b/install/update.php @@ -1,6 +1,6 @@ <?php -define( 'UPDATE_VERSION' , 1134 ); +define( 'UPDATE_VERSION' , 1135 ); /** * @@ -1537,3 +1537,14 @@ function update_r1133() { return UPDATE_FAILED; } + +function update_r1134() { + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $r = q("ALTER TABLE xlink ADD xlink_static numeric(1) NOT NULL DEFAULT '0', create index xlink_static on xlink ( \"xlink_static\" ) "); + } + else + $r = q("ALTER TABLE xlink ADD xlink_static TINYINT( 1 ) NOT NULL DEFAULT '0', ADD INDEX ( xlink_static ) "); + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; +}
\ No newline at end of file diff --git a/mod/acl.php b/mod/acl.php index d406942c3..8eff93a9a 100644 --- a/mod/acl.php +++ b/mod/acl.php @@ -33,7 +33,7 @@ function acl_init(&$a){ $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; // This horrible mess is needed because position also returns 0 if nothing is found. W/ould be MUCH easier if it instead returned a very large value - // Otherwise we could just order by LEAST(POSTION($search IN xchan_name),POSITION($search IN xchan_addr)). + // Otherwise we could just order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)). $order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) ." then POSITION('".dbesc($search)."' IN xchan_name) else position('".dbesc($search)."' IN xchan_addr) end, "; $col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' ); $sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; @@ -171,6 +171,7 @@ function acl_init(&$a){ ); } elseif(($type == 'a') || ($type == 'p')) { + $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and not (xchan_flags & %d)>0 @@ -180,6 +181,7 @@ function acl_init(&$a){ intval(XCHAN_FLAGS_DELETED) ); + } elseif($type == 'x') { $r = navbar_complete($a); @@ -209,7 +211,7 @@ function acl_init(&$a){ foreach($r as $g){ // remove RSS feeds from ACLs - they are inaccessible - if(strpos($g['hash'],'/')) + if(strpos($g['hash'],'/') && $type != 'a') continue; if(($g['abook_their_perms'] & PERMS_W_TAGWALL) && $type == 'c' && (! $noforums)) { @@ -233,7 +235,7 @@ function acl_init(&$a){ "id" => $g['id'], "xid" => $g['hash'], "link" => $g['nick'], - "nick" => substr($g['nick'],0,strpos($g['nick'],'@')), + "nick" => (($g['nick']) ? substr($g['nick'],0,strpos($g['nick'],'@')) : t('RSS')), "self" => (($g['abook_flags'] & ABOOK_FLAG_SELF) ? 'abook-self' : ''), "taggable" => '', "label" => '', @@ -248,6 +250,8 @@ function acl_init(&$a){ 'count' => $count, 'items' => $items, ); + + echo json_encode($o); diff --git a/mod/directory.php b/mod/directory.php index 4ceda293d..2a07208a4 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -274,17 +274,21 @@ function directory_content(&$a) { $arr = array('contact' => $rr, 'entry' => $entry); call_hooks('directory_item', $arr); - + + unset($profile); + unset($location); + + if(! $arr['entry']) { + continue; + } + if($sort_order == '' && $suggest) { $entries[$addresses[$rr['address']]] = $arr['entry']; // Use the same indexes as originally to get the best suggestion first } + else { $entries[] = $arr['entry']; } - unset($profile); - unset($location); - - } ksort($entries); // Sort array by key so that foreach-constructs work as expected diff --git a/mod/help.php b/mod/help.php index 5cdeda58f..0081e54e7 100644 --- a/mod/help.php +++ b/mod/help.php @@ -37,20 +37,28 @@ function help_content(&$a) { $text = ''; if(argc() > 1) { - $text = load_doc_file('doc/' . $a->argv[1] . '.md'); - $a->page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags(argv(1)))); + $path = ''; + for($x = 1; $x < argc(); $x ++) { + if(strlen($path)) + $path .= '/'; + $path .= argv($x); + } + $title = basename($path); + + $text = load_doc_file('doc/' . $path . '.md'); + $a->page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title))); if(! $text) { - $text = load_doc_file('doc/' . $a->argv[1] . '.bb'); + $text = load_doc_file('doc/' . $path . '.bb'); if($text) $doctype = 'bbcode'; - $a->page['title'] = t('Help:') . ' ' . ucwords(str_replace('_',' ',notags(argv(1)))); + $a->page['title'] = t('Help:') . ' ' . ucwords(str_replace('_',' ',notags($title))); } if(! $text) { - $text = load_doc_file('doc/' . $a->argv[1] . '.html'); + $text = load_doc_file('doc/' . $path . '.html'); if($text) $doctype = 'html'; - $a->page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags(argv(1)))); + $a->page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title))); } } diff --git a/mod/poco.php b/mod/poco.php index 152f5a143..098c9a240 100644 --- a/mod/poco.php +++ b/mod/poco.php @@ -1,210 +1,7 @@ <?php -function poco_init(&$a) { - - $system_mode = false; - - if(intval(get_config('system','block_public')) && (! local_user()) && (! remote_user())) { - logger('mod_poco: block_public'); - http_status_exit(401); - } - - $observer = $a->get_observer(); - - if(argc() > 1) { - $user = notags(trim(argv(1))); - } - if(! x($user)) { - $c = q("select * from pconfig where cat = 'system' and k = 'suggestme' and v = '1'"); - if(! $c) { - logger('mod_poco: system mode. No candidates.', LOGGER_DEBUG); - http_status_exit(404); - } - $system_mode = true; - } - - - $format = (($_REQUEST['format']) ? $_REQUEST['format'] : 'json'); - - $justme = false; - - if(argc() > 2 && argv(2) === '@me') - $justme = true; - if(argc() > 3) { - if(argv(3) === '@all') - $justme = false; - elseif(argv(3) === '@self') - $justme = true; - } - if(argc() > 4 && intval(argv(4)) && $justme == false) - $cid = intval(argv(4)); - - if(! $system_mode) { - - $r = q("SELECT channel_id from channel where channel_address = '%s' limit 1", - dbesc($user) - ); - if(! $r) { - logger('mod_poco: user mode. Account not found. ' . $user); - http_status_exit(404); - } - - $channel_id = $r[0]['channel_id']; - $ohash = (($observer) ? $observer['xchan_hash'] : ''); - - if(! perm_is_allowed($channel_id,$ohash,'view_contacts')) { - logger('mod_poco: user mode. Permission denied for ' . $ohash . ' user: ' . $user); - http_status_exit(401); - } - - } - - if($justme) - $sql_extra = " and ( abook_flags & " . ABOOK_FLAG_SELF . " )>0 "; - else - $sql_extra = " and abook_flags = 0 "; - - if($cid) - $sql_extra = sprintf(" and abook_id = %d ",intval($cid)); - - if($system_mode) { - $r = q("SELECT count(*) as `total` from abook where ( abook_flags & " . ABOOK_FLAG_SELF . - " )>0 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') "); - } - else { - $r = q("SELECT count(*) as `total` from abook where abook_channel = %d - $sql_extra ", - intval($channel_id) - ); - $rooms = q("select * from menu_item where ( mitem_flags & " . intval(MENU_ITEM_CHATROOM) . " )>0 and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = '' and mitem_channel_id = %d", - intval($channel_id) - ); - } - if($r) - $totalResults = intval($r[0]['total']); - else - $totalResults = 0; +require_once('include/socgraph.php'); - $startIndex = intval($_GET['startIndex']); - if(! $startIndex) - $startIndex = 0; - $itemsPerPage = ((x($_GET,'count') && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults); - - - if($system_mode) { - $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where ( abook_flags & " . ABOOK_FLAG_SELF . - " )>0 and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') limit %d offset %d ", - intval($itemsPerPage), - intval($startIndex) - ); - } - else { - $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d - $sql_extra LIMIT %d OFFSET %d", - intval($channel_id), - intval($itemsPerPage), - intval($startIndex) - ); - } - - $ret = array(); - if(x($_GET,'sorted')) - $ret['sorted'] = 'false'; - if(x($_GET,'filtered')) - $ret['filtered'] = 'false'; - if(x($_GET,'updatedSince')) - $ret['updateSince'] = 'false'; - - $ret['startIndex'] = (string) $startIndex; - $ret['itemsPerPage'] = (string) $itemsPerPage; - $ret['totalResults'] = (string) $totalResults; - - if($rooms) { - $ret['chatrooms'] = array(); - foreach($rooms as $room) { - $ret['chatrooms'][] = array('url' => $room['mitem_link'], 'desc' => $room['mitem_desc']); - } - } - - $ret['entry'] = array(); - - - $fields_ret = array( - 'id' => false, - 'guid' => false, - 'guid_sig' => false, - 'hash' => false, - 'displayName' => false, - 'urls' => false, - 'preferredUsername' => false, - 'photos' => false, - 'rating' => false - ); - - if((! x($_GET,'fields')) || ($_GET['fields'] === '@all')) - foreach($fields_ret as $k => $v) - $fields_ret[$k] = true; - else { - $fields_req = explode(',',$_GET['fields']); - foreach($fields_req as $f) - $fields_ret[trim($f)] = true; - } - - if(is_array($r)) { - if(count($r)) { - foreach($r as $rr) { - $entry = array(); - if($fields_ret['id']) - $entry['id'] = $rr['abook_id']; - if($fields_ret['guid']) - $entry['guid'] = $rr['xchan_guid']; - if($fields_ret['guid_sig']) - $entry['guid_sig'] = $rr['xchan_guid_sig']; - if($fields_ret['hash']) - $entry['hash'] = $rr['xchan_hash']; - - if($fields_ret['displayName']) - $entry['displayName'] = $rr['xchan_name']; - if($fields_ret['urls']) { - $entry['urls'] = array(array('value' => $rr['xchan_url'], 'type' => 'profile')); - $network = $rr['xchan_network']; - if(strpos($network,'friendica') !== false) - $network = 'friendica'; - if($rr['xchan_addr']) - $entry['urls'][] = array('value' => 'acct:' . $rr['xchan_addr'], 'type' => $network); - } - if($fields_ret['preferredUsername']) - $entry['preferredUsername'] = substr($rr['xchan_addr'],0,strpos($rr['xchan_addr'],'@')); - if($fields_ret['photos']) - $entry['photos'] = array(array('value' => $rr['xchan_photo_l'], 'mimetype' => $rr['xchan_photo_mimetype'], 'type' => 'profile')); - if($fields_ret['rating']) { - $entry['rating'] = ((array_key_exists('abook_rating',$rr)) ? intval($rr['abook_rating']) : 0); - $entry['rating_text'] = ((array_key_exists('abook_rating_text',$rr)) ? $rr['abook_rating_text'] : ''); - // maybe this should be a composite calculated rating in $system_mode - if($system_mode) - $entry['rating'] = 0; - } - $ret['entry'][] = $entry; - } - } - else - $ret['entry'][] = array(); - } - else - http_status_exit(500); - - if($format === 'xml') { - header('Content-type: text/xml'); - echo replace_macros(get_markup_template('poco_xml.tpl'),array_xmlify(array('$response' => $ret))); - http_status_exit(500); - } - if($format === 'json') { - header('Content-type: application/json'); - echo json_encode($ret); - killme(); - } - else - http_status_exit(500); - - -}
\ No newline at end of file +function poco_init(&$a) { + poco($a,false); +} diff --git a/mod/search.php b/mod/search.php index 2ea6ad86f..5b15b0593 100644 --- a/mod/search.php +++ b/mod/search.php @@ -21,6 +21,10 @@ function search_content(&$a,$update = 0, $load = false) { require_once('include/conversation.php'); require_once('include/items.php'); + $format = (($_REQUEST['format']) ? $_REQUEST['format'] : ''); + if($format !== '') { + $update = $load = 1; + } $observer = $a->get_observer(); $observer_hash = (($observer) ? $observer['xchan_hash'] : ''); @@ -179,6 +183,19 @@ function search_content(&$a,$update = 0, $load = false) { $items = array(); } + + if($format == 'json') { + $result = array(); + require_once('include/conversation.php'); + foreach($items as $item) { + $item['html'] = bbcode($item['body']); + $x = encode_item($item); + $x['html'] = prepare_text($item['body'],$item['mimetype']); + $result[] = $x; + } + json_return_and_die(array('success' => true,'messages' => $result)); + } + if($tag) $o .= '<h2>Items tagged with: ' . htmlspecialchars($search, ENT_COMPAT,'UTF-8') . '</h2>'; else diff --git a/mod/share.php b/mod/share.php index 78a25ee10..d70336ed1 100644 --- a/mod/share.php +++ b/mod/share.php @@ -53,7 +53,7 @@ function share_init(&$a) { "' avatar='".$r[0]['author']['xchan_photo_s']. "' link='".$r[0]['plink']. "' posted='".$r[0]['created']. - "' message_id='".$r[0]['mid']."']\n"; + "' message_id='".$r[0]['mid']."']"; if($r[0]['title']) $o .= '[b]'.$r[0]['title'].'[/b]'."\n"; $o .= $r[0]['body']; diff --git a/mod/sharedwithme.php b/mod/sharedwithme.php index 8b7d2661c..56cbc35ec 100644 --- a/mod/sharedwithme.php +++ b/mod/sharedwithme.php @@ -73,27 +73,37 @@ function sharedwithme_content(&$a) { dbesc($channel['channel_hash']) ); - $o = profile_tabs($a, $is_owner, $channel['channel_address']); - - $o .= '<div class="section-title-wrapper">'; - - $o .= '<a href="/sharedwithme/dropall" onclick="return confirmDelete();" class="btn btn-xs btn-default pull-right"><i class="icon-trash"></i> ' . t('Remove all entries') . '</a>'; - - $o .= '<h2>' . t('Files shared with me') . '</h2>'; - - $o .= '</div>'; - - $o .= '<div class="section-content-wrapper">'; + $items =array(); if($r) { foreach($r as $rr) { $object = json_decode($rr['object'],true); - $url = rawurldecode(get_rel_link($object['link'],'alternate')); - $o .= '<a href="' . $url . '?f=&zid=' . $channel['xchan_addr'] . '">' . $url . '</a> <a href="/sharedwithme/' . $rr['id'] . '/drop" onclick="return confirmDelete();"><i class="icon-trash drop-icons"></i></a><br><br>'; + + $item = array(); + $item['id'] = $rr['id']; + $item['objfiletype'] = $object['filetype']; + $item['objfiletypeclass'] = getIconFromType($object['filetype']); + $item['objurl'] = rawurldecode(get_rel_link($object['link'],'alternate')) . '?f=&zid=' . $channel['xchan_addr']; + $item['objfilename'] = $object['filename']; + $item['objfilesize'] = userReadableSize($object['filesize']); + $item['objedited'] = $object['edited']; + + $items[] = $item; + } } - $o .= '</div>'; + $o = profile_tabs($a, $is_owner, $channel['channel_address']); + + $o .= replace_macros(get_markup_template('sharedwithme.tpl'), array( + '$header' => t('Files: shared with me'), + '$name' => t('Name'), + '$size' => t('Size'), + '$lastmod' => t('Last Modified'), + '$dropall' => t('Remove all files'), + '$drop' => t('Remove this file'), + '$items' => $items + )); return $o; diff --git a/mod/xpoco.php b/mod/xpoco.php new file mode 100644 index 000000000..560966750 --- /dev/null +++ b/mod/xpoco.php @@ -0,0 +1,7 @@ +<?php + +require_once('include/socgraph.php'); + +function xpoco_init(&$a) { + poco($a,true); +} diff --git a/version.inc b/version.inc index 2574e9160..8b85b7799 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -2015-01-25.927 +2015-01-28.930 diff --git a/view/css/conversation.css b/view/css/conversation.css index 7a5ffc2f7..8bc71bb6d 100644 --- a/view/css/conversation.css +++ b/view/css/conversation.css @@ -195,6 +195,10 @@ a.wall-item-name-link { clear: both; } +.shared_header { + margin-bottom: 20px; +} + /* comment_item */ .comment-edit-text-empty, .comment-edit-text-full { diff --git a/view/css/mod_sharedwithme.css b/view/css/mod_sharedwithme.css new file mode 100644 index 000000000..79fe0d7a9 --- /dev/null +++ b/view/css/mod_sharedwithme.css @@ -0,0 +1,24 @@ +#cloud-index { + width: 100%; +} + +#cloud-index td:nth-child(1){ + padding: 7px 3px 7px 10px; +} + +#cloud-index th:nth-child(4), +#cloud-index td:nth-child(4){ + padding: 7px 3px; + white-space: nowrap; +} + +#cloud-index th:nth-child(5), +#cloud-index td:nth-child(5){ + padding: 7px 10px 7px 7px; + white-space: nowrap; +} + +.cloud-index-tool { + padding: 7px 10px; +} + diff --git a/view/de/lostpass_eml.tpl b/view/de/lostpass_eml.tpl index 2175d2e5d..02a71b77a 100644 --- a/view/de/lostpass_eml.tpl +++ b/view/de/lostpass_eml.tpl @@ -1,6 +1,6 @@ Hallo {{$username}}, - auf {{$sitename} wurde eine Rücksetzung Deines Passwortes angefordert. +auf {{$sitename}} wurde eine Rücksetzung Deines Passwortes angefordert. Bitte klicke auf den Link unten, um diese Anforderung zu bestätigen, oder kopiere den Link und füge ihn in die Adresszeile Deines Browsers ein. @@ -27,6 +27,4 @@ Username: {{$email}} Viele Grüße, - der Administrator von {{$sitename}} - -
\ No newline at end of file +der Administrator von {{$sitename}} diff --git a/view/tpl/cloud_header.tpl b/view/tpl/cloud_header.tpl index 403323085..c75815d07 100644 --- a/view/tpl/cloud_header.tpl +++ b/view/tpl/cloud_header.tpl @@ -1,7 +1,9 @@ <div class="section-title-wrapper"> {{if $actionspanel}} <div class="pull-right"> + {{if $is_owner}} <a href="/sharedwithme" class="btn btn-xs btn-default"><i class="icon-cloud-download"></i> {{$shared}}</a> + {{/if}} <button id="files-create-btn" class="btn btn-xs btn-primary" title="{{if $quota.limit || $quota.used}}{{$quota.desc}}{{/if}}" onclick="openClose('files-mkdir-tools'); closeMenu('files-upload-tools');"><i class="icon-folder-close-alt"></i> {{$create}}</button> <button id="files-upload-btn" class="btn btn-xs btn-success" title="{{if $quota.limit || $quota.used}}{{$quota.desc}}{{/if}}" onclick="openClose('files-upload-tools'); closeMenu('files-mkdir-tools');"><i class="icon-upload"></i> {{$upload}}</button> </div> diff --git a/view/tpl/sharedwithme.tpl b/view/tpl/sharedwithme.tpl new file mode 100644 index 000000000..1aeb9d4d7 --- /dev/null +++ b/view/tpl/sharedwithme.tpl @@ -0,0 +1,24 @@ +<div class="section-title-wrapper"> + <a href="/sharedwithme/dropall" onclick="return confirmDelete();" class="btn btn-xs btn-default pull-right"><i class="icon-trash"></i> {{$dropall}}</a> + <h2>{{$header}}</h2> +</div> +<div class="generic-content-wrapper section-content-wrapper-np"> + <table id="cloud-index"> + <tr> + <th width="1%"></th> + <th width="92%">{{$name}}</th> + <th width="1%"></th> + <th width="1%" class="hidden-xs">{{$size}}</th> + <th width="1%" class="hidden-xs">{{$lastmod}}</th> + </tr> + {{foreach $items as $item}} + <tr id="cloud-index-{{$item.id}}"> + <td><i class="{{$item.objfiletypeclass}}" title="{{$item.objfiletype}}"></i></td> + <td><a href="{{$item.objurl}}">{{$item.objfilename}}</a></td> + <td class="cloud-index-tool"><a href="/sharedwithme/{{$item.id}}/drop" title="{{$drop}}" onclick="return confirmDelete();"><i class="icon-trash drop-icons"></i></a></td> + <td class="hidden-xs">{{$item.objfilesize}}</td> + <td class="hidden-xs">{{$item.objedited}}</td> + </tr> + {{/foreach}} + </table> +</div> |