507 Commits
2.0 ... 2.2

Author SHA1 Message Date
Mario Vavti
bc2b948f1f Merge branch 2.2RC 2017-03-08 09:39:46 +01:00
Mario Vavti
ff9442474d version 2.2 and changelog 2017-03-08 09:28:58 +01:00
zotlabs
92996e550c allow post_activity_item to be passed an empty ACL without resetting to channel default 2017-03-06 21:02:50 -08:00
zotlabs
c3c4254882 add public_policy to the nwiki container also. This should not affect the recent bug as presented, but is being added for consistency. 2017-03-06 18:01:18 -08:00
zotlabs
751c4c3169 correct fix for wiki anonymous read issue (items_permissions_sql checks item.public_policy which was set for posts, not wikis) 2017-03-06 15:35:17 -08:00
jeroenpraat
f783d594cc Big 2.2 string update Dutch 2017-03-06 22:50:52 +01:00
Mario Vavti
6e32be7e43 allow unauthenticated access to public wiki pages 2017-03-06 22:32:44 +01:00
Mario Vavti
4471c45fb7 do not collapse long nsfw content 2017-03-06 11:53:06 +01:00
Mario Vavti
a165303602 update changelog 2017-03-04 17:04:30 +01:00
Mario Vavti
7251ce6e17 we need item edited for wiki page history, not item created 2017-03-04 16:57:26 +01:00
Mario Vavti
a894456550 fix badge position for narrow navbar 2017-03-03 10:04:57 +01:00
Mario Vavti
1eba847e99 provide info if there are no sche,es available 2017-03-02 12:52:09 +01:00
Mario Vavti
729d52f10a reset schema value after we empty and repopulate it. second half of fix for #624 2017-03-02 11:39:14 +01:00
Mario Vavti
79e8e4599e reset schema value after we empty and repopulate it. first half of fix for #624 2017-03-02 11:39:01 +01:00
Mario Vavti
ba5cfd8b25 setting top position of contextual-help in schemes does not work with narrow navbar setting. schema css is always called last. 2017-03-02 11:38:47 +01:00
Mario Vavti
288905c361 add title to connect button 2017-03-01 11:39:51 +01:00
Mario Vavti
3071f3b71c minor template fixes 2017-03-01 11:37:40 +01:00
Mario Vavti
07d443a159 missing css class 2017-02-28 13:24:09 +01:00
zotlabs
1acfe53f74 Merge branch '2.2RC' of https://github.com/redmatrix/hubzilla into 2.2RC_merge 2017-02-27 14:55:34 -08:00
zotlabs
265eb2b440 document the filesize limitations on uploading via /cloud, fix non-functional anchor 2017-02-27 14:55:17 -08:00
Mario Vavti
69e145a630 fix js issue in markdown mimetype wikis if content contains quotes 2017-02-27 13:52:51 +01:00
Mario Vavti
1a28720c56 update changelog 2017-02-27 11:42:25 +01:00
Mario Vavti
805cae7b31 whitespace 2017-02-27 11:12:35 +01:00
Mario Vavti
1070f3ed6b missing clear 2017-02-27 10:55:25 +01:00
Mario Vavti
2467698045 do not mess up schemas 2017-02-27 10:45:31 +01:00
Mario Vavti
b6c4e6a6d0 lower version requirement to 2.2RC 2017-02-27 10:18:05 +01:00
Mario Vavti
8e3e90ddd2 set minversion and maxversion for themes in view/theme/themename/php/theme.php instead of separate file. 2017-02-27 10:16:04 +01:00
Mario Vavti
8a69a5c3c7 add a minversion to the theme and fallback to default if requirement is not met. mark incompatible themes in the theme selector 2017-02-26 21:22:19 +01:00
zotlabs
e819727b09 send sync packet on profile photo permissions change 2017-02-25 15:04:59 -08:00
zotlabs
4b1f87050f Merge branch '2.2RC' of https://github.com/redmatrix/hubzilla into 2.2RC_merge 2017-02-25 13:57:08 -08:00
zotlabs
919de44a71 escape tags on viewsrc output in case it is not text/bbcode. 2017-02-25 13:56:52 -08:00
Mario Vavti
d59095c2e6 bump version 2017-02-25 21:34:19 +01:00
Mario Vavti
65e18f5b8f use chanlink_url() in directory since the xchan might not yet be available on our server 2017-02-24 10:07:14 +01:00
zotlabs
e9243e9660 minor edits 2017-02-23 11:33:13 -08:00
zotlabs
59645f51a9 Merge branch '2.2RC' of https://github.com/redmatrix/hubzilla into 2.2RC_merge 2017-02-23 11:31:52 -08:00
Mario Vavti
dd3e530a63 update changelog 2017-02-23 14:53:09 +01:00
Mario Vavti
3e2e60fb86 update changelog 2017-02-23 14:51:09 +01:00
Mario Vavti
9bab858fd1 move collapsed login and register buttons to the left 2017-02-23 12:32:27 +01:00
Mario Vavti
0ef8c5bda8 move collapsed login and register buttons to the left 2017-02-23 12:31:41 +01:00
Mario Vavti
d4be96cd03 yet one more place to use chanlink_hash() instead of chanlink_url() 2017-02-23 12:25:16 +01:00
Mario Vavti
3d0c6700db yet one more place to use chanlink_hash() instead of chanlink_url() 2017-02-23 12:24:42 +01:00
Mario Vavti
5012baba15 one more place to use chanlink_hash() instead of chanlink_url() 2017-02-23 11:41:03 +01:00
Mario Vavti
41c67fa345 more places to use chanlink_hash() instead of chanlink_url() for profile_link 2017-02-23 10:36:00 +01:00
Mario Vavti
c75852455b use chanlink_hash() instead of chanlink_url() for $profile_link 2017-02-23 09:53:24 +01:00
zotlabs
27fa15e95d Merge pull request #685 from phellmes/dev
Update DE translation strings
2017-02-23 12:11:09 +11:00
phellmes
175e222927 Update DE translation strings 2017-02-22 14:50:28 +01:00
Mario Vavti
55924f5c5b apps improvements 2017-02-22 11:22:43 +01:00
zotlabs
956f0043fc change text back to 'add apps' 2017-02-21 23:16:05 -08:00
zotlabs
70cdbe4816 Merge pull request #684 from anaqreon/dev
Change Add Apps to Manage Apps and support translation.
2017-02-22 18:14:30 +11:00
zotlabs
6644dc4861 use head_add_link() for feed discovery 2017-02-21 18:58:51 -08:00
Andrew Manning
3e144baacd Change Add Apps to Manage Apps and support translation. 2017-02-21 20:32:13 -05:00
zotlabs
bbacfbdd6a display page not updating after comment 2017-02-21 15:24:39 -08:00
Mario Vavti
cbc0e5b934 do not lock out channels with only read perms from all post actions. we check read/write permissions for each command later in the process 2017-02-21 14:52:42 +01:00
Mario Vavti
81d556d32e wrong permission 2017-02-21 10:34:40 +01:00
zotlabs
5ad5a0fa07 detect no acl 2017-02-20 23:13:27 -08:00
zotlabs
e54ba7ecbc fix find_folder_hash_by_path() which was not safe against multiple attach structures with the same filename but in different directories 2017-02-20 23:03:48 -08:00
zotlabs
1c1d1f1185 update fr translation 2017-02-20 18:46:51 -08:00
zotlabs
bc1812840a don't search on empty filename - we shouldn't find it. The reason why this change is being made is because we actually did find it due to a development glitch 2017-02-20 15:06:17 -08:00
zotlabs
74def75ca3 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-20 14:14:26 -08:00
Mario Vavti
924b353e5a width must be 100% here 2017-02-20 23:09:21 +01:00
zotlabs
31618a4310 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-20 14:07:42 -08:00
zotlabs
21e3481810 wiki page permissions issue 2017-02-20 14:07:22 -08:00
Mario Vavti
d7ba2c7168 if we slide to left aside make the overlay darker and leave aside as is 2017-02-20 14:02:39 +01:00
zotlabs
6f811fd7f9 bug in adding main.js as a js source 2017-02-19 17:04:37 -08:00
zotlabs
573846707c fix several places where head_add_(css|js) functions have been used incorrectly. It appears that mistakes were made going back a long time and propagated. Here's the way it should work:
- if there is no preceding / character, we look for the file within all the appropriate theme directories.
- otherwise the file should have a preceding /, which means use this path relative to the hubzilla basedir
- files beginning with // are considered to be schemeless URLs.

