Merge branch 'dev' into perms
This commit is contained in:
commit
85d2ad4aea
76
CHANGELOG
76
CHANGELOG
@ -1,3 +1,79 @@
|
|||||||
|
Hubzilla 1.8
|
||||||
|
Administration:
|
||||||
|
Cleanup and resolve some edge cases with addon repository manager
|
||||||
|
Provide sort field and direction on all fields of account and channel administration tables
|
||||||
|
Rename 'user' administration to account administration to reflect its true purpose
|
||||||
|
'safemode' tool to quickly disable and re-enable addons during a hypothetical upgrade crisis
|
||||||
|
Security:
|
||||||
|
Edited comments to private posts could lose their privacy settings under some circumstances
|
||||||
|
Provide zot-finger signatures to prevent a possible but rare exploit involving DNS spoofing and phishing
|
||||||
|
ACL selections:
|
||||||
|
Various improvements to the ACL editor to further simplify the concepts and make it more intuitive
|
||||||
|
Chat:
|
||||||
|
Notifications of chatroom activity using standard browser notification interfaces.
|
||||||
|
Themes:
|
||||||
|
Allow a theme:schema string to represent a valid theme name. This fixes issues with setting schemas on site themes.
|
||||||
|
Pubsites:
|
||||||
|
Show server role (identify UNO or basic sites as opposed to hubzilla pro) and link to statistics
|
||||||
|
Documentation:
|
||||||
|
Clarify privacy rights of commenters w/r/t conversation owners, as this policy is network dependent.
|
||||||
|
Wiki (Git backed):
|
||||||
|
Brand new feature. We'll call it experimental until it has undergone a bit more testing.
|
||||||
|
Account Cloning:
|
||||||
|
Regression on clone channel creation created a new channel name each time.
|
||||||
|
New issue (fixed) with directory creation on cloned file content
|
||||||
|
Content Rendering:
|
||||||
|
Add inline code (in addition to the existing code blocks) to BBcode
|
||||||
|
Add emoji reactions
|
||||||
|
Add emojis as extended smilies with auto-complete support
|
||||||
|
Emoji added as feature so it can be enabled/disabled and locked
|
||||||
|
Ability to configure the standard reactions available on a site basis
|
||||||
|
Disable 'convenience' ajax autoload on pgdn key, as it could lead to premature memory exhaustion
|
||||||
|
Photos:
|
||||||
|
Change album sort ordering, allow widgets and plugins to define other orderings
|
||||||
|
Apps:
|
||||||
|
Synchronise app list with changes to system apps
|
||||||
|
Preserve existing app categories on app updates/edits
|
||||||
|
Regression: fixed translated system app names
|
||||||
|
Architecture:
|
||||||
|
Provide autoloaded class files and libraries for plugins.
|
||||||
|
Further refactoring of session driver to sort out some cookie anomolies
|
||||||
|
Experimental PDO database driver
|
||||||
|
Creation of Daemon Master class and port all daemon (background task) interfaces to use it
|
||||||
|
Create separate class for each of 'Cron', 'Cron daily', and 'Cron weekly'.
|
||||||
|
Always run a Cron maintenance task if not run in the last four hours
|
||||||
|
Refactor the template classes
|
||||||
|
Refactor the ConversationItem mess into ThreadItem and ThreadStream
|
||||||
|
Refactor Apps, Enotify, and Chat library code
|
||||||
|
Refactor the various Config libraries (Config, PConfig, XConfig, AConfig, AbConfig, and IConfig)
|
||||||
|
Created WebServer class for top level
|
||||||
|
Remove mcrypt dependencies (deprecated in PHP 7.1)
|
||||||
|
Remove all reserved (including merely 'not recommended') words as DB table column names
|
||||||
|
Provide mutex lock on DB logging to prevent recursion under rare failure modes.
|
||||||
|
Bugfixes:
|
||||||
|
Remove db_close function on page end - not needed and will not work with persistent DB connections.
|
||||||
|
Undefined ref_session_write
|
||||||
|
Some session functions needed to be static to work with CalDAV/CardDAV
|
||||||
|
CLI interface: argc and argv were reversed
|
||||||
|
HTML entities double encoded in edited titles
|
||||||
|
Prevent delivering to empty recipients
|
||||||
|
Sabre library setting some security headers for SAML after we've emitted HTML content
|
||||||
|
Always initialise miniApp (caused obscure warning message if not set)
|
||||||
|
Block 'sys' channels from being 'random profile' candidates
|
||||||
|
DB update failed email could be sent in the wrong language under rare circumstances
|
||||||
|
Openid remote authentication used incorrect namespace
|
||||||
|
URL attached to profile "things" was not linked, always showing the "thing" manage page
|
||||||
|
New connection wasn't added to default privacy group when "auto-accept" was enabled
|
||||||
|
Regression: iconfig sharing wasn't working properly
|
||||||
|
Plugins:
|
||||||
|
CalDAV/CardDAV plugin provided
|
||||||
|
Issue sending Diaspora 'like' activities from sources that did not propagate the DCV
|
||||||
|
Allow 'superblock' to work across API calls from third party clients
|
||||||
|
statistics.json: use 'zot' as protocol
|
||||||
|
Issues fixed during testing of ability to follow Diaspora tags
|
||||||
|
Parse issue with Diaspora reshare content
|
||||||
|
Chess: moved to main repo, ported to 1.8
|
||||||
|
|
||||||
Hubzilla 1.6
|
Hubzilla 1.6
|
||||||
Cleanup and standardise the interfaces to the "jot" editor
|
Cleanup and standardise the interfaces to the "jot" editor
|
||||||
Router re-written to support calling class object methods as controllers
|
Router re-written to support calling class object methods as controllers
|
||||||
|
43
Zotlabs/Daemon/README.md
Normal file
43
Zotlabs/Daemon/README.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
Daemon (background) Processes
|
||||||
|
=============================
|
||||||
|
|
||||||
|
|
||||||
|
This directory provides background tasks which are executed by a
|
||||||
|
command-line process and detached from normal web processing.
|
||||||
|
|
||||||
|
Background tasks are invoked by calling
|
||||||
|
|
||||||
|
|
||||||
|
Zotlabs\Daemon\Master::Summon([ $cmd, $arg1, $argn... ]);
|
||||||
|
|
||||||
|
The Master class loads the desired command file and passes the arguments.
|
||||||
|
|
||||||
|
|
||||||
|
To create a background task 'Foo' use the following template.
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Daemon;
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
|
||||||
|
static public function run($argc,$argv) {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The Master class "summons" the command by creating an executable script
|
||||||
|
from the provided arguments, then it invokes "Release" to execute the script
|
||||||
|
detached from web processing. This process calls the static::run() function
|
||||||
|
with any command line arguments using the traditional argc, argv format.
|
||||||
|
|
||||||
|
Please note: These are *real* $argc, $argv variables passed from the command
|
||||||
|
line, and not the parsed argc() and argv() functions/variables which were
|
||||||
|
obtained from parsing path components of the request URL by web processes.
|
||||||
|
|
||||||
|
Background processes do not emit displayable output except through logs. They
|
||||||
|
should also not make any assumptions about their HTML and web environment
|
||||||
|
(as they do not have a web environment), particularly with respect to global
|
||||||
|
variables such as $_SERVER, $_REQUEST, $_GET, $_POST, $_COOKIES, and $_SESSION.
|
||||||
|
|
@ -5,18 +5,18 @@ namespace Zotlabs\Lib;
|
|||||||
|
|
||||||
class AbConfig {
|
class AbConfig {
|
||||||
|
|
||||||
static public function Load($chash,$xhash) {
|
static public function Load($chan,$xhash) {
|
||||||
$r = q("select * from abconfig where chan = '%s' and xchan = '%s'",
|
$r = q("select * from abconfig where chan = %d and xchan = '%s'",
|
||||||
dbesc($chash),
|
intval($chan),
|
||||||
dbesc($xhash)
|
dbesc($xhash)
|
||||||
);
|
);
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function Get($chash,$xhash,$family,$key) {
|
static public function Get($chan,$xhash,$family,$key) {
|
||||||
$r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
$r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1",
|
||||||
dbesc($chash),
|
intval($chan),
|
||||||
dbesc($xhash),
|
dbesc($xhash),
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key)
|
dbesc($key)
|
||||||
@ -28,14 +28,14 @@ class AbConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function Set($chash,$xhash,$family,$key,$value) {
|
static public function Set($chan,$xhash,$family,$key,$value) {
|
||||||
|
|
||||||
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
|
||||||
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
|
||||||
|
|
||||||
if(self::Get($chash,$xhash,$family,$key) === false) {
|
if(self::Get($chan,$xhash,$family,$key) === false) {
|
||||||
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ",
|
$r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( %d, '%s', '%s', '%s', '%s' ) ",
|
||||||
dbesc($chash),
|
intval($chan),
|
||||||
dbesc($xhash),
|
dbesc($xhash),
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key),
|
dbesc($key),
|
||||||
@ -43,9 +43,9 @@ class AbConfig {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
|
$r = q("update abconfig set v = '%s' where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||||
dbesc($dbvalue),
|
dbesc($dbvalue),
|
||||||
dbesc($chash),
|
dbesc($chan),
|
||||||
dbesc($xhash),
|
dbesc($xhash),
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key)
|
dbesc($key)
|
||||||
@ -58,10 +58,10 @@ class AbConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function Delete($chash,$xhash,$family,$key) {
|
static public function Delete($chan,$xhash,$family,$key) {
|
||||||
|
|
||||||
$r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ",
|
$r = q("delete from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' ",
|
||||||
dbesc($chash),
|
intval($chan),
|
||||||
dbesc($xhash),
|
dbesc($xhash),
|
||||||
dbesc($family),
|
dbesc($family),
|
||||||
dbesc($key)
|
dbesc($key)
|
||||||
@ -70,4 +70,4 @@ class AbConfig {
|
|||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -215,6 +215,7 @@ class Apps {
|
|||||||
'Settings' => t('Settings'),
|
'Settings' => t('Settings'),
|
||||||
'Files' => t('Files'),
|
'Files' => t('Files'),
|
||||||
'Webpages' => t('Webpages'),
|
'Webpages' => t('Webpages'),
|
||||||
|
'Wiki' => t('Wiki'),
|
||||||
'Channel Home' => t('Channel Home'),
|
'Channel Home' => t('Channel Home'),
|
||||||
'View Profile' => t('View Profile'),
|
'View Profile' => t('View Profile'),
|
||||||
'Photos' => t('Photos'),
|
'Photos' => t('Photos'),
|
||||||
@ -263,6 +264,8 @@ class Apps {
|
|||||||
if(! $papp['photo'])
|
if(! $papp['photo'])
|
||||||
$papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
|
$papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
|
||||||
|
|
||||||
|
self::translate_system_apps($papp);
|
||||||
|
|
||||||
$papp['papp'] = self::papp_encode($papp);
|
$papp['papp'] = self::papp_encode($papp);
|
||||||
|
|
||||||
if(! strstr($papp['url'],'://'))
|
if(! strstr($papp['url'],'://'))
|
||||||
|
46
Zotlabs/Lib/Cache.php
Normal file
46
Zotlabs/Lib/Cache.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php /** @file */
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cache api
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Cache {
|
||||||
|
public static function get($key) {
|
||||||
|
$r = q("SELECT v FROM cache WHERE k = '%s' limit 1",
|
||||||
|
dbesc($key)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($r)
|
||||||
|
return $r[0]['v'];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function set($key,$value) {
|
||||||
|
|
||||||
|
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
|
||||||
|
dbesc($key)
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
|
||||||
|
dbesc($value),
|
||||||
|
dbesc(datetime_convert()),
|
||||||
|
dbesc($key));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
|
||||||
|
dbesc($key),
|
||||||
|
dbesc($value),
|
||||||
|
dbesc(datetime_convert()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function clear() {
|
||||||
|
q("DELETE FROM cache WHERE updated < '%s'",
|
||||||
|
dbesc(datetime_convert('UTC','UTC',"now - 30 days")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
112
Zotlabs/Lib/SuperCurl.php
Normal file
112
Zotlabs/Lib/SuperCurl.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief wrapper for z_fetch_url() which can be instantiated with several built-in parameters and
|
||||||
|
* these can be modified and re-used. Useful for CalDAV and other processes which need to authenticate
|
||||||
|
* and set lots of CURL options (many of which stay the same from one call to the next).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SuperCurl {
|
||||||
|
|
||||||
|
|
||||||
|
private $auth;
|
||||||
|
private $url;
|
||||||
|
|
||||||
|
private $curlopt = array();
|
||||||
|
|
||||||
|
private $headers = null;
|
||||||
|
public $filepos = 0;
|
||||||
|
public $filehandle = 0;
|
||||||
|
public $request_data = '';
|
||||||
|
|
||||||
|
private $request_method = 'GET';
|
||||||
|
private $upload = false;
|
||||||
|
|
||||||
|
|
||||||
|
private function set_data($s) {
|
||||||
|
$this->request_data = $s;
|
||||||
|
$this->filepos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function curl_read($ch,$fh,$size) {
|
||||||
|
|
||||||
|
if($this->filepos < 0) {
|
||||||
|
unset($fh);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$s = substr($this->request_data,$this->filepos,$size);
|
||||||
|
|
||||||
|
if(strlen($s) < $size)
|
||||||
|
$this->filepos = (-1);
|
||||||
|
else
|
||||||
|
$this->filepos = $this->filepos + $size;
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct($opts = array()) {
|
||||||
|
$this->set($opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set($opts = array()) {
|
||||||
|
if($opts) {
|
||||||
|
foreach($opts as $k => $v) {
|
||||||
|
switch($k) {
|
||||||
|
case 'http_auth':
|
||||||
|
$this->auth = $v;
|
||||||
|
break;
|
||||||
|
case 'custom':
|
||||||
|
$this->request_method = $v;
|
||||||
|
break;
|
||||||
|
case 'url':
|
||||||
|
$this->url = $v;
|
||||||
|
break;
|
||||||
|
case 'data':
|
||||||
|
$this->set_data($v);
|
||||||
|
if($v) {
|
||||||
|
$this->upload = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->upload = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'headers':
|
||||||
|
$this->headers = $v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->curlopts[$k] = $v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec() {
|
||||||
|
$opts = $this->curlopts;
|
||||||
|
if($this->auth)
|
||||||
|
$opts['http_auth'] = $this->auth;
|
||||||
|
if($this->custom)
|
||||||
|
$opts['custom'] = $this->custom;
|
||||||
|
if($this->headers)
|
||||||
|
$opts['headers'] = $this->headers;
|
||||||
|
if($this->upload) {
|
||||||
|
$opts['upload'] = true;
|
||||||
|
$opts['infile'] = $this->filehandle;
|
||||||
|
$opts['infilesize'] = strlen($this->request_data);
|
||||||
|
$opts['readfunc'] = [ $this, 'curl_read' ] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
$recurse = 0;
|
||||||
|
return z_fetch_url($this->url,true,$recurse,(($opts) ? $opts : null));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -122,7 +122,7 @@ class XConfig {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
App::$config[$xchan][$family][$key] = $value;
|
\App::$config[$xchan][$family][$key] = $value;
|
||||||
|
|
||||||
if($ret)
|
if($ret)
|
||||||
return $value;
|
return $value;
|
||||||
@ -157,4 +157,4 @@ class XConfig {
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class Achievements extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$profile = 0;
|
$profile = 0;
|
||||||
$profile = argv(1);
|
$profile = argv(1);
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
$r = q("select channel_id from channel where channel_address = '%s'",
|
$r = q("select channel_id from channel where channel_address = '%s'",
|
||||||
dbesc($which)
|
dbesc($which)
|
||||||
|
@ -65,18 +65,20 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
intval($count),
|
intval($count),
|
||||||
intval($start)
|
intval($start)
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach($r as $g){
|
if($r) {
|
||||||
// logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
|
foreach($r as $g){
|
||||||
$groups[] = array(
|
// logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
|
||||||
"type" => "g",
|
$groups[] = array(
|
||||||
"photo" => "images/twopeople.png",
|
"type" => "g",
|
||||||
"name" => $g['gname'],
|
"photo" => "images/twopeople.png",
|
||||||
"id" => $g['id'],
|
"name" => $g['gname'],
|
||||||
"xid" => $g['hash'],
|
"id" => $g['id'],
|
||||||
"uids" => group_get_members_xchan($g['id']),
|
"xid" => $g['hash'],
|
||||||
"link" => ''
|
"uids" => group_get_members_xchan($g['id']),
|
||||||
);
|
"link" => ''
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +206,7 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
$r = array();
|
$r = array();
|
||||||
|
|
||||||
if(count($r)) {
|
if($r) {
|
||||||
foreach($r as $g){
|
foreach($r as $g){
|
||||||
|
|
||||||
// remove RSS feeds from ACLs - they are inaccessible
|
// remove RSS feeds from ACLs - they are inaccessible
|
||||||
|
@ -1738,7 +1738,7 @@ class Admin extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
// name, label, value, help string, extra data...
|
// name, label, value, help string, extra data...
|
||||||
'$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""),
|
'$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""),
|
||||||
'$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Red top-level directory.")),
|
'$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")),
|
||||||
'$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
|
'$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
|
||||||
|
|
||||||
'$form_security_token' => get_form_security_token('admin_logs'),
|
'$form_security_token' => get_form_security_token('admin_logs'),
|
||||||
|
@ -12,7 +12,7 @@ class Block extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$which = argv(1);
|
$which = argv(1);
|
||||||
$profile = 0;
|
$profile = 0;
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
if(\App::$profile['profile_uid'])
|
if(\App::$profile['profile_uid'])
|
||||||
head_set_icon(\App::$profile['thumb']);
|
head_set_icon(\App::$profile['thumb']);
|
||||||
@ -52,8 +52,8 @@ class Block extends \Zotlabs\Web\Controller {
|
|||||||
require_once('include/security.php');
|
require_once('include/security.php');
|
||||||
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
||||||
|
|
||||||
$r = q("select item.* from item left join item_id on item.id = item_id.iid
|
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||||
where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and
|
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and iconfig.k = 'BUILDBLOCK' and
|
||||||
item_type = %d $sql_options $revision limit 1",
|
item_type = %d $sql_options $revision limit 1",
|
||||||
intval($u[0]['channel_id']),
|
intval($u[0]['channel_id']),
|
||||||
dbesc($page_id),
|
dbesc($page_id),
|
||||||
@ -64,8 +64,8 @@ class Block extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
// Check again with no permissions clause to see if it is a permissions issue
|
// Check again with no permissions clause to see if it is a permissions issue
|
||||||
|
|
||||||
$x = q("select item.* from item left join item_id on item.id = item_id.iid
|
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||||
where item.uid = %d and sid = '%s' and service = 'BUILDBLOCK' and
|
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and iconfig.k = 'BUILDBLOCK' and
|
||||||
item_type = %d $revision limit 1",
|
item_type = %d $revision limit 1",
|
||||||
intval($u[0]['channel_id']),
|
intval($u[0]['channel_id']),
|
||||||
dbesc($page_id),
|
dbesc($page_id),
|
||||||
|
@ -22,12 +22,12 @@ class Blocks extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_load($a,$which);
|
profile_load($which);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(! \App::$profile) {
|
if(! \App::$profile) {
|
||||||
notice( t('Requested profile is not available.') . EOL );
|
notice( t('Requested profile is not available.') . EOL );
|
||||||
@ -111,8 +111,11 @@ class Blocks extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$editor = status_editor($a,$x);
|
$editor = status_editor($a,$x);
|
||||||
|
|
||||||
$r = q("select iid, sid, mid, title, body, mimetype, created, edited from item_id left join item on item_id.iid = item.id
|
|
||||||
where item_id.uid = %d and service = 'BUILDBLOCK' and item_type = %d order by item.created desc",
|
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
|
||||||
|
left join item on iconfig.iid = item.id
|
||||||
|
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'
|
||||||
|
and item_type = %d order by item.created desc",
|
||||||
intval($owner),
|
intval($owner),
|
||||||
intval(ITEM_TYPE_BLOCK)
|
intval(ITEM_TYPE_BLOCK)
|
||||||
);
|
);
|
||||||
@ -129,12 +132,12 @@ class Blocks extends \Zotlabs\Web\Controller {
|
|||||||
'created' => $rr['created'],
|
'created' => $rr['created'],
|
||||||
'edited' => $rr['edited'],
|
'edited' => $rr['edited'],
|
||||||
'mimetype' => $rr['mimetype'],
|
'mimetype' => $rr['mimetype'],
|
||||||
'pagetitle' => $rr['sid'],
|
'pagetitle' => $rr['v'],
|
||||||
'mid' => $rr['mid']
|
'mid' => $rr['mid']
|
||||||
);
|
);
|
||||||
$pages[$rr['iid']][] = array(
|
$pages[$rr['iid']][] = array(
|
||||||
'url' => $rr['iid'],
|
'url' => $rr['iid'],
|
||||||
'name' => $rr['sid'],
|
'name' => $rr['v'],
|
||||||
'title' => $rr['title'],
|
'title' => $rr['title'],
|
||||||
'created' => $rr['created'],
|
'created' => $rr['created'],
|
||||||
'edited' => $rr['edited'],
|
'edited' => $rr['edited'],
|
||||||
|
@ -20,7 +20,7 @@ class Cal extends \Zotlabs\Web\Controller {
|
|||||||
if(argc() > 1) {
|
if(argc() > 1) {
|
||||||
$nick = argv(1);
|
$nick = argv(1);
|
||||||
|
|
||||||
profile_load($a,$nick);
|
profile_load($nick);
|
||||||
|
|
||||||
$channelx = channelx_by_nick($nick);
|
$channelx = channelx_by_nick($nick);
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class Channel extends \Zotlabs\Web\Controller {
|
|||||||
// Run profile_load() here to make sure the theme is set before
|
// Run profile_load() here to make sure the theme is set before
|
||||||
// we start loading content
|
// we start loading content
|
||||||
|
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class Chat extends \Zotlabs\Web\Controller {
|
|||||||
// Run profile_load() here to make sure the theme is set before
|
// Run profile_load() here to make sure the theme is set before
|
||||||
// we start loading content
|
// we start loading content
|
||||||
|
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class Cloud extends \Zotlabs\Web\Controller {
|
|||||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
||||||
|
|
||||||
if ($which)
|
if ($which)
|
||||||
profile_load($a, $which, $profile);
|
profile_load( $which, $profile);
|
||||||
|
|
||||||
$auth = new \Zotlabs\Storage\BasicAuth();
|
$auth = new \Zotlabs\Storage\BasicAuth();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class Common extends \Zotlabs\Web\Controller {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if($x)
|
if($x)
|
||||||
profile_load($a,$x[0]['channel_address'],0);
|
profile_load($x[0]['channel_address'],0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class Connect extends \Zotlabs\Web\Controller {
|
|||||||
if($r)
|
if($r)
|
||||||
\App::$data['channel'] = $r[0];
|
\App::$data['channel'] = $r[0];
|
||||||
|
|
||||||
profile_load($a,$which,'');
|
profile_load($which,'');
|
||||||
}
|
}
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
|
@ -16,14 +16,14 @@ require_once('include/zot.php');
|
|||||||
require_once('include/widgets.php');
|
require_once('include/widgets.php');
|
||||||
require_once('include/photos.php');
|
require_once('include/photos.php');
|
||||||
|
|
||||||
/* @brief Initialize the connection-editor
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class Connedit extends \Zotlabs\Web\Controller {
|
class Connedit extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
/* @brief Initialize the connection-editor
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
if(! local_channel())
|
if(! local_channel())
|
||||||
@ -51,7 +51,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
if(! local_channel())
|
if(! local_channel())
|
||||||
return;
|
return;
|
||||||
@ -219,7 +219,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
//Update profile photo permissions
|
//Update profile photo permissions
|
||||||
|
|
||||||
logger('A new profile was assigned - updating profile photos');
|
logger('A new profile was assigned - updating profile photos');
|
||||||
profile_photo_set_profile_perms($profile_id);
|
profile_photo_set_profile_perms(local_channel(),$profile_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +345,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
unset($clone['abook_account']);
|
unset($clone['abook_account']);
|
||||||
unset($clone['abook_channel']);
|
unset($clone['abook_channel']);
|
||||||
|
|
||||||
$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
|
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
|
||||||
if($abconfig)
|
if($abconfig)
|
||||||
$clone['abconfig'] = $abconfig;
|
$clone['abconfig'] = $abconfig;
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$sort_type = 0;
|
$sort_type = 0;
|
||||||
$o = '';
|
$o = '';
|
||||||
@ -418,7 +418,13 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||||||
goaway(z_root() . '/connedit/' . $contact_id);
|
goaway(z_root() . '/connedit/' . $contact_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if($cmd === 'resetphoto') {
|
||||||
|
q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s' limit 1",
|
||||||
|
dbesc($orig_record[0]['xchan_hash'])
|
||||||
|
);
|
||||||
|
$cmd = 'refresh';
|
||||||
|
}
|
||||||
|
|
||||||
if($cmd === 'refresh') {
|
if($cmd === 'refresh') {
|
||||||
if($orig_record[0]['xchan_network'] === 'zot') {
|
if($orig_record[0]['xchan_network'] === 'zot') {
|
||||||
if(! zot_refresh($orig_record[0],\App::get_channel()))
|
if(! zot_refresh($orig_record[0],\App::get_channel()))
|
||||||
|
@ -29,7 +29,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
profile_load($a,$channel['channel_address']);
|
profile_load($channel['channel_address']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
return;
|
return;
|
||||||
@ -271,7 +271,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
notice( t('Permission denied.') . EOL );
|
notice( t('Permission denied.') . EOL );
|
||||||
|
@ -58,7 +58,7 @@ class Dav extends \Zotlabs\Web\Controller {
|
|||||||
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
|
||||||
|
|
||||||
if ($which)
|
if ($which)
|
||||||
profile_load($a, $which, $profile);
|
profile_load( $which, $profile);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,12 +106,13 @@ class Display extends \Zotlabs\Web\Controller {
|
|||||||
$x = q("select * from channel where channel_id = %d limit 1",
|
$x = q("select * from channel where channel_id = %d limit 1",
|
||||||
intval($target_item['uid'])
|
intval($target_item['uid'])
|
||||||
);
|
);
|
||||||
$y = q("select * from item_id where uid = %d and service = 'WEBPAGE' and iid = %d limit 1",
|
$y = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||||
|
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1",
|
||||||
intval($target_item['uid']),
|
intval($target_item['uid']),
|
||||||
intval($target_item['id'])
|
intval($target_item['id'])
|
||||||
);
|
);
|
||||||
if($x && $y) {
|
if($x && $y) {
|
||||||
goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['sid']);
|
goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notice( t('Page not found.') . EOL);
|
notice( t('Page not found.') . EOL);
|
||||||
|
@ -21,7 +21,7 @@ class Editblock extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_load($a,$which);
|
profile_load($which);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,11 +85,11 @@ class Editblock extends \Zotlabs\Web\Controller {
|
|||||||
intval($owner)
|
intval($owner)
|
||||||
);
|
);
|
||||||
if($itm) {
|
if($itm) {
|
||||||
$item_id = q("select * from item_id where service = 'BUILDBLOCK' and iid = %d limit 1",
|
$item_id = q("select * from iconfig where cat = 'system' and k = 'BUILDBLOCK' and iid = %d limit 1",
|
||||||
intval($itm[0]['id'])
|
intval($itm[0]['id'])
|
||||||
);
|
);
|
||||||
if($item_id)
|
if($item_id)
|
||||||
$block_title = $item_id[0]['sid'];
|
$block_title = $item_id[0]['v'];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notice( t('Item not found') . EOL);
|
notice( t('Item not found') . EOL);
|
||||||
|
@ -21,7 +21,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_load($a,$which);
|
profile_load($which);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,11 +96,12 @@ class Editlayout extends \Zotlabs\Web\Controller {
|
|||||||
intval($owner)
|
intval($owner)
|
||||||
);
|
);
|
||||||
|
|
||||||
$item_id = q("select * from item_id where service = 'PDL' and iid = %d limit 1",
|
$item_id = q("select * from iconfig where cat = 'system' and k = 'PDL' and iid = %d limit 1",
|
||||||
intval($itm[0]['id'])
|
intval($itm[0]['id'])
|
||||||
);
|
);
|
||||||
if($item_id)
|
if($item_id)
|
||||||
$layout_title = $item_id[0]['sid'];
|
$layout_title = $item_id[0]['v'];
|
||||||
|
|
||||||
|
|
||||||
$rp = 'layouts/' . $which;
|
$rp = 'layouts/' . $which;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_load($a,$which);
|
profile_load($which);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,11 +114,11 @@ class Editwebpage extends \Zotlabs\Web\Controller {
|
|||||||
$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
|
$itm[0]['body'] = crypto_unencapsulate(json_decode_plus($itm[0]['body']),$key);
|
||||||
}
|
}
|
||||||
|
|
||||||
$item_id = q("select * from item_id where service = 'WEBPAGE' and iid = %d limit 1",
|
$item_id = q("select * from iconfig where cat = 'system' and k = 'WEBPAGE' and iid = %d limit 1",
|
||||||
intval($itm[0]['id'])
|
intval($itm[0]['id'])
|
||||||
);
|
);
|
||||||
if($item_id)
|
if($item_id)
|
||||||
$page_title = $item_id[0]['sid'];
|
$page_title = $item_id[0]['v'];
|
||||||
|
|
||||||
$mimetype = $itm[0]['mimetype'];
|
$mimetype = $itm[0]['mimetype'];
|
||||||
|
|
||||||
|
180
Zotlabs/Module/Embedphotos.php
Normal file
180
Zotlabs/Module/Embedphotos.php
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
<?php
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This is the POST destination for the embedphotos button
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class Embedphotos extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function post() {
|
||||||
|
|
||||||
|
if (argc() > 1 && argv(1) === 'album') {
|
||||||
|
// API: /embedphotos/album
|
||||||
|
$name = (x($_POST,'name') ? $_POST['name'] : null );
|
||||||
|
if (!$name) {
|
||||||
|
json_return_and_die(array('errormsg' => 'Error retrieving album', 'status' => false));
|
||||||
|
}
|
||||||
|
$album = $this->embedphotos_widget_album(array('channel' => \App::get_channel(), 'album' => $name));
|
||||||
|
json_return_and_die(array('status' => true, 'content' => $album));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (argc() > 1 && argv(1) === 'albumlist') {
|
||||||
|
// API: /embedphotos/albumlist
|
||||||
|
$album_list = $this->embedphotos_album_list($a);
|
||||||
|
json_return_and_die(array('status' => true, 'albumlist' => $album_list));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (argc() > 1 && argv(1) === 'photolink') {
|
||||||
|
// API: /embedphotos/photolink
|
||||||
|
$href = (x($_POST,'href') ? $_POST['href'] : null );
|
||||||
|
if (!$href) {
|
||||||
|
json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false));
|
||||||
|
}
|
||||||
|
$resource_id = array_pop(explode("/", $href));
|
||||||
|
$r = q("SELECT obj from item where resource_type = 'photo' and resource_id = '%s' limit 1",
|
||||||
|
dbesc($resource_id)
|
||||||
|
);
|
||||||
|
if(!$r) {
|
||||||
|
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
|
||||||
|
}
|
||||||
|
$obj = json_decode($r[0]['obj'], true);
|
||||||
|
if(x($obj,'body')) {
|
||||||
|
$photolink = $obj['body'];
|
||||||
|
} elseif (x($obj,'bbcode')) {
|
||||||
|
$photolink = $obj['bbcode'];
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false));
|
||||||
|
}
|
||||||
|
json_return_and_die(array('status' => true, 'photolink' => $photolink));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copied from include/widgets.php::widget_album() with a modification to get the profile_uid from
|
||||||
|
* the input array as in widget_item()
|
||||||
|
* @param type $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function embedphotos_widget_album($args) {
|
||||||
|
|
||||||
|
$channel_id = 0;
|
||||||
|
if(array_key_exists('channel',$args))
|
||||||
|
$channel = $args['channel'];
|
||||||
|
$channel_id = intval($channel['channel_id']);
|
||||||
|
if(! $channel_id)
|
||||||
|
$channel_id = \App::$profile_uid;
|
||||||
|
if(! $channel_id)
|
||||||
|
return '';
|
||||||
|
$owner_uid = $channel_id;
|
||||||
|
require_once('include/security.php');
|
||||||
|
$sql_extra = permissions_sql($channel_id);
|
||||||
|
|
||||||
|
if(! perm_is_allowed($channel_id,get_observer_hash(),'view_storage'))
|
||||||
|
return '';
|
||||||
|
|
||||||
|
if($args['album'])
|
||||||
|
$album = $args['album'];
|
||||||
|
if($args['title'])
|
||||||
|
$title = $args['title'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This may return incorrect permissions if you have multiple directories of the same name.
|
||||||
|
* It is a limitation of the photo table using a name for a photo album instead of a folder hash
|
||||||
|
*/
|
||||||
|
|
||||||
|
if($album) {
|
||||||
|
$x = q("select hash from attach where filename = '%s' and uid = %d limit 1",
|
||||||
|
dbesc($album),
|
||||||
|
intval($owner_uid)
|
||||||
|
);
|
||||||
|
if($x) {
|
||||||
|
$y = attach_can_view_folder($owner_uid,get_observer_hash(),$x[0]['hash']);
|
||||||
|
if(! $y)
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = 'DESC';
|
||||||
|
|
||||||
|
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
|
||||||
|
(SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph
|
||||||
|
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
|
||||||
|
ORDER BY created $order",
|
||||||
|
intval($owner_uid),
|
||||||
|
dbesc($album),
|
||||||
|
intval(PHOTO_NORMAL),
|
||||||
|
intval(PHOTO_PROFILE)
|
||||||
|
);
|
||||||
|
|
||||||
|
$photos = array();
|
||||||
|
if(count($r)) {
|
||||||
|
$twist = 'rotright';
|
||||||
|
foreach($r as $rr) {
|
||||||
|
|
||||||
|
if($twist == 'rotright')
|
||||||
|
$twist = 'rotleft';
|
||||||
|
else
|
||||||
|
$twist = 'rotright';
|
||||||
|
|
||||||
|
$ext = $phototypes[$rr['mimetype']];
|
||||||
|
|
||||||
|
$imgalt_e = $rr['filename'];
|
||||||
|
$desc_e = $rr['description'];
|
||||||
|
|
||||||
|
$imagelink = (z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/image/' . $rr['resource_id']
|
||||||
|
. (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''));
|
||||||
|
|
||||||
|
$photos[] = array(
|
||||||
|
'id' => $rr['id'],
|
||||||
|
'twist' => ' ' . $twist . rand(2,4),
|
||||||
|
'link' => $imagelink,
|
||||||
|
'title' => t('View Photo'),
|
||||||
|
'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext,
|
||||||
|
'alt' => $imgalt_e,
|
||||||
|
'desc'=> $desc_e,
|
||||||
|
'ext' => $ext,
|
||||||
|
'hash'=> $rr['resource_id'],
|
||||||
|
'unknown' => t('Unknown')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tpl = get_markup_template('photo_album.tpl');
|
||||||
|
$o .= replace_macros($tpl, array(
|
||||||
|
'$photos' => $photos,
|
||||||
|
'$album' => (($title) ? $title : $album),
|
||||||
|
'$album_id' => rand(),
|
||||||
|
'$album_edit' => array(t('Edit Album'), $album_edit),
|
||||||
|
'$can_post' => false,
|
||||||
|
'$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)),
|
||||||
|
'$order' => false,
|
||||||
|
'$upload_form' => $upload_form,
|
||||||
|
'$usage' => $usage_message
|
||||||
|
));
|
||||||
|
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function embedphotos_album_list($a) {
|
||||||
|
$o = '';
|
||||||
|
require_once('include/photos.php');
|
||||||
|
$p = photos_albums_list(\App::get_channel(), \App::get_observer());
|
||||||
|
if ($p['success']) {
|
||||||
|
return $p['albums'];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -43,7 +43,7 @@ class Follow extends \Zotlabs\Web\Controller {
|
|||||||
unset($clone['abook_account']);
|
unset($clone['abook_account']);
|
||||||
unset($clone['abook_channel']);
|
unset($clone['abook_channel']);
|
||||||
|
|
||||||
$abconfig = load_abconfig($channel['channel_hash'],$clone['abook_xchan']);
|
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
|
||||||
if($abconfig)
|
if($abconfig)
|
||||||
$clone['abconfig'] = $abconfig;
|
$clone['abconfig'] = $abconfig;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class Hcard extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ class Id extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$profile = '';
|
$profile = '';
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
$op = new MysqlProvider;
|
$op = new MysqlProvider;
|
||||||
$op->server();
|
$op->server();
|
||||||
|
@ -137,9 +137,7 @@ class Impel extends \Zotlabs\Web\Controller {
|
|||||||
require_once('library/urlify/URLify.php');
|
require_once('library/urlify/URLify.php');
|
||||||
$pagetitle = strtolower(\URLify::transliterate($j['pagetitle']));
|
$pagetitle = strtolower(\URLify::transliterate($j['pagetitle']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Verify ability to use html or php!!!
|
// Verify ability to use html or php!!!
|
||||||
|
|
||||||
$execflag = false;
|
$execflag = false;
|
||||||
@ -154,21 +152,14 @@ class Impel extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$remote_id = 0;
|
|
||||||
|
|
||||||
$z = q("select * from item_id where sid = '%s' and service = '%s' and uid = %d limit 1",
|
|
||||||
dbesc($pagetitle),
|
|
||||||
dbesc($namespace),
|
|
||||||
intval(local_channel())
|
|
||||||
);
|
|
||||||
|
|
||||||
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
|
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
|
||||||
dbesc($arr['mid']),
|
dbesc($arr['mid']),
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
\Zotlabs\Lib\IConfig::Set($arr,'system',$namespace,(($pagetitle) ? $pagetitle : substr($arr['mid'],0,16)),true);
|
||||||
|
|
||||||
if($z && $i) {
|
if($i) {
|
||||||
$remote_id = $z[0]['id'];
|
|
||||||
$arr['id'] = $i[0]['id'];
|
$arr['id'] = $i[0]['id'];
|
||||||
// don't update if it has the same timestamp as the original
|
// don't update if it has the same timestamp as the original
|
||||||
if($arr['edited'] > $i[0]['edited'])
|
if($arr['edited'] > $i[0]['edited'])
|
||||||
@ -182,12 +173,12 @@ class Impel extends \Zotlabs\Web\Controller {
|
|||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$x = item_store($arr,$execflag);
|
else
|
||||||
|
$x = item_store($arr,$execflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($x['success']) {
|
if($x && $x['success']) {
|
||||||
$item_id = $x['item_id'];
|
$item_id = $x['item_id'];
|
||||||
update_remote_id($channel,$item_id,$arr['item_type'],$pagetitle,$namespace,$remote_id,$arr['mid']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +190,8 @@ class Impel extends \Zotlabs\Web\Controller {
|
|||||||
notice( sprintf( t('%s element installation failed'), $installed_type));
|
notice( sprintf( t('%s element installation failed'), $installed_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
//??? should perhaps return ret?
|
//??? should perhaps return ret?
|
||||||
|
|
||||||
json_return_and_die(true);
|
json_return_and_die(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,8 @@ class Import extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
// import channel
|
// import channel
|
||||||
|
|
||||||
|
$relocate = ((array_key_exists('relocate',$data)) ? $data['relocate'] : null);
|
||||||
|
|
||||||
if(array_key_exists('channel',$data)) {
|
if(array_key_exists('channel',$data)) {
|
||||||
|
|
||||||
if($completed < 1) {
|
if($completed < 1) {
|
||||||
@ -387,8 +389,7 @@ class Import extends \Zotlabs\Web\Controller {
|
|||||||
if($abconfig) {
|
if($abconfig) {
|
||||||
// @fixme does not handle sync of del_abconfig
|
// @fixme does not handle sync of del_abconfig
|
||||||
foreach($abconfig as $abc) {
|
foreach($abconfig as $abc) {
|
||||||
if($abc['chan'] === $channel['channel_hash'])
|
set_abconfig($channel['channel_id'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
|
||||||
set_abconfig($abc['chan'],$abc['xchan'],$abc['cat'],$abc['k'],$abc['v']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,7 +476,7 @@ class Import extends \Zotlabs\Web\Controller {
|
|||||||
import_events($channel,$data['event']);
|
import_events($channel,$data['event']);
|
||||||
|
|
||||||
if(is_array($data['event_item']))
|
if(is_array($data['event_item']))
|
||||||
import_items($channel,$data['event_item']);
|
import_items($channel,$data['event_item'],false,$relocate);
|
||||||
|
|
||||||
if(is_array($data['menu']))
|
if(is_array($data['menu']))
|
||||||
import_menus($channel,$data['menu']);
|
import_menus($channel,$data['menu']);
|
||||||
@ -486,7 +487,7 @@ class Import extends \Zotlabs\Web\Controller {
|
|||||||
$saved_notification_flags = notifications_off($channel['channel_id']);
|
$saved_notification_flags = notifications_off($channel['channel_id']);
|
||||||
|
|
||||||
if($import_posts && array_key_exists('item',$data) && $data['item'])
|
if($import_posts && array_key_exists('item',$data) && $data['item'])
|
||||||
import_items($channel,$data['item']);
|
import_items($channel,$data['item'],false,$relocate);
|
||||||
|
|
||||||
notifications_on($channel['channel_id'],$saved_notification_flags);
|
notifications_on($channel['channel_id'],$saved_notification_flags);
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class Import_items extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
|
|
||||||
if(array_key_exists('item',$data) && $data['item']) {
|
if(array_key_exists('item',$data) && $data['item']) {
|
||||||
import_items($channel,$data['item']);
|
import_items($channel,$data['item'],false,((array_key_exists('relocate',$data)) ? $data['relocate'] : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(array_key_exists('item_id',$data) && $data['item_id']) {
|
if(array_key_exists('item_id',$data) && $data['item_id']) {
|
||||||
@ -106,7 +106,7 @@ class Import_items extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
notice( t('Permission denied') . EOL);
|
notice( t('Permission denied') . EOL);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Zotlabs\Module;
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,7 +230,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if($namespace && $remote_id) {
|
if($namespace && $remote_id) {
|
||||||
// It wasn't an internally generated post - see if we've got an item matching this remote service id
|
// It wasn't an internally generated post - see if we've got an item matching this remote service id
|
||||||
$i = q("select iid from item_id where service = '%s' and sid = '%s' limit 1",
|
$i = q("select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1",
|
||||||
dbesc($namespace),
|
dbesc($namespace),
|
||||||
dbesc($remote_id)
|
dbesc($remote_id)
|
||||||
);
|
);
|
||||||
@ -880,13 +881,21 @@ class Item extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($webpage) {
|
||||||
|
Zlib\IConfig::Set($datarray,'system', webpage_to_namespace($webpage),
|
||||||
|
(($pagetitle) ? $pagetitle : substr($datarray['mid'],0,16)),true);
|
||||||
|
}
|
||||||
|
elseif($namespace) {
|
||||||
|
Zlib\IConfig::Set($datarray,'system', $namespace,
|
||||||
|
(($remote_id) ? $remote_id : substr($datarray['mid'],0,16)),true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if($orig_post) {
|
if($orig_post) {
|
||||||
$datarray['id'] = $post_id;
|
$datarray['id'] = $post_id;
|
||||||
|
|
||||||
item_store_update($datarray,$execflag);
|
$x = item_store_update($datarray,$execflag);
|
||||||
|
|
||||||
update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid);
|
|
||||||
|
|
||||||
if(! $parent) {
|
if(! $parent) {
|
||||||
$r = q("select * from item where id = %d",
|
$r = q("select * from item where id = %d",
|
||||||
intval($post_id)
|
intval($post_id)
|
||||||
@ -894,10 +903,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||||||
if($r) {
|
if($r) {
|
||||||
xchan_query($r);
|
xchan_query($r);
|
||||||
$sync_item = fetch_post_tags($r);
|
$sync_item = fetch_post_tags($r);
|
||||||
$rid = q("select * from item_id where iid = %d",
|
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||||
intval($post_id)
|
|
||||||
);
|
|
||||||
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(! $nopush)
|
if(! $nopush)
|
||||||
@ -978,10 +984,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||||||
goaway(z_root() . "/" . $return_path );
|
goaway(z_root() . "/" . $return_path );
|
||||||
// NOTREACHED
|
// NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid);
|
|
||||||
|
|
||||||
if(($parent) && ($parent != $post_id)) {
|
if(($parent) && ($parent != $post_id)) {
|
||||||
// Store the comment signature information in case we need to relay to Diaspora
|
// Store the comment signature information in case we need to relay to Diaspora
|
||||||
//$ditem = $datarray;
|
//$ditem = $datarray;
|
||||||
@ -995,10 +998,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||||||
if($r) {
|
if($r) {
|
||||||
xchan_query($r);
|
xchan_query($r);
|
||||||
$sync_item = fetch_post_tags($r);
|
$sync_item = fetch_post_tags($r);
|
||||||
$rid = q("select * from item_id where iid = %d",
|
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true))));
|
||||||
intval($post_id)
|
|
||||||
);
|
|
||||||
build_sync_packet($uid,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class Layouts extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_load($a,$which);
|
profile_load($which);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,13 +90,14 @@ class Layouts extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This feature is not exposed in redbasic ui since it is not clear why one would want to
|
// This feature is not exposed in redbasic ui since it is not clear why one would want to
|
||||||
//download a json encoded pdl file - we dont have a possibility to import it.
|
// download a json encoded pdl file - we dont have a possibility to import it.
|
||||||
//Use the buildin share/install feature instead.
|
// Use the buildin share/install feature instead.
|
||||||
|
|
||||||
if((argc() > 3) && (argv(2) === 'share') && (argv(3))) {
|
if((argc() > 3) && (argv(2) === 'share') && (argv(3))) {
|
||||||
$r = q("select sid, service, mimetype, title, body from item_id
|
$r = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig
|
||||||
left join item on item.id = item_id.iid
|
left join item on item.id = iconfig.iid
|
||||||
where item_id.uid = %d and item.mid = '%s' and service = 'PDL' order by sid asc",
|
where uid = %d and mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc",
|
||||||
intval($owner),
|
intval($owner),
|
||||||
dbesc(argv(3))
|
dbesc(argv(3))
|
||||||
);
|
);
|
||||||
@ -141,8 +142,9 @@ class Layouts extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$editor = status_editor($a,$x);
|
$editor = status_editor($a,$x);
|
||||||
|
|
||||||
$r = q("select iid, sid, mid, title, body, mimetype, created, edited, item_type from item_id left join item on item_id.iid = item.id
|
$r = q("select iconfig.iid, iconfig.v, mid, title, body, mimetype, created, edited, item_type from iconfig
|
||||||
where item_id.uid = %d and service = 'PDL' and item_type = %d order by item.created desc",
|
left join item on iconfig.iid = item.id
|
||||||
|
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d order by item.created desc",
|
||||||
intval($owner),
|
intval($owner),
|
||||||
intval(ITEM_TYPE_PDL)
|
intval(ITEM_TYPE_PDL)
|
||||||
);
|
);
|
||||||
@ -164,7 +166,7 @@ class Layouts extends \Zotlabs\Web\Controller {
|
|||||||
);
|
);
|
||||||
$pages[$rr['iid']][] = array(
|
$pages[$rr['iid']][] = array(
|
||||||
'url' => $rr['iid'],
|
'url' => $rr['iid'],
|
||||||
'title' => $rr['sid'],
|
'title' => $rr['v'],
|
||||||
'descr' => $rr['title'],
|
'descr' => $rr['title'],
|
||||||
'mid' => $rr['mid'],
|
'mid' => $rr['mid'],
|
||||||
'created' => $rr['created'],
|
'created' => $rr['created'],
|
||||||
|
@ -13,7 +13,7 @@ class Page extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$which = argv(1);
|
$which = argv(1);
|
||||||
$profile = 0;
|
$profile = 0;
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -65,9 +65,10 @@ class Page extends \Zotlabs\Web\Controller {
|
|||||||
require_once('include/security.php');
|
require_once('include/security.php');
|
||||||
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
$sql_options = item_permissions_sql($u[0]['channel_id']);
|
||||||
|
|
||||||
$r = q("select item.* from item left join item_id on item.id = item_id.iid
|
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||||
where item.uid = %d and sid = '%s' and item.item_delayed = 0 and (( service = 'WEBPAGE' and item_type = %d )
|
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||||
OR ( service = 'PDL' AND item_type = %d )) $sql_options $revision limit 1",
|
and (( iconfig.k = 'WEBPAGE' and item_type = %d )
|
||||||
|
OR ( iconfig.k = 'PDL' AND item_type = %d )) $sql_options $revision limit 1",
|
||||||
intval($u[0]['channel_id']),
|
intval($u[0]['channel_id']),
|
||||||
dbesc($page_id),
|
dbesc($page_id),
|
||||||
intval(ITEM_TYPE_WEBPAGE),
|
intval(ITEM_TYPE_WEBPAGE),
|
||||||
@ -77,9 +78,9 @@ class Page extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
// Check again with no permissions clause to see if it is a permissions issue
|
// Check again with no permissions clause to see if it is a permissions issue
|
||||||
|
|
||||||
$x = q("select item.* from item left join item_id on item.id = item_id.iid
|
$x = q("select item.* from item left join iconfig on item.id = iconfig.iid
|
||||||
where item.uid = %d and sid = '%s' and item.item_delayed = 0 and service = 'WEBPAGE' and
|
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' and item.item_delayed = 0
|
||||||
item_type = %d $revision limit 1",
|
and iconfig.k = 'WEBPAGE' and item_type = %d $revision limit 1",
|
||||||
intval($u[0]['channel_id']),
|
intval($u[0]['channel_id']),
|
||||||
dbesc($page_id),
|
dbesc($page_id),
|
||||||
intval(ITEM_TYPE_WEBPAGE)
|
intval(ITEM_TYPE_WEBPAGE)
|
||||||
@ -119,11 +120,8 @@ class Page extends \Zotlabs\Web\Controller {
|
|||||||
\App::$data['webpage'] = $r;
|
\App::$data['webpage'] = $r;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
|
||||||
|
|
||||||
$r = \App::$data['webpage'];
|
$r = \App::$data['webpage'];
|
||||||
if(! $r)
|
if(! $r)
|
||||||
|
@ -20,7 +20,7 @@ class Pdledit extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
notice( t('Permission denied.') . EOL);
|
notice( t('Permission denied.') . EOL);
|
||||||
@ -32,18 +32,18 @@ class Pdledit extends \Zotlabs\Web\Controller {
|
|||||||
else {
|
else {
|
||||||
$o .= '<div class="generic-content-wrapper-styled">';
|
$o .= '<div class="generic-content-wrapper-styled">';
|
||||||
$o .= '<h1>' . t('Edit System Page Description') . '</h1>';
|
$o .= '<h1>' . t('Edit System Page Description') . '</h1>';
|
||||||
$files = glob('mod/*');
|
$files = glob('Zotlabs/Module/*.php');
|
||||||
if($files) {
|
if($files) {
|
||||||
foreach($files as $f) {
|
foreach($files as $f) {
|
||||||
$name = basename($f,'.php');
|
$name = lcfirst(basename($f,'.php'));
|
||||||
$x = theme_include('mod_' . $name . '.pdl');
|
$x = theme_include('mod_' . $name . '.pdl');
|
||||||
if($x) {
|
if($x) {
|
||||||
$o .= '<a href="pdledit/' . $name . '" >' . $name . '</a><br />';
|
$o .= '<a href="pdledit/' . $name . '" >' . $name . '</a><br />';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$o .= '</div>';
|
$o .= '</div>';
|
||||||
|
|
||||||
// list module pdl files
|
// list module pdl files
|
||||||
return $o;
|
return $o;
|
||||||
|
@ -62,7 +62,7 @@ class Photo extends \Zotlabs\Web\Controller {
|
|||||||
intval($uid),
|
intval($uid),
|
||||||
intval(PHOTO_PROFILE)
|
intval(PHOTO_PROFILE)
|
||||||
);
|
);
|
||||||
if(count($r)) {
|
if($r) {
|
||||||
$data = dbunescbin($r[0]['content']);
|
$data = dbunescbin($r[0]['content']);
|
||||||
$mimetype = $r[0]['mimetype'];
|
$mimetype = $r[0]['mimetype'];
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ class Photo extends \Zotlabs\Web\Controller {
|
|||||||
* Other photos
|
* Other photos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Check for a cookie to indicate display pixel density, in order to detect high-resolution
|
/* Check for a cookie to indicate display pixel density, in order to detect high-resolution
|
||||||
displays. This procedure was derived from the "Retina Images" by Jeremey Worboys,
|
displays. This procedure was derived from the "Retina Images" by Jeremey Worboys,
|
||||||
used in accordance with the Creative Commons Attribution 3.0 Unported License.
|
used in accordance with the Creative Commons Attribution 3.0 Unported License.
|
||||||
Project link: https://github.com/Retina-Images/Retina-Images
|
Project link: https://github.com/Retina-Images/Retina-Images
|
||||||
|
@ -27,7 +27,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||||||
if(argc() > 1) {
|
if(argc() > 1) {
|
||||||
$nick = argv(1);
|
$nick = argv(1);
|
||||||
|
|
||||||
profile_load($a,$nick);
|
profile_load($nick);
|
||||||
|
|
||||||
$channelx = channelx_by_nick($nick);
|
$channelx = channelx_by_nick($nick);
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class Profile extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,19 +23,18 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
/* @brief Initalize the profile-photo edit view
|
/* @brief Initalize the profile-photo edit view
|
||||||
*
|
*
|
||||||
* @param $a Current application
|
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$channel = \App::get_channel();
|
$channel = \App::get_channel();
|
||||||
profile_load($a,$channel['channel_address']);
|
profile_load($channel['channel_address']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
if(! local_channel()) {
|
if(! local_channel()) {
|
||||||
return;
|
return;
|
||||||
@ -54,24 +53,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||||
|
|
||||||
if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) {
|
if((array_key_exists('postfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||||
|
|
||||||
// unless proven otherwise
|
|
||||||
$is_default_profile = 1;
|
|
||||||
|
|
||||||
if($_REQUEST['profile']) {
|
|
||||||
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
|
|
||||||
intval($_REQUEST['profile']),
|
|
||||||
intval(local_channel())
|
|
||||||
);
|
|
||||||
if($r) {
|
|
||||||
$profile = $r[0];
|
|
||||||
if(! intval($profile['is_default']))
|
|
||||||
$is_default_profile = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// phase 2 - we have finished cropping
|
// phase 2 - we have finished cropping
|
||||||
|
|
||||||
@ -86,7 +68,23 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
$scale = substr($image_id,-1,1);
|
$scale = substr($image_id,-1,1);
|
||||||
$image_id = substr($image_id,0,-2);
|
$image_id = substr($image_id,0,-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// unless proven otherwise
|
||||||
|
$is_default_profile = 1;
|
||||||
|
|
||||||
|
if($_REQUEST['profile']) {
|
||||||
|
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
|
||||||
|
intval($_REQUEST['profile']),
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
$profile = $r[0];
|
||||||
|
if(! intval($profile['is_default']))
|
||||||
|
$is_default_profile = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$srcX = $_POST['xstart'];
|
$srcX = $_POST['xstart'];
|
||||||
$srcY = $_POST['ystart'];
|
$srcY = $_POST['ystart'];
|
||||||
@ -110,30 +108,38 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$aid = get_account_id();
|
$aid = get_account_id();
|
||||||
|
|
||||||
$p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
|
$p = [
|
||||||
'filename' => $base_image['filename'], 'album' => t('Profile Photos'));
|
'aid' => $aid,
|
||||||
|
'uid' => local_channel(),
|
||||||
|
'resource_id' => $base_image['resource_id'],
|
||||||
|
'filename' => $base_image['filename'],
|
||||||
|
'album' => t('Profile Photos')
|
||||||
|
];
|
||||||
|
|
||||||
$p['imgscale'] = 4;
|
$p['imgscale'] = PHOTO_RES_PROFILE_300;
|
||||||
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
||||||
|
|
||||||
$r1 = $im->save($p);
|
$r1 = $im->save($p);
|
||||||
|
|
||||||
$im->scaleImage(80);
|
$im->scaleImage(80);
|
||||||
$p['imgscale'] = 5;
|
$p['imgscale'] = PHOTO_RES_PROFILE_80;
|
||||||
|
|
||||||
$r2 = $im->save($p);
|
$r2 = $im->save($p);
|
||||||
|
|
||||||
$im->scaleImage(48);
|
$im->scaleImage(48);
|
||||||
$p['imgscale'] = 6;
|
$p['imgscale'] = PHOTO_RES_PROFILE_48;
|
||||||
|
|
||||||
$r3 = $im->save($p);
|
$r3 = $im->save($p);
|
||||||
|
|
||||||
if($r1 === false || $r2 === false || $r3 === false) {
|
if($r1 === false || $r2 === false || $r3 === false) {
|
||||||
// if one failed, delete them all so we can start over.
|
// if one failed, delete them all so we can start over.
|
||||||
notice( t('Image resize failed.') . EOL );
|
notice( t('Image resize failed.') . EOL );
|
||||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 4 ",
|
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
|
||||||
dbesc($base_image['resource_id']),
|
dbesc($base_image['resource_id']),
|
||||||
local_channel()
|
local_channel(),
|
||||||
|
intval(PHOTO_RES_PROFILE_300),
|
||||||
|
intval(PHOTO_RES_PROFILE_80),
|
||||||
|
intval(PHOTO_RES_PROFILE_48)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -183,10 +189,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
// Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
|
// Now copy profile-permissions to pictures, to prevent privacyleaks by automatically created folder 'Profile Pictures'
|
||||||
|
|
||||||
profile_photo_set_profile_perms($_REQUEST['profile']);
|
profile_photo_set_profile_perms(local_channel(),$_REQUEST['profile']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
notice( t('Unable to process image') . EOL);
|
notice( t('Unable to process image') . EOL);
|
||||||
@ -196,7 +199,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
return; // NOTREACHED
|
return; // NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A new photo was uploaded. Store it and save some important details
|
||||||
|
// in App::$data for use in the cropping function
|
||||||
|
|
||||||
|
|
||||||
$hash = photo_new_resource();
|
$hash = photo_new_resource();
|
||||||
$smallest = 0;
|
$smallest = 0;
|
||||||
@ -220,7 +225,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
$os_storage = false;
|
$os_storage = false;
|
||||||
|
|
||||||
foreach($i as $ii) {
|
foreach($i as $ii) {
|
||||||
if(intval($ii['imgscale']) < 2) {
|
if(intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||||
$smallest = intval($ii['imgscale']);
|
$smallest = intval($ii['imgscale']);
|
||||||
$os_storage = intval($ii['os_storage']);
|
$os_storage = intval($ii['os_storage']);
|
||||||
$imagedata = $ii['content'];
|
$imagedata = $ii['content'];
|
||||||
@ -238,7 +243,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||||
|
|
||||||
|
// This will "fall through" to the get() method, and since
|
||||||
|
// App::$data['imagecrop'] is set, it will proceed to cropping
|
||||||
|
// rather than present the upload form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -269,11 +277,19 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
notice( t('Permission denied.') . EOL );
|
notice( t('Permission denied.') . EOL );
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
|
||||||
|
|
||||||
$resource_id = argv(2);
|
$resource_id = argv(2);
|
||||||
|
|
||||||
|
// When using an existing photo, we don't have a dialogue to offer a choice of profiles,
|
||||||
|
// so it gets attached to the default
|
||||||
|
|
||||||
|
$p = q("select id from profile where is_default = 1 and uid = %d",
|
||||||
|
intval(local_channel())
|
||||||
|
);
|
||||||
|
if($p) {
|
||||||
|
$_REQUEST['profile'] = $p[0]['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
|
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
|
||||||
intval(local_channel()),
|
intval(local_channel()),
|
||||||
@ -285,11 +301,11 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
$havescale = false;
|
$havescale = false;
|
||||||
foreach($r as $rr) {
|
foreach($r as $rr) {
|
||||||
if($rr['imgscale'] == 5)
|
if($rr['imgscale'] == PHOTO_RES_PROFILE_80)
|
||||||
$havescale = true;
|
$havescale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set an already loaded photo as profile photo
|
// set an already loaded and cropped photo as profile photo
|
||||||
|
|
||||||
if(($r[0]['album'] == t('Profile Photos')) && ($havescale)) {
|
if(($r[0]['album'] == t('Profile Photos')) && ($havescale)) {
|
||||||
// unset any existing profile photos
|
// unset any existing profile photos
|
||||||
@ -310,7 +326,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
dbesc($channel['xchan_hash'])
|
dbesc($channel['xchan_hash'])
|
||||||
);
|
);
|
||||||
|
|
||||||
profile_photo_set_profile_perms(); //Reset default photo permissions to public
|
profile_photo_set_profile_perms(local_channel()); // Reset default photo permissions to public
|
||||||
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
||||||
goaway(z_root() . '/profiles');
|
goaway(z_root() . '/profiles');
|
||||||
}
|
}
|
||||||
@ -342,17 +358,22 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
if($i) {
|
if($i) {
|
||||||
$hash = $i[0]['resource_id'];
|
$hash = $i[0]['resource_id'];
|
||||||
foreach($i as $ii) {
|
foreach($i as $ii) {
|
||||||
if(intval($ii['imgscale']) < 2) {
|
if(intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||||
$smallest = intval($ii['imgscale']);
|
$smallest = intval($ii['imgscale']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
$this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||||
|
|
||||||
|
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
|
||||||
}
|
}
|
||||||
|
|
||||||
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d",
|
|
||||||
|
// present an upload form
|
||||||
|
|
||||||
|
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
|
||||||
intval(local_channel())
|
intval(local_channel())
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -379,6 +400,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
// present a cropping form
|
||||||
|
|
||||||
$filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'];
|
$filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'];
|
||||||
$resolution = \App::$data['imagecrop_resolution'];
|
$resolution = \App::$data['imagecrop_resolution'];
|
||||||
$tpl = get_markup_template("cropbody.tpl");
|
$tpl = get_markup_template("cropbody.tpl");
|
||||||
@ -416,13 +440,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||||||
if($max_length > 0)
|
if($max_length > 0)
|
||||||
$ph->scaleImage($max_length);
|
$ph->scaleImage($max_length);
|
||||||
|
|
||||||
$width = $ph->getWidth();
|
\App::$data['width'] = $ph->getWidth();
|
||||||
$height = $ph->getHeight();
|
\App::$data['height'] = $ph->getHeight();
|
||||||
|
|
||||||
if($width < 500 || $height < 500) {
|
if(\App::$data['width'] < 500 || \App::$data['height'] < 500) {
|
||||||
$ph->scaleImageUp(400);
|
$ph->scaleImageUp(400);
|
||||||
$width = $ph->getWidth();
|
\App::$data['width'] = $ph->getWidth();
|
||||||
$height = $ph->getHeight();
|
\App::$data['height'] = $ph->getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$chan = \App::get_channel();
|
$chan = \App::get_channel();
|
||||||
|
|
||||||
profile_load($a,$chan['channel_address'],$r[0]['id']);
|
profile_load($chan['channel_address'],$r[0]['id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,7 +584,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
if($is_default) {
|
if($is_default) {
|
||||||
// reload the info for the sidebar widget - why does this not work?
|
// reload the info for the sidebar widget - why does this not work?
|
||||||
profile_load($a,$channel['channel_address']);
|
profile_load($channel['channel_address']);
|
||||||
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class Profperm extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$profile = \App::$argv[1];
|
$profile = \App::$argv[1];
|
||||||
|
|
||||||
profile_load($a,$which,$profile);
|
profile_load($which,$profile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ class Profperm extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
//Time to update the permissions on the profile-pictures as well
|
//Time to update the permissions on the profile-pictures as well
|
||||||
|
|
||||||
profile_photo_set_profile_perms($profile['id']);
|
profile_photo_set_profile_perms(local_channel(),$profile['id']);
|
||||||
|
|
||||||
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'",
|
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_profile = '%s'",
|
||||||
intval(local_channel()),
|
intval(local_channel()),
|
||||||
|
80
Zotlabs/Module/README.md
Normal file
80
Zotlabs/Module/README.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
Zotlabs/Module
|
||||||
|
==============
|
||||||
|
|
||||||
|
|
||||||
|
This directory contains controller modules for handling web requests. The
|
||||||
|
lowercase class name indicates the head of the URL path which this module
|
||||||
|
handles. There are other methods of attaching (routing) URL paths to
|
||||||
|
controllers, but this is the primary method used in this project.
|
||||||
|
|
||||||
|
Module controllers MUST reside in this directory and namespace to be
|
||||||
|
autoloaded (unless other specific routing methods are employed). They
|
||||||
|
typically use and extend the class definition in Zotlabs/Web/Controller
|
||||||
|
as a template.
|
||||||
|
|
||||||
|
Template:
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Web;
|
||||||
|
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
|
||||||
|
function init() {}
|
||||||
|
function post() {}
|
||||||
|
function get() {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Typical Module declaration for the '/foo' URL route:
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
class Foo extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
// init() handler goes here
|
||||||
|
}
|
||||||
|
|
||||||
|
function post() {
|
||||||
|
// post handler goes here
|
||||||
|
}
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
return 'Hello world.' . EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
This model provides callbacks for public functions named init(), post(),
|
||||||
|
and get(). init() is always called. post() is called if $_POST variables
|
||||||
|
are present, and get() is called if none of the prior functions terminated
|
||||||
|
the handler. The get() method typically retuns a string which represents
|
||||||
|
the contents of the content region of the resulting page. Modules which emit
|
||||||
|
json, xml or other machine-readable formats typically emit their contents
|
||||||
|
inside the init() function and call 'killme()' to terminate the Module.
|
||||||
|
|
||||||
|
Modules are passed the URL path as argc,argv arguments. For a path such as
|
||||||
|
|
||||||
|
https://mysite.something/foo/bar/baz
|
||||||
|
|
||||||
|
The app will typically invoke the Module class 'Foo' and pass it
|
||||||
|
|
||||||
|
$x = argc(); // $x = 3
|
||||||
|
|
||||||
|
$x = argv(0); // $x = 'foo'
|
||||||
|
$x = argv(1); // $x = 'bar'
|
||||||
|
$x = argv(2); // $x = 'baz'
|
||||||
|
|
||||||
|
These are handled in a similar fashion to their counterparts in the Unix shell
|
||||||
|
or C/C++ languages. Do not confuse the argc(),argv() functions with the
|
||||||
|
global variables $argc,$argv which are passed to command line programs. These
|
||||||
|
are handled separately by command line and Zotlabs/Daemon class functions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,7 +24,7 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function post() {
|
function post() {
|
||||||
|
|
||||||
$address = trim($_REQUEST['address']);
|
$address = trim($_REQUEST['address']);
|
||||||
|
|
||||||
@ -34,13 +34,13 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
require_once('library/openid/openid.php');
|
require_once('library/openid/openid.php');
|
||||||
$openid = new LightOpenID(z_root());
|
$openid = new \LightOpenID(z_root());
|
||||||
$openid->identity = $address;
|
$openid->identity = $address;
|
||||||
$openid->returnUrl = z_root() . '/openid';
|
$openid->returnUrl = z_root() . '/openid';
|
||||||
$openid->required = array('namePerson/friendly', 'namePerson');
|
$openid->required = array('namePerson/friendly', 'namePerson');
|
||||||
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
|
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
|
||||||
goaway($openid->authUrl());
|
goaway($openid->authUrl());
|
||||||
} catch (Exception $e) {
|
} catch (\Exception $e) {
|
||||||
notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'. t('The error message was:').' '.$e->getMessage());
|
notice( t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'. t('The error message was:').' '.$e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class Rmagic extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$o = replace_macros(get_markup_template('rmagic.tpl'),array(
|
$o = replace_macros(get_markup_template('rmagic.tpl'),array(
|
||||||
'$title' => t('Remote Authentication'),
|
'$title' => t('Remote Authentication'),
|
||||||
|
@ -27,28 +27,11 @@ class Siteinfo extends \Zotlabs\Web\Controller {
|
|||||||
else {
|
else {
|
||||||
$version = $commit = '';
|
$version = $commit = '';
|
||||||
}
|
}
|
||||||
$visible_plugins = array();
|
|
||||||
if(is_array(\App::$plugins) && count(\App::$plugins)) {
|
$plugins_list = implode(', ',visible_plugin_list());
|
||||||
$r = q("select * from addon where hidden = 0");
|
|
||||||
if(count($r))
|
if($plugins_list)
|
||||||
foreach($r as $rr)
|
$plugins_text = t('Installed plugins/addons/apps:');
|
||||||
$visible_plugins[] = $rr['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$plugins_list = '';
|
|
||||||
if(count($visible_plugins)) {
|
|
||||||
$plugins_text = t('Installed plugins/addons/apps:');
|
|
||||||
$sorted = $visible_plugins;
|
|
||||||
$s = '';
|
|
||||||
sort($sorted);
|
|
||||||
foreach($sorted as $p) {
|
|
||||||
if(strlen($p)) {
|
|
||||||
if(strlen($s)) $s .= ', ';
|
|
||||||
$s .= $p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$plugins_list .= $s;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
$plugins_text = t('No installed plugins/addons/apps');
|
$plugins_text = t('No installed plugins/addons/apps');
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class Thing extends \Zotlabs\Web\Controller {
|
|||||||
$verb = escape_tags($_REQUEST['verb']);
|
$verb = escape_tags($_REQUEST['verb']);
|
||||||
$activity = intval($_REQUEST['activity']);
|
$activity = intval($_REQUEST['activity']);
|
||||||
$profile_guid = escape_tags($_REQUEST['profile_assign']);
|
$profile_guid = escape_tags($_REQUEST['profile_assign']);
|
||||||
$url = $_REQUEST['link'];
|
$url = $_REQUEST['url'];
|
||||||
$photo = $_REQUEST['img'];
|
$photo = $_REQUEST['img'];
|
||||||
|
|
||||||
$hash = random_string();
|
$hash = random_string();
|
||||||
@ -235,7 +235,7 @@ class Thing extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
// @FIXME one problem with things is we can't share them unless we provide the channel in the url
|
// @FIXME one problem with things is we can't share them unless we provide the channel in the url
|
||||||
// so we can definitively lookup the owner.
|
// so we can definitively lookup the owner.
|
||||||
|
@ -44,7 +44,7 @@ class Uexport extends \Zotlabs\Web\Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
$y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
|
$y = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class Viewconnections extends \Zotlabs\Web\Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(argc() > 1)
|
if(argc() > 1)
|
||||||
profile_load($a,argv(1));
|
profile_load(argv(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
@ -23,12 +23,12 @@ class Webpages extends \Zotlabs\Web\Controller {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_load($a,$which);
|
profile_load($which);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
|
||||||
if(! \App::$profile) {
|
if(! \App::$profile) {
|
||||||
notice( t('Requested profile is not available.') . EOL );
|
notice( t('Requested profile is not available.') . EOL );
|
||||||
@ -138,11 +138,19 @@ class Webpages extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
$sql_extra = item_permissions_sql($owner);
|
$sql_extra = item_permissions_sql($owner);
|
||||||
|
|
||||||
$r = q("select * from item_id left join item on item_id.iid = item.id
|
|
||||||
where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
|
$r = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||||
|
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||||
|
$sql_extra order by item.created desc",
|
||||||
intval($owner),
|
intval($owner),
|
||||||
intval(ITEM_TYPE_WEBPAGE)
|
intval(ITEM_TYPE_WEBPAGE)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// $r = q("select * from item_id left join item on item_id.iid = item.id
|
||||||
|
// where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
|
||||||
|
// intval($owner),
|
||||||
|
// intval(ITEM_TYPE_WEBPAGE)
|
||||||
|
// );
|
||||||
|
|
||||||
$pages = null;
|
$pages = null;
|
||||||
|
|
||||||
@ -160,13 +168,13 @@ class Webpages extends \Zotlabs\Web\Controller {
|
|||||||
'created' => $rr['created'],
|
'created' => $rr['created'],
|
||||||
'edited' => $rr['edited'],
|
'edited' => $rr['edited'],
|
||||||
'mimetype' => $rr['mimetype'],
|
'mimetype' => $rr['mimetype'],
|
||||||
'pagetitle' => $rr['sid'],
|
'pagetitle' => $rr['v'],
|
||||||
'mid' => $rr['mid'],
|
'mid' => $rr['mid'],
|
||||||
'layout_mid' => $rr['layout_mid']
|
'layout_mid' => $rr['layout_mid']
|
||||||
);
|
);
|
||||||
$pages[$rr['iid']][] = array(
|
$pages[$rr['iid']][] = array(
|
||||||
'url' => $rr['iid'],
|
'url' => $rr['iid'],
|
||||||
'pagetitle' => $rr['sid'],
|
'pagetitle' => $rr['v'],
|
||||||
'title' => $rr['title'],
|
'title' => $rr['title'],
|
||||||
'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']),
|
'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']),
|
||||||
'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']),
|
'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']),
|
||||||
|
515
Zotlabs/Module/Wiki.php
Normal file
515
Zotlabs/Module/Wiki.php
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
<?php /** @file */
|
||||||
|
|
||||||
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
class Wiki extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
// Determine which channel's wikis to display to the observer
|
||||||
|
$nick = null;
|
||||||
|
if (argc() > 1)
|
||||||
|
$nick = argv(1); // if the channel name is in the URL, use that
|
||||||
|
if (!$nick && local_channel()) { // if no channel name was provided, assume the current logged in channel
|
||||||
|
$channel = \App::get_channel();
|
||||||
|
if ($channel && $channel['channel_address']) {
|
||||||
|
$nick = $channel['channel_address'];
|
||||||
|
goaway(z_root() . '/wiki/' . $nick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$nick) {
|
||||||
|
notice(t('You must be logged in to see this page.') . EOL);
|
||||||
|
goaway('/login');
|
||||||
|
}
|
||||||
|
profile_load($nick);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
require_once('include/wiki.php');
|
||||||
|
require_once('include/acl_selectors.php');
|
||||||
|
// TODO: Combine the interface configuration into a unified object
|
||||||
|
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
|
||||||
|
$wiki_owner = false;
|
||||||
|
$showNewWikiButton = false;
|
||||||
|
$showCommitMsg = false;
|
||||||
|
$hidePageHistory = false;
|
||||||
|
$pageHistory = array();
|
||||||
|
$local_observer = null;
|
||||||
|
$resource_id = '';
|
||||||
|
|
||||||
|
// init() should have forced the URL to redirect to /wiki/channel so assume argc() > 1
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick); // The channel who owns the wikis being viewed
|
||||||
|
if(! $channel) {
|
||||||
|
notice('Invalid channel' . EOL);
|
||||||
|
goaway('/' . argv(0));
|
||||||
|
}
|
||||||
|
// Determine if the observer is the channel owner so the ACL dialog can be populated
|
||||||
|
if (local_channel() === intval($channel['channel_id'])) {
|
||||||
|
$local_observer = \App::get_channel();
|
||||||
|
$wiki_owner = true;
|
||||||
|
|
||||||
|
// Obtain the default permission settings of the channel
|
||||||
|
$channel_acl = array(
|
||||||
|
'allow_cid' => $local_observer['channel_allow_cid'],
|
||||||
|
'allow_gid' => $local_observer['channel_allow_gid'],
|
||||||
|
'deny_cid' => $local_observer['channel_deny_cid'],
|
||||||
|
'deny_gid' => $local_observer['channel_deny_gid']
|
||||||
|
);
|
||||||
|
// Initialize the ACL to the channel default permissions
|
||||||
|
$x = array(
|
||||||
|
'lockstate' => (( $local_observer['channel_allow_cid'] ||
|
||||||
|
$local_observer['channel_allow_gid'] ||
|
||||||
|
$local_observer['channel_deny_cid'] ||
|
||||||
|
$local_observer['channel_deny_gid'])
|
||||||
|
? 'lock' : 'unlock'),
|
||||||
|
'acl' => populate_acl($channel_acl),
|
||||||
|
'bang' => ''
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Not the channel owner
|
||||||
|
$channel_acl = $x = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (argc()) {
|
||||||
|
case 2:
|
||||||
|
// Configure page template
|
||||||
|
$wikiheaderName = t('Wiki');
|
||||||
|
$wikiheaderPage = t('Sandbox');
|
||||||
|
require_once('library/markdown.php');
|
||||||
|
$content = t('"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."');
|
||||||
|
$renderedContent = Markdown(json_decode($content));
|
||||||
|
$hide_editor = false;
|
||||||
|
$showPageControls = false;
|
||||||
|
$showNewWikiButton = $wiki_owner;
|
||||||
|
$showNewPageButton = false;
|
||||||
|
$hidePageHistory = true;
|
||||||
|
$showCommitMsg = false;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// /wiki/channel/wiki -> No page was specified, so redirect to Home.md
|
||||||
|
$wikiUrlName = urlencode(argv(2));
|
||||||
|
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/Home');
|
||||||
|
case 4:
|
||||||
|
// GET /wiki/channel/wiki/page
|
||||||
|
// Fetch the wiki info and determine observer permissions
|
||||||
|
$wikiUrlName = urlencode(argv(2));
|
||||||
|
$pageUrlName = urlencode(argv(3));
|
||||||
|
$w = wiki_exists_by_name($channel['channel_id'], $wikiUrlName);
|
||||||
|
if(!$w['resource_id']) {
|
||||||
|
notice('Wiki not found' . EOL);
|
||||||
|
goaway('/'.argv(0).'/'.argv(1));
|
||||||
|
}
|
||||||
|
$resource_id = $w['resource_id'];
|
||||||
|
|
||||||
|
if (!$wiki_owner) {
|
||||||
|
// Check for observer permissions
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['read']) {
|
||||||
|
notice('Permission denied.' . EOL);
|
||||||
|
goaway('/'.argv(0).'/'.argv(1));
|
||||||
|
}
|
||||||
|
if($perms['write']) {
|
||||||
|
$wiki_editor = true;
|
||||||
|
} else {
|
||||||
|
$wiki_editor = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$wiki_editor = true;
|
||||||
|
}
|
||||||
|
$wikiheaderName = urldecode($wikiUrlName);
|
||||||
|
$wikiheaderPage = urldecode($pageUrlName);
|
||||||
|
$p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||||
|
if(!$p['success']) {
|
||||||
|
notice('Error retrieving page content' . EOL);
|
||||||
|
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
|
||||||
|
}
|
||||||
|
$content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"');
|
||||||
|
// Render the Markdown-formatted page content in HTML
|
||||||
|
require_once('library/markdown.php');
|
||||||
|
$renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName);
|
||||||
|
$hide_editor = false;
|
||||||
|
$showPageControls = $wiki_editor;
|
||||||
|
$showNewWikiButton = $wiki_owner;
|
||||||
|
$showNewPageButton = $wiki_editor;
|
||||||
|
$hidePageHistory = false;
|
||||||
|
$showCommitMsg = true;
|
||||||
|
$pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||||
|
break;
|
||||||
|
default: // Strip the extraneous URL components
|
||||||
|
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName);
|
||||||
|
}
|
||||||
|
|
||||||
|
$wikiModalID = random_string(3);
|
||||||
|
$wikiModal = replace_macros(
|
||||||
|
get_markup_template('generic_modal.tpl'), array(
|
||||||
|
'$id' => $wikiModalID,
|
||||||
|
'$title' => t('Revision Comparison'),
|
||||||
|
'$ok' => t('Revert'),
|
||||||
|
'$cancel' => t('Cancel')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
|
||||||
|
'$wikiheaderName' => $wikiheaderName,
|
||||||
|
'$wikiheaderPage' => $wikiheaderPage,
|
||||||
|
'$hideEditor' => $hide_editor,
|
||||||
|
'$showPageControls' => $showPageControls,
|
||||||
|
'$showNewWikiButton'=> $showNewWikiButton,
|
||||||
|
'$showNewPageButton'=> $showNewPageButton,
|
||||||
|
'$hidePageHistory' => $hidePageHistory,
|
||||||
|
'$showCommitMsg' => $showCommitMsg,
|
||||||
|
'$channel' => $channel['channel_address'],
|
||||||
|
'$resource_id' => $resource_id,
|
||||||
|
'$page' => $pageUrlName,
|
||||||
|
'$lockstate' => $x['lockstate'],
|
||||||
|
'$acl' => $x['acl'],
|
||||||
|
'$bang' => $x['bang'],
|
||||||
|
'$content' => $content,
|
||||||
|
'$renderedContent' => $renderedContent,
|
||||||
|
'$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''),
|
||||||
|
'$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''),
|
||||||
|
'$pageRename' => array('pageRename', t('Enter the new name:'), '', ''),
|
||||||
|
'$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'),
|
||||||
|
'$pageHistory' => $pageHistory['history'],
|
||||||
|
'$wikiModal' => $wikiModal,
|
||||||
|
'$wikiModalID' => $wikiModalID,
|
||||||
|
'$commit' => 'HEAD',
|
||||||
|
'$embedPhotos' => t('Embed image from photo albums'),
|
||||||
|
'$embedPhotosModalTitle' => t('Embed an image from your albums'),
|
||||||
|
'$embedPhotosModalCancel' => t('Cancel'),
|
||||||
|
'$embedPhotosModalOK' => t('OK'),
|
||||||
|
'$modalchooseimages' => t('Choose images to embed'),
|
||||||
|
'$modalchoosealbum' => t('Choose an album'),
|
||||||
|
'$modaldiffalbum' => t('Choose a different album...'),
|
||||||
|
'$modalerrorlist' => t('Error getting album list'),
|
||||||
|
'$modalerrorlink' => t('Error getting photo link'),
|
||||||
|
'$modalerroralbum' => t('Error getting album'),
|
||||||
|
));
|
||||||
|
head_add_js('library/ace/ace.js'); // Ace Code Editor
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
function post() {
|
||||||
|
require_once('include/wiki.php');
|
||||||
|
|
||||||
|
// /wiki/channel/preview
|
||||||
|
// Render mardown-formatted text in HTML for preview
|
||||||
|
if((argc() > 2) && (argv(2) === 'preview')) {
|
||||||
|
$content = $_POST['content'];
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
require_once('library/markdown.php');
|
||||||
|
$html = purify_html(Markdown($content));
|
||||||
|
$w = wiki_get_wiki($resource_id);
|
||||||
|
$wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName'];
|
||||||
|
$html = wiki_convert_links($html,$wikiURL);
|
||||||
|
json_return_and_die(array('html' => $html, 'success' => true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new wiki
|
||||||
|
// /wiki/channel/create/wiki
|
||||||
|
if ((argc() > 3) && (argv(2) === 'create') && (argv(3) === 'wiki')) {
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
// Determine if observer has permission to create wiki
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
// Only the channel owner can create a wiki, at least until we create a
|
||||||
|
// more detail permissions framework
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
goaway('/'.argv(0).'/'.$nick.'/');
|
||||||
|
}
|
||||||
|
$wiki = array();
|
||||||
|
// Generate new wiki info from input name
|
||||||
|
$wiki['postVisible'] = ((intval($_POST['postVisible']) === 0) ? 0 : 1);
|
||||||
|
$wiki['rawName'] = $_POST['wikiName'];
|
||||||
|
$wiki['htmlName'] = escape_tags($_POST['wikiName']);
|
||||||
|
$wiki['urlName'] = urlencode($_POST['wikiName']);
|
||||||
|
if($wiki['urlName'] === '') {
|
||||||
|
notice('Error creating wiki. Invalid name.');
|
||||||
|
goaway('/wiki');
|
||||||
|
}
|
||||||
|
// Get ACL for permissions
|
||||||
|
$acl = new \Zotlabs\Access\AccessList($channel);
|
||||||
|
$acl->set_from_array($_POST);
|
||||||
|
$r = wiki_create_wiki($channel, $observer_hash, $wiki, $acl);
|
||||||
|
if ($r['success']) {
|
||||||
|
$homePage = wiki_create_page('Home', $r['item']['resource_id']);
|
||||||
|
if(!$homePage['success']) {
|
||||||
|
notice('Wiki created, but error creating Home page.');
|
||||||
|
goaway('/wiki/'.$nick.'/'.$wiki['urlName']);
|
||||||
|
}
|
||||||
|
goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['page']['urlName']);
|
||||||
|
} else {
|
||||||
|
notice('Error creating wiki');
|
||||||
|
goaway('/wiki');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a wiki
|
||||||
|
if ((argc() > 3) && (argv(2) === 'delete') && (argv(3) === 'wiki')) {
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
// Only the channel owner can delete a wiki, at least until we create a
|
||||||
|
// more detail permissions framework
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
logger('Wiki delete permission denied.' . EOL);
|
||||||
|
json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
|
||||||
|
}
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$deleted = wiki_delete_wiki($resource_id);
|
||||||
|
if ($deleted['success']) {
|
||||||
|
json_return_and_die(array('message' => '', 'success' => true));
|
||||||
|
} else {
|
||||||
|
logger('Error deleting wiki: ' . $resource_id);
|
||||||
|
json_return_and_die(array('message' => 'Error deleting wiki', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a page
|
||||||
|
if ((argc() === 4) && (argv(2) === 'create') && (argv(3) === 'page')) {
|
||||||
|
$nick = argv(1);
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
// Determine if observer has permission to create a page
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['write']) {
|
||||||
|
logger('Wiki write permission denied. ' . EOL);
|
||||||
|
json_return_and_die(array('success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$name = $_POST['name']; //Get new page name
|
||||||
|
if(urlencode(escape_tags($_POST['name'])) === '') {
|
||||||
|
json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false));
|
||||||
|
}
|
||||||
|
$page = wiki_create_page($name, $resource_id);
|
||||||
|
if ($page['success']) {
|
||||||
|
json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']), 'success' => true));
|
||||||
|
} else {
|
||||||
|
logger('Error creating page');
|
||||||
|
json_return_and_die(array('message' => 'Error creating page.', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch page list for a wiki
|
||||||
|
if ((argc() === 5) && (argv(2) === 'get') && (argv(3) === 'page') && (argv(4) === 'list')) {
|
||||||
|
$resource_id = $_POST['resource_id']; // resource_id for wiki in db
|
||||||
|
$channel = get_channel_by_nick(argv(1));
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['read']) {
|
||||||
|
logger('Wiki read permission denied.' . EOL);
|
||||||
|
json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$page_list_html = widget_wiki_pages(array(
|
||||||
|
'resource_id' => $resource_id,
|
||||||
|
'refresh' => true,
|
||||||
|
'channel' => argv(1)));
|
||||||
|
json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save a page
|
||||||
|
if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) {
|
||||||
|
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$pageUrlName = $_POST['name'];
|
||||||
|
$pageHtmlName = escape_tags($_POST['name']);
|
||||||
|
$content = $_POST['content']; //Get new content
|
||||||
|
$commitMsg = $_POST['commitMsg'];
|
||||||
|
if ($commitMsg === '') {
|
||||||
|
$commitMsg = 'Updated ' . $pageHtmlName;
|
||||||
|
}
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
// Determine if observer has permission to save content
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['write']) {
|
||||||
|
logger('Wiki write permission denied. ' . EOL);
|
||||||
|
json_return_and_die(array('success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
|
||||||
|
if($saved['success']) {
|
||||||
|
$ob = \App::get_observer();
|
||||||
|
$commit = wiki_git_commit(array(
|
||||||
|
'commit_msg' => $commitMsg,
|
||||||
|
'resource_id' => $resource_id,
|
||||||
|
'observer' => $ob,
|
||||||
|
'files' => array($pageUrlName.'.md')
|
||||||
|
));
|
||||||
|
if($commit['success']) {
|
||||||
|
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('message' => 'Error making git commit','success' => false));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('message' => 'Error saving page', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update page history
|
||||||
|
// /wiki/channel/history/page
|
||||||
|
if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) {
|
||||||
|
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$pageUrlName = $_POST['name'];
|
||||||
|
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
// Determine if observer has permission to read content
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['read']) {
|
||||||
|
logger('Wiki read permission denied.' . EOL);
|
||||||
|
json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$historyHTML = widget_wiki_page_history(array(
|
||||||
|
'resource_id' => $resource_id,
|
||||||
|
'pageUrlName' => $pageUrlName
|
||||||
|
));
|
||||||
|
json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a page
|
||||||
|
if ((argc() === 4) && (argv(2) === 'delete') && (argv(3) === 'page')) {
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$pageUrlName = $_POST['name'];
|
||||||
|
if ($pageUrlName === 'Home') {
|
||||||
|
json_return_and_die(array('message' => 'Cannot delete Home','success' => false));
|
||||||
|
}
|
||||||
|
// Determine if observer has permission to delete pages
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['write']) {
|
||||||
|
logger('Wiki write permission denied. ' . EOL);
|
||||||
|
json_return_and_die(array('success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$deleted = wiki_delete_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||||
|
if($deleted['success']) {
|
||||||
|
$ob = \App::get_observer();
|
||||||
|
$commit = wiki_git_commit(array(
|
||||||
|
'commit_msg' => 'Deleted ' . $pageUrlName,
|
||||||
|
'resource_id' => $resource_id,
|
||||||
|
'observer' => $ob,
|
||||||
|
'files' => null
|
||||||
|
));
|
||||||
|
if($commit['success']) {
|
||||||
|
json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('message' => 'Error making git commit','success' => false));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('message' => 'Error deleting page', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Revert a page
|
||||||
|
if ((argc() === 4) && (argv(2) === 'revert') && (argv(3) === 'page')) {
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$pageUrlName = $_POST['name'];
|
||||||
|
$commitHash = $_POST['commitHash'];
|
||||||
|
// Determine if observer has permission to revert pages
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['write']) {
|
||||||
|
logger('Wiki write permission denied.' . EOL);
|
||||||
|
json_return_and_die(array('success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||||
|
if($reverted['success']) {
|
||||||
|
json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('content' => '', 'message' => 'Error reverting page', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare page revisions
|
||||||
|
if ((argc() === 4) && (argv(2) === 'compare') && (argv(3) === 'page')) {
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$pageUrlName = $_POST['name'];
|
||||||
|
$compareCommit = $_POST['compareCommit'];
|
||||||
|
$currentCommit = $_POST['currentCommit'];
|
||||||
|
// Determine if observer has permission to revert pages
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['read']) {
|
||||||
|
logger('Wiki read permission denied.' . EOL);
|
||||||
|
json_return_and_die(array('success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||||
|
if($compare['success']) {
|
||||||
|
$diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">Current Revision</td><td class="lead" width="50%">Selected Revision</td></tr></table>' . $compare['diff'];
|
||||||
|
json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename a page
|
||||||
|
if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) {
|
||||||
|
$resource_id = $_POST['resource_id'];
|
||||||
|
$pageUrlName = $_POST['oldName'];
|
||||||
|
$pageNewName = $_POST['newName'];
|
||||||
|
if ($pageUrlName === 'Home') {
|
||||||
|
json_return_and_die(array('message' => 'Cannot rename Home','success' => false));
|
||||||
|
}
|
||||||
|
if(urlencode(escape_tags($pageNewName)) === '') {
|
||||||
|
json_return_and_die(array('message' => 'Error renaming page. Invalid name.', 'success' => false));
|
||||||
|
}
|
||||||
|
// Determine if observer has permission to rename pages
|
||||||
|
$nick = argv(1);
|
||||||
|
$channel = get_channel_by_nick($nick);
|
||||||
|
if (local_channel() !== intval($channel['channel_id'])) {
|
||||||
|
$observer_hash = get_observer_hash();
|
||||||
|
$perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
|
||||||
|
if(!$perms['write']) {
|
||||||
|
logger('Wiki write permission denied. ' . EOL);
|
||||||
|
json_return_and_die(array('success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
|
||||||
|
if($renamed['success']) {
|
||||||
|
$ob = \App::get_observer();
|
||||||
|
$commit = wiki_git_commit(array(
|
||||||
|
'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'],
|
||||||
|
'resource_id' => $resource_id,
|
||||||
|
'observer' => $ob,
|
||||||
|
'files' => array($pageUrlName . '.md', $renamed['page']['fileName']),
|
||||||
|
'all' => true
|
||||||
|
));
|
||||||
|
if($commit['success']) {
|
||||||
|
json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('message' => 'Error making git commit','success' => false));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//notice('You must be authenticated.');
|
||||||
|
json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -179,7 +179,8 @@ class Comanche {
|
|||||||
$channel_id = $this->get_channel_id();
|
$channel_id = $this->get_channel_id();
|
||||||
|
|
||||||
if($channel_id) {
|
if($channel_id) {
|
||||||
$r = q("select * from item inner join item_id on iid = item.id and item_id.uid = item.uid and item.uid = %d and service = 'BUILDBLOCK' and sid = '%s' limit 1",
|
$r = q("select * from item inner join iconfig on iconfig.iid = item.id and item.uid = %d
|
||||||
|
and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK' and iconfig.v = '%s' limit 1",
|
||||||
intval($channel_id),
|
intval($channel_id),
|
||||||
dbesc($name)
|
dbesc($name)
|
||||||
);
|
);
|
||||||
@ -282,12 +283,12 @@ class Comanche {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widgets will have to get any operational arguments from the session, the
|
* Render a widget
|
||||||
* global app environment, or config storage until we implement argument passing
|
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $text
|
* @param string $text
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function widget($name, $text) {
|
function widget($name, $text) {
|
||||||
$vars = array();
|
$vars = array();
|
||||||
$matches = array();
|
$matches = array();
|
||||||
@ -314,7 +315,7 @@ class Comanche {
|
|||||||
require_once(theme_include($theme_widget));
|
require_once(theme_include($theme_widget));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function_exists($func))
|
if(function_exists($func))
|
||||||
return $func($vars);
|
return $func($vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
namespace Zotlabs\Storage;
|
namespace Zotlabs\Storage;
|
||||||
|
|
||||||
use Sabre\DAV;
|
use Sabre\DAV;
|
||||||
|
use Sabre\HTTP\RequestInterface;
|
||||||
|
use Sabre\HTTP\ResponseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Authentication backend class for DAV.
|
* @brief Authentication backend class for DAV.
|
||||||
@ -145,6 +147,57 @@ class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When this method is called, the backend must check if authentication was
|
||||||
|
* successful.
|
||||||
|
*
|
||||||
|
* The returned value must be one of the following
|
||||||
|
*
|
||||||
|
* [true, "principals/username"]
|
||||||
|
* [false, "reason for failure"]
|
||||||
|
*
|
||||||
|
* If authentication was successful, it's expected that the authentication
|
||||||
|
* backend returns a so-called principal url.
|
||||||
|
*
|
||||||
|
* Examples of a principal url:
|
||||||
|
*
|
||||||
|
* principals/admin
|
||||||
|
* principals/user1
|
||||||
|
* principals/users/joe
|
||||||
|
* principals/uid/123457
|
||||||
|
*
|
||||||
|
* If you don't use WebDAV ACL (RFC3744) we recommend that you simply
|
||||||
|
* return a string such as:
|
||||||
|
*
|
||||||
|
* principals/users/[username]
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function check(RequestInterface $request, ResponseInterface $response) {
|
||||||
|
|
||||||
|
if(local_channel()) {
|
||||||
|
return [ true, $this->principalPrefix . $this->channel_name ];
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth = new \Sabre\HTTP\Auth\Basic(
|
||||||
|
$this->realm,
|
||||||
|
$request,
|
||||||
|
$response
|
||||||
|
);
|
||||||
|
|
||||||
|
$userpass = $auth->getCredentials();
|
||||||
|
if (!$userpass) {
|
||||||
|
return [false, "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured"];
|
||||||
|
}
|
||||||
|
if (!$this->validateUserPass($userpass[0], $userpass[1])) {
|
||||||
|
return [false, "Username or password was incorrect"];
|
||||||
|
}
|
||||||
|
return [true, $this->principalPrefix . $userpass[0]];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected function check_module_access($channel_id) {
|
protected function check_module_access($channel_id) {
|
||||||
if($channel_id && \App::$module === 'cdav') {
|
if($channel_id && \App::$module === 'cdav') {
|
||||||
$x = get_pconfig($channel_id,'cdav','enabled');
|
$x = get_pconfig($channel_id,'cdav','enabled');
|
||||||
|
738
Zotlabs/Storage/CalDAVClient.php
Normal file
738
Zotlabs/Storage/CalDAVClient.php
Normal file
@ -0,0 +1,738 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Storage;
|
||||||
|
|
||||||
|
// The Hubzilla CalDAV client will store calendar information in the 'cal' DB table.
|
||||||
|
// Event information will remain in the 'event' table. In order to implement CalDAV on top of our
|
||||||
|
// existing system, there is an event table column called vdata. This will hold the "one true record"
|
||||||
|
// of the event in VCALENDAR format. When we receive a foreign event, we will pick out the fields
|
||||||
|
// of this entry that are important to us and use it to populate the other event table fields.
|
||||||
|
// When we make an event change, it is required that we load this entry as a vobject, make the changes on the
|
||||||
|
// vobject, and then store the result back in event.vdata. This will preserve foreign keys which we
|
||||||
|
// know nothing about. Then we sync this back to the DAV server.
|
||||||
|
|
||||||
|
// We still need a DB update to create a 'cal' table entry for our existing events and link these together.
|
||||||
|
// I'm currently anticipating separating tasks/to-do items from events, so each new account wil get two default calendars.
|
||||||
|
|
||||||
|
// We will eventually provide for magic-auth or cookie login of the CURL process so we won't be required to
|
||||||
|
// store our hubzilla password. Currently for testing we are using HTTP BASIC-AUTH and must initialise the
|
||||||
|
// username/password correctly to make the connection.
|
||||||
|
|
||||||
|
// Repeating events will be awkward because every instance has the same UUID. This would make it difficult to
|
||||||
|
// search for upcoming events if the initial instance was created (for instance) a few years ago. So the current plan is
|
||||||
|
// to create event instances for a prescribed time limit from now (perhaps 5-10 years for annual events).
|
||||||
|
// This plan may change. The repurcussions of this decision mean that an edit to a recurring event must
|
||||||
|
// edit all existing instances of the event, and only one unique instance can be used for sync.
|
||||||
|
// Sabre vobject provides a function to automatically expand recurring events into individual event instances.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CalDAVClient {
|
||||||
|
|
||||||
|
private $username;
|
||||||
|
private $password;
|
||||||
|
|
||||||
|
private $url;
|
||||||
|
|
||||||
|
public $filepos = 0;
|
||||||
|
public $request_data = '';
|
||||||
|
|
||||||
|
function __construct($user,$pass,$url) {
|
||||||
|
$this->username = $user;
|
||||||
|
$this->password = $pass;
|
||||||
|
$this->url = $url;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_data($s) {
|
||||||
|
$this->request_data = $s;
|
||||||
|
$this->filepos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function curl_read($ch,$fh,$size) {
|
||||||
|
|
||||||
|
if($this->filepos < 0) {
|
||||||
|
unset($fh);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$s = substr($this->request_data,$this->filepos,$size);
|
||||||
|
|
||||||
|
if(strlen($s) < $size)
|
||||||
|
$this->filepos = (-1);
|
||||||
|
else
|
||||||
|
$this->filepos = $this->filepos + $size;
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ctag_fetch() {
|
||||||
|
$headers = [ 'Depth: 0', 'Prefer: return-minimal', 'Content-Type: application/xml; charset=utf-8'];
|
||||||
|
|
||||||
|
// recommended ctag fetch by sabre
|
||||||
|
|
||||||
|
$this->set_data('<?xml version="1.0"?>
|
||||||
|
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:prop>
|
||||||
|
<d:displayname />
|
||||||
|
<cs:getctag />
|
||||||
|
<d:sync-token />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>');
|
||||||
|
|
||||||
|
// thunderbird uses this - it's a bit more verbose on what capabilities
|
||||||
|
// are provided by the server
|
||||||
|
|
||||||
|
$this->set_data('<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<D:propfind xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<D:prop>
|
||||||
|
<D:resourcetype/>
|
||||||
|
<D:owner/>
|
||||||
|
<D:current-user-principal/>
|
||||||
|
<D:supported-report-set/>
|
||||||
|
<C:supported-calendar-component-set/>
|
||||||
|
<CS:getctag/>
|
||||||
|
</D:prop>
|
||||||
|
</D:propfind>');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$auth = $this->username . ':' . $this->password;
|
||||||
|
|
||||||
|
$recurse = 0;
|
||||||
|
|
||||||
|
$x = z_fetch_url($this->url,true,$recurse,
|
||||||
|
[ 'headers' => $headers,
|
||||||
|
'http_auth' => $auth,
|
||||||
|
'custom' => 'PROPFIND',
|
||||||
|
'upload' => true,
|
||||||
|
'infile' => 3,
|
||||||
|
'infilesize' => strlen($this->request_data),
|
||||||
|
'readfunc' => [ $this, 'curl_read' ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function detail_fetch() {
|
||||||
|
$headers = [ 'Depth: 1', 'Prefer: return-minimal', 'Content-Type: application/xml; charset=utf-8'];
|
||||||
|
|
||||||
|
// this query should return all objects in the given calendar, you can filter it appropriately
|
||||||
|
// using filter options
|
||||||
|
|
||||||
|
$this->set_data('<?xml version="1.0"?>
|
||||||
|
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag />
|
||||||
|
<c:calendar-data />
|
||||||
|
</d:prop>
|
||||||
|
<c:filter>
|
||||||
|
<c:comp-filter name="VCALENDAR" />
|
||||||
|
</c:filter>
|
||||||
|
</c:calendar-query>');
|
||||||
|
|
||||||
|
$auth = $this->username . ':' . $this->password;
|
||||||
|
|
||||||
|
$recurse = 0;
|
||||||
|
$x = z_fetch_url($this->url,true,$recurse,
|
||||||
|
[ 'headers' => $headers,
|
||||||
|
'http_auth' => $auth,
|
||||||
|
'custom' => 'REPORT',
|
||||||
|
'upload' => true,
|
||||||
|
'infile' => 3,
|
||||||
|
'infilesize' => strlen($this->request_data),
|
||||||
|
'readfunc' => [ $this, 'curl_read' ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
PROPFIND /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Depth: 0
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:prop>
|
||||||
|
<d:displayname />
|
||||||
|
<cs:getctag />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>
|
||||||
|
|
||||||
|
// Responses: success
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:displayname>Home calendar</d:displayname>
|
||||||
|
<cs:getctag>3145</cs:getctag>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
// Responses: fail
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:displayname />
|
||||||
|
<cs:getctag />
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 403 Forbidden</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
|
||||||
|
// sample request body in DOM
|
||||||
|
// prepare request body
|
||||||
|
$doc = new DOMDocument('1.0', 'utf-8');
|
||||||
|
$doc->formatOutput = true;
|
||||||
|
|
||||||
|
$query = $doc->createElement('c:calendar-query');
|
||||||
|
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:c', 'urn:ietf:params:xml:ns:caldav');
|
||||||
|
$query->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:d', 'DAV:');
|
||||||
|
|
||||||
|
$prop = $doc->createElement('d:prop');
|
||||||
|
$prop->appendChild($doc->createElement('d:getetag'));
|
||||||
|
$prop->appendChild($doc->createElement('c:calendar-data'));
|
||||||
|
$query->appendChild($prop);
|
||||||
|
$doc->appendChild($query);
|
||||||
|
$body = $doc->saveXML();
|
||||||
|
|
||||||
|
echo "Body: " . $body . "<br>";
|
||||||
|
|
||||||
|
|
||||||
|
Now we download every single object in this calendar. To do this, we use a REPORT method.
|
||||||
|
|
||||||
|
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Depth: 1
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag />
|
||||||
|
<c:calendar-data />
|
||||||
|
</d:prop>
|
||||||
|
<c:filter>
|
||||||
|
<c:comp-filter name="VCALENDAR" />
|
||||||
|
</c:filter>
|
||||||
|
</c:calendar-query>
|
||||||
|
|
||||||
|
This request will give us every object that's a VCALENDAR object, and its etag.
|
||||||
|
|
||||||
|
If you're only interested in VTODO (because you're writing a todo app) you can also filter for just those:
|
||||||
|
|
||||||
|
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Depth: 1
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag />
|
||||||
|
<c:calendar-data />
|
||||||
|
</d:prop>
|
||||||
|
<c:filter>
|
||||||
|
<c:comp-filter name="VCALENDAR">
|
||||||
|
<c:comp-filter name="VTODO" />
|
||||||
|
</c:comp-filter>
|
||||||
|
</c:filter>
|
||||||
|
</c:calendar-query>
|
||||||
|
|
||||||
|
Similarly it's also possible to filter to just events, or only get events within a specific time-range.
|
||||||
|
|
||||||
|
This report will return a multi-status object again:
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>"2134-314"</d:getetag>
|
||||||
|
<c:calendar-data>BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
CALSCALE:GREGORIAN
|
||||||
|
BEGIN:VTODO
|
||||||
|
UID:132456762153245
|
||||||
|
SUMMARY:Do the dishes
|
||||||
|
DUE:20121028T115600Z
|
||||||
|
END:VTODO
|
||||||
|
END:VCALENDAR
|
||||||
|
</c:calendar-data>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/132456-34365.ics</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>"5467-323"</d:getetag>
|
||||||
|
<c:calendar-data>BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
CALSCALE:GREGORIAN
|
||||||
|
BEGIN:VEVENT
|
||||||
|
UID:132456-34365
|
||||||
|
SUMMARY:Weekly meeting
|
||||||
|
DTSTART:20120101T120000
|
||||||
|
DURATION:PT1H
|
||||||
|
RRULE:FREQ=WEEKLY
|
||||||
|
END:VEVENT
|
||||||
|
END:VCALENDAR
|
||||||
|
</c:calendar-data>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
This calendar only contained 2 objects. A todo and a weekly event.
|
||||||
|
|
||||||
|
So after you retrieved and processed these, for each object you must retain:
|
||||||
|
|
||||||
|
The calendar data itself
|
||||||
|
The url
|
||||||
|
The etag
|
||||||
|
|
||||||
|
In this case all urls ended with .ics. This is often the case, but you must not rely on this. In this case the UID in the calendar object was also identical to a part of the url. This too is often the case, but again not something you can rely on, so don't make any assumptions.
|
||||||
|
|
||||||
|
The url and the UID have no meaningful relationship, so treat both those items as separate unique identifiers.
|
||||||
|
Finding out if anything changed
|
||||||
|
|
||||||
|
To see if anything in a calendar changed, we simply request the ctag again on the calendar. If the ctag did not change, you still have the latest copy.
|
||||||
|
|
||||||
|
If it did change, you must request all the etags in the entire calendar again:
|
||||||
|
|
||||||
|
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Depth: 1
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag />
|
||||||
|
</d:prop>
|
||||||
|
<c:filter>
|
||||||
|
<c:comp-filter name="VCALENDAR">
|
||||||
|
<c:comp-filter name="VTODO" />
|
||||||
|
</c:comp-filter>
|
||||||
|
</c:filter>
|
||||||
|
</c:calendar-query>
|
||||||
|
|
||||||
|
Note that this last request is extremely similar to a previous one, but we are only asking fo the etag, not the calendar-data.
|
||||||
|
|
||||||
|
The reason for this, is that calendars can be rather huge. It will save a TON of bandwidth to only check the etag first.
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>"xxxx-xxx"</d:getetag>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>"5-12"</d:getetag>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
Judging from this last request, 3 things have changed:
|
||||||
|
|
||||||
|
The etag for the task has changed, so the contents must be different
|
||||||
|
There's a new url, some other client must have added an object
|
||||||
|
One object is missing, something must have deleted it.
|
||||||
|
|
||||||
|
So based on those 3 items we know that we need to delete an object from our local list, and fetch the contents for the new item, and the updated one.
|
||||||
|
|
||||||
|
To fetch the data for these, you can simply issue GET requests:
|
||||||
|
|
||||||
|
GET /calendars/johndoe/home/132456762153245.ics HTTP/1.1
|
||||||
|
|
||||||
|
But, because in a worst-case scenario this could result in a LOT of GET requests we can do a 'multiget'.
|
||||||
|
|
||||||
|
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Depth: 1
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<c:calendar-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag />
|
||||||
|
<c:calendar-data />
|
||||||
|
</d:prop>
|
||||||
|
<d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
|
||||||
|
<d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
|
||||||
|
</c:calendar-multiget>
|
||||||
|
|
||||||
|
This request will simply return a multi-status again with the calendar-data and etag.
|
||||||
|
A small note about application design
|
||||||
|
|
||||||
|
If you read this far and understood what's been said, you may have realized that it's a bit cumbersome to have a separate step for the initial sync, and subsequent updates.
|
||||||
|
|
||||||
|
It would totally be possible to skip the 'initial sync', and just use calendar-query and calendar-multiget REPORTS for the initial sync as well.
|
||||||
|
Updating a calendar object
|
||||||
|
|
||||||
|
Updating a calendar object is rather simple:
|
||||||
|
|
||||||
|
PUT /calendars/johndoe/home/132456762153245.ics HTTP/1.1
|
||||||
|
Content-Type: text/calendar; charset=utf-8
|
||||||
|
If-Match: "2134-314"
|
||||||
|
|
||||||
|
BEGIN:VCALENDAR
|
||||||
|
....
|
||||||
|
END:VCALENDAR
|
||||||
|
|
||||||
|
A response to this will be something like this:
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
ETag: "2134-315"
|
||||||
|
|
||||||
|
The update gave us back the new ETag. SabreDAV gives this ETag on updates back most of the time, but not always.
|
||||||
|
|
||||||
|
There are cases where the caldav server must modify the iCalendar object right after storage. In those cases an ETag will not be returned, and you should issue a GET request immediately to get the correct object.
|
||||||
|
|
||||||
|
A few notes:
|
||||||
|
|
||||||
|
You must not change the UID of the original object
|
||||||
|
Every object should hold only 1 event or task.
|
||||||
|
You cannot change an VEVENT into a VTODO.
|
||||||
|
|
||||||
|
Creating a calendar object
|
||||||
|
|
||||||
|
Creating a calendar object is almost identical, except that you don't have a url yet to a calendar object.
|
||||||
|
|
||||||
|
Instead, it is up to you to determine the new url.
|
||||||
|
|
||||||
|
PUT /calendars/johndoe/home/somerandomstring.ics HTTP/1.1
|
||||||
|
Content-Type: text/calendar; charset=utf-8
|
||||||
|
|
||||||
|
BEGIN:VCALENDAR
|
||||||
|
....
|
||||||
|
END:VCALENDAR
|
||||||
|
|
||||||
|
A response to this will be something like this:
|
||||||
|
|
||||||
|
HTTP/1.1 201 Created
|
||||||
|
ETag: "21345-324"
|
||||||
|
|
||||||
|
Similar to updating, an ETag is often returned, but there are cases where this is not true.
|
||||||
|
Deleting a calendar object
|
||||||
|
|
||||||
|
Deleting is simple enough:
|
||||||
|
|
||||||
|
DELETE /calendars/johndoe/home/132456762153245.ics HTTP/1.1
|
||||||
|
If-Match: "2134-314"
|
||||||
|
|
||||||
|
Speeding up Sync with WebDAV-Sync
|
||||||
|
|
||||||
|
WebDAV-Sync is a protocol extension that is defined in rfc6578. Because this extension was defined later, some servers may not support this yet.
|
||||||
|
|
||||||
|
SabreDAV supports this since 2.0.
|
||||||
|
|
||||||
|
WebDAV-Sync allows a client to ask just for calendars that have changed. The process on a high-level is as follows:
|
||||||
|
|
||||||
|
Client requests sync-token from server.
|
||||||
|
Server reports token 15.
|
||||||
|
Some time passes.
|
||||||
|
Client does a Sync REPORT on an calendar, and supplied token 15.
|
||||||
|
Server returns vcard urls that have changed or have been deleted and returns token 17.
|
||||||
|
|
||||||
|
As you can see, after the initial sync, only items that have been created, modified or deleted will ever be sent.
|
||||||
|
|
||||||
|
This has a lot of advantages. The transmitted xml bodies can generally be a lot shorter, and is also easier on both client and server in terms of memory and CPU usage, because only a limited set of items will have to be compared.
|
||||||
|
|
||||||
|
It's important to note, that a client should only do Sync operations, if the server reports that it has support for it. The quickest way to do so, is to request {DAV}sync-token on the calendar you wish to sync.
|
||||||
|
|
||||||
|
Technically, a server may support 'sync' on one calendar, and it may not support it on another, although this is probably rare.
|
||||||
|
Getting the first sync-token
|
||||||
|
|
||||||
|
Initially, we just request a sync token when asking for calendar information:
|
||||||
|
|
||||||
|
PROPFIND /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Depth: 0
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:prop>
|
||||||
|
<d:displayname />
|
||||||
|
<cs:getctag />
|
||||||
|
<d:sync-token />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>
|
||||||
|
|
||||||
|
This would return something as follows:
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:displayname>My calendar</d:displayname>
|
||||||
|
<cs:getctag>3145</cs:getctag>
|
||||||
|
<d:sync-token>http://sabredav.org/ns/sync-token/3145</d:sync-token>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
As you can see, the sync-token is a url. It always should be a url. Even though a number appears in the url, you are not allowed to attach any meaning to that url. Some servers may have use an increasing number, another server may use a completely random string.
|
||||||
|
Receiving changes
|
||||||
|
|
||||||
|
After a sync token has been obtained, and the client already has the initial copy of the calendar, the client is able to request all changes since the token was issued.
|
||||||
|
|
||||||
|
This is done with a REPORT request that may look like this:
|
||||||
|
|
||||||
|
REPORT /calendars/johndoe/home/ HTTP/1.1
|
||||||
|
Host: dav.example.org
|
||||||
|
Content-Type: application/xml; charset="utf-8"
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<d:sync-collection xmlns:d="DAV:">
|
||||||
|
<d:sync-token>http://sabredav.org/ns/sync/3145</d:sync-token>
|
||||||
|
<d:sync-level>1</d:sync-level>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag/>
|
||||||
|
</d:prop>
|
||||||
|
</d:sync-collection>
|
||||||
|
|
||||||
|
This requests all the changes since sync-token identified by http://sabredav.org/ns/sync/3145, and for the calendar objects that have been added or modified, we're requesting the etag.
|
||||||
|
|
||||||
|
The response to a query like this is another multistatus xml body. Example:
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-Status
|
||||||
|
Content-Type: application/xml; charset="utf-8"
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<d:multistatus xmlns:d="DAV:">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/newevent.ics</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>"33441-34321"</d:getetag>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/updatedevent.ics</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>"33541-34696"</d:getetag>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/deletedevent.ics</d:href>
|
||||||
|
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||||
|
</d:response>
|
||||||
|
<d:sync-token>http://sabredav.org/ns/sync/5001</d:sync-token>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
The last response reported two changes: newevent.ics and updatedevent.ics. There's no way to tell from the response wether those cards got created or updated, you, as a client can only infer this based on the vcards you are already aware of.
|
||||||
|
|
||||||
|
The entry with name deletedevent.ics got deleted as indicated by the 404 status. Note that the status element is here a child of d:response when in all previous examples it has been a child of d:propstat.
|
||||||
|
|
||||||
|
The other difference with the other multi-status examples, is that this one has a sync-token element with the latest sync-token.
|
||||||
|
Caveats
|
||||||
|
|
||||||
|
Note that a server is free to 'forget' any sync-tokens that have been previously issued. In this case it may be needed to do a full-sync again.
|
||||||
|
|
||||||
|
In case the supplied sync-token is not recognized by the server, a HTTP error is emitted. SabreDAV emits a 403.
|
||||||
|
Discovery
|
||||||
|
|
||||||
|
Ideally you will want to make sure that all the calendars in an account are automatically discovered. The best user interface would be to just have to ask for three items:
|
||||||
|
|
||||||
|
Username
|
||||||
|
Password
|
||||||
|
Server
|
||||||
|
|
||||||
|
And the server should be as short as possible. This is possible with most servers.
|
||||||
|
|
||||||
|
If, for example a user specified 'dav.example.org' for the server, the first thing you should do is attempt to send a PROPFIND request to https://dav.example.org/. Note that you SHOULD try the https url before the http url.
|
||||||
|
|
||||||
|
This PROPFIND request looks as follows:
|
||||||
|
|
||||||
|
PROPFIND / HTTP/1.1
|
||||||
|
Depth: 0
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:propfind xmlns:d="DAV:">
|
||||||
|
<d:prop>
|
||||||
|
<d:current-user-principal />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>
|
||||||
|
|
||||||
|
This will return a response such as the following:
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:current-user-principal>
|
||||||
|
<d:href>/principals/users/johndoe/</d:href>
|
||||||
|
</d:current-user-principal>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
A 'principal' is a user. The url that's being returned, is a url that refers to the current user. On this url you can request additional information about the user.
|
||||||
|
|
||||||
|
What we need from this url, is their 'calendar home'. The calendar home is a collection that contains all of the users' calendars.
|
||||||
|
|
||||||
|
To request that, issue the following request:
|
||||||
|
|
||||||
|
PROPFIND /principals/users/johndoe/ HTTP/1.1
|
||||||
|
Depth: 0
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:prop>
|
||||||
|
<c:calendar-home-set />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>
|
||||||
|
|
||||||
|
This will return a response such as the following:
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/principals/users/johndoe/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<c:calendar-home-set>
|
||||||
|
<d:href>/calendars/johndoe/</d:href>
|
||||||
|
</c:calendar-home-set>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
|
||||||
|
Lastly, to list all the calendars for the user, issue a PROPFIND request with Depth: 1.
|
||||||
|
|
||||||
|
PROPFIND /calendars/johndoe/ HTTP/1.1
|
||||||
|
Depth: 1
|
||||||
|
Prefer: return-minimal
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:prop>
|
||||||
|
<d:resourcetype />
|
||||||
|
<d:displayname />
|
||||||
|
<cs:getctag />
|
||||||
|
<c:supported-calendar-component-set />
|
||||||
|
</d:prop>
|
||||||
|
</d:propfind>
|
||||||
|
|
||||||
|
In that last request, we asked for 4 properties.
|
||||||
|
|
||||||
|
The resourcetype tells us what type of object we're getting back. You must read out the resourcetype and ensure that it contains at least a calendar element in the CalDAV namespace. Other items may be returned, including non- calendar, which your application should ignore.
|
||||||
|
|
||||||
|
The displayname is a human-readable string for the calendarname, the ctag was already covered in an earlier section.
|
||||||
|
|
||||||
|
Lastly, supported-calendar-component-set. This gives us a list of components that the calendar accepts. This could be just VTODO, VEVENT, VJOURNAL or a combination of these three.
|
||||||
|
|
||||||
|
If you are just creating a todo-list application, this means you should only list the calendars that support the VTODO component.
|
||||||
|
|
||||||
|
HTTP/1.1 207 Multi-status
|
||||||
|
Content-Type: application/xml; charset=utf-8
|
||||||
|
|
||||||
|
<d:multistatus xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:resourcetype>
|
||||||
|
<d:collection/>
|
||||||
|
</d:resourcetype>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/home/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:resourcetype>
|
||||||
|
<d:collection/>
|
||||||
|
<c:calendar/>
|
||||||
|
</d:resourcetype>
|
||||||
|
<d:displayname>Home calendar</d:displayname>
|
||||||
|
<cs:getctag>3145</cs:getctag>
|
||||||
|
<c:supported-calendar-component-set>
|
||||||
|
<c:comp name="VEVENT" />
|
||||||
|
</c:supported-calendar-component-set>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/calendars/johndoe/tasks/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:prop>
|
||||||
|
<d:resourcetype>
|
||||||
|
<d:collection/>
|
||||||
|
<c:calendar/>
|
||||||
|
</d:resourcetype>
|
||||||
|
<d:displayname>My TODO list</d:displayname>
|
||||||
|
<cs:getctag>3345</cs:getctag>
|
||||||
|
<c:supported-calendar-component-set>
|
||||||
|
<c:comp name="VTODO" />
|
||||||
|
</c:supported-calendar-component-set>
|
||||||
|
</d:prop>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
||||||
|
*/
|
@ -75,6 +75,15 @@ class GitRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function initRepo() {
|
||||||
|
if(!$this->path) return false;
|
||||||
|
try {
|
||||||
|
return $this->git->init($this->path);
|
||||||
|
} catch (\PHPGit\Exception\GitException $ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function pull() {
|
public function pull() {
|
||||||
try {
|
try {
|
||||||
@ -118,6 +127,15 @@ class GitRepo {
|
|||||||
$repo['logs'] = $git->log(array('limit' => 50));
|
$repo['logs'] = $git->log(array('limit' => 50));
|
||||||
return $repo;
|
return $repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Commit changes to the repo. Default is to stage all changes and commit everything.
|
||||||
|
public function commit($msg, $options = array()) {
|
||||||
|
try {
|
||||||
|
return $this->git->commit($msg, $options);
|
||||||
|
} catch (\PHPGit\Exception\GitException $ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function isValidGitRepoURL($url) {
|
public static function isValidGitRepoURL($url) {
|
||||||
if (validate_url($url) && strrpos(parse_url($url, PHP_URL_PATH), '.')) {
|
if (validate_url($url) && strrpos(parse_url($url, PHP_URL_PATH), '.')) {
|
||||||
|
@ -21,6 +21,9 @@ class CheckJS {
|
|||||||
$page = urlencode(\App::$query_string);
|
$page = urlencode(\App::$query_string);
|
||||||
|
|
||||||
if($test) {
|
if($test) {
|
||||||
|
self::$jsdisabled = 1;
|
||||||
|
if(array_key_exists('jsdisabled',$_COOKIE))
|
||||||
|
self::$jsdisabled = $_COOKIE['jsdisabled'];
|
||||||
|
|
||||||
if(! array_key_exists('jsdisabled',$_COOKIE)) {
|
if(! array_key_exists('jsdisabled',$_COOKIE)) {
|
||||||
\App::$page['htmlhead'] .= "\r\n" . '<script>document.cookie="jsdisabled=0; path=/"; var jsMatch = /\&jsdisabled=0/; if (!jsMatch.exec(location.href)) { location.href = "' . z_root() . '/nojs/0?f=&redir=' . $page . '" ; }</script>' . "\r\n";
|
\App::$page['htmlhead'] .= "\r\n" . '<script>document.cookie="jsdisabled=0; path=/"; var jsMatch = /\&jsdisabled=0/; if (!jsMatch.exec(location.href)) { location.href = "' . z_root() . '/nojs/0?f=&redir=' . $page . '" ; }</script>' . "\r\n";
|
||||||
|
@ -9,4 +9,5 @@ class Controller {
|
|||||||
function post() {}
|
function post() {}
|
||||||
function get() {}
|
function get() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
app/wiki.apd
Normal file
4
app/wiki.apd
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
url: $baseurl/wiki/$nick
|
||||||
|
requires: local_channel
|
||||||
|
name: Wiki
|
||||||
|
photo: $baseurl/app/wiki.png
|
BIN
app/wiki.png
Normal file
BIN
app/wiki.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
15
boot.php
15
boot.php
@ -34,7 +34,6 @@ require_once('include/text.php');
|
|||||||
require_once('include/datetime.php');
|
require_once('include/datetime.php');
|
||||||
require_once('include/language.php');
|
require_once('include/language.php');
|
||||||
require_once('include/nav.php');
|
require_once('include/nav.php');
|
||||||
require_once('include/cache.php');
|
|
||||||
require_once('include/permissions.php');
|
require_once('include/permissions.php');
|
||||||
require_once('library/Mobile_Detect/Mobile_Detect.php');
|
require_once('library/Mobile_Detect/Mobile_Detect.php');
|
||||||
require_once('include/features.php');
|
require_once('include/features.php');
|
||||||
@ -45,10 +44,10 @@ require_once('include/account.php');
|
|||||||
|
|
||||||
|
|
||||||
define ( 'PLATFORM_NAME', 'hubzilla' );
|
define ( 'PLATFORM_NAME', 'hubzilla' );
|
||||||
define ( 'STD_VERSION', '1.7.3' );
|
define ( 'STD_VERSION', '1.9' );
|
||||||
define ( 'ZOT_REVISION', 1.1 );
|
define ( 'ZOT_REVISION', '1.1' );
|
||||||
|
|
||||||
define ( 'DB_UPDATE_VERSION', 1176 );
|
define ( 'DB_UPDATE_VERSION', 1179 );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -514,6 +513,7 @@ define ( 'ACTIVITY_OBJ_ALBUM', NAMESPACE_ACTIVITY_SCHEMA . 'photo-album' );
|
|||||||
define ( 'ACTIVITY_OBJ_EVENT', NAMESPACE_ACTIVITY_SCHEMA . 'event' );
|
define ( 'ACTIVITY_OBJ_EVENT', NAMESPACE_ACTIVITY_SCHEMA . 'event' );
|
||||||
define ( 'ACTIVITY_OBJ_GROUP', NAMESPACE_ACTIVITY_SCHEMA . 'group' );
|
define ( 'ACTIVITY_OBJ_GROUP', NAMESPACE_ACTIVITY_SCHEMA . 'group' );
|
||||||
define ( 'ACTIVITY_OBJ_GAME', NAMESPACE_ACTIVITY_SCHEMA . 'game' );
|
define ( 'ACTIVITY_OBJ_GAME', NAMESPACE_ACTIVITY_SCHEMA . 'game' );
|
||||||
|
define ( 'ACTIVITY_OBJ_WIKI', NAMESPACE_ACTIVITY_SCHEMA . 'wiki' );
|
||||||
define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_ZOT . '/activity/tagterm' );
|
define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_ZOT . '/activity/tagterm' );
|
||||||
define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_ZOT . '/activity/profile' );
|
define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_ZOT . '/activity/profile' );
|
||||||
define ( 'ACTIVITY_OBJ_THING', NAMESPACE_ZOT . '/activity/thing' );
|
define ( 'ACTIVITY_OBJ_THING', NAMESPACE_ZOT . '/activity/thing' );
|
||||||
@ -770,6 +770,7 @@ class App {
|
|||||||
public static $groups;
|
public static $groups;
|
||||||
public static $language;
|
public static $language;
|
||||||
public static $langsave;
|
public static $langsave;
|
||||||
|
public static $rtl = false;
|
||||||
public static $plugins_admin;
|
public static $plugins_admin;
|
||||||
public static $module_loaded = false;
|
public static $module_loaded = false;
|
||||||
public static $query_string;
|
public static $query_string;
|
||||||
@ -2281,6 +2282,12 @@ function construct_page(&$a) {
|
|||||||
$page = App::$page;
|
$page = App::$page;
|
||||||
$profile = App::$profile;
|
$profile = App::$profile;
|
||||||
|
|
||||||
|
// There's some experimental support for right-to-left text in the view/php/default.php page template.
|
||||||
|
// In v1.9 we started providing direction preference in the per language hstrings.php file
|
||||||
|
// This requires somebody with fluency in a RTL language to make happen
|
||||||
|
|
||||||
|
$page['direction'] = 0; // ((App::$rtl) ? 1 : 0);
|
||||||
|
|
||||||
header("Content-type: text/html; charset=utf-8");
|
header("Content-type: text/html; charset=utf-8");
|
||||||
|
|
||||||
// security headers - see https://securityheaders.io
|
// security headers - see https://securityheaders.io
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
[h2]Documentation for Hub Administrators[/h2]
|
[h2]Documentation for Hub Administrators[/h2]
|
||||||
|
[h3]Deploying your hub[/h3]
|
||||||
[h3]Administrators[/h3]
|
|
||||||
|
|
||||||
[zrl=[baseurl]/help/install]Install[/zrl]
|
[zrl=[baseurl]/help/install]Install[/zrl]
|
||||||
[zrl=[baseurl]/help/red2pi]Installing $Projectname on the Raspberry Pi[/zrl]
|
[zrl=[baseurl]/help/red2pi]Installing $Projectname on the Raspberry Pi[/zrl]
|
||||||
[zrl=[baseurl]/help/Hubzilla_on_OpenShift]$Projectname on OpenShift[/zrl]
|
[zrl=[baseurl]/help/Hubzilla_on_OpenShift]$Projectname on OpenShift[/zrl]
|
||||||
|
[h3]Taking care of your hub[/h3]
|
||||||
[zrl=[baseurl]/help/troubleshooting]Troubleshooting Tips[/zrl]
|
[zrl=[baseurl]/help/troubleshooting]Troubleshooting Tips[/zrl]
|
||||||
|
[zrl=[baseurl]/help/theme_management]Theme Management[/zrl]
|
||||||
[zrl=[baseurl]/help/hidden_configs]Tweaking $Projectname's Hidden Configurations[/zrl]
|
[zrl=[baseurl]/help/hidden_configs]Tweaking $Projectname's Hidden Configurations[/zrl]
|
||||||
[zrl=[baseurl]/help/faq_admins]FAQ For Admins[/zrl]
|
|
||||||
[zrl=[baseurl]/help/service_classes]Service Classes[/zrl]
|
[zrl=[baseurl]/help/service_classes]Service Classes[/zrl]
|
||||||
[zrl=[baseurl]/help/directories]Working with and configuring Directories[/zrl]
|
[zrl=[baseurl]/help/directories]Working with and configuring Directories[/zrl]
|
||||||
[zrl=[baseurl]/help/theme_management]Theme Management[/zrl]
|
[h3]Frequently asked questions[/h3]
|
||||||
|
[zrl=[baseurl]/help/faq_admins]FAQ For Admins[/zrl]
|
||||||
|
|
||||||
|
#include doc/macros/main_footer.bb;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<li>[img float=right]https://zothub.com/images/default_profile_photos/rainbow_man/48.jpg[/img] <img src="https://zothub.com/images/default_profile_photos/rainbow_man/48.jpg" style="float:right;" alt="Image/photo" /><br />
|
<li>[img float=right]https://zothub.com/images/default_profile_photos/rainbow_man/48.jpg[/img] <img src="https://zothub.com/images/default_profile_photos/rainbow_man/48.jpg" style="float:right;" alt="Image/photo" /><br />
|
||||||
<div style="clear:both;"></div>
|
<div style="clear:both;"></div>
|
||||||
<li>[code]code[/code] <code>code</code><br />
|
<li>[code]code[/code] <code>code</code><br />
|
||||||
|
<li>[code=xxx]syntax highlighted code[/code] <code>supported languages php, css, mysql, sql, abap, diff, html, perl, ruby, vbscript, avrc, dtd, java, xml, cpp, python, javascript, js, json, sh</code><br />
|
||||||
<li>[quote]quote[/quote] <blockquote>quote</blockquote><br />
|
<li>[quote]quote[/quote] <blockquote>quote</blockquote><br />
|
||||||
<li>[quote=Author]Author? Me? No, no, no...[/quote] <br /><strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote><br />
|
<li>[quote=Author]Author? Me? No, no, no...[/quote] <br /><strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote><br />
|
||||||
<li> [nobb] may be used to escape bbcode.</ul><br />
|
<li> [nobb] may be used to escape bbcode.</ul><br />
|
||||||
@ -83,7 +84,7 @@ or<br /><br />[dl terms="b"]<br />[*= First element term] First element descript
|
|||||||
<li>[spoiler] for hiding spoilers<br /><br /></li>
|
<li>[spoiler] for hiding spoilers<br /><br /></li>
|
||||||
|
|
||||||
<li>[rpost=title]Text to post[/rpost] The observer will be returned to their home hub to enter a post with the specified title and body. Both are optional</li>
|
<li>[rpost=title]Text to post[/rpost] The observer will be returned to their home hub to enter a post with the specified title and body. Both are optional</li>
|
||||||
<li>[qr]text to post[/qr] - create a QR code.</li>
|
<li>[qr]text to post[/qr] - create a QR code (if the qrator plugin is installed).</li>
|
||||||
<li>[toc] - create a table of content in a webpage. Please refer to the <a href="http://ndabas.github.io/toc/" target="_blank">original jquery toc</a> to get more explanations.
|
<li>[toc] - create a table of content in a webpage. Please refer to the <a href="http://ndabas.github.io/toc/" target="_blank">original jquery toc</a> to get more explanations.
|
||||||
<ul>
|
<ul>
|
||||||
<li>Optional param: 'data-toc'. If ommited the default is 'body'</li>
|
<li>Optional param: 'data-toc'. If ommited the default is 'body'</li>
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
[b]Channels[/b]
|
[h2]Channels[/h2]
|
||||||
|
|
||||||
|
[h3]What are channels?[/h3]
|
||||||
|
|
||||||
Channels are simply collections of content stored in one place. A channel can represent anything. It could represent you, a website, a forum, photo albums, anything. For most people, their first channel with be "Me".
|
Channels are simply collections of content stored in one place. A channel can represent anything. It could represent you, a website, a forum, photo albums, anything. For most people, their first channel with be "Me".
|
||||||
|
|
||||||
The most important features for a channel that represents "me" are:
|
The most important features for a channel that represents "me" are:
|
||||||
|
[ul]
|
||||||
|
[*]Secure and private "spam free" communications
|
||||||
|
|
||||||
Secure and private "spam free" communications
|
[*]Identity and "single-signon" across the entire network
|
||||||
|
|
||||||
Identity and "single-signon" across the entire network
|
[*]Privacy controls and permissions which extend to the entire network
|
||||||
|
|
||||||
Privacy controls and permissions which extend to the entire network
|
|
||||||
|
|
||||||
Directory services (like a phone book)
|
|
||||||
|
|
||||||
|
[*]Directory services (like a phone book)
|
||||||
|
[/ul]
|
||||||
In short, a channel that represents yourself is "me, on the internet".
|
In short, a channel that represents yourself is "me, on the internet".
|
||||||
|
|
||||||
|
[h3]Creating channels[/h3]
|
||||||
|
|
||||||
You will be required to create your first channel as part of the sign up process. You can also create additonal channels from the "Select channel" link.
|
You will be required to create your first channel as part of the sign up process. You can also create additonal channels from the "Select channel" link.
|
||||||
|
|
||||||
You will be asked to provide a channel name, and a short nick name. For a channel that represents yourself, it is a good idea to use your real name here to ensure your friends can find you, and connect to your channel. The short nickname will be used to generate a "webbie". This is a bit like a username, and will look like an email address, taking the form nickname@domain. You should put a little thought into what you want to use here. Imagine somebody asking for your webbie and having to tell them it is "llamas-are_kewl.123". "llamasarecool" would be a much better choice.
|
You will be asked to provide a channel name, and a short nick name. For a channel that represents yourself, it is a good idea to use your real name here to ensure your friends can find you, and connect to your channel. The short nickname will be used to generate a "webbie". This is a bit like a username, and will look like an email address, taking the form nickname@domain. You should put a little thought into what you want to use here. Imagine somebody asking for your webbie and having to tell them it is "llamas-are_kewl.123". "llamasarecool" would be a much better choice.
|
||||||
@ -22,9 +26,14 @@ Once you have created your channel, you will be taken to the settings page, wher
|
|||||||
|
|
||||||
Once you have done this, your channel is ready to use. At [observer=1][observer.url][/observer][observer=0]example.com/channel/username[/observer] you will find your channel "stream". This is where your recent activity will appear, in reverse chronological order. If you post in the box marked "share", the entry will appear at the top of your stream. You will also find links to all the other communication areas for this channel here. The "About" tab contains your "profile", the photos page contain photo albums, and the events page contains events share by both yourself and your contacts.
|
Once you have done this, your channel is ready to use. At [observer=1][observer.url][/observer][observer=0]example.com/channel/username[/observer] you will find your channel "stream". This is where your recent activity will appear, in reverse chronological order. If you post in the box marked "share", the entry will appear at the top of your stream. You will also find links to all the other communication areas for this channel here. The "About" tab contains your "profile", the photos page contain photo albums, and the events page contains events share by both yourself and your contacts.
|
||||||
|
|
||||||
|
[h3]The grid, permissions and delegation[/h3]
|
||||||
|
|
||||||
The "Grid" page contains all recent posts from across the $Projectname network, again in reverse chronologial order. The exact posts that appear here depend largely on your permissions. At their most permissive, you will receive posts from complete strangers. At the other end of the scale, you may see posts from only your friends - or if you're feeling really anti-social, only your own posts.
|
The "Grid" page contains all recent posts from across the $Projectname network, again in reverse chronologial order. The exact posts that appear here depend largely on your permissions. At their most permissive, you will receive posts from complete strangers. At the other end of the scale, you may see posts from only your friends - or if you're feeling really anti-social, only your own posts.
|
||||||
|
|
||||||
As mentioned at the start, many other kinds of channel are possible, however, the creation procedure is the same. The difference between channels lies primarily in the permissions assigned. For example, a channel for sharing documents with colleagues at work would probably want more permissive settings for "Can write to my "public" file storage" than a personal account. For more information, see the permissions section.
|
As mentioned at the start, many other kinds of channel are possible, however, the creation procedure is the same. The difference between channels lies primarily in the permissions assigned. For example, a channel for sharing documents with colleagues at work would probably want more permissive settings for "Can write to my "public" file storage" than a personal account. For more information, see the [zrl=[baseurl]/help/roles]permissions section[/zrl].
|
||||||
|
|
||||||
|
You can also delegate control of your channels' posts and connections, but not its configurations, to another channel. That is done by editing a connection and assigning it the permission to administer your channel's resources.
|
||||||
|
|
||||||
#include doc/macros/main_footer.bb;
|
#include doc/macros/main_footer.bb;
|
||||||
|
|
||||||
|
|
||||||
|
10
doc/context/de/wiki/help.html
Normal file
10
doc/context/de/wiki/help.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Allgemein</dt>
|
||||||
|
<dd>Jedes Wiki ist eine Sammlung aus mit Markdown formatierten Seiten.</dd>
|
||||||
|
<dt><a href="#" onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Click to highlight element...">Wiki Liste</a></dt>
|
||||||
|
<dd>Wikis die dem eigenen Kanal gehören und <i>mit der Berechtigung zum Anschauen</i>, sind in der Seitenleiste gelistet.</dd>
|
||||||
|
<dt><a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element...">Seiten Versionen</a></dt>
|
||||||
|
<dd>Jede Änderung einer Seite wird gespeichert, um eine schnelle Berichtigung zu ermöglichen. Klick auf das <b>Versionsgeschichte</b> Tab um den Verlauf der Seitenbearbeitung zu sehen, einschließlich Datum und Autor. Der Zurück-Knopf lädt die ausgewählte Änderung, aber ohne die Seite automatisch zu spreichern.</dd>
|
||||||
|
<dt><a href="#" onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Click to highlight element...">Seiten</a></dt>
|
||||||
|
<dd>Die Seiten des Wikis werden in <b>Wiki Seiten</b> gelistet. Vor dem Speichern einer Seite über das <b>Seiten</b> Dropdown Menu, hast Du die Möglichkeit eine <a href="#" onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Click to highlight element...">Zusammenfassung der Änderungen</a> einzutragen. Dieser Text wird anschließend unter <a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element..."><b>Seiten Versionen</b></a> in der Versionsgeschichte angezeigt.</dd>
|
||||||
|
</dl>
|
10
doc/context/en/wiki/help.html
Normal file
10
doc/context/en/wiki/help.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>General</dt>
|
||||||
|
<dd>Each wiki is a collection of pages, composed as Markdown-formatted text files.</dd>
|
||||||
|
<dt><a href='#' onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Click to highlight element...">Wiki List</a></dt>
|
||||||
|
<dd>Wikis owned by the channel <i>that you have permission to view</i> are listed in the side panel.</dd>
|
||||||
|
<dt><a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element...">Page History</a></dt>
|
||||||
|
<dd>Every revision of a page is saved to allow quick reversion. Click the <b>History</b> tab to view a history of page revisions, including the date and author of each. The revert button will load the selected revision but will not automatically save the page.</dd>
|
||||||
|
<dt><a href='#' onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Click to highlight element...">Pages</a></dt>
|
||||||
|
<dd>The list of pages in the wiki are listed in the <b>Wiki Pages</b> panel. Prior to saving page edits using the <b>Page</b> control dropdown menu, you may <a href='#' onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Click to highlight element...">enter a custom message</a> to be displayed in the <a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Click to highlight element..."><b>Page History</b></a> viewer along with the revision.</dd>
|
||||||
|
</dl>
|
1
doc/context/es
Symbolic link
1
doc/context/es
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
es-es
|
@ -1 +0,0 @@
|
|||||||
es
|
|
10
doc/context/es-es/wiki/help.html
Normal file
10
doc/context/es-es/wiki/help.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>General</dt>
|
||||||
|
<dd>Cada wiki es una colección de páginas, compuestas como ficheros de texto formateados en Markdown.</dd>
|
||||||
|
<dt><a href='#' onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Pulsar para resaltar el elemento...">Lista de wikis</a></dt>
|
||||||
|
<dd>Las páginas wiki propiedad del canal <i>que esté autorizado a ver</i> aparecen en el panel lateral.</dd>
|
||||||
|
<dt><a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Pulsar para resaltar el elemento...">Historial de la página</a></dt>
|
||||||
|
<dd>Cada revisión de una página se salva para permitir su rápida recuperación. Pulsar en la pestaña <b>Historial</b> para ver las revisiones de la página, incluyendo la fecha y el autor de cada una. El botón de reversión cargará la revisión seleccionada, pero no salvará automáticamente la página.</dd>
|
||||||
|
<dt><a href='#' onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Pulsar para resaltar el elemento...">Páginas</a></dt>
|
||||||
|
<dd>La lista de páginas en el wiki aparece en el panel <b>Páginas del wiki</b>. Antes de salvar las páginas editadas usando el control <b>Página</b> en el menú desplegable, puede <a href='#' onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Pulsar para resaltar el elemento...">escribir un mensaje personalizado</a> que se verá en el visor <a href='#' onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Pulsar para resaltar el elemento..."><b>Historial de la página</b></a> junto con la revisión.</dd>
|
||||||
|
</dl>
|
10
doc/context/it/wiki/help.html
Normal file
10
doc/context/it/wiki/help.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>General</dt>
|
||||||
|
<dd>Ogni wiki è una raccolta di pagine, composta di file di testo formattati con Markdown.</dd>
|
||||||
|
<dt><a href="#" onclick='contextualHelpFocus("#wiki_list", 1); return false;' title="Fai click per evidenziare l'elemento...">Elenco dei Wiki</a></dt>
|
||||||
|
<dd>I Wiki del canale <i>che sei abilitato a vedere</i> sono elencati nel pannello laterale.</dd>
|
||||||
|
<dt><a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Fai click per evidenziare l'elemento...">Cronologia della pagina</a></dt>
|
||||||
|
<dd>Le revisioni di ogni pagina vengono salvate per rendere possibile un ripristino veloce. Fai click sulla tab <b>Cronologia</b> per vedere l'elenco delle revisioni, con autore e data delle stesse. Il bottone di ripristino riporterà alla revisione selezionata, senza salvare automaticamente la pagina.</dd>
|
||||||
|
<dt><a href="#" onclick='contextualHelpFocus("#wiki_page_list", 1); return false;' title="Fai click per evidenziare l'elemento...">Pagine</a></dt>
|
||||||
|
<dd>L'elenco delle pagine del wiki si trova nel pannello <b>Pagine del wiki</b>. Prima di salvare le modifiche con il menu a discela <b>Pagina</b>, puoi <a href="#" onclick='contextualHelpFocus("#id_commitMsg", 0); return false;' title="Fai click per evidenziare l'elemento...">inserire un messaggio</a> che verrà visualizzato nella visualizzazione della <a href="#" onclick='contextualHelpFocus("#wiki-get-history", 0); return false;' title="Fai click per evidenziare l'elemento..."><b>storia della pagina</b></a> insieme alla revisione.</dd>
|
||||||
|
</dl>
|
@ -1,6 +1,7 @@
|
|||||||
[h2]Database Tables[/h2]
|
[h2]Database Tables[/h2]
|
||||||
[table]
|
[table]
|
||||||
[tr][th]Table[/th][th]Description[/th][/tr]
|
[tr][th]Table[/th][th]Description[/th][/tr]
|
||||||
|
[tr][td][zrl=[baseurl]/help/database/db_abconfig]abconfig[/zrl][/td][td]arbitrary storage for connections of local channels[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_abook]abook[/zrl][/td][td]connections of local channels[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_abook]abook[/zrl][/td][td]connections of local channels[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_account]account[/zrl][/td][td]service provider account[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_account]account[/zrl][/td][td]service provider account[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_addon]addon[/zrl][/td][td]registered plugins[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_addon]addon[/zrl][/td][td]registered plugins[/td][/tr]
|
||||||
@ -8,6 +9,7 @@
|
|||||||
[tr][td][zrl=[baseurl]/help/database/db_attach]attach[/zrl][/td][td]file attachments[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_attach]attach[/zrl][/td][td]file attachments[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_auth_codes]auth_codes[/zrl][/td][td]OAuth usage[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_auth_codes]auth_codes[/zrl][/td][td]OAuth usage[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_cache]cache[/zrl][/td][td]OEmbed cache[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_cache]cache[/zrl][/td][td]OEmbed cache[/td][/tr]
|
||||||
|
[tr][td][zrl=[baseurl]/help/database/db_cal]cal[/zrl][/td][td]CalDAV containers for events[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_channel]channel[/zrl][/td][td]local channels[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_channel]channel[/zrl][/td][td]local channels[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_chat]chat[/zrl][/td][td]chat room content[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_chat]chat[/zrl][/td][td]chat room content[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_chatpresence]chatpresence[/zrl][/td][td]channel presence information for chat[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_chatpresence]chatpresence[/zrl][/td][td]channel presence information for chat[/td][/tr]
|
||||||
@ -16,17 +18,14 @@
|
|||||||
[tr][td][zrl=[baseurl]/help/database/db_config]config[/zrl][/td][td]main configuration storage[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_config]config[/zrl][/td][td]main configuration storage[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_conv]conv[/zrl][/td][td]Diaspora private messages meta conversation structure[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_conv]conv[/zrl][/td][td]Diaspora private messages meta conversation structure[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_event]event[/zrl][/td][td]Events[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_event]event[/zrl][/td][td]Events[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_fcontact]fcontact[/zrl][/td][td]friend suggestion stuff (obsolete)[/td][/tr]
|
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_ffinder]ffinder[/zrl][/td][td]friend suggestion stuff (obsolete)[/td][/tr]
|
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_fserver]fserver[/zrl][/td][td]obsolete[/td][/tr]
|
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_fsuggest]fsuggest[/zrl][/td][td]friend suggestion stuff (unused)[/td][/tr]
|
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_group_member]group_member[/zrl][/td][td]privacy groups (collections), group info[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_group_member]group_member[/zrl][/td][td]privacy groups (collections), group info[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_groups]groups[/zrl][/td][td]privacy groups (collections), member info[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_groups]groups[/zrl][/td][td]privacy groups (collections), member info[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_hook]hook[/zrl][/td][td]plugin hook registry[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_hook]hook[/zrl][/td][td]plugin hook registry[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_hubloc]hubloc[/zrl][/td][td]xchan location storage, ties a hub location to an xchan[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_hubloc]hubloc[/zrl][/td][td]xchan location storage, ties a hub location to an xchan[/td][/tr]
|
||||||
|
[tr][td][zrl=[baseurl]/help/database/db_iconfig]iconfig[/zrl][/td][td]extensible arbitrary storage for items[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_issue]issue[/zrl][/td][td]future bug/issue database[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_issue]issue[/zrl][/td][td]future bug/issue database[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_item]item[/zrl][/td][td]all posts and webpages[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_item]item[/zrl][/td][td]all posts and webpages[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_item_id]item_id[/zrl][/td][td]other identifiers on other services for posts[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_item_id]item_id[/zrl][/td][td](deprecated by iconfig) other identifiers on other services for posts[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_likes]likes[/zrl][/td][td]likes of 'things'[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_likes]likes[/zrl][/td][td]likes of 'things'[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_mail]mail[/zrl][/td][td]private messages[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_mail]mail[/zrl][/td][td]private messages[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_menu]menu[/zrl][/td][td]webpage menu data[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_menu]menu[/zrl][/td][td]webpage menu data[/td][/tr]
|
||||||
@ -48,7 +47,6 @@
|
|||||||
[tr][td][zrl=[baseurl]/help/database/db_sign]sign[/zrl][/td][td]Diaspora signatures. To be phased out.[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_sign]sign[/zrl][/td][td]Diaspora signatures. To be phased out.[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_site]site[/zrl][/td][td]site table to find directory peers[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_site]site[/zrl][/td][td]site table to find directory peers[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_source]source[/zrl][/td][td]channel sources data[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_source]source[/zrl][/td][td]channel sources data[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_spam]spam[/zrl][/td][td]unfinished[/td][/tr]
|
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_sys_perms]sys_perms[/zrl][/td][td]extensible permissions for OAuth[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_sys_perms]sys_perms[/zrl][/td][td]extensible permissions for OAuth[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_term]term[/zrl][/td][td]item taxonomy (categories, tags, etc.) table[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_term]term[/zrl][/td][td]item taxonomy (categories, tags, etc.) table[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_tokens]tokens[/zrl][/td][td]OAuth usage[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_tokens]tokens[/zrl][/td][td]OAuth usage[/td][/tr]
|
||||||
@ -60,6 +58,7 @@
|
|||||||
[tr][td][zrl=[baseurl]/help/database/db_xconfig]xconfig[/zrl][/td][td]as pconfig but for channels with no local account[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_xconfig]xconfig[/zrl][/td][td]as pconfig but for channels with no local account[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_xign]xign[/zrl][/td][td]channels ignored by friend suggestions[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_xign]xign[/zrl][/td][td]channels ignored by friend suggestions[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_xlink]xlink[/zrl][/td][td]"friends of friends" linkages derived from poco, also ratings storage[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_xlink]xlink[/zrl][/td][td]"friends of friends" linkages derived from poco, also ratings storage[/td][/tr]
|
||||||
|
[tr][td][zrl=[baseurl]/help/database/db_xperm]xperm[/zrl][/td][td]OAuth/OpenID-Connect extensible permissions permissions storage[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_xprof]xprof[/zrl][/td][td]if this hub is a directory server, contains basic public profile info of everybody in the network[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_xprof]xprof[/zrl][/td][td]if this hub is a directory server, contains basic public profile info of everybody in the network[/td][/tr]
|
||||||
[tr][td][zrl=[baseurl]/help/database/db_xtag]xtag[/zrl][/td][td]if this hub is a directory server, contains tags or interests of everybody in the network[/td][/tr]
|
[tr][td][zrl=[baseurl]/help/database/db_xtag]xtag[/zrl][/td][td]if this hub is a directory server, contains tags or interests of everybody in the network[/td][/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
@ -15,10 +15,6 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]abook_closeness[/td][td]"closeness" value for optional affinity tool, 0-99[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]99[/td][td]
|
[tr][td]abook_closeness[/td][td]"closeness" value for optional affinity tool, 0-99[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]99[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]abook_rating[/td][td]The channel owner's (public) rating of this connection -10 to +10, default 0 or unrated[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
|
||||||
[/td][/tr]
|
|
||||||
[tr][td]abook_rating_text[/td][td]The channel owner's (public) rating of this connection free form text[/td][td]text[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
|
||||||
[/td][/tr]
|
|
||||||
[tr][td]abook_created[/td][td]Datetime this record was created[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
[tr][td]abook_created[/td][td]Datetime this record was created[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]abook_updated[/td][td]Datetime this record was modified[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
[tr][td]abook_updated[/td][td]Datetime this record was modified[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
@ -32,16 +28,27 @@
|
|||||||
[tr][td]abook_profile[/td][td]profile.guid of profile to display to this connection if authenticated[/td][td]char(64)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
[tr][td]abook_profile[/td][td]profile.guid of profile to display to this connection if authenticated[/td][td]char(64)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]abook_blocked[/td][td]Bi-directional communications with this channel are blocked, regardless of other permissions. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_blocked[/td][td]Bi-directional communications with this channel are blocked, regardless of other permissions. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_ignored[/td][td]Incoming communications from this channel are blocked, regardless of other permissions. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_ignored[/td][td]Incoming communications from this channel are blocked, regardless of other permissions. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_hidden[/td][td]This connection will not be shown as a connection to anybody but the channel owner[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_hidden[/td][td]This connection will not be shown as a connection to anybody but the channel owner[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_archived[/td][td]This connection is likely non-functioning and the entry and conversations are preserved, but further polled communications will not be attempted. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_archived[/td][td]This connection is likely non-functioning and the entry and conversations are preserved, but further polled communications will not be attempted. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_pending[/td][td]A connection request was received from this channel but has not been approved by the channel owner, public communications may still be visible but no additional permissions have been granted. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_pending[/td][td]A connection request was received from this channel but has not been approved by the channel owner, public communications may still be visible but no additional permissions have been granted. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_unconnected[/td][td]currently unused. Projected usage is to indicate "one-way" connections which were insitgated on this end but are still pending on the remote end. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_unconnected[/td][td]currently unused. Projected usage is to indicate "one-way" connections which were insitgated on this end but are still pending on the remote end. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_self[/td][td]is a special case where the owner is the target. Every channel has one abook entry with abook_self and with a target abook_xchan set to channel.channel_hash . When this flag is present, abook_my_perms is the default permissions granted to all new connections and several other fields are unused.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_self[/td][td]is a special case where the owner is the target. Every channel has one abook entry with abook_self and with a target abook_xchan set to channel.channel_hash . When this flag is present, abook_my_perms is the default permissions granted to all new connections and several other fields are unused.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_feed[/td][td]indicates this connection is an RSS/Atom feed and may trigger special handling.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_feed[/td][td]indicates this connection is an RSS/Atom feed and may trigger special handling.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_incl[/td][td]connection filter allow rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_incl[/td][td]connection filter allow rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_excl[/td][td]connection filter deny rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_excl[/td][td]connection filter deny rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]abook_instance[/td][td]comma separated list of site urls of all channel clones that this connection is connected with (used only for singleton networks which don't support cloning)[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_instance[/td][td]comma separated list of site urls of all channel clones that this connection is connected with (used only for singleton networks which don't support cloning)[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[/th][/tr]
|
[/th][/tr]
|
||||||
[tr][td]id[/td][td][/td]generated index[td]int(11)[/td][td]NO[/td][td]PRI[/td][td]NULL[/td][td]auto_increment
|
[tr][td]id[/td][td][/td]generated index[td]int(11)[/td][td]NO[/td][td]PRI[/td][td]NULL[/td][td]auto_increment
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]name[/td][td]plugin base (file)name[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]aname[/td][td]plugin base (file)name[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]version[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]version[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
@ -11,7 +11,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]hidden[/td][td]currently unused[/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]hidden[/td][td]currently unused[/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]timestamp[/td][td]file timestamp to check for reloads[/td][td]bigint(20)[/td][td]NO[/td][td][/td][td]0[/td][td]
|
[tr][td]tstamp[/td][td]file timestamp to check for reloads[/td][td]bigint(20)[/td][td]NO[/td][td][/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]plugin_admin[/td][td]1 = has admin config, 0 = has no admin config[/td][td]tinyint(1)[/td][td]NO[/td][td][/td][td]0[/td][td]
|
[tr][td]plugin_admin[/td][td]1 = has admin config, 0 = has no admin config[/td][td]tinyint(1)[/td][td]NO[/td][td][/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -27,8 +27,20 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]app_page[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
[tr][td]app_page[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]app_requires[/td][td]currently unused[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
[tr][td]app_requires[/td][td]access rules[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
|
||||||
|
[tr][td]app_created[/td][td]datetime of app creation[/td][td]datetime[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]app_edited[/td][td]datetime of last app edit[/td][td]datetime[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
|
||||||
|
[tr][td]app_deleted[/td][td]1 = deleted, 0 = normal[/td][td]int(11)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]app_system[/td][td]1 = imported system app, 0 = member created app[/td][td]int(11)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
|
||||||
|
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
Storage for personal apps
|
Storage for personal apps
|
||||||
|
@ -29,9 +29,11 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]os_storage[/td][td]if 0, data contains content; if 1 data contains path to content (always 1 in hubzilla)[/td][td]tinyint[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]os_storage[/td][td]if 0, data contains content; if 1 data contains path to content (always 1 in hubzilla)[/td][td]tinyint[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
[tr][td]os_path[/td][td]under construction, store the system path[/td][td]mediumtext[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]display_path[/td][td]under construction, store the human readable path[/td][td]mediumtext[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]display_path[/td][td]under construction, store the human readable path[/td][td]mediumtext[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]data[/td][td]file data or pathname to stored data if ATTACH_FLAG_OS[/td][td]longblob[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]content[/td][td]file data or pathname to stored data if ATTACH_FLAG_OS[/td][td]longblob[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]created[/td][td]creation time[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
[tr][td]created[/td][td]creation time[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]channel_dirdate[/td][td]time when directory was last pinged. Must do this once a month[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
[tr][td]channel_dirdate[/td][td]time when directory was last pinged. Must do this once a month[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
[tr][td]channel_lastpost[/td][td]date of last post for this channel. May not be fully implemented[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[tr][td]channel_deleted[/td][td]time when channel was deleted[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
[tr][td]channel_deleted[/td][td]time when channel was deleted[/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]channel_max_anon_mail[/td][td]unused[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]10[/td][td]
|
[tr][td]channel_max_anon_mail[/td][td]unused[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]10[/td][td]
|
||||||
@ -95,6 +97,8 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]channel_system[/td][td]if 1, this is the special system channel on this site[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]128[/td][td]
|
[tr][td]channel_system[/td][td]if 1, this is the special system channel on this site[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]128[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
[tr][td]channel_moved[/td][td]URL of relocated channel, making this instance abandoned if set[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
||||||
|
[/td][/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
Return to [zrl=[baseurl]/help/database]database documentation[/zrl]
|
Return to [zrl=[baseurl]/help/database]database documentation[/zrl]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]cp_status[/td][td]text status description e.g. "online"[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]cp_status[/td][td]text status description e.g. "online"[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]cp_client[/td][td][/td]IP address of this client[td]char(128)[/td][td]NO[/td][td][/td][td][/td][td]
|
[tr][td]cp_client[/td][td]IP address of this client[/td][td]char(128)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]redirect_uri[/td][td][/td][td]varchar(200)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]redirect_uri[/td][td][/td][td]varchar(200)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]name[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
|
[tr][td]clname[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]icon[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
|
[tr][td]icon[/td][td][/td][td]text[/td][td]YES[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]edited[/td][td][/td][td]datetime[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]edited[/td][td][/td][td]datetime[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]start[/td][td][/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]dtstart[/td][td][/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]finish[/td][td][/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]dtend[/td][td][/td][td]datetime[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]summary[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]summary[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
@ -25,13 +25,13 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]location[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]location[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]type[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]etype[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]nofinish[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]nofinish[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]adjust[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]1[/td][td]
|
[tr][td]adjust[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]1[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]ignore[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]dismissed[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]allow_cid[/td][td][/td][td]mediumtext[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]allow_cid[/td][td][/td][td]mediumtext[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
@ -41,6 +41,24 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]deny_gid[/td][td][/td][td]mediumtext[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]deny_gid[/td][td][/td][td]mediumtext[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
|
||||||
|
[tr][td]event_status[/td][td][/td][td]charr(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]event_status_date[/td][td][/td][td]datetime[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]event_percent[/td][td][/td][td]smallint(6)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]event_repeat[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]event_sequence[/td][td][/td][td]smallint[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]event_priority[/td][td][/td][td]smallint[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]event_vdata[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]cal_id[/td][td][/td][td]int(10)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
Return to [zrl=[baseurl]/help/database]database documentation[/zrl]
|
Return to [zrl=[baseurl]/help/database]database documentation[/zrl]
|
@ -11,7 +11,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]deleted[/td][td]1 indicates the group has been deleted[/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]deleted[/td][td]1 indicates the group has been deleted[/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]name[/td][td]human readable name of group[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]gname[/td][td]human readable name of group[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]file[/td][td]relative filename of hook handler[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]file[/td][td]relative filename of hook handler[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]function[/td][td]function name of hook handler[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]fn[/td][td]function name of hook handler[/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]priority[/td][td]not yet implemented - can be used to sort conflicts in hook handling by calling handlers in priority order[/td][td]int(11) unsigned[/td][td]NO[/td][td][/td][td]0[/td][td]
|
[tr][td]priority[/td][td]can be used to sort conflicts in hook handling by calling handlers in priority order[/td][td]int(11) unsigned[/td][td]NO[/td][td][/td][td]0[/td][td]
|
||||||
|
[/td][/tr]
|
||||||
|
[tr][td]hook_version[/td][td]version 0 hooks must have two arguments, the App and the hook data. version 1 hooks have 1 argument - the hook data[/td][td]int(11) unsigned[/td][td]NO[/td][td][/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]obj_type[/td][td]ActivityStreams object type (old style URI)[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
[tr][td]obj_type[/td][td]ActivityStreams object type (old style URI)[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]object[/td][td]JSON encoded object structure unless it is an implied object (normal post)[/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]obj[/td][td]JSON encoded object structure unless it is an implied object (normal post)[/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]tgt_type[/td][td]ActivityStreams target type if applicable (URI)[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
[tr][td]tgt_type[/td][td]ActivityStreams target type if applicable (URI)[/td][td]char(255)[/td][td]NO[/td][td][/td][td][/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]hash[/td][td][/td][td]char(64)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]hash[/td][td][/td][td]char(64)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]name[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]xname[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]url[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]url[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
@ -25,7 +25,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]seen[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]seen[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]type[/td][td][/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]ntype[/td][td][/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]verb[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]verb[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -23,15 +23,15 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]filename[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]filename[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]type[/td][td][/td][td]char(128)[/td][td]NO[/td][td]MUL[/td][td]image/jpeg[/td][td]
|
[tr][td]mimetype[/td][td][/td][td]char(128)[/td][td]NO[/td][td]MUL[/td][td]image/jpeg[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]height[/td][td][/td][td]smallint(6)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]height[/td][td][/td][td]smallint(6)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]width[/td][td][/td][td]smallint(6)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]width[/td][td][/td][td]smallint(6)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]size[/td][td][/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]filesize[/td][td][/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]data[/td][td][/td][td]mediumblob[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]content[/td][td][/td][td]mediumblob[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]scale[/td][td][/td][td]tinyint(3)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]scale[/td][td][/td][td]tinyint(3)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]hide_friends[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]hide_friends[/td][td][/td][td]tinyint(1)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]name[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]fullname[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]pdesc[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]pdesc[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
@ -41,7 +41,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]marital[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]marital[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]with[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]partner[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]howlong[/td][td][/td][td]datetime[/td][td]NO[/td][td][/td][td]0000-00-00 00:00:00[/td][td]
|
[tr][td]howlong[/td][td][/td][td]datetime[/td][td]NO[/td][td][/td][td]0000-00-00 00:00:00[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
@ -73,7 +73,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]romance[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]romance[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]work[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]employment[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]education[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
[tr][td]education[/td][td][/td][td]text[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]otype[/td][td]type of linked thing[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]otype[/td][td]type of linked thing[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]type[/td][td]taxonomy type (See Tag/term types in boot.php)[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]ttype[/td][td]taxonomy type (See Tag/term types in boot.php)[/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
[tr][td]term[/td][td]the actual taxonomy term[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
[tr][td]term[/td][td]the actual taxonomy term[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||||
[/td][/tr]
|
[/td][/tr]
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
[b]External Resource Links[/b]
|
[h2]External resource links[/h2]
|
||||||
|
[h3]Third-Party Themes[/h3]
|
||||||
[b][color= grey][size=24]External Links[/size][/color][/b]
|
[ul]
|
||||||
[b]Third-Party Themes[/b]
|
|
||||||
|
|
||||||
[*][url=https://github.com/omigeot/redstrap3]Redstrap[/url]
|
[*][url=https://github.com/omigeot/redstrap3]Redstrap[/url]
|
||||||
[*][url=https://bitbucket.org/tobiasd/red-clean]Clean[/url]
|
[*][url=https://bitbucket.org/tobiasd/red-clean]Clean[/url]
|
||||||
[*][url=https://github.com/tonybaldwin/redmatrixthemes/]nubasic[/url]
|
[*][url=https://github.com/tonybaldwin/redmatrixthemes/]nubasic[/url]
|
||||||
[*][url=https://github.com/deadsuperhero/redmatrix-themes]Sean Tilley's themes[/url]
|
[*][url=https://github.com/deadsuperhero/redmatrix-themes]Sean Tilley's themes[/url]
|
||||||
|
[/ul]
|
||||||
[b]Third-Party Addons[/b]
|
[h3]Third-Party addons[/h3]
|
||||||
|
[ul]
|
||||||
[*][url=https://abcentric.net/git/abcjsplugin.git]ABCjs integration - display scores in posts (WIP)[/url]
|
[*][url=https://abcentric.net/git/abcjsplugin.git]ABCjs integration - display scores in posts (WIP)[/url]
|
||||||
[b]Related Projects[/b]
|
[/ul]
|
||||||
|
[h3]Related projects[/h3]
|
||||||
|
[ul]
|
||||||
[*][url=https://addons.mozilla.org/en-US/firefox/addon/redshare/]Redshare for Firefox[/url]
|
[*][url=https://addons.mozilla.org/en-US/firefox/addon/redshare/]Redshare for Firefox[/url]
|
||||||
[*][url=https://github.com/cvogeley/red-for-android]Red for Android[/url]
|
[*][url=https://github.com/cvogeley/red-for-android]Red for Android[/url]
|
||||||
[*][url=https://github.com/zzottel/feed2red]feed2red.pl (posts Atom/RSS feeds to channel)[/url]
|
[*][url=https://github.com/zzottel/feed2red]feed2red.pl (posts Atom/RSS feeds to channel)[/url]
|
||||||
[*][url=https://wordpress.org/plugins/hubzilla-wp/]WordPress gateway (combine with wppost addon for full features)[/url]
|
[*][url=https://wordpress.org/plugins/hubzilla-wp/]WordPress gateway (combine with wppost addon for full features)[/url]
|
||||||
|
[/ul]
|
||||||
|
|
||||||
#include doc/macros/main_footer.bb;
|
#include doc/macros/main_footer.bb;
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
|
[h2]Project and site information[/h2]
|
||||||
[h2]Project/Site Information[/h2]
|
[h3]$Projectname[/h3]
|
||||||
|
|
||||||
[zrl=[baseurl]/help/Privacy]Privacy Policy[/zrl]
|
[zrl=[baseurl]/help/Privacy]Privacy Policy[/zrl]
|
||||||
|
|
||||||
[zrl=[baseurl]/help/history]$Projectname history[/zrl]
|
[zrl=[baseurl]/help/history]$Projectname history[/zrl]
|
||||||
|
[h3]External resources[/h3]
|
||||||
[h3]External Resources[/h3]
|
[zrl=[baseurl]/help/external-resource-links]List of external resources[/zrl]
|
||||||
[zrl=[baseurl]/help/external-resource-links]External Resource Links[/zrl]
|
|
||||||
|
|
||||||
[url=https://github.com/redmatrix/hubzilla]Main Website[/url]
|
[url=https://github.com/redmatrix/hubzilla]Main Website[/url]
|
||||||
[url=https://github.com/redmatrix/hubzilla-addons]Addon Website[/url]
|
[url=https://github.com/redmatrix/hubzilla-addons]Addon Website[/url]
|
||||||
|
|
||||||
[url=[baseurl]/help/credits]$Projectname Credits[/url]
|
[url=[baseurl]/help/credits]$Projectname Credits[/url]
|
||||||
|
[h3]About this $Projectname hub[/h3]
|
||||||
[h3]About This $Projectname Hub[/h3]
|
|
||||||
[zrl=[baseurl]/help/TermsOfService]Terms of Service For This Hub[/zrl]
|
[zrl=[baseurl]/help/TermsOfService]Terms of Service For This Hub[/zrl]
|
||||||
[zrl=[baseurl]/siteinfo]Hub Information (/siteinfo)[/zrl]
|
[zrl=[baseurl]/siteinfo]Hub Information (/siteinfo)[/zrl]
|
||||||
[zrl=[baseurl]/siteinfo/json]Detailed Technical Hub Information in JSON format(/siteinfo/json)[/zrl]
|
[zrl=[baseurl]/siteinfo/json]Detailed Technical Hub Information in JSON format(/siteinfo/json)[/zrl]
|
||||||
|
|
||||||
|
#include doc/macros/main_footer.bb;
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>$Projectname Doxygen API Documentation</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>$Projectname Doxygen API Documentation not rendered</h1>
|
|
||||||
|
|
||||||
To get the Doxygen API Documentation you must render it with the program <a href="http://www.doxygen.org">Doxygen</a> (included in most distributions).
|
|
||||||
<pre>
|
|
||||||
$ doxygen util/Doxyfile
|
|
||||||
</pre>
|
|
||||||
<br>
|
|
||||||
<a href="javascript:history.back()">back</a>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user