Compare commits

...

612 Commits
1.2 ... 1.4

Author SHA1 Message Date
redmatrix
a29c0371f1 commit 1.4 2016-04-14 20:11:36 -07:00
redmatrix
a8f7af2079 provide general purpose verification class, remove include/session.php (no longer used) 2016-04-14 18:51:06 -07:00
redmatrix
7ae7fac234 Merge branch 'master' into dev 2016-04-14 17:35:47 -07:00
redmatrix
d1fb4e9b03 revup #337 2016-04-14 17:34:08 -07:00
redmatrix
ed0bff798b fix marked bug in code 2016-04-13 22:58:37 -07:00
redmatrix
3f0bb1bb1d Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-13 16:37:10 -07:00
redmatrix
9a0b61e4af refactor the js detection into a checkjs class which is only enabled on demand (currently only the channel and display pages). Will probably require a bit more work to hide/disable the cover photo when js is disabled. Have not actually tested without js to discover any other potential page issues. Have only confirmed that the detection class works and redirects to set a jsdisabled cookie and reload the page with that cookie+variable set if called from the channel page. 2016-04-13 16:31:06 -07:00
Mario Vavti
b81291cd5c some bbcode autocomplete refinement for edit webpage 2016-04-13 11:56:43 +02:00
redmatrix
a8a0ca8291 Merge branch 'master' into dev 2016-04-13 01:02:23 -07:00
redmatrix
1c61be4113 issue #337 2016-04-13 01:01:01 -07:00
redmatrix
91cc365143 reverse the logic of the jsenabled setting so that sessions without js are performance penalised instead of regular sessions. 2016-04-12 22:55:26 -07:00
redmatrix
f4a27afee9 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-12 19:42:02 -07:00
redmatrix
be654f1769 Important work on the sessionhandler to maintain compatibility with php7 and php5x (x > 4)
Merge branch 'master' into dev
2016-04-12 19:40:19 -07:00
redmatrix
73628db7e2 revup issue #337 2016-04-12 18:43:50 -07:00
Mario Vavti
571c72f853 improve bbco autocomplete to not execute listNewLineAutocomplete() many times after many ajax page reloads 2016-04-12 11:55:50 +02:00
redmatrix
b788b38edf remove obsolete jotVideoURL() and jotAudioURL() 2016-04-11 21:40:03 -07:00
redmatrix
09861abab7 when saving bookmarks from a post allow choice of bookmark to be saved (default is all of them); this implements the backend. Additional work will be required on the front end or within plugins to make this happen. 2016-04-11 20:53:08 -07:00
redmatrix
202035fc68 move all DB session storage logic to SessionHandler where it belongs 2016-04-11 19:19:58 -07:00
redmatrix
5ab1d509d2 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-11 13:04:17 -07:00
redmatrix
1b83d88fe6 remove references to ref_session_write - can't use 2016-04-11 13:03:34 -07:00
Mario Vavti
482962648f whitespace 2016-04-11 11:01:53 +02:00
redmatrix
326f3cfc85 Merge branch 'master' into dev 2016-04-11 00:52:34 -07:00
redmatrix
4ba8526745 revup 2016-04-11 00:50:50 -07:00
redmatrix
0269825bc0 localise the opensearch link 2016-04-10 21:56:16 -07:00
redmatrix
5cb3143c04 issue #331 use timeago.js for reshared publish date instead of relative_date() which does not play well with other networks. 2016-04-10 21:30:35 -07:00
redmatrix
d1a2aecfa0 move more session related stuff such as paranoia handling (IP address changes) into the session object and extend remember_me cookies once a day so that they will never expire (theoretically). The DB session driver will extend its expiration on every session write (in the case of persistent sessions). 2016-04-10 19:20:41 -07:00
redmatrix
0fe4957274 when setting the session handler as an object using the auto register shutdown flag, explicitly calling session_write_close() should no longer be required. It shouldn't cause any issues if it is called twice, but the session driver interface has been known to sometimes act in unexpected ways and there are lots of "subtleties" which can often be difficult to debug. The mentioned flag implies PHP 5.4 minimum but I believe we require that anyway. 2016-04-10 17:42:32 -07:00
redmatrix
e9f1bac062 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-10 17:03:30 -07:00
redmatrix
58692e3565 Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-04-10 17:02:26 -07:00
redmatrix
7db733c9a0 revup 2016-04-10 17:02:08 -07:00
redmatrix
abfbe9c937 a few issues: block public not blocking mod_cal, typo in sql for one clone file sync operation, fix_system_urls not catching cached contact photos, extend sessionhandler expiration when remember_me is enabled as the stored session is expiring long before the browser session. 2016-04-10 16:56:08 -07:00
jeroenpraat
f437705007 Update Dutch and Spanish 2016-04-10 20:58:00 +02:00
Mario Vavti
46ed79c87a fix autocomplete for /channel and /display 2016-04-09 12:27:36 +02:00
Mario Vavti
e2b4d33627 some work on comanche autocomplete 2016-04-09 12:16:42 +02:00
Mario Vavti
7690dca67b enable bbcode autocomplete for other places 2016-04-09 09:24:14 +02:00
redmatrix
c0bdcfedeb log if the session handler fails and surface the ssl_cookie config setting 2016-04-08 05:10:36 -07:00
redmatrix
9b66b5eee3 objectify all the session management stuff 2016-04-08 04:44:10 -07:00
redmatrix
2db59f3b76 Merge branch 'master' into dev 2016-04-08 03:32:28 -07:00
redmatrix
44e21f6198 revup 2016-04-08 03:31:32 -07:00
redmatrix
279f32b13d send file sync packets for all known file operations 2016-04-07 18:54:48 -07:00
redmatrix
3a6187af3d implement updates of attach data to sync'd clones. 2016-04-07 16:44:53 -07:00
redmatrix
516f776c94 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-07 16:25:16 -07:00
redmatrix
cc62793d6f Merge branch 'master' into dev 2016-04-07 16:24:59 -07:00
redmatrix
d87daaedd1 revup issue #337 2016-04-07 16:23:57 -07:00
Mario Vavti
cf84ff3344 translate the most common bbcodes to their *real name*. finally we should probably use an array for each bbcode containing the bbcode the real name and possibly a template for use as a peview in the dropdown 2016-04-07 23:03:55 +02:00
Mario Vavti
e419b2c18c some more autocompletion for bbcode tables - leave it open if we wanna use th or td though 2016-04-07 11:34:38 +02:00
Mario Vavti
58324473a9 move li back in the list since it will be used far less than list 2016-04-07 11:16:30 +02:00
redmatrix
62d842de31 Merge branch 'master' into dev 2016-04-06 22:23:07 -07:00
redmatrix
aa678ba0ff reset profile photo and cover photo bits for existing photos if a new one arrives from a clone 2016-04-06 22:14:05 -07:00
redmatrix
e4391e6336 missing profile photo in export data 2016-04-06 21:36:47 -07:00
redmatrix
aa0412d83b use the explicit form of build_sync_packet so that file/photo sync will work even when the actual observer is a guest (with permission to upload). 2016-04-06 20:25:52 -07:00
redmatrix
861f5232d3 more work on file sync to clones, 60-70% test coverage, mostly working but many changes made during testing which themselves have not yet been tested 2016-04-06 19:56:38 -07:00
redmatrix
9831ad515d file sync testing continued 2016-04-06 18:46:29 -07:00
redmatrix
6650916435 file sync testing 2016-04-06 18:38:48 -07:00
redmatrix
64cc0b794a Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-06 18:08:06 -07:00
redmatrix
29363a185d file sync work 2016-04-06 18:07:29 -07:00
Mario Vavti
e41082dccc automate bbcode list creation even further 2016-04-07 00:46:45 +02:00
Mario Vavti
97ccbf1bfb adjust the regex to also work with asteriks and use the simpler syntax for lists 2016-04-06 22:18:59 +02:00
redmatrix
a20ef706fd issue #340 2016-04-06 05:44:40 -07:00
redmatrix
adad8f2ebc getting file sync data - missed parent folder 2016-04-06 05:20:55 -07:00
redmatrix
0533db5d38 revup issue #337 2016-04-06 02:33:58 -07:00
redmatrix
fb9c12df15 rework the "remember me" fix to be a bit less hackish 2016-04-06 02:33:11 -07:00
redmatrix
5a2a8717e3 provide function to collect file/photo sync data per help/filesync 2016-04-05 23:11:24 -07:00
redmatrix
0d50d29538 Merge branch 'master' into dev 2016-04-05 22:15:29 -07:00
redmatrix
54aa998b52 undeclared static property App::$stringsave (push_lang() and pop_lang()) 2016-04-05 22:13:56 -07:00
redmatrix
10f1e2d51b add some doco to getfile module 2016-04-05 21:20:23 -07:00
redmatrix
9fd8634b62 server side of file/photo sync to deliver the file data. We'll sign it using our channel_hash and the current time to make it difficult to forge a request; as the sync process is not going to have magic-auth ability. 2016-04-05 21:10:08 -07:00
redmatrix
fd07940b10 provide stream resource pointer option to z_fetch_url() and z_post_url() per earlier doco commit on syncing files/photos across clones. 2016-04-05 18:24:24 -07:00
redmatrix
6f6051f7e3 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-05 16:44:11 -07:00
redmatrix
f9778fda83 add some doco on some of the issues and approaches to file/photo syncing and cloning 2016-04-05 16:42:33 -07:00
redmatrix
ea3fb53e4b Merge pull request #339 from anaqreon/autocomplete
Improve (un)ordered list autocompletion for list construction
2016-04-06 06:07:32 +10:00
redmatrix
a7d5bf6854 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-05 12:51:22 -07:00
redmatrix
0e7a963173 Merge branch 'master' into dev 2016-04-05 12:51:06 -07:00
redmatrix
4aa2733699 revup issue #337 2016-04-05 12:49:58 -07:00
Andrew Manning
1eb6067c31 Improve (un)ordered list autocompletion for list construction 2016-04-05 14:46:16 -04:00
Mario Vavti
bd29551f9a fix contextual help 2016-04-05 16:59:32 +02:00
Mario Vavti
32ccdd1f57 use min version of justifiedGallery 2016-04-05 15:28:39 +02:00
Mario Vavti
deaf0e99fd expand list of bbcode in autocomplete 2016-04-05 15:27:45 +02:00
Mario Vavti
d99a1d8de0 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-04-05 15:24:42 +02:00
Mario Vavti
0012030826 update upstream lib jusutifiedGallery 2016-04-05 15:24:05 +02:00
redmatrix
ec41170121 Merge pull request #338 from anaqreon/contextual-help
Contextual help
2016-04-05 22:43:15 +10:00
redmatrix
1d5ea5efae explain the two aspects of federation which need to be handled in core to pass comments successfully amongst sites which optionally provide federation. Let's hope this list doesn't grow. 2016-04-04 17:02:27 -07:00
redmatrix
01ad485f65 SECURITY: Do not link unknown and unverified code repositories to the project without some form of confirmation that one accepts the significant risks involved. 2016-04-04 16:17:50 -07:00
redmatrix
447c59fd9b Merge branch 'master' into dev 2016-04-04 13:32:58 -07:00
redmatrix
3de40bdf04 Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-04-04 13:31:31 -07:00
redmatrix
ba6c346b46 revup - issue #337 2016-04-04 13:30:59 -07:00
Mario Vavti
1c9f773900 Merge branch 'master' into dev 2016-04-04 17:13:10 +02:00
Mario Vavti
ec651f219e a simple autocomplete for bbcode or comanche - partly implemented 2016-04-04 17:12:23 +02:00
Mario Vavti
ee8a9384d5 Merge branch 'master' into dev 2016-04-04 10:37:20 +02:00
Mario Vavti
bba34a7a8e do not use dropdown class if there is nothing to dropdown 2016-04-04 10:37:07 +02:00
Mario Vavti
dfa12b2919 Merge branch 'master' into dev 2016-04-04 10:13:30 +02:00
Mario Vavti
9b9f29a0b2 whitespace 2016-04-04 10:10:19 +02:00
Mario Vavti
4a9aad2a33 whitespace 2016-04-04 10:09:46 +02:00
Mario Vavti
69617b5c34 fullscreen mode for photo albums view 2016-04-04 10:09:13 +02:00
redmatrix
222ace3770 For GNU-social discovery, use the URI in the feed (author.uri) rather than try to pick out which of the aliases in webfinger are likely to be the right one. If we get it wrong, our communications with them will be discarded and there is no rhyme or reason to the logic about which representation is likely to be the one true account URI. It appears to vary with the clean_url setting of the site and this info isn't available to us except with a sequence of expensive probes and testing various ways of re-writing URLs to see if we get a response. 2016-04-03 20:55:38 -07:00
redmatrix
2e7d2a63c3 provide a backup copy of prior notes widget content if the contents were just nuked. 2016-04-03 19:34:19 -07:00
Andrew Manning
0523b4b2f1 Merge branch 'master' of https://github.com/redmatrix/hubzilla into contextual-help 2016-04-03 21:36:29 -04:00
redmatrix
a703835b5c Bug: "remember me" doesn't 2016-04-03 17:38:17 -07:00
redmatrix
bf3f3564e0 issue #138 ; make ajaxchat optional and configurable. For reasons we've discussed repeatedly the ajax chat will not be removed from core as XMPP chat does not provide decentralised access control compatible with nomadic identity. 2016-04-03 16:41:40 -07:00
redmatrix
102d41ccb9 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-03 16:17:54 -07:00
redmatrix
cfad5ba8b8 Merge branch 'master' into dev 2016-04-03 16:17:31 -07:00
redmatrix
b4c1baada1 Merge branch 'master' of https://github.com/redmatrix/hubzilla into master_merge 2016-04-03 16:16:14 -07:00
redmatrix
1ca3eeedff issue #337 2016-04-03 16:15:41 -07:00
Mario Vavti
298b53e93a Merge branch 'master' into dev 2016-04-03 18:00:25 +02:00
Mario Vavti
f13096a6f3 various fixes 2016-04-03 18:00:03 +02:00
Mario Vavti
470f14b919 Merge branch 'master' into dev 2016-04-03 15:27:26 +02:00
Mario Vavti
53311a30ad reduce chat-item-title fontsize to match wall-item-ago 2016-04-03 15:27:10 +02:00
Mario Vavti
5634a4bb61 Merge branch 'master' into dev 2016-04-03 14:56:52 +02:00
Mario Vavti
738e14348d update upstream libs fullcalendar and moment to a recent version 2016-04-03 14:56:19 +02:00
Mario Vavti
787e2ef961 Merge branch 'master' into dev 2016-04-03 12:20:10 +02:00
Mario Vavti
db4e9aeaad fullscreen mode for events 2016-04-03 12:19:49 +02:00
Mario Vavti
7850b04853 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev 2016-04-03 11:35:47 +02:00
Mario Vavti
b6f18a9a0b Merge branch 'master' into dev 2016-04-03 11:35:06 +02:00
Mario Vavti
b8d8be7013 show chat expiration time in overview and minor fixes 2016-04-03 11:34:07 +02:00
redmatrix
84feff9500 Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge 2016-04-02 21:09:05 -07:00
redmatrix
81ba293561 Merge branch 'master' into dev 2016-04-02 21:07:34 -07:00
redmatrix
8b3c099a12 use constant 2016-04-02 21:06:41 -07:00
Mario Vavti
2772a72095 ge branch 'master' into dev 2016-04-03 00:19:30 +02:00
Mario Vavti
e361ee9253 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-04-03 00:04:30 +02:00
Mario Vavti
3edd4ce78f ease transition between fullscreen and inline view for small screens 2016-04-03 00:04:05 +02:00
redmatrix
381cc3e6f8 Merge branch 'master' into dev 2016-04-02 13:54:49 -07:00
redmatrix
d09694587d typo in router 2016-04-02 13:52:16 -07:00
redmatrix
63451db3f6 small changes in README.md 2016-04-02 01:47:46 -07:00
redmatrix
7660afdb0f revup 2016-04-02 00:28:51 -07:00
jeroenpraat
72d995d35f Update nl and es-es strings 2016-04-01 23:24:13 +02:00
redmatrix
2a32df75f1 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-04-01 03:27:46 -07:00
redmatrix
e16da7a166 unreferenced app member 2016-04-01 03:27:21 -07:00
Mario Vavti
5b55726a93 on update only jump to bottom if we actually got a new message 2016-04-01 11:13:04 +02:00
Mario Vavti
bbe93d0e1d scroll chat to bottom on fullscreen toggle 2016-04-01 10:29:58 +02:00
Mario Vavti
5dd422e2d8 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-04-01 10:20:26 +02:00
Mario Vavti
a564f495a7 improve scroll to bottom in chat 2016-04-01 10:20:10 +02:00
redmatrix
995555f357 ditto for typohelper 2016-04-01 01:04:37 -07:00
redmatrix
40f3857691 change call to App::init() to bring back include path (only in typocheck) 2016-04-01 01:02:03 -07:00
redmatrix
5d884c2f3d suddenly we have includepath issues - provide the explicit paths 2016-04-01 00:59:30 -07:00
redmatrix
8f006a98c4 primary hub change 2016-04-01 00:54:23 -07:00
Mario Vavti
ebac0bdcca Chat Rooms -> Chatrooms 2016-04-01 09:46:41 +02:00
Mario Vavti
3575ef8a39 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-04-01 08:57:05 +02:00
Mario Vavti
60bb8f25f7 move fullscreen js code to redbasic.js where it belongs to 2016-04-01 08:56:51 +02:00
redmatrix
2d3dd673e4 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-31 23:41:41 -07:00
redmatrix
9d47de65d9 undeclared static vars 2016-03-31 23:41:20 -07:00
Mario Vavti
c6d9100649 missing template 2016-04-01 08:36:02 +02:00
redmatrix
44283dbbbb change the App constructor 2016-03-31 20:24:30 -07:00
redmatrix
0cda431456 create miniApp to convert existing settings files to the static App class 2016-03-31 20:15:47 -07:00
redmatrix
bbfe4de310 increment std_version 2016-03-31 18:57:44 -07:00
redmatrix
36b388ab8c issue #336 2016-03-31 18:53:05 -07:00
redmatrix
c0b3d7e1b4 Merge branch 'static' 2016-03-31 17:32:51 -07:00
redmatrix
9abd95fad3 static App 2016-03-31 16:06:03 -07:00
Mario Vavti
50d9b29347 slightly change the way fullscreen works and bring it to mod mail 2016-04-01 00:16:39 +02:00
Mario Vavti
90a5ba01a3 make fullscreen mode available for other modules and some cleanup 2016-03-31 23:13:40 +02:00
Mario Vavti
6c2673ae2a various fixes regarding mod chat 2016-03-31 22:42:28 +02:00
redmatrix
256c228efd initial conversion to static app class 2016-03-31 13:00:04 -07:00
Mario Vavti
3fdd110e07 mod chat rework continued 2016-03-31 13:21:48 +02:00
redmatrix
1cd3b41825 deprecate $a->get_baseurl() 2016-03-30 22:13:24 -07:00
redmatrix
4148211086 change primary directory 2016-03-30 18:37:37 -07:00
redmatrix
4ba9a5ef75 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-30 16:39:08 -07:00
redmatrix
6a6dbec033 issue #319 - NOTE: this does not fix the issue, it only reports it and continues. We need to examine any logger statements that contain 'stack:' as a result of reporting this issue and find and fix the original problem - which is that set_pconfig is being called without a valid $uid. I'm worried that since we will now continue on without throwing a PHP error that nobody will ever notice or find the problem that is causing this. 2016-03-30 16:33:23 -07:00
Mario Vavti
df891f4ad2 more work on mod chat 2016-03-31 00:37:40 +02:00
Mario Vavti
08461c7049 more on mod chat 2016-03-30 14:44:03 +02:00
Mario Vavti
5462453bf2 some work on mod chat 2016-03-30 14:31:55 +02:00
redmatrix
e4f3605054 add page title to the html title 2016-03-29 14:14:17 -07:00
redmatrix
f65ede9c38 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-28 16:08:31 -07:00
redmatrix
a6ad37c691 revup 2016-03-28 16:08:11 -07:00
Mario Vavti
ba0812c447 highlight table row on hover 2016-03-27 22:37:07 +02:00
jeroenpraat
dbde9a0940 Update es_es+n. Switch the feeds as requested by Mike. 2016-03-27 14:03:02 +02:00
redmatrix
d3f38c9f43 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-26 14:34:19 -07:00
redmatrix
971e7321c6 issue #319 part 2 2016-03-26 14:33:36 -07:00
jeroenpraat
eeb1c463e3 Small, but I think useful hack. Added a top posts only atom feed, so people can choose directly from their browser which feed they need. 2016-03-26 22:32:46 +01:00
Andrew Manning
99d9456b3a More help content for channel pages. Channel, photos, files, about. 2016-03-26 14:55:16 -04:00
Mario Vavti
97eef2b88c removed link to connected apps by accident 2016-03-26 19:34:38 +01:00
Andrew Manning
c25ef1d9a8 Search docs/context/ hierarchically for help.html files to reduce redundancy 2016-03-26 14:31:41 -04:00
Andrew Manning
661b0084f3 Added help for post permissions 2016-03-26 14:17:53 -04:00
Mario Vavti
f714e97d63 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-26 18:46:07 +01:00
Mario Vavti
a507063174 move link to /locs to settings menu if we have more than one location and some template work on locs 2016-03-26 18:43:38 +01:00
git-marijus
3caf51b075 Merge pull request #333 from phellmes/de20160324
Update DE translation strings
2016-03-25 10:26:12 +01:00
redmatrix
92ec46b62e revup 2016-03-24 19:18:25 -07:00
phellmes
9b06d952a2 Update DE translation strings 2016-03-24 09:08:12 +01:00
redmatrix
531710142c add hook to allow plugins to perform a follow activity from an activityfeed 2016-03-23 20:04:09 -07:00
Andrew Manning
59827b6dfd Merge branch 'master' of https://github.com/redmatrix/hubzilla into contextual-help 2016-03-23 21:17:23 -04:00
Andrew Manning
61bef7d4b0 Network page help with auto-scroll and element highlighting 2016-03-23 21:16:21 -04:00
redmatrix
f200dd4395 atom specifies a uri or iri for the id. message_id isn't suitable here. 2016-03-23 16:36:27 -07:00
redmatrix
a8ac0ed549 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-22 19:59:47 -07:00
redmatrix
6f2ba0c619 rewrite the webfinger discovery logic 2016-03-22 19:58:59 -07:00
Wave
0a14ac1f60 Merge pull request #332 from wave72/master
Updated Italian strings
2016-03-22 11:53:57 +01:00
Paolo Tacconi
02140b2f76 Updated Italian strings 2016-03-22 11:49:03 +01:00
Mario Vavti
c6b89b99b9 Add a link to /locs to channel manager 2016-03-22 10:29:17 +01:00
redmatrix
51a840f46a update network_to_name (reserve DFRN for future use) 2016-03-21 22:02:18 -07:00
redmatrix
b081c3e94b Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-21 21:32:35 -07:00
redmatrix
ec99e3ed62 attempting to work with braindead lighttpd gnusocial servers 2016-03-21 21:31:28 -07:00
Mario Vavti
97e1a6dfde whip mod manage into shape 2016-03-22 02:06:19 +01:00
Andrew Manning
56c86b6567 Override navbar help button to open contextual help panel. Contextual help for mail written. 2016-03-21 06:33:02 -04:00
redmatrix
28599fe652 more federation work 2016-03-20 21:41:19 -07:00
redmatrix
d3e7ef70e8 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-20 19:56:36 -07:00
redmatrix
fea532af4d rework salmon - important, update addons also if you have enabled gnusoc addon 2016-03-20 19:55:53 -07:00
Mario Vavti
f5b22dfd5b erge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-21 00:41:09 +01:00
redmatrix
48e62bb50a Merge pull request #329 from git-marijus/master
fix #328 by using a seperate query instead of group_concat
2016-03-21 10:22:30 +11:00
Mario Vavti
513078e1f7 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-20 23:52:55 +01:00
redmatrix
23151100de Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-20 15:32:09 -07:00
redmatrix
eb68b66c58 issue #330 - permit archived connections in ACLs. If they are to be blocked for delivery (or some other purpose) this should probably happen in the delivery mechanism (or other related sub-system) rather than the permissions mechanism, although currently we still attempt direct delivery to archived connections. Technically "archived" means merely that we won't 'poll' the connection according to the current definition. 2016-03-20 15:27:26 -07:00
Mario Vavti
1ddb43b0d3 an attempt to visualize the supremacy of dont show over show in the acl selector 2016-03-20 23:07:39 +01:00
Mario Vavti
9fcd470aca fix #328 by using a seperate query instead of group_concat 2016-03-20 20:26:55 +01:00
jeroenpraat
23419e4c26 Update NL + es_ES strings. 2016-03-20 14:39:22 +01:00
Mario Vavti
34b42566b6 add fixme 2016-03-20 02:25:59 +01:00
Mario Vavti
f7ff48f806 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-20 01:46:13 +01:00
Mario Vavti
30cf56bdb5 make >>indicate group members<< in acl selector work again on group > show or group > dont show is selected 2016-03-20 01:45:56 +01:00
redmatrix
77094f8d2b make the admin side menu extensible and provide a hook for a channel "move" operation that federation plugins might use to re-establish connections after a channel move. 2016-03-19 16:17:19 -07:00
Mario Vavti
51cd4e8519 missing return false for map link 2016-03-19 02:20:59 +01:00
Mario Vavti
bd249b276d add use as cover photo link to photos view 2016-03-18 17:49:31 +01:00
redmatrix
b6ae2bff01 change rev 2016-03-17 18:42:32 -07:00
redmatrix
21c1f89eba SECURITY: DAV authentication issue 2016-03-17 18:40:03 -07:00
redmatrix
df61970b39 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-17 12:16:25 -07:00
redmatrix
f82afca84d no xchan here if using zot protocol 2016-03-17 12:15:28 -07:00
jeroenpraat
eca119d695 See issue https://github.com/redmatrix/hubzilla-addons/issues/17 (UNO: enable the Diaspora protocol for all channels (if addon is enabled) - I had to do this during channel creation and not in the addon itself, or else the member can't change this after the channel is created. Tested it on UNO and normal Hubzilla. If this is not the right place for this, please move it. If not wanted at all, please discuss. 2016-03-17 15:48:44 +01:00
Mario Vavti
40162cd6b7 some work on profile listing 2016-03-17 12:56:55 +01:00
Mario Vavti
a41a05e6c0 bring more structure to profiles edit 2016-03-17 11:50:53 +01:00
redmatrix
a83cdbeb39 typo 2016-03-16 22:02:19 -07:00
redmatrix
6d4fe5c56f Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-16 21:06:15 -07:00
redmatrix
3a8f6e6576 more federation backend 2016-03-16 21:05:52 -07:00
redmatrix
38eb79705e lots of work on federated channel discovery 2016-03-16 18:00:13 -07:00
git-marijus
f7ddd44c2e Merge pull request #327 from anaqreon/ownmapp-typo
Misspelling of ownMapp in homeinstall script
2016-03-16 23:10:24 +01:00
Mario Vavti
2165733ddc move buttons to dropdown menu and some cleanup 2016-03-16 23:07:29 +01:00
Mario Vavti
d22b21c56f still more janitor work on profiles 2016-03-16 13:45:24 +01:00
redmatrix
4188419b30 more federation backend work 2016-03-15 17:54:06 -07:00
Mario Vavti
d98d7003ed even more janitor work on profiles 2016-03-15 21:38:03 +01:00
Andrew Manning
1692380ac7 Misspelling of ownMapp 2016-03-15 10:54:45 -04:00
redmatrix
01a28ddf8d Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-15 01:32:41 -07:00
redmatrix
e8d19659c0 some heavy lifting porting the old salmon code 2016-03-15 00:50:03 -07:00
redmatrix
b673b6835d federation work 2016-03-14 22:14:17 -07:00
redmatrix
ef7494359f some re-working of webfinger and hcard parsing which will be necessary going forward. 2016-03-14 18:12:35 -07:00
jeroenpraat
b8e8517725 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-14 15:46:57 +01:00
jeroenpraat
def0454952 update nl + es-es strings 2016-03-14 15:43:51 +01:00
redmatrix
2f5862713e Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-13 18:16:11 -07:00
redmatrix
6729c27b77 git update everything 2016-03-13 18:15:38 -07:00
redmatrix
fbfa391965 Merge pull request #323 from phellmes/de20160313
Update DE translation strings
2016-03-14 10:45:54 +11:00
Mario Vavti
38beabb508 fix spacing 2016-03-13 21:27:29 +01:00
Mario Vavti
a8d5c83251 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-13 21:19:33 +01:00
Mario Vavti
370a007ee2 more janitor work on profiles 2016-03-13 21:19:15 +01:00
redmatrix
7747a23a78 Merge pull request #324 from einervonvielen/install-script_add-hubsites_stop-hubzilla
Install script: stop of apache, mysql
2016-03-14 06:19:18 +11:00
EinerVonVielen
c573670821 Install script: Added plugin hubsites and stop of apache, mysql 2016-03-13 16:32:34 +01:00
phellmes
a752d44313 Update DE translation strings 2016-03-13 13:29:14 +01:00
redmatrix
9406ff714b Merge pull request #322 from einervonvielen/homeinstall_with_plugins
Added installation of extended plugins and themes to homeinstall script
2016-03-13 15:21:00 +11:00
redmatrix
cc29e27acc issue #320 - regression, after removing channel attached to an authenticated session the session was not completely cleared. 2016-03-12 19:53:07 -08:00
EinerVonVielen
b2563528ee Added installation of extended plugins and themes to homeinstall script 2016-03-13 02:37:38 +01:00
redmatrix
70ad69d38c Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-12 16:47:11 -08:00
redmatrix
cb0c43bc68 provide service federation overview - how to go about it and the appropriate places to attach your plugin. 2016-03-12 16:45:53 -08:00
Mario Vavti
7efffbf102 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-12 22:14:08 +01:00
Mario Vavti
2d8deb6082 some janitor work on profiles 2016-03-12 22:13:46 +01:00
Jeroen van Riet Paap
5de79cdb10 Merge pull request #321 from einervonvielen/fix_german_help_link_to_github
Fix: german help > link to of project in github
2016-03-12 22:04:56 +01:00
EinerVonVielen
6837c2ef1e Fix: German help > link to of project in github. The link Pointed to
redmatrix.
Now the link points to hubzilla.
2016-03-12 21:46:13 +01:00
Mario Vavti
4e9440396c remove superfluous return 2016-03-11 10:54:04 +01:00
redmatrix
32c23ef562 some minor cleanups 2016-03-10 15:43:59 -08:00
jeroenpraat
107f80892a UNO: Hide bookmark tools in items (#^ and in menu) 2016-03-10 19:40:28 +01:00
redmatrix
fbcb711945 we've come a long way since this faq entry on the limits of cloning was written 2016-03-09 19:03:09 -08:00
redmatrix
e95a494041 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-09 16:23:46 -08:00
redmatrix
7732532964 handle UNO move channel operation 2016-03-09 15:56:51 -08:00
jeroenpraat
bb09b8a385 Update doc 2016-03-09 23:25:37 +01:00
redmatrix
b9b46a3f88 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-09 14:18:11 -08:00
redmatrix
7bb461380e issue #319 - make sure we have a local_channel() and an App::channel before trying to change the default schema for a channel 2016-03-09 14:15:50 -08:00
redmatrix
f5f79b39b8 Merge pull request #318 from git-marijus/master
should have probably done that on tag release
2016-03-10 09:03:59 +11:00
Mario Vavti
14e55e8bd6 should have probably done that on tag release 2016-03-09 13:06:24 +01:00
redmatrix
bc9d5f5a48 Merge pull request #317 from git-marijus/master
Issue #316 make /display updates work. Basically copy and paste what …
2016-03-09 20:10:48 +11:00
Mario Vavti
c2cdd41e81 Issue #316 make /display updates work. Basically copy and paste what we do on load and add $simple_update to the query. 2016-03-09 10:04:33 +01:00
redmatrix
256cd6baac work on implementing account/channel move (as opposed to clone) 2016-03-09 00:46:17 -08:00
redmatrix
843cc1481a isue #315 2016-03-08 16:46:47 -08:00
redmatrix
cf4dc2caa8 move "generator" to HttpMeta 2016-03-08 16:21:35 -08:00
redmatrix
1258f9bb21 turn 'OpenGraph' into a more general purpose HTTP meta facility for setting any meta header 2016-03-08 16:06:58 -08:00
redmatrix
5f41d06bb9 revup 2016-03-08 15:50:34 -08:00
Wave
8f4fe106ef Merge pull request #314 from wave72/master
Updated Italian strings
2016-03-08 15:54:54 +01:00
Paolo Tacconi
d74274c7e4 Updated Italian strings 2016-03-08 15:51:21 +01:00
Mario Vavti
d59268a5d8 removed id by mistake - add it again 2016-03-08 11:47:17 +01:00
Mario Vavti
f364343b55 add generic-content-wrapper and setction-content-wrapper to profile_edit.tpl 2016-03-08 11:43:21 +01:00
redmatrix
9debfa348a add syslog loglevels to dba functions 2016-03-07 20:43:52 -08:00
redmatrix
32e903e956 a bit of page cleanup for edit profiles 2016-03-07 18:49:17 -08:00
redmatrix
bd8fe768d3 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-07 16:55:12 -08:00
redmatrix
848c038970 issue #313 2016-03-07 16:54:58 -08:00
jeroenpraat
24fa201218 Small, but important fix for Dutch 2016-03-08 01:47:01 +01:00
redmatrix
1a77fb4c1d Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-07 15:12:09 -08:00
redmatrix
76467b5a35 allow modules/addons to override the og:title field 2016-03-07 15:11:11 -08:00
redmatrix
d5db25808a Facebook scraper "OpenGraph" support; modules will need to set the required fields (type, image, url) as well as any desired optional or type specific fields. We will set the title during pagebuild. 2016-03-07 15:03:53 -08:00
Mario Vavti
6824fb9f93 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-07 21:48:12 +01:00
Mario Vavti
b2216f8203 prevent page jumping if the narrow navbar setting is used 2016-03-07 21:47:52 +01:00
jeroenpraat
0799a0a3be Spanish and Dutch strings + fix es>es-es link 2016-03-07 20:29:14 +01:00
redmatrix
a2e0574fce Merge pull request #312 from jeroenpraat/master
Redbasic: Fix the issue with derived themes and schemas
2016-03-08 06:03:55 +11:00
Jeroen van Riet Paap
68d7ab6b55 Merge pull request #308 from HaakonME/master
Updated Norwegian strings for Hubzilla.

@HaakonME Can you please check if this commit is correct: https://github.com/redmatrix/hubzilla/pull/308/files#diff-8844953d2396d7486ea8e8b194c1ce96
2016-03-07 19:53:58 +01:00
Jeroen van Riet Paap
4a2c805270 Merge pull request #310 from einervonvielen/updated_homeinstall_instructions
Updated readme.md for homeinstall script
2016-03-07 19:49:58 +01:00
Jeroen van Riet Paap
7d5b266227 Merge pull request #309 from tluther/master
Doco / EMail templates
2016-03-07 19:47:47 +01:00
Jeroen van Riet Paap
1f56ff5407 Update DerivedTheme1.md 2016-03-07 17:07:34 +01:00
Jeroen van Riet Paap
95f5f3d44d Show only schema selector when Redbasic (so not a derived theme) 2016-03-07 17:06:10 +01:00
Jeroen van Riet Paap
7a5213cc8e Set the schema to the default schema in derived themes.
See the documentation for creating derived themes how to override this.
2016-03-07 17:03:02 +01:00
Jeroen van Riet Paap
f1f19372ad Update config.php 2016-03-07 17:01:12 +01:00
Haakon Meland Eriksen
276f44328e Merge remote-tracking branch 'upstream/master' 2016-03-07 06:00:26 +01:00
redmatrix
da3f1326e0 revup 2016-03-06 15:32:46 -08:00
Tobias Luther
a013ddbb91 Doc: Minor correction cloud URL in cloud.bb 2016-03-06 21:32:36 +01:00
Tobias Luther
1c6faa3a00 Added Link to TOS to EMail templates targeting members 2016-03-06 18:45:43 +01:00
einervonvielen
b7f15ccac1 Update of readme according to the last changes
The homeinstall script was changed recently. To reflect these changes the readme.md was updated to.
2016-03-06 18:40:49 +01:00
www-data
1fb7b9baae Doco: corrected git URL in git for non-developers 2016-03-06 18:34:50 +01:00
Haakon Meland Eriksen
a1e4940bea Merge remote-tracking branch 'upstream/master' 2016-03-06 18:33:28 +01:00
root
287ffe93f6 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-06 17:24:15 +01:00
root
2407379623 Das ist notwendig, um weiter zu arbeien. Merge branch 'master' of https://github.com/einervonvielen/hubzilla 2016-03-06 17:19:33 +01:00
jeroenpraat
7162403292 Also make it clear with (mouse) hover text that you must click on the cover photo to show the channel/more 2016-03-06 17:02:58 +01:00
jeroenpraat
004468f231 Mouse cursor set to pointer for coverphoto div (instead of arrow). Or else it's not clear that you can click on it to show something (the channel in this case). 2016-03-06 16:21:26 +01:00
Haakon Meland Eriksen
2d7e307e74 Updated Norwegian strings for Hubzilla 2016-03-05 14:11:56 +01:00
Haakon Meland Eriksen
d7466ade46 Merge remote-tracking branch 'upstream/master' 2016-03-05 10:01:42 +01:00
Haakon Meland Eriksen
01c0e5c46c Merge remote-tracking branch 'upstream/master' 2016-03-04 23:42:30 +01:00
redmatrix
86f840843f Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-04 14:38:47 -08:00
redmatrix
9a0f0181a5 issues #306 and #307 2016-03-04 14:38:14 -08:00
Mario Vavti
25ebac8d0b show cover-photo upload link only for the default profile 2016-03-04 16:07:41 +01:00
Mario Vavti
edf6da7189 add cover photo upload link to edit profile 2016-03-04 15:44:33 +01:00
Haakon Meland Eriksen
059da4d017 Merge remote-tracking branch 'upstream/master' 2016-03-04 06:05:47 +01:00
redmatrix
a59d1b22f6 Update the CHANGELOG for V1.3 2016-03-03 18:55:10 -08:00
redmatrix
dd4a66353a Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-03 14:49:34 -08:00
redmatrix
2cf54c465d remove the markdown feature. Do not re-enable unless you are willing to support it. 2016-03-03 14:47:39 -08:00
Mario Vavti
d3491c9165 fix jot form 2016-03-03 13:46:08 +01:00
Mario Vavti
8ca877bdd3 slide up cover on click 2016-03-03 12:31:49 +01:00
Mario Vavti
b704f977da Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-03 12:08:21 +01:00
Mario Vavti
59e04aed1b move cover-photo to template, add the ability to define a title and subtitle (defaults to channel name and addres), move js from redbasic.js to template. 2016-03-03 12:07:58 +01:00
redmatrix
436e91a1e1 rename the menu entry and page to 'Profile Fields' to maintain consistency 2016-03-02 16:39:34 -08:00
redmatrix
6f4c45a489 UI cleanup for admin profile field management page 2016-03-02 15:36:14 -08:00
redmatrix
157bbb14b5 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-02 11:35:48 -08:00
redmatrix
5c22f59c4f issue #305 2016-03-02 11:32:32 -08:00
Jeroen van Riet Paap
aa62bad07b little nl string fix 2016-03-02 15:33:18 +01:00
Mario Vavti
d3f2d2a2db small fix to simple cover-photo 2016-03-02 14:30:33 +01:00
Mario Vavti
c5d08fd5fd add a fade in effect to main while scrolling up cover photo 2016-03-02 13:33:18 +01:00
Mario Vavti
22729da2a2 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-02 12:31:46 +01:00
Mario Vavti
c97cc1487c a simple cover-photo implementation for redbasic default template 2016-03-02 12:31:25 +01:00
redmatrix
428b4dbad6 sort out the with and howlong dependencies 2016-03-01 22:47:07 -08:00
Haakon Meland Eriksen
264abef817 Merge remote-tracking branch 'upstream/master' 2016-03-02 06:06:39 +01:00
redmatrix
548bf884a4 profile field admin page (functional only: still needs a lot of HTML/CSS cleanup) 2016-03-01 21:06:27 -08:00
redmatrix
a0baa480e3 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-03-01 15:01:48 -08:00
redmatrix
765dd5569b Allow configuration of the display order of profile fields. This is an important piece of a more general profile configuration framework which will eventually be accessible via the admin page. 2016-03-01 14:55:04 -08:00
redmatrix
c19a1a6b82 revup 2016-03-01 14:13:38 -08:00
jeroenpraat
8b61e546fe Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-01 22:09:06 +01:00
jeroenpraat
7206e8af3a Small fix for deleted forum channels showing in the forum widget (had this after migration from RM on 1 or 2 channels) 2016-03-01 22:08:50 +01:00
Mario Vavti
7808689198 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-03-01 20:40:33 +01:00
Mario Vavti
966d1586c0 fix js error and add id to field input block 2016-03-01 20:40:11 +01:00
redmatrix
edffd9f183 Merge pull request #304 from phormanns/master
fix typo in postgres schema
2016-03-02 06:22:46 +11:00
Peter Hormanns
7edc505c2f fix typo in postgres schema 2016-03-01 17:54:52 +01:00
Mario Vavti
4df78b06cf fix padding 2016-03-01 15:11:15 +01:00
Mario Vavti
492609d20b do not show empty buttons if not logged in 2016-03-01 14:41:14 +01:00
Mario Vavti
0f76af261c another resize issue 2016-03-01 14:11:42 +01:00
Mario Vavti
9d00db06b2 fix resize issue 2016-03-01 14:03:34 +01:00
Mario Vavti
141f3e21b2 move preview content outside of editor space 2016-03-01 13:40:19 +01:00
Mario Vavti
fe6cbb414c adjust padding 2016-03-01 13:32:18 +01:00
Mario Vavti
e13d65eea3 set line-height to initial 2016-03-01 13:29:59 +01:00
Mario Vavti
4d6050f8e5 another css fix 2016-03-01 13:22:19 +01:00
Mario Vavti
0ebce75c7d css fixes to make jot look better with background colors or images 2016-03-01 13:09:04 +01:00
redmatrix
91bb4bdf50 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-29 19:34:23 -08:00
redmatrix
be2b7c0b5f abconfig 2016-02-29 19:31:52 -08:00
Mario Vavti
2d45f9f385 provide footer bbcode 2016-02-29 23:58:32 +01:00
redmatrix
44b2503572 revup 2016-02-29 13:42:30 -08:00
Mario Vavti
3f90da5643 remove unused variable 2016-02-29 22:07:14 +01:00
Mario Vavti
d27a627c4f simplify profile edit button(s) and make it useful for multiple profiles 2016-02-29 22:01:13 +01:00
jeroenpraat
55ab5360d9 update es-es. tested it and it works now. Don't know what happened earlier. 2016-02-29 19:36:53 +01:00
Mario Vavti
bfeeb76143 fix deletion of files from filesystem 2016-02-29 15:37:34 +01:00
Mario Vavti
f2d3be2e67 do not process update activity if there is no item to update and simplify code a little 2016-02-29 14:22:35 +01:00
jeroenpraat
60b818eb24 revert es-es update. something went wrong. later today I will examine what. 2016-02-29 09:07:29 +01:00
redmatrix
ebe70a41b9 build_sync_packet - no need to sleep after the last sync delivery. 2016-02-28 18:26:08 -08:00
redmatrix
da79662081 stop the PHP warnings from Thomas's buggered sitekey 2016-02-28 16:33:52 -08:00
redmatrix
72f3f7c172 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-28 15:07:00 -08:00
redmatrix
713a796d9f revup 2016-02-28 15:06:42 -08:00
jeroenpraat
69c6d8b617 update es-es strings 2016-02-28 17:33:22 +01:00
Haakon Meland Eriksen
e084a85e79 Merge remote-tracking branch 'upstream/master' 2016-02-28 09:10:39 +01:00
redmatrix
a1f046992d I haven't investigated 'why', but the addition of the router class in 1db3409f36 resulted in the setup global variable $install_wizard_pass to not get initiated at the global level when the setup module file was included. This corrects the situation and makes install work but without explaining why the variable wasn't instantiated in the first place. This may be important - if any other modules use global variables internally. I don't believe that any do, but the behaviour needs to be resolved or documented. 2016-02-27 17:27:46 -08:00
redmatrix
cd5630476f Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-27 16:29:13 -08:00
redmatrix
f7f20c5917 z_fetch_url and z_post_url returning false 2016-02-27 16:27:37 -08:00
redmatrix
44797fe988 Merge pull request #302 from phellmes/de20160227
Update DE translation strings
2016-02-28 09:57:04 +11:00
Haakon Meland Eriksen
c5333b5187 Merge remote-tracking branch 'upstream/master' 2016-02-27 21:40:00 +01:00
Mario Vavti
2d045a12bf Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-02-27 16:52:11 +01:00
Mario Vavti
a2fe22412f missing include 2016-02-27 16:51:54 +01:00
jeroenpraat
df69465357 update NL strings 2016-02-27 15:56:45 +01:00
phellmes
e4361cb202 Update DE translation strings 2016-02-27 14:28:06 +01:00
Mario Vavti
58cf9d832c make attach_delete() return and comment out album rename functionality since this is not supported by the backend at the moment. 2016-02-27 12:31:07 +01:00
Haakon Meland Eriksen
cf5383fdbe Merge remote-tracking branch 'upstream/master' 2016-02-27 11:24:02 +01:00
redmatrix
6126070a1d Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-26 12:49:02 -08:00
redmatrix
459166116d turn timezone aware birthdays into a feature for those who want an uncluttered calendar - at the expense of possibly sending somebody's birthday greeting on the wrong day if they are in a different timezone. 2016-02-26 12:45:44 -08:00
Mario Vavti
776bc51172 fix link to photo album and make sure that small photos are not overwritten by body text. 2016-02-26 15:21:14 +01:00
Mario Vavti
df57c90d2d several photo item template fixes 2016-02-26 14:25:18 +01:00
Mario Vavti
5a563b8e76 some improvement for file activity 2016-02-26 11:17:21 +01:00
Mario Vavti
0653a2e0a9 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-02-26 09:21:01 +01:00
Mario Vavti
d19dfc87a6 get rid of duplicate function 2016-02-26 09:20:44 +01:00
redmatrix
dc8c7a2d2e small improvements to profile like activity 2016-02-25 16:21:38 -08:00
redmatrix
ba2ede0a8f this reverts ea54987ca4 2016-02-25 15:41:52 -08:00
redmatrix
6892ba4cd8 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-25 15:14:57 -08:00
Mario Vavti
5ad9b48f1d revert f62ec4132e - allow one self to be added to a privacy group. 2016-02-25 23:59:57 +01:00
redmatrix
7972de13ca backtrace openssl_verify errors so that we can find bad keys - as there is very little relevant context available at this level. 2016-02-25 14:34:30 -08:00
Mario Vavti
ea54987ca4 in update_birthdays() we should probably set adjust to 0 instead of 1 since a birthday is more a kind of a global holiday 2016-02-25 23:03:38 +01:00
Mario Vavti
b2474334a7 provide an edit button for the profile page 2016-02-25 22:50:16 +01:00
redmatrix
2a0d4a2011 Merge pull request #299 from git-marijus/master
we have got a button for events in the nav. no need for it in the tab…
2016-02-26 06:27:42 +11:00
Mario Vavti
be27fb5644 we have got a button for events in the nav. no need for it in the tabs if we are local. 2016-02-25 13:40:15 +01:00
redmatrix
ebfa1a12b9 when creating an event from a post in our stream, if the original post was private, set the event permissions to "just me". If it was a public event, set the event permissions to the channel default permissions. 2016-02-25 00:36:35 -08:00
Haakon Meland Eriksen
21f2df399d Merge remote-tracking branch 'upstream/master' 2016-02-25 06:05:12 +01:00
redmatrix
43521bb10b Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-24 18:56:04 -08:00
redmatrix
c95d7c69eb issue #216 - calendar sharing 2016-02-24 18:54:52 -08:00
jeroenpraat
f12b0fe316 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-02-25 02:05:16 +01:00
jeroenpraat
8944d7a7a2 another dutch update 2016-02-25 02:03:58 +01:00
redmatrix
6300f47cdc schema change to support channel move (a completely different operation than channel clone) 2016-02-24 17:00:16 -08:00
redmatrix
2b95580cc0 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-24 16:41:46 -08:00
jeroenpraat
93b84f1262 interim dutch string update 2016-02-25 01:39:50 +01:00
jeroenpraat
1ffae1327f Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-02-25 01:05:31 +01:00
jeroenpraat
01a8292d65 fix TOS 2016-02-25 01:04:37 +01:00
Mario Vavti
9d3ce55978 fix boxy scheme 2016-02-25 00:24:58 +01:00
redmatrix
7e6febe2a6 add 'requires' field to plugin info to list other dependent plugins/addons and disable if dependencies are not installed/enabled 2016-02-24 15:19:28 -08:00
Mario Vavti
e73df9ed1d give nav dropdowns a fixed width to preventtext-overflow: ellipsis cut of to much of the text in some situations 2016-02-24 23:16:42 +01:00
redmatrix
b101a8f6fb missing function 2016-02-24 11:20:46 -08:00
Haakon Meland Eriksen
ddeab48f9b Merge remote-tracking branch 'upstream/master' 2016-02-24 17:44:27 +01:00
redmatrix
d074c53889 function to process atom stream without actually storing anything 2016-02-23 16:34:53 -08:00
git-marijus
039eb58524 Merge pull request #297 from bashrc/bashrc/comma
Remove stray comma
2016-02-23 22:53:14 +01:00
Bob Mottram
29c9e7c0a2 Remove stray comma 2016-02-23 19:50:45 +00:00
Wave
f15a06c0c2 Merge pull request #296 from wave72/master
Updated Italian strings
2016-02-23 11:55:23 +01:00
Paolo Tacconi
ab89eb050a Updated Italian strings 2016-02-23 11:52:45 +01:00
Mario Vavti
eca1f84328 change wording in case where registration is by apprval only 2016-02-23 11:23:43 +01:00
redmatrix
3bde7b8f18 add salmon key param 2016-02-22 16:20:19 -08:00
jeroenpraat
9db1148650 pubsites: network column is not needed anymore (mentioned in intro text). Because of more vertical space Access and Register columnis separate again. 2016-02-22 19:28:32 +01:00
jeroenpraat
502fed198d only hubs from local configured project on pubsites (hubzilla by default). as agreed with Mike. 2016-02-22 19:10:01 +01:00
Mario Vavti
411c510778 change wording 2016-02-22 13:42:05 +01:00
Mario Vavti
dd6e3d873d some work on mod/register 2016-02-22 13:04:48 +01:00
redmatrix
f9b092c619 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-21 18:15:40 -08:00
redmatrix
edc7c0837b remove bookmark identifier from embedded links since they aren't bookmarkable without an associated taxonomy entry. 2016-02-21 18:14:28 -08:00
jeroenpraat
f535d438b2 I don't think we need redmatrix hubs (or hubs without no project name) in this list. The other way around (hubzilla in redmatrix pubsites) is no problem I think. If not agreed, please revert. 2016-02-22 03:03:32 +01:00
redmatrix
119ffd2d2d Merge pull request #290 from anaqreon/homeinstall
Added sendmail installation to .homeinstall script so that hub can se…
2016-02-22 12:43:41 +11:00
redmatrix
2c3bec3d7c Merge pull request #291 from phellmes/de201602201300
Update DE strings
2016-02-22 12:43:15 +11:00
redmatrix
f1564b4cff retry the move of AccessList to composer format (one or more third-party plugins will likely break as a result) 2016-02-21 16:49:49 -08:00
redmatrix
c9252d49f7 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-21 14:54:59 -08:00
redmatrix
411abdf8a7 fix double encoding 2016-02-21 14:54:34 -08:00
jeroenpraat
1fcc863298 There was nothing wrong with my pimped pubsites (was another problem). Took the opportunity to update schemas. Plus updated spanish and dutch strings. 2016-02-21 23:00:12 +01:00
jeroenpraat
e37c1ed981 Revert pubsites.php. There seems something wrong. Let me troubleshoot that first. 2016-02-21 20:00:09 +01:00
jeroenpraat
0c5a2925ad Pimped the pubsites page. I tried to get this into a .tpl-file, but it was to complicated for me. Pubsites page is now more narrow (fits on most devices) and location is not taking a complete column (location is almost never used). Also a fix on the auto-create-channel part on the register page. 2016-02-21 19:31:11 +01:00
Andrew Manning
272ffe6983 Renamed homeinstall config file and added check for required config parameters. Spelling corrections. 2016-02-20 14:04:11 -05:00
Andrew Manning
368bb18935 Merge branch 'master' of https://github.com/redmatrix/hubzilla into homeinstall 2016-02-20 13:53:00 -05:00
Mario Vavti
22f172d697 grid->network, whitespace and bootstrapify create button 2016-02-20 14:01:20 +01:00
phellmes
fe9abcfaae Update DE strings 2016-02-20 13:47:25 +01:00
redmatrix
dfbe2eaf98 Revert "move accesslist class to namespace"
This reverts commit a9711895cf.
2016-02-20 00:49:37 -08:00
redmatrix
a9711895cf move accesslist class to namespace 2016-02-20 19:39:54 +11:00
redmatrix
8882ffc0de ensure auto_channel_create() is executed for all workflows when UNO is set. 2016-02-19 19:21:57 -08:00
redmatrix
fdd7faab51 string update 2016-02-19 19:12:26 -08:00
redmatrix
d004017b01 issue #288 allow relative_date() to be translated into languages with more than two plural forms, such as pl. 2016-02-19 19:07:07 -08:00
Andrew Manning
f2d27d543d Added sendmail installation to .homeinstall script so that hub can send email notifications 2016-02-19 20:43:28 -05:00
redmatrix
1db3409f36 add router class 2016-02-19 16:19:15 -08:00
redmatrix
cfa2ac2d0a move dreport to zotlabs\zot namespace 2016-02-19 14:02:55 -08:00
redmatrix
ebc66d7008 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-19 13:36:48 -08:00
redmatrix
3f0eb84ecf get_feature_default() was using filtered view, preventing it from working in all cases 2016-02-19 13:34:29 -08:00
Mario Vavti
fbc6c60805 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-02-19 22:28:57 +01:00
Mario Vavti
02e82e496e pimp up mod new_channel 2016-02-19 22:28:21 +01:00
redmatrix
8e586008dd issue #287 require old password to change password 2016-02-19 13:18:51 -08:00
redmatrix
50c7c33ed1 no linefeed at end 2016-02-19 12:02:23 -08:00
redmatrix
ca52d39abe finish up the storage move 2016-02-19 11:58:17 -08:00
redmatrix
28d07fd6b2 move storage assets to zotlabs/storage 2016-02-19 00:06:10 -08:00
redmatrix
5a7b994e59 siteinfo regression with Zotlabs\Project - add an autoloader 2016-02-18 19:32:06 -08:00
redmatrix
4512a4cdd4 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-18 15:26:50 -08:00
redmatrix
342fda94e4 Provide Zotlabs\Project and System class for querying details about the project/version info. Move these out of /boot.php 2016-02-18 15:24:58 -08:00
Haakon Meland Eriksen
cc264b2d60 Merge remote-tracking branch 'upstream/master' 2016-02-18 20:33:25 +01:00
jeroenpraat
33c34984e6 h1>h2 (thanks to Mario) and help text below label on register page (like on new channel). 2016-02-18 19:48:11 +01:00
jeroenpraat
fe392a3144 Removed export temporary from UNO. Removed 'Remove Channel' from UNO, cause a UNO member has only 1 channel, so it's logical to remove the acccount (by experience on UNO hub). Styling oauth settings. 2016-02-18 16:53:04 +01:00
Wave
eeed7077ca Merge pull request #286 from wave72/master
updated Italian strings
2016-02-18 15:06:19 +01:00
Paolo Tacconi
dba1854837 updated Italian strings 2016-02-18 15:01:53 +01:00
redmatrix
c107bcfbd9 some necessary doco for set_iconfig() 2016-02-18 00:51:36 -08:00
redmatrix
912ebfebff Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-18 00:23:31 -08:00
redmatrix
76bf892f9f iconfig - add sharing variable 2016-02-18 00:20:08 -08:00
redmatrix
12a9b49c6d Merge pull request #285 from anaqreon/master
Added the installation of curl to the .homeinstall script
2016-02-18 13:53:13 +11:00
Andrew Manning
aecf9e32ef Added the installation of curl to the .homeinstall script 2016-02-17 21:15:43 -05:00
redmatrix
879bc71927 this qualifies as an interface change 2016-02-17 17:29:06 -08:00
redmatrix
4da7fcb41d schema updates for iconfig 2016-02-17 16:24:26 -08:00
redmatrix
3a84e7051e Merge branch 'iconfig' 2016-02-17 16:21:22 -08:00
redmatrix
161050df07 format atom event renderings so they are reasonably compatible with GNU-social 2016-02-17 15:56:30 -08:00
redmatrix
29284319a5 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-17 14:36:16 -08:00
redmatrix
86e73fd313 add ca help files (per Paco) 2016-02-17 14:35:45 -08:00
redmatrix
62e141a89c provide del_iconfig for completeness 2016-02-17 14:14:42 -08:00
jeroenpraat
cd8b7687c1 More clarification about privacy of private content. Changed Channel Name to simply Name when registering/creating an account or channel. First time when people see this they get confused (by experience on my hubs). This will even be more with UNO. 2016-02-17 20:47:52 +01:00
Mario Vavti
4436cd9ade Change description 2016-02-17 12:37:02 +01:00
Mario Vavti
ddbe3c7426 make always preload images before rendering the page a display setting 2016-02-17 12:32:12 +01:00
Mario Vavti
b8c7b2f81d more refinement on collapsing 2016-02-17 11:07:47 +01:00
redmatrix
696c6e88ea iconfig debugging - federation now working 2016-02-17 01:05:28 -08:00
redmatrix
a83eb14ff6 iconfig debugging 2016-02-17 00:42:51 -08:00
redmatrix
8e6dc0b66b revup 2016-02-17 00:14:49 -08:00
redmatrix
41ec5403e1 slight changes to set_iconfig - if passed an item structure only update the structure. Update the DB only if passed an item_id. This makes a clean separation of behaviour that's easy to document. One could get into some weird situations the original way which tried to update and sync both. 2016-02-16 22:53:27 -08:00
redmatrix
77eb6c5761 more work on iconfig 2016-02-16 20:49:32 -08:00
redmatrix
89c6cda303 allow admin to set and lock features when UNO is enabled 2016-02-16 18:58:29 -08:00
redmatrix
d49afead67 allow redirection to site workflow page even if auto channel create is applied 2016-02-16 18:36:29 -08:00
redmatrix
0a10215371 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-16 18:15:40 -08:00
redmatrix
64f5d80ff2 some iconfig basics 2016-02-16 18:15:19 -08:00
redmatrix
28a593e1ce revup 2016-02-16 15:19:52 -08:00
jeroenpraat
f738902107 @hubdomain also for auto-create-channel + adding css wrapper (ongoing work) 2016-02-16 21:46:24 +01:00
Mario Vavti
364972a292 Thats probably better but there are still edge cases... 2016-02-16 21:29:09 +01:00
Mario Vavti
0eb0256502 typo 2016-02-16 21:02:28 +01:00
Mario Vavti
679fb7d0d2 content -> viewport 2016-02-16 20:58:10 +01:00
Mario Vavti
45247d1595 only prefetch images on update_mode update 2016-02-16 20:53:38 +01:00
Mario Vavti
3be6ef6bfc since we preload images now we also can collapse and calculate posts above the viewport 2016-02-16 14:42:13 +01:00
redmatrix
c5827c8b4f Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-15 20:33:10 -08:00
redmatrix
bb381daae3 update fr strings from transifex 2016-02-15 20:32:42 -08:00
redmatrix
d0090f09fb Merge pull request #283 from phellmes/connedit
Add string translation to auto approval option
2016-02-16 10:33:39 +11:00
Mario Vavti
afb86aa908 clean up some unused stuff and start loading content a bit earlier 2016-02-15 22:20:55 +01:00
phellmes
3b97a9f766 Add string translation to auto approval option
Make the description for the auto-approval option translatable.
Put the switch array of that option (with another missing t-funtion)
into a $yes_no variable to be consistent with other settings pages.
2016-02-15 21:23:04 +01:00
redmatrix
d3c779f635 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-14 16:17:15 -08:00
redmatrix
4f285911f0 form cleanup (profile_photo and cover_photo), admin 'user_approve' not found, missing close div in mood_content.tpl 2016-02-14 16:15:55 -08:00
jeroenpraat
8ccddfefd9 Spanish and Dutch string update 2016-02-14 16:18:03 +01:00
redmatrix
4351a83d16 Merge pull request #282 from royalterra/master
add https://blablanet.es faillback server
2016-02-14 07:13:22 +11:00
royalterra
ddefe3b3ac add https://blablanet.es faillback server
{"version":"2016-02-12.1307H","version_tag":"1.2.2","server_role":"advanced","commit":"dd2d123","url":"https:\/\/blablanet.es","plugins":["b2tbtn","bookmarker","chess","dfedfix","diaspora","diaspost","dirstats","donar","jappixmini","libertree","ljpost","mailhost","mchat","metatag","noticias","pgpkey","pumpio","sendzid","smiley_pack","smileybutton","statistics","statistics_json","status","statusnet","twitter","wholikesme","wppost","xmpp","xmppac"],"register_policy":"REGISTER_OPEN","invitation_only":0,"directory_mode":"DIRECTORY_MODE_SECONDARY","language":"es","rss_connections":1,"expiration":0,"default_service_restrictions":false,"locked_features":[],"admin":[{"name":"BlaBlanet-ES","address":"blablanet-es@blablanet.es","channel":"https:\/\/blablanet.es\/channel\/blablanet-es"}],"site_name":"BlablaNet Espa\u00f1a  donde est\u00e1n tus amigos, Tu Red Social","platform":"BlaBlaNet","dbdriver":"mysqli","lastpoll":"2016-02-13 14:39:07","info":"","channels_total":29,"channels_active_halfyear":26,"channels_active_monthly":11,"local_posts":6600,"hide_in_statistics":0}
2016-02-13 15:16:09 +00:00
Haakon Meland Eriksen
b77c5ae61e Merge remote-tracking branch 'upstream/master' 2016-02-13 11:02:43 +01:00
redmatrix
dd2d12350c Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-12 14:03:09 -08:00
redmatrix
ade91f8190 directory modes reversed 2016-02-12 14:02:50 -08:00
Jeroen van Riet Paap
d04aef4c44 don't confuse people with matrix 2016-02-12 17:17:26 +01:00
Mario Vavti
689a6dc085 https://blablanet.es/siteinfo/json reports itself as directory_mode DIRECTORY_MODE_PRIMARY. AFAIK this should not be the case as we can only have one primary per realm. 2016-02-12 11:12:47 +01:00
Mario Vavti
0b487122f6 tryout: introduce loading of images before rendering content and provide some detailed logging in js-console 2016-02-12 11:00:50 +01:00
Haakon Meland Eriksen
ac4a8fde3a Merge remote-tracking branch 'upstream/master' 2016-02-12 06:28:40 +01:00
redmatrix
31aaf40ade Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-11 20:37:42 -08:00
redmatrix
af7c7642bb whitespace 2016-02-11 20:37:30 -08:00
redmatrix
d939173c0e Merge pull request #278 from royalterra/master
Update boot.php Add Failback Server blablanet.es
2016-02-12 14:31:29 +11:00
redmatrix
a87efe45e0 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-11 15:25:26 -08:00
redmatrix
55515a25d1 guest photo upload failing when js_upload is in use due to non-existent acl parameters 2016-02-11 15:24:21 -08:00
royalterra
7d7a254238 Merge pull request #1 from royalterra/royalterra-patch-1
Update boot.php Failback Server blablanet.es
2016-02-11 22:35:45 +00:00
royalterra
564a5ea4d5 Update boot.php Failback Server blablanet.es
This HUB is running us fallback many months us fallback server
2016-02-11 22:21:03 +00:00
Mario Vavti
d9c59a19fb update readmore.js to a more recent version 2016-02-11 13:51:37 +01:00
redmatrix
83b5adf194 feed dates are always UTC. This means we will need another mechanism to pass localised dates to items_fetch() 2016-02-10 23:05:47 -08:00
redmatrix
a26d1794fe feed dates weren't being honoured. When that was fixed they turned out to be reversed. 2016-02-10 23:00:40 -08:00
redmatrix
06a1258a9a put a sane lower time limit on content search for public feed requests 2016-02-10 19:29:00 -08:00
redmatrix
d31d3df4ea hook changes to support pubsubhubbub 2016-02-10 19:12:28 -08:00
redmatrix
91801d2e2c rev update 2016-02-10 13:55:51 -08:00
Haakon Meland Eriksen
95c686de6e Merge remote-tracking branch 'upstream/master' 2016-02-09 20:30:30 +01:00
jeroenpraat
bcb94f8238 Merge branch 'master' of https://github.com/redmatrix/hubzilla 2016-02-09 16:15:49 +01:00
jeroenpraat
1d2260b44e Castellano and Nederlands string updates 2016-02-09 16:15:20 +01:00
git-marijus
81c10fc739 Merge pull request #276 from phellmes/invite
Invite module UI and strings update
2016-02-09 15:57:45 +01:00
phellmes
191a2fd5be [invite module] remove trailing spaces from translatable strings 2016-02-09 14:20:26 +01:00
phellmes
97be144913 [invite module] update UI template 2016-02-09 14:07:54 +01:00
Haakon Meland Eriksen
8c99228c8a Merge remote-tracking branch 'upstream/master' 2016-02-09 06:03:43 +01:00
redmatrix
f984502499 need to re-arrange a few things for a short vcard 2016-02-08 19:33:25 -08:00
redmatrix
315ce6d880 lots more zcard tweaks 2016-02-08 18:16:42 -08:00
redmatrix
3da8f9b13c duplicated lines in en config file 2016-02-08 14:51:03 -08:00
redmatrix
a14b87baf2 make yet another recommended security header optional - this time because of piwik. Personally I think if you want to track people you really don't understand this project and its history, but whatever.... 2016-02-08 14:48:11 -08:00
redmatrix
90fd23e0cd try that patch again 2016-02-08 14:19:49 -08:00
redmatrix
d96e985be0 Revert "sort out the well-known acme-challenge mess - at least on apache"
This reverts commit be99c7fe12.
2016-02-08 14:06:44 -08:00
redmatrix
c8788204a9 Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-08 13:58:25 -08:00
redmatrix
be99c7fe12 sort out the well-known acme-challenge mess - at least on apache 2016-02-08 13:57:40 -08:00
Mario Vavti
48963f62f9 avoid collapsing only above the viewport 2016-02-08 22:19:38 +01:00
redmatrix
00ae6bdac6 a few tweaks to uno settings page to allow a default ACL to be created 2016-02-07 21:06:17 -08:00
redmatrix
a606173e07 change register workflow if uno is set 2016-02-07 20:11:08 -08:00
redmatrix
d8e6fd5df0 provide get_server_role() to abstract different roles and capabilities 2016-02-07 18:11:10 -08:00
redmatrix
ec950de205 block public was still referenced in admin/site template 2016-02-07 15:44:42 -08:00
redmatrix
62e7fa6a23 update UI template for 'mood' module 2016-02-07 15:38:54 -08:00
Haakon Meland Eriksen
2935c5fe1a Merge remote-tracking branch 'upstream/master' 2016-02-06 12:57:25 +01:00
redmatrix
021584d782 fix uno import by disabling for now 2016-02-05 23:45:16 -08:00
redmatrix
a5c111ef4f uno stuff 2016-02-05 23:13:33 -08:00
redmatrix
7868e47643 more uno groundwork 2016-02-05 13:32:15 -08:00
redmatrix
b4e3cd000f rev update 2016-02-05 00:06:35 -08:00
redmatrix
9c3568800c remove blackout setting now that the keepout plugin performs the same tasks (plus a lot more) 2016-02-04 23:59:09 -08:00
redmatrix
9cf105f8ea initial uno config 2016-02-04 23:58:31 -08:00
redmatrix
a8456782b5 will probably need this to make it work 2016-02-04 22:39:56 -08:00
Haakon Meland Eriksen
2afdba48f0 Merge remote-tracking branch 'upstream/master' 2016-02-05 06:28:52 +01:00
redmatrix
4250895243 make strict transport security header optional 2016-02-04 20:38:22 -08:00
redmatrix
bfeb89075f comment buttons hook 2016-02-04 19:06:11 -08:00
redmatrix
721f61a71d update docs 2016-02-04 18:38:36 -08:00
redmatrix
a6e5d26aea Merge https://github.com/redmatrix/hubzilla into pending_merge 2016-02-04 18:36:36 -08:00
redmatrix
d586f64e40 update the poke page layout and UI 2016-02-04 18:35:40 -08:00
redmatrix
a0900ba052 Merge pull request #274 from mrjive/master
Small adding in search result page in /help
2016-02-05 11:11:36 +11:00
redmatrix
40b00ab362 add system black/white list for embeds ahead of personal config 2016-02-04 16:09:36 -08:00
redmatrix
18208fab84 poke basic config setting 2016-02-04 11:58:56 -08:00
Haakon Meland Eriksen
8f810a3dcf Merge remote-tracking branch 'upstream/master' 2016-02-04 06:01:15 +01:00
redmatrix
c598bbb8a9 Merge branch 'embedsec' 2016-02-03 20:33:34 -08:00
redmatrix
e6f388d869 finish moving block_public to the new security page 2016-02-03 20:32:26 -08:00
redmatrix
24e2eedd0f don't implement the default embed whitelist just yet 2016-02-03 20:29:46 -08:00
redmatrix
c75f76f740 heavy lifting on admin security page 2016-02-03 20:24:46 -08:00
redmatrix
006efbd906 change view_storage from perms_public to perms_specific in the social_private role 2016-02-03 15:44:36 -08:00
redmatrix
28386d7471 admin security page for configuring white and black lists and other security options. 2016-02-03 15:23:24 -08:00
mrjive
f9545dc359 Added section-title-wrapper and section-conent-wrapper to search result page in /help 2016-02-03 14:02:34 -08:00
mrjive
e527a52f6a Merge pull request #21 from redmatrix/master
updating from original codebase
2016-02-03 22:46:54 +01:00
redmatrix
a7ed50ecd4 more zcard tweaks 2016-02-02 19:39:47 -08:00
redmatrix
06dcaaa821 some zcard cleanup - still eneds a lot more work 2016-02-02 17:14:07 -08:00
Haakon Meland Eriksen
36ac48779c Merge remote-tracking branch 'upstream/master' 2016-02-02 17:51:34 +01:00
Wave
88669fa033 Merge pull request #271 from wave72/master
Updated Italian strings
2016-02-02 16:59:03 +01:00
Paolo Tacconi
225aa28a1b Updated Italian strings 2016-02-02 16:52:25 +01:00
Mario Vavti
f1245206ce change aside width to reflect recent widget style changes 2016-02-02 12:40:40 +01:00
redmatrix
7f453949a1 minor tweaks 2016-02-01 23:09:45 -08:00
redmatrix
38f385f67d slight formatting improvements 2016-02-01 21:23:47 -08:00
redmatrix
5f5342c0d3 adjust for folks that still have 175px profile photos 2016-02-01 21:21:22 -08:00
redmatrix
15e003f030 missing template 2016-02-01 21:14:36 -08:00
redmatrix
5edbc00865 profile embeds (still needs a bit of work) 2016-02-01 21:09:50 -08:00
redmatrix
723a49ccee add photos to the profile "likes this" dropdowns 2016-02-01 17:42:53 -08:00
redmatrix
ff487a0271 more oembed provider work - channel articles 2016-02-01 14:52:08 -08:00
mrjive
337735094b Merge pull request #20 from redmatrix/master
updating from original codebase
2016-02-01 11:25:07 +01:00
redmatrix
01b5b13475 oep for the photo top page 2016-01-31 20:44:54 -08:00
redmatrix
fd9f792f90 add album embed (embed the most recent photo with link to album) 2016-01-31 20:05:47 -08:00
redmatrix
e8ded61efb minor changes to changelog 2016-01-31 19:26:02 -08:00
redmatrix
b0e098bb68 rev update 2016-01-31 19:16:32 -08:00
Haakon Meland Eriksen
0cd82ec680 Merge remote-tracking branch 'upstream/master' 2016-01-31 10:38:19 +01:00
Haakon Meland Eriksen
76484f1541 Merge remote-tracking branch 'upstream/master' 2016-01-30 12:05:49 +01:00
mrjive
28943af494 Merge pull request #19 from redmatrix/master
updating from original codebase
2016-01-28 23:19:13 +01:00
Haakon Meland Eriksen
9abff11f86 Merge remote-tracking branch 'upstream/master' 2016-01-28 18:28:04 +01:00
Haakon Meland Eriksen
d49c5b3d8e Merge remote-tracking branch 'upstream/master' 2016-01-28 06:24:47 +01:00
Haakon Meland Eriksen
c766cf9565 Merge remote-tracking branch 'upstream/master' 2016-01-27 17:24:05 +01:00
Haakon Meland Eriksen
e4674142c6 Merge remote-tracking branch 'upstream/master' 2016-01-25 07:33:18 +01:00
Haakon Meland Eriksen
089509ab87 Merge remote-tracking branch 'upstream/master' 2016-01-24 10:35:20 +01:00
Haakon Meland Eriksen
0d119d83b0 Merge remote-tracking branch 'upstream/master' 2016-01-22 19:15:46 +01:00
Haakon Meland Eriksen
b0d5b9fd2c Merge remote-tracking branch 'upstream/master' 2016-01-22 06:37:30 +01:00
Haakon Meland Eriksen
fb1e6ca6c1 Merge remote-tracking branch 'upstream/master' 2016-01-21 17:30:04 +01:00
mrjive
c49e4f52ae Merge pull request #18 from redmatrix/master
updating from original codebase
2016-01-21 09:51:32 +01:00
Haakon Meland Eriksen
da6abe5462 Added auto_channel_create to config to ease registration 2016-01-19 21:06:55 +01:00
mrjive
763c700372 Merge pull request #17 from redmatrix/master
updating from original codebase
2016-01-15 20:58:10 +01:00
mrjive
2696deb2a1 Merge pull request #16 from redmatrix/master
updating from original codebase
2016-01-14 18:07:56 +01:00
mrjive
5c937c5642 Merge pull request #15 from redmatrix/master
updating from original codebase
2016-01-14 09:30:50 +01:00
Einer von Vielen
f510cd3111 . 2016-01-13 23:46:31 +01:00
mrjive
3206a46a92 Merge pull request #14 from redmatrix/master
updating from original codebase
2016-01-11 11:37:43 +01:00
mrjive
9cbbc92062 Merge pull request #13 from redmatrix/master
updating from original codebase
2016-01-10 09:44:43 +01:00
mrjive
0fa34c6880 Merge pull request #12 from redmatrix/master
updating from original codebase
2016-01-07 10:47:11 +01:00
mrjive
dcb5f62413 Merge pull request #11 from redmatrix/master
updating from original codebase
2016-01-04 18:20:49 +01:00
mrjive
07f5bdde60 Merge pull request #10 from redmatrix/master
updating from original codebase
2016-01-03 09:52:37 +01:00
mrjive
0513463256 Merge pull request #9 from redmatrix/master
updating from original codebase
2015-12-04 10:32:14 +01:00
mrjive
53a796afcc Merge pull request #8 from redmatrix/master
get fresh code from HZ base
2015-11-11 16:51:48 +01:00
mrjive
a4c3058f84 Merge pull request #7 from redmatrix/master
updating from original codebase
2015-10-26 21:55:47 +01:00
mrjive
32522b61f2 Merge pull request #6 from redmatrix/master
updating from original codebase
2015-10-02 09:45:03 +02:00
mrjive
11c1573b55 Merge pull request #5 from redmatrix/master
updating from original codebase
2015-09-29 08:01:51 +02:00
mrjive
006ca4421a Merge pull request #4 from redmatrix/master
updating from original codebase
2015-09-23 17:13:55 +02:00
mrjive
5ec3d3e36d Merge pull request #3 from redmatrix/master
updating from original codebase
2015-09-22 13:11:54 +02:00
mrjive
49d11ed9f8 Merge pull request #2 from redmatrix/master
get fresh code from HZ base
2015-09-21 15:41:17 +02:00
mrjive
024af91df8 Merge pull request #1 from redmatrix/master
updating from original codebase
2015-09-17 09:27:13 +02:00
468 changed files with 107796 additions and 97628 deletions

View File

@@ -2,7 +2,10 @@
Run hubzilla-setup.sh for an unattended installation of hubzilla.
The script is known to work with Debian stable (Jessie).
The script is known to work with Debian 8.3 stable (Jessie)
+ Home-PC (Debian-8.3.0-amd64)
+ DigitalOcean droplet (Debian 8.3 x64 / 512 MB Memory / 20 GB Disk / NYC3)
# Step-by-Step Overwiew
@@ -19,13 +22,20 @@ Software
+ Fresh installation of Debian on your mini-pc
+ Router with open ports 80 and 443 for your Debian
## The basic steps
## The basic steps (quick overview)
+ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS)
+ Clone hubzilla to /var/www/html
+ Copy hubzilla-config.txt and hubzilla-setup.sh to your Debian (future hub)
+ Edit hubzilla-config.txt. Enter your values there: db pass, domain, values for dyn DNS
+ Run hubzilla-setup.sh as root ... wait, wait, wait until the script is finised
+ Log on to your new debian (server)
- apt-get install git
- mkdir -p /var/www/html
- cd /var/www/html
- git clone https://github.com/redmatrix/hubzilla.git .
- cp .homeinstall/hubzilla-config.txt.template .homeinstall/hubzilla-config.txt
- nano .homeinstall/hubzilla-config.txt
- Enter your values there: db pass, domain, values for dyn DNS
- hubzilla-setup.sh as root
- ... wait, wait, wait until the script is finised
- reboot
+ Open your domain with a browser and step throught the initial configuration of hubzilla.
# Step-by-Step in Detail
@@ -76,6 +86,8 @@ There are two way to get a domain
### Method 1: Get yourself an own Domain (recommended)
...for example at selfHOST.de
### Method 2 Register a (free) Subdomain
Register a free subdomain for example at
@@ -118,8 +130,12 @@ Clone hubzilla from git ("git pull" will update it later)
Change to the install script
cd html/.homeinstall/
Copy the template file
cp hubzilla-config.txt.template hubzilla-config.txt
Change the file "hubzilla-config.txt". Enter your values there.
Change the file "hubzilla-config.txt". Read the instructions there and enter your values.
nano hubzilla-config.txt
@@ -146,10 +162,3 @@ Leave db type "MySQL" untouched.
Follow the instructions in the next pages.
# The Script explained
This chapter shows you
- What the script does exactly
- Explanations on technical details. May be this will encourage you to play with bash scripts?

