Compare commits

...

468 Commits
1.8 ... 1.10

Author SHA1 Message Date
redmatrix
ae5c10a71c Merge branch '1.10RC' 2016-07-28 19:58:05 -07:00
redmatrix
4d5202353f Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge 2016-07-28 18:26:32 -07:00
redmatrix
142bcd6806 move fixes to po2php forward to 1.10 2016-07-28 18:26:06 -07:00
hubzilla
7075697f60 Merge pull request #465 from phellmes/de20160728
Update DE translation strings
2016-07-29 09:55:47 +10:00
redmatrix
856133b07d fix it strings after merge stuffup 2016-07-28 16:53:18 -07:00
redmatrix
0b2d809309 github didn't accept the last push. Touching the files to force a git revision 2016-07-28 16:47:08 -07:00
jeroenpraat
ec383aca03 Updated language files for release 2016-07-28 16:37:19 -07:00
redmatrix
bc74425872 Revert "Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge"
This reverts commit 35f17acb38, reversing
changes made to 58cf5f310d.
2016-07-28 16:02:51 -07:00
redmatrix
35f17acb38 Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge 2016-07-28 13:15:10 -07:00
redmatrix
58cf5f310d sql typo 2016-07-28 13:14:48 -07:00
redmatrix
2d916b531b Revert "issue #466, sql typo"
This reverts commit 4ce8f965aa.
2016-07-28 13:13:59 -07:00
redmatrix
12952c9821 issue #466, sql typo 2016-07-28 13:11:01 -07:00
jeroenpraat
47e1c4e059 Updated language files for release 2016-07-28 21:33:02 +02:00
jeroenpraat
47119ddc7d Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC 2016-07-28 21:07:46 +02:00
phellmes
18f0961caa Update DE translation strings 2016-07-28 14:09:29 +02:00
Mario Vavti
e65949f594 make progressbar slightly more transparent and give it a default width of 3px to indicate which files are to be uploaded 2016-07-28 11:54:42 +02:00
Mario Vavti
b05c1a9829 use single quote for js and double quote for html with proper escapes and implement a simple progressbar 2016-07-28 11:45:57 +02:00
Mario Vavti
9fa3956aa8 translate mime types to icons, update some icons, move file preview (upload progress) below table header 2016-07-28 10:28:48 +02:00
redmatrix
02fc082e45 github didn't accept the last push. Touching the files to force a git revision 2016-07-27 22:40:33 -07:00
redmatrix
be1ffca6f4 fix italian strings (messed up by rtl variable); and finish removing openid from core 2016-07-27 22:28:30 -07:00
hubzilla
987eb90e18 Merge pull request #464 from anaqreon/hover-visuals
Enhanced visual feedback for file drag hover
2016-07-28 12:07:01 +10:00
Andrew Manning
932aeebcf1 Enhanced visual feedback for file drag hover 2016-07-27 21:03:41 -04:00
redmatrix
5f3a8cbe93 add the hidden flag also 2016-07-27 16:14:46 -07:00
Mario Vavti
f808f1601b rework drag and drop to drag directly into files area, implement the default upload button to work with the same mechanism as drag and drop, revert 560af7a5b8 since it did not work so well with the new cloud upload mechanism 2016-07-27 16:49:55 +02:00
redmatrix
672c3d7c6d Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-26 22:51:07 -07:00
redmatrix
72479041ae don't include deleted or orphaned xchans in ratings search 2016-07-26 22:50:31 -07:00
hubzilla
e286b510f1 Merge pull request #463 from git-marijus/dev
allow multiple-file cloud upload
2016-07-27 14:54:51 +10:00
redmatrix
315dafbe12 restrict url cache to 254 maxlen 2016-07-26 20:05:40 -07:00
redmatrix
80e4338314 missing s 2016-07-26 19:28:28 -07:00
redmatrix
db176eec40 set App::$error on 404 so we don't get two 'Page not found.' page bodies. 2016-07-26 17:24:17 -07:00
redmatrix
02f88fc7b2 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-26 15:59:06 -07:00
redmatrix
56957b60e2 issue #460 - remove reference to $a which was passed by value since it doesn't exist. Ultimately $a needs to be removed completely but that's a bit messier. 2016-07-26 15:57:33 -07:00
Mario Vavti
7126fd4b31 fix drag and drop 2016-07-26 15:57:47 +02:00
Mario Vavti
560af7a5b8 allow multiple-file cloud upload 2016-07-26 13:17:46 +02:00
Wave
e38880a686 Merge pull request #462 from wave72/dev
Updated Italian strings
2016-07-26 09:51:54 +02:00
Wave72
29dd4ad39b Updated Italian strings 2016-07-26 09:51:06 +02:00
Mario Vavti
54ecf0f45f URLUtil path has changed since sabredav 1.8 - fixes renaming issue in dav clients 2016-07-26 09:05:38 +02:00
Mario Vavti
6900dd34a4 URLUtil path has changed since sabredav 1.8 - fixes renaming issue in dav clients 2016-07-26 09:04:52 +02:00
redmatrix
70dae328b5 check for new permissions and update channels and connections with defaults if any are found and if there are defaults for any channel roles which are being used on this site. 2016-07-25 21:59:52 -07:00
redmatrix
5d4245ff01 move openid to addon 2016-07-25 17:16:41 -07:00
redmatrix
24d28bc23a issue #460 2016-07-25 13:29:06 -07:00
redmatrix
d786eca126 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-25 13:27:42 -07:00
redmatrix
2fb4952137 issue #460 2016-07-25 13:27:17 -07:00
Mario Vavti
da512cef64 revert multiple test 2016-07-25 11:43:01 +02:00
Mario Vavti
f41b037fbe css fixes 2016-07-25 11:41:27 +02:00
redmatrix
0f5f1c98ca revert cloud acl selector (branched so as to continue development) 2016-07-25 01:46:40 -07:00
redmatrix
01338a7610 make drag/drop work with acl, which bypassed the form 2016-07-24 22:58:26 -07:00
redmatrix
063b4286e7 trace log pconfig cache if for some reason it isn't an array 2016-07-24 22:36:37 -07:00
redmatrix
271f85be3b add acl selection to files upload via /cloud (still missing from directory creation) 2016-07-24 20:27:59 -07:00
redmatrix
b5f2b4af35 string update and some minor comment edits 2016-07-24 16:11:34 -07:00
redmatrix
9967f2ab28 call wall_attach rather than wall_upload for drag/drop; which means you can drag/drop any file and not just photos. 2016-07-24 16:09:33 -07:00
hubzilla
52c3960946 Merge pull request #459 from anaqreon/jot-drag-attach
Drag and drop one image file at a time into the post editor will uplo…
2016-07-25 08:55:12 +10:00
Andrew Manning
1b1170bcf6 Drag and drop one image file at a time into the post editor will upload it. 2016-07-24 17:33:34 -04:00
hubzilla
eb03877aa4 Merge pull request #458 from anaqreon/dragdropupload
Drag-and-drop file upload for cloud files
2016-07-24 23:13:05 +10:00
Andrew Manning
4c4d185937 Remove logger calls 2016-07-24 08:35:21 -04:00
Andrew Manning
6998bb1f23 Multiple file upload by drag and drop with progress indicators and auto page reload 2016-07-24 07:41:53 -04:00
Andrew Manning
3a60bef2b6 Include credentials for session cookie in xhr 2016-07-23 08:39:23 -04:00
Andrew Manning
eb1eb38c01 AJAX single upload might be working, but permissions problems seem to cause failure. 2016-07-23 07:59:28 -04:00
Andrew Manning
3c5598407e Drag and drop file information display in cloud files upload form. No actual upload implemented yet. 2016-07-22 21:27:32 -04:00
Mario Vavti
4ffc4ee70a rename the patch so that it explains what it does 2016-07-22 14:29:16 +02:00
Mario Vavti
52db649022 apply our custom patch to readmore.js 2016-07-22 14:14:20 +02:00
Mario Vavti
38e46fff54 upgrade readmore.js and improve collapsing a little 2016-07-22 14:03:14 +02:00
Wave
744ad84714 Merge pull request #6 from redmatrix/dev
Dev
2016-07-22 10:55:02 +02:00
redmatrix
7d897a3f03 more work on #453 2016-07-21 23:06:55 -07:00
redmatrix
79eeeaee95 fix birthday addtocal 2016-07-21 21:36:10 -07:00
redmatrix
2c1b432613 fix birthday addtocal 2016-07-21 21:35:26 -07:00
redmatrix
0c3d5e99a2 PConfig : Check for is_null($uid) as well as false. We actually allow $uid = 0 though it shouldn't normally happen. 2016-07-21 20:50:39 -07:00
redmatrix
dca8a05026 Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge 2016-07-21 20:06:08 -07:00
redmatrix
5cfc286972 zat URL auth updated to match changes to the atoken_login interface 2016-07-21 20:06:02 -07:00
redmatrix
bc46f70a90 zat URL auth updated to match changes to the atoken_login interface 2016-07-21 20:04:30 -07:00
redmatrix
8566f91303 fail oembed if it is attempted and less than 80% of the original content is left after html filtering. For the original poster, this will fall back to linkinfo results. If the embed gets through their site but is filtered downstream (with more than 20% of the content removed), it will result in just a link. 2016-07-21 17:44:04 -07:00
Mario Vavti
b63aff77df merge 1.10RC into dev 2016-07-22 01:13:56 +02:00
Mario Vavti
5a1eb65ed6 missing $ 2016-07-22 01:07:53 +02:00
redmatrix
98a2dcad90 Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge 2016-07-21 15:51:25 -07:00
redmatrix
77a021025f DAV auth issue 2016-07-21 15:51:10 -07:00
redmatrix
63123759ed DAV auth issue 2016-07-21 15:50:07 -07:00
redmatrix
6167291488 issue #411 2016-07-21 11:28:38 +02:00
redmatrix
cf0b1f1f15 typo 2016-07-21 01:48:20 -07:00
redmatrix
824dedbe9d issue #453 and a bug noted from the logfiles related to the schema change last month 2016-07-20 23:05:31 -07:00
redmatrix
da707736a0 issue #453 and a bug noted from the logfiles related to the schema change last month 2016-07-20 23:04:07 -07:00
redmatrix
8f57bb95fe undefined function 2016-07-20 21:57:15 -07:00
redmatrix
0c3543ac43 undefined function 2016-07-20 21:55:23 -07:00
redmatrix
d2e5b7cb76 delete test doc 2016-07-20 20:29:33 -07:00
redmatrix
6a56a509d3 Merge branch 'dev' into perms 2016-07-20 19:03:18 -07:00
redmatrix
dffa08adcc fix vevent multi-line formatting 2016-07-20 19:00:45 -07:00
redmatrix
779885f9af fix vevent multi-line formatting 2016-07-20 18:59:51 -07:00
redmatrix
542fcaff9a Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge 2016-07-20 17:57:42 -07:00
redmatrix
bc8c74eb42 sort out some of the authentication mess - with luck this may fix the DAV auth issue which I simply could not duplicate or find a reason for. 2016-07-20 17:57:17 -07:00
redmatrix
3affb2e817 sort out some of the authentication mess - with luck this may fix the DAV auth issue which I simply could not duplicate or find a reason for. 2016-07-20 17:55:40 -07:00
redmatrix
df0cd4dbc7 Merge branch 'dev' into perms 2016-07-20 13:39:10 -07:00
Mario Vavti
d54ad98802 Merge branch '1.10RC' into dev 2016-07-20 22:01:58 +02:00
Mario Vavti
1d90c4ea99 Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC 2016-07-20 22:00:58 +02:00
Mario Vavti
4da005e209 type m query in Acl.php should probably^Ceturn xchan_hash as hash and not as id. This fixes the issue that autocomplete for mail returns null for data.xid 2016-07-20 22:00:41 +02:00
git-marijus
c3149a8d59 Merge pull request #456 from anaqreon/1.10RC-updates
Wiki delete page confirmation and max image width
2016-07-20 20:50:50 +02:00
git-marijus
fd507ff597 Merge pull request #455 from anaqreon/wiki
Wiki delete page confirmation and max image width
2016-07-20 20:50:17 +02:00
Mario Vavti
8c2b93da72 Merge branch '1.10RC' into dev 2016-07-20 20:44:20 +02:00
Mario Vavti
ca82b45fe4 fix /mail wsod issue reported by giac hellvecio 2016-07-20 20:43:12 +02:00
Andrew Manning
da49befb18 Wiki delete page confirmation and max image width 2016-07-20 05:44:29 -04:00
Andrew Manning
e0d9d30bcf Merge remote-tracking branch 'upstream/dev' into wiki 2016-07-20 05:39:08 -04:00
redmatrix
a3e5307b93 fix the forum detection in include/zot 2016-07-19 22:57:23 -07:00
redmatrix
ae6256f95a another couple of minor perms fixes 2016-07-19 22:32:22 -07:00
redmatrix
a961d5e6c8 permission fixes 2016-07-19 20:49:54 -07:00
redmatrix
237cca7a0d fixes to perms 2016-07-19 19:33:48 -07:00
redmatrix
2c9938f0d5 add test sequence 2016-07-19 18:41:36 -07:00
redmatrix
ea83032863 translate more old perms calls 2016-07-19 17:52:45 -07:00
redmatrix
6a4573b935 Merge branch 'dev' into perms 2016-07-19 17:05:59 -07:00
redmatrix
9421e42dad doc correction 2016-07-19 17:04:38 -07:00
redmatrix
f4b658d7b1 issue #411 2016-07-19 05:13:18 -07:00
redmatrix
7272b97e9a yet more grungy perms work. 2016-07-19 01:26:28 -07:00
redmatrix
8a9f062b95 Merge branch 'dev' into perms 2016-07-18 22:35:31 -07:00
redmatrix
eac35c05e9 Merge branch '1.10RC' of https://github.com/redmatrix/hubzilla into 1.10RC_merge 2016-07-18 22:34:16 -07:00
redmatrix
07b96f2430 runaway cron emails 2016-07-18 22:34:07 -07:00
redmatrix
269b3cef72 runaway cron emails 2016-07-18 22:33:26 -07:00
redmatrix
99cf2cbaa9 missing bracket 2016-07-18 21:46:40 -07:00
redmatrix
b63165b6e0 more perms work (a lot more) 2016-07-18 21:37:34 -07:00
redmatrix
32ce790717 move legacy code inside the legacy check 2016-07-18 19:09:27 -07:00
redmatrix
b5b57523f1 more perms work 2016-07-18 16:45:43 -07:00
redmatrix
7524948a97 Merge branch 'dev' into perms 2016-07-18 16:10:41 -07:00
redmatrix
f9b67d3630 more perms work 2016-07-18 13:44:39 -07:00
Mario Vavti
3beb94dc52 whitespace 2016-07-18 13:52:26 +02:00
Mario Vavti
4371e6ad97 resolve merge conflict 2016-07-18 13:50:32 +02:00
Mario Vavti
f44ca74e99 do not transform hashes to tags in [code=xxx] or [code] blocks 2016-07-18 13:48:09 +02:00
redmatrix
10fa5c20e7 export/import channel permissions 2016-07-17 22:40:39 -07:00
redmatrix
f7833411a1 clone channel perms 2016-07-17 22:18:35 -07:00
redmatrix
de4f9d68bd Merge branch 'dev' into perms 2016-07-17 21:40:04 -07:00
redmatrix
571b8cc85b roll version 2016-07-17 19:57:19 -07:00
redmatrix
883fc5d753 update changelog 2016-07-17 19:56:32 -07:00
redmatrix
25b2a6e0cf update changelog 2016-07-17 19:54:59 -07:00
redmatrix
4febdc3bcd jquery update issue prevents comments from reloading and resetting watch cursor 2016-07-17 18:33:45 -07:00
redmatrix
c3617f5d1e jquery update issue prevents comments from reloading and resetting watch cursor 2016-07-17 18:32:38 -07:00
redmatrix
fc78ba7c2f change std_version 2016-07-17 16:38:21 -07:00
redmatrix
279359c1bd Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-17 16:05:46 -07:00
redmatrix
dc9fa7cf64 include attach.php at the module level since 2d4b75428a wasn't backported to dev and we're about to branch an RC 2016-07-17 16:04:00 -07:00
Mario Vavti
2b674d4cd9 hide fullscreen button in embedphotos modal album view 2016-07-17 12:54:10 +02:00
redmatrix
5d0ddb3123 booboo 2016-07-17 02:49:41 -07:00
hubzilla
2d4b75428a Merge pull request #452 from anaqreon/patch-1
Fixed whitescreen when creating folders via cloud files web interface
2016-07-17 19:40:26 +10:00
Mario Vavti
f39d20ac97 some work on guest access token ui 2016-07-17 11:29:37 +02:00
Andrew Manning
db2b6f1268 Fixed whitescreen when creating folders via cloud files web interface
I'm getting a "not found" error when I try to create folders in the cloud files web interface. I click the "Create" button beside the "Upload" button, type a bland name for a new folder, and I get a white screen. Including the attach.php file fixes the bug.