Therefore 'foo.css' means find the best theme-able representation of foo.css.
'/library/foo.css' means only use the version of foo.css that is in /library.
2017-02-19 16:50:41 -08:00
zotlabs
02e487f306 this icon also appears to require the fixed-width attribute 2017-02-19 14:14:58 -08:00
zotlabs
73b28b5d94 change primary directory per request 2017-02-18 12:40:43 -08:00
zotlabs
2a7ec29cd1 string update 2017-02-17 12:32:02 -08:00
Mario Vavti
d4f8a8dedd add the generic-icons-nav class 2017-02-17 18:32:18 +01:00
Mario Vavti
f23c380cae add register button for collapsed state 2017-02-17 16:31:36 +01:00
Mario Vavti
7151467db7 fixed width icons for item dropdown 2017-02-17 16:08:18 +01:00
Mario Vavti
16a8416495 css fixes and rename link to full docs to help since its app is also called help 2017-02-17 15:07:20 +01:00
zotlabs
5db3b71c6a strip possible quotes from attribute_contains() haystacks 2017-02-15 11:35:36 -08:00
zotlabs
8897c5763a typo 2017-02-15 10:55:53 -08:00
zotlabs
07d92796d2 provide HTTP header parser which honours continuation lines and despite the fact that continuation lines have been deprecated - as they still exist in the wild. 2017-02-14 20:57:14 -08:00
zotlabs
1f39c16d99 util/pconfig - don't enumerate empty arrays, mod_acl - add more comments 2017-02-13 17:51:39 -08:00
zotlabs
c8aeb5b160 Merge pull request #676 from anaqreon/doco
Doco
2017-02-14 12:51:01 +11:00
Andrew Manning
69b08a2062 Merge remote-tracking branch 'upstream/dev' into doco 2017-02-13 20:38:11 -05:00
Andrew Manning
05fd5eb8be Integrated more content and deleted the original locations where applicable. 2017-02-13 20:37:58 -05:00
zotlabs
8ed0913df6 Merge pull request #675 from mjfriaza/dev
Updated the Spanish translation
2017-02-14 06:44:16 +11:00
Manuel Jiménez Friaza
d85bcb2e37 Fix 'settings/channel' page in Spanish contextual help 2017-02-13 15:48:06 +01:00
Manuel Jiménez Friaza
09e5732f8a Updated the Spanish contextual help 2017-02-13 15:24:54 +01:00
Manuel Jiménez Friaza
d7fcf31be5 Updated the Spanish translation 2017-02-13 13:56:17 +01:00
zotlabs
f63aaa5429 be consistent with the name 2017-02-12 18:42:43 -08:00
zotlabs
321241da02 add default permcat to channel settings form 2017-02-12 18:40:26 -08:00
zotlabs
7c72886b1b Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-12 17:40:45 -08:00
zotlabs
2a52592292 testing and bug fixes virtual profile groups 2017-02-12 17:40:18 -08:00
zotlabs
ccdfbc721f Create virtual privacy groups for private profile member lists 2017-02-12 15:56:33 -08:00
Andrew Manning
a3436aea02 Some more work converting api_zot to bbcode. This page needs some serious formatting work. 2017-02-12 14:27:09 -05:00
Mario Vavti
f62b2fc114 css fix 2017-02-12 20:06:09 +01:00
Andrew Manning
baf612bd59 Reformat code of conduct for developers and integrate. 2017-02-12 13:59:17 -05:00
Andrew Manning
f3490440b4 Deleting original help content pages that have been integrated into the new doco 2017-02-12 07:38:43 -05:00
zotlabs
5cc1c30d7f Merge pull request #671 from anaqreon/webimport
Fix webpage element import tool
2017-02-12 18:10:09 +11:00
Andrew Manning
0017de46e4 remove logger lines 2017-02-11 20:54:09 -05:00
Andrew Manning
1cd1328b0c Merge remote-tracking branch 'upstream/dev' into webimport 2017-02-11 20:52:17 -05:00
Andrew Manning
8ff9ad7636 Webpage import tool works again after setting iconfig properly and following the Impel class function example. More testing is needed. 2017-02-11 20:52:06 -05:00
zotlabs
1ba1c5b44e Merge pull request #670 from anaqreon/doco
Scroll to doco links with anchor references when there is a ?zid parameter
2017-02-12 07:47:06 +11:00
Andrew Manning
7db55d8db2 Update Zot protocol link 2017-02-11 14:46:24 -05:00
Andrew Manning
e058b19f53 Scroll to doco links with anchor references when there is a ?zid parameter. 2017-02-11 14:40:04 -05:00
Mario Vavti
bc3605a502 whitespace 2017-02-10 10:50:16 +01:00
Mario Vavti
ce4daad431 do not use modal-sm class 2017-02-10 10:02:48 +01:00
Mario Vavti
0360d42d30 add a login button for collapsed state and refine login modal 2017-02-10 10:01:43 +01:00
zotlabs
1fb37f93cc more permissions optimisations 2017-02-09 19:52:13 -08:00
zotlabs
fce33402e7 use profile_store_lowlevel() when creating additional profiles 2017-02-09 17:40:56 -08:00
zotlabs
abadd0bd34 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-09 17:31:31 -08:00
zotlabs
16f27d0004 more work on permcats and consolidating calls that try to discover connect permissions, also create lowlevel store functions for abook and profile - since these currently may have issues with sql strict mode. 2017-02-09 17:29:24 -08:00
Mario Vavti
242eede258 wrap resizing in document ready function 2017-02-09 12:01:55 +01:00
zotlabs
8dc349caac minor theming and whitespace 2017-02-08 19:47:34 -08:00
zotlabs
91819bfc2d bringer - all basic functionality is implemented 2017-02-08 17:21:32 -08:00
zotlabs
6ee691e019 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-08 11:29:45 -08:00
zotlabs
28f0833237 fix immediate issue with multiple login forms until I can figure out an elegant way to "popup" the modal login form already on the page. We still may need this fix for the actual login module which should always be callable and present a login form even if the nav is completely borked. 2017-02-08 11:24:21 -08:00
Mario Vavti
eb415fd869 better detection of when to show the feature button and document nav mode for app_render() 2017-02-08 11:17:09 +01:00
Mario Vavti
ace0a1cb75 do not show feature button if the app is shared. css fixes 2017-02-08 10:56:03 +01:00
zotlabs
6ceaea8478 open permission tab by default - when you're creating permission categories 2017-02-07 21:03:14 -08:00
zotlabs
30659aef50 initial permcat creation ability, in /settings/permcats; functional permcat creation for testing but still needs a lot of UX work before promoting the ability 2017-02-07 20:29:03 -08:00
zotlabs
46d0e23e7b atokens - we only need one permission column 2017-02-07 19:49:15 -08:00
zotlabs
2d3e20d96e move permcat initialisation to zlib 2017-02-07 17:51:56 -08:00
zotlabs
723b51c931 provide a few system defined permcats; will require a permission editor page to define new (personal) ones. 2017-02-07 17:17:38 -08:00
zotlabs
a6160e3026 move permcat library functions to Zlib 2017-02-07 16:43:00 -08:00
zotlabs
ecca69442d Merge branch 'abroles' into dev 2017-02-07 16:15:15 -08:00
zotlabs
b2bae867d0 more background work for permcat support 2017-02-07 16:08:27 -08:00
zotlabs
cfe843b870 nits 2017-02-07 14:02:13 -08:00
Mario Vavti
1cef3f15d5 sort the apps 2017-02-07 22:32:25 +01:00
Mario Vavti
1bb56309a6 default to manual conversation updates 2017-02-07 20:45:13 +01:00
zotlabs
6468b7a914 update readme; probably not finished with this yet so feel free to make suggestions 2017-02-06 15:28:50 -08:00
zotlabs
6a083e8452 bring back view links for all notification types (esp: network, channel) for easy access 2017-02-06 14:32:50 -08:00
zotlabs
27cac334e1 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-06 14:12:43 -08:00
zotlabs
947478ca76 don't add zid to app links if they're on this system and we're logged in already. This messes up the null arg detection in mod_network. 2017-02-06 14:10:54 -08:00
Mario Vavti
c75357faa3 also take care of the collapsed state apps 2017-02-06 20:36:26 +01:00
Mario Vavti
e9a27393b8 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-02-06 20:30:24 +01:00
Mario Vavti
5d12c56510 only check for mode 2017-02-06 20:30:02 +01:00
zotlabs
00cfc4be44 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-02-06 11:14:59 -08:00
Mario Vavti
70edcabca1 move icon stuff back to app_render() and send navapps through app_render() 2017-02-06 20:10:10 +01:00
Mario Vavti
dce5e8d0cc fix wiki and chat .apd 2017-02-06 14:50:23 +01:00
Mario Vavti
59baf34170 make sure we do not remove other categories on app un-feature 2017-02-06 14:37:33 +01:00
Mario Vavti
5aa1146fe9 minor fixes 2017-02-06 13:58:49 +01:00
Mario Vavti
8059260c18 import system apps on initial load 2017-02-06 13:45:46 +01:00
Mario Vavti
91bc8d473f update templates 2017-02-06 13:30:56 +01:00
Mario Vavti
3d4f2d146e add profile app 2017-02-06 13:19:14 +01:00
Mario Vavti
ce61a64bd2 remove profile app 2017-02-06 13:17:58 +01:00
Mario Vavti
e2a498c8ca update apps 2017-02-06 13:17:02 +01:00
Mario Vavti
758e7b92eb update apps 2017-02-06 13:16:33 +01:00
Mario Vavti
cf4cdffcc1 parse icons in get_system_apps() 2017-02-06 10:49:42 +01:00
Mario Vavti
e70c87ed41 merge dev 2017-02-06 10:08:05 +01:00
zotlabs
d8472cc9f5 import - get rid of 'step system', we should be able to process any import file at any time. 2017-02-05 20:46:11 -08:00
zotlabs
56a08f0d17 make channel move an option (in addition to cloning) 2017-02-05 20:26:06 -08:00
zotlabs
eb3685f537 remove per-page login css (home, login); add support for alternative markdown mention format 2017-02-05 18:47:35 -08:00
zotlabs
201a6b8742 nav_login element width was page dependent. Put this in theme css 2017-02-05 14:55:46 -08:00
zotlabs
e2ee4ae024 better theming of rmagic page 2017-02-05 14:45:28 -08:00
zotlabs
23e3e2c504 Merge pull request #665 from einervonvielen/introduced_dehydrated
The script letsencrypt.sh was replaced by dehydrated.
2017-02-06 06:50:26 +11:00
zotlabs
ab698305bf Merge pull request #666 from einervonvielen/dehydrated_for_dev
The script letsencrypt.sh was replaced by dehydrated.
2017-02-06 06:50:02 +11:00
Einer von Vielen
143ae2b788 The script letsencrypt.sh was replaced by dehydrated. 2017-02-05 19:36:23 +01:00
Einer von Vielen
baf50ea84a The script letsencrypt.sh was replaced by dehydrated. 2017-02-05 19:14:37 +01:00
zotlabs
73845e01ed cleanup 2017-02-04 14:58:13 -08:00
Mario Vavti
178e3d5bc8 allow featuring of apps in /apps and update some more apd files 2017-02-04 18:36:50 +01:00
Mario Vavti
a94254a375 merge dev 2017-02-04 16:17:52 +01:00
zotlabs
fc4083346e more work on nav-modal 2017-02-03 15:31:01 -08:00
zotlabs
f79a11cbf7 trying nav-login as modal 2017-02-03 13:47:29 -08:00
Mario Vavti
edc0a7ef91 update some apps and refine navapps.tpl 2017-02-03 15:24:21 +01:00
Mario Vavti
dce9a70ff5 check for app-icons in app_list() instead of app_render() 2017-02-03 12:12:05 +01:00
Mario Vavti
631a8278d3 do not hide button - just gray it out 2017-02-03 11:21:06 +01:00
zotlabs
bae37c8e6f string update 2017-02-03 02:12:30 -08:00
Mario Vavti
a5c1685ea0 hide notifications button if there are none 2017-02-03 11:00:35 +01:00
Mario Vavti
d0a0051d85 use openClose() for nav-login 2017-02-03 09:35:35 +01:00
Mario Vavti
8e4960f31d use openClose() for nav-login 2017-02-03 09:33:09 +01:00
Mario Vavti
dd2a5e6b28 Merge branch 'dev' into wip-app-bin 2017-02-03 09:24:09 +01:00
zotlabs
7e1e9ac94a rename bb2diaspora.php to markdown.php 2017-02-02 19:12:48 -08:00
zotlabs
29daf1ecee unused since 2012 2017-02-02 18:16:44 -08:00
zotlabs
c62df39ce3 move firefox social api configuration to plugin 2017-02-02 17:23:58 -08:00
zotlabs
a91e7cbe8d move rsd service to twitter_api plugin 2017-02-02 15:25:35 -08:00
zotlabs
159f02ba07 build_pagehead hook added 2017-02-02 14:52:14 -08:00
zotlabs
2daafe80a5 move opensearch to plugins 2017-02-02 14:49:51 -08:00
Mario Vavti
028b2a655d whitespace cleanup 2017-02-02 20:39:06 +01:00
Mario Vavti
fd52cefe09 provide separate collased menus for apps and notifications 2017-02-02 20:10:35 +01:00
Mario Vavti
0e0dee43ab Merge branch 'dev' into wip-app-bin 2017-02-02 14:27:13 +01:00
Mario Vavti
e2ee565f05 cherry-pick nav-login changes 2017-02-02 14:24:19 +01:00
Mario Vavti
63e06578c4 use bootstrap dropdown for login 2017-02-02 14:19:23 +01:00
Mario Vavti
a1f03015ec move channel manager up in the menu 2017-02-02 11:35:42 +01:00
Mario Vavti
8220a6584c remove apps from usermenu 2017-02-02 11:19:06 +01:00
Mario Vavti
d4b51c491f do not use style in template 2017-02-02 10:59:20 +01:00
Mario Vavti
3f66d9f8cd do not use data-toggle on the badge and use fixed with for icons 2017-02-02 10:54:44 +01:00
Mario Vavti
852073fc68 dropdown menus should be restricted in height in normal view but not in collapsed view 2017-02-02 10:33:23 +01:00
Mario Vavti
17082cda3c remove badge hover effect 2017-02-02 10:15:05 +01:00
Mario Vavti
7ffa98118f really fix badge positions 2017-02-02 10:12:56 +01:00
Mario Vavti
c3bada3c32 resolve merge conflict 2017-02-02 09:38:07 +01:00
zotlabs
23303391e0 move dreamhost hack to plugin 2017-02-01 22:45:03 -08:00
zotlabs
8ac8acc49c drug dealers have users 2017-02-01 18:18:41 -08:00
zotlabs
94290102b6 tested extensible permissions by adding wiki permissions. Discovered a couple of issues that needed attention in the process. 2017-02-01 18:05:02 -08:00
zotlabs
f94c244b9f Merge pull request #664 from anaqreon/doco
Doco updates
2017-02-02 12:52:09 +11:00
Andrew Manning
ec823196e0 Remove old tags and mentions doco pages 2017-02-01 20:47:03 -05:00
Andrew Manning
957647bf06 Remove dead links 2017-02-01 20:43:47 -05:00
Andrew Manning
df5524979d Integrate tags and mentions page doco into member guide. Fix bug when loading page with section link. Change URL when scrolling to stay current with viewed section to facilitate easy help page link sharing. 2017-02-01 20:39:27 -05:00
Andrew Manning
0ae3e50bd4 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-02-01 20:07:38 -05:00
zotlabs
db710cd2df fix a few style issues with nav login panel 2017-02-01 14:45:52 -08:00
Andrew Manning
61407ad6c8 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-02-01 17:08:46 -05:00
Mario Vavti
2e0180ba55 Merge branch 'dev' into wip-app-bin 2017-02-01 22:36:25 +01:00
Mario Vavti
d476b7477b fix notifications badge positioning and rendering of submenus in collapsed mode 2017-02-01 22:24:37 +01:00
zotlabs
ec037abf92 bookmarks missing from tags and mentions doc 2017-02-01 11:29:18 -08:00
Mario Vavti
1a56045b42 nav dropdown-menu overrides 2017-02-01 13:08:41 +01:00
Mario Vavti
bf820beb79 remove experimental_app_bin config conditional 2017-02-01 12:59:56 +01:00
Mario Vavti
cde7a3f66c more work on app-bin 2017-02-01 12:52:19 +01:00
zotlabs
4f99d641c5 superfluous whitespace cleanup 2017-01-31 17:32:52 -08:00
zotlabs
f4aca35a88 move diaspora account import to the diaspora plugin 2017-01-31 16:01:47 -08:00
zotlabs
732065bf13 channel export - use a selected list of functional data categories to export; this allows one to export single data sets instead of always exporting everything we know about 2017-01-31 15:28:25 -08:00
Andrew Manning
d3d540a28b Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-01-31 17:36:42 -05:00
Mario Vavti
a6cbebe03c hide featured app category in the app category widget 2017-01-31 12:53:33 +01:00
Mario Vavti
e1b54b6843 fix typos 2017-01-31 09:43:58 +01:00
zotlabs
aadbd5a92d Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-30 15:05:10 -08:00
zotlabs
7b065365e0 consolidate hubloc storage 2017-01-30 15:01:22 -08:00
Mario Vavti
d0827dbb3c provide a feature/unfeature app button 2017-01-30 15:17:46 +01:00
Andrew Manning
fab103524a Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-01-30 06:03:53 -05:00
zotlabs
15be542e56 Merge pull request #662 from anaqreon/affinity-settings
Affinity settings
2017-01-30 18:04:53 +11:00
zotlabs
eebea70019 queue optimisations for sites that have lingered in the queue for more than a couple of days. 2017-01-29 17:16:06 -08:00
Andrew Manning
b58d56826b Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-01-29 20:02:34 -05:00
Andrew Manning
e770768b79 Link to Guest Access Tokens doco in context help. 2017-01-29 20:02:31 -05:00
Andrew Manning
17011a7637 Remove unrelated chatroom panel stuff that was included accidentally 2017-01-29 19:56:19 -05:00
Andrew Manning
f891860408 Merge remote-tracking branch 'upstream/dev' into affinity-settings 2017-01-29 19:53:41 -05:00
Andrew Manning
3424c7dc87 Add affinity slider tool settings for min and max defaults in settings/featured 2017-01-29 19:53:29 -05:00
zotlabs
dbf7ff9791 no quotes on dbutcnow() output 2017-01-29 16:33:30 -08:00
zotlabs
9addcfe827 finish remaining places where xchan_store_lowlevel needs to be used 2017-01-29 15:25:24 -08:00
zotlabs
d5d67708ac Alter the queue so that each queue item stores the scheduled time of the next delivery. This keeps the query for
queued items simple. We no longer group by posturl; as the queue update function will only keep one item per destination
scheduled for shorter term processing. Others (multiple queued items for a single destination) will be scheduled for
delivery far into the future and only delivered if the hub responds to the "active" or short term queue item.
2017-01-29 14:45:25 -08:00
zotlabs
5aa0017e91 provide lowlevel xchan storage function to ensure that all non-null rows are initialised 2017-01-28 15:01:19 -08:00
zotlabs
f90d5f3dc8 string update 2017-01-27 12:13:30 -08:00
Mario Vavti
8b5793e629 more work on app-bin 2017-01-27 17:51:49 +01:00
Mario Vavti
de668f5999 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-01-27 14:00:43 +01:00
Mario Vavti
606463114b add icons and links to appman and apps edit to app-bin 2017-01-27 14:00:27 +01:00
Andrew Manning
40242ff7dc Merge remote-tracking branch 'upstream/dev' into addon-repo-gui 2017-01-27 07:21:52 -05:00
Andrew Manning
e411c7e8b3 Improve context help with screenshot and replace "addon" with "plugin". 2017-01-27 07:21:23 -05:00
zotlabs
80e1130bb5 Merge pull request #655 from anaqreon/addon-repo-gui
Addon repo management GUI
2017-01-27 13:27:36 +11:00
Andrew Manning
d9a5b11c9a Fixed numerous bugs with the addon repo management GUI. Only show Manage Repos button if webserver has write permission on extend/addon/. 2017-01-26 21:20:15 -05:00
zotlabs
22839e48d0 better handling of html special chars in wiki and wikipage names 2017-01-26 15:16:41 -08:00
Mario Vavti
f7f39cf6c0 missing single quote in query 2017-01-26 14:50:52 +01:00
Mario Vavti
54826808cf minor cleanup 2017-01-26 12:23:59 +01:00
Mario Vavti
b30e799847 query for item_hidden is not needed anymore 2017-01-26 11:43:21 +01:00
Mario Vavti
b4aaa1953c fix wiki list template 2017-01-26 11:24:15 +01:00
Mario Vavti
d64dcd298e haystack/needle mixup 2017-01-26 11:03:41 +01:00
Mario Vavti
02e8058c50 fix renaming of wiki pages 2017-01-26 10:46:44 +01:00
zotlabs
93057fae8c missing quote in nav template 2017-01-25 21:43:55 -08:00
zotlabs
5bc6941b57 resolve the linked item delete issue by declaring what types of linked items cannot be deleted 2017-01-25 14:40:04 -08:00
zotlabs
45dbd31d28 only allow wiki owner to delete pages 2017-01-25 12:21:52 -08:00
zotlabs
45a9eca792 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-25 11:47:51 -08:00
zotlabs
b43064ce6e roll minor version 2017-01-25 11:46:59 -08:00
zotlabs
660c658c85 initialise item['postopts'] for mysql >= 5.7 2017-01-25 11:46:33 -08:00
zotlabs
7804ae6a78 initialise item['postopts'] for mysql >= 5.7 2017-01-25 11:43:54 -08:00
zotlabs
c916906716 Merge pull request #653 from git-marijus/dev
fixes for wiki create/delete page
2017-01-26 06:37:35 +11:00
Mario Vavti
1db57c498d fixes for wiki create/delete page 2017-01-25 19:41:47 +01:00
zotlabs
54f7cd5302 typo 2017-01-24 20:17:05 -08:00
zotlabs
9e70d54300 always sync parent wiki when syncing pages, just in case the original wiki creation wasn't synced. 2017-01-24 20:14:58 -08:00
zotlabs
7465ca269b Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2017-01-24 19:44:55 -08:00
zotlabs
508157f07f block well-known from oembed 2017-01-24 19:44:45 -08:00
zotlabs
33aa373b3f minor 2017-01-24 19:44:24 -08:00
zotlabs
d96a7bc1fa block well-known from oembed 2017-01-24 18:33:41 -08:00
zotlabs
dad8397763 initial selections for extensible permission categories ("permcats") 2017-01-24 16:00:58 -08:00
Mario Vavti
e26295b6fa do not show location row on small viewports. 2017-01-24 10:26:50 +01:00
Mario Vavti
c8239c739d do not show location row on small viewports. 2017-01-24 10:25:31 +01:00
zotlabs
6c4f7caba1 nav-login - basic, crude theming 2017-01-23 16:51:23 -08:00
zotlabs
cb47354a4f put login form into the nav bar. Proof of concept - needs a bit of UI tweaks. 2017-01-23 16:31:40 -08:00
zotlabs
61588a4b77 add observer.language to the doco 2017-01-23 15:42:41 -08:00
zotlabs
142dd0053a Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-23 11:37:18 -08:00
zotlabs
0d9e12737a remnant code that checked for version to see if an app was installed. We do that differently now. 2017-01-23 11:36:28 -08:00
Mario Vavti
dfafa81bfe give apps a bit more horizontal space 2017-01-23 17:10:52 +01:00
Hubzilla
cda284424f synced wikis should be relocated 2017-01-22 18:56:14 -08:00
Hubzilla
610699d3c4 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-22 18:53:13 -08:00
Hubzilla
17f1d39fcf basic support for clone syncing of wikis and wiki pages 2017-01-22 18:48:45 -08:00
zotlabs
85766126e3 Merge pull request #650 from mjfriaza/dev
Translation of the new strings into the Spanish version
2017-01-23 12:07:16 +11:00
Hubzilla
3bafa05ad1 force app icons to fixed width 2017-01-22 16:09:55 -08:00
Hubzilla
1627297143 use icons for app photos. 2017-01-22 15:17:37 -08:00
Mario Vavti
951376852c some work on app_bin - just to get it going 2017-01-22 13:45:34 +01:00
Manuel Jiménez Friaza
4d3647066f Translation of the new strings into the Spanish version 2017-01-22 12:13:28 +01:00
Mario Vavti
9e509aa25b $a is deprecated 2017-01-22 10:21:01 +01:00
Mario Vavti
d2226c0e9b whitespace cleanup 2017-01-22 10:20:39 +01:00
Hubzilla
1d65bc6382 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-21 15:24:09 -08:00
Hubzilla
b513662b52 remove the channel introduction on the system notifications page. "Hubzilla, George commented on your status 20 minutes ago". We need the channel introduction (in this case "Hubzilla," in emails for situations where one person controls a lot of channels. We don't need it on the web notification summary; where you're only viewing notifications for a single given channel. 2017-01-21 15:20:59 -08:00
Mario Vavti
8794106e85 add observer.language to autocomplete and return a default value for observer 2017-01-21 23:28:57 +01:00
Mario Vavti
88caa14030 fix text highlighter for PHP version 7.1 2017-01-21 21:04:36 +01:00
Hubzilla
bb233a9872 add bbcode language conditionals to wiki 2017-01-20 15:42:15 -08:00
Hubzilla
9acd3ebd42 observer.language!={something} for completeness 2017-01-20 15:30:08 -08:00
Hubzilla
0368b6730f language aware content 2017-01-20 13:36:37 -08:00
Hubzilla
ece1dd1d7e js errors with raw message-id, string update 2017-01-20 12:03:46 -08:00
Hubzilla
f57926d9ec Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-19 15:40:28 -08:00
Hubzilla
96f196febd add gen_link_id() function to selectively encode/decode the message-id component of /display/ links for message-ids that contain troublesome characters 2017-01-19 15:37:30 -08:00
Mario Vavti
4295b1945e we need channel_id here not the whole channel 2017-01-19 10:02:26 +01:00
Hubzilla
5ce96b9b95 more urlencoding of message-ids which are used in links 2017-01-18 19:36:06 -08:00
Hubzilla
7dfadfea4a urlencode the message-id component of generated /display/ links; in most cases this will be a no-op, unless the message-id is a url of some kind from a different provider. 2017-01-18 18:45:17 -08:00
Hubzilla
d4e58e94f6 native wiki updates 2017-01-18 18:18:37 -08:00
Hubzilla
6e504b7bc9 nwiki updates 2017-01-18 17:45:27 -08:00
zotlabs
7f944515de more work on native wiki - revert now works; still remaining: diff, delete-page, rename-page and export wiki. 2017-01-17 23:39:28 -08:00
zotlabs
b6595a44d1 native wiki stuff 2017-01-17 17:41:19 -08:00
zotlabs
335d9af8dc daemon_addon hook - lets plugins create custom background processes. 2017-01-17 00:14:47 -08:00
zotlabs
8478ecc675 Merge pull request #645 from git-marijus/dev
do not choke if photo_factory() returns null
2017-01-16 18:31:09 +11:00
zotlabs
e5662dc893 vcard export from profile 2017-01-15 21:23:43 -08:00
zotlabs
0ef2cd8719 array pointer in wrong place 2017-01-15 19:55:59 -08:00
zotlabs
c32bc9dda4 more integration of vcard and profiles 2017-01-15 19:51:14 -08:00
zotlabs
d7080defd3 Still trying to make the documentation link just a wee bit more obvious. 2017-01-15 16:08:51 -08:00
zotlabs
b20cce1408 attach_delete() - remove photo resources even if the attach table row wasn't found. 2017-01-15 15:24:51 -08:00
Mario Vavti
9682c48b5b min version bump 2017-01-15 13:53:56 +01:00
git-marijus
6a242f0d08 Merge pull request #646 from anaqreon/doco
Make master doco current with dev doco
2017-01-15 13:50:18 +01:00
Andrew Manning
b1f3ccc6ee pull in some CSS 2017-01-15 07:27:48 -05:00
Mario Vavti
a36d74dad5 do not choke if photo_factory() returns null 2017-01-15 13:23:28 +01:00
Andrew Manning
128d47430d pull latest doco from dev branch 2017-01-15 07:22:19 -05:00
zotlabs
e843d27f8c Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-13 13:23:21 -08:00
zotlabs
4f1e4ffa70 several minor app nits 2017-01-13 13:22:36 -08:00
zotlabs
7249eebc75 string update 2017-01-13 04:12:21 -08:00
Mario Vavti
8ea0b2051a another try on preventing double scrollbars when a modal is larger than the viewport 2017-01-13 13:04:30 +01:00
Mario Vavti
c8678ba5a9 evert "prevent double scrollbar when we have a modal larger than the viewport"
This reverts commit 2ace4c57d0.
2017-01-13 12:53:45 +01:00
Mario Vavti
2ace4c57d0 prevent double scrollbar when we have a modal larger than the viewport 2017-01-13 11:24:34 +01:00
Mario Vavti
8ef84e2aa7 possibly improve the album list query and save the result in App::$data 2017-01-13 11:22:50 +01:00
zotlabs
bb0f3afb71 default cover photo support. 2017-01-12 18:52:29 -08:00
zotlabs
9fb8661eef missing protect_sprintf which is the source of issue #642 - if a mention search contains % it will result in an SQL vsprintf error 2017-01-12 13:05:36 -08:00
Mario Vavti
91b81d6a2c fullscreen in album-view is disfunctional atm 2017-01-12 15:29:49 +01:00
Mario Vavti
88ac326caf we should actually check for existance of a given album at this place. this query can probably be more simple though 2017-01-12 12:32:31 +01:00
Mario Vavti
bdd420a08e Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2017-01-11 22:16:19 +01:00
Mario Vavti
76daa03df0 comment out redundant querys 2017-01-11 22:16:02 +01:00
zotlabs
62ad4dd109 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-11 12:32:19 -08:00
zotlabs
41dc40dd84 expires lost during edit 2017-01-11 12:31:55 -08:00
Mario Vavti
2fc47cc52b fix embedimage if an albumname contains quotes 2017-01-11 10:59:46 +01:00
zotlabs
9ad44a2060 btlogger trace file logging not working as desired. 2017-01-10 17:37:41 -08:00
zotlabs
5092cb75f4 normalise feed id 2017-01-10 14:25:11 -08:00
zotlabs
f2f6a05342 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-10 11:22:32 -08:00
zotlabs
52441dd754 add gravizot.de to directory server fallbacks 2017-01-10 11:21:51 -08:00
Mario Vavti
38dd1c342a font awesome 4.7.0 2017-01-10 10:19:22 +01:00
Mario Vavti
0f89db3b46 /connedit do not show vcard and section selector if not yet approved. whitespace cleanup 2017-01-10 10:15:48 +01:00
zotlabs
120afb30c1 obj_type on edit activity was wrong 2017-01-09 22:12:44 -08:00
zotlabs
47bc573de5 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-09 14:38:49 -08:00
zotlabs
a6272fcf76 channel move stuff (disabled currently because not yet complete) 2017-01-09 14:37:56 -08:00
Mario Vavti
b8f0e565f5 implement a menu to select a section to be open by default 2017-01-09 12:03:32 +01:00
zotlabs
83c9753507 Merge pull request #640 from mjfriaza/dev
Updated the Spanish translation
2017-01-09 08:37:20 +11:00
zotlabs
91e0733e8e Comanche: add greater/less than (plus greater/less than or equal) conditionals 2017-01-07 16:14:04 -08:00
zotlabs
dd97d84c19 Comanche conditionals - provide a conditional "~=" form for testing 'contains' (case independent substring match). Also add $request the request uri) to the supported variables. 2017-01-07 15:58:01 -08:00
zotlabs
b2a4075e12 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-07 13:58:29 -08:00
zotlabs
96e668a5b9 add enclosures and categories to atom feed 2017-01-07 13:29:32 -08:00
zotlabs
c9f4184126 allow the atom_entry hook to change the results 2017-01-07 12:47:19 -08:00
zotlabs
6f1209ea49 typo 2017-01-07 04:51:44 -08:00
zotlabs
89f0ecf25d update the atom_entry hook 2017-01-07 04:04:11 -08:00
Manuel Jiménez Friaza
eca70d81c8 Updated the Spanish translation 2017-01-07 12:26:54 +01:00
Mario Vavti
639966622f min version bump 2017-01-07 10:09:45 +01:00
Mario Vavti
be7e249630 fix main width if right aside is hidden 2017-01-07 10:07:50 +01:00
Mario Vavti
d1493e6b70 fix main width if right aside is hidden 2017-01-07 10:07:05 +01:00
zotlabs
fb059bfdc3 more feedutils cleanup 2017-01-06 20:20:49 -08:00
zotlabs
a3c45d47e6 add the ostatus:conversation element which is now more or less required by GNU-Social to work around some short-comings of the OStatus delivery model when it comes to conversational message grouping. If this element isn't there, message replies will not get grouped with the parent specified in thr:in-reply-to, which exists to group conversations together. The reasoning being that due to the point-to-point delivery model, a reply could arrive on one site which does not have a copy of the parent specified by thr:in-reply-to. Hence further replies arriving on this site are grouped with the first arrived comment as the parent. Since this project doesn't allow comments which don't have top-level parents, we can just set it to the parent-mid and save being forced to create a new database structure for orphan children acting as parents. 2017-01-06 13:42:45 -08:00
zotlabs
6db2561eda preserve the original message-id coming from feeds - we will have to escape them properly before calling mod_display. 2017-01-06 13:25:57 -08:00
zotlabs
ba2d0fae0e Merge branch 'dev' into gnusoc 2017-01-06 12:24:26 -08:00
zotlabs
7f9e91f1c7 strings 2017-01-06 12:19:41 -08:00
zotlabs
2312302dea setup: check disabled functions more precisely than using a string match 2017-01-05 14:17:56 -08:00
zotlabs
dfede52048 ical import/export - provide mechanism to preserve original source formatting across zot based systems. 2017-01-05 13:55:04 -08:00
zotlabs
a87d12f167 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-05 12:19:14 -08:00
zotlabs
ec18c3770b issue #639, voting setting is lost after post is edited (also the disabling of comments) 2017-01-05 12:17:36 -08:00
Mario Vavti
3e0ea9727f same fix for mobile view 2017-01-05 17:55:25 +01:00
Mario Vavti
e64378f94f same fix for mobile view 2017-01-05 17:54:44 +01:00
Mario Vavti
888a7aa6b2 another min version bump 2017-01-05 17:43:24 +01:00
Mario Vavti
9cf2f424ad fix an issue with sticky_kit where input fields and textareas would blur on recalc. auto resize the notes textarea since if it sticks to the bottom it can not be properly resized 2017-01-05 17:42:30 +01:00
Mario Vavti
a1b35fb7d1 fix an issue with sticky_kit where input fields and textareas would blur on recalc. auto resize the notes textarea since if it sticks to the bottom it can not be properly resized 2017-01-05 17:40:45 +01:00
zotlabs
982b596fa4 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2017-01-04 15:29:14 -08:00
zotlabs
1ce8168d72 some gnusoc fixes 2017-01-04 11:47:08 -08:00
Mario Vavti
93ce2728b7 css fix 2017-01-04 16:40:11 +01:00
Mario Vavti
0364bf4913 css fix 2017-01-04 16:39:14 +01:00
Mario Vavti
48813c55d5 bump min version 2017-01-04 15:52:59 +01:00
Mario Vavti
a9a35ccb6b trigger sticky_kit:recalc if the size of left_aside_wrapper changes 2017-01-04 15:50:17 +01:00
Mario Vavti
4d5c20ce17 fix expand-aside button hiding if aside is empty 2017-01-04 15:50:13 +01:00
zotlabs
ced84a2b01 zot protocol doco updates 2017-01-03 12:59:05 -08:00
jeroenpraat
6a0055f69f Fixing some schemas 2017-01-03 21:07:49 +01:00
Mario Vavti
07b299abd2 trigger sticky_kit:recalc if the size of left_aside_wrapper changes 2017-01-03 17:56:40 +01:00
zotlabs
ae563e2b1c fix chat member list when one or members are connected via access tokens 2017-01-02 23:35:40 -08:00
zotlabs
1ceca4ae19 set 'adjust for viewer timezone' as the default for new events. 2017-01-02 14:13:02 -08:00
git-marijus
fa611b3616 Merge pull request #637 from anaqreon/dev
Guest access tokens
2017-01-02 20:08:51 +01:00
Andrew Manning
bc0d4f28ef Merge remote-tracking branch 'upstream/dev' into dev 2017-01-02 07:56:23 -05:00
zotlabs
369a29ac90 new roadmap 2017-01-01 22:33:18 -08:00
zotlabs
b88a735e54 feature: allow event creation in other timezones than your own. 2017-01-01 19:51:44 -08:00
zotlabs
dca4de80fd Merge branch 'pcard' into dev 2017-01-01 14:16:15 -08:00
zotlabs
bead3e6095 profile vcard - generate vcard on profile update 2017-01-01 14:15:07 -08:00
zotlabs
1436b075bf issue #636 - some localised (e.g. Italian) strings have single quotes which throw JS errors when used in single quoted template constructs. 2017-01-01 13:46:20 -08:00
zotlabs
9831b358f8 profile vcard - preliminary work 2017-01-01 13:29:27 -08:00
Andrew Manning
7b11e634aa Merge remote-tracking branch 'upstream/dev' into dev 2017-01-01 14:28:21 -05:00
Andrew Manning
dce5c7e249 Add guest access token section to member guide with screenshot of settings 2017-01-01 14:28:13 -05:00
Andrew Manning
7f60ab49b2 Merge pull request #634 from anaqreon/dev
I'm going to go ahead and merge this. It should be easy to revert undesired changes.
2017-01-01 08:06:30 -05:00
Andrew Manning
d1d3dcf1a0 Deleted old versions that have been integrated. Integrated and slightly revised Comanche doco. 2017-01-01 08:00:43 -05:00
Andrew Manning
ce87a0c1d3 Merge remote-tracking branch 'upstream/dev' into dev 2017-01-01 07:41:36 -05:00
zotlabs
75067524ae Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-12-31 16:03:52 -08:00
zotlabs
1cd779459b better fix for #629 #635 based on ownership/authorship rather than message flags which could be forged 2016-12-31 16:03:41 -08:00
zotlabs
e2eb0b2eac better fix for #629 #635 based on ownership/authorship rather than message flags which could be forged 2016-12-31 15:56:45 -08:00
zotlabs
709bcedbed Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-31 13:39:40 -08:00
zotlabs
444e938e2d issues #629, #635 - edited post arriving from downstream source was not being rejected 2016-12-31 13:38:19 -08:00
Mario Vavti
9820baf82e fix expand-aside button hiding if aside is empty 2016-12-31 12:55:10 +01:00
Mario Vavti
7f2c7cacd3 bump min version 2016-12-31 09:44:27 +01:00
Mario Vavti
62a911a57e prevent eventual double scrollbar 2016-12-31 09:44:16 +01:00
Mario Vavti
fcd34e41ca css fixes and get rid of a javascript workaround 2016-12-31 09:44:09 +01:00
zotlabs
ba8a5ac82b peoplefind widget should honour directory option settings (such as this site only). 2016-12-30 13:31:59 -08:00
zotlabs
e5a6c0a94d Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-30 13:12:56 -08:00
zotlabs
a9c8d4a216 peoplefind widget should honour directory option settings (such as this site only). 2016-12-30 13:09:35 -08:00
Mario Vavti
6c7da13cd3 prevent eventual double scrollbar 2016-12-30 20:50:12 +01:00
Andrew Manning
2ba23ebb13 Reorganized and revised Zot Protocol content. Deleted some of the old pages that have been refactored. 2016-12-30 09:10:26 -05:00
Mario Vavti
74d69bdedc Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-12-30 13:35:59 +01:00
Mario Vavti
8a074dedb6 css fixes and get rid of a javascript workaround 2016-12-30 13:35:43 +01:00
zotlabs
3dd4bf9955 move api version call back to core 2016-12-30 02:48:42 -08:00
zotlabs
2e2254371a move api version call back to core 2016-12-30 02:45:16 -08:00
zotlabs
693f7366a2 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-30 02:36:24 -08:00
zotlabs
b673c804be profile clone issue with dev 2016-12-30 02:34:26 -08:00
zotlabs
03a1086ba3 logger typos 2016-12-30 02:32:53 -08:00
zotlabs
e8a2ad4315 logger typos 2016-12-30 02:31:53 -08:00
Mario Vavti
c9cbd2f4f6 update fullcalendar to version 3.1 2016-12-30 10:18:05 +01:00
zotlabs
90a99fc221 Merge pull request #633 from anaqreon/dev
Doco
2016-12-29 14:52:01 +11:00
Andrew Manning
a649c3b72e Merge remote-tracking branch 'upstream/dev' into dev 2016-12-28 19:41:09 -05:00
Andrew Manning
caec5d81eb Split Zot protocol and API into two pages. Revise text to add detail and improve presentation. 2016-12-28 19:40:53 -05:00
zotlabs
e4ec976a1f Merge pull request #632 from anaqreon/dev
Zot structures doco integrated into the Zot page.
2016-12-29 07:13:53 +11:00
Andrew Manning
13768fdb9b Zot structures doco integrated into the Zot page. Added nowrap option to [code] BBcode tag. 2016-12-28 14:58:25 -05:00
zotlabs
46e4bd5fe0 Merge pull request #631 from anaqreon/dev
Add webpage doco to Member guide. Add nav menu highlighting when scro…
2016-12-28 12:03:59 +11:00
Andrew Manning
95683c6239 Add webpage doco to Member guide. Add nav menu highlighting when scrolling past content 2016-12-27 19:57:53 -05:00
zotlabs
db9ea66069 Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-12-27 15:28:52 -08:00
zotlabs
ef02464e3c issue with HTML in code blocks in markdown in wiki 2016-12-27 15:28:42 -08:00
zotlabs
d29bd4b054 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-27 15:27:38 -08:00
zotlabs
17b7042a25 issue with HTML in code blocks in markdown in wiki 2016-12-27 15:26:47 -08:00
Andrew Manning
75afb37987 Merge pull request #630 from anaqreon/dev
BBcode reference page is essentially complete.
2016-12-27 07:37:13 -05:00
Andrew Manning
528a66fc97 Revert parseIdentityAwareHTML() 2016-12-27 07:35:33 -05:00
Andrew Manning
b245311a7e Revert parseIdentityAwareHTML() 2016-12-27 07:34:47 -05:00
Andrew Manning
4b2ef39648 BBcode reference page is essentially complete. There is still room for improvement. 2016-12-27 07:32:39 -05:00
zotlabs
286c3eafe3 minor cleanup 2016-12-26 14:17:40 -08:00
zotlabs
3bb6c667db Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-26 13:11:54 -08:00
zotlabs
b530d1d449 perform input validation on xchan_store and re-enable the post method of the xchan api endpoint. 2016-12-26 13:10:24 -08:00
zotlabs
fdbb5b67a8 Merge pull request #628 from anaqreon/dev
Doco revisions
2016-12-27 07:29:57 +11:00
Andrew Manning
67f09fb1d6 Almost completed reconstruction of bbcode reference page 2016-12-26 14:59:18 -05:00
Andrew Manning
1a5dd5c87c Updated markup language support doco. Modified parseIdentityAwareHTML BBcode parsing to support the BBcode reference which is now in /help/member/bbcode.html. Add Bootstrap classes to tables for BBcode tables that have the border=0 or border=1 options set. 2016-12-26 08:58:40 -05:00
Andrew Manning
c2a189ab18 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-12-26 06:52:56 -05:00
zotlabs
56219f9f61 create first webpage as 'home' if none exist. 2016-12-25 14:40:50 -08:00
zotlabs
c38e7ee3e3 show webpages link to visitors if a 'home' page exists. This means the nav menu must be used to edit pages. 2016-12-25 14:26:27 -08:00
Andrew Manning
5e490ed8b7 Fix broken link 2016-12-25 12:59:34 -05:00
zotlabs
9f9b1d3ce6 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-24 15:02:03 -08:00
zotlabs
35ed9b9b72 issue with post signatures if posted from api and logged in locally with a different identity. 2016-12-24 15:00:37 -08:00
Mario Vavti
4ab2d46113 update changelog 2016-12-23 10:07:12 +01:00
zotlabs
1e53528363 Merge pull request #627 from anaqreon/dev
Merging proposed changes to 2.0RC for doco revisions
2016-12-23 15:35:12 +11:00
Andrew Manning
5d8334d7f4 Merging proposed changes to 2.0RC for doco revisions 2016-12-22 21:49:16 -05:00
Mario Vavti
3629468d47 move style info into css file 2016-12-22 15:20:02 +01:00
Mario Vavti
c5d6f58988 another check 2016-12-22 15:01:29 +01:00
Mario Vavti
6cb527a937 a cleaner way to work around browser bugs 2016-12-22 14:55:05 +01:00
Mario Vavti
2ce6d47519 more robust crossbrowser support 2016-12-22 11:54:04 +01:00
zotlabs
f2bfdfdedd provide separate logging (if configured) for btlogger which is used to catch really subtle issues which don't always leave an audit trail. Similar to dbfail.out, the file btlogger.out (if it exists and is write-able) will only log these unusual situations with backtraces so we can find the culprits. 2016-12-21 23:35:54 -08:00
zotlabs
9d49faca61 update util/hz to use zot api instead of the (now optional) twitter api 2016-12-21 16:44:33 -08:00
zotlabs
bb85e139f1 more vcard work 2016-12-21 15:03:33 -08:00
Mario Vavti
fcc92299eb css fixes 2016-12-21 12:55:49 +01:00
Mario Vavti
04472bd730 fix a glitch in sticky-kit and comment out alt_pager() in widget_conversations since it will not work there 2016-12-21 11:51:24 +01:00
Mario Vavti
e91a4bebed update changelog 2016-12-21 10:15:14 +01:00
zotlabs
3d811a17fe provide call button on connections list if mobile|tablet and a phone number exists 2016-12-20 23:26:31 -08:00
zotlabs
f3ec818a66 abook_vcard cleanup 2016-12-20 20:37:06 -08:00
zotlabs
a270ca5101 allow update of fn and initial setting from channel name 2016-12-20 19:31:50 -08:00
zotlabs
493aa9f20d progress on abook_vcard 2016-12-20 18:43:20 -08:00
zotlabs
6ff462abf3 more abook_vcard 2016-12-20 17:19:53 -08:00
zotlabs
4103344e48 abook_vcard first commit 2016-12-20 16:45:12 -08:00
Mario Vavti
7b7fa5f77b turns out we do need this in certain situations 2016-12-20 14:53:58 +01:00
Mario Vavti
4d478a3306 some changes to heading sizes to make some sense in the doco (this will undergo some refinement in the next release cycle when we possibly upgrade to bootstrap 4) and get rid of the accordion for now. 2016-12-20 11:37:57 +01:00
Andrew Manning
90dfa2ccaf More heading work and some content rearrangement. 2016-12-19 19:35:36 -08:00
Andrew Manning
c968d11943 Move headings down to start at H3 at Mario's direction 2016-12-19 19:35:19 -08:00
zotlabs
e0918816fb Merge pull request #622 from mjfriaza/dev
Translated new strings into Spanish version
2016-12-20 14:32:01 +11:00
zotlabs
d2cc7df7db allow tel: links on mobile devices 2016-12-19 18:59:40 -08:00
zotlabs
231b70b987 call zidify_links() when formatting bbcode for internal consumption 2016-12-19 16:06:49 -08:00
zotlabs
1798ebd395 improve oembed cache security 2016-12-19 15:38:42 -08:00
zotlabs
b1f4ea6206 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-19 14:35:44 -08:00
zotlabs
350627988e zidify private mail 2016-12-19 14:35:13 -08:00
Mario Vavti
3fe616b8fe Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-12-19 20:36:56 +01:00
Mario Vavti
a12b2c8d33 fix contextualHelpFocus() to work wit sticky aside 2016-12-19 20:36:40 +01:00
jeroenpraat
468fb3c77a Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-12-19 16:52:17 +01:00
jeroenpraat
3a4bd27333 Update NL strings 2016-12-19 16:51:30 +01:00
Mario Vavti
3ad3d3037f make sticky aside available for small screens. we had to get rid of the transition effect for this to work reliably 2016-12-19 12:46:36 +01:00
Mario Vavti
9c5f2de4ec this is not needed 2016-12-19 09:48:01 +01:00
zotlabs
ca2e2f5f45 deprecate bb_iframe 2016-12-18 22:33:23 -08:00
zotlabs
92f3d863fa re-factor item_photo_menu - there is some room for future development, currently it was made compatible with minimal template changes 2016-12-18 16:26:00 -08:00
Manuel Jiménez Friaza
5970df0606 Translated new strings into Spanish version 2016-12-17 13:20:04 +01:00
zotlabs
e1819a874f use darkorange. 2016-12-16 22:47:25 -08:00
zotlabs
0c665e11f1 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-16 19:57:49 -08:00
zotlabs
827d4c5fb0 use lock colour to indicate that permissions have been set by the software to something you might not expect rather than an exclamation mark. This may not be the best colour in this page context, but it serves the intended purpose. Perhaps orange might be less intrusive and still convey the desired information. 2016-12-16 19:54:07 -08:00
zotlabs
e46fcc2893 string update 2016-12-16 19:52:19 -08:00
Mario Vavti
6eed7eb540 display inline instead of floating 2016-12-16 22:50:19 +01:00
Mario Vavti
dc34bf18bb retrigger after fullscreen 2016-12-16 16:24:17 +01:00
Mario Vavti
6bde70d60a move the sticky-kit^Cquery plugin to /lib and see if we want this for the whole app 2016-12-16 16:14:56 +01:00
Mario Vavti
5252211c92 some fixes for doco nav 2016-12-16 11:49:27 +01:00
zotlabs
1d63654662 there are occasional sites which use different capitalisation of Content-Type; which is rare, but completely legal. 2016-12-15 18:08:23 -08:00
zotlabs
6cf17c7bcc use array_shift - it's cleaner 2016-12-15 16:41:01 -08:00
zotlabs
95485a0da2 z_fetch_url incorrect variable 2016-12-15 16:02:52 -08:00
zotlabs
f67acc82cf html2plain warnings 2016-12-15 13:45:27 -08:00
Mario Vavti
e2f1ce7758 note widget: whitespace and resize the textarea to reveal full content 2016-12-15 14:50:26 +01:00
Mario Vavti
273ab304b9 reworked doco navigation 2016-12-15 12:25:59 +01:00
Mario Vavti
2a2a4b96c7 more wiki cleanup 2016-12-15 10:56:16 +01:00
zotlabs
b630a01131 Merge pull request #600 from toppoint/dev
Configuring email notifications per channel
2016-12-15 15:56:52 +11:00
ilu33
f25189fc74 Drop on switch for notifications 2016-12-15 05:55:23 +01:00
zotlabs
00fc66d8e8 postgres is picky about this stuff 2016-12-14 20:51:10 -08:00
ilu33
97f17374f2 Missing single quotes 2016-12-15 05:47:02 +01:00
xxx
f16b19faf3 Merge branch 'dev' of https://github.com/toppoint/hubzilla into dev 2016-12-15 04:59:54 +01:00
ilu33
4ce16e9e91 Configuring email notifications per channel 2016-12-15 04:56:34 +01:00
zotlabs
bae28965ab issue #446 apps usability - disable app if attached to a plugin that is uninstalled, allow system apps to be soft deleted and undeleted from the edit pane. 2016-12-14 19:11:01 -08:00
zotlabs
63efbdffe6 markdown regex 2016-12-14 14:27:00 -08:00
Mario Vavti
a7af6d8a3c fix regex 2016-12-14 13:18:02 +01:00
Mario Vavti
028935a318 wiki: do not show revert buttons if we do not have write perms and minor cleanup 2016-12-14 11:55:52 +01:00
Mario Vavti
62353191e8 fix btn-group rendering 2016-12-14 09:57:22 +01:00
zotlabs
cbffd32d8e use absolute namespace in case this gets moved 2016-12-13 20:05:36 -08:00
zotlabs
0394a3e939 tag and mention handling in private mail (which required refactoring the bbcode cleanup stuff in mod_item) 2016-12-13 20:01:38 -08:00
zotlabs
8e400e9e40 update hook doco 2016-12-13 18:47:07 -08:00
zotlabs
66a53c6d3c add plugin hook to zot_best_algorithm() 2016-12-13 18:43:47 -08:00
zotlabs
f111c5c325 mail preview (basic functionality) 2016-12-13 17:30:02 -08:00
zotlabs
c4a9b61da6 restructuring include/message for mail preview 2016-12-13 16:34:08 -08:00
zotlabs
23823811e9 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-12-13 15:15:37 -08:00
jeroenpraat
dce03a36d0 update dutch strings 2016-12-13 23:37:03 +01:00
Mario Vavti
b24b3d21e1 dropdown position fixes 2016-12-13 11:24:29 +01:00
Mario Vavti
0927af40c3 bring lockview to wikilist 2016-12-13 11:14:22 +01:00
Mario Vavti
0979f11cc3 do not increase opacity to more than 1 2016-12-13 10:23:56 +01:00
Mario Vavti
68bdd26426 simplify wikilist widget 2016-12-13 10:09:56 +01:00
git-marijus
e00062ea8f Merge pull request #619 from anaqreon/dev
Make region_1 table of contents "unsticky" when width is less than
2016-12-13 09:27:15 +01:00
zotlabs
ca44ce5f8c document the stream_item hook before I forget 2016-12-12 20:28:13 -08:00
Andrew Manning
812ac259e2 Make region_1 table of contents "unsticky" when width is less than 768px for better mobile support. 2016-12-12 20:10:50 -05:00
ilu33
ae4cf98458 Configuring email notifications per channel 2016-11-24 04:32:23 +01:00
877 changed files with 165790 additions and 45433 deletions