View File

@@ -9,7 +9,9 @@ db_pass=
###############################################
### MANDATORY - let's encrypt #################
#
# Hubilla does not allow ecrypted communication, httpS.
# Hubilla requires encrypted communication via secure HTTP (HTTPS).
# This script automates installation of an SSL certificate from
# Let's Encrypt (https://letsencrypt.org)
#
# Please give the domain name of your hub
#
@@ -136,12 +138,12 @@ backup_device_pass=
### OPTIONAL - do not mess with things below ##
# (...if you are not certain)
#
# Usally you are done here
# All what comes below is OPTIONAL
# Usually you are done here
# Everything below is OPTIONAL
#
###############################################
#
# Database for huzilla
# Database for hubzilla
hubzilla_db_name=hubzilla
hubzilla_db_user=hubzilla
hubzilla_db_pass=$db_pass
@@ -168,7 +170,7 @@ phpmyadminpass=$db_pass
# * in eclipse: switch php debugger from zend to xdebug
# * in eclipse: add local hubzilla github repository
#
# Wich user will use eclipse?
# Which user will use eclipse?
# Leave this empty if you do not want to prepare hubzilla for debugging
#
#developer_name=

View File

@@ -5,7 +5,7 @@
#
# This file automates the installation of hubzilla under Debian Linux
#
# 1) Edit the file "hubzilla-config.txt"
# 1) Copy the file "hubzilla-config.txt.template" to "hubzilla-config.txt"
# Follow the instuctions there
#
# 2) Switch to user "root" by typing "su -"
@@ -92,12 +92,12 @@
# Credits
# -------
#
# The srcipt is based on Thomas Willinghams script "debian-setup.sh"
# The script is based on Thomas Willinghams script "debian-setup.sh"
# which he used to install the red#matrix.
#
# The script uses another script from https://github.com/lukas2511/letsencrypt.sh
#
# The documentation of bash is here
# The documentation for bash is here
# https://www.gnu.org/software/bash/manual/bash.html
#
function check_sanity {
@@ -120,6 +120,15 @@ function check_sanity {
function check_config {
print_info "config check..."
# Check for required parameters
if [ -z "$db_pass" ]
then
die "db_pass not set in $configfile"
fi
if [ -z "$le_domain" ]
then
die "le_domain not set in $configfile"
fi
# backup is important and should be checked
if [ -n "$backup_device_name" ]
then
@@ -215,11 +224,34 @@ function print_warn {
echo -e '\e[0m'
}
function stop_hubzilla {
if [ -d /etc/apache2 ]
then
print_info "stopping apache webserver..."
service apache2 stop
fi
if [ -f /etc/init.d/mysql ]
then
print_info "stopping mysql db..."
/etc/init.d/mysql stop
fi
}
function install_apache {
print_info "installing apache..."
nocheck_install "apache2 apache2-utils"
}
function install_curl {
print_info "installing curl..."
nocheck_install "curl"
}
function install_sendmail {
print_info "installing sendmail..."
nocheck_install "sendmail sendmail-bin"
}
function install_php {
# openssl and mbstring are included in libapache2-mod-php5
# to_to: php5-suhosin
@@ -542,7 +574,8 @@ function install_hubzilla {
chmod -R 777 store
touch .htconfig.php
chmod ou+w .htconfig.php
cd ..
install_hubzilla_plugins
cd /var/www/
chown -R www-data:www-data html
chown root:www-data /var/www/html/
chown root:www-data /var/www/html/.htaccess
@@ -556,6 +589,73 @@ function install_hubzilla {
print_info "installed hubzilla"
}
function install_hubzilla_plugins {
print_info "installing hubzilla plugins..."
cd /var/www/html
plugin_install=.homeinstall/plugin_install.txt
theme_install=.homeinstall/theme_install.txt
# overwrite script to update the plugin and themes
rm -f $plugins_update
echo "cd /var/www/html" >> $plugins_update
###################
# write plugin file
if [ ! -f "$plugin_install" ]
then
echo "# To install a plugin" >> $plugin_install
echo "# 1. add the plugin in a new line and run" >> $plugin_install
echo "# 2. run" >> $plugin_install
echo "# cd /var/www/html/.homeinstall" >> $plugin_install
echo "# ./hubzilla-setup.sh" >> $plugin_install
echo "https://gitlab.com/zot/ownmapp.git ownMapp" >> $plugin_install
echo "https://gitlab.com/zot/hubzilla-chess.git chess" >> $plugin_install
fi
# install plugins
while read -r line; do
[[ "$line" =~ ^#.*$ ]] && continue
p_url=$(echo $line | awk -F' ' '{print $1}')
p_name=$(echo $line | awk -F' ' '{print $2}')
# basic check of format
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
then
# install addon
util/add_addon_repo $line
util/update_addon_repo $p_name # not sure if this line is neccessary
echo "util/update_addon_repo $p_name" >> $plugins_update
else
print_info "skipping installation of a plugin from file $plugin_install - something wrong with format in line: $line"
fi
done < "$plugin_install"
###################
# write theme file
if [ ! -f "$theme_install" ]
then
echo "# To install a theme" >> $theme_install
echo "# 1. add the theme in a new line and run" >> $theme_install
echo "# 2. run" >> $theme_install
echo "# cd /var/www/html/.homeinstall" >> $theme_install
echo "# ./hubzilla-setup.sh" >> $theme_install
echo "https://github.com/DeadSuperHero/hubzilla-themes.git DeadSuperHeroThemes" >> $theme_install
fi
# install plugins
while read -r line; do
[[ "$line" =~ ^#.*$ ]] && continue
p_url=$(echo $line | awk -F' ' '{print $1}')
p_name=$(echo $line | awk -F' ' '{print $2}')
# basic check of format
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
then
# install addon
util/add_theme_repo $line
util/update_theme_repo $p_name # not sure if this line is neccessary
echo "util/update_theme_repo $p_name" >> $plugins_update
else
print_info "skipping installation of a theme from file $theme_install - something wrong with format in line: $line"
fi
done < "$theme_install"
print_info "installed hubzilla plugins and themes"
}
function rewrite_to_https {
print_info "configuring apache to redirect http to httpS ..."
htaccessfile=/var/www/html/.htaccess
@@ -743,6 +843,7 @@ echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily
echo "git -C /var/www/html/ pull" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - updating hubhilla addons...\"" >> /var/www/$hubzilladaily
echo "git -C /var/www/html/addon/ pull" >> /var/www/$hubzilladaily
echo "bash /var/www/html/$plugins_update" >> /var/www/$hubzilladaily
echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily
echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily
echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily
@@ -804,9 +905,11 @@ check_sanity
# Read config file edited by user
configfile=hubzilla-config.txt
source $configfile
selfhostdir=/etc/selfhost
selfhostscript=selfhost-updater.sh
hubzilladaily=hubzilla-daily.sh
plugins_update=.homeinstall/plugins_update.sh
snapshotconfig=/etc/rsnapshot_hubzilla.conf
snapshotconfig_external_device=/etc/rsnapshot_hubzilla_external_device.conf
backup_mount_point=/media/hubzilla_backup
@@ -816,7 +919,10 @@ sslconf=/etc/apache2/sites-available/default-ssl.conf
#set -x # activate debugging from here
check_config
stop_hubzilla
update_upgrade
install_curl
install_sendmail
install_apache
install_php
install_mysql

View File

@@ -24,6 +24,9 @@ AddType audio/ogg .oga
# Also place auth information into REMOTE_USER for sites running
# in CGI mode.
RewriteCond %{REQUEST_URI} ^/\.well\-known/.*
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]

View File

@@ -181,6 +181,7 @@ echo "chmod done, permissions set to 777 on poller script."
# to make Hubzilla on OpenShift a more pleasant experience
echo "Changing default configuration to conserve space and autocreate a social private channel upon account registration"
cd ${OPENSHIFT_REPO_DIR}
util/config system auto_channel_create
util/config system default_permissions_role social_private
util/config system workflow_channel_next channel
util/config system expire_delivery_reports 3

168
CHANGELOG Normal file
View File

@@ -0,0 +1,168 @@
Hubzilla 1.4
[This list may appear brief, but encompasses a huge amount of re-writing and re-factoring
of the internal code structure to gain long-term performance and stability and provide a standard
interface to alternate protocol federation plugins which were made possible by the UNO configuration.
UNO is a configuration of hubzilla introduced in 1.3 with reduced complexity and which provides
improved protocol federation potential to other networks by virtue of removing nomadic identity
(which is not possible to model or work around using other network protocols).]
Implement channel move operation for UNO configuration
Remove bookmark references in UNO (which has no bookmarks by default)
UI cleanup profiles/chat/manage
Refactor webfinger probes and salmon backend for GNU-social federation
SECURITY: DAV authentication exploit
Context help added
More help pages
Provide 'posts only' feed
Refactor App to remove globals
Refactor Session to remove globals
provide a fullscreen mode for selected modules and functions
Regression: some addon routes broken
fix "remember me"
Autocomplete tool extended to bbcode/comanche
Clone sync of file/photo updates
system rename (e.g. http to https or DNS name change) missing some connection photos
calendar module not blocked to public whhen block_public enabled
Use timeago.js in reshare content so that timestamps will be correct on federated reshares
Rework detection of JavaScript to avoid reload penalty under normal operation
Changed primary directory server to a hubzilla server
Plugins:
Diaspora - switch to alternate XML parser to avoid storing compound objects
GNU-Social - Huge amounts of work, federation somewhat working now, several issues remain
Friendica - Initial federation work (not yet published)
Hubzilla 1.3
Admin Security configuration page created which consolidates several previously hidden settings:
Communication white/black lists
Channel white/black lists
OEmbed white/black lists
Admin Profile Fields page created which manages the availability and order of standard profile fields and allows new fields to be created/managed
"Poke" module reworked - page UI updated and "poke basic" setting introduced which limits the available poke "verbs".
"Mood" module UI reworked
"profile_photo" module UI reworked
"cover_photo" module UI reworked
"new_channel" module UI reworked
"register" module UI reworked
"pubsites" module UI reworked
item-meta ("iconfig") created which implements arbitrary storage for item metadata for plugins
abook-meta ("abconfig") created which implements arbitrary storage for connection metadata for plugins
"Strict transport security header" made optional as it conflicts with some existing Apache/nginx configurations
"Hubzilla UNO" (Hubzilla with radically simplified and locked site settings) implemented as an install configuration.
.well-known directory conflict worked out to support LetsEncrypt cert ownership checks without disrupting webfinger and other internal uses of .well-known
Lots of work on 'zcards' which are self-contained HTML representations of a channel including cover photos, profile photos, and some text information
Long standing bug uncovered which failed to properly restrict the lower time limit for public feed requests
A number of fixes to "readmore" to fix page jumping
Bugfix: persons other than the channel owner who have permission to upload photos to a channel could not do so if the js_upload plugin/addon was enabled
Siteinfo incorrectly identifying secondary directory servers
Allow admin to set and lock features when UNO is configured
Atom feeds: alter how events are formatted to be compatible with GNU-social
Allow guest/visitor access to view personal calendar
Moved several more classes to "composer format" and provided an autoloader.
Bugfix: require existing password to change password
Bugfix: allow relative_date() to be translated to Polish which has more than two plural forms.
Plugin API: add "requires" keyword to module header to indicate dependent addons
ActivityStreams improvements and cleanup: photo and file activities
UI cleanup for editing profile when multiple profiles enabled
Removed the "markdown" feature as there are numerous issues and no maintainer.
Provide "footer" bbcode to ease theming of post footer content
Bugfix: install issues caused by composer code refactor and typo in postgres load file
Plugins:
keepout - "block public on steroids"
pubsubhubbub - provides PuSH support to Atom feeds, required for GNU-social federation
GNUsocial protocol - under development
Diaspora protocol - some work to ease migration to the new signing format
Diaspost - disabled; numerous issues and no maintainer
smileybutton - theme work and fixed compatibility with other jot-tools plugins
Hubzilla 1.2
Provide extra HTTP security headers (several of them).
Allow a site to disable delivery reports if disk space is limited
Regression: Wrong theme when viewing single post as non-member
Some Diaspora profile photos use relative URLs - force absolute
Add locked features to siteinfo report to aid remote debugging
Provide version compatibility checking to plugins (minversion, maxversion, and minphpversion)
Account config storage
Provide optional integrated registration and channel create form
cli utility for managing addons
issue with sharing photo "items"
cover photo manager: upload, crop, and store
cover photo widget created
rework the connections list page and provide a few management features there
fixed issue with Comanche layout definitions loaded by plugins
provide ability to separate delivery functions from item_store() and item_store_update() - some forum messages were being redelivered when cloned.
call build_sync_packet() on pdledit changes
Abstract the project name and version so these can be customised or removed
Allow hiding the ratings links on a per-site basis
db_type not present in international setup templates - was unable to choose postgres.
item_photo_menu logically divided into a) actions on the post, b) actions related to the author
bug: default channel not reset to 0 when last channel removed
create widget containing only the contact block
regression: public forums granted send stream permissions to connections
workaround Firefox's refusal to honour disabling autocomplete of passwords
regression: photo's uploaded to a channel by a guest (with file write permissions) not saved correctly.
provide mechanisms for custom .well-known handlers (needed for LetsEncrypt ownership verification)
proc_run modified to use exec() instead of proc_open() - causing issues on some PHP installations
remote delegation failure under a specific set of circumstances which we were finally able to duplicate
Delegation section of Channel Manager was missing names and contained useless notification icons.
Change "expire" channel setting to show system limit if there is one.
Regression: provide a one-click ignore of pending connection
Config to control directory keyword generation on client and server.
"Collections" renamed to "Privacy Groups", documentation improved
widget_item - allow use of page title instead of message id
Add site black/white list checking to all .well-known services
reduce incidents of screen jumping when "showmore" is activated
add oembed provider for photos
Addons:
CSS theming of pageheader plugin
xmpp addon ported from Friendica
Diaspora private mail issues after the third reply
Occasional issue with Diaspora connection requests
Add notification email to Diaspora PMs
Allow anonymising platform and version for statistics
msgfooter addon created
removed embedly plugin
sync clones after superblock addition
"keepout" plugin created
Hubzilla 1.1
Rewrote and simplified the Queue manager and delivery system
Rewrote and simplified the outer layers of the Zot protocol
Use a standard version numbering scheme in addition to the snapshot tags
Provide a channel blacklist for blocking channels with abusive or illegal content at the hub level
Make the black/white lists pluggable
Update template library
Support for letsencrypt certs in various places
Cleanup of login and register pages
Better error responses for permission denied on channel file repositories
Disabled the public stream by default for new installs (can be enabled if desired)
Cleanup of API authentication and rework the old OAuth1 stuff
Add API "status with media" support compatible with Twitter and conflicting method for GNU-social
Rework photo ActivityStreams objects to align better with ActivityStreams producers/consumers
Several minor API fixes to work better with AndStatus client
Invitation only site - experimental support added, needs more work
Fix delivery loop condition due to corrupted data which resulted in recursive upstream delivery
Provide more support for external (git) widget collections.
Extend the Queue API to 3rd-party network addons which have experienced downtime recently.
Regression: Inherited permissions were not explicitly set
Regression: "Xyz posted on your wall" notification sent when creating webpages at another channel
Regression: Custom permissions not pre-populated on channel creation with named role.
Provide "Public" string when a post can be made public, instead of "visible to default audience"
Allow hub admin to specify a default role type for the first channel created, reducing complexity
Ability for a hub admin to set feature defaults and lock them, reducing complexity
Change default expiration of delivery reports to 10 days to accomodate sites with reduced resources
Addons/Plugins:
Pageheader addon ported from Friendica
Hubwall (allow admin to send email to all accounts on this hub) created
GNU-social - queueing added
Diaspora - fixes for various failures to update profile photos, updates to queue API
Cross Domain Authenticated Chess (Andrew Manning's repository)
And... the normal "lots of bugs fixed, translations updated, and documentation improved"

View File

@@ -3,26 +3,26 @@
Hubzilla - Community Server
===========================
Help us redefine the web - using integrated and united community websites.
--------------------------------------------------------------------------
Connected and linked web communities.
-------------------------------------
<p align="center" markdown="1">
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
</p>
**What are Hubs?**
**What are Hubz?**
Hubs are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
Hubz are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
This allows hub members on any hub to securely and privately share anything; with anybody, on any hub - anywhere; or share stuff publicly with anybody on the internet if desired.
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache, although Mariadb or Postgres and Nginx could also be used - we're pretty easy). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache and popular variants). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
Hubzilla hubs are
Hubzilla hubz are
* decentralised
* inherently social
* optionally inter-networked with other hubs
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubs)
* optionally inter-networked with other hubz
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubz)
Possible website applications include

View File

@@ -1,5 +1,7 @@
<?php
namespace Zotlabs\Access;
class AccessList {
@@ -88,61 +90,3 @@ class AccessList {
}
/**
* @brief Used to wrap ACL elements in angle brackets for storage.
*
* @param[in,out] array &$item
*/
function sanitise_acl(&$item) {
if (strlen($item))
$item = '<' . notags(trim($item)) . '>';
else
unset($item);
}
/**
* @brief Convert an ACL array to a storable string.
*
* @param array $p
* @return array
*/
function perms2str($p) {
$ret = '';
if (is_array($p))
$tmp = $p;
else
$tmp = explode(',', $p);
if (is_array($tmp)) {
array_walk($tmp, 'sanitise_acl');
$ret = implode('', $tmp);
}
return $ret;
}
/**
* @brief Turn user/group ACLs stored as angle bracketed text into arrays.
*
* turn string array of angle-bracketed elements into string array
* e.g. "<123xyz><246qyo><sxo33e>" => array(123xyz,246qyo,sxo33e);
*
* @param string $s
* @return array
*/
function expand_acl($s) {
$ret = array();
if(strlen($s)) {
$t = str_replace('<','',$s);
$a = explode('>',$t);
foreach($a as $aa) {
if($aa)
$ret[] = $aa;
}
}
return $ret;
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Zotlabs\Project;
class System {
function get_platform_name() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['platform_name'])
return \App::$config['system']['platform_name'];
return PLATFORM_NAME;
}
function get_site_name() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['sitename'])
return \App::$config['system']['sitename'];
return '';
}
function get_project_version() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
return '';
return RED_VERSION;
}
function get_update_version() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
return '';
return DB_UPDATE_VERSION;
}
function get_notify_icon() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['email_notify_icon_url'])
return \App::$config['system']['email_notify_icon_url'];
return z_root() . '/images/hz-white-32.png';
}
function get_site_icon() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['site_icon_url'])
return \App::$config['system']['site_icon_url'];
return z_root() . '/images/hz-32.png';
}
function get_server_role() {
if(UNO)
return 'basic';
return 'advanced';
}
// return the standardised version. Since we can't easily compare
// before the STD_VERSION definition was applied, we have to treat
// all prior release versions the same. You can dig through them
// with other means (such as RED_VERSION) if necessary.
function get_std_version() {
if(defined('STD_VERSION'))
return STD_VERSION;
return '0.0.0';
}
}