Version 1.9.1+99354ac
2016-07-16 21:23:29 -04:00
Mario Vavti
f396b1bf73 check for variables after schema files have been added 2016-07-16 16:18:36 +02:00
Mario Vavti
e237dfc660 check for variables in schemes 2016-07-16 12:32:22 +02:00
Mario Vavti
641029ab18 hide/show mixup 2016-07-16 10:56:46 +02:00
Mario Vavti
065ef29de2 only use visibility for tabs 2016-07-16 10:52:06 +02:00
redmatrix
aac0fa2b5f os_delete_prohibit 2016-07-16 01:02:41 -07:00
redmatrix
17edec8e4a add new service class restriction to the doco 2016-07-15 21:59:41 -07:00
redmatrix
8e667866fd add service class restrictions to access_tokens 2016-07-15 21:57:41 -07:00
redmatrix
01fe7d6620 remove expired access tokens 2016-07-15 17:34:44 -07:00
redmatrix
f3aff45042 provide examples for using access tokens in urls 2016-07-15 16:31:21 -07:00
redmatrix
d6d94d9427 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-15 15:31:50 -07:00
redmatrix
acb78205c8 login isn't always your email. 2016-07-15 15:30:52 -07:00
redmatrix
dcb3c2c299 mod_home: if using an atoken login on the home page redirect to the channel page of the channel that owns the atoken. 2016-07-15 15:26:36 -07:00
Mario Vavti
9048f8cffe bump minor version because of jquery update 2016-07-15 14:53:15 +02:00
Mario Vavti
4a2fb8336e round up height 2016-07-15 14:23:10 +02:00
Mario Vavti
34a16e0ab9 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-07-15 13:21:07 +02:00
Mario Vavti
c2779b6f33 add jquery migrate for version 3 2016-07-15 13:20:55 +02:00
Mario Vavti
2e32b5f467 upgrade to jquery-3.1 and minor fixes 2016-07-15 13:20:00 +02:00
redmatrix
da5ec98f98 make lockview work with throwaway identities 2016-07-15 02:07:27 -07:00
redmatrix
d54f5a3831 more cleanup of atoken UI 2016-07-15 01:43:09 -07:00
redmatrix
5e475acb85 cleanup and debug of atoken feature 2016-07-15 01:33:28 -07:00
redmatrix
f666d8a083 enforce non-empty name and token/password on access tokens until better checks are instituted. 2016-07-15 01:06:25 -07:00
redmatrix
7ee7f00bf3 Here's the basic UI for the Zot Access Tokens, requires some minor cleanup 2016-07-14 22:41:53 -07:00
redmatrix
397a23499d make the xchan_hash for the access token location independent 2016-07-14 21:28:17 -07:00
redmatrix
d660bde324 missing brace 2016-07-14 20:53:38 -07:00
redmatrix
94bd53c0f1 schema updates for zot access tokens 2016-07-14 20:51:15 -07:00
redmatrix
f70f4a4e85 add zat to acl 2016-07-14 20:26:22 -07:00
redmatrix
f3eb9af046 more ZAT work 2016-07-14 19:43:47 -07:00
redmatrix
e6c8614801 first cut at zot access tokens 2016-07-14 19:24:15 -07:00
redmatrix
05a9f2f0f5 markdown is whitespace sensitive 2016-07-14 17:46:21 -07:00
redmatrix
115ef3249c who are we 2016-07-14 17:45:09 -07:00
redmatrix
191cd21028 more perms work 2016-07-13 23:05:19 -07:00
redmatrix
b3a785711c deprecate/remove json_decode_plus 2016-07-13 22:11:06 -07:00
redmatrix
503b420292 rework perm_is_allowed 2016-07-13 20:23:20 -07:00
redmatrix
0aa205044b Merge branch 'dev' into perms 2016-07-13 20:19:11 -07:00
redmatrix
00afe56cad let abconfig specify a family 2016-07-13 20:17:40 -07:00
redmatrix
1fd65c934d lots more permission work 2016-07-13 19:53:28 -07:00
redmatrix
b72720f6b6 Merge branch 'dev' into perms 2016-07-13 18:24:45 -07:00
redmatrix
f60a0c5ce0 document mod_acl a bit better and try to remove some redundancies and consolidate the various options 2016-07-13 17:51:19 -07:00
redmatrix
18565600b2 missing namespace prefix \ 2016-07-12 22:58:12 -07:00
redmatrix
f4e4e734de more work on perms 2016-07-12 21:47:24 -07:00
redmatrix
6424bac47c Merge branch 'dev' into perms 2016-07-12 20:50:27 -07:00
redmatrix
bdd7d24ac1 update_remote_id - updated to work with iconfig 2016-07-12 19:08:36 -07:00
redmatrix
0fa807e7ad don't try to send sync packets to dead sites. 2016-07-12 18:38:39 -07:00
redmatrix
b6987b4287 the abconfig defaults weren't changed in the schema files when they were changed in the code 2016-07-12 13:15:20 -07:00
redmatrix
ed0e2b52d7 move permissiondescription class to zotlabs/lib 2016-07-11 21:46:16 -07:00
redmatrix
168d35747d use the get_hostname function rather than parse the url 2016-07-11 18:59:54 -07:00
redmatrix
a01baab4f0 Merge branch 'dev' into perms 2016-07-11 17:45:10 -07:00
redmatrix
17c3e12eab document the new change_channel hook 2016-07-11 17:43:10 -07:00
redmatrix
71b001fdb7 more perms work - notably the stuff in public_perms 2016-07-11 17:02:49 -07:00
redmatrix
833de9180e create change_channel hook 2016-07-11 13:46:06 -07:00
redmatrix
fb36561a68 force non-null sess_data 2016-07-11 13:27:44 -07:00
redmatrix
67c60229ca use the profile_uid here. 2016-07-11 13:20:12 -07:00
redmatrix
f4bcb82041 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-11 13:19:13 -07:00
Habeas Codice
983ccef87c NOT NULL constraint without default and INSERT does not provide one 2016-07-11 10:55:42 -07:00
Mario Vavti
a849dcadb6 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-07-11 12:50:12 +02:00
Mario Vavti
d5afd0d7c2 do not use visibility for fullscreen button and move fullscreen button to the right 2016-07-11 12:49:53 +02:00
redmatrix
cc83983ae5 perms work 2016-07-10 17:45:14 -07:00
hubzilla
ba5183b244 Merge pull request #451 from git-marijus/dev
remove check for mcrypt
2016-07-11 09:06:11 +10:00
Mario Vavti
3d3584b36c remove check for mcrypt 2016-07-10 13:42:04 +02:00
Mario Vavti
e11219888d Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-07-10 11:34:10 +02:00
redmatrix
e6638b4715 change default so we don't have to check for array existence later 2016-07-09 21:23:00 -07:00
redmatrix
c9db8c6857 more permissions work 2016-07-09 21:08:02 -07:00
redmatrix
917a465ccd more work on perms 2016-07-09 19:03:29 -07:00
redmatrix
ce5adbf51e more sql fine tuning 2016-07-09 18:10:13 -07:00
Andrew Manning
50e581d88a Set max-width for embedded images 2016-07-09 20:24:16 -04:00
Andrew Manning
47d7fc70e8 Merge remote-tracking branch 'upstream/dev' into wiki 2016-07-09 20:17:20 -04:00
redmatrix
e2574cf069 some work on the forum widget queries 2016-07-09 16:07:53 -07:00
redmatrix
ee1ec0428b gak one more typo 2016-07-07 18:53:09 -07:00
redmatrix
3b17dca252 typo 2016-07-07 18:51:56 -07:00
redmatrix
eef40cb3fd duplicate supression SQL query was horribly inefficient and could cause issues in resource deprived environments. 2016-07-07 18:47:18 -07:00
hubzilla
9f413ed174 Merge pull request #450 from git-marijus/dev
fix /cloud after recent changes
2016-07-08 10:40:59 +10:00
redmatrix
233cfc29d6 hide the redeliver option one level down since it should rarely be needed by folks outside of shared hosting. 2016-07-07 17:23:52 -07:00
redmatrix
e11330a5c8 revise how we store perm_limits 2016-07-07 16:44:58 -07:00
Mario Vavti
0b2ad9deca Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-07-07 20:39:52 +02:00
Mario Vavti
227320f6f0 more fixes for /cloud and /dav 2016-07-07 20:16:27 +02:00
redmatrix
3bee6543fb reduce the memory usage of the expire query dramatically. 2016-07-06 22:19:05 -07:00
redmatrix
581a3c5323 expire crashing on shared hosting from memory exhaustion. Lower the expire limit. Also the sys channel was being expired with everybody else due to a flag change regression. 2016-07-06 22:02:06 -07:00
Mario Vavti
a59e84cadd Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-07-06 21:31:17 +02:00
Mario Vavti
d4627a0b1c fix /cloud after recent changes 2016-07-06 21:31:05 +02:00
redmatrix
08a4763bff more work on permissions 2016-07-05 20:21:47 -07:00
redmatrix
537f30f707 Merge branch 'dev' into perms 2016-07-05 19:40:09 -07:00
redmatrix
ad954d01de unused file 2016-07-05 17:57:36 -07:00
redmatrix
e3d70e6b62 merge include/reddav.php into Zotlabs/Storage/Directory.php 2016-07-05 17:54:05 -07:00
redmatrix
cbf009a95d cleanup 2016-07-05 16:56:40 -07:00
redmatrix
35cc763a92 regression - save bookmarks no longer present in item menu 2016-07-05 16:24:45 -07:00
redmatrix
cf05111622 start to refactor the permission roles 2016-07-04 22:37:30 -07:00
redmatrix
e6224898d2 more heavy lifting on xtensible perms 2016-07-04 21:33:25 -07:00
redmatrix
d566ffa678 more heavy lifting on extensible perms 2016-07-04 17:55:13 -07:00
redmatrix
6bf2e8a108 some perms fixes to stuff that was already written before I move on 2016-07-04 16:30:03 -07:00
redmatrix
805ecde6a5 minor 2016-07-04 00:12:53 -07:00
redmatrix
2a26b0ae91 perms work - settings page 2016-07-03 22:47:46 -07:00
redmatrix
916e088462 make permissionlimits into a class 2016-07-03 18:20:15 -07:00
redmatrix
c918bbba25 more work on x permissions 2016-07-03 17:10:00 -07:00
redmatrix
57226b2e13 Merge branch 'dev' into perms 2016-07-03 15:58:20 -07:00
hubzilla
f46eecc1e7 Merge pull request #448 from Treer/avatars
Force local cache update when user changes their profile picture
2016-07-04 06:38:49 +10:00
Treer
5c062aaec4 force immediate avatar update 2016-07-03 22:38:05 +10:00
Treer
b87106b6fe Mark nickname as required field, if left empty then channel creation fails silently 2016-07-03 17:59:44 +10:00
redmatrix
523e7b5084 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-07-01 20:48:49 -07:00
redmatrix
41fa2d6c69 delivery invoked twice in mod_tagger, once in post_activity_item() and another at the main module level 2016-07-01 20:46:57 -07:00
redmatrix
5947467339 use small photo for Diaspora attribution correction; the medium looks awkward in the D* stream. 2016-07-01 20:34:00 -07:00
Mario Vavti
0a11991340 use visibility instead of display to hide elements 2016-07-01 12:58:15 +02:00
Andrew Manning
0630609d6e Merge remote-tracking branch 'upstream/dev' into wiki 2016-07-01 06:36:25 -04:00
Andrew Manning
205924ff29 JavaScript popup for page delete confirmation 2016-07-01 06:35:49 -04:00
Mario Vavti
7371e08625 ditch the change_view widget and make header fixed in fullscreen mode 2016-07-01 12:21:19 +02:00
redmatrix
bb5ec8cfb8 allow multiple apd's per plugin dir 2016-07-01 02:16:23 -07:00
redmatrix
e6c8de5e4c if cron is broken because the entire db or config table is crashed, don't send a cron broken email - because we have no way of limiting it to just one email. We need a working config to do that. 2016-06-30 21:43:00 -07:00
redmatrix
bd403276f2 disable wiki if feature disabled, sync updates of delayed publish posts 2016-06-30 21:27:59 -07:00
redmatrix
7f8dcf4f12 sync flags even if post has not been edited 2016-06-30 21:12:39 -07:00
hubzilla
eef8f3b417 Merge pull request #445 from anaqreon/wiki
Table of contents with links is generated if [toc] is found in Markdown text
2016-07-01 11:57:48 +10:00
Andrew Manning
0fd8eeec23 Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-30 21:51:33 -04:00
Andrew Manning
7124c0aee5 Replace homemade table of content generator with existing jQuery plugin. Now toc is linked to document headings. 2016-06-30 21:50:38 -04:00
Mario Vavti
852b2659e9 update moment.js to version 2.13 2016-06-30 21:56:00 +02:00
redmatrix
1cc816f662 dreport: convert timestamp to channel localtime and get rid of old pre-template code 2016-06-29 22:53:18 -07:00
redmatrix
bfe84a9ff7 templatise the Dreport page and add a redeliver option for when things stuff up badly. 2016-06-29 22:46:47 -07:00
redmatrix
339e620738 wiki featured disabled by default in UNO. 2016-06-29 21:03:53 -07:00
redmatrix
9ef710c557 provide wiki as a feature (default is on so there aren't any surprises) and add to channel menu and profile tabs 2016-06-29 20:59:00 -07:00
redmatrix
df4ff26845 only request geolocation permission if we're creating a post. 2016-06-29 17:53:59 -07:00
redmatrix
2e93a09d83 stream large photos through buffered I/O if possible 2016-06-29 17:31:48 -07:00
hubzilla
05aba0b4dd Merge pull request #444 from git-marijus/dev
Merge branch sabre32 into dev
2016-06-30 09:34:22 +10:00
Mario Vavti
f098600c41 missing backslash leads to wsod on refresh permissions 2016-06-29 23:04:34 +02:00
Mario Vavti
ad83825d4f missing backslash leads to wsod on refresh permissions 2016-06-29 22:50:40 +02:00
Mario Vavti
3102440d40 Merge branch 'dev' into sabre32 2016-06-29 09:11:22 +02:00
redmatrix
715b1667d9 readability 2016-06-28 20:48:43 -07:00
redmatrix
7d62e087c6 identity_export_year() was a bit short-sighted. We really require arbitrary date ranges. A new function was created to tackle this - channel_export_items() which takes a channel, and a start and finish date. Finish date will default to "now" if not set. Will be working this into the interface under a module named "export_items" which will correspond closely to the existing "import_items" module you'll need to do the reverse operation. Will also make it available via the API. Once that is complete, I anticipate removing identity_export_year() as it will then be somewhat redundant, and modifying the documentation on the channel export page accordingly. Note: the function works strictly in GMT so an interface would need to convert from channel local time. 2016-06-28 13:36:48 -07:00
Mario Vavti
dcc65bbacb update to sabre/dav to version 3.2.0 2016-06-28 21:45:14 +02:00
Mario Vavti
feaad50b6c Merge branch 'dev' into sabre32 2016-06-28 13:45:00 +02:00
Mario Vavti
7b2d54dffa fix month view in fullscreen mode 2016-06-28 13:44:32 +02:00
Mario Vavti
e170217c33 erge branch 'dev' into sabre32 2016-06-28 11:57:03 +02:00
Mario Vavti
aff58934c0 update fullcalendar to version 2.8.0 2016-06-28 11:56:28 +02:00
Mario Vavti
9f576369a9 Merge branch 'dev' into sabre32 2016-06-28 11:09:22 +02:00
redmatrix
7d7f43c205 still working through some issues with curl magic-auth
fixed profile photo upload
2016-06-27 22:25:37 -07:00
redmatrix
30a5fe3061 provide a daemon for implementing zot magic-auth over curl. 2016-06-27 19:53:35 -07:00
redmatrix
b155e93ab1 add letsencrypt x3 intermediate cert and new cert file, improve UX of new registrations 2016-06-27 19:04:00 -07:00
redmatrix
3704ff57cb replace [+] and [-] with chevron icons 2016-06-27 16:50:06 -07:00
redmatrix
ee1d527497 comment on the setup page about the possible need for intermediate certs. 2016-06-27 16:15:47 -07:00
Habeas Codice
f40f7b4d6e typos 2016-06-27 16:06:09 -07:00
Mario Vavti
911510f999 Merge branch 'dev' into sabre32 2016-06-27 22:14:42 +02:00
Habeas Codice
45f5ac560d typos 2016-06-27 06:28:08 -07:00
redmatrix
fe7020e2f8 start on re-write of the permissions doc. Some of this will change (slightly), as the permissions framework is currently evolving. Most of the concepts and mechanisms will remain the same, but we need to simplify and do a better job of explaining the concepts. 2016-06-27 05:18:35 -07:00
redmatrix
17e161006a added permissionroles 2016-06-27 04:44:10 -07:00
redmatrix
85d2ad4aea Merge branch 'dev' into perms 2016-06-27 04:00:10 -07:00
Mario Vavti
5b9cd0af64 Merge branch 'dev' into sabre32 2016-06-27 09:54:01 +02:00
redmatrix
8d298d5a06 fix for the rendering side of issue #412. We traditionally store all
"user generated" content with ENT_COMPAT encoding to reduce the attack
vector for JS CSS exploits. This may present compatibility issues sharing
wikis to platforms which do not provide such CSS protection. We can either
decide that wikis are inherently insecure and filter them on render (with
an associated performance penalty), or keep the existing method of filtering
on store. I'm not making that choice. I'm merely fixing the obvious rendering
issue in mono-platform viewing.
2016-06-26 22:26:45 -07:00
redmatrix
3035c792dc remove the app $a passed to profile_load, also add profile_load to mod_wiki which should fix issue #431 2016-06-26 22:13:59 -07:00
redmatrix
2029b2b9ed document the daemon classes 2016-06-26 21:58:09 -07:00
redmatrix
900d8f3b0a Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-26 20:17:12 -07:00
redmatrix
e2de2f65d5 issue #442, tables contain too much whitespace (there's a definite issue here, but I should note the offending example was full of carriage returns as well as linefeeds; which exacerbated the problem). 2016-06-26 20:15:42 -07:00
Andrew Manning
81da9f99e4 Fixed bug with rendering table of contents upon page load 2016-06-26 15:41:25 -04:00
Andrew Manning
216f034b6d Also generate table of contents when loading the page 2016-06-26 15:27:55 -04:00
Andrew Manning
b96edd8b9a Added table of contents generator. Table is inserted wherever [toc] is encountered. 2016-06-26 15:04:47 -04:00
Mario Vavti
27ee95106d Merge branch 'dev' into sabre32 2016-06-26 08:59:58 +02:00
hubzilla
dac3138fd1 Merge pull request #441 from Treer/cdn
fix absolute .js urls
2016-06-26 13:43:07 +10:00
Treer
e0a7637626 fix absolute .js urls 2016-06-26 13:08:40 +10:00
hubzilla
8c4481733f Merge pull request #438 from anaqreon/wiki
Wiki post generation option and image embed tool
2016-06-26 08:25:31 +10:00
hubzilla
d20e62dcd3 Merge pull request #440 from Treer/misc
fix help link
2016-06-26 08:25:06 +10:00
hubzilla
7805a3c527 Merge pull request #439 from Treer/cdn
Allow absolute links to css and js files (for CDN links)
2016-06-26 08:22:16 +10:00
Andrew Manning
0df3978cc5 A page name wrapped in double brackets is converted into a link to another page in the current wiki 2016-06-25 14:29:52 -05:00
Treer
bd4a88cd3e fix help link 2016-06-26 03:17:10 +10:00
Treer
2dc1236dca Allow absolute links to css and js files 2016-06-25 22:38:15 +10:00
Mario Vavti
2528d97f52 Merge branch 'dev' into sabre32 2016-06-25 13:58:24 +02:00
Andrew Manning
241b257556 Insert image links wherever cursor is in the editor 2016-06-25 06:50:24 -05:00
Andrew Manning
83a42afddf Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-25 06:30:15 -05:00
Andrew Manning
780f83a118 Post generation about new wiki is optional, default is NOT to post. Fixed bug in wiki creation. Added embed image dialog and album browser. 2016-06-25 06:27:14 -05:00
Alexandre Hannud Abdo
ec3651d216 Improvements to help pages 2016-06-25 04:13:29 -07:00
redmatrix
6154fc7686 Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-06-25 04:11:03 -07:00
redmatrix
1924459abd media (e.g. video) files weren't being detected correctly in oembed, causing the stream to try and load large videos (and failing) 2016-06-25 04:10:48 -07:00
redmatrix
f66576f366 media (e.g. video) files weren't being detected correctly in oembed, causing the stream to try and load large videos (and failing) 2016-06-25 04:09:07 -07:00
hubzilla
7470fc7f24 Merge pull request #437 from solstag/help
Improvements to help pages
2016-06-25 20:24:28 +10:00
Alexandre Hannud Abdo
0e041a3b64 Improvements to help pages 2016-06-25 00:18:24 +00:00
Mario Vavti
c8ae04a96a Merge branch 'dev' into sabre32 2016-06-24 11:25:20 +02:00
redmatrix
c809b6f95e Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-24 02:18:26 -07:00
redmatrix
1577efa25e fix pdledit list mode 2016-06-24 02:17:25 -07:00
redmatrix
fb93ae2128 fix pdledit "list layouts" 2016-06-24 02:07:12 -07:00
hubzilla
25c9e9ef93 Merge pull request #435 from dissolve/microformats2
add url permalink mf2 markup
2016-06-24 14:55:56 +10:00
Ben Roberts
812dc9e898 add url permalink mf2 markup 2016-06-24 00:45:39 -04:00
hubzilla
bf4b698573 Merge pull request #434 from dissolve/microformats2
p-author missing from embedded h-card in items
2016-06-24 13:58:01 +10:00
Ben Roberts
5162c55e5d p-author missing from embedded h-card in items 2016-06-23 23:46:02 -04:00
redmatrix
096619dbbe make dropdown-caret invoke the dropdown 2016-06-23 20:13:20 -07:00
redmatrix
fa02a09107 SuperCurl to provide a re-usable curl options stack and just change options that are different from one call to the next 2016-06-23 20:05:57 -07:00
redmatrix
51e2ef39c2 db update for abconfig transition 2016-06-23 18:35:01 -07:00
redmatrix
b19bbf5473 change AbConfig to use channel_id instead of channel_hash; which was a mistake in retrospect 2016-06-23 18:12:26 -07:00
redmatrix
e5c66d94f2 relocate the cache class 2016-06-23 05:18:58 -07:00
redmatrix
2a32713dfc Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-23 01:18:17 -07:00
redmatrix
acf26d5c63 code cleanup for profile_photos 2016-06-23 01:17:44 -07:00
Mario Vavti
39b14b6b81 Merge branch 'dev' into sabre32 2016-06-23 10:14:13 +02:00
hubzilla
ac81a3a5ef Merge pull request #433 from dissolve/microformats2
microformats 2 for posts
2016-06-23 14:39:26 +10:00
Ben Roberts
ab628eb2a3 microformats 2 for posts 2016-06-22 23:59:27 -04:00
redmatrix
b8c5a91940 set profile when "use existing photo" 2016-06-22 20:46:44 -07:00
redmatrix
f7d2c99a3a move revision up 2016-06-22 20:18:29 -07:00
redmatrix
32408ed6a3 missing class selector when "use photo as profile photo" 2016-06-22 20:18:08 -07:00
redmatrix
515b054a6e missing class selector when "use photo as profile photo" 2016-06-22 20:17:19 -07:00
redmatrix
cef77ce5bb the xchan_query wasn't fully optimised as we were comparing quoted and unquoted strings when looking for duplicates 2016-06-22 19:22:59 -07:00
redmatrix
1267d995ef db statement debugging 2016-06-22 19:08:59 -07:00
redmatrix
ec8091a102 use the normal html escape for '@' in addresses rather than the high-plane unicode variant. This makes it copy-able, but not easily scrape-able. 2016-06-22 18:00:18 -07:00
Mario Vavti
5536df51f5 erge branch 'dev' into sabre32 2016-06-22 09:58:55 +02:00
redmatrix
f48b12ff52 provide a skeleton of the current CalDAVClient with lots of notes about how best to move forward just in case anybody is feeling ambitious or anxious. 2016-06-21 20:44:55 -07:00
redmatrix
415a8d1e01 channel homepage not providing content when javascript disabled 2016-06-21 19:42:08 -07:00
redmatrix
2a840460dd vcard spec changes 2016-06-21 19:25:14 -07:00
redmatrix
12f114c4be Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-21 18:26:16 -07:00
redmatrix
b593c3a9b9 1. provide automatic relocation of important links in items that are imported or synced to clones
2. provide framework for custom curl request bodies using custom/non-standard request methods. This was a real nightmare because curl doesn't actually let you specify a string to send as the request body (except when doing POST). You have to treat it as a file upload using a custom file handler function which provides the actual content in chunks as if it were buffered I/O.
3. item_store and item_store_update now return the item that was stored
2016-06-21 18:24:36 -07:00
redmatrix
8fa26db1b3 1. provide automatic relocation of important links in items that are imported or synced to clones
2. provide framework for custom curl request bodies using custom/non-standard request methods. This was a real nightmare because curl doesn't actually let you specify a string to send as the request body (except when doing POST). You have to treat it as a file upload using a custom file handler function which provides the actual content in chunks as if it were buffered I/O.
2016-06-21 18:18:06 -07:00
Mario Vavti
ecae0b3d97 Merge branch 'dev' into sabre32 2016-06-21 10:08:49 +02:00
redmatrix
63423c8ee1 make sure the optimisations are reliable 2016-06-20 20:56:58 -07:00
redmatrix
ed16660867 code optimisation 2016-06-20 20:34:19 -07:00
redmatrix
9c9d6363af update attach on import if exists 2016-06-20 19:39:12 -07:00
redmatrix
3a43b1d85d Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-20 13:43:36 -07:00
redmatrix
76f07a7f97 Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-06-20 13:42:51 -07:00
redmatrix
4d219df04e fix siteinfo plugin list 2016-06-20 13:42:39 -07:00
redmatrix
01bfadaeaa fix siteinfo plugin list 2016-06-20 13:42:04 -07:00
hubzilla
670d12219b Merge pull request #429 from anaqreon/wiki
Wiki page revision comparison viewer
2016-06-21 06:23:58 +10:00
Mario Vavti
da2c0a22f9 Merge branch 'dev' into sabre32 2016-06-20 22:05:03 +02:00
Mario Vavti
953ac6f3c7 last merge from master did reset the std_version to 1.8 - set it back to 1.9 for dev 2016-06-20 22:03:39 +02:00
Mario Vavti
545219b839 Merge branch 'dev' into sabre32 2016-06-20 21:47:49 +02:00
Mario Vavti
985fb44424 Merge branch 'master' into dev 2016-06-20 21:46:33 +02:00
Mario Vavti
17c5502330 missing backslash leading to wsod on xconfig changes 2016-06-20 21:45:15 +02:00
Andrew Manning
aa88837a31 Merge branch 'dev' into wiki 2016-06-20 13:28:50 -04:00
Andrew Manning
a3ec9f3940 Add formatted heading for revision comparison viewer 2016-06-20 13:27:05 -04:00
Andrew Manning
8cd9a1e4fc Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-20 13:07:29 -04:00
Andrew Manning
f4d9d34bbc Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-06-20 13:06:32 -04:00
Andrew Manning
20b4fc9198 Do not change active page commit until user reverts the page 2016-06-20 13:05:18 -04:00
Mario Vavti
e40112b40d Merge branch 'dev' into sabre32 2016-06-20 09:31:27 +02:00
redmatrix
cc09f9a7a5 Added many of the recent schema changes to the database schema documentation 2016-06-19 22:50:41 -07:00
redmatrix
4b505948f0 update the bbcode doc 2016-06-19 22:04:08 -07:00
redmatrix
3cf6f1f79c merge conflict 2016-06-19 21:47:04 -07:00
redmatrix
905374c86e experimental rtl support; this will probably require a fair bit of work. 2016-06-19 21:10:57 -07:00
redmatrix
30841d9470 Don't use count() to check DB results 2016-06-19 18:57:56 -07:00
Mario Vavti
7a4efcf67f return something so we can make a conclusion 2016-06-19 20:34:38 +02:00
Mario Vavti
6e0eb532a5 Merge branch 'dev' into sabre32 2016-06-19 11:04:02 +02:00
redmatrix
b6324246ff hebrew hstrings.php was empty 2016-06-18 20:25:31 -07:00
root
76e11b46b7 hebrew translation 2016-06-18 20:03:38 -07:00
redmatrix
3dad4a9ff1 update the top level database doc, the individual schema pages are still out of date. 2016-06-18 19:57:44 -07:00
redmatrix
dbb0a0283f schema changes needed for the caldav client bit 2016-06-18 15:33:47 -07:00
Mario Vavti
178b440f05 Merge branch 'dev' into sabre32 2016-06-18 11:10:40 +02:00
redmatrix
755dd67ec7 changelog update for 1.8 2016-06-17 22:42:17 -07:00
redmatrix
2e7606f569 the text link to a thing will take you to the local thing page, both as a link for editing and as a destination in case there is no thing photo. If there's a photo, the photo link will take you to the thing URL. 2016-06-17 21:44:08 -07:00
redmatrix
c81f6b9f6f "thing" always showing default url, not that supplied by the thing. 2016-06-17 16:28:36 -07:00
redmatrix
d0f0a99909 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-17 15:02:07 -07:00
redmatrix
2793086c0d 1. string update, 2. pretty print json blobs 2016-06-17 14:58:03 -07:00
Andrew Manning
80d3a831f3 Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-17 06:36:09 -04:00
Andrew Manning
961539258b Wiki page revision comparison tool with diff displayed in modal dialog. Leverages Diff class from http://code.stephenmorley.org/php/diff-implementation with license CC0 1.0 universal http://creativecommons.org/publicdomain/zero/1.0/legalcode 2016-06-17 06:33:39 -04:00
Mario Vavti
9749bbcedc Merge branch 'dev' into sabre32 2016-06-17 11:58:14 +02:00
Mario Vavti
aa5ac9dc3f only use height: auto for week and day view 2016-06-17 11:57:36 +02:00
Mario Vavti
0324bc5cf0 Merge branch 'dev' into sabre32 2016-06-17 10:04:27 +02:00
redmatrix
f6d7628254 core changes to better support media migrations 2016-06-16 20:16:39 -07:00
Andrew Manning
e5f4d80bbe Merge remote-tracking branch 'upstream/dev' into dev 2016-06-16 19:45:02 -04:00
redmatrix
aa77b04860 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-16 05:08:26 -07:00
Mario Vavti
5b479d63d6 Merge branch 'dev' into sabre32 2016-06-16 12:22:32 +02:00
Mario Vavti
8924f94d05 show month view in full height in fullscreen view 2016-06-16 12:21:59 +02:00
Mario Vavti
a873b7b6e8 mrge branch 'dev' into sabre32 2016-06-16 11:37:16 +02:00
Mario Vavti
7baa20d559 fix scrollbars 2016-06-16 11:36:51 +02:00
Mario Vavti
2b7f114c2d Merge branch 'dev' into sabre32 2016-06-16 11:22:52 +02:00
Mario Vavti
951bf5ec2e update 3rd party lib fullcalendar to version 2.7.3 2016-06-16 11:22:08 +02:00
Mario Vavti
28a7458e48 Merge branch 'dev' into sabre32 2016-06-16 10:26:47 +02:00
redmatrix
a2a87fec54 code comments 2016-06-15 22:36:00 -07:00
redmatrix
d457f11717 custom request methods for curl 2016-06-15 21:25:26 -07:00
redmatrix
bc5f73e6c3 provide a default for undefined languages 2016-06-15 20:51:55 -07:00
redmatrix
1dc35db1fe ignore case in language names and add 'js' as an alias for 'javascript' 2016-06-15 20:25:19 -07:00
redmatrix
427badcae9 improve readability of comments 2016-06-15 20:09:40 -07:00
hubzilla
e0b705fd54 Merge pull request #422 from anaqreon/wiki
Wiki rename page feature added. Bug fixes related to git commits.
2016-06-16 13:01:49 +10:00
redmatrix
854c23a751 This was the reason for the large line widths - an extra linefeed after each li element 2016-06-15 19:59:30 -07:00
redmatrix
fa48de33c2 provide syntax based [colour] highlighting on code blocks for popular languages. I'm not happy with the line height on the list elements but couldn't see where this was defaulted. This uses the syntax [code=xxx]some code snippet[/code], where xxx represents a code/language style - with about 18 builtins. 2016-06-15 19:44:15 -07:00
Andrew Manning
fc7c4e64ff Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-15 21:48:47 -04:00
redmatrix
476116a972 translate already imported system apps 2016-06-15 16:24:45 -07:00
Andrew Manning
f2dda646ec Merge remote-tracking branch 'upstream/dev' into dev 2016-06-15 19:15:47 -04:00
Mario Vavti
05ed20d336 Merge branch 'dev' into sabre32 2016-06-15 17:34:03 +02:00
redmatrix
47fc0c7958 add new connection to default group when auto-accepted 2016-06-15 05:28:16 -07:00
Andrew Manning
688171d016 Rename page feature added. Fixed bug in git commit function and other minor fixes. 2016-06-15 06:25:31 -04:00
Mario Vavti
9a0dff08bc Merge branch 'dev' into sabre32 2016-06-15 08:42:51 +02:00
redmatrix
77dedf6648 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-14 20:31:10 -07:00
redmatrix
212d8b6cfd support cookie auth in Sabre DAV 2016-06-14 20:30:34 -07:00
hubzilla
9eb23a1208 Merge pull request #419 from anaqreon/wiki
Wiki context help translations IT and ES-ES
2016-06-15 10:06:08 +10:00
redmatrix
ccfd028919 readme for the module directory, also provide an undocumented way to reset the timestamp on connection photos to force a refresh without messing with the database directly. 2016-06-14 17:04:29 -07:00
Andrew Manning
e5a919c32e Fix Spanish wiki translation 2016-06-14 19:58:33 -04:00
Andrew Manning
eeaafe9f39 Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-14 19:56:04 -04:00
Andrew Manning
6430a232f8 Add Italian wiki context help translation 2016-06-14 19:55:31 -04:00
Mario Vavti
24569a18db css fix 2016-06-14 23:21:26 +02:00
Mario Vavti
5c458e9111 Merge branch 'dev' into sabre32 2016-06-14 09:42:43 +02:00
redmatrix
0ef2622621 some work to provide propagation and honouring of the item_notshown flag. 2016-06-13 22:09:22 -07:00
redmatrix
1ff9abe1b4 missing iconfig conversion 2016-06-13 21:16:36 -07:00
hubzilla
8e5948716e Merge pull request #418 from anaqreon/wiki
Wiki context help translations DE and ES-ES
2016-06-14 13:03:30 +10:00
redmatrix
1e68d4fb75 deprecate the item_id table - replace with iconfig. A possibly useful function in the iconfig class would be a search which takes a service id and type and uid, matches against an item and returns the iid. That could save a bit of code duplication. 2016-06-13 19:58:24 -07:00
Andrew Manning
1bec739195 Missing space in Spanish translation 2016-06-13 21:59:51 -04:00
Andrew Manning
025a7d2f0f Missing onclick attributes in German translation 2016-06-13 21:57:48 -04:00
Andrew Manning
ebf238be5d Move Spanish context help translation from es to es-es and make es a symlink to es-es 2016-06-13 21:47:05 -04:00
Andrew Manning
98484f0def Move Spanish context help translation from es to es-es and make es a symlink to es-es 2016-06-13 21:42:00 -04:00
Andrew Manning
892f061ad6 Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-13 20:48:57 -04:00
Andrew Manning
8bfb620a13 Add DE and ES-ES translations for wiki context help 2016-06-13 20:48:19 -04:00
Mario Vavti
b6d425838f css fixes 2016-06-13 17:19:49 +02:00
Mario Vavti
e963714ad6 Merge branch 'dev' into sabre32 2016-06-13 09:18:39 +02:00
hubzilla
6d4188f05e Merge pull request #417 from anaqreon/wiki
Wiki context help first draft
2016-06-13 12:10:20 +10:00
Andrew Manning
3e804757c1 Context help for wiki interface 2016-06-12 21:15:52 -04:00
Andrew Manning
cc43a49b6d Merge remote-tracking branch 'upstream/dev' into wiki 2016-06-12 20:24:26 -04:00
hubzilla
b18b9464a4 Merge pull request #416 from anaqreon/embedphotos
Add embed photos button with album browser to new post editor
2016-06-13 10:15:09 +10:00
Andrew Manning
71d4f65cb2 Move javascript functions back to jot-header.tpl 2016-06-12 20:10:37 -04:00
Andrew Manning
b5933e9d44 Photo embed button with album browser works in new post editor. 2016-06-12 19:41:37 -04:00
redmatrix
81b3c59711 DB schema issue with import 2016-06-12 16:34:27 -07:00
Andrew Manning
410f5389ae Apply purify_html to page content before preview and save to prevent JavaScript code injection. 2016-06-12 15:18:43 -07:00
Andrew Manning
a1183bf09a Merge remote-tracking branch 'upstream/dev' into embedphotos 2016-06-12 14:38:48 -04:00
Andrew Manning
43055e0199 Apply purify_html to page content before preview and save to prevent JavaScript code injection. 2016-06-12 07:14:12 -04:00
redmatrix
1789c3242a Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-06-11 15:29:25 -07:00
redmatrix
f41380de77 remove debugging 2016-06-11 15:28:52 -07:00
redmatrix
0e0a6f5f8d Work supporting issue #411, add an optional priority (int) as a second arg to head_add_js to affect the load ordering, larger numbered priorities will be included after lower numbered ones. Default priority is 0.Note that we treat main.js differently and always add main.js to the page last, regardless of any other
ordering.
2016-06-11 15:23:13 -07:00
Mario Vavti
ef95c68b4f Merge branch 'dev' into sabre32 2016-06-11 20:33:03 +02:00
Mario Vavti
bdbbe00bdf Merge branch 'dev' into sabre32 2016-06-11 20:12:41 +02:00
Mario Vavti
86985b454f Merge branch 'dev' into sabre32 2016-06-10 12:22:01 +02:00
Mario Vavti
9d5d3a9468 Merge branch 'dev' into sabre32 2016-06-10 10:45:09 +02:00
Andrew Manning
7fc2b13fe6 Stashing changes. Not a functional state. 2016-06-09 20:06:36 -04:00
redmatrix
d5d5d78e3a initial perms work 2016-06-09 16:16:56 -07:00
Mario Vavti
85e82e919e more style work 2016-06-09 22:05:52 +02:00
Mario Vavti
9b96fe66a6 Merge branch 'sabre32' of https://github.com/redmatrix/hubzilla into sabre32 2016-06-09 09:10:46 +02:00
Mario Vavti
11045b92fb Merge branch 'dev' into sabre32 2016-06-09 09:09:13 +02:00
Mario Vavti
4234c9a194 Merge branch 'dev' into sabre32 2016-06-08 12:04:45 +02:00
Mario Vavti
75b97cafb0 Merge branch 'dev' into sabre32 2016-06-07 09:43:14 +02:00
Mario Vavti
655290b022 Merge branch 'sabre32' of https://github.com/redmatrix/hubzilla into sabre32 2016-06-06 14:14:40 +02:00
Mario Vavti
b886a40471 Merge branch 'dev' into sabre32 2016-06-06 09:39:56 +02:00
Mario Vavti
cfbd2fc85c Merge branch 'dev' into sabre32 2016-06-05 20:04:12 +02:00
Mario Vavti
25aded6b9b Merge branch 'sabre32' of https://github.com/redmatrix/hubzilla into sabre32 2016-06-03 11:04:16 +02:00
Mario Vavti
8d6c2b5d4a Merge branch 'dev' into sabre32 2016-06-03 11:03:44 +02:00
Mario Vavti
7582802f03 Merge branch 'dev' into sabre32 2016-06-03 09:40:37 +02:00
Mario Vavti
f23bdde464 Merge branch 'dev' into sabre32 2016-06-02 11:02:15 +02:00
Mario Vavti
b4eb9f2a11 Merge branch 'sabre32' of https://github.com/redmatrix/hubzilla into sabre32 2016-06-01 10:00:44 +02:00
Mario Vavti
c1039977f1 Merge branch 'dev' into sabre32 2016-06-01 09:15:56 +02:00
Mario Vavti
380f65d309 Merge branch 'dev' into sabre32 2016-05-31 11:01:24 +02:00
Mario Vavti
316fee93f7 Merge branch 'dev' into sabre32 2016-05-31 10:59:11 +02:00
Mario Vavti
1523e116b9 Merge branch 'sabre32' of https://github.com/redmatrix/hubzilla into sabre32 2016-05-30 10:12:39 +02:00
Mario Vavti
90f2959076 Merge branch 'dev' into sabre32 2016-05-30 10:10:44 +02:00
Mario Vavti
6d4adfcedc Merge branch 'dev' into sabre32 2016-05-30 10:08:13 +02:00
Mario Vavti
cac6cef495 use composer to install sabre32 2016-05-29 10:58:11 +02:00
Mario Vavti
aab9766c53 missed some files 2016-05-29 00:33:28 +02:00
Mario Vavti
66effbfe08 upgrade to sabre32 2016-05-28 17:46:24 +02:00
535 changed files with 82429 additions and 51348 deletions

View File

@@ -1,3 +1,44 @@
Hubzilla 1.10
Wiki:
Lots of enhanced functionality, usability improvements, and bugfixes from v1.8
Turned into an optional feature (default on) but disabled in UNO
Sync:
Items are now relocated (links patched) when syncing to clones
Access Tokens:
New feature - allows members to create access controlled guest logins and create/share 'dropbox' style links to protected resources.
UI:
Use icons instead of iconic text constructs
Only request geolocation permission when creating a post, not on page load
provide 'redeliver' option on Delivery Report page for when things really stuff up
CalDAV/CardDAV management pages with heaps of functionality
Lib:
z_fetch_url() updated to accept different request methods and request bodies
item_store(), item_store_update() now return the stored items
vcard microformat changes to remain spec compliant
microformat meta tags added to post/comments
AbConfig API changed to use channel_id rather than channel_hash, which was overly complicated to use
SuperCurl class added to provide a framework for re-use of obscure CURL options
Allow absolute links to CSS/JS files on CDN
Add Let'sEncrypt intermediate cert to lib in case you forget to install it on the server
Update fullcalendar and jquery (3.1) libs
Update sabre/dav to 3.2.0
Change content export from a month/year system to begin/end
Use streaming I/O for delivering large photos
Allow multiple App description files in a single plugin directory
optimise a couple of troublesome/inefficient SQL queries
avoid sending clone sync packets to dead sites
Resolved Issues:
channel home page not providing content to clients with javascript disabled
Replace '@' obfuscation with html entity rather than the unicode look-alike
xchan_query() failing to detect duplicates, resulting in inefficient queries
issues with 'use existing photo' for profile photo
layout editor "list all layouts" returned empty
oembed - better detect video file URLs so they aren't loaded into memory.
handcrafted bbcode tables could end up with way too much whitespace due to CRLF translation
refresh permissions whitescreen in 1.8
force immediate profile photo update on local site
regression: 'save bookmarks' post action missing
Hubzilla 1.8
Administration:
Cleanup and resolve some edge cases with addon repository manager

View File

@@ -47,4 +47,16 @@ Possible website applications include
<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.
[![Build Status](https://travis-ci.org/redmatrix/hubzilla.svg)](https://travis-ci.org/redmatrix/hubzilla)

View File

@@ -41,7 +41,6 @@ class Cron {
require_once('include/sharedwithme.php');
apply_updates();
// expire any expired mail
q("delete from mail where expires != '%s' and expires < %s ",
@@ -63,6 +62,15 @@ class Cron {
}
// delete expired access tokens
q("delete from atoken where atoken_expires != '%s' && atoken_expires < %s",
dbesc(NULL_DATE),
db_utcnow()
);
// Ensure that every channel pings a directory server once a month. This way we can discover
// channels and sites that quietly vanished and prevent the directory from accumulating stale
// or dead entries.
@@ -93,6 +101,18 @@ class Cron {
intval($rr['id'])
);
if($x) {
$z = q("select * from item where id = %d",
intval($message_id)
);
if($z) {
xchan_query($z);
$sync_item = fetch_post_tags($z);
build_sync_packet($sync_item[0]['uid'],
[
'item' => [ encode_item($sync_item[0],true) ]
]
);
}
Master::Summon(array('Notifier','wall-new',$rr['id']));
}
}

View File

@@ -15,7 +15,6 @@ class Cron_weekly {
call_hooks('cron_weekly',datetime_convert());
z_check_cert();
require_once('include/hubloc.php');

View File

@@ -0,0 +1,55 @@
<?php
namespace Zotlabs\Daemon;
// generate a curl compatible cookie file with an authenticated session for the given channel_id.
// If this file is then used with curl and the destination url is sent through zid() or manually
// manipulated to add a zid, it should allow curl to provide zot magic-auth across domains.
// Handles expiration of stale cookies currently by deleting them and rewriting the file.
class CurlAuth {
static public function run($argc,$argv) {
if($argc != 2)
killme();
\App::$session->start();
$_SESSION['authenticated'] = 1;
$_SESSION['uid'] = $argv[1];
$x = session_id();
$f = 'store/[data]/cookie_' . $argv[1];
$c = 'store/[data]/cookien_' . $argv[1];
$e = file_exists($f);
$output = '';
if($e) {
$lines = file($f);
if($lines) {
foreach($lines as $line) {
if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) {
$tokens = explode("\t", $line);
$tokens = array_map('trim', $tokens);
if($tokens[4] > time()) {
$output .= $line . "\n";
}
}
else
$output .= $line;
}
}
}
$t = time() + (24 * 3600);
file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
file_put_contents($c,$x);
killme();
}
}

View File

@@ -38,7 +38,7 @@ class Expire {
logger('site_expire: ' . $site_expire);
$r = q("SELECT channel_id, channel_address, channel_pageflags, channel_expire_days from channel where true");
$r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true");
if ($r) {
foreach ($r as $rr) {

43
Zotlabs/Daemon/README.md Normal file
View File

@@ -0,0 +1,43 @@
Daemon (background) Processes
=============================
This directory provides background tasks which are executed by a
command-line process and detached from normal web processing.
Background tasks are invoked by calling
Zotlabs\Daemon\Master::Summon([ $cmd, $arg1, $argn... ]);
The Master class loads the desired command file and passes the arguments.
To create a background task 'Foo' use the following template.
<?php
namespace Zotlabs\Daemon;
class Foo {
static public function run($argc,$argv) {
// do something
}
}
The Master class "summons" the command by creating an executable script
from the provided arguments, then it invokes "Release" to execute the script
detached from web processing. This process calls the static::run() function
with any command line arguments using the traditional argc, argv format.
Please note: These are *real* $argc, $argv variables passed from the command
line, and not the parsed argc() and argv() functions/variables which were
obtained from parsing path components of the request URL by web processes.
Background processes do not emit displayable output except through logs. They
should also not make any assumptions about their HTML and web environment
(as they do not have a web environment), particularly with respect to global
variables such as $_SERVER, $_REQUEST, $_GET, $_POST, $_COOKIES, and $_SESSION.

View File

@@ -5,18 +5,20 @@ namespace Zotlabs\Lib;
class AbConfig {
static public function Load($chash,$xhash) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
dbesc($chash),
static public function Load($chan,$xhash,$family = '') {
if($family)
$where = sprintf(" and family = '%s' ",dbesc($family));
$r = q("select * from abconfig where chan = %d and xchan = '%s' $where",
intval($chan),
dbesc($xhash)
);
return $r;
}
static public function Get($chash,$xhash,$family,$key) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
dbesc($chash),
static public function Get($chan,$xhash,$family,$key) {
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
intval($chan),
dbesc($xhash),
dbesc($family),
dbesc($key)
@@ -28,14 +30,14 @@ class AbConfig {
}
static public function Set($chash,$xhash,$family,$key,$value) {
static public function Set($chan,$xhash,$family,$key,$value) {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(self::Get($chash,$xhash,$family,$key) === false) {
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
dbesc($chash),
if(self::Get($chan,$xhash,$family,$key) === false) {
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( %d, '%s', '%s', '%s', '%s' ) ",
intval($chan),
dbesc($xhash),
dbesc($family),
dbesc($key),
@@ -43,9 +45,9 @@ class AbConfig {
);
}
else {
$r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
$r = q("update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($dbvalue),
dbesc($chash),
dbesc($chan),
dbesc($xhash),
dbesc($family),
dbesc($key)
@@ -58,10 +60,10 @@ class AbConfig {
}
static public function Delete($chash,$xhash,$family,$key) {
static public function Delete($chan,$xhash,$family,$key) {
$r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($chash),
$r = q("delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
intval($chan),
dbesc($xhash),
dbesc($family),
dbesc($key)
@@ -70,4 +72,4 @@ class AbConfig {
return $r;
}
}
}

View File

@@ -33,8 +33,9 @@ class Apps {
$files = glob('addon/*/*.apd');
if($files) {
foreach($files as $f) {
$n = basename($f,'.apd');
if(plugin_is_installed($n)) {
$path = explode('/',$f);
$plugin = $path[1];
if(plugin_is_installed($plugin)) {
$x = self::parse_app_description($f,$translate);
if($x) {
$ret[] = $x;

46
Zotlabs/Lib/Cache.php Normal file
View File

@@ -0,0 +1,46 @@
<?php /** @file */
namespace Zotlabs\Lib;
/**
* cache api
*/
class Cache {
public static function get($key) {
$r = q("SELECT v FROM cache WHERE k = '%s' limit 1",
dbesc($key)
);
if ($r)
return $r[0]['v'];
return null;
}
public static function set($key,$value) {
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
dbesc($key)
);
if($r) {
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
dbesc($value),
dbesc(datetime_convert()),
dbesc($key));
}
else {
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
dbesc($key),
dbesc($value),
dbesc(datetime_convert()));
}
}
public static function clear() {
q("DELETE FROM cache WHERE updated < '%s'",
dbesc(datetime_convert('UTC','UTC',"now - 30 days")));
}
}

View File

@@ -1,6 +1,6 @@
<?php
if(class_exists('PermissionDescription')) return;
namespace Zotlabs\Lib;
require_once("include/permissions.php");
require_once("include/language.php");

127
Zotlabs/Lib/SuperCurl.php Normal file
View File

@@ -0,0 +1,127 @@
<?php
namespace Zotlabs\Lib;
/**
* @brief wrapper for z_fetch_url() which can be instantiated with several built-in parameters and
* these can be modified and re-used. Useful for CalDAV and other processes which need to authenticate
* and set lots of CURL options (many of which stay the same from one call to the next).
*/
class SuperCurl {
private $auth;
private $url;
private $curlopt = array();
private $headers = null;
public $filepos = 0;
public $filehandle = 0;
public $request_data = '';
private $request_method = 'GET';
private $upload = false;
private $cookies = false;
private function set_data($s) {
$this->request_data = $s;
$this->filepos = 0;
}
public function curl_read($ch,$fh,$size) {
if($this->filepos < 0) {
unset($fh);
return '';
}
$s = substr($this->request_data,$this->filepos,$size);
if(strlen($s) < $size)
$this->filepos = (-1);
else
$this->filepos = $this->filepos + $size;
return $s;
}
public function __construct($opts = array()) {
$this->set($opts);
}
private function set($opts = array()) {
if($opts) {
foreach($opts as $k => $v) {
switch($k) {
case 'http_auth':
$this->auth = $v;
break;
case 'magicauth':
// currently experimental
$this->magicauth = $v;
\Zotlabs\Daemon\Master::Summon([ 'CurlAuth', $v ]);
break;
case 'custom':
$this->request_method = $v;
break;
case 'url':
$this->url = $v;
break;
case 'data':
$this->set_data($v);
if($v) {
$this->upload = true;
}
else {
$this->upload = false;
}
break;
case 'headers':
$this->headers = $v;
break;
default:
$this->curlopts[$k] = $v;
break;
}
}
}
}
function exec() {
$opts = $this->curlopts;
$url = $this->url;
if($this->auth)
$opts['http_auth'] = $this->auth;
if($this->magicauth) {
$opts['cookiejar'] = 'store/[data]/cookie_' . $this->magicauth;
$opts['cookiefile'] = 'store/[data]/cookie_' . $this->magicauth;
$opts['cookie'] = 'PHPSESSID=' . trim(file_get_contents('store/[data]/cookien_' . $this->magicauth));
$c = channelx_by_n($this->magicauth);
if($c)
$url = zid($this->url,$c['channel_address'] . '@' . \App::get_hostname());
}
if($this->custom)
$opts['custom'] = $this->custom;
if($this->headers)
$opts['headers'] = $this->headers;
if($this->upload) {
$opts['upload'] = true;
$opts['infile'] = $this->filehandle;
$opts['infilesize'] = strlen($this->request_data);
$opts['readfunc'] = [ $this, 'curl_read' ] ;
}
$recurse = 0;
return z_fetch_url($this->url,true,$recurse,(($opts) ? $opts : null));
}
}

View File

@@ -248,7 +248,7 @@ class ThreadItem {
$has_bookmarks = false;
if(is_array($item['term'])) {
foreach($item['term'] as $t) {
if(!UNO && $t['type'] == TERM_BOOKMARK)
if(!UNO && $t['ttype'] == TERM_BOOKMARK)
$has_bookmarks = true;
}
}
@@ -418,7 +418,7 @@ class ThreadItem {
if(($nb_children > $visible_comments) || ($thread_level > 1)) {
$result['children'][0]['comment_firstcollapsed'] = true;
$result['children'][0]['num_comments'] = $comment_count_txt;
$result['children'][0]['hide_text'] = t('[+] show all');
$result['children'][0]['hide_text'] = sprintf( t('%s show all'), '<i class="fa fa-chevron-down"></i>');
if($thread_level > 1) {
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
}

View File

@@ -122,7 +122,7 @@ class XConfig {
);
}
App::$config[$xchan][$family][$key] = $value;
\App::$config[$xchan][$family][$key] = $value;
if($ret)
return $value;
@@ -157,4 +157,4 @@ class XConfig {
return $ret;
}
}
}

View File

@@ -18,7 +18,7 @@ class Achievements extends \Zotlabs\Web\Controller {
$profile = 0;
$profile = argv(1);
profile_load($a,$which,$profile);
profile_load($which,$profile);
$r = q("select channel_id from channel where channel_address = '%s'",
dbesc($which)

View File

@@ -1,7 +1,18 @@
<?php
namespace Zotlabs\Module;
/* ACL selector json backend */
/*
* ACL selector json backend
* This module provides JSON lists of connections and local/remote channels
* (xchans) to populate various tools such as the ACL (AccessControlList) popup
* and various auto-complete functions (such as email recipients, search, and
* mention targets.
* There are two primary output structural formats. One for the ACL widget and
* the other for auto-completion.
* Many of the behaviour variations are triggered on the use of single character keys
* however this functionality has grown in an ad-hoc manner and has gotten quite messy over time.
*/
require_once("include/acl_selectors.php");
require_once("include/group.php");
@@ -10,40 +21,63 @@ class Acl extends \Zotlabs\Web\Controller {
function init(){
// logger('mod_acl: ' . print_r($_REQUEST,true));
// logger('mod_acl: ' . print_r($_REQUEST,true));
$start = (x($_REQUEST,'start')?$_REQUEST['start']:0);
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
$search = (x($_REQUEST,'search')?$_REQUEST['search']:"");
$type = (x($_REQUEST,'type')?$_REQUEST['type']:"");
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
$start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0);
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500);
$search = (x($_REQUEST,'search') ? $_REQUEST['search'] : '');
$type = (x($_REQUEST,'type') ? $_REQUEST['type'] : '');
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
// $type =
// '' => standard ACL request
// 'g' => Groups only ACL request
// 'c' => Connections only ACL request or editor (textarea) mention request
// $_REQUEST['search'] contains ACL search text.
// $type =
// 'm' => autocomplete private mail recipient (checks post_mail permission)
// 'a' => autocomplete connections (mod_connections, mod_poke, mod_sources, mod_photos)
// 'x' => nav search bar autocomplete (match any xchan)
// $_REQUEST['query'] contains autocomplete search text.
// List of channels whose connections to also suggest, e.g. currently viewed channel or channels mentioned in a post
// List of channels whose connections to also suggest,
// e.g. currently viewed channel or channels mentioned in a post
$extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array());
// For use with jquery.autocomplete for private mail completion
// The different autocomplete libraries use different names for the search text
// parameter. Internaly we'll use $search to represent the search text no matter
// what request variable it was attached to.
if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
if(! $type)
$type = 'm';
if(array_key_exists('query',$_REQUEST)) {
$search = $_REQUEST['query'];
}
if(!(local_channel()))
if(!($type == 'x' || $type == 'c'))
killme();
if( (! local_channel()) && (! ($type == 'x' || $type == 'c')))
killme();
if ($search != "") {
if($search) {
$sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
$sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") ";
// This horrible mess is needed because position also returns 0 if nothing is found. W/ould be MUCH easier if it instead returned a very large value
// Otherwise we could just order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
$order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) ." then POSITION('".dbesc($search)."' IN xchan_name) else position('".dbesc($search)."' IN xchan_addr) end, ";
// This horrible mess is needed because position also returns 0 if nothing is found.
// Would be MUCH easier if it instead returned a very large value
// Otherwise we could just
// order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
$order_extra2 = "CASE WHEN xchan_name LIKE "
. protect_sprintf( "'%" . dbesc($search) . "%'" )
. " then POSITION('" . dbesc($search)
. "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, ";
$col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' );
$sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " ";
} else {
}
else {
$sql_extra = $sql_extra2 = $sql_extra3 = "";
}
@@ -51,7 +85,7 @@ class Acl extends \Zotlabs\Web\Controller {
$groups = array();
$contacts = array();
if ($type=='' || $type=='g'){
if($type == '' || $type == 'g') {
$r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname`
FROM `groups`,`group_member`
@@ -82,7 +116,7 @@ class Acl extends \Zotlabs\Web\Controller {
}
}
if ($type=='' || $type=='c') {
if($type == '' || $type == 'c') {
$extra_channels_sql = '';
// Only include channels who allow the observer to view their permissions
foreach($extra_channels as $channel) {
@@ -96,13 +130,40 @@ class Acl extends \Zotlabs\Web\Controller {
if(local_channel()) {
if($extra_channels_sql != '')
$extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and abook_hidden = 0 ";
$r2 = null;
$r1 = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);
if($r1) {
require_once('include/security.php');
$r2 = array();
foreach($r1 as $rr) {
$x = atoken_xchan($rr);
$r2[] = [
'id' => 'a' . $rr['atoken_id'] ,
'hash' => $x['xchan_hash'],
'name' => $x['xchan_name'],
'micro' => $x['xchan_photo_m'],
'url' => z_root(),
'nick' => $x['xchan_addr'],
'abook_their_perms' => 0,
'abook_flags' => 0,
'abook_self' => 0
];
}
}
$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, abook_flags, abook_self
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE (abook_channel = %d $extra_channels_sql) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" ,
intval(local_channel())
);
if($r2)
$r = array_merge($r2,$r);
}
else { // Visitors
$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self
@@ -161,7 +222,7 @@ class Acl extends \Zotlabs\Web\Controller {
}
elseif($type == 'm') {
$r = q("SELECT xchan_hash as id, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
$r = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0)
and xchan_deleted = 0
@@ -171,7 +232,7 @@ class Acl extends \Zotlabs\Web\Controller {
intval(PERMS_W_MAIL)
);
}
elseif(($type == 'a') || ($type == 'p')) {
elseif($type == 'a') {
$r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d
@@ -296,7 +357,7 @@ class Acl extends \Zotlabs\Web\Controller {
$url = $directory['url'] . '/dirsearch';
}
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100);
if($url) {
$query = $url . '?f=' ;
$query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : '');

View File

@@ -12,7 +12,7 @@ class Block extends \Zotlabs\Web\Controller {
$which = argv(1);
$profile = 0;
profile_load($a,$which,$profile);
profile_load($which,$profile);
if(\App::$profile['profile_uid'])
head_set_icon(\App::$profile['thumb']);
@@ -52,8 +52,8 @@ class Block extends \Zotlabs\Web\Controller {
require_once('include/security.php');
$sql_options = item_permissions_sql($u[0]['channel_id']);
$r = q("select item.* from item left join item_id on item.id = item_id.iid
where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and iconfig.k = 'BUILDBLOCK' and
item_type = %d $sql_options $revision limit 1",
intval($u[0]['channel_id']),
dbesc($page_id),
@@ -64,8 +64,8 @@ class Block extends \Zotlabs\Web\Controller {
// Check again with no permissions clause to see if it is a permissions issue
$x = q("select item.* from item left join item_id on item.id = item_id.iid
where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and iconfig.k = 'BUILDBLOCK' and
item_type = %d $revision limit 1",
intval($u[0]['channel_id']),
dbesc($page_id),

View File

@@ -22,12 +22,12 @@ class Blocks extends \Zotlabs\Web\Controller {
else
return;
profile_load($a,$which);
profile_load($which);
}
function get() {
function get() {
if(! \App::$profile) {
notice( t('Requested profile is not available.') . EOL );
@@ -111,8 +111,11 @@ class Blocks extends \Zotlabs\Web\Controller {
$editor = status_editor($a,$x);
$r = q("select iid, sid, mid, title, body, mimetype, created, edited from item_id left join item on item_id.iid = item.id
where item_id.uid = %d and service = 'BUILDBLOCK' and item_type = %d order by item.created desc",
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
left join item on iconfig.iid = item.id
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'
and item_type = %d order by item.created desc",
intval($owner),
intval(ITEM_TYPE_BLOCK)
);
@@ -129,12 +132,12 @@ class Blocks extends \Zotlabs\Web\Controller {
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'pagetitle' => $rr['sid'],
'pagetitle' => $rr['v'],
'mid' => $rr['mid']
);
$pages[$rr['iid']][] = array(
'url' => $rr['iid'],
'name' => $rr['sid'],
'name' => $rr['v'],
'title' => $rr['title'],
'created' => $rr['created'],
'edited' => $rr['edited'],

View File

@@ -20,7 +20,7 @@ class Cal extends \Zotlabs\Web\Controller {
if(argc() > 1) {
$nick = argv(1);
profile_load($a,$nick);
profile_load($nick);
$channelx = channelx_by_nick($nick);

View File

@@ -9,7 +9,6 @@ require_once('include/security.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/permissions.php');
require_once('include/PermissionDescription.php');
class Channel extends \Zotlabs\Web\Controller {
@@ -48,7 +47,7 @@ class Channel extends \Zotlabs\Web\Controller {
// Run profile_load() here to make sure the theme is set before
// we start loading content
profile_load($a,$which,$profile);
profile_load($which,$profile);
}
@@ -133,7 +132,7 @@ class Channel extends \Zotlabs\Web\Controller {
'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
'nickname' => \App::$profile['channel_address'],
'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
'acl' => (($is_owner) ? populate_acl($channel_acl,true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
'acl' => (($is_owner) ? populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''),
'showacl' => (($is_owner) ? 'yes' : ''),
'bang' => '',
'visitor' => (($is_owner || $observer) ? true : false),

View File

@@ -39,7 +39,7 @@ class Chat extends \Zotlabs\Web\Controller {
// Run profile_load() here to make sure the theme is set before
// we start loading content
profile_load($a,$which,$profile);
profile_load($which,$profile);
}

View File

@@ -13,6 +13,9 @@ use \Zotlabs\Storage;
// composer autoloader for SabreDAV
require_once('vendor/autoload.php');
require_once('include/attach.php');
/**
* @brief Fires up the SabreDAV server.
*
@@ -23,7 +26,6 @@ require_once('vendor/autoload.php');
class Cloud extends \Zotlabs\Web\Controller {
function init() {
require_once('include/reddav.php');
if (! is_dir('store'))
os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false);
@@ -37,7 +39,7 @@ class Cloud extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
if ($which)
profile_load($a, $which, $profile);
profile_load( $which, $profile);
$auth = new \Zotlabs\Storage\BasicAuth();
@@ -79,17 +81,6 @@ class Cloud extends \Zotlabs\Web\Controller {
$is_readable = false;
if($_SERVER['REQUEST_METHOD'] === 'GET') {
try {
$x = RedFileData('/' . \App::$cmd, $auth);
}
catch(\Exception $e) {
if($e instanceof Sabre\DAV\Exception\Forbidden) {
http_status_exit(401, 'Permission denied.');
}
}
}
// provide a directory view for the cloud in Hubzilla
$browser = new \Zotlabs\Storage\Browser($auth);
$auth->setBrowserPlugin($browser);

View File

@@ -21,7 +21,7 @@ class Common extends \Zotlabs\Web\Controller {
);
if($x)
profile_load($a,$x[0]['channel_address'],0);
profile_load($x[0]['channel_address'],0);
}

View File

@@ -26,7 +26,7 @@ class Connect extends \Zotlabs\Web\Controller {
if($r)
\App::$data['channel'] = $r[0];
profile_load($a,$which,'');
profile_load($which,'');
}
function post() {

View File

@@ -16,14 +16,14 @@ require_once('include/zot.php');
require_once('include/widgets.php');
require_once('include/photos.php');
/* @brief Initialize the connection-editor
*
*
*/
class Connedit extends \Zotlabs\Web\Controller {
/* @brief Initialize the connection-editor
*
*
*/
function init() {
if(! local_channel())
@@ -51,7 +51,7 @@ class Connedit extends \Zotlabs\Web\Controller {
*
*/
function post() {
function post() {
if(! local_channel())
return;
@@ -219,7 +219,7 @@ class Connedit extends \Zotlabs\Web\Controller {
//Update profile photo permissions
logger('A new profile was assigned - updating profile photos');
profile_photo_set_profile_perms($profile_id);
profile_photo_set_profile_perms(local_channel(),$profile_id);
}
@@ -345,7 +345,7 @@ class Connedit extends \Zotlabs\Web\Controller {
unset($clone['abook_account']);
unset($clone['abook_channel']);
$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if($abconfig)
$clone['abconfig'] = $abconfig;
@@ -357,7 +357,7 @@ class Connedit extends \Zotlabs\Web\Controller {
*
*/
function get() {
function get() {
$sort_type = 0;
$o = '';
@@ -418,7 +418,13 @@ class Connedit extends \Zotlabs\Web\Controller {
goaway(z_root() . '/connedit/' . $contact_id);
}
if($cmd === 'resetphoto') {
q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s' limit 1",
dbesc($orig_record[0]['xchan_hash'])
);
$cmd = 'refresh';
}
if($cmd === 'refresh') {
if($orig_record[0]['xchan_network'] === 'zot') {
if(! zot_refresh($orig_record[0],\App::get_channel()))
@@ -427,7 +433,7 @@ class Connedit extends \Zotlabs\Web\Controller {
else {
// if you are on a different network we'll force a refresh of the connection basic info
Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
\Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
}
goaway(z_root() . '/connedit/' . $contact_id);
}

View File

@@ -29,7 +29,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
}
$channel = \App::get_channel();
profile_load($a,$channel['channel_address']);
profile_load($channel['channel_address']);
}
@@ -40,7 +40,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
*
*/
function post() {
function post() {
if(! local_channel()) {
return;
@@ -50,7 +50,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) {
if((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) {
// phase 2 - we have finished cropping
@@ -271,7 +271,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
*/
function get() {
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL );

View File

@@ -14,6 +14,7 @@ use \Zotlabs\Storage;
// composer autoloader for SabreDAV
require_once('vendor/autoload.php');
require_once('include/attach.php');
/**
* @brief Fires up the SabreDAV server.
@@ -44,60 +45,16 @@ class Dav extends \Zotlabs\Web\Controller {
}
}
require_once('include/reddav.php');
if (! is_dir('store'))
os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false);
$which = null;
if (argc() > 1)
$which = argv(1);
profile_load(argv(1),0);
$profile = 0;
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
if ($which)
profile_load($a, $which, $profile);
$auth = new \Zotlabs\Storage\BasicAuth();
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . 'WebDAV');
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . ' ' . 'WebDAV');
// $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function($userName,$password) {
// if(account_verify_password($userName,$password))
// return true;
// return false;
// });
// $ob_hash = get_observer_hash();
// if ($ob_hash) {
// if (local_channel()) {
// $channel = \App::get_channel();
// $auth->setCurrentUser($channel['channel_address']);
// $auth->channel_id = $channel['channel_id'];
// $auth->channel_hash = $channel['channel_hash'];
// $auth->channel_account_id = $channel['channel_account_id'];
// if($channel['channel_timezone'])
// $auth->setTimezone($channel['channel_timezone']);
// }
// $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']);
// $_SERVER['QUERY_STRING'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['QUERY_STRING']);
//
// $_SERVER['REQUEST_URI'] = str_replace(array('?f=', '&f='), array('', ''), $_SERVER['REQUEST_URI']);
// $_SERVER['REQUEST_URI'] = strip_zids($_SERVER['REQUEST_URI']);
// $_SERVER['REQUEST_URI'] = preg_replace('/[\?&]davguest=(.*?)([\?&]|$)/ism', '', $_SERVER['REQUEST_URI']);
$rootDirectory = new \Zotlabs\Storage\Directory('/', $auth);
// A SabreDAV server-object
@@ -114,48 +71,13 @@ class Dav extends \Zotlabs\Web\Controller {
$server->addPlugin($lockPlugin);
// The next section of code allows us to bypass prompting for http-auth if a
// FILE is being accessed anonymously and permissions allow this. This way
// one can create hotlinks to public media files in their cloud and anonymous
// viewers won't get asked to login.
// If a DIRECTORY is accessed or there are permission issues accessing the
// file and we aren't previously authenticated via zot, prompt for HTTP-auth.
// This will be the default case for mounting a DAV directory.
// In order to avoid prompting for passwords for viewing a DIRECTORY, add
// the URL query parameter 'davguest=1'.
// $isapublic_file = false;
// $davguest = ((x($_SESSION, 'davguest')) ? true : false);
// if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) {
// try {
// $x = RedFileData('/' . \App::$cmd, $auth);
// if($x instanceof \Zotlabs\Storage\File)
// $isapublic_file = true;
// }
// catch (Exception $e) {
// $isapublic_file = false;
// }
// }
// if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) {
// try {
// $auth->Authenticate($server, t('$Projectname channel'));
// }
// catch (Exception $e) {
// logger('mod_cloud: auth exception' . $e->getMessage());
// http_status_exit($e->getHTTPCode(), $e->getMessage());
// }
// }
// require_once('Zotlabs/Storage/Browser.php');
// provide a directory view for the cloud in Hubzilla
$browser = new \Zotlabs\Storage\Browser($auth);
$auth->setBrowserPlugin($browser);
// Experimental QuotaPlugin
// require_once('Zotlabs/Storage/QuotaPlugin.php');
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
// require_once('Zotlabs/Storage/QuotaPlugin.php');
// $server->addPlugin(new \Zotlabs\Storage\QuotaPlugin($auth));
// All we need to do now, is to fire up the server
$server->exec();

View File

@@ -106,12 +106,13 @@ class Display extends \Zotlabs\Web\Controller {
$x = q("select * from channel where channel_id = %d limit 1",
intval($target_item['uid'])
);
$y = q("select * from item_id where uid = %d and service = 'WEBPAGE' and iid = %d limit 1",
$y = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1",
intval($target_item['uid']),
intval($target_item['id'])
);
if($x && $y) {
goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['sid']);
goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
}
else {
notice( t('Page not found.') . EOL);

View File

@@ -16,7 +16,24 @@ class Dreport extends \Zotlabs\Web\Controller {
$channel = \App::get_channel();
$mid = ((argc() > 1) ? argv(1) : '');
if($mid === 'push') {
$table = 'push';
$mid = ((argc() > 2) ? argv(2) : '');
if($mid) {
$i = q("select id from item where mid = '%s' and author_xchan = '%s' and uid = %d",
dbesc($mid),
dbesc($channel['channel_hash']),
intval($channel['channel_id'])
);
if($i) {
\Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]);
}
}
sleep(3);
goaway(z_root() . '/dreport/' . urlencode($mid));
}
if($mid === 'mail') {
$table = 'mail';
$mid = ((argc() > 2) ? argv(2) : '');
@@ -59,11 +76,7 @@ class Dreport extends \Zotlabs\Web\Controller {
notice( t('no results') . EOL);
return;
}
$o .= '<div class="generic-content-wrapper-styled">';
$o .= '<h2>' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '</h2>';
$o .= '<table>';
for($x = 0; $x < count($r); $x++ ) {
$r[$x]['name'] = escape_tags(substr($r[$x]['dreport_recip'],strpos($r[$x]['dreport_recip'],' ')));
@@ -119,13 +132,25 @@ class Dreport extends \Zotlabs\Web\Controller {
}
usort($r,'self::dreport_gravity_sort');
$entries = array();
foreach($r as $rr) {
$o .= '<tr><td width="40%">' . $rr['name'] . '</td><td width="20%">' . escape_tags($rr['dreport_result']) . '</td><td width="20%">' . escape_tags($rr['dreport_time']) . '</td></tr>';
$entries[] = [
'name' => $rr['name'],
'result' => escape_tags($rr['dreport_result']),
'time' => escape_tags(datetime_convert('UTC',date_default_timezone_get(),$rr['dreport_time']))
];
}
$o .= '</table>';
$o .= '</div>';
$o = replace_macros(get_markup_template('dreport.tpl'), array(
'$title' => sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...',
'$table' => $table,
'$mid' => urlencode($mid),
'$options' => t('Options'),
'$push' => t('Redeliver'),
'$entries' => $entries
));
return $o;

View File

@@ -21,7 +21,7 @@ class Editblock extends \Zotlabs\Web\Controller {
else
return;
profile_load($a,$which);
profile_load($which);
}
@@ -85,11 +85,11 @@ class Editblock extends \Zotlabs\Web\Controller {
intval($owner)
);
if($itm) {
$item_id = q("select * from item_id where service = 'BUILDBLOCK' and iid = %d limit 1",
$item_id = q("select * from iconfig where cat = 'system' and k = 'BUILDBLOCK' and iid = %d limit 1",
intval($itm[0]['id'])
);
if($item_id)
$block_title = $item_id[0]['sid'];
$block_title = $item_id[0]['v'];
}
else {
notice( t('Item not found') . EOL);

View File

@@ -21,7 +21,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
else
return;
profile_load($a,$which);
profile_load($which);
}
@@ -96,11 +96,12 @@ class Editlayout extends \Zotlabs\Web\Controller {
intval($owner)
);
$item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1",
$item_id = q("select * from iconfig where cat = 'system' and k = 'PDL' and iid = %d limit 1",
intval($itm[0]['id'])
);
if($item_id)
$layout_title = $item_id[0]['sid'];
$layout_title = $item_id[0]['v'];
$rp = 'layouts/' . $which;

View File

@@ -4,7 +4,6 @@ namespace Zotlabs\Module;
require_once('include/channel.php');
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
require_once('include/PermissionDescription.php');
class Editwebpage extends \Zotlabs\Web\Controller {
@@ -23,7 +22,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
else
return;
profile_load($a,$which);
profile_load($which);
}
@@ -114,11 +113,11 @@ class Editwebpage extends \Zotlabs\Web\Controller {
$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
}
$item_id = q("select * from item_id where service = 'WEBPAGE' and iid = %d limit 1",
$item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1",
intval($itm[0]['id'])
);
if($item_id)
$page_title = $item_id[0]['sid'];
$page_title = $item_id[0]['v'];
$mimetype = $itm[0]['mimetype'];
@@ -151,7 +150,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
'body' => undo_post_tagging($itm[0]['body']),
'post_id' => $post_id,
'visitor' => ($is_owner) ? true : false,
'acl' => populate_acl($itm[0],false,\PermissionDescription::fromGlobalPermission('view_pages')),
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
'showacl' => ($is_owner) ? true : false,
'mimetype' => $mimetype,
'mimeselect' => true,

View File

@@ -0,0 +1,180 @@
<?php
namespace Zotlabs\Module;
/**
*
* This is the POST destination for the embedphotos button
*
*/
class Embedphotos extends \Zotlabs\Web\Controller {
function get() {
}
function post() {
if (argc() > 1 && argv(1) === 'album') {
// API: /embedphotos/album
$name = (x($_POST,'name') ? $_POST['name'] : null );
if (!$name) {
json_return_and_die(array('errormsg' => 'Error retrieving album', 'status' => false));
}
$album = $this->embedphotos_widget_album(array('channel' => \App::get_channel(), 'album' => $name));
json_return_and_die(array('status' => true, 'content' => $album));
}
if (argc() > 1 && argv(1) === 'albumlist') {
// API: /embedphotos/albumlist
$album_list = $this->embedphotos_album_list($a);
json_return_and_die(array('status' => true, 'albumlist' => $album_list));
}
if (argc() > 1 && argv(1) === 'photolink') {
// API: /embedphotos/photolink
$href = (x($_POST,'href') ? $_POST['href'] : null );
if (!$href) {
json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false));
}
$resource_id = array_pop(explode("/", $href));
$r = q("SELECT obj from item where resource_type = 'photo' and resource_id = '%s' limit 1",
dbesc($resource_id)
);
if(!$r) {
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
}
$obj = json_decode($r[0]['obj'], true);
if(x($obj,'body')) {
$photolink = $obj['body'];
} elseif (x($obj,'bbcode')) {
$photolink = $obj['bbcode'];
} else {
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
}
json_return_and_die(array('status' => true, 'photolink' => $photolink));
}
}
/**
* Copied from include/widgets.php::widget_album() with a modification to get the profile_uid from
* the input array as in widget_item()
* @param type $name
* @return string
*/
function embedphotos_widget_album($args) {
$channel_id = 0;
if(array_key_exists('channel',$args))
$channel = $args['channel'];
$channel_id = intval($channel['channel_id']);
if(! $channel_id)
$channel_id = \App::$profile_uid;
if(! $channel_id)
return '';
$owner_uid = $channel_id;
require_once('include/security.php');
$sql_extra = permissions_sql($channel_id);
if(! perm_is_allowed($channel_id,get_observer_hash(),'view_storage'))
return '';
if($args['album'])
$album = $args['album'];
if($args['title'])
$title = $args['title'];
/**
* This may return incorrect permissions if you have multiple directories of the same name.
* It is a limitation of the photo table using a name for a photo album instead of a folder hash
*/
if($album) {
$x = q("select hash from attach where filename = '%s' and uid = %d limit 1",
dbesc($album),
intval($owner_uid)
);
if($x) {
$y = attach_can_view_folder($owner_uid,get_observer_hash(),$x[0]['hash']);
if(! $y)
return '';
}
}
$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 ) $sql_extra GROUP BY resource_id) ph
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
ORDER BY created $order",
intval($owner_uid),
dbesc($album),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE)
);
$photos = array();
if(count($r)) {
$twist = 'rotright';
foreach($r as $rr) {
if($twist == 'rotright')
$twist = 'rotleft';
else
$twist = 'rotright';
$ext = $phototypes[$rr['mimetype']];
$imgalt_e = $rr['filename'];
$desc_e = $rr['description'];
$imagelink = (z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id']
. (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''));
$photos[] = array(
'id' => $rr['id'],
'twist' => ' ' . $twist . rand(2,4),
'link' => $imagelink,
'title' => t('View Photo'),
'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext,
'alt' => $imgalt_e,
'desc'=> $desc_e,
'ext' => $ext,
'hash'=> $rr['resource_id'],
'unknown' => t('Unknown')
);
}
}
$tpl = get_markup_template('photo_album.tpl');
$o .= replace_macros($tpl, array(
'$photos' => $photos,
'$album' => (($title) ? $title : $album),
'$album_id' => rand(),
'$album_edit' => array(t('Edit Album'), $album_edit),
'$can_post' => false,
'$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)),
'$order' => false,
'$upload_form' => $upload_form,
'$no_fullscreen_btn' => true
));
return $o;
}
function embedphotos_album_list($a) {
$o = '';
require_once('include/photos.php');
$p = photos_albums_list(\App::get_channel(), \App::get_observer());
if ($p['success']) {
return $p['albums'];
} else {
return null;
}
}
}

View File

@@ -6,7 +6,6 @@ require_once('include/bbcode.php');
require_once('include/datetime.php');
require_once('include/event.php');
require_once('include/items.php');
require_once('include/PermissionDescription.php');
class Events extends \Zotlabs\Web\Controller {
@@ -471,7 +470,7 @@ class Events extends \Zotlabs\Web\Controller {
'$permissions' => t('Permission settings'),
// populating the acl dialog was a permission description from view_stream because Cal.php, which
// displays events, says "since we don't currently have an event permission - use the stream permission"
'$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \PermissionDescription::fromGlobalPermission('view_stream'))),
'$acl' => (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'))),
'$submit' => t('Submit'),
'$advanced' => t('Advanced Options')
@@ -668,8 +667,10 @@ class Events extends \Zotlabs\Web\Controller {
'$export' => array(z_root()."/events/$y/$m/export",t('Export'),'',''),
'$calendar' => cal($y,$m,$links, ' eventcal'),
'$events' => $events,
'$upload' => t('Import'),
'$submit' => t('Submit'),
'$view_label' => t('View'),
'$month' => t('Month'),
'$week' => t('Week'),
'$day' => t('Day'),
'$prev' => t('Previous'),
'$next' => t('Next'),
'$today' => t('Today'),

View File

@@ -6,7 +6,6 @@ namespace Zotlabs\Module;
*/
require_once('include/attach.php');
require_once('include/PermissionDescription.php');
/**
@@ -134,7 +133,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
$cloudpath = get_cloudpath($f) . (intval($f['is_dir']) ? '?f=&davguest=1' : '');
$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
$aclselect_e = populate_acl($f, false, \PermissionDescription::fromGlobalPermission('view_storage'));
$aclselect_e = populate_acl($f, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage'));
$is_a_dir = (intval($f['is_dir']) ? true : false);
$lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock');

View File

@@ -43,7 +43,7 @@ class Follow extends \Zotlabs\Web\Controller {
unset($clone['abook_account']);
unset($clone['abook_channel']);
$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if($abconfig)
$clone['abconfig'] = $abconfig;

View File

@@ -40,7 +40,7 @@ class Hcard extends \Zotlabs\Web\Controller {
}
}
profile_load($a,$which,$profile);
profile_load($which,$profile);
}

View File

@@ -28,6 +28,19 @@ class Home extends \Zotlabs\Web\Controller {
goaway($dest);
}
if(remote_channel() && (! $splash) && $_SESSION['atoken']) {
$r = q("select * from atoken where atoken_id = %d",
intval($_SESSION['atoken'])
);
if($r) {
$x = channelx_by_n($r[0]['atoken_uid']);
if($x) {
goaway(z_root() . '/channel/' . $x['channel_address']);
}
}
}
if(get_account_id() && ! $splash) {
goaway(z_root() . '/new_channel');

View File

@@ -57,7 +57,7 @@ class Id extends \Zotlabs\Web\Controller {
$profile = '';
$channel = \App::get_channel();
profile_load($a,$which,$profile);
profile_load($which,$profile);
$op = new MysqlProvider;
$op->server();

View File

@@ -137,9 +137,7 @@ class Impel extends \Zotlabs\Web\Controller {
require_once('library/urlify/URLify.php');
$pagetitle = strtolower(\URLify::transliterate($j['pagetitle']));
}
// Verify ability to use html or php!!!
$execflag = false;
@@ -154,21 +152,14 @@ class Impel extends \Zotlabs\Web\Controller {
}
}
$remote_id = 0;
$z = q("select * from item_id where sid = '%s' and service = '%s' and uid = %d limit 1",
dbesc($pagetitle),
dbesc($namespace),
intval(local_channel())
);
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
intval(local_channel())
);
\Zotlabs\Lib\IConfig::Set($arr,'system',$namespace,(($pagetitle) ? $pagetitle : substr($arr['mid'],0,16)),true);
if($z && $i) {
$remote_id = $z[0]['id'];
if($i) {
$arr['id'] = $i[0]['id'];
// don't update if it has the same timestamp as the original
if($arr['edited'] > $i[0]['edited'])
@@ -182,12 +173,12 @@ class Impel extends \Zotlabs\Web\Controller {
intval(local_channel())
);
}
$x = item_store($arr,$execflag);
else
$x = item_store($arr,$execflag);
}
if($x['success']) {
if($x && $x['success']) {
$item_id = $x['item_id'];
update_remote_id($channel,$item_id,$arr['item_type'],$pagetitle,$namespace,$remote_id,$arr['mid']);
}
}
@@ -199,7 +190,8 @@ class Impel extends \Zotlabs\Web\Controller {
notice( sprintf( t('%s element installation failed'), $installed_type));
}
//??? should perhaps return ret?
//??? should perhaps return ret?
json_return_and_die(true);
}

View File

@@ -131,6 +131,8 @@ class Import extends \Zotlabs\Web\Controller {
// import channel
$relocate = ((array_key_exists('relocate',$data)) ? $data['relocate'] : null);
if(array_key_exists('channel',$data)) {
if($completed < 1) {
@@ -387,8 +389,7 @@ class Import extends \Zotlabs\Web\Controller {
if($abconfig) {
// @fixme does not handle sync of del_abconfig
foreach($abconfig as $abc) {
if($abc['chan'] === $channel['channel_hash'])
set_abconfig($abc['chan'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
}
}
@@ -475,7 +476,7 @@ class Import extends \Zotlabs\Web\Controller {
import_events($channel,$data['event']);
if(is_array($data['event_item']))
import_items($channel,$data['event_item']);
import_items($channel,$data['event_item'],false,$relocate);
if(is_array($data['menu']))
import_menus($channel,$data['menu']);
@@ -486,7 +487,7 @@ class Import extends \Zotlabs\Web\Controller {
$saved_notification_flags = notifications_off($channel['channel_id']);
if($import_posts && array_key_exists('item',$data) && $data['item'])
import_items($channel,$data['item']);
import_items($channel,$data['item'],false,$relocate);
notifications_on($channel['channel_id'],$saved_notification_flags);

View File

@@ -78,6 +78,8 @@ class Import_items extends \Zotlabs\Web\Controller {
// logger('import: data: ' . print_r($data,true));
// print_r($data);
if(! is_array($data))
return;
if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) {
$v1 = substr($data['compatibility']['database'],-4);
@@ -92,7 +94,7 @@ class Import_items extends \Zotlabs\Web\Controller {
if(array_key_exists('item',$data) && $data['item']) {
import_items($channel,$data['item']);
import_items($channel,$data['item'],false,((array_key_exists('relocate',$data)) ? $data['relocate'] : null));
}
if(array_key_exists('item_id',$data) && $data['item_id']) {
@@ -106,7 +108,7 @@ class Import_items extends \Zotlabs\Web\Controller {
function get() {
function get() {
if(! local_channel()) {
notice( t('Permission denied') . EOL);

View File

@@ -1,4 +1,5 @@
<?php
namespace Zotlabs\Module;
/**
@@ -92,7 +93,7 @@ class Item extends \Zotlabs\Web\Controller {
$origin = (($api_source && array_key_exists('origin',$_REQUEST)) ? intval($_REQUEST['origin']) : 1);
// To represent message-ids on other networks - this will create an item_id record
// To represent message-ids on other networks - this will create an iconfig record
$namespace = (($api_source && array_key_exists('namespace',$_REQUEST)) ? strip_tags($_REQUEST['namespace']) : '');
$remote_id = (($api_source && array_key_exists('remote_id',$_REQUEST)) ? strip_tags($_REQUEST['remote_id']) : '');
@@ -182,7 +183,9 @@ class Item extends \Zotlabs\Web\Controller {
}
// can_comment_on_post() needs info from the following xchan_query
xchan_query($r);
// This may be from the discover tab which means we need to correct the effective uid
xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel()));
$parent_item = $r[0];
$parent = $r[0]['id'];
@@ -229,7 +232,7 @@ class Item extends \Zotlabs\Web\Controller {
if($namespace && $remote_id) {
// It wasn't an internally generated post - see if we've got an item matching this remote service id
$i = q("select iid from item_id where service = '%s' and sid = '%s' limit 1",
$i = q("select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1",
dbesc($namespace),
dbesc($remote_id)
);
@@ -534,7 +537,7 @@ class Item extends \Zotlabs\Web\Controller {
}
/**
* fix naked links by passing through a callback to see if this is a red site
* 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.
*/
@@ -833,21 +836,23 @@ class Item extends \Zotlabs\Web\Controller {
if($orig_post)
$datarray['edit'] = true;
// suppress duplicates, *unless* you're editing an existing post. This could get picked up
// as a duplicate if you're editing it very soon after posting it initially and you edited
// some attribute besides the content, such as title or categories.
if(feature_enabled($profile_uid,'suppress_duplicates') && (! $orig_post)) {
$z = q("select created from item where uid = %d and body = '%s'",
$z = q("select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1",
intval($profile_uid),
db_utcnow(),
db_quoteinterval('2 MINUTE'),
dbesc($body)
);
if($z) {
foreach($z as $zz) {
if($zz['created'] > datetime_convert('UTC','UTC', 'now - 2 minutes')) {
$datarray['cancel'] = 1;
notice( t('Duplicate post suppressed.') . EOL);
logger('Duplicate post. Faking plugin cancel.');
}
}
$datarray['cancel'] = 1;
notice( t('Duplicate post suppressed.') . EOL);
logger('Duplicate post. Faking plugin cancel.');
}
}
@@ -880,13 +885,21 @@ class Item extends \Zotlabs\Web\Controller {
}
}
if($webpage) {
Zlib\IConfig::Set($datarray,'system', webpage_to_namespace($webpage),
(($pagetitle) ? $pagetitle : substr($datarray['mid'],0,16)),true);
}
elseif($namespace) {
Zlib\IConfig::Set($datarray,'system', $namespace,
(($remote_id) ? $remote_id : substr($datarray['mid'],0,16)),true);
}
if($orig_post) {
$datarray['id'] = $post_id;
item_store_update($datarray,$execflag);
update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid);
$x = item_store_update($datarray,$execflag);
if(! $parent) {
$r = q("select * from item where id = %d",
intval($post_id)
@@ -894,10 +907,7 @@ class Item extends \Zotlabs\Web\Controller {
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
$rid = q("select * from item_id where iid = %d",
intval($post_id)
);
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid));
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
}
}
if(! $nopush)
@@ -978,10 +988,7 @@ class Item extends \Zotlabs\Web\Controller {
goaway(z_root() . "/" . $return_path );
// NOTREACHED
}
update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid);
if(($parent) && ($parent != $post_id)) {
// Store the comment signature information in case we need to relay to Diaspora
//$ditem = $datarray;
@@ -995,10 +1002,7 @@ class Item extends \Zotlabs\Web\Controller {
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
$rid = q("select * from item_id where iid = %d",
intval($post_id)
);
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid));
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
}
}
@@ -1012,11 +1016,6 @@ class Item extends \Zotlabs\Web\Controller {
logger('post_complete');
// figure out how to return, depending on from whence we came
if($api_source)

View File

@@ -21,7 +21,7 @@ class Layouts extends \Zotlabs\Web\Controller {
else
return;
profile_load($a,$which);
profile_load($which);
}
@@ -90,13 +90,14 @@ class Layouts extends \Zotlabs\Web\Controller {
return;
}
//This feature is not exposed in redbasic ui since it is not clear why one would want to
//download a json encoded pdl file - we dont have a possibility to import it.
//Use the buildin share/install feature instead.
// This feature is not exposed in redbasic ui since it is not clear why one would want to
// download a json encoded pdl file - we dont have a possibility to import it.
// Use the buildin share/install feature instead.
if((argc() > 3) && (argv(2) === 'share') && (argv(3))) {
$r = q("select sid, service, mimetype, title, body from item_id
left join item on item.id = item_id.iid
where item_id.uid = %d and item.mid = '%s' and service = 'PDL' order by sid asc",
$r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig
left join item on item.id = iconfig.iid
where uid = %d and mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc",
intval($owner),
dbesc(argv(3))
);
@@ -141,8 +142,9 @@ class Layouts extends \Zotlabs\Web\Controller {
$editor = status_editor($a,$x);
$r = q("select iid, sid, mid, title, body, mimetype, created, edited, item_type from item_id left join item on item_id.iid = item.id
where item_id.uid = %d and service = 'PDL' and item_type = %d order by item.created desc",
$r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig
left join item on iconfig.iid = item.id
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d order by item.created desc",
intval($owner),
intval(ITEM_TYPE_PDL)
);
@@ -164,7 +166,7 @@ class Layouts extends \Zotlabs\Web\Controller {
);
$pages[$rr['iid']][] = array(
'url' => $rr['iid'],
'title' => $rr['sid'],
'title' => $rr['v'],
'descr' => $rr['title'],
'mid' => $rr['mid'],
'created' => $rr['created'],

View File

@@ -1,17 +1,31 @@
<?php
namespace Zotlabs\Module;
require_once('include/security.php');
class Lockview extends \Zotlabs\Web\Controller {
function get() {
$atokens = array();
if(local_channel()) {
$at = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);
if($at) {
foreach($at as $t) {
$atokens[] = atoken_xchan($t);
}
}
}
$type = ((argc() > 1) ? argv(1) : 0);
if (is_numeric($type)) {
$item_id = intval($type);
$type='item';
} else {
}
else {
$item_id = ((argc() > 2) ? intval(argv(2)) : 0);
}
@@ -98,6 +112,13 @@ class Lockview extends \Zotlabs\Web\Controller {
if($r)
foreach($r as $rr)
$l[] = '<li>' . $rr['xchan_name'] . '</li>';
if($atokens) {
foreach($atokens as $at) {
if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) {
$l[] = '<li>' . $at['xchan_name'] . '</li>';
}
}
}
}
if(count($deny_groups)) {
$r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
@@ -110,6 +131,16 @@ class Lockview extends \Zotlabs\Web\Controller {
if($r)
foreach($r as $rr)
$l[] = '<li><strike>' . $rr['xchan_name'] . '</strike></li>';
if($atokens) {
foreach($atokens as $at) {
if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) {
$l[] = '<li><strike>' . $at['xchan_name'] . '</strike></li>';
}
}
}
}
echo $o . implode($l);

View File

@@ -7,6 +7,9 @@ class Login extends \Zotlabs\Web\Controller {
function get() {
if(local_channel())
goaway(z_root());
if(remote_channel() && $_SESSION['atoken'])
goaway(z_root());
return login((\App::$config['system']['register_policy'] == REGISTER_CLOSED) ? false : true);
}

View File

@@ -6,8 +6,6 @@ require_once('include/group.php');
require_once('include/contact_widgets.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/PermissionDescription.php');
class Network extends \Zotlabs\Web\Controller {
@@ -171,7 +169,7 @@ class Network extends \Zotlabs\Web\Controller {
'default_location' => $channel['channel_location'],
'nickname' => $channel['channel_address'],
'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'bang' => (($private_editing) ? '!' : ''),
'visitor' => true,
'profile_uid' => local_channel(),

View File

@@ -62,7 +62,7 @@ class New_channel extends \Zotlabs\Web\Controller {
}
function post() {
function post() {
$arr = $_POST;
@@ -96,7 +96,7 @@ class New_channel extends \Zotlabs\Web\Controller {
}
function get() {
function get() {
$acc = \App::get_account();
@@ -125,9 +125,9 @@ class New_channel extends \Zotlabs\Web\Controller {
}
}
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'));
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*");
$nickhub = '@' . \App::get_hostname();
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub));
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*");
$privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" );
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',get_roles());

View File

@@ -48,7 +48,7 @@ class Openid extends \Zotlabs\Web\Controller {
$_SESSION['uid'] = $r[0]['channel_id'];
$_SESSION['account_id'] = $r[0]['channel_account_id'];
$_SESSION['authenticated'] = true;
authenticate_success($record,true,true,true,true);
authenticate_success($record,$r[0],true,true,true,true);
goaway(z_root());
}
}

View File

@@ -13,7 +13,7 @@ class Page extends \Zotlabs\Web\Controller {
$which = argv(1);
$profile = 0;
profile_load($a,$which,$profile);
profile_load($which,$profile);
@@ -65,9 +65,10 @@ class Page extends \Zotlabs\Web\Controller {
require_once('include/security.php');
$sql_options = item_permissions_sql($u[0]['channel_id']);
$r = q("select item.* from item left join item_id on item.id = item_id.iid
where item.uid = %d and sid = '%s' and item.item_delayed = 0 and (( service = 'WEBPAGE' and item_type = %d )
OR ( service = 'PDL' AND item_type = %d )) $sql_options $revision limit 1",
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
and (( iconfig.k = 'WEBPAGE' and item_type = %d )
OR ( iconfig.k = 'PDL' AND item_type = %d )) $sql_options $revision limit 1",
intval($u[0]['channel_id']),
dbesc($page_id),
intval(ITEM_TYPE_WEBPAGE),
@@ -77,9 +78,9 @@ class Page extends \Zotlabs\Web\Controller {
// Check again with no permissions clause to see if it is a permissions issue
$x = q("select item.* from item left join item_id on item.id = item_id.iid
where item.uid = %d and sid = '%s' and item.item_delayed = 0 and service = 'WEBPAGE' and
item_type = %d $revision limit 1",
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
and iconfig.k = 'WEBPAGE' and item_type = %d $revision limit 1",
intval($u[0]['channel_id']),
dbesc($page_id),
intval(ITEM_TYPE_WEBPAGE)
@@ -119,11 +120,8 @@ class Page extends \Zotlabs\Web\Controller {
\App::$data['webpage'] = $r;
}
function get() {
function get() {
$r = \App::$data['webpage'];
if(! $r)

View File

@@ -20,7 +20,7 @@ class Pdledit extends \Zotlabs\Web\Controller {
}
function get() {
function get() {
if(! local_channel()) {
notice( t('Permission denied.') . EOL);
@@ -32,18 +32,18 @@ class Pdledit extends \Zotlabs\Web\Controller {
else {
$o .= '<div class="generic-content-wrapper-styled">';
$o .= '<h1>' . t('Edit System Page Description') . '</h1>';
$files = glob('mod/*');
$files = glob('Zotlabs/Module/*.php');
if($files) {
foreach($files as $f) {
$name = basename($f,'.php');
$name = lcfirst(basename($f,'.php'));
$x = theme_include('mod_' . $name . '.pdl');
if($x) {
$o .= '<a href="pdledit/' . $name . '" >' . $name . '</a><br />';
}
}
}
$o .= '</div>';
$o .= '</div>';
// list module pdl files
return $o;

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module;
require_once('include/security.php');
require_once('include/attach.php');
require_once('include/photo/photo_driver.php');
@@ -10,6 +11,8 @@ class Photo extends \Zotlabs\Web\Controller {
function init() {
$prvcachecontrol = false;
$streaming = null;
$channel = null;
switch(argc()) {
case 4:
@@ -62,7 +65,7 @@ class Photo extends \Zotlabs\Web\Controller {
intval($uid),
intval(PHOTO_PROFILE)
);
if(count($r)) {
if($r) {
$data = dbunescbin($r[0]['content']);
$mimetype = $r[0]['mimetype'];
}
@@ -79,7 +82,7 @@ class Photo extends \Zotlabs\Web\Controller {
* Other photos
*/
/* Check for a cookie to indicate display pixel density, in order to detect high-resolution
/* Check for a cookie to indicate display pixel density, in order to detect high-resolution
displays. This procedure was derived from the "Retina Images" by Jeremey Worboys,
used in accordance with the Creative Commons Attribution 3.0 Unported License.
Project link: https://github.com/Retina-Images/Retina-Images
@@ -131,6 +134,8 @@ class Photo extends \Zotlabs\Web\Controller {
$sql_extra = permissions_sql($r[0]['uid']);
$channel = channelx_by_n($r[0]['uid']);
// Now we'll see if we can access the photo
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1",
@@ -141,8 +146,9 @@ class Photo extends \Zotlabs\Web\Controller {
if($r && $allowed) {
$data = dbunescbin($r[0]['content']);
$mimetype = $r[0]['mimetype'];
if(intval($r[0]['os_storage']))
$data = file_get_contents($data);
if(intval($r[0]['os_storage'])) {
$streaming = $data;
}
}
else {
@@ -242,7 +248,25 @@ class Photo extends \Zotlabs\Web\Controller {
header("Cache-Control: max-age=" . $cache);
}
echo $data;
// If it's a file resource, stream it.
if($streaming && $channel) {
if(strpos($streaming,'store') !== false)
$istream = fopen($streaming,'rb');
else
$istream = fopen('store/' . $channel['channel_address'] . '/' . $streaming,'rb');
$ostream = fopen('php://output','wb');
if($istream && $ostream) {
pipe_streams($istream,$ostream);
fclose($istream);
fclose($ostream);
}
}
else {
echo $data;
}
killme();
// NOTREACHED
}

View File

@@ -9,8 +9,6 @@ require_once('include/bbcode.php');
require_once('include/security.php');
require_once('include/attach.php');
require_once('include/text.php');
require_once('include/PermissionDescription.php');
class Photos extends \Zotlabs\Web\Controller {
@@ -27,7 +25,7 @@ class Photos extends \Zotlabs\Web\Controller {
if(argc() > 1) {
$nick = argv(1);
profile_load($a,$nick);
profile_load($nick);
$channelx = channelx_by_nick($nick);
@@ -633,7 +631,7 @@ class Photos extends \Zotlabs\Web\Controller {
$lockstate = (($acl->is_private()) ? 'lock' : 'unlock');
}
$aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_storage')) : '');
$aclselect = (($_is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
// this is wrong but is to work around an issue with js_upload wherein it chokes if these variables
// don't exist. They really should be set to a parseable representation of the channel's default permissions
@@ -1023,7 +1021,7 @@ class Photos extends \Zotlabs\Web\Controller {
if($can_post) {
$album_e = $ph[0]['album'];
$caption_e = $ph[0]['description'];
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \PermissionDescription::fromGlobalPermission('view_storage')) : '');
$aclselect_e = (($_is_owner) ? populate_acl($ph[0], true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_storage')) : '');
$albums = ((array_key_exists('albums', \App::$data)) ? \App::$data['albums'] : photos_albums_list(\App::$data['channel'],\App::$data['observer']));
$_SESSION['album_return'] = bin2hex($ph[0]['album']);

View File

@@ -173,7 +173,7 @@ class Ping extends \Zotlabs\Web\Controller {
);
break;
case 'all_events':
$r = q("update event set `dimissed` = 1 where `dismissed` = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ",
$r = q("update event set `dismissed` = 1 where `dismissed` = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ",
intval(local_channel()),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')),
dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days'))

View File

@@ -48,7 +48,7 @@ class Profile extends \Zotlabs\Web\Controller {
}
}
profile_load($a,$which,$profile);
profile_load($which,$profile);
}

View File

@@ -23,19 +23,18 @@ class Profile_photo extends \Zotlabs\Web\Controller {
/* @brief Initalize the profile-photo edit view
*
* @param $a Current application
* @return void
*
*/
function init() {
function init() {
if(! local_channel()) {
return;
}
$channel = \App::get_channel();
profile_load($a,$channel['channel_address']);
profile_load($channel['channel_address']);
}
@@ -46,7 +45,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
*
*/
function post() {
function post() {
if(! local_channel()) {
return;
@@ -54,24 +53,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) {
// unless proven otherwise
$is_default_profile = 1;
if($_REQUEST['profile']) {
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
intval($_REQUEST['profile']),
intval(local_channel())
);
if($r) {
$profile = $r[0];
if(! intval($profile['is_default']))
$is_default_profile = 0;
}
}
if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
// phase 2 - we have finished cropping
@@ -86,18 +68,33 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$scale = substr($image_id,-1,1);
$image_id = substr($image_id,0,-2);
}
// unless proven otherwise
$is_default_profile = 1;
if($_REQUEST['profile']) {
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
intval($_REQUEST['profile']),
intval(local_channel())
);
if($r) {
$profile = $r[0];
if(! intval($profile['is_default']))
$is_default_profile = 0;
}
}
$srcX = $_POST['xstart'];
$srcY = $_POST['ystart'];
$srcW = $_POST['xfinal'] - $srcX;
$srcH = $_POST['yfinal'] - $srcY;
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
dbesc($image_id),
dbesc(local_channel()),
intval($scale));
if($r) {
$base_image = $r[0];
@@ -110,30 +107,38 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$aid = get_account_id();
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'], 'album' => t('Profile Photos'));
$p = [
'aid' => $aid,
'uid' => local_channel(),
'resource_id' => $base_image['resource_id'],
'filename' => $base_image['filename'],
'album' => t('Profile Photos')
];
$p['imgscale'] = 4;
$p['imgscale'] = PHOTO_RES_PROFILE_300;
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
$r1 = $im->save($p);
$im->scaleImage(80);
$p['imgscale'] = 5;
$p['imgscale'] = PHOTO_RES_PROFILE_80;
$r2 = $im->save($p);
$im->scaleImage(48);
$p['imgscale'] = 6;
$p['imgscale'] = PHOTO_RES_PROFILE_48;
$r3 = $im->save($p);
if($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 4 ",
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
dbesc($base_image['resource_id']),
local_channel()
local_channel(),
intval(PHOTO_RES_PROFILE_300),
intval(PHOTO_RES_PROFILE_80),
intval(PHOTO_RES_PROFILE_48)
);
return;
}
@@ -175,6 +180,8 @@ class Profile_photo extends \Zotlabs\Web\Controller {
dbesc(datetime_convert()),
dbesc($channel['xchan_hash'])
);
// Similarly, tell the nav bar to bypass the cache and update the avater image.
$_SESSION['reload_avatar'] = true;
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
@@ -183,10 +190,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
// Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
profile_photo_set_profile_perms($_REQUEST['profile']);
profile_photo_set_profile_perms(local_channel(),$_REQUEST['profile']);
}
else
notice( t('Unable to process image') . EOL);
@@ -196,7 +200,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
return; // NOTREACHED
}
// A new photo was uploaded. Store it and save some important details
// in App::$data for use in the cropping function
$hash = photo_new_resource();
$smallest = 0;
@@ -220,7 +226,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$os_storage = false;
foreach($i as $ii) {
if(intval($ii['imgscale']) < 2) {
if(intval($ii['imgscale']) < PHOTO_RES_640) {
$smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
$imagedata = $ii['content'];
@@ -238,7 +244,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
}
return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
// This will "fall through" to the get() method, and since
// App::$data['imagecrop'] is set, it will proceed to cropping
// rather than present the upload form
}
@@ -269,11 +278,19 @@ class Profile_photo extends \Zotlabs\Web\Controller {
notice( t('Permission denied.') . EOL );
return;
};
// check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
$resource_id = argv(2);
// When using an existing photo, we don't have a dialogue to offer a choice of profiles,
// so it gets attached to the default
$p = q("select id from profile where is_default = 1 and uid = %d",
intval(local_channel())
);
if($p) {
$_REQUEST['profile'] = $p[0]['id'];
}
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
intval(local_channel()),
@@ -285,11 +302,11 @@ class Profile_photo extends \Zotlabs\Web\Controller {
}
$havescale = false;
foreach($r as $rr) {
if($rr['imgscale'] == 5)
if($rr['imgscale'] == PHOTO_RES_PROFILE_80)
$havescale = true;
}
// set an already loaded photo as profile photo
// set an already loaded and cropped photo as profile photo
if(($r[0]['album'] == t('Profile Photos')) && ($havescale)) {
// unset any existing profile photos
@@ -310,7 +327,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
dbesc($channel['xchan_hash'])
);
profile_photo_set_profile_perms(); //Reset default photo permissions to public
profile_photo_set_profile_perms(local_channel()); // Reset default photo permissions to public
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
goaway(z_root() . '/profiles');
}
@@ -342,17 +359,22 @@ class Profile_photo extends \Zotlabs\Web\Controller {
if($i) {
$hash = $i[0]['resource_id'];
foreach($i as $ii) {
if(intval($ii['imgscale']) < 2) {
if(intval($ii['imgscale']) < PHOTO_RES_640) {
$smallest = intval($ii['imgscale']);
}
}
}
}
profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
$this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
}
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d",
// present an upload form
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
intval(local_channel())
);
@@ -379,6 +401,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
return $o;
}
else {
// present a cropping form
$filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'];
$resolution = \App::$data['imagecrop_resolution'];
$tpl = get_markup_template("cropbody.tpl");
@@ -416,13 +441,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
if($max_length > 0)
$ph->scaleImage($max_length);
$width = $ph->getWidth();
$height = $ph->getHeight();
\App::$data['width'] = $ph->getWidth();
\App::$data['height'] = $ph->getHeight();
if($width < 500 || $height < 500) {
if(\App::$data['width'] < 500 || \App::$data['height'] < 500) {
$ph->scaleImageUp(400);
$width = $ph->getWidth();
$height = $ph->getHeight();
\App::$data['width'] = $ph->getWidth();
\App::$data['height'] = $ph->getHeight();
}

View File

@@ -193,7 +193,7 @@ class Profiles extends \Zotlabs\Web\Controller {
$chan = \App::get_channel();
profile_load($a,$chan['channel_address'],$r[0]['id']);
profile_load($chan['channel_address'],$r[0]['id']);
}
}
@@ -584,7 +584,7 @@ class Profiles extends \Zotlabs\Web\Controller {
if($is_default) {
// reload the info for the sidebar widget - why does this not work?
profile_load($a,$channel['channel_address']);
profile_load($channel['channel_address']);
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
}
}

View File

@@ -17,7 +17,7 @@ class Profperm extends \Zotlabs\Web\Controller {
$profile = \App::$argv[1];
profile_load($a,$which,$profile);
profile_load($which,$profile);
}
@@ -97,7 +97,7 @@ class Profperm extends \Zotlabs\Web\Controller {
//Time to update the permissions on the profile-pictures as well
profile_photo_set_profile_perms($profile['id']);
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'",
intval(local_channel()),

80
Zotlabs/Module/README.md Normal file
View File

@@ -0,0 +1,80 @@
Zotlabs/Module
==============
This directory contains controller modules for handling web requests. The
lowercase class name indicates the head of the URL path which this module
handles. There are other methods of attaching (routing) URL paths to
controllers, but this is the primary method used in this project.
Module controllers MUST reside in this directory and namespace to be
autoloaded (unless other specific routing methods are employed). They
typically use and extend the class definition in Zotlabs/Web/Controller
as a template.
Template:
<?php
namespace Zotlabs\Web;
class Controller {
function init() {}
function post() {}
function get() {}
}
Typical Module declaration for the '/foo' URL route:
<?php
namespace Zotlabs\Module;
class Foo extends \Zotlabs\Web\Controller {
function init() {
// init() handler goes here
}
function post() {
// post handler goes here
}
function get() {
return 'Hello world.' . EOL;
}
}
This model provides callbacks for public functions named init(), post(),
and get(). init() is always called. post() is called if $_POST variables
are present, and get() is called if none of the prior functions terminated
the handler. The get() method typically retuns a string which represents
the contents of the content region of the resulting page. Modules which emit
json, xml or other machine-readable formats typically emit their contents
inside the init() function and call 'killme()' to terminate the Module.
Modules are passed the URL path as argc,argv arguments. For a path such as
https://mysite.something/foo/bar/baz
The app will typically invoke the Module class 'Foo' and pass it
$x = argc(); // $x = 3
$x = argv(0); // $x = 'foo'
$x = argv(1); // $x = 'bar'
$x = argv(2); // $x = 'baz'
These are handled in a similar fashion to their counterparts in the Unix shell
or C/C++ languages. Do not confuse the argc(),argv() functions with the
global variables $argc,$argv which are passed to command line programs. These
are handled separately by command line and Zotlabs/Daemon class functions.

View File

@@ -146,7 +146,7 @@ class Register extends \Zotlabs\Web\Controller {
goaway(z_root());
}
authenticate_success($result['account'],true,false,true);
authenticate_success($result['account'],null,true,false,true);
$new_channel = false;
$next_page = 'new_channel';
@@ -259,7 +259,8 @@ class Register extends \Zotlabs\Web\Controller {
'$email' => $email,
'$pass1' => $password,
'$pass2' => $password2,
'$submit' => ((UNO || $auto_create || $registration_is) ? t('Register') : t('Proceed to create your first channel'))
'$submit' => t('Register'),
'$verify_note' => t('This site may require email verification after submitting this form. If you are returned to a login page, please check your email for instructions.')
));
return $o;

View File

@@ -25,7 +25,8 @@ class Removeaccount extends \Zotlabs\Web\Controller {
$account = \App::get_account();
$account_id = get_account_id();
if(! account_verify_password($account['account_email'],$_POST['qxz_password']))
$x = account_verify_password($account['account_email'],$_POST['qxz_password']);
if(! ($x && $x['account']))
return;
if($account['account_password_changed'] != NULL_DATE) {

View File

@@ -24,7 +24,9 @@ class Removeme extends \Zotlabs\Web\Controller {
$account = \App::get_account();
if(! account_verify_password($account['account_email'],$_POST['qxz_password']))
$x = account_verify_password($account['account_email'],$_POST['qxz_password']);
if(! ($x && $x['account']))
return;
if($account['account_password_changed'] != NULL_DATE) {

View File

@@ -2,7 +2,6 @@
namespace Zotlabs\Module;
class Rmagic extends \Zotlabs\Web\Controller {
function init() {

View File

@@ -7,7 +7,6 @@ require_once('include/items.php');
require_once('include/taxonomy.php');
require_once('include/conversation.php');
require_once('include/zot.php');
require_once('include/PermissionDescription.php');
/**
* remote post
@@ -116,7 +115,7 @@ class Rpost extends \Zotlabs\Web\Controller {
'default_location' => $channel['channel_location'],
'nickname' => $channel['channel_address'],
'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
'acl' => populate_acl($channel_acl, true, \PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'acl' => populate_acl($channel_acl, true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'bang' => '',
'visitor' => true,
'profile_uid' => local_channel(),

View File

@@ -2,8 +2,6 @@
namespace Zotlabs\Module; /** @file */
require_once('include/zot.php');
require_once('include/PermissionDescription.php');
class Settings extends \Zotlabs\Web\Controller {
@@ -30,7 +28,7 @@ class Settings extends \Zotlabs\Web\Controller {
}
function post() {
function post() {
if(! local_channel())
return;
@@ -119,6 +117,60 @@ class Settings extends \Zotlabs\Web\Controller {
build_sync_packet();
return;
}
if((argc() > 1) && (argv(1) == 'tokens')) {
check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens');
$token_errs = 0;
if(array_key_exists('token',$_POST)) {
$atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0);
$name = trim(escape_tags($_POST['name']));
$token = trim($_POST['token']);
if((! $name) || (! $token))
$token_errs ++;
if(trim($_POST['expires']))
$expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']);
else
$expires = NULL_DATE;
$max_atokens = service_class_fetch(local_channel(),'access_tokens');
if($max_atokens) {
$r = q("select count(atoken_id) as total where atoken_uid = %d",
intval(local_channel())
);
if($r && intval($r[0]['total']) >= $max_tokens) {
notice( sprintf( t('This channel is limited to %d tokens'), $max_tokens) . EOL);
return;
}
}
}
if($token_errs) {
notice( t('Name and Password are required.') . EOL);
return;
}
if($atoken_id) {
$r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expires = '%s'
where atoken_id = %d and atoken_uid = %d",
dbesc($name),
dbesc($token),
dbesc($expires),
intval($atoken_id),
intval($channel['channel_id'])
);
}
else {
$r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )
values ( %d, %d, '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel['channel_id']),
dbesc($name),
dbesc($token),
dbesc($expires)
);
}
info( t('Token saved.') . EOL);
return;
}
@@ -708,6 +760,53 @@ class Settings extends \Zotlabs\Web\Controller {
));
return $o;
}
if((argc() > 1) && (argv(1) === 'tokens')) {
$atoken = null;
if(argc() > 2) {
$id = argv(2);
$atoken = q("select * from atoken where atoken_id = %d and atoken_uid = %d",
intval($id),
intval(local_channel())
);
if($atoken)
$atoken = $atoken[0];
if($atoken && argc() > 3 && argv(3) === 'drop') {
$r = q("delete from atoken where atoken_id = %d",
intval($id)
);
}
}
$t = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);
$desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access the private content.');
$desc2 = t('You may also provide <em>dropbox</em> style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:');
$tpl = get_markup_template("settings_tokens.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("settings_tokens"),
'$title' => t('Guest Access Tokens'),
'$desc' => $desc,
'$desc2' => $desc2,
'$tokens' => $t,
'$atoken' => $atoken,
'$url1' => z_root() . '/channel/' . $channel['channel_address'],
'$url2' => z_root() . '/photos/' . $channel['channel_address'],
'$name' => array('name', t('Login Name') . ' <span class="required">*</span>', (($atoken) ? $atoken['atoken_name'] : ''),''),
'$token'=> array('token', t('Login Password') . ' <span class="required">*</span>',(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''),
'$expires'=> array('expires', t('Expires (yyyy-mm-dd)'), (($atoken['atoken_expires'] && $atoken['atoken_expires'] != NULL_DATE) ? datetime_convert('UTC',date_default_timezone_get(),$atoken['atoken_expires']) : ''), ''),
'$submit' => t('Submit')
));
return $o;
}
@@ -1066,7 +1165,7 @@ class Settings extends \Zotlabs\Web\Controller {
'$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')),
'$permissions' => t('Default Post and Publish Permissions'),
'$permdesc' => t("\x28click to open/close\x29"),
'$aclselect' => populate_acl($perm_defaults, false, \PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
'$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
'$suggestme' => $suggestme,
'$group_select' => $group_select,
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()),

View File

@@ -493,7 +493,6 @@ class Setup extends \Zotlabs\Web\Controller {
$this->check_add($ck_funcs, t('OpenSSL PHP module'), true, true);
$this->check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true);
$this->check_add($ck_funcs, t('mb_string PHP module'), true, true);
$this->check_add($ck_funcs, t('mcrypt PHP module'), true, true);
$this->check_add($ck_funcs, t('xml PHP module'), true, true);
if(function_exists('apache_get_modules')){
@@ -530,10 +529,6 @@ class Setup extends \Zotlabs\Web\Controller {
$ck_funcs[4]['status'] = false;
$ck_funcs[4]['help'] = t('Error: mb_string PHP module required but not installed.');
}
if(! function_exists('mcrypt_encrypt')) {
$ck_funcs[5]['status'] = false;
$ck_funcs[5]['help'] = t('Error: mcrypt PHP module required but not installed.');
}
if(! extension_loaded('xml')) {
$ck_funcs[6]['status'] = false;
$ck_funcs[6]['help'] = t('Error: xml PHP module required for DAV but not installed.');
@@ -596,7 +591,7 @@ class Setup extends \Zotlabs\Web\Controller {
if(! is_writable('store')) {
$status = false;
$help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
$help = t('This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
$help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
}
@@ -639,6 +634,9 @@ class Setup extends \Zotlabs\Web\Controller {
$help .= t('If your certificate is not recognized, members of other sites (who may themselves have valid certificates) will get a warning message on their own site complaining about security issues.') . EOL;
$help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL;
$help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL;
$help .= t('If you are confident that the certificate is valid and signed by a trusted authority, check to see if you have failed to install an intermediate cert. These are not normally required by browsers, but are required for server-to-server communications.') . EOL;
$this->check_add($checks, t('SSL certificate validation'), false, true, $help);
}
@@ -695,6 +693,7 @@ class Setup extends \Zotlabs\Web\Controller {
// install the standard theme
set_config('system', 'allowed_themes', 'redbasic');
// Set a lenient list of ciphers if using openssl. Other ssl engines
// (e.g. NSS used in RedHat) require different syntax, so hopefully
// the default curl cipher list will work for most sites. If not,
@@ -704,7 +703,9 @@ class Setup extends \Zotlabs\Web\Controller {
// z_fetch_url() is also used to import shared links and other content
// so in theory most any cipher could show up and we should do our best
// to make the content available rather than tell folks that there's a
// weird SSL error which they can't do anything about.
// weird SSL error which they can't do anything about. This does not affect
// the SSL server, but is only a client negotiation to find something workable.
// Hence it will not make your system susceptible to POODL or other nasties.
$x = curl_version();
if(stristr($x['ssl_version'],'openssl'))

View File

@@ -27,28 +27,11 @@ class Siteinfo extends \Zotlabs\Web\Controller {
else {
$version = $commit = '';
}
$visible_plugins = array();
if(is_array(\App::$plugins) && count(\App::$plugins)) {
$r = q("select * from addon where hidden = 0");
if(count($r))
foreach($r as $rr)
$visible_plugins[] = $rr['name'];
}
$plugins_list = '';
if(count($visible_plugins)) {
$plugins_text = t('Installed plugins/addons/apps:');
$sorted = $visible_plugins;
$s = '';
sort($sorted);
foreach($sorted as $p) {
if(strlen($p)) {
if(strlen($s)) $s .= ', ';
$s .= $p;
}
}
$plugins_list .= $s;
}
$plugins_list = implode(', ',visible_plugin_list());
if($plugins_list)
$plugins_text = t('Installed plugins/addons/apps:');
else
$plugins_text = t('No installed plugins/addons/apps');

View File

@@ -30,7 +30,20 @@ class Starred extends \Zotlabs\Web\Controller {
intval(local_channel()),
intval($message_id)
);
$r = q("select * from item where id = %d",
intval($message_id)
);
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet(local_channel(),[
'item' => [
encode_item($sync_item[0],true)
]
]);
}
header('Content-type: application/json');
echo json_encode(array('result' => $item_starred));
killme();

View File

@@ -129,9 +129,14 @@ class Tagger extends \Zotlabs\Web\Controller {
store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid);
$ret = post_activity_item($arr);
if($ret['success'])
\Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id']));
if($ret['success']) {
build_sync_packet(local_channel(),
[
'item' => [ encode_item($ret['activity'],true) ]
]
);
}
killme();

View File

@@ -44,7 +44,7 @@ class Uexport extends \Zotlabs\Web\Controller {
}
}
function get() {
function get() {
$y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');

View File

@@ -10,8 +10,11 @@ class Viewconnections extends \Zotlabs\Web\Controller {
if(observer_prohibited()) {
return;
}
if(argc() > 1)
profile_load($a,argv(1));
if(argc() > 1) {
profile_load(argv(1));
}
}
function get() {

View File

@@ -4,7 +4,6 @@ namespace Zotlabs\Module;
require_once('include/channel.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/PermissionDescription.php');
class Webpages extends \Zotlabs\Web\Controller {
@@ -23,12 +22,12 @@ class Webpages extends \Zotlabs\Web\Controller {
else
return;
profile_load($a,$which);
profile_load($which);
}
function get() {
function get() {
if(! \App::$profile) {
notice( t('Requested profile is not available.') . EOL );
@@ -105,7 +104,7 @@ class Webpages extends \Zotlabs\Web\Controller {
'is_owner' => true,
'nickname' => \App::$profile['channel_address'],
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
'acl' => (($is_owner) ? populate_acl($channel_acl,false, \PermissionDescription::fromGlobalPermission('view_pages')) : ''),
'acl' => (($is_owner) ? populate_acl($channel_acl,false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''),
'showacl' => (($is_owner) ? true : false),
'visitor' => true,
'hide_location' => true,
@@ -138,11 +137,19 @@ class Webpages extends \Zotlabs\Web\Controller {
$sql_extra = item_permissions_sql($owner);
$r = q("select * from item_id left join item on item_id.iid = item.id
where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
$r = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d
$sql_extra order by item.created desc",
intval($owner),
intval(ITEM_TYPE_WEBPAGE)
);
// $r = q("select * from item_id left join item on item_id.iid = item.id
// where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
// intval($owner),
// intval(ITEM_TYPE_WEBPAGE)
// );
$pages = null;
@@ -160,13 +167,13 @@ class Webpages extends \Zotlabs\Web\Controller {
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'pagetitle' => $rr['sid'],
'pagetitle' => $rr['v'],
'mid' => $rr['mid'],
'layout_mid' => $rr['layout_mid']
);
$pages[$rr['iid']][] = array(
'url' => $rr['iid'],
'pagetitle' => $rr['sid'],
'pagetitle' => $rr['v'],
'title' => $rr['title'],
'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']),
'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']),

View File

@@ -1,6 +1,6 @@
<?php
<?php /** @file */
namespace Zotlabs\Module;/** @file */
namespace Zotlabs\Module;
class Wiki extends \Zotlabs\Web\Controller {
@@ -20,11 +20,28 @@ class Wiki extends \Zotlabs\Web\Controller {
notice(t('You must be logged in to see this page.') . EOL);
goaway('/login');
}
profile_load($nick);
}
function get() {
if(observer_prohibited(true)) {
return login();
}
if(! feature_enabled(\App::$profile_uid,'wiki')) {
notice( t('Not found') . EOL);
return;
}
$tab = 'wiki';
require_once('include/wiki.php');
require_once('include/acl_selectors.php');
require_once('include/conversation.php');
// TODO: Combine the interface configuration into a unified object
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
$wiki_owner = false;
@@ -72,8 +89,11 @@ class Wiki extends \Zotlabs\Web\Controller {
switch (argc()) {
case 2:
// Configure page template
$wikiheader = t('Wiki Sandbox');
$content = '"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."';
$wikiheaderName = t('Wiki');
$wikiheaderPage = t('Sandbox');
require_once('library/markdown.php');
$content = t('"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."');
$renderedContent = Markdown(json_decode($content));
$hide_editor = false;
$showPageControls = false;
$showNewWikiButton = $wiki_owner;
@@ -113,13 +133,18 @@ class Wiki extends \Zotlabs\Web\Controller {
} else {
$wiki_editor = true;
}
$wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page
$wikiheaderName = urldecode($wikiUrlName);
$wikiheaderPage = urldecode($pageUrlName);
$p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if(!$p['success']) {
notice('Error retrieving page content' . EOL);
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
}
$content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"');
$content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"');
// Render the Markdown-formatted page content in HTML
require_once('library/markdown.php');
$html = wiki_generate_toc(purify_html(Markdown(json_decode($content))));
$renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName);
$hide_editor = false;
$showPageControls = $wiki_editor;
$showNewWikiButton = $wiki_owner;
@@ -131,11 +156,25 @@ class Wiki extends \Zotlabs\Web\Controller {
default: // Strip the extraneous URL components
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName);
}
// Render the Markdown-formatted page content in HTML
require_once('library/markdown.php');
$wikiModalID = random_string(3);
$wikiModal = replace_macros(
get_markup_template('generic_modal.tpl'), array(
'$id' => $wikiModalID,
'$title' => t('Revision Comparison'),
'$ok' => t('Revert'),
'$cancel' => t('Cancel')
)
);
$is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
$o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
'$wikiheader' => $wikiheader,
'$wikiheaderName' => $wikiheaderName,
'$wikiheaderPage' => $wikiheaderPage,
'$hideEditor' => $hide_editor,
'$showPageControls' => $showPageControls,
'$showNewWikiButton'=> $showNewWikiButton,
@@ -149,11 +188,25 @@ class Wiki extends \Zotlabs\Web\Controller {
'$acl' => $x['acl'],
'$bang' => $x['bang'],
'$content' => $content,
'$renderedContent' => Markdown(json_decode($content)),
'$renderedContent' => $renderedContent,
'$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''),
'$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''),
'$pageRename' => array('pageRename', t('Enter the new name:'), '', ''),
'$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'),
'$pageHistory' => $pageHistory['history']
'$pageHistory' => $pageHistory['history'],
'$wikiModal' => $wikiModal,
'$wikiModalID' => $wikiModalID,
'$commit' => 'HEAD',
'$embedPhotos' => t('Embed image from photo albums'),
'$embedPhotosModalTitle' => t('Embed an image from your albums'),
'$embedPhotosModalCancel' => t('Cancel'),
'$embedPhotosModalOK' => t('OK'),
'$modalchooseimages' => t('Choose images to embed'),
'$modalchoosealbum' => t('Choose an album'),
'$modaldiffalbum' => t('Choose a different album...'),
'$modalerrorlist' => t('Error getting album list'),
'$modalerrorlink' => t('Error getting photo link'),
'$modalerroralbum' => t('Error getting album'),
));
head_add_js('library/ace/ace.js'); // Ace Code Editor
return $o;
@@ -166,8 +219,12 @@ class Wiki extends \Zotlabs\Web\Controller {
// Render mardown-formatted text in HTML for preview
if((argc() > 2) && (argv(2) === 'preview')) {
$content = $_POST['content'];
$resource_id = $_POST['resource_id'];
require_once('library/markdown.php');
$html = purify_html(Markdown($content));
$html = wiki_generate_toc(purify_html(Markdown($content)));
$w = wiki_get_wiki($resource_id);
$wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
$html = wiki_convert_links($html,$wikiURL);
json_return_and_die(array('html' => $html, 'success' => true));
}
@@ -185,6 +242,7 @@ 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']);
@@ -218,20 +276,7 @@ class Wiki extends \Zotlabs\Web\Controller {
if (local_channel() !== intval($channel['channel_id'])) {
logger('Wiki delete permission denied.' . EOL);
json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
} else {
/*
$channel = get_channel_by_nick($nick);
$observer_hash = get_observer_hash();
// Figure out who the page owner is.
$perms = get_all_perms(intval($channel['channel_id']), $observer_hash);
// TODO: Create a new permission setting for wiki analogous to webpages. Until
// then, use webpage permissions
if (!$perms['write_pages']) {
logger('Wiki delete permission denied.' . EOL);
json_return_and_die(array('success' => false));
}
*/
}
}
$resource_id = $_POST['resource_id'];
$deleted = wiki_delete_wiki($resource_id);
if ($deleted['success']) {
@@ -377,7 +422,7 @@ class Wiki extends \Zotlabs\Web\Controller {
if($deleted['success']) {
$ob = \App::get_observer();
$commit = wiki_git_commit(array(
'commit_msg' => 'Deleted ' . $pageHtmlName,
'commit_msg' => 'Deleted ' . $pageUrlName,
'resource_id' => $resource_id,
'observer' => $ob,
'files' => null
@@ -408,7 +453,7 @@ class Wiki extends \Zotlabs\Web\Controller {
json_return_and_die(array('success' => false));
}
}
$reverted = wiki_revert_page(array('commitHash' => $commitHash, 'observer' => \App::get_observer(), 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
$reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
if($reverted['success']) {
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
} else {
@@ -416,6 +461,73 @@ class Wiki extends \Zotlabs\Web\Controller {
}
}
// Compare page revisions
if ((argc() === 4) && (argv(2) === 'compare') && (argv(3) === 'page')) {
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['name'];
$compareCommit = $_POST['compareCommit'];
$currentCommit = $_POST['currentCommit'];
// Determine if observer has permission to revert pages
$nick = argv(1);
$channel = get_channel_by_nick($nick);
if (local_channel() !== intval($channel['channel_id'])) {
$observer_hash = get_observer_hash();
$perms = wiki_get_permissions($resource_id, intval($channel['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));
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'];
json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
} else {
json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
}
}
// Rename a page
if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) {
$resource_id = $_POST['resource_id'];
$pageUrlName = $_POST['oldName'];
$pageNewName = $_POST['newName'];
if ($pageUrlName === 'Home') {
json_return_and_die(array('message' => 'Cannot rename Home','success' => false));
}
if(urlencode(escape_tags($pageNewName)) === '') {
json_return_and_die(array('message' => 'Error renaming page. Invalid name.', 'success' => false));
}
// Determine if observer has permission to rename pages
$nick = argv(1);
$channel = get_channel_by_nick($nick);
if (local_channel() !== intval($channel['channel_id'])) {
$observer_hash = get_observer_hash();
$perms = wiki_get_permissions($resource_id, intval($channel['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));
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 . '.md', $renamed['page']['fileName']),
'all' => true
));
if($commit['success']) {
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
} else {
json_return_and_die(array('message' => 'Error making git commit','success' => false));
}
} else {
json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
}
}
//notice('You must be authenticated.');
json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));

View File

@@ -179,7 +179,8 @@ class Comanche {
$channel_id = $this->get_channel_id();
if($channel_id) {
$r = q("select * from item inner join item_id on iid = item.id and item_id.uid = item.uid and item.uid = %d and service = 'BUILDBLOCK' and sid = '%s' limit 1",
$r = q("select * from item inner join iconfig on iconfig.iid = item.id and item.uid = %d
and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK' and iconfig.v = '%s' limit 1",
intval($channel_id),
dbesc($name)
);
@@ -282,12 +283,12 @@ class Comanche {
/**
* Widgets will have to get any operational arguments from the session, the
* global app environment, or config storage until we implement argument passing
* Render a widget
*
* @param string $name
* @param string $text
*/
function widget($name, $text) {
$vars = array();
$matches = array();
@@ -314,7 +315,7 @@ class Comanche {
require_once(theme_include($theme_widget));
}
if (function_exists($func))
if(function_exists($func))
return $func($vars);
}

View File

@@ -3,6 +3,8 @@
namespace Zotlabs\Storage;
use Sabre\DAV;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
/**
* @brief Authentication backend class for DAV.
@@ -89,33 +91,20 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
require_once('include/auth.php');
$record = account_verify_password($username, $password);
if ($record && $record['account_default_channel']) {
$r = q("SELECT * FROM channel WHERE channel_account_id = %d AND channel_id = %d LIMIT 1",
intval($record['account_id']),
intval($record['account_default_channel'])
);
if($r && $this->check_module_access($r[0]['channel_id'])) {
return $this->setAuthenticated($r[0]);
if($record && $record['account']) {
if($record['channel'])
$channel = $record['channel'];
else {
$r = q("SELECT * FROM channel WHERE channel_account_id = %d AND channel_id = %d LIMIT 1",
intval($record['account']['account_id']),
intval($record['account']['account_default_channel'])
);
if($r)
$channel = $r[0];
}
}
$r = q("SELECT * FROM channel WHERE channel_address = '%s' LIMIT 1",
dbesc($username)
);
if ($r) {
$x = q("SELECT account_flags, account_salt, account_password FROM account WHERE account_id = %d LIMIT 1",
intval($r[0]['channel_account_id'])
);
if ($x) {
// @fixme this foreach should not be needed?
foreach ($x as $record) {
if ((($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED))
&& (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) {
logger('password verified for ' . $username);
if($this->check_module_access($r[0]['channel_id']))
return $this->setAuthenticated($r[0]);
}
}
}
if($channel && $this->check_module_access($channel['channel_id'])) {
return $this->setAuthenticated($channel);
}
if($this->module_disabled)
@@ -145,6 +134,58 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
return true;
}
/**
* When this method is called, the backend must check if authentication was
* successful.
*
* The returned value must be one of the following
*
* [true, "principals/username"]
* [false, "reason for failure"]
*
* If authentication was successful, it's expected that the authentication
* backend returns a so-called principal url.
*
* Examples of a principal url:
*
* principals/admin
* principals/user1
* principals/users/joe
* principals/uid/123457
*
* If you don't use WebDAV ACL (RFC3744) we recommend that you simply
* return a string such as:
*
* principals/users/[username]
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return array
*/
function check(RequestInterface $request, ResponseInterface $response) {
if(local_channel()) {
$this->setAuthenticated(\App::get_channel());
return [ true, $this->principalPrefix . $this->channel_name ];
}
$auth = new \Sabre\HTTP\Auth\Basic(
$this->realm,
$request,
$response
);
$userpass = $auth->getCredentials();
if (!$userpass) {
return [false, "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured"];
}
if (!$this->validateUserPass($userpass[0], $userpass[1])) {
return [false, "Username or password was incorrect"];
}
return [true, $this->principalPrefix . $userpass[0]];
}
protected function check_module_access($channel_id) {
if($channel_id && \App::$module === 'cdav') {
$x = get_pconfig($channel_id,'cdav','enabled');
@@ -222,4 +263,4 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
logger('owner_id ' . $this->owner_id, LOGGER_DATA);
logger('owner_nick ' . $this->owner_nick, LOGGER_DATA);
}
}
}

View File

@@ -219,7 +219,7 @@ class Browser extends DAV\Browser\Plugin {
$output = '';
if ($this->enablePost) {
$this->server->emit('onHTMLActionsPanel', array($parent, &$output));
$this->server->emit('onHTMLActionsPanel', array($parent, &$output, $path));
}
$html .= replace_macros(get_markup_template('cloud.tpl'), array(
@@ -266,7 +266,7 @@ class Browser extends DAV\Browser\Plugin {
* @param \Sabre\DAV\INode $node
* @param string &$output
*/
public function htmlActionsPanel(DAV\INode $node, &$output) {
public function htmlActionsPanel(DAV\INode $node, &$output, $path) {
if (! $node instanceof DAV\ICollection)
return;

View File

@@ -0,0 +1,738 @@
<?php
namespace Zotlabs\Storage;
// The Hubzilla CalDAV client will store calendar information in the 'cal' DB table.
// Event information will remain in the 'event' table. In order to implement CalDAV on top of our
// existing system, there is an event table column called vdata. This will hold the "one true record"
// of the event in VCALENDAR format. When we receive a foreign event, we will pick out the fields
// of this entry that are important to us and use it to populate the other event table fields.
// When we make an event change, it is required that we load this entry as a vobject, make the changes on the
// vobject, and then store the result back in event.vdata. This will preserve foreign keys which we
// know nothing about. Then we sync this back to the DAV server.
// We still need a DB update to create a 'cal' table entry for our existing events and link these together.
// I'm currently anticipating separating tasks/to-do items from events, so each new account wil get two default calendars.
// We will eventually provide for magic-auth or cookie login of the CURL process so we won't be required to
// store our hubzilla password. Currently for testing we are using HTTP BASIC-AUTH and must initialise the
// username/password correctly to make the connection.
// Repeating events will be awkward because every instance has the same UUID. This would make it difficult to
// search for upcoming events if the initial instance was created (for instance) a few years ago. So the current plan is
// to create event instances for a prescribed time limit from now (perhaps 5-10 years for annual events).
// This plan may change. The repurcussions of this decision mean that an edit to a recurring event must
// edit all existing instances of the event, and only one unique instance can be used for sync.
// Sabre vobject provides a function to automatically expand recurring events into individual event instances.
class CalDAVClient {
private $username;
private $password;
private $url;
public $filepos = 0;
public $request_data = '';
function __construct($user,$pass,$url) {
$this->username = $user;
$this->password = $pass;
$this->url = $url;
}
private function set_data($s) {
$this->request_data = $s;
$this->filepos = 0;
}
public function curl_read($ch,$fh,$size) {
if($this->filepos < 0) {
unset($fh);
return '';
}
$s = substr($this->request_data,$this->filepos,$size);
if(strlen($s) < $size)
$this->filepos = (-1);
else
$this->filepos = $this->filepos + $size;
return $s;
}
function ctag_fetch() {
$headers = [ 'Depth: 0', 'Prefer: return-minimal', 'Content-Type: application/xml; charset=utf-8'];
// recommended ctag fetch by sabre
$this->set_data('<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:prop>
<d:displayname />
<cs:getctag />
<d:sync-token />
</d:prop>
</d:propfind>');
// thunderbird uses this - it's a bit more verbose on what capabilities
// are provided by the server
$this->set_data('<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:resourcetype/>
<D:owner/>
<D:current-user-principal/>
<D:supported-report-set/>
<C:supported-calendar-component-set/>
<CS:getctag/>
</D:prop>
</D:propfind>');
$auth = $this->username . ':' . $this->password;
$recurse = 0;
$x = z_fetch_url($this->url,true,$recurse,
[ 'headers' => $headers,
'http_auth' => $auth,
'custom' => 'PROPFIND',
'upload' => true,
'infile' => 3,
'infilesize' => strlen($this->request_data),
'readfunc' => [ $this, 'curl_read' ]
]);
return $x;
}
function detail_fetch() {
$headers = [ 'Depth: 1', 'Prefer: return-minimal', 'Content-Type: application/xml; charset=utf-8'];
// this query should return all objects in the given calendar, you can filter it appropriately
// using filter options
$this->set_data('<?xml version="1.0"?>
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR" />
</c:filter>
</c:calendar-query>');
$auth = $this->username . ':' . $this->password;
$recurse = 0;
$x = z_fetch_url($this->url,true,$recurse,
[ 'headers' => $headers,
'http_auth' => $auth,
'custom' => 'REPORT',
'upload' => true,
'infile' => 3,
'infilesize' => strlen($this->request_data),
'readfunc' => [ $this, 'curl_read' ]
]);
return $x;
}
}
/*
PROPFIND /calendars/johndoe/home/ HTTP/1.1
Depth: 0
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:prop>
<d:displayname />
<cs:getctag />
</d:prop>
</d:propfind>
// Responses: success
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:response>
<d:href>/calendars/johndoe/home/</d:href>
<d:propstat>
<d:prop>
<d:displayname>Home calendar</d:displayname>
<cs:getctag>3145</cs:getctag>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
// Responses: fail
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:response>
<d:href>/calendars/johndoe/home/</d:href>
<d:propstat>
<d:prop>
<d:displayname />
<cs:getctag />
</d:prop>
<d:status>HTTP/1.1 403 Forbidden</d:status>
</d:propstat>
</d:response>
</d:multistatus>
// sample request body in DOM
// prepare request body
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$query = $doc->createElement('c:calendar-query');
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:c', 'urn:ietf:params:xml:ns:caldav');
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:d', 'DAV:');
$prop = $doc->createElement('d:prop');
$prop->appendChild($doc->createElement('d:getetag'));
$prop->appendChild($doc->createElement('c:calendar-data'));
$query->appendChild($prop);
$doc->appendChild($query);
$body = $doc->saveXML();
echo "Body: " . $body . "<br>";
Now we download every single object in this calendar. To do this, we use a REPORT method.
REPORT /calendars/johndoe/home/ HTTP/1.1
Depth: 1
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR" />
</c:filter>
</c:calendar-query>
This request will give us every object that's a VCALENDAR object, and its etag.
If you're only interested in VTODO (because you're writing a todo app) you can also filter for just those:
REPORT /calendars/johndoe/home/ HTTP/1.1
Depth: 1
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
<c:comp-filter name="VTODO" />
</c:comp-filter>
</c:filter>
</c:calendar-query>
Similarly it's also possible to filter to just events, or only get events within a specific time-range.
This report will return a multi-status object again:
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:response>
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
<d:propstat>
<d:prop>
<d:getetag>"2134-314"</d:getetag>
<c:calendar-data>BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VTODO
UID:132456762153245
SUMMARY:Do the dishes
DUE:20121028T115600Z
END:VTODO
END:VCALENDAR
</c:calendar-data>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/calendars/johndoe/home/132456-34365.ics</d:href>
<d:propstat>
<d:prop>
<d:getetag>"5467-323"</d:getetag>
<c:calendar-data>BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
UID:132456-34365
SUMMARY:Weekly meeting
DTSTART:20120101T120000
DURATION:PT1H
RRULE:FREQ=WEEKLY
END:VEVENT
END:VCALENDAR
</c:calendar-data>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
This calendar only contained 2 objects. A todo and a weekly event.
So after you retrieved and processed these, for each object you must retain:
The calendar data itself
The url
The etag
In this case all urls ended with .ics. This is often the case, but you must not rely on this. In this case the UID in the calendar object was also identical to a part of the url. This too is often the case, but again not something you can rely on, so don't make any assumptions.
The url and the UID have no meaningful relationship, so treat both those items as separate unique identifiers.
Finding out if anything changed
To see if anything in a calendar changed, we simply request the ctag again on the calendar. If the ctag did not change, you still have the latest copy.
If it did change, you must request all the etags in the entire calendar again:
REPORT /calendars/johndoe/home/ HTTP/1.1
Depth: 1
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
<c:comp-filter name="VTODO" />
</c:comp-filter>
</c:filter>
</c:calendar-query>
Note that this last request is extremely similar to a previous one, but we are only asking fo the etag, not the calendar-data.
The reason for this, is that calendars can be rather huge. It will save a TON of bandwidth to only check the etag first.
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:response>
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
<d:propstat>
<d:prop>
<d:getetag>"xxxx-xxx"</d:getetag>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
<d:propstat>
<d:prop>
<d:getetag>"5-12"</d:getetag>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
Judging from this last request, 3 things have changed:
The etag for the task has changed, so the contents must be different
There's a new url, some other client must have added an object
One object is missing, something must have deleted it.
So based on those 3 items we know that we need to delete an object from our local list, and fetch the contents for the new item, and the updated one.
To fetch the data for these, you can simply issue GET requests:
GET /calendars/johndoe/home/132456762153245.ics HTTP/1.1
But, because in a worst-case scenario this could result in a LOT of GET requests we can do a 'multiget'.
REPORT /calendars/johndoe/home/ HTTP/1.1
Depth: 1
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<c:calendar-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
<d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
</c:calendar-multiget>
This request will simply return a multi-status again with the calendar-data and etag.
A small note about application design
If you read this far and understood what's been said, you may have realized that it's a bit cumbersome to have a separate step for the initial sync, and subsequent updates.
It would totally be possible to skip the 'initial sync', and just use calendar-query and calendar-multiget REPORTS for the initial sync as well.
Updating a calendar object
Updating a calendar object is rather simple:
PUT /calendars/johndoe/home/132456762153245.ics HTTP/1.1
Content-Type: text/calendar; charset=utf-8
If-Match: "2134-314"
BEGIN:VCALENDAR
....
END:VCALENDAR
A response to this will be something like this:
HTTP/1.1 204 No Content
ETag: "2134-315"
The update gave us back the new ETag. SabreDAV gives this ETag on updates back most of the time, but not always.
There are cases where the caldav server must modify the iCalendar object right after storage. In those cases an ETag will not be returned, and you should issue a GET request immediately to get the correct object.
A few notes:
You must not change the UID of the original object
Every object should hold only 1 event or task.
You cannot change an VEVENT into a VTODO.
Creating a calendar object
Creating a calendar object is almost identical, except that you don't have a url yet to a calendar object.
Instead, it is up to you to determine the new url.
PUT /calendars/johndoe/home/somerandomstring.ics HTTP/1.1
Content-Type: text/calendar; charset=utf-8
BEGIN:VCALENDAR
....
END:VCALENDAR
A response to this will be something like this:
HTTP/1.1 201 Created
ETag: "21345-324"
Similar to updating, an ETag is often returned, but there are cases where this is not true.
Deleting a calendar object
Deleting is simple enough:
DELETE /calendars/johndoe/home/132456762153245.ics HTTP/1.1
If-Match: "2134-314"
Speeding up Sync with WebDAV-Sync
WebDAV-Sync is a protocol extension that is defined in rfc6578. Because this extension was defined later, some servers may not support this yet.
SabreDAV supports this since 2.0.
WebDAV-Sync allows a client to ask just for calendars that have changed. The process on a high-level is as follows:
Client requests sync-token from server.
Server reports token 15.
Some time passes.
Client does a Sync REPORT on an calendar, and supplied token 15.
Server returns vcard urls that have changed or have been deleted and returns token 17.
As you can see, after the initial sync, only items that have been created, modified or deleted will ever be sent.
This has a lot of advantages. The transmitted xml bodies can generally be a lot shorter, and is also easier on both client and server in terms of memory and CPU usage, because only a limited set of items will have to be compared.
It's important to note, that a client should only do Sync operations, if the server reports that it has support for it. The quickest way to do so, is to request {DAV}sync-token on the calendar you wish to sync.
Technically, a server may support 'sync' on one calendar, and it may not support it on another, although this is probably rare.
Getting the first sync-token
Initially, we just request a sync token when asking for calendar information:
PROPFIND /calendars/johndoe/home/ HTTP/1.1
Depth: 0
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:prop>
<d:displayname />
<cs:getctag />
<d:sync-token />
</d:prop>
</d:propfind>
This would return something as follows:
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:response>
<d:href>/calendars/johndoe/home/</d:href>
<d:propstat>
<d:prop>
<d:displayname>My calendar</d:displayname>
<cs:getctag>3145</cs:getctag>
<d:sync-token>http://sabredav.org/ns/sync-token/3145</d:sync-token>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
As you can see, the sync-token is a url. It always should be a url. Even though a number appears in the url, you are not allowed to attach any meaning to that url. Some servers may have use an increasing number, another server may use a completely random string.
Receiving changes
After a sync token has been obtained, and the client already has the initial copy of the calendar, the client is able to request all changes since the token was issued.
This is done with a REPORT request that may look like this:
REPORT /calendars/johndoe/home/ HTTP/1.1
Host: dav.example.org
Content-Type: application/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<d:sync-collection xmlns:d="DAV:">
<d:sync-token>http://sabredav.org/ns/sync/3145</d:sync-token>
<d:sync-level>1</d:sync-level>
<d:prop>
<d:getetag/>
</d:prop>
</d:sync-collection>
This requests all the changes since sync-token identified by http://sabredav.org/ns/sync/3145, and for the calendar objects that have been added or modified, we're requesting the etag.
The response to a query like this is another multistatus xml body. Example:
HTTP/1.1 207 Multi-Status
Content-Type: application/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<d:multistatus xmlns:d="DAV:">
<d:response>
<d:href>/calendars/johndoe/home/newevent.ics</d:href>
<d:propstat>
<d:prop>
<d:getetag>"33441-34321"</d:getetag>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/calendars/johndoe/home/updatedevent.ics</d:href>
<d:propstat>
<d:prop>
<d:getetag>"33541-34696"</d:getetag>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/calendars/johndoe/home/deletedevent.ics</d:href>
<d:status>HTTP/1.1 404 Not Found</d:status>
</d:response>
<d:sync-token>http://sabredav.org/ns/sync/5001</d:sync-token>
</d:multistatus>
The last response reported two changes: newevent.ics and updatedevent.ics. There's no way to tell from the response wether those cards got created or updated, you, as a client can only infer this based on the vcards you are already aware of.
The entry with name deletedevent.ics got deleted as indicated by the 404 status. Note that the status element is here a child of d:response when in all previous examples it has been a child of d:propstat.
The other difference with the other multi-status examples, is that this one has a sync-token element with the latest sync-token.
Caveats
Note that a server is free to 'forget' any sync-tokens that have been previously issued. In this case it may be needed to do a full-sync again.
In case the supplied sync-token is not recognized by the server, a HTTP error is emitted. SabreDAV emits a 403.
Discovery
Ideally you will want to make sure that all the calendars in an account are automatically discovered. The best user interface would be to just have to ask for three items:
Username
Password
Server
And the server should be as short as possible. This is possible with most servers.
If, for example a user specified 'dav.example.org' for the server, the first thing you should do is attempt to send a PROPFIND request to https://dav.example.org/. Note that you SHOULD try the https url before the http url.
This PROPFIND request looks as follows:
PROPFIND / HTTP/1.1
Depth: 0
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:">
<d:prop>
<d:current-user-principal />
</d:prop>
</d:propfind>
This will return a response such as the following:
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
<d:response>
<d:href>/</d:href>
<d:propstat>
<d:prop>
<d:current-user-principal>
<d:href>/principals/users/johndoe/</d:href>
</d:current-user-principal>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
A 'principal' is a user. The url that's being returned, is a url that refers to the current user. On this url you can request additional information about the user.
What we need from this url, is their 'calendar home'. The calendar home is a collection that contains all of the users' calendars.
To request that, issue the following request:
PROPFIND /principals/users/johndoe/ HTTP/1.1
Depth: 0
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<c:calendar-home-set />
</d:prop>
</d:propfind>
This will return a response such as the following:
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:response>
<d:href>/principals/users/johndoe/</d:href>
<d:propstat>
<d:prop>
<c:calendar-home-set>
<d:href>/calendars/johndoe/</d:href>
</c:calendar-home-set>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
Lastly, to list all the calendars for the user, issue a PROPFIND request with Depth: 1.
PROPFIND /calendars/johndoe/ HTTP/1.1
Depth: 1
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:resourcetype />
<d:displayname />
<cs:getctag />
<c:supported-calendar-component-set />
</d:prop>
</d:propfind>
In that last request, we asked for 4 properties.
The resourcetype tells us what type of object we're getting back. You must read out the resourcetype and ensure that it contains at least a calendar element in the CalDAV namespace. Other items may be returned, including non- calendar, which your application should ignore.
The displayname is a human-readable string for the calendarname, the ctag was already covered in an earlier section.
Lastly, supported-calendar-component-set. This gives us a list of components that the calendar accepts. This could be just VTODO, VEVENT, VJOURNAL or a combination of these three.
If you are just creating a todo-list application, this means you should only list the calendars that support the VTODO component.
HTTP/1.1 207 Multi-status
Content-Type: application/xml; charset=utf-8
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:response>
<d:href>/calendars/johndoe/</d:href>
<d:propstat>
<d:prop>
<d:resourcetype>
<d:collection/>
</d:resourcetype>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/calendars/johndoe/home/</d:href>
<d:propstat>
<d:prop>
<d:resourcetype>
<d:collection/>
<c:calendar/>
</d:resourcetype>
<d:displayname>Home calendar</d:displayname>
<cs:getctag>3145</cs:getctag>
<c:supported-calendar-component-set>
<c:comp name="VEVENT" />
</c:supported-calendar-component-set>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/calendars/johndoe/tasks/</d:href>
<d:propstat>
<d:prop>
<d:resourcetype>
<d:collection/>
<c:calendar/>
</d:resourcetype>
<d:displayname>My TODO list</d:displayname>
<cs:getctag>3345</cs:getctag>
<c:supported-calendar-component-set>
<c:comp name="VTODO" />
</c:supported-calendar-component-set>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
*/

View File

@@ -3,6 +3,7 @@
namespace Zotlabs\Storage;
use Sabre\DAV;
use Sabre\HTTP;
/**
* @brief RedDirectory class.
@@ -91,7 +92,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
throw new DAV\Exception\Forbidden('Permission denied.');
}
$contents = RedCollectionData($this->red_path, $this->auth);
$contents = $this->CollectionData($this->red_path, $this->auth);
return $contents;
}
@@ -119,7 +120,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
return new Directory('/' . $modulename, $this->auth);
}
$x = RedFileData($this->ext_path . '/' . $name, $this->auth);
$x = $this->FileData($this->ext_path . '/' . $name, $this->auth);
if ($x) {
return $x;
}
@@ -159,7 +160,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
throw new DAV\Exception\Forbidden('Permission denied.');
}
list($parent_path, ) = DAV\URLUtil::splitPath($this->red_path);
list($parent_path, ) = HTTP\URLUtil::splitPath($this->red_path);
$new_path = $parent_path . '/' . $name;
$r = q("UPDATE attach SET filename = '%s' WHERE hash = '%s' AND uid = %d",
@@ -206,6 +207,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
throw new DAV\Exception\Forbidden('Permission denied.');
}
$mimetype = z_mime_content_type($name);
$c = q("SELECT * FROM channel WHERE channel_id = %d AND channel_removed = 0 LIMIT 1",
@@ -369,6 +371,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
);
if ($r) {
require_once('include/attach.php');
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
if($result['success']) {
@@ -431,8 +434,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
return true;
}
$x = RedFileData($this->ext_path . '/' . $name, $this->auth, true);
//logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA);
$x = $this->FileData($this->ext_path . '/' . $name, $this->auth, true);
//logger('FileData returns: ' . print_r($x, true), LOGGER_DATA);
if ($x)
return true;
@@ -565,4 +568,280 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$free
);
}
/**
* @brief Array with all Directory and File DAV\Node items for the given path.
*
*
* @param string $file path to a directory
* @param \Zotlabs\Storage\BasicAuth &$auth
* @returns null|array \Sabre\DAV\INode[]
* @throw \Sabre\DAV\Exception\Forbidden
* @throw \Sabre\DAV\Exception\NotFound
*/
function CollectionData($file, &$auth) {
$ret = array();
$x = strpos($file, '/cloud');
if ($x === 0) {
$file = substr($file, 6);
}
// return a list of channel if we are not inside a channel
if ((! $file) || ($file === '/')) {
return $this->ChannelList($auth);
}
$file = trim($file, '/');
$path_arr = explode('/', $file);
if (! $path_arr)
return null;
$channel_name = $path_arr[0];
$r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' LIMIT 1",
dbesc($channel_name)
);
if (! $r)
return null;
$channel_id = $r[0]['channel_id'];
$perms = permissions_sql($channel_id);
$auth->owner_id = $channel_id;
$path = '/' . $channel_name;
$folder = '';
$errors = false;
$permission_error = false;
for ($x = 1; $x < count($path_arr); $x++) {
$r = q("SELECT id, hash, filename, flags, is_dir FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND is_dir != 0 $perms LIMIT 1",
dbesc($folder),
dbesc($path_arr[$x]),
intval($channel_id)
);
if (! $r) {
// path wasn't found. Try without permissions to see if it was the result of permissions.
$errors = true;
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 limit 1",
dbesc($folder),
basename($path_arr[$x]),
intval($channel_id)
);
if ($r) {
$permission_error = true;
}
break;
}
if ($r && intval($r[0]['is_dir'])) {
$folder = $r[0]['hash'];
$path = $path . '/' . $r[0]['filename'];
}
}
if ($errors) {
if ($permission_error) {
throw new DAV\Exception\Forbidden('Permission denied.');
}
else {
throw new DAV\Exception\NotFound('A component of the request file path could not be found.');
}
}
// This should no longer be needed since we just returned errors for paths not found
if ($path !== '/' . $file) {
logger("Path mismatch: $path !== /$file");
return NULL;
}
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$prefix = 'DISTINCT ON (filename)';
$suffix = 'ORDER BY filename';
}
else {
$prefix = '';
$suffix = 'GROUP BY filename';
}
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
dbesc($folder),
intval($channel_id)
);
foreach ($r as $rr) {
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
if (intval($rr['is_dir'])) {
$ret[] = new Directory($path . '/' . $rr['filename'], $auth);
}
else {
$ret[] = new File($path . '/' . $rr['filename'], $rr, $auth);
}
}
return $ret;
}
/**
* @brief Returns an array with viewable channels.
*
* Get a list of Directory objects with all the channels where the visitor
* has <b>view_storage</b> perms.
*
*
* @param BasicAuth &$auth
* @return array Directory[]
*/
function ChannelList(&$auth) {
$ret = array();
$r = q("SELECT channel_id, channel_address FROM channel WHERE channel_removed = 0
AND channel_system = 0 AND NOT (channel_pageflags & %d)>0",
intval(PAGE_HIDDEN)
);
if ($r) {
foreach ($r as $rr) {
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DATA);
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
$ret[] = new Directory('/cloud/' . $rr['channel_address'], $auth);
}
}
}
return $ret;
}
/**
* @brief
*
*
* @param string $file
* path to file or directory
* @param BasicAuth &$auth
* @param boolean $test (optional) enable test mode
* @return File|Directory|boolean|null
* @throw \Sabre\DAV\Exception\Forbidden
*/
function FileData($file, &$auth, $test = false) {
logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DATA);
$x = strpos($file, '/cloud');
if ($x === 0) {
$file = substr($file, 6);
}
else {
$x = strpos($file,'/dav');
if($x === 0)
$file = substr($file,4);
}
if ((! $file) || ($file === '/')) {
return new Directory('/', $auth);
}
$file = trim($file, '/');
$path_arr = explode('/', $file);
if (! $path_arr)
return null;
$channel_name = $path_arr[0];
$r = q("select channel_id from channel where channel_address = '%s' limit 1",
dbesc($channel_name)
);
if (! $r)
return null;
$channel_id = $r[0]['channel_id'];
$path = '/' . $channel_name;
$auth->owner_id = $channel_id;
$permission_error = false;
$folder = '';
require_once('include/security.php');
$perms = permissions_sql($channel_id);
$errors = false;
for ($x = 1; $x < count($path_arr); $x++) {
$r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 $perms",
dbesc($folder),
dbesc($path_arr[$x]),
intval($channel_id)
);
if ($r && intval($r[0]['is_dir'])) {
$folder = $r[0]['hash'];
$path = $path . '/' . $r[0]['filename'];
}
if (! $r) {
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
where folder = '%s' and filename = '%s' and uid = %d $perms order by filename limit 1",
dbesc($folder),
dbesc(basename($file)),
intval($channel_id)
);
}
if (! $r) {
$errors = true;
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach
where folder = '%s' and filename = '%s' and uid = %d order by filename limit 1",
dbesc($folder),
dbesc(basename($file)),
intval($channel_id)
);
if ($r)
$permission_error = true;
}
}
if ($path === '/' . $file) {
if ($test)
return true;
// final component was a directory.
return new Directory($file, $auth);
}
if ($errors) {
logger('not found ' . $file);
if ($test)
return false;
if ($permission_error) {
logger('permission error ' . $file);
throw new DAV\Exception\Forbidden('Permission denied.');
}
return;
}
if ($r) {
if ($test)
return true;
if (intval($r[0]['is_dir'])) {
return new Directory($path . '/' . $r[0]['filename'], $auth);
}
else {
return new File($path . '/' . $r[0]['filename'], $r[0], $auth);
}
}
return false;
}
}

View File

@@ -337,6 +337,10 @@ class File extends DAV\Node implements DAV\IFile {
}
}
if(get_pconfig($this->auth->owner_id,'system','os_delete_prohibit') && \App::$module == 'dav') {
throw new DAV\Exception\Forbidden('Permission denied.');
}
attach_delete($this->auth->owner_id, $this->data['hash']);
$ch = channelx_by_n($this->auth->owner_id);

View File

@@ -21,6 +21,9 @@ class CheckJS {
$page = urlencode(\App::$query_string);
if($test) {
self::$jsdisabled = 1;
if(array_key_exists('jsdisabled',$_COOKIE))
self::$jsdisabled = $_COOKIE['jsdisabled'];
if(! array_key_exists('jsdisabled',$_COOKIE)) {
\App::$page['htmlhead'] .= "\r\n" . '<script>document.cookie="jsdisabled=0; path=/"; var jsMatch = /\&jsdisabled=0/; if (!jsMatch.exec(location.href)) { location.href = "' . z_root() . '/nojs/0?f=&redir=' . $page . '" ; }</script>' . "\r\n";

View File

@@ -9,4 +9,5 @@ class Controller {
function post() {}
function get() {}
}
}

View File

@@ -24,7 +24,8 @@ class SessionHandler implements \SessionHandlerInterface {
return $r[0]['sess_data'];
}
else {
q("INSERT INTO `session` (sid, expire) values ('%s', '%s')",
q("INSERT INTO `session` (sess_data, sid, expire) values ('%s', '%s', '%s')",
dbesc(''),
dbesc($id),
dbesc(time() + 300)
);

View File

@@ -59,7 +59,14 @@ class WebServer {
\App::$query_string = strip_zids(\App::$query_string);
if(! local_channel()) {
$_SESSION['my_address'] = $_GET['zid'];
zid_init($a);
zid_init();
}
}
if((x($_GET,'zat')) && (! \App::$install)) {
\App::$query_string = strip_zats(\App::$query_string);
if(! local_channel()) {
zat_init();
}
}

View File

@@ -28,7 +28,7 @@ class Finger {
if (strpos($webbie,'@') === false) {
$address = $webbie;
$host = App::get_hostname();
$host = \App::get_hostname();
} else {
$address = substr($webbie,0,strpos($webbie,'@'));
$host = substr($webbie,strpos($webbie,'@')+1);
@@ -127,4 +127,4 @@ class Finger {
return $x;
}
}
}

View File

@@ -34,7 +34,6 @@ require_once('include/text.php');
require_once('include/datetime.php');
require_once('include/language.php');
require_once('include/nav.php');
require_once('include/cache.php');
require_once('include/permissions.php');
require_once('library/Mobile_Detect/Mobile_Detect.php');
require_once('include/features.php');
@@ -45,10 +44,10 @@ require_once('include/account.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
define ( 'STD_VERSION', '1.8' );
define ( 'STD_VERSION', '1.10' );
define ( 'ZOT_REVISION', '1.1' );
define ( 'DB_UPDATE_VERSION', 1176 );
define ( 'DB_UPDATE_VERSION', 1180 );
/**
@@ -771,6 +770,7 @@ class App {
public static $groups;
public static $language;
public static $langsave;
public static $rtl = false;
public static $plugins_admin;
public static $module_loaded = false;
public static $query_string;
@@ -1703,7 +1703,7 @@ function login($register = false, $form_id = 'main-login', $hiddens=false) {
'$logout' => t('Logout'),
'$login' => t('Login'),
'$form_id' => $form_id,
'$lname' => array('username', t('Email') , '', ''),
'$lname' => array('username', t('Login/Email') , '', ''),
'$lpassword' => array('password', t('Password'), '', ''),
'$remember_me' => array('remember_me', t('Remember me'), '', '',array(t('No'),t('Yes'))),
'$hiddens' => $hiddens,
@@ -1744,13 +1744,7 @@ function goaway($s) {
}
function shutdown() {
<<<<<<< HEAD
global $db;
if(is_object($db) && $db->connected)
$db->close();
=======
>>>>>>> 1.8RC
}
/**
@@ -2288,6 +2282,12 @@ function construct_page(&$a) {
$page = App::$page;
$profile = App::$profile;
// There's some experimental support for right-to-left text in the view/php/default.php page template.
// In v1.9 we started providing direction preference in the per language hstrings.php file
// This requires somebody with fluency in a RTL language to make happen
$page['direction'] = 0; // ((App::$rtl) ? 1 : 0);
header("Content-type: text/html; charset=utf-8");
// security headers - see https://securityheaders.io
@@ -2463,9 +2463,10 @@ function check_cron_broken() {
return;
}
set_config('system','lastcroncheck',datetime_convert());
if(($d) && ($d > datetime_convert('UTC','UTC','now - 3 days'))) {
// Scheduled tasks have run successfully in the last 3 days.
set_config('system','lastcroncheck',datetime_convert());
return;
}

View File

@@ -1,15 +1,15 @@
[h2]Documentation for Hub Administrators[/h2]
[h3]Administrators[/h3]
[h3]Deploying your hub[/h3]
[zrl=[baseurl]/help/install]Install[/zrl]
[zrl=[baseurl]/help/red2pi]Installing $Projectname on the Raspberry Pi[/zrl]
[zrl=[baseurl]/help/Hubzilla_on_OpenShift]$Projectname on OpenShift[/zrl]
[h3]Taking care of your hub[/h3]
[zrl=[baseurl]/help/troubleshooting]Troubleshooting Tips[/zrl]
[zrl=[baseurl]/help/theme_management]Theme Management[/zrl]
[zrl=[baseurl]/help/hidden_configs]Tweaking $Projectname's Hidden Configurations[/zrl]
[zrl=[baseurl]/help/faq_admins]FAQ For Admins[/zrl]
[zrl=[baseurl]/help/service_classes]Service Classes[/zrl]
[zrl=[baseurl]/help/directories]Working with and configuring Directories[/zrl]
[zrl=[baseurl]/help/theme_management]Theme Management[/zrl]
[h3]Frequently asked questions[/h3]
[zrl=[baseurl]/help/faq_admins]FAQ For Admins[/zrl]
#include doc/macros/main_footer.bb;

View File

@@ -14,6 +14,7 @@
<li>[img float=right]https://zothub.com/images/default_profile_photos/rainbow_man/48.jpg[/img] <img src="https://zothub.com/images/default_profile_photos/rainbow_man/48.jpg" style="float:right;" alt="Image/photo" /><br />
<div style="clear:both;"></div>
<li>[code]code[/code] <code>code</code><br />
<li>[code=xxx]syntax highlighted code[/code] <code>supported languages php, css, mysql, sql, abap, diff, html, perl, ruby, vbscript, avrc, dtd, java, xml, cpp, python, javascript, js, json, sh</code><br />
<li>[quote]quote[/quote] <blockquote>quote</blockquote><br />
<li>[quote=Author]Author? Me? No, no, no...[/quote] <br /><strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote><br />
<li> [nobb] may be used to escape bbcode.</ul><br />
@@ -83,7 +84,7 @@ or<br /><br />[dl terms="b"]<br />[*= First element term] First element descript
<li>[spoiler] for hiding spoilers<br /><br /></li>
<li>[rpost=title]Text to post[/rpost] The observer will be returned to their home hub to enter a post with the specified title and body. Both are optional</li>
<li>[qr]text to post[/qr] - create a QR code.</li>
<li>[qr]text to post[/qr] - create a QR code (if the qrator plugin is installed).</li>
<li>[toc] - create a table of content in a webpage. Please refer to the <a href="http://ndabas.github.io/toc/" target="_blank">original jquery toc</a> to get more explanations.
<ul>
<li>Optional param: 'data-toc'. If ommited the default is 'body'</li>

View File

@@ -1,19 +1,23 @@
[b]Channels[/b]
[h2]Channels[/h2]
[h3]What are channels?[/h3]
Channels are simply collections of content stored in one place. A channel can represent anything. It could represent you, a website, a forum, photo albums, anything. For most people, their first channel with be &quot;Me&quot;.
The most important features for a channel that represents &quot;me&quot; are:
[ul]
[*]Secure and private &quot;spam free&quot; communications
Secure and private &quot;spam free&quot; communications
[*]Identity and &quot;single-signon&quot; across the entire network
Identity and &quot;single-signon&quot; across the entire network
Privacy controls and permissions which extend to the entire network
Directory services (like a phone book)
[*]Privacy controls and permissions which extend to the entire network
[*]Directory services (like a phone book)
[/ul]
In short, a channel that represents yourself is &quot;me, on the internet&quot;.
[h3]Creating channels[/h3]
You will be required to create your first channel as part of the sign up process. You can also create additonal channels from the &quot;Select channel&quot; link.
You will be asked to provide a channel name, and a short nick name. For a channel that represents yourself, it is a good idea to use your real name here to ensure your friends can find you, and connect to your channel. The short nickname will be used to generate a &quot;webbie&quot;. This is a bit like a username, and will look like an email address, taking the form nickname@domain. You should put a little thought into what you want to use here. Imagine somebody asking for your webbie and having to tell them it is &quot;llamas-are_kewl.123&quot;. &quot;llamasarecool&quot; would be a much better choice.
@@ -22,9 +26,14 @@ Once you have created your channel, you will be taken to the settings page, wher
Once you have done this, your channel is ready to use. At [observer=1][observer.url][/observer][observer=0]example.com/channel/username[/observer] you will find your channel &quot;stream&quot;. This is where your recent activity will appear, in reverse chronological order. If you post in the box marked &quot;share&quot;, the entry will appear at the top of your stream. You will also find links to all the other communication areas for this channel here. The &quot;About&quot; tab contains your &quot;profile&quot;, the photos page contain photo albums, and the events page contains events share by both yourself and your contacts.
[h3]The grid, permissions and delegation[/h3]
The &quot;Grid&quot; page contains all recent posts from across the $Projectname network, again in reverse chronologial order. The exact posts that appear here depend largely on your permissions. At their most permissive, you will receive posts from complete strangers. At the other end of the scale, you may see posts from only your friends - or if you're feeling really anti-social, only your own posts.
As mentioned at the start, many other kinds of channel are possible, however, the creation procedure is the same. The difference between channels lies primarily in the permissions assigned. For example, a channel for sharing documents with colleagues at work would probably want more permissive settings for &quot;Can write to my &quot;public&quot; file storage&quot; than a personal account. For more information, see the permissions section.
As mentioned at the start, many other kinds of channel are possible, however, the creation procedure is the same. The difference between channels lies primarily in the permissions assigned. For example, a channel for sharing documents with colleagues at work would probably want more permissive settings for &quot;Can write to my &quot;public&quot; file storage&quot; than a personal account. For more information, see the [zrl=[baseurl]/help/roles]permissions section[/zrl].
You can also delegate control of your channels' posts and connections, but not its configurations, to another channel. That is done by editing a connection and assigning it the permission to administer your channel's resources.
#include doc/macros/main_footer.bb;

View File

@@ -0,0 +1,10 @@
<dl class="dl-horizontal">
<dt>Allgemein</dt>
<dd>Jedes Wiki ist eine Sammlung aus mit Markdown formatierten Seiten.</dd>
<dt><a href="#" onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Click to highlight element...">Wiki Liste</a></dt>
<dd>Wikis die dem eigenen Kanal gehören und <i>mit der Berechtigung zum Anschauen</i>, sind in der Seitenleiste gelistet.</dd>
<dt><a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element...">Seiten Versionen</a></dt>
<dd>Jede Änderung einer Seite wird gespeichert, um eine schnelle Berichtigung zu ermöglichen. Klick auf das <b>Versionsgeschichte</b> Tab um den Verlauf der Seitenbearbeitung zu sehen, einschließlich Datum und Autor. Der Zurück-Knopf lädt die ausgewählte Änderung, aber ohne die Seite automatisch zu spreichern.</dd>
<dt><a href="#" onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Click to highlight element...">Seiten</a></dt>
<dd>Die Seiten des Wikis werden in <b>Wiki Seiten</b> gelistet. Vor dem Speichern einer Seite über das <b>Seiten</b> Dropdown Menu, hast Du die Möglichkeit eine <a href="#" onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Click to highlight element...">Zusammenfassung der Änderungen</a> einzutragen. Dieser Text wird anschließend unter <a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element..."><b>Seiten Versionen</b></a> in der Versionsgeschichte angezeigt.</dd>
</dl>

View File

@@ -0,0 +1,10 @@
<dl class="dl-horizontal">
<dt>General</dt>
<dd>Each wiki is a collection of pages, composed as Markdown-formatted text files.</dd>
<dt><a href='#' onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Click to highlight element...">Wiki List</a></dt>
<dd>Wikis owned by the channel <i>that you have permission to view</i> are listed in the side panel.</dd>
<dt><a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element...">Page History</a></dt>
<dd>Every revision of a page is saved to allow quick reversion. Click the <b>History</b> tab to view a history of page revisions, including the date and author of each. The revert button will load the selected revision but will not automatically save the page.</dd>
<dt><a href='#' onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Click to highlight element...">Pages</a></dt>
<dd>The list of pages in the wiki are listed in the <b>Wiki Pages</b> panel. Prior to saving page edits using the <b>Page</b> control dropdown menu, you may <a href='#' onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Click to highlight element...">enter a custom message</a> to be displayed in the <a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element..."><b>Page History</b></a> viewer along with the revision.</dd>
</dl>

View File

@@ -0,0 +1,10 @@
<dl class="dl-horizontal">
<dt>General</dt>
<dd>Cada wiki es una colección de páginas, compuestas como ficheros de texto formateados en Markdown.</dd>
<dt><a href='#' onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Pulsar para resaltar el elemento...">Lista de wikis</a></dt>
<dd>Las páginas wiki propiedad del canal <i>que esté autorizado a ver</i> aparecen en el panel lateral.</dd>
<dt><a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Pulsar para resaltar el elemento...">Historial de la página</a></dt>
<dd>Cada revisión de una página se salva para permitir su rápida recuperación. Pulsar en la pestaña <b>Historial</b> para ver las revisiones de la página, incluyendo la fecha y el autor de cada una. El botón de reversión cargará la revisión seleccionada, pero no salvará automáticamente la página.</dd>
<dt><a href='#' onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Pulsar para resaltar el elemento...">Páginas</a></dt>
<dd>La lista de páginas en el wiki aparece en el panel <b>Páginas del wiki</b>. Antes de salvar las páginas editadas usando el control <b>Página</b> en el menú desplegable, puede <a href='#' onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Pulsar para resaltar el elemento...">escribir un mensaje personalizado</a> que se verá en el visor <a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Pulsar para resaltar el elemento..."><b>Historial de la página</b></a> junto con la revisión.</dd>
</dl>

View File

@@ -0,0 +1,10 @@
<dl class="dl-horizontal">
<dt>General</dt>
<dd>Ogni wiki è una raccolta di pagine, composta di file di testo formattati con Markdown.</dd>
<dt><a href="#" onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Fai click per evidenziare l'elemento...">Elenco dei Wiki</a></dt>
<dd>I Wiki del canale <i>che sei abilitato a vedere</i> sono elencati nel pannello laterale.</dd>
<dt><a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Fai click per evidenziare l'elemento...">Cronologia della pagina</a></dt>
<dd>Le revisioni di ogni pagina vengono salvate per rendere possibile un ripristino veloce. Fai click sulla tab <b>Cronologia</b> per vedere l'elenco delle revisioni, con autore e data delle stesse. Il bottone di ripristino riporterà alla revisione selezionata, senza salvare automaticamente la pagina.</dd>
<dt><a href="#" onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Fai click per evidenziare l'elemento...">Pagine</a></dt>
<dd>L'elenco delle pagine del wiki si trova nel pannello <b>Pagine del wiki</b>. Prima di salvare le modifiche con il menu a discela <b>Pagina</b>, puoi <a href="#" onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Fai click per evidenziare l'elemento...">inserire un messaggio</a> che verrà visualizzato nella visualizzazione della <a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Fai click per evidenziare l'elemento..."><b>storia della pagina</b></a> insieme alla revisione.</dd>
</dl>

View File

@@ -1,6 +1,7 @@
[h2]Database Tables[/h2]
[table]
[tr][th]Table[/th][th]Description[/th][/tr]
[tr][td][zrl=[baseurl]/help/database/db_abconfig]abconfig[/zrl][/td][td]arbitrary storage for connections of local channels[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_abook]abook[/zrl][/td][td]connections of local channels[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_account]account[/zrl][/td][td]service provider account[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_addon]addon[/zrl][/td][td]registered plugins[/td][/tr]
@@ -8,6 +9,7 @@
[tr][td][zrl=[baseurl]/help/database/db_attach]attach[/zrl][/td][td]file attachments[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_auth_codes]auth_codes[/zrl][/td][td]OAuth usage[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_cache]cache[/zrl][/td][td]OEmbed cache[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_cal]cal[/zrl][/td][td]CalDAV containers for events[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_channel]channel[/zrl][/td][td]local channels[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_chat]chat[/zrl][/td][td]chat room content[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_chatpresence]chatpresence[/zrl][/td][td]channel presence information for chat[/td][/tr]
@@ -16,17 +18,14 @@
[tr][td][zrl=[baseurl]/help/database/db_config]config[/zrl][/td][td]main configuration storage[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_conv]conv[/zrl][/td][td]Diaspora private messages meta conversation structure[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_event]event[/zrl][/td][td]Events[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_fcontact]fcontact[/zrl][/td][td]friend suggestion stuff (obsolete)[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_ffinder]ffinder[/zrl][/td][td]friend suggestion stuff (obsolete)[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_fserver]fserver[/zrl][/td][td]obsolete[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_fsuggest]fsuggest[/zrl][/td][td]friend suggestion stuff (unused)[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_group_member]group_member[/zrl][/td][td]privacy groups (collections), group info[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_groups]groups[/zrl][/td][td]privacy groups (collections), member info[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_hook]hook[/zrl][/td][td]plugin hook registry[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_hubloc]hubloc[/zrl][/td][td]xchan location storage, ties a hub location to an xchan[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_iconfig]iconfig[/zrl][/td][td]extensible arbitrary storage for items[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_issue]issue[/zrl][/td][td]future bug/issue database[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_item]item[/zrl][/td][td]all posts and webpages[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_item_id]item_id[/zrl][/td][td]other identifiers on other services for posts[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_item_id]item_id[/zrl][/td][td](deprecated by iconfig) other identifiers on other services for posts[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_likes]likes[/zrl][/td][td]likes of 'things'[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_mail]mail[/zrl][/td][td]private messages[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_menu]menu[/zrl][/td][td]webpage menu data[/td][/tr]
@@ -48,7 +47,6 @@
[tr][td][zrl=[baseurl]/help/database/db_sign]sign[/zrl][/td][td]Diaspora signatures. To be phased out.[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_site]site[/zrl][/td][td]site table to find directory peers[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_source]source[/zrl][/td][td]channel sources data[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_spam]spam[/zrl][/td][td]unfinished[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_sys_perms]sys_perms[/zrl][/td][td]extensible permissions for OAuth[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_term]term[/zrl][/td][td]item taxonomy (categories, tags, etc.) table[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_tokens]tokens[/zrl][/td][td]OAuth usage[/td][/tr]
@@ -60,6 +58,7 @@
[tr][td][zrl=[baseurl]/help/database/db_xconfig]xconfig[/zrl][/td][td]as pconfig but for channels with no local account[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_xign]xign[/zrl][/td][td]channels ignored by friend suggestions[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_xlink]xlink[/zrl][/td][td]"friends of friends" linkages derived from poco, also ratings storage[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_xperm]xperm[/zrl][/td][td]OAuth/OpenID-Connect extensible permissions permissions storage[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_xprof]xprof[/zrl][/td][td]if this hub is a directory server, contains basic public profile info of everybody in the network[/td][/tr]
[tr][td][zrl=[baseurl]/help/database/db_xtag]xtag[/zrl][/td][td]if this hub is a directory server, contains tags or interests of everybody in the network[/td][/tr]
[/table]

View File

@@ -15,10 +15,6 @@
[/td][/tr]
[tr][td]abook_closeness[/td][td]"closeness" value for optional affinity tool, 0-99[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]99[/td][td]
[/td][/tr]
[tr][td]abook_rating[/td][td]The channel owner's (public) rating of this connection -10 to +10, default 0 or unrated[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_rating_text[/td][td]The channel owner's (public) rating of this connection free form text[/td][td]text[/td][td]NO[/td][td]MUL[/td][td][/td][td]
[/td][/tr]
[tr][td]abook_created[/td][td]Datetime this record was created[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
[/td][/tr]
[tr][td]abook_updated[/td][td]Datetime this record was modified[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
@@ -32,16 +28,27 @@
[tr][td]abook_profile[/td][td]profile.guid of profile to display to this connection if authenticated[/td][td]char(64)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
[/td][/tr]
[tr][td]abook_blocked[/td][td]Bi-directional communications with this channel are blocked, regardless of other permissions. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_ignored[/td][td]Incoming communications from this channel are blocked, regardless of other permissions. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_hidden[/td][td]This connection will not be shown as a connection to anybody but the channel owner[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_archived[/td][td]This connection is likely non-functioning and the entry and conversations are preserved, but further polled communications will not be attempted. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_pending[/td][td]A connection request was received from this channel but has not been approved by the channel owner, public communications may still be visible but no additional permissions have been granted. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_unconnected[/td][td]currently unused. Projected usage is to indicate "one-way" connections which were insitgated on this end but are still pending on the remote end. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_self[/td][td]is a special case where the owner is the target. Every channel has one abook entry with abook_self and with a target abook_xchan set to channel.channel_hash . When this flag is present, abook_my_perms is the default permissions granted to all new connections and several other fields are unused.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_feed[/td][td]indicates this connection is an RSS/Atom feed and may trigger special handling.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_incl[/td][td]connection filter allow rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_excl[/td][td]connection filter deny rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]abook_instance[/td][td]comma separated list of site urls of all channel clones that this connection is connected with (used only for singleton networks which don't support cloning)[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[/table]

View File

@@ -3,7 +3,7 @@
[/th][/tr]
[tr][td]id[/td][td][/td]generated index[td]int(11)[/td][td]NO[/td][td]PRI[/td][td]NULL[/td][td]auto_increment
[/td][/tr]
[tr][td]name[/td][td]plugin base (file)name[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
[tr][td]aname[/td][td]plugin base (file)name[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
[/td][/tr]
[tr][td]version[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
[/td][/tr]
@@ -11,7 +11,7 @@
[/td][/tr]
[tr][td]hidden[/td][td]currently unused[/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]timestamp[/td][td]file timestamp to check for reloads[/td][td]bigint(20)[/td][td]NO[/td][td][/td][td]0[/td][td]
[tr][td]tstamp[/td][td]file timestamp to check for reloads[/td][td]bigint(20)[/td][td]NO[/td][td][/td][td]0[/td][td]
[/td][/tr]
[tr][td]plugin_admin[/td][td]1 = has admin config, 0 = has no admin config[/td][td]tinyint(1)[/td][td]NO[/td][td][/td][td]0[/td][td]
[/td][/tr]

View File

@@ -27,8 +27,20 @@
[/td][/tr]
[tr][td]app_page[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[tr][td]app_requires[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
[tr][td]app_requires[/td][td]access rules[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[tr][td]app_created[/td][td]datetime of app creation[/td][td]datetime[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[tr][td]app_edited[/td][td]datetime of last app edit[/td][td]datetime[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[tr][td]app_deleted[/td][td]1 = deleted, 0 = normal[/td][td]int(11)[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[tr][td]app_system[/td][td]1 = imported system app, 0 = member created app[/td][td]int(11)[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[/table]
Storage for personal apps

View File

@@ -29,9 +29,11 @@
[/td][/tr]
[tr][td]os_storage[/td][td]if 0, data contains content; if 1 data contains path to content (always 1 in hubzilla)[/td][td]tinyint[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]os_path[/td][td]under construction, store the system path[/td][td]mediumtext[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]display_path[/td][td]under construction, store the human readable path[/td][td]mediumtext[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
[/td][/tr]
[tr][td]data[/td][td]file data or pathname to stored data if ATTACH_FLAG_OS[/td][td]longblob[/td][td]NO[/td][td][/td][td]NULL[/td][td]
[tr][td]content[/td][td]file data or pathname to stored data if ATTACH_FLAG_OS[/td][td]longblob[/td][td]NO[/td][td][/td][td]NULL[/td][td]
[/td][/tr]
[tr][td]created[/td][td]creation time[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
[/td][/tr]

View File

@@ -35,6 +35,8 @@
[/td][/tr]
[tr][td]channel_dirdate[/td][td]time when directory was last pinged. Must do this once a month[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
[/td][/tr]
[tr][td]channel_lastpost[/td][td]date of last post for this channel. May not be fully implemented[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
[/td][/tr]
[tr][td]channel_deleted[/td][td]time when channel was deleted[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
[/td][/tr]
[tr][td]channel_max_anon_mail[/td][td]unused[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]10[/td][td]
@@ -95,6 +97,8 @@
[/td][/tr]
[tr][td]channel_system[/td][td]if 1, this is the special system channel on this site[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]128[/td][td]
[/td][/tr]
[tr][td]channel_moved[/td][td]URL of relocated channel, making this instance abandoned if set[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
[/td][/tr]
[/table]
Return to [zrl=[baseurl]/help/database]database documentation[/zrl]

View File

@@ -11,7 +11,7 @@
[/td][/tr]
[tr][td]cp_status[/td][td]text status description e.g. "online"[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
[/td][/tr]
[tr][td]cp_client[/td][td][/td]IP address of this client[td]char(128)[/td][td]NO[/td][td][/td][td][/td][td]
[tr][td]cp_client[/td][td]IP address of this client[/td][td]char(128)[/td][td]NO[/td][td][/td][td][/td][td]
[/td][/tr]
[/table]

View File

@@ -7,7 +7,7 @@
[/td][/tr]
[tr][td]redirect_uri[/td][td][/td][td]varchar(200)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
[/td][/tr]
[tr][td]name[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
[tr][td]clname[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
[/td][/tr]
[tr][td]icon[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
[/td][/tr]

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