View File

@@ -491,7 +491,7 @@ END
print_info "letsenrypt exists already (nothing downloaded > no certificate created and registered)"
return 0
fi
git clone https://github.com/lukas2511/letsencrypt.sh $le_dir
git clone https://github.com/lukas2511/dehydrated $le_dir
cd $le_dir
# create config file for letsencrypt.sh
echo "WELLKNOWN=$le_dir" > $le_dir/config.sh
@@ -511,9 +511,9 @@ END
then
die "Failed to load $url_http"
fi
# run letsencrypt.sh
# run script dehydrated
#
./letsencrypt.sh --cron --config $le_dir/config.sh
./dehydrated --cron --config $le_dir/config.sh
}
function configure_apache_for_https {
@@ -730,8 +730,8 @@ echo "#" >> /var/www/$hubzilladaily
echo "echo \" \"" >> /var/www/$hubzilladaily
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
echo "echo \" \"" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - renew certificat...\"" >> /var/www/$hubzilladaily
echo "bash $le_dir/letsencrypt.sh --cron --config $le_dir/config.sh" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$hubzilladaily
echo "bash $le_dir/dehydrated --cron --config $le_dir/config.sh" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "# stop hubzilla" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - stoping apache and mysql...\"" >> /var/www/$hubzilladaily
@@ -798,7 +798,7 @@ echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
echo "du -h /var/cache/rsnapshot/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "# update" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - updating letsencrypt.sh...\"" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - updating dehydrated...\"" >> /var/www/$hubzilladaily
echo "git -C /var/www/letsencrypt/ pull" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily
echo "git -C /var/www/html/ pull" >> /var/www/$hubzilladaily

View File

@@ -1,3 +1,94 @@
Hubzilla 2.2 (2017-03-08)
- Don't collapse long nsfw content if nsfw plugin is already collapsing it
- Provide version compatibility check for themes (minversion, maxversion)
- Use chanlink_hash() instead of chanlink_url() where appropriate
- Use head_add_link() for feed discovery
- Provide HTTP header parser which honours continuation lines
- Numerous doco improvements
- Implement virtual privacy groups from restricted profile access list
- Implement permission roles
- Implement app-tray
- Default to manual conversation updates
- Implement channel move for all server roles
- Implement nav login modal
- Rename bb2diaspora.php to markdown.php
- Remove obsolete module 'match'
- Move firefox social api configuration to plugin
- Move rsd service to twitter_api plugin
- Add build_pagehead hook
- Move opensearch to plugins
- Move dreamhost hack to plugin
- Add wiki permissions
- Introduce hubloc_store_lowlevel() and xchan_store_lowlevel()
- Move diaspora account import to the diaspora plugin
- Allow export of single data sets instead of always exporting everything we know about in channel export
- Queue optimisations for sites that have lingered in the queue for more than a couple of days
- Add affinity slider tool settings for min and max defaults in settings/featured
- Provide lowlevel xchan storage function to ensure that all non-null rows are initialised
- Implement native wiki
- Block well-known from oembed
- Implement observer.language bbcode and observer.language comanche conditional
- Implement daemon_addon hook to let plugins create custom background processes
- Implement profile vcards
- Implement connection vcards
- Implement 'click to call' in address book
- Default cover photo
- Remove fullscreen functionality in photo album view
- Update fontawesome lib to version 4.7.0
- Implement a menu to select a section to be open by default in connedit
- Improve comanche conditionals
- Add enclosures and categories to atom feed parsing
- Allow the atom_entry hook to change the results
- Set 'adjust for viewer timezone' as the default for new events
- Allow event creation in other timezones than your own
- Update fullcalendar lib to version 3.1
- Move api version call back to core
- Create first webpage as 'home' if none exist
- Show webpages link to visitors if a 'home' page exists
Bugfixes
- Fix schema not saved if session theme != selected theme and schema select display issue
- Fix no acl not detected in post_activity_item()
- Fix find_folder_hash_by_path() was not safe against multiple attach structures with the same filename but in different directories
- Fix don't search on empty filename - we shouldn't find it. The reason why this change is being made is because we actually did find it due to a development glitch
- Fix several places where head_add_(css|js) functions have been used incorrectly.
- Fix webpage import tool
- Fix numerous bugs with the addon repo management GUI
- Fix attach_delete() to remove photo resources even if the attach table row wasn't found
- Fix choking if photo_factory() returns null
- Fix embedimage if an albumname contains quotes
- Fix chat member list when one or more members are connected via access tokens
- Fix issue #636 - some localised (e.g. Italian) strings have single quotes which throw JS errors when used in single quoted template constructs
- Fix issues #629 and #635 - edited post arriving from downstream source was not being rejected
- Fix peoplefind widget not honouring directory option settings
- Fix issue with HTML in code blocks in markdown in wiki
- Fix issue with post signatures if posted from api and logged in locally with a different identity
Plugins/Addon
- Add experimental webmention plugin
- NSFW: Use button instead of text link
- Diaspora: gracefully handle multiple photos per post
- Diaspora: change profile photo permission call
- Logrotate: don't throw an error if another server process renamed the logfile before we got to it
- Chess: the channel owner must be one of the players, so only require selecting one connection for an opponent
- Move firefox social api configuration to plugin from core
- Move rsd service to twitter_api plugin from core
- Move opensearch to plugins from core
- Move dreamhost hack to plugin from
- Move diaspora account import to addon from core
- Reflect hubloc store changes in plugins
- Reflect xchan store changes in plugins
- Rendezvous: Fixed marker creation bug
- Rendezvous: Center on marker if specified in URL, and update browser address bar with shareable link when selecting markers on the map
- Rendezvous: Set default value of 0 for priximity alert when making new markers
- Move gitwiki to plugins from core which has been replaced by native wiki
- Openclipatar: reflect changes to files and photos which were unified in core some time ago
- Reintroduce gnusocial plugin after security/functionality review
- Twitter_api: hubzilla core issue 638 - unsupported message-id field not available in all twitter api functions
- Superblock: update to reflect core changes
- Rendezvous: implement static marker proximity alert
- Phpmailer: security update
Hubzilla 2.0 (2016-12-23)
- Deprecate bb_iframe
- Note widget: resize the textarea to reveal full content

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2016 the Hubzilla Community
Copyright (c) 2010-2017 the Hubzilla Community
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@@ -3,60 +3,27 @@
Hubzilla - Community Server
===========================
Groupware re-imagined and re-invented.
--------------------------------------
Connect and link decentralised web communities.
-----------------------------------------------
<p align="center" markdown="1">
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
</p>
**What are Hubz?**
Hubz are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
This allows hub members on any hub to securely and privately share anything; with anybody, on any hub - anywhere; or share stuff publicly with anybody on the internet if desired.
**What is Hubzilla?**
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache and popular variants). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
Hubzilla is a general purpose communication server integrated with a web publishing system and a decentralised permission system. If this sounds like a bunch of technical mumbo-jumbo to you, just think of it as an independent platform for sharing stuff online.
Hubzilla hubz are
Hubzilla contains some social network bits, some cloud storage bits, some blog and forum bits, and some content management bits. These are all integrated within a common privacy framework - and it is all decentralised.
* decentralised
* inherently social
* optionally inter-networked with other hubz
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubz)
Everything you publish or share can be restricted to those channels and people you wish to share them with; and these permissions work completely invisibly - even with channels on different servers or other communications services.
Possible website applications include
Migration and live backups of your connections, settings, and everything you publish are built-in, so you never need worry about server failure.
* decentralised social networking nodes
* personal cloud storage
* file dropboxes
* managing organisational communications and activities
* collaboration and community decision-making
* small business websites
* public and private media/file libraries
* blogs
* event promotion
* feed aggregation and republishing
* forums
* dating websites
* pretty much anything you can do on a traditional blog or community website, but that you could do better if you could easily connect it with other websites or privately share things across website boundaries.
Hubzilla is completely decentralised and open source, for you modify or adapt to your needs and desires. Plugins, themes, and numerous configuration options extend the overall capabilities to do anything you can imagine.
<p align="center" markdown="1">
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
</p>
**Who Are We and What Are Our Principles?**
The Hubzilla community is powered by passionate volunteers creating an open source **commons** of decentralised services which are highly integrated and can rival the feature set of centralised providers. We are open to sponsorship and donations to cover expenses and compensate for our time and energy, however the project core is basically non-profit and is not designed for the purpose of commercial gain or exploitation.
Some sites may include monetisation strategies such as subscriptions and *freemium* models where members pay for resources they consume beyond a basic level. The project community supports such monetisation initiatives (nobody should be forced to pay "out of pocket" to provide a service to others), but we maintain the **commons** to provide open and free access of the software to all.
The software is not designed for data collection of its members or providing advertising. We don't have a need or desire for these things and feel that software built around these goals is poorly designed and represents compromised principles and ethics.
As a project, we are inclusive of all beliefs and cultures and do what we are able to provide an environment that is free from hostility and harrassment. Whether or not we succeed in this endaevour requires constant vigilance and help from all members of the community, working together to build an inter-networking tool with amazing potential.
**Who Are We?**
The Hubzilla community consists of passionate volunteers creating an open source commons of decentralised services which are highly integrated and can rival the feature set of large centralised providers. We do our best to provide ethical software which places you in control of your online communications and privacy expectations.
[![Build Status](https://travis-ci.org/redmatrix/hubzilla.svg)](https://travis-ci.org/redmatrix/hubzilla)

View File

@@ -8,7 +8,7 @@ use Zotlabs\Lib as Zlib;
class PermissionRoles {
static public function version() {
return 1;
return 2;
}
static function role_perms($role) {
@@ -25,7 +25,7 @@ class PermissionRoles {
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'chat', 'post_like', 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -38,7 +38,7 @@ class PermissionRoles {
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'chat', 'post_like' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -52,7 +52,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' ];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
@@ -67,7 +67,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'republish', 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -80,7 +80,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -95,7 +95,7 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_wall', 'post_comments',
'view_pages', 'view_wiki', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -103,6 +103,7 @@ class PermissionRoles {
$ret['limits']['view_contacts'] = PERMS_SPECIFIC;
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
$ret['limits']['view_wiki'] = PERMS_SPECIFIC;
break;
@@ -114,7 +115,7 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -128,7 +129,7 @@ class PermissionRoles {
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -143,7 +144,7 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_like' , 'republish' ];
'view_pages', 'view_wiki', 'post_like' , 'republish' ];
$ret['limits'] = PermissionLimits::Std_Limits();
@@ -157,8 +158,8 @@ class PermissionRoles {
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'republish', 'chat' ];
'view_pages', 'view_wiki', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'republish', 'chat', 'write_wiki' ];
$ret['limits'] = PermissionLimits::Std_Limits();
break;
@@ -185,6 +186,12 @@ class PermissionRoles {
// if($perm === 'mynewperm')
// \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1);
if($perm === 'view_wiki')
\Zotlabs\Access\PermissionLimits::Set($uid,$perm,PERMS_PUBLIC);
if($perm === 'write_wiki')
\Zotlabs\Access\PermissionLimits::Set($uid,$perm,PERMS_SPECIFIC);
// set autoperms here if applicable
// choices are to set to 0, 1, or the value of an existing perm
@@ -195,7 +202,13 @@ class PermissionRoles {
$value = 0;
// if($perm === 'mynewperm')
// $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm'));
// $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm');
if($perm === 'view_wiki')
$value = get_abconfig($uid,$c['channel_hash'],'autoperms','view_pages');
if($perm === 'write_wiki')
$value = get_abconfig($uid,$c['channel_hash'],'autoperms','write_pages');
if($c) {
set_abconfig($uid,$c['channel_hash'],'autoperms',$perm,$value);
@@ -212,8 +225,16 @@ class PermissionRoles {
// case 'mynewperm':
// choices are to set to 1, set to 0, or clone an existing perm
// set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
// get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm'));
// intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm')));
case 'view_wiki':
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','view_pages')));
case 'write_wiki':
set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm,
intval(get_abconfig($uid,$ab['abook_xchan'],'my_perms','write_pages')));
default:
break;
}
@@ -255,6 +276,4 @@ class PermissionRoles {
return $roles;
}
}

View File

@@ -18,7 +18,7 @@ class Permissions {
* permission roles. You will want to set a default PermissionLimit for each channel and also
* provide a sane default for any existing connections. You may or may not wish to provide a
* default auto permission. If in doubt, leave this alone as custom permissions by definition
* are the responsbility of the channel owner to manage. You just don't want to create any
* are the responsibility of the channel owner to manage. You just don't want to create any
* suprises or break things so you have an opportunity to provide sane settings.
*
* Update the version here and in PermissionRoles
@@ -36,7 +36,7 @@ class Permissions {
static public function version() {
// This must match the version in PermissionRoles.php before permission updates can run.
return 1;
return 2;
}
@@ -50,7 +50,9 @@ class Permissions {
'view_storage' => t('Can view my file storage and photos'),
'write_storage' => t('Can upload/modify my file storage and photos'),
'view_pages' => t('Can view my channel webpages'),
'view_wiki' => t('Can view my wiki pages'),
'write_pages' => t('Can create/edit my channel webpages'),
'write_wiki' => t('Can write to my wiki pages'),
'post_wall' => t('Can post on my channel (wall) page'),
'post_comments' => t('Can comment on or like my posts'),
'post_mail' => t('Can send me private mail messages'),
@@ -92,6 +94,10 @@ class Permissions {
// Undeclared permissions are set to 0
static public function FilledPerms($arr) {
if(is_null($arr)) {
btlogger('FilledPerms: null');
}
$everything = self::Perms();
$ret = [];
foreach($everything as $k => $v) {
@@ -104,6 +110,17 @@ class Permissions {
}
static public function OPerms($arr) {
$ret = [];
if($arr) {
foreach($arr as $k => $v) {
$ret[] = [ 'name' => $k, 'value' => $v ];
}
}
return $ret;
}
static public function FilledAutoperms($channel_id) {
if(! intval(get_pconfig($channel_id,'system','autoperms')))
return false;
@@ -114,7 +131,7 @@ class Permissions {
);
if($r) {
foreach($r as $rr) {
$arr[$rr['k']] = $arr[$rr['v']];
$arr[$rr['k']] = intval($rr['v']);
}
}
return $arr;
@@ -129,4 +146,76 @@ class Permissions {
}
return true;
}
static public function connect_perms($channel_id) {
$my_perms = [];
$permcat = null;
$automatic = 0;
// If a default permcat exists, use that
$pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
if(! in_array($pc, [ '','default' ])) {
$pcp = new Zlib\Permcat($channel_id);
$permcat = $pcp->fetch($pc);
if($permcat && $permcat['perms']) {
foreach($permcat['perms'] as $p) {
$my_perms[$p['name']] = $p['value'];
}
}
}
// look up the permission role to see if it specified auto-connect
// and if there was no permcat or a default permcat, set the perms
// from the role
$role = get_pconfig($channel_id,'system','permissions_role');
if($role) {
$xx = PermissionRoles::role_perms($role);
if($xx['perms_auto'])
$automatic = 1;
if((! $my_perms) && ($xx['perms_connect'])) {
$default_perms = $xx['perms_connect'];
$my_perms = Permissions::FilledPerms($default_perms);
}
}
// If we reached this point without having any permission information,
// it is likely a custom permissions role. First see if there are any
// automatic permissions.
if(! $my_perms) {
$m = Permissions::FilledAutoperms($channel_id);
if($m) {
$automatic = 1;
$my_perms = $m;
}
}
// If we reached this point with no permissions, the channel is using
// custom perms but they are not automatic. They will be stored in abconfig with
// the channel's channel_hash (the 'self' connection).
if(! $my_perms) {
$r = q("select channel_hash from channel where channel_id = %d",
intval($channel_id)
);
if($r) {
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
intval($channel_id),
dbesc($r[0]['channel_hash'])
);
if($x) {
foreach($x as $xv) {
$my_perms[$xv['k']] = intval($xv['v']);
}
}
}
}
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
}
}

14
Zotlabs/Daemon/Addon.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
namespace Zotlabs\Daemon;
require_once('include/zot.php');
class Addon {
static public function run($argc,$argv) {
call_hooks('daemon_addon',$argv);
}
}

View File

@@ -3,7 +3,6 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
require_once('include/hubloc.php');
class Checksites {

View File

@@ -76,7 +76,6 @@ class Cron_daily {
Master::Summon(array('Expire'));
Master::Summon(array('Cli_suggest'));
require_once('include/hubloc.php');
remove_obsolete_hublocs();
call_hooks('cron_daily',datetime_convert());

View File

@@ -17,7 +17,6 @@ class Cron_weekly {
z_check_cert();
require_once('include/hubloc.php');
prune_hub_reinstalls();
mark_orphan_hubsxchans();

View File

@@ -61,30 +61,15 @@ class Queue {
// the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once
// or twice a day.
// FIXME: can we sort postgres on outq_priority and maintain the 'distinct' ?
// The order by max(outq_priority) might be a dodgy query because of the group by.
// The desired result is to return a sequence in the order most likely to be delivered in this run.
// If a hub has already been sitting in the queue for a few days, they should be delivered last;
// hence every failure should drop them further down the priority list.
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$prefix = 'DISTINCT ON (outq_posturl)';
$suffix = 'ORDER BY outq_posturl';
} else {
$prefix = '';
$suffix = 'GROUP BY outq_posturl ORDER BY max(outq_priority)';
}
$r = q("SELECT $prefix * FROM outq WHERE outq_delivered = 0 and (( outq_created > %s - INTERVAL %s and outq_updated < %s - INTERVAL %s ) OR ( outq_updated < %s - INTERVAL %s )) $suffix",
db_utcnow(), db_quoteinterval('12 HOUR'),
db_utcnow(), db_quoteinterval('15 MINUTE'),
db_utcnow(), db_quoteinterval('1 HOUR')
$r = q("SELECT * FROM outq WHERE outq_delivered = 0 and outq_scheduled < %s ",
db_utcnow()
);
}
if(! $r)
return;
foreach($r as $rr) {
queue_deliver($rr);
foreach($r as $rv) {
queue_deliver($rv);
}
}
}

View File

@@ -38,6 +38,7 @@ class Apps {
if(plugin_is_installed($plugin)) {
$x = self::parse_app_description($f,$translate);
if($x) {
$x['plugin'] = $plugin;
$ret[] = $x;
}
}
@@ -54,7 +55,6 @@ class Apps {
return;
$apps = self::get_system_apps(false);
self::$installed_system_apps = q("select * from app where app_system = 1 and app_channel = %d",
intval(local_channel())
);
@@ -102,11 +102,13 @@ class Apps {
foreach(self::$installed_system_apps as $iapp) {
if($iapp['app_id'] == hash('whirlpool',$app['name'])) {
$notfound = false;
if($iapp['app_version'] != $app['version']) {
if(($iapp['app_version'] != $app['version'])
|| ($app['plugin'] && (! $iapp['app_plugin']))) {
return intval($iapp['app_id']);
}
}
}
return $notfound;
}
@@ -144,8 +146,11 @@ class Apps {
$ret['type'] = 'system';
foreach($ret as $k => $v) {
if(strpos($v,'http') === 0)
$ret[$k] = zid($v);
if(strpos($v,'http') === 0) {
if(! (local_channel() && strpos($v,z_root()) === 0)) {
$ret[$k] = zid($v);
}
}
}
if(array_key_exists('desc',$ret))
@@ -157,6 +162,8 @@ class Apps {
if(array_key_exists('version',$ret))
$ret['version'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['version']);
if(array_key_exists('categories',$ret))
$ret['categories'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$ret['categories']);
if(array_key_exists('requires',$ret)) {
$requires = explode(',',$ret['requires']);
@@ -238,9 +245,9 @@ class Apps {
'Profile Photo' => t('Profile Photo')
);
if(array_key_exists($arr['name'],$apps))
if(array_key_exists($arr['name'],$apps)) {
$arr['name'] = $apps[$arr['name']];
}
}
@@ -255,6 +262,7 @@ class Apps {
* list: normal mode for viewing an app on the app page
* no buttons are shown
* edit: viewing the app page in editing mode provides a delete button
* nav: render apps for app-bin
*/
$installed = false;
@@ -267,14 +275,20 @@ class Apps {
self::translate_system_apps($papp);
if(($papp['plugin']) && (! plugin_is_installed($papp['plugin'])))
return '';
$papp['papp'] = self::papp_encode($papp);
if(! strstr($papp['url'],'://'))
$papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
foreach($papp as $k => $v) {
if(strpos($v,'http') === 0 && $k != 'papp')
$papp[$k] = zid($v);
if(strpos($v,'http') === 0 && $k != 'papp') {
if(! (local_channel() && strpos($v,z_root()) === 0)) {
$papp[$k] = zid($v);
}
}
if($k === 'desc')
$papp['desc'] = str_replace(array('\'','"'),array('&#39;','&dquot;'),$papp['desc']);
@@ -332,14 +346,23 @@ class Apps {
}
$install_action = (($installed) ? t('Update') : t('Install'));
$icon = ((strpos($papp['photo'],'icon:') === 0) ? substr($papp['photo'],5) : '');
return replace_macros(get_markup_template('app.tpl'),array(
'$app' => $papp,
'$icon' => $icon,
'$hosturl' => $hosturl,
'$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''),
'$install' => (($hosturl && $mode == 'view') ? $install_action : ''),
'$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''),
'$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : '')
'$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : ''),
'$undelete' => ((local_channel() && $installed && $mode == 'edit') ? t('Undelete') : ''),
'$deleted' => $papp['deleted'],
'$feature' => (($papp['embed']) ? false : true),
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
'$navapps' => (($mode == 'nav') ? true : false),
'$add' => t('Add to app-tray'),
'$remove' => t('Remove from app-tray')
));
}
@@ -382,36 +405,82 @@ class Apps {
intval($uid)
);
if($x) {
$x[0]['app_deleted'] = 1;
q("delete from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($x[0]['id'])
);
if($x[0]['app_system']) {
$r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
if(! intval($x[0]['app_deleted'])) {
$x[0]['app_deleted'] = 1;
q("delete from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($x[0]['id'])
);
if($x[0]['app_system']) {
$r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
}
else {
$r = q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
// we don't sync system apps - they may be completely different on the other system
build_sync_packet($uid,array('app' => $x));
}
}
else {
$r = q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
// we don't sync system apps - they may be completely different on the other system
build_sync_packet($uid,array('app' => $x));
self::app_undestroy($uid,$app);
}
}
}
}
static public function app_undestroy($uid,$app) {
// undelete a system app
if($uid && $app['guid']) {
$x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
dbesc($app['guid']),
intval($uid)
);
if($x) {
if($x[0]['app_system']) {
$r = q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
}
}
}
}
static public function app_feature($uid,$app) {
$r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
dbesc($app['guid']),
intval($uid)
);
$x = q("select * from term where otype = %d and oid = %d and term = 'nav_featured_app' limit 1",
intval(TERM_OBJ_APP),
intval($r[0]['id'])
);
if($x) {
q("delete from term where otype = %d and oid = %d and term = 'nav_featured_app'",
intval(TERM_OBJ_APP),
intval($x[0]['oid'])
);
}
else {
store_item_tag($uid,$r[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,'nav_featured_app',escape_tags(z_root() . '/apps/?f=&cat=nav_featured_app'));
}
}
static public function app_installed($uid,$app) {
$r = q("select id from app where app_id = '%s' and app_version = '%s' and app_channel = %d limit 1",
$r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''),
dbesc((array_key_exists('version',$app)) ? $app['version'] : ''),
intval($uid)
);
return(($r) ? true : false);
@@ -421,7 +490,7 @@ class Apps {
static public function app_list($uid, $deleted = false, $cat = '') {
if($deleted)
$sql_extra = " and app_deleted = 1 ";
$sql_extra = "";
else
$sql_extra = " and app_deleted = 0 ";
@@ -445,6 +514,7 @@ class Apps {
$r = q("select * from app where app_channel = %d $sql_extra order by app_name asc",
intval($uid)
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
if(! $r[$x]['app_system'])
@@ -455,6 +525,7 @@ class Apps {
);
}
}
return($r);
}
@@ -467,7 +538,7 @@ class Apps {
static public function app_store($arr) {
// logger('app_store: ' . print_r($arr,true));
//logger('app_store: ' . print_r($arr,true));
$darray = array();
$ret = array('success' => false);
@@ -478,7 +549,7 @@ class Apps {
if((! $darray['app_url']) || (! $darray['app_channel']))
return $ret;
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
if($arr['photo'] && (strpos($arr['photo'],'icon:') !== 0) && (! strstr($arr['photo'],z_root()))) {
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@@ -494,13 +565,14 @@ class Apps {
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
$darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags($arr['plugin']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
$created = datetime_convert();
$r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
$r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_plugin, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d )",
dbesc($darray['app_id']),
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
@@ -517,6 +589,7 @@ class Apps {
dbesc($created),
dbesc($created),
intval($darray['app_system']),
dbesc($darray['app_plugin']),
intval($darray['app_deleted'])
);
if($r) {
@@ -545,6 +618,7 @@ class Apps {
static public function app_update($arr) {
//logger('app_update: ' . print_r($arr,true));
$darray = array();
$ret = array('success' => false);
@@ -555,7 +629,7 @@ class Apps {
if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id']))
return $ret;
if($arr['photo'] && ! strstr($arr['photo'],z_root())) {
if($arr['photo'] && (strpos($arr['photo'],'icon:') !== 0) && (! strstr($arr['photo'],z_root()))) {
$x = import_xchan_photo($arr['photo'],get_observer_hash(),true);
$arr['photo'] = $x[1];
}
@@ -569,13 +643,14 @@ class Apps {
$darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : '');
$darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : '');
$darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : '');
$darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags($arr['plugin']) : '');
$darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : '');
$darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0);
$darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0);
$edited = datetime_convert();
$r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d",
$r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_plugin = '%s', app_deleted = %d where app_id = '%s' and app_channel = %d",
dbesc($darray['app_sig']),
dbesc($darray['app_author']),
dbesc($darray['app_name']),
@@ -589,6 +664,7 @@ class Apps {
dbesc($darray['app_requires']),
dbesc($edited),
intval($darray['app_system']),
dbesc($darray['app_plugin']),
intval($darray['app_deleted']),
dbesc($darray['app_id']),
intval($darray['app_channel'])
@@ -655,6 +731,9 @@ class Apps {
if($app['app_photo'])
$ret['photo'] = $app['app_photo'];
if($app['app_icon'])
$ret['icon'] = $app['app_icon'];
if($app['app_version'])
$ret['version'] = $app['app_version'];
@@ -673,6 +752,9 @@ class Apps {
if($app['app_system'])
$ret['system'] = $app['app_system'];
if($app['app_plugin'])
$ret['plugin'] = $app['app_plugin'];
if($app['app_deleted'])
$ret['deleted'] = $app['app_deleted'];
@@ -690,6 +772,8 @@ class Apps {
if(! $embed)
return $ret;
$ret['embed'] = true;
if(array_key_exists('categories',$ret))
unset($ret['categories']);

210
Zotlabs/Lib/NativeWiki.php Normal file
View File

@@ -0,0 +1,210 @@
<?php
namespace Zotlabs\Lib;
define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
class NativeWiki {
static public function listwikis($channel, $observer_hash) {
$sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
$wikis = q("SELECT * FROM item
WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
if($wikis) {
foreach($wikis as &$w) {
$w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
$w['htmlName'] = escape_tags($w['rawName']);
$w['urlName'] = urlencode(urlencode($w['rawName']));
$w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
$w['lock'] = (($w['item_private'] || $w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? true : false);
}
}
// TODO: query db for wikis the observer can access. Return with two lists, for read and write access
return array('wikis' => $wikis);
}
function create_wiki($channel, $observer_hash, $wiki, $acl) {
// Generate unique resource_id using the same method as item_message_id()
do {
$dups = false;
$resource_id = random_string();
$r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1",
dbesc($resource_id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
if($r)
$dups = true;
} while($dups == true);
$ac = $acl->get();
$mid = item_message_id();
$arr = array(); // Initialize the array of parameters for the post
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
$wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
$arr['mid'] = $mid;
$arr['parent_mid'] = $mid;
$arr['item_hidden'] = $item_hidden;
$arr['resource_type'] = NWIKI_ITEM_RESOURCE_TYPE;
$arr['resource_id'] = $resource_id;
$arr['owner_xchan'] = $channel['channel_hash'];
$arr['author_xchan'] = $observer_hash;
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
$arr['llink'] = $arr['plink'];
$arr['title'] = $wiki['htmlName']; // name of new wiki;
$arr['allow_cid'] = $ac['allow_cid'];
$arr['allow_gid'] = $ac['allow_gid'];
$arr['deny_cid'] = $ac['deny_cid'];
$arr['deny_gid'] = $ac['deny_gid'];
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['item_private'] = intval($acl->is_private());
$arr['verb'] = ACTIVITY_CREATE;
$arr['obj_type'] = ACTIVITY_OBJ_WIKI;
$arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_wiki'),true);
// Save the wiki name information using iconfig. This is shareable.
if(! set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) {
return array('item' => null, 'success' => false);
}
if(! set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
return array('item' => null, 'success' => false);
}
$post = item_store($arr);
$item_id = $post['item_id'];
if($item_id) {
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
return array('item' => $post['item'], 'item_id' => $item_id, 'success' => true);
}
else {
return array('item' => null, 'success' => false);
}
}
static public function sync_a_wiki_item($uid,$id,$resource_id) {
$r = q("SELECT * from item WHERE uid = %d AND ( id = %d OR ( resource_type = '%s' and resource_id = %d )) ",
intval($uid),
intval($id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
intval($resource_id)
);
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet($uid,array('wiki' => array(encode_item($sync_item[0],true))));
}
}
function delete_wiki($channel_id,$observer_hash,$resource_id) {
$w = self::get_wiki($channel_id,$observer_hash,$resource_id);
$item = $w['wiki'];
if(! $item) {
return array('item' => null, 'success' => false);
}
else {
$drop = drop_item($item['id'], false, DROPITEM_NORMAL, true);
}
info( t('Wiki files deleted successfully'));
return array('item' => $item, 'item_id' => $item['id'], 'success' => (($drop === 1) ? true : false));
}
static public function get_wiki($channel_id, $observer_hash, $resource_id) {
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$item = q("SELECT * FROM item WHERE uid = %d AND resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0
$sql_extra limit 1",
intval($channel_id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if(! $item) {
return array('wiki' => null);
}
else {
$w = $item[0]; // wiki item table record
// Get wiki metadata
$rawName = get_iconfig($w, 'wiki', 'rawName');
$mimeType = get_iconfig($w, 'wiki', 'mimeType');
return array(
'wiki' => $w,
'rawName' => $rawName,
'htmlName' => escape_tags($rawName),
'urlName' => urlencode(urlencode($rawName)),
'mimeType' => $mimeType
);
}
}
static public function exists_by_name($uid, $urlName) {
$sql_extra = item_permissions_sql($uid);
$item = q("SELECT item.id, resource_id FROM item left join iconfig on iconfig.iid = item.id
WHERE resource_type = '%s' AND iconfig.v = '%s' AND uid = %d
AND item_deleted = 0 $sql_extra limit 1",
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc(urldecode($urlName)),
intval($uid)
);
if($item) {
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
}
else {
return array('id' => null, 'resource_id' => null);
}
}
static public function get_permissions($resource_id, $owner_id, $observer_hash) {
// TODO: For now, only the owner can edit
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
if(local_channel() && local_channel() == $owner_id) {
return [ 'read' => true, 'write' => true, 'success' => true ];
}
$r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
intval($owner_id),
dbesc(NWIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if(! $r) {
return array('read' => false, 'write' => false, 'success' => true);
}
else {
// TODO: Create a new permission setting for wiki analogous to webpages. Until
// then, use webpage permissions
$write = perm_is_allowed($owner_id, $observer_hash,'write_wiki');
return array('read' => true, 'write' => $write, 'success' => true);
}
}
}

View File

@@ -0,0 +1,664 @@
<?php
namespace Zotlabs\Lib;
use \Zotlabs\Lib as Zlib;
class NativeWikiPage {
static public function page_list($channel_id,$observer_hash, $resource_id) {
// TODO: Create item table records for pages so that metadata like title can be applied
$w = Zlib\NativeWiki::get_wiki($channel_id,$observer_hash,$resource_id);
$pages[] = [
'resource_id' => '',
'title' => 'Home',
'url' => 'Home',
'link_id' => 'id_wiki_home_0'
];
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and item_deleted = 0
$sql_extra group by mid",
dbesc($resource_id),
intval($channel_id)
);
if($r) {
$items = fetch_post_tags($r,true);
foreach($items as $page_item) {
$title = get_iconfig($page_item['id'],'nwikipage','pagetitle',t('(No Title)'));
if(urldecode($title) !== 'Home') {
$pages[] = [
'resource_id' => $resource_id,
'title' => escape_tags($title),
'url' => urlencode(urlencode($title)),
'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $page_item['id']
];
}
}
}
return array('pages' => $pages, 'wiki' => $w);
}
static public function create_page($channel_id, $observer_hash, $name, $resource_id) {
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
}
// create an empty activity
$arr = [];
$arr['uid'] = $channel_id;
$arr['author_xchan'] = $observer_hash;
$arr['resource_type'] = 'nwikipage';
$arr['resource_id'] = $resource_id;
$arr['allow_cid'] = $w['wiki']['allow_cid'];
$arr['allow_gid'] = $w['wiki']['allow_gid'];
$arr['deny_cid'] = $w['wiki']['deny_cid'];
$arr['deny_gid'] = $w['wiki']['deny_gid'];
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel_id,'view_wiki'),true);
// We may wish to change this some day.
$arr['item_unpublished'] = 1;
set_iconfig($arr,'nwikipage','pagetitle',(($name) ? $name : t('(No Title)')),true);
$p = post_activity_item($arr, false, false);
if($p['item_id']) {
$page = [
'rawName' => $name,
'htmlName' => escape_tags($name),
'urlName' => urlencode($name),
];
return array('page' => $page, 'item_id' => $p['item_id'], 'item' => $p['activity'], 'wiki' => $w, 'message' => '', 'success' => true);
}
return [ 'success' => false, 'message' => t('Wiki page create failed.') ];
}
static public function rename_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$pageNewName = ((array_key_exists('pageNewName',$arr)) ? $arr['pageNewName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if(! $w['wiki']) {
return array('message' => t('Wiki not found.'), 'success' => false);
}
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageNewName)
);
if($ic) {
return [ 'success' => false, 'message' => t('Destination name already exists') ];
}
$ids = [];
$ic = q("select *, item.id as item_id from iconfig left join item on iconfig.iid = item.id
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
set_iconfig($c['item_id'],'nwikipage','pagetitle',$pageNewName);
}
$page = [
'rawName' => $pageNewName,
'htmlName' => escape_tags($pageNewName),
'urlName' => urlencode(escape_tags($pageNewName))
];
return [ 'success' => true, 'page' => $page ];
}
return [ 'success' => false, 'item_id' => $c['item_id'], 'message' => t('Page not found') ];
}
static public function get_page_content($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? intval($arr['channel_id']) : 0);
$revision = ((array_key_exists('revision',$arr)) ? intval($arr['revision']) : (-1));
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
}
$item = self::load_page($arr);
if($item) {
$content = $item['body'];
return [
'content' => json_encode($content),
'mimeType' => $w['mimeType'],
'message' => '',
'success' => true
];
}
return array('content' => null, 'message' => t('Error reading page content'), 'success' => false);
}
static public function page_history($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
}
$items = self::load_page_history($arr);
$history = [];
if($items) {
$processed = 0;
foreach($items as $item) {
if($processed > 1000)
break;
$processed ++;
$history[] = [
'revision' => $item['revision'],
'date' => datetime_convert('UTC',date_default_timezone_get(),$item['edited']),
'name' => $item['author']['xchan_name'],
'title' => get_iconfig($item,'nwikipage','commit_msg')
];
}
return [ 'success' => true, 'history' => $history ];
}
return [ 'success' => false ];
}
static public function load_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
}
$ids = '';
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
if($ids)
$ids .= ',';
$ids .= intval($c['iid']);
}
}
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
if($revision == (-1))
$sql_extra .= " order by revision desc ";
elseif($revision)
$sql_extra .= " and revision = " . intval($revision) . " ";
$r = null;
if($ids) {
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) $sql_extra limit 1",
dbesc($resource_id),
intval($channel_id)
);
if($r) {
$items = fetch_post_tags($r,true);
return $items[0];
}
}
return null;
}
static public function load_page_history($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : (-1));
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
}
$ids = '';
$ic = q("select * from iconfig left join item on iconfig.iid = item.id where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
if($ids)
$ids .= ',';
$ids .= intval($c['iid']);
}
}
$sql_extra = item_permissions_sql($channel_id,$observer_hash);
$sql_extra .= " order by revision desc ";
$r = null;
if($ids) {
$r = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s' and uid = %d and id in ( $ids ) and item_deleted = 0 $sql_extra",
dbesc($resource_id),
intval($channel_id)
);
if($r) {
xchan_query($r);
$items = fetch_post_tags($r,true);
return $items;
}
}
return null;
}
static public function prepare_content($s) {
$text = preg_replace_callback('{
(?:\n\n|\A\n?)
( # $1 = the code block -- one or more lines, starting with a space/tab
(?>
[ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
.*\n+
)+
)
((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
}xm',
'self::nwiki_prepare_content_callback', $s);
return $text;
}
static public function nwiki_prepare_content_callback($matches) {
$codeblock = $matches[1];
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES, UTF8, false);
return "\n\n" . $codeblock ;
}
static public function save_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$content = ((array_key_exists('content',$arr)) ? purify_html(Zlib\NativeWikiPage::prepare_content($arr['content'])) : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$revision = ((array_key_exists('revision',$arr)) ? $arr['revision'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('message' => t('Error reading wiki'), 'success' => false);
}
// fetch the most recently saved revision.
$item = self::load_page($arr);
if(! $item) {
return array('message' => t('Page not found'), 'success' => false);
}
// change just the fields we need to change to create a revision;
unset($item['id']);
unset($item['author']);
$item['parent'] = 0;
$item['body'] = $content;
$item['author_xchan'] = $observer_hash;
$item['revision'] = (($arr['revision']) ? intval($arr['revision']) + 1 : intval($item['revision']) + 1);
$item['edited'] = datetime_convert();
if($item['iconfig'] && is_array($item['iconfig']) && count($item['iconfig'])) {
for($x = 0; $x < count($item['iconfig']); $x ++) {
unset($item['iconfig'][$x]['id']);
unset($item['iconfig'][$x]['iid']);
}
}
$ret = item_store($item, false, false);
if($ret['item_id'])
return array('message' => '', 'item_id' => $ret['item_id'], 'filename' => $filename, 'success' => true);
else
return array('message' => t('Page update failed.'), 'success' => false);
}
static public function delete_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if(! $w['wiki']) {
return [ 'success' => false, 'message' => t('Error reading wiki') ];
}
$ids = [];
$ic = q("select * from iconfig left join item on iconfig.iid = item.id
where uid = %d and cat = 'nwikipage' and k = 'pagetitle' and v = '%s'",
intval($channel_id),
dbesc($pageUrlName)
);
if($ic) {
foreach($ic as $c) {
$ids[] = intval($c['iid']);
}
}
if($ids) {
drop_items($ids);
return [ 'success' => true ];
}
return [ 'success' => false, 'message' => t('Nothing deleted') ];
}
static public function revert_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
if (! $commitHash) {
return array('content' => $content, 'message' => 'No commit was provided', 'success' => false);
}
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
}
$x = $arr;
if(intval($commitHash) > 0) {
unset($x['commitHash']);
$x['revision'] = intval($commitHash) - 1;
$loaded = self::load_page($x);
if($loaded) {
$content = $loaded['body'];
return [ 'content' => $content, 'success' => true ];
}
return [ 'content' => $content, 'success' => false ];
}
}
static public function compare_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : (-1));
$compareCommit = ((array_key_exists('compareCommit',$arr)) ? $arr['compareCommit'] : 0);
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (!$w['wiki']) {
return array('message' => t('Error reading wiki'), 'success' => false);
}
$x = $arr;
$x['revision'] = (-1);
$currpage = self::load_page($x);
if($currpage)
$currentContent = $currpage['body'];
$x['revision'] = $compareCommit;
$comppage = self::load_page($x);
if($comppage)
$compareContent = $comppage['body'];
if($currpage && $comppage) {
require_once('library/class.Diff.php');
$diff = \Diff::toTable(\Diff::compare($currentContent, $compareContent));
return [ 'success' => true, 'diff' => $diff ];
}
return [ 'success' => false, 'message' => t('Compare: object not found.') ];
}
static public function commit($arr) {
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : t('Page updated'));
$observer_hash = ((array_key_exists('observer_hash',$arr)) ? $arr['observer_hash'] : '');
$channel_id = ((array_key_exists('channel_id',$arr)) ? $arr['channel_id'] : 0);
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : t('Untitled'));
if(array_key_exists('resource_id', $arr)) {
$resource_id = $arr['resource_id'];
}
else {
return array('message' => t('Wiki resource_id required for git commit'), 'success' => false);
}
$w = Zlib\NativeWiki::get_wiki($channel_id, $observer_hash, $resource_id);
if (! $w['wiki']) {
return array('message' => t('Error reading wiki'), 'success' => false);
}
$page = self::load_page($arr);
if($page) {
set_iconfig($page['id'],'nwikipage','commit_msg',escape_tags($commit_msg),true);
return [ 'success' => true, 'item_id' => $page['id'], 'page' => $page ];
}
return [ 'success' => false, 'message' => t('Page not found.') ];
}
static public function convert_links($s, $wikiURL) {
if (strpos($s,'[[') !== false) {
preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
$pages = $pageURLs = array();
foreach ($match[1] as $m) {
// TODO: Why do we need to double urlencode for this to work?
$pageURLs[] = urlencode(urlencode(escape_tags($m)));
$pages[] = $m;
}
$idx = 0;
while(strpos($s,'[[') !== false) {
$replace = '<a href="'.$wikiURL.'/'.$pageURLs[$idx].'">'.$pages[$idx].'</a>';
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
$idx++;
}
}
return $s;
}
/**
* Replace the instances of the string [toc] with a list element that will be populated by
* a table of contents by the JavaScript library
* @param string $s
* @return string
*/
static public function generate_toc($s) {
if (strpos($s,'[toc]') !== false) {
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
}
return $s;
}
/**
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
* @param string $s
* @return string
*/
static public function bbcode($s) {
$s = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $s);
$s = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $s);
$s = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $s);
$observer = \App::get_observer();
if ($observer) {
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
$s2 = '</span>';
$obsBaseURL = $observer['xchan_connurl'];
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
$s = str_replace('[observer.photo]', '', $s);
}
else {
$s = str_replace('[observer.baseurl]', '', $s);
$s = str_replace('[observer.url]', '', $s);
$s = str_replace('[observer.name]', '', $s);
$s = str_replace('[observer.address]', '', $s);
$s = str_replace('[observer.webname]', '', $s);
$s = str_replace('[observer.photo]', '', $s);
}
return $s;
}
static public function get_file_ext($arr) {
if($arr['mimeType'] == 'text/bbcode')
return '.bb';
else
return '.md';
}
// This function is derived from
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
static public function toc($content) {
// ensure using only "\n" as line-break
$source = str_replace(["\r\n", "\r"], "\n", $content);
// look for markdown TOC items
preg_match_all(
'/^(?:=|-|#).*$/m',
$source,
$matches,
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
);
// preprocess: iterate matched lines to create an array of items
// where each item is an array(level, text)
$file_size = strlen($source);
foreach ($matches[0] as $item) {
$found_mark = substr($item[0], 0, 1);
if ($found_mark == '#') {
// text is the found item
$item_text = $item[0];
$item_level = strrpos($item_text, '#') + 1;
$item_text = substr($item_text, $item_level);
} else {
// text is the previous line (empty if <hr>)
$item_offset = $item[1];
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
$item_text =
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
$item_text = trim($item_text);
$item_level = $found_mark == '=' ? 1 : 2;
}
if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
// item is an horizontal separator or a table header, don't mind
continue;
}
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
}
$o = '';
foreach($raw_toc as $t) {
$level = intval($t['level']);
$text = $t['text'];
switch ($level) {
case 1:
$li = '* ';
break;
case 2:
$li = ' * ';
break;
case 3:
$li = ' * ';
break;
case 4:
$li = ' * ';
break;
default:
$li = '* ';
break;
}
$o .= $li . $text . "\n";
}
return $o;
}
}

146
Zotlabs/Lib/Permcat.php Normal file
View File

@@ -0,0 +1,146 @@
<?php
namespace Zotlabs\Lib;
use \Zotlabs\Access as Zaccess;
class Permcat {
private $permcats = [];
public function __construct($channel_id) {
$perms = [];
// first check role perms for a perms_connect setting
$role = get_pconfig($channel_id,'system','permissions_role');
if($role) {
$x = Zaccess\PermissionRoles::role_perms($role);
if($x['perms_connect']) {
$perms = Zaccess\Permissions::FilledPerms($x['perms_connect']);
}
}
// if no role perms it may be a custom role, see if there any autoperms
if(! $perms) {
$perms = Zaccess\Permissions::FilledAutoPerms($channel_id);
}
// if no autoperms it may be a custom role with manual perms
if(! $perms) {
$r = q("select channel_hash from channel where channel_id = %d",
intval($channel_id)
);
if($r) {
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
intval($channel_id),
dbesc($r[0]['channel_hash'])
);
if($x) {
foreach($x as $xv) {
$perms[$xv['k']] = intval($xv['v']);
}
}
}
}
// nothing was found - create a filled permission array where all permissions are 0
if(! $perms) {
$perms = Zaccess\Permissions::FilledPerms([]);
}
$this->permcats[] = [
'name' => 'default',
'localname' => t('default','permcat'),
'perms' => Zaccess\Permissions::Operms($perms),
'system' => 1
];
$p = $this->load_permcats($channel_id);
if($p) {
for($x = 0; $x < count($p); $x++) {
$this->permcats[] = [
'name' => $p[$x][0],
'localname' => $p[$x][1],
'perms' => Zaccess\Permissions::Operms(Zaccess\Permissions::FilledPerms($p[$x][2])),
'system' => intval($p[$x][3])
];
}
}
}
public function listing() {
return $this->permcats;
}
public function fetch($name) {
if($name && $this->permcats) {
foreach($this->permcats as $permcat) {
if(strcasecmp($permcat['name'],$name) === 0) {
return $permcat;
}
}
}
return ['error' => true];
}
public function load_permcats($uid) {
$permcats = [
[ 'follower', t('follower','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
'post_like' ], 1
],
[ 'contributor', t('contributor','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1
],
[ 'publisher', t('publisher','permcat'),
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages',
'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver',
'chat', 'republish' ], 1
]
];
if($uid) {
$x = q("select * from pconfig where uid = %d and cat = 'permcat'",
intval($uid)
);
if($x) {
foreach($x as $xv) {
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
$permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
}
}
}
call_hooks('permcats',$permcats);
return $permcats;
}
static public function find_permcat($arr,$name) {
if((! $arr) || (! $name))
return false;
foreach($arr as $p)
if($p['name'] == $name)
return $p['value'];
}
static public function update($channel_id, $name,$permarr) {
PConfig::Set($channel_id,'permcat',$name,$permarr);
}
static public function delete($channel_id,$name) {
PConfig::Delete($channel_id,'permcat',$name);
}
}

View File

@@ -136,7 +136,7 @@ class ThreadItem {
$filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false);
$profile_avatar = $item['author']['xchan_photo_m'];
$profile_link = chanlink_url($item['author']['xchan_url']);
$profile_link = chanlink_hash($item['author_xchan']);
$profile_name = $item['author']['xchan_name'];
$location = format_location($item);
@@ -295,7 +295,7 @@ class ThreadItem {
$owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@'));
$viewthread = $item['llink'];
if($conv->get_mode() === 'channel')
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid'];
$viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . urlencode($item['mid']);
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
@@ -335,6 +335,8 @@ class ThreadItem {
'wall' => t('Wall-to-Wall'),
'vwall' => t('via Wall-To-Wall:'),
'profile_url' => $profile_link,
'thread_action_menu' => thread_action_menu($item,$conv->get_mode()),
'thread_author_menu' => thread_author_menu($item,$conv->get_mode()),
'item_photo_menu' => item_photo_menu($item),
'dreport' => $dreport,
'name' => $profile_name,
@@ -407,7 +409,7 @@ class ThreadItem {
'comment' => $this->get_comment_box($indent),
'previewing' => ($conv->is_preview() ? ' preview ' : ''),
'wait' => t('Please wait'),
'submid' => substr($item['mid'],0,32),
'submid' => str_replace(['+','='], ['',''], base64_encode(substr($item['mid'],0,32))),
'thread_level' => $thread_level
);
@@ -765,7 +767,7 @@ class ThreadItem {
return;
if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) {
$this->owner_url = chanlink_url($this->data['owner']['xchan_url']);
$this->owner_url = chanlink_hash($this->data['owner']['xchan_hash']);
$this->owner_photo = $this->data['owner']['xchan_photo_m'];
$this->owner_name = $this->data['owner']['xchan_name'];
$this->wall_to_wall = true;

View File

@@ -19,7 +19,7 @@ require_once("include/group.php");
class Acl extends \Zotlabs\Web\Controller {
function init(){
function init() {
// logger('mod_acl: ' . print_r($_REQUEST,true));
@@ -49,7 +49,7 @@ class Acl extends \Zotlabs\Web\Controller {
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
// The different autocomplete libraries use different names for the search text
// parameter. Internaly we'll use $search to represent the search text no matter
// parameter. Internally we'll use $search to represent the search text no matter
// what request variable it was attached to.
if(array_key_exists('query',$_REQUEST)) {
@@ -87,8 +87,8 @@ class Acl extends \Zotlabs\Web\Controller {
$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, ";
. " then POSITION('" . protect_sprintf(dbesc($search))
. "' IN xchan_name) else position('" . protect_sprintf(dbesc($search)) . "' IN xchan_addr) end, ";
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
@@ -103,7 +103,28 @@ class Acl extends \Zotlabs\Web\Controller {
$contacts = array();
if($type == '' || $type == 'g') {
// virtual groups based on private profile viewing ability
$r = q("select id, profile_guid, profile_name from profile where is_default = 0 and uid = %d",
intval(local_channel())
);
if($r) {
foreach($r as $rv) {
$groups[] = array(
"type" => "g",
"photo" => "images/twopeople.png",
"name" => t('Profile','acl') . ' ' . $rv['profile_name'],
"id" => 'vp' . $rv['id'],
"xid" => 'vp.' . $rv['profile_guid'],
"uids" => group_get_profile_members_xchan(local_channel(), $rv['id']),
"link" => ''
);
}
}
// Normal privacy groups
$r = q("SELECT groups.id, groups.hash, groups.gname
FROM groups, group_member
WHERE groups.deleted = 0 AND groups.uid = %d
@@ -134,25 +155,34 @@ class Acl extends \Zotlabs\Web\Controller {
}
if($type == '' || $type == 'c') {
$extra_channels_sql = '';
// Only include channels who allow the observer to view their permissions
foreach($extra_channels as $channel) {
if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts'))
$extra_channels_sql .= "," . intval($channel);
// Only include channels who allow the observer to view their connections
if($extra_channels) {
foreach($extra_channels as $channel) {
if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts')) {
if($extra_channel_sql)
$extra_channels_sql .= ',';
$extra_channels_sql .= intval($channel);
}
}
}
$extra_channels_sql = substr($extra_channels_sql,1); // Remove initial comma
// Getting info from the abook is better for local users because it contains info about permissions
if(local_channel()) {
if($extra_channels_sql != '')
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
// Add atokens belonging to the local channel @TODO restrict by search
$r2 = null;
$r1 = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);
if($r1) {
require_once('include/security.php');
$r2 = array();
@@ -172,6 +202,7 @@ class Acl extends \Zotlabs\Web\Controller {
}
}
// add connections
$r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, xchan_pubforum, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash

View File

@@ -36,7 +36,7 @@ class Plugins {
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
}
else {
if (!symlink('extend/addon', $addonDir)) {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -57,7 +57,7 @@ class Plugins {
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
$source = 'extend/addon/' . $repoName . '/' . $file;
$source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
@@ -86,7 +86,7 @@ class Plugins {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink('extend/addon', $addonDir)) {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -119,7 +119,7 @@ class Plugins {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink('extend/addon', $addonDir)) {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -156,7 +156,7 @@ class Plugins {
$files = array_diff(scandir($repoDir), array('.', '..'));
foreach ($files as $file) {
if (is_dir($repoDir . '/' . $file) && $file !== '.git') {
$source = 'extend/addon/' . $repoName . '/' . $file;
$source = '../extend/addon/' . $repoName . '/' . $file;
$target = realpath('addon/') . '/' . $file;
unlink($target);
if (!symlink($source, $target)) {
@@ -176,13 +176,13 @@ class Plugins {
$repoURL = $_REQUEST['repoURL'];
$extendDir = 'store/[data]/git/sys/extend';
$addonDir = $extendDir . '/addon';
$tempAddonDir = 'store/[data]/git/sys/temp';
$tempAddonDir = realpath('store/[data]') . '/git/sys/temp';
if (!file_exists($extendDir)) {
if (!mkdir($extendDir, 0770, true)) {
logger('Error creating extend folder: ' . $extendDir);
json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false));
} else {
if (!symlink('extend/addon', $addonDir)) {
if (!symlink(realpath('extend/addon'), $addonDir)) {
logger('Error creating symlink to addon folder: ' . $addonDir);
json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false));
}
@@ -395,6 +395,10 @@ class Plugins {
usort($plugins,'self::plugin_sort');
$allowManageRepos = false;
if(is_writable('extend/addon') && is_writable('store/[data]')) {
$allowManageRepos = true;
}
$admin_plugins_add_repo_form= replace_macros(
get_markup_template('admin_plugins_addrepo.tpl'), array(
@@ -432,6 +436,7 @@ class Plugins {
'$plugins' => $plugins,
'$disabled' => t('Disabled - version incompatibility'),
'$form_security_token' => get_form_security_token('admin_plugins'),
'$allowManageRepos' => $allowManageRepos,
'$managerepos' => t('Manage Repos'),
'$installedtitle' => t('Installed Plugin Repositories'),
'$addnewrepotitle' => t('Install a New Plugin Repository'),

View File

@@ -15,7 +15,6 @@ class Queue {
$expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0);
if($_REQUEST['drophub']) {
require_once('hubloc.php');
hubloc_mark_as_down($_REQUEST['drophub']);
remove_queue_by_posturl($_REQUEST['drophub']);
}

View File

@@ -163,6 +163,14 @@ class Site {
foreach($files as $file) {
$vars = '';
$f = basename($file);
$info = get_theme_info($f);
$compatible = check_plugin_versions($info);
if(!$compatible) {
$theme_choices[$f] = $theme_choices_mobile[$f] = sprintf(t('%s - (Incompatible)'), $f);
continue;
}
if (file_exists($file . '/library'))
continue;
if (file_exists($file . '/mobile'))
@@ -310,4 +318,4 @@ class Site {
));
}
}
}

View File

@@ -230,4 +230,4 @@ class Themes {
}
}

View File

@@ -27,6 +27,7 @@ class Appman extends \Zotlabs\Web\Controller {
'price' => escape_tags($_REQUEST['price']),
'requires' => escape_tags($_REQUEST['requires']),
'system' => intval($_REQUEST['system']),
'plugin' => escape_tags($_REQUEST['plugin']),
'sig' => escape_tags($_REQUEST['sig']),
'categories' => escape_tags($_REQUEST['categories'])
);
@@ -35,8 +36,9 @@ class Appman extends \Zotlabs\Web\Controller {
if(Zlib\Apps::app_installed(local_channel(),$arr))
info( t('App installed.') . EOL);
return;
goaway(z_root() . '/apps');
return; //not reached
}
@@ -56,13 +58,18 @@ class Appman extends \Zotlabs\Web\Controller {
if($_POST['delete']) {
Zlib\Apps::app_destroy(local_channel(),$papp);
}
if($_POST['edit']) {
return;
}
if($_POST['feature']) {
Zlib\Apps::app_feature(local_channel(),$papp);
}
if($_SESSION['return_url'])
goaway(z_root() . '/' . $_SESSION['return_url']);
goaway(z_root() . '/apps');
@@ -75,7 +82,7 @@ class Appman extends \Zotlabs\Web\Controller {
notice( t('Permission denied.') . EOL);
return;
}
$channel = \App::get_channel();
$app = null;
$embed = null;
@@ -121,6 +128,7 @@ class Appman extends \Zotlabs\Web\Controller {
'$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''),
'$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''),
'$system' => (($app) ? intval($app['app_system']) : 0),
'$plugin' => (($app) ? $app['app_plugin'] : ''),
'$requires' => (($app) ? $app['app_requires'] : ''),
'$embed' => $embed,
'$submit' => t('Submit')

View File

@@ -12,16 +12,15 @@ class Apps extends \Zotlabs\Web\Controller {
$mode = 'edit';
else
$mode = 'list';
$_SESSION['return_url'] = \App::$cmd;
$_SESSION['return_url'] = \App::$query_string;
$apps = array();
if(local_channel()) {
Zlib\Apps::import_system_apps();
$syslist = array();
$list = Zlib\Apps::app_list(local_channel(), false, $_GET['cat']);
$list = Zlib\Apps::app_list(local_channel(), (($mode == 'edit') ? true : false), $_GET['cat']);
if($list) {
foreach($list as $x) {
$syslist[] = Zlib\Apps::app_encode($x);
@@ -39,12 +38,15 @@ class Apps extends \Zotlabs\Web\Controller {
foreach($syslist as $app) {
$apps[] = Zlib\Apps::app_render($app,$mode);
}
return replace_macros(get_markup_template('myapps.tpl'), array(
'$sitename' => get_config('system','sitename'),
'$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? ' - ' . escape_tags($_GET['cat']) : ''),
'$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? escape_tags($_GET['cat']) : ''),
'$title' => t('Apps'),
'$apps' => $apps,
'$authed' => ((local_channel()) ? true : false),
'$manage' => t('Manage apps'),
'$create' => (($mode == 'edit') ? t('Create new app') : '')
));
}

View File

@@ -292,8 +292,8 @@ class Cal extends \Zotlabs\Web\Controller {
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
}
$html = format_event_html($rr);
$rr['desc'] = bbcode($rr['desc']);
$rr['location'] = bbcode($rr['location']);
$rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
$rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
$events[] = array(
'id'=>$rr['id'],
'hash' => $rr['event_hash'],

View File

@@ -41,12 +41,20 @@ class Channel extends \Zotlabs\Web\Controller {
$profile = argv(1);
}
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Posts and comments') . '" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n" ;
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" title="' . t('Only posts') . '" href="' . z_root() . '/feed/' . $which . '?top=1" />' . "\r\n" ;
head_add_link( [
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Posts and comments'),
'href' => z_root() . '/feed/' . $which
]);
head_add_link( [
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Only posts'),
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
]);
// Not yet ready for prime time
// \App::$page['htmlhead'] .= '<link rel="openid.server" href="' . z_root() . '/id/' . $which .'?f=" />' . "\r\n" ;
// \App::$page['htmlhead'] .= '<link rel="openid.delegate" href="' . z_root() . '/channel/' . $which .'" />' . "\r\n" ;
// Run profile_load() here to make sure the theme is set before
// we start loading content

View File

@@ -33,9 +33,7 @@ class Chat extends \Zotlabs\Web\Controller {
$which = $channel['channel_address'];
$profile = argv(1);
}
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
// Run profile_load() here to make sure the theme is set before
// we start loading content

View File

@@ -111,8 +111,22 @@ class Chatsvc extends \Zotlabs\Web\Controller {
intval(\App::$data['chat']['room_id'])
);
if($r) {
foreach($r as $rr) {
switch($rr['cp_status']) {
foreach($r as $rv) {
if(! $rv['xchan_name']) {
$rv['xchan_hash'] = $rv['cp_xchan'];
$rv['xchan_name'] = substr($rv['cp_xchan'],strrpos($rv['cp_xchan'],'.')+1);
$rv['xchan_addr'] = '';
$rv['xchan_network'] = 'unknown';
$rv['xchan_url'] = z_root();
$rv['xchan_hidden'] = 1;
$rv['xchan_photo_mimetype'] = 'image/jpeg';
$rv['xchan_photo_l'] = get_default_profile_photo(300);
$rv['xchan_photo_m'] = get_default_profile_photo(80);
$rv['xchan_photo_s'] = get_default_profile_photo(48);
}
switch($rv['cp_status']) {
case 'away':
$status = t('Away');
$status_class = 'away';
@@ -124,7 +138,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
break;
}
$inroom[] = array('img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'],'name' => $rr['xchan_name'], 'status' => $status, 'status_class' => $status_class);
$inroom[] = array('img' => zid($rv['xchan_photo_m']), 'img_type' => $rv['xchan_photo_mimetype'],'name' => $rv['xchan_name'], 'status' => $status, 'status_class' => $status_class);
}
}
@@ -143,7 +157,7 @@ class Chatsvc extends \Zotlabs\Web\Controller {
'name' => $rr['xchan_name'],
'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'),
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'),
'text' => smilies(bbcode($rr['chat_text'])),
'text' => zidify_links(smilies(bbcode($rr['chat_text']))),
'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '')
);
}

View File

@@ -37,8 +37,6 @@ class Cloud extends \Zotlabs\Web\Controller {
$profile = 0;
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
if ($which)
profile_load( $which, $profile);
@@ -59,8 +57,6 @@ class Cloud extends \Zotlabs\Web\Controller {
$auth->observer = $ob_hash;
}
if ($_GET['davguest'])
$_SESSION['davguest'] = true;
$_SERVER['QUERY_STRING'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['QUERY_STRING']);
$_SERVER['QUERY_STRING'] = strip_zids($_SERVER['QUERY_STRING']);

View File

@@ -228,10 +228,18 @@ class Connections extends \Zotlabs\Web\Controller {
$contacts = array();
if(count($r)) {
if($r) {
vcard_query($r);
foreach($r as $rr) {
if($rr['xchan_url']) {
if(($rr['vcard']) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr'])
$phone = ((\App::$is_mobile || \App::$is_tablet) ? $rr['vcard']['tels'][0]['nr'] : '');
else
$phone = '';
$status_str = '';
$status = array(
@@ -261,12 +269,14 @@ class Connections extends \Zotlabs\Web\Controller {
'link' => z_root() . '/connedit/' . $rr['abook_id'],
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
'delete' => t('Delete'),
'url' => chanlink_url($rr['xchan_url']),
'url' => chanlink_hash($rr['xchan_hash']),
'webbie_label' => t('Channel address'),
'webbie' => $rr['xchan_addr'],
'network_label' => t('Network'),
'network' => network_to_name($rr['xchan_network']),
'public_forum' => ((intval($rr['xchan_pubforum'])) ? true : false),
'call' => t('Call'),
'phone' => $phone,
'status_label' => t('Status'),
'status' => $status_str,
'connected_label' => t('Connected'),

View File

@@ -37,7 +37,7 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(argv(1))
);
if($r) {
\App::$poi = $r[0];
\App::$poi = array_shift($r);
}
}
@@ -86,6 +86,12 @@ class Connedit extends \Zotlabs\Web\Controller {
call_hooks('contact_edit_post', $_POST);
$vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard');
$vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
$serialised_vcard = update_vcard($_REQUEST,$vcard);
if($serialised_vcard)
set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$serialised_vcard);
if(intval($orig_record[0]['abook_self'])) {
$autoperms = intval($_POST['autoperms']);
$is_self = true;
@@ -206,6 +212,7 @@ class Connedit extends \Zotlabs\Web\Controller {
}
if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) {
$new_friend = true;
// @fixme it won't be common, but when you accept a new connection request
@@ -215,21 +222,13 @@ class Connedit extends \Zotlabs\Web\Controller {
// request. The workaround is to approve the connection, then go back and
// adjust permissions as desired.
$abook_my_perms = get_channel_default_perms(local_channel());
$role = get_pconfig(local_channel(),'system','permissions_role');
if($role) {
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
if($x['perms_connect']) {
$abook_my_perms = $x['perms_connect'];
$p = \Zotlabs\Access\Permissions::connect_perms(local_channel());
$my_perms = $p['perms'];
if($my_perms) {
foreach($my_perms as $k => $v) {
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
}
}
$filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms);
foreach($filled_perms as $k => $v) {
set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v);
}
}
$abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']);
@@ -246,14 +245,6 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(local_channel())
);
if($orig_record[0]['abook_profile'] != $profile_id) {
//Update profile photo permissions
logger('A new profile was assigned - updating profile photos');
profile_photo_set_profile_perms(local_channel(),$profile_id);
}
if($r)
info( t('Connection updated.') . EOL);
else
@@ -367,7 +358,7 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(\App::$poi['abook_id'])
);
if($r) {
\App::$poi = $r[0];
\App::$poi = array_shift($r);
}
$clone = \App::$poi;
@@ -639,6 +630,15 @@ class Connedit extends \Zotlabs\Web\Controller {
),
);
$sections = [];
$sections['perms'] = [
'label' => t('Permissions'),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=&section=perms',
'sel' => '',
'title' => t('Open Individual Permissions section by default'),
];
$self = false;
@@ -647,17 +647,32 @@ class Connedit extends \Zotlabs\Web\Controller {
$abook_prev = $abook_next = 0;
}
$vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard');
$vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
$vcard = (($vctmp) ? get_vcard_array($vctmp,$contact['abook_id']) : [] );
if(! $vcard)
$vcard['fn'] = $contact['xchan_name'];
$tpl = get_markup_template("abook_edit.tpl");
if(feature_enabled(local_channel(),'affinity')) {
$sections['affinity'] = [
'label' => t('Affinity'),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=&section=affinity',
'sel' => '',
'title' => t('Open Set Affinity section by default'),
];
$labels = array(
$labels = [
t('Me'),
t('Family'),
t('Friends'),
t('Acquaintances'),
t('All')
);
];
call_hooks('affinity_labels',$labels);
$label_str = '';
@@ -679,6 +694,15 @@ class Connedit extends \Zotlabs\Web\Controller {
'$labels' => $label_str,
));
}
if(feature_enabled(local_channel(),'connfilter')) {
$sections['filter'] = [
'label' => t('Filter'),
'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=&section=filter',
'sel' => '',
'title' => t('Open Custom Filter section by default'),
];
}
$rating_val = 0;
$rating_text = '';
@@ -754,6 +778,15 @@ class Connedit extends \Zotlabs\Web\Controller {
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
}
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
$pcatlist = $pcat->listing();
$permcats = [];
if($pcatlist) {
foreach($pcatlist as $pc) {
$permcats[$pc['name']] = $pc['localname'];
}
}
$locstr = '';
$locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s'
@@ -775,12 +808,16 @@ class Connedit extends \Zotlabs\Web\Controller {
else
$locstr = t('none');
$o .= replace_macros($tpl,array(
$o .= replace_macros($tpl, [
'$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])),
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no),
'$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ],
'$permcat_new' => t('Add permission role'),
'$permcat_enable' => feature_enabled(local_channel(),'permcats'),
'$addr' => $contact['xchan_addr'],
'$section' => $section,
'$sections' => $sections,
'$vcard' => $vcard,
'$addr_text' => t('This connection\'s primary address is'),
'$loc_text' => t('Available locations:'),
'$locstr' => $locstr,
@@ -818,13 +855,42 @@ class Connedit extends \Zotlabs\Web\Controller {
'$permnote_self' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'),
'$lastupdtext' => t('Last update:'),
'$last_update' => relative_date($contact['abook_connected']),
'$is_mobile' => ((\App::$is_mobile || \App::$is_tablet) ? true : false),
'$profile_select' => contact_profile_assign($contact['abook_profile']),
'$multiprofs' => $multiprofs,
'$contact_id' => $contact['abook_id'],
'$name' => $contact['xchan_name'],
'$abook_prev' => $abook_prev,
'$abook_next' => $abook_next
));
'$abook_next' => $abook_next,
'$vcard_label' => t('Details'),
'$displayname' => $displayname,
'$name_label' => t('Name'),
'$org_label' => t('Organisation'),
'$title_label' => t('Title'),
'$tel_label' => t('Phone'),
'$email_label' => t('Email'),
'$impp_label' => t('Instant messenger'),
'$url_label' => t('Website'),
'$adr_label' => t('Address'),
'$note_label' => t('Note'),
'$mobile' => t('Mobile'),
'$home' => t('Home'),
'$work' => t('Work'),
'$other' => t('Other'),
'$add_card' => t('Add Contact'),
'$add_field' => t('Add Field'),
'$create' => t('Create'),
'$update' => t('Update'),
'$delete' => t('Delete'),
'$cancel' => t('Cancel'),
'$po_box' => t('P.O. Box'),
'$extra' => t('Additional'),
'$street' => t('Street'),
'$locality' => t('Locality'),
'$region' => t('Region'),
'$zip_code' => t('ZIP Code'),
'$country' => t('Country')
]);
$arr = array('contact' => $contact,'output' => $o);

View File

@@ -68,6 +68,7 @@ class Directory extends \Zotlabs\Web\Controller {
$observer = get_observer_hash();
$globaldir = get_directory_setting($observer, 'globaldir');
// override your personal global search pref if we're doing a navbar search of the directory
if(intval($_REQUEST['navsearch']))
$globaldir = 1;
@@ -262,7 +263,7 @@ class Directory extends \Zotlabs\Web\Controller {
$hometown = ((x($profile,'hometown') == 1) ? $profile['hometown'] : False);
$about = ((x($profile,'about') == 1) ? bbcode($profile['about']) : False);
$about = ((x($profile,'about') == 1) ? zidify_links(bbcode($profile['about'])) : False);
$keywords = ((x($profile,'keywords')) ? $profile['keywords'] : '');

View File

@@ -1,12 +1,17 @@
<?php
namespace Zotlabs\Module;
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/items.php');
class Display extends \Zotlabs\Web\Controller {
function get($update = 0, $load = false) {
$checkjs = new \Zotlabs\Web\CheckJS(1);
if($load)
@@ -18,30 +23,21 @@ class Display extends \Zotlabs\Web\Controller {
return;
}
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/items.php');
\App::$page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array());
if(argc() > 1 && argv(1) !== 'load')
$item_hash = argv(1);
if($_REQUEST['mid'])
$item_hash = $_REQUEST['mid'];
if(! $item_hash) {
if(! $item_hash) {
\App::$error = 404;
notice( t('Item not found.') . EOL);
return;
}
$observer_is_owner = false;
$updateable = false;
if(local_channel() && (! $update)) {
@@ -93,9 +89,15 @@ class Display extends \Zotlabs\Web\Controller {
// find a copy of the item somewhere
$target_item = null;
if(strpos($item_hash,'b64.') === 0)
$decoded = @base64url_decode(substr($item_hash,4));
if($decoded)
$item_hash = $decoded;
$r = q("select id, uid, mid, parent_mid, item_type, item_deleted from item where mid like '%s' limit 1",
dbesc($item_hash . '%')
dbesc($item_hash . '%'),
dbesc($decoded . '%')
);
if($r) {
@@ -180,10 +182,9 @@ class Display extends \Zotlabs\Web\Controller {
$item_normal = item_normal();
$sql_extra = public_permissions_sql($observer_hash);
if(($update && $load) || ($checkjs->disabled())) {
$updateable = false;
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start']));
@@ -193,9 +194,9 @@ class Display extends \Zotlabs\Web\Controller {
require_once('include/channel.php');
$sys = get_sys_channel();
$sysid = $sys['channel_id'];
if(local_channel()) {
$r = q("SELECT * from item
$r = q("SELECT item.id as item_id from item
WHERE uid = %d
and mid = '%s'
$item_normal
@@ -209,6 +210,7 @@ class Display extends \Zotlabs\Web\Controller {
}
}
if($r === null) {
// in case somebody turned off public access to sys channel content using permissions
@@ -218,7 +220,7 @@ class Display extends \Zotlabs\Web\Controller {
$sysid = 0;
$r = q("SELECT * from item
$r = q("SELECT item.id as item_id from item
WHERE mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
@@ -241,11 +243,11 @@ class Display extends \Zotlabs\Web\Controller {
require_once('include/channel.php');
$sys = get_sys_channel();
$sysid = $sys['channel_id'];
if(local_channel()) {
$r = q("SELECT * from item
$r = q("SELECT item.parent AS item_id from item
WHERE uid = %d
and mid = '%s'
and parent_mid = '%s'
$item_normal
$simple_update
limit 1",
@@ -256,14 +258,15 @@ class Display extends \Zotlabs\Web\Controller {
$updateable = true;
}
}
if($r === null) {
// in case somebody turned off public access to sys channel content using permissions
// make that content unsearchable by ensuring the owner_xchan can't match
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
$sysid = 0;
$r = q("SELECT * from item
WHERE mid = '%s'
$r = q("SELECT item.parent AS item_id from item
WHERE parent_mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
@@ -285,7 +288,7 @@ class Display extends \Zotlabs\Web\Controller {
if($r) {
$parents_str = ids_to_querystr($r,'id');
$parents_str = ids_to_querystr($r,'item_id');
if($parents_str) {
$items = q("SELECT item.*, item.id AS item_id
@@ -315,10 +318,10 @@ class Display extends \Zotlabs\Web\Controller {
if($updateable) {
$x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
intval(local_channel()),
intval($r[0]['parent'])
intval($r[0]['item_id'])
);
}
$o .= '<div id="content-complete"></div>';
return $o;

View File

@@ -78,6 +78,7 @@ class Editpost extends \Zotlabs\Web\Controller {
$x = array(
'nickname' => $channel['channel_address'],
'item' => $itm[0],
'editor_autocomplete'=> true,
'bbco_autocomplete'=> 'bbcode',
'return_path' => $_SESSION['return_url'],

View File

@@ -43,6 +43,10 @@ class Events extends \Zotlabs\Web\Controller {
$adjust = intval($_POST['adjust']);
$nofinish = intval($_POST['nofinish']);
$timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
$categories = escape_tags(trim($_POST['category']));
// only allow editing your own events.
@@ -71,9 +75,9 @@ class Events extends \Zotlabs\Web\Controller {
if($adjust) {
$start = datetime_convert(date_default_timezone_get(),'UTC',$start);
$start = datetime_convert($tz,'UTC',$start);
if(! $nofinish)
$finish = datetime_convert(date_default_timezone_get(),'UTC',$finish);
$finish = datetime_convert($tz,'UTC',$finish);
}
else {
$start = datetime_convert('UTC','UTC',$start);
@@ -374,11 +378,14 @@ class Events extends \Zotlabs\Web\Controller {
$event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']);
$mid = ((x($orig_event)) ? $orig_event['mid'] : '');
if(! x($orig_event))
if(! x($orig_event)) {
$sh_checked = '';
else
$a_checked = ' checked="checked" ';
}
else {
$sh_checked = ((($orig_event['allow_cid'] === '<' . $channel['channel_hash'] . '>' || (! $orig_event['allow_cid'])) && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' );
}
if($orig_event['event_xchan'])
$sh_checked .= ' disabled="disabled" ';
@@ -478,6 +485,8 @@ class Events extends \Zotlabs\Web\Controller {
'$allow_gid' => acl2json($permissions['allow_gid']),
'$deny_cid' => acl2json($permissions['deny_cid']),
'$deny_gid' => acl2json($permissions['deny_gid']),
'$tz_choose' => feature_enabled(local_channel(),'event_tz_select'),
'$timezone' => array('timezone_select' , t('Timezone:'), date_default_timezone_get(), '', get_timezones()),
'$lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
@@ -625,14 +634,14 @@ class Events extends \Zotlabs\Web\Controller {
$drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
$title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8'));
$title = strip_tags(html_entity_decode(zidify_links(bbcode($rr['summary'])),ENT_QUOTES,'UTF-8'));
if(! $title) {
list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
$title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
}
$html = format_event_html($rr);
$rr['desc'] = bbcode($rr['desc']);
$rr['location'] = bbcode($rr['location']);
$rr['desc'] = zidify_links(smilies(bbcode($rr['desc'])));
$rr['location'] = zidify_links(smilies(bbcode($rr['location'])));
$events[] = array(
'id'=>$rr['id'],
'hash' => $rr['event_hash'],

View File

@@ -1,71 +0,0 @@
<?php
namespace Zotlabs\Module;
class Ffsapi extends \Zotlabs\Web\Controller {
function get() {
$baseurl = z_root();
$name = get_config('system','sitename');
$description = t('Share content from Firefox to $Projectname');
$author = 'Mike Macgirvin';
$homepage = 'http://hubzilla.org';
$activate = t('Activate the Firefox $Projectname provider');
$s = <<< EOT
<script>
var baseurl = '$baseurl';
var data = {
"origin": baseurl,
// currently required
"name": '$name',
"iconURL": baseurl+"/images/hz-16.png",
"icon32URL": baseurl+"/images/hz-32.png",
"icon64URL": baseurl+"/images/hz-64.png",
// at least one of these must be defined
// "workerURL": baseurl+"/worker.js",
// "sidebarURL": baseurl+"/sidebar.htm",
"shareURL": baseurl+"/rpost?f=&url=%{url}",
// status buttons are scheduled for Firefox 26 or 27
//"statusURL": baseurl+"/statusPanel.html",
// social bookmarks are available in Firefox 26
"markURL": baseurl+"/rbmark?f=&url=%{url}&title=%{title}",
// icons should be 32x32 pixels
// "markedIcon": baseurl+"/images/checkbox-checked-32.png",
// "unmarkedIcon": baseurl+"/images/checkbox-unchecked-32.png",
"unmarkedIcon": baseurl+"/images/hz-bookmark-32.png",
// should be available for display purposes
"description": "$description",
"author": "$author",
"homepageURL": "$homepage",
// optional
"version": "1.0"
}
function activate(node) {
var event = new CustomEvent("ActivateSocialFeature");
var jdata = JSON.stringify(data);
node.setAttribute("data-service", JSON.stringify(data));
node.dispatchEvent(event);
}
</script>
<button onclick="activate(this)" title="$activate" class="btn btn-primary">$activate</button>
EOT;
return $s;
}
}

View File

@@ -56,19 +56,21 @@ class Fhublocs extends \Zotlabs\Web\Controller {
// Create a verified hub location pointing to this site.
$h = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($rr['channel_guid']),
dbesc($rr['channel_guid_sig']),
dbesc($rr['channel_hash']),
dbesc(channel_reddress($rr)),
intval($primary),
dbesc(z_root()),
dbesc(base64url_encode(rsa_sign(z_root(),$rr['channel_prvkey']))),
dbesc(\App::get_hostname()),
dbesc(z_root() . '/post'),
dbesc($sitekey),
dbesc('zot')
$h = hubloc_store_lowlevel(
[
'hubloc_guid' => $rr['channel_guid'],
'hubloc_guid_sig' => $rr['channel_guid_sig'],
'hubloc_hash' => $rr['channel_hash'],
'hubloc_addr' => channel_reddress($rr),
'hubloc_network' => 'zot',
'hubloc_primary' => $primary,
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$rr['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => $sitekey
]
);
if($h)

View File

@@ -29,7 +29,20 @@ class Hcard extends \Zotlabs\Web\Controller {
$profile = $r[0]['profile_guid'];
}
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
head_add_link( [
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Posts and comments'),
'href' => z_root() . '/feed/' . $which
]);
head_add_link( [
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Only posts'),
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
]);
if(! $profile) {
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",

View File

@@ -5,6 +5,7 @@ namespace Zotlabs\Module;
class Hostxrd extends \Zotlabs\Web\Controller {
function init() {
session_write_close();
header('Access-Control-Allow-Origin: *');
header("Content-type: application/xrd+xml");
logger('hostxrd',LOGGER_DEBUG);

View File

@@ -1,4 +1,5 @@
<?php
namespace Zotlabs\Module;
// Import a channel, either by direct file upload or via
@@ -21,33 +22,18 @@ class Import extends \Zotlabs\Web\Controller {
return;
}
$max_identities = account_service_class_fetch($account_id,'total_identities');
$max_friends = account_service_class_fetch($account_id,'total_channels');
$max_feeds = account_service_class_fetch($account_id,'total_feeds');
if($max_identities !== false) {
$r = q("select channel_id from channel where channel_account_id = %d",
intval($account_id)
);
if($r && count($r) > $max_identities) {
notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL);
return;
}
}
$data = null;
$seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0);
$import_posts = ((x($_REQUEST,'import_posts')) ? intval($_REQUEST['import_posts']) : 0);
$src = $_FILES['filename']['tmp_name'];
$filename = basename($_FILES['filename']['name']);
$filesize = intval($_FILES['filename']['size']);
$filetype = $_FILES['filename']['type'];
$completed = ((array_key_exists('import_step',$_SESSION)) ? intval($_SESSION['import_step']) : 0);
if($completed)
logger('saved import step: ' . $_SESSION['import_step']);
$max_friends = account_service_class_fetch($account_id,'total_channels');
$max_feeds = account_service_class_fetch($account_id,'total_feeds');
$data = null;
$seize = ((x($_REQUEST,'make_primary')) ? intval($_REQUEST['make_primary']) : 0);
$import_posts = ((x($_REQUEST,'import_posts')) ? intval($_REQUEST['import_posts']) : 0);
$moving = intval($_REQUEST['moving']);
$src = $_FILES['filename']['tmp_name'];
$filename = basename($_FILES['filename']['name']);
$filesize = intval($_FILES['filename']['size']);
$filetype = $_FILES['filename']['type'];
if($src) {
// This is OS specific and could also fail if your tmpdir isn't very large
@@ -112,14 +98,12 @@ class Import extends \Zotlabs\Web\Controller {
// print_r($data);
if(array_key_exists('user',$data) && array_key_exists('version',$data)) {
require_once('include/Import/import_diaspora.php');
import_diaspora($data);
return;
if(! array_key_exists('compatibility',$data)) {
call_hooks('import_foreign_channel_data',$data);
if($data['handled'])
return;
}
$moving = false;
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
$v1 = substr($data['compatibility']['database'],-4);
$v2 = substr(DB_UPDATE_VERSION,-4);
@@ -140,28 +124,26 @@ class Import extends \Zotlabs\Web\Controller {
if(array_key_exists('channel',$data)) {
if($completed < 1) {
$channel = import_channel($data['channel'], $account_id, $seize);
$max_identities = account_service_class_fetch($account_id,'total_identities');
}
else {
$r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
intval($account_id),
dbesc($channel['channel_guid'])
if($max_identities !== false) {
$r = q("select channel_id from channel where channel_account_id = %d",
intval($account_id)
);
if($r)
$channel = $r[0];
}
if(! $channel) {
logger('mod_import: channel not found. ', print_r($channel,true));
notice( t('Cloned channel not found. Import failed.') . EOL);
return;
if($r && count($r) > $max_identities) {
notice( sprintf( t('Your service plan only allows %d channels.'), $max_identities) . EOL);
return;
}
}
$channel = import_channel($data['channel'], $account_id, $seize);
}
else {
$moving = false;
$channel = \App::get_channel();
}
if(! $channel)
$channel = \App::get_channel();
if(! $channel) {
logger('mod_import: channel not found. ', print_r($channel,true));
notice( t('No channel. Import failed.') . EOL);
@@ -169,18 +151,17 @@ class Import extends \Zotlabs\Web\Controller {
}
if($completed < 2) {
if(is_array($data['config'])) {
import_config($channel,$data['config']);
}
logger('import step 2');
$_SESSION['import_step'] = 2;
if(is_array($data['config'])) {
import_config($channel,$data['config']);
}
logger('import step 2');
if($completed < 3) {
if(array_key_exists('channel',$data)) {
if($data['photo']) {
require_once('include/photo/photo_driver.php');
import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],$account_id,$channel['channel_id']);
@@ -188,41 +169,36 @@ class Import extends \Zotlabs\Web\Controller {
if(is_array($data['profile']))
import_profiles($channel,$data['profile']);
logger('import step 3');
$_SESSION['import_step'] = 3;
}
logger('import step 3');
if($completed < 4) {
if(is_array($data['hubloc']) && (! $moving)) {
import_hublocs($channel,$data['hubloc'],$seize);
}
logger('import step 4');
$_SESSION['import_step'] = 4;
if(is_array($data['hubloc'])) {
import_hublocs($channel,$data['hubloc'],$seize,$moving);
}
if($completed < 5) {
// create new hubloc for the new channel at this site
$r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary,
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )
values ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )",
dbesc($channel['channel_guid']),
dbesc($channel['channel_guid_sig']),
dbesc($channel['channel_hash']),
dbesc(channel_reddress($channel)),
dbesc('zot'),
intval(($seize) ? 1 : 0),
dbesc(z_root()),
dbesc(base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))),
dbesc(\App::get_hostname()),
dbesc(z_root() . '/post'),
dbesc(get_config('system','pubkey'))
logger('import step 4');
// create new hubloc for the new channel at this site
if(array_key_exists('channel',$data)) {
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_hash' => $channel['channel_hash'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_network' => 'zot',
'hubloc_primary' => (($seize) ? 1 : 0),
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_updated' => datetime_convert()
]
);
// reset the original primary hubloc if it is being seized
if($seize) {
@@ -231,221 +207,206 @@ class Import extends \Zotlabs\Web\Controller {
dbesc(z_root())
);
}
logger('import step 5');
$_SESSION['import_step'] = 5;
}
logger('import step 5');
if($completed < 6) {
// import xchans and contact photos
// import xchans and contact photos
if($seize) {
if(array_key_exists('channel',$data) && $seize) {
// replace any existing xchan we may have on this site if we're seizing control
// replace any existing xchan we may have on this site if we're seizing control
$r = q("delete from xchan where xchan_hash = '%s'",
dbesc($channel['channel_hash'])
);
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )",
dbesc($channel['channel_hash']),
dbesc($channel['channel_guid']),
dbesc($channel['channel_guid_sig']),
dbesc($channel['channel_pubkey']),
dbesc(z_root() . "/photo/profile/l/" . $channel['channel_id']),
dbesc(z_root() . "/photo/profile/m/" . $channel['channel_id']),
dbesc(z_root() . "/photo/profile/s/" . $channel['channel_id']),
dbesc(channel_reddress($channel)),
dbesc(z_root() . '/channel/' . $channel['channel_address']),
dbesc(z_root() . '/follow?f=&url=%s'),
dbesc(z_root() . '/poco/' . $channel['channel_address']),
dbesc($channel['channel_name']),
dbesc('zot'),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
0,0,0,0,0,0,0
);
}
logger('import step 6');
$_SESSION['import_step'] = 6;
$r = q("delete from xchan where xchan_hash = '%s'",
dbesc($channel['channel_hash'])
);
$r = xchan_store_lowlevel(
[
'xchan_hash' => $channel['channel_hash'],
'xchan_guid' => $channel['channel_guid'],
'xchan_guid_sig' => $channel['channel_guid_sig'],
'xchan_pubkey' => $channel['channel_pubkey'],
'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
'xchan_addr' => channel_reddress($channel),
'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot',
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert()
]
);
}
if($completed < 7) {
$xchans = $data['xchan'];
if($xchans) {
foreach($xchans as $xchan) {
$hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
logger('forged xchan: ' . print_r($xchan,true));
continue;
}
if(! array_key_exists('xchan_hidden',$xchan)) {
$xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0);
$xchan['xchan_orphan'] = (($xchan['xchan_flags'] & 0x0002) ? 1 : 0);
$xchan['xchan_censored'] = (($xchan['xchan_flags'] & 0x0004) ? 1 : 0);
$xchan['xchan_selfcensored'] = (($xchan['xchan_flags'] & 0x0008) ? 1 : 0);
$xchan['xchan_system'] = (($xchan['xchan_flags'] & 0x0010) ? 1 : 0);
$xchan['xchan_pubforum'] = (($xchan['xchan_flags'] & 0x0020) ? 1 : 0);
$xchan['xchan_deleted'] = (($xchan['xchan_flags'] & 0x1000) ? 1 : 0);
}
$r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1",
dbesc($xchan['xchan_hash'])
);
if($r)
continue;
logger('import step 6');
create_table_from_array('xchan',$xchan);
$xchans = $data['xchan'];
if($xchans) {
foreach($xchans as $xchan) {
$hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) {
logger('forged xchan: ' . print_r($xchan,true));
continue;
}
if(! array_key_exists('xchan_hidden',$xchan)) {
$xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0);
$xchan['xchan_orphan'] = (($xchan['xchan_flags'] & 0x0002) ? 1 : 0);
$xchan['xchan_censored'] = (($xchan['xchan_flags'] & 0x0004) ? 1 : 0);
$xchan['xchan_selfcensored'] = (($xchan['xchan_flags'] & 0x0008) ? 1 : 0);
$xchan['xchan_system'] = (($xchan['xchan_flags'] & 0x0010) ? 1 : 0);
$xchan['xchan_pubforum'] = (($xchan['xchan_flags'] & 0x0020) ? 1 : 0);
$xchan['xchan_deleted'] = (($xchan['xchan_flags'] & 0x1000) ? 1 : 0);
}
$r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1",
dbesc($xchan['xchan_hash'])
);
if($r)
continue;
create_table_from_array('xchan',$xchan);
require_once('include/photo/photo_driver.php');
$photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
if($photos[4])
$photodate = NULL_DATE;
else
$photodate = $xchan['xchan_photo_date'];
require_once('include/photo/photo_driver.php');
$photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
if($photos[4])
$photodate = NULL_DATE;
else
$photodate = $xchan['xchan_photo_date'];
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s'
where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($photodate),
dbesc($xchan['xchan_hash'])
);
}
}
logger('import step 7');
$_SESSION['import_step'] = 7;
}
// FIXME - ensure we have an xchan if somebody is trying to pull a fast one
if($completed < 8) {
$friends = 0;
$feeds = 0;
// import contacts
$abooks = $data['abook'];
if($abooks) {
foreach($abooks as $abook) {
$abook_copy = $abook;
$abconfig = null;
if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
$abconfig = $abook['abconfig'];
unset($abook['abook_id']);
unset($abook['abook_rating']);
unset($abook['abook_rating_text']);
unset($abook['abconfig']);
unset($abook['abook_their_perms']);
unset($abook['abook_my_perms']);
$abook['abook_account'] = $account_id;
$abook['abook_channel'] = $channel['channel_id'];
if(! array_key_exists('abook_blocked',$abook)) {
$abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001 ) ? 1 : 0);
$abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002 ) ? 1 : 0);
$abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004 ) ? 1 : 0);
$abook['abook_archived'] = (($abook['abook_flags'] & 0x0008 ) ? 1 : 0);
$abook['abook_pending'] = (($abook['abook_flags'] & 0x0010 ) ? 1 : 0);
$abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020 ) ? 1 : 0);
$abook['abook_self'] = (($abook['abook_flags'] & 0x0080 ) ? 1 : 0);
$abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0);
}
if($abook['abook_self']) {
$role = get_pconfig($channel['channel_id'],'system','permissions_role');
if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {
q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ",
dbesc($abook['abook_xchan'])
);
}
}
else {
if($max_friends !== false && $friends > $max_friends)
continue;
if($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds))
continue;
}
create_table_from_array('abook',$abook);
$friends ++;
if(intval($abook['abook_feed']))
$feeds ++;
translate_abook_perms_inbound($channel,$abook_copy);
if($abconfig) {
// @fixme does not handle sync of del_abconfig
foreach($abconfig as $abc) {
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
}
}
}
}
logger('import step 8');
$_SESSION['import_step'] = 8;
}
if($completed < 9) {
$groups = $data['group'];
if($groups) {
$saved = array();
foreach($groups as $group) {
$saved[$group['hash']] = array('old' => $group['id']);
if(array_key_exists('name',$group)) {
$group['gname'] = $group['name'];
unset($group['name']);
}
unset($group['id']);
$group['uid'] = $channel['channel_id'];
create_table_from_array('groups',$group);
}
$r = q("select * from groups where uid = %d",
intval($channel['channel_id'])
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($photodate),
dbesc($xchan['xchan_hash'])
);
if($r) {
foreach($r as $rr) {
$saved[$rr['hash']]['new'] = $rr['id'];
}
logger('import step 7');
}
$friends = 0;
$feeds = 0;
// import contacts
$abooks = $data['abook'];
if($abooks) {
foreach($abooks as $abook) {
$abook_copy = $abook;
$abconfig = null;
if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
$abconfig = $abook['abconfig'];
unset($abook['abook_id']);
unset($abook['abook_rating']);
unset($abook['abook_rating_text']);
unset($abook['abconfig']);
unset($abook['abook_their_perms']);
unset($abook['abook_my_perms']);
$abook['abook_account'] = $account_id;
$abook['abook_channel'] = $channel['channel_id'];
if(! array_key_exists('abook_blocked',$abook)) {
$abook['abook_blocked'] = (($abook['abook_flags'] & 0x0001 ) ? 1 : 0);
$abook['abook_ignored'] = (($abook['abook_flags'] & 0x0002 ) ? 1 : 0);
$abook['abook_hidden'] = (($abook['abook_flags'] & 0x0004 ) ? 1 : 0);
$abook['abook_archived'] = (($abook['abook_flags'] & 0x0008 ) ? 1 : 0);
$abook['abook_pending'] = (($abook['abook_flags'] & 0x0010 ) ? 1 : 0);
$abook['abook_unconnected'] = (($abook['abook_flags'] & 0x0020 ) ? 1 : 0);
$abook['abook_self'] = (($abook['abook_flags'] & 0x0080 ) ? 1 : 0);
$abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0);
}
if($abook['abook_self']) {
$role = get_pconfig($channel['channel_id'],'system','permissions_role');
if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {
q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ",
dbesc($abook['abook_xchan'])
);
}
}
}
else {
if($max_friends !== false && $friends > $max_friends)
continue;
if($max_feeds !== false && intval($abook['abook_feed']) && ($feeds > $max_feeds))
continue;
}
create_table_from_array('abook',$abook);
$friends ++;
if(intval($abook['abook_feed']))
$feeds ++;
translate_abook_perms_inbound($channel,$abook_copy);
$group_members = $data['group_member'];
if($group_members) {
foreach($group_members as $group_member) {
unset($group_member['id']);
$group_member['uid'] = $channel['channel_id'];
foreach($saved as $x) {
if($x['old'] == $group_member['gid'])
$group_member['gid'] = $x['new'];
if($abconfig) {
// @fixme does not handle sync of del_abconfig
foreach($abconfig as $abc) {
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
}
create_table_from_array('group_member',$group_member);
}
}
logger('import step 9');
$_SESSION['import_step'] = 9;
logger('import step 8');
}
$groups = $data['group'];
if($groups) {
$saved = array();
foreach($groups as $group) {
$saved[$group['hash']] = array('old' => $group['id']);
if(array_key_exists('name',$group)) {
$group['gname'] = $group['name'];
unset($group['name']);
}
unset($group['id']);
$group['uid'] = $channel['channel_id'];
create_table_from_array('groups',$group);
}
$r = q("select * from groups where uid = %d",
intval($channel['channel_id'])
);
if($r) {
foreach($r as $rr) {
$saved[$rr['hash']]['new'] = $rr['id'];
}
}
}
$group_members = $data['group_member'];
if($group_members) {
foreach($group_members as $group_member) {
unset($group_member['id']);
$group_member['uid'] = $channel['channel_id'];
foreach($saved as $x) {
if($x['old'] == $group_member['gid'])
$group_member['gid'] = $x['new'];
}
create_table_from_array('group_member',$group_member);
}
}
logger('import step 9');
if(is_array($data['obj']))
import_objs($channel,$data['obj']);
@@ -472,6 +433,12 @@ class Import extends \Zotlabs\Web\Controller {
if(is_array($data['menu']))
import_menus($channel,$data['menu']);
if(is_array($data['wiki']))
import_items($channel,$data['wiki'],false,$relocate);
if(is_array($data['webpages']))
import_items($channel,$data['webpages'],false,$relocate);
$addon = array('channel' => $channel,'data' => $data);
call_hooks('import_channel',$addon);
@@ -487,9 +454,6 @@ class Import extends \Zotlabs\Web\Controller {
if(array_key_exists('item_id',$data) && $data['item_id'])
import_item_ids($channel,$data['item_id']);
// FIXME - ensure we have a self entry if somebody is trying to pull a fast one
// send out refresh requests
// notify old server that it may no longer be primary.
@@ -504,7 +468,6 @@ class Import extends \Zotlabs\Web\Controller {
change_channel($channel['channel_id']);
unset($_SESSION['import_step']);
goaway(z_root() . '/network' );
}
@@ -536,7 +499,8 @@ class Import extends \Zotlabs\Web\Controller {
'$label_old_pass' => t('Your old login password'),
'$common' => t('For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media.'),
'$label_import_primary' => t('Make this hub my primary location'),
'$label_import_posts' => t('Import existing posts if possible (experimental - limited by available memory'),
'$label_import_moving' => t('Move this channel (disable all previous locations)'),
'$label_import_posts' => t('Import a few months of posts if possible (limited by available memory'),
'$pleasewait' => t('This process may take several minutes to complete. Please submit the form only once and leave this page open until finished.'),
'$email' => '',
'$pass' => '',

View File

@@ -21,6 +21,7 @@ require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/attach.php');
require_once('include/bbcode.php');
require_once('include/security.php');
use \Zotlabs\Lib as Zlib;
@@ -34,9 +35,7 @@ class Item extends \Zotlabs\Web\Controller {
if((! local_channel()) && (! remote_channel()) && (! x($_REQUEST,'commenter')))
return;
require_once('include/security.php');
$uid = local_channel();
$channel = null;
$observer = null;
@@ -141,6 +140,7 @@ class Item extends \Zotlabs\Web\Controller {
$item_flags = $item_restrict = 0;
$expires = NULL_DATE;
$route = '';
$parent_item = null;
@@ -395,6 +395,7 @@ class Item extends \Zotlabs\Web\Controller {
$postopts = $orig_post['postopts'];
$created = $orig_post['created'];
$expires = $orig_post['expires'];
$mid = $orig_post['mid'];
$parent_mid = $orig_post['parent_mid'];
$plink = $orig_post['plink'];
@@ -428,7 +429,9 @@ class Item extends \Zotlabs\Web\Controller {
$body = trim($_REQUEST['body']);
$body .= trim($_REQUEST['attachment']);
$postopts = '';
$allow_empty = ((array_key_exists('allow_empty',$_REQUEST)) ? intval($_REQUEST['allow_empty']) : 0);
$private = intval($acl->is_private() || ($public_policy));
// If this is a comment, set the permissions from the parent.
@@ -441,7 +444,7 @@ class Item extends \Zotlabs\Web\Controller {
$owner_hash = $parent_item['owner_xchan'];
}
if(! strlen($body)) {
if((! $allow_empty) && (! strlen($body))) {
if($preview)
killme();
info( t('Empty post discarded.') . EOL );
@@ -454,7 +457,6 @@ class Item extends \Zotlabs\Web\Controller {
}
$expires = NULL_DATE;
if(feature_enabled($profile_uid,'content_expire')) {
if(x($_REQUEST,'expire')) {
@@ -463,7 +465,8 @@ class Item extends \Zotlabs\Web\Controller {
$expires = NULL_DATE;
}
}
$mimetype = notags(trim($_REQUEST['mimetype']));
if(! $mimetype)
$mimetype = 'text/bbcode';
@@ -520,7 +523,7 @@ class Item extends \Zotlabs\Web\Controller {
// <img src="javascript:alert('hacked');" />
// if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) {
// require_once('include/bb2diaspora.php');
// require_once('include/markdown.php');
// $body = escape_tags(trim($body));
// $body = str_replace("\n",'<br />', $body);
// $body = preg_replace_callback('/\[share(.*?)\]/ism','\share_shield',$body);
@@ -556,42 +559,8 @@ class Item extends \Zotlabs\Web\Controller {
if($x)
$body .= "\n\n@group+" . $x[0]['abook_id'] . "\n";
}
/**
* fix naked links by passing through a callback to see if this is a hubzilla site
* (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both.
* First protect any url inside certain bbcode tags so we don't double link it.
*/
$body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\(\)]+)/ism", 'nakedoembed', $body);
$body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\(\)]+)/ism", '\red_zrl_callback', $body);
$body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body);
$body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body);
$body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body);
// fix any img tags that should be zmg
$body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body);
$body = bb_translate_video($body);
/**
* Fold multi-line [code] sequences
*/
$body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body);
$body = scale_external_images($body,false);
$body = cleanup_bbcode($body);
// Look for tags and linkify them
$results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid);
@@ -755,6 +724,8 @@ class Item extends \Zotlabs\Web\Controller {
if(! $mid) {
$mid = (($message_id) ? $message_id : item_message_id());
}
if(! $parent_mid) {
$parent_mid = $mid;
}
@@ -768,7 +739,7 @@ class Item extends \Zotlabs\Web\Controller {
$thr_parent = $mid;
$datarray = array();
$item_thread_top = ((! $parent) ? 1 : 0);
if ((! $plink) && ($item_thread_top)) {
@@ -966,7 +937,7 @@ class Item extends \Zotlabs\Web\Controller {
'from_xchan' => $datarray['author_xchan'],
'to_xchan' => $datarray['owner_xchan'],
'item' => $datarray,
'link' => z_root() . '/display/' . $datarray['mid'],
'link' => z_root() . '/display/' . gen_link_id($datarray['mid']),
'verb' => ACTIVITY_POST,
'otype' => 'item',
'parent' => $parent,
@@ -984,7 +955,7 @@ class Item extends \Zotlabs\Web\Controller {
'from_xchan' => $datarray['author_xchan'],
'to_xchan' => $datarray['owner_xchan'],
'item' => $datarray,
'link' => z_root() . '/display/' . $datarray['mid'],
'link' => z_root() . '/display/' . gen_link_id($datarray['mid']),
'verb' => ACTIVITY_POST,
'otype' => 'item'
));
@@ -1036,7 +1007,7 @@ class Item extends \Zotlabs\Web\Controller {
}
$datarray['id'] = $post_id;
$datarray['llink'] = z_root() . '/display/' . $channel['channel_address'] . '/' . $post_id;
$datarray['llink'] = z_root() . '/display/' . gen_link_id($datarray['mid']);
call_hooks('post_local_end', $datarray);
@@ -1070,9 +1041,7 @@ class Item extends \Zotlabs\Web\Controller {
if((! local_channel()) && (! remote_channel()))
return;
require_once('include/security.php');
if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) {
require_once('include/items.php');

View File

@@ -447,7 +447,7 @@ class Like extends \Zotlabs\Web\Controller {
$arr['thr_parent'] = $item['mid'];
$ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$allow_cid = $item['allow_cid'];
$allow_gid = $item['allow_gid'];
$deny_cid = $item['deny_cid'];

View File

@@ -32,10 +32,10 @@ class Lockview extends \Zotlabs\Web\Controller {
if(! $item_id)
killme();
if (!in_array($type, array('item','photo','event', 'menu_item', 'chatroom')))
if (! in_array($type, array('item', 'photo', 'attach', 'event', 'menu_item', 'chatroom')))
killme();
//we have different naming in in menu_item table and chatroom table
// we have different naming in in menu_item table and chatroom table
switch($type) {
case 'menu_item':
$id = 'mitem_id';
@@ -101,6 +101,22 @@ class Lockview extends \Zotlabs\Web\Controller {
stringify_array_elms($deny_groups,true);
stringify_array_elms($deny_users,true);
$profile_groups = [];
if($allowed_groups) {
foreach($allowed_groups as $g) {
if(substr($g,0,4) === '\'vp.') {
$profile_groups[] = '\'' . substr($g,4);
}
}
}
if(count($profile_groups)) {
$r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
if($r)
foreach($r as $rr)
$l[] = '<li><b>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</b></li>';
}
if(count($allowed_groups)) {
$r = q("SELECT gname FROM groups WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
if($r)
@@ -120,6 +136,25 @@ class Lockview extends \Zotlabs\Web\Controller {
}
}
}
$profile_groups = [];
if($deny_groups) {
foreach($deny_groups as $g) {
if(substr($g,0,4) === '\'vp.') {
$profile_groups[] = '\'' . substr($g,4);
}
}
}
if(count($profile_groups)) {
$r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
if($r)
foreach($r as $rr)
$l[] = '<li><b><strike>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</strike></b></li>';
}
if(count($deny_groups)) {
$r = q("SELECT gname FROM groups WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
if($r)

View File

@@ -23,7 +23,34 @@ class Mail extends \Zotlabs\Web\Controller {
$rstr = ((x($_REQUEST,'messagerecip')) ? notags(trim($_REQUEST['messagerecip'])) : '');
$preview = ((x($_REQUEST,'preview')) ? intval($_REQUEST['preview']) : 0);
$expires = ((x($_REQUEST,'expires')) ? datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['expires']) : NULL_DATE);
if($preview) {
$body = cleanup_bbcode($body);
$results = linkify_tags($a, $body, local_channel());
if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) {
$attachments = array();
foreach($match[2] as $mtch) {
$hash = substr($mtch,0,strpos($mtch,','));
$rev = intval(substr($mtch,strpos($mtch,',')));
$r = attach_by_hash_nodata($hash,get_observer_hash(),$rev);
if($r['success']) {
$attachments[] = array(
'href' => z_root() . '/attach/' . $r['data']['hash'],
'length' => $r['data']['filesize'],
'type' => $r['data']['filetype'],
'title' => urlencode($r['data']['filename']),
'revision' => $r['data']['revision']
);
}
$body = trim(str_replace($match[1],'',$body));
}
}
echo json_encode(['preview' => zidify_links(smilies(bbcode($body)))]);
killme();
}
// If we have a raw string for a recipient which hasn't been auto-filled,
// it means they probably aren't in our address book, hence we don't know
// if we have permission to send them private messages.
@@ -82,6 +109,8 @@ class Mail extends \Zotlabs\Web\Controller {
require_once('include/text.php');
linkify_tags($a, $body, local_channel());
// I don't think this is used any more.
if($preview) {
$mail = [
'mailbox' => 'outbox',
@@ -90,8 +119,8 @@ class Mail extends \Zotlabs\Web\Controller {
'from_name' => $channel['xchan_name'],
'from_url' => $channel['xchan_url'],
'from_photo' => $channel['xchan_photo_s'],
'subject' => smilies(bbcode($subject)),
'body' => smilies(bbcode($body)),
'subject' => zidify_links(smilies(bbcode($subject))),
'body' => zidify_links(smilies(bbcode($body))),
'attachments' => '',
'can_recall' => false,
'is_recalled' => '',
@@ -341,7 +370,7 @@ class Mail extends \Zotlabs\Web\Controller {
'to_url' => chanlink_hash($message['to_xchan']),
'to_photo' => $message['to']['xchan_photo_s'],
'subject' => $message['title'],
'body' => smilies(bbcode($message['body'])),
'body' => zidify_links(smilies(bbcode($message['body']))),
'attachments' => $s,
'delete' => t('Delete message'),
'dreport' => t('Delivery report'),

View File

@@ -1,84 +0,0 @@
<?php
namespace Zotlabs\Module;
/**
* @brief Controller for /match.
*
* It takes keywords from your profile and queries the directory server for
* matching keywords from other profiles.
*
* @FIXME this has never been properly ported from Friendica.
*
* @param App &$a
* @return void|string
*/
class Match extends \Zotlabs\Web\Controller {
function get() {
$o = '';
if (! local_channel())
return;
$_SESSION['return_url'] = z_root() . '/' . \App::$cmd;
$o .= '<h2>' . t('Profile Match') . '</h2>';
$r = q("SELECT keywords FROM profile WHERE is_default = 1 AND uid = %d LIMIT 1",
intval(local_channel())
);
if (! count($r))
return;
if (! $r[0]['keywords']) {
notice( t('No keywords to match. Please add keywords to your default profile.') . EOL);
return;
}
$params = array();
$tags = trim($r[0]['keywords']);
if ($tags) {
$params['s'] = $tags;
if (\App::$pager['page'] != 1)
$params['p'] = \App::$pager['page'];
// if(strlen(get_config('system','directory_submit_url')))
// $x = post_url('http://dir.friendica.com/msearch', $params);
// else
// $x = post_url(z_root() . '/msearch', $params);
$j = json_decode($x);
if ($j->total) {
\App::set_pager_total($j->total);
\App::set_pager_itemspage($j->items_page);
}
if (count($j->results)) {
$tpl = get_markup_template('match.tpl');
foreach ($j->results as $jj) {
$connlnk = z_root() . '/follow/?url=' . $jj->url;
$o .= replace_macros($tpl,array(
'$url' => zid($jj->url),
'$name' => $jj->name,
'$photo' => $jj->photo,
'$inttxt' => ' ' . t('is interested in:'),
'$conntxt' => t('Connect'),
'$connlnk' => $connlnk,
'$tags' => $jj->tags
));
}
} else {
info( t('No matches') . EOL);
}
}
$o .= cleardiv();
$o .= paginate($a);
return $o;
}
}

View File

@@ -79,7 +79,7 @@ class Message extends \Zotlabs\Web\Controller {
'to_photo' => $rr['to']['xchan_photo_s'],
'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
'delete' => t('Delete conversation'),
'body' => smilies(bbcode($rr['body'])),
'body' => zidify_links(smilies(bbcode($rr['body']))),
'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')),
'seen' => $rr['seen']
);

View File

@@ -89,7 +89,7 @@ class Mood extends \Zotlabs\Web\Controller {
$item['item_thread_top'] = 1;
if ((! $arr['plink']) && intval($arr['item_thread_top'])) {
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
}

View File

@@ -23,10 +23,13 @@ class Notifications extends \Zotlabs\Web\Controller {
if($r) {
$notifications_available = 1;
foreach ($r as $it) {
$x = strip_tags(bbcode($it['msg']));
if(strpos($x,','))
$x = substr($x,strpos($x,',')+1);
$notif_content .= replace_macros(get_markup_template('notify.tpl'),array(
'$item_link' => z_root().'/notify/view/'. $it['id'],
'$item_image' => $it['photo'],
'$item_text' => strip_tags(bbcode($it['msg'])),
'$item_text' => $x,
'$item_when' => relative_date($it['created'])
));
}

View File

@@ -16,7 +16,7 @@ class Oexchange extends \Zotlabs\Web\Controller {
}
}
function get() {
function get() {
if(! local_channel()) {
if(remote_channel()) {

View File

@@ -1,24 +0,0 @@
<?php
namespace Zotlabs\Module;
class Opensearch extends \Zotlabs\Web\Controller {
function init() {
$tpl = get_markup_template('opensearch.tpl');
header("Content-type: application/opensearchdescription+xml");
$o = replace_macros($tpl, array(
'$baseurl' => z_root(),
'$nodename' => \App::get_hostname(),
));
echo $o;
killme();
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Zotlabs\Module;
use \Zotlabs\Lib as Zlib;
class Permcat extends \Zotlabs\Web\Controller {
private $permcats = [];
public function init() {
if(! local_channel())
return;
$permcat = new Zlib\Permcat(local_channel());
if(argc() > 1)
json_return_and_die($permcat->fetch(argv(1)));
json_return_and_die($permcat->listing());
}
}

View File

@@ -188,13 +188,12 @@ class Photos extends \Zotlabs\Web\Controller {
}
if((argc() > 2) && (x($_REQUEST,'delete')) && ($_REQUEST['delete'] === t('Delete Photo'))) {
// same as above but remove single photo
$ob_hash = get_observer_hash();
if(! $ob_hash)
goaway(z_root() . '/' . $_SESSION['photo_return']);
$r = q("SELECT id, resource_id FROM photo WHERE ( xchan = '%s' or uid = %d ) AND resource_id = '%s' LIMIT 1",
dbesc($ob_hash),
intval(local_channel()),
@@ -686,36 +685,32 @@ class Photos extends \Zotlabs\Web\Controller {
notice( t('Album name could not be decoded') . EOL);
logger('mod_photos: illegal album encoding: ' . $datum);
$datum = '';
goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
}
}
$album = (($datum) ? hex2bin($datum) : '');
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
$r = q("SELECT resource_id, max(imgscale) AS imgscale FROM photo WHERE uid = %d AND album = '%s'
AND imgscale <= 4 and photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id",
//check if the album exists and if we have perms
$r = q("SELECT album FROM photo WHERE uid = %d AND album = '%s' and is_nsfw = %d $sql_extra LIMIT 1",
intval($owner_uid),
dbesc($album),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
intval($unsafe)
);
if(count($r)) {
\App::set_pager_total(count($r));
if($r) {
\App::set_pager_itemspage(60);
} else {
goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
}
if($_GET['order'] === 'posted')
$order = 'ASC';
else
$order = 'DESC';
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
(SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id) ph
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
@@ -1280,9 +1275,9 @@ class Photos extends \Zotlabs\Web\Controller {
// Default - show recent photos with upload link (if applicable)
//$o = '';
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
/*
$r = q("SELECT resource_id, max(imgscale) AS imgscale FROM photo WHERE uid = %d
and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY resource_id",
intval(\App::$data['channel']['channel_id']),
@@ -1294,6 +1289,9 @@ class Photos extends \Zotlabs\Web\Controller {
\App::set_pager_total(count($r));
\App::set_pager_itemspage(60);
}
*/
\App::set_pager_itemspage(60);
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo p
INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo

View File

@@ -37,8 +37,21 @@ class Profile extends \Zotlabs\Web\Controller {
$profile = $r[0]['profile_guid'];
}
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which .'" />' . "\r\n" ;
head_add_link( [
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Posts and comments'),
'href' => z_root() . '/feed/' . $which
]);
head_add_link( [
'rel' => 'alternate',
'type' => 'application/atom+xml',
'title' => t('Only posts'),
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
]);
if(! $profile) {
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
dbesc(argv(1))
@@ -60,7 +73,9 @@ class Profile extends \Zotlabs\Web\Controller {
}
$groups = array();
$tab = 'profile';
$o = '';
@@ -69,6 +84,15 @@ class Profile extends \Zotlabs\Web\Controller {
return;
}
if(argc() > 2 && argv(2) === 'vcard') {
header('Content-type: text/vcard');
header('content-disposition: attachment; filename="' . t('vcard') . '-' . $profile['channel_address'] . '.vcf"' );
echo \App::$profile['profile_vcard'];
killme();
}
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);

View File

@@ -180,6 +180,14 @@ class Profile_photo extends \Zotlabs\Web\Controller {
dbesc(datetime_convert()),
dbesc($channel['xchan_hash'])
);
photo_profile_setperms(local_channel(),$base_image['resource_id'],$_REQUEST['profile']);
$sync = attach_export_data($channel,$base_image['resource_id']);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
// Similarly, tell the nav bar to bypass the cache and update the avater image.
$_SESSION['reload_avatar'] = true;
@@ -188,9 +196,6 @@ class Profile_photo extends \Zotlabs\Web\Controller {
// Update directory in background
\Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id']));
// Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
profile_photo_set_profile_perms(local_channel(),$_REQUEST['profile']);
}
else
notice( t('Unable to process image') . EOL);
@@ -338,7 +343,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
dbesc($channel['xchan_hash'])
);
profile_photo_set_profile_perms(local_channel()); // Reset default photo permissions to public
photo_profile_setperms(local_channel(),$resource_id,$_REQUEST['profile']);
$sync = attach_export_data($channel,$resource_id);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
goaway(z_root() . '/profiles');
}

View File

@@ -70,15 +70,16 @@ class Profiles extends \Zotlabs\Web\Controller {
$r1 = q("SELECT fullname, photo, thumb FROM profile WHERE uid = %d AND is_default = 1 LIMIT 1",
intval(local_channel()));
$r2 = q("INSERT INTO profile (aid, uid , profile_guid, profile_name , fullname, photo, thumb)
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
intval(get_account_id()),
intval(local_channel()),
dbesc(random_string()),
dbesc($name),
dbesc($r1[0]['fullname']),
dbesc($r1[0]['photo']),
dbesc($r1[0]['thumb'])
$r2 = profile_store_lowlevel(
[
'aid' => intval(get_account_id()),
'uid' => intval(local_channel()),
'profile_guid' => random_string(),
'profile_name' => $name,
'fullname' => $r1[0]['fullname'],
'photo' => $r1[0]['photo'],
'thumb' => $r1[0]['thumb']
]
);
$r3 = q("SELECT id FROM profile WHERE uid = %d AND profile_name = '%s' LIMIT 1",
@@ -191,7 +192,7 @@ class Profiles extends \Zotlabs\Web\Controller {
}
}
function post() {
function post() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
@@ -243,6 +244,7 @@ class Profiles extends \Zotlabs\Web\Controller {
check_form_security_token_redirectOnErr('/profiles', 'profile_edit');
$is_default = (($orig[0]['is_default']) ? 1 : 0);
$profile_name = notags(trim($_POST['profile_name']));
@@ -315,6 +317,43 @@ class Profiles extends \Zotlabs\Web\Controller {
$hide_friends = ((intval($_POST['hide_friends'])) ? 1: 0);
$orig_vcard = (($orig[0]['profile_vcard']) ? \Sabre\VObject\Reader::read($orig[0]['profile_vcard']) : null);
$channel = \App::get_channel();
$default_vcard_cat = ((defined('DEFAULT_VCARD_CAT')) ? DEFAULT_VCARD_CAT : 'HOME');
$defcard = [
'fn' => $name,
'title' => $pdesc,
'photo' => $channel['xchan_photo_l'],
'adr' => [],
'adr_type' => [ $default_vcard_cat ],
'tel' => [],
'tel_type' => [ $default_vcard_cat ],
'email' => [],
'email_type' => [ $default_vcard_cat ],
'impp' => [],
'impp_type' => [ $default_vcard_cat ],
'url' => [],
'url_type' => [ $default_vcard_cat ]
];
$defcard['adr'][] = [
0 => '',
1 => '',
2 => $address,
3 => $locality,
4 => $region,
5 => $postal_code,
6 => $country_name
];
$profile_vcard = update_vcard($defcard,$orig_vcard);
require_once('include/text.php');
linkify_tags($a, $likes, local_channel());
linkify_tags($a, $dislikes, local_channel());
@@ -511,7 +550,8 @@ class Profiles extends \Zotlabs\Web\Controller {
romance = '%s',
employment = '%s',
education = '%s',
hide_friends = %d
hide_friends = %d,
profile_vcard = '%s'
WHERE id = %d AND uid = %d",
dbesc($profile_name),
dbesc($name),
@@ -546,6 +586,7 @@ class Profiles extends \Zotlabs\Web\Controller {
dbesc($work),
dbesc($education),
intval($hide_friends),
dbesc($profile_vcard),
intval(argv(1)),
intval(local_channel())
);

View File

@@ -22,7 +22,7 @@ class Profperm extends \Zotlabs\Web\Controller {
}
function get() {
function get() {
if(! local_channel()) {
notice( t('Permission denied') . EOL);
@@ -94,12 +94,8 @@ class Profperm extends \Zotlabs\Web\Controller {
}
//Time to update the permissions on the profile-pictures as well
profile_photo_set_profile_perms(local_channel(),$profile['id']);
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'",
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d AND abook_profile = '%s'",
intval(local_channel()),
dbesc($profile['profile_guid'])
);

View File

@@ -70,13 +70,12 @@ class Rmagic extends \Zotlabs\Web\Controller {
function get() {
$o = replace_macros(get_markup_template('rmagic.tpl'),array(
'$title' => t('Remote Authentication'),
'$desc' => t('Enter your channel address (e.g. channel@example.com)'),
'$submit' => t('Authenticate')
));
return $o;
return replace_macros(get_markup_template('rmagic.tpl'),
[
'$title' => t('Remote Authentication'),
'$address' => [ 'address', t('Enter your channel address (e.g. channel@example.com)'), '', '' ],
'$submit' => t('Authenticate')
]
);
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Zotlabs\Module;
class Rsd_xml extends \Zotlabs\Web\Controller {
function init() {
header ("Content-Type: text/xml");
echo replace_macros(get_markup_template('rsd.tpl'),array(
'$project' => \Zotlabs\Lib\System::get_platform_name(),
'$baseurl' => z_root(),
'$apipath' => z_root() . '/api/'
));
killme();
}
}

View File

@@ -211,7 +211,7 @@ class Search extends \Zotlabs\Web\Controller {
$result = array();
require_once('include/conversation.php');
foreach($items as $item) {
$item['html'] = bbcode($item['body']);
$item['html'] = zidify_links(bbcode($item['body']));
$x = encode_item($item);
$x['html'] = prepare_text($item['body'],$item['mimetype']);
$result[] = $x;

View File

@@ -18,6 +18,7 @@ class Channel {
$role = ((x($_POST,'permissions_role')) ? notags(trim($_POST['permissions_role'])) : '');
$oldrole = get_pconfig(local_channel(),'system','permissions_role');
if(($role != $oldrole) || ($role === 'custom')) {
@@ -88,15 +89,17 @@ class Channel {
intval(local_channel())
);
}
$x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
foreach($x as $k => $v) {
set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v);
if($role_permissions['perms_auto']) {
set_pconfig(local_channel(),'autoperms',$k,$v);
}
else {
del_pconfig(local_channel(),'autoperms',$k);
if($role_permissions['perms_connect']) {
$x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
foreach($x as $k => $v) {
set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v);
if($role_permissions['perms_auto']) {
set_pconfig(local_channel(),'autoperms',$k,$v);
}
else {
del_pconfig(local_channel(),'autoperms',$k);
}
}
}
@@ -142,6 +145,7 @@ class Channel {
$post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0);
$post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0);
$adult = (($_POST['adult'] == 1) ? 1 : 0);
$defpermcat = ((x($_POST,'defpermcat')) ? notags(trim($_POST['defpermcat'])) : 'default');
$cal_first_day = (((x($_POST,'first_day')) && (intval($_POST['first_day']) == 1)) ? 1: 0);
@@ -230,6 +234,7 @@ class Channel {
set_pconfig(local_channel(),'system','photo_path',$photo_path);
set_pconfig(local_channel(),'system','attach_path',$attach_path);
set_pconfig(local_channel(),'system','cal_first_day',$cal_first_day);
set_pconfig(local_channel(),'system','default_permcat',$defpermcat);
$r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d $set_perms where channel_id = %d",
dbesc($username),
@@ -409,6 +414,19 @@ class Channel {
'$basepath' => \App::get_hostname()
));
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
$pcatlist = $pcat->listing();
$permcats = [];
if($pcatlist) {
foreach($pcatlist as $pc) {
$permcats[$pc['name']] = $pc['localname'];
}
}
$default_permcat = get_pconfig(local_channel(),'system','default_permcat','default');
$stpl = get_markup_template('settings.tpl');
@@ -448,7 +466,10 @@ class Channel {
$always_show_in_notices = get_pconfig(local_channel(),'system','always_show_in_notices');
if($vnotify === false)
$vnotify = (-1);
$plugin = [ 'basic' => '', 'security' => '', 'notify' => '', 'misc' => '' ];
call_hooks('channel_settings',$plugin);
$o .= replace_macros($stpl,array(
'$ptitle' => t('Channel Settings'),
@@ -495,7 +516,8 @@ class Channel {
'$suggestme' => $suggestme,
'$group_select' => $group_select,
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', $perm_roles),
'$defpermcat' => [ 'defpermcat', t('Default Permissions Group'), $default_permcat, '', $permcats ],
'$permcat_enable' => feature_enabled(local_channel(),'permcats'),
'$profile_in_dir' => $profile_in_dir,
'$hide_friends' => $hide_friends,
'$hide_wall' => $hide_wall,
@@ -537,6 +559,10 @@ class Channel {
'$always_show_in_notices' => array('always_show_in_notices', t('Also show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no),
'$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')),
'$basic_addon' => $plugin['basic'],
'$sec_addon' => $plugin['security'],
'$notify_addon' => $plugin['notify'],
'$misc_addon' => $plugin['misc'],
'$h_advn' => t('Advanced Account/Page Type Settings'),
'$h_descadvn' => t('Change the behaviour of this account for special situations'),

View File

@@ -65,7 +65,7 @@ class Display {
set_pconfig(local_channel(),'system','manual_conversation_update', $manual_update);
$newschema = '';
if($theme == $existing_theme){
if($theme){
// call theme_post only if theme has not been changed
if( ($themeconfigfile = $this->get_theme_config_file($theme)) != null){
require_once($themeconfigfile);
@@ -130,12 +130,20 @@ class Display {
if($allowed_themes) {
foreach($allowed_themes as $th) {
$f = $th;
$info = get_theme_info($th);
$compatible = check_plugin_versions($info);
if(!$compatible) {
$mobile_themes[$f] = $themes[$f] = sprintf(t('%s - (Incompatible)'), $f);
continue;
}
$is_experimental = file_exists('view/theme/' . $th . '/experimental');
$unsupported = file_exists('view/theme/' . $th . '/unsupported');
$is_mobile = file_exists('view/theme/' . $th . '/mobile');
$is_library = file_exists('view/theme/'. $th . '/library');
$mobile_themes["---"] = t("No special theme for mobile devices");
$mobile_themes['---'] = t("No special theme for mobile devices");
if (!$is_experimental or ($is_experimental && (get_config('experimentals','exp_themes')==1 or get_config('experimentals','exp_themes')===false))){
$theme_name = (($is_experimental) ? sprintf(t('%s - (Experimental)'), $f) : $f);
if (! $is_library) {
@@ -147,7 +155,6 @@ class Display {
}
}
}
}
}
@@ -206,7 +213,7 @@ class Display {
'$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')),
'$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 100 items')),
'$nosmile' => array('nosmile', t("Show emoticons (smilies) as images"), 1-intval($nosmile), '', $yes_no),
'$manual_update' => array('manual_update', t('Manual conversation updates'), channel_manual_conv_update(local_channel()), t('Default is automatic, which may increase screen jumping'), $yes_no),
'$manual_update' => array('manual_update', t('Manual conversation updates'), channel_manual_conv_update(local_channel()), t('Default is on, turning this off may increase screen jumping'), $yes_no),
'$title_tosource' => array('title_tosource', t("Link post titles to source"), $title_tosource, '', $yes_no),
'$layout_editor' => t('System Page Layout Editor - (advanced)'),
'$theme_config' => $theme_config,

View File

@@ -10,6 +10,16 @@ class Featured {
call_hooks('feature_settings_post', $_POST);
if(intval($_POST['affinity_cmax'])) {
set_pconfig(local_channel(),'affinity','cmax',intval($_POST['affinity_cmax']));
}
if(intval($_POST['affinity_cmin'])) {
set_pconfig(local_channel(),'affinity','cmin',intval($_POST['affinity_cmin']));
}
if(intval($_POST['affinity_cmax']) || intval($_POST['affinity_cmin'])) {
info( t('Affinity Slider settings updated.') . EOL);
}
build_sync_packet();
return;
}
@@ -23,6 +33,25 @@ class Featured {
if(! $r)
$settings_addons = t('No feature settings configured');
if(feature_enabled(local_channel(),'affinity')) {
$cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
$cmax = (($cmax) ? $cmax : 99);
$setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
'$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, '')
));
$cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
$cmin = (($cmin) ? $cmin : 0);
$setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
'$field' => array('affinity_cmin', t('Default minimum affinity level'), $cmin, '')
));
$settings_addons .= replace_macros(get_markup_template('generic_addon_settings.tpl'), array(
'$addon' => array('affinity_slider', '' . t('Affinity Slider Settings'), '', t('Submit')),
'$content' => $setting_fields
));
}
call_hooks('feature_settings', $settings_addons);
$tpl = get_markup_template("settings_addons.tpl");

View File

@@ -0,0 +1,117 @@
<?php
namespace Zotlabs\Module\Settings;
class Permcats {
function post() {
if(! local_channel())
return;
$channel = \App::get_channel();
check_form_security_token_redirectOnErr('/settings/permcats', 'settings_permcats');
$all_perms = \Zotlabs\Access\Permissions::Perms();
$name = escape_tags(trim($_POST['name']));
$pcarr = [];
if($all_perms) {
foreach($all_perms as $perm => $desc) {
if(array_key_exists('perms_' . $perm, $_POST)) {
$pcarr[] = $perm;
}
}
}
\Zotlabs\Lib\Permcat::update(local_channel(),$name,$pcarr);
build_sync_packet();
info( t('Permission category saved.') . EOL);
return;
}
function get() {
logger('cmd: ' . \App::$cmd);
if(! local_channel())
return;
$channel = \App::get_channel();
if(argc() > 2)
$name = argv(2);
if(argc() > 3 && argv(3) === 'drop') {
\Zotlabs\Lib\Permcat::delete(local_channel(),$name);
build_sync_packet();
json_return_and_die([ 'success' => true ]);
}
$desc = t('Use this form to create permission rules for various classes of people or connections.');
$existing = [];
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
$pcatlist = $pcat->listing();
$permcats = [];
if($pcatlist) {
foreach($pcatlist as $pc) {
if(($pc['name']) && ($name) && ($pc['name'] == $name))
$existing = $pc['perms'];
if(! $pc['system'])
$permcats[$pc['name']] = $pc['localname'];
}
}
$global_perms = \Zotlabs\Access\Permissions::Perms();
foreach($global_perms as $k => $v) {
$thisperm = \Zotlabs\Lib\Permcat::find_permcat($existing,$k);
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
if($existing[$k])
$thisperm = "1";
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
}
$tpl = get_markup_template("settings_permcats.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("settings_permcats"),
'$title' => t('Permission Categories'),
'$desc' => $desc,
'$desc2' => $desc2,
'$tokens' => $t,
'$permcats' => $permcats,
'$atoken' => $atoken,
'$url1' => z_root() . '/channel/' . $channel['channel_address'],
'$url2' => z_root() . '/photos/' . $channel['channel_address'],
'$name' => array('name', t('Permission Name') . ' <span class="required">*</span>', (($name) ? $name : ''), ''),
'$me' => t('My Settings'),
'$perms' => $perms,
'$inherited' => t('inherited'),
'$notself' => 0,
'$self' => 1,
'$permlbl' => t('Individual Permissions'),
'$permnote' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
'$submit' => t('Submit')
));
return $o;
}
}

View File

@@ -161,7 +161,8 @@ class Tokens {
'$me' => t('My Settings'),
'$perms' => $perms,
'$inherited' => t('inherited'),
'$notself' => '1',
'$notself' => 0,
'$self' => 1,
'$permlbl' => t('Individual Permissions'),
'$permnote' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
'$submit' => t('Submit')

View File

@@ -496,6 +496,11 @@ class Setup extends \Zotlabs\Web\Controller {
function check_funcs(&$checks) {
$ck_funcs = array();
$disabled = explode(',',ini_get('disable_functions'));
if($disabled)
array_walk($disabled,'array_trim');
// add check metadata, the real check is done bit later and return values set
$this->check_add($ck_funcs, t('libCurl PHP module'), true, true);
$this->check_add($ck_funcs, t('GD graphics PHP module'), true, true);
@@ -511,13 +516,13 @@ class Setup extends \Zotlabs\Web\Controller {
$this->check_add($ck_funcs, t('Apache mod_rewrite module'), true, true);
}
}
if((! function_exists('exec')) || strstr(ini_get('disable_functions'),'exec')) {
if((! function_exists('exec')) || in_array('exec',$disabled)) {
$this->check_add($ck_funcs, t('exec'), false, true, t('Error: exec is required but is either not installed or has been disabled in php.ini'));
}
else {
$this->check_add($ck_funcs, t('exec'), true, true);
}
if((! function_exists('shell_exec')) || strstr(ini_get('disable_functions'),'shell_exec')) {
if((! function_exists('shell_exec')) || in_array('shell_exec',$disabled)) {
$this->check_add($ck_funcs, t('shell_exec'), false, true, t('Error: shell_exec is required but is either not installed or has been disabled in php.ini'));
}
else {

View File

@@ -138,7 +138,7 @@ class Subthread extends \Zotlabs\Web\Controller {
$ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . $item['mid'] . ']' . $post_type . '[/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink );

View File

@@ -60,7 +60,7 @@ class Tagger extends \Zotlabs\Web\Controller {
$links = array(array('rel' => 'alternate','type' => 'text/html',
'href' => z_root() . '/display/' . $item['mid']));
'href' => z_root() . '/display/' . gen_link_id($item['mid'])));
$target = json_encode(array(
'type' => $targettype,
@@ -81,11 +81,6 @@ class Tagger extends \Zotlabs\Web\Controller {
),
));
$link = xmlify('<link rel="alternate" type="text/html" href="'
. z_root() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
$tagid = z_root() . '/search?tag=' . $term;
$objtype = ACTIVITY_OBJ_TAGTERM;

View File

@@ -9,10 +9,11 @@ class Uexport extends \Zotlabs\Web\Controller {
killme();
if(argc() > 1) {
$sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : '');
$channel = \App::get_channel();
require_once('include/channel.php');
if(argc() > 1 && intval(argv(1)) > 1900) {
$year = intval(argv(1));
}
@@ -30,15 +31,16 @@ class Uexport extends \Zotlabs\Web\Controller {
}
if(argc() > 1 && argv(1) === 'basic') {
echo json_encode(identity_basic_export(local_channel()));
echo json_encode(identity_basic_export(local_channel(),$sections));
killme();
}
// FIXME - this basically doesn't work in the wild with a channel more than a few months old due to memory and execution time limits.
// It probably needs to be built at the CLI and offered to download as a tarball. Maybe stored in the members dav.
// Warning: this option may consume a lot of memory
if(argc() > 1 && argv(1) === 'complete') {
echo json_encode(identity_basic_export(local_channel(),true));
$sections = get_default_export_sections();
$sections[] = 'items';
echo json_encode(identity_basic_export(local_channel(),$sections));
killme();
}
}
@@ -57,6 +59,7 @@ class Uexport extends \Zotlabs\Web\Controller {
'$basic' => t('Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content.'),
'$fulltitle' => t('Export Content'),
'$full' => t('Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin.'),
'$by_year' => t('Export your posts from a given year.'),
'$extra' => t('You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range.'),

View File

@@ -21,26 +21,10 @@ class Update_display extends \Zotlabs\Web\Controller {
$mod = new Display();
$text = $mod->get($profile_uid, $load);
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
$replace = "<img\${1} dst=\"\${2}\"";
// $text = preg_replace($pattern, $replace, $text);
/*
if(! $load) {
$replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
$pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
$text = preg_replace($pattern, $replace, $text);
$pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
$text = preg_replace($pattern, $replace, $text);
$pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
$text = preg_replace($pattern, $replace, $text);
$pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
$text = preg_replace($pattern, $replace, $text);
}
*/
echo str_replace("\t",' ',$text);
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
echo "</body></html>\r\n";
// logger('update_display: ' . $text);
killme();
}

View File

@@ -70,7 +70,7 @@ class Viewconnections extends \Zotlabs\Web\Controller {
foreach($r as $rr) {
$url = chanlink_url($rr['xchan_url']);
$url = chanlink_hash($rr['xchan_hash']);
if($url) {
$contacts[] = array(
'id' => $rr['abook_id'],

View File

@@ -36,7 +36,9 @@ class Viewsrc extends \Zotlabs\Web\Controller {
if($r) {
if(intval($r[0]['item_obscured']))
$r[0]['body'] = crypto_unencapsulate(json_decode($r[0]['body'],true),get_config('system','prvkey'));
$o = (($json) ? json_encode($r[0]['body']) : str_replace("\n",'<br />',$r[0]['body']));
$content = escape_tags($r[0]['body']);
$o = (($json) ? json_encode($content) : str_replace("\n",'<br />',$content));
}
}

View File

@@ -173,7 +173,6 @@ class Webpages extends \Zotlabs\Web\Controller {
if($_REQUEST['pagetitle'])
$x['pagetitle'] = $_REQUEST['pagetitle'];
$editor = status_editor($a,$x);
// Get a list of webpages. We can't display all them because endless scroll makes that unusable,
// so just list titles and an edit link.
@@ -197,6 +196,11 @@ class Webpages extends \Zotlabs\Web\Controller {
// intval(ITEM_TYPE_WEBPAGE)
// );
if(! $r)
$x['pagetitle'] = 'home';
$editor = status_editor($a,$x);
$pages = null;
if($r) {

View File

@@ -8,6 +8,8 @@ class Wfinger extends \Zotlabs\Web\Controller {
function init() {
session_write_close();
$result = array();
$scheme = '';

View File

@@ -2,26 +2,35 @@
namespace Zotlabs\Module;
use \Zotlabs\Lib as Zlib;
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
require_once('include/bbcode.php');
class Wiki extends \Zotlabs\Web\Controller {
private $wiki = null;
function init() {
// Determine which channel's wikis to display to the observer
$nick = null;
if (argc() > 1)
$nick = argv(1); // if the channel name is in the URL, use that
if (!$nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
if (! $nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
$channel = \App::get_channel();
if ($channel && $channel['channel_address']) {
$nick = $channel['channel_address'];
goaway(z_root() . '/wiki/' . $nick);
}
}
if (!$nick) {
notice(t('You must be logged in to see this page.') . EOL);
goaway('/login');
if (! $nick) {
notice( t('Profile Unavailable.') . EOL);
goaway(z_root());
}
profile_load($nick);
profile_load($nick);
}
function get() {
@@ -35,13 +44,15 @@ class Wiki extends \Zotlabs\Web\Controller {
return;
}
require_once('include/wiki.php');
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
require_once('include/bbcode.php');
if(! perm_is_allowed(\App::$profile_uid,get_observer_hash(),'view_wiki')) {
notice( t('Permission denied.') . EOL);
return;
}
// TODO: Combine the interface configuration into a unified object
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
$wiki_owner = false;
$showNewWikiButton = false;
$pageHistory = array();
@@ -49,12 +60,16 @@ class Wiki extends \Zotlabs\Web\Controller {
$resource_id = '';
// init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1
$nick = argv(1);
$owner = channelx_by_nick($nick); // The channel who owns the wikis being viewed
if(! $owner) {
notice( t('Invalid channel') . EOL);
goaway('/' . argv(0));
}
$observer_hash = get_observer_hash();
// Determine if the observer is the channel owner so the ACL dialog can be populated
if (local_channel() === intval($owner['channel_id'])) {
@@ -62,12 +77,14 @@ class Wiki extends \Zotlabs\Web\Controller {
// Obtain the default permission settings of the channel
$owner_acl = array(
'allow_cid' => $owner['channel_allow_cid'],
'allow_gid' => $owner['channel_allow_gid'],
'deny_cid' => $owner['channel_deny_cid'],
'deny_gid' => $owner['channel_deny_gid']
'allow_cid' => $owner['channel_allow_cid'],
'allow_gid' => $owner['channel_allow_gid'],
'deny_cid' => $owner['channel_deny_cid'],
'deny_gid' => $owner['channel_deny_gid']
);
// Initialize the ACL to the channel default permissions
$x = array(
'lockstate' => (( $owner['channel_allow_cid'] ||
$owner['channel_allow_gid'] ||
@@ -78,11 +95,12 @@ class Wiki extends \Zotlabs\Web\Controller {
'acl' => populate_acl($owner_acl),
'allow_cid' => acl2json($owner_acl['allow_cid']),
'allow_gid' => acl2json($owner_acl['allow_gid']),
'deny_cid' => acl2json($owner_acl['deny_cid']),
'deny_gid' => acl2json($owner_acl['deny_gid']),
'deny_cid' => acl2json($owner_acl['deny_cid']),
'deny_gid' => acl2json($owner_acl['deny_gid']),
'bang' => ''
);
} else {
}
else {
// Not the channel owner
$owner_acl = $x = array();
}
@@ -91,12 +109,13 @@ class Wiki extends \Zotlabs\Web\Controller {
$o = profile_tabs($a, $is_owner, \App::$profile['channel_address']);
// Download a wiki
/*
if((argc() > 3) && (argv(2) === 'download') && (argv(3) === 'wiki')) {
$resource_id = argv(4);
$w = wiki_get_wiki($resource_id);
if(!$w['path']) {
$w = Zlib\NativeWiki::get_wiki($owner,$observer_hash,$resource_id);
if(! $w['htmlName']) {
notice(t('Error retrieving wiki') . EOL);
}
@@ -111,7 +130,7 @@ class Wiki extends \Zotlabs\Web\Controller {
$zip_filepath = '/tmp/' . $zip_folder_name . '/' . $zip_filename;
// Generate the zip file
\Zotlabs\Lib\ExtendedZip::zipTree($w['path'], $zip_filepath, \ZipArchive::CREATE);
ZLib\ExtendedZip::zipTree($w['path'], $zip_filepath, \ZipArchive::CREATE);
// Output the file for download
@@ -130,11 +149,11 @@ class Wiki extends \Zotlabs\Web\Controller {
killme();
}
switch (argc()) {
*/
switch(argc()) {
case 2:
$wikis = wiki_list($owner, get_observer_hash());
if ($wikis) {
$wikis = Zlib\NativeWiki::listwikis($owner, get_observer_hash());
if($wikis) {
$o .= replace_macros(get_markup_template('wikilist.tpl'), array(
'$header' => t('Wikis'),
'$channel' => $owner['channel_address'],
@@ -161,72 +180,76 @@ class Wiki extends \Zotlabs\Web\Controller {
return $o;
}
break;
case 3:
// /wiki/channel/wiki -> No page was specified, so redirect to Home.md
$wikiUrlName = urlencode(argv(2));
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/Home');
goaway(z_root() . '/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/Home');
case 4:
// GET /wiki/channel/wiki/page
// Fetch the wiki info and determine observer permissions
$wikiUrlName = urlencode(argv(2));
$pageUrlName = urlencode(argv(3));
$w = wiki_exists_by_name($owner['channel_id'], $wikiUrlName);
if(!$w['resource_id']) {
$wikiUrlName = urldecode(argv(2));
$pageUrlName = urldecode(argv(3));
$w = Zlib\NativeWiki::exists_by_name($owner['channel_id'], $wikiUrlName);
if(! $w['resource_id']) {
notice(t('Wiki not found') . EOL);
goaway('/'.argv(0).'/'.argv(1));
return; //not reached
goaway(z_root() . '/' . argv(0) . '/' . argv(1));
}
$resource_id = $w['resource_id'];
if (!$wiki_owner) {
if(! $wiki_owner) {
// Check for observer permissions
$observer_hash = get_observer_hash();
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['read']) {
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['read']) {
notice(t('Permission denied.') . EOL);
goaway('/'.argv(0).'/'.argv(1));
goaway(z_root() . '/' . argv(0) . '/' . argv(1));
return; //not reached
}
if($perms['write']) {
$wiki_editor = true;
} else {
$wiki_editor = false;
}
} else {
$wiki_editor = (($perms['write']) ? true : false);
}
else {
$wiki_editor = true;
}
$wikiheaderName = urldecode($wikiUrlName);
$wikiheaderPage = urldecode($pageUrlName);
$renamePage = (($wikiheaderPage === 'Home') ? '' : t('Rename page'));
$p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if(!$p['success']) {
notice(t('Error retrieving page content') . EOL);
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
return; //not reached
$p = Zlib\NativeWikiPage::get_page_content(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if(! $p['success']) {
notice( t('Error retrieving page content') . EOL);
goaway(z_root() . '/' . argv(0) . '/' . argv(1) );
}
$mimeType = $p['mimeType'];
$rawContent = (($p['mimeType'] == 'text/bbcode') ? htmlspecialchars_decode(json_decode($p['content']),ENT_COMPAT) : htmlspecialchars_decode($p['content'],ENT_COMPAT));
$rawContent = htmlspecialchars_decode(json_decode($p['content']),ENT_COMPAT);
$content = ($p['content'] !== '' ? $rawContent : '"# New page\n"');
// Render the Markdown-formatted page content in HTML
if($mimeType == 'text/bbcode') {
$renderedContent = wiki_convert_links(bbcode($content),argv(0).'/'.argv(1).'/'.$wikiUrlName);
$renderedContent = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))), argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
else {
require_once('library/markdown.php');
$html = wiki_generate_toc(zidify_text(purify_html(Markdown(wiki_bbcode(json_decode($content))))));
$renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName);
$html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(Markdown(Zlib\NativeWikiPage::bbcode($content)))));
$renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
$showPageControls = $wiki_editor;
break;
default: // Strip the extraneous URL components
goaway('/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/' . $pageUrlName);
return; //not reached
}
$wikiModalID = random_string(3);
@@ -237,6 +260,8 @@ class Wiki extends \Zotlabs\Web\Controller {
'$ok' => (($showPageControls) ? t('Revert') : ''),
'$cancel' => t('Cancel')
));
$placeholder = t('Short description of your changes (optional)');
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
'$wikiheaderName' => $wikiheaderName,
@@ -252,7 +277,7 @@ class Wiki extends \Zotlabs\Web\Controller {
'$content' => $content,
'$renderedContent' => $renderedContent,
'$pageRename' => array('pageRename', t('New page name'), '', ''),
'$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="Short description of your changes (optional)"'),
'$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="' . $placeholder . '"'),
'$wikiModal' => $wikiModal,
'$wikiModalID' => $wikiModalID,
'$commit' => 'HEAD',
@@ -269,13 +294,13 @@ class Wiki extends \Zotlabs\Web\Controller {
));
if($p['mimeType'] != 'text/bbcode')
head_add_js('library/ace/ace.js'); // Ace Code Editor
head_add_js('/library/ace/ace.js'); // Ace Code Editor
return $o;
}
function post() {
require_once('include/wiki.php');
require_once('include/bbcode.php');
$nick = argv(1);
@@ -287,25 +312,25 @@ class Wiki extends \Zotlabs\Web\Controller {
return;
}
// /wiki/channel/preview
// Render mardown-formatted text in HTML for preview
if((argc() > 2) && (argv(2) === 'preview')) {
$content = $_POST['content'];
$resource_id = $_POST['resource_id'];
$w = wiki_get_wiki($resource_id);
$wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
$w = Zlib\NativeWiki::get_wiki($owner['channel_id'],$observer_hash,$resource_id);
$wikiURL = argv(0) . '/' . argv(1) . '/' . $w['urlName'];
$mimeType = $w['mimeType'];
if($mimeType == 'text/bbcode') {
$html = wiki_convert_links(bbcode($content),$wikiURL);
$html = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))),$wikiURL);
}
else {
require_once('library/markdown.php');
$content = wiki_bbcode($content);
$html = wiki_generate_toc(zidify_text(purify_html(Markdown($content))));
$html = wiki_convert_links($html,$wikiURL);
$content = Zlib\NativeWikiPage::bbcode($content);
$html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(Markdown($content))));
$html = Zlib\NativeWikiPage::convert_links($html,$wikiURL);
}
json_return_and_die(array('html' => $html, 'success' => true));
}
@@ -322,11 +347,11 @@ class Wiki extends \Zotlabs\Web\Controller {
}
$wiki = array();
// Generate new wiki info from input name
$wiki['postVisible'] = ((intval($_POST['postVisible']) === 0) ? 0 : 1);
$wiki['rawName'] = $_POST['wikiName'];
$wiki['htmlName'] = escape_tags($_POST['wikiName']);
$wiki['urlName'] = urlencode($_POST['wikiName']);
$wiki['mimeType'] = $_POST['mimeType'];
$wiki['postVisible'] = ((intval($_POST['postVisible'])) ? 1 : 0);
$wiki['rawName'] = $_POST['wikiName'];
$wiki['htmlName'] = escape_tags($_POST['wikiName']);
$wiki['urlName'] = urlencode(urlencode($_POST['wikiName']));
$wiki['mimeType'] = $_POST['mimeType'];
if($wiki['urlName'] === '') {
notice( t('Error creating wiki. Invalid name.') . EOL);
@@ -336,17 +361,20 @@ class Wiki extends \Zotlabs\Web\Controller {
// Get ACL for permissions
$acl = new \Zotlabs\Access\AccessList($owner);
$acl->set_from_array($_POST);
$r = wiki_create_wiki($owner, $observer_hash, $wiki, $acl);
if ($r['success']) {
$homePage = wiki_create_page('Home', $r['item']['resource_id']);
if(!$homePage['success']) {
$r = Zlib\NativeWiki::create_wiki($owner, $observer_hash, $wiki, $acl);
if($r['success']) {
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$r['item_id'],$r['item']['resource_id']);
$homePage = Zlib\NativeWikiPage::create_page($owner['channel_id'],$observer_hash,'Home', $r['item']['resource_id']);
if(! $homePage['success']) {
notice( t('Wiki created, but error creating Home page.'));
goaway('/wiki/'.$nick.'/'.$wiki['urlName']);
goaway(z_root() . '/wiki/' . $nick . '/' . $wiki['urlName']);
}
goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['page']['urlName']);
} else {
notice(t('Error creating wiki'));
goaway('/wiki');
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$homePage['item_id'],$r['item']['resource_id']);
goaway(z_root() . '/wiki/' . $nick . '/' . $wiki['urlName'] . '/' . $homePage['page']['urlName']);
}
else {
notice( t('Error creating wiki'));
goaway(z_root() . '/wiki');
}
}
@@ -357,15 +385,17 @@ class Wiki extends \Zotlabs\Web\Controller {
// more detail permissions framework
if (local_channel() !== intval($owner['channel_id'])) {
logger('Wiki delete permission denied.');
json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
json_return_and_die(array('message' => t('Wiki delete permission denied.'), 'success' => false));
}
$resource_id = $_POST['resource_id'];
$deleted = wiki_delete_wiki($resource_id);
$deleted = Zlib\NativeWiki::delete_wiki($owner['channel_id'],$observer_hash,$resource_id);
if ($deleted['success']) {
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$deleted['item_id'],$resource_id);
json_return_and_die(array('message' => '', 'success' => true));
} else {
logger('Error deleting wiki: ' . $resource_id);
json_return_and_die(array('message' => 'Error deleting wiki', 'success' => false));
}
else {
logger('Error deleting wiki: ' . $resource_id . ' ' . $deleted['message']);
json_return_and_die(array('message' => t('Error deleting wiki'), 'success' => false));
}
}
@@ -377,41 +407,48 @@ class Wiki extends \Zotlabs\Web\Controller {
// Determine if observer has permission to create a page
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['write']) {
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
$name = $_POST['name']; //Get new page name
if(urlencode(escape_tags($_POST['name'])) === '') {
$name = $_POST['pageName']; //Get new page name
if(urlencode(escape_tags($_POST['pageName'])) === '') {
json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false));
}
$page = wiki_create_page($name, $resource_id);
if ($page['success']) {
$ob = \App::get_observer();
$commit = wiki_git_commit(array(
'commit_msg' => t('New page created'),
'resource_id' => $resource_id,
'observer' => $ob,
'files' => array($page['page']['fileName'])
));
$page = Zlib\NativeWikiPage::create_page($owner['channel_id'],$observer_hash, $name, $resource_id);
if($page['item_id']) {
$commit = Zlib\NativeWikiPage::commit(array(
'commit_msg' => t('New page created'),
'resource_id' => $resource_id,
'channel_id' => $owner['channel_id'],
'observer_hash' => $observer_hash,
'pageUrlName' => $name
));
if($commit['success']) {
json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.$page['page']['urlName'], 'success' => true));
} else {
json_return_and_die(array('message' => 'Error making git commit','url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']),'success' => false));
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . urlencode($page['wiki']['urlName']) . '/' . urlencode($page['page']['urlName']), 'success' => true));
}
else {
json_return_and_die(array('message' => 'Error making git commit','url' => '/' . argv(0) . '/' . argv(1) . '/' . urlencode($page['wiki']['urlName']) . '/' . urlencode($page['page']['urlName']),'success' => false));
}
} else {
}
else {
logger('Error creating page');
json_return_and_die(array('message' => 'Error creating page.', 'success' => false));
}
}
// Fetch page list for a wiki
if ((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
if((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
$resource_id = $_POST['resource_id']; // resource_id for wiki in db
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['read']) {
logger('Wiki read permission denied.' . EOL);
json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false));
@@ -437,27 +474,33 @@ class Wiki extends \Zotlabs\Web\Controller {
}
// Determine if observer has permission to save content
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['write']) {
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
$saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
$saved = Zlib\NativeWikiPage::save_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
if($saved['success']) {
$ob = \App::get_observer();
$commit = wiki_git_commit(array(
'commit_msg' => $commitMsg,
'resource_id' => $resource_id,
'observer' => $ob,
'files' => array($saved['fileName'])
));
$commit = Zlib\NativeWikiPage::commit(array(
'commit_msg' => $commitMsg,
'pageUrlName' => $pageUrlName,
'resource_id' => $resource_id,
'channel_id' => $owner['channel_id'],
'observer_hash' => $observer_hash,
'revision' => (-1)
));
if($commit['success']) {
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
} else {
}
else {
json_return_and_die(array('message' => 'Error making git commit','success' => false));
}
} else {
}
else {
json_return_and_die(array('message' => 'Error saving page', 'success' => false));
}
}
@@ -472,8 +515,8 @@ class Wiki extends \Zotlabs\Web\Controller {
// Determine if observer has permission to read content
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['read']) {
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['read']) {
logger('Wiki read permission denied.' . EOL);
json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
}
@@ -481,59 +524,59 @@ class Wiki extends \Zotlabs\Web\Controller {
$historyHTML = widget_wiki_page_history(array(
'resource_id' => $resource_id,
'pageUrlName' => $pageUrlName,
'permsWrite' => $perms['write']
'permsWrite' => $perms['write']
));
json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true));
}
// Delete a page
if ((argc() === 4) && (argv(2) === 'delete') && (argv(3) === 'page')) {
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
if ($pageUrlName === 'Home') {
json_return_and_die(array('message' => 'Cannot delete Home','success' => false));
json_return_and_die(array('message' => t('Cannot delete Home'),'success' => false));
}
// Determine if observer has permission to delete pages
// currently just allow page owner
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['write']) {
if((! local_channel()) || (local_channel() != $owner['channel_id'])) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
$deleted = wiki_delete_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
$deleted = Zlib\NativeWikiPage::delete_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($deleted['success']) {
$ob = \App::get_observer();
$commit = wiki_git_commit(array(
'commit_msg' => 'Deleted ' . $pageUrlName,
'resource_id' => $resource_id,
'observer' => $ob,
'files' => null
));
if($commit['success']) {
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error making git commit','success' => false));
}
} else {
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
}
else {
json_return_and_die(array('message' => 'Error deleting page', 'success' => false));
}
}
// Revert a page
if ((argc() === 4) && (argv(2) === 'revert') && (argv(3) === 'page')) {
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
$commitHash = $_POST['commitHash'];
// Determine if observer has permission to revert pages
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['write']) {
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['write']) {
logger('Wiki write permission denied.' . EOL);
json_return_and_die(array('success' => false));
}
$reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
$reverted = Zlib\NativeWikiPage::revert_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($reverted['success']) {
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
} else {
@@ -549,15 +592,15 @@ class Wiki extends \Zotlabs\Web\Controller {
$currentCommit = $_POST['currentCommit'];
// Determine if observer has permission to revert pages
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['read']) {
logger('Wiki read permission denied.' . EOL);
json_return_and_die(array('success' => false));
}
$compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
$compare = Zlib\NativeWikiPage::compare_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($compare['success']) {
$diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">Current Revision</td><td class="lead" width="50%">Selected Revision</td></tr></table>' . $compare['diff'];
$diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">' . t('Current Revision') . '</td><td class="lead" width="50%">' . t('Selected Revision') . '</td></tr></table>' . $compare['diff'];
json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
} else {
json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
@@ -577,34 +620,37 @@ class Wiki extends \Zotlabs\Web\Controller {
}
// Determine if observer has permission to rename pages
$perms = wiki_get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(!$perms['write']) {
$perms = Zlib\NativeWiki::get_permissions($resource_id, intval($owner['channel_id']), $observer_hash);
if(! $perms['write']) {
logger('Wiki write permission denied. ' . EOL);
json_return_and_die(array('success' => false));
}
$renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
$renamed = Zlib\NativeWikiPage::rename_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
if($renamed['success']) {
$ob = \App::get_observer();
$commit = wiki_git_commit(array(
'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
'resource_id' => $resource_id,
'observer' => $ob,
'files' => array($pageUrlName . substr($renamed['page']['fileName'], -3), $renamed['page']['fileName']),
'all' => true
));
$commit = Zlib\NativeWikiPage::commit(array(
'channel_id' => $owner['channel_id'],
'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
'resource_id' => $resource_id,
'observer_hash' => $observer_hash,
'pageUrlName' => $pageNewName
));
if($commit['success']) {
Zlib\NativeWiki::sync_a_wiki_item($owner['channel_id'],$commit['item_id'],$resource_id);
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
} else {
}
else {
json_return_and_die(array('message' => 'Error making git commit','success' => false));
}
} else {
}
else {
json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
}
}
//notice( t('You must be authenticated.'));
json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));
json_return_and_die(array('message' => t('You must be authenticated.'), 'success' => false));
}
}

View File

@@ -99,13 +99,28 @@ class Comanche {
}
}
/**
* Currently supported condition variables:
*
* $config.xxx.yyy - get_config with cat = xxx and k = yyy
* $request - request uri for this page
* $observer.language - viewer's preferred language (closest match)
* $observer.address - xchan_addr or false
* $observer.name - xchan_name or false
* $observer - xchan_hash of observer or empty string
*/
function get_condition_var($v) {
if($v) {
$x = explode('.',$v);
if($x[0] == 'config')
return get_config($x[1],$x[2]);
elseif($x[0] === 'request')
return $_SERVER['REQUEST_URI'];
elseif($x[0] === 'observer') {
if(count($x) > 1) {
if($x[1] == 'language')
return \App::$language;
$y = \App::get_observer();
if(! $y)
return false;
@@ -125,20 +140,35 @@ class Comanche {
function test_condition($s) {
// This is extensible. The first version of variable testing supports tests of the forms:
// [if $config.system.foo ~= baz] which will check if get_config('system','foo') contains the string 'baz';
// [if $config.system.foo == baz] which will check if get_config('system','foo') is the string 'baz';
// [if $config.system.foo != baz] which will check if get_config('system','foo') is not the string 'baz';
// You may check numeric entries, but these checks are evaluated as strings.
// [if $config.system.foo >= 3] which will check if get_config('system','foo') is greater than or equal to 3;
// [if $config.system.foo > 3] which will check if get_config('system','foo') is greater than 3;
// [if $config.system.foo <= 3] which will check if get_config('system','foo') is less than or equal to 3;
// [if $config.system.foo < 3] which will check if get_config('system','foo') is less than 3;
// [if $config.system.foo {} baz] which will check if 'baz' is an array element in get_config('system','foo')
// [if $config.system.foo {*} baz] which will check if 'baz' is an array key in get_config('system','foo')
// [if $config.system.foo] which will check for a return of a true condition for get_config('system','foo');
// The values 0, '', an empty array, and an unset value will all evaluate to false.
if(preg_match('/[\$](.*?)\s\~\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if(stripos($x,trim($matches[2])) !== false)
return true;
return false;
}
if(preg_match('/[\$](.*?)\s\=\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x == trim($matches[2]))
return true;
return false;
}
if(preg_match('/[\$](.*?)\s\!\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x != trim($matches[2]))
@@ -146,6 +176,31 @@ class Comanche {
return false;
}
if(preg_match('/[\$](.*?)\s\>\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x >= trim($matches[2]))
return true;
return false;
}
if(preg_match('/[\$](.*?)\s\<\=\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x <= trim($matches[2]))
return true;
return false;
}
if(preg_match('/[\$](.*?)\s\>\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x > trim($matches[2]))
return true;
return false;
}
if(preg_match('/[\$](.*?)\s\>\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if($x < trim($matches[2]))
return true;
return false;
}
if(preg_match('/[\$](.*?)\s\{\}\s(.*?)$/',$s,$matches)) {
$x = $this->get_condition_var($matches[1]);
if(is_array($x) && in_array(trim($matches[2]),$x))

View File

@@ -70,9 +70,15 @@ class Theme {
$chosen_theme = $_GET['theme_preview'];
// Allow theme selection of the form 'theme_name:schema_name'
$themepair = explode(':', $chosen_theme);
// Check if $chosen_theme is compatible with core. If not fall back to default
$info = get_theme_info($themepair[0]);
$compatible = check_plugin_versions($info);
if(!$compatible) {
$chosen_theme = '';
}
if($chosen_theme && (file_exists('view/theme/' . $themepair[0] . '/css/style.css') || file_exists('view/theme/' . $themepair[0] . '/php/style.php'))) {
return($themepair);
}
@@ -125,9 +131,9 @@ class Theme {
$opts .= $schema_str;
if(file_exists('view/theme/' . $t . '/php/style.php'))
return('view/theme/' . $t . '/php/style.pcss' . $opts);
return('/view/theme/' . $t . '/php/style.pcss' . $opts);
return('view/theme/' . $t . '/css/style.css');
return('/view/theme/' . $t . '/css/style.css');
}
function debug() {

View File

@@ -314,7 +314,13 @@ class Browser extends DAV\Browser\Plugin {
$quota['desc'] = $quotaDesc;
$quota['warning'] = ((($limit) && ((round($used / $limit, 1) * 100) >= 90)) ? t('WARNING:') : ''); // 10485760 bytes = 100MB
$path = trim(str_replace('cloud/' . $this->auth->owner_nick, '', $path), '/');
// strip 'cloud/nickname', but only at the beginning of the path
$special = 'cloud/' . $this->auth->owner_nick;
$count = strlen($special);
if(strpos($path,$special) === 0)
$path = trim(substr($path,$count),'/');
$output .= replace_macros(get_markup_template('cloud_actionspanel.tpl'), array(
'$folder_header' => t('Create new folder'),

View File

@@ -0,0 +1,46 @@
<?php
namespace Zotlabs\Web;
class HTTPHeaders {
private $in_progress = [];
private $parsed = [];
function __construct($headers) {
$lines = explode("\n",str_replace("\r",'',$headers));
if($lines) {
foreach($lines as $line) {
if(preg_match('/^\s+/',$line,$matches) && trim($line)) {
if($this->in_progress['k']) {
$this->in_progress['v'] .= ' ' . ltrim($line);
continue;
}
}
else {
if($this->in_progress['k']) {
$this->parsed[] = [ $this->in_progress['k'] => $this->in_progress['v'] ];
$this->in_progress = [];
}
$this->in_progress['k'] = strtolower(substr($line,0,strpos($line,':')));
$this->in_progress['v'] = ltrim(substr($line,strpos($line,':') + 1));
}
}
if($this->in_progress['k']) {
$this->parsed[] = [ $this->in_progress['k'] => $this->in_progress['v'] ];
$this->in_progress = [];
}
}
}
function fetch() {
return $this->parsed;
}
}

View File

@@ -121,29 +121,24 @@ class Router {
/*
* The URL provided does not resolve to a valid module.
*
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
* We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
* we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
* this will often succeed and eventually do the right thing.
*
* Otherwise we are going to emit a 404 not found.
*/
if(! (\App::$module_loaded)) {
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
$x = [
'module' => $module,
'installed' => \App::$module_loaded,
'controller' => $this->controller
];
call_hooks('page_not_found',$x);
// Stupid browser tried to pre-fetch our Javascript img template.
// Don't log the event or return anything - just quietly exit.
if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
killme();
}
if((x($_SERVER, 'QUERY_STRING'))
&& ($_SERVER['QUERY_STRING'] === 'q=internal_error.html')
&& \App::$config['system']['dreamhost_error_hack']) {
logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI'],LOGGER_DEBUG);
goaway(z_root() . $_SERVER['REQUEST_URI']);
}
if(get_config('system','log_404',true)) {
logger("Module {$module} not found.", LOGGER_DEBUG, LOG_WARNING);
logger('index.php: page not found: ' . $_SERVER['REQUEST_URI']

View File

@@ -1,4 +0,0 @@
url: $baseurl/admin
requires: admin
name: Site Admin
photo: $baseurl/app/admin.png

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/bookmarks
requires: local_channel
name: View Bookmarks
photo: $baseurl/app/bookmarks.png
photo: icon:bookmark
categories: Productivity

View File

@@ -1,3 +1,5 @@
version: 1
url: https://github.com/redmatrix/hubzilla/issues
name: Report Bug
photo: $baseurl/app/bugreport.png
photo: icon:bug
categories: System

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/channel/$nick
requires: local_channel
name: Channel Home
photo: $baseurl/app/home.png
photo: icon:home
categories: nav_featured_app, Personal

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/chat/$nick
requires: local_channel
requires: local_channel, ajaxchat
name: My Chatrooms
photo: $baseurl/app/chat.png
photo: icon:comments-o
categories: Productivity

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/connections
requires: local_channel
name: Connections
photo: $baseurl/app/connections.png
photo: icon:users
categories: nav_featured_app, Networking

View File

@@ -1,3 +1,5 @@
version: 1
url: $baseurl/directory
name: Directory
photo: $baseurl/app/directory.png
photo: icon:sitemap
categories: nav_featured_app, Networking

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/events
requires: local_channel
name: Events
photo: $baseurl/app/events.png
photo: icon:calendar
categories: nav_featured_app, Productivity

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/settings/features
requires: local_channel
name: Features
photo: $baseurl/app/features.png
photo: icon:cogs
categories: System

View File

@@ -1,4 +0,0 @@
url: $baseurl/ffsapi
requires: local_channel
name: Firefox Share
photo: $baseurl/app/firefoxshare.png

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/network
requires: local_channel
name: Grid
photo: $baseurl/images/hubzilla_logo_6.png
photo: icon:th
categories: nav_featured_app, Networking

View File

@@ -1,3 +1,5 @@
version: 1
url: $baseurl/help
name: Help
photo: $baseurl/app/help.png
photo: icon:question
categories: nav_featured_app, System

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/invite
requires: local_channel
name: Invite
photo: $baseurl/app/invite.png
photo: icon:user-plus
categories: Networking

View File

@@ -1,3 +1,5 @@
version: 1
url: $baseurl/lang
name: Language
photo: $baseurl/app/lang.png
photo: icon:language
categories: System

View File

@@ -1,4 +1,5 @@
version: 1
url: $baseurl/login
requires: nologin
name: Login
photo: $baseurl/app/login.png
photo: icon:sign-in

View File

@@ -1,4 +1,6 @@
url: $baseurl/message
version: 1
url: $baseurl/mail/combined
requires: local_channel
name: Mail
photo: $baseurl/app/mail.png
photo: icon:envelope
categories: nav_featured_app, Personal

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/manage
requires: local_channel
name: Channel Manager
photo: $baseurl/app/manage.png
photo: icon:id-card-o
categories: Personal

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/mood
requires: local_channel
name: Mood
photo: $baseurl/app/mood.png
photo: icon:smile-o
categories: Social

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/photos/$nick
requires: local_channel
name: Photos
photo: $baseurl/app/photos.png
photo: icon:photo
categories: Multimedia

View File

@@ -1,4 +1,6 @@
version: 1
url: $baseurl/poke
requires: local_channel
name: Poke
photo: $baseurl/app/poke.png
photo: icon:hand-o-right
categories: Social

View File

@@ -1,4 +1,6 @@
url: $baseurl/rpost?f=&body=%0A
version: 1
url: $baseurl/rpost?f=&body=
requires: observer
name: Post
photo: $baseurl/app/post.png
photo: icon:pencil-square
categories: Productivity

View File

@@ -1,4 +0,0 @@
url: $baseurl/profile_photo
requires: local_channel
name: Profile Photo
photo: $baseurl/app/pphoto.png

Some files were not shown because too many files have changed in this diff Show More