View File

@@ -1,11 +1,11 @@
<?php
namespace RedMatrix\RedDAV;
namespace Zotlabs\Storage;
use Sabre\DAV;
/**
* @brief Authentication backend class for RedDAV.
* @brief Authentication backend class for DAV.
*
* This class also contains some data which is not necessary for authentication
* like timezone settings.
@@ -15,7 +15,7 @@ use Sabre\DAV;
* @link http://github.com/friendica/red
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
/**
* @brief This variable holds the currently logged-in channel_address.
@@ -45,18 +45,18 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
public $observer = '';
/**
*
* @see RedBrowser::set_writeable()
* @see Browser::set_writeable()
* @var \Sabre\DAV\Browser\Plugin
*/
public $browser;
/**
* channel_id of the current visited path. Set in RedDirectory::getDir().
* channel_id of the current visited path. Set in Directory::getDir().
*
* @var int
*/
public $owner_id = 0;
/**
* channel_name of the current visited path. Set in RedDirectory::getDir().
* channel_name of the current visited path. Set in Directory::getDir().
*
* Used for creating the path in cloud/
*
@@ -110,7 +110,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
if ($x) {
// @fixme this foreach should not be needed?
foreach ($x as $record) {
if (($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)
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);
return $this->setAuthenticated($r[0]);
@@ -197,7 +197,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
}
/**
* @brief Prints out all RedBasicAuth variables to logger().
* @brief Prints out all BasicAuth variables to logger().
*
* @return void
*/

View File

@@ -1,6 +1,6 @@
<?php
namespace RedMatrix\RedDAV;
namespace Zotlabs\Storage;
use Sabre\DAV;
@@ -15,7 +15,7 @@ use Sabre\DAV;
* @link http://github.com/friendica/red
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
class RedBrowser extends DAV\Browser\Plugin {
class Browser extends DAV\Browser\Plugin {
/**
* @see set_writeable()
@@ -243,7 +243,7 @@ class RedBrowser extends DAV\Browser\Plugin {
));
$a = get_app();
$a->page['content'] = $html;
\App::$page['content'] = $html;
load_pdl($a);
$theme_info_file = "view/theme/" . current_theme() . "/php/theme.php";

View File

@@ -1,6 +1,6 @@
<?php
namespace RedMatrix\RedDAV;
namespace Zotlabs\Storage;
use Sabre\DAV;
@@ -16,7 +16,7 @@ use Sabre\DAV;
* @link http://github.com/friendica/red
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
/**
* @brief The path inside /cloud
@@ -53,7 +53,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
logger('directory ' . $ext_path, LOGGER_DATA);
$this->ext_path = $ext_path;
// remove "/cloud" from the beginning of the path
$modulename = get_app()->module;
$modulename = \App::$module;
$this->red_path = ((strpos($ext_path, '/' . $modulename) === 0) ? substr($ext_path, strlen($modulename) + 1) : $ext_path);
if (! $this->red_path) {
$this->red_path = '/';
@@ -114,9 +114,9 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
throw new DAV\Exception\Forbidden('Permission denied.');
}
$modulename = get_app()->module;
$modulename = \App::$module;
if ($this->red_path === '/' && $name === $modulename) {
return new RedDirectory('/' . $modulename, $this->auth);
return new Directory('/' . $modulename, $this->auth);
}
$x = RedFileData($this->ext_path . '/' . $name, $this->auth);
@@ -168,6 +168,14 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
intval($this->auth->owner_id)
);
$ch = channelx_by_n($this->auth->owner_id);
if($ch) {
$sync = attach_export_data($ch,$this->folder_hash);
if($sync)
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
}
$this->red_path = $new_path;
}
@@ -332,9 +340,15 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
require_once('include/photos.php');
$args = array( 'resource_id' => $hash, 'album' => $album, 'os_path' => $f, 'filename' => $name, 'getimagesize' => $x, 'directory' => $direct);
$p = photo_upload($c[0],get_app()->get_observer(),$args);
$p = photo_upload($c[0],\App::get_observer(),$args);
}
$sync = attach_export_data($c[0],$hash);
if($sync)
build_sync_packet($c[0]['channel_id'],array('file' => array($sync)));
}
/**
@@ -356,7 +370,14 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
if ($r) {
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
if (! $result['success']) {
if($result['success']) {
$sync = attach_export_data($r[0],$ret['data']['hash']);
if($sync) {
build_sync_packet($r[0]['channel_id'],array('file' => array($sync)));
}
}
else {
logger('error ' . print_r($result, true), LOGGER_DEBUG);
}
}
@@ -380,6 +401,15 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
}
attach_delete($this->auth->owner_id, $this->folder_hash);
$ch = channelx_by_n($this->auth->owner_id);
if($ch) {
$sync = attach_export_data($ch,$this->folder_hash,true);
if($sync)
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
}
}
@@ -393,7 +423,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
public function childExists($name) {
// On /cloud we show a list of available channels.
// @todo what happens if no channels are available?
$modulename = get_app()->module;
$modulename = \App::$module;
if ($this->red_path === '/' && $name === $modulename) {
//logger('We are at ' $modulename . ' show a channel list', LOGGER_DEBUG);
return true;
@@ -417,7 +447,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
logger('GetDir: ' . $this->ext_path, LOGGER_DEBUG);
$this->auth->log();
$modulename = get_app()->module;
$modulename = \App::$module;
$file = $this->ext_path;

View File

@@ -1,6 +1,6 @@
<?php
namespace RedMatrix\RedDAV;
namespace Zotlabs\Storage;
use Sabre\DAV;
@@ -15,7 +15,7 @@ use Sabre\DAV;
* @link http://github.com/friendica/red
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
class RedFile extends DAV\Node implements DAV\IFile {
class File extends DAV\Node implements DAV\IFile {
/**
* The file from attach table.
@@ -84,6 +84,20 @@ class RedFile extends DAV\Node implements DAV\IFile {
dbesc($this->data['hash']),
intval($this->data['id'])
);
if($this->data->is_photo) {
$r = q("update photo set filename = '%s' where resource_id = '%s' and uid = %d",
dbesc($newName),
dbesc($this->data['hash']),
intval($this->auth->owner_id)
);
}
$ch = channelx_by_n($this->auth->owner_id);
if($ch) {
$sync = attach_export_data($ch,$this->data['hash']);
if($sync)
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
}
}
/**
@@ -173,7 +187,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
if($is_photo) {
require_once('include/photos.php');
$args = array( 'resource_id' => $this->data['hash'], 'album' => $album, 'os_path' => $f, 'filename' => $r[0]['filename'], 'getimagesize' => $gis, 'directory' => $direct );
$p = photo_upload($c[0],get_app()->get_observer(),$args);
$p = photo_upload($c[0],\App::get_observer(),$args);
}
// update the folder's lastmodified timestamp
@@ -205,6 +219,12 @@ class RedFile extends DAV\Node implements DAV\IFile {
return;
}
}
$sync = attach_export_data($c[0],$this->data['hash']);
if($sync)
build_sync_packet($c[0]['channel_id'],array('file' => array($sync)));
}
/**
@@ -318,5 +338,12 @@ class RedFile extends DAV\Node implements DAV\IFile {
}
attach_delete($this->auth->owner_id, $this->data['hash']);
$ch = channelx_by_n($this->auth->owner_id);
if($ch) {
$sync = attach_export_data($ch,$this->data['hash'],true);
if($sync)
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
}
}
}

36
Zotlabs/Web/CheckJS.php Normal file
View File

@@ -0,0 +1,36 @@
<?php
namespace Zotlabs\Web;
class CheckJS {
private static $jsdisabled = 0;
function __construct($test = 0) {
if(intval($_REQUEST['jsdisabled']))
$this->jsdisabled = 1;
if(intval($_COOKIE['jsdisabled']))
$this->jsdisabled = 1;
if(! $this->jsdisabled) {
$page = urlencode(\App::$query_string);
if($test) {
\App::$page['htmlhead'] .= "\r\n" . '<meta http-equiv="refresh" content="0; url=' . z_root() . '/nojs?f=&redir=' . $page . '">' . "\r\n";
}
else {
\App::$page['htmlhead'] .= "\r\n" . '<noscript><meta http-equiv="refresh" content="0; url=' . z_root() . '/nojs?f=&redir=' . $page . '"></noscript>' . "\r\n";
}
}
}
function disabled() {
return self::$jsdisabled;
}
}

66
Zotlabs/Web/HttpMeta.php Normal file
View File

@@ -0,0 +1,66 @@
<?php
namespace Zotlabs\Web;
class HttpMeta {
private $vars = null;
private $og = null;
function __construct() {
$this->vars = array();
$this->og = array();
}
function set($property,$value) {
if(strpos($property,'og:') === 0)
$this->og[$property] = $value;
else
$this->vars[$property] = $value;
}
function check_required() {
if(
($this->og)
&& array_key_exists('og:title',$this->og)
&& array_key_exists('og:type', $this->og)
&& array_key_exists('og:image',$this->og)
&& array_key_exists('og:url', $this->og)
)
return true;
return false;
}
function get_field($field) {
if(strpos($field,'og:') === 0)
$arr = $this->og;
else
$arr = $this->vars;
if($arr && array_key_exists($field,$arr) && $arr[$field])
return $arr[$field];
return false;
}
function get() {
$o = '';
if($this->vars) {
foreach($this->vars as $k => $v) {
$o .= '<meta property="' . $k . '" content="' . urlencode($v) . '" />' . "\r\n" ;
}
}
if($this->check_required()) {
foreach($this->og as $k => $v) {
$o .= '<meta property="' . $k . '" content="' . urlencode($v) . '" />' . "\r\n" ;
}
}
if($o)
return "\r\n" . $o;
return $o;
}
}

203
Zotlabs/Web/Router.php Normal file
View File

@@ -0,0 +1,203 @@
<?php
namespace Zotlabs\Web;
class Router {
function __construct(&$a) {
/**
*
* We have already parsed the server path into App::$argc and App::$argv
*
* App::$argv[0] is our module name. We will load the file mod/{App::$argv[0]}.php
* and use it for handling our URL request.
* The module file contains a few functions that we call in various circumstances
* and in the following order:
*
* "module"_init
* "module"_post (only called if there are $_POST variables)
* "module"_content - the string return of this function contains our page body
*
* Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do
* so within the module init and/or post functions and then invoke killme() to terminate
* further processing.
*/
$module = \App::$module;
if(strlen($module)) {
/**
*
* We will always have a module name.
* First see if we have a plugin which is masquerading as a module.
*
*/
if(is_array(\App::$plugins) && in_array($module,\App::$plugins) && file_exists("addon/{$module}/{$module}.php")) {
include_once("addon/{$module}/{$module}.php");
if(function_exists($module . '_module'))
\App::$module_loaded = true;
}
if((strpos($module,'admin') === 0) && (! is_site_admin())) {
\App::$module_loaded = false;
notice( t('Permission denied.') . EOL);
goaway(z_root());
}
/**
* If the site has a custom module to over-ride the standard module, use it.
* Otherwise, look for the standard program module in the 'mod' directory
*/
if(! (\App::$module_loaded)) {
if(file_exists("mod/site/{$module}.php")) {
include_once("mod/site/{$module}.php");
\App::$module_loaded = true;
}
elseif(file_exists("mod/{$module}.php")) {
include_once("mod/{$module}.php");
\App::$module_loaded = true;
}
else logger("mod/{$module}.php not found.");
}
/**
* This provides a place for plugins to register module handlers which don't otherwise exist on the system.
* If the plugin sets 'installed' to true we won't throw a 404 error for the specified module even if
* there is no specific module file or matching plugin name.
* The plugin should catch at least one of the module hooks for this URL.
*/
$x = array('module' => $module, 'installed' => false);
call_hooks('module_loaded', $x);
if($x['installed'])
\App::$module_loaded = true;
/**
* The URL provided does not resolve to a valid module.
*
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
* We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
* we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
* this will often succeed and eventually do the right thing.
*
* Otherwise we are going to emit a 404 not found.
*/
if(! (\App::$module_loaded)) {
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
killme();
}
if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && \App::$config['system']['dreamhost_error_hack']) {
logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
goaway(z_root() . $_SERVER['REQUEST_URI']);
}
logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG);
header($_SERVER['SERVER_PROTOCOL'] . ' 404 ' . t('Not Found'));
$tpl = get_markup_template('404.tpl');
\App::$page['content'] = replace_macros($tpl, array(
'$message' => t('Page not found.')
));
// pretend this is a module so it will initialise the theme
\App::$module = '404';
\App::$module_loaded = true;
}
}
}
function Dispatch(&$a) {
/**
* Call module functions
*/
if(\App::$module_loaded) {
\App::$page['page_title'] = \App::$module;
$placeholder = '';
/**
* No theme has been specified when calling the module_init functions
* For this reason, please restrict the use of templates to those which
* do not provide any presentation details - as themes will not be able
* to over-ride them.
*/
if(function_exists(\App::$module . '_init')) {
$arr = array('init' => true, 'replace' => false);
call_hooks(\App::$module . '_mod_init', $arr);
if(! $arr['replace']) {
$func = \App::$module . '_init';
$func($a);
}
}
/**
* Do all theme initialiasion here before calling any additional module functions.
* The module_init function may have changed the theme.
* Additionally any page with a Comanche template may alter the theme.
* So we'll check for those now.
*/
/**
* In case a page has overloaded a module, see if we already have a layout defined
* otherwise, if a PDL file exists for this module, use it
* The member may have also created a customised PDL that's stored in the config
*/
load_pdl($a);
/**
* load current theme info
*/
$theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php';
if (file_exists($theme_info_file)){
require_once($theme_info_file);
}
if(function_exists(str_replace('-', '_', current_theme()) . '_init')) {
$func = str_replace('-', '_', current_theme()) . '_init';
$func($a);
}
elseif (x(\App::$theme_info, 'extends') && file_exists('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php')) {
require_once('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php');
if(function_exists(str_replace('-', '_', \App::$theme_info['extends']) . '_init')) {
$func = str_replace('-', '_', \App::$theme_info['extends']) . '_init';
$func($a);
}
}
if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! \App::$error)
&& (function_exists(\App::$module . '_post'))
&& (! x($_POST, 'auth-params'))) {
call_hooks(\App::$module . '_mod_post', $_POST);
$func = \App::$module . '_post';
$func($a);
}
if((! \App::$error) && (function_exists(\App::$module . '_content'))) {
$arr = array('content' => \App::$page['content'], 'replace' => false);
call_hooks(\App::$module . '_mod_content', $arr);
\App::$page['content'] = $arr['content'];
if(! $arr['replace']) {
$func = \App::$module . '_content';
$arr = array('content' => $func($a));
}
call_hooks(\App::$module . '_mod_aftercontent', $arr);
\App::$page['content'] .= $arr['content'];
}
}
}
}

160
Zotlabs/Web/Session.php Normal file
View File

@@ -0,0 +1,160 @@
<?php
namespace Zotlabs\Web;
/**
*
* @brief This file includes session related functions.
*
* Session management functions. These provide database storage of PHP
* session info.
*/
class Session {
private static $handler = null;
private static $session_started = false;
function init() {
$gc_probability = 50;
ini_set('session.gc_probability', $gc_probability);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_httponly', 1);
/*
* Set our session storage functions.
*/
$handler = new \Zotlabs\Web\SessionHandler();
self::$handler = $handler;
$x = session_set_save_handler($handler,true);
if(! $x)
logger('Session save handler initialisation failed.',LOGGER_NORMAL,LOG_ERR);
// Force cookies to be secure (https only) if this site is SSL enabled.
// Must be done before session_start().
$arr = session_get_cookie_params();
session_set_cookie_params(
((isset($arr['lifetime'])) ? $arr['lifetime'] : 0),
((isset($arr['path'])) ? $arr['path'] : '/'),
((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()),
((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
((isset($arr['httponly'])) ? $arr['httponly'] : true)
);
}
function start() {
session_start();
self::$session_started = true;
}
/**
* @brief Resets the current session.
*
* @return void
*/
function nuke() {
self::new_cookie(0); // 0 means delete on browser exit
if($_SESSION && count($_SESSION)) {
foreach($_SESSION as $k => $v) {
unset($_SESSION[$k]);
}
}
}
function new_cookie($xtime) {
$newxtime = (($xtime> 0) ? (time() + $xtime) : 0);
$old_sid = session_id();
if(self::$handler && self::$session_started) {
session_regenerate_id(true);
// force SessionHandler record creation with the new session_id
// which occurs as a side effect of read()
self::$handler->read(session_id());
}
else
logger('no session handler');
if (x($_COOKIE, 'jsdisabled')) {
setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime);
}
setcookie(session_name(),session_id(),$newxtime);
$arr = array('expire' => $xtime);
call_hooks('new_cookie', $arr);
}
function extend_cookie() {
// if there's a long-term cookie, extend it
$xtime = (($_SESSION['remember_me']) ? (60 * 60 * 24 * 365) : 0 );
if($xtime)
setcookie(session_name(),session_id(),(time() + $xtime));
$arr = array('expire' => $xtime);
call_hooks('extend_cookie', $arr);
}
function return_check() {
// check a returning visitor against IP changes.
// If the change results in being blocked from re-entry with the current cookie
// nuke the session and logout.
// Returning at all indicates the session is still valid.
// first check if we're enforcing that sessions can't change IP address
// @todo what to do with IPv6 addresses
if($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) {
logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
$partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
$partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
$paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia'));
if(! $paranoia)
$paranoia = intval(get_config('system', 'paranoia'));
switch($paranoia) {
case 0:
// no IP checking
break;
case 2:
// check 2 octets
$partial1 = substr($partial1, 0, strrpos($partial1, '.'));
$partial2 = substr($partial2, 0, strrpos($partial2, '.'));
if($partial1 == $partial2)
break;
case 1:
// check 3 octets
if($partial1 == $partial2)
break;
case 3:
default:
// check any difference at all
logger('Session address changed. Paranoid setting in effect, blocking session. '
. $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
self::nuke();
goaway(z_root());
break;
}
}
return true;
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Zotlabs\Web;
class SessionHandler implements \SessionHandlerInterface {
function open ($s, $n) {
return true;
}
// IMPORTANT: if we read the session and it doesn't exist, create an empty record.
// We rely on this due to differing PHP implementation of session_regenerate_id()
// some which call read explicitly and some that do not. So we call it explicitly
// just after sid regeneration to force a record to exist.
function read ($id) {
if($id) {
$r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
if($r) {
return $r[0]['data'];
}
else {
q("INSERT INTO `session` (sid, expire) values ('%s', '%s')",
dbesc($id),
dbesc(time() + 300)
);
}
}
return '';
}
function write ($id, $data) {
if(! $id || ! $data) {
return false;
}
// Unless we authenticate somehow, only keep a session for 5 minutes
// The viewer can extend this by performing any web action using the
// original cookie, but this allows us to cleanup the hundreds or
// thousands of empty sessions left around from web crawlers which are
// assigned cookies on each page that they never use.
$expire = time() + 300;
if($_SESSION) {
if(array_key_exists('remember_me',$_SESSION) && intval($_SESSION['remember_me']))
$expire = time() + (60 * 60 * 24 * 365);
elseif(local_channel())
$expire = time() + (60 * 60 * 24 * 3);
elseif(remote_channel())
$expire = time() + (60 * 60 * 24 * 1);
}
q("UPDATE `session`
SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'",
dbesc($data),
dbesc($expire),
dbesc($id)
);
return true;
}
function close() {
return true;
}
function destroy ($id) {
q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
return true;
}
function gc($expire) {
q("DELETE FROM session WHERE expire < %d", dbesc(time()));
return true;
}
}

View File

@@ -132,7 +132,7 @@ class Auth {
// tell them to logout if they're logged in locally as anything but the target remote account
// in which case just shut up because they don't need to be doing this at all.
if (get_app()->channel['channel_hash'] == $hubloc['xchan_hash']) {
if (\App::$channel['channel_hash'] == $hubloc['xchan_hash']) {
return true;
}
else {
@@ -242,9 +242,9 @@ class Auth {
$arr = array('xchan' => $hubloc, 'url' => $this->desturl, 'session' => $_SESSION);
call_hooks('magic_auth_success',$arr);
get_app()->set_observer($hubloc);
\App::set_observer($hubloc);
require_once('include/security.php');
get_app()->set_groups(init_groups_visitor($_SESSION['visitor_id']));
\App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
info(sprintf( t('Welcome %s. Remote authentication successful.'),$hubloc['xchan_name']));
logger('mod_zot: auth success from ' . $hubloc['xchan_addr']);
$this->success = true;
@@ -341,5 +341,5 @@ class Auth {
* Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is
* a string whose contents are not defined by protocol. Example: "basic" or "gold".
*
* @param[in,out] App &$a
* @param[in,out] \App &$a
*/

View File

@@ -1,5 +1,5 @@
<?php
namespace Zotlabs\Zot;
class DReport {

View File

@@ -41,9 +41,10 @@ class Receiver {
if(! $this->messagetype)
$this->error = true;
$this->sender = ((array_key_exists('sender',$this->data)) ? $this->data['sender'] : null);
$this->recipients = ((array_key_exists('recipients',$this->data)) ? $this->data['recipients'] : null);
if($this->data) {
$this->sender = ((array_key_exists('sender',$this->data)) ? $this->data['sender'] : null);
$this->recipients = ((array_key_exists('recipients',$this->data)) ? $this->data['recipients'] : null);
}
if($this->sender)
$this->ValidateSender();

42
Zotlabs/Zot/Verify.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
namespace Zotlabs\Zot;
class Verify {
function create($type,$channel_id,$token,$meta) {
return q("insert into verify ( type, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
dbesc($type),
intval($channel_id),
dbesc($token),
dbesc($meta),
dbesc(datetime_convert())
);
}
function match($type,$channel_id,$token,$meta) {
$r = q("select id from verify where type = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
dbesc($type),
intval($channel_id),
dbesc($token),
dbesc($meta)
);
if($r) {
q("delete from verify where id = %d",
intval($r[0]['id'])
);
return true;
}
return false;
}
function purge($type,$interval) {
q("delete from verify where type = '%s' and created < %s - INTERVAL %s",
dbesc($type),
db_utcnow(),
db_quoteinterval($interval)
);
}
}

View File

@@ -2,9 +2,6 @@
namespace Zotlabs\Zot;
require_once('Zotlabs/Zot/IHandler.php');
class ZotHandler implements IHandler {
function Ping() {

718
boot.php

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ view/php/default.php
<html>
<head>
<title><?php if(x($page,'title')) echo $page['title'] ?></title>
<script>var baseurl="<?php echo $a->get_baseurl() ?>";</script>
<script>var baseurl="<?php echo z_root() ?>";</script>
<?php if(x($page,'htmlhead')) echo $page['htmlhead'] ?>
</head>
<body>

View File

@@ -38,7 +38,7 @@ Inside it, put the following information - edit as needed
function mytheme_init(&$a) {
$a->theme_info['extends'] = 'redbasic';
App::$theme_info['extends'] = 'redbasic';
}
@@ -63,7 +63,6 @@ In it, put the following:
That's it. This tells the software to read the PCSS information for the redbasic theme first, and then read our CSS file which will just consist of changes we want to make from our parent theme (redbasic).
Now create the actual CSS file for your theme. Put it in view/theme/mytheme/css/style.css (where we just told the software to look for it). For our example, we'll just change the body background color so you can see that it works. You can use any CSS you'd like.
@@ -74,4 +73,29 @@ Now create the actual CSS file for your theme. Put it in view/theme/mytheme/css
You've just successfully created a derived theme. This needs to be enabled in the admin "themes" panel, and then anybody on the site can use it by selecting it in Settings->Display Settings as their default theme.
**Lesson 2**
If you want to use the redbasic schemas for your derived theme, you have to do a bit more.
Do everything as above, but don't create view/theme/mytheme/php/style.php, but copy instead view/theme/redbasic/php/style.php to view/theme/mytheme/php/style.php. Modify that file and remove (or comment out) these two lines:
if(local_channel() && App::$channel && App::$channel['channel_theme'] != 'redbasic')
set_pconfig(local_channel(), 'redbasic', 'schema', '---');
Also add this line at the bottom:
echo @file_get_contents('view/theme/mytheme/css/style.css');
To show the schema selector you have to copy view/theme/redbasic/tpl/theme_settings.tpl to view/theme/mytheme/tpl/theme_settings.tpl. Modify that file and replace the lines:
{{if $theme == redbasic}}
{{include file="field_select.tpl" field=$schema}}
{{/if}}
with:
{{include file="field_select.tpl" field=$schema}}
#include doc/macros/main_footer.bb;

View File

@@ -12,7 +12,7 @@ There are certain scenarios where you might want your own directory-server that
* On the hub that will be the Directory Server, open the .htconfig.php file and set:
`$a->config['system']['directory_mode'] = DIRECTORY_MODE_PRIMARY;`
`App::$config['system']['directory_mode'] = DIRECTORY_MODE_PRIMARY;`
By default it should already be set as **DIRECTORY_MODE_NORMAL**, so just edit that line to say **DIRECTORY_MODE_PRIMARY**

View File

@@ -48,10 +48,9 @@ Content (especially status posts) that you share with other networks or that you
Comments to posts that were created by others and posts which are designated as forum posts belong to you as the creator/author, but the distribution of these posts is not under your direct control. These posts/comments MAY be re-distributed to others, and MAY be visible to anybody on the internet. In the case of comments, the creator of the "first message" in the thread to which you are replying controls the distribution of all comments and replies to that message.
**Private Information**
$Projectname developers will ensure that any content you provide which is designated as PRIVATE will be protected against eavesdropping - to the best of their ability. Private content is generally hidden or obscured even from hub administrators. It is also stripped from email notifications. It is difficult but NOT impossible for this content to be seen by a hub administrator. End to end encryption is provided as an optional feature and this CANNOT be seen, even by a determined administrator.
$Projectname developers will ensure that any content you provide which is designated as PRIVATE will be protected against eavesdropping - to the best of their ability. Private channel content CAN be seen in the database of every involved hub administrator, but private messages are obscured in the database. The latter means that it is very difficult, but NOT impossible for this content to be seen by a hub administrator. Private channel content and private messages are also stripped from email notifications. End to end encryption is provided as an optional feature and this CANNOT be seen, even by a determined administrator.
##Identity Privacy

78
doc/ca/Privacy.md Normal file
View File

@@ -0,0 +1,78 @@
Política de Privacitat
======================
##Sumari##
Q: Qui pot veure el meu contingut?
A: Per defecte TOTHOM A INTERNET, EXCEPTE que ho hagis restringit. $Projectname permet te triar el nivell de privacitat que desitgis. El contingut restringit no serà visible als "espies de la xarxa " ni als anunciants. Estarà protegit contra l'espionatge per estranys - de la millor manera que sabem. Administradors de nodes amb habilitats i paciència suficients poden ser capaços d'espiar a algunes comunicacions privades però han de invertir molt esforç per fer-ho. Hi maneres de Privacitat en $Projectname que són fins i tot resistents a escoltes il·legals pels administradors de nodes hàbils i decidits.
Q: Pot el meu contingut ser censurat?
A: $Projectname (la xarxa de nodes) NO POT censurat el teu contingut. Els administradors de servidor i del node estan subjectes a les lleis locals i poden suprimir contingut censurable des del seu lloc/node. Qualsevol POT convertir-se en un administrador de node, inclòs tu; i per tant publicar contingut que d'altra manera podria ser censurat. Encara i això estaràs subjecte a les teves lleis locals. Es la teva decisió.
##Definicions
**$Projectname**
Coneguda d'un altre forma com "la xarxa", Hubzilla és una col·lecció d'equips individuals/servidors (àlies nodes) que connecten entre si per formar una xarxa cooperativa més gran.
**node (hub)**
Un equip individual o un servidor connectat a $Projectname. Aquests són proporcionats per un **administrador del node** i poden ser públics o privats, de pagament o gratuïts.
**administrador del node**
L'operador del sistema d'un node individual.
##Polítiques
**Informació Pública**
Qualsevol informació o cualsevol cosa publicada per tu a $Projectname POT ser pública o visible a qualsevol a Internet. En la mesura que sigui possible, $Projectname te permet protegir el contingut i restringir qui pot veure-ho.
La teva foto de perfil, el nom del teu canal, i la ubicació (URL o adreça de xarxa) del seu canal són visibles per a qualsevol persona a Internet i els controls de privacitat no afectaràn la visualització d'aquests elements.
POTS proporcionar, a més, un altra informació de perfil. Qualsevol informació que proporcionis en el teu perfil públic **per defecte** POT ser transmesa a altres centres en $Projectname i, a més, és possible que aparegui en el directori del canal. POTS restringir la visualització d'aquesta informació de perfil. Es POT restringir (permets que visualitzin), només als membres del teu nucli, o només les connexions (amics), o altres conjunts limitats de espectadors com desitgis. Si vols que el teu perfil estigui restringit, has d'establir la configuració de privacitat adequada, o simplement NO PROPORCIONIS informació addicional.
**Contingut**
El contingut que proporciones (missatges d'estat, fotos, arxius, etc.) et pertany a tu. Per defecte a $Projectname és publica contingut de forma oberta i visible per qualsevol en internet (PÚBLIC). POTS controlar això a la seva configuració del canal i restringir els permisos per defecte o pot restringir la visibilitat de qualsevol article únic publicat per separat (PRIVAT). Els desenvolupadors $Projectname s'han d'assegurat que el contingut restringit és visible NOMÉs per als que estan a la llista d'autoritzats - han emprat el millor d'ells per això.
El contingut (especialment les entrades d'estat) que es comparteixen amb altres xarxes o que has fet visible a qualsevol a Internet (PÚBLIC) no poden ser retirats (esborrats) fàcilment un cop que ha estat publicats. Pot haver estat compartit amb altres xarxes i posat a disposició a través de feeds RSS/Atom. També pot haver estat sindicat en altres llocs $Projectname. Pot aparèixer en les xarxes d'espionatge i recerques a Internet. Si no desitges aquest comportament per defecte, si et plau, ajusta la configuració del canal i restringeix qui pot veure el teu contingut.
**Comentaris i entrades a Forums**
Els comentaris als llocs que es van crear per altres i entrades que es designen com missatges al fòrum pertanyen tant a tu com al creador/autor, però la distribució d'aquests llocs no està sota el teu control directe. Aquestes entrades/comentaris es poden tornar a distribuir als altres, i pot ser visible per qualsevol en internet. En el cas dels comentaris, el creador del "primer missatge" al fil al qual està responent controla la distribució de tots els comentaris i respostes a aquest missatge.
**Informació Privada**
Els desenvolupadors de $Projectname aseguraràn que cualsevol contingut que creis designat com PRIVAT estarà protegit contra estaràn protegits contra les escoltes - han emprat el millor d'ells per això. El contingut privat generalment s'amaga o enfosqueix fins i tot als administradors de nodes. També s'eliminen les notificacions per correu electrònic. És difícil, però no impossible que aquest contingut sigui vist per un administrador de node. El xifrat extrem a extrem es facilita com una característica opcional i fa el contingut, NO VISIBLE, fins i tot per un administrador determinat a veure'l.
##Privacitat de la Identitat
La Privacitat per la teva identitat és un altre aspecte. En tenir una identitat descentralitzada a $Projectname, la seva privacitat s'estén més enllà del seu node d'inici. Si vols tenir el control complet de la teva privacitat i seguretat has d'executar el teu propi centre en un servidor dedicat. Per a moltes persones, això és complicat i pot esgotar les seves habilitats tècniques. Així que anem a enumerar algunes precaucions que pots fer per assegurar la teva privacitat tant com sigui possible.
Una identitat descentralitzat té molts avantatges i te dóna un munt de característiques interessants, però has de ser conscient del fet que la teva identitat és coneguda per altres centres de la xarxa $Projectname. Un d'aquests avantatges és que altres canals poden servir contingut personalitzat i permetrà veure el contingut privat (com fotos privades que altres volen compartir amb vostè). Per això els canals necessiten saber qui ets. Però entenem que de vegades aquests altres canals en saben més de tu del que pugui desitjar. Per exemple, el plug-in Visage pot dir-li al propietari d'un canal l'última vegada que vas visitar el seu perfil. Pots renunciar fàcilment a aquest baix nivell de seguiment, que creiem inofensiu.
* Pots activar [No Em Segueixis (anglès:Do Not Track (DNT))](http://donottrack.us/) al teu navegador web. Respectem aquesta nova política de privacitat proposada. Tots en navegadors moderns soporten DNT. Trobaràs als ajustos de privacitat del teu navegador web o sino pots consultar el manual del navegador. Això no afectarà la funcionalitat de $Projectname. Aquest ajust, segurament, es suficient per la majoria de la gent.
* Pots [deshabilitar publicacions](ajustos) del teu canal al nostre canal de directoris. Si vols que la gent trobi el teu canal, has de facilitar la teva direcció del canal a ell(a). Pensem que això es un bon indicador que, en aquest cas, vols es un extra de privacitat i automaticament s'activarà "No Em Segueixis" (DNT).
* Pots tenir un node blocat. Això significa que tots els canals i contingut en aquest node no es públic i invisible al món exterior. Això és quelcom que només ho pot fer l'administrador del teu node. També es respecta això i automàticament s'activa DNT si és sel·leccionat.
###Censura
$Projectname és una xarxa global que inclou a totes les religions i cultures. Això no implica que tots els membres de la xarxa pensin de la mateixa manera que tu pel que fa en temes polèmics, i algunes persones poden sentir una forta oposició al contingut que publiquis. En general, si desitjes publicar alguna cosa que saps que no és universalment acceptable, el millor enfocament consisteix a restringir l'audiència utilitzant els controls de privacitat a un petit cercle d'amics.
$Projectname com un proveïdor de la xarxa no pot censurar el contingut. No obstant això, els administradors de node poden censurar qualsevol contingut que apareix en el seu centre per complir amb les lleis locals o fins i tot el seu judici personal. La seva decisió serà inapel·lable. Si té problemes amb qualsevol administrador de node, pots moure el teu compte i publicacions a un altre lloc que estigui més d'acord amb les teves expectatives. Si us plau comprova (periòdicament) les [Condicions d'ús](help/TermsOfService) del teu centre per aprendre sobre les normes o directrius. Si el teu contingut consisteix en un material que és il·legal o que pugui causar problemes, es recomana ENCARIDAMENT a allotjar tu mateix (convertir-te en un administrador de node). Podràs trobar que el teu contingut està bloquejat en alguns centres, però $Projectname, com a xarxa, no pot bloquejar una vegada publicat.
$Projectname RECOMANA que els administradors de nodes ofereixin un període de gràcia de 1-2 dies entre advertir al titular d'un compte, que hi ha contingut que ha de ser eliminat, i l'eliminació física o desactivació del compte. Això li donarà al propietari del contingut l'oportunitat d'exportar els seus canal de meta-dades i importar-lo a un altre lloc. En rares ocasions el contingut pot ser de tal naturalesa que es justifiqui l'eliminació immediata del compte. Aquesta és una decisió del node, no és una decisió de $Projectname.
Si normalment i regularment publiques contingut per a adults o de caràcter ofensiu, es recomana ENCARIDAMENT que marquis el compte com "NSFW" (No segur per al treball). Això evitarà que es mostri la teva foto de perfil al directori, excepte per als espectadors que han optat per desactivar el "mode segur". Si la teva foto de perfil es considera per a adults o ofensiu pels administradors de directori, l'administrador del directori POT marcar la teva foto de perfil com NSFW. Actualment no hi ha un sistema oficial per revertir aquesta decisió. Així DEURIES marcar tu mateix, el teu compte, com a NSFW si és probable que no sigui apropiat per a audiències generals.
#include doc/macros/main_footer.bb;

8
doc/ca/TermsOfService.md Normal file
View File

@@ -0,0 +1,8 @@
Termes del Servei
================
Aquest node Hubzilla encara no te Termes del Servei. Estic buscant un model adient.....
En resum empreu el servei respectant els altres i no cometeu il·legalitats. Aquest node no s'identifica amb les opinions dels usuaris ni es responsablilitza de les mateixes.
#include doc/SiteTOS.md;

27
doc/ca/about.bb Normal file
View File

@@ -0,0 +1,27 @@
[b]Que és[/b]
$Projectname és una xarxa de comunicacions descentralitzades, que permet comunicacions lliures de censura, amb privacitat, i per tant lliure de les urpes opressores de gegants contemporanis de comunicació corporativa. Aquests gegants funcionen principalment com xarxes d''espionatge per a cobrar a clients de totes les classes i tipus, a més de monopolitzar i centralitzar Internet; una característica que no formava part dels objectius originals i revolucionàries que van produir la World Wide Web.
$Projectname és gratuït i de codi obert. Està dissenyat per a creixèr des de una raspberry pi de 35, fins el màxim de la gama de servidors AMD i servidors empresarials de múltiples nuclis que funcionen amb Intel Xeon. Pot ser utilitzat per a suportar la comunicació entre uns pocs individus, o l'escalar a molts milers i més.
$Projectname pretén ser àgil i capaç de treballar amb múltiples recursos informàtics. És fàcil d'utilitzar pels usuaris habituals d''ordinadors, així com per administradors de sistemes i desenvolupadors.
La forma d'utilitzar depèn de com voleu utilitzar-lo.
Està escrit en el llenguatge de scripting PHP, pel que és trivial instal·lar-lo en qualsevol plataforma d'allotjament en ús avui en dia. Això inclou l'auto-allotjament a casa, en els proveïdors d'allotjament, com ara [url=http://mediatemple.com/]Media Temple[/url] i [url=http://www.dreamhost.com/]Dreamhost[/url], o en servidors virtuals i dedicats, oferts per gràcia de [url=https://www.linode.com]Linode[/url], [url=http://greenqloud.com]GreenQloud[/url] o [url=https://aws.amazon.com]Amazon AWS[/url].
En altres paraules, $Projectname es pot executar en qualsevol plataforma informàtica que vingui amb un servidor web, una base de dades compatible amb MySQL i el llenguatge de scripting PHP.
De pas, $Projectname ofereix una sèrie de atractius únics:
[b]Identificació amb un sol clic d'usuari:[/b] vol dir que pot accedir a llocs en $Projectname simplement fent clic als enllaços a llocs remots. L''autenticació passa automàgicament en segon plà. Oblida't de recordar múltiples noms d'usuari amb múltiples contrasenyes en accedir a diferents llocs en línia.
[b]La clonació:[/b] de les identitats en línia. La seva presència en línia ja no ha d'estar lligat a un sol servidor, nom de domini o adreça IP. Pot clonar i importar la seva identitat (o canal com en diem) a un altre servidor (o, en un concentrasor com son coneguts els servidors a $Projectname). Ara, si el seu concentrador/servidor cau, no et preocupis, els teus contactes, missatges [i]*[/i], i els missatges de [i]*[/i] automàgicament segueixen estant disponibles i accessibles al seu canal clonat. [i](*: només es perden els missatges i els missatges a partir del moment en que va clonar el seu canal)[/i]
[b]Privacitat:[/b] les identitats a $Projectname (Zot identificadors) es poden eliminar, salvar/descarregar i clonar. L'usuari el control total de les seves dades. Si vostè decideix esborrar tot el seu contingut i esborrar la seva ID Zot, tot el que has de fer és fer clic a un enllaç i s'eliminen immediatament d concentrador/servidor. No hi ha preguntes, sense problemes.
#include doc/macros/main_footer.bb;

View File

@@ -0,0 +1,19 @@
[size=large][b]Comptes, Perfils i Canals[/b][/size]
Una vegada t'has registrat amb un [i]compte[/i] al servei, també has de crear un [i]perfil[/i] i un [i]canal[/i].
[b]Compte[/b]
Tens i]un[/i] compte. Això consisteix en una adreça de correu electrònic i una contrasenya. Amb el teu compte pots accedit al teu perfil i al teu canal.
[i]Pensa en el teu compte com una via per autenticar-te al teu lloc $Projectname. Et permet fer coses com, crear perfils i canals amb els que podràs amb altres persones.[/i]
[b]Perfil[/b]
Segurament t'has registrat a altres serveis a internet, com fòrums, o comunicacions en línia. Per a tots ells proveeixes alguna informació de tu, data de naixement, país, edat, i que es el que d'agrada. [observer=1]If you like you can see your profile here: [baseurl]/profile/[observer.webname] and edit it by clicking on the pencil icon next to your avatar image. [/observer]
Unlike other services $Projectname offers you the advantage of creating [i]many more profiles[/i]. That way you are able to distinguish between profiles targeted specially at everyone (your public profile), your work mates, your family and your partner.
[i]Think of your profile as the basic information about yourself you tell other people.[/i]
[b]Channel[/b]
During the registration you created your first [i]channel[/i]. Yes, besides several profiles you are able to have several channels. This might be a bit confusing in the beginning, but let's clear things up. You already have created one channel. You can use this one for the public, to communicate with people about every day life. But perhaps you are an avid book reader and many people are bored by that. So you open a [i]second channel[/i] just for the book lovers, where you all can talk about books as much as you like. Obviously this is a new stream of posts, with a new profile (... or new profile[i]s[/i] ...) and completely different contacts. Some connections might exist in both channels, but there will be some that are exclusive to only one of both. You yourself just switch between both of them just like you would in real life switch when talking to people you meet on the street or people you meet specially to talk about books. You can even connect to yourself, or better: to your other channel. :)
[i]Think of a channel as different spaces dedicated to different topics where you meet with different people.[/i]
#include doc/macros/main_footer.bb;

15
doc/ca/admins.bb Normal file
View File

@@ -0,0 +1,15 @@
[h2]Documentació per a Administradors de Concentradors (dits Hubs en anglès)[/h2]
[h3]Administradors[/h3]
[zrl=[baseurl]/help/install]Instal·lació[/zrl]
[zrl=[baseurl]/help/red2pi]Instal·lant $Projectname en una Raspberry Pi[/zrl]
[zrl=[baseurl]/help/Hubzilla_on_OpenShift]$Projectname en OpenShift[/zrl]
[zrl=[baseurl]/help/troubleshooting]Consells per solucionar problemes[/zrl]
[zrl=[baseurl]/help/hidden_configs]Afinant Configuracions ocultes de $Projectname[/zrl]
[zrl=[baseurl]/help/faq_admins]FAQ Per als Administradors[/zrl]
[zrl=[baseurl]/help/service_classes]Classes de Serveis[/zrl]
[zrl=[baseurl]/help/directories]Treballant amb i configuració de directoris[/zrl]
[zrl=[baseurl]/help/theme_management]Gestió de Temes[/zrl]

32
doc/ca/channels.bb Normal file
View File

@@ -0,0 +1,32 @@
[b]Canals[/b]
Els canals són simplement col·leccions de continguts emmagatzemats en un sol lloc. Un canal pot representar qualsevol cosa. Podria representi, un lloc web, un fòrum, àlbums de fotos, qualsevol cosa. Per a la majoria de la gent, el seu primer canal serà &quot;Ell&quot; mateix.
Les característiques més importants d'un canal que &quot;em&quot; representa són:
Comunicacions segures i privades &quot;lliures d'spam&quot;
Identitat i &quot;un sol inici de sessió &quot; a través de tota la xarxa
Controls de privacitat i permisos que s'estenen a tota la xarxa
Serveis de directori (com una guia telefònica)
En resum, una cadena que et representa a mateix és &quot;jo, a l'Internet &quot;.
Hauràs de crear el teu primer canal com a part del procés de registre. També pots crear canals additonal des del menú &quot;Selecciona canal &quot;.
Se li demanarà que proporcioni un nom de canal, i un curt sobrenom. Per a un canal que et representa a tu mateix, és una bona idea utilitzar el teu nom real per assegurar-se que els teus amics puguin trobar-te, i connectar al teu canal. El sobrenom curt s'utilitzarà per generar un nom &quot;intermediari&quot;. Això és una mica com un nom d'usuari, i es veurà com una adreça de correu electrònic, prenent forma sobrenom@domini. Has de pensar una mica en que desitges utilitzar aquí. Imagina a algú demanant la teu nom intermediari i haver de dir-los que és &quot;Crema-miss_issipi.123&quot;. &quot;cremamississipi&quot; seria una opció molt millor.
Una vegada que hagis creat el teu canal, se't portarà a la pàgina de configuració, que permet definir el teu canal, i establir els teus permisos predeterminats.
Un cop fet això, el canal està llest per utilitzar. En [observer=1][observer.url][/observer][observer=0]example.com/channel/username[/observer] trobaràs el teu canal de &quot;flux&quot;. Aquí és on apareixerà la teva activitat recent, en ordre cronològic invers. Si publica a la casella &quot;compartir&quot;, apareixerà l'entrada a la part superior del teu flux. També trobaràs enllaços a totes les altres àrees de comunicació per aquest canal. El fitxa &quot;en quant a &quot; conté el teu &quot;perfil&quot;, la pàgina de fotos conté àlbums de fotos, i la pàgina d'esdeveniments conté esdeveniments compartits per tu i els teus contactes.
La pàgina &quot;Xarxa&quot; conté tots els missatges recents de tota la xarxa $Projectname, de nou amb sentit cronològic invers. Els missatges exactes que apareixen aquí depenen en gran mesura dels teus permisos. En la teva forma més permissiva, rebràs missatges de desconeguts. A l'altre extrem de l'escala, podràs veure els missatges de només els seus amics - o si ets realment antisocial, només els teus propis missatges.
Com s'ha esmentat al principi, són possibles molts altres tipus de canal, però, el procediment de creació és el mateix. La diferència entre els canals es troba principalment en els permisos assignats. Per exemple, una cadena per a l'intercanvi de documents amb els seus col.legues a la feina, és millor si canvieu valors més permissius per &quot;Em pot escriure en el meu&quot; públic &quot;magatzem d'arxius &quot;, que un compte personal. Per obtenir més informació, consulteu la secció de permisos.
#include doc/macros/main_footer.bb;

34
doc/ca/develop.bb Normal file
View File

@@ -0,0 +1,34 @@
[h2]Documentació per Desenvolupadors[/h2]
[h3]Documentació Tècnica[/h3]
[zrl=[baseurl]/help/Zot---A-High-Level-Overview]Una vista en profunditat a Zot[/zrl]
[zrl=[baseurl]/help/zot]Una introducció a Zot[/zrl]
[zrl=[baseurl]/help/zot_structures]Estuctures a Zot[/zrl]
[zrl=[baseurl]/help/comanche]Descripcions de Pàgina a Comanche[/zrl]
[zrl=[baseurl]/help/Creating-Templates]Creant Plantilles a Comanche[/zrl]
[zrl=[baseurl]/help/Widgets]Artilugis[/zrl]
[zrl=[baseurl]/help/plugins]Complements[/zrl]
[zrl=[baseurl]/help/hooklist]Ganxos (detallat - en construcció)[/zrl]
[zrl=[baseurl]/help/doco]Documentació[/zrl]
[zrl=[baseurl]/help/DerivedTheme1]Creant Temes Derivats[/zrl]
[zrl=[baseurl]/help/schema_development]Esquemes[/zrl]
[zrl=[baseurl]/help/Translations]Traduccions[/zrl]
[zrl=[baseurl]/help/developers]Desenvolupadors[/zrl]
[zrl=[baseurl]/help/intro_for_developers]Introducció per Desenvolupadors[/zrl]
[zrl=[baseurl]/help/database]Documentació del esquema de la base de dades[/zrl]
[zrl=[baseurl]/help/api_functions]Funcions de la API[/zrl]
[zrl=[baseurl]/help/api_posting]Entrades a $Projectname emprant la API[/zrl]
[zrl=[baseurl]/help/developer_function_primer]Funcions Red 101[/zrl]
[zrl=[baseurl]/doc/html/]Refrència del Codi (Doxygen generat - ajust de cookies)[/zrl]
[zrl=[baseurl]/help/to_do_doco]Llista de Pendents per a la Documentació del Projecte $Projectname[/zrl]
[zrl=[baseurl]/help/to_do_code]Llista de Pendents per a Desenvolupadors[/zrl]
[zrl=[baseurl]/help/roadmap]Full de ruta[/zrl]
[zrl=[baseurl]/help/git_for_non_developers]Git per a No-Desenvolupadors[/zrl]
[zrl=[baseurl]/help/dev_beginner]Manual pas-a-pas per a desenvolupadors principiants[/zrl]
[h3]Preguntes Més Freqüents (FAQ) Per Desenvolupadors[/h3]
[zrl=[baseurl]/help/faq_developers]FAQ Per Desenvoupadors[/zrl]
[h3]Recursos Externs[/h3]
[url=https://zothub.com/channel/one]Development Channel[/url]
[url=https://federated.social/channel/postgres]Postgres-specific $Projectname Admin Support Channel[/url]

202
doc/ca/features.bb Normal file
View File

@@ -0,0 +1,202 @@
[b][size=36]Característiques[/size][/b]
[b][size=24]$Projectname en Poques Paraules[/size][/b]
TL;DR
$Projectname proveeix publicacions i comunicacions socials distribuïdes amb [b]permisos descentralitzats[/b].
Així, que vol dir "permisos descentralitzats"? Em donen la habilitat de compàrtir quelcom al meu lloc web (fotos, mitjans, arxius, pàgines web, etc.) Aamb persones específiques en llocs completament diferents - encara que no necesàriament amb [i]tothom[/i] en aquests llocs web; i no es necessita tenir un usuari i contrasenya en aquests altres llocs web per poder fer-ho ni per poder tafanejar el que ells han compartit amb mi. Ells tenen un usuari i contrasenya al seu lloc web i "màgica autenticació" entre llocs web afiliats a la xarxa. També, al esser centralitzat, no hi ha terceres parts que puguin saltar-se els permisos i veure el que estàs fent a la xarxa.
$Projectname combina moltes característiques dels blocs tradicionals, les xarxes socials i els mitjans de comunicació, sistemes de gestió de continguts i emmagatzematge en el núvol personal en un marc de treball fàcil d'utilitzar. Cada node de la xarxa pot funcionar independent o enllaçar amb altres nodes per crear una súper-xarxa; deixant la privacitat sota el control de l'editor original.
$Projectname és una aplicació de servidor web de codi obert escrit originalment en PHP/MySQL i és fàcilment instalable per aquells amb habilitats d'administració web bàsiques. També s'estén fàcilment a través de plugins i temes i altres eines de tercers.
[b][size=24]Característiques de $Projectname[/size][/b]
$Projectname és un tot terreny per a la publicació web i una xarxa de comunicacions amb diverses característiques úniques. Està dissenyat per a ser utilitzat per la gamma més àmplia de persones a la web, dels blocaires no tècnics, als programadors de PHP experts i administradors de sistemes experimentats.
A aquesta pàgina s'enumeren algunes de les característiques fonamentals de $Projectname que s'inclouen amb la versió oficial. Igual que amb la majoria del programari lliure i de codi obert, pot haver moltes altres extensions, complements, plugins, temes i configuracions que estan limitats només per les necessitats i la imaginació dels membres.
[b][size=24]Construït per la Privacitat i la Llibertat[/size][/b]
Un dels objectius de disseny de $Projectname és permetre la comunicació fàcil a la web, mentre que preserva la intimitat, si així es desitja pels membres. Per aconseguir aquest objectiu, $Projectname inclou una sèrie de característiques que permeten nivells arbitraris de privacitat:
[b]Control Lliscant d'Afinitat[/b]
En afegir connexions en $Projectname, els membres tenen l'opció d'assignar nivells de "afinitat" (el prop que la seva amistat és amb el contacte) per a la nova connexió. Per exemple, quan s'afegeix a algú que resulta ser una persona a la que segueixes el seu bloc, podries assignar al seu canal un nivell d'afinitat de &quot;Coneguts&quot;.
D'altra banda, quan s'afegeix el canal d'un amic, que pot ser col·locat sota el nivell d'afinitat de &quot;Amics&quot;.
En aquest punt, l'eina [i]Control Lliscant d'Afinitat[/i] de $Projectname, que en general apareix a la part superior de la teva pàgina, ajusta el contingut de la pàgina per incloure als que estan dins del rang afinitat desitjada. No es mostraran Canals fora d'aquest rang, llevat que s'ajusti el Control Lliscant per incloure'ls.
El Control Lliscant D'Afinitat permet filtrar instantàniament grans quantitats de contingut, agrupats per nivells de proximitat.
[b]Filtre de Connexions[/b]
Tens la capacitat de controlar amb precisió el que apareix en el teu flux emprant opcionalment el "filtre de connexió". Quan s'activa, l'editor de connexió proporciona entrades per a la selecció de criteris que ha de ser aparellat amb la finalitat d'incloure o excloure un lloc específic d'un canal específic. Una vegada que un missatge s'ha permès, tots els comentaris a aquest lloc se'ls permet, independentment de si s'ajusten als criteris de selecció. Pots seleccionar paraules que si estàn presents al bloc o assegurar-te que està inclosses en el teu flux. Les expressions regulars es poden usar per al control encara més fi, així com hashtags o fins i tot l'idioma detectat del lloc.
[b]Llista de Control d'Accés[/b]
En compartir el contingut, els membres tenen l'opció de restringir qui veu el contingut. En fer clic al cadenat sota de la casella de compartir, un pot triar els destinataris desitjats del lloc, fent clic en els seus noms.
Un cop enviat, el missatge serà visible únicament pel remitent i els destinataris seleccionats. En altres paraules, el missatge no apareixerà al mur públic.
Llistes de Control d'Accés es poden aplicar als continguts i missatges, fotos, esdeveniments, pàgines web, sales de xat i arxius.
[b]Inici de Sessió Únic[/b]
Les Llistes de Control d'Accés treballen per a tots els canals a la xarxa gràcies a la nostra tecnologia única d'inici de sessió únic. La majoria dels enllaços interns proporcionen una identitat símbolica que pot ser verificada en altres llocs $Projectname i s'utilitza per controlar l'accés als recursos privats. Entres una vegada al teu concentrador. Després d'això, l'autenticació de tots els recursos de $Projectname és "màgia".
[b]WebDAV activa l'Emagatzematge d'Arxius[/b]
Els arxius poden ser enviats a la teva àrea d'emmagatzematge personal utilitzant les teves utilitats del sistema operatiu (arrossegar i deixar anar en la majoria dels casos). Pots protegir aquests arxius amb la Llista de Control d'Accés amb qualsevol combinació de membres de $Projectname (incloent alguns membres d'altres terceres xarxes) o fer-los públics.
[b]Foto Àlbums[/b]
Salva Fotos en Àlbums. Totes les fotografies es poden protegir mitjançant llistes de control d'accés.
[b]Calendari d'Esdeveniments[/b]
Creació i gestió d'esdeveniments i tasques, que també poden ser protegits amb llistes de control d'accés. Els esdeveniments poden ser importats/exportats a un altre programari amb el format estàndard de la indústria vCalendar/iCal i compartida en els llocs amb els altres. Esdeveniments d'aniversari s'agreguen automàticament dels teus amics i es tradueixen a la seva zona horària correcta així sabràs exactament quan es produeix l'aniversari - no importa on et trobis en el món en relació amb la persona de l'aniversari. Els esdeveniments es creen normalment amb taulells d'assistència perquè els teus amics i connexions puguin confirmar la seva assistència a l'instant.
[b]Sales de Xat[/b]
Pots crear qualsevol nombre de sales de xat personals i permetre l'accés a través de llistes de control d'accés. Aquestes solen ser més segures que XMPP, IRC, i altres transports de missatgeria instantània, encara que també permetem l'ús d'aquests altres serveis a través de connectors.
[b]Constructor de Pàgines Web[/b]
$Projectname moltes eines de creació de "Gestió de Contingut" per a la creació de pàgines web, incloent l'edició disposició, menús, blocs, widgets, i pàgina/contingut per regions. Totes aquestes poden ser d'accés controlat perquè les pàgines resultants siguin privades per al seu públic objectiu.
[b]Apps/Aplicacions[/b]
Apps poden ser construïdes i distribuïdes pels membres. Aquestes aplicacions són diferents del tradicional "bloqueig pel proveïdor" perquè són controlats completament per l'autor - que pot proporcionar control d'accés a les pàgines d'aplicacions de destinació i la càrrega consegüent per a aquest accés. La majoria de les aplicacions en $Projectname són gratuïtes i es poden crear fàcilment per aquells que no tenen coneixements de programació.
[b]Disposició[/b]
La disposició de la pàgina es basa en un llenguatge de descripció anomenat Comanche. $Projectname en si mateix està escrit amb dissenys de Comanche i es poden canviar. Això permet un nivell de personalització que no se sol trobar en els anomenats "entorns multiusuari".
[b]Favorits[/b]
Compartir i guardar/administrar els enllaços de favorits proporcionats en les converses.
[b]Xifrat de missatges privats i Dubtes sobre la confidencialitat[/b]
El correu privat s'emmagatzema en un format ocult. Si això no és a prova de bales, en general, evita l'espionatge informal per l'administrador del lloc o ISP.
Cada canal de $Projectname el seu propi conjunt únic de claus RSA (de 4096 bits) públiques i privades associades, que es genera quan es crea primer els canals. Això s'utilitza per protegir els missatges privats i missatges en trànsit.
A més, els missatges poden ser creats utilitzant "xifrat d'extrem a extrem", que no pot ser llegit per els operadors $Projectname o ISPs o algú que no coneixi el codi d'accés.
Els missatges públics en general, no es xifren en trànsit o en l'emmagatzematge.
Els missatges privats poden ser retirats (com si no s'hagués enviat), encara que no es garanteix que el destinatari no l'ha llegit abans que l'hagis retirat.
Entrades i missatges poden ser creats amb una data de venciment, moment en el qual s'eliminaran/borraran en el lloc del destinatari.
[b]Servei de Federació[/b]
A més de l'afegit (addon) "connectors d'entrades creuades" a una varietat de xarxes alternatives, no hi ha suport natiu per a la importació de continguts de RSS/Atom i usar això per crear canals especials. A més, una implementació experimental, però de treball del protocol de la Diàspora permet la comunicació amb la gent en les xarxes socials friendica i Diàspora descentralitzats. Actualment això es va marcar experimental a causa de que aquestes xarxes no tenen el mateix nivell de funcions de privacitat i encriptació i habilitats com $Projectname i poden presentar riscos per a la privacitat.
També hi ha suport experimental per a l'autenticació OpenID que es pot utilitzar en les llistes de control d'accés. Aquest és un treball en progrés. El seu concentrador $Projectname pot ser utilitzat com un proveïdor d'OpenID per autenticar als serveis externs que utilitzen aquesta tecnologia.
Els canals poden tenir permisos per convertir-se en "canals derivats" on dos o més canals existents es combinen per crear un nou canal d'actualitat.
[b]Col·leccions[/b]
"Col·leccions" és la nostra implementació de grups de privacitat, que és similar a Google "Cercles" i "Aspectes" de Diaspora. Això li permet filtrar el flux entrant per col·leccions o grups, i automàticament configurar la llista de control d'accés sortint a només aquells en la Col·lecció quan publiqui. Pots obviar tot això en qualsevol moment (abans d'enviar l'entrada).
[b]Serveis de Directori [/b]
Oferim fàcil accés a un directori de membres i proporcionem eines descentralitzades capaçes de proporcionar amics "suggerits". Els directoris són llocs normals $Projectname que han optat per acceptar la funció de servidor de directori. Això requereix més recursos que la majoria dels llocs típics pel que no és el predeterminat. Els Directoris estan sincronitzats i reflecteixen el que tots ells contenen amb informació actualitzada sobre tota la xarxa (subjecte a demores normals de propagació).
[b]TLS/SSL[/b]
Els concentradors de $Projectname que empran TLS/SSL, les comunicacions entre client i servidor son encriptades via TLS/SSL. Donades les recents revelacions en els mitjans de comunicació en relació amb, la vigilància global i l'elusió de xifrat pel NSA i GCHQ, és raonable suposar que les comunicacions HTTPS-protegides es poden veure compromeses de diverses maneres. Les comunicacions privades són en conseqüència xifrades en un nivell superior abans d'enviar-les fora del lloc.
[b]Ajustos del Canals[/b]
Quan es crea un canal, es tria un rol al que s'apliquen una sèrie d'ajustos de seguretat i privacitat preconfigurats. Aquests són elegits per les millors pràctiques per mantenir la privacitat en els nivells requerits.
Si escolliu un paper privacitat "personalitzat", cada canal permet permisos de gra fi que es fixaràn per a diferents aspectes de la comunicació. Per exemple, sota la capçalera &quot;Ajusts de Seguretat i Privacitat&quot;, cada aspecte a la banda esquerra de la pàgina, té sis (6) Opcions possibles de visualització/accés, que es poden seleccionar fent clic al menú desplegable. També hi ha una sèrie d'altres opcions de privacitat que pots editar.
Les opcions són:
- Ningú, excepte tu mateix.
- Només aquells que es permeten específicament.
- Qualsevol persona en la seva llibreta d'adreces.
- Qualsevol en aquest lloc web.
- Qualsevol persona en aquesta xarxa.
- Qualsevol autenticat.
- Qualsevol persona a Internet.
[b]Forums Públics i Privats[/b]
Els fòrums són típicament canals que poden estar obertes a la participació de múltiples autors. Actualment existeixen dos mecanismes per pujar als fòrums: 1) els missatges "de mur a mur" i 2) a través de les etiquetes de foro @menció. Els fòrums poden ser creats per qualsevol persona i s'utilitzats per a qualsevol propòsit. El directori conté una opció per buscar fòrums públics. Als Fòrums privats només es poden fer entrades pels membres i sovint només son vistos pels membres.
[b]Clonat de Comptes[/b]
Els Comptes a $Projectname es refereixen com a [i]identitats nómades[/i], perquè la identitat d'un membre no està lligada al concentrador/servidor on es va crear originalment. Per exemple, quan es crea un compte de Facebook o Gmail, que està lligat a aquests serveis. No poden funcionar sense Facebook.com o Gmail.com.
Per contra, imagina que has creat una identitat a $Projectname anomenada [b]tina@Hubzillahub.com[/b]. Aquesta es pot clonar a un altre hub de $Projectname amb el mateix nom o un altre de diferent: per exemple [b]viuPerSempre@HubzillaHub.info[/b]
Tots dos canals estan ara sincronitzats, el que significa que tots els seus contactes i preferències es dupliquen en el teu clon. No importa si s'envia un missatge des del seu hub original o el nou centre. Els missatges/emtrades seran reflectits/des en tots dos comptes.
Aquesta és una característica bastant revolucionària, si tenim en compte alguns dels escenaris:
- Què passa si el concentrador/servidor on la identitat es basa cau sobtadament fora de línia? Sense clonació, un membre no pot comunicar fins que aquest centre torna a estar de nou en línia (sens dubte molts de vosaltres heu vist i maleït el Twitter "Fail Whale"). Amb la clonació, es pot iniciar la sessió al compte clonat, i la vida continua feliços per sempre. - L'administrador del teu concentrador/servidor ja no es pot permetre el luxe de pagar el concentrador/servidor $Projectname que ofereix gratuitament. Llavors anuncia que el centre serà tancant en dues setmanes. Això li dóna temps suficient als socis/partíceps per clonar la seva identitat/s i preservar les seves relacions de $Projectname, amics i contingut. - Què passa si la teva identitat està subjecta a la censura del govern? El teu proveïdor del concentrador/servidor pot ser obligat a eliminar el teu compte, juntament amb les identitats i dades associades. Amb la clonació, a $Projectname ofereixes [b]resistència a la censura[/b]. Pots tenir centenars de clons, si vols, amb noms totalment diferents, i existents en molts centres diferents, escampats a tot l'Internet.
$Projectname ofereix noves i interesants possibilitats per a la privacitat. Pots llegir més a la pàgina &lt;&lt;Bones Pràctiques en Comunicacions Privades&gt;&gt;.
A tenir en compte. Per a una explicació completa de la clonació d'identitat, llegir el &lt;HOW TO CLONE MY IDENTITY&gt;.
[b]Perfils Multiples[/b]
Es poden crear qualsevol nombre de perfils amb informació diferent i es poden fer-se visible/s a alguns de les teves connexions/amics. Un perfil "per defecte" es pot veure per qualsevol persona i pot contenir informació limitada, amb més informació disponible per grups o persones seleccionades. Això vol dir que el perfil (i el contingut del lloc) per als teus amics bevedors de cervesa pot ser diferents del que presentes als seus companys de treball, i també completament diferent del que és visible per al públic en general.
[b]Còpies de Seguretat del Compte[/b]
Hubzilla ofereix una còpia de seguretat del compte, amb un simple clic, on pots descarregar una còpia de seguretat completa del teu perfil(s).
Les còpies de seguretat es poden utilitzar per clonar o restaurar un perfil.
[b]Eliminació del Compte[/b]
Els comptes poden ser [b]esborrats immediatament[/b] fent clic en un enllaç. [b]Això és així[/b]. Tot el contingut associat s'elimina de la xarxa (això inclou els missatges i qualsevol altre tipus de contingut produït pel perfil suprimit). Depenent del nombre de connexions que , el procés d'eliminació de contingut remot podria portar el seu temps, però està previst que passi tan aviat com sigui possible.
[b][size=20]Creació de Contingut[/size][/b]
[b]Escribint Entrades[/b]
$Projectname suporta un nombre de diferents alternatives per afegir contingut amb text enriquit. La opció per defecte es una variant personalitzada de _BBcode, ajustada per al seu ús a $Projectname. Pots activar l'ús de Markdown (un llenguatge de marques) fàcil de treballar amb ell. Un editor visual també es pot emprar. El editor visual tradicionalment emprat en $Projectname va tenir seriosos problemes i ha estat eliminat. Estem actualment buscant un substitut.
Quant creem &quot;llocs Web&quot;, El contingut espot afegir en HTML, Markdown, BBcode, i/o text plà.
[b]Esborrat del contingut[/b]
Qualsevol contingut creat a $Projectname roman sota el control del membre (o canal) que el va crear originalment. En qualsevol moment, un membre pot esborrar un missatge o un rang de missatges. El procés d'esborrat assegura que el contingut es eliminat, indiferentment de on es va publicar si en el canal primari (l'inicial)del concentrador/servidor o en altre qualsevol on el canal es va autenticar remotament via Zot ($Projectname communicació i protocol d'autenticació).
[b]Multimedia[/b]
Igual que qualsevol altre sistema modern de blocs, xarxes socials, o d'un servei de micro-blogging, $Projectname és compatible amb la càrrega d'arxius, la incorporació dels vídeos, l'enllaç de pàgines web.
[b]Vista Prèvia/Edició[/b]
Les entrades es poder pre visualitzar abans d'enviar-les i reeditar desprès de ser enviades.
[b]Votacions/Consens[/b]
El missatges poden convertir-se en "consensos", són articles que ofereixen als lectors una forma de retroalimentació, es recopilen en comptadors de "d'acord", "en desacord" i "abstenir-se". Que permeten mesurar l'interès per les idees i crear enquestes informals.
[b]Estenent $Projectname[/b]
$Projectname es pot estendre per diferents nombre de vies, a través de la personalització del lloc, la teva personalització, ajustos optatius, temes i addons/plugins.
[b]API[/b]
Una API està disponible per al seu ús per serveis de terceres part. Està basat originalment en una de les primeres API's de Twitter(de la que existeixen cents d'eines de terceres parts). S'està ampliant actualment per proporcionar accés a les instal·lacions i capacitats que són específiques de $Projectname. L'accés pot ser proporcionada per usuari/contrasenya o OAuth i es proporciona registre de clients d'aplicacions OAuth.
#include doc/macros/main_footer.bb;

3
doc/ca/first-post.bb Normal file
View File

@@ -0,0 +1,3 @@
[size=large]La teva primera entrada[/size]
... pendent de ser escrita ...

20
doc/ca/general.bb Normal file
View File

@@ -0,0 +1,20 @@
[h2]Informació del Projecte/Lloc[/h2]
[zrl=[baseurl]/help/Privacy]Politica de Privacitat[/zrl]
[zrl=[baseurl]/help/history]Història de $Projectname[/zrl]
[h3]Recursos Externs[/h3]
[zrl=[baseurl]/help/external-resource-links]Enllaços a Recursos Externs[/zrl]
[url=https://github.com/redmatrix/hubzilla]Lloc Web Principal[/url]
[url=https://github.com/redmatrix/hubzilla-addons]Complements del Lloc Web[/url]
[url=[baseurl]/help/credits]Credits en $Projectname[/url]
[h3]Sobre Aquest Node $Projectname[/h3]
[zrl=[baseurl]/help/TermsOfService]Termes de Servei per a AQUEST Node[/zrl]
[zrl=[baseurl]/siteinfo]Informació del Node[/zrl]
[zrl=[baseurl]/siteinfo/json]Informació Tècnica Detallada en format JSON d'aquest Node[/zrl]

12
doc/ca/main.bb Normal file
View File

@@ -0,0 +1,12 @@
[zrl=[baseurl]/help/about][b]Que és $Projectname?[/b][/zrl]
$Projectname és una plataforma de comunicació i publicació descentralitzada que et permet mantenir el control de les teves necessitats de comunicació, gràcies a l'encriptació automàtica i control d'accés de gra fi. Éts tu, i només tu qui decideixes qui pot veure les teves coses.
[zrl=[baseurl]/help/features][b]Característiques de $Projectname[/b][/zrl]
$Projectname ja s'està executant com una xarxa distribuïda global i demostra la seva versatilitat i escalabilitat des de independent fins a grans llocs.
Penseu en plataformes independents de comunicació de la família, de comunitats en línia distribuïdes, fòrums de suport, blocs i pàgines web. O proveïdors de continguts professionals amb canals premium comercials i accés de continguts específics. El que vulguis, $Projectname és allà per atendre la teva creativitat.
[zrl=[baseurl]/help/what_is_zot][b]Tens Zot? Be, Deuries.[/b][/zrl]
Zot és el gran nou protocol de communicació inventat especialment per a $Projectname. Com a membre, ja no estàs lligat a un sol lloc o concentrador (hub) gràcies a les "identitats nòmades". Migra fàcilment a un altre servidor i manté els teus contactes intactes, o clona i executa el mateix canal en diversos servidors. Encara que un d'ells tanqui, no es perd res. A més, una vegada que estàs dins de $Projectname no hi ha necessitat d'autenticar dues vegades, fins i tot quan s'accedeix des d'un altre lloc $Projectname. Zot és el que difèrencia $Projectname de qualsevol altre projecte.

25
doc/ca/members.bb Normal file
View File

@@ -0,0 +1,25 @@
[h2]Documentació per a Membres del Concentrador[/h2]
[h3]Començant[/h3]
[zrl=[baseurl]/help/registration]Registrant un Compte[/zrl]
[zrl=[baseurl]/help/accounts_profiles_channels_basics]Tu a $Projectname: breument comptes, perfils i canals[/zrl]
[zrl=[baseurl]/help/profiles]Perfils[/zrl]
[zrl=[baseurl]/help/channels]Canals[/zrl]
[zrl=[baseurl]/help/roles]Permisos per roles i tipus de Canals[/zrl]
[zrl=[baseurl]/help/first-post]La teva primera entrada[/zrl]
[zrl=[baseurl]/help/connecting_to_channels]Connectant Amb Altres Canals[/zrl]
[zrl=[baseurl]/help/permissions]Permisos I Encriptació: Tu Tens El Control[/zrl]
[zrl=[baseurl]/help/cloud]Emmagatzegament Al Núbol[/zrl]
[zrl=[baseurl]/help/remove_account]Esborrar un Canal o un Compte[/zrl]
[h3]Ajuda per als Membres[/h3]
[zrl=[baseurl]/help/tags_and_mentions]Etiquetes i Mencions[/zrl]
[zrl=[baseurl]/help/webpages]Pàgines Web[/zrl]
[zrl=[baseurl]/help/bbcode]Referència BBcode per a entrades i comentaris[/zrl]
[zrl=[baseurl]/help/checking_account_quota_usage]Comprovant la Quota d'Ús del Compte[/zrl]
[zrl=[baseurl]/help/cloud_desktop_clients]Clients d'Escriptori al Núbol[/zrl]
[zrl=[baseurl]/help/AdvancedSearch]Cerca Avançada al Directori[/zrl]
[zrl=[baseurl]/help/addons]Ajuda pels Addons[/zrl]
[zrl=[baseurl]/help/diaspora_compat]Compatibilitat de Comunicacions amb Diaspora (Diaspora i Friendica)[/zrl]
[zrl=[baseurl]/help/faq_members]FAQ Per Membres[/zrl]
[zrl=[baseurl]/help/bugs]Errors, Assumptes, i les coses que arriben de cop a la nit...[/zrl]

37
doc/ca/profiles.bb Normal file
View File

@@ -0,0 +1,37 @@
[b]Profiles[/b]
$Projectname has unlimited profiles. You may use different profiles to show different &quot;sides of yourself&quot; to different audiences. This is different to having different channels. Different channels allow for completely different sets of information. You may have a channel for yourself, a channel for your sports team, a channel for your website, or whatever else. A profile allows for finely graded &quot;sides&quot; of each channel. For example, your default public profile might say &quot;Hello, I'm Fred, and I like laughing&quot;. You may show your close friends a profile that adds &quot;and I also enjoy dwarf tossing&quot;.
You always have a profile known as your &quot;default&quot; or &quot;public&quot; profile. This profile is always available to the general public and cannot be hidden (there may be rare exceptions on privately run or disconnected sites). You may, and probably should restrict the information you make available on your public profile.
That said, if you want other friends to be able to find you, it helps to have the following information in your public profile...
[ul][*]Your real name or at least a nickname everybody knows
[*]A photo of you
[*]Your location on the planet, at least to a country level.[/ul]
In addition, if you'd like to meet people that share some general interests with you, please take a moment and add some &quot;Keywords&quot; to your profile. Such as &quot;music, linux, photography&quot; or whatever. You can add as many keywords as you like.
To create an alternate profile, first go to [zrl=[baseurl]/settings/features]Settings &gt; Additional Features[/zrl] and enable &quot;Multiple Profiles&quot; there, otherwise you won't have the ability to use more than just your default profile.
Then select &quot;Edit Profiles&quot; from the menu of your $Projectname site. You may edit an existing profile, change the profile photo, add things to a profile or create a new profile. You may also create a &quot;clone&quot; of an existing profile if you only wish to change a few items but don't wish to enter all the information again. To do that, click on the profile you want to clone and choose &quot;Clone this profile&quot; there.
In the list of your profiles, you can also choose the contacts who can see a specific profile. Just click on &quot;Edit visibility&quot; next to the profile in question (only available for the profiles that are not your default profile) and then click on user images to add them to or remove them from the group of people who can see this profile.
Once a profile has been selected, when the person views your profile, they will see the private profile you have assigned. If they are not authenticated, they will see your public profile.
There is a setting which allows you to publish your profile to a directory and ensure that it can be found by others. You can change this setting on the &quot;Settings&quot; page.
If you do not wish to be found be people unless you give them your channel address, you may leave your profile unpublished.
[b]Keywords and Directory Search[/b]
On the directory page, you may search for people with published profiles. Currently, only the name field and the keywords are searched. You may also include such keywords in your default profile - which may be used to search for common interests with other members. Keywords are used in the channel suggestion tool and although they aren't visible in the directory, they are shown if people visit your profile page.
On your Connnections page and in the directory there is a link to &quot;Suggestions&quot; or &quot;Channel Suggestions&quot;, respectively. This will find channels who have matching and/or similar keywords. The more keywords you provide, the more relevant the search results that are returned. These are sorted by relevance.
See Also
[zrl=[baseurl]/help/AdvancedSearch]Advanced Searching[/zrl]
#include doc/macros/main_footer.bb;

35
doc/ca/registration.bb Normal file
View File

@@ -0,0 +1,35 @@
[size=large][b]Registre[/b][/size]
No tots els llocs $Projectname permeten la inscripció oberta. Si es permet el registre, veureu un enllaç de &quot; Registre &quot; immediatament sota de l'entrada a la pàgina principal del lloc. Seguint aquest enllaç et portarà a la pàgina de registre del lloc. En alguns llocs es pot redirigir a un altre lloc que permet registres. Com tots els llocs $Projectname estan vinculats, no importa on resideix el teu compte.
[b]La Teva Adreça de Correu Electrònic[/b]
Si us plau introdueix la teva adreça de correu electrònic vàlida. La teva adreça de correu electrònic mai es farà pública. Aquesta adreça s'utilitzarà per activar el teu compte, que (opcionalment) enviarà notificacions de correu electrònic per als missatges entrants o articles, [i]i per recuperar contrasenyes perdudes[/i].
[b]Contrasenya[/b]
Introdueix una contrasenya de la teva elecció, i repeix-la en la segona casella per assegurar-te que es va escriure correctament. Com $Projectname ofereix una identitat descentralitzada, Es pot accedir al teu compte en molts altres llocs web no només en el que t'has donat d'alta.
[b]Termes Del Servei[/b]
Clica a l'enllaç per llegir els [zrl=[baseurl]/help/TermsOfService]Termes de Servei[/zrl] del lloc. Una vegada llegits, marca la casella al formulari de registre per confirmar.
[b]Registre[/b]
Una vegada que hagis proporcionat els detalls necessaris, fes clic al botó "Registrar-se". Alguns llocs poden requerir l'aprovació de l'administrador abans de processar el registre, s'avisarà si aquest és el cas. Si us plau, mira el teu correu electrònic (incloent carpetes d'spam) per poder finalitzar la teva aprovació de registre.
[b]Crear un Canal[/b]
A continuació, se et presentarà la pantalla &quot; Afegir un canal&quot;. Normalment, el primer canal serà un que et representa - pel que l'ús del seu propi nom (o pseudònim) com el nom del canal és una bona idea. El nom de la cadena ha de ser pensat com un títol o descripció breu del teu canal. El &quot; triar un sobrenom curt &quot; és similar a un &quot;nom d'usuari &quot;. Farem servir tot el que entra aquí per crear una adreça de canal, que altres persones utilitzaran per connectar-se amb tu, i que utilitzaràs per iniciar sessió en altres llocs. Això s'assembla a una adreça de correu electrònic, i pren la forma nickname@siteyouregisteredat.xyz
Quan es crea el teu canal se't portarà directament a la pàgina de configuració on pots definir permisos, habilitar les funcions, etc. Totes aquestes coses es tracten a la secció corresponent dels fitxers d'ajuda.
Veure Tambè
[zrl=[baseurl]/help/accounts_profiles_channels_basics]Lo Basic sobre Identitats dins $Projectname[/zrl]
[zrl=[baseurl]/help/accounts]Comptes[/zrl]
[zrl=[baseurl]/help/profiles]Perfils[/zrl]
[zrl=[baseurl]/help/permissions]Permisos[/zrl]
[zrl=[baseurl]/help/remove_account]Eliminar Compte[/zrl]
#include doc/macros/main_footer.bb;

61
doc/ca/what_is_zot.bb Normal file
View File

@@ -0,0 +1,61 @@
[b]Qué és Zot?[/b]
Zot és el protocol que fa funcionar $Projectname, proveeix tres Característiques esencials: Comunicacions, Identitat, i Control d'Accéss.
Les funcionalitats que proveeix es poden describir de la següent manera:
- una relació en línia es només un munt de permisos
- internet és només un altre carpeta
[b][size=20]Comunicacions[/size][/b]
Zot és un protocol revolucionari que ofereix [i]comunicacions descentralitzades[/i] i [i]gestió d'identitat[/i] en tota la malla (o entrallat de connexions). El resultat es una plataforma que proveeix serveis web comparables amb els que ofereixen les grans companyies, però sense elles ni els seus problemes de privacitat, la seva insaciable necessitat de beneficis, ni la seva idea dels jardins-privats.
Comunicacions i xarxes socials són una part integral del teixit. Qualsevol canal (i qualsevol servei ofert per aquest canal) por fer ús complert de les grans caracteristiques de comunicació social a escala global. Aquestes comunicacions poden ser públiques o privades - i comunicacions privades no es limiten a encriptar totalment l'enviament, sino que també encripten l'emmagatzegament per tal d'impedir que, administradors de sistemes murris o proveidors de servei, accidental o intencionadament tafanegin o revelin dades personals.
Zot permet un ampli vental de serveis en segon plà per a la xarxa, des de oferir suggeriments d'amics, a serveis de directori. També pot realitzar altres coses que normalment només són possibles en un proveïdor centralitzat, com missatges &quot;de mur a mur&quot;. Perfils particulars/múltiples es poden crear fàcilment i el contingut del web es pot adaptar a l'espectador a través del [i]Control Lliscant d'Afinitat[/i].
No trobaràs, de cap manera, aquestes característiques en altres serveis de comunicació descentralitzades. A més de proporcionar la descentralització de concentradors (servidors), potser la característica més innovadora i interessant de Zot és el subministrament de serveis [i]d'identitat descentralitzada[/i].
[b][size=20]Identitat[/size][/b]
La capa que permet identitat mitjançant Zot es única. Facilita [i]l'identificació única invisible[/i] al llarg de tots els llocs de la malla.
També ofereix [i]identitat nómada[/i], de tal forma que les teves comunicacions amb amics, familiars , i qualsevol amb el que et comuniquis no s'han de veure afectats per la pérdua (caiguda, desconnexió) temporal/permanent del teu node de comunicació primari.
Les parts importants de la teva identitat i les relacions es poden copiar a una memòria USB, o el teu ordinador portàtil, i poden aparèixer en qualsevol node de la xarxa en qualsevol moment - amb tots els teus amics i preferències intactes.
Fonamentalment, aquestes instàncies (identitats) nòmades es mantenen en sincronia per tal que qualsevol instància pugui fer-se càrrec si un altre està en perill o danyada. Això el protegeix contra no només d'una fallada del sistema, sinó també de sobrecàrregues temporals del lloc i/o la manipulació governamental o censura.
Identitat nòmada, inici de sessió únic, i nodes $Projectname descentralitzats, al nostre parer, introduir un alt grau de grau de [i]resiliència[/i] i [i]persistència[/i] en les comunicacions d'Internet, que són profundament necessàries en direcció contrària de les tendències mundials cap a la centralització corporativa, així com la vigilància governamental indiscriminada i la censura.
Com naveges per la xarxa, els canals de visualització i el seu contingut únic, que es produeix sobre la marxa, fins i tot a través de centres de servidors completament diferents. No hi ha contrasenyes per entrar. No hi ha res a escriure. No tens que posar teu nom en cada nou lloc que visites.
Com Zot pot fer això? En diem [i]identificació-màgica[/i], perquè $Projectname oculta els detalls de les complexitats que van a l'inici únic de sessió, les identitats nòmades, i l'experiència de navegació a la xarxa. Aquest és un dels objectius de disseny de $Projectname: per augmentar la privacitat i la llibertat a la xarxa, alhora que redueix la complexitat i el tedi interposat per la necessitat d'introduir noves contrasenyes i noms d'usuari per a cada vista diferent, que pots visitar en línia.
Entrar com a usuari només una vegada en el teu centre d'origen (o qualsevol centre de recolçament nòmada que hagis triat). Això permet accedir a tots els serveis autenticats en qualsevol lloc de la malla - com ara anar a comprar, blocs, fòrums, i l'accés a la informació privada. Això és igual que els serveis oferts pels grans proveïdors de les empreses amb enormes bases de dades d'usuaris; però, pots ser un membre d'aquesta comunitat, així com un servidor en aquesta xarxa emprant un RasberryPi de 35$. La teva contrasenya no s'emmagatzema en un miler de diferents llocs, o encara pitjor, només en uns pocs llocs com Google i Facebook, fora del teu control directe.
No pots ser silenciat. No pots ser eliminat de la xarxa, llevat que triïs per sortir, tu mateix.
[b][size=20]Control d'Accés[/size][/b]
La capa de identitat de Zot permet proporcionar permisos específics a qualsevol contingut que desitgis publicar - i aquests permisos s'estenen per $ProjectName. Això és com tenir un sol súper gran espai web format per un exèrcit de petits llocs web individuals - i on cada canal a la xarxa pot controlar completament les seves preferències de privacitat i ús compartit dels recursos web que creen.
Actualment, la xarxa suporta comunicacions, àlbums de fotos, esdeveniments, i arxius. Això s'ampliarà en el futur per proporcionar serveis de gestió de continguts (pàgines web) i instal·lacions d'emmagatzematge en el núvol, com biblioteques WebDAV i multimèdia. Cada objecte i la forma en què es comparteix i amb qui està completament sota el teu control.
Aquest tipus de control està disponible en grans proveïdors de serveis com Facebook i Google, ja que poseeixen la base de dades d'usuari. Dins de la xarxa, no hi ha necessitat d'un gran usuari de base de dades a la teva màquina - perquè la xarxa [i]és[/i] la teva base de dades d'usuari. essencialment infinita capacitat (limitada pel nombre total de nodes en línia a través d'Internet), i s'estén entre centenars, i potencialment milions d'ordinadors.
L'accés pot ser concedit o negat per a qualsevol recurs, a qualsevol canal, o qualsevol grup de canals; en qualsevol lloc dins de la malla. Altres podràn accedir al teu contingut si els permets fer-ho, i ni tan sols cal tenir un compte al node. Les teves fotos privades no es poden veure, perquè els permissos realment funcionen; no són un complement que s'ha afegit a l'últim moment. Si no ets a la llista d'espectadors permesos per a una foto en particular, tu no la veuràs.
[b][size=18]Recursos Addicionals i Enllaços[/size][/b]
Per més detalla, informació tècnica sobre Zot, clica sobre algún dels següents enllaços:
- [url=https://github.com/friendica/red/wiki/Zot---A-High-Level-Overview]Vista per experts (en anglès)[/url]
- [url=https://github.com/friendica/red/wiki/zot]Especificació pel desenvolupament de Zot (en anglès)[/url]
- [url=https://github.com/redmatrix/hubzilla/blob/master/include/zot.php]Referència per la implementació de Zot en PHP (en anglès)[/url]
#include doc/macros/main_footer.bb;

View File

@@ -10,7 +10,7 @@ On many public servers there may be limits on disk usage.
The quickest and easiest way to share files is through file attachments. In the row of icons below the status post editor is a tool to upload attachments. Click the tool, select a file and submit. After the file is uploaded, you will see an attachment code placed inside the text region. Do not edit this line or it may break the ability for your friends to see the attachment. You can use the post permissions dialogue box or privacy hashtags to restrict the visibility of the file - which will be set to match the permissions of the post your are sending.
To delete attachments or change the permissions on the stored files, visit [observer.baseurl]/filestorage/{{username}}&quot; replacing {{username}} with the nickname you provided during channel creation.
To delete attachments or change the permissions on the stored files, visit [observer.baseurl]/cloud/{{username}}&quot; replacing {{username}} with the nickname you provided during channel creation.
[b]Web Access[/b]

View File

@@ -0,0 +1,3 @@
<h3>Security Settings</h3>
<p>This page contains various administrator settings related to security.</p>
<p>To save any changes you make to these settings, you must press the Submit button.</p>

View File

@@ -0,0 +1,24 @@
<script>
var contextualHelp1 = function (target, openSidePanel) {
$("#help-content").removeClass('help-content-open'); // Close the help panel
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
if (openSidePanel) {
$("main").addClass('region_1-on'); // Open the side panel to highlight element
} else {
$("main").removeClass('region_1-on');
}
// Animate the page scroll to the element and then pulse the element to direct attention
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
for (i = 0; i < 3; i++) {
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
}
}
</script>
<dl class="dl-horizontal">
<dt>General</dt>
<dd>This is the home page of a channel. It is similar to someone's profile "wall" in a social network context. Posts created by the channel are displayed according to the observer's viewing permissions.</dd>
<dt>Create a Post</dt>
<dd>If you have permission to create posts on the channel page, then you will see the post editor at the top.</dd>
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
</dl>

View File

@@ -0,0 +1,22 @@
<script>
var contextualHelp1 = function (target, openSidePanel) {
$("#help-content").removeClass('help-content-open'); // Close the help panel
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
if (openSidePanel) {
$("main").addClass('region_1-on'); // Open the side panel to highlight element
} else {
$("main").removeClass('region_1-on');
}
// Animate the page scroll to the element and then pulse the element to direct attention
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
for (i = 0; i < 3; i++) {
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
}
}
</script>
<dl class="dl-horizontal">
<dt>General</dt>
<dd>This page displays a channel's "cloud" files. The files visible to the observer depend on the individual file permissions set by the channel owner. If you have permission to create/upload files you will see control buttons above the file list.</dd>
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
</dl>

View File

@@ -0,0 +1,10 @@
<dl class="dl-horizontal">
<dt>General</dt>
<dd>The messages displayed in private mail are visible only to you and the single recipient. </dd>
<dt>Combined View</dt>
<dd>Complete conversations can be viewed in a continuous thread by selecting <b>Combined View</b>. Available conversations are displayed beneath the menu in the side panel.</dd>
<dt>Inbox/Outbox</dt>
<dd>Individual sent messages are viewed by selecting <b>Outbox</b>, and incoming messages are viewed using the <b>Inbox</b> filter.</dd>
<dt>New Message</dt>
<dd>Individual messages have delivery reports that can be viewed using the drop-down menu. Messages can also be recalled from the same menu, which can prevent the recipient from viewing the message <i>if they have not already read it</i>.</dd>
</dl>

View File

@@ -0,0 +1,26 @@
<script>
var contextualHelp1 = function (target, openSidePanel) {
$("#help-content").removeClass('help-content-open'); // Close the help panel
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
if (openSidePanel) {
$("main").addClass('region_1-on'); // Open the side panel to highlight element
} else {
$("main").removeClass('region_1-on');
}
// Animate the page scroll to the element and then pulse the element to direct attention
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
for (i = 0; i < 3; i++) {
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
}
}
</script>
<dl class="dl-horizontal">
<dt>General</dt>
<dd>The network page displays a stream of posts and conversations, typically ordered by the most recently updated. This page is highly customizable.</dd>
<dt><a href='#' onclick='contextualHelp1("#profile-jot-wrapper", 0); return false;' title="Click to highlight element...">Create a Post</a></dt>
<dd>At the top of the page there is a text box that says "Share". Clicking this box opens a new post editor. The post editor is customizable, but the basic editor provides fields for a post body and an optional post <b>Title</b>. Buttons below the text area to the left provide shortcuts to text formatting and inserting links, images, and other data into the post. The buttons to the right provide a post preview, the post permissions setting, and a <b>Submit</b> button to send the post.</dd>
<dt><a href='#' onclick='contextualHelp1("#group-sidebar", 1); return false;' title="Click to highlight element...">Privacy Groups</a></dt>
<dd>The privacy groups you have created are displayed in the side panel. Selecting them filters posts to those created by channels in the chosen group.</dd>
<dt><a href='#' onclick='$("#dbtn-acl").click(); return false;' title="Click to highlight element...">Post Permissions</a></dt>
<dd>The access control list (ACL) is what you use to set who can see your new post. Pressing the ACL button beside the Submit button will display a dialog in which you can select what channels and/or privacy groups can see the post. You can also select who is explicitly denied access. For example, say you are planning a surprise party for a friend. You can send an invitation post to everyone in your <b>Friends</b> group <i>except</i> the friend you are surprising. In this case you "show" the <b>Friends</b> group but "don't show" that one person.</dd>
</dl>

View File

@@ -0,0 +1,22 @@
<script>
var contextualHelp1 = function (target, openSidePanel) {
$("#help-content").removeClass('help-content-open'); // Close the help panel
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
if (openSidePanel) {
$("main").addClass('region_1-on'); // Open the side panel to highlight element
} else {
$("main").removeClass('region_1-on');
}
// Animate the page scroll to the element and then pulse the element to direct attention
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
for (i = 0; i < 3; i++) {
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
}
}
</script>
<dl class="dl-horizontal">
<dt>General</dt>
<dd>This page displays a channel's photo albums. The images visible to the observer depend on the individual image permissions.</dd>
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
</dl>

View File

@@ -0,0 +1,22 @@
<script>
var contextualHelp1 = function (target, openSidePanel) {
$("#help-content").removeClass('help-content-open'); // Close the help panel
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
if (openSidePanel) {
$("main").addClass('region_1-on'); // Open the side panel to highlight element
} else {
$("main").removeClass('region_1-on');
}
// Animate the page scroll to the element and then pulse the element to direct attention
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
for (i = 0; i < 3; i++) {
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
}
}
</script>
<dl class="dl-horizontal">
<dt>General</dt>
<dd>This is the profile page of a channel. It typically displays information describing the channel. If the channel represents a person in a social network, for example, then the profile might provide contact information and other personal details about the person. Channels can have multiple profiles, where the displayed profile depends on the observer.</dd>
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
</dl>

View File

@@ -7,8 +7,8 @@
[h3]Externe Ressourcen[/h3]
[zrl=[baseurl]/help/external-resource-links]Links zu externen Ressourcen[/zrl]
[url=https://github.com/redmatrix/redmatrix]Haupt-Website[/url]
[url=https://github.com/redmatrix/redmatrix-addons]Addons-Website[/url]
[url=https://github.com/redmatrix/hubzilla]Haupt-Website[/url]
[url=https://github.com/redmatrix/hubzilla-addons]Addons-Website[/url]
[url=[baseurl]/help/credits]$Projectname Credits[/url]

View File

@@ -21,7 +21,7 @@ Returns the global app structure ($a).
* App::get_observer()
(App:: is usually assigned to the global $a), so $a->get_observer() or get_app()->get_observer() - returns an xchan structure representing the current viewer if authenticated (locally or remotely).
(App:: is usually assigned to the global $a), so App::get_observer() or App::get_observer() - returns an xchan structure representing the current viewer if authenticated (locally or remotely).
* get_config($family,$key), get_pconfig($uid,$family,$key)

View File

@@ -242,7 +242,7 @@ Befor you register a first user switch off the registration mails.
Open /var/www/.htconfig.php
and make sure "0" is set in this line
[code]
$a->config['system']['verify_email'] = 0;
App::$config['system']['verify_email'] = 0;
[/code]
You should be able to change the file as "yourself" (instead of using root or www-data).

View File

@@ -30,7 +30,7 @@ To configure this, please look in your .htconfig.php file for the following text
// DIRECTORY_MODE_PRIMARY = main directory server
// DIRECTORY_MODE_STANDALONE = "off the grid" or private directory services
$a->config['system']['directory_mode'] = DIRECTORY_MODE_STANDALONE;
App::$config['system']['directory_mode'] = DIRECTORY_MODE_STANDALONE;
[/code]

View File

@@ -8,22 +8,22 @@ $a is a class defined in boot.php and passed all around $Projectname as a global
We don't ever create more than one instance and always modify the elements of the single instance. The mechanics of this are somewhat tricky. If you have a function that is passed $a and needs to modify $a you need to declare it as a reference with '&' e.g.
[code]function foo(&$a) { $a->something = 'x'; // whatever };
[code]function foo(&$a) { App::$something = 'x'; // whatever };
*or* access it within your function as a global variable via get_app()
function foo() {
$a = get_app();
$a->something = 'x';
App::$something = 'x';
}
function foo($a) { $a->something = 'x'; };
function foo($a) { App::$something = 'x'; };
will *not* change the global app state.
function foo() {
get_app()->something = 'x';
App::$something = 'x';
}
[/code]

View File

@@ -8,7 +8,7 @@ Short anser: No, there isn't. There are reasons. You are able to change permisso
If a posting is public this is even harder, as the $Projectname is a global network and there is no way to follow a post, let alone reclaim it reliably. Other networks that may receive your post have no reliable way to delete or reclaim the post.
[h3]I downloaded my channel and imported it (cloned my identity) to another site but there is no content, no posts, no photos. What is wrong???[/h3]
To be honest: Nothing. That's the way it is right now. Technically it is surely possible to take at least your own posts and maybe even files with you, but this has simply put not implemented yet. When creating this feature we thought that keeping all your contacts was more important. Your friends have already seen your old content. Once we find someone willing to implement this, it will be done. :)
Posts and photos/files are provided separately from the channel basic information. This is due to memory limitations dealing with years of conversations and photo archives. Posts and conversations can be synced separately from the basic channel information. Photos and file archives can be transferred using a plugin tool such as 'redfiles', which is currently listed as "experimental". When creating this feature we thought that keeping all your contacts was the most important task. Your friends have already seen your old content. Posts/conversations were next in priority and these may now be synced. Files and photos are the last bit to get completely working. Once we find someone willing to finish implementing this, it will be done. :)
[h3]I can't see private resources[/h3]
You have probably disabled third party cookies. You need to enable them for remote authentication to work.
[h3]There are a lot of foreign language posts. Let's auto-translate them.[/h3]

71
doc/federate.bb Normal file
View File

@@ -0,0 +1,71 @@
[h2]Creating protocol federation services[/h2]
There are three main components to writing federation plugins. These are:
[1] Channel discovery and making connections
[2] Sending posts/messages
[3] Receiving posts/messages
In addition, federation drivers must handle
[4] differences in privacy policies (and content formats)
[h3]Making connections[/h3]
The core application provides channel discovery in the following sequence:
[1] Zot channel discovery
[2] Webfinger (channel@hub) lookup
[2.1] RFC7033 webfinger
[2.2] XRD based webfinger (old style)
[3] URL discovery (currently only used to discover RSS feeds)
[4] If all of these fail, the network is "unknown" and we are unable to communicate with or connect with the channel. An 'xchan' record [i]may[/i] still be created [b]if[/b] there is enough information known to identify a unique channel.
Any of the lookup services may be bound to a plugin and extended. When a channel is discovered, we create an 'xchan' record which is a platform neutral representation of the channel identity. If we need to send information to the channel, a 'hubloc' (hub location) record is also generally required. A 'follow' plugin hook is provided to bypass webfinger and this discovery sequence completely.
The final step in gluing this together is to create an 'abook' record, which attaches an xchan in a relationship to a local channel with a given set of permissions.
For networks which do not support nomadic identity, your plugin must also set "abook_instance" which is a comma-separated list of local URLs that the remote channel is connected with. For instance if your member was connected to my channel clone at https://example.com, the abook_instance for that connection would read 'https://example.com'. If you also connected to my clone at https://abc.example.com, the string would be changed to 'https://example.com,https://abc.example.com'. This allows local channels to differentiate which instance a given remote channel is connected with and avoid delivery failures to those channels from other clone instances.
A federation plugin for a webfinger based system needs only to examine the webfinger or XRD results and identify a protocol stack which can be used to connect or communicate. Then create an xchan record with the given 'xchan_network' type and a hubloc record with the same 'hubloc_network' with the information given. Currently the plugin will need to create the entire record, but in the future this will be extended so that the plugin only need identify a network name and the record will be populated with all other known values.
An xchan record is always required in order to connect. To connect, create an abook record with the desired permissions.
Additional information that your plugin requires for communication can be stored in the xconfig table and/or abconfig table if there is no convenient or appropriate table column in the xchan or hubloc tables.
When a connection is made, we generally call the notifier (include/notifier.php) to send a message to the remote channel. This is bound to the hook 'permissions_create'. Your plugin will need to handle this in order to send a "follow" or "make friends" message to the other network.
Notes: The first stage zot lookup will be replaced with a webfinger lookup. This work is in progress. A separate lookup was required initially as webfinger does not allow non-SSL connections. We will provide non-SSL zot lookups (usually test and development sites) via the "old" XRD based webfinger to avoid this limitation.
The core application will attempt to create xchan records for projects identified as members of the "open web"; currently Hubzilla, Friendica, Diaspora, GNU-Social and Pump.io. This is so that comments can be passed amongst project sites and the network correctly identified. A federation plugin is required to fully federate with other networks, but comments may be passed to sites without such a plugin installed so that there are no unexplained holes in conversations.
The core application must also provide signing ability for Diaspora comments since they require a special signing format and must be signed by the comment author regardless of whether that channel federates with Diaspora. The owner of the conversation may federate with Diaspora so the comments must be signed. This is unfortunate but necessary.
[h3]Sending Messages[/h3]
Whenever any message is sent (with the sole exception of directory communications), we invoke the notifier (include/notifier.php), and pass it the type of message and generally an identifier to lookup the information being sent from the database (items or conversational things, private mail, permissions updates, etc.).
The notifier has several hooks which may be used by plugins in different ways, depending on how their delivery loop works. For different message types and complex delivery situations you may need to tie into multiple hooks. The 'permissions_create' hook was mentioned in the first section. There is also a 'permissions_update' message if permissions have changed and the other end of the link needs to be advised. Few services will provide or handle this (as their permissions are static), but it is also used for instance to send profile and profile photo update messages and you may wish to handle this.
The next plugin hook is 'notifier_process'. It is passed an array providing the complete state of the notifier and is called once per notifier invocation. It contains the complete list of recipients (with xchan_network set for each).
There is also 'notifier_hub' which like 'notifier_process' is passed the complete state of the notifier, but the difference is that it is called for each individual hub or distinct URL delivery and may be matched on the hubloc_network type. Hub delivery is much more efficient than recipient delivery but may not be suitable for all protocol stacks.
Your plugin will be required to understand the message state and recipients and translate the sent item to the desired format. You will also be required to check privacy and block communication to anybody but the intended recipients - *if* it is a private communication. The plugin will often at this point stick the message into the queue and return the queue id to the notifier.
Queue handlers exist already for simple posted data. If you create a queue entry with 'post' type we'll open an HTTP POST request and post the data provided and acknowledge success or failure. You can create other forms of communication by providing a different outq_driver type and handling the processing of queue requests yourself. Delivery reporting is available if you wish to acknowledge different error conditions, or anything beyond success/failure. Advanced delivery reporting will also require a custom queue type. The basic 'post' type only deals with success (communication successful with the remote site) and failure.
[h3]Receiving Messages[/h3]
Receiving messages from the remote network will probably require a 'receive' endpoint or module dedicated to your network communication protocol. This is a URL route that your plugin may need to register with the'module_loaded' hook. You module will then take responsibility for importing any data which arrives at that endpoint and translating it to the format required for this project and storing the resulting data. The basic structure we use is an extensible activitystream item but with slightly different field names and several optional fields. It can be easily mapped to an activitystream. Additional data can be stored in the "iconfig" table. item_store() and item_store_update() are generally used to store the data and send appropriate notifications. Similiar facilities are available for private mail and profile information.

61
doc/filesync.md Normal file
View File

@@ -0,0 +1,61 @@
File Sync and Clone
===================
File cloning across multiple instances of a channel is a very hard problem, due to the nature of PHP memory allocation. This needs to be handled dramatically differently than cloning or syncing of other information. (Processing one large video file or 40-50 photos could exhaust memory). Therefore we can't easily just dump all the data to a dump file and sequentially process it. Loading the dump file itself is likely to exhaust memory.
There are also two primary operations we are considering. The first is the hardest - saving and then importing all your channel information into a new channel clone. The second is synchronising file changes as they occur across two or more "active" clones.
For the first cut at this tool we will concentrate on the second case, while trying to maintain some measure of compatibility with the first case so that we can re-use the same tools.
Meta Data
=========
First we need the metadata for the file in order to precisely re-construct its structure on another site. This requires the following information:
'attach' structure (without file contents - which is the default) for the file itself **and** its parent directories so that we can re-create its precise place in the file system, since we do not know if the parent directory has been imported previously or ever.
'photo' structure for any photo elements which were created as a result of uploading this file into the system. This typically contains several different 'scales' or thumbnail images, some of which may be cropped for profile photo use or cover photo use. We need to retain the cropping information which is not present in the metadata, but only in the stored data. The actual thumbnail image data may or may not be included in the metadata. A cover photo of large scale (scale #7) could potentially cause memory issues. Not as bad as a 100M video, but if you have several of these they could add up.
'item' entries which are linked to this file. These can be file share activities, the "parent item" linked to photos, and any attached conversation items (photo likes, comments, etc.)
All of these items will require URL replacement and re-signing of the item as they are relocated to another site.
File Data
=========
Then we have the actual file data we need to reconstruct the file. This needs to be stored separately from the meta-data to avoid memory exhaustion when processing. The actual file data can be used to reconstruct the attach structure and the first four photo scales. If this is a photo, we need access to the "#4 scale" (profile photo) and the #7 scale (cover photo) as they were originally cropped. All other thumbnails can be generated from these.
File Sync
=========
We will consider this operation first because it is probably the most straightforward to implement. When a photo is added to or removed or changed from the source system, we will send a clone sync packet to all known clones containing the metadata - but **no file data** . We can only send one sync packet per file operation that needs to be synced.
The receiving end will create and perform URL translation on all the metadata structures and store them. Then it will need to fetch the actual data. Assuming CURL supports streaming, an authenticated request is sent to the original site and the original file is requested and streamed directly to disk (bypassing all processing). If photo scale #4 or scale #7 is required, these are requested and stored into their respective structures. We're assuming in this case that the cover photo large scale will not exhaust memory. If CURL cannot be made to support streaming, request packets need to be queued and sent to the origination site to obtain "chunks" of the file and re-assembled once all chunks have been retrieved.
The authenticated request depends on the mechanism. For CURL streaming, some signed secret with a timestamp will probably need to be generated and posted to the file origination site. Then the data can be retrieved with minimal internal processing and dumped directly to disk using stdio buffering. In the case of a zot request, the zot request packet will be validated, however scheduling chunk batches and re-assembling them could be tricky.
File Backup/Restore
===================
This is much more complicated as we do not have an authenticate web server to request data from. The metadata can be mostly the same, but we need some form of signalling that we will not be fetching the file via the web. This will likely require a client side process to parse each metadata file and locate a file on disk which it is associated with. Then the data would need to be streamed to the destination server with a special endpoint designed for this task. A java app might be the best option here to retain platform neutrality.
Another option would be to use WebDAV for this step. The metadata files would be uploaded first, and then the data files. If a data file corresponded to an existing metadata file, the metadata would be processed; the file stored appropriately, and the metadata file then removed. In this case, photos of scales 4 and 7 would need to be provided in the metadata.
Optionally, this step could also be performed with a filesystem local to the destination server. This would be the highest performance, and a suite of shell-based tools (in the case of Linux) could perform the "client-side" of the task.
The complexity of this task mandates careful planning into how the data is organised and stored and if necessary backed up remotely or transmitted for backup by the source website.
Backward Compatibility
======================
There are some obvious issues with making data available for backup or cloning which existed on the system prior to the existence of restore/sync tools. To keep the tools themselves relatively uncomplicated (to the extent possible given the constraints) backward compatibility may have to be preformed by dedicated plugin or addon.

View File

@@ -14,7 +14,7 @@ Once you've done that, cd into the directory, and add an upstream.
[code]
cd red
git remote add upstream https://github.com/redmatrix/redmatrix
git remote add upstream https://github.com/redmatrix/hubzilla
[/code]
From now on, you can pull upstream changes with the command

View File

@@ -83,7 +83,9 @@ This document assumes you're an administrator.
'forum', 'forum_restricted' and 'forum_private'.
Read more about permissions roles [zrl=[baseurl]/help/roles]here[/zrl].
[b]system.workflow_channel_next[/b]
The page to direct users to immediately after creating a channel.
The page to direct new members to immediately after creating a channel.
[b]system.workflow_register_next[/b]
The page to direct members to immediately after creating an account (only when auto_channel_create or UNO is enabled).
[b]system.max_daily_registrations[/b]
Set the maximum number of new registrations allowed on any day.
Useful to prevent oversubscription after a bout of publicity
@@ -100,6 +102,10 @@ This document assumes you're an administrator.
[b]system.paranoia[/b]
As the pconfig, but on a site-wide basis. Can be overwritten
by member settings.
[b]system.transport_security_header[/b]
if non-zero and SSL is being used, include a strict-transport-security header on webpages
[b]system.poke_basic[/b]
Reduce the number of poke verbs to exactly 1 ("poke"). Disable other verbs.
[b]system.openssl_conf_file[/b]
Specify a file containing OpenSSL configuration. Read the code first.
If you can't read the code, don't play with it.

View File

@@ -1 +0,0 @@
[h2]discover_by_webbie[/h2]

View File

@@ -0,0 +1,14 @@
[h2]discover_channel_webfinger[/h2]
Called after performing channel discovery using RFC7033 webfinger and where the channel is not recognised as zot.
Passed an array:
address: URL or address that is being discovered
success: set to true if the plugin discovers something
webfinger: array of webfinger links (output of webfinger_rfc7033())
if your plugin indicates success you are expected to generate and populate an xchan (and hubloc) record prior to returning.

View File

@@ -8,5 +8,5 @@ The hook data for this call consists of an array
This element contains the HTML content which was prepared for this page by calling the module_content() function. It is invoked after the content has been created. It does not contain the result of AJAX or asynchronous page load calls.
The current module may be determined by lookin at $a->module
The current module may be determined by lookin at App::$module

View File

@@ -6,5 +6,5 @@ The hook data for this call consists of an array
This element contains the HTML content before calling the module_content() function. It is invoked before the content region has been populated. This may or may not be empty as there may be other processes or addons generating content prior to your hook handler is run. Be certain to preserve any current content. Typically anything you add here will be placed at the top of the content region of the page, but in any event prior to the main content region being generated.
The current module may be determined by lookin at $a->module
The current module may be determined by lookin at App::$module

View File

@@ -127,7 +127,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/directory_item]directory_item[/zrl]
Called when generating a directory listing for display
[zrl=[baseurl]/help/hook/discover_by_webbie]discover_by_webbie[/zrl]
[zrl=[baseurl]/help/hook/discover_channel_webfinger]discover_channel_webfinger[/zrl]
Called when performing a webfinger lookup
[zrl=[baseurl]/help/hook/display_item]display_item[/zrl]

View File

@@ -17,7 +17,6 @@ We need much more than this, but here are areas where developers can help. Pleas
[li]Integrate the &quot;open site&quot; list with the register page[/li]
[li]Support comments and member notes on documentation pages (to achieve an effect similar to php.net)[/li]
[li]Support comments on webpages[/li]
[li]implement oembed provider interface[/li]
[li]refactor the oembed client interface so that we can safely sandbox remote content[/li]
[li]Write more webpage layouts[/li]
[li]Write more webpage widgets[/li]
@@ -33,8 +32,6 @@ We need much more than this, but here are areas where developers can help. Pleas
[li]API extensions, for Twitter API - search, friending, threading. For Red API, lots of stuff[/li]
[li]Import channel from Diaspora/Friendica (Diaspora partially done)[/li]
[li]MediaGoblin photo "crosspost" connector[/li]
[li]Create management page/UI for extensible profile fields[/li]
[li]Create interface to include/exclude and re-order standard profile fields[/li]
[li]App taxonomy[/li]
[li]Customisable App collection pages[/li]
[li]replace the tinymce visual editor and/or make the visual editor pluggable and responsive to different output formats. We probably want library/bbedit for bbcode. This needs a fair bit of work to catch up with our &quot;enhanced bbcode&quot;, but start with images, links, bold and highlight and work from there.[/li]

View File

@@ -1,4 +1,5 @@
<?php /** @file */
if(class_exists('BaseObject'))
return;

View File

@@ -75,12 +75,12 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
$a = get_app();
if(! $xchan) {
if($a->poi) {
$xchan = $a->poi;
if(App::$poi) {
$xchan = App::$poi;
}
elseif(is_array($a->profile) && $a->profile['channel_hash']) {
elseif(is_array(App::$profile) && App::$profile['channel_hash']) {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($a->profile['channel_hash'])
dbesc(App::$profile['channel_hash'])
);
if($r)
$xchan = $r[0];
@@ -102,7 +102,7 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
}
if(array_key_exists('channel_id',$xchan))
$a->profile_uid = $xchan['channel_id'];
App::$profile_uid = $xchan['channel_id'];
$url = (($observer)
? z_root() . '/magic?f=&dest=' . $xchan['xchan_url'] . '&addr=' . $xchan['xchan_addr']
@@ -111,7 +111,7 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
return replace_macros(get_markup_template('xchan_vcard.tpl'),array(
'$name' => $xchan['xchan_name'],
'$photo' => ((is_array($a->profile) && array_key_exists('photo',$a->profile)) ? $a->profile['photo'] : $xchan['xchan_photo_l']),
'$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']),
'$follow' => $xchan['xchan_addr'],
'$link' => zid($xchan['xchan_url']),
'$connect' => $connect,
@@ -235,7 +235,7 @@ function account_remove($account_id,$local = true,$unset_session=true) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
notice( sprintf(t("User '%s' deleted"),$account_email) . EOL);
goaway(get_app()->get_baseurl());
goaway(z_root());
}
return $r;
@@ -263,7 +263,7 @@ function rrmdir($path)
return false;
}
function channel_remove($channel_id, $local = true, $unset_session=true) {
function channel_remove($channel_id, $local = true, $unset_session=false) {
if(! $channel_id)
return;
@@ -333,19 +333,19 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
);
// if this was the default channel, set another one as default
if($a->account['account_default_channel'] == $channel_id) {
if(App::$account['account_default_channel'] == $channel_id) {
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1",
intval($a->account['account_id']),
intval(App::$account['account_id']),
intval(PAGE_REMOVED));
if ($r) {
$rr = q("update account set account_default_channel = %d where account_id = %d",
intval($r[0]['channel_id']),
intval($a->account['account_id']));
intval(App::$account['account_id']));
logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']);
}
else {
$rr = q("update account set account_default_channel = 0 where account_id = %d",
intval($a->account['account_id'])
intval(App::$account['account_id'])
);
}
}
@@ -389,9 +389,8 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
proc_run('php','include/directory.php',$channel_id);
if($channel_id == local_channel() && $unset_session) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
goaway($a->get_baseurl());
\Zotlabs\Web\Session::nuke();
goaway(z_root());
}
}

View File

@@ -15,6 +15,7 @@ require_once('include/items.php');
*/
class Conversation extends BaseObject {
private $threads = array();
private $mode = null;
private $observer = null;
@@ -47,33 +48,26 @@ class Conversation extends BaseObject {
$a = $this->get_app();
$this->observer = $a->get_observer();
$this->observer = App::get_observer();
$ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
switch($mode) {
case 'network':
// if(array_key_exists('firehose',$a->data) && intval($a->data['firehose'])) {
// $this->profile_owner = intval($a->data['firehose']);
// $this->writable = false;
// }
// else {
$this->profile_owner = local_channel();
$this->writable = true;
// }
$this->profile_owner = local_channel();
$this->writable = true;
break;
case 'channel':
$this->profile_owner = $a->profile['profile_uid'];
$this->profile_owner = App::$profile['profile_uid'];
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
break;
case 'display':
// in this mode we set profile_owner after initialisation (from conversation()) and then
// pull some trickery which allows us to re-invoke this function afterward
// it's an ugly hack so FIXME
// $this->profile_owner = $a->profile['uid'];
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
break;
case 'page':
$this->profile_owner = $a->profile['uid'];
$this->profile_owner = App::$profile['uid'];
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
break;
default:
@@ -142,11 +136,11 @@ class Conversation extends BaseObject {
public function add_thread($item) {
$item_id = $item->get_id();
if(!$item_id) {
logger('[ERROR] Conversation::add_thread : Item has no ID!!', LOGGER_DEBUG);
logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR);
return false;
}
if($this->get_thread($item->get_id())) {
logger('[WARN] Conversation::add_thread : Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG);
logger('Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG, LOG_WARNING);
return false;
}
@@ -177,11 +171,6 @@ class Conversation extends BaseObject {
}
}
require_once('include/identity.php');
// $sys = get_sys_channel();
// if($sys && $item->get_data_value('uid') == $sys['channel_id']) {
// $item->set_commentable(false);
// }
$item->set_conversation($this);
$this->threads[] = $item;
@@ -209,7 +198,7 @@ class Conversation extends BaseObject {
$item_data = $item->get_template_data($conv_responses);
}
if(!$item_data) {
logger('[ERROR] Conversation::get_template_data : Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG);
logger('Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG, LOG_ERR);
return false;
}
$result[] = $item_data;

View File

@@ -8,7 +8,7 @@ require_once('include/photo/photo_driver.php');
function import_diaspora($data) {
$a = get_app();
$account = $a->get_account();
$account = App::get_account();
if(! $account)
return false;

View File

@@ -97,7 +97,7 @@ class Item extends BaseObject {
$mode = $conv->get_mode();
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
$edpost = array($a->get_baseurl($ssl_state)."/editpost/".$item['id'], t("Edit"));
$edpost = array(z_root()."/editpost/".$item['id'], t("Edit"));
else
$edpost = false;
@@ -241,7 +241,7 @@ class Item extends BaseObject {
$has_bookmarks = false;
if(is_array($item['term'])) {
foreach($item['term'] as $t) {
if($t['type'] == TERM_BOOKMARK)
if(!UNO && $t['type'] == TERM_BOOKMARK)
$has_bookmarks = true;
}
}
@@ -681,14 +681,20 @@ class Item extends BaseObject {
$qc = ((local_channel()) ? get_pconfig(local_channel(),'system','qcomment') : null);
$qcomment = (($qc) ? explode("\n",$qc) : null);
$arr = array('comment_buttons' => '','id' => $this->get_id());
call_hooks('comment_buttons',$arr);
$comment_buttons = $arr['comment_buttons'];
$comment_box = replace_macros($template,array(
'$return_path' => '',
'$threaded' => $this->is_threaded(),
'$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
'$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
'$id' => $this->get_id(),
'$parent' => $this->get_id(),
'$qcomment' => $qcomment,
'$comment_buttons' => $comment_buttons,
'$profile_uid' => $conv->get_profile_owner(),
'$mylink' => $observer['xchan_url'],
'$mytitle' => t('This is you'),
@@ -708,7 +714,7 @@ class Item extends BaseObject {
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
'$encrypt' => t('Encrypt text'),
'$cipher' => $conv->get_cipher(),
'$sourceapp' => get_app()->sourcename
'$sourceapp' => App::$sourcename
));

View File

@@ -248,7 +248,7 @@ function verify_email_address($arr) {
$res = mail($arr['email'], email_header_encode(sprintf( t('Registration confirmation for %s'), get_config('system','sitename'))),
$email_msg,
'From: ' . 'Administrator' . '@' . get_app()->get_hostname() . "\n"
'From: ' . 'Administrator' . '@' . App::get_hostname() . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
. 'Content-transfer-encoding: 8bit'
);
@@ -314,7 +314,7 @@ function send_reg_approval_email($arr) {
$res = mail($admin['email'], sprintf( t('Registration request at %s'), get_config('system','sitename')),
$email_msg,
'From: ' . t('Administrator') . '@' . get_app()->get_hostname() . "\n"
'From: ' . t('Administrator') . '@' . App::get_hostname() . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
. 'Content-transfer-encoding: 8bit'
);
@@ -341,7 +341,7 @@ function send_register_success_email($email,$password) {
$res = mail($email, sprintf( t('Registration details for %s'), get_config('system','sitename')),
$email_msg,
'From: ' . t('Administrator') . '@' . get_app()->get_hostname() . "\n"
'From: ' . t('Administrator') . '@' . App::get_hostname() . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
. 'Content-transfer-encoding: 8bit'
);
@@ -407,7 +407,7 @@ function account_allow($hash) {
pop_lang();
if(get_config('system','auto_channel_create'))
if(get_config('system','auto_channel_create') || UNO)
auto_channel_create($register[0]['uid']);
if ($res) {
@@ -500,7 +500,7 @@ function account_approve($hash) {
);
if(get_config('system','auto_channel_create'))
if(get_config('system','auto_channel_create') || UNO)
auto_channel_create($register[0]['uid']);
info( t('Account verified. Please login.') . EOL );
@@ -655,7 +655,7 @@ function account_service_class_allows($aid, $property, $usage = false) {
function service_class_fetch($uid, $property) {
$a = get_app();
if($uid == local_channel()) {
$service_class = $a->account['account_service_class'];
$service_class = App::$account['account_service_class'];
}
else {
$r = q("select account_service_class as service_class

View File

@@ -23,7 +23,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
// e.g. 'network_pre_group_deny', 'profile_pre_group_allow'
call_hooks($a->module . '_pre_' . $selname, $arr);
call_hooks(App::$module . '_pre_' . $selname, $arr);
if($r) {
foreach($r as $rr) {
@@ -39,7 +39,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
}
$o .= "</select>\r\n";
call_hooks($a->module . '_post_' . $selname, $o);
call_hooks(App::$module . '_post_' . $selname, $o);
return $o;
@@ -127,7 +127,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
// e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
call_hooks($a->module . '_pre_' . $selname, $arr);
call_hooks(App::$module . '_pre_' . $selname, $arr);
if(count($r)) {
foreach($r as $rr) {
@@ -145,7 +145,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
$o .= "</select>\r\n";
call_hooks($a->module . '_post_' . $selname, $o);
call_hooks(App::$module . '_post_' . $selname, $o);
return $o;
}*/
@@ -182,7 +182,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
// e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
call_hooks($a->module . '_pre_' . $selname, $arr);
call_hooks(App::$module . '_pre_' . $selname, $arr);
if($r) {
foreach($r as $rr) {
@@ -200,7 +200,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$o .= "</select>\r\n";
call_hooks($a->module . '_post_' . $selname, $o);
call_hooks(App::$module . '_post_' . $selname, $o);
return $o;
}

View File

@@ -11,7 +11,7 @@ function profile_activity($changed, $value) {
require_once('include/items.php');
$self = $a->get_channel();
$self = App::get_channel();
if(! count($self))
return;

View File

@@ -34,7 +34,7 @@ require_once('include/api_auth.php');
function api_user() {
$aid = get_account_id();
$channel = get_app()->get_channel();
$channel = App::get_channel();
if(($aid) && (x($_REQUEST,'channel'))) {
@@ -79,7 +79,7 @@ require_once('include/api_auth.php');
$type="json";
foreach ($API as $p=>$info){
if (strpos($a->query_string, $p)===0){
if (strpos(App::$query_string, $p)===0){
$called_api= explode("/",$p);
//unset($_SERVER['PHP_AUTH_USER']);
if ($info['auth'] === true && api_user() === false) {
@@ -88,18 +88,18 @@ require_once('include/api_auth.php');
load_contact_links(api_user());
$channel = $a->get_channel();
$channel = App::get_channel();
logger('API call for ' . $channel['channel_name'] . ': ' . $a->query_string);
logger('API call for ' . $channel['channel_name'] . ': ' . App::$query_string);
logger('API parameters: ' . print_r($_REQUEST,true));
$type="json";
if (strpos($a->query_string, ".xml")>0) $type="xml";
if (strpos($a->query_string, ".json")>0) $type="json";
if (strpos($a->query_string, ".rss")>0) $type="rss";
if (strpos($a->query_string, ".atom")>0) $type="atom";
if (strpos($a->query_string, ".as")>0) $type="as";
if (strpos(App::$query_string, ".xml")>0) $type="xml";
if (strpos(App::$query_string, ".json")>0) $type="json";
if (strpos(App::$query_string, ".rss")>0) $type="rss";
if (strpos(App::$query_string, ".atom")>0) $type="atom";
if (strpos(App::$query_string, ".as")>0) $type="as";
$r = call_user_func($info['func'], $a, $type);
if ($r===false) return;
@@ -141,7 +141,7 @@ require_once('include/api_auth.php');
}
}
header("HTTP/1.1 404 Not Found");
logger('API call not implemented: '.$a->query_string." - ".print_r($_REQUEST,true));
logger('API call not implemented: '.App::$query_string." - ".print_r($_REQUEST,true));
$r = '<status><error>not implemented</error></status>';
switch($type){
case "xml":
@@ -171,12 +171,12 @@ require_once('include/api_auth.php');
$arr['$user'] = $user_info;
$arr['$rss'] = array(
'alternate' => $user_info['url'],
'self' => $a->get_baseurl(). "/". $a->query_string,
'base' => $a->get_baseurl(),
'self' => z_root(). "/". App::$query_string,
'base' => z_root(),
'updated' => api_date(null),
'atom_updated' => datetime_convert('UTC','UTC','now',ATOM_TIME),
'language' => $user_info['language'],
'logo' => $a->get_baseurl()."/images/rm-64.png",
'logo' => z_root()."/images/rm-64.png",
);
return $arr;
@@ -213,7 +213,7 @@ require_once('include/api_auth.php');
$extra_query .= " AND abook_channel = ".intval(api_user());
}
if (is_null($user) && argc() > (count($called_api)-1) && (strstr($a->cmd,'/users'))){
if (is_null($user) && argc() > (count($called_api)-1) && (strstr(App::$cmd,'/users'))){
$argid = count($called_api);
list($xx, $null) = explode(".",argv($argid));
if(is_numeric($xx)){
@@ -318,7 +318,7 @@ require_once('include/api_auth.php');
'location' => ($usr) ? $usr[0]['channel_location'] : '',
'profile_image_url' => $uinfo[0]['xchan_photo_l'],
'url' => $uinfo[0]['xchan_url'],
'contact_url' => $a->get_baseurl() . "/connections/".$uinfo[0]['abook_id'],
'contact_url' => z_root() . "/connections/".$uinfo[0]['abook_id'],
'protected' => false,
'friends_count' => intval($countfriends),
'created_at' => api_date($uinfo[0]['abook_created']),
@@ -326,7 +326,7 @@ require_once('include/api_auth.php');
'time_zone' => 'UTC', //$uinfo[0]['timezone'],
'geo_enabled' => false,
'statuses_count' => intval($countitms), //#XXX: fix me
'lang' => get_app()->language,
'lang' => App::$language,
'description' => (($profile) ? $profile[0]['pdesc'] : ''),
'followers_count' => intval($countfollowers),
'favourites_count' => intval($starred),
@@ -486,7 +486,7 @@ require_once('include/api_auth.php');
function api_account_logout(&$a, $type){
require_once('include/auth.php');
nuke_session();
\Zotlabs\Web\Session::nuke();
return api_apply_template("user", $type, array('$user' => null));
}
@@ -635,13 +635,13 @@ require_once('include/api_auth.php');
function api_albums(&$a,$type) {
json_return_and_die(photos_albums_list($a->get_channel(),$a->get_observer()));
json_return_and_die(photos_albums_list(App::get_channel(),App::get_observer()));
}
api_register_func('api/red/albums','api_albums', true);
function api_photos(&$a,$type) {
$album = $_REQUEST['album'];
json_return_and_die(photos_list_photos($a->get_channel(),$a->get_observer(),$album));
json_return_and_die(photos_list_photos(App::get_channel(),App::get_observer(),$album));
}
api_register_func('api/red/photos','api_photos', true);
@@ -768,7 +768,7 @@ require_once('include/api_auth.php');
}
$txt = html2bbcode($txt);
$a->argv[1] = $user_info['screen_name'];
App::$argv[1] = $user_info['screen_name'];
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
$_FILES['userfile'] = $_FILES['media'];
@@ -872,7 +872,7 @@ require_once('include/api_auth.php');
// upload each image if we have any
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
require_once('mod/wall_attach.php');
$a->data['api_info'] = $user_info;
App::$data['api_info'] = $user_info;
$media = wall_attach_post($a);
if(strlen($media)>0)
@@ -885,7 +885,7 @@ require_once('include/api_auth.php');
// upload each image if we have any
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
require_once('mod/wall_attach.php');
$a->data['api_info'] = $user_info;
App::$data['api_info'] = $user_info;
$media = wall_attach_post($a);
if(strlen($media)>0)
@@ -960,7 +960,7 @@ require_once('include/api_auth.php');
$arr['records'] = 999999;
$arr['item_type'] = '*';
$i = items_fetch($arr,$a->get_channel(),get_observer_hash());
$i = items_fetch($arr,App::get_channel(),get_observer_hash());
if(! $i)
json_return_and_die(array());
@@ -1230,7 +1230,7 @@ require_once('include/api_auth.php');
$sql_extra .= ' AND `item`.`parent` = `item`.`id`';
if (api_user() != $user_info['uid']) {
$observer = get_app()->get_observer();
$observer = App::get_observer();
require_once('include/permissions.php');
if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
return '';
@@ -1272,8 +1272,8 @@ require_once('include/api_auth.php');
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as['title'] = $a->config['sitename']." Home Timeline";
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
$as['title'] = App::$config['sitename']." Home Timeline";
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
return($as);
break;
}
@@ -1333,8 +1333,8 @@ require_once('include/api_auth.php');
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as['title'] = $a->config['sitename']. " " . t('Public Timeline');
$as['link']['url'] = $a->get_baseurl()."/";
$as['title'] = App::$config['sitename']. " " . t('Public Timeline');
$as['link']['url'] = z_root()."/";
return($as);
break;
}
@@ -1409,7 +1409,7 @@ require_once('include/api_auth.php');
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
$observer = get_app()->get_observer();
$observer = App::get_observer();
$item_normal = item_normal();
@@ -1526,7 +1526,7 @@ require_once('include/api_auth.php');
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
$myurl = $a->get_baseurl() . '/channel/'. $a->user['nickname'];
$myurl = z_root() . '/channel/'. App::$user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/channel/','/u/',$myurl);
@@ -1561,8 +1561,8 @@ require_once('include/api_auth.php');
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as["title"] = $a->config['sitename']." Mentions";
$as['link']['url'] = $a->get_baseurl()."/";
$as["title"] = App::$config['sitename']." Mentions";
$as['link']['url'] = z_root()."/";
return($as);
break;
}
@@ -1633,7 +1633,7 @@ require_once('include/api_auth.php');
$arr['cid'] = $user_info['id'];
$r = items_fetch($arr,get_app()->get_channel(),get_observer_hash());
$r = items_fetch($arr,App::get_channel(),get_observer_hash());
$ret = api_format_items($r,$user_info);
@@ -1752,7 +1752,7 @@ require_once('include/api_auth.php');
$sql_extra .= ' AND `item`.`parent` = `item`.`id`';
if (api_user() != $user_info['uid']) {
$observer = get_app()->get_observer();
$observer = App::get_observer();
require_once('include/permissions.php');
if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
return '';
@@ -1783,8 +1783,8 @@ require_once('include/api_auth.php');
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as['title'] = $a->config['sitename']." Home Timeline";
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
$as['title'] = App::$config['sitename']." Home Timeline";
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
return($as);
break;
}
@@ -1801,7 +1801,7 @@ require_once('include/api_auth.php');
function api_format_as($a, $ret, $user_info) {
$as = array();
$as['title'] = $a->config['sitename']." Public Timeline";
$as['title'] = App::$config['sitename']." Public Timeline";
$items = array();
foreach ($ret as $item) {
$singleitem["actor"]["displayName"] = $item["user"]["name"];
@@ -1857,7 +1857,7 @@ require_once('include/api_auth.php');
$items[] = $singleitem;
}
$as['items'] = $items;
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
$as['link']['rel'] = "alternate";
$as['link']['type'] = "text/html";
return($as);
@@ -1978,8 +1978,8 @@ require_once('include/api_auth.php');
'entities' => '',
'objecttype' => (($item['obj_type']) ? $item['obj_type'] : ACTIVITY_OBJ_NOTE),
'verb' => (($item['verb']) ? $item['verb'] : ACTIVITY_POST),
'self' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type,
'edit' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type,
'self' => z_root()."/api/statuses/show/".$item['id'].".".$type,
'edit' => z_root()."/api/statuses/show/".$item['id'].".".$type,
);
$status = array_merge($status, $status2);
@@ -2088,8 +2088,8 @@ require_once('include/api_auth.php');
load_config('system');
$name = get_config('system','sitename');
$server = $a->get_hostname();
$logo = $a->get_baseurl() . '/images/rm-64.png';
$server = App::get_hostname();
$logo = z_root() . '/images/rm-64.png';
$email = get_config('system','admin_email');
$closed = ((get_config('system','register_policy') == REGISTER_CLOSED) ? 'true' : 'false');
$private = ((get_config('system','block_public')) ? 'true' : 'false');
@@ -2097,7 +2097,7 @@ require_once('include/api_auth.php');
if(get_config('system','api_import_size'))
$texlimit = string(get_config('system','api_import_size'));
$ssl = ((get_config('system','have_ssl')) ? 'true' : 'false');
$sslserver = (($ssl === 'true') ? str_replace('http:','https:',$a->get_baseurl()) : '');
$sslserver = (($ssl === 'true') ? str_replace('http:','https:',z_root()) : '');
$config = array(
'site' => array('name' => $name,'server' => $server, 'theme' => 'default', 'path' => '',
@@ -2106,10 +2106,10 @@ require_once('include/api_auth.php');
'private' => $private, 'textlimit' => $textlimit, 'sslserver' => $sslserver, 'ssl' => $ssl,
'shorturllength' => '30',
'hubzilla' => array(
'PLATFORM_NAME' => get_platform_name(),
'RED_VERSION' => get_project_version(),
'PLATFORM_NAME' => Zotlabs\Project\System::get_platform_name(),
'RED_VERSION' => Zotlabs\Project\System::get_project_version(),
'ZOT_REVISION' => ZOT_REVISION,
'DB_UPDATE_VERSION' => get_update_version()
'DB_UPDATE_VERSION' => Zotlabs\Project\System::get_update_version()
)
));
@@ -2142,12 +2142,12 @@ require_once('include/api_auth.php');
if($type === 'xml') {
header("Content-type: application/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>' . get_project_version() . '</version>' . "\r\n";
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>' . Zotlabs\Project\System::get_project_version() . '</version>' . "\r\n";
killme();
}
elseif($type === 'json') {
header("Content-type: application/json");
echo '"' . get_project_version() . '"';
echo '"' . Zotlabs\Project\System::get_project_version() . '"';
killme();
}
}
@@ -2270,9 +2270,9 @@ require_once('include/api_auth.php');
if ($page<0) $page=0;
$start = $page*$count;
$channel = $a->get_channel();
$channel = App::get_channel();
$profile_url = $a->get_baseurl() . '/channel/' . $channel['channel_address'];
$profile_url = z_root() . '/channel/' . $channel['channel_address'];
if ($box=="sentbox") {
$sql_extra = "`from_xchan`='".dbesc( $channel['channel_hash'] )."'";
}

View File

@@ -20,9 +20,9 @@ function api_login(&$a){
if (!is_null($token)){
$oauth->loginUser($token->uid);
$a->set_oauth_key($consumer->key);
App::set_oauth_key($consumer->key);
call_hooks('logged_in', $a->user);
call_hooks('logged_in', App::$user);
return;
}
killme();

View File

@@ -48,12 +48,12 @@ function parse_app_description($f) {
$ret = array();
$baseurl = z_root();
$channel = get_app()->get_channel();
$channel = App::get_channel();
$address = (($channel) ? $channel['channel_address'] : '');
//future expansion
$observer = get_app()->get_observer();
$observer = App::get_observer();
$lines = @file($f);
@@ -217,7 +217,7 @@ function app_render($papp,$mode = 'view') {
return '';
break;
case 'observer':
$observer = get_app()->get_observer();
$observer = App::get_observer();
if(! $observer)
return '';
break;
@@ -239,7 +239,7 @@ function app_render($papp,$mode = 'view') {
$hosturl = z_root() . '/';
}
elseif(remote_channel()) {
$observer = get_app()->get_observer();
$observer = App::get_observer();
if($observer && $observer['xchan_network'] === 'zot') {
// some folks might have xchan_url redirected offsite, use the connurl
$x = parse_url($observer['xchan_connurl']);
@@ -354,7 +354,7 @@ function app_store($arr) {
}
$darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . get_app()->get_hostname());
$darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . App::get_hostname());
$darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
$darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash());
$darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown'));

View File

@@ -13,6 +13,7 @@
require_once('include/permissions.php');
require_once('include/security.php');
require_once('include/group.php');
/**
* @brief Guess the mimetype from file ending.
@@ -845,7 +846,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
// Caution: This re-uses $sql_options set further above
$r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_options limit 1",
$r = q("select * from attach where uid = %d and hash = '%s' $sql_options limit 1",
intval($channel_id),
dbesc($hash)
);
@@ -863,6 +864,12 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
// This would've been called already with a success result in photos_upload() if it was a photo.
call_hooks('photo_upload_end',$ret);
}
$sync = attach_export_data($channel,$hash);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
return $ret;
}
@@ -1242,7 +1249,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
$channel_address = (($c) ? $c[0]['channel_address'] : 'notfound');
$photo_sql = (($is_photo) ? " and is_photo = 1 " : '');
$r = q("SELECT hash, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
$r = q("SELECT hash, os_storage, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
dbesc($resource),
intval($channel_id)
);
@@ -1313,7 +1320,9 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
intval($channel_id)
);
file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', $notify=0);
file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', $notify=1);
return;
}
/**
@@ -1468,13 +1477,13 @@ function pipe_streams($in, $out) {
* @param string $deny_cid
* @param string $deny_gid
* @param string $verb
* @param boolean $no_activity
* @param boolean $notify
*/
function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $verb, $notify) {
require_once('include/items.php');
$poster = get_app()->get_observer();
$poster = App::get_observer();
//if we got no object something went wrong
if(!$object)
@@ -1514,13 +1523,21 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$mid = item_message_id();
$arr = array();
$objtype = ACTIVITY_OBJ_FILE;
$arr = array();
$arr['aid'] = get_account_id();
$arr['uid'] = $channel_id;
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_unseen'] = 1;
$objtype = ACTIVITY_OBJ_FILE;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
$arr['item_hidden'] = 1;
$arr['obj_type'] = $objtype;
$arr['resource_id'] = $object['hash'];
$arr['resource_type'] = 'attach';
$private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0);
@@ -1548,36 +1565,27 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
}
//send update activity and create a new one
if($update && $verb == 'post' ) {
//send update activity and create a new one
//updates should be sent to everybody with recursive perms and all eventual former allowed members ($object['allow_cid'] etc.).
$u_arr_allow_cid = array_unique(array_merge($arr_allow_cid, expand_acl($object['allow_cid'])));
$u_arr_allow_gid = array_unique(array_merge($arr_allow_gid, expand_acl($object['allow_gid'])));
$u_arr_deny_cid = array_unique(array_merge($arr_deny_cid, expand_acl($object['deny_cid'])));
$u_arr_deny_gid = array_unique(array_merge($arr_deny_gid, expand_acl($object['deny_gid'])));
$private = (($u_arr_allow_cid[0] || $u_arr_allow_gid[0] || $u_arr_deny_cid[0] || $u_arr_deny_gid[0]) ? 1 : 0);
$u_mid = item_message_id();
$arr['aid'] = get_account_id();
$arr['uid'] = $channel_id;
$arr['mid'] = $u_mid;
$arr['parent_mid'] = $u_mid;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
//updates should be visible to everybody -> perms may have changed
$arr['allow_cid'] = '';
$arr['allow_gid'] = '';
$arr['deny_cid'] = '';
$arr['deny_gid'] = '';
$arr['item_hidden'] = 1;
$arr['item_private'] = 0;
$arr['allow_cid'] = perms2str($u_arr_allow_cid);
$arr['allow_gid'] = perms2str($u_arr_allow_gid);
$arr['deny_cid'] = perms2str($u_arr_deny_cid);
$arr['deny_gid'] = perms2str($u_arr_deny_gid);
$arr['item_private'] = $private;
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj_type'] = $objtype;
$arr['object'] = $u_jsonobject;
$arr['resource_id'] = $object['hash'];
$arr['resource_type'] = 'attach';
$arr['body'] = '';
$post = item_store($arr);
@@ -1593,32 +1601,25 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
//notice( t('File activity updated') . EOL);
}
//don't create new activity if notify was not enabled
if(! $notify) {
return;
}
$arr = array();
//don't create new activity if we have an update request but there is no item to update
//this can e.g. happen when deleting images
if(! $y && $verb == 'update') {
return;
}
$arr['aid'] = get_account_id();
$arr['uid'] = $channel_id;
$arr['mid'] = $mid;
$arr['parent_mid'] = $mid;
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_unseen'] = 1;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
$arr['allow_cid'] = perms2str($arr_allow_cid);
$arr['allow_gid'] = perms2str($arr_allow_gid);
$arr['deny_cid'] = perms2str($arr_deny_cid);
$arr['deny_gid'] = perms2str($arr_deny_gid);
$arr['item_hidden'] = 1;
$arr['item_private'] = $private;
$arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST);
$arr['obj_type'] = $objtype;
$arr['resource_id'] = $object['hash'];
$arr['resource_type'] = 'attach';
$arr['object'] = (($update) ? $u_jsonobject : $jsonobject);
$arr['body'] = '';
@@ -1701,11 +1702,11 @@ function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny
$ret = array();
$parent_arr = array();
$count_values = array();
$poster = get_app()->get_observer();
$poster = App::get_observer();
//turn allow_gid into allow_cid's
foreach($arr_allow_gid as $gid) {
$in_group = in_group($gid);
$in_group = group_get_members($gid);
$arr_allow_cid = array_unique(array_merge($arr_allow_cid, $in_group));
}
@@ -1727,7 +1728,7 @@ function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny
* */
if($parent_arr['allow_gid']) {
foreach($parent_arr['allow_gid'][$count] as $gid) {
$in_group = in_group($gid);
$in_group = group_get_members($gid);
$parent_arr['allow_cid'][$count] = array_unique(array_merge($parent_arr['allow_cid'][$count], $in_group));
}
}
@@ -1808,31 +1809,6 @@ function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny
return $ret;
}
/**
* @brief Returns members of a group.
*
* @param int $group_id id of the group to look up
*/
function in_group($group_id) {
$group_members = array();
/** @TODO make these two queries one with a join. */
$x = q("SELECT id FROM groups WHERE hash = '%s'",
dbesc($group_id)
);
$r = q("SELECT xchan FROM group_member WHERE gid = %d",
intval($x[0]['id'])
);
foreach($r as $ig) {
$group_members[] = $ig['xchan'];
}
return $group_members;
}
function filepath_macro($s) {
return str_replace(
@@ -1844,3 +1820,89 @@ function filepath_macro($s) {
}
function attach_export_data($channel, $resource_id, $deleted = false) {
$ret = array();
$paths = array();
$hash_ptr = $resource_id;
$ret['fetch_url'] = z_root() . '/getfile';
$ret['original_channel'] = $channel['channel_address'];
if($deleted) {
$ret['attach'] = array(array('hash' => $resource_id, 'deleted' => 1));
return $ret;
}
do {
$r = q("select * from attach where hash = '%s' and uid = %d limit 1",
dbesc($hash_ptr),
intval($channel['channel_id'])
);
if(! $r)
break;
if($hash_ptr === $resource_id) {
$attach_ptr = $r[0];
}
$hash_ptr = $r[0]['folder'];
$paths[] = $r[0];
} while($hash_ptr);
$paths = array_reverse($paths);
$ret['attach'] = $paths;
if($attach_ptr['is_photo']) {
$r = q("select * from photo where resource_id = '%s' and uid = %d order by scale asc",
dbesc($resource_id),
intval($channel['channel_id'])
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['data'] = base64_encode($r[$x]['data']);
}
$ret['photo'] = $r;
}
$r = q("select * from item where resource_id = '%s' and resource_type = 'photo' and uid = %d ",
dbesc($resource_id),
intval($channel['channel_id'])
);
if($r) {
$ret['item'] = array();
$items = q("select item.*, item.id as item_id from item where item.parent = %d ",
intval($r[0]['id'])
);
if($items) {
xchan_query($items);
$items = fetch_post_tags($items,true);
foreach($items as $rr)
$ret['item'][] = encode_item($rr,true);
}
}
}
return $ret;
}
/* strip off 'store/nickname/' from the provided path */
function get_attach_binname($s) {
$p = $s;
if(strpos($s,'store/') === 0) {
$p = substr($s,6);
$p = substr($p,strpos($p,'/')+1);
}
return $p;
}

View File

@@ -12,33 +12,6 @@
require_once('include/api_auth.php');
require_once('include/security.php');
/**
* @brief Resets the current session.
*
* @return void
*/
function nuke_session() {
new_cookie(0); // 0 means delete on browser exit
unset($_SESSION['authenticated']);
unset($_SESSION['account_id']);
unset($_SESSION['uid']);
unset($_SESSION['visitor_id']);
unset($_SESSION['administrator']);
unset($_SESSION['cid']);
unset($_SESSION['theme']);
unset($_SESSION['mobile_theme']);
unset($_SESSION['show_mobile']);
unset($_SESSION['page_flags']);
unset($_SESSION['delegate']);
unset($_SESSION['delegate_channel']);
unset($_SESSION['my_url']);
unset($_SESSION['my_address']);
unset($_SESSION['addr']);
unset($_SESSION['return_url']);
unset($_SESSION['remote_service_class']);
unset($_SESSION['remote_hub']);
}
/**
* @brief Verify login credentials.
@@ -124,11 +97,11 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
// process a logout request
if(((x($_POST, 'auth-params')) && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) {
if(((x($_POST, 'auth-params')) && ($_POST['auth-params'] === 'logout')) || (App::$module === 'logout')) {
// process logout request
$args = array('channel_id' => local_channel());
call_hooks('logging_out', $args);
nuke_session();
\Zotlabs\Web\Session::nuke();
info( t('Logged out.') . EOL);
goaway(z_root());
}
@@ -144,7 +117,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
intval(ACCOUNT_ROLE_ADMIN)
);
if($x) {
new_cookie(60 * 60 * 24); // one day
\Zotlabs\Web\Session::new_cookie(60 * 60 * 24); // one day
$_SESSION['last_login_date'] = datetime_convert();
unset($_SESSION['visitor_id']); // no longer a visitor
authenticate_success($x[0], true, true);
@@ -155,75 +128,41 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
dbesc($_SESSION['visitor_id'])
);
if($r) {
get_app()->set_observer($r[0]);
App::set_observer($r[0]);
}
else {
unset($_SESSION['visitor_id']);
unset($_SESSION['authenticated']);
}
$a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
}
// already logged in user returning
if(x($_SESSION, 'uid') || x($_SESSION, 'account_id')) {
// first check if we're enforcing that sessions can't change IP address
// @todo what to do with IPv6 addresses
if($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) {
logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
$partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
$partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
$paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia'));
if(! $paranoia)
$paranoia = intval(get_config('system', 'paranoia'));
switch($paranoia) {
case 0:
// no IP checking
break;
case 2:
// check 2 octets
$partial1 = substr($partial1, 0, strrpos($partial1, '.'));
$partial2 = substr($partial2, 0, strrpos($partial2, '.'));
if($partial1 == $partial2)
break;
case 1:
// check 3 octets
if($partial1 == $partial2)
break;
case 3:
default:
// check any difference at all
logger('Session address changed. Paranoid setting in effect, blocking session. '
. $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
nuke_session();
goaway(z_root());
break;
}
}
Zotlabs\Web\Session::return_check();
$r = q("select * from account where account_id = %d limit 1",
intval($_SESSION['account_id'])
);
if(($r) && (($r[0]['account_flags'] == ACCOUNT_OK) || ($r[0]['account_flags'] == ACCOUNT_UNVERIFIED))) {
get_app()->account = $r[0];
App::$account = $r[0];
$login_refresh = false;
if(! x($_SESSION,'last_login_date')) {
$_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
}
if(strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0 ) {
$_SESSION['last_login_date'] = datetime_convert();
Zotlabs\Web\Session::extend_cookie();
$login_refresh = true;
}
authenticate_success($r[0], false, false, false, $login_refresh);
}
else {
$_SESSION['account_id'] = 0;
nuke_session();
\Zotlabs\Web\Session::nuke();
goaway(z_root());
}
} // end logged in user returning
@@ -231,7 +170,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
else {
if(isset($_SESSION)) {
nuke_session();
\Zotlabs\Web\Session::nuke();
}
// handle a fresh login request
@@ -264,16 +203,16 @@ else {
$record = $addon_auth['user_record'];
}
else {
$record = get_app()->account = account_verify_password($_POST['username'], $_POST['password']);
$record = App::$account = account_verify_password($_POST['username'], $_POST['password']);
if(get_app()->account) {
$_SESSION['account_id'] = get_app()->account['account_id'];
if(App::$account) {
$_SESSION['account_id'] = App::$account['account_id'];
}
else {
notice( t('Failed authentication') . EOL);
}
logger('authenticate: ' . print_r(get_app()->account, true), LOGGER_DEBUG);
logger('authenticate: ' . print_r(App::$account, true), LOGGER_ALL);
}
if((! $record) || (! count($record))) {
@@ -301,11 +240,13 @@ else {
// (i.e. expire when the browser is closed), even when there's a time expiration
// on the cookie
if($_POST['remember']) {
new_cookie(31449600); // one year
if($_POST['remember_me']) {
$_SESSION['remember_me'] = 1;
\Zotlabs\Web\Session::new_cookie(31449600); // one year
}
else {
new_cookie(0); // 0 means delete on browser exit
$_SESSION['remember_me'] = 0;
\Zotlabs\Web\Session::new_cookie(0); // 0 means delete on browser exit
}
// if we haven't failed up this point, log them in.

View File

@@ -473,7 +473,7 @@ function format_event_diaspora($ev) {
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)))
. '](' . $a->get_baseurl() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
if(! $ev['nofinish'])
$o .= t('Finishes:') . ' ' . '['
@@ -481,7 +481,7 @@ function format_event_diaspora($ev) {
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
. '](' . $a->get_baseurl() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
if(strlen($ev['location']))
$o .= t('Location:') . bb2diaspora($ev['location'])

View File

@@ -37,7 +37,7 @@ function tryzrlvideo($match) {
if($zrl)
$link = zid($link);
return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
}
// [noparse][i]italic[/i][/noparse] turns into
@@ -243,9 +243,7 @@ function bb_ShareAttributes($match) {
if ($matches[1] != "")
$message_id = $matches[1];
/** @FIXME - this should really be a wall-item-ago so it will get updated on the client */
$reldate = (($posted) ? relative_date($posted) : '');
$reldate = '<span class="autotime" title="' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'c') . '" >' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'r') . '</span>';
$headline = '<div class="shared_container"> <div class="shared_header">';
@@ -280,9 +278,9 @@ function bb_location($match) {
function bb_iframe($match) {
$a = get_app();
$sandbox = ((strpos($match[1], $a->get_hostname())) ? ' sandbox="allow-scripts" ' : '');
$sandbox = ((strpos($match[1], App::get_hostname())) ? ' sandbox="allow-scripts" ' : '');
return '<iframe ' . $sandbox . ' src="' . $match[1] . '" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="' . $match[1] . '">' . $match[1] . '</a></iframe>';
return '<iframe ' . $sandbox . ' src="' . $match[1] . '" width="' . App::$videowidth . '" height="' . App::$videoheight . '"><a href="' . $match[1] . '">' . $match[1] . '</a></iframe>';
}
function bb_ShareAttributesSimple($match) {
@@ -315,9 +313,9 @@ function bb_ShareAttributesSimple($match) {
function rpost_callback($match) {
if ($match[2]) {
return str_replace($match[0], get_rpost_path(get_app()->get_observer()) . '&title=' . urlencode($match[2]) . '&body=' . urlencode($match[3]), $match[0]);
return str_replace($match[0], get_rpost_path(App::get_observer()) . '&title=' . urlencode($match[2]) . '&body=' . urlencode($match[3]), $match[0]);
} else {
return str_replace($match[0], get_rpost_path(get_app()->get_observer()) . '&body=' . urlencode($match[3]), $match[0]);
return str_replace($match[0], get_rpost_path(App::get_observer()) . '&body=' . urlencode($match[3]), $match[0]);
}
}
@@ -401,7 +399,7 @@ function bb_observer($Text) {
$a = get_app();
$observer = $a->get_observer();
$observer = App::get_observer();
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
if ($observer) {
@@ -415,7 +413,7 @@ function bb_observer($Text) {
}
}
$channel = $a->get_channel();
$channel = App::get_channel();
if (strpos($Text,'[/channel]') !== false) {
if ($channel) {
@@ -477,7 +475,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
if($cache)
$observer = false;
else
$observer = $a->get_observer();
$observer = App::get_observer();
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
if ($observer) {
@@ -494,7 +492,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
if($cache)
$channel = false;
else
$channel = $a->get_channel();
$channel = App::get_channel();
if (strpos($Text,'[/channel]') !== false) {
if ($channel) {
@@ -593,6 +591,11 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_blank" >$1</a>', $Text);
$Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_blank" >$2</a>', $Text);
}
// Remove bookmarks from UNO
if (UNO)
$Text = str_replace('<span class="bookmark-identifier">#^</span>', '', $Text);
// Perform MAIL Search
if (strpos($Text,'[/mail]') !== false) {
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" target="_blank" >$1</a>', $Text);
@@ -684,7 +687,11 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
}
// Check for centered text
if (strpos($Text,'[/center]') !== false) {
$Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
$Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
}
// Check for footer
if (strpos($Text,'[/footer]') !== false) {
$Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $Text);
}
// Check for list text
$Text = str_replace("[*]", "<li>", $Text);
@@ -841,7 +848,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// crypt
if (strpos($Text,'[/crypt]') !== false) {
$x = random_string();
$Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text);
$Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img src="' .z_root() . '/images/lock_icon.gif" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text);
$Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text);
}
@@ -921,7 +928,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
// if ($tryoembed)
// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>', $Text);
// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . App::$videowidth . '" height="' . App::$videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>', $Text);
// else
// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", "http://www.youtube.com/watch?v=$1", $Text);
// }
@@ -935,7 +942,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// $Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
// if ($tryoembed)
// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . App::$videowidth . '" height="' . App::$videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
// else
// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", "http://vimeo.com/$1", $Text);
// }

View File

@@ -202,7 +202,7 @@ function chatroom_list($uid) {
require_once('include/security.php');
$sql_extra = permissions_sql($uid);
$r = q("select cr_name, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
$r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
intval($uid)
);

View File

@@ -9,25 +9,32 @@ function cli_startup() {
global $a, $db, $default_timezone;
if(is_null($a)) {
$a = new App;
$a = new miniApp;
}
App::init();
if(is_null($db)) {
@include(".htconfig.php");
$a->timezone = ((x($default_timezone)) ? $default_timezone : 'UTC');
date_default_timezone_set($a->timezone);
$a->convert();
if(! defined('UNO'))
define('UNO', 0);
App::$timezone = ((x($default_timezone)) ? $default_timezone : 'UTC');
date_default_timezone_set(App::$timezone);
require_once('include/dba/dba_driver.php');
$db = dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type);
unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type);
};
require_once('include/session.php');
\Zotlabs\Web\Session::init();
load_config('system');
$a->set_baseurl(get_config('system','baseurl'));
App::set_baseurl(get_config('system','baseurl'));
load_hooks();

View File

@@ -56,34 +56,34 @@ function comanche_parser(&$a, $s, $pass = 0) {
if($pass == 0) {
$cnt = preg_match("/\[layout\](.*?)\[\/layout\]/ism", $s, $matches);
if($cnt)
$a->page['template'] = trim($matches[1]);
App::$page['template'] = trim($matches[1]);
$cnt = preg_match("/\[template=(.*?)\](.*?)\[\/template\]/ism", $s, $matches);
if($cnt) {
$a->page['template'] = trim($matches[2]);
$a->page['template_style'] = trim($matches[2]) . '_' . $matches[1];
App::$page['template'] = trim($matches[2]);
App::$page['template_style'] = trim($matches[2]) . '_' . $matches[1];
}
$cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $s, $matches);
if($cnt) {
$a->page['template'] = trim($matches[1]);
App::$page['template'] = trim($matches[1]);
}
$cnt = preg_match("/\[theme=(.*?)\](.*?)\[\/theme\]/ism", $s, $matches);
if($cnt) {
$a->layout['schema'] = trim($matches[1]);
$a->layout['theme'] = trim($matches[2]);
App::$layout['schema'] = trim($matches[1]);
App::$layout['theme'] = trim($matches[2]);
}
$cnt = preg_match("/\[theme\](.*?)\[\/theme\]/ism", $s, $matches);
if($cnt)
$a->layout['theme'] = trim($matches[1]);
App::$layout['theme'] = trim($matches[1]);
$cnt = preg_match_all("/\[webpage\](.*?)\[\/webpage\]/ism", $s, $matches, PREG_SET_ORDER);
if($cnt) {
// only the last webpage definition is used if there is more than one
foreach($matches as $mtch) {
$a->layout['webpage'] = comanche_webpage($a,$mtch[1]);
App::$layout['webpage'] = comanche_webpage($a,$mtch[1]);
}
}
@@ -92,7 +92,7 @@ function comanche_parser(&$a, $s, $pass = 0) {
$cnt = preg_match_all("/\[region=(.*?)\](.*?)\[\/region\]/ism", $s, $matches, PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
$a->layout['region_' . $mtch[1]] = comanche_region($a,$mtch[2]);
App::$layout['region_' . $mtch[1]] = comanche_region($a,$mtch[2]);
}
}
@@ -122,8 +122,8 @@ function comanche_menu($s, $class = '') {
function comanche_replace_region($match) {
$a = get_app();
if (array_key_exists($match[1], $a->page)) {
return $a->page[$match[1]];
if (array_key_exists($match[1], App::$page)) {
return App::$page[$match[1]];
}
}
@@ -136,7 +136,7 @@ function comanche_replace_region($match) {
* @return channel_id
*/
function comanche_get_channel_id() {
$channel_id = ((is_array(get_app()->profile)) ? get_app()->profile['profile_uid'] : 0);
$channel_id = ((is_array(App::$profile)) ? App::$profile['profile_uid'] : 0);
if ((! $channel_id) && (local_channel()))
$channel_id = local_channel();
@@ -190,7 +190,7 @@ function comanche_block($s, $class = '') {
}
if(trim($r[0]['body']) === '$content') {
$o .= get_app()->page['content'];
$o .= App::$page['content'];
}
else {
$o .= prepare_text($r[0]['body'], $r[0]['mimetype']);
@@ -378,6 +378,6 @@ function comanche_region(&$a, $s) {
function register_page_template($arr) {
get_app()->page_layouts[$arr['template']] = array($arr['variant']);
App::$page_layouts[$arr['template']] = array($arr['variant']);
return;
}

View File

@@ -22,7 +22,7 @@
* an identifier. This is for example for people who do not have a local account.
* The storage is of size MEDIUMTEXT.
* @code{.php}
* $observer = $a->get_observer_hash();
* $observer = App::get_observer_hash();
* if ($observer) {
* $var = get_xconfig($observer, 'category', 'key');
* }@endcode
@@ -38,7 +38,7 @@
* @brief Loads the hub's configuration from database to a cached storage.
*
* Retrieve a category ($family) of config variables from database to a cached
* storage in the global $a->config[$family].
* storage in the global App::$config[$family].
*
* @param string $family
* The category of the configuration value
@@ -46,19 +46,19 @@
function load_config($family) {
global $a;
if(! array_key_exists($family, $a->config))
$a->config[$family] = array();
if(! array_key_exists($family, App::$config))
App::$config[$family] = array();
if(! array_key_exists('config_loaded', $a->config[$family])) {
if(! array_key_exists('config_loaded', App::$config[$family])) {
$r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
if($r !== false) {
if($r) {
foreach($r as $rr) {
$k = $rr['k'];
$a->config[$family][$k] = $rr['v'];
App::$config[$family][$k] = $rr['v'];
}
}
$a->config[$family]['config_loaded'] = true;
App::$config[$family]['config_loaded'] = true;
}
}
}
@@ -68,7 +68,7 @@ function load_config($family) {
* and a key.
*
* Get a particular config variable from the given category ($family) and the
* $key from a cached storage in $a->config[$family]. If a key is found in the
* $key from a cached storage in App::$config[$family]. If a key is found in the
* DB but does not exist in local config cache, pull it into the cache so we
* do not have to hit the DB again for this item.
*
@@ -83,16 +83,16 @@ function load_config($family) {
function get_config($family, $key) {
global $a;
if((! array_key_exists($family, $a->config)) || (! array_key_exists('config_loaded', $a->config[$family])))
if((! array_key_exists($family, App::$config)) || (! array_key_exists('config_loaded', App::$config[$family])))
load_config($family);
if(array_key_exists('config_loaded', $a->config[$family])) {
if(! array_key_exists($key, $a->config[$family])) {
if(array_key_exists('config_loaded', App::$config[$family])) {
if(! array_key_exists($key, App::$config[$family])) {
return false;
}
return ((! is_array($a->config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$family][$key]))
? unserialize($a->config[$family][$key])
: $a->config[$family][$key]
return ((! is_array(App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$family][$key]))
? unserialize(App::$config[$family][$key])
: App::$config[$family][$key]
);
}
return false;
@@ -148,7 +148,7 @@ function set_config($family, $key, $value) {
dbesc($dbvalue)
);
if($ret) {
$a->config[$family][$key] = $value;
App::$config[$family][$key] = $value;
$ret = $value;
}
return $ret;
@@ -161,7 +161,7 @@ function set_config($family, $key, $value) {
);
if($ret) {
$a->config[$family][$key] = $value;
App::$config[$family][$key] = $value;
$ret = $value;
}
return $ret;
@@ -170,7 +170,7 @@ function set_config($family, $key, $value) {
/**
* @brief Deletes the given key from the hub's configuration database.
*
* Removes the configured value from the stored cache in $a->config[$family]
* Removes the configured value from the stored cache in App::$config[$family]
* and removes it from the database.
*
* @param string $family
@@ -183,8 +183,8 @@ function del_config($family, $key) {
global $a;
$ret = false;
if(array_key_exists($family, $a->config) && array_key_exists($key, $a->config[$family]))
unset($a->config[$family][$key]);
if(array_key_exists($family, App::$config) && array_key_exists($key, App::$config[$family]))
unset(App::$config[$family][$key]);
$ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s'",
dbesc($family),
dbesc($key)
@@ -197,7 +197,7 @@ function del_config($family, $key) {
* @brief Loads all configuration values of a channel into a cached storage.
*
* All configuration values of the given channel are stored in global cache
* which is available under the global variable $a->config[$uid].
* which is available under the global variable App::$config[$uid].
*
* @param string $uid
* The channel_id
@@ -209,8 +209,8 @@ function load_pconfig($uid) {
if($uid === false)
return false;
if(! array_key_exists($uid, $a->config))
$a->config[$uid] = array();
if(! array_key_exists($uid, App::$config))
App::$config[$uid] = array();
$r = q("SELECT * FROM pconfig WHERE uid = %d",
intval($uid)
@@ -220,11 +220,11 @@ function load_pconfig($uid) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, $a->config[$uid])) {
$a->config[$uid][$c] = array();
$a->config[$uid][$c]['config_loaded'] = true;
if(! array_key_exists($c, App::$config[$uid])) {
App::$config[$uid][$c] = array();
App::$config[$uid][$c]['config_loaded'] = true;
}
$a->config[$uid][$c][$k] = $rr['v'];
App::$config[$uid][$c][$k] = $rr['v'];
}
}
}
@@ -234,7 +234,7 @@ function load_pconfig($uid) {
* ($family) and a key.
*
* Get a particular channel's config value from the given category ($family)
* and the $key from a cached storage in $a->config[$uid].
* and the $key from a cached storage in App::$config[$uid].
*
* Returns false if not set.
*
@@ -254,15 +254,15 @@ function get_pconfig($uid, $family, $key, $instore = false) {
if($uid === false)
return false;
if(! array_key_exists($uid, $a->config))
if(! array_key_exists($uid, App::$config))
load_pconfig($uid);
if((! array_key_exists($family, $a->config[$uid])) || (! array_key_exists($key, $a->config[$uid][$family])))
if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family])))
return false;
return ((! is_array($a->config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$uid][$family][$key]))
? unserialize($a->config[$uid][$family][$key])
: $a->config[$uid][$family][$key]
return ((! is_array(App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$uid][$family][$key]))
? unserialize(App::$config[$uid][$family][$key])
: App::$config[$uid][$family][$key]
);
}
@@ -287,27 +287,38 @@ function get_pconfig($uid, $family, $key, $instore = false) {
function set_pconfig($uid, $family, $key, $value) {
global $a;
// this catches subtle errors where this function has been called
// with local_channel() when not logged in (which returns false)
// and throws an error in array_key_exists below.
// we provide a function backtrace in the logs so that we can find
// and fix the calling function.
if($uid === false) {
btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR);
return;
}
// manage array value
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_pconfig($uid, $family, $key) === false) {
if(! array_key_exists($uid, $a->config))
$a->config[$uid] = array();
if(! array_key_exists($family, $a->config[$uid]))
$a->config[$uid][$family] = array();
if(! array_key_exists($uid, App::$config))
App::$config[$uid] = array();
if(! array_key_exists($family, App::$config[$uid]))
App::$config[$uid][$family] = array();
// keep a separate copy for all variables which were
// set in the life of this page. We need this to
// synchronise channel clones.
if(! array_key_exists('transient', $a->config[$uid]))
$a->config[$uid]['transient'] = array();
if(! array_key_exists($family, $a->config[$uid]['transient']))
$a->config[$uid]['transient'][$family] = array();
if(! array_key_exists('transient', App::$config[$uid]))
App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, App::$config[$uid]['transient']))
App::$config[$uid]['transient'][$family] = array();
$a->config[$uid][$family][$key] = $value;
$a->config[$uid]['transient'][$family][$key] = $value;
App::$config[$uid][$family][$key] = $value;
App::$config[$uid]['transient'][$family][$key] = $value;
$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
intval($uid),
@@ -332,13 +343,13 @@ function set_pconfig($uid, $family, $key, $value) {
// set in the life of this page. We need this to
// synchronise channel clones.
if(! array_key_exists('transient', $a->config[$uid]))
$a->config[$uid]['transient'] = array();
if(! array_key_exists($family, $a->config[$uid]['transient']))
$a->config[$uid]['transient'][$family] = array();
if(! array_key_exists('transient', App::$config[$uid]))
App::$config[$uid]['transient'] = array();
if(! array_key_exists($family, App::$config[$uid]['transient']))
App::$config[$uid]['transient'][$family] = array();
$a->config[$uid][$family][$key] = $value;
$a->config[$uid]['transient'][$family][$key] = $value;
App::$config[$uid][$family][$key] = $value;
App::$config[$uid]['transient'][$family][$key] = $value;
if($ret)
return $value;
@@ -349,7 +360,7 @@ function set_pconfig($uid, $family, $key, $value) {
/**
* @brief Deletes the given key from the channel's configuration.
*
* Removes the configured value from the stored cache in $a->config[$uid]
* Removes the configured value from the stored cache in App::$config[$uid]
* and removes it from the database.
*
* @param string $uid
@@ -364,8 +375,8 @@ function del_pconfig($uid, $family, $key) {
global $a;
$ret = false;
if (x($a->config[$uid][$family], $key))
unset($a->config[$uid][$family][$key]);
if (x(App::$config[$uid][$family], $key))
unset(App::$config[$uid][$family][$key]);
$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'",
intval($uid),
dbesc($family),
@@ -380,7 +391,7 @@ function del_pconfig($uid, $family, $key) {
* @brief Loads a full xchan's configuration into a cached storage.
*
* All configuration values of the given observer hash are stored in global
* cache which is available under the global variable $a->config[$xchan].
* cache which is available under the global variable App::$config[$xchan].
*
* @param string $xchan
* The observer's hash
@@ -392,8 +403,8 @@ function load_xconfig($xchan) {
if(! $xchan)
return false;
if(! array_key_exists($xchan, $a->config))
$a->config[$xchan] = array();
if(! array_key_exists($xchan, App::$config))
App::$config[$xchan] = array();
$r = q("SELECT * FROM xconfig WHERE xchan = '%s'",
dbesc($xchan)
@@ -403,11 +414,11 @@ function load_xconfig($xchan) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
if(! array_key_exists($c, $a->config[$xchan])) {
$a->config[$xchan][$c] = array();
$a->config[$xchan][$c]['config_loaded'] = true;
if(! array_key_exists($c, App::$config[$xchan])) {
App::$config[$xchan][$c] = array();
App::$config[$xchan][$c]['config_loaded'] = true;
}
$a->config[$xchan][$c][$k] = $rr['v'];
App::$config[$xchan][$c][$k] = $rr['v'];
}
}
}
@@ -417,7 +428,7 @@ function load_xconfig($xchan) {
* name ($family) and a key.
*
* Get a particular observer's config value from the given category ($family)
* and the $key from a cached storage in $a->config[$xchan].
* and the $key from a cached storage in App::$config[$xchan].
*
* Returns false if not set.
*
@@ -435,15 +446,15 @@ function get_xconfig($xchan, $family, $key) {
if(! $xchan)
return false;
if(! array_key_exists($xchan, $a->config))
if(! array_key_exists($xchan, App::$config))
load_xconfig($xchan);
if((! array_key_exists($family, $a->config[$xchan])) || (! array_key_exists($key, $a->config[$xchan][$family])))
if((! array_key_exists($family, App::$config[$xchan])) || (! array_key_exists($key, App::$config[$xchan][$family])))
return false;
return ((! is_array($a->config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$xchan][$family][$key]))
? unserialize($a->config[$xchan][$family][$key])
: $a->config[$xchan][$family][$key]
return ((! is_array(App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$xchan][$family][$key]))
? unserialize(App::$config[$xchan][$family][$key])
: App::$config[$xchan][$family][$key]
);
}
@@ -473,12 +484,12 @@ function set_xconfig($xchan, $family, $key, $value) {
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_xconfig($xchan, $family, $key) === false) {
if(! array_key_exists($xchan, $a->config))
$a->config[$xchan] = array();
if(! array_key_exists($family, $a->config[$xchan]))
$a->config[$xchan][$family] = array();
if(! array_key_exists($xchan, App::$config))
App::$config[$xchan] = array();
if(! array_key_exists($family, App::$config[$xchan]))
App::$config[$xchan][$family] = array();
$a->config[$xchan][$family][$key] = $value;
App::$config[$xchan][$family][$key] = $value;
$ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
dbesc($xchan),
dbesc($family),
@@ -497,7 +508,7 @@ function set_xconfig($xchan, $family, $key, $value) {
dbesc($key)
);
$a->config[$xchan][$family][$key] = $value;
App::$config[$xchan][$family][$key] = $value;
if($ret)
return $value;
@@ -507,7 +518,7 @@ function set_xconfig($xchan, $family, $key, $value) {
/**
* @brief Deletes the given key from the observer's config.
*
* Removes the configured value from the stored cache in $a->config[$xchan]
* Removes the configured value from the stored cache in App::$config[$xchan]
* and removes it from the database.
*
* @param string $xchan
@@ -522,8 +533,8 @@ function del_xconfig($xchan, $family, $key) {
global $a;
$ret = false;
if(x($a->config[$xchan][$family], $key))
unset($a->config[$xchan][$family][$key]);
if(x(App::$config[$xchan][$family], $key))
unset(App::$config[$xchan][$family][$key]);
$ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'",
dbesc($xchan),
dbesc($family),
@@ -549,4 +560,68 @@ function set_aconfig($account_id, $family, $key, $value) {
function del_aconfig($account_id, $family, $key) {
return del_xconfig('a_' . $account_id, $family, $key);
}
}
function load_abconfig($chash,$xhash) {
$r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
dbesc($chash),
dbesc($xhash)
);
return $r;
}
function get_abconfig($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),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
if($r) {
return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']);
}
return false;
}
function set_abconfig($chash,$xhash,$family,$key,$value) {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_abconfig($chash,$xhash,$family,$key) === false) {
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
}
else {
$r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($dbvalue),
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
}
if($r)
return $value;
return false;
}
function del_abconfig($chash,$xhash,$family,$key) {
$r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
dbesc($chash),
dbesc($xhash),
dbesc($family),
dbesc($key)
);
return $r;
}

View File

@@ -73,16 +73,18 @@ function contact_poll_interval($current, $disabled = false) {
function network_to_name($s) {
$nets = array(
NETWORK_DFRN => t('Friendica'),
NETWORK_OSTATUS => t('OStatus'),
NETWORK_FEED => t('RSS/Atom'),
NETWORK_MAIL => t('Email'),
NETWORK_DIASPORA => t('Diaspora'),
NETWORK_FACEBOOK => t('Facebook'),
NETWORK_ZOT => t('Zot'),
NETWORK_LINKEDIN => t('LinkedIn'),
NETWORK_XMPP => t('XMPP/IM'),
NETWORK_MYSPACE => t('MySpace'),
NETWORK_DFRN => t('Friendica'),
NETWORK_FRND => t('Friendica'),
NETWORK_OSTATUS => t('OStatus'),
NETWORK_GNUSOCIAL => t('GNU-Social'),
NETWORK_FEED => t('RSS/Atom'),
NETWORK_MAIL => t('Email'),
NETWORK_DIASPORA => t('Diaspora'),
NETWORK_FACEBOOK => t('Facebook'),
NETWORK_ZOT => t('Zot'),
NETWORK_LINKEDIN => t('LinkedIn'),
NETWORK_XMPP => t('XMPP/IM'),
NETWORK_MYSPACE => t('MySpace'),
);
call_hooks('network_to_name', $nets);

View File

@@ -10,7 +10,7 @@ function findpeople_widget() {
if(get_config('system','invitation_only')) {
$x = get_pconfig(local_channel(),'system','invites_remaining');
if($x || is_site_admin()) {
$a->page['aside'] .= '<div class="side-link" id="side-invite-remain">'
App::$page['aside'] .= '<div class="side-link" id="side-invite-remain">'
. sprintf( tt('%d invitation available','%d invitations available',$x), $x)
. '</div>' . $inv;
}
@@ -68,7 +68,7 @@ function categories_widget($baseurl,$selected = '') {
$a = get_app();
if(! feature_enabled($a->profile['profile_uid'],'categories'))
if(! feature_enabled(App::$profile['profile_uid'],'categories'))
return '';
$item_normal = item_normal();
@@ -83,9 +83,9 @@ function categories_widget($baseurl,$selected = '') {
and item.item_wall = 1
$item_normal
order by term.term asc",
intval($a->profile['profile_uid']),
intval(App::$profile['profile_uid']),
intval(TERM_CATEGORY),
dbesc($a->profile['channel_hash'])
dbesc(App::$profile['channel_hash'])
);
if($r && count($r)) {
foreach($r as $rr)
@@ -126,7 +126,7 @@ function common_friends_visitor_widget($profile_uid) {
return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
'$desc' => sprintf( tt("%d connection in common", "%d connections in common", $t), $t),
'$base' => $a->get_baseurl(),
'$base' => z_root(),
'$uid' => $profile_uid,
'$cid' => $observer,
'$linkmore' => (($t > 5) ? 'true' : ''),

View File

@@ -54,7 +54,7 @@ function item_redir_and_replace_images($body, $images, $cid) {
$origbody = $body;
$newbody = '';
$observer = get_app()->get_observer();
$observer = App::get_observer();
$obhash = (($observer) ? $observer['xchan_hash'] : '');
$obaddr = (($observer) ? $observer['xchan_addr'] : '');
@@ -489,7 +489,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$live_update_div = '<div id="live-network"></div>' . "\r\n"
. "<script> var profile_uid = " . $_SESSION['uid']
. "; var netargs = '" . substr($a->cmd,8)
. "; var netargs = '" . substr(App::$cmd,8)
. '?f='
. ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '')
. ((x($_GET,'search')) ? '&search=' . $_GET['search'] : '')
@@ -504,12 +504,12 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
. ((x($_GET,'cmax')) ? '&cmax=' . $_GET['cmax'] : '')
. ((x($_GET,'file')) ? '&file=' . $_GET['file'] : '')
. ((x($_GET,'uri')) ? '&uri=' . $_GET['uri'] : '')
. "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
. "'; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
}
}
elseif ($mode === 'channel') {
$profile_owner = $a->profile['profile_uid'];
$profile_owner = App::$profile['profile_uid'];
$page_writeable = ($profile_owner == local_channel());
if (!$update) {
@@ -519,8 +519,8 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
// because browser prefetching might change it on us. We have to deliver it with the page.
$live_update_div = '<div id="live-channel"></div>' . "\r\n"
. "<script> var profile_uid = " . $a->profile['profile_uid']
. "; var netargs = '?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
. "<script> var profile_uid = " . App::$profile['profile_uid']
. "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
}
}
}
@@ -532,7 +532,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
}
elseif ($mode === 'page') {
$profile_owner = $a->profile['uid'];
$profile_owner = App::$profile['uid'];
$page_writeable = ($profile_owner == local_channel());
$live_update_div = '<div id="live-page"></div>' . "\r\n";
}
@@ -542,11 +542,11 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
}
elseif ($mode === 'photos') {
$profile_onwer = $a->profile['profile_uid'];
$profile_onwer = App::$profile['profile_uid'];
$page_writeable = ($profile_owner == local_channel());
$live_update_div = '<div id="live-photos"></div>' . "\r\n";
// for photos we've already formatted the top-level item (the photo)
$content_html = $a->data['photo_html'];
$content_html = App::$data['photo_html'];
}
$page_dropping = ((local_channel() && local_channel() == $profile_owner) ? true : false);
@@ -555,13 +555,13 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$page_dropping = false;
$channel = $a->get_channel();
$observer = $a->get_observer();
$channel = App::get_channel();
$observer = App::get_observer();
if($update)
$return_url = $_SESSION['return_url'];
else
$return_url = $_SESSION['return_url'] = $a->query_string;
$return_url = $_SESSION['return_url'] = App::$query_string;
load_contact_links(local_channel());
@@ -623,7 +623,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$nickname = $item['nickname'];
}
else
$nickname = $a->user['nickname'];
$nickname = App::$user['nickname'];
$profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']);
if($item['author-link'] && (! $item['author-name']))
@@ -844,12 +844,12 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$o .= replace_macros($page_template, array(
'$baseurl' => $a->get_baseurl($ssl_state),
'$baseurl' => z_root(),
'$photo_item' => $content_html,
'$live_update' => $live_update_div,
'$remove' => t('remove'),
'$mode' => $mode,
'$user' => $a->user,
'$user' => App::$user,
'$threads' => $threads,
'$wait' => t('Loading...'),
'$dropping' => ($page_dropping?t('Delete Selected Items'):False),
@@ -869,13 +869,13 @@ function best_link_url($item) {
$clean_url = normalise_link($item['author-link']);
if((local_channel()) && (local_channel() == $item['uid'])) {
if(isset($a->contacts) && x($a->contacts,$clean_url)) {
if($a->contacts[$clean_url]['network'] === NETWORK_DFRN) {
$best_url = $a->get_baseurl($ssl_state) . '/redir/' . $a->contacts[$clean_url]['id'];
if(isset(App::$contacts) && x(App::$contacts,$clean_url)) {
if(App::$contacts[$clean_url]['network'] === NETWORK_DFRN) {
$best_url = z_root() . '/redir/' . App::$contacts[$clean_url]['id'];
$sparkle = true;
}
else
$best_url = $a->contacts[$clean_url]['url'];
$best_url = App::$contacts[$clean_url]['url'];
}
}
if(! $best_url) {
@@ -907,9 +907,9 @@ function item_photo_menu($item){
if($local_channel) {
$ssl_state = true;
if(! count($a->contacts))
if(! count(App::$contacts))
load_contact_links($local_channel);
$channel = $a->get_channel();
$channel = App::get_channel();
$channel_hash = (($channel) ? $channel['channel_hash'] : '');
}
@@ -925,19 +925,19 @@ function item_photo_menu($item){
$profile_link = chanlink_hash($item['author_xchan']);
if($item['uid'] > 0)
$pm_url = $a->get_baseurl($ssl_state) . '/mail/new/?f=&hash=' . $item['author_xchan'];
$pm_url = z_root() . '/mail/new/?f=&hash=' . $item['author_xchan'];
if($a->contacts && array_key_exists($item['author_xchan'],$a->contacts))
$contact = $a->contacts[$item['author_xchan']];
if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts))
$contact = App::$contacts[$item['author_xchan']];
else
if($local_channel && $item['author']['xchan_addr'])
$follow_url = z_root() . '/follow/?f=&url=' . $item['author']['xchan_addr'];
if($contact) {
$poke_link = $a->get_baseurl($ssl_state) . '/poke/?f=&c=' . $contact['abook_id'];
$poke_link = z_root() . '/poke/?f=&c=' . $contact['abook_id'];
if (! intval($contact['abook_self']))
$contact_url = $a->get_baseurl($ssl_state) . '/connedit/' . $contact['abook_id'];
$posts_link = $a->get_baseurl($ssl_state) . '/network/?cid=' . $contact['abook_id'];
$contact_url = z_root() . '/connedit/' . $contact['abook_id'];
$posts_link = z_root() . '/network/?cid=' . $contact['abook_id'];
$clean_url = normalise_link($item['author-link']);
}
@@ -1110,6 +1110,11 @@ function status_editor($a, $x, $popup = false) {
$o = '';
require_once('include/Contact.php');
$c = channelx_by_n($x['profile_uid']);
if($c && $c['channel_moved'])
return $o;
$geotag = (($x['allow_location']) ? replace_macros(get_markup_template('jot_geotag.tpl'), array()) : '');
$plaintext = true;
@@ -1154,9 +1159,9 @@ function status_editor($a, $x, $popup = false) {
$tpl = get_markup_template('jot-header.tpl');
$a->page['htmlhead'] .= replace_macros($tpl, array(
App::$page['htmlhead'] .= replace_macros($tpl, array(
'$newpost' => 'true',
'$baseurl' => $a->get_baseurl(true),
'$baseurl' => z_root(),
'$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'),
'$pretext' => ((x($x,'pretext')) ? $x['pretext'] : ''),
'$geotag' => $geotag,
@@ -1168,7 +1173,9 @@ function status_editor($a, $x, $popup = false) {
'$term' => t('Tag term:'),
'$fileas' => t('Save to Folder:'),
'$whereareu' => t('Where are you right now?'),
'$expireswhen' => t('Expires YYYY-MM-DD HH:MM')
'$expireswhen' => t('Expires YYYY-MM-DD HH:MM'),
'$editor_autocomplete'=> ((x($x,'editor_autocomplete')) ? $x['editor_autocomplete'] : ''),
'$bbco_autocomplete'=> ((x($x,'bbco_autocomplete')) ? $x['bbco_autocomplete'] : ''),
));
$tpl = get_markup_template('jot.tpl');
@@ -1197,8 +1204,8 @@ function status_editor($a, $x, $popup = false) {
call_hooks('jot_networks', $jotnets);
$o .= replace_macros($tpl, array(
'$return_path' => ((x($x, 'return_path')) ? $x['return_path'] : $a->query_string),
'$action' => $a->get_baseurl(true) . '/item',
'$return_path' => ((x($x, 'return_path')) ? $x['return_path'] : App::$query_string),
'$action' => z_root() . '/item',
'$share' => (x($x,'button') ? $x['button'] : t('Share')),
'$webpage' => $webpage,
'$placeholdpagetitle' => ((x($x,'ptlabel')) ? $x['ptlabel'] : t('Page link name')),
@@ -1241,7 +1248,7 @@ function status_editor($a, $x, $popup = false) {
'$content' => ((x($x,'body')) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8') : ''),
'$attachment' => ((x($x, 'attachment')) ? $x['attachment'] : ''),
'$post_id' => '',
'$baseurl' => $a->get_baseurl(true),
'$baseurl' => z_root(),
'$defloc' => $x['default_location'],
'$visitor' => $x['visitor'],
'$public' => t('Public post'),
@@ -1269,6 +1276,7 @@ function status_editor($a, $x, $popup = false) {
'$expiryModalOK' => t('OK'),
'$expiryModalCANCEL' => t('Cancel'),
'$expanded' => ((x($x, 'expanded')) ? $x['expanded'] : false),
'$bbcode' => ((x($x, 'bbcode')) ? $x['bbcode'] : false)
));
if ($popup === true) {
@@ -1419,12 +1427,12 @@ function prepare_page($item) {
$a = get_app();
$naked = 1;
// $naked = ((get_pconfig($item['uid'],'system','nakedpage')) ? 1 : 0);
$observer = $a->get_observer();
$observer = App::get_observer();
//240 chars is the longest we can have before we start hitting problems with suhosin sites
$preview = substr(urlencode($item['body']), 0, 240);
$link = z_root() . '/' . $a->cmd;
if(array_key_exists('webpage',$a->layout) && array_key_exists('authored',$a->layout['webpage'])) {
if($a->layout['webpage']['authored'] === 'none')
$link = z_root() . '/' . App::$cmd;
if(array_key_exists('webpage',App::$layout) && array_key_exists('authored',App::$layout['webpage'])) {
if(App::$layout['webpage']['authored'] === 'none')
$naked = 1;
// ... other possible options
}
@@ -1503,7 +1511,7 @@ function network_tabs() {
if ($no_active=='active') $all_active='active';
$cmd = $a->cmd;
$cmd = App::$cmd;
// tabs
$tabs = array();
@@ -1587,15 +1595,25 @@ function network_tabs() {
function profile_tabs($a, $is_owner = false, $nickname = null){
// Don't provide any profile tabs if we're running as the sys channel
if ($a->is_sys)
if (App::$is_sys)
return;
$channel = $a->get_channel();
$channel = App::get_channel();
if (is_null($nickname))
$nickname = $channel['channel_address'];
$uid = (($a->profile['profile_uid']) ? $a->profile['profile_uid'] : local_channel());
$uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel());
if($uid == local_channel()) {
$cal_link = '';
}
else {
$cal_link = '/cal/' . $nickname;
}
if (get_pconfig($uid, 'system', 'noprofiletabs'))
return;
@@ -1603,8 +1621,8 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
if (x($_GET, 'tab'))
$tab = notags(trim($_GET['tab']));
$url = $a->get_baseurl() . '/channel/' . $nickname;
$pr = $a->get_baseurl() . '/profile/' . $nickname;
$url = z_root() . '/channel/' . $nickname;
$pr = z_root() . '/profile/' . $nickname;
$tabs = array(
array(
@@ -1630,27 +1648,38 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
if ($p['view_storage']) {
$tabs[] = array(
'label' => t('Photos'),
'url' => $a->get_baseurl() . '/photos/' . $nickname,
'url' => z_root() . '/photos/' . $nickname,
'sel' => ((argv(0) == 'photos') ? 'active' : ''),
'title' => t('Photo Albums'),
'id' => 'photo-tab',
);
$tabs[] = array(
'label' => t('Files'),
'url' => $a->get_baseurl() . '/cloud/' . $nickname,
'url' => z_root() . '/cloud/' . $nickname,
'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''),
'title' => t('Files and Storage'),
'id' => 'files-tab',
);
}
if ($p['chat']) {
if($p['view_stream'] && $cal_link) {
$tabs[] = array(
'label' => t('Events'),
'url' => z_root() . $cal_link,
'sel' => ((argv(0) == 'cal' || argv(0) == 'events') ? 'active' : ''),
'title' => t('Events'),
'id' => 'event-tab',
);
}
if ($p['chat'] && feature_enabled($uid,'ajaxchat')) {
require_once('include/chat.php');
$has_chats = chatroom_list_count($uid);
if ($has_chats) {
$tabs[] = array(
'label' => t('Chatrooms'),
'url' => $a->get_baseurl() . '/chat/' . $nickname,
'url' => z_root() . '/chat/' . $nickname,
'sel' => ((argv(0) == 'chat') ? 'active' : '' ),
'title' => t('Chatrooms'),
'id' => 'chat-tab',
@@ -1663,7 +1692,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
if ($is_owner && $has_bookmarks) {
$tabs[] = array(
'label' => t('Bookmarks'),
'url' => $a->get_baseurl() . '/bookmarks',
'url' => z_root() . '/bookmarks',
'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''),
'title' => t('Saved Bookmarks'),
'id' => 'bookmarks-tab',
@@ -1673,7 +1702,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
if ($p['write_pages'] && feature_enabled($uid,'webpages')) {
$tabs[] = array(
'label' => t('Webpages'),
'url' => $a->get_baseurl() . '/webpages/' . $nickname,
'url' => z_root() . '/webpages/' . $nickname,
'sel' => ((argv(0) == 'webpages') ? 'active' : ''),
'title' => t('Manage Webpages'),
'id' => 'webpages-tab',

View File

@@ -20,7 +20,14 @@ function rsa_verify($data,$sig,$key,$alg = 'sha256') {
if(intval(OPENSSL_ALGO_SHA256) && $alg === 'sha256')
$alg = OPENSSL_ALGO_SHA256;
$verify = openssl_verify($data,$sig,$key,$alg);
$verify = @openssl_verify($data,$sig,$key,$alg);
if(! $verify) {
while($msg = openssl_error_string())
logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR);
btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR);
}
return $verify;
}
@@ -241,6 +248,7 @@ function pkcs1_encode($Modulus,$PublicExponent) {
}
// http://stackoverflow.com/questions/27568570/how-to-convert-raw-modulus-exponent-to-rsa-public-key-pem-format
function metopem($m,$e) {
$der = pkcs8_encode($m,$e);
$key = DerToPem($der,false);
@@ -291,11 +299,33 @@ function metorsa($m,$e) {
return $key;
}
function salmon_key($pubkey) {
pemtome($pubkey,$m,$e);
return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ;
}
function convert_salmon_key($key) {
if(strstr($key,','))
$rawkey = substr($key,strpos($key,',')+1);
else
$rawkey = substr($key,5);
$key_info = explode('.',$rawkey);
$m = base64url_decode($key_info[1]);
$e = base64url_decode($key_info[2]);
logger('key details: ' . print_r($key_info,true), LOGGER_DATA);
$salmon_key = metopem($m,$e);
return $salmon_key;
}
function z_obscure($s) {
return json_encode(crypto_encapsulate($s,get_config('system','pubkey')));
}
@@ -305,3 +335,4 @@ function z_unobscure($s) {
return $s;
return crypto_unencapsulate(json_decode($s,true),get_config('system','prvkey'));
}

View File

@@ -119,6 +119,8 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
* @return string
*/
function dob($dob) {
$a = get_app();
list($year, $month, $day) = sscanf($dob, '%4d-%2d-%2d');
$f = get_config('system', 'birthday_input_format');
if (! $f)
@@ -129,7 +131,15 @@ function dob($dob) {
else
$value = (($year) ? datetime_convert('UTC','UTC',$dob,'Y-m-d') : datetime_convert('UTC','UTC',$dob,'m-d'));
$o = '<input type="text" name="dob" value="' . $value . '" placeholder="' . t('YYYY-MM-DD or MM-DD') . '" />';
$o = replace_macros(get_markup_template("field_input.tpl"), array('$field' => array(
'dob',
t('Birthday'),
$value,
((intval($value)) ? t('Age: ') . age($value,App::$user['timezone'],App::$user['timezone']) : ''),
'',
'placeholder="' . t('YYYY-MM-DD or MM-DD') .'"'
)));
// if ($dob && $dob != '0000-00-00')
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
@@ -269,15 +279,16 @@ function relative_date($posted_date, $format = null) {
return t('less than a second ago');
}
$a = array( 12 * 30 * 24 * 60 * 60 => array( t('year'), t('years')),
30 * 24 * 60 * 60 => array( t('month'), t('months')),
7 * 24 * 60 * 60 => array( t('week'), t('weeks')),
24 * 60 * 60 => array( t('day'), t('days')),
60 * 60 => array( t('hour'), t('hours')),
60 => array( t('minute'), t('minutes')),
1 => array( t('second'), t('seconds'))
$a = array( 12 * 30 * 24 * 60 * 60 => 'y',
30 * 24 * 60 * 60 => 'm',
7 * 24 * 60 * 60 => 'w',
24 * 60 * 60 => 'd',
60 * 60 => 'h',
60 => 'i',
1 => 's'
);
foreach ($a as $secs => $str) {
$d = $etime / $secs;
if ($d >= 1) {
@@ -285,11 +296,43 @@ function relative_date($posted_date, $format = null) {
if (! $format)
$format = t('%1$d %2$s ago', 'e.g. 22 hours ago, 1 minute ago');
return sprintf($format, $r, (($r == 1) ? $str[0] : $str[1]));
return sprintf($format, $r, plural_dates($str,$r));
}
}
}
function plural_dates($k,$n) {
switch($k) {
case 'y':
return tt('year','years',$n,'relative_date');
break;
case 'm':
return tt('month','months',$n,'relative_date');
break;
case 'w':
return tt('week','weeks',$n,'relative_date');
break;
case 'd':
return tt('day','days',$n,'relative_date');
break;
case 'h':
return tt('hour','hours',$n,'relative_date');
break;
case 'i':
return tt('minute','minutes',$n,'relative_date');
break;
case 's':
return tt('second','seconds',$n,'relative_date');
break;
default:
return;
}
}
/**
* @brief Returns timezone correct age in years.
*
@@ -516,7 +559,7 @@ function update_birthdays() {
$ev['event_xchan'] = $rr['xchan_hash'];
$ev['start'] = datetime_convert('UTC', 'UTC', $rr['abook_dob']);
$ev['finish'] = datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day ');
$ev['adjust'] = 1;
$ev['adjust'] = intval(feature_enabled($rr['abook_channel'],'smart_birthdays'));
$ev['summary'] = sprintf( t('%1$s\'s birthday'), $rr['xchan_name']);
$ev['description'] = sprintf( t('Happy Birthday %1$s'),
'[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]') ;

View File

@@ -303,9 +303,9 @@ function q($sql) {
if($stmt === false) {
if(version_compare(PHP_VERSION, '5.4.0') >= 0)
logger('dba: vsprintf error: ' .
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1), true));
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1), true),LOGGER_NORMAL,LOG_CRIT);
else
logger('dba: vsprintf error: ' . print_r(debug_backtrace(), true));
logger('dba: vsprintf error: ' . print_r(debug_backtrace(), true),LOGGER_NORMAL,LOG_CRIT);
}
return $db->q($stmt);
}
@@ -314,7 +314,7 @@ function q($sql) {
* This will happen occasionally trying to store the
* session data after abnormal program termination
*/
logger('dba: no database: ' . print_r($args,true));
logger('dba: no database: ' . print_r($args,true),LOGGER_NORMAL,LOG_CRIT);
return false;
}
@@ -385,6 +385,7 @@ function db_getfunc($f) {
if(isset($lookup[$f]) && isset($lookup[$f][ACTIVE_DBTYPE]))
return $lookup[$f][ACTIVE_DBTYPE];
logger('Unable to abstract DB function "'. $f . '" for dbtype ' . ACTIVE_DBTYPE, LOGGER_DEBUG);
logger('Unable to abstract DB function "'. $f . '" for dbtype ' . ACTIVE_DBTYPE, LOGGER_DEBUG, LOG_ERR);
return $f;
}

View File

@@ -32,7 +32,7 @@ class dba_mysqli extends dba_driver {
if($this->error) {
logger('dba_mysqli: ERROR: ' . printable($sql) . "\n" . $this->error);
logger('dba_mysqli: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR);
if(file_exists('dbfail.out')) {
file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . "\n" . $this->error . "\n", FILE_APPEND);
}
@@ -40,13 +40,13 @@ class dba_mysqli extends dba_driver {
if(($result === true) || ($result === false)) {
if($this->debug) {
logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'));
logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'), LOGGER_NORMAL,(($result) ? LOG_INFO : LOG_ERR));
}
return $result;
}
if($this->debug) {
logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returned ' . $result->num_rows . ' results.');
logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returned ' . $result->num_rows . ' results.', LOGGER_NORMAL, LOG_INFO);
}
$r = array();
@@ -55,7 +55,7 @@ class dba_mysqli extends dba_driver {
$r[] = $x;
$result->free_result();
if($this->debug) {
logger('dba_mysqli: ' . printable(print_r($r,true)));
logger('dba_mysqli: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO);
}
}
return $r;

View File

@@ -421,7 +421,7 @@ function local_dir_update($uid, $force) {
$arr = array('channel_id' => $uid, 'hash' => $hash, 'profile' => $profile);
call_hooks('local_dir_update', $arr);
$address = $p[0]['channel_address'] . '@' . get_app()->get_hostname();
$address = $p[0]['channel_address'] . '@' . App::get_hostname();
if (perm_is_allowed($uid, '', 'view_profile')) {
import_directory_profile($hash, $arr['profile'], $address, 0);
@@ -436,6 +436,6 @@ function local_dir_update($uid, $force) {
}
}
$ud_hash = random_string() . '@' . get_app()->get_hostname();
update_modtime($hash, $ud_hash, $p[0]['channel_address'] . '@' . get_app()->get_hostname(),(($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
$ud_hash = random_string() . '@' . App::get_hostname();
update_modtime($hash, $ud_hash, $p[0]['channel_address'] . '@' . App::get_hostname(),(($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
}

View File

@@ -56,13 +56,13 @@ function notification($params) {
$banner = t('$Projectname Notification');
$product = t('$projectname'); // PLATFORM_NAME;
$siteurl = $a->get_baseurl(true);
$siteurl = z_root();
$thanks = t('Thank You,');
$sitename = get_config('system','sitename');
$site_admin = sprintf( t('%s Administrator'), $sitename);
$sender_name = $product;
$hostname = $a->get_hostname();
$hostname = App::get_hostname();
if(strpos($hostname,':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
@@ -419,12 +419,12 @@ function notification($params) {
return;
}
$itemlink = $a->get_baseurl() . '/notify/view/' . $notify_id;
$itemlink = z_root() . '/notify/view/' . $notify_id;
$msg = str_replace('$itemlink',$itemlink,$epreamble);
// wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
if (($a->language === 'en' || (! $a->language)) && strpos($msg,', '))
if ((App::$language === 'en' || (! App::$language)) && strpos($msg,', '))
$msg = substr($msg,strpos($msg,', ')+1);
$r = q("update notify set msg = '%s' where id = %d and uid = %d",
@@ -441,7 +441,7 @@ function notification($params) {
logger('notification: sending notification email');
$hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
if($hn && (! stristr(get_app()->get_hostname(),$hn))) {
if($hn && (! stristr(App::get_hostname(),$hn))) {
// this isn't the email notification host
pop_lang();
return;
@@ -455,7 +455,7 @@ function notification($params) {
// use $_SESSION['zid_override'] to force zid() to use
// the recipient address instead of the current observer
$_SESSION['zid_override'] = $recip['channel_address'] . '@' . get_app()->get_hostname();
$_SESSION['zid_override'] = $recip['channel_address'] . '@' . App::get_hostname();
$_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
$textversion = zidify_links($textversion);
@@ -529,7 +529,7 @@ function notification($params) {
$tpl = get_markup_template('email_notify_html.tpl');
$email_html_body = replace_macros($tpl,array(
'$banner' => $datarray['banner'],
'$notify_icon' => get_notify_icon(),
'$notify_icon' => Zotlabs\Project\System::get_notify_icon(),
'$product' => $datarray['product'],
'$preamble' => $datarray['preamble'],
'$sitename' => $datarray['sitename'],

View File

@@ -67,7 +67,7 @@ function ical_wrapper($ev) {
$o .= "BEGIN:VCALENDAR";
$o .= "\r\nVERSION:2.0";
$o .= "\r\nMETHOD:PUBLISH";
$o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . get_platform_name() . "//" . strtoupper(get_app()->language). "\r\n";
$o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . Zotlabs\Project\System::get_platform_name() . "//" . strtoupper(App::$language). "\r\n";
if(array_key_exists('start', $ev))
$o .= format_event_ical($ev);
else {
@@ -361,7 +361,7 @@ function event_store_event($arr) {
if(array_key_exists('external_id',$arr))
$hash = $arr['external_id'];
else
$hash = random_string() . '@' . get_app()->get_hostname();
$hash = random_string() . '@' . App::get_hostname();
$r = q("INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,start,finish,summary,description,location,type,
adjust,nofinish, event_status, event_status_date, event_percent, event_repeat, event_sequence, event_priority, allow_cid,allow_gid,deny_cid,deny_gid)
@@ -440,6 +440,17 @@ function event_addtocal($item_id, $uid) {
$ev['event_hash'] = $item['resource_id'];
}
if($ev->private)
$ev['allow_cid'] = '<' . $channel['channel_hash'] . '>';
else {
$acl = new Zotlabs\Access\AccessList($channel);
$x = $acl->get();
$ev['allow_cid'] = $x['allow_cid'];
$ev['allow_gid'] = $x['allow_gid'];
$ev['deny_cid'] = $x['deny_cid'];
$ev['deny_gid'] = $x['deny_gid'];
}
$event = event_store_event($ev);
if($event) {
$r = q("update item set resource_id = '%s', resource_type = 'event' where id = %d and uid = %d",

View File

@@ -25,7 +25,7 @@ function feature_enabled($uid,$feature) {
}
function get_feature_default($feature) {
$f = get_features();
$f = get_features(false);
foreach($f as $cat) {
foreach($cat as $feat) {
if(is_array($feat) && $feat[0] === $feature)
@@ -38,6 +38,9 @@ function get_feature_default($feature) {
function get_features($filtered = true) {
if(UNO && $filtered)
return array();
$arr = array(
// General
@@ -53,7 +56,8 @@ function get_features($filtered = true) {
array('private_notes', t('Private Notes'), t('Enables a tool to store notes and reminders (note: not encrypted)'),false,get_config('feature_lock','private_notes')),
array('nav_channel_select', t('Navigation Channel Select'), t('Change channels directly from within the navigation dropdown menu'),false,get_config('feature_lock','nav_channel_select')),
array('photo_location', t('Photo Location'), t('If location data is available on uploaded photos, link this to a map.'),false,get_config('feature_lock','photo_location')),
array('ajaxchat', t('Access Controlled Chatrooms'), t('Provide chatrooms and chat services with access control.'),true,get_config('feature_lock','ajaxchat')),
array('smart_birthdays', t('Smart Birthdays'), t('Make birthday events timezone aware in case your friends are scattered across the planet.'),true,get_config('feature_lock','smart_birthdays')),
array('expert', t('Expert Mode'), t('Enable Expert Mode to provide advanced configuration options'),false,get_config('feature_lock','expert')),
array('premium_channel', t('Premium Channel'), t('Allows you to set restrictions and terms on those that connect with your channel'),false,get_config('feature_lock','premium_channel')),
),
@@ -62,7 +66,7 @@ function get_features($filtered = true) {
'composition' => array(
t('Post Composition Features'),
// array('richtext', t('Richtext Editor'), t('Enable richtext editor'),falseget_config('feature_lock','richtext')),
array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false,get_config('feature_lock','markdown')),
// array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false,get_config('feature_lock','markdown')),
array('large_photos', t('Large Photos'), t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'),false,get_config('feature_lock','large_photos')),
array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds'),false,get_config('feature_lock','channel_sources')),
array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key'),false,get_config('feature_lock','content_encrypt')),

View File

@@ -134,26 +134,29 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
$their_perms = 0;
$xchan_hash = '';
$r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1",
dbesc($url),
dbesc($url)
);
if(! $r) {
// attempt network auto-discovery
if(strpos($url,'@') && (! $is_http)) {
$d = discover_by_webbie($url);
}
elseif($is_http) {
if(get_config('system','feed_contacts'))
$d = discover_by_webbie($url);
if((! $d) && ($is_http)) {
// try RSS discovery
if(get_config('system','feed_contacts')) {
$d = discover_by_url($url);
}
else {
$result['message'] = t('Protocol disabled.');
return $result;
}
}
if($d) {
$r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1",
dbesc($url),
@@ -161,6 +164,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
);
}
}
// if discovery was a success we should have an xchan record in $r
if($r) {
$xchan = $r[0];
$xchan_hash = $r[0]['xchan_hash'];
@@ -175,7 +181,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
return $result;
}
$x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => 1, 'singleton' => 0);
$allowed = (($is_red || $r[0]['xchan_network'] === 'rss') ? 1 : 0);
$x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => $allowed, 'singleton' => 0);
call_hooks('follow_allow',$x);
@@ -185,28 +193,13 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
}
$singleton = intval($x['singleton']);
if((local_channel()) && $uid == local_channel()) {
$aid = get_account_id();
$hash = get_observer_hash();
$ch = $a->get_channel();
$default_group = $ch['channel_default_group'];
}
else {
$r = q("select * from channel where channel_id = %d limit 1",
intval($uid)
);
if(! $r) {
$result['message'] = t('local account not found.');
return $result;
}
$aid = $r[0]['channel_account_id'];
$hash = $r[0]['channel_hash'];
$default_group = $r[0]['channel_default_group'];
}
$aid = $channel['channel_account_id'];
$hash = get_observer_hash();
$default_group = $channel['channel_default_group'];
if($xchan['xchan_network'] === 'rss') {
if($is_http) {
// check service class feed limits
$r = q("select count(*) as total from abook where abook_account = %d and abook_feed = 1 ",
intval($aid)
@@ -230,7 +223,6 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
intval($uid)
);
if($r) {
$abook_instance = $r[0]['abook_instance'];
@@ -280,7 +272,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
proc_run('php', 'include/notifier.php', 'permission_create', $result['abook']['abook_id']);
}
$arr = array('channel_id' => $uid, 'abook' => $result['abook']);
$arr = array('channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook']);
call_hooks('follow', $arr);

View File

@@ -200,7 +200,7 @@ function group_get_members($gid) {
if(intval($gid)) {
$r = q("SELECT * FROM `group_member`
LEFT JOIN abook ON abook_xchan = `group_member`.`xchan` left join xchan on xchan_hash = abook_xchan
WHERE `gid` = %d AND abook_channel = %d and `group_member`.`uid` = %d and xchan_deleted = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
WHERE `gid` = %d AND abook_channel = %d and `group_member`.`uid` = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
intval($gid),
intval(local_channel()),
intval(local_channel())
@@ -211,6 +211,22 @@ function group_get_members($gid) {
return $ret;
}
function group_get_members_xchan($gid) {
$ret = array();
if(intval($gid)) {
$r = q("SELECT xchan FROM group_member WHERE gid = %d AND uid = %d",
intval($gid),
intval(local_channel())
);
if(count($r)) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
return $ret;
}
function mini_group_select($uid,$group = '') {
$grps = array();

View File

@@ -134,10 +134,17 @@ function hubloc_change_primary($hubloc) {
$r = q("select channel_id, channel_primary from channel where channel_hash = '%s' limit 1",
dbesc($hubloc['hubloc_hash'])
);
if(($r) && (! $r[0]['channel_primary'])) {
q("update channel set channel_primary = 1 where channel_id = %d",
intval($r[0]['channel_id'])
);
if($r) {
if(! $r[0]['channel_primary']) {
q("update channel set channel_primary = 1 where channel_id = %d",
intval($r[0]['channel_id'])
);
}
else {
q("update channel set channel_primary = 0 where channel_id = %d",
intval($r[0]['channel_id'])
);
}
}
// do we even have an xchan for this hubloc and if so is it already set as primary?